From 7eeb85beb6bb44923e4046690604b5b07d79036e Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 29 Oct 2021 22:06:52 +0200 Subject: [PATCH] sms, improve cycle counting, fix vcounter for 224/240 lines --- pico/pico_int.h | 3 ++- pico/sms.c | 32 ++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/pico/pico_int.h b/pico/pico_int.h index 216138f5..e6da5182 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -199,7 +199,7 @@ extern struct DrZ80 drZ80; #define Z80_STATE_SIZE 0x60 #define z80_resetCycles() \ - Pico.t.z80c_cnt = Pico.t.z80c_aim = Pico.t.z80_scanline = 0 + Pico.t.z80c_cnt -= Pico.t.z80c_aim, Pico.t.z80c_aim = Pico.t.z80_scanline = 0 #define z80_cyclesDone() \ (Pico.t.z80c_aim - z80_cyclesLeft) @@ -437,6 +437,7 @@ struct PicoTiming unsigned int z80c_cnt; // z80 cycles done (this frame) unsigned int z80c_aim; + unsigned int z80c_line_start; int z80_scanline; int timer_a_next_oflow, timer_a_step; // in z80 cycles diff --git a/pico/sms.c b/pico/sms.c index 90b3007d..43321443 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -239,7 +239,7 @@ static void z80_sms_out(unsigned short a, unsigned char d) } else { // pad. latch hcounter if one of the TH lines is switched to 1 if ((Pico.ms.io_ctl ^ d) & d & 0xa0) - Pico.ms.vdp_hlatch = vdp_hcounter(228 - z80_cyclesLeft); + Pico.ms.vdp_hlatch = vdp_hcounter(z80_cyclesDone() - Pico.t.z80c_line_start); Pico.ms.io_ctl = d; } break; @@ -261,6 +261,12 @@ static void z80_sms_out(unsigned short a, unsigned char d) } } +static void z80_exec(int aim) +{ + Pico.t.z80c_aim = aim; + Pico.t.z80c_cnt += z80_run(Pico.t.z80c_aim - Pico.t.z80c_cnt); +} + // ROM/SRAM bank mapping, see https://www.smspower.org/Development/Mappers @@ -639,13 +645,13 @@ void PicoFrameMS(void) int is_pal = Pico.m.pal; int lines = is_pal ? 313 : 262; int cycles_line = 228; - int cycles_done = 0, cycles_aim = 0; int skip = PicoIn.skipFrame; int lines_vis = 192; int hint; // Hint counter int nmi; int y; + z80_resetCycles(); PsndStartFrame(); nmi = (PicoIn.pad[0] >> 7) & 1; @@ -661,12 +667,19 @@ void PicoFrameMS(void) for (y = 0; y < lines; y++) { pv->v_counter = Pico.m.scanline = y; - if (y > 218) - pv->v_counter = y - 6; + switch (is_pal ? -lines_vis : lines_vis) { + case 192: if (y > 218) pv->v_counter = y - (lines-256); break; + case 224: if (y > 234) pv->v_counter = y - (lines-256); break; + case -192: if (y > 242) pv->v_counter = y - (lines-256); break; + case -224: if (y > 258) pv->v_counter = y - (lines-256); break; + case -240: if (y > 266) pv->v_counter = y - (lines-256); break; + } if (y < lines_vis && !skip) PicoLineSMS(y); + Pico.t.z80c_line_start = Pico.t.z80c_aim; + // Interrupt handling. Simulate interrupt flagged and immediately reset in // same insn by flagging the irq, execute for 1 insn, then checking if the // irq is still pending. (GG Chicago, SMS Back to the Future III) @@ -676,18 +689,19 @@ void PicoFrameMS(void) { hint = pv->reg[0x0a]; pv->pending_ints |= 2; - cycles_done += z80_run(1); + z80_exec(Pico.t.z80c_cnt + 1); + if ((pv->reg[0] & 0x10) && (pv->pending_ints & 2)) { elprintf(EL_INTS, "hint"); z80_int_assert(1); } - pv->pending_ints &= ~2; + pv->pending_ints &= ~2; // lost if not caught immediately } } else if (y == lines_vis + 1) { pv->pending_ints &= ~2; pv->pending_ints |= 1; - cycles_done += z80_run(1); + z80_exec(Pico.t.z80c_cnt + 1); if ((pv->reg[1] & 0x20) && (pv->pending_ints & 1)) { elprintf(EL_INTS, "vint"); @@ -695,9 +709,7 @@ void PicoFrameMS(void) } } - cycles_aim += cycles_line; - Pico.t.z80c_aim = cycles_aim; - cycles_done += z80_run(cycles_aim - cycles_done); + z80_exec(Pico.t.z80c_line_start + cycles_line); } if (PicoIn.sndOut) -- 2.39.5