From: Toni Wilen Date: Thu, 2 May 2024 17:19:54 +0000 (+0300) Subject: Handle bitplane DMA wraparound allocation correctly in NTSC (long/short line toggle). X-Git-Tag: 5300~18 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=1ba63e427cc47cdc84539bb7fa7a720d4ca107dd;p=francis%2Fwinuae.git Handle bitplane DMA wraparound allocation correctly in NTSC (long/short line toggle). --- diff --git a/custom.cpp b/custom.cpp index ce5e0080..fe426b2b 100644 --- a/custom.cpp +++ b/custom.cpp @@ -902,6 +902,17 @@ static int expand_sprres(uae_u16 con0, uae_u16 con3) return res; } +static int islinetoggle(void) +{ + int linetoggle = 0; + if (!(new_beamcon0 & BEAMCON0_LOLDIS) && !(new_beamcon0 & BEAMCON0_PAL) && ecs_agnus) { + linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line + } else if (!ecs_agnus && currprefs.ntscmode) { + linetoggle = 1; // hardwired NTSC Agnus + } + return linetoggle; +} + STATIC_INLINE uae_u8 *pfield_xlateptr(uaecptr plpt, int bytecount) { if (!chipmem_check_indirect(plpt, bytecount)) { @@ -2047,6 +2058,7 @@ static void estimate_last_fetch_cycle(int hpos) #else estimated_cycles = estimated_cycles_buf0; #endif + uae_s8 *ecycs = estimated_cycles; // bitplane DMA end can wrap around, even in non-overrun cases int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos; int start_pos2 = start_pos; @@ -2064,13 +2076,16 @@ static void estimate_last_fetch_cycle(int hpos) #endif if (!off2 && start_pos + fetchstart <= end_pos) { - memcpy(estimated_cycles + start_pos, curr_diagram, fetchstart); + memcpy(ecycs + start_pos, curr_diagram, fetchstart); start_pos += fetchstart; } else { - estimated_cycles[start_pos] = curr_diagram[off2]; + ecycs[start_pos] = curr_diagram[off2]; start_pos++; if (start_pos >= maxhpos) { start_pos = 0; + if (islinetoggle()) { + ecycs = maxhposeven ? estimated_cycles_buf0 : estimated_cycles_buf1; + } } if (start_pos == REFRESH_FIRST_HPOS) { // bpl sequencer repeated this cycle @@ -2086,10 +2101,10 @@ static void estimate_last_fetch_cycle(int hpos) // zero rest of buffer if (end_pos != start_pos2) { if (end_pos > start_pos2) { - memset(estimated_cycles + end_pos, 0, maxhpos - end_pos); - memset(estimated_cycles, 0, start_pos2); + memset(ecycs + end_pos, 0, maxhpos - end_pos); + memset(ecycs, 0, start_pos2); } else { - memset(estimated_cycles + end_pos, 0, start_pos2 - end_pos); + memset(ecycs + end_pos, 0, start_pos2 - end_pos); } } estimated_bplcon0 = bplcon0; @@ -2323,17 +2338,6 @@ int get_bitplane_dma_rel(int hpos, int off) return 0; } -static int islinetoggle(void) -{ - int linetoggle = 0; - if (!(new_beamcon0 & BEAMCON0_LOLDIS) && !(new_beamcon0 & BEAMCON0_PAL) && ecs_agnus) { - linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line - } else if (!ecs_agnus && currprefs.ntscmode) { - linetoggle = 1; // hardwired NTSC Agnus - } - return linetoggle; -} - static void compute_shifter_mask(void) { int shifter_size = 16 << (fetchmode + LORES_TO_SHRES_SHIFT - toscr_res); @@ -13234,10 +13238,12 @@ static void hsync_handler_pre(bool onvsync) hpos_hsync_extra = maxhpos; lol_prev = lol; - if (islinetoggle()) + if (islinetoggle()) { lol = lol ? 0 : 1; - else + } else { lol = 0; + } + memset(cycle_line_slot, 0, maxhposm1 + 1); // to record decisions correctly between end of scanline and start of hsync if (!eventtab[ev_hsynch].active) { @@ -13962,8 +13968,6 @@ static void delayed_framestart(uae_u32 v) // this prepares for new line static void hsync_handler_post(bool onvsync) { - memset(cycle_line_slot, 0, maxhposm1 + 1); - // genlock active: // vertical: interlaced = toggles every other field, non-interlaced = both fields (normal) // horizontal: PAL = every line, NTSC = every other line