]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/BUF.ASM
2 ; buffer management for MSDOS
7 CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
19 i_need LastBuffer
,DWORD
23 SUBTTL SETVISIT
,SKIPVISIT
-- MANAGE BUFFER SCANS
25 procedure SETVISIT
,near
26 ASSUME
DS:NOTHING
,ES:NOTHING
31 ; Set up a scan of I/O buffers
34 ; NOTE: This pre-scan is needed because a hard disk error
35 ; may cause a scan to stop in the middle leaving some
36 ; visit flags set, and some not set.
37 ; DS:DI Points to [BUFFHEAD]
38 ; No other registers altered
53 ASSUME
DS:NOTHING
,ES:NOTHING
56 ; DS:DI Points to a buffer
58 ; Skip visited buffers
60 ; DS:DI Points to next unvisited buffer
61 ; Zero is set if skip to LAST buffer
62 ; No other registers altered
74 SUBTTL SCANPLACE
, PLACEBUF
-- PUT A BUFFER BACK
IN THE POOL
76 procedure ScanPlace
,near
77 ASSUME
DS:NOTHING
,ES:NOTHING
82 ; Save scan location and call PLACEBUF
84 ; DS:DI Points to saved scan location
85 ; SI destroyed, other registers unchanged
88 LES SI,[DI.NEXTBUF
] ; Save scan location
91 POP DS ; Restore scan location
99 procedure PLACEBUF
,NEAR
100 ASSUME
DS:NOTHING
,ES:NOTHING
103 ; DS:DI points to buffer
105 ; Remove buffer from queue and re-insert it in proper place.
106 ; If buffer doesn't go at end, and isn't free, decrement
108 ; NO registers altered
110 ; DS:SI -- Curbuf, current buffer in list
111 ; ES:DI -- Buf, buffer passed as argument
112 ; BP:CX -- Pointsave, saved Buf.nextbuf
113 ; DX:BX -- Lastbuf, previous buffer in list
114 ; AL -- Inserted, Buf has been inserted
115 ; AH -- Removed, Buf has been removed
120 XOR AX,AX ; Inserted = Removed = FALSE
122 MOV BP,ES ; Pointsave = Buf.nextbuf
124 MOV ES,SI ; Buf is ES:DI
125 LDS SI,[BUFFHEAD
] ; Curbuf = HEAD
126 CALL POINTCOMP
; Buf == HEAD?
128 CMP CX,-1 ; Buf is LAST?
129 JZ NRETJ
; Only one buffer, nothing to do
130 MOV WORD PTR [BUFFHEAD
],CX
131 MOV WORD PTR [BUFFHEAD
+2],BP ; HEAD = Pointsave
132 INC AH ; Removed = TRUE
134 MOV SI,CX ; Curbuf = HEAD
136 MOV BL,ES:[DI.BUFPRI
]
139 NEWHEAD: ; If Buf.pri < HEAD.pri
140 MOV WORD PTR ES:[DI.NEXTBUF
],SI
141 MOV WORD PTR ES:[DI.NEXTBUF
+2],DS ; Buf.nextbuf = HEAD
142 MOV WORD PTR [BUFFHEAD
],DI
143 MOV WORD PTR [BUFFHEAD
+2],ES ; HEAD = Buf
144 INC AL ; Inserted = TRUE
146 JNZ NRET
; If Removed == TRUE
155 MOV WORD PTR [SI.NEXTBUF
],CX ; If Curbuf.nextbuf == buf
156 MOV WORD PTR [SI.NEXTBUF
+2],BP ; Curbuf.nextbuf = Pointsave
157 INC AH ; Removed = TRUE
159 JNZ SHUFFLE
; If Inserted == TRUE
163 PUSH CX ; If NOT Inserted
164 MOV CL,ES:[DI.BUFPRI
]
168 PUSH DS ; If Buf.pri < Curbuf.pri
170 MOV WORD PTR [BX.NEXTBUF
],DI
171 MOV WORD PTR [BX.NEXTBUF
+2],ES ; Lastbuf.nextbuf = Buf
173 MOV WORD PTR ES:[DI.NEXTBUF
],SI
174 MOV WORD PTR ES:[DI.NEXTBUF
+2],DS ; Buf.nextbuf = Curbuf
175 INC AL ; Inserted = TRUE
177 JNZ SHUFFLE
; If Removed == TRUE
180 MOV DX,DS ; Lastbuf = Curbuf
181 CMP WORD PTR [SI.NEXTBUF
],-1
183 LDS SI,[SI.NEXTBUF
] ; Curbuf = Curbuf.nextbuf
185 ISLAST: ; If Curbuf is LAST
186 MOV WORD PTR [SI.NEXTBUF
],DI
187 MOV WORD PTR [SI.NEXTBUF
+2],ES ; Curbuf.nextbuf = Buf
188 MOV WORD PTR ES:[DI.NEXTBUF
],-1
189 MOV WORD PTR ES:[DI.NEXTBUF
+2],-1 ; Buf is LAST
197 CMP [DI.BUFPRI
],FREEPRI
210 CMP CX,-1 ; Buf is LAST?
211 JZ NRET
; Buffer already last
212 MOV BP,ES ; Pointsave = Buf.nextbuf
214 POP ES ; Buf is ES:DI
215 LDS SI,[BUFFHEAD
] ; Curbuf = HEAD
216 CALL POINTCOMP
; Buf == HEAD?
218 MOV WORD PTR [BUFFHEAD
],CX
219 MOV WORD PTR [BUFFHEAD
+2],BP ; HEAD = Pointsave
235 MOV WORD PTR [SI.NEXTBUF
],CX ; If Curbuf.nextbuf == buf
236 MOV WORD PTR [SI.NEXTBUF
+2],BP ; Curbuf.nextbuf = Pointsave
250 MOV WORD PTR [SI.NEXTBUF
],DI
251 MOV WORD PTR [SI.NEXTBUF
+2],ES ; Curbuf.nextbuf = Buf
252 MOV WORD PTR ES:[DI.NEXTBUF
],-1
253 MOV WORD PTR ES:[DI.NEXTBUF
+2],-1 ; Buf is LAST
260 procedure PLACEHEAD
,NEAR
261 ASSUME
DS:NOTHING
,ES:NOTHING
263 ; SAME AS PLACEBUF except places buffer at head
269 MOV WORD PTR [BUFFHEAD
],DI
270 MOV WORD PTR [BUFFHEAD
+2],ES
271 MOV WORD PTR ES:[DI.NEXTBUF
],SI
272 MOV WORD PTR ES:[DI.NEXTBUF
+2],DS
286 MOV WORD PTR [SI.NEXTBUF
],-1
287 MOV WORD PTR [SI.NEXTBUF
+2],-1 ; Buf is LAST
292 SUBTTL POINTCOMP
-- 20 BIT POINTER COMPARE
294 procedure PointComp
,NEAR
295 ASSUME
DS:NOTHING
,ES:NOTHING
297 ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality
298 ; DO NOT USE FOR < or >
299 ; No Registers altered
313 SUBTTL GETBUFFR
-- GET A SECTOR
INTO A BUFFER
315 procedure GETBUFFR
,NEAR
316 ASSUME
DS:DOSGROUP
,ES:NOTHING
319 ; AH = Priority buffer is to have
320 ; AL = 0 means sector must be pre-read
322 ; DX = Desired physical sector number
323 ; ES:BP = Pointer to drive parameters
325 ; Get the specified sector into one of the I/O buffers
326 ; And shuffle the queue
328 ; [CURBUF] Points to the Buffer for the sector
329 ; DX,ES:BP unchanged, all other registers destroyed
334 MOV AL,ES:[BP.dpb_drive
]
337 CMP DI,-1 ; Recency pointer valid?
340 JNZ SKBUF
; Wrong sector
342 JNZ SKBUF
; Wrong Drive
343 JMP SHORT JUSTBUF
; Just asked for same buffer
361 CALL BUFWRITE
; Write out the dirty buffer
366 RDSEC: ; Read in the new sector
367 TEST BYTE PTR [PREREAD
],-1
369 LEA BX,[DI.BufInSiz
] ; Point at buffer
377 JMP SHORT GOTTHESEC
; Buffer is marked free if read barfs
379 invoke DREAD
; Buffer is marked free if read barfs
386 MOV WORD PTR [DI.BUFDRVDP
],BP
387 MOV WORD PTR [DI.BUFDRVDP
+2],ES
389 MOV AL,ES:[BP.dpb_drive
]
390 MOV WORD PTR [DI.BUFDRV
],AX
392 MOV AX,1 ; Default to not a FAT sector
395 MOV AL,ES:[BP.dpb_FAT_count
]
396 MOV AH,ES:[BP.dpb_FAT_size
]
398 MOV WORD PTR [DI.BUFWRTCNT
],AX
401 MOV WORD PTR [CURBUF
+2],DS
402 MOV WORD PTR [LASTBUFFER
+2],DS
406 MOV WORD PTR [CURBUF
],DI
407 MOV WORD PTR [LASTBUFFER
],DI
412 SUBTTL FLUSHBUF
-- WRITE
OUT DIRTY BUFFERS
414 procedure FlushBuf
,NEAR
415 ASSUME
DS:DOSGROUP
,ES:NOTHING
419 ; AL = Physical unit number
422 ; Write out all dirty buffers for unit, and flag them as clean
423 ; DS Preserved, all others destroyed (ES too)
430 JZ SKIPBFF
; Skip free buffers
432 JZ DOBUFFER
; Do all dirty buffers
434 JNZ SKIPBFF
; Buffer not for this unit
436 CMP BYTE PTR [DI.BUFDIRTY
],0
437 JZ SKIPBFF
; Buffer not dirty
439 PUSH WORD PTR [DI.BUFDRV
]
442 XOR AH,AH ; Buffer is clean
443 CMP AL,BYTE PTR [WPERR
]
445 MOV AL,0FFH ; Invalidate buffer, it is inconsistent
447 MOV WORD PTR [DI.BUFDRV
],AX
459 SUBTTL BUFWRITE
-- WRITE
OUT A BUFFER
IF DIRTY
461 procedure BufWrite
,NEAR
462 ASSUME
DS:NOTHING
,ES:NOTHING
465 ; DS:DI Points to the buffer
467 ; Write out all the buffer if dirty.
470 ; DS:DI Preserved, ALL others destroyed (ES too)
473 XCHG AX,WORD PTR [DI.BUFDRV
] ; Free, in case write barfs
475 retz
; Buffer is free.
477 retz
; Buffer is clean.
478 CMP AL,BYTE PTR [WPERR
]
479 retz
; If in WP error zap buffer
481 LEA BX,[DI.BufInSiz
] ; Point at buffer
483 MOV CX,WORD PTR [DI.BUFWRTCNT
]
484 MOV AL,CH ; [DI.BUFWRTINC]
494 invoke DWRITE
; Write out the dirty buffer