RAM display program for the Membership Card

Last updated Nov 29 2012. Edited by Herb Johnson, (c) Herb Johnson, except for content written by others. Current production of the 1802 COSMAC Membership Card is described and priced on the "membership card" home page. Other Membership Card software is on another Web page.


On Nov 26 2012, Cristian Arezzini posted into cosmacelf Yahoo group a RAM display program for the Membership Card. With his permission, here's the program, with commentary by Lee Hart - edited by Herb Johnson

Code and commentary

subject: First attempt at coding
date: Nov 26 2012
from: Cristian Arezzini
reply from: Lee Hart


> I decided to write a program that scans the whole memory and displays
> the data values on the LEDs. But the speed is controllable with the
> front panel switches; and when you press the IN button, the scanning
> pauses and the computer shows on the LEDs the page that is being scanned.
> Anyway, here's my code, and I'd appreciate any inputs - it's surely by
> no means optimized, but it does work.
> The program uses R0 as a program counter, R1 for the memory sweep,
> R2 for the delay cycle and R3 points to a "scratchpad byte" so that
> the INP instruction doesn't damage random locations.
> The first thing I noticed is that I can't use the GHI 0 instruction
> as a shortcut to load 0 in D, because I use the exended ETOPS
> operating system, so my programs are never in page 0!


A good first program!

An interesting thing about the 1802 is that there are *many* ways to do any given task. You get to create your own "architecture". :-)

Saving bytes or making it run faster doesn't matter much any more, but it's still an entertaining intellectual exercise (like crosswords or Suduko). So...

> Initialization:
> 00: F8 LDI 00 ;Loads 0 in D (can't use GHI 0 because it's not page 0)
> 01: 00
> 02: B1 PHI 1 ;R1=0
> 03: A1 PLO 1
> 04: 90 GHI 0 ;Loads the current memory page
> 05: B3 PHI 3 ;and uses it as high byte for the scratchpad byte
> 06: F8 LDI FF ;and uses FF
> 07: FF
> 08: A3 PLO 3 ;as low byte (R3={page}FF)

If you're going to load 00 and FF, you could load the FF first, then decrement it to get the 00's. This takes 8 instead of 9 bytes, as follows:

LDI FF ;set R3=xxFF
PHI 1 ;set R1 to FFFF
DEC 1 ;decrement so R1=0000
GHI 0 ;get current page
PHI 3 ; and set R3=pageFF,

> Delay cycle:
> 0F: E3 SEX 3 ;R3=X
> 10: 6C INP 4 ;D=M(R3)=Switches (loads what's in the switches
>              ; to D and to M(R3), which is the scratchpad)
> 11: A2 PLO 2 ;Copies it to R2.low, for the delay cycle
> 12: 82 GLO 2 ;Reads the R2.low
> 13: 22 DEC 2 ; and decrements it
> 14: 3A BNZ 12 ;If it's not zero, repeat loop from 12
> 15: 12

You have obviously figured out the unique method that the 1802 uses for its I/O instructions. Note that sometimes you can leave X=P for the OUT instructions; it then outputs the inline byte immediately after the OUT instruction from the program itself. But that's not useful in this case.

The delay loop doesn't need to use register R2. You could read the switches into D, decrement D (subtract 1), and loop until 0. It saves a byte and is one instruction shorter. Using the register is useful if you need a longer delay (more than 256 loops).

10: 6C INP 4 ;read the switches into D
11: FF SMI 1 ;subtract 1
12: 01
13: 3A BNZ 11 ;loop until 0
14: 11

> I really wish some instructions didn't do so much... i.e. why does the
> INP instruction have to read to D *and* to a byte in memory? Or, why
> can't I output to LEDs what's in the accumulator? :)

You can obviously use memory-mapped I/O, just like the 6502/6800/68000 etc. But I think RCA wanted to include some simple on-chip minimalist I/O so it didn't require so many external parts.

The OUT instruction increments X so you can leave X=P and do OUT immediates (output a constant from the program itself).

The INP instruction writes to memory to save whatever was loaded. But it also puts it in D because it's very likely you'll want to test the byte that was read. I do think it would have been handier (and more symmetrical) if INP also incremented X after writing. That would have provided an INP immediate; not useful for a program in ROM, but it would also do no harm and you'd still have the copy in D. And if the program is in RAM, it would not execute the byte loaded.

- Lee Hart

Contact information:
Herb Johnson
New Jersey, USA
To email @ me, see
see my home Web page.

This page and edited content is copyright Herb Johnson (c) 2012. Copyright of other contents beyond brief quotes, is held by those authors. Contact Herb at www.retrotechnology.com, an email address is available on that page..