1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-02 02:49:28 +00:00

Sought: (i) to instruct the CPC that it should be a 664, not a 464, if given a disk image (at least until I have RAM paging implemented for a 6128); (ii) to support ROM selection within the CPC and allow paging in of AMSDOS.

This commit is contained in:
Thomas Harte 2017-08-05 19:20:38 -04:00
parent 0f4343cd84
commit caf3ac0645
4 changed files with 58 additions and 16 deletions

View File

@ -567,8 +567,10 @@ class ConcreteMachine:
case 1: crtc_bus_handler_.set_colour(*cycle.value & 0x1f); break; case 1: crtc_bus_handler_.set_colour(*cycle.value & 0x1f); break;
case 2: case 2:
// Perform ROM paging. // Perform ROM paging.
read_pointers_[0] = (*cycle.value & 4) ? &ram_[0] : os_.data(); read_pointers_[0] = (*cycle.value & 4) ? &ram_[0] : roms_[rom_model_].data();
read_pointers_[3] = (*cycle.value & 8) ? &ram_[49152] : basic_.data();
upper_rom_is_paged_ = !(*cycle.value & 8);
read_pointers_[3] = upper_rom_is_paged_ ? roms_[upper_rom_].data() : &ram_[49152];
// Reset the interrupt timer if requested. // Reset the interrupt timer if requested.
if(*cycle.value & 0x10) interrupt_timer_.reset_count(); if(*cycle.value & 0x10) interrupt_timer_.reset_count();
@ -580,6 +582,12 @@ class ConcreteMachine:
} }
} }
// Check for an upper ROM selection
if(has_fdc_ && address == 0xdf00) {
upper_rom_ = (*cycle.value == 7) ? ROMType::AMSDOS : rom_model_ + 1;
if(upper_rom_is_paged_) read_pointers_[3] = roms_[upper_rom_].data();
}
// Check for a CRTC access // Check for a CRTC access
if(!(address & 0x4000)) { if(!(address & 0x4000)) {
switch((address >> 8) & 3) { switch((address >> 8) & 3) {
@ -666,11 +674,28 @@ class ConcreteMachine:
/// The ConfigurationTarget entry point; should configure this meachine as described by @c target. /// The ConfigurationTarget entry point; should configure this meachine as described by @c target.
void configure_as_target(const StaticAnalyser::Target &target) { void configure_as_target(const StaticAnalyser::Target &target) {
// Establish reset memory map as per machine model (or, for now, as a hard-wired 464) switch(target.amstradcpc.model) {
read_pointers_[0] = os_.data(); case StaticAnalyser::AmstradCPCModel::CPC464:
rom_model_ = ROMType::OS464;
has_fdc_ = false;
break;
case StaticAnalyser::AmstradCPCModel::CPC664:
rom_model_ = ROMType::OS664;
has_fdc_ = true;
break;
case StaticAnalyser::AmstradCPCModel::CPC6128:
rom_model_ = ROMType::OS6128;
has_fdc_ = true;
break;
}
// Establish default memory map
upper_rom_is_paged_ = true;
upper_rom_ = rom_model_ + 1;
read_pointers_[0] = roms_[rom_model_].data();
read_pointers_[1] = &ram_[16384]; read_pointers_[1] = &ram_[16384];
read_pointers_[2] = &ram_[32768]; read_pointers_[2] = &ram_[32768];
read_pointers_[3] = basic_.data(); read_pointers_[3] = roms_[upper_rom_].data();
write_pointers_[0] = &ram_[0]; write_pointers_[0] = &ram_[0];
write_pointers_[1] = &ram_[16384]; write_pointers_[1] = &ram_[16384];
@ -681,16 +706,13 @@ class ConcreteMachine:
if(!target.tapes.empty()) { if(!target.tapes.empty()) {
tape_player_.set_tape(target.tapes.front()); tape_player_.set_tape(target.tapes.front());
} }
// TODO: disks.
} }
// See header; provides the system ROMs. // See header; provides the system ROMs.
void set_rom(ROMType type, std::vector<uint8_t> data) { void set_rom(ROMType type, std::vector<uint8_t> data) {
// Keep only the two ROMs that are currently of interest. roms_[(int)type] = data;
switch(type) {
case ROMType::OS464: os_ = data; break;
case ROMType::BASIC464: basic_ = data; break;
default: break;
}
} }
// See header; sets a key as either pressed or released. // See header; sets a key as either pressed or released.
@ -722,8 +744,12 @@ class ConcreteMachine:
HalfCycles crtc_counter_; HalfCycles crtc_counter_;
HalfCycles half_cycles_since_ay_update_; HalfCycles half_cycles_since_ay_update_;
uint8_t ram_[65536]; uint8_t ram_[128 * 1024];
std::vector<uint8_t> os_, basic_; std::vector<uint8_t> roms_[7];
int rom_model_;
bool has_fdc_;
bool upper_rom_is_paged_;
int upper_rom_;
uint8_t *read_pointers_[4]; uint8_t *read_pointers_[4];
uint8_t *write_pointers_[4]; uint8_t *write_pointers_[4];

View File

@ -18,9 +18,10 @@
namespace AmstradCPC { namespace AmstradCPC {
enum ROMType: uint8_t { enum ROMType: int {
OS464, OS664, OS6128, OS464 = 0, BASIC464,
BASIC464, BASIC664, BASIC6128, OS664, BASIC664,
OS6128, BASIC6128,
AMSDOS AMSDOS
}; };

View File

@ -19,5 +19,8 @@ void StaticAnalyser::AmstradCPC::AddTargets(
target.disks = disks; target.disks = disks;
target.tapes = tapes; target.tapes = tapes;
target.cartridges = cartridges; target.cartridges = cartridges;
target.amstradcpc.model = target.disks.empty() ? AmstradCPCModel::CPC464 : AmstradCPCModel::CPC664;
destination.push_back(target); destination.push_back(target);
} }

View File

@ -46,6 +46,12 @@ enum class ZX8081MemoryModel {
SixtyFourKB SixtyFourKB
}; };
enum class AmstradCPCModel {
CPC464,
CPC664,
CPC6128
};
/*! /*!
A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration, A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration,
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness. and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
@ -61,6 +67,8 @@ struct Target {
} machine; } machine;
float probability; float probability;
// TODO: this is too C-like a solution; make Target a base class and
// turn the following into information held by more specific subclasses.
union { union {
struct { struct {
bool has_adfs; bool has_adfs;
@ -87,6 +95,10 @@ struct Target {
ZX8081MemoryModel memory_model; ZX8081MemoryModel memory_model;
bool isZX81; bool isZX81;
} zx8081; } zx8081;
struct {
AmstradCPCModel model;
} amstradcpc;
}; };
std::string loadingCommand; std::string loadingCommand;