Parcourir la source

Some improvements

Fix minor bugs (pong, pong2 now works)
Add fontset support
Still outstanding bugs: pong doesn't keep track of score, aliens reappear.
Alex il y a 6 ans
Parent
révision
4d282a5f7d
1 fichiers modifiés avec 44 ajouts et 21 suppressions
  1. 44
    21
      main.c

+ 44
- 21
main.c Voir le fichier

@@ -5,7 +5,7 @@
5 5
 #include <time.h>
6 6
 #include <SDL2/SDL.h>
7 7
 
8
-#define DEBUG 1
8
+#define DEBUG 0
9 9
 #define TDISP 0
10 10
 
11 11
 typedef uint8_t		byte;
@@ -23,6 +23,26 @@ typedef struct {
23 23
 	byte stack_pointer;
24 24
 } emulator_state_s;
25 25
 
26
+byte chip8_fontset[80] =
27
+{ 
28
+  0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
29
+  0x20, 0x60, 0x20, 0x20, 0x70, // 1
30
+  0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
31
+  0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
32
+  0x90, 0x90, 0xF0, 0x10, 0x10, // 4
33
+  0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
34
+  0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
35
+  0xF0, 0x10, 0x20, 0x40, 0x40, // 7
36
+  0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
37
+  0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
38
+  0xF0, 0x90, 0xF0, 0x90, 0x90, // A
39
+  0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
40
+  0xF0, 0x80, 0x80, 0x80, 0xF0, // C
41
+  0xE0, 0x90, 0x90, 0x90, 0xE0, // D
42
+  0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
43
+  0xF0, 0x80, 0xF0, 0x80, 0x80  // F
44
+};
45
+
26 46
 byte keymap[0x10] = { 	SDL_SCANCODE_X, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_Q, 
27 47
 						SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_D, 
28 48
 						SDL_SCANCODE_Z, SDL_SCANCODE_C, SDL_SCANCODE_4, SDL_SCANCODE_R, SDL_SCANCODE_F, SDL_SCANCODE_V };
@@ -41,6 +61,7 @@ int main(int argc, char **argv) {
41 61
 	
42 62
 	emulator_state_s state = { 0 }; // initialize everything to 0
43 63
 	state.program_counter = 0x200; // chip8 programs start at 0x200 address space
64
+	memcpy(state.memory, chip8_fontset, 80);
44 65
 	
45 66
 	FILE *f = fopen(argv[1], "rb");
46 67
 	fread(&state.memory[0x200], 0x1000 - 0x200, 1, f); // see above comment
@@ -75,7 +96,7 @@ int main(int argc, char **argv) {
75 96
 		// SDL_PumpEvents();
76 97
 		const byte *keystate = SDL_GetKeyboardState(NULL);
77 98
 
78
-		for (int i = 0; i < 0x10 && !press; ++i) {
99
+		for (int i = 0; i < 0x10; ++i) {
79 100
 			if (keystate[keymap[i]]){
80 101
 				state.input[i] = 1;
81 102
 				press = 1;
@@ -103,12 +124,10 @@ int main(int argc, char **argv) {
103 124
 			case 0x0000: // screen clear or function return 
104 125
 				if (opcode == 0x00E0){
105 126
 					memset(state.screen, 0, 64 * 32);
106
-					SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF);
107
-					SDL_RenderClear(renderer);
108 127
 					if (DEBUG) printf("Clearing screen ");
109 128
 				}
110 129
 				
111
-				else if (opcode = 0x00EE) {
130
+				else if (opcode == 0x00EE) {
112 131
 					state.program_counter = state.stack[--state.stack_pointer];
113 132
 					if (DEBUG) printf("Returning to %x ", state.stack[state.stack_pointer]);
114 133
 				}
@@ -161,14 +180,14 @@ int main(int argc, char **argv) {
161 180
 
162 181
 			case 0x6000: // set reg to constant
163 182
 				reg = (opcode & 0x0F00) >> 8;
164
-				state.registers[reg] = opcode & 0x00FF;
183
+				state.registers[reg] = (byte) opcode;
165 184
 				if (DEBUG) printf("Assigning %hx to %i", state.registers[reg], reg);
166 185
 
167 186
 				break;
168 187
 
169 188
 			case 0x7000: // add constant to reg
170 189
 				reg = (opcode & 0x0F00) >> 8;
171
-				state.registers[reg] += opcode & 0x00FF;
190
+				state.registers[reg] += (byte) opcode;
172 191
 				if (DEBUG) printf("Add %hi to reg %i (%hi)", opcode & 0x00FF, reg, state.registers[reg]);
173 192
 				
174 193
 				break;
@@ -203,23 +222,23 @@ int main(int argc, char **argv) {
203 222
 						unsigned int add = state.registers[first] + state.registers[second];
204 223
 						if (add > 255) state.registers[0xF] = 1;
205 224
 						else state.registers[0xF] = 0;
206
-						state.registers[first] = add & 0x00FF;
225
+						state.registers[first] = (byte) add;
207 226
 						if (DEBUG) printf("ADD register %i to %i (%hx) ", second, first, state.registers[first]);
208 227
 						if (DEBUG) printf("VF is %hx", state.registers[0xF]);
209 228
 						break;
210 229
 
211 230
 					case 5: // X = X - Y, VF = X - Y < 0
212 231
 						state.registers[first] -= state.registers[second];
213
-						if (state.registers[first] > state.registers[second]) state.registers[0xF] = 1;
214
-						else state.registers[0xF] = 0;
232
+						if (state.registers[first] > state.registers[second]) state.registers[0xF] = 0;
233
+						else state.registers[0xF] = 1;
215 234
 						if (DEBUG) printf("SUB register %i from %i (%hx) ", second, first, state.registers[first]);
216 235
 						if (DEBUG) printf("VF is %hx", state.registers[0xF]);
217 236
 						break;
218 237
 
219 238
 					case 6: // set least significant bit of X in VF, bitshift right
220
-						state.registers[0xF] = state.registers[first] & 0x000F;
239
+						state.registers[0xF] = state.registers[first] & 0b00000001;
221 240
 						state.registers[first] /= 2;
222
-						if (DEBUG) printf("RS register %i (%hx) ", first, second, state.registers[first]);
241
+						if (DEBUG) printf("RS register %i (%hx) ", first, state.registers[first]);
223 242
 						if (DEBUG) printf("VF is %hx", state.registers[0xF]);
224 243
 						break;
225 244
 
@@ -232,9 +251,9 @@ int main(int argc, char **argv) {
232 251
 						break;
233 252
 
234 253
 					case 0xE:; // set msot significant bit of X in VF, bitshift left
235
-						state.registers[0xF] = (state.registers[first] & 0xF000) >> 12;
254
+						state.registers[0xF] = (state.registers[first] & 0b10000000) >> 7;
236 255
 						state.registers[first] *= 2;
237
-						if (DEBUG) printf("LS register %i (%hx) ", first, second, state.registers[first]);
256
+						if (DEBUG) printf("LS register %i (%hx) ", first, state.registers[first]);
238 257
 						if (DEBUG) printf("VF is %hx", state.registers[0xF]);
239 258
 						break;
240 259
 
@@ -285,10 +304,13 @@ int main(int argc, char **argv) {
285 304
 					for (int xpos = 0; xpos < 8; ++xpos)
286 305
 					{
287 306
 						int ypos = y + line;
288
-						if (ypos > 63) ypos -= 64;
289
-						if (!(data & (1 << xpos))) continue;
290
-						if (state.screen[x + (7 - xpos)][ypos]) state.registers[0xF] = 1;
291
-						state.screen[x + (7 - xpos)][ypos] ^= 1;
307
+						byte mask = 1 << 7 - xpos;
308
+						if (ypos > 31) ypos -= 32;
309
+						if (!(data & mask)) continue;
310
+						if (state.screen[x + xpos][ypos]){
311
+							state.registers[0xF] = 1;
312
+						}
313
+						state.screen[x + xpos][ypos] ^= 1;
292 314
 					}
293 315
 				}
294 316
 
@@ -348,7 +370,8 @@ int main(int argc, char **argv) {
348 370
 						break;
349 371
 
350 372
 					case 0x29:
351
-						break; // fontset not implemented yet
373
+						state.address_I = state.registers[reg] * 5;
374
+						break;
352 375
 
353 376
 					case 0x33:;
354 377
 						int value = state.registers[reg];
@@ -358,12 +381,12 @@ int main(int argc, char **argv) {
358 381
 						break;
359 382
 
360 383
 					case 0x55:
361
-						for (int i = 0; i < (reg + 1); ++i)
384
+						for (int i = 0; i <= reg; ++i)
362 385
 							state.memory[state.address_I + i] = state.registers[i];
363 386
 						break;
364 387
 
365 388
 					case 0x65:
366
-						for (int i = 0; i < (reg + 1); ++i)
389
+						for (int i = 0; i <= reg + 1; ++i)
367 390
 							state.registers[i] = state.memory[state.address_I + i];
368 391
 						break;
369 392