Implement load immediate to (hl)
parent
dcaf0588de
commit
e95cd263c5
39
src/run.rs
39
src/run.rs
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue