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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / DISK2.ASM
1 ; SCCSID = @(#)disk2.asm 1.3 85/06/19
2 ; SCCSID = @(#)disk2.asm 1.3 85/06/19
3 TITLE DISK2 - Disk utility routines
4 NAME Disk2
5 ; Low level Read and write routines for local SFT I/O on files and devs
6 ;
7 ; DskRead
8 ; DWRITE
9 ; DSKWRITE
10 ; HarderrRW
11 ; SETUP
12 ; BREAKDOWN
13 ; READ_LOCK_VIOLATION
14 ; WRITE_LOCK_VIOLATION
15 ; DISKREAD
16 ; SET_ACC_ERR_DS
17 ; SET_ACC_ERR
18 ; SETSFT
19 ; SETCLUS
20 ; AddRec
21 ;
22 ; Revision history:
23 ;
24 ; AN000 version 4.00 Jan. 1988
25 ;
26
27 ;
28 ; get the appropriate segment definitions
29 ;
30 .xlist
31 include dosseg.asm
32
33 CODE SEGMENT BYTE PUBLIC 'CODE'
34 ASSUME SS:DOSGROUP,CS:DOSGROUP
35
36 .xcref
37 INCLUDE DOSSYM.INC
38 INCLUDE DEVSYM.INC
39 include version.inc
40 .cref
41 .list
42
43 Installed = TRUE
44
45 i_need THISSFT,DWORD
46 i_need DMAADD,DWORD
47 i_need NEXTADD,WORD
48 i_need ThisDrv,BYTE
49 i_need SecClusPos,BYTE
50 i_need ClusNum,WORD
51 i_need ReadOp,BYTE
52 i_need Trans,BYTE
53 i_need BytPos,4
54 i_need SecPos,DWORD ; DOS 4.00 >32mb ;AN000;
55 i_need BytSecPos,WORD
56 i_need BytCnt1,WORD
57 i_need BytCnt2,WORD
58 i_need SecCnt,WORD
59 i_need ThisDPB,DWORD
60 i_need LastPos,WORD
61 i_need EXTERRPT,DWORD
62 i_need CALLVIDRW,DWORD
63 i_need ALLOWED,BYTE
64 i_need DEVCALL,BYTE
65 i_need CALLSCNT,WORD
66 i_need DISK_FULL,BYTE ; disk full flag for ran blk wrt
67 i_need FSeek_drive,BYTE ; DOS 4.00 ;AN000;
68 i_need FSeek_firclus,WORD ; DOS 4.00 ;AN000;
69 i_need HIGH_SECTOR,WORD ; F.C. >32mb ;AN000;
70 i_need TEMP_VAR2,WORD ; LB. ;AN000;
71 i_need TEMP_VAR,WORD ; LB. ;AN000;
72 i_need IFS_DRIVER_ERR,WORD ; LB. ;AN000;
73 i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000;
74 i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000;
75 i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000;
76 i_need LastBuffer,DWORD
77 i_need FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000;
78
79 IF BUFFERFLAG
80 EXTRN SAVE_MAP:NEAR
81 EXTRN RESTORE_MAP:NEAR
82 EXTRN SAVE_USER_MAP:NEAR
83 EXTRN RESTORE_USER_MAP:NEAR
84 i_need BUF_EMS_SAFE_FLAG,BYTE
85 i_need BUF_EMS_MODE,BYTE
86 i_need CURADD,WORD
87 ENDIF
88
89
90 Break <DSKREAD -- PHYSICAL DISK READ>
91
92 ; Inputs:
93 ; DS:BX = Transfer addr
94 ; CX = Number of sectors
95 ; [HIGH_SECTOR] = Absolute record number (HIGH)
96 ; DX = Absolute record number (LOW)
97 ; ES:BP = Base of drive parameters
98 ; Function:
99 ; Call BIOS to perform disk read
100 ; Outputs:
101 ; DI = CX on entry
102 ; CX = Number of sectors unsuccessfully transfered
103 ; AX = Status word as returned by BIOS (error code in AL if error)
104 ; Zero set if OK (from BIOS) (carry clear)
105 ; Zero clear if error (carry clear)
106 ; SI Destroyed, others preserved
107
108 procedure DskRead,NEAR
109 ASSUME DS:NOTHING,ES:NOTHING
110
111 Assert ISDPB,<ES,BP>,"DskRead"
112 PUSH CX
113 MOV AH,ES:[BP.dpb_media]
114 MOV AL,ES:[BP.dpb_UNIT]
115 PUSH BX
116 PUSH ES
117 invoke SETREAD
118 JMP DODSKOP
119
120 Break <DWRITE -- SEE ABOUT WRITING>
121
122 ; Inputs:
123 ; DS:BX = Transfer address
124 ; CX = Number of sectors
125 ; [HIGH_SECTOR] = Absolute record number (HIGH)
126 ; DX = Absolute record number (LOW)
127 ; ES:BP = Base of drive parameters
128 ; [ALLOWED] must be set in case HARDERR called
129 ; Function:
130 ; Calls BIOS to perform disk write. If BIOS reports
131 ; errors, will call HARDERRRW for further action.
132 ; Output:
133 ; Carry set if error (currently, user FAILed to I 24)
134 ; BP preserved. All other registers destroyed.
135
136 entry DWRITE
137 ASSUME DS:NOTHING,ES:NOTHING
138
139 Assert ISDPB,<ES,BP>,"DWrite"
140 CALL DSKWRITE
141 retz ; Carry clear
142 MOV BYTE PTR [READOP],1
143 invoke HARDERRRW
144 CMP AL,1 ; Check for retry
145 JZ DWRITE
146 CMP AL,3 ; Check for FAIL
147 CLC
148 JNZ NO_CAR2 ; Ignore
149 STC
150 NO_CAR2:
151 return
152
153 Break <DSKWRITE -- PHYSICAL DISK WRITE>
154
155 ; Inputs:
156 ; DS:BX = Transfer addr
157 ; CX = Number of sectors
158 ; DX = Absolute record number (LOW)
159 ; [HIGH_SECTOR] = Absolute record number (HIGH)
160 ; ES:BP = Base of drive parameters
161 ; Function:
162 ; Call BIOS to perform disk read
163 ; Outputs:
164 ; DI = CX on entry
165 ; CX = Number of sectors unsuccessfully transfered
166 ; AX = Status word as returned by BIOS (error code in AL if error)
167 ; Zero set if OK (from BIOS) (carry clear)
168 ; Zero clear if error (carry clear)
169 ; SI Destroyed, others preserved
170
171 entry DSKWRITE
172 ASSUME DS:NOTHING,ES:NOTHING
173
174 Assert ISDPB,<ES,BP>,"DskWrite"
175 PUSH CX
176 MOV AH,ES:[BP.dpb_media]
177 MOV AL,ES:[BP.dpb_UNIT]
178 PUSH BX
179 PUSH ES
180 invoke SETWRITE
181 DODSKOP:
182 MOV CX,DS ; Save DS
183 POP DS ; DS:BP points to DPB
184 PUSH DS
185 LDS SI,DS:[BP.dpb_driver_addr]
186 invoke DEVIOCALL2
187 MOV DS,CX ; Restore DS
188 POP ES ; Restore ES
189 POP BX
190 MOV CX,[CALLSCNT] ; Number of sectors transferred
191 POP DI
192 SUB CX,DI
193 NEG CX ; Number of sectors not transferred
194 MOV AX,[DEVCALL.REQSTAT]
195 MOV [IFS_DRIVER_ERR],AX ;IFS. save it for IFS ;AN000;
196 TEST AX,STERR
197 return
198 EndProc DskRead
199
200
201
202 Break <HardErrRW - map extended errors and call harderr>
203
204 ; Inputs:
205 ; AX is error code from read or write
206 ; Other registers set as per HARDERR
207 ; Function:
208 ; Checks the error code for special extended
209 ; errors and maps them if needed. Then invokes
210 ; Harderr
211 ; Outputs:
212 ; Of HARDERR
213 ; AX may be modified prior to call to HARDERR.
214 ; No other registers altered.
215
216 procedure HARDERRRW,near
217 ASSUME DS:NOTHING,ES:NOTHING
218
219 CMP AL,error_I24_wrong_disk
220 JNZ DO_ERR ; Nothing to do
221 PUSH DS
222 PUSH SI
223 LDS SI,[CALLVIDRW] ; Get pointer from dev
224 MOV WORD PTR [EXTERRPT+2],DS ; Set ext err pointer
225 MOV WORD PTR [EXTERRPT],SI
226 POP SI
227 POP DS
228 DO_ERR:
229 invoke HARDERR
230 return
231
232 EndProc HARDERRRW
233
234 Break <SETUP -- SETUP A DISK READ OR WRITE FROM USER>
235
236 ; Inputs:
237 ; ES:DI point to SFT (value also in THISSFT)
238 ; [DMAADD] contains transfer address
239 ; CX = Byte count
240 ; WARNING Stack must be clean, two ret addrs on stack, 1st of caller,
241 ; 2nd of caller of caller.
242 ; Outputs:
243 ; CX = byte count
244 ; [THISDPB] = Base of drive parameters if file
245 ; = Pointer to device header if device or NET
246 ; ES:DI Points to SFT
247 ; [NEXTADD] = Displacement of disk transfer within segment
248 ; [TRANS] = 0 (No transfers yet)
249 ; [BYTPOS] = Byte position in file
250 ;
251 ; The following fields are relevant to local files (not devices) only:
252 ;
253 ; [SECPOS] = Position of first sector (local files only)
254 ; [BYTSECPOS] = Byte position in first sector (local files only)
255 ; [CLUSNUM] = First cluster (local files only)
256 ; [SECCLUSPOS] = Sector within first cluster (local files only)
257 ; [THISDRV] = Physical unit number (local files only)
258 ;
259 ; RETURNS ONE LEVEL UP WITH:
260 ; CX = 0
261 ; CARRY = Clear
262 ; IF AN ERROR IS DETECTED
263 ; All other registers destroyed
264
265 procedure SETUP,NEAR
266 DOSAssume CS,<DS>,"SetUp"
267 ASSUME ES:NOTHING
268
269 Assert ISSFT,<ES,DI>,"SetUp"
270 LDS SI,ES:[DI.sf_devptr]
271 ASSUME DS:NOTHING
272 MOV WORD PTR [THISDPB+2],DS
273 context DS
274 MOV WORD PTR [THISDPB],SI
275 MOV BX,WORD PTR [DMAADD]
276 MOV [NEXTADD],BX ;Set NEXTADD to start of Xaddr
277 MOV BYTE PTR [TRANS],0 ;No transferes
278 MOV AX,WORD PTR ES:[DI.sf_Position]
279 MOV DX,WORD PTR ES:[DI.sf_Position+2]
280 MOV WORD PTR [BYTPOS+2],DX ;Set it
281 MOV WORD PTR [BYTPOS],AX
282 TEST ES:[DI.sf_flags],sf_isnet + devid_device
283 JNZ NOSETSTUFF ;Following not done on devs or NET
284 PUSH ES
285 LES BP,[THISDPB] ;Point at the DPB
286 Assert ISDPB,<ES,BP>,"Setup"
287 MOV BL,ES:[BP.dpb_drive]
288 MOV [THISDRV],BL ;Set THISDRV
289 MOV BX,ES:[BP.dpb_sector_size]
290 ; CMP DX,BX ; See if divide will overflow
291 ; JNC EOFERR ; for 16 bit sector
292 ;; 32 bit divide
293 invoke DIV32 ; F.C. >32mb ;AN000;
294 MOV WORD PTR [SECPOS],AX ; F.C. >32mb ;AN000;
295 MOV BX,[HIGH_SECTOR] ; F.C. >32mb ;AN000;
296 MOV WORD PTR [SECPOS+2],BX ; F.C. >32mb ;AN000;
297
298 MOV [BYTSECPOS],DX
299 MOV DX,AX
300 AND AL,ES:[BP.dpb_cluster_mask]
301 MOV [SECCLUSPOS],AL
302 MOV AX,CX ; Save byte count
303 ; MOV CL,ES:[BP.dpb_cluster_shift]
304 PUSH WORD PTR [SECPOS+2] ; F.C. >32mb ;AN000;
305 POP [HIGH_SECTOR] ; F.C. >32mb ;AN000;
306 PUSH AX ; F.C. >32mb save ax ;AN000;
307 MOV AX,DX ; F.C. >32mb ax=dx ;AN000;
308 invoke SHR32 ; F.C. >32mb shift ax ;AN000;
309 MOV DX,AX ; F.C. >32mb dx=ax ;AN000;
310 POP AX ; F.C. >32mb restore dx ;AN000;
311
312 ; SHR DX,CL
313 CMP DX,ES:[BP.dpb_max_cluster] ;>32mb if > disk size ;AN000; ;AN000;
314 JA EOFERR ;>32mb then EOF ;AN000; ;AN000;
315
316 MOV [CLUSNUM],DX
317 POP ES ; ES:DI point to SFT
318 MOV CX,AX ; Put byte count back in CX
319 NOSETSTUFF:
320 MOV AX,CX ; Need it in AX too
321 ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment
322 JNC OK ; Must be less than 64K
323 MOV AX,WORD PTR [DMAADD]
324 NEG AX ; Amount of room left in segment (know
325 ; less than 64K since max value of CX
326 ; is FFFF).
327 JNZ NoDec
328 DEC AX
329 NoDec:
330 MOV CX,AX ; Can do this much
331 JCXZ NOROOM ; Silly user gave Xaddr of FFFF in segment
332 OK:
333 return
334
335 EOFERR:
336 POP ES ; ES:DI point to SFT
337 XOR CX,CX ; No bytes read
338 ;;;;;;;;;;; 7/18/86
339 ; MOV BYTE PTR [DISK_FULL],1 ; set disk full flag
340 ;;;;;;;;;;;
341 NOROOM:
342 POP BX ; Kill return address
343 CLC
344 return ; RETURN TO CALLER OF CALLER
345 EndProc SETUP
346
347 Break <BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES>
348
349 ; Inputs:
350 ; CX = Length of disk transfer in bytes
351 ; ES:BP = Base of drive parameters
352 ; [BYTSECPOS] = Byte position witin first sector
353 ; Outputs:
354 ; [BYTCNT1] = Bytes to transfer in first sector
355 ; [SECCNT] = No. of whole sectors to transfer
356 ; [BYTCNT2] = Bytes to transfer in last sector
357 ; AX, BX, DX destroyed. No other registers affected.
358
359 procedure BREAKDOWN,near
360 DOSAssume CS,<DS>,"BreakDown"
361 ASSUME ES:NOTHING
362
363 Assert ISDPB,<ES,BP>,"BreakDown"
364 MOV AX,[BYTSECPOS]
365 MOV BX,CX
366 OR AX,AX
367 JZ SAVFIR ; Partial first sector?
368 SUB AX,ES:[BP.dpb_sector_size]
369 NEG AX ; Max number of bytes left in first sector
370 SUB BX,AX ; Subtract from total length
371 JAE SAVFIR
372 ADD AX,BX ; Don't use all of the rest of the sector
373 XOR BX,BX ; And no bytes are left
374 SAVFIR:
375 MOV [BYTCNT1],AX
376 MOV AX,BX
377 XOR DX,DX
378 DIV ES:[BP.dpb_sector_size] ; How many whole sectors?
379 MOV [SECCNT],AX
380 MOV [BYTCNT2],DX ; Bytes remaining for last sector
381 OR DX,[BYTCNT1]
382 retnz ; NOT (BYTCNT1 = BYTCNT2 = 0)
383 CMP AX,1
384 retnz
385 MOV AX,ES:[BP.dpb_sector_size] ; Buffer EXACT one sector I/O
386 MOV [BYTCNT2],AX
387 MOV [SECCNT],DX ; DX = 0
388 RET45:
389 return
390 EndProc BreakDown
391
392 ; ES:DI points to SFT. This entry used by NET_READ
393 ; Carry set if to return error (CX=0,AX=error_sharing_violation).
394 ; Else do retrys.
395 ; ES:DI,DS,CX preserved
396
397 procedure READ_LOCK_VIOLATION,NEAR
398 DOSAssume CS,<DS>,"Read_Lock_Violation"
399 ASSUME ES:NOTHING
400
401 Assert ISSFT,<ES,DI>,"ReadLockViolation"
402
403 MOV [READOP],0
404 ERR_ON_CHECK:
405 TEST ES:[DI.sf_mode],sf_isfcb
406 JNZ HARD_ERR
407 PUSH CX
408 MOV CL,BYTE PTR ES:[DI.sf_mode]
409 AND CL,sharing_mask
410 CMP CL,sharing_compat
411 POP CX
412 JNE NO_HARD_ERR
413 HARD_ERR:
414 invoke LOCK_VIOLATION
415 retnc ; User wants Retrys
416 NO_HARD_ERR:
417 XOR CX,CX ;No bytes transferred
418 MOV AX,error_lock_violation
419 STC
420 return
421
422 EndProc READ_LOCK_VIOLATION
423
424 ; Same as READ_LOCK_VIOLATION except for READOP.
425 ; This entry used by NET_WRITE
426 procedure WRITE_LOCK_VIOLATION,NEAR
427 DOSAssume CS,<DS>,"Write_Lock_Violation"
428 ASSUME ES:NOTHING
429 Assert ISSFT,<ES,DI>,"WriteLockViolation"
430
431 MOV [READOP],1
432 JMP ERR_ON_CHECK
433
434 EndProc WRITE_LOCK_VIOLATION
435
436
437 Break <DISKREAD -- PERFORM USER DISK READ>
438
439 ; Inputs:
440 ; Outputs of SETUP
441 ; Function:
442 ; Perform disk read
443 ; Outputs:
444 ; Carry clear
445 ; CX = No. of bytes read
446 ; ES:DI point to SFT
447 ; SFT offset and cluster pointers updated
448 ; Carry set
449 ; CX = 0
450 ; ES:DI point to SFT
451 ; AX has error code
452
453 procedure DISKREAD,NEAR
454 DOSAssume CS,<DS>,"DiskRead"
455 ASSUME ES:NOTHING
456
457 Assert ISSFT,<ES,DI>,"DISKREAD"
458 PUSH ES:[DI.sf_firclus] ; set up 1st cluster # for FastSeek
459 POP [FSeek_firclus] ; 11/5/86
460
461 MOV AX,WORD PTR ES:[DI.sf_size]
462 MOV BX,WORD PTR ES:[DI.sf_size+2]
463 SUB AX,WORD PTR [BYTPOS]
464 SBB BX,WORD PTR [BYTPOS+2]
465 JB RDERR ;Read starts past EOF
466 JNZ ENUF ;More than 64k to EOF
467 OR AX,AX
468 JZ RDERR ;Read starts at EOF
469 CMP AX,CX
470 JAE ENUF ;I/O fits
471 MOV CX,AX ;Limit read to up til EOF
472 ENUF:
473 invoke CHECK_READ_LOCK ;IFS. check read lock ;AN000;
474 JNC Read_Ok ; There are no locks
475 return
476
477 READ_OK:
478 LES BP,[THISDPB]
479 Assert ISDPB,<ES,BP>,"DISKREAD/ReadOK"
480 MOV AL,ES:[BP.dpb_drive] ; set up drive # for FastSeek
481 MOV [FSeek_drive],AL ; 11/5/86 ;AN000;
482
483 CALL BREAKDOWN
484 MOV CX,[CLUSNUM]
485 invoke FNDCLUS
486 ;------------------------------------------------------------------------
487 IF NOT IBMCOPYRIGHT
488 JC SET_ACC_ERR_DS ; fix to take care of I24 fail
489 ; migrated from 330a - HKN
490 ENDIF
491 ;------------------------------------------------------------------------
492 OR CX,CX
493 JZ SKIPERR
494 RDERR:
495 MOV [DISK_FULL],1 ;MS. EOF detection ;AN000;
496 MOV AH,0EH ;MS. read/data/fail ;AN000;
497 transfer WRTERR22
498 RDLASTJ:JMP RDLAST
499 SETSFTJ2: JMP SETSFT
500
501 CANOT_READ:
502 POP CX ; Clean stack
503 POP CX
504 POP BX
505
506 entry SET_ACC_ERR_DS
507 ASSUME DS:NOTHING,ES:NOTHING
508 Context DS
509
510 entry SET_ACC_ERR
511 DOSAssume CS,<DS>,"SET_ACC_ERR"
512
513 XOR CX,CX
514 MOV AX,error_access_denied
515 STC
516 return
517
518 SKIPERR:
519 MOV [LASTPOS],DX
520 MOV [CLUSNUM],BX
521 CMP [BYTCNT1],0
522 JZ RDMID
523 invoke BUFRD
524 JC SET_ACC_ERR_DS
525 RDMID:
526 CMP [SECCNT],0
527 JZ RDLASTJ
528 invoke NEXTSEC
529 JC SETSFTJ2
530 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
531 ONSEC:
532 MOV DL,[SECCLUSPOS]
533 MOV CX,[SECCNT]
534 MOV BX,[CLUSNUM]
535 RDLP:
536 invoke OPTIMIZE
537 JC SET_ACC_ERR_DS
538 PUSH DI
539 PUSH AX
540 PUSH BX
541 MOV [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE
542 MOV DS,WORD PTR [DMAADD+2]
543 ASSUME DS:NOTHING
544 PUSH DX
545 PUSH CX
546 invoke SET_RQ_SC_PARMS ;LB. do this for SC ;AN000;
547
548 IF BUFFERFLAG
549 pushf
550 cmp [BUF_EMS_SAFE_FLAG], 1
551 je safe_read
552 call save_map
553 call restore_user_map
554 safe_read:
555 popf
556 ENDIF
557
558 invoke DREAD
559
560 IF BUFFERFLAG
561 pushf
562 cmp [BUF_EMS_SAFE_FLAG], 1
563 je safe_mapping
564 call save_user_map
565 call restore_map
566 safe_mapping:
567 popf
568 ENDIF
569
570 POP BX
571 POP DX
572 JNC SKP_CANOT_READ
573 JMP CANOT_READ
574 SKP_CANOT_READ:
575 MOV [TEMP_VAR],BX ;LB. save sector count ;AN000;
576 MOV [TEMP_VAR2],DX ;LB. 1st sector ;AN000;
577 SCAN_NEXT:
578 ;;;;;;; invoke GETCURHEAD ;LB. get buffer header ;AN000;
579 PUSH DX ;LB. save regs ;AN000;
580 PUSH AX ;LB. ;AN000;
581 PUSH BX ;LB. ;AN000;
582 MOV AX,DX ;LB.
583 ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000;
584 XOR DX,DX ;LB. to avoid divide overflow ;AN000;
585 DIV [BUF_HASH_COUNT] ;LB. get remainder ;AN000;
586 ADD DX,DX ;LB. 8 bytes per entry ;AN000;
587 ADD DX,DX ;LB. ;AN000;
588 ADD DX,DX ;LB. times 8 ;AN000;
589
590 LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000;
591 ADD DI,DX ;LB position to entry ;AN000;
592 CMP [DI.Dirty_Count],0 ;LB dirty hash entry ? ;AN000;
593 JNZ yesdirty ;LB yes and map it ;AN000;
594 POP BX ;LB. ;AN000;
595 POP AX ;LB. ;AN000;
596 POP DX ;LB. ;AN000;
597
598 IF NOT BUFFERFLAG
599 JMP SHORT end_scan ;LB. ;AN000;
600 ELSE
601 JMP END_SCAN
602 ENDIF
603
604 yesdirty:
605 MOV WORD PTR [CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000;
606 MOV WORD PTR [CurHashEntry],DI ;LB. ;AN000;
607 MOV WORD PTR [LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000;
608 MOV BX,[DI.EMS_PAGE_NUM] ;LB. logical page ;AN000;
609
610 IF NOT BUFFERFLAG
611 LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000;
612 MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000;
613 invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000;
614 ELSE
615 ; int 3
616 push ds
617 push di ; save hash ptr
618
619 LDS DI,[DI.BUFFER_BUCKET] ;ds:di is 1st buffer addr
620 POP AX ; Recall transfer address
621 PUSH AX
622 PUSH DI ; Save search environment
623 PUSH DX ; F.C. no need for high sector, <64K
624 push cx
625
626 MOV DX,[TEMP_VAR2] ;LB. get 1st sector #
627 SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer?
628 NEG DX
629 MOV DI,AX
630 MOV AX,DX
631 MOV CX,ES:[BP.dpb_sector_size]
632 MUL CX
633 ADD DI,AX ; Put the buffer here
634 mov [CURADD], di
635
636 pop cx
637 pop dx
638 pop di
639
640 invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000;
641 pop di ; restore hash ptr.
642 pop ds
643 LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000;
644 MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000;
645 ENDIF
646 ;AN000;
647 POP BX ;LB. ;AN000;
648 POP AX ;LB. ;AN000;
649 POP DX ;LB. ;AN000;
650
651
652 Assert ISDPB,<ES,BP>,"DISKREAD/RdLp"
653 MOV AL,ES:[BP.dpb_drive]
654 NXTBUF: ; Must see if one of these sectors is buffered
655 invoke BUFF_RANGE_CHECK ;F.C. >32mb
656 JNC inrange ;LB. ;AN000;
657 mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000;
658 JMP DONXTBUF ;LB. ;AN000;
659 inrange:
660 TEST [DI.buf_flags],buf_dirty
661 JZ CLBUFF ; Buffer is clean, so OK
662 ; A sector has been read in when a dirty copy of it is in a buffer
663 ; The buffered sector must now be read into the right place
664 POP AX ; Recall transfer address
665 PUSH AX
666 PUSH DI ; Save search environment
667 PUSH DX ; F.C. no need for high sector, <64K
668
669 MOV DX,[TEMP_VAR2] ;LB. get 1st sector #
670 SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer?
671 NEG DX
672 MOV SI,DI
673 MOV DI,AX
674 MOV AX,DX
675 MOV CX,ES:[BP.dpb_sector_size]
676 MUL CX
677 ADD DI,AX ; Put the buffer here
678 LEA SI,[SI].BUFINSIZ
679 SHR CX,1
680 PUSH ES
681 MOV ES,WORD PTR [DMAADD+2]
682 REP MOVSW
683 JNC EVENMOV
684 MOVSB
685 EVENMOV:
686 POP ES
687 POP DX
688 POP DI
689 MOV AL,ES:[BP.dpb_drive]
690 invoke SCANPLACE ;LB. done with this chain ;AN000;
691 JMP SHORT end_scan ;LB. ;AN000;
692 CLBUFF:
693 invoke SCANPLACE
694 DONXTBUF:
695 CMP DI,[FIRST_BUFF_ADDR] ;LB. end of buffers ;AN000;
696 JNZ NXTBUF
697 end_scan:
698 ADD DX,1 ;LB. next sector # ;AN000;
699 ADC [HIGH_SECTOR],0 ;LB. ;AN000;
700 DEC [TEMP_VAR] ;LB. decrement count ;AN000;
701 JZ SCAN_DONE ;LB. scan next sector ;AN000;
702 JMP SCAN_NEXT ;LB. scan next sector ;AN000;
703 SCAN_DONE:
704 Context DS
705 POP CX
706 POP CX
707 POP BX
708 JCXZ RDLAST
709 invoke IsEOF ; test for eof on fat size
710 JAE SETSFT
711 MOV DL,0
712 INC [LASTPOS] ; We'll be using next cluster
713 JMP RDLP
714
715 RDLAST:
716 MOV AX,[BYTCNT2]
717 OR AX,AX
718 JZ SETSFT
719 MOV [BYTCNT1],AX
720 invoke NEXTSEC
721 JC SETSFT
722 MOV [BYTSECPOS],0
723 invoke BUFRD
724 JNC SETSFT
725 JMP SET_ACC_ERR_DS
726
727 ; Inputs:
728 ; [NEXTADD],[CLUSNUM],[LASTPOS] set to determine transfer size
729 ; and set cluster fields
730 ; Function:
731 ; Update [THISSFT] based on the transfer
732 ; Outputs:
733 ; sf_position, sf_lstclus, and sf_cluspos updated
734 ; ES:DI points to [THISSFT]
735 ; CX No. of bytes transferred
736 ; Carry clear
737
738 entry SETSFT
739 DOSAssume CS,<DS>,"SetSFT"
740 ASSUME ES:NOTHING
741
742 LES DI,[THISSFT]
743
744 ; Same as SETSFT except ES:DI already points to SFT
745 entry SETCLUS
746 DOSAssume CS,<DS>,"SetClus"
747 ASSUME ES:NOTHING
748
749 Assert ISSFT,<ES,DI>,"SetClus"
750 MOV CX,[NEXTADD]
751 SUB CX,WORD PTR [DMAADD] ; Number of bytes transfered
752 TEST ES:[DI.sf_flags],devid_device
753 JNZ ADDREC ; don't set clusters if device
754 MOV AX,[CLUSNUM]
755 MOV ES:[DI.sf_lstclus],AX
756 MOV AX,[LASTPOS]
757 MOV ES:[DI.sf_cluspos],AX
758
759 ; Inputs:
760 ; ES:DI points to SFT
761 ; CX is No. Bytes transferred
762 ; Function:
763 ; Update the SFT offset based on the transfer
764 ; Outputs:
765 ; sf_position updated to point to first byte after transfer
766 ; ES:DI points to SFT
767 ; CX No. of bytes transferred
768 ; Carry clear
769
770 entry AddRec
771 DOSAssume CS,<DS>,"AddRec"
772 ASSUME ES:NOTHING
773
774 Assert ISSFT,<ES,DI>,"AddRec"
775 JCXZ RET28 ; If no records read, don't change position
776 ADD WORD PTR ES:[DI.sf_position],CX ; Update current position
777 ADC WORD PTR ES:[DI.sf_position+2],0
778 RET28: CLC
779 return
780 EndProc DISKREAD
781
782 CODE ENDS
783 END
784 \1a