Initial commmit
A · Makefile +2, -01@@ -0,0 +1,2 @@
2+chip8: main.c
3+ $(CC) main.c -o chip8 `sdl2-config --cflags --libs` -Wall -Wextra -pedantic -std=c99
A · main.c
+171, -0 1@@ -0,0 +1,171 @@
2+/*** includes ***/
3+#include <SDL2/SDL.h>
4+#include <errno.h>
5+#include <stddef.h>
6+#include <stdio.h>
7+#include <sys/stat.h>
8+#include <time.h>
9+#include <unistd.h>
10+
11+/*** data ***/
12+// opcode store
13+// All opcodes are 2 bytes and so are unsigned short
14+unsigned short opcode;
15+// 4KB of RAM
16+unsigned char memory[4096];
17+// CPU Register
18+// 16 general purpose 8 bit registers
19+unsigned char V[16];
20+// Index or Address Register
21+unsigned short I;
22+// Program counter | A psudo register that points to the next instruction on the
23+// stack Instruction pointer being my preffered nomenclature
24+unsigned short pc;
25+// Display containing 2048 pixels in an array
26+unsigned char gfx[64 * 32];
27+// Timer registers that countdown to 0 at 60Hz
28+unsigned char delay_timer;
29+unsigned char sound_timer;
30+//
31+unsigned short stack[16];
32+unsigned short stack_pointer;
33+
34+// Fontset used by CHIP 8
35+// Also used to draw sprits using XOR
36+// DEC HEX BIN RESULT DEC HEX BIN RESULT
37+// 240 0xF0 1111 0000 **** 240 0xF0 1111 0000 ****
38+// 144 0x90 1001 0000 * * 16 0x10 0001 0000 *
39+// 144 0x90 1001 0000 * * 32 0x20 0010 0000 *
40+// 144 0x90 1001 0000 * * 64 0x40 0100 0000 *
41+// 240 0xF0 1111 0000 **** 64 0x40 0100 0000 *
42+
43+unsigned char chip8_fontset[80] = {
44+ 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
45+ 0x20, 0x60, 0x20, 0x20, 0x70, // 1
46+ 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
47+ 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
48+ 0x90, 0x90, 0xF0, 0x10, 0x10, // 4
49+ 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
50+ 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
51+ 0xF0, 0x10, 0x20, 0x40, 0x40, // 7
52+ 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
53+ 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
54+ 0xF0, 0x90, 0xF0, 0x90, 0x90, // A
55+ 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
56+ 0xF0, 0x80, 0x80, 0x80, 0xF0, // C
57+ 0xE0, 0x90, 0x90, 0x90, 0xE0, // D
58+ 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
59+ 0xF0, 0x80, 0xF0, 0x80, 0x80 // F
60+};
61+
62+// Keypad
63+unsigned char keypad[16];
64+
65+// Screen dimension constants
66+const int SCREEN_WIDTH = 640;
67+const int SCREEN_HEIGHT = 320;
68+
69+/*** initialize cpu ***/
70+void chip8_initialize(void) {
71+ pc = 0x200; // program counter starts at 0x200 or 512
72+ opcode = 0; // reset current opcode
73+ I = 0; // reset current index register
74+ stack_pointer = 0; // reset stack pointer
75+ printf("Chip 8 Initialized successfully \n");
76+ // Load fontset into memory
77+ //for (int i = 0; i < 80; i++) {
78+ // memory[i] = fontset[i];
79+ // }
80+ memcpy(memory, chip8_fontset, sizeof(chip8_fontset));
81+}
82+
83+/*** load rom ***/
84+void chip8_load_program(char *filename) {
85+ FILE *program = fopen(filename, "rb");
86+
87+ // get file size
88+ fseek(program, 0, SEEK_END);
89+ long buf_len = ftell(program);
90+ rewind(program);
91+
92+ // load data into buffer
93+ char *buf = malloc((buf_len + 1) * sizeof(char));
94+ fread(buf, buf_len, 1, program);
95+ printf("Rom loaded succesfully \n");
96+ printf("Rom size: %zu bytes \n", buf_len);
97+ fclose(program);
98+
99+ // load rom into memory
100+ for (int i = 0; i < buf_len; i++) {
101+ memory[0x200 + i] = buf[i];
102+ // Big endian so check last two values from the right
103+ printf("Byte successfully read: %08X \n", buf[i]);
104+ }
105+ // clear buffer
106+ free(buf);
107+}
108+
109+/*** initialize display ***/
110+int chip8_init_display (){
111+ SDL_Init(SDL_INIT_VIDEO);
112+ // Init Window struct
113+ SDL_Window *window;
114+ // Init window
115+ window =
116+ SDL_CreateWindow(
117+ "CHIP8",
118+ SDL_WINDOWPOS_CENTERED,
119+ SDL_WINDOWPOS_CENTERED,
120+ SCREEN_WIDTH,
121+ SCREEN_HEIGHT,
122+ 0);
123+ // Init renderer struct
124+ SDL_Renderer* renderer;
125+ // Init renderer
126+ renderer =
127+ SDL_CreateRenderer(
128+ window,
129+ -1,
130+ SDL_RENDERER_ACCELERATED);
131+ //SDL Render color (background)
132+ SDL_SetRenderDrawColor( renderer, 0, 0, 0, 0 );
133+ // Clear the current color and use the one specified above
134+ SDL_RenderClear( renderer );
135+ // Shape
136+ SDL_Rect rectangle;
137+ rectangle.x = 0;
138+ rectangle.y = 0;
139+ rectangle.w = 90;
140+ rectangle.h = 100;
141+
142+ SDL_SetRenderDrawColor( renderer, 0, 0, 255, 255 );
143+ SDL_RenderFillRect( renderer, &rectangle );
144+ SDL_RenderPresent(renderer);
145+
146+
147+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
148+ printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
149+ return -1;
150+ }
151+
152+ // Check that the window was successfully created
153+ if (window == NULL) {
154+ // In the case that the window could not be made...
155+ printf("Could not create window: %s\n", SDL_GetError());
156+ return -1;
157+ }
158+ SDL_Delay(3000);
159+ // Pause execution for 3000 milliseconds, for example
160+ // Close and destroy the window
161+ SDL_DestroyWindow(window);
162+ // Clean up
163+ SDL_Quit();
164+ return 0;
165+}
166+
167+int main(int argc, char *argv[]) {
168+ chip8_initialize();
169+ chip8_load_program(argv[1]);
170+ chip8_init_display();
171+ return 0;
172+}