From f61d0a4534142f1b40e2677a698f03110aa3be00 Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 9 Jun 2023 19:22:51 +0000 Subject: [PATCH] core, testpico fixes --- pico/memory.c | 31 ++++++++++++++++++++++++------- pico/pico_int.h | 2 +- pico/videoport.c | 12 ++++++++---- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/pico/memory.c b/pico/memory.c index 33e2aa5d..3cc2feea 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -1039,10 +1039,24 @@ static void m68k_mem_setup(void) static int get_scanline(int is_from_z80) { if (is_from_z80) { - int mclk_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim : z80_cyclesDone()) * 15; - int mclk_line = Pico.t.z80_scanline * 488 * 7; - while (mclk_z80 - mclk_line >= 488 * 7) - Pico.t.z80_scanline++, mclk_line += 488 * 7; + // ugh... compute by dividing cycles since frame start by cycles per line + // need some fractional resolution here, else there may be an extra line + int cycles_line = cycles_68k_to_z80(488 << 8); // cycles per line, as Q8 + int cycles_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim:z80_cyclesDone())<<8; + int cycles = cycles_line * Pico.t.z80_scanline; + // approximation by multiplying with inverse + if (cycles_z80 - cycles >= 2*cycles_line) { + // compute 1/cycles_line, storing the result to avoid future dividing + static int cycles_line_o, cycles_line_i; + if (cycles_line_o != cycles_line) + { cycles_line_o = cycles_line, cycles_line_i = (1<<22) / cycles_line; } + // compute lines = diff/cycles_line = diff*(1/cycles_line) + int lines = ((cycles_z80 - cycles) * cycles_line_i) >> 22; + Pico.t.z80_scanline += lines, cycles += cycles_line * lines; + } + // handle any rounding leftover + while (cycles_z80 - cycles >= cycles_line) + Pico.t.z80_scanline ++, cycles += cycles_line; return Pico.t.z80_scanline; } @@ -1342,7 +1356,8 @@ void PicoWrite16_32x(u32 a, u32 d) {} static unsigned char z80_md_vdp_read(unsigned short a) { if ((a & 0xff00) == 0x7f00) { - z80_subCLeft(3); + static int f; f = (f&0xff) + 0x8c; // 0.6 + z80_subCLeft(2+(f>>8)); // 3.3 per kabuto, but notaz' test implies 2.6 ?!? Pico.t.z80_buscycles += 7; switch (a & 0x0d) @@ -1368,9 +1383,10 @@ static unsigned char z80_md_bank_read(unsigned short a) unsigned char ret; // account for 68K bus access on both CPUs. + static int f; f = (f&0xff) + 0x4c; // 0.3 + z80_subCLeft(3+(f>>8)); // 3.3 per kabuto // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to // the 68K. Count the stolen cycles to be accounted later in the 68k CPU runs - z80_subCLeft(3); Pico.t.z80_buscycles += 7; addr68k = Pico.m.z80_bank68k << 15; @@ -1413,9 +1429,10 @@ static void z80_md_bank_write(unsigned int a, unsigned char data) unsigned int addr68k; // account for 68K bus access on both CPUs. + static int f; f = (f&0xff) + 0x4c; // 0.3 + z80_subCLeft(3+(f>>8)); // 3.3 per kabuto // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to // the 68K. Count the stolen cycles to be accounted later in the 68K CPU runs - z80_subCLeft(3); Pico.t.z80_buscycles += 7; addr68k = Pico.m.z80_bank68k << 15; diff --git a/pico/pico_int.h b/pico/pico_int.h index 3ed7c0f8..f6618b9d 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -205,7 +205,7 @@ extern struct DrZ80 drZ80; (Pico.t.z80c_aim - z80_cyclesLeft) // one line has 488 68K cycles and 228 Z80 cycles, 228/488*8192=3827 -#define cycles_68k_to_z80(x) ((x) * 3857 >> 13) +#define cycles_68k_to_z80(x) ((x) * 3847 >> 13) // ----------------------- SH2 CPU ----------------------- diff --git a/pico/videoport.c b/pico/videoport.c index c39a5605..6fb47a7f 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -17,7 +17,8 @@ enum { clkdiv = 2 }; // CPU clock granularity: one of 1,2,4,8 // VDP Slot timing, taken from http://gendev.spritesmind.net/ // forum/viewtopic.php?f=22&t=851&sid=d5701a71396ee7f700c74fb7cd85cb09 -// Thank you very much for the great work, Nemesis! +// http://plutiedev.com/mirror/kabuto-hardware-notes +// Thank you very much for the great work, Nemesis, Kabuto! // Slot clock is sysclock/20 for h32 and sysclock/16 for h40. // One scanline is 63.7us/63.5us (h32/h40) long which is 488.6/487.4 68k cycles. @@ -30,13 +31,15 @@ enum { slcpu = 488 }; // is generated also depends on the video mode. enum { hint32 = 0x85, gapstart32 = 0x94, gapend32 = 0xe9}; enum { hint40 = 0xa5, gapstart40 = 0xb7, gapend40 = 0xe5}; +// XXX Kabuto says gapend40 is 0xe4, but then a line would've 211 slots, while +// it's 210 in all other sources I looked at? // The horizontal sync period (HBLANK) is 30/37 slots (h32/h40): // h32: 4 slots front porch (1.49us), 13 HSYNC (4.84us), 13 back porch (4.84us) // h40: 5 slots front porch (1.49us), 16 HSYNC (4.77us), 16 back porch (4.77us) -// HBLANK starts in slot 0x93/0xb4, according to Nemesis' measurements. +// HBLANK starts in slot 0x93/0xb3 and ends after slot 0x05 (from Kabuto's doc) enum { hboff32 = 0x93-hint32, hblen32 = 0xf8-(gapend32-gapstart32)-hint32};//30 -enum { hboff40 = 0xb4-hint40, hblen40 = 0xf8-(gapend40-gapstart40)-hint40};//37 +enum { hboff40 = 0xb3-hint40, hblen40 = 0xf8-(gapend40-gapstart40)-hint40};//37 // number of slots in a scanline #define slots32 (0x100-(gapend32-gapstart32)) // 171 @@ -1030,7 +1033,8 @@ static u32 VideoSr(const struct PicoVideo *pv) { unsigned int hp = pv->reg[12]&1 ? hboff40*488/slots40 : hboff32*488/slots32; unsigned int hl = pv->reg[12]&1 ? hblen40*488/slots40 : hblen32*488/slots32; - unsigned int c = SekCyclesDone() - Pico.t.m68c_line_start; + // XXX -2 is to please notaz' testpico, but why is this? + unsigned int c = SekCyclesDone()-2 - Pico.t.m68c_line_start; u32 d; PicoVideoFIFOSync(c); -- 2.39.5