diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs index ecc0eeaeeadf5465b04dff2eea934847d71545e1..4722429573330ffa542c0261b450945c933aa03b 100644 --- a/examples/sdl/src/main.rs +++ b/examples/sdl/src/main.rs @@ -84,21 +84,21 @@ fn main() { let mut game_boy = GameBoy::new(); game_boy.load_boot_default(); - game_boy.load_rom_file("../../res/roms.prop/tetris.gb"); + //game_boy.load_rom_file("../../res/roms.prop/tetris.gb"); //game_boy.load_rom_file("../../res/roms.prop/alleyway.gb"); //game_boy.load_rom_file("../../res/roms/firstwhite.gb"); //game_boy.load_rom_file("../../res/roms/opus5.gb"); //game_boy.load_rom_file("../../res/roms/paradius/cpu/01-special.gb"); // PASSED - //game_boy.load_rom_file("../../res/roms/paradius/cpu/02-interrupts.gb"); // NO FINISH + //game_boy.load_rom_file("../../res/roms/paradius/cpu/02-interrupts.gb"); // FAILED #2 //game_boy.load_rom_file("../../res/roms/paradius/cpu/03-op sp,hl.gb"); // PASSED //game_boy.load_rom_file("../../res/roms/paradius/cpu/04-op r,imm.gb"); // PASSED //game_boy.load_rom_file("../../res/roms/paradius/cpu/05-op rp.gb"); // PASSED //game_boy.load_rom_file("../../res/roms/paradius/cpu/06-ld r,r.gb"); // PASSED //game_boy.load_rom_file("../../res/roms/paradius/cpu/07-jr,jp,call,ret,rst.gb"); // PASSED //game_boy.load_rom_file("../../res/roms/paradius/cpu/08-misc instrs.gb"); // PASSED - //game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // NO FINISH + game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // NO FINISH //game_boy.load_rom_file("../../res/roms/paradius/cpu/11-op a,(hl).gb"); // NO FINISH let mut counter = 0u32; diff --git a/src/cpu.rs b/src/cpu.rs index e56b8e5f2ba55ba83eeb4130c1818b043f980049..1e29d760c946baf923b91ef179fcb6b9b657f110 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -98,10 +98,6 @@ impl Cpu { } pub fn clock(&mut self) -> u8 { - if self.halted { - return 4; - } - // gathers the PC (program counter) reference that // is going to be used in the fetching phase let pc = self.pc; @@ -115,11 +111,14 @@ impl Cpu { if self.ime { // @todo aggregate all of this interrupts in the MMU if (self.mmu.ie & 0x01 == 0x01) && self.mmu.ppu().int_vblank() { - println!("Going to run V-Blank interrupt handler"); - let pc = self.pc; + println!("Going to run V-Blank interrupt handler (0x40)"); + self.disable_int(); self.push_word(pc); self.pc = 0x40; + + // acknowledges that the V-Blank interrupt has been + // properly handled self.mmu.ppu().ack_vblank(); // in case the CPU is currently halted waiting @@ -132,6 +131,13 @@ impl Cpu { } } + // in case the CPU is currently in the halted state + // returns the control flow immediately with the associated + // number of cycles estimated for the halted execution + if self.halted { + return 4; + } + // fetches the current instruction and increments // the PC (program counter) accordingly let mut opcode = self.mmu.read(self.pc); @@ -151,6 +157,9 @@ impl Cpu { let (instruction_fn, instruction_time, instruction_str) = instruction; if *instruction_str == "! UNIMP !" || *instruction_str == "HALT" { + if *instruction_str == "HALT" { + println!("Waiting for {:x} in HALT", self.mmu.ie); + } println!( "{}\t(0x{:02x})\t${:04x} {}", instruction_str, opcode, pc, is_prefix diff --git a/src/inst.rs b/src/inst.rs index a50aa73f055063255895cf64bb7d765ac598a93e..faf104823355677f80df5ab208d82fb5750f8b64 100644 --- a/src/inst.rs +++ b/src/inst.rs @@ -322,14 +322,14 @@ pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 256] = [ (sla_l, 8, "SLA L"), (sla_mhl, 16, "SLA [HL]"), (sla_a, 8, "SLA A"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), + (sra_b, 8, "SRA B"), + (sra_c, 8, "SRA C"), + (sra_d, 8, "SRA D"), + (sra_e, 8, "SRA E"), + (sra_h, 8, "SRA H"), + (sra_l, 8, "SRA L"), + (sra_mhl, 16, "SRA [HL]"), + (sra_a, 8, "SRA A"), // 0x3 opcodes (noimpl, 4, "! UNIMP !"), (noimpl, 4, "! UNIMP !"), @@ -2218,6 +2218,41 @@ fn sla_a(cpu: &mut Cpu) { cpu.a = sla(cpu, cpu.a); } +fn sra_b(cpu: &mut Cpu) { + cpu.b = sra(cpu, cpu.b); +} + +fn sra_c(cpu: &mut Cpu) { + cpu.c = sra(cpu, cpu.c); +} + +fn sra_d(cpu: &mut Cpu) { + cpu.d = sra(cpu, cpu.d); +} + +fn sra_e(cpu: &mut Cpu) { + cpu.e = sra(cpu, cpu.e); +} + +fn sra_h(cpu: &mut Cpu) { + cpu.h = sra(cpu, cpu.h); +} + +fn sra_l(cpu: &mut Cpu) { + cpu.l = sra(cpu, cpu.l); +} + +fn sra_mhl(cpu: &mut Cpu) { + let hl = cpu.hl(); + let byte = cpu.mmu.read(hl); + let result = sra(cpu, byte); + cpu.mmu.write(hl, result); +} + +fn sra_a(cpu: &mut Cpu) { + cpu.a = sra(cpu, cpu.a); +} + fn swap_a(cpu: &mut Cpu) { cpu.a = swap(cpu, cpu.a) } @@ -2777,7 +2812,18 @@ fn sla(cpu: &mut Cpu, value: u8) -> u8 { cpu.set_sub(false); cpu.set_zero(result == 0); cpu.set_half_carry(false); - cpu.set_carry(value & 0x80 != 0); + cpu.set_carry(value & 0x80 == 0x80); + + result +} + +fn sra(cpu: &mut Cpu, value: u8) -> u8 { + let result = (value >> 1) | (value & 0x80); + + cpu.set_sub(false); + cpu.set_zero(result == 0); + cpu.set_half_carry(false); + cpu.set_carry(value & 0x01 == 0x01); result }