mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-19 23:32:28 +00:00
Adds nonsense disk reads, which seems to lead to bitplane and blitter requests.
Progress, at last!
This commit is contained in:
parent
9215535bee
commit
dda154c7c6
@ -18,23 +18,17 @@ using namespace Amiga;
|
||||
|
||||
namespace {
|
||||
|
||||
enum InterruptFlag: uint16_t {
|
||||
SerialPortTransmit = 1 << 0,
|
||||
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.
|
||||
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...> {};
|
||||
|
||||
}
|
||||
|
||||
Chipset::Chipset(uint16_t *ram, size_t size) :
|
||||
@ -54,10 +48,15 @@ Chipset::Changes Chipset::run_until_cpu_slot() {
|
||||
|
||||
void Chipset::set_cia_interrupts(bool cia_a, bool cia_b) {
|
||||
// TODO: are these really latched, or are they active live?
|
||||
interrupt_requests_ &= ~(InterruptFlag::IOPortsAndTimers | InterruptFlag::External);
|
||||
interrupt_requests_ &= ~InterruptMask<InterruptFlag::IOPortsAndTimers, InterruptFlag::External>::value;
|
||||
interrupt_requests_ |=
|
||||
(cia_a ? InterruptFlag::IOPortsAndTimers : 0) |
|
||||
(cia_b ? InterruptFlag::External : 0);
|
||||
(cia_a ? InterruptMask<InterruptFlag::IOPortsAndTimers>::value : 0) |
|
||||
(cia_b ? InterruptMask<InterruptFlag::External>::value : 0);
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
void Chipset::posit_interrupt(InterruptFlag flag) {
|
||||
interrupt_requests_ |= uint16_t(flag);
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
@ -220,6 +219,9 @@ template <int cycle> void Chipset::output() {
|
||||
}
|
||||
|
||||
template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
||||
constexpr auto CopperFlag = DMAMask<DMAFlag::Copper, DMAFlag::AllBelow>::value;
|
||||
constexpr auto DiskFlag = DMAMask<DMAFlag::Disk, DMAFlag::AllBelow>::value;
|
||||
|
||||
if constexpr (cycle & 1) {
|
||||
// Odd slot priority is:
|
||||
//
|
||||
@ -227,7 +229,7 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
||||
// 2. Bitplane.
|
||||
// 3. Blitter.
|
||||
// 4. CPU.
|
||||
if((dma_control_ & 0x280) == 0x280) {
|
||||
if((dma_control_ & CopperFlag) == CopperFlag) {
|
||||
if(copper_.advance(uint16_t(((y_ & 0xff) << 8) | (cycle & 0xfe)))) {
|
||||
return false;
|
||||
}
|
||||
@ -242,6 +244,11 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
||||
// 2. Disk, then audio, then sprites depending on region.
|
||||
// 3. Blitter.
|
||||
// 4. CPU.
|
||||
if constexpr (cycle >= 4 && cycle <= 6) {
|
||||
if((dma_control_ & DiskFlag) == DiskFlag) {
|
||||
disk_.advance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -325,7 +332,7 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
||||
|
||||
if(y_ == frame_height_) {
|
||||
++changes.vsyncs;
|
||||
interrupt_requests_ |= InterruptFlag::VerticalBlank;
|
||||
interrupt_requests_ |= InterruptMask<InterruptFlag::VerticalBlank>::value;
|
||||
update_interrupts();
|
||||
|
||||
y_ = 0;
|
||||
@ -346,17 +353,17 @@ void Chipset::update_interrupts() {
|
||||
|
||||
const uint16_t enabled_requests = interrupt_enable_ & interrupt_requests_ & 0x3fff;
|
||||
if(enabled_requests && (interrupt_enable_ & 0x4000)) {
|
||||
if(enabled_requests & (InterruptFlag::External)) {
|
||||
if(enabled_requests & InterruptMask<InterruptFlag::External>::value) {
|
||||
interrupt_level_ = 6;
|
||||
} else if(enabled_requests & (InterruptFlag::SerialPortReceive | InterruptFlag::DiskSyncMatch)) {
|
||||
} else if(enabled_requests & InterruptMask<InterruptFlag::SerialPortReceive, InterruptFlag::DiskSyncMatch>::value) {
|
||||
interrupt_level_ = 5;
|
||||
} else if(enabled_requests & (InterruptFlag::AudioChannel0 | InterruptFlag::AudioChannel1 | InterruptFlag::AudioChannel2 | InterruptFlag::AudioChannel3)) {
|
||||
} else if(enabled_requests & InterruptMask<InterruptFlag::AudioChannel0, InterruptFlag::AudioChannel1, InterruptFlag::AudioChannel2, InterruptFlag::AudioChannel3>::value) {
|
||||
interrupt_level_ = 4;
|
||||
} else if(enabled_requests & (InterruptFlag::Copper | InterruptFlag::VerticalBlank | InterruptFlag::Blitter)) {
|
||||
} else if(enabled_requests & InterruptMask<InterruptFlag::Copper, InterruptFlag::VerticalBlank, InterruptFlag::Blitter>::value) {
|
||||
interrupt_level_ = 3;
|
||||
} else if(enabled_requests & (InterruptFlag::IOPortsAndTimers)) {
|
||||
} else if(enabled_requests & InterruptMask<InterruptFlag::IOPortsAndTimers>::value) {
|
||||
interrupt_level_ = 2;
|
||||
} else if(enabled_requests & (InterruptFlag::SerialPortTransmit | InterruptFlag::DiskBlock | InterruptFlag::Software)) {
|
||||
} else if(enabled_requests & InterruptMask<InterruptFlag::SerialPortTransmit, InterruptFlag::DiskBlock, InterruptFlag::Software>::value) {
|
||||
interrupt_level_ = 1;
|
||||
}
|
||||
}
|
||||
@ -671,6 +678,25 @@ void Chipset::Sprite::set_image_data(int slot, uint16_t value) {
|
||||
LOG("Sprite image data " << slot << " to " << PADHEX(4) << value);
|
||||
}
|
||||
|
||||
// MARK: - Disk.
|
||||
|
||||
void Chipset::DiskDMA::advance() {
|
||||
if(!dma_enable_) return;
|
||||
|
||||
if(!write_) {
|
||||
// TODO: run an actual PLL, collect actual disk data.
|
||||
if(length_) {
|
||||
ram_[address_ & ram_mask_] = 0xffff;
|
||||
++address_;
|
||||
--length_;
|
||||
|
||||
if(!length_) {
|
||||
chipset_.posit_interrupt(InterruptFlag::DiskBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CRT connection.
|
||||
|
||||
void Chipset::set_scan_target(Outputs::Display::ScanTarget *scan_target) {
|
||||
@ -688,3 +714,4 @@ void Chipset::set_display_type(Outputs::Display::DisplayType type) {
|
||||
Outputs::Display::DisplayType Chipset::get_display_type() const {
|
||||
return crt_.get_display_type();
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,39 @@
|
||||
|
||||
namespace Amiga {
|
||||
|
||||
enum class InterruptFlag: uint16_t {
|
||||
SerialPortTransmit = 1 << 0,
|
||||
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 {
|
||||
AudioChannel0 = 1 << 0,
|
||||
AudioChannel1 = 1 << 1,
|
||||
AudioChannel2 = 1 << 2,
|
||||
AudioChannel3 = 1 << 3,
|
||||
Disk = 1 << 4,
|
||||
Sprites = 1 << 5,
|
||||
Blitter = 1 << 6,
|
||||
Copper = 1 << 7,
|
||||
Bitplane = 1 << 8,
|
||||
AllBelow = 1 << 9,
|
||||
BlitterPriority = 1 << 10,
|
||||
BlitterZero = 1 << 13,
|
||||
BlitterBusy = 1 << 14,
|
||||
};
|
||||
|
||||
class Chipset {
|
||||
public:
|
||||
Chipset(uint16_t *ram, size_t size);
|
||||
@ -72,6 +105,7 @@ class Chipset {
|
||||
uint16_t *ram_ = nullptr;
|
||||
uint32_t ram_mask_ = 0;
|
||||
};
|
||||
friend DMADevice;
|
||||
|
||||
// MARK: - Interrupts.
|
||||
|
||||
@ -80,6 +114,7 @@ class Chipset {
|
||||
int interrupt_level_ = 0;
|
||||
|
||||
void update_interrupts();
|
||||
void posit_interrupt(InterruptFlag);
|
||||
|
||||
// MARK: - Scheduler.
|
||||
|
||||
@ -190,6 +225,8 @@ class Chipset {
|
||||
}
|
||||
}
|
||||
|
||||
void advance();
|
||||
|
||||
private:
|
||||
uint32_t address_;
|
||||
uint16_t length_;
|
||||
|
Loading…
Reference in New Issue
Block a user