; HBYE.Z80 v1 17 Apr 88 ; ; By Irv Hoff, based on Russ Pencin's PBBS, based on Simon Ewin's EMX. ; ;----------------------------------------------------------------------- ; ; This program is called as BYE5's EXFILE when a user is logged off ; ASEG ; Needed by M80 - else ignore any error .Z80 ORG 0100H ; JP START ; VER: DEFB 1 ; Version ; INCLUDE HBBSHDR.INC ; Options and header file INCLUDE HBBSUBS.INC ; Subroutine file INCLUDE HDOSHDR.INC ; Clock read routine ; START: LD DE,241 LD C,SETUSR CALL SPBDOS AND A CP 77 JR Z,CONTINUE CALL PRINT DEFB 'BYE NOT PRESENT...ABORTING.',CR,LF,0 RET ; CONTINUE: LD HL,0 ADD HL,SP LD (CCPSTK),HL ; Save the return address LD SP,STACK ; Install our stack CALL ENDBBS ; Returns HL-> last byte of file LD A,0FFH ; Flag byte for message routines LD (HL),A INC HL ; This is start of the message storage buffer LD (MSG),HL ; The next defines the message space for use ; When entering a message LD DE,MSGBUF+128 ; Messages must be multiples of 64 then... ADD HL,DE ; This become the start of general buffer XOR A LD (HL),A INC HL LD (MSGARR),HL LD A,SYSDRV ; System files are here LD E,A LD C,SELDSK CALL SPBDOS ; Log to the drive LD A,SYSUSR LD E,A LD C,SETUSR ; Log to the user area CALL SPBDOS ; ; Get index info from disk and store it im memory for later ; CALL IOPEN ; INDEX.BBS CALL GET ; Get record CALL CLOSE ; Close file LD HL,IDATEF ; Move from buffer LD DE,IDATE ; To storage LD BC,NDXLEN ; This many bytes LDIR ; Move record LD A,0CDH ; Disable CRL-C's at 0000h LD (0),A ; LD A,0C3H ; Patch error in HBBSUBS to prevent chain loop LD (ERROR),A ; LD HL,BYERROR ; Address of local error handler LD (ERROR+1),HL ; LD A,(REENTR) ; Anyone here? OR A JP Z,HBRET3 ; Nope, all finished ;... ; ; Valid user is on system, and has typed BYE. Signoff the user and ; perform his maintenance. ; MAINT: LD C,86 ; BYE DISKLOG status request LD E,0FFH ; Ask for status CALL SPBDOS CP 77 ; 77 says "NO is set in BYE5" JR Z,MAINT1 ; Exit with no change to the flag LD A,(DSKFLG) ; See if DISK LOG is on now OR A JR Z,MAINT1 ; If not, exit LD C,LOGST ; BYE5 DISLOG status request LD E,0 ; Now turn off the DISKLOG in BYE5 CALL SPBDOS ; MAINT1: CALL GETTIM LD HL,USERS ; Address the filename CALL OPEN ; Open the file LD HL,USRLEN ; Set the record size LD (RRSZ),HL LD HL,(USREC) ; Get the user record number in HL CALL GET ; Get record into buffer CALL CLOSE ; And close the file LD HL,AVAILF ; Save it for callers file update LD DE,AVAIL LD BC,USRLEN LDIR ; ; Now check to see if there is a carrier, if not, don't ask for a msg. ; Either he hung up already or BYE5 is set to sign off prior to bringing ; up this exit program. ; LD C,MDCARCK CALL SPBDOS JP Z,NOPE ; No carrier, so update without comment LD A,(ACESSF) ; Don't ask the Sysop for a comment CP 9 JP C,FEDBK ;..... ; ; Log the Sysop's activity to COMMENTS ; LOGOUT: LD A,2 ; Bump # lines by one for 'from' info LD (LINES),A LD DE,1 LD C,RMWRT CALL SPBDOS LD HL,COMMENTS CALL SPOPEN ; Open file for comments quietly... LD HL,64 LD (RRSZ),HL ; Set record size LD HL,0 ; Get record number CALL GET LD HL,(RNDBUF) ; Is first 2 bytes of record 0 PUSH HL ; Save this comment's record number LD A,(LINES) LD D,0 LD E,A ADD HL,DE ; New number for next comment LD (RNDBUF),HL ; Store it LD HL,0 ; Record number CALL PUT ; And write it ; ; And finally, write each 64 byte line to sequential records ; PASWRITE: POP HL ; Get starting record number back LD (RRNO),HL LD IY,BREAKIN ; Point to breakin message LD A,(LINES) DEC A ; Less one because of 'from' line LD B,A ; Set up counter CALL WRTLP XOR A LD HL,RNDBUF LD (HL),A LD DE,RNDBUF+1 LD BC,63 LDIR ; Clear random buffer LD HL,UNAME LD BC,0 ; PASLOP: INC BC INC HL LD A,(HL) CP 0 JR NZ,PASLOP LD HL,UNAME LD DE,RNDBUF LDIR ; Add line with caller's name LD A,32 ; Keep SYSREAD happy LD (DE),A CALL GETTIM ; Get date and time LD HL,TIME INC DE LD BC,8 LDIR ; Move time string into place LD A,32 LD (DE),A ; Keep SYSREAD happy LD HL,DATE INC DE LD BC,8 LDIR ; And date LD HL,MSGBRK LD BC,15 LDIR LD HL,(RRNO) CALL PUT ; Write last line CALL CLOSE ; All done LD DE,0 LD C,RMWRT CALL SPBDOS ; Clear write lock JP NOPE ;..... ; BREAKIN:DEFB 'Sysop login: Please check time and date ' DEFB 'of your last log...',0,0,0,0 ; MSGBRK: DEFB CR,LF,'=== EOM ===',CR,LF,0 ;..... ; WRTLP: PUSH BC PUSH IY POP HL LD DE,RNDBUF LD BC,MSGLEN LDIR PUSH HL POP IY LD HL,(RRNO) CALL PUT LD HL,(RRNO) INC HL LD (RRNO),HL POP BC DJNZ WRTLP RET ;..... ; FEDBK EQU $ ; IF NOT CMMNT JP NOPE ; Option to bypass private note request ENDIF ; NOT CMMNT ; CALL PRINT DEFB CR,LF DEFB 'Wish to leave any public comments to the Sysop? ',0 CALL EATCHR ; ; Delay routine to insure logoff after 15 seconds ; DELAY1: CALL GETTIM LD A,(BTIME+2) LD (OLDSEC),A LD B,15 ; 15 seconds to respond ; DELAY2: PUSH HL ; Save the values, consume some time PUSH DE PUSH BC PUSH AF LD E,0FFH LD C,DIRCON CALL SPBDOS ; Get console status OR A ; Character ready? JR Z,DELAY3 ; Keep going LD SP,STACK ; Clear up the stack, to exit CALL CAPS CP 'Y' JR Z,CMNT ; Exit,clear stack, write the note CALL PRINT DEFB 'No',CR,LF,0 JP NOPE ; Exit, did not want to write a note ;... ; DELAY3: POP AF POP BC ; Restore the values POP DE POP HL CALL GETTIM LD A,(OLDSEC) LD HL,BTIME+2 CP (HL) JR Z,DELAY2 LD A,(BTIME+2) LD (OLDSEC),A DJNZ DELAY2 ; Another second gone CALL PRINT DEFB 'Timed out',0 JP NOPE ; Timed out, exit ;..... ; ;----------------------------------------------------------------------- ; CMNT: CALL PRINT DEFB 'Yes',0 LD A,ALLLV ; See if access allows public messages LD B,A LD A,(ACESS) CP B JR C,CMNT1 ; Can not leave a public message XOR A ; Else make it public to Sysop JR CMNT2 ; CMNT1: LD A,1 ; Restrict him to private ; CMNT2: LD (PFLAG),A ; Force private LD HL,SYSOP ; Was 'sysop' so move name at label LD DE,MTOTMP ; 'sysop' to mto stuff LD BC,NAMLEN LDIR CALL UOPEN LD HL,USRLEN ; Record length LD (RRSZ),HL LD HL,MTOTMP ; Get to: name ; @PMHSH: LD A,(HL) ; Get a character INC HL ; Next character CP ' ' ; See if it's a space JR NZ,@PMHSH LD A,(HL) ; Get first char of last name CALL HASH ; Calc starting pos'n in USERS.BBS LD (HSHREC),HL LD HL,(HSHREC) ; @PMLP: CALL GET LD A,(ACESSF) ; See if active 0=deleted, 1=twit, >=2 okay CP 2 JR C,@PMLP0 LD HL,UNAMEF ; See if to user LD DE,MTOTMP LD B,NAMLEN CALL MATCH OR A JR Z,@GOTIT ; @PMLP0: LD HL,(RRNO) INC HL ; Next record number EX DE,HL ; Make HL safe LD HL,MAXU XOR A ; Clear carry SBC HL,DE ; Done with records? EX DE,HL ; Get HL back JR NZ,@PMLP LD HL,0 ; Load up first record in file JR @PMLP ; No, keep going ; @GOTIT: CALL CLOSE LD HL,(RRNO) LD (MTOREC),HL ; Save record number for later ; ; Set the user's preferred terminal with for writing, reading messages ; CMNTE: LD A,(LENG) ; Get user's terminal line width LD (LIN1),A LD (LIN2),A ADD A,1 LD (LIN4),A SUB 8 LD (LIN3),A CALL PRINT DEFB CR,LF,CR,LF DEFB 'You can use up to ',0 LD H,0 LD L,MSGLIN CALL PB2ASC ; Show maximum message length CALL PRINT DEFB ' lines for this message' DEFB CR,LF DEFB 'Use a space in 1st column to add a blank line' DEFB CR,LF DEFB 'Use 2 to exit',CR,LF,CR,LF DEFB 'Enter text...',CR,LF,CR,LF,0 XOR A LD (CRS),A LD (COLUMN),A ; Current column number LD (LINCNT),A LD (LSTLN),A ; Set last line routine LD (PNTCHR),A ; Zero printing character flag LD (SPCSTR),A ; Zero the 'no space yet' flag CALL LINNUM ; Show the current line number LD HL,0 ; Ready to 0 buffers LD IX,(MSG) ; Point to start of buffer LD BC,MSGBUF ; Get length of buffer ; ; Add any special delete characters here ; DEL EQU 7FH ; 'normal' delete key DELOS EQU 1FH ; ^- on the OS-1 ; MSLOP: PUSH BC ; Save the character counter registers CALL GETCH POP BC ; Get the character count back AND 7FH ; Remove any parity CP BS ; Normal backspace? JP Z,BCKSPC ; If yes, exit CP DEL ; Delete key used for backspace? JP Z,BCKSPC ; If yes, exit CP DELOS ; Special backspace key of some sort? JP Z,BCKSPC ; If yes, exit CP TAB ; Tab key to jump ahead on line? JP Z,CHKTAB ; If yes, exit CP ' ' ; space character? JP Z,CHKSPC ; If yes, exit, show we got one CP CR ; New line requested? CALL Z,CRLF ; If yes, display CR-LF both CP ' '+1 JR C,MSLOP ; Must be a printable character CP '~'+1 JR NC,MSLOP LD (PNTCHR),A ; Have a printing character this line ; MSLOP1: CALL ENTCHR JP MSLOP ;..... ; CHRCNT: DEFB 0 ; Character count for word wrap transfer LINCNT: DEFB 0 ; Line count for messages PNTCHR: DEFB 0 ; Got a printing char. for auto-wrap SPCSTR: DEFB 0 ; Flag to show a space has been received ; ; Got printable character, add to buffer, then show it. First, see if ; if any room is left in the buffer, to continue the message. ; ENTCHR: PUSH AF ; Save the character DEC BC ; Buffer has a '0' to terminate LD A,B ; Check MSP of buffer length OR A ; Less than 255 characters available? JR NZ,ENTCH0 ; Nope, continue OR C ; Check LSP of buffer length JP Z,ENDBUF ; If Buffer is empty now, exit LD A,C ; See how far under 255 chars. we are CP 150 ; Under 150 characters left to go? CALL C,LSTLN ; If yes, warn user one time only ; ; Now check to see if line length would be exceeded ; ENTCH0: LD A,(COLUMN) ; See what column we are in now ; LIN1 EQU $+1 ; CP 72 ; Check maximum line length JP C,ENTCH7 ; If less, can continue normally LD A,(SPCSTR) ; Had any space characters yet? OR A JR NZ,ENTCH1 ; If yes, exit POP AF ; Set the stack correctly JR ENTCH6 ; No space char. yet, beep and exit ; ; Line will be too long, so remove characters from buffer back to last ; printing character in previous word, store temporarily, insert CR-LF ; then place the characters on next line and continue. ; ENTCH1: XOR A ; Zero first character in temp. buffer LD HL,TBUFF LD (HL),A ; Zero 1st character in TBUFF ; ; Next store current typed character into temporary buffer, if a space ; handle as CRLF unless no printing characters are on the line yet. ; POP AF ; Get typed character back CP ' ' ; See if it was a space JR NZ,ENTCH2 ; If not, exit LD A,(PNTCHR) ; See if printing character yet OR A JP Z,ENTCH6 ; No, beep and ignore LD A,' ' ; Restore the character CALL ENTCH8 ; Enter the space into the message JP TURNUP ; Now turn up a new line ; ENTCH2: INC HL ; Next TBUFF position LD (HL),A ; Store typed character temporarily ; ; Now get into the message buffer and pick off characters back to end of ; previous word. Store into temporary buffer, quit if a space character. ; ENTCH3: INC HL ; Next TBUFF position DEC IX ; Previous message buffer address LD A,(IX) ; Get the character from message buffer CP ' ' ; See if a space character, yet JR Z,ENTCH4 ; If yes, exit CP '-' ; Accomodate hyphenated words JR Z,ENTCH4 ; Exit and turn up a new line LD (HL),A ; Store the character temporarily PUSH BC PUSH HL PUSH IX CALL PRINT DEFB BS,' ',BS,0 ; Remove it from the display POP IX POP HL POP BC JR ENTCH3 ; Keep looping until space char. found ; ; Found a space character or hyphen ; ENTCH4: INC IX ; Position to first printing character CALL TURNUP ; Display a new line on CRT ; ; Now start replacing characters from temporary buffer to next line ; ENTCH5: DEC HL ; Get previous temp. buffer position LD A,(HL) ; Get the character there OR A RET Z ; CALL ENTCH8 ; Display and enter the character JP ENTCH5 ; Continue until done ; ; Line will be too long with this character and no spaces have been sent ; yet, so can't use auto-wrap at this point. Beep and wait for a ; or backspace to some other character. ; ENTCH6: PUSH BC CALL PRINT ; Sound off as can't continue at present DEFB BEL,0 POP BC RET ; Return for next character ; ENTCH7: POP AF ; Get the character back ; ENTCH8: LD (IX),A ; Add to buffer PUSH IX ; In case BIOS uses IX CALL ECHO ; Show character POP IX ; Restore the IX value INC IX ; Increment it for next character LD A,(COLUMN) ; Get current position on line INC A LD (COLUMN),A XOR A ; In meanwhile, zero it just in case LD (IX),A ; Float a 0 at end of message LD (CRS),A ; Reset the consecutive CR count RET ;..... ; BCKSPC: LD A,(COLUMN) ; Get position on the line OR A JP Z,MSLOP ; If zero, can't backspace DEC A LD (COLUMN),A ; This backspace go to left margin? JR NZ,BCKSP1 ; If not, exit LD (PNTCHR),A ; Reset flag for printing character LD (SPCSTR),A ; Reset flag for got a space character LD A,1 LD (CRS),A ; Set the consecutive CR count ; BCKSP1: DEC IX ; Move the buffer pointer back one XOR A ; Float a 0 at end of message LD (IX),A INC BC PUSH BC PUSH IX CALL PRINT DEFB BS,' ',BS,0 ; Backspace one POP IX POP BC JP MSLOP ;..... ; ; Check for a tab, expand up to 8 spaces if yes, quit prior to end of ; line. ; CHKTAB: LD A,(COLUMN) ; Get position on line ; LIN2 EQU $+1 ; CP 72 ; At end now? JP NC,MSLOP ; If yes, exit ; LIN3 EQU $+1 ; CP 72-7 ; Prevent a partial tab at end of line JR C,CHKT1 ; No close to end, handle normally AND 7 ; Stop at normal tab before line end JP Z,MSLOP ; If at tab stop, quit CHKT1: LD A,' ' CALL ENTCHR LD A,(COLUMN) AND 7 JR NZ,CHKTAB JP MSLOP ; CHKSPC: LD (SPCSTR),A ; Keep track of last space received JP MSLOP1 ;..... ; ; Enter and display a CR-LF ; CRLF: CALL CRCOM ; Call common section ; LD A,(CRS) ; Bump # cr in a row INC A ; And if over 3 then quit LD (CRS),A CP 2 JP NC,EXITCR ; Two consecutive CR, so quit LD A,CR LD (IX),A ; Store in the buffer PUSH IX ; Save buffer address CALL ECHO ; Show the CR on the CRT POP IX ; Get the buffer address back INC IX ; Increment to next position LD A,LF CALL ECHO ; Display a line feed on CRT XOR A ; Clear the A register LD (COLUMN),A ; Show in Column 0, now LD (PNTCHR),A ; Reset flag for printing character LD (SPCSTR),A ; Reset flag for got a space character LD (IX),A ; Terminate message with a 0 CALL LINNUM ; Show next line number RET ;..... ; CRCOM: DEC BC ; Add back one count for this CR LD A,B ; More that 256 characters left? OR A RET NZ ; If yes, everything is ok OR C ; See if out of space entirely JR Z,CRCOM1 ; If yes, reset stack and exit LD A,C ; See if only two lines left CP 150 ; Last 150 characters? JP C,LSTLN ; If yes, tell user only 2 lines left RET ;... ; CRCOM1: POP HL ; Remove CALL CRCOM from stack ; ENDBUF: POP AF ; Clear stack INC BC ; Re-align counter PUSH BC ; Save it DEC IX ; Back to end of block PUSH IX ; Save again XOR A LD (IX),A ; Set end of message CALL PRINT DEFB CR,LF,CR,LF DEFB '++ Buffer Full ++',0 JP EXITM ;..... ; ; Puts a line number while writing a message ; LINNUM EQU $ ; IF NOT LINNOS RET ENDIF ; NOT LINNOS ; IF LINNOS PUSH BC PUSH HL LD A,(LINCNT) INC A LD (LINCNT),A CP 10 JR NC,LINNUM1 CALL PRINT DEFB ' ',0 ; LINNUM1:LD A,(LINCNT) LD H,0 LD L,A CALL PB2ASC CALL PRINT DEFB ': ',0 POP HL POP BC RET ENDIF ; LINNOS ;..... ; LSTLN: NOP ; Get's changed to a RET PUSH BC PUSH IX CALL PRINT DEFB CR,LF,'++ Only 2 lines left ++',CR,LF,0 LD A,0C9H ; Disable last line message so it can LD (LSTLN),A ; only be shown the one time POP IX POP BC RET ;..... ; TURNUP: CALL CRCOM ; See if any room left, etc. PUSH BC PUSH HL PUSH IX CALL PRINT DEFB CR,LF,0 POP IX POP HL POP BC LD A,1 LD (CRS),A XOR A LD (COLUMN),A LD (PNTCHR),A LD (SPCSTR),A CALL LINNUM ; Show next line RET ;..... ; EXITCR: POP HL ; Remove 'CALL CRLF' from stack PUSH BC ; Save buffer length for later handling PUSH IX ; Save address for later handling LD IX,(MSG) INC IX LD A,(IX) OR A JR NZ,EXITM1 POP IX POP BC JP NOPE ;... ; EXITM: CALL PRINT DEFB CR,LF,0 ; EXITM1: CALL PRINT DEFB CR,' ',CR,LF DEFB 'Save, Abort, Continue, Edit, List: ',0 ; EXITM4: CALL GETCH CP CR JP Z,CONT CALL CAPS CP 'A' JR Z,ABXIT CP 'C' JP Z,CONT CP 'E' JP Z,EDIT CP 'L' JP Z,LISTE ; Actual LIST is a subroutine this calls CP 'S' JP Z,SAVE JR EXITM4 ;..... ; ABXIT: CALL PRINT DEFB 'Abort',CR,LF,CR,LF DEFB 'Abort this message? ',0 CALL GETCH CALL CAPS CP 'Y' JR Z,ABXIT1 CALL PRINT DEFB 'No',CR,LF,0 JP EXITM ;... ; ABXIT1: CALL PRINT DEFB 'Yes',CR,LF,0 POP IX POP BC JP NOPE ;..... ; EDIT: XOR A ; Clear edit buffers LD HL,EBUF LD (HL),A LD DE,EBUF+1 LD BC,129 ; Including elen and rlen LDIR CALL PRINT DEFB 'Edit',CR,LF,CR,LF DEFB 'Characters to change: ',0 XOR A LD C,A LD D,A LD B,64 CALL INPUT OR A JP Z,EXITM LD (ELEN),A ; Save length LD C,A LD B,0 LD HL,INBUF LD DE,EBUF LDIR ; Move search edit string to buffer CALL PRINT DEFB CR,LF DEFB 'Change them to these: ',0 XOR A LD C,A LD D,A LD B,64 CALL INPUT LD (RLEN),A ; Save length OR A JR Z,CHKSTR ; If no replacement then skip move LD C,A LD B,0 LD HL,INBUF LD DE,RBUF LDIR ; Move new string into place ; CHKSTR: LD HL,EBUF ; Point to search string LD DE,(MSG) ; And message start ; SELOP: LD A,(DE) CP (HL) JR Z,SELOP0 INC DE ; Next in buffer LD A,(DE) OR A ; At end? JR NZ,SELOP ; Not yet so try again JP NOSTR ; String not found ;... ; SELOP0: PUSH DE PUSH HL ; Save current positions ; SELOP1: INC HL INC DE LD A,(HL) ; At end of edit string yet? OR A JR Z,SELOP2 ; Got a match LD A,(DE) CP (HL) JR Z,SELOP1 POP HL POP DE INC DE ; Point to next in buffer JR SELOP ; Go look some more ;..... ; SELOP2: POP HL ; Get rid of junk PUSH DE ; Save end of found string LD A,(ELEN) LD B,A LD A,(RLEN) CP B ; Compare lengths of strings JP Z,REQU JP C,RLESS ; ; ------------------------------------------------------------------ ; | While all the message routines use the stack, this section in | ; | particular is EXTREMELY stack intensive. Use a LOT of care if | ; | you change ANY of this. | ; ------------------------------------------------------------------ ; ; These routines enter with stack as: ; ; top - end of found string ; next - start of found string ; next - current pos in buffer ; next - characters remaining in buffer ; RGTR: SUB B LD E,A LD D,0 ; De=diff LD (DIFF),DE ; Need later POP IY ; Get end POP BC ; Get start POP IX ; Get current POP HL ; Get chars left PUSH HL ; And restore them PUSH IX ; And current PUSH BC ; And start PUSH IY ; And end AND A ; Clear carry SBC HL,DE ; Hl must be > de JP C,LNGSTR ; Too long so abort LD (NEWFRE),HL ; Save characters free for later PUSH IX ; End of buffer POP HL ; In hl PUSH HL ADD HL,DE ; New end in hl EX DE,HL ; De=move to POP HL ; Hl=move from PUSH IY POP BC ; Bc=end of found string PUSH HL ; Save move from AND A ; Clear carry SBC HL,BC ; Hl=# characters to move INC HL ; Need one more moved PUSH HL POP BC ; Bc=count POP HL ; Hl=move from LDDR ; Move back to open space up POP HL ; Don't need end anymore POP DE ; Move to LD HL,RBUF ; From here LD A,(RLEN) LD C,A LD B,0 ; This many LDIR POP IX POP BC LD HL,(NEWFRE) PUSH HL ; Save new characters remaining PUSH IX ; And current pos in buffer POP HL ; To hl LD DE,(DIFF) ADD HL,DE PUSH HL ; Save new position on stack JP EXITM ;..... ; RLESS: LD A,(RLEN) OR A JR Z,RL0 ; If 0 then we are deleteing so skip first move LD C,A LD B,0 POP HL ; Get end of found string POP DE ; Get start of found string PUSH HL ; Need end later LD HL,RBUF LDIR ; Move new string to old position JR RL1 ; Skip next unless no replacement string ; RL0: POP HL ; End of found string POP DE PUSH HL ; For next pop ; RL1: POP HL ; Move from here (de set from ldir or rl0) POP BC ; Get current buffer position PUSH BC ; Save again PUSH DE ; Save end of old string (in buffer) PUSH HL ; Save start of string to move up (in buffer) AND A ; Clear carry PUSH HL PUSH BC ; Reverse bc and hl POP HL POP BC SBC HL,BC ; Hl=characters to move less one INC HL ; Re-align PUSH HL POP BC ; Count POP HL ; From POP DE ; To LDIR ; Move rest of string up LD A,(RLEN) LD B,A LD A,(ELEN) SUB B LD E,A LD D,0 ; De=diff POP IX POP HL ; Get characters left ADD HL,DE ; Update count PUSH HL ; Save it PUSH IX POP HL ; Get current position AND A SBC HL,DE ; Update PUSH HL JP EXITM ;..... ; REQU: LD A,(RLEN) LD C,A LD B,0 POP DE ; Don't need end of found string address POP DE ; Get start of found string LD HL,RBUF LDIR ; Move new string into buffer JP EXITM ;..... ; LNGSTR: POP HL POP HL ; Clear stack CALL PRINT DEFB CR,LF,CR,LF DEFB 'Replacement string too long.',0 JP EXITM ;..... ; NOSTR: CALL PRINT DEFB CR,LF,CR,LF DEFB 'Old string not found...',0 JP EXITM ;..... ; CONT: CALL PRINT DEFB 'Continue' DEFB CR,LF,CR,LF,0 POP IX POP BC DEC BC ; Buffer full when 1 byte left LD A,B OR C ; See if at end of buffer INC BC ; Realign counter JR Z,NOCONT ; Nope, so go PUSH BC PUSH IX CALL PRINT DEFB 'Continue entering text...' DEFB CR,LF,CR,LF,0 LD A,(LINCNT) DEC A LD (LINCNT),A CALL LINNUM POP IX POP BC JP MSLOP ; Go for it... ;..... ; NOCONT: PUSH BC PUSH IX CALL PRINT DEFB 'Cant''t continue, at end of buffer.',CR,LF DEFB 'Use E)dit to delete from and change message...',0 JP EXITM ;..... ; ;----------------------------------------------------------------------- ; displays messages ; LISTE: CALL PRINT DEFB 'List',CR,LF,0 CALL LIST JP EXITM1 ;... ; LIST: CALL PRINT ; Start a new line DEFB CR,LF,0 XOR A LD (COLUMN),A ; Current column number LD (PNTCHR),A ; Reset printing character flag LD (SPCSTR),A ; Flag to show a space has been received LD HL,(MSG) ; Independent check for line length LD IX,(MSG) ; Point to buffer ; ; Count the text one character at a time. If too many for the desired ; maximum line length, do a word wrap on the local display. ; LSTLP: LD A,(HL) ; Get the character OR A JP Z,LSTLP1 ; End of message, exit CP CR ; End of line character? JP Z,LSTNEW ; See if CR should be retained CP ' ' ; See if 01 or other non-printing JR C,LSTLP4 ; Skip any non-printing characters ; LSTLP1: LD A,(COLUMN) ; Increment for this character INC A LD (COLUMN),A LD A,(HL) ; Get the character back again CP CR+1 ; See if a or end of message JP C,SHOLIN ; If yes, send the new line CP ' ' JR NZ,LSTLP2 LD (SPCSTR),A JR LSTLP3 ;..... ; LSTLP2: LD (PNTCHR),A ; Show a printing character on the line ; LSTLP3: LD A,(COLUMN) ; See what column we are in now ; LIN4 EQU $+1 ; CP 72 JP NC,LSTWRP ; Exit if line is now too long ; LSTLP4: INC HL JP LSTLP ; Get the next character ; ; Line was too long, see why and fix the count accordingly ; LSTWRP: LD A,(HL) ; Get the character back CP ' ' ; Space at end of full line? JR NZ,LSTWR3 ; Not a space, exit PUSH HL ; Save current location CALL LSTSP1 ; Eliminate any trailing spaces POP HL ; Get the original location again PUSH HL ; Save once more ; LSTWR1: INC HL ; Increment next position in line LD A,(HL) ; Get that character CP ' ' ; Double space after a period? JR NZ,LSTWR2 ; If not exit, done LD (HL),3 ; Else eliminate the extra space JP LSTWR1 ; Check/eliminate any more spaces ;... ; LSTWR2: POP HL ; Restore the buffer location JR SHOLIN ; Go show the line ;... ; LSTWR3: DEC HL LD A,(COLUMN) DEC A LD (COLUMN),A LD A,(SPCSTR) ; Any spaces yet? OR A JR Z,SHOLIN ; If not show what we have so far LD A,(HL) CP '-' JR Z,SHOLIN CP ' ' JR NZ,LSTWR3 ; Neither of these, keep backtracking PUSH HL CALL LSTSP ; Check for any trailing spaces POP HL JR SHOLIN ; Then display the line ; LSTSP: DEC HL ; Don't check current location ; LSTSP1: LD A,(HL) ; Get the character CP ' ' ; A space character? RET NZ ; Exit if not ; LD (HL),3 ; Don't keep the space JR LSTSP ; See if any more spaces ;... ; ; Ok all finished, now, display the line ; SHOLIN: LD A,(IX) OR A ; Message all finished? RET Z ; Yes, exit CP CR JR Z,LSTCR ; Exit if at end of this line CP 3 JR NZ,SHOLN1 LD (IX),' ' ; Change the "Ignore char" back to space ; SHOLN1: CP ' ' JR C,SHOLN2 ; Ignore non-printing CALL ECHO ; Display the character ; SHOLN2: LD A,(COLUMN) DEC A LD (COLUMN),A JR Z,LSTCR ; If zero, no so add one ; LSTWR5: INC IX JR SHOLIN ; Do the next character ;..... ; ; Displays CR, resets the column counter, then checks to see if time for ; the [more] pause, returns with LF in 'A', not displayed yet. ; LSTCR: CALL LSTUP ; Display a CR and check for [more] INC HL ; Increment for this character PUSH HL ; Transfer HL address to IX POP IX JP LSTLP ; Back to work for the next line ; LSTUP: XOR A LD (COLUMN),A ; Reset column counter LD (PNTCHR),A ; Reset printing character flag LD (SPCSTR),A ; Reset space character flag LD A,CR ; Turn up a new line CALL ECHO LD A,LF CALL ECHO PUSH HL LD E,0FFH LD C,DIRCON CALL SPBDOS ; See if a pause is requested OR A JR Z,LSTUP1 ; If not, keep on going CALL GETCH ; Else wait for another character ; LSTUP1: POP HL ; Restore the stack RET ;..... ; ; Found a CR, check following character to see if: ; ; 1) end of message - keep CR ; 2) space - keep CR, as intentional new line ; 3) printing character - means this was a short line so remove CR ; LSTNEW: INC HL ; Check next character LD A,(HL) OR A ; See if end of message JR Z,LSTN1 ; If yes, handle this CR normally CP ' ' ; Is it a space for blank line? JR Z,LSTCK ; If yes, handle normally DEC HL ; Back to normal position LD A,(PNTCHR) ; Current line have any printing chars? OR A JP Z,LSTCK1 ; If not, keep the CR and check spaces LD (HL),' ' ; Change the CR to a space character JP LSTCK1 ; Now check for any trailing spaces ;... ; LSTN1: DEC HL JP LSTLP1 ; Keep the CR, handle normally ;..... ; ; Keeping the CR, so check for any trailing spaces ; LSTCK: DEC HL ; Back to the CR location ; LSTCK1: PUSH HL ; Save this location for now LD A,(SPCSTR) ; Current line have any spaces? OR A JR Z,LSTCK3 ; If not, can't have any trailing spaces ; LSTCK2: DEC HL ; Previous location on line LD A,(HL) ; Get the previous character CP ' ' ; Was it a trailing space character? JR NZ,LSTCK3 ; If not, ext LD (HL),3 ; Eliminates the trailing space JR LSTCK2 ; Check for additional trailing spaces ; LSTCK3: POP HL ; Back to the original CR location JP LSTLP1 ; Handle normally ;..... ; end of display messages ;----------------------------------------------------------------------- ; save the message SAVE: CALL PRINT DEFB 'Save',0 POP IX POP BC ; Must clear stack first LD HL,MSGBUF ; Get max characters allowed AND A ; Clear carry SBC HL,BC ; HL=number of characters in message INC HL ; Plus one LD DE,64 LD C,0FFH ; Set up quotient ; DLOP: INC C AND A ; Clear carry SBC HL,DE ; Divide by 64 to get number of lines JR NC,DLOP ADD HL,DE ; Remainder back in hl LD A,C ; Get number of lines INC A ; Bump # lines by one for 'from' info INC A ; And one for 'to' and time/date LD (LINES),A LD A,H OR L ; If any remainder then need extra line JR Z,NOREM LD A,(LINES) INC A LD (LINES),A ; Save new value ; NOREM: CALL PRINT DEFB CR,LF DEFB 'Updating index, message and user files...',0 LD DE,1 LD C,RMWRT CALL SPBDOS ; ; Set flag in 'to' user's record so he's bumped to mail next signon ; USET: CALL UOPEN ; Read 'to' user into buffer LD HL,USRLEN LD (RRSZ),HL LD HL,(MTOREC) ; Record # saved when we searched for 'to' user CALL GET LD A,(MAILF) ; Flag mail waiting INC A ; Show one more LD (MAILF),A ; And set it LD HL,(RRNO) ; Get record number CALL PUT ; And write record back CALL CLOSE CALL MOPEN ; ; Have to open new record for message in MSGINDEX so set up for it ; LD HL,(IMRNM) LD (MSTRF),HL ; Set message record number LD A,(LINES) LD (MBLKF),A ; & number lines (records) LD D,0 LD E,A ADD HL,DE ; Calc new record start LD (IMRNM),HL ; And store in index LD HL,(IMNDX) ; And bump number records in index INC HL LD (MRECF),HL ; Store rec# in msgindex LD (IMNDX),HL LD (RRNO),HL ; Set record number in buffer ; ; Now write the msgindex record # determined above ; WRITE: CALL GETTIM ; Get date/time string LD HL,(IMNXT) ; Next message number LD (MNUMF),HL ; Make it this message LD HL,MTOTMP LD DE,MTOF LD BC,NAMLEN LDIR ; Set message 'to' field LD HL,TIME ; Get the current time LD DE,MTIMF ; Put it in MSGINDEX.BBS LD BC,5 ; Just the hour and minutes is ample LDIR LD IY,IDATE LD IX,MDATF ; And date LD A,(IY) LD (IX),A LD A,(IY+1) LD (IX+1),A LD A,(IY+2) LD (IX+2),A LD IY,PFLAG ; Private flag LD A,(IY) LD (MPUBF),A LD DE,MSUBF LD HL,MSUBTMP LD BC,26 LDIR ; Set subject field LD HL,UNAME ; Get user's name LD BC,NAMLEN LDIR ; Move users name XOR A ; Clear 'A' INC A ; And increment so it's a 1 LD (MANUMF),A ; And then store in area number LD HL,(RRNO) CALL PUT CALL CLOSE ; MSGINDEX closed ; ; Now update index info ; LD HL,(MSTRF) ; Get record number for first line LD (STRTMP),HL ; Save it for later ; ; Set the area number to 1, all comments must go to area 1 ; LD HL,(IMNXT) INC HL LD (IMNXT),HL ; Update next message number LD HL,IDATE ; Update INDEX information LD DE,IDATEF LD BC,NDXLEN LDIR CALL IOPEN CALL PUT CALL CLOSE ; INDEX closed ; ; And finally, write each 64 byte line to sequential records ; LD HL,MESSAGES CALL OPEN LD HL,MSGLEN LD (RRSZ),HL LD HL,(STRTMP) ; Set record number for first line LD (RRNO),HL ; ; Now we create the first two records which are the message header with ; time/date, to/from, subject stuff ; CALL CLRBUF ; Nice clean buffer LD HL,MSG1 ; Move first of header to buffer LD DE,RNDBUF LD BC,6 LDIR LD HL,DATE ; And date string LD BC,8 LDIR LD A,' ' LD (DE),A INC DE LD HL,TIME ; And time string LD BC,8 LDIR LD A,' ' LD (DE),A INC DE LD A,CR LD (DE),A INC DE LD HL,MSG2 ; Next header bit LD BC,6 LDIR LD HL,MTOTMP ; Who to LD BC,NAMLEN LDIR LD A,CR ; End of line LD (DE),A INC DE XOR A ; Insure clean buffer LD (DE),A CALL STRIP ; Waste the nulls LD HL,(RRNO) ; Get record # CALL PUT ; And write it CALL CLRBUF ; Clear the buffer for next stuff ; ; Now get 'From' name and move into place ; LD HL,MSG3 LD DE,RNDBUF LD BC,6 LDIR ; Move characters before 'from' name LD HL,UNAME ; Get user's name LD BC,NAMLEN LDIR ; Move users name LD A,CR LD (DE),A ; Last carriage return INC DE LD (DE),A ; Twice CALL STRIP ; Get rid of nulls LD HL,(RRNO) INC HL CALL PUT ; Write second record LD HL,(RRNO) INC HL LD (RRNO),HL ; Save updated record number LD IY,(MSG) ; Point to message LD A,(LINES) DEC A ; Less 2 for time/date stuff ... DEC A ; That has already been written LD B,A ; Set up counter CALL WRTLP CALL CLOSE LD DE,0 LD C,RMWRT CALL SPBDOS ; Clear write lock CALL PRINT DEFB CR,LF,0 JP NOPE ;..... ; ; Take the nulls out of the record being written to MESSAGES.BBS. ; This is only needed on the first 2 records which contain data ; moved from other areas that use nulls to pad the fields... ; STRIP: LD HL,RNDBUF ; Start of buffer LD B,MSGLEN ; Length of each message record ; STRIP0: LD A,(HL) ; Get character OR A ; Is it a null? JR NZ,STRIP1 ; Not 0 INC A ; Yes, so change 0 to 1 ; STRIP1: LD (HL),A ; Save character INC HL ; Next character DJNZ STRIP0 ; Do entire buffer RET ; Done ;..... ; ; Clear buffer for next ; CLRBUF: XOR A LD HL,RNDBUF LD (HL),A LD DE,RNDBUF+1 LD BC,USRLEN ; Longest used length LDIR RET ;..... ; ; Header data strings... ; MSG1: DEFB 'Left ' ; 6 characters before time/date MSG2: DEFB 'For ' ; 6 characters before who to MSG3: DEFB 'From ' ; 6 characters before who from ;..... ; ; Update the fields ; NOPE: LD C,LOGST ; BYE DISKLOG status request LD E,0FFH ; Ask for status CALL SPBDOS CP 77 ; 77 says "NO is set in BYE5" JR Z,NOPE1 ; Exit with no change to the flag LD A,(DSKFLG) ; See if DISKLOG was originally on OR A JR Z,NOPE1 ; If not, all done LD C,86 ; BYE5 DISKLOG status byte LD E,RDCON ; Else turn the DISKLOG back on CALL SPBDOS ; To catch Sysop's log off time ; NOPE1: LD HL,USERS ; Address the filename CALL OPEN ; Open the file LD HL,USRLEN ; Set the record size LD (RRSZ),HL ; LD HL,(USREC) ; Reget the user record no. in hl CALL GET ; Get record into buffer CALL CLOSE ; And close the file LD HL,(UPLDSF) ; No. of previous uploads LD A,(UPLOADS) LD D,0 ; Clear high order bit LD E,A ; Get current uploads LD (UPLODS),DE ; Save them for logoff ADD HL,DE ; Get total LD (UPLDST),HL ; For totals LD (UPLDSF),HL ; Update the random buffer LD HL,(DNLDSF) ; No. of previous downloads LD A,(DNLOADS) LD D,0 ; Clear high order bit LD E,A ; Get current downloads LD (DNLODS),DE ; Save them for log off ADD HL,DE ; Get totals LD (DNLDST),HL ; For totals LD (DNLDSF),HL ; Update the random buffer directly LD A,(TRMCD) ; Get the current terminal ID LD (TCODEF),A ; Update terminal type LD DE,255 LD C,RMNULL CALL SPBDOS LD (NNULLF),A ; Update number of nulls LD A,(MSPEED) ; LD (BDCDEF),A ; Update baud rate byte ; ; Determine the logon, logoff, and elapsed time ; CALL PRINT DEFB CR,LF,'Please wait...',0 LD HL,LOGSTR ; Get address of logon time LD DE,ONTIM ; Point to where to put it LD BC,8 ; No. of bytes LDIR ; Move em CALL GETTIM ; Get the current time LD HL,TIME ; Point to the time string LD DE,OFFTIM ; Where to put it LD BC,8 ; LDIR ; Move it CALL CALCTIM ; Calculate the elapsed time LD HL,ELPTIM ; Get binary minutes CALL GETBIN ; Hours (as minutes) in a LD E,A ; By multiplying by 60 LD D,0 LD L,60 LD H,0 CALL MLDL LD A,L PUSH AF ; Save it LD HL,ELPTIM+3 ; Point to minutes CALL GETBIN ; Get minutes (binary in a) POP BC ; Restore hours (as minutes) ADD A,B ; Get total minutes in-line LD B,A ; Hold that thought... LD A,(TOTMEF) ; Get current time used ADD A,B ; Add this session and resave ... LD (TOTMEF),A ; Place in user's record ; UPDACC: LD HL,JUNK ; Get the junk location LD DE,ASCACC ; Get the location of ASCII Access SBC HL,DE ; See if they are the same location JR Z,NOUPD ; Sysop not using ASCACC so skip update LD A,(ASCACC) ; Special to update access from SUB ASCII ; The low memory access storage area LD (ACESSF),A ; In case MBASIC has changed it ; ; Rewrite the record ; NOUPD: LD DE,1 LD C,RMWRT CALL SPBDOS LD HL,USERS ; Reopen the file CALL OPEN LD HL,USRLEN LD (RRSZ),HL LD HL,(USREC) CALL PUT ; Replace the record CALL CLOSE ; Close the file ; ; Don't include the Sysop in the caller's list ; LD A,(ACESS) CP 9 JP NC,SYSSKP LD HL,CALLRS CALL SPOPEN ; Open file for callers LD HL,64 LD (RRSZ),HL ; Set record size LD HL,0 ; Get record number CALL GET LD HL,(RNDBUF) ; Is first 2 bytes of record 0 PUSH HL ; Save this callers's record number INC HL ; Bump callers's record number LD (RNDBUF),HL ; Store it LD HL,0 ; Record number CALL PUT ; And write it ; ; And finally, write the 64 byte line to sequential record ; POP HL ; Get starting record number back LD (RRNO),HL LD A,' ' LD HL,RNDBUF ; Fill buffer with spaces LD (HL),A LD DE,RNDBUF+1 LD BC,63 LDIR LD DE,RNDBUF LD HL,DATE LD BC,5 LDIR ; Move date string into place INC DE LD HL,ONTIM LD BC,5 LDIR ; Start time LD A,'-' LD (DE),A INC DE LD HL,OFFTIM LD BC,5 LDIR ; Stop time INC DE LD A,(MSPEED) LD BC,6 LD HL,B300S CP 1 JR Z,DLDIR ; Prepare 300 bps string LD HL,B1200S CP 5 JR Z,DLDIR ; Prepare 1200 bps string LD HL,B2400S ; Else it's 2400 bps ; DLDIR: LDIR ; Move it INC DE LD HL,UNAME LD B,17+1 ; Make sure we move =< 17 CALL MOVNM ; MOVNM needs one extra character LD A,B ; Check if B already 0 OR A ; Set flags JR Z,CITY ; Yep, forget padding DEC DE ; Prevents too many spaces ; NDONE: INC DE ; Increment to fill the area DJNZ NDONE ; Continue until 'B' is zero ; CITY: INC DE ; Space character before start of city LD HL,CITST LD BC,19 ADD HL,BC LD B,20 ; ; Decrementing to last character of state ; CITY1: LD A,(HL) CP 'A' JR NC,CITY2 DEC HL DEC B JP Z,PDONE JR CITY1 ; ; Decrementing to last character ahead of state ; CITY2: LD (SAVEST),HL ; first character of state LD A,(HL) CP 'A' JR C,CITY3 DEC HL DEC B JR Z,CITY4 JR CITY2 ; ; Decrementing to last character of city ; CITY3: LD A,(HL) CP 'A' JR NC,CITY4 DEC HL DEC B JR NZ,CITY3 ; ; Now are at end of city and know how many characters that is ; CITY4: LD A,16 CP B JR NC,CITY5 LD B,A ; CITY5: LD C,B ; Save the value for now LD HL,CITST ; CITY6: LD A,(HL) AND 7FH ; Strip off any parity INC HL DJNZ CITY6 ; LD B,C ; Get the original value back INC B ; Increment for MOVNM LD HL,CITST CALL MOVNM LD B,1 LD A,C CP 15 JP NC,CITY7 INC C LD A,',' LD (DE),A LD A,17 SUB C LD B,A ; CITY7: INC DE DJNZ CITY7 ; LD HL,(SAVEST) INC HL LD A,(HL) LD (DE),A INC DE INC HL LD A,(HL) LD (DE),A INC DE JR PDONE ;..... ; ; SAVEST: DEFW 0 ; PDONE: LD DE,RNDBUF+61 ; Use last three spaces for cr-lf-0 LD HL,CRLFSTR LD BC,3 LDIR ; Leaves a null at the end (pretty trick) LD HL,(RRNO) CALL PUT ; Write last line CALL CLOSE ; All done ; SYSSKP: LD HL,REENTR LD (HL),0 ; Reset re-enter bit LD DE,0 LD C,RMWRT CALL SPBDOS ; Clear write lock ; ; Now print the session statistics even if the guy hung up, the Sysop ; might be interested. ; PSTATS: CALL PRINT DEFB CR,' ' DEFB CR,'Session Statistics' DEFB CR,LF DEFB CR,LF,'User.............. ',0 LD HL,UNAME LD B,NAMLEN ; Max chars to print CALL PRINTN ; CALL PRINT DEFB CR,LF,'Logoff............ ',0 LD HL,OFFTIM CALL PRINTM ; CALL PRINT DEFB CR,LF,'Logon............. ',0 LD HL,ONTIM CALL PRINTM ; CALL PRINT DEFB CR,LF,'Connect time...... ',0 LD HL,ELPTIM CALL PRINTM ; CALL PRINT DEFB CR,LF,'New uploads....... ',0 LD HL,(UPLODS) CALL PB2ASC ; CALL PRINT DEFB CR,LF,'New downloads..... ',0 LD HL,(DNLODS) CALL PB2ASC ; CALL PRINT DEFB CR,LF,'Upload total...... ',0 LD HL,(UPLDST) CALL PB2ASC ; CALL PRINT DEFB CR,LF,'Download total.... ',0 LD HL,(DNLDST) CALL PB2ASC CALL PRINT DEFB CR,LF,CR,LF DEFB ' Goodbye and thanks for calling ',0 LD HL,LOCSTR CALL PRINTM LD B,NAMLEN LD HL,UNAME CALL PRINTS CALL PRINT DEFB CR,LF,CR,LF,DEL,DEL,0 ; ; Now check to see if there is a carrier or not... ; CKCAR: LD C,MDCARCK ; See if carrier is still on CALL SPBDOS JP NZ,CKDON1 ; If yes, exit LD A,44H ; For Ram Disk users, backs up when LD (MSPEED),A ; carrier is lost ; ; Checks the current date. If past midnight, sets a maintenance flag ; into low memory at MSPEED for BYE5H to use in its LOGOFF routine. ; ; Open the index file and copy to memory ; CKDON1: CALL IOPEN CALL GET ; Get record CALL CLOSE ; Close file LD HL,IDATEF ; Move from buffer LD DE,IDATE ; To storage LD BC,NDXLEN ; This many bytes LDIR ; Move record ; ; New date routine ; LD IX,BDATE ; Get today's date LD IY,MUSRD ; Get last user update CALL DATDIF ; Compare them LD A,H ; H has the flags OR A JP P,CKDON2 ; Go update if less, otherwise exit LD A,66H ; Trips other maintenance pgms in BYE5 LD (MSPEED),A ; CKDON2: LD C,IMDONE ; Turn off the carrier CALL SPBDOS ; ; Print the CALLERS file ; HBRET: LD HL,CALLRS CALL OPEN CP 0FFH ; Did it exist? JP Z,HBRET3 ; If not, exit ; CALL PRINT DEFB CR,LF,'Previous callers',CR,LF,CR,LF,0 LD HL,64 LD (RRSZ),HL ; Set record size LD HL,0 ; Get record number CALL GET LD HL,(RNDBUF) ; Is first 2 bytes of record 0 LD (RRNO),HL ; Our starting record # LD C,LOGST ; Copying to disk log? LD E,0FFH CALL SPBDOS CP 77 JP Z,HBRET1 ; If not, exit LD A,10 LD (HBCNT),A ; HBRET1: LD HL,(RRNO) DEC HL LD A,H OR L ; Record zero? JP Z,HBRET2 ; Yup...get out CALL GET ; Nope... LD HL,RNDBUF CALL PRINTM ; Print it to the null LD A,(HBCNT) DEC A ; Decrement the count LD (HBCNT),A JR NZ,HBRET1 ; Looked at max number requested yet? ; HBRET2: CALL CLOSE ; ; All done now, return to BYE5, waiting for the next caller ; HBRET3: LD HL,(CCPSTK) LD SP,HL RET ; Return to BYE5 ;..... ; HBCNT: DEFB 12 ; Number of previous users to look at ; ;----------------------------------------------------------------------- ; local subroutines ; BYERROR:CALL FERR ; This is error trap from HBBSUBS DEFB CR,LF,'+ HBBSUBS error, aborting +',7,CR,LF,'$' ; FERR: POP DE LD C,STRING CALL SPBDOS JP HBRET ;..... ; ; Subroutines to handle user, index, and message files ; UOPEN: LD HL,USERS JP OPEN ; Get user info to memory ;..... ; ; IOPEN: LD HL,INDEX ; Point to index name CALL OPEN ; Open file LD HL,NDXLEN ; Length of record LD (RRSZ),HL ; Set into buffer LD HL,0 ; Set record number RET ;..... ; MOPEN: LD HL,MSGINDEX ; Point to index name CALL OPEN ; Open file LD HL,MNDXLEN ; Length of record LD (RRSZ),HL ; Set into buffer RET ;..... ; EATCHR: LD C,RDCON ; Check console status CALL SPBDOS OR A RET Z ; No characters, exit ; LD C,RDCON ; Get the character CALL SPBDOS CP ' ' ; Non-printing character? JR C,EATCH1 ; If yes, ignore and exit CALL PRINT ; Else remove from the display DEFB BS,' ',BS,0 ; EATCH1: XOR A ; Ignore this character JR EATCHR ; See if any more characters ;..... ; ; This routine will convert a binary number 0-99 in (A), to two ascii ; digits. ASCII is returned in (A)=most sign. nibble, (B)=LSN. ; BIN2ASC:CALL BINBCD ; First convert it to packed bcd LD B,A ; Save binary AND 0FH ; Get lsn ADD A,'0' ; Make ascii LD C,A ; Save it LD A,B ; Get binary again RRA RRA RRA RRA AND 0FH ADD A,'0' ; Make ascii, MSN in (A) LD B,C ; LSN in (B) RET ;..... ; ; This routine will convert a binary 0-99 number to packed BCD. ; Call with (A)=binary number, exits with (A)=BCD number ; BINBCD: PUSH DE LD E,255 ; -1 ; BLP: INC E ; Increment 10's counter SUB 10 ; Sub 10 each pass JR NC,BLP ADD A,10 ; Get the number back LD D,A LD A,E RLCA RLCA RLCA RLCA ADD A,D ; Put the two together POP DE RET ;..... ; ; Calculate the elapsed time - from TIMEDIF.ASM by S. Kluger ; CALCTIM:LD HL,ONTIM+6 ; Point to start time secs CALL GETBIN ; Get binary LD D,A ; Save it LD HL,OFFTIM+6 ; Stop time secs CALL GETBIN LD E,0 ; Reset the borrow flag SUB D ; Subtract JR NC,SKBS ; Skip if no borrow DEC E ; Else make e = ff ADD A,60 ; Make mod 60 ; SKBS: LD HL,ELPTIM+7 ; Point to elapsed time seconds CALL STORA LD HL,ONTIM+3 CALL GETBIN LD D,A LD HL,OFFTIM+3 CALL GETBIN INC E ; If not borrow JR NZ,SKBM1 ; Then skip INC D ; Else add borrowed value ; SKBM1: LD E,0 SUB D JR NC,SKBM2 ; Skip if no borrow DEC E ADD A,60 ; Make mod 60 ; SKBM2: LD HL,ELPTIM+4 CALL STORA ; Store it LD HL,ONTIM CALL GETBIN LD D,A LD HL,OFFTIM CALL GETBIN INC E JR NZ,SKBH1 INC D ; SKBH1: SUB D JR NC,SKBH2 ADD A,24 ; Add 24 hrs ; SKBH2: LD HL,ELPTIM+1 JR STORA ; GETBIN: LD A,(HL) ; Get tens AND 0FH LD B,A ; Save XOR A LD C,10 ; Set up multiplier ; MUL: ADD A,C DEC B JR NZ,MUL LD B,A ; Save tens INC HL ; Point to units LD A,(HL) AND 0FH ; ADD A,B ; Add tens RET ; Return value in ac ;..... ; STORA: LD B,-1 ; TLP: INC B SUB 10 JR NC,TLP ADD A,10 OR 30H LD (HL),A DEC HL LD A,30H ADD A,B LD (HL),A RET ;..... ; ;*********************************************************************** ; ; SUBROUTINE: HASH ; PURPOSE: Calc pos'n in USERS.BBS to start search ; INPUT: A =first character of last name ; OUTPUT: HL=pos'n in USERS.BBS to begin search ; USES: A,DE,HL ; ;*********************************************************************** ; HASH: SUB 41H ; Make it 0 thru 25 ADD A,A ; Double it LD HL,HSHTBL ; Point to start of table LD E,A ; Calc pos'n in table LD D,0 ADD HL,DE LD A,(HL) ; Get starting position in HL INC HL LD H,(HL) LD L,A RET ;..... ; EBUF: DEFS 64 ; Edit string buffer RBUF: DEFS 64 ; Replacement string buffer ELEN: DEFB 0 ; Length of old string RLEN: DEFB 0 ; Length of new string NEWFRE: DEFW 0 ; Temp storage DIFF: DEFW 0 ; Ditto COLUMN: DEFB 0 ; Current column counter CRS: DEFB 0 ; Carriage return counter OLDSEC: DEFB 0 MTOTMP: DEFS 30 MSUBTMP:DEFB 'Exit Comment' ; MSUBLEN EQU $-MSUBTMP ; MSUB: DEFS 26-MSUBLEN MTOREC: DEFW 0 HSHREC: DEFW 0 STRTMP: DEFW 0 PFLAG: DEFB 0 TLINES: DEFB 0 ; AUTOP0: DEFB 'MM/DD/YY at ' AUTOP1: DEFB 'HH:MM HBYE auto-purged ' AUTOP2: DEFB 'nn user(s) and ' AUTOP3: DEFB 'nn message(s)',0,0 BYESTR: DEFB 'BYE' UPLODS: DEFW 0000 UPLDST: DEFW 0000 DNLODS: DEFW 0000 DNLDST: DEFW 0000 ONTIM: DEFB '00:00:00',0 OFFTIM: DEFB '00:00:00',0 ELPTIM: DEFB '00:00:00',0 B300S: DEFB ' 300 bps ' B1200S: DEFB ' 1200 bps ' B2400S: DEFB ' 2400 bps ' DELUSR: DEFB 0 DELMSG: DEFB 0 LINES: DEFB 0 CCPSTK: DEFW 0 DELLEV: DEFB 0 TMPSTK: DEFW 0 ; DEFS 128 ; Stack area ; STACK EQU $ ; MSG: DEFW 0 ; Message entry storage MSGARR: DEFW 0 ; Storage for message pointers HBSEND: DEFS 0 ; END