From 583c3cfe7de7a85af889e72dd11a58d6bb08027d Mon Sep 17 00:00:00 2001 From: Thomas Harte <thomas.harte@gmail.com> Date: Tue, 16 Jan 2018 22:27:41 -0500 Subject: [PATCH] Allows the MSX to load ROMs that aren't quite multiples of 8kb. --- StaticAnalyser/Acorn/StaticAnalyser.cpp | 2 +- StaticAnalyser/MSX/StaticAnalyser.cpp | 19 +++++++++++++------ Storage/Cartridge/Cartridge.hpp | 22 +++++++++++++++++++--- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/StaticAnalyser/Acorn/StaticAnalyser.cpp b/StaticAnalyser/Acorn/StaticAnalyser.cpp index c1ba2dfd2..ddcc86be4 100644 --- a/StaticAnalyser/Acorn/StaticAnalyser.cpp +++ b/StaticAnalyser/Acorn/StaticAnalyser.cpp @@ -24,7 +24,7 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> if(segments.size() != 1) continue; // which must be 8 or 16 kb in size - Storage::Cartridge::Cartridge::Segment segment = segments.front(); + const Storage::Cartridge::Cartridge::Segment &segment = segments.front(); if(segment.data.size() != 0x4000 && segment.data.size() != 0x2000) continue; // is a copyright string present? diff --git a/StaticAnalyser/MSX/StaticAnalyser.cpp b/StaticAnalyser/MSX/StaticAnalyser.cpp index 6120d5f32..c9aa4f402 100644 --- a/StaticAnalyser/MSX/StaticAnalyser.cpp +++ b/StaticAnalyser/MSX/StaticAnalyser.cpp @@ -34,10 +34,10 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> // Only one mapped item is allowed. if(segments.size() != 1) continue; - // Which must be a multiple of 16 kb in size. + // Which must be no more than 63 bytes larger than a multiple of 8 kb in size. Storage::Cartridge::Cartridge::Segment segment = segments.front(); const size_t data_size = segment.data.size(); - if(data_size < 0x2000 || data_size & 0x3fff) continue; + if(data_size < 0x2000 || (data_size & 0x1fff) > 64) continue; // Check for a ROM header at address 0; if it's not found then try 0x4000 // and adjust the start address; @@ -184,10 +184,17 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> } } - // Apply the standard MSX start address. - msx_cartridges.emplace_back(new Storage::Cartridge::Cartridge({ - Storage::Cartridge::Cartridge::Segment(start_address, segment.data) - })); + // Size down to a multiple of 8kb in size and apply the start address. + std::vector<Storage::Cartridge::Cartridge::Segment> output_segments; + if(segment.data.size() & 0x1fff) { + std::vector<uint8_t> truncated_data; + std::vector<uint8_t>::difference_type truncated_size = static_cast<std::vector<uint8_t>::difference_type>(segment.data.size() & ~0x1fff); + truncated_data.insert(truncated_data.begin(), segment.data.begin(), segment.data.begin() + truncated_size); + output_segments.emplace_back(start_address, truncated_data); + } else { + output_segments.emplace_back(start_address, segment.data); + } + msx_cartridges.emplace_back(new Storage::Cartridge::Cartridge(output_segments)); } return msx_cartridges; diff --git a/Storage/Cartridge/Cartridge.hpp b/Storage/Cartridge/Cartridge.hpp index e5dc14c31..3b92b755a 100644 --- a/Storage/Cartridge/Cartridge.hpp +++ b/Storage/Cartridge/Cartridge.hpp @@ -28,12 +28,28 @@ namespace Cartridge { class Cartridge { public: struct Segment { - Segment(size_t start_address, size_t end_address, std::vector<uint8_t> data) : - start_address(start_address), end_address(end_address), data(std::move(data)) {} + Segment(size_t start_address, size_t end_address, std::vector<uint8_t> &&data) : + start_address(start_address), end_address(end_address), data(data) {} - Segment(size_t start_address, std::vector<uint8_t> data) : + Segment(size_t start_address, size_t end_address, const std::vector<uint8_t> &data) : + start_address(start_address), end_address(end_address), data(data) {} + + Segment(size_t start_address, std::vector<uint8_t> &&data) : Segment(start_address, start_address + data.size(), data) {} + Segment(size_t start_address, const std::vector<uint8_t> &data) : + Segment(start_address, start_address + data.size(), data) {} + + Segment(Segment &&segment) : + start_address(segment.start_address), + end_address(segment.end_address), + data(std::move(segment.data)) {} + + Segment(const Segment &segment) : + start_address(segment.start_address), + end_address(segment.end_address), + data(segment.data) {} + /// Indicates that an address is unknown. static const size_t UnknownAddress;