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

Ties bitplane collection to line position.

Outgoing bug: incrementing the video relative offset too often, due to cycles that are discovered to be CPU-targetted.
This commit is contained in:
Thomas Harte 2021-09-19 21:55:45 -04:00
parent 3d85f820f4
commit a4263b5a8c
2 changed files with 21 additions and 23 deletions

View File

@ -222,7 +222,7 @@ void Chipset::flush_output() {
pixels_ = nullptr; pixels_ = nullptr;
} }
/// @returns @c true if this was a CPU slot; @c false otherwise.
template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() { template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
constexpr auto BlitterFlag = DMAMask<DMAFlag::Blitter, DMAFlag::AllBelow>::value; constexpr auto BlitterFlag = DMAMask<DMAFlag::Blitter, DMAFlag::AllBelow>::value;
constexpr auto BitplaneFlag = DMAMask<DMAFlag::Bitplane, DMAFlag::AllBelow>::value; constexpr auto BitplaneFlag = DMAMask<DMAFlag::Bitplane, DMAFlag::AllBelow>::value;
@ -239,7 +239,7 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
if((dma_control_ & BitplaneFlag) == BitplaneFlag) { if((dma_control_ & BitplaneFlag) == BitplaneFlag) {
// TODO: offer a cycle for bitplane collection. // TODO: offer a cycle for bitplane collection.
// Probably need to indicate odd or even? // Probably need to indicate odd or even?
if(fetch_horizontal_ && fetch_vertical_ && bitplanes_.template advance<cycle&1>()) { if(fetch_horizontal_ && fetch_vertical_ && bitplanes_.advance(cycle)) { // TODO: cycle should be relative to start of collection.
did_fetch_ = true; did_fetch_ = true;
return false; return false;
} }
@ -278,6 +278,11 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
return (dma_control_ & BlitterFlag) != BlitterFlag || !blitter_.advance(); return (dma_control_ & BlitterFlag) != BlitterFlag || !blitter_.advance();
} }
/// Performs all slots starting with @c first_slot and ending just before @c last_slot.
/// If @c stop_on_cpu is true, stops upon discovery of a CPU slot.
///
/// @returns the number of slots completed if @c stop_on_cpu was true and a CPU slot was found.
/// @c -1 otherwise.
template <bool stop_on_cpu> int Chipset::advance_slots(int first_slot, int last_slot) { template <bool stop_on_cpu> int Chipset::advance_slots(int first_slot, int last_slot) {
if(first_slot == last_slot) { if(first_slot == last_slot) {
return -1; return -1;
@ -753,37 +758,32 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
// MARK: - Bitplanes. // MARK: - Bitplanes.
template <bool is_odd> bool Chipset::Bitplanes::advance() { bool Chipset::Bitplanes::advance(int cycle) {
// Offset is preincremented in order to simplify the exit
// pathways below. As a result all in-switch offsets are
// off by 1. This is dealt with in the macro.
++collection_offset_;
// TODO: possibly dispatch a BitplaneData. // TODO: possibly dispatch a BitplaneData.
// The chipset has responsibility for applying a delay, // The chipset has responsibility for applying a delay,
// and the pixel-level start/stop boundaries. // and the pixel-level start/stop boundaries.
#define BIND_CYCLE(offset, plane) \ #define BIND_CYCLE(offset, plane) \
case (offset + 1)&7: \ case offset: \
if(plane_count_ > plane) { \ if(plane_count_ > plane) { \
next[plane] = ram_[pointer_[plane] & ram_mask_]; \ next[plane] = ram_[pointer_[plane] & ram_mask_]; \
++pointer_[plane]; \ ++pointer_[plane]; \
if constexpr (!plane) { \ if constexpr (!plane) { \
chipset_.post_bitplanes(next); \ chipset_.post_bitplanes(next); \
} \ } \
return true; \ return true; \
} \ } \
return false; return false;
if(is_high_res_) { if(is_high_res_) {
// TODO: I'm unclear whether this is correct, or merely // TODO: I'm unclear whether this is correct, or merely
// an artefact of the way the Hardware Reference Manual // an artefact of the way the Hardware Reference Manual
// depicts per-line DMA responsibilities. // depicts per-line DMA responsibilities.
if(collection_offset_ < 4) { if(cycle < 4) {
return false; return false;
} }
switch(collection_offset_&7) { switch(cycle&7) {
default: return false; default: return false;
BIND_CYCLE(0, 3); BIND_CYCLE(0, 3);
BIND_CYCLE(1, 1); BIND_CYCLE(1, 1);
@ -795,7 +795,7 @@ template <bool is_odd> bool Chipset::Bitplanes::advance() {
BIND_CYCLE(7, 0); BIND_CYCLE(7, 0);
} }
} else { } else {
switch(collection_offset_&7) { switch(cycle&7) {
default: return false; default: return false;
BIND_CYCLE(1, 3); BIND_CYCLE(1, 3);
BIND_CYCLE(2, 5); BIND_CYCLE(2, 5);
@ -811,7 +811,6 @@ template <bool is_odd> bool Chipset::Bitplanes::advance() {
void Chipset::Bitplanes::do_end_of_line() { void Chipset::Bitplanes::do_end_of_line() {
// TODO: apply modulos. // TODO: apply modulos.
collection_offset_ = 0;
} }
void Chipset::Bitplanes::set_control(uint16_t control) { void Chipset::Bitplanes::set_control(uint16_t control) {

View File

@ -171,13 +171,12 @@ class Chipset {
public: public:
using DMADevice::DMADevice; using DMADevice::DMADevice;
template <bool is_odd> bool advance(); bool advance(int cycle);
void do_end_of_line(); void do_end_of_line();
void set_control(uint16_t); void set_control(uint16_t);
private: private:
bool is_high_res_ = false; bool is_high_res_ = false;
int collection_offset_ = 0;
int plane_count_ = 0; int plane_count_ = 0;
BitplaneData next; BitplaneData next;