BizHawk/BizHawk.Emulation.DiscSystem/Internal/Jobs/LoadSBIJob.cs

81 lines
2.3 KiB
C#

using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using BizHawk.Common.IOExtensions;
namespace BizHawk.Emulation.DiscSystem.SBI
{
/// <summary>
/// Loads SBI files into an internal representation.
/// </summary>
class LoadSBIJob : DiscJob
{
/// <summary>
/// The file to be loaded
/// </summary>
public string IN_Path;
/// <summary>
/// The resulting interpreted data
/// </summary>
public SubQPatchData OUT_Data;
public void Run()
{
using (var fs = File.OpenRead(IN_Path))
{
BinaryReader br = new BinaryReader(fs);
string sig = br.ReadStringFixedAscii(4);
if (sig != "SBI\0")
throw new SBIParseException("Missing magic number");
SubQPatchData ret = new SubQPatchData();
List<short> bytes = new List<short>();
//read records until done
for (; ; )
{
//graceful end
if (fs.Position == fs.Length)
break;
if (fs.Position + 4 > fs.Length) throw new SBIParseException("Broken record");
var m = BCD2.BCDToInt(br.ReadByte());
var s = BCD2.BCDToInt(br.ReadByte());
var f = BCD2.BCDToInt(br.ReadByte());
var ts = new Timestamp(m, s, f);
ret.ABAs.Add(ts.Sector);
int type = br.ReadByte();
switch (type)
{
case 1: //Q0..Q9
if (fs.Position + 10 > fs.Length) throw new SBIParseException("Broken record");
for (int i = 0; i <= 9; i++) bytes.Add(br.ReadByte());
for (int i = 10; i <= 11; i++) bytes.Add(-1);
break;
case 2: //Q3..Q5
if (fs.Position + 3 > fs.Length) throw new SBIParseException("Broken record");
for (int i = 0; i <= 2; i++) bytes.Add(-1);
for (int i = 3; i <= 5; i++) bytes.Add(br.ReadByte());
for (int i = 6; i <= 11; i++) bytes.Add(-1);
break;
case 3: //Q7..Q9
if (fs.Position + 3 > fs.Length) throw new SBIParseException("Broken record");
for (int i = 0; i <= 6; i++) bytes.Add(-1);
for (int i = 7; i <= 9; i++) bytes.Add(br.ReadByte());
for (int i = 10; i <= 11; i++) bytes.Add(-1);
break;
default:
throw new SBIParseException("Broken record");
}
}
ret.subq = bytes.ToArray();
OUT_Data = ret;
}
}
}
}