mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Introduces an explicit area of floating bus, starts adding bus errors.
This commit is contained in:
parent
332f0d6167
commit
0ed87c61bd
@ -83,7 +83,8 @@ class ConcreteMachine:
|
|||||||
// Set up basic memory map.
|
// Set up basic memory map.
|
||||||
memory_map_[0] = BusDevice::MostlyRAM;
|
memory_map_[0] = BusDevice::MostlyRAM;
|
||||||
int c = 1;
|
int c = 1;
|
||||||
for(; c < 0x08; ++c) memory_map_[c] = BusDevice::RAM;
|
for(; c < int(ram_.size() >> 15); ++c) memory_map_[c] = BusDevice::RAM;
|
||||||
|
for(; c < 0x40; ++c) memory_map_[c] = BusDevice::Floating;
|
||||||
for(; c < 0xff; ++c) memory_map_[c] = BusDevice::Unassigned;
|
for(; c < 0xff; ++c) memory_map_[c] = BusDevice::Unassigned;
|
||||||
|
|
||||||
const bool is_early_tos = true;
|
const bool is_early_tos = true;
|
||||||
@ -174,19 +175,30 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
// If this is a new strobing of the address signal, test for bus error and pre-DTack delay.
|
// If this is a new strobing of the address signal, test for bus error and pre-DTack delay.
|
||||||
//
|
//
|
||||||
// DTack delay rule: if accessing RAM or the shifter, align with the two cycles next available
|
|
||||||
// for the CPU to access that side of the bus.
|
|
||||||
HalfCycles delay(0);
|
HalfCycles delay(0);
|
||||||
if((cycle.operation & Microcycle::NewAddress) && (address < ram_.size() || (address == (0xff8260 >> 1)))) {
|
if(cycle.operation & Microcycle::NewAddress) {
|
||||||
// DTack will be implicit; work out how long until that should be,
|
if(
|
||||||
// and apply bus error constraints.
|
// Anything unassigned should generate a bus error.
|
||||||
const int i_phase = bus_phase_.as<int>() & 7;
|
(memory_map_[address >> 15] == BusDevice::Unassigned) ||
|
||||||
if(i_phase < 4) {
|
|
||||||
delay = HalfCycles(4 - i_phase);
|
// Bus errors also apply to unprivileged access to the first 0x800 bytes, or the IO area.
|
||||||
advance_time(delay);
|
(!is_supervisor && (address < 0x400 || memory_map_[address >> 15] == BusDevice::IO))
|
||||||
|
) {
|
||||||
|
mc68000_.set_bus_error(true);
|
||||||
|
return delay; // TODO: there should be an extra delay here.
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: presumably test is if(after declared memory size and (not supervisor or before hardware space)) bus_error?
|
// DTack delay rule: if accessing RAM or the shifter, align with the two cycles next available
|
||||||
|
// for the CPU to access that side of the bus.
|
||||||
|
if(address < ram_.size() || (address == (0xff8260 >> 1))) {
|
||||||
|
// DTack will be implicit; work out how long until that should be,
|
||||||
|
// and apply bus error constraints.
|
||||||
|
const int i_phase = bus_phase_.as<int>() & 7;
|
||||||
|
if(i_phase < 4) {
|
||||||
|
delay = HalfCycles(4 - i_phase);
|
||||||
|
advance_time(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *memory = nullptr;
|
uint16_t *memory = nullptr;
|
||||||
@ -199,8 +211,6 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
case BusDevice::RAM:
|
case BusDevice::RAM:
|
||||||
memory = ram_.data();
|
memory = ram_.data();
|
||||||
address &= ram_.size() - 1;
|
|
||||||
// TODO: align with the next access window.
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BusDevice::ROM:
|
case BusDevice::ROM:
|
||||||
@ -208,8 +218,9 @@ class ConcreteMachine:
|
|||||||
address %= rom_.size();
|
address %= rom_.size();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BusDevice::Floating:
|
||||||
|
// TODO: provide vapour reads here. But: will these always be of the last video fetch?
|
||||||
case BusDevice::Unassigned:
|
case BusDevice::Unassigned:
|
||||||
// TODO: figure out the rules about bus errors.
|
|
||||||
case BusDevice::Cartridge:
|
case BusDevice::Cartridge:
|
||||||
/*
|
/*
|
||||||
TOS 1.0 appears to attempt to read from the catridge before it has setup
|
TOS 1.0 appears to attempt to read from the catridge before it has setup
|
||||||
@ -443,7 +454,20 @@ class ConcreteMachine:
|
|||||||
std::vector<uint16_t> rom_;
|
std::vector<uint16_t> rom_;
|
||||||
|
|
||||||
enum class BusDevice {
|
enum class BusDevice {
|
||||||
MostlyRAM, RAM, ROM, Cartridge, IO, Unassigned
|
/// A mostly RAM page is one that returns ROM for the first 8 bytes, RAM elsewhere.
|
||||||
|
MostlyRAM,
|
||||||
|
/// Allows reads and writes to ram_.
|
||||||
|
RAM,
|
||||||
|
/// Nothing is mapped to this area, and it also doesn't trigger an exception upon access.
|
||||||
|
Floating,
|
||||||
|
/// Allows reading from rom_; writes do nothing.
|
||||||
|
ROM,
|
||||||
|
/// Allows interaction with a cartrige_.
|
||||||
|
Cartridge,
|
||||||
|
/// Marks the IO page, in which finer decoding will occur.
|
||||||
|
IO,
|
||||||
|
/// An unassigned page has nothing below it, in a way that triggers exceptions.
|
||||||
|
Unassigned
|
||||||
};
|
};
|
||||||
BusDevice memory_map_[256];
|
BusDevice memory_map_[256];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user