Add support for disks with arbitrary number of tracks; add sample disk images

This commit is contained in:
Chris Torrence 2024-02-21 09:13:55 -07:00
parent 2f199f601c
commit 6cd06758c2
8 changed files with 54 additions and 36 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__/dsk2po.cpython-311.pyc

BIN
35track.dsk Normal file

Binary file not shown.

BIN
35track.po Normal file

Binary file not shown.

BIN
40track.dsk Normal file

Binary file not shown.

BIN
40track.po Normal file

Binary file not shown.

View File

@ -1,5 +1,6 @@
# dsk2po
Python script to convert Apple II/III .DSK (DO) images to ProDOS-ordered images
# dsk2po and po2dsk
Python scripts to convert Apple II/III .DSK (DO) images to ProDOS-ordered images
and vice versa.
This is nothing very exciting, it just maps sectors in .dsk (DOS-order, .do) files
into those of a .po (ProDOS-order) file. Most Apple II emulators can handle both,
@ -11,7 +12,10 @@ Usage is just (assuming you've done `chmod 755 dsk2po.py`, else precede with pyt
./dsk2po.py image.dsk
This will create image.dsk.po alongside it. Pretty much no checking is done.
It just goes through 35 tracks and converts them, then ends.
It just goes through all the tracks and converts them, then ends.
Both scripts will handle an arbitrary number of tracks, but will print a
warning if the number of tracks is not 35.
This can be used as an action for find, like so:

View File

@ -1,33 +1,39 @@
#!/usr/bin/env python3
# unscramble dsk into po
# Paul Hagstrom, Dec 2015
import sys, getopt, re
import sys, getopt, re, os
def main(argv=None):
print("dsk2po - convert dsk files to po files")
print("dsk2po - convert dsk files to po files")
try:
opts, args = getopt.getopt(sys.argv[1:], '')
except getopt.GetoptError as err:
print(str(err))
usage()
return 1
try:
dskfilename = args[0]
except:
print('You need to provide the name of a DSK file to begin.')
return 1
try:
opts, args = getopt.getopt(sys.argv[1:], '')
except getopt.GetoptError as err:
print(str(err))
usage()
return 1
try:
dskfilename = args[0]
except:
print('You need to provide the name of a DSK file to begin.')
return 1
potracks = []
with open(dskfilename, mode="rb") as dskfile:
for track in range(35):
trackbuffer = dskfile.read(4096)
potracks.append(dsk2po(trackbuffer))
pofilename = re.sub('\.dsk$', '', dskfilename, flags=re.IGNORECASE) + ".po"
print('Writing po image to {}'.format(pofilename))
with open(pofilename, mode="wb") as pofile:
for potrack in potracks:
pofile.write(potrack)
return 0
# Handle arbitrary number of tracks (normally should be 35)
fileSize = os.path.getsize(dskfilename)
ntracks = fileSize // 4096
if ntracks != 35:
print("Warning: DSK file has non-standard {} tracks".format(ntracks))
potracks = []
with open(dskfilename, mode="rb") as dskfile:
for track in range(ntracks):
trackbuffer = dskfile.read(4096)
potracks.append(dsk2po(trackbuffer))
pofilename = re.sub('\.dsk$', '', dskfilename, flags=re.IGNORECASE) + ".po"
print('Writing po image to {}'.format(pofilename))
with open(pofilename, mode="wb") as pofile:
for potrack in potracks:
pofile.write(potrack)
return 0
# From Beneath Apple ProDOS, table 3.1
# block 000 physical 0, 2 DOS 0, E page 0, 1
@ -45,12 +51,12 @@ def main(argv=None):
block_map = [0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15]
def dsk2po(trackbuffer):
potrack = bytearray()
for chunk in range(16):
chunk_start = 256*block_map[chunk]
chunk_end = chunk_start + 256
potrack.extend(trackbuffer[chunk_start:chunk_end])
return potrack
potrack = bytearray()
for chunk in range(16):
chunk_start = 256*block_map[chunk]
chunk_end = chunk_start + 256
potrack.extend(trackbuffer[chunk_start:chunk_end])
return potrack
if __name__ == "__main__":
sys.exit(main())
sys.exit(main())

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# scramble po back into dsk
# Chris Torrence, Oct 2020
import sys, getopt, re
import sys, getopt, re, os
from dsk2po import dsk2po
def main(argv=None):
print("po2dsk - convert po files to dsk files")
@ -18,10 +18,17 @@ def main(argv=None):
print('You need to provide the name of a PO file to begin.')
return 1
# Handle arbitrary number of tracks (normally should be 35)
fileSize = os.path.getsize(filenameIn)
ntracks = fileSize // 4096
if ntracks != 35:
print("Warning: PO file has non-standard {} tracks".format(ntracks))
tracks = []
# Note that the same algorithm can be used to convert in either direction
with open(filenameIn, mode="rb") as fileIn:
for track in range(35):
for track in range(ntracks):
trackbuffer = fileIn.read(4096)
tracks.append(dsk2po(trackbuffer))
dskfilename = re.sub('\.po$', '', filenameIn, flags=re.IGNORECASE) + ".dsk"