mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-01-07 19:31:22 +00:00
Added tests for DOS 33 disk images; code still failing all tests, but making progress
This commit is contained in:
parent
4928a35700
commit
3157b13727
@ -57,14 +57,14 @@ class Dos33Dirent(object):
|
||||
format = np.dtype([
|
||||
('track', 'u1'),
|
||||
('sector', 'u1'),
|
||||
('flags', 'u1'),
|
||||
('flag', 'u1'),
|
||||
('name','S30'),
|
||||
('num_sectors','<u2'),
|
||||
])
|
||||
|
||||
def __init__(self, image, file_num=0, bytes=None):
|
||||
self.file_num = file_num
|
||||
self.flags = 0
|
||||
self.file_type = 0
|
||||
self.locked = False
|
||||
self.deleted = False
|
||||
self.track = 0
|
||||
@ -79,8 +79,8 @@ class Dos33Dirent(object):
|
||||
self.parse_raw_dirent(image, bytes)
|
||||
|
||||
def __str__(self):
|
||||
flags = self.summary()
|
||||
return "File #%-2d (%s) %03d %-30s %03d %03d" % (self.file_num, flags, self.num_sectors, self.filename, self.track, self.sector)
|
||||
flag = self.summary()
|
||||
return "File #%-2d (%s) %03d %-30s %03d %03d" % (self.file_num, flag, self.num_sectors, self.filename, self.track, self.sector)
|
||||
|
||||
type_map = {
|
||||
0x0: "T",
|
||||
@ -94,18 +94,25 @@ class Dos33Dirent(object):
|
||||
}
|
||||
|
||||
def summary(self):
|
||||
locked = "*" if self.flags else " "
|
||||
f = self.flags & 0x7f
|
||||
locked = "*" if self.locked else " "
|
||||
try:
|
||||
file_type = self.type_map[f]
|
||||
file_type = self.type_map[self.file_type]
|
||||
except KeyError:
|
||||
file_type = "?"
|
||||
flags = "%s%s" % (locked, file_type)
|
||||
return flags
|
||||
flag = "%s%s" % (locked, file_type)
|
||||
return flag
|
||||
|
||||
@property
|
||||
def verbose_info(self):
|
||||
return self.summary
|
||||
|
||||
@property
|
||||
def in_use(self):
|
||||
return not self.deleted
|
||||
|
||||
@property
|
||||
def flag(self):
|
||||
return 0xff if self.deleted else self.file_type | (0x80 * int(self.locked))
|
||||
|
||||
def parse_raw_dirent(self, image, bytes):
|
||||
if bytes is None:
|
||||
@ -114,10 +121,12 @@ class Dos33Dirent(object):
|
||||
self.track = values[0]
|
||||
if self.track == 0xff:
|
||||
self.deleted = True
|
||||
self.track = bytes[0x20]
|
||||
else:
|
||||
self.deleted = False
|
||||
self.sector = values[1]
|
||||
self.flags = values[2]
|
||||
self.file_type = values[2] & 0x7f
|
||||
self.locked = values[2] & 0x80
|
||||
self.filename = (bytes[3:0x20] - 0x80).tostring().rstrip()
|
||||
self.num_sectors = int(values[4])
|
||||
self.is_sane = self.sanity_check(image)
|
||||
@ -125,12 +134,11 @@ class Dos33Dirent(object):
|
||||
def encode_dirent(self):
|
||||
data = np.zeros([self.format.itemsize], dtype=np.uint8)
|
||||
values = data.view(dtype=self.format)[0]
|
||||
flag = (1 * int(self.opened_output)) | (2 * int(self.dos_2)) | (4 * int(self.mydos)) | (0x10 * int(self.is_dir)) | (0x20 * int(self.locked)) | (0x40 * int(self.in_use)) | (0x80 * int(self.locked))
|
||||
values[0] = flag
|
||||
values[1] = self.num_sectors
|
||||
values[2] = self.starting_sector
|
||||
values[0] = self.track
|
||||
values[1] = self.sector
|
||||
values[2] = self.flag
|
||||
values[3] = self.filename
|
||||
values[4] = self.ext
|
||||
values[4] = self.num_sectors
|
||||
return data
|
||||
|
||||
def mark_deleted(self):
|
||||
@ -215,8 +223,9 @@ class Dos33Dirent(object):
|
||||
|
||||
def set_values(self, filename, filetype, index):
|
||||
self.filename = "%-30s" % filename[0:30]
|
||||
self.flag = self.type_map.get(filetype, 0x04)
|
||||
self.file_type = self.type_map.get(filetype, 0x04)
|
||||
self.locked = False
|
||||
self.deleted = False
|
||||
|
||||
|
||||
class Dos33Header(AtrHeader):
|
||||
@ -281,6 +290,14 @@ class Dos33DiskImage(DiskImageBase):
|
||||
@property
|
||||
def payload_bytes_per_sector(self):
|
||||
return 256
|
||||
|
||||
@property
|
||||
def vtoc_class(self):
|
||||
return Dos33VTOC
|
||||
|
||||
@property
|
||||
def directory_class(self):
|
||||
return Dos33Directory
|
||||
|
||||
def get_boot_sector_info(self):
|
||||
# based on logic from a2server
|
||||
@ -326,7 +343,7 @@ class Dos33DiskImage(DiskImageBase):
|
||||
self.total_sectors = int(values['num_tracks']) * int(values['sectors_per_track'])
|
||||
self.dos_release = values['dos_release']
|
||||
|
||||
def get_directory(self):
|
||||
def get_directory(self, directory=None):
|
||||
sector = self.first_catalog
|
||||
num = 0
|
||||
files = []
|
||||
@ -338,10 +355,14 @@ class Dos33DiskImage(DiskImageBase):
|
||||
i = 0xb
|
||||
while i < 256:
|
||||
dirent = Dos33Dirent(self, num, values[i:i+0x23])
|
||||
if not dirent.is_sane:
|
||||
sector = 0
|
||||
if dirent.flag == 0:
|
||||
break
|
||||
files.append(dirent)
|
||||
if not dirent.is_sane:
|
||||
self.all_sane = False
|
||||
else:
|
||||
files.append(dirent)
|
||||
if directory is not None:
|
||||
directory.set(num, dirent)
|
||||
print dirent
|
||||
i += 0x23
|
||||
num += 1
|
||||
@ -389,12 +410,14 @@ class Dos33DiskImage(DiskImageBase):
|
||||
return segments
|
||||
|
||||
def get_next_directory_sector(self, sector):
|
||||
if sector == -1:
|
||||
sector = self.first_catalog
|
||||
self.assert_valid_sector(sector)
|
||||
print "reading catalog sector", sector
|
||||
raw, _, _ = self.get_raw_bytes(sector)
|
||||
next_sector = self.header.sector_from_track(raw[1], raw[2])
|
||||
if next_sector == 0:
|
||||
# need to figure out where the next sector should be
|
||||
raise NoSpaceInDirectory("No space left in catalog")
|
||||
|
||||
def get_file_segment(self, dirent):
|
||||
byte_order = []
|
||||
|
@ -2,15 +2,19 @@ import numpy as np
|
||||
|
||||
from mock import *
|
||||
|
||||
from atrcopy import SegmentData, AtariDosDiskImage, InvalidBinaryFile
|
||||
from atrcopy import SegmentData, AtariDosDiskImage, Dos33DiskImage,InvalidBinaryFile
|
||||
from atrcopy.errors import *
|
||||
|
||||
|
||||
class TestAtariDosSDImage(object):
|
||||
class BaseFilesystemModifyTest(object):
|
||||
diskimage_type = None
|
||||
sample_file = None
|
||||
num_files_in_sample = 0
|
||||
|
||||
def setup(self):
|
||||
data = np.fromfile("../test_data/dos_sd_test1.atr", dtype=np.uint8)
|
||||
data = np.fromfile(self.sample_file, dtype=np.uint8)
|
||||
rawdata = SegmentData(data)
|
||||
self.image = AtariDosDiskImage(rawdata)
|
||||
self.image = self.diskimage_type(rawdata)
|
||||
|
||||
def check_entries(self, entries, prefix="TEST", save=None):
|
||||
orig_num_files = len(self.image.files)
|
||||
@ -39,21 +43,21 @@ class TestAtariDosSDImage(object):
|
||||
return filenames
|
||||
|
||||
def test_small(self):
|
||||
assert len(self.image.files) == 5
|
||||
assert len(self.image.files) == self.num_files_in_sample
|
||||
|
||||
data = np.asarray([0xff, 0xff, 0x00, 0x60, 0x01, 0x60, 1, 2], dtype=np.uint8)
|
||||
self.image.write_file("TEST.XEX", None, data)
|
||||
assert len(self.image.files) == 6
|
||||
assert len(self.image.files) == self.num_files_in_sample + 1
|
||||
|
||||
data2 = self.image.find_file("TEST.XEX")
|
||||
assert data.tostring() == data2
|
||||
|
||||
def test_50k(self):
|
||||
assert len(self.image.files) == 5
|
||||
assert len(self.image.files) == self.num_files_in_sample
|
||||
|
||||
data = np.arange(50*1024, dtype=np.uint8)
|
||||
self.image.write_file("RAMP50K.BIN", None, data)
|
||||
assert len(self.image.files) == 6
|
||||
assert len(self.image.files) == self.num_files_in_sample + 1
|
||||
|
||||
data2 = self.image.find_file("RAMP50K.BIN")
|
||||
assert data.tostring() == data2
|
||||
@ -75,14 +79,14 @@ class TestAtariDosSDImage(object):
|
||||
self.check_entries(entries, save="many_small.atr")
|
||||
|
||||
def test_big_failure(self):
|
||||
assert len(self.image.files) == 5
|
||||
assert len(self.image.files) == self.num_files_in_sample
|
||||
|
||||
data = np.arange(50*1024, dtype=np.uint8)
|
||||
self.image.write_file("RAMP50K.BIN", None, data)
|
||||
assert len(self.image.files) == 6
|
||||
assert len(self.image.files) == self.num_files_in_sample + 1
|
||||
with pytest.raises(NotEnoughSpaceOnDisk):
|
||||
self.image.write_file("RAMP50K2.BIN", None, data)
|
||||
assert len(self.image.files) == 6
|
||||
assert len(self.image.files) == self.num_files_in_sample + 1
|
||||
|
||||
def test_delete(self):
|
||||
entries1 = [
|
||||
@ -104,15 +108,25 @@ class TestAtariDosSDImage(object):
|
||||
]
|
||||
|
||||
filenames = self.check_entries(entries1, "FIRST")
|
||||
assert len(self.image.files) == 16
|
||||
assert len(self.image.files) == self.num_files_in_sample + 11
|
||||
self.image.delete_file(filenames[2])
|
||||
self.image.delete_file(filenames[5])
|
||||
self.image.delete_file(filenames[0])
|
||||
self.image.delete_file(filenames[8])
|
||||
assert len(self.image.files) == 12
|
||||
assert len(self.image.files) == self.num_files_in_sample + 7
|
||||
|
||||
filename = self.check_entries(entries2, "SECOND", save="test_delete.atr")
|
||||
assert len(self.image.files) == 14
|
||||
assert len(self.image.files) == self.num_files_in_sample + 9
|
||||
|
||||
# class TestAtariDosSDImage(BaseFilesystemModifyTest):
|
||||
# diskimage_type = AtariDosDiskImage
|
||||
# sample_file = "../test_data/dos_sd_test1.atr"
|
||||
# num_files_in_sample
|
||||
|
||||
class TestDos33Image(BaseFilesystemModifyTest):
|
||||
diskimage_type = Dos33DiskImage
|
||||
sample_file = "../test_data/dos33_master.dsk"
|
||||
num_files_in_sample = 19
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user