; HCHAT.Z80 v1 17 Apr 88 ; ; By Irv Hoff, based on Russ Pencin's PBBS, based on Simon Ewin's EMX. ; ;----------------------------------------------------------------------- ; ; This program allows the user to CHAT 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, HCHAT will ask the user if ; he wants to leave a note to the Sysop, if he does, HCHAT will chain ; to HNOTE. You must set the name of your HNOTE program at the label ; "HNOTE:". You may change the NOTE question at label "NOTIN:". ; ; Assemble this program and place it on A0: as CHAT.COM. ; ; 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. ; ;----------------------------------------------------------------------- ; NO EQU 0 YES EQU NOT NO ; ; Chat mode can now be used after midnight, set equates in ; HBBSHDR.INC to whatever you want for CHAT0 (available from) ; and CHAT1 (available to) times. Set both the same for "al- ; ways available". (I like from 10 am through midnight to 2 am.) ; ; 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 NOTE.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 following equate YES if using ZCMD29 with its AUTO ; equate also set yes. This will tell the user to manually ; call up the NOTE.COM pgm. Else set NO, and it can come up ; automatically. ; - Notes by Irv Hoff ; ;----------------------------------------------------------------------- ; AUTO EQU NO ; Yes if using ZCMD with BYE autoload ; 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 ; HNOTE: DEFB 4,'NOTE' ; Length and Name of your HNOTE program DEFB 0 ; Null terminated ; NOTIN: DEFB CR,LF,CR,LF DEFB 'The Sysop is not available at this time',CR,LF ; IF NOT AUTO DEFB 'Would you like to leave a private note? ',0 ENDIF ; NOT AUTO ; IF AUTO DEFB 'Type NOTE at the CP/M prompt to leave him a note' DEFB CR,LF,0 ENDIF ; AUTO ; START: LD C,SETUSR LD E,241 CALL SPBDOS ; See if BYE5 is active CP 77 JP Z,BEGIN ; Yes, proceed CALL PRINT ; Else abort DEFB CR,LF,'BYE not available, aborting...',CR,LF,0 RET ;... ; BEGIN: LD HL,0 ADD HL,SP LD (CCPSTK),HL ; Save the return address LD SP,STACK ; Install our stack LD E,255 LD C,RMMXT CALL SPBDOS ; Get MXTIME from BYE LD (MXTIME),A ; And store it LD E,0 LD C,RMMXT CALL SPBDOS ; Set unlimited time during CHAT LD C,RMRTC CALL SPBDOS ; Call TCHECK and return with TON LD (OLDTON),A ; Save the old time on amount LD C,SETUSR LD E,0FFH CALL SPBDOS ; Get current user LD (OLDUSR),A ; And save it LD C,CURDRV CALL SPBDOS ; Get current drive LD (OLDDRV),A ; And save it CALL PRINT ; Print all the neat stuff DEFB CR,LF,'HCHAT v',0 LD A,(VER) ; Get the version number LD L,A LD H,0 CALL PB2ASC 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 ; ;----------------------------------------------------------------------- ; YAK: LD A,(FCB+1) CP 'C' JP Z,YAKOK LD E,255 ; See if the bell is on LD C,RMBELL CALL SPBDOS OR A JP Z,NOYAK ; Nope..sorry charlie... CALL PRINT DEFB CR,LF,0 CALL GETTIM ; Get time and convert to binary LD A,CHAT0 ; Available 'from' hour LD B,CHAT1 ; Available 'to' hour CP B ; See which is larger LD A,(BTIME) ; Get current time JP Z,OKYAK ; If same times, ok to yak JR C,YAK2 ; 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) ; YAK2: 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: 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,AVAILF ; Save it for callers file update LD DE,AVAIL LD BC,USRLEN LDIR CALL PRINT DEFB CR,LF,'Hold on, ',0 LD B,NAMLEN LD HL,UNAME CALL PRINTN CALL PRINT ; Print: DEFB ' - You may use ^C or ^X to abort',CR,LF,CR,LF,0 CALL PRINT DEFB ' |',0 LD A,ALERT ; Get the number of tries allowed LD (LINES),A ; BARS1: CALL PRINT ; Print bar and space DEFB '-',0 LD A,(LINES) DEC A ; Done with bars? LD (LINES),A JR NZ,BARS1 ; Not done, do it again ; CALL PRINT DEFB '|',CR,LF,0 LD A,ALERT ; Restore value LD (LINES),A ; Temp counter CALL PRINT DEFB 'Ringing: ',0 ; ; Attempt to alert operator ; RNGBEL: CALL DELAY ; Exit if operator answers CALL PRINT ; Print bell, period, space DEFB BEL,'.',0 ; Ring the bell LD A,(LINES) DEC A ; Done with alert attempts? LD (LINES),A ; Store new count JR NZ,RNGBEL ; Not zero yet keep trying JP NOYAK ; Give up ;..... ; ; Delay routine to wait between beeps ; DELAY: CALL GETTIM LD A,(BTIME+2) LD (OLDSEC),A PUSH HL ; Save the values, consume some time PUSH DE PUSH BC PUSH AF ; DELAY1: LD C,CONST ; See if a character was typed CALL SPBDOS OR A JR Z,DELAY2 ; If not, keep going LD C,RDCON ; Else get the character CALL SPBDOS JR DELAY3 ; And exit ;... ; DELAY2: CALL GETTIM LD A,(OLDSEC) LD HL,BTIME+2 CP (HL) JR Z,DELAY1 ; ; Return if second has changed - ; POP AF POP BC ; Restore the values POP DE POP HL RET ;... ; DELAY3: CP ESC ; Was it the right answer? JR Z,YAKOK CP ' '+1 JR C,DELAY4 PUSH AF ; Save the character for now CALL PRINT DEFB BS,' ',BS,0 POP AF ; DELAY4: AND 1BH ; Allows upper, lower or control CP 'C'-40H JR Z,DELAY5 CP 'X'-40H JR Z,DELAY5 ; Yes? then go back to CP/M CP 'K'-40H JR NZ,DELAY2 ; None of these, ignore ; DELAY5: LD SP,STACK ; Fix the stack JP NOYAK ;..... ; ; Operator is present ; YAKOK: 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,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 C,LOGST ; Else turn it off during CHAT LD E,0 CALL SPBDOS ; YAKOK1: LD SP,STACK ; Fix stack LD C,RMRTC ; Get the current time on CALL SPBDOS LD (OLDTON),A ; Store it LD E,255 LD C,RMMXT CALL SPBDOS LD (OLDMXT),A ; Get old max time OR A JR Z,YAKOK2 ; User already has unlimited time LD E,90 ; Give him plenty of time to chat ADD A,E ; Add to old max time LD E,A LD C,RMMXT ; Reset to new max time CALL SPBDOS ; YAKOK2: CALL PRINT DEFB CR,LF,CR,LF DEFB 'Operator is available, please go ahead...',CR,LF DEFB 'Use three to exit',CR,LF,0 ; YAKOK3: LD IY,LINES LD (IY),3 ; YAKOK4: CALL PRINT DEFB CR,LF,0 LD B,68+15 ; Input length + 15 for simple linewrap XOR A ; Allow echo LD C,A ; No caps forced LD D,1 ; Turns linewrap on CALL INPUT ; Get line OR A JR NZ,YAKOK3 DEC (IY) JR NZ,YAKOK4 LD A,(OLDMXT) OR A JP NZ,YAKOK5 LD E,A LD C,RMMXT CALL SPBDOS JP REXIT ;... ; ; Add time to maximum time ; YAKOK5: PUSH AF LD C,RMRTC CALL SPBDOS PUSH AF LD A,(OLDTON) LD B,A POP AF SUB B LD B,A POP AF ADD A,B LD E,A LD C,RMMXT CALL SPBDOS JP REXIT ;..... ; NOYAK: LD HL,NOTIN ; Load nobody home message CALL PRINTM ; IF AUTO JP REXIT ENDIF ; AUTO ;..... ; ; If not using ZCMD29 in AUTO-LOAD, call up the NOTE.COM program to ; leave a message ; CALL GETCH CALL CAPS CALL ECHO CP 'Y' JP NZ,REXIT LD A,(MXTIME) ; Get MXTIME back OR A JR Z,LNOTE ; Load the note program PUSH AF ; Save the old max time LD C,RMRTC ; Get TON in 'A' CALL SPBDOS ; 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,RMMXT CALL SPBDOS ; Set new MXTIME ; LNOTE: CALL PRINT DEFB CR,LF,'Loading NOTE...Please wait...',CR,LF,0 CALL RESTR LD HL,HNOTE ; Load up command pointer PUSH HL ; Set up for command buffer JP CPM+30 ; Move command without logging into INITAR. ; REXIT: CALL PRINT DEFB CR,LF,0 LD A,(ACESS) ; See if SYSOP CP 8 JR NC,REXIT1 ; If yes, ignore turning DISK LOG on 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,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 C,LOGST ; BYE DISKLOG status request LD E,1 ; Turn DISKLOG back on, then CALL SPBDOS ; REXIT1: LD A,(MXTIME) ; Get MXTIME back OR A JR Z,REXIT2 PUSH AF ; Save the old max time LD C,RMRTC ; Get TON in 'A' CALL SPBDOS ; 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,RMMXT CALL SPBDOS ; Set new MXTIME ; REXIT2: CALL RESTR LD HL,(CCPSTK) LD SP,HL ; Restore original stack RET ; And exit ;..... ; ;----------------------------------------------------------------------- ; ; Subroutines ; ;----------------------------------------------------------------------- ; RESTR: LD A,(OLDDRV) ; Restores the drive/user areas LD E,A LD C,SELDSK CALL SPBDOS ; Restore original drive LD A,(OLDUSR) LD E,A LD C,SETUSR CALL SPBDOS ; Restore original user area RET ;..... ; EATCHR: LD C,CONST ; 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 ;..... ; NOMSG: DEFB 'No ',CR,LF,0 COLUMN: DEFB 0 ; Current column counter CRS: DEFB 0 ; Carriage return counter MXTIME: DEFB 0 ; Temporary storage for MXTOS OLDMXT: DEFB 0 ; OLD MTOS OLDSEC: DEFB 0 OLDTON: DEFB 0 ; Old TOS OLDDRV: DEFB 0 OLDUSR: DEFB 0 LINES: DEFB 0 CCPSTK: DEFW 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