Bravo, Peter, tour de force! You da man.
A few comments and perhaps some interesting background for some folks here: I've been involved with more than a few reverse-engineering activities on (P)/ROM firmware in my past.
In one case, we used a shop that used fuming nitric acid to 'decap' the plastic (epoxy) DIP packages. Ugly job, but there are co's that do it - not just for reverse engineering but for product failure analysis, etc. Cost us about $400 total to decap 3 chips and photomicrograph the dies.
In this particular situation, unfortunately, the parts we really cared about had EPROM not mask ROM, and we couldn't get the data out (not enough chip info, semiproprietary part/pinout, address mappings, etc. These were Japanese Motorola/Toshiba custom flavors of 68HC11s.) The parts we didn't care as much about were 4-bit CPUs w/mask ROM and there were no equivalent E/PROM microcontrollers available except special eval board stuff so we couldn't do retrofits even if we'd taken the time to extract ROM data. FPGA/CPLD stuff today could've changed this perhaps.
Getting data on Japenese lower-end microcontrollers tied with Japanese products is quite difficult. These are not always 'custom' parts but they never make it into databooks.
Many of these parts are not sold in US or Europe either (esp 4-bitters and some of the low-end 8-bit variants).
On chips with smaller much feature sizes, the glass passivation layer can interfere with reading ROM contents; if the ROM metallization layer is not in the top 2 layers life can be hard too, looking at the bits. Sometimes ROM row/column lines are staggered or are in funny order too - do not have directly incrementing address relationship vs. #rows/#columns traversed.
However, we've had success with quite a few EPROM microcontrollers in the late 80s/early 90s. Many had "security bits" that were subvertible - in some cases on 8051 variants, the EPROM security bit(s) were not latched except at full reset, so booting the CPU 'wild' - straight power up w/no forced reset - allowed external program to, after awhile, get control of the free-running CPU, deal with /EA ROM-bank toggling and have external program begin to fetch & emit internal ROM data. Later revisions of these parts latched the /EA (external access) pin at power-up, not reset.
CPUs that offer either 'ROM verify' (but no readback) or even 'encrypted verify' as an option (and left enabled by mfgr in shipped product) allow a scripted EPROM/CPU burner to verify against a ROM image constructed "on the fly". Sometimes a bit of logic is needed to reset targeted CPU each pass (one pass per byte; each pass has to start back from $0000 again and verify upward to the next new byte to test.) In theroy this process could take 256*ROM_size passes, and is thus time consuming and can take overnight (depending on size of PROM area & speed of burner verify pass & communications speed). Using byte test sequences sorted by some prior knowledge of avg opcode/operand frequency (or a 2nd-order predictor - knowing some opcodes, likely operands can be chosen with higher degree of confidence) instead of just trying $00...$FF can speed things up. PROM data read back as 16 bit words would be a real b*tch to deal with since 65536 possibilities per location: set the process running and go on vacation.
Even with encrypted verify - where the data read out is still encrypted - these are usu simple XOR/XNOR masks with a short key (16 or 32 bytes), and the typical mask string has something like ***5/89 ACE CO./ ROBERT SMITH *** - that is, the key has a partially known or partially predictable plaintext. Key values that are unknown can be examined by checking decrypted/disassembled code for sensibility and checking for ROM checksum (often $00 or $0000).
Happy hacking!
Bill Wiese
San Jose, CA