int21h.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,067 行 · 第 1/5 页

ASM
2,067
字号
;
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
;
        .386P
_Int21h segment para private 'extension code' use32
        assume cs:_Int21h, ds:nothing, es:nothing
Int21hStart     label byte

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
OldInt21h       df 0
Int21hCSeg      dw ?
Int21hDSeg      dw ?
Int21hDDSeg     dw ?
Int21hSystemFlags dd ?
;
Int21hCountryTab db size RealRegsStruc dup (?)
;
Int21hDOS4GFlag db 0
;
DOS16DummySegment       DW      0


;------------------------------------------------------------------------------
;
;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


;------------------------------------------------------------------------------
;
; MED 02/02/2003, in STRUCS.INC
;;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
        push    ds
        push    es
        push    fs
        push    gs
        pushad          ;/
        push    eax
        movzx   eax,ah          ;Need extended register version.
        cmp     DWORD PTR cs:[Int21hTable+eax*4],offset Int21hNotOurs
        jz      Int21hNotOurs
        pop     eax
        mov     ebp,esp         ;Make registers addressable.
        mov     esi,Int_Flags32
        test    BYTE PTR cs:Int21hSystemFlags,1 ;/
        jz      int211_32bit0           ;/
        movzx   ebp,bp          ;/
        mov     esi,Int_Flags16
int211_32Bit0:  add     esi,ebp
        and     BYTE PTR ss:[esi],not 1
        cld                     ;Default direction.
        test    WORD PTR ss:[esi],1 shl 9       ;Were interrupts enabled?
        jz      int211_NoInts
        sti                     ;Turn interrupts back on.
int211_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    DWORD PTR cs:[Int21hTable+eax*4]        ;Pass control to handler.
        popad                   ;\
        pop     gs
        pop     fs
        pop     es
        pop     ds
        test    BYTE PTR cs:Int21hSystemFlags,1
        jz      int211_32Bit1
        iret
int211_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.
        pop     gs
        pop     fs
        pop     es
        pop     ds
;       cli
        jmp     FWORD PTR cs:[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_Struc.EPSP_TransSize-1 sized chunks into the transfer buffer
;and pass to the real mode handler.
;
int214_0:       mov     ecx,edx         ;Get current count.
        cmp     ecx,fs:[EPSP_Struc.EPSP_TransSize]
        jc      int214_1
        mov     ecx,fs:[EPSP_Struc.EPSP_TransSize]      ;Use transfer buffer size -1.
        dec     ecx
int214_1:       mov     es,fs:[EPSP_Struc.EPSP_TransProt]       ;Point to transfer buffer.
        xor     edi,edi
        sub     edx,ecx         ;Update total counter.
        Int21h_repmovs          ;Copy this data.
        mov     BYTE PTR es:[edi],"$"   ;Terminate this string.
        ;
        ;Call the real mode handler to deal with this chunk.
        ;
        mov     es,cs:Int21hDSeg
        mov     edi,offset Int21Buffer
        mov     es:RealRegsStruc.Real_EAX[edi],0900h
        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
        ;
        ;Keep looping till all data is done.
        ;
        or      edx,edx
        jnz     int214_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_Struc.EPSP_TransProt]       ;Point to transfer buffer.
        mov     BYTE PTR es:[0],al              ;Store length byte.
        ;
        ;Call the real mode handler to read the string.
        ;
        mov     es,cs:Int21hDSeg
        mov     edi,offset Int21Buffer
        mov     es:RealRegsStruc.Real_EAX[edi],0A00h
        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
        ;
        ;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_Struc.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     DWORD PTR fs:[EPSP_Struc.EPSP_Dta],esi
        mov     WORD PTR fs:[EPSP_Struc.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,DWORD PTR fs:[EPSP_Struc.EPSP_DTA]  ;Copy current DTA address into
        mov     [ebp+Int_EBX],eax       ;return register storage.
        mov     ax,WORD PTR fs:[EPSP_Struc.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    BYTE PTR cs:Int21hSystemFlags,1 ;16 or 32-bit -1 check?
        jz      int2110_32Bit0
        cmp     dx,-1           ;Setting code?
        jmp     int2110_ExitCheck               ;pass to old handler?
int2110_32Bit0: cmp     edx,-1
int2110_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:RealRegsStruc.Real_EAX[edi],eax
        mov     eax,[ebp+Int_EBX]
        mov     es:RealRegsStruc.Real_EBX[edi],eax
        mov     es:RealRegsStruc.Real_EDX[edi],0
        mov     ax,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_EBX[edi]
        mov     [ebp+Int_BX],ax
        DOS4GExtend w[ebp+Int_EBX+2]
        mov     ax,es:RealRegsStruc.Real_Flags[edi]
        and     al,1
        call    Int21hAL2Carry  ;Set carry.
        or      al,al
        jnz     int2110_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_Struc.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:RealRegsStruc.Real_IP[edi],ax
        mov     ax,w[esi+14h]   ;Fetch selector.
        mov     es:RealRegsStruc.Real_CS[edi],ax
        ;
        ;Set new re-map function address.
        ;
        mov     eax,offset int2110_RemapCall
        mov     w[esi+12h],ax
        mov     w[esi+14h],cs
        ;
int2110_9:      ret
;
;The remap handler.
;
int2110_RemapCall:
        push    edi
        push    es
        mov     es,cs:Int21hDDSeg
        mov     edi,offset Int21hCountryTab
        mov     es:RealRegsStruc.Real_EAX[edi],eax
        push    es:RealRegsStruc.Real_CS[edi]
        push    es:RealRegsStruc.Real_IP[edi]
        sys     FarCallReal
        pop     es:RealRegsStruc.Real_IP[edi]
        pop     es:RealRegsStruc.Real_CS[edi]
        mov     eax,es:RealRegsStruc.Real_EAX[edi]
        pop     es
        pop     edi
        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_Struc.EPSP_TransProt]
        xor     edi,edi
        inc     ecx             ;Include terminator.
        rep     movsb

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?