diff --git a/atrcopy.py b/atrcopy.py index abe8242..bdeacb1 100755 --- a/atrcopy.py +++ b/atrcopy.py @@ -233,19 +233,12 @@ class XEXSegmentSaver(SegmentSaver): class DefaultSegment(object): - debug = False savers = [SegmentSaver] - def __init__(self, start_addr=0, data=None, name="All", error=None): + def __init__(self, data, style, start_addr=0, name="All", error=None): self.start_addr = int(start_addr) # force python int to decouple from possibly being a numpy datatype - if data is None: - data = np.fromstring("", dtype=np.uint8) - else: - data = to_numpy(data) self.data = data - self.style = np.zeros_like(self.data, dtype=np.uint8) - if self.debug: - self.style = np.arange(len(self), dtype=np.uint8) + self.style = style self.error = error self.name = name self.page_size = -1 @@ -310,8 +303,8 @@ class DefaultSegment(object): return self._search_copy class ObjSegment(DefaultSegment): - def __init__(self, metadata_start, data_start, start_addr, end_addr, data, name="", error=None): - DefaultSegment.__init__(self, start_addr, data, name, error) + def __init__(self, data, style, metadata_start, data_start, start_addr, end_addr, name="", error=None): + DefaultSegment.__init__(self, data, style, start_addr, name, error) self.metadata_start = metadata_start self.data_start = data_start @@ -326,8 +319,8 @@ class XexSegment(ObjSegment): savers = [SegmentSaver, XEXSegmentSaver] class RawSectorsSegment(DefaultSegment): - def __init__(self, first_sector, num_sectors, count, data, **kwargs): - DefaultSegment.__init__(self, 0, data, **kwargs) + def __init__(self, data, style, first_sector, num_sectors, count, **kwargs): + DefaultSegment.__init__(self, data, style, 0, **kwargs) self.page_size = 128 self.first_sector = first_sector self.num_sectors = num_sectors @@ -348,9 +341,9 @@ class RawSectorsSegment(DefaultSegment): return "s%03d:%02X" % (sector + self.first_sector, byte) class IndexedByteSegment(DefaultSegment): - def __init__(self, byte_order, bytes, **kwargs): + def __init__(self, data, style, byte_order, **kwargs): self.order = byte_order - DefaultSegment.__init__(self, 0, bytes, **kwargs) + DefaultSegment.__init__(self, data, style, 0, **kwargs) def __str__(self): return "%s ($%x @ $%x)" % (self.name, len(self), self.order[0]) @@ -378,31 +371,29 @@ class AtariDosFile(object): Ref: http://www.atarimax.com/jindroush.atari.org/afmtexe.html """ - def __init__(self, data): - self.data = to_numpy(data) - self.size = len(self.data) + def __init__(self, data, style=None): + self.bytes = to_numpy(data) + self.size = np.alen(self.bytes) + if style is None: + self.style = np.zeros(self.size, dtype=np.uint8) + else: + self.style = style self.segments = [] self.parse_segments() def __str__(self): return "\n".join(str(s) for s in self.segments) + "\n" - def get_obj_segment(self, metadata_start, data_start, start_addr, end_addr, data, name=""): - """Subclass use: override this method to create a custom segment. - - By default uses an ObjSegment - """ - return ObjSegment(metadata_start, data_start, start_addr, end_addr, data, name) - def parse_segments(self): - bytes = self.data + b = self.bytes + s = self.style pos = 0 first = True while pos < self.size: if pos + 1 < self.size: - header, = bytes[pos:pos+2].view(dtype=' 0: - self.segments.append(ObjSegment(0, 0, 0, self.header.atr_header_offset, self.bytes[0:self.header.atr_header_offset], name="%s Header" % self.header.file_format)) - self.segments.append(RawSectorsSegment(1, self.header.max_sectors, self.header.image_size, self.bytes[self.header.atr_header_offset:], name="Raw disk sectors")) + self.segments.append(ObjSegment(b[0:i], s[0:i], 0, 0, 0, i, name="%s Header" % self.header.file_format)) + self.segments.append(RawSectorsSegment(b[i:], s[i:], 1, self.header.max_sectors, self.header.image_size, name="Raw disk sectors")) self.segments.extend(self.get_boot_segments()) self.segments.extend(self.get_vtoc_segments()) self.segments.extend(self.get_directory_segments()) @@ -550,14 +543,16 @@ class BootDiskImage(DiskImageBase): def check_size(self): self.header.check_size(self.size) + start, size = self.header.get_pos(1) + b = self.bytes i = self.header.atr_header_offset - flag = self.bytes[i:i + 2].view(dtype=' 0: start, count = self.get_contiguous_sectors(self.vtoc2, 1) - segment = RawSectorsSegment(self.vtoc2, 1, count, self.bytes[start:start+count], name="VTOC2") + segment = RawSectorsSegment(b[start:start+count], s[start:start+count], self.vtoc2, 1, count, name="VTOC2") segments.append(segment) return segments def get_directory_segments(self): + b = self.bytes + s = self.style segments = [] addr = 0 start, count = self.get_contiguous_sectors(361, 8) - segment = RawSectorsSegment(361, 8, count, self.bytes[start:start+count], name="Directory") + segment = RawSectorsSegment(b[start:start+count], s[start:start+count], 361, 8, count, name="Directory") segments.append(segment) return segments @@ -694,7 +695,7 @@ class AtariDosDiskImage(DiskImageBase): byte_order.extend(range(pos, pos + size)) if last: break - segment = IndexedByteSegment(byte_order, self.bytes, name=dirent.get_filename()) + segment = IndexedByteSegment(self.bytes, self.style, byte_order, name=dirent.get_filename()) return segment @@ -743,7 +744,9 @@ class KBootImage(DiskImageBase): self.files = [dirent] def get_file_segment(self, dirent): - return XexSegment(0, 0, 0, dirent.exe_start, self.bytes[dirent.exe_start:dirent.exe_start + dirent.exe_size], name="KBoot Executable") + start = dirent.exe_start + end = dirent.exe_start + dirent.exe_size + return XexSegment(self.bytes[start:end], self.style[start:end], 0, 0, 0, start, name="KBoot Executable") def to_numpy(value): @@ -812,7 +815,7 @@ def run(): break except InvalidDiskImage: pass - except InvalidAtrHeader: + except AtrError: for format in [AtariDosDiskImage]: try: image = format(data) @@ -821,7 +824,7 @@ def run(): except: raise #pass - except: + except AtrError: if options.verbose: print "%s: Doesn't look like a supported disk image" % filename try: image = AtariDosFile(data)