diff --git a/DotN64/CPU/VR4300/VR4300.OpCode.cs b/DotN64/CPU/VR4300/VR4300.OpCode.cs index 5f175a8..3d10ced 100644 --- a/DotN64/CPU/VR4300/VR4300.OpCode.cs +++ b/DotN64/CPU/VR4300/VR4300.OpCode.cs @@ -63,7 +63,9 @@ /// Branch On Greater Than Zero. BGTZ = 0b000111, /// Store Doubleword. - SD = 0b111111 + SD = 0b111111, + /// Load Halfword. + LH = 0b100001 } } } diff --git a/DotN64/CPU/VR4300/VR4300.cs b/DotN64/CPU/VR4300/VR4300.cs index c0a03c0..eab9a76 100644 --- a/DotN64/CPU/VR4300/VR4300.cs +++ b/DotN64/CPU/VR4300/VR4300.cs @@ -166,6 +166,7 @@ namespace DotN64.CPU [Instruction.From(OpCode.LB)] = i => Load(i, AccessSize.Byte), [Instruction.From(OpCode.BGTZ)] = i => Branch(i, (rs, rt) => rs > 0), [Instruction.From(OpCode.SD)] = i => Store(i, AccessSize.DoubleWord), + [Instruction.From(OpCode.LH)] = i => Load(i, AccessSize.HalfWord), [Instruction.From(SpecialOpCode.ADD)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RS] + (int)GPR[i.RT]), [Instruction.From(SpecialOpCode.JR)] = i => Jump(GPR[i.RS]), [Instruction.From(SpecialOpCode.SRL)] = i => GPR[i.RD] = (ulong)(int)((uint)GPR[i.RT] >> i.SA), @@ -349,10 +350,20 @@ namespace DotN64.CPU switch (size) { case AccessSize.Byte: - WriteSysAD(physicalAddress, (ReadWord(address) & ~((uint)(1 << 8) - 1)) | (byte)data); + { + physicalAddress &= ~0b11u; + var shift = ((int)address & 0b11 ^ -(int)CP0.Config.BE) << 3; + + WriteSysAD(physicalAddress, (ReadSysAD(physicalAddress) & ~(uint.MaxValue << shift)) | (uint)((byte)data << shift)); + } break; case AccessSize.HalfWord: - WriteSysAD(physicalAddress, (ReadWord(address) & ~((uint)(1 << 16) - 1)) | (ushort)data); + { + physicalAddress &= ~0b11u; + var shift = ((int)address & 0b11 ^ (-(int)CP0.Config.BE << 1)) << 3; + + WriteSysAD(physicalAddress, (ReadSysAD(physicalAddress) & ~(uint.MaxValue << shift)) | (uint)((ushort)data << shift)); + } break; case AccessSize.Word: WriteSysAD(physicalAddress, (uint)data); diff --git a/DotN64/Diagnostics/Debugger.cs b/DotN64/Diagnostics/Debugger.cs index 1b8838f..702c499 100644 --- a/DotN64/Diagnostics/Debugger.cs +++ b/DotN64/Diagnostics/Debugger.cs @@ -35,6 +35,7 @@ namespace DotN64.Diagnostics [VR4300.Instruction.From(VR4300.OpCode.LBU)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.LUI)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.LD)] = InstructionFormat.I, + [VR4300.Instruction.From(VR4300.OpCode.LH)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.LHU)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.LW)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.ORI)] = InstructionFormat.I,