static int get_scanline(int is_from_z80)\r
{\r
if (is_from_z80) {\r
- int mclk_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim : z80_cyclesDone()) * 15;\r
- int mclk_line = Pico.t.z80_scanline * 488 * 7;\r
- while (mclk_z80 - mclk_line >= 488 * 7)\r
- Pico.t.z80_scanline++, mclk_line += 488 * 7;\r
+ // ugh... compute by dividing cycles since frame start by cycles per line\r
+ // need some fractional resolution here, else there may be an extra line\r
+ int cycles_line = cycles_68k_to_z80(488 << 8); // cycles per line, as Q8\r
+ int cycles_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim:z80_cyclesDone())<<8;\r
+ int cycles = cycles_line * Pico.t.z80_scanline;\r
+ // approximation by multiplying with inverse\r
+ if (cycles_z80 - cycles >= 2*cycles_line) {\r
+ // compute 1/cycles_line, storing the result to avoid future dividing\r
+ static int cycles_line_o, cycles_line_i;\r
+ if (cycles_line_o != cycles_line)\r
+ { cycles_line_o = cycles_line, cycles_line_i = (1<<22) / cycles_line; }\r
+ // compute lines = diff/cycles_line = diff*(1/cycles_line)\r
+ int lines = ((cycles_z80 - cycles) * cycles_line_i) >> 22;\r
+ Pico.t.z80_scanline += lines, cycles += cycles_line * lines;\r
+ }\r
+ // handle any rounding leftover\r
+ while (cycles_z80 - cycles >= cycles_line)\r
+ Pico.t.z80_scanline ++, cycles += cycles_line;\r
return Pico.t.z80_scanline;\r
}\r
\r
static unsigned char z80_md_vdp_read(unsigned short a)\r
{\r
if ((a & 0xff00) == 0x7f00) {\r
- z80_subCLeft(3);\r
+ static int f; f = (f&0xff) + 0x8c; // 0.6\r
+ z80_subCLeft(2+(f>>8)); // 3.3 per kabuto, but notaz' test implies 2.6 ?!?\r
Pico.t.z80_buscycles += 7;\r
\r
switch (a & 0x0d)\r
unsigned char ret;\r
\r
// account for 68K bus access on both CPUs.\r
+ static int f; f = (f&0xff) + 0x4c; // 0.3\r
+ z80_subCLeft(3+(f>>8)); // 3.3 per kabuto\r
// don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to\r
// the 68K. Count the stolen cycles to be accounted later in the 68k CPU runs\r
- z80_subCLeft(3);\r
Pico.t.z80_buscycles += 7;\r
\r
addr68k = Pico.m.z80_bank68k << 15;\r
unsigned int addr68k;\r
\r
// account for 68K bus access on both CPUs.\r
+ static int f; f = (f&0xff) + 0x4c; // 0.3\r
+ z80_subCLeft(3+(f>>8)); // 3.3 per kabuto\r
// don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to\r
// the 68K. Count the stolen cycles to be accounted later in the 68K CPU runs\r
- z80_subCLeft(3);\r
Pico.t.z80_buscycles += 7;\r
\r
addr68k = Pico.m.z80_bank68k << 15;\r
\r
// VDP Slot timing, taken from http://gendev.spritesmind.net/\r
// forum/viewtopic.php?f=22&t=851&sid=d5701a71396ee7f700c74fb7cd85cb09\r
-// Thank you very much for the great work, Nemesis!\r
+// http://plutiedev.com/mirror/kabuto-hardware-notes\r
+// Thank you very much for the great work, Nemesis, Kabuto!\r
\r
// Slot clock is sysclock/20 for h32 and sysclock/16 for h40.\r
// One scanline is 63.7us/63.5us (h32/h40) long which is 488.6/487.4 68k cycles.\r
// is generated also depends on the video mode.\r
enum { hint32 = 0x85, gapstart32 = 0x94, gapend32 = 0xe9};\r
enum { hint40 = 0xa5, gapstart40 = 0xb7, gapend40 = 0xe5};\r
+// XXX Kabuto says gapend40 is 0xe4, but then a line would've 211 slots, while\r
+// it's 210 in all other sources I looked at?\r
\r
// The horizontal sync period (HBLANK) is 30/37 slots (h32/h40):\r
// h32: 4 slots front porch (1.49us), 13 HSYNC (4.84us), 13 back porch (4.84us)\r
// h40: 5 slots front porch (1.49us), 16 HSYNC (4.77us), 16 back porch (4.77us)\r
-// HBLANK starts in slot 0x93/0xb4, according to Nemesis' measurements.\r
+// HBLANK starts in slot 0x93/0xb3 and ends after slot 0x05 (from Kabuto's doc)\r
enum { hboff32 = 0x93-hint32, hblen32 = 0xf8-(gapend32-gapstart32)-hint32};//30\r
-enum { hboff40 = 0xb4-hint40, hblen40 = 0xf8-(gapend40-gapstart40)-hint40};//37\r
+enum { hboff40 = 0xb3-hint40, hblen40 = 0xf8-(gapend40-gapstart40)-hint40};//37\r
\r
// number of slots in a scanline\r
#define slots32 (0x100-(gapend32-gapstart32)) // 171\r
{\r
unsigned int hp = pv->reg[12]&1 ? hboff40*488/slots40 : hboff32*488/slots32;\r
unsigned int hl = pv->reg[12]&1 ? hblen40*488/slots40 : hblen32*488/slots32;\r
- unsigned int c = SekCyclesDone() - Pico.t.m68c_line_start;\r
+ // XXX -2 is to please notaz' testpico, but why is this?\r
+ unsigned int c = SekCyclesDone()-2 - Pico.t.m68c_line_start;\r
u32 d;\r
\r
PicoVideoFIFOSync(c);\r