home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / caway349.zip / SOURCE / ALL / INTERRUP.ASM < prev    next >
Assembly Source File  |  1999-04-05  |  36KB  |  1,680 lines

  1. ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  2. ;
  3. ;Protected mode interrupt/exception handlers.
  4. ;
  5.  
  6. ;-------------------------------------------------------------------------------
  7. ;
  8. ;Generate the initial entry points for the interupt handlers.
  9. ;
  10. InterruptHandler proc near
  11.     rept 256
  12.     db 0e8h
  13.     dd offset IntHandler-($+4)
  14.     db 3 dup (-1)
  15.     endm
  16. InterruptHandler endp
  17.  
  18.  
  19. ;-------------------------------------------------------------------------------
  20. InterruptTable    proc    near
  21. ;
  22. ;Interupt handler entry points (Int nn and IntR).
  23. ;
  24. IntNum    = 0
  25.     rept 2fh
  26.     dd offset IntNN386Catch+IntNum
  27.     dw DpmiEmuCS
  28. IntNum    = IntNum+8
  29.     endm
  30.     dd offset Raw2FPatch
  31.     dw DpmiEmuCS
  32. IntNum    = IntNum+8
  33.     rept 30h-2fh
  34.     dd offset IntNN386Catch+IntNum
  35.     dw DpmiEmuCS
  36. IntNum    = IntNum+8
  37.     endm
  38.     dd offset RawDPMIPatch
  39.     dw DpmiEmuCS
  40. IntNum    = IntNum+8
  41.     rept 256-32h
  42.     dd offset IntNN386Catch+IntNum
  43.     dw DpmiEmuCS
  44. IntNum    = IntNum+8
  45.     endm
  46. InterruptTable    endp
  47.  
  48.  
  49. ;-------------------------------------------------------------------------------
  50. IntNN386Catch    proc    near
  51.     rept 256
  52.     db 0e8h
  53.     dd offset IntNN386-($+4)
  54.     db 3 dup (-1)
  55.     endm
  56. IntNN386Catch    endp
  57.  
  58.  
  59. ;-------------------------------------------------------------------------------
  60. ExceptionTable    proc    near
  61. ;
  62. ;Exception handler entry points (Processor exceptions).
  63. ;
  64. IntNum    = 0
  65.     rept 32
  66.     dd offset ExcepNN386Catch+IntNum
  67.     dw DpmiEmuCS
  68. IntNum    = IntNum+8
  69.     endm
  70. ExceptionTable    endp
  71.  
  72.  
  73. ;-------------------------------------------------------------------------------
  74. ExcepNN386Catch proc near
  75.     rept 32
  76.     db 0e8h
  77.     dd offset ExcepNN386-($+4)
  78.     db 3 dup (-1)
  79.     endm
  80. ExcepNN386Catch endp
  81.  
  82.  
  83. ;-------------------------------------------------------------------------------
  84. ;
  85. ;Get protected mode interupt handler address.
  86. ;
  87. ;On Entry:-
  88. ;
  89. ;BL    - Interupt vector number.
  90. ;
  91. ;On Exit:-
  92. ;
  93. ;CF set on error. (no errors looked for).
  94. ;
  95. ;CX:EDX    - selector:offset of current handler.
  96. ;
  97. RawGetVector    proc    near
  98.     call    RAWCopyCheck
  99.     ;
  100.     pushm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  101.     mov    ax,DpmiEmuDS
  102.     mov    ds,ax
  103.     movzx    eax,bl
  104.     mov    ebx,eax
  105.     shl    ebx,1        ;*2
  106.     mov    eax,ebx
  107.     shl    ebx,1        ;*4
  108.     add    ebx,eax        ;*6
  109.     add    ebx,offset InterruptTable
  110.     mov    edx,[ebx]        ;get offset.
  111.     mov    cx,[ebx+4]        ;get segment selector.
  112.     popm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  113.     ret
  114. RawGetVector    endp
  115.  
  116.  
  117. ;-------------------------------------------------------------------------------
  118. ;
  119. ;Get real mode interupt handler address.
  120. ;
  121. ;On Entry:-
  122. ;
  123. ;BL    - Interupt vector number.
  124. ;
  125. ;On Exit:-
  126. ;
  127. ;CF set on error. (no errors looked for).
  128. ;
  129. ;CX:DX    - selector:offset of current handler.
  130. ;
  131. RawGetRVector    proc    near
  132.     call    RAWCopyCheck
  133.     ;
  134.     pushm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  135.     mov    ax,KernalZero
  136.     mov    es,ax
  137.     movzx    ebx,bl
  138.     shl    ebx,2
  139.     mov    dx,es:[ebx]
  140.     mov    cx,es:[ebx+2]
  141.     popm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  142.     ret
  143. RawGetRVector    endp
  144.  
  145.  
  146. ;-------------------------------------------------------------------------------
  147. ;
  148. ;Get protected mode exception handler address.
  149. ;
  150. ;On Entry:-
  151. ;
  152. ;BL    - Exception vector number.
  153. ;
  154. ;On Exit:-
  155. ;
  156. ;CF set on error.
  157. ;
  158. ;CX:EDX    - selector:offset of current handler.
  159. ;
  160. RawGetEVector    proc    near
  161.     call    RAWCopyCheck
  162.     ;
  163. ;    pushm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  164.     push    ds
  165.     push    es
  166.     push    fs
  167.     push    gs
  168.     push    ebx
  169.     push    esi
  170.     push    edi
  171.     push    ebp
  172.     push    eax            ; push last so is easily accessible for changing
  173.  
  174.     mov    ax,DpmiEmuDS
  175.     mov    ds,ax
  176.     movzx    eax,bl
  177.     mov    edx,eax
  178.     mov    ebx,eax
  179.     shl    ebx,1        ;*2
  180.     mov    eax,ebx
  181.     shl    ebx,1        ;*4
  182.     add    ebx,eax        ;*6
  183.     add    ebx,offset ExceptionTable
  184.     ;
  185.     cmp    dl,14        ;Special case for 14
  186.  
  187. ;    jnz    @@Normal
  188.     je    Special14    ; MED 01/17/96
  189.     cmp    dl,20h
  190.     jc    @@Normal
  191.     stc                ; flag error
  192.     pop    eax
  193.     mov    ax,8021h    ; flag invalid value
  194.     push    eax
  195.     jmp    @@GotVect    ; don't get vector
  196.  
  197. Special14:
  198.     cmp    w[OldExcep14+4],0    ;Virtual memory active?
  199.     jz    @@Normal
  200.     ;
  201.     ;Vector 14 and VMM is installed.
  202.     ;
  203.     mov    edx,d[OldExcep14]
  204.     mov    cx,w[OldExcep14+4]
  205.     jmp    @@GotVect
  206. @@Normal:    ;
  207.  
  208.     clc        ; MED 01/17/96, flag no error
  209.  
  210.     mov    edx,[ebx]        ;get offset.
  211.     mov    cx,[ebx+4]        ;get segment selector.
  212. @@GotVect:    ;
  213. ;    popm    eax,ebx,esi,edi,ebp,ds,es,fs,gs
  214.     pop    eax
  215.     pop    ebp
  216.     pop    edi
  217.     pop    esi
  218.     pop    ebx
  219.     pop    gs
  220.     pop    fs
  221.     pop    es
  222.     pop    ds
  223.  
  224.     ret
  225. RawGetEVector    endp
  226.  
  227.  
  228. ;-------------------------------------------------------------------------------
  229. ;
  230. ;Set protected mode interupt handler address.
  231. ;
  232. ;On Entry:-
  233. ;
  234. ;BL    - Interupt vector number.
  235. ;CX:EDX    - selector:offset of new handler.
  236. ;
  237. ;On Exit:-
  238. ;
  239. ;CF set on error.
  240. ;
  241. RawSetVector    proc    near
  242.     call    RAWCopyCheck
  243.     ;
  244.     pushm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  245.     mov    ax,DpmiEmuDS
  246.     mov    ds,ax
  247.     test    DpmiEmuSystemFlags,1
  248.     jz    @@use32_add
  249.     movzx    edx,dx
  250.     ;
  251. @@use32_add:    ;Check if its a hardware interrupt.
  252.     ;
  253.     mov    ax,KernalDS
  254.     mov    ds,ax
  255.     assume ds:_cwRaw
  256.     movzx    ebx,bl
  257.     mov    al,[ebx+Int2CallCheck]
  258.     or    al,al
  259.     jz    @@NotHardware
  260.  
  261. ;*** MED 11/30/95
  262.     cmp    bl,23h            ; always allow 23h callback
  263.     je    med2
  264.     cmp    bl,24h            ; always allow 24h callback
  265.     je    med2
  266.     test    NoPassFlag,0ffh    ; see if not passing hardware interrupts from real to protected mode
  267.     jne    @@NotHardware
  268.  
  269.     ;
  270.  
  271. med2:
  272.     cmp    cx,DpmiEmuCS        ;restoreing previous vector?
  273.     jnz    @@Setting
  274. @@Restoreing:    ;
  275.     pushad
  276.     movzx    cx,bl
  277.     sub    bl,al
  278.     movzx    bx,bl
  279.     mov    ax,size CallBackStruc
  280.     mul    bx
  281.     mov    bx,ax
  282.     add    bx,offset CallBackTable
  283.     test    CallBackFlags[bx],1    ;this one in use?
  284.     jz    @@DoneHardware    ;not likely.
  285.     pushf
  286.     cli
  287.     push    es
  288.     mov    ax,KernalZero
  289.     mov    es,ax
  290.     mov    CallBackFlags[bx],0    ;Mark this one as un-used.
  291.     push    cx
  292.     mov    cx,w[CallBackReal+2+bx]    ;get origional real mode vector.
  293.     mov    dx,w[CallBackReal+bx]
  294.     pop    bx
  295.     shl    bx,2
  296.     mov    es:[bx],dx
  297.     mov    es:[bx+2],cx
  298.     pop    es
  299.     popf
  300.     jmp    @@DoneHardware
  301. @@Setting:    ;
  302.     pushad
  303.     movzx    cx,bl
  304.     sub    bl,al
  305.     movzx    bx,bl
  306.     mov    ax,size CallBackStruc
  307.     mul    bx
  308.     mov    dx,bx
  309.     mov    bx,ax
  310.     add    bx,offset CallBackTable
  311.     test    CallBackFlags[bx],1        ;this one in use?
  312.     jnz    @@DoneHardware
  313.     pushf
  314.     cli
  315.     push    es
  316.     mov    ax,KernalZero
  317.     mov    es,ax
  318.     mov    CallBackNum[bx],cl    ;set interupt number.
  319.     mov    CallBackFlags[bx],1+2    ;mark call back as used interupt.
  320.     mov    ax,CallBackSize
  321.     mul    dx
  322.     mov    si,offset ICallBackList
  323.     add    si,ax        ;index list of calls.
  324.     push    bx
  325.     mov    bx,cx
  326.     shl    bx,2
  327.     mov    dx,es:[bx]
  328.     mov    cx,es:[bx+2]
  329.     mov    es:[bx],si
  330.     mov    es:w[bx+2],seg _cwRaw
  331.     pop    bx
  332.     mov    w[CallBackReal+2+bx],cx    ;store origional real mode vector.
  333.     mov    w[CallBackReal+bx],dx
  334.     pop    es
  335.     popf
  336. @@DoneHardware: popad
  337. @@NotHardware:    mov    ax,DpmiEmuDS
  338.     mov    ds,ax
  339.     assume ds:_cwDPMIEMU
  340.     movzx    eax,bl
  341.     mov    ebx,eax
  342.     shl    ebx,1        ;*2
  343.     mov    eax,ebx
  344.     shl    ebx,1        ;*4
  345.     add    ebx,eax        ;*6
  346.     add    ebx,offset InterruptTable
  347.     pushf
  348.     cli
  349.     mov    [ebx],edx        ;set offset.
  350.     mov    [ebx+4],cx        ;set segment selector.
  351.     popf
  352.     popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  353.     ret
  354. RawSetVector    endp
  355.  
  356.  
  357. ;-------------------------------------------------------------------------------
  358. ;
  359. ;Set real mode interupt handler address.
  360. ;
  361. ;On Entry:-
  362. ;
  363. ;BL    - Interupt vector number.
  364. ;CX:DX    - selector:offset of new handler.
  365. ;
  366. ;On Exit:-
  367. ;
  368. ;CF set on error.
  369. ;
  370. RawSetRVector    proc    near
  371.     call    RAWCopyCheck
  372.     ;
  373.     pushm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  374.     mov    ax,KernalZero
  375.     mov    es,ax
  376.     movzx    ebx,bl
  377.     shl    ebx,2
  378.     pushf
  379.     cli
  380.     mov    es:[ebx],dx
  381.     mov    es:[ebx+2],cx
  382.     popf
  383.     popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  384.     ret
  385. RawSetRVector    endp
  386.  
  387.  
  388. ;-------------------------------------------------------------------------------
  389. ;
  390. ;Set protected mode exception handler address.
  391. ;
  392. ;On Entry:-
  393. ;
  394. ;BL    - Exception vector number.
  395. ;CX:EDX    - selector:offset of new handler.
  396. ;
  397. ;On Exit:-
  398. ;
  399. ;CF set on error.
  400. ;
  401. RawSetEVector    proc    near
  402.     call    RAWCopyCheck
  403.     ;
  404. ;    pushm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  405.     push    ds
  406.     push    es
  407.     push    fs
  408.     push    gs
  409.     push    ebx
  410.     push    ecx
  411.     push    edx
  412.     push    esi
  413.     push    edi
  414.     push    ebp
  415.     push    eax            ; push last so is easily accessible for changing
  416.  
  417.     mov    ax,DpmiEmuDS
  418.     mov    ds,ax
  419.     movzx    eax,bl
  420.     push    eax
  421.     mov    ebx,eax
  422.     shl    ebx,1        ;*2
  423.     mov    eax,ebx
  424.     shl    ebx,1        ;*4
  425.     add    ebx,eax        ;*6
  426.     pop    eax
  427.     add    ebx,offset ExceptionTable
  428.     ;
  429.     cmp    al,14        ;Special case for 14
  430.  
  431. ;    jnz    @@Normal
  432.     je    Special14    ; MED 01/17/96
  433.     cmp    al,20h
  434.     jc    @@Normal
  435.     stc                ; flag error
  436.     pop    eax
  437.     mov    ax,8021h    ; flag invalid value
  438.     push    eax
  439.     jmp    @@GotVect    ; don't set vector
  440.  
  441. Special14:
  442.     cmp    w[OldExcep14+4],0    ;Virtual memory active?
  443.     jz    @@Normal
  444.     ;
  445.     ;Vector 14 and VMM is still installed.
  446.     ;
  447.     mov    d[OldExcep14],edx
  448.     mov    w[OldExcep14+4],cx
  449.     jmp    @@GotVect
  450. @@Normal:    ;
  451.  
  452.     clc        ; MED 01/17/96, flag no error
  453.  
  454.     mov    [ebx],edx        ;set offset.
  455.     mov    [ebx+4],cx        ;set segment selector.
  456. @@GotVect:    ;
  457.  
  458. ;    popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
  459.     pop    eax
  460.     pop    ebp
  461.     pop    edi
  462.     pop    esi
  463.     pop    edx
  464.     pop    ecx
  465.     pop    ebx
  466.     pop    gs
  467.     pop    fs
  468.     pop    es
  469.     pop    ds
  470.  
  471.     ret
  472. RawSetEVector    endp
  473.  
  474.  
  475. ;-------------------------------------------------------------------------------
  476. ;
  477. ;Allocate a real mode call back address.
  478. ;
  479. ;On Entry:-
  480. ;
  481. ;DS:ESI    - Protected mode code.
  482. ;ES:EDI    - Real mode register structure.
  483. ;
  484. ;On Exit:-
  485. ;
  486. ;Carry set on error, else,
  487. ;
  488. ;CX:DX    - Real mode address allocated.
  489. ;
  490. RAWGetCallBack    proc near
  491.     call    RAWCopyCheck
  492.     ;
  493.     pushm    eax,ebx,esi,edi,ebp,ds,es
  494.     mov    ax,ds
  495.     push    ax
  496.     mov    ax,KernalDS
  497.     mov    ds,ax
  498.     assume ds:_cwRaw
  499.     pop    ax
  500.     ;
  501. ;;MED 02/16/96
  502.     mov    ebx,offset CallBackTable+((size CallBackStruc)*(16+3))
  503.     mov    ecx,MaxCallBacks-(16+3)
  504.     mov    edx,16+3
  505. ;    mov    ebx,offset CallBackTable+((size CallBackStruc)*(16+4))
  506. ;    mov    ecx,MaxCallBacks-(16+4)
  507. ;    mov    edx,16+4
  508.  
  509. @@0:    test    CallBackFlags[ebx],1        ;this one in use?
  510.     jz    @@1
  511.     add    ebx,size CallBackStruc
  512.     inc    edx
  513.     dec    ecx
  514.     jnz    @@0
  515.     jmp    @@9
  516.     ;
  517. @@1:    pushad
  518.     xor    eax,eax
  519.     mov    cx,1
  520.     int    31h
  521.     mov    w[CallBackStackSel+ebx],ax
  522.     popad
  523.     jc    @@9
  524.     pushad
  525.     mov    bx,w[CallBackStackSel+ebx]
  526.     mov    eax,8
  527.     xor    ecx,ecx
  528.     or    edx,-1
  529.     int    31h
  530.     popad
  531.     ;
  532.     mov    w[CallBackProt+4+ebx],ax    ;store protected mode code address.
  533.     mov    d[CallBackProt+0+ebx],esi    ;/
  534.     mov    w[CallBackRegs+4+ebx],es    ;store register table address.
  535.     mov    d[CallBackRegs+0+ebx],edi    ;/
  536.     mov    ax,CallBackSize
  537.     mul    dx
  538.     mov    esi,offset CallBackList
  539.     movzx    eax,ax
  540.     add    esi,eax        ;index list of calls.
  541.     mov    CallBackOff[ebx],si    ;store call back address.
  542.     mov    CallBackFlags[ebx],1    ;flag this entry in use.
  543.     mov    ax,_cwRaw
  544.     mov    cx,ax        ;get real mode code seg.
  545.     mov    dx,si        ;get real mode offset.
  546.     clc
  547.     jmp    @@10
  548.     ;
  549. @@9:    stc
  550. @@10:    popm    eax,ebx,esi,edi,ebp,ds,es
  551.     ret
  552.     assume ds:_cwDPMIEMU
  553. RAWGetCallBack endp
  554.  
  555.  
  556. ;-------------------------------------------------------------------------------
  557. ;
  558. ;Release a previously allocated real mode call back address.
  559. ;
  560. ;On Entry:-
  561. ;
  562. ;CX:DX    - Real mode call back address.
  563. ;
  564. RAWRelCallBack proc near
  565.     call    RAWCopyCheck
  566.     ;
  567.     pushad
  568.     pushm    ds,es,fs,gs
  569.     push    ax
  570.     mov    ax,KernalDS
  571.     mov    ds,ax
  572.     assume ds:_cwRaw
  573.     pop    ax
  574.     ;
  575.     mov    esi,offset CallBackTable
  576.     mov    ebx,MaxCallBacks
  577. @@0:    test    CallBackFlags[esi],1
  578.     jz    @@1
  579.     cmp    dx,CallBackOff[esi]
  580.     jnz    @@1
  581.     mov    CallBackFlags[esi],0
  582.     mov    bx,CallBackStackSel[esi]
  583.     mov    ax,1
  584.     int    31h
  585.     clc
  586.     jmp    @@2
  587.     ;
  588. @@1:    add    esi,size CallBackStruc
  589.     dec    ebx
  590.     jnz    @@0
  591.     stc
  592.     ;
  593. @@2:    popm    ds,es,fs,gs
  594.     popad
  595.     ret
  596.     assume ds:_cwDPMIEMU
  597. RAWRelCallBack endp
  598.  
  599.  
  600. ;-------------------------------------------------------------------------------
  601. ;
  602. ;Need to retrieve the interupt number.
  603. ;
  604. IntHandler    proc    near
  605.     pushm    ds,eax
  606.     mov    ax,DpmiEmuDS        ;make our data addresable.
  607.     mov    ds,ax        ;/
  608.     movzx    esp,sp        ;our stack never >64k.
  609.     mov    eax,[esp+(4+4)]    ;get return address.
  610.     sub    eax,offset InterruptHandler
  611.     shr    eax,3        ;convert it to an interrupt number.
  612.     mov    ExceptionIndex,eax    ;/
  613. ;
  614. ;Check if this is an exception or interrupt (any error code)
  615. ;
  616.     cmp    esp,tPL0StackSize-4-((4+4)+(4)+(4)+(4+4+4)+(4+4))
  617.     ;                            |    |   |     |      |
  618.     ; EAX:DS --------------------/    |   |     |      |
  619.     ;                                 |   |     |      |
  620.     ; Return address -----------------/   |     |      |
  621.     ;                                     |     |      |
  622.     ; Error code -------------------------/     |      |
  623.     ;                                           |      |
  624.     ; EIP:CS:Eflags ----------------------------/      |
  625.     ;                                                  |
  626.     ; ESP:SS ------------------------------------------/
  627.     ;
  628.     jnz    @@NoCode
  629.     and    w[esp+(4+4)+(4)+(4)+(4+4)],0011111111010101b
  630.  
  631. ; MED 12/02/95
  632. ; check if Exception Index is 0dh
  633. ;  if so and instruction at CS:EIP is:
  634. ;   mov eax,cr0 [0f 20 c0]  or
  635. ;   mov cr0,eax [0f 22 c0] or
  636. ;   mov    eax,cr3 [0f 20 d8] or
  637. ;   mov    cr3,eax [0f 22 d8]
  638. ;  then emulate it here and return
  639. ; MED 11/12/98, emulate RDMSR [0f 32]
  640. ; MED 04/05/99, emulate WBINVD [0f 09]
  641. ;   WRMSR [0f 30]
  642. ;   mov eax,cr4 [0f 20 e0]
  643. ;   mov cr4,eax [0f 22 e0]
  644.     push    ds
  645.     cmp    eax,0dh
  646.     jne    mednoem            ; not a GPF
  647.  
  648.     mov    ax,ss:[esp+(4+4)+(4)+(4+4)+4]    ; ax==original CS
  649. ;    verr    ax            ; check for looping lockup invalid value
  650. ;    jnz    mednoem
  651.     mov    ds,ax
  652.     mov    eax,ss:[esp+(4+4)+(4)+(4)+4]    ; eax==original EIP
  653.  
  654.     cmp    BYTE PTR ds:[eax],0fh    ; first opcode byte
  655.     jne    mednoem            ; no match
  656.     cmp    WORD PTR ds:[eax+1],0c020h    ; mov eax,cr0
  657.     jne    med2
  658.     mov    eax,cr0
  659.     mov    ss:[esp+4],eax        ; update original eax with cr0 value
  660.     jmp    medemu
  661.  
  662. med2:
  663.     cmp    WORD PTR ds:[eax+1],0c022h    ; move cr0,eax
  664.     jne    med3            ; no match
  665.     mov    eax,ss:[esp+4]    ; get original eax value
  666.     mov    cr0,eax            ; update cr0 value with original eax
  667.     jmp    medemu
  668.  
  669. med3:
  670.     cmp    WORD PTR ds:[eax+1],0d820h    ; mov eax,cr3
  671.     jne    med4
  672.     mov    eax,cr3
  673.     mov    ss:[esp+4],eax        ; update original eax with cr3 value
  674.     jmp    medemu
  675.  
  676. med4:
  677.     cmp    WORD PTR ds:[eax+1],0d822h    ; move cr3,eax
  678.     jne    med5            ; no match
  679.     mov    eax,ss:[esp+4]    ; get original eax value
  680.     mov    cr3,eax            ; update cr3 value with original eax
  681.     jmp    medemu
  682.  
  683. med5:
  684.     cmp    WORD PTR ds:[eax+1],0e022h    ; move cr4,eax
  685.     jne    med6            ; no match
  686.     mov    eax,ss:[esp+4]    ; get original eax value
  687.  
  688. .586
  689.     mov    cr4,eax            ; update cr4 value with original eax
  690.     jmp    medemu
  691.  
  692. med6:
  693.     cmp    WORD PTR ds:[eax+1],0e020h    ; mov eax,cr4
  694.     jne    med7
  695.  
  696. .586
  697.     mov    eax,cr4
  698.     mov    ss:[esp+4],eax        ; update original eax with cr4 value
  699.     jmp    medemu
  700.  
  701. med7:
  702.     cmp    BYTE PTR ds:[eax+1],9    ; WBINVD
  703.     jne    med8
  704.  
  705. .586
  706.     wbinvd
  707.     mov    eax,2
  708.     jmp    medemu2
  709.  
  710. med8:
  711.     cmp    BYTE PTR ds:[eax+1],30h    ; WRMSR
  712.     jne    med9
  713.  
  714. .586
  715.     wrmsr
  716.     mov    eax,2
  717.     jmp    medemu2
  718.  
  719. med9:
  720.     cmp    BYTE PTR ds:[eax+1],32h    ; RDMSR
  721.     jne    mednoem
  722.  
  723. ;    push    eax
  724. .586
  725.     rdmsr
  726. ;    DB    0fh                ; RDMSR instruction
  727. ;    DB    32h
  728. ;    mov    ss:[esp+8],eax    ; update original eax value
  729. ;    pop    eax
  730.     mov    ss:[esp+4],eax    ; update original eax value
  731.     mov    eax,2
  732.     jmp    medemu2
  733.  
  734. medemu:
  735.     mov    eax,3
  736.  
  737. medemu2:
  738.     add    ss:[esp+(4+4)+(4)+(4)+4],eax    ; adjust EIP past emulated instruction
  739.     pop    ds
  740.     popm    ds,eax            ; restore original ds,eax
  741.     add    esp,8                ; flush return address and error code off stack
  742.  
  743.     iretd
  744.  
  745. mednoem:
  746.     pop    ds
  747.  
  748.     mov    eax,[esp+(4+4)+(4)]    ;get error code.
  749.     mov    ExceptionCode,eax    ;/
  750.     mov    eax,[esp+(4+4)+(4)+(4)+(4+4)] ;Get flags.
  751.     or    eax,65536
  752.     mov    ExceptionFlags,eax    ;Let dispatch know its an exception.
  753.     mov    eax,cr2        ;Grab this now to save more PL
  754.     mov    ExceptionCR2,eax    ;switches for page faults.
  755.     popm    ds,eax
  756.     add    esp,4        ;skip error code.
  757.     jmp    @@SortedCode2
  758. @@NoCode:    and    w[esp+(4+4)+(4)+(4+4)],0011111111010101b
  759.     mov    eax,[esp+(4+4)+(4)+(4+4)]    ;Get flags.
  760.     and    eax,not 65536
  761.     mov    ExceptionFlags,eax
  762.     cmp ExceptionIndex,0
  763.     jz @@ForceException
  764.     cmp    ExceptionIndex,1    ;int 1
  765.     jnz    @@SortedCode
  766. @@ForceException:
  767. ;    or    ExceptionFlags,65535    ;force an exception.
  768.     or    ExceptionFlags,65536    ;force an exception.
  769.  
  770. @@SortedCode:    popm    ds,eax
  771. @@SortedCode2:    add    esp,4        ;skip return address.
  772.     ;
  773.     ;Check which stack we should switch back to.
  774.     ;
  775.     pushm    ds,eax
  776.     cmp    w[esp+(4+4)+(4+4+4)+(4)],KernalSS
  777.     jz    KernalStack        ;Already on system stack?
  778.     mov    ax,DpmiEmuDS
  779.     mov    ds,ax
  780.     test    ExceptionFlags,65536    ;exception?
  781.     jnz    KernalStack
  782.     ;
  783.     push    ebx
  784.     mov    ebx,ExceptionIndex
  785.     mov    ax,KernalDS        ;make our data addresable.
  786.     mov    ds,ax
  787.     assume ds:_cwRaw
  788.     cmp    b[ebx+Int2CallCheck],0    ;Hardware INT?
  789.     pop    ebx
  790.     assume ds:_cwDPMIEMU
  791.     jnz    KernalStack
  792.     jmp    IntStack
  793. IntHandler    endp
  794.  
  795.  
  796. ;-------------------------------------------------------------------------------
  797. ;
  798. ;It's a user stack and its not an exception or hardware interupt so switch back
  799. ;to the origional stack via a system stack to allow re-entrancy if origional
  800. ;stack needs to be fetched from disk.
  801. ;
  802. IntStack    proc    near
  803.     popm    ds,eax
  804.     ;
  805.     ;Get new stack address.
  806.     ;
  807.     pushm    eax,ebx,ds
  808.     mov    ax,KernalDS        ;make our data addresable.
  809.     mov    ds,ax
  810.     assume ds:_cwRaw
  811.     mov    ebx,RawStackPos    ;get next stack address.
  812.     sub    RawStackPos,RawStackDif
  813.     mov    ax,KernalSS
  814.     mov    ds,ax
  815.     assume ds:nothing
  816.     ;
  817.     ;Put old details onto new stack.
  818.     ;
  819.     test    cs:DpmiEmuSystemFlags,1
  820.     jz    @@iUse32
  821.     mov    eax,[esp+(4+4+4)+(4+4+4+4)]
  822.     sub    ebx,2
  823.     mov    [ebx],ax        ;SS
  824.     mov    eax,[esp+(4+4+4)+(4+4+4)]
  825.     sub    ebx,2
  826.     mov    [ebx],ax        ;ESP
  827.     mov    eax,[esp+(4+4+4)+(4+4)]
  828.     sub    ebx,2
  829.     mov    [ebx],ax        ;EFlags
  830.     mov    eax,[esp+(4+4+4)+(4)]
  831.     sub    ebx,2
  832.     mov    [ebx],ax        ;CS
  833.     mov    eax,[esp+(4+4+4)+(0)]
  834.     sub    ebx,2
  835.     mov    [ebx],ax        ;EIP
  836.     jmp    @@iUse0
  837.     ;
  838. @@iUse32:    mov    eax,[esp+(4+4+4)+(4+4+4+4)]
  839.     sub    ebx,4
  840.     mov    [ebx],eax        ;SS
  841.     mov    eax,[esp+(4+4+4)+(4+4+4)]
  842.     sub    ebx,4
  843.     mov    [ebx],eax        ;ESP
  844.     mov    eax,[esp+(4+4+4)+(4+4)]
  845.     sub    ebx,4
  846.     mov    [ebx],eax        ;EFlags
  847.     mov    eax,[esp+(4+4+4)+(4)]
  848.     sub    ebx,4
  849.     mov    [ebx],eax        ;CS
  850.     mov    eax,[esp+(4+4+4)+(0)]
  851.     sub    ebx,4
  852.     mov    [ebx],eax        ;EIP
  853.     ;
  854. @@iUse0:    ;Put new details into current stack.
  855.     ;
  856.     mov    eax,offset @@Int
  857.     mov    [esp+(4+4+4)+(0)],eax    ;EIP
  858.     xor    eax,eax
  859.     mov    ax,DpmiEmuCS
  860.     mov    [esp+(4+4+4)+(4)],eax    ;CS
  861.     pushfd
  862.     pop    eax
  863.     mov    [esp+(4+4+4)+(4+4)],eax    ;EFlags
  864.     mov    [esp+(4+4+4)+(4+4+4)],ebx    ;ESP
  865.     xor    eax,eax
  866.     mov    ax,KernalSS
  867.     mov    [esp+(4+4+4)+(4+4+4+4)],eax ;SS
  868.     popm    eax,ebx,ds
  869.     assume ds:_cwDPMIEMU
  870.     iretd
  871.     ;
  872. @@Int:    ;Now switch back to origional stack.
  873.     ;
  874.     assume ds:nothing
  875.     push    cs:ExceptionIndex    ;need to know the INT number.
  876.     pushm    eax,ebx,esi,ds
  877.     test    cs:DpmiEmuSystemFlags,1
  878.     jz    @@i2Use32
  879.     xor    ebx,ebx
  880.     mov    ax,ss
  881.     mov    ds,ax
  882.     mov    bx,sp
  883.     lss    sp,[ebx+(4+4+4+4+4)+(2+2+2)] ;get origional stack again.
  884.     mov    ax,[ebx+(4+4+4+4+4)+(2+2)] ;get flags.
  885.     push    ax
  886.     mov    ax,[ebx+(4+4+4+4+4)+(2)]    ;get CS
  887.     push    ax
  888.     mov    ax,[ebx+(4+4+4+4+4)+(0)]    ;get IP
  889.     push    ax
  890.     xor    eax,eax
  891.     mov    ax,[ebx+(4+4+4+4+4)+(2+2)] ;get flags again.
  892.     and    ax,1111110011111111b    ;lose IF & TF
  893.     push    eax        ;int handler flags.
  894.     jmp    @@i2Use0
  895.     ;
  896. @@i2Use32:    mov    ax,ss
  897.     mov    ds,ax
  898.     mov    ebx,esp
  899.     lss    esp,[ebx+(4+4+4+4+4)+(4+4+4)] ;get origional stack again.
  900.     mov    eax,[ebx+(4+4+4+4+4)+(4+4)] ;get flags.
  901.     push    eax
  902.     mov    eax,[ebx+(4+4+4+4+4)+(4)]    ;get CS
  903.     push    eax
  904.     mov    eax,[ebx+(4+4+4+4+4)+(0)]    ;get IP
  905.     push    eax
  906.     mov    eax,[ebx+(4+4+4+4+4)+(4+4)] ;get flags again.
  907.     and    ax,1111110011111111b    ;lose IF & TF
  908.     push    eax        ;int handler flags.
  909.     ;
  910. @@i2Use0:    mov    eax,[ebx+(4+4+4+4)]    ;get INT index.
  911.     shl    eax,1
  912.     mov    esi,eax
  913.     shl    eax,1
  914.     add    esi,eax        ;*6 for index into table.
  915.     add    esi,offset InterruptTable
  916.     xor    eax,eax
  917.     mov    ax,cs:[esi+4]    ;get int handler CS
  918.     push    eax
  919.     mov    eax,cs:[esi]        ;get INT handler EIP.
  920.     push    eax
  921.     mov    eax,[ebx+(4+4+4)]    ;EAX
  922.     push    eax
  923.     mov    eax,[ebx+(4+4)]    ;EBX
  924.     push    eax
  925.     mov    eax,[ebx+(4)]    ;ESI
  926.     push    eax
  927.     mov    eax,[ebx+(0)]    ;DS
  928.     push    eax
  929.     mov    ax,KernalDS
  930.     mov    ds,ax
  931.     assume ds:_cwRaw
  932.     add    RawStackPos,RawStackDif
  933.     assume ds:_cwDPMIEMU
  934.     popm    eax,ebx,esi,ds
  935.     iretd            ;pass control to INT handler.
  936. IntStack    endp
  937.  
  938.  
  939. ;-------------------------------------------------------------------------------
  940. ;
  941. ;Either we were already on the system stack or we have an exception or hardware
  942. ;interupt on our hands. Either way we need to switch to another piece of the
  943. ;system stack to make sure we're using a legitimate one.
  944. ;
  945. KernalStack    proc    near
  946.     popm    ds,eax
  947.     ;
  948.     ;Get new stack address.
  949.     ;
  950.     pushm    eax,ebx,ds
  951.     mov    ax,KernalDS        ;make our data addresable.
  952.     mov    ds,ax
  953.     assume ds:_cwRaw
  954.     mov    ebx,RawStackPos    ;get next stack address.
  955.     sub    RawStackPos,RawStackDif
  956.     mov    ax,KernalSS
  957.     mov    ds,ax
  958.     assume ds:nothing
  959.     ;
  960. @@Update:    ;Put old details onto new stack.
  961.     ;
  962.     test    cs:DpmiEmuSystemFlags,1
  963.     jz    @@Use32
  964.     mov    eax,[esp+(4+4+4)+(4+4+4+4)]
  965.     sub    ebx,2
  966.     mov    [ebx],ax        ;SS
  967.     mov    eax,[esp+(4+4+4)+(4+4+4)]
  968.     sub    ebx,2
  969.     mov    [ebx],ax        ;ESP
  970.     mov    eax,[esp+(4+4+4)+(4+4)]
  971.     sub    ebx,2
  972.     mov    [ebx],ax        ;EFlags
  973.     mov    eax,[esp+(4+4+4)+(4)]
  974.     sub    ebx,2
  975.     mov    [ebx],ax        ;CS
  976.     mov    eax,[esp+(4+4+4)+(0)]
  977.     sub    ebx,2
  978.     mov    [ebx],ax        ;EIP
  979.     jmp    @@Use0
  980.     ;
  981. @@Use32:    mov    eax,[esp+(4+4+4)+(4+4+4+4)]
  982.     sub    ebx,4
  983.     mov    [ebx],eax        ;SS
  984.     mov    eax,[esp+(4+4+4)+(4+4+4)]
  985.     sub    ebx,4
  986.     mov    [ebx],eax        ;ESP
  987.     mov    eax,[esp+(4+4+4)+(4+4)]
  988.     sub    ebx,4
  989.     mov    [ebx],eax        ;EFlags
  990.     mov    eax,[esp+(4+4+4)+(4)]
  991.     sub    ebx,4
  992.     mov    [ebx],eax        ;CS
  993.     mov    eax,[esp+(4+4+4)+(0)]
  994.     sub    ebx,4
  995.     mov    [ebx],eax        ;EIP
  996.     ;
  997. @@Use0:    ;Put new details into current stack.
  998.     ;
  999.     mov    eax,offset IntDispatch
  1000.     mov    [esp+(4+4+4)+(0)],eax    ;EIP
  1001.     xor    eax,eax
  1002.     mov    ax,DpmiEmuCS
  1003.     mov    [esp+(4+4+4)+(4)],eax    ;CS
  1004.     pushfd
  1005.     pop    eax
  1006.     mov    [esp+(4+4+4)+(4+4)],eax    ;EFlags
  1007.     mov    [esp+(4+4+4)+(4+4+4)],ebx    ;ESP
  1008.     xor    eax,eax
  1009.     mov    ax,KernalSS
  1010.     mov    [esp+(4+4+4)+(4+4+4+4)],eax ;SS
  1011.     popm    eax,ebx,ds
  1012.     assume ds:_cwDPMIEMU
  1013.     ;
  1014.     ;Pass control to interupt dispatcher.
  1015.     ;
  1016.     iretd
  1017. KernalStack    endp
  1018.  
  1019.  
  1020. ;-------------------------------------------------------------------------------
  1021. ;
  1022. ;Direct control to exception or interupt handler.
  1023. ;
  1024. IntDispatch    proc    near
  1025.     pushm    eax,esi,edi,ds
  1026.     mov    ax,DpmiEmuDS
  1027.     mov    ds,ax
  1028.     and    w[ExceptionFlags],1111110011111111b
  1029.     mov    esi,ExceptionIndex    ;Get the exception number.
  1030.     add    esi,esi        ;*2
  1031.     mov    eax,esi
  1032.     add    esi,esi        ;*4
  1033.     add    esi,eax        ;*6
  1034.     test    ExceptionFlags,65536
  1035.     jnz    @@Excep
  1036.     ;
  1037.     ;Dispatch normal interrupt.
  1038.     ;
  1039.     add    esi,offset InterruptTable
  1040.     test    DpmiEmuSystemFlags,1
  1041.     jz    @@Use32Bit14
  1042.     mov    eax,[esi]
  1043.     mov    d[@@Call2],eax
  1044.     mov    ax,[esi+4]
  1045.     mov    w[@@Call2+4],ax
  1046.     mov    eax,offset @@Resume
  1047.     mov    w[@@Call20],ax
  1048.     mov    w[@@Call20+2],cs
  1049.     popm    eax,esi,edi,ds
  1050.     assume ds:nothing
  1051.     push    cs:w[ExceptionFlags]    ;EFlags before entry.
  1052.     push    cs:w[@@Call20+2]    ;CS
  1053.     push    cs:w[@@Call20]    ;EIP
  1054.     jmp    cs:f[@@Call2]
  1055.     assume ds:_cwDPMIEMU
  1056.     ;
  1057. @@Use32Bit14:    mov    eax,[esi]
  1058.     mov    d[@@Call2],eax
  1059.     mov    ax,[esi+4]
  1060.     mov    w[@@Call2+4],ax
  1061.     mov    d[@@Call20],offset @@Resume
  1062.     mov    w[@@Call20+4],cs
  1063.     popm    eax,esi,edi,ds
  1064.     assume ds:nothing
  1065.     push    cs:d[ExceptionFlags]    ;EFlags before entry.
  1066.     push    cs:d[@@Call20+4]    ;CS
  1067.     push    cs:d[@@Call20]    ;EIP
  1068.     jmp    cs:f[@@Call2]
  1069.     assume ds:_cwDPMIEMU
  1070.     ;
  1071.  
  1072. ;; MED 08/13/96
  1073. ;    nop        ; make debugger EIP adjustment from debug int benign?
  1074.  
  1075. @@Resume:    ;Return from normal int.
  1076.     ;
  1077.     pushfd
  1078.     cli            ;stop interupts interfering.
  1079.     pushm    eax,ebx,ds
  1080.     mov    ax,ss
  1081.     mov    ds,ax
  1082.     mov    ebx,esp
  1083.     assume ds:nothing
  1084.     test    cs:DpmiEmuSystemFlags,1
  1085.     assume ds:_cwDPMIEMU
  1086.     jz    @@Use32
  1087.     ;
  1088.     movzx    ebx,bx
  1089.     lss    sp,d[ebx+(4+4+4+4)+(2+2+2)] ;get old stack address.
  1090.     and    w[ebx+(4+4+4+4)+(2+2)],0000011100000000b ;retain IF & TF.
  1091.     and    w[ebx+(4+4+4)],1111100011111111b     ;lose IF & TF.
  1092.     mov    ax,[ebx+(4+4+4)]
  1093.     or    ax,[ebx+(4+4+4+4)+(2+2)]
  1094.     push    ax        ;EFlags.
  1095.     mov    ax,[ebx+(4+4+4+4)+(2)]
  1096.     push    ax        ;CS
  1097.     mov    ax,[ebx+(4+4+4+4)+(0)]
  1098.     push    ax        ;EIP
  1099.     mov    eax,[ebx+(4+4)]
  1100.     push    eax        ;EAX
  1101.     mov    eax,[ebx+(4)]
  1102.     push    eax        ;EBX
  1103.     mov    eax,[ebx+(0)]
  1104.     push    eax        ;DS
  1105.     mov    ax,KernalDS
  1106.     mov    ds,ax
  1107.     assume ds:_cwRaw
  1108.     add    RawStackPos,RawStackDif    ;update next stack.
  1109.     assume ds:_cwDPMIEMU
  1110.     popm    eax,ebx,ds
  1111.     db 66h
  1112.     iret
  1113.     ;
  1114. @@Use32:    lss    esp,f[ebx+(4+4+4+4)+(4+4+4)] ;get old stack address.
  1115.     and    w[ebx+(4+4+4+4)+(4+4)],0000011100000000b ;retain IF & TF.
  1116.     and    w[ebx+(4+4+4)],1111100011111111b     ;lose IF & TF.
  1117.     mov    eax,[ebx+(4+4+4)]
  1118.     or    eax,[ebx+(4+4+4+4)+(4+4)]
  1119.     push    eax        ;EFlags.
  1120.     mov    eax,[ebx+(4+4+4+4)+(4)]
  1121.     push    eax        ;CS
  1122.     mov    eax,[ebx+(4+4+4+4)+(0)]
  1123.     push    eax        ;EIP
  1124.     mov    eax,[ebx+(4+4)]
  1125.     push    eax        ;EAX
  1126.     mov    eax,[ebx+(4)]
  1127.     push    eax        ;EBX
  1128.     mov    eax,[ebx+(0)]
  1129.     push    eax        ;DS
  1130.     mov    ax,KernalDS
  1131.     mov    ds,ax
  1132.     assume ds:_cwRaw
  1133.     add    RawStackPos,RawStackDif    ;update next stack.
  1134.     assume ds:_cwDPMIEMU
  1135.     popm    eax,ebx,ds
  1136.     iretd
  1137.  
  1138.     ;
  1139. @@Excep:    ;Dispatch exception.
  1140.     ;
  1141.     add    esi,offset ExceptionTable
  1142.     test    DpmiEmuSystemFlags,1
  1143.     jz    @@eUse32Bit14
  1144.     mov    eax,[esi]
  1145.     mov    d[@@Call2],eax
  1146.     mov    ax,[esi+4]
  1147.     mov    w[@@Call2+4],ax
  1148.     mov    eax,offset @@ResumeExp
  1149.     mov    w[@@Call20],ax
  1150.     mov    w[@@Call20+2],cs
  1151.     popm    eax,esi,edi,ds
  1152.     assume ds:nothing
  1153.     push    cs:w[ExceptionCode]    ;EFlags before entry.
  1154.     push    cs:w[@@Call20+2]    ;CS
  1155.     push    cs:w[@@Call20]    ;EIP
  1156.     jmp    cs:f[@@Call2]
  1157.     assume ds:_cwDPMIEMU
  1158.     ;
  1159. @@eUse32Bit14:    mov    eax,[esi]
  1160.     mov    d[@@Call2],eax
  1161.     mov    ax,[esi+4]
  1162.     mov    w[@@Call2+4],ax
  1163.     mov    d[@@Call20],offset @@ResumeExp
  1164.     mov    w[@@Call20+4],cs
  1165.     popm    eax,esi,edi,ds
  1166.     assume ds:nothing
  1167.     push    cs:d[ExceptionCode]    ;EFlags before entry.
  1168.     push    cs:d[@@Call20+4]    ;CS
  1169.     push    cs:d[@@Call20]    ;EIP
  1170.     jmp    cs:f[@@Call2]
  1171.     assume ds:_cwDPMIEMU
  1172.     ;
  1173. @@ResumeExp:    ;Return from exception.
  1174.     ;
  1175.     cli
  1176.     assume ds:nothing
  1177.     test    cs:DpmiEmuSystemFlags,1
  1178.     assume ds:_cwDPMIEMU
  1179.     jz    @@ExpUse32
  1180.     ;
  1181.     add    sp,2
  1182.     pushfd
  1183.     pushm    eax,ebx,ds
  1184.     mov    ax,ss
  1185.     mov    ds,ax
  1186.     mov    ebx,esp
  1187.     movzx    ebx,bx
  1188.     lss    sp,d[ebx+(4+4+4+4)+(2+2+2)] ;get old stack address.
  1189.     mov    ax,[ebx+(4+4+4+4)+(2+2)]
  1190.     push    ax        ;EFlags.
  1191.     mov    ax,[ebx+(4+4+4+4)+(2)]
  1192.     push    ax        ;CS
  1193.     mov    ax,[ebx+(4+4+4+4)+(0)]
  1194.     push    ax        ;EIP
  1195.     mov    eax,[ebx+(4+4)]
  1196.     push    eax        ;EAX
  1197.     mov    eax,[ebx+(4)]
  1198.     push    eax        ;EBX
  1199.     mov    eax,[ebx+(0)]
  1200.     push    eax        ;DS
  1201.     mov    ax,KernalDS
  1202.     mov    ds,ax
  1203.     assume ds:_cwRaw
  1204.     add    RawStackPos,RawStackDif    ;update next stack.
  1205.     assume ds:_cwDPMIEMU
  1206.     popm    eax,ebx,ds
  1207.     db 66h
  1208.     iret
  1209.     ;
  1210. @@ExpUse32:    add    esp,4
  1211.     pushfd
  1212.     pushm    eax,ebx,ds
  1213.     mov    ax,ss
  1214.     mov    ds,ax
  1215.     mov    ebx,esp
  1216.     lss    esp,f[ebx+(4+4+4+4)+(4+4+4)] ;get old stack address.
  1217.     mov    eax,[ebx+(4+4+4+4)+(4+4)]
  1218.     push    eax        ;EFlags.
  1219.     mov    eax,[ebx+(4+4+4+4)+(4)]
  1220.     push    eax        ;CS
  1221.     mov    eax,[ebx+(4+4+4+4)+(0)]
  1222.     push    eax        ;EIP
  1223.     mov    eax,[ebx+(4+4)]
  1224.     push    eax        ;EAX
  1225.     mov    eax,[ebx+(4)]
  1226.     push    eax        ;EBX
  1227.     mov    eax,[ebx+(0)]
  1228.     push    eax        ;DS
  1229.     mov    ax,KernalDS
  1230.     mov    ds,ax
  1231.     assume ds:_cwRaw
  1232.     add    RawStackPos,RawStackDif    ;update next stack.
  1233.     assume ds:_cwDPMIEMU
  1234.     popm    eax,ebx,ds
  1235.     iretd
  1236.     ;
  1237. @@Call2    df 0,0
  1238. @@Call20    df 0,0
  1239. IntDispatch    endp
  1240.  
  1241.  
  1242. ;-------------------------------------------------------------------------------
  1243. ;
  1244. ;Handle an INT nn instruction by retrieving registers from the stack and
  1245. ;reflect to real mode.
  1246. ;
  1247. IntNN386    proc    far
  1248.     sub    esp,4+4
  1249.     pushm    ds,es,fs,gs
  1250.     sub    esp,10*2
  1251.     pushad
  1252.     ;
  1253.     mov    ax,DpmiEmuDS        ;make our data addresable.
  1254.     mov    ds,ax        ;/
  1255.     mov    ebp,esp
  1256.     test    DpmiEmuSystemFlags,1
  1257.     jz    @@Use32Bit19
  1258.     movzx    ebp,bp
  1259.     movzx    eax,w[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)]
  1260.     jmp    @@Use16Bit19
  1261. @@Use32Bit19:    mov    eax,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)]
  1262. @@Use16Bit19:    mov    [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)],eax
  1263.     mov    edx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4)]
  1264.     sub    edx,offset IntNN386Catch
  1265.     shr    edx,3
  1266.     mov    d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],0
  1267.     ;
  1268.     mov    edi,ebp
  1269.     push    ss
  1270.     pop    es
  1271.     ;
  1272.     ;If this is a "hardware" interrupt we should mark it as
  1273.     ;busy if it isn't already marked.
  1274.     ;
  1275.     mov    ebx,edx
  1276.     push    ds
  1277.     mov    ax,KernalDS
  1278.     mov    ds,ax
  1279.     assume ds:_cwRaw
  1280.     mov    al,[ebx+Int2CallCheck]
  1281.     or    al,al        ;Hardware?
  1282.     jz    @@c2
  1283.     sub    bl,al
  1284.     shl    ebx,3        ;*8
  1285.     mov    eax,ebx
  1286.     shl    ebx,1        ;*16
  1287.     add    ebx,eax        ;*24
  1288.     add    ebx,offset CallBackTable
  1289.     test    CallBackFlags[ebx],1
  1290.     jz    @@c2
  1291.     test    CallBackFlags[ebx],128    ;already busy?
  1292.     jnz    @@c2
  1293.     or    CallBackFlags[ebx],128    ;mark it as busy.
  1294.     mov    d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],ebx
  1295.     assume ds:_cwDPMIEMU
  1296. @@c2:    pop    ds
  1297.     ;
  1298.     ;Now pass control to the INT simulator.
  1299.     ;
  1300.     mov    eax,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)]
  1301.     and    eax,1111100011111111b
  1302.     push    eax
  1303.     popfd
  1304.     mov    ebx,edx
  1305.     mov    es:Real_SP[edi],0
  1306.     mov    es:Real_SS[edi],0
  1307.     call    EmuRAWSimulateINT
  1308.     ;
  1309.     cmp    d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],0
  1310.     jz    @@NoCall
  1311.     push    ds
  1312.     mov    esi,d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)]
  1313.     mov    ax,KernalDS
  1314.     mov    ds,ax
  1315.     assume ds:_cwRaw
  1316.     and    CallBackFlags[esi],255-128
  1317.     assume ds:_cwDPMIEMU
  1318.     pop    ds
  1319. @@NoCall:    ;
  1320.     ;Update the flags.
  1321.     ;
  1322.     mov    ax,es:Real_Flags[edi]
  1323.     and    ax,1000100011111111b        ;lose IF.
  1324.     ;
  1325.     test    DpmiEmuSystemFlags,1
  1326.     jz    @@Use32Bit
  1327.     mov    bx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)]
  1328.     and    bx,0111011100000000b        ;retain IF.
  1329.     or    ax,bx
  1330.     mov    [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)],ax
  1331.     popad
  1332.     add    sp,10*2
  1333.     popm    ds,es,fs,gs
  1334.     add    sp,4+4+4
  1335.     db 66h
  1336.     iret            ;Switch back to calling program.
  1337.     ;
  1338. @@Use32Bit:    mov    bx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)]
  1339.     and    bx,0111011100000000b        ;retain IF.
  1340.     or    ax,bx
  1341.     mov    [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)],ax
  1342.     popad
  1343.     add    esp,10*2
  1344.     popm    ds,es,fs,gs
  1345.     add    esp,4+4+4
  1346.     iretd            ;Switch back to calling program.
  1347. IntNN386    endp
  1348.  
  1349.  
  1350. ;-------------------------------------------------------------------------------
  1351. ;
  1352. ;An unhandled low level exception has occured so terminate the program.
  1353. ;
  1354. ExcepNN386    proc    far
  1355.     pushm    eax,ds
  1356.     mov    ax,DpmiEmuDS
  1357.     mov    ds,ax
  1358.     mov    eax,[esp+(4+4)]
  1359.     sub    eax,offset ExcepNN386Catch
  1360.     shr    eax,3
  1361.     mov    ExceptionIndex,eax
  1362.     popm    eax,ds
  1363.     add    esp,4        ;skip return address
  1364.     ;
  1365.     pushm    ds,es,fs,gs
  1366.     pushm    eax,ebx,ecx,edx,esi,edi,ebp        ;save general registers.
  1367.     mov    ax,DpmiEmuDS        ;make our data addresable.
  1368.     mov    ds,ax        ;/
  1369.     test    DpmiEmuSystemFlags,1
  1370.     jz    @@Use32Bit16
  1371.     movzx    eax,w[esp+(4+4+4+4)+(4+4+4+4+4+4+4)+(2+2)]
  1372.     mov    ExceptionEFL,eax
  1373.     jmp    @@Use16Bit16
  1374. @@Use32Bit16:    mov    eax,[esp+(4+4+4+4)+(4+4+4+4+4+4+4)+(4+4)]
  1375.     mov    ExceptionEFL,eax
  1376.     ;
  1377. @@Use16Bit16:    ;Retrieve register values and get outa here.
  1378.     ;
  1379.     mov    ax,DpmiEmuDS        ;make sure our data is addresable.
  1380.     mov    es,ax        ;/
  1381.     assume es:_cwDPMIEMU
  1382.     mov    ax,ss
  1383.     mov    ds,ax
  1384.     assume ds:nothing
  1385.     mov    esi,esp
  1386.     mov    edi,offset ExceptionEBP
  1387.     mov    ecx,(4+4+4+4+4+4+4)+(4+4+4+4)
  1388.     cld
  1389.     db 67h
  1390.     rep    movsb        ;copy registers off the stack.
  1391.     ;
  1392.     test    cs:DpmiEmuSystemFlags,1
  1393.     jz    @@Use32Bit17
  1394.     add    esi,2+2+2        ;skip return address/flags.
  1395.     db 67h
  1396.     movsw
  1397.     add    edi,2
  1398.     db 67h
  1399.     movsw
  1400.     add    edi,2
  1401.     db 67h
  1402.     movsw
  1403.     add    edi,2
  1404.     jmp    @@Use16Bit17
  1405. @@Use32Bit17:    add    esi,4+4+4        ;skip return address/flags.
  1406.     mov    ecx,4+4+4
  1407.     cld
  1408.     db 67h
  1409.     rep    movsb        ;get real return address.
  1410. @@Use16Bit17:    ;
  1411.     test    cs:DpmiEmuSystemFlags,1
  1412.     jz    @@Use32Bit678
  1413.     movzx    eax,w[esi]
  1414.     mov    es:ExceptionESP,eax
  1415.     mov    ax,[esi+2]
  1416.     mov    es:ExceptionSS,ax
  1417.     jmp    @@Use16Bit678
  1418.     ;
  1419. @@Use32Bit678:    mov    eax,[esi]
  1420.     mov    es:ExceptionESP,eax
  1421.     mov    ax,[esi+4]
  1422.     mov    es:ExceptionSS,ax
  1423. @@Use16Bit678:    ;
  1424.     push    es
  1425.     pop    ds
  1426.     assume es:nothing
  1427.     assume ds:_cwDPMIEMU
  1428. ;
  1429. ;Now switch to PL0 to get CR0-3 values.
  1430. ;
  1431.     call    EmuRawPL32PL0
  1432.     str    ax        ;get TR
  1433.     mov    ExceptionTR,ax
  1434.     mov    eax,cr0
  1435.     mov    ExceptionCR0,eax
  1436.     mov    eax,cr2
  1437.     mov    ExceptionCR2,eax
  1438.     mov    eax,cr3
  1439.     mov    ExceptionCR3,eax
  1440.     mov    cx,MainSS
  1441.     mov    edx,offset _cwStackEnd-256
  1442.     call    EmuRawPL02PL3
  1443. ;
  1444. ;Convert register values into ASCII ready for printing.
  1445. ;
  1446.     mov    eax,ExceptionIndex
  1447.     mov    ecx,2
  1448.     mov    edi,offset ExceptionINum
  1449.     call    Bin2HexE
  1450.     mov    eax,ExceptionCode    ;high word undefined upto 486.
  1451.     mov    ecx,4
  1452.     mov    edi,offset ExceptionENum
  1453.     call    Bin2HexE
  1454.     ;
  1455.     movzx    eax,ExceptionTR
  1456.     mov    ecx,4
  1457.     mov    edi,offset ExceptionTRt
  1458.     call    Bin2HexE
  1459.     mov    eax,ExceptionCR0
  1460.     mov    ecx,8
  1461.     mov    edi,offset ExceptionCR0t
  1462.     call    Bin2HexE
  1463.     mov    eax,ExceptionCR2
  1464.     mov    ecx,8
  1465.     mov    edi,offset ExceptionCR2t
  1466.     call    Bin2HexE
  1467.     mov    eax,ExceptionCR3
  1468.     mov    ecx,8
  1469.     mov    edi,offset ExceptionCR3t
  1470.     call    Bin2HexE
  1471.     ;
  1472.     mov    eax,ExceptionEAX
  1473.     mov    ecx,8
  1474.     mov    edi,offset ExceptionEAXt
  1475.     call    Bin2HexE
  1476.     mov    eax,ExceptionEBX
  1477.     mov    ecx,8
  1478.     mov    edi,offset ExceptionEBXt
  1479.     call    Bin2HexE
  1480.     mov    eax,ExceptionECX
  1481.     mov    ecx,8
  1482.     mov    edi,offset ExceptionECXt
  1483.     call    Bin2HexE
  1484.     mov    eax,ExceptionEDX
  1485.     mov    ecx,8
  1486.     mov    edi,offset ExceptionEDXt
  1487.     call    Bin2HexE
  1488.     mov    eax,ExceptionESI
  1489.     mov    ecx,8
  1490.     mov    edi,offset ExceptionESIt
  1491.     call    Bin2HexE
  1492.     mov    eax,ExceptionEDI
  1493.     mov    ecx,8
  1494.     mov    edi,offset ExceptionEDIt
  1495.     call    Bin2HexE
  1496.     mov    eax,ExceptionEBP
  1497.     mov    ecx,8
  1498.     mov    edi,offset ExceptionEBPt
  1499.     call    Bin2HexE
  1500.     mov    eax,ExceptionESP
  1501.     mov    ecx,8
  1502.     mov    edi,offset ExceptionESPt
  1503.     call    Bin2HexE
  1504.     mov    eax,ExceptionEIP
  1505.     mov    ecx,8
  1506.     mov    edi,offset ExceptionEIPt
  1507.     call    Bin2HexE
  1508.     mov    eax,ExceptionEFL
  1509.     mov    ecx,8
  1510.     mov    edi,offset ExceptionEFLt
  1511.     call    Bin2HexE
  1512.     ;
  1513.     movzx    eax,ExceptionCS
  1514.     mov    ecx,4
  1515.     mov    edi,offset ExceptionCSt
  1516.     call    Bin2HexE
  1517.     movzx    eax,ExceptionDS
  1518.     mov    ecx,4
  1519.     mov    edi,offset ExceptionDSt
  1520.     call    Bin2HexE
  1521.     movzx    eax,ExceptionES
  1522.     mov    ecx,4
  1523.     mov    edi,offset ExceptionESt
  1524.     call    Bin2HexE
  1525.     movzx    eax,ExceptionFS
  1526.     mov    ecx,4
  1527.     mov    edi,offset ExceptionFSt
  1528.     call    Bin2HexE
  1529.     movzx    eax,ExceptionGS
  1530.     mov    ecx,4
  1531.     mov    edi,offset ExceptionGSt
  1532.     call    Bin2HexE
  1533.     movzx    eax,ExceptionSS
  1534.     mov    ecx,4
  1535.     mov    edi,offset ExceptionSSt
  1536.     call    Bin2HexE
  1537.     mov    edi,offset ExceptionSysFlags
  1538.     mov    eax,DpmiEmuSystemFlags
  1539.     mov    ecx,8
  1540.     call    Bin2HexE
  1541. ;
  1542. ;Copy register details into the transfer buffer.
  1543. ;
  1544.     push    ds
  1545.     mov    ax,MainDS
  1546.     mov    ds,ax
  1547.     assume ds:_cwMain
  1548.     movzx    edi,TransferReal
  1549.     assume ds:_cwDPMIEMU
  1550.     pop    ds
  1551.     shl    edi,4
  1552.     mov    esi,offset ExceptionHeader
  1553.     mov    ecx,offset ExceptionHeaderEnd-ExceptionHeader
  1554.     mov    ax,KernalZero
  1555.     mov    es,ax
  1556.     rep    movsb
  1557.     push    ds
  1558.     pop    es
  1559. ;
  1560. ;Print the message.
  1561. ;
  1562.     push    ds
  1563.     mov    ax,MainDS
  1564.     mov    ds,ax
  1565.     assume ds:_cwMain
  1566.     mov    ax,TransferReal
  1567.     assume ds:_cwDPMIEMU
  1568.     pop    ds
  1569.     mov    edi,offset ExceptionIntBuffer
  1570.     mov    Real_DS[edi],ax
  1571.     mov    Real_EDX[edi],0
  1572.     mov    Real_EAX[edi],0900h
  1573.     mov    Real_SP[edi],0
  1574.     mov    Real_SS[edi],0
  1575.     mov    bl,21h
  1576.     call    EmuRawSimulateINT
  1577. ;
  1578. ;Now switch back to exit code.
  1579. ;
  1580.     mov    ax,InitDS
  1581.     mov    ds,ax
  1582.     assume ds:_cwInit
  1583.     mov    IErrorNumber,0
  1584.     mov    ax,InitCS
  1585.     push    ax
  1586.     mov    ax,offset InitError
  1587.     push    ax
  1588.     db 66h
  1589.     retf
  1590.     assume ds:_cwDPMIEMU
  1591. ExcepNN386    endp
  1592.  
  1593. ;
  1594. DpmiEmuSystemFlags dd 0
  1595. ;
  1596. ; do NOT change order of these variables (you can add at the end), MED 01/08/96
  1597. ExceptionCode    dd 0
  1598. ExceptionFlags    dd 0
  1599. ExceptionIndex dd 0
  1600. ;
  1601. ExceptionEBP    dd ?
  1602. ExceptionEDI    dd ?
  1603. ExceptionESI    dd ?
  1604. ExceptionEDX    dd ?
  1605. ExceptionECX    dd ?
  1606. ExceptionEBX    dd ?
  1607. ExceptionEAX    dd ?
  1608. ExceptionGS    dw ?,?
  1609. ExceptionFS    dw ?,?
  1610. ExceptionES    dw ?,?
  1611. ExceptionDS    dw ?,?
  1612. ExceptionEIP    dd ?
  1613. ExceptionCS    dw ?,?
  1614. ExceptionEFL    dd ?
  1615. ExceptionESP    dd ?
  1616. ExceptionSS    dw ?,?
  1617. ExceptionTR    dw ?
  1618. ExceptionCR0    dd ?
  1619. ExceptionCR2    dd ?
  1620. ExceptionCR3    dd ?
  1621. ;
  1622. ExceptionHeader label byte
  1623.     db 13,10,"CauseWay Error 09 : Unrecoverable internal exception, program terminated.",13,10
  1624.     db 13,10,'Exception: '
  1625. ExceptionINum    db '00, Error code: '
  1626. ExceptionENum    db '0000',13,10,13,10
  1627.     db 'EAX='
  1628. ExceptionEAXt    db '00000000 '
  1629.     db 'EBX='
  1630. ExceptionEBXt    db '00000000 '
  1631.     db 'ECX='
  1632. ExceptionECXt    db '00000000 '
  1633.     db 'EDX='
  1634. ExceptionEDXt    db '00000000 '
  1635.     db 'ESI='
  1636. ExceptionESIt    db '00000000 '
  1637.     db 13,10
  1638.     db 'EDI='
  1639. ExceptionEDIt    db '00000000 '
  1640.     db 'EBP='
  1641. ExceptionEBPt    db '00000000 '
  1642.     db 'ESP='
  1643. ExceptionESPt    db '00000000 '
  1644.     db 'EIP='
  1645. ExceptionEIPt    db '00000000 '
  1646.     db 'EFL='
  1647. ExceptionEFLt    db '00000000 '
  1648.     db 13,10,13,10
  1649.     db 'CS='
  1650. ExceptionCSt    db '0000 '
  1651.     db 'DS='
  1652. ExceptionDSt    db '0000 '
  1653.     db 'ES='
  1654. ExceptionESt    db '0000 '
  1655.     db 'FS='
  1656. ExceptionFSt    db '0000 '
  1657.     db 'GS='
  1658. ExceptionGSt    db '0000 '
  1659.     db 'SS='
  1660. ExceptionSSt    db '0000 '
  1661.     db 13,10,13,10
  1662.     db 'CR0='
  1663. ExceptionCR0t    db '00000000 '
  1664.     db 'CR2='
  1665. ExceptionCR2t    db '00000000 '
  1666.     db 'CR3='
  1667. ExceptionCR3t    db '00000000 '
  1668.     db 'TR='
  1669. ExceptionTRt    db '0000'
  1670.     db 13,10,13,10
  1671.     db 'SystemFlags='
  1672. ExceptionSysFlags db '00000000 '
  1673.     db 13,10,13,10,'$'
  1674. ExceptionHeaderEnd    label byte
  1675. ;
  1676. ExceptionIntBuffer db size RealRegsStruc dup (?)
  1677. ;
  1678.  
  1679.  
  1680.