]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/DISK3.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / DISK3.ASM
1 ; SCCSID = @(#)disk3.asm 1.3 85/07/26
2 ; SCCSID = @(#)disk3.asm 1.3 85/07/26
3 TITLE DISK3 - Disk utility routines
4 NAME Disk3
5 ; Low level Read and write routines for local SFT I/O on files and devs
6 ;
7 ; DISKWRITE
8 ; WRTERR
9 ;
10 ; Revision history:
11 ;
12 ; AN000 version 4.00 Jan. 1988
13 ;
14
15 ;
16 ; get the appropriate segment definitions
17 ;
18 .xlist
19 include dosseg.asm
20
21 CODE SEGMENT BYTE PUBLIC 'CODE'
22 ASSUME SS:DOSGROUP,CS:DOSGROUP
23
24 .xcref
25 INCLUDE DOSSYM.INC
26 INCLUDE DEVSYM.INC
27 include version.inc
28 .cref
29 .list
30
31 Installed = TRUE
32
33 i_need THISSFT,DWORD
34 i_need DMAADD,DWORD
35 i_need SecClusPos,BYTE
36 i_need ClusNum,WORD
37 i_need Trans,BYTE
38 i_need BytPos,4
39 i_need SecPos,DWORD ;F.C. >32mb ;AN000;
40 i_need BytSecPos,WORD
41 i_need BytCnt1,WORD
42 i_need BytCnt2,WORD
43 i_need SecCnt,WORD
44 i_need ThisDPB,DWORD
45 i_need LastPos,WORD
46 i_need ValSec,WORD ;F.C. >32mb ;AN000;
47 i_need GrowCnt,DWORD
48 i_need ALLOWED,BYTE
49 I_need JShare,DWORD
50 I_need FSeek_drive,BYTE ; DOS 4.00 ;AN000;
51 I_need FSeek_firclus,WORD ; DOS 4.00 ;AN000;
52 I_need FSeek_logclus,WORD ; DOS 4.00 ;AN000;
53 I_need HIGH_SECTOR,WORD ;F.C. >32mb ;AN000;
54 I_need HIGH_SECTOR_TEMP,WORD ;F.C. >32mb ;AN000;
55 I_need EXTERR,WORD ; DOS 4.00 ;AN000;
56 I_need EXTERR_LOCUS,BYTE ; DOS 4.00 ;AN000;
57 I_need EXTERR_ACTION,BYTE ; DOS 4.00 ;AN000;
58 I_need EXTERR_CLASS,BYTE ; DOS 4.00 ;AN000;
59 I_need EXITHOLD,DWORD ; DOS 4.00 ;AN000;
60 I_need DISK_FULL,BYTE ; DOS 4.00 ;AN000;
61 I_need SC_DRIVE,BYTE ; DOS 4.00 ;AN000;
62 I_need SC_CACHE_COUNT,WORD ; DOS 4.00 ;AN000;
63 I_need ThisDRV,BYTE ; DOS 4.00 ;AN000;
64 I_need User_In_AX,WORD ; DOS 4.00 ;AN000;
65 I_need DOS34_FLAG,WORD ; DOS 4.00 ;AN000;
66 I_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 ;AN000;
67
68 IF BUFFERFLAG
69 EXTRN SAVE_MAP:NEAR
70 EXTRN RESTORE_MAP:NEAR
71 EXTRN SAVE_USER_MAP:NEAR
72 EXTRN RESTORE_USER_MAP:NEAR
73 i_need BUF_EMS_SAFE_FLAG,BYTE
74 i_need BUF_EMS_MODE,BYTE
75 ENDIF
76
77
78
79 Break <DISKWRITE -- PERFORM USER DISK WRITE>
80
81 ; Inputs:
82 ; Outputs of SETUP
83 ; Function:
84 ; Perform disk write
85 ; Outputs:
86 ; Carry clear
87 ; CX = No. of bytes read
88 ; ES:DI point to SFT
89 ; SFT offset and cluster pointers updated
90 ; Carry set
91 ; CX = 0
92 ; ES:DI point to SFT
93 ; AX has error code
94
95 procedure DISKWRITE,NEAR
96 DOSAssume CS,<DS>,"DiskWrite"
97 ASSUME ES:NOTHING
98
99 Assert ISSFT,<ES,DI>,"DiskWrite"
100 PUSH ES:[DI.sf_firclus] ; set up 1st cluster # for FastSeek
101 POP [FSeek_firclus]
102
103 invoke CHECK_WRITE_LOCK ;IFS. check write lock ;AN000;
104 JNC WRITE_OK ;IFS. lock check ok ;AN000;
105 return
106
107 WRTEOFJ:
108 JMP WRTEOF
109
110 WRITE_OK:
111 AND ES:[DI.sf_flags],NOT (sf_close_nodate OR devid_file_clean)
112 ; Mark file as dirty, clear no date on close
113 LES BP,[THISDPB]
114 Assert ISDPB,<ES,BP>,"DiskWrite/WriteOk"
115 MOV AL,ES:[BP.dpb_drive] ; set up drive # for FastSeek
116 MOV [FSeek_drive],AL ; 11/5/86 DOS 4.00
117
118 invoke BREAKDOWN
119 MOV AX,WORD PTR [BYTPOS]
120 MOV DX,WORD PTR [BYTPOS+2]
121 JCXZ WRTEOFJ ;Make the file length = sf_position
122 ADD AX,CX
123 ADC DX,0 ; AX:DX=byte after last byte accessed
124 ;
125 ; Make sure divide won't overflow
126 ;
127 MOV BX,ES:[BP.dpb_sector_size]
128 ; CMP DX,BX ;F.C. >32mb 16 bit sector check ;AN000;
129 ; JAE WrtErr ;F.C. >32mb ;AN000;
130
131 CALL DIV32 ;F.C. perform 32 bit divide ;AN000;
132 MOV BX,AX ; Save last full sector
133 OR DX,DX
134 JNZ CALCLUS
135 SUB AX,1 ; AX must be zero base indexed ;AC000;
136 SBB [HIGH_SECTOR],0 ;F.C. >32mb ;AN000;
137 CALCLUS:
138 PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000;
139 CALL SHR32 ;F.C. >32mb ;AN000;
140 POP [HIGH_SECTOR] ;F.C. >32mb ;AN000;
141
142 ; SHR AX,CL ; Last cluster to be accessed
143 PUSH AX
144 PUSH DX ; Save the size of the "tail"
145 PUSH ES
146 LES DI,[THISSFT]
147 Assert ISSFT,<ES,DI>,"DiskWrite/CalClus"
148 MOV AX,WORD PTR ES:[DI.sf_size]
149 MOV DX,WORD PTR ES:[DI.sf_size+2]
150 POP ES
151
152
153
154 PUSH AX ;F.C. >32mb ;AN000;
155 MOV AX,DX ;F.C. >32mb ;AN000;
156 XOR DX,DX ;F.C. >32mb ;AN000;
157 DIV ES:[BP.dpb_sector_size] ;F.C. >32mb ;AN000;
158 MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb ;AN000;
159 POP AX ;F.C. >32mb ;AN000;
160
161 DIV ES:[BP.dpb_sector_size]
162 MOV CX,AX ; Save last full sector of current file
163 OR DX,DX
164 JZ NORNDUP
165 ADD AX,1 ; Round up if any remainder ;AC000;
166 ADC [HIGH_SECTOR_TEMP],0 ;F.C. >32mb ;AN000;
167 NORNDUP:
168 PUSH [HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000;
169 POP WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000;
170 MOV WORD PTR [VALSEC],AX ;Number of sectors that have been written
171 XOR AX,AX
172 MOV WORD PTR [GROWCNT],AX
173 MOV WORD PTR [GROWCNT+2],AX
174 POP AX
175
176 MOV DI,[HIGH_SECTOR] ;F.C. >32mb ;AN000;
177 CMP DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000;
178 JB NOGROW ;F.C. >32mb ;AN000;
179 JZ lowsec ;F.C. >32mb ;AN000;
180 SUB BX,CX ;F.C. >32mb ;AN000;
181 SBB DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb di:bx no. of sectors ;AN000;
182 JMP yesgrow ;F.C. >32mb ;AN000;
183 lowsec:
184 MOV DI,0 ;F.C. >32mb
185 SUB BX,CX ; Number of full sectors
186 JB NOGROW
187 JZ TESTTAIL
188 yesgrow:
189 MOV CX,DX
190 XCHG AX,BX
191 MUL ES:[BP.dpb_sector_size] ; Bytes of full sector growth
192 MOV [HIGH_SECTOR],DX ;F.C. >32mb save dx ;AN000;
193 MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb save ax ;AN000;
194 MOV AX,DI ;F.C. >32mb ;AN000;
195 MUL ES:[BP.dpb_sector_size] ;F.C. >32mb do higher word multiply ;AN000;
196 ADD AX,[HIGH_SECTOR] ;F.C. >32mb add lower value ;AN000;
197 MOV DX,AX ;F.C. >32mb DX:AX is the result of ;AN000;
198 MOV AX,[HIGH_SECTOR_TEMP] ;F.C. >32mb a 32 bit multiply ;AN000;
199
200 SUB AX,CX ; Take off current "tail"
201 SBB DX,0 ; 32-bit extension
202 ADD AX,BX ; Add on new "tail"
203 ADC DX,0 ; ripple tim's head off
204 JMP SHORT SETGRW
205 HAVSTART:
206 ;int 3
207 MOV CX,AX
208 invoke SKPCLP
209 JCXZ DOWRTJ
210 ;;; 11/5/86 FastSeek
211 MOV [FSeek_logclus],DX ; delete EOF (FFFFH)
212 INC [FSeek_logclus]
213 invoke FastSeek_Truncate ;
214 ;;; 11/5/86 FastSeek
215 invoke ALLOCATE
216 JNC DOWRTJ
217
218 entry WRTERR
219 DOSAssume CS,<DS>,"DiskWrite/WrtErr"
220 ASSUME ES:NOTHING
221
222 MOV AH,0FH ;MS. write/data/fail/abort ;AN000;
223 entry WRTERR22
224 MOV AL,[THISDRV] ;MS. ;AN000;
225 CALL File_Handle_Fail_Error ;MS. issue disk full I24
226 MOV CX,0 ;No bytes transferred
227 ; XOR CX,CX ; will be deleted
228 LES DI,[THISSFT]
229 Assert ISSFT,<ES,DI>,"DiskWrite/WrtErr"
230 ; CLC
231 return
232
233 DOWRTJ: JMP DOWRT
234
235 ACC_ERRWJ:
236 JMP SET_ACC_ERRW
237
238 TESTTAIL:
239 SUB AX,DX
240 JBE NOGROW
241 XOR DX,DX
242 SETGRW:
243 MOV WORD PTR [GROWCNT],AX
244 MOV WORD PTR [GROWCNT+2],DX
245 NOGROW:
246 POP AX
247 MOV CX,[CLUSNUM] ; First cluster accessed
248 invoke FNDCLUS
249 JC ACC_ERRWJ
250 MOV [CLUSNUM],BX
251 MOV [LASTPOS],DX
252 ;;; 11/5/86 FastSeek
253 MOV [FSeek_logclus],AX ; set up last position
254 SUB AX,DX ; Last cluster minus current cluster
255 JZ DOWRT ; If we have last clus, we must have first
256 JCXZ HAVSTART ; See if no more data
257 PUSH CX ; No. of clusters short of first
258 MOV CX,AX
259
260 ;;; 11/5/86 FastSeek
261 CMP [CLUSNUM],0 ;FS. null file ;AN000;
262 JZ NULL_FILE ;FS. yes ;AN000;
263 MOV [FSeek_logclus],DX ;FS. delete EOF (FFFFH) ;AN000;
264 INC [FSeek_logclus] ;FS. ;AN000;
265 invoke FastSeek_Truncate ;FS. ;AN000;
266 NULL_FILE:
267 ;;; 11/5/86 FastSeek
268 invoke ALLOCATE
269 POP AX
270 JC WRTERR
271 MOV CX,AX
272 MOV DX,[LASTPOS]
273 INC DX
274 DEC CX
275 JZ NOSKIP
276 ;;; 11/5/86 FastSeek
277 MOV [FSeek_logclus],DX ;
278 ADD [FSeek_logclus],CX ; set up last position
279 invoke SKPCLP
280 JC ACC_ERRWJ
281 NOSKIP:
282 MOV [CLUSNUM],BX
283 MOV [LASTPOS],DX
284 DOWRT:
285 CMP [BYTCNT1],0
286 JZ WRTMID
287 MOV BX,[CLUSNUM]
288 invoke BUFWRT
289 JC ACC_ERRWJ
290 WRTMID:
291 MOV AX,[SECCNT]
292 OR AX,AX
293 JNZ havemid
294 JMP WRTLAST
295 havemid:
296 ADD WORD PTR [SECPOS],AX
297 ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000;
298 invoke NEXTSEC
299 JNC gotok
300 JMP ACC_ERRWJ
301 gotok:
302 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
303 MOV DL,[SECCLUSPOS]
304 MOV BX,[CLUSNUM]
305 MOV CX,[SECCNT]
306 WRTLP:
307 invoke OPTIMIZE
308 JNC wokok
309 JMP ACC_ERRWJ
310 wokok:
311 PUSH DI
312 PUSH AX
313 PUSH DX
314 PUSH BX
315 Assert ISDPB,<ES,BP>,"DiskWrite/WrtLp"
316 MOV AL,ES:[BP.dpb_drive]
317 MOV [SC_DRIVE],AL ;LB. save it for INVALIDATE_SC ;AN000;
318 PUSH CX ;LB. ;AN000;
319 PUSH [HIGH_SECTOR] ;LB. ;AN000;
320 SCANNEXT: ;LB. ;AN000;
321 invoke GETCURHEAD ;LB. ;AN000;
322 ASSUME DS:NOTHING
323 NEXTBUFF: ; Search for buffers
324 CMP [SC_CACHE_COUNT],0 ;LB. SC support ? ;AN000;
325 JZ nosc ;LB. no ;AN000;
326 PUSH AX ;LB. save reg ;AN000;
327 PUSH CX ;LB. save reg ;AN000;
328 PUSH DX ;LB. save reg ;AN000;
329 invoke INVALIDATE_SC ;LB. invalidate SC ;AN000;
330 POP DX ;LB. save reg ;AN000;
331 POP CX ;LB. save reg ;AN000;
332 POP AX ;LB. save reg ;AN000;
333 nosc:
334 CALL BUFF_RANGE_CHECK ;F.C. >32mb ;AN000;
335 JNC inrange2 ;F.C. >32mb ;AN000;
336 mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000;
337 JMP DONEXTBUFF ;LB. ;AN000;
338 inrange2:
339 TEST [DI.buf_flags],buf_dirty ;LB. if dirty ;AN000;
340 JZ not_dirty ;LB. ;AN000;
341 invoke DEC_DIRTY_COUNT ;LB. then decrement dirty count ;AN000;
342 not_dirty:
343 MOV WORD PTR [DI.buf_ID],(buf_visit SHL 8) OR 0FFH ; Free the buffer, it is being over written
344 invoke SCANPLACE
345 DONEXTBUFF:
346 CMP DI,[FIRST_BUFF_ADDR] ;LB. end of chain ;AN000;
347 JNZ NEXTBUFF ;LB. no ;AN000;
348 ADD DX,1 ;LB. next sector number ;AN000;
349 ADC [HIGH_SECTOR],0 ;LB. ;AN000;
350 LOOP SCANNEXT ;LB. check again ;AN000;
351 POP [HIGH_SECTOR] ;LB. ;AN000;
352 POP CX ;LB. get count back ;AN000;
353
354 POP BX
355 POP DX
356 MOV DS,WORD PTR [DMAADD+2]
357 MOV [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE
358
359 IF BUFFERFLAG
360 pushf
361 cmp [BUF_EMS_MODE], -1
362 je safe_write
363 call save_map
364 call restore_user_map
365 safe_write:
366 popf
367 ENDIF
368
369 invoke DWRITE
370
371 IF BUFFERFLAG
372 pushf
373 cmp [BUF_EMS_MODE], -1
374 je safe_map
375 call save_user_map
376 call restore_map
377 safe_map:
378 popf
379 ENDIF
380
381 POP CX
382 POP BX
383 Context DS
384 JC SET_ACC_ERRW
385 JCXZ WRTLAST
386 MOV DL,0
387 INC [LASTPOS] ; We'll be using next cluster
388 JMP WRTLP
389
390 WRTLAST:
391 MOV AX,[BYTCNT2]
392 OR AX,AX
393 JZ FINWRT
394 MOV [BYTCNT1],AX
395 invoke NEXTSEC
396 JC SET_ACC_ERRW
397 MOV [BYTSECPOS],0
398 invoke BUFWRT
399 JC SET_ACC_ERRW
400 FINWRT:
401 LES DI,[THISSFT]
402 Assert ISSFT,<ES,DI>,"DiskWrite/FinWrt"
403 MOV AX,WORD PTR [GROWCNT]
404 MOV CX,WORD PTR [GROWCNT+2]
405 OR AX,AX
406 JNZ UPDATE_size
407 JCXZ SAMSIZ
408 Update_size:
409 ADD WORD PTR ES:[DI.sf_size],AX
410 ADC WORD PTR ES:[DI.sf_size+2],CX
411 ;
412 ; Make sure that all other SFT's see this growth also.
413 ;
414 MOV AX,1
415 if installed
416 call JShare + 14 * 4
417 else
418 Call ShSU
419 endif
420 SAMSIZ:
421 transfer SETCLUS ; ES:DI already points to SFT
422
423 SET_ACC_ERRW:
424 transfer SET_ACC_ERR_DS
425
426 WRTEOF:
427 MOV CX,AX
428 OR CX,DX
429 JZ KILLFIL
430 SUB AX,1
431 SBB DX,0
432
433 PUSH BX
434 MOV BX,ES:[BP.dpb_sector_size] ;F.C. >32mb ;AN000;
435 CALL DIV32 ;F.C. >32mb ;AN000;
436 POP BX ;F.C. >32mb ;AN000;
437 CALL SHR32 ;F.C. >32mb ;AN000;
438
439
440 ; SHR AX,CL
441 MOV CX,AX
442 invoke FNDCLUS
443 SET_ACC_ERRWJ2:
444 JC SET_ACC_ERRW
445 ;;; 11/5/86 FastSeek
446 MOV [FSeek_logclus],DX ; truncate clusters starting from DX
447 invoke FastSeek_Truncate
448 ;;; 11/5/86 FastSeek
449 JCXZ RELFILE
450 invoke ALLOCATE
451 JC WRTERRJ ;;;;;;;;; disk full
452 UPDATE:
453 LES DI,[THISSFT]
454 Assert ISSFT,<ES,DI>,"DiskWrite/update"
455 MOV AX,WORD PTR [BYTPOS]
456 MOV WORD PTR ES:[DI.sf_size],AX
457 MOV AX,WORD PTR [BYTPOS+2]
458 MOV WORD PTR ES:[DI.sf_size+2],AX
459 ;
460 ; Make sure that all other SFT's see this growth also.
461 ;
462 MOV AX,2
463 if installed
464 Call JShare + 14 * 4
465 else
466 Call ShSU
467 endif
468 XOR CX,CX
469 transfer ADDREC
470
471 WRTERRJ: JMP WRTERR
472 ;;;;;;;;;;;;;;;; 7/18/86
473 ;;;;;;;;;;;;;;;;;
474 RELFILE:
475 MOV DX,0FFFFH
476 invoke RELBLKS
477 Set_Acc_ERRWJJ:
478 JC SET_ACC_ERRWJ2
479 JMP SHORT UPDATE
480
481 KILLFIL:
482 XOR BX,BX
483 PUSH ES
484 LES DI,[THISSFT]
485 Assert ISSFT,<ES,DI>,"DiskWrite/KillFil"
486 MOV ES:[DI.sf_cluspos],BX
487 MOV ES:[DI.sf_lstclus],BX
488 XCHG BX,ES:[DI.sf_firclus]
489 POP ES
490 ;; 11/5/86 FastSeek
491 invoke Delete_FSeek ; delete fastseek entry
492
493 OR BX,BX
494 JZ UPDATEJ
495 ;; 10/23/86 FastOpen update
496 PUSH ES ; since first cluster # is 0
497 PUSH BP ; we must delete the old cache entry
498 PUSH AX
499 PUSH CX
500 PUSH DX
501 LES BP,[THISDPB] ; get current DPB
502 MOV DL,ES:[BP.dpb_drive] ; get current drive
503 MOV CX,BX ; first cluster #
504 MOV AH,2 ; delete cache entry by drive:firclus
505 invoke FastOpen_Update ; call fastopen
506 POP DX
507 POP CX
508 POP AX
509 POP BP
510 POP ES
511 ;; 10/23/86 FastOpen update
512
513 invoke RELEASE
514 JC SET_ACC_ERRWJJ
515 UpDateJ:
516 JMP UPDATE
517 EndProc DISKWRITE
518
519
520
521 Break <DIV32 -- PERFORM 32 BIT DIVIDE>
522
523 ; Inputs:
524 ; DX:AX = 32 bit dividend BX= divisor
525 ; Function:
526 ; Perform 32 bit division
527 ; Outputs:
528 ; [HIGH_SECTOR]:AX = quotiend , DX= remainder
529
530 procedure DIV32,NEAR
531 ASSUME DS:NOTHING,ES:NOTHING
532
533
534 PUSH AX ;F.C. >32mb ;AN000;
535 MOV AX,DX ;F.C. >32mb ;AN000;
536 XOR DX,DX ;F.C. >32mb ;AN000;
537 DIV BX ;F.C. >32mb ;AN000;
538 MOV [HIGH_SECTOR],AX ;F.C. >32mb ;AN000;
539 POP AX ;F.C. >32mb ;AN000;
540
541
542 DIV BX ; AX=last sector accessed
543 return
544
545 EndProc DIV32
546
547 Break <SHR32 -- PERFORM 32 BIT SHIFT RIGHT>
548
549 ; Inputs:
550 ; [HIGH_SECTOR]:AX = 32 bit sector number
551 ; Function:
552 ; Perform 32 bit shift right
553 ; Outputs:
554 ; AX= cluster number
555
556 procedure SHR32,NEAR
557 ASSUME DS:NOTHING,ES:NOTHING
558
559
560 MOV CL,ES:[BP.dpb_cluster_shift]
561 XOR CH,CH
562 entry ROTASHFT ;F.C. >32mb ;AN000;
563 OR CX,CX ;F.C. >32mb ;AN000;
564 JZ norota ;F.C. >32mb ;AN000;
565 ROTASHFT2:
566 CLC ;F.C. >32mb ;AN000;
567 RCR [HIGH_SECTOR],1 ;F.C. >32mb ;AN000;
568 RCR AX,1 ;F.C. >32mb ;AN000;
569 LOOP ROTASHFT2 ;F.C. >32mb: ;AN000;
570 norota:
571 return
572
573 EndProc SHR32
574
575
576 ; Issue File Handle Fail INT 24 Critical Error
577 ; Input: Disk_Full=0 ok
578 ; 1 disk full or EOF
579 ; Function: issue critical error for disk full or EOF error
580 ;
581 ; OutPut: carry clear , no I24
582 ; carry set, fail from I24
583
584 procedure File_Handle_Fail_Error,NEAR ;AN000;
585 ASSUME ES:NOTHING,DS:NOTHING ;AN000;
586 ;AN000;
587 CMP [DISK_FULL],0 ;MS. disk full or EOF ;AN000;
588 JZ Fexit ;MS. no ;AN000;
589 TEST [DOS34_FLAG],Disable_EOF_I24 ;MS. check input status ? ;AN000;
590 JNZ Fexit ;MS. yes ;AN000;
591 ;AN000;
592 LES DI,[THISSFT] ;MS. get current SFT ;AN000;
593 ; LES DI,ES:[DI.sf_DEVPTR];MS. get device header ;AN000;
594 TEST ES:[DI.sf_flags],Handle_Fail_I24 ;MS. gen I24 ? ;AN000;
595 JZ Fexit ;MS. no ;AN000;
596 PUSH DS ;MS. save DS ;AN000;
597 TEST AH,1 ;MS. READ ? ;AN000;
598 JZ readeof ;MS. yes ;AN000;
599 MOV [EXTERR],error_Handle_Disk_Full ;MS. set extended error ;AN000;
600 JMP SHORT errset ;MS. set extended error ;AN000;
601 readeof:
602 MOV [EXTERR],error_Handle_EOF ;MS. set extended error ;AN000;
603 errset:
604 MOV [EXTERR_CLASS],errCLASS_OutRes ;MS. set class ;AN000;
605 MOV [EXTERR_ACTION],errACT_Abort ;MS. set action ;AN000;
606 MOV [EXTERR_LOCUS],errLOC_Unk ;MS. set locus ;AN000;
607 MOV word ptr [EXITHOLD + 2],ES ;MS. save es:bp in exithold ;AN000;
608 MOV word ptr [EXITHOLD],BP ;MS. ;AN000;
609 TEST ES:[DI.sf_flags],devid_device ;MS. device ? ;AN000;
610 JNZ chardev2 ;MS. yes ;AN000;
611 LDS SI,ES:[DI.sf_DEVPTR] ;MS. get dpb ;AN000;
612 LDS SI,[SI.dpb_driver_addr] ;MS. get drive device haeder ;AN000;
613 JMP SHORT doi24 ;MS. gen I24 ? ;AN000;
614 chardev2:
615 LDS SI,ES:[DI.sf_DEVPTR] ;MS. get chr dev header ;AN000;
616 doi24:
617 MOV BP,DS ;MS. bp:si -> device header ;AN000;
618 MOV DI,error_I24_gen_failure ;MS. general error ;AN000;
619 invoke NET_I24_ENTRY ;MS. issue I24 ;AN000;
620 STC ;MS. must be fail ;AN000;
621 POP DS ;MS. restore DS ;AN000;
622 MOV AX,[EXTERR] ;MS. set error ;AN000;
623 JMP SHORT Fend ;MS. exit ;AN000;
624 Fexit: ;AN000;
625 CLC ;MS. clear carry ;AN000;
626 Fend: ;AN000;
627 return ;MS. ;AN000;
628 ;AN000;
629 EndProc File_Handle_Fail_Error ;AN000;
630
631
632 Break <BUFF_RANGE_CHECK- buffer range checkink>
633
634 ; Inputs:
635 ; DS:DI -> buffer. AL= drive #
636 ; [HIGH_SECTOR]:DX = sector #
637 ; Function:
638 ; check if sector is in the buffer
639 ; Outputs:
640 ; carry clear= in the range
641 ; set = not in the range
642
643 procedure BUFF_RANGE_CHECK,NEAR
644 ASSUME DS:NOTHING,ES:NOTHING
645
646 CMP WORD PTR [DI.buf_sector],DX ;AN000;
647 JNZ DONEXTBUFF2 ; not this sector ;F.C. >32mb ;AN000;
648 MOV SI,[HIGH_SECTOR] ;F.C. >32mb ;AN000;
649 CMP WORD PTR [DI.buf_sector+2],SI ;F.C. >32mb ;AN000;
650 JNZ DONEXTBUFF2 ; Not for this drive
651 CMP AL,[DI.buf_ID]
652 JZ secfound ; Buffer has the sector ;AN000;
653 DONEXTBUFF2:
654 STC
655 secfound:
656 return
657
658 EndProc BUFF_RANGE_CHECK
659
660 CODE ENDS
661 END
662 \1a