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:
parent
f3e895f17c
commit
edb75e69cb
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -228,7 +228,7 @@ class Chipset: private ClockingHint::Observer {
|
||||
}
|
||||
};
|
||||
|
||||
class Bitplanes: public DMADevice<6> {
|
||||
class Bitplanes: public DMADevice<6, 2> {
|
||||
public:
|
||||
using DMADevice::DMADevice;
|
||||
|
||||
|
@ -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_{};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user