﻿# CSW2CDT -- http://cngsoft.no-ip.org/csw2cdt.htm #

	  //@@@@  //@@@@@ //@@ //@@ //@@@@   //@@@@ //@@@@@  //@@@@@@
	 //@@//@@//@@ //@@//@@ //@@//@@//@@ //@@//@@ //@@/@@ //@/@@/@
	//@@     //@@     //@@ //@@    //@@//@@      //@@//@@  //@@
	//@@      //@@@@@ //@@/@/@@ //@@@@ //@@      //@@//@@  //@@
	//@@          //@@//@@@@@@@//@@    //@@      //@@//@@  //@@
	 //@@//@@//@@ //@@//@@@/@@@//@@//@@ //@@//@@ //@@/@@   //@@
	  //@@@@  //@@@@@ //@@ //@@//@@@@@@  //@@@@ //@@@@@   //@@@@

	encoder-decoder of CSW audio and TZX 8-bit computer tape data
			by Cesar Nicolas-Gonzalez

## Foreword ##

CSW2CDT is a cross-platform encoder-decoder of CSW (v1) 1-bit sample files and
CDT/TZX (v1+) tape files. Its purpose is the preservation of single-bit computer
tapes in general and 8-bit home computer tapes in particular, with emphasis on
the Amstrad CPC and the Sinclair Spectrum, and their shared CDT/TZX tape file
format, but also able to encode and decode TSX tapes from the MSX platform; the
PZX tape format, a middle point between CSW and CDT/TZX, is secondarily
supported as well. Its companion tool CSW0 is an encoder-decoder of RIFF WAVE
audio files and CSW (v1) files; both encoders can thus work together to encode
extant tapes into tape files, and to decode these files back into audio than can
be recorded on real tapes or fed to computers and emulators alike.

Software and documentation are provided "as is" with no warranty. The source
code of CSW2CDT and its binaries follow the GNU General Public License v3, as
seen in the file GPL.TXT within the package.

## How to use ##

Both CSW2CDT and CSW0 rely on the standard C library, so they don't need any
extra libraries to compile and run.

The general idea of turning a source tape into a fully encoded CDT/TZX file is
to be done in three steps: first, the tape must be sampled into an audio file;
second, CSW0 will read that audio file and encode its contents into a partially
processed CSW file; third, CSW2CDT will take the CSW file from the second step
and parse its data into a fully processed CDT/TZX file that can be examined with
editors and fed to emulators. Because noise is a problem in tapes (and even more
so as they age and grow old) each stage may need the user to perform multiple
retries with different parameters, until the resulting files are good enough to
move on to the next stage.

Similarly, the reverse procedure of decoding an extant CDT/TZX file starts by
feeding said file to CSW2CDT, who will decode it into a CSW file, and continues
by feeding the resulting CSW file to CSW0, who will encode it into a WAV file
that can be recorded on a tape or played back on a real machine or an emulator.

Both operations may require user input: removing noise following certain
parameters, stating a particular type of tape encoding, etc.

The package also includes CSW2CDT-UI, a Windows binary that simplifies parts of
the work by hiding the command line operations: the user can select files and
options on a dialog instead of having to type commands and paths in full. The
procedures stay the same, however, so the following episodes about CSW0 and
CSW2CDT apply to CSW2CDT-UI as well.

## from WAV to CSW and back: CSW0 ##

The command line syntax of CSW0 is as follows:

	csw0 [-f L H] [-m N] [-e N] [-l|r] [-t N] [-n] [--M1:S1 M2:S2] source
[target]

When the source path is a RIFF WAVE file (default extension is ".wav"), the
target path will be a CSW v1 file (default extension is ".csw"), and vice versa,
when the source is a CSW file, the target will be a WAV file; if the target is
missing, it will be generated by taking the source and swapping its extension.

The parameter "-t N" is limited to CSW-to-WAV decoding: it sets the signal
shape, ranging from 0 (perfectly square) to 100 (perfectly triangular).

All the other parameters are used in the WAV-to-CSW encoding:

* -f L H : enable pass-band filter, in Hz. The pass-band filter's lower bound is
the integer L, while its upper bound is the integer H. When one of the bounds is
zero, the filter will become either lo-pass (L = 0) or hi-pass (H = 0). The
filters can help remove noise from the signal, but they also can remove
legitimate signal from the sample.
* -m N : set middle point between -127 and 127. Samples are effectively handled
as signed 8-bit values where 0 is the middle point. However, some tapes may not
be pegged to such value; this option lets the user set the required middle point
value.
* -e N : set error margin between 0 and 127. The higher the value, the less
sensible the 8-to-1-bit conversion will be to signal variations within the error
margin.
* -l : left channel only. Ignored if the source is mono.
* -r : right channel only. Ignored if the source is mono, too.
* --M1:S1 M2:S2 : clip from M1 min S1 sec to M2 min S2 sec. This lets the user
set where in the source to start processing the signal (M1:S1, minutes:seconds)
and where to end (M2:S2). Notice that M1 and M2 are optional: time marks can be
defined as seconds, --S1 S2.

Finally, the parameter "-n" impacts both encoding and decoding: it negates the
output polarity, a trait that some tape encodings rely on (see below).

## from CSW to CDT/TZX and back: CSW2CDT ##

The command line syntax of CSW2CDT is as follows:

	csw2cdt [-0|1|4|5|8] [-b] [-y] [-Y] [-x] [-X] [-l F] [-L] [-Z] [-e N]
[-c N] [-C N] [-m N] [-p N] [-P N] [-t N] [-z N] [-r N] [-w N] [--TYPE] [--MM:SS
TYPE] [-f N] source [target]

As in CSW0, when the source path is a CSW file, the target path will be a
CDT/TZX file (default extension is ".cdt"), and vice versa, when the source is a
CDT/TZX file the target will be a CSW file. Again, if the target is missing, it
will be generated by taking the source and swapping its extension.

The parameter "-f N" is limited to CDT/TZX-to-CSW decoding: it sets the output
sample rate in Hz, 44100 by default.

All the other parameters belong to the CSW-to-CDT/TZX encoding. Five options
control the behavior of the encoder when the last bits in a block bitstream
don't fill a whole byte:

* -0 : pad all incomplete bytes with 0s. All bytes with one to seven bits will
be padded.
* -1 : pad all incomplete bytes with 1s. Ditto.
* -4 : clip or pad incomplete bytes with 0s. Bytes with four to seven bits will
be padded; those with one to three bits will be clipped.
* -5 : clip or pad incomplete bytes with 1s. Ditto.
* -8 : clip all incomplete bytes. All bytes with one to seven bits will be
clipped.

The remaining options control the operations of detection and encoding:

* -b : force BIT1:BIT0 = 2. The BIT1 signal is twice as long as BIT0 in most
tapes, although not always; noisy or distorted tapes may need this parameter.
* -y : force SYNC1 = SYNC2. Ditto, the lengths of the SYNC edges are often equal
or similar to each other, but not always; this parameter may help against noise
and distortion.
* -Y : allow TONE < SYNC. The sheer majority of tape encodings rely on long TONE
edges and short SYNC edges, but there are some that rely on short tones and long
syncs. This parameter enables their detection.
* -x : TZX 1.00 compatible mode. CSW2CDT normally generates TZX 1.20 blocks, but
some emulators are limited to the TZX 1.00 block set.
* -X : show block count in log file. The first field of the log file normally
shows timestamps (in minutes and seconds) rather than the block count.
* -l F : set log file path ('-' for stdout). CSW2CDT describes the encoded data
as a human-readable list of blocks; by default, this list is stored as a log
file named after the target plus the extension ".log", and this option lets the
user set a different log file or use the console output instead.
* -L : abridge TONE+SYNC blocks in log file. Complex tapes can generate heavy
log files even when the amount of actual data is small; this option merges
together consecutive TONE and SYNC entries into a single PULSES log entry.
* -Z : store BLOCK $10 as BLOCK $10 instead. A shortcut of "-z 0".
* -e N : frequency bias. Due to bad storage or bad sampling, some tapes may
become shorter and sped-up or longer and slowed-down. This value adjusts the
tape frequency, ranging from 1 (heavy slow down) to 9 (heavy speed up).
* -c N : minimum sample size of edges. Length of the shortest valid edge in
samples: any edges shorter than this value will be merged together with their
immediately neighbouring edges into a single edge.
* -C N : positive/negative edges bias. Tapes where positive edges are stronger
than the negative ones (or vice versa) may benefit from modifying this value;
its default value (5) assumes no bias, values below 5 (down to 1) or above 5 (up
to 9) will tweak the positive/negative bias.
* -m N : minimum SYNC:TONE percentage. Percentage of the minimum SYNC:TONE
ratio, used to tell where the pilot tone ends and the data bits begin. The
higher the value, the more strict the tests; resulting in false negatives (i.e.
valid data will be deemed noise and rejected) if the value is too high, and
false positives (i.e. noise will be deemed valid data and accepted) if it's too
low.
* -p N : minimum amount of tone edges. Length in edges of the shortest valid
pilot tone: some custom tape formats have overly short pilot tones, for example
the Alkatraz encoding used by multiple games from U.S. Gold for Sinclair
Spectrum and Amstrad CPC.
* -P N : minimum amount of data edges. Length in edges of the shortest valid
data block: some custom tapes feature overly short data blocks, for example
"Dragon Ninja" for Amstrad CPC where the levels are tagged with a single-byte
(16 edges) data block.
* -t N : minimum BIT0:BIT1 percentage. Typical tapes use a 1:2 ratio, but some
need more (or less) leeway when telling bits apart. When this value is too high,
data blocks will lose valid yet noisy bits and become truncated; when it's too
low, blocks grow will longer than expected as .
* -z N : minimum BLOCK $10 percentage. The default encoding used in Sinclair
Spectrum tapes has its own block in the TZX format and the encoder will use it
instead of the more flexible BLOCK $11 if the detected traits of the block are
sufficiently similar to the ones implied by BLOCK $10: the higher the
percentage, the more likely a BLOCK $11 part will be encoded as BLOCK $10. N can
be zero: the encoder won't output any BLOCK $10.
* -r N : force odd (1) or even (2) pilot tone. Some encodings (for example those
used by Gremlin Graphics in "Basil the Great Mouse Detective") are sensible to
the actual output sign, rather than merely measuring the time between two output
sign changes. This option lets the user manually set the block's polarity.
* -w N : current encoding fine-tune (see below)
* --TYPE : the main type of data encoding used in the tape: running CSW2CDT
without parameters lists the currently available types. Detection of typical
"tone-sync-bits" blocks is generally automatic, but other blocks are either
unusual in their structure (for example the Unilode encoding has no "tone" or
"sync" stages: it starts right at "bits") or in their contents (for example the
Microkey encoding stores the first 8 bits in the "bits" stage at 1000 baud, but
all the remaining bits are stored at 2000 baud). Because these unusual traits
cannot be guessed in advance, the automatic encoding will fail and the user will
have to state the tape type.
* --MM:SS TYPE : enable encoding TYPE after MM min SS sec. Several encoding
types can be specified; each one will take over when the encoder reaches their
MM:SS (minutes:seconds) time mark.

The currently supported encoding types are described as follows:

* alkatraz : the encoding of many games released by U.S. Gold and related
companies. It often shows a smoothly animated three-digit countdown on the title
screen. Its "tone-sync-bits" method relies on a very short pilot tone, high
bitrates and encrypted data.
* amstrad : the default encoding used in Amstrad CPC tapes. it's a typical
tone-sync-bits method where 1.- the tone edges are identical to the BIT1 edges,
2.- the sync edges are identical to the BIT0 edges, 3.- BIT1 edges are twice as
long as BIT0 edges, and 4.- the bitstream is made of 1 ID byte followed by
strings of 256 bytes and 16-bit CCITT checksums. In normal cases this type can
be automatically handled by the encoder, but some cases may require the user to
state this type.
* bleepload1 : the encoding of early games released by Firebird on Amstrad CPC:
"Chimera", "Spiky Harold", "Thrust", "The Willow Pattern"... The method uses
nonstandard single edges instead of typical double edges, and it lacks the
"tone" and "sync" stages. It often includes a similarly nonstandard musical part
where the computer plays a song after the title screen, while the game proper
loads.
* bleepload2 : the encoding of late games released by Firebird on Amstrad CPC,
such as "Bubble Bobble" and "The Sentinel", or rereleases of early titles such
as "Thrust". The method is more typical than Bleepload1 (standard double edges,
"tone-sync-bits" stages) although it sometimes includes a not-so-standard
musical part, for example "Bomb Scare", "Booty" and "Druid".
* carsoncity : the encoding of just one French game, "Carson City". It unusually
uses short tone edges and long sync edges and relies on fixed polarity; it also
lacks pauses between most blocks, leading to glued data.
* cassys : the encoding of several games developed by Electric Dreams: "Mermaid
Madness", "Tempest", "Wonder Boy".... It shares some traits with the Amstrad
encoding (tone and BIT1 are the same length, SYNC and BIT0 are the same length,
BIT1 is twice as long as BIT0) but they're otherwise incompatible with each
other.
* ehservices : the encoding of CPC-only games released by EH Services, later
known as Titus: "One", "The Blues Brothers", "Wild Streets"... The method is
unusual: it uses both single and double edges, and each bit is encoded with
either a long edge or two short edges.
* frankbruno : the encoding of at least one CPC game from Elite: "Frank Bruno's
Boxing". It's nonstandard: instead of two sync edges and a bitstream of double
edges, it features 32 sync edges and a bitstream of single edges.
* gremlin1 : the encoding of several CPC games released by Gremlin Graphics:
"Basil the Great Mouse Detective", "Mickey Mouse", "Skate Crazy"... It's unusual
because it relies on fixed polarity: if the tape deck flips the output sign, the
tape will fail to load.
	* "-w 1" tells the encoder to encode the Spectrum version of "Basil the
Great Mouse Detective", the only known tape using this method on Spectrum, and
slightly different to its CPC counterpart.
* gremlin2 : the encoding of other CPC games released by Gremlin Graphics:
"Impossamole", "Mask", "Samurai Trilogy"... It divides the bitstream into many
small sub-blocks interleaved with strings of edges.
	* "-w 1" tells the encoder to encode the Spectrum version of "Mask", the
only known tape using this method on Spectrum, also slightly different to its
CPC counterpart.
* hexagon : the encoding of several late multi-loading games: "Alien Storm",
"Gauntlet 3", "Super Monaco GP"... It's similar to Alkatraz in that it features
high bitrates and encrypted data.
* kansas : the default encoding of MSX tapes. By default, CSW2CDT will encode it
into Kansas City Standard blocks (BLOCK $4B) if the target file format is TSX
rather than CDT/TZX or PZX.
* keytone : the encoding used in several CPC games ("Dragontorc", "Killer Ring",
"They Stole a Million"...) where most of the tape is unprotected, but the datas
within are encrypted, and the decryption key is stored in either a tiny data
block or a couple of tones.
* maubeuge : the encoding of two CPC-only French text adventure games
("Marmelade" and "Rat Connection"). It features a decryption tone after the
loader, and the protected block lacks the "tone" and "sync" stages.
* microkey : the encoding of several CPC games ("Bobsleigh", "Tomahawk", Steve
Evans' "Z"...). It's similar to the Amstrad encoding, but the first 8 bits in
the bitstream are recorded at half the bitrate of the following data.
* operasoft : the encoding of most games for CPC from Opera Soft ("Goody",
"Mutan Zone", "Sol Negro"...). It lacks the "tone" and "sync" stages, and relies
on fixed polarity. Early releases had no checksum at all; late releases feature
a 16-bit checksum.
* poliload : the encoding of several late games from Dinamic, in some cases
featuring a simple Mastermind-like game playing while the game proper loads:
"AMC", "Rescate Atlantida"... The giant blocks are actually many small
"tone-sync-bits" blocks glued together, without pauses inbetween.
* puffyssaga : the encoding of Ubi Soft's CPC-only "Puffy's Saga" (both the game
and its levels) and "Skateball". It lacks the "tone" and "sync" stages.
* ricochet : the encoding of most games released (or rereleased) under the
Ricochet budget label: "Octoplex", "Pinball Power"... Blocks often come in pairs
(a header and a body) glued together; the encoding itself is a modified clone of
the Spectrum encoding, with bitrates between 90% and 110%.
* spectrum : the default encoding in Spectrum tapes. It's the method that almost
all other methods plagiarised or at least imitated: the "tone-sync-bits" stages
and the bitstreams' first 1-byte ID and final 1-byte checksum (actually a parity
check) stem from here. It also appears in many CPC games, for example the
original Spanish releases of many titles from Topo Soft: "Desperado", "Mad Mix
Game", "Stardust"... In normal cases this encoding is automatically handled by
the encoder, but some tapes may need the user to state this type.
* specvar0 : a sped-down (87%) clone of the Spectrum encoding, seen in titles
from Elite such as "Supertrux".
* specvar1 : a sped-up (120%) clone of the Spectrum encoding, seen in titles
from Gremlin ("Gauntlet", "Mask III"...) and Grandslam ("Pacmania",
"Thunderbirds"...)
* specvar2 : a sped-up (133%) clone of the Spectrum encoding, seen in many CPC
games from Dinamic: "Abu Simbel Profanation", "After the War", "Camelot
Warriors"...
* speedlock0 : the original version of the Speedlock protection, used in the
first release of the Spectrum game "Daley Thompson's Decathlon". The "tone" and
"sync" stages are complex interleaved strings of tones and edges, and the
bitrate is 2000 baud.
* speedlock1 : an early revision of Speedlock for Spectrum: "Bounty Bob Strikes
Back", "Highway Encounter"...
* speedlock2 : an early revision of Speedlock for CPC: "Arkanoid", "Batman",
"Donkey Kong", "Highway Encounter"...
	* "-w N" is used here to state that the block ID is 8 bits at the N-th
block: for example "-w 1" is required to encode side B of "Super Cycle" for CPC,
as the level blocks carry 8-bit block IDs instead of 5-bit.
* speedlock3 : a later revision of Speedlock for Spectrum: "Alien Highway",
"Leviathan", "Head over Heels", "Tarzan"... The bitstream is now divided in
variable-sized chunks and 42-edge separators, and a timer (in minutes, seconds
and decimals, unlike the three-digit countdown from Alkatraz tapes) appears on
the title screen.
* speedlock4 : a later revision of Speedlock for CPC: "Combat School", "Gryzor",
"Renegade", "Tarzan"...
	* "-w N" is used here to state that the encoding changes to "speedlock2"
at the N-th block: for example "-w 4" is used by "Nigel Mansell's Grand Prix"
for CPC because the levels carry 8-bit IDs instead of 5-bit.
* speedlock5 : another revision of Speedlock for Spectrum: "Athena", "Combat
School", "Wizball"... The "tone" and "sync" stages are straightforward; a timer
appears on the title screen.
* speedlock6 : the last revision of Speedlock for CPC: "Arkanoid II - Revenge of
Doh", "Operation Wolf", "The Untouchables"... The bitrate drops to 1600 baud.
* speedlock7 : the last revision of Speedlock for Spectrum: "Operation Wolf",
the 128K-compatible rerelease of "Daley Thompson's Decathlon"... The "tone" and
"sync" stages are straightforward; the bitrate drops to 1600 baud; a timer
appears on the title screen.
* unilode : the encoding of several games released by Oxford Digital and Domark:
"Sailing", "Trivial Pursuit", "Yes Prime Minister"... It lacks the "tone" and
"sync" stages.
* zydroload : the encoding of several games developed by New Frontier, mainly
published by Infogrames: "Light Corridor", "Hostages", "North and South"...

CSW2CDT secondarily supports the PZX format. This format can store pauses,
series of pulses (such as tones and syncs) and streams of bits, but instead of
merging them into several types of blocks with multiple parameters as the
CDT/TZX format does, it handles them as three simple block types. Notice that
the file extension ".pzx" was devised for ZX Spectrum tapes; Amstrad CPC tapes
expect the file extension ".cdp".

## Example ##

Let's suppose that we have a crystal-clear sample of the tape release of "Inside
Outing" (either for ZX Spectrum or Amstrad CPC) named "insidout.wav", but it's a
stereo sample and only the left channel carries the actual tape contents;
encoding it into a CSW1 file would require this command:

	csw0 -l insidout.wav insidout.csw

If this is the original Amstrad CPC release of "Inside Outing", turning the
resulting CSW1 file "insidout.csw" into a valid CDT file for Amstrad CPC
emulators and devices requires specifying the tape type, as the smoothly
animated countdown on the title screen and the high bitrate mean this is an
Alkatraz-protected tape. Let's "beautify" the tape while we encode it by
balancing values and clipping or padding incomplete bytes with ones, as default
CPC blocks always end in 64 BIT1 edges:

	csw0 -b -y -5 --alkatraz insidout.csw insidout.cdt

Something similar would happen if this were the original ZX Spectrum release,
that also displays a smooth countdown on the title screen and features a high
bitrate, and is thus an Alkatraz tape. Notice that the target path now ends in
".tzx", the standard extension of ZX Spectrum tapes, whereas ".cdt" would belong
in an Amstrad CPC tape. So let's also encode the tape and beautify it with
balanced values, clipping incomplete bytes altogether and encouraging the usage
of BLOCK $10 to encode the loader:

	csw0 -b -y -8 -z 20 --alkatraz insidout.csw insidout.tzx

In both cases a file named "insidout.log" will include a list of the blocks
within the resulting tape file. For example, this is how it might look like
after generating the CPC tape:

	------------------------------------------------------------------------
-------
	#####  type   encoding    pilot     syncs   BIT0:BIT1 pct   length check
pause
	------------------------------------------------------------------------
-------
	00001 INFOS: 2022-12-24 12:34:56 CSW2CDT 20221224 -b -y -8 --alkatraz
	00002 SILENT ---------- --------- --------- --------- --- -------- -- --
11536
	00003 CUSTOM amstrad*   4095x2384 1508,1111 1248:2383  71    263:8 00 OK
2557
	00004 CUSTOM amstrad*   4099x2385 1508,1032 1246:2395  70   2069:8 00 OK
2564
	00005 CUSTOM amstrad*   4099x2392 1508,1111 1253:2392  70    263:8 00 OK
2566
	00006 CUSTOM amstrad*   4099x2394 1429,1190 1250:2400  70   1295:8 00 OK
18599
	00007 CUSTOM alkatraz    143x2314 0873,0635 0614:1181 143  58515:8 64 --
10227
	------------------------------------------------------------------------
-------

And this is how the log might look like after encoding the Spectrum tape:

	------------------------------------------------------------------------
-------
	#####  type   encoding    pilot     syncs   BIT0:BIT1 pct   length check
pause
	------------------------------------------------------------------------
-------
	00001 INFOS: 2022-12-24 12:34:56 CSW2CDT 20221224 -b -y -8 -z 20
--alkatraz
	00002 SILENT            --------- --------- --------- --- -------- -- --
15372
	00003 NORMAL spectrum*  8062x2168 0674,0675 0856:1712 100     19:8 00 OK
982
	00004 NORMAL spectrum*  3222x2168 0674,0675 0855:1710 100   1100:8 00 OK
1670
	00005 CUSTOM alkatraz   6107x2165 0714,0714 0564:1129 151   3962:8 24 --
18833
	00006 CUSTOM alkatraz    139x2165 0714,0715 0564:1129 151  46335:8 8E --
10218
	------------------------------------------------------------------------
-------

In both cases the asterisk after the encoding type ("amstrad*" and "spectrum*")
means that the encoder automatically recognized the type. Notice that this means
that the encoder can also calculate the CRC of said blocks (or in the case of
Amstrad blocks, the amount of errors either in the bitstream [$01..] or the
trailer [$FA..$FF]) and write "OK" if it matches; in comparison, the encryption
of Alkatraz-protected blocks prevents automated CRC calculation.

The remaining fields display the amount and duration of pilot tone edges, the
duration of the sync edges, and the duration of the BIT0 and BIT1 data edges;
"pct" is an approximation of the baud rate in comparison to the default ZX
Spectrum bitrate (1350 baud). The length is shown in bytes; the amount of bits
in the last byte is shown after the colon. The pause is measured in
milliseconds.

## Version history ##

- 20240224 -- first public release. The list of double-hyphen encodings is
"amstrad", "alkatraz", "bleepload1", "bleepload2", "carsoncity", "cassys",
"ehservices", "frankbruno", "gremlin1", "gremlin2", "hexagon", "kansas",
"keytone", "maubeuge", "microkey", "operasoft", "poliload", "puffyssaga",
"ricochet", "spectrum", "specvar0", "specvar1", "specvar2", "speedlock0",
"speedlock1", "speedlock2", "speedlock3", "speedlock4", "speedlock5",
"speedlock6", "speedlock7", "unilode" and "zydroload".
- 20240328 -- minor patch. Added sanity checks when playing TZX blocks $19 and
$2B (suggested by Beginner, Patrik and Woodster), fixed bug in encoders
"speedlock6" and "speedlock7" (reported by Dlfrsilver and Imulilla).
- 20240531 -- minor patch. New multipart Speedlock handler: types 3-4 and 5-7
unify and improve the chunk separator detection logic, while fixing a bug in the
dummy trailing bits of multipart blocks. Parameter "-w N" behaves differently in
Speedlock tapes: it specifies the N-th block where the ID is 8 bits long, for
example the levels of "Super Cycle" and "Nigel Mansell's Grand Prix". Option "-P
N" lets the user set the minimum amount of data edges, for example -P 16 in the
original release of "Dragon Ninja" for Amstrad CPC. Tweaks in the Bleepload2
detection. New option "-Z" (equivalent to "-z 0") forbids the generation of TZX
BLOCK $10 altogether.
- 20240727 -- minor patch. Improved Gremlin handlers: type Gremlin0 is gone,
Gremlin1 handles single-part blocks (f.e. "Basil the Great Mouse Detective"),
Gremlin2 handles multi-part blocks (f.e. "Mask") and more attention is paid to
the separators between headers and bodies.
