73 lines
3.9 KiB
Markdown
73 lines
3.9 KiB
Markdown
---
|
|
title: Learning Emulation, Part 2
|
|
date: 2016-11-23 23:23:18.664038
|
|
tags: ["C", "Emulation"]
|
|
---
|
|
_This is the second post in a series I'm writing about Chip-8 emulation. If you want to see the first one, head [here]({{< relref "/blog/01_learning_emulation.md" >}})._
|
|
|
|
Now that we have an understanding of the physical capabilities of a Chip-8 system, we can write code that will represent such a system on our computer. In this post we'll start writing some basic code - be prepared.
|
|
|
|
### A Simple Representation
|
|
We'll start with the memory. Chip-8 has, as we remember, 4096 memory locations, all of which are bytes. We will create an array of 4096 bytes to match that.
|
|
```
|
|
unsigned char memory[4096];
|
|
```
|
|
If we have instructions in memory, we also need what's called a program counter, a variable that points to the next instruction in memory we have to execute. This variable would never need to be negative, and hold a value of up to 4095. The type we use for the program counter would thus have to be bigger than a `char` (max unsigned value of 256). The next biggest type we can have would be a `short`.
|
|
```
|
|
unsigned short int pc;
|
|
```
|
|
Next up, the registers. They all hold an 8-bit value, which is always positive. We can represent them with a 16-long array.
|
|
```
|
|
unsigned char v[16];
|
|
```
|
|
_Note: I used `v` for the variable name as the registers are named `V0`-`VF`_ in the Chip-8 specs.
|
|
|
|
We also need to create the `I` register. As it's used to handle memory locations, it needs to be able to hold values up to 4095, just like the program counter. So we write it as a short integer.
|
|
```
|
|
unsigned short int i;
|
|
```
|
|
Now, the stack. The stack is, unsurprisingly, a [stack datastructure](https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29). According to the Wiki page on Chip-8,
|
|
> modern implementations [of the stack] normally have at least 16 levels
|
|
|
|
Because of that, we're going to represent the stack as a 16-long array of short integers. These integers will represent locations in memory at which a jump was made to a subroutine. If this sounds confusing, it'll be explained when we implement it. Additionally, we'd need a stack pointer, which holds a number up to 15 and gives the index in the stack of the latest value that was added.
|
|
```
|
|
unsigned short int stack[16];
|
|
unsigned char stackp;
|
|
```
|
|
We're almost there. We now need to add the timers. I do not remember seeing the size of these timers on the Wiki, so we'll represent them with generous integers.
|
|
```
|
|
unsigned int delay_timer;
|
|
unsigned int sound_timer;
|
|
```
|
|
Finally, we need a variable to hold the display pixels (which are true or false values). My code is in C, and C did not have a primitive boolean type out of the box unti C99. Because I'm mildly crazy, I will avoid this new feature and use, instead, a char. If your language of choice supports booleans (and / or you don't exhibit compulsive behaviors), by all means use them. Anyway, since the display is 64x32, we can make a display variable like this:
|
|
```
|
|
unsigned char display[64 * 32];
|
|
```
|
|
If we were to use booleans, this might look something like:
|
|
```
|
|
bool display[64 * 32];
|
|
```
|
|
Those are all the variables that we have to keep track of!
|
|
Let's group them under a single chip `struct`.
|
|
```
|
|
struct chip_s {
|
|
unsigned char memory[4096];
|
|
unsigned short int pc;
|
|
unsigned char v[16];
|
|
unsigned short int i;
|
|
|
|
unsigned short int stack[16];
|
|
unsigned char stackp;
|
|
|
|
unsigned int delay_timer;
|
|
unsigned int sound_timer;
|
|
|
|
unsigned char display[32 * 64];
|
|
};
|
|
```
|
|
Since this is C, if we were to just use a `struct` we'd have to use the `struct` keyword every time. To avoid doing that, I'll use a `typedef` to define a `chip_t` type:
|
|
```
|
|
typedef struct chip_s chip_t;
|
|
```
|
|
That's it for today! By the end of this post you should have a data type representing a simple Chip-8 machine. I think the next two posts will be independent of each other: one for basic rendering with GLFW, and one for actual Chip-8 code.
|