Skip to content

Adding A Narrow ROM To the 1802 Olduino – III

I’ve tried a couple of things accessing the ROM.  First, although I was warned, I forgot that the ROM address lines are scrambled to make the layout practical.  A0 goes to the ROM’s A4, A3 goes to the ROM’s A0, and A4 goes to the ROM’s A3.  Nothing I can’t fix in software but the ROM image I got Josh to burn is no good.

For determining power consumption I tried running the Olduino with the ROM in place but not accessed and then with various duty cycles. With no ROM access the Olduino is using about 60ma.  With the heaviest duty cycle I could manage it’s about 170ma(!).  So my plan to use it as a boot device is fine but you probably wouldn’t put your monitor in it.

It’s possible that there is something else going on because i am fighting some kind of issue that might be memory-related.  If I run the program below the output from the dump() routine is fine for addresses below 0x8000 but it’s corrupt for the addresses in the ROM.  If I move the dump code into main() it works fine. I can only think of some kind of memory overlap but I don’t know what. The ROM contents as printed is “correct” and the dump showing address 003F does in fact report what’s at 3F so this may not really be mysterious – just some sort of finger problem.

UPDATE: I dinked around with this for hours with no satisfactory result. Certainly the problem goes away if i remove the rom but i’m not sure if it’s the RAM not making good contact or some more straightforward electrical issue.

 #include <olduino.h>
#include <nstdlib.h>
#include <cpu1802spd4port7.h>
void dump(unsigned char* data, unsigned int len){
	unsigned int i=0;
	printf("dumping %d bytes at %x",len,data);
		if (0==(i%8)) printf("\n%x ",data);
		printf("%cx ",*data++);
void main(){
	unsigned char*ptr=(unsigned char *)32768;
	unsigned int i=0;
	printf("dumper here 3\n");
		if (0==(i%8)) printf("\n%x ",ptr);
		printf("%cx ",*ptr++);
	printf("\ndone inline dump\n");
	dump((unsigned char *)0x8000,64);

#include <olduino.c>
#include <nstdlib.c>
16:35:30.322> run1802.7.1(2000) for Hardware Loader
16:35:30.322> dumper here 3
16:35:30.432> 8000 37 30 F8 C0 AE 00 80 7A
16:35:30.432> 8008 12 09 00 80 F8 7B BE 30
16:35:30.432> 8010 EE 15 09 30 C4 80 37 FF
16:35:30.615> 8018 3F D8 6E 19 67 00 0E FF
16:35:30.615> 8020 FF FF FF FF FF FF FF FF
16:35:30.615> 8028 FF FF FF FF FF FF FF FF
16:35:30.615> 8030 FF FF FF FF FF FF FF FF
16:35:30.615> 8038 FF FF FF FF FF FF FF FF
16:35:30.615> done inline dump
16:35:30.615> dumping 64 bytes at 003F
16:35:30.922> 003F A1 B1 C0 00 75 81 FA 07
16:35:30.922> 0047 AB 91 FA 00 BB 8B CA 00
16:35:30.922> 004F 61 9B CA 00 61 F8 A4 AC
16:35:30.922> 0057 F8 0E BC 87 AD 97 BD D4
16:35:30.922> 005F 09 CB F8 9F AC F8 0E BC
16:35:30.922> 0067 87 AB 97 BB 17 0B AD F8
16:35:30.922> 006F 00 BD D4 09 CB 11 22 86
16:35:30.922> 0077 52 81 F7 96 52 91 77 12
16:35:30.922> done

UPDATE: I dinked around with this for hours with no satisfactory result. Certainly the problem goes away if i remove the rom but i’m not sure if it’s the RAM not making good contact or some more straightforward electrical issue.

UPDATE: I did a memory test of the RAM with the ROM in circuit and it looked fine. I made a simpler program that exhibits the fault:

#include <nstdlib.h>
#include <cpu1802spd4port7.h>
void dump(unsigned char* data){
    unsigned int i=0;
    printf(" %x",data);
void main(){
	printf("dumper here 6\n");
	dump((unsigned char *)0x8fff);
#include <nstdlib.c>
********************partial assembly text follows ****************
_dump:		;framesize=8
	reserve 6
	st2 R12,'O',sp,(8); flag1 
;void dump(unsigned char* data){
;    unsigned int i=0;
	ld2z R11
	st2 R11,'O',sp,(4); ASGNU2(addr,reg)
;    printf(" %x",data);
	ldaD R12,L2; reg:acon
	ld2 R13,'O',sp,(8) ;reg:INDIRP2(addr)
	Ccall _printf
	release 6

_main: ;copt is peeping your size 6 frame with oct 23 rules
	reserve 4
;void main(){
;	printf("dumper here 6\n");
	ldaD R12,L4; reg:acon
	Ccall _printf
;	dump((unsigned char *)0x8fff);
 	ldaD R12,0x8fff; reg:acon
	Ccall _dump

********************output follows ********************
15:32:08.807> run1802.7.1(2000) for Hardware Loader
15:32:08.807> dumper here 6

The address is passed to dump() in R12 and what is received is, in fact, the value that’s loaded into R12 by the printf() preceding the dump() call. Looking at the assembly code i just have no idea how this is happening!

Adding A Narrow ROM To the 1802 Olduino – II

Electrically this was not too bad.  I had actually picked a bad spot to cut the A14 trace but no big deal. The ROM’s A14 on pin 27 is jumpered to the RAM’s pin 1 and the ROM’s VPP on pin 1 is jumpered to VCC on its own pin 28.


Mechanically it is quite a bit trickier. I am using these little tiny pin sockets so I can remove the ROM for programming.  Even so, it barely fits under the RAM although there’s lots of room above it.  Getting the rom and sockets in place to solder was very finicky.  You normally put the pins on the IC then insert in the board and solder but these ROM chips have been through the wars and getting everything aligned was brutal.  I ended up starting with just a couple of pins at each end and insering the chip from the back of the board where I had better access. Then I’d remove it and try it in the correct orientation.  Gradually, with a lot of fiddling I added pins, went front and back, and eventually everything lined up.

17-06-21 plenty of roomThe final mechanical issue is that there isn’t really room under the RAM for the bulky ROM chip. The RAM is just barely in its socket and it wouldn’t be reliable. I’ll have to either replace the RAM socket with something higher or use another layer of the socket pins.

Adding A Narrow ROM To the 1802 Olduino

The 1802 Olduino is based on the 1802 Membership Card by Lee Hart.  The board is quite full so in order to allow both ROM and RAM, Lee put a footprint for a .3″ wide memory chip under the .6″ wide footprint I use for non-volatile memory. I like the idea of adding a ROM so I can eventually get rid of the AVR on the olduino board and have the 1802 bootloader in ROM.  I have in mind to do a bit-bang serial xmodem loader but as a trial I’m going to burn the “fakeloader” into an EPROM so its gone off to Josh Bensadon who has a programmer that can handle the chip.

Because my NVRAM is .6″ wide, I have to put the ROM in the narrow socket.  Herb Johnson on the COSMAC mailing list was nice enough to let me have a couple of Cypress CY27C256s.  These are UV erasable EPROM so the pin layout is slightly different than the RAM that Lee was thinking of when he laid it out.  PIN 1 needs to go to 5V instead of A14, and pin 27 needs to go to A14 instead of /Write-Enable.

Boggling over the datasheets, the schematic, the actual board, and a copy of the board layout gerber files from Lee I’ve concluded that I can clip the traces leading to those pins under the board without hurting anything else and then jumper pin 1 of the inner chip across to its pin 28 and pin 27 over to pin 1 of the outside chip.  I’ve cut the traces and verified that the board still works but i’m waiting til I get the chip back from josh to do the jumpers. In the images below the segment of the board with the red Xs for the cuts is reversed from the gerber and the actual board because i found it easier to work with the top and bottom copper images if I was looking at both from the top.

Goodbye Mr Chips



I got another end-of-life parts warning from digikey today.  This time for the 6 pin ATTINY10 I use to generate the millisecond interrupt for the olduino/z.  You can see it in the image almost hidden by the single male header I needed to program it. I forget but I think it only took power, ground and one pin to program.  OK, it’s only 32 bytes of ram and 1K of flash but come on, isn’t that the cutest thing ever?  I’ll buy a few more before the year is up.

I’ve had a few other chips go obsolete on me: the TP3465V SPI chip that I used in the olduino/Z and the STK16C88 non volatile RAM that I use in both olduinos. In each case I’ve sourced a couple of spares from eBay because there’s really no follow-on replacement for either. The ATTINY10 6 pin package is obsolete in favour of an SOIC 8 pin which is not that much bigger but doesn’t seem nearly as cute.

Debugging – How the Heck Did That Ever Work?

Because I’m lazy, I do everything in C and, if it works, I leave it alone til it doesn’t. In this case, I had written the fake loader in C. So I was going through all the init code, setting up stacks and registers then eventually loading or branching to an already loaded program that repeated the initialization code. Critically, the CPU was running with R3 as the program counter when it hit the second copy of the init code. The init code expects to be running on R0 so when it started loading R3, hilarity ensued. That was tough. Thankfully it failed nicely in the emulator so it turned up after some head scratching.

On the plus side, this forced me to redo the loader in assembly which i should have done from the beginning. It only takes 21 bytes but i’m going to settle on location 0x100 for the target program to leave me room for a better loader, maybe a register save etc.

When I get to the serial/xmodem loader that won’t be enough room so maybe I’ll make it 512 – that just saves me changing the target code location.

;;1806loader simulates 1802 load mode in run for 1805/6
target: equ 256
	b4 run		;bypass bootloader if IN pressed
	ldi	(target)&255
	plo	14
	ldi	(target)>>8; was/256
	phi	14
	sex 14		;in X register
noEF4:	bn4 noEF4	;loop til IN pressed
	inp 6		;load memory
	nop		;let the AVR breathe
	out 7		; echo
yEF4:	b4 yEF4		;wait til switch released
	br noEF4	;back for more
run:	lbr target	;finally - off we go

Debugging – Just Shoot Me

I came back to the 1806 olduino after a break and encountered a bug that has me scratching my head.  I’m using something I call the fakeloader to emulate 1802 load mode on the 1806.   fakeloader.c gets compiled to low memory and looks to the AVR external loader like an 1802’s load mode. Fakeloader loads the code from the external loader to location 0x800 and runs it from there.   The AVR external loader does actually know what’s going on, If it sees code compiled for location 0 it puts the 1802 in load mode as usual; if it sees code compiled for a different address it puts the processor in RUN and counts on the fakeloader.

I had a little test program called hellofromtheotherside.c that i would run that could report where it was loaded and what kind of processor it was compiled for.  The trouble was it didn’t work! I could run almost anything compiling it for location 0x800 and loading it via the fakeloader but not hellofromtheotherside.  After much dinking around my simplest fail/no-fail case involves code that is never executed! The test case is below, In the function dump(which is never executed!) there’s a for loop.  I can make it fail or run depending on whether there are a couple of print statements inside the for loop or not.  Although the code is never executed, the version with the print statements inside the loop compiles to more code and ALTHOUGH THAT CODE IS NEVER EXECUTED it seems to load to low memory being overwritten as well as simply not printing. The version below is the one that fails. If I were to close out the for loop on the 12th(**A) line and comment out the } on the 15th line(**B) it would work.

Obviously, everything after dump() including main() and the library routines are in slightly different locations but I don’t know what’s leading to the failure. cr*p.

void fun(int i){}
int bar(int s,int b,int c){
	int local=42;
	return local+c;
#include <nstdlib.h>
#include <cpu1802spd4port7.h>
#define putc(x) out(7,x)
void dump(unsigned char* data, unsigned int len){
	unsigned int i=0;
	printf("dumping %d bytes at %x",len,data);
		if (0==(i%8)) printf("\n%x ",data);
		printf("%cx ",*data++);
void main()
	char* dummy=(void*) &fun;
	printf("Hello World!9!\n");
#include <nstdlib.c>

The failing case, with the printfs outside the loop body generates LESS code than the working case(because the compiler puts i in a register). I stuck enough db’s in the bottom of dump to move main to the same place and it suddenly works! Moving them down to above the nstdlib include also works. Moving them down to below the nstdlib include also works. So something in the epilog is getting b*ggered.

Further diddling by taking out filler I can get it to work with 2 bytes of filler or fail with 1. In the guts of the epilog it works with lcc1802init: at 15EC and fails when it’s at 15E8. In any case, by the time it gets to the call routine it will be the same because there’s an align 256 that brings it to 0x1700 in either case. I give up for now.

Also, I’ve been assuming this won’t fail in the emulator but don’t really know that. worth a try tomorrow.

UV EPROM Defeats Ghetto Programmer

I was able to get the breadboard programmer to read(I think) the CY27C256 EPROMS but my attempts at programming failed. The essence of the programming is to apply a series of 200 uS low pulses on the chip select (pin 20) while holding VPP(pin 1) at 12 volts. I first built that into the ghetto programmer code but when it didn’t work I just made a standalone sketch that would do 30 pulses and changed all the other signal levels with jumpers.  I set it up with A14,13 & 12 at +V and the others at 0 so i would be programming location 7000; i pulled D0-D7 high, held /OE(pin 22) at +V; applied 12V from a wall wart to VPP, and pulsed pin 22. After 30 pulses I disconnected the jumpers and tried to read the same location but all the bits remain stubbornly 0.

I tried each of two chips with the same result so it’s more likely some error on my part than a faulty part.

The chips have a signature built in which you read out by holding all address lines low except A9 which you connect to 12V(!).  I was able to do that on the breadboard and read out the signature successfully so it’s even less likely that the chips are bad.  I have a friend in Toronto who can maybe program them for me so i’ll try that.  I was surprised not to have found an arduino shield or schematic for programming them but i see why now – it’s a lot of trouble.

The pics below show the eprom on the breadboard set up to read the signature and then to program it.  In each case the 12V VPP is being supplied from a wall wart through the alligator clips at the bottom.  There’s an arduino off to the right supplying 5V and, in the programming case, pulsing the /CE pin low.