Avances y correccion basica, funciona pero con detalles
This commit is contained in:
BIN
roms/1-chip8-logo.ch8
Normal file
BIN
roms/1-chip8-logo.ch8
Normal file
Binary file not shown.
Binary file not shown.
BIN
roms/2-ibm-logo.ch8
Normal file
BIN
roms/2-ibm-logo.ch8
Normal file
Binary file not shown.
BIN
roms/3-corax+.ch8
Normal file
BIN
roms/3-corax+.ch8
Normal file
Binary file not shown.
BIN
roms/4-flags.ch8
Normal file
BIN
roms/4-flags.ch8
Normal file
Binary file not shown.
BIN
roms/5-quirks.ch8
Normal file
BIN
roms/5-quirks.ch8
Normal file
Binary file not shown.
BIN
roms/6-keypad.ch8
Normal file
BIN
roms/6-keypad.ch8
Normal file
Binary file not shown.
@@ -7,8 +7,11 @@
|
|||||||
|
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
|
|
||||||
Chip8::Chip8(): target_cycle_time(1.0 / 700.0), last_update_time(0), accumulator(0) {}
|
Chip8::Chip8(): target_cycle_time{1.0 / 700.0},
|
||||||
|
last_update_time{0},
|
||||||
|
accumulator{0},
|
||||||
|
run{false},
|
||||||
|
step{false} {}
|
||||||
|
|
||||||
bool Chip8::init() {
|
bool Chip8::init() {
|
||||||
if (!graphics.init()) {
|
if (!graphics.init()) {
|
||||||
@@ -18,11 +21,9 @@ bool Chip8::init() {
|
|||||||
last_update_time = SDL_GetTicks();
|
last_update_time = SDL_GetTicks();
|
||||||
accumulator = 0;
|
accumulator = 0;
|
||||||
|
|
||||||
const auto rom = read_rom("roms/1-ibm-logo.ch8");
|
const auto rom = read_rom("roms/6-keypad.ch8");
|
||||||
interpreter.load_rom(rom);
|
interpreter.load_rom(rom);
|
||||||
|
|
||||||
interpreter.display.set();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +31,6 @@ void Chip8::set_keyboard_state(std::span<const bool> keyboard_state) {
|
|||||||
this->keyboard_state = keyboard_state;
|
this->keyboard_state = keyboard_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> Chip8::read_rom(const std::string& path) {
|
std::vector<uint8_t> Chip8::read_rom(const std::string& path) {
|
||||||
std::ifstream rom_file(path, std::ios::binary);
|
std::ifstream rom_file(path, std::ios::binary);
|
||||||
|
|
||||||
@@ -72,24 +72,59 @@ void Chip8::load_keyboard() {
|
|||||||
|
|
||||||
|
|
||||||
void Chip8::update() {
|
void Chip8::update() {
|
||||||
auto current_time = SDL_GetTicks();
|
|
||||||
double delta_time = static_cast<double>(current_time - last_update_time) / 1000.0;
|
|
||||||
last_update_time = current_time;
|
|
||||||
accumulator += delta_time;
|
|
||||||
|
|
||||||
load_keyboard();
|
load_keyboard();
|
||||||
while (accumulator >= target_cycle_time) {
|
|
||||||
interpreter.run();
|
|
||||||
accumulator -= target_cycle_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << std::format("PC: {:03X} | SP: {:02X} | V0-VF: ", interpreter.pc, interpreter.sp);
|
buffer << std::format(
|
||||||
|
"PC: {:03X} | SP: {:02X} | I {:02X} | DT {:02X} | ST {:02X} | INST: {:02X}{:02X} | V0-VF: ",
|
||||||
|
interpreter.pc,
|
||||||
|
interpreter.sp,
|
||||||
|
interpreter.i,
|
||||||
|
interpreter.dt,
|
||||||
|
interpreter.st,
|
||||||
|
interpreter.memory[interpreter.pc],
|
||||||
|
interpreter.memory[interpreter.pc + 1]
|
||||||
|
);
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
buffer << std::format("{:02X}", interpreter.v[i]);
|
buffer << std::format("{:02X}", interpreter.v[i]);
|
||||||
if (i < 15) buffer << ",";
|
if (i < 15) buffer << ",";
|
||||||
}
|
}
|
||||||
buffer << " |";
|
buffer << " | ";
|
||||||
|
|
||||||
|
if (run) {
|
||||||
|
execute_instructions();
|
||||||
|
} else if (step) {
|
||||||
|
execute_instruction();
|
||||||
|
step = false;
|
||||||
|
last_update_time = SDL_GetTicks();
|
||||||
|
} else {
|
||||||
|
last_update_time = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
graphics.draw(interpreter.display, buffer.str());
|
graphics.draw(interpreter.display, buffer.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chip8::execute_instructions() {
|
||||||
|
const auto current_time = SDL_GetTicks();
|
||||||
|
const auto delta_time = static_cast<double>(current_time - last_update_time) / 1000.0;
|
||||||
|
last_update_time = current_time;
|
||||||
|
accumulator += delta_time;
|
||||||
|
|
||||||
|
while (accumulator >= target_cycle_time) {
|
||||||
|
execute_instruction();
|
||||||
|
accumulator -= target_cycle_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chip8::execute_instruction() {
|
||||||
|
interpreter.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chip8::on_keydown(SDL_Scancode scancode) {
|
||||||
|
if (scancode == SDL_SCANCODE_F1) {
|
||||||
|
run = !run;
|
||||||
|
} else if (scancode == SDL_SCANCODE_F2) {
|
||||||
|
step = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ class Chip8 {
|
|||||||
double accumulator;
|
double accumulator;
|
||||||
|
|
||||||
std::span<const bool> keyboard_state;
|
std::span<const bool> keyboard_state;
|
||||||
|
bool run;
|
||||||
|
bool step;
|
||||||
|
|
||||||
void load_keyboard();
|
void load_keyboard();
|
||||||
|
void execute_instructions();
|
||||||
|
void execute_instruction();
|
||||||
public:
|
public:
|
||||||
Chip8();
|
Chip8();
|
||||||
|
|
||||||
@@ -29,6 +32,7 @@ public:
|
|||||||
std::vector<uint8_t> read_rom(const std::string& path);
|
std::vector<uint8_t> read_rom(const std::string& path);
|
||||||
|
|
||||||
void set_keyboard_state(std::span<const bool> keyboard_state);
|
void set_keyboard_state(std::span<const bool> keyboard_state);
|
||||||
|
void on_keydown(SDL_Scancode scancode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Interpreter.h"
|
#include "Interpreter.h"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -60,13 +61,23 @@ void Interpreter::run() {
|
|||||||
const uint8_t low_instruction = memory[pc + 1];
|
const uint8_t low_instruction = memory[pc + 1];
|
||||||
const uint16_t instruction = (high_instruction << 8) | low_instruction;
|
const uint16_t instruction = (high_instruction << 8) | low_instruction;
|
||||||
|
|
||||||
const uint8_t opcode = instruction & 0xF000 >> 12;
|
const uint8_t opcode = (instruction & 0xF000) >> 12;
|
||||||
const uint8_t x = instruction & 0x0F00 >> 8;
|
const uint8_t x = (instruction & 0x0F00) >> 8;
|
||||||
const uint8_t y = instruction & 0x00F0 >> 4;
|
const uint8_t y = (instruction & 0x00F0) >> 4;
|
||||||
const uint8_t n = instruction & 0x000F;
|
const uint8_t n = instruction & 0x000F;
|
||||||
const uint8_t kk = instruction & 0x00FF;
|
const uint8_t kk = instruction & 0x00FF;
|
||||||
const uint16_t nnn = instruction & 0x0FFF;
|
const uint16_t nnn = instruction & 0x0FFF;
|
||||||
|
|
||||||
|
std::cout << std::format(
|
||||||
|
"INST: {:04X} | OPCODE: {:X} | X: {:X} | Y: {:X} | N: {:X} | KK: {:X} | NNN: {:X}",
|
||||||
|
instruction,
|
||||||
|
opcode,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
n,
|
||||||
|
kk,
|
||||||
|
nnn
|
||||||
|
) << std::endl;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
@@ -383,7 +394,7 @@ void Interpreter::display_sprite(uint8_t x, uint8_t y, const uint8_t n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto pixel = (sprite_byte >> (7 - bit)) & 0x01;
|
const auto pixel = (sprite_byte >> (7 - bit)) & 0x01;
|
||||||
const auto index = (start_y * 64) + current_x;
|
const auto index = (current_y * 64) + current_x;
|
||||||
|
|
||||||
if (pixel) {
|
if (pixel) {
|
||||||
if (display[index]) {
|
if (display[index]) {
|
||||||
@@ -475,59 +486,3 @@ void Interpreter::load_registers_from_memory(const uint8_t x) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::debug_display_console() {
|
|
||||||
std::cout << "\n=== CHIP-8 Display Debug ===" << std::endl;
|
|
||||||
std::cout << "Resolution: 64x32 pixels" << std::endl;
|
|
||||||
std::cout << "Display buffer size: " << display.size() << std::endl;
|
|
||||||
|
|
||||||
// Contar píxeles activos
|
|
||||||
int active_pixels = 0;
|
|
||||||
for (int i = 0; i < display.size(); i++) {
|
|
||||||
if (display[i]) active_pixels++;
|
|
||||||
}
|
|
||||||
std::cout << "Active pixels: " << active_pixels << std::endl;
|
|
||||||
|
|
||||||
std::cout << "\nDisplay contents:" << std::endl;
|
|
||||||
std::cout << " ";
|
|
||||||
|
|
||||||
// Números de columna (cada 8 píxeles)
|
|
||||||
for (int x = 0; x < 64; x += 8) {
|
|
||||||
std::cout << std::setw(2) << std::setfill(' ') << x << " ";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
// Dibujar el display
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
std::cout << std::setw(2) << std::setfill(' ') << y << " ";
|
|
||||||
|
|
||||||
for (int x = 0; x < 64; x++) {
|
|
||||||
int index = (y * 64) + x;
|
|
||||||
|
|
||||||
if (display[index]) {
|
|
||||||
std::cout << "█"; // Píxel activo
|
|
||||||
} else {
|
|
||||||
std::cout << "·"; // Píxel inactivo
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separador cada 8 píxeles para mayor legibilidad
|
|
||||||
if ((x + 1) % 8 == 0 && x < 63) {
|
|
||||||
std::cout << "|";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
// Línea separadora cada 8 filas
|
|
||||||
if ((y + 1) % 8 == 0 && y < 31) {
|
|
||||||
std::cout << " ";
|
|
||||||
for (int x = 0; x < 64; x++) {
|
|
||||||
std::cout << "-";
|
|
||||||
if ((x + 1) % 8 == 0 && x < 63) {
|
|
||||||
std::cout << "+";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << "=== End Display Debug ===" << std::endl << std::endl;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ public:
|
|||||||
void load_rom(const std::vector<uint8_t>& rom);
|
void load_rom(const std::vector<uint8_t>& rom);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void debug_display_console();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,16 @@ SDL_AppResult SDL_AppIterate(void* appstate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
||||||
|
const auto chip8 = static_cast<Chip8*>(appstate);
|
||||||
|
|
||||||
if (event->type == SDL_EVENT_QUIT) {
|
if (event->type == SDL_EVENT_QUIT) {
|
||||||
return SDL_APP_SUCCESS;
|
return SDL_APP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||||
|
chip8->on_keydown(event->key.scancode);
|
||||||
|
}
|
||||||
|
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user