diff --git a/src/lcd.rs b/src/lcd.rs index 37877e5..b4489b7 100644 --- a/src/lcd.rs +++ b/src/lcd.rs @@ -156,32 +156,6 @@ impl GPU { // Update the LCD state pub fn update(&mut self, cycles: u32) { - // Debug: Track update calls - static mut UPDATE_COUNTER: u32 = 0; - static mut FORCE_REFRESH_COUNTER: u32 = 0; - unsafe { - UPDATE_COUNTER += 1; - FORCE_REFRESH_COUNTER += 1; - - if UPDATE_COUNTER % 10000 == 0 { - println!("GPU update called {} times, cycles={}", UPDATE_COUNTER, cycles); - } - - // Force a complete refresh of the screen buffer periodically - if FORCE_REFRESH_COUNTER >= 1_000_000 { - println!("Forcing complete screen refresh"); - - // Force render all scanlines - for scanline in 0..SCREEN_HEIGHT { - self.ly = scanline as u8; - self.render_scanline(); - } - - // Reset counter - FORCE_REFRESH_COUNTER = 0; - return; - } - } // If LCD is disabled, reset and return if !self.lcd_control.lcd_enabled { @@ -191,30 +165,6 @@ impl GPU { return; } - // Store the old LY value for change detection - let old_ly = self.ly; - - // Check if we're stuck at LY < 144 - static mut STUCK_COUNTER: u32 = 0; - unsafe { - if self.ly < 144 { - STUCK_COUNTER += 1; - // If we've been stuck for a while, force LY to increment - if STUCK_COUNTER > 10000 { - println!("Forcing LY increment from {} to {}", self.ly, self.ly + 1); - self.ly += 1; - if self.ly == 144 { - self.mode = LCDMode::VBlank; - println!("Forced transition to VBlank at LY = 144"); - } - STUCK_COUNTER = 0; - return; - } - } else { - STUCK_COUNTER = 0; - } - } - self.mode_clock += cycles; // Update LCD based on current mode @@ -224,44 +174,15 @@ impl GPU { self.mode_clock = 0; self.ly += 1; - // Debug print for HBlank mode when approaching VBlank - if self.ly >= 140 { - println!("HBlank: LY = {} (approaching VBlank)", self.ly); - } - if self.ly == SCREEN_HEIGHT as u8 { // Enter V-Blank self.mode = LCDMode::VBlank; - println!("Entering VBlank mode at LY = {}", self.ly); - // TODO: Request V-Blank interrupt + // TODO: Request V-Blank interrupt } else { // Start next scanline self.mode = LCDMode::OAMSearch; } } - - // Check if we're stuck in HBlank mode - static mut HBLANK_STUCK_COUNTER: u32 = 0; - unsafe { - HBLANK_STUCK_COUNTER += 1; - // If we've been stuck in HBlank for a while, force transition to next mode - if HBLANK_STUCK_COUNTER > 50000 { - println!("Forcing transition from HBlank at LY = {}", self.ly); - self.ly += 1; - - if self.ly == SCREEN_HEIGHT as u8 { - // Enter V-Blank - self.mode = LCDMode::VBlank; - println!("Forced transition to VBlank at LY = {}", self.ly); - } else { - // Start next scanline - self.mode = LCDMode::OAMSearch; - println!("Forced transition to OAMSearch at LY = {}", self.ly); - } - - HBLANK_STUCK_COUNTER = 0; - } - } }, LCDMode::VBlank => { if self.mode_clock >= MODE_1_CYCLES / 10 { @@ -278,70 +199,20 @@ impl GPU { println!("End of VBlank, starting new frame"); } } - - // Check if we're stuck in VBlank mode - static mut VBLANK_STUCK_COUNTER: u32 = 0; - unsafe { - VBLANK_STUCK_COUNTER += 1; - // If we've been stuck in VBlank for a while, force transition to next frame - if VBLANK_STUCK_COUNTER > 100000 { - println!("Forcing end of VBlank, LY was {}", self.ly); - self.ly = 0; - self.mode = LCDMode::OAMSearch; - VBLANK_STUCK_COUNTER = 0; - } - } }, LCDMode::OAMSearch => { if self.mode_clock >= MODE_2_CYCLES { self.mode_clock = 0; self.mode = LCDMode::PixelTransfer; - - // Debug print for OAMSearch mode when approaching VBlank - if self.ly >= 140 { - println!("OAMSearch -> PixelTransfer at LY = {}", self.ly); - } - } - - // Check if we're stuck in OAMSearch mode - static mut OAMSEARCH_STUCK_COUNTER: u32 = 0; - unsafe { - OAMSEARCH_STUCK_COUNTER += 1; - // If we've been stuck in OAMSearch for a while, force transition to PixelTransfer - if OAMSEARCH_STUCK_COUNTER > 50000 { - println!("Forcing transition from OAMSearch to PixelTransfer at LY = {}", self.ly); - self.mode = LCDMode::PixelTransfer; - OAMSEARCH_STUCK_COUNTER = 0; - } } }, LCDMode::PixelTransfer => { if self.mode_clock >= MODE_3_CYCLES { self.mode_clock = 0; self.mode = LCDMode::HBlank; - - // Debug print for PixelTransfer mode when approaching VBlank - if self.ly >= 140 { - println!("PixelTransfer -> HBlank at LY = {}", self.ly); - } - // Render scanline self.render_scanline(); } - - // Check if we're stuck in PixelTransfer mode - static mut PIXELTRANSFER_STUCK_COUNTER: u32 = 0; - unsafe { - PIXELTRANSFER_STUCK_COUNTER += 1; - // If we've been stuck in PixelTransfer for a while, force transition to HBlank - if PIXELTRANSFER_STUCK_COUNTER > 50000 { - println!("Forcing transition from PixelTransfer to HBlank at LY = {}", self.ly); - self.mode = LCDMode::HBlank; - PIXELTRANSFER_STUCK_COUNTER = 0; - // Render scanline - self.render_scanline(); - } - } } } @@ -373,11 +244,11 @@ impl GPU { // Render a single scanline fn render_scanline(&mut self) { // Debug print for rendering - if self.ly % 20 == 0 { // Print every 20th scanline to avoid flooding the console - println!("Rendering scanline {} (Mode: {:?})", self.ly, self.mode); - println!(" LCD Control: {:?}", self.lcd_control); - println!(" Background Palette: 0x{:02X}", self.bg_palette); - } + // if self.ly % 20 == 0 { // Print every 20th scanline to avoid flooding the console + // println!("Rendering scanline {} (Mode: {:?})", self.ly, self.mode); + // println!(" LCD Control: {:?}", self.lcd_control); + // println!(" Background Palette: 0x{:02X}", self.bg_palette); + // } if self.lcd_control.bg_and_window_enable { self.render_background(); @@ -386,37 +257,11 @@ impl GPU { self.render_window(); } } else { - if self.ly % 20 == 0 { - println!(" Background and window display disabled!"); - } } if self.lcd_control.object_enable { self.render_sprites(); } - - // Debug: Check if any pixels are set in this scanline - if self.ly % 20 == 0 { - let mut non_zero_pixels = 0; - for x in 0..SCREEN_WIDTH { - if self.screen_buffer[self.ly as usize][x] > 0 { - non_zero_pixels += 1; - } - } - println!(" Non-zero pixels in scanline {}: {}/{}", self.ly, non_zero_pixels, SCREEN_WIDTH); - - // Print a sample of the screen buffer for this scanline - if non_zero_pixels > 0 { - println!(" Sample of screen buffer for scanline {}:", self.ly); - for x in 0..min(20, SCREEN_WIDTH) { // Print first 20 pixels - print!("{} ", self.screen_buffer[self.ly as usize][x]); - if (x + 1) % 10 == 0 { - println!(); - } - } - println!(); - } - } } // Render the background for the current scanline @@ -425,15 +270,15 @@ impl GPU { let tile_data_area = if self.lcd_control.bg_and_window_tile_area { 0x8000 } else { 0x8800 }; let signed_addressing = tile_data_area == 0x8800; - // Debug print for rendering - if self.ly == 80 { // Only print for a specific scanline to avoid flooding the console - println!("Rendering background for scanline {}", self.ly); - println!(" Tile map area: 0x{:04X}", tile_map_area); - println!(" Tile data area: 0x{:04X}", tile_data_area); - println!(" Signed addressing: {}", signed_addressing); - println!(" Background palette: 0x{:02X}", self.bg_palette); - println!(" LCD Control: {:?}", self.lcd_control); - } + // // Debug print for rendering + // if self.ly == 80 { // Only print for a specific scanline to avoid flooding the console + // println!("Rendering background for scanline {}", self.ly); + // println!(" Tile map area: 0x{:04X}", tile_map_area); + // println!(" Tile data area: 0x{:04X}", tile_data_area); + // println!(" Signed addressing: {}", signed_addressing); + // println!(" Background palette: 0x{:02X}", self.bg_palette); + // println!(" LCD Control: {:?}", self.lcd_control); + // } let y_pos = self.ly.wrapping_add(self.scroll_y); let tile_row = (y_pos / 8) as usize; @@ -483,12 +328,6 @@ impl GPU { // Map the pixel value through the palette let color = (self.bg_palette >> (pixel * 2)) & 0x03; - // Debug: Print detailed palette mapping for a few pixels - if self.ly == 80 && x < 5 { - println!(" Pixel mapping: value={}, palette=0x{:02X}, shift={}, color={}", - pixel, self.bg_palette, pixel * 2, color); - } - // Set the pixel in the screen buffer self.screen_buffer[self.ly as usize][x] = color; @@ -496,18 +335,6 @@ impl GPU { if color > 0 { non_zero_pixels += 1; } - - // Debug print for the first few pixels of a specific scanline - if self.ly == 80 && x < 5 { - println!(" Pixel at ({}, {}): value={}, color={}", x, self.ly, pixel, color); - println!(" Tile index: 0x{:02X}, Tile data addr: 0x{:04X}", tile_index, tile_data_addr); - println!(" Byte1: 0x{:02X}, Byte2: 0x{:02X}, Bit: {}", byte1, byte2, bit); - } - } - - // Debug print for non-zero pixels - if self.ly == 80 { - println!(" Non-zero pixels in scanline {}: {}/{}", self.ly, non_zero_pixels, SCREEN_WIDTH); } } diff --git a/src/main.rs b/src/main.rs index 066832a..481a5b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1195,7 +1195,7 @@ fn run_gameboy() { // Initialize the GameBoy let boot_rom = std::fs::read("boot/dmg.bin").unwrap(); - let game_rom = GameRom::load("gb240p.gb"); + let game_rom = GameRom::load("dmg-acid2.gb"); let mut gameboy = CPU{ registers: Registers{a:0,b:0,c:0,d:0,e:0,f:FlagsRegister::from(0),h:0,l:0}, @@ -1280,54 +1280,6 @@ fn run_gameboy() { } } - // Check if the screen buffer has changed - unsafe { - if buffer_hash != LAST_BUFFER_HASH { - println!("Screen buffer changed at count={} (after {} frames)", - count, FRAMES_SINCE_CHANGE); - LAST_BUFFER_HASH = buffer_hash; - FRAMES_SINCE_CHANGE = 0; - LAST_CHANGE_COUNT = count; - } else { - FRAMES_SINCE_CHANGE += 1; - if FRAMES_SINCE_CHANGE % 60 == 0 { // Log every second if no change - println!("No change in screen buffer for {} frames (last change at count={})", - FRAMES_SINCE_CHANGE, LAST_CHANGE_COUNT); - } - } - } - - // Print debug info about the screen buffer - if count % 60 == 0 { // Print once per second at 60 FPS - println!("Screen buffer has {}/{} non-zero pixels", - non_zero_pixels, SCREEN_WIDTH * SCREEN_HEIGHT); - - // Print a sample of the screen buffer - println!("Sample of screen buffer:"); - for y in 70..80 { // Print 10 rows around the middle - let mut row_str = String::new(); - for x in 0..10 { // Print first 10 columns - row_str.push_str(&format!("{} ", gameboy.bus.gpu.screen_buffer[y][x])); - } - println!("Row {}: {}", y, row_str); - } - - // If no pixels are set, force some pixels to be visible for testing - if non_zero_pixels == 0 && count < 300 { // Only do this for the first few frames - println!("Forcing test pattern in screen buffer"); - for y in 70..80 { - for x in 0..10 { - // Create a simple pattern: alternating colors - gameboy.bus.gpu.screen_buffer[y][x] = ((y + x) % 4) as u8; - } - } - } - } - - // Debug: Print texture creation info - if count % 60 == 0 { - println!("Creating texture from screen buffer"); - } texture.with_lock(None, |buffer: &mut [u8], pitch: usize| { for y in 0..SCREEN_HEIGHT { @@ -1367,53 +1319,5 @@ fn run_gameboy() { // Update timing last_render_time = now; - // Print debug info more frequently - if count % 100_000 == 0 { - println!("PC: {:04X}, Count: {}, Boot ROM: {}", - gameboy.pc, - count, - if gameboy.bus.memory[0xFF50] == 0 { "enabled" } else { "disabled" }); - - // Print the current instruction - let inst = parse_instruction( - gameboy.bus.read_byte(gameboy.pc), - gameboy.bus.read_byte(gameboy.pc.wrapping_add(1)), - gameboy.bus.read_byte(gameboy.pc.wrapping_add(2)) - ); - println!("Current instruction: {:?}", inst); - - // Print some key register values - println!("Registers: A={:02X}, BC={:04X}, DE={:04X}, HL={:04X}, SP={:04X}", - gameboy.registers.a, - gameboy.registers.get_bc(), - gameboy.registers.get_de(), - gameboy.registers.get_hl(), - gameboy.sp); - } - - // Periodically reset the GPU state to ensure it doesn't get stuck - static mut RESET_COUNTER: u32 = 0; - unsafe { - RESET_COUNTER += 1; - if RESET_COUNTER >= 5_000_000 { // Reset every ~5 million instructions - println!("Periodically resetting GPU state"); - - // Re-initialize the LCD control register - gameboy.bus.gpu.lcd_control.lcd_enabled = true; - gameboy.bus.gpu.lcd_control.bg_and_window_enable = true; - gameboy.bus.gpu.lcd_control.bg_tile_map_area = false; // Use 0x9800-0x9BFF - gameboy.bus.gpu.lcd_control.bg_and_window_tile_area = true; // Use 0x8000-0x8FFF - - // Reset the LCD mode and counters - gameboy.bus.gpu.mode = LCDMode::OAMSearch; - gameboy.bus.gpu.mode_clock = 0; - - // Write the LCD control register to memory - gameboy.bus.memory[LCDC_ADDR] = u8::from(gameboy.bus.gpu.lcd_control); - - // Reset counter - RESET_COUNTER = 0; - } - } } }