TITLE NBYE.MAC 12 August 1984 ENTRY BYELDR ; ; NBYE10.MAC -- Yet Another Remote Console Program for CP/M and MODEM ; ; Gary Case ; 585 Big Sky Court ; Colorado Springs, CO ; 80919 ; (303) 599-0744 ; ; *** Keep date and version current in VERMSG and DATMSG below *** ; VERMSG MACRO DB 'Version 1.0' ENDM ; DATMSG MACRO DB '12 August 1984' ENDM ; ; ;****************************************************************************** ; ; Version 1.0 -- 12 August 1984 ; ; This program is the result of frustrations with the multiple versions of ; BYE-type programs and the large number of options these programs support. ; Further, the BYE-type programs tend to always be customized for a particular ; system, so (in my opinion) the auto-relocating loader used in BYE3 and its ; offshoots is unnecessary, given its restrictions and tendency to incorrectly ; relocate constants. This program uses the .PHASE directive in Microsoft's ; M80 assembler to create a version of BYE for the desired location, which ; can be below the CCP, above the BIOS, or in between various CPM components. ; I use it, for example, in between the CCP and BDOS. ; ; ; The I/O-specific, modem-specific, and clock-specific routines must be ; separately coded in files named NBYEIO.INC, NBYEMDM.INC, and NBYECLK.INC ; respectively. If an S-100 modem is used, NBYEIO.INC is not included, since ; these modem cards do not require separate input/output ports. The ; requirements for the NBYEMDM.INC and NBYECLK.INC routines are documented in ; NBYEMDM.DOC and NBYECLK.DOC. The NBYEIO.INC file requirements are a ; function of the specific NBYEMDM.INC routines. NBYECLK.INC is not required ; if the system does not include clock support. ; ; Any implementation-specific special code is supported through NBYEUSER.INC. ; This contains 5 routines which NBYE calls at specific instances. See the ; file NBYEUSER.DOC for specifications for these routines. ; ; The primary changes between this BYE program and the existing BYE3-type ; programs are: ; ; -- Substantial reduction in the number of assembly-time options. ; Most of the options useful in running bulletin board systems ; have been incorporated as 'always there' code, with option bytes ; that allow the functional state to be controlled. Several of the ; options in BYE3 were not even referenced (!) and have been ; eliminated. ; ; -- Removal of much code that is essentially hardware dependent to ; the NBYEMDM.INC file. Examples of this are the multiple checks ; for ringing state in BYE3 (If necessary, let the modem-dependent ; code do this -- if 'MRING' says the phone's ringing, believe it!), ; the multiple baud rate checks (Most rates in BYE3 are really PMMI ; dependent), etc. ; ; -- Removal of the loader routine and switching to the Microsoft M80 ; assembler vice Digital Research's ASM. ; ; -- Substantial cleanup of the comments throughout the program. ; ; -- A well-defined (I hope) set of modem interface routines. ; There may be an equivalent set of documentation for BYE3, but ; I'm not aware of it, and it seems unlikely given the amount of ; residual PMMI-dependent code throughout the BYE3 programs. ; ; -- Moved the low-memory addresses so they don't conflict with ; 'standard' (is there any such thing?) ZCPR2 addresses. Be sure ; your version of XMODEM uses the same addresses. ; ; ;****************************************************************************** ; ; Configuration Section, Part 1 -- Required Items ; ; TRUE EQU -1 ;Conditional assembly values FALSE EQU 0 ; ; S100MDM EQU FALSE ;Using an S-100 card modem? (e.g. PMMI) ;If FALSE, a NBYEIO.INC file is required. ; BYEADR EQU 0C000H ;Define the starting address for BYE. To ;determine this, do the following: ; ; 1) Assemble with BYEADR EQU 0 and note the ; value of ZZZBYE in the symbol table. ; 'M80 ,TTY:=NBYE' will terminate with ; this value on the CRT since it's the ; last (alphabetically) label. ; ; 2) Subtract the value of ZZZBYE from the ; starting address of your BDOS if you ; want BYE to run underneath CP/M, or ; from the highest memory address in ; your system if you want it to run above ; CP/M. Note that in the latter case ; your CP/M system must not extend beyond ; the BYE starting address. ; ; CALLBAK EQU TRUE ;Want callback feature? This is ignored if ;the MRING entry in NBYEMDM.INC returns a ;connect status (see NBYEMDM.DOC). ; ; HAVCLK EQU TRUE ;Is the time and date available? If TRUE ;a NBYECLK.INC file is required. ; ; DUAL$IO EQU TRUE ;Want local console linked with modem? ;If TRUE either can use the computer while a ;remote user is active. Handy for 'chatting' ;with the remote user. ; ; ;****************************************************************************** ; ; Configuration Section, Part 2 -- Optional Items ; ; VERBOSE EQU TRUE ;Want messages on local console showing status ;of the BYE program at all times? ;(e.g. 'Waiting for Ring', 'Ringing', etc.) ; BASE EQU 0 ;Base address of the CP/M System ; ; MHZ EQU 4 ;Clock speed of your computer. ;(Not used by NBYE, but available for the delay ; routines in the NBYEMDM.INC insert) ; ; CLRMSG MACRO ;String that clears your CRT. If not desired DB ESC,'*' ;just use DB ''. Suggest a few nulls at the DB 0,0,0,0,0,0 ;end for timing purposes. ENDM ; ; ; *** Communication with XMODEM, etc. ; ; NOTE: If any (or all) of the following are not desired just ; set them all to the same harmless address anywhere ; in memory. ; CHOUR EQU BASE+056H ;Current hour CMIN EQU BASE+057H ;Current minute LHOUR EQU BASE+050H ;Logon hour LMIN EQU BASE+051H ;Logon minute ; STATUS EQU BASE+053H ;Status of current user ; 0 ==> Non-Priveleged <>0 ==> Priveleged ; (No Time Limits) ; MSPEED EQU BASE+058H ;Modem Speed Indicator ;(See NBYEMDM.DOC) ; UPLOAD EQU BASE+054H ;Count of files Uploaded by Current User DNLOAD EQU BASE+055H ;Count of files Downloaded by Current User ; ; ; *** Access Constraints ; MAXDRV EQU 'B' ;Maximum consecutive drive caller can select MAXUSR EQU 7 ;Maximum user area caller can select EXCDRV EQU 'M' ;Exception drive (i.e. 'M' for pseudo-disk) ;(If none, just use 'A') ; MAXIDLE EQU 10 ;Number of minutes the remote caller can do ;nothing before he will be automatically ;logged out (0 ==> No Limit, Max of 255) ; IDLEKNT EQU 38000 ;Only used if MAXIDLE <>0. 'Tunes' the delay ;loop used in counting the minutes specified ;by MAXIDLE. Adjust this number so the system ;actually kills the caller in MAXIDLE minutes. ; MAXMIN EQU 90 ;Maximum time a caller is allowed to stay on ;the system (0 ==> No Limit) ;This is only checked if HAVCLK is TRUE. ; PASSWD MACRO DB '' ;The desired logon password. Use: DB '' ENDM ;if no password is desired. ; ; ; *** Signon, Signoff and Warm Boot Messages -- Use DB '' ; if not desired. ; ; NOTE: If HIMSG is not sent (i.e. DB '') then ; the number of NULLs is set to 0 and no ; reply is expected. Otherwise the caller ; must enter a number between 0 and 9, and ; NULLS is set to this number. ; HIMSG MACRO DB CR,LF,LF DB 'Welcome, how many nulls do you need (0-9)? ' ENDM ; BYEMSG MACRO DB CR,LF,LF DB 'Good-bye, call again...',CR,LF ENDM ; WBMSG MACRO DB CR,LF,'Booting CP/M...' ENDM ; ; ; *** File names -- Must be disk number (0 ==> Default, 1 ==> A:, etc.) ; followed by exactly 11 characters if used, else ; must be DB '' ; FILEUSR EQU 0 ;User area for the following files. Not used ;if running under CP/M 1.4 ; ; WELFIL MACRO ;Welcome File -- sent after HIMSG response DB 1,'WELCOME TXT' ENDM ; ; ONCOM MACRO ;File to execute at logon -- note this DB 1,'TIME COM' ;includes the filetype, allowing other than ENDM ;.COM files to be executed. ; ; BYECOM MACRO ;File to execute at user's logoff -- i.e. DB 1,'TIME COM' ;user typed 'BYE' or timed out. ENDM ;See note at 'ONCOM'. ; ; OFFCOM MACRO ;File to execute at abnormal logoff -- i.e. DB 1,'TIME COM' ;lost carrier or 'Nurdkey' abort by SYSOP. ENDM ;See note at 'ONCOM'. ; ; ;****************************************************************************** ; ; Fixed Equates ; ; ; *** ASCII equates ; NULL EQU 0 BELL EQU 7 BKSPC EQU 8 LF EQU 10 CR EQU 13 ESC EQU 27 RUBOUT EQU 127 ; ; ; *** CP/M Interface Locations ; WBOOT EQU BASE ;Warm boot vector address BDOS EQU BASE+5 ;User entry point for CP/M function calls FCB EQU BASE+05CH ;Default file control block ; ; ; *** Miscellaneous Items ; DBHEX MACRO VALUE D1 SET VALUE/16 IFT D1 GT 9 D1 SET D1+7 ENDIF D2 SET VALUE MOD 16 IFT D2 GT 9 D2 SET D2+7 ENDIF DB D1+'0',D2+'0' ENDM ; ;****************************************************************************** ; ; Loader Module ; ; BYELDR: ;Routine to load BYE in place. First checks to see if we've ;previously loaded BYE, and simply enters the already loaded ;module if so. ; ; LXI B,BLDFLG ;IS BYE ALREADY LOADED? LXI D,BNDFLG ;(AND UNALTERED) LXI H,BYE$IMAGE+(BLDFLG-BYE) LDAX B CMP M JNZ LDBYE ;...NO LDAX D CMP M JNZ LDBYE ;...NO INX B INX D INX H LDAX B CMP M JNZ LDBYE ;...NO LDAX D CMP M JNZ LDBYE ;...NO INX B INX D INX H LDAX B CMP M JNZ LDBYE ;...NO LDAX D CMP M JNZ LDBYE ;...NO LDA BYE ;...YES, ENTER THE ALREADY LOADED PROGRAM CPI JMP ; UNLESS THE FIRST FEW BYTES HAVE BEEN JNZ LDBYE ; DESTROYED LDA BYE+3 CPI JMP JNZ LDBYE LHLD BYE+4 LXI D,-START DAD D MOV A,H ORA L JZ BYE+3 ; LDBYE: LHLD BDOS+1 ;ARE WE LOADING BELOW THE ACTUAL BDOS? LXI D,-BYEADR DAD D JNC BYEHI ;...NO LHLD BDOS+1 ;...YES, COMPLETE BDOS REVECTORING SHLD BYE$IMAGE+1 LXI H,BYEADR SHLD BDOS+1 BYEHI: LXI H,BYE$IMAGE ;MEMORY IMAGE OF BYE LXI D,BYE ;EXECUTION ADDRESS LXI B,BYESIZE ;SIZE OF THE PROGRAM MOVBYE: MOV A,M ;MOVE THE PROGRAM IN PLACE STAX D INX D INX H DCX B MOV A,B ORA C JNZ MOVBYE CALL BJADR ;GET BIOS JUMP TABLE ADDRESS AND COUNT LXI D,BIOSVECT ;AND SAVE THE JUMP TABLE CALL MOVE LDA BASE+4 ;SET DISK/USER TO SELECT WHEN WE EXIT BYE STA BWBDU MVI C,12 ;GET CP/M VERSION NUMBER CALL BDOS MOV A,L ;AND SAVE FOR BYE'S USE STA CPMVER LHLD WBOOT+1 ;STORE WARM BOOT REVECTORING ADDRESS FOR 'BYE' INX H SHLD WBREVEC LXI D,11 ;AND THE ADDRESS OF THE BIOS PRINTER DRIVER DAD D SHLD LSTADR LDA USRFLG ;INIT LOG COUNTERS IF NOT PREVIOUSLY DONE CPI 0AAH CNZ RESET LDA USRFLG+1 CPI 055H CNZ RESET LXI H,BASE+080H ;OPTION ON THE COMMAND LINE? MOV A,M ORA A JZ START ;...NO MOV B,A ;...MAYBE, SKIP LEADING BLANKS SKPBKS: INX H MOV A,M CPI ' ' JNZ CHKOPT DCR B JNZ SKPBKS JMP START ;...NO, THERE'S NOTHING BUT BLANKS CHKOPT: CPI '/' ;...MAYBE, SEE IF WE'VE FOUND A '/' JNZ START ; AND ABORT IF NOT INX H ;...FOUND A '/' -- NOW CHECK THE OPTION MOV A,B ;FIRST VALIDATE THE COMMAND LINE AND IGNORE CPI 2 ;THE '/x' IF ANYTHING FOLLOWS THE x JNZ START IFT VERBOSE CALL LCLMSG DB CR,LF,'...Initializing the MODEM ',0FFH ENDIF ;VERBOSE CALL MINIT ;BE SURE MODEM GETS INITIALIZED MOV A,M ;NOW GET OPTION CHARACTER AND PROCESS IT: STA OPTION ;(FIRST SAVING FOR LATER USE) CPI 'A' ;...ANSWER IMMEDIATELY JZ ANSWER CPI 'C' ;...ANSWER AND EXECUTE A .COM FILE (OR EQUIV) JZ ANSWER CPI 'R' ;...RESET COUNTERS CZ RESET JMP START ;...AND AWAY WE GO... ; ; ;****************************************************************************** ; BYE$IMAGE EQU $ .PHASE BYEADR ; ; This section is fixed for BYE3 compatability. This allows XMODEM ; and bulletin board programs that use 'known' features of BYE3 and its ; derivatives to work with NBYE. Here is a handy reference table for the ; fixed area: (see also the item definitions which follow) ; ; Address Item ; ; BYE+00 Jump to BDOS ; BYE+03 Jump to start of BYE ; BYE+06 Jump to Warm Boot ; BYE+09 Jump to Routine to Print Logon Statistics ; BYE+10 Maximum User Area for Remote User (+1) ; BYE+11 Maximum Drive for Remote User (1 = A:) ; BYE+12 Not Used -- Reserved for Compatability ; BYE+13 Number of Nulls to Send after Line Feed ; BYE+14 Uppercase Only Flag ; BYE+15 Send Line Feeds Flag ; BYE+16 RBBS File Update Flag ; BYE+17 Hardcopy Log Flag ; BYE+18 Lost Carrier Flag ; BYE+19 Console Output Vector for local console ; BYE+21 'BYE' flag ; ; ; BYE: JMP 0 ;REVECTORED BDOS CALLS JMP START ;SKIP FIXED AREA TO ACTUAL START OF BYE ; MCBOOT: JMP MBOOT ;REVECTORED WARM BOOT JUMP JMP PRNLOG ;PRINT LOGON STATISTICS ; MXUSR: DB 0 ;MAXIMUM USER AREA FOR REMOTE USER + 1 ; MXDRV: DB 0 ;MAXIMUM DRIVE NUMBER FOR REMOTE USER (1 = A:) ;(EXCEPT FOR 'EXCDRV') ; DB 0 ;*** UNUSED BYTE -- RESERVED FOR COMPATABILITY ; NULLS: DB 0 ;NUMBER OF NULLS TO FOLLOW A LINE FEED ; ULCSW: DB 0 ;UPPERCASE ONLY FLAG ; 0 ==> UPPER/LOWER <> 0 ==> UPPER ONLY ; LFEEDS: DB 0 ;SEND LINE FEEDS FLAG ; 0 ==> SEND LINE FEEDS <> 0 ==> NO LINE FEEDS ; WRTLOC: DB 0 ;RBBS FILE UPDATE FLAG LOCATION ; HARDON: DB 0 ;HARDCOPY LOG FLAG ; 0 ==> NO HARDCOPY LOG <> 0 ==> HARDCOPY LOG ; LOSTFLG: DB 0 ;CARRIER LOST FLAG ; 0 ==> CARRIER OKAY <> 0 ==> CARRIER LOST ; COVECT: DW 0 ;ADDRESS OF LOCAL CONSOLE OUTPUT ROUTINE ;(USED BY XMODEM) ; BLDFLG: DB 'BYE' ;FLAG TO LET OTHERS KNOW BYE IS LOADED ; ; ; ;****************************************************************************** ; ; Hardware-specific routines are loaded here ; IFF S100MDM PAGE INCLUDE NBYEIO.INC ;INPUT/OUTPUT PORT CODE USED BY 'NBYEMDM.INC' ENDIF ;S100MDM ; PAGE INCLUDE NBYEMDM.INC ;THE MODEM SUPPORT ROUTINES ; IFT HAVCLK PAGE INCLUDE NBYECLK.INC ;CLOCK SUPPORT CODE ENDIF ;HAVCLK ; PAGE INCLUDE NBYEUSER.INC ;THE IMPLEMENTATION-SPECIFIC ROUTINES ; ; ; PAGE ;****************************************************************************** ; ; The BYE program itself (finally!). ; MBOOT: ;The BYE warm boot entry. ; ; LDA WBOOT ;CHECK FOR FORCED LOGOFF CPI JMP JNZ RESTART ;AND FORCE USER OFF IF NOT A JUMP INSTRUCTION XITING EQU $+1 MVI A,0 ;OR IF WE JUST RAN THE 'BYECOM' FILE ORA A JNZ EXITNG CALL ILPRNT ;ELSE PRINT WARM BOOT MESSAGE WBMSG DB 0FFH LHLD BIOSVECT+3+1 ;AND DO THE ACTUAL WARM BOOT THROUGH THE BIOS JMP USRWBOOT ;(OR ANY SPECIAL CODE USER MAY SUBSTITUTE) ; ; START: ;Entry point when invoked by 'BYE' at the CP/M command level. ; ; LXI SP,STACK ;SET LOCAL STACK XRA A STA LOSTFLG ;INIT CARRIER LOST FLAG IFT HAVCLK STA TFLAG ;INIT VALID TIME FLAG ENDIF ;HAVCLK LDA PATCHD ;BIOS VECTORS PATCHED? ORA A JNZ RESTART ;...YES, ASSUME INVOKED BY A REMOTE USER CALL LCLMSG ;...NO, MUST BE LOCAL -- SO SIGN ON BVMSG: DB CR,LF,'NBYE ' VERMSG DB ' @' DBHEX %(HIGH BYEADR) DBHEX %(LOW BYEADR) DB CR,LF DATMSG DB CR,LF,0FFH JMP HANGUP ;LET'S GO WAIT FOR A CALL ; ; CHECK: ;Carrier check point. Called from console output routine to ;ensure we don't keep going after lost carrier. If a file ;update is in progress (per WRTLOC) we will wait until it's ;done before killing everything. ; ; LDA LOSTFLG ;EXIT WITH CARRY IF ALREADY KNOWN LOST CARRIER DCR A CPI 0FFH RC LDA WRTLOC ;GET WRITE IN PROGRESS FLAG ORA A RNZ ;IF BUSY, DON'T LET MODEM HANG UP CALL CHKCAR ;ELSE SEE IF WE STILL HAVE CARRIER RNC ;AND EXIT IF SO CALL LCLMSG ;ELSE SHOW WHAT HAPPENED DB CR,LF DB ' [Carrier Lost]',CR,LF,0FFH ; CONXIT: LXI SP,STACK ;ENSURE VALID STACK CALL UNPATCH ;RESTORE ORIGINAL BIOS JUMP TABLE XRA A ;RESET LOST CARRIER FLAG STA LOSTFLG MVI A,CALL ;TRAP WARM BOOTS IN CASE THE EXIT .COM FILE STA BASE ;WARM BOOTS INSTEAD OF 'RET'-ING LXI H,MBOOT ;AND RESTORE THE WARM BOOT TRAP WBREVEC EQU $+1 SHLD $-$ ;(SET BY LOADER CODE) CALL LDFILE ;LOAD THE EXIT .COM FILE (IF ANY) OFFCOM DB 0FFH CNC BASE+100H ;RUN IT IF LOADED ; ; RESTART: ;Entry point when restarting due to user timeout, lost carrier, ;forced logoff due to changed jump vector at WBOOT, or caller ;logged off with 'BYE'. ; ; LXI SP,STACK ;ENSURE VALID STACK IFT HAVCLK XRA A ;INIT VALID TIME FLAG FOR NEXT USER STA TFLAG ENDIF ;HAVCLK LDA PATCHD ;SKIP SIGN-OFF MESSAGE IF NOT PATCHED ORA A JZ HANGUP STA XITING ;SET 'EXITING' FLAG IN CASE 'BYECOM' FILE WARM CALL LDFILE ;BOOTS AND LOAD ANY 'GOODBYE' .COM FILE BYECOM DB 0FFH CNC BASE+100H ;RUN IT IF LOADED EXITNG: CALL ILPRNT ;PRINT DESIRED SIGN-OFF MESSAGE BYEMSG DB 0FFH CALL DELAY ;WAIT FOR LAST CHARACTER TO GO OUT BEFORE CALL DELAY ;RE-INITIALIZING THE MODEM CALL UNPATCH ;UNDO THE BIOS PATCHES ; HANGUP: LXI SP,STACK ;SET LOCAL STACK BWBDU EQU $+1 MVI A,0 ;FORCE NEXT WARM BOOT TO DRIVE/USER IN EFFECT STA BASE+4 ;WHEN BYE WAS INVOKED BY LOCAL OPERATOR XRA A ;AND KILL ANY PENDING OPTION STA OPTION STA XITING ;RESET THE 'EXITING' FLAG IFT VERBOSE CALL LCLMSG DB CR,LF,'...Initializing the MODEM ',0FFH ENDIF ;VERBOSE CALL MINIT ;INIT THE MODEM MVI A,JMP ;KILL ANY TRAPS LEFT FROM .COM FILE STA WBOOT CALL USRINIT ;DO ANY SPECIAL INITIALIZATION IFT VERBOSE CALL LCLMSG DB CR,LF,'...Waiting for Ring ',0FFH ENDIF ;VERBOSE ; ; RINGWT: ;Wait for phone to ring. Answer if callback feature not ;desired, else check for single ring and if so wait 45 seconds ;for the callback. Keep checking local console for local ;operator request. ; ; CALL LCSTAT ;CHARACTER TYPED AT LOCAL CONSOLE? JZ NOLCHR ;...NO CALL LCIN ;...YES, GET IT CPI 'C'-040H ;CHECK FOR CONTROL-C CZ LCRQST ;AND SERVICE THE REQUEST IF SO NOLCHR: CALL MRING ;SEE IF THE PHONE'S RINGING JC CNECTD ;IT'S ALREADY CONNECTED!! JZ RINGWT ;IT'S NOT RINGING ; IFT VERBOSE CALL LCLMSG DB CR,LF,'...Ringing ',0FFH ENDIF ;VERBOSE IFT CALLBAK MVI B,75 ;SEE IF NO RING IN NEXT 7.5 SECONDS WAITNX: CALL DELAY CALL MRING JNZ WAITNR ;RINGING -- IT'S NOT FOR ME DCR B JNZ WAITNX JMP EXPECT ;NO MORE RINGS -- IT'S FOR ME! ; WAITNR: MVI B,100 ;WAIT FOR 10 SECONDS WITH NO RING IFT VERBOSE CALL LCLMSG DB CR,LF,'...Ringing Again ',0FFH ENDIF ;VERBOSE WNR: CALL DELAY CALL MRING JNZ WAITNR DCR B JNZ WNR LXI H,VOICE ;RECORD AS A VOICE CALL CALL INCLOG IFT VERBOSE CALL LCLMSG DB CR,LF,"...Call wasn't for me ",0FFH ENDIF ;VERBOSE JMP HANGUP ;AND GO WAIT FOR NEXT CALL ; EXPECT: LXI B,450 ;WAIT 45 SECONDS FOR SECOND CALL IFT VERBOSE CALL LCLMSG DB CR,LF,'...Expecting a Call ',0FFH ENDIF ;VERBOSE MYCALL: CALL MRING ;PHONE RINGING? JNZ ANSWER ;...YES, THAT'S MY CALL CALL DELAY ;...NO, KEEP WAITING DCX B MOV A,B ORA C JNZ MYCALL JMP HANGUP ;TIMED OUT -- GIVE UP AND WAIT FOR NEXT CALL ENDIF ;CALLBAK ; ; ANSWER: ;Answer routine. Answers the phone, waits for the caller to ;type a carriage return (if multiple baud rates supported), ;and sets the modem port to the appropriate baud rate. ; ; IFT VERBOSE CALL LCLMSG DB CR,LF,'...Answering the Phone ',0FFH ENDIF ;VERBOSE LXI H,ANSCAL ;BUMP ANSWERED CALLS COUNTER CALL INCLOG CALL MANSWER ;ANSWER THE PHONE JZ HANGUP ;FORGET IT IF WE DIDN'T GET A CARRIER IFT VERBOSE CALL LCLMSG DB CR,LF,'...Have Carrier ',0FFH ENDIF ;VERBOSE CNECTD: CALL LOWCHK ;KEEP REVECTORING BDOS JUMP IF BELOW BDOS LXI H,300 ;LIMIT TIME WE'LL TRY TO ESTABLISH BAUD RATE W4BAUD: CALL MBAUD ;GET THE BAUD RATE WE'RE CONNECTED AT AND STORE STA MSPEED ;THE INDICATOR FOR OTHER PROGRAMS (E.G. XMODEM) JNC WELCOME ;CONTINUE IF WE WERE SUCCESSFUL IFT VERBOSE CALL LCLMSG DB CR,LF,'...Unable to Get Baud Rate ',0FFH ENDIF ;VERBOSE CALL DELAY ;CHECK MAXIMUM BAUD RATE DETERMINATION TIME DCX H MOV A,H ORA L JZ HANGUP ;AND GIVE UP IF WE'VE EXCEEDED IT CALL MCARRIER ;ELSE TRY AGAIN IF WE STILL HAVE CARRIER JNZ W4BAUD JMP HANGUP ;...GIVE UP OTHERWISE ; ; WELCOME: ;Welcome routine -- We've got carrier and have set the ;appropriate baud rate, so let's say 'Hi' to the caller. ; ; CALL PATCH ;PATCH THE BIOS JUMP VECTORS IFT VERBOSE CALL LCLMSG DB CR,LF,'...Welcoming the Caller ',0FFH ENDIF ;VERBOSE MVI A,MAXDRV-'A'+1 ;RESET MAX DRIVE/USER VALUES FOR THE NEW CALLER STA MXDRV MVI A,MAXUSR+1 STA MXUSR XRA A ;BE SURE LINE FEEDS ARE TURNED ON STA LFEEDS STA ULCSW ;INIT TO UPPER AND LOWER CASE IFT HAVCLK STA TFLAG ;RESET VALID TIME FOR CURRENT USER FLAG ENDIF ;HAVCLK STA STATUS ;EVERYONE STARTS OUT NON-PRIVELEGED STA UPLOAD ;AND INIT THE UPLOAD/DOWNLOAD COUNTERS STA DNLOAD GETNUL: CALL ILPRNT ;GET NUMBER OF NULLS NEEDED HIMSG DB 0FFH LDA GETNUL+3 ;DID WE SEND A MESSAGE PROMPTING NULL COUNT? INR A JZ SETNUL ;...NO, USE ZERO CALL MINPUT ;...YES, GET USER'S RESPONSE PUSH PSW ;SAVE IT CALL MOUTPUT ;ECHO IT POP PSW ;SEE IF VALID SUI '0' CPI 9+1 JNC GETNUL ;AND RETRY IF NOT SETNUL: STA NULLS ;STORE DESIRED NULL COUNT CALL CRLF ;BUMP DOWN A LINE CALL LDFILE ;GET THE WELCOME FILE (IF ANY) WELFIL DB 0FFH JC CHKPWD ;NO WELCOME FILE, SO GO CHECK THE PASSWORD LXI H,BASE+0100H ;WELCOME FILE NOW IN MEMORY, SO SEND IT OUT WFTYPE: MOV A,M ;GET NEXT CHARACTER INX H ;KEEP ADDRESS POINTER CURRENT CPI 1AH ;END OF THE FILE? JZ CHKPWD ;...YES, TIME TO CHECK PASSWORD CALL MOUTPUT ;...NO, SEND TO CONSOLE CALL MSTAT ;SEE IF USER TYPED ANYTHING JZ WFTYPE ;AND CONTINUE IF NOT CALL MINPUTU ;ELSE PROCESS THE CHARACTER CPI 'S'-040H ;...PAUSE THE LISTING UNTIL NEXT CHARACTER CZ MINPUTU CPI 'C'-040H ;...ABORT THE WELCOME FILE JZ CHKPWD CPI 'K'-040H ;...ABORT THE WELCOME FILE JZ CHKPWD CPI 'K' ;...ABORT THE WELCOME FILE JZ CHKPWD JMP WFTYPE ; ; CHKPWD: ;We've said hello and set up the appropriate number of nulls. ;Now let's be sure the caller's allowed on this system. ; ; LDA USRPWD ;NEED A PASSWORD? CPI CR JZ PWDOK ;...NO, SKIP IT MVI B,3 ;...YES, SET NUMBER OF TRIES ALLOWED PWINP: CALL ILPRNT ;PROMPT THE PASSWORD DB CR,LF DB 'Enter Password: ' DB 0FFH CALL MISTAT ;CLEAR ANY PENDING INPUT CNZ MINP LXI H,USRPWD ;POINT TO PASSWORD MVI E,0 ;AND RESET ERRORS FLAG PWCHR: CALL MINPUTU ;GET NEXT CHARACTER FROM CALLER PUSH PSW ;SAVE CHARACTER CPI ' ' ;ECHO TO LOCAL CONSOLE WITH CONTROL CHARACTERS JNC PWDIS ;SHOWN AS ^ MVI C,'^' CALL LCOUT POP PSW PUSH PSW ADI 040H PWDIS: MOV C,A CALL LCOUT POP PSW CPI 'U'-040H ;ALLOW CTRL-U TO RESTART WITHOUT COUNTING JZ PWINP CMP M ;CHARACTER MATCH PASSWORD? JZ PWCHOK ;...YES MVI E,1 ;...NO, SET ERRORS FLAG PWCHOK: INX H ;BUMP POINTER TO NEXT CHARACTER IN PASSWORD CPI CR ;CALLER DONE ENTERING THE PASSWORD? JNZ PWCHR ;...NO MOV A,E ;...YES, SEE IF HE WAS SUCCESSFUL ORA A JZ PWDOK ;GOOD PASSWORD -- LOG HIM IN CALL ILPRNT ;ELSE TELL USER HE MISSED IT DB CR,LF DB 'Incorrect Password' DB CR,LF,0FFH DCR B ;SEE IF HE GETS TO TRY AGAIN JNZ PWINP ;AND START OVER IF SO CALL LCLMSG ;ELSE SHOW SYSOP WHAT HAPPENED DB CR,LF DB ' [Bad Password]',CR,LF,0FFH JMP CONXIT ;AND KILL THE CONNECT ; PWDOK: LXI H,LOGDON ;CALLER NOW LOGGED IN -- UPDATE THE COUNTER CALL INCLOG IFT HAVCLK CALL TIME ;GET CURRENT TIME LDA CHOUR ;AND SET TIME OF THIS LOGON STA LHOUR LDA CMIN STA LMIN JC TNOAVL ;TIME WASN'T AVAILABLE MVI A,0FFH ;TIME WAS AVAILABLE - SET VALID LOGON TIME FLAG STA TFLAG TNOAVL EQU $ ENDIF ;HAVCLK CALL USRLOGD ;DO ANY SPECIAL PROCESSING FOR THE NEW USER LDA ONEXEC+3 ;HAVE A .COM FILE TO EXECUTE? INR A JZ GO2CPM ;...NO, LET'S START CP/M FOR THE CALLER LDA OPTION ;...YES, FIRST CHECK FOR /A OPTION TO BYPASS IT CPI 'A' JZ GO2CPM ;SKIP .COM FILE IF /A OPTION ONEXEC: CALL LDFILE ;LOAD THE .COM FILE (OR EQUIV) TO RUN AT LOGIN ONCOM DB 0FFH JC GO2CPM ;NO FILE, OR COULDN'T LOAD SUCCESSFULLY CALL CRLF ;FILE LOADED -- SEND CR/LF AND EXECUTE THE FILE CALL 100H GO2CPM: JMP WBOOT ;NOW WARM BOOT CP/M FOR REMOTE CALLER'S USE ; ; ; *** End of the Main BYE Routine *** ; ;****************************************************************************** ; ; Subroutines used by BYE are in the following file: ; PAGE INCLUDE NBYESUBR.INC ; ; PAGE ;****************************************************************************** ; ; Data Storage Area -- Initialized and Loaded ; PATCHD: DB 0 ;BIOS VECTORS PATCHED FLAG ; 0 ==> NO <> 0 ==> YES ; BYEJT: JMP MCBOOT ;COLD BOOT ** BYE'S JUMP TABLE ** JMP MBOOT ;WARM BOOT JMP MSTAT ;CONSOLE STATUS JMP MINPUT ;CONSOLE INPUT JMP MOUTPUTC ;CONSOLE OUTPUT ; BIOSVECT: DS 15 ;STORAGE FOR ORIGINAL BIOS VECTORS ; USRPWD: PASSWD ;LOGON PASSWORD (IF ANY) DB CR ; CPMVER: DB 0 ;CP/M VERSION NUMBER RETURNED FROM FUNCTION 12 ; BNDFLG: DB 'BYE' ;FLAGS END OF THE LOADED PART OF BYE ; BYESIZE EQU $-BYE ; ;****************************************************************************** ; ; Data Storage Area -- UnInitialized and Not Loaded ; USRFLG EQU $ ;FLAG THAT COUNTERS HAVE BEEN INITIALIZED ; AA,55 ==> YES VOICE EQU USRFLG+2 ;NBR OF VOICE CALLERS ANSCAL EQU VOICE+2 ;NBR OF TIMES WE ANSWERED THE PHONE LOGDON EQU ANSCAL+2 ;NBR OF TIMES SOMEONE LOGGED ON THE SYSTEM ; TFLAG EQU LOGDON+2 ;VALID LOGON TIME SET FLAG ; 0 ==> NOT VALID TIME ; OPTION EQU TFLAG+1 ;CURRENT OPTION -- SAVED WHEN BYE INVOKED ; STACK EQU OPTION+1+70 ;LOCAL STACK AREA ZZZBYE EQU STACK ;LABEL TO HELP COMPUTE BYE LOAD ADDRESS ; .DEPHASE ; ; END BYELDR