summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/DEV.ASM
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--v4.0/src/DOS/DEV.ASM841
1 files changed, 841 insertions, 0 deletions
diff --git a/v4.0/src/DOS/DEV.ASM b/v4.0/src/DOS/DEV.ASM
new file mode 100644
index 0000000..20c3f74
--- /dev/null
+++ b/v4.0/src/DOS/DEV.ASM
@@ -0,0 +1,841 @@
1; SCCSID = @(#)dev.asm 1.2 85/07/23
2; SCCSID = @(#)dev.asm 1.2 85/07/23
3TITLE DEV - Device call routines
4NAME Dev
5; Misc Routines to do 1-12 low level I/O and call devices
6;
7; IOFUNC
8; DEVIOCALL
9; SETREAD
10; SETWRITE
11; DEVIOCALL2
12; DEV_OPEN_SFT
13; DEV_CLOSE_SFT
14; RW_SC
15; IN_SC
16; INVALIDATE_SC
17; VIRREAD
18; SC2BUF
19;
20; Revision history:
21;
22; A000 version 4.00 Jan. 1988
23; A010 disable change line for SHARE /NC
24
25;
26; get the appropriate segment definitions
27;
28.xlist
29include dosseg.asm
30
31CODE SEGMENT BYTE PUBLIC 'CODE'
32 ASSUME SS:DOSGROUP,CS:DOSGROUP
33
34.xcref
35INCLUDE DOSSYM.INC
36INCLUDE DEVSYM.INC
37include version.inc
38.cref
39.list
40
41 i_need IOXAD,DWORD
42 i_need IOSCNT,WORD
43 i_need DEVIOBUF,4
44 i_need IOCALL,BYTE
45 i_need IOMED,BYTE
46 i_need IORCHR,BYTE
47 i_need CALLSCNT,WORD
48 i_need DMAAdd,DWORD
49 i_need CallDevAd,DWORD
50 i_need CallXAD,DWORD
51 i_need DPBHead,DWORD
52 i_need ThisSFT,DWORD
53 i_need ThisDPB,DWORD
54 i_need DevCall,DWORD
55 i_need VerFlg,BYTE
56 i_need HIGH_SECTOR,WORD ;AN000;
57 i_need CALLSSEC,WORD ;AN000;
58 i_need CALLNEWSC,DWORD ;AN000;
59 i_need SC_CACHE_COUNT,WORD ;AN000;
60 i_need SC_CACHE_PTR,DWORD ;AN000;
61 i_need CURSC_SECTOR,WORD ;AN000;
62 i_need SEQ_SECTOR,DWORD ;AN000;
63 i_need SC_SECTOR_SIZE,WORD ;AN000;
64 i_need CURSC_DRIVE,BYTE ;AN000;
65 i_need SC_DRIVE,BYTE ;AN000;
66 i_need SC_STATUS,WORD ;AN000;
67 i_need SC_FLAG,BYTE ;AN000;
68 i_need TEMP_VAR,WORD ;AN000;
69 i_need TEMP_VAR2,WORD ;AN000;
70 i_need InterChar,BYTE ;AN000; interim character flag 2/13/KK
71 i_need InterCon,BYTE ;AN000; Console mode flag(1:interim mode) 2/13/KK
72 i_need SaveCurFlg,BYTE ;AN000; Console out mode(1:print & don't adv cursor) 2 /13/KK
73 i_need DDMOVE,BYTE ;AN000; flag for DWORD move
74 i_need DOS34_FLAG,WORD ;AN000;
75 i_need fshare,BYTE ;AN010; share flag
76
77Break <IOFUNC -- DO FUNCTION 1-12 I/O>
78
79; Inputs:
80; DS:SI Points to SFT
81; AH is function code
82; = 0 Input
83; = 1 Input Status
84; = 2 Output
85; = 3 Output Status
86; = 4 Flush
87; = 5 Input Status - System WAIT invoked for K09 if no char
88; present.
89; AL = character if output
90; Function:
91; Perform indicated I/O to device or file
92; Outputs:
93; AL is character if input
94; If a status call
95; zero set if not ready
96; zero reset if ready (character in AL for input status)
97; For regular files:
98; Input Status
99; Gets character but restores position
100; Zero set on EOF
101; Input
102; Gets character advances position
103; Returns ^Z on EOF
104; Output Status
105; Always ready
106; AX altered, all other registers preserved
107
108 procedure IOFUNC,NEAR
109ASSUME DS:NOTHING,ES:NOTHING
110
111 Assert ISSFT,<DS,SI>,"IOFUNC"
112 MOV WORD PTR [IOXAD+2],SS
113 MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF
114 MOV WORD PTR [IOSCNT],1
115 MOV WORD PTR [DEVIOBUF],AX
116 TEST [SI.sf_flags],sf_isnet
117 JZ IOTO22 ;AN000;
118 JMP IOTOFILE ;AN000;
119IOTO22:
120 TEST [SI.sf_flags],devid_device
121 JNZ IOTo33 ;AN000;
122 JMP IOTOFILE ;AN000;
123IOTO33:
124 invoke save_world
125 MOV DX,DS
126 MOV BX,SS
127 MOV DS,BX
128 MOV ES,BX
129 ASSUME DS:DOSGroup
130 XOR BX,BX
131 cmp ah,5 ; system wait enabled?
132 jnz no_sys_wait
133 or bx,0400H ; Set bit 10 in status word for driver
134 ; It is up to device driver to carry out
135 ; appropriate action.
136no_sys_wait:
137 MOV [IOCALL.REQSTAT],BX
138 XOR BX,BX
139 MOV BYTE PTR [IOMED],BL
140
141Table Segment
142Public DEV001S, DEV001E ; Pathgen labels
143DEV001s:
144; length of packets
145LenTab DB DRDWRHL, DRDNDHL, DRDWRHL, DSTATHL, DFLSHL, DRDNDHL
146
147; Error Function
148
149CmdTab DB 86h, DEVRD ; 0 input
150 DB 86h, DEVRDND ; 1 input status
151 DB 87h, DEVWRT ; 2 output
152 DB 87h, DEVOST ; 3 output status
153 DB 86h, DEVIFL ; 4 input flush
154 DB 86H, DEVRDND ; 5 input status with system WAIT
155DEV001E:
156Table ENDS
157
158 MOV BL,AH ; get function
159 MOV AH,LenTab[BX]
160 SHL BX,1
161 MOV CX,WORD PTR CmdTab[BX]
162
163 MOV BX,OFFSET DOSGROUP:IOCALL
164
165 MOV [IOCALL.REQLEN],AH
166 MOV [IOCALL.REQFUNC],CH
167 IF DBCS ;AN000;
168;----------------------------- Start of DBCS 2/13/KK
169 PUSH CX ;AN000;
170 MOV CL, [InterCon] ;AN000;
171 CMP CH, DEVRD ;AN000; 0 input
172 JZ SETIN ;AN000;
173 CMP CH, DEVRDND ;AN000; 1(5) input status without(with) system WAIT
174 JZ SETIN ;AN000;
175 MOV CL, [SaveCurflg] ;AN000;
176 CMP CH, DEVWRT ;AN000; 2 output
177 JZ CHKERROUT ;AN000;
178 XOR CL,CL ;AN000; else, do normal
179SETIN: ;AN000;
180 MOV BYTE PTR [IoMed], CL ;AN000; set interim I/O indication
181 POP CX ;AN000;
182;----------------------------- End of DBCS 2/13/KK
183 ENDIF ;AN000;
184 MOV DS,DX
185ASSUME DS:NOTHING
186 CALL DEVIOCALL
187 MOV DI,[IOCALL.REQSTAT]
188 TEST DI,STERR
189 JNZ DevErr
190OkDevIO:
191 MOV AX,SS
192 MOV DS,AX
193 ASSUME DS:DOSGroup
194 IF DBCS ;AN000;
195 MOV [InterChar],0 ;AN000; reset interim character flag 2/13/KK
196 TEST DI,Ddkey ;AN000; is this a dead key (interim char)? 2/13/KK
197 JZ NotInterim ;AN000; no, flag already reset... 2/13/KK
198 INC [InterChar] ;AN000; yes, set flag for future 2/13/KK
199NotInterim: ;AN000; 2/13/KK
200 ENDIF ;AN000;
201 CMP CH,DEVRDND
202 JNZ DNODRD
203 MOV AL,BYTE PTR [IORCHR]
204 MOV [DEVIOBUF],AL
205
206DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1]
207 NOT AH ; Zero = busy, not zero = ready
208 AND AH,STBUI SHR 8
209
210QuickReturn: ;AN000; 2/13/KK
211 invoke restore_world
212ASSUME DS:NOTHING
213 MOV AX,WORD PTR [DEVIOBUF]
214 return
215
216;IOTOFILEJ:
217; JMP SHORT IOTOFILE
218 IF DBCS ;AN000;
219;------------------------------ Start of DBCS 2/13/KK
220CHKERROUT: ;AN000;
221 MOV DS, DX ;AN000;
222 TEST [SI.sf_flags], devid_device_con_out ;AN000; output to console ?
223 JNZ GOOD ;AN000; yes
224 CMP CL, 01 ;AN000; write interim ?
225 JNZ GOOD ;AN000; no,
226 POP CX ;AN000;
227 JMP SHORT QuickReturn ;AN000; avoid writting interims to other than
228 ;AN000; console device
229GOOD: ;AN000;
230 PUSH SS ;AN000;
231 POP DS ;AN000;
232 JMP SETIN ;AN000;
233;------------------------------ End of DBCS 2/13/KK
234 ENDIF ;AN000;
235DevErr:
236 TEST CS:[DOS34_FLAG],X25_Special ;AN000; from disk.asm
237 JZ notx25 ;AN000; no
238 PUSH AX ;AN000; unknown command ?
239 MOV AX,DI ;AN000;
240 AND AX,error_I24_bad_command ;AN000;
241 CMP AL,error_I24_bad_command ;AN000;
242 POP AX ;AN000;
243 JNZ notx25 ;AN000; no, then error
244 JMP okDevIO ;AN000;
245notx25:
246 MOV AH,CL
247 invoke CHARHARD
248 CMP AL,1
249 JNZ NO_RETRY
250 invoke restore_world
251 JMP IOFUNC
252
253NO_RETRY:
254; Know user must have wanted Ignore OR Fail. Make sure device shows ready
255; so that DOS doesn't get caught in a status loop when user simply wants
256; to ignore the error.
257 AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8)
258 JMP OKDevIO
259
260IOTOFILE:
261ASSUME DS:NOTHING
262 OR AH,AH
263 JZ IOIN
264 DEC AH
265 JZ IOIST
266 DEC AH
267 JZ IOUT
268 return ; NON ZERO FLAG FOR OUTPUT STATUS
269
270IOIST:
271 PUSH WORD PTR [SI.sf_position] ; Save position
272 PUSH WORD PTR [SI.sf_position+2]
273 CALL IOIN
274 POP WORD PTR [SI.sf_position+2] ; Restore position
275 POP WORD PTR [SI.sf_position]
276 return
277
278IOUT:
279 CALL SETXADDR
280 invoke DOS_WRITE
281 CALL RESTXADDR ; If you change this into a jmp don't
282 return ; come crying to me when things don't
283 ; work ARR
284
285IOIN:
286 CALL SETXADDR
287 OR [DOS34_FLAG],Disable_EOF_I24 ;AN000;
288 invoke DOS_READ
289 AND [DOS34_FLAG],NO_Disable_EOF_I24 ;AN000;
290 OR CX,CX ; Check EOF
291 CALL RESTXADDR
292 MOV AL,[DEVIOBUF] ; Get byte from trans addr
293 retnz
294 MOV AL,1AH ; ^Z if no bytes
295 return
296
297SETXADDR:
298 POP WORD PTR [CALLSCNT] ; Return address
299 invoke save_world
300 PUSH WORD PTR [DMAADD] ; Save Disk trans addr
301 PUSH WORD PTR [DMAADD+2]
302 MOV WORD PTR [THISSFT+2],DS
303 Context DS
304 MOV WORD PTR [THISSFT],SI ; Finish setting SFT pointer
305 MOV CX,WORD PTR [IOXAD+2]
306 MOV WORD PTR [DMAADD+2],CX
307 MOV CX,WORD PTR [IOXAD]
308 MOV WORD PTR [DMAADD],CX ; Set byte trans addr
309 MOV CX,[IOSCNT] ; ioscnt specifies length of buffer
310 JMP SHORT RESTRET ; RETURN ADDRESS
311
312RESTXADDR:
313 DOSAssume CS,<DS>,"RestXAddr"
314 POP WORD PTR [CALLSCNT] ; Return address
315 POP WORD PTR [DMAADD+2] ; Restore Disk trans addr
316 POP WORD PTR [DMAADD]
317 invoke restore_world
318ASSUME DS:NOTHING
319RESTRET:JMP WORD PTR [CALLSCNT] ; Return address
320EndProc IOFUNC
321
322Break <DEV_OPEN_SFT, DEV_CLOSE_SFT - OPEN or CLOSE A DEVICE>
323
324; Inputs:
325; ES:DI Points to SFT
326; Function:
327; Issue an OPEN call to the correct device
328; Outputs:
329; None
330; ALL preserved
331
332 procedure DEV_OPEN_SFT,NEAR
333ASSUME DS:NOTHING,ES:NOTHING
334
335 Assert ISSFT,<ES,DI>,"Dev_Open_SFT"
336 invoke Save_World
337 MOV AL,DEVOPN
338 JMP SHORT DO_OPCLS
339
340EndProc DEV_OPEN_SFT
341
342; Inputs:
343; ES:DI Points to SFT
344; Function:
345; Issue a CLOSE call to the correct device
346; Outputs:
347; None
348; ALL preserved
349
350 procedure DEV_CLOSE_SFT,NEAR
351ASSUME DS:NOTHING,ES:NOTHING
352
353 Assert ISSFT,<ES,DI>,"Dev_Close_SFT"
354 invoke Save_World
355 MOV AL,DEVCLS
356
357;
358; Main entry for device open and close. AL contains the function requested.
359; Subtlety: if Sharing is NOT loaded then we do NOT issue open/close to block
360; devices. This allows networks to function but does NOT hang up with bogus
361; change-line code.
362;
363 entry DO_OPCLS
364;
365; Is the SFT for the net? If so, no action necessary.
366;
367 invoke Test_IFS_Remote ;AC000;
368 JNZ OPCLS_DONE ; NOP on net SFTs
369 XOR AH,AH ; Unit
370 TEST ES:[DI.sf_flags],devid_device
371 LES DI,ES:[DI.sf_devptr] ; Get DPB or device
372 JNZ Got_Dev_Addr
373;
374; We are about to call device open/close on a block driver. If no sharing
375; then just short circuit to done.
376;
377;;;;; invoke CheckShare
378 CMP fshare,1 ;AN010; /NC or no SHARE
379 JBE opCLs_Done ;AN010; yes
380 MOV AH,ES:[DI.dpb_UNIT]
381 MOV CL,ES:[DI.dpb_drive]
382 LES DI,ES:[DI.dpb_driver_addr] ; Get device
383GOT_DEV_ADDR: ; ES:DI -> device
384 TEST ES:[DI.SDEVATT],DEVOPCL
385 JZ OPCLS_DONE ; Device can't
386 PUSH ES
387 POP DS
388 MOV SI,DI ; DS:SI -> device
389OPCLS_RETRY:
390 Context ES
391 MOV DI,OFFSET DOSGROUP:DEVCALL
392 MOV BX,DI
393 PUSH AX
394 MOV AL,DOPCLHL
395 STOSB ; Length
396 POP AX
397 XCHG AH,AL
398 STOSB ; Unit
399 XCHG AH,AL
400 STOSB ; Command
401 MOV WORD PTR ES:[DI],0 ; Status
402 PUSH AX ; Save Unit,Command
403 invoke DEVIOCALL2
404 MOV DI,ES:[BX.REQSTAT]
405 TEST DI,STERR
406 JZ OPCLS_DONEP ; No error
407 TEST [SI.SDEVATT],DEVTYP
408 JZ BLKDEV
409 MOV AH,86H ; Read error in data, Char dev
410 JMP SHORT HRDERR
411
412BLKDEV:
413 MOV AL,CL ; Drive # in AL
414 MOV AH,6 ; Read error in data, Blk dev
415HRDERR:
416 invoke CHARHARD
417 CMP AL,1
418 JNZ OPCLS_DONEP ; IGNORE or FAIL
419 ; Note that FAIL is essentually IGNORED
420 POP AX ; Get back Unit, Command
421 JMP OPCLS_RETRY
422
423OPCLS_DONEP:
424 POP AX ; Clean stack
425OPCLS_DONE:
426 invoke Restore_World
427 return
428
429EndProc DEV_CLOSE_SFT
430
431Break <DEVIOCALL, DEVIOCALL2 - CALL A DEVICE>
432
433; Inputs:
434; DS:SI Points to device SFT
435; ES:BX Points to request data
436; Function:
437; Call the device
438; Outputs:
439; DS:SI -> Device driver
440; DS:SI,AX destroyed, others preserved
441
442 procedure DEVIOCALL,NEAR
443ASSUME DS:NOTHING,ES:NOTHING
444
445 Assert ISSFT,<DS,SI>,"DevIOCall"
446 LDS SI,[SI.sf_devptr]
447
448 entry DEVIOCALL2
449
450 EnterCrit critDevice
451
452 TEST [SI.SDEVATT],DevTyp ;AN000; >32mb block device ?
453 JNZ chardev2 ;AN000; >32mb no
454 CMP ES:[BX.REQFUNC],DEVRD ;AN000; >32mb read ?
455 JZ chkext ;AN000; >32mb yes
456 CMP ES:[BX.REQFUNC],DEVWRT ;AN000; >32mb write ?
457 JZ chkext ;AN000; >32mb yes
458 CMP ES:[BX.REQFUNC],DEVWRTV;AN000; >32mb write/verify ?
459 JNZ chardev2 ;AN000; >32mb no
460chkext:
461 CALL RW_SC ;AN000;LB. use secondary cache if there
462 JC dev_exit ;AN000;LB. done
463
464 TEST [SI.SDEVATT],EXTDRVR ;AN000;>32mb extended driver?
465 JZ chksector ;AN000;>32mb no
466 ADD BYTE PTR ES:[BX],8 ;AN000;>32mb make length to 30
467 MOV AX,[CALLSSEC] ;AN000;>32mb
468 MOV [CALLSSEC],-1 ;AN000;>32mb old sector =-1
469 MOV WORD PTR [CALLNEWSC],AX ;AN000;>32mb new sector =
470 MOV AX,[HIGH_SECTOR] ;AN000; >32mb low sector,high sector
471 MOV WORD PTR [CALLNEWSC+2],AX ;AN000; >32mb
472 JMP chardev2 ;AN000; >32mb
473chksector: ;AN000; >32mb
474 CMP [HIGH_SECTOR],0 ;AN000; >32mb if >32mb
475 JZ chardev2 ;AN000; >32mb then fake error
476 MOV ES:[BX.REQSTAT],STERR+STDON+ERROR_I24_NOT_DOS_DISK ;AN000; >32mb
477 JMP SHORT dev_exit ;AN000; >32mb
478
479chardev2: ;AN000;
480; As above only DS:SI points to device header on entry, and DS:SI is preserved
481 MOV AX,[SI.SDEVSTRAT]
482 MOV WORD PTR [CALLDEVAD],AX
483 MOV WORD PTR [CALLDEVAD+2],DS
484 CALL DWORD PTR [CALLDEVAD]
485 MOV AX,[SI.SDEVINT]
486 MOV WORD PTR [CALLDEVAD],AX
487 CALL DWORD PTR [CALLDEVAD]
488 CALL VIRREAD ;AN000;LB. move data from SC to buffer
489 JC chardev2 ;AN000;LB. bad sector or exceeds max sec
490dev_exit:
491 LeaveCrit critDevice
492 return
493EndProc DEVIOCALL
494
495Break <SETREAD, SETWRITE -- SET UP HEADER BLOCK>
496
497; Inputs:
498; DS:BX = Transfer Address
499; CX = Record Count
500; DX = Starting Record
501; AH = Media Byte
502; AL = Unit Code
503; Function:
504; Set up the device call header at DEVCALL
505; Output:
506; ES:BX Points to DEVCALL
507; No other registers effected
508
509 procedure SETREAD,NEAR
510ASSUME DS:NOTHING,ES:NOTHING
511
512 PUSH DI
513 PUSH CX
514 PUSH AX
515 MOV CL,DEVRD
516SETCALLHEAD:
517 MOV AL,DRDWRHL
518 PUSH SS
519 POP ES
520 MOV DI,OFFSET DOSGROUP:DEVCALL
521 STOSB ; length
522 POP AX
523 STOSB ; Unit
524 PUSH AX
525 MOV AL,CL
526 STOSB ; Command code
527 XOR AX,AX
528 STOSW ; Status
529 ADD DI,8 ; Skip link fields
530 POP AX
531 XCHG AH,AL
532 STOSB ; Media byte
533 XCHG AL,AH
534 PUSH AX
535 MOV AX,BX
536 STOSW
537 MOV AX,DS
538 STOSW ; Transfer addr
539 POP CX ; Real AX
540 POP AX ; Real CX
541 STOSW ; Count
542 XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX
543 STOSW ; Start
544 XCHG AX,CX
545 XCHG DX,CX
546 POP DI
547 MOV BX,OFFSET DOSGROUP:DEVCALL
548 return
549
550 entry SETWRITE
551ASSUME DS:NOTHING,ES:NOTHING
552
553; Inputs:
554; DS:BX = Transfer Address
555; CX = Record Count
556; DX = Starting Record
557; AH = Media Byte
558; AL = Unit Code
559; Function:
560; Set up the device call header at DEVCALL
561; Output:
562; ES:BX Points to DEVCALL
563; No other registers effected
564
565 PUSH DI
566 PUSH CX
567 PUSH AX
568 MOV CL,DEVWRT
569 ADD CL,[VERFLG]
570 JMP SHORT SETCALLHEAD
571EndProc SETREAD
572
573
574Break <RW_SC -- Read Write Secondary Cache>
575
576; Inputs:
577; [SC_CACHE_COUNT]= secondary cache count
578; [SC_STATUS]= SC validity status
579; [SEQ_SECTOR]= last sector read
580; Function:
581; Read from or write through secondary cache
582; Output:
583; ES:BX Points to DEVCALL
584; carry clear, I/O is not done
585; [SC_FLAG]=1 if continuos sectors will be read
586; carry set, I/O is done
587
588
589 procedure RW_SC,NEAR ;AN000;
590ASSUME DS:NOTHING,ES:NOTHING ;AN000;
591
592 CMP [SC_CACHE_COUNT],0 ;AN000;LB. secondary cache exists?
593 JZ scexit4 ;AN000;LB. no, do nothing
594 CMP [CALLSCNT],1 ;AN000;LB. sector count = 1 (buffer I/O)
595 JNZ scexit4 ;AN000;LB. no, do nothing
596 PUSH CX ;AN000;;LB.
597 PUSH DX ;AN000;;LB. yes
598 PUSH DS ;AN000;;LB. save registers
599 PUSH SI ;AN000;;LB.
600 PUSH ES ;AN000;;LB.
601 PUSH DI ;AN000;;LB.
602 MOV DX,WORD PTR [CALLSSEC] ;AN000;;LB. starting sector
603 CMP BYTE PTR [DEVCALL.REQFUNC],DEVRD ;AN000;LB. read ? ;AN000;
604 JZ doread ;AN000;LB. yes ;AN000;
605 CALL INVALIDATE_SC ;AN000;LB. invalidate SC ;AN000;
606 JMP scexit2 ;AN000;LB. back to normal ;AN000;
607scexit4: ;AN000; ;AN000;
608 CLC ;AN000;LB. I/O not done yet ;AN000;
609 return ;AN000;LB. ;AN000;
610doread: ;AN000; ;AN000;
611 CALL SC2BUF ;AN000;LB. check if in SC ;AN000;
612 JC readSC ;AN000;LB. ;AN000;
613 MOV [DEVCALL.REQSTAT],STDON ;AN000;LB. fake done and ok ;AN000;
614 STC ;AN000;LB. set carry ;AN000;
615 JMP saveseq ;AN000;LB. save seq. sector # ;AN000;
616readSC: ;AN000;
617 MOV AX,WORD PTR [HIGH_SECTOR] ;AN000;;LB. subtract sector num from
618 MOV CX,WORD PTR [CALLSSEC] ;AN000;;LB. saved sequential sector
619 SUB CX,WORD PTR [SEQ_SECTOR] ;AN000;;LB. number
620 SBB AX,WORD PTR [SEQ_SECTOR+2] ;AN000;;LB.
621 CMP AX,0 ;AN000;;LB. greater than 64K
622 JNZ saveseq2 ;AN000;;LB. yes,save seq. sector #
623chklow: ;AN000;
624 CMP CX,1 ;AN000;;LB. <= 1
625 JA saveseq2 ;AN000;;LB. no, not sequential
626 MOV [SC_STATUS],-1 ;AN000;;LB. prsume all SC valid
627 MOV AX,[SC_CACHE_COUNT] ;AN000;;LB. yes, sequential
628 MOV [CALLSCNT],AX ;AN000;;LB. read continuous sectors
629readsr:
630 MOV AX,WORD PTR [CALLXAD+2] ;AN000;;LB. save buffer addr
631 MOV [TEMP_VAR2],AX ;AN000;;LB. in temp vars
632 MOV AX,WORD PTR [CALLXAD] ;AN000;;LB.
633 MOV [TEMP_VAR],AX ;AN000;;LB.
634 ;AN000;
635 MOV AX,WORD PTR [SC_CACHE_PTR] ;AN000;LB. use SC cache addr as ;AN000;
636 MOV WORD PTR [CALLXAD],AX ;AN000;LB. transfer addr ;AN000;
637 MOV AX,WORD PTR [SC_CACHE_PTR+2] ;AN000;LB. ;AN000;
638 MOV WORD PTR [CALLXAD+2],AX ;AN000;LB. ;AN000;
639 MOV [SC_FLAG],1 ;AN000;LB. flag it for later ;AN000;
640 MOV AL,[SC_DRIVE] ;AN000;;LB. current drive
641 MOV [CURSC_DRIVE],AL ;AN000;;LB. set current drive
642 MOV AX,WORD PTR [CALLSSEC] ;AN000;;LB. current sector
643 MOV [CURSC_SECTOR],AX ;AN000;;LB. set current sector
644 MOV AX,WORD PTR [CALLSSEC+2] ;AN000;;LB.
645 MOV [CURSC_SECTOR+2],AX ;AN000;;LB.
646saveseq2: ;AN000;
647 CLC ;AN000;LB. clear carry ;AN000;
648saveseq: ;AN000; ;AN000;
649 MOV AX,[HIGH_SECTOR] ;AN000;LB. save current sector # ;AN000;
650 MOV WORD PTR [SEQ_SECTOR+2],AX ;AN000;LB. for access mode ref. ;AN000;
651 MOV AX,[CALLSSEC] ;AN000;LB. ;AN000;
652 MOV WORD PTR [SEQ_SECTOR],AX ;AN000;LB. ;AN000;
653 JMP scexit ;AN000;LB. ;AN000;
654 ;AN000;
655scexit2: ;AN000;LB. ;AN000;
656 CLC ;AN000;LB. clear carry ;AN000;
657scexit: ;AN000; ;AN000;
658 POP DI ;AN000;;LB.
659 POP ES ;AN000;;LB. restore registers
660 POP SI ;AN000;;LB.
661 POP DS ;AN000;;LB.
662 POP DX ;AN000;;LB.
663 POP CX ;AN000;;LB.
664 return ;AN000;;LB.
665 ;AN000;
666EndProc RW_SC ;AN000;
667
668Break <IN_SC -- check if in secondary cache>
669
670; Inputs: [SC_DRIVE]= requesting drive
671; [CURSC_DRIVE]= current SC drive
672; [CURSC_SECTOR] = starting scetor # of SC
673; [SC_CACHE_COUNT] = SC count
674; [HIGH_SECTOR]:DX= sector number
675; Function:
676; Check if the sector is in secondary cache
677; Output:
678; carry clear, in SC
679; CX= the index in the secondary cache
680; carry set, not in SC
681;
682
683 procedure IN_SC,NEAR ;AN000;
684ASSUME DS:NOTHING,ES:NOTHING ;AN000;
685
686 MOV AL,[SC_DRIVE] ;AN000;;LB. current drive
687 CMP AL,[CURSC_DRIVE] ;AN000;;LB. same as SC drive
688 JNZ outrange2 ;AN000;;LB. no
689 MOV AX,WORD PTR [HIGH_SECTOR] ;AN000;;LB. subtract sector num from
690 MOV CX,DX ;AN000;;LB. secondary starting sector
691 SUB CX,WORD PTR [CURSC_SECTOR] ;AN000;;LB. number
692 SBB AX,WORD PTR [CURSC_SECTOR+2] ;AN000;;LB.
693 CMP AX,0 ;AN000;;LB. greater than 64K
694 JNZ outrange2 ;AN000;;LB. yes
695 CMP CX,[SC_CACHE_COUNT] ;AN000;;LB. greater than SC count
696 JAE outrange2 ;AN000;;LB. yes
697 CLC ;AN000;;LB. clear carry
698 JMP short inexit ;AN000;;LB. in SC
699outrange2: ;AN000;;LB. set carry
700 STC ;AN000;;LB.
701inexit: ;AN000;;LB.
702 return ;AN000;;LB.
703
704EndProc IN_SC ;AN000;
705
706Break <INVALIDATE_SC - invalide secondary cache>
707
708; Inputs: [SC_DRIVE]= requesting drive
709; [CURSC_DRIVE]= current SC drive
710; [CURSC_SECTOR] = starting scetor # of SC
711; [SC_CACHE_COUNT] = SC count
712; [SC_STAUS] = SC status word
713; [HIGH_SECTOR]:DX= sceotor number
714;
715; Function:
716; invalidate secondary cache if in there
717; Output:
718; [SC_STATUS] is updated
719;
720
721 procedure INVALIDATE_SC,NEAR ;AN000;
722ASSUME DS:NOTHING,ES:NOTHING ;AN000;
723
724 CALL IN_SC ;AN000;;LB. in secondary cache
725 JC outrange ;AN000;;LB. no
726 MOV AX,1 ;AN000;;LB. invalidate the sector
727 SHL AX,CL ;AN000;;LB. in the secondary cache
728 NOT AX ;AN000;;LB.
729 AND [SC_STATUS],AX ;AN000;;LB. save the status
730outrange: ;AN000;;LB.
731 return ;AN000;;LB.
732
733EndProc INVALIDATE_SC ;AN000;
734
735
736Break <VIRREAD- virtually read data into buffer>
737
738; Inputs: SC_FLAG = 0 , no sectors were read into SC
739; 1, continous sectors were read into SC
740; Function:
741; Move data from SC to buffer
742; Output:
743; carry clear, data is moved to buffer
744; carry set, bad sector or exceeds maximum sector
745; SC_FLAG =0
746; CALLSCNT=1
747; SC_STATUS= -1 if succeeded
748; 0 if failed
749
750 procedure VIRREAD,NEAR ;AN000;
751ASSUME DS:NOTHING,ES:NOTHING ;AN000;
752
753 CMP [SC_FLAG],0 ;AN000;;LB. from SC fill
754 JZ sc2end ;AN000;;LB. no
755 MOV AX,[TEMP_VAR2] ;AN000;;LB. restore buffer addr
756 MOV WORD PTR [CALLXAD+2],AX ;AN000;;LB.
757 MOV AX,[TEMP_VAR] ;AN000;;LB.
758 MOV WORD PTR [CALLXAD],AX ;AN000;;LB.
759 MOV [SC_FLAG],0 ;AN000;;LB. reset sc_flag
760 MOV [CALLSCNT],1 ;AN000;;LB. one sector transferred
761
762 TEST [DEVCALL.REQSTAT],STERR ;AN000;;LB. error?
763 JNZ scerror ;AN000;;LB. yes
764 PUSH DS ;AN000;;LB.
765 PUSH SI ;AN000;;LB.
766 PUSH ES ;AN000;;LB.
767 PUSH DI ;AN000;;LB.
768 PUSH DX ;AN000;;LB.
769 PUSH CX ;AN000;;LB.
770 XOR CX,CX ;AN000;;LB. we want first sector in SC
771 CALL SC2BUF2 ;AN000;;LB. move data from SC to buffer
772 POP CX ;AN000;;LB.
773 POP DX ;AN000;;LB.
774 POP DI ;AN000;;LB.
775 POP ES ;AN000;;LB.
776 POP SI ;AN000;;LB.
777 POP DS ;AN000;;LB.
778 JMP SHORT sc2end ;AN000;;LB. return
779
780scerror: ;AN000;
781 MOV [CALLSCNT],1 ;AN000;;LB. reset sector count to 1
782 MOV [SC_STATUS],0 ;AN000;;LB. invalidate all SC sectors
783 MOV [CURSC_DRIVE],-1 ;AN000;;LB. invalidate drive
784 STC ;AN000;;LB. carry set
785 return ;AN000;;LB.
786
787sc2end: ;AN000;
788 CLC ;AN000;;LB. carry clear
789 return ;AN000;;LB.
790
791EndProc VIRREAD ;AN000;
792
793Break <SC2BUF- move data from SC to buffer>
794
795; Inputs: [SC_STATUS] = SC validity status
796; [SC_SECTOR_SIZE] = request sector size
797; [SC_CACHE_PTR] = pointer to SC
798; Function:
799; Move data from SC to buffer
800; Output:
801; carry clear, in SC and data is moved
802; carry set, not in SC and data is not moved
803
804 procedure SC2BUF,NEAR ;AN000;
805ASSUME DS:NOTHING,ES:NOTHING ;AN000;
806
807 CALL IN_SC ;AN000;;LB. in secondary cache
808 JC noSC ;AN000;;LB. no
809 MOV AX,1 ;AN000;;LB. check if valid sector
810 SHL AX,CL ;AN000;;LB. in the secondary cache
811 TEST [SC_STATUS],AX ;AN000;;LB.
812 JZ noSC ;AN000;;LB. invalid
813entry SC2BUF2 ;AN000;
814 MOV AX,CX ;AN000;;LB. times index with
815 MUL [SC_SECTOR_SIZE] ;AN000;;LB. sector size
816 ADD AX,WORD PTR [SC_CACHE_PTR] ;AN000;;LB. add SC starting addr
817 ADC DX,WORD PTR [SC_CACHE_PTR+2];AN000;;LB.
818 MOV DS,DX ;AN000; ;LB. DS:SI-> SC sector addr
819 MOV SI,AX ;AN000; ;LB.
820 MOV ES,WORD PTR [CALLXAD+2] ;AN000; ;LB. ES:DI-> buffer addr
821 MOV DI,WORD PTR [CALLXAD] ;AN000; ;LB.
822 MOV CX,[SC_SECTOR_SIZE] ;AN000; ;LB. count= sector size
823 SHR CX,1 ;AN000; ;LB. may use DWORD move for 386
824entry MOVWORDS ;AN000;
825 CMP [DDMOVE],0 ;AN000; ;LB. 386 ?
826 JZ nodd ;AN000; ;LB. no
827 SHR CX,1 ;AN000; ;LB. words/2
828 DB 66H ;AN000; ;LB. use double word move
829nodd:
830 REP MOVSW ;AN000; ;LB. move to buffer
831 CLC ;AN000; ;LB. clear carry
832 return ;AN000; ;LB. exit
833noSC: ;AN000;
834 STC ;AN000; ;LB. set carry
835sexit: ;AN000;
836 return ;AN000; ;LB.
837
838EndProc SC2BUF
839CODE ENDS
840 END
841 \ No newline at end of file