mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-21 21:33:54 +00:00
Add an explicit flush-pipeline step; some tests now pass.
This commit is contained in:
parent
03d4960a03
commit
93d2a612ee
@ -344,7 +344,6 @@ bool Blitter::advance_dma() {
|
||||
x_ = 0;
|
||||
int loop_index_ = -1;
|
||||
write_phase_ = WritePhase::Starting;
|
||||
stopping_ = false;
|
||||
|
||||
while(true) {
|
||||
const auto next = sequencer_.next();
|
||||
@ -362,7 +361,6 @@ bool Blitter::advance_dma() {
|
||||
++y_;
|
||||
if(y_ == height_) {
|
||||
sequencer_.complete();
|
||||
stopping_ = true;
|
||||
}
|
||||
pointer_[0] += modulos_[0] * channel_enables_[0] * direction_;
|
||||
pointer_[1] += modulos_[1] * channel_enables_[1] * direction_;
|
||||
@ -389,10 +387,18 @@ bool Blitter::advance_dma() {
|
||||
case Channel::None:
|
||||
continue;
|
||||
case Channel::Write: break;
|
||||
case Channel::FlushPipeline:
|
||||
// HACK. REMOVE ONCE NON-BLOCKING.
|
||||
posit_interrupt(InterruptFlag::Blitter);
|
||||
height_ = 0;
|
||||
// END HACK.
|
||||
|
||||
if(write_phase_ == WritePhase::Full) {
|
||||
ram_[write_address_ & ram_mask_] = write_value_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a32_ = (a32_ << 16) | (a_data_ & transient_a_mask_);
|
||||
b32_ = (b32_ << 16) | b_data_;
|
||||
|
||||
@ -443,13 +449,14 @@ bool Blitter::advance_dma() {
|
||||
|
||||
switch(write_phase_) {
|
||||
case WritePhase::Full:
|
||||
ram_[write_address_ & ram_mask_] = output;
|
||||
ram_[write_address_ & ram_mask_] = write_value_;
|
||||
[[fallthrough]];
|
||||
|
||||
case WritePhase::Starting:
|
||||
write_phase_ = WritePhase::Full;
|
||||
write_address_ = pointer_[3];
|
||||
write_value_ = output;
|
||||
pointer_[3] += direction_;
|
||||
continue;
|
||||
|
||||
default: break;
|
||||
|
@ -27,16 +27,14 @@ class BlitterSequencer {
|
||||
public:
|
||||
enum class Channel {
|
||||
/// Tells the caller to calculate and load a new piece of output
|
||||
/// into the output pipeline,
|
||||
/// into the output pipeline.
|
||||
///
|
||||
/// If any inputs are enabled then a two-stage output pipeline applies:
|
||||
/// if anything is already in the pipeline then it should now be written.
|
||||
/// Then the new value should be placed into the pipeline ready for the
|
||||
/// next write slot.
|
||||
///
|
||||
/// If the pipeline is empty, this acts the same as @c None, indicating
|
||||
/// an unused DMA slot.
|
||||
/// If any inputs are enabled then a one-slot output pipeline applies:
|
||||
/// output will rest in the pipeline for one write phase before being written.
|
||||
Write,
|
||||
/// Indicates that a write should occur if anything is in the pipeline, otherwise
|
||||
/// no activity should occur.
|
||||
FlushPipeline,
|
||||
/// The caller should read from channel C.
|
||||
C,
|
||||
/// The caller should read from channel B.
|
||||
@ -77,7 +75,7 @@ class BlitterSequencer {
|
||||
default: break;
|
||||
|
||||
case Phase::Complete:
|
||||
return std::make_pair(Channel::Write, loop_);
|
||||
return std::make_pair(Channel::FlushPipeline, loop_);
|
||||
|
||||
case Phase::PauseAndComplete:
|
||||
phase_ = Phase::Complete;
|
||||
@ -211,11 +209,10 @@ class Blitter: public DMADevice<4, 4> {
|
||||
uint32_t write_address_ = 0xffff'ffff;
|
||||
uint16_t write_value_ = 0;
|
||||
enum WritePhase {
|
||||
Starting, Full, Stopped
|
||||
Starting, Full
|
||||
} write_phase_;
|
||||
int y_, x_;
|
||||
uint16_t transient_a_mask_;
|
||||
bool stopping_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -315,6 +315,7 @@ using WriteVector = std::vector<std::pair<uint32_t, uint16_t>>;
|
||||
case Channel::C: [components addObject:[NSString stringWithFormat:@"C%d", next.second]]; break;
|
||||
|
||||
case Channel::Write:
|
||||
case Channel::FlushPipeline:
|
||||
if(is_first_write) {
|
||||
is_first_write = false;
|
||||
[components addObject:@"-"];
|
||||
|
Loading…
Reference in New Issue
Block a user