Compucolor.org – Virtual Media

Listing of file='FILEIO.MAC;01' on disk='vmedia/tiny_c_v3.0-sector.ccvf'

; @@@@ COMPUCOLOR I/O ROUTINES @@@@
;
;	FCS ROUTINES
;
	EXTRN OUTCH,EMESS,PFSPC,OPEN,RWSEQI,INSEQO,CLSEQO
	EXTRN ADHLA,SUBHD,CMPHD,CMPDH,NEGH,HLNEG
	EXTRN GAREC,PTREC,RBLKI,WBLKI,GTBYT

FOPT	EQU	0
FATR	EQU	1
FNAM	EQU	2
FTYP	EQU	8
FVER	EQU	11
FSBK	EQU	12
FSIZ	EQU	14
FLBC	EQU	16
FLAD	EQU	17
FSAT	EQU	19
FSPR	EQU	21
FDBK	EQU	22
FDEN	EQU	23
FAUX	EQU	24
FHAN	EQU	26
FFCN	EQU	28
FDRV	EQU	29
FBLK	EQU	30
FBUF	EQU	32
FXBC	EQU	34
FPTR	EQU	36
FPBE	EQU	38

FILSIZE	EQU	256	; NORMAL FILE BUFFER SIZE

CR	EQU	13
LF	EQU	10

	EXTRN	DSUB,MOVE,PN,PX,TOPTOI
;
;	OPEN A FILE
;
	ENTRY	FOPEN

FOPEN:	CALL	SETFPB
	DCR	A
	MOV	M,A
	STA	IOFLAG
	XCHG		; DE:=#FPB
	POP	H	; HL:=#FILE SPECIFIER
	LXI	B,DEFAULT
	CALL	PFSPC	; PARSE FILE SPEC.
	JC	FERR	; ERROR?
	LHLD	FPBCUR	; HL:=#FPB
	CALL	OPEN	; OPEN FILE
	JC	FERR	; ERROR?
	PUSH	H	; SAVE FPB
	LXI	D,FBUF
	DAD	D
	XCHG
	LHLD	FPBPTR	; MOVE BUFFER INFO INTO FPB
	LXI	B,-4
	CALL	MOVE
	POP	H	; RESTORE FPB
	LDA	IOFLAG	; CHECK READ OR WRITE
	ORA	A	; READ?
	JZ	FOPEN1	; YES
	CALL	INSEQO	; NO, INITIALIZE FOR WRITE
	JMP	FCHECK

FOPEN1:	CALL	RWSEQI	; INITIALIZE FOR READ
	JMP	FCHECK
;
;	READ A RECORD
;
	ENTRY	FREAD

FREAD:	CALL	SETFPB
	POP	B	; BC:=#BUFFER
	PUSH	B
	LXI	D,256	; DE:=LENGTH OF BUFFER
	CALL	GAREC	; READ RECORD
	POP	H
FREAD1:	JNC	FOK	; NO ERRORS?
	JNZ	FERR	; NON-EOF ERROR?
	SBB	A	; A:=-1
	RET
;
;	WRITE A RECORD
;
	ENTRY	FWRITE

FWRITE:	CALL	SETFPB
	POP	B	; BC:=#BUFFER
	CALL	DSUB	; DE:=LENGTH
	INX	D
	CALL	PTREC	; PUT RECORD
FCHECK:	JC	FERR	; ERROR?
FOK:	XRA	A	; A:=0, CARRY:=0
	RET

FERR:	CALL	PX
	DB	CR,LF,0
	CALL	EMESS	; CALL FCS ERROR MESSAGE
	CALL	PX
	DB	'ON UNIT ',0
FERR1:	LHLD	IOUNIT
	XCHG
	CALL	PN
	CALL	PX
	DB	CR,LF,0
	XRA	A
	INR	A
	RET
;
;	CLOSE FILE
;
	ENTRY	FCLOSE

FCLOSE:	CALL	SETFPB
	MOV	A,M
	ORA	A
	CNZ	CLSEQO	; CLOSE IF WRITING
	POP	H
	JMP	FCHECK
;
;	GET SINGLE BYTE
;
	ENTRY	GBYTE

GBYTE:	CALL	SETFPB
	CALL	GTBYT
	MOV	E,A	; STORE BYTE
	POP	H
	JMP	FREAD1
;
;	READ BLOCKS
;
	ENTRY	BREAD

BREAD:	CALL	SETFPB
	CALL	SETBLK	; SETUP FPB
	CALL	RBLKI
BREAD1:	POP	H	; RESTORE HL
	JC	FERR	; ERROR?
	PUSH	H	; NO, DE:=ACTUAL TRANSFER SIZE
	LHLD	FPBCUR
	LXI	D,FAUX
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	POP	H
	JMP	FOK
;
;	WRITE BLOCKS
;
	ENTRY	BWRITE

BWRITE:	CALL	SETFPB
	CALL	SETBLK	; SET FPB
	CALL	WBLKI
	JMP	BREAD1
;
;	GET FPB ADDR
;
	ENTRY	FADDR

FADDR:	CALL	SETFPB
	RET

	ENTRY	SETFPB

SETFPB:	XTHL
	PUSH	H	; SNEAK HL ONTO STACK
	PUSH	PSW
	MOV	A,C
	STA	IOUNIT	; SAVE I/O UNIT #
	DCR	A
	JM	SETERR	; TOO LOW?
	CPI	NUNITS	; TOO HIGH
	JP	SETERR	; YES
	ADD	A	; CONVERT TO 3 WORD RECORD OFFSET
	MOV	B,A
	ADD	B
	ADD	B
	LXI	H,FPBTBL
	CALL	ADHLA	; HL:=# OF # OF FPB
	PUSH	D
	MOV	E,M
	INX	H
	MOV	D,M
	INX	H
	SHLD	FPBPTR	; STORE POINTER TO BUFFER INFO
	XCHG		; HL:=#FPB
	SHLD	FPBCUR
	POP	D
	POP	PSW
	RET		; NORMAL RETURN

SETERR:	CALL	PX
	DB	CR,LF,'ILLEGAL UNIT ',0
	POP	PSW
	POP	H	; POP RETURN
	POP	H	; POP THE HIDDEN HL
	JMP	FERR1
;
;	SETUP FPB
;
	ENTRY	SETBLK

SETBLK:	PUSH	H
	LXI	D,FBLK
	DAD	D
	LXI	D,BLOCKN
	XCHG
	LXI	B,-6
	CALL	MOVE
	POP	H
	RET
;
;	SAVE PARAMS IN BLOCKN
;
	ENTRY	POPOFF

POPOFF:	CALL	TOPTOI
	PUSH	D	; UNIT
	CALL	TOPTOI	; BLOCK #
	XCHG
	SHLD	BLOCKN
	CALL	TOPTOI	; LAST BYTE
	PUSH	D
	CALL	TOPTOI	; FIRST BYTE
	POP	H
	CALL	SUBHD
	INX	H
	SHLD	XBC	; LENGTH
	XCHG
	SHLD	BUF	; BASE ADDR.
	POP	B	; UNIT
	RET
;
; DATA STRUCTURES
;

	PUBLIC DEFAULT,FPBCUR,FPBPTR,IOFLAG,IOUNIT
	PUBLIC BLOCKN,BUF,XBC

DEFAULT:DB	'C  '
FPBCUR:	DW	0	; CURRENT FPB ADDRESS
FPBPTR:	DW	0	; POINTER TO BUFFER INFO.
IOFLAG:	DW	0	; READ/WRITE FLAG
IOUNIT:	DW	0	; I/O UNIT #
BLOCKN:	DW	0	; BLOCK #
BUF:	DW	0	; BLOCK BUFFER
XBC:	DW	0	; BLOCK SIZE

FPBTBL:	DW	FPB1,FPBF1,FPBF2-FPBF1
	DW	FPB2,FPBF2,FPBF3-FPBF2
	DW	FPB3,FPBF3,FPBF4-FPBF3
	DW	FPB4,FPBF4,FPBF5-FPBF4
	DW	FPB1,FPBF1,FPBF5-FPBF1

NUNITS	EQU	($-FPBTBL)/6

	PUBLIC LOADUNIT

LOADUNIT: DB	NUNITS

FPB1:	DS	FPBE
FPB2:	DS	FPBE
FPB3:	DS	FPBE
FPB4:	DS	FPBE

FPBF1:	DS	FILSIZE
FPBF2:	DS	FILSIZE
FPBF3:	DS	FILSIZE
FPBF4:	DS	FILSIZE
FPBF5	EQU	$

	END