What happens if r/m=4, SIB.base=EBP and SIB.index not being ESP? Is EBP+index*scale still used in that case?
Edit: Just made the instruction decoding of the SIB byte more in line with the other instructions.
It will now perform the base and index, where the base may be omitted (for the [disp32] case), otherwise suffixed with a '+' before the index part). The index part, if used (non-SP), will give a simple reg*1/2/4 followed by a displacement (not if MOD=0 with non-EBP base). For ESP index, it will be either a simple base (if a non-[disp32] base is used (selected by MOD=0 with EBP base) or an offset from the base (when a base exists, so the MOD=0 with EBP base doesn't apply).
So some example outputs now:
EBP+EAX*4+08 (reg with 8-bit displacement, mod=1)
EBP+EAX*4+12345678 (reg with 32-bit displacement, mod=2)
12345678 (this is the case of MOD=0, EBP base and index ESP. Since the no base applies here, the + isn't prefixed, and the ESP doesn't output any index disassembly (not calculates it, just the base is returned))
ESP+08 (base ESP, index ESP with 8-bit displacement, mod=1)
ESP+12345678 (base ESP, index ESP with 32-bit displacement)
EBP+EAX*4+12 (base EBP (because mod=1), index EAX with 8-bit displacement)
EBP+EAX*4+12345678 (base EBP (mod=2), index EAX with 32-bit displacement)
Edit: OK. Verified it with the test386.asm testsuite (which AFAIK checks all modr/m memory inputs and outputs using SMC). It checks out (together with the 80386 instructions tests) without errors.
Then what is going wrong with the emulator? If test386.asm can't find any errors, what is the cause of JJ2 crashing (together with Windows 2000 and newer failing to boot)?
Edit: Hmmm... Even though Windows 95C boots, it can't seem to properly find the onboard PCI IDE controller anymore (the hard drive itself is in legacy INT13 mode) of the i440fx motherboard? That shouldn't happen?
Edit: OK. I modified the PCI vs legacy settings on the PCI interface a bit (based on just the 41/43h registers now):
- Setting bit 7 of those registers (or bit 15 of the word registers) now enables it's legacy mode (disabling PCI mode). The enabled bit in register 04h is still used to disable the entire controllers connected.
- Clearing bit 7 of those registers (or bit 15 of the word registers) now enables PCI mode, converting the device into a full PCI-compatible device (with the BAR0-3 registers activating as expected).
- Clearing bit 0 of register 4 disables the entire controller as expected now (also effecting it when it's in legacy mode). The IDE register range occupied by the controller will now also disappear from read/write accesses accordingly. Although the legacy IRQ lines are still connected in this case, the PCI lines are properly lowered. I don't know what the behaviour of the real device is in that case.
So basically, setting bit 7(or 15 depending on the size of the register addressed) turns it into a legacy port, while clearing the bit puts it into PCI mode instead. Both ports can be set individually. If the second port is set to PCI mode and the first port to legacy, the hardware will move the second port BARs to listen to the first port BARs instead (so instead of programming BAR2&3 you need to program BAR0&1 for the second port when 41h=80h and 43h=00h for example).
Edit: Windows 9x seems to like the controller for now (with of course both controllers enabled in the BIOS to detect and boot from it while it's setup to the onboard controller in the emulator settings).