mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-07-05 13:28:56 +00:00
Heathrow: interrupt registers & mode 1 interrupts.
This commit is contained in:
parent
617f75851b
commit
8be44dad82
@ -209,28 +209,22 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
|
|||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
|
|
||||||
switch (offset & 0xFC) {
|
switch (offset & 0xFC) {
|
||||||
case 0x14:
|
case MIO_INT_EVENTS2:
|
||||||
LOG_F(9, "read from MIO:Int_Mask2 register \n");
|
res = this->int_events2;
|
||||||
|
break;
|
||||||
|
case MIO_INT_MASK2:
|
||||||
res = this->int_mask2;
|
res = this->int_mask2;
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case MIO_INT_LEVELS2:
|
||||||
LOG_F(9, "read from MIO:Int_Clear2 register \n");
|
|
||||||
res = this->int_clear2;
|
|
||||||
break;
|
|
||||||
case 0x1C:
|
|
||||||
LOG_F(9, "read from MIO:Int_Levels2 register \n");
|
|
||||||
res = this->int_levels2;
|
res = this->int_levels2;
|
||||||
break;
|
break;
|
||||||
case 0x24:
|
case MIO_INT_EVENTS1:
|
||||||
LOG_F(9, "read from MIO:Int_Mask1 register \n");
|
res = this->int_events1;
|
||||||
|
break;
|
||||||
|
case MIO_INT_MASK1:
|
||||||
res = this->int_mask1;
|
res = this->int_mask1;
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case MIO_INT_LEVELS1:
|
||||||
LOG_F(9, "read from MIO:Int_Clear1 register \n");
|
|
||||||
res = this->int_clear1;
|
|
||||||
break;
|
|
||||||
case 0x2C:
|
|
||||||
LOG_F(9, "read from MIO:Int_Levels1 register \n");
|
|
||||||
res = this->int_levels1;
|
res = this->int_levels1;
|
||||||
break;
|
break;
|
||||||
case 0x34: /* heathrowIDs / HEATHROW_MBCR (Linux): media bay config reg? */
|
case 0x34: /* heathrowIDs / HEATHROW_MBCR (Linux): media bay config reg? */
|
||||||
@ -239,41 +233,39 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
|
|||||||
break;
|
break;
|
||||||
case 0x38:
|
case 0x38:
|
||||||
LOG_F(9, "read from MIO:Feat_Ctrl register \n");
|
LOG_F(9, "read from MIO:Feat_Ctrl register \n");
|
||||||
res = BYTESWAP_32(this->feat_ctrl);
|
res = this->feat_ctrl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_F(WARNING, "read from unknown MIO register at %x \n", offset);
|
LOG_F(WARNING, "read from unknown MIO register at %x \n", offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return BYTESWAP_32(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
|
void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
|
||||||
switch (offset & 0xFC) {
|
switch (offset & 0xFC) {
|
||||||
case 0x14:
|
case MIO_INT_MASK2:
|
||||||
LOG_F(9, "write %x to MIO:Int_Mask2 register \n", value);
|
this->int_mask2 |= BYTESWAP_32(value) & ~MACIO_INT_MODE;
|
||||||
this->int_mask2 = value;
|
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case MIO_INT_CLEAR2:
|
||||||
LOG_F(9, "write %x to MIO:Int_Clear2 register \n", value);
|
if (value & MACIO_INT_CLR) {
|
||||||
this->int_clear2 = value;
|
this->int_events2 = 0;
|
||||||
|
} else {
|
||||||
|
this->int_events2 &= BYTESWAP_32(value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1C:
|
case MIO_INT_MASK1:
|
||||||
LOG_F(9, "write %x to MIO:Int_Levels2 register \n", value);
|
this->int_mask1 = BYTESWAP_32(value);
|
||||||
this->int_levels2 = value;
|
// copy IntMode bit to InterruptMask2 register
|
||||||
|
this->int_mask2 = (this->int_mask2 & ~MACIO_INT_MODE) | (this->int_mask1 & MACIO_INT_MODE);
|
||||||
break;
|
break;
|
||||||
case 0x24:
|
case MIO_INT_CLEAR1:
|
||||||
LOG_F(9, "write %x to MIO:Int_Mask1 register \n", value);
|
if (value & MACIO_INT_CLR) {
|
||||||
this->int_mask1 = value;
|
this->int_events1 = 0;
|
||||||
break;
|
} else {
|
||||||
case 0x28:
|
this->int_events1 &= BYTESWAP_32(value);
|
||||||
LOG_F(9, "write %x to MIO:Int_Clear1 register \n", value);
|
}
|
||||||
this->int_clear1 = value;
|
|
||||||
break;
|
|
||||||
case 0x2C:
|
|
||||||
LOG_F(9, "write %x to MIO:Int_Levels1 register \n", value);
|
|
||||||
this->int_levels1 = value;
|
|
||||||
break;
|
break;
|
||||||
case 0x34:
|
case 0x34:
|
||||||
LOG_F(WARNING, "Attempted to write %x to MIO:ID at %x; Address : %x \n", value, offset, ppc_state.pc);
|
LOG_F(WARNING, "Attempted to write %x to MIO:ID at %x; Address : %x \n", value, offset, ppc_state.pc);
|
||||||
@ -306,6 +298,16 @@ void HeathrowIC::feature_control(const uint32_t value)
|
|||||||
|
|
||||||
uint32_t HeathrowIC::register_dev_int(IntSrc src_id)
|
uint32_t HeathrowIC::register_dev_int(IntSrc src_id)
|
||||||
{
|
{
|
||||||
|
switch (src_id) {
|
||||||
|
case IntSrc::VIA_CUDA:
|
||||||
|
return 1 << 7;
|
||||||
|
case IntSrc::SCSI1:
|
||||||
|
return 1 << 1;
|
||||||
|
case IntSrc::SWIM3:
|
||||||
|
return 1 << 8;
|
||||||
|
default:
|
||||||
|
ABORT_F("Heathrow: unknown interrupt source %d", src_id);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,6 +318,35 @@ uint32_t HeathrowIC::register_dma_int(IntSrc src_id)
|
|||||||
|
|
||||||
void HeathrowIC::ack_int(uint32_t irq_id, uint8_t irq_line_state)
|
void HeathrowIC::ack_int(uint32_t irq_id, uint8_t irq_line_state)
|
||||||
{
|
{
|
||||||
|
if (this->int_mask1 & MACIO_INT_MODE) { // 68k interrupt emulation mode?
|
||||||
|
if (irq_id > 0x200000) {
|
||||||
|
irq_id >>= 21;
|
||||||
|
this->int_events2 |= irq_id; // signal IRQ line change
|
||||||
|
this->int_events2 &= this->int_mask2;
|
||||||
|
// update IRQ line state
|
||||||
|
if (irq_line_state) {
|
||||||
|
this->int_levels2 |= irq_id;
|
||||||
|
} else {
|
||||||
|
this->int_levels2 &= ~irq_id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
irq_id <<= 11;
|
||||||
|
this->int_events1 |= irq_id; // signal IRQ line change
|
||||||
|
this->int_events1 &= this->int_mask1;
|
||||||
|
// update IRQ line state
|
||||||
|
if (irq_line_state) {
|
||||||
|
this->int_levels1 |= irq_id;
|
||||||
|
} else {
|
||||||
|
this->int_levels1 &= ~irq_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// signal CPU interrupt
|
||||||
|
if (this->int_events1 || this->int_events2) {
|
||||||
|
ppc_ext_int();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ABORT_F("Heathrow: native interrupt mode not implemented");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state)
|
void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
Copyright (C) 2018-21 divingkatae and maximum
|
Copyright (C) 2018-22 divingkatae and maximum
|
||||||
(theweirdo) spatium
|
(theweirdo) spatium
|
||||||
|
|
||||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
@ -67,6 +67,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
/** Interrupt related constants. */
|
||||||
|
#define MACIO_INT_CLR 0x80UL // clears bits in the interrupt events registers
|
||||||
|
#define MACIO_INT_MODE 0x80000000UL // interrupt mode: 0 - native, 1 - 68k-style
|
||||||
|
|
||||||
/** Offsets to common MacIO interrupt registers. */
|
/** Offsets to common MacIO interrupt registers. */
|
||||||
enum {
|
enum {
|
||||||
MIO_INT_EVENTS2 = 0x10,
|
MIO_INT_EVENTS2 = 0x10,
|
||||||
@ -164,11 +168,11 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t base_addr = 0;
|
uint32_t base_addr = 0;
|
||||||
|
uint32_t int_events2 = 0;
|
||||||
uint32_t int_mask2 = 0;
|
uint32_t int_mask2 = 0;
|
||||||
uint32_t int_clear2 = 0;
|
|
||||||
uint32_t int_levels2 = 0;
|
uint32_t int_levels2 = 0;
|
||||||
|
uint32_t int_events1 = 0;
|
||||||
uint32_t int_mask1 = 0;
|
uint32_t int_mask1 = 0;
|
||||||
uint32_t int_clear1 = 0;
|
|
||||||
uint32_t int_levels1 = 0;
|
uint32_t int_levels1 = 0;
|
||||||
uint32_t macio_id = 0xF0700008UL;
|
uint32_t macio_id = 0xF0700008UL;
|
||||||
uint32_t feat_ctrl = 0; // features control register
|
uint32_t feat_ctrl = 0; // features control register
|
||||||
|
Loading…
Reference in New Issue
Block a user