1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-02 20:30:00 +00:00

Introduce putative blitter sequencer.

This commit is contained in:
Thomas Harte 2022-07-26 17:05:05 -04:00
parent 804c12034c
commit 2c95dea4db
2 changed files with 101 additions and 0 deletions

View File

@ -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;

View File

@ -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;