summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/DISK2.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/DISK2.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DOS/DISK2.ASM')
-rw-r--r--v4.0/src/DOS/DISK2.ASM784
1 files changed, 784 insertions, 0 deletions
diff --git a/v4.0/src/DOS/DISK2.ASM b/v4.0/src/DOS/DISK2.ASM
new file mode 100644
index 0000000..bb76e89
--- /dev/null
+++ b/v4.0/src/DOS/DISK2.ASM
@@ -0,0 +1,784 @@
1; SCCSID = @(#)disk2.asm 1.3 85/06/19
2; SCCSID = @(#)disk2.asm 1.3 85/06/19
3TITLE DISK2 - Disk utility routines
4NAME 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
31include dosseg.asm
32
33CODE SEGMENT BYTE PUBLIC 'CODE'
34 ASSUME SS:DOSGROUP,CS:DOSGROUP
35
36.xcref
37INCLUDE DOSSYM.INC
38INCLUDE DEVSYM.INC
39include version.inc
40.cref
41.list
42
43Installed = 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
79IF 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
87ENDIF
88
89
90Break <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
109ASSUME 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
120Break <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
137ASSUME 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
150NO_CAR2:
151 return
152
153Break <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
172ASSUME 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
181DODSKOP:
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
198EndProc DskRead
199
200
201
202Break <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
217ASSUME 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
228DO_ERR:
229 invoke HARDERR
230 return
231
232EndProc HARDERRRW
233
234Break <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]
271ASSUME 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
319NOSETSTUFF:
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
329NoDec:
330 MOV CX,AX ; Can do this much
331 JCXZ NOROOM ; Silly user gave Xaddr of FFFF in segment
332OK:
333 return
334
335EOFERR:
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;;;;;;;;;;;
341NOROOM:
342 POP BX ; Kill return address
343 CLC
344 return ; RETURN TO CALLER OF CALLER
345EndProc SETUP
346
347Break <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
374SAVFIR:
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
388RET45:
389 return
390EndProc 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
404ERR_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
413HARD_ERR:
414 invoke LOCK_VIOLATION
415 retnc ; User wants Retrys
416NO_HARD_ERR:
417 XOR CX,CX ;No bytes transferred
418 MOV AX,error_lock_violation
419 STC
420 return
421
422EndProc 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
434EndProc WRITE_LOCK_VIOLATION
435
436
437Break <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
472ENUF:
473 invoke CHECK_READ_LOCK ;IFS. check read lock ;AN000;
474 JNC Read_Ok ; There are no locks
475 return
476
477READ_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;------------------------------------------------------------------------
487IF NOT IBMCOPYRIGHT
488 JC SET_ACC_ERR_DS ; fix to take care of I24 fail
489 ; migrated from 330a - HKN
490ENDIF
491;------------------------------------------------------------------------
492 OR CX,CX
493 JZ SKIPERR
494RDERR:
495 MOV [DISK_FULL],1 ;MS. EOF detection ;AN000;
496 MOV AH,0EH ;MS. read/data/fail ;AN000;
497 transfer WRTERR22
498RDLASTJ:JMP RDLAST
499SETSFTJ2: JMP SETSFT
500
501CANOT_READ:
502 POP CX ; Clean stack
503 POP CX
504 POP BX
505
506 entry SET_ACC_ERR_DS
507ASSUME 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
518SKIPERR:
519 MOV [LASTPOS],DX
520 MOV [CLUSNUM],BX
521 CMP [BYTCNT1],0
522 JZ RDMID
523 invoke BUFRD
524 JC SET_ACC_ERR_DS
525RDMID:
526 CMP [SECCNT],0
527 JZ RDLASTJ
528 invoke NEXTSEC
529 JC SETSFTJ2
530 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
531ONSEC:
532 MOV DL,[SECCLUSPOS]
533 MOV CX,[SECCNT]
534 MOV BX,[CLUSNUM]
535RDLP:
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]
543ASSUME DS:NOTHING
544 PUSH DX
545 PUSH CX
546 invoke SET_RQ_SC_PARMS ;LB. do this for SC ;AN000;
547
548IF BUFFERFLAG
549 pushf
550 cmp [BUF_EMS_SAFE_FLAG], 1
551 je safe_read
552 call save_map
553 call restore_user_map
554safe_read:
555 popf
556ENDIF
557
558 invoke DREAD
559
560IF BUFFERFLAG
561 pushf
562 cmp [BUF_EMS_SAFE_FLAG], 1
563 je safe_mapping
564 call save_user_map
565 call restore_map
566safe_mapping:
567 popf
568ENDIF
569
570 POP BX
571 POP DX
572 JNC SKP_CANOT_READ
573 JMP CANOT_READ
574SKP_CANOT_READ:
575 MOV [TEMP_VAR],BX ;LB. save sector count ;AN000;
576 MOV [TEMP_VAR2],DX ;LB. 1st sector ;AN000;
577SCAN_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
598IF NOT BUFFERFLAG
599 JMP SHORT end_scan ;LB. ;AN000;
600ELSE
601 JMP END_SCAN
602ENDIF
603
604yesdirty:
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
610IF 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;
614ELSE
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;
645ENDIF
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]
654NXTBUF: ; 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;
659inrange:
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
685EVENMOV:
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;
692CLBUFF:
693 invoke SCANPLACE
694DONXTBUF:
695 CMP DI,[FIRST_BUFF_ADDR] ;LB. end of buffers ;AN000;
696 JNZ NXTBUF
697end_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;
703SCAN_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
715RDLAST:
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
778RET28: CLC
779 return
780EndProc DISKREAD
781
782CODE ENDS
783 END
784 \ No newline at end of file