From 443fb46beb5c1b428436d89fe439edd1a30ef37a Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Thu, 26 Mar 2015 04:03:10 -0400 Subject: [PATCH] Add signal handling, plus basic instruction fetch logic. --- src/iomanager.c | 27 ++++++++++++++++++++++++++- src/z80.c | 22 ++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/iomanager.c b/src/iomanager.c index 2fff5e3..806b950 100644 --- a/src/iomanager.c +++ b/src/iomanager.c @@ -1,11 +1,24 @@ /* Copyright (C) 2014-2015 Ben Kurtovic Released under the terms of the MIT License. See LICENSE for details. */ +#include +#include #include #include "iomanager.h" #include "logging.h" +static volatile bool caught_signal; + +/* + Signal handler for SIGINT. +*/ +static void handle_sigint(int sig) +{ + (void) sig; // We don't care + caught_signal = true; +} + /* Emulate a Game Gear. Handle I/O with the host computer. @@ -13,11 +26,14 @@ */ void iomanager_emulate(GameGear *gg) { + caught_signal = false; + signal(SIGINT, handle_sigint); + DEBUG("IOManager powering GameGear") gamegear_power(gg, true); // TODO: use SDL events - while (1) { + while (!caught_signal) { if (gamegear_simulate(gg)) { ERROR("caught exception: %s", gamegear_get_exception(gg)) #ifdef DEBUG_MODE @@ -28,6 +44,15 @@ void iomanager_emulate(GameGear *gg) usleep(1000 * 1000 / 60); } + if (caught_signal) { + WARN("caught signal, stopping...") +#ifdef DEBUG_MODE + z80_dump_registers(&gg->cpu); +#endif + } + DEBUG("IOManager unpowering GameGear") gamegear_power(gg, false); + + signal(SIGINT, SIG_DFL); } diff --git a/src/z80.c b/src/z80.c index ba55b39..f572548 100644 --- a/src/z80.c +++ b/src/z80.c @@ -86,6 +86,19 @@ static inline uint8_t get_interrupt_mode(Z80 *z80) return 2; } +/* ------------------------------------------------------------------------- */ + +static uint8_t z80_inst_nop(Z80 *z80) { + z80->regfile.pc++; + return 4; +} + +static uint8_t (*instruction_lookup_table[256])(Z80*) = { + z80_inst_nop +}; + +/* ------------------------------------------------------------------------- */ + /* Emulate the given number of cycles of the Z80, or until an exception. @@ -98,9 +111,14 @@ bool z80_do_cycles(Z80 *z80, double cycles) if (z80->except) return true; - z80->pending_cycles += cycles; - // TODO: fetch instruction... + cycles -= z80->pending_cycles; + while (cycles > 0) { + // uint8_t opcode = mmu_read_byte(&z80->mmu, z80->regfile.pc); + uint8_t opcode = 0x00; + cycles -= (*instruction_lookup_table[opcode])(z80) - 2; + } + z80->pending_cycles = -cycles; return false; }