home *** CD-ROM | disk | FTP | other *** search
Text File | 1984-04-29 | 36.8 KB | 1,659 lines |
- ; BYE V6.9
- ; REMOTE CONSOLE PROGRAM FOR CP/M AND MODEM
- ;
- ;---------------------------------------------------------------
- ; This version of BYE is contributed to CP/M-Net 'as-is'.
- ; It has been hacked for Australian conditions, where
- ; autodial and auto answer are illegal. The Bell-103
- ; modem equates have also been removed.
- ; Nevertheless It shows how CDOS can be configured by BYE
- ; as an RCPM host DOS.
- ; The table patching routines shown here effectively enable/disable
- ; the printer and allow remote access to the DOS
- ;
- ; Sorry about the hacking folks..
- ; If you need any help contact Trevor Marshall,
- ; 26 Mirrelia Way,
- ; Ferndale, West Australia 6155.
- ;
- ; ps. If anyone manages to get INFOSOFT IOS to work with this pgm
- ; please let me know. I have ascertained that although IOS
- ; is table driven identiaccly to CDOS (the table information
- ; came from INFOSOFT) it pulls the vector addresses in during
- ; initialization rather than every time a call is made and
- ; although this makes it faster it will not operate with this BYE.
- ; Maybe there is an undocumented system call or something???
- ; 14 July 1981
- ;-----------------------------------------------------------------
- ;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.
- ;The following had a hand in its development:
- ; Bill Precht, Hank Syzszka, P.L.Kelley, Bruce Ratoff,David Kozinn
- ; ,Ron Fowler, Dave Hardy, Bruce Levison, Keith Petersen and Robbin Hough.
- ; before Trevor Marshall reworked it for CDOS and IOS.
- ;For further background information see the file 'BYE69.ASM'.
- ;
- ;------------------------------------------------
- ;
- ;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)
- ;
- ;------------------------------------------------
- ; The original BYE programs will not work with CDOS (IOS) because
- ; they do not use the bios jump table for internal calls to I/O.
- ; Instead they are table driven, by an SDVT whick looks like:
- ; SDVT DW CON,TERM,RDR,PUN,LIST,CLOCK
- ; which in turn vectors to tables such as the console I/O
- ; CON DW CINIT,CSTAT,CINDATA,CRDY,COUTDATA
- ; and list
- ; LIST DW LINIT,LRDY,LOUT
- ;
- ; These tables are patched to vector to our modem BIOS.
- ; We can locate them by using the 81H system BDOS call
- ; which returns a user register pointer in BC
- ; (BC) -> URREG (2)
- ; SCHSW (1)
- ; SDVT (2)
- ; SDT (2)
- ; SYSBOT(2)
- ; OPILINK (2)
- ; and so we can calculate the SDVT address.
- ;
- ; For further information (or bug info) contact
- ; Trevor Marshall
- ; Wait-Aid,West Aust Inst Tech,
- ; Hayman Rd, Bentley, Western Australia 6102
- ; or ring (09) 457 6059 any time.
- ;
- ;-------------------------------------------------------
- ;
- ;
- ;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 0EA00H ;RUNNING LOCATION OF CODE
- ;
- CDOS EQU TRUE ;If running CDOS or IOS
- ;
- TREVORS EQU TRUE ;True for my design
- ;
- ;
- ;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 FALSE ;WANT TO COUNT NUMBER OF USERS?
- HARDLOG EQU FALSE ;WANT TO ECHO REMOTE KBD TO PRINTER?
- MAXDRV EQU 1 ;HIGHEST DRIVE SUPPORTED
- FASTCLK EQU TRUE ;SET TRUE FOR 4 MHZ CLOCK
- TIMEOUT EQU FALSE ;WANT AUTO LOG-OFF FOR SLEEPY CALLERS?
- TOVALUE EQU 7 ;THIS IS 7 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 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
- ;
- ;
- ;****************************************************
- ;* End of option configuration section *
- ;****************************************************
- ;
- ;All modem I/O and control are here
- ;
- ;************ Trevor's modem I/O area ************
- ;
- IF TREVORS
- ;
- ; USART is Intel 8251 or equivalent
- ;
- DPORT EQU 0F0H ;DATA PORT
- CPORT EQU 0F1H ;CONTROL PORT
- SPORT EQU CPORT ;STATUS PORT
- BPORT EQU 0F2H ;BAUD RATE PORT
- ;RPORT EQU 69H ;RING INDICATOR PORT
- ;
- ;The following are CPORT commands
- ;
- RSTINS EQU 42H ;RESET USART AND SEND DTR
- MODINS1 EQU 4EH ;8 BITS, NO PARITY, 1 STOP BIT, 16X BAUD RATE
- MODINS2 EQU 0CEH ;8 BITS, NO PARITY, 2 STOP BITS, 16X BAUD RATE
- ONINS EQU 17H ;RESET ERROR FLAGS, SEND DTR, ENABLE RECEIVE
- ;AND TRANSMIT
- OFFINS EQU 10H ;DROP DTR, DISABLE RECEIVE AND TRANSMIT
- ;
- ;The following are SPORT status masks
- ;
- TRNRDY EQU 01H ;TRANSMITER EMPTY
- RCVRDY EQU 02H ;DATA AVAILABLE
- PERR EQU 08H ;PARITY ERROR
- ORERR EQU 10H ;OVERRUN ERROR
- FRERR EQU 20H ;FRAMING ERROR
- TOERR EQU ORERR + FRERR ;OVERRUN PLUS FRAMING ERROR
- DSR EQU 80H ;DATA SET READY
- ;
- ;The following are baud rates for BPORT. The lower 4 bits are used
- ;
- BD110 EQU 22H ;110 BAUD
- BD300 EQU 55H ;300 BAUD
- BD1200 EQU 77H ;1200 BAUD
- BD2400 EQU 0AAH ;2400 BAUD
- BD4800 EQU 0CCH ;4800 BAUD
- BD9600 EQU 0EEH ;9600 BAUD
- ;
- ;Ring indicator port mask
- ;
- RI EQU 40H ;NOT RING INDICATOR (LOW TRUE)
- P2RDET EQU RI
- ;
- ;
- ENDIF ;TREVORS
- ;
- ;---------------------------------------------------------
- ;
- ORG 100H
- ;
- ;Move modem interface program up to high RAM and jump to it
- ;but first..
- ; Ensure that the user is logged off if BYE is entered
- ; whilst the vectors have been PATCHED
- LD HL,(1) ;Get addr of jmp table in BIOS
- INC HL ;see if it points beyond this addr
- LD E,(HL) ; i.e., if it points above the BIOS
- INC HL ; it must have been patched
- LD D,(HL) ;addr now in DE
- LD HL,DEST ;get address of BYE code into HL
- LD A,L ; SUB HL,DE
- SUB E ; HL should be > DE
- LD L,A ; i.e., result should be >0 & <8
- LD A,H
- SBC D
- ; MOV H,A
- AND 80H ;if result is negative (or >32k )
- JP NZ,GOODBY ; CDOS is patched already
- ;
- MOVEUP LD BC,PEND-START+1 ;NUMBER OF BYTES TO MOVE
- LD HL,DEST+PEND-START+1;END OF MOVED CODE
- LD DE,SOURCE+PEND-START;END OF SOURCE CODE
- ;
- MVLP LD A,(DE) ;GET BYTE
- DEC HL ;BUMP POINTERS
- LD (HL),A ;NEW HOME
- DEC DE
- DEC BC ;BUMP BYTE COUNT
- LD A,B ;CHECK IF ZERO
- OR C
- JP NZ,MVLP ;IF NOT, DO SOME MORE
- ;
- PUSH HL ;SAVE FOR LATER JUMP
- LD A,0C3H ;CLEAR ANY TRAPS SO SYSOP..
- LD (0),A ;CAN USER "BYE -A"
- XOR A ;NEXT WARMBOOT TO USR0/DRV A
- LD (4),A
- LD C,14 ;MAKE DRIVE A DEFAULT
- LD E,A ;LOG-IN DRIVE CP/M FUNCTION
- CALL BDOS
- ;
- 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
- ;
- XOR A ;GET 0
- LD (LOSTFLG),A ;SHOW NO CARR. LOST
- ;
- ;Don't allow a remote user to do 'BYE -A'
- ;
- ;Check for -A option on command - request to
- ;go immediately into answer mode
- LD HL,FCB+1 ;TO OPTION
- LD A,(HL)
- CP '-' ;OPTION?
- JP NZ,HANGUP
- ;Should be JMP NOSLASH??
- ;Got an option - validate it
- INC HL ;TO OPTION BYTE
- LD A,(HL) ;GET IT
- LD (OPTION),A ;MIGHT NEED LATER
- CP 'A' ;ANSWER?
- JP Z,ANSWER
- ;
- ;; IF COMFILE
- ;; CPI 'C'
- ;; JZ ANSWER
- ;; ENDIF ;COMFILE
- ;
- IF USRLOG ;CHECK FOR RESET OF COUNTERS
- CP 'R'
- CALL Z,RESET
- ENDIF ;USRLOG
- ;
- JP 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?
- JP C,HANGUP ;NOBODY THERE
- ;
- GOODBY EQU $+OFFSET
- CALL ILPRT ;PRINT THIS MSG:
- DEFB CR,LF,'Cheerio, please call again'
- DEFB CR,LF,0
- CALL UNPATCH ;UNDO BIOS PATCHES
- ;
- ;Nobody there, or we are done, so hang up
- ;
- HANGUP EQU $+OFFSET
- LD SP,STACK ;SET UP LOCAL STACK
- XOR A ;FORCE NEXT WARMBOOT TO USER 0
- LD (4),A ;AND DRIVE A
- LD C,14 ;MAKE DRIVE A DEFAULT
- LD E,A
- CALL BDOS
- LD A,' ' ;DON'T ALLOW OPTIONS..
- LD (OPTION),A ;..AFTER 1 "BYE / <ANYTHING>"
- ;
- IF COMFILE
- CALL LODCOM ;LOAD THE COM FILE
- ENDIF ;COMFILE
- ;
- ;
- HANGUP2 EQU $+OFFSET
- ;
- ;Clear DTR causing phone to hang up
- ;Was some code in here I deleted by accident;;;;;;;;;;;;;;;;
- ;;OFFTI EQU $+OFFSET
- ;; CALL DELAY ;0.1 SECOND DELAY
- ;; DCR B
- ;; JNZ OFFTI ;KEEP LOOPING UNTIL FINISHED
- ;; POP B ;RESTORE B
- ;; MVI A,ONINS ;TURN DTR ON ALLOWING MODEM TO ANSWER PHONE
- ;; OUT CPORT
- ;; ENDIF ;SUPERB
- ;
- ; IF TREVORS ;code required
- ; ENDIF ;TREVORS
- ;
- LD A,0C3H ;CLEAR ANY TRAPS..
- LD (0),A ;..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.
- ;; CALL UCSTS
- ;; 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
- ;; IN 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
- ;; IN 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
- ;; 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.
- ;
- LD L,45 ;DELAY 4.5 SECONDS FOR NEXT RING
- ;
- WAITNX EQU $+OFFSET
- CALL DELAY ;WAIT .1 SECONDS
- DEC L ;MORE TO GO?
- JP NZ,WAITNX ;YES, LOOP
- IN A,RPORT ;GET THE STATUS
- AND P2RDET ;RINGING AGAIN?
- JP NZ,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
- IN A,RPORT ;GET THE STATUS
- AND P2RDET ;STILL RINGING?
- JP Z,ENDRNG2 ;WAIT UNTIL RING FINISHED
- LD L,45 ;DELAY 4.5 SECONDS FOR NEXT RING
- ;
- WAITNX2 EQU $+OFFSET
- CALL DELAY ;WAIT .1 SECONDS
- DEC L ;MOE TO GO?
- JP NZ,WAITNX2 ;YES, LOOP
- IN A,RPORT ;GET THE STATUS
- AND P2RDET ;RINGING AGAIN?
- JP NZ,EXPECT ;NO?...ITS FOR ME!
- ;
- ;Call not for computer - wait until ringing done, then reset
- ;
- WAITNR EQU $+OFFSET
- LD L,100 ;WAIT FOR 10 SECS NO RINGING
- ;
- WAITNRL EQU $+OFFSET
- CALL DELAY ;DELAY .1 SECONDS
- IN A,RPORT ;GET THE STATUS
- AND P2RDET ;STILL RINGING?
- JP Z,WAITNR ;YES, WAIT 10 MORE SECONDS
- DEC L ;NO RING, MAYBE WE'RE DONE
- JP NZ,WAITNRL ;NO, LOOP SOME MORE
- ENDIF ;CALLBACK
- ;
- IF CALLBAK AND USRLOG
- LD A,(NONUSR) ;RECORD AS VOICE CALL
- INC 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
- LD (NONUSR),A ;SAVE NEW COUNT
- ENDIF ;CALLBK AND USRLOG
- ;
- IF CALLBAK ;CONTINUE WITH CALLBAK ROUTINES
- JP HANGUP2 ;GO WAIT FOR NEXT CALL
- ;
- EXPECT EQU $+OFFSET
- LD HL,400 ;40 SECONDS TO WAIT FOR SECOND CALL
- ;
- RELOOK EQU $+OFFSET
- IN A,RPORT ;GET THE STATUS
- AND P2RDET ;RINGING AGAIN?
- JP Z,ANSWER ;YES, GO ANSWER IT
- CALL DELAY ;WAIT .1 SECOND
- DEC HL ;ONE LESS COUNT
- LD A,H
- OR L ;IS COUNT ZERO?
- JP NZ,RELOOK ;NO, LOOK SOME MORE
- JP HANGUP2 ;COUNT DONE, WAIT FOR NEW CALL
- ;
- ENDIF ;END OF CALLBACK ROUTINES
- ;
- ;Setup modem
- ;
- ANSWER EQU $+OFFSET
- ;
- IF USRLOG ;COUNT # OF LOGON ATTEMPTS
- LD A,(OLDUSR) ;GET # OF ATTEPMTS
- INC A ;ADD THIS CALL
- ENDIF ;USRLOG
- ;
- IF USRLOG AND DECIMAL
- DAA ;MAKE IT DECIMAL
- ENDIF ;USRLOG AND DECIMAL
- ;
- IF USRLOG
- LD (OLDUSR),A ;SAVE NEW COUNT
- ENDIF ;USRLOG
- ;-----------------------------------------------------
- IF TREVORS
- LD A,BD300 ;LOAD 300 BAUD
- OUT BPORT,A
- LD A,2 ;ensure UART points at cmd register
- OUT CPORT,A
- CALL UDELAY
- OUT CPORT,A
- CALL UDELAY
- OUT CPORT,A
- CALL UDELAY
- LD A,RSTINS ;RESET USART
- OUT CPORT,A
- CALL UDELAY ;USART DELAY
- LD A,MODINS2 ;2 STOP BITS, ETC.
- OUT CPORT,A
- CALL UDELAY ;USART DELAY
- LD A,ONINS ;DSR, ETC.
- OUT CPORT,A
- CALL CARCK ;SEE IF CARRIER IS PRESENT
- JP C,HANGUP2
- ;Test input for baud rate
- IN A,DPORT ;Clear any rubbish
- IN A,DPORT
- CALL PATCH ;PATCH JUMP TABLE
- CALL TSTBAUD ;SEE IF 300 BAUD
- JP Z,WELCOME ;YES, EXIT
- ;
- LD A,BD1200 ;LOAD 1200 BAUD
- OUT BPORT,A
- CALL TSTBAUD ;SEE IF 1200 BAUD
- JP Z,WELCOME ;YES,EXIT
- ;
- LD A,BD110 ;LOAD 110 BAUD
- OUT BPORT,A
- CALL TSTBAUD ;TEST FOR 110 BAUD
- JP Z,WELCOME
- ENDIF ;TREVORS
- ;
- ;;; CALL UNPATCH
- JP ANSWER ;TEST MORE - INVALID BAUD RATE
- ;
- IF TREVORS
- UDELAY EQU $+OFFSET
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- RET
- ENDIF ;TREVORS
- ;
- ;Get the console status when unpatched
- ;
- UCSTS EQU $+OFFSET
- ;
- LD C,CSTS ;IN CPM 1.4, WE HAVE TO GET..
- CALL BDOS ;..THE STATUS FIRST
- OR A
- RET Z
- LD C,CI ;AND THEN THE CHARACTER
- CALL BDOS
- RET
- ;
- ;Following are the USRLOG routines
- ;
- IF USRLOG ;INCLUDE RESET FUNCTIONS
- RESET EQU $+OFFSET ;RESET ALL LOGON COUNTERS
- XOR A
- ENDIF ;USRLOG
- ;
- IF USRLOG AND PWRQD
- LD (OLDUSR),A ;RESET ATTEMPT COUNTER
- ENDIF ;USRLOG AND PWRQD
- ;
- IF USRLOG
- LD (NEWUSR),A ;RESET LOGON COUNTER
- ENDIF ;USRLOG
- ;
- IF USRLOG AND CALLBAK
- LD (NONUSR),A ;RESET VOICE COUNTER
- ENDIF ;USRLOG AND CALLBAK
- ;
- IF USRLOG
- RET
- ENDIF ;USRLOG
- ;
- PRNLOG EQU $+OFFSET
- ;
- IF USRLOG AND PWRQD;PRINT # OF LOGON ATTEMPTS
- LD C,PRINTF
- LD DE,ATMSG
- CALL BDOS
- LD A,(OLDUSR)
- CALL HXOUT
- ENDIF ;USRLOG AND PWRQD
- ;
- IF USRLOG ;PRINT # OF LOGONS
- LD C,PRINTF
- LD DE,SUMSG
- CALL BDOS
- LD A,(NEWUSR)
- CALL HXOUT
- ENDIF ;USRLOG
- ;
- IF USRLOG AND CALLBAK;# OF VOICE CALLS
- LD C,PRINTF
- LD DE,VCMSG
- CALL BDOS
- LD A,(NONUSR)
- CALL HXOUT
- ENDIF ;USRLOG AND CALLBAK
- ;
- IF USRLOG
- JP 0 ;WARM-BOOT BACK TO CP/M
- ENDIF ;USRLOG
- ;
- IF USRLOG AND PWRQD
- ATMSG EQU $+OFFSET
- DEFB LF,CR,'NUMBER OF LOGON ATTEMPTS: $'
- ENDIF ;USRLOG AND PWRQD
- ;
- IF USRLOG
- SUMSG EQU $+OFFSET
- DEFB LF,CR,'NUMBER OF LOGONS: $'
- ENDIF ;USRLOG
- ;
- IF USRLOG AND CALLBAK
- VCMSG EQU $+OFFSET
- DEFB LF,CR,'NUMBER OF VOICE CALLS: $'
- ENDIF ;USRLOG AND CALLBAK
- ;
- IF USRLOG
- HXOUT EQU $+OFFSET
- LD B,A ;SAVE NUMBER
- RRA ;ROTATE RIGHT 4 BITS
- RRA ;TO MAKE AN ASCII DIGIT
- RRA
- RRA
- CALL ONEOUT ;OUTPUT MSH TO CONSOLE
- LD A,B ;GET NUMBER BACK
- ;
- ONEOUT EQU $+OFFSET
- AND 0FH ;GET LSH FOR OUTPUT
- CP 0AH ;CHECK IF ALPHA
- JP C,NOTAL2
- ADD 07H
- ;
- NOTAL2 EQU $+OFFSET
- ADD 30H
- PUSH BC
- LD C,02H
- LD E,A ;OUTPUT THE NUMBER
- CALL BDOS
- POP BC
- RET
- ENDIF ;USRLOG
- ;
- ;Welcome to the system
- ;
- WELCOME EQU $+OFFSET
- ;
- GETNULL EQU $+OFFSET
- CALL ILPRT ;PRINT THIS MSG:
- DEFB CR,LF
- DEFB '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
- CP '0'
- JP C,GETNULL ;BAD, RETRY
- CP '9'+1
- JP NC,GETNULL ;BAD
- SUB '0' ;MAKE BINARY
- LD (NULLS),A ;SAVE COUNT
- ;
- IF TRAPLC
- GETULC EQU $+OFFSET
- CALL ILPRT ;PRINT THIS MSG:
- DEFB CR,LF
- DEFB 'CAN YOUR TERMINAL DISPLAY LOWER CASE? ',0
- LD A,20H ;FORCE CASE CONVERSION FOR NOW
- LD (ULCSW),A
- CALL MINPUT ;GET Y OR NO
- ;;; MOV C,A
- CALL MOUTPUT ;ECHO
- ;;; MOV A,C
- CP 'N'
- JP Z,DONEOPT ;WE'RE ALREADY SET UP FOR NO LWR CASE
- CP 'Y'
- JP NZ,GETULC ;WASN'T Y OR N...GO ASK AGAIN
- XOR A
- LD (ULCSW),A ;SET FLAG FOR NO CONVERSION
- ;
- DONEOPT EQU $+OFFSET
- ENDIF ;TRAPLC
- ;
- CALL ILPRT
- DEFB CR,LF,0
- ;Print the welcome file
- LD HL,WELFILN ;SOURCE
- LD DE,FCB ;DESTINATION
- LD B,13 ;LENGTH
- CALL MOVE ;MOVE THE NAME
- ;Set DMA address to 80h
- LD DE,80H
- LD C,STDMA
- CALL BDOS
- ;
- ;Open the welcome file
- LD DE,FCB
- LD C,OPEN
- CALL BDOS
- ;Did it exist?
- INC A ;A=> 0 MEANS "NO"
- JP Z,PASSINT ;NO WELCOME FILE
- ;Got a file, type it
- XOR A ;GET 0
- LD (FCBRNO),A ;ZERO RECORD #
- LD HL,100H ;GET INITIAL BUFF POINTER
- ;
- ;Type the welcome file
- WELTYLP EQU $+OFFSET
- CALL RDBYTE ;GET A BYTE
- CP 1AH ;EOF?
- JP Z,PASSINT ;YES, DONE
- ;;; MOV C,A ;SETUP FOR TYPE
- CALL MOUTPUT ;TYPE THE CHAR
- CALL MSTAT ;CHECK FOR..
- OR A ;CHAR TYPED?
- JP Z,WELTYLP ;..NO, LOOP
- CALL MINPUT ;..YES, GET CHAR
- CP 'C'-40H ;CTL-C?
- JP NZ,WELTYLP ;..NO, LOOP UNTIL EOF
- ;
- ;Get the password
- ;
- PASSINT EQU $+OFFSET
- ;
- IF PWRQD
- LD D,5 ;5 TRIES AT PASSWORD
- ;
- PASSINP EQU $+OFFSET
- CALL ILPRT
- DEFB CR,LF,'ENTER PASSWORD: ',0
- LD HL,PASSWD ;POINT TO PASSWORD
- LD E,0 ;NO MISSED LETTERS
- IN A,DPORT ;CLEAR OUT GARBAGE
- ;
- PWMLP EQU $+OFFSET
- CALL MINPUT ;GET A CHAR
- CP 'U'-40H ;CTL-U?
- JP Z,PASSINP ;YES, RE-GET IT
- CP 60H ;LOWER CASE?
- JP C,NOTLC ;NO,
- AND 5FH ;MAKE UPPER CASE ALPHA
- ;
- NOTLC EQU $+OFFSET
- CP (HL) ;MATCH PASSWORD?
- JP Z,PWMAT ;..YES
- LD E,1 ;..NO, SHOW MISS
- CP CR ;C/R?
- JP NZ,PWMLP ;..NO, WAIT FOR C/R
- ;
- ;Password didn't match
- ;
- PWNMAT EQU $+OFFSET
- CALL ILPRT
- DEFB '++INCORRECT++',CR,LF,0
- DEC D ;MORE TRIES?
- JP NZ,PASSINP ;YES
- JP BADPASS ;NO, GO HANG UP
- ;
- ;Character matched in password
- ;
- PWMAT EQU $+OFFSET
- INC HL ;TO NEXT CHAR
- CP CR ;END?
- JP NZ,PWMLP ;..NO, LOOP
- ;End of password. Any missed chars?
- LD A,E ;GET FLAG
- OR A
- JP NZ,PWNMAT ;NOT RIGHT
- ;Password correct
- ENDIF ;PWRQD
- ;
- NOPASS EQU $+OFFSET
- ;
- IF USRLOG ;COUNT # OF SUCCESSFUL LOGONS
- LD A,(NEWUSR) ;GET LAST VALUE
- INC A ;INCREMENT IT
- ENDIF ;USRLOG
- ;
- IF USRLOG AND DECIMAL
- DAA ;MAKE IT DECIMAL
- ENDIF ;USRLOG AND DECIMAL
- ;
- IF USRLOG
- LD (NEWUSR),A ;SAVE NEW VALUE
- ENDIF ;USRLOG
- ;
- ;; CALL ILPRT
- ;; DB CR,LF,'Booting CDOS.. ',0DH,0AH,0 ;PUT BOOT-UP MSG HERE
- ;
- IF COMFILE
- LD A,(OPTION)
- CP 'A' ;SYSOP CAN BYPASS COM FILE BY..
- JP Z,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
- LD A,'@' ;Tell RBBS that this is a
- LD (5DH),A ; new caller
- JP 100H ;EVERYONE ELSE GETS COM FILE
- ENDIF ;COMFILE
- ;
- IF NOT COMFILE
- JP 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
- CP CR ;IF A CARRIAGE RETURN...
- RET Z ;.. RETURN
- CP LF ;IF A LINEFEED...
- RET ;RET ZERO FLAG, ELSE NOT ZERO
- ;
- ;Loss of connection test
- ;
- CARCK EQU $+OFFSET
- ;
- ;;; IF SUPERB
- ;
- ;Racal-Vadic modem automatically hangs up phone 1 second
- ;after carrier loss.
- ;
- ;;; IN SPORT ;GET STATUS
- ;;; ANI DSR ;CHECK IF CARRIER ON
- ;;; JNZ CARCK2 ;YES, CONTINUE ON
- ;;; STC ;SET CARRY BIT FOR NO CARRIER
- ;;; RET
- ;;; ENDIF ;SUPERB
- ;
- IF TREVORS
- ;
- ;; IN SPORT ;GET STATUS
- ;; ANI DSR ;CHECK IF CARRIER ON
- ;; JNZ CARCK2 ;YES, CONTINUE ON
- ;******************always have carrier
- ;; STC ;SET CARRY BIT FOR NO CARRIER
- ;; RET
- ENDIF ;TREVORS
- ;
- ;Now test drive #'s and (if CP/M 2.x) user #'s to
- ;insure that maximums are not exceeded.
- ;
- CARCK2 EQU $+OFFSET
- LD A,(4) ;CHECK DISK/USER #
- AND 0FH ;ISOLATE DRIVE
- CP MAXDRV ;VALID DRIVE?
- JP C,CARCK3 ;YES, SKIP THIS JUNK
- LD A,(4) ;GET WHOLE LOGIN BYTE
- AND 0F0H ;RETAIN USER # & FORCE DRIVE TO A
- LD (4),A ;UPDATE LOGIN BYTE
- CALL ILPRT ;TELL USER WHAT HE DID
- DEFB 'Invalid drive - returning to A:',0
- JP 0 ;WARM BOOT
- ;
- CARCK3 EQU $+OFFSET
- ;
- CARCK4 EQU $+OFFSET
- OR 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
- LD DE,VCOLDBT ;POINT TO SAVE LOCATION
- LD 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
- EX DE,HL ;MOVE TO DE
- LD HL,NEWJTBL ;POINT TO NEW
- CALL MOVE ;MOVE IT
- ;
- IF CDOS ;we must copy and replace SDVT console entries
- ;
- LD C,81H
- CALL BDOS ;Get user register pointer
- LD HL,3
- ADD HL,BC ;HL now pointing to SDVT entry
- LD E,(HL)
- INC HL
- LD D,(HL) ;Have SDVT vector in DE
- EX DE,HL ;in HL
- LD E,(HL)
- INC HL
- LD D,(HL) ;Have CON$TABLE in DE
- EX DE,HL ;in HL
- LD (CON$TABLE),HL ;save it in RAM
- LD DE,DOSSDVT ;where we will save it
- LD B,10 ;10 bytes to move
- CALL MOVE ;(hl) to (de)
- ;
- LD HL,(CON$TABLE) ;Now overlay with our SDVT
- EX DE,HL
- LD HL,SDVT ;our SDVT points to modem routines
- LD B,10
- CALL MOVE
- ;
- ; Now patch the vectors into our CONIN etc
- LD HL,(DOSCSTAT)
- LD (CSTAT),HL
- LD HL,(DOSCIND)
- LD (CIND),HL
- LD HL,(DOSCOUTD)
- LD (COUTD),HL
- IF NOT PRINTER
- ; Now replace printer table LINIT and LOUT entry
- LD C,81H
- CALL BDOS ;Get user register pointer
- LD HL,3 ;calculate the SDVT entry
- ADD HL,BC
- LD E,(HL)
- INC HL
- LD D,(HL) ;Have SDVT table addr in DE
- LD HL,8 ;get LIST table addr
- ADD HL,DE
- LD E,(HL)
- INC HL
- LD D,(HL) ;DE points at LIST table
- INC DE
- INC DE
- EX DE,HL
- LD (LRDY$ADDR),HL ;where we will save it
- LD E,(HL)
- INC HL
- LD D,(HL) ;Have original LRDY vector in DE
- EX DE,HL ;inHL
- LD (SAVE$LRDY),HL
- EX DE,HL ;get back table ptr
- INC HL
- LD E,(HL)
- INC HL
- LD D,(HL) ;have LOUT vec in DE
- EX DE,HL
- LD (SAVE$LOUT),HL
- CALL DISABLE$PRINTER
- ENDIF ;NOT PRINTER
- ENDIF ;CDOS
- RET
- ;
- ;Now replace the vectors if required
- IF NOT PRINTER ;we will patch out table entries
- DISABLE$PRINTER EQU $+OFFSET
- LD HL,(LRDY$ADDR)
- LD DE,MSTAT1 ;Replace vector
- LD (HL),E
- INC HL
- LD (HL),D
- ;
- INC HL ;now replace LOUT
- LD DE,DUMMY ;merely RETurn
- LD (HL),E
- INC HL
- LD (HL),D
- RET
- ;
- ENABLE$PRINTER EQU $+OFFSET
- ;Now return the vectors if required
- LD HL,(SAVE$LRDY) ;get original vector
- EX DE,HL ;into DE
- LD HL,(LRDY$ADDR)
- LD (HL),E
- INC HL
- LD (HL),D
- ;
- INC HL ;now replace LOUT
- PUSH HL
- LD HL,(SAVE$LOUT)
- EX DE,HL
- POP HL
- LD (HL),E
- INC HL
- LD (HL),D
- RET
- ENDIF ;NOT PRINTER
- UNPATCH EQU $+OFFSET
- CALL TBLADDR ;HL=CP/M'S JMP TABLE
- EX DE,HL ;MOVE TO DE
- LD HL,VCOLDBT ;GET SAVED TABLE
- CALL MOVE ;MOVE ORIG BACK
- ;
- IF CDOS ;must also move SDVT back
- LD HL,(CON$TABLE)
- EX DE,HL ;DE now holds addr of CDOS's SDVT
- LD HL,DOSSDVT ;HL has the saved SDVT addr
- LD B,10 ;length of SDVT
- CALL MOVE ;restore old SDVT
- IF NOT PRINTER
- CALL ENABLE$PRINTER
- ENDIF ;NOT PRINTER
- ENDIF ;CDOS
- RET
- ;
- ;Calculate HL=CP/M's jump table, B=length
- ;
- TBLADDR EQU $+OFFSET
- LD HL,(1) ;GET BIOS POINTER
- DEC HL ;..SKIP
- DEC HL ;..TO
- DEC HL ;..COLD BOOT
- ;
- IF NOT CDOS
- IF NOT PRINTER
- LD B,18 ;BYTES TO MOVE
- ENDIF
- ;
- IF PRINTER ;RETAIN LIST DEVICE?
- LD B,15 ;DON'T MOVE LISTER JUMP
- ENDIF
- ;
- ENDIF ;NOT CDOS
- IF CDOS
- LD B,6 ;only copy the two boot vectors
- ENDIF ;CDOS
- RET
- ;
- ;Move (HL) to (DE), length in (B)
- ;
- MOVE EQU $+OFFSET
- LD A,(HL) ;GET A BYTE
- LD (DE),A ;PUT AT NEW HOME
- INC DE ;BUMP POINTERS
- INC HL
- DEC B ;DEC BYTE COUNT
- JP NZ,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
- RET NC ;ALL OK
- ;
- ;Carrier is lost. Type message so local console shows the reason
- ;
- BADPASS EQU $+OFFSET ;COME HERE ON BAD PASSWORD
- LD A,1 ;SHOW CARRIER LOST SO
- LD (LOSTFLG),A ;..WE WON'T CK AGAIN
- LD SP,STACK ;ENSURE VALID STACK
- CALL ILPRT
- DEFB CR,LF
- DEFB '++CARRIER LOST++'
- DEFB CR,LF,' ',0
- CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL
- XOR A ;CLEAR OUT CARRIER..
- LD (LOSTFLG),A ;..LOST FLAG
- JP HANGUP
- ;
- ;Readbyte routine - used to read the welcome file
- ;
- RDBYTE EQU $+OFFSET
- LD A,H ;TIME TO READ?
- OR A ;..IF AT 100H
- JP Z,NORD ;NO READ REQ'D
- ;Have to read a sector
- LD DE,FCB
- LD C,READ
- CALL BDOS
- OR A ;OK?
- LD A,1AH ;FAKE UP EOF
- RET NZ ;RET EOF IF BAD
- LD HL,80H
- ;
- NORD EQU $+OFFSET
- LD A,(HL) ;GET CHAR
- INC HL ;TO NEXT
- RET
- ;
- ;Keyboard/modem status test routine
- ;
- MSTAT EQU $+OFFSET
- ;
- IF DUAL$IO ;WANT LOCAL CONSOLE?
- CALL CONSTAT ;GET LOCAL STATUS
- OR A
- RET NZ ;RET IF LOCAL CHAR
- ENDIF ;DUAL$IO
- ;
- IF TREVORS
- IN A,SPORT ;GET STATUS
- AND RCVRDY ;GOT A CHARACTER
- RET Z ;RETURN IF NOT
- ;; IN SPORT ;GET STATUS
- ;; ANI TOERR ;CHECK FOR FRAMING AND OVERRUN ERRORS
- ;; JZ MSTAT1 ;NO ERRORS
- ;; MVI A,ONINS ;RESET ERROR FLAGS
- ;; OUT CPORT
- ;; XRA A ;RETURN FALSE
- ;; RET
- ENDIF ;TREVORS
- ;
- MSTAT1 EQU $+OFFSET
- LD A,0FFH ;SHOW READY
- OR A
- RET
- ;
- ;Modem input function, checks local console first
- ;
- MINPUT EQU $+OFFSET
- ;
- IF TIMEOUT
- PUSH HL
- LD HL,TOVALUE*MINUTES;INITIALIZE TIMEOUT COUNTER
- LD (TOCNT),HL
- POP HL
- ENDIF ;TIMEOUT
- ;
- MINPUT1 EQU $+OFFSET
- LD A,(LOSTFLG) ;KNOWN LOSS..
- OR A ;..OF CARRIER?
- CALL Z,CHECK ;CARRIER STILL ON?
- CALL MSTAT ;ANYTHING?
- OR A
- ;
- IF NOT TIMEOUT
- JP Z,MINPUT ;LOOP TILL CHAR RCD
- ENDIF ;NOT TIMEOUT
- ;
- IF TIMEOUT
- JP NZ,MINPUT2
- CALL KDELAY ;KILL 50 MS
- PUSH HL
- LD HL,(TOCNT) ;KNOCK DOWN TIMEOUT COUNTER
- DEC HL
- LD (TOCNT),HL
- LD A,H
- OR L
- POP HL
- JP NZ,MINPUT1 ;STILL TIME LEFT..KEEP TRYING
- CALL ILPRT
- DEFB '++INPUT TIMED OUT++',7,7,0
- JP NOSLASH
- ENDIF ;TIMEOUT
- ;
- MINPUT2 EQU $+OFFSET
- ;
- IF DUAL$IO ;BOTH LOCAL AND REMOTE
- CALL CONSTAT ;CHECK LOCAL CONSOLE
- OR A ;CHAR?
- JP NZ,CONIN ;..YES, READ IT, RET.
- ENDIF
- ;
- ;Local console wasn't ready, so read modem
- ;
- IN A,DPORT ;GET DATA BYTE
- AND 7FH ;DELETE PARITY
- JP Z,MINPUT ;IGNORE NULLS
- ;
- IF HARDLOG
- CP 20H
- JP NC,MINPUT3
- CP CR
- JP NZ,NOLOG
- ;
- MINPUT3 EQU $+OFFSET
- CALL LISTOUT ;ECHO ON PRINTER
- CP CR
- JP NZ,NOLOG ;CR NEEDS LINEFEED
- LD A,LF
- CALL LISTOUT ;SO SEND IT
- LD A,CR ;GET BACK CR
- ENDIF ;END OF HARDLOG
- ;
- NOLOG EQU $+OFFSET
- ;
- CP 3 ;IS IT CONTROL-C?
- RET NZ ;NO, PASS IT THRU
- LD A,(0) ;SEE IF WARM BOOT DISABLED
- CP 0C3H ;JMP MEANS WARM BOOT OK
- LD A,3 ;SO RETURN CONTROL-C
- RET Z
- XOR A ;ELSE CONVERT TO NULL
- RET
- ;
- ;Modem output function
- ;
- MOUTPUT EQU $+OFFSET
- LD C,A ;char is passed in A for CDOS
- CMOUTPUT EQU $+OFFSET ;CP/M passes it in C
- ;
- ;If we already know carrier is lost, don't check
- ;for it again or loop trying to output.
- LD A,(LOSTFLG) ;KNOWN LOSS OF CARRIER?
- OR A
- JP NZ,SILENT ;AVOID LOOP IN CASE CARRIER LOST
- CALL CHECK ;CARRIER STILL ON?
- ;
- IF TREVORS
- IN A,SPORT ;GET MODEM STATUS
- AND TRNRDY ;TRANSMIT BUFFER EMPTY?
- ENDIF ;TREVORS
- ;
- JP Z,CMOUTPUT ;LOOP IF NOT READY
- ;
- LD A,C ;GET CHAR
- AND 7FH ;STRIP PARITY BIT
- ;
- IF TRAPLC
- CP 60H ;CHECK FOR LOWER CASE
- JP C,MOUTP2 ;SKIP IF NOT LC
- CP 7FH ;CHECK FOR RUBOUT
- JP Z,MOUTP2
- PUSH HL
- LD HL,ULCSW ;SUBTRACT EITHER 20H OR 0
- SUB (HL)
- POP HL
- LD C,A ;FORCE ON LOCAL AS WELL AS REMOTE
- ;
- MOUTP2 EQU $+OFFSET
- ENDIF ;TRAPLC
- ;
- OUT DPORT,A ;OUTPUT TO MODEM
- ;
- SILENT EQU $+OFFSET
- ;
- IF DUAL$IO ;TO LOCAL ALSO?
- LD A,C ;for CDOS
- PUSH AF ;SAVE CHAR
- CALL CONOUT ;SEND TO REGULAR BIOS char in A or C
- POP AF ;GET CHAR AGAIN
- ENDIF ;DUAL$IO
- ;
- ;Check for nulls
- CP LF ;TIME FOR NULLS?
- RET NZ ;NO, RETURN
- ;Send nulls if required
- LD A,(NULLS) ;GET COUNT
- OR A ;ANY?
- RET Z ;..NO
- PUSH BC
- LD B,A ;SAVE COUNT
- LD A,0 ;0 IS A NULL
- ;
- NULLP EQU $+OFFSET
- CALL MOUTPUT ;TYPE A NULL
- DEC B ;MORE?
- JP NZ,NULLP ;..YES, LOOP
- POP BC
- LD 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
- JP VWARMBT ;++++++++++++++;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ;Inline print routine
- ;
- ILPRT EQU $+OFFSET
- EX (SP),HL ;SAVE HL, GET MSG
- PUSH BC ;SAVE BC REGS
- ;
- ILPLP EQU $+OFFSET
- LD C,(HL) ;GET CHAR
- CALL CMOUTPUT ;OUTPUT IT
- INC HL ;POINT TO NEXT
- LD A,(HL) ;TEST
- OR A ;..FOR END
- JP NZ,ILPLP
- POP BC ;RESTORE BC REGS
- EX (SP),HL ;RESTORE HL, RET ADDR
- RET ;RET PAST MSG
- ;
- IF PWRQD ;KEEP PASSWORD HERE
- ;Access password (ends in carriage return)
- ;
- PASSWD EQU $+OFFSET
- DEFB 'HELLO' ;THE PASSWORD ITSELF
- DEFB CR ;END OF PASSWORD
- ;Allow room for bigger password to be patched in
- DEFB 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
- XOR A ;INITIALIZE FCB
- LD (COMFCB),A
- LD HL,COMFCB+12
- LD B,21
- ;
- ZLOOP EQU $+OFFSET
- LD (HL),0
- INC HL
- DEC B
- JP NZ,ZLOOP
- ;
- LD C,OPEN ;NOW OPEN THE FILE
- LD DE,COMFCB
- CALL BDOS
- INC A ;SHOULD BE NON-ZERO
- JP Z,ABORT ;NO FILE, ABORT
- ;
- ;Now load the file
- LD HL,(6) ;GET TOP OF MEMORY
- LD DE,-80H ;RECORD LOADS CAN'T START..
- ADD HL,DE ;..ABOVE (BDOS) - 80H
- PUSH HL ;SAVE ON STACK
- ;
- LD DE,80H ;TPA-80H
- LD BC,0 ;KEEP A RECORD COUNTER
- PUSH BC ;SAVE COUNTER
- PUSH DE ;AND LOAD ADDRESS
- ;
- GLOOP EQU $+OFFSET
- POP DE ;GET TPA ADRS
- LD HL,80H ;POINT TO NXT ADRS TO READ TO
- ADD HL,DE ;HL HAS THE ADDRESS
- POP BC ;INCREMENT THE COUNTER
- ;Check for load past top-of-memory
- POP DE ;GET (TOP-OF-MEMORY)
- PUSH DE ;RE-SAVE FOR NEXT TIME
- LD A,E ;SUBTRACT: (TOP) - (ADRS)
- SUB L
- LD A,D ;ONLY THE CARRY NEEDED
- SBC H
- JP NC,SIZEOK ;CY= BETTER MOVCPM
- CALL ERRXIT ;SO TELL THE STORY
- DEFB 'Out of memory','$'
- ;
- SIZEOK EQU $+OFFSET
- INC BC
- PUSH BC
- PUSH HL ;SAVE TPA ADRS
- EX DE,HL ;ALIGN REGISTERS
- LD C,STDMA ;TELL BDOS WHERE TO PUT RECORD
- CALL BDOS
- LD DE,COMFCB ;NOW READ THE RECORD
- LD C,READ
- CALL BDOS
- OR A
- JP Z,GLOOP ;A=0 IF MORE TO READ
- POP BC ;UNJUNK STACK
- POP BC ;THIS IS OUR COUNTER
- POP HL ;MORE JUNK ON STACK
- LD A,B ;CHECK FOR ZERO
- OR C
- JP Z,ABORT ;WE SHOULD HAVE READ SOMETHING
- LD DE,80H ;WE DID, RESET DMA TO 80H
- LD C,STDMA
- CALL BDOS
- CALL LOADOK ;PRINT THIS MSG TO CONSOLE:
- DEFB 'RBBS loaded',CR,LF,'$'
- ;
- LOADOK EQU $+OFFSET
- POP DE
- LD A,(OPTION) ;SEE IF THIS WAS "BYE /C"
- CP 'C' ;IF IT WAS THEN..
- RET Z ;..DON'T PRINT MESSAGE
- LD C,PRINTF
- CALL BDOS
- RET
- ;
- ABORT EQU $+OFFSET
- CALL ERRXIT
- DEFB CR,LF
- DEFB 'Open err','$'
- ;
- ERRXIT EQU $+OFFSET
- POP DE
- LD C,PRINTF
- CALL BDOS ;PRINT THE ABORT MSG
- JP 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 BC
- PUSH DE
- PUSH HL
- CSTAT EQU $+1+OFFSET
- CALL VCONSTAT
- POP HL
- POP DE
- POP BC
- RET
- ;
- CONIN EQU $+OFFSET
- PUSH BC
- PUSH DE
- PUSH HL
- CIND EQU $+1+OFFSET
- CALL VCONIN
- ;
- IF FKEYS
- CALL CKFUNC
- ENDIF ;FKEYS
- ;
- POP HL
- POP DE
- POP BC
- RET
- ;
- CKFUNC EQU $+OFFSET
- ;
- IF FKEYS
- CP SYSDKEY
- JP Z,SYSDOWN ;TELL CALLER TO LEAVE
- CP TWITKEY
- JP Z,GOODBY ;MAKE CALLER LEAVE
- ;; CP MSGKEY
- ;; RET NZ
- ;; CALL ILPRT ;SEND CALLER A MESSAGE
- ;; DEFB 'MESSAGE FROM OPERATOR:',0
- ;; LD A,' ' ;SOMETHING TO RETURN WITH
- RET
- ;
- SYSDOWN EQU $+OFFSET
- CALL ILPRT
- DEFB 'SYSTEM DOWN IN'
- DEFB ' 5 MINUTES....',0
- LD A,' '
- RET
- ENDIF ;FKEYS
- ;
- CONOUT EQU $+OFFSET
- PUSH BC
- PUSH DE
- PUSH HL
- ; MOV A,C ;Get char in A for CDOS
- PUSH AF
- COUTD EQU $+1+OFFSET
- CALL VCONOUT
- POP AF
- POP HL
- POP DE
- POP BC
- RET
- ;
- LISTOUT EQU $+OFFSET
- PUSH BC
- PUSH DE
- PUSH HL
- PUSH AF
- IF NOT PRINTER
- CALL ENABLE$PRINTER
- ENDIF ;NOT PRINTER
- POP AF
- PUSH AF
- LD A,C ;char needed in A
- LOUT EQU $+1+OFFSET
- CALL VLISTOUT
- IF NOT PRINTER
- CALL DISABLE$PRINTER
- ENDIF ;NOT PRINTER
- POP AF
- POP HL
- POP DE
- POP BC
- MINIT EQU $+OFFSET ;merely a return opcode
- RET
- ;
- ;This is the JMP table which is copied on top
- ;of the one pointed to by location 1 in CP/M
- ;If CDOS is in use only the first 2 vectors are replaced
- NEWJTBL EQU $+OFFSET
- JP MBOOT ;COLD BOOT
- JP MBOOT ;WARM BOOT
- JP MSTAT ;MODEM STATUS TEST
- JP MINPUT ;MODEM INPUT ROUTINE
- JP CMOUTPUT ;MODEM OUTPUT ROUTINE
- DUMMY EQU $+OFFSET
- RET ;DUMMY LIST DEVICE
- NOP
- NOP
- ;
- WELFILN EQU $+OFFSET
- DEFB 0,'WELCOME ',0
- ;Welcome file name ^^^^^^^^^^^ (must be 11 characters)
- ;
- NULLS EQU $+OFFSET
- DEFB 5
- ;
- COMFCB EQU $+OFFSET
- DEFB 0,'RBBS COM'
- ;COM file name ^^^^^^^^^^^ (must be 11 characters)
- ;
- IF NOT CDOS
- PEND EQU $+OFFSET ;END OF RELOCATED CODE
- ENDIF ;NOT CDOS
- ;
- ;These areas are not initialized for CP/M only
- ;
- DEFS 21 ;REST OF COM FCB
- ;
- IF CDOS
- ; This is the SDVT table which is copied on top
- ; of the one in CDOS or IOS
- SDVT EQU $+OFFSET ;10 BYTES LONG
- DEFW MINIT ;returns OK immediately
- DEFW MSTAT
- DEFW MINPUT
- DEFW MSTAT1 ;wants status,gets READY
- DEFW MOUTPUT
- ;
- PEND EQU $+OFFSET ;END OF RELOCATED CODE
- ;
- DEFS 2 ;to allow for movement errors
- CON$TABLE EQU $+OFFSET
- DEFS 2 ;Store DOSSDVT addr here
- LRDY$ADDR EQU $+OFFSET
- DEFS 2
- SAVE$LRDY EQU $+OFFSET
- DEFS 2
- SAVE$LOUT EQU $+OFFSET
- DEFS 2
- ;
- ;Save the original SDVT here
- DOSSDVT EQU $+OFFSET
- DEFS 2
- DOSCSTAT EQU $+OFFSET
- DEFS 2
- DOSCIND EQU $+OFFSET
- DEFS 2
- DEFS 2
- DOSCOUTD EQU $+OFFSET
- DEFS 2
- ;
- ENDIF ;CDOS
- ULCSW EQU $+OFFSET
- DEFS 1
- ;
- OPTION EQU $+OFFSET
- DEFS 1
- ;
- TOCNT EQU $+OFFSET
- DEFS 2
- ;
- ;Byte to keep track of lost carrier when
- ;typing "++CARRIER LOST++" so we don't loop
- ;
- LOSTFLG EQU $+OFFSET
- DEFS 1
- ;
- ;Save the CP/M jump table here
- ;
- VCOLDBT EQU $+OFFSET
- DEFS 3
- ;
- VWARMBT EQU $+OFFSET
- DEFS 3
- ;
- VCONSTAT EQU $+OFFSET
- DEFS 3
- ;
- VCONIN EQU $+OFFSET
- DEFS 3
- ;
- VCONOUT EQU $+OFFSET
- DEFS 3
- ;
- VLISTOUT EQU $+OFFSET
- DEFS 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
- DEFS 1
- ;
- NEWUSR EQU $+OFFSET
- DEFS 1
- ;
- NONUSR EQU $+OFFSET
- DEFS 1
- ENDIF ;USRLOG
- ;
- ;
- DEFS 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
-