Difference between revisions of "CP1610"

From Intellivision Wiki
Jump to: navigation, search
m (General Behavior)
Line 17: Line 17:
  
 
==General Behavior==
 
==General Behavior==
The R7 register behaves as program counter for the CP1610.  When the CP1610 is reset, the R7 register value resets to $1000.  The CP1610 then reads, decodes, and executes the opcode at the location reference by R7 and the increments R7 to the next instruction.  It repeats this behavior indefinitely, or until a HLT instruction is read.<br/><br/>
+
The R7 register behaves as program counter for the CP1610.  On the Intellivision, the CP1610 initializes R7 to the value $1000.  The CP1610 then reads, decodes, and executes the opcode at the location reference by R7 and the increments R7 to the next instruction.  It repeats this behavior indefinitely, or until a HLT instruction is read.<br/><br/>
  
 
Although most opcodes are only one memory location in length (one 10-bit value or "decle"), a few opcodes stretch to two or three memory locations, causing R7 to increment by more than a single value in order to find the next instruction to execute.  The processor receives hardware interrupts from the STIC which occur once per screen refresh.  The STIC may also request the CP1610 temporarily halt processing to allow the STIC to perform direct memory accesses.<br/><br/>
 
Although most opcodes are only one memory location in length (one 10-bit value or "decle"), a few opcodes stretch to two or three memory locations, causing R7 to increment by more than a single value in order to find the next instruction to execute.  The processor receives hardware interrupts from the STIC which occur once per screen refresh.  The STIC may also request the CP1610 temporarily halt processing to allow the STIC to perform direct memory accesses.<br/><br/>

Revision as of 00:32, 11 January 2005

The CPU used in the Intellivision Master Component is a General Instruments CP1610. The CP1610 is a general purpose microprocessor capable of supporting 16-bit addresses and 10-bit instructions.

Overview

Clock Speed894,886.25 Hz
Address Width16-bit
Instruction Width10-bit
Reset Address$1000
Interrupt Address$1004
FlagsS, Z, O, C, I, D, inter
RegistersR0, R1, R2, R3, R4, R5, R6, R7
Signal PinsINTRM, BUSRQ, BUSAK
External PinsEXT


General Behavior

The R7 register behaves as program counter for the CP1610. On the Intellivision, the CP1610 initializes R7 to the value $1000. The CP1610 then reads, decodes, and executes the opcode at the location reference by R7 and the increments R7 to the next instruction. It repeats this behavior indefinitely, or until a HLT instruction is read.

Although most opcodes are only one memory location in length (one 10-bit value or "decle"), a few opcodes stretch to two or three memory locations, causing R7 to increment by more than a single value in order to find the next instruction to execute. The processor receives hardware interrupts from the STIC which occur once per screen refresh. The STIC may also request the CP1610 temporarily halt processing to allow the STIC to perform direct memory accesses.

Flags

SSign Flag. If set, indicates that the previous operation resulted in negative value.
CCarry Flag. If set, indicates that the previous operation resulted in a number too large to be contained in a single register.
ZZero Flag. If set, indicates that the previous operation resulted in zero.
OOverflow Flag. If set, indicates that the previous operation resulted in an overflow or underflow.
IInterrupt Enable Flag. If set, allows the INTRM line to trigger an interrupt, causing the CPU to jump to the interrupt subroutine located in the Executive ROM at $1004.
DDouble Data Flag. If set, causing the next opcode, if it is capable of operating on a 16-bit operand, to load the 16-bit operand from the lowest 8 bits of two consecutive memory locations, rather than all 16-bits of a single memory location.

Signal Pins

INTRMThis is an input pin connected to the SR1 output pin on the STIC. The STIC signals the CP1610 on this pin during vertical blank, and the CP1610 jumps to the interrupt vector at $1004 after the next interruptible instruction.
BUSRQThis is an input pin connected to the SR2 output pin on the STIC. The STIC signals the CP1610 on this pin when it wishes to perform direct memory accesses on the memory bus, and the CP1610 halts after the next interruptible instruction.
BUSAKThis is an output pin connected to the SST input pin on the STIC. The CP1610 acknowledges a request signaled by the STIC on BUSRQ by signaling back to the STIC on the BUSAK.
EXT 1-4There are 4 external pins which may be used as inputs to the CP1610. The BEXT instruction is used to branch based on the current value represented by these 4 pins. However, these pins are not connected in the Intellivision, so the BEXT instruction is typically never used.

Interruptibility

Each CP1610 opcode is considered either "interruptible" or "not interruptible". The interruptibility of an opcode determines whether or not the CP1610 checks the status of INTRM and BUSRQ. The CP1610 will only check for an interrupt request signaled via INTRM only if the I flag is set and only after the next interruptible instruction. Note that the signal from the STIC via INTRM is only alive for the duration of vertical blank, exactly 3,791 CP1610 clock cycles. If the I flag is clear for that entire duration, or if the CP1610 never encounters an interruptible instruction during that time, the CP1610 will miss the interrupt altogether. I have personally noticed this as a problem in particular for the game Dreadnaught Factor.

Similarly, the CP1610 only receives a signal from the STIC via BUSRQ for a total of exactly 114 CP1610 clock cycles. Although unaffected by the status of the I flag, if the CP1610 nonetheless encounters a stream of uninterruptible instructions, it will miss the chance to halt altogether and will fail to signal back to the STIC on BUSAK. The STIC, in turn, will fail to perform the necessary direct memory accesses to fetch the next row of cards to display. The exact behavior of the Intellivision hardware is unknown if this occurs, but it is believed to likely render a duplicate of the previous row of cards.

Registers

TBD

Instruction Set

Below is a detailed breakdown of all the opcodes available as a part of the CP1610 instruction set. This information is somewhat incomplete at the moment, but will be filled out a bit more in the near future.

RangeInstructionMnemonicOpcodeFlags
$0000HaLTHLT0000:0000:0000:0000 
$0001Set DouBle DataSDBD0000:0000:0000:0001
$0002Enable InterruptSEIS0000:0000:0000:0010
$0003Disable InterruptSDIS0000:0000:0000:0011
$0004JumpJ/JD/JE/J@
JSR/JSRD/JSRE/JSR@
0000:0000:0000:0100
$0005???TCI0000:0000:0000:0101
$0006CLeaR CarryCLRC0000:0000:0000:0110
$0007SET CarrySETC0000:0000:0000:0111
$0008-$000FINCrement RegisterINCR0000:0000:0000:1rrr
rrr = target register
$0010-$0017DECrement RegisterDECR0000:0000:0001:0rrr
rrr = target register
$0018-$001FCOMplement RegisterCOMR0000:0000:0001:1rrr
rrr = target register
$0020-$0027NEGate RegisterNEGR0000:0000:0010:0rrr
rrr = target register
$0028-$002FADd Carry to RegisterADCR0000:0000:0010:1rrr
rrr = target register
$0030-$0033Get the Status WorDGSWD0000:0000:0011:00rr
rr = target register
$0034-$0035No OPerationNOP0000:0000:0011:010x
x = ignored
$0036-$0037???SIN0000:0000:0011:011x
x = ignored
$0038-$003FRetrieve Status WorDRSWD0000:0000:0011:1rrr
rrr = target register
$0040-$0047SWAP bytesSWAP0000:0000:0100:0srr
s: 0 = swap once, 1 = swap twice
rr = target register
$0048-$004FShift Logical LeftSLL0000:0000:0100:1srr
s = shift count
rr = target register
$0050-$0057Rotate Left with CarryRLC0000:0000:0101:0srr
s = rotate count
rr = target register
$0058-$005FShift Logical Left with CarrySLLC0000:0000:0101:1srr
s = shift count
rr = target register
$0060-$0067Shift Logical RightSLR0000:0000:0110:0srr
s = shift count
rr = target register
$0068-$006FShift Arithmetic RightSAR0000:0000:0110:1srr
s = shift count
rr = target register
$0070-$0077Rotate Right with CarryRRC0000:0000:0111:0srr
s = rotate count
rr = target register
$0078-$007FShift Arithmetic Right with CarrySARC0000:0000:0111:1srr
s = shift count
rr = target register
$0080-$00BFMOVe RightMOVR0000:0000:10ss:sddd
sss = source register
ddd = destination register
$00C0-$00FFADD RegistersADDR0000:0000:11ss:sddd
sss = source register
ddd = destination register
$0100-$013FSUBtract RegistersSUBR0000:0001:00ss:sddd
sss = source register
ddd = destination register
$0140-$017FCoMPare RegistersCMPR0000:0001:01ss:sddd
sss = source register
ddd = destination register
$0180-$01BFAND RegistersANDR0000:0001:10ss:sddd
sss = source register
ddd = destination register
$01C0-$01FFXOR RegistersXORR0000:0001:11ss:sddd
sss = source register
ddd = destination register
$0200-$023FBranchB/BC/BOV/BPL
BEQ/BLT/BLE/BUSC
NOPP/BNC/BNOV/BMI
BNEQ/BGE/BGT/BESC
BEXT
0000:0010:00de:nccc
d = direction
e = external
n = negation
ccc = condition
$0240-$0247MoVe OutMVO0000:0010:0100:0rrr
rrr = register to move
$0248-$027FMoVe Out IndirectMVO@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$0280-$0287MoVe InMVI0000:0010:1000:0rrr
rrr = register to move
$0288-$02BFMoVe In IndirectMVI@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$02C0-$02C7ADDADD0000:0010:0100:0rrr
rrr = register to store result
$02C8-$02FFADD IndirectADD@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$0300-$0307SUBtractSUB0000:0010:0100:0rrr
rrr = register to store result
$0308-$033FSUBtract IndirectSUB@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$0340-$0347CoMPareCMP0000:0010:0100:0rrr
rrr = register to store result
$0348-$037FCoMPare IndirectCMP@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$0380-$0387ANDAND0000:0010:0100:0rrr
rrr = register to store result
$0388-$03BFAND IndirectAND@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to move
$03C0-$03C7XORXOR0000:0010:0100:0rrr
rrr = register to store result
$03C8-$03FFXOR IndirectXOR@0000:0010:01ss:srrr
sss = register with address (not zero)
rrr = register to store result