From: Toni Wilen Date: Sat, 16 Jul 2022 14:14:46 +0000 (+0300) Subject: Copper special case updates. X-Git-Tag: 41000~194 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=3a9c9db66ea21bb53f48ed26bd6454659c4d8e81;p=francis%2Fwinuae.git Copper special case updates. --- diff --git a/custom.cpp b/custom.cpp index 3cbe92d6..0fda92a8 100644 --- a/custom.cpp +++ b/custom.cpp @@ -483,6 +483,8 @@ enum copper_states { COP_skip1, COP_strobe_delay1, COP_strobe_delay2, + COP_strobe_delay3, + COP_strobe_delay4, COP_strobe_delay1x, COP_strobe_delay2x, COP_strobe_extra, // just to skip current cycle when CPU wrote to COPJMP @@ -6983,14 +6985,15 @@ static void vhpos_adj(uae_u16 *hpp, uae_u16 *vpp) { uae_u16 hp = *hpp; uae_u16 vp = *vpp; + hp++; if (hp == maxhpos) { hp = 0; - } - if (hp <= 1) { + } else if (hp == 1) { // HP=0-1: VP = previous line. vp = vpos_prev; } + *hpp = hp; *vpp = vp; } @@ -7492,7 +7495,20 @@ static void COPJMP(int num, int vblank) cop_state.state = COP_strobe_delay1; } } else { - cop_state.state = vblank ? COP_strobe_delay2 : (copper_access ? COP_strobe_delay1 : COP_strobe_extra); + if (vblank) { + cop_state.state = COP_strobe_delay2; + switch (cop_state.state_prev) + { + case copper_states::COP_read2: + case copper_states::COP_read1: + // Wake up is delayed by 1 copper cycle if copper is currently loading words + cop_state.state = COP_strobe_delay3; + break; + + } + } else { + cop_state.state = copper_access ? COP_strobe_delay1 : COP_strobe_extra; + } } cop_state.vblankip = cop1lc; copper_enabled_thisline = 0; @@ -9513,6 +9529,7 @@ static void do_copper_fetch(int hpos, uae_u16 id) break; } case COP_strobe_delay2: + case COP_strobe_delay3: { // fake MOVE phase 2 #ifdef DEBUGGER @@ -9527,7 +9544,11 @@ static void do_copper_fetch(int hpos, uae_u16 id) record_dma_read_value(cop_state.ir[1]); } #endif - cop_state.state = COP_read1; + if (cop_state.state == COP_strobe_delay3) { + cop_state.state = COP_strobe_delay4; + } else { + cop_state.state = COP_read1; + } // Next cycle finally reads from new pointer if (cop_state.strobe == 1) { cop_state.ip = cop1lc; @@ -9538,6 +9559,13 @@ static void do_copper_fetch(int hpos, uae_u16 id) alloc_cycle(hpos, CYCLE_COPPER); } break; + case COP_strobe_delay4: + { + // COPJMP when previous instruction is mid-cycle + cop_state.state = COP_read1; + alloc_cycle(hpos, CYCLE_COPPER); + } + break; case COP_strobe_delay2x: if (debug_dma) { record_dma_event(DMA_EVENT_SPECIAL, hpos, vpos); @@ -9758,6 +9786,8 @@ static int coppercomp(int hpos, bool blitwait) int hpos_cmp = hpos; int vpos_cmp = vpos; + // If waiting for last cycle of line and last cycle is even cycle: + // Horizontal counter has already wrapped around to zero. if (hpos_cmp == maxhposm1 && maxhposeven == COPPER_CYCLE_POLARITY) { hpos_cmp = 0; } @@ -9769,6 +9799,11 @@ static int coppercomp(int hpos, bool blitwait) return -1; } + // Cycle 0: copper can't wake up + if (hpos == 0) { + return 1; + } + if ((cop_state.ir[1] & 0x8000) == 0) { decide_blitter(hpos); if (blit_busy(-1, false)) { @@ -9863,6 +9898,8 @@ static void update_copper(int until_hpos) } break; case COP_strobe_delay2: + case COP_strobe_delay3: + case COP_strobe_delay4: // Second cycle after COPJMP does basically skipped MOVE (MOVE to 1FE) // Cycle is used and needs to be free. copper_cant_read(hpos, CYCLE_PIPE_COPPER); @@ -12441,14 +12478,14 @@ void vsync_event_done(void) } } -static void delayed_copjmp(uae_u32 v) +static void check_vblank_copjmp(uae_u32 v) { COPJMP(1, 1); } static void delayed_framestart(uae_u32 v) { - COPJMP(1, 1); + check_vblank_copjmp(0); send_interrupt(5, 2 * CYCLE_UNIT); // total REFRESH_FIRST_HPOS + 1 } @@ -12548,7 +12585,7 @@ static void hsync_handler_post(bool onvsync) } else if (vb_start_line == 1) { send_interrupt(5, (REFRESH_FIRST_HPOS + 1) * CYCLE_UNIT); } else if (vpos == 0) { - event2_newevent_xx(-1, 2 * CYCLE_UNIT, 0, delayed_copjmp); + event2_newevent_xx(-1, 2 * CYCLE_UNIT, 0, check_vblank_copjmp); } // lastline - 1?