alistair
9 months ago
4 changed files with 583 additions and 597 deletions
@ -1,4 +1,7 @@
@@ -1,4 +1,7 @@
|
||||
|
||||
|
||||
chip: chip.c |
||||
gcc -O2 main.c chip.c -Wall -Wextra -Werror -o chip
|
||||
|
||||
test: chip.c |
||||
gcc -O0 -g chip.c -fsanitize=address -fsanitize=undefined -Wall -Wextra -o test
|
||||
gcc -DDEBUG -O0 -g main.c chip.c -fsanitize=address -fsanitize=undefined -Wall -Wextra -o test
|
||||
|
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
|
||||
#pragma once |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
|
||||
void hexdump(const void *d, size_t datalen); |
||||
|
||||
#define DISPLAY_WIDTH_BYTES 8 |
||||
#define DISPLAY_WIDTH_BITS 64 |
||||
|
||||
#define DISPLAY_HEIGHT_BYTES 4 |
||||
#define DISPLAY_HEIGHT_BITS 32 |
||||
|
||||
struct display { |
||||
uint8_t *buffer; |
||||
uint8_t width; |
||||
uint8_t height; |
||||
int buffser_size; |
||||
}; |
||||
|
||||
struct emu_value { |
||||
uint8_t pad[0x27]; |
||||
uint16_t program_counter; |
||||
uint16_t pointer_register; |
||||
uint8_t registers[16]; |
||||
uint8_t extended_display_mode; |
||||
uint8_t delay_timer; |
||||
uint8_t sound_timer; |
||||
uint8_t font[80]; |
||||
uint16_t stack[160]; |
||||
uint8_t stack_top; |
||||
uint8_t unused; |
||||
}; |
||||
|
||||
typedef union { |
||||
uint8_t all_memory[0x1000]; |
||||
struct { |
||||
union { |
||||
struct emu_value values; |
||||
uint8_t reserved_memory[0x200]; |
||||
}; |
||||
uint8_t main_memory[0xE00]; |
||||
}; |
||||
} chip_memory; |
||||
|
||||
typedef struct { |
||||
chip_memory memory; |
||||
struct display display; |
||||
struct emu_value *value; |
||||
uint8_t display_pad1[4]; |
||||
uint8_t display_buffer[(2 * DISPLAY_WIDTH_BYTES) // max columns
|
||||
* (2 * DISPLAY_HEIGHT_BITS)]; // max rows
|
||||
uint8_t display_pad2[4]; |
||||
// struct emu_value reserved;
|
||||
} emu_state; |
||||
|
||||
void initialize(emu_state *state); |
||||
void print_display(struct display *display); |
||||
|
||||
void loop(emu_state *state); |
||||
|
||||
extern int chip_errored; |
||||
|
||||
#define info(str) \ |
||||
do { \
|
||||
printf("INFO %s:%d %s\n", __FILE__, __LINE__, str); \
|
||||
} while (0) |
||||
|
||||
#define warn(str) \ |
||||
do { \
|
||||
printf("WARN %s:%d %s\n", __FILE__, __LINE__, str); \
|
||||
} while (0) |
||||
|
||||
#define error(str) \ |
||||
do { \
|
||||
printf("ERRO %s:%d %s\n", __FILE__, __LINE__, str); \
|
||||
chip_errored = 1; \
|
||||
} while (0) |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
|
||||
#include "chip.h" |
||||
|
||||
#include <stdio.h> |
||||
#include <unistd.h> |
||||
|
||||
int main(int argc, char **argv) { |
||||
|
||||
emu_state state = {}; |
||||
|
||||
if (argc < 2) { |
||||
printf("No program given.\n"); |
||||
return 1; |
||||
} |
||||
|
||||
initialize(&state); |
||||
FILE *f = fopen(argv[1], "r"); |
||||
size_t err = 0; |
||||
size_t bytes = 0; |
||||
|
||||
do { |
||||
err = fread(state.memory.main_memory, sizeof(char), |
||||
sizeof(state.memory.main_memory), f); |
||||
bytes += err; |
||||
} while (err > 0); |
||||
fclose(f); |
||||
printf("Read bytes %ld\n", bytes); |
||||
|
||||
info("Read program in"); |
||||
hexdump(state.memory.all_memory, sizeof(state.memory.all_memory)); |
||||
|
||||
print_display(&state.display); |
||||
info("Starting."); |
||||
|
||||
while (!chip_errored) { |
||||
loop(&state); |
||||
usleep(3000); |
||||
} |
||||
|
||||
// hexdump(state.memory.all_memory, sizeof(state.memory.all_memory));
|
||||
print_display(&state.display); |
||||
} |
Loading…
Reference in new issue