EPROM Emulator Mk2

by Philip Pemberton

for the Olimex sponsored PCB contest

This is a simple 512kbit EPROM emulator based on a PIC16F877.

As far as features go, it's a pretty normal emulator. Access time is about 120nS, but you can get it down to around 90 if you use high-speed bus buffers and RAM. Upload time is about three seconds for 32K, or about five for the full 64K.

I suppose the other advantage is that the design, firmware and protocols are open. I did ask a few emulator manufacturers if they published the protocols for their emulators - almost all of them considered them to be trade secrets.

The other big advantage of having open firmware would be the tweakability.

Don't like something? Change it. Found a bug? Fix it. All you need is an ICSP-capable PIC programmer and some wire.


Component Selection Notes

In my prototype, I replaced the 74HC245s with 74ABT245s, the 74HC32 with a 74AC32 and the 4052 with a 74HC4052. This was done to reduce the access time of the emulator to around 90 nanoseconds.

The RAM may be difficult to source. Any 1Mbit SRAM with the same pinout as the 62LV1024 should be suitable as a substitute.

Circuit Description

RS232: The RS232 interface is provided by a Maxim MAX233 line driver (IC4). This device converts the +12/-12V levels on RS232 connector CN1 into +5/0V levels on the PIC's RXD and TXD I/O pins.

Reset Generation: The reset signals RESET and /RESET are generated from the main RST signal by a pair of transistors (one NPN, one PNP). When RST is low, the reset outputs are in a high-impedance state. When RST is high, /RESET is pulled low via transistor T1 and protection resistor R4. This causes the base of PNP transistor Q1 to be pulled low, which connects RESET (active-high reset) to TGTVCC (target's Vcc supply) via protection resistor R3.

The two 10-ohm protection resistors limit the current through the transistors to around 500mA maximum. This enables the transistors to pull the reset lines active quite rapidly, while still (hopefully) preventing them from being blown to bits if they are accidentally connected directly to the power supply. It is best not to attempt to test this protection circuitry unless you enjoy the smell of Magic Smoke (tm) escaping from semiconductor devices.

CPU: The CPU (IC2) is a Microchip PIC16F877 in-circuit reprogrammable FLASH MCU. Its clock is derived from 10MHz crystal XTAL, while in-circuit reprogrammability is provided by connector SV1.

RAM and emulation circuitry: A Brilliance Semiconductor BS62LV1024 1Mbit static RAM (IC1) forms the core of the circuit. Data is loaded into this RAM by IC2 and IC3, while bus buffers IC9, IC11 and IC12 are used to isolate the emulator from the target while data is being loaded into the RAM. The buffers also provide some damage protection for the RAM.

When data is not being loaded, control line /RUN is held low by IC2. This enables address buffers IC11 and IC12, which connect the address lines on the target connector to IC1. The two most-significant address bits are routed through a 4052 multiplexer to allow some simple pinout alterations to allow emulation of different target devices. The active input on the 4052 is selected by IC2 using the SELA and SELB control lines.

Quad OR gate IC7 is used to generate the enable signal for IC9. IC7b checks the state of the /CE and /OE pins on the target connector; if either is high, then the output of IC7b will be high. The output of IC7b is routed to one of IC7c's inputs, along with the /RUN control signal. This means that if the emulator is in Load mode (/RUN high) or if the target is disabling the emulator (/CE or /OE high), then the output of IC7c will be high. IC7c's output is connected directly to buffer IC9's active-low /GATE input.

Firmware description


  1. Set RST and /RUN high. Wait >1mS for target to enter reset mode.
  2. Set /READ and /WRITE high. Set /AHOE low.


  1. Place the most significant byte of the address on A7..A0 and strobe AHEN high for >1uS.
  2. Place the least significant byte of the address on A7..A0.
  3. Place the data byte on D7..D0.
  4. Strobe /WRITE low for >1uS.
  5. While there are still more data bytes to write, increment the address and go to step 3.


  1. Set /READ and /WRITE Hi-Z. Set /AHOE high.
  2. Set SELA and SELB to match the device to be emulated (see table in the schematic).
  3. Set RST and /RUN low.

Protocol description

Read in conjunction with "Protocol Guide.odt" (OpenOffice format).


  1. Send at least 300 NOP (0x00) commands to clear the emulator's input buffer.
  2. Flush the host's serial input buffer.
  3. Send "SET MODE" command with MODE=LOAD (0x00).


  1. Send repeated "BASIC WRITE BLOCK" commands until the emulator has been loaded with the desired data.


  1. Send "SET MODE" command with MODE=RUN (0x01).

All Files


EDA data

There's also another PCB - an interface board that converts the target connector into a panel-mount IDC34. It's only really useful if you use the same case I did though (a Hammond Manufacturing 1598BB). Let me know if you want it.


Protocol guide.odt (OpenOffice format).

Protocal Guide.pdf


Future improvements