# HG changeset patch # User Michael Pavone # Date 1498808178 25200 # Node ID 2b34469e3f81e4ec85db7979740f8b1f737336d0 # Parent 0ba6760f4c6de00ea68dda2238dc1821d9dd29e2 Change where vscroll is latched in full plane mode. Fixes Top Gear 2 diff -r 0ba6760f4c6d -r 2b34469e3f81 menu.s68 --- a/menu.s68 Mon Jun 26 23:40:07 2017 -0700 +++ b/menu.s68 Fri Jun 30 00:36:18 2017 -0700 @@ -838,7 +838,7 @@ dbra d0, .regloop vdpaccess $0, VDP_CRAM_WRITE - move.w #$020, (a0) + move.w #$400, (a0) move.w #$EEE, (a0) move.w #$222, (a0) diff -r 0ba6760f4c6d -r 2b34469e3f81 vdp.c --- a/vdp.c Mon Jun 26 23:40:07 2017 -0700 +++ b/vdp.c Fri Jun 30 00:36:18 2017 -0700 @@ -1050,8 +1050,8 @@ vscroll_shift = 3; } //TODO: Further research on vscroll latch behavior and the "first column bug" - if (!column) { - if (context->regs[REG_MODE_3] & BIT_VSCROLL) { + if (context->regs[REG_MODE_3] & BIT_VSCROLL) { + if (!column) { if (context->regs[REG_MODE_4] & BIT_H40) { //Based on observed behavior documented by Eke-Eke, I'm guessing the VDP //ends up fetching the last value on the VSRAM bus in the H40 case @@ -1063,11 +1063,9 @@ //supposedly it's always forced to 0 in the H32 case context->vscroll_latch[0] = context->vscroll_latch[1] = 0; } - } else { - context->vscroll_latch[vsram_off] = context->vsram[vsram_off]; + } else if (context->regs[REG_MODE_3] & BIT_VSCROLL) { + context->vscroll_latch[vsram_off] = context->vsram[column - 2 + vsram_off]; } - } else if (context->regs[REG_MODE_3] & BIT_VSCROLL) { - context->vscroll_latch[vsram_off] = context->vsram[column - 2 + vsram_off]; } if (!vsram_off) { uint16_t left_col, right_col; @@ -2154,6 +2152,12 @@ SPRITE_RENDER_H40(242) SPRITE_RENDER_H40(243) //provides "garbage" for border when plane A selected case 244: + if (!(context->regs[REG_MODE_3] & BIT_VSCROLL)) { + //TODO: Develop some tests on hardware to see when vscroll latch actually happens for full plane mode + //See note in vdp_h32 for why this was moved out of read_map_scroll + context->vscroll_latch[0] = context->vsram[0]; + context->vscroll_latch[1] = context->vsram[1]; + } address = (context->regs[REG_HSCROLL] & 0x3F) << 10; mask = 0; if (context->regs[REG_MODE_3] & 0x2) { @@ -2363,6 +2367,15 @@ SPRITE_RENDER_H32(241) SPRITE_RENDER_H32(242) case 243: + if (!(context->regs[REG_MODE_3] & BIT_VSCROLL)) { + //TODO: Develop some tests on hardware to see when vscroll latch actually happens for full plane mode + //Top Gear 2 has a very efficient HINT routine that can occassionally hit this slot with a VSRAM write + //Since CRAM-updatnig HINT routines seem to indicate that my HINT latency is perhaps slightly too high + //the most reasonable explanation is that vscroll is latched before this slot, but tests are needed + //to confirm that one way or another + context->vscroll_latch[0] = context->vsram[0]; + context->vscroll_latch[1] = context->vsram[1]; + } external_slot(context); //provides "garbage" for border when plane A selected render_border_garbage(