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
/
CPMUG019.ARK
/
LINK73.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
17KB
|
534 lines
; LINK - SUPPORT COMMUNICATIONS LINK WITH CYBER
;
; L.E. HUGHES EDCAM JULY, 1977
; BDOS ENTRY POINT AND FUNCTION CODES
BDOS EQU 0005H
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
; DEFAULT FCB AND FIELD DEFINITIONS
FCB EQU 5CH
FN EQU 1 ;FILE NAME FIELD (REL)
FT EQU 9 ;FILE TYPE FIELD (REL)
NR EQU 32 ;NEXT RECORD FIELD (REL)
DBUF EQU 80H ;DEFAULT DISK BUFFER ADDRESS
; ASCII CONTROL CHARACTERS
LF EQU 012Q ;LINE FEED
CR EQU 015Q ;CARRIAGE RETURN
DEL EQU 177Q ;DELETE
; I/O PORT ADDRESSES
COND EQU 012H ;CONSOLE DATA PORT
CONS EQU 013H ;CONSOLE STATUS PORT
MODD EQU 014H ;MODEM DATA PORT
MODS EQU 015H ;MODEM STATUS PORT
CONT EQU 018H ;SIO CONTROL PORT FOR MODEM
; STATUS PORT BIT DEFINITIONS
TBE EQU 001Q ;TRANSMIT BUFFER READY FOR ANOTHER BYTE
RDA EQU 002Q ;READ DATA AVAILABLE
; MAIN PROGRAM
ORG 100H
LINK: LXI H,0 ;SAVE OLD STACK POINTER
DAD SP
SHLD OLDSP
LXI SP,STACK+64 ;CREATE LOCAL STACK
LINKM: IN CONT ;CHECK CTS TO SEE IF NEED INTERNAL RESET
ANI 080H ;CTS INVERTED AT THIS PORT
JZ LINKC ;DONOT NEED RESET
LXI H,APPS ;INITIALIZE PORTS
MVI B,5
LINK1: MOV A,M
INX H
OUT MODS
DCR B
JNZ LINK1
IN MODD
IN MODD
MVI A,047Q ;SEND MODEM RTS AND DTR
OUT MODS ; AND ENABLE RECEIVER AND TRANSMITTER
LINKC: LXI H,APPS ;INITIALIZE PORTS
MVI B,5
LINKD: MOV A,M
INX H
OUT CONS
DCR B
JNZ LINKD
IN COND ;CLEAR USART READ BUFFERS
IN COND
MVI A,047Q ;SEND CONSOLE CTS AND DSR,
OUT CONS ; AND ENABLE RECEIVER AND TRANSMITTER
LINK2: 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
CALL WCCR ;WRITE CR/LF TO CONSOLE
MVI A,7 ;RING BELL ON CONSOLE, TO LET
CALL WCC ; CLONE KNOW WE'RE READY
; MAIN LOOP
LINK3: IN CONS ;JUMP IF NO DATA FROM CONSOLE
ANI RDA
JZ LINK4
IN COND ;ELSE READ CONSOLE DATA
ANI 177Q ;CALL PCC IF CONTROL CHAR
CPI 40Q
CC PCC
JC LINK4 ;JUMP IF PCC HANDLED CHAR
ORI 200Q ;ELSE SET VALID DATA BIT
STA INCH ;AND STORE IN INPUT CHAR BUFFER
LINK4: IN CONS ;JUMP IF CONSOLE XMIT BUFFER BUSY
ANI TBE
JZ LINK5
LDA OUTCH ;JUMP IF NO DATA FOR CONSOLE
ORA A
JP LINK5
ANI 177Q ;ELSE DISCARD VALID DATA BIT
OUT COND ; AND OUTPUT CHAR TO CONSOLE
XRA A ; THEN CLEAR OUTPUT CHAR BUFFER
STA OUTCH
LINK5: IN MODS ;JUMP IF NO DATA FROM MODEM
ANI RDA
JZ LINK6
IN MODD ;ELSE READ MODEM DATA
ANI 177Q ;DISCARD PARITY BIT
CALL SAVE ;SAVE CHAR IN TEXT BUFFER IF FLAG ON
ORI 200Q ;SET DATA VALID BIT
STA OUTCH ;STORE IN OUTPUT CHAR BUFFER
LINK6: IN MODS ;JUMP IF MODEM XMIT BUFFER BUSY
ANI TBE
JZ LINK7
LDA INCH ;JUMP IF NO DATA FOR MODEM
ORA A
JP LINK7
ANI 177Q ;ELSE DISCARD VALID DATA BIT
OUT MODD ; AND OUTPUT CHAR TO MODEM
XRA A ; THEN CLEAR INPUT CHAR BUFFER
STA INCH
LINK7: JMP LINK3 ;END OF MAIN LOOP
; PCC - PROCESS CONTROL CHARACTER
PCC: CPI 'X'-100Q ;JUMP IF NOT CONTROL-X
JNZ PCC1
LHLD OLDSP ;ELSE CLEAN UP ACT AND GO HOME
SPHL
RET
PCC1: CPI 'S'-100Q ;JUMP IF NOT CONTROL-S
JNZ PCC2
CALL STF ;SEND TEXT FILE TO MODEM
STC ;TELL LINK TO IGNORE THIS CHARACTER
RET
PCC2: CPI 'R'-100Q ;JUMP IF NOT CONTROL-R
JNZ PCC3
MVI A,1 ;TURN ON TEXT SAVE FLAG
STA FLAG
STC
RET
PCC3: CPI 'Q'-100Q ;JUMP IF NOT CONTROL-Q
JNZ PCC4
XRA A ;TURN OFF TEXT SAVE FLAG
STA FLAG
CALL WTB ;WRITE TEXT BUFFER TO DISK
LXI H,TBUF ;CLEAR TEXT BUFFER
SHLD PTR
LXI H,0
SHLD SIZE
STC
RET
PCC4: STC ;LET LINK HANDLE ALL OTHER CONTROL CODES
CMC
RET
; 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
XRA A ;ELSE REWIND FILE AND GET ON WITH IT
STA FCB+NR
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'-100Q ;JUMP IF END-OF-FILE CHARACTER
JZ STF5
CPI LF ;IGNORE LINE FEEDS
JZ STF4
CALL WMC ;WRITE CHARACTER TO MODEM
CALL WCC ;WRITE CHARACTER TO CONSOLE
CPI CR ;JUMP IF NOT CARRIAGE RETURN
JNZ STF4
STF3: CALL RMC ;AWAIT LINE FEED FROM MODEM
CPI LF
JNZ STF3
CALL WCC ;ECHO LINE FEED TO CONSOLE
STF4: DCR C ;LOOP THRU REST OF DBUF
JNZ STF2
JMP STF1 ;GO GET NEXT RECORD FROM DISK
STF5: CALL CLOSE ;CLEAN UP ACT AND GO HOME
RET
STF6: LXI H,STFS1 ;PRINT 'FILE NAME ERROR'
CALL WCS
RET
STF7: LXI H,STFS2 ;PRINT 'FILE NOT FOUND'
CALL WCS
RET
STFS1: DB 'FILE NAME ERROR',CR,LF,0
STFS2: DB 'FILE NOT FOUND',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
PUSH H
LHLD PTR
MOV M,A
INX H
SHLD PTR
LHLD SIZE ;SIZE = SIZE + 1
INX H
SHLD SIZE
POP H
RET
; 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
CALL DELT ;DELETE OLD FILE, IF ANY
CALL MAKE ;MAKE NEW FILE
XRA A ;REWIND FILE
STA FCB+NR
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'-100Q ;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
RET
WTB5: LXI H,WTBS1 ;PRINT 'TEXT BUFFER EMPTY'
CALL WCS
RET
WTB6: LXI H,WTBS2 ;PRINT 'FILE NAME ERROR'
CALL WCS
RET
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
IN CONS
ANI TBE
JZ $-4
POP PSW
OUT COND
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'-100Q ;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: IN CONS
ANI RDA
JZ $-4
IN COND
ANI 177Q
RET
; WMC - WRITE MODEM CHARACTER
;
; ENTRY CONDITIONS
; A - CHARACTER TO WRITE
WMC: PUSH PSW
IN MODS
ANI TBE
JZ $-4
POP PSW
OUT MODD
RET
; RMC - READ MODEM CHARACTER
;
; EXIT CONDITIONS:
; A - CHARACTER READ
RMC: IN MODS
ANI RDA
JZ $-4
IN MODD
ANI 177Q
RET
; GFN - GET FILE NAME
GFN: CALL WCCR
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 141Q ;IF LC, CONVERT TO UC
JC $+5
SUI 40Q
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 141Q ;IF LC, CONVERT TO UC
JC $+5
SUI 40Q
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: STC ;CLEAR ERROR FLAG AND RETURN
CMC
RET
GFN6: STC ;SET ERROR FLAG AND RETURN
RET
GFNS1: DB '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
; DATA AREA
APPS: DB 000Q,000Q,000Q,100Q,156Q
INCH: DS 1 ;INPUT CHAR BUFFER (TO CYBER)
OUTCH: DS 1 ;OUTPUT CHAR BUFFER (FROM CYBER)
OLDSP: DS 2 ;OLD STACK POINTER
STACK: DS 64 ;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