created 24.01.2016, last changes: 06.03.2017 ps

>>> COP400 ROM dumper <<<

Deep inside Apple's Lisa live two COP421 microcontrollers. These are members of National Semiconductor's COP400 ("COPS II") 4 bit microcontroller family. The COP421 comes in a DIP-24 package and has 1024 bytes mask ROM, 64x 4 bit RAM, a simple timer and 16 I/O lines. Not much from today's point of view, but this is a 1977 NMOS design! A detailed description of these devices can be found in the 1988 National Semiconductor Microcontrollers Databook.

COP420 block diagram

Note that a byte is always eight bits, even in a 4 bit architecture.

In 1977 there was no FlashROM, and EPROM technology required a high-voltage process and expensive ceramic packages with UV permeable quartz glass windows. For cost-optimized mass production, metal mask ROM was the only option. Apple used two different ROM masks in the Lisa: COP421-KPK/N controls the controls the spindle motor of the Widget hard disk drive, and COP421-HZT/N is located on the I/O board and takes care of keyboard, mouse and time of day. In case you should ever need to replace a COP400 microcontroller, make sure to get the right ROM mask, indicated by the three-letter code.

COP400 Test Mode

Every electronic device needs to be end-of-line tested before shipping. This includes integrated circuits -- many things can go wrong during diffusion, metallization and packaging. So there has to be some kind of algorithm that allows ROM mask verification. And yes, the 1988 National Semiconductor Microcontrollers Databook contains two application notes that describe test procedures.

Test mode is entered by pulling the SO pin high with a 100 Ω resistor. During normal operation, SO is the output of the Serial I/O shift register, and it is low after Reset. This separates the Instruction Decode block from the ROM Program Memory (see block diagram above) and connects one of these to the Port L Drivers. Now we have two options: either we can insert instructions into Port L, which will be executed as if they would come from ROM (including incrementing the PC), or we could monitor the ROM contents without executing anything. The level at the SI pin decides what to do. High means instruction mode, low means ROM dump mode. The whole procedure is described in Application Note AB-4. Sounds easy, isn't it?

On the left COP400 ROM dump sequence from AB-4, 1988 National Microcontrollers Databook, on the right cycle timing from COP421 datasheet. tPD0, tPD1 can be up to 1 s. That's jitter! Click on the diagrams to enlarge.
COP400 ROM dump sequence from National AB-4 Cycle timing from COP421 datasheet

No, it isn't. There are two issues that render this task more difficult than expected. At first, timing. All input level changes have to be related to the SK pin, which provides an Instruction Clock signal. This pin is an output with a very bad slew rate. When inserting instructions, the L lines have to change 0..200 ns after the falling edge of SK. Second, which is not so clear in the beginning, there are a couple of errors in the timing diagram given in AB-4 FIGURE 3. And finally, there is a minimum clock rate of fCKI = 1.6 MHz required in the datasheet. Like most NMOS devices, the COP400 seems to use dynamic memory for its internal registers.


COP421 with R8C module Can we implement this in software on a microcontroller? There are two big issues: the latency from detecting the falling edge of SK to setting Port L would be much bigger than 200 ns, and the maximum clock frequency that could be achieved by toggling a pin would be around 500 kHz. This is 1/3 of the minimum required according to the datasheet.

Despite of the timing diagram given in the COP421 datasheet (see above), the block schematic indicates a fixed divider between CKI and SK. Therefore a preliminary test has been done: a 1 MHz signal has been applied to the CKI pin, the controller was set into test mode, and SK was observed with an oscilloscope. And there was a rectangular waveform with very bad risetime, acceptable fall time and exactly 1/16th of the clock frequency! An 1 kΩ pullup resistor at SK fixed the risetime, and now it was clear that all timing could be synchronized to CKI instead of SK. And we generate CKI ourself whereas we can only monitor SK. Now 500 kHz is still too slow compared to the 1.6 MHz reqired in the datasheet, but this is worth a try. Usually there is plenty of margin at room temperature -- a R6502 which is rated at 100 kHz to 1 MHz works fine at a couple of kilohertz.

The COP400 ROM dumper consists of a Renesas R8C microcontroller that connects directly to the COPS Under Test ("CUT"). A generic module has been used which contains a R8C/348G controller, a FTDI FT232R serial-to-USB bridge, optional voltage regulator and support components. The CUT is placed onto a piece of prototype board and wired to the R8C according to the following table:

signal COP421 pin R8C module pin R8C pin
VDD 9 JP1.1, JP2.1
100 nF + 47 F to Gnd
Gnd 1 JP1.24, JP2.24 -
CKI 3 JP2.5 P2.1
/RESET 4 JP2.2 P2.4
SK 16 JP1.21
1 kΩ to VDD
SO 15 100 Ω to VDD -
SI 14 JP1.23 P2.5
L0 13 JP1.12 P0.0
L1 12 JP1.11 P0.1
L2 11 JP1.10 P0.2
L3 10 JP1.9 P0.3
L4 8 JP1.4 P0.4
L5 7 JP1.3 P0.5
L6 6 JP1.2 P0.6
L7 5 JP2.23 P0.7

This is more or less a disposeable setup. After both COP421 masks have been recovered, I don't think I will ever need it again. Therefore it is only a quick & dirty mockup.

COP400 ROM dumper setup. Top and bottom view.
top side bottom side

The whole test sequence has been implemented in software. At first, /Reset and SI are set low and clock cycles are generated for approximately 130 ms. This allows the controller to stabilize. SO is held high by the 100 Ω resistor. Then SI is set high to switch into instruction insertion mode. Again clock pulses are generated while monitoring SK, until the second rising edge is detected. Now the software is in sync with the rising edge of SK -- this is where the instruction byte should be applied to Port L. /Reset is deasserted and after 16 clock cycles (one SK period) the first instruction is applied. Again, 16 clock cycles, and the next instruction. This goes on until the whole test program has been transferred. The last command is a NOP (0x44), and in the middle of the low phase of its SK cycle (i.e. after 11 clocks) SI is set low to enter ROM dump mode. The following program code has been used:

 xxx:  00     CLRA           ; clear A. Every COP400 program has to start with this instruction.
 xxx:  63FC   JMP 0x3FC      ; set PC to 0x3FC
 3FC:  BF     LQID           ; transfer a ROM constant into Q. Usually this is indirectly addressed, but
 3FD:  44     db 0x44        ;   as ROM is disconnected, we have to provide the value here.
 3FE:  3364   LEI 0x4        ; set EN2 bit, which configures Port L as output with the value given in Q
 000:  44     NOP            ; we apply the same value from the other side...
        ... and set SI low to enter ROM dump mode at PC = 0x000.

Note thet the opcode for LEI 0x4 is 3364, not 3344 as stated in the application note. Besides that, SI must be switched low during the SK low phase of the NOP instruction itself, not in the next cycle. With the timing given in FIGURE 3 of AB-4, the ROM dump would start at address 0x001, i.e. the first byte is missing. Even with unknown ROM code, it is possible to recognize this condition because every COP400 program has to start with a CLRA (0x00) instruction. The correct timing is shown in the oscilloscope screenshots below:

Instruction insertion and start of ROM dump. Channel 1 is SK (instruction cycle clock), channel 2 is SI. Digial channels 0..7 are Port L lines. Click on the images for full-size versions.
timing - instruction insertion detail
Detail view of instruction insertion cycle (left) and switch-over to ROM dump mode (right).
detail detail

The ROM dumper program reads 2048 bytes which is the maximum size for the COP400 architecture. This means for a COP421 the ROM code will appear twice, but in case a 2 kB COP444 needs to be dumped this will also be possible. The microcontroller is operated at an average clock of 500 kHz, which is outside its specification. However, as expected before there is a lot of margin. During my experiments the clock could be stopped for nearly one second before the controller died and required a /Reset to come back.

Design Ressources

Both Lisa COP421 controllers have been dumped, I have send the image files and disassemblies to Therefore I don't expect anyone to feel the necessity to recreate my setup. I will keep it for some time (until I need the parts ;-), so just contact me if you have a controller to be read. Anyway, here are the project files:

a) Renesas R8C module. This is the same board as used for UsbWidEx.

b) Object code.

The smallest R8C/34 with 32 kB can be used here, the program is very short. Besides UART0, no special periphery is used. Therefore the code should run on other R8C types, too. Refer to my UsbWidEx article for a description of the flash procedure.

Dumping a COP421

Here is the recording of a sample session, just to give an impression of the user interface. The R8C board is connected to an USB port and a terminal window has been opened for the virtual COM port. With Windows 7 / 64 bit I use TeraTerm. The RS-232 settings are 57600-8-1, no handshake. After the first keypress, the welcome message appears:

COPSreader V0.99
 (c) Patrick Schaefer, 2016

  1 - read COP400 ROM
  2 - print hex dump
  3 - print Intel Hex file
Select function: 

Pressing "1" starts the ROM read sequence.

reading COP421 ...done.

Now the ROM mask has been transferred into a buffer. It can be printed either as a hex dump

COPSreader V0.99
 (c) Patrick Schaefer, 2016

  1 - read COP400 ROM
  2 - print hex dump
  3 - print Intel Hex file
Select function: 2

Data Buffer:

0000: 00335F326BEC20CC 324F22CD4F2162F8 .3_2k 2O"O!b
0010: 6A5620D98C2D7F7E 8F684069FA687768 jV ٌ-~.h@ihwh
0020: 406924684041EB6A 7B69BE68FFD96019 @i$h@Aj{ih`.
0030: 7361697369737361 6173736973696173 saisissaassisias
07E0: AA33616329336DAA 336563290F005F06 3ac)3m3ec).._.
07F0: 153600160034ED61 E52300063FAB3360 .6...4a#..?3`

or in Intel Hex format for further processing

COPSreader V0.99
 (c) Patrick Schaefer, 2016

  1 - read COP400 ROM
  2 - print hex dump
  3 - print Intel Hex file
Select function: 3


That's all. Note that always 2048 bytes are read. Therefore the ROM contents of a COP410/411 will repeat four times, a COP420/421 two times and only a COP444 will fill the whole buffer area.

I did not find a freeware disassembler for COP400 microcontrollers. In fact, I did not find any at all. There seems to be some kind of COP400 emulator inside the MAME arcade machine emulator code. So if anyone wants to write one, this may be a starting point. The two Apple masks have been disassembled manually. This is more or less a find & replace job. Every hex number represents an instruction, except for 0x60..0x6F and 0x33 -- these are two byte instructions. Each COP400 program has to start with 0x00, empty space is 0x00, and NOP is 0x44. Alfred's as assembler can be used to convert the disassembly back into COPS code. For a plausibility check, or if someone wants to design a new ROM mask. Have fun!

An Update: In January 2016 there was no COPS400 disassembler -- well there is one now :-). Analyzing some HP-IL peripherals (which also use National microcontrollers), Dr. Vassilis Prevelakis wrote cop4disass, a disassembler for the COP402. The source is on github: cop4disass produces output compatible with the as macro assembler.

COP4 Emulator Boards

To allow software development and testing, National offered thee ROMless COP4 devices: COP402, COP402M and COP404L. These have a DIP-40 package. 28 of the 40 pins provide the same function as for a COP420, the other twelve connect to an external 2kB 2716-type EPROM. Address and data lines are multiplexed, therefore a 74LS573 is needed to latch the lower address byte. All three ROMless devices are similar, but there are small differences that could have an impact on their ability to replace a given mask ROM controller:

Type internal
Vcc range max. clock frequency
cycle time
COP402 64 x4 bit up to 1 kByte 4.5 to 6.3 V 4 MHz, Crystal /16
(> 4 s)
COP420, COP421, COP422
COP402M 64 x4 bit up to 1 kByte 4.5 to 6.3 V 4 MHz, Crystal /16
(> 4 s)
COP420, COP421, COP422
with Microbus option
COP404LSN-5 128 x4 bit up to 2 kByte 4.5 to 5.5 V 2 MHz, Crystal /32
(> 16 s)
COP444L, COP420L, COP421L
low power devices

Here are two emulator boards that allow substitution of 28 pin resp. 24 pin mask ROM devices with a 40 pin ROMless device plus EPROM. They can be used to test software modifications, trace program flow by monitoring the ROM address lines, or just to replace broken COP4 mask ROM chips. Use a COP402 to substitute 4 MHz COP420/421/422 and a COP404LSN-5 as a replacement for 2 MHz low-power devices.

Emulator boards for 24 pin and 28 pin devices.
28 pin emulator board 24 pin emulator board

There is no schematic diagram, the wiring is exactly as recommended in the COP404L datasheet. I have used a 74LS (or 'HCT) 573 instead of the 74LS373 because its pin order made routing easier. For the EPROM, either a 2716 or 2732 with access time below 1000 ns (yes, one microsecond!) can be used. With a 2716, set the BANK jumper to the Hi position (connecting /PGM to VDD). For a 2732, use it to select the upper or lower 2k bank (A11 high or low). Testpoint TP1 is Gnd, TP2 is VDD. Fit 10 .. 47 F / 16 V for C1 and 100 nF for C2 and C3.

Note that the 74LS573 is upside down and needs to be fitted below the EPROM, which of course has to be put into a socket. If yu use a COP402 controller, duplicate the ROM image to fill the whole 2 kB area of the EPROM. This is because A10 is driven from pin 32 of the controller socket. For a COP404L this is A10, but the COP402 uses this pin to provide a SKIP signal that indicates a contitional branch (SKIP instruction) has been taken. Therefore this pin can be high or low depending on the program flow. Duplicating the 1k ROM image makes A10 don't care, i.e. the controller will address the same memory location for both states.

Standard COP4 controllers have a minimum instruction cycle time of 4 s, i.e. a maximum clock frequency of 250 kHz. CPU clock is generated by dividing the external clock source (crystal, RC, TTL signal) by 16, by 8 or by 4. This ratio is set by ROM Option 3. The ROMless devices have a fixed ratio of 16 (COP402) or 32 (COP404L), therefore your emulator might need a different clock source than your target. For that case, a Pierce tank circuit is provided on the board. Chose the components according to the required frequency.

X1 / MHz R1 / kOhm R2 / MOhm C4 / pF C5 / pF from datasheet
4 4.7 1 22 22 COP420
3.58 3.3 1 22 27 COP420
2.097 8.2 1 47 33 COP420
2.097 1 1 56 6..36 COP404L

In case you prefer the Colpitts circuit shown in earlier revisions of the datasheets, cut the traces between C5, X1 and R2 and re-wire them accordingly. On the bottom of the PCB are two solder bridges that connect CKO and CKI either to the tank circuit or to pin 2 and 3 of the target connector. The pictures below show an assembled COP421 emulator board used to replace the COP421-HZT/N on the I/O board of a Lisa 2/5.

COP421 replacement board (left), fitted to a Lisa 2/5 (right). "1820-4073" is the Hewlett packard part number for a COP402 and "1818-3160" is a National NMC27C16-45 in disguise.
front and reaw view installed in Lisa IO board

As usual: I will give absolutely no guarantee that the software or circuit will work as described, that it will not destroy your computer, the circuit itself, or any peripherials connected to it. I also refuse any responsibilty for data losses resulting from the use of this software and circuit design. It's freeware. If you want some guarantee, buy a commerial product. It is explicitly prohibited to use the software and circuit described here in places where failure or malfunction may be dangerous to the health or result in monetary losses.

COPSreader and the COP4 emulator layouts are copyright (c) by Dr. Patrick Schfer, 2016 - 2017

Apple, Lisa and the COP421-KPK and -HZT masks are (c) by Apple Computer Inc.

----> Back to my home page

This page is hosted at John, a server of the Computer Club der RWTH Aachen e.V. Validated by HTML Validator (based on Tidy)