interrup.asm

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

ASM
1,848
字号
        mov     ds,ax
        assume ds:_cwDPMIEMU
        movzx   eax,bl
        mov     ebx,eax
        shl     ebx,1           ;*2
        mov     eax,ebx
        shl     ebx,1           ;*4
        add     ebx,eax         ;*6
        add     ebx,offset InterruptTable
        pushf
        cli
        mov     [ebx],edx               ;set offset.
        mov     [ebx+4],cx              ;set segment selector.
        popf
        pop     gs
        pop     fs
        pop     es
        pop     ds
        pop     ebp
        pop     edi
        pop     esi
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        ret
RawSetVector    endp


;-------------------------------------------------------------------------------
;
;Set real mode interupt handler address.
;
;On Entry:-
;
;BL     - Interupt vector number.
;CX:DX  - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetRVector   proc    near
        ;
        push    eax
        push    ebx
        push    ecx
        push    edx
        push    esi
        push    edi
        push    ebp
        push    ds
        push    es
        push    fs
        push    gs
        mov     ax,KernalZero
        mov     es,ax
        movzx   ebx,bl
        shl     ebx,2
        pushf
        cli
        mov     es:[ebx],dx
        mov     es:[ebx+2],cx
        popf
        pop     gs
        pop     fs
        pop     es
        pop     ds
        pop     ebp
        pop     edi
        pop     esi
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        ret
RawSetRVector   endp


;-------------------------------------------------------------------------------
;
;Set protected mode exception handler address.
;
;On Entry:-
;
;BL     - Exception vector number.
;CX:EDX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetEVector   proc    near
        ;
;       pushm   eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
        push    ds
        push    es
        push    fs
        push    gs
        push    ebx
        push    ecx
        push    edx
        push    esi
        push    edi
        push    ebp
        push    eax                     ; push last so is easily accessible for changing

        mov     ax,DpmiEmuDS
        mov     ds,ax
        movzx   eax,bl
        push    eax
        mov     ebx,eax
        shl     ebx,1           ;*2
        mov     eax,ebx
        shl     ebx,1           ;*4
        add     ebx,eax         ;*6
        pop     eax
        add     ebx,offset ExceptionTable
        ;
        cmp     al,14           ;Special case for 14

;       jnz     @@Normal
        je      Special14x      ; MED 01/17/96
        cmp     al,20h
        jc      inter11_Normal
        stc                             ; flag error
        pop     eax
        mov     ax,8021h        ; flag invalid value
        push    eax
        jmp     inter11_GotVect ; don't set vector

Special14x:
        cmp     w[OldExcep14+4],0       ;Virtual memory active?
        jz      inter11_Normal
        ;
        ;Vector 14 and VMM is still installed.
        ;
        mov     d[OldExcep14],edx
        mov     w[OldExcep14+4],cx
        jmp     inter11_GotVect
inter11_Normal: ;

        clc             ; MED 01/17/96, flag no error

        mov     [ebx],edx               ;set offset.
        mov     [ebx+4],cx              ;set segment selector.
inter11_GotVect:        ;

;       popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
        pop     eax
        pop     ebp
        pop     edi
        pop     esi
        pop     edx
        pop     ecx
        pop     ebx
        pop     gs
        pop     fs
        pop     es
        pop     ds

        ret
RawSetEVector   endp


;-------------------------------------------------------------------------------
;
;Allocate a real mode call back address.
;
;On Entry:-
;
;DS:ESI - Protected mode code.
;ES:EDI - Real mode register structure.
;
;On Exit:-
;
;Carry set on error, else,
;
;CX:DX  - Real mode address allocated.
;
RAWGetCallBack  proc near
        ;
        push    eax
        push    ebx
        push    esi
        push    edi
        push    ebp
        push    ds
        push    es
        mov     ax,ds
        push    ax
        mov     ax,KernalDS
        mov     ds,ax
        assume ds:_cwRaw
        pop     ax
        ;
;;MED 02/16/96
        mov     ebx,offset CallBackTable+((size CallBackStruc)*(16+3))
        mov     ecx,MaxCallBacks-(16+3)
        mov     edx,16+3
;       mov     ebx,offset CallBackTable+((size CallBackStruc)*(16+4))
;       mov     ecx,MaxCallBacks-(16+4)
;       mov     edx,16+4

inter12_0:      test    CallBackStruc.CallBackFlags[ebx],1              ;this one in use?
        jz      inter12_1
        add     ebx,size CallBackStruc
        inc     edx
        dec     ecx
        jnz     inter12_0
        jmp     inter12_9
        ;
inter12_1:      pushad
        xor     eax,eax
        mov     cx,1
        int     31h
        mov     w[CallBackStruc.CallBackStackSel+ebx],ax
        popad
        jc      inter12_9
        pushad
        mov     bx,w[CallBackStruc.CallBackStackSel+ebx]
        mov     eax,8
        xor     ecx,ecx
        or      edx,-1
        int     31h
        popad
        ;
        mov     w[CallBackStruc.CallBackProt+4+ebx],ax  ;store protected mode code address.
        mov     d[CallBackStruc.CallBackProt+0+ebx],esi ;/
        mov     w[CallBackStruc.CallBackRegs+4+ebx],es  ;store register table address.
        mov     d[CallBackStruc.CallBackRegs+0+ebx],edi ;/
        mov     ax,CallBackSize
        mul     dx
        mov     esi,offset CallBackList
        movzx   eax,ax
        add     esi,eax         ;index list of calls.
        mov     CallBackStruc.CallBackOff[ebx],si       ;store call back address.
        mov     CallBackStruc.CallBackFlags[ebx],1      ;flag this entry in use.
        mov     ax,_cwRaw
        mov     cx,ax           ;get real mode code seg.
        mov     dx,si           ;get real mode offset.
        clc
        jmp     inter12_10
        ;
inter12_9:      stc
inter12_10:
        pop     es
        pop     ds
        pop     ebp
        pop     edi
        pop     esi
        pop     ebx
        pop     eax
        ret
        assume ds:_cwDPMIEMU
RAWGetCallBack endp


;-------------------------------------------------------------------------------
;
;Release a previously allocated real mode call back address.
;
;On Entry:-
;
;CX:DX  - Real mode call back address.
;
RAWRelCallBack proc near
        ;
        pushad
        push    ds
        push    es
        push    fs
        push    gs
        push    ax
        mov     ax,KernalDS
        mov     ds,ax
        assume ds:_cwRaw
        pop     ax
        ;
        mov     esi,offset CallBackTable
        mov     ebx,MaxCallBacks
inter13_0:      test    CallBackStruc.CallBackFlags[esi],1
        jz      inter13_1
        cmp     dx,CallBackStruc.CallBackOff[esi]
        jnz     inter13_1
        mov     CallBackStruc.CallBackFlags[esi],0
        mov     bx,CallBackStruc.CallBackStackSel[esi]
        mov     ax,1
        int     31h
        clc
        jmp     inter13_2
        ;
inter13_1:      add     esi,size CallBackStruc
        dec     ebx
        jnz     inter13_0
        stc
        ;
inter13_2:
        pop     gs
        pop     fs
        pop     es
        pop     ds
        popad
        ret
        assume ds:_cwDPMIEMU
RAWRelCallBack endp


;-------------------------------------------------------------------------------
;
;Need to retrieve the interupt number.
;
IntHandler      proc    near
        push    ds
        push    eax
        mov     ax,DpmiEmuDS            ;make our data addresable.
        mov     ds,ax           ;/
        movzx   esp,sp          ;our stack never >64k.
        mov     eax,[esp+(4+4)] ;get return address.
        sub     eax,offset InterruptHandler
        shr     eax,3           ;convert it to an interrupt number.
        mov     ExceptionIndex,eax      ;/
;
;Check if this is an exception or interrupt (any error code)
;
        cmp     esp,tPL0StackSize-4-((4+4)+(4)+(4)+(4+4+4)+(4+4))
        ;                            |    |   |     |      |
        ; EAX:DS --------------------/    |   |     |      |
        ;                                 |   |     |      |
        ; Return address -----------------/   |     |      |
        ;                                     |     |      |
        ; Error code -------------------------/     |      |
        ;                                           |      |
        ; EIP:CS:Eflags ----------------------------/      |
        ;                                                  |
        ; ESP:SS ------------------------------------------/
        ;
        jnz     inter14_NoCode
        and     w[esp+(4+4)+(4)+(4)+(4+4)],0011111111010101b

; MED 12/02/95
; check if Exception Index is 0dh
;  if so and instruction at CS:EIP is:
;   mov eax,cr0 [0f 20 c0]  or
;   mov cr0,eax [0f 22 c0] or
;   mov eax,cr3 [0f 20 d8] or
;   mov cr3,eax [0f 22 d8]
;  then emulate it here and return
; MED 11/12/98, emulate RDMSR [0f 32]
; MED 04/05/99, emulate WBINVD [0f 09]
;   WRMSR [0f 30]
;   mov eax,cr4 [0f 20 e0]
;   mov cr4,eax [0f 22 e0]
; MED 05/02/2000, mov ebx,cr4 [0f 20 e3]
;   mov eax,cr2 [0f 20 d0]
        push    ds
        cmp     eax,0dh
        jne     mednoem                 ; not a GPF

        mov     ax,ss:[esp+(4+4)+(4)+(4+4)+4]   ; ax==original CS
;       verr    ax                      ; check for looping lockup invalid value
;       jnz     mednoem
        mov     ds,ax
        mov     eax,ss:[esp+(4+4)+(4)+(4)+4]    ; eax==original EIP

        cmp     BYTE PTR ds:[eax],0fh   ; first opcode byte
        jne     mednoem                 ; no match
        cmp     WORD PTR ds:[eax+1],0c020h      ; mov eax,cr0
        jne     med2b
        mov     eax,cr0
        mov     ss:[esp+4],eax          ; update original eax with cr0 value
        jmp     medemu

med2b:
        cmp     WORD PTR ds:[eax+1],0c022h      ; move cr0,eax
        jne     med3b                   ; no match
        mov     eax,ss:[esp+4]  ; get original eax value
        mov     cr0,eax                 ; update cr0 value with original eax
        jmp     medemu

med3b:
        cmp     WORD PTR ds:[eax+1],0d820h      ; mov eax,cr3
        jne     med4b
        mov     eax,cr3
        mov     ss:[esp+4],eax          ; update original eax with cr3 value
        jmp     medemu

med4b:
        cmp     WORD PTR ds:[eax+1],0d822h      ; move cr3,eax
        jne     med5b                   ; no match
        mov     eax,ss:[esp+4]  ; get original eax value
        mov     cr3,eax                 ; update cr3 value with original eax
        jmp     medemu

med5b:
        cmp     WORD PTR ds:[eax+1],0e022h      ; move cr4,eax
        jne     med6b                   ; no match
        mov     eax,ss:[esp+4]  ; get original eax value

.586
        mov     cr4,eax                 ; update cr4 value with original eax
        jmp     medemu

med6b:
        cmp     WORD PTR ds:[eax+1],0e020h      ; mov eax,cr4
        jne     med7b

.586
        mov     eax,cr4
        mov     ss:[esp+4],eax          ; update original eax with cr4 value
        jmp     medemu

med7b:
        cmp     BYTE PTR ds:[eax+1],9   ; WBINVD
        jne     med8b

.586
        wbinvd
        mov     eax,2
        jmp     medemu2

med8b:
        cmp     BYTE PTR ds:[eax+1],30h ; WRMSR
        jne     med9b

.586
        mov     eax,ss:[esp+4]  ; get original eax value
        wrmsr
        mov     eax,2
        jmp     medemu2

med9b:
        cmp     BYTE PTR ds:[eax+1],32h ; RDMSR
        jne     med10b

;       push    eax
.586
        rdmsr
;       DB      0fh                             ; RDMSR instruction
;       DB      32h
;       mov     ss:[esp+8],eax  ; update original eax value
;       pop     eax
        mov     ss:[esp+4],eax  ; update original eax value
        mov     eax,2
        jmp     medemu2

med10b:
        cmp     WORD PTR ds:[eax+1],0e320h      ; mov ebx,cr4
        jne     med11b                  ; no match

.586
        mov     ebx,cr4
        jmp     medemu

med11b:
        cmp     WORD PTR ds:[eax+1],0d020h      ; mov eax,cr2
        jne     mednoem
        mov     eax,cr2
        mov     ss:[esp+4],eax          ; update original eax with cr2 value
;       jmp     medemu

medemu:

⌨️ 快捷键说明

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