Make the CPU SB/SH tests pass.

Implemented the LH opcode.

Something isn't quite right, as not all cases were fixed (RDP hello world works, but I8RLEVideo, I8VideoDecode and a few others still aren't totally right). Also, some games still incorrectly set the User mode among other bits in the status register.
master
Nabile Rahmani 2018-12-10 19:59:20 +01:00
parent 6c5a34eaa6
commit dcf1766d73
3 changed files with 17 additions and 3 deletions

View File

@ -63,7 +63,9 @@
/// <summary>Branch On Greater Than Zero.</summary>
BGTZ = 0b000111,
/// <summary>Store Doubleword.</summary>
SD = 0b111111
SD = 0b111111,
/// <summary>Load Halfword.</summary>
LH = 0b100001
}
}
}

View File

@ -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);

View File

@ -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,