mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
sms, fix irq cleared in same instruction as asserted
This commit is contained in:
parent
3039d6d852
commit
985bbf1c03
1 changed files with 9 additions and 14 deletions
23
pico/sms.c
23
pico/sms.c
|
@ -20,8 +20,6 @@ extern void YM2413_regWrite(unsigned reg);
|
||||||
extern void YM2413_dataWrite(unsigned data);
|
extern void YM2413_dataWrite(unsigned data);
|
||||||
|
|
||||||
|
|
||||||
static int vdp_lastline;
|
|
||||||
|
|
||||||
static unsigned char vdp_data_read(void)
|
static unsigned char vdp_data_read(void)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pv = &Pico.video;
|
struct PicoVideo *pv = &Pico.video;
|
||||||
|
@ -47,11 +45,6 @@ static unsigned char vdp_ctl_read(void)
|
||||||
if (pv->reg[0] & 0x04)
|
if (pv->reg[0] & 0x04)
|
||||||
d |= 0x1f; // unused bits in mode 4 read as 1
|
d |= 0x1f; // unused bits in mode 4 read as 1
|
||||||
|
|
||||||
// the vint state must be set one instruction in advance, else reading status
|
|
||||||
// would never report vint before the irq handler, which it does on a real SMS
|
|
||||||
if (vdp_lastline && z80_cyclesLeft < 10) // e.g. Chicago GG
|
|
||||||
d |= 0x80;
|
|
||||||
|
|
||||||
elprintf(EL_SR, "VDP sr: %02x", d);
|
elprintf(EL_SR, "VDP sr: %02x", d);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -481,7 +474,6 @@ void PicoFrameMS(void)
|
||||||
|
|
||||||
for (y = 0; y < lines; y++)
|
for (y = 0; y < lines; y++)
|
||||||
{
|
{
|
||||||
vdp_lastline = lines_vis == y;
|
|
||||||
pv->v_counter = Pico.m.scanline = y;
|
pv->v_counter = Pico.m.scanline = y;
|
||||||
if (y > 218)
|
if (y > 218)
|
||||||
pv->v_counter = y - 6;
|
pv->v_counter = y - 6;
|
||||||
|
@ -489,29 +481,32 @@ void PicoFrameMS(void)
|
||||||
if (y < lines_vis && !skip)
|
if (y < lines_vis && !skip)
|
||||||
PicoLineSMS(y);
|
PicoLineSMS(y);
|
||||||
|
|
||||||
|
// Interrupt handling. Simulate interrupt flagged and immediately reset in
|
||||||
|
// same insn by flagging the irq, execute for 1 insn, then checking if the
|
||||||
|
// irq is still pending. (GG Chicago, SMS Back to the Future III)
|
||||||
if (y <= lines_vis)
|
if (y <= lines_vis)
|
||||||
{
|
{
|
||||||
if (--hint < 0)
|
if (--hint < 0)
|
||||||
{
|
{
|
||||||
hint = pv->reg[0x0a];
|
hint = pv->reg[0x0a];
|
||||||
pv->pending_ints |= 2;
|
pv->pending_ints |= 2;
|
||||||
if (pv->reg[0] & 0x10) {
|
cycles_done += z80_run(1);
|
||||||
|
if ((pv->reg[0] & 0x10) && (pv->pending_ints & 2)) {
|
||||||
elprintf(EL_INTS, "hint");
|
elprintf(EL_INTS, "hint");
|
||||||
z80_int_assert(1);
|
z80_int_assert(1);
|
||||||
}
|
}
|
||||||
} else if (pv->pending_ints & 2) {
|
|
||||||
pv->pending_ints &= ~2;
|
pv->pending_ints &= ~2;
|
||||||
z80_int_assert(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (y == lines_vis + 1) {
|
else if (y == lines_vis + 1) {
|
||||||
pv->pending_ints &= ~2;
|
pv->pending_ints &= ~2;
|
||||||
pv->pending_ints |= 1;
|
pv->pending_ints |= 1;
|
||||||
if (pv->reg[1] & 0x20) {
|
cycles_done += z80_run(1);
|
||||||
|
|
||||||
|
if ((pv->reg[1] & 0x20) && (pv->pending_ints & 1)) {
|
||||||
elprintf(EL_INTS, "vint");
|
elprintf(EL_INTS, "vint");
|
||||||
z80_int_assert(1);
|
z80_int_assert(1);
|
||||||
} else
|
}
|
||||||
z80_int_assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cycles_aim += cycles_line;
|
cycles_aim += cycles_line;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue