mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Breaks up loop for arithmetic simplicity.
This commit is contained in:
parent
402eab10f8
commit
82205d71cc
@ -127,6 +127,8 @@ bool Chipset::Copper::advance(uint16_t position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int cycle> void Chipset::output() {
|
template <int cycle> void Chipset::output() {
|
||||||
|
// Notes to self on guesses below:
|
||||||
|
//
|
||||||
// Hardware stop is at 0x18;
|
// Hardware stop is at 0x18;
|
||||||
// 12/64 * 227 = 42.5625
|
// 12/64 * 227 = 42.5625
|
||||||
//
|
//
|
||||||
@ -242,6 +244,41 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool stop_on_cpu> int Chipset::advance_slots(int first_slot, int last_slot) {
|
||||||
|
if(first_slot == last_slot) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define C(x) \
|
||||||
|
case x: \
|
||||||
|
if constexpr(stop_on_cpu) {\
|
||||||
|
if(perform_cycle<x, stop_on_cpu>()) {\
|
||||||
|
return x - first_slot;\
|
||||||
|
}\
|
||||||
|
} else {\
|
||||||
|
perform_cycle<x, stop_on_cpu>(); \
|
||||||
|
} \
|
||||||
|
output<x>(); \
|
||||||
|
if((x + 1) == last_slot) break; \
|
||||||
|
[[fallthrough]]
|
||||||
|
|
||||||
|
#define C10(x) C(x); C(x+1); C(x+2); C(x+3); C(x+4); C(x+5); C(x+6); C(x+7); C(x+8); C(x+9);
|
||||||
|
switch(first_slot) {
|
||||||
|
C10(0); C10(10); C10(20); C10(30); C10(40);
|
||||||
|
C10(50); C10(60); C10(70); C10(80); C10(90);
|
||||||
|
C10(100); C10(110); C10(120); C10(130); C10(140);
|
||||||
|
C10(150); C10(160); C10(170); C10(180); C10(190);
|
||||||
|
C10(200); C10(210);
|
||||||
|
C(220); C(221); C(222); C(223); C(224);
|
||||||
|
C(225); C(226); C(227); C(228);
|
||||||
|
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
#undef C
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
||||||
Changes changes;
|
Changes changes;
|
||||||
|
|
||||||
@ -252,54 +289,19 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
|||||||
// Update raster position, spooling out graphics.
|
// Update raster position, spooling out graphics.
|
||||||
while(pixels_remaining) {
|
while(pixels_remaining) {
|
||||||
// Determine number of pixels left on this line.
|
// Determine number of pixels left on this line.
|
||||||
int line_pixels = std::min(pixels_remaining, (line_length_ * 4) - line_cycle_);
|
const int line_pixels = std::min(pixels_remaining, (line_length_ * 4) - line_cycle_);
|
||||||
|
|
||||||
//
|
const int start_slot = line_cycle_ >> 2;
|
||||||
// Run DMA scheduler.
|
const int end_slot = (line_cycle_ + line_pixels) >> 2;
|
||||||
//
|
const int actual_slots = advance_slots<stop_on_cpu>(start_slot, end_slot);
|
||||||
|
|
||||||
int final_slot = (line_cycle_ + line_pixels) >> 2;
|
if(actual_slots >= 0) {
|
||||||
|
// TODO: abbreviate run, prior to adding to totals below.
|
||||||
if((line_cycle_ >> 2) == final_slot) {
|
assert(false);
|
||||||
// Not enough pixels left to fill any whole slots, just stop.
|
|
||||||
line_cycle_ += line_pixels;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to window boundary.
|
line_cycle_ += line_pixels;
|
||||||
const int distance_to_boundary = ((line_cycle_ - 1) & 3) ^ 3;
|
pixels_remaining -= line_pixels;
|
||||||
line_pixels -= distance_to_boundary;
|
|
||||||
pixels_remaining -= distance_to_boundary;
|
|
||||||
line_cycle_ += distance_to_boundary;
|
|
||||||
|
|
||||||
#define C(x) \
|
|
||||||
case x: \
|
|
||||||
assert(!(line_cycle_&3)); \
|
|
||||||
if constexpr(stop_on_cpu) {\
|
|
||||||
if(perform_cycle<x, stop_on_cpu>()) {\
|
|
||||||
break;\
|
|
||||||
}\
|
|
||||||
} else {\
|
|
||||||
perform_cycle<x, stop_on_cpu>(); \
|
|
||||||
} \
|
|
||||||
output<x>(); \
|
|
||||||
if((line_cycle_ >> 2) == final_slot) break; \
|
|
||||||
line_cycle_ += 4; \
|
|
||||||
pixels_remaining -= 4;
|
|
||||||
|
|
||||||
#define C10(x) C(x); C(x+1); C(x+2); C(x+3); C(x+4); C(x+5); C(x+6); C(x+7); C(x+8); C(x+9);
|
|
||||||
switch(line_cycle_ >> 2) {
|
|
||||||
C10(0); C10(10); C10(20); C10(30); C10(40);
|
|
||||||
C10(50); C10(60); C10(70); C10(80); C10(90);
|
|
||||||
C10(100); C10(110); C10(120); C10(130); C10(140);
|
|
||||||
C10(150); C10(160); C10(170); C10(180); C10(190);
|
|
||||||
C10(200); C10(210);
|
|
||||||
C(220); C(221); C(222); C(223); C(224);
|
|
||||||
C(225); C(226); C(227); C(228);
|
|
||||||
|
|
||||||
default: assert(false);
|
|
||||||
}
|
|
||||||
#undef C
|
|
||||||
|
|
||||||
// Advance intraline counter and possibly ripple upwards into
|
// Advance intraline counter and possibly ripple upwards into
|
||||||
// lines and fields.
|
// lines and fields.
|
||||||
@ -320,6 +322,7 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
|||||||
copper_.reload(0);
|
copper_.reload(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(line_cycle_ < line_length_ * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
changes.interrupt_level = interrupt_level_;
|
changes.interrupt_level = interrupt_level_;
|
||||||
|
@ -66,6 +66,7 @@ class Chipset {
|
|||||||
// MARK: - Scheduler.
|
// MARK: - Scheduler.
|
||||||
|
|
||||||
template <bool stop_on_cpu> Changes run(HalfCycles duration = HalfCycles());
|
template <bool stop_on_cpu> Changes run(HalfCycles duration = HalfCycles());
|
||||||
|
template <bool stop_on_cpu> int advance_slots(int, int);
|
||||||
template <int cycle, bool stop_if_cpu> bool perform_cycle();
|
template <int cycle, bool stop_if_cpu> bool perform_cycle();
|
||||||
template <int cycle> void output();
|
template <int cycle> void output();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user