1-23-2023: Updated Elf Clone project to have the 1861 emulator have the ability to drive video out at the same time as driving a little 1.5" OLED display over I2C. The assembly code is ugly due to the manipulation of the incoming data and maintaining the timing for the video out. Also, added support for a more modern PIC18F26K40 processor (about $2) while keeping the old PIC18F2620 (about $6) up to date. The 1861 source code has been ported to the new Microchip XC8 as assembler (MPASM is dead) and the MPLAB-X project has been included.

Note: When downloading files, click the circled icon at the top of the new page to retrieve the file.



Elf Clone

Click on Images for larger versions

The pictures above show the clone running my old MAP (Memory Access Program) that I put into ROM on my real Elf back in the early 80s. If you click on the pictures and zoom into the left bottom you can see the tiny OLED display.

The video below named Elf Clone Update is running graphics6.hex. The C source is included with the C compiler below. The video named Elf Clone doing video is running graphicis8.hex running on an earlier versin of the clone. Both of these programs are written in C and run on an Elf with 4K or RAM. The run the same on my real Elf and my PIC based Elf Clone.

1802 emulator Code: B1802_18F.asm (V0.09 Debug, V0.16 Emulator: 7-23-2011) Old Version 0.14

1802 emulator Intel Hex for programming PIC: B1802_18F.hex (7-23-2011) Old Version

1861 emulator Code: 1861Emulator.X.zip (1-21-2023) (Old B1861_18F.asm (V0.07 8-21-2011))

1861 emulator Intel Hex for programming PIC: Latest in 1861 emulator Code (Old B1861_18F.hex (8-21-2011))

Schematic: ElfClone3.pdf (1-22-2023) older ElfClone2.pdf (11-09-2010) Old Version

Breadboard Layout: Layout.pdf (Note that the two RAMs are stacked on top each other with one pin lifted.)

Devices: PIC18F4620 for 1802 and PIC18F2620 or PIC18F26K40 for 1861 (My Pic Page)

Simulator Results: Simulator.zip

Hardware Results: HW.zip

1802Control.zip (V0.03 3-09-2010) PC side 1802 control program to download code for Elf Clone and also to access debug mode of the 1802 which allows new emulator code to be downloaded to flash memory and 1802 code to be written to the section of flash memory that is used to emulate a ROM.

  • This is a bus accurate full speed Elf created without an 1802 or 1861. This project is able to load a programs via dip switches and execute them. The image on the left is the final hardware soldered onto a proto board. The image in the center shows the solderless breadboard prototype with video output from the 1861 emulator while running my grfont3 program from "ROM". The next image is the SourceBoost (www.sourceboost.com/home.html) development environment simulating the code that emulates the PIC running the grfont3 program produced by my 1802 C compiler. I wrote plugins for source boost to emulate the hardware as well as dump a VCD trace of the simulation. The last image is the Nintendo DS touchscreen hex keypad I now use. Details of this keypad can be found on My Pic Page.

    • The simulator results file Simulator.zip has a value change dump of the simulator displaying video. The zip file also has a VCD Viewer that I wrote that can be used to load the VCD file and examine the bus cycles. With this tool it is possible to see the TPA, TPB, MRD, MWR and data bus signals that should look familiar. The goal is to keep the timing the same independent of the instruction being executed.

    • The hardware results file HW.zip has some hex dumps as well as my logic analyzer (My Pic Page) application that allows the hex dumps to be loaded which shows various cycles being executed by the "1802". These are early dumps before I wired up the Elf glue logic but show interrupt, dma and load operation on real hardware.

    • The PIC is clocked with a 7.16 MHz crystal which is 4x the rate of a standard Elf with Pixie chip. This gave me 32 PIC instructions per 1802 state cycle to get the job done. I use the internal PLL to multiply the clock by another 4 as the PIC needs 4 clocks per instruction. For most 1802 instructions this was cake but some were quite challenging as the PIC has to implement the instruction plus keep TPA and TPB going as well as implement the normal 1802 bus cycles not to mention the need to respond to the mode pins, DMA and interrupts.

    • I didn't use PALs for the glue logic to keep the price down (the programmer is much more expensive than the TTL parts). I estimate the cost to build this project at around $60. The PIC processors are $6 for 18F4620 and about $5 for the 18F2620. The programmer (PICKit2) costs $35. The other TTL, resistors and switches could be purchased for $10 to $15. Then some money for a piece of perfboard and wire to solder it all together.

    • Features:

    • The 18F4620 has 64K bytes of flash memory of which I use about 10K for the emulator. The remaining 48K of flash memory is used as a ROM that is copied to external RAM on entry into the reset state such that the 64K RAM in the clone can be initialized and treated as though it is a ROM. Turn off the power and it there the next day. No UV eraser required.

    • The RS-232 port of the PIC is used to access a DEBUG mode (when the ELF DEBUG switch is flipped) such that a host computer can download new firmware or ROM images for external RAM. This also allows external RAM to be written and read. This is very handy.

    • 0x68 instruction is used to allow 1802 to jump back into debug mode (0x68 0x00) or reset the chip (0x68 0x01).

    • Able to build an Elf with a single Mouser order. No need to track down antique parts.

    • Uses PICs capture/compare hardware to detect rising edges for display on and display off for 1861 emulator.

    • Implement a virtual RS-232 hardware interface via 0x68 instructions. Basically, allow 1802 code to access the RS-232 hardware in the PIC to allow 115K baud communication to a PC or terminal.

    • Touch screen hex keypad (My Pic Page).

My First Computer


Click Image for Larger View

Code: In ROM, on cassete tape, and on paper.

Schematic: Not translated. On paper

Device: CDP1802CD

This is my first computer. Actually, this is a repackaging that I did in 1984 of my first computer that I made in 1977. I have no pictures of the orignal machine which was constructed on perf board. The hex keypad is an addition that I made in 1979. Before that, I programmed in binary!

Logic Analyzer


Click Image for Larger View

Code: In Rom and on paper

Schematic: Not translated on paper

Devices: CDP1802CD processor and CDP1861CD video generator

This project is an 16 channel 1K deep 5 megasample/sec logic analyzer that displays the resulting waves on a TV set or monitor. There are two boards. The one that is visible is the logic analyzer made from surplus TTL parts and some fast static RAMs (4 1K by 4-bit). The lower board uses the 1802, 1861 and more TTL and CMOS parts to implement the user interface. The 16 toggle switches on the front select the trigger event for each channel (1,0 or X center off). The switch on the far left selects which edge of the event to trigger on. The red pushbuttons control arming the trigger and displaying the results on the screen.

I won The Ohio State University design contest with this device during my last year of undergrad (1985).

Cassette Interface

Follow this link to my PIC processor page for details: Cassette Interface



Windows: TedsElf.zip Version 0.19 (9-8-2009)

This program emulates my first computer described above. Get ROM Code and Tubes below for a cheap thrill. The 8 LEds above the keypad are the PORT 4 display that I use. The lit LED above that is the Q LED. The [Y[[[KK display at the top left is my 7 digit ASCII display. See Clock below for a program to make it wiggle. The S and H keys on the keypad do nothing. The L key is the Input key (Load button). I assert EF3 on any hex key down and EF4 on the input key down. The Auto Load switch will pulse the input button every other hex key press.

To load a simple program using the Hex key pad. Click Reset, then Load, then key in 7 B 3 0 0 0. Then click Reset then Run after making sure the run addresss is set to zero. The Q LED should light. For more fun, repeat the procedure but use:

E2 F8 01 B2 13 93 52 64 22 30 04

I use the windows timer function (interrupts) to update the gui at a rate of about 50 frames per second. After each update I let the1802 run for about 2000 instructions. I foget the exact numbers but I set it up to match the speed of an ELF running at 3.58MHz/2. The video animation rates seem to match my real machine pretty well and run smoothly. I simulate the 1861 interrupts and DMA access (and EF1 pulse) so that the frame buffer and resolution can be controlled under software control like a real machine. I've only tested 64x64 (difficult) mode and 64x128. I have not tested 64x32 mode but I expect it to work. I used 64x128 mode for my Logic Analyzer above in the Hardware section.

The Debug Control window shown above can be opened up by selecting the View menu then selecting Debug Window. A single break point can be set and then the processor can be single stepped. The display shows the processor stopped in the video interrupt routine (P=1) with the 1861 Pixie chip currently set to DMA the line starting at address 0x01b0 (R0). It is not real pretty, but if you have the assember listing up next to this debugger window it makes it pretty easy to debug programs.

The file load function accepts hex files produced with my Assembler below which will include a run address and and optional description. Intel hex file format is also supported but there is no way to embed the start address or description.

C Compiler

Windows Command Line plus examples: cc1802.zip Version 1.03 (7-21-2012)

Linux Command Line plus examples: cc1802.tar.gz Version 1.00 (3-09-2010)

The output is a single .s file that can be assembled with the assembler below.

Usage: cc1802 [options] filename

-I include_dir Add include_dir for directory search

-elf_os Produce code to run under Elf/OS (starting at 0x2000)

-rom Generate code for a ROM

Requires use of -data_start and -code_start and

optionally -video_start and video_size for video

space and optionally -stack_size

-nlb Use no long branches (required for 1861 video)

-mem_config Config Set memory configuration (Default is 0)

0: {Stack, Program} (Set stack size)

1: {Program,Stack} (Set stack size)

2: {Video,Stack,Program} (Set video size, and stack size)

3: {Stack,Video,Program} (Set video size and stack size)

4: {Program,Stack,Video} (Set stack size plus video size and optionally video start)

-stack_size Size Size in bytes (default is 256)

-video_start Addr Address to start video memory (should snap to page)

-video_size Size (default is 512 for single 64x64 display buffer)

-mem_start Addr First address to populate (default is 0)

-code_start Addr First address for instructions (rom mode only)

-data_start Addr First address for stack and data (rom mode only)

The -mem_config and -video_start exist to get the code to run on different systems where monitor programs trash memory while loading programs. My monitor uses page zero for variables and page one and two for video memory, so I use -mem_config 3 and use the defaults. This places the stack in page zero and 1861 video memory in pages one and two. The program starts at location 0x0300. For programs that do not use video memory, use -mem_config 0 -stack_size 0x300 to give 768 bytes of stack and a program that starts at location 0x300.

Programs that use the 1861 must use the -nlb option so that no long branches are generated. My work-around to this problem is a little ugly but does the job.

Check out the example flags.c to see how to deal with input and output ports as well as the external flags and Q. Here is the source:

void main()


unsigned char input,flag4;


flag4 = EF4;


input = INP4 & 7;

if(input==1) Q = 1;

if(input==0) Q = 0;


OUT4 = (Q<<7) | (input<<4) | (EF4<<3) | (EF3<<2) | (EF2<<1) | EF1;



A word of caution about syntax errors. Please fix the first error encountered as currently the compiler does not recover very well from a prior error so it may complain about a valid line because it is in a confused state. The biggest problem that may show up is forgetting to declare a function as returning a type. All functions must be declared to either return a defined type or void.

Features that still need to be implemented

  • Conditional operator a = (b>3) ? 25 : 17;

    • I'm not sure how to do this but it seems like the equation engine has to deal with this.

    • Similar to if(b>3){ r7=25 }else{ r7=17}

    • I hope this is very similar to implementing function calls and arrays in equations.

  • Implement a+=3, a-=3, a*=5 ...

  • Finish up remaining keyword implementations

    • goto plus lables

    • sizeof

Features that are not currently supported but may be one day

  • handle double triple .. arrays [][][]

  • handle structures and typedefs

  • Handle long

  • Handle float


Windows Command Line: AsmDsm1802.zip Version 1.00 (3-09-2010) / Version 0.22 (12-10-2010)

Source: AsmDsmSource.zip

Manual: asm1802.html (view)

Three output formats are supported (-format_intel outputs intel hex format, -format_ted outputs hex format for TedsElf emulator, -format_elf_os outputs binary format for Elf/OS).

I grew up programming my Elf in Hex as it was my only computer. Now that I have other machines I broke down and wrote a lame disassembler and assembler. I do not like the mnemonics that RCA came up with so created my own which for me are easier to use. The assembler supports RCAs mnemonics as well so you don't have to use the new names. For example, I use ld instead of LDN, LDA, LDX, LDXA, LDI, GLO and GHI and figure out what op-code to generate based on the source format. Here are some examples:

0032 0x001c 0x43 ld *r3++ ;LDA

0033 0x001d 0x05 ld *r5 ;LDN

0034 0x001e 0xf0 ld *rx ;LDX

0035 0x001f 0x72 ld *rx++ ;LDXA

0036 0x0020 0xf8 0x09 ld 9 ;LDI

0037 0x0022 0xf8 0x0a ld Piddle.0 ;LDI (Low 8 bits)

0038 0x0024 0x8e ld r14.0 ;GLO

0039 0x0025 0x97 ld r7.1 ;GHI

Around 1990 I wrote an assembler for a TI DSP that used a similar format (TI's invention not mine) but I think it is much easer to read and understand what the code is doing. See my TI DSP projects here.

The disassembler can read Intel Hex format or my annotated Hex format that comes out of my Cassette Interface project (above) which uses a PIC processor. Every geek should learn about these parts as they are a way of life.

Simple little program to get the PORT 4 LEDs to count

.title "Count"

.desc "This program counts using the output"

.desc "display."

.start Main ; Start address

.org 0x0000

Main: sex 2

ld 1

st r2.1

Loop: inc r3

ld r3.1

st *r2

out 4

dec r2

br Loop

ROM Code

Source: None yet. I only have a file dump from my cassette interface as the source is pencil and paper

Hex File: Rom.zip

This project contains the monitor program shown in the picture above for my first computer. It also contains functions to draw circles, lines, boxes, do a little math and drive the ASCII display. This code is required to run most of the programs.

To run the monitor, start execution at address 0xf000. Turn off the auto load function and use the 4 and 6 keys to select the desired function. For the emulator, only Edit, Find, Move and Run make sense. Once the desired selection is lit pulse the Input key (L on the emulator). For Edit, enter a 4 digit address to edit. The 2,4,6 and 8 keys control the cursor position. Use E to exit. Pulse the Input switch to enter edit mode. When in Edit mode, enter hex digits to change memory. When finished, pulse the Input switch to return to cursor move mode. Click the E to exit then select RUN and enter a 4 digit run address followed by pulsing the input switch to confirm in order to run code at the selected location.


Source: Tubes.s (Translated from notes. Originally written in 1985)

Hex File: Tubes.zip

This program draws circles on the screen with a trail that is erased as the code runs. This program requires the ROM Code to run. Run the program from address 0x400. For the emulator, first load the ROM code then Tubes.hex and click the Run button.


Source: None yet. Currently just pencil on paper (I wrote this back in 1985)

Hex File: Hinge.zip

This program draws a big hinge on the screen with a trail that is erased as the code runs. This program requires the ROM Code above to run. Run the program from address 0x400. For the emulator, first load the ROM code then Hinge.hex and click the Run button.


Source: Clock.s

Hex File: Clock.zip

This program uses the real-time clock at location 0xd000 to 0xd004 to display the current time on the ASCII display. This program requires the ROM Code above to run. Run the program from address 0x300. For the emulator, first load the ROM code then Clock.hex and click the Run button. It is not possible to set the time using the emulator as the emulator gets the time from the Windows OS.