Add support for disks with arbitrary number of tracks; add sample disk images
This commit is contained in:
parent
2f199f601c
commit
6cd06758c2
|
@ -0,0 +1 @@
|
|||
__pycache__/dsk2po.cpython-311.pyc
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
10
README.md
10
README.md
|
@ -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:
|
||||
|
||||
|
|
68
dsk2po.py
68
dsk2po.py
|
@ -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())
|
||||
|
|
11
po2dsk.py
11
po2dsk.py
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue