While trying to use a "modern" sound card (an Aztech Sound Galaxy Pro 16 II) in an XT compatible 8086 computer, I encountered the problem that the drivers and tools (like the mixer initialization tool and the resource configuration tool) are compiled with 286 real mode instructions (
SHL r/m, imm8). I considered different approaches:
- Disassemble the whole program with IDA, mark up all offsets, and reassemble it with an assembler that synthesizes 8086 instructions to emulate the 80286 instructions.
- Re-Engineer the tools I need
- Write an automatic debugger, that places breakpoints on all 80286 instructions and emulates them.
I dropped the first two ideas because of the great amount of manual work they need after getting the idea for the third approach. I am in no way striving for perfect 286 emulation, just emulation of the features typically used by compiled C programs. I am sure some one had that idea before me, though. Does anyone know of an implementation of that idea, so I don't have to implement it myself?
I am aware that I don't have to use that specific sound card, but I anticipate I will repeatedly encounter software that uses 286 instructions without being otherwise useless on XT computers, so a generic solution might be helpful in the future.
The program at hand,
HWSET.EXE, contains the following 286 real mode instructions (and a consideration, how easy the
JMP FAR suggestion by Raffzahn could be implemented). This list is complete according to the list of unsupported first bytes of the 8086. I made no effort to detect instructions that are invalid on an 8086 only due to certain bits in subsequent bytes, as I am not aware of any:
- 27 instances of
ENTER, 22 of them as
ENTER 2, 0. Enter is 4 Bytes, so a
JMP FARoverwrites the first byte of the following instruction, which is
MOV AX, imm16or
- 61 insances of
LEAVE; RET(this is more than
ENTERbecause of functions with multiple return instructions). This is just 2 bytes, and the bytes after these two bytes can not be patched, as
RETis followed by a new entry point.
- 33 instances of
- 145 instances of
PUSH imm8(most of them
PUSH 1(these push instructions are generally used in conjunction with
CALL (near), so there are 5 bytes at least in total.
- 18 instances of
SHL r8, imm8(with imm8 != 1), no obvious usage pattern, but 2 bytes afterwards seem to be at all samples I inspected by hand.
- 25 instances of
SHR r8, imm8(with imm8 != 1), seems to be from macro-assisted assembly code. This 3-byte instruction is mostly followed by 2 pops, so it can be replaced by a far jump.
- 6 instances of imul r16, rm16, imm8