mirror of
https://github.com/paulhagstrom/dsk2po.git
synced 2024-12-12 12:29:14 +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
|
||||
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
Block a user