COP8

Revision as of 04:14, 7 January 2025 by 97.102.205.224 (talk) (Update infobox to describe instruction cycle time; the input 10x clock is an implementation detail not suited for a summary infobox. Explain the mess in text: 10 MHz input clock, doubled (some models) to 20 MHz master clock, divided to 2 MHz instruction cycle. Also relevant is 0 Hz minimum clock rate (static design tolerates stopped clock).)
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

Template:About Template:Short description Template:Infobox CPU

The National Semiconductor COP8 is an 8-bit CISC core microcontroller. COP8 is an enhancement to the earlier COP400 4-bit microcontroller family. COP8 main features are:

  • Large amount of I/O pins
  • Up to 32 KB of Flash memory/ROM for code and data
  • Very low EMI
  • Many integrated peripherals (meant as single chip design)
  • In-System Programming
  • Free assembler toolchain. Commercial C compilers available
  • Free Multitasking OS and TCP/IP stack
  • Peak of 2 million instructions per second

The COP8 has a basic instruction cycle time 1/10 of the clock frequency; a maximum 10 MHz clock will result in a maximum 1 MHz instruction execution rate. (The 10 MHz clock is used directly by some timer peripherals.) The maximum instruction execution rate is 1 cycle per byte, and most 1-byte instructions operate in one instruction cycle. Some, particularly branch instructions, take one or two cycles more. Some models include a clock doubler, and although they still accept a maximum 10 MHz input clock, they internally double it to a 20 MHz master clock which then results in a 2 MHz instruction execution rate.Template:R

The chip is a static logic design which can tolerate an arbitrarily slow clock;Template:R most models include a second Template:Val quartz clock crystal oscillator which can be used for the CPU clock while the high-speed clock is disabled to save power.

Registers and memory mapEdit

COP8 registers
14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (bit position)
Main registers
A Accumulator
PCU PCL Program Counter
Note: All other programmer-visible registers and status bits are allocated in RAM.

The COP8 uses separate instruction and data spaces (Harvard architecture).Template:R Instruction address space is 15-bit (32 KiB maximum), while data addresses are 8-bit (256 bytes maximum, extended via bank-switching).

To allow software bugs to be caught, all invalid instruction addresses read as zero, which is a trap instruction. Invalid RAM above the stack reads as all-ones, which is an invalid address.

The CPU has an 8-bit accumulator and 15-bit program counter. 16 additional 8-bit registers (R0–R15) and an 8-bit program status word are memory mapped. There are special instructions to access them, but general RAM access instructions may also be used.

The memory map is divided into half RAM and half control registers as follows:

COP8 data address space
Addresses Use
0x00–6F General purpose RAM, used for stack
0x70–7F Unused, reads as all-ones (0xFF) to trap stack underflows
0x80–8F Unused, reads undefined
0x90–BF Additional peripheral control registers
0xC0–CF Peripheral control registers.
0xD0–DF General purpose I/O ports L, G, I, C and D
0xE0–E8 Reserved
0xE9 Microwire shift register
0xEA–ED Timer 1 registers
0xEE CNTRL register, control bits for Microwire & Timer 1
0xEF PSW, CPU program status word
0xF0–FB R0–R11, on-chip RAM mapped as registers
0xFC R12, a.k.a. X, secondary indirect pointer register
0xFD R13, a.k.a. SP, stack pointer register
0xFE R14, a.k.a. B, primary indirect pointer register
0xFF R15, a.k.a. S, data segment extension register

If RAM is not banked, then R15 (S) is just another general-purpose register. If RAM is banked, then the low half of the data address space (addresses 0x00–7F) is directed to a RAM bank selected by S. The special purpose registers in the high half of the data address space are always visible. The data registers at 0xFx can be used to copy data between banks.

RAM banks other than bank 0 have all 128 bytes available. The stack (addressed via the stack pointer) is always on bank 0, no matter how the S register is set.

Control transfersEdit

In addition to 3-byte <syntaxhighlight lang="text" class="" style="" inline="1">JMPL</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">JSRL</syntaxhighlight> instructions which can address the entire address space, 2-byte versions of these instructions, <syntaxhighlight lang="text" class="" style="" inline="1">JMP</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">JSR</syntaxhighlight>, can jump within a 4K page. The instruction specifies the low 12 bits, and the high 3 bits of the PC are preserved. (These are intended primarily for models with up to 4K of ROM.) For short-distance branches, there are 63 1-byte instructions, <syntaxhighlight lang="text" class="" style="" inline="1">JP</syntaxhighlight>, which perform PC-relative branches from PC−32 to PC+31. This is a 15-bit addition, and no page boundary requirements apply.

There are also jump indirect and load accumulator indirect instructions which use the accumulator contents as the low 8 bits of an address; the high 7 bits of the current PC are preserved.

Conditional branches per se do not exist, nor does the processor provide the traditional ZCVN status flags, although the program status word contains carry and half-carry flags for multi-byte arithmetic. Rather, there are a number of compare-and-skip instructions. For example, <syntaxhighlight lang="text" class="" style="" inline="1">IFEQ</syntaxhighlight> compares its two operands, and skips the following instruction if they are unequal. Any instruction may be skipped; it is not limited to branches.

An interesting extension of this mechanism is the <syntaxhighlight lang="text" class="" style="" inline="1">RETSK</syntaxhighlight> return-and-skip instruction, which lets any subroutine conditionally skip the instruction following the call. This provides a very compact way to return a boolean value from a subroutine.

Another feature unique to the COP8 architecture is the <syntaxhighlight lang="text" class="" style="" inline="1">IFBNE</syntaxhighlight> instruction. This one-byte instruction compares the low 4 bits of the B (memory pointer) register with a 4-bit immediate constant, and can be used to loop until B has reached the end of a small (up to 16 byte) buffer. There is also a one-byte <syntaxhighlight lang="text" class="" style="" inline="1">LD B,#imm4</syntaxhighlight> instruction.

Instruction setEdit

COP8 operands are listed in destination, source order. Most instructions have the accumulator A as one of the operands. The other operand is generally chosen from an 8-bit immediate value, an 8-bit RAM address, or <syntaxhighlight lang="text" class="" style="" inline="1">[B]</syntaxhighlight>, the RAM address selected by the B register. The <syntaxhighlight lang="text" class="" style="" inline="1">LD</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">X</syntaxhighlight> (exchange with accumulator) instructions also support RAM addressing by the X register (<syntaxhighlight lang="text" class="" style="" inline="1">[X]</syntaxhighlight>) and post-inc/decrement variants (<syntaxhighlight lang="text" class="" style="" inline="1">[B+]</syntaxhighlight>, <syntaxhighlight lang="text" class="" style="" inline="1">[B−]</syntaxhighlight>, <syntaxhighlight lang="text" class="" style="" inline="1">[X+]</syntaxhighlight>, <syntaxhighlight lang="text" class="" style="" inline="1">[X−]</syntaxhighlight>).

Indirect addressing via B is particularly fast, and can be done in the same cycle that the instruction is executed; even <syntaxhighlight lang="text" class="" style="" inline="1">X A,[B]</syntaxhighlight> is a one-cycle instruction.

On the other hand, absolute RAM addressing is only directly encoded for five instructions: LD A,addr8, X A,addr8, IFEQ addr8,#imm8, LD addr8,#imm8, and DIR addr8. The latter is a "direct addressing" prefix opcode which may be prepended to any instruction with a <syntaxhighlight lang="text" class="" style="" inline="1">[B]</syntaxhighlight> operand, and changes the operand to the specified memory location. (Conditional-skip instructions skip the prefix and following instruction as a pair.) Using <syntaxhighlight lang="text" class="" style="" inline="1">DIR</syntaxhighlight> with the <syntaxhighlight lang="text" class="" style="" inline="1">LD A,[B]</syntaxhighlight>, <syntaxhighlight lang="text" class="" style="" inline="1">X A,[B]</syntaxhighlight> and LD [B],#imm8 instructions is not documented, as the dedicated instructions are more efficient.

All "move" instructions are called <syntaxhighlight lang="text" class="" style="" inline="1">LD</syntaxhighlight> (load) even if the destination is a memory address (LD addr8,#imm8). Unusually, there are no <syntaxhighlight lang="text" class="" style="" inline="1">LD</syntaxhighlight> instructions with the accumulator as a source; stores must be done with the <syntaxhighlight lang="text" class="" style="" inline="1">X</syntaxhighlight> instruction which exchanges the accumulator with the memory operand, storing A and loading the previous memory contents.

There are instructions to fetch from tables in ROM. These combine the high 7 bits of the program counter (PCU) with the accumulator, fetch a byte from that address, and place it in the accumulator (<syntaxhighlight lang="text" class="" style="" inline="1">LAID</syntaxhighlight> instruction) or the low 8 bits of the program counter PCL (<syntaxhighlight lang="text" class="" style="" inline="1">JID</syntaxhighlight> instruction). Because the next instruction executed must be in the same 256-byte page of ROM as the table itself, a 256-entry table is not possible.

COP8 family instruction set<ref name=basic>Template:Cite book</ref><ref name=feature>Template:Cite book Extracted from zipped ISO image 530094-003_COP8_Tools_Docs_Aug1999.zip, retrieved 2020-01-07.</ref><ref name=comparison>{{#invoke:citation/CS1|citation
CitationClass=web

}}</ref><ref>{{#invoke:citation/CS1|citation

CitationClass=web

}}</ref>

Opcode Operands Mnemonic Cycles Description
7 6 5 4 3 2 1 0 b2 b3
0 0 0 0 0 0 0 0 INTR 7 Software interrupt (push PC, PC ← 0x00ff)
0 0 0 offset JP +disp5 3 PC ← PC + offset; jump 1–31 bytes forward (offset≠0)
0 0 1 0 high low JMP addr12 3 PC[11:0] ← addr. Top 3 bits of PC preserved.
0 0 1 1 high low JSR addr12 5 Jump to subroutine: push PC, proceed as JMP.
0 1 0 0 k IFBNE #imm4 1 Skip next instruction if (B & 15) = k.
0 1 0 1 k LD B,#imm4 1 B ← 15 − k (zero-extended)
0 1 1 0 0 opcode Miscellaneous instructions
0 1 1 0 0 0 0 0 k ANDSZ A,#imm8Template:Efn 2 Skip if A & k = 0 (=IFBIT #bit,A)
0 1 1 0 0 0 0 1 addr JSRB addr8Template:Efn 5 Push PC, jump to boot ROM subroutine at address<ref name=cop8s>{{#invoke:citation/CS1|citation CitationClass=web

}}</ref>

0 1 1 0 0 0 1 (reserved for boot ROM)Template:EfnTemplate:R
0 1 1 0 0 1 0 0 CLR A 1 A ← 0
0 1 1 0 0 1 0 1 SWAP A 1 A ← A<<4 Template:Pipe A>>4; swap nibbles
0 1 1 0 0 1 1 0 DCOR A 1 Decimal correct after BCD addition
0 1 1 0 0 1 1 1 PUSH ATemplate:Efn 3 [SP] ← A, SP ← SP−1
0 1 1 opc bit Bit operations on [B]Template:Efn
0 1 1 0 1 bit RBIT #bit,[B]Template:Efn 1 Reset (clear to 0) given bit of RAM
0 1 1 1 0 bit IFBIT #bit,[B]Template:Efn 1 Test given bit of RAM, skip if zero
0 1 1 1 1 bit SBIT #bit,[B]Template:Efn 1 Set (to 1) given bit of RAM
1 0 0 m 0 opcode k? Binary operations, A ← A op operand
1 0 0 0 0 opcode OP A,[B]Template:Efn 1 A ← A op [B]
1 0 0 1 0 opcode k OP A,#imm8 2 A ← A op k
1 0 0 m 0 0 0 0 k? ADC A,operand C,A ← A + operand + C; add with carry
1 0 0 m 0 0 0 1 k? SUBC A,operand C,A ← A + ~operand + C (A − operand − ~C)
1 0 0 m 0 0 1 0 k? IFEQ A,operand Skip if A ≠ operand
1 0 0 m 0 0 1 1 k? IFGT A,operand Skip if A ≤ operand
1 0 0 m 0 1 0 0 k? ADD A,operand A ← A + operand (carry unchanged!)
1 0 0 m 0 1 0 1 k? AND A,operand A ← A & operand
1 0 0 m 0 1 1 0 k? XOR A,operand A ← A ^ operand
1 0 0 m 0 1 1 1 k? OR A,operand A ← A Template:Pipe operand
1 0 0 0 1 opcode Zero-operand instructions
1 0 0 0 1 0 0 0 IFC 1 Skip if carry clear
1 0 0 0 1 0 0 1 IFNC 1 Skip if carry set
1 0 0 0 1 0 1 0 INC A 1 A ← A + 1 (carry unchanged)
1 0 0 0 1 0 1 1 DEC A 1 A ← A − 1 (carry unchanged)
1 0 0 0 1 1 0 0 POP ATemplate:Efn 3 SP ← SP+1, A ← [SP]
1 0 0 0 1 1 0 1 RETSK 5 Pop PC, skip one instruction
1 0 0 0 1 1 1 0 RET 5 Pop PC high, pop PC low
1 0 0 0 1 1 1 1 RETI 5 Return and enable interrupts
1 0 0 1 1 opcode k Instructions with immediate operand
1 0 0 1 1 0 0 0 k LD A,#imm8 2 A ← k
1 0 0 1 1 0 0 1 k IFNE A,#imm8Template:Efn 2 Skip if A = k
1 0 0 1 1 0 1 0 k LD [B+],#imm8 3 [B] ← k, B ← B + 1
1 0 0 1 1 0 1 1 k LD [B−],#imm8 3 [B] ← k, B ← B − 1
1 0 0 1 1 1 0 0 addr X A,addr8 3 A ↔ [addr], exchange
1 0 0 1 1 1 0 1 addr LD A,addr8 3 A ← [addr]
1 0 0 1 1 1 1 0 k LD [B],#imm8 2 [B] ← k
1 0 0 1 1 1 1 1 k LD B,#imm8Template:Efn 2 B ← k (=LD R14,#k, one cycle faster)
1 0 1 opcode 0 c Miscellaneous instructions
1 0 1 0 0 0 0 0 RC 1 C ← 0; reset carry to 0
1 0 1 0 0 0 0 1 SC 1 C ← 1; set carry to 1
1 0 1 0 0 1 0 0 LAID 3 A ← ROM[PCU:A]; load from ROM
1 0 1 0 0 1 0 1 JID 3 PCL ← ROM[PCU:A]; jump via ROM table
1 0 1 0 1 0 0 0 RLC ATemplate:Efn 1 C,A ← A,C; rotate left through carry (=ADC A,A)
1 0 1 0 1 0 0 1 addr k IFEQ addr8,#imm8Template:Efn 3 Skip if [addr] ≠ k
1 0 1 0 1 1 0 0 high low JMPL addr15 4 PC ← address
1 0 1 0 1 1 0 1 high low JSRL addr15 5 Push PC, PC ← address
1 0 1 1 0 0 0 0 RRC A 1 A,C ← C,A; rotate right through carry
1 0 1 1 0 0 0 1 (reserved)
1 0 1 1 0 1 0 0 VISTemplate:Efn 5 PC ← ROM[vector table]; Vector Interrupt Select
1 0 1 1 0 1 0 1 RPNDTemplate:Efn 1 Reset pending interrupt flag
1 0 1 1 1 0 0 0 NOP 1 No operation
1 0 1 1 1 0 0 1 IFNE A,[B]Template:EfnTemplate:Efn 1 Skip if A = [B]
1 0 1 1 1 1 0 0 addr k LD addr8,#imm8 3 [addr] ← k
1 0 1 1 1 1 0 1 addr Template:AnchorDIR addr8 3 Change next instruction's operand from [B] to [addr]
1 0 1 R L = 1 ± Load/exchange operations
1 0 1 0 0 0 1 0 X A,[B+] 2 A ↔ [B], B ← B+1
1 0 1 0 0 0 1 1 X A,[B−] 2 A ↔ [B], B ← B−1
1 0 1 0 0 1 1 0 X A,[B] 1 A ↔ [B]
1 0 1 0 1 0 1 0 LD A,[B+] 2 A ← [B], B ← B+1
1 0 1 0 1 0 1 1 LD A,[B−] 2 A ← [B], B ← B−1
1 0 1 0 1 1 1 0 LD A,[B] 1 A ← [B]
1 0 1 1 0 0 1 0 X A,[X+] 3 A ↔ [X], X ← X+1
1 0 1 1 0 0 1 1 X A,[X−] 3 A ↔ [X], X ← X−1
1 0 1 1 0 1 1 0 X A,[X] 3 A ↔ [X]
1 0 1 1 1 0 1 0 LD A,[X+] 3 A ← [X], X ← X+1
1 0 1 1 1 0 1 1 LD A,[X−] 3 A ← [X], X ← X−1
1 0 1 1 1 1 1 0 LD A,[X] 3 A ← [X]
1 0 1 1 1 1 (reserved)
1 1 0 0 register DRSZ register 3 registerregister − 1, skip if result is zero
1 1 0 1 register k LD register,#imm8 3 registerk (=LD 0xf0+register,#k, one byte shorter)
1 1 1 offset JP −disp5 3 PC ← PC − 32 + offset; jump 1–32 bytes backward
7 6 5 4 3 2 1 0 b2 b3 Mnemonic Cycles Description

Template:Notelist

Notable usesEdit

ReferencesEdit

Template:Reflist

External linksEdit

Template:8bitMCUs