Chip-8 on the COSMAC VIP: Initialisation

This post is part of a series on the Chip-8 interpreter. In this post I will look at how the Chip-8 interpreter is launched and initialised on the COSMAC VIP. If you are unfamiliar with the RCA CDP1802 processor, you might want to read this earlier post first. In a previous post I talked about how the VIP’s ROM is executed. The ROM basically provides four functions:

  1. The user can enter bytes to be written to memory from a selected address
  2. The user can inspect the memory at a selected address to see what is stored there
  3. The user can save a block of memory to tape from a selected address
  4. The user can restore a block of memory from tape to a selected address

That’s it! To access these functions, the user must hold the C key down as they flip the RUN switch on the VIP. If they flip RUN without holding the C key the ROM will do just three things. First it will enable the RAM, then it will find the top of available RAM to determine how much memory the system has, then it will execute the programme stored in RAM at 0x0000.

So it is expected that the user has entered and verified the Chip-8 interpreter using functions 1 and 2, saved it for further use with function 3 and then used function 4 each time they want to run the interpreter.

Whenever any programme is first run on the VIP, the registers are configured as follows:

  • X is 0, so R0 will be used for indirect register addressing operations.
  • P is also 0, so R0 is the program counter.
  • R0 points to the start of RAM (0x0000).
  • R1 points to the last byte of on-card RAM (note that this might not be the last byte of all the RAM, if an external RAM module has been installed).
  • The remaining registers will be in an undefined state.

Another important thing to note is that the VIP’s display will be off at this point, so no screen refresh interrupts will be generated.

Chip-8 uses the general purpose 16-bit registers in different roles as follows:

Register Function
R0 DMA pointer for screen refresh
R1 Program counter for interrupt routine
R2 Stack pointer
R3 Interpreter subroutine/machine code subroutine program counter
R4 CALL (fetch and decode) subroutine program counter
R5 Chip-8 program counter
R6 VX pointer (this points to the chip-8 variable used as the first parameter in an instruction)
R7 VY pointer (this points to the chip-8 variable used as the second parameter in an instruction)
R8 Timers (R8.0 is the tone timer and R8.1 is the general purpose timer)
R9 Random number
RA I pointer
RB Display page pointer
RC Used for temporary storage only
RD Used for temporary storage only
RE Used for temporary storage only
RF Used for temporary storage only

I’ll explain these in more detail as they become relevant. One initial thing to note though, is that the roles chosen for each register are not arbitrary. Whenever DMA is used, as it is by the display controller in the COSMAC VIP, R0 is always used as the pointer to the memory to be accessed. Also whenever interrupts are enabled, as they will be when the display is switched on, R1 should always be set as the program counter for the interrupt routine and should initially be pointing to the first byte of that routine. Here’s a flowchart showing how the interpreter sets these up.

A flowchart showing the Chip-8 initialisation sequence

Here’s the code for this section of the interpreter.

Address (hex) Code (hex) Labels Assembly Comments
0000 91 GHI 1 When a program is initially run R1 points to the end of the last available page of on-card RAM.
0001 BB PHI B Sets RB to highest memory page (this is the display page)
0002 FF 01 SMI 0x01 Point to previous page in RAM
0004 B2 PHI 2 Set the high order byte of the stack pointer to this page
0005 B6 PHI 6 Set the high order byte of the VX pointer to this page
0006 F8 CF LDI 0xCF Initialise low order byte of stack pointer
0008 A2 PLO 2
0009 F8 81 LDI 0x81 These next four instructions set the Program Counter for the interrupt routine in R1 to 0x8146
000B B1 PHI 1
000C F8 46 LDI 0x46
000E A1 PLO 1
000F 90 GHI 0 Set R4 to 0x001B in preparation for assignment as Program Counter for the call routine
0010 B4 PHI 4
0011 F8 1B LDI 0x1B
0013 A4 PLO 4
0014 F8 01 LDI 0x01 Set R5 to 0x01FC. This register will act as the Chip 8 Program Counter.
0016 B5 PHI 5
0017 F8 FC LDI 0xFC
0019 A5 PLO 5
001A D4 SEP 4 R4 is now the interpreter program counter. This has no effect on the sequence at this point because R4 points to 001B which is the next instruction pointed to by the old PC in R0.

This sequence is run just once, when the interpreter first starts. The whole thing takes 40 machine cycles. One machine cycle on the CDP1802 requires 8 clock cycles. So, on the COSMAC VIP, which has a clock speed of 1.7609Mhz, one machine cycle takes 4.54 micro seconds. This equates to an execution time of 181.6 micro seconds for this routine.

For a programmer of a contemporary interpreter, the initialise sequence is unlikely to follow this pattern, although the basic tasks, such as initialising the stack pointer, will still need to be carried out.

In the next post in this series, I’ll look at the Chip-8 call, or fetch and decode, sequence in detail.

For other posts in this series, refer to the index or instruction index.

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

4 Responses to "Chip-8 on the COSMAC VIP: Initialisation"

Leave a reply