EWM Update: Illegal Instructions
Today I found out that ProDOS 2.4.1 crashes in my Apple ][+ emulator. Very early on when booting a disk, even before it displays the welcome screen. This is odd because ProDOS 2.4.1 is supposed to be compatible with any Apple II model that has 64KB of RAM.
After some sleuthing I figured out what is happening here. The big hint is what the emulator prints:
CPU: Exited because of unimplemented instruction 0x1a at 0x2095
This is a good hint. The Apple ][+ uses a 6502, and for that CPU there
is no instruction with opcode 0x1a
. It does exist on the 65C02,
which later models of the Apple II family use, where it is the INC
,
Increment Accumulator, instruction.
ProDOS 2.4.1 is supposed to run on all models, including the 6502, so why is this happening? Are we trying to execute some random invalid code in memory or is there something else happening?
Looking at the code around 0x2095
we can see this:
...
2093: A9 00 LDA #$00
2095: 1A ??? ; Invalid on 6502, INC on 65C02
2096: D0 11 BNE $20A9
...
It is now pretty clear what this does. This is code to detect the CPU type.
On a 6502 the $1A
instruction is invalid, but it does does not halt
or interrupt the the CPU. On the 65C02 it increments the
accumulator. The above CPU detection code takes advantage of that: on
a 65C02, the accumulator wil increment to 1 and the branch to $20A9
will happen. On the 6502 the accumulator stays zero and the branch
will not happen.
The problem is that my emulator does not handle illegal instructions
correctly. It incorrectly triggers an interrupt, which puts the
program counter at 0x03FE
, which is what we see in the screenshot
too.
(Ending up at 0x3FE
is actually not correct since the interrupt
handler is at 0x03FB
. So maybe that is another bug.)
I fixed this with a patch that does two things:
I brought back the
--strict
option for the emulator. If--strict
is enabled, then the emulator will immediate abort if it encounters an invalid instruction. This is not correct behaviour, because the 6502 does not actually do this in real hardware, but it can be used o verify that programs are correct.I aliased all unimplemented 6502 instructions to
nop
. So they are simply ignored. This is also not entirely correct because some of those instructions have undocumented behaviour that some programs may take advantage of.
For now this is a decent fix. ProDOS 2.4.1 boots again. Maybe some day I will try to implement the undocumented behaviour of the 6502.
If you are interested in playing around with my emulator, you can find the project at github.com/st3fan/ewm.
Most of my professional and personal work is Open Source. You can find many projects at github.com/st3fan - feel free to leave a bug report or open a feature request.