This is part of a series of posts analysing the Chip-8 interpreter on the RCA COSMAC VIP computer. These posts may be useful if you are building a Chip-8 interpreter on another platform or if you have an interest in the operation of the COSMAC VIP. For other posts in the series refer to the index or instruction index.
INSTRUCTION GROUP: 3XNN
Skip if VX = NN
INSTRUCTION GROUP: 4XNN
Skip if VX ≠ NN
INSTRUCTION GROUP: 5XY0
Skip if VX = VY
INSTRUCTION GROUP: 9XY0
Skip if VX ≠ VY
INSTRUCTION GROUP: EX9E
Skip if VX = current key press
INSTRUCTION GROUP: EXA1
Skip if VX ≠ current key press
All of these instruction groups cause the following instruction to be skipped if their condition is true. They all work the same way – they perform the test and, if it is true, they increment the Chip-8 programme counter by 2 to skip the next instruction before returning to the fetch and decode routine. If it’s not true, they simply return to the fetch and decode routine.
Here’s the code for all of them:
Labels | Code (hex) | Comments |
NO_ SKIP: | D4 | This is the final instruction of the handler for group 1MMM instructions, but it is ‘borrowed’ by these handlers as a convenient way of returning to the fetch and decode routine. |
3XNN: | 45 | This is the entry point for the 3XNN instruction group (Skip if VX = NN). |
TEST_ FOR_ EQUALITY: | E6 | The VX pointer (R6) will now be used for register indirect addressing operations. |
0185 | F3 | XOR NN with the contents of VX. A number XOR’d with itself will be zero, so if the result of this operation is zero then the the contents of VX is equal to NN. |
0186 | 3A 82 | If VX does not equal NN (indicated by a non-zero result), then return to the fetch and decode routine. |
SKIP_ INSTR: | 15 | Skip first byte of next instruction |
0189 | 15 | Skip second byte of next instruction |
018A | D4 | Return to the fetch and decode routine. |
4XNN: | 45 | This is the entry point for the 4XNN instruction group (Skip if VX ≠ NN). On entry the Chip-8 programme counter (R5) will be pointing to the second byte of the instruction, which contains the value NN to be compared. This is loaded into the accumulator before the programme counter is advanced to point to the next Chip-8 instruction. |
TEST_ FOR_ INEQUALITY: | E6 | The VX pointer (R6) will now be used for register indirect addressing operations. |
018D | F3 | XOR NN with the contents of VX. A number XOR’d with itself will be zero, so if the result of this operation is not zero then the the contents of VX is not equal to NN. |
018E | 3A 88 | If VX does not equal NN (indicated by a non-zero result), then skip the next instruction. |
0190 | D4 | Return to the fetch and decode routine. |
9XY0: | 45 | This is the entry point for the 9XY0 instruction group (Skip if VX ≠ VY). |
0192 | 07 | Get the value in the VY variable into the accumulator. |
0193 | 30 8C | Branch to the test for inequality. The operands will be VX (pointed to by R6) and VY, which is now held in D. |
5XY0: | 45 | This is the entry point for the 5XY0 instruction group (Skip if VX = VY). |
0196 | 07 | Get the value in the VY variable into the accumulator. |
0197 | 30 84 | Branch to the test for inequality. The operands will be VX (pointed to by R6) and VY, which is now held in D. |
EX9E/EXA1: | E6 | This is the entry point for instruction groups EX9E (Skip if VX = current key press) and EXA1 (Skip if VX ≠ current key press). |
019A | 62 | This will take the value in VX and output it to the keyboard latch. This causes external flag 3 to be set if that key is currently held down or reset if not. |
019B | 26 | OUT instructions cause the register currently selected in X to be automatically advanced. This instruction resets the VX pointer to point to the correct variable. This is a necessary precaution because if the selected variable is VF, the increment will cause the VX pointer to be pointing to the wrong page entirely when the next instruction is fetched. |
019C | 45 | Get the second byte of the Chip-8 instruction and advance the Chip-8 programme counter (R5) |
019D | A3 | The second byte of the instruction is actually the low-order byte of the address of the next part of the handler to be run, depending on whether we are testing for a key being pressed (0x9E) or not being pressed (0xA1). This value is loaded into the interpreter programme counter (R3) so that execution continues from the correct point. |
019E | 36 88 | Execution continues from here for the EX9E instruction. |
01A0 | D4 | Return to the fetch and decode routine. |
01A1 | 3E 88 | Execution continues from here for the EXA1 instruction. |
01A3 | D4 | Return to the fetch and decode routine |
Timings for these instruction groups are shown in the table below:
Instruction Group | Evaluation Result | Machine Cycles | Execution Time (microseconds) |
3XNN & 4XNN | True | 14 | 63.56 |
3XNN & 4XNN | False | 10 | 45.4 |
5XY0 & 9XY0 | True | 18 | 81.72 |
5XY0 & 9XY0 | False | 14 | 63.56 |
EX9E & EXA1 | True | 18 | 81.72 |
EX9E & EXA1 | False | 14 | 63.56 |
Again, a contemporary interpreter is expected to implement all six of these instruction groups.
Be First to Comment