Skip to content

Half-baked Benchmark

I jury-rigged a dhrystone benchmark for the 1802 at 10MHz. It clocked about 150 dhrystones per second compared to my best previous result of 81/sec for an 1806 at 4MHz. For comparison, a Z80 at 4MHz can do 300/sec but with a much better compiler.

Biggest problem in adapting it was to have the AVR be fast enough to grab the report output from the 1802. I had to put a ton of nops in the 1802 print routines. Not sure if this affected timing.


Overclocking Failure Modes

Using my simple two chip circuit, I wanted to investigate what happened when an 180x ran over its clock limits. I tried my oldest chip, an 1802CD and a newer 1802ACE.

I was running a program equivalent to the following;

0000 LBR FF03
FF03 LBR 0000

This was all actually in the first 6 bytes of an NVRAM with all except the first 3 address lines pulled low.

The reason for this code was to force the 1802 to run in two pages alternately because there was reason to believe that getting the high order address byte correct could be an early failure point.

The first three images show the 1802CD running at 2 and 4 MHz and failing at 6.  In the 2 and 4 MHz cases, keying on the TPAs, you see the init cycle then fetch from 0000, execute 0001, execute 0002, fetch FF03, execute FF04, execute FF05.

17-10-14 CDP1802CD 6MHz zoom

At 6 MHZ it is going through the motions of fetch/execute but i don’t think it’s doing anything sensible. The first fetch is from something like xxxxx000xxxxx111, the subsequent execute reads something like xxxxx000xxxxx001 then it might be trying to fetch from xxxxx010xxxxx111 but the high address is gone before the TPA negative edge.  I think it has just lost it’s sh*t.  Presumably there are a whole bunch of things going on in the chip which are keyed off clock pulses and each with its own calculus of rise and fall setup and hold times. As long as the clock pulses are reasonably far apart it all works but if you crowd them: chaos ensues.

It should be noted that this 40 year old chip has a maximum clock frequency of 2.5Mhz at 5V so it’s a testament to engineering conservatism that it holds together at 4MHz. There still could be a bunch of failures that don’t show up in this simple test but I know from earlier experiments that this chip will execute arbitrary code properly at 4MHz.

Turning to a later version of the chip, the CDP1802ACE is rated for 3.2 MHz at 5V.  In this simple circuit and test it runs fine at 12 MHz and fails at 16 MHz(I don’t have an intermediate frequency resonator). The image below shows it in at 16MHz – it is doing fetch/execute but the address is stuck at xxxxx000xxxxx110. It’s worth noting that even here the high and low addresses are on the bus correctly with respect to TPA.

17-10-14 CDP1202ACE 16mhz
below for the record is the same test at 12MHz which looks fine to me. I have not yet tried this chip with real code in a real circuit.
17-10-14 CDP1202ACE 12mhz

One other learning in passing: The /MRD line is low for >400 ns so there’s just no risk that i would ever oveerun the NVRAM which has a response time of 45 ns.

Also, I can see the extraordinarily tight timing of the high address byte availability at these higher frequencies. The image below shows a fetch where the CPU is going from page 0 to say page FF. The high address lines come up well before TPA but they stay up only for 41 ns after TPA drops. This is enough time for a fast latch to capture it but not a ton more.
17-10-15 TPA1802
The 1806ACEs timing is a bit different than the 1802’s but not in this area. The high address is available for less time overall but the same time after the fall of TPA(which is when you have to latch it)
17-10-15 TPA1806
Also, the 1806 simply will not synch with a 16MHz resonator – it went to around 4-5MHz.

1806s from aliexpress


I ordered 5 each 1802ACE, 1802BCE, and 1806ACE from a seller on aliexpress in late august. The BCE devices are slightly higher spec than the A’s and the 1806s are descendants of the 1802 with a few added instructions and some newer features like a built in timer.

The 1802ACEs came last week And the 1806s came today so that’s just about six weeks from order to delivery.  The 1806s look very nice. They’ve obviously been pulled from circuits for resale but they’re in good shape. One lot of 10 1802‘s that I got from eBay is suspiciously nice looking, as if they’ve been sanded down and remarked which seems like a ridiculous amount of work for someone to go to but…

I’m looking forward to testing these for function and performance.

In Which I am Awash in 1802’s


I got two lots of 1802s today one lot of ten from an ebay seller and five from an aliexpress store. The ebay lot was very nicely packaged in foam and anti-static plastic, the aliexpress chips were stacked with the bottom chip reversed – very sturdy seeming.

Both sets are marked CDP1802ACE,.

The ebay chips are marked as Harris with a date code(?) of H9610 on top.  The bottoms are all marked MALAY with various lot numbers(?) like YJ66B, WQ24K, YJ52B, YJ80C, YJ37B.

The aliexpress chips are marked as RCA Z with date codes(?) of 610,719, 901, and 923. The bottom markings are less clear but include 6FVT0/06493, 6FVAA/U6714, 6FVM0,K6305, 6BVR0/N2556.

I would say all the chips are pulls rather than new old stock. They are very clean but the bottoms show tool marks and scratches and the pins look a bit battered. Interestingly it looks like someone went to some trouble to restore the original splayed out position of the pins – I had to go through some effort to bend them in like I would with a new chip.

I put one from each batch into a modified Membership Card and tested them both quickly. Both ran a blink sketch at up to 10MHz although the aliexpress Harris chip needed a reload so it might be a bit flaky. I tried a 16MHz resonator for fun but neither chip worked.

Below is one or the other of them blinking away like nobody’s business at 10MHz. It should be noted that this is C code it’s running so it’s accessing memory in the first couple of k of low memory and writing to the stack in high memory- it’s probably a fair test.

Ali express store (about five weeks delivery)

eBay seller (about three weeks delivery)

Two Chip 1806 Circuit

I’ve been using Lee Hart’s Membership Card CPU board as the basis for the 1802 Olduino.  It’s great and has a lot of capability and excellent build quality and documentation. As I work toward my high speed 1806 version though, there’s a lot of stuff on the board that I don’t need to drag along – the clock gate chip, the multiple memory types, provision for load mode etc.

As a beginning here’s my two chip 1806 circuit on a breadboard.  I’m using a non-volatile RAM that I programmed using an olduino so I don’t need load mode or a ROM.  I’m not using the upper address bits at the moment so no latch. I’ll next add the address latch and then gating to stop random writes to low memory.

17-09-25 twochip2

UPDATE: I am not getting a solid power on reset with that circuit. I occasionally get a glitch on /CLEAR. It seems there’s major hysteresis in the circuit.  /Clear takes 20 ms to go high with +V but >200ms to go low when +V goes away.  If power comes back within that 200ms it glitches.

Bye-bye mystery circuit

I need a breadboard to start building my three chip wonder so I pulled this off my dead project shelf and I’m cannibalizing it. I honestly have no idea what it was meant to be. I sort of recall a standalone 1802 project that got out of control and got shelved but I don’t see a 40 pin footprint on there and there’s a pin marked miso which doesn’t make a lot of sense. There is a 28 pin ram that supports the 1802 idea but anyway bygones.

Dinosaur Chip

That’s my original 1802 chip in ceramic with gold pins. It’s 40 years old and has been in and out of more circuits than I can count. It’s notably thinner than its later plastic counterparts- I’m surprised I haven’t broken it by now.

And There We Go – UV EPROM Succumbs to Sunlight

17-09-03 erased eprom
So in the end it took about 8 days of mostly sunny weather outdoors on a south-facing window-sill to clear all of the CY27C256. It also got briefly rained on then dried off with rubbing alcohol but i doubt that had any effect.
Actually there are STILL some uncleared locations in the eprom. It’s fine for testing if i’m careful.

Inexpensive W5500 Ethernet Modules on Amazon

17-09-03 Robotdyn
17-09-03 KNACROJPG
I found a couple of inexpensive W5500-based ethernet modules on Amazon. One of them under $10. They’re not directly arduino/olduino compatible but I like the W5500 so much that they’re worth a look. Affilliate links here and here.

Xmodem Loader For The 1802 Olduino


With this setup the AVR is reset by CTS but the serial signals are going direct to Q and /EF3 on the 1802

I have a more-or-less working xmodem bootloader for the 1802/1806. I want to run this without the AVR but for the moment it’s still in the circuit. The AVR is disconnected from the serial lines but it still has control of the 1802’s control lines to reset it.
As it stands, the xmodem sender on the host pulses RTS which resets the AVR. The AVR holds the 1802 in reset for a couple of seconds looking for data on its disconnected serial then starts the 1802.

The 1802 then sends a NAK on the serial line which starts the xmodem sequence. The fly in the ointment is that Q is low during the couple of seconds the AVR is waiting and the xmodem sender can interpret this as a 0. I have the same problem with the Olduino/Z’s loader and I always discard the first character received. It’s more intermittent with the 1802 and if i just discard the first character I often miss the NAK – because the loader doesn’t retry, it’s cooked.

Eventually I’ll get rid of the AVR but in the meantime maybe I get the loader to try a couple of NAKs with a shorter delay for response – 100ms instead of a second maybe.

I tried running without the AVR but i have a problem getting a clean reset of the 1802.
The details of the current reset are:
RTS goes low for 20ms but the AVR’s reset line goes low only for .4ms
4ms after RTS goes low, /CLEAR goes low, then /WAIT pulse low briefly – 7ns
2 seconds later /WAIT pulses low for 5 ms, 5ms later /CLEAR goes high
7ms later the 1802 sends the NAK
17ms later the xmodem sender responds and we’re off to the races.

The bootloader follows modified to NAK twice before timing out to the application. In combination with the sender throwing a way the first byte received this works pretty well.

;17-07-19 Standalone xmodem boot loader xmboot.asm
;	receives to fixed address APPADDR
	relaxed on
NAK:	EQU 0x15
SOH:	EQU 0x01
EOT:	EQU 0x04
ACK:	EQU 0x06
Rrcv:	EQU 8
Rsnd:	EQU 9
R14:	EQU 14
R12:	EQU 12
R11:	EQU 11
R3:	EQU 3
stkaddr: EQU 0x7FFF
blksize:	EQU 128
ldAD:	macro	reg1,directaddress	;load an absolute address or a constant into a register
	ldi	(directaddress)&255
	plo	reg1
	ldi	(directaddress)>>8; was/256
	phi	reg1

	seq			;prep Q for serial output
; XMODEM receiver based on xr.asm by Michael H Riley and serial routines by Josh Bensadon   
	ldaD 	2,stkaddr
	sex	2
	ldaD	3,here
	sep	3
	ldaD	Rsnd,serout
	ldaD    Rrcv,serinT
	ldi     NAK             ; need to send NAK to start
        sep     Rsnd
        sep     Rrcv          	; test for incoming character or timeout
        bnf     ckeot		;continue if no timeout
	ldaD    Rrcv,serinT	;reload address of serial routine with timeout
	ldi     NAK             ; retry NAK to start
        sep     Rsnd
        sep     Rrcv          	; test for incoming character or timeout
        bnf     ckeot		;continue if no timeout
	lbr launchapp		;timeout - launch already loaded application

filelp:    ;receive address is in R12, length goes in R11
;begining of block read. returns to filelp or exits to filedn   				
        sep     Rrcv          	; wait for incoming character
ckeot:	smi     EOT              ; check for EOT
        lbz     filedn           ; jump if so

	sep     Rrcv               ; read block number
	sep     Rrcv               ; read inverted block number

	ldi     blksize             ; 128 bytes to receive
	plo     r11

readlp: sep     Rrcv               ; read data byte
        str     r12                  ; store into output buffer
        inc     r12                  ; point to next position
        dec     r11                  ; decrement block count
        glo     r11                  ; see if done
        bnz     readlp              ; loop back if not
;end of block read
        sep     Rrcv               ; read checksum byte

        ldi     ACK                  ; send an ACK
        sep     Rsnd
       	lbr     filelp              ; loop back for more
        ldi     ACK                  ; acknowledge end of transmission
        sep     Rsnd

launchapp:				;dispatch code newly loaded or previously left 
	ldaD	0,APPADDR	;prepare to launch as if reset
	sex	0		;X=0
	sep	0		;PC=0 & go to loaded application

; *******************************************************************
; *** This software is copyright 2005 by Michael H Riley          ***
; *** You have permission to use, modify, copy, and distribute    ***
; *** this software so long as this copyright notice is retained. ***
; *** This software may not be used in commercial applications    ***
; *** without express written permission from the author.         ***
; *******************************************************************
	include ""	
	org	0x200
;This is a standin for the program to be loaded
	br	die

***File follows
;bit-bang Serial routines adapted from Josh Bensadon's VELFbios-v3.1.asm
;Transmit Byte via Q connected to RS232 driver
;call via sep, returns via sep R3
;Byte to send in D
;Destroys r14
;17-09-02 this version times out on the first call only - approx 1.5 sec at 4MHz
bitdelay: MACRO baudrate,cpuspeed,baseline,xreg
	rept ((cpuspeed/(baudrate*8)-baseline))/3
	rept (((cpuspeed/(baudrate*8)-baseline)#3))>=1
	sex xreg
	align 64
serout:			;entry from assembly with char in D
	phi R14		;save char in R14.1
	ldi 9		;9 bits to transmit (1 start + 8 data)
	plo r14
	ghi R14
	shl		;set start bit
	rshr		;DF=0

	bdf $+5		;10.5   jump to seq to send a 1 bit
	req		;11.5   send a 0 bit
	br $+5		;1      jump +5 to next shift
	seq		;11.5   send a 1 bit
	br $+2		;1      jump +2 to next shift (NOP for timing)
	rshr		;2      shift next bit to DF flag
	phi r14		;3      save D in r14.1
	DEC r14		;4      dec bit count
	glo r14		;5      get bit count
	bz .txcret	;6      if 0 then all 9 bits (start and data) sent
	ghi r14		;7      restore D
	bitdelay __BAUDRATE,LCC1802CPUSPEED,20,2,{EXPAND}
	br .txcloop	;9.5    loop back to send next bit
.txcret: ghi r14		;7
	bitdelay __BAUDRATE,LCC1802CPUSPEED,16,2
	seq		;11.5 stop bit
	bitdelay __BAUDRATE,LCC1802CPUSPEED,4,2
	sep R3		;return 
	br serout	;reset for next time
;Receive Byte via EF3 connected to RS232 receiver
;Receives 8 bits
;call via sep
;Returns with Byte received in D, DF is set if the start bit is never seen
;Destroys r14
	align 64
serinT:			;serial input with timeout of 65535*6*16 machine cycles - approx 1.5 sec at 4MHZ
	ldaD R14,0x4000	;R14 is timeout loop counter
.rxcw:	b3 .okgo	;check for start bit after each instruction
	dec 14
	b3 .okgo	;check for start bit after each instruction
	ghi 14
	b3 .okgo	;check for start bit after each instruction
	bnz .rxcw
;here we've had a timeout - set DF and return
	ldi 1
	sep R3		;return
	br  serinT	;for next time
.serinN:	bn3 .serinN	;serial input without timeout	
.okgo:			;here we know the start bit is present
 	ldi 8		;start bit +7 bits from loop, last bit on returning
	plo r14
	ldi 0
	NOP		;delay to center samples

	bitdelay __BAUDRATE,LCC1802CPUSPEED,20,2
	b3 $+6		;11.5 sample rx input bit
	ori 80h		;1
	br $+4		;2
	phi r14		;1
	phi r14		;2
	shr		;3
	phi r14		;4
	DEC r14		;5
	glo r14		;6
	bz .rxcret	;7
	ghi r14		;8
	br  .rxcloop	;9
.rxcret: ghi r14	;8
	ghi r14		;9
	bitdelay __BAUDRATE,LCC1802CPUSPEED,20,2
	b3 $+4		;11.5 sample last rx input bit
	ori 80h		; for a 1 bit
	adi 0		;clear the DF flag because no timeout
	sep R3		;return
	br  .serinN	;for next time - only timeout on first call
from __future__ import print_function
import sys
import logging
import serial
    from cStringIO import StringIO
    from StringIO import StringIO
from xmodem import XMODEM, CRC
from time import sleep
import os
if len(sys.argv)>1:
print ("File Size is",fileSize)

def getc(size, timeout=1):
def putc(data, timeout=1):
    global xcount,xprog
    if (len(data)==128): # if it's a block
    	for x in range(newprog-xprog):
    sleep(0.001) # give device time to send ACK

#Main program starts here - define the serial port, set RTS off, then open it
port = serial.Serial(parity=serial.PARITY_NONE,
#open the file to be loaded
stream = open(filename,'rb')
sleep(0.1) #ditch the 1st char - always seems to be 0

#transfer the file
result=XMODEM(getc, putc).send(stream, quiet = 1)


if result:
    print ("\ntransfer successful")
    print ("\ntransfer unsuccessful")
    x=raw_input("press enter to continue...");

This Time It’s Serious 

 We have a string of sunny days forecast with no precipitation. It’s propped up in full sun at a 45 degree angle. If a week like this doesn’t do it, I call BS on the whole sunlight erasing UV chips thing.

I have a blank chip on its way and I do mean to order an eraser if I need one, but I would like to see this work.

I was a bit worried about the chip overheating but I measured it when it was in the plastic bag and it hit 109°F. The chips are rated for something like 85°C in the service and 150°C in storage.

Update: After a bit less than a week of steady sunny days the UV EPROM is clearly losing its programming. Large parts of the chip are cleared to 0s although there are still remnants of the code. The erasure pattern is certainly peculiar though. locations 00-07,10-17,20-27 etc are cleared to 0’s but 08-0F,18-1F etc still have quite a few bits set corresponding to the originally programmed code. Further down the chip huge swaths have been cleared to 0.

The common wisdom was that a couple of weeks of sun would do it and i’d say that’s fair. I would add that modern window glass protected the chip VERY well and even a sandwich bag inhibited erasure. The image on the left is the current state and the right is the state when i set it out to bake 6 days ago.

Summary – Overclocking the COSMAC CPU’s

The video above shows the membership card CPU board that powers the 1802 Olduino running at 8MHZ. The Membership Card normally runs at 1.8MHz but the CPU’s are rated for 5MHz and I had been running the olduino at 4MHz. I built a new CPU card which Lee Hart, the designer, thought would suit the higher speed. The 4093 chip used in the clock oscillator has been replaced with a higher spec 74HC132 and I left a socket for the resonator so I could try various speeds.

I had three CPU chips handy to test with, an RCA branded CDP1802ACE, a Harris branded CDP1806ACE, and an RCA branded CDP1805ACE. These are all 5V parts rated for 5MHz. The 1806 and 1805 have extra instructions and the 1805 has onboard memory but both are pin compatible with the 1802 except for lacking the hardware load mode.

Having loaded a blink program with the 1802 at 4MHz, I tried each chip with 4,6, and 8MHz resonators. The 1802 ran fine at 4 and 6MHz but failed at 8MHz although it seemed to be clocking ok and producing timing pulses. The 1806 worked at 4 and 6MHz but at 8MHz it stopped producing TPA and TPB. The 1805 ran fine at 4,6, 8, and even 10MHz. I think the difference is down to sample variation rather than CPU type or brand but I may source additional parts to try.

In the gallery below there’s a chunk of the membership card schematic showing the pin changes to accommodate the 74HC132 replacing the 4093, images of the top and bottom of the board showing cut traces and jumpers to make the pin changes, and an image of the bottom of the finished board with those changes plus my other changes that accommodate the narrow ROM at U8 and bring signals over to a secondary connector for the olduino card.

Well duh… Also YAY!

I started doggedly buzzing out all the connections and realized that without the front panel or the olduino adapter, the membership card circuitry has /mwrite disconnected so a super-simple program would work but the blink sketch wouldn’t.
The video above has it running the blink sketch with a 6MHz resonator in place. The orange jumper in the 30 pin connector is bridging /mwrite. It would not blink at 8MHz but I’ll leave that for another day.

Despite all the nonsense I’m a bit excited about running it naked like this. As soon as I get a bootloader in ROM I’ll make a little adapter to fit on the 30 pin connector with the power/serial header and a Q LED(oh, and a reset circuit). I’ll lose my SPI circuitry but it will be easier to get at the processor and memory while I work on the speed.

And still puzzled

I’m pretty sure it’s a mistake to try and debug a hardware problem by looking at the software but that’s what I’m doing. Trying to trace what goes wrong by looking at the bottom five address lines TPA and /mread. Of course, when I hook everything up it works!


I think the following is true:

  • The simplest loop (seq,req,br 0)will run with or without the olduino attached
  • A similar program with a filler in it will only run with the olduino attached
     lbr far:
     db dup 256(0)
far: req
     lbr 0

Feels like something to do with an address line but the olduino doesn’t attach to the address lines. This is at 4MHZ so there’s nothing i haven’t run before.
17-08-20 bottom 1
Ah – just noticed that the lead that should have been going to TPB on pin 33 of the 1802 was actually connected to one of the address lines on pin 28. TPB is an input to the olduino board so it doesn’t seem a big deal but…

And sadly, fixing that didn’t change the symptoms. More tomorrow.

First Mate is So So

I finished off soldering the CPU card and tried it with the olduino adapter.  Initially things looked great – a blink sketch loaded and blinked merrily away at 4MHZ. After that not so good. I tried replacing the resonator for 8MHZ. No blinky but when i put the 4MHZ crystal back in it blinked. Going back to the testbed(taking off the olduino card) I find Q stuck at 5V although the processor is cycling and address lines are flipping. Put back the olduino adapter and it blinks! I have no hypothesis about the cause.

In the gallery below you can see the bottom of the card with the secondary header added and soldered and the simple testbed.

WooHoo – The Screamer is Screaming!

17-08-19 8MHZ 47pfAs of end of day today all of the on-board soldering is done and the clock circuit delivers stable pulses up to (probably) 10 MHZ. The processor is generating timing pulses and state codes and generally looks good. I tried actually running a 7B 7A 30 00 sequence by loading in on a working olduino and transplanting the memory but it doesn’t seem to be pulsing Q. It is doing fetch/execute cycles though so i’m sure it’s something simple.

I say it probably works at 10MHZ because my logic analyzer shows varying pulse widths averaging 10MHZ – I think it’s just an issue of sampling at 24MHZ.

Update: when I actually hooked up the probe to Q I could see it pulsing just fine at 8MHZ!
17-08-20 Q

UV Eprom’s is Tough!

I got my EPROM programmer today so I pulled the CY27C256 in from it’s sunbathing and read it out. The program josh burned in is still there! The first part of the EPROM seems completely as-burned although there are blocks later on that do show some corruption. I had accepted that it was never going to erase protected by 2 layers of good window glass but I did think that a week outside in a ziplock would do the trick!
I’ll have to buy an eraser but in the meantime I’ll get Josh to mail me back the second sample I sent him and use that. I’m going to want this part on hand for building up the 1806 screamer for the next couple of days but I’ll eventually put it back out for another sun-soak unless the I order an eraser and it shows up quickly.

Building an 1806 Screamer III

There’s the top and bottom view with the passives mounted except those that go under the socket for the wide memory chip. I’m not proud of the soldering but my experience with these boards is that i need to make sure the holes are full of solder to be confident that it’s a good connection.

Building an 1806 Screamer II

There are the board changes I need to make to accommodate the 74HC132 replacing the 4093 and the CY27C256. The 74HC132 is needed for the higher clock speed and the changes are the same ones I made before. For the CY27C256 ROM It’s basically the same but I’m cutting the trace in what I think will be an easier spot and I’m not initially rewiring pin 1 (VPP) because the data sheet says it’s a “don’t care” unless it’s actually 12V.

Next Steps:

  1. make the trace cuts noted in red
  2. install the small components – resistors, jumpers,capacitors
  3. install the sockets
  4. cut the wide memory chip socket (U2) to allow the narrow(U8) chip to go in
  5.  install socket pins for the narrow chip and resonator
  6. install the 30 pin connector
  7. test all the +V and gnd points for correct voltages
  8. install the resonator and 74HC132 – see if it clocks at 4MHZ, 6MHZ and 8MHZ
  9. install the other ICs checking for smoke
  10. 10 see if the processor will execute code from the wide memory
  11. install the 8 pin connector
  12. try it with the olduino board at 4MHZ.