113 lines
4.8 KiB
Python
Executable File
113 lines
4.8 KiB
Python
Executable File
__version__ = "2.3.0"
|
|
|
|
try:
|
|
import numpy as np
|
|
except ImportError:
|
|
raise RuntimeError("atrcopy %s requires numpy" % __version__)
|
|
|
|
from errors import *
|
|
from diskimages import AtrHeader, BootDiskImage
|
|
from ataridos import AtariDosDiskImage, AtariDosFile
|
|
from kboot import KBootImage
|
|
from spartados import SpartaDosDiskImage
|
|
from utils import to_numpy
|
|
|
|
def process(image, dirent, options):
|
|
skip = False
|
|
action = "copying to"
|
|
filename = dirent.get_filename()
|
|
outfilename = filename
|
|
if options.no_sys:
|
|
if dirent.ext == "SYS":
|
|
skip = True
|
|
action = "skipping system file"
|
|
if not skip:
|
|
if options.xex:
|
|
outfilename = "%s%s.XEX" % (dirent.filename, dirent.ext)
|
|
if options.lower:
|
|
outfilename = outfilename.lower()
|
|
|
|
if options.dry_run:
|
|
action = "DRY_RUN: %s" % action
|
|
skip = True
|
|
if options.extract:
|
|
print "%s: %s %s" % (dirent, action, outfilename)
|
|
if not skip:
|
|
bytes = image.get_file(dirent)
|
|
with open(outfilename, "wb") as fh:
|
|
fh.write(bytes)
|
|
else:
|
|
print dirent
|
|
|
|
def run():
|
|
import sys
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Extract images off ATR format disks")
|
|
parser.add_argument("-v", "--verbose", default=0, action="count")
|
|
parser.add_argument("-d", "--debug", action="store_true", default=False, help="debug the currently under-development parser")
|
|
parser.add_argument("-l", "--lower", action="store_true", default=False, help="convert filenames to lower case")
|
|
parser.add_argument("--dry-run", action="store_true", default=False, help="don't extract, just show what would have been extracted")
|
|
parser.add_argument("-n", "--no-sys", action="store_true", default=False, help="only extract things that look like games (no DOS or .SYS files)")
|
|
parser.add_argument("-x", "--extract", action="store_true", default=False, help="extract files")
|
|
parser.add_argument("--xex", action="store_true", default=False, help="add .xex extension")
|
|
parser.add_argument("-f", "--force", action="store_true", default=False, help="force operation on disk images that have bad directory entries or look like boot disks")
|
|
parser.add_argument("files", metavar="ATR", nargs="+", help="an ATR image file [or a list of them]")
|
|
parser.add_argument("-s", "--segments", action="store_true", default=False, help="display segments")
|
|
options, extra_args = parser.parse_known_args()
|
|
|
|
for filename in options.files:
|
|
with open(filename, "rb") as fh:
|
|
data = fh.read()
|
|
image = None
|
|
if options.debug:
|
|
data = to_numpy(data)
|
|
header = AtrHeader(data[0:16])
|
|
image = SpartaDosDiskImage(data, filename)
|
|
else:
|
|
try:
|
|
data = to_numpy(data)
|
|
try:
|
|
header = AtrHeader(data[0:16])
|
|
for format in [KBootImage, SpartaDosDiskImage, AtariDosDiskImage]:
|
|
if options.verbose: print "trying", format.__name__
|
|
try:
|
|
image = format(data, filename)
|
|
print "%s: %s" % (filename, image)
|
|
break
|
|
except InvalidDiskImage:
|
|
pass
|
|
except AtrError:
|
|
for format in [AtariDosDiskImage]:
|
|
try:
|
|
image = format(data)
|
|
print "%s: %s" % (filename, image)
|
|
break
|
|
except:
|
|
raise
|
|
#pass
|
|
except AtrError:
|
|
if options.verbose: print "%s: Doesn't look like a supported disk image" % filename
|
|
try:
|
|
image = AtariDosFile(data)
|
|
print "%s:\n%s" % (filename, image)
|
|
except InvalidBinaryFile:
|
|
if options.verbose: print "%s: Doesn't look like an XEX either" % filename
|
|
continue
|
|
if image is None:
|
|
image = BootDiskImage(data, filename)
|
|
if options.segments:
|
|
image.parse_segments()
|
|
print "\n".join([str(a) for a in image.segments])
|
|
elif image.files or options.force:
|
|
for dirent in image.files:
|
|
try:
|
|
process(image, dirent, options)
|
|
except FileNumberMismatchError164:
|
|
print "Error 164: %s" % str(dirent)
|
|
except ByteNotInFile166:
|
|
print "Invalid sector for: %s" % str(dirent)
|
|
|
|
if __name__ == "__main__":
|
|
run()
|