-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchip8.h
123 lines (106 loc) · 4.95 KB
/
chip8.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef __CHIP8_H__
#define __CHIP8_H__
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// CHIP-8 run at 540 Hz
#define CYCLE_FREQUENCY 540
// delay around 1851 microseconds a cycle
#define CYCLE_DELAY(X) (1000000 / (X))
// delay around 16666 microseconds to decrease timer
#define TIMER_DELAY (1000000 / 60)
#define MEM_SIZE 4096
#define MEM_START 0x200
#define DISPLAY_HEIGHT 32
#define DISPLAY_WIDTH 64
#define KEY_SIZE 16
#define DISPLAY_WHITE 0xFFFFFFFF
#define DISPLAY_BLACK 0x00000000
#define FONTSET_SIZE 80
#define FONTSET_MEM_START 0x50
extern uint8_t chip8_fontset[];
typedef uint8_t byte;
enum sys_state { SYS_QUIT, SYS_RUNNING, SYS_PAUSE };
typedef struct chip8 {
uint8_t mem[MEM_SIZE];
uint8_t reg[16];
uint16_t index_reg;
uint16_t pc; // keep trace of opcode address
uint16_t opcode; // keep trace of opcode
uint16_t stack[16];
uint8_t sp; // keep trace of stack top
uint8_t delay_timer;
uint8_t sound_timer;
// 32-bit pixel format can store RGB color information and an 8-bit
// transparency channel (alpha channel)
uint32_t display[DISPLAY_HEIGHT][DISPLAY_WIDTH];
uint8_t keys[16]; // pressed or not
uint8_t display_refresh_flag;
enum sys_state state;
} CHIP8;
CHIP8 *chip8_init();
uint8_t chip8_load_rom(CHIP8 *chip8, const char *rom_name);
void chip8_cycle(CHIP8 *chip8);
void chip8_timer(CHIP8 *chip8);
#define _OPCODE (chip8->opcode)
#define X(opcode) (uint8_t)((0x0F00 & (opcode)) >> 8)
#define Y(opcode) (uint8_t)((0x00F0 & (opcode)) >> 4)
#define N(opcode) (uint8_t)(0x000F & (opcode))
#define NN(opcode) (uint8_t)(0x00FF & (opcode))
#define NNN(opcode) (uint16_t)(0x0FFF & (opcode))
#define VX(opcode) (chip8->reg[X(opcode)])
#define VY(opcode) (chip8->reg[Y(opcode)])
#define _VF (chip8->reg[0xF])
#define _I (chip8->index_reg)
typedef void (*opcode_func)(CHIP8 *chip);
#define OPCODE(N) opcode_##N(chip8)
void opcode_00E0(CHIP8 *chip); // Clear the screen
void opcode_00EE(CHIP8 *chip); // Return from a subroutine
void opcode_1NNN(CHIP8 *chip); // Jump to address NNN
void opcode_2NNN(CHIP8 *chip); // Call subroutine at NNN
void opcode_3XNN(CHIP8 *chip); // Skip next instruction if VX equals NN
void opcode_4XNN(CHIP8 *chip); // Skip next instruction if VX doesn't equal NN
void opcode_5XY0(CHIP8 *chip); // Skip next instruction if VX equals VY
void opcode_6XNN(CHIP8 *chip); // Set VX to NN
void opcode_7XNN(CHIP8 *chip); // Add NN to VX
void opcode_8XY0(CHIP8 *chip); // Set VX to the value of VY
void opcode_8XY1(CHIP8 *chip); // Set VX to VX OR VY
void opcode_8XY2(CHIP8 *chip); // Set VX to VX AND VY
void opcode_8XY3(CHIP8 *chip); // Set VX to VX XOR VY
void opcode_8XY4(
CHIP8 *chip); // Add VY to VX; VF is set to 1 if there's a carry, else 0
void opcode_8XY5(CHIP8 *chip); // Subtract VY from VX; VF is set to 0 if
// there's a borrow, else 1
void opcode_8XY6(CHIP8 *chip); // Store the least significant bit of VX in VF
// and then shift VX to the right by 1
void opcode_8XY7(CHIP8 *chip); // Set VX to VY minus VX; VF is set to 0 if
// there's a borrow, else 1
void opcode_8XYE(CHIP8 *chip); // Store the most significant bit of VX in VF
// and then shift VX to the left by 1
void opcode_9XY0(CHIP8 *chip); // Skip next instruction if VX doesn't equal VY
void opcode_ANNN(CHIP8 *chip); // Set I to the address NNN
void opcode_BNNN(CHIP8 *chip); // Jump to the address NNN plus V0
void opcode_CXNN(CHIP8 *chip); // Set VX to the result of a bitwise AND
// operation on a random number and NN
void opcode_DXYN(CHIP8 *chip); // Draw a sprite at coordinates VX, VY with a
// width of 8 pixels and a height of N pixels
void opcode_EX9E(
CHIP8 *chip); // Skip next instruction if the key stored in VX is pressed
void opcode_EXA1(CHIP8 *chip); // Skip next instruction if the key stored in VX
// isn't pressed
void opcode_FX07(CHIP8 *chip); // Set VX to the value of the delay timer
void opcode_FX0A(CHIP8 *chip); // Wait for a key press and store the key in VX
void opcode_FX15(CHIP8 *chip); // Set the delay timer to the value in VX
void opcode_FX18(CHIP8 *chip); // Set the sound timer to the value in VX
void opcode_FX1E(CHIP8 *chip); // Add the value stored in VX to I; VF is set to
// 1 if there's a range overflow, else 0
void opcode_FX29(CHIP8 *chip); // Set I to the location of the sprite for the
// character in VX
void opcode_FX33(CHIP8 *chip); // Store the binary-coded decimal representation
// of VX at address I, I+1, and I+2
void opcode_FX55(
CHIP8 *chip); // Store V0 to VX (inclusive) in memory starting at address I
void opcode_FX65(CHIP8 *chip); // Fill V0 to VX (inclusive) with values from
// memory starting at address I
#endif