Pissing about with TZX support

This commit is contained in:
2026-05-01 20:02:18 +01:00
parent 8efcf00286
commit b1e7210e95
7 changed files with 277 additions and 23 deletions

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using static Core.Io.TurboSpeedBlock;
namespace Core.Io
{
@@ -65,6 +66,66 @@ namespace Core.Io
blocks.Add(turboBlock);
break;
case 0x12: // Pure Tone Block
blocks.Add(new PureToneBlock
{
PulseLength = br.ReadUInt16(),
PulseCount = br.ReadUInt16()
});
break;
case 0x13: // Pulse Sequence Block
var seqBlock = new PulseSequenceBlock();
byte rawCount = br.ReadByte();
// TZX Spec: A raw count of 0 means 256 pulses!
seqBlock.PulseCount = (rawCount == 0) ? 256 : rawCount;
seqBlock.Pulses = new ushort[seqBlock.PulseCount];
for (int i = 0; i < seqBlock.PulseCount; i++)
{
seqBlock.Pulses[i] = br.ReadUInt16();
}
blocks.Add(seqBlock);
break;
case 0x14: // Pure Data Block
var pureData = new PureDataBlock
{
ZeroBitPulseLength = br.ReadUInt16(),
OneBitPulseLength = br.ReadUInt16(),
UsedBitsInLastByte = br.ReadByte(),
PauseAfterMs = br.ReadUInt16()
};
// Assemble the 24-bit length
byte pdLen0 = br.ReadByte();
byte pdLen1 = br.ReadByte();
byte pdLen2 = br.ReadByte();
pureData.DataLength = pdLen0 | (pdLen1 << 8) | (pdLen2 << 16);
pureData.Data = br.ReadBytes(pureData.DataLength);
blocks.Add(pureData);
break;
case 0x20: // Pause / Stop Tape Block
blocks.Add(new PauseBlock { PauseDurationMs = br.ReadUInt16() });
break;
case 0x21: // Group Start Block
byte groupNameLength = br.ReadByte();
string groupName = System.Text.Encoding.ASCII.GetString(br.ReadBytes(groupNameLength));
blocks.Add(new GroupStartBlock { GroupName = groupName });
break;
case 0x22: // Group End Block
// This block has no payload data at all! Just the ID.
blocks.Add(new GroupEndBlock());
break;
case 0x30: // Text Description Block
byte textLength30 = br.ReadByte();
string description = System.Text.Encoding.ASCII.GetString(br.ReadBytes(textLength30));
blocks.Add(new TextDescriptionBlock { Description = description });
break;
case 0x32: // Archive Info Block
var archiveBlock = new ArchiveInfoBlock();
@@ -76,10 +137,10 @@ namespace Core.Io
for (int i = 0; i < stringCount; i++)
{
byte textId = br.ReadByte();
byte textLength = br.ReadByte();
byte textLength32 = br.ReadByte();
// Read the raw bytes and convert them to an ASCII string
string text = System.Text.Encoding.ASCII.GetString(br.ReadBytes(textLength));
string text = System.Text.Encoding.ASCII.GetString(br.ReadBytes(textLength32));
archiveBlock.Metadata[textId] = text;
}