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 + -
显示快捷键?