mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Edges towards a working memory subsystem. At least structurally.
This commit is contained in:
parent
43611792ac
commit
817f93a490
@ -46,6 +46,25 @@ class ConcreteMachine:
|
||||
if(!roms[0]) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
}
|
||||
rom_ = *roms[0];
|
||||
|
||||
size_t ram_size = 0;
|
||||
switch(target.memory_model) {
|
||||
case Target::MemoryModel::TwoHundredAndFiftySixKB:
|
||||
ram_size = 256;
|
||||
break;
|
||||
|
||||
case Target::MemoryModel::OneMB:
|
||||
ram_size = 256 + 1024;
|
||||
break;
|
||||
|
||||
case Target::MemoryModel::EightMB:
|
||||
ram_size = 256 + 8 * 1024;
|
||||
break;
|
||||
}
|
||||
ram_.resize(ram_size * 1024);
|
||||
|
||||
// TODO: establish initial bus mapping and storage.
|
||||
}
|
||||
|
||||
void run_for(const Cycles cycles) override {
|
||||
@ -60,11 +79,82 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
forceinline Cycles perform_bus_operation(const CPU::WDC65816::BusOperation operation, const uint32_t address, uint8_t *const value) {
|
||||
return Cycles(5);
|
||||
const BankMapping &mapping = bank_mapping_[address >> 8];
|
||||
|
||||
if(mapping.flags & BankMapping::IsIO) {
|
||||
// TODO: all IO accesses.
|
||||
} else {
|
||||
const BankStorage &storage = bank_storage_[mapping.destination];
|
||||
|
||||
// TODO: branching below is predicated on the idea that an extra 64kb of scratch write area
|
||||
// and 64kb of 0xffs would be worse than branching due to the data set increase. Verify that?
|
||||
if(isReadOperation(operation)) {
|
||||
*value = storage.read ? storage.read[address & 0xffff] : 0xff;
|
||||
} else {
|
||||
if(storage.write) {
|
||||
storage.write[address & 0xffff] = *value;
|
||||
if(mapping.flags & BankMapping::IsShadowed) {
|
||||
bank_storage_[mapping.destination + 0xe0].write[address & 0xffff] = *value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cycles duration;
|
||||
|
||||
// Determine the cost of this access.
|
||||
if((mapping.flags & BankMapping::Is1Mhz) || ((mapping.flags & BankMapping::IsShadowed) && !isReadOperation(operation))) {
|
||||
// TODO: (i) get into phase; (ii) allow for the 1Mhz bus length being sporadically 16 rather than 14.
|
||||
duration = Cycles(14);
|
||||
} else {
|
||||
// TODO: (i) get into phase; (ii) allow for collisions with the refresh cycle.
|
||||
duration = Cycles(5);
|
||||
}
|
||||
fast_access_phase_ = (fast_access_phase_ + duration.as<int>()) % 5; // TODO: modulo something else, to allow for refresh.
|
||||
slow_access_phase_ = (slow_access_phase_ + duration.as<int>()) % 14; // TODO: modulo something else, to allow for stretched cycles.
|
||||
return duration;
|
||||
}
|
||||
|
||||
private:
|
||||
CPU::WDC65816::Processor<ConcreteMachine, false> m65816_;
|
||||
|
||||
int fast_access_phase_ = 0;
|
||||
int slow_access_phase_ = 0;
|
||||
|
||||
// MARK: - Memory layout and storage.
|
||||
|
||||
// Memory layout part 1: the bank mapping. Indexed by the top 16 bits of the address,
|
||||
// each entry provides the actual bank that should be used plus some flags affecting the
|
||||
// access: whether this section of memory is currently enabled for shadowing, whether
|
||||
// accesses should cost 1 Mhz, and whether this is actually an IO area.
|
||||
//
|
||||
// Implementation note: the shadow and IO flags are more sensibly part of this table;
|
||||
// logically the 1Mhz flag would ideally go with BankStorage but since there's no space
|
||||
// in there currently set aside for flags, keeping it in the mapping will do.
|
||||
struct BankMapping {
|
||||
uint8_t destination = 0;
|
||||
uint8_t flags = 0;
|
||||
|
||||
enum Flag: uint8_t {
|
||||
IsShadowed = 1 << 0,
|
||||
Is1Mhz = 1 << 1,
|
||||
IsIO = 1 << 2,
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(BankMapping) == 2);
|
||||
BankMapping bank_mapping_[65536];
|
||||
|
||||
// Memory layout part 2: the bank storage. For each bank both a read and a write pointer
|
||||
// are offered, indicating where the contents of this bank actually reside.
|
||||
struct BankStorage {
|
||||
uint8_t *write = nullptr;
|
||||
const uint8_t *read = nullptr;
|
||||
};
|
||||
BankStorage bank_storage_[256];
|
||||
|
||||
// Actual memory storage.
|
||||
std::vector<uint8_t> ram_;
|
||||
std::vector<uint8_t> rom_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user