int21h.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,067 行 · 第 1/5 页
ASM
2,067 行
;Function 5A emulation.
;
Int21hCreateTemp proc near
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.
inc ecx
mov es,fs:[EPSP_Struc.EPSP_TransProt]
xor edi,edi
rep movsb
mov edi,offset Int21Buffer
mov es,cs:Int21hDSeg
mov eax,[ebp+Int_EAX]
mov es:RealRegsStruc.Real_EAX[edi],eax
mov eax,[ebp+Int_ECX]
mov es:RealRegsStruc.Real_ECX[edi],eax
mov es:RealRegsStruc.Real_EDX[edi],0
mov ax,WORD PTR fs:[EPSP_Struc.EPSP_TransReal]
mov es:RealRegsStruc.Real_DS[edi],ax
mov bl,21h
sys IntXX
mov eax,es:RealRegsStruc.Real_EAX[edi]
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
mov ax,es:RealRegsStruc.Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al
jnz int2127_9
mov ds,fs:[EPSP_Struc.EPSP_TransProt]
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_EDX]
call Int21hExtend_ES_EDI ;Extend [E]SI.
rep movsb
int2127_9: ret
Int21hCreateTemp endp
;------------------------------------------------------------------------------
;
;Function 5E emulation.
;
Int21hMSNet proc near
cmp ax,5e00h
jnz Int21hNotOurs
;
mov edi,offset Int21Buffer
mov es,cs:Int21hDseg
mov eax,[ebp+Int_EAX]
mov es:RealRegsStruc.Real_EAX[edi],eax
mov es:RealRegsStruc.Real_EDX[edi],0
mov ax,WORD PTR fs:[EPSP_Struc.EPSP_TransReal]
mov es:RealRegsStruc.Real_DS[edi],ax
mov bl,21h
sys IntXX ;read pen values.
mov eax,es:RealRegsStruc.Real_ECX[edi]
mov [ebp+Int_CX],ax
DOS4GExtend w[ebp+Int_ECX+2]
mov eax,es:RealRegsStruc.Real_EAX[edi]
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
mov ax,es:RealRegsStruc.Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
or al,al
jnz int2128_9
mov ds,WORD PTR fs:[EPSP_Struc.EPSP_TransProt]
xor esi,esi
mov es,[ebp+Int_ES]
mov edi,[ebp+Int_EDX]
call Int21hExtend_ES_EDI ;Extend [E]SI.
mov ecx,16/4
rep movsd ;copy the results.
int2128_9: ret
Int21hMSNet endp
;------------------------------------------------------------------------------
;
;Function 67 emulation.
;
Int21hSetHandles proc near
;
;Set handle count with DOS.
;
mov es,cs:Int21hDSeg
mov edi,offset Int21Buffer
mov es:RealRegsStruc.Real_EAX[edi],6700h
mov ax,[ebp+Int_BX]
mov es:RealRegsStruc.Real_EBX[edi],eax
mov bl,21h
sys IntXX
test es:RealRegsStruc.Real_Flags[edi],1
jz int2129_0
mov al,1
call Int21hAL2Carry ;Set carry.
mov eax,es:RealRegsStruc.Real_EAX[edi]
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
ret
;
;Change succeded so modify handle table selector base.
;
int2129_0: mov ds,cs:Int21hDSeg
assume ds:_cwMain
movzx eax,RealPSPSegment
shl eax,4
mov ds,RealSegment
assume ds:nothing
movzx edx,WORD PTR ds:[PSP_Struc.PSP_HandlePtr+2+eax]
shl edx,4
movzx ebx,WORD PTR ds:[PSP_Struc.PSP_HandlePtr+eax]
add edx,ebx
movzx ecx,WORD PTR ds:[PSP_Struc.PSP_Handles+eax]
mov bx,WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2]
sys SetSelDet32
;
;Now modify all PSP handle counts.
;
mov ds,cs:Int21hDSeg
assume ds:_cwMain
mov esi,BasePSPAddress
mov ds,RealSegment
assume ds:nothing
mov bx,[ebp+Int_BX]
int2129_1: mov PSP_Struc.PSP_Handles[esi],bx
mov esi,EPSP_Struc.EPSP_NextPSP[esi]
or esi,esi
jnz int2129_1
ret
if 0
mov bx,[ebp+Int_BX]
cmp bx,WORD PTR fs:[PSP_Struc.PSP_Handles] ;more or less?
jz int2129_sh0
jnc int2129_shb0
;
;Want less handles!
;
mov ax,fs
cmp ax,WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2] ;table still in PSP?
jz int2129_sh0
;
;Current table not in PSP.
;
cmp bx,20+1 ;20 is the lower limit.
jnc int2129_shs0
;
;Reduceing to 20 handles so move the table back into the PSP.
;
push fs
pop es
mov edi,offset PSP_Struc.PSP_HandleList
mov ecx,20
mov al,-1
rep stosb ;initialise the table first.
mov edi,offset PSP_HandleList
lds si,DWORD PTR fs:[PSP_Struc.PSP_HandlePtr] ;point to current list.
movzx esi,si
mov ecx,20
rep movsb ;copy 1st 20 entries.
jmp int2129_shs1
;
int2129_shs0: ;Still more than 20 handles so just re-size the memory.
;
push bx
movzx ecx,bx ;1 byte per entry.
mov bx,WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2]
sys ResMem32 ;re-size the memory.
pop bx
jc int2129_sh0 ;not sure if this can happen.
;
int2129_shs1: ;Now update the the DOS side of things and the PSP.
;
mov ax,bx
sub ax,WORD PTR fs:[PSP_Struc.PSP_Handles] ;find out how many less than before.
mov WORD PTR fs:[PSP_Struc.PSP_Handles],bx ;set new number of handles.
mov ds,cs:Int21hDSeg
assume ds:_cwMain
push ds
pop es
sub TotalHandles,ax ;update total count needed.
mov ax,TotalHandles
assume ds:nothing
or ax,1
mov edi,offset Int21Buffer
mov es:RealRegsStruc.Real_EAX[edi],6700h
mov es:RealRegsStruc.Real_EBX[edi],eax
mov bl,21h
sys IntXX ;set new value with DOS.
jmp int2129_sh0
;
int2129_shb0: ;Want more handles.
;
mov ax,bx
sub ax,WORD PTR fs:[PSP_Struc.PSP_Handles] ;find out how many more.
mov ds,cs:Int21hDSeg
assume ds:_cwMain
push ds
pop es
add ax,TotalHandles ;get total count needed.
assume ds:nothing
or ax,1
mov edi,offset Int21Buffer
mov es:RealRegsStruc.Real_EAX[edi],6700h
mov es:RealRegsStruc.Real_EBX[edi],eax
mov ecx,ebx
mov bl,21h
sys IntXX
mov ebx,ecx
mov eax,es:RealRegsStruc.Real_EAX[edi]
test es:RealRegsStruc.Real_Flags[edi],1
jnz int2129_sh0 ;no can do!
;
;We managed to set the new number with DOS, now try and get the
;memory needed to take care of things in protected mode.
;
mov ax,fs
cmp ax,WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2] ;table still in PSP?
jnz int2129_shb1
;
;Current table is in the PSP still so we want a fresh block
;of memory and a new selector.
;
movzx ecx,bx ;1 byte per entry.
sys GetMem32 ;allocate the memory.
jc int2129_shb2
push es
mov es,bx ;point to new memory.
xor edi,edi
mov al,-1
push ecx
movzx ecx,cx
rep stosb ;initialise table to nothing.
xor edi,edi
push ds
lds si,DWORD PTR fs:[PSP_Struc.PSP_HandlePtr]
movzx esi,si
mov cx,WORD PTR fs:[PSP_Struc.PSP_Handles]
movzx ecx,cx
rep movsb ;copy existing entries.
pop ds
pop ecx
mov WORD PTR fs:[PSP_Struc.PSP_HandlePtr],0
mov WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2],es
pop es
mov ax,cx
sub ax,WORD PTR fs:[PSP_Struc.PSP_Handles] ;find out how many more.
mov ds,cs:Int21hDSeg
assume ds:_cwMain
add TotalHandles,ax
assume ds:nothing
mov WORD PTR fs:[PSP_Struc.PSP_Handles],cx ;set new number.
xor ax,ax
clc
jmp int2129_sh0
;
int2129_shb1: ;Current table is NOT in the PSP so just do a re-size on the
;memory.
;
movzx ecx,bx ;1 byte per handle.
mov bx,WORD PTR fs:[PSP_Struc.PSP_HandlePtr+2]
sys ResMem32 ;try and get adjusted memory.
jc int2129_shb2
sub cx,WORD PTR fs:[PSP_Struc.PSP_Handles] ;get number differance.
mov di,WORD PTR fs:[PSP_Struc.PSP_Handles] ;get origional value.
mov al,-1
push ecx
push es
movzx edi,di
movzx ecx,cx
mov es,bx
rep stosb ;initialise new entries.
pop es
pop ecx
sub ax,WORD PTR fs:[PSP_Struc.PSP_Handles] ;find out how many more.
mov ds,cs:Int21hDSeg
assume ds:_cwMain
add TotalHandles,ax
assume ds:nothing
mov WORD PTR fs:[PSP_Struc.PSP_Handles],cx ;set new number.
xor ax,ax
clc
jmp int2129_sh0
;
int2129_shb2: ;Couldn't get the memory at the protected mode end of things
;so we need to put the DOS version back to its origional size.
;
mov ds,cs:Int21hDSeg
assume ds:_cwMain
mov ax,TotalHandles ;get total count needed.
assume ds:nothing
push ds
pop es
or ax,1
mov edi,offset Int21Buffer
mov es:RealRegsStruc.Real_EAX[edi],6700h
mov es:RealRegsStruc.Real_EBX[edi],eax
mov bl,21h
sys IntXX
stc
;
int2129_sh0: ;Finaly we pass our results back to the caller.
;
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
pushf
pop ax
and al,1
call Int21hAL2Carry ;Set carry.
ret
endif
Int21hSetHandles endp
;------------------------------------------------------------------------------
;
;Function 6C emulation.
;
Int21hExtendOpen proc near
mov ds,[ebp+Int_DS]
mov esi,[ebp+Int_ESI]
call Int21hExtend_DS_ESI ;Extend [E]SI.
xor al,al
call Int21hStringLen
inc ecx
mov es,WORD PTR fs:[EPSP_Struc.EPSP_TransProt]
xor edi,edi
rep movsb
mov edi,offset Int21Buffer
mov es,cs:Int21hDSeg
mov eax,[ebp+Int_EAX]
mov es:RealRegsStruc.Real_EAX[edi],eax
mov eax,[ebp+Int_EBX]
mov es:RealRegsStruc.Real_EBX[edi],eax
mov eax,[ebp+Int_ECX]
mov es:RealRegsStruc.Real_ECX[edi],eax
mov eax,[ebp+Int_EDX]
mov es:RealRegsStruc.Real_EDX[edi],edx
mov es:RealRegsStruc.Real_ESI[edi],0
mov ax,WORD PTR fs:[EPSP_Struc.EPSP_TransReal]
mov es:RealRegsStruc.Real_DS[edi],ax
mov bl,21h
sys IntXX
mov eax,es:RealRegsStruc.Real_EAX[edi]
mov [ebp+Int_AX],ax
DOS4GExtend w[ebp+Int_EAX+2]
mov eax,es:RealRegsStruc.Real_ECX[edi]
mov [ebp+Int_CX],ax
DOS4GExtend w[ebp+Int_ECX+2]
mov ax,es:RealRegsStruc.Real_Flags[edi]
and al,1
call Int21hAL2Carry ;Set carry.
ret
Int21hExtendOpen endp
;------------------------------------------------------------------------------
;
;Function FF, DOS4G detection.
;
Int21hDOS4GTest proc near
;
;This check only allowed for 32-bit programs which is what DOS4G uses.
;
test BYTE PTR cs:Int21hSystemFlags,1
jnz Int21hNotOurs
;
;Check register setup.
;
cmp b[ebp+Int_AL],0 ;AX=0FF00h
jnz Int21hNotOurs
cmp w[ebp+Int_DX],78h ;DX=0078h
jnz Int21hNotOurs
; changed for dummy segment modification
; mov w[ebp+Int_GS],ds
mov d[ebp+Int_EAX],4734ffffh
;
;Flag DOS4G mode for INT handling.
;
push ds
push eax
push ebx
push ecx
; mov ecx,ds ; save application DS value
xor ecx,ecx
mov cx,ds ; save application DS value
assume ds:nothing
mov ds,cs:Int21hDDSeg
assume ds:_Int21h
; give Watcom a dummy segment for it to stuff silly __D16SegInfo
; values in without trashing things, MED 12/12/95
mov ax,DOS16DummySegment
test ax,ax
jne setgs
push ecx ; save application DS value
; MED 07/15/97
DUMMYSEGMENTSIZE EQU 48h ; must be multiple of four
; mov ecx,44h ; dummy segment size
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?