implement display

This commit is contained in:
2025-07-11 15:14:45 +02:00
parent 975e8939d0
commit 9bf79d3ad5
2 changed files with 58 additions and 9 deletions

3
build.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
set -xe
cc -O3 -o chip8 chip8.c -lSDL2

64
chip8.c
View File

@@ -1,4 +1,5 @@
// http://devernay.free.fr/hacks/chip8/C8TECH10.HTM // http://devernay.free.fr/hacks/chip8/C8TECH10.HTM
#include <SDL2/SDL.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -26,6 +27,8 @@ typedef struct CHIP8 {
uint16_t I; uint16_t I;
uint8_t delay_timer; uint8_t delay_timer;
uint8_t sound_timer; uint8_t sound_timer;
uint8_t keyboard[16];
uint8_t *display;
} CHIP8; } CHIP8;
CHIP8 chip8_create() { CHIP8 chip8_create() {
@@ -49,6 +52,7 @@ CHIP8 chip8_create() {
}; };
CHIP8 c = {0}; CHIP8 c = {0};
c.memory = calloc(1, 4096); c.memory = calloc(1, 4096);
c.display = calloc(1, 64 * 32);
for (size_t i = 0; i < 80; i++) for (size_t i = 0; i < 80; i++)
c.memory[i] = fonts[i]; c.memory[i] = fonts[i];
c.pc = 0x200; c.pc = 0x200;
@@ -194,15 +198,15 @@ void chip8_disassemble(CHIP8 *c, size_t ins_count) {
} }
} }
void chip8_execute(CHIP8 *c) { void chip8_step(CHIP8 *c) {
while (1) { do {
READ_INS(); READ_INS();
switch ((ins >> 12) & 0xF) { switch ((ins >> 12) & 0xF) {
case 0x0: { case 0x0: {
switch (nnn) { switch (nnn) {
case 0x0E0: case 0x0E0:
puts("TODO: CLS"); memset(c->display, 0, 64 * 32);
break; break;
case 0x0EE: case 0x0EE:
c->pc = c->stack[c->sp]; c->pc = c->stack[c->sp];
@@ -295,7 +299,21 @@ void chip8_execute(CHIP8 *c) {
c->reg[x] = (rand() % 256) & kk; c->reg[x] = (rand() % 256) & kk;
} break; } break;
case 0xD: { case 0xD: {
printf("TODO: DRW V%x, V%x, %u\n", x, y, n); c->reg[0xF] = 0;
for (size_t row = 0; row < n; row++) {
for (int col = 0; col < 8; col++) {
if ((c->memory[c->I + row] & (0b10000000 >> col)) != 0) {
size_t pixel_x = (c->reg[x] + col) % 64;
size_t pixel_y = (c->reg[y] + row) % 32;
size_t offset = pixel_x + (pixel_y * 64);
if (c->display[offset] == 1) {
c->reg[0xF] = 1;
}
c->display[offset] ^= 1;
}
}
}
} break; } break;
case 0xE: { case 0xE: {
switch (kk) { switch (kk) {
@@ -351,10 +369,13 @@ void chip8_execute(CHIP8 *c) {
default: default:
BAD_INS(); BAD_INS();
} }
} } while (0);
} }
void chip8_free(CHIP8 c) { free(c.memory); } void chip8_free(CHIP8 c) {
free(c.memory);
free(c.display);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc < 2) { if (argc < 2) {
@@ -373,8 +394,33 @@ int main(int argc, char *argv[]) {
c.memory[0x200 + i] = buffer[i]; c.memory[0x200 + i] = buffer[i];
} }
// chip8_disassemble(&c, n / 2); SDL_Init(SDL_INIT_VIDEO);
chip8_execute(&c); SDL_Window *window =
SDL_CreateWindow("CHIP-8", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 320, SDL_WINDOW_SHOWN);
SDL_Surface *surface = SDL_GetWindowSurface(window);
chip8_free(c); while (1) {
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
return 0;
}
}
chip8_step(&c);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF));
for (size_t y = 0; y < 32; y++) {
for (size_t x = 0; x < 64; x++) {
if (c.display[x + y * 64] == 1) {
SDL_Rect rect = {x * 10, y * 10, 10, 10};
SDL_FillRect(surface, &rect,
SDL_MapRGB(surface->format, 0x00, 0x00, 0x00));
}
}
}
SDL_UpdateWindowSurface(window);
}
} }