interrupted block instructions flag state [holub, Manuel Sainz de Baranda y Goñi, Peter Helcmanovsky]

This commit is contained in:
Andrei Holub 2023-08-20 08:33:52 -04:00
parent fc744e25ec
commit 0f4a47d505
2 changed files with 46 additions and 9 deletions

View File

@ -1078,8 +1078,8 @@ DEF( ldi() )
CALL nomreq_addr(2); CALL nomreq_addr(2);
THEN THEN
set_f(F & (SF | ZF | CF)); set_f(F & (SF | ZF | CF));
if ((A + TDAT8) & 0x02) F |= YF; /* bit 1 -> flag 5 */ if ((A + TDAT8) & 0x02) F |= YF; // bit 1 -> flag 5
if ((A + TDAT8) & 0x08) F |= XF; /* bit 3 -> flag 3 */ if ((A + TDAT8) & 0x08) F |= XF; // bit 3 -> flag 3
HL++; DE++; BC--; HL++; DE++; BC--;
if(BC) F |= VF; if(BC) F |= VF;
ENDDEF ENDDEF
@ -1098,8 +1098,8 @@ DEF( cpi() )
HL++; BC--; HL++; BC--;
set_f((F & CF) | (SZ[res]&~(YF|XF)) | ((A^TDAT8^res)&HF) | NF); set_f((F & CF) | (SZ[res]&~(YF|XF)) | ((A^TDAT8^res)&HF) | NF);
if (F & HF) res -= 1; if (F & HF) res -= 1;
if (res & 0x02) F |= YF; /* bit 1 -> flag 5 */ if (res & 0x02) F |= YF; // bit 1 -> flag 5
if (res & 0x08) F |= XF; /* bit 3 -> flag 3 */ if (res & 0x08) F |= XF; // bit 3 -> flag 3
if (BC) F |= VF; if (BC) F |= VF;
ENDDEF ENDDEF
@ -1159,9 +1159,9 @@ DEF( ldd() )
CALL wm(); CALL wm();
CALL nomreq_addr(2); CALL nomreq_addr(2);
THEN THEN
F &= SF | ZF | CF; set_f(F & (SF | ZF | CF));
if ((A + TDAT8) & 0x02) F |= YF; /* bit 1 -> flag 5 */ if ((A + TDAT8) & 0x02) F |= YF; // bit 1 -> flag 5
if ((A + TDAT8) & 0x08) F |= XF; /* bit 3 -> flag 3 */ if ((A + TDAT8) & 0x08) F |= XF; // bit 3 -> flag 3
HL--; DE--; BC--; HL--; DE--; BC--;
if (BC) F |= VF; if (BC) F |= VF;
ENDDEF ENDDEF
@ -1182,8 +1182,8 @@ DEF( cpd() )
HL--; BC--; HL--; BC--;
set_f((F & CF) | (SZ[res]&~(YF|XF)) | ((A^TDAT8^res)&HF) | NF); set_f((F & CF) | (SZ[res]&~(YF|XF)) | ((A^TDAT8^res)&HF) | NF);
if (F & HF) res -= 1; if (F & HF) res -= 1;
if (res & 0x02) F |= YF; /* bit 1 -> flag 5 */ if (res & 0x02) F |= YF; // bit 1 -> flag 5
if (res & 0x08) F |= XF; /* bit 3 -> flag 3 */ if (res & 0x08) F |= XF; // bit 3 -> flag 3
if (BC) F |= VF; if (BC) F |= VF;
ENDDEF ENDDEF
@ -1243,6 +1243,8 @@ DEF( ldir() )
THEN THEN
PC -= 2; PC -= 2;
WZ = PC + 1; WZ = PC + 1;
F &= ~(YF | XF);
F |= (PC >> 8) & (YF | XF);
ENDIF ENDIF
ENDDEF ENDDEF
@ -1258,9 +1260,35 @@ DEF( cpir() )
THEN THEN
PC -= 2; PC -= 2;
WZ = PC + 1; WZ = PC + 1;
F &= ~(YF | XF);
F |= (PC >> 8) & (YF | XF);
ENDIF ENDIF
ENDDEF ENDDEF
inline void z80_device::block_io_interrupted_flags()
{
F &= ~(YF | XF);
F |= (PC >> 8) & (YF | XF);
if (F & CF)
{
F &= ~HF;
if (TDAT8 & 0x80)
{
F ^= (SZP[(B - 1) & 0x07] ^ PF) & PF;
if ((B & 0x0f) == 0x00) F |= HF;
}
else
{
F ^= (SZP[(B + 1) & 0x07] ^ PF) & PF;
if ((B & 0x0f) == 0x0f) F |= HF;
}
}
else
{
F ^=(SZP[B & 0x07] ^ PF) & PF;
}
}
/*************************************************************** /***************************************************************
* INIR * INIR
***************************************************************/ ***************************************************************/
@ -1272,6 +1300,7 @@ DEF( inir() )
CALL nomreq_addr(5); CALL nomreq_addr(5);
THEN THEN
PC -= 2; PC -= 2;
block_io_interrupted_flags();
ENDIF ENDIF
ENDDEF ENDDEF
@ -1286,6 +1315,7 @@ DEF( otir() )
CALL nomreq_addr(5); CALL nomreq_addr(5);
THEN THEN
PC -= 2; PC -= 2;
block_io_interrupted_flags();
ENDIF ENDIF
ENDDEF ENDDEF
@ -1301,6 +1331,8 @@ DEF( lddr() )
THEN THEN
PC -= 2; PC -= 2;
WZ = PC + 1; WZ = PC + 1;
F &= ~(YF | XF);
F |= (PC >> 8) & (YF | XF);
ENDIF ENDIF
ENDDEF ENDDEF
@ -1316,6 +1348,8 @@ DEF( cpdr() )
THEN THEN
PC -= 2; PC -= 2;
WZ = PC + 1; WZ = PC + 1;
F &= ~(YF | XF);
F |= (PC >> 8) & (YF | XF);
ENDIF ENDIF
ENDDEF ENDDEF
@ -1330,6 +1364,7 @@ DEF( indr() )
CALL nomreq_addr(5); CALL nomreq_addr(5);
THEN THEN
PC -= 2; PC -= 2;
block_io_interrupted_flags();
ENDIF ENDIF
ENDDEF ENDDEF
@ -1344,6 +1379,7 @@ DEF( otdr() )
CALL nomreq_addr(5); CALL nomreq_addr(5);
THEN THEN
PC -= 2; PC -= 2;
block_io_interrupted_flags();
ENDIF ENDIF
ENDDEF ENDDEF

View File

@ -243,6 +243,7 @@ protected:
ops_type otdr(); ops_type otdr();
void ei(); void ei();
void set_f(u8 f); void set_f(u8 f);
void block_io_interrupted_flags();
ops_type next_op(); ops_type next_op();
virtual void check_interrupts(); virtual void check_interrupts();