;
; PROGRAM IMPORT <DEVICE><FILENAME> FROM USB
; 
;
CR	EQU	0DH
LF	EQU	0AH
;
; ISIS CALLS
;
OPEN	EQU		0
CLOSE	EQU		1
READ	EQU		3
WRITE	EQU		4
EXIT	EQU		9
ERROR	EQU		12
;
CRTS	EQU		0F7H
CRTD	EQU		067H
TTYI	EQU		0F4H
TTYO	EQU		0F4H
TTYS	EQU		0F5H
TTYC	EQU		0F5H
;
TRDY	EQU	00000001B
RRDY	EQU	00000010B
;
DTR	EQU	00000010B
;
	EXTRN	ISIS
	EXTRN	CO
	EXTRN	CI
;
	CSEG
;
IMPORT:	LXI		SP,STCKA+4	; OUR OWN USER STACK AREA
		CALL	DTRHI
;
GETFN:
		MVI		C,READ		; CALL ISIS TO READ THE COMMAND
		LXI		D,RBLK		; LINE TO BUFFER
		CALL	ISIS
		LDA		STATUS
		ORA		A
		JNZ		ERR
;
		LXI		H,BUFFER	; WE NEED A PRIVATE COPY OF <FILENAME>
		LXI		D,FILENM	; AND WITHOUT <DEVICE>
		MVI		C,128
MOVEIT:
		MOV		A,M		; MOV CHAR FROM BUFFER
		CPI		':'
		CZ		BUMPH4	; CALL TO SCOOT H OVER BY 4 TO AVOID DEVICE
		INX		H		; INR PTR
		STAX	D		; PUT IN FILENM
		INX		D		; BUMP THAT PTR
MVIT0:
		MOV		A,M		; INSPECT WHAT IS WAS
		CPI		20H		; A SPACE?
		JZ		ZERO	; IF SO, WE GOT THE WHOLE FILENAME
		CPI		CR		; A CR?
		JZ		ZERO	; IF SO, WE GOT IT
		DCR		C		; LIMIT TO 128 BYTES MOVED
		JZ		ZERO	; JUMP TO ZERO IF LIMIT
		JMP		MOVEIT	; OTHERWISE, MORE TO DO
;
ZERO:	MVI		A,0		; WE NEED A ZERO RIGHT AFTER <FILENAME>
		STAX	D		; D POINTS TO WHERE TO PUT THE 0
;
;
OPENFL:					; OPEN THE FILE THE USER WANTED
						; THIS GETS THE AFT FOR THE TEXT NAME
		MVI		C,OPEN	; OPEN FOR WRITING
		LXI		D,OBLK
		CALL	ISIS	; THIS PUT THE AFTN IN RAFT IN WBLK
		LDA		STATUS
		ORA		A
		JNZ		ERR
		JMP		LAUNCH	; READY NOW TO READ ALL BLOCKS IN THE FILE
;
; NAME OF FILE IS IN BUFFER
;
BUMPH4:	INX		H
		INX		H
		INX		H
		INX		H
		MOV		A,M
		RET
;
TYPEMSG:	DB		'TYPE ',0		; STRING USB NEEDS FOR TYPE
;
USBRD:	DB		CR,LF,'READ THE USB, NOW WRITING ISIS FILE',CR,LF,0
;
LAUNCH:
		LXI		H,TYPEMSG	; POINT TO USB COMMAND
LNCH0:
		MOV		C,M			; SEND CHAR TO USB
		CALL	CRTOUT
		INX		H			; IS NEXT A 0?
		MOV		A,M
		CPI		0
		JNZ		LNCH0		; IF ZERO, NOW SEND <FILENAME>
;
		LXI		H,FILENM	; NOW THE FILENAME
LNCH1:
		MOV		C,M			; SEND <FILENAME>
		CALL	CRTOUT
		INX		H
		MOV		A,M
		CPI		0			; END MARKER 0?
		JNZ		LNCH1
		MVI		C,CR		; GIVE THE USB THE CR TO LAUNCH COMMAND
		CALL	CRTOUT
;
		MVI		C,CR		; FIX CURSOR
		CALL	CO
		MVI		C,LF
		CALL	CO
;
;
WRTDSK:	LXI		H,DATBUFF	; GET STARTING ADDR OF DATA BUFFER
		SHLD	RDPTR		; PUT THAT IN THE READ BLOCK FOR ISIS IO
							; READY TO READ THE FIRST 512 BYTE BLOCK
NXTSCT:
		MVI		C,WRITE		; WRITE 512 BYTES OF THE FILE
		LXI		D,WBLK		; WHICH DEFINES 512 BYTES ARE TO BE WROTE
		CALL	ISIS
		LDA		STATUS
		ORA		A
		JNZ		ERR
;							; NO ERROR, DATA IS GOOD
		LHLD	ACTUAL
		MOV		A,H			; 512 IS 200H, SO H=2 IF GOT 512		
		ANI		2
		JZ		SENDUSB		
		XCHG				; WE'RE GOING TO ADD THAT TO DATPR
		LHLD	DATPTR
		DAD		D
		SHLD	DATPTR		; UPDATES POINTER INSIDE THIS LOOP
		SHLD	RDPTR		; SO NEXT READ OP KNOWS WHERE TO BUFFER
		JMP		NXTSCT		; LOOP FOR MORE SECTORS
;
GETUSB:
		XCHG				; WE NEED TO ADD THE ACTUAL HERE TOO
		LHLD	DATPTR
		DAD		D
		SHLD	BUFFTOP		; BUT THIS IS TOP OF BUFFER POINTER
							; TO TELL CRTOUT WHERE TO STOP	
		LXI		H,DISKRD	; MSG TO USER WE FINISHED WITH DISK
SX0:
		MOV		A,M	
		CPI		0
		JZ		SX1
		MOV		C,M
		CALL	CO
		INX		H
		JMP		SX0
SX1:
		LXI		H,DATBUFF	; START AT BEGINNING
MORE:
		MOV		C,M
		CALL	CRTOUT
		INX		H
		XCHG				; NEED TO USE HL
		LHLD	BUFFTOP
		XCHG				; RESTORE HL
		MOV		A,L			; ARE WE POINTING TO LAST?
		CMP		E
		JNZ		MORE		; LOOP TO SEND MORE CHARS TO USB
		MOV		A,H			; TEST ALL 16-BITS
		CMP		D
		JNZ		MORE		; BUT IF HL=DE, THEN WE'RE DONE HERE
		JMP		WRAPUP
;
;
DTRHI:	MVI		A,35H		; SETS DTR HIGH
		OUT		CRTS		; IN THE CRT USART
		MVI		A,37H
		OUT		CRTS
		MVI		A,35H
		OUT		CRTS
		RET
;
DTRLO:	IN		CRTS
		ANI		4
		JZ		DTRLO		; WAIT FOR TX EMPTY
		LXI		D,1000H
DTRLO0:						; GIVE THE USB A LITTLE TIME
		DCR		E
		JNZ		DTRLO0
		DCR		D
		JNZ		DTRLO0
;
		MVI		A,37H		; TOGGLE DTR AND USB SD0 LOW
		OUT		CRTS
		MVI		A,35H		; RETURN THEM TO HIGH
		OUT		CRTS
		RET					; TIME TO WRAP IT UP
;

WRAPUP:	CALL	DTRLO	; TOGGLE DTR AFTER WAITING FOR USART AND SLOW USB
		JMP		DONE
;
CRTOUT:				; WRITES A CHAR TO THE CRT USART AND THE USB
		IN	0F7H
		ANI	TRDY
		JZ	CRTOUT
		MOV	A,C
		OUT	0F6H
		RET
;
CRTIN:				; READS A CHAR FROM THE USB THROUGH CRT USART
		IN	0F7H
		ANI	RRDY
		JZ	CRTIN
		IN	0F6H
		RET
;
DONE:	MVI		C,CLOSE
		LXI		D,CBLK
		CALL	ISIS
DONE0:
		MVI		C,EXIT
		LXI		D,XBLK
		CALL	ISIS
ERR:
		MVI		C,ERROR
		LXI		D,EBLK
		CALL	ISIS
		JMP		DONE0
;
		DSEG
OBLK:
		DW		WAFT
		DW		BUFFER
		DW		2		; 2, FILE IS OPENED FOR OUTPUT (WRITE)
		DW		0
		DW		STATUS
;
CBLK:
CAFT:	DW		RAFT	; WE CLOSE WHAT WE OPENED, WAS ONLY 1
		DW		STATUS
;
RBLK:
OAFT:
RAFT:	DW		1		; OPEN PUTS THE AFT HERE FOR WRITE OPS
RDPTR:	DW		BUFFER	; WHERE TO PUT READ DATA
		DW		512		; READS WILL GET 4 BLOCKS, 512 BYTES
		DW		ACTUAL
		DW		STATUS
;
ACTUAL:	DW		512		; HOW MANY BYTES WERE ACTUALLY READ
;
RTOTAL:	DW		0		; RUNNING TOTAL OF BYTES TRANSFERRED
;
WBLK:					; WRITING FOR IMPORT
WAFT:	DS		2
		DW		BUFFER
WCNT:	DS		2
		DW		STATUS
;
XBLK:		DW		STATUS
EBLK:
STATUS:		DS		2
			DW		STATUS
;
BUFFER:		DS		512
;
FILENM:		DS		128
;
STCKA:		DS		4
;
DATPTR:		DW		DATBUFF	; POINTER IN DATBUFF WHERE TO WRITE
							; ENDING VALUE IS WHERE USB SHOULD STOP
;
BUFFTOP:	DW		DATBUFF+38400
;
DATBUFF:	DS		38400	; NEED A DATA BUFFER THAT CAN HOLD
							; 300 BLOCKS OF 128 BYTES
;
			END		EXPORT

