105 lines
3.5 KiB
C
105 lines
3.5 KiB
C
#include "headers/utils.h"
|
|
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "headers/stb_image.h"
|
|
|
|
// Prints an error (same argument format as printf)
|
|
// And stops the execution of the program
|
|
void critical_error(const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
printf("[Error] ");
|
|
vprintf(format, args);
|
|
va_end(args);
|
|
|
|
#ifdef USE_EMSCRIPT
|
|
emscripten_cancel_main_loop();
|
|
#endif
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Prints the binary representation of a number
|
|
void print_binary(uint32_t x, int n) {
|
|
printf(" ");
|
|
for (int i = n - 1; i >= 0; i--) {
|
|
printf("%d", (x >> i) & 1);
|
|
}
|
|
}
|
|
|
|
// Load a character set from an image
|
|
uint8_t* load_character_set(const char* path) {
|
|
// Load the PNG image using stb_image
|
|
int width, height, channels;
|
|
unsigned char* image_data = stbi_load(path, &width, &height, &channels, STBI_rgb);
|
|
|
|
if (image_data == NULL) {
|
|
critical_error("Could not load character set %s: %s\n", path, stbi_failure_reason());
|
|
}
|
|
|
|
uint8_t* packed_data = malloc(width * height * sizeof(uint8_t));
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
for (int x = 0; x < width; x++) {
|
|
int index = (y * width + x);
|
|
int indexRGB = (y * width + x) * channels;
|
|
unsigned char red = image_data[indexRGB];
|
|
if (index >= width * height) critical_error("error %d", index);
|
|
packed_data[index] = red ? 0 : 1;
|
|
//printf(packed_data[index] ? "X" : " ");
|
|
}
|
|
//printf("\n");
|
|
}
|
|
|
|
// Free the allocated memory for the image data
|
|
stbi_image_free(image_data);
|
|
|
|
printf("Loaded character set %s: %dx%dx%d\n", path, width, height, channels);
|
|
|
|
return packed_data;
|
|
}
|
|
|
|
// Prints the current state of the CPU
|
|
void cpu_debug(cpu_t* cpu) {
|
|
if (cpu->pc != 0x80010070) {
|
|
uint16_t instruction = (mem_read(cpu, cpu->pc, 1) << 8) | mem_read(cpu, cpu->pc + 1, 1);
|
|
uint8_t high = (instruction >> 12) & 0x0F;
|
|
uint8_t high8 = instruction >> 8;
|
|
uint8_t low = instruction & 0x0F;
|
|
uint8_t low8 = instruction & 0xFF;
|
|
|
|
printf("[%d][0x%08X] instruction: 0x%04X -", cpu->instruction_count, cpu->pc, instruction);
|
|
print_binary(instruction, 16);
|
|
print_binary(high, 4);
|
|
print_binary(low, 4);
|
|
printf("\n");
|
|
}
|
|
else printf("[%d][0x%08X] instruction: syscall\n", cpu->instruction_count, cpu->pc);
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
int r = cpu->r[i];
|
|
if (r != 0)
|
|
printf("r%d: 0x%08X, ", i, r);
|
|
}
|
|
|
|
printf("pr: 0x%08X, cursor: %d-%d, T: %d\n", cpu->pr, cpu->disp->cursor.col, cpu->disp->cursor.row, (cpu->sr >> 31) & 1);
|
|
// printf("pr: 0x%08X, macl: 0x%08X, gbr: 0x%08X, T: %d\n", cpu->pr, cpu->macl, cpu->gbr, cpu->disp->cursor.col, cpu->disp->cursor.row, (cpu->sr >> 31) & 1);
|
|
// printf("mem: 0x%02X 0x%02X 0x%02X 0x%02X\n", mem_read(cpu, 0x00300670, 1), mem_read(cpu, 0x00300670 + 1, 1), mem_read(cpu, 0x00300670 + 2, 1), mem_read(cpu, 0x00300670 + 3, 1));
|
|
}
|
|
|
|
// Prints the current state of the VRAM
|
|
void vram_debug(cpu_t* cpu) {
|
|
for (int y = 0; y < 64; y++) {
|
|
for (int x = 0; x < 16; x++) {
|
|
for (int b = 7; b >= 0; b--) {
|
|
int id = x + y * 16;
|
|
if (id < 0 || id >= VRAM_SIZE) critical_error("error %d", id);
|
|
int bit = ((cpu->disp->vram[id] >> b) & 1) || y == 0 || y == 63 || (x == 0 && b == 7) || (x == 15 && b == 0);
|
|
|
|
printf(bit ? "_" : "X");
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
printf("\n");
|
|
} |