COP8
This articleneeds additional citations forverification.(December 2009) |
TheNational SemiconductorCOP8is an 8-bitCISCcoremicrocontroller.COP8 is an enhancement to the earlierCOP4004-bit microcontroller family. COP8 main features are:
- Large amount ofI/Opins
- Up to 32 KB ofFlash memory/ROMfor code and data
- Very lowEMI(no known bugs)
- Many integrated peripherals (meant as single chip design)
- In-System Programming
- Freeassemblertoolchain. CommercialCcompilers available
- Free Multitasking OS andTCP/IPstack
It has a machine cycle of up to 2M cycles per second, but most versions seem to be overclockable to up to 2.8M cycles per second (28 MHz clock).[citation needed]
Registers and memory map[edit]
|
The COP8 uses separate instruction and data spaces (Harvard architecture).[1]: 2-1 [2]: 2-4 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-bitprogram counter.16 additional 8-bit registers (R0–R15) and an 8-bitprogram status wordare 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:
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 | Microwireshift 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, general purpose registers (additional RAM) |
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 0xFxcan 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 transfers[edit]
In addition to 3-byteJMPL
andJSRL
instructions which can address the entire address space, 2-byte versions of these instructions,JMP
andJSR
,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,JP
,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 branchesper sedo not exist, nor does the processor provide thetraditional 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,IFEQ
compares its two operands, and skips the following instruction if they are unequal. Any instruction may be skipped; it is not limited to branches.
A feature unique to the COP8 architecture is theIFBNE
instruction. This 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 reaches the end of a small (up to 16 byte) buffer.
An interesting extension of this mechanism is theRETSK
return-and-skip instruction, which lets any subroutine call conditionally skip the following instruction. This provides a very compact way to return aboolean valuefrom a subroutine.
Instruction set[edit]
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[B]
,the RAM address selected by the B register. Some instructions also support RAM addressing by the X register ([X]
), and post-inc/decrement variants ([B+]
,[B−]
,[X+]
,[X−]
).
Indirect addressing via B is particularly fast, and can be done in the same cycle that the instruction is executed.
On the other hand, absolute RAM addressing is not directly encoded in most cases. Rather, a special "direct addressing" prefix opcode, followed by a 1-byte address, may precede any instruction with a[B]
operand, and changes it to a memory direct operand. This adds two bytes and three cycles to the instruction. (Conditional-skip instructions skip the prefix and following instruction as a pair.)
All "move" instructions are calledLD
(load) even if the destination is a memory address. Unusually, there are noLD
instructions with the accumulator as a source; stores are done with theX
instruction whichexchangesthe accumulator with the memory operand, storing A and loading the previous memory contents. (This takes no additional time;X A,[B]
is a one-cycle instruction.)
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 (LAID
instruction) or the low 8 bits of the program counter PCL (JID
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.
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 reserved) | ||||
0 | 0 | 1 | 0 | addrhi | addrlo | — | JMPaddr12 | 3 | PC[11:0] ←address.Top 3 bits of PC preserved. | |||
0 | 0 | 1 | 1 | addrhi | addrlo | — | JSRaddr12 | 5 | Jump to subroutine: push PC, proceed as JMP. | |||
0 | 1 | 0 | 0 | k | — | — | IFBNE #imm4 | 1 | Execute next instruction if (B & 15) ≠k;skip if (B & 15) =k. | |||
0 | 1 | 0 | 1 | k | — | — | LD B,#imm4 | 1 | B ← 15 −k(zero-extended) | |||
0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | k | — | ANDSZ A,#imm8* | 2 | Skip if A &k= 0 (=IFBIT #bit,A) |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | addrlo | — | JSRBaddr8† | 5 | Push PC, jump to boot ROM subroutine at address[5] |
0 | 1 | 1 | 0 | 0 | 0 | 1 | – | — | — | (reserved for boot ROM†)[5] | ||
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 | A>>4; swap nibbles |
0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | — | — | DCOR A | 1 | Decimal correct afterBCDaddition |
0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | — | — | PUSH A* | 3 | [SP] ← A, SP ← SP−1 |
0 | 1 | 1 | 0 | 1 | bit | — | — | RBIT #bit,[B] | 1 | Reset (clear to 0) given bit of RAM | ||
0 | 1 | 1 | 1 | 0 | bit | — | — | IFBIT #bit,[B] | 1 | Test given bit of RAM, skip if zero | ||
0 | 1 | 1 | 1 | 1 | bit | — | — | SBIT #bit,[B] | 1 | Set (to 1) given bit of RAM | ||
1 | 0 | 0 | m | 0 | opcode | operand | — | ALU operations, A ← A opoperand | ||||
1 | 0 | 0 | 0 | 0 | opcode | — | — | OPA,[B] | 1 | ALU operation with A and [B] (with [address] using DIR prefix) | ||
1 | 0 | 0 | 1 | 0 | opcode | k | — | OPA,#imm8 | 2 | ALU operation with A and immediatek | ||
1 | 0 | 0 | m | 0 | 0 | 0 | 0 | operand | — | ADC A,operand | C,A ← A +operand+ C; add with carry | |
1 | 0 | 0 | m | 0 | 0 | 0 | 1 | operand | — | SUBC A,operand | C,A ← A + ~operand+ C (A −operand− ~C) | |
1 | 0 | 0 | m | 0 | 0 | 1 | 0 | operand | — | IFEQ A,operand | Skip if A ≠operand | |
1 | 0 | 0 | m | 0 | 0 | 1 | 1 | operand | — | IFGT A,operand | Skip if A ≤operand | |
1 | 0 | 0 | m | 0 | 1 | 0 | 0 | operand | — | ADD A,operand | A ← A +operand(carry unchanged!) | |
1 | 0 | 0 | m | 0 | 1 | 0 | 1 | operand | — | AND A,operand | A ← A &operand | |
1 | 0 | 0 | m | 0 | 1 | 1 | 0 | operand | — | XOR A,operand | A ← A ^operand | |
1 | 0 | 0 | m | 0 | 1 | 1 | 1 | operand | — | OR A,operand | A ← A |operand | |
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 A* | 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 | 0 | 0 | 0 | k | — | LD A,#imm8 | 2 | A ←k |
1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | k | — | IFNE A,#imm8* | 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 | address | — | X A,addr8 | 3 | A ↔ [address], exchange |
1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | address | — | LD A,addr8 | 3 | A ← [address] |
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,#imm8* | 2 | B ←k(one cycle faster than LD R14,#k) |
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 | 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 | 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 | 0 | 1 | 1 | 0 | — | — | X A,[B] | 1 | A ↔ [B] |
1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | — | — | (reserved) | ||
1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | — | — | RLC A* | 1 | C,A ← A,C; rotate left through carry (=ADC A,A) |
1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | address | k | IFEQaddr8,#imm8* | 3 | Skip if [address] ≠k |
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 | 0 | 0 | addrhi | addrlo | JMPLaddr15 | 4 | PC ←address |
1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | addrhi | addrlo | JSRLaddr15 | 5 | Push PC, PC ←address |
1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | — | — | LD A,[B] | 1 | A ← [B] |
1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | — | — | (reserved) | ||
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 | 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 | 0 | 0 | — | — | VIS* | 5 | PC ← ROM[vector table]; Vector Interrupt Select |
1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | — | — | RPND* | 1 | Reset pending interrupt flag |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | — | — | X A,[X] | 3 | A ↔ [X] |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | — | — | (reserved) | ||
1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | — | — | NOP | 1 | No operation |
1 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | — | — | IFNE A,[B]* | 1 | Skip if A = [B] |
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 | 0 | 0 | address | k | LDaddr8,#imm8 | 3 | [address] ←k |
1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | address | — | DIRaddr8 | 3 | Change next instruction's operand from [B] to [address] |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | — | — | LD A,[X] | 3 | A ← [X] |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | — | — | (reserved) | ||
1 | 1 | 0 | 0 | register | — | — | DRSZregister | 3 | register←register− 1, skip if result is zero | |||
1 | 1 | 0 | 1 | register | k | — | LDregister,#imm8 | 3 | register←k(=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 |
*: Only on "feature family" (COP888/COP8SA) cores; not present on "basic family" (COP800) cores.
†: Only on "flash family" (COP8TA/COP8C) models with boot ROM forin-system programming
References[edit]
- ^abCOP8 Basic Family User's Manual(PDF).Revision 002.National Semiconductor.June 1996. Literature Number 620895-002.Retrieved2021-01-02.
- ^abAleaf, Abdul (July 1996)."Comparison of COP878x to the Enhanced COP8SAx7 Family - Hardware/Software Considerations"(PDF).National Semiconductor.Application Note 1043.
- ^COP8 Feature Family User's Manual.Revision 005.National Semiconductor.March 1999. Literature Number 620897-005.Extracted fromzippedISO image530094-003_COP8_Tools_Docs_Aug1999.zip,retrieved 2020-01-07.
- ^"COP8SAx Designer's Guide"(PDF).National Semiconductor.January 1997. Literature Number 620894-001.
- ^ab"COP8SBR9/COP8SCR9/COP8SDR98-Bit CMOS Flash Based Microcontroller with 32k Memory, Virtual EEPROM and Brownout"(PDF)(data sheet).National Semiconductor.April 2002.Retrieved2021-01-06.
External links[edit]
- National Semiconductor Embedded Microcontrollers(CR16and COP8)
- microcontroller-faq/COP8,1995
- "National Semiconductor COP8".EDN’s 25th Annual Microprocessor/Microcontroller Directory.EDN.24 September 1998.