Mesen2/UI/Interop/CpuTypeExtensions.cs
Sour 8d6830a70a SNES: Add support for ST018 coprocessor
Used by a single game: Hayazashi Nidan Morita Shougi 2
2024-12-29 23:41:52 +09:00

279 lines
7.6 KiB
C#

using System;
namespace Mesen.Interop
{
public static class CpuTypeExtensions
{
public static MemoryType ToMemoryType(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => MemoryType.SnesMemory,
CpuType.Spc => MemoryType.SpcMemory,
CpuType.NecDsp => MemoryType.NecDspMemory,
CpuType.Sa1 => MemoryType.Sa1Memory,
CpuType.Gsu => MemoryType.GsuMemory,
CpuType.Cx4 => MemoryType.Cx4Memory,
CpuType.St018 => MemoryType.St018Memory,
CpuType.Gameboy => MemoryType.GameboyMemory,
CpuType.Nes => MemoryType.NesMemory,
CpuType.Pce => MemoryType.PceMemory,
CpuType.Sms => MemoryType.SmsMemory,
CpuType.Gba => MemoryType.GbaMemory,
CpuType.Ws => MemoryType.WsMemory,
_ => throw new Exception("Invalid CPU type"),
};
}
public static MemoryType GetVramMemoryType(this CpuType cpuType, bool getExtendedRam = false)
{
return cpuType switch {
CpuType.Snes => MemoryType.SnesVideoRam,
CpuType.Gameboy => MemoryType.GbVideoRam,
CpuType.Nes => MemoryType.NesPpuMemory,
CpuType.Pce => getExtendedRam ? MemoryType.PceVideoRamVdc2 : MemoryType.PceVideoRam,
CpuType.Sms => MemoryType.SmsVideoRam,
CpuType.Gba => MemoryType.GbaVideoRam,
CpuType.Ws => MemoryType.WsWorkRam,
_ => throw new Exception("Invalid CPU type"),
};
}
public static MemoryType GetSpriteRamMemoryType(this CpuType cpuType, bool getExtendedRam = false)
{
return cpuType switch {
CpuType.Snes => MemoryType.SnesSpriteRam,
CpuType.Gameboy => MemoryType.GbSpriteRam,
CpuType.Nes => MemoryType.NesSpriteRam,
CpuType.Pce => getExtendedRam ? MemoryType.PceSpriteRamVdc2 : MemoryType.PceSpriteRam,
CpuType.Sms => MemoryType.None,
CpuType.Gba => MemoryType.GbaSpriteRam,
CpuType.Ws => MemoryType.None,
_ => throw new Exception("Invalid CPU type"),
};
}
public static MemoryType GetPrgRomMemoryType(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => MemoryType.SnesPrgRom,
CpuType.NecDsp => MemoryType.DspProgramRom,
CpuType.Sa1 => MemoryType.SnesPrgRom,
CpuType.Gsu => MemoryType.SnesPrgRom,
CpuType.Cx4 => MemoryType.SnesPrgRom,
CpuType.St018 => MemoryType.St018PrgRom,
CpuType.Gameboy => MemoryType.GbPrgRom,
CpuType.Nes => MemoryType.NesPrgRom,
CpuType.Pce => MemoryType.PcePrgRom,
CpuType.Sms => MemoryType.SmsPrgRom,
CpuType.Gba => MemoryType.GbaPrgRom,
CpuType.Ws => MemoryType.WsPrgRom,
_ => throw new Exception("Invalid CPU type"),
};
}
public static MemoryType GetSystemRamType(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => MemoryType.SnesWorkRam,
CpuType.NecDsp => MemoryType.DspDataRam,
CpuType.Sa1 => MemoryType.Sa1InternalRam,
CpuType.Gsu => MemoryType.GsuWorkRam,
CpuType.Cx4 => MemoryType.Cx4DataRam,
CpuType.St018 => MemoryType.St018WorkRam,
CpuType.Gameboy => MemoryType.GbWorkRam,
CpuType.Nes => MemoryType.NesInternalRam,
CpuType.Pce => MemoryType.PceWorkRam,
CpuType.Sms => MemoryType.SmsWorkRam,
CpuType.Gba => MemoryType.GbaIntWorkRam,
CpuType.Ws => MemoryType.WsWorkRam,
_ => throw new Exception("Invalid CPU type"),
};
}
public static int GetAddressSize(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => 6,
CpuType.Spc => 4,
CpuType.NecDsp => 4,
CpuType.Sa1 => 6,
CpuType.Gsu => 6,
CpuType.Cx4 => 6,
CpuType.St018 => 8,
CpuType.Gameboy => 4,
CpuType.Nes => 4,
CpuType.Pce => 4,
CpuType.Sms => 4,
CpuType.Gba => 7,
CpuType.Ws => 5,
_ => throw new Exception("Invalid CPU type"),
};
}
public static int GetByteCodeSize(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => 4,
CpuType.Spc => 3,
CpuType.NecDsp => 3,
CpuType.Sa1 => 4,
CpuType.Gsu => 3,
CpuType.Cx4 => 4,
CpuType.St018 => 4,
CpuType.Gameboy => 3,
CpuType.Nes => 3,
CpuType.Pce => 4,
CpuType.Sms => 4,
CpuType.Gba => 4,
CpuType.Ws => 4,
_ => throw new Exception("Invalid CPU type"),
};
}
public static DebuggerFlags GetDebuggerFlag(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => DebuggerFlags.SnesDebuggerEnabled,
CpuType.Spc => DebuggerFlags.SpcDebuggerEnabled,
CpuType.NecDsp => DebuggerFlags.NecDspDebuggerEnabled,
CpuType.Sa1 => DebuggerFlags.Sa1DebuggerEnabled,
CpuType.Gsu => DebuggerFlags.GsuDebuggerEnabled,
CpuType.Cx4 => DebuggerFlags.Cx4DebuggerEnabled,
CpuType.St018 => DebuggerFlags.St018DebuggerEnabled,
CpuType.Gameboy => DebuggerFlags.GbDebuggerEnabled,
CpuType.Nes => DebuggerFlags.NesDebuggerEnabled,
CpuType.Pce => DebuggerFlags.PceDebuggerEnabled,
CpuType.Sms => DebuggerFlags.SmsDebuggerEnabled,
CpuType.Gba => DebuggerFlags.GbaDebuggerEnabled,
CpuType.Ws => DebuggerFlags.WsDebuggerEnabled,
_ => throw new Exception("Invalid CPU type"),
};
}
public static ConsoleType GetConsoleType(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => ConsoleType.Snes,
CpuType.Spc => ConsoleType.Snes,
CpuType.NecDsp => ConsoleType.Snes,
CpuType.Sa1 => ConsoleType.Snes,
CpuType.Gsu => ConsoleType.Snes,
CpuType.Cx4 => ConsoleType.Snes,
CpuType.St018 => ConsoleType.Snes,
CpuType.Gameboy => ConsoleType.Gameboy,
CpuType.Nes => ConsoleType.Nes,
CpuType.Pce => ConsoleType.PcEngine,
CpuType.Sms => ConsoleType.Sms,
CpuType.Gba => ConsoleType.Gba,
CpuType.Ws => ConsoleType.Ws,
_ => throw new Exception("Invalid CPU type"),
};
}
public static bool SupportsAssembler(this CpuType cpuType)
{
switch(cpuType) {
case CpuType.Snes:
case CpuType.Gameboy:
case CpuType.Nes:
case CpuType.Pce:
case CpuType.Sms:
return true;
default:
return false;
};
}
public static bool SupportsFunctionList(this CpuType cpuType)
{
switch(cpuType) {
case CpuType.Snes:
case CpuType.Sa1:
case CpuType.Gameboy:
case CpuType.Nes:
case CpuType.Pce:
case CpuType.Sms:
case CpuType.Gba:
case CpuType.Ws:
return true;
default:
return false;
};
}
public static bool SupportsCallStack(this CpuType cpuType)
{
switch(cpuType) {
case CpuType.Gsu:
return false;
default:
return true;
};
}
public static bool SupportsMemoryMappings(this CpuType cpuType)
{
switch(cpuType) {
case CpuType.Gameboy:
case CpuType.Nes:
case CpuType.Pce:
case CpuType.Sms:
case CpuType.Ws:
return true;
default:
return false;
};
}
public static bool HasDummyOperations(this CpuType cpuType)
{
switch(cpuType) {
case CpuType.Spc:
case CpuType.Nes:
case CpuType.Pce:
return true;
default:
return false;
};
}
public static byte GetNopOpCode(this CpuType cpuType)
{
return cpuType switch {
CpuType.Snes => 0xEA,
CpuType.Gameboy => 0x00,
CpuType.Nes => 0xEA,
CpuType.Pce => 0xEA,
CpuType.Sms => 0x00,
//TODOGBA - assembler support
CpuType.Ws => 0x90,
_ => throw new Exception("Invalid CPU type"),
};
}
public static bool CanAccessMemoryType(this CpuType cpuType, MemoryType memType)
{
switch(memType) {
case MemoryType.None:
return false;
case MemoryType.SnesPrgRom:
return cpuType == CpuType.Snes || cpuType == CpuType.Sa1 || cpuType == CpuType.Gsu || cpuType == CpuType.Cx4;
case MemoryType.SnesSaveRam:
return cpuType == CpuType.Snes || cpuType == CpuType.Sa1 || cpuType == CpuType.Cx4;
default:
//All other types are specific to a single CPU type
return memType.ToCpuType() == cpuType;
}
}
}
}