aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2016-08-27 01:47:43 +0200
committerWalter van Niftrik2016-08-28 11:23:34 +0200
commit0a053e4ce4fa440172792e00ebfaa676b412c846 (patch)
tree79a430e8238202dfbaebd5f7aa656e6ce706f006
parent8f29f067a41548da7625ebfec43e7ca8f22dfe4a (diff)
downloadscummvm-rg350-0a053e4ce4fa440172792e00ebfaa676b412c846.tar.gz
scummvm-rg350-0a053e4ce4fa440172792e00ebfaa676b412c846.tar.bz2
scummvm-rg350-0a053e4ce4fa440172792e00ebfaa676b412c846.zip
ADL: Add support for reading .xfd Atari disk images
-rw-r--r--engines/adl/disk.cpp70
-rw-r--r--engines/adl/disk.h20
-rw-r--r--engines/adl/hires0.cpp2
-rw-r--r--engines/adl/hires2.cpp6
4 files changed, 58 insertions, 40 deletions
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 49e01f9d0f..6a5cf0b20c 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,15 +28,7 @@
namespace Adl {
-#define TRACKS 35
-// The Apple II uses either 13- or 16-sector disks. We currently pad out
-// 13-sector disks, so we set SECTORS_PER_TRACK to 16 here.
-#define SECTORS_PER_TRACK 16
-#define BYTES_PER_SECTOR 256
-#define RAW_IMAGE_SIZE(S) (TRACKS * (S) * BYTES_PER_SECTOR)
-#define NIB_IMAGE_SIZE (RAW_IMAGE_SIZE(13) * 2)
-
-static Common::SeekableReadStream *readImage_DSK(const Common::String &filename) {
+static Common::SeekableReadStream *readImage(const Common::String &filename) {
Common::File *f = new Common::File;
if (!f->open(filename)) {
@@ -44,9 +36,6 @@ static Common::SeekableReadStream *readImage_DSK(const Common::String &filename)
return nullptr;
}
- if (f->size() != RAW_IMAGE_SIZE(16))
- error("Unrecognized DSK image '%s' of size %d bytes", filename.c_str(), f->size());
-
return f;
}
@@ -63,7 +52,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
if (!f.open(filename))
return nullptr;
- if (f.size() != NIB_IMAGE_SIZE)
+ if (f.size() != 232960)
error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), f.size());
// starting at 0xaa, 32 is invalid (see below)
@@ -73,7 +62,9 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// we always pad it out
const uint sectorsPerTrack = 16;
- byte *diskImage = (byte *)calloc(RAW_IMAGE_SIZE(sectorsPerTrack), 1);
+ const uint bytesPerSector = 256;
+ const uint imageSize = 35 * sectorsPerTrack * bytesPerSector;
+ byte *const diskImage = (byte *)calloc(imageSize, 1);
bool sawAddress = false;
uint8 volNo, track, sector;
@@ -120,13 +111,13 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// We should always find the data field after an address field.
// TODO: we ignore volNo?
- byte *output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ byte *output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
if (newStyle) {
// We hardcode the DOS 3.3 mapping here. TODO: Do we also need raw/prodos?
int raw2dos[16] = { 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 };
sector = raw2dos[sector];
- output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
// 6-and-2 uses 342 on-disk bytes
byte inbuffer[342];
@@ -216,36 +207,59 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
}
}
- return new Common::MemoryReadStream(diskImage, RAW_IMAGE_SIZE(sectorsPerTrack), DisposeAfterUse::YES);
+ return new Common::MemoryReadStream(diskImage, imageSize, DisposeAfterUse::YES);
}
bool DiskImage::open(const Common::String &filename) {
Common::String lcName(filename);
lcName.toLowercase();
- if (lcName.hasSuffix(".dsk"))
- _stream = readImage_DSK(filename);
- else if (lcName.hasSuffix(".nib"))
+ if (lcName.hasSuffix(".dsk")) {
+ _stream = readImage(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".nib")) {
_stream = readImage_NIB(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".xfd")) {
+ _stream = readImage(filename);
+ _tracks = 40;
+ _sectorsPerTrack = 18;
+ _bytesPerSector = 128;
+ }
+
+ int expectedSize = _tracks * _sectorsPerTrack * _bytesPerSector;
+
+ if (!_stream)
+ return false;
+
+ if (_stream->size() != expectedSize)
+ error("Unrecognized disk image '%s' of size %d bytes (expected %d bytes)", filename.c_str(), _stream->size(), expectedSize);
- return _stream != nullptr;
+ return true;
}
const DataBlockPtr DiskImage::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _mode13));
+ return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _sectorLimit));
}
-Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorsPerTrackToRead) const {
- const uint bytesToRead = size * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
+Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorLimit) const {
+ const uint bytesToRead = size * _bytesPerSector + _bytesPerSector - offset;
byte *const data = (byte *)malloc(bytesToRead);
uint dataOffset = 0;
- if (sector > sectorsPerTrackToRead - 1)
- error("Sector %i is out of bounds for %i-sector reading", sector, sectorsPerTrackToRead);
+ if (sectorLimit == 0)
+ sectorLimit = _sectorsPerTrack;
+
+ if (sector >= sectorLimit)
+ error("Sector %i is out of bounds for %i-sector reading", sector, sectorLimit);
while (dataOffset < bytesToRead) {
- uint bytesRemInTrack = (sectorsPerTrackToRead - 1 - sector) * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
- _stream->seek((track * SECTORS_PER_TRACK + sector) * BYTES_PER_SECTOR + offset);
+ uint bytesRemInTrack = (sectorLimit - 1 - sector) * _bytesPerSector + _bytesPerSector - offset;
+ _stream->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
if (bytesToRead - dataOffset < bytesRemInTrack)
bytesRemInTrack = bytesToRead - dataOffset;
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 1041f0cebd..653d76ff10 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -74,7 +74,10 @@ class DiskImage {
public:
DiskImage() :
_stream(nullptr),
- _mode13(false) { }
+ _tracks(0),
+ _sectorsPerTrack(0),
+ _bytesPerSector(0),
+ _sectorLimit(0) { }
~DiskImage() {
delete _stream;
@@ -82,32 +85,33 @@ public:
bool open(const Common::String &filename);
const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
- Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsPerTrackToRead = 16) const;
- void setMode13(bool enable) { _mode13 = enable; }
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsUsed = 0) const;
+ void setSectorLimit(uint sectorLimit) { _sectorLimit = sectorLimit; } // Maximum number of sectors to read per track before stepping
protected:
class DataBlock : public Adl::DataBlock {
public:
- DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, bool mode13) :
+ DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, uint sectorLimit) :
_track(track),
_sector(sector),
_offset(offset),
_size(size),
- _mode13(mode13),
+ _sectorLimit(sectorLimit),
_disk(disk) { }
Common::SeekableReadStream *createReadStream() const {
- return _disk->createReadStream(_track, _sector, _offset, _size, (_mode13 ? 13 : 16));
+ return _disk->createReadStream(_track, _sector, _offset, _size, _sectorLimit);
}
private:
uint _track, _sector, _offset, _size;
- bool _mode13;
+ uint _sectorLimit;
const DiskImage *_disk;
};
Common::SeekableReadStream *_stream;
- bool _mode13; // Older 13-sector format
+ uint _tracks, _sectorsPerTrack, _bytesPerSector;
+ uint _sectorLimit;
};
// Data in plain files
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index a348779e89..875a06c73d 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -35,7 +35,7 @@ void HiRes0Engine::init() {
if (!_disk->open(IDS_HR0_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR0_DISK_IMAGE "'");
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 2));
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 14db237d82..d0e459c96c 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -37,7 +37,7 @@ void HiRes2Engine::runIntro() const {
// This only works for the 16-sector re-release. The original
// release is not supported at this time, because we don't have
// access to it.
- _disk->setMode13(false);
+ _disk->setSectorLimit(0);
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
@@ -50,7 +50,7 @@ void HiRes2Engine::runIntro() const {
_display->printString(str);
delay(2000);
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
}
void HiRes2Engine::init() {
@@ -60,7 +60,7 @@ void HiRes2Engine::init() {
if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));