mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 18:15:47 +00:00
615 lines
21 KiB
NASM
615 lines
21 KiB
NASM
;
|
||
; MSCODE.ASM -- MSDOS code
|
||
;
|
||
|
||
INCLUDE DOSSEG.ASM
|
||
INCLUDE STDSW.ASM
|
||
|
||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||
ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
|
||
.xcref
|
||
INCLUDE DOSSYM.ASM
|
||
INCLUDE DEVSYM.ASM
|
||
.cref
|
||
.list
|
||
|
||
IFNDEF KANJI
|
||
KANJI EQU 0 ; FALSE
|
||
ENDIF
|
||
|
||
IFNDEF IBM
|
||
IBM EQU 0
|
||
ENDIF
|
||
|
||
IFNDEF HIGHMEM
|
||
HIGHMEM EQU 0
|
||
ENDIF
|
||
|
||
|
||
i_need USER_SP,WORD
|
||
i_need USER_SS,WORD
|
||
i_need SAVEDS,WORD
|
||
i_need SAVEBX,WORD
|
||
i_need INDOS,BYTE
|
||
i_need NSP,WORD
|
||
i_need NSS,WORD
|
||
i_need CURRENTPDB,WORD
|
||
i_need AUXSTACK,BYTE
|
||
i_need CONSWAP,BYTE
|
||
i_need IDLEINT,BYTE
|
||
i_need NOSETDIR,BYTE
|
||
i_need ERRORMODE,BYTE
|
||
i_need IOSTACK,BYTE
|
||
i_need WPERR,BYTE
|
||
i_need DSKSTACK,BYTE
|
||
i_need CNTCFLAG,BYTE
|
||
i_need LEAVEADDR,WORD
|
||
i_need NULLDEVPT,DWORD
|
||
|
||
IF NOT IBM
|
||
i_need OEM_HANDLER,DWORD
|
||
ENDIF
|
||
|
||
EXTRN DSKSTATCHK:NEAR,GETBP:NEAR,DSKREAD:NEAR,DSKWRITE:NEAR
|
||
|
||
|
||
BREAK <Copyright notice and version>
|
||
|
||
CODSTRT EQU $
|
||
|
||
IF NOT IBM
|
||
IF NOT KANJI
|
||
PUBLIC HEADER
|
||
HEADER DB 13,10,"Microsoft MS-DOS version "
|
||
DB DOS_MAJOR_VERSION + "0"
|
||
DB "."
|
||
DB (DOS_MINOR_VERSION / 10) + "0"
|
||
DB (DOS_MINOR_VERSION MOD 10) + "0"
|
||
IF HIGHMEM
|
||
DB "H"
|
||
ENDIF
|
||
ENDIF
|
||
IF KANJI
|
||
PUBLIC HEADER
|
||
HEADER DB 13,10,82h,"M"+1fh,82h,"i"+20h,82h,"c"+20h,82h,"r"+20h,82h,"o"+20h
|
||
DB 82h,"s"+20h,82h,"o"+20h,82h,"f"+20h,82h,"t"+20h
|
||
DB 81h,40h,82h,"M"+1fh,82h,"S"+1fh,81h,5dh+1fh
|
||
DB 82h,"D"+1fh,82h,"O"+1fh,82h,"S"+1fh,81h,40h
|
||
DB 82h,DOS_MAJOR_VERSION+"0"+1fh
|
||
DB 81h,25h+1fh
|
||
DB 82h,(DOS_MINOR_VERSION / 10)+"0"+1fh
|
||
DB 82h,(DOS_MINOR_VERSION MOD 10)+"0"+1fh
|
||
DB 94h,0c5h
|
||
ENDIF
|
||
DB 13,10
|
||
DB "Copyright 1981,82,83 Microsoft Corp.",13,10,"$"
|
||
ENDIF
|
||
BREAK <System call entry points and dispatcher>
|
||
ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
|
||
procedure SYSTEM_CALL,NEAR
|
||
entry QUIT ; INT 20H entry point
|
||
MOV AH,0
|
||
JMP SHORT SAVREGS
|
||
|
||
entry COMMAND ; Interrupt call entry point (INT 21H)
|
||
|
||
IF NOT IBM
|
||
CMP AH,SET_OEM_HANDLER
|
||
JB NOTOEM
|
||
JMP $SET_OEM_HANDLER
|
||
NOTOEM:
|
||
ENDIF
|
||
|
||
CMP AH,MAXCOM
|
||
JBE SAVREGS
|
||
BADCALL:
|
||
MOV AL,0
|
||
entry IRET
|
||
IRET
|
||
|
||
entry CALL_ENTRY ; System call entry point and dispatcher
|
||
POP AX ; IP from the long call at 5
|
||
POP AX ; Segment from the long call at 5
|
||
POP [User_SP] ; IP from the CALL 5
|
||
PUSHF ; Start re-ordering the stack
|
||
CLI
|
||
PUSH AX ; Save segment
|
||
PUSH [User_SP] ; Stack now ordered as if INT had been used
|
||
CMP CL,MAXCALL ; This entry point doesn't get as many calls
|
||
JA BADCALL
|
||
MOV AH,CL
|
||
SAVREGS:
|
||
CALL save_world
|
||
MOV [SaveDS],DS
|
||
MOV [SaveBX],BX
|
||
MOV BX,CS
|
||
MOV DS,BX
|
||
ASSUME DS:DOSGROUP
|
||
INC [INDOS] ; Flag that we're in the DOS
|
||
MOV AX,[user_SP]
|
||
MOV [NSP],AX
|
||
MOV AX,[user_SS]
|
||
MOV [NSS],AX
|
||
POP AX
|
||
PUSH AX
|
||
MOV [user_SP],SP
|
||
MOV [user_SS],SS
|
||
;
|
||
; save user stack in his area for later returns (possibly from EXEC)
|
||
; Here comes multitasking!!!
|
||
;
|
||
MOV DS,[CurrentPDB]
|
||
MOV WORD PTR DS:[PDB_User_stack],SP
|
||
MOV WORD PTR DS:[PDB_User_stack+2],SS
|
||
|
||
MOV BX,CS ; no holes here.
|
||
MOV SS,BX
|
||
ASSUME SS:DOSGROUP
|
||
|
||
entry REDISP
|
||
MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts
|
||
STI ; Stack OK now
|
||
PUSH CS
|
||
POP DS
|
||
XOR BH,BH
|
||
MOV [CONSWAP],BH
|
||
MOV [IDLEINT],1
|
||
MOV BYTE PTR [NoSetDir],0 ; set directories on search
|
||
MOV BL,AH
|
||
SHL BX,1
|
||
CLD
|
||
OR AH,AH
|
||
JZ DSKROUT ; ABORT
|
||
CMP AH,12
|
||
JBE IOROUT ; Character I/O
|
||
CMP AH,GET_CURRENT_PDB ; INT 24 needs GET,SET PDB
|
||
JZ IOROUT
|
||
CMP AH,SET_CURRENT_PDB
|
||
JNZ DSKROUT
|
||
IOROUT:
|
||
CMP [ERRORMODE],0
|
||
JNZ DISPCALL ; Stay on AUXSTACK if INT 24
|
||
MOV SP,OFFSET DOSGROUP:IOSTACK
|
||
JMP SHORT DISPCALL
|
||
|
||
DSKROUT:
|
||
MOV [ERRORMODE],0 ; Cannot make non 1-12 calls in
|
||
MOV [WPERR],-1 ; error mode, so good place to
|
||
; make sure flags are reset
|
||
MOV SP,OFFSET DOSGROUP:DSKSTACK
|
||
TEST [CNTCFLAG],-1
|
||
JZ DISPCALL
|
||
PUSH AX
|
||
invoke DSKSTATCHK
|
||
POP AX
|
||
DISPCALL:
|
||
PUSH [LEAVEADDR]
|
||
PUSH CS:[BX+DISPATCH]
|
||
MOV BX,[SaveBX]
|
||
MOV DS,[SaveDS]
|
||
ASSUME DS:NOTHING
|
||
return
|
||
|
||
entry LEAVE
|
||
ASSUME SS:NOTHING ; User routines may misbehave
|
||
CLI
|
||
DEC [INDOS]
|
||
MOV SP,[user_SP]
|
||
MOV SS,[user_SS]
|
||
MOV BP,SP
|
||
MOV BYTE PTR [BP.user_AX],AL
|
||
MOV AX,[NSP]
|
||
MOV [user_SP],AX
|
||
MOV AX,[NSS]
|
||
MOV [user_SS],AX
|
||
CALL restore_world
|
||
|
||
IRET
|
||
SYSTEM_CALL ENDP
|
||
|
||
;
|
||
; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from
|
||
; the stack prior to giving the user control
|
||
;
|
||
ASSUME DS:NOTHING,ES:NOTHING
|
||
restore_tmp DW ?
|
||
procedure restore_world,NEAR
|
||
POP restore_tmp ; POP restore_tmp
|
||
POP AX ; PUSH ES
|
||
POP BX ; PUSH DS
|
||
POP CX ; PUSH BP
|
||
POP DX ; PUSH DI
|
||
POP SI ; PUSH SI
|
||
POP DI ; PUSH DX
|
||
POP BP ; PUSH CX
|
||
POP DS ; PUSH BX
|
||
POP ES ; PUSH AX
|
||
world_ret:
|
||
PUSH restore_tmp ; PUSH restore_tmp
|
||
return
|
||
restore_world ENDP
|
||
|
||
;
|
||
; save_world saves complete registers on the stack
|
||
;
|
||
procedure save_world,NEAR
|
||
POP restore_tmp
|
||
PUSH ES
|
||
PUSH DS
|
||
PUSH BP
|
||
PUSH DI
|
||
PUSH SI
|
||
PUSH DX
|
||
PUSH CX
|
||
PUSH BX
|
||
PUSH AX
|
||
JMP SHORT world_ret
|
||
save_world ENDP
|
||
|
||
;
|
||
; get_user_stack returns the user's stack (and hence registers) in DS:SI
|
||
;
|
||
procedure get_user_stack,NEAR
|
||
LDS SI,DWORD PTR [user_SP]
|
||
return
|
||
get_user_stack ENDP
|
||
|
||
; Standard Functions
|
||
DISPATCH LABEL WORD
|
||
.lall
|
||
short_addr $ABORT ; 0 0
|
||
.xall
|
||
short_addr $STD_CON_INPUT ; 1 1
|
||
short_addr $STD_CON_OUTPUT ; 2 2
|
||
short_addr $STD_AUX_INPUT ; 3 3
|
||
short_addr $STD_AUX_OUTPUT ; 4 4
|
||
short_addr $STD_PRINTER_OUTPUT ; 5 5
|
||
short_addr $RAW_CON_IO ; 6 6
|
||
short_addr $RAW_CON_INPUT ; 7 7
|
||
short_addr $STD_CON_INPUT_NO_ECHO ; 8 8
|
||
short_addr $STD_CON_STRING_OUTPUT ; 9 9
|
||
short_addr $STD_CON_STRING_INPUT ; 10 A
|
||
short_addr $STD_CON_INPUT_STATUS ; 11 B
|
||
short_addr $STD_CON_INPUT_FLUSH ; 12 C
|
||
short_addr $DISK_RESET ; 13 D
|
||
short_addr $SET_DEFAULT_DRIVE ; 14 E
|
||
short_addr $FCB_OPEN ; 15 F
|
||
short_addr $FCB_CLOSE ; 16 10
|
||
short_addr $DIR_SEARCH_FIRST ; 17 11
|
||
short_addr $DIR_SEARCH_NEXT ; 18 12
|
||
short_addr $FCB_DELETE ; 19 13
|
||
short_addr $FCB_SEQ_READ ; 20 14
|
||
short_addr $FCB_SEQ_WRITE ; 21 15
|
||
short_addr $FCB_CREATE ; 22 16
|
||
short_addr $FCB_RENAME ; 23 17
|
||
short_addr CPMFUNC ; 24 18
|
||
short_addr $GET_DEFAULT_DRIVE ; 25 19
|
||
short_addr $SET_DMA ; 26 1A
|
||
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $SLEAZEFUNC ; 27 1B
|
||
short_addr $SLEAZEFUNCDL ; 28 1C
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
|
||
short_addr CPMFUNC ; 29 1D
|
||
short_addr CPMFUNC ; 30 1E
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $GET_DEFAULT_DPB ; 31 1F
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
short_addr CPMFUNC ; 32 20
|
||
short_addr $FCB_RANDOM_READ ; 33 21
|
||
short_addr $FCB_RANDOM_WRITE ; 34 22
|
||
short_addr $GET_FCB_FILE_LENGTH ; 35 23
|
||
short_addr $GET_FCB_POSITION ; 36 24
|
||
MAXCALL = ($-DISPATCH)/2 - 1
|
||
|
||
; Extended Functions
|
||
short_addr $SET_INTERRUPT_VECTOR ; 37 25
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $CREATE_PROCESS_DATA_BLOCK ; 38 26
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
short_addr $FCB_RANDOM_READ_BLOCK ; 39 27
|
||
short_addr $FCB_RANDOM_WRITE_BLOCK ; 40 28
|
||
short_addr $PARSE_FILE_DESCRIPTOR ; 41 29
|
||
short_addr $GET_DATE ; 42 2A
|
||
short_addr $SET_DATE ; 43 2B
|
||
short_addr $GET_TIME ; 44 2C
|
||
short_addr $SET_TIME ; 45 2D
|
||
short_addr $SET_VERIFY_ON_WRITE ; 46 2E
|
||
|
||
; Extended functionality group
|
||
short_addr $GET_DMA ; 47 2F
|
||
short_addr $GET_VERSION ; 48 30
|
||
short_addr $Keep_Process ; 49 31
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $GET_DPB ; 50 32
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
short_addr $SET_CTRL_C_TRAPPING ; 51 33
|
||
short_addr $GET_INDOS_FLAG ; 52 34
|
||
short_addr $GET_INTERRUPT_VECTOR ; 53 35
|
||
short_addr $GET_DRIVE_FREESPACE ; 54 36
|
||
short_addr $CHAR_OPER ; 55 37
|
||
short_addr $INTERNATIONAL ; 56 38
|
||
; XENIX CALLS
|
||
; Directory Group
|
||
short_addr $MKDIR ; 57 39
|
||
short_addr $RMDIR ; 58 3A
|
||
short_addr $CHDIR ; 59 3B
|
||
; File Group
|
||
short_addr $CREAT ; 60 3C
|
||
short_addr $OPEN ; 61 3D
|
||
short_addr $CLOSE ; 62 3E
|
||
short_addr $READ ; 63 3F
|
||
short_addr $WRITE ; 64 40
|
||
short_addr $UNLINK ; 65 41
|
||
short_addr $LSEEK ; 66 42
|
||
short_addr $CHMOD ; 67 43
|
||
short_addr $IOCTL ; 68 44
|
||
short_addr $DUP ; 69 45
|
||
short_addr $DUP2 ; 70 46
|
||
short_addr $CURRENT_DIR ; 71 47
|
||
; Memory Group
|
||
short_addr $ALLOC ; 72 48
|
||
short_addr $DEALLOC ; 73 49
|
||
short_addr $SETBLOCK ; 74 4A
|
||
; Process Group
|
||
short_addr $EXEC ; 75 4B
|
||
short_addr $EXIT ; 76 4C
|
||
short_addr $WAIT ; 77 4D
|
||
short_addr $FIND_FIRST ; 78 4E
|
||
; Special Group
|
||
short_addr $FIND_NEXT ; 79 4F
|
||
; SPECIAL SYSTEM GROUP
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $SET_CURRENT_PDB ; 80 50
|
||
short_addr $GET_CURRENT_PDB ; 81 51
|
||
short_addr $GET_IN_VARS ; 82 52
|
||
short_addr $SETDPB ; 83 53
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
short_addr $GET_VERIFY_ON_WRITE ; 84 54
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
; ;
|
||
short_addr $DUP_PDB ; 85 55
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
short_addr $RENAME ; 86 56
|
||
short_addr $FILE_TIMES ; 87 57
|
||
short_addr $AllocOper ; 88 58
|
||
|
||
MAXCOM = ($-DISPATCH)/2 - 1
|
||
|
||
CPMFUNC:
|
||
XOR AL,AL
|
||
return
|
||
|
||
IF NOT IBM
|
||
BREAK <Set_OEM_Handler -- Set OEM sys call address and handle OEM Calls>
|
||
|
||
$SET_OEM_HANDLER:
|
||
ASSUME DS:NOTHING,ES:NOTHING
|
||
|
||
; Inputs:
|
||
; User registers, User Stack, INTS disabled
|
||
; If CALL F8, DS:DX is new handler address
|
||
; Function:
|
||
; Process OEM INT 21 extensions
|
||
; Outputs:
|
||
; Jumps to OEM_HANDLER if appropriate
|
||
|
||
JNE DO_OEM_FUNC ; If above F8 try to jump to handler
|
||
MOV WORD PTR [OEM_HANDLER],DX ; Set Handler
|
||
MOV WORD PTR [OEM_HANDLER+2],DS
|
||
IRET ; Quick return, Have altered no registers
|
||
|
||
DO_OEM_FUNC:
|
||
CMP WORD PTR [OEM_HANDLER],-1
|
||
JNZ OEM_JMP
|
||
JMP BADCALL ; Handler not initialized
|
||
|
||
OEM_JMP:
|
||
JMP [OEM_HANDLER]
|
||
|
||
ENDIF
|
||
|
||
|
||
ASSUME SS:DOSGROUP
|
||
|
||
;
|
||
; $Set_current_PDB takes BX and sets it to be the current process
|
||
; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
|
||
;
|
||
procedure $SET_CURRENT_PDB,NEAR
|
||
ASSUME DS:NOTHING,SS:NOTHING
|
||
MOV [CurrentPDB],BX
|
||
return
|
||
$SET_CURRENT_PDB ENDP
|
||
|
||
;
|
||
; $get_current_PDB returns in BX the current process
|
||
; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
|
||
;
|
||
procedure $GET_CURRENT_PDB,NEAR
|
||
ASSUME DS:NOTHING,SS:NOTHING
|
||
invoke get_user_stack
|
||
PUSH [CurrentPDB]
|
||
POP [SI.user_BX]
|
||
return
|
||
$GET_CURRENT_PDB ENDP
|
||
; ;
|
||
; C A V E A T P R O G R A M M E R ;
|
||
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
||
|
||
BREAK <NullDev -- Driver for null device>
|
||
procedure SNULDEV,FAR
|
||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
MOV WORD PTR [NULLDEVPT],BX
|
||
MOV WORD PTR [NULLDEVPT+2],ES
|
||
return
|
||
SNULDEV ENDP
|
||
|
||
procedure INULDEV,FAR
|
||
PUSH ES
|
||
PUSH BX
|
||
LES BX,[NULLDEVPT]
|
||
OR ES:[BX.REQSTAT],STDON ; Set done bit
|
||
POP BX
|
||
POP ES
|
||
return
|
||
|
||
INULDEV ENDP
|
||
|
||
|
||
BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers>>
|
||
|
||
|
||
IF IBM
|
||
ERRIN: ; Codes returned by BIOS
|
||
DB 2 ; NO RESPONSE
|
||
DB 6 ; SEEK FAILURE
|
||
DB 12 ; GENERAL ERROR
|
||
DB 4 ; BAD CRC
|
||
DB 8 ; SECTOR NOT FOUND
|
||
DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK
|
||
ERROUT: ; DISK ERRORS RETURNED FROM INT 25 and 26
|
||
DB 80H ; NO RESPONSE
|
||
DB 40H ; Seek failure
|
||
DB 2 ; Address Mark not found
|
||
DB 8 ; DMA OVERRUN
|
||
DB 4 ; SECTOR NOT FOUND
|
||
DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK
|
||
|
||
NUMERR EQU $-ERROUT
|
||
ENDIF
|
||
|
||
procedure ABSDRD,FAR
|
||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
|
||
CLI
|
||
MOV [user_SS],SS
|
||
MOV [user_SP],SP
|
||
PUSH CS
|
||
POP SS
|
||
ASSUME SS:DOSGROUP
|
||
MOV SP,OFFSET DOSGROUP:DSKSTACK
|
||
INC BYTE PTR [INDOS]
|
||
STI
|
||
CLD
|
||
PUSH ES
|
||
PUSH DS
|
||
PUSH SS
|
||
POP DS
|
||
ASSUME DS:DOSGROUP
|
||
invoke GETBP
|
||
POP DS
|
||
ASSUME DS:NOTHING
|
||
JC ILEAVE
|
||
invoke DSKREAD
|
||
TLEAVE:
|
||
JZ ILEAVE
|
||
|
||
IF IBM
|
||
; Translate the error code to ancient 1.1 codes
|
||
PUSH ES
|
||
PUSH CS
|
||
POP ES
|
||
XOR AH,AH ; Nul error code
|
||
MOV CX,NUMERR ; Number of possible error conditions
|
||
MOV DI,OFFSET DOSGROUP:ERRIN ; Point to error conditions
|
||
REPNE SCASB
|
||
JNZ LEAVECODE ; Not found
|
||
MOV AH,ES:[DI+NUMERR-1] ; Get translation
|
||
LEAVECODE:
|
||
POP ES
|
||
ENDIF
|
||
|
||
STC
|
||
ILEAVE:
|
||
POP ES
|
||
CLI
|
||
DEC BYTE PTR [INDOS]
|
||
MOV SP,[user_SP]
|
||
MOV SS,[user_SS]
|
||
ASSUME SS:NOTHING
|
||
STI
|
||
return
|
||
ABSDRD ENDP
|
||
|
||
procedure ABSDWRT,FAR
|
||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
|
||
CLI
|
||
MOV [user_SS],SS
|
||
MOV [user_SP],SP
|
||
PUSH CS
|
||
POP SS
|
||
ASSUME SS:DOSGROUP
|
||
MOV SP,OFFSET DOSGROUP:DSKSTACK
|
||
INC BYTE PTR [INDOS]
|
||
STI
|
||
CLD
|
||
PUSH ES
|
||
PUSH DS
|
||
PUSH SS
|
||
POP DS
|
||
ASSUME DS:DOSGROUP
|
||
invoke GETBP
|
||
POP DS
|
||
ASSUME DS:NOTHING
|
||
JC ILEAVE
|
||
invoke DSKWRITE
|
||
JMP TLEAVE
|
||
ABSDWRT ENDP
|
||
|
||
|
||
|
||
procedure SYS_RETURN,NEAR
|
||
ASSUME DS:NOTHING,ES:NOTHING
|
||
entry SYS_RET_OK
|
||
call get_user_stack
|
||
PUSH [SI.user_F]
|
||
POPF
|
||
CLC
|
||
JMP SHORT DO_RET
|
||
|
||
entry SYS_RET_ERR
|
||
XOR AH,AH ; hack to allow for smaller error rets
|
||
call get_user_stack
|
||
PUSH [SI.user_F]
|
||
POPF
|
||
STC
|
||
DO_RET:
|
||
MOV [SI.user_AX],AX ; Really only sets AH
|
||
PUSHF
|
||
POP [SI.user_F] ; dump on his flags
|
||
return
|
||
SYS_RETURN ENDP
|
||
|
||
do_ext
|
||
|
||
CODE ENDS
|
||
END
|
||
|