1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Merge pull request #892 from TomHarte/FixedFloatingBus

Attempts to implement proper floating bus behaviour.
This commit is contained in:
Thomas Harte 2021-03-24 21:44:01 -04:00 committed by GitHub
commit e42b6cb3c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 5 deletions

View File

@ -167,6 +167,8 @@ template <VideoTiming timing> class Video {
last_fetches_[1] = memory_[attribute_address_];
last_fetches_[2] = memory_[pixel_address_+1];
last_fetches_[3] = memory_[attribute_address_+1];
set_last_contended_area_access(last_fetches_[3]);
pixel_address_ += 2;
attribute_address_ += 2;
@ -315,21 +317,37 @@ template <VideoTiming timing> class Video {
}
/*!
@returns Whatever the ULA or gate array has fetched this cycle, or 0xff if it has fetched nothing.
@returns Whatever the ULA or gate array would expose via the floating bus, this cycle.
*/
uint8_t get_current_fetch() const {
uint8_t get_floating_value() const {
constexpr auto timings = get_timings();
const int line = time_into_frame_ / timings.cycles_per_line;
if(line >= 192) return 0xff;
const int time_into_line = time_into_frame_ % timings.cycles_per_line;
if(time_into_line >= 256 || (time_into_line&8)) {
return 0xff;
return last_contended_access_;
}
// The +2a and +3 always return the low bit as set.
if constexpr (timing == VideoTiming::Plus3) {
return last_fetches_[(time_into_line >> 1) & 3] | 1;
}
return last_fetches_[(time_into_line >> 1) & 3];
}
/*!
Relevant to the +2a and +3 only, sets the most recent value read from or
written to contended memory. This is what will be returned if the floating
bus is accessed when the gate array isn't currently reading.
*/
void set_last_contended_area_access([[maybe_unused]] uint8_t value) {
if constexpr (timing == VideoTiming::Plus3) {
last_contended_access_ = value | 1;
}
}
/*!
Sets the current border colour.
*/
@ -367,6 +385,7 @@ template <VideoTiming timing> class Video {
bool is_alternate_line_ = false;
uint8_t last_fetches_[4] = {0xff, 0xff, 0xff, 0xff};
uint8_t last_contended_access_ = 0xff;
#define RGB(r, g, b) (r << 4) | (g << 2) | b
static constexpr uint8_t palette[] = {

View File

@ -223,6 +223,10 @@ template<Model model> class ConcreteMachine:
case PartialMachineCycle::Read:
*cycle.value = read_pointers_[address >> 14][address];
if(is_contended_[address >> 14]) {
video_.last_valid()->set_last_contended_area_access(*cycle.value);
}
break;
case PartialMachineCycle::Write:
@ -230,7 +234,13 @@ template<Model model> class ConcreteMachine:
if(is_video_[address >> 14] && (address & 0x3fff) < 6912) {
video_.flush();
}
write_pointers_[address >> 14][address] = *cycle.value;
// Fill the floating bus buffer if this write is within the contended area.
if(is_contended_[address >> 14]) {
video_.last_valid()->set_last_contended_area_access(*cycle.value);
}
break;
case PartialMachineCycle::Output:
@ -331,8 +341,9 @@ template<Model model> class ConcreteMachine:
// Check for a floating bus read; these are particularly arcane
// on the +2a/+3. See footnote to https://spectrumforeveryone.com/technical/memory-contention-floating-bus/
if((address & 0xf003) == 0x0001) {
*cycle.value &= video_->get_current_fetch();
// and, much more rigorously, http://sky.relative-path.com/zx/floating_bus.html
if(!disable_paging_ && (address & 0xf003) == 0x0001) {
*cycle.value &= video_->get_floating_value();
}
if constexpr (model == Model::Plus3) {