1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Implement bitplane modulos.

This commit is contained in:
Thomas Harte 2021-10-29 11:29:22 -07:00
parent f3e895f17c
commit edb75e69cb
6 changed files with 33 additions and 24 deletions

View File

@ -76,13 +76,6 @@ void Blitter::set_horizontal_size([[maybe_unused]] uint16_t value) {
LOG("Set horizontal size " << PADHEX(4) << value);
}
void Blitter::set_modulo(int channel, uint16_t value) {
LOG("Set modulo size " << channel << " to " << PADHEX(4) << value);
// Convert by sign extension.
modulos_[channel] = uint32_t(int16_t(value) >> 1);
}
void Blitter::set_data(int channel, uint16_t value) {
LOG("Set data " << channel << " to " << PADHEX(4) << value);

View File

@ -17,7 +17,7 @@
namespace Amiga {
class Blitter: public DMADevice<4> {
class Blitter: public DMADevice<4, 4> {
public:
using DMADevice::DMADevice;
@ -33,7 +33,6 @@ class Blitter: public DMADevice<4> {
void set_minterms(uint16_t value);
void set_vertical_size(uint16_t value);
void set_horizontal_size(uint16_t value);
void set_modulo(int channel, uint16_t value);
void set_data(int channel, uint16_t value);
uint16_t get_status();
@ -60,7 +59,6 @@ class Blitter: public DMADevice<4> {
uint8_t minterms_ = 0;
uint32_t a32_ = 0, b32_ = 0;
uint16_t a_data_ = 0, b_data_ = 0, c_data_ = 0;
uint32_t modulos_[4]{};
bool not_zero_flag_ = false;
};

View File

@ -96,6 +96,7 @@ Chipset::Changes Chipset::run_until_cpu_slot() {
void Chipset::set_cia_interrupts(bool cia_a_interrupt, bool cia_b_interrupt) {
// TODO: are these really latched, or are they active live?
// If latched, is it only on a leading edge?
// interrupt_requests_ &= ~InterruptMask<InterruptFlag::IOPortsAndTimers, InterruptFlag::External>::value;
interrupt_requests_ |=
(cia_a_interrupt ? InterruptMask<InterruptFlag::IOPortsAndTimers>::value : 0) |
@ -462,8 +463,6 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
// }
if(did_fetch_) {
// TODO: find out when modulos are actually applied, since
// they're dynamically programmable.
bitplanes_.do_end_of_line();
previous_bitplanes_.clear();
}
@ -762,8 +761,10 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
break;
case Write(0x108):
bitplanes_.set_modulo<0>(cycle.value16());
break;
case Write(0x10a):
LOG("TODO: Bitplane modulo; " << PADHEX(4) << cycle.value16() << " to " << *cycle.address);
bitplanes_.set_modulo<1>(cycle.value16());
break;
case Write(0x110):
@ -804,10 +805,10 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
case Write(0x05c): blitter_.set_vertical_size(cycle.value16()); break;
case Write(0x05e): blitter_.set_horizontal_size(cycle.value16()); break;
case Write(0x060): blitter_.set_modulo(2, cycle.value16()); break;
case Write(0x062): blitter_.set_modulo(1, cycle.value16()); break;
case Write(0x064): blitter_.set_modulo(0, cycle.value16()); break;
case Write(0x066): blitter_.set_modulo(3, cycle.value16()); break;
case Write(0x060): blitter_.set_modulo<2>(cycle.value16()); break;
case Write(0x062): blitter_.set_modulo<1>(cycle.value16()); break;
case Write(0x064): blitter_.set_modulo<0>(cycle.value16()); break;
case Write(0x066): blitter_.set_modulo<3>(cycle.value16()); break;
case Write(0x070): blitter_.set_data(2, cycle.value16()); break;
case Write(0x072): blitter_.set_data(1, cycle.value16()); break;
@ -955,7 +956,14 @@ bool Chipset::Bitplanes::advance(int cycle) {
}
void Chipset::Bitplanes::do_end_of_line() {
// TODO: apply modulos.
// Apply modulos here. Posssibly correct?
pointer_[0] += modulos_[1];
pointer_[2] += modulos_[1];
pointer_[4] += modulos_[1];
pointer_[1] += modulos_[0];
pointer_[3] += modulos_[0];
pointer_[5] += modulos_[0];
}
void Chipset::Bitplanes::set_control(uint16_t control) {

View File

@ -228,7 +228,7 @@ class Chipset: private ClockingHint::Observer {
}
};
class Bitplanes: public DMADevice<6> {
class Bitplanes: public DMADevice<6, 2> {
public:
using DMADevice::DMADevice;

View File

@ -32,7 +32,7 @@ class DMADeviceBase {
const uint32_t ram_mask_ = 0;
};
template <size_t num_addresses> class DMADevice: public DMADeviceBase {
template <size_t num_addresses, size_t num_modulos = 0> class DMADevice: public DMADeviceBase {
public:
using DMADeviceBase::DMADeviceBase;
@ -40,10 +40,19 @@ template <size_t num_addresses> class DMADevice: public DMADeviceBase {
template <int id, int shift> void set_pointer(uint16_t value) {
static_assert(id < num_addresses);
static_assert(shift == 0 || shift == 16);
byte_pointer_[id] = (byte_pointer_[id] & (0xffff'0000 >> shift)) | uint32_t(value << shift);
pointer_[id] = byte_pointer_[id] >> 1;
}
/// Writes the word @c value to the modulo register @c id, shifting it by @c shift (0 or 16) first.
template <int id> void set_modulo(uint16_t value) {
static_assert(id < num_modulos);
// Convert by sign extension.
modulos_[id] = uint32_t(int16_t(value) >> 1);
}
template <int id, int shift> uint16_t get_pointer() {
// Restore the original least-significant bit.
const uint32_t source = (pointer_[id] << 1) | (byte_pointer_[id] & 1);
@ -54,6 +63,7 @@ template <size_t num_addresses> class DMADevice: public DMADeviceBase {
// These are shifted right one to provide word-indexing pointers;
// subclasses should use e.g. ram_[pointer_[0] & ram_mask_] directly.
std::array<uint32_t, num_addresses> pointer_{};
std::array<uint32_t, num_modulos> modulos_{};
private:
std::array<uint32_t, num_addresses> byte_pointer_{};

View File

@ -142,19 +142,19 @@ using WriteVector = std::vector<std::pair<uint32_t, uint16_t>>;
}
if([type isEqualToString:@"bltamod"]) {
blitter.set_modulo(0, param1);
blitter.set_modulo<0>(param1);
continue;
}
if([type isEqualToString:@"bltbmod"]) {
blitter.set_modulo(1, param1);
blitter.set_modulo<1>(param1);
continue;
}
if([type isEqualToString:@"bltcmod"]) {
blitter.set_modulo(2, param1);
blitter.set_modulo<2>(param1);
continue;
}
if([type isEqualToString:@"bltdmod"]) {
blitter.set_modulo(3, param1);
blitter.set_modulo<3>(param1);
continue;
}