TITLE PREG.MAC v4.51 Jul 30/89 ; Filename PREG45.MAC ; Author Terry Pinto ; Language Z-80 Assembler ; Last Update May 02/89 ; By Terry Pinto ; Following are two examples of the assembly and linking process using ; two of the more popular assemblers today. Make sure that you set the ; appropriate equate in PBBSEQU.HDR. ; Assembly/Link - Using M80/L80 ; M80 =PREGnn/N ; L80 /P:100,PREGnn,PBBSUBS,SYSLIB/S,PREGnn/N/E ; ; Using SLR180 ; SLR PREGnn ; SLRNKP PREGnn,/A:100,PREGnn,PBBSUBS,SYSLIB/S,/E ; PREG is a registration program designed to be used in conjunction with ; the Public Bulletin Board System (PBBS). On signon, PREG will get the ; users profile and check the registration flag, bit 0 of FBYTE, and if ; set will abort and return control to the operating system displaying ; a message (if SIGN is set YES) reporting that the user's registration ; has been validated. The entire signon process is bypassed if SIGN is ; set to yes rendering PREG transparent to the user. If PREG finds that ; the registration bit is not set, the user is forced to complete this ; registration. The user is asked if they wish to register at this time ; and if they select NO, the call is terminated and the registration bit ; is not set. This will force the user through this proceedure on every ; call until they complete their registration. The text at label WELC ; should relay this information to the user. When the user elects to ; continue with the registration process, they will be asked to supply ; additional information about themselves. The questions asked can be ; changed to suit the needs of the system. Pay close attention to the ; information requarding these changes should and be necessary. When the ; user does not elect to fill out the registration, PREG exits through ; the error handler defined as ERRFIL in the PBBSDB.HDR file. ; ; The registration database is set up so that you can configure it as you ; see fit. The default settings are those used on my system and I've found ; that they work quite well. The only important thing to remember is that ; each record is limited to 128 bytes in length. You will need to edit the ; fields defined under REQ to suit your systems needs. Only the data will ; be saved in the data base and each field is a fixed length. If you are ; at all familiar with dBASE, you will be able to read this file in as an ; ASCII file with the SDF clause... ; ; example: ; CREATE filename ALL FIELDS DEFINED AS CHARACTER ; USE filename ; APPEND FROM filename.ext SDF ; ; This will read in the entire registration database and allow you to ; utilize the powers of dBASE to sort or index the database and generate ; printouts based on whichever data you think is necessary. For instance, ; if you have a 500 name user base and a few of the fields you keep in ; your database are NAME, ADDRESS, CITY, STATE, ZIP and a YES/NO field ; called DONATION, you could generate mailing labels of all those users ; that saw fit to donate to the upkeep of your system and send them a ; personalized thank you note. ; ; NOTE: While this method will read in the registration database and allow ; you to index, sort and otherwise manipulate your registration database, it ; IS NOT recommended that you re-write the database back out to an ASCII disk ; file. Due to some inconsistancies in the way DBASE II handles the EOF marker, ; some file corruption can occur. The above proceedure will not alter your ; original registration database. ; PREG is used as part of: ; The Public Bulletin Board System ; Author: Ian Cottrell ; 44 Lindhurst Cres ; Ottawa, ON, Canada ; K2G 0T7 ; The Information Centre RCP/M ; (613) 952-2289 (300/1200/2400) ;------------------------------------------------------------------ ; PBBS represents many hours of design, coding and debugging. ; However, I do not believe in SHAREWARE. So, if you find ; PBBS of value to you and wish to pay for it in some way, ; please consider a small contribution ($50 suggested) to your ; local Cancer Society in both of our names (thus creating a ; new class of software - charityware!). Then send a little ; note telling me what you did and we will both feel good! In ; any case, please share this program with others, it is free ; and no form of remuneration may be accepted by anyone except ; its author. ; Version 4.50 05/02/89 Initial release of PREG ; Version 4.51 07/30/89 Removed ':' after labels in ; SIGN: EQU YES and STACK: EQU $ ; to maintain M80 compatibility. ;------------------------------------------------------------------------- ; NOTE: This file MUST be linked to PBSUB416.REL ;------------------------------------------------------------------------- EXT F$OPEN,F$MOPEN,F$WRITE,F$CLOSE,F$APPEND,F$APPL EXT R$READ,R$WRITE EXT PFN2 INCLUDE PBBSEQU.HDR ; PBBS configuration equates IF M80 ; M80 .Z80 ; Needed for M80 ASEG ORG 100H ENDIF ; M80 JP START ; Jump around header and data Z3IDEN: DB 'Z3ENV' ; Z3 Identifier Z3TYPE: DB 1 ; Z3 Environment (external) Z3EADR: DW 0000 ; Z3 Environment (address) Z3LOAD: DW 0000 ; Z3 load address ; Version name, date and levels VNAME:: DB 'PREG ' ; Name VERDAT::DB '89/' ; Year DB '07/' ; Month DB '30 ' ; Day DB 'v',0 ; Status VER:: DB 4 ; Version VERR:: DB 51 ; Revision AUTHOR::DB ' by: Terry Pinto',CR,LF,0 INCLUDE PBBSDB.HDR ; PBBS configuration strings, etc INCLUDE BDOSHDR.MAC ; Time and date conversions BELL EQU 7 ; bell character GETUSR EQU 32 ; get user GETDRV EQU 25 ; get drive REGLEN EQU 128 ; length of registration record ; ------------------------------------------------------------------------ ; USER CONFIGURATION SECTION - EDIT AS NECESSARY! ; ------------------------------------------------------------------------ ; Setting CNFRM to yes will display the maximum length of user input with ; underlines. This will give the user guidelines to the maximum allowable ; input expected. Setting to NO will disable this display. ; ; Example: Name: TERRY PINTO___________________ (Max input 30) ; (CNFRM - YES) Address: 14385 SW WALKER RD. B3________ (Max input 30) ; CitySt: BEAVERTON OR_______ (Max input 20) ; Zip: 97006 (Max input 5) ; Telephone: 503 644-0900 (Max input 12) ; Age: 39 (Max input 2) ; Sex: M (Max input 1) CNFRM EQU YES ; YES to show maximum allowable input ; Setting of the LVL2 equate will bypass all activity of PREG for users ; above level 2 access. If you only want to present your first time users ; with the registration program, then set LVL2 to YES. Although PREG will ; check the registration bit in FBYTE and produce the same results, this ; activity takes a little longer time. Some SYSOPs may elect to speed up ; their systems by eliminating this check. LVL2 EQU NO ; YES to run for access level 2 only ; The signon message for this program can be controlled by this equate. If ; you set SIGN to NO the system will not display any signon message. If the ; settings for CREDIT and VERSION in the PBBSEQU.HDR file are also set to ; NO, PVER will be totally transparant to the user if they are already ; validated by the system. SIGN EQU YES ; yes to display signon message ; This next message will be part of the signon message. This part will ; be the actual request you issue for the information. WELC: DB CR,LF,'To apply for registration to APRAS, it is necessary' DB CR,LF,'for you to supply all of the additional information.' DB CR,LF,'If you fail to supply the information requested, it' DB CR,LF,'will result in your application being denied and your' DB CR,LF,'call being terminated. The information requested is' DB CR,LF,'for our records and will be kept confidential.' DB CR,LF,0 ; This next block contains all of the text sent to the user requesting ; your information. Edit so that they will make sense on your system. ; There is no restriction on the length of each statement as long as ; each is terminated with a binary 0. Each text is preceeded with the ; maximum length of input allowed. These lengths are reflected in the ; DS statements below. RNAM: DB 30,' Name: ',0 ; text for field 1 RADD: DB 30,' Address: ',0 ; text for field 2 RCIT: DB 20,' City, St: ',0 ; text for field 3 RZIP: DB 5,' Zip: ',0 ; text for field 4 RPHN: DB 12,'Telephone: ',0 ; text for field 5 RAGE: DB 2,' Age: ',0 ; text for field 6 RSEX: DB 1,' Sex: ',0 ; text for field 7 NAME: DS 30 ; field 1 length ADDR: DS 30 ; field 2 length CITY: DS 20 ; field 3 length ZIP: DS 5 ; field 4 length TPHONE: DS 12 ; field 5 length AGE: DS 2 ; field 6 length SEX: DS 1 ; field 7 length ; The next statement defines the total length of the record and should ; always be the FILELENGTH-(LASTFIELD+1)-FIRSTFIELD. RXTRA: DS REGLEN-(SEX+1-NAME) ; ------------------------------------------------------------------------ ; END OF USER CONFIGURATION SECTION - MAKE NO CHANGES FROM HERE ON! ; ------------------------------------------------------------------------ ; Check for BYE presence START: LD E,241 LD C,BEXIST CALL BDOS ; See if BYE5 is active CP 77 JR Z,CBBS ; Check for PBBS operation CALL PRINT ; Else, abort DB CR,LF,'BYE5 not available, aborting...',CR,LF,0 JP EXIT ; Restore D/U and exit CBBS: LD A,(REENTR) ; Get re-entry byte OR A ; See if set JR NZ,BEGIN ; if yes - start program CALL PRINT ; If not - abort DB CR,LF,'User record not available, aborting...',CR,LF,0 JP EXIT ; Restore D/U and exit ; Preserve system stack, and initialize program stack BEGIN: LD (CCPSTK),SP ; Save the return address LD SP,STACK ; Install our stack IF LVL2 LD A,(LOCK) ; get user access level CP 2 ; are they above level 2 JP NZ,EXIT1 ; if yes - exit ENDIF ; LVL2 ; Save current drive/user LD E,0FFH LD C,GETUSR CALL BDOS ; Get current user LD (OLDUSR),A ; Save it LD C,GETDRV CALL BDOS ; Get current drive LD (OLDDRV),A ; Save it ; Everything ok, let's begin SIGNON: IF SIGN CALL PVER ; print program signon and version number IF CREDITS LD HL,AUTHOR ; point to author credits CALL PRINTM ; and display them ELSE CALL PCRLF ENDIF ; CREDITS ENDIF ; SIGN ; Now we log into the drive/user areas defined in the PBBSEQU.HDR file ; as the SYSDRV and SYSUSR. LD A,SYSDRV ; log into system drive LD E,A LD C,LOGDRV CALL SPBDOS LD A,SYSUSR ; log into system user area LD E,A LD C,LOGUSR CALL SPBDOS ; Routine to get the active user's record back into memory to be used as ; source material for the user's name, city/state and telephone number. ; The use of this information will eliminate the need to duplicate input ; on the part of the user. It will also insure the accuracy of both the ; registration and user databases. LD DE,USER ; point to USERS.PBS FCB CALL F$OPEN ; open file JP NZ,FOERR ; file error routines FOPEN: CALL SDMA ; set DMA address LD DE,USER ; point to USERS.PBS FCB LD HL,(USREC) ; get users record number CALL R$READ ; read user record into memory JP NZ,RERR CALL F$CLOSE ; close user file JP NZ,FCERR LD HL,TBUFF ; point to TBUFF LD DE,AVAIL ; point to AVAIL (memory buffer) LD BC,USRLEN ; length of user file record LDIR ; move data to memory buffer LD A,(FBYTE) ; get user flag byte BIT 0,A ; test registration bit JP Z,ALREG ; if not set - continue with registration IF SIGN LD HL,UNAME ; point to user name CALL PRINTN ; and display it CALL PRINT DB ' - Registration Validated',cr,lf,0 ENDIF ; SIGN JP EXIT ; Open registration file for append with the last record in memory. Update ; the end-of-file marker and then get the next record for input. If the ; file is not found it will be created. ALREG: LD DE,REGS ; point to FCB CALL F$APPL ; open for append with last record in memory JR NZ,NEOF ; file not found LD HL,NOEND ; point to bytes for not end of file LD DE,TBUFF+125 ; position in buffer LD BC,3 ; length of no end of file LDIR ; move bytes LD DE,REGS ; point to REGISTER.LIB FCB CALL F$WRITE ; write record JP NZ,FWERR CALL F$CLOSE ; close file JP NZ,FCERR NEOF: LD HL,WELC ; point to welcome message CALL PRINTM ; and display it CALL PCRLF CALL PRINT ; ask user if they want to register now DB 'Would you like to register now? (Y/n) ',0 CALL GETCH ; get user input CALL CAPS ; capitolize input CALL ECHO ; echo input to display CP 'N' ; did user say NO JP Z,ERROR ; if yes - exit and terminate call LD A,' ' ; initialize buffer at NAME to spaces LD HL,NAME ; for proper field alignment LD BC,REGLEN ; length of registration record CLBUF: LD (HL),A ; clear buffer byte INC HL ; point to next byte DJNZ CLBUF ; continue until done ;------------------------------------------------------------------------- ; Display request text, get response from user and save input in buffer GETIN: CALL PCRLF1 ; Field for NAME displays a method for getting the information from the ; user record and moving it into the registration buffer automatically ; displaying the data to the user. LD HL,RNAM ; point to field 1 text LD A,(HL) ; get length LD B,A ; and place in B INC HL ; point to text CALL PRINTM ; and display it IF CNFRM CALL PRLINE ENDIF ; CNFRM LD HL,UNAME ; point to user name CALL PRINTL ; and display it CALL PCRLF LD HL,RNAM ; print request for name LD A,(HL) ; get length LD B,A ; and place in B LD HL,UNAME ; point to user name LD DE,NAME ; point to name buffer CALL MOVEBF ; move data and padd with ' ' ; Field for ADDRESS displays a method for displaying the request text and ; getting the input from the user. LD HL,RADD ; print request for address LD DE,ADDR CALL DSPLY LD HL,ADDR LD HL,RCIT LD A,(HL) LD B,A INC HL CALL PRINTM IF CNFRM CALL PRLINE ENDIF ; CNFRM LD HL,CITST CALL PRINTL CALL PCRLF LD HL,RCIT ; print request for city LD A,(HL) LD B,A LD HL,CITST LD DE,CITY CALL MOVEBF LD HL,RZIP ; print request for zip LD DE,ZIP CALL DSPLY LD HL,ZIP LD HL,RPHN LD A,(HL) LD B,A INC HL CALL PRINTM IF CNFRM CALL PRLINE ENDIF ; CNFRM LD HL,PHONE CALL PRINTL CALL PCRLF LD HL,RPHN ; print request for telephone number LD A,(HL) LD B,A LD HL,PHONE LD DE,TPHONE CALL MOVEBF LD HL,RAGE ; print request for age LD DE,AGE CALL DSPLY LD HL,AGE LD HL,RSEX ; print request for sex (don't laugh!!) LD DE,SEX CALL DSPLY LD HL,SEX ;------------------------------------------------------------------------- LDONE: CALL PCRLF CALL PRINT ; get user confirmation DB 'Is the above information correct? (Y/n) ',0 CALL GETCH CALL CAPS CALL ECHO CP 'N' ; if not correct - restart registration JP Z,GETIN CALL PRINT DB CR,LF,LF,'Updating Registration Files >>> ',CR,LF,0 ; Open file registration file and position for save ROPEN: LD DE,REGS ; point to FCB CALL F$APPEND ; open file for append JP Z,SETD ; NZ set if file not found CALL F$MOPEN ; open file (create if does not exist) JP NZ,FOERR ; Move data to TBUFF. SYSLIB routines default to an FCB of 80H unless ; a SETDMA is used to change it. SETD: LD HL,NAME ; point to buffer LD DE,TBUFF ; point to TBUFF LD BC,REGLEN ; length of record LDIR ; move data to TBUFF LD HL,ENDOF ; get end of file marker LD DE,TBUFF+125 ; point to last three bytes in file LD BC,3 ; length of end of file marker LDIR ; mark end of file ; Write record to file RPUT: LD DE,REGS ; point to FCB CALL F$WRITE ; write data from TBUFF to file JP NZ,FWERR CALL F$CLOSE ; close file JP NZ,FCERR LD DE,USER ; open user file CALL F$OPEN JP NZ,FOERR LD HL,(USREC) ; current user record number CALL R$READ ; read record JP NZ,RERR LD A,(FBYTE) ; get registration bit SET 0,A ; set LD (FBYTE),A ; and save LD HL,AVAIL ; move to TBUFF for write LD DE,TBUFF LD BC,USRLEN LDIR LD HL,(USREC) ; current user record number LD DE,USER ; point to FCB CALL R$WRITE ; write buffer to file JP NZ,RERR CALL F$CLOSE ; close file JP NZ,FCERR EXIT: LD A,(OLDDRV) ; load into system drive LD E,A LD C,LOGDRV CALL SPBDOS LD A,(OLDUSR) ; load into system user area LD E,A LD C,LOGUSR CALL SPBDOS EXIT1: LD SP,(CCPSTK) JP 0 GETINP: CALL PRINT DB CR,LF,'You MUST supply ALL of the information requested',0 RET ; Subroutines DSPLY: PUSH DE LD A,(HL) ; get length of input PUSH AF ; save input length on stack LD B,A ; place in B INC HL ; point to message CALL PRINTM ; display request for input IF CNFRM CALL PRLINE ENDIF ; CNFRM POP AF ; restore input length from stack LD B,A ; initialize INPUT routine for maximum input LD A,0 ; set INPUT to echo input to screen LD D,A ; set INPUT to no-wrap LD C,20H ; set INPUT to force upper case CALL INPUT ; get user input CP 0 ; get length of input JR NZ,INOK ; if non-zero, there was input CALL GETINP ; else - display error message POP BC ; clear return address from stack JP GETIN ; restart input INOK: POP DE LD C,A ; place length of input in BC LD B,0 LDIR ; move input CALL PCRLF RET ; Move data to buffer and pad with ' ' MOVEBF: LD A,(HL) ; get first byte CP 0 ; is it a 0 JR NZ,FILLBF ; if not - save it LD A,' ' ; if yes - replace with ' ' FILLBF: LD (DE),A ; place in buffer INC HL ; advance pointers INC DE DJNZ MOVEBF ; continue until done RET ; Display line at the length of user input PRLINE: PUSH HL PUSH DE PUSH BC LD A,'_' CALL LNE POP BC PUSH BC LD A,BS CALL LNE POP BC POP DE POP HL RET LNE: CALL ECHO DJNZ LNE RET ; Check input buffer for supplied data SDMA: LD C,SETDMA LD DE,TBUFF CALL BDOS RET ; File error routines FCERR: INC DE CALL PFN2 CALL PRINT DB ' -> Error in Closing File',bell,0 JP EXIT FWERR: INC DE CALL PFN2 CP 1 JR NZ,FW2 CALL PRINT DB ' -> Error in Extending File',bell,0 JP EXIT FW2: CP 2 JR NZ,FW3 CALL PRINT DB ' -> End of Disk Data',bell,0 JP EXIT FW3: CP 0FFH JR NZ,FWU CALL PRINT DB ' -> No More Directory Space',bell,0 JP EXIT FWU: CALL PRINT DB ' -> Unknown File Error',bell,0 JP EXIT FOERR: INC DE CALL PFN2 CALL PRINT DB ' -> File Not Opened',bell,0 JP EXIT RERR: INC DE CALL PFN2 CP 1 JR NZ,RR3 CALL PRINT DB ' -> Attempt to Read Unwritten Record',bell,0 JP EXIT RR3: CP 3 JR NZ,RR4 CALL PRINT DB ' -> Could Not Close Current Extent',bell,0 JP EXIT RR4: CP 4 JR NZ,RR5 CALL PRINT DB ' -> Attempt to Read Unwritten Extent',bell,0 JP EXIT RR5: CP 5 JR NZ,RR6 CALL PRINT DB ' -> Directory Full',bell,0 JP EXIT RR6: CP 6 JP NZ,FWU CALL PRINT DB ' -> Attempt to Read Beyond End of Disk',bell,0 JP EXIT ; Data section USER: DB 0 ; 0=search on default drive DB 'USERS ' ; file name DB 'PBS' ; file type DS 24 REGS: DB 0 ; 0=search on default drive DB 'REGISTER' ; file name DB 'LIB' ; file type DS 24 ENDOF: DB 0DH,0AH,1AH ; marker for end of file NOEND: DB 20H,0DH,0AH ; not end of file TNAME: DS 30 ; temporary name storage TCITST: DS 30 ; temporary city-state storage TTPHNE: DS 12 ; temporary telephone storage OLDDRV: DB 0 ; storage for original drive OLDUSR: DB 0 ; storage for original user REC: DW 0 ; registration record number CCPSTK: DW 0 ; storage for original stack address DS 64 STACK EQU $ END