diff --git a/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj b/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj index 0cbcbe07d..4ba4dcb7a 100644 --- a/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj +++ b/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj @@ -109,6 +109,9 @@ + + + @@ -134,6 +137,7 @@ + @@ -147,7 +151,7 @@ - + diff --git a/DiscImageChef.Decoders/Sega/CD.cs b/DiscImageChef.Decoders/Sega/CD.cs new file mode 100644 index 000000000..65a503410 --- /dev/null +++ b/DiscImageChef.Decoders/Sega/CD.cs @@ -0,0 +1,326 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : CD.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Globalization; +using System.Text; +using DiscImageChef.Console; + +namespace DiscImageChef.Decoders.Sega +{ + public static class CD + { + public struct IPBin + { + public byte[] SegaHardwareID; //16 + public byte[] volume_name; //11 // 0x010, Varies + public byte[] spare_space1; //1 // 0x01B, 0x00 + public byte[] volume_version; //2 // 0x01C, Volume version in BCD. <100 = Prerelease. + public byte[] volume_type; //2 // 0x01E, Bit 0 = 1 => CD-ROM. Rest should be 0. + public byte[] system_name; //11 // 0x020, Unknown, varies! + public byte[] spare_space2; //1 // 0x02B, 0x00 + public byte[] system_version; //2 // 0x02C, Should be 1 + public byte[] spare_space3; //2 // 0x02E, 0x0000 + public byte[] ip_address; //4 // 0x030, Initial program address + public byte[] ip_loadsize; //4 // 0x034, Load size of initial program + public byte[] ip_entry_address; //4 // 0x038, Initial program entry address + public byte[] ip_work_ram_size; //4 // 0x03C, Initial program work RAM size in bytes + public byte[] sp_address; //4 // 0x040, System program address + public byte[] sp_loadsize; //4 // 0x044, Load size of system program + public byte[] sp_entry_address; //4 // 0x048, System program entry address + public byte[] sp_work_ram_size; //4 // 0x04C, System program work RAM size in bytes + public byte[] release_date; //8 // 0x050, MMDDYYYY + public byte[] unknown1; //7 // 0x058, Seems to be all 0x20s + public byte[] spare_space4; //1 // 0x05F, 0x00 ? + public byte[] system_reserved; //160 // 0x060, System Reserved Area + public byte[] hardware_id; //16 // 0x100, Hardware ID + public byte[] copyright; //3 // 0x110, "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced + public byte[] developer_code; //5 // 0x113 or 0x110, "SEGA" or "T-xx" + public byte[] release_date2; //8 // 0x118, Another release date, this with month in letters? + public byte[] domestic_title; //48 // 0x120, Domestic version of the game title + public byte[] overseas_title; //48 // 0x150, Overseas version of the game title + public byte[] product_code; //13 // 0x180, Official product code + public byte[] peripherals; //16 // 0x190, Supported peripherals, see above + public byte[] spare_space6; //16 // 0x1A0, 0x20 + public byte[] spare_space7; //64 // 0x1B0, Inside here should be modem information, but I need to get a modem-enabled game + public byte[] region_codes; //16 // 0x1F0, Region codes, space-filled + } + + public static IPBin? DecodeIPBin(byte[] ipbin_sector) + { + if(ipbin_sector == null) + return null; + + if(ipbin_sector.Length < 512) + return null; + + IPBin ipbin = new IPBin(); + ipbin.SegaHardwareID = new byte[16]; + // Definitions following + ipbin.volume_name = new byte[11]; // 0x010, Varies + ipbin.spare_space1 = new byte[1]; // 0x01B, 0x00 + ipbin.volume_version = new byte[2]; // 0x01C, Volume version in BCD. <100 = Prerelease. + ipbin.volume_type = new byte[2]; // 0x01E, Bit 0 = 1 => CD-ROM. Rest should be 0. + ipbin.system_name = new byte[11]; // 0x020, Unknown, varies! + ipbin.spare_space2 = new byte[1]; // 0x02B, 0x00 + ipbin.system_version = new byte[2]; // 0x02C, Should be 1 + ipbin.spare_space3 = new byte[2]; // 0x02E, 0x0000 + ipbin.ip_address = new byte[4]; // 0x030, Initial program address + ipbin.ip_loadsize = new byte[4]; // 0x034, Load size of initial program + ipbin.ip_entry_address = new byte[4]; // 0x038, Initial program entry address + ipbin.ip_work_ram_size = new byte[4]; // 0x03C, Initial program work RAM size in bytes + ipbin.sp_address = new byte[4]; // 0x040, System program address + ipbin.sp_loadsize = new byte[4]; // 0x044, Load size of system program + ipbin.sp_entry_address = new byte[4]; // 0x048, System program entry address + ipbin.sp_work_ram_size = new byte[4]; // 0x04C, System program work RAM size in bytes + ipbin.release_date = new byte[8]; // 0x050, MMDDYYYY + ipbin.unknown1 = new byte[7]; // 0x058, Seems to be all 0x20s + ipbin.spare_space4 = new byte[1]; // 0x05F, 0x00 ? + ipbin.system_reserved = new byte[160]; // 0x060, System Reserved Area + ipbin.hardware_id = new byte[16]; // 0x100, Hardware ID + ipbin.copyright = new byte[3]; // 0x110, "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced + ipbin.developer_code = new byte[5]; // 0x113 or 0x110, "SEGA" or "T-xx" + ipbin.release_date2 = new byte[8]; // 0x118, Another release date, this with month in letters? + ipbin.domestic_title = new byte[48]; // 0x120, Domestic version of the game title + ipbin.overseas_title = new byte[48]; // 0x150, Overseas version of the game title + ipbin.product_code = new byte[13]; // 0x180, Official product code + ipbin.peripherals = new byte[16]; // 0x190, Supported peripherals, see above + ipbin.spare_space6 = new byte[16]; // 0x1A0, 0x20 + ipbin.spare_space7 = new byte[64]; // 0x1B0, Inside here should be modem information, but I need to get a modem-enabled game + ipbin.region_codes = new byte[16]; // 0x1F0, Region codes, space-filled + + //Reading all data + Array.Copy(ipbin_sector, 0x000, ipbin.SegaHardwareID, 0, 16); + Array.Copy(ipbin_sector, 0x010, ipbin.volume_name, 0, 11); // Varies + Array.Copy(ipbin_sector, 0x01B, ipbin.spare_space1, 0, 1); // 0x00 + Array.Copy(ipbin_sector, 0x01C, ipbin.volume_version, 0, 2); // Volume version in BCD. <100 = Prerelease. + Array.Copy(ipbin_sector, 0x01E, ipbin.volume_type, 0, 2); // Bit 0 = 1 => CD-ROM. Rest should be 0. + Array.Copy(ipbin_sector, 0x020, ipbin.system_name, 0, 11); // Unknown, varies! + Array.Copy(ipbin_sector, 0x02B, ipbin.spare_space2, 0, 1); // 0x00 + Array.Copy(ipbin_sector, 0x02C, ipbin.system_version, 0, 2); // Should be 1 + Array.Copy(ipbin_sector, 0x02E, ipbin.spare_space3, 0, 2); // 0x0000 + Array.Copy(ipbin_sector, 0x030, ipbin.ip_address, 0, 4); // Initial program address + Array.Copy(ipbin_sector, 0x034, ipbin.ip_loadsize, 0, 4); // Load size of initial program + Array.Copy(ipbin_sector, 0x038, ipbin.ip_entry_address, 0, 4); // Initial program entry address + Array.Copy(ipbin_sector, 0x03C, ipbin.ip_work_ram_size, 0, 4); // Initial program work RAM size in bytes + Array.Copy(ipbin_sector, 0x040, ipbin.sp_address, 0, 4); // System program address + Array.Copy(ipbin_sector, 0x044, ipbin.sp_loadsize, 0, 4); // Load size of system program + Array.Copy(ipbin_sector, 0x048, ipbin.sp_entry_address, 0, 4); // System program entry address + Array.Copy(ipbin_sector, 0x04C, ipbin.sp_work_ram_size, 0, 4); // System program work RAM size in bytes + Array.Copy(ipbin_sector, 0x050, ipbin.release_date, 0, 8); // MMDDYYYY + Array.Copy(ipbin_sector, 0x058, ipbin.unknown1, 0, 7); // Seems to be all 0x20s + Array.Copy(ipbin_sector, 0x05F, ipbin.spare_space4, 0, 1); // 0x00 ? + Array.Copy(ipbin_sector, 0x060, ipbin.system_reserved, 0, 160); // System Reserved Area + Array.Copy(ipbin_sector, 0x100, ipbin.hardware_id, 0, 16); // Hardware ID + Array.Copy(ipbin_sector, 0x110, ipbin.copyright, 0, 3); // "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced + if(Encoding.ASCII.GetString(ipbin.copyright) == "(C)") + Array.Copy(ipbin_sector, 0x113, ipbin.developer_code, 0, 5); // "SEGA" or "T-xx" + else + Array.Copy(ipbin_sector, 0x110, ipbin.developer_code, 0, 5); // "SEGA" or "T-xx" + Array.Copy(ipbin_sector, 0x118, ipbin.release_date2, 0, 8); // Another release date, this with month in letters? + Array.Copy(ipbin_sector, 0x120, ipbin.domestic_title, 0, 48); // Domestic version of the game title + Array.Copy(ipbin_sector, 0x150, ipbin.overseas_title, 0, 48); // Overseas version of the game title + //Array.Copy(ipbin_sector, 0x000, application_type, 0, 2); // Application type + //Array.Copy(ipbin_sector, 0x000, space_space5, 0, 1); // 0x20 + Array.Copy(ipbin_sector, 0x180, ipbin.product_code, 0, 13); // Official product code + Array.Copy(ipbin_sector, 0x190, ipbin.peripherals, 0, 16); // Supported peripherals, see above + Array.Copy(ipbin_sector, 0x1A0, ipbin.spare_space6, 0, 16); // 0x20 + Array.Copy(ipbin_sector, 0x1B0, ipbin.spare_space7, 0, 64); // Inside here should be modem information, but I need to get a modem-enabled game + Array.Copy(ipbin_sector, 0x1F0, ipbin.region_codes, 0, 16); // Region codes, space-filled + + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_name = \"{0}\"", Encoding.ASCII.GetString(ipbin.volume_name)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.system_name = \"{0}\"", Encoding.ASCII.GetString(ipbin.system_name)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_version = \"{0}\"", Encoding.ASCII.GetString(ipbin.volume_version)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_type = 0x{0}", BitConverter.ToInt16(ipbin.volume_type, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.system_version = 0x{0}", BitConverter.ToInt16(ipbin.system_version, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_address = 0x{0}", BitConverter.ToInt32(ipbin.ip_address, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_loadsize = {0}", BitConverter.ToInt32(ipbin.ip_loadsize, 0)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_entry_address = 0x{0}", BitConverter.ToInt32(ipbin.ip_entry_address, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_work_ram_size = {0}", BitConverter.ToInt32(ipbin.ip_work_ram_size, 0)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_address = 0x{0}", BitConverter.ToInt32(ipbin.sp_address, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_loadsize = {0}", BitConverter.ToInt32(ipbin.sp_loadsize, 0)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_entry_address = 0x{0}", BitConverter.ToInt32(ipbin.sp_entry_address, 0).ToString("X")); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_work_ram_size = {0}", BitConverter.ToInt32(ipbin.sp_work_ram_size, 0)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.release_date = \"{0}\"", Encoding.ASCII.GetString(ipbin.release_date)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.release_date2 = \"{0}\"", Encoding.ASCII.GetString(ipbin.release_date2)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.developer_code = \"{0}\"", Encoding.ASCII.GetString(ipbin.developer_code)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.domestic_title = \"{0}\"", Encoding.ASCII.GetString(ipbin.domestic_title)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.overseas_title = \"{0}\"", Encoding.ASCII.GetString(ipbin.overseas_title)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.product_code = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_code)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.peripherals = \"{0}\"", Encoding.ASCII.GetString(ipbin.peripherals)); + DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.region_codes = \"{0}\"", Encoding.ASCII.GetString(ipbin.region_codes)); + + string id = Encoding.ASCII.GetString(ipbin.SegaHardwareID); + + if(id == "SEGADISCSYSTEM " || id == "SEGADATADISC " || id == "SEGAOS ") + return ipbin; + else + return null; + } + + public static string Prettify(IPBin? decoded) + { + if(decoded == null) + return null; + + IPBin ipbin = decoded.Value; + + StringBuilder IPBinInformation = new StringBuilder(); + + IPBinInformation.AppendLine("--------------------------------"); + IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); + IPBinInformation.AppendLine("--------------------------------"); + + // Decoding all data + DateTime ipbindate = DateTime.MinValue; + CultureInfo provider = CultureInfo.InvariantCulture; + try + { + ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(ipbin.release_date), "MMddyyyy", provider); + } + catch + { + try + { + ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(ipbin.release_date2), "yyyy.MMM", provider); + } +#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + catch { } +#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + } + + /* + switch (Encoding.ASCII.GetString(application_type)) + { + case "GM": + IPBinInformation.AppendLine("Disc is a game."); + break; + case "AI": + IPBinInformation.AppendLine("Disc is an application."); + break; + default: + IPBinInformation.AppendLine("Disc is from unknown type."); + break; + } + */ + + IPBinInformation.AppendFormat("Volume name: {0}", Encoding.ASCII.GetString(ipbin.volume_name)).AppendLine(); + //IPBinInformation.AppendFormat("Volume version: {0}", Encoding.ASCII.GetString(ipbin.volume_version)).AppendLine(); + //IPBinInformation.AppendFormat("{0}", Encoding.ASCII.GetString(ipbin.volume_type)).AppendLine(); + IPBinInformation.AppendFormat("System name: {0}", Encoding.ASCII.GetString(ipbin.system_name)).AppendLine(); + //IPBinInformation.AppendFormat("System version: {0}", Encoding.ASCII.GetString(ipbin.system_version)).AppendLine(); + IPBinInformation.AppendFormat("Initial program address: 0x{0}", BitConverter.ToInt32(ipbin.ip_address, 0).ToString("X")).AppendLine(); + IPBinInformation.AppendFormat("Initial program load size: {0} bytes", BitConverter.ToInt32(ipbin.ip_loadsize, 0)).AppendLine(); + IPBinInformation.AppendFormat("Initial program entry address: 0x{0}", BitConverter.ToInt32(ipbin.ip_entry_address, 0).ToString("X")).AppendLine(); + IPBinInformation.AppendFormat("Initial program work RAM: {0} bytes", BitConverter.ToInt32(ipbin.ip_work_ram_size, 0)).AppendLine(); + IPBinInformation.AppendFormat("System program address: 0x{0}", BitConverter.ToInt32(ipbin.sp_address, 0).ToString("X")).AppendLine(); + IPBinInformation.AppendFormat("System program load size: {0} bytes", BitConverter.ToInt32(ipbin.sp_loadsize, 0)).AppendLine(); + IPBinInformation.AppendFormat("System program entry address: 0x{0}", BitConverter.ToInt32(ipbin.sp_entry_address, 0).ToString("X")).AppendLine(); + IPBinInformation.AppendFormat("System program work RAM: {0} bytes", BitConverter.ToInt32(ipbin.sp_work_ram_size, 0)).AppendLine(); + if(ipbindate != DateTime.MinValue) + IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); + //IPBinInformation.AppendFormat("Release date (other format): {0}", Encoding.ASCII.GetString(release_date2)).AppendLine(); + IPBinInformation.AppendFormat("Hardware ID: {0}", Encoding.ASCII.GetString(ipbin.hardware_id)).AppendLine(); + IPBinInformation.AppendFormat("Developer code: {0}", Encoding.ASCII.GetString(ipbin.developer_code)).AppendLine(); + IPBinInformation.AppendFormat("Domestic title: {0}", Encoding.ASCII.GetString(ipbin.domestic_title)).AppendLine(); + IPBinInformation.AppendFormat("Overseas title: {0}", Encoding.ASCII.GetString(ipbin.overseas_title)).AppendLine(); + IPBinInformation.AppendFormat("Product code: {0}", Encoding.ASCII.GetString(ipbin.product_code)).AppendLine(); + IPBinInformation.AppendFormat("Peripherals:").AppendLine(); + foreach(byte peripheral in ipbin.peripherals) + { + switch((char)peripheral) + { + case 'A': + IPBinInformation.AppendLine("Game supports analog controller."); + break; + case 'B': + IPBinInformation.AppendLine("Game supports trackball."); + break; + case 'G': + IPBinInformation.AppendLine("Game supports light gun."); + break; + case 'J': + IPBinInformation.AppendLine("Game supports JoyPad."); + break; + case 'K': + IPBinInformation.AppendLine("Game supports keyboard."); + break; + case 'M': + IPBinInformation.AppendLine("Game supports mouse."); + break; + case 'O': + IPBinInformation.AppendLine("Game supports Master System's JoyPad."); + break; + case 'P': + IPBinInformation.AppendLine("Game supports printer interface."); + break; + case 'R': + IPBinInformation.AppendLine("Game supports serial (RS-232C) interface."); + break; + case 'T': + IPBinInformation.AppendLine("Game supports tablet interface."); + break; + case 'V': + IPBinInformation.AppendLine("Game supports paddle controller."); + break; + case ' ': + break; + default: + IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine(); + break; + } + } + IPBinInformation.AppendLine("Regions supported:"); + foreach(byte region in ipbin.region_codes) + { + switch((char)region) + { + case 'J': + IPBinInformation.AppendLine("Japanese NTSC."); + break; + case 'U': + IPBinInformation.AppendLine("USA NTSC."); + break; + case 'E': + IPBinInformation.AppendLine("Europe PAL."); + break; + case ' ': + break; + default: + IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); + break; + } + } + + return IPBinInformation.ToString(); + } + } +} diff --git a/DiscImageChef.Decoders/Sega/Dreamcast.cs b/DiscImageChef.Decoders/Sega/Dreamcast.cs new file mode 100644 index 000000000..a14586bb7 --- /dev/null +++ b/DiscImageChef.Decoders/Sega/Dreamcast.cs @@ -0,0 +1,249 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Dreamcast.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Globalization; +using System.Text; +using DiscImageChef.Console; + +namespace DiscImageChef.Decoders.Sega +{ + public class Dreamcast + { + public struct IPBin + { + public byte[] SegaHardwareID; //16 + public byte[] maker_id; //16 // 0x010, "SEGA ENTERPRISES" + public byte[] dreamcast_crc; //4 // 0x020, CRC of product_no and product_version + public byte[] spare_space1; //1 // 0x024, " " + public byte[] dreamcast_media; //6 // 0x025, "GD-ROM" + public byte[] disc_no; //1 // 0x02B, Disc number + public byte[] disc_no_separator; //1 // 0x02C, '/' + public byte[] disc_total_nos; //1 // 0x02D, Total number of discs + public byte[] spare_space2; //2 // 0x02E, " " + public byte[] region_codes; //8 // 0x030, Region codes, space-filled + public byte[] peripherals; //7 // 0x038, Supported peripherals, bitwise + public byte[] product_no; //10 // 0x03C, Product number + public byte[] product_version; //6 // 0x046, Product version + public byte[] release_date; //8 // 0x04C, YYYYMMDD + public byte[] spare_space3; //8 // 0x054, " " + public byte[] boot_filename; //12 // 0x05C, Usually "1ST_READ.BIN" or "0WINCE.BIN " + public byte[] producer; //16 // 0x068, Game producer, space-filled + public byte[] product_name; //128 // 0x078, Game name, space-filled + } + + public static IPBin? DecodeIPBin(byte[] ipbin_sector) + { + if(ipbin_sector == null) + return null; + + if(ipbin_sector.Length < 512) + return null; + + IPBin ipbin = new IPBin(); + ipbin.SegaHardwareID = new byte[16]; + // Declarations following + ipbin.maker_id = new byte[16]; // 0x010, "SEGA ENTERPRISES" + ipbin.dreamcast_crc = new byte[4]; // 0x020, CRC of product_no and product_version + ipbin.spare_space1 = new byte[1]; // 0x024, " " + ipbin.dreamcast_media = new byte[6]; // 0x025, "GD-ROM" + ipbin.disc_no = new byte[1]; // 0x02B, Disc number + ipbin.disc_no_separator = new byte[1]; // 0x02C, '/' + ipbin.disc_total_nos = new byte[1]; // 0x02D, Total number of discs + ipbin.spare_space2 = new byte[2]; // 0x02E, " " + ipbin.region_codes = new byte[8]; // 0x030, Region codes, space-filled + ipbin.peripherals = new byte[7]; // 0x038, Supported peripherals, bitwise + ipbin.product_no = new byte[10]; // 0x03C, Product number + ipbin.product_version = new byte[6]; // 0x046, Product version + ipbin.release_date = new byte[8]; // 0x04C, YYYYMMDD + ipbin.spare_space3 = new byte[8]; // 0x054, " " + ipbin.boot_filename = new byte[12]; // 0x05C, Usually "1ST_READ.BIN" or "0WINCE.BIN " + ipbin.producer = new byte[16]; // 0x068, Game producer, space-filled + ipbin.product_name = new byte[128]; // 0x078, Game name, space-filled + // Reading all data + Array.Copy(ipbin_sector, 0x010, ipbin.maker_id, 0, 16); // "SEGA ENTERPRISES" + Array.Copy(ipbin_sector, 0x020, ipbin.dreamcast_crc, 0, 4); // CRC of product_no and product_version (hex) + Array.Copy(ipbin_sector, 0x024, ipbin.spare_space1, 0, 1); // " " + Array.Copy(ipbin_sector, 0x025, ipbin.dreamcast_media, 0, 6); // "GD-ROM" + Array.Copy(ipbin_sector, 0x02B, ipbin.disc_no, 0, 1); // Disc number + Array.Copy(ipbin_sector, 0x02C, ipbin.disc_no_separator, 0, 1); // '/' + Array.Copy(ipbin_sector, 0x02D, ipbin.disc_total_nos, 0, 1); // Total number of discs + Array.Copy(ipbin_sector, 0x02E, ipbin.spare_space2, 0, 2); // " " + Array.Copy(ipbin_sector, 0x030, ipbin.region_codes, 0, 8); // Region codes, space-filled + Array.Copy(ipbin_sector, 0x038, ipbin.peripherals, 0, 7); // Supported peripherals, hexadecimal + Array.Copy(ipbin_sector, 0x040, ipbin.product_no, 0, 10); // Product number + Array.Copy(ipbin_sector, 0x04A, ipbin.product_version, 0, 6); // Product version + Array.Copy(ipbin_sector, 0x050, ipbin.release_date, 0, 8); // YYYYMMDD + Array.Copy(ipbin_sector, 0x058, ipbin.spare_space3, 0, 8); // " " + Array.Copy(ipbin_sector, 0x060, ipbin.boot_filename, 0, 12); // Usually "1ST_READ.BIN" or "0WINCE.BIN " + Array.Copy(ipbin_sector, 0x070, ipbin.producer, 0, 16); // Game producer, space-filled + Array.Copy(ipbin_sector, 0x080, ipbin.product_name, 0, 128); // Game name, space-filled + + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.maker_id = \"{0}\"", Encoding.ASCII.GetString(ipbin.maker_id)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.dreamcast_crc = 0x{0}", Encoding.ASCII.GetString(ipbin.dreamcast_crc)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space1 = \"{0}\"", Encoding.ASCII.GetString(ipbin.spare_space1)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.dreamcast_media = \"{0}\"", Encoding.ASCII.GetString(ipbin.dreamcast_media)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_no = {0}", Encoding.ASCII.GetString(ipbin.disc_no)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_no_separator = \"{0}\"", Encoding.ASCII.GetString(ipbin.disc_no_separator)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_total_nos = \"{0}\"", Encoding.ASCII.GetString(ipbin.disc_total_nos)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space2 = \"{0}\"", Encoding.ASCII.GetString(ipbin.spare_space2)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.region_codes = \"{0}\"", Encoding.ASCII.GetString(ipbin.region_codes)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.peripherals = \"{0}\"", Encoding.ASCII.GetString(ipbin.peripherals)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_no = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_no)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_version = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_version)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.release_date = \"{0}\"", Encoding.ASCII.GetString(ipbin.release_date)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space3 = \"{0}\"", Encoding.ASCII.GetString(ipbin.spare_space3)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.boot_filename = \"{0}\"", Encoding.ASCII.GetString(ipbin.boot_filename)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.producer = \"{0}\"", Encoding.ASCII.GetString(ipbin.producer)); + DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_name = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_name)); + + string id = Encoding.ASCII.GetString(ipbin.SegaHardwareID); + + if(id == "SEGA SEGAKATANA ") + return ipbin; + else + return null; + } + + public static string Prettify(IPBin? decoded) + { + if(decoded == null) + return null; + + IPBin ipbin = decoded.Value; + + StringBuilder IPBinInformation = new StringBuilder(); + + IPBinInformation.AppendLine("--------------------------------"); + IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); + IPBinInformation.AppendLine("--------------------------------"); + + // Decoding all data + DateTime ipbindate; + CultureInfo provider = CultureInfo.InvariantCulture; + ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(ipbin.release_date), "yyyyMMdd", provider); + IPBinInformation.AppendFormat("Product name: {0}", Encoding.ASCII.GetString(ipbin.product_name)).AppendLine(); + IPBinInformation.AppendFormat("Product version: {0}", Encoding.ASCII.GetString(ipbin.product_version)).AppendLine(); + IPBinInformation.AppendFormat("Producer: {0}", Encoding.ASCII.GetString(ipbin.producer)).AppendLine(); + IPBinInformation.AppendFormat("Disc media: {0}", Encoding.ASCII.GetString(ipbin.dreamcast_media)).AppendLine(); + IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(ipbin.disc_no), Encoding.ASCII.GetString(ipbin.disc_total_nos)).AppendLine(); + IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); + switch(Encoding.ASCII.GetString(ipbin.boot_filename)) + { + case "1ST_READ.BIN": + IPBinInformation.AppendLine("Disc boots natively."); + break; + case "0WINCE.BIN ": + IPBinInformation.AppendLine("Disc boots using Windows CE."); + break; + default: + IPBinInformation.AppendFormat("Disc boots using unknown loader: {0}.", Encoding.ASCII.GetString(ipbin.boot_filename)).AppendLine(); + break; + } + IPBinInformation.AppendLine("Regions supported:"); + foreach(byte region in ipbin.region_codes) + { + switch((char)region) + { + case 'J': + IPBinInformation.AppendLine("Japanese NTSC."); + break; + case 'U': + IPBinInformation.AppendLine("North America NTSC."); + break; + case 'E': + IPBinInformation.AppendLine("Europe PAL."); + break; + case ' ': + break; + default: + IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); + break; + } + } + + int iPeripherals = int.Parse(Encoding.ASCII.GetString(ipbin.peripherals), NumberStyles.HexNumber); + + if((iPeripherals & 0x00000001) == 0x00000001) + IPBinInformation.AppendLine("Game uses Windows CE."); + + IPBinInformation.AppendFormat("Peripherals:").AppendLine(); + + if((iPeripherals & 0x00000010) == 0x00000010) + IPBinInformation.AppendLine("Game supports the VGA Box."); + if((iPeripherals & 0x00000100) == 0x00000100) + IPBinInformation.AppendLine("Game supports other expansion."); + if((iPeripherals & 0x00000200) == 0x00000200) + IPBinInformation.AppendLine("Game supports Puru Puru pack."); + if((iPeripherals & 0x00000400) == 0x00000400) + IPBinInformation.AppendLine("Game supports Mike Device."); + if((iPeripherals & 0x00000800) == 0x00000800) + IPBinInformation.AppendLine("Game supports Memory Card."); + if((iPeripherals & 0x00001000) == 0x00001000) + IPBinInformation.AppendLine("Game requires A + B + Start buttons and D-Pad."); + if((iPeripherals & 0x00002000) == 0x00002000) + IPBinInformation.AppendLine("Game requires C button."); + if((iPeripherals & 0x00004000) == 0x00004000) + IPBinInformation.AppendLine("Game requires D button."); + if((iPeripherals & 0x00008000) == 0x00008000) + IPBinInformation.AppendLine("Game requires X button."); + if((iPeripherals & 0x00010000) == 0x00010000) + IPBinInformation.AppendLine("Game requires Y button."); + if((iPeripherals & 0x00020000) == 0x00020000) + IPBinInformation.AppendLine("Game requires Z button."); + if((iPeripherals & 0x00040000) == 0x00040000) + IPBinInformation.AppendLine("Game requires expanded direction buttons."); + if((iPeripherals & 0x00080000) == 0x00080000) + IPBinInformation.AppendLine("Game requires analog R trigger."); + if((iPeripherals & 0x00100000) == 0x00100000) + IPBinInformation.AppendLine("Game requires analog L trigger."); + if((iPeripherals & 0x00200000) == 0x00200000) + IPBinInformation.AppendLine("Game requires analog horizontal controller."); + if((iPeripherals & 0x00400000) == 0x00400000) + IPBinInformation.AppendLine("Game requires analog vertical controller."); + if((iPeripherals & 0x00800000) == 0x00800000) + IPBinInformation.AppendLine("Game requires expanded analog horizontal controller."); + if((iPeripherals & 0x01000000) == 0x01000000) + IPBinInformation.AppendLine("Game requires expanded analog vertical controller."); + if((iPeripherals & 0x02000000) == 0x02000000) + IPBinInformation.AppendLine("Game supports Gun."); + if((iPeripherals & 0x04000000) == 0x04000000) + IPBinInformation.AppendLine("Game supports Keyboard."); + if((iPeripherals & 0x08000000) == 0x08000000) + IPBinInformation.AppendLine("Game supports Mouse."); + + if((iPeripherals & 0xF00000EE) != 0) + IPBinInformation.AppendFormat("Game supports unknown peripherals mask {0:X2}", (iPeripherals & 0xF00000EE)); + + return IPBinInformation.ToString(); + } + } +} diff --git a/DiscImageChef.Decoders/Sega/Saturn.cs b/DiscImageChef.Decoders/Sega/Saturn.cs new file mode 100644 index 000000000..d8ba75cee --- /dev/null +++ b/DiscImageChef.Decoders/Sega/Saturn.cs @@ -0,0 +1,198 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Saturn.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Globalization; +using System.Text; +using DiscImageChef.Console; + +namespace DiscImageChef.Decoders.Sega +{ + public static class Saturn + { + public struct IPBin + { + public byte[] SegaHardwareID; //16 + public byte[] maker_id; //[16 // 0x010, "SEGA ENTERPRISES" + public byte[] product_no; //[10 // 0x020, Product number + public byte[] product_version; //[6 // 0x02A, Product version + public byte[] release_date; //[8 // 0x030, YYYYMMDD + public byte[] saturn_media; //[3 // 0x038, "CD-" + public byte[] disc_no; //[1 // 0x03B, Disc number + public byte[] disc_no_separator; //[1 // 0x03C, '/' + public byte[] disc_total_nos; //[1 // 0x03D, Total number of discs + public byte[] spare_space1; //[2 // 0x03E, " " + public byte[] region_codes; //[16 // 0x040, Region codes, space-filled + public byte[] peripherals; //[16 // 0x050, Supported peripherals, see above + public byte[] product_name; //[112 // 0x060, Game name, space-filled + } + + public static IPBin? DecodeIPBin(byte[] ipbin_sector) + { + if(ipbin_sector == null) + return null; + + if(ipbin_sector.Length < 512) + return null; + + IPBin ipbin = new IPBin(); + ipbin.SegaHardwareID = new byte[16]; + // Definitions following + ipbin.maker_id = new byte[16]; // 0x010, "SEGA ENTERPRISES" + ipbin.product_no = new byte[10]; // 0x020, Product number + ipbin.product_version = new byte[6]; // 0x02A, Product version + ipbin.release_date = new byte[8]; // 0x030, YYYYMMDD + ipbin.saturn_media = new byte[3]; // 0x038, "CD-" + ipbin.disc_no = new byte[1]; // 0x03B, Disc number + ipbin.disc_no_separator = new byte[1]; // 0x03C, '/' + ipbin.disc_total_nos = new byte[1]; // 0x03D, Total number of discs + ipbin.spare_space1 = new byte[2]; // 0x03E, " " + ipbin.region_codes = new byte[16]; // 0x040, Region codes, space-filled + ipbin.peripherals = new byte[16]; // 0x050, Supported peripherals, see above + ipbin.product_name = new byte[112]; // 0x060, Game name, space-filled + // Reading all data + Array.Copy(ipbin_sector, 0x010, ipbin.maker_id, 0, 16); // "SEGA ENTERPRISES" + Array.Copy(ipbin_sector, 0x020, ipbin.product_no, 0, 10); // Product number + Array.Copy(ipbin_sector, 0x02A, ipbin.product_version, 0, 6); // Product version + Array.Copy(ipbin_sector, 0x030, ipbin.release_date, 0, 8); // YYYYMMDD + Array.Copy(ipbin_sector, 0x038, ipbin.saturn_media, 0, 3); // "CD-" + Array.Copy(ipbin_sector, 0x03B, ipbin.disc_no, 0, 1); // Disc number + Array.Copy(ipbin_sector, 0x03C, ipbin.disc_no_separator, 0, 1); // '/' + Array.Copy(ipbin_sector, 0x03D, ipbin.disc_total_nos, 0, 1); // Total number of discs + Array.Copy(ipbin_sector, 0x03E, ipbin.spare_space1, 0, 2); // " " + Array.Copy(ipbin_sector, 0x040, ipbin.region_codes, 0, 16); // Region codes, space-filled + Array.Copy(ipbin_sector, 0x050, ipbin.peripherals, 0, 16); // Supported peripherals, see above + Array.Copy(ipbin_sector, 0x060, ipbin.product_name, 0, 112); // Game name, space-filled + + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.maker_id = \"{0}\"", Encoding.ASCII.GetString(ipbin.maker_id)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_no = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_no)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_version = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_version)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.release_datedate = \"{0}\"", Encoding.ASCII.GetString(ipbin.release_date)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.saturn_media = \"{0}\"", Encoding.ASCII.GetString(ipbin.saturn_media)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_no = {0}", Encoding.ASCII.GetString(ipbin.disc_no)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_no_separator = \"{0}\"", Encoding.ASCII.GetString(ipbin.disc_no_separator)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_total_nos = {0}", Encoding.ASCII.GetString(ipbin.disc_total_nos)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.release_date = \"{0}\"", Encoding.ASCII.GetString(ipbin.release_date)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.spare_space1 = \"{0}\"", Encoding.ASCII.GetString(ipbin.spare_space1)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.region_codes = \"{0}\"", Encoding.ASCII.GetString(ipbin.region_codes)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.peripherals = \"{0}\"", Encoding.ASCII.GetString(ipbin.peripherals)); + DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_name = \"{0}\"", Encoding.ASCII.GetString(ipbin.product_name)); + + string id = Encoding.ASCII.GetString(ipbin.SegaHardwareID); + + if(id == "SEGA SEGASATURN ") + return ipbin; + else + return null; + } + + public static string Prettify(IPBin? decoded) + { + if(decoded == null) + return null; + + IPBin ipbin = decoded.Value; + + StringBuilder IPBinInformation = new StringBuilder(); + + IPBinInformation.AppendLine("--------------------------------"); + IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); + IPBinInformation.AppendLine("--------------------------------"); + + // Decoding all data + DateTime ipbindate; + CultureInfo provider = CultureInfo.InvariantCulture; + ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(ipbin.release_date), "yyyyMMdd", provider); + IPBinInformation.AppendFormat("Product name: {0}", Encoding.ASCII.GetString(ipbin.product_name)).AppendLine(); + IPBinInformation.AppendFormat("Product number: {0}", Encoding.ASCII.GetString(ipbin.product_no)).AppendLine(); + IPBinInformation.AppendFormat("Product version: {0}", Encoding.ASCII.GetString(ipbin.product_version)).AppendLine(); + IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); + IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(ipbin.disc_no), Encoding.ASCII.GetString(ipbin.disc_total_nos)).AppendLine(); + + IPBinInformation.AppendFormat("Peripherals:").AppendLine(); + foreach(byte peripheral in ipbin.peripherals) + { + switch((char)peripheral) + { + case 'A': + IPBinInformation.AppendLine("Game supports analog controller."); + break; + case 'J': + IPBinInformation.AppendLine("Game supports JoyPad."); + break; + case 'K': + IPBinInformation.AppendLine("Game supports keyboard."); + break; + case 'M': + IPBinInformation.AppendLine("Game supports mouse."); + break; + case 'S': + IPBinInformation.AppendLine("Game supports analog steering controller."); + break; + case 'T': + IPBinInformation.AppendLine("Game supports multitap."); + break; + case ' ': + break; + default: + IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine(); + break; + } + } + IPBinInformation.AppendLine("Regions supported:"); + foreach(byte region in ipbin.region_codes) + { + switch((char)region) + { + case 'J': + IPBinInformation.AppendLine("Japanese NTSC."); + break; + case 'U': + IPBinInformation.AppendLine("North America NTSC."); + break; + case 'E': + IPBinInformation.AppendLine("Europe PAL."); + break; + case 'T': + IPBinInformation.AppendLine("Asia NTSC."); + break; + case ' ': + break; + default: + IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); + break; + } + } + + return IPBinInformation.ToString(); + } + } +} diff --git a/DiscImageChef.Filesystems/ISO9660.cs b/DiscImageChef.Filesystems/ISO9660.cs index 3f03a59fa..69dd747a1 100644 --- a/DiscImageChef.Filesystems/ISO9660.cs +++ b/DiscImageChef.Filesystems/ISO9660.cs @@ -309,532 +309,10 @@ namespace DiscImageChef.Filesystems } }*/ - #region SEGA IP.BIN Read and decoding - - bool SegaCD = false; - bool Saturn = false; - bool Dreamcast = false; - StringBuilder IPBinInformation = new StringBuilder(); - - byte[] SegaHardwareID = new byte[16]; byte[] ipbin_sector = imagePlugin.ReadSector(0 + partition.Start); - Array.Copy(ipbin_sector, 0x000, SegaHardwareID, 0, 16); - - DicConsole.DebugWriteLine("ISO9660 plugin", "SegaHardwareID = \"{0}\"", CurrentEncoding.GetString(SegaHardwareID)); - - switch(CurrentEncoding.GetString(SegaHardwareID)) - { - case "SEGADISCSYSTEM ": - case "SEGADATADISC ": - case "SEGAOS ": - { - SegaCD = true; // Ok, this contains SegaCD IP.BIN - - DicConsole.DebugWriteLine("ISO9660 plugin", "Found SegaCD IP.BIN"); - - IPBinInformation.AppendLine("--------------------------------"); - IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); - IPBinInformation.AppendLine("--------------------------------"); - - // Definitions following - byte[] volume_name = new byte[11]; // 0x010, Varies - byte[] spare_space1 = new byte[1]; // 0x01B, 0x00 - byte[] volume_version = new byte[2]; // 0x01C, Volume version in BCD. <100 = Prerelease. - byte[] volume_type = new byte[2]; // 0x01E, Bit 0 = 1 => CD-ROM. Rest should be 0. - byte[] system_name = new byte[11]; // 0x020, Unknown, varies! - byte[] spare_space2 = new byte[1]; // 0x02B, 0x00 - byte[] system_version = new byte[2]; // 0x02C, Should be 1 - byte[] spare_space3 = new byte[2]; // 0x02E, 0x0000 - byte[] ip_address = new byte[4]; // 0x030, Initial program address - byte[] ip_loadsize = new byte[4]; // 0x034, Load size of initial program - byte[] ip_entry_address = new byte[4]; // 0x038, Initial program entry address - byte[] ip_work_ram_size = new byte[4]; // 0x03C, Initial program work RAM size in bytes - byte[] sp_address = new byte[4]; // 0x040, System program address - byte[] sp_loadsize = new byte[4]; // 0x044, Load size of system program - byte[] sp_entry_address = new byte[4]; // 0x048, System program entry address - byte[] sp_work_ram_size = new byte[4]; // 0x04C, System program work RAM size in bytes - byte[] release_date = new byte[8]; // 0x050, MMDDYYYY - byte[] unknown1 = new byte[7]; // 0x058, Seems to be all 0x20s - byte[] spare_space4 = new byte[1]; // 0x05F, 0x00 ? - byte[] system_reserved = new byte[160]; // 0x060, System Reserved Area - byte[] hardware_id = new byte[16]; // 0x100, Hardware ID - byte[] copyright = new byte[3]; // 0x110, "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced - byte[] developer_code = new byte[5]; // 0x113 or 0x110, "SEGA" or "T-xx" - byte[] release_date2 = new byte[8]; // 0x118, Another release date, this with month in letters? - byte[] domestic_title = new byte[48]; // 0x120, Domestic version of the game title - byte[] overseas_title = new byte[48]; // 0x150, Overseas version of the game title - byte[] product_code = new byte[13]; // 0x180, Official product code - byte[] peripherals = new byte[16]; // 0x190, Supported peripherals, see above - byte[] spare_space6 = new byte[16]; // 0x1A0, 0x20 - byte[] spare_space7 = new byte[64]; // 0x1B0, Inside here should be modem information, but I need to get a modem-enabled game - byte[] region_codes = new byte[16]; // 0x1F0, Region codes, space-filled - //Reading all data - Array.Copy(ipbin_sector, 0x010, volume_name, 0, 11); // Varies - Array.Copy(ipbin_sector, 0x01B, spare_space1, 0, 1); // 0x00 - Array.Copy(ipbin_sector, 0x01C, volume_version, 0, 2); // Volume version in BCD. <100 = Prerelease. - Array.Copy(ipbin_sector, 0x01E, volume_type, 0, 2); // Bit 0 = 1 => CD-ROM. Rest should be 0. - Array.Copy(ipbin_sector, 0x020, system_name, 0, 11); // Unknown, varies! - Array.Copy(ipbin_sector, 0x02B, spare_space2, 0, 1); // 0x00 - Array.Copy(ipbin_sector, 0x02C, system_version, 0, 2); // Should be 1 - Array.Copy(ipbin_sector, 0x02E, spare_space3, 0, 2); // 0x0000 - Array.Copy(ipbin_sector, 0x030, ip_address, 0, 4); // Initial program address - Array.Copy(ipbin_sector, 0x034, ip_loadsize, 0, 4); // Load size of initial program - Array.Copy(ipbin_sector, 0x038, ip_entry_address, 0, 4); // Initial program entry address - Array.Copy(ipbin_sector, 0x03C, ip_work_ram_size, 0, 4); // Initial program work RAM size in bytes - Array.Copy(ipbin_sector, 0x040, sp_address, 0, 4); // System program address - Array.Copy(ipbin_sector, 0x044, sp_loadsize, 0, 4); // Load size of system program - Array.Copy(ipbin_sector, 0x048, sp_entry_address, 0, 4); // System program entry address - Array.Copy(ipbin_sector, 0x04C, sp_work_ram_size, 0, 4); // System program work RAM size in bytes - Array.Copy(ipbin_sector, 0x050, release_date, 0, 8); // MMDDYYYY - Array.Copy(ipbin_sector, 0x058, unknown1, 0, 7); // Seems to be all 0x20s - Array.Copy(ipbin_sector, 0x05F, spare_space4, 0, 1); // 0x00 ? - Array.Copy(ipbin_sector, 0x060, system_reserved, 0, 160); // System Reserved Area - Array.Copy(ipbin_sector, 0x100, hardware_id, 0, 16); // Hardware ID - Array.Copy(ipbin_sector, 0x110, copyright, 0, 3); // "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced - if(CurrentEncoding.GetString(copyright) == "(C)") - Array.Copy(ipbin_sector, 0x113, developer_code, 0, 5); // "SEGA" or "T-xx" - else - Array.Copy(ipbin_sector, 0x110, developer_code, 0, 5); // "SEGA" or "T-xx" - Array.Copy(ipbin_sector, 0x118, release_date2, 0, 8); // Another release date, this with month in letters? - Array.Copy(ipbin_sector, 0x120, domestic_title, 0, 48); // Domestic version of the game title - Array.Copy(ipbin_sector, 0x150, overseas_title, 0, 48); // Overseas version of the game title - //Array.Copy(ipbin_sector, 0x000, application_type, 0, 2); // Application type - //Array.Copy(ipbin_sector, 0x000, space_space5, 0, 1); // 0x20 - Array.Copy(ipbin_sector, 0x180, product_code, 0, 13); // Official product code - Array.Copy(ipbin_sector, 0x190, peripherals, 0, 16); // Supported peripherals, see above - Array.Copy(ipbin_sector, 0x1A0, spare_space6, 0, 16); // 0x20 - Array.Copy(ipbin_sector, 0x1B0, spare_space7, 0, 64); // Inside here should be modem information, but I need to get a modem-enabled game - Array.Copy(ipbin_sector, 0x1F0, region_codes, 0, 16); // Region codes, space-filled - - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_name = \"{0}\"", CurrentEncoding.GetString(volume_name)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.system_name = \"{0}\"", CurrentEncoding.GetString(system_name)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_version = \"{0}\"", CurrentEncoding.GetString(volume_version)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.volume_type = 0x{0}", BitConverter.ToInt16(volume_type, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.system_version = 0x{0}", BitConverter.ToInt16(system_version, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_address = 0x{0}", BitConverter.ToInt32(ip_address, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_loadsize = {0}", BitConverter.ToInt32(ip_loadsize, 0)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_entry_address = 0x{0}", BitConverter.ToInt32(ip_entry_address, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.ip_work_ram_size = {0}", BitConverter.ToInt32(ip_work_ram_size, 0)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_address = 0x{0}", BitConverter.ToInt32(sp_address, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_loadsize = {0}", BitConverter.ToInt32(sp_loadsize, 0)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_entry_address = 0x{0}", BitConverter.ToInt32(sp_entry_address, 0).ToString("X")); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.sp_work_ram_size = {0}", BitConverter.ToInt32(sp_work_ram_size, 0)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.release_date = \"{0}\"", CurrentEncoding.GetString(release_date)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.release_date2 = \"{0}\"", CurrentEncoding.GetString(release_date2)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.developer_code = \"{0}\"", CurrentEncoding.GetString(developer_code)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.domestic_title = \"{0}\"", CurrentEncoding.GetString(domestic_title)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.overseas_title = \"{0}\"", CurrentEncoding.GetString(overseas_title)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.product_code = \"{0}\"", CurrentEncoding.GetString(product_code)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.peripherals = \"{0}\"", CurrentEncoding.GetString(peripherals)); - DicConsole.DebugWriteLine("ISO9660 plugin", "segacd_ipbin.region_codes = \"{0}\"", CurrentEncoding.GetString(region_codes)); - - // Decoding all data - DateTime ipbindate = DateTime.MinValue; - CultureInfo provider = CultureInfo.InvariantCulture; - try - { - ipbindate = DateTime.ParseExact(CurrentEncoding.GetString(release_date), "MMddyyyy", provider); - } - catch - { - try - { - ipbindate = DateTime.ParseExact(CurrentEncoding.GetString(release_date2), "yyyy.MMM", provider); - } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body - catch { } -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body - } - - /* - switch (CurrentEncoding.GetString(application_type)) - { - case "GM": - IPBinInformation.AppendLine("Disc is a game."); - break; - case "AI": - IPBinInformation.AppendLine("Disc is an application."); - break; - default: - IPBinInformation.AppendLine("Disc is from unknown type."); - break; - } - */ - - IPBinInformation.AppendFormat("Volume name: {0}", CurrentEncoding.GetString(volume_name)).AppendLine(); - //IPBinInformation.AppendFormat("Volume version: {0}", CurrentEncoding.GetString(volume_version)).AppendLine(); - //IPBinInformation.AppendFormat("{0}", CurrentEncoding.GetString(volume_type)).AppendLine(); - IPBinInformation.AppendFormat("System name: {0}", CurrentEncoding.GetString(system_name)).AppendLine(); - //IPBinInformation.AppendFormat("System version: {0}", CurrentEncoding.GetString(system_version)).AppendLine(); - IPBinInformation.AppendFormat("Initial program address: 0x{0}", BitConverter.ToInt32(ip_address, 0).ToString("X")).AppendLine(); - IPBinInformation.AppendFormat("Initial program load size: {0} bytes", BitConverter.ToInt32(ip_loadsize, 0)).AppendLine(); - IPBinInformation.AppendFormat("Initial program entry address: 0x{0}", BitConverter.ToInt32(ip_entry_address, 0).ToString("X")).AppendLine(); - IPBinInformation.AppendFormat("Initial program work RAM: {0} bytes", BitConverter.ToInt32(ip_work_ram_size, 0)).AppendLine(); - IPBinInformation.AppendFormat("System program address: 0x{0}", BitConverter.ToInt32(sp_address, 0).ToString("X")).AppendLine(); - IPBinInformation.AppendFormat("System program load size: {0} bytes", BitConverter.ToInt32(sp_loadsize, 0)).AppendLine(); - IPBinInformation.AppendFormat("System program entry address: 0x{0}", BitConverter.ToInt32(sp_entry_address, 0).ToString("X")).AppendLine(); - IPBinInformation.AppendFormat("System program work RAM: {0} bytes", BitConverter.ToInt32(sp_work_ram_size, 0)).AppendLine(); - if(ipbindate != DateTime.MinValue) - IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); - //IPBinInformation.AppendFormat("Release date (other format): {0}", CurrentEncoding.GetString(release_date2)).AppendLine(); - IPBinInformation.AppendFormat("Hardware ID: {0}", CurrentEncoding.GetString(hardware_id)).AppendLine(); - IPBinInformation.AppendFormat("Developer code: {0}", CurrentEncoding.GetString(developer_code)).AppendLine(); - IPBinInformation.AppendFormat("Domestic title: {0}", CurrentEncoding.GetString(domestic_title)).AppendLine(); - IPBinInformation.AppendFormat("Overseas title: {0}", CurrentEncoding.GetString(overseas_title)).AppendLine(); - IPBinInformation.AppendFormat("Product code: {0}", CurrentEncoding.GetString(product_code)).AppendLine(); - IPBinInformation.AppendFormat("Peripherals:").AppendLine(); - foreach(byte peripheral in peripherals) - { - switch((char)peripheral) - { - case 'A': - IPBinInformation.AppendLine("Game supports analog controller."); - break; - case 'B': - IPBinInformation.AppendLine("Game supports trackball."); - break; - case 'G': - IPBinInformation.AppendLine("Game supports light gun."); - break; - case 'J': - IPBinInformation.AppendLine("Game supports JoyPad."); - break; - case 'K': - IPBinInformation.AppendLine("Game supports keyboard."); - break; - case 'M': - IPBinInformation.AppendLine("Game supports mouse."); - break; - case 'O': - IPBinInformation.AppendLine("Game supports Master System's JoyPad."); - break; - case 'P': - IPBinInformation.AppendLine("Game supports printer interface."); - break; - case 'R': - IPBinInformation.AppendLine("Game supports serial (RS-232C) interface."); - break; - case 'T': - IPBinInformation.AppendLine("Game supports tablet interface."); - break; - case 'V': - IPBinInformation.AppendLine("Game supports paddle controller."); - break; - case ' ': - break; - default: - IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine(); - break; - } - } - IPBinInformation.AppendLine("Regions supported:"); - foreach(byte region in region_codes) - { - switch((char)region) - { - case 'J': - IPBinInformation.AppendLine("Japanese NTSC."); - break; - case 'U': - IPBinInformation.AppendLine("USA NTSC."); - break; - case 'E': - IPBinInformation.AppendLine("Europe PAL."); - break; - case ' ': - break; - default: - IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); - break; - } - } - - break; - } - case "SEGA SEGASATURN ": - { - Saturn = true; - - DicConsole.DebugWriteLine("ISO9660 plugin", "Found Sega Saturn IP.BIN"); - - IPBinInformation.AppendLine("--------------------------------"); - IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); - IPBinInformation.AppendLine("--------------------------------"); - - // Definitions following - byte[] maker_id = new byte[16]; // 0x010, "SEGA ENTERPRISES" - byte[] product_no = new byte[10]; // 0x020, Product number - byte[] product_version = new byte[6]; // 0x02A, Product version - byte[] release_date = new byte[8]; // 0x030, YYYYMMDD - byte[] saturn_media = new byte[3]; // 0x038, "CD-" - byte[] disc_no = new byte[1]; // 0x03B, Disc number - byte[] disc_no_separator = new byte[1]; // 0x03C, '/' - byte[] disc_total_nos = new byte[1]; // 0x03D, Total number of discs - byte[] spare_space1 = new byte[2]; // 0x03E, " " - byte[] region_codes = new byte[16]; // 0x040, Region codes, space-filled - byte[] peripherals = new byte[16]; // 0x050, Supported peripherals, see above - byte[] product_name = new byte[112]; // 0x060, Game name, space-filled - // Reading all data - Array.Copy(ipbin_sector, 0x010, maker_id, 0, 16); // "SEGA ENTERPRISES" - Array.Copy(ipbin_sector, 0x020, product_no, 0, 10); // Product number - Array.Copy(ipbin_sector, 0x02A, product_version, 0, 6); // Product version - Array.Copy(ipbin_sector, 0x030, release_date, 0, 8); // YYYYMMDD - Array.Copy(ipbin_sector, 0x038, saturn_media, 0, 3); // "CD-" - Array.Copy(ipbin_sector, 0x03B, disc_no, 0, 1); // Disc number - Array.Copy(ipbin_sector, 0x03C, disc_no_separator, 0, 1); // '/' - Array.Copy(ipbin_sector, 0x03D, disc_total_nos, 0, 1); // Total number of discs - Array.Copy(ipbin_sector, 0x03E, spare_space1, 0, 2); // " " - Array.Copy(ipbin_sector, 0x040, region_codes, 0, 16); // Region codes, space-filled - Array.Copy(ipbin_sector, 0x050, peripherals, 0, 16); // Supported peripherals, see above - Array.Copy(ipbin_sector, 0x060, product_name, 0, 112); // Game name, space-filled - - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.maker_id = \"{0}\"", CurrentEncoding.GetString(maker_id)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_no = \"{0}\"", CurrentEncoding.GetString(product_no)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_version = \"{0}\"", CurrentEncoding.GetString(product_version)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.release_datedate = \"{0}\"", CurrentEncoding.GetString(release_date)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.saturn_media = \"{0}\"", CurrentEncoding.GetString(saturn_media)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_no = {0}", CurrentEncoding.GetString(disc_no)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_no_separator = \"{0}\"", CurrentEncoding.GetString(disc_no_separator)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.disc_total_nos = {0}", CurrentEncoding.GetString(disc_total_nos)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.release_date = \"{0}\"", CurrentEncoding.GetString(release_date)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.spare_space1 = \"{0}\"", CurrentEncoding.GetString(spare_space1)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.region_codes = \"{0}\"", CurrentEncoding.GetString(region_codes)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.peripherals = \"{0}\"", CurrentEncoding.GetString(peripherals)); - DicConsole.DebugWriteLine("ISO9660 plugin", "saturn_ipbin.product_name = \"{0}\"", CurrentEncoding.GetString(product_name)); - - // Decoding all data - DateTime ipbindate; - CultureInfo provider = CultureInfo.InvariantCulture; - ipbindate = DateTime.ParseExact(CurrentEncoding.GetString(release_date), "yyyyMMdd", provider); - IPBinInformation.AppendFormat("Product name: {0}", CurrentEncoding.GetString(product_name)).AppendLine(); - IPBinInformation.AppendFormat("Product number: {0}", CurrentEncoding.GetString(product_no)).AppendLine(); - IPBinInformation.AppendFormat("Product version: {0}", CurrentEncoding.GetString(product_version)).AppendLine(); - IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); - IPBinInformation.AppendFormat("Disc number {0} of {1}", CurrentEncoding.GetString(disc_no), CurrentEncoding.GetString(disc_total_nos)).AppendLine(); - - IPBinInformation.AppendFormat("Peripherals:").AppendLine(); - foreach(byte peripheral in peripherals) - { - switch((char)peripheral) - { - case 'A': - IPBinInformation.AppendLine("Game supports analog controller."); - break; - case 'J': - IPBinInformation.AppendLine("Game supports JoyPad."); - break; - case 'K': - IPBinInformation.AppendLine("Game supports keyboard."); - break; - case 'M': - IPBinInformation.AppendLine("Game supports mouse."); - break; - case 'S': - IPBinInformation.AppendLine("Game supports analog steering controller."); - break; - case 'T': - IPBinInformation.AppendLine("Game supports multitap."); - break; - case ' ': - break; - default: - IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine(); - break; - } - } - IPBinInformation.AppendLine("Regions supported:"); - foreach(byte region in region_codes) - { - switch((char)region) - { - case 'J': - IPBinInformation.AppendLine("Japanese NTSC."); - break; - case 'U': - IPBinInformation.AppendLine("North America NTSC."); - break; - case 'E': - IPBinInformation.AppendLine("Europe PAL."); - break; - case 'T': - IPBinInformation.AppendLine("Asia NTSC."); - break; - case ' ': - break; - default: - IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); - break; - } - } - - break; - } - case "SEGA SEGAKATANA ": - { - Dreamcast = true; - - DicConsole.DebugWriteLine("ISO9660 plugin", "Found Sega Dreamcast IP.BIN"); - - IPBinInformation.AppendLine("--------------------------------"); - IPBinInformation.AppendLine("SEGA IP.BIN INFORMATION:"); - IPBinInformation.AppendLine("--------------------------------"); - - // Declarations following - byte[] maker_id = new byte[16]; // 0x010, "SEGA ENTERPRISES" - byte[] dreamcast_crc = new byte[4]; // 0x020, CRC of product_no and product_version - byte[] spare_space1 = new byte[1]; // 0x024, " " - byte[] dreamcast_media = new byte[6]; // 0x025, "GD-ROM" - byte[] disc_no = new byte[1]; // 0x02B, Disc number - byte[] disc_no_separator = new byte[1]; // 0x02C, '/' - byte[] disc_total_nos = new byte[1]; // 0x02D, Total number of discs - byte[] spare_space2 = new byte[2]; // 0x02E, " " - byte[] region_codes = new byte[8]; // 0x030, Region codes, space-filled - byte[] peripherals = new byte[7]; // 0x038, Supported peripherals, bitwise - byte[] product_no = new byte[10]; // 0x03C, Product number - byte[] product_version = new byte[6]; // 0x046, Product version - byte[] release_date = new byte[8]; // 0x04C, YYYYMMDD - byte[] spare_space3 = new byte[8]; // 0x054, " " - byte[] boot_filename = new byte[12]; // 0x05C, Usually "1ST_READ.BIN" or "0WINCE.BIN " - byte[] producer = new byte[16]; // 0x068, Game producer, space-filled - byte[] product_name = new byte[128]; // 0x078, Game name, space-filled - // Reading all data - Array.Copy(ipbin_sector, 0x010, maker_id, 0, 16); // "SEGA ENTERPRISES" - Array.Copy(ipbin_sector, 0x020, dreamcast_crc, 0, 4); // CRC of product_no and product_version (hex) - Array.Copy(ipbin_sector, 0x024, spare_space1, 0, 1); // " " - Array.Copy(ipbin_sector, 0x025, dreamcast_media, 0, 6); // "GD-ROM" - Array.Copy(ipbin_sector, 0x02B, disc_no, 0, 1); // Disc number - Array.Copy(ipbin_sector, 0x02C, disc_no_separator, 0, 1); // '/' - Array.Copy(ipbin_sector, 0x02D, disc_total_nos, 0, 1); // Total number of discs - Array.Copy(ipbin_sector, 0x02E, spare_space2, 0, 2); // " " - Array.Copy(ipbin_sector, 0x030, region_codes, 0, 8); // Region codes, space-filled - Array.Copy(ipbin_sector, 0x038, peripherals, 0, 7); // Supported peripherals, hexadecimal - Array.Copy(ipbin_sector, 0x040, product_no, 0, 10); // Product number - Array.Copy(ipbin_sector, 0x04A, product_version, 0, 6); // Product version - Array.Copy(ipbin_sector, 0x050, release_date, 0, 8); // YYYYMMDD - Array.Copy(ipbin_sector, 0x058, spare_space3, 0, 8); // " " - Array.Copy(ipbin_sector, 0x060, boot_filename, 0, 12); // Usually "1ST_READ.BIN" or "0WINCE.BIN " - Array.Copy(ipbin_sector, 0x070, producer, 0, 16); // Game producer, space-filled - Array.Copy(ipbin_sector, 0x080, product_name, 0, 128); // Game name, space-filled - - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.maker_id = \"{0}\"", CurrentEncoding.GetString(maker_id)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.dreamcast_crc = 0x{0}", CurrentEncoding.GetString(dreamcast_crc)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space1 = \"{0}\"", CurrentEncoding.GetString(spare_space1)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.dreamcast_media = \"{0}\"", CurrentEncoding.GetString(dreamcast_media)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_no = {0}", CurrentEncoding.GetString(disc_no)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_no_separator = \"{0}\"", CurrentEncoding.GetString(disc_no_separator)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.disc_total_nos = \"{0}\"", CurrentEncoding.GetString(disc_total_nos)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space2 = \"{0}\"", CurrentEncoding.GetString(spare_space2)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.region_codes = \"{0}\"", CurrentEncoding.GetString(region_codes)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.peripherals = \"{0}\"", CurrentEncoding.GetString(peripherals)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_no = \"{0}\"", CurrentEncoding.GetString(product_no)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_version = \"{0}\"", CurrentEncoding.GetString(product_version)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.release_date = \"{0}\"", CurrentEncoding.GetString(release_date)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.spare_space3 = \"{0}\"", CurrentEncoding.GetString(spare_space3)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.boot_filename = \"{0}\"", CurrentEncoding.GetString(boot_filename)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.producer = \"{0}\"", CurrentEncoding.GetString(producer)); - DicConsole.DebugWriteLine("ISO9660 plugin", "dreamcast_ipbin.product_name = \"{0}\"", CurrentEncoding.GetString(product_name)); - - // Decoding all data - DateTime ipbindate; - CultureInfo provider = CultureInfo.InvariantCulture; - ipbindate = DateTime.ParseExact(CurrentEncoding.GetString(release_date), "yyyyMMdd", provider); - IPBinInformation.AppendFormat("Product name: {0}", CurrentEncoding.GetString(product_name)).AppendLine(); - IPBinInformation.AppendFormat("Product version: {0}", CurrentEncoding.GetString(product_version)).AppendLine(); - IPBinInformation.AppendFormat("Producer: {0}", CurrentEncoding.GetString(producer)).AppendLine(); - IPBinInformation.AppendFormat("Disc media: {0}", CurrentEncoding.GetString(dreamcast_media)).AppendLine(); - IPBinInformation.AppendFormat("Disc number {0} of {1}", CurrentEncoding.GetString(disc_no), CurrentEncoding.GetString(disc_total_nos)).AppendLine(); - IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine(); - switch(CurrentEncoding.GetString(boot_filename)) - { - case "1ST_READ.BIN": - IPBinInformation.AppendLine("Disc boots natively."); - break; - case "0WINCE.BIN ": - IPBinInformation.AppendLine("Disc boots using Windows CE."); - break; - default: - IPBinInformation.AppendFormat("Disc boots using unknown loader: {0}.", CurrentEncoding.GetString(boot_filename)).AppendLine(); - break; - } - IPBinInformation.AppendLine("Regions supported:"); - foreach(byte region in region_codes) - { - switch((char)region) - { - case 'J': - IPBinInformation.AppendLine("Japanese NTSC."); - break; - case 'U': - IPBinInformation.AppendLine("North America NTSC."); - break; - case 'E': - IPBinInformation.AppendLine("Europe PAL."); - break; - case ' ': - break; - default: - IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine(); - break; - } - } - - int iPeripherals = int.Parse(CurrentEncoding.GetString(peripherals), NumberStyles.HexNumber); - - if((iPeripherals & 0x00000001) == 0x00000001) - IPBinInformation.AppendLine("Game uses Windows CE."); - - IPBinInformation.AppendFormat("Peripherals:").AppendLine(); - - if((iPeripherals & 0x00000010) == 0x00000010) - IPBinInformation.AppendLine("Game supports the VGA Box."); - if((iPeripherals & 0x00000100) == 0x00000100) - IPBinInformation.AppendLine("Game supports other expansion."); - if((iPeripherals & 0x00000200) == 0x00000200) - IPBinInformation.AppendLine("Game supports Puru Puru pack."); - if((iPeripherals & 0x00000400) == 0x00000400) - IPBinInformation.AppendLine("Game supports Mike Device."); - if((iPeripherals & 0x00000800) == 0x00000800) - IPBinInformation.AppendLine("Game supports Memory Card."); - if((iPeripherals & 0x00001000) == 0x00001000) - IPBinInformation.AppendLine("Game requires A + B + Start buttons and D-Pad."); - if((iPeripherals & 0x00002000) == 0x00002000) - IPBinInformation.AppendLine("Game requires C button."); - if((iPeripherals & 0x00004000) == 0x00004000) - IPBinInformation.AppendLine("Game requires D button."); - if((iPeripherals & 0x00008000) == 0x00008000) - IPBinInformation.AppendLine("Game requires X button."); - if((iPeripherals & 0x00010000) == 0x00010000) - IPBinInformation.AppendLine("Game requires Y button."); - if((iPeripherals & 0x00020000) == 0x00020000) - IPBinInformation.AppendLine("Game requires Z button."); - if((iPeripherals & 0x00040000) == 0x00040000) - IPBinInformation.AppendLine("Game requires expanded direction buttons."); - if((iPeripherals & 0x00080000) == 0x00080000) - IPBinInformation.AppendLine("Game requires analog R trigger."); - if((iPeripherals & 0x00100000) == 0x00100000) - IPBinInformation.AppendLine("Game requires analog L trigger."); - if((iPeripherals & 0x00200000) == 0x00200000) - IPBinInformation.AppendLine("Game requires analog horizontal controller."); - if((iPeripherals & 0x00400000) == 0x00400000) - IPBinInformation.AppendLine("Game requires analog vertical controller."); - if((iPeripherals & 0x00800000) == 0x00800000) - IPBinInformation.AppendLine("Game requires expanded analog horizontal controller."); - if((iPeripherals & 0x01000000) == 0x01000000) - IPBinInformation.AppendLine("Game requires expanded analog vertical controller."); - if((iPeripherals & 0x02000000) == 0x02000000) - IPBinInformation.AppendLine("Game supports Gun."); - if((iPeripherals & 0x04000000) == 0x04000000) - IPBinInformation.AppendLine("Game supports Keyboard."); - if((iPeripherals & 0x08000000) == 0x08000000) - IPBinInformation.AppendLine("Game supports Mouse."); - - if((iPeripherals & 0xEE) != 0) - IPBinInformation.AppendFormat("Game supports unknown peripherals mask {0:X2}", (iPeripherals & 0xEE)); - - break; - } - } - #endregion + Decoders.Sega.CD.IPBin? SegaCD = Decoders.Sega.CD.DecodeIPBin(ipbin_sector); + Decoders.Sega.Saturn.IPBin? Saturn = Decoders.Sega.Saturn.DecodeIPBin(ipbin_sector); + Decoders.Sega.Dreamcast.IPBin? Dreamcast = Decoders.Sega.Dreamcast.DecodeIPBin(ipbin_sector); ISOMetadata.AppendFormat("ISO9660 file system").AppendLine(); if(Joliet) @@ -843,20 +321,20 @@ namespace DiscImageChef.Filesystems ISOMetadata.AppendFormat("Rock Ridge Interchange Protocol present.").AppendLine(); if(Bootable) ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine(); - if(SegaCD) + if(SegaCD != null) { ISOMetadata.AppendLine("This is a SegaCD / MegaCD disc."); - ISOMetadata.AppendLine(IPBinInformation.ToString()); + ISOMetadata.AppendLine(Decoders.Sega.CD.Prettify(SegaCD)); } - if(Saturn) + if(Saturn != null) { ISOMetadata.AppendLine("This is a Sega Saturn disc."); - ISOMetadata.AppendLine(IPBinInformation.ToString()); + ISOMetadata.AppendLine(Decoders.Sega.Saturn.Prettify(Saturn)); } - if(Dreamcast) + if(Dreamcast != null) { ISOMetadata.AppendLine("This is a Sega Dreamcast disc."); - ISOMetadata.AppendLine(IPBinInformation.ToString()); + ISOMetadata.AppendLine(Decoders.Sega.Dreamcast.Prettify(Dreamcast)); } ISOMetadata.AppendLine("--------------------------------"); ISOMetadata.AppendLine("VOLUME DESCRIPTOR INFORMATION:"); @@ -984,7 +462,7 @@ namespace DiscImageChef.Filesystems } } - xmlFSType.Bootable |= Bootable || SegaCD || Saturn || Dreamcast; + xmlFSType.Bootable |= Bootable || SegaCD != null || Saturn != null || Dreamcast != null; xmlFSType.Clusters = (long)(partition.End - partition.Start + 1); xmlFSType.ClusterSize = 2048;