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