diff --git a/src/run.rs b/src/run.rs index dae5297..2986798 100644 --- a/src/run.rs +++ b/src/run.rs @@ -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)); + } }