1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +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:
Thomas Harte 2017-12-02 16:01:30 -05:00
parent d3dd8f3f2a
commit ca26ce8400
9 changed files with 94 additions and 25 deletions

View File

@ -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_++;
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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();
}
};
/*!

View File

@ -8,4 +8,5 @@
#include "Cartridge.hpp"
const int Storage::Cartridge::Cartridge::Segment::UnknownAddress = -1;
const size_t Storage::Cartridge::Cartridge::Segment::UnknownAddress = -1;

View File

@ -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_;
};
}