From ca6f9bb91893cf50c8e09bf7396085a7d69e80ab Mon Sep 17 00:00:00 2001 From: gbc dev Date: Thu, 16 Jul 2026 12:49:02 +0200 Subject: headless: $ED opcode = clean power-off (exit + battery save) The unused SM83 opcode $ED now sets gb->poweroff, which breaks the headless loop so the normal cart_free()->cart_save() path runs. Lets a guest OS shut the emulator down cleanly (and flush its .sav) instead of relying on an external timeout/SIGTERM, which could SIGKILL before the save. run_frame() also stops on poweroff so exit is immediate. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c index 648ded2..935c9e7 100644 --- a/src/main.c +++ b/src/main.c @@ -24,7 +24,7 @@ static void run_frame(GB *gb) { gb->ppu.frame_ready = false; // safety bound in case LCD is off (no frame_ready) u64 budget = gb->cycles + 70224 * 2; - while (!gb->ppu.frame_ready && gb->cycles < budget) + while (!gb->ppu.frame_ready && gb->cycles < budget && !gb->poweroff) cpu_step(gb); } @@ -120,7 +120,7 @@ int main(int argc, char **argv) { double start_t = now_sec(); u64 start_cyc = gb->cycles; const double HZ = 4194304.0; - while (running) { + while (running && !gb->poweroff) { run_frame(gb); // advance ~a frame's worth of cycles if (!uncapped) { double target = start_t + (gb->cycles - start_cyc) / HZ; -- cgit v1.3.1-sl0p