mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-02-13 16:30:30 +00:00
Added --run-addr (--brun) command line param
* for dos33, have to create a tiny segment at the beginning to store a JMP if addr is not the first byte in the first segment
This commit is contained in:
parent
d50ee6639c
commit
e93f09e298
@ -1,6 +1,9 @@
|
||||
__version__ = "4.0.0"
|
||||
|
||||
import sys
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import numpy as np
|
||||
@ -143,7 +146,7 @@ def list_files(image, files):
|
||||
print dirent.extra_metadata(image)
|
||||
|
||||
|
||||
def assemble(image, source_files, data_files):
|
||||
def assemble(image, source_files, data_files, run_addr=""):
|
||||
if source_files:
|
||||
try:
|
||||
import pyatasm
|
||||
@ -156,15 +159,17 @@ def assemble(image, source_files, data_files):
|
||||
asm = pyatasm.Assemble(name)
|
||||
except SyntaxError, e:
|
||||
raise AtrError("Assembly error: %s" % e.msg)
|
||||
log.debug("Assembled %s into:" % name)
|
||||
for first, last, object_code in asm.segments:
|
||||
s = segments.add_segment(object_code, first)
|
||||
print s.name
|
||||
log.debug(" %s" % s.name)
|
||||
for name in data_files:
|
||||
if "@" not in name:
|
||||
raise AtrError("Data files must include a load address specified with the @ char")
|
||||
name, addr = name.rsplit("@", 1)
|
||||
first = text_to_int(addr)
|
||||
subset = slice(0, -1)
|
||||
log.debug("Adding data file %s at $%04x" % (name, first))
|
||||
subset = slice(0, sys.maxint)
|
||||
if "[" in name and "]" in name:
|
||||
name, slicetext = name.rsplit("[", 1)
|
||||
if ":" in slicetext:
|
||||
@ -183,11 +188,17 @@ def assemble(image, source_files, data_files):
|
||||
with open(name, 'rb') as fh:
|
||||
data = fh.read()[subset]
|
||||
s = segments.add_segment(data, first)
|
||||
print s.name
|
||||
log.debug("read data for %s" % s.name)
|
||||
if options.verbose:
|
||||
for s in segments:
|
||||
print "%s - %04x)" % (str(s)[:-1], s.start_addr + len(s))
|
||||
file_data, filetype = image.create_executable_file_image(segments)
|
||||
if run_addr:
|
||||
try:
|
||||
run_addr = text_to_int(run_addr)
|
||||
except ValueError:
|
||||
run_addr = None
|
||||
|
||||
file_data, filetype = image.create_executable_file_image(segments, run_addr)
|
||||
changed = save_file(image, options.output, filetype, file_data)
|
||||
if changed:
|
||||
image.save()
|
||||
@ -216,6 +227,7 @@ def run():
|
||||
parser.add_argument("-t", "--filetype", action="store", default="", help="file type metadata for writing to disk images that require it")
|
||||
parser.add_argument("-s", "--asm", nargs="+", action="append", help="source file(s) to assemble using pyatasm (requires -o to specify filename stored on disk image)")
|
||||
parser.add_argument("-b", "--bytes", nargs="+", action="append", help="data file(s) to add to assembly, specify as file@addr (requires -o to specify filename stored on disk image)")
|
||||
parser.add_argument("--run-addr", "--brun", action="store", default="", help="run address of binary file if not the first byte of the first segment")
|
||||
parser.add_argument("-o", "--output", action="store", default="", help="output file name for those commands that need it")
|
||||
parser.add_argument("-f", "--force", action="store_true", default=False, help="force operation, allowing file overwrites or attempt operation on non-standard disk images")
|
||||
parser.add_argument("--all", action="store_true", default=False, help="operate on all files on disk image")
|
||||
@ -276,7 +288,7 @@ def run():
|
||||
elif options.asm or options.bytes:
|
||||
asm = options.asm[0] if options.asm else []
|
||||
datafiles = options.bytes[0] if options.bytes else []
|
||||
assemble(parser.image, asm, datafiles)
|
||||
assemble(parser.image, asm, datafiles, options.run_addr)
|
||||
else:
|
||||
list_files(parser.image, file_list)
|
||||
|
||||
|
@ -649,7 +649,7 @@ class AtariDosDiskImage(DiskImageBase):
|
||||
log.debug("%s not a binary file; skipping segment generation" % str(segment))
|
||||
return segments_out
|
||||
|
||||
def create_executable_file_image(self, segments,run_addr=None):
|
||||
def create_executable_file_image(self, segments, run_addr=None):
|
||||
return get_xex(segments, run_addr), "XEX"
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@ import numpy as np
|
||||
from errors import *
|
||||
from diskimages import BaseHeader, DiskImageBase
|
||||
from utils import Directory, VTOC, WriteableSector, BaseSectorList, Dirent
|
||||
from segments import DefaultSegment, EmptySegment, ObjSegment, RawTrackSectorSegment, SegmentSaver, get_style_bits
|
||||
from segments import DefaultSegment, EmptySegment, ObjSegment, RawTrackSectorSegment, SegmentSaver, get_style_bits, SegmentData
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -586,21 +586,33 @@ class Dos33DiskImage(DiskImageBase):
|
||||
segment = EmptySegment(self.rawdata, name=dirent.filename)
|
||||
return segment
|
||||
|
||||
def create_executable_file_image(self, segments):
|
||||
def create_executable_file_image(self, segments, run_addr=None):
|
||||
# Apple 2 executables get executed at the first address loaded. If the
|
||||
# run_addr is not the first byte of the combined data, have to create a
|
||||
# new 3-byte segment with a "JMP run_addr" to go at the beginning
|
||||
origin = 100000000
|
||||
last = -1
|
||||
|
||||
for s in segments:
|
||||
origin = min(origin, s.start_addr)
|
||||
last = max(last, s.start_addr + len(s))
|
||||
print "contiguous bytes needed: %04x - %04x" % (origin, last)
|
||||
log.debug("contiguous bytes needed: %04x - %04x" % (origin, last))
|
||||
if run_addr and run_addr != origin:
|
||||
origin -= 3
|
||||
hi, lo = divmod(run_addr, 256)
|
||||
raw = SegmentData([0x4c, lo, hi])
|
||||
all_segments = [DefaultSegment(raw, start_addr=origin)]
|
||||
all_segments.extend(segments)
|
||||
else:
|
||||
all_segments = segments
|
||||
size = last - origin
|
||||
image = np.zeros([size + 4], dtype=np.uint8)
|
||||
words = image[0:4].view(dtype="<u2") # always little endian
|
||||
words[0] = origin
|
||||
words[1] = size
|
||||
for s in segments:
|
||||
for s in all_segments:
|
||||
index = s.start_addr - origin + 4
|
||||
print "setting data for %04x - %04x at %04x" % (s.start_addr, s.start_addr + len(s), index)
|
||||
print "setting data for %04x - %04x at index %04x" % (s.start_addr, s.start_addr + len(s), index)
|
||||
image[index:index + len(s)] = s.data
|
||||
return image, 'B'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user