Chip-8 on the COSMAC VIP: Generating Random Numbers

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: CXNN
Load VX with a random number from 0 to 255 ANDed with NN

This instruction is essential for games or other applications where you need to generate apparently random behaviour.

This routine relies on a random number seed. Although this value is never explicitly initialised, because it uses register R9 it will be at zero when the interpreter is run. The interrupt routine in the COSMAC VIP’s operating system increments this value 60 times every second (see this earlier post on interrupts for more detail).

The random number seed is then modified further whenever a random number is generated. The flowchart shows how this works:

A flowchart showing the sequence for Chip-8 random number generation

Here’s the code for this routine:

Address (hex) Code (hex) Labels Assembly Comments
01D9 19 CXNN: INC 9 Increment random number seed (R9). This value is incremented 60 times a second by the interrupt routine, but this may not have run since the last random number was generated, so it is also incremented here
01DA 89 GLO 9 Get the low-order byte of the random number seed
01DB AE PLO E Save this in RE.0
01DC 93 GHI 3 Get the high order byte of the interpreter programme counter (This will be 0x01)
01DD BE PHI E Put this in RE.1. RE now points to a random byte of interpreter code in page 0x01
01DE 99 GHI 9 Get the high order byte of the random number seed
01DF EE SEX E Use RE for register indirect addressing
01E0 F4 ADD Add value of random byte from interpreter code to the current high-order byte of the random number seed
01E1 56 STR 6 Store this in VX
01E2 76 SHRC Shift the result one bit to the right. This will effectively divide the full result of the addition by 2 as it takes into account the carry bit generated by the addition
01E3 E6 SEX 6 Use VX pointer for register indirect addressing
01E4 F4 ADD Add current value in VX to shifted value in accumulator
01E5 B9 PHI 9 Save this as the new high-order byte of the random number seed
01E6 56 STR 6 Put this value in VX
01E7 45 LDA 5 Get second byte of Chip-8 instruction and advance programme counter
01E8 F2 AND Use this to mask the random number in VX
01E9 56 STR 6 Put final value in VX
01EA D4 SEP 4 Return to the fetch and decode routine

Execution time for this instruction is 36 machine cycles (163.44 microseconds).

There are a couple of things to note about this routine. Firstly, as it uses the code in the interpreter as a base source of numbers, the distribution of numbers will not be even. That’s not a massive issue – you probably wouldn’t want to use this random number generator as a source of numbers for any scientific experiment, but it’s perfectly adequate for games.

Secondly, the use of a mask gives this routine a lot of flexibility. The obvious use of the mask is to restrict numbers to a particular range. For example, if you wanted to generate only numbers between zero and 15, you could use CX0F (binary: 00001111). However, you can also do things like only generating even numbers (CXFE – binary: 11111110). Then you would just add 0x01 to the result to only generate odd numbers. You could also only generate multiples of a higher value. For example, multiples of 16 (CXF0 – binary 11110000).

The programmer of a contemporary interpreter should provide the correct behaviour for this instruction, including the masking. The method used for generating the numbers can either follow the algorithm of the original interpreter, or use the facility for random number generation that is provided by whatever language you are using for the interpreter. The former will result in behaviour that is more faithful to the original interpreter, but the latter will almost certainly result in a better distribution of numbers.

This entry was posted in Chip-8, Retro Computing and tagged , , , , . Bookmark the permalink.

2 Responses to "Chip-8 on the COSMAC VIP: Generating Random Numbers"

Leave a reply