- [FIX] Les interrupcions comencen mirant IE & IF, i després IME. Estava al reves.

- [FIX] En cada interrupció se marcava el exit_from_halt, i sino estaves en halt, el pròxim halt no tenía efecte.
- [FIX] Implementat el halt bug quan va despres de EI
- [FIX] una demanda de interrupció ha de quedar marcada en IF, encara que en IE no estiga habilitada.
- [FIX] durant el pintat se marquen les interrupcions que toque, i al final es quan s'envia tot junt.
- [FIX] estava enviant una interrupcio VBLANK al acabar el pintat total, com en spectrum, adicional a la que toca, i tot anava loco.
- [FIX] Llevats tots els fullrefresh, no funciona be en GameBoy
This commit is contained in:
2025-01-27 22:09:02 +01:00
parent 44f4f1a85b
commit 974251540d
3 changed files with 44 additions and 22 deletions

View File

@@ -360,7 +360,8 @@ namespace debug
pause(); pause();
is_debugging = true; is_debugging = true;
show(); show();
if ( gbscreen::getFullRefresh()) gbscreen::fullrefresh(); gbscreen::redraw(true);
//if ( gbscreen::getFullRefresh()) gbscreen::fullrefresh();
} }
void cont() { void cont() {
@@ -777,7 +778,8 @@ namespace debug
uint8_t dt = sm83::step(); uint8_t dt = sm83::step();
//zx_tape::update(dt); //zx_tape::update(dt);
//zx_ula::sound_update(dt); //zx_ula::sound_update(dt);
gbscreen::fullrefresh(); gbscreen::refresh(dt);
gbscreen::redraw();
//z80analyze::refresh(); //z80analyze::refresh();
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) { } else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
sm83::step(); sm83::step();

View File

@@ -301,7 +301,7 @@ namespace gbscreen
} }
// gestió de en quin dot i linea estem, i tot el que ha de passar // gestió de en quin dot i linea estem, i tot el que ha de passar
bool stat_interrupt = false; uint8_t interrupts = 0x00;
dots_in_scanline++; dots_in_scanline++;
if ( (dots_in_scanline==80) && (LY<144) ) if ( (dots_in_scanline==80) && (LY<144) )
{ {
@@ -310,7 +310,7 @@ namespace gbscreen
else if ( (dots_in_scanline==252) && (LY<144) ) else if ( (dots_in_scanline==252) && (LY<144) )
{ {
STAT = (STAT & 0xFC); // Set mode 0 STAT = (STAT & 0xFC); // Set mode 0
if (STAT&0x08) stat_interrupt = true; if (STAT&0x08) interrupts |= INTERRUPT_LCD;
} }
else if (dots_in_scanline==456) else if (dots_in_scanline==456)
{ {
@@ -319,17 +319,17 @@ namespace gbscreen
if (LY==144) if (LY==144)
{ {
STAT = (STAT & 0xFC) | 0x01; // Set mode 1 STAT = (STAT & 0xFC) | 0x01; // Set mode 1
mem::writeMem(0xff41, STAT); //mem::writeMem(0xff41, STAT);
mem::writeMem(0xff44, LY); //mem::writeMem(0xff44, LY);
sm83::interrupt(INTERRUPT_VBLANK); interrupts |= INTERRUPT_VBLANK;
if (STAT&0x10) stat_interrupt = true; if (STAT&0x10) interrupts |= INTERRUPT_LCD;
} }
else else
{ {
if (LY<144) if (LY<144)
{ {
STAT = (STAT & 0xFC) | 0x02; // Set mode 2 STAT = (STAT & 0xFC) | 0x02; // Set mode 2
if (STAT&0x20) stat_interrupt = true; if (STAT&0x20) interrupts |= INTERRUPT_LCD;
fill_line_buffer_bkg(LY); fill_line_buffer_bkg(LY);
fill_line_buffer_win(LY); fill_line_buffer_win(LY);
fill_line_buffer_obj(LY); fill_line_buffer_obj(LY);
@@ -342,7 +342,7 @@ namespace gbscreen
if (LY==LYC) if (LY==LYC)
{ {
STAT = (STAT & 0xFB) | 0x04; STAT = (STAT & 0xFB) | 0x04;
if (STAT&0x40) stat_interrupt = true; if (STAT&0x40) interrupts |= INTERRUPT_LCD;
} }
else else
{ {
@@ -350,11 +350,11 @@ namespace gbscreen
} }
} }
if (stat_interrupt) if (interrupts)
{ {
mem::writeMem(0xff41, STAT); mem::writeMem(0xff41, STAT);
mem::writeMem(0xff44, LY); mem::writeMem(0xff44, LY);
sm83::interrupt(INTERRUPT_LCD); sm83::interrupt(interrupts);
} }
t_screen++; t_screen++;
@@ -363,7 +363,7 @@ namespace gbscreen
t_screen=0; t_screen=0;
ptr_pixel = gb_pixels; ptr_pixel = gb_pixels;
redraw(); redraw();
if (!full) sm83::interrupt(INTERRUPT_VBLANK); //if (!full) sm83::interrupt(INTERRUPT_VBLANK);
} }
} }
mem::writeMem(0xff41, STAT); mem::writeMem(0xff41, STAT);
@@ -383,7 +383,8 @@ namespace gbscreen
void debugrefresh(const uint32_t dt) void debugrefresh(const uint32_t dt)
{ {
if (full_refresh) fullrefresh(); else refresh(dt); /*if (full_refresh) fullrefresh(); else*/ refresh(dt);
redraw();
} }
void redraw(const bool present) void redraw(const bool present)

View File

@@ -46,6 +46,7 @@ namespace sm83
uint8_t *_rIME = &regs[12]; uint8_t *_rIME = &regs[12];
bool halted = false;
bool exit_from_halt = false; bool exit_from_halt = false;
int pending_ei = 0; int pending_ei = 0;
@@ -521,12 +522,18 @@ namespace sm83
void processInterrupts() void processInterrupts()
{ {
uint8_t *IE = mem::rawPtr(0xffff);
uint8_t *IF = mem::rawPtr(0xff0f); uint8_t *IF = mem::rawPtr(0xff0f);
if ( (*IF & *IE) == 0 ) return;
if (halted) {
//exit_from_halt = true;
halted = false;
rPC++;
}
if (ime==0) return; if (ime==0) return;
if ( (*IF & 0x1f) == 0) return;
DI(); DI();
PUSH(rPC); PUSH(rPC);
t+=20; //t+=20;
if (*IF & INTERRUPT_VBLANK) { if (*IF & INTERRUPT_VBLANK) {
rPC = 0x40; rPC = 0x40;
*IF = *IF & ~INTERRUPT_VBLANK; *IF = *IF & ~INTERRUPT_VBLANK;
@@ -584,12 +591,24 @@ namespace sm83
void HALT() void HALT()
{ {
if (exit_from_halt) { if (!halted) {
exit_from_halt = false; uint8_t *IE = mem::rawPtr(0xffff);
uint8_t *IF = mem::rawPtr(0xff0f);
if ( (ime==0) && ((*IF & *IE) != 0) ) {
// [TODO] HALT BUG
if (pending_ei==2) rPC--;
return;
} else { } else {
halted = true;
}
}
/*if (exit_from_halt) {
exit_from_halt = false;
halted = false;
} else {*/
//printf("HALT\n"); //printf("HALT\n");
rPC--; rPC--;
} //}
} }
void STOP() void STOP()
@@ -600,9 +619,9 @@ namespace sm83
void interrupt(uint8_t type) void interrupt(uint8_t type)
{ {
const uint8_t IE = mem::readMem(0xffff); const uint8_t IE = mem::readMem(0xffff);
if (IE & type) exit_from_halt = true; //if (IE & type) exit_from_halt = true;
const uint8_t IF = mem::readMem(0xff0f); const uint8_t IF = mem::readMem(0xff0f);
mem::writeMem(0xff0f, IF | (IE & type)); mem::writeMem(0xff0f, IF | type);
//processInterrupts(); //processInterrupts();
} }