diff --git a/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs b/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs index 51605f8499..c4b39bfeb5 100644 --- a/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs +++ b/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs @@ -57,8 +57,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902 public const ushort RD_F = 42; // special read case to pop value into F public const ushort EI_RETI = 43; // reti has no delay in interrupt enable public const ushort INT_GET = 44; - public const ushort GBC_INTERRUPT = 45; - public const ushort HALT_CHK = 46; // when in halt mode, actually check I Flag here + public const ushort HALT_CHK = 45; // when in halt mode, actually check I Flag here public LR35902() { @@ -294,13 +293,6 @@ namespace BizHawk.Emulation.Common.Components.LR35902 if (is_GBC) { // call the interrupt processor after 4 extra cycles - /* - cur_instr = new ushort[] - {IDLE, - IDLE, - IDLE, - GBC_INTERRUPT }; - */ if (!Halt_bug_3) { INTERRUPT_GBC_NOP(); @@ -309,6 +301,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902 { INTERRUPT_(); Halt_bug_3 = false; + Console.WriteLine("Hit this"); } } else @@ -502,11 +495,6 @@ namespace BizHawk.Emulation.Common.Components.LR35902 Regs[cur_instr[instr_pntr++]] = INT_vectors[int_src]; break; - case GBC_INTERRUPT: - // only used when exiting HALT from GBC, an extra NOP is added to avoid HALT bug - INTERRUPT_(); - instr_pntr = 0; - break; case HALT_CHK: I_use = FlagI; if (Halt_bug_2 && I_use) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs index 4cebae5985..fb3c2e976a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -134,7 +134,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk break; case 0xFF45: // LYC LYC = value; - if (LY != LYC) { STAT &= 0xFB; } + if (LCDC.Bit(7)) + { + if (LY != LYC) { STAT &= 0xFB; } + else { STAT |= 0x4; } + } break; case 0xFF46: // DMA DMA_addr = value; @@ -346,24 +350,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } cycle = 0; - LY += LY_inc; - no_scan = false; + LY_actual = LY; - // here is where LY = LYC gets cleared (but only if LY isnt 0 as that's a special case - if (LY_inc == 1) - { - LYC_INT = false; - STAT &= 0xFB; - } + no_scan = false; if (LY == 0 && LY_inc == 0) { LY_inc = 1; Core.in_vblank = false; - VBL_INT = false; - if (STAT.Bit(3)) { HBL_INT = true; } - - STAT &= 0xFC; // special note here, the y coordiate of the window is kept if the window is deactivated // meaning it will pick up where it left off if re-enabled later @@ -387,6 +381,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } } + if (cycle == 452) + { + LY += LY_inc; + + // here is where LY = LYC gets cleared (but only if LY isnt 0 as that's a special case) + if (LY_inc == 1) + { + LYC_INT = false; + STAT &= 0xFB; + } + else + { + VBL_INT = false; + if (STAT.Bit(3)) { HBL_INT = true; } + + STAT &= 0xFC; + } + + Core.cpu.LY = LY; + } + + if ((LY == 153) && (cycle == 0)) + { + LY = 0; + LY_inc = 0; + + } + // exit vblank if LCD went from off to on if (LCD_was_off) { @@ -406,21 +428,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } // the VBL stat is continuously asserted - if ((LY >= 144)) + if ((LY_actual >= 144)) { if (STAT.Bit(4)) { - if ((cycle >= 4) && (LY == 144)) + if ((cycle >= 0) && (LY_actual == 144)) { VBL_INT = true; } - else if (LY > 144) + else if (LY_actual > 144) { VBL_INT = true; } } - if ((cycle == 0) && (LY == 144)) { + if ((cycle == 0) && (LY_actual == 144)) { HBL_INT = false; @@ -432,16 +454,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk Core.REG_FF0F |= 0x01; } - if ((LY >= 144) && (cycle == 4)) + if ((LY_actual >= 144) && (cycle == 0)) { // a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1 if (STAT.Bit(5)) { OAM_INT = true; } } - if ((LY == 153) && (cycle == 8)) + if ((LY_actual == 153) && (cycle == 4)) { - LY = 0; - LY_inc = 0; + LY_actual = 0; Core.cpu.LY = LY; } } @@ -454,12 +475,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // there is no mode 2 (presumably it missed the trigger) // mode 3 is very short, probably in some self test mode before turning on? - if (cycle == 8) + if (cycle == 4) { - LYC_INT = false; - STAT &= 0xFB; + if (LY != LYC) + { + LYC_INT = false; + STAT &= 0xFB; + } - if (LY == LYC) + if ((LY == LYC) && !STAT.Bit(2)) { // set STAT coincidence FLAG and interrupt flag if it is enabled STAT |= 0x04; @@ -467,7 +491,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } } - if (cycle == 84) + if (cycle == 80) { STAT &= 0xFC; @@ -480,7 +504,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk VRAM_access_write = false; } - if (cycle == 256) + if (cycle == 252) { STAT &= 0xFC; OAM_INT = false; @@ -495,9 +519,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - if (cycle < 80) + if (cycle < 76) { - if (cycle == 4) + if (cycle == 0) { // apparently, writes can make it to OAM one cycle longer then reads OAM_access_write = false; @@ -511,12 +535,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } // here OAM scanning is performed - OAM_scan(cycle); + OAM_scan(cycle + 4); } - else if (cycle >= 80 && LY < 144) + else if (cycle >= 76 && LY_actual < 144) { + if (cycle == 76) + { + OAM_access_read = false; + OAM_access_write = true; + VRAM_access_read = false; + } - if (cycle == 84) + if (cycle == 80) { STAT &= 0xFC; STAT |= 0x03; @@ -526,20 +556,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } // render the screen and handle hblank - render(cycle - 80); + render(cycle - 76); } - } + } + + if (cycle >= 452) + { + OAM_access_read = false; + OAM_scan(cycle - 452); + } } if ((LY_inc == 0)) { - if (cycle == 12) + if (cycle == 8) { LYC_INT = false; STAT &= 0xFB; // Special case of LY = LYC - if (LY == LYC) + if ((LY == LYC) && !STAT.Bit(2)) { // set STAT coincidence FLAG and interrupt flag if it is enabled STAT |= 0x04; @@ -550,13 +586,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (STAT.Bit(5)) { OAM_INT = true; } } - if (cycle == 92) { OAM_INT = false; } + if (cycle == 88) { OAM_INT = false; } } // here LY=LYC will be asserted - if ((cycle == 4) && (LY != 0)) + if ((cycle == 0) && (LY_actual != 0)) { - if (LY == LYC) + if ((LY == LYC) && !STAT.Bit(2)) { // set STAT coincidence FLAG and interrupt flag if it is enabled STAT |= 0x04; @@ -568,7 +604,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - STAT &= 0xF8; + STAT &= 0xFC; VBL_INT = LYC_INT = HBL_INT = OAM_INT = false; @@ -577,6 +613,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk LCD_was_off = true; LY = 0; + LY_actual = 0; Core.cpu.LY = LY; cycle = 0; @@ -610,10 +647,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // i.e. just keeping track of the lowest x-value sprite if (render_cycle == 0) { - OAM_access_read = false; - OAM_access_write = true; - VRAM_access_read = false; - // window X is latched for the scanline, mid-line changes have no effect window_x_latch = window_x; @@ -628,6 +661,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk fetch_sprite_01 = false; fetch_sprite_4 = false; going_to_fetch = false; + first_fetch = true; no_sprites = false; evaled_sprites = 0; @@ -811,7 +845,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (pixel_counter == 160) { read_case = 8; - hbl_countdown = 7; + hbl_countdown = 5; } } else if ((render_counter >= render_offset) && (pixel_counter < 0)) @@ -1136,7 +1170,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (going_to_fetch) { going_to_fetch = false; - sprite_fetch_counter = 0; + sprite_fetch_counter = first_fetch ? 2 : 0; + first_fetch = false; if (fetch_sprite_01) { @@ -1375,8 +1410,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines? if (OAM_cycle == 0) { - OAM_access_read = false; - OAM_scan_index = 0; SL_sprites_index = 0; write_sprite = 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs index 7c97350f8b..00eb0d539e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs @@ -78,7 +78,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (LCDC.Bit(7)) { if (LY != LYC) { STAT &= 0xFB; } - else { STAT |= 0x4; /*if (STAT.Bit(6)) { LYC_INT = true; } */} + else { STAT |= 0x4; } } break; case 0xFF46: // DMA @@ -302,15 +302,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // here mode 2 will be set to true and interrupts fired if enabled STAT &= 0xFC; STAT |= 0x2; - if (STAT.Bit(5)) - { - OAM_INT = true; - } + if (STAT.Bit(5)) { OAM_INT = true; } HBL_INT = false; } - // here OAM scanning is performed OAM_scan(cycle + 4); } @@ -398,19 +394,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // assert the STAT IRQ line if the line went from zero to 1 stat_line = VBL_INT | LYC_INT | HBL_INT | OAM_INT; - /* - if (stat_line) { - Console.Write("OAM: "); - Console.Write(OAM_INT); - Console.Write(" LYC: "); - Console.Write(LYC_INT); - Console.Write(" VBL: "); - Console.Write(VBL_INT); - Console.Write(" HBL: "); - Console.Write(HBL_INT); - Console.WriteLine(Core.cpu.TotalExecutedCycles); - } - */ + if (stat_line && !stat_line_old) { if (Core.REG_FFFF.Bit(1)) { Core.cpu.FlagI = true; }