1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-30 22:29:56 +00:00

Switch to regular integer types for flags.

This commit is contained in:
Thomas Harte 2022-07-26 09:22:05 -04:00
parent af7c56d313
commit ce7f57f251
5 changed files with 70 additions and 81 deletions

View File

@ -111,7 +111,7 @@ bool Audio::advance_dma(int channel) {
} }
void Audio::output() { void Audio::output() {
constexpr InterruptFlag interrupts[] = { constexpr InterruptFlag::FlagT interrupts[] = {
InterruptFlag::AudioChannel0, InterruptFlag::AudioChannel0,
InterruptFlag::AudioChannel1, InterruptFlag::AudioChannel1,
InterruptFlag::AudioChannel2, InterruptFlag::AudioChannel2,

View File

@ -21,35 +21,6 @@
using namespace Amiga; using namespace Amiga;
// TODO: I don't think the nonsense below, which was intended to allow a typed enum but also
// clean combination, really works. Rethink.
namespace {
template <typename EnumT, EnumT... T> struct Mask {
static constexpr uint16_t value = 0;
};
template <typename EnumT, EnumT F, EnumT... T> struct Mask<EnumT, F, T...> {
static constexpr uint16_t value = uint16_t(F) | Mask<EnumT, T...>::value;
};
template <InterruptFlag... Flags> struct InterruptMask: Mask<InterruptFlag, Flags...> {};
template <DMAFlag... Flags> struct DMAMask: Mask<DMAFlag, Flags...> {};
constexpr uint16_t AudioFlags[] = {
DMAMask<DMAFlag::AudioChannel0, DMAFlag::AllBelow>::value,
DMAMask<DMAFlag::AudioChannel1, DMAFlag::AllBelow>::value,
DMAMask<DMAFlag::AudioChannel2, DMAFlag::AllBelow>::value,
DMAMask<DMAFlag::AudioChannel3, DMAFlag::AllBelow>::value,
};
constexpr auto BlitterFlag = DMAMask<DMAFlag::Blitter, DMAFlag::AllBelow>::value;
constexpr auto BitplaneFlag = DMAMask<DMAFlag::Bitplane, DMAFlag::AllBelow>::value;
constexpr auto CopperFlag = DMAMask<DMAFlag::Copper, DMAFlag::AllBelow>::value;
constexpr auto DiskFlag = DMAMask<DMAFlag::Disk, DMAFlag::AllBelow>::value;
constexpr auto SpritesFlag = DMAMask<DMAFlag::Sprites, DMAFlag::AllBelow>::value;
}
#define DMA_CONSTRUCT *this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1 #define DMA_CONSTRUCT *this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1
Chipset::Chipset(MemoryMap &map, int input_clock_rate) : Chipset::Chipset(MemoryMap &map, int input_clock_rate) :
@ -94,17 +65,17 @@ void Chipset::set_cia_interrupts(bool cia_a_interrupt, bool cia_b_interrupt) {
// If latched, is it only on a leading edge? // If latched, is it only on a leading edge?
// interrupt_requests_ &= ~InterruptMask<InterruptFlag::IOPortsAndTimers, InterruptFlag::External>::value; // interrupt_requests_ &= ~InterruptMask<InterruptFlag::IOPortsAndTimers, InterruptFlag::External>::value;
interrupt_requests_ |= interrupt_requests_ |=
(cia_a_interrupt ? InterruptMask<InterruptFlag::IOPortsAndTimers>::value : 0) | (cia_a_interrupt ? InterruptFlag::IOPortsAndTimers : 0) |
(cia_b_interrupt ? InterruptMask<InterruptFlag::External>::value : 0); (cia_b_interrupt ? InterruptFlag::External : 0);
update_interrupts(); update_interrupts();
} }
void Chipset::posit_interrupt(InterruptFlag flag) { void Chipset::posit_interrupt(InterruptFlag::FlagT flag) {
interrupt_requests_ |= uint16_t(flag); interrupt_requests_ |= flag;
update_interrupts(); update_interrupts();
} }
void DMADeviceBase::posit_interrupt(InterruptFlag flag) { void DMADeviceBase::posit_interrupt(InterruptFlag::FlagT flag) {
chipset_.posit_interrupt(flag); chipset_.posit_interrupt(flag);
} }
@ -557,9 +528,10 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
} }
} }
constexpr auto BitplaneEnabled = DMAFlag::AllBelow | DMAFlag::Bitplane;
if( if(
horizontal_fetch_ != HorizontalFetch::Stopped && horizontal_fetch_ != HorizontalFetch::Stopped &&
(dma_control_ & BitplaneFlag) == BitplaneFlag && (dma_control_ & BitplaneEnabled) == BitplaneEnabled &&
fetch_vertical_ && fetch_vertical_ &&
bitplanes_.advance_dma(cycle - horizontal_offset_) bitplanes_.advance_dma(cycle - horizontal_offset_)
) { ) {
@ -622,7 +594,8 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
} }
if constexpr (cycle >= 0x08 && cycle < 0x0e) { if constexpr (cycle >= 0x08 && cycle < 0x0e) {
if((dma_control_ & DiskFlag) == DiskFlag) { constexpr auto DiskEnabled = DMAFlag::AllBelow | DMAFlag::Disk;
if((dma_control_ & DiskEnabled) == DiskEnabled) {
if(disk_.advance_dma()) { if(disk_.advance_dma()) {
return false; return false;
} }
@ -634,6 +607,13 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
static_assert(channel >= 0 && channel < 4); static_assert(channel >= 0 && channel < 4);
static_assert(cycle != 0x15 || channel == 3); static_assert(cycle != 0x15 || channel == 3);
constexpr DMAFlag::FlagT AudioFlags[] = {
DMAFlag::AllBelow | DMAFlag::AudioChannel0,
DMAFlag::AllBelow | DMAFlag::AudioChannel1,
DMAFlag::AllBelow | DMAFlag::AudioChannel2,
DMAFlag::AllBelow | DMAFlag::AudioChannel3,
};
if((dma_control_ & AudioFlags[channel]) == AudioFlags[channel]) { if((dma_control_ & AudioFlags[channel]) == AudioFlags[channel]) {
if(audio_.advance_dma(channel)) { if(audio_.advance_dma(channel)) {
return false; return false;
@ -642,7 +622,8 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
} }
if constexpr (cycle >= 0x16 && cycle < 0x36) { if constexpr (cycle >= 0x16 && cycle < 0x36) {
if(y_ >= vertical_blank_height_ && (dma_control_ & SpritesFlag) == SpritesFlag) { constexpr auto SpritesEnabled = DMAFlag::AllBelow | DMAFlag::Sprites;
if(y_ >= vertical_blank_height_ && (dma_control_ & SpritesEnabled) == SpritesEnabled) {
constexpr auto sprite_id = (cycle - 0x16) >> 2; constexpr auto sprite_id = (cycle - 0x16) >> 2;
static_assert(sprite_id >= 0 && sprite_id < std::tuple_size<decltype(sprites_)>::value); static_assert(sprite_id >= 0 && sprite_id < std::tuple_size<decltype(sprites_)>::value);
@ -656,7 +637,8 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
// is just possibly to pass to the Copper. // is just possibly to pass to the Copper.
// //
// The Blitter and CPU are dealt with outside of the odd/even test. // The Blitter and CPU are dealt with outside of the odd/even test.
if((dma_control_ & CopperFlag) == CopperFlag) { constexpr auto CopperEnabled = DMAFlag::AllBelow | DMAFlag::Copper;
if((dma_control_ & CopperEnabled) == CopperEnabled) {
if(copper_.advance_dma(uint16_t(((y_ & 0xff) << 8) | cycle), blitter_.get_status())) { if(copper_.advance_dma(uint16_t(((y_ & 0xff) << 8) | cycle), blitter_.get_status())) {
return false; return false;
} }
@ -667,7 +649,10 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
// Down here: give first refusal to the Blitter, otherwise // Down here: give first refusal to the Blitter, otherwise
// pass on to the CPU. // pass on to the CPU.
return (dma_control_ & BlitterFlag) != BlitterFlag || !blitter_.advance_dma(); //
// TODO: Blitter nasty flag. Who owns that?
constexpr auto BlitterEnabled = DMAFlag::AllBelow | DMAFlag::Blitter;
return (dma_control_ & BlitterEnabled) != BlitterEnabled || !blitter_.advance_dma();
} }
/// Performs all slots starting with @c first_slot and ending just before @c last_slot. /// Performs all slots starting with @c first_slot and ending just before @c last_slot.
@ -764,7 +749,7 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
if(y_ == short_field_height_ + is_long_field_) { if(y_ == short_field_height_ + is_long_field_) {
++vsyncs; ++vsyncs;
interrupt_requests_ |= InterruptMask<InterruptFlag::VerticalBlank>::value; interrupt_requests_ |= InterruptFlag::VerticalBlank;
update_interrupts(); update_interrupts();
y_ = 0; y_ = 0;
@ -832,17 +817,17 @@ void Chipset::update_interrupts() {
const uint16_t enabled_requests = interrupt_enable_ & interrupt_requests_ & 0x3fff; const uint16_t enabled_requests = interrupt_enable_ & interrupt_requests_ & 0x3fff;
if(enabled_requests && (interrupt_enable_ & 0x4000)) { if(enabled_requests && (interrupt_enable_ & 0x4000)) {
if(enabled_requests & InterruptMask<InterruptFlag::External>::value) { if(enabled_requests & InterruptFlag::External) {
interrupt_level_ = 6; interrupt_level_ = 6;
} else if(enabled_requests & InterruptMask<InterruptFlag::SerialPortReceive, InterruptFlag::DiskSyncMatch>::value) { } else if(enabled_requests & (InterruptFlag::SerialPortReceive | InterruptFlag::DiskSyncMatch)) {
interrupt_level_ = 5; interrupt_level_ = 5;
} else if(enabled_requests & InterruptMask<InterruptFlag::AudioChannel0, InterruptFlag::AudioChannel1, InterruptFlag::AudioChannel2, InterruptFlag::AudioChannel3>::value) { } else if(enabled_requests & (InterruptFlag::AudioChannel0 | InterruptFlag::AudioChannel1 | InterruptFlag::AudioChannel2 | InterruptFlag::AudioChannel3)) {
interrupt_level_ = 4; interrupt_level_ = 4;
} else if(enabled_requests & InterruptMask<InterruptFlag::Copper, InterruptFlag::VerticalBlank, InterruptFlag::Blitter>::value) { } else if(enabled_requests & (InterruptFlag::Copper | InterruptFlag::VerticalBlank | InterruptFlag::Blitter)) {
interrupt_level_ = 3; interrupt_level_ = 3;
} else if(enabled_requests & InterruptMask<InterruptFlag::IOPortsAndTimers>::value) { } else if(enabled_requests & InterruptFlag::IOPortsAndTimers) {
interrupt_level_ = 2; interrupt_level_ = 2;
} else if(enabled_requests & InterruptMask<InterruptFlag::SerialPortTransmit, InterruptFlag::DiskBlock, InterruptFlag::Software>::value) { } else if(enabled_requests & (InterruptFlag::SerialPortTransmit | InterruptFlag::DiskBlock | InterruptFlag::Software)) {
interrupt_level_ = 1; interrupt_level_ = 1;
} }
} }

View File

@ -125,7 +125,7 @@ class Chipset: private ClockingHint::Observer {
int interrupt_level_ = 0; int interrupt_level_ = 0;
void update_interrupts(); void update_interrupts();
void posit_interrupt(InterruptFlag); void posit_interrupt(InterruptFlag::FlagT);
// MARK: - Scheduler. // MARK: - Scheduler.

View File

@ -24,7 +24,7 @@ class DMADeviceBase {
DMADeviceBase(Chipset &chipset, uint16_t *ram, size_t word_size) : DMADeviceBase(Chipset &chipset, uint16_t *ram, size_t word_size) :
chipset_(chipset), ram_(ram), ram_mask_(uint32_t(word_size - 1)) {} chipset_(chipset), ram_(ram), ram_mask_(uint32_t(word_size - 1)) {}
void posit_interrupt(Amiga::InterruptFlag); void posit_interrupt(Amiga::InterruptFlag::FlagT);
protected: protected:
Chipset &chipset_; Chipset &chipset_;

View File

@ -11,39 +11,43 @@
namespace Amiga { namespace Amiga {
enum class InterruptFlag: uint16_t { namespace InterruptFlag {
SerialPortTransmit = 1 << 0, using FlagT = uint16_t;
DiskBlock = 1 << 1,
Software = 1 << 2,
IOPortsAndTimers = 1 << 3, // i.e. CIA A.
Copper = 1 << 4,
VerticalBlank = 1 << 5,
Blitter = 1 << 6,
AudioChannel0 = 1 << 7,
AudioChannel1 = 1 << 8,
AudioChannel2 = 1 << 9,
AudioChannel3 = 1 << 10,
SerialPortReceive = 1 << 11,
DiskSyncMatch = 1 << 12,
External = 1 << 13, // i.e. CIA B.
};
enum class DMAFlag: uint16_t { constexpr FlagT SerialPortTransmit = 1 << 0;
AudioChannel0 = 1 << 0, constexpr FlagT DiskBlock = 1 << 1;
AudioChannel1 = 1 << 1, constexpr FlagT Software = 1 << 2;
AudioChannel2 = 1 << 2, constexpr FlagT IOPortsAndTimers = 1 << 3; // i.e. CIA A.
AudioChannel3 = 1 << 3, constexpr FlagT Copper = 1 << 4;
Disk = 1 << 4, constexpr FlagT VerticalBlank = 1 << 5;
Sprites = 1 << 5, constexpr FlagT Blitter = 1 << 6;
Blitter = 1 << 6, constexpr FlagT AudioChannel0 = 1 << 7;
Copper = 1 << 7, constexpr FlagT AudioChannel1 = 1 << 8;
Bitplane = 1 << 8, constexpr FlagT AudioChannel2 = 1 << 9;
AllBelow = 1 << 9, constexpr FlagT AudioChannel3 = 1 << 10;
BlitterPriority = 1 << 10, constexpr FlagT SerialPortReceive = 1 << 11;
BlitterZero = 1 << 13, constexpr FlagT DiskSyncMatch = 1 << 12;
BlitterBusy = 1 << 14, constexpr FlagT External = 1 << 13; // i.e. CIA B.
}; }
}; namespace DMAFlag {
using FlagT = uint16_t;
constexpr FlagT AudioChannel0 = 1 << 0;
constexpr FlagT AudioChannel1 = 1 << 1;
constexpr FlagT AudioChannel2 = 1 << 2;
constexpr FlagT AudioChannel3 = 1 << 3;
constexpr FlagT Disk = 1 << 4;
constexpr FlagT Sprites = 1 << 5;
constexpr FlagT Blitter = 1 << 6;
constexpr FlagT Copper = 1 << 7;
constexpr FlagT Bitplane = 1 << 8;
constexpr FlagT AllBelow = 1 << 9;
constexpr FlagT BlitterPriority = 1 << 10;
constexpr FlagT BlitterZero = 1 << 13;
constexpr FlagT BlitterBusy = 1 << 14;
}
}
#endif /* Flags_hpp */ #endif /* Flags_hpp */