📄 int21h.asm
字号:
ret
Int21hOpenFile endp
;------------------------------------------------------------------------------
;
;Function 3F emulation.
;
Int21hReadFile proc near
mov ds,[ebp+Int_DS] ;Point to source.
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
mov es,cs:Int21hDSeg
mov edi,offset Int21Buffer
movzx edx,w[ebp+Int_CX] ;Get length.
cmp cs:Int21hDOS4GFlag,0
jz @@4
mov edx,[ebp+Int_ECX] ;Get length.
@@4: xor ebx,ebx ;Reset length read.
@@0: mov ecx,edx
cmp ecx,fs:[EPSP_TransSize]
jc @@1
mov ecx,fs:[EPSP_TransSize]
@@1: mov es:Real_ECX[edi],ecx ;Store length.
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov ax,[ebp+Int_AX]
mov es:Real_EAX[edi],eax
mov ax,[ebp+Int_BX] ;Set handle.
mov es:Real_EBX[edi],eax
push ebx
mov bl,21h
sys IntXX
pop ebx
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al ;Carry set?
jz @@2
mov ebx,es:Real_EAX[edi] ;get return code.
jmp @@3
@@2: mov eax,es:Real_EAX[edi] ;get bytes read.
movzx eax,ax
sub edx,eax ;Update count remaining.
add ebx,eax ;Update count so far.
push ecx
mov ecx,eax
pushm edi,es
pushm esi,ds
popm edi,es
mov ds,fs:[EPSP_TransProt]
xor esi,esi
Int21h_repmovs ;Copy this data.
pushm edi,es
popm esi,ds
popm edi,es
pop ecx
cmp eax,ecx
jnz @@3
or edx,edx
jnz @@0
@@3: mov [ebp+Int_AX],bx ;store length or return code.
cmp cs:Int21hDOS4GFlag,0
jz @@5
mov [ebp+Int_EAX],ebx
@@5: ret
Int21hReadFile endp
;------------------------------------------------------------------------------
;
;Function 40 emulation.
;
Int21hWriteFile proc near
mov ds,[ebp+Int_DS] ;Point to source.
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
mov es,cs:Int21hDSeg
mov edi,offset Int21Buffer
movzx edx,w[ebp+Int_CX] ;Get length.
cmp cs:Int21hDOS4GFlag,0
jz @@4
mov edx,[ebp+Int_ECX] ;Get length.
@@4: xor ebx,ebx ;Reset length read.
@@0: mov ecx,edx
cmp ecx,fs:[EPSP_TransSize]
jc @@1
mov ecx,fs:[EPSP_TransSize]
@@1: mov es:Real_ECX[edi],ecx ;Store length.
mov es:Real_EDX[edi],0
mov ax,fs:[EPSP_TransReal]
mov es:Real_DS[edi],ax
mov ax,[ebp+Int_AX]
mov es:Real_EAX[edi],eax
mov ax,[ebp+Int_BX] ;Set handle.
mov es:Real_EBX[edi],eax
pushm ecx,edi,es
mov es,fs:[EPSP_TransProt]
xor edi,edi
Int21h_repmovs ;Copy this data.
popm ecx,edi,es
push ebx
mov bl,21h
sys IntXX ;Do the write.
pop ebx
mov ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al ;Carry set?
jz @@2
mov ebx,es:Real_EAX[edi] ;get return code.
jmp @@3
@@2: mov eax,es:Real_EAX[edi] ;get bytes read.
movzx eax,ax
sub edx,eax ;Update count remaining.
add ebx,eax ;Update count so far.
cmp eax,ecx ;Get anything?
jnz @@3
or edx,edx
jnz @@0
@@3: mov [ebp+Int_AX],bx ;store length or return code.
cmp cs:Int21hDOS4GFlag,0
jz @@5
mov [ebp+Int_EAX],ebx
@@5: ret
Int21hWriteFile endp
;------------------------------------------------------------------------------
;
;Function 44 emulation.
;
Int21hIOCTLDispatch proc near
mov al,[ebp+Int_AL]
cmp al,02h ;IOCTL?
jz Int21hReadFile
cmp al,03h
jz Int21hWriteFile
cmp al,04h
jz Int21hReadFile
cmp al,05h
jz Int21hWriteFile
jmp Int21hNotOurs
Int21hIOCTLDispatch endp
;------------------------------------------------------------------------------
;
;Function 47 emulation.
;
Int21hGetCurDir proc near
;
;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_EDX]
mov es:Real_EDX[edi],eax
mov es:Real_ESI[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 ax,es:Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al
jnz @@9
;
;Copy returned info to callers buffer.
;
mov ds,fs:[EPSP_TransProt] ;Point to source data.
xor esi,esi
xor al,al ;Character to look for.
call Int21hStringLen ;Get length of this string.
inc ecx
mov es,[ebp+Int_DS]
mov edi,[ebp+Int_ESI]
call Int21hExtend_ES_EDI ;Extend [E]SI.
rep movsb
@@9: ret
Int21hGetCurDir endp
;------------------------------------------------------------------------------
;
;Function 48 emulation.
;
Int21hAllocMem proc near
cmp bx,-1 ;maximum free check?
jz @@AllocMuch
movzx ebx,bx
shl ebx,4 ;convert paragraphs to bytes.
mov dx,bx
shr ebx,16
mov cx,bx
sys GetMem ;try to allocate memory.
jc @@AllocMuch ;report how much free then.
mov [ebp+Int_AX],bx ;get the selector allocated.
DOS4GExtend w[ebp+Int_EAX+2]
ret
;
@@AllocMuch: mov cx,-1
mov dx,-1
sys GetMem ;get free memory size.
mov bx,cx
shl ebx,16
mov bx,dx
cmp ebx,0fffeh*16 ;can't report too much.
jc @@AllocOK
mov ebx,0fffeh*16
@@AllocOK: shr ebx,4 ;convert to paragraphs free.
mov [ebp+Int_BX],ax
DOS4GExtend w[ebp+Int_EBX+2]
mov w[ebp+Int_AX],1
DOS4GExtend w[ebp+Int_EAX+2]
call Int21hAL2Carry ;Set carry.
ret
Int21hAllocMem endp
;------------------------------------------------------------------------------
;
;Function 49 emulation.
;
Int21hRelMem proc near
mov bx,[ebp+Int_ES]
mov ds,[ebp+Int_DS]
mov es,[ebp+Int_ES]
mov fs,[ebp+Int_FS]
mov gs,[ebp+Int_GS]
sys RelMem
mov [ebp+Int_DS],ds
mov [ebp+Int_ES],es
mov [ebp+Int_FS],fs
mov [ebp+Int_GS],gs
ret
Int21hRelMem endp
;------------------------------------------------------------------------------
;
;Function 4A emulation.
;
Int21hResMem proc near
movzx ebx,w[ebp+Int_BX]
shl ebx,4 ;convert paragraphs to bytes.
mov dx,bx
shr ebx,16
mov cx,bx
mov bx,[ebp+Int_ES]
sys ResMem
pushf
pop ax
and al,1
call Int21hAL2Carry ;Set carry.
ret
Int21hResMem endp
;------------------------------------------------------------------------------
;
;Function 4B emulation.
;
Int21hExecFile proc near
cmp b[ebp+Int_AL],0 ;We only support sub-function 0.
jz @@OK
@@Done: call Int21hAL2Carry ;Set carry.
ret
;
@@OK: ;Copy the file name into transfer buffer.
;
mov ds,[ebp+Int_DS]
mov esi,[ebp+Int_EDX]
call Int21hExtend_DS_ESI ;Extend [E]SI.
xor al,al
call Int21hStringLen ;Get length of this string.
inc ecx
mov es,fs:[EPSP_TransProt]
xor edi,edi
rep movsb ;Copy the file name.
;
;Copy the command line into transfer buffer.
;
mov ebx,[ebp+Int_EBX]
mov ds,[ebp+Int_ES]
cmp cs:Int21hDOS4GFlag,0
jz @@0
lds esi,f[ebx+4+2]
jmp @@Ef4
@@0: test cs:Int21hSystemFlags,1
jz @@Ef3
movzx ebx,bx
movzx esi,w[ebx+2] ;Get command line offset.
mov ds,[ebx+2+2] ;& segment.
jmp @@Ef4
@@Ef3: mov esi,[ebx+2]
mov ds,[ebx+2+4]
@@Ef4: mov es,fs:[EPSP_TransProt]
mov edi,256
movzx ecx,b[esi] ;get command line length.
inc ecx ;include length byte.
rep movsb
mov al,0dh
stosb
mov al,0
stosb
;
;Copy the FCB's
;
if 0
pushm ecx,esi,edi,ds,es
push ds
mov ds,cs:Int21hDSeg
assume ds:_cwMain
test SystemFlags,1
assume ds:nothing
pop ds
jz @@Ef6
movzx ebx,bx
movzx edi,es:w[ebx+(2)+(2+2)] ;Get FCB 1 offset.
mov es,es:[ebx+(2)+(2+2)+2] ;& segment.
jmp @@Ef7
@@Ef6: mov edi,es:[ebx+(2)+(4+2)]
mov es,es:[ebx+(2)+(4+2)+4]
@@Ef7: mov ds,cs:Int21hDSeg
assume ds:_cwMain
lds esi,TransferBuffer
assume ds:nothing
add esi,512
pushm esi,edi,ds,es
popm edi,esi,es,ds
mov ecx,10h
cld
rep movsb
popm ecx,esi,edi,ds,es
;
pushm ecx,esi,edi,ds,es
push ds
mov ds,cs:Int21hDSeg
assume ds:_cwMain
test SystemFlags,1
assume ds:nothing
pop ds
jz @@Ef8
movzx ebx,bx
movzx edi,es:w[ebx+(2)+(2+2)+(2+2)] ;Get FCB 2 offset.
mov es,es:[ebx+(2)+(2+2)+(2+2)+2] ;& segment.
jmp @@Ef9
@@Ef8: mov edi,es:[ebx+(2)+(4+2)+(4+2)]
mov es,es:[ebx+(2)+(4+2)+(4+2)+4]
@@Ef9: mov ds,cs:Int21hDSeg
assume ds:_cwMain
lds esi,TransferBuffer
assume ds:nothing
add esi,512+16
pushm esi,edi,ds,es
popm edi,esi,es,ds
mov ecx,10h
cld
rep movsb
popm ecx,esi,edi,ds,es
endif
;
;Sort out the environment.
;
mov edi,[ebp+Int_EBX]
mov es,[ebp+Int_ES]
call Int21hExtend_ES_EDI ;Extend [E]SI.
mov ebx,edi
xor esi,esi
cmp cs:Int21hDOS4GFlag,0
jz @@1
cmp es:w[ebx+4],0
jz @@2
lds esi,es:f[ebx]
jmp @@ef12
@@1: cmp es:w[ebx],0 ;got an environment?
jnz @@Ef10
@@2: mov ds,fs:w[PSP_Environment] ;Get current environment.
jmp @@Ef12
@@Ef10: mov ds,es:[ebx] ;get environment segment.
@@Ef12: push esi
@@3: lodsb
or al,al
jnz @@3
cmp b[esi],0 ;double zero?
jnz @@3
inc esi
inc esi
pop eax
push eax
sub esi,eax
mov ecx,esi
add esi,256 ;make space for execution path.
add esi,15
shr esi,4 ;get paragraphs needed.
mov edi,offset Int21Buffer
mov es,cs:Int21hDSeg
mov es:Real_EBX[edi],esi
mov es:Real_EAX[edi],4800h
pop esi
mov bl,21h
sys IntXX ;allocate this memory.
mov eax,es:Real_EAX[edi] ;get segment address.
test es:Real_Flags[edi],1
mov di,ax
mov al,1
jnz @@Ef13
movzx edi,di
push edi
shl edi,4
mov es,cs:Int21hDSeg
assume es:_cwMain
mov es,es:RealSegment
assume es:nothing
rep movsb ;Copy environment.
pop edx
;
;Patch INT 21h exec function to preserve the stack.
;
pushad
mov ds,cs:Int21hDSeg
assume ds:_cwMain
cmp NoEXECPatchFlag,0
jne medex1
mov bl,21h
mov ax,200h
int 31h
mov w[OldInt21hExec],dx
mov w[OldInt21hExec+2],cx
mov dx,offset Int21hExecPatch
mov cx,_cwMain
mov bl,21h
mov ax,201h
IFNDEF DEBUG5
int 31h
ENDIF
medex1:
assume ds:nothing
popad
;
;Setup real mode parameter block.
;
mov ax,fs:w[EPSP_TransReal]
mov ds,fs:w[EPSP_TransProt]
mov esi,512+32
mov w[esi],dx ;set environment segment.
mov w[esi+2],256 ;command tail offset.
mov w[esi+4],ax ;command tail segment.
mov w[esi+6],512 ;FCB 1 offset.
mov w[esi+8],ax ;FCB 1 segment.
mov w[esi+10],512+16 ;FCB 2 offset.
mov w[esi+12],ax ;FCB 2 segment.
;
mov edi,offset Int21Buffer
mov es,cs:Int21hDSeg
mov es:Real_EAX[edi],4b00h
mov es:Real_EBX[edi],512+32
mov es:Real_EDX[edi],0
mov es:Real_DS[edi],ax
mov es:Real_ES[edi],ax
mov bl,21h
sys IntXX
;
;Restore INT 21h patch.
;
pushad
mov ds,cs:Int21hDSeg
assume ds:_cwMain
cmp NoEXECPatchFlag,0
jne medex2
mov bl,21h
mov dx,w[OldInt21hExec]
mov cx,w[OldInt21hExec+2]
mov d[OldInt21hExec],0
mov ax,201h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -