TYPR BYE.ASM TYPR? A>TYPE BYE.ASM ;V6.3 (Revised 9/23/80) ; ;REMOTE CONSOLE PROGRAM FOR CP/M ;BASED ON AN ORIGINAL PROGRAM WRITTEN ;BY DAVE JAFFE, JANUARY 1979 ; ;Rewritten for PMMI modem ;by Ward Christensen, February 1979 ; ;I'd also like to give credit to Bill Precht ; for the "label + offset" idea allowing ; this program to relocate itself ; without using DDT to initially set it up ; ;05/06/79 Added routine to allow "callback" operation so modem ; does not answer normal voice calls. By Robbin Hough ; and Keith Petersen, W8SDZ. ; ;09/24/79 Added routines to allow automatic multiple baud ; rate selection, exit to CP/M from local console, ; echo nr. of nulls selected. By Keith Petersen, ; with thanks to Bob Mathias for suggestions. ; ;01/24/80 Added routines to preserve registers when calling ; the user's CBIOS. Added conditional assembly for ; callback feature. Increased stack space to 60. ; By Keith Petersen. ; ;06/11/80 Added routines to allow conditional assembly for ; Morrow's Discus 2D board (all Rev's) with memory ; mapped I/O. ; By Dave Hardy ; ;06/11/80 Added 710 Baud rate selection option at sign-on. ; By Dave Hardy and Bruce Levison. ; ;06/29/80 Added USRLOG routines to keep track of number ; of callers, and display on front panel ; of IMSAI (i.e. output number to port FFH). ; By Dave Hardy ; ;07/10/80 Added code to allow auto-answer after first ; or second ring for more reliable auto-answer ; when using "ringback" option. ; By Dave Hardy ; ;07/11/80 Added conditional assembly for password and ; user log routines, and routines to print USRLOG ; information on console after program exit. ; By Dave Hardy ; ;07/16/80 Added "/R" command option to allow USRLOG ; counters to be reset upon entry. ; By Dave Hardy ; Š;09/15/80 Added conditional assembly for automatic timed ; log-out, drive and user number masking, lower ; case query at login, and cp/m 2.x. Thanks to ; Bruce Ratoff for the routines (lifted from his ; 'DCHBYE54.ASM') used to implement these functions ; NOTE: in order to implement the timed log-out, it ; was necessary to do timing in software loops. ; Therefore, a new equate, FASTCLK, has been added ; to allow for 4mhz clock speeds. Also added Bruce ; Ratoff's overrun/framing error checking when read- ; ing the modem port. ; By Ron Fowler ; ;09/16/80 Added conditional assembly to allow automatic ; loading of a com file instead of cp/m boot. Also ; added decimal usrlog counters as conditional as- ; sembly. ; By Ron Fowler ; ;9/19/80 Modified to prevent re-load of the com file when ; a voice call comes in. Reset the DMA address back ; to 80h after the com file is loaded. ; By Ron Fowler ; ;9/19/80 Added conditional assembly to give the operator a ; 'twit' logout key. Added conditionals for 'message ; from operator' and 'system down in 5 minutes' keys. ; Added front-panel selection of hard-copy log, remote ; 'black-out', and password option. Also, if cpm/2 is ; used, a message is printed when an unsupported user ; area is entered. ; By Ron Fowler and Dave Hardy ; ;9/19/80 Added new '/' option C, which has the same affect as ; /A, except that /C loads the com file after answering ; the phone, while /A boots cp/m. ; By Ron Fowler ; ;9/19/80 Modified COM file load routine to prevent BDOS ; overwrite if the COM file won't fit in the TPA ; By Ron Fowler ; ;9/20/80 Modified status checking during ring-wait routine to ; use cp/m BDOS call, as suggested by Keith Petersen. ; This should make the program more portable. Also ; added Bruce Ratoff's update to DCHBYE program (5.5), ; that allows the use of bye from non-zero user areas. ; By Ron Fowler ; ;9/23/80 Fixed bugs that prevented "bye /a" and "bye /c" from ; working properly. Also repaired several errors in ; conditional assembly nesting. -->Ron Fowler ; ;------------------------------------------------ ; Š;CHANGE THE FOLLOWING EQUATE TO AN AREA IN YOUR ;HI MEMORY WHERE THIS PROGRAM MAY PATCH ITSELF IN. ;APPROX MEMORY REQUIREMENTS: UP TO xxxx BYTES. ; DEST EQU 0F800H ;RUNNING LOCATION OF CODE ; ;CHANGE THE FOLLOWING TO YOUR PRINTER DATA ;ADDRESS IF YOU HAVE INVERTED MEMORY-MAPPED I/O, ;OR TO PRINTER DATA PORT IF YOU HAVE PORT I/O. ; PTRPORT EQU 0FFH ;PUT YOUR PRINTER DATA PORT HERE ;IT CAN BE MEMORY-MAPPED ; ;CHANGE THE FOLLOWING IF YOUR PMMI IS NOT AT 0C0H ;(THE OTHER PORT EQUATES ARE BASED ON THIS VALUE) ; TPORT EQU 0C0H ;UART CONTROL/STATUS PORT ; ; ;YOU WILL LIKELY ALSO WANT TO CHANGE THE PASSWORD, ;LOCATED BELOW AT LABEL "PASSWD", AND THE MESSAGES ;PRINTED AT LABEL "WELCOME" AND JUST ABOVE LABEL ;"HANGUP" ; ;------------------------------------------------ ; ;THIS PROGRAM RUNS UP IN HIGH RAM. IT GETS THERE ;BY BEING MOVED THERE WHEN 'BYE' IS TYPED. ; ;THE PROGRAM IN HI RAM DOES THE FOLLOWING: ; ; 1. HANGS UP THE PHONE ; 2. AWAITS RING DETECT, ALLOWS EXIT ; TO CP/M IF LOCAL KBD TYPES CTL-C ; 3. OUTPUTS CARRIER (SEE CALLBACK ROUTINES) ; 4. AWAITS INCOMING CARRIER ; GOING TO STEP 1 IF NONE ; FOUND IN 15 SECONDS ; 5. ASKS NUMBER OF NULLS (0-9) ; 6. TYPES THE FILE "WELCOME" FROM ; DISK, ALLOWING CTL-C TO SKIP IT ; 7. ASKS FOR A PASSWORD, ALLOWING ; 5 TRIES TO GET IT RIGHT. ; 8. WHEN PASSWORD ENTERED, IF USED, DROPS ; INTO CP/M. ; 9. CALLER CAN LEAVE BY HANGING UP, ; (ANY TIME CARRIER IS LOST, IT ; WAITS 15 SECONDS, THEN GOES ; BACK TO STEP 1), OR THE CALLER ; MAY TYPE THE PROGRAM NAME (BYE) ; ; SYSTEM EQUATES: FALSE EQU 0 TRUE EQU NOT FALSE BDOS EQU 5 ŠCR EQU 0DH LF EQU 0AH MINUTES EQU 20*60 ;CONSTANT FOR 1 MIN TIM DLY ; ;**************************************************** ;* OPTION CONFIGURATION SECTION * ;**************************************************** ; PRINTER EQU FALSE ;WANT TO RETAIN LIST DEVICE? DUAL$IO EQU TRUE ;WANT CONSOLE & MODEM? CALLBAK EQU TRUE ;WANT CALLBACK FEATURE? PWRQD EQU TRUE ;WANT TO USE PASSWORD? USRLOG EQU TRUE ;WANT TO COUNT NUMBER OF USERS? MAP$IO EQU FALSE ;WANT MEMORY-MAPPED I/O? IMSAI EQU TRUE ;ADDS VARIOUS OPIONS W/SENSE SW'S CPM2 EQU TRUE ;USING CP/M 2.X? MAX$USER EQU 10 ;SET TO 0 FOR CP/M 1.X MAX$DRIVE EQU 2 ;HIGHEST DRIVE SUPPORTED FASTCLK EQU FALSE ;SET TRUE FOR 4 MHZ CLOCK TIMEOUT EQU TRUE ;WANT AUTO LOG-OFF FOR SLEEPY CALLERS? TOVALUE EQU 7 ;THIS IS 7 MINUTES TO AUTO LOGOUT COMFILE EQU TRUE ;WANT TO AUTOBOOT A COM FILE? COMUSR EQU 0 ;USER # THAT COMFILE IS KEPT IN DECIMAL EQU TRUE ;WANT DECIMAL VALUES FOR LOGS? CK$LWC EQU TRUE ;WANT TO TRAP LOWER CASE? ; ; SPECIAL KEYS FOR SPECIAL FUNCTIONS ; FKEYS EQU TRUE ;WANT SPECIAL FUNCTION KEYS? ; ;ASSIGN FUNCTION KEYS TO THE FOLLOWING CONTROL CODES (IF USED): ; TWITKEY EQU 'N'-40H ;KEYCODE TO LOG-OUT A CREEP MSGKEY EQU 'Q'-40H ;KEYCODE TO PRINT 'MESG FROM OPER:' SYSDKEY EQU 'O'-40H ;KEYCODE TO PRINT SYS DOWN MSG ; ; FRONT-PANEL SELECTION OPTIONS ; SENSE EQU 0FFH ;SENSE SWITCH PORT NUMBER ; BLACKOUT EQU TRUE ;SWITCH TO TURN OFF REMOTE SEND HARDLOG EQU TRUE ;SWITCH TO ECHO REMOTE KBD TO PRINTER SELPASS EQU TRUE ;SWITCH TO REQUIRE A PASSWORD ; ; ASSIGNMENT OF FRONT-PANEL OPTIONS TO SWITCHES: ; LOGSW EQU 01H ;TURN ON FOR HARDCOPY PWDSW EQU 02H ;TURN ON FOR 'PASSWORD' MODE BLACKSW EQU 04H ;TURN ON TO BLACK OUT REMOTE END ENABLF EQU 08H ;TURN ON TO ENABLE SPL FUNC KEYS ; ;**************************************************** ;* END OF OPTION CONFIGURATION SECTION * ;**************************************************** ; Š; ; PMMI MODEM PORT ASSIGNMENTS: ; ;PMMI MODEM PORT EQUATES (TPORT PREVIOUSLY DONE) ; DPORT EQU TPORT+1 ;DATA PORT RPORT EQU TPORT+2 ;RATE GEN/MODEM STATUS CPORT EQU TPORT+3 ;MODEM CONTROL ; ;MODEM CONTROL COMMAND WORDS ; P3CLEAR EQU 3FH ;IDLE MODE ; ;SET FOLLOWING TO 5FH FOR >300 BAUD ; P3TODTR EQU 5FH ;Turn On DTR ; ;SWITCH HOOK AND MODEM COMMANDS, ; OUTPUT TO TPORT (PORT 0) ; P0BYE EQU 0 ;ON HOOK, OR DIALING BREAK P0ORIG EQU 1 ;OFF HOOK, ORIG. P0ANSW EQU 2 ;ANSWER PHONE P08BIT EQU 0CH ;8 DATA BITS P0NOPY EQU 10H ;NO PARITY P0EPS EQU 20H ;EVEN PARITY SELECT P0TSB EQU 40H ;2 STOP BITS P0EI EQU 80H ;ENABLE INTERRUPTS P0NORM EQU P08BIT+P0NOPY ;I USE 8 BITS, NO PARITY P0110 EQU P08BIT+P0NOPY+P0TSB ;SAME W/2 STOP BITS ; ;MODEM STATUS, INPUT ON RPORT (PORT 3) ; P2DTD EQU 1 ;DIAL TONE DETECT P2RDET EQU 2 ;RING DETECT P2CTS EQU 4 ;CTS (CARRIER DETECT) P2RXBRK EQU 8 ;RECEIVE BREAK P2CONN EQU 10H ;CONNECTED? (0=YES, ; 1=MODEM CHIP HUNG UP) P2TMPUL EQU 80H ;TIMER PULSES (40% UP CYCLE) ; ;TIMER RATE SELECTION ; TRATE EQU 250 ;VALUE FOR .1 SEC ; ;PMMI MODEM STATUS MASKS ; P0TBMT EQU 1 ;XMIT BUFF EMPTY P0DAV EQU 2 ;DATA AVAILABLE P0TEOC EQU 4 ;TEST END OF CHAR P0RPE EQU 8 ;REC'D PARITY ERR P0ORUN EQU 10H ;OVERRUN P0FERR EQU 20H ;FRAMING ERROR ; ;BAUD RATE DIVISORS Š; B110 EQU 142 ;110 BAUD B300 EQU 52 ;300 BAUD B450 EQU 35 ;450 BAUD B600 EQU 26 ;600 BAUD B710 EQU 22 ;710 BAUD ; ORG 100H ; ;MOVE THE MODEM INTERFACE PROGRAM UP TO HI RAM ;AND JUMP TO IT. ; MOVEUP LXI B,PEND-START+1 ;NUMBER OF BYTES TO MOVE LXI H,DEST+PEND-START+1 ;END OF MOVED CODE LXI D,SOURCE+PEND-START ;END OF SOURCE CODE MVLP LDAX D ;GET BYTE DCX H ;BUMP POINTERS MOV M,A ;NEW HOME DCX D DCX B ;BUMP BYTE COUNT MOV A,B ;CHECK IF ZERO ORA C JNZ MVLP ;IF NOT, DO SOME MORE PUSH H ;SAVE FOR LATER JUMP MVI A,0C3H ;CLEAR ANY TRAPS SO SYSOP.. STA 0 ;CAN USER "BYE /A" XRA A ;NEXT WARMBOOT TO USR0/DRV A STA 4 MVI C,14 ;MAKE DRIVE A DEFAULT MOV E,A ;LOG-IN DRIVE CP/M FUNCTION CALL BDOS ; IF CPM2 ;SET USER 0 MVI C,32 ;GET/SET USR CP/M FUNCTION MVI E,COMUSR CALL BDOS ENDIF ; RET ;TO ADRS PUSHED ABOVE ; ; SOURCE EQU $ ;BOUNDARY MEMORY MARKER ; OFFSET EQU DEST-SOURCE ;RELOC AMOUNT ;-----------------------------------------------; ; THE FOLLOWING CODE GETS MOVED ; ; TO HI RAM LOCATED AT "DEST", ; ; WHERE IT IS EXECUTED. ; ;-----------------------------------------------; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XX C A U T I O N : IF MODIFYING ANYTHING XX ;XX IN THIS PROGRAM FROM HERE ON: XX ;XX A-L-L LABELS MUST BE OF THE FORM: XX ;XX label EQU $+OFFSET XX ;XX IN ORDER THAT THE RELOCATION TO HI RAM XX Š;XX WORK SUCCESSFULLY. FORGETTING TO XX ;XX SPECIFY '$+OFFSET' WILL CAUSE THE PRO- XX ;XX GRAM TO JMP INTO WHATEVER IS CURRENTLY XX ;XX IN LOW MEMORY, WITH UNPREDICTABLE XX ;XX RESULTS. BE CAREFUL.... XX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; ; IF CARRIER LOST, HANG UP, AWAIT RING. ; OTHERWISE, SAY GOODBYE, AND HANG UP ; START EQU $+OFFSET ; XRA A ;GET 0 STA LOSTFLG ;SHOW NO CARR. LOST ; ; DON'T ALLOW A REMOTE USER TO DO 'BYE /A' ; CALL CARCK JNC GOODBY ; ;CHECK FOR /A OPTION ON COMMAND - REQUEST TO ;GO IMMEDIATELY INTO ANSWER MODE ; LXI H,FCB+1 ;TO OPTION MOV A,M CPI '/' ;OPTION? JNZ NOSLASH ;GOT AN OPTION - VALIDATE IT INX H ;TO OPTION BYTE MOV A,M ;GET IT STA OPTION ;MIGHT NEED LATER CPI 'A' ;ANSWER? JZ ANSWER ; IF COMFILE CPI 'C' JZ ANSWER ENDIF ; IF USRLOG ;CHECK FOR RESET OF COUNTERS CPI 'R' CZ RESET ENDIF ;NO OPTION, OR INVALID ONE NOSLASH EQU $+OFFSET CALL CARCK ;SIGNED OFF W/THIS PROG? JC HANGUP ;NOBODY THERE ; GOODBY EQU $+OFFSET CALL ILPRT ;PRINT THIS MSG: DB CR,LF,'GOOD BYE, CALL AGAIN' DB CR,LF,CR,LF,0 CALL UNPATCH ;UNDO BIOS PATCHES ; ; NOBODY THERE, OR WE ARE DONE, SO HANG UP Š; HANGUP EQU $+OFFSET LXI SP,STACK ;SET UP LOCAL STACK XRA A ;FORCE NEXT WARMBOOT TO USER 0 STA 4 ;AND DRIVE A MVI C,14 ;MAKE DRIVE A DEFAULT MOV E,A CALL BDOS MVI A,' ' ;DON'T ALLOW OPTIONS.. STA OPTION ;..AFTER 1 "BYE / " ; IF CPM2 AND COMFILE MVI C,32 ;GET/SET USER CODE MVI E,COMUSR ;LOCATION OF OUR COMFILE CALL BDOS ENDIF ; IF COMFILE CALL LODCOM ;LOAD THE COM FILE ENDIF ; ; HANGUP2 EQU $+OFFSET ; ;CLEAR DTR CAUSING PHONE TO HANG UP MVI A,P3CLEAR ;CLEAR.. OUT CPORT ;..DTR MVI A,0C3H ;CLEAR ANY TRAPS.. STA 0 ;..LEFT FROM COM FILE ; ; AWAIT RINGING ; RINGWT EQU $+OFFSET ;CHECK LOCAL KEYBOARD FOR CTL-C EXIT REQUEST. ;NOTE: MUST DO DIRECT INPUT BECAUSE CBIOS PATCHES ;ARE NOT DONE UNTIL CALL COMES IN. ; CALL UCSTS ; ANI 7FH ;STRIP PARITY BIT CPI 'C'-40H ;CONTROL C? ; IF NOT USRLOG JZ 0 ;YES, --EXIT-- TO CP/M ENDIF ; IF USRLOG ;PRINT OUT USER INFO JZ PRNLOG ENDIF ; RINGW2 EQU $+OFFSET IN RPORT ;GET THE STATUS ANI P2RDET ;RINGING? JNZ RINGWT ;NO, WAIT ; Š;THE PHONE IS RINGING, NOW WAIT UNTIL RING IS FINISHED ENDRING EQU $+OFFSET CALL DELAY ;.1 SEC DELAY FOR DEBOUNCE IN RPORT ;GET STATUS ANI P2RDET ;STILL RINGING? JZ ENDRING ;WAIT UNTIL RING FINISHED ; IF CALLBAK ;NEXT ROUTINES IMPLEMENT CALLBACK ; ; THIS ROUTINE MINIMIZES THE COMPUTER'S INTERFERENCE ; WITH NORMAL HOUSEHOLD PHONE USE BY HAVING COMPUTER ; FOLK DIAL, LET THE PHONE RING ONCE, HANG UP AND ; THEN DIAL AGAIN. WHEN THE PHONE RINGS ONLY ONCE IT ; ALERTS THE COMPUTER WHICH THEN WAITS FOR AND ANSWERS ; ANY RING WHICH OCCURS WITHIN THE NEXT 40 SECONDS. ; MVI L,45 ;DELAY 4.5 SECONDS FOR NEXT RING WAITNX EQU $+OFFSET CALL DELAY ;WAIT .1 SECONDS DCR L ;MORE TO GO? JNZ WAITNX ;YES?...LOOP IN RPORT ;GET THE STATUS ANI P2RDET ;RINGING AGAIN? JNZ EXPECT ;NO?...ITS FOR ME! ENDRNG2 EQU $+OFFSET ;IF SECOND RING THEN CHECK IN RPORT ;FOR THIRD RING, IN CASE CALLER'S ANI P2RDET ;PHONE EXCHANGE IS NOT SYNC'ED JZ ENDRNG2 ;WITH COMPUTER'S. MVI L,45 WAITNX2 EQU $+OFFSET CALL DELAY DCR L JNZ WAITNX2 IN RPORT ANI P2RDET JNZ EXPECT ;ANSWER IF NO THIRD RING ;CALL NOT FOR COMPUTER - WAIT UNTIL RINGING DONE, THEN RESET WAITNR EQU $+OFFSET MVI L,100 ;WAIT FOR 10 SECS NO RINGING WAITNRL EQU $+OFFSET CALL DELAY ;DELAY .1 SECONDS IN RPORT ;GET THE STATUS ANI P2RDET ;STILL RINGING? JZ WAITNR ;YES, WAIT 10 MORE SECONDS DCR L ;NO RING, MAYBE WE'RE DONE JNZ WAITNRL ;NO, LOOP SOME MORE ENDIF ; IF CALLBAK AND USRLOG LDA NONUSR ;RECORD AS VOICE CALL INR A ENDIF ; IF CALLBAK AND USRLOG AND DECIMAL Š DAA ENDIF ; IF CALLBAK AND USRLOG STA NONUSR ENDIF ; IF CALLBAK ;CONTINUE WITH CALLBAK ROUTINES JMP HANGUP2 ; EXPECT EQU $+OFFSET LXI H,400 ;40 SECONDS TO REDIAL RELOOK EQU $+OFFSET IN RPORT ANI P2RDET ;RINGING AGAIN? JZ ANSWER CALL DELAY DCX H MOV A,H ORA L JNZ RELOOK JMP HANGUP2 ; ENDIF ;END OF CALLBACK ROUTINES ; ;SETUP MODEM ANSWER EQU $+OFFSET IF USRLOG ;COUNT # OF LOGON ATTEMPTS LDA OLDUSR ;GET # OF ATTEPMTS INR A ;ADD THIS CALL ENDIF ; IF USRLOG AND DECIMAL DAA ENDIF ; IF USRLOG STA OLDUSR ;SAVE # OF ATTEMPTS ENDIF ; MVI A,P3TODTR ;TURN ON OUT CPORT ;..DTR CALL DELAY ;GIVE TIME TO TURN ON MVI A,P0110+P0ANSW OUT TPORT ;ANSWER PHONE CALL DELAY ;GIVE TIME FOR ANSWER CALL UCSTS IN DPORT ;CLEAR MODEM PORT IN DPORT ;MAKE SURE ITS CLEAR MVI A,B110 ;SELECT 110 BAUD OUT RPORT ;SET BAUD RATE ;OUTPUT VALUE ALLOWING MODEM TO HANG UP ON ;LOSS OF CARRIER MVI A,P0110 ;NORMAL MODE FOR 110 BAUD OUT TPORT Š CALL CARCK ;LOOK FOR CARRIER JC HANGUP2 ;AWAIT ANOTHER CALLER ;NOW TEST INPUT FOR BAUD RATE CALL PATCH ;PATCH JMP TABLE CALL TSTBAUD ;SEE IF BAUD = 110 JZ WELCOME ;YES, EXIT MVI A,P0NORM ;SET FOR 1 STOP BIT, ETC. OUT TPORT MVI A,B300 ;SET DIVISOR OUT RPORT ;.. TO 300 RATE CALL TSTBAUD ;SEE IF BAUD = 300 JZ WELCOME ;YES, EXIT MVI A,B450 ;SET DIVISOR OUT RPORT ;.. TO 450 RATE MVI A,5FH OUT CPORT ;SET FILTER VALUE FOR > 300 CALL TSTBAUD ;SEE IF BAUD = 450 JZ WELCOME ;YES, EXIT MVI A,B600 ;SET DIVISOR OUT RPORT ;.. TO 600 RATE CALL TSTBAUD ;SEE IF BAUD = 600 JZ WELCOME ;YES, EXIT MVI A,B710 ;SET DIVISOR OUT RPORT ;.. TO 781 RATE CALL TSTBAUD ;SEE IF BAUD = 710 JZ WELCOME ;YES, EXIT CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL JMP ANSWER ;TEST MORE - INVALID BAUD RATE ; ; Get the console status when unpatched ; UCSTS EQU $+OFFSET IF CPM2 MVI C,DIRECTIO ;DIRECT I/O CALL WILL RETURN MVI E,0FFH ;ASK FOR INPUT CALL BDOS ;A=0 IF NO CHAR WAITING RET ENDIF ; IF NOT CPM2 MVI C,CSTS ;IN CPM 1.X, WE HAVE TO GET.. CALL BDOS ;..THE STATUS FIRST ORA A RZ MVI C,CI ;AND THEN THE CHARACTER CALL BDOS RET ENDIF ; ;FOLLOWING ARE THE USRLOG ROUTINES ; IF USRLOG ;INCLUDE RESET FUNCTIONS RESET EQU $+OFFSET ;RESET ALL LOGON COUNTERS XRA A Š ENDIF ; IF USRLOG AND PWRQD STA OLDUSR ;RESET ATTEMPT COUNTER ENDIF ; IF USRLOG STA NEWUSR ;RESET LOGON COUNTER ENDIF ; IF USRLOG AND CALLBAK STA NONUSR ;RESET VOICE COUNTER ENDIF ; IF USRLOG AND IMSAI CMA OUT SENSE ;RESET IMSAI PANEL DISPLAY ENDIF ; IF USRLOG RET ENDIF ; PRNLOG EQU $+OFFSET ; IF USRLOG AND PWRQD ;PRINT # OF LOGON ATTEMPTS MVI C,09H LXI D,ATMSG CALL BDOS LDA OLDUSR CALL HXOUT ENDIF ; IF USRLOG ;PRINT # OF LOGONS MVI C,09H LXI D,SUMSG CALL BDOS LDA NEWUSR CALL HXOUT ENDIF ; IF USRLOG AND CALLBAK ;# OF VOICE CALLS MVI C,09H LXI D,VCMSG CALL BDOS LDA NONUSR CALL HXOUT ENDIF ; IF USRLOG JMP 0 ;WARM-BOOT BACK TO CP/M ENDIF ; IF USRLOG AND PWRQD ATMSG EQU $+OFFSET Š DB LF,CR,'NUMBER OF LOGON ATTEMPTS: $' ENDIF ; IF USRLOG SUMSG EQU $+OFFSET DB LF,CR,'NUMBER OF LOGONS: $' ENDIF ; IF USRLOG AND CALLBAK VCMSG EQU $+OFFSET DB LF,CR,'NUMBER OF VOICE CALLS: $' ENDIF ; IF USRLOG HXOUT EQU $+OFFSET MOV B,A ;SAVE NUMBER RAR ;ROTATE RIGHT 4 BITS RAR ;TO MAKE AN ASCII DIGIT RAR RAR CALL ONEOUT ;OUTPUT MSH TO CONSOLE MOV A,B ;GET NUMBER BACK ONEOUT EQU $+OFFSET ANI 0FH ;GET LSH FOR OUTPUT CPI 0AH ;CHECK IF ALPHA JC NOTAL2 ADI 07H NOTAL2 EQU $+OFFSET ADI 30H PUSH B MVI C,02H MOV E,A ;OUTPUT THE NUMBER CALL BDOS POP B RET ENDIF ; ;WELCOME TO THE SYSTEM ; WELCOME EQU $+OFFSET ; GETNULL EQU $+OFFSET CALL ILPRT ;PRINT THIS MSG: DB CR,LF DB 'HOW MANY NULLS DO YOU NEED? ',0 CALL MINPUT ;GET VALUE MOV C,A CALL MOUTPUT ;ECHO CHAR MOV A,C CPI '0' JC GETNULL ;BAD, RETRY CPI '9'+1 JNC GETNULL ;BAD SUI '0' ;MAKE BINARY STA NULLS ;SAVE COUNT Š; IF CK$LWC GETULC EQU $+OFFSET CALL ILPRT ;NOWPRINT THIS MSG: DB CR,LF DB 'CAN YOUR TERMINAL DISPLAY LOWER CASE? ',0 MVI A,20H ;FORCE CASE CONVERSION FOR NOW STA ULCSW CALL MINPUT ;GET Y OR NO MOV C,A CALL MOUTPUT ;ECHO MOV A,C CPI 'N' JZ DONEOPT ;WE'RE ALREADY SET UP FOR NO LWR CASE CPI 'Y' JNZ GETULC ;WASN'T Y OR N...ASK HIM AGAIN XRA A STA ULCSW ;SET FLAG FOR NO CONVERSION DONEOPT EQU $+OFFSET ENDIF ; CALL ILPRT DB CR,LF,0 ;PRINT THE WELCOME FILE LXI H,WELFILN ;SOURCE LXI D,FCB ;DESTINATION MVI B,13 ;LENGTH CALL MOVE ;MOVE THE NAME ;SET DMA ADDR TO 80H LXI D,80H MVI C,STDMA CALL BDOS ;OPEN THE WELCOME FILE LXI D,FCB MVI C,OPEN CALL BDOS ;DID IT EXIST? INR A ;A=> 0 MEANS "NO" JZ PASSINT ;NO WELCOME FILE ;GOT A FILE, TYPE IT XRA A ;GET 0 STA FCBRNO ;ZERO RECORD # LXI H,100H ;GET INITIAL BUFF POINTER ;TYPE THE WELCOME FILE WELTYLP EQU $+OFFSET CALL RDBYTE ;GET A BYTE CPI 1AH ;EOF? JZ PASSINT ;YES, DONE MOV C,A ;SETUP FOR TYPE CALL MOUTPUT ;TYPE THE CHAR CALL MSTAT ;CHECK FOR.. ORA A ;CHAR TYPED? JZ WELTYLP ;..NO, LOOP CALL MINPUT ;..YES, GET CHAR CPI 'C'-40H ;CTL-C? Š JNZ WELTYLP ;..NO, LOOP UNTIL EOF ; ;GET THE PASSWORD ; PASSINT EQU $+OFFSET ; ; IF PWRQD AND IMSAI AND SELPASS IN SENSE ;TURN THE SWITCH UP.. ANI PWDSW ;..TO REQUIRE THE PASSWORD JZ NOPASS ENDIF ; IF PWRQD MVI D,5 ;5 TRIES AT PASSWORD PASSINP EQU $+OFFSET CALL ILPRT DB CR,LF,'ENTER PASSWORD: ',0 LXI H,PASSWD ;POINT TO PASSWORD MVI E,0 ;NO MISSED LETTERS IN DPORT ;CLEAR OUT GARBAGE PWMLP EQU $+OFFSET CALL MINPUT ;GET A CHAR CPI 'U'-40H ;CTL-U? JZ PASSINP ;YES, RE-GET IT CPI 60H ;LOWER CASE? JC NOTLC ;NO, ANI 5FH ;MAKE UPPER CASE ALPHA NOTLC EQU $+OFFSET CMP M ;MATCH PASSWORD? JZ PWMAT ;..YES MVI E,1 ;..NO, SHOW MISS CPI CR ;C/R? JNZ PWMLP ;..NO, WAIT FOR C/R ;PASSWORD DIDN'T MATCH PWNMAT EQU $+OFFSET CALL ILPRT DB '++INCORRECT++',CR,LF,0 DCR D ;MORE TRIES? JNZ PASSINP ;YES JMP BADPASS ;NO, GO HANG UP ;CHARACTER MATCHED IN PASSWORD PWMAT EQU $+OFFSET INX H ;TO NEXT CHAR CPI CR ;END? JNZ PWMLP ;..NO, LOOP ;END OF PASSWORD. ANY MISSED CHARS? MOV A,E ;GET FLAG ORA A JNZ PWNMAT ;NOT RIGHT ;PASSWORD CORRECT ENDIF ; NOPASS EQU $+OFFSET ; Š IF USRLOG ;COUNT # OF SUCCESSFUL LOGONS LDA NEWUSR ;GET LAST VALUE INR A ;INCREMENT IT ENDIF ; IF USRLOG AND DECIMAL DAA ENDIF ;DECIMAL ; IF USRLOG STA NEWUSR ;SAVE NEW VALUE ENDIF ;USRLOG ; IF IMSAI AND USRLOG ;DISPLAY ON IMSAI CMA OUT SENSE ;DISPLAY ON IMSAI FRONT PANEL ENDIF ; CALL ILPRT DB CR,LF,'',0 ;PUT BOOT-UP MSG HERE ; IF COMFILE LDA OPTION CPI 'A' ;SYSOP CAN BYPASS COM FILE BY.. JZ 0 ;..TYPING "BYE /A" CPI 'C' ;OPER CAN ALSO GO TO COM.. JNZ 100H ;..FILE LOAD WITH "BYE /C" CALL ILPRT ;PRINT THIS MESSAGE:' DB 'Loading system...',CR,LF,0 CALL LODCOM JMP 100H ;EVERYONE ELSE GETS COM FILE ENDIF ; IF NOT COMFILE JMP 0 ENDIF ; ;TSTBAUD ATTEMPTS TO READ A LF OR CR, RETURNS WITH ;ZERO FLAG IF THE CHARACTER READ IS ONE OF THESE TWO. ; TSTBAUD EQU $+OFFSET CALL MINPUT ;GET CHARACTER FROM MODEM CPI CR ;IF A CARRIAGE RETURN... RZ ;.. RETURN CPI LF ;IF A LINEFEED... RET ;RET ZERO FLAG, ELSE NOT ZERO ; ; LOSS OF CONNECTION TEST ; ;THE PMMI MODEM AUTOMATICALLY HANGS UP THE ;PHONE AFTER 15 SECONDS OF LOSS OF CARRIER, ;PROVIDING YOU OUTPUT TO PORT 0 TO ALLOW IT. ;(WHICH THIS PROGRAM DOES) ; ;..SO, THIS ROUTINE FIRST CHECKS IF THE MODEM Š;HAS HUNG UP, AND IF SO, RETURNS WITH CARRY SET. ;IF NOT, IT CHECKS FOR CARRIER, AND RETURNS ;IF CARRIER IS ON, OTHERWISE WAITS FOR CARRIER ;WHILE STILL TESTING FOR DISCONNECT ; ;IT TESTS THE PMMI "CTS" (CLEAR TO SEND) BIT ;WHICH IS 0 WHEN THERE IS CARRIER ; CARCK EQU $+OFFSET IN RPORT ;GET STATUS ANI P2CONN ;CONNECTED? STC ;(IN CASE NOT) RNZ ;HUNG UP. ;STILL CONNECTED, CHECK FOR CARRIER IN RPORT ;LOOK AT STATUS ANI P2CTS ;GET CARRIER DETECT BIT JZ CARCK2 ;CONTINUE W/TESTS ; ;LOOP UNTIL EITHER CONNECTION LOST, OR ;CARRIER RETURNS ; JMP CARCK ; ; NOW TEST DRIVE #'S AND (IF CPM 2.X) ; USER #'S TO INSURE THAT MAXIMUMS ; ARE NOT EXCEEDED ; CARCK2 EQU $+OFFSET LDA 4 ;CHECK DISK/USER # ANI 0FH ;ISOLATE DRIVE CPI MAX$DRIVE ;VALID DRIVE? JC CARCK3 ;YES, SKIP THIS JUNK LDA 4 ;RESTORE WHOLE LOGIN BYTE ANI 0F0H ;RETAIN USER # STA 4 ;FORCE DRIVE TO A JMP 0 ;FORCE WARM BOOT CARCK3 EQU $+OFFSET ; IF CPM2 LDA 4 ;REFRESH LOGIN BYTE AGAIN ANI 0F0H ;ISOLATE USER # CPI MAX$USER*16+1 ;VALID USER #? JC CARCK4 ;YES, DON'T CHANGE LDA 4 ;GET BACK LOGIN BYTE ANI 0FH ;KEEP DRIVE, ZERO USER STA 4 CALL ILPRT ;TELL HIM WHAT HAPPENED DB 'INVALID USER NUMBER',0 JMP 0 ;FORCE WARM BOOT ENDIF ; CARCK4 EQU $+OFFSET ORA A RET ; Š; .1 SEC DELAY ROUTINE ; DELAY EQU $+OFFSET PUSH B ; IF FASTCLK LXI B,16667 ;4 MHZ TIMING CONSTANT ENDIF ; IF NOT FASTCLK LXI B,8334 ;2 MHZ TIMING CONSTANT ENDIF ; DELAY1 EQU $+OFFSET DCX B MOV A,B ORA C JNZ DELAY1 POP B RET ; ; 50 MS DELAY ROUTINE ; KDELAY EQU $+OFFSET PUSH B ; IF FASTCLK LXI B,8334 ENDIF ; IF NOT FASTCLK LXI B,4167 ENDIF ; JMP DELAY1 ; ;PATCH IN THE NEW JMP TABLE (SAVING THE OLD) ; PATCH EQU $+OFFSET CALL TBLADDR ;CALC HL= CP/M JMP TABLE LXI D,VCOLDBT ;POINT TO SAVE LOCATION CALL MOVE ;MOVE IT ;NOW MOVE NEW JMP TABLE TO CP/M CALL TBLADDR ;CALC HL=CP/M'S JMP TABLE XCHG ;MOVE TO DE LXI H,NEWJTBL ;POINT TO NEW CALL MOVE ;MOVE IT RET ; UNPATCH EQU $+OFFSET CALL TBLADDR ;HL=CP/M'S JMP TABLE XCHG ;MOVE TO DE LXI H,VCOLDBT ;GET SAVED TABLE CALL MOVE ;MOVE ORIG BACK RET Š; ;CALCULATE HL=CP/M'S JUMP TABLE, B=LENGTH ; TBLADDR EQU $+OFFSET LHLD 1 ;GET BIOS POINTER DCX H ;..SKIP DCX H ;..TO DCX H ;..COLD BOOT ; IF NOT PRINTER MVI B,18 ;BYTES TO MOVE ENDIF ; IF PRINTER ;RETAIN LIST DEVICE? MVI B,15 ;DON'T MOVE LISTER JUMP ENDIF ; RET ; ;MOVE (HL) TO (DE), LENGTH IN (B) ; MOVE EQU $+OFFSET MOV A,M ;GET A BYTE STAX D ;PUT AT NEW HOME INX D ;BUMP POINTERS INX H DCR B ;DEC BYTE COUNT JNZ MOVE ;IF MORE, DO IT RET ;IF NOT,RETURN ; ;COMMON ROUTINE TO CHECK FOR CARRIER LOST, ;CALLED FROM CONSOLE OUT ; CHECK EQU $+OFFSET CALL CARCK ;SEE IF CARRIER STILL ON RNC ;ALL OK ;CARRIER IS LOST. TYPE MESSAGE SO LOCAL CONSOLE ; SHOWS THE REASON BADPASS EQU $+OFFSET ;COME HERE ON BAD PASSWORD MVI A,1 ;SHOW CARRIER LOST SO STA LOSTFLG ;..WE WON'T CK AGAIN LXI SP,STACK ;ENSURE VALID STACK CALL ILPRT DB CR,LF DB '++CARRIER LOST++' DB CR,LF,' ',0 CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL XRA A ;CLEAR OUT CARRIER.. STA LOSTFLG ;..LOST FLAG JMP HANGUP ; ;READBYTE ROUTINE - USED TO READ THE ; WELCOME FILE ; RDBYTE EQU $+OFFSET Š MOV A,H ;TIME TO READ? ORA A ;..IF AT 100H JZ NORD ;NO READ REQ'D ;HAVE TO READ A SECTOR LXI D,FCB MVI C,READ CALL BDOS ORA A ;OK? MVI A,1AH ;FAKE UP EOF RNZ ;RET EOF IF BAD LXI H,80H NORD EQU $+OFFSET MOV A,M ;GET CHAR INX H ;TO NEXT RET ; ;KEYBOARD/MODEM STATUS TEST ROUTINE ; MSTAT EQU $+OFFSET ; IF DUAL$IO ;WANT LOCAL CONSOLE? CALL CONSTAT ;GET LOCAL STATUS ORA A RNZ ;RET IF LOCAL CHAR ENDIF ; IN TPORT ;GET STATUS ANI P0DAV ;DATA AVAILABLE? RZ ;RETURN IF NOT READY IN TPORT ;GET STATUS ANI 30H ;CHECK FRAMING AND OVERRUN BITS JZ MSTAT1 ;NO ERRORS...LEGIT CHARACTER IN DPORT ;SWALLOW CHARACTER (CLEARS PODAV) XRA A ;RETURN FALSE RET MSTAT1 EQU $+OFFSET MVI A,0FFH ;SHOW READY ORA A RET ; ;MODEM INPUT FUNCTION, CHECKS LOCAL CONSOLE FIRST ; MINPUT EQU $+OFFSET ; IF TIMEOUT PUSH H LXI H,TOVALUE*MINUTES ;INITIALIZE TIMEOUT COUNTER SHLD TOCNT POP H ENDIF ; MINPUT1 EQU $+OFFSET LDA LOSTFLG ;KNOWN LOSS.. ORA A ;..OF CARRIER? CZ CHECK ;CARRIER STILL ON? Š CALL MSTAT ;ANYTHING? ORA A ; IF NOT TIMEOUT JZ MINPUT ;LOOP TILL CHAR RCD ENDIF ; IF TIMEOUT JNZ MINPUT2 CALL KDELAY ;KILL 50 MS PUSH H LHLD TOCNT ;KNOCK DOWN TIMEOUT COUNTER DCX H SHLD TOCNT MOV A,H ORA L POP H JNZ MINPUT1 ;STILL TIME LEFT..KEEP TRYING CALL ILPRT DB '+++INPUT TIMED OUT+++',7,7,0 JMP NOSLASH ENDIF ; MINPUT2 EQU $+OFFSET ; IF DUAL$IO ;BOTH LOCAL AND REMOTE CALL CONSTAT ;CHECK LOCAL CONSOLE ORA A ;CHAR? JNZ CONIN ;..YES, READ IT, RET. ENDIF ; ; LOCAL CONSOLE WASN'T READY, SO READ MODEM ; IN DPORT ;GET DATA BYTE ANI 7FH ;DELETE PARITY JZ MINPUT ;IGNORE NULLS ; IF IMSAI AND HARDLOG AND PRINTER PUSH B MOV B,A IN SENSE ANI LOGSW MOV A,B POP B JZ NOLOG ENDIF ;END OF IMSAI CONDITIONAL ; IF HARDLOG AND PRINTER AND NOT MAP$IO OUT PTRPORT ;ECHO ON PRINTER ENDIF ; IF HARDLOG AND PRINTER AND MAP$IO STA PTRPORT ENDIF ; Š IF HARDLOG AND PRINTER CPI CR JZ NOLOG ;CR NEEDS LINEFEED MVI A,LF ENDIF ; IF HARDLOG AND PRINTER AND NOT MAP$IO OUT PTRPORT ;SO SEND IT ENDIF ; IF HARDLOG AND PRINTER AND MAP$IO STA PTRPORT ENDIF ; IF HARDLOG AND PRINTER MVI A,CR ;GET BACK CR ENDIF ;END OF (HARDLOG AND PRINTER) ; NOLOG EQU $+OFFSET ; CPI 3 ;IS IT CONTROL-C? RNZ ;NO, PASS IT THRU LDA 0 ;SEE IF WARM BOOT DISABLED CPI 0C3H ;JMP MEANS WARM BOOT OK MVI A,3 ;SO RETURN CONTROL-C RZ XRA A ;ELSE CONVERT TO NULL RET ; MOUTPUT EQU $+OFFSET ;IF WE ALREADY KNOW CARRIER IS LOST, ;DON'T CHECK FOR IT AGAIN LDA LOSTFLG ;KNOWN LOSS OF CARRIER? ORA A CZ CHECK ;CARRIER STILL ON? IN TPORT ;READ MODEM STATUS ANI P0TBMT ;XMIT BUFF EMPTY? JZ MOUTPUT ;LOOP IF NOT READY ; IF IMSAI AND BLACKOUT AND DUAL$IO IN SENSE ;FLIP SWITCH UP... ANI BLACKSW ;..TO BLIND REMOTE USER JNZ SILENT ENDIF ; MOV A,C ;GET CHAR ; IF CK$LWC CPI 60H ;CHECK FOR LOWER CASE JC MOUTP2 ;SKIP IF NOT LC CPI 7FH ;CHECK FOR RUBOUT JZ MOUTP2 PUSH H LXI H,ULCSW ;SUBTRACE EITHER 20H OR 0 SUB M Š POP H MOV C,A ;FORCE ON LOCAL AS WELL AS REMOTE MOUTP2 EQU $+OFFSET ENDIF ; OUT DPORT ;OUTPUT TO MODEM SILENT EQU $+OFFSET ; IF DUAL$IO ;TO LOCAL ALSO? CALL CONOUT ;SEND TO REGULAR BIOS ENDIF ; ;CHECK FOR NULLS ; CPI LF ;TIME FOR NULLS? RNZ ;NO, RETURN ;SEND NULLS IF REQUIRED LDA NULLS ;GET COUNT ORA A ;ANY? RZ ;..NO PUSH B MOV B,A ;SAVE COUNT MVI C,0 ;0 IS A NULL NULLP EQU $+OFFSET CALL MOUTPUT ;TYPE A NULL DCR B ;MORE? JNZ NULLP ;..YES, LOOP POP B RET ; ; BOOT TRAP-BECOMES DISCONNECT IF ; JMP AT 0 HAS BEEN ALTERED ; MBOOT EQU $+OFFSET LDA 0 ;LOOK AT OPCODE CPI 0C3H ;IS IT STILL JMP? JZ VWARMBT ;YES, ALLOW IT JMP NOSLASH ;NO, DISCONNECT ; ; INLINE PRINT ROUTINE ; CALL ILPRT ; DB 'MSG',0 ; ILPRT EQU $+OFFSET XTHL ;SAVE HL, GET MSG PUSH B ;SAVE ILPLP EQU $+OFFSET MOV C,M ;GET CHAR CALL MOUTPUT ;OUTPUT IT INX H ;POINT TO NEXT MOV A,M ;TEST ORA A ;..FOR END JNZ ILPLP POP B ;RESTORE XTHL ;RESTORE HL, RET ADDR Š RET ;RET PAST MSG ; IF PWRQD ;KEEP PASSWORD HERE ;ACCESS PASSWORD (ENDS IN C/R) ; PASSWD EQU $+OFFSET DB 'SHARE' ;THE PASSWORD ITSELF DB CR ;END OF PASSWORD ;ALLOW ROOM FOR BIGGER PASSWORD TO BE ; PATCHED IN DB 0,0,0,0,0,0,0,0,0,0,0,0,0 ENDIF ; ; ROUTINE TO LOAD THE COM FILE ; IF COMFILE LODCOM EQU $+OFFSET XRA A ;INITIALIZE FCB STA COMFCB LXI H,COMFCB+12 MVI B,21 ZLOOP EQU $+OFFSET MVI M,0 INX H DCR B JNZ ZLOOP MVI C,OPEN ;NOW OPEN THE FILE LXI D,COMFCB CALL BDOS INR A ;SHOULD BE NON-ZERO JZ ABORT ;NO FILE, ABORT ; ; NOW LOAD THE FILE ; LHLD 6 ;GET TOP OF MEMORY LXI D,-80H ;RECORD LOADS CAN'T START.. DAD D ;..ABOVE (BDOS) - 80H PUSH H ;SAVE ON STACK ; LXI D,80H ;TPA-80H LXI B,0 ;KEEP A RECORD COUNTER PUSH B ;SAVE COUNTER PUSH D ;AND LOAD ADDRESS GLOOP EQU $+OFFSET POP D ;GET TPA ADRS LXI H,80H ;POINT TO NXT ADRS TO READ TO DAD D ;HL HAS THE ADDRESS POP B ;INCREMENT THE COUNTER ; ; CHECK FOR LOAD PAST TOP-OF-MEMORY ; POP D ;GET -(TOP-OF-MEMORY) PUSH D ;RE-SAVE FOR NEXT TIME ; MOV A,E ;SUBTRACT: (TOP) - (ADRS) Š SUB L MOV A,D ;ONLY THE CARRY NEEDED SBB H ; JNC SIZEOK ;CY= BETTER MOVCPM CALL ERRXIT ;SO TELL THE STORY DB '++ PROGRAM AREA TOO SMALL ++','$' ; SIZEOK EQU $+OFFSET INX B PUSH B PUSH H ;SAVE TPA ADRS XCHG ;ALIGN REGISTERS MVI C,STDMA ;TELL BDOS WHERE TO PUT RECORD CALL BDOS LXI D,COMFCB ;NOW READ THE RECORD MVI C,READ CALL BDOS ORA A JZ GLOOP ;A=0 IF MORE TO READ POP B ;UNJUNK STACK POP B ;THIS IS OUR COUNTER POP H ;MORE JUNK ON STACK MOV A,B ;CHECK FOR ZERO ORA C JZ ABORT ;WE SHOULD HAVE READ SOMETHING LXI D,80H ;WE DID, RESET DMA TO 80H MVI C,STDMA CALL BDOS CALL LOADOK ;PRINT THIS MSG TO CONSOLE: DB '++ COM FILE LOADED ++',CR,LF,'$' LOADOK EQU $+OFFSET POP D LDA OPTION ;SEE IF THIS WAS "BYE /C" CPI 'C' ;IF IT WAS THEN.. RZ ;..DON'T PRINT MESSAGE MVI C,PRINTF CALL BDOS RET ABORT EQU $+OFFSET CALL ERRXIT DB CR,LF DB '+++CANNOT FIND COM FILE.+++','$' ERRXIT EQU $+OFFSET POP D MVI C,PRINTF CALL BDOS ;PRINT THE ABORT MSG JMP 0 ;GIVE UP ENDIF ; ;THIS AREA IS USED FOR VECTORING CALLS TO THE ;USER'S CBIOS, BUT SAVING THE REGISTERS FIRST ;IN CASE THEY ARE DESTROYED. ; ŠCONSTAT EQU $+OFFSET PUSH B PUSH D PUSH H CALL VCONSTAT POP H POP D POP B RET ; CONIN EQU $+OFFSET PUSH B PUSH D PUSH H CALL VCONIN ; IF FKEYS CALL CKFUNC ENDIF ; POP H POP D POP B ; ; CKFUNC EQU $+OFFSET ; IF FKEYS AND IMSAI PUSH B MOV B,A ;SAVE CHAR IN SENSE ;READ THE SWITCHES ANI ENABLF ;CHECK FKEY ENAB SW MOV A,B POP B RZ ;NO FUNCT IF SW OFF ENDIF ; IF FKEYS CPI SYSDKEY JZ SYSDOWN ;TELL CALLER TO LEAVE CPI TWITKEY JZ GOODBY ;MAKE CALLER LEAVE CPI MSGKEY RNZ CALL ILPRT ;SEND CALLER A MESSAGE DB 'MESSAGE FROM OPERATOR:',0 MVI A,' ' ;SOMETHING TO RETURN WITH RET ; SYSDOWN EQU $+OFFSET CALL ILPRT DB 'SYSTEM DOWN IN' DB ' 5 MINUTES....',0 MVI A,' ' RET Š ENDIF ; CONOUT EQU $+OFFSET PUSH B PUSH D PUSH H CALL VCONOUT POP H POP D POP B RET ; ; ; THIS IS THE JMP TABLE WHICH IS COPIED ; ON TOP OF THE ONE POINTED TO BY ; LOCATION 1 IN CP/M ; NEWJTBL EQU $+OFFSET JMP MBOOT ;COLD BOOT JMP MBOOT ;WARM BOOT JMP MSTAT ;MODEM STATUS TEST JMP MINPUT ;MODEM INPUT ROUTINE JMP MOUTPUT ;MODEM OUTPUT ROUTINE RET ;DUMMY LIST DEVICE NOP NOP ; WELFILN EQU $+OFFSET DB 0,'WELCOME ',0 ;WELCOME FILE NAME ^^^^^^^^^^^ ; NULLS EQU $+OFFSET DB 5 ; COMFCB EQU $+OFFSET DB 0,'CBBS COM' PEND EQU $+OFFSET ;END OF RELOCATED CODE ; ; THESE AREAS ARE NOT INITIALIZED ; DS 21 ;REST OF COM FCB ULCSW EQU $+OFFSET DS 1 OPTION EQU $+OFFSET DS 1 TOCNT EQU $+OFFSET DS 2 ; ; ;KEEP TRACK OF LOST CARRIER WHEN TYPING ;"++CARRIER LOST++" SO WE DON'T LOOP ; LOSTFLG EQU $+OFFSET DS 1 ; Š;SAVE THE CP/M JUMP TABLE HERE ; VCOLDBT EQU $+OFFSET DS 3 VWARMBT EQU $+OFFSET DS 3 VCONSTAT EQU $+OFFSET DS 3 VCONIN EQU $+OFFSET DS 3 VCONOUT EQU $+OFFSET DS 3 VLISTOUT EQU $+OFFSET DS 3 ; ; SINCE THESE AREAS ARE NOT INITIALIZED, ; THE FOLLOWING COUNTERS WILL NOT BE CHANGED ; BY SUBSEQUENT LOADS OF THIS PROGRAM ; IF USRLOG OLDUSR EQU $+OFFSET DS 1 NEWUSR EQU $+OFFSET DS 1 NONUSR EQU $+OFFSET DS 1 ENDIF ; ; DS 60 STACK EQU $+OFFSET ;LOCAL STACK ; WRCON EQU 2 OPEN EQU 15 READ EQU 20 STDMA EQU 26 PRINTF EQU 9 DIRECTIO EQU 6 CSTS EQU 11 CI EQU 1 FCB EQU 5CH FCBRNO EQU FCB+32 ; END A>