mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 18:30:21 +00:00
Slightly corrects style errors in the Cartridge hierarchy, and introduces mapping of .ROM to the MSX when appropriate.
This commit is contained in:
parent
d3dd8f3f2a
commit
ca26ce8400
@ -105,14 +105,14 @@ void TMS9918::run_for(const HalfCycles cycles) {
|
||||
|
||||
while(access_pointer_ < end) {
|
||||
switch(access_pointer_%3) {
|
||||
case 2:
|
||||
pattern_name_ = ram_[row_base + character_column];
|
||||
break;
|
||||
case 1: break; // TODO: CPU access.
|
||||
case 0:
|
||||
pattern_buffer_[character_column] = ram_[pattern_generator_table_address_ + (pattern_name_ << 3) + (row_ & 7)];
|
||||
character_column++;
|
||||
break;
|
||||
case 1: break; // TODO: CPU access.
|
||||
case 2:
|
||||
pattern_name_ = ram_[row_base + character_column];
|
||||
break;
|
||||
}
|
||||
access_pointer_++;
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
AcornCartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
|
||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> acorn_cartridges;
|
||||
|
||||
for(std::shared_ptr<Storage::Cartridge::Cartridge> cartridge : cartridges) {
|
||||
const std::list<Storage::Cartridge::Cartridge::Segment> &segments = cartridge->get_segments();
|
||||
for(const auto &cartridge : cartridges) {
|
||||
const auto &segments = cartridge->get_segments();
|
||||
|
||||
// only one mapped item is allowed
|
||||
if(segments.size() != 1) continue;
|
||||
|
@ -189,7 +189,7 @@ void StaticAnalyser::Atari::AddTargets(const Media &media, std::list<Target> &de
|
||||
|
||||
// try to figure out the paging scheme
|
||||
if(!media.cartridges.empty()) {
|
||||
const std::list<Storage::Cartridge::Cartridge::Segment> &segments = media.cartridges.front()->get_segments();
|
||||
const auto &segments = media.cartridges.front()->get_segments();
|
||||
|
||||
if(segments.size() == 1) {
|
||||
const Storage::Cartridge::Cartridge::Segment &segment = segments.front();
|
||||
|
@ -21,8 +21,8 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
Vic20CartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
|
||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> vic20_cartridges;
|
||||
|
||||
for(std::shared_ptr<Storage::Cartridge::Cartridge> cartridge : cartridges) {
|
||||
const std::list<Storage::Cartridge::Cartridge::Segment> &segments = cartridge->get_segments();
|
||||
for(const auto &cartridge : cartridges) {
|
||||
const auto &segments = cartridge->get_segments();
|
||||
|
||||
// only one mapped item is allowed
|
||||
if(segments.size() != 1) continue;
|
||||
|
@ -8,11 +8,68 @@
|
||||
|
||||
#include "StaticAnalyser.hpp"
|
||||
|
||||
void StaticAnalyser::MSX::AddTargets(const Media &media, std::list<Target> &destination) {
|
||||
// Very trusting...
|
||||
Target target;
|
||||
target.machine = Target::MSX;
|
||||
target.probability = 1.0;
|
||||
target.media = media;
|
||||
destination.push_back(target);
|
||||
/*
|
||||
DEFB "AB" ; expansion ROM header
|
||||
DEFW initcode ; start of the init code, 0 if no initcode
|
||||
DEFW callstat; pointer to CALL statement handler, 0 if no such handler
|
||||
DEFW device; pointer to expansion device handler, 0 if no such handler
|
||||
DEFW basic ; pointer to the start of a tokenized basicprogram, 0 if no basicprogram
|
||||
DEFS 6,0 ; room reserved for future extensions
|
||||
*/
|
||||
static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
MSXCartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
|
||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> msx_cartridges;
|
||||
|
||||
for(const auto &cartridge : cartridges) {
|
||||
const auto &segments = cartridge->get_segments();
|
||||
|
||||
// Only one mapped item is allowed.
|
||||
if(segments.size() != 1) continue;
|
||||
|
||||
// Which must be a multiple of 16 kb in size.
|
||||
Storage::Cartridge::Cartridge::Segment segment = segments.front();
|
||||
const size_t data_size = segment.data.size();
|
||||
if(data_size < 0x4000 || data_size & 0x3fff) continue;
|
||||
|
||||
// Check for a ROM header at address 0; TODO: if it's not found then try 0x4000
|
||||
// and consider swapping the image.
|
||||
|
||||
// Check for the expansion ROM header and the reserved bytes.
|
||||
if(segment.data[0] != 0x41 || segment.data[1] != 0x42) continue;
|
||||
bool all_zeroes = true;
|
||||
for(size_t c = 0; c < 6; ++c) {
|
||||
if(segment.data[10 + c] != 0) all_zeroes = false;
|
||||
}
|
||||
if(!all_zeroes) continue;
|
||||
|
||||
// Pick a paging address based on the four pointers.
|
||||
uint16_t start_address = 0xc000;
|
||||
for(size_t c = 0; c < 8; c += 2) {
|
||||
uint16_t code_pointer = static_cast<uint16_t>(segment.data[2 + c] | segment.data[3 + c] << 8);
|
||||
if(code_pointer) {
|
||||
start_address = std::min(static_cast<uint16_t>(code_pointer &~ 0x3fff), start_address);
|
||||
}
|
||||
}
|
||||
|
||||
// That'll do then, but apply the detected start address.
|
||||
// printf("%04x\n", start_address);
|
||||
|
||||
msx_cartridges.emplace_back(new Storage::Cartridge::Cartridge({
|
||||
Storage::Cartridge::Cartridge::Segment(start_address, segment.data)
|
||||
}));
|
||||
}
|
||||
|
||||
return msx_cartridges;
|
||||
}
|
||||
|
||||
void StaticAnalyser::MSX::AddTargets(const Media &media, std::list<Target> &destination) {
|
||||
Target target;
|
||||
|
||||
target.media.cartridges = MSXCartridgesFrom(media.cartridges);
|
||||
|
||||
if(!target.media.empty()) {
|
||||
target.machine = Target::MSX;
|
||||
target.probability = 1.0;
|
||||
destination.push_back(target);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ static Media GetMediaAndPlatforms(const char *file_name, TargetPlatform::IntType
|
||||
}
|
||||
}
|
||||
|
||||
Format("rom", result.cartridges, Cartridge::BinaryDump, TargetPlatform::Acorn) // ROM
|
||||
Format("rom", result.cartridges, Cartridge::BinaryDump, TargetPlatform::Acorn | TargetPlatform::MSX) // ROM
|
||||
Format("ssd", result.disks, Disk::DiskImageHolder<Storage::Disk::SSD>, TargetPlatform::Acorn) // SSD
|
||||
Format("tap", result.tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP (Commodore)
|
||||
Format("tap", result.tapes, Tape::OricTAP, TargetPlatform::Oric) // TAP (Oric)
|
||||
|
@ -59,6 +59,10 @@ struct Media {
|
||||
std::list<std::shared_ptr<Storage::Disk::Disk>> disks;
|
||||
std::list<std::shared_ptr<Storage::Tape::Tape>> tapes;
|
||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> cartridges;
|
||||
|
||||
bool empty() const {
|
||||
return disks.empty() && tapes.empty() && cartridges.empty();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -8,4 +8,5 @@
|
||||
|
||||
#include "Cartridge.hpp"
|
||||
|
||||
const int Storage::Cartridge::Cartridge::Segment::UnknownAddress = -1;
|
||||
const size_t Storage::Cartridge::Cartridge::Segment::UnknownAddress = -1;
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#ifndef Storage_Cartridge_hpp
|
||||
#define Storage_Cartridge_hpp
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
@ -29,19 +28,22 @@ namespace Cartridge {
|
||||
class Cartridge {
|
||||
public:
|
||||
struct Segment {
|
||||
Segment(int start_address, int end_address, std::vector<uint8_t> data) :
|
||||
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(int start_address, std::vector<uint8_t> data) :
|
||||
Segment(start_address, start_address + data.size(), data) {}
|
||||
|
||||
/// Indicates that an address is unknown.
|
||||
static const int UnknownAddress;
|
||||
static const size_t UnknownAddress;
|
||||
|
||||
/// The initial CPU-exposed starting address for this segment; may be @c UnknownAddress.
|
||||
int start_address;
|
||||
size_t start_address;
|
||||
/*!
|
||||
The initial CPU-exposed ending address for this segment; may be @c UnknownAddress. Not necessarily equal
|
||||
to start_address + data_length due to potential paging.
|
||||
*/
|
||||
int end_address;
|
||||
size_t end_address;
|
||||
|
||||
/*!
|
||||
The data contents for this segment. If @c start_address and @c end_address are suppled then
|
||||
@ -51,11 +53,16 @@ class Cartridge {
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
const std::list<Segment> &get_segments() { return segments_; }
|
||||
const std::vector<Segment> &get_segments() const {
|
||||
return segments_;
|
||||
}
|
||||
virtual ~Cartridge() {}
|
||||
|
||||
Cartridge() {}
|
||||
Cartridge(const std::vector<Segment> &segments) : segments_(segments) {}
|
||||
|
||||
protected:
|
||||
std::list<Segment> segments_;
|
||||
std::vector<Segment> segments_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user