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 { LDToHLAddress {
src: register::Single, 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 { struct RunnableInstruction {
@ -111,6 +115,7 @@ impl RunnableInstruction {
0x73 => Self::make_ld_to_hl_address(register::Single::E, data), 0x73 => Self::make_ld_to_hl_address(register::Single::E, data),
0x74 => Self::make_ld_to_hl_address(register::Single::H, data), 0x74 => Self::make_ld_to_hl_address(register::Single::H, data),
0x75 => Self::make_ld_to_hl_address(register::Single::L, 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}"), _ => panic!("invalid opcode {opcode:0x}"),
} }
} }
@ -161,6 +166,16 @@ impl RunnableInstruction {
&data[1..], &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 { impl Processor {
@ -195,6 +210,15 @@ impl Processor {
panic!("invalid address stored in (hl): {dst_address}") 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); self.num_cycles += u64::from(instruction.cycles);
@ -345,4 +369,19 @@ mod tests {
processor.run(&ins); processor.run(&ins);
assert_eq!(Some(0xCC), processor.memory.get(0xCCCC)); 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));
}
} }