home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG006.ARK / MAILLIST.DOC < prev    next >
Text File  |  1984-04-29  |  19KB  |  524 lines

  1. FILENAME: MAILLIST.DOC, 09/17/77 by Ward Christensen
  2. ------------------------------------------------------------
  3. DOCUMENTATION FILE FOR THE COMPUTER CLUB
  4. MAILING LIST PROGRAMS WRITTEN IN BASIC-E.
  5. -------------------------------------------------------
  6. THESE PROGRAMS ARE BEING PROVIDED THROUGH THE COURTESY OF THE
  7. AUTHOR FOR THE SOLE USE OF HOBBYIST COMPUTER CLUBS IN
  8. MAINTAINING THEIR MAILING LISTS.
  9. ------------------------------------------------------
  10.  
  11. The needs of a computer club in maintaining a mailing
  12. list consist of the following requirements:
  13.  
  14.      1)  A file of names with sufficient information
  15.      about each member.
  16.      2)  A maintenance program to add, change, and delete
  17.      records.
  18.      3)  A sort program to change the order of the file (by
  19.      last name, zip, etc.) for report purposes.
  20.      4)  A program to print:
  21.          Alphabetic master listings
  22.          Mailing labels (usually in Zip sequence)
  23.          Name tags for meeting use.
  24.  
  25. The programs on this disk fulfill these needs.
  26.  
  27.      1)  PREFMT.BAS preformats the required size file
  28.      2)  MAINT.BAS maintains the mailing list
  29.      3)  SORT.ASM sorts the file, producing an index file
  30.      4)  REPORT.BAS prints listings labels and name tags.
  31. ------------------------------------------------------------
  32. As currently implemented, the file consists of 512, 128
  33. byte (1 sector) records.  It was originally thought that
  34. 1 sector records would be required because of the sort
  35. program written in assembler.  However, the sort program
  36. was eventually written to be independent of file length.
  37. Note that 128 is still a very good value, because of
  38. the efficiency of BASIC/E only having to
  39. read 1 sector per record.  If the record length was
  40. say, 150 bytes, then 2 sectors would always have to
  41. be read.  Also, random writing would have to read
  42. modify, and write sectors because of the sector overlap.
  43.  
  44.  
  45. For speed of access during maintenance, the file is
  46. written using a randomizing or hashing technique on the
  47. person's name.  The algorithm is as follows:  A variable
  48. is initialized to 0.  Then, every other letter in the person's
  49. name (1, 3, 5 ... n) is, one at a time, added into the
  50. variable.  The variable is doubled between each addition.
  51. Then, the result is divided by the number of records in
  52. the file, and the remainder is used as a record number.
  53. When adding, if the record is already in use, the file is
  54. sequentially read from that point until an open record is
  55. found.  When retrieving, the record randomized to is read,
  56. and the name is matched.  If it is not the right name,
  57. the file is read sequentially until the a record with
  58. a matching name is found.  You may press 'DEL' (or rubout)
  59. to stop the scan in case, for instance, you misspelled the
  60. name.  Note that the technique is simple, and is not for-
  61. giving of misspelled names.
  62.  
  63. The algorithm, in BASIC this is:
  64.     KEY=0
  65.     FOR I=1 TO LEN(KEY$) STEP 2
  66.     KEY = 2*KEY + ASC(MID$(KEY$,I,1))
  67.     NEXT I
  68.     KEY = KEY- FILE.SIZE*INT(KEY/FILE.SIZE)
  69.     IF KEY = 0 THEN KEY = 1
  70. ------------------------------------------------------------
  71. The file currently has the following fields in the record:
  72.  
  73. SORT:    A 4 byte field on which the file is sorted, to
  74.     be in alpha sequence.  This means that you do
  75.     not store the file as 'lastname,firstname'
  76.     which is very 'computeristic' and 'impersonal'.
  77.     instead, you key in the name in it's natural
  78.     form, then use the 4 byte SORT field
  79.     for sorting.  For example, if the name is
  80.     James R. Smith, then the sort field would be
  81.     keyed in as SMIT.
  82.  
  83. NAME:    The person's 'natural' name, i.e. first name first.
  84.     Remember BASIC won't allow commas,
  85.     so don't key in J. SMITH, JR. but rather
  86.     J. SMITH JR.
  87.  
  88. ORGANIZATION:    This field is normally blank, but is provided
  89.     when a 4-line address is required.  When
  90.     adding a person, BASIC/E will not accept
  91.     a totally blank input, so 1 blank must be keyed
  92.     when ORGANIZATION is not present.
  93.  
  94. STREET:    The street address
  95.  
  96. CITY:    The city AND state.  Since BASIC will not
  97.     allow a comma in an input line, simply use
  98.     a space after the city, such as:
  99.             CHICAGO IL
  100.     I originally considered putting STATE as a
  101.     separate field, but BASIC/E files use quotes
  102.     around each field, and separate fields by
  103.     commas.  Thereore, a 2 byte state field would
  104.     take 5 bytes.  There just wasn't sufficient
  105.     room in a 128 byte record.  (Although recall
  106.     that I now realize the record length does not
  107.     have to be restricted to 128 bytes.
  108.  
  109. ZIP:    5 byte numeric zip code
  110.  
  111. PHONE:    10 digits, with parenthesis, spaces, and dash, as:
  112.     (312) 555-1212
  113.  
  114. COMPUTER:    A 5 byte field used to keep track of the 
  115.     computer owned, such as A8800, IMSAI, DGZ80, etc.
  116.  
  117. PAID:    A 2 byte field showing when membership is again due,
  118.     in the form YYMM such as 7809
  119.  
  120. TYPE:    A 1 byte 'type of member' field.  Currently used:
  121.     G    Group (another computer club)
  122.     M    Magazine
  123.     H    Hobbyist
  124.     V    Vendor
  125.  
  126.     These are arbitrary values, however the REPORT
  127.     program, when printing name tags for a meeting,
  128.     will not print tags for type G or type M.
  129.  
  130. --------------------PREFORMAT PROGRAM--------------------
  131.  
  132. This program preformats the file.  It writes records
  133. with a '0' flag byte, i.e. empty records.  From then
  134. on, the Maint program is used to add, change, and delete
  135. members of the file.
  136.  
  137. ------------------MAINTENANCE PROGRAM--------------------
  138.  
  139. This program maintains the file.  It has the following
  140. commands implemented to do so:
  141.  
  142. MACRO:    Allows issuing a string of up to 10
  143.     commands, over and over.  Useful for
  144.     doing such things as scanning the
  145.     file for a certain field
  146.     value, then changing the value,
  147.     and doing it over and over.
  148.     FORMAT:    MACRO
  149.     You will be prompted for input.
  150.     When running in MACRO mode, a DEL
  151.     from the keyboard will stop execution
  152.  
  153. HELP:    Prints a summary of the commands
  154.     available.
  155.  
  156. FIND:    This is the ONLY command which
  157.     accesses the file thru the randomizing routine.
  158.     FORMAT:  FIND name   where name is the
  159.     exactly spelled name of a person in the file.
  160.     EXAMPLE: FIND WARD CHRISTENSEN
  161.     The name is arithmetically hashed to a record
  162.     number.  The file is scanned from that record
  163.     number forward (wraps from end to beginning)
  164.     until a matching name is found.  You can press
  165.     DEL at any time to stop the scan and return
  166.     to command mode.
  167.  
  168. READ:    This command is used to read a particular
  169.     record in the file by record number.  It is
  170.     not frequently needed.
  171.     FORMAT:  READ recno
  172.     EXAMPLE: READ 20
  173.  
  174. DUMP:    This command sequentially dumps the file
  175.     from a given starting record number.
  176.     Press DEL to stop the dumping.
  177.     FORMAT: DUMP recno
  178.     EXAMPLE: DUMP 155
  179.  
  180. C:    This command is used to change the contents
  181.     of a field in the record most recently read
  182.     into memory.  It can change an entire field
  183.     by replacing it with a new value, or can do
  184.     a character string replacement such as to correct
  185.     a misspelled field value.
  186.     FORMAT: C fieldname newvalue
  187.     EXAMPLE: C NAME J. SMITH
  188.     The field name can be abbreviated.  The
  189.     table of field names in the program will
  190.     be searched until the first 'n' letters
  191.     of a name match the 'n' letters in the field name
  192.     used in the C command.  N is therefore a sufficient
  193.     abbreviation for NAME, but C will find CITY
  194.     and not COMPUTER, so use CO for COMPUTER.
  195.  
  196.     FORMAT: C fieldname /oldvalue/newvalue/
  197.     EXAMPLE: C N /TIANSON/TENSEN/
  198.     The above example would change WARD CHRISTIANSON
  199.     to WARD CHRISTENSEN.  The closing '/' is
  200.     optional.
  201.  
  202. LIST:    Used to list the contents of the record
  203.     most recently read into memory.
  204.     FORMAT: LIST
  205.  
  206. ?:    This command is used to scan the disk
  207.     from the current position (the last record
  208.     number read) for any field matching a value
  209.     placed in the command.  Only the first 'n'
  210.     characters of the field on disk are matched,
  211.     where 'n' is the number of characters given
  212.     in the command.  The match always starts
  213.     with the leftmost byte of the field.
  214.     FORMAT: ? fieldname value
  215.     EXAMPLE: ? CO ALTAIR
  216.     The contents of each field read will be
  217.     displayed whether or not it matches.
  218.     Use DEL to stop the scan.
  219.  
  220. F:    This command (Find) works like C
  221.     except that the field read from disk is scanned
  222.     for a match at each position in the field, not
  223.     just the first.  For example, if everyone
  224.     in the club having a Z-80 computer has
  225.     a 'Z' somewhere in their COMPUTER field,
  226.     but it differs from user to user (such as DGZ80,
  227.     IMSZ8, Z2, etc.) then you could find
  228.     someone with a Z80 by saying:
  229.     F CO Z
  230.     FORMAT: F fieldname charstring
  231.     EXAMPLE: F STATE IL
  232.     NOTE this runs 'lots' slower than '?' because
  233.     of multiple comparisons being done on each
  234.     field.
  235.  
  236. WRITE:    This command is used to randomize and write
  237.     a record to disk.  It is used after the ADD
  238.     command, or when changing someones name.
  239.     See "CHANGING A NAME" below.
  240.     FORMAT: WRITE
  241.  
  242. ADD:    This command is used to add a new name
  243.     to the file.  You will be prompted for each
  244.     field.  If a field is blank, you cannot just
  245.     press C/R because BASIC/E will give you a
  246.     WARNING II message.  Therefore, put in 1 space
  247.     the press return.
  248.  
  249.     If you want to stop the ADD function, such as
  250.     if you realize you made a mistake and don't
  251.     want to go back and change it with the C function,
  252.     type QUIT in response to any input.
  253.     FORMAT: ADD
  254.     You will be prompted for the input.
  255.     NOTE the record is only built in a matrix
  256.     in memory, and that the WRITE function must be
  257.     executed to actually write the name to disk.
  258.     This allows using the C and LIST command to
  259.     verify and change the contents of the record
  260.     before writing it to disk.
  261.     Also, see "CHANGING A NAME" below.
  262.  
  263.     There is one problem when adding records to
  264.     the file, and that is that you cannot add a record
  265.     which exceeds the record length.  BASIC/E will
  266.     unforgivingly issue an ER error and drop you
  267.     back into CP/M.  Due to the preallocation of the file,
  268.     however, this is not serious as only the record
  269.     currently being added is lost.  A 'lot' of
  270.     code could be added to add up the lengths of each
  271.     field, plus 1 for the flag, plus 3 for each field
  272.     (the quotes around the value, plus the comma separating
  273.     values) but I just decided not to bother.
  274.  
  275. ERASE:    This command will erase the record most
  276.     recently read.  The record will still remain in memory
  277.     such that a WRITE command could be used to write
  278.     it back to disk, as would be required with a name
  279.     change.
  280.     FORMAT: ERASE
  281.  
  282. UPDATE:    This command writes a record BACK to disk, and
  283.     is used following a FIND or READ command.  Npote
  284.     that if used after an ADD command, you will overlay
  285.     the wrong record.  You must use WRITE after ADD.
  286.     FORMAT: UPDATE
  287.  
  288. FREE:    Used to determine how much memory is left
  289.     during the running of the MAINT program.  Used
  290.     during program development to see if room remained
  291.     to add more function
  292.  
  293. PURGE:    Used to purge the file of records whose memberships
  294.     have expired.  The file is scanned for a matching
  295.     date (PAID field) as given in the command, and
  296.     all records matching are deleted.  It is suggested
  297.     the printer be turned on before issuing the PURGE
  298.     command to keep an 'audit trail' of who was purged.
  299.     FORMAT: PURGE yymm
  300.     EXAMPLE: PURGE 7709
  301.  
  302. END:    Used to end execution.  Control-C can also
  303.     be used, as the file doesn't have to be closed,
  304.     because it is pre-allocated.
  305.  
  306. CHANGING A NAME: Since the file is written by randomizing
  307.     the name field, you cannot simply FIND someone, use C
  308.     to change their name, and UPDATE the record.  Why?
  309.     Next time you want to find them, you will type
  310.     FIND newname and will randomize to it.  However,
  311.     the name is stored under the randomizing of the
  312.     OLD name.  Therefore, after changing a name,
  313.     issue an ERASE to get rid of the old record, then
  314.     WRITE to re-randomize the new name and write the
  315.     record.  This works because ERASE doesn't change
  316.     the contents of the record maintained in the
  317.     matrix in memory.
  318. --------------------SORT PROGRAM--------------------
  319.  
  320. The sort program is an assembler program which reads the
  321. mailing list, extracting the first 5 characters of a
  322. specified field, and doing a memory-resident bubble sort
  323. of the field and it's correspoiding record number.
  324. It then writes an ASCII file of just the record numbers.
  325. It is currently set up for 3 byte record numbers,
  326. but may be easily changed for 4 byte record numbers.
  327. (Comments in SORT.ASM show how).  The file of record
  328. numbers is then used in the REPORT program to process the
  329. file in the sequence asked for.  The index file is read
  330. into a table rather than accessed sequentially, for speed.
  331.  
  332.     FORMAT: SORT infilename outfilename fieldnumber
  333.     EXAMPLE: SORT CACHE.FIL NAME 1
  334.  
  335.     Note that 'outfilename' can be any valid
  336.     CP/M file name.
  337.  
  338.     The field numbers currently implemented are as
  339.     follows:
  340.  
  341.     1.    SORT
  342.     2.    NAME
  343.     3.    ORGANIZATION
  344.     4.    STREET
  345.     5.    CITY
  346.     6.    ZIP
  347.     7.    PHONE
  348.     8.    COMPUTER
  349.     9.    PAID
  350.     10.    TYPE
  351.  
  352. --------------------REPORT PROGRAM--------------------
  353.  
  354. The report program is used to produce listings,
  355. mailing labels, and name tags.  The listings can
  356. be either 130 columns wide, or can be printed with 2
  357. lines for each person, on 8.5 wide paper.  Name tags
  358. and Labels may be printed 3-up or 4-up, with variable
  359. width and height labels.  It is currently written for a
  360. Centronics 101 with the feature of expanding the width
  361. of characters when you print CHR$(14).  If you do
  362. not have this facility, the program will have to
  363. be changed.  Note this affects only the printing of name
  364. tags (which print the name and computer double width)
  365. and the title of the report.  Also the program prints CHR$(11)
  366. (Vertical Tab) to eject the paper to a new page.  If you
  367. do not have this feature, you will have to insert the proper
  368. number of null print statements to cause an eject to the
  369. next page.  Some printers may require CHR$(12)
  370. (Forms Feed) instead.
  371.  
  372. Since there is not currently a way to turn on the
  373. printer from BASIC/E, this program requires a CBIOS
  374. with manual printer control, such as thru a sense switch,
  375. to operate correctly.  The program prompts you with
  376. 'press linefeed' which then allows you time to
  377. turn on the sense switch.  When it sees the linefeed on 
  378. the keyboard port, it starts the listing.
  379. When the listing is complete, it awaits a 'del'
  380. from the keyboard before continuing.  This again gives
  381. you time to turn off the sense switch controlling the
  382. printer.
  383.  
  384. The commands currently implemented in the program are:
  385.  
  386. HELP:    Prints a summary of commands available.
  387.  
  388. INDEX:    Names the file of record numbers (output
  389.     from the SORT program), and causes the file to
  390.     be read into memory.
  391.  
  392.     FORMAT: INDEX filename
  393.     EXAMPLE: INDEX NAME.FIL
  394.  
  395. POSITION: Positions the file to a particular
  396.     record relative to the INDEX file which has
  397.     been read.  Used to restart a listing, or
  398.     to scan for starting the listing in the middle.
  399.     It can position either by record number, or
  400.     by the contents of the field sorted upon.
  401.  
  402.     FORMAT: POSITION recno
  403.     EXAMPLE: POSITION 55
  404.             or
  405.     FORMAT: POSITION fieldname fieldvalue
  406.     EXAMPLE: POSITION ZIP 60419
  407.  
  408.     In the first example, the file is positioned
  409.     to the 55th record in the index
  410.     table.  In the second example, the file is
  411.     sequentially read (from whatever position is
  412.     currently is at) until a zip matching 60419 is
  413.     found.  You may find it useful to use the
  414.     first format to get 'close' because positioning by
  415.     record number is fast, then use the position by
  416.     field value until the exact one is found.
  417.     NOTE that it is somewhat meaningless to POSITION
  418.     on a field which is not the sort field, as the
  419.     field being positioned upon is not read in order.
  420.  
  421.     NOTE if you stop the listing, then want to
  422.     restart it from the beginning, you must
  423.     issue POSITION 1 to start over again.
  424.  
  425. TITLE:    This command is used to supply a title
  426.     for the listing.
  427.  
  428.     FORMAT: TITLE any character string
  429.     EXAMPLE: TITLE SEPTEMBER MEETING ALPHA LISTING
  430.  
  431. PRINT:    This command is used to initiate the printing
  432.     of a listing.  The listing will be either:
  433.     72 columns wide if width < 80, or
  434.     132 columns wide if width > 79.
  435.     Other than being less than or greater than 80,
  436.     the setting of width does not effect the output
  437.     of the PRINT function.
  438.     FORMAT: PRINT
  439.  
  440. WIDTH:    Sets print width.  The meaning of the width
  441.     depends upon the function being asked for:
  442.  
  443.     TAGS or LABELS - the WIDTH setting is the actual
  444.     number of characters wide the labels are.
  445.  
  446.     PRINT - the WIDTH setting determines the report width
  447.     but only as to whether width is <80 or >79.
  448.  
  449.     FORMAT: WIDTH nn
  450.     EXAMPLE: WIDTH 36
  451.  
  452. LENGTH:    Sets the length of the gummed
  453.     labels used for the LABELS or TAGS function.
  454.     Default is 6 lines long.
  455.  
  456.     FORMAT: LENGTH nn
  457.     EXAMPLE: LENGTH 5
  458.  
  459. TAGS:    Initiates the printing of name tags.
  460.     An algorithm is used to split the first name
  461.     from the last name:  The name is scanned from
  462.     the back until a space is found.  The part
  463.     of the name to the right of the space is now
  464.     considered the last name, and the part to the
  465.     left the first name.  Then, certain 'reasonableness'
  466.     tests are performed:  If the first 2 letters of the
  467.     last name are JR, then the scan continues again
  468.     to the left.  Then, the last few characters of
  469.     the 'first name' are checked to see if they are any
  470.     of the common double word last names, such as
  471.     ' VAN' or ' DE' or ' DI' or ' MC'.  If so,
  472.     scanning continues again.  You might have to change
  473.     this algorithm depending upon the names you encounter,
  474.     such as 3 word names (VAN DER HEIDE) or VON, or
  475.     the myriad of names I have not yet dreamed of.
  476.     FORMAT: TAGS
  477.  
  478. LABELS:    This initiates the printing of mailing labels.
  479.     It uses the settings of WIDTH, LENGTH, and UP
  480.     to determine the physical format.
  481.  
  482.     A typical label is printed as follows:
  483.  
  484.         FERN P. DOCK        7709
  485.         HENWAY CORPORATION
  486.         BOX 1234
  487.         FERNWOOD OH        12345
  488.  
  489.     (What's a HENWAY?   about 3 pounds).
  490.  
  491.     Note the PAID date is printed in the upper
  492.     right of the label.
  493.     FORMAT: LABELS
  494.  
  495. CHECK:    This function checks the setting of the
  496.     various variables, such as what record
  497.     you are positioned to, whether an index has
  498.     been read or not, and the current settings
  499.     of: WIDTH, LENGTH, etc.
  500.     FORMAT: CHECK
  501.  
  502. UP:    This is used to cause printing of LABELS
  503.     or name TAGS 3-UP or 4-UP.  (UP referring to
  504.     how many labels are printed side-by-side.
  505.     The program has not been generalized to handle
  506.     1-up or 2-up.
  507.  
  508.     FORMAT: UP n
  509.     EXAMPLE: UP 3
  510.  
  511.     3 or 4 are the only values supported.
  512.  
  513. END:    Causes ending of program execution.
  514.  
  515. --------------------MISC. COMMENTS--------------------
  516.  
  517. Use abbreviations to keep the width of each field
  518. within the width allowed in the report program,
  519. or else the TAB to the next field will cause an extra
  520. line to be printed.  This will offset the line counter,
  521. and may cause the program to print a page which is too
  522. long.
  523.  
  524.