Skip to content

Commit 3dccaa6

Browse files
authored
formats/tzx_cas.cpp: Fixed regression in TAP format; Added checksum validation (MT9104) (#13322)
1 parent 219193f commit 3dccaa6

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/lib/formats/tzx_cas.cpp

+38-12
Original file line numberDiff line numberDiff line change
@@ -804,31 +804,56 @@ static int cdt_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
804804
return size;
805805
}
806806

807-
static int tap_cas_to_wav_size( const uint8_t *casdata, int caslen )
807+
static int tap_cas_to_wav_size(const uint8_t *casdata, int caslen)
808808
{
809+
/*
810+
TAP Header:
811+
| 0 | W | Length of Data Block (N) | -+
812+
| 2 | B | Flag Byte | -+
813+
| 3 | B*(N-2) | Data | | Data Block
814+
| N+1 | B | XOR Checksum of [2..N] | -+
815+
*/
816+
809817
int size = 0;
810818
const uint8_t *p = casdata;
811819

812-
while (caslen > 0)
820+
while (caslen > 2)
813821
{
814822
int data_size = get_u16le(&p[0]);
815-
int pilot_length = (p[2] == 0x00) ? 8063 : 3223;
816-
caslen -= data_size;
817-
if (caslen < 0)
823+
p += 2;
824+
caslen -= 2;
825+
if (caslen < data_size)
818826
{
819-
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X byte but only 0x%X available.\n", data_size, data_size + caslen);
820-
data_size += caslen;
827+
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X bytes but only 0x%X available.\n", data_size, caslen);
828+
data_size = caslen;
821829
}
830+
caslen -= data_size;
831+
832+
// Data Block
822833
LOG_FORMATS("tap_cas_to_wav_size: Handling TAP block containing 0x%X bytes", data_size);
823-
p += 2;
834+
const int pilot_length = (p[0] == 0x00) ? 8063 : 3223;
824835
size += tzx_cas_handle_block(nullptr, p, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
825-
LOG_FORMATS(", total size is now: %d\n", size);
836+
LOG_FORMATS(", total size is now: %d", size);
837+
838+
// Validate Checksum
839+
const uint8_t checksum = p[data_size - 1];
840+
LOG_FORMATS(", checksum 0x%X\n", checksum);
841+
uint8_t check = 0x00;
842+
for(int i = 0; i < (data_size - 1); i++)
843+
{
844+
check ^= p[i];
845+
}
846+
if (check != checksum)
847+
{
848+
LOG_FORMATS("tap_cas_to_wav_size: wrong checksum 0x%X\n", check);
849+
}
850+
826851
p += data_size;
827852
}
828853
return size;
829854
}
830855

831-
static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes )
856+
static int tap_cas_fill_wave(int16_t *buffer, int length, const uint8_t *bytes)
832857
{
833858
int16_t *p = buffer;
834859
int size = 0;
@@ -837,7 +862,9 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
837862
while (size < length)
838863
{
839864
int data_size = get_u16le(&bytes[0]);
840-
int pilot_length = (bytes[2] == 0x00) ? 8063 : 3223;
865+
bytes += 2;
866+
867+
int pilot_length = (bytes[0] == 0x00) ? 8063 : 3223;
841868
LOG_FORMATS("tap_cas_fill_wave: Handling TAP block containing 0x%X bytes\n", data_size);
842869
/*
843870
length -= data_size;
@@ -846,7 +873,6 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
846873
data_size += length; // Take as much as we can.
847874
}
848875
*/
849-
bytes += 2;
850876
size += tzx_cas_handle_block(&p, bytes, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
851877
bytes += data_size;
852878
}

0 commit comments

Comments
 (0)