- [FIX] Les interrupcions també han d'executar-se al escriure directament en 0xFF0F (IE)

- [FIX] Els 4 bits menys significants del registre F han de ser sempre 0
- [FIX] Arreglats (crec? estaven mal?) els flags de half carry de algunes operacions aritmètiques
- [FIX] Crec que DAA ara va com toca? (potser? abans no?)
This commit is contained in:
2025-01-27 14:04:09 +01:00
parent 7f5760d826
commit 44f4f1a85b
6 changed files with 73 additions and 20 deletions

View File

@@ -156,6 +156,7 @@ namespace sm83
void POP(uint16_t *a)
{
*a = READ_MEM_16(rSP);
if (a == _rAF) *a = *a & 0xfff0;
rSP+=2;
}
@@ -244,7 +245,8 @@ namespace sm83
const uint8_t res = rA + b;
rF=0;
if (res==0) SET_FLAGS(fZ);
if ( (res & 0x0f) < (rA & 0x0f) ) SET_FLAGS(fH);
//if ( (res & 0x0f) < (rA & 0x0f) ) SET_FLAGS(fH);
if ( (rA&0x0f) + (b&0x0f) > 0x0f ) SET_FLAGS(fH);
if ( res < rA ) SET_FLAGS(fC);
rA = (uint8_t)res;
}
@@ -257,7 +259,8 @@ namespace sm83
uint16_t res = rA + b + 1;
rF=0;
if (res==0) SET_FLAGS(fZ);
if ( (res & 0x0f) <= (rA & 0x0f) ) SET_FLAGS(fH);
//if ( (res & 0x0f) <= (rA & 0x0f) ) SET_FLAGS(fH);
if ( (rA&0x0f) + (b&0x0f) + 1 > 0x0f ) SET_FLAGS(fH);
if ( res > 255 ) SET_FLAGS(fC);
rA = (uint8_t)res;
}
@@ -269,7 +272,8 @@ namespace sm83
rF=0;
if (res==0) SET_FLAGS(fZ);
SET_FLAGS(fN);
if ( (res & 0x0f) > (rA & 0x0f) ) SET_FLAGS(fH);
//if ( (res & 0x0f) > (rA & 0x0f) ) SET_FLAGS(fH);
if ( int(rA&0x0f) - int(b&0x0f) < 0 ) SET_FLAGS(fH);
if ( res > rA ) SET_FLAGS(fC);
if (update) rA = (uint8_t)res;
}
@@ -283,7 +287,8 @@ namespace sm83
rF=0;
if (res==0) SET_FLAGS(fZ);
SET_FLAGS(fN);
if ( (res & 0x0f) >= (rA & 0x0f) ) SET_FLAGS(fH);
//if ( (res & 0x0f) >= (rA & 0x0f) ) SET_FLAGS(fH);
if ( int(rA&0x0f) - int(b&0x0f) - 1 < 0 ) SET_FLAGS(fH);
if ( res >= rA ) SET_FLAGS(fC);
rA = (uint8_t)res;
}
@@ -366,7 +371,7 @@ namespace sm83
t+=4;
}
*/
void DAA()
void oldDAA()
{
bool carry_set = false;
uint8_t old = rA;
@@ -379,6 +384,49 @@ namespace sm83
if (carry_set) SET_FLAGS(fC);
}
void notsooldDAA()
{
bool carry_set = false;
bool halfcarry_set = true;
if (!(rF & fN)) {
if ((rF & fC) || rA > 0x99) { rA += 0x60; carry_set = true; }
if ((rF & fH) || ((rA & 0x0f) > 0x09)) { halfcarry_set = false; rA += 0x6; }
} else if ( (rF & fC) && (rF & fH) ) {
rA += 0x9A;
halfcarry_set = false;
} else if (rF & fC) {
rA += 0xA0;
} else if (rF & fH) {
rA += 0xFA;
halfcarry_set = false;
}
KEEP_FLAGS(fN);
if (rA==0) SET_FLAGS(fZ);
if (carry_set) SET_FLAGS(fC);
//if (halfcarry_set) SET_FLAGS(fH);
//rF = rF & ~fH;
}
void DAA()
{
int t = rA;
int corr = 0;
corr |= (rF & fH) ? 0x06 : 0x00;
corr |= (rF & fC) ? 0x60 : 0x00;
if (rF & fN)
t -= corr;
else {
corr |= (t & 0x0F) > 0x09 ? 0x06 : 0x00;
corr |= (t > 0x99) ? 0x60 : 0x00;
t += corr;
}
KEEP_FLAGS(fN);
if (t==0) SET_FLAGS(fZ);
if (corr & 0x60 != 0) SET_FLAGS(fC);
t &= 0xFF;
rA = t;
}
void CPL()
{
rA = ~rA;
@@ -473,27 +521,27 @@ namespace sm83
void processInterrupts()
{
const uint8_t IF = mem::readMem(0xff0f);
uint8_t *IF = mem::rawPtr(0xff0f);
if (ime==0) return;
if ( (IF & 0x1f) == 0) return;
if ( (*IF & 0x1f) == 0) return;
DI();
PUSH(rPC);
t+=20;
if (IF & INTERRUPT_VBLANK) {
if (*IF & INTERRUPT_VBLANK) {
rPC = 0x40;
mem::writeMem(0xff0f, IF & ~INTERRUPT_VBLANK);
} else if (IF & INTERRUPT_LCD) {
*IF = *IF & ~INTERRUPT_VBLANK;
} else if (*IF & INTERRUPT_LCD) {
rPC = 0x48;
mem::writeMem(0xff0f, IF & ~INTERRUPT_LCD);
} else if (IF & INTERRUPT_TIMER) {
*IF = *IF & ~INTERRUPT_LCD;
} else if (*IF & INTERRUPT_TIMER) {
rPC = 0x50;
mem::writeMem(0xff0f, IF & ~INTERRUPT_TIMER);
} else if (IF & INTERRUPT_SERIAL) {
*IF = *IF & ~INTERRUPT_TIMER;
} else if (*IF & INTERRUPT_SERIAL) {
rPC = 0x58;
mem::writeMem(0xff0f, IF & ~INTERRUPT_SERIAL);
} else if (IF & INTERRUPT_JOYPAD) {
*IF = *IF & ~INTERRUPT_SERIAL;
} else if (*IF & INTERRUPT_JOYPAD) {
rPC = 0x60;
mem::writeMem(0xff0f, IF & ~INTERRUPT_JOYPAD);
*IF = *IF & ~INTERRUPT_JOYPAD;
}
/*if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
@@ -555,7 +603,7 @@ namespace sm83
if (IE & type) exit_from_halt = true;
const uint8_t IF = mem::readMem(0xff0f);
mem::writeMem(0xff0f, IF | (IE & type));
processInterrupts();
//processInterrupts();
}
static inline const uint8_t RLC(const uint8_t v)