Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

formats/tzx_cas.cpp: Fixed regression in TAP format; Added checksum validation (MT9104) #13322

Merged
merged 1 commit into from
Feb 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions src/lib/formats/tzx_cas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,31 +804,56 @@ static int cdt_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
return size;
}

static int tap_cas_to_wav_size( const uint8_t *casdata, int caslen )
static int tap_cas_to_wav_size(const uint8_t *casdata, int caslen)
{
/*
TAP Header:
| 0 | W | Length of Data Block (N) | -+
| 2 | B | Flag Byte | -+
| 3 | B*(N-2) | Data | | Data Block
| N+1 | B | XOR Checksum of [2..N] | -+
*/

int size = 0;
const uint8_t *p = casdata;

while (caslen > 0)
while (caslen > 2)
{
int data_size = get_u16le(&p[0]);
int pilot_length = (p[2] == 0x00) ? 8063 : 3223;
caslen -= data_size;
if (caslen < 0)
p += 2;
caslen -= 2;
if (caslen < data_size)
{
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X byte but only 0x%X available.\n", data_size, data_size + caslen);
data_size += caslen;
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X bytes but only 0x%X available.\n", data_size, caslen);
data_size = caslen;
}
caslen -= data_size;

// Data Block
LOG_FORMATS("tap_cas_to_wav_size: Handling TAP block containing 0x%X bytes", data_size);
p += 2;
const int pilot_length = (p[0] == 0x00) ? 8063 : 3223;
size += tzx_cas_handle_block(nullptr, p, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
LOG_FORMATS(", total size is now: %d\n", size);
LOG_FORMATS(", total size is now: %d", size);

// Validate Checksum
const uint8_t checksum = p[data_size - 1];
LOG_FORMATS(", checksum 0x%X\n", checksum);
uint8_t check = 0x00;
for(int i = 0; i < (data_size - 1); i++)
{
check ^= p[i];
}
if (check != checksum)
{
LOG_FORMATS("tap_cas_to_wav_size: wrong checksum 0x%X\n", check);
}

p += data_size;
}
return size;
}

static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes )
static int tap_cas_fill_wave(int16_t *buffer, int length, const uint8_t *bytes)
{
int16_t *p = buffer;
int size = 0;
Expand All @@ -837,7 +862,9 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
while (size < length)
{
int data_size = get_u16le(&bytes[0]);
int pilot_length = (bytes[2] == 0x00) ? 8063 : 3223;
bytes += 2;

int pilot_length = (bytes[0] == 0x00) ? 8063 : 3223;
LOG_FORMATS("tap_cas_fill_wave: Handling TAP block containing 0x%X bytes\n", data_size);
/*
length -= data_size;
Expand All @@ -846,7 +873,6 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
data_size += length; // Take as much as we can.
}
*/
bytes += 2;
size += tzx_cas_handle_block(&p, bytes, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
bytes += data_size;
}
Expand Down
Loading