Still haven't got very far with the PCB layout, mostly because KiCad refuses to acknowledge the presence of the footprint databases.
But I *have* started writing the firmware. Except for specific tests, I'm having to stick to documented NMOS opcodes, which is fun. The first order of business is initialising the CPU (assuming as little as possible), then the VIA and shift registers, then immediately checking to see whether we're dealing with a divided clock (in which case we have to activate the workaround). Then I initialise the display and show a title string - turns out "6502 Fake Finder" fits precisely across a 16-character line - and access the debug trigger address (though there's nothing behind the NMI handler yet). So far so good, and we don't even need to use RAM to get this far.
So the next item is a very simple RAM test. I write the self-address to every entry in zero page, verify it, then do the same with the bitwise inverse. With ZP proved, I then use it to indirect-index over the rest of the 8KB RAM with the same test, followed by a self-page test. If any of these tests fail, I display the failing address (two digits if it happened during the ZP test, four digits otherwise) and halt in a busy loop.
All of the above display routines are inline-coded. But once the RAM test is completed, I can use the stack and therefore subroutines, so there's now a simple series of display routines ready for use. Currently these are able to copy an arbitrary zero-terminated string from a given address to a given place on the display; I'll probably add something to allow scrolling the display too.
From there, I can start implementing some actual identification tests. I'll probably start with several pure-software tests that can distinguish NMOS from CMOS - the BRA opcode, the JMP ($xxFF) bug, the Z flag after $99 + $01 in decimal mode (with a sanity check to ensure decimal mode itself works), and the cycle count differences of certain instructions (measurable by way of the VIA timers). I can also safely test ROR for the early-production bug. After that, I can move on to distinguishing the different CMOS CPUs.
One of the trickier instructions to test for is WAI - next to STP, which is almost impossible to test from the "inside". For a start, $CB is the undocumented 2-byte "SBX" on NMOS, so it may be best to just skip this test (along with many other CMOS-specific tests) if the CPU has already been identified as NMOS. On WDC chips, it will pull RDY low until an interrupt occurs - which we can trigger at will through the VIA, and monitor the RDY signal into the bargain. On non-WDC CMOS 6502s, $CB is a single-byte NOP - except on the 65CE02, where it is the 3-byte ASW abs. So to identify a WDC CPU, we first have to either eliminate the 65CE02 as well as the NMOS, or cope with the fact that some bytes may be skipped and additional accesses made. Then we can use both a read of the VIA timers and a check of the RDY signal to see whether the WAI operations actually occurred.
On the hardware signal side, note the trace from PB7 (via PB6) to CA1. This allows the active shift register to be sampled at a chosen time when T1 runs down, not merely when the CPU gets around to it. By repeating a test with different sampling times and shift register setups, a complete "signature" of the CPU's external behaviour can be obtained and compared to what's expected of each known model. Figuring out precisely what *is* expected might be an interesting project for a long flight…
|