diff --git a/src/bus.rs b/src/bus.rs index cbb9b33..b577a94 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -58,7 +58,7 @@ pub struct Bus { impl Bus { pub fn new() -> Self { - let game_rom = match ROM::load_file("ignore/tetris.gb".to_string()) { + let game_rom = match ROM::load_file("ignore/dmg-acid2.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs_individual/01-special.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs_individual/02-interrupts.gb".to_string()) { @@ -76,6 +76,7 @@ impl Bus { _ => panic!("Could not read ROM"), }; let mut data = [0x00; 0x10000]; + data[0xFF00] = 0b11001111; data[0xFF01] = 0x00; data[0xFF02] = 0x7E; data[0xFF04] = 0x18; @@ -95,6 +96,7 @@ impl Bus { data[0xFF4A] = 0x00; data[0xFF4B] = 0x00; + data[0xFFFF] = 0x00; Self { data, diff --git a/src/cpu.rs b/src/cpu.rs index 3d2d96b..d2c3a23 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -843,6 +843,7 @@ pub struct CPU { exec_calls_count: usize, is_halted: bool, ime: bool, // Interrupt Master Enable + ei_delay: bool, } impl CPU { @@ -853,6 +854,7 @@ impl CPU { last_op_cycles: Cycles(0), exec_calls_count: 0, is_halted: false, + ei_delay: false, ime: true, } } @@ -913,7 +915,6 @@ impl CPU { bus.set_interrupt_flag(interrupt, false); let vector = interrupt.get_vector(); self.exec(Opcode::CALL(OpcodeParameter::U16(vector)), bus); - println!("Interrupt: {:?}", interrupt); } pub fn check_interrupts(&mut self, bus: &mut Bus) -> Option { @@ -952,6 +953,12 @@ impl CPU { } self.increment_cycles(cycles); self.exec(opcode, bus); + if self.ei_delay && !self.ime { + println!("EI delay"); + self.ei_delay = false; + self.run(bus); + self.ime = true; + } } else if self.is_halted { self.increment_cycles(Cycles(1)); } @@ -1781,25 +1788,20 @@ impl CPU { Opcode::EI => { println!("EI"); self.registers.increment(Register::PC, 1); - self.ime = true; + self.ei_delay = true; }, // Disable interrupts Opcode::DI => { - println!("DI"); self.registers.increment(Register::PC, 1); self.ime = false; }, // Same as enabling interrupts and then executing RET Opcode::RETI => { - println!("RETI"); - let prev_pc = self.registers.get(Register::PC); - self.exec(Opcode::EI, bus); self.exec(Opcode::RET(OpcodeParameter::NoParam), bus); - self.registers.set(Register::PC, prev_pc.wrapping_add(1)); + self.ime = true; }, // Don't execute instructions until an interrupt is requested Opcode::HALT => { - println!("HALT"); self.registers.increment(Register::PC, 1); self.is_halted = true; }, @@ -1807,8 +1809,9 @@ impl CPU { self.registers.increment(Register::PC, 2); }, Opcode::NOP => self.registers.increment(Register::PC, 1), - Opcode::IllegalInstruction => {panic!("Illegal instruction");}, - _ => {panic!("Illegal instruction");}, + /* Opcode::IllegalInstruction => {panic!("Illegal instruction");}, + _ => {panic!("Illegal instruction");}, */ + _ => self.registers.increment(Register::PC, 1), }; } } diff --git a/src/ppu.rs b/src/ppu.rs index c9c86ba..4241e29 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -163,16 +163,20 @@ impl PPU { self.reset_cycles(); PPU::set_lcd_y(bus, PPU::get_lcd_y(bus).wrapping_add(1)); - - let lyc_compare = PPU::get_lcd_y(bus) == bus.read(LCD_Y_COMPARE_ADDRESS); - PPU::set_lcd_status(bus, LCDStatus::LYCFlag, lyc_compare); - if PPU::get_lcd_status(bus, LCDStatus::LYCInterrupt) && lyc_compare { - PPU::request_interrupt(bus, Interrupt::LCDSTAT); - } // Frame completed if PPU::get_lcd_y(bus) > 153 { PPU::set_lcd_y(bus, 0); } + PPU::check_lyc(bus); + } + } + + fn check_lyc(bus: &mut Bus) { + let lyc_compare = PPU::get_lcd_y(bus) == bus.read(LCD_Y_COMPARE_ADDRESS); + if PPU::get_lcd_status(bus, LCDStatus::LYCInterrupt) && lyc_compare { + println!("lyc"); + PPU::set_lcd_status(bus, LCDStatus::LYCFlag, lyc_compare); + PPU::request_interrupt(bus, Interrupt::LCDSTAT); } } @@ -330,6 +334,7 @@ impl PPU { } fn get_palette(index: u8, palette_byte: u8) -> u8 { + let index = index & 0b11; match index { 0b00 => palette_byte & 0b11, 0b01 => (palette_byte >> 2) & 0b11, @@ -340,12 +345,13 @@ impl PPU { } fn get_pixel(two_bit_pixel: u8) -> Pixel { + let two_bit_pixel = two_bit_pixel & 0b11; match two_bit_pixel { - 0x00 => Pixel::White, - 0x01 => Pixel::Light, - 0x10 => Pixel::Dark, - 0x11 => Pixel::Black, - _ => Pixel::Black, + 0b00 => Pixel::White, + 0b01 => Pixel::Light, + 0b10 => Pixel::Dark, + 0b11 => Pixel::Black, + _ => Pixel::White, } } diff --git a/src/timer.rs b/src/timer.rs index 48cb06e..7ca3ed5 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -48,7 +48,7 @@ impl Timer { if self.cycles.0 >= tima_rate { if tima.checked_add(1) == None { bus.write(TIMER_COUNTER_ADDRESS, bus.read(TIMER_MODULO_ADDRESS)); - bus.set_interrupt_flag(Interrupt::Timer, false); + bus.set_interrupt_flag(Interrupt::Timer, true); } else { bus.write(TIMER_COUNTER_ADDRESS, tima.wrapping_add(1)); }