chore: improve unreachable! and panic! error messages
This commit is contained in:
parent
2813b762dd
commit
342e6616ac
12
src/bus.rs
12
src/bus.rs
|
@ -102,7 +102,7 @@ impl Bus {
|
||||||
0xA000..=0xBFFF => match self.cartridge.as_ref() {
|
0xA000..=0xBFFF => match self.cartridge.as_ref() {
|
||||||
// 8KB External RAM
|
// 8KB External RAM
|
||||||
Some(cart) => cart.read_byte(addr),
|
Some(cart) => cart.read_byte(addr),
|
||||||
None => panic!("Tried to read from the external RAM of a non-existent cartridge"),
|
None => panic!("Tried to read from a non-existent cartridge"),
|
||||||
},
|
},
|
||||||
0xC000..=0xCFFF => {
|
0xC000..=0xCFFF => {
|
||||||
// 4KB Work RAM Bank 0
|
// 4KB Work RAM Bank 0
|
||||||
|
@ -120,7 +120,7 @@ impl Bus {
|
||||||
// Sprite Attribute Table
|
// Sprite Attribute Table
|
||||||
unimplemented!("Unable to read {:#06X} in the Sprite Attribute Table", addr);
|
unimplemented!("Unable to read {:#06X} in the Sprite Attribute Table", addr);
|
||||||
}
|
}
|
||||||
0xFEA0..=0xFEFF => unreachable!("{:#06X} is not allowed to be used", addr),
|
0xFEA0..=0xFEFF => unreachable!("{:#06X} is not allowed to be read from", addr),
|
||||||
0xFF00..=0xFF7F => {
|
0xFF00..=0xFF7F => {
|
||||||
// IO Registers
|
// IO Registers
|
||||||
match addr {
|
match addr {
|
||||||
|
@ -169,14 +169,14 @@ impl Bus {
|
||||||
// 16KB ROM bank 00
|
// 16KB ROM bank 00
|
||||||
match self.cartridge.as_mut() {
|
match self.cartridge.as_mut() {
|
||||||
Some(cart) => cart.write_byte(addr, byte),
|
Some(cart) => cart.write_byte(addr, byte),
|
||||||
None => panic!("Tried to write into non-existent Cartridge"),
|
None => panic!("Tried to write into non-existent cartridge"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x4000..=0x7FFF => {
|
0x4000..=0x7FFF => {
|
||||||
// 16KB ROM Bank 01 -> NN (switchable via MB)
|
// 16KB ROM Bank 01 -> NN (switchable via MB)
|
||||||
match self.cartridge.as_mut() {
|
match self.cartridge.as_mut() {
|
||||||
Some(cart) => cart.write_byte(addr, byte),
|
Some(cart) => cart.write_byte(addr, byte),
|
||||||
None => panic!("Tried to write into non-existent Cartridge"),
|
None => panic!("Tried to write into non-existent cartridge"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x8000..=0x9FFF => {
|
0x8000..=0x9FFF => {
|
||||||
|
@ -187,7 +187,7 @@ impl Bus {
|
||||||
// 8KB External RAM
|
// 8KB External RAM
|
||||||
match self.cartridge.as_mut() {
|
match self.cartridge.as_mut() {
|
||||||
Some(cart) => cart.write_byte(addr, byte),
|
Some(cart) => cart.write_byte(addr, byte),
|
||||||
None => panic!("Tried to write into non-existent Cartridge"),
|
None => panic!("Tried to write into non-existent cartridge"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xC000..=0xCFFF => {
|
0xC000..=0xCFFF => {
|
||||||
|
@ -206,7 +206,7 @@ impl Bus {
|
||||||
// Sprite Attribute Table
|
// Sprite Attribute Table
|
||||||
unimplemented!("Unable to write to {:#06X} in Sprite Attribute Table", addr);
|
unimplemented!("Unable to write to {:#06X} in Sprite Attribute Table", addr);
|
||||||
}
|
}
|
||||||
0xFEA0..=0xFEFF => unreachable!("{:#06X} is not allowed to be used", addr),
|
0xFEA0..=0xFEFF => unreachable!("{:#06X} is not allowed to be written to", addr),
|
||||||
0xFF00..=0xFF7F => {
|
0xFF00..=0xFF7F => {
|
||||||
// IO Registers
|
// IO Registers
|
||||||
match addr {
|
match addr {
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl Cartridge {
|
||||||
0x00 => MBCKind::None,
|
0x00 => MBCKind::None,
|
||||||
0x01 => MBCKind::MBC1,
|
0x01 => MBCKind::MBC1,
|
||||||
0x19 => MBCKind::MBC5,
|
0x19 => MBCKind::MBC5,
|
||||||
_ => panic!("Cartridge uses an unknown Memory Bank Controller"),
|
_ => unimplemented!("{} is the id of an unsupported memory bank controller", id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ impl MBC1 {
|
||||||
ThirtyTwo | Sixteen | Eight | Four => 0,
|
ThirtyTwo | Sixteen | Eight | Four => 0,
|
||||||
SixtyFour => (self.ram_bank & 0x01) << 5,
|
SixtyFour => (self.ram_bank & 0x01) << 5,
|
||||||
OneHundredTwentyEight => self.ram_bank << 5,
|
OneHundredTwentyEight => self.ram_bank << 5,
|
||||||
_ => unreachable!("{:#?} is not a valid MBC1 BankCount", self.bank_count),
|
_ => unreachable!("{:?} is not a valid MBC1 BankCount", self.bank_count),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,13 +126,15 @@ impl MBC1 {
|
||||||
num &= !(0x03 << 5);
|
num &= !(0x03 << 5);
|
||||||
num | ((self.ram_bank) << 5)
|
num | ((self.ram_bank) << 5)
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:#?} is not a valid MBC1 BankCount", self.bank_count),
|
_ => unreachable!("{:?} is not a valid MBC1 BankCount", self.bank_count),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_rom_size_bitmask(&self, byte: u8) -> u8 {
|
fn apply_rom_size_bitmask(&self, byte: u8) -> u8 {
|
||||||
use BankCount::*;
|
use BankCount::*;
|
||||||
|
|
||||||
|
let err_bc = self.bank_count; // Bank Count, but with a shorter name
|
||||||
|
|
||||||
match self.bank_count {
|
match self.bank_count {
|
||||||
Four => byte & 0b00000011,
|
Four => byte & 0b00000011,
|
||||||
Eight => byte & 0b00000111,
|
Eight => byte & 0b00000111,
|
||||||
|
@ -140,7 +142,7 @@ impl MBC1 {
|
||||||
ThirtyTwo => byte & 0b00011111,
|
ThirtyTwo => byte & 0b00011111,
|
||||||
SixtyFour => byte & 0b00011111,
|
SixtyFour => byte & 0b00011111,
|
||||||
OneHundredTwentyEight => byte & 0b00011111,
|
OneHundredTwentyEight => byte & 0b00011111,
|
||||||
_ => unreachable!("{:#?} does not have a bitmask in MBC1", self.bank_count),
|
_ => unreachable!("{:?} does not have a rom size bitmask in MBC1", err_bc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ impl From<u8> for RamSize {
|
||||||
0x03 => _32KB,
|
0x03 => _32KB,
|
||||||
0x04 => _128KB,
|
0x04 => _128KB,
|
||||||
0x05 => _64KB,
|
0x05 => _64KB,
|
||||||
_ => unreachable!("{:#04X} is an invalid value for RAMSize"),
|
_ => unreachable!("{:#04X} is not a valid value for RAMSize", byte),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +360,7 @@ impl From<u8> for BankCount {
|
||||||
0x52 => SeventyTwo,
|
0x52 => SeventyTwo,
|
||||||
0x53 => Eighty,
|
0x53 => Eighty,
|
||||||
0x54 => NinetySix,
|
0x54 => NinetySix,
|
||||||
_ => unreachable!("{:#04X} is an invalid value for BankCount", byte),
|
_ => unreachable!("{:#04X} is not a valid value for BankCount", byte),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl Instruction {
|
||||||
| RegisterPair::DE
|
| RegisterPair::DE
|
||||||
| RegisterPair::HL
|
| RegisterPair::HL
|
||||||
| RegisterPair::SP => cpu.set_register_pair(pair, nn),
|
| RegisterPair::SP => cpu.set_register_pair(pair, nn),
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"LD {:?}, nn\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ impl Instruction {
|
||||||
|
|
||||||
cpu.set_register_pair(RegisterPair::HL, addr - 1);
|
cpu.set_register_pair(RegisterPair::HL, addr - 1);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"LD ({:?}), A\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl Instruction {
|
||||||
|
|
||||||
cpu.set_register_pair(RegisterPair::HL, addr - 1);
|
cpu.set_register_pair(RegisterPair::HL, addr - 1);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"LD A, ({:?})\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, byte);
|
cpu.set_register(Register::A, byte);
|
||||||
Cycles::new(16)
|
Cycles::new(16)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"LD {:?}, {:?}\" instruction", lhs, rhs),
|
||||||
},
|
},
|
||||||
Instruction::STOP => Cycles::new(4),
|
Instruction::STOP => Cycles::new(4),
|
||||||
Instruction::JR(cond, offset) => {
|
Instruction::JR(cond, offset) => {
|
||||||
|
@ -356,7 +356,7 @@ impl Instruction {
|
||||||
|
|
||||||
cpu.set_register_pair(RegisterPair::HL, sum);
|
cpu.set_register_pair(RegisterPair::HL, sum);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"ADD HL, {:?}\" instruction", pair),
|
||||||
}
|
}
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
|
@ -402,7 +402,7 @@ impl Instruction {
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"ADD {:?}, {:?}\" instruction", lhs, rhs),
|
||||||
},
|
},
|
||||||
Instruction::INC(registers) => {
|
Instruction::INC(registers) => {
|
||||||
match registers {
|
match registers {
|
||||||
|
@ -445,7 +445,7 @@ impl Instruction {
|
||||||
let value = cpu.register_pair(pair);
|
let value = cpu.register_pair(pair);
|
||||||
cpu.set_register_pair(pair, value + 1);
|
cpu.set_register_pair(pair, value + 1);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"INC {:?}\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ impl Instruction {
|
||||||
let value = cpu.register_pair(pair);
|
let value = cpu.register_pair(pair);
|
||||||
cpu.set_register_pair(pair, value - 1);
|
cpu.set_register_pair(pair, value - 1);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"DEC {:?}\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
@ -618,7 +618,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, sum);
|
cpu.set_register(Register::A, sum);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"ADC {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::SUB(target) => match target {
|
Instruction::SUB(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -660,7 +660,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, diff);
|
cpu.set_register(Register::A, diff);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"SUB {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::SBC(target) => match target {
|
Instruction::SBC(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -705,7 +705,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, diff);
|
cpu.set_register(Register::A, diff);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"SBC {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::AND(target) => match target {
|
Instruction::AND(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -749,7 +749,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, result);
|
cpu.set_register(Register::A, result);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"AND {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::XOR(target) => match target {
|
Instruction::XOR(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -793,7 +793,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, result);
|
cpu.set_register(Register::A, result);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"XOR {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::OR(target) => match target {
|
Instruction::OR(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -837,7 +837,7 @@ impl Instruction {
|
||||||
cpu.set_register(Register::A, result);
|
cpu.set_register(Register::A, result);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"OR {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::CP(target) => match target {
|
Instruction::CP(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
|
@ -875,7 +875,7 @@ impl Instruction {
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"CP {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::RET(cond) => {
|
Instruction::RET(cond) => {
|
||||||
// RET cc[y] | Essentially a POP PC, Return from Subroutine
|
// RET cc[y] | Essentially a POP PC, Return from Subroutine
|
||||||
|
@ -931,14 +931,14 @@ impl Instruction {
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
Instruction::POP(pair) => {
|
Instruction::POP(pair) => {
|
||||||
// POP rp2[p] | Pop from stack into register pair rp[2]
|
// POP rp2[p] | Pop from stack into register pair rp2[]
|
||||||
// Flags are set when we call cpu.set_register_pair(RegisterPair::AF, value);
|
// Flags are set when we call cpu.set_register_pair(RegisterPair::AF, value);
|
||||||
match pair {
|
match pair {
|
||||||
RegisterPair::BC | RegisterPair::DE | RegisterPair::HL | RegisterPair::AF => {
|
RegisterPair::BC | RegisterPair::DE | RegisterPair::HL | RegisterPair::AF => {
|
||||||
let value = Self::pop(cpu);
|
let value = Self::pop(cpu);
|
||||||
cpu.set_register_pair(pair, value);
|
cpu.set_register_pair(pair, value);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"POP {:?}\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
@ -995,7 +995,7 @@ impl Instruction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"JP {:?}\" instruction", target),
|
||||||
},
|
},
|
||||||
Instruction::DI => {
|
Instruction::DI => {
|
||||||
// Disable IME
|
// Disable IME
|
||||||
|
@ -1061,7 +1061,7 @@ impl Instruction {
|
||||||
let value = cpu.register_pair(pair);
|
let value = cpu.register_pair(pair);
|
||||||
Self::push(cpu, value);
|
Self::push(cpu, value);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!("There is no \"PUSH {:?}\" instruction", pair),
|
||||||
}
|
}
|
||||||
Cycles::new(16)
|
Cycles::new(16)
|
||||||
}
|
}
|
||||||
|
@ -1814,22 +1814,22 @@ impl Instruction {
|
||||||
JumpCondition::Always,
|
JumpCondition::Always,
|
||||||
JPTarget::ImmediateWord(cpu.read_imm_word(pc)),
|
JPTarget::ImmediateWord(cpu.read_imm_word(pc)),
|
||||||
),
|
),
|
||||||
(3, 3, _, 1, _) => unreachable!("This is the 0xCB Prefix"),
|
(3, 3, _, 1, _) => unreachable!("0xCB is handled by Instruction::from_prefixed_byte"),
|
||||||
// (3, 3, _, 2, _) => unreachable!(), ("removed" in documentation)
|
// (3, 3, _, 2, _) => unreachable!("\"removed\" in documentation"),
|
||||||
// (3, 3, _, 3, _) => unreachable!(), ("removed" in documentation)
|
// (3, 3, _, 3, _) => unreachable!("\"removed\" in documentation"),
|
||||||
// (3, 3, _, 4, _) => unreachable!(), ("removed" in documentation)
|
// (3, 3, _, 4, _) => unreachable!("\"removed\" in documentation"),
|
||||||
// (3, 3, _, 5, _) => unreachable!(), ("removed" in documentation)
|
// (3, 3, _, 5, _) => unreachable!("\"removed\" in documentation"),
|
||||||
(3, 3, _, 6, _) => Self::DI,
|
(3, 3, _, 6, _) => Self::DI,
|
||||||
(3, 3, _, 7, _) => Self::EI,
|
(3, 3, _, 7, _) => Self::EI,
|
||||||
(3, 4, _, 0..=3, _) => Self::CALL(Table::cc(y), cpu.read_imm_word(pc)), // CALL cc[y], nn
|
(3, 4, _, 0..=3, _) => Self::CALL(Table::cc(y), cpu.read_imm_word(pc)), // CALL cc[y], nn
|
||||||
// (3, 4, _, 4..=7, _) => unreachable!(), ("removed" in documentation)
|
// (3, 4, _, 4..=7, _) => unreachable!("\"removed\" in documentation"),
|
||||||
(3, 5, 0, _, _) => Self::PUSH(Table::rp2(p)), // PUSH rp2[p]
|
(3, 5, 0, _, _) => Self::PUSH(Table::rp2(p)), // PUSH rp2[p]
|
||||||
(3, 5, 1, _, 0) => Self::CALL(JumpCondition::Always, cpu.read_imm_word(pc)), // CALL nn
|
(3, 5, 1, _, 0) => Self::CALL(JumpCondition::Always, cpu.read_imm_word(pc)), // CALL nn
|
||||||
// (3, 5, 1, _, 1..=3) => unreachable!(), ("removed" in documentation)
|
// (3, 5, 1, _, 1..=3) => unreachable!("\"removed\" in documentation"),
|
||||||
(3, 6, _, _, _) => Table::x3_alu(y, cpu.read_imm_byte(pc)),
|
(3, 6, _, _, _) => Table::x3_alu(y, cpu.read_imm_byte(pc)),
|
||||||
(3, 7, _, _, _) => Self::RST(y * 8), // RST n
|
(3, 7, _, _, _) => Self::RST(y * 8), // RST n
|
||||||
_ => panic!(
|
_ => unreachable!(
|
||||||
"Unknown Opcode: {:#x?}\n x: {}, z: {}, q: {}, y: {}, p: {}",
|
"Unknown Opcode: {:#04X}\n x: {}, z: {}, q: {}, y: {}, p: {}",
|
||||||
opcode, x, z, q, y, p
|
opcode, x, z, q, y, p
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -1851,8 +1851,8 @@ impl Instruction {
|
||||||
1 => Self::BIT(y, Table::r(z)), // BIT y, r[z]
|
1 => Self::BIT(y, Table::r(z)), // BIT y, r[z]
|
||||||
2 => Self::RES(y, Table::r(z)), // RES y, r[z]
|
2 => Self::RES(y, Table::r(z)), // RES y, r[z]
|
||||||
3 => Self::SET(y, Table::r(z)), // SET y, r[z]
|
3 => Self::SET(y, Table::r(z)), // SET y, r[z]
|
||||||
_ => panic!(
|
_ => unreachable!(
|
||||||
"Unknown Prefixed Opcode: 0xCB {:#x?}\n x: {}, z: {}, q: {}, y: {}, p: {}",
|
"Unknown Prefixed Opcode: 0xCB {:#04X}\n x: {}, z: {}, q: {}, y: {}, p: {}",
|
||||||
opcode, x, z, q, y, p
|
opcode, x, z, q, y, p
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue