mirror of
https://github.com/paulhagstrom/dsk2po.git
synced 2025-01-13 18:29:59 +00:00
Add support for disks with arbitrary number of tracks; add sample disk images
This commit is contained in:
parent
2f199f601c
commit
6cd06758c2
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
__pycache__/dsk2po.cpython-311.pyc
|
BIN
35track.dsk
Normal file
BIN
35track.dsk
Normal file
Binary file not shown.
BIN
35track.po
Normal file
BIN
35track.po
Normal file
Binary file not shown.
BIN
40track.dsk
Normal file
BIN
40track.dsk
Normal file
Binary file not shown.
BIN
40track.po
Normal file
BIN
40track.po
Normal file
Binary file not shown.
10
README.md
10
README.md
@ -1,5 +1,6 @@
|
|||||||
# dsk2po
|
# dsk2po and po2dsk
|
||||||
Python script to convert Apple II/III .DSK (DO) images to ProDOS-ordered images
|
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
|
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,
|
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
|
./dsk2po.py image.dsk
|
||||||
|
|
||||||
This will create image.dsk.po alongside it. Pretty much no checking is done.
|
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:
|
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
|
#!/usr/bin/env python3
|
||||||
# unscramble dsk into po
|
# unscramble dsk into po
|
||||||
# Paul Hagstrom, Dec 2015
|
# Paul Hagstrom, Dec 2015
|
||||||
import sys, getopt, re
|
import sys, getopt, re, os
|
||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
print("dsk2po - convert dsk files to po files")
|
print("dsk2po - convert dsk files to po files")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], '')
|
opts, args = getopt.getopt(sys.argv[1:], '')
|
||||||
except getopt.GetoptError as err:
|
except getopt.GetoptError as err:
|
||||||
print(str(err))
|
print(str(err))
|
||||||
usage()
|
usage()
|
||||||
return 1
|
return 1
|
||||||
try:
|
try:
|
||||||
dskfilename = args[0]
|
dskfilename = args[0]
|
||||||
except:
|
except:
|
||||||
print('You need to provide the name of a DSK file to begin.')
|
print('You need to provide the name of a DSK file to begin.')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
potracks = []
|
# Handle arbitrary number of tracks (normally should be 35)
|
||||||
with open(dskfilename, mode="rb") as dskfile:
|
fileSize = os.path.getsize(dskfilename)
|
||||||
for track in range(35):
|
ntracks = fileSize // 4096
|
||||||
trackbuffer = dskfile.read(4096)
|
if ntracks != 35:
|
||||||
potracks.append(dsk2po(trackbuffer))
|
print("Warning: DSK file has non-standard {} tracks".format(ntracks))
|
||||||
pofilename = re.sub('\.dsk$', '', dskfilename, flags=re.IGNORECASE) + ".po"
|
|
||||||
print('Writing po image to {}'.format(pofilename))
|
potracks = []
|
||||||
with open(pofilename, mode="wb") as pofile:
|
with open(dskfilename, mode="rb") as dskfile:
|
||||||
for potrack in potracks:
|
for track in range(ntracks):
|
||||||
pofile.write(potrack)
|
trackbuffer = dskfile.read(4096)
|
||||||
return 0
|
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
|
# From Beneath Apple ProDOS, table 3.1
|
||||||
# block 000 physical 0, 2 DOS 0, E page 0, 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]
|
block_map = [0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15]
|
||||||
|
|
||||||
def dsk2po(trackbuffer):
|
def dsk2po(trackbuffer):
|
||||||
potrack = bytearray()
|
potrack = bytearray()
|
||||||
for chunk in range(16):
|
for chunk in range(16):
|
||||||
chunk_start = 256*block_map[chunk]
|
chunk_start = 256*block_map[chunk]
|
||||||
chunk_end = chunk_start + 256
|
chunk_end = chunk_start + 256
|
||||||
potrack.extend(trackbuffer[chunk_start:chunk_end])
|
potrack.extend(trackbuffer[chunk_start:chunk_end])
|
||||||
return potrack
|
return potrack
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
11
po2dsk.py
11
po2dsk.py
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# scramble po back into dsk
|
# scramble po back into dsk
|
||||||
# Chris Torrence, Oct 2020
|
# Chris Torrence, Oct 2020
|
||||||
import sys, getopt, re
|
import sys, getopt, re, os
|
||||||
from dsk2po import dsk2po
|
from dsk2po import dsk2po
|
||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
print("po2dsk - convert po files to dsk files")
|
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.')
|
print('You need to provide the name of a PO file to begin.')
|
||||||
return 1
|
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 = []
|
tracks = []
|
||||||
|
|
||||||
# Note that the same algorithm can be used to convert in either direction
|
# Note that the same algorithm can be used to convert in either direction
|
||||||
with open(filenameIn, mode="rb") as fileIn:
|
with open(filenameIn, mode="rb") as fileIn:
|
||||||
for track in range(35):
|
for track in range(ntracks):
|
||||||
trackbuffer = fileIn.read(4096)
|
trackbuffer = fileIn.read(4096)
|
||||||
tracks.append(dsk2po(trackbuffer))
|
tracks.append(dsk2po(trackbuffer))
|
||||||
dskfilename = re.sub('\.po$', '', filenameIn, flags=re.IGNORECASE) + ".dsk"
|
dskfilename = re.sub('\.po$', '', filenameIn, flags=re.IGNORECASE) + ".dsk"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user