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:
parent
af7c56d313
commit
ce7f57f251
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user