1 ; SCCSID = @(#)mscode.asm 1.2 85/07/23
3 ; MSCODE.ASM -- MSDOS code
17 AsmVars
<Kanji
, Debug
>
19 CODE SEGMENT BYTE PUBLIC 'CODE'
21 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
23 I_need InDos
,BYTE ; TRUE => we are in dos, no interrupt
24 I_need OpenBuf
,128 ; temp name buffer
25 I_need ExtErr
,WORD ; extended error code
26 I_need User_SS
,WORD ; stack segment from user
27 I_need User_SP
,WORD ; stack pointer from user
28 I_need DskStack
,BYTE ; stack segment inside DOS
29 I_need ThisCDS
,DWORD ; Currently referenced CDS pointer
30 I_need ThisDPB
,DWORD ; Currently referenced DPB pointer
31 I_need Err_Table_21
; allowed return map table for errors
32 I_need FailErr
,BYTE ; TRUE => system call is being failed
33 I_need ExtErr_Action
,BYTE ; recommended action
34 I_need ExtErr_Class
,BYTE ; error classification
35 I_need ExtErr_Locus
,BYTE ; error location
36 I_need I21_Map_E_Tab
,BYTE ; mapping extended error table
37 I_need User_In_AX
,WORD ; initial input user AX
38 I_need FOO
,WORD ; return address for dos 2f dispatch
39 I_need DTAB
,WORD ; dos 2f dispatch table
40 I_need HIGH_SECTOR
,WORD ; >32mb
41 I_need IFS_DRIVER_ERR
,WORD ; >32mb
42 I_need FastOpenFlg
,BYTE ;
43 I_need FastSeekFlg
,BYTE ;
44 I_need CURSC_DRIVE
,BYTE ;
46 BREAK <NullDev
-- Driver for null device
>
49 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
50 OR ES:[BX.REQSTAT
],STDON
; Set done bit
52 RET ; MUST NOT BE A RETURN!
55 BREAK <AbsDRD
, AbsDWRT
-- INT int_disk_read
, int_disk_write handlers
>
59 Public MSC001S
,MSC001E
62 ; Codes returned by BIOS
68 DB 8 ; SECTOR NOT FOUND
69 DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK
71 ; DISK ERRORS RETURNED FROM INT 25 and 26
74 DB 2 ; Address Mark not found
76 DB 4 ; SECTOR NOT FOUND
77 DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK
85 ; AbsSetup - setup for abs disk functions
87 Procedure AbsSetup
,NEAR
88 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
95 JC errdriv
;PM. error drive ;AN000;
96 MOV ES:[BP.dpb_free_cnt
],-1 ; do not trust user at all.
102 MOV [HIGH_SECTOR
],0 ;>32mb from API ;AN000;
103 CALL RW32_CONVERT
;>32mb convert 32bit format to 16bit ;AN000;
106 invoke SET_RQ_SC_PARMS
;LB. set up SC parms ;AN000;
111 MOV SI,OFFSET DOSGROUP
:OPENBUF
113 ADD BYTE PTR [SI],"A"
114 MOV WORD PTR [SI+1],003AH ; ":",0
117 INT int_IBM
; Will set carry if shared
123 MOV ExtErr
,error_not_supported
127 ; Interrupt 25 handler. Performs absolute disk read.
128 ; Inputs: AL - 0-based drive number
129 ; DS:BX point to destination buffer
130 ; CX number of logical sectors to read
131 ; DX starting logical sector number (0-based)
132 ; Outputs: Original flags still on stack
135 ; AL same as low byte of DI from INT 24
138 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
146 MOV SP,OFFSET DOSGROUP
:DSKSTACK
147 invoke Save_World
;>32mb save all regs ;AN000;
152 ; Here is a gross temporary fix to get around a serious design flaw in
153 ; the secondary cache. The secondary cache does not check for media
154 ; changed (it should). Hence, you can change disks, do an absolute
155 ; read, and get data from the previous disk. To get around this,
156 ; we just won't use the secondary cache for absolute disk reads.
159 MOV [CURSC_DRIVE
],-1 ; invalidate SC ;AN000;
167 ; Translate the error code to ancient 1.1 codes
171 XOR AH,AH ; Nul error code
172 MOV CX,NUMERR
; Number of possible error conditions
173 MOV DI,OFFSET DOSGROUP
:ERRIN
; Point to error conditions
175 JNZ LEAVECODE
; Not found
176 MOV AH,ES:[DI+NUMERR
-1] ; Get translation
180 MOV [IFS_DRIVER_ERR
],AX ;>32mb save error
184 invoke Restore_World
;>32mb ;AN000;
190 MOV AX,[IFS_DRIVER_ERR
] ;>32mb restore error ;AN000;
192 RET ; This must not be a RETURN!
195 ; Interrupt 26 handler. Performs absolute disk write.
196 ; Inputs: AL - 0-based drive number
197 ; DS:BX point to source buffer
198 ; CX number of logical sectors to write
199 ; DX starting logical sector number (0-based)
200 ; Outputs: Original flags still on stack
203 ; AL same as low byte of DI from INT 24
205 procedure ABSDWRT
,FAR
206 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
214 MOV SP,OFFSET DOSGROUP
:DSKSTACK
215 invoke Save_World
;>32mb save all regs ;AN000;
222 MOV [CURSC_DRIVE
],-1 ; invalidate SC ;AN000;
223 CALL Fastxxx_Purge
; purge fatopen ;AN000;
231 ; AL = Logical unit number (A = 0)
233 ; Find Drive Parameter Block
235 ; ES:BP points to DPB
237 ; Carry set if unit number bad or unit is a NET device.
238 ; Later case sets extended error error_I24_not_supported
239 ; No other registers altered
242 DOSAssume
CS,<DS>,"GetBP"
246 ADD AL,1 ; No increment; need carry flag
249 JNC SkipGet
;PM. good drive ;AN000;
250 XOR AH,AH ;DCR. ax= error code ;AN000;
251 CMP AX,error_not_dos_disk
;DCR. is unknown media ? ;AN000;
252 JZ SkipGet
;DCR. yes, let it go ;AN000;
254 MOV ExtErr
,AX ;PM. invalid drive or Non DOS drive ;AN000;
255 MOV [IFS_DRIVER_ERR
],0201H ;PM. other errors/unknown unit ;AN000;
260 TEST ES:[BP.curdir_flags
],curdir_isnet
; Clears carry
262 LES BP,ES:[BP.curdir_ifs_hdr
] ;IFS. if remote file ;AN000;
263 TEST ES:[BP.ifs_attribute
],IFSREMOTE
;IFS. ;AN000;
265 JZ GETBP_CDS
;IFS. then error ;AN000;
266 MOV ExtErr
,error_not_supported
271 LES BP,ES:[BP.curdir_devptr
]
274 DOSAssume
CS,<DS>,"GotDPB"
275 ; Load THISDPB from ES:BP
277 MOV WORD PTR [THISDPB
],BP
278 MOV WORD PTR [THISDPB
+2],ES
282 BREAK <SYS_RET_OK SYS_RET_ERR CAL_LK ETAB_LK set system
call returns
>
287 ; These are the general system call exit mechanisms. All internal system
288 ; calls will transfer (jump) to one of these at the end. Their sole purpose
289 ; is to set the user's flags and set his AX register for return.
292 procedure SYS_RETURN
,NEAR
293 ASSUME
DS:NOTHING
,ES:NOTHING
295 invoke FETCHI_CHECK
; TAG checking for FETCHI
296 invoke get_user_stack
297 AND [SI.user_F
],NOT f_Carry
; turn off user's carry flag
298 JMP SHORT DO_RET
; carry is now clear
301 XOR AH,AH ; hack to allow for smaller error rets
302 invoke ETAB_LK
; Make sure code is OK, EXTERR gets set
305 invoke get_user_stack
306 OR [SI.user_F
],f_Carry
; signal carry to user
307 STC ; also, signal internal error
309 MOV [SI.user_AX
],AX ; Really only sets AH
326 MOV SI,OFFSET DOSGROUP
:ERR_TABLE_21
327 CMP [FAILERR
],0 ; Check for SPECIAL case.
328 JZ EXTENDED_NORMAL
; All is OK.
329 MOV [EXTERR
],error_FAIL_I24
; Ooops, this is the REAL reason
330 MOV SI,OFFSET DOSGROUP
:ERR_TABLE_21
332 invoke CAL_LK
; Set CLASS,ACTION,LOCUS for EXTERR
339 ; SI is OFFSET in DOSGROUP of CLASS,ACTION,LOCUS Table to use
340 ; (DS NEED not be DOSGROUP)
341 ; [EXTERR] is set with error
343 ; Look up and set CLASS ACTION and LOCUS values for GetExtendedError
346 ; [EXTERR_ACTION] set
347 ; [EXTERR_LOCUS] set (EXCEPT on certain errors as determined by table)
350 procedure CAL_LK
,NEAR
351 ASSUME
DS:NOTHING
,ES:NOTHING
356 Context
DS ; DS:SI -> Table
357 MOV BX,[EXTERR
] ; Get error in BL
361 JZ GOT_VALS
; End of table
363 JZ GOT_VALS
; Got entry
364 ADD SI,3 ; Next table entry
368 LODSW ; AL is CLASS, AH is ACTION
371 MOV [EXTERR_ACTION
],AH ; Set ACTION
375 MOV [EXTERR_CLASS
],AL ; Set CLASS
380 MOV [EXTERR_LOCUS
],AL
390 ; [USER_IN_AX] has AH value of system call involved
392 ; Make sure error code is appropriate to this call.
394 ; AX MAY be mapped error code
395 ; [EXTERR] = Input AX
396 ; Destroys ONLY AX and FLAGS
398 procedure ETAB_LK
,NEAR
399 ASSUME
DS:NOTHING
,ES:NOTHING
406 MOV [EXTERR
],AX ; Set EXTERR with "real" error
407 MOV SI,OFFSET DOSGROUP
:I21_MAP_E_TAB
408 MOV BH,AL ; Real code to BH
409 MOV BL,BYTE PTR [USER_IN_AX
+ 1] ; Sys call to BL
412 CMP AL,0FFH ; End of table?
413 JZ NOT_IN_TABLE
; Yes
414 CMP AL,BL ; Found call?
416 XCHG AH,AL ; Count to AL
417 XOR AH,AH ; Make word for add
418 ADD SI,AX ; Next table entry
422 MOV AL,BH ; Restore original code
427 XOR CH,CH ; Count of valid err codes to CX
434 XOR AH,AH ; AX is now valid code
443 BREAK <DOS 2F Handler
and default NET 2F handler
>
448 ; SetBad sets up info for bad functions
450 Procedure SetBad
,NEAR
451 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
452 MOV AX,error_invalid_function
; ALL NET REQUESTS get inv func
453 MOV ExtErr_LOCUS
,errLoc_UNK
458 ; BadCall is the initial routine for bad function calls
460 procedure BadCall
,FAR
465 ; OKCall always sets carry to off.
468 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
473 ; INT 2F handler works as follows:
475 ; MOV AX,multiplex:function
478 ; The handler itself needs to make the AX available for the various routines.
484 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
494 RET 2 ; long return + clear flags off stack
497 CMP AH,multSHARE
; is this a share request
498 JZ TestInstall
; yes, check for installation
501 CMP AH,NLSFUNC
; is this a DOS 3.3 NLSFUNC request
502 JZ TestInstall
; yes check for installation
505 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
508 IRET ; This assume that we are at the head
513 PUSH FOO
; push return address
514 PUSH DTab
; push table address
527 MOV AX,[BP+0Eh] ; get AX value
530 JMP BadFunc
; return indicates invalid function
532 Procedure INT2F_etcetera
,NEAR
541 EndProc INT2F_etcetera
544 ;Input: same as ABSDRD and ABSDWRT
546 ;Functions: convert 32bit absolute RW input parms to 16bit input parms
547 ;Output: carry set when CX=-1 and drive is less then 32mb
548 ; carry clear, parms ok
550 Procedure RW32_CONVERT
,NEAR
551 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
552 CMP CX,-1 ;>32mb new format ? ;AN000;
553 JZ new32format
;>32mb yes ;AN000;
554 PUSH AX ;>32mb save ax ;AN000;
555 PUSH DX ;>32mb save dx ;AN000;
556 MOV AX,ES:[BP.dpb_max_cluster
] ;>32mb get max cluster # ;AN000;
557 MOV DL,ES:[BP.dpb_cluster_mask
] ;>32mb ;AN000;
558 CMP DL,0FEH ;>32mb removable ? ;AN000;
559 JZ letold
;>32mb yes ;AN000;
560 INC DL ;>32mb ;AN000;
561 XOR DH,DH ;>32mb dx = sector/cluster ;AN000;
562 MUL DX ;>32mb dx:ax= max sector # ;AN000;
563 OR DX,DX ;>32mb > 32mb ? ;AN000;
565 POP DX ;>32mb retore dx ;AN000;
566 POP AX ;>32mb restore ax ;AN000;
567 JZ old_style
;>32mb no ;AN000;
568 MOV [IFS_DRIVER_ERR
],0207H ;>32mb error ;AN000;
570 return
;>32mb ;AN000;
572 MOV DX,WORD PTR [BX.SECTOR_RBA
+2];>32mb ;AN000;
573 MOV [HIGH_SECTOR
],DX ;>32mb ;AN000;
574 MOV DX,WORD PTR [BX.SECTOR_RBA
] ;>32mb ;AN000;
575 MOV CX,[BX.ABS_RW_COUNT
] ;>32mb ;AN000;
576 LDS BX,[BX.BUFFER_ADDR
] ;>32mb ;AN000;
577 old_style: ;>32mb ;AN000;
579 return
;>32mb ;AN000;
584 ;Functions: Purge Fastopen/seek Cache Buffers
588 Procedure Fastxxx_Purge
,NEAR
589 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
590 PUSH AX ; save regs. ;AN000;
593 TEST FastSeekflg
,Fast_yes
; fastseek installed ? ;AN000;
594 JZ topen
; no ;AN000;
595 MOV AH,FastSeek_ID
; set fastseek id ;AN000;
596 JMP SHORT dofast
; ;AN000;
598 TEST FastOpenflg
,Fast_yes
; fastopen installed ? ;AN000;
599 JZ nofast
; no ;AN000;
600 MOV AH,FastOpen_ID
; set fastseek installed ;AN000;
602 MOV AL,FONC_purge
; purge ;AN000;
603 MOV DL,ES:[BP.dpb_drive
] ; set up drive number ;AN000;
604 invoke Fast_Dispatch
; call fastopen/seek ;AN000;
607 POP SI ; restore regs ;AN000;
610 return
; exit ;AN000;
611 EndProc Fastxxx_Purge