Add support for programatically manipulating 16 bit registers

jsmoo
Nick Krichevsky 2022-04-09 13:57:50 -04:00
parent ef2aff5a8e
commit d85c7b8a98
1 changed files with 69 additions and 1 deletions

View File

@ -23,6 +23,12 @@ pub enum SingleEightBit {
L,
}
#[derive(Debug, Clone, Copy, strum_macros::Display)]
pub enum SixteenBit {
Combined(Combined),
Single(SingleSixteenBit),
}
// Combined represents a pair of two registers taht can be acted on as a single 8 bit
// 16 bit register.
#[derive(Debug, Clone, Copy, strum_macros::Display)]
@ -33,6 +39,12 @@ pub enum Combined {
HL,
}
#[derive(Debug, Clone, Copy, strum_macros::Display)]
pub enum SingleSixteenBit {
StackPointer,
ProgramCounter,
}
/// Registers holds all of the registers for the Gameboy
#[derive(Debug, Clone)]
pub struct Registers {
@ -141,7 +153,24 @@ impl Registers {
*register_ref = value;
}
/// Get the value of a pair of registers
/// Get the value of a 16 bit register, whether it's natively a 16 bit register or a combination of
/// 8 bit registers
pub fn get_16bit_register(&self, register: SixteenBit) -> u16 {
match register {
SixteenBit::Single(single) => self.get_single_16bit_register(single),
SixteenBit::Combined(combined) => self.get_combined_register(combined),
}
}
/// Get the value of a single 16 bit register (i.e. a natively 16 bit register)
pub fn get_single_16bit_register(&self, register: SingleSixteenBit) -> u16 {
match register {
SingleSixteenBit::StackPointer => self.stack_pointer,
SingleSixteenBit::ProgramCounter => self.program_counter,
}
}
/// Get the value of combined single 16 bit register (i.e. a combination of two 8 bit registers)
pub fn get_combined_register(&self, registers: Combined) -> u16 {
let (left_register, right_register) = self.get_register_values_for_combined(registers);
let mut res = 0_u16;
@ -151,6 +180,25 @@ impl Registers {
res
}
/// Set the value of a 16 bit register, whether it's natively a 16 bit register or a combination of
/// 8 bit registers
pub fn set_16bit_register(&mut self, register: SixteenBit, value: u16) {
match register {
SixteenBit::Single(single) => self.set_single_16bit_register(single, value),
SixteenBit::Combined(combined) => self.set_combined_register(combined, value),
}
}
/// Set the value of a single 16 bit register (i.e. a natively 16 bit register)
pub fn set_single_16bit_register(&mut self, register: SingleSixteenBit, value: u16) {
let register_ref = match register {
SingleSixteenBit::StackPointer => &mut self.stack_pointer,
SingleSixteenBit::ProgramCounter => &mut self.program_counter,
};
*register_ref = value;
}
/// Set the value of a pair of registers
pub fn set_combined_register(&mut self, registers: Combined, value: u16) {
let (left_register, right_register) = self.get_register_mut_refs_for_combined(registers);
@ -268,4 +316,24 @@ mod tests {
"got {combined_value:0b}, expected 0011001111001100"
);
}
#[test_case(Combined::AF)]
#[test_case(Combined::BC)]
#[test_case(Combined::DE)]
#[test_case(Combined::HL)]
fn test_set_sixteen_bit_register_combined(register: Combined) {
let mut registers = Registers::new();
registers.set_16bit_register(SixteenBit::Combined(register), 0x1122);
assert_eq!(0x1122, registers.get_combined_register(register));
}
#[test_case(SingleSixteenBit::StackPointer)]
#[test_case(SingleSixteenBit::ProgramCounter)]
fn test_set_sixteen_bit_register_single(register: SingleSixteenBit) {
let mut registers = Registers::new();
registers.set_16bit_register(SixteenBit::Single(register), 0x1122);
assert_eq!(0x1122, registers.get_single_16bit_register(register));
}
}