📄 int21h.asm
字号:
;
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
;
.386
_Int21h segment para public 'extension code' use32
assume cs:_Int21h, ds:nothing, es:nothing
Int21hStart label byte
;------------------------------------------------------------------------------
;
;DTA size for find first/next seems to be a little volatile so I'll use an EQU
;here incase it needs to change again.
;
DTASize equ 44-1
;------------------------------------------------------------------------------
;
;Some equates to make stacked register access simpler.
;
Int_EDI equ 0
Int_DI equ 0
Int_ESI equ 4
Int_SI equ 4
Int_EBP equ 8
Int_BP equ 8
Int_ESP equ 12
Int_SP equ 12
Int_EBX equ 16
Int_BX equ 16
Int_BL equ 16
Int_BH equ 17
Int_EDX equ 20
Int_DX equ 20
Int_DL equ 20
Int_DH equ 21
Int_ECX equ 24
Int_CX equ 24
Int_CL equ 24
Int_CH equ 25
Int_EAX equ 28
Int_AX equ 28
Int_AL equ 28
Int_AH equ 29
Int_GS equ 32
Int_FS equ 36
Int_ES equ 40
Int_DS equ 44
Int_Off equ 48
Int_Seg16 equ 50
Int_Seg32 equ 52
Int_Flags16 equ 52
Int_Flags32 equ 56
Int21h_repmovs macro
push ecx
shr ecx,2
rep movsd ;Copy the data.
pop ecx
and ecx,3
rep movsb
endm
DOS4GExtend macro p1
local __0
cmp cs:Int21hDOS4GFlag,0
jz __0
mov p1,0
__0: ;
endm
;------------------------------------------------------------------------------
;
;The DOS function control code.
;
;All registers are stacked and EBP is setup to give access to the stacked
;values. Carry is cleared, interrupts are enabled if they we're enabled at
;entry. FS is set to the current PSP. Then the function specific handler is
;called.
;
;All this default setup means some handlers have unecesary processing overhead
;but the majority need it and it saves space.
;
;NOTES:
;
;None of the FCB related functions are modified.
;Media ID byte pointer of Get drive default data not yet implemented.
;
Int21h proc near
pushm ds,es,fs,gs ;Preserve all registers.
pushad ;/
push eax
movzx eax,ah ;Need extended register version.
cmp cs:d[Int21hTable+eax*4],offset Int21hNotOurs
jz Int21hNotOurs
pop eax
mov ebp,esp ;Make registers addressable.
mov esi,Int_Flags32
test cs:Int21hSystemFlags,1 ;/
jz @@32bit0 ;/
movzx ebp,bp ;/
mov esi,Int_Flags16
@@32Bit0: add esi,ebp
and ss:b[esi],not 1
cld ;Default direction.
test ss:w[esi],1 shl 9 ;Were interrupts enabled?
jz @@NoInts
sti ;Turn interrupts back on.
@@NoInts: mov fs,cs:Int21hDSeg
assume fs:_cwMain
mov fs,fs:PSPSegment ;Point to PSP.
assume fs:nothing
movzx eax,ah ;Need extended register version.
call cs:d[Int21hTable+eax*4] ;Pass control to handler.
popad ;\
popm ds,es,fs,gs ;Restore all registers.
test cs:Int21hSystemFlags,1
jz @@32Bit1
iret
@@32Bit1: iretd ;Return to caller.
Int21h endp
;------------------------------------------------------------------------------
;
;Handler for functions that need to be passed to old DOS interrupt.
;
Int21hNotOurs proc near
pop eax ;Lose return address.
popad ;Restore registers.
popm ds,es,fs,gs
; cli
jmp cs:f[OldInt21h] ;pass it onto previous handler.
Int21hNotOurs endp
;------------------------------------------------------------------------------
Int21hInvalid proc near
jmp Int21hNotOurs
Int21hInvalid endp
;------------------------------------------------------------------------------
;
;Function 09h emulation.
;
Int21hPrintString proc near
mov esi,[ebp+Int_EDX] ;Point to source data.
mov ds,[ebp+Int_DS]
call Int21hExtend_DS_ESI ;Extend [E]SI.
mov al,"$" ;Character to look for.
call Int21hStringLen ;Get length of this string.
mov edx,ecx
;
;Now copy EPSP_TransSize-1 sized chunks into the transfer buffer
;and pass to the real mode handler.
;
@@0: mov ecx,edx ;Get current count.
cmp ecx,fs:[EPSP_TransSize]
jc @@1
mov ecx,fs:[EPSP_TransSize] ;Use transfer buffer size -1.
dec ecx
@@1: mov es,fs:[EPSP_TransProt] ;Point to transfer buffer.
xor edi,edi
sub edx,ecx ;Update total counter.
Int21h_repmovs ;Copy this data.
mov es:b[edi],"$" ;Terminate this string.
;
;Call the real mode handler to deal with this chunk.
;
mov es,cs:Int21hDSeg
mov edi,offset Int21Buffer
mov es:Real_EAX[edi],0900h
mov es:Real_EDX[edi],0
mov ax,fs:w[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
;
;Keep looping till all data is done.
;
or edx,edx
jnz @@0
;
;All done so return to caller.
;
ret
Int21hPrintString endp
;------------------------------------------------------------------------------
;
;Function 0A emulation.
;
Int21hGetString proc near
mov esi,[ebp+Int_EDX] ;Point to source data.
mov ds,[ebp+Int_DS]
call Int21hExtend_DS_ESI ;Extend [E]SI.
mov al,[esi] ;Get length byte.
mov es,fs:[EPSP_TransProt] ;Point to transfer buffer.
mov es:b[0],al ;Store length byte.
;
;Call the real mode handler to read the string.
;
mov es,cs:Int21hDSeg
mov edi,offset Int21Buffer
mov es:Real_EAX[edi],0A00h
mov es:Real_EDX[edi],0
mov ax,fs:w[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
;
;Copy returned string back into callers buffer.
;
mov edi,[ebp+Int_EDX] ;Point to destination buffer.
mov es,[ebp+Int_DS]
call Int21hExtend_ES_EDI ;Extend [E]DI.
mov ds,fs:[EPSP_TransProt]
xor esi,esi ;Point to source data.
movzx ecx,b[esi+1] ;get length of string read.
add ecx,1+1+1 ;max+len+eol.
Int21h_repmovs ;Copy this data.
;
;All done so return to caller.
;
ret
Int21hGetString endp
;------------------------------------------------------------------------------
;
;Function 1A emulation.
;
Int21hSetDTA proc near
mov esi,[ebp+Int_EDX] ;Point to source data.
mov ds,[ebp+Int_DS]
call Int21hExtend_DS_ESI ;Extend [E]SI.
mov fs:d[EPSP_Dta],esi
mov fs:w[EPSP_Dta+4],ds ;Store new DTA address.
ret
Int21hSetDTA endp
;------------------------------------------------------------------------------
;
;Function 25 emulation.
;
Int21hSetVect proc near
mov edx,[ebp+Int_EDX]
mov cx,[ebp+Int_DS]
mov bl,[ebp+Int_AL]
sys SetVect
ret
Int21hSetVect endp
;------------------------------------------------------------------------------
;
;Function 2F emulation.
;
Int21hGetDTA proc near
mov eax,fs:d[EPSP_DTA] ;Copy current DTA address into
mov [ebp+Int_EBX],eax ;return register storage.
mov ax,fs:w[EPSP_DTA+4]
mov [ebp+Int_ES],ax
ret
Int21hGetDTA endp
;------------------------------------------------------------------------------
;
;Function 35 emulation.
;
Int21hGetVect proc near
mov bl,[ebp+Int_AL]
xor edx,edx
sys GetVect
mov [ebp+Int_ES],cx
mov [ebp+Int_EBX],edx
ret
Int21hGetVect endp
;------------------------------------------------------------------------------
;
;Function 38 emulation.
;
Int21hGetSetCountry proc near
test cs:Int21hSystemFlags,1 ;16 or 32-bit -1 check?
jz @@32Bit0
cmp dx,-1 ;Setting code?
jmp @@ExitCheck ;pass to old handler?
@@32Bit0: cmp edx,-1
@@ExitCheck: jz Int21hNotOurs ;Go through normal stuff for SET.
;
;Call the real mode handler to take care of things.
;
mov es,cs:Int21hDseg
mov edi,offset Int21Buffer
mov eax,[ebp+Int_EAX]
mov es:Real_EAX[edi],eax
mov eax,[ebp+Int_EBX]
mov es:Real_EBX[edi],eax
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
mov eax,es:Real_EAX[edi]
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
mov eax,es:Real_EBX[edi]
mov [ebp+Int_BX],ax
DOS4GExtend w[ebp+Int_EBX+2]
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al
jnz @@9
;
;Copy returned info to callers buffer.
;
mov edi,[ebp+Int_EDX] ;Point to source data.
mov es,[ebp+Int_DS]
call Int21hExtend_ES_EDI ;Extend [E]DI.
mov ds,fs:[EPSP_TransProt]
xor esi,esi
mov ecx,22h
rep movsb
;
;Get re-map function address.
;
mov es,cs:Int21hDDSeg
mov edi,offset Int21hCountryTab
xor esi,esi
mov ax,w[esi+12h] ;Fetch offset.
mov es:Real_IP[edi],ax
mov ax,w[esi+14h] ;Fetch selector.
mov es:Real_CS[edi],ax
;
;Set new re-map function address.
;
mov eax,offset @@RemapCall
mov w[esi+12h],ax
mov w[esi+14h],cs
;
@@9: ret
;
;The remap handler.
;
@@RemapCall: pushm edi,es
mov es,cs:Int21hDDSeg
mov edi,offset Int21hCountryTab
mov es:Real_EAX[edi],eax
push es:Real_CS[edi]
push es:Real_IP[edi]
sys FarCallReal
pop es:Real_IP[edi]
pop es:Real_CS[edi]
mov eax,es:Real_EAX[edi]
popm edi,es
db 66h
retf
Int21hGetSetCountry endp
;------------------------------------------------------------------------------
;
;Function 39 emulation.
;
Int21hCreateDIR proc near
;
;Copy string into transfer buffer.
;
mov ds,[ebp+Int_DS]
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
xor al,al ;Character to look for.
call Int21hStringLen ;Get length of this string.
mov es,fs:[EPSP_TransProt]
xor edi,edi
inc ecx ;Include terminator.
rep movsb
;
;Pass control to real mode handler.
;
mov es,cs:Int21hDseg
mov edi,offset Int21Buffer
mov eax,[ebp+Int_EAX]
mov es:Real_EAX[edi],eax
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
mov eax,es:Real_EAX[edi] ;Get return code.
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
ret
Int21hCreateDIR endp
;------------------------------------------------------------------------------
;
;Function 3C emulation.
;
Int21hCreateFile proc near
;
;Copy string into transfer buffer.
;
mov ds,[ebp+Int_DS]
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
xor al,al ;Character to look for.
call Int21hStringLen ;Get length of this string.
mov es,fs:[EPSP_TransProt]
xor edi,edi
inc ecx ;Include terminator.
rep movsb
;
;Pass control to real mode handler.
;
mov es,cs:Int21hDseg
mov edi,offset Int21Buffer
mov eax,[ebp+Int_EAX]
mov es:Real_EAX[edi],eax
mov eax,[ebp+Int_ECX]
mov es:Real_ECX[edi],eax
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
mov eax,es:Real_EAX[edi] ;Get return code.
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
mov eax,es:Real_ECX[edi]
mov [ebp+Int_CX],ax
DOS4GExtend w[ebp+Int_ECX+2]
ret
Int21hCreateFile endp
;------------------------------------------------------------------------------
;
;Function 3D emulation.
;
Int21hOpenFile proc near
;
;Copy string into transfer buffer.
;
mov ds,[ebp+Int_DS]
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
xor al,al ;Character to look for.
call Int21hStringLen ;Get length of this string.
mov es,fs:[EPSP_TransProt]
xor edi,edi
inc ecx ;Include terminator.
rep movsb
;
;Pass control to real mode handler.
;
mov es,cs:Int21hDseg
mov edi,offset Int21Buffer
mov eax,[ebp+Int_EAX]
mov es:Real_EAX[edi],eax
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov bl,21h
sys IntXX
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
mov eax,es:Real_EAX[edi] ;Get return code.
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -