; 						>>B/S<<
;	I/OS BUFFER MANAGER
;
;	REV 2.00 RLR	01/01/80 I/OS Z/80
;	REV 2.02 KRS	03/30/80 I/OS 8080
;	REV 2.23 KRS	9/80 BIG/SMALL
;	REV 2.34 KRS	12/31/80 
;	REV 2.35 DEW	10/81 macros added 
;	REV 2.37 KRS	ADD UPDATES FROM MULTI VERSION
;	rev 2.40 sbw	Need BRELSE in type 2S system
;       rev 2.41 blc    ROMable version
;
	icl	pdef		;02.39
	icl	df		;02.39
	df.dos			;02.39
	df.cpu			;02.39
	df.sys			;02.39
;
	NAM	BFM237
;
	ENT	HDRADR,BS1ADR,GETFRE,FLSALL,FREALL	;02.23
	ENT	BS1DWRT,BS1WRT,BDWRITE			;02.23
	ENT	BS1READ,BREAD				;02.23
	ENT	BS2MBLK,BS2WRT,BS2GFRE			;02.37
	ENT	BRELSE					;02.37	;02.40
	EXT	DIRWR					;02.25
	EXT	NEGHL,DSKIO,CMPHL			;02.37
;
	ifc	sysucb=single				;02.37
	ext	?ubf1					;02.37
	elsec						;02.37
	ext	urreg					;02.37
	endc						;02.37
;
;
IOREAD	EQU	4
IOWRT	EQU	6
;
B.FLAG:	EQU	0	; FLAG WORD			 02.23
B.FWRD:	EQU	2	; FOWARD CHAIN			 02.23
B.BWRD:	EQU	4	; BACKWARD CHAIN		 02.23
B.BUF:	EQU	6	; BUFFER PTR			 02.23
B.UNIT:	EQU	8	; UNIT NUMBER			 02.23
B.BLK:	EQU	9	; BLOCK NUMBER			 02.23
B.ERR:	EQU	12	; ERROR BYTE			 02.23
B.WCNT:	EQU	14	; WORD COUNT			 02.23
;
HDRLEN	EQU	16	; 16 BYTE HEADERS
;   FLAG AND MASK FOR FLAG WORD
M$VALID	EQU	4	; BLK DATA IS VALID
M$BUSY	EQU	8	; BUF IS IN USE
M$REQD	EQU	10H	; REQUEST PENDING ON BLK
M$MODFY	EQU	20H	; BLOCK MODIFYIED
	EJECT
        ram
BUFHDR:	DW	0,0,0,0,0,0,0,0			        ;02.41
BUFER:	DS	128					;02.23
	rog						;02.23
;
;========== routines added at rev			 02.23
HDRADR:	LXI	H,BUFHDR
	RET
;
BS2MBLK:						;02.37
	CALL	BS2WRT					;02.37
	LXI	H,BUFHDR+B.UNIT				;02.37
	MOV	M,B					;02.37
	INX	H					;02.37
	MOV	M,C					;02.37
	INX	H					;02.37
	MOV	M,D					;02.37
	INX	H					;02.37
	MOV	M,E					;02.37
	MVI	A,M$VALID+M$MODFY			;02.37
	STA	BUFHDR+B.FLAG				;02.37
	POP	H					;02.37
	RET
BS2GFRE:						;02.37
GETFRE:	
	LDA	BUFHDR+B.FLAG				;02.37
	ANI	M$MODFY					;02.37
	CNZ	BS2WRT					;02.37
	XRA	A
	STA	BUFHDR+B.FLAG
BS1ADR:	LXI	H,BUFER
	RET
;
FLSALL:	XRA	A
	BR	DFLUSH					;02.35
;
FREALL:	XRA	A
	DCR	A
DFLUSH:	PUSH	PSW
	XRA	A
	STA	BUFHDR+B.FLAG
	POP	PSW
	PUSH	H
	PUSH	B
	PUSH	D
	BR	XFLUSH					;02.35
;
BS1DWRT:
BS1WRT:
BDWRITE:
BS2WRT:							;02.37
	PUSH	D
	PUSH	B
	PUSH	H
	LDA	BUFHDR+B.FLAG
	ANI	M$VALID					;02.37
	BRZ	COMREX					;02.35
	LXI	H,BUFHDR
	MVI	B,IOWRT
	CALL	TRUEIO
COMREX:	POP	H					;02.37
COMRET:	POP	B
	POP	D
	RET
;
BS1READ: PUSH	D
	PUSH	B
	CALL	BREAD
	ADRUCB	BF1					;02.37
	LXI	D,BUFER
	MOV	M,E
	INX	H
	MOV	M,D
	XCHG						;02.37
	BR	COMRET					;02.35
;
;======== end of routines added at rev			;02.23
	EJECT
XFLUSH:	MVI	A,9	; FOR FLUSH FUNCTION	02.07K
	BRZ	YHOM	;			02.07K	;02.35
	MVI	A,11	; OR JUST FREE		02.07K
YHOM:	CALL	DSKIO	; DO IT			02.07K
	POP	D	;(2A)				 02.23
	POP	B	;(2)
	POP	H	;(1)
	RET
;
;	READ BLOCK (IN CORE OR NOT)
;	RETURNS HL=BUFFER, A=ERROR
;	B=UNIT (MSB=NO INTERLEAVE), C,D,E=BLK
;
BREAD:	CALL	FDBLK
     .IF
	ORA	A	; IF NOT IN BUFFER (NO ERROR A=0)
	BRZ	.ELSE					;02.35
     .THEN		; THEN MUST GET IT
	LXI	H,BUFHDR				;02.23
	PUSH	H		; SAVE HDR
	PUSH	D
	LXI	D,B.UNIT
	DAD	D
	POP	D		; NOW AT UNIT
	MOV	M,B
	INX	H		; NOW AT BLK
	MOV	M,E
	INX	H		; NMOW AT BLK+1
	MOV	M,D
	INX	H		; NOW AT BLK+2
	MOV	M,C
	POP	H		; HDR ADDR BACK
	MOV	A,M
	ORI	M$VALID		; NOW VALID
	MOV	M,A
	PUSH	B
	MVI	B,IOREAD	; READ
	CALL	TRUEIO
	POP	B
     .ENDIF
	lxi	h,bufer					;02.23
	RET
	EJECT
;
;	RELEASE BUFFER (MAKE NOT BUSY)
;	HL=BUFFER
;
BRELSE:
	RET
;
;
;  DO IO THAT IS REQUESTED
;
TRUEIO:	PUSH	H		; HEADER ADDRESS
	PUSH	D
	LXI	D,B.UNIT
	DAD	D
	POP	D
	MOV	A,M
	RLC			; TO LSB
	ANI	1		; AND ONLY LSB
	XRI	1		; COMPL INTERLEAVED FLAG
	ADD	B		; COMMAND
	PUSH	AF		; SAVE COMMAND
	MOV	A,M		; UNIT AGAIN
	ANI	7FH		; CLEAR INTERLEAVED FLAG
	MOV	B,A
	INX	H		; BLK
	MOV	E,M
	INX	H		; BLK+1
	MOV	D,M
	INX	H		; BLK+2
	MOV	C,M
;
;       six lines are replaced with
;
        lxi     h,bufer                                 ;02.41
;
	POP	AF
	CALL	DSKIO		; RETURNS A=ERROR (B+C TOO)
	POP	H		; HEADER ADDRESS
	RET
FDBLK:	LXI	H,BUFHDR				;02.23
     .DO
	PUSH	H
	MOV	A,M		; B.FLAG
	ANI	M$VALID
	BRZ	.NEXT					;02.35
     ; IF VALID & MY BLOCK
	PUSH	D
	LXI	D,B.UNIT
	DAD	D
	POP	D
	MOV	A,B		; THIS UNIT
	CMP	M
	BRNZ	.NEXT		; WRONG UNIT		;02.35
	INX	H
	MOV	A,E		; BLK
	CMP	M
	BRNZ	.NEXT		; WRONG BLOCK		;02.35
	INX	H
	MOV	A,D		; BLK+1
	CMP	M
	BRNZ	.NEXT		; WRONG BLOCK		;02.35
	INX	H
	MOV	A,C		; BLK+2
	CMP	M
	BRNZ	.NEXT		; WRONG BLOCK		;02.35
	POP	H
     ; IF THEN FOUND IT
	XRA	A
	RET
     .NEXT		; TRY NEXT ONE
	POP	H
	MVI	A,-1	; HL=OLDEST
	RET
	END
