Example #1
0
def _analyse_szx(szxfile):
    szx = read_bin_file(szxfile)

    magic = _get_block_id(szx, 0)
    if magic != 'ZXST':
        raise SkoolKitError("{} is not an SZX file".format(szxfile))

    print('Version: {}.{}'.format(szx[4], szx[5]))
    machine_id = szx[6]
    print('Machine: {}'.format(SZX_MACHINES.get(machine_id, 'Unknown')))
    variables = {'chMachineId': machine_id}

    i = 8
    while i < len(szx):
        block_id = _get_block_id(szx, i)
        block_size = get_dword(szx, i + 4)
        i += 8
        print('{}: {} bytes'.format(block_id, block_size))
        printer = SZX_BLOCK_PRINTERS.get(block_id)
        if printer:
            for line in printer(szx[i:i + block_size], variables):
                print("  " + line)
        i += block_size
Example #2
0
def _analyse_szx(szxfile):
    szx = read_bin_file(szxfile)

    magic = _get_block_id(szx, 0)
    if magic != 'ZXST':
        raise SkoolKitError("{} is not an SZX file".format(szxfile))

    print('Version: {}.{}'.format(szx[4], szx[5]))
    machine_id = szx[6]
    print('Machine: {}'.format(SZX_MACHINES.get(machine_id, 'Unknown')))
    variables = {'chMachineId': machine_id}

    i = 8
    while i < len(szx):
        block_id = _get_block_id(szx, i)
        block_size = get_dword(szx, i + 4)
        i += 8
        print('{}: {} bytes'.format(block_id, block_size))
        printer = SZX_BLOCK_PRINTERS.get(block_id)
        if printer:
            for line in printer(szx[i:i + block_size], variables):
                print("  " + line)
        i += block_size
Example #3
0
def _get_block_info(data, i, block_num):
    # http://www.worldofspectrum.org/TZXformat.html
    block_id = data[i]
    info = []
    tape_data = []
    i += 1
    if block_id == 16:
        header = "Standard speed data"
        length = get_word(data, i + 2)
        tape_data = data[i + 4 : i + 4 + length]
        i += 4 + length
    elif block_id == 17:
        header = "Turbo speed data"
        length = get_word3(data, i + 15)
        tape_data = data[i + 18 : i + 18 + length]
        i += 18 + length
    elif block_id == 18:
        header = "Pure tone"
        info.append("Pulse length: {} T-states".format(get_word(data, i)))
        info.append("Pulses: {}".format(get_word(data, i + 2)))
        i += 4
    elif block_id == 19:
        header = "Pulse sequence"
        info.append("Pulses: {}".format(data[i]))
        i += 2 * data[i] + 1
    elif block_id == 20:
        header = "Pure data"
        length = get_word3(data, i + 7)
        tape_data = data[i + 10 : i + 10 + length]
        i += length + 10
    elif block_id == 21:
        header = "Direct recording"
        i += get_word3(data, i + 5) + 8
    elif block_id == 24:
        header = "CSW recording"
        i += get_dword(data, i) + 4
    elif block_id == 25:
        header = "Generalized data"
        i += get_dword(data, i) + 4
    elif block_id == 32:
        duration = get_word(data, i)
        if duration:
            header = "Pause (silence)"
            info.append("Duration: {}ms".format(duration))
        else:
            header = "'Stop the tape' command"
        i += 2
    elif block_id == 33:
        header = "Group start"
        length = data[i]
        info.extend(_format_text("Name", data, i + 1, length))
        i += length + 1
    elif block_id == 34:
        header = "Group end"
    elif block_id == 35:
        header = "Jump to block"
        offset = get_word(data, i)
        if offset > 32767:
            offset -= 65536
        info.append("Destination block: {}".format(block_num + offset))
        i += 2
    elif block_id == 36:
        header = "Loop start"
        info.append("Repetitions: {}".format(get_word(data, i)))
        i += 2
    elif block_id == 37:
        header = "Loop end"
    elif block_id == 38:
        header = "Call sequence"
        i += get_word(data, i) * 2 + 2
    elif block_id == 39:
        header = "Return from sequence"
    elif block_id == 40:
        header = "Select block"
        index = i + 3
        for j in range(data[i + 2]):
            offset = get_word(data, index)
            length = data[index + 2]
            prefix = "Option {} (block {})".format(j + 1, block_num + offset)
            info.extend(_format_text(prefix, data, index + 3, length))
            index += length + 3
        i += get_word(data, i) + 2
    elif block_id == 42:
        header = "Stop the tape if in 48K mode"
        i += 4
    elif block_id == 43:
        header = "Set signal level"
        i += 5
    elif block_id == 48:
        header = "Text description"
        length = data[i]
        info.extend(_format_text("Text", data, i + 1, length))
        i += length + 1
    elif block_id == 49:
        header = "Message"
        length = data[i + 1]
        info.extend(_format_text("Message", data, i + 2, length))
        i += length + 2
    elif block_id == 50:
        header = "Archive info"
        num_strings = data[i + 2]
        j = i + 3
        for k in range(num_strings):
            try:
                str_len = data[j + 1]
            except IndexError:
                raise SkoolKitError("Unexpected end of file")
            info.extend(_format_text(ARCHIVE_INFO.get(data[j], str(data[j])), data, j + 2, str_len))
            j += 2 + str_len
        i += get_word(data, i) + 2
    elif block_id == 51:
        header = "Hardware type"
        i += data[i] * 3 + 1
    elif block_id == 53:
        header = "Custom info"
        i += get_dword(data, i + 16) + 20
    elif block_id == 90:
        header = '"Glue" block'
        i += 9
    else:
        raise SkoolKitError("Unknown block ID: 0x{:02X}".format(block_id))
    return i, block_id, header, info, tape_data
Example #4
0
def _get_tzx_block(data, i):
    # http://www.worldofspectrum.org/TZXformat.html
    block_id = data[i]
    tape_data = None
    i += 1
    if block_id == 16:
        # Standard speed data block
        length = get_word(data, i + 2)
        tape_data = data[i + 4:i + 4 + length]
        i += 4 + length
    elif block_id == 17:
        # Turbo speed data block
        length = get_word3(data, i + 15)
        tape_data = data[i + 18:i + 18 + length]
        i += 18 + length
    elif block_id == 18:
        # Pure tone
        i += 4
    elif block_id == 19:
        # Sequence of pulses of various lengths
        i += 2 * data[i] + 1
    elif block_id == 20:
        # Pure data block
        length = get_word3(data, i + 7)
        tape_data = data[i + 10:i + 10 + length]
        i += 10 + length
    elif block_id == 21:
        # Direct recording block
        i += get_word3(data, i + 5) + 8
    elif block_id == 24:
        # CSW recording block
        i += get_dword(data, i) + 4
    elif block_id == 25:
        # Generalized data block
        i += get_dword(data, i) + 4
    elif block_id == 32:
        # Pause (silence) or 'Stop the tape' command
        i += 2
    elif block_id == 33:
        # Group start
        i += data[i] + 1
    elif block_id == 34:
        # Group end
        pass
    elif block_id == 35:
        # Jump to block
        i += 2
    elif block_id == 36:
        # Loop start
        i += 2
    elif block_id == 37:
        # Loop end
        pass
    elif block_id == 38:
        # Call sequence
        i += get_word(data, i) * 2 + 2
    elif block_id == 39:
        # Return from sequence
        pass
    elif block_id == 40:
        # Select block
        i += get_word(data, i) + 2
    elif block_id == 42:
        # Stop the tape if in 48K mode
        i += 4
    elif block_id == 43:
        # Set signal level
        i += 5
    elif block_id == 48:
        # Text description
        i += data[i] + 1
    elif block_id == 49:
        # Message block
        i += data[i + 1] + 2
    elif block_id == 50:
        # Archive info
        i += get_word(data, i) + 2
    elif block_id == 51:
        # Hardware type
        i += data[i] * 3 + 1
    elif block_id == 53:
        # Custom info block
        i += get_dword(data, i + 16) + 20
    elif block_id == 90:
        # "Glue" block
        i += 9
    else:
        raise TapeError('Unknown TZX block ID: 0x{:X}'.format(block_id))
    return i, tape_data
Example #5
0
def _get_tzx_block(data, i):
    # http://www.worldofspectrum.org/TZXformat.html
    block_id = data[i]
    tape_data = None
    i += 1
    if block_id == 16:
        # Standard speed data block
        length = get_word(data, i + 2)
        tape_data = data[i + 4:i + 4 + length]
        i += 4 + length
    elif block_id == 17:
        # Turbo speed data block
        length = get_word3(data, i + 15)
        tape_data = data[i + 18:i + 18 + length]
        i += 18 + length
    elif block_id == 18:
        # Pure tone
        i += 4
    elif block_id == 19:
        # Sequence of pulses of various lengths
        i += 2 * data[i] + 1
    elif block_id == 20:
        # Pure data block
        length = get_word3(data, i + 7)
        tape_data = data[i + 10:i + 10 + length]
        i += 10 + length
    elif block_id == 21:
        # Direct recording block
        i += get_word3(data, i + 5) + 8
    elif block_id == 24:
        # CSW recording block
        i += get_dword(data, i) + 4
    elif block_id == 25:
        # Generalized data block
        i += get_dword(data, i) + 4
    elif block_id == 32:
        # Pause (silence) or 'Stop the tape' command
        i += 2
    elif block_id == 33:
        # Group start
        i += data[i] + 1
    elif block_id == 34:
        # Group end
        pass
    elif block_id == 35:
        # Jump to block
        i += 2
    elif block_id == 36:
        # Loop start
        i += 2
    elif block_id == 37:
        # Loop end
        pass
    elif block_id == 38:
        # Call sequence
        i += get_word(data, i) * 2 + 2
    elif block_id == 39:
        # Return from sequence
        pass
    elif block_id == 40:
        # Select block
        i += get_word(data, i) + 2
    elif block_id == 42:
        # Stop the tape if in 48K mode
        i += 4
    elif block_id == 43:
        # Set signal level
        i += 5
    elif block_id == 48:
        # Text description
        i += data[i] + 1
    elif block_id == 49:
        # Message block
        i += data[i + 1] + 2
    elif block_id == 50:
        # Archive info
        i += get_word(data, i) + 2
    elif block_id == 51:
        # Hardware type
        i += data[i] * 3 + 1
    elif block_id == 53:
        # Custom info block
        i += get_dword(data, i + 16) + 20
    elif block_id == 90:
        # "Glue" block
        i += 9
    else:
        raise TapeError('Unknown TZX block ID: 0x{:X}'.format(block_id))
    return i, tape_data
Example #6
0
def _get_block_info(data, i, block_num):
    # https://worldofspectrum.net/features/TZXformat.html
    block_id = data[i]
    info = []
    tape_data = []
    i += 1
    if block_id == 16:
        header = 'Standard speed data'
        length = get_word(data, i + 2)
        tape_data = data[i + 4:i + 4 + length]
        i += 4 + length
    elif block_id == 17:
        header = 'Turbo speed data'
        length = get_word3(data, i + 15)
        tape_data = data[i + 18:i + 18 + length]
        i += 18 + length
    elif block_id == 18:
        header = 'Pure tone'
        info.append('Pulse length: {} T-states'.format(get_word(data, i)))
        info.append('Pulses: {}'.format(get_word(data, i + 2)))
        i += 4
    elif block_id == 19:
        header = 'Pulse sequence'
        num_pulses = data[i]
        i += 1
        for pulse in range(num_pulses):
            info.append('Pulse {}/{}: {}'.format(pulse + 1, num_pulses,
                                                 get_word(data, i)))
            i += 2
    elif block_id == 20:
        header = 'Pure data'
        info.append('0-pulse: {}'.format(get_word(data, i)))
        info.append('1-pulse: {}'.format(get_word(data, i + 2)))
        info.append('Used bits in last byte: {}'.format(data[i + 4]))
        info.append('Pause: {}ms'.format(get_word(data, i + 5)))
        length = get_word3(data, i + 7)
        tape_data = data[i + 10:i + 10 + length]
        i += length + 10
    elif block_id == 21:
        header = 'Direct recording'
        i += get_word3(data, i + 5) + 8
    elif block_id == 24:
        header = 'CSW recording'
        i += get_dword(data, i) + 4
    elif block_id == 25:
        header = 'Generalized data'
        i += get_dword(data, i) + 4
    elif block_id == 32:
        duration = get_word(data, i)
        if duration:
            header = "Pause (silence)"
            info.append('Duration: {}ms'.format(duration))
        else:
            header = "'Stop the tape' command"
        i += 2
    elif block_id == 33:
        header = 'Group start'
        length = data[i]
        info.extend(_format_text('Name', data, i + 1, length))
        i += length + 1
    elif block_id == 34:
        header = 'Group end'
    elif block_id == 35:
        header = 'Jump to block'
        offset = get_word(data, i)
        if offset > 32767:
            offset -= 65536
        info.append('Destination block: {}'.format(block_num + offset))
        i += 2
    elif block_id == 36:
        header = 'Loop start'
        info.append('Repetitions: {}'.format(get_word(data, i)))
        i += 2
    elif block_id == 37:
        header = 'Loop end'
    elif block_id == 38:
        header = 'Call sequence'
        i += get_word(data, i) * 2 + 2
    elif block_id == 39:
        header = 'Return from sequence'
    elif block_id == 40:
        header = 'Select block'
        index = i + 3
        for j in range(data[i + 2]):
            offset = get_word(data, index)
            length = data[index + 2]
            prefix = 'Option {} (block {})'.format(j + 1, block_num + offset)
            info.extend(_format_text(prefix, data, index + 3, length))
            index += length + 3
        i += get_word(data, i) + 2
    elif block_id == 42:
        header = 'Stop the tape if in 48K mode'
        i += 4
    elif block_id == 43:
        header = 'Set signal level'
        i += 5
    elif block_id == 48:
        header = 'Text description'
        length = data[i]
        info.extend(_format_text('Text', data, i + 1, length))
        i += length + 1
    elif block_id == 49:
        header = 'Message'
        length = data[i + 1]
        info.extend(_format_text('Message', data, i + 2, length))
        i += length + 2
    elif block_id == 50:
        header = 'Archive info'
        num_strings = data[i + 2]
        j = i + 3
        for k in range(num_strings):
            try:
                str_len = data[j + 1]
            except IndexError:
                raise SkoolKitError('Unexpected end of file')
            info.extend(
                _format_text(ARCHIVE_INFO.get(data[j], str(data[j])), data,
                             j + 2, str_len))
            j += 2 + str_len
        i += get_word(data, i) + 2
    elif block_id == 51:
        header = 'Hardware type'
        i += 1
        for j in range(data[i - 1]):
            hw_type, hw_ids = HARDWARE_TYPE.get(data[i], ('Unknown', {}))
            info.extend(('- Type: {}'.format(hw_type), '  Name: {}'.format(
                hw_ids.get(data[i + 1], 'Unknown')), '  Info: {}'.format(
                    HARDWARE_INFO[data[i] > 0].get(data[i + 2], 'Unknown'))))
            i += 3
    elif block_id == 53:
        header = 'Custom info'
        ident = _get_str(data[i:i + 16]).strip()
        length = get_dword(data, i + 16)
        info.extend(_format_text(ident, data, i + 20, length, True))
        i += length + 20
    elif block_id == 90:
        header = '"Glue" block'
        i += 9
    else:
        raise SkoolKitError('Unknown block ID: 0x{:02X}'.format(block_id))
    return i, block_id, header, info, tape_data
Example #7
0
def _get_block_info(data, i, block_num):
    # http://www.worldofspectrum.org/TZXformat.html
    block_id = data[i]
    info = []
    tape_data = []
    i += 1
    if block_id == 16:
        header = 'Standard speed data'
        length = get_word(data, i + 2)
        tape_data = data[i + 4:i + 4 + length]
        i += 4 + length
    elif block_id == 17:
        header = 'Turbo speed data'
        length = get_word3(data, i + 15)
        tape_data = data[i + 18:i + 18 + length]
        i += 18 + length
    elif block_id == 18:
        header = 'Pure tone'
        info.append('Pulse length: {} T-states'.format(get_word(data, i)))
        info.append('Pulses: {}'.format(get_word(data, i + 2)))
        i += 4
    elif block_id == 19:
        header = 'Pulse sequence'
        num_pulses = data[i]
        i += 1
        for pulse in range(num_pulses):
            info.append('Pulse {}/{}: {}'.format(pulse + 1, num_pulses, get_word(data, i)))
            i += 2
    elif block_id == 20:
        header = 'Pure data'
        info.append('0-pulse: {}'.format(get_word(data, i)))
        info.append('1-pulse: {}'.format(get_word(data, i + 2)))
        info.append('Used bits in last byte: {}'.format(data[i + 4]))
        info.append('Pause: {}ms'.format(get_word(data, i + 5)))
        length = get_word3(data, i + 7)
        tape_data = data[i + 10:i + 10 + length]
        i += length + 10
    elif block_id == 21:
        header = 'Direct recording'
        i += get_word3(data, i + 5) + 8
    elif block_id == 24:
        header = 'CSW recording'
        i += get_dword(data, i) + 4
    elif block_id == 25:
        header = 'Generalized data'
        i += get_dword(data, i) + 4
    elif block_id == 32:
        duration = get_word(data, i)
        if duration:
            header = "Pause (silence)"
            info.append('Duration: {}ms'.format(duration))
        else:
            header = "'Stop the tape' command"
        i += 2
    elif block_id == 33:
        header = 'Group start'
        length = data[i]
        info.extend(_format_text('Name', data, i + 1, length))
        i += length + 1
    elif block_id == 34:
        header = 'Group end'
    elif block_id == 35:
        header = 'Jump to block'
        offset = get_word(data, i)
        if offset > 32767:
            offset -= 65536
        info.append('Destination block: {}'.format(block_num + offset))
        i += 2
    elif block_id == 36:
        header = 'Loop start'
        info.append('Repetitions: {}'.format(get_word(data, i)))
        i += 2
    elif block_id == 37:
        header = 'Loop end'
    elif block_id == 38:
        header = 'Call sequence'
        i += get_word(data, i) * 2 + 2
    elif block_id == 39:
        header = 'Return from sequence'
    elif block_id == 40:
        header = 'Select block'
        index = i + 3
        for j in range(data[i + 2]):
            offset = get_word(data, index)
            length = data[index + 2]
            prefix = 'Option {} (block {})'.format(j + 1, block_num + offset)
            info.extend(_format_text(prefix, data, index + 3, length))
            index += length + 3
        i += get_word(data, i) + 2
    elif block_id == 42:
        header = 'Stop the tape if in 48K mode'
        i += 4
    elif block_id == 43:
        header = 'Set signal level'
        i += 5
    elif block_id == 48:
        header = 'Text description'
        length = data[i]
        info.extend(_format_text('Text', data, i + 1, length))
        i += length + 1
    elif block_id == 49:
        header = 'Message'
        length = data[i + 1]
        info.extend(_format_text('Message', data, i + 2, length))
        i += length + 2
    elif block_id == 50:
        header = 'Archive info'
        num_strings = data[i + 2]
        j = i + 3
        for k in range(num_strings):
            try:
                str_len = data[j + 1]
            except IndexError:
                raise SkoolKitError('Unexpected end of file')
            info.extend(_format_text(ARCHIVE_INFO.get(data[j], str(data[j])), data, j + 2, str_len))
            j += 2 + str_len
        i += get_word(data, i) + 2
    elif block_id == 51:
        header = 'Hardware type'
        i += data[i] * 3 + 1
    elif block_id == 53:
        header = 'Custom info'
        i += get_dword(data, i + 16) + 20
    elif block_id == 90:
        header = '"Glue" block'
        i += 9
    else:
        raise SkoolKitError('Unknown block ID: 0x{:02X}'.format(block_id))
    return i, block_id, header, info, tape_data