-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error, unimplemented opcode 66 at cs:ip = 0098:4FB3 #56
Comments
Hi! The opcode you found is from a 386 instruction - implementing the 386 instructions will be a significant effort, yes - it will be certainly easier to take an existing 386 CPU emulator and put it in place of the existing 286 one. The 386 CPU added all the 32 bit instructions, the 32 bit protected-mode, paging, new exceptions, etc. My original intention with EMU2 was to run old 16-bit DOS programs, those work in a 8088 or 8086 CPU, and don´t need newer opcodes. Have Fun! |
Further explaining, the 66h is not an opcode, it is an opcode prefix, that changes the next instruction size from 16bit to 32bit, so to implement it you will need to implement all existing 16 bit instructions in a 32 bit version. |
Hello @dmsc, For context, it seems there is a version of this I am a bit surprised that the program is executing a 32-bit instruction, apparently (?) without checking beforehand that it is running on a 32-bit-capable platform (alternatively, there might have been a check that somehow went wrong). Thank you! |
There are a few versions of the compiler. We are looking at versions 3.5 and 3.6, which only appear to exist as 16bit binaries. For a little more context, this is part of a matching decompilation project, where specific compiler versions are required to produce the correct result. |
Hello @mkst, What are the last few (10 or so) instructions that are run before the It is possible that Thank you! |
Here's the last 20 commands (I've also attached the whole log file should that be of interest). It's all Greek to me!
|
Hi! From that log, the instruction at that address is "XOR EBP, EBP", this is the disassembly of the function end:
So, the instruction does not have any side effects (it is followed by a POP BP), it only crashes on any processor without 32 bit support, so this is intentional. Note that just above there is an INT 27h, this checks for any DOS extender loaded, if the function returns that the CPU does not implement 32 bit opcodes, it also jumps to the faulting instruction:
And finally, if the offending instruction is replaced with a NOP, this is the result:
Have Fun! |
Does this suggest that the program could be patched to be treated as a 32bit app from the get go (and thus runnable via wine)? Or is this a fundamentally 16bit app with 32bit extension (and therefore 386 emulation is the only way to go)? Thanks for your time & responses! |
You probably need a DOS extender and a 80386 emulator, I don´t know if it uses a DSO extender to work in protected-mode or simply to access extended memory. Try running it in DOSBOX with DPMI disabled. |
Hello @dmsc, I tried the Thank you! |
I should have been more clear, we can run the CC1PSX compiler via dosemu/dosbox BUT we are after a lighter solution. We are finding that the process seems to take 5 seconds to run a compilation command (still trying to determine what exactly is going wrong, it only takes 500ms when running it by hand) and I wondered if emu2 could be a lightweight alternative.. |
@mkst : what exactly do you mean by running (I suppose if you run the program under different conditions, then yes, you are going to get some extra overhead in different places. So perhaps what you simply need to do is to figure out where the extra overhead is coming from when you start up Thank you! |
Hah I've been trying to keep the details light to avoid derailing this Issue... but here goes. We have a PR to our project (decompme/decomp.me#651) that adds dosemu2 in order to support these old compilers that won't run under WINE. When testing the PR locally I found that the execution of dosemu2 is taking ~5 seconds. As I was getting nowhere with figuring out the slowdown, I went on a hunt for alternatives to dosemu2, of which emu2 looked like a potential candidate - however as it only supports 16bit instructions (and this CC1PSX requires 32bit support but presents itself as a 16bit exe) it turns out it's not going to be a drop-in replacement. As another tangent, we have our own lightweight alternative to WINE (https://github.com/decompals/wibo) which is only for cli applications (it has some magic to kick off the exe and then intercepts all DLL calls with our own replacements) - do you know if something similar would be possible for dos? i.e. intercepting systemcalls rather than trying to emulate an x86 processor? |
Hi!
You will need to emulate at least a 80386, as DOS applications rely on x86 16 bit support and real-mode, and this is very difficult to manage that in current x86 processors. Also, by running natively, you can't run your program in other CPU architectures. For example, the I refrained to add 80386 support to emu2 because it opens a can of worms - many DOS programs when detecting a 386 try to start in protected mode, or even in unreal mode. I have a branch that tries to add 80286 protected mode support, and I could not make it work with many programs, as 286 protected mode is not that documented. |
Hello @dmsc,
Nice analysis!
Out of curiosity, on real hardware there's no crash, instead an 80186 or 80286 CPU will generate an invalid opcode exception (INT 6), rather than ignore the 66h addr32 prefix like the 8086 does, correct? Does MSDOS (or the BIOS) just have a null (IRET only) handler for this vector, causing the program to resume execution just past the 66h byte for what will then be a
Wow, so an MSDOS .exe talks to the PC programmable interrupt controller... Do you find this and other hardware port I/O is somewhat common in programs that attempt to manage XMS or APIs that came later in DOS? Thank you! |
Hi!
Yes. emu2 does generate the INT 6 (actually a TRAP in a 80286), and the default handler terminates the application. In a 8086, the opcode 66h is an alias for 76h, ("JAE"), consuming the next byte and generally executing bogus code.
No, the 80286 TRAP should set the CS:IP saved in the stack to the faulting instruction, so a IRET will return to the same instruction, causing a fault again, so the PC will lockup.
Typical is accessing the PIC and the keyboard controller - this is needed to exit from protected mode in 80286. For a command line program, you can ignore all those accesses, most are there because they are part of the C standard library at initialization. Most C runtimes start by saving the interrupt handlers and accessing the PIC to ensure that software interrupts are properly handled. Have Fun! |
Hello @dmsc,
I think something like WiBo might be able to run I think what a WiBo-like wrapper will need to care about, is what services the actual 32-bit COFF program — the thing that appears after the DOS extender stub in the program binary — really needs. The DOS extender used seems to be Thank you! |
Hello @dmsc,
I am curious — what problems did you encounter in particular? (And, I do not quite believe that 80286 protected mode is "not that documented". Intel's Software Developer's Manual is still very much around. And the source code listings of IBM's PC AT BIOS, including its protected mode services, are available. But one needs to read these really closely.) Thank you! |
We're looking for a lightweight alternative to dosemu2 for running some old dos-based compilers, however instantly hit a hurdle with emu2:
I can see from the code that this is explicit behaviour:
.. is this because it's a significant amount of work to implement? where would one even start if I wanted to try? or should I throw in the towel now :)
The text was updated successfully, but these errors were encountered: