The Greene Machine Bulletin Board System


     Thank you for not buying a Bulletin Board Program!  I think you will find that The Greene Machine will do just about everything you want a system to do and the price is right.     This introduction will take you through the basic setup of the program and then we will take each section and look at it a little more closely. Also, you will find a section on the various important variables used in the program, file structure, and some hints on how to modify the thing to your own needs. There will also be detailed instructions on how to set the whole thing up and how to maintain the system. We have been running this system in its various forms since 2/3/82 and have not had any problems that were not Sysop caused! Just remember, keep those disks backed up and if you do modify the program, test-test-test, before putting the new version on-line!!!


Basic Program Structure
     The program has been written in several parts and runs as a series of overlays. This was needed to stay within the memory available on the TRS-80. Here I will discuss the basic modules that go into the BBS. Files will be covered in another section.


DRIVER/CMD
     This program provides 2 functions. It is the RS-232 driver and it includes a Lineinput routine. The RS-232 driver patches itself into the Keyboard and Video Device Control Blocks and sets its own High Mem pointer. The entire program loads starting at X'FC00. The reason behind the Lineinput routine is this. There are 2 ways of inputing a line of characters, either you use DOS lineinput command or you can use an Inkey$ to build an input string. The lineinput is great, but it does not check for carrier and it does not check for a lack of input timeout. Building a string using Inkey$ will allow all of these functions, but it is SLOW. We will discuss the use of this function in a separate section.


ENTRY/BAS
     This module is the program that waits for an incoming call and provides certain SYSOP functions.


COMMAND/BAS
     This is the main command routine of the BBS. It acts to call the other BBS functions and guides a user through his call.


MESSAGE/BAS
     The message entry and recovery section of the BBS.  This is the heart of the program. Included in this module is both the open messages and the private mail section.  Access to each message base is allowed or denied by the sysop.


DLMOD/BAS
     This module controls up/downloading and depending on your system configuration will have to be changed. Its main function is to accept a filespec and call in MODEMBB1/CMD.


MODEMBB1/CMD
     This is the bulletin board host package for the MODEM/CMD public domain terminal program. This program does the actual file transfers.


PACKER/BAS
     The textfile packing program. The use of this program will be detailed later.


BLDMENU/BAS
     A short routine that will permit you to automatically build your download menu.


MODEM/CMD
     The public domain terminal program. Not used in the BBS but you can give it to anyone that wants to transfer files with you.


NOBUG15/BAS
     A very handy program used to generate text files such as the system help and system info files.  Also great to build messages to send to other Bulletin Boards.  This is an easy to use mini-text editor and is public domain.



     The rest of the program is made up of the various text and directory files that hold the actual messages. The structure of these will be covered later. Now we will look a bit closer at each of the modules and try to see how they work.


DRIVER/CMD
     You will find a DRIVER/CMD and DRIVER3/CMD on the main BBS disk. The DRIVER3/CMD is for Mod III's and DRIVER/CMD for the I. Once this program is loaded, you forget it. It patches into the Keyboard DCB at X'4016 and the Video DCB at X'401E and its operation is fully automatic. The part of the program that concerns you is the lineinput routine.  This routine requires several variables to be POKED into memory. The variables determine if upper/lower case or upper case only is to be accepted by the program, the length of the string that can be input (up to 63 characters), if video is to be blinded for passwords and such and if it is a LOCAL entry, turn off carrier detect and system timeout functions. The variables used are these:

FK - if a (1) then local entry, (0) remote entry.

BL - if a (1) blind the video, automatically returns to (0) after use!

LS - length of the input string.  May be 1 to 63 characters.

FC - if (0) then accept upper and lower case, (1)= upper case only.

If you are adding a function to the system and you want only an uppercase string of 20 characters, you would set LS=20:FC=1 and GOSUB to the input routine. Coming back from the routine you will return with IN$ if all went well, if there was a loss of carrier or the 6 minute period was exceeded, the system will automatically reset. I recommend the use of this function to add any new commands to the system. It is easy to use and we will look at a specific example when we look at the COMMAND/BAS module. Once the length of the string has been reached (LS=X) the system will not accept any further input and will send a Control G back to the caller on each keystroke. This routine also masks out all control functions that can play havoc with your system! Formfeeds, breaks and such are removed before the system can see them. The only control functions that are accepted are Control S and Control Q and these are needed for some of the printing terminals that have a limited buffer. There is a chance of system hang if someone sends a Cntl S and then drops carrier. This happens to us about once a month or so and we hit the reset and live with it. If you are having a lot of trouble with this, let me know and I will give you a fix for the trouble or load DRIVER/ASM in EDTASM and find INXLAT and change the 96 (Shift @) to a null (0) and reassemble the program. Also included in the program is a variable nulls after carriage return. This is for slower printers and is user accessed from the main menu.


ENTRY/BAS
     The ENTRY/BAS program provides initial entry into the Bulletin Board. It also provides SYSOP access to various functions such as returning to DOS, setting Date & Time, Intializing Chat, Local Logon, and permitting Non-sysop Local Logon. These functions are available using a keyboard scan routine. Most of these are self-explanatory. The <N> access to the system permits a person other than the Sysop to logon from the keyboard. The <N> command goes through the same procedure as a caller over the modem will use.  The <L> command is strictly for Sysop use. The use of this command does not increment the call counter, so that you will have a more accurate tally of callers and it does not enter Sysop in the Userlog. This eliminates seeing Sysop 50 times a day in the Userlog.     Of course the main purpose of this module is to logon callers. Thats why we are running this thing, isn't it?  The system permits two caller types, ID'ed users and first time callers. System entry is pretty straight forward. If an ID'ed user forgot his Account Number, he is able to use the system to find it again and log on. After entry the Logfile and Chatflag are updated and a record is made on your line-printer. Once the caller has identified himself, control is passed to Command/Bas. Error trapping in this routine includes names over 40 characters long, people that can't remember their name, people trying to find someone elses logon code through a hit and miss technique and the normal loss of carrier and system timeout. While first and last names are allowed to 20 characters each, the overall Name$ will not permit more than a total of 20 characters, and will generate an error. We have found that people entering more than 20 characters for a name are trying to bust the system and they are not-very-gracefully dropped.   There is not much you can modify in this section except for the initial sign on message and such. We have found that users do not like very wordy or cute intros as it costs too much in long distance phone bills. Keep it short and to the point!


Command/Bas
     Since this module controls most of the operation of the BBS, we will spend some time taking it apart and seeing what all it does and how it does it.     Input to the entire system is through the lineinput routine of Driver/cmd. The actual method of inputting data can be seen in line #40-100. The first thing is poke various variables into memory for the use of the routine.  Once again the variables used are:

BL -  blanks video display if (1), normal display if (0).   Always reset to (0) after use. (line 60)

LS - Length of string. Must be set to a value between 1 and 63. This is the actual size string that the system will accept.

FK - Set to (1) if carrier checking and lack of input timeout is to be disabled. This is not normally done except for Sysop entry from the keyboard.

FC - If (0) then accept upper and lower case input. If (1)  convert all input to upper case only. The helps eliminate those "if a$="A" or a$="a" type lines in the program.

The rest of line 60 gives the Defusr address and calls the subroutine.  Line 50 does the checking for various conditions returned from the subroutine. If X is (0) (this is a value passed from the subroutine back to BASIC), all is OK. If X is (1) then we have lost carrier and if X is (2) the lack of input timer has expired. Both of these conditions will cause a jump to line 70, Lprint an error message and RUN"ENTRY/BAS" resetting the system for the next call.     On a non-error return from the subroutine (X=0) we jump to line 60. This line fist sets BL back to (0), sets the IN$ to a null string and finds the location of IN$ (varptr). A quick idea of what actually takes place in the machine language lineinput routine is now needed. We have told the system how many characters to accept into the string (LS=X), but this does not mean that many characters were actually used. The driver counts characters and saves this count at &HFC42. The actual buffer that holds the characters is located at &HFC00. For those of you not familiar with the VARPTR command, this points to the address where a string can be found. The first byte returned on VARPTR is the length of the string and the next 2 bytes point to the location of the string. What is done in line 60 is clear the IN$, find its location in memory, poke that location with the contents of &HFC42 (length of string in buffer) and poke the next 2 locations with the address of the buffer (0,252 is actually &HFC00 in decimal with the low order byte first). We have now converted IN$ to the keyboard or RS-232 inputy and pass this back to the program. Lines 70-90 are the reset function and line 100 gives the <=== after a single key input (LS=1) is received. To show the actual operation of this process, look at line 190. This line permits the SYSOP to enter Basic with a password (BINARY), we are setting up for video blanking, (BL=1), upper case only (FC=1) and 5 characters (LS=5). We then gosub 40 and return from the subroutine with IN$ which is checked for the password. This is how all input to the system is handled and I recommend you stick with it so that you may easily perform carrier checking and time out functions. I tried using a LINEINPUT routine from BASIC fora while, but loss of carrier would hang the system. The routine is easy once you study it for a while and makes for a consistant data entry format.     Now to get back to the rest of the program.... The monster of a statement at line 10, DEFFN is used for editing message input. This is a Boolean expression that compares 3 strings and will be discussed later. This is needed to insure various conditions and I am not sure that even I understand it anymore! Line 20 sets up 2 AD$ strings. These are the command strings used in this sectionof the program. There are 2 AD strings, because one is used for the SYSOP and the other for all callers. We might as well talk about levels of access to the system at this time. Through out the program you will see PR$. This is the priority string and defines what a caller can and can not do. The SYSOP has a PR$="AZ" and all other callers have PR$="AA" to PR$="AK". The ones I use are:

AA = new caller
AD = caller with an ID, can access the OPEN section
AE = caller with ID that can access the X-rated section
AK = caller with ID that can access the Couples section
AZ = SYSOP
     The names of these sections can be changed to whatever you wish and I will show you where and how. For example  you could use the OPEN section as is for all callers, the X-rated section for those that have an ID with the system and the Couples section for club members or friends. The level of access granted a caller can be determined by the system or left strictly in the control of the SYSOP. This method is much more secure than a password based system.  If a caller does not have the access priority, he does NOT get into that section.     Line 110 is a good place to return to from any subroutines that you may enter. It closes all files, clears the stack (CMD"F=POPS" and reinforces error trapping. From this line the main menu is displayed (XP=0) or the eXpert menu is shown (XP=-1), from either line 280 or 250. Line 120 LPRINTS the CC$. This string is used for error reporting and message entry and gets dumped to the printer when over 200 characters long. Line 150-170 get the command and check it out against the Command string (AD$) and feed control of the program to the various sections. Line 180 lets the SYSOP use R to return the program to "ENTRY/BAS" and 190 allows entry to BASIC. 200 is the eXpert Toggle. 210 goes to Message/Bas with MB=1 (MB determines which message base will be accessed. See the description of MESSAGE/BAS for info. 220 - 240 is the termination routine, with message to SYSOP 250-280 is the command menu. 290 controls number of NULLS after a CR/LF for slow printers. This is normally set to 0. 300-320 is a TIME ON SYSTEM routine called from the T command and from the termination routine. 330-380 is a disk text file routine that will access the USE file (H command) or the INFO/PCL file (S command). If you wish to have a lot of textfiles on your system you might consider a single command in the main menu & build a submenu here. This section will open the file and extract the data 1 line at a time checking for a <P>ause or <A>bort using an INKEY$. 390-430 is the Chat function. It checks to see if SYSOP is available for chat and if so sends a horrible tone out the cassette port. If the "A" key is pressed and held down, the page will be answered, else in a minute ar so the "SORRY, SYSOP DOES NOT ANSWER..." message will print to the screen and control will bo back to line 110. Chat itself is a continuous LINEINPUT (used here because YOU will see loss of carrier and can reset the system if carrier is dropped), check for END and clear the string to get next line of chat. This method seems to avoid most of the garbage collection found on  other systems (keyboard locks while string handling takes place). 440-530 prints the USERLOG. The userlog contains the names, location and date/time of the last 100 callers. It is made up of a circular queue, the pointer to which is saved in the file CHATFLAG. The LOGFILE is access thru 2 nested FOR-NEXT loops. Special cases are required if the SYSOP has logged on locally (CHATFLAG is not accessed from ENTRY/BAS (FK=1) or if the pointer and the number of entries in the LOGFILE are the same. This is the case for the first 100 callers and then occurs every 100 callers after that.  Don't worry about it, the program takes care of the LOGFILE without any work from the SYSOP! 540-550 enters and LPRINTS the termination message for SYSOP. Message entry will be covered in MESSAGE/BAS. 560 The timing loop if <P>ause is hit during data recovery. 570-700 Message entry and edit routine to be covered in MESSAGE/BAS. 710-810 This access the various lists of telephone numbers, searches the list and prints the numbers out. There are 3 listings of numbers, OTHER, OTHER1 and X-rated. If you wish to change these lists, some conventions in format must be maintained. See the entry for these lists for details. 820 This is a SYSOP function that allows a DOS command to be entered (O from main menu). 840-1140 Logon request <Z> command. This routine checks for a logon code and and accepts the required data for a logon code. This section can be modified for your own requirements. Just keep the format the same and you won't have any trouble. Line 1000 checks for the requested level of access and assigns PB$ to it. It also changes PR$ (Priority string) to that value. The       only exception is for Couples access. AK must be given by SYSOP. If you want complete control over who does what, change PB$ from AE or AD and put it at AA (newuser) until you do whatever checking you want. 1030-1080 places the info in the ID file and Lprints it. 1090-1130 is a special case for Couples access. WE require special info and use this format. 1140 is FUNCTION ABORTED and returns to the main menu. 1160 Calls the DLMOD/BAS for file transfer. 1170 Calls MESSAGE/BAS with MB=4 (Electronic mail). 1180-1550 This is a mini-data base manager for SYSOP use. It is used to examine, modify and kill ID file accounts. This is menu driven and pretty much self explanatory. The ID file entry is broken into several sections. 1 byte  A or K- Active or Killed account. The program looks at this when assigning an account number. 14 bytes This is the users password to the system. 20 bytes Users name. 20 bytes User location. 12 bytes User telephone number. 2 bytes User access priority (AA, AD, AE, AK or AZ). 8 bytes Date of last call. The menu entries are these. 1 - List entire list -  send the entire file to lineprinter. 2 - List specific account- List info for a single account. 3 - Kill Account. Changes A to K for a single account if requested. You may answer Y to kill/N to leave alone or Q to jump back to menu. 4 - Search List A name search only. Enter any name and it will give you the account numbers for that name. This uses an INSTR function so if you enter a single letter it will find all names with that letter. (Enter S and it will print the name Smith or Johnson or so on). 5 - Change Info This is the update portion of the manager. Enter the account number you want to change and it will print the current info on that account. Enter the number of the item you want to change, the new data and press enter. Use an 8 to update the disk file. 6 - Return to BBS Returns control to the BBS. 7 - List Highest Account - Tells how many accounts are active in     system. 8 - Kill Multiple Accounts. Asks for a starting number to start the Kill function and then steps through 1 at a time and gives you the option of killing the account, passing it by or quiting. This section of the program is accessed by SYSOP COMMAND <B>. I realize that many improvements can be made in this section and it is kind of weak. It has served my purposes well for the past 8 months, but please feel free to make any changes you feel necessary. 1560-1570  This is the error trapping section of the program. It will print the error to the screen for someone with an access over AA and adds the error to the CC$. It is pretty effective and recovers from all errors without bombing the program. That pretty well covers the COMMAND/BAS section of the system. The DLMOD/BAS and MESSAGE/BAS are a snap compared to this and will be covered next.


MESSAGE/BAS
     The MESSAGE/BAS module controls entry and retrieval of Mail, Bulletins and Discussions. Before going to the program we will spend some time on the structure of the disk files and how they are used. Each message base has several files attached to it, xDIRFILE, xTXTFILE, xDISCDIR and xDISCn. The "x" signifys which base we are in; if x=C,then the Couples section; x=X,the X-rated; x=M, Mail section and x=null, the Open section. The n in xDISCn is the number of the discussion section.     The xDIRFILE acts as a pointer and directory to the xTXTFILE. Each entry in this file is 63 characters long and divided like this; 1 byte for a marker flag D=DISC, M=MAIL, B=BULLETIN, X=KILLED File. 20 bytes for The Addressee if Mail or Subject if Bull or Disc. 20 bytes for FROM 17 bytes for Date/Time. 4  bytes giving the pointer to the xTXTFILE. 1  byte to show if Mail is unopened or not. "*" denotes unread Mail, else it is a null string. The 4 bytes acting as a pointer actually point to the 1st and last line of the position of the message in the xTXTFILE and are HEX digits. The xTXTFILE entry is made up of 64 characters 2 bytes show the length of the following string 62 bytes are the message line.     The DISCUSSION section is a special case. Each DISC is a sequentially accessed file and when a user adds to the file, his comments are appended to the end of the appropriate xDISCn.     Now that you have a deep understanding of the data structures used, we will take a look at the actual program. This time we will not go line by line, but follow a logical flow for message entry and retreival.

10     This is the monster DEFFN used later on in the EDIT mode.
20-50 These lines set up AA$, AB$ ,AC$ and AE$ for the files we will be working with.
60-120 This is the normal data entry routine discussed previously.     We enter the module with MB=1 or MB=4. If MB=4, Mail function is specified. The program will fall through to line 50, AA$ will be set to MDIRFILE and AB$ to MTXTFILE.  If MB=1, the program will go to line 20 and set the strings to their specified names. Entry is always made to the OPEN section or the MAIL section. All checking for access permission is done later on. We will assume a user is coming in to read the Bulletins and will post one.     From Line 20 a jump is made to 130.  130 has a gosub 310 which prints the Menu and asks for selection and returns to 140. In this case, we have selected <B> for the Bulletin section. The program will continue to line 150 and jump to 250 for the Submenu. Here we select <R> to read the Bulletins. Line 270 feeds control to line 700. 710 jumps to 920 if Discussion was selected. The selected DIRFILE is opened and the number of messages in that section is displayed. The next submenu is displayed and we will       assume a single message is to be read. Both DIRFILE and TXTFILE are opened, the message number is checked to make sure it is valid, and the DIRFILE entry for that number is retrieved. In line 840 the header for the message is set up, and in 850-880 the message is pulled from the TXTFILE using the pointers found in the DIRFILE. Message entry follows the same general path. A gosub is made to line 1050 where the option of a FORMLETTER is permitted. If you wish to send the same letter to several people, once you have written the letter you may send it as many times as you like to different addresses. The SYSOP may enter 50 lines of text, while the rest of the users are limited to 16 lines. A loop is set up entering data into M$(L) array, the L is bumped and entry continues until a Carriage Return on a blank line or the number of allowed lines is reached.     Once entry has finished, the option to Save, Edit, Abort, etc is given. The EDIT command uses the DEFFN we defined in line 20. The Edit takes place in line 1150-1180. A check is made for valid line number, the old text is entered, the new text is entered and then the FN is run.  This function verifies that the old string actually exist, and that the new sting will not exceed the 62 character limit. If these conditions are met, the substitution is made, and a jump is made back to the submenu. The <S> command returns to line 390 and each individual line is stashed in the TXTFILE. The sequence is the same for all the various message bases and <E>lectonic mail. The only special case is the Discussion section. The Discussion files use the DISCDIR file to locate subjects, but since they are sequential files, they must be read from beginning to end. The <S>kip command permits jumping to the next entry in the file by searching for the line "Comments by ....". Text to the Discussion is saved with an OPEN"E" to extend the file. Depending on the number of Message Bases you wish to have on your system, you can change the various menus to reflect the number and names of the sections.  Also, by modifying the PR$ at lines 220 and 230 you may allow or deny access to various sections. For instance, if you want 2 message bases named Open and Club, use the CTXTFILE, CDIRFILE, CDISCDIR and CDISC files. Delete MB=3 at line 40, change the Menu at Line 320, delete 220 since you will not use MB=3, and decide what level of access will get into the CLUB section in line 230 (here it is set for PR$>"AE"). This allows you to have a private section for Club members only or whoever you wish to allow access.     The <E>lectronic Mail is very private and users must be sure to enter the name of the recipient EXACTLY as it appears in the Userlog or the recipient will never know that there is mail waiting. The SYSOP may go into MDIRFILE with SUPERZAP or SUPER UTILITY and change names in case of spelling errors or such. This is up to you and you will have to decide if you want to clean up after your users.     You will notice that lines 350, 1190 and 1420 are REM lines. We have run into occasions that some users like to junk up files with objectionable entries. By removing the REM "'" from these lines you can deny message entry to those people that don't have a LOGON code for the system.  This gives you the ability to limit message entry to only those that have taken the time to establish a logon code and are known to you. I don't recommend this unless absolutely necessary. When starting a new system, you need all the messages you can get. We have had some problems with callers and have found out that if you limit entry for a couple of weeks the pests disappear and don't come back.  Use this feature at your discretion.


DLMOD/BAS
     This is a short program that acts as a driver for Modembb1/cmd. The main purpose of this program is to allow a user to see the download menu and act as an interface between the user and Modembb1/cmd. You may notice some references to MODEM80/CMD and the host for MODEM80, XMODEM/SOP. These file transfer protocols DO NOT yet work with the BBS, but I am working on the problem. To use this module, you must have built a textfile called MENU that contains the names of the programs you have available for downloading (See a later section for information on BLDMENU/BAS).

DOWNLOADING     The normal input routine is found at lines 20-80. The user will view the download menu in lines 520 - 550. The main menu is found in lines 140 -150. If downloading is selected, a jump is made to line 270. Here the file name of the program to download is entered, and the user is prompted on the action he should take on his end. A DOSCMD is executed and Modembb1/cmd takes control. After the completion of a successful or termination of an aborted transfer, one of the codes in lines 410-460 is printed to the screen and control jumps back to the main menu.

UPLOADING     Upload works the same way except that the string that is built strips off the /ext that the user adds and includes the extention /UPL. This prevents someone from messing around with your system by sending files with a /CMD or /SYS which might cause problems!!! The only modifications you should have to make in this module is in lines:
200, 350, 500 and 530. These lines have a :2 in them to specify the disk that programs will be transfered to and from, and you may wish to change them to your configuration.


Miscellaneous Files     There are a few other files on the system that might not have been mentioned elsewhere. Others, Others1 and Xrated are lists of BBS's. Transfer will list some info on file transfer. Explain gives some info on the logon procedure. Use and Info/pcl are the Help and System Info files. Use NOBUG15/BAS to modify for your system.
                                                             