- [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

@@ -5,7 +5,7 @@ run: compile
./gb
debug: compile
gdb --args gb tetris.gb
gdb --args gb supermarioland.gb
debug1: compile
gdb -ex run gb

View File

@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
//zx_ula::sound_init();
debug::stop();
//debug::stop();
bool should_exit = false;
SDL_Event e;

View File

@@ -1,5 +1,6 @@
#include "mbc1.h"
#include "mem.h"
#include "sm83.h"
#include <stdlib.h>
#include <SDL2/SDL.h>
@@ -111,6 +112,7 @@ namespace mbc1
if ( (address==0xFF50) && ((value&0x01) != 1) ) return; //Only allow disabling boot room
if ( (address==0xFF00) ) { value = value & 0x30; }
if ( (address==0xFF04) ) { hram[address-0xFE00] = 0; return; }
if ( (address==0xFF0F) ) { hram[address-0xFE00] = value; sm83::processInterrupts(); return; }
if ( (address==0xFF46) ) mem::init_dma_transfer(value);
hram[address - 0xFE00] = value;
}

View File

@@ -1,5 +1,6 @@
#include "mbc_none.h"
#include "mem.h"
#include "sm83.h"
#include <stdlib.h>
#include <SDL2/SDL.h>
@@ -72,6 +73,7 @@ namespace mbc_none
if ( (address==0xFF50) && ((value&0x01) != 1) ) return; //Only allow disabling boot room
if ( (address==0xFF00) ) { value = value & 0x30; }
if ( (address==0xFF04) ) { hram[address-0xFE00] = 0; return; }
if ( (address==0xFF0F) ) { hram[address-0xFE00] = value; sm83::processInterrupts(); return; }
if ( (address==0xFF46) ) mem::init_dma_transfer(value);
hram[address - 0xFE00] = value;
}

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)

1
sm83.h
View File

@@ -20,6 +20,7 @@ namespace sm83
void setClock(uint32_t freq);
uint32_t getClock();
void processInterrupts();
void interrupt(uint8_t type);
uint32_t step();