diff options
author | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2020-11-30 17:33:25 +0300 |
---|---|---|
committer | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2020-11-30 17:33:25 +0300 |
commit | eb10ea5213b4362d9cc859593a89adab05237765 (patch) | |
tree | fde607aad441c723b1b4c6ebb8df0017e0c1cc4e | |
parent | 93445c376eaf4bebf3e6f36bbe35d6337c17c76d (diff) |
Much more FDS stuff
-rw-r--r-- | FdsBlockDiskInfo.cs | 71 | ||||
-rw-r--r-- | FdsBlockFileAmount.cs | 2 | ||||
-rw-r--r-- | FdsBlockFileData.cs | 2 | ||||
-rw-r--r-- | FdsBlockFileHeader.cs | 2 | ||||
-rw-r--r-- | FdsDiskFile.cs | 32 | ||||
-rw-r--r-- | FdsDiskSide.cs | 40 | ||||
-rw-r--r-- | FdsFile.cs | 5 | ||||
-rw-r--r-- | IFdsBlock.cs | 1 | ||||
-rw-r--r-- | NesContainers.csproj | 4 | ||||
-rw-r--r-- | UnifFile.cs | 5 |
10 files changed, 123 insertions, 41 deletions
diff --git a/FdsBlockDiskInfo.cs b/FdsBlockDiskInfo.cs index c208b6b..c9c5b39 100644 --- a/FdsBlockDiskInfo.cs +++ b/FdsBlockDiskInfo.cs @@ -23,7 +23,52 @@ namespace com.clusterrr.Famicom.Containers }
public enum Country
{
- Japan = 0x49
+ Japan = 0x49,
+ }
+
+ public enum Manufacturer
+ {
+ Unlicensed = 0x00,
+ Nintendo = 0x01,
+ Capcom = 0x08,
+ Jaleco = 0x0A,
+ Hudson_Soft = 0x18,
+ Irem = 0x49,
+ Gakken = 0x4A,
+ BulletProof_Software = 0x8B,
+ PackInVideo = 0x99,
+ Tecmo = 0x9B,
+ Imagineer = 0x9C,
+ Scorpion_Soft = 0xA2,
+ Konami = 0xA4,
+ Kawada_Co = 0xA6,
+ Takara = 0xA7,
+ Royal_Industries = 0xA8,
+ Toei_Animation = 0xAC,
+ Namco = 0xAF,
+ ASCII_Corporation = 0xB1,
+ Bandai = 0xB2,
+ Soft_Pro_Inc = 0xB3,
+ HAL_Laboratory = 0xB6,
+ Sunsoft_and_Ask_Co = 0xBB,
+ Toshiba_EMI = 0xBC,
+ Taito = 0xC0,
+ Sunsoft = 0xC1,
+ Kemco = 0xC2,
+ Square = 0xC3,
+ Tokuma_Shoten = 0xC4,
+ Data_East = 0xC5,
+ Tonkin_House_and_Tokyo_Shoseki = 0xC6,
+ East_Cube = 0xC7,
+ Konami_and_Ultra_and_Palcom = 0xCA,
+ NTVIC_and_VAP = 0xCB,
+ Use_Co = 0xCC,
+ Pony_Canyon_and_FCI = 0xCE,
+ Sofel = 0xD1,
+ Bothtec_Inc = 0xD2,
+ Hiro_Co = 0xDB,
+ Athena = 0xE7,
+ Atlus = 0xEB,
}
[MarshalAs(UnmanagedType.U1)]
@@ -44,9 +89,9 @@ namespace com.clusterrr.Famicom.Containers [MarshalAs(UnmanagedType.U1)]
private byte manufacturerCode;
/// <summary>
- /// Manufacturer code. $00 = Unlicensed, $01 = Nintendo
+ /// Manufacturer code. = = 0x00, Unlicensed, = = 0x01, Nintendo
/// </summary>
- public byte ManufacturerCode { get => manufacturerCode; set => manufacturerCode = value; }
+ public Manufacturer ManufacturerCode { get => (Manufacturer)manufacturerCode; set => manufacturerCode = (byte)value; }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
char[] gameName;
@@ -58,9 +103,9 @@ namespace com.clusterrr.Famicom.Containers [MarshalAs(UnmanagedType.U1)]
char gameType;
/// <summary>
- /// $20 = " " — Normal disk
- /// $45 = "E" — Event(e.g.Japanese national DiskFax tournaments)
- /// $52 = "R" — Reduction in price via advertising
+ /// = = 0x20, " " — Normal disk
+ /// = = 0x45, "E" — Event(e.g.Japanese national DiskFax tournaments)
+ /// = = 0x52, "R" — Reduction in price via advertising
/// </summary>
public char GameType { get => gameType; set => gameType = value; }
@@ -88,13 +133,13 @@ namespace com.clusterrr.Famicom.Containers [MarshalAs(UnmanagedType.U1)]
byte diskType;
/// <summary>
- /// Disk type. $00 = FMC ("normal card"), $01 = FSC ("card with shutter"). May correlate with FMC and FSC product codes
+ /// Disk type. = = 0x00, FMC ("normal card"), = = 0x01, FSC ("card with shutter"). May correlate with FMC and FSC product codes
/// </summary>
public DiskTypes DiskType { get => (DiskTypes)diskType; set => diskType = (byte)value; }
[MarshalAs(UnmanagedType.U1)]
// Speculative: (Err.10) Possibly indicates disk #; usually $00
- // Speculative: $00 = yellow disk, $01 = blue or gold disk, $FE = white disk, $FF = blue disk
+ // Speculative: = = 0x00, yellow disk, = = 0x01, blue or gold disk, = = 0xFE, white disk, = = 0xFF, blue disk
byte unknown01 = 0x00;
[MarshalAs(UnmanagedType.U1)]
byte bootFile;
@@ -147,10 +192,10 @@ namespace com.clusterrr.Famicom.Containers }
[MarshalAs(UnmanagedType.U1)]
- // $49 = Japan
+ // = = 0x49, Japan
byte countryCode = (byte)Country.Japan;
/// <summary>
- /// Country code. $49 = Japan
+ /// Country code. = = 0x49, Japan
/// </summary>
public Country CountryCode { get => (Country)countryCode; set => countryCode = (byte)value; }
@@ -222,13 +267,13 @@ namespace com.clusterrr.Famicom.Containers [MarshalAs(UnmanagedType.U1)]
byte diskRewriteCount = 0x00;
/// <summary>
- /// Disk rewrite count. $00 = Original (no copies)
+ /// Disk rewrite count. = = 0x00, Original (no copies)
/// </summary>
public byte DiskRewriteCount
{
get
{
- return (byte)((diskRewriteCount & 0x0F) + ((diskRewriteCount >> 4) & 0x0F) * 10);
+ return (diskRewriteCount == 0xFF) ? (byte)0 : (byte)((diskRewriteCount & 0x0F) + ((diskRewriteCount >> 4) & 0x0F) * 10);
}
set
{
@@ -267,6 +312,8 @@ namespace com.clusterrr.Famicom.Containers /// </summary>
public bool EndOfHeadMeet { get => endOfHeadMeet; set => endOfHeadMeet = value; }
+ public uint Length => 56;
+
public static FdsBlockDiskInfo FromBytes(byte[] rawData, int position = 0)
{
int rawsize = Marshal.SizeOf(typeof(FdsBlockDiskInfo));
diff --git a/FdsBlockFileAmount.cs b/FdsBlockFileAmount.cs index 8858151..9ed5163 100644 --- a/FdsBlockFileAmount.cs +++ b/FdsBlockFileAmount.cs @@ -29,6 +29,8 @@ namespace com.clusterrr.Famicom.Containers /// </summary>
public bool EndOfHeadMeet { get; set; } = false;
+ public uint Length => 2;
+
public static FdsBlockFileAmount FromBytes(byte[] rawData, int position = 0)
{
var retobj = new FdsBlockFileAmount();
diff --git a/FdsBlockFileData.cs b/FdsBlockFileData.cs index 51345bd..c5ab761 100644 --- a/FdsBlockFileData.cs +++ b/FdsBlockFileData.cs @@ -33,6 +33,8 @@ namespace com.clusterrr.Famicom.Containers /// </summary>
public bool EndOfHeadMeet { get; set; } = false;
+ public uint Length => (uint)(data.Length + 1);
+
public static FdsBlockFileData FromBytes(byte[] rawData, int position = 0, int size = -1)
{
var retobj = new FdsBlockFileData();
diff --git a/FdsBlockFileHeader.cs b/FdsBlockFileHeader.cs index 99c301c..5db2c7f 100644 --- a/FdsBlockFileHeader.cs +++ b/FdsBlockFileHeader.cs @@ -65,6 +65,8 @@ namespace com.clusterrr.Famicom.Containers /// </summary>
public bool EndOfHeadMeet { get => endOfHeadMeet; set => endOfHeadMeet = value; }
+ public uint Length => 16;
+
public static FdsBlockFileHeader FromBytes(byte[] rawData, int position = 0)
{
int rawsize = Marshal.SizeOf(typeof(FdsBlockFileHeader));
diff --git a/FdsDiskFile.cs b/FdsDiskFile.cs index 3607d83..6ce92b3 100644 --- a/FdsDiskFile.cs +++ b/FdsDiskFile.cs @@ -10,37 +10,39 @@ namespace com.clusterrr.Famicom.Containers {
private FdsBlockFileHeader headerBlock;
private FdsBlockFileData dataBlock;
+ public FdsBlockFileHeader HeaderBlock { get => headerBlock; set => headerBlock = value; }
+ public FdsBlockFileData DataBlock { get => dataBlock; set => dataBlock = value; }
- public byte FileNumber { get => headerBlock.FileNumber; set => headerBlock.FileNumber = value; }
- public byte FileIndicateCode { get => headerBlock.FileIndicateCode; set => headerBlock.FileIndicateCode = value; }
- public string FileName { get => headerBlock.FileName; set => headerBlock.FileName = value; }
- public ushort FileAddress { get => headerBlock.FileAddress; set => headerBlock.FileAddress = value; }
- public ushort FileSize { get => (ushort)dataBlock.Data.Count(); }
- public FdsBlockFileHeader.Kind FileKind { get => headerBlock.FileKind; set => headerBlock.FileKind = value; }
+ public byte FileNumber { get => HeaderBlock.FileNumber; set => HeaderBlock.FileNumber = value; }
+ public byte FileIndicateCode { get => HeaderBlock.FileIndicateCode; set => HeaderBlock.FileIndicateCode = value; }
+ public string FileName { get => HeaderBlock.FileName; set => HeaderBlock.FileName = value; }
+ public ushort FileAddress { get => HeaderBlock.FileAddress; set => HeaderBlock.FileAddress = value; }
+ public ushort FileSize { get => (ushort)DataBlock.Data.Count(); }
+ public FdsBlockFileHeader.Kind FileKind { get => HeaderBlock.FileKind; set => HeaderBlock.FileKind = value; }
public IEnumerable<byte> Data
{
- get => dataBlock.Data;
+ get => DataBlock.Data;
set
{
- dataBlock.Data = value;
- headerBlock.FileSize = (ushort)dataBlock.Data.Count();
+ DataBlock.Data = value;
+ HeaderBlock.FileSize = (ushort)DataBlock.Data.Count();
}
}
public FdsDiskFile(FdsBlockFileHeader headerBlock, FdsBlockFileData dataBlock)
{
- this.headerBlock = headerBlock;
- this.dataBlock = dataBlock;
+ this.HeaderBlock = headerBlock;
+ this.DataBlock = dataBlock;
headerBlock.FileSize = (ushort)dataBlock.Data.Count();
}
public FdsDiskFile()
{
- this.headerBlock = new FdsBlockFileHeader();
- this.dataBlock = new FdsBlockFileData();
- headerBlock.FileSize = (ushort)dataBlock.Data.Count();
+ this.HeaderBlock = new FdsBlockFileHeader();
+ this.DataBlock = new FdsBlockFileData();
+ HeaderBlock.FileSize = (ushort)DataBlock.Data.Count();
}
- public byte[] ToBytes() => Enumerable.Concat(headerBlock.ToBytes(), dataBlock.ToBytes()).ToArray();
+ public byte[] ToBytes() => Enumerable.Concat(HeaderBlock.ToBytes(), DataBlock.ToBytes()).ToArray();
}
}
diff --git a/FdsDiskSide.cs b/FdsDiskSide.cs index 11f16d3..4d1af1f 100644 --- a/FdsDiskSide.cs +++ b/FdsDiskSide.cs @@ -9,12 +9,15 @@ namespace com.clusterrr.Famicom.Containers public class FdsDiskSide
{
FdsBlockDiskInfo diskInfoBlock;
-
+ /// <summary>
+ /// Disk info block
+ /// </summary>
+ public FdsBlockDiskInfo DiskInfoBlock { get => diskInfoBlock; }
public string DiskVerification { get => diskInfoBlock.DiskVerification; }
/// <summary>
/// Manufacturer code. $00 = Unlicensed, $01 = Nintendo
/// </summary>
- public byte ManufacturerCode { get => diskInfoBlock.ManufacturerCode; set => diskInfoBlock.ManufacturerCode = value; }
+ public FdsBlockDiskInfo.Manufacturer ManufacturerCode { get => diskInfoBlock.ManufacturerCode; set => diskInfoBlock.ManufacturerCode = value; }
/// <summary>
/// 3-letter ASCII code per game (e.g. ZEL for The Legend of Zelda)
/// </summary>
@@ -125,15 +128,23 @@ namespace com.clusterrr.Famicom.Containers pos += 2;
while (pos < data.Length)
{
- var fileHeaderBlock = FdsBlockFileHeader.FromBytes(data.Skip(pos).Take(16).ToArray());
- if (!fileHeaderBlock.IsValid)
- break;
- pos += 16;
- var fileDataBlock = FdsBlockFileData.FromBytes(data.Skip(pos).Take(fileHeaderBlock.FileSize + 1).ToArray());
- if (!fileDataBlock.IsValid)
+ try
+ {
+ var fileHeaderBlock = FdsBlockFileHeader.FromBytes(data.Skip(pos).Take(16).ToArray());
+ if (!fileHeaderBlock.IsValid)
+ break;
+ pos += 16;
+ var fileDataBlock = FdsBlockFileData.FromBytes(data.Skip(pos).Take(fileHeaderBlock.FileSize + 1).ToArray());
+ if (!fileDataBlock.IsValid)
+ break;
+ pos += fileHeaderBlock.FileSize + 1;
+ files.Add(new FdsDiskFile(fileHeaderBlock, fileDataBlock));
+ }
+ catch
+ {
+ // just break on out of range
break;
- pos += fileHeaderBlock.FileSize + 1;
- files.Add(new FdsDiskFile(fileHeaderBlock, fileDataBlock));
+ }
}
}
@@ -143,6 +154,15 @@ namespace com.clusterrr.Famicom.Containers files[i].FileNumber = (byte)i;
}
+ public IEnumerable<IFdsBlock> GetBlocks()
+ {
+ var blocks = new List<IFdsBlock>();
+ blocks.Add(diskInfoBlock);
+ blocks.Add(fileAmountBlock);
+ blocks.AddRange(files.SelectMany(f => new IFdsBlock[] { f.HeaderBlock, f.DataBlock }));
+ return blocks;
+ }
+
public static FdsDiskSide FromBytes(byte[] data)
{
return new FdsDiskSide(data);
@@ -26,7 +26,7 @@ namespace com.clusterrr.Famicom.Containers public FdsFile(byte[] data) : this()
{
- if (data[0] == (byte)'F' && data[1] == (byte)'D' && data[2] == (byte)'S')
+ if (data[0] == (byte)'F' && data[1] == (byte)'D' && data[2] == (byte)'S' && data[3] == 0x1A)
data = data.Skip(16).ToArray(); // skip header
for (int i = 0; i < data.Length; i += 65500)
{
@@ -54,7 +54,8 @@ namespace com.clusterrr.Famicom.Containers header[0] = (byte)'F';
header[1] = (byte)'D';
header[2] = (byte)'S';
- header[3] = (byte)sides.Count();
+ header[3] = 0x1A;
+ header[4] = (byte)sides.Count();
data = Enumerable.Concat(header, data);
}
return data.ToArray();
diff --git a/IFdsBlock.cs b/IFdsBlock.cs index e8ec78d..6171d65 100644 --- a/IFdsBlock.cs +++ b/IFdsBlock.cs @@ -12,6 +12,7 @@ namespace com.clusterrr.Famicom.Containers bool IsValid { get; }
bool CrcOk { get; set; }
bool EndOfHeadMeet { get; set; }
+ uint Length { get; }
byte[] ToBytes();
}
}
diff --git a/NesContainers.csproj b/NesContainers.csproj index 089048c..56b8ae4 100644 --- a/NesContainers.csproj +++ b/NesContainers.csproj @@ -43,9 +43,9 @@ </ItemGroup>
<ItemGroup>
<Compile Include="Crc32Calculator.cs" />
- <Compile Include="FdsFile.cs" />
+ <Compile Include="FdsDiskFile.cs" />
<Compile Include="FdsDiskSide.cs" />
- <Compile Include="FdsGame.cs" />
+ <Compile Include="FdsFile.cs" />
<Compile Include="IFdsBlock.cs" />
<Compile Include="FdsBlockDiskInfo.cs" />
<Compile Include="FdsBlockFileAmount.cs" />
diff --git a/UnifFile.cs b/UnifFile.cs index 0e9606e..f6d586c 100644 --- a/UnifFile.cs +++ b/UnifFile.cs @@ -54,6 +54,11 @@ namespace com.clusterrr.Famicom.Containers {
}
+ public static UnifFile FromBytes(byte[] data)
+ {
+ return new UnifFile(data);
+ }
+
/// <summary>
/// Save UNIF file
/// </summary>
|