TZX tape format handling re-write nearly complete (supporting advanced protection/loader schemes)
This commit is contained in:
parent
42b5f5dc5d
commit
b9729d0dc2
|
@ -281,6 +281,7 @@
|
|||
<Compile Include="Computers\SinclairSpectrum\Media\Tape\TapeCommand.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Media\Tape\TapeDataBlock.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Media\Tape\TapSerializer.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Media\Tape\TzxSerializer.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\SoundProviderMixer.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\MachineType.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.cs" />
|
||||
|
|
|
@ -233,12 +233,25 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="tapeData"></param>
|
||||
public void LoadTape(byte[] tapeData)
|
||||
{
|
||||
// attempt TZX deserialization
|
||||
TzxSerializer tzxSer = new TzxSerializer(this);
|
||||
try
|
||||
{
|
||||
tzxSer.DeSerialize(tapeData);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TAP format not detected
|
||||
var e = ex;
|
||||
}
|
||||
|
||||
// attempt TAP deserialization
|
||||
TapSerializer tapSer = new TapSerializer(this);
|
||||
|
||||
try
|
||||
{
|
||||
tapSer.DeSerialize(tapeData);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="buf"></param>
|
||||
/// <param name="offsetIndex"></param>
|
||||
/// <returns></returns>
|
||||
protected static ushort GetUInt16(byte[] buf, int offsetIndex)
|
||||
protected static ushort GetWordValue(byte[] buf, int offsetIndex)
|
||||
{
|
||||
return (ushort)(buf[offsetIndex] | buf[offsetIndex + 1] << 8);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="buf"></param>
|
||||
/// <param name="offsetIndex"></param>
|
||||
/// <param name="value"></param>
|
||||
protected static void setUint16(byte[] buf, int offsetIndex, ushort value)
|
||||
protected static void SetWordValue(byte[] buf, int offsetIndex, ushort value)
|
||||
{
|
||||
buf[offsetIndex] = (byte)value;
|
||||
buf[offsetIndex + 1] = (byte)(value >> 8);
|
||||
|
|
|
@ -126,6 +126,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
checksum (checkbittoggle would be a better name!).............^^
|
||||
*/
|
||||
|
||||
// clear existing tape blocks
|
||||
_datacorder.DataBlocks.Clear();
|
||||
|
||||
// convert bytearray to memory stream
|
||||
MemoryStream stream = new MemoryStream(data);
|
||||
|
@ -174,7 +176,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
}
|
||||
|
||||
// process the flag byte
|
||||
// process the type byte
|
||||
/* (The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file.
|
||||
A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal.
|
||||
If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given)
|
||||
|
@ -206,9 +208,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(type + ": ");
|
||||
sb.Append(fileName + " ");
|
||||
sb.Append(GetUInt16(blockdata, 14));
|
||||
sb.Append(GetWordValue(blockdata, 14));
|
||||
sb.Append(":");
|
||||
sb.Append(GetUInt16(blockdata, 12));
|
||||
sb.Append(GetWordValue(blockdata, 12));
|
||||
description = sb.ToString();
|
||||
}
|
||||
else if (blockdata[0] == 0xFF)
|
||||
|
@ -223,7 +225,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
description += string.Format(", crc {0}", ((crc != 0) ? string.Format("bad (#{0:X2}!=#{1:X2})", crcFile, crcValue) : "ok"));
|
||||
}
|
||||
|
||||
tdb.BlockDescription = description;
|
||||
tdb.BlockDescription = BlockType.Standard_Speed_Data_Block;
|
||||
|
||||
// calculate the data periods for this block
|
||||
int pilotLength = 0;
|
||||
|
|
|
@ -19,17 +19,28 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public int BlockID
|
||||
{
|
||||
get { return _blockID; }
|
||||
set { _blockID = value; }
|
||||
set {
|
||||
_blockID = value;
|
||||
|
||||
if (MetaData == null)
|
||||
MetaData = new Dictionary<BlockDescriptorTitle, string>();
|
||||
|
||||
AddMetaData(BlockDescriptorTitle.Block_ID, value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Description of the block
|
||||
/// The block type
|
||||
/// </summary>
|
||||
private string _blockDescription;
|
||||
public string BlockDescription
|
||||
private BlockType _blockType;
|
||||
public BlockType BlockDescription
|
||||
{
|
||||
get { return _blockDescription; }
|
||||
set { _blockDescription = value; }
|
||||
get { return _blockType; }
|
||||
set {
|
||||
_blockType = value;
|
||||
if (MetaData == null)
|
||||
MetaData = new Dictionary<BlockDescriptorTitle, string>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -42,6 +53,63 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
set { _blockData = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An array of bytearray encoded strings (stored in this format for easy Bizhawk serialization)
|
||||
/// Its basically tape information
|
||||
/// </summary>
|
||||
private byte[][] _tapeDescriptionData;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Tape Description Data in a human readable format
|
||||
/// </summary>
|
||||
public List<string> TapeDescriptionData
|
||||
{
|
||||
get
|
||||
{
|
||||
List<string> data = new List<string>();
|
||||
|
||||
foreach (byte[] b in _tapeDescriptionData)
|
||||
{
|
||||
data.Add(Encoding.ASCII.GetString(b));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Block Meta Data
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of block related data
|
||||
/// </summary>
|
||||
public Dictionary<BlockDescriptorTitle, string> MetaData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single metadata item to the Dictionary
|
||||
/// </summary>
|
||||
/// <param name="descriptor"></param>
|
||||
/// <param name="data"></param>
|
||||
public void AddMetaData(BlockDescriptorTitle descriptor, string data)
|
||||
{
|
||||
// check whether entry already exists
|
||||
bool check = MetaData.ContainsKey(descriptor);
|
||||
if (check)
|
||||
{
|
||||
// already exists - update
|
||||
MetaData[descriptor] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create new
|
||||
MetaData.Add(descriptor, data);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// List containing the pulse timing values
|
||||
/// </summary>
|
||||
|
@ -92,7 +160,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ser.BeginSection("DataBlock" + blockPosition);
|
||||
|
||||
ser.Sync("_blockID", ref _blockID);
|
||||
ser.SyncFixedString("_blockDescription", ref _blockDescription, 50);
|
||||
//ser.SyncFixedString("_blockDescription", ref _blockDescription, 200);
|
||||
ser.SyncEnum("_blockType", ref _blockType);
|
||||
ser.Sync("_blockData", ref _blockData, true);
|
||||
ser.SyncEnum("_command", ref _command);
|
||||
|
||||
|
@ -112,4 +181,84 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ser.EndSection();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The types of TZX blocks
|
||||
/// </summary>
|
||||
public enum BlockType
|
||||
{
|
||||
Standard_Speed_Data_Block = 0x10,
|
||||
Turbo_Speed_Data_Block = 0x11,
|
||||
Pure_Tone = 0x12,
|
||||
Pulse_Sequence = 0x13,
|
||||
Pure_Data_Block = 0x14,
|
||||
Direct_Recording = 0x15,
|
||||
CSW_Recording = 0x18,
|
||||
Generalized_Data_Block = 0x19,
|
||||
Pause_or_Stop_the_Tape = 0x20,
|
||||
Group_Start = 0x21,
|
||||
Group_End = 0x22,
|
||||
Jump_to_Block = 0x23,
|
||||
Loop_Start = 0x24,
|
||||
Loop_End = 0x25,
|
||||
Call_Sequence = 0x26,
|
||||
Return_From_Sequence = 0x27,
|
||||
Select_Block = 0x28,
|
||||
Stop_the_Tape_48K = 0x2A,
|
||||
Set_Signal_Level = 0x2B,
|
||||
Text_Description = 0x30,
|
||||
Message_Block = 0x31,
|
||||
Archive_Info = 0x32,
|
||||
Hardware_Type = 0x33,
|
||||
Custom_Info_Block = 0x35,
|
||||
Glue_Block = 0x5A,
|
||||
|
||||
// depreciated blocks
|
||||
C64_ROM_Type_Data_Block = 0x16,
|
||||
C64_Turbo_Tape_Data_Block = 0x17,
|
||||
Emulation_Info = 0x34,
|
||||
Snapshot_Block = 0x40,
|
||||
|
||||
// unsupported / undetected
|
||||
Unsupported
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Different title possibilities
|
||||
/// </summary>
|
||||
public enum BlockDescriptorTitle
|
||||
{
|
||||
Undefined,
|
||||
Block_ID,
|
||||
Program,
|
||||
Data_Bytes,
|
||||
Bytes,
|
||||
|
||||
Pilot_Pulse_Length,
|
||||
Pilot_Pulse_Count,
|
||||
First_Sync_Length,
|
||||
Second_Sync_Length,
|
||||
Zero_Bit_Length,
|
||||
One_Bit_Length,
|
||||
Data_Length,
|
||||
Bits_In_Last_Byte,
|
||||
Pause_After_Data,
|
||||
|
||||
Pulse_Length,
|
||||
Pulse_Count,
|
||||
|
||||
Text_Description,
|
||||
Title,
|
||||
Publisher,
|
||||
Author,
|
||||
Year,
|
||||
Language,
|
||||
Type,
|
||||
Price,
|
||||
Protection,
|
||||
Origin,
|
||||
Comments,
|
||||
|
||||
Needs_Parsing
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue