home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
sigm
/
sigmv066.ark
/
APBYE.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
36KB
|
1,563 lines
; APBYE V6.9 (revised 3/30/81)
; REMOTE CONSOLE PROGRAM FOR CP/M AND MODEM
;
;This program allows modem callers to use your CP/M system
;just as if they were seated at the system console. Special
;assembly-time options allow limiting the caller's access by
;password and/or access to only a message-service program.
;
;Based on an original program written by Dave Jaffe, January 1979
;Rewritten for PMMI modem by Ward Christensen, February 1979.
;
;MODIFIED FOR DCH MMII
;BY DAVID MORITZ, MARCH 1981
;
;
;PLEASE NOTIFY ME OF ANY MOD-
;IFICATIONS:
;
; DAVID MORITZ
; 2228 N. SAWYER
; CGO.,IL. 60647
;
; 312 384-4762
; (24 HR. MODEM)
;
;Thanks to Bill Precht for the "label + offset" idea allowing
;this program to relocate itself without using DDT to initially
;set it up.
;
;Modifications/fixes: (in reverse order to minimize reading time)
;
;03/30/81 COMBINED APBYE12 WITH
;MODIFIED VERSION OF BYE69.
;
;THANKS TO GORDON BANKS FOR THE
;ADDITION OF 'HIMEM' ROUTINES
;TO PREVENT TRANSIENT PROGRAMS
;FROM OVERWRITING BYE BY CHANGING
;THE JUMP VECTOR IN 6,7 TO BDOS
;TO ALLOW JUMPING AROUND THE
;PROGRAM.
;
;03/20/81 Fixed MOUTPUT so parity bit is stripped before outputting
; character to modem. Corrected 3/18/81 null fix. Added
; additional description to heading of this file. (KBP)
;
;03/18/81 Add first-ring debounce routine, change PMMI HANGUP
; to do break for faster disconnect, fix error in P3TODTR
; equate for PMMI, added end-of-program error message to
; mark ending address (see note at label DEST). By KBP.
; Fix bug that prevented nulls at end of line if DUAL$IO
; was true. By Hank Szyszka.
;
;
;02/17/81 Added check for extraneous control characters in
; hardcopy log. (Formfeed seems to be a common "hit").
; Changed local startup test to directly test for carrier
; instead of calling CARCK, to avoid 15 second delay.
; <BRR>
;
; Rearranged patch list to "most recent first" order.
; Added message for invalid-drive test.
; Added ANI 7Fh to upper case conversion test so that
; it's not fooled by bit 7 being set.
; Added WELUSR equate for user # containing WELCOME file.
; Removed PTRPORT equate and changed hardcopy logic to
; work through the BIOS printer driver. <BRR>
;
;01/22/81 Changed carrier detect routine for DC Hayes to wait for
; 15 seconds after loss of carrier to return. <DAVID KOZINN>
;
; if present. <DAVID KOZINN>
;
;
;09/23/80 Fixed bugs that prevented "bye /a" and "bye /c" from
; working properly. Also repaired several errors in
; conditional assembly nesting. By Ron Fowler
;
;09/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
;
;09/19/80 Modified COM file load routine to prevent BDOS
; overwrite if the COM file won't fit in the TPA
; By Ron Fowler
;
;09/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
;
;09/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
;
;09/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
;
;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
; assembly. By Ron Fowler
;
;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
;
;07/16/80 Added "/R" command option to allow USRLOG
; counters to be reset upon entry. 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/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
;
;06/29/80 Added USRLOG routines to keep track of number
; OF CALLERS.
; By Dave Hardy
;
;
;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.
;
;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.
;
;05/06/79 Added routine to allow "callback" operation so modem
; does not answer normal voice calls. By Robbin Hough
; and Keith Petersen, W8SDZ.
;
;------------------------------------------------
;
;This program runs up in high RAM. It gets there
;by being moved there when 'BYE' is typed.
;
;The program in high 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 tried 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
CR EQU 0DH
LF EQU 0AH
MINUTES EQU 20*60 ;CONSTANT FOR 1 MIN TIME DELAY
;
;Change the following equate to an area in your
;high memory where this program may patch itself in.
;Approximate memory requirements: 2k bytes or more,
;depending upon the options selected. A marker has
;been placed at the end to deliberately print an error
;message during assembly in order to determine the actual
;ending address of the program. The error message will
;not affect the assembly. Make sure you have memory
;available up to the address shown.
;
DEST EQU 0BE00H ;RUNNING LOCATION OF CODE
RSET EQU 0DAF0H ;WHERE CP/MLOADS THE BDOS ADDRESS
JUMP EQU 0C3H ;OP-CODE FOR A JMP
;
CONDATA EQU 0E000H
;
;
;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'.
;
;****************************************************
;* Option configuration section *
;****************************************************
;
PRINTER EQU FALSE ;WANT TO RETAIN LIST DEVICE?
DUAL$IO EQU TRUE ;WANT CONSOLE & MODEM?
CALLBAK EQU FALSE ;WANT CALLBACK FEATURE?
PWRQD EQU FALSE ;WANT TO USE PASSWORD?
USRLOG EQU TRUE ;WANT TO COUNT NUMBER OF USERS?
HARDLOG EQU FALSE ;WANT TO ECHO REMOTE KBD TO PRINTER?
CPM2 EQU TRUE ;USING CP/M 2.x?
MAXUSR EQU 3 ;SET TO 0 FOR CP/M 1.4
MAXDRV EQU 3 ;HIGHEST DRIVE SUPPORTED
FASTCLK EQU FALSE ;SET TRUE FOR 4 MHZ CLOCK
TIMEOUT EQU TRUE ;WANT AUTO LOG-OFF FOR SLEEPY CALLERS?
TOVALUE EQU 3 ;THIS IS 3 MINUTES TO AUTO LOGOUT
WELUSR EQU 0 ;USER # THAT WELCOME FILE IS KEPT IN
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?
TRAPLC EQU FALSE ;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
;
;
;****************************************************
;* End of option configuration section *
;****************************************************
;
;
;
;MMII MODEM ADDRESS EQUATES
;
TPORT EQU 0E0A6H ;CONTROL/STATUS PORT
DPORT EQU 0E0A7H ;DATA PORT
RPORT EQU 0E0A5H ;RATE GEN/MODEM STATUS
CPORT EQU 0E0A5H ;MODEM CONTROL
RPORT1 EQU 0E0A6H ;STATUS
;
;Switch hook and modem commands, output to TPORT (port 0)
;
P0BYE EQU 0 ;ON HOOK, OR DIALING BREAK
P0ORIG EQU 8EH ;OFF HOOK, ORIG.
P0ANSW EQU 8AH ;ANSWER PHONE
P0TSB EQU 08H ;2 STOP BITS
P0EI EQU 20H ;ENABLE INTERRUPTS
P0NORM EQU 15H ;NORMAL 8 BITS, NO PARITY
P0110 EQU 11H ;SAME W/2 STOP BITS
;
;Modem status, input on RPORT (port 3)
;
P2RDET EQU 80H ;RING DETECT
P2CTS EQU 04H ;CTS (CARRIER DETECT)
;
;MMII modem status masks
;
P0TBMT EQU 2 ;XMIT BUFF EMPTY
P0DAV EQU 1 ;DATA AVAILABLE
P0RPE EQU 40H ;REC'D PARITY ERR
P0ORUN EQU 20H ;OVERRUN
P0FERR EQU 10H ;FRAMING ERROR
;
;Baud rate divisors
;
B110 EQU 0 ;110 BAUD
B300 EQU 1 ;300 BAUD
;
;
;
;
;---------------------------------------------------------
;
ORG 100H
;
;Move modem interface program up to high RAM and jump to it
;
;BUT FIRST, PROTECT BYE BY RESETTING BDOS JUMPS
;
HIMEM LDA BDOS+2 ;HAS HIMEM ALREADY BEEN SET?
CPI 0CCH ;THIS IS WHAT IS NORMALLY THERE
JZ CONT ;STILL CC, SO CONTINUE
JMP MOVEUP ;ELSE SKIP NEXT BIT
CONT LHLD BDOS+1 ;LOAD CURRENT BDOS JUMP
SHLD DEST-2 ;PUT IN FRONT OF BYE
MVI A,JUMP ;WRITE A JMP OP-CODE IN FRONT OF THAT
STA DEST-3
LXI H,DEST-3 ;MOVE THE NEW JUMP-TO ADDRESS..
SHLD RSET+1 ;..TO THE RESET VECTOR SETTER
SHLD BDOS+1 ;AND TO BDOS JUMP ADDRESS
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,WELUSR
CALL BDOS
ENDIF ;CPM2
;
RET ;TO ADRS PUSHED ABOVE
;
;
SOURCE EQU $ ;BOUNDARY MEMORY MARKER
;
OFFSET EQU DEST-SOURCE ;RELOC AMOUNT
;
;-----------------------------------------------;
; The following code gets moved ;
; to high 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 high XX
;XX RAM 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'
;
;
LDA RPORT1 ;AS ABOVE, FOR PMMI MODEM
ANI P2CTS ;CD DEDUCED FROM CTS
JZ 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 HANGUP
;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 ;COMFILE
;
IF USRLOG ;CHECK FOR RESET OF COUNTERS
CPI 'R'
CZ RESET
ENDIF ;USRLOG
;
JMP HANGUP ;WE KNOW IT'S LOCAL, SO SKIP CALL TO CARCK
;
;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 / <ANYTHING>"
;
IF CPM2 AND COMFILE
MVI C,32 ;GET/SET USER CODE
MVI E,COMUSR ;LOCATION OF OUR COMFILE
CALL BDOS
ENDIF ;CPM2 AND COMFILE
;
IF COMFILE
CALL LODCOM ;LOAD THE COM FILE
ENDIF ;COMFILE
;
;
HANGUP2 EQU $+OFFSET
;
;Clear DTR causing phone to hang up
;
;
XRA A ;GET DISCONNECT VALUE
STA TPORT ;RESET ORIG/ANSW
STA CPORT ;TURN OFF DTR, DO BREAK
;
;
;
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 input via BDOS because CBIOS patches
;are not done until call comes in.
LDA CONDATA
ANI 7FH ;STRIP PARITY BIT
CPI 'C'-40H ;CONTROL C?
;
IF NOT USRLOG
JZ 0 ;YES, --EXIT-- TO CP/M
ENDIF ;NOT USRLOG
;
IF USRLOG ;PRINT OUT USER INFO
JZ PRNLOG
ENDIF ;USRLOG
;
RINGW2 EQU $+OFFSET
LDA RPORT ;GET THE STATUS
ANI P2RDET ;RINGING?
JNZ RINGWT ;NO, WAIT
;
;The phone may be ringing. Wait .1 sec and look
;again to make sure it isn't just relay bounce
CALL DELAY ;.1 SEC DELAY FOR DEBOUNCE
LDA RPORT ;GET STATUS
ANI P2RDET ;STILL RINGING?
JNZ RINGWT ;NO, IT WAS RELAY BOUNCE
;
;The phone is definitely ringing, now wait until ring is finished
;
ENDRING EQU $+OFFSET
CALL DELAY ;.1 SEC DELAY FOR DEBOUNCE
LDA 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 househole 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
LDA RPORT ;GET THE STATUS
ANI P2RDET ;RINGING AGAIN?
JNZ EXPECT ;NO?...ITS FOR ME!
;
;If second ring, then check for third ring, in case
;caller's phone exchange not synch'ed with computer's
;
ENDRNG2 EQU $+OFFSET
LDA RPORT ;GET THE STATUS
ANI P2RDET ;STILL RINGING?
JZ ENDRNG2 ;WAIT UNTIL RING FINISHED
MVI L,45 ;DELAY 4.5 SECONDS FOR NEXT RING
;
WAITNX2 EQU $+OFFSET
CALL DELAY ;WAIT .1 SECONDS
DCR L ;MOE TO GO?
JNZ WAITNX2 ;YES, LOOP
LDA RPORT ;GET THE STATUS
ANI P2RDET ;RINGING AGAIN?
JNZ EXPECT ;NO?...ITS FOR ME!
;
;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
LDA 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 ;ADD ONE TO COUNT
ENDIF ;CALLBAK AND USRLOG
;
IF CALLBAK AND USRLOG AND DECIMAL
DAA ;MAKE DECIMAL
ENDIF ;CALLBK AND USRLOG AND DECIMAL
;
IF CALLBAK AND USRLOG
STA NONUSR ;SAVE NEW COUNT
ENDIF ;CALLBK AND USRLOG
;
IF CALLBAK ;CONTINUE WITH CALLBAK ROUTINES
JMP HANGUP2 ;GO WAIT FOR NEXT CALL
;
EXPECT EQU $+OFFSET
LXI H,400 ;40 SECONDS TO WAIT FOR SECOND CALL
;
RELOOK EQU $+OFFSET
LDA RPORT ;GET THE STATUS
ANI P2RDET ;RINGING AGAIN?
JZ ANSWER ;YES, GO ANSWER IT
CALL DELAY ;WAIT .1 SECOND
DCX H ;ONE LESS COUNT
MOV A,H
ORA L ;IS COUNT ZERO?
JNZ RELOOK ;NO, LOOK SOME MORE
JMP HANGUP2 ;COUNT DONE, WAIT FOR NEW CALL
;
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 ;USRLOG
;
IF USRLOG AND DECIMAL
DAA ;MAKE IT DECIMAL
ENDIF ;USRLOG AND DECIMAL
;
IF USRLOG
STA OLDUSR ;SAVE NEW COUNT
ENDIF ;USRLOG
;
;
MVI A,P0ANSW ;TURN ON DTR
STA CPORT ;.. AND SET FILTER VALUE FOR 300 BAUD
MVI E,20
ANSWR1 EQU $+OFFSET
CALL DELAY ;GIVE TIME TO TURN ON
DCR E
JNZ ANSWR1
MVI A,P0110
STA TPORT ;ANSWER PHONE
CALL DELAY ;GIVE TIME FOR ANSWER
LDA CONDATA
LDA DPORT ;CLEAR MODEM PORT
LDA DPORT ;MAKE SURE ITS CLEAR
;Output value allowing modem to hang up on loss of carrier
CALL CARCK0
JC HANGUP
;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.
STA TPORT
MVI A,B300+P0ANSW ;SET DIVISOR
STA CPORT ;.. TO 300 RATE
CALL TSTBAUD ;SEE IF BAUD = 300
JZ WELCOME ;YES, EXIT
CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL
JMP ANSWER ;TEST MORE - INVALID BAUD RATE
;
;
;Following are the USRLOG routines
;
IF USRLOG ;INCLUDE RESET FUNCTIONS
RESET EQU $+OFFSET ;RESET ALL LOGON COUNTERS
XRA A
ENDIF ;USRLOG
;
IF USRLOG AND PWRQD
STA OLDUSR ;RESET ATTEMPT COUNTER
ENDIF ;USRLOG AND PWRQD
;
IF USRLOG
STA NEWUSR ;RESET LOGON COUNTER
ENDIF ;USRLOG
;
IF USRLOG AND CALLBAK
STA NONUSR ;RESET VOICE COUNTER
ENDIF ;USRLOG AND CALLBAK
;
;
IF USRLOG
RET
ENDIF ;USRLOG
;
PRNLOG EQU $+OFFSET
;
IF USRLOG AND PWRQD ;PRINT # OF LOGON ATTEMPTS
MVI C,PRINTF
LXI D,ATMSG
CALL BDOS
LDA OLDUSR
CALL HXOUT
ENDIF ;USRLOG AND PWRQD
;
IF USRLOG ;PRINT # OF LOGONS
MVI C,PRINTF
LXI D,SUMSG
CALL BDOS
LDA NEWUSR
CALL HXOUT
ENDIF ;USRLOG
;
IF USRLOG AND CALLBAK ;# OF VOICE CALLS
MVI C,PRINTF
LXI D,VCMSG
CALL BDOS
LDA NONUSR
CALL HXOUT
ENDIF ;USRLOG AND CALLBAK
;
IF USRLOG
JMP 0 ;WARM-BOOT BACK TO CP/M
ENDIF ;USRLOG
;
IF USRLOG AND PWRQD
ATMSG EQU $+OFFSET
DB LF,CR,'NUMBER OF LOGON ATTEMPTS: $'
ENDIF ;USRLOG AND PWRQD
;
IF USRLOG
SUMSG EQU $+OFFSET
DB LF,CR,'NUMBER OF LOGONS: $'
ENDIF ;USRLOG
;
IF USRLOG AND CALLBAK
VCMSG EQU $+OFFSET
DB LF,CR,'NUMBER OF VOICE CALLS: $'
ENDIF ;USRLOG AND CALLBAK
;
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 ;USRLOG
;
;Welcome to the system
;
WELCOME EQU $+OFFSET
;
GETNULL EQU $+OFFSET
CALL ILPRT ;PRINT THIS MSG:
DB CR,LF
DB 'HOW MANY NULLS (0-9) DO YOU NEED? ',0
CALL MINPUT ;GET VALUE
MOV C,A ;TO C FOR MOUTPUT
CALL MOUTPUT ;ECHO CHAR
MOV A,C ;RESTORE VALUE
CPI '0'
JC GETNULL ;BAD, RETRY
CPI '9'+1
JNC GETNULL ;BAD
SUI '0' ;MAKE BINARY
STA NULLS ;SAVE COUNT
;
IF TRAPLC
GETULC EQU $+OFFSET
CALL ILPRT ;PRINT 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...GO ASK AGAIN
XRA A
STA ULCSW ;SET FLAG FOR NO CONVERSION
;
DONEOPT EQU $+OFFSET
ENDIF ;TRAPLC
;
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 address to 80h
LXI D,80H
MVI C,STDMA
CALL BDOS
;
IF CPM2
;Set user number for welcome file
MVI C,32
MVI E,WELUSR
CALL BDOS
ENDIF ;CPM2
;
;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
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
LDA 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 ;PWRQD
;
NOPASS EQU $+OFFSET
;
IF USRLOG ;COUNT # OF SUCCESSFUL LOGONS
LDA NEWUSR ;GET LAST VALUE
INR A ;INCREMENT IT
ENDIF ;USRLOG
;
IF USRLOG AND DECIMAL
DAA ;MAKE IT DECIMAL
ENDIF ;USRLOG AND DECIMAL
;
IF USRLOG
STA NEWUSR ;SAVE NEW VALUE
ENDIF ;USRLOG
;
CALL ILPRT
DB CR,LF,' ',0 ;PUT BOOT-UP MSG HERE
;
IF COMFILE AND CPM2
MVI C,32
MVI E,COMUSR ;SWITCH TO COM FILE USER #
CALL BDOS
ENDIF ;COMFILE AND CPM2
;
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 ;COMFILE
;
IF NOT COMFILE
JMP 0
ENDIF ;NOT COMFILE
;
;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
;
CARCK0 EQU $+OFFSET;INITIAL
PUSH D ;CARRIER
MVI E,150 ;DETECT
JMP CARCK5 ;ROUTINE
CARCK EQU $+OFFSET
PUSH D
MVI E,150
CARCK1 EQU $+OFFSET
LDA RPORT1
ANI P2CTS ;GOT A CARRIER?
JZ CARCK2 ;YES, GO ON WITH TESTS
CALL DELAY ;WAIT .1 SECONDS
DCR E ;COUNT DOWN TIME
JNZ CARCK1
STC
POP D
RET
;
;NOW TEST DRIVE #'S AND (IF CP/M 2.X) USER #'S TO
;insure that maximums are not exceeded.
;
CARCK2 EQU $+OFFSET
LDA 4 ;CHECK DISK/USER #
ANI 0FH ;ISOLATE DRIVE
CPI MAXDRV ;VALID DRIVE?
JC CARCK3 ;YES, SKIP THIS JUNK
LDA 4 ;GET WHOLE LOGIN BYTE
ANI 0F0H ;RETAIN USER # & FORCE DRIVE TO A
STA 4 ;UPDATE LOGIN BYTE
CALL ILPRT ;TELL USER WHAT HE DID
DB 'INVALID DRIVE - RETURNING TO A:',0
JMP 0 ;WARM BOOT
;
CARCK3 EQU $+OFFSET
;
IF CPM2
LDA 4 ;GET LOGIN BYTE
ANI 0F0H ;ISOLATE USER #
CPI MAXUSR*16+1 ;VALID USER #?
JC CARCK4 ;YES, DON'T CHANGE
LDA 4 ;GET LOGIN BYTE AGAIN
ANI 0FH ;KEEP DRIVE, ZERO USER
STA 4 ;UPDATE LOGIN BYTE
CALL ILPRT ;TELL HIM WHAT HAPPENED
DB '++INVALID USER NUMBER - RETURNING TO 0++',0
JMP 0 ;WARM BOOT
ENDIF ;CPM2
;
CARCK4 EQU $+OFFSET
ORA A
POP D
RET
;
CARCK5 EQU $+OFFSET
LDA DPORT
LDA DPORT
LDA RPORT1
LDA RPORT1
ANI P2CTS
JZ CARCK2
CALL DELAY
DCR E
JNZ CARCK5
STC
POP D
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
MVI B,18 ;ALWAYS SAVE PRINTER VECTOR
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 ;DUAL$IO
;
LDA TPORT ;GET STATUS
ANI P0DAV ;DATA AVAILABLE?
RZ ;RETURN IF NOT READY
LDA TPORT ;GET STATUS
ANI 30H ;CHECK FRAMING AND OVERRUN BITS
JZ MSTAT1 ;NO ERRORS...LEGIT CHARACTER
LDA DPORT ;SWALLOW CHARACTER (CLEARS PODAV)
SUB 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 ;TIMEOUT
;
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 ;NOT TIMEOUT
;
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 ;TIMEOUT
;
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
;
LDA DPORT ;GET DATA BYTE
ANI 7FH ;DELETE PARITY
JZ MINPUT ;IGNORE NULLS
IF HARDLOG
CPI 20H
JNC MINPUT3
CPI CR
JNZ NOLOG
;
MINPUT3 EQU $+OFFSET
CALL LISTOUT ;ECHO ON PRINTER
CPI CR
JNZ NOLOG ;CR NEEDS LINEFEED
MVI A,LF
CALL LISTOUT ;SO SEND IT
MVI A,CR ;GET BACK CR
ENDIF ;END OF HARDLOG
;
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
;
;Modem output function
;
MOUTPUT EQU $+OFFSET
;
;If we already know carrier is lost, don't check
;for it again or loop trying to output.
LDA LOSTFLG ;KNOWN LOSS OF CARRIER?
ORA A
JNZ SILENT ;AVOID LOOP IN CASE CARRIER LOST
CALL CHECK ;CARRIER STILL ON?
LDA TPORT ;GET MODEM STATUS
ANI P0TBMT ;TRANSMIT BUFFER EMPTY?
JZ MOUTPUT ;LOOP IF NOT READY
MOV A,C ;GET CHAR
ANI 7FH ;STRIP PARITY BIT
IF TRAPLC
CPI 60H ;CHECK FOR LOWER CASE
JC MOUTP2 ;SKIP IF NOT LC
CPI 7FH ;CHECK FOR RUBOUT
JZ MOUTP2
PUSH H
LXI H,ULCSW ;SUBTRACT EITHER 20H OR 0
SUB M
POP H
MOV C,A ;FORCE ON LOCAL AS WELL AS REMOTE
;
MOUTP2 EQU $+OFFSET
ENDIF ;TRAPLC
;
STA DPORT ;OUTPUT TO MODEM
;
SILENT EQU $+OFFSET
;
IF DUAL$IO ;TO LOCAL ALSO?
PUSH PSW ;SAVE CHAR
CALL CONOUT ;SEND TO REGULAR BIOS
POP PSW ;GET CHAR AGAIN
ENDIF ;DUAL$IO
;
;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
MVI C,LF ;RESTORE LF
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
;
ILPRT EQU $+OFFSET
XTHL ;SAVE HL, GET MSG
PUSH B ;SAVE BC REGS
;
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 BC REGS
XTHL ;RESTORE HL, RET ADDR
RET ;RET PAST MSG
;
IF PWRQD ;KEEP PASSWORD HERE
;Access password (ends in carriage return)
;
PASSWD EQU $+OFFSET
DB 'HELLO' ;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 ;PWRQD
;
;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 ;WARM BOOT
ENDIF ;COMFILE
;
;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 ;FKEYS
;
POP H
POP D
POP B
RET
;
CKFUNC EQU $+OFFSET
;
;
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 ;FKEYS
;
CONOUT EQU $+OFFSET
PUSH B
PUSH D
PUSH H
CALL VCONOUT
POP H
POP D
POP B
RET
;
LISTOUT EQU $+OFFSET
PUSH B
PUSH D
PUSH H
PUSH PSW
MOV C,A
CALL VLISTOUT
POP PSW
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 ^^^^^^^^^^^ (must be 11 characters)
;
NULLS EQU $+OFFSET
DB 5
;
COMFCB EQU $+OFFSET
DB 0,'RBBS COM'
;COM file name ^^^^^^^^^^^ (must be 11 characters)
;
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
;
;Byte to 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 ;USRLOG
;
;
DS 60
STACK EQU $+OFFSET ;LOCAL STACK
;
ENDMARK EQU $+OFFSET ;! IGNORE ERROR. THIS MARKS END OF PGM
;
;BDOS equates
;
CI EQU 1
WRCON EQU 2
DRECTIO EQU 6
PRINTF EQU 9
CSTS EQU 11
OPEN EQU 15
READ EQU 20
STDMA EQU 26
BDOS EQU 5
FCB EQU 5CH
FCBRNO EQU FCB+32
;
END