Difference between revisions of "CP1610"

From Intellivision Wiki
Jump to: navigation, search
(Registers)
 
(113 intermediate revisions by 54 users not shown)
Line 1: Line 1:
 
[[Category:CP1610]]
 
[[Category:CP1610]]
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.  <br/><br/>
+
The CPU used in the Intellivision [[Category:Master Component]] is a [[General Instruments]] CP1610.  The CP1610 is a general purpose microprocessor capable of supporting 16-bit addresses and 10-bit instructions.  <br/><br/>
  
 
==Overview==
 
==Overview==
 
<table border>
 
<table border>
<tr><td>Clock Speed</td><td>894,886.25 Hz</td></tr>
+
<tr><td>Clock Speed</td><td>894,886.25 Hz (NTSC)<br/>1MHz (PAL/SECAM)</td></tr>
 
<tr><td>Address Width</td><td>16-bit</td></tr>
 
<tr><td>Address Width</td><td>16-bit</td></tr>
<tr><td>Instruction Width</td><td>10-bit</td></tr>
+
<tr><td>Instruction Opcode Width</td><td>10-bit</td></tr>
 
<tr><td>Reset Address</td><td>$1000</td></tr>
 
<tr><td>Reset Address</td><td>$1000</td></tr>
 
<tr><td>Interrupt Address</td><td>$1004</td></tr>
 
<tr><td>Interrupt Address</td><td>$1004</td></tr>
<tr><td>Flags</td><td>S, Z, O, C, I, D, inter</td></tr>
+
<tr><td>[[#Flags|Flags]]</td><td>S, Z, O, C, I, D</td></tr>
<tr><td>Registers</td><td>R0, R1, R2, R3, R4, R5, R6, R7</td></tr>
+
<tr><td>[[#Registers|Registers]]</td><td>Eight 16-bit Registers, R0-R7</td></tr>
<tr><td>Signal Pins</td><td>INTRM, BUSRQ, BUSAK</td></tr>
 
<tr><td>External Pins</td><td>EXT</td></tr>
 
 
</table>
 
</table>
 
<br/>
 
<br/>
  
 
==General Behavior==
 
==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.<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.  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 CP1610 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/>
+
The processor also receives hardware interrupts from the [[STIC]] which occur once per screen refresh and cause the CP1610 to jump to the interrupt subroutine located at $1004 in the [[Executive ROM]].  The STIC may also request the CP1610 temporarily halt processing to allow the [[STIC]] to perform direct memory accesses.<br/><br/>
  
 
==Flags==
 
==Flags==
Line 26: Line 24:
 
<tr><td>C</td><td>[[Carry Flag]]</td><td>If set, indicates that the previous operation resulted in unsigned integer overflow.</td></tr>
 
<tr><td>C</td><td>[[Carry Flag]]</td><td>If set, indicates that the previous operation resulted in unsigned integer overflow.</td></tr>
 
<tr><td>Z</td><td>[[Zero Flag]]</td><td>If set, indicates that the previous operation resulted in zero.</td></tr>
 
<tr><td>Z</td><td>[[Zero Flag]]</td><td>If set, indicates that the previous operation resulted in zero.</td></tr>
<tr><td>O</td><td>Overflow Flag</td><td>If set, indicates that the previous operation gave a signed result that is inconsistent with the signs of the source operands.  (Signed overflow.)</td></tr>
+
<tr><td>O</td><td>[[Overflow Flag]]</td><td>If set, indicates that the previous operation gave a signed result that is inconsistent with the signs of the source operands.  (Signed overflow.)</td></tr>
<tr><td>I</td><td>Interrupt Enable Flag</td><td>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.</td></tr>
+
<tr><td>I</td><td>[[Interrupt Enable Flag]]</td><td>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.</td></tr>
<tr><td>D</td><td>Double Data Flag</td><td>If set, it causes 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.</td></tr>
+
<tr><td>D</td><td>[[Double Byte Data Flag]]</td><td>If set, it causes the next instruction to read a 16-bit operand with two 8-bit memory accesses, if it supports it.</td></tr>
 
</table><br/>
 
</table><br/>
  
 
Special notes:
 
Special notes:
* The S, C, Z, and O flags are directly visible to the programmer via the GSWD instruction.  The I and D flags are internal to the CPU, and not visible directly visible to the programmer.
+
* The S, C, Z, and O flags are directly visible to the programmer via the [[GSWD]] instruction.  The I and D flags are internal to the CPU, and not visible directly visible to the programmer.
* The C and O flags serve a secondary purpose for the shift and rotate instructions.  The SLLC, SARC, RLC and RRC use the C and O flags to store bits that get "shifted away."  Also, the RLC and RRC instructions "shift in" the bits stored in C and O.
+
* The C and O flags serve a secondary purpose for the shift and rotate instructions.  The [[SLLC]], [[SARC]], [[RLC]] and [[RRC]] use the C and O flags to store bits that get "shifted away."  Also, the [[RLC]] and [[RRC]] instructions "shift in" the bits stored in C and O.
* The S flag takes on a special role also with the shift instructions.  The SWAP, SLR, SAR, SARC and RRC instructions set the S flag based on bit 7 of the result, rather than bit 15.
+
* The S flag takes on a special role also with the shift instructions.  The [[SWAP]], [[SLR]], [[SAR]], [[SARC]] and [[RRC]] instructions set the S flag based on bit 7 of the result, rather than bit 15.<br/><br/>
  
 
==Signal Pins==
 
==Signal Pins==
Line 42: Line 40:
 
<td>A high-to-low transition on this pin causes the CPU to take an interrupt if interrupts are enabled.  If the signal transitions back to the "high" state prior to taking the interrupt, the CPU will ignore the interrupt.</td><td>Connects to the SR1 output pin on the STIC.  The STIC signals [[VBlank Interrupt]] to the CP1610 on this pin, and the CP1610 jumps to the interrupt vector at $1004 after the next interruptible instruction.</td></tr>
 
<td>A high-to-low transition on this pin causes the CPU to take an interrupt if interrupts are enabled.  If the signal transitions back to the "high" state prior to taking the interrupt, the CPU will ignore the interrupt.</td><td>Connects to the SR1 output pin on the STIC.  The STIC signals [[VBlank Interrupt]] to the CP1610 on this pin, and the CP1610 jumps to the interrupt vector at $1004 after the next interruptible instruction.</td></tr>
 
<tr><td>INTR</td><td>INTerrupt Request.</td><td>Input</td>
 
<tr><td>INTR</td><td>INTerrupt Request.</td><td>Input</td>
<td>A high-to-low transition on this pin causes the CPU to take an interrupt, regardles of whether interrupts are enabled.</td><td>The Intellivision leaves this signal tied to +5v (deasserted).</td></tr>  
+
<td>A high-to-low transition on this pin causes the CPU to take an interrupt, regardless of whether interrupts are enabled.</td><td>The Intellivision leaves this signal tied to +5v (deasserted).</td></tr>  
 
<tr><td>BUSRQ</td><td>BUS ReQuest.</td><td>Input</td>
 
<tr><td>BUSRQ</td><td>BUS ReQuest.</td><td>Input</td>
 
<td>A high-to-low transition on this pin requests that the CPU halt so that something else may access the bus.</td>
 
<td>A high-to-low transition on this pin requests that the CPU halt so that something else may access the bus.</td>
Line 61: Line 59:
 
<tr><td>PCIT</td><td>Program Counter Inhibit/Trap.</td><td>Bidirectional.</td>
 
<tr><td>PCIT</td><td>Program Counter Inhibit/Trap.</td><td>Bidirectional.</td>
 
<td>External hardware can prevent the CPU from incrementing the program counter by asserting this signal.  The SIN instruction generates a pulse on this line.</td><td> The Intellivision leaves this signal tied to +5v (deasserted) through a resistor.</td></tr>
 
<td>External hardware can prevent the CPU from incrementing the program counter by asserting this signal.  The SIN instruction generates a pulse on this line.</td><td> The Intellivision leaves this signal tied to +5v (deasserted) through a resistor.</td></tr>
<tr><td>STPST</td><td>SToP-STart.</td><td>Input</td><td>Stops or starts the execution of the CPU whenever it sees a high-to-low transition.</td><td>The Intellivision leaves this signal tied to +5v.</td></tr>
+
<tr><td>STPST</td><td>SToP-STart.</td><td>Input</td><td>Stops or starts the execution of the CPU whenever it sees a high-to-low transition.  Can restart the CPU after a [[HLT]] instruction.</td><td>The Intellivision leaves this signal tied to +5v.</td></tr>
<tr><td>HALT</td><td>HALTed.</td><td>Output</td><td>Indicates the CPU halted.</td><td>The Intellvision leaves this signal unconnected.</td></tr>
+
<tr><td>HALT</td><td>HALTed.</td><td>Output</td><td>Indicates the CPU halted, either due to STPST or a [[HLT]] instruction.</td><td>The Intellivision leaves this signal unconnected.</td></tr>
 
<tr><td>BDRDY</td><td>Bus Data ReaDY.</td><td>Input</td><td>When deasserted, it causes the CPU to wait for data to become available on the bus, effectively inserting wait states.</td><td>The Intellivision leaves this signal unconnected, and thus has no notion of wait states.</td></tr>
 
<tr><td>BDRDY</td><td>Bus Data ReaDY.</td><td>Input</td><td>When deasserted, it causes the CPU to wait for data to become available on the bus, effectively inserting wait states.</td><td>The Intellivision leaves this signal unconnected, and thus has no notion of wait states.</td></tr>
</table><br/>
+
</table><br/><br/>
  
 
==Interruptibility==
 
==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 after executing that instruction, and prior to executing the next.  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 altogetherI have personally noticed this as a problem in particular for the game Dreadnaught Factor.<br/><br/>
+
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 after executing that instruction, and prior to executing the next.  The CP1610 will check for an interrupt request signaled via INTRM only if <strong>both</strong> the [[Interrupt Enable Flag]] flag is set <strong>and</strong> previous instruction was an interruptible instruction.  It is important to understand that the [[Interrupt Enable Flag]] and the interruptibility of each opcode are completely separate functions and both work together to control when the CP1610 accepts interrupts on the INTRM lineFor more information on interrupts, see the [[VBlank Interrupt]] topic.<br/><br/>
  
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 displayThe 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.<br/><br/>
+
Similarly, the [[STIC]] only asserts BUSRQ to the CP1610 for 114 CP1610 clock cycles (on NTSC systems)The [[Interrupt Enable Flag]] does not affect the CPU's ability to respond to this bus request.  Non-interruptible instructions, however, do.  Thus, if a program contains an extended sequence of non-interruptible instructions, the CPU will not halt in time for the [[System RAM]] to prepare the next row of display cards.  Instead, the machine will duplicate the previous row and push the rest of the display down.  It appears that the CPU must halt within about 57 cycles of  
 +
BUSRQ first being asserted in order to prevent display glitches.<br/><br/>
  
 
==Registers==
 
==Registers==
Line 75: Line 74:
  
 
<table border>
 
<table border>
<tr><td>R0</td><td>General Purpose.</td></tr>
+
<tr><th colspan=2>Register Name</th><th>Description</th></tr>
<tr><td>R1</td><td>General Purpose.</td></tr>
+
<tr><th colspan=2>R0</th><td>General Purpose.</td></tr>
<tr><td>R2</td><td>General Purpose.</td></tr>
+
<tr><th colspan=2>R1</th><td>General Purpose.</td></tr>
<tr><td>R3</td><td>General Purpose.</td></tr>
+
<tr><th colspan=2>R2</th><td>General Purpose.</td></tr>
<tr><td>R4</td><td>General Purpose. Auto-Incrementing.</td></tr>
+
<tr><th colspan=2>R3</th><td>General Purpose.</td></tr>
<tr><td>R5</td><td>General Purpose. Auto-Incrementing.</td></tr>
+
<tr><th colspan=2>R4</th><td>General Purpose. Auto-increments on indirect reads and writes.</td></tr>
<tr><td>R6</td><td>General Purpose. Auto-Incrementing.  Auto-Decrementing.</td></tr>
+
<tr><th colspan=2>R5</th><td>General Purpose. Auto-increments on indirect reads and writes.</td></tr>
<tr><td>R7</td><td>Program Counter. Auto-Incrementing.</td></tr>
+
<tr><th>R6</th><th>SP</th><td>Stack Pointer. Auto-increments on indirect reads.  Auto-decrements on indirect writes.</td></tr>
 +
<tr><th>R7</th><th>PC</th><td>Program Counter. Auto-increments on indirect reads and writes.</td></tr>
 
</table>
 
</table>
<br/><br/>
+
<br/>
 +
The names "SP" and "PC" are assembler aliases for "R6" and "R7," respectively.  They may be used interchangeably.
 +
 
 +
==Addressing Modes==
 +
The CP1610 supports several addressing modes.  Click on any of the addressing modes below for more information.<br/>
 +
<table border>
 +
<tr><td>[[Implied Mode|Implied]]</td><td>The opcode's inputs or outputs are implied by the opcode itself.</td></tr>
 +
<tr><td>[[Register Mode|Register]]</td><td>The value to be read or written is contained in one or more registers. No memory access are required to execute Register-mode opcodes.</td></tr>
 +
<tr><td>[[Direct Mode|Direct]]</td><td>The address of the value to be read or written is specified by the value immediately following the address of the opcode.</td></tr>
 +
<tr><td>[[Immediate Mode|Immediate]]</td><td>The address of the value to be read or written is the address immediately following the opcode.  Note that immediate mode addressing is really just Indirect addressing using the R7 register.</td></tr>
 +
<tr><td>[[Indirect Mode|Indirect]]</td><td>The address of the value to be read or written is contained in one of the registers.</td></tr>
 +
<tr><td>[[Stack Mode|Stack]]</td><td>This [[Indirect Mode]] through R6, the stack pointer.</td></tr>
 +
</table><br/><br/>
  
 
==Instruction Set==
 
==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.<br/><br/>
+
Below is a detailed breakdown of all the opcodes available as a part of the CP1610 instruction set.  Click on each opcode for more information.  Also, you might look at the original [[GI Instruction Set Reference]], which is a handy (if occasionally incomplete or inaccurate) guide.<br/><br/>
 +
 
 
<table border width=100%>
 
<table border width=100%>
<tr><th width=1%>Range</th><th width=1%>Instruction</th><th width=1%>Mnemonic</th><th width=1%>Opcode</th><th>Flags</th></tr>
+
<tr><th width=1% rowspan=2>Range</th><th rowspan=2>Instruction</th><th rowspan=2>Mnemonic(s)</th><th width=1% rowspan=2>Cycles</th><th rowspan=2>Interruptible</th><th colspan=5>Input Flags</th><th colspan=6>Output Flags</th></tr>
<tr><td>$0000</td><td>[[Halt|HaLT]]</td><td>HLT</td><td>0000:0000:0000:0000</td><td>&#160;</td></tr>
+
 
<tr><td>$0001</td><td>Set DouBle Data</td><td>SDBD</td><td>0000:0000:0000:0001</td><td></td></tr>
+
<tr><th>S</th><th>Z</th><th>O</th><th>C</th><th>D</th><th>S</th><th>Z</th><th>O</th><th>C</th><th>I</th><th>D</th></tr>
<tr><td>$0002</td><td>Enable Interrupt System</td><td>EIS</td><td>0000:0000:0000:0010</td><td></td></tr>
+
 
<tr><td>$0003</td><td>Disable Interrupt System</td><td>DIS</td><td>0000:0000:0000:0011</td><td></td></tr>
+
<tr><td>$0000</td><td>[[HLT|Halt]]</td><td>[[HLT]]</td><td>NA</td><td>No</td><td colspan=5></td><td colspan=6></td></tr>
<tr><td>$0004</td><td>[[Jump]]</td><td>J/JD/JE/J@<br/>JSR/JSRD/JSRE/JSR@</td><td>0000:0000:0000:0100</td><td></td></tr>
+
 
<tr><td>$0005</td><td>Terminate Current Interrupt</td><td>TCI</td><td>0000:0000:0000:0101</td><td></td></tr>
+
<tr><td>$0001</td><td>[[SDBD|Set Double Byte Data]]</td><td>[[SDBD]]</td><td>4</td><td>No</td><td colspan=5><td colspan=5></td><td>D</td></tr>
<tr><td>$0006</td><td>CLeaR Carry</td><td>CLRC</td><td>0000:0000:0000:0110</td><td></td></tr>
+
 
<tr><td>$0007</td><td>SET Carry</td><td>SETC</td><td>0000:0000:0000:0111</td><td></td></tr>
+
<tr><td>$0002</td><td>[[EIS|Enable Interrupt System]]</td><td>[[EIS]]</td><td>4</td><td>No</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td nowrap>$0008-$000F</td><td>INCrement Register</td><td>INCR</td><td>0000:0000:0000:1rrr<br/>rrr = target register</td><td></td></tr>
+
 
<tr><td>$0010-$0017</td><td>DECrement Register</td><td>DECR</td><td>0000:0000:0001:0rrr<br/>rrr = target register</td><td></td></tr>
+
<tr><td>$0003</td><td>[[DIS|Disable Interrupt System]]</td><td>[[DIS]]</td><td>4</td><td>No</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td>$0018-$001F</td><td>COMplement Register</td><td>COMR</td><td>0000:0000:0001:1rrr<br/>rrr = target register</td><td></td></tr>
+
 
<tr><td>$0020-$0027</td><td>NEGate Register</td><td>NEGR</td><td>0000:0000:0010:0rrr<br/>rrr = target register</td><td></td></tr>
+
<tr><td rowspan=6>$0004</td><td rowspan=6>[[Jump]]</td><td>[[J]]</td><td>12</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
<tr><td>$0028-$002F</td><td>ADd Carry to Register</td><td>ADCR</td><td>0000:0000:0010:1rrr<br/>rrr = target register</td><td></td></tr>
+
 
<tr><td>$0030-$0033</td><td>Get the Status WorD</td><td>GSWD</td><td>0000:0000:0011:00rr<br/>rr = target register</td><td></td></tr>
+
<tr><td>[[JE]]</td><td>12</td><td>Yes</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td>$0034-$0035</td><td>No OPeration</td><td>NOP</td><td>0000:0000:0011:010x<br/>x = ignored</td><td></td></tr>
+
<tr><td>[[JD]]</td><td>12</td><td>Yes</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td>$0036-$0037</td><td>Software INterrupt</td><td>SIN</td><td>0000:0000:0011:011x<br/>x = ignored</td><td></td></tr>
+
<tr><td>[[JSR]]</td><td>12</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
<tr><td>$0038-$003F</td><td>Return Status WorD</td><td>RSWD</td><td>0000:0000:0011:1rrr<br/>rrr = target register</td><td></td></tr>
+
<tr><td>[[JSRE]]</td><td>12</td><td>Yes</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td>$0040-$0047</td><td>SWAP bytes</td><td>SWAP</td><td>0000:0000:0100:0srr<br/>s: 0 = swap once, 1 = swap twice<br/>rr = target register</td><td></td></tr>
+
<tr><td>[[JSRD]]</td><td>12</td><td>Yes</td><td colspan=5><td colspan=4></td><td>I</td><td></td></tr>
<tr><td>$0048-$004F</td><td>Shift Logical Left</td><td>SLL</td><td>0000:0000:0100:1srr<br/>s = shift count<br/>rr = target register</td><td></td></tr>
+
 
<tr><td>$0050-$0057</td><td>Rotate Left through Carry</td><td>RLC</td><td>0000:0000:0101:0srr<br/>s = rotate count<br/>rr = target register</td><td></td></tr>
+
<tr><td>$0005</td><td>[[TCI|Terminate Current Interrupt]]</td><td>[[TCI]]</td><td>4</td><td>No</td><td colspan=5><td colspan=6></td></tr>
<tr><td>$0058-$005F</td><td>Shift Logical Left through Carry</td><td>SLLC</td><td>0000:0000:0101:1srr<br/>s = shift count<br/>rr = target register</td><td></td></tr>
+
 
<tr><td>$0060-$0067</td><td>Shift Logical Right</td><td>SLR</td><td>0000:0000:0110:0srr<br/>s = shift count<br/>rr = target register</td><td></td></tr>
+
<tr><td>$0006</td><td>[[CLRC|Clear Carry]]</td><td>[[CLRC]]</td><td>4</td><td>No</td><td colspan=5><td colspan=3></td><td>C</td><td colspan=2></td></tr>
<tr><td>$0068-$006F</td><td>Shift Arithmetic Right</td><td>SAR</td><td>0000:0000:0110:1srr<br/>s = shift count<br/>rr = target register</td><td></td></tr>
+
 
<tr><td>$0070-$0077</td><td>Rotate Right through Carry</td><td>RRC</td><td>0000:0000:0111:0srr<br/>s = rotate count<br/>rr = target register</td><td></td></tr>
+
<tr><td>$0007</td><td>[[SETC|Set Carry]]</td><td>[[SETC]]</td><td>4</td><td>No</td><td colspan=5><td colspan=3></td><td>C</td><td colspan=2></td></tr>
<tr><td>$0078-$007F</td><td>Shift Arithmetic Rightthrough Carry</td><td>SARC</td><td>0000:0000:0111:1srr<br/>s = shift count<br/>rr = target register</td><td></td></tr>
+
 
<tr><td>$0080-$00BF</td><td>MOVe Register</td><td>MOVR</td><td>0000:0000:10ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
<tr><td>$0008-$000F</td><td>[[INCR|Increment Register]]</td><td>[[INCR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
<tr><td>$00C0-$00FF</td><td>ADD Registers</td><td>ADDR</td><td>0000:0000:11ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
 
<tr><td>$0100-$013F</td><td>SUBtract Registers</td><td>SUBR</td><td>0000:0001:00ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
<tr><td>$0010-$0017</td><td>[[DECR|Decrement Register]]</td><td>[[DECR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
<tr><td>$0140-$017F</td><td>CoMPare Registers</td><td>CMPR</td><td>0000:0001:01ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
 
<tr><td>$0180-$01BF</td><td>AND Registers</td><td>ANDR</td><td>0000:0001:10ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
<tr><td>$0018-$001F</td><td>[[COMR|Complement Register]]</td><td>[[COMR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
<tr><td>$01C0-$01FF</td><td>XOR Registers</td><td>XORR</td><td>0000:0001:11ss:sddd<br/>sss = source register<br/>ddd = destination register</td><td></td></tr>
+
 
<tr><td>$0200-$023F</td><td>Branch</td><td>B/BC/BOV/BPL<br/>BEQ/BLT/BLE/BUSC<br/>NOPP/BNC/BNOV/BMI<br/>BNEQ/BGE/BGT/BESC<br/>BEXT</td><td>0000:0010:00de:nccc<br/>d = direction<br/>e = external<br/>n = negation<br/>ccc = condition</td><td></td></tr>
+
<tr><td>$0020-$0027</td><td>[[NEGR|Negate Register]]</td><td>[[NEGR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
<tr><td>$0240-$0247</td><td>MoVe Out</td><td>MVO</td><td>0000:0010:0100:0rrr<br/>rrr = register to move</td><td></td></tr>
+
 
<tr><td>$0248-$027F</td><td>MoVe Out Indirect</td><td>MVO@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0028-$002F</td><td>[[ADCR|Add Carry to Register]]</td><td>[[ADCR]]</td><td>6</td><td>Yes</td><td colspan=3></td><td>C</td><td></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
<tr><td>$0280-$0287</td><td>MoVe In</td><td>MVI</td><td>0000:0010:1000:0rrr<br/>rrr = register to move</td><td></td></tr>
+
 
<tr><td>$0288-$02BF</td><td>MoVe In Indirect</td><td>MVI@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0030-$0033</td><td>[[GSWD|Get the Status Word]]</td><td>[[GSWD]]</td><td>6</td><td>Yes</td><td>S</td><td>Z</td><td>O</td><td>C</td><td></td><td colspan=6></td></tr>
<tr><td>$02C0-$02C7</td><td>ADD</td><td>ADD</td><td>0000:0010:0100:0rrr<br/>rrr = register to store result</td><td></td></tr>
+
 
<tr><td>$02C8-$02FF</td><td>ADD Indirect</td><td>ADD@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0034-$0035</td><td>[[NOP|No Operation]]</td><td>[[NOP]]</td><td>6</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
<tr><td>$0300-$0307</td><td>SUBtract</td><td>SUB</td><td>0000:0010:0100:0rrr<br/>rrr = register to store result</td><td></td></tr>
+
 
<tr><td>$0308-$033F</td><td>SUBtract Indirect</td><td>SUB@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0036-$0037</td><td>[[SIN|Software Interrupt]]</td><td>[[SIN]]</td><td>6</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
<tr><td>$0340-$0347</td><td>CoMPare</td><td>CMP</td><td>0000:0010:0100:0rrr<br/>rrr = register to store result</td><td></td></tr>
+
 
<tr><td>$0348-$037F</td><td>CoMPare Indirect</td><td>CMP@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0038-$003F</td><td>[[RSWD|Return Status Word]]</td><td>[[RSWD]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
<tr><td>$0380-$0387</td><td>AND</td><td>AND</td><td>0000:0010:0100:0rrr<br/>rrr = register to store result</td><td></td></tr>
+
 
<tr><td>$0388-$03BF</td><td>AND Indirect</td><td>AND@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to move</td><td></td></tr>
+
<tr><td>$0040-$0047</td><td>[[SWAP|Swap Bytes]]</td><td>[[SWAP]]</td><td>6/8</td><td>No</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
<tr><td>$03C0-$03C7</td><td>XOR</td><td>XOR</td><td>0000:0010:0100:0rrr<br/>rrr = register to store result</td><td></td></tr>
+
 
<tr><td>$03C8-$03FF</td><td>XOR Indirect</td><td>XOR@</td><td>0000:0010:01ss:srrr<br/>sss = register with address (not zero)<br/>rrr = register to store result</td><td></td></tr>
+
<tr><td>$0048-$004F</td><td>[[SLL|Shift Logical Left]]</td><td>[[SLL]]</td><td>6/8</td><td>No</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$0050-$0057</td><td>[[RLC|Rotate Left through Carry]]</td><td>[[RLC]]</td><td>6/8</td><td>No</td><td colspan=2></td><td>O</td><td>C</td><td></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0058-$005F</td><td>[[SLLC|Shift Logical Left through Carry]]</td><td>[[SLLC]]</td><td>6/8</td><td>No</td><td colspan=2></td><td>O</td><td>C</td><td></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0060-$0067</td><td>[[SLR|Shift Logical Right]]</td><td>[[SLR]]</td><td>6/8</td><td>No</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$0068-$006F</td><td>[[SAR|Shift Arithmetic Right]]</td><td>[[SAR]]</td><td>6/8</td><td>No</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$0070-$0077</td><td>[[RRC|Rotate Right through Carry]]</td><td>[[RRC]]</td><td>6/8</td><td>No</td><td colspan=2></td><td>O</td><td>C</td><td></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0078-$007F</td><td>[[SARC|Shift Arithmetic Right through Carry]]</td><td>[[SARC]]</td><td>6/8</td><td>No</td><td colspan=2></td><td>O</td><td>C</td><td></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0080-$00BF</td><td>[[MOVR|Move Register]]</td><td>[[MOVR]]</td><td>6/7</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$00C0-$00FF</td><td>[[ADDR|Add Registers]]</td><td>[[ADDR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0100-$013F</td><td>[[SUBR|Subtract Registers]]</td><td>[[SUBR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0140-$017F</td><td>[[CMPR|Compare Registers]]</td><td>[[CMPR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0180-$01BF</td><td>[[ANDR|And Registers]]</td><td>[[ANDR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$01C0-$01FF</td><td>[[XORR|Xor Registers]]</td><td>[[XORR]]</td><td>6</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td rowspan=17>$0200-$023F</td><td rowspan=17>[[Branch]]</td><td>[[B]]</td><td>9</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
 +
 
 +
<tr><td>[[BC]]</td><td>7/9</td><td>Yes</td><td colspan=3></td><td>C</td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[BOV]]</td><td>7/9</td><td>Yes</td><td colspan=2></td><td>O</td><td colspan=2></td><td colspan=6></td></tr>
 +
<tr><td>[[BPL]]</td><td>7/9</td><td>Yes</td><td>S</td><td colspan=4></td><td colspan=6></td></tr>
 +
<tr><td>[[BEQ]]</td><td>7/9</td><td>Yes</td><td></td><td>Z</td><td colspan=3></td><td colspan=6></td></tr>
 +
<tr><td>[[BLT]]</td><td>7/9</td><td>Yes</td><td>S</td><td></td><td>O</td><td colspan=2></td><td colspan=6></td></tr>
 +
<tr><td>[[BLE]]</td><td>7/9</td><td>Yes</td><td>S</td><td>Z</td><td>O</td><td></td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[BUSC]]</td><td>7/9</td><td>Yes</td><td>S</td><td colspan=2></TD><td>C</td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[NOPP]]</td><td>7</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
 +
<tr><td>[[BNC]]</td><td>7/9</td><td>Yes</td><td colspan=3></td><td>C</td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[BNOV]]</td><td>7/9</td><td>Yes</td><td colspan=2></td><td>O</td><td colspan=2></td><td colspan=6></td></tr>
 +
<tr><td>[[BMI]]</td><td>7/9</td><td>Yes</td><td>S</td><td colspan=4></td><td colspan=6></td></tr>
 +
<tr><td>[[BNEQ]]</td><td>7/9</td><td>Yes</td><td></td><td>Z</td><td colspan=3></td><td colspan=6></td></tr>
 +
<tr><td>[[BGE]]</td><td>7/9</td><td>Yes</td><td>S</td><td></td><td>O</td><td colspan=2></td><td colspan=6></td></tr>
 +
<tr><td>[[BGT]]</td><td>7/9</td><td>Yes</td><td>S</td><td>Z</td><td>O</td><td></td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[BESC]]</td><td>7/9</td><td>Yes</td><td>S</td><td colspan=2><td>C</td><td></td><td colspan=6></td></tr>
 +
<tr><td>[[BEXT]]</td><td>7/9</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$0240-$0247</td><td>[[MVO|Move Out]]</td><td>[[MVO]]</td><td>11</td><td>No</td><td colspan=5></td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$0248-$026F</td><td>[[MVO@|Move Out Indirect]]</td><td>[[MVO@]]</td><td>9</td><td>No</td><td colspan=4></td><td>D</td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$0270-$027F</td><td>[[MVOI|Move Out Immediate]]</td><td>[[MVOI]]</td><td>9</td><td>No</td><td colspan=4></td><td>D</td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$0280-$0287</td><td>[[MVI|Move In]]</td><td>[[MVI]]</td><td>10</td><td>Yes</td><td colspan=5></td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$0288-$02AF</td><td>[[MVI@|Move In Indirect]]</td><td>[[MVI@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$02B0-$02BF</td><td>[[MVII|Move In Immediate]]</td><td>[[MVII]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td colspan=6></td></tr>
 +
 
 +
<tr><td>$02C0-$02C7</td><td>[[ADD|Add]]</td><td>[[ADD]]</td><td>10</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$02C8-$02EF</td><td>[[ADD@|Add Indirect]]</td><td>[[ADD@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$02F0-$02FF</td><td>[[ADDI|Add Immediate]]</td><td>[[ADDI]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0300-$0307</td><td>[[SUB|Subtract]]</td><td>[[SUB]]</td><td>10</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0308-$032F</td><td>[[SUB@|Subtract Indirect]]</td><td>[[SUB@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0330-$033F</td><td>[[SUBI|Subtract Immediate]]</td><td>[[SUBI]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0340-$0347</td><td>[[CMP|Compare]]</td><td>[[CMP]]</td><td>10</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0348-$036F</td><td>[[CMP@|Compare Indirect]]</td><td>[[CMP@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0370-$037F</td><td>[[CMPI|Compare Immediate]]</td><td>[[CMPI]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td>O</td><td>C</td><td colspan=2></td></tr>
 +
 
 +
<tr><td>$0380-$0387</td><td>[[AND|And]]</td><td>[[AND]]</td><td>10</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$0388-$03AF</td><td>[[AND@|And Indirect]]</td><td>[[AND@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$03B0-$03BF</td><td>[[ANDI|And Immediate]]</td><td>[[ANDI]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$03C0-$03C7</td><td>[[XOR|Xor]]</td><td>[[XOR]]</td><td>10</td><td>Yes</td><td colspan=5></td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$03C8-$03EF</td><td>[[XOR@|Xor Indirect]]</td><td>[[XOR@]]</td><td>8/10/11</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 +
<tr><td>$03F0-$03FF</td><td>[[XORI|Xor Immediate]]</td><td>[[XORI]]</td><td>8/10</td><td>Yes</td><td colspan=4></td><td>D</td><td>S</td><td>Z</td><td colspan=4></td></tr>
 +
 
 
</table>
 
</table>

Latest revision as of 06:03, 5 August 2012

The CPU used in the Intellivision 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 (NTSC)
1MHz (PAL/SECAM)
Address Width16-bit
Instruction Opcode Width10-bit
Reset Address$1000
Interrupt Address$1004
FlagsS, Z, O, C, I, D
RegistersEight 16-bit Registers, R0-R7


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. 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 CP1610 repeats this behavior indefinitely, or until a HLT instruction is read.

The processor also receives hardware interrupts from the STIC which occur once per screen refresh and cause the CP1610 to jump to the interrupt subroutine located at $1004 in the Executive ROM. The STIC may also request the CP1610 temporarily halt processing to allow the STIC to perform direct memory accesses.

Flags

SSign FlagIf set, indicates that the previous operation resulted in negative value, which is determined by a one (1) in bit 15 of the result.
CCarry FlagIf set, indicates that the previous operation resulted in unsigned integer overflow.
ZZero FlagIf set, indicates that the previous operation resulted in zero.
OOverflow FlagIf set, indicates that the previous operation gave a signed result that is inconsistent with the signs of the source operands. (Signed overflow.)
IInterrupt Enable FlagIf 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 Byte Data FlagIf set, it causes the next instruction to read a 16-bit operand with two 8-bit memory accesses, if it supports it.

Special notes:

  • The S, C, Z, and O flags are directly visible to the programmer via the GSWD instruction. The I and D flags are internal to the CPU, and not visible directly visible to the programmer.
  • The C and O flags serve a secondary purpose for the shift and rotate instructions. The SLLC, SARC, RLC and RRC use the C and O flags to store bits that get "shifted away." Also, the RLC and RRC instructions "shift in" the bits stored in C and O.
  • The S flag takes on a special role also with the shift instructions. The SWAP, SLR, SAR, SARC and RRC instructions set the S flag based on bit 7 of the result, rather than bit 15.

Signal Pins

SignalNameDirectionPurposeUse on Intellivision
INTRMINTerrupt Request, Masked.Input A high-to-low transition on this pin causes the CPU to take an interrupt if interrupts are enabled. If the signal transitions back to the "high" state prior to taking the interrupt, the CPU will ignore the interrupt.Connects to the SR1 output pin on the STIC. The STIC signals VBlank Interrupt to the CP1610 on this pin, and the CP1610 jumps to the interrupt vector at $1004 after the next interruptible instruction.
INTRINTerrupt Request.Input A high-to-low transition on this pin causes the CPU to take an interrupt, regardless of whether interrupts are enabled.The Intellivision leaves this signal tied to +5v (deasserted).
BUSRQBUS ReQuest.Input A high-to-low transition on this pin requests that the CPU halt so that something else may access the bus. Connects to the SR2 output pin on the STIC. The STIC signals the CP1610 on this pin at points during active display when it needs to access System RAM. The CP1610 halts after the next interruptible instruction, regardless of whether interrupts are enabled.
BUSAKBUS AcKnowledge.Output Asserted (active-low output) when the CPU has yielded the bus. Connects to the SST input pins on the System RAM and the GROM. The CP1610 acknowledges the STIC's bus request by signaling to the System RAM and GROM that it halted by request of the STIC.
MSYNCMaster SYNC.Input Asserting this signal (active low) resets the CPU and synchronizes it to its clocks. Connects to the MSYNC output of the STIC. The STIC generates this signal shortly after powerup after the clock stabilizes, or whenever someone releases the reset button or asserts RESET on the cartridge port.
EBCA0 - EBCA3External Branch Condition Address.Output The four outputs EBCA0 through EBCA3, along with the single input ECBI provide a mechanism for external hardware to generate branch control inputs to the CPU. The BEXT instruction includes a 4-bit field that the CP1610 asserts on EBCA0 - EBCA3. External hardware then asserts a 0 or 1 on EBCI to indicate whether to take the branch. This allows up to 16 different branch conditions to be asserted to the CPU. These pins are not connected in the Intellivision, so the BEXT instruction is typically never used.
EBCIExternal Branch Condition Input.Input
TCITerminate Current Interrupt.Output TCI is both an instruction as well as a pin on the device. The TCI instruction pulses the TCI pin on the CP1610. The Intellivision leaves this signal unconnected, and so the TCI instruction is effectively a NOP.
PCITProgram Counter Inhibit/Trap.Bidirectional. External hardware can prevent the CPU from incrementing the program counter by asserting this signal. The SIN instruction generates a pulse on this line. The Intellivision leaves this signal tied to +5v (deasserted) through a resistor.
STPSTSToP-STart.InputStops or starts the execution of the CPU whenever it sees a high-to-low transition. Can restart the CPU after a HLT instruction.The Intellivision leaves this signal tied to +5v.
HALTHALTed.OutputIndicates the CPU halted, either due to STPST or a HLT instruction.The Intellivision leaves this signal unconnected.
BDRDYBus Data ReaDY.InputWhen deasserted, it causes the CPU to wait for data to become available on the bus, effectively inserting wait states.The Intellivision leaves this signal unconnected, and thus has no notion of wait states.


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 after executing that instruction, and prior to executing the next. The CP1610 will check for an interrupt request signaled via INTRM only if both the Interrupt Enable Flag flag is set and previous instruction was an interruptible instruction. It is important to understand that the Interrupt Enable Flag and the interruptibility of each opcode are completely separate functions and both work together to control when the CP1610 accepts interrupts on the INTRM line. For more information on interrupts, see the VBlank Interrupt topic.

Similarly, the STIC only asserts BUSRQ to the CP1610 for 114 CP1610 clock cycles (on NTSC systems). The Interrupt Enable Flag does not affect the CPU's ability to respond to this bus request. Non-interruptible instructions, however, do. Thus, if a program contains an extended sequence of non-interruptible instructions, the CPU will not halt in time for the System RAM to prepare the next row of display cards. Instead, the machine will duplicate the previous row and push the rest of the display down. It appears that the CPU must halt within about 57 cycles of BUSRQ first being asserted in order to prevent display glitches.

Registers

There are eight 16-bit registers available in the CP1610, labelled R0-R7.

Register NameDescription
R0General Purpose.
R1General Purpose.
R2General Purpose.
R3General Purpose.
R4General Purpose. Auto-increments on indirect reads and writes.
R5General Purpose. Auto-increments on indirect reads and writes.
R6SPStack Pointer. Auto-increments on indirect reads. Auto-decrements on indirect writes.
R7PCProgram Counter. Auto-increments on indirect reads and writes.


The names "SP" and "PC" are assembler aliases for "R6" and "R7," respectively. They may be used interchangeably.

Addressing Modes

The CP1610 supports several addressing modes. Click on any of the addressing modes below for more information.

ImpliedThe opcode's inputs or outputs are implied by the opcode itself.
RegisterThe value to be read or written is contained in one or more registers. No memory access are required to execute Register-mode opcodes.
DirectThe address of the value to be read or written is specified by the value immediately following the address of the opcode.
ImmediateThe address of the value to be read or written is the address immediately following the opcode. Note that immediate mode addressing is really just Indirect addressing using the R7 register.
IndirectThe address of the value to be read or written is contained in one of the registers.
StackThis Indirect Mode through R6, the stack pointer.


Instruction Set

Below is a detailed breakdown of all the opcodes available as a part of the CP1610 instruction set. Click on each opcode for more information. Also, you might look at the original GI Instruction Set Reference, which is a handy (if occasionally incomplete or inaccurate) guide.

RangeInstructionMnemonic(s)CyclesInterruptibleInput FlagsOutput Flags
SZOCDSZOCID
$0000HaltHLTNANo
$0001Set Double Byte DataSDBD4NoD
$0002Enable Interrupt SystemEIS4NoI
$0003Disable Interrupt SystemDIS4NoI
$0004JumpJ12Yes
JE12YesI
JD12YesI
JSR12Yes
JSRE12YesI
JSRD12YesI
$0005Terminate Current InterruptTCI4No
$0006Clear CarryCLRC4NoC
$0007Set CarrySETC4NoC
$0008-$000FIncrement RegisterINCR6YesSZ
$0010-$0017Decrement RegisterDECR6YesSZ
$0018-$001FComplement RegisterCOMR6YesSZ
$0020-$0027Negate RegisterNEGR6YesSZOC
$0028-$002FAdd Carry to RegisterADCR6YesCSZOC
$0030-$0033Get the Status WordGSWD6YesSZOC
$0034-$0035No OperationNOP6Yes
$0036-$0037Software InterruptSIN6Yes
$0038-$003FReturn Status WordRSWD6YesSZOC
$0040-$0047Swap BytesSWAP6/8NoSZ
$0048-$004FShift Logical LeftSLL6/8NoSZ
$0050-$0057Rotate Left through CarryRLC6/8NoOCSZOC
$0058-$005FShift Logical Left through CarrySLLC6/8NoOCSZOC
$0060-$0067Shift Logical RightSLR6/8NoSZ
$0068-$006FShift Arithmetic RightSAR6/8NoSZ
$0070-$0077Rotate Right through CarryRRC6/8NoOCSZOC
$0078-$007FShift Arithmetic Right through CarrySARC6/8NoOCSZOC
$0080-$00BFMove RegisterMOVR6/7YesSZ
$00C0-$00FFAdd RegistersADDR6YesSZOC
$0100-$013FSubtract RegistersSUBR6YesSZOC
$0140-$017FCompare RegistersCMPR6YesSZOC
$0180-$01BFAnd RegistersANDR6YesSZ
$01C0-$01FFXor RegistersXORR6YesSZ
$0200-$023FBranchB9Yes
BC7/9YesC
BOV7/9YesO
BPL7/9YesS
BEQ7/9YesZ
BLT7/9YesSO
BLE7/9YesSZO
BUSC7/9YesSC
NOPP7Yes
BNC7/9YesC
BNOV7/9YesO
BMI7/9YesS
BNEQ7/9YesZ
BGE7/9YesSO
BGT7/9YesSZO
BESC7/9YesSC
BEXT7/9Yes
$0240-$0247Move OutMVO11No
$0248-$026FMove Out IndirectMVO@9NoD
$0270-$027FMove Out ImmediateMVOI9NoD
$0280-$0287Move InMVI10Yes
$0288-$02AFMove In IndirectMVI@8/10/11YesD
$02B0-$02BFMove In ImmediateMVII8/10YesD
$02C0-$02C7AddADD10YesSZOC
$02C8-$02EFAdd IndirectADD@8/10/11YesDSZOC
$02F0-$02FFAdd ImmediateADDI8/10YesDSZOC
$0300-$0307SubtractSUB10YesSZOC
$0308-$032FSubtract IndirectSUB@8/10/11YesDSZOC
$0330-$033FSubtract ImmediateSUBI8/10YesDSZOC
$0340-$0347CompareCMP10YesSZOC
$0348-$036FCompare IndirectCMP@8/10/11YesDSZOC
$0370-$037FCompare ImmediateCMPI8/10YesDSZOC
$0380-$0387AndAND10YesSZ
$0388-$03AFAnd IndirectAND@8/10/11YesDSZ
$03B0-$03BFAnd ImmediateANDI8/10YesDSZ
$03C0-$03C7XorXOR10YesSZ
$03C8-$03EFXor IndirectXOR@8/10/11YesDSZ
$03F0-$03FFXor ImmediateXORI8/10YesDSZ