mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-07-08 18:06:41 +00:00
Add NES cart printing
This commit is contained in:
185
SabreTools.Serialization/Extensions/NESCart.cs
Normal file
185
SabreTools.Serialization/Extensions/NESCart.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using SabreTools.Data.Models.NES;
|
||||
|
||||
namespace SabreTools.Data.Extensions
|
||||
{
|
||||
public static class NESCart
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert a <see cref="CPUPPUTiming"/> value to string
|
||||
/// </summary>
|
||||
public static string FromCPUPPUTiming(this CPUPPUTiming timing)
|
||||
{
|
||||
return timing switch
|
||||
{
|
||||
CPUPPUTiming.RP2C02 => "RP2C02 (NTSC NES)",
|
||||
CPUPPUTiming.RP2C07 => "RP2C07 (Licensed PAL NES)",
|
||||
CPUPPUTiming.MultipleRegion => "Multiple-region",
|
||||
CPUPPUTiming.UA6538 => "UA6538 (Dendy)",
|
||||
_ => $"Unknown {(byte)timing}",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="DefaultExpansionDevice"/> value to string
|
||||
/// </summary>
|
||||
public static string FromDefaultExpansionDevice(this DefaultExpansionDevice device)
|
||||
{
|
||||
return device switch
|
||||
{
|
||||
DefaultExpansionDevice.Unspecified => "Unspecified",
|
||||
DefaultExpansionDevice.StandardControllers => "Standard NES/Famicom controllers",
|
||||
DefaultExpansionDevice.NESFourScore => "NES Four Score/Satellite with two additional standard controllers",
|
||||
DefaultExpansionDevice.FamicomFourPlayersAdapter => "Famicom Four Players Adapter with two additional standard controllers using the 'simple' protocol",
|
||||
DefaultExpansionDevice.VsSystem4016 => "Vs. System (1P via $4016)",
|
||||
DefaultExpansionDevice.VsSystem4017 => "Vs. System (1P via $4017)",
|
||||
DefaultExpansionDevice.Reserved06 => "Reserved (0x06)",
|
||||
DefaultExpansionDevice.VsZapper => "Vs. Zapper",
|
||||
DefaultExpansionDevice.Zapper4017 => "Zapper ($4017)",
|
||||
DefaultExpansionDevice.TwoZappers => "Two Zappers",
|
||||
DefaultExpansionDevice.BandaiHyperShotLightgun => "Bandai Hyper Shot Lightgun",
|
||||
DefaultExpansionDevice.PowerPadSideA => "Power Pad Side A",
|
||||
DefaultExpansionDevice.PowerPadSideB => "Power Pad Side B",
|
||||
DefaultExpansionDevice.FamilyTrainerSideA => "Family Trainer Side A",
|
||||
DefaultExpansionDevice.FamilyTrainerSideB => "Family Trainer Side B",
|
||||
DefaultExpansionDevice.ArkanoidVausControllerNES => "Arkanoid Vaus Controller (NES)",
|
||||
DefaultExpansionDevice.ArkanoidVausControllerFamicom => "Arkanoid Vaus Controller (Famicom)",
|
||||
DefaultExpansionDevice.TwoVausControllersPlusFamicomDataRecorder => "Two Vaus Controllers plus Famicom Data Recorder",
|
||||
DefaultExpansionDevice.KonamiHyperShotController => "Konami Hyper Shot Controller",
|
||||
DefaultExpansionDevice.CoconutsPachinkoController => "Coconuts Pachinko Controller",
|
||||
DefaultExpansionDevice.ExcitingBoxingPunchingBag => "Exciting Boxing Punching Bag (Blowup Doll)",
|
||||
DefaultExpansionDevice.JissenMahjongController => "Jissen Mahjong Controller",
|
||||
DefaultExpansionDevice.YonezawaPartyTap => "米澤 (Yonezawa) Party Tap",
|
||||
DefaultExpansionDevice.OekaKidsTablet => "Oeka Kids Tablet",
|
||||
DefaultExpansionDevice.SunsoftBarcodeBattler => "Sunsoft Barcode Battler",
|
||||
DefaultExpansionDevice.MiraclePianoKeyboard => "Miracle Piano Keyboard",
|
||||
DefaultExpansionDevice.PokkunMoguraaTapTapMat => "Pokkun Moguraa Tap-tap Mat (Whack-a-Mole Mat and Mallet)",
|
||||
DefaultExpansionDevice.TopRider => "Top Rider (Inflatable Bicycle)",
|
||||
DefaultExpansionDevice.DoubleFisted => "Double-Fisted (Requires or allows use of two controllers by one player)",
|
||||
DefaultExpansionDevice.Famicom3DSystem => "Famicom 3D System",
|
||||
DefaultExpansionDevice.DoremikkoKeyboard => "Doremikko Keyboard",
|
||||
DefaultExpansionDevice.ROBGyromite => "R.O.B. Gyromite",
|
||||
DefaultExpansionDevice.FamicomDataRecorder => "Famicom Data Recorder ('silent' keyboard)",
|
||||
DefaultExpansionDevice.ASCIITurboFile => "ASCII Turbo File",
|
||||
DefaultExpansionDevice.IGSStorageBattleBox => "IGS Storage Battle Box",
|
||||
DefaultExpansionDevice.FamilyBASICKeyboardPlusFamicomDataRecorder => "Family BASIC Keyboard plus Famicom Data Recorder",
|
||||
DefaultExpansionDevice.DongdaPECKeyboard => "东达 (Dōngdá) PEC Keyboard",
|
||||
DefaultExpansionDevice.BitCorpBit79Keyboard => "普澤 (Pǔzé, a.k.a. Bit Corp.) Bit-79 Keyboard",
|
||||
DefaultExpansionDevice.SuborKeyboard => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusMacroWinnersMouse => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Macro Winners Mouse",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4016 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4016",
|
||||
DefaultExpansionDevice.SNESMouse4016 => "SNES Mouse ($4016)",
|
||||
DefaultExpansionDevice.Multicart => "Multicart",
|
||||
DefaultExpansionDevice.TwoSNESControllers => "Two SNES controllers replacing the two standard NES controllers",
|
||||
DefaultExpansionDevice.RacerMateBicycle => "RacerMate Bicycle",
|
||||
DefaultExpansionDevice.UForce => "U-Force",
|
||||
DefaultExpansionDevice.ROBStackUp => "R.O.B. Stack-Up",
|
||||
DefaultExpansionDevice.CityPatrolmanLightgun => "City Patrolman Lightgun",
|
||||
DefaultExpansionDevice.SharpC1CassetteInterface => "Sharp C1 Cassette Interface",
|
||||
DefaultExpansionDevice.StandardControllerWithSwappedInputs => "Standard Controller with swapped Left-Right/Up-Down/B-A",
|
||||
DefaultExpansionDevice.ExcaliburSudokuPad => "Excalibur Sudoku Pad",
|
||||
DefaultExpansionDevice.ABLPinball => "ABL Pinball",
|
||||
DefaultExpansionDevice.GoldenNuggetCasinoExtraButtons => "Golden Nugget Casino extra buttons",
|
||||
DefaultExpansionDevice.KedaKeyboard => "科达 (Kēdá) Keyboard",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4017",
|
||||
DefaultExpansionDevice.PortTestController => "Port test controller",
|
||||
DefaultExpansionDevice.BandaiMultiGamePlayerGamepad => "Bandai Multi Game Player Gamepad buttons",
|
||||
DefaultExpansionDevice.VenomTVDanceMat => "Venom TV Dance Mat",
|
||||
DefaultExpansionDevice.LGTVRemoteControl => "LG TV Remote Control",
|
||||
DefaultExpansionDevice.FamicomNetworkController => "Famicom Network Controller",
|
||||
DefaultExpansionDevice.KingFishingController => "King Fishing Controller",
|
||||
DefaultExpansionDevice.CroakyKaraokeController => "Croaky Karaoke Controller",
|
||||
DefaultExpansionDevice.KingwonKeyboard => "科王 (Kēwáng, a.k.a. Kingwon) Keyboard",
|
||||
DefaultExpansionDevice.ZechengKeyboard => "泽诚 (Zéchéng) Keyboard",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusL90RotatedPS2Mouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus L90-rotated PS/2 mouse in $4017",
|
||||
DefaultExpansionDevice.PS2KeyboardInUM6578PS2PortPS2Mouse4017 => "PS/2 Keyboard in UM6578 PS/2 port, PS/2 Mouse via $4017",
|
||||
DefaultExpansionDevice.PS2MouseInUM6578PS2Port => "PS/2 Mouse in UM6578 PS/2 port",
|
||||
DefaultExpansionDevice.YuxingMouse4016 => "裕兴 (Yùxìng) Mouse via $4016",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusYuxingMouse4016 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus 裕兴 (Yùxìng) Mouse mouse in $4016",
|
||||
DefaultExpansionDevice.GigggleTVPump => "Gigggle TV Pump",
|
||||
DefaultExpansionDevice.BBKKeyboardPlusR90RotatedPS2Mouse4017 => "步步高 (Bùbùgāo, a.k.a. BBK) Keyboard plus R90-rotated PS/2 mouse in $4017",
|
||||
DefaultExpansionDevice.MagicalCooking => "Magical Cooking",
|
||||
DefaultExpansionDevice.SNESMouse4017 => "SNES Mouse ($4017)",
|
||||
DefaultExpansionDevice.Zapper4016 => "Zapper ($4016)",
|
||||
DefaultExpansionDevice.ArkanoidVausControllerPrototype => "Arkanoid Vaus Controller (Prototype)",
|
||||
DefaultExpansionDevice.TVMahjongGameController => "TV 麻雀 Game (TV Mahjong Game) Controller",
|
||||
DefaultExpansionDevice.MahjongGekitouDensetsuController => "麻雀激闘伝説 (Mahjong Gekitou Densetsu) Controller",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusXInvertedPS2Mouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus X-inverted PS/2 mouse in $4017",
|
||||
DefaultExpansionDevice.IBMPCXTKeyboard => "IBM PC/XT Keyboard",
|
||||
DefaultExpansionDevice.SuborKeyboardPlusMegaBookMouse => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Mega Book Mouse",
|
||||
_ => $"Unknown {(byte)device}",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="ExtendedConsoleType"/> value to string
|
||||
/// </summary>
|
||||
public static string FromExtendedConsoleType(this ExtendedConsoleType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ExtendedConsoleType.RegularSystem => "Regular NES/Famicom/Dendy",
|
||||
ExtendedConsoleType.NintendoVsSystem => "Nintendo Vs. System",
|
||||
ExtendedConsoleType.Playchoice10 => "Playchoice 10",
|
||||
ExtendedConsoleType.RegularFamicloneDecimalMode => "Regular Famiclone, but with CPU that supports Decimal Mode",
|
||||
ExtendedConsoleType.RegularNESWithEPSM => "Regular NES/Famicom with EPSM module or plug-through cartridge",
|
||||
ExtendedConsoleType.VRTechnologyVT01 => "V.R. Technology VT01 with red/cyan STN palette",
|
||||
ExtendedConsoleType.VRTechnologyVT02 => "V.R. Technology VT02",
|
||||
ExtendedConsoleType.VRTechnologyVT03 => "V.R. Technology VT03",
|
||||
ExtendedConsoleType.VRTechnologyVT09 => "V.R. Technology VT09",
|
||||
ExtendedConsoleType.VRTechnologyVT32 => "V.R. Technology VT32",
|
||||
ExtendedConsoleType.VRTechnologyVT369 => "V.R. Technology VT369",
|
||||
ExtendedConsoleType.UMCUM6578 => "UMC UM6578",
|
||||
ExtendedConsoleType.FamicomNetworkSystem => "Famicom Network System",
|
||||
ExtendedConsoleType.ReservedD => "Reserved (0x0D)",
|
||||
ExtendedConsoleType.ReservedE => "Reserved (0x0E)",
|
||||
ExtendedConsoleType.ReservedF => "Reserved (0x0F)",
|
||||
_ => $"Unknown {(byte)type}",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="VsHardwareType"/> value to string
|
||||
/// </summary>
|
||||
public static string FromVsHardwareType(this VsHardwareType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
VsHardwareType.VsUnisystem => "Vs. Unisystem (normal)",
|
||||
VsHardwareType.VsUnisystemRBIBaseballProtection => "Vs. Unisystem (RBI Baseball protection)",
|
||||
VsHardwareType.VsUnisystemTKOBoxingProtection => "Vs. Unisystem (TKO Boxing protection)",
|
||||
VsHardwareType.VsUnisystemSuperXeviousProtection => "Vs. Unisystem (Super Xevious protection)",
|
||||
VsHardwareType.VsUnisystemVsIceClimberJapanProtection => "Vs. Unisystem (Vs. Ice Climber Japan protection)",
|
||||
VsHardwareType.VsDualSystem => "Vs. Dual System (normal)",
|
||||
VsHardwareType.VsDualSystemRaidOnBungelingBayProtection => "Vs. Dual System (Raid on Bungeling Bay protection)",
|
||||
_ => $"Unknown {(byte)type}",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="VsSystemType"/> value to string
|
||||
/// </summary>
|
||||
public static string FromVsSystemType(this VsSystemType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
VsSystemType.AnyRP2C03RC2C03Variant => "Any RP2C03/RC2C03 variant",
|
||||
VsSystemType.Reserved1 => "Reserved (0x01)",
|
||||
VsSystemType.RP2C040001 => "RP2C04-0001",
|
||||
VsSystemType.RP2C040002 => "RP2C04-0002",
|
||||
VsSystemType.RP2C040003 => "RP2C04-0003",
|
||||
VsSystemType.RP2C040004 => "RP2C04-0004",
|
||||
VsSystemType.Reserved6 => "Reserved (0x06)",
|
||||
VsSystemType.Reserved7 => "Reserved (0x07)",
|
||||
VsSystemType.RC2C0501 => "RC2C05-01 (signature unknown)",
|
||||
VsSystemType.RC2C0502 => "RC2C05-02 ($2002 AND $3F =$3D)",
|
||||
VsSystemType.RC2C0503 => "RC2C05-03 ($2002 AND $1F =$1C)",
|
||||
VsSystemType.RC2C0504 => "RC2C05-04 ($2002 AND $1F =$1B)",
|
||||
VsSystemType.ReservedC => "Reserved (0x0C)",
|
||||
VsSystemType.ReservedD => "Reserved (0x0D)",
|
||||
VsSystemType.ReservedE => "Reserved (0x0E)",
|
||||
VsSystemType.ReservedF => "Reserved (0x0F)",
|
||||
_ => $"Unknown {(byte)type}",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,42 +164,35 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// CPU/PPU Timing
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum CPUPPUTiming : byte
|
||||
{
|
||||
#region Bits 0-1
|
||||
|
||||
/// <summary>
|
||||
/// NTSC NES
|
||||
/// </summary>
|
||||
RP2C02 = 0b00000000,
|
||||
RP2C02 = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Licensed PAL NES
|
||||
/// </summary>
|
||||
RP2C07 = 0b00000001,
|
||||
RP2C07 = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Multiple-region
|
||||
/// </summary>
|
||||
MultipleRegion = 0b00000010,
|
||||
MultipleRegion = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Dendy
|
||||
/// </summary>
|
||||
UA6538 = 0b00000011,
|
||||
|
||||
#endregion
|
||||
UA6538 = 0x03,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vs. System Type and Extended Console Type
|
||||
/// Vs. System Type
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ExtendedSystemType : byte
|
||||
/// <remarks>Actually only 4 bits</remarks>
|
||||
public enum VsSystemType : byte
|
||||
{
|
||||
#region Bits 0-3 (Vs. System Type)
|
||||
|
||||
/// <summary>
|
||||
/// Any RP2C03/RC2C03 variant
|
||||
/// </summary>
|
||||
@@ -208,7 +201,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReserved1 = 0x01,
|
||||
Reserved1 = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// RP2C04-0001
|
||||
@@ -238,7 +231,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReserved7 = 0x07,
|
||||
Reserved7 = 0x07,
|
||||
|
||||
/// <summary>
|
||||
/// RC2C05-01 (signature unknown)
|
||||
@@ -263,27 +256,30 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReservedC = 0x0C,
|
||||
ReservedC = 0x0C,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReservedD = 0x0D,
|
||||
ReservedD = 0x0D,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReservedE = 0x0E,
|
||||
ReservedE = 0x0E,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
VsReservedF = 0x0F,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bits 4-7 (Vs. System Type)
|
||||
ReservedF = 0x0F,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Hardware Type
|
||||
/// </summary>
|
||||
/// <remarks>Actually only 4 bits</remarks>
|
||||
public enum VsHardwareType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Vs. Unisystem (normal)
|
||||
/// </summary>
|
||||
@@ -292,37 +288,39 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Vs. Unisystem (RBI Baseball protection)
|
||||
/// </summary>
|
||||
VsUnisystemRBIBaseballProtection = 0x10,
|
||||
VsUnisystemRBIBaseballProtection = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Unisystem (TKO Boxing protection)
|
||||
/// </summary>
|
||||
VsUnisystemTKOBoxingProtection = 0x20,
|
||||
VsUnisystemTKOBoxingProtection = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Unisystem (Super Xevious protection)
|
||||
/// </summary>
|
||||
VsUnisystemSuperXeviousProtection = 0x30,
|
||||
VsUnisystemSuperXeviousProtection = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Unisystem (Vs. Ice Climber Japan protection)
|
||||
/// </summary>
|
||||
VsUnisystemVsIceClimberJapanProtection = 0x40,
|
||||
VsUnisystemVsIceClimberJapanProtection = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Dual System (normal)
|
||||
/// </summary>
|
||||
VsDualSystem = 0x50,
|
||||
VsDualSystem = 0x05,
|
||||
|
||||
/// <summary>
|
||||
/// Vs. Dual System (Raid on Bungeling Bay protection)
|
||||
/// </summary>
|
||||
VsDualSystemRaidOnBungelingBayProtection = 0x60,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bits 0-3 (Extended Console Type)
|
||||
VsDualSystemRaidOnBungelingBayProtection = 0x06,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extended Console Type
|
||||
/// </summary>
|
||||
public enum ExtendedConsoleType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Regular NES/Famicom/Dendy
|
||||
/// </summary>
|
||||
@@ -391,19 +389,17 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
ExtendedConsoleReservedD = 0x0D,
|
||||
ReservedD = 0x0D,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
ExtendedConsoleReservedE = 0x0E,
|
||||
ReservedE = 0x0E,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
ExtendedConsoleReservedF = 0x0F,
|
||||
|
||||
#endregion
|
||||
ReservedF = 0x0F,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -500,7 +496,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Two Vaus Controllers plus Famicom Data Recorder
|
||||
/// </summary>
|
||||
TwoVausControllers = 0x11,
|
||||
TwoVausControllersPlusFamicomDataRecorder = 0x11,
|
||||
|
||||
/// <summary>
|
||||
/// Konami Hyper Shot Controller
|
||||
@@ -590,7 +586,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// Family BASIC Keyboard plus Famicom Data Recorder
|
||||
/// </summary>
|
||||
FamilyBASICKeyboard = 0x23,
|
||||
FamilyBASICKeyboardPlusFamicomDataRecorder = 0x23,
|
||||
|
||||
/// <summary>
|
||||
/// 东达 (Dōngdá) PEC Keyboard
|
||||
@@ -740,7 +736,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// PS/2 Keyboard in UM6578 PS/2 port, PS/2 Mouse via $4017
|
||||
/// </summary>
|
||||
PS2KeyboardInUM6578PS2Port = 0x41,
|
||||
PS2KeyboardInUM6578PS2PortPS2Mouse4017 = 0x41,
|
||||
|
||||
/// <summary>
|
||||
/// PS/2 Mouse in UM6578 PS/2 port
|
||||
@@ -750,13 +746,13 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// 裕兴 (Yùxìng) Mouse via $4016
|
||||
/// </summary>
|
||||
YuxingMouse = 0x43,
|
||||
YuxingMouse4016 = 0x43,
|
||||
|
||||
/// <summary>
|
||||
/// 小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus 裕兴 (Yùxìng)
|
||||
/// Mouse mouse in $4016
|
||||
/// </summary>
|
||||
SuborKeyboardPlusYuxingMouse = 0x44,
|
||||
SuborKeyboardPlusYuxingMouse4016 = 0x44,
|
||||
|
||||
/// <summary>
|
||||
/// Gigggle TV Pump
|
||||
@@ -766,7 +762,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// 步步高 (Bùbùgāo, a.k.a. BBK) Keyboard plus R90-rotated PS/2 mouse in $4017
|
||||
/// </summary>
|
||||
BBKKeyboardPlusR90RotatedPS2Mouse = 0x46,
|
||||
BBKKeyboardPlusR90RotatedPS2Mouse4017 = 0x46,
|
||||
|
||||
/// <summary>
|
||||
/// Magical Cooking
|
||||
@@ -801,7 +797,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// <summary>
|
||||
/// 小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus X-inverted PS/2 mouse in $4017
|
||||
/// </summary>
|
||||
SuborKeyboardPlusXInvertedPS2Mouse = 0x4D,
|
||||
SuborKeyboardPlusXInvertedPS2Mouse4017 = 0x4D,
|
||||
|
||||
/// <summary>
|
||||
/// IBM PC/XT Keyboard
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace SabreTools.Data.Models.NES
|
||||
/// When Byte 7 AND 3 =1: Vs. System Type
|
||||
/// When Byte 7 AND 3 =3: Extended Console Type
|
||||
/// </remarks>
|
||||
public ExtendedSystemType ExtendedSystemType { get; set; }
|
||||
public byte ExtendedSystemType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of miscellaneous ROMs present
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace SabreTools.Serialization.Readers
|
||||
obj.PRGRAMEEPROMSize = data.ReadByteValue();
|
||||
obj.CHRRAMSize = data.ReadByteValue();
|
||||
obj.CPUPPUTiming = (CPUPPUTiming)data.ReadByteValue();
|
||||
obj.ExtendedSystemType = (ExtendedSystemType)data.ReadByteValue();
|
||||
obj.ExtendedSystemType = data.ReadByteValue();
|
||||
obj.MiscellaneousROMs = data.ReadByteValue();
|
||||
obj.DefaultExpansionDevice = (DefaultExpansionDevice)data.ReadByteValue();
|
||||
|
||||
|
||||
284
SabreTools.Serialization/Wrappers/NESCart.Printing.cs
Normal file
284
SabreTools.Serialization/Wrappers/NESCart.Printing.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
using System.Text;
|
||||
using SabreTools.Data.Extensions;
|
||||
using SabreTools.Data.Models.NES;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public partial class NESCart : IPrintable
|
||||
{
|
||||
#if NETCOREAPP
|
||||
/// <inheritdoc/>
|
||||
public string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(Model, _jsonSerializerOptions);
|
||||
#endif
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PrintInformation(StringBuilder builder)
|
||||
{
|
||||
builder.AppendLine("Nintendo Entertainment System Cart Information:");
|
||||
builder.AppendLine("-------------------------");
|
||||
builder.AppendLine();
|
||||
|
||||
Print(builder, Model.Header);
|
||||
|
||||
builder.AppendLine(Model.Trainer, "Trainer Data");
|
||||
builder.AppendLine(Model.PRGROMData, "PRG-ROM Data");
|
||||
builder.AppendLine(Model.CHRROMData, "CHR-ROM Data");
|
||||
builder.AppendLine(Model.PlayChoiceINSTROM, "PlayChoice INST-ROM Data");
|
||||
builder.AppendLine(Model.PlayChoicePROM, "PlayChoice PROM Data");
|
||||
builder.AppendLine(Model.Title, "Title:");
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, Header? header)
|
||||
{
|
||||
builder.AppendLine(" Header Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (header is null)
|
||||
{
|
||||
builder.AppendLine(" No header present");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
|
||||
builder.AppendLine(header.IdentificationString, " Identification string");
|
||||
builder.AppendLine(header.PRGROMSize, " PRG-ROM size in 16KiB units");
|
||||
builder.AppendLine(header.CHRROMSize, " CHR-ROM size in 8KiB units");
|
||||
|
||||
#region Flag 6
|
||||
|
||||
builder.AppendLine(" Flag 6:");
|
||||
|
||||
// Bit 0
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag6 & Flag6.NametableArrangementHorizontal) != 0)
|
||||
#else
|
||||
if (header.Flag6.HasFlag(Flag6.NametableArrangementHorizontal))
|
||||
#endif
|
||||
builder.AppendLine(" Nametable Arrangement: Horizontal");
|
||||
else
|
||||
builder.AppendLine(" Nametable Arrangement: Vertical");
|
||||
|
||||
// Bit 1
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag6 & Flag6.BatteryBackedPRGRAMPresent) != 0)
|
||||
#else
|
||||
if (header.Flag6.HasFlag(Flag6.BatteryBackedPRGRAMPresent))
|
||||
#endif
|
||||
builder.AppendLine(" Battery-Backed PRG RAM: Present");
|
||||
else
|
||||
builder.AppendLine(" Battery-Backed PRG RAM: Not present");
|
||||
|
||||
// Bit 2
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag6 & Flag6.TrainerPresent) != 0)
|
||||
#else
|
||||
if (header.Flag6.HasFlag(Flag6.TrainerPresent))
|
||||
#endif
|
||||
builder.AppendLine(" Trainer: Present");
|
||||
else
|
||||
builder.AppendLine(" Trainer: Not present");
|
||||
|
||||
// Bit 3
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag6 & Flag6.AlternativeNametableLayout) != 0)
|
||||
#else
|
||||
if (header.Flag6.HasFlag(Flag6.AlternativeNametableLayout))
|
||||
#endif
|
||||
builder.AppendLine(" Alternative Nametable Layout: True");
|
||||
else
|
||||
builder.AppendLine(" Alternative Nametable Layout: False");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Flag 7
|
||||
|
||||
builder.AppendLine(" Flag 7:");
|
||||
|
||||
// Bits 0-1
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag7 & Flag7.ExtendedConsoleType) != 0)
|
||||
#else
|
||||
if (header.Flag7.HasFlag(Flag7.ExtendedConsoleType))
|
||||
#endif
|
||||
builder.AppendLine(" System Type: Extended Console Type");
|
||||
#if NET20 || NET35
|
||||
else if ((header.Flag7 & Flag7.PlayChoice10) != 0)
|
||||
#else
|
||||
else if (header.Flag7.HasFlag(Flag7.PlayChoice10))
|
||||
#endif
|
||||
builder.AppendLine(" System Type: PlayChoice-10");
|
||||
#if NET20 || NET35
|
||||
else if ((header.Flag7 & Flag7.VSUnisystem) != 0)
|
||||
#else
|
||||
else if (header.Flag7.HasFlag(Flag7.VSUnisystem))
|
||||
#endif
|
||||
builder.AppendLine(" System Type: Vs. Unisystem");
|
||||
else
|
||||
builder.AppendLine(" System Type: Nintendo Entertainment System/Family Computer");
|
||||
|
||||
// Bits 2-3
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag7 & Flag7.NES20) != 0)
|
||||
#else
|
||||
if (header.Flag7.HasFlag(Flag7.NES20))
|
||||
#endif
|
||||
builder.AppendLine(" NES 2.0: True");
|
||||
else
|
||||
builder.AppendLine(" NES 2.0: False");
|
||||
|
||||
#endregion
|
||||
|
||||
byte mapperNumber = (byte)((((byte)header.Flag7 >> 4) << 4) | (byte)((byte)header.Flag6 >> 4));
|
||||
builder.AppendLine(mapperNumber, " Mapper number");
|
||||
|
||||
if (header is Header1 header1)
|
||||
{
|
||||
// Byte 8
|
||||
builder.AppendLine(header1.PRGRAMSize, prefixString: " PRG-RAM size in 8KiB units");
|
||||
|
||||
// Byte 9
|
||||
builder.AppendLine($" TV system: {header1.TVSystem} (0x{header1.TVSystem:X})");
|
||||
|
||||
// Byte 10
|
||||
#region Flag 10
|
||||
|
||||
builder.AppendLine(" Flag 10:");
|
||||
|
||||
// Bits 0-1
|
||||
#if NET20 || NET35
|
||||
if ((header1.Flag10 & Flag10.DualCompatible2) != 0)
|
||||
#else
|
||||
if (header1.Flag10.HasFlag(Flag10.DualCompatible2))
|
||||
#endif
|
||||
builder.AppendLine(" TV System: Dual-compatible");
|
||||
#if NET20 || NET35
|
||||
else if ((header1.Flag10 & Flag10.PAL) != 0)
|
||||
#else
|
||||
else if (header1.Flag10.HasFlag(Flag10.PAL))
|
||||
#endif
|
||||
builder.AppendLine(" TV System: PAL");
|
||||
#if NET20 || NET35
|
||||
else if ((header1.Flag10 & Flag10.DualCompatible1) != 0)
|
||||
#else
|
||||
else if (header1.Flag10.HasFlag(Flag10.DualCompatible1))
|
||||
#endif
|
||||
builder.AppendLine(" TV System: Dual-compatible");
|
||||
else
|
||||
builder.AppendLine(" TV System: NTSC");
|
||||
|
||||
// Bit 4
|
||||
#if NET20 || NET35
|
||||
if ((header1.Flag10 & Flag10.PRGRAMNotPresent) != 0)
|
||||
#else
|
||||
if (header1.Flag10.HasFlag(Flag10.PRGRAMNotPresent))
|
||||
#endif
|
||||
builder.AppendLine(" PRG-RAM: Not present");
|
||||
else
|
||||
builder.AppendLine(" PRG-RAM: Present");
|
||||
|
||||
// Bit 5
|
||||
#if NET20 || NET35
|
||||
if ((header1.Flag10 & Flag10.BoardHasBusConflicts) != 0)
|
||||
#else
|
||||
if (header1.Flag10.HasFlag(Flag10.BoardHasBusConflicts))
|
||||
#endif
|
||||
builder.AppendLine(" Has Bus Conflicts: True");
|
||||
else
|
||||
builder.AppendLine(" Has Bus Conflicts: False");
|
||||
|
||||
#endregion
|
||||
|
||||
// Bytes 11-15
|
||||
builder.AppendLine(header1.Padding, " Padding");
|
||||
}
|
||||
else if (header is Header2 header2)
|
||||
{
|
||||
// Byte 8
|
||||
byte mapperMsb = (byte)(header2.MapperMSBSubmapper & 0x0F);
|
||||
ushort extendedMapperNumber = (ushort)((mapperMsb << 8)
|
||||
| (byte)((((byte)header.Flag7 >> 4) << 4)
|
||||
| (byte)((byte)header.Flag6 >> 4)));
|
||||
byte submapperNumber = (byte)(header2.MapperMSBSubmapper >> 4);
|
||||
|
||||
builder.AppendLine(mapperMsb, " Mapper MSB");
|
||||
builder.AppendLine(extendedMapperNumber, " Extended mapper number");
|
||||
builder.AppendLine(submapperNumber, " Submapper number");
|
||||
|
||||
// Byte 9
|
||||
byte prgRomMsb = (byte)(header2.PRGCHRMSB & 0x0F);
|
||||
ushort extendedPrgRomSize = (ushort)((prgRomMsb << 8) | header.PRGROMSize);
|
||||
byte chrRomMsb = (byte)(header2.PRGCHRMSB >> 4);
|
||||
ushort extendedChrRomSize = (ushort)((chrRomMsb << 8) | header.CHRROMSize);
|
||||
|
||||
builder.AppendLine(prgRomMsb, " PRG-ROM size MSB");
|
||||
builder.AppendLine(extendedPrgRomSize, " Extended PRG-ROM size");
|
||||
builder.AppendLine(chrRomMsb, " CHR-ROM size MSB");
|
||||
builder.AppendLine(extendedChrRomSize, " Extended CHR-ROM size");
|
||||
|
||||
// Byte 10
|
||||
byte prgRamShiftCount = (byte)(header2.PRGRAMEEPROMSize & 0x0F);
|
||||
int prgRamSize = prgRamShiftCount > 0 ? 64 << prgRamShiftCount : 0;
|
||||
byte eepromShiftCount = (byte)(header2.PRGRAMEEPROMSize >> 4);
|
||||
int eepromSize = eepromShiftCount > 0 ? 64 << eepromShiftCount : 0;
|
||||
|
||||
builder.AppendLine(prgRamShiftCount, " PRG-RAM shift count");
|
||||
builder.AppendLine(prgRamSize, " PRG-RAM size");
|
||||
builder.AppendLine(eepromShiftCount, " PRG-NVRAM/EEPROM shift count");
|
||||
builder.AppendLine(eepromSize, " PRG-NVRAM/EEPROM size");
|
||||
|
||||
// Byte 11
|
||||
byte chrRamShiftCount = (byte)(header2.CHRRAMSize & 0x0F);
|
||||
int chrRamSize = chrRamShiftCount > 0 ? 64 << chrRamShiftCount : 0;
|
||||
byte chrNvramShiftCount = (byte)(header2.CHRRAMSize >> 4);
|
||||
int chrNvramSize = eepromShiftCount > 0 ? 64 << chrNvramShiftCount : 0;
|
||||
|
||||
builder.AppendLine(chrRamShiftCount, " CHR-RAM shift count");
|
||||
builder.AppendLine(chrRamSize, " CHR-RAM size");
|
||||
builder.AppendLine(chrNvramShiftCount, " CHR-NVRAM shift count");
|
||||
builder.AppendLine(chrNvramSize, " CHR-NVRAM size");
|
||||
|
||||
// Byte 12
|
||||
string cpuTiming = header2.CPUPPUTiming.FromCPUPPUTiming();
|
||||
builder.AppendLine(cpuTiming, " CPU timing");
|
||||
|
||||
// Byte 13
|
||||
#if NET20 || NET35
|
||||
if ((header.Flag7 & Flag7.ExtendedConsoleType) != 0)
|
||||
#else
|
||||
if (header.Flag7.HasFlag(Flag7.ExtendedConsoleType))
|
||||
#endif
|
||||
{
|
||||
ExtendedConsoleType extendedConsoleType = (ExtendedConsoleType)(header2.ExtendedSystemType & 0x0F);
|
||||
string extendedConsoleTypeString = extendedConsoleType.FromExtendedConsoleType();
|
||||
builder.AppendLine(extendedConsoleTypeString, " Extended console type");
|
||||
}
|
||||
#if NET20 || NET35
|
||||
else if ((header.Flag7 & Flag7.VSUnisystem) != 0)
|
||||
#else
|
||||
else if (header.Flag7.HasFlag(Flag7.VSUnisystem))
|
||||
#endif
|
||||
{
|
||||
VsSystemType vsSystemType = (VsSystemType)(header2.ExtendedSystemType & 0x0F);
|
||||
string vsSystemTypeString = vsSystemType.FromVsSystemType();
|
||||
builder.AppendLine(vsSystemTypeString, " Vs. system type");
|
||||
|
||||
VsHardwareType vsHardwareType = (VsHardwareType)(header2.ExtendedSystemType >> 4);
|
||||
string vsHardwareTypeString = vsHardwareType.FromVsHardwareType();
|
||||
builder.AppendLine(vsHardwareTypeString, " Vs. hardware type");
|
||||
}
|
||||
|
||||
// Byte 14
|
||||
builder.AppendLine(header2.MiscellaneousROMs, " Number of miscellaneous ROMs");
|
||||
|
||||
// Byte 15
|
||||
string defaultExpansionDevice = header2.DefaultExpansionDevice.FromDefaultExpansionDevice();
|
||||
builder.AppendLine(defaultExpansionDevice, " Default expansion device");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(" Unrecognized header type!");
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,8 @@ using SabreTools.Data.Models.NES;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
// TODO: Add printer class
|
||||
// TODO: Add extension properties
|
||||
public class NESCart : WrapperBase<Cart>
|
||||
public partial class NESCart : WrapperBase<Cart>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
|
||||
Reference in New Issue
Block a user