summaryrefslogtreecommitdiff
path: root/v2.0/source/MSCODE.ASM
diff options
context:
space:
mode:
authorGravatar Rich Turner1983-08-12 17:53:34 -0700
committerGravatar Rich Turner2018-09-21 17:53:34 -0700
commit80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch)
treeee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source/MSCODE.ASM
parentMS-DOS v1.25 Release (diff)
downloadms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source/MSCODE.ASM')
-rw-r--r--v2.0/source/MSCODE.ASM615
1 files changed, 615 insertions, 0 deletions
diff --git a/v2.0/source/MSCODE.ASM b/v2.0/source/MSCODE.ASM
new file mode 100644
index 0000000..c4b58bc
--- /dev/null
+++ b/v2.0/source/MSCODE.ASM
@@ -0,0 +1,615 @@
1;
2; MSCODE.ASM -- MSDOS code
3;
4
5INCLUDE DOSSEG.ASM
6INCLUDE STDSW.ASM
7
8CODE SEGMENT BYTE PUBLIC 'CODE'
9ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
10
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17IFNDEF KANJI
18KANJI EQU 0 ; FALSE
19ENDIF
20
21IFNDEF IBM
22IBM EQU 0
23ENDIF
24
25IFNDEF HIGHMEM
26HIGHMEM EQU 0
27ENDIF
28
29
30 i_need USER_SP,WORD
31 i_need USER_SS,WORD
32 i_need SAVEDS,WORD
33 i_need SAVEBX,WORD
34 i_need INDOS,BYTE
35 i_need NSP,WORD
36 i_need NSS,WORD
37 i_need CURRENTPDB,WORD
38 i_need AUXSTACK,BYTE
39 i_need CONSWAP,BYTE
40 i_need IDLEINT,BYTE
41 i_need NOSETDIR,BYTE
42 i_need ERRORMODE,BYTE
43 i_need IOSTACK,BYTE
44 i_need WPERR,BYTE
45 i_need DSKSTACK,BYTE
46 i_need CNTCFLAG,BYTE
47 i_need LEAVEADDR,WORD
48 i_need NULLDEVPT,DWORD
49
50 IF NOT IBM
51 i_need OEM_HANDLER,DWORD
52 ENDIF
53
54 EXTRN DSKSTATCHK:NEAR,GETBP:NEAR,DSKREAD:NEAR,DSKWRITE:NEAR
55
56
57BREAK <Copyright notice and version>
58
59CODSTRT EQU $
60
61 IF NOT IBM
62 IF NOT KANJI
63 PUBLIC HEADER
64HEADER DB 13,10,"Microsoft MS-DOS version "
65 DB DOS_MAJOR_VERSION + "0"
66 DB "."
67 DB (DOS_MINOR_VERSION / 10) + "0"
68 DB (DOS_MINOR_VERSION MOD 10) + "0"
69 IF HIGHMEM
70 DB "H"
71 ENDIF
72 ENDIF
73 IF KANJI
74 PUBLIC HEADER
75HEADER DB 13,10,82h,"M"+1fh,82h,"i"+20h,82h,"c"+20h,82h,"r"+20h,82h,"o"+20h
76 DB 82h,"s"+20h,82h,"o"+20h,82h,"f"+20h,82h,"t"+20h
77 DB 81h,40h,82h,"M"+1fh,82h,"S"+1fh,81h,5dh+1fh
78 DB 82h,"D"+1fh,82h,"O"+1fh,82h,"S"+1fh,81h,40h
79 DB 82h,DOS_MAJOR_VERSION+"0"+1fh
80 DB 81h,25h+1fh
81 DB 82h,(DOS_MINOR_VERSION / 10)+"0"+1fh
82 DB 82h,(DOS_MINOR_VERSION MOD 10)+"0"+1fh
83 DB 94h,0c5h
84 ENDIF
85 DB 13,10
86 DB "Copyright 1981,82,83 Microsoft Corp.",13,10,"$"
87 ENDIF
88BREAK <System call entry points and dispatcher>
89ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
90
91 procedure SYSTEM_CALL,NEAR
92entry QUIT ; INT 20H entry point
93 MOV AH,0
94 JMP SHORT SAVREGS
95
96entry COMMAND ; Interrupt call entry point (INT 21H)
97
98 IF NOT IBM
99 CMP AH,SET_OEM_HANDLER
100 JB NOTOEM
101 JMP $SET_OEM_HANDLER
102NOTOEM:
103 ENDIF
104
105 CMP AH,MAXCOM
106 JBE SAVREGS
107BADCALL:
108 MOV AL,0
109entry IRET
110 IRET
111
112entry CALL_ENTRY ; System call entry point and dispatcher
113 POP AX ; IP from the long call at 5
114 POP AX ; Segment from the long call at 5
115 POP [User_SP] ; IP from the CALL 5
116 PUSHF ; Start re-ordering the stack
117 CLI
118 PUSH AX ; Save segment
119 PUSH [User_SP] ; Stack now ordered as if INT had been used
120 CMP CL,MAXCALL ; This entry point doesn't get as many calls
121 JA BADCALL
122 MOV AH,CL
123SAVREGS:
124 CALL save_world
125 MOV [SaveDS],DS
126 MOV [SaveBX],BX
127 MOV BX,CS
128 MOV DS,BX
129ASSUME DS:DOSGROUP
130 INC [INDOS] ; Flag that we're in the DOS
131 MOV AX,[user_SP]
132 MOV [NSP],AX
133 MOV AX,[user_SS]
134 MOV [NSS],AX
135 POP AX
136 PUSH AX
137 MOV [user_SP],SP
138 MOV [user_SS],SS
139;
140; save user stack in his area for later returns (possibly from EXEC)
141; Here comes multitasking!!!
142;
143 MOV DS,[CurrentPDB]
144 MOV WORD PTR DS:[PDB_User_stack],SP
145 MOV WORD PTR DS:[PDB_User_stack+2],SS
146
147 MOV BX,CS ; no holes here.
148 MOV SS,BX
149ASSUME SS:DOSGROUP
150
151 entry REDISP
152 MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts
153 STI ; Stack OK now
154 PUSH CS
155 POP DS
156 XOR BH,BH
157 MOV [CONSWAP],BH
158 MOV [IDLEINT],1
159 MOV BYTE PTR [NoSetDir],0 ; set directories on search
160 MOV BL,AH
161 SHL BX,1
162 CLD
163 OR AH,AH
164 JZ DSKROUT ; ABORT
165 CMP AH,12
166 JBE IOROUT ; Character I/O
167 CMP AH,GET_CURRENT_PDB ; INT 24 needs GET,SET PDB
168 JZ IOROUT
169 CMP AH,SET_CURRENT_PDB
170 JNZ DSKROUT
171IOROUT:
172 CMP [ERRORMODE],0
173 JNZ DISPCALL ; Stay on AUXSTACK if INT 24
174 MOV SP,OFFSET DOSGROUP:IOSTACK
175 JMP SHORT DISPCALL
176
177DSKROUT:
178 MOV [ERRORMODE],0 ; Cannot make non 1-12 calls in
179 MOV [WPERR],-1 ; error mode, so good place to
180 ; make sure flags are reset
181 MOV SP,OFFSET DOSGROUP:DSKSTACK
182 TEST [CNTCFLAG],-1
183 JZ DISPCALL
184 PUSH AX
185 invoke DSKSTATCHK
186 POP AX
187DISPCALL:
188 PUSH [LEAVEADDR]
189 PUSH CS:[BX+DISPATCH]
190 MOV BX,[SaveBX]
191 MOV DS,[SaveDS]
192ASSUME DS:NOTHING
193 return
194
195 entry LEAVE
196ASSUME SS:NOTHING ; User routines may misbehave
197 CLI
198 DEC [INDOS]
199 MOV SP,[user_SP]
200 MOV SS,[user_SS]
201 MOV BP,SP
202 MOV BYTE PTR [BP.user_AX],AL
203 MOV AX,[NSP]
204 MOV [user_SP],AX
205 MOV AX,[NSS]
206 MOV [user_SS],AX
207 CALL restore_world
208
209 IRET
210SYSTEM_CALL ENDP
211
212;
213; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from
214; the stack prior to giving the user control
215;
216 ASSUME DS:NOTHING,ES:NOTHING
217restore_tmp DW ?
218 procedure restore_world,NEAR
219 POP restore_tmp ; POP restore_tmp
220 POP AX ; PUSH ES
221 POP BX ; PUSH DS
222 POP CX ; PUSH BP
223 POP DX ; PUSH DI
224 POP SI ; PUSH SI
225 POP DI ; PUSH DX
226 POP BP ; PUSH CX
227 POP DS ; PUSH BX
228 POP ES ; PUSH AX
229world_ret:
230 PUSH restore_tmp ; PUSH restore_tmp
231 return
232restore_world ENDP
233
234;
235; save_world saves complete registers on the stack
236;
237 procedure save_world,NEAR
238 POP restore_tmp
239 PUSH ES
240 PUSH DS
241 PUSH BP
242 PUSH DI
243 PUSH SI
244 PUSH DX
245 PUSH CX
246 PUSH BX
247 PUSH AX
248 JMP SHORT world_ret
249save_world ENDP
250
251;
252; get_user_stack returns the user's stack (and hence registers) in DS:SI
253;
254 procedure get_user_stack,NEAR
255 LDS SI,DWORD PTR [user_SP]
256 return
257get_user_stack ENDP
258
259; Standard Functions
260DISPATCH LABEL WORD
261.lall
262 short_addr $ABORT ; 0 0
263.xall
264 short_addr $STD_CON_INPUT ; 1 1
265 short_addr $STD_CON_OUTPUT ; 2 2
266 short_addr $STD_AUX_INPUT ; 3 3
267 short_addr $STD_AUX_OUTPUT ; 4 4
268 short_addr $STD_PRINTER_OUTPUT ; 5 5
269 short_addr $RAW_CON_IO ; 6 6
270 short_addr $RAW_CON_INPUT ; 7 7
271 short_addr $STD_CON_INPUT_NO_ECHO ; 8 8
272 short_addr $STD_CON_STRING_OUTPUT ; 9 9
273 short_addr $STD_CON_STRING_INPUT ; 10 A
274 short_addr $STD_CON_INPUT_STATUS ; 11 B
275 short_addr $STD_CON_INPUT_FLUSH ; 12 C
276 short_addr $DISK_RESET ; 13 D
277 short_addr $SET_DEFAULT_DRIVE ; 14 E
278 short_addr $FCB_OPEN ; 15 F
279 short_addr $FCB_CLOSE ; 16 10
280 short_addr $DIR_SEARCH_FIRST ; 17 11
281 short_addr $DIR_SEARCH_NEXT ; 18 12
282 short_addr $FCB_DELETE ; 19 13
283 short_addr $FCB_SEQ_READ ; 20 14
284 short_addr $FCB_SEQ_WRITE ; 21 15
285 short_addr $FCB_CREATE ; 22 16
286 short_addr $FCB_RENAME ; 23 17
287 short_addr CPMFUNC ; 24 18
288 short_addr $GET_DEFAULT_DRIVE ; 25 19
289 short_addr $SET_DMA ; 26 1A
290
291;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
292; C A V E A T P R O G R A M M E R ;
293; ;
294 short_addr $SLEAZEFUNC ; 27 1B
295 short_addr $SLEAZEFUNCDL ; 28 1C
296; ;
297; C A V E A T P R O G R A M M E R ;
298;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
299
300 short_addr CPMFUNC ; 29 1D
301 short_addr CPMFUNC ; 30 1E
302;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
303; C A V E A T P R O G R A M M E R ;
304; ;
305 short_addr $GET_DEFAULT_DPB ; 31 1F
306; ;
307; C A V E A T P R O G R A M M E R ;
308;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
309 short_addr CPMFUNC ; 32 20
310 short_addr $FCB_RANDOM_READ ; 33 21
311 short_addr $FCB_RANDOM_WRITE ; 34 22
312 short_addr $GET_FCB_FILE_LENGTH ; 35 23
313 short_addr $GET_FCB_POSITION ; 36 24
314MAXCALL = ($-DISPATCH)/2 - 1
315
316; Extended Functions
317 short_addr $SET_INTERRUPT_VECTOR ; 37 25
318;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
319; C A V E A T P R O G R A M M E R ;
320; ;
321 short_addr $CREATE_PROCESS_DATA_BLOCK ; 38 26
322; ;
323; C A V E A T P R O G R A M M E R ;
324;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
325 short_addr $FCB_RANDOM_READ_BLOCK ; 39 27
326 short_addr $FCB_RANDOM_WRITE_BLOCK ; 40 28
327 short_addr $PARSE_FILE_DESCRIPTOR ; 41 29
328 short_addr $GET_DATE ; 42 2A
329 short_addr $SET_DATE ; 43 2B
330 short_addr $GET_TIME ; 44 2C
331 short_addr $SET_TIME ; 45 2D
332 short_addr $SET_VERIFY_ON_WRITE ; 46 2E
333
334; Extended functionality group
335 short_addr $GET_DMA ; 47 2F
336 short_addr $GET_VERSION ; 48 30
337 short_addr $Keep_Process ; 49 31
338;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
339; C A V E A T P R O G R A M M E R ;
340; ;
341 short_addr $GET_DPB ; 50 32
342; ;
343; C A V E A T P R O G R A M M E R ;
344;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
345 short_addr $SET_CTRL_C_TRAPPING ; 51 33
346 short_addr $GET_INDOS_FLAG ; 52 34
347 short_addr $GET_INTERRUPT_VECTOR ; 53 35
348 short_addr $GET_DRIVE_FREESPACE ; 54 36
349 short_addr $CHAR_OPER ; 55 37
350 short_addr $INTERNATIONAL ; 56 38
351; XENIX CALLS
352; Directory Group
353 short_addr $MKDIR ; 57 39
354 short_addr $RMDIR ; 58 3A
355 short_addr $CHDIR ; 59 3B
356; File Group
357 short_addr $CREAT ; 60 3C
358 short_addr $OPEN ; 61 3D
359 short_addr $CLOSE ; 62 3E
360 short_addr $READ ; 63 3F
361 short_addr $WRITE ; 64 40
362 short_addr $UNLINK ; 65 41
363 short_addr $LSEEK ; 66 42
364 short_addr $CHMOD ; 67 43
365 short_addr $IOCTL ; 68 44
366 short_addr $DUP ; 69 45
367 short_addr $DUP2 ; 70 46
368 short_addr $CURRENT_DIR ; 71 47
369; Memory Group
370 short_addr $ALLOC ; 72 48
371 short_addr $DEALLOC ; 73 49
372 short_addr $SETBLOCK ; 74 4A
373; Process Group
374 short_addr $EXEC ; 75 4B
375 short_addr $EXIT ; 76 4C
376 short_addr $WAIT ; 77 4D
377 short_addr $FIND_FIRST ; 78 4E
378; Special Group
379 short_addr $FIND_NEXT ; 79 4F
380; SPECIAL SYSTEM GROUP
381;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
382; C A V E A T P R O G R A M M E R ;
383; ;
384 short_addr $SET_CURRENT_PDB ; 80 50
385 short_addr $GET_CURRENT_PDB ; 81 51
386 short_addr $GET_IN_VARS ; 82 52
387 short_addr $SETDPB ; 83 53
388; ;
389; C A V E A T P R O G R A M M E R ;
390;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
391 short_addr $GET_VERIFY_ON_WRITE ; 84 54
392;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
393; C A V E A T P R O G R A M M E R ;
394; ;
395 short_addr $DUP_PDB ; 85 55
396; ;
397; C A V E A T P R O G R A M M E R ;
398;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
399 short_addr $RENAME ; 86 56
400 short_addr $FILE_TIMES ; 87 57
401 short_addr $AllocOper ; 88 58
402
403MAXCOM = ($-DISPATCH)/2 - 1
404
405CPMFUNC:
406 XOR AL,AL
407 return
408
409 IF NOT IBM
410BREAK <Set_OEM_Handler -- Set OEM sys call address and handle OEM Calls>
411
412$SET_OEM_HANDLER:
413ASSUME DS:NOTHING,ES:NOTHING
414
415; Inputs:
416; User registers, User Stack, INTS disabled
417; If CALL F8, DS:DX is new handler address
418; Function:
419; Process OEM INT 21 extensions
420; Outputs:
421; Jumps to OEM_HANDLER if appropriate
422
423 JNE DO_OEM_FUNC ; If above F8 try to jump to handler
424 MOV WORD PTR [OEM_HANDLER],DX ; Set Handler
425 MOV WORD PTR [OEM_HANDLER+2],DS
426 IRET ; Quick return, Have altered no registers
427
428DO_OEM_FUNC:
429 CMP WORD PTR [OEM_HANDLER],-1
430 JNZ OEM_JMP
431 JMP BADCALL ; Handler not initialized
432
433OEM_JMP:
434 JMP [OEM_HANDLER]
435
436 ENDIF
437
438
439ASSUME SS:DOSGROUP
440
441;
442; $Set_current_PDB takes BX and sets it to be the current process
443; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
444;
445 procedure $SET_CURRENT_PDB,NEAR
446 ASSUME DS:NOTHING,SS:NOTHING
447 MOV [CurrentPDB],BX
448 return
449$SET_CURRENT_PDB ENDP
450
451;
452; $get_current_PDB returns in BX the current process
453; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
454;
455 procedure $GET_CURRENT_PDB,NEAR
456 ASSUME DS:NOTHING,SS:NOTHING
457 invoke get_user_stack
458 PUSH [CurrentPDB]
459 POP [SI.user_BX]
460 return
461$GET_CURRENT_PDB ENDP
462; ;
463; C A V E A T P R O G R A M M E R ;
464;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
465
466BREAK <NullDev -- Driver for null device>
467 procedure SNULDEV,FAR
468ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
469 MOV WORD PTR [NULLDEVPT],BX
470 MOV WORD PTR [NULLDEVPT+2],ES
471 return
472SNULDEV ENDP
473
474 procedure INULDEV,FAR
475 PUSH ES
476 PUSH BX
477 LES BX,[NULLDEVPT]
478 OR ES:[BX.REQSTAT],STDON ; Set done bit
479 POP BX
480 POP ES
481 return
482
483INULDEV ENDP
484
485
486BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers>>
487
488
489 IF IBM
490ERRIN: ; Codes returned by BIOS
491 DB 2 ; NO RESPONSE
492 DB 6 ; SEEK FAILURE
493 DB 12 ; GENERAL ERROR
494 DB 4 ; BAD CRC
495 DB 8 ; SECTOR NOT FOUND
496 DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK
497ERROUT: ; DISK ERRORS RETURNED FROM INT 25 and 26
498 DB 80H ; NO RESPONSE
499 DB 40H ; Seek failure
500 DB 2 ; Address Mark not found
501 DB 8 ; DMA OVERRUN
502 DB 4 ; SECTOR NOT FOUND
503 DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK
504
505NUMERR EQU $-ERROUT
506 ENDIF
507
508 procedure ABSDRD,FAR
509ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
510
511 CLI
512 MOV [user_SS],SS
513 MOV [user_SP],SP
514 PUSH CS
515 POP SS
516ASSUME SS:DOSGROUP
517 MOV SP,OFFSET DOSGROUP:DSKSTACK
518 INC BYTE PTR [INDOS]
519 STI
520 CLD
521 PUSH ES
522 PUSH DS
523 PUSH SS
524 POP DS
525ASSUME DS:DOSGROUP
526 invoke GETBP
527 POP DS
528ASSUME DS:NOTHING
529 JC ILEAVE
530 invoke DSKREAD
531TLEAVE:
532 JZ ILEAVE
533
534 IF IBM
535; Translate the error code to ancient 1.1 codes
536 PUSH ES
537 PUSH CS
538 POP ES
539 XOR AH,AH ; Nul error code
540 MOV CX,NUMERR ; Number of possible error conditions
541 MOV DI,OFFSET DOSGROUP:ERRIN ; Point to error conditions
542 REPNE SCASB
543 JNZ LEAVECODE ; Not found
544 MOV AH,ES:[DI+NUMERR-1] ; Get translation
545LEAVECODE:
546 POP ES
547 ENDIF
548
549 STC
550ILEAVE:
551 POP ES
552 CLI
553 DEC BYTE PTR [INDOS]
554 MOV SP,[user_SP]
555 MOV SS,[user_SS]
556ASSUME SS:NOTHING
557 STI
558 return
559ABSDRD ENDP
560
561 procedure ABSDWRT,FAR
562ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
563
564 CLI
565 MOV [user_SS],SS
566 MOV [user_SP],SP
567 PUSH CS
568 POP SS
569ASSUME SS:DOSGROUP
570 MOV SP,OFFSET DOSGROUP:DSKSTACK
571 INC BYTE PTR [INDOS]
572 STI
573 CLD
574 PUSH ES
575 PUSH DS
576 PUSH SS
577 POP DS
578ASSUME DS:DOSGROUP
579 invoke GETBP
580 POP DS
581ASSUME DS:NOTHING
582 JC ILEAVE
583 invoke DSKWRITE
584 JMP TLEAVE
585ABSDWRT ENDP
586
587
588
589 procedure SYS_RETURN,NEAR
590 ASSUME DS:NOTHING,ES:NOTHING
591 entry SYS_RET_OK
592 call get_user_stack
593 PUSH [SI.user_F]
594 POPF
595 CLC
596 JMP SHORT DO_RET
597
598 entry SYS_RET_ERR
599 XOR AH,AH ; hack to allow for smaller error rets
600 call get_user_stack
601 PUSH [SI.user_F]
602 POPF
603 STC
604DO_RET:
605 MOV [SI.user_AX],AX ; Really only sets AH
606 PUSHF
607 POP [SI.user_F] ; dump on his flags
608 return
609SYS_RETURN ENDP
610
611do_ext
612
613CODE ENDS
614 END
615 \ No newline at end of file