Last updated Sept 4 2020. Edited by Herb Johnson, (c) Herb Johnson, except for content written by Lee Hart and others.
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.
IN LOAD CLR R/W S11 S10 S9 S8 down down down 0. Select LOAD mode (R/W down to avoid write) before applying power
To examine memory
IN LOAD CLR R/W 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
IN LOAD CLR R/W 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
IN LOAD CLR R/W 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
IN LOAD CLR R/W 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.
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
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.
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.
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
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.
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.
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 ram: db 0 ; storage for memory writes end
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..