;       SCCSID = @(#)buffer.inc	6.1 90/11/17

;	SCCSID = @(#)buffer.inc	13.6 89/10/06
;

	extrn	GDT_Buffers:WORD	; Buffer segment selector in GDT


BufferContext macro srl,gr
LOCAL i
    IFNB <gr>				;; if intermediate general register
	mov	gr,GSEL GDT_Buffers
	IRP sr,<srl>
	    mov	    sr,gr
	ENDM
    ELSE
	IRP sr,<srl>			;; for sr = *first* segreg in list
	    i = 0
	    IRP r,<srl>			;;  for r = each segreg in list
		i = i + 1
		IF i EQ 1		;; if r is first in list
		    push    GSEL GDT_Buffers  ;; do push immediate
		ELSE			;; else r is second (or later) in list
		    push    sr		;; and sr contains desired value
		ENDIF
		pop	r
	    ENDM
	    EXITM			;; quit after sr = first in list
	ENDM
    ENDIF
    IRP sr,<srl>
	ASSUME	sr:NOTHING
    ENDM
endm
.xcref	BufferContext


;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
;	     C	A  V  E	 A  T	  P  R	O  G  R	 A  M  M  E  R		   ;
;									   ;
NBUFDFLT	EQU	6	; Default number of buffers in pool
NBUF_NONREMMEDIA	EQU	3; Number reserved exclus.ly for nonrem.media
; Ensure that there are some buffers for removable media as well
;
.errnz	NBUFDFLT LE NBUF_NONREMMEDIA
;

;*  Fixed fields at front of Buffer Segment

BUFSEG		STRUC
bs_MRUHead	DW	?	; Head of MRU buffer list (LRU tail)
bs_MRUTail	DW	?	; Tail of MRU buffer list (LRU head)
bs_FreeHead	DW	?	; Head of Free buffer list
bs_Handle	DW	?	; Handle for virtual memory manager
bs_nBuffers	DW	?	; Number of buffers in segment
bs_buffsize	DW	?	; Size of buffer+header, in bytes.
bs_seglimit	DW	?	; Limit for entire buffer segment.
bs_pStats	DW	?	; Offset of statistics block (for PROFILE)
bs_offRemMed	DW	?	; Minimum "legal" offset of buffer for
				; removable media
bs_MaxSec       DW      ?       ; Maximum sector size for block device drivers
bs_BigBufBase   DW      ?       ; Base of big buffers pool
bs_BigBufMap    DW      ?       ; Big buffers usage bit map (bit0 - Buf0)
bs_physBufSeg   DD      ?       ; Buffer segment Physical Address
;bs_pad   DB      (24-bs_pad) dup (?)   ; keep it DWORD aligned
BUFSEG		ENDS

BUFBASE		EQU	SIZE BUFSEG	; Offset of buffer array in segment.

;* Field definition for I/O buffer information

BUFFINFO	STRUC
buf_next	DW	?	; Pointer to next buffer in list (-1 = end)
buf_prev	DW	?	; Pointer to previous buffer in list (-1 = end)
buf_freeLink	DW	?	; Pointer to next free buffer (-1 = end)
buf_hVPB	DW	?	; serial number of volume
buf_sector	DD	?	; Sector number of buffer
; The following two items are sometimes referenced as a word
buf_wrtcnt	DB	?	; For FAT sectors, # times sector written out
buf_wrtcntinc	DW	?	;  "   "     "   , # sectors between each write
buf_flags	DB	?	; Bit 7 = 1 if buffer dirty
				; Bit 6 = 1 if buffer seen in search
				; Bit 5 = 1 if process waiting for buffer
				; Bit 4 = 1 if in use by process
				; Bit 3 = 1 if buffer is DATA
				; Bit 2 = 1 if buffer is DIR
				; Bit 1 = 1 if buffer is FAT
				; Bit 0 = 1 if buffer is in swapper pool
buf_tid		DW	?	; thread ID of buffer owner
buf_refcnt	DW	?	; number of threads using buffer for read
buf_fill	DW	?	; random debugging information
buf_pad		db	(24-buf_pad) dup (?)	; Force dword alignment.
BUFFINFO	ENDS

BUFINSIZ	EQU	SIZE BUFFINFO	; Size of structure in bytes

BUF_NIL		EQU	-1		; Nil pointer for buf_next,buf_prev

BUF_FREE	EQU	0000h		; buf_hVPB of free buffer

;*  Flag byte masks
BUF_DIRTY	EQU	10000000B
BUF_VISIT	EQU	01000000B
BUF_WANT	EQU	00100000B
BUF_BUSY	EQU	00010000B

BUF_ISDATA	EQU	00001000B
BUF_ISDIR	EQU	00000100B
BUF_ISFAT	EQU	00000010B
BUF_TYPE_0	EQU	11110000B	; AND sets type to "none"
BUF_ATTEMPTING_READ EQU  00000001B	 ; AND sets type to "none"

;* Equates for FlushBuf
fFB_FAILDISCARD		EQU	0	; discard  buf even when write fails
fFB_FAILNODISCARD	EQU	1	; don't discard when write fails
;									   ;
;	     C	A  V  E	 A  T	  P  R	O  G  R	 A  M  M  E  R		   ;
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;

SUBTTL
