home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG040.ARK
/
PMMIBYE3.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
17KB
|
721 lines
;V3.0 (Revised 9/24/79)
;
;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
;
;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.
;
;------------------------------------------------
;CHANGE THE FOLLOWING EQUATE TO AN AREA IN YOUR
;HI MEMORY WHERE THIS PROGRAM MAY PATCH ITSELF IN.
;APPROX MEMORY REQUIREMENTS: 800 BYTES.
;
DEST EQU 0F000H ;RUNNING LOCATION OF CODE
;
;CHANGE THE FOLLOWING TO YOUR LOCAL CONSOLE KEYBOARD
;DATA PORT NUMBER.
;
CONDATA EQU 02H ;LOCAL CONSOLE INPUT DATA PORT
;
;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
; 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, 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
;
PRINTER EQU FALSE ;WANT TO RETAIN LIST DEVICE?
DUAL$IO EQU TRUE ;WANT CONSOLE & MODEM?
;
; 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 7FH ;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
;
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
PCHL ;JUMP TO "START"
;
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
;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
CPI 'A' ;ANSWER?
JZ ANSWER
;NO OPTION, OR INVALID ONE
NOSLASH EQU $+OFFSET
CALL CARCK ;SIGNED OFF W/THIS PROG?
JC HANGUP ;NOBODY THERE
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
;
;CLEAR DTR CAUSING PHONE TO HANG UP
MVI A,P3CLEAR ;CLEAR..
OUT CPORT ;..DTR
;
; 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.
IN CONDATA ;CHECK LOCAL KBD
ANI 7FH ;STRIP PARITY BIT
CPI 'C'-40H ;CONTROL C?
JZ 0 ;YES, --EXIT-- TO CP/M
;
RINGW2 EQU $+OFFSET
IN RPORT ;GET THE STATUS
ANI P2RDET ;RINGING?
JNZ RINGWT ;NO, WAIT
;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
;
;PHONE IS RINGING
;
; 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!
;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
JMP HANGUP
;
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 HANGUP
;
;SETUP MODEM
ANSWER EQU $+OFFSET
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
IN CONDATA ;CLEAR LOCAL KBD PORT
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 HANGUP ;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
CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL
JMP ANSWER ;TEST MORE - INVALID BAUD RATE
;
;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
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
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
CALL ILPRT
DB CR,LF,'BOOTING CP/M...',0
JMP 0 ;GO TO CP/M
;
;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
RZ ;RET IF CARRIER ON
;LOOP UNTIL EITHER CONNECTION LOST, OR
;CARRIER RETURNS
JMP CARCK
;
; .1 SEC DELAY ROUTINE
;
DELAY EQU $+OFFSET
MVI A,TRATE ;.1 SEC COUNT
OUT RPORT ;TO RATE PORT
DLYHI EQU $+OFFSET
IN RPORT ;GET PORT W/TIMER BIT
ANI P2TMPUL ;HI?
JNZ DLYHI ;..LOOP UNTIL LOW
;END OF HI PULSE, WAIT FOR END OF LOW
DLYLO EQU $+OFFSET
IN RPORT ;GET TIMER PULSE
ANI P2TMPUL ;LOW?
JZ DLYLO ;YES, LOOP
RET
;
;PATCH IN THE NEW JMP TABLE (SAVING THE OLD)
;
PATCH EQU $+OFFSET
CALL TBLADDR ;CALC HL= CP/M JMP TABLE
LXI D,CONSTAT ;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,CONSTAT ;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
INX H ;..SKIP
INX H ;..TO
INX H ;..CONSOLE STAT
;
IF NOT PRINTER
MVI B,12 ;BYTES TO MOVE
ENDIF
;
IF PRINTER ;RETAIN LIST DEVICE?
MVI B,9 ;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 STATUS, AND 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
MVI A,0FFH ;SHOW READY
RET
;
;MODEM INPUT FUNCTION, CHECKS LOCAL CONSOLE FIRST
;
MINPUT EQU $+OFFSET
LDA LOSTFLG ;KNOWN LOSS..
ORA A ;..OF CARRIER?
CZ CHECK ;CARRIER STILL ON?
;
CALL MSTAT ;ANYTHING?
ORA A
JZ MINPUT ;LOOP TILL CHAR RCD
;GOT CHAR - SEE WHICH PORT
;
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
RET
;
;MODEM OUTPUT ROUTINE. OUTPUTS TO MODEM,
;THEN TO LOCAL CONSOLE
;
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
MOV A,C ;GET CHAR
OUT DPORT ;OUTPUT TO MODEM
;
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
;
; 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
;
;ACCESS PASSWORD (ENDS IN C/R)
;
PASSWD EQU $+OFFSET
DB 'HOUGH' ;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
;
; 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 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
;
PEND EQU $+OFFSET ;END OF RELOCATED CODE
;
;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
;
CONSTAT EQU $+OFFSET
DS 3
CONIN EQU $+OFFSET
DS 3
CONOUT EQU $+OFFSET
DS 3
LISTOUT EQU $+OFFSET
DS 3
;
DS 40
STACK EQU $+OFFSET ;LOCAL STACK
;
WRCON EQU 2
OPEN EQU 15
READ EQU 20
STDMA EQU 26
FCB EQU 5CH
FCBRNO EQU FCB+32
;
END