TITLE 'PCHAT.MAC, version 5.00 October 09/90' ; Filename PCHT50.MAC ; Author Ian Cottrell ; Language Z-80 Assembler ; Last Update Oct 09/90 ; By Ian Cottrell ; This program allows the user to CHAT with the Sysop, if the bell ; flag in BYE is on and the Chat times are correct. If either of these ; two conditions prevent him from chatting, PCHAT will ask the user if ; he wants to leave a note to the Sysop. If he does, PCHAT will chain ; to PMSG. You must set the name of your PMSG program at the label ; PMSG:. You may change the NOTE question at label NOTIN:. ; Assemble this program and place it on A0: as CHAT.COM. ; Requires BYE5 and PBBS v4.5 or later ; The Sysop may bypass the time and BYE check by entering CHAT C. This ; was added to allow the Sysop to talk to a user even though the chat ; time was not within the limits. ; PCHAT is based on code from PBBS and 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) ;--------------------------------------------------------------- ;----------------------------------------------------------------------- ; Chat mode can now be used after midnight, set equates in ; PBBSDB.HDR to whatever you want for CHAT0 (available from) ; and CHAT1 (available to) times. Set both the same for ; "always available". ; If using ZCMD29 with the AUTO option set YES so it will ; autoload BYE on a power loss (to resume normal operation ; with no operator present to restore the system), this ; will prevent PCHAT from automatically loading the PMSG.COM ; program since the autoload feature is disabled if BYE.COM ; is already present. (Else BYE.COM would be reloaded on ; each warm boot, which would cause the phone to hang up.) ; Set the AUTO equate to YES if using ZCMD29 with its AUTO ; equate also set yes. This will tell the user to manually ; call up the PMSG.COM program (which SHOULD be renamed to ; NOTE.COM). Else set NO, and it can come up automatically. ; - Notes by Irv Hoff ; - Additions by Ian Cottrell ;--------------------------------------------------------------- ; NOTE: This file MUST be linked to PBBSUBS.REL.... INCLUDE PBBSEQU.HDR ; PBBS configuration equates IF M80 .Z80 ; Needed for M80 IF LINK80 CSEG ELSE ASEG ORG 100H ENDIF ; LINK80 ENDIF ; M80 AUTO EQU NO ; Yes if using ZCMD with BYE autoload 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 'PCHAT ' ; Name DB 'Release v ',0 ; Status VER:: DB 5 ; Version VERR:: DB 00 ; Revision VERDAT: DB 90 ; Year DB 10 ; Month DB 09 ; Day INCLUDE PBBSDB.HDR ; PBBS configuration data INCLUDE BDOSHDR.MAC ; Time and date conversions PNOTE: DB 4,'NOTE',0 ; Length and name of your note program (PMSG) NOTIN: DB CR,LF,'The Sysop is not available at this time',CR,LF IF AUTO DB 'Type NOTE at the system prompt to leave him a note' DB CR,LF,0 ELSE DB 'Would you like to leave a note? ',0 ENDIF ; [NOT] AUTO ;---------------------------------------------------------------------------- ; Start of Progam ;---------------------------------------------------------------------------- START: LD C,BEXIST ; Check for the presence of BYE LD E,241 CALL BDOS ; See if BYE5 is active CP 77 JP Z,BEGIN ; Yes, proceed CALL PRINT ; Else abort DB CR,LF,'BYE not available, aborting...',CR,LF,0 RET ; BYE is active. Set a local stack, record the user's time on system ; and see if the Sysop is available. BEGIN: LD (CCPSTK),SP ; Save system stack LD SP,STACK ; Install our stack LD E,255 LD C,MXTIME CALL BDOS ; Get MXTIME from BYE LD (MAXTIM),A ; and store it LD E,0 LD C,MXTIME ; Use BYE to set CALL BDOS ; unlimited time during CHAT LD C,RTCCHK CALL BDOS ; Call TCHECK and return with TON LD (OLDTON),A ; Save the old time on amount LD C,LOGUSR LD E,0FFH CALL BDOS ; Get current user LD (OLDUSR),A ; and save it LD C,25 CALL BDOS ; Get current drive LD (OLDDRV),A ; and save it CALL PVER ; Print the version LD E,SYSDRV LD C,LOGDRV CALL BDOS ; Log system drive LD E,SYSUSR LD C,LOGUSR CALL BDOS ; Log system user area YAK: LD A,(FCB+1) ; Check command line CP 'C' ; for a 'C' JP Z,YAKOK ; If there, skip bell & time check LD E,255 ; See if the bell is on LD C,BELLON CALL BDOS OR A JP Z,NOYAK ; Nope. Sorry, Charlie... CALL PCRLF CALL GETTIM ; Get time and convert to binary LD A,CHAT0 ; Available start hour LD B,CHAT1 ; Available end hour CP B ; See which is larger LD A,(BTIME) ; Get current time JP Z,OKYAK ; If same times, ok to yak JR C,YAK1 ; Asking for up to 11 pm or less, exit ; This area handles times past midnight, such as 1800 to 0100, etc. CP CHAT1 ; Get quitting time JR C,OKYAK ; If less, ok to ask for Sysop CP CHAT0 ; Get starting time JR NC,OKYAK ; If more, ok to ask for Sysop JP NOYAK ; This area handles times up to 2300 (11 pm). YAK1: CP CHAT0 ; Get starting time JP C,NOYAK ; If less, do not ask for Sysop CP CHAT1 ; Get quitting time JP NC,NOYAK ; If more, do not ask for Sysop ; Ok to proceed ; User is on system, and has typed CHAT. Allow the user to leave a ; private note if CHAT not available and then exit back to CP/M. OKYAK: CALL UOPEN ; Open users file LD HL,(USREC) ; Reget the user record no. in HL CALL GET ; Get record into buffer CALL CLOSE ; Users file LD HL,AVAILF ; Save user record LD DE,AVAIL ; for callers file LD BC,USRLEN ; update LDIR CALL PRINT DB CR,LF,'Hold on, ',0 LD HL,UNAME LD B,30 CALL PRINTN CALL PRINT ; Print: DB ' - You may use ^C or ^X to abort',CR,LF,LF DB ' |',0 LD A,ALERT ; Get number of 'rings' LD (LINES),A ; LINES=ALERT LD IY,LINES ; Point to counter BARS1: CALL PRINT ; Print bar and space DB '-',0 DEC (IY) ; Done with bars? JR NZ,BARS1 ; Not done, do it again CALL PRINT DB '|',CR,LF,0 LD A,ALERT ; Restore number of rings LD (LINES),A ; Temp counter CALL PRINT DB 'Ringing: ',0 ; Attempt to alert operator. RNGBEL: CALL DELAY CALL PRINT ; Ring the bell and DB BEL,'.',0 ; print a period DEC (IY) ; Done with alert attempts? JR NZ,RNGBEL ; If not zero yet, keep trying JP NOYAK ; Else, give up ; Delay routine to wait between beeps DELAY: CALL GETTIM ; Get time and convert to binary LD A,(BTIME+2) ; Get seconds (binary) LD (OLDSEC),A ; and save it PUSH HL ; Save the values, consume some time PUSH DE PUSH BC PUSH AF ; Check for user's input. DELAY2: LD E,0FFH LD C,6 CALL SPBDOS ; Get console status OR A ; Character ready? JR NZ,DELAY4 ; If so, go check it out DELAY3: CALL GETTIM ; Else, get the time (binary) again LD A,(OLDSEC) ; Compare old LD HL,BTIME+2 ; seconds to CP (HL) ; new seconds JR Z,DELAY2 ; If unchanged, continue POP AF ; Else, restore values and return POP BC POP DE POP HL RET DELAY4: AND 31 ; Convert to equivalent CTL character CP 'X'-40H ; CTL-X, user has cold feet? JR Z,DELAY5 ; If so, then go back to system CP 'K'-40H ; CTL-K JR Z,DELAY5 CP 'C'-40H ; CTL-C to quit? JR Z,DELAY5 ; Ok, then back to system CP ESC ; Was it the right answer? JR Z,YAKOK JR DELAY3 ; If not, keep timing DELAY5: LD SP,STACK ; Restore local stack JP NOYAK ; Operator is present. YAKOK: IF DSKLOG LD E,0FFH ; Ask for status LD C,SDSKLOG ; BYE DISKLOG status request CALL BDOS CP 77 ; 77 says "NO is set in BYE5" JR Z,YAKOK1 ; Exit with no change to the flag LD A,(DSKFLG) ; See if DISKLOG is in use OR A JR Z,YAKOK1 ; Exit if not LD E,0 ; Else turn it off during CHAT LD C,SDSKLOG CALL BDOS ENDIF YAKOK1: LD SP,STACK ; Reset local stack CALL PRINT DB CR,LF,LF,'Operator is available, please go ahead...',CR,LF DB 'Use three to exit',CR,LF,0 YAKOK2: LD IY,LINES ; Use LINES a counter LD (IY),3 ; Set to 3 YAKOK3: CALL PCRLF LD B,70+15 ; Input length + 15 for autowrap XOR A ; Allow echo LD C,A ; No caps forced LD D,1 ; Want line-wrap at 72rd character CALL INPUT ; Get line OR A JR NZ,YAKOK2 DEC (IY) JR NZ,YAKOK3 JP REXIT NOYAK: LD HL,NOTIN ; Nobody home message CALL PRINTM IF AUTO JP REXIT ELSE CALL GETCH CALL CAPS CALL ECHO CP 'Y' JP NZ,REXIT LD A,(MAXTIM) ; Get maximum time back OR A JR Z,LNOTE ; Load the note program (PMSG renamed to NOTE) PUSH AF ; Save the old max time LD C,RTCCHK ; Get TON in 'A' CALL BDOS ; Get current time on PUSH AF ; Save it LD A,(OLDTON) LD B,A ; Move to B register POP AF ; Get old max time back SUB B ; Get difference LD B,A ; Swap POP AF ; Get original back ADD A,B ; Add 'em LD E,A LD C,MXTIME CALL BDOS ; Set new MXTIME LNOTE: CALL PRINT DB CR,LF,'Loading NOTE...Please wait...',CR,LF,0 CALL RESTR ; Restore user's original drive/user area LD HL,PNOTE ; Load up command pointer PUSH HL ; Set up for command buffer JP CPM1 ; Execute note program ENDIF ; AUTO REXIT: IF DSKLOG LD A,(ACESS) ; Access level CP COSYS ; Sysop? JR NC,REXIT1 ; If yes, ignore DISKLOG LD E,0FFH ; Ask for status LD C,SDSKLOG ; BYE DISKLOG status request CALL BDOS CP 77 ; 77 says "NO is set in BYE5" JR Z,REXIT1 ; Exit with no change to the flag LD A,(DSKFLG) ; See if DISK LOG was turned off OR A JR Z,REXIT1 ; If zero, was never in use LD E,1 ; Turn DISKLOG back on, then LD C,SDSKLOG ; BYE DISKLOG status request CALL BDOS ENDIF REXIT1: LD A,(MAXTIM) ; Get maximum time back OR A ; Unlimited? JR Z,REXIT2 ; If so, return to system ; User did not have unlimited time, adjust BYE's Time On System. PUSH AF ; Save the old max time LD C,RTCCHK ; Get TON in A CALL BDOS ; Get current time on PUSH AF ; Save it LD A,(OLDTON) LD B,A ; Move to B POP AF ; Get new back SUB B ; Get difference LD B,A ; Swap POP AF ; Get original back ADD A,B ; Add 'em LD E,A LD C,MXTIME CALL BDOS ; Set new MXTIME REXIT2: CALL RESTR ; Restore user's original drive/user area LD SP,(CCPSTK) ; Restore original stack RET ; and exit ; Subroutines. RESTR: LD A,(OLDDRV) ; Restores the drive/user areas LD E,A LD C,LOGDRV CALL BDOS ; Restore original drive LD A,(OLDUSR) LD E,A LD C,LOGUSR CALL BDOS ; Restore original user area RET EATCHR: LD E,0FFH ; Request LD C,6 ; direct console input CALL SPBDOS OR A ; Character recieved? JR NZ,EATCHR ; If yes, loop RET ; Else, all done COLUMN: DB 0 ; Current column counter CRS: DB 0 ; Carriage return counter MAXTIM: DB 0 ; Temporary storage for MXTOS OLDTON: DB 0 ; Old TOS OLDSEC: DB 0 ; Old seconds OLDUSR: DB 0 OLDDRV: DB 0 LINES: DB 0 CCPSTK::DW 0 TMPSTK::DW 0 DS 128 ; Stack area STACK EQU $ MSG:: DW 0 ; Message entry storage starts after ; linked PBBSUBS.REL file MSGARR::DW 0 ; Storage for message pointers END