summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/MS_CODE.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/MS_CODE.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/MS_CODE.ASM')
-rw-r--r--v4.0/src/DOS/MS_CODE.ASM614
1 files changed, 614 insertions, 0 deletions
diff --git a/v4.0/src/DOS/MS_CODE.ASM b/v4.0/src/DOS/MS_CODE.ASM
new file mode 100644
index 0000000..1bdd4af
--- /dev/null
+++ b/v4.0/src/DOS/MS_CODE.ASM
@@ -0,0 +1,614 @@
1; SCCSID = @(#)mscode.asm 1.2 85/07/23
2;
3; MSCODE.ASM -- MSDOS code
4;
5
6.xlist
7.xcref
8include dossym.inc
9include devsym.inc
10include dosseg.asm
11include ifssym.inc
12include fastopen.inc
13include fastxxxx.inc
14.cref
15.list
16
17AsmVars <Kanji, Debug>
18
19CODE SEGMENT BYTE PUBLIC 'CODE'
20
21ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
22
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 ;
45
46BREAK <NullDev -- Driver for null device>
47
48procedure SNULDEV,FAR
49ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
50 OR ES:[BX.REQSTAT],STDON ; Set done bit
51entry INULDEV
52 RET ; MUST NOT BE A RETURN!
53EndProc SNULDEV
54
55BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers>
56
57
58TABLE SEGMENT
59Public MSC001S,MSC001E
60MSC001S label byte
61 IF IBM
62; Codes returned by BIOS
63ERRIN:
64 DB 2 ; NO RESPONSE
65 DB 6 ; SEEK FAILURE
66 DB 12 ; GENERAL ERROR
67 DB 4 ; BAD CRC
68 DB 8 ; SECTOR NOT FOUND
69 DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK
70ERROUT:
71; DISK ERRORS RETURNED FROM INT 25 and 26
72 DB 80H ; NO RESPONSE
73 DB 40H ; Seek failure
74 DB 2 ; Address Mark not found
75 DB 10H ; BAD CRC
76 DB 4 ; SECTOR NOT FOUND
77 DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK
78
79NUMERR EQU $-ERROUT
80 ENDIF
81MSC001E label byte
82
83TABLE ENDS
84
85; AbsSetup - setup for abs disk functions
86
87Procedure AbsSetup,NEAR
88 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
89 INC INDOS
90 STI
91 CLD
92 PUSH DS
93 Context DS
94 CALL GETBP
95 JC errdriv ;PM. error drive ;AN000;
96 MOV ES:[BP.dpb_free_cnt],-1 ; do not trust user at all.
97errdriv:
98 POP DS
99ASSUME DS:NOTHING
100 retc
101
102 MOV [HIGH_SECTOR],0 ;>32mb from API ;AN000;
103 CALL RW32_CONVERT ;>32mb convert 32bit format to 16bit ;AN000;
104 retc
105
106 invoke SET_RQ_SC_PARMS ;LB. set up SC parms ;AN000;
107 PUSH DS
108 PUSH SI
109 PUSH AX
110 Context DS
111 MOV SI,OFFSET DOSGROUP:OPENBUF
112 MOV [SI],AL
113 ADD BYTE PTR [SI],"A"
114 MOV WORD PTR [SI+1],003AH ; ":",0
115 MOV AX,0300H
116 CLC
117 INT int_IBM ; Will set carry if shared
118 POP AX
119 POP SI
120 POP DS
121ASSUME DS:NOTHING
122 retnc
123 MOV ExtErr,error_not_supported
124 return
125EndProc AbsSetup
126
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
133; Carry set
134; AH error from BIOS
135; AL same as low byte of DI from INT 24
136
137 procedure ABSDRD,FAR
138 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
139
140 CLI
141 MOV [user_SS],SS
142 MOV [user_SP],SP
143 PUSH CS
144 POP SS
145ASSUME SS:DOSGROUP
146 MOV SP,OFFSET DOSGROUP:DSKSTACK
147 invoke Save_World ;>32mb save all regs ;AN000;
148 PUSH ES
149 CALL AbsSetup
150 JC ILEAVE
151if not ibmcopyright
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.
157; -mw 8/5/88
158 EnterCrit critDisk
159 MOV [CURSC_DRIVE],-1 ; invalidate SC ;AN000;
160 LeaveCrit critDisk
161endif
162 invoke DSKREAD
163TLEAVE:
164 JZ ILEAVE
165
166 IF IBM
167; Translate the error code to ancient 1.1 codes
168 PUSH ES
169 PUSH CS
170 POP ES
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
174 REPNE SCASB
175 JNZ LEAVECODE ; Not found
176 MOV AH,ES:[DI+NUMERR-1] ; Get translation
177LEAVECODE:
178 POP ES
179 ENDIF
180 MOV [IFS_DRIVER_ERR],AX ;>32mb save error
181 STC
182ILEAVE:
183 POP ES
184 invoke Restore_World ;>32mb ;AN000;
185 CLI
186 DEC INDOS
187 MOV SS,[user_SS]
188ASSUME SS:NOTHING
189 MOV SP,[user_SP]
190 MOV AX,[IFS_DRIVER_ERR] ;>32mb restore error ;AN000;
191 STI
192 RET ; This must not be a RETURN!
193EndProc ABSDRD
194
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
201; Carry set
202; AH error from BIOS
203; AL same as low byte of DI from INT 24
204
205 procedure ABSDWRT,FAR
206ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
207
208 CLI
209 MOV [user_SS],SS
210 MOV [user_SP],SP
211 PUSH CS
212 POP SS
213ASSUME SS:DOSGROUP
214 MOV SP,OFFSET DOSGROUP:DSKSTACK
215 invoke Save_World ;>32mb save all regs ;AN000;
216
217 PUSH ES
218 CALL AbsSetup
219 JC ILEAVE
220
221 EnterCrit critDisk
222 MOV [CURSC_DRIVE],-1 ; invalidate SC ;AN000;
223 CALL Fastxxx_Purge ; purge fatopen ;AN000;
224 LeaveCrit critDisk
225
226 invoke DSKWRITE
227 JMP TLEAVE
228EndProc ABSDWRT
229
230; Inputs:
231; AL = Logical unit number (A = 0)
232; Function:
233; Find Drive Parameter Block
234; Outputs:
235; ES:BP points to DPB
236; [THISDPB] = ES:BP
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
240
241Procedure GETBP,NEAR
242 DOSAssume CS,<DS>,"GetBP"
243 ASSUME ES:NOTHING
244
245 PUSH AX
246 ADD AL,1 ; No increment; need carry flag
247 JC SkipGet
248 invoke GetThisDrv
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;
253 STC ;DCR. ;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;
256SkipGet:
257 POP AX
258 retc
259 LES BP,[THISCDS]
260 TEST ES:[BP.curdir_flags],curdir_isnet ; Clears carry
261 JZ GETBP_CDS
262 LES BP,ES:[BP.curdir_ifs_hdr] ;IFS. if remote file ;AN000;
263 TEST ES:[BP.ifs_attribute],IFSREMOTE ;IFS. ;AN000;
264 LES BP,[THISCDS]
265 JZ GETBP_CDS ;IFS. then error ;AN000;
266 MOV ExtErr,error_not_supported
267 STC
268 return
269
270GETBP_CDS:
271 LES BP,ES:[BP.curdir_devptr]
272
273 entry GOTDPB
274 DOSAssume CS,<DS>,"GotDPB"
275; Load THISDPB from ES:BP
276
277 MOV WORD PTR [THISDPB],BP
278 MOV WORD PTR [THISDPB+2],ES
279 return
280EndProc GetBP
281
282BREAK <SYS_RET_OK SYS_RET_ERR CAL_LK ETAB_LK set system call returns>
283
284ASSUME SS:DOSGROUP
285
286;
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.
290;
291
292procedure SYS_RETURN,NEAR
293 ASSUME DS:NOTHING,ES:NOTHING
294entry SYS_RET_OK
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
299
300entry SYS_RET_ERR
301 XOR AH,AH ; hack to allow for smaller error rets
302 invoke ETAB_LK ; Make sure code is OK, EXTERR gets set
303 CALL ErrorMap
304entry From_GetSet
305 invoke get_user_stack
306 OR [SI.user_F],f_Carry ; signal carry to user
307 STC ; also, signal internal error
308DO_RET:
309 MOV [SI.user_AX],AX ; Really only sets AH
310 return
311
312 entry FCB_RET_OK
313 entry CPMFunc
314 XOR AL,AL
315 return
316
317 entry FCB_RET_ERR
318 XOR AH,AH
319 mov exterr,AX
320 CALL ErrorMap
321 MOV AL,-1
322 return
323
324 entry errorMap
325 PUSH SI
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
331EXTENDED_NORMAL:
332 invoke CAL_LK ; Set CLASS,ACTION,LOCUS for EXTERR
333 POP SI
334 return
335
336EndProc SYS_RETURN
337
338; Inputs:
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
342; Function:
343; Look up and set CLASS ACTION and LOCUS values for GetExtendedError
344; Outputs:
345; [EXTERR_CLASS] set
346; [EXTERR_ACTION] set
347; [EXTERR_LOCUS] set (EXCEPT on certain errors as determined by table)
348; Destroys SI, FLAGS
349
350 procedure CAL_LK,NEAR
351ASSUME DS:NOTHING,ES:NOTHING
352
353 PUSH DS
354 PUSH AX
355 PUSH BX
356 Context DS ; DS:SI -> Table
357 MOV BX,[EXTERR] ; Get error in BL
358TABLK1:
359 LODSB
360 CMP AL,0FFH
361 JZ GOT_VALS ; End of table
362 CMP AL,BL
363 JZ GOT_VALS ; Got entry
364 ADD SI,3 ; Next table entry
365 JMP TABLK1
366
367GOT_VALS:
368 LODSW ; AL is CLASS, AH is ACTION
369 CMP AH,0FFH
370 JZ NO_SET_ACT
371 MOV [EXTERR_ACTION],AH ; Set ACTION
372NO_SET_ACT:
373 CMP AL,0FFH
374 JZ NO_SET_CLS
375 MOV [EXTERR_CLASS],AL ; Set CLASS
376NO_SET_CLS:
377 LODSB ; Get LOCUS
378 CMP AL,0FFH
379 JZ NO_SET_LOC
380 MOV [EXTERR_LOCUS],AL
381NO_SET_LOC:
382 POP BX
383 POP AX
384 POP DS
385 return
386EndProc CAL_LK
387
388; Inputs:
389; AX is error code
390; [USER_IN_AX] has AH value of system call involved
391; Function:
392; Make sure error code is appropriate to this call.
393; Outputs:
394; AX MAY be mapped error code
395; [EXTERR] = Input AX
396; Destroys ONLY AX and FLAGS
397
398 procedure ETAB_LK,NEAR
399ASSUME DS:NOTHING,ES:NOTHING
400
401 PUSH DS
402 PUSH SI
403 PUSH CX
404 PUSH BX
405 Context DS
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
410TABLK2:
411 LODSW
412 CMP AL,0FFH ; End of table?
413 JZ NOT_IN_TABLE ; Yes
414 CMP AL,BL ; Found call?
415 JZ GOT_CALL ; Yes
416 XCHG AH,AL ; Count to AL
417 XOR AH,AH ; Make word for add
418 ADD SI,AX ; Next table entry
419 JMP TABLK2
420
421NOT_IN_TABLE:
422 MOV AL,BH ; Restore original code
423 JMP SHORT NO_MAP
424
425GOT_CALL:
426 MOV CL,AH
427 XOR CH,CH ; Count of valid err codes to CX
428CHECK_CODE:
429 LODSB
430 CMP AL,BH ; Code OK?
431 JZ NO_MAP ; Yes
432 LOOP CHECK_CODE
433NO_MAP:
434 XOR AH,AH ; AX is now valid code
435 POP BX
436 POP CX
437 POP SI
438 POP DS
439 return
440
441EndProc ETAB_LK
442
443BREAK <DOS 2F Handler and default NET 2F handler>
444
445IF installed
446
447;
448; SetBad sets up info for bad functions
449;
450Procedure 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
454 STC
455 ret
456EndProc SetBad
457;
458; BadCall is the initial routine for bad function calls
459;
460procedure BadCall,FAR
461 call SetBad
462 ret
463EndProc BadCall
464;
465; OKCall always sets carry to off.
466;
467Procedure OKCall,FAR
468 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
469 CLC
470 ret
471EndProc OKCall
472
473; INT 2F handler works as follows:
474; PUSH AX
475; MOV AX,multiplex:function
476; INT 2F
477; POP ...
478; The handler itself needs to make the AX available for the various routines.
479
480PUBLIC Int2F
481INT2F PROC FAR
482
483INT2FNT:
484 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
485 STI
486 CMP AH,multNET
487 JNZ INT2FSHR
488TestInstall:
489 OR AL,AL
490 JZ Leave2F
491BadFunc:
492 CALL SetBad
493 entry Leave2F
494 RET 2 ; long return + clear flags off stack
495
496INT2FSHR:
497 CMP AH,multSHARE ; is this a share request
498 JZ TestInstall ; yes, check for installation
499
500INT2FNLS:
501 CMP AH,NLSFUNC ; is this a DOS 3.3 NLSFUNC request
502 JZ TestInstall ; yes check for installation
503
504INT2FDOS:
505 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
506 CMP AH,multDOS
507 JZ DispatchDOS
508 IRET ; This assume that we are at the head
509 ; of the list
510INT2F ENDP
511
512DispatchDOS:
513 PUSH FOO ; push return address
514 PUSH DTab ; push table address
515 PUSH AX ; push index
516 PUSH BP
517 MOV BP,SP
518; stack looks like:
519; 0 BP
520; 2 DISPATCH
521; 4 TABLE
522; 6 RETURN
523; 8 LONG-RETURN
524; c FLAGS
525; e AX
526
527 MOV AX,[BP+0Eh] ; get AX value
528 POP BP
529 Invoke TableDispatch
530 JMP BadFunc ; return indicates invalid function
531
532Procedure INT2F_etcetera,NEAR
533 entry DosGetGroup
534 PUSH CS
535 POP DS
536 return
537
538 entry DOSInstall
539 MOV AL,0FFh
540 return
541EndProc INT2F_etcetera
542
543ENDIF
544;Input: same as ABSDRD and ABSDWRT
545; ES:BP -> DPB
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
549;
550Procedure 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;
564letold:
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;
569 STC ;>32mb ;AN000;
570 return ;>32mb ;AN000;
571new32format:
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;
577old_style: ;>32mb ;AN000;
578 CLC ;>32mb ;AN000;
579 return ;>32mb ;AN000;
580EndProc RW32_CONVERT
581
582
583;Input: None
584;Functions: Purge Fastopen/seek Cache Buffers
585;Output: None
586;
587;
588Procedure Fastxxx_Purge,NEAR
589 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
590 PUSH AX ; save regs. ;AN000;
591 PUSH SI ;AN000;
592 PUSH DX ;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;
597topen:
598 TEST FastOpenflg,Fast_yes ; fastopen installed ? ;AN000;
599 JZ nofast ; no ;AN000;
600 MOV AH,FastOpen_ID ; set fastseek installed ;AN000;
601dofast:
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;
605nofast:
606 POP DX ;AN000;
607 POP SI ; restore regs ;AN000;
608 POP AX ; ;AN000;
609
610 return ; exit ;AN000;
611EndProc Fastxxx_Purge
612
613CODE ENDS
614 \ No newline at end of file