interrup.asm

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

ASM
1,848
字号
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;Protected mode interrupt/exception handlers.
;

;-------------------------------------------------------------------------------

;
DpmiEmuSystemFlags dd 0
;
; do NOT change order of these variables (you can add at the end), MED 01/08/96
ExceptionCode   dd 0
ExceptionFlags  dd 0
ExceptionIndex  dd 0
;
ExceptionEBP    dd ?
ExceptionEDI    dd ?
ExceptionESI    dd ?
ExceptionEDX    dd ?
ExceptionECX    dd ?
ExceptionEBX    dd ?
ExceptionEAX    dd ?
ExceptionGS     dw ?,?
ExceptionFS     dw ?,?
ExceptionES     dw ?,?
ExceptionDS     dw ?,?
ExceptionEIP    dd ?
ExceptionCS     dw ?,?
ExceptionEFL    dd ?
ExceptionESP    dd ?
ExceptionSS     dw ?,?
ExceptionTR     dw ?
ExceptionCR0    dd ?
ExceptionCR2    dd ?
ExceptionCR3    dd ?
;
ExceptionHeader label byte
        db 13,10,"CauseWay Error 09 : Unrecoverable internal exception, program terminated.",13,10
        db 13,10,'Exception: '
ExceptionINum   db '00, Error code: '
ExceptionENum   db '0000',13,10,13,10
        db 'EAX='
ExceptionEAXt   db '00000000 '
        db 'EBX='
ExceptionEBXt   db '00000000 '
        db 'ECX='
ExceptionECXt   db '00000000 '
        db 'EDX='
ExceptionEDXt   db '00000000 '
        db 'ESI='
ExceptionESIt   db '00000000 '
        db 13,10
        db 'EDI='
ExceptionEDIt   db '00000000 '
        db 'EBP='
ExceptionEBPt   db '00000000 '
        db 'ESP='
ExceptionESPt   db '00000000 '
        db 'EIP='
ExceptionEIPt   db '00000000 '
        db 'EFL='
ExceptionEFLt   db '00000000 '
        db 13,10,13,10
        db 'CS='
ExceptionCSt    db '0000 '
        db 'DS='
ExceptionDSt    db '0000 '
        db 'ES='
ExceptionESt    db '0000 '
        db 'FS='
ExceptionFSt    db '0000 '
        db 'GS='
ExceptionGSt    db '0000 '
        db 'SS='
ExceptionSSt    db '0000 '
        db 13,10,13,10
        db 'CR0='
ExceptionCR0t   db '00000000 '
        db 'CR2='
ExceptionCR2t   db '00000000 '
        db 'CR3='
ExceptionCR3t   db '00000000 '
        db 'TR='
ExceptionTRt    db '0000'
        db 13,10,13,10
        db 'SystemFlags='
ExceptionSysFlags db '00000000 '
        db 13,10,13,10,'$'
ExceptionHeaderEnd      label byte
;
ExceptionIntBuffer db size RealRegsStruc dup (?)
;

;
;Generate the initial entry points for the interupt handlers.
;
InterruptHandler proc near
        rept 256
        db 0e8h
        dd offset IntHandler-($+4)
        db 3 dup (-1)
        endm
InterruptHandler endp


;-------------------------------------------------------------------------------
InterruptTable  proc    near
;
;Interupt handler entry points (Int nn and IntR).
;
IntNum  = 0
        rept 2fh
        dd offset IntNN386Catch+IntNum
        dw DpmiEmuCS
IntNum  = IntNum+8
        endm
        dd offset Raw2FPatch
        dw DpmiEmuCS
IntNum  = IntNum+8
        rept 30h-2fh
        dd offset IntNN386Catch+IntNum
        dw DpmiEmuCS
IntNum  = IntNum+8
        endm
        dd offset RawDPMIPatch
        dw DpmiEmuCS
IntNum  = IntNum+8
        rept 256-32h
        dd offset IntNN386Catch+IntNum
        dw DpmiEmuCS
IntNum  = IntNum+8
        endm
InterruptTable  endp


;-------------------------------------------------------------------------------
IntNN386Catch   proc    near
        rept 256
        db 0e8h
        dd offset IntNN386-($+4)
        db 3 dup (-1)
        endm
IntNN386Catch   endp


;-------------------------------------------------------------------------------
ExceptionTable  proc    near
;
;Exception handler entry points (Processor exceptions).
;
IntNum  = 0
        rept 32
        dd offset ExcepNN386Catch+IntNum
        dw DpmiEmuCS
IntNum  = IntNum+8
        endm
ExceptionTable  endp


;-------------------------------------------------------------------------------
ExcepNN386Catch proc near
        rept 32
        db 0e8h
        dd offset ExcepNN386-($+4)
        db 3 dup (-1)
        endm
ExcepNN386Catch endp


;-------------------------------------------------------------------------------
;
;Get protected mode interupt handler address.
;
;On Entry:-
;
;BL     - Interupt vector number.
;
;On Exit:-
;
;CF set on error. (no errors looked for).
;
;CX:EDX - selector:offset of current handler.
;
RawGetVector    proc    near
        ;
        push    eax
        push    ebx
        push    esi
        push    edi
        push    ebp
        push    ds
        push    es
        push    fs
        push    gs
        mov     ax,DpmiEmuDS
        mov     ds,ax
        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
        mov     edx,[ebx]               ;get offset.
        mov     cx,[ebx+4]              ;get segment selector.
        pop     gs
        pop     fs
        pop     es
        pop     ds
        pop     ebp
        pop     edi
        pop     esi
        pop     ebx
        pop     eax
        ret
RawGetVector    endp


;-------------------------------------------------------------------------------
;
;Get real mode interupt handler address.
;
;On Entry:-
;
;BL     - Interupt vector number.
;
;On Exit:-
;
;CF set on error. (no errors looked for).
;
;CX:DX  - selector:offset of current handler.
;
RawGetRVector   proc    near
        ;
        push    eax
        push    ebx
        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
        mov     dx,es:[ebx]
        mov     cx,es:[ebx+2]
        pop     gs
        pop     fs
        pop     es
        pop     ds
        pop     ebp
        pop     edi
        pop     esi
        pop     ebx
        pop     eax
        ret
RawGetRVector   endp


;-------------------------------------------------------------------------------
;
;Get protected mode exception handler address.
;
;On Entry:-
;
;BL     - Exception vector number.
;
;On Exit:-
;
;CF set on error.
;
;CX:EDX - selector:offset of current handler.
;
RawGetEVector   proc    near
        ;
;       pushm   eax,ebx,esi,edi,ebp,ds,es,fs,gs
        push    ds
        push    es
        push    fs
        push    gs
        push    ebx
        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
        mov     edx,eax
        mov     ebx,eax
        shl     ebx,1           ;*2
        mov     eax,ebx
        shl     ebx,1           ;*4
        add     ebx,eax         ;*6
        add     ebx,offset ExceptionTable
        ;
        cmp     dl,14           ;Special case for 14

;       jnz     @@Normal
        je      Special14       ; MED 01/17/96
        cmp     dl,20h
        jc      inter8_Normal
        stc                             ; flag error
        pop     eax
        mov     ax,8021h        ; flag invalid value
        push    eax
        jmp     inter8_GotVect  ; don't get vector

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

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

        mov     edx,[ebx]               ;get offset.
        mov     cx,[ebx+4]              ;get segment selector.
inter8_GotVect: ;
;       popm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
        pop     eax
        pop     ebp
        pop     edi
        pop     esi
        pop     ebx
        pop     gs
        pop     fs
        pop     es
        pop     ds

        ret
RawGetEVector   endp


;-------------------------------------------------------------------------------
;
;Set protected mode interupt handler address.
;
;On Entry:-
;
;BL     - Interupt vector number.
;CX:EDX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetVector    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,DpmiEmuDS
        mov     ds,ax
        test    BYTE PTR DpmiEmuSystemFlags,1
        jz      inter9_use32_add
        movzx   edx,dx
        ;
inter9_use32_add:       ;Check if its a hardware interrupt.
        ;
        mov     ax,KernalDS
        mov     ds,ax
        assume ds:_cwRaw
        movzx   ebx,bl
        mov     al,[ebx+Int2CallCheck]
        or      al,al
        jz      inter9_NotHardware

;*** MED 11/30/95
        cmp     bl,23h                  ; always allow 23h callback
        je      med2a
        cmp     bl,24h                  ; always allow 24h callback
        je      med2a
        test    BYTE PTR NoPassFlag,0ffh        ; see if not passing hardware interrupts from real to protected mode
        jne     inter9_NotHardware

        ;

med2a:
        cmp     cx,DpmiEmuCS            ;restoreing previous vector?
        jnz     inter9_Setting
inter9_Restoreing:      ;
        pushad
        movzx   cx,bl
        sub     bl,al
        movzx   bx,bl
        mov     ax,size CallBackStruc
        mul     bx
        mov     bx,ax
        add     bx,offset CallBackTable
        test    CallBackStruc.CallBackFlags[bx],1       ;this one in use?
        jz      inter9_DoneHardware     ;not likely.
        pushf
        cli
        push    es
        mov     ax,KernalZero
        mov     es,ax
        mov     CallBackStruc.CallBackFlags[bx],0       ;Mark this one as un-used.
        push    cx
        mov     cx,w[CallBackStruc.CallBackReal+2+bx]   ;get origional real mode vector.
        mov     dx,w[CallBackStruc.CallBackReal+bx]
        pop     bx
        shl     bx,2
        mov     es:[bx],dx
        mov     es:[bx+2],cx
        pop     es
        popf
        jmp     inter9_DoneHardware
inter9_Setting: ;
        pushad
        movzx   cx,bl
        sub     bl,al
        movzx   bx,bl
        mov     ax,size CallBackStruc
        mul     bx
        mov     dx,bx
        mov     bx,ax
        add     bx,offset CallBackTable
        test    CallBackStruc.CallBackFlags[bx],1               ;this one in use?
        jnz     inter9_DoneHardware
        pushf
        cli
        push    es
        mov     ax,KernalZero
        mov     es,ax
        mov     CallBackStruc.CallBackNum[bx],cl        ;set interupt number.
        mov     CallBackStruc.CallBackFlags[bx],1+2     ;mark call back as used interupt.
        mov     ax,CallBackSize
        mul     dx
        mov     si,offset ICallBackList
        add     si,ax           ;index list of calls.
        push    bx
        mov     bx,cx
        shl     bx,2
        mov     dx,es:[bx]
        mov     cx,es:[bx+2]
        mov     es:[bx],si
        mov     WORD PTR es:[bx+2],seg _cwRaw
        pop     bx
        mov     w[CallBackStruc.CallBackReal+2+bx],cx   ;store origional real mode vector.
        mov     w[CallBackStruc.CallBackReal+bx],dx
        pop     es
        popf
inter9_DoneHardware: popad
inter9_NotHardware:     mov     ax,DpmiEmuDS

⌨️ 快捷键说明

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