Python module to read .tap images

You need an actual VIC.

Moderator: Moderators

Post Reply
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Python module to read .tap images

Post by srowe »

I've been getting to grips with the details of the Commodore tape format and have created a Python module that can extract files from .tap files

https://pypi.org/project/tapfile/

Combined with the d64 module I wrote a while ago this script can then be used to create a disk image from a tap file

Code: Select all

import struct
import sys

from d64 import DiskImage
from tap_file import TapFile, TapHeader, HeaderType


tape_image = TapFile(sys.argv[1])
with DiskImage(sys.argv[2], 'w') as disk_image:
    for obj in tape_image.contents():
        if isinstance(obj, TapHeader):
            if obj.htype in (HeaderType.PRG_RELOC, HeaderType.PRG):
                print("Copying PRG file", obj.name)
                out_file = disk_image.path(obj.name).open('w', ftype='PRG')
                out_file.write(struct.pack('<H', obj.start))
            elif obj.htype == HeaderType.SEQ_HDR:
                print("Copying SEQ file", obj.name)
                out_file = disk_image.path(obj.name).open('w', ftype='SEQ')
            elif obj.htype == HeaderType.SEQ_DATA:
                out_file.write(obj.data)
                if obj.seq_eof:
                    out_file.close()
        else:
            # PRG contents
            out_file.write(obj.data)
            out_file.close()
raspberrypioneer
Vic 20 Newbie
Posts: 4
Joined: Thu Feb 23, 2023 3:11 pm
Location: UK

Re: Python module to read .tap images

Post by raspberrypioneer »

Thank you very much for your tap file converter! I found it useful in converting some Vic-20 tap files to working D64 / PRG format programs. :D

I had to do a few things to get it up and running on Windows using VS Code with Python 3.11:

pip install tapfile
pip install d64

Amend the file open command in a few of the routines e.g. in magic.py

#with filepath.open('rb') as fileh:
with open(filepath,'rb') as fileh:

Create the empty d64 file using Dirmaster first, then run the converter program
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Python module to read .tap images

Post by srowe »

Looks like you were trying to use a string rather than a pathlib.Path object? Could you give the full code example?

You might find cbm-shell useful, rather than using these modules directly.

https://cbmshell.readthedocs.io/en/latest/index.html

You can do a move from .tap to .d64 with just

Code: Select all

(cbm) attach ref.tap
Attached ref.tap to 0
(cbm) attach test.d64
Attached test.d64 to 1
(cbm) copy 0:TEST 1:
Copying ImagePath(0:b'TEST') to ImagePath(1:b'TEST')
(cbm) 
raspberrypioneer
Vic 20 Newbie
Posts: 4
Joined: Thu Feb 23, 2023 3:11 pm
Location: UK

Re: Python module to read .tap images

Post by raspberrypioneer »

Suspect it was that, I used file names as strings, although I did try passing file names as arguments at one point. This is the code I used, basically tweaking your version using file names in strings (ok for the one-off things I'm doing):

Code: Select all

import struct
#import sys

from d64 import DiskImage
from tap_file import TapFileReader, TapHeader, HeaderType

tap_file_name = "C:/test/Mickey the Bricky.tap"
# Create the empty d64 file using dirmaster first
d64_file_name = "C:/test/Mickey the Bricky.d64"

# tape_image = TapFileReader(sys.argv[1])
# with DiskImage(sys.argv[2], 'w') as disk_image:

tape_image = TapFileReader(tap_file_name)
with DiskImage(d64_file_name, 'w') as disk_image:
    for obj in tape_image.contents():
        if isinstance(obj, TapHeader):
            if obj.htype in (HeaderType.PRG_RELOC, HeaderType.PRG):
                print("Copying PRG file", obj.name)
                out_file = disk_image.path(obj.name).open('w', ftype='PRG')
                out_file.write(struct.pack('<H', obj.start))
            elif obj.htype == HeaderType.SEQ:
                print("Copying SEQ file", obj.name)
                out_file = disk_image.path(obj.name).open('w', ftype='SEQ')
        else:
            # PRG or SEQ data
            out_file.write(obj.data)
            if obj.eof:
                out_file.close()
Thanks again, got the result in the end with this and a working game (I've just extracted the PRG from the D64 as that's all I need in this case). Will check out cbm-shell though, looks much easier. :)
Post Reply