DIV0.ASM 20 KB

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