Implement load immediate to (hl)

jsmoo
Nick Krichevsky 2022-04-04 23:41:25 -04:00
parent dcaf0588de
commit e95cd263c5
1 changed files with 39 additions and 0 deletions

View File

@ -33,6 +33,10 @@ pub enum Instruction {
LDToHLAddress {
src: register::Single,
},
// 3.3.1.2, but the (hl), n instruction [why is this in this section? it's so out of place]
LDnToHLAddress {
value: u8,
},
}
struct RunnableInstruction {
@ -111,6 +115,7 @@ impl RunnableInstruction {
0x73 => Self::make_ld_to_hl_address(register::Single::E, data),
0x74 => Self::make_ld_to_hl_address(register::Single::H, data),
0x75 => Self::make_ld_to_hl_address(register::Single::L, data),
0x36 => Self::make_ld_n_to_hl_address(data),
_ => panic!("invalid opcode {opcode:0x}"),
}
}
@ -161,6 +166,16 @@ impl RunnableInstruction {
&data[1..],
)
}
fn make_ld_n_to_hl_address(data: &[u8]) -> (RunnableInstruction, &[u8]) {
(
RunnableInstruction {
instruction: Instruction::LDnToHLAddress { value: data[1] },
cycles: 12,
},
&data[2..],
)
}
}
impl Processor {
@ -195,6 +210,15 @@ impl Processor {
panic!("invalid address stored in (hl): {dst_address}")
}
}
Instruction::LDnToHLAddress { value } => {
let dst_address = self.registers.get_combined_register(register::Combined::HL);
let memory_value = self.memory.set(dst_address.into(), value);
if memory_value.is_none() {
panic!("invalid address stored in (hl): {dst_address}")
}
}
}
self.num_cycles += u64::from(instruction.cycles);
@ -345,4 +369,19 @@ mod tests {
processor.run(&ins);
assert_eq!(Some(0xCC), processor.memory.get(0xCCCC));
}
#[test]
fn test_load_immediate_to_memory() {
let mut processor = Processor::default();
processor
.registers
.set_combined_register(register::Combined::HL, 0xCCDE);
let data = [0x36, 0x1D, 0x00];
let (ins, extra_data) = RunnableInstruction::from_data(&data);
assert_eq!(extra_data, &[0x00]);
processor.run(&ins);
assert_eq!(Some(0x1D), processor.memory.get(0xCCDE));
}
}