core, fix Pico horizontal irq (on irq level 5)

This commit is contained in:
kub 2024-01-20 17:15:51 +01:00
parent 214a6c624c
commit ba2b97dc24
5 changed files with 10 additions and 7 deletions

View file

@ -185,6 +185,7 @@ int PicoReset(void)
PicoDetectRegion();
Pico.video.status = 0x3428 | Pico.m.pal; // 'always set' bits | vblank | collision | pal
Pico.video.hint_irq = (PicoIn.AHW & PAHW_PICO ? 5 : 4);
PsndReset(); // pal must be known here

View file

@ -105,8 +105,8 @@ static void do_hint(struct PicoVideo *pv)
pv->pending_ints |= 0x10;
if (pv->reg[0] & 0x10) {
elprintf(EL_INTS, "hint: @ %06x [%u]", SekPc, SekCyclesDone());
if (SekIrqLevel < 4)
SekInterrupt(4);
if (SekIrqLevel < pv->hint_irq)
SekInterrupt(pv->hint_irq);
}
}

View file

@ -312,7 +312,7 @@ struct PicoVideo
unsigned char debug_p; // ... parsed: PVD_*
unsigned char addr_u; // bit16 of .addr
unsigned char hint_cnt;
unsigned char pad2;
unsigned char hint_irq; // irq# of HINT (4 on MD, 5 on Pico)
unsigned short hv_latch; // latched hvcounter value
signed int fifo_cnt; // pending xfers for blocking FIFO queue entries
signed int fifo_bgcnt; // pending xfers for background FIFO queue entries

View file

@ -35,7 +35,8 @@ static int do_ack(int level)
if (pv->pending_ints & pv->reg[1] & 0x20) {
pv->pending_ints &= ~0x20;
pv->status &= ~SR_F;
return (pv->reg[0] & pv->pending_ints & 0x10) >> 2;
if (pv->reg[0] & pv->pending_ints & 0x10)
return pv->hint_irq;
}
else if (pv->pending_ints & pv->reg[0] & 0x10)
pv->pending_ints &= ~0x10;

View file

@ -979,7 +979,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(u32 a,unsigned short d)
}
SATaddr = ((pvid->reg[5]&0x7f) << 9) | ((pvid->reg[6]&0x20) << 11);
SATmask = ~0x1ff;
if (Pico.video.reg[12]&1)
if (pvid->reg[12]&1)
SATaddr &= ~0x200, SATmask &= ~0x200; // H40, zero lowest SAT bit
//elprintf(EL_STATUS, "spritep moved to %04x", SATaddr);
return;
@ -993,8 +993,9 @@ update_irq:
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
pints = pvid->pending_ints & lines;
if (pints & 0x20) irq = 6;
else if (pints & 0x10) irq = 4;
SekInterrupt(irq); // update line
else if (pints & 0x10) irq = pvid->hint_irq;
if (SekIrqLevel < irq)
SekInterrupt(irq); // update line
// this is broken because cost of current insn isn't known here
if (irq) SekEndRun(21); // make it delayed