mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2024-11-29 11:51:14 +00:00
Created new segment type to hold raw sectors rather than huge number of individual segments
* added segment label function to return sector number and offset into sector given the index
This commit is contained in:
parent
784aed230e
commit
be8e0ada1a
59
atrcopy.py
59
atrcopy.py
@ -193,6 +193,7 @@ class ObjSegment(object):
|
|||||||
if name and not name.endswith(" "):
|
if name and not name.endswith(" "):
|
||||||
name += " "
|
name += " "
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.page_size = -1
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = "%s%04x-%04x (%04x @ %04x)" % (self.name, self.start_addr, self.end_addr, len(self.data), self.data_start)
|
s = "%s%04x-%04x (%04x @ %04x)" % (self.name, self.start_addr, self.end_addr, len(self.data), self.data_start)
|
||||||
@ -206,6 +207,29 @@ class ObjSegment(object):
|
|||||||
def __getitem__(self, val):
|
def __getitem__(self, val):
|
||||||
return self.data[val]
|
return self.data[val]
|
||||||
|
|
||||||
|
def label(self, index):
|
||||||
|
return "%04x" % (index + self.start_addr)
|
||||||
|
|
||||||
|
class RawSectorsSegment(ObjSegment):
|
||||||
|
def __init__(self, first_sector, num_sectors, count, data, **kwargs):
|
||||||
|
ObjSegment.__init__(self, 0, 0, 0, count, data, **kwargs)
|
||||||
|
self.page_size = 128
|
||||||
|
self.first_sector = first_sector
|
||||||
|
self.num_sectors = num_sectors
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.num_sectors > 1:
|
||||||
|
s = "%s (sectors %d-%d)" % (self.name, self.first_sector, self.first_sector + self.num_sectors - 1)
|
||||||
|
else:
|
||||||
|
s = "%s (sector %d)" % (self.name, self.first_sector)
|
||||||
|
if self.error:
|
||||||
|
s += " " + self.error
|
||||||
|
return s
|
||||||
|
|
||||||
|
def label(self, index):
|
||||||
|
sector, byte = divmod(index, self.page_size)
|
||||||
|
return "s%03d:%02x" % (sector + self.first_sector, byte)
|
||||||
|
|
||||||
class AtariDosFile(object):
|
class AtariDosFile(object):
|
||||||
"""Parse a binary chunk into segments according to the Atari DOS object
|
"""Parse a binary chunk into segments according to the Atari DOS object
|
||||||
file format.
|
file format.
|
||||||
@ -262,6 +286,7 @@ class AtrDiskImage(object):
|
|||||||
self.bytes = bytes
|
self.bytes = bytes
|
||||||
self.header = None
|
self.header = None
|
||||||
self.first_vtoc = 360
|
self.first_vtoc = 360
|
||||||
|
self.num_vtoc = 1
|
||||||
self.first_data_after_vtoc = 369
|
self.first_data_after_vtoc = 369
|
||||||
self.total_sectors = 0
|
self.total_sectors = 0
|
||||||
self.unused_sectors = 0
|
self.unused_sectors = 0
|
||||||
@ -331,6 +356,7 @@ class AtrDiskImage(object):
|
|||||||
else:
|
else:
|
||||||
num = (code * 2) - 3
|
num = (code * 2) - 3
|
||||||
self.first_vtoc = 360 - num + 1
|
self.first_vtoc = 360 - num + 1
|
||||||
|
self.num_vtoc = num
|
||||||
self.total_sectors = values[1]
|
self.total_sectors = values[1]
|
||||||
self.unused_sectors = values[2]
|
self.unused_sectors = values[2]
|
||||||
|
|
||||||
@ -371,6 +397,16 @@ class AtrDiskImage(object):
|
|||||||
return bytes
|
return bytes
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def get_contiguous_sectors(self, sector, num):
|
||||||
|
start = 0
|
||||||
|
count = 0
|
||||||
|
for index in range(sector, sector + num):
|
||||||
|
pos, size = self.header.get_pos(index)
|
||||||
|
if start == 0:
|
||||||
|
start = pos
|
||||||
|
count += size
|
||||||
|
return start, count
|
||||||
|
|
||||||
def get_boot_segments(self):
|
def get_boot_segments(self):
|
||||||
bytes = self.get_sectors(1)[0:20]
|
bytes = self.get_sectors(1)[0:20]
|
||||||
values = struct.unpack("<BBHHBHBBBHBHBH", bytes)
|
values = struct.unpack("<BBHHBHBBBHBHBH", bytes)
|
||||||
@ -386,22 +422,29 @@ class AtrDiskImage(object):
|
|||||||
segments = [sectors, header, code]
|
segments = [sectors, header, code]
|
||||||
return segments
|
return segments
|
||||||
|
|
||||||
def get_sector_segments(self):
|
def get_vtoc_segments(self):
|
||||||
segments = []
|
segments = []
|
||||||
addr = 0
|
addr = 0
|
||||||
for index in range(1, self.header.max_sectors + 1):
|
start, count = self.get_contiguous_sectors(self.first_vtoc, self.num_vtoc)
|
||||||
bytes = self.get_sectors(index)
|
segment = RawSectorsSegment(self.first_vtoc, self.num_vtoc, count, self.bytes[start:start+count], name="VTOC")
|
||||||
sector = ObjSegment(0, 0, addr, addr + len(bytes), bytes, name="Sector %03d" % (index))
|
segments.append(segment)
|
||||||
addr += len(bytes)
|
return segments
|
||||||
segments.append(sector)
|
|
||||||
|
def get_directory_segments(self):
|
||||||
|
segments = []
|
||||||
|
addr = 0
|
||||||
|
start, count = self.get_contiguous_sectors(361, 8)
|
||||||
|
segment = RawSectorsSegment(361, 8, count, self.bytes[start:start+count], name="Directory")
|
||||||
|
segments.append(segment)
|
||||||
return segments
|
return segments
|
||||||
|
|
||||||
def parse_segments(self):
|
def parse_segments(self):
|
||||||
if self.header.size_in_bytes > 0:
|
if self.header.size_in_bytes > 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(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(ObjSegment(0, 0, 0, self.header.size_in_bytes, self.bytes[self.header.atr_header_offset:], name="Raw disk sectors"))
|
self.segments.append(RawSectorsSegment(1, self.header.max_sectors, self.header.size_in_bytes, self.bytes[self.header.atr_header_offset:], name="Raw disk sectors"))
|
||||||
self.segments.extend(self.get_boot_segments())
|
self.segments.extend(self.get_boot_segments())
|
||||||
self.segments.extend(self.get_sector_segments())
|
self.segments.extend(self.get_vtoc_segments())
|
||||||
|
self.segments.extend(self.get_directory_segments())
|
||||||
|
|
||||||
# for dirent in self.atr.files:
|
# for dirent in self.atr.files:
|
||||||
# try:
|
# try:
|
||||||
|
Loading…
Reference in New Issue
Block a user