diff --git a/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChip.cs b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChip.cs new file mode 100644 index 0000000..6389708 --- /dev/null +++ b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChip.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; + +namespace Commodore64.Cartridge.FileFormats.Crt { + + public class CrtChip { + + public string Identifier { get; set; } + public UInt32 ChipLength { get; set; } + public CrtChipType ChipType { get; set; } + public UInt16 Bank { get; set; } + public UInt16 Address { get; set; } + public UInt16 Length { get; set; } + + public byte[] Data { get; set; } + + + public static CrtChip FromBytes(byte[] data) { + + var c = new CrtChip(); + + c.Identifier = Encoding.ASCII.GetString(data, 0, 0x04); + + if (c.Identifier.ToUpper() != "CHIP") throw new FileFormatException(".CRT CHIP-packet identifier is not correct."); + + c.ChipLength = BitConverter.ToUInt32(data.Skip(0x04).Take(sizeof(UInt32)).Reverse().ToArray(), 0); + c.ChipType = (CrtChipType) BitConverter.ToUInt16(data.Skip(0x08).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + c.Bank = BitConverter.ToUInt16(data.Skip(0x0A).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + c.Address = BitConverter.ToUInt16(data.Skip(0x0C).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + c.Length = BitConverter.ToUInt16(data.Skip(0x0E).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + + c.Data = data.Skip(0x10).Take(c.Length).ToArray(); + + return c; + } + + } + +} diff --git a/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChipType.cs b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChipType.cs new file mode 100644 index 0000000..6a9b070 --- /dev/null +++ b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtChipType.cs @@ -0,0 +1,11 @@ +using System; + +namespace Commodore64.Cartridge.FileFormats.Crt { + + public enum CrtChipType : UInt16 { + ROM = 0, + RAM = 1, + FLASH_ROM = 2, + } + +} diff --git a/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtFile.cs b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtFile.cs new file mode 100644 index 0000000..7c7cac1 --- /dev/null +++ b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtFile.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Commodore64.Cartridge.FileFormats.Crt { + public class CrtFile { + public CrtHeader Header { get; set; } + public List Chips { get; set; } = new List(); + + + public static CrtFile FromBytes(byte[] data) { + var crt = new CrtFile(); + + crt.Header = CrtHeader.FromBytes(data); + + // TODO: Add support for multiple CHIP-sections + crt.Chips.Add(CrtChip.FromBytes(data.Skip(0x40).ToArray())); + + return crt; + } + + public static CrtFile FromFile(string path) { + return FromBytes(File.ReadAllBytes(path)); + } + } +} diff --git a/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHardwareType.cs b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHardwareType.cs new file mode 100644 index 0000000..f61c6cb --- /dev/null +++ b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHardwareType.cs @@ -0,0 +1,29 @@ +using System; + +namespace Commodore64.Cartridge.FileFormats.Crt { + + public enum CrtHardwareType : UInt16 { + ACTION_REPLAY = 1, + KCS_POWER_CARTRIDGE = 2, + FINAL_CARTRIDGE_III = 3, + SIMONS_BASIC = 4, + OCEAN_TYPE_1_256_AND_128_KB = 5, + EXPERT_CARTRIDGE = 6, + FUN_PLAY = 7, + SUPER_GAMES = 8, + ATOMIC_POWER = 9, + EPYX_FASTLOAD = 10, + WESTERMANN = 11, + REX = 12, + FINAL_CARTRIDGE_I = 13, + MAGIC_FORMEL = 14, + C64_GAME_SYSTEM = 15, + WARPSPEED = 16, + DINAMIC = 17, + ZAXXON = 18, + MAGIC_DESK, _DOMARK, _HES_AUSTRALIA = 19, + SUPER_SNAPSHOT_5 = 20, + COMAL_80 = 21, + } + +} diff --git a/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHeader.cs b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHeader.cs new file mode 100644 index 0000000..e3a8165 --- /dev/null +++ b/ComputerSystems/Commodore64/Cartridge/FileFormats/Crt/CrtHeader.cs @@ -0,0 +1,39 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; + +namespace Commodore64.Cartridge.FileFormats.Crt { + + public class CrtHeader { + + public string Identifier { get; set; } + public UInt32 Length { get; set; } + public UInt16 Version { get; set; } + public CrtHardwareType HardwareType { get; set; } + public byte ExRomLine { get; set; } + public byte GameLine { get; set; } + public string Name { get; set; } + + public static CrtHeader FromBytes(byte[] data) { + + if (data.Length < 0x40) throw new ArgumentOutOfRangeException(nameof(data), "Length is less than minimum .CRT header length."); + + var h = new CrtHeader(); + + h.Identifier = Encoding.ASCII.GetString(data, 0, 0x10).Trim(); + + if (h.Identifier.ToUpper() != "C64 CARTRIDGE") throw new FileFormatException(".CRT header identifier is not correct."); + + h.Length = BitConverter.ToUInt32(data.Skip(0x10).Take(sizeof(UInt32)).Reverse().ToArray(), 0); + h.Version = BitConverter.ToUInt16(data.Skip(0x14).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + h.HardwareType = (CrtHardwareType) BitConverter.ToUInt16(data.Skip(0x16).Take(sizeof(UInt16)).Reverse().ToArray(), 0); + h.ExRomLine = data[0x18]; + h.GameLine = data[0x19]; + h.Name = Encoding.ASCII.GetString(data, 0x20, 0x20).Trim('\0'); + + + return h; + } + } +} diff --git a/ComputerSystems/Commodore64/Commodore64.csproj b/ComputerSystems/Commodore64/Commodore64.csproj index 8bc8bea..a72b07d 100644 --- a/ComputerSystems/Commodore64/Commodore64.csproj +++ b/ComputerSystems/Commodore64/Commodore64.csproj @@ -57,6 +57,11 @@ + + + + + @@ -128,5 +133,6 @@ MicroProcessor + \ No newline at end of file