Skip to content

Commit

Permalink
Enable tap2sna.py to ignore unsupported TZX blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
skoolkid committed Oct 17, 2023
1 parent 0de33ba commit 934c300
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
11 changes: 7 additions & 4 deletions skoolkit/tap2sna.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,15 @@ class TapeError(Exception):
pass

class TapeBlockTimings:
def __init__(self, pilot_len=0, pilot=0, sync=(), zero=0, one=0, pause=0, used_bits=8):
def __init__(self, pilot_len=0, pilot=0, sync=(), zero=0, one=0, pause=0, used_bits=8, error=None):
self.pilot_len = pilot_len
self.pilot = pilot
self.sync = sync
self.zero = zero
self.one = one
self.pause = pause
self.used_bits = used_bits
self.error = error

def get_tape_block_timings(first_byte, pause=3500000):
if first_byte == 0:
Expand Down Expand Up @@ -611,17 +612,17 @@ def _get_tzx_block(data, i, sim):
elif block_id == 21:
# Direct recording block
if sim:
raise TapeError("TZX Direct Recording (0x15) not supported")
timings = TapeBlockTimings(error="TZX Direct Recording (0x15) not supported")
i += get_word3(data, i + 5) + 8
elif block_id == 24:
# CSW recording block
if sim:
raise TapeError("TZX CSW Recording (0x18) not supported")
timings = TapeBlockTimings(error="TZX CSW Recording (0x18) not supported")
i += get_dword(data, i) + 4
elif block_id == 25:
# Generalized data block
if sim:
raise TapeError("TZX Generalized Data Block (0x19) not supported")
timings = TapeBlockTimings(error="TZX Generalized Data Block (0x19) not supported")
i += get_dword(data, i) + 4
elif block_id == 32:
# Pause (silence) or 'Stop the tape' command
Expand Down Expand Up @@ -694,6 +695,8 @@ def _get_tzx_blocks(data, sim, start, stop, is48):
break
i, block_id, timings, tape_data = _get_tzx_block(data, i, sim)
if block_num >= start:
if timings and timings.error:
raise TapeError(timings.error)
if sim:
if block_id == 0x20:
if stop == 0 and timings.pause == 0:
Expand Down
63 changes: 62 additions & 1 deletion tests/test_tap2sna.py
Original file line number Diff line number Diff line change
Expand Up @@ -1948,11 +1948,30 @@ def test_sim_load_with_tzx_block_type_0x15(self):
self.assertEqual(self.out.getvalue(), '')
self.assertEqual(self.err.getvalue(), '')

@patch.object(tap2sna, 'LoadTracer', MockLoadTracer)
@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_can_ignore_tzx_block_type_0x15(self):
direct_recording_block = (
21, # Block ID
79, 0, # T-states per sample
0, 0, # Pause
8, # Used bits in last byte
3, 0, 0, # Data length
1, 2, 3, # Data
)
tzxfile = self._write_tzx((
direct_recording_block,
create_tzx_header_block()
))
output, error = self.run_tap2sna(f'--tape-start 2 {tzxfile}')
self.assertEqual(error, '')
self.assertEqual(len(load_tracer.blocks), 1)

@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_with_tzx_block_type_0x18(self):
block = [
24, # Block ID
11, 0, 0, 0, # Block length
10, 0, 0, 0, # Block length
0, 0, # Pause
68, 172, # Sampling rate
1, # Compression type
Expand All @@ -1967,6 +1986,26 @@ def test_sim_load_with_tzx_block_type_0x18(self):
self.assertEqual(self.out.getvalue(), '')
self.assertEqual(self.err.getvalue(), '')

@patch.object(tap2sna, 'LoadTracer', MockLoadTracer)
@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_can_ignore_tzx_block_type_0x18(self):
csw_recording_block = (
24, # Block ID
10, 0, 0, 0, # Block length
0, 0, # Pause
68, 172, # Sampling rate
1, # Compression type
1, 0, 0, 0, # Number of stored pulses
1, # CSW Data
)
tzxfile = self._write_tzx((
csw_recording_block,
create_tzx_header_block()
))
output, error = self.run_tap2sna(f'--tape-start 2 {tzxfile}')
self.assertEqual(error, '')
self.assertEqual(len(load_tracer.blocks), 1)

@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_with_tzx_block_type_0x19(self):
block = [
Expand All @@ -1988,6 +2027,28 @@ def test_sim_load_with_tzx_block_type_0x19(self):
self.assertEqual(self.out.getvalue(), '')
self.assertEqual(self.err.getvalue(), '')

@patch.object(tap2sna, 'LoadTracer', MockLoadTracer)
@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_can_ignore_tzx_block_type_0x19(self):
generalized_data_block = (
25, # Block ID
14, 0, 0, 0, # Block length
0, 0, # Pause
0, 0, 0, 0, # Number of symbols in pilot/sync block
1, # Maximum number of pulses per pilot/sync symbol
1, # Number of pilot/sync symbols in alphabet table
0, 0, 0, 0, # Number of symbols in data stream
1, # Maximum number of pulses per data symbol
1, # Number of data symbols in alphabet table
)
tzxfile = self._write_tzx((
generalized_data_block,
create_tzx_header_block()
))
output, error = self.run_tap2sna(f'--tape-start 2 {tzxfile}')
self.assertEqual(error, '')
self.assertEqual(len(load_tracer.blocks), 1)

@patch.object(tap2sna, '_write_snapshot', mock_write_snapshot)
def test_sim_load_with_trace(self):
basic_data = [
Expand Down

0 comments on commit 934c300

Please sign in to comment.