Handle cartridge swap events by updating the memory map. Reduces branching and calls.

master
Nabile Rahmani 2018-06-27 16:08:45 +02:00
parent 599130bf38
commit 34dfe21c05
4 changed files with 55 additions and 9 deletions

View File

@ -13,7 +13,7 @@ namespace DotN64
#endregion
#region Properties
public byte[] ROM { get; set; }
public byte[] ROM { get; }
public uint ClockRate => BitHelper.FromBigEndian(BitConverter.ToUInt32(ROM, 0x04));
@ -38,15 +38,19 @@ namespace DotN64
public byte Version => ROM[0x3F];
#endregion
#region Constructors
public Cartridge(byte[] rom)
{
ROM = rom;
}
#endregion
#region Methods
public static Cartridge FromFile(FileInfo file)
{
using (var reader = new BinaryReader(file.OpenRead()))
{
return new Cartridge
{
ROM = reader.ReadBytes((int)reader.BaseStream.Length)
};
return new Cartridge(reader.ReadBytes((int)reader.BaseStream.Length));
}
}
#endregion

View File

@ -46,6 +46,9 @@ namespace DotN64.Helpers
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ToBigEndian(uint value) => (uint)IPAddress.HostToNetworkOrder((int)value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ReadOpenBus(uint address) => (uint)(address & ~((1 << 16) - 1) | address >> 16);
#endregion
}
}

View File

@ -17,7 +17,23 @@ namespace DotN64
public PeripheralInterface PIF { get; }
public Cartridge Cartridge { get; set; }
private Cartridge cartridge;
public Cartridge Cartridge
{
get => cartridge;
set
{
if (Cartridge == value)
return;
cartridge = value;
CartridgeSwapped?.Invoke(this, value);
}
}
#endregion
#region Events
public event Action<Nintendo64, Cartridge> CartridgeSwapped;
#endregion
#region Constructors

View File

@ -9,7 +9,14 @@ namespace DotN64.RCP
{
public partial class ParallelInterface : Interface
{
#region Fields
private readonly MappingEntry[] memoryMaps;
private readonly int cartridgeMapIndex;
#endregion
#region Properties
private ref MappingEntry CartridgeMap => ref memoryMaps[cartridgeMapIndex];
public Statuses Status { get; set; }
public Domain[] Domains { get; } = new[]
@ -38,7 +45,8 @@ namespace DotN64.RCP
public ParallelInterface(RealityCoprocessor rcp)
: base(rcp)
{
MemoryMaps = new[]
MappingEntry cartridgeMap;
MemoryMaps = memoryMaps = new[]
{
new MappingEntry(0x04600010, 0x04600013) // PI status.
{
@ -94,9 +102,24 @@ namespace DotN64.RCP
rcp.MI.Interrupt |= MIPSInterface.Interrupts.PI;
}
},
new MappingEntry(0x10000000, 0x1FBFFFFF) // Cartridge Domain 1 Address 2.
cartridgeMap = new MappingEntry(0x10000000, 0x1FBFFFFF, false) // Cartridge Domain 1 Address 2.
{
Read = o => BitHelper.FromBigEndian(BitConverter.ToUInt32(rcp.nintendo64.Cartridge.ROM, (int)o))
Read = BitHelper.ReadOpenBus
}
};
cartridgeMapIndex = Array.IndexOf(memoryMaps, cartridgeMap);
rcp.nintendo64.CartridgeSwapped += (n, c) =>
{
if (c != null)
{
var rom = c.ROM;
CartridgeMap.OffsetAddress = true;
CartridgeMap.Read = o => BitHelper.FromBigEndian(BitConverter.ToUInt32(rom, (int)o));
}
else
{
CartridgeMap.OffsetAddress = false;
CartridgeMap.Read = BitHelper.ReadOpenBus;
}
};
}