Difference between revisions of "Patching OS/2 for fast machines"

From Computer History Wiki
Jump to: navigation, search
(Created page with "This was just posted today on [http://www.os2museum.com OS/2 Museum]... <pre> The crash is a division by zero (trap 0) on a DIV CX instruction where the CX register contains z...")
 
m (+cat)
 
(2 intermediate revisions by one other user not shown)
Line 1: Line 1:
This was just posted today on [http://www.os2museum.com OS/2 Museum]...
+
This was just posted today on [http://www.os2museum.com OS/2 Museum]... This is needed for all 1.x series versions of [[OS/2]] for fast machines, regardless if they are being emulated or not.
 
 
 
 
  
 
<pre>
 
<pre>
Line 22: Line 20:
 
     DIV  CX        ; traps if CX = 0
 
     DIV  CX        ; traps if CX = 0
 
     SHR  CX, 1
 
     SHR  CX, 1
 +
 
This obviously became a problem as far back as 1991, because OS/2 1.30.1 contains slightly different code:
 
This obviously became a problem as far back as 1991, because OS/2 1.30.1 contains slightly different code:
  
Line 31: Line 30:
 
L3:
 
L3:
 
     DIV  CX
 
     DIV  CX
 +
 
In other words, if CX is zero, it is forced to a non-zero value to avoid the division by zero trap.
 
In other words, if CX is zero, it is forced to a non-zero value to avoid the division by zero trap.
  
Line 37: Line 37:
  
 
It's simple enough to do in HEX.
 
It's simple enough to do in HEX.
 +
 +
So basically change this:
 +
<pre>B8F401BBC800F7E3F7F1</pre>
 +
into this:
 +
<pre>B8F401BBC800F7E39090</pre>
 +
 +
[[Category: OS/2]]

Latest revision as of 02:44, 17 December 2018

This was just posted today on OS/2 Museum... This is needed for all 1.x series versions of OS/2 for fast machines, regardless if they are being emulated or not.

The crash is a division by zero (trap 0) on a DIV CX instruction where the CX register contains zero. The way around this problem is patching OS/2 and getting rid of the bad loop. The original code sequence looks like this:

    MOV  DX, 3
L1:
    XOR  CX, CX
L2:
    LOOP L2        ; loop 65,536 times
    DEC  DX        ; run the loop 3 times
    JNE  L1
    CLI
    ...            ; read current tick
    STI
    SUB  CX, BX
    MOV  AX, 1F4h  ; 500
    MOV  BX, 0C8h  ; 200
    MUL  BX        ; 500 * 200 = 100,000
    DIV  CX        ; traps if CX = 0
    SHR  CX, 1

This obviously became a problem as far back as 1991, because OS/2 1.30.1 contains slightly different code:

    MOV  BX, 0C8h ; 200
    MUL  BX
    CMP  CX, 0
    JNE  L3
    MOV  CX, 1Fh  ; 31
L3:
    DIV  CX

In other words, if CX is zero, it is forced to a non-zero value to avoid the division by zero trap.

As it turns out, the MOV/MOV/MUL/DIV instruction sequence is quite unique and occurs only in the BASEDD0x.SYS drivers. To avoid the crash, it is sufficient to remove the DIV instruction, replacing it by NOPs.

It's simple enough to do in HEX.

So basically change this:

B8F401BBC800F7E3F7F1

into this:

B8F401BBC800F7E39090