The intro of International Karate + has a graphic bug on the top, see image:
International Karate + (1988)(System 3)[cr OCL][m Invisible Crime].adf.zip

Interesting: The Copper is utilised to trigger interrupts at certain positions (Write to INTREQ):

Suspicious: I don't think that the lower part of the list is supposed to be executed.
TODO: Check how many interrupts are triggered (Note: Wait commands use bit masking).
Next: Check where Copper execution is supposed to end.
[3129] ( 12,113) 0010B8 BC---A 4030 0780 Copper: pokeCOP1LCH(0000)
[3129] ( 12,113) 0010B8 BC---A 4030 0780 Copper: pokeCOP1LCL(0E74)
[3129] ( 12,127) 0010BE BC---A 4030 0780 Copper: pokeCOPJMP1(): Jumping to E74
[3129] ( 66,226) 0029C0 BC---A 4030 0780 [000E74] Agnus: Copper blocked (bus busy)
[3129] ( 67, 4) 0029C2 BC---A 4030 0780 [000E78] Copper: COPPC: E78 move(BPL1PTH, $7) (7)
The intro triggers a Copper interrupt and lets the CPU write to COP1LCH, COP1LCL, and COPJMP1 inside the interrupt handler. This should not only modify the Copper program counter, but also restart the (now waiting) Copper. In vAmiga, the Copper is not restarted immediately. It wakes up at the old trigger position that was set to raster line 66 before the IRQ was triggered.
TODO: Find out the details about the exact behaviour of COP1LCH, COP1LCL, and COPJMP1.
Excerpt from SAE:
case COP_strobe_extra: {
if (copdebug) debug("COP_strobe_extra");
if (copdebug) debug("COP_strobe_extra: vpos = %d ($%x) hpos = %d ($%x)", vpos, vpos, old_hpos, old_hpos);
// Wait 1 copper cycle doing nothing
cop_state.state = COP_strobe_delay1;
break;
}
case COP_strobe_delay1: {
if (copdebug) debug("COP_strobe_delay1: vpos = %d ($%x) hpos = %d ($%x) dmacon = $%X dmaen = $%X", vpos, vpos, old_hpos, old_hpos, SAEV_Custom_dmacon, SAEC_Custom_DMAF_DMAEN);
// First cycle after COPJMP is just like normal first read cycle
// Cycle is used and needs to be free.
if (SAER.playfield.copper_cant_read(old_hpos, 1))
continue;
//SAER.events.alloc_cycle(old_hpos, SAEC_Events_cycle_line_COPPER);
maxhpos = SAER.playfield.get_maxhpos();
if (old_hpos == maxhpos - 2) {
// if COP_strobe_delay2 would cross scanlines (positioned immediately
// after first strobe/refresh slot) it will disappear!
cop_state.state = COP_read1;
if (cop_state.strobe == 1)
cop_state.ip = cop1lc;
else
cop_state.ip = cop2lc;
cop_state.strobe = 0;
} else {
cop_state.state = COP_strobe_delay2;
cop_state.ip += 2;
}
break;
}
case COP_strobe_delay2: {
if (copdebug) debug("COP_strobe_delay2: vpos = %d ($%x) hpos = %d ($%x) dmacon = $%X dmaen = $%X", vpos, vpos, old_hpos, old_hpos, SAEV_Custom_dmacon, SAEC_Custom_DMAF_DMAEN);
// Second cycle after COPJMP. This is the strange one.
// This cycle does not need to be free
// But it still gets allocated by copper if it is free = CPU and blitter can't use it.
//if (!SAER.playfield.copper_cant_read(old_hpos, 0)) SAER.events.alloc_cycle(old_hpos, SAEC_Events_cycle_line_COPPER);
cop_state.state = COP_read1;
// Next cycle finally reads from new pointer
if (cop_state.strobe == 1)
cop_state.ip = cop1lc;
else
cop_state.ip = cop2lc;
cop_state.strobe = 0;
break;
}
case COP_strobe_delay1x: {
if (copdebug) debug("COP_strobe_delay1x: vpos = %d ($%x) hpos = %d ($%x)", vpos, vpos, old_hpos, old_hpos);
// First cycle after COPJMP and Copper was waiting. This is the buggy one.
// Cycle can be free and copper won"t allocate it.
// If Blitter uses this cycle = Copper"s PC gets copied to blitter DMA pointer..
cop_state.state = COP_strobe_delay2x;
break;
}
case COP_strobe_delay2x: {
if (copdebug) debug("COP_strobe_delay2x: vpos = %d ($%x) hpos = %d ($%x)", vpos, vpos, old_hpos, old_hpos);
// Second cycle fetches following word and tosses it away. Must be free cycle
// but it is not allocated, blitter or cpu can still use it.
if (SAER.playfield.copper_cant_read(old_hpos, 1))
continue;
//SAER_Events_cycle_line[old_hpos] |= SAEC_Events_cycle_line_COPPER_SPECIAL;
cop_state.state = COP_read1;
// Next cycle finally reads from new pointer
if (cop_state.strobe == 1)
cop_state.ip = cop1lc;
else
cop_state.ip = cop2lc;
cop_state.strobe = 0;
break;
}
Copper test jump3a pinpoints the issue we are facing here:
UAE:

vAmiga 馃檲:

Works well in v0.38 馃槑.

I played this for half an hour or so without any issue. BTW, the white opponent is rather weak, but the blue one has beaten me up badly every time 馃. But he shouldn't feel too safe. Before he messes up with me again he should consider that I know each and every register in Denise by now. Once I figured out his sprite number... 馃槇
Most helpful comment
Works well in v0.38 馃槑.
I played this for half an hour or so without any issue. BTW, the white opponent is rather weak, but the blue one has beaten me up badly every time 馃. But he shouldn't feel too safe. Before he messes up with me again he should consider that I know each and every register in Denise by now. Once I figured out his sprite number... 馃槇