From 48924bdfba1ff6ada0e1e9356ffa84a257e9a603 Mon Sep 17 00:00:00 2001 From: Nabile Rahmani Date: Thu, 29 Nov 2018 04:39:23 +0100 Subject: [PATCH] Handle endianness on sub-word CPU reads (fixes garbled text on test ROMs). - Added SD opcode for running some test ROMs. - Quit the debugger when the N64 is powered off. --- DotN64/CPU/VR4300/VR4300.OpCode.cs | 4 +++- DotN64/CPU/VR4300/VR4300.cs | 7 +++++-- DotN64/Diagnostics/Debugger.cs | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/DotN64/CPU/VR4300/VR4300.OpCode.cs b/DotN64/CPU/VR4300/VR4300.OpCode.cs index 7b1f672..5f175a8 100644 --- a/DotN64/CPU/VR4300/VR4300.OpCode.cs +++ b/DotN64/CPU/VR4300/VR4300.OpCode.cs @@ -61,7 +61,9 @@ /// Load Byte. LB = 0b100000, /// Branch On Greater Than Zero. - BGTZ = 0b000111 + BGTZ = 0b000111, + /// Store Doubleword. + SD = 0b111111 } } } diff --git a/DotN64/CPU/VR4300/VR4300.cs b/DotN64/CPU/VR4300/VR4300.cs index 51257b1..c0a03c0 100644 --- a/DotN64/CPU/VR4300/VR4300.cs +++ b/DotN64/CPU/VR4300/VR4300.cs @@ -165,6 +165,7 @@ namespace DotN64.CPU [Instruction.From(OpCode.J)] = i => Jump((PC & ~((ulong)(1 << 28) - 1)) | (i.Target << 2)), [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(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), @@ -326,9 +327,11 @@ namespace DotN64.CPU switch (size) { case AccessSize.Byte: - return (byte)ReadSysAD(physicalAddress); + physicalAddress &= ~0b11u; + return (byte)(ReadSysAD(physicalAddress) >> (((int)address & 0b11 ^ -(int)CP0.Config.BE) << 3)); case AccessSize.HalfWord: - return (ushort)ReadSysAD(physicalAddress); + physicalAddress &= ~0b11u; + return (ushort)(ReadSysAD(physicalAddress) >> (((int)address & 0b11 ^ (-(int)CP0.Config.BE << 1)) << 3)); case AccessSize.Word: return ReadSysAD(physicalAddress); case AccessSize.DoubleWord: diff --git a/DotN64/Diagnostics/Debugger.cs b/DotN64/Diagnostics/Debugger.cs index d16f8fa..1b8838f 100644 --- a/DotN64/Diagnostics/Debugger.cs +++ b/DotN64/Diagnostics/Debugger.cs @@ -39,6 +39,7 @@ namespace DotN64.Diagnostics [VR4300.Instruction.From(VR4300.OpCode.LW)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.ORI)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.SB)] = InstructionFormat.I, + [VR4300.Instruction.From(VR4300.OpCode.SD)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.SH)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.SLTI)] = InstructionFormat.I, [VR4300.Instruction.From(VR4300.OpCode.SLTIU)] = InstructionFormat.I, @@ -296,7 +297,7 @@ namespace DotN64.Diagnostics { DebuggerStatus = debug ? Status.Debugging : Status.Running; - while (DebuggerStatus != Status.Stopped) + while (DebuggerStatus != Status.Stopped && nintendo64.Power == Switch.On) { switch (DebuggerStatus) {