Operating and Testing the 1802 Membership Card

Last updated Sept 4 2020. Edited by Herb Johnson, (c) Herb Johnson, except for content written by Lee Hart and others.

Basic 1802 MC switch operations

[assembled kit]


The group of four switches on the left are, from left to right:

S11  IN    (a pushbutton)
S10  LOAD  (a toggle switch)
S9   CLEAR (a toggle switch)
S8   READ/WRITE (a toggle switch)

S10 LOAD and S9 CLR are the mode switches. They select 1 of 4 modes:

RUN   - both up
WAIT  - right up, left down (CLR up, LOAD down)
CLEAR - right down, left up (CLR down, LOAD up)
LOAD  - both down

The IN button is used to step through memory during LOAD mode.
The READ/WRITE switch disables memory write. Put it in WRITE to load a program or to run programs that change memory.

A video demonstration of loading, verifying and running a program is later in this document.

Power-up state

S11  S10  S9   S8
     down down down  0. Select LOAD mode (R/W down to avoid write)
                        before applying power

To examine memory

S11  S10  S9   S8
     down down down  0. Select LOAD mode (R/W down to avoid write)
     up   down down  1. Select CLEAR mode (resets program counter to 0)
     down down down  2. Select LOAD mode (R/W down to select read)
push                 3. Reads memory location 0, displays contents on
                        the LEDs, then increments program counter to 1
push                 4. Reads memory location 1,
push                 5. Reads memory location 2, etc.

To load memory

S11  S10  S9   S8
     down down down  0. Select LOAD mode (R/W down to avoid write)
     up   down down  1. Select CLEAR mode (resets program counter to 0)
     down down down     Select LOAD mode (R/W down disables write)
     down down up    2. Select LOAD mode (R/W up to enable write)
push                 3. Set switches S0-S7 to byte to write to memory,
                        then push IN. LEDs will change to show the
                        data written, and program counter increments
push                 4. Set switches to next byte, press IN,
push                 5. Set switches to next byte, press IN, etc.

To modify memory location N

S11  S10  S9   S8
     down down down  0. Select LOAD mode (R/W down to disable write)
     up   down down  1. Select CLEAR mode (resets program counter to 0)
     down down down  2. Select LOAD mode (R/W down to disable write)
push                 3. Reads memory location 0, displays contents on
                        the LEDs, then increments program counter to 1
push                 4. Reads memory location 1,
push                 5. Reads memory location 2, etc.
push                 6. Reads memory location N-1, 
                        increments program counter to N
     down down up    7. Select LOAD mode (R/W up to permit write)
push                 8. Set switches S0-S7, push to byte to write to memory.
                        (then "examine memory" to verify results)

To run a program in memory

S11  S10  S9   S8
     down down down  0. Select LOAD mode (R/W down to disable write)
     up   down down  1. Select CLEAR mode (resets program counter to 0)
     up   down up    1.5 (do this if program writes to memory)
     up   up   --    2. Select RUN mode. Program begins executing at 0.

Written by Lee Hart Mar 25 2010.

Test programs

Herb: What do you recommend for a test configuration with NO ROM? Jumper settings and some switch toggling? Should I make a ROM header with specific data pins tied to ground to force an instruction?

Lee Hart: With no ROM or RAM [and running in RUN mode], the CPU will execute "air", and march aimlessly through the addresses. Look at the address and data buses with a 'scope or logic probe and you should see them all toggling. Note that the IDL instruction (all 0's) will *halt* the CPU, so add one pullup [1k, 10k, etc.] resistor from supply [+5 volts] to any data bus line to prevent the IDL instruction.

With a RAM, the front panel switches will work as follows:

[To write:] Select CLEAR, then LOAD mode. With WRITE enabled, set the data switches, and push the IN button. The LEDs should display the byte just loaded into memory address 0000.

Continue setting the data switches and pressing IN to load more bytes into consecutive locations.

To read: select CLEAR, select WRITE PROTECT, then select the LOAD mode. This time, it ignores the data switches. Each press of the IN button displays the contents of consecutive locations in memory starting at 0000. With a ROM, read mode is the only mode that works.

Your first programs: turn Q LED on and off

Try loading

address    data
0000    7B    set Q (turn on the Q LED)
0001    00    idle (halt until clear, DMA, or interrupt)

Next try a loop:

address    data
0000    7B    set Q (turn the Q LED on)
0001    38    NBR (no branch, just continue)
0002    7A    reset Q (turn the Q LED off)
0003    30    BR 0000 (branch back to 0)
0004    00    

Q should produce a square wave, blinking on/off. The square wave frequency is the 1802's clock frequency divided by 64, so the blinks will be too fast to see, but you can verify it with a 'scope.

Blink Q LED at visible rate

This program blinks Q far slower, so you can see it.

0000    7A    reset Q
0001    F8    load...
0002    10    ... 10 hex (change this byte to blink faster or slower)
0003    B1    ... into register 1's high byte
0004    21    decrement register 1
0005    91    get high byte of register 1
0006    3A    branch if not zero...
0007    04    ... to 0004
0008    31    branch if Q=1...
0009    00    ... to 0000 and reset Q
000A    7B    set Q
000B    30    branch...
000C    01    ... to 0001 to skip reset

In assembler, this looks like:

   0001                 R1	EQU	1
   0000                 start	ORG	0H
   0000   7a            	REQ		;reset Q
   0001   f8 10         L0:	LDI	10H	;counter
   0003   b1            	PHI	R1	;into high R1
   0004   21            L1:	DEC	R1	;decrement
   0005   91            	GHI	R1	;
   0006   3a 04         	BNZ	L1	;branch until R1 is zero
   0008   31 00         	BQ	start	;if Q set, go back
   000a   7b            	SEQ		;otherwise set Q
   000b   30 01         	BR	L0	;and branch to counter
   000d                 	END

I made a YouTube video, to show how to toggle in this program. It's called "Toggle Q on COSMAC 1802 Membership Card" by herbrjohnson.

Read switches, display result

Here's programs to read the data switches, and display them on the LEDs.

addr    data    instruction       
----    ----    -----------        
00    E1    SEX 1    ; set X=1
01    90    GHI R0    ; D=R0 high byte (i.e. 0)
02    B1    PHI R1    ; set R1=00xx
03    F8 0A LDI 0AH    ; set D= hex 0A
05    A1    PLO R1    ; set R1=000A
06    6C    INP 4    ; read switches
07    64    OUT 4    ; write to LEDs, but increments R(X)
08    30 00 BR 0    ; branch to 0 to reset R1 to 10
0A    xx        ; RAM storage for INP/OUT instructions

Note that RESET sets P=0, X=0 and R0=0000. So R0 is the program counter (P) and R0 is the index register (X) until it's changed with the SEX instruction. Also note: this program writes to memory so READ/WRITE must be in WRITE position.

- Lee Hart Feb 21st 2010, shorter version & read data switches Sept 5 2010

This program is a bit more complex. It reads the 8 data switches, displays their settings on the 8 LEDs, and pulses Q at a rate set by the switches. It tests the Membership Card's ability to read the switches and write to the lights. If you connect a speaker or a pair of headphones between J2 pin 15 (TXD, controlled by Q) and pin 19 (ground you'll hear a tone whose frequency is set by the switches. Run the program with S8 up (write). - Lee Hart June 2018

Address code Mnemonic Comments
0000 E1 	SEX 1 	;Set X register to 1 (OMG! The 1802 has sex!)
0001 90 	GHI 0 	;Get HIgh byte of register 0 in D (which is 0; so this sets D=0)
0002 B1 	PHI 1 	;Put D in HIgh byte of register 1 (so R1=00xx)
0003 F8 10	LDI 10h 	;Load D Immediately with 10 hex (TWO bytes in this instruction!)
0005 A1 	PLO 1 	;Put D in the LOw half of R1 (so R1=0010)
0006 6C 	INP 4 	;INPut port 4 (front panel switches) & write it to memory at (R1)
0007 64 	OUT 4 	;OUTput to port 4 (front panel LEDs) contents of memory at (R1)
0008 7B 	SEQ 		;Set Q. (At this point, D = the value read from the switches)
0009 FF 01	SMI 1 	;Subtract Memory Immediately from D (this means D=D-1)
000B 3A 08	BNZ 08h 	;Branch if Not Zero to address 0008 (so this loops “switch” times)
000D 7A 	REQ 		;Reset Q
000E 30 00	BR 00h 	;BRanch unconditionally back to address 0000
0010 xx 			;(This address is where INP and OUT save the switch value)

To display the complement of the switches, a little more dramatic display program is below. I use R3, not R1. Note how INP, OUT and arithmetic/logic operations like XRI work in different ways. - Herb Johnson, June 2012. (Thanks to Scott and Lisa for catching an opcode error in this program.)

0000 80		glo  R0	; zero value in R0 at reset
0001 B3		phi  R3	; high byte = 00
0002 F8 10  	ldi  10H	; low byte  = 10
0004 A3		plo  R3	; R3=0010 now
0005 E3		sex  R3	; X-->R3
0006 6C	loop:	inp  4	; read switches into D and M(R3)
0007 FB FF   	xri  0FFH	; invert the bits in D
0009 53		str  R3	; save result in M(R3)
000A 64		out  4	; and write M(R3) to LED's (incr R3)
000B 23		dec  R3	; cancel incr with decr
000C 30 06  	br   loop	; to read and write again
000E  		END

Testing the serial interface

This section is about brief testing for serial connections, not details of serial operation. Rev G and later of the M/S card uses EF3 for serial in, and Q for serial out. There's options on the Front Panel Board to wire in transistors to "interface" these for "RS-232" signal levels, and if necessary to invert signals. Check the Rev G support Web page for discussion and links. There's also links on that page, for customer modification of earlier revision cards. For later or earlier Membership Card versions, find links on the Membership Card home page.

On other Web pages, there's comprehensive notes about serial operation, and detailed notes on the serial interface. You also need an 1802 program that operates a software "bit-bang" UART to perform as a serial I/O "device". Also refer to your kit assembly manual and the appropriate version support page.

To test the hardware for whatever serial input/output you are operating, a "software loopback" may be useful. What is "looped back", are the characters sent by your serial "terminal" (program on some personal computer), to the M/S card serial interface, and echoed back to that "terminal". The 1802 programs below simply "echo" EF3 input to Q output, possibly "inverting" the signal if necessary. No baud rates, no adjustments to the CPU "clock" needed (if the clock is running "fast" enough). Also listed are instructions for testing EF3, EF4 and controlling Q.

Important hardware note: The 1802 microprocessor pins for EF1, EF2, EF3, EF4 are ACTIVE LOW. This means that a Vcc (positive) voltage level on pin 22 of the CPU - called "/EF3" - will be read by the CPU as a a logic 0. The backslash means "active low" or "inverted".

Here's the relevant 1802 instructions, followed by two software loopback programs. Choose one or the other, they are short, toggle them in at 0000H (or 8000H, same code) and verify the connections between your "terminal" and your Membership Card - Herb Johnson

   0000                 LABEL:
   0000   7b            	SEQ			;set Q=1
   0001   7a            	REQ			;reset Q=0
   0002   36 00         	B3	LABEL		;branch if EF3=1
   0004   3e 00         	BN3	LABEL		;branch if EF3=0
   0006   37 00         	B4	LABEL		;branch if EF4=1
   0008   3f 00         	BN4	LABEL		;branch if EF4=0

                        ;CPU EFx signals are *ACTIVE LOW*!!
   0000                 	ORG	0000H		;
                        ;Q follows EF3, inverts /EF3 signal at pin 22
   0000   7a            L0:	REQ			;clear Q
   0001   3e 00         L1:	BN3	L0		;loop to clear Q while EF3=0
   0003   7b            	SEQ			; but when EF3=1, set Q
   0004   30 01         	BR	L1		; and keep checking EF3. 
                        ;if /EF3 is high, EF3 is low, Q gets reset over and over
                        ;if /EF3 is low, EF3 is high, Q gets set over and over.
   0000                 	ORG	0000H		;
                        ;Q is reverse of EF3, follows /EF3 singal at pin 22
   0000   7b            L0:	SEQ			;set Q
   0001   3e 00         L1:	BN3	L0		;loop to set Q while EF3=0
   0003   7a            	REQ			; but when EF3=1, reset Q
   0004   30 01         	BR	L1		; and keep checking EF3. 
                        ;if /EF3 is high, EF3 is low, Q gets set over and over
                        ;if /EF3 is low, EF3 is high, Q gets reset over and over.

Serial binary loader with "bit bang UART"

A binary loader is a program used to load binary executables into a computer; it's a legacy going back to computers of the 70's, like the 1802 Membership Card without a ROM monitor. Since the Membership Card lacks a hardware UART, the processor must convert the serial binary stream into bytes. Then the loader will load those bytes into a selected portion of memory.

Here's a Web page which describes a binary serial loader with those features. It's small enough to be toggled manually into memory. There's a few versions to cover issues like the sense of the EF3 input line and also how to move the loader out of the way of a desired binary. The Web page tries to explain all these considerations and descriptions.

A possible front-panel monitor

Lee Hart, June 2019: "This is something I'm working on. I'm aiming for something short and simple. It could be toggled in as an early demo program, that gets used to enter bigger programs. (It's not tested or debugged yet)." - Lee Hart

; SOS.ASM -- Switch Operating System -- by Lee Hart 6/12/19
; A tiny Monitor program for the 1802 Elf and Membership Card.
; Uses switch front panel, and 256 bytes of RAM. Commands:
; READ memory starting at address 00xx:
;	1. CLEAR.
;	2. READ (memory protect on).
;	3. Set switches to xx (LOW byte of desired starting address).
;	4. RUN.
;	5. Press IN to display data in that address, then increment address.
;	6. CLEAR when done.
; WRITE to memory starting at address 00xx:
;	1. Same as READ while READ (memory protect on).
;	2. To WRITE, set switches to write data.
;	3. WRITE (memory protect off).
;	4. Press IN to write data to current address, display data at that
;		address, (confirms that it wrote), then increment address.
;	5. Can switch back and forth between READ and WRITE.
;	6. CLEAR when done.
; RUN program starting at address 00xx:
;	1. CLEAR.
;	2. Set switches to xx (LOW byte of desired starting address).
;	3. Press and hold IN button.
;	4. RUN. Execute program at 00xx with P=R0 when IN is released.
;	5. CLEAR when done.

	org	0
	ghi 0			; initialize R1 as a address pointer
	phi 1			;	R1=00xx
	ldi ram
	plo 1			;	R1=00ram
	sex	1			;	X=1
	inp 4			; read data switches into D
	bn4 read		; if IN is pressed (EF4 pin low),
run: b4 run			;	is RUN; wait for IN to be released,
	plo	0			;	then jump R0 to address!
read:				; else IN not pressed; is READ/WRITE
	plo 1			;	point R1 to address
r1:	bn4	r1			;	wait for IN to be pressed
r2:	b4	r2			;	wait for IN to be released
	inp 4			;	read switches, (try to) write to address, inc address
					;	(writes if S8=WRITE, reads if S8=READ)
	dec	1			;	decrement R1 (to point back to address just written)
	out	4			;	output address contents to LEDs
	br	r1			;	loop to read next
	db 0			; storage for memory writes

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) 2020. Contents written by Lee Hart, are copyright Lee Hart (c) 2014. 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..