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

Attempts more properly to implement line mode.

This commit is contained in:
Thomas Harte 2021-09-28 21:39:09 -04:00
parent cb460de94d
commit ffcd2ea10c
2 changed files with 50 additions and 29 deletions

View File

@ -139,41 +139,64 @@ bool Blitter::advance() {
// * bit 3 = 1 => major variable negative; otherwise positive;
// * bit 2 = 1 => minor variable negative; otherwise positive.
//
// Implementation below is heavily based on the documentation found
// at https://github.com/niklasekstrom/blitter-subpixel-line/blob/master/Drawing%20lines%20using%20the%20Amiga%20blitter.pdf
printf("!!! Line %08x\n", pointer_[3]);
int error = int(pointer_[0]) * line_sign_;
bool draw_ = true;
while(height_--) {
// plot(x, y)
c_ = ram_[pointer_[3] & ram_mask_];
ram_[pointer_[3] & ram_mask_] =
apply_minterm<uint16_t>(
a_ >> shifts_[0],
0xffff, // TODO: b_ & (0x8000 >> shifts_[1]) but not that.
c_, minterms_);
shifts_[1] = (shifts_[1] + 1) & 15;
if(draw_) {
c_ = ram_[pointer_[3] & ram_mask_];
// c_ |= a_ >> shifts_[0]; // TODO: there's an XOR mode, I think?
ram_[pointer_[3] & ram_mask_] =
apply_minterm<uint16_t>(a_ >> shifts_[0], b_, c_, minterms_);
draw_ &= !one_dot_;
}
// Assumed for now: direction 0.
pointer_[3] += modulos_[2];
if(error > 0) {
constexpr int LEFT = 1 << 0;
constexpr int RIGHT = 1 << 1;
constexpr int UP = 1 << 2;
constexpr int DOWN = 1 << 3;
int step = (line_direction_ & 4) ?
((line_direction_ & 1) ? LEFT : RIGHT) :
((line_direction_ & 1) ? UP : DOWN);
if(error < 0) {
error += modulos_[1];
} else {
step |=
(line_direction_ & 4) ?
((line_direction_ & 2) ? UP : DOWN) :
((line_direction_ & 2) ? LEFT : RIGHT);
error += modulos_[0];
}
if(step & LEFT) {
--shifts_[0];
if(shifts_[0] == -1) {
--pointer_[3];
}
} else if(step & RIGHT) {
++shifts_[0];
if(shifts_[0] == 16) {
shifts_[0] = 0;
++pointer_[3];
}
error -= modulos_[0] - modulos_[1];
}
error += modulos_[1];
shifts_[0] &= 15;
// plot(x, y)
// if error > 0 {
// ++y
// error -= 2*dx
// }
// d += 2*dy
if(step & UP) {
pointer_[3] -= modulos_[2];
draw_ = true;
} else if(step & DOWN) {
pointer_[3] += modulos_[2];
draw_ = true;
}
}
// ram_[pointer_[3] & ram_mask_] = 0xffff;
} else {
// Copy mode.
printf("!!! Copy %08x\n", pointer_[3]);

View File

@ -241,11 +241,11 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
//
// TODO: figure out how the hard stops factor into this.
//
// TODO: eliminate hard-coded 300 below. There's clearly something
// TODO: eliminate hard-coded 320 below. There's clearly something
// (well, probably many things) I don't yet understand about the
// fetch window.
fetch_horizontal_ |= (cycle << 1) == fetch_window_[0];
fetch_horizontal_ &= (cycle << 1) != (fetch_window_[0] + 300);
fetch_horizontal_ &= (cycle << 1) != (fetch_window_[0] + 320);
// fetch_horizontal_ &= (cycle << 1) != fetch_window_[1];
//fetch_window_[1];
@ -253,7 +253,7 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
if((dma_control_ & BitplaneFlag) == BitplaneFlag) {
// TODO: offer a cycle for bitplane collection.
// Probably need to indicate odd or even?
if(fetch_horizontal_ && fetch_vertical_ && bitplanes_.advance(cycle)) { // TODO: cycle should be relative to start of collection.
if(fetch_horizontal_ && fetch_vertical_ && bitplanes_.advance(cycle - (fetch_window_[0] >> 1))) { // TODO: cycle should be relative to start of collection.
did_fetch_ = true;
return false;
}
@ -774,10 +774,6 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
// MARK: - Bitplanes.
bool Chipset::Bitplanes::advance(int cycle) {
// TODO: possibly dispatch a BitplaneData.
// The chipset has responsibility for applying a delay,
// and the pixel-level start/stop boundaries.
#define BIND_CYCLE(offset, plane) \
case offset: \
if(plane_count_ > plane) { \
@ -822,6 +818,8 @@ bool Chipset::Bitplanes::advance(int cycle) {
}
return false;
#undef BIND_CYCLE
}
void Chipset::Bitplanes::do_end_of_line() {