please dont rip this site

RCA CDP1802 CPU

The 1802 (actually, a specialized version of the architecture) was the first CPU (vs processors made from discrete components) to enter space (if it's a space probe from the 80's, it probably had an 1802 onboard). It also helped run the Magellan probe that mapped and then crashed (intentionally!) into Venus^. The 1802 also entered space in control of the Galileo probe^ and as a display controller on the Space Shuttle and on MAGSAT, OSCAR 9-11, UoSAT-1, UoSAT-2, later DMSP, Dynamics Explorer A & B. Note: It did NOT travel on the Viking or Voyagers, as is often claimed.^

It's just an 8 bit uC, with 64K address space, a slow 2.5Mhz clock and really poor efficiency (most instructions take 16 to 24 clock cycles), 91 instructions, 1 interrupt level and a wierd external DMA.

The 1802 is unusual for two reasons: It was made as static core CMOS called COSMOS (COmplementary Silicon/Metal-Oxide Semiconductor) so the clock could run as slowly as you like, all the way down to stopped. This allows for very low power operation and instant low power mode... just stop the clock. The architecture is also unusual with 16 general purpose registers, any one of which can become the program counter.

Registers

Name Width Description
D 8 Accumulator
P 4 PC Pointer. This register is NOT the Program Counter, but points to one of the 16 Address registers, which then becomes the PC. The next instruction to excecute comes from the memory address pointed to by the Address Register pointed to by P. Each instruction cycle loads that value into the I and N Control Registers, then excecutes those values. M(R(P)) -> I,N. As a result, there are effecivly 16 PC's, any one of which can become active by loading P via the SEP instruction. Of course, then you wouldn't have any data pointers... or a stack pointer, DMA, INT, etc...
X 4 Address Pointer. Like the P register, X points to one of the 16 Address registers, but that memory value is then used in arithmetic, logic, and I/O instructions. X is loaded with the SEX (!) instruction.
R(0)-R(F) 16x16 Address registers. There are 16, and each is 16 bits wide.
R(0) is the DMA pointer.
R(1) is used as the interrupt routine PC an interrupt sets P to 1.
R(2) is used as the stack pointer (as required by the MARK instruction),
R(3) is used as the primary Program Counter although, as noted, the PC is really R(P).
DF 1 Carry bit
IE 1 Interrupt Enable
I,N 4 Instruction registers. Internal registers which hold the instruction currently being excecuted.
T 8 Temporary register. An internal register used to hold the values of P and X when they are being saved via the MARK instruction.

Instruction Set

# Op Description Action
0 IDL IDLE WAIT FOR DMA OR INTERRUPT; M(R(0)) -> BUS (Note 3)
0N LDN LOAD VIA N M(R(N)) -> D; FOR N
1N INC INCREMENT REG N R(N) + 1 -> R(N)
2N DEC DECREMENT REG N R(N) - 1 -> R(N)
30 BR SHORT BRANCH M(R(P)) -> R(P).0
31 BQ SHORT BRANCH IF Q = 1 "IF Q = 1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
32 BZ SHORT BRANCH IF D = 0 "IF D = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
33 BDF SHORT BRANCH IF DF = 1 "IF DF = 1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P) (Note 2)"
34 B1 SHORT BRANCH IF EF1 = 1 (EF1 = VSS) "IF EF1 =1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
35 B2 SHORT BRANCH IF EF2 = 1 (EF2 = VSS) "IF EF2 = 1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
36 B3 SHORT BRANCH IF EF3 = 1 (EF3 = VSS) "IF EF3 = 1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
37 B4 SHORT BRANCH IF EF4 = 1 (EF4 = VSS) "IF EF4 = 1, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
38 NBR NO SHORT BRANCH (See SKP) R(P) + 1 -> R(P) (Note 2)
38 SKP SHORT SKIP (See NBR) R(P) + 1 -> R(P) (Note 2)
39 BNQ SHORT BRANCH IF Q = 0 "IF Q = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
3A BNZ SHORT BRANCH IF D NOT 0 "IF D NOT 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
3B BNF SHORT BRANCH IF DF = 0 "IF DF = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P) (Note 2)"
3C BN1 SHORT BRANCH IF EF1 = 0 (EF1 = VCC) "IF EF1 = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
3D BN2 SHORT BRANCH IF EF2 = 0 (EF2 = VCC) "IF EF2 = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
3E BN3 SHORT BRANCH IF EF3 = 0 (EF3 = VCC) "IF EF3 = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
3F BN4 SHORT BRANCH IF EF4 = 0 (EF4 = VCC) "IF EF4 = 0, M(R(P)) -> R(P).0, ELSE R(P) + 1 -> R(P)"
4N LDA LOAD ADVANCE M(R(N)) -> D; R(N) + 1 -> R(N)
5N STR STORE VIA N D -> M(R(N))
60 IRX INCREMENT REG X R(X) + 1 -> R(X)
61 OUT 1 OUTPUT 1 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 1
62 OUT 2 OUTPUT 2 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 2
63 OUT 3 OUTPUT 3 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 3
64 OUT 4 OUTPUT 4 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 4
65 OUT 5 OUTPUT 5 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 5
66 OUT 6 OUTPUT 6 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 6
67 OUT 7 OUTPUT 7 M(R(X)) -> BUS; R(X) + 1 -> R(X); N LINES = 7
68 not assigned
69 INP 1 INPUT 1 BUS -> M(R(X)); BUS -> D; N LINES = 1
6A INP 2 INPUT 2 BUS -> M(R(X)); BUS -> D; N LINES = 2
6B INP 3 INPUT 3 BUS -> M(R(X)); BUS -> D; N LINES = 3
6C INP 4 INPUT 4 BUS -> M(R(X)); BUS -> D; N LINES = 4
6D INP 5 INPUT 5 BUS -> M(R(X)); BUS -> D; N LINES = 5
6E INP 6 INPUT 6 BUS -> M(R(X)); BUS -> D; N LINES = 6
6F INP 7 INPUT 7 BUS -> M(R(X)); BUS -> D; N LINES = 7
70 RET RETURN "M(R(X)) -> (X, P); R(X) + 1 -> R(X), 1 -> IE"
71 DIS DISABLE "M(R(X)) -> (X, P); R(X) + 1 -> R(X), 0 -> IE"
72 LDXA LOAD VIA X AND ADVANCE M(R(X)) -> D; R(X) + 1 -> R(X)
73 STXD STORE VIA X AND DECREMENT D -> M(R(X)); R(X) - 1 -> R(X)
74 ADC ADD WITH CARRY "M(R(X)) + D + DF -> DF, D"
75 SDB SUBTRACT D WITH BORROW "M(R(X)) - D - (NOT DF) -> DF, D"
76 SHRC SHIFT RIGHT WITH CARRY "SHIFT D RIGHT, LSB(D) -> DF, DF -> MSB(D) (Note 2)"
76 RSHR RING SHIFT RIGHT "SHIFT D RIGHT, LSB(D) -> DF, DF -> MSB(D) (Note 2)"
77 SMB SUBTRACT MEMORY WITH BORROW "D-M(R(X))-(NOT DF) -> DF, D"
78 SAV SAVE T -> M(R(X))
79 MARK "PUSH X, P TO STACK" "(X, P)-> T; (X, P)-> M(R(2)), THEN P-> X; R(2) - 1-> R(2)"
7A REQ RESET Q 0 -> Q
7B SEQ SET Q 1 -> Q
7C ADCI "ADD WITH CARRY, IMMEDIATE" "M(R(P)) + D + DF -> DF, D; R(P) + 1 -> R(P)"
7D SDBI "SUBTRACT D WITH BORROW, IMMEDIATE" "M(R(P)) - D - (Not DF) -> DF, D; R(P) + 1 -> R(P)"
7E SHLC SHIFT LEFT WITH CARRY "SHIFT D LEFT, MSB(D) -> DF, DF -> LSB(D) (Note 2)"
7E RSHL RING SHIFT LEFT "SHIFT D LEFT, MSB(D) -> DF, DF -> LSB(D) (Note 2)"
7F SMBI "SUBTRACT MEMORY WITH BORROW, IMMEDIATE" "D-M(R(P))-(NOT DF) -> DF, D; R(P) + 1 -> R(P)"
8N GLO GET LOW REG N R(N).0 -> D
9N GHI GET HIGH REG N R(N).1 -> D
AN PLO PUT LOW REG N D -> R(N).0
BN PHI PUT HIGH REG N D -> R(N).1
C0 LBR LONG BRANCH "M(R(P)) -> R(P). 1, M(R(P) + 1) -> R(P).0"
C1 LBQ LONG BRANCH IF Q = 1 "IF Q = 1, M(R(P)) -> R(P).1, M(R(P) + 1) -> R(P).0, ELSE R(P) + 2 -> R(P)"
C2 LBZ LONG BRANCH IF D = 0 "IF D = 0, M(R(P)) -> R(P).1, M(R(P) +1) -> R(P).0, ELSE R(P) + 2 -> R(P)"
C3 LBDF LONG BRANCH IF DF = 1 "IF DF = 1, M(R(P))-> R(P).1, M(R(P) + 1)-> R(P).0, ELSE R(P) + 2 -> R(P)"
C4 NOP NO OPERATION CONTINUE
C5 LSNQ LONG SKIP IF Q = 0 "IF Q = 0, R(P) + 2 -> R(P), ELSE CONTINUE"
C6 LSNZ LONG SKIP IF D NOT 0 "IF D Not 0, R(P) + 2 -> R(P), ELSE CONTINUE"
C7 LSNF LONG SKIP IF DF = 0 "IF DF = 0, R(P) + 2 -> R(P), ELSE CONTINUE"
C8 NLBR NO LONG BRANCH (See LSKP) R(P) = 2 -> R(P) (Note 2)
C8 LSKP LONG SKIP (See NLBR) R(P) + 2 -> R(P) (Note 2)
C9 LBNQ LONG BRANCH IF Q = 0 "IF Q = 0, M(R(P)) -> R(P).1, M(R(P) + 1) -> R(P).0 EISE R(P) + 2 -> R(P)"
CA LBNZ LONG BRANCH IF D NOT 0 "IF D Not 0, M(R(P))-> R(P).1, M(R(P) + 1)-> R(P).0, ELSE R(P) + 2 -> R(P)"
CB LBNF LONG BRANCH IF DF = 0 "IF DF = 0, M(R(P))-> R(P).1, M(R(P) + 1)-> R(P).0, ELSE R(P) + 2 -> R(P)"
CC LSIE LONG SKIP IF IE = 1 "IF IE = 1, R(P) + 2 -> R(P), ELSE CONTINUE"
CD LSQ LONG SKIP IF Q = 1 "IF Q = 1, R(P) + 2 -> R(P), ELSE CONTINUE"
CE LSZ LONG SKIP IF D = 0 "IF D = 0, R(P) + 2 -> R(P), ELSE CONTINUE"
CF LSDF LONG SKIP IF DF = 1 "IF DF = 1, R(P) + 2 -> R(P), ELSE CONTINUE"
DN SEP SET P N -> P
EN SEX SET X N -> X
F0 LDX LOAD VIA X M(R(X)) -> D
F1 OR OR M(R(X)) OR D -> D
F2 AND AND M(R(X)) AND D -> D
F3 XOR EXCLUSIVE OR M(R(X)) XOR D -> D
F4 ADD ADD "M(R(X)) + D -> DF, D"
F5 SD SUBTRACT D "M(R(X)) - D -> DF, D"
F6 SHR SHIFT RIGHT "SHIFT D RIGHT, LSB(D) -> DF, 0 -> MSB(D)"
F7 SM SUBTRACT MEMORY "D-M(R(X)) -> DF, D"
F8 LDI LOAD IMMEDIATE M(R(P)) -> D; R(P) + 1 -> R(P)
F9 ORI OR IMMEDIATE M(R(P)) OR D -> D; R(P) + 1 -> R(P)
FA ANI AND IMMEDIATE M(R(P)) AND D -> D; R(P) + 1 -> R(P)
FB XRI EXCLUSIVE OR IMMEDIATE M(R(P)) XOR D -> D; R(P) + 1 -> R(P)
FC ADI ADD IMMEDIATE "M(R(P)) + D -> DF, D; R(P) + 1 -> R(P)"
FD SDI SUBTRACT D IMMEDIATE "M(R(P)) - D -> DF, D; R(P) + 1 -> R(P)"
FE SHL SHIFT LEFT "SHIFT D LEFT, MSB(D) -> DF, 0 -> LSB(D)"
FF SMI SUBTRACT MEMORY IMMEDIATE "D-M(R(P)) -> DF, D; R(P) + 1 -> R(P)"

NOTES

* 0. Nomenclature / register summary:

       D    : data register, accumulator (16 bits).
       DF   : data flag, carry (1 bit).
       P    : program-counter register designator (4 bits).
       X    : index register designator (4 bits).
       I    : high nibble of instruction (4-bits)
       N    : low nibble of instruction (4 bits).
       R(d) : 1 of 16 16-bit registers as designated by d.
       Q    : Q flag (1 bit).
       IE   : interrupt enable flag (1 bit).
       T    : saved-state register (X,P) on interrupt (8 bits).
       M(a) : memory location addressed by a (8 bits).
 

* 1. The arithmetic operations and the shift instructions are the only instructions that can alter the DF.

After an add instruction:
	DF = 1 denotes a carry has occurred
	DF = 0 Denotes a carry has not occurred
After a subtract instruction:
	DF = 1 denotes no borrow. D is a true positive number
	DF = 0 denotes a borrow. D is twoÕs complement
The syntax Ò-(not DF)Ó denotes the subtraction of the borrow.

* 2. This instruction is associated with more than one mnemonic. Each mnemonic is individually listed.

* 3. An idle instruction initiates a repeating S1 cycle. The processor will continue to idle until an I/O request (INTERRUPT, DMA-lN, or DMA- OUT) is activated. When the request is acknowledged, the idle cycle is terminated and the I/O request is serviced, and then normal operation is resumed.

* 4. Long-Branch, Long-Skip and No Op instructions require three cycles to complete (1 fetch + 2 execute). Long-Branch instructions are three bytes long. The first byte specifies the condition to be tested; and the second and third byte, the branching address.

If the tested condition is met, then branching takes place; the branching address bytes are loaded in the high-and-low order bytes of the current program counter, respectively. This operation effects a branch to any memory location. If the tested condition is not met, the branching address bytes are skipped over, and the next instruction in sequence is fetched and executed.
This operation is taken for the case of unconditional no branch (NLBR).

* 5. The short-branch instructions are two bytes long. The first byte specifies the condition to be tested, and the second specifies the branching address.

If the tested condition is met, then branching takes place; the branching address byte is loaded into the low-order byte position of the current program counter. This effects a branch within the current 256-byte page of the memory, i.e., the page which holds the branching address. If the tested condition is not met, the branching address byte is skipped over, and the next instruction in sequence is fetched and executed. This same action is taken in the case of unconditional no branch (NBR).

* 6. The skip instructions are one byte long. There is one Unconditional Short-Skip (SKP) and eight Long-Skip instructions. The Unconditional Short-Skip instruction takes 2 cycles to complete (1 fetch + 1 execute). Its action is to skip over the byte following it.
Then the next instruction in sequence is fetched and executed. This SKP instruction is identical to the unconditional no-branch instruction (NBR) except that the skipped-over byte is not considered part of the program.
The Long-Skip instructions take three cycles to complete (1 fetch + 2 execute).

If the tested condition is met, then Long Skip takes place; the current program counter is incremented twice. Thus two bytes are skipped over, and the next instruction in sequence is fetched and executed. If the tested condition is not met, then no action is taken. Execution is continued by fetching the next instruction in sequence.

Stack operations: Call / Return, Push / Pop.

Note that although there is a return from interrupt instruction, there is no standard call and return. Or standard stack push or pop. The MARK instruction uses R(2) as a stack pointer to save X and P but since those are 4 bits each, and P must point to the register used as the program counter, that can't be used to push data. As the MARK instruction and P hint, call / return and data stacks are built from multiple instructions and clever program layout.

To call a routine, we first load the starting address of the code into the Register which will become the PC. Then we set the P register to point to that register. The code is then executed. To return, we need to set P back to whatever register it was before. At this point, the Register used for the subroutine points to the end of the routine, and will need to be reloaded for the next call.

This is fine for a general call to subroutine, but for something we will do repeatedly, like an interrupt, we can avoid this by setting up the subroutine with the entry point in the middle, and at the end, branch back up to the start, where we set P back to the original Register. That leaves our subroutine register pointing to the entry point of the subroutine; ready for the next call. Because interrupts simply save P and X to T then set them to 1 and 2 (respectivly), we can set R(1) to the entry point of our interrupt routine, and as long as we do this branch to the top, and do a RET to restore P and X from T just before the entry point, we can set it and forget it.

A data stack can be implemented by setting X to a Register which points to empty memory. Then Push by loading the value to push into D (e.g. GLO or GHI) then using STXD to store D to the memory location pointed to by the Register pointed to by X, and decrementing that Register. Pop is the opposite, but the Register used is hard coded using LDA #, to move a byte into D from the memory value pointed to by the register pointed to in the LDA instruction (the #, so LDA 2 uses R(2)). But... LDA increments the Register after loading the value, so you have the INC 2 (or INC whichever Register is your stack pointer) first, then LDA, then store the value from D to wherever, THEN... INC 2 so the stack is ready for a new value. Yike. But it works. And you can have multiple stacks, which is cool.

Support Chips

1821 (1024×1 RAM), 1822 (256×4 RAM), 1823 (128×8 RAM), 1824 (32×8 RAM), 1826 (64×8 RAM), 1831/2 (512×8 ROM), 1833/4 (1024×8 ROM), 1835/6/7 (2048×8 ROM), 1851 (Programmable I/O Interface, 1852 (8-bit I/O Port), 1853 (n-bit Decoder I/O Interface), 1854 (UART), 1855 (multiply/divide coprocessor), 1856 (4-bit memory buffer), 1857 (4-bit I/O buffer), 1858 (4-bit latch w decoder), 1859 (4-bit latch w dual decoder), 1861 (Video display controller), 1862 (color generator), 1863 (Programmable tone generator), 1864 (PAL interface), 1866, 1867, 1868 (latch/decoder memory interface), 1869 (Video Interface System, Address and Sound Generator), 1870, 1876 (Video Interface System), 1871 (Keyboard encoder), 1872, 1874, 1875 (8-bit I/O Port), 1877 (Programmable Interrupt Controller), 1878 (Dual Timer), 1879 (Timer), 1881, 1882, 1883 (Latch w Decoder Memory Interface)

See also:


file: /Techref/1802/index.htm, 26KB, , updated: 2023/6/20 20:21, local time: 2024/11/5 06:41,
TOP NEW HELP FIND: 
18.226.88.151:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/Techref/1802/index.htm"> 1802 Processor</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?