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 (ENTER, LEAVE, PUSH imm8, PUSH imm16, 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 asENTER 2, 0. Enter is 4 Bytes, so aJMP FARoverwrites the first byte of the following instruction, which isPUSH SI,PUSH DI,MOV AX, imm16orPUSH imm8 - 61 insances of
LEAVE; RET(this is more thanENTERbecause of functions with multiple return instructions). This is just 2 bytes, and the bytes after these two bytes can not be patched, asRETis followed by a new entry point. - 33 instances of
PUSH imm16 - 145 instances of
PUSH imm8(most of themPUSH 0orPUSH 1(these push instructions are generally used in conjunction withCALL (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