diff --git a/src/main.rs b/src/main.rs index a2b85bf..6b036c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -119,12 +119,14 @@ struct CPU { pc: u16, bus: MemoryBus, sp: u16, - boot_rom: Vec, } +const BOOT_BEGIN: usize = 0x0000; +const BOOT_END: usize = 0x00FF; +const CART_BEGIN: usize = 0x0100; +const CART_END: usize = 0x7FFF; const VRAM_BEGIN: usize = 0x8000; const VRAM_END: usize = 0x9FFF; -const CART_BEGIN: usize = 0x0000; -const CART_END: usize = 0x7FFF; + struct GPU { vram: Vec, tile_set: [[[TilePixelValue; 8]; 8]; 384] } #[derive(Copy, Clone)] enum TilePixelValue { Three, Two, One, Zero } @@ -134,7 +136,7 @@ impl GPU { self.vram[address] } fn write_vram(&mut self, index: usize, value: u8) { - self.vram[index] = value; + // self.vram[index] = value; // If our index is greater than 0x1800, we're not writing to the tile set storage // so we can just return. if index >= 0x1800 { return } @@ -199,6 +201,7 @@ struct MemoryBus { memory: [u8; 0xFFFF], gpu: GPU, rom: GameRom, + boot: Vec, } impl MemoryBus { fn read_byte(&self, address: u16) -> u8 { @@ -207,8 +210,15 @@ impl MemoryBus { VRAM_BEGIN ..= VRAM_END => { self.gpu.read_vram(address - VRAM_BEGIN) } + BOOT_BEGIN..=BOOT_END => { + if self.memory[0xFF50] == 0x00 { + self.boot[address] + }else { + self.rom.read_byte(address) + } + } CART_BEGIN ..= CART_END => {self.rom.read_byte(address)} - _ => self.memory[address as usize] + _ => self.memory[address] } } fn write_byte(&mut self, address: u16, value: u8) { @@ -334,12 +344,7 @@ impl CPU { let l = self.bus.memory.len(); println!("{l}"); println!("CPU init"); - // println!("Boot ROM: {:02X?}", self.boot_rom); - for (address, byte) in self.boot_rom.iter().enumerate() { - self.bus.write_byte(address as u16, *byte); - } - // println!("Game ROM: {:02X?}", self.game_rom); - + self.bus.write_byte(0xFF50, 0x00); } fn check_condition(&self, condition: Condition) -> bool { match condition { @@ -942,6 +947,14 @@ impl CPU { _ => { panic!("Invalid u16 opcode: {:02X}", opcode); } } } + fn execute_next_instruction(&mut self) { + if self.pc >= 0x100 { + println!("Boot Complete"); + } + let inst = self.next_instruction(); + println!("{} {:?}", self.pc, inst); + self.execute(inst); + } fn execute(&mut self, instruction: Instruction) { match instruction { Instruction::ADC(target) => { @@ -953,6 +966,10 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::ADD(target) => { let value = self.get_target_value(target); @@ -962,6 +979,10 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::ADDHL(target) => { let value = self.get_u16_reg_value(target); @@ -971,6 +992,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (new_value & 0xFF) + (value & 0xFF) > 0xFF; + self.pc += 1; } Instruction::ADDSP(value) => { let offset = (value as i16) as u16; @@ -980,6 +1002,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (new_value & 0xFF) + (offset & 0xFF) > 0xFF; + self.pc += 2; } Instruction::AND(target) => { let value = self.get_target_value(target); @@ -988,17 +1011,22 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = false; self.registers.f.half_carry = true; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::BIT(bit, target) => { let value = self.get_target_value(target); self.registers.f.zero = value >> bit & 0x1 == 0; self.registers.f.subtract = false; self.registers.f.half_carry = true; + self.pc += 2; } Instruction::CALL(condition, address) => { if self.check_condition(condition) { self.sp = self.sp.wrapping_sub(2); - let pc = self.pc; + let pc = self.pc+3; self.bus.write_byte(self.sp + 1, ((pc >> 8) & 0xFF) as u8); self.bus.write_byte(self.sp, (pc & 0xFF) as u8); self.pc = address; @@ -1008,6 +1036,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.half_carry = false; self.registers.f.carry = !self.registers.f.carry; + self.pc += 1; } Instruction::CP(target) => { let value = self.get_target_value(target); @@ -1016,11 +1045,16 @@ impl CPU { self.registers.f.subtract = true; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::CPL => { self.registers.a = !self.registers.a; self.registers.f.subtract = true; self.registers.f.half_carry = true; + self.pc += 1; } Instruction::DAA => { let new_value; @@ -1047,6 +1081,7 @@ impl CPU { self.registers.f.carry = did_overflow; self.registers.f.zero = new_value == 0; self.registers.f.half_carry = false; + self.pc += 1; } Instruction::DEC(target) => { match target { @@ -1066,6 +1101,7 @@ impl CPU { Target::Address(_) => {} Target::Immediate(_) => {} } + self.pc += 1; } Instruction::DECHL(register) => { let target = Target::U16Register(register); @@ -1075,10 +1111,17 @@ impl CPU { self.registers.f.zero = new_value == 0; self.registers.f.subtract = true; self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF; + self.pc += 1; + } + Instruction::DI => { + self.pc += 1; + } + Instruction::EI => { + self.pc += 1; + } + Instruction::HALT => { + self.pc += 1; } - Instruction::DI => {} - Instruction::EI => {} - Instruction::HALT => {todo!();} Instruction::INC(target) => { match target { @@ -1098,6 +1141,7 @@ impl CPU { Target::Address(_) => {} Target::Immediate(_) => {} } + self.pc += 1; } Instruction::INCHL(register) => { let target = Target::U16Register(register); @@ -1107,6 +1151,7 @@ impl CPU { self.registers.f.zero = new_value == 0; self.registers.f.subtract = true; self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF; + self.pc += 1; } Instruction::JP(condition, address) => { if self.check_condition(condition) { @@ -1119,7 +1164,7 @@ impl CPU { Instruction::JR(condition, offset) => { if self.check_condition(condition) { self.pc = if offset.is_negative() { - self.pc.wrapping_sub(offset.abs() as u16) + self.pc.wrapping_sub(offset.abs() as u16 - 1) } else { self.pc.wrapping_add(offset as u16) } @@ -1130,94 +1175,116 @@ impl CPU { LoadTarget::CopyR8R8(dest_register, source_register) => { let value = self.get_u8_reg_value(source_register); self.set_u8_reg_value(dest_register, value); + self.pc += 1; } LoadTarget::CopyR8N8(dest_register, value) => { self.set_u8_reg_value(dest_register, value); + self.pc += 2; } LoadTarget::CopyR16N16(dest_register, value) => { self.set_u16_reg_value(dest_register, value); + self.pc += 3; } LoadTarget::CopyHLR8(source_register) => { let value = self.get_u8_reg_value(source_register); let address = self.registers.get_hl(); self.bus.write_byte(address, value); + self.pc += 1; } LoadTarget::CopyHLN8(value) => { let address = self.registers.get_hl(); self.bus.write_byte(address, value); + self.pc += 2; } LoadTarget::CopyR8HL(dest_register) => { let address = self.registers.get_hl(); let value = self.bus.read_byte(address); self.set_u8_reg_value(dest_register, value); + self.pc += 1; } LoadTarget::CopyR16A(dest_register) => { let address = self.get_u16_reg_value(dest_register); self.bus.write_byte(address, self.registers.a); + self.pc += 1; } LoadTarget::CopyN16A(address) => { self.bus.write_byte(address, self.registers.a); + self.pc += 3; } LoadTarget::CopyPortA(target) => { let offset = self.get_target_value(target); let address = 0xFF00 | offset as u16; self.bus.write_byte(address, self.registers.a); + self.pc += 2; } LoadTarget::CopyAPort(target) => { let offset = self.get_target_value(target); let address = 0xFF00 | offset as u16; self.registers.a = self.bus.read_byte(address); + self.pc += 2; } LoadTarget::CopyHN16A(address) => { if address >= 0xFF00 { self.bus.write_byte(address, self.registers.a) } + self.pc += 2; } LoadTarget::CopyHCA => { let address = 0xFF00 + self.registers.c as u16; - self.bus.write_byte(address, self.registers.a) + self.bus.write_byte(address, self.registers.a); + self.pc += 1; } LoadTarget::CopyAR16(source_register) => { let address = self.get_u16_reg_value(source_register); self.registers.a = self.bus.read_byte(address); + self.pc += 1; } LoadTarget::CopyAN16(address) => { self.registers.a = self.bus.read_byte(address); + self.pc += 3; } LoadTarget::CopyHAN16(address) => { if address >= 0xFF00 { - self.registers.a = self.bus.read_byte(address) + self.registers.a = self.bus.read_byte(address); } + self.pc += 2; } LoadTarget::CopyHAC => { - self.registers.a = self.bus.read_byte(0xFF00+self.registers.c as u16) + self.registers.a = self.bus.read_byte(0xFF00+self.registers.c as u16); + self.pc += 1; } LoadTarget::CopyHLIA => { let address = self.registers.get_hl(); self.bus.write_byte(address, self.registers.a); self.registers.set_hl(address.wrapping_add(1)); + self.pc += 1; } LoadTarget::CopyHLDA => { let address = self.registers.get_hl(); self.bus.write_byte(address, self.registers.a); self.registers.set_hl(address.wrapping_sub(1)); + self.pc += 1; } LoadTarget::CopyAHLI => { let address = self.registers.get_hl(); self.registers.a = self.bus.read_byte(address); self.registers.set_hl(address.wrapping_add(1)); + self.pc += 1; } LoadTarget::CopyAHLD => { let address = self.registers.get_hl(); self.registers.a = self.bus.read_byte(address); self.registers.set_hl(address.wrapping_sub(1)); + self.pc += 1; } LoadTarget::CopySPN16(value) => { self.sp = value; + self.pc += 3; } LoadTarget::CopyN16SP(address) => { self.bus.write_byte(address, (0xF & self.sp) as u8); self.bus.write_byte(address + 1, (self.sp >> 8) as u8); + self.pc += 3; } LoadTarget::CopyHLSPE8(value) => { @@ -1230,14 +1297,17 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = (new_value & 0xFF) + (self.sp & 0xFF) > 0xFF; self.registers.f.half_carry = (new_value & 0xF) + (self.sp & 0xF) > 0xF; - + self.pc += 2; } LoadTarget::CopySPHL => { self.sp = self.registers.get_hl(); + self.pc += 1; } } } - Instruction::NOP => {} + Instruction::NOP => { + self.pc += 1; + } Instruction::OR(target) => { let value = self.get_target_value(target); self.registers.a = value | self.registers.a; @@ -1245,23 +1315,32 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = false; self.registers.f.half_carry = false; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::POP(target) => { let value = self.pop_stack(); self.set_u16_reg_value(target, value); + self.pc += 1; } Instruction::PUSH(target) => { let value = self.get_u16_reg_value(target); self.push_stack(value); + self.pc += 1; } Instruction::RES(bit, target) => { let mut value = self.get_target_value(target); value &= !(1 << bit); self.set_target_value(target, value); + self.pc += 2; } Instruction::RET(condition) => { if self.check_condition(condition) { self.pc = self.pop_stack(); + } else { + self.pc += 1; } } Instruction::RETI => { @@ -1276,6 +1355,10 @@ impl CPU { self.registers.f.zero = false; self.registers.f.subtract = false; self.registers.f.half_carry = false; + self.pc += match self.bus.read_byte(self.pc) { + 0x17 => {1} + _ => {2} + } } Instruction::RLC(target) => { let old_value = self.get_target_value(target); @@ -1285,6 +1368,10 @@ impl CPU { self.registers.f.zero = false; self.registers.f.subtract = false; self.registers.f.half_carry = false; + self.pc += match self.bus.read_byte(self.pc) { + 0x07 => {1} + _ => {2} + } } Instruction::RR(target) => { let old_value = self.get_target_value(target); @@ -1295,6 +1382,10 @@ impl CPU { self.registers.f.zero = false; self.registers.f.subtract = false; self.registers.f.half_carry = false; + self.pc += match self.bus.read_byte(self.pc) { + 0x1F => {1} + _ => {2} + } } Instruction::RRC(target) => { let old_value = self.get_target_value(target); @@ -1304,6 +1395,10 @@ impl CPU { self.registers.f.zero = false; self.registers.f.subtract = false; self.registers.f.half_carry = false; + self.pc += match self.bus.read_byte(self.pc) { + 0x0F => {1} + _ => {2} + } } Instruction::RST(idx) => { self.push_stack(self.pc); @@ -1319,16 +1414,22 @@ impl CPU { self.registers.f.subtract = true; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::SCF => { self.registers.f.carry = true; self.registers.f.subtract = false; self.registers.f.half_carry = false; + self.pc += 1; } Instruction::SET(bit, target) => { let mut value = self.get_target_value(target); value |= 1 << bit; self.set_target_value(target, value); + self.pc += 2; } Instruction::SLA(target) => { let value = self.get_target_value(target); @@ -1338,6 +1439,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = value & 0x80 == 0x80; self.registers.f.half_carry = false; + self.pc += 2; } Instruction::SRA(target) => { let value = self.get_target_value(target); @@ -1347,6 +1449,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = value & 0x80 == 0x80; self.registers.f.half_carry = false; + self.pc += 2; } Instruction::SRL(target) => { let value = self.get_target_value(target); @@ -1356,9 +1459,10 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = value & 0x1 == 0x1; self.registers.f.half_carry = false; + self.pc += 2; } Instruction::STOP(_) => { - + self.pc += 2; } Instruction::SUB(target) => { let value = self.get_target_value(target); @@ -1368,6 +1472,10 @@ impl CPU { self.registers.f.subtract = true; self.registers.f.carry = did_overflow; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } Instruction::SWAP(target) => { let value = self.get_target_value(target); @@ -1377,6 +1485,7 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = false; self.registers.f.half_carry = false; + self.pc += 2; } Instruction::XOR(target) => { let value = self.get_target_value(target); @@ -1385,6 +1494,10 @@ impl CPU { self.registers.f.subtract = false; self.registers.f.carry = false; self.registers.f.half_carry = false; + self.pc += match target { + Target::Immediate(_) => {2} + _ => {1} + }; } } } @@ -1402,18 +1515,14 @@ fn main() { pc:0, bus:MemoryBus{ memory: [0xFFu8; 0xFFFF], - gpu:GPU{ vram: Vec::with_capacity(VRAM_END-VRAM_BEGIN), tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] }, + gpu:GPU{ vram: vec![0xFFu8;VRAM_END-VRAM_BEGIN+1], tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] }, rom: game_rom, + boot: boot_rom, }, sp: 0, - boot_rom, }; gameboy.init(); - let sp = gameboy.sp; - println!("{sp:?}"); - let f = gameboy.next_instruction(); - println!("{f:?}"); - gameboy.execute(f); - let sp = gameboy.sp; - println!("{sp:?}"); + loop { + gameboy.execute_next_instruction() + } }