1 ; SCCSID = @(#)dev.asm 1.2 85/07/23
2 ; SCCSID = @(#)dev.asm 1.2 85/07/23
3 TITLE DEV
- Device
call routines
5 ; Misc Routines to do 1-12 low level I/O and call devices
22 ; A000 version 4.00 Jan. 1988
23 ; A010 disable change line for SHARE /NC
26 ; get the appropriate segment definitions
31 CODE SEGMENT BYTE PUBLIC 'CODE'
32 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
49 i_need CallDevAd
,DWORD
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
77 Break <IOFUNC
-- DO FUNCTION
1-12 I
/O
>
87 ; = 5 Input Status - System WAIT invoked for K09 if no char
89 ; AL = character if output
91 ; Perform indicated I/O to device or file
93 ; AL is character if input
95 ; zero set if not ready
96 ; zero reset if ready (character in AL for input status)
99 ; Gets character but restores position
102 ; Gets character advances position
106 ; AX altered, all other registers preserved
108 procedure IOFUNC
,NEAR
109 ASSUME
DS:NOTHING
,ES:NOTHING
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
120 TEST [SI.sf_flags
],devid_device
131 cmp ah,5 ; system wait enabled?
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.
137 MOV [IOCALL
.REQSTAT
],BX
139 MOV BYTE PTR [IOMED
],BL
142 Public DEV001S
, DEV001E
; Pathgen labels
145 LenTab
DB DRDWRHL
, DRDNDHL
, DRDWRHL
, DSTATHL
, DFLSHL
, DRDNDHL
149 CmdTab
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
158 MOV BL,AH ; get function
161 MOV CX,WORD PTR CmdTab
[BX]
163 MOV BX,OFFSET DOSGROUP
:IOCALL
165 MOV [IOCALL
.REQLEN
],AH
166 MOV [IOCALL
.REQFUNC
],CH
168 ;----------------------------- Start of DBCS 2/13/KK
170 MOV CL, [InterCon
] ;AN000;
171 CMP CH, DEVRD
;AN000; 0 input
173 CMP CH, DEVRDND
;AN000; 1(5) input status without(with) system WAIT
175 MOV CL, [SaveCurflg
] ;AN000;
176 CMP CH, DEVWRT
;AN000; 2 output
178 XOR CL,CL ;AN000; else, do normal
180 MOV BYTE PTR [IoMed
], CL ;AN000; set interim I/O indication
182 ;----------------------------- End of DBCS 2/13/KK
187 MOV DI,[IOCALL
.REQSTAT
]
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
199 NotInterim: ;AN000; 2/13/KK
203 MOV AL,BYTE PTR [IORCHR
]
206 DNODRD: MOV AH,BYTE PTR [IOCALL
.REQSTAT
+1]
207 NOT AH ; Zero = busy, not zero = ready
210 QuickReturn: ;AN000; 2/13/KK
213 MOV AX,WORD PTR [DEVIOBUF
]
219 ;------------------------------ Start of DBCS 2/13/KK
222 TEST [SI.sf_flags
], devid_device_con_out
;AN000; output to console ?
224 CMP CL, 01 ;AN000; write interim ?
227 JMP SHORT QuickReturn
;AN000; avoid writting interims to other than
228 ;AN000; console device
233 ;------------------------------ End of DBCS 2/13/KK
236 TEST CS:[DOS34_FLAG
],X25_Special
;AN000; from disk.asm
238 PUSH AX ;AN000; unknown command ?
240 AND AX,error_I24_bad_command
;AN000;
241 CMP AL,error_I24_bad_command
;AN000;
243 JNZ notx25
;AN000; no, then error
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)
268 return
; NON ZERO FLAG FOR OUTPUT STATUS
271 PUSH WORD PTR [SI.sf_position
] ; Save position
272 PUSH WORD PTR [SI.sf_position
+2]
274 POP WORD PTR [SI.sf_position
+2] ; Restore position
275 POP WORD PTR [SI.sf_position
]
281 CALL RESTXADDR
; If you change this into a jmp don't
282 return
; come crying to me when things don't
287 OR [DOS34_FLAG
],Disable_EOF_I24
;AN000;
289 AND [DOS34_FLAG
],NO_Disable_EOF_I24
;AN000;
292 MOV AL,[DEVIOBUF
] ; Get byte from trans addr
294 MOV AL,1
AH ; ^Z if no bytes
298 POP WORD PTR [CALLSCNT
] ; Return address
300 PUSH WORD PTR [DMAADD
] ; Save Disk trans addr
301 PUSH WORD PTR [DMAADD
+2]
302 MOV WORD PTR [THISSFT
+2],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
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
]
319 RESTRET:JMP WORD PTR [CALLSCNT
] ; Return address
322 Break <DEV_OPEN_SFT
, DEV_CLOSE_SFT
- OPEN
or CLOSE A DEVICE
>
325 ; ES:DI Points to SFT
327 ; Issue an OPEN call to the correct device
332 procedure DEV_OPEN_SFT
,NEAR
333 ASSUME
DS:NOTHING
,ES:NOTHING
335 Assert ISSFT
,<ES,DI>,"Dev_Open_SFT"
343 ; ES:DI Points to SFT
345 ; Issue a CLOSE call to the correct device
350 procedure DEV_CLOSE_SFT
,NEAR
351 ASSUME
DS:NOTHING
,ES:NOTHING
353 Assert ISSFT
,<ES,DI>,"Dev_Close_SFT"
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
365 ; Is the SFT for the net? If so, no action necessary.
367 invoke Test_IFS_Remote
;AC000;
368 JNZ OPCLS_DONE
; NOP on net SFTs
370 TEST ES:[DI.sf_flags
],devid_device
371 LES DI,ES:[DI.sf_devptr
] ; Get DPB or device
374 ; We are about to call device open/close on a block driver. If no sharing
375 ; then just short circuit to done.
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
383 GOT_DEV_ADDR: ; ES:DI -> device
384 TEST ES:[DI.SDEVATT
],DEVOPCL
385 JZ OPCLS_DONE
; Device can't
388 MOV SI,DI ; DS:SI -> device
391 MOV DI,OFFSET DOSGROUP
:DEVCALL
401 MOV WORD PTR ES:[DI],0 ; Status
402 PUSH AX ; Save Unit,Command
404 MOV DI,ES:[BX.REQSTAT
]
406 JZ OPCLS_DONEP
; No error
407 TEST [SI.SDEVATT
],DEVTYP
409 MOV AH,86H
; Read error in data, Char dev
413 MOV AL,CL ; Drive # in AL
414 MOV AH,6 ; Read error in data, Blk dev
418 JNZ OPCLS_DONEP
; IGNORE or FAIL
419 ; Note that FAIL is essentually IGNORED
420 POP AX ; Get back Unit, Command
429 EndProc DEV_CLOSE_SFT
431 Break <DEVIOCALL
, DEVIOCALL2
- CALL A DEVICE
>
434 ; DS:SI Points to device SFT
435 ; ES:BX Points to request data
439 ; DS:SI -> Device driver
440 ; DS:SI,AX destroyed, others preserved
442 procedure DEVIOCALL
,NEAR
443 ASSUME
DS:NOTHING
,ES:NOTHING
445 Assert ISSFT
,<DS,SI>,"DevIOCall"
446 LDS SI,[SI.sf_devptr
]
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
461 CALL RW_SC
;AN000;LB. use secondary cache if there
462 JC dev_exit
;AN000;LB. done
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
473 chksector: ;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
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
]
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
495 Break <SETREAD
, SETWRITE
-- SET UP HEADER BLOCK
>
498 ; DS:BX = Transfer Address
500 ; DX = Starting Record
504 ; Set up the device call header at DEVCALL
506 ; ES:BX Points to DEVCALL
507 ; No other registers effected
509 procedure SETREAD
,NEAR
510 ASSUME
DS:NOTHING
,ES:NOTHING
520 MOV DI,OFFSET DOSGROUP
:DEVCALL
529 ADD DI,8 ; Skip link fields
538 STOSW ; Transfer addr
542 XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX
547 MOV BX,OFFSET DOSGROUP
:DEVCALL
551 ASSUME
DS:NOTHING
,ES:NOTHING
554 ; DS:BX = Transfer Address
556 ; DX = Starting Record
560 ; Set up the device call header at DEVCALL
562 ; ES:BX Points to DEVCALL
563 ; No other registers effected
570 JMP SHORT SETCALLHEAD
574 Break <RW_SC
-- Read Write Secondary Cache
>
577 ; [SC_CACHE_COUNT]= secondary cache count
578 ; [SC_STATUS]= SC validity status
579 ; [SEQ_SECTOR]= last sector read
581 ; Read from or write through secondary cache
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
589 procedure RW_SC
,NEAR ;AN000;
590 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
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
597 PUSH DX ;AN000;;LB. yes
598 PUSH DS ;AN000;;LB. save registers
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;
607 scexit4: ;AN000; ;AN000;
608 CLC ;AN000;LB. I/O not done yet ;AN000;
609 return
;AN000;LB. ;AN000;
610 doread: ;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;
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 #
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
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.
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.
647 CLC ;AN000;LB. clear carry ;AN000;
648 saveseq: ;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;
655 scexit2: ;AN000;LB. ;AN000;
656 CLC ;AN000;LB. clear carry ;AN000;
657 scexit: ;AN000; ;AN000;
659 POP ES ;AN000;;LB. restore registers
666 EndProc RW_SC
;AN000;
668 Break <IN_SC
-- check
if in secondary cache
>
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
676 ; Check if the sector is in secondary cache
679 ; CX= the index in the secondary cache
680 ; carry set, not in SC
683 procedure IN_SC
,NEAR ;AN000;
684 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
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
699 outrange2: ;AN000;;LB. set carry
704 EndProc IN_SC
;AN000;
706 Break <INVALIDATE_SC
- invalide secondary cache
>
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
716 ; invalidate secondary cache if in there
718 ; [SC_STATUS] is updated
721 procedure INVALIDATE_SC
,NEAR ;AN000;
722 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
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
729 AND [SC_STATUS
],AX ;AN000;;LB. save the status
730 outrange: ;AN000;;LB.
733 EndProc INVALIDATE_SC
;AN000;
736 Break <VIRREAD
- virtually read
data into buffer
>
738 ; Inputs: SC_FLAG = 0 , no sectors were read into SC
739 ; 1, continous sectors were read into SC
741 ; Move data from SC to buffer
743 ; carry clear, data is moved to buffer
744 ; carry set, bad sector or exceeds maximum sector
747 ; SC_STATUS= -1 if succeeded
750 procedure VIRREAD
,NEAR ;AN000;
751 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
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
762 TEST [DEVCALL
.REQSTAT
],STERR
;AN000;;LB. error?
763 JNZ scerror
;AN000;;LB. yes
770 XOR CX,CX ;AN000;;LB. we want first sector in SC
771 CALL SC2BUF2
;AN000;;LB. move data from SC to buffer
778 JMP SHORT sc2end
;AN000;;LB. return
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
788 CLC ;AN000;;LB. carry clear
791 EndProc VIRREAD
;AN000;
793 Break <SC2BUF
- move
data from SC to buffer
>
795 ; Inputs: [SC_STATUS] = SC validity status
796 ; [SC_SECTOR_SIZE] = request sector size
797 ; [SC_CACHE_PTR] = pointer to SC
799 ; Move data from SC to buffer
801 ; carry clear, in SC and data is moved
802 ; carry set, not in SC and data is not moved
804 procedure SC2BUF
,NEAR ;AN000;
805 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
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
813 entry 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
824 entry 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
830 REP MOVSW ;AN000; ;LB. move to buffer
831 CLC ;AN000; ;LB. clear carry
832 return
;AN000; ;LB. exit
834 STC ;AN000; ;LB. set carry