diff --git a/devices/ioctrl/grandcentral.cpp b/devices/ioctrl/grandcentral.cpp index 04c2176..3fcf0de 100644 --- a/devices/ioctrl/grandcentral.cpp +++ b/devices/ioctrl/grandcentral.cpp @@ -19,6 +19,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include #include #include @@ -121,6 +122,14 @@ uint32_t GrandCentral::read(uint32_t reg_start, uint32_t offset, int size) this->base_addr + offset); } } else { // Interrupt related registers + switch (offset) { + case MIO_INT_MASK1: + return BYTESWAP_32(this->int_mask); + case MIO_INT_LEVELS1: + return BYTESWAP_32(this->int_levels); + case MIO_INT_EVENTS1: + return BYTESWAP_32(this->int_events); + } } LOG_F(WARNING, "GC: reading from unmapped I/O memory 0x%X", this->base_addr + offset); @@ -190,6 +199,13 @@ void GrandCentral::write(uint32_t reg_start, uint32_t offset, uint32_t value, in case MIO_INT_MASK1: this->int_mask = BYTESWAP_32(value); break; + case MIO_INT_CLEAR1: + if (value & MACIO_INT_CLR) { + this->int_events = 0; + } else { + this->int_events &= BYTESWAP_32(value); + } + break; default: LOG_F(WARNING, "GC: writing to unmapped I/O memory 0x%X", this->base_addr + offset); @@ -199,18 +215,46 @@ void GrandCentral::write(uint32_t reg_start, uint32_t offset, uint32_t value, in uint32_t GrandCentral::register_dev_int(IntSrc src_id) { + switch (src_id) { + case IntSrc::VIA_CUDA: + return 1 << 18; + case IntSrc::SCSI1: + return 1 << 12; + case IntSrc::SWIM3: + return 1 << 19; + default: + ABORT_F("GC: unknown interrupt source %d", src_id); + } return 0; } uint32_t GrandCentral::register_dma_int(IntSrc src_id) { + ABORT_F("GC: register_dma_int() not implemened"); return 0; } void GrandCentral::ack_int(uint32_t irq_id, uint8_t irq_line_state) { + if (this->int_mask & MACIO_INT_MODE) { // 68k interrupt emulation mode? + this->int_events |= irq_id; // signal IRQ line change + this->int_events &= this->int_mask; + // update IRQ line state + if (irq_line_state) { + this->int_levels |= irq_id; + } else { + this->int_levels &= ~irq_id; + } + // signal CPU interrupt + if (this->int_events) { + ppc_ext_int(); + } + } else { + ABORT_F("GC: native interrupt mode not implemented"); + } } void GrandCentral::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state) { + ABORT_F("GC: ack_dma_int() not implemened"); } diff --git a/devices/ioctrl/macio.h b/devices/ioctrl/macio.h index b8a0a69..3862550 100644 --- a/devices/ioctrl/macio.h +++ b/devices/ioctrl/macio.h @@ -104,7 +104,11 @@ protected: private: uint32_t base_addr = 0; - uint32_t int_mask = 0; + + // interrupt state + uint32_t int_mask = 0; + uint32_t int_levels = 0; + uint32_t int_events = 0; uint32_t nvram_addr_hi;