home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / div / div0.asm next >
Assembly Source File  |  1998-06-08  |  20KB  |  971 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/div/rcs/div0.asm $
  13. ; $Revision: 1.4 $
  14. ; $Author: john $
  15. ; $Date: 1995/02/07 17:55:58 $
  16. ;
  17. ; Divide by zero error handler functions
  18. ;
  19. ; $Log: div0.asm $
  20. ; Revision 1.4  1995/02/07  17:55:58  john
  21. ; Made the debug counter variables public.
  22. ; Revision 1.3  1994/01/14  15:34:12  john
  23. ; Added counters for number of overflows.
  24. ; Revision 1.2  1993/10/26  17:25:45  john
  25. ; fixed bug in init, cx was being trashed.
  26. ; Revision 1.1  1993/09/17  12:37:51  john
  27. ; Initial revision
  28. ;
  29. ;
  30.  
  31.  
  32.  
  33. ; DIV0.ASM   - Provides routines to capture divide overflow exceptions.
  34. ;              See DIV0.H for calling parameters.
  35.  
  36. .386
  37.  
  38.  
  39.  
  40. _DATA   SEGMENT BYTE PUBLIC USE32 'DATA'
  41.  
  42.         MAX_SIZE EQU 100
  43.  
  44.         Old_Ex_Sel      dw ?            ; Old Selector
  45.         Old_Ex_Off      dd ?            ; Old offset
  46.  
  47.         Already_Init    dd  0           ; Equal to 1 when installed
  48.  
  49.         DefaultMode dd  0               ; What to do when not in list.
  50.  
  51.         ; Callback List
  52.         CB_Size     dw  0
  53.         CB_Source   dd  MAX_SIZE DUP (0)
  54.         CB_Dest     dd  MAX_SIZE DUP (0)
  55.  
  56.         ; Saturation List
  57.         SAT_Size    dw  0
  58.         SAT_Source  dd  MAX_SIZE DUP (0)
  59.  
  60.  
  61.                PUBLIC _div0_num_handled_by_cblist
  62.         PUBLIC _div0_num_handled_by_satlist
  63.         PUBLIC _div0_num_saturated
  64.  
  65.                _div0_num_handled_by_cblist    dd    0
  66.         _div0_num_handled_by_satlist    dd    0
  67.         _div0_num_saturated        dd    0
  68.  
  69. _DATA   ENDS
  70.  
  71. DGROUP  GROUP _DATA
  72.  
  73.  
  74. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  75.  
  76.         ASSUME  DS:_DATA
  77.         ASSUME  CS:_TEXT
  78.  
  79. DivideByZeroException:
  80.  
  81. PREFIX_ADRSIZ   EQU 01100111b
  82. PREFIX_OPSIZE   EQU 01100110b
  83. PREFIX_LOCK     EQU 11110000b
  84. PREFIX_CS       EQU 00101110b
  85. PREFIX_DS       EQU 00111110b
  86. PREFIX_ES       EQU 00100110b
  87. PREFIX_FS       EQU 01100100b
  88. PREFIX_GS       EQU 01100101b
  89. PREFIX_SS       EQU 00110110b
  90. OPCODE_NOP      EQU 10010000b
  91.  
  92.  
  93. OVERFLOW_8BIT_UNSIGNED EQU 0FFh
  94. OVERFLOW_16BIT_UNSIGNED EQU 0FFFFh
  95. OVERFLOW_32BIT_UNSIGNED EQU 0FFFFFFFFh
  96.  
  97. OVERFLOW_8BIT_NEGATIVE EQU -128
  98. OVERFLOW_16BIT_NEGATIVE EQU -32768
  99. OVERFLOW_32BIT_NEGATIVE EQU -2147483648
  100.  
  101.  
  102. OVERFLOW_8BIT_POSITIVE EQU 127
  103. OVERFLOW_16BIT_POSITIVE EQU 32767
  104. OVERFLOW_32BIT_POSITIVE EQU 2147483647
  105.  
  106.  
  107.  
  108. SAVED_REGS  EQU 32
  109. SAVED_EAX   EQU DWORD PTR SS:[ESP+0]         ; 4
  110.  
  111. SAVED_AL    EQU BYTE PTR SS:[ESP+0]
  112. SAVED_AH    EQU BYTE PTR SS:[ESP+1]
  113. SAVED_AX    EQU WORD PTR SS:[ESP+0]
  114.  
  115. SAVED_EBX   EQU DWORD PTR SS:[ESP+4]         ; 4
  116.  
  117. SAVED_BL    EQU BYTE PTR SS:[ESP+4]
  118. SAVED_BH    EQU BYTE PTR SS:[ESP+5]
  119. SAVED_BX    EQU WORD PTR SS:[ESP+4]
  120.  
  121. SAVED_ECX   EQU DWORD PTR SS:[ESP+8]         ; 4
  122.  
  123. SAVED_CL    EQU BYTE PTR SS:[ESP+8]
  124. SAVED_CH    EQU BYTE PTR SS:[ESP+9]
  125. SAVED_CX    EQU WORD PTR SS:[ESP+8]
  126.  
  127. SAVED_EDX   EQU DWORD PTR SS:[ESP+12]        ; 4
  128.  
  129. SAVED_DL    EQU BYTE PTR SS:[ESP+12]
  130. SAVED_DH    EQU BYTE PTR SS:[ESP+13]
  131. SAVED_DX    EQU WORD PTR SS:[ESP+12]
  132.  
  133. SAVED_ESI   EQU DWORD PTR SS:[ESP+16]        ; 4
  134. SAVED_SI    EQU WORD PTR SS:[ESP+16]
  135.  
  136. SAVED_EDI   EQU DWORD PTR SS:[ESP+20]        ; 4
  137. SAVED_DI    EQU WORD PTR SS:[ESP+20]
  138.  
  139. SAVED_ES    EQU WORD PTR SS:[ESP+24]        ; 4
  140.  
  141. SAVED_DS    EQU WORD PTR SS:[ESP+28]        ; 4
  142.  
  143. BAD_EIP     EQU DWORD PTR SS:[ESP+0Ch+SAVED_REGS]
  144. BAD_CS      EQU WORD PTR SS:[ESP+10h+SAVED_REGS]
  145. SAVED_ESP   EQU DWORD PTR SS:[ESP+18h+SAVED_REGS]
  146. SAVED_SP    EQU WORD PTR SS:[ESP+18h+SAVED_REGS]
  147. SAVED_SS    EQU WORD PTR SS:[ESP+1Ch+SAVED_REGS]
  148.  
  149.         ;int 3       ; Bypass by typing:  /eip++
  150.  
  151.         push    ds
  152.         push    es
  153.         push    edi
  154.         push    esi
  155.         push    edx
  156.         push    ecx
  157.         push    ebx
  158.         push    eax
  159.  
  160.         mov     ax, DGROUP
  161.         mov     ds, ax
  162.  
  163.         mov     eax, BAD_EIP
  164.  
  165.         xor     ecx, ecx
  166.  
  167. NextCB:
  168.         cmp     cx, CB_Size
  169.         je      CheckSatList
  170.         cmp     CB_Source[ecx*4], eax
  171.         jne     NotIt
  172.         ; Found the right Call Back item
  173.         inc    _div0_num_handled_by_cblist
  174.         mov     ecx, CB_Dest[ecx*4]
  175.         mov     BAD_EIP, ecx
  176.         jmp     NormalReturn
  177. NotIt:
  178.         inc     cx
  179.         jmp     NextCB
  180.  
  181.  
  182.  
  183. CheckSatList:
  184.         xor     ecx, ecx
  185. NextSAT:
  186.         cmp     cx, SAT_Size
  187.         je      UseDefaultAction
  188.         cmp     SAT_Source[ecx*4], eax
  189.         jne     NotIt1
  190.         ; Found the right Saturation item
  191.         inc    _div0_num_handled_by_satlist
  192.  
  193.         jmp     SaturateIt
  194. NotIt1:
  195.         inc     cx
  196.         jmp     NextCB
  197.  
  198.  
  199.  
  200. UseDefaultAction:
  201.         cmp     DefaultMode, 1
  202.         je      DefaultSaturate
  203.  
  204.         ;======  Return Error Code. =============
  205.         ;int     3               ; Pop into debugger if active
  206.         call    div0_close_
  207.         jmp     NormalReturn
  208.  
  209. DefaultSaturate:
  210.         ; This is hit when mode=DM_SATURATE and the instruction
  211.         ; isn't in any callback or saturate lists. For your handy debugging
  212.         ; information, the instruction that caused this exception is at
  213.         ; BX:EAX.
  214.         inc    _div0_num_saturated 
  215.  
  216.         mov     eax, BAD_EIP
  217.         mov     bx, BAD_CS
  218.         int     3
  219.  
  220. SaturateIt:
  221.  
  222.         xor     ebx, ebx
  223.         xor     ecx, ecx
  224.         xor     esi, esi
  225.         xor     edi, edi
  226.  
  227.         mov     es, SAVED_DS
  228.  
  229.         mov     eax, BAD_EIP
  230.  
  231.         ; EAX = Pointer to Div instruction
  232.         ; BH = temp byte holder
  233.         ; BL = temp byte holder
  234.         ; CH = Bits 0=8bit, 1=16bit, 2=32bit, 3=DIV
  235.         ; CL = Temp bit shifter
  236.         ; EDX = temp 32-bit holder
  237.  
  238.  
  239. PrefixCheck:
  240.         mov     bl, BYTE PTR CS:[eax]
  241.         cmp     bl, PREFIX_OPSIZE
  242.         je      OperandSize
  243.         cmp     bl, PREFIX_ADRSIZ
  244.         je      OverPrefix
  245.         cmp     bl, PREFIX_LOCK
  246.         je      OverPrefix
  247.         cmp     bl, PREFIX_CS
  248.         je      PrefixCS
  249.         cmp     bl, PREFIX_DS
  250.         je      PrefixDS
  251.         cmp     bl, PREFIX_ES
  252.         je      PrefixES
  253.         cmp     bl, PREFIX_FS
  254.         je      PrefixFS
  255.         cmp     bl, PREFIX_GS
  256.         je      PrefixGS
  257.         cmp     bl, PREFIX_SS
  258.         je      PrefixSS
  259.         jmp     DoneWithPrefixes
  260.  
  261. OverPrefix:
  262.         inc     eax
  263.         jmp     PrefixCheck
  264.  
  265. PrefixCS:
  266.         mov     es, BAD_CS
  267.         jmp     OverPrefix
  268.  
  269. PrefixDS:
  270.         push    ds
  271.         pop     es
  272.         jmp     OverPrefix
  273.  
  274. PrefixES:
  275.         mov     es, SAVED_ES
  276.  
  277. PrefixFS:
  278.         push    fs
  279.         pop     es
  280.         jmp     OverPrefix
  281.  
  282. PrefixGS:
  283.         push    gs
  284.         pop     es
  285.         jmp     OverPrefix
  286.  
  287. PrefixSS:
  288.         mov     es, SAVED_SS
  289.         jmp     OverPrefix
  290.  
  291. OperandSize:
  292.         or      ch, 10b     ; Flag 16-bit
  293.         jmp     OverPrefix
  294.  
  295. DoneWithPrefixes:
  296.  
  297.         ; Check for the divide opcode.
  298.         cmp     bl, 0F7h
  299.         je      OP32OR16BIT
  300.  
  301.         cmp     bl, 0F6h
  302.         je      OP8BIT
  303.  
  304.         ; Something is wrong!!!!! This should never be reached!!!
  305.         pop     eax
  306.         pop     ebx
  307.         pop     ecx
  308.         pop     edx
  309.         pop     esi
  310.         pop     edi
  311.         pop     es
  312.         pop     ds
  313.  
  314.         int     3
  315.         retf
  316.  
  317.  
  318. OP32OR16BIT:
  319.         test    ch, 10b
  320.         jnz     OP16BIT
  321.  
  322. OP32BIT:
  323.         or      ch, 100b    ; Flag 32-bit
  324.         jmp     GotOpSize
  325.  
  326. OP8BIT:
  327.         or      ch, 1b      ; Flag 8-bit
  328.         jmp     GotOpSize
  329.  
  330. OP16BIT:
  331.  
  332.  
  333. GotOpSize:
  334.         inc     eax     ; We should be pointing to the mod,111,r/m byte
  335.         mov     bl, BYTE PTR CS:[eax]
  336.         inc     eax
  337.  
  338.         mov     bh, bl
  339.         shr     bh, 6       ; BH = mod bits
  340.  
  341.         test    bl, 001000b
  342.         ;           110 = Div
  343.         ;           111 = iDiv
  344.         jz      IsDIV
  345.         ; This is a signed division
  346.         or      ch, 1000b   ; Flag Signed
  347. IsDIV:
  348.         and     bl, 111b    ; BL = r/m bits
  349.  
  350.         cmp     bh, 11b
  351.         je      MOD_11
  352.  
  353.  
  354. DoRMbits:
  355.  
  356.         cmp     bl, 000b
  357.         je      RM_000
  358.         cmp     bl, 001b
  359.         je      RM_001
  360.         cmp     bl, 010b
  361.         je      RM_010
  362.         cmp     bl, 011b
  363.         je      RM_011
  364.         cmp     bl, 100b
  365.         je      RM_100
  366.         cmp     bl, 101b
  367.         je      RM_101
  368.         cmp     bl, 110b
  369.         je      RM_110
  370.         jmp     RM_111
  371.  
  372. RM_000:
  373.         add     esi, SAVED_EAX
  374.         jmp     doneRM
  375.  
  376. RM_001:
  377.         add     esi, SAVED_ECX
  378.         jmp     doneRM
  379.  
  380. RM_010:
  381.         add     esi, SAVED_EDX
  382.         jmp     doneRM
  383.  
  384. RM_011:
  385.         add     esi, SAVED_EBX
  386.         jmp     doneRM
  387.  
  388. RM_100:
  389.         jmp     RM_SIB
  390.  
  391.  
  392. RM_101:
  393.         cmp     bh, 00b
  394.         je      DSdisp32
  395.  
  396.         add     esi, ebp
  397.         mov     es, SAVED_SS
  398.         jmp     doneRM
  399.  
  400. DSdisp32:
  401.         mov     bh, 10b
  402.         jmp     doneRM
  403.  
  404. RM_110:
  405.         add     esi, SAVED_ESI
  406.         jmp     doneRM
  407.  
  408. RM_111:
  409.         add     esi, SAVED_EDI
  410.         jmp     doneRM
  411.  
  412.  
  413. RM_SIB:
  414.         mov     bl, BYTE PTR CS:[eax]   ; BL = s-i-b byte
  415.  
  416.         mov     cl, bl
  417.         shl     cl, 6
  418.  
  419.         shl     bl, 3
  420.         and     bl, 111b
  421.  
  422.         cmp     bl, 000b
  423.         je      INDEX_EAX
  424.         cmp     bl, 001b
  425.         je      INDEX_ECX
  426.         cmp     bl, 010b
  427.         je      INDEX_EDX
  428.         cmp     bl, 011b
  429.         je      INDEX_EBX
  430.         cmp     bl, 100b
  431.         je      doneSIB1
  432.         cmp     bl, 101b
  433.         je      INDEX_EBP
  434.         cmp     bl, 110b
  435.         je      INDEX_ESI
  436.         jmp     INDEX_EDI
  437.  
  438.  
  439. INDEX_EAX:
  440.         mov     edx, SAVED_EAX
  441.         jmp     doneSIB
  442. INDEX_ECX:
  443.         mov     edx, SAVED_ECX
  444.         jmp     doneSIB
  445. INDEX_EDX:
  446.         mov     edx, SAVED_EDX
  447.         jmp     doneSIB
  448. INDEX_EBX:
  449.         mov     edx, SAVED_EBX
  450.         jmp     doneSIB
  451. INDEX_EBP:
  452.         mov     edx, ebp
  453.         jmp     doneSIB
  454. INDEX_ESI:
  455.         mov     edx, SAVED_ESI
  456.         jmp     doneSIB
  457. INDEX_EDI:
  458.         mov     edx, SAVED_EDI
  459.         jmp     doneSIB
  460.  
  461. doneSIB:
  462.         shl     edx, cl
  463.         add     esi, edx
  464.  
  465.  
  466. doneSIB1:
  467.         mov     bl, BYTE PTR CS:[eax]   ; BL = s-i-b byte
  468.         inc     eax
  469.  
  470.         mov     bh, bl
  471.         shl     bh, 6
  472.         and     bl, 111b
  473.         jmp     DoRMbits
  474.  
  475.  
  476. doneRM: ;BH = mod
  477.  
  478.         cmp     bh, 00b
  479.         je      MOD_00
  480.         cmp     bh, 01b
  481.         je      MOD_01
  482.         cmp     bh, 10b
  483.         je      MOD_10
  484.         jmp     MOD_11
  485.  
  486.  
  487. MOD_00:     ; No displacement
  488.         jmp     doneMOD
  489.  
  490. MOD_01: ; disp8
  491.         movsx   edx, BYTE PTR CS:[eax]
  492.         add     eax, 1
  493.         add     esi, edx
  494.         jmp     doneMOD
  495.  
  496. MOD_10:
  497.         mov     edx, DWORD PTR CS:[eax]
  498.         add     eax, 4
  499.         add     esi, edx
  500.         jmp     doneMOD
  501.  
  502. MOD_11: cmp     bl, 000b
  503.         je      REG_000
  504.         cmp     bl, 001b
  505.         je      REG_001
  506.         cmp     bl, 010b
  507.         je      REG_010
  508.         cmp     bl, 011b
  509.         je      REG_011
  510.         cmp     bl, 100b
  511.         je      REG_100
  512.         cmp     bl, 101b
  513.         je      REG_101
  514.         cmp     bl, 110b
  515.         je      REG_110
  516.         jmp     REG_111
  517.  
  518.  
  519. REG_000:
  520.         test    ch, 1b              ; Check if 8-bit
  521.         jz      @f                  ; Skip if not
  522.         movsx   edx,    SAVED_AL
  523. @@:     test    ch, 10b             ; Check if 16-bit
  524.         jz      @f                  ; Skip if not
  525.         movsx   edx,    SAVED_AX
  526. @@:     test    ch, 100b            ; Check if 32-bit
  527.         jz      GotValue            ; skip if not
  528.         mov     edx,    SAVED_EAX
  529.         jmp     GotValue
  530.  
  531. REG_001:
  532.         test    ch, 1b              ; Check if 8-bit
  533.         jz      @f                  ; Skip if not
  534.         movsx   edx,    SAVED_CL
  535. @@:     test    ch, 10b             ; Check if 16-bit
  536.         jz      @f                  ; Skip if not
  537.         movsx   edx,    SAVED_CX
  538. @@:     test    ch, 100b            ; Check if 32-bit
  539.         jz      GotValue            ; skip if not
  540.         mov     edx,    SAVED_ECX
  541.         jmp     GotValue
  542. REG_010:
  543.         test    ch, 1b              ; Check if 8-bit
  544.         jz      @f                  ; Skip if not
  545.         movsx   edx,    SAVED_DL
  546. @@:     test    ch, 10b             ; Check if 16-bit
  547.         jz      @f                  ; Skip if not
  548.         movsx   edx,    SAVED_DX
  549. @@:     test    ch, 100b            ; Check if 32-bit
  550.         jz      GotValue            ; skip if not
  551.         mov     edx,    SAVED_EDX
  552.         jmp     GotValue
  553. REG_011:
  554.         test    ch, 1b              ; Check if 8-bit
  555.         jz      @f                  ; Skip if not
  556.         movsx   edx,    SAVED_BL
  557. @@:     test    ch, 10b             ; Check if 16-bit
  558.         jz      @f                  ; Skip if not
  559.         movsx   edx,    SAVED_BX
  560. @@:     test    ch, 100b            ; Check if 32-bit
  561.         jz      GotValue            ; skip if not
  562.         mov     edx,    SAVED_EDX
  563.         jmp     GotValue
  564. REG_100:
  565.         test    ch, 1b              ; Check if 8-bit
  566.         jz      @f                  ; Skip if not
  567.         movsx   edx,    SAVED_AH
  568. @@:     test    ch, 10b             ; Check if 16-bit
  569.         jz      @f                  ; Skip if not
  570.         movsx    edx,    SAVED_SP
  571. @@:     test    ch, 100b            ; Check if 32-bit
  572.         jz      GotValue            ; skip if not
  573.         mov     edx,    SAVED_ESP
  574.         jmp     GotValue
  575. REG_101:
  576.         test    ch, 1b              ; Check if 8-bit
  577.         jz      @f                  ; Skip if not
  578.         movsx   edx,    SAVED_CH
  579. @@:     test    ch, 10b             ; Check if 16-bit
  580.         jz      @f                  ; Skip if not
  581.         movsx   edx,    bp
  582. @@:     test    ch, 100b            ; Check if 32-bit
  583.         jz      GotValue            ; skip if not
  584.         mov     edx,    ebp
  585.         jmp     GotValue
  586. REG_110:
  587.         test    ch, 1b              ; Check if 8-bit
  588.         jz      @f                  ; Skip if not
  589.         movsx   edx,    SAVED_DH
  590. @@:     test    ch, 10b             ; Check if 16-bit
  591.         jz      @f                  ; Skip if not
  592.         movsx   edx,    SAVED_SI
  593. @@:     test    ch, 100b            ; Check if 32-bit
  594.         jz      GotValue            ; skip if not
  595.         mov     edx,    SAVED_ESI
  596.         jmp     GotValue
  597. REG_111:
  598.         test    ch, 1b              ; Check if 8-bit
  599.         jz      @f                  ; Skip if not
  600.         movsx   edx,    SAVED_BH
  601. @@:     test    ch, 10b             ; Check if 16-bit
  602.         jz      @f                  ; Skip if not
  603.         movsx   edx,    SAVED_DI
  604. @@:     test    ch, 100b            ; Check if 32-bit
  605.         jz      GotValue            ; skip if not
  606.         mov     edx,    SAVED_EDI
  607.         jmp     GotValue
  608.  
  609.  
  610. doneMOD:
  611.         test    ch, 1b              ; Check if 8-bit
  612.         jz      @f                  ; Skip if not
  613.         movsx   edx,    BYTE PTR ES:[esi]
  614. @@:     test    ch, 10b             ; Check if 16-bit
  615.         jz      @f                  ; Skip if not
  616.         movsx   edx,    WORD PTR ES:[esi]
  617. @@:     test    ch, 100b            ; Check if 32-bit
  618.         jz      GotValue            ; skip if not
  619.         mov     edx,    DWORD PTR ES:[esi]
  620.  
  621. GotValue:
  622.         ; EAX = Pointer to instruction right after DIV
  623.         ; CH = Bits 0=8bit, 1=16bit, 2=32bit, 3=DIV
  624.         ; EDX = 32-bit sign extended divisor (source operand)
  625.  
  626.         mov     BAD_EIP, eax    ; Point EIP to next instruction
  627.  
  628.  
  629.         ; if size=8  then AL=1..., AH=1...
  630.         ; if size=16 then AX=1..., DX=1...
  631.         ; if size=32 then EAX=1..., EDX=1...
  632.         ;
  633.         ; resultsign = - (Assume negative or unsigned)
  634.         ;
  635.         ; If signed then
  636.         ;    if size=8 then  resultsign = sign(ah:al) * sign(edx)
  637.         ;    if size=16 then resultsign = sign(dx:ax) * sign(edx)
  638.         ;    if size=32 then resultsign = sign(dx:ax) * sign(edx)
  639.         ;
  640.         ; if resultsign == + then
  641.         ;    if size=8 then  AL = 01...
  642.         ;    if size=16 then AX = 01...
  643.         ;    if size=32 then EAX = 01...
  644.         ;
  645.  
  646.         test    ch, 1000b
  647.         jz      UnSigned
  648.  
  649.         shr     edx, 31
  650.  
  651.         ; Signed return
  652.         test    ch, 1b              ; Check if 8-bit
  653.         jnz     Get8Sign
  654.         test    ch, 10b             ; Check if 16-bit
  655.         jnz     Get16Sign
  656.         jmp     Get32Sign         ; Else is 32-bit
  657.  
  658. Get8Sign:
  659.         mov     ah, SAVED_AH
  660.         shr     ah, 7           ; AH = sign of divisor
  661.         xor     ah, dl
  662.         jnz     Neg8Return
  663.         jmp     Pos8Return
  664.  
  665. Get16Sign:
  666.         mov     ah, SAVED_DH
  667.         shr     ah, 7           ; AH = sign of divisor
  668.         xor     ah, dl
  669.         jnz     Neg16Return
  670.         jmp     Pos16Return
  671.  
  672. Get32Sign:
  673.         mov     eax, SAVED_EDX
  674.         shr     eax, 31           ; AL = sign of divisor
  675.         xor     al, dl
  676.         jnz     Neg32Return
  677.         jmp     Pos32Return
  678.  
  679. UnSigned: ; We need to find the sign
  680.         ; Unsigned div return
  681.         test    ch, 1b              ; Check if 8-bit
  682.         jnz     Unsigned8Return
  683.         test    ch, 10b             ; Check if 16-bit
  684.         jnz     Unsigned16Return
  685.         jmp     Unsigned32Return         ; Else is 32-bit
  686.  
  687.  
  688. NormalReturn:
  689.         pop     eax
  690.         pop     ebx
  691.         pop     ecx
  692.         pop     edx
  693.         pop     esi
  694.         pop     edi
  695.         pop     es
  696.         pop     ds
  697.         retf
  698.  
  699.  
  700. Neg8Return:
  701.         pop     eax
  702.         mov     al, OVERFLOW_8BIT_NEGATIVE
  703.         mov     ah, 0       ; Remainder = 0
  704.         pop     ebx
  705.         pop     ecx
  706.         pop     edx
  707.         pop     esi
  708.         pop     edi
  709.         pop     es
  710.         pop     ds
  711.         retf
  712.  
  713. Neg16Return:
  714.         pop     eax
  715.         mov     ax, OVERFLOW_16BIT_NEGATIVE
  716.         pop     ebx
  717.         pop     ecx
  718.         pop     edx
  719.         mov     dx, 0       ; Remainder = 0
  720.         pop     esi
  721.         pop     edi
  722.         pop     es
  723.         pop     ds
  724.         retf
  725.  
  726. Neg32Return:
  727.         pop     eax
  728.         mov     eax, OVERFLOW_32BIT_NEGATIVE
  729.         pop     ebx
  730.         pop     ecx
  731.         pop     edx
  732.         mov     edx, 0          ; Remainder = 0
  733.         pop     esi
  734.         pop     edi
  735.         pop     es
  736.         pop     ds
  737.         retf
  738.  
  739.  
  740. Pos8Return:
  741.         pop     eax
  742.         mov     al, OVERFLOW_8BIT_POSITIVE
  743.         mov     ah, 0           ; Remainder = 0
  744.         pop     ebx
  745.         pop     ecx
  746.         pop     edx
  747.         pop     esi
  748.         pop     edi
  749.         pop     es
  750.         pop     ds
  751.         retf
  752.  
  753. Pos16Return:
  754.         pop     eax
  755.         mov     ax, OVERFLOW_16BIT_POSITIVE
  756.         pop     ebx
  757.         pop     ecx
  758.         pop     edx
  759.         mov     dx, 0           ; Remainder = 0
  760.         pop     esi
  761.         pop     edi
  762.         pop     es
  763.         pop     ds
  764.         retf
  765.  
  766. Pos32Return:
  767.         pop     eax
  768.         mov     eax, OVERFLOW_32BIT_POSITIVE
  769.         pop     ebx
  770.         pop     ecx
  771.         pop     edx
  772.         mov     edx, 0          ; Remainder = 0
  773.         pop     esi
  774.         pop     edi
  775.         pop     es
  776.         pop     ds
  777.         retf
  778.  
  779. Unsigned8Return:
  780.         pop     eax
  781.         mov     al, OVERFLOW_8BIT_UNSIGNED
  782.         mov     ah, 0       ; Remainder = 0
  783.         pop     ebx
  784.         pop     ecx
  785.         pop     edx
  786.         pop     esi
  787.         pop     edi
  788.         pop     es
  789.         pop     ds
  790.         retf
  791.  
  792. Unsigned16Return:
  793.         pop     eax
  794.         mov     ax, OVERFLOW_16BIT_UNSIGNED
  795.         pop     ebx
  796.         pop     ecx
  797.         pop     edx
  798.         mov     dx, 0       ; Remainder = 0
  799.         pop     esi
  800.         pop     edi
  801.         pop     es
  802.         pop     ds
  803.         retf
  804.  
  805. Unsigned32Return:
  806.         pop     eax
  807.         mov     eax, OVERFLOW_32BIT_UNSIGNED
  808.         pop     ebx
  809.         pop     ecx
  810.         pop     edx
  811.         mov     edx, 0          ; Remainder = 0
  812.         pop     esi
  813.         pop     edi
  814.         pop     es
  815.         pop     ds
  816.         retf
  817.  
  818.  
  819. PUBLIC  div0_close_
  820.  
  821. div0_close_:
  822.         push    eax
  823.         push    ecx
  824.         push    edx
  825.  
  826.         mov     Already_Init, 0
  827.  
  828.         mov     eax, 0203h
  829.         mov     bl, 0
  830.         mov     cx, Old_Ex_Sel
  831.         mov     edx, Old_Ex_Off
  832.         int     31h
  833.  
  834.         pop     edx
  835.         pop     ecx
  836.         pop     eax
  837.  
  838.         ret
  839.  
  840.  
  841.  
  842.  
  843.  
  844. PUBLIC  div0_set_saturate_
  845.  
  846. div0_set_saturate_:
  847.         ; EAX = div_addr
  848.  
  849.         push    ecx
  850.  
  851.         xor     ecx, ecx
  852.         mov     cx, SAT_Size
  853.         inc     cx
  854.         cmp     cx, MAX_SIZE
  855.         jae     TooMany1
  856.         mov     SAT_Size, cx
  857.  
  858.         dec     ecx
  859.         mov     SAT_Source[ecx*4], eax
  860.  
  861.         mov     eax, 1
  862.         pop     ecx
  863.         ret
  864.  
  865. TooMany1:
  866.         mov     eax, 0
  867.         pop     ecx
  868.         ret
  869.  
  870.  
  871. PUBLIC  div0_set_handler_
  872.  
  873. div0_set_handler_:
  874.         ; EAX = div_addr
  875.         ; EDX = handler_addr
  876.         push    ecx
  877.  
  878.         xor     ecx, ecx
  879.         mov     cx, CB_Size
  880.         inc     cx
  881.         cmp     cx, MAX_SIZE
  882.         jae     TooMany
  883.         mov     CB_Size, cx
  884.  
  885.         dec     ecx
  886.         mov     CB_Source[ecx*4], eax
  887.         mov     CB_Dest[ecx*4], edx
  888.  
  889.         mov     eax, 1
  890.         pop     ecx
  891.         ret
  892.  
  893. TooMany:
  894.         mov     eax, 0
  895.         pop     ecx
  896.         ret
  897.  
  898.  
  899.  
  900. PUBLIC  div0_set_mode_
  901.  
  902. div0_set_mode_:
  903.         and     eax, 1
  904.         mov     DefaultMode, eax
  905.         ret
  906.  
  907.  
  908. PUBLIC  div0_init_
  909.  
  910. div0_init_:
  911.         push    ds
  912.         push    ebx
  913.         push    ecx
  914.         push    edx
  915.  
  916.         cmp     Already_Init, 1
  917.         je      AlreadyInstalled
  918.  
  919.         mov     Already_Init, 1
  920.  
  921.                mov    _div0_num_handled_by_cblist, 0
  922.         mov    _div0_num_handled_by_satlist, 0
  923.         mov    _div0_num_saturated, 0
  924.  
  925.         and     eax, 1
  926.         mov     DefaultMode, eax
  927.  
  928.         mov     SAT_Size, 0
  929.         mov     CB_Size, 0
  930.  
  931.         mov     eax, 0202h
  932.         mov     bl, 0
  933.         int     31h
  934.         jc      ToBadSoSadItFailed
  935.         mov     Old_Ex_Sel,cx
  936.         mov     Old_Ex_Off,edx
  937.  
  938.         mov     eax, 0203h
  939.         mov     bl, 0
  940.         mov     cx, cs
  941.         mov     edx, offset DivideByZeroException
  942.         int     31h
  943.         jc      ToBadSoSadItFailed
  944.  
  945. AlreadyInstalled:
  946.         mov     eax, 1
  947.         pop     edx
  948.         pop     ecx
  949.         pop     ebx
  950.         pop     ds
  951.         ret
  952.  
  953. ToBadSoSadItFailed:
  954.         mov     eax, 0
  955.         pop     edx
  956.         pop     ebx
  957.         pop     ds
  958.         ret
  959.  
  960. _TEXT   ENDS
  961.  
  962.  
  963.         END
  964.  
  965.  
  966. 
  967.