;	TITLE	'SEND - SEND CP/M FILE OVER SERIAL LINK'
;	AUTHOR:	LAWRENCE E. HUGHES, MYCROFT LABS
;	DATE:	JUNE 6, 1980
 
;	PORT LOCATIONS AND STATUS BITS FOR COMMUNICATIONS PORT
;	NOTE: SEE ROUTINES INIT, RACL AND WACL AT END OF PROGRAM
;	PORTS FOR SIERRA DATA SCIENCES SBC-100 SIOB

DATA	EQU	??H		;SERIAL PORT DATA
STAT	EQU	??H		;SERIAL PORT STATUS
RDA	EQU	??H		;READ DATA AVAIL. FLAG
TBE	EQU	??H		;TRANS. BUFFER EMPTY FLAG
 
;	DEVICE INDEPENDENT EQUATES
 
BDOS	EQU	0005H		;BDOS ENTRY POINT
WCCFC	EQU	02		;WRITE CONSOLE CHARACTER
WCBFC	EQU	09		;WRITE CONSOLE BUFFER
OPNFC	EQU	15		;OPEN FILE
CLSFC	EQU	16		;CLOSE FILE
SRFFC	EQU	17		;SEARCH FIRST
SRNFC	EQU	18		;SEARCH NEXT
RSRFC	EQU	20		;READ SEQUENTIAL RECORD
 
SFCB	EQU	005CH		;SYSTEM FILE CONTROL BLOCK
FN	EQU	01		;FILE NAME FIELD
FT	EQU	09		;FILE TYPE FIELD
EX	EQU	12		;EXTENT NUMBER FIELD
NR	EQU	32		;NEXT RECORD FIELD
 
DBUF	EQU	0080H		;SYSTEM DISK BUFFER
 
SOH	EQU	01H		;START OF HEADER
STX	EQU	02H		;START OF TEXT
EOT	EQU	04H		;END OF TRANSMISSION
ENQ	EQU	05H		;ENQUIRE
ACK	EQU	06H		;ACKNOWLEDGE
BEL	EQU	07H		;BELL
LF	EQU	0AH		;LINE FEED
CR	EQU	0DH		;CARRIAGE RETURN
NAK	EQU	15H		;NEGATIVE ACKNOWLEDGE
ETB	EQU	17H		;END OF TRANSMISSION BLOCK
CAN	EQU	18H		;CANCEL
 
EOS	EQU	'$'		;END OF STRING
 
	ORG	100H
SEND:	LXI	H,0		;SAVE SYSTEM SP
	DAD	SP
	SHLD	OLDSP
	LXI	SP,STACK+64
	LXI	D,MSG0		;PRINT HEADING
	CALL	WASC
	CALL	INIT		;INITIALIZE LINK PORT
	LXI	D,SFCB		;POINT TO AFN
	CALL	GETFL		;GET FILE LIST
	LDA	FLCNT		;JUMP IF AT LEAST ONE FOUND
	ORA	A
	JNZ	SEND0
	LXI	D,MSG1		;PRINT 'FILE(S) NOT FOUND'
	CALL	WASC

SEND0:	LHLD	FLPTR		;HL = PTR TO NEXT NAME
	LXI	D,SFCB		;DE = DESTINATION ADDR
	MVI	B,16		;# OF BYTES TO MOVE
	CALL	MOVE
	SHLD	FLPTR		;UPDATE FILE LIST PTR
SEND2:	IN	STAT		;AWAIT ACK FROM RECEIVER
	ANI	RDA
	JNZ	SEND2A
	MVI	A,ENQ		;SEND ANOTHER ENQ
	CALL	WACL
	JMP	SEND2
SEND2A:	IN	DATA		;DISCARD ACK
	LDA	FLCNT		;EXIT IF FILELIST COUNT = 0
	ORA	A
	JZ	SENDX
SEND1:	XRA	A		;OPEN FILE
	STA	SFCB+EX
	LXI	D,SFCB
	CALL	OPEN
	XRA	A		;REWIND FILE
	STA	SFCB+NR
	MVI	A,SOH		;SEND SOH
	CALL	WACL
	LXI	H,SFCB+1	;FWA OF FILENAME
	MVI	B,11		;FILENAME LENGTH
	CALL	SMSG		;SEND FILENAME
	JC	SEND8		;ABORT ON ERROR
	LXI	D,MSG6		;PRINT 'NOW SENDING'
	CALL	WASC
	LXI	H,SFCB+1	;PRINT FILENAME
	MVI	B,11
	CALL	PMSG
	CALL	WEOLC
SEND6:	LXI	D,SFCB		;READ NEXT RECORD
	CALL	READ
	ORA	A		;JUMP IF OK
	JZ	SEND3
	CPI	1		;JUMP IF EOF
	JZ	SEND7
	LXI	D,MSG2		;PRINT 'FILE READ ERROR'
	CALL	WASC
	MVI	A,CAN		;ABORT OTHER END
	CALL	WACL
	JMP	SENDX		;EXIT
SEND3:	MVI	A,STX		;SEND STX
	CALL	WACL
	LXI	H,DBUF		;SEND RECORD
	MVI	B,128		;RECORD LENGTH
	CALL	SMSG		;SEND MESSAGE
	JC	SEND8		;ABORT ON ERROR
	JMP	SEND6
SEND7:	MVI	A,ETB		;SEND ETB
	CALL	WACL
	LXI	D,SFCB		;CLOSE FILE
	CALL	CLOSE
	LXI	H,FLCNT		;DECREMENT FILELIST COUNT
	DCR	M
	JMP	SEND0		;LOOP
	JMP	SENDX
SEND8:	LXI	D,MSG7		;PRINT 'ABORTED'
	CALL	WASC
SENDX:	MVI	A,EOT		;SEND EOT
	CALL	WACL
	LXI	D,MSG5		;PRINT 'ALL FILES SENT'
	CALL	WASC
	LHLD	OLDSP		;EXIT TO DOS
	SPHL
	RET
 
GETFL:	LXI	H,FLIST		;FLPTR = FWA OF FILELIST
	SHLD	FLPTR
	XRA	A		;FLCNT = 0
	STA	FLCNT
	PUSH	D
GETFL1:	CALL	SRCHF		;SEARCH FOR FIRST OCCURANCE
	CPI	255		;JUMP IF NONE FOUND
	JZ	GETFL3
GETFL2:	ANI	03H		;DE = DBUG + 32 * (A AND 3)
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	MOV	L,A
	MVI	H,0
	LXI	D,DBUF
	DAD	D
	XCHG
	LHLD	FLPTR		;HL = FILE LIST PTR
	XCHG
	MVI	B,16		;B = # OF BYTES TO MOVE
	CALL	MOVE
	XCHG
	SHLD	FLPTR		;UPDATE FILELIST POINTER
	LXI	H,FLCNT		;INCREMENT FILELIST COUNT
	INR	M
	POP	D
	PUSH	D
	CALL	SRCHN		;SEARCH FOR NEXT OCCURANCE
	CPI	255		;LOOP IF ANOTHER FOUND
	JNZ	GETFL2
GETFL3:	POP	D
	LXI	H,FLIST		;RESET FILELIST POINTER
	SHLD	FLPTR
	RET
 
PMSG:	MOV	A,M
	INX	H
	CALL	WACC
	DCR	B
	JNZ	PMSG
	RET
 
WEOLC:	MVI	A,CR
	CALL	WACC
	MVI	A,LF
	JMP	WACC
 
WACC:	PUSH	H
	PUSH	D
	PUSH	B
	MOV	E,A
	MVI	C,WCCFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
MOVE:	MOV	A,M
	INX	H
	STAX	D
	INX	D
	DCR	B
	JNZ	MOVE
	RET
 
SRCHF:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,SRFFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
SRCHN:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,SRNFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
SMSG:	MVI	C,0		;CLEAR CHECKSUM
	PUSH	H		;SAVE FWA OF MESSAGE
	PUSH	B		;SAVE MESSAGE LENGTH
SMSG1:	MOV	A,M		;FETCH NEXT CHAR
	INX	H
	CALL	WACL		;SEND IT
	DCR	B		;DECREMENT COUNT
	JNZ	SMSG1		;LOOP UNTIL ZERO
 	XRA	A		;SEND CHECKSUM
	SUB	C
	CALL	WACL
	CALL	RACL		;AWAIT RESPONSE
	CPI	ACK		;JUMP IF ACK
	JZ	SMSG4
	CPI	NAK		;JUMP IF NOT NAK
	JNZ	SMSG2
	POP	B		;RESTORE FWA AND COUNT
	POP	H
	JMP	SMSG		;SEND IT AGAIN
SMSG2:	CPI	CAN		;JUMP IF CAN
	JZ	SMSG3
	LXI	D,MSG3		;PRINT 'UNKNOWN CODE'
	CALL	WASC
SMSG3:	POP	B		;ERROR EXIT
	POP	H
	STC
	RET
SMSG4:	POP	B		;NORMAL EXIT
	POP	H
	STC
	CMC
	RET
 
WASC:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,WCBFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
OPEN:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,OPNFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
CLOSE:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,CLSFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
READ:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,RSRFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
 
;		FOLLOWING DEVICE DEPENDENT CODE IS FOR 
; 	     SIERRA DATA SCIENCES SBC-100 SIO-B (Z80-DART)
;	change the following to match your computer - this is for
;	Z80 sio or  dart
;	INIT - ROUTINE TO INITIALIZE COMMUNICATIONS PORT

INIT:	MVI	A,47H
	OUT	89H
	MVI	A,0DH		;9600 BAUD
	OUT	89H		;TO CTC CHANNEL 1  
INITP:	LXI	H,INITS
INIT1:	MOV	A,M
	INX	H
	CPI	'$'
	JZ	GBBL
	NOP!NOP
	OUT	STAT
	JMP	INIT1
 
INITS:	DB	4,68,3,193,5,234,1,4,'$'

GBBL:	IN	DATA
	IN	DATA
	IN	DATA
	RET
	 
;	RACL - READ ASCII CHAR FROM LINK (DO NOT STRIP BIT 7)

RACL:	IN	STAT
	ANI	RDA
	JZ	RACL
	IN	DATA
	RET
 
;	WACL - WRITE ASCII CHAR TO LINK

WACL:	PUSSS
D
0E WESESESE FAPISSSSSS
SSISSSSSSSSSSSSSSSSSSSSSSSSSSSSSSUAP:
	M

D
0ES

E
E
WSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPR
A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	A	;	
IB
BSht 1982, Mycroft labs inc.',CR,LF,LF
	DB	'	  (put your computer name here)     '
	DB	'	SIO-B - 9600 BAUD',19H,CR,LF,LF,LF,EOS
MSG1:	DB	'**** FILE(S) NOT FOUND ****',CR,LF,EOS
MSG2:	DB	'**** FILE READ ERROR! ****',CR,LF,EOS
MSG3:	DB	'**** UNKNOWN RESPONSE ****',CR,LF,EOS
MSG5:	DB	 CR,LF,LF,'	DONE',CR,LF,BEL,EOS
MSG6:	DB	'NOW SENDING . . .   ',EOS
MSG7:	DB	'**** ABORTED ****',CR,LF,BEL,EOS
 
OLDSP:	DS	2		;SYSTEM SP
STACK:	DS	64		;LOCAL STACK
FLCNT:	DS	1		;FILE LIST COUNT
FLPTR:	DS	2		;FILE LIST POINTER
FLIST:	DS	16*64		;FILE LIST

 END
SEND6
SEND7:	MVI	A,ETB		;SEND ETB
	CALL	WACL
	LXI	D,SFCB		;CLOSE FI