home *** CD-ROM | disk | FTP | other *** search
- ; PLINK.ASM
- ; (latest version SEPT 25 1980)
- ;
- ; PLINK - SUPPORT COMMUNICATIONS LINK WITH CYBER
- ;
- ;PLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO
- ;ESTABLISH A COMMUNICATIONS LINK WITH A REMOTE COMPUTER
- ;
- ; ORIGINAL BY L.E. HUGHES EDCAM JULY, 1977
- ;
- ; This version by Keith Petersen, W8SDZ.
- ; WITH HEATH EQUATES ADDED BY TOM JORGENSON
- ;
- ; TRS-80 MODEL 1 mods by Steve Vinokuroff, Vanc CBBS
- ; Optional Triger characters by Steve Vinokuroff
- ; TRS-80 mods by Dennis Breckenridge, Burnaby CBBS
- ; D.C.Hayes mods by Bruce Ratoff, Iselin NJ Remote CP/M
- ;
- ;This program currently supports the following modems
- ; or computers via conditional assembly.
- ;
- ; 1. PMMI modem
- ; 2. ANY serial i/o board (TUART INCLUDED)
- ; 3. TRS-80 model 1
- ; 4. TRS-80 model 2
- ; 5. HEATH H8 WITH 8251 UART AT PORT 330Q
- ; 6. D.C.Hayes 80-103A or Micromodem 100
- ;
- ;
- ;-->NOTE: IF ASSEMBLED AS WRITTEN WILL WORK WITH D.C.Hayes 80-103A
- ; OR MICROMODEM 100 AT PORT 90H
- ;
- ;PLINK CURRENTLY SUPPORTS TWO WAY TRANSFER OF TEXT FILES
- ;BETWEEN THE CP/M DISK AND THE REMOTE COMPUTER. THE FOLLOWING
- ;CONTROL CODES MAY BE INITIATED FROM THE CONSOLE KEYBOARD:
- ;
- ; ****************************************************
- ; * COMMANDS: *
- ; * *
- ; * CONTROL E EXIT PLINK TO CP/M WARM BOOT *
- ; * CONTROL T TRANSMIT ASCII FILE TO MODEM. *
- ; * ASKS FOR DRIVE AND FILENAME.TYP *
- ; * CONTROL C ABORT FILE SEND TO MODEM *
- ; * CONTROL Y SAVE INCOMING ASCII IN RAM BUFFER *
- ; * FOR LATER TRANSFER TO DISK *
- ; * CONTROL Q WRITE RAM BUFFER TO DISK - ASKS *
- ; * FOR DRIVE AND FILENAME.TYP *
- ; * DELETE BACKSPACE WHEN IN COMMAND MODE *
- ; * ASKING FOR FILENAME *
- ; * CONTROL U ABORT CURRENT LINE WHEN IN COMMAND *
- ; * MODE ASKING FOR FILENAME *
- ; * *
- ; * (NOTE: ALL OTHER CONTROL CODES ARE PASSED TO *
- ; * MODEM OUTPUT) *
- ; ****************************************************
- ;
- ;
- ;CONDITIONAL ASSEMBLY SWITCHES <<-- SET FOR YOUR SYSTEM
- ;
- TUART SET 0 ;CROMEMCO TUART I/O BOARD
- PMMI EQU 0 ;PUT A 1 HERE IF YOU HAVE A PMMI
- DCH EQU 1 ;PUT A 1 HERE IF YOU HAVE A D.C.HAYES
- TRS1 EQU 0 ;PUT A 1 HERE IF YOU HAVE TRS80-MOD1
- TRSPT EQU 0 ;PUT 1 HERE IF YOU HAVE TRS80-MOD2
- ;USING PICKLES & TROUT CP/M 2.X
- H84 EQU 0 ;PUT 1 HERE IF YOU HAVE H8/H8-4
- IF H84
- TUART SET 1
- ENDIF
- ;
- INIT$REQUIRED EQU 1 ;PUT 1 HERE IF INITIALIZATION NEEDED
- ;
- IF TRS1 OR PMMI OR TUART OR DCH
- PORT EQU 1
- ENDIF
- ;
- IF TRSPT
- PORT EQU 0 ;STILL NEED THE SWITCH
- ENDIF
- ;
- ;
- ;
- ;BDOS ENTRY POINT AND FUNCTION CODES
- ;
- IF NOT TRS1
- BASE SET 0 ;STANDARD CPM
- ENDIF
- ;
- IF TRS1 OR H84
- BASE SET 4200H ;TRS-80 MODEL 1 CP/M BASE ADDRESS
- ENDIF
- ;
- BDOS EQU BASE+5
- RESDSK EQU 13 ;RESET DISK SYSTEM
- OFFC EQU 15 ;OPEN FILE
- CFFC EQU 16 ;CLOSE FILE
- DFFC EQU 19 ;DELETE FILE
- RRFC EQU 20 ;READ RECORD
- WRFC EQU 21 ;WRITE RECORD
- MFFC EQU 22 ;MAKE FILE
- ;
- ; TRS80 PICKLES AND TROUT SIO CALLS
- ; OFFSET BY -3 THAT IS ADD 3 TO ALL CALLS
- ;
- SETSIO EQU 30H ;SET UP Z80 SIO
- SIOTST EQU 33H ;READ SIO STATUS
- SIOINP EQU 36H ;INPUT A CHAR
- SIOOUT EQU 39H ;OUTPUT A CHAR
- ;
- ;DEFAULT FCB AND FIELD DEFINITIONS
- ;
- FCB EQU BASE+5CH
- FN EQU 1 ;FILE NAME FIELD (REL)
- FT EQU 9 ;FILE TYPE FIELD (REL)
- EX EQU 12 ;FILE EXTENT FIELD (REL)
- NR EQU 32 ;NEXT RECORD FIELD (REL)
- DBUF EQU BASE+80H ;DEFAULT DISK BUFFER ADDRESS
- ;
- ;ASCII CONTROL CHARACTERS
- ;
- CR EQU 0DH ;CARRIAGE RETURN
- LF EQU 0AH ;LINE FEED
- DEL EQU 7FH ;DELETE (RUBOUT)
- BELL EQU 07H ;BELL SIGNAL
- TAB EQU 09H ;HORIZONTAL TAB
- XON EQU 11H ;X-ON CHARACTER
- NULL EQU 00H ;NULL CHAR
- ;
- ;THE FOLLOWING "TRIGER" EQUATE IS SET TO "LF" (LINEFEED)
- ;BY DEFAULT. AN OPTIONAL TRIGER CHAR MAY BE PASSED VIA FCB1
- ;
- ; IE: PLINK B WILL SET TRIGER TO "BELL"
- ;
- ;THE FOLLOWING OPTIONS ARE ALLOWED
- ;
- ; 1. B = BELL 07H
- ; 2. X = XON 11H
- ; 3. U = UPLOAD NO TRIGER CHECK AT ALL
- ;ANY OTHER ASCII CHARACTER MAY BE PASSED THROUGH FCB1
- ;
- ;
- TRIGER EQU LF ;DEFAULT VALUE
- ;
- ;
- ;WARNING CHARACTER FOR LOW MEMORY
- ;
- WRNSIG EQU BELL ;IF YOU HAVE ONE, PUT 'BELL' HERE
- ;...ELSE PUT '*' HERE.
- ;
- ;MODEM I/O PORT ADDRESSES
- ;
- IF PMMI
- MODD EQU 0C1H ;MODEM DATA PORT
- MODS EQU 0C0H ;MODEM STATUS PORT
- MODINIT EQU 29H ;INITIALIZE BYTE ORIGINATE,
- ;7 DATA, EVEN PARITY, 1 STOP
- ENDIF
- ;
- IF DCH
- MODD EQU 90H ;MODEM DATA PORT
- MODS EQU 91H ;MODEM STATUS PORT
- MODINIT EQU 05H ;7 DATA, EVEN PARITY, 1 STOP
- ENDIF
- ;
- IF TRS1
- MODD EQU 0EBH ;TRS80 MOD 1 RS232 DATA PORT
- MODS EQU 0EAH ; AND THE RS232 STATUS PORT
- ENDIF
- ;
- IF TUART
- MODD EQU 0D8H ;<<--MODIFY FOR YOURS
- MODS EQU 0DDH ;<<--MODIFY FOR YOURS
- ENDIF
- ;
- ;MODEM STATUS PORT BIT DEFINITIONS
- ;
- IF PMMI
- MTBE EQU 01H ;MODEM TRANS. BUFFER READY FLAG
- MRDA EQU 02H ;MODEM RECEIVE DATA AVAIL. FLAG
- ENDIF
- ;
- IF DCH
- MTBE EQU 02H ;MODEM TRANS. BUFFER READY FLAG
- MRDA EQU 01H ;MODEM RECEIVE DATA AVAIL. FLAG
- ENDIF
- ;
- IF TRS1
- MTBE EQU 40H ;TRS80 MOD1 RS232 BUFFER READY
- MRDA EQU 80H ;MODEM RECEIVE DATA AVAIL.
- ENDIF
- ;
- IF TUART ;<<--OR ANY OTHER SERIAL I/O
- MTBE EQU 20H ;<<--MODIFY FOR YOURS
- MRDA EQU 1H ;<<--MODIFY FOR YOURS
- ENDIF
- ;
- ; **MAIN PROGRAM**
- ;
- ORG BASE+100H
- ;
- LINK: LXI SP,STACK+64 ;CREATE LOCAL STACK
- LHLD BASE+1 ;POINT TO CP/M JMP TABLE
- LXI D,3 ;GET READY TO ADD 3
- DAD D ;POINT TO CON STATUS JMP
- SHLD CITCAL+1 ;MODIFY CALL ADRS
- DAD D ;POINT TO CON IN JMP
- SHLD RCCAL+1 ;MODIFY CALL ADRS
- DAD D ;POINT TO CON OUT JMP
- SHLD WCCAL+1 ;MODIFY CALL ADRS
- LDA FCB+1 ;SEE IF OPTIONAL TRIGER CHAR
- CPI 20H ;BLANK.. ?
- JZ SKP ;..BLANK SO USE DEFAULT "LF"
- CPI 'B' ;BELL WANTED
- JZ TRGBEL
- CPI 'X' ;XON WANTED
- JZ TRGXON
- CPI 'U' ;UPLOADING NO CHECKING FOR TRIGER
- JZ TRGUPL
- ;
- SETTRG STA OVERLY+1 ;STORE THE CHARACTER AS IS THEN
- JMP SKP
- ;
- TRGBEL MVI A,BELL
- JMP SETTRG
- ;
- TRGXON MVI A,XON
- JMP SETTRG
- ;
- TRGUPL XRA A ;ZERO OUT JUMP
- STA OVERL1+1 ;CHANGE CHECK FOR C/R TO NULL
- STA OVERL2+1 ;AND SEND LINEFEEDS AS WELL
- JMP SKP
- ;
- SKP EQU $
- IF H84
- MVI A,80H; SET DLAB BIT IN 8250 UART
- OUT 0DBH; 8250 AT PORT D8H (330Q)
- NOP ! NOP ! NOP
- NOP ! NOP
- MVI A,01H; MSB OF BAUD RATE DIVISOR
- OUT 0D9H; ...TO UART
- NOP ! NOP ! NOP
- NOP ! NOP
- MVI A,80H; LSB OF BAUD RATE DIVISOR
- OUT 0D8H; ...TO UART
- NOP ! NOP ! NOP
- NOP ! NOP
- MVI A,03H; 8 BITS, 1 STOP BIT, NO PARITY, DLAB RESET
- OUT 0DBH; ...TO UART
- NOP ! NOP ! NOP
- NOP ! NOP
- MVI A,0; RESET CONTROL REGISTER
- OUT 0DCH; ...TO UART
- JMP CONT
- ENDIF
- IF INIT$REQUIRED AND NOT H84 OR PMMI AND NOT H84
- MVI A,MODINIT
- OUT MODS ;INITIALIZE MODEM PORT
- ENDIF
- ;
- IF TUART
- MVI A,80H ;DSR ON BIT 7 PARL PORT B
- OUT 54H
- ENDIF
- ;
- IF TRSPT ;MUST SET UP SERIAL CHANNEL
- RESET: LXI H,INITR ;STORE RETURN ADDRESS
- PUSH H
- LHLD 1
- LXI D,SETSIO ;SIO SETUP ROUTINE
- DAD D
- PUSH H ;STORE ON STACK
- MVI C,00H ;NO PARITY CHAN-A
- MVI D,0E6H ;8 bits ,1 STOP
- MVI E,3 ;300 BAUD
- MVI L,00H ;DISABLE EXT/ACK SIO FUNCTIONS
- MVI H,'S'-40H ;CONTROL S (X-ON)
- RET ;TROUGH SETUP PROG
- INITR NOP ;DO IT TO IT
- ENDIF
- ;
- IF TRS1 ;INIT FOR TRS80 MOD1 RS232
- OUT 0E8H ;RESET RS232
- IN 0E9H ;READ THE SWITCHES
- ANI 0F8H
- ORI 5
- OUT 0EAH ;SET DSR AND CTS
- MVI A,55H ;300 BAUD
- OUT 0E9H
- ENDIF
- ;
- ;
- IF PORT
- IN MODD ;CLEAR MODEM UART READ BUFFERS
- IN MODD
- ENDIF
- ;
- CONT XRA A ;CLEAR CHAR BUFFERS
- STA INCH
- STA OUTCH
- STA FLAG ;CLEAR TEXT SAVE FLAG
- LXI H,TBUF ;SET PTR TO TBUF
- SHLD PTR
- LXI H,0 ;SIZE = 0
- SHLD SIZE
- LXI H,LINKMS ;PRINT SIGN-ON MESSAGE
- CALL WCS
- ;
- ; MAIN LOOP
- ;
- LINK3: CALL CITEST ;JUMP IF NO DATA FROM CONSOLE
- JZ LINK4
- CALL RCC ;ELSE READ CONSOLE DATA
- CPI 20H
- CC PCC ;CALL PCC IF CONTROL CHAR
- JC LINK4 ;JUMP IF PCC HANDLED CHAR
- ORI 80H ;ELSE SET VALID DATA BIT
- STA INCH ;AND STORE IN INPUT CHAR BUFFER
- LINK4: LDA OUTCH ;JUMP IF NO DATA FOR CONSOLE
- ORA A
- JP LINK5
- ANI 7FH ;ELSE DISCARD VALID DATA BIT
- CALL WCC ;SEND CHAR TO CONSOLE
- XRA A ;THEN CLEAR OUTPUT CHAR BUFFER
- STA OUTCH
- LINK5: CALL MITEST ;JUMP IF NO DATA FROM MODEM
- JZ LINK6
- CALL RMC2 ;ELSE READ MODEM DATA
- CALL SAVE ;SAVE CHAR IN TEXT BUFFER IF FLAG ON
- ORI 80H ;SET DATA VALID BIT
- STA OUTCH ;STORE IN OUTPUT CHAR BUFFER
- LINK6: CALL MOTEST ;JUMP IF MODEM XMIT BUFFER BUSY
- JZ LINK7
- LDA INCH ;JUMP IF NO DATA FOR MODEM
- ORA A
- JP LINK7
- ANI 7FH ;DISCARD VALID DATA BIT
- ;
- IF PORT
- OUT MODD ;OUTPUT CHAR TO MODEM
- ENDIF
- ;
- IF TRSPT
- PUSH B ;STORE REGISTERS
- PUSH H
- PUSH D
- CALL WMC ;SEND CHAR
- POP D
- POP H
- POP B
- ENDIF
- ;
- XRA A ;...THEN CLEAR INPUT CHAR BUFFER
- STA INCH
- LINK7: JMP LINK3 ;END OF MAIN LOOP
- ;
- LINKMS: DB CR,LF,'PLINK as of 25-SEP-80'
- DB CR,LF,LF,'READY',CR,LF,LF,0
- ;
- ; PCC - PROCESS CONTROL CHARACTER
- ;
- PCC: CPI 'E'-40H ;JUMP OUT IF CTRL E
- JNZ PCC1
- PUSH H
- LXI H,AYS ;PRINT 'ARE YOU SURE'
- CALL WCS
- POP H
- CALL RCC ;GET ANSWER
- CALL WCC ;ECHO IT
- ANI 5FH ;MAKE UPPER CASE
- CPI 'Y' ;YES?
- JZ PCCEX ;EXIT
- CALL WCCR ;CRLF
- STC ;TELL LINK TO IGNORE THIS CHARACTER
- ;
- IF TRSPT
- POP PSW ;GOBBLE UP CALL ADDRESS
- JMP RESET ;RE-INITIALIZE SIO
- ENDIF
- ;
- IF PORT
- RET
- ENDIF
- ;
- PCC1: CPI 'T'-40H ;JUMP IF NOT CONTROL-T
- JNZ PCC2
- CALL STF ;TRANSMIT TEXT FILE TO MODEM
- STC ;TELL LINK TO IGNORE THIS CHARACTER
- RET
- ;
- PCC2: CPI 'Y'-40H ;JUMP IF NOT CONTROL-Y
- JNZ PCC3
- MVI A,1 ;TURN ON TEXT SAVE FLAG
- STA FLAG
- LXI H,PCCMR ;PRINT 'SAVING INCOMING TEXT IN MEMORY'
- CALL WCS
- STC ;TELL LINK TO IGNORE THIS CHARACTER
- RET
- ;
- PCC3: CPI 'Q'-40H ;JUMP IF NOT CONTROL-Q
- JNZ PCC4
- XRA A ;TURN OFF TEXT SAVE FLAG
- STA FLAG
- CALL WTB ;WRITE TEXT BUFFER TO DISK
- STC
- RET
- ;
- PCC4: STC ;LET LINK HANDLE ALL OTHER CONT. CODES
- CMC
- RET
- ;
- PCCEX: LXI H,DISMS ;PRINT 'MODEM NOT DISCONNECTED'
- CALL WCS
- JMP BASE ;EXIT TO WARM BOOT
- ;
- AYS: DB CR,LF,'EXIT TO CP/M - ARE YOU SURE (Y OR N)?',0
- IF PMMI OR DCH
- DISMS: DB CR,LF,'++DON''T FORGET - THE MODEM '
- DB 'IS NOT DISCONNECTED++',CR,LF
- DB 'USE "MODEM D" TO DISCONNECT',0
- ENDIF
- ;
- IF NOT PMMI AND NOT DCH
- DISMS: DB CR,LF,'+++ EXIT TO CP/M +++',CR,LF,0
- ENDIF
- ;
- PCCMR: DB CR,LF,'SAVING INCOMING TEXT IN MEMORY',CR,LF,0
- ;
- ; STF - SEND TEXT FILE (TO MODEM)
- ;
- STF: CALL GFN ;GET NAME OF DISK FILE TO SEND
- JC STF6 ;JUMP IF FILE NAME ERROR
- CALL OPEN ;TRY TO OPEN SPECIFIED FILE
- CPI 255 ;JUMP IF FILE NOT FOUND
- JZ STF7
- STF1: CALL READ ;READ NEXT RECORD INTO DBUF
- CPI 1 ;JUMP IF END-OF-FILE
- JZ STF5
- LXI H,DBUF ;POINT TO DISK BUFFER
- MVI C,128
- STF2: MOV A,M ;FETCH NEXT CHAR FROM DBUF
- INX H
- CPI 'Z'-40H ;JUMP IF END-OF-FILE CHARACTER
- JZ STF5
- OVERL2 CPI LF ;IGNORE LINE FEEDS
- JZ STF4
- CALL WMC ;WRITE CHARACTER TO MODEM
- CALL WCC ;WRITE CHARACTER TO CONSOLE
- OVERL1 CPI CR ;JUMP IF NOT CARRIAGE RETURN
- JNZ STF4
- STF3: CALL CITEST ;CHECK CONSOLE DATA READY
- JZ STF3A ;NO DATA THERE
- CALL RCC ;GET CONSOLE CHARACTER
- CPI 'C'-40H ;CONTROL C ABORTS IT
- JZ STF8
- STF3A: CALL MITEST ;WAIT FOR NEXT MODEM KHARACTER
- JZ STF3
- CALL RMC2 ;CHECK MODEM FOR TRIGGER CHAR.
- OVERLY CPI TRIGER
- JNZ STF3
- CALL WCCR ;SEND CRLF TO CONSOLE
- STF4: DCR C ;LOOP THRU REST OF DBUF
- JNZ STF2
- JMP STF1 ;GO GET NEXT RECORD FROM DISK
- ;
- STF5: LXI H,STFSM ;PRINT 'FILE SEND COMPLETE'
- CALL WCS
- RET
- ;
- STF6: LXI H,STFS1 ;PRINT 'FILE NAME ERROR'
- CALL WCS
- RET
- ;
- STF7: LXI H,STFS2 ;PRINT 'FILE NOT FOUND'
- CALL WCS
- RET
- ;
- STF8: LXI H,STFSA ;PRINT 'FILE SEND ABORTED'
- CALL WCS
- RET
- ;
- STFSM: DB 'FILE SEND COMPLETE',CR,LF,0
- STFS1: DB 'FILE NAME ERROR',CR,LF,0
- STFS2: DB 'FILE NOT FOUND',CR,LF,0
- STFSA: DB CR,LF,'FILE SEND ABORTED',CR,LF,0
- ;
- ; SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON
- ;
- ; ENTRY CONDITIONS
- ; A - CHARACTER TO SAVE
- ;
- SAVE: PUSH PSW
- LDA FLAG
- ORA A
- JNZ SAVE1
- POP PSW
- RET
- ;
- SAVE1: POP PSW
- CPI DEL ;RUBOUT (DEL) ?
- RZ ;YES, IGNORE IT
- CPI 20H ;TEST FOR CONTROL CHARACTERS
- JNC SAVE2 ;JUMP IF NOT CONTROL CHAR.
- CPI CR ;ALLOW CR TO BE SAVED
- JZ SAVE2
- CPI LF ;ALLOW LF TO BE SAVED
- JZ SAVE2
- CPI TAB ;ALLOW TAB TO BE SAVED
- JZ SAVE2
- RET ;IGNORE ALL OTHER CONTROL CHARS.
- ;
- SAVE2: PUSH H
- LHLD SIZE ;SIZE = SIZE + 1
- INX H
- SHLD SIZE
- LHLD PTR
- MOV M,A
- INX H
- SHLD PTR
- PUSH PSW
- LDA BASE+7 ;GET SYSTEM SIZE
- SUI 1 ;SO WE DONT CRASH CP/M
- CMP H ;ARE WE OUT OF ROOM?
- JZ SAVEAB ;YES, ABORT
- SUI 4 ;LEAVE SOME ROOM (1K)
- CMP H
- MVI A,WRNSIG ;SIGNAL CONSOLE RUNNING OUT OF SPACE
- CC WCC
- POP PSW
- POP H
- RET
- ;
- ; SAVEAB - RAN OUT OF ROOM, ISSUE MESSAGE AND FLOW
- ; THROUGH TO DISK SAVE ROUTINE
- ;
- SAVEND: DB BELL,CR,LF,'ABORTING - NO ROOM LEFT',0
- ;
- SAVEAB: LXI SP,STACK+64 ;REINITIALIZE STACK
- LXI H,SAVEND ;PRINT 'ABORTING - NO ROOM LEFT'
- CALL WCS
- LXI H,LINK ;SET UP RETURN ADDRESS
- PUSH H ;LEAVE IT ON THE STACK
- ;
- ; WTB - WRITE TEXT BUFFER TO DISK
- ;
- WTB: LHLD SIZE ;JUMP IF TEXT BUFFER EMPTY
- MOV A,L
- ORA H
- JZ WTB5
- MVI C,RESDSK ;RESET IN CASE READ-ONLY
- CALL BDOS
- CALL GFN ;GET FILE NAME
- JC WTB6 ;JUMP IF FILE NAME ERROR
- CALL DELT ;DELETE OLD FILE, IF ANY
- CALL MAKE ;MAKE NEW FILE
- LHLD SIZE ;DE = TBUF SIZE
- XCHG
- LXI H,DBUF ;TOP OF STACK POINTS TO DBUF
- PUSH H
- LXI H,TBUF ;HL POINTS TO TBUF
- WTB1: MVI C,128 ;DISK BUFFER SIZE
- WTB2: MOV A,M ;FETCH NEXT BYTE OF TBUF
- INX H
- XTHL
- MOV M,A ;STORE IN DBUF
- INX H
- XTHL
- DCX D ;SIZE = SIZE - 1
- MOV A,D ;EXIT LOOP IF SIZE = 0
- ORA E
- JZ WTB3
- DCR C ;LOOP UNTIL DBUF FULL
- JNZ WTB2
- CALL WRITE ;WRITE FULL DBUF TO DISK
- XTHL ;TOP OF STACK POINTS TO DBUF
- LXI H,DBUF
- XTHL
- JMP WTB1 ;LOOP UNTIL END OF TBUF
- ;
- WTB3: POP H ;HL POINTS TO CURRENT PLACE IN DBUF
- WTB4: MVI M,'Z'-40H ;STORE EOF CODE
- INX H
- DCR C ;LOOP THRU REST OF DBUF
- JNZ WTB4
- CALL WRITE ;WRITE LAST SECTOR TO DISK
- CALL CLOSE ;CLEAN UP ACT AND GO HOME
- LXI H,TBUF ;CLEAR TEXT BUFFER
- SHLD PTR
- LXI H,0
- SHLD SIZE
- LXI H,WTBSM ;PRINT 'BUFFER SAVED ON DISK'
- CALL WCS
- RET
- ;
- WTB5: LXI H,WTBS1 ;PRINT 'TEXT BUFFER EMPTY'
- CALL WCS
- RET
- ;
- WTB6: LXI H,WTBS2 ;PRINT 'FILE NAME ERROR'
- CALL WCS
- RET
- ;
- WTBSM: DB CR,LF,'BUFFER SAVED ON DISK',CR,LF
- DB 'MEMORY SAVE CANCELLED',CR,LF,0
- WTBS1: DB 'TEXT BUFFER EMPTY',CR,LF,0
- WTBS2: DB 'FILE NAME ERROR',CR,LF,0
- ;
- ; WCS - WRITE CONSOLE STRING
- ;
- ;
- ; ENTRY CONDITIONS
- ; HL - POINTS TO STRING (TERM BY ZERO BYTE)
- ;
- WCS: MOV A,M
- INX H
- ORA A
- RZ
- CALL WCC
- JMP WCS
- ;
- ; WCCR - WRITE CONSOLE CARRIAGE RETURN (AND LINE FEED)
- ;
- WCCR: MVI A,CR
- CALL WCC
- MVI A,LF
- ;
- ; WCC - WRITE CONSOLE CHARACTER
- ;
- ; ENTRY CONDITIONS:
- ; A - CHARACTER TO WRITE
- ;
- WCC: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- MOV C,A ;GET CHARACTER FOR CBIOS
- WCCAL: CALL $-$ ;MODIFIED BY INIT.
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;
- ; RCS - READ CONSOLE STRING (WITH ECHO)
- ;
- ; EXIT CONDITIONS
- ; B - NUMBER OF CHARACTERS READ (<255)
- ; HL - POINTS TO LAST CHAR STORED (CR)
- ;
- RCS: LXI H,IBUF
- MVI B,0
- RCS1: CALL RCC ;READ NEXT CHAR FROM CONSOLE
- CPI DEL ;JUMP IF NOT DEL
- JNZ RCS2
- INR B ;IGNORE DEL IF IBUF ALREADY EMPTY
- DCR B
- JZ RCS1
- DCX H ;ELSE DISCARD LAST CHAR
- MOV A,M ;ECHO DISCARDED CHAR TO CONSOLE
- CALL WCC
- DCR B ;DECREMENT COUNT
- JMP RCS1 ; AND LOOP
- ;
- RCS2: CPI 'U'-40H ;JUMP IF NOT CONTROL U
- JNZ RCS3
- CALL WCCR ;ELSE ABORT CURRENT LINE
- JMP RCS ; AND START OVER
- ;
- RCS3: CALL WCC ;ECHO CHAR TO CONSOLE
- MOV M,A ;STORE CHAR IN IBUF
- INR B ;INCREMENT COUNT
- CPI CR ;JUMP IF CARRIAGE RETURN
- JZ RCS4
- INX H ;ELSE ADVANCE POINTER
- JMP RCS1 ; AND LOOP
- ;
- RCS4: MVI A,LF ;ISSUE LINE FEED AND RETURN
- CALL WCC
- RET
- ;
- ; RCC - READ CONSOLE CHARACTER
- ;
- ; EXIT CONDITIONS
- ; A - CHARACTER READ
- ;
- RCC: PUSH B
- PUSH D
- PUSH H
- RCCAL: CALL $-$ ;MODIFIED BY INI\.
- POP H
- POP D
- POP B
- RET
- ;
- ; WMC - WRITE MODEM CHARACTER
- ;
- ; ENTRY CONDITIONS
- ; A - CHARACTER TO WRITE
- ;
- ;
- IF PORT
- WMC: PUSH PSW
- WMCL: IN MODS
- ANI MTBE
- JZ WMCL
- POP PSW
- ANI 7FH ;STRIP PARITY BIT
- OUT MODD
- RET
- ENDIF
- ;
- IF TRSPT
- WMC: PUSH H
- PUSH D
- PUSH PSW
- WMCL: CALL MOTEST ;TEST STATUS
- JZ WMCL ;LOOP TILL TX EMPTY
- POP PSW ;RESTORE CHAR
- ANI 7FH ;STRIP PARITY
- PUSH B ;STORE B
- MOV C,A ;PUT CHAR INTO C
- MVI B,00H ;CHANNEL A
- LXI H,WMCRE ;STORE RETURN ADDRESS
- PUSH H
- LHLD 1 ;GET BASE ADDRESS
- LXI D,SIOOUT
- DAD D
- PCHL ;JUMP TO IT
- WMCRE: POP B ;RESTORE IT
- POP D
- POP H
- RET
- ENDIF
- ;
- ; RMC - READ MODEM CHARACTER
- ;
- ; EXIT CONDITIONS:
- ; A - CHARACTER READ
- ;
- ;
- IF PORT
- RMC: IN MODS
- ANI MRDA
- JZ RMC
- RMC2: IN MODD
- ANI 7FH
- RET
- ENDIF
- ;
- IF TRSPT
- RMC: CALL MITEST ;CHAR AVAILABLE
- JZ RMC ;LOOP IF NOT READY
- RMC2: PUSH B ;STORE B
- PUSH D
- PUSH H
- MVI B,00H ;CHANNEL A
- LXI H,RMCRE ;RETURN ADDRESS
- PUSH H
- LHLD 1
- LXI D,SIOINP
- DAD D
- PCHL
- RMCRE: POP H
- POP D
- POP B
- ANI 7FH ;STRIP PARITY
- RET
- ENDIF
- ;
- ;
- ; GFN - GET FILE NAME
- ;
- GFN: LXI H,GFNSD ;PRINT 'WHICH DRIVE?'
- CALL WCS
- CALL RCC ;GET ANSWER FROM CONSOLE
- CALL WCC ;ECHO IT TO CONSOLE
- ANI 5FH ;MAKE UPPER CASE
- SUI 'A'-1
- JC GFN ;REQUIRE ALPHABETIC
- JZ GFN
- CPI 17 ;ALLOW 16 DRIVES (AS IN CP/M 2.X)
- JNC GFN
- STA FCB
- GFNB: LXI H,GFNS1 ;PRINT 'FILENAME? '
- CALL WCS
- CALL RCS ;READ RESPONSE INTO IBUF
- LXI H,FCB+FN ;BLANK FILL FN AND FT FIELDS
- MVI C,11
- GFN1: MVI M,' '
- INX H
- DCR C
- JNZ GFN1
- LXI H,IBUF ;POINT TO INPUT BUFFER
- LXI D,FCB+FN ;SCAN OFF FN FIELD
- MVI C,9
- GFN2: MOV A,M ;FETCH NEXT CHAR FROM IBUF
- INX H
- CPI 61H ;IF LC, CONVERT TO UC
- JC GFN2A
- SUI 20H
- GFN2A: CPI CR ;JUMP IF END OF LINE
- JZ GFN5
- CPI '.' ;JUMP IF END OF NAME
- JZ GFN3
- STAX D ;ELSE STORE CHAR IN FN FIELD
- INX D
- DCR C ;LOOP IF 8 OR LESS CHARS SO FAR
- JNZ GFN2
- JMP GFN6 ;ELSE TAKE ERROR EXIT
- ;
- GFN3: LXI D,FCB+FT ;SCAN OFF FT FIELD
- MVI C,4
- GFN4: MOV A,M ;FETCH NEXT CHAR FROM IBUF
- INX H
- CPI 61H ;IF LC, CONVERT TO UC
- JC GFN4A
- SUI 20H
- GFN4A: CPI CR ;JUMP IF END OF LINE
- JZ GFN5
- STAX D ;ELSE STORE CHAR IN FT FIELD
- INX D
- DCR C ;LOOP IF 3 OR LESS CHARS SO FAR
- JNZ GFN4
- JMP GFN6 ;ELSE TAKE ERROR EXIT
- ;
- GFN5: XRA A
- STA FCB+EX ;SET EXTENT NUMBER TO ZERO
- STA FCB+NR ;SET RECORD NUMBER TO ZERO
- STC ;CLEAR ERROR FLAG AND RETURN
- CMC
- RET
- ;
- GFN6: STC ;SET ERROR FLAG AND RETURN
- RET
- ;
- GFNSD: DB CR,LF,'WHICH DRIVE? ',0
- GFNS1: DB CR,LF,'FILENAME? ',0
- ;
- ; OPEN - OPEN DISK FILE
- ;
- OPEN: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,OFFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; READ - READ RECORD FROM DISK FILE
- ;
- READ: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,RRFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; CLOSE - CLOSE DISK FILE
- ;
- CLOSE: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,CFFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; DELT - DELETE DISK FILE
- ;
- DELT: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,DFFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; WRITE - WRITE RECORD TO DISK
- ;
- WRITE: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,WRFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; MAKE - MAKE NEW DISK FILE
- ;
- MAKE: PUSH H
- PUSH D
- PUSH B
- LXI D,FCB
- MVI C,MFFC
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; CITEST - CHECK CONSOLE INPUT STATUS
- ;
- CITEST: PUSH B
- PUSH D
- PUSH H
- CITCAL: CALL $-$ ;MODIFIED BY INIT.
- ORA A ;SET ZERO FLAG
- POP H
- POP D
- POP B
- RET ;ZERO FLAG CARRIES ANSWER
- ;
- ; MITEST - CHECK MODEM INPUT STATUS
- ;
- IF PORT
- MITEST: IN MODS ;GET MODEM UART STATUS
- ANI MRDA ;ANY DATA AVAILABLE?
- RET ;ZERO FLAG CARRIES ANSWER
- ENDIF
- ;
- ;
- IF TRSPT
- ;
- MITEST: PUSH B
- PUSH H
- PUSH D
- MVI B,00 ;CHANNEL A
- LXI H,MITSTR
- PUSH H
- LHLD 1
- LXI D,SIOTST
- DAD D
- PCHL
- MITSTR: POP D
- POP H
- ANI 01 ;TX EMPTY
- POP B
- RET ;ZERO FLAG HOLDS THE ANSWER
- ENDIF
- ;
- ; MOTEST - CHECK MODEM OUTPUT STATUS
- ;
- ;
- IF PORT
- MOTEST: IN MODS ;GET MODEM UART STATUS
- ANI MTBE ;UART READY FOR CHARACTER?
- RET ;ZERO FLAG CARRIES ANSWER
- ENDIF
- ;
- IF TRSPT
- MOTEST: PUSH B
- PUSH H
- PUSH D
- MVI B,00 ;CHANNEL A
- LXI H,MOTSTR
- PUSH H
- LHLD 1
- LXI D,SIOTST
- DAD D
- PCHL
- MOTSTR: ANI 02 ;BUFFER EMPTY
- POP D
- POP H
- POP B
- RET
- ENDIF
- ;
- ; DATA AREA
- ;
- INCH: DS 1 ;INPUT CHAR BUFFER (TO CYBER)
- OUTCH: DS 1 ;OUTPUT CHAR BUFFER (FROM CIBER)
- STACK: DS 80 ;LOCAL STACK
- IBUF: DS 256 ;INPUT BUFFER
- ;
- ; TEXT BUFFER
- ;
- FLAG: DS 1 ;TEXT SAVE FLAG
- PTR: DS 2 ;TEXT BUFFER POINTER
- SIZE: DS 2 ;TEXT BUFFER SIZE
- TBUF: EQU $ ;START OF TEXT BUFFER
- ;
- END LINK
- ;
-
-