Skip to content

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 starting at 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 starting from a selected address
  4. The user can restore a block of memory from tape to start at 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 programme 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 also 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 describing the Chip-8 initialisation process.
A flowchart describing the Chip-8 initialisation process

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

Labels
Address (hex)

Code (hex)
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 post index or instruction index.

Published inProgrammingRetro Computing

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *