mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-14 10:47:14 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
468
v2.0/source/CTRLC.ASM
Normal file
468
v2.0/source/CTRLC.ASM
Normal file
|
@ -0,0 +1,468 @@
|
|||
;
|
||||
; ^C status routines for MSDOS
|
||||
;
|
||||
|
||||
INCLUDE DOSSEG.ASM
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.ASM
|
||||
INCLUDE DEVSYM.ASM
|
||||
.cref
|
||||
.list
|
||||
|
||||
i_need DevIOBuf,BYTE
|
||||
i_need DidCTRLC,BYTE
|
||||
i_need INDOS,BYTE
|
||||
i_need DSKSTCOM,BYTE
|
||||
i_need DSKSTCALL,BYTE
|
||||
i_need DSKSTST,WORD
|
||||
i_need BCON,DWORD
|
||||
i_need DSKCHRET,BYTE
|
||||
i_need DSKSTCNT,WORD
|
||||
i_need IDLEINT,BYTE
|
||||
i_need CONSWAP,BYTE
|
||||
i_need user_SS,WORD
|
||||
i_need user_SP,WORD
|
||||
i_need ERRORMODE,BYTE
|
||||
i_need ConC_spSave,WORD
|
||||
i_need Exit_type,BYTE
|
||||
i_need PFLAG,BYTE
|
||||
i_need ExitHold,DWORD
|
||||
i_need WPErr,BYTE
|
||||
i_need ReadOp,BYTE
|
||||
i_need CONTSTK,WORD
|
||||
i_need Exit_Code,WORD
|
||||
i_need CurrentPDB,WORD
|
||||
i_need DIVMES,BYTE
|
||||
i_need DivMesLen,BYTE
|
||||
|
||||
SUBTTL Checks for ^C in CON I/O
|
||||
PAGE
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in
|
||||
CMP BYTE PTR [INDOS],1
|
||||
retnz ; Do NOTHING
|
||||
PUSH CX
|
||||
PUSH ES
|
||||
PUSH BX
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
PUSH CS
|
||||
POP ES
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
XOR CX,CX
|
||||
MOV BYTE PTR [DSKSTCOM],DEVRDND
|
||||
MOV BYTE PTR [DSKSTCALL],DRDNDHL
|
||||
MOV [DSKSTST],CX
|
||||
MOV BX,OFFSET DOSGROUP:DSKSTCALL
|
||||
LDS SI,[BCON]
|
||||
ASSUME DS:NOTHING
|
||||
invoke DEVIOCALL2
|
||||
TEST [DSKSTST],STBUI
|
||||
JNZ ZRET ; No characters available
|
||||
MOV AL,BYTE PTR [DSKCHRET]
|
||||
DSK1:
|
||||
CMP AL,"C"-"@"
|
||||
JNZ RET36
|
||||
MOV BYTE PTR [DSKSTCOM],DEVRD
|
||||
MOV BYTE PTR [DSKSTCALL],DRDWRHL
|
||||
MOV BYTE PTR [DSKCHRET],CL
|
||||
MOV [DSKSTST],CX
|
||||
INC CX
|
||||
MOV [DSKSTCNT],CX
|
||||
invoke DEVIOCALL2 ; Eat the ^C
|
||||
POP SI
|
||||
POP DS
|
||||
POP BX ; Clean stack
|
||||
POP ES
|
||||
POP CX
|
||||
JMP SHORT CNTCHAND
|
||||
|
||||
ZRET:
|
||||
XOR AL,AL ; Set zero
|
||||
RET36:
|
||||
POP SI
|
||||
POP DS
|
||||
POP BX
|
||||
POP ES
|
||||
POP CX
|
||||
return
|
||||
|
||||
NOSTOP:
|
||||
CMP AL,"P"-"@"
|
||||
JZ INCHK
|
||||
|
||||
IF NOT TOGLPRN
|
||||
CMP AL,"N"-"@"
|
||||
JZ INCHK
|
||||
ENDIF
|
||||
|
||||
CMP AL,"C"-"@"
|
||||
JZ INCHK
|
||||
return
|
||||
DSKSTATCHK ENDP
|
||||
|
||||
procedure SPOOLINT,NEAR
|
||||
PUSHF
|
||||
CMP BYTE PTR [IDLEINT],0
|
||||
JZ POPFRET
|
||||
CMP BYTE PTR [ERRORMODE],0
|
||||
JNZ POPFRET ;No spool ints in error mode
|
||||
INT int_spooler
|
||||
POPFRET:
|
||||
POPF
|
||||
RET18: return
|
||||
SPOOLINT ENDP
|
||||
|
||||
procedure STATCHK,NEAR
|
||||
|
||||
invoke DSKSTATCHK ; Allows ^C to be detected under
|
||||
; input redirection
|
||||
PUSH BX
|
||||
XOR BX,BX
|
||||
invoke GET_IO_FCB
|
||||
POP BX
|
||||
JC RET18
|
||||
MOV AH,1
|
||||
invoke IOFUNC
|
||||
JZ SPOOLINT
|
||||
CMP AL,'S'-'@'
|
||||
JNZ NOSTOP
|
||||
XOR AH,AH
|
||||
invoke IOFUNC ; Eat Cntrl-S
|
||||
JMP SHORT PAUSOSTRT
|
||||
PRINTOFF:
|
||||
PRINTON:
|
||||
NOT BYTE PTR [PFLAG]
|
||||
return
|
||||
|
||||
PAUSOLP:
|
||||
CALL SPOOLINT
|
||||
PAUSOSTRT:
|
||||
MOV AH,1
|
||||
invoke IOFUNC
|
||||
JZ PAUSOLP
|
||||
INCHK:
|
||||
PUSH BX
|
||||
XOR BX,BX
|
||||
invoke GET_IO_FCB
|
||||
POP BX
|
||||
JC RET18
|
||||
XOR AH,AH
|
||||
invoke IOFUNC
|
||||
CMP AL,'P'-'@'
|
||||
JZ PRINTON
|
||||
IF NOT TOGLPRN
|
||||
CMP AL,'N'-'@'
|
||||
JZ PRINTOFF
|
||||
ENDIF
|
||||
CMP AL,'C'-'@'
|
||||
retnz
|
||||
STATCHK ENDP
|
||||
|
||||
procedure CNTCHAND,NEAR
|
||||
; Ctrl-C handler.
|
||||
; "^C" and CR/LF is printed. Then the user registers are restored and
|
||||
; the user CTRL-C handler is executed. At this point the top of the stack
|
||||
; has 1) the interrupt return address should the user CTRL-C handler wish
|
||||
; to allow processing to continue; 2) the original interrupt return address
|
||||
; to the code that performed the function call in the first place. If
|
||||
; the user CTRL-C handler wishes to continue, it must leave all registers
|
||||
; unchanged and RET (not IRET) with carry CLEAR. If carry is SET then
|
||||
; an terminate system call is simulated.
|
||||
MOV AL,3 ; Display "^C"
|
||||
invoke BUFOUT
|
||||
invoke CRLF
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
CMP BYTE PTR [CONSWAP],0
|
||||
JZ NOSWAP
|
||||
invoke SWAPBACK
|
||||
NOSWAP:
|
||||
CLI ; Prepare to play with stack
|
||||
MOV SP,[user_SP]
|
||||
MOV SS,[user_SS] ; User stack now restored
|
||||
ASSUME SS:NOTHING
|
||||
invoke restore_world ; User registers now restored
|
||||
ASSUME DS:NOTHING
|
||||
MOV BYTE PTR [INDOS],0 ; Go to known state
|
||||
MOV BYTE PTR [ERRORMODE],0
|
||||
MOV [ConC_spsave],SP ; save his SP
|
||||
INT int_ctrl_c ; Execute user Ctrl-C handler
|
||||
MOV [user_SS],AX ; save the AX
|
||||
PUSHF ; and the flags (maybe new call)
|
||||
POP AX
|
||||
CMP SP,[ConC_spsave]
|
||||
JNZ ctrlc_try_new ; new syscall maybe?
|
||||
ctrlc_repeat:
|
||||
MOV AX,[user_SS] ; no...
|
||||
transfer COMMAND ; Repeat command otherwise
|
||||
|
||||
ctrlc_try_new:
|
||||
SUB [ConC_spsave],2 ; Are there flags on the stack?
|
||||
CMP SP,[ConC_spsave]
|
||||
JZ ctrlc_new ; yes, new system call
|
||||
|
||||
ctrlc_abort:
|
||||
MOV AX,(EXIT SHL 8) + 0
|
||||
MOV BYTE PTR [DidCTRLC],0FFh
|
||||
|
||||
transfer COMMAND ; give up by faking $EXIT
|
||||
|
||||
ctrlc_new:
|
||||
PUSH AX
|
||||
POPF
|
||||
POP [user_SS]
|
||||
JNC ctrlc_repeat ; repeat operation
|
||||
JMP ctrlc_abort ; indicate ^ced
|
||||
|
||||
CNTCHAND ENDP
|
||||
|
||||
SUBTTL DIVISION OVERFLOW INTERRUPT
|
||||
PAGE
|
||||
; Default handler for division overflow trap
|
||||
procedure DIVOV,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
MOV SI,OFFSET DOSGROUP:DIVMES
|
||||
CALL RealDivOv
|
||||
JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow
|
||||
DIVOV ENDP
|
||||
|
||||
;
|
||||
; RealDivOv: perform actual divide overflow stuff.
|
||||
; Inputs: none
|
||||
; Outputs: message to BCON
|
||||
;
|
||||
procedure RealDivOv,NEAR ; Do divide overflow and clock process
|
||||
|
||||
PUSH CS ; get ES addressability
|
||||
POP ES
|
||||
|
||||
PUSH CS ; get DS addressability
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
|
||||
MOV BYTE PTR [DskStCom],DevWrt
|
||||
MOV BYTE PTR [DskStCall],DRdWrHL
|
||||
MOV [DskSTST],0
|
||||
MOV BL,[DivMesLen]
|
||||
XOR BH,BH
|
||||
MOV [DskStCnt],BX
|
||||
MOV BX,OFFSET DOSGROUP:DskStCall
|
||||
MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU)
|
||||
LDS SI,[BCON]
|
||||
ASSUME DS:NOTHING
|
||||
invoke DEVIOCALL2
|
||||
MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf
|
||||
MOV [DskStCnt],1
|
||||
return
|
||||
RealDivOv ENDP
|
||||
|
||||
SUBTTL CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER
|
||||
PAGE
|
||||
procedure CHARHARD,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
|
||||
|
||||
; Character device error handler
|
||||
; Same function as HARDERR
|
||||
|
||||
MOV WORD PTR [EXITHOLD+2],ES
|
||||
MOV WORD PTR [EXITHOLD],BP
|
||||
PUSH SI
|
||||
AND DI,STECODE
|
||||
MOV BP,DS ;Device pointer is BP:SI
|
||||
CALL FATALC
|
||||
POP SI
|
||||
return
|
||||
CHARHARD ENDP
|
||||
|
||||
procedure HardErr,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Hard disk error handler. Entry conditions:
|
||||
; DS:BX = Original disk transfer address
|
||||
; DX = Original logical sector number
|
||||
; CX = Number of sectors to go (first one gave the error)
|
||||
; AX = Hardware error code
|
||||
; DI = Original sector transfer count
|
||||
; ES:BP = Base of drive parameters
|
||||
; [READOP] = 0 for read, 1 for write
|
||||
;
|
||||
XCHG AX,DI ; Error code in DI, count in AX
|
||||
AND DI,STECODE ; And off status bits
|
||||
CMP DI,WRECODE ; Write Protect Error?
|
||||
JNZ NOSETWRPERR
|
||||
PUSH AX
|
||||
MOV AL,ES:[BP.dpb_drive]
|
||||
MOV BYTE PTR [WPERR],AL ; Flag drive with WP error
|
||||
POP AX
|
||||
NOSETWRPERR:
|
||||
SUB AX,CX ; Number of sectors successfully transferred
|
||||
ADD DX,AX ; First sector number to retry
|
||||
PUSH DX
|
||||
MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred
|
||||
POP DX
|
||||
ADD BX,AX ; First address for retry
|
||||
XOR AH,AH ; Flag disk section in error
|
||||
CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area?
|
||||
JB ERRINT
|
||||
INC AH ; Flag for FAT
|
||||
CMP DX,ES:[BP.dpb_dir_sector] ; In FAT?
|
||||
JB ERRINT
|
||||
INC AH
|
||||
CMP DX,ES:[BP.dpb_first_sector] ; In directory?
|
||||
JB ERRINT
|
||||
INC AH ; Must be in data area
|
||||
ERRINT:
|
||||
SHL AH,1 ; Make room for read/write bit
|
||||
OR AH,BYTE PTR [READOP]
|
||||
entry FATAL
|
||||
MOV AL,ES:[BP.dpb_drive] ; Get drive number
|
||||
entry FATAL1
|
||||
MOV WORD PTR [EXITHOLD+2],ES
|
||||
MOV WORD PTR [EXITHOLD],BP ; The only things we preserve
|
||||
LES SI,ES:[BP.dpb_driver_addr]
|
||||
MOV BP,ES ; BP:SI points to the device involved
|
||||
FATALC:
|
||||
CMP BYTE PTR [ERRORMODE],0
|
||||
JNZ SETIGN ; No INT 24s if already INT 24
|
||||
MOV [CONTSTK],SP
|
||||
PUSH SS
|
||||
POP ES
|
||||
ASSUME ES:DOSGROUP
|
||||
CLI ; Prepare to play with stack
|
||||
INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress
|
||||
DEC BYTE PTR [INDOS] ; INT 24 handler might not return
|
||||
MOV SS,[user_SS]
|
||||
ASSUME SS:NOTHING
|
||||
MOV SP,ES:[user_SP] ; User stack pointer restored
|
||||
INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES
|
||||
MOV ES:[user_SP],SP ; restore our stack
|
||||
MOV ES:[user_SS],SS
|
||||
MOV SP,ES
|
||||
MOV SS,SP
|
||||
ASSUME SS:DOSGROUP
|
||||
MOV SP,[CONTSTK]
|
||||
INC BYTE PTR [INDOS] ; Back in the DOS
|
||||
MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24
|
||||
STI
|
||||
IGNRET:
|
||||
LES BP,[EXITHOLD]
|
||||
ASSUME ES:NOTHING
|
||||
CMP AL,2
|
||||
JZ error_abort
|
||||
MOV BYTE PTR [WPERR],-1 ;Forget about WP error
|
||||
return
|
||||
|
||||
SETIGN:
|
||||
XOR AL,AL ;Flag ignore
|
||||
JMP SHORT IGNRET
|
||||
|
||||
error_abort:
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
CMP BYTE PTR [CONSWAP],0
|
||||
JZ NOSWAP2
|
||||
invoke SWAPBACK
|
||||
NOSWAP2:
|
||||
MOV BYTE PTR [exit_Type],Exit_hard_error
|
||||
MOV DS,[CurrentPDB]
|
||||
ASSUME DS:NOTHING
|
||||
|
||||
;
|
||||
; reset_environment checks the DS value against the CurrentPDB. If they
|
||||
; are different, then an old-style return is performed. If they are
|
||||
; the same, then we release jfns and restore to parent. We still use
|
||||
; the PDB at DS:0 as the source of the terminate addresses.
|
||||
;
|
||||
; output: none.
|
||||
;
|
||||
entry reset_environment
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
PUSH DS ; save PDB of process
|
||||
|
||||
MOV AL,int_Terminate
|
||||
invoke $Get_interrupt_vector ; and who to go to
|
||||
MOV WORD PTR [EXITHOLD+2],ES ; save return address
|
||||
MOV WORD PTR [EXITHOLD],BX
|
||||
|
||||
MOV BX,[CurrentPDB] ; get current process
|
||||
MOV DS,BX ;
|
||||
MOV AX,DS:[PDB_Parent_PID] ; get parent to return to
|
||||
POP CX
|
||||
;
|
||||
; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB
|
||||
; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not
|
||||
; Exit_keep_process
|
||||
;
|
||||
CMP AX,BX
|
||||
JZ reset_return ; parentPDB = CurrentPDB
|
||||
CMP BX,CX
|
||||
JNZ reset_return ; CurrentPDB <> ThisPDB
|
||||
PUSH AX ; save parent
|
||||
CMP BYTE PTR [exit_type],Exit_keep_process
|
||||
JZ reset_to_parent ; keeping this process
|
||||
|
||||
invoke arena_free_process
|
||||
|
||||
; reset environment at [CurrentPDB]; close those handles
|
||||
MOV CX,FilPerProc
|
||||
|
||||
reset_free_jfn:
|
||||
MOV BX,CX
|
||||
PUSH CX
|
||||
DEC BX ; get jfn
|
||||
invoke $CLOSE ; close it, ignore return
|
||||
POP CX
|
||||
LOOP reset_free_jfn ; and do 'em all
|
||||
|
||||
reset_to_parent:
|
||||
POP [CurrentPDB] ; set up process as parent
|
||||
|
||||
reset_return: ; come here for normal return
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV AL,-1
|
||||
invoke FLUSHBUF ; make sure that everything is clean
|
||||
|
||||
CLI
|
||||
MOV BYTE PTR [INDOS],0 ;Go to known state
|
||||
MOV BYTE PTR [WPERR],-1 ;Forget about WP error
|
||||
;
|
||||
; Snake into multitasking... Get stack from CurrentPDB person
|
||||
;
|
||||
MOV DS,[CurrentPDB]
|
||||
ASSUME DS:NOTHING
|
||||
MOV SS,WORD PTR DS:[PDB_user_stack+2]
|
||||
MOV SP,WORD PTR DS:[PDB_user_stack]
|
||||
|
||||
ASSUME SS:NOTHING
|
||||
invoke restore_world
|
||||
ASSUME ES:NOTHING
|
||||
POP AX ; suck off CS:IP of interrupt...
|
||||
POP AX
|
||||
POP AX
|
||||
MOV AX,0F202h ; STI
|
||||
PUSH AX
|
||||
PUSH WORD PTR [EXITHOLD+2]
|
||||
PUSH WORD PTR [EXITHOLD]
|
||||
STI
|
||||
IRET ; Long return back to user terminate address
|
||||
HardErr ENDP
|
||||
|
||||
ASSUME SS:DOSGROUP
|
||||
|
||||
do_ext
|
||||
|
||||
CODE ENDS
|
||||
END
|
Loading…
Add table
Add a link
Reference in a new issue