home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
modems
/
modem
/
plink67a.aqm
/
PLINK67A.ASM
Wrap
Assembly Source File
|
1985-02-09
|
37KB
|
1,282 lines
; PLINK.ASM VER 6.7
; (REVISED 5/6/82)
;
;PLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO
;ESTABLISH A COMMUNICATIONS LINK WITH A REMOTE COMPUTER.
;
;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/H89 WITH 8250 UART AT PORT 330Q
; 6. D.C.HAYES 80-103A OR MICROMODEM 100
; 7. MITS 2SI/O BOARD, PORTS 10H &11H = CONSOLE, 12H & 13H = MODEM
; 8. INTEL SBC OR NATIONAL BLC MULTI-BUS BOARDS USING 8251 USART
; 9. APPLE II WITH Z-80 CARD AND SUPER SERIAL IN SLOT 2
;
;ORIGINALLY WRITTEN BY L.E. HUGHES (EDCAM) IN JULY, 1977. MANY
;MODIFICATIONS HAVE BEEN MADE SINCE THIS TIME, AS SHOWN IN THE
;FOLLOWING SUMMARY.
;
;FIXES/UPDATES (IN REVERSE ORDER TO MINIMIZE READING TIME):
;
; NOV 8, 1982. APPLE EQUATES CHANGED FOR SUPER SERIAL CARD (MIKE COHEN)
;
; JUNE 15, 1982. ADDED FEATURE TO AUTOMATICALLY SEND
; X-OFF TO REMOTE WHEN BUFFER FILLS AND DISK SAVE BEGINS (CHRIS HAYS)
; JUNE 15, 1982. FIXED DELETE/BACKSPACE PROBLEM
; WHEN USED WITH APPLE CP/M (CHRIS HAYS)
; MAY 6, 1982. ADDED APPLE II EQUATES (CHRIS HAYS)
; MAY 6, 1982. ADDED ERROR TRAP AND RECOVERY ROUTINE
; IN CASE THE DISK GETS FULL WHEN SAVING BUFFER. CHRIS HAYS
; MAY 6, 1982. ADDED CONDITIONAL ASSEMBLY SWITCH TO ALLOW
; MICRONET UPLOAD TO WORK CORRECTLY. OPTION IS ACTIVATED
; WHEN THE 'U' (UPLOAD) TRIGGER OPTION IS SELECTED. CHRIS HAYS.
; JUNE 26, 1981. ADDED MESSAGE WHEN EXITING IF LAST BUFFER WAS
; NOT SAVED. TED SHAPIN.
;
;JUNE 14, 1981, BY KEITH PETERSEN, W8SDZ. CHANGED PORT
;EQUATE TO 'EQU' INSTEAD OF 'SET'. ASM DOESN'T LIKE 'SET'
;WHEN LATER CONDITIONALS ARE BASED ON A LABEL DEFINED THAT
;WAY.
;
;JUNE 7, 1981, BY TOM JORGENSON (CP-MIG). CHANGED CP/M
;ORIGIN FROM BEING VIA SETS TO REFERENCED TO BASE, ADDED
;TRUE/FALSE RATHER THAN NUMERIC VALUES (FOR READABILITY),
;CHANGED ^Q FUNCTION TO ^W (WRITE) BECAUSE SOME SYSTEMS
;(NOTABLY MICRONET) USE ^S/^Q TO SUSPEND/RESUME OUTPUT,
;CHANGED PAGE 0 REFERENCES IN TRS ROUTINES TO USE
;BASE EQUATE PROPERLY, CHANGED PORT EQUATES TO DEFAULT
;TO TRUE, REINSERTED HEATH EQUATES, AND CLEANED UP CODE
;IN SEVERAL PLACES.
;
;JUNE 7, 1981, BY KEITH PETERSEN, W8SDZ. FIXED PROBLEM WITH
;EQUATES WHICH PREVENTED ASSEMBLY BY 'ASM' WHEN TUART OPTION
;WAS SELECTED.
;
;JUNE 6, 1981, BY KEITH PETERSEN, W8SDZ. ADDED VERSION NUMBER,
;CLEANED UP FILE.
;
;MAY 12, 1981, BY T. SHAPIN. ADDED CODE FOR 8251 USART ON INTEL
;SBC OR NATIONAL BLC MULTIBUS BOARD WITH MODIFIED CP/M ORIGIN.
;ADDED PROMPT TO SIGNON. ADDED TOGGLE TO ^Y TO SAVE OR IGNORE
;INCOMING TEXT. ADDED ^C ABORT ON FILE NAME RESPONSE.
;
;NOVEMBER 10, 1980, BY KELLY SMITH. ADDED CONDITIONAL ASSEMBLY
;SWITCH FOR MITS 2SI/O BOARD, USING "STANDARD" MITS PORTS 10 AND
;11 HEX FOR THE CONSOLE, AND 12 AND 13 HEX FOR THE MODEM.
;
;OCTOBER 18, 1980, BY KEITH PETERSEN, W8SDZ.
;
;HEATH EQUATES ADDED BY TOM JORGENSON.
;
;TRS-80 MODEL 1 MODS BY STEVE VINOKUROFF, VANCOUVER CBBS.
;
;OPTIONAL TRIGGER CHARACTERS BY STEVE VINOKUROFF.
;
;TRS-80 MODS BY DENNIS BRECKENRIDGE, BURNABY CBBS.
;
;D.C.HAYES MODS BY BRUCE RATOFF, ISELIN NEW JERSEY REMOTE CP/M.
;
;NOTE: IF YOU ADD IMPROVEMENTS OR OTHERWISE UPDATE
;THIS PROGRAM, PLEASE MODEM A COPY OF THE NEW FILE
;TO "TECHNICAL CBBS" IN DEARBORN, MICHIGAN - PHONE
;313-759-6569>>RINGBACK.
;(110, 300, 450 OR 600 BAUD).
;FILENAME PLINKXX.NEW.
;
;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:
;
;CONTROL-E EXIT PLINK TO CP/M "WARM-BOOT".
;
;CONTROL-T TRANSMIT ASCII FILE TO REMOTE SYSTEM, ASKS FOR
; DRIVE (A, B, ETC.) AND FILENAME.TYP.
;
;CONTROL-C ABORTS TRANSMISSION OF FILE TO REMOTE SYSTEM.
;
;CONTROL-Y SWITCHES BETWEEN SAVING AND IGNORING
; INCOMING ASCII DATA IN RAM BUFFER,
; FOR LATER TRANSFER TO DISK.
;
;CONTROL-W WRITES RAM BUFFER TO DISK, AND ASKS FOR DRIVE
; AND FILENAME.TYP.
;
;DEL (DELETE) BACKSPACE WHEN IN COMMAND MODE (E.G. ^T OR ^W).
;
;CONTROL-U ABORTS CURRENT LINE WHEN IN COMMAND MODE.
;
;(NOTE: ALL OTHER CONTROL CODES ARE PASSED TO MODEM OUTPUT, AND
;MAY BE INTERPRETED BY THE REMOTE SYSTEM AS VARIOUS CONTROL
;FUNCTIONS.)
;
;TRUE/FALSE DEFINITIONS
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
;CONDITIONAL ASSEMBLY SWITCHES <<-- SET FOR YOUR SYSTEM
;(SELECT ONLY ONE AS TRUE) - (NOTE: USE TUART FOR OTHER
;SERIAL PORTS NOT DEFINED).
;
MITSIO EQU FALSE ;TRUE, IF MITS 2SI/O BOARD
H84 EQU FALSE ;TRUE, IF YOU HAVE H8/H8-4 OR H89
TUART EQU FALSE ;TRUE, IF CROMENCO TUART OR OTHER SERIAL
PMMI EQU FALSE ;TRUE, IF PMMI (SET INITREQ TRUE ONLY
;IF ORIG MODE AND PARITY IS REQUIRED)
DCH EQU FALSE ;TRUE, IF D.C.HAYES
TRS1 EQU FALSE ;TRUE, IF TRS-80 MODEL 1
TRSPT EQU FALSE ;TRUE, IF TRS-80 MODEL 2
;USING PICKLES & TROUT CP/M 2.X
MULTI EQU FALSE ;TRUE, IF SBC OR BLC 8251 USART
APPLE EQU TRUE ;TRUE, IF APPLE CP/M
;
MNET EQU TRUE ;TRUE, IF MICRONET UPLOAD FEATURE WANTED
;
INITREQ EQU FALSE ;TRUE, IF PORT INITIALIZATION REQUIRED
;
IF NOT (TRSPT OR APPLE)
PORT EQU TRUE ;TRUE, ON MOST SYSTEMS
ENDIF
;
IF TRSPT OR APPLE
PORT EQU FALSE ;THIS IS THE ODDBALL
ENDIF
;
;BDOS ENTRY POINT AND FUNCTION CODES
;
BASE EQU 0 ;<<-- SET TO OFFSET OF CP/M FOR YOUR
;SYSTEM, STANDARD SYSTEMS ARE 0, SOME
;'ALTERNATE' SYSTEMS ARE 4200H
;
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
;
IF MULTI
MODS EQU 0DDH ;MODEM CONTROL
MTBE EQU 1 ;BIT TO TEST FOR SEND
MRDA EQU 2 ;BIT TO TEST FOR RECEIVE
MXOR EQU 3 ;MASK TO MAKE MTBE AND MRDA 'LOW TRUE'
MODD EQU 0DCH ;MODEM DATA PORT
ENDIF
;
;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
IF NOT APPLE
DEL EQU 7FH ;DELETE (RUBOUT)
ENDIF
;
IF APPLE
DEL EQU 08H ;APPLE USES BS INSTEAD
ENDIF
;
BELL EQU 07H ;BELL SIGNAL
TAB EQU 09H ;HORIZONTAL TAB
XOFF EQU 13H ;X-OFF CHARACTER
XON EQU 11H ;X-ON CHARACTER
NULL EQU 00H ;NULL CHAR
;
;THE FOLLOWING "TRIGGER" EQUATE IS SET TO "LF" (LINEFEED)
;BY DEFAULT. AN OPTIONAL TRIGGER CHAR MAY BE PASSED VIA FCB1
;
; IE: PLINK B WILL SET TRIGGER TO "BELL"
;
;THE FOLLOWING OPTIONS ARE ALLOWED
;
; 1. B = BELL 07H
; 2. X = XON 11H
; 3. U = UPLOAD NO TRIGGER CHECK AT ALL
;
;ANY OTHER ASCII CHARACTER MAY BE PASSED THROUGH FCB1
;
;
TRIGGER EQU LF ;DEFAULT VALUE
;
;
;WARNING CHARACTER FOR LOW MEMORY
;
IF NOT APPLE
WRNSIG EQU BELL ;IF YOU HAVE ONE, PUT 'BELL' HERE
;...ELSE PUT '*' HERE.
ENDIF
;
IF APPLE
WRNSIG EQU '*' ;APPLE BELL LOSES 100MS
ENDIF ;SO USE '*' INSTEAD
;
;MODEM I/O PORT ADDRESSES
;
IF MITSIO
MODD EQU 13H ;MODEM DATA PORT
MODS EQU 12H ;MODEM STATUS PORT
MODRSET EQU 03H ;6850 ACIA RESET
MODINIT EQU 11H ;8 DATA, NO PARITY, 2 STOP
ENDIF
;
IF H84
MODD EQU 330Q ;MODEM DATA PORT
MODS EQU 335Q ;MODEM STATUS PORT
ENDIF
;
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 0D6H ;<<--MODIFY FOR YOURS
MODS EQU 0D7H ;<<--MODIFY FOR YOURS
ENDIF
;
IF APPLE ;THESE ARE FOR SUPER SERIAL CARD
MODD EQU 0E0A8H ;INSTALLED IN SLOT 2
MODS EQU 0E0A9H ;CHANGE IF NECESSARY
ENDIF
;
;MODEM STATUS PORT BIT DEFINITIONS
;
IF H84
MTBE EQU 40Q ;MODEM THRE TRANSMIT READY BIT
MRDA EQU 01Q ;MODEM RDA REC'D DATA BIT
MXOR EQU 41Q ;MASK TO MAKE MTBE AND MRDA 'NEGATIVE LOGIC'
ENDIF
;
IF PMMI
MTBE EQU 01H ;MODEM TRANS. BUFFER READY FLAG
MRDA EQU 02H ;MODEM RECEIVE DATA AVAIL. FLAG
MXOR EQU 03H ;MASK TO MAKE MTBE AND MRDA "LOW TRUE"
ENDIF
;
IF DCH OR MITSIO
MTBE EQU 02H ;MODEM TRANS. BUFFER READY FLAG
MRDA EQU 01H ;MODEM RECEIVE DATA AVAIL. FLAG
MXOR EQU 03H
ENDIF
;
IF TRS1
MTBE EQU 40H ;TRS80 MOD1 RS232 BUFFER READY
MRDA EQU 80H ;MODEM RECEIVE DATA AVAIL.
MXOR EQU 0C0H
ENDIF
;
IF TUART ;<<--OR ANY OTHER SERIAL I/O
MTBE EQU 1 ;<<--MODIFY FOR YOURS
MRDA EQU 2 ;<<--MODIFY FOR YOURS
MXOR EQU 3 ;<<--MODIFY FOR YOURS
ENDIF
;
IF APPLE
MTBE EQU 10H ;TRANSMIT BUFFER READY FLAG
MRDA EQU 08H ;RECEIVE DATA AVAIL FLAG
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 TRIGGER 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 TRIGGER
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 MITSIO
MVI A,MODRSET
OUT MODS
MVI A,MODINIT
OUT MODS
ENDIF
;
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 INITREQ AND (NOT H84) AND (NOT MITSIO)
MVI A,MODINIT
OUT MODS ;INITIALIZE MODEM PORT
ENDIF
;
IF INITREQ AND 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
;
IF MULTI ;INITIALIZE 8251
XRA A
OUT MODS
OUT MODS
OUT MODS
MVI A,40H
OUT MODS
MVI A,0CFH ;300 BAUD (THIS DEPENDS ON STRAPPING)
OUT MODS
MVI A,37H
OUT MODS
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 APPLE
STA 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 VER 6.7'
DB CR,LF,CR,LF
DB '[^T]RANSMIT, [^Y]ANK, [^W]RITE, [^E]XIT, [^C]ANCEL'
DB CR,LF,'READY',CR,LF,LF,0
;
;PCC - PROCESS CONTROL CHARACTER
;
PCC: CPI 'E'-40H ;JUMP OUT IF CTRL E
JNZ PCC1
PUSH H
LHLD SIZE ; CHECK FOR SOMETHING IN TEXT BUFFER
MOV A,L ; AND GIVE WARNING
ORA H
JZ PCCEX ; BEFORE EXIT
LXI H,AYS ;PRINT 'DO YOU WANT TO SAVE...
CALL WCS
POP H
CALL RCC ;GET ANSWER
CALL WCC ;ECHO IT
ANI 5FH ;MAKE UPPER CASE
CPI 'Y' ;YES?
CZ WTB ; WRITE OUT BUFFER
JMP PCCEX ;EXIT
; CALL WCCR ;CRLF
; STC ;TELL PLINK 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 PLINK TO IGNORE THIS CHARACTER
RET
;
PCC2: CPI 'Y'-40H ;JUMP IF NOT CONTROL-Y
JNZ PCC3
LDA FLAG
DCR A ;WAS IT ZERO?
JNZ PCC2A ;YES
STA FLAG ;NO, WAS 1, NOW 0
LXI H,PCMNIX ;PRINT IGNORE INCOMING STUFF
JMP PCC2B
;
PCC2A: MVI A,1 ;TURN ON TEXT SAVE FLAG
STA FLAG
LXI H,PCCMR ;PRINT 'SAVING INCOMING TEXT IN MEMORY'
;
PCC2B: CALL WCS
STC ;TELL PLINK TO IGNORE THIS CHARACTER
RET
;
PCC3: CPI 'W'-40H ;JUMP IF NOT CONTROL-W
JNZ PCC4
XRA A ;TURN OFF TEXT SAVE FLAG
STA FLAG
CALL WTB ;WRITE TEXT BUFFER TO DISK
STC
RET
;
PCC4: STC ;LET PLINK 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,'DO YOU WANT TO SAVE THE STUFF IN'
DB CR,LF,'THE BUFFER BEFORE EXIT TO CP/M (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
PCMNIX: DB CR,LF,'IGNORING INCOMING TEXT',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 CHARACTER
JZ STF3
CALL RMC2 ;CHECK MODEM FOR TRIGGER CHAR.
;
OVERLY CPI TRIGGER
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 OR ABORT',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: MVI A,XOFF ;TELL REMOTE
CALL WMC ;TO STOP SENDING
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
CALL GFN ;GET FILE NAME
JC WTB6 ;JUMP IF FILE NAME ERROR
MVI C,RESDSK ;RESET IN CASE READ-ONLY
CALL BDOS ;OR ERROR RECOVERY
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
CPI 00H ;DID WE HAVE AN ERROR?
JNZ WRER ;IF SO, BAIL OUT
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
CPI 00H ;ERROR?
JNZ WRER ;IF SO HANDLE IT, ELSE
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
;
WRER: LXI H,WRERMS
CALL WCS ;PRINT ERROR MESSAGE
JMP WTB ;AND START OVER
;
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 OR ABORT',CR,LF,0
WRERMS: DB 'ERROR WRITING DATA',CR,LF,'(DISK FULL)',CR,LF
DB 'PLEASE CHANGE DISK OR USE ANOTHER DRIVE',CR,LF
DB 'AND REENTER:',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
;
IF NOT APPLE ;FOR APPLE SKIP NEXT AND
;SEND DEL TO CONSOLE
MOV A,M ;ECHO DISCARDED CHAR TO CONSOLE
ENDIF
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 INIT.
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
XRI MXOR
ANI MTBE
JNZ 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 BASE+1 ;GET BASE ADDRESS
LXI D,SIOOUT
DAD D
PCHL ;JUMP TO IT
;
WMCRE: POP B ;RESTORE IT
POP D
POP H
RET
ENDIF
;
IF APPLE
WMC PUSH PSW
WMCL LDA MODS
ANI MTBE
JZ WMCL
POP PSW
ANI 07FH
STA MODD
RET
ENDIF
;
;RMC - READ MODEM CHARACTER
;
; EXIT CONDITIONS:
; A - CHARACTER READ
;
;
IF PORT
RMC: IN MODS
XRI MXOR
ANI MRDA
JNZ 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
;
IF APPLE
RMC: LDA MODS
ANI MRDA
JZ RMC
RMC2: LDA MODD
ANI 07FH
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
CPI 'C'-40H ;^C MEANS ABORT
JZ GFN6
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
XRI MXOR ;INVERT HIGH-TRUE BITS
ANI MRDA ;ANY DATA AVAILABLE?
MVI A,0
JNZ MITST1
CMA
;
MITST1: ORA A
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 BASE+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
;
IF APPLE
MITEST LDA MODS
ANI MRDA
RET
ENDIF
;
;MOTEST - CHECK MODEM OUTPUT STATUS
;
IF PORT
MOTEST: IN MODS ;GET MODEM UART STATUS
XRI MXOR ;INVERT HIGH-TRUE BITS
ANI MTBE ;UART READY FOR CHARACTER?
MVI A,0
JNZ MOTST1 ;ZERO FLAG CARRIES ANSWER
CMA
;
MOTST1: ORA A ;SET ZERO FLAG IF READY
RET
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
;
IF APPLE
MOTEST LDA MODS
ANI MTBE
RET
ENDIF
;
IF MNET
LDA OVERL1+1
CPI 00H ;IF NOT UPLOAD THEN SKIP IT
RNZ
;THIS ROUTINE ALLOWS
CKXOFF: PUSH H ;MICRONET X-OFF/XON
LXI H,2751 ;TO WORK CORRECTLY
MS8: DCX H ;33 MSEC DELAY
MOV A,L
ORA H
JNZ MS8
POP H
CALL MITEST
RZ
CALL RMC2
CPI XOFF ;IF NOT X-OFF
RNZ ;THEN CONTINUE
WAITON: CALL MITEST ;ELSE WAIT FOR X-ON
JZ WAITON
CALL RMC2 ;GOT SOMETHING
CPI XON ;IS IT X-ON?
RZ ;IF SO, WE'RE THROUGH WAITING
CPI 01H ;CTL-A SAME AS X-ON
RZ
CALL WCC ;IF IT WAS NOT AN X-ON
JP WAITON ;THEN WRITE TO CONSOLE
ENDIF ;AND WAIT SOME MORE
;
;
;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