mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-21 21:33:54 +00:00
Introduce putative blitter sequencer.
This commit is contained in:
parent
804c12034c
commit
2c95dea4db
@ -191,6 +191,34 @@ uint16_t Blitter::get_status() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Due to the pipeline, writes are delayed by one slot — the first write will occur
|
||||
// after the second set of inputs has been fetched, and every sequence with writes enabled
|
||||
// will end with an additional write.
|
||||
//
|
||||
// USE Code
|
||||
// in Active
|
||||
// BLTCON0 Channels Cycle Sequence
|
||||
// --------- -------- --------------
|
||||
// F A B C D A0 B0 C0 - A1 B1 C1 D0 A2 B2 C2 D1 D2
|
||||
// E A B C A0 B0 C0 A1 B1 C1 A2 B2 C2
|
||||
// D A B D A0 B0 - A1 B1 D0 A2 B2 D1 - D2
|
||||
// C A B A0 B0 - A1 B1 - A2 B2
|
||||
// B A C D A0 C0 - A1 C1 D0 A2 C2 D1 - D2
|
||||
// A A C A0 C0 A1 C1 A2 C2
|
||||
// 9 A D A0 - A1 D0 A2 D1 - D2
|
||||
// 8 A A0 - A1 - A2
|
||||
// 7 B C D B0 C0 - - B1 C1 D0 - B2 C2 D1 - D2
|
||||
// 6 B C B0 C0 - B1 C1 - B2 C2
|
||||
// 5 B D B0 - - B1 D0 - B2 D1 - D2
|
||||
// 4 B B0 - - B1 - - B2
|
||||
// 3 C D C0 - - C1 D0 - C2 D1 - D2
|
||||
// 2 C C0 - C1 - C2
|
||||
// 1 D D0 - D1 - D2
|
||||
// 0 none - - - -
|
||||
//
|
||||
//
|
||||
// Table 6-2: Typical Blitter Cycle Sequence
|
||||
|
||||
bool Blitter::advance_dma() {
|
||||
if(!height_) return false;
|
||||
|
||||
|
@ -17,6 +17,79 @@
|
||||
|
||||
namespace Amiga {
|
||||
|
||||
class BlitterSequencer {
|
||||
public:
|
||||
enum class Channel {
|
||||
Write, C, B, A, None
|
||||
};
|
||||
|
||||
void set_control(int control) {
|
||||
control_ = control;
|
||||
}
|
||||
|
||||
void complete() {
|
||||
complete_ = true;
|
||||
}
|
||||
|
||||
Channel next() {
|
||||
if(complete_ && !index_) {
|
||||
// TODO: this isn't quite right; some patterns leave a gap before
|
||||
// the final write, some don't. Figure this out.
|
||||
return Channel::Write;
|
||||
}
|
||||
|
||||
Channel next = Channel::None;
|
||||
|
||||
switch(control_) {
|
||||
default: break;
|
||||
|
||||
case 1: next = next_channel(pattern1); break;
|
||||
case 2: next = next_channel(pattern2); break;
|
||||
case 3: next = next_channel(pattern3); break;
|
||||
case 4: next = next_channel(pattern4); break;
|
||||
case 5: next = next_channel(pattern5); break;
|
||||
case 6: next = next_channel(pattern6); break;
|
||||
case 7: next = next_channel(pattern7); break;
|
||||
case 8: next = next_channel(pattern8); break;
|
||||
case 9: next = next_channel(pattern9); break;
|
||||
case 10: next = next_channel(patternA); break;
|
||||
case 11: next = next_channel(patternB); break;
|
||||
case 12: next = next_channel(patternC); break;
|
||||
case 13: next = next_channel(patternD); break;
|
||||
case 14: next = next_channel(patternE); break;
|
||||
case 15: next = next_channel(patternF); break;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr std::array<Channel, 2> pattern1 = { Channel::Write, Channel::None };
|
||||
static constexpr std::array<Channel, 2> pattern2 = { Channel::C, Channel::None };
|
||||
static constexpr std::array<Channel, 3> pattern3 = { Channel::C, Channel::Write, Channel::None };
|
||||
static constexpr std::array<Channel, 3> pattern4 = { Channel::B, Channel::None, Channel::None };
|
||||
static constexpr std::array<Channel, 3> pattern5 = { Channel::B, Channel::Write, Channel::None };
|
||||
static constexpr std::array<Channel, 3> pattern6 = { Channel::B, Channel::C, Channel::None };
|
||||
static constexpr std::array<Channel, 4> pattern7 = { Channel::B, Channel::C, Channel::Write, Channel::None };
|
||||
static constexpr std::array<Channel, 2> pattern8 = { Channel::A, Channel::None };
|
||||
static constexpr std::array<Channel, 2> pattern9 = { Channel::A, Channel::Write };
|
||||
static constexpr std::array<Channel, 2> patternA = { Channel::A, Channel::C };
|
||||
static constexpr std::array<Channel, 3> patternB = { Channel::A, Channel::C, Channel::Write };
|
||||
static constexpr std::array<Channel, 3> patternC = { Channel::A, Channel::B, Channel::None };
|
||||
static constexpr std::array<Channel, 3> patternD = { Channel::A, Channel::B, Channel::Write };
|
||||
static constexpr std::array<Channel, 3> patternE = { Channel::A, Channel::B, Channel::C };
|
||||
static constexpr std::array<Channel, 4> patternF = { Channel::A, Channel::B, Channel::C, Channel::Write };
|
||||
template <typename ArrayT> Channel next_channel(const ArrayT &list) {
|
||||
const Channel result = list[index_];
|
||||
index_ = (index_ + 1) % list.size();
|
||||
return result;
|
||||
}
|
||||
|
||||
int control_ = 0;
|
||||
int index_ = 0;
|
||||
bool complete_ = false;
|
||||
};
|
||||
|
||||
class Blitter: public DMADevice<4, 4> {
|
||||
public:
|
||||
using DMADevice::DMADevice;
|
||||
|
Loading…
Reference in New Issue
Block a user