Initial work on setting up for interrupts

This commit is contained in:
dingusdev 2021-11-21 16:17:15 -07:00
parent 84ded9fc7a
commit 49a5951647
4 changed files with 171 additions and 13 deletions

View File

@ -0,0 +1,65 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <cpu/ppc/ppcemu.h>
#include "hwinterrupt.h"
#include <cinttypes>
#include <string>
#include <loguru.hpp>
using namespace std;
InterruptManager::InterruptManager(std::string sys_type) {
if (sys_type.compare("Heathrow") == 0) {
scsi0_dma_mask_bit = (1 << 0);
scca_dma_out_mask_bit = (1 << 4);
scca_dma_in_mask_bit = (1 << 5);
sccb_dma_out_mask_bit = (1 << 6);
sccb_dma_in_mask_bit = (1 << 7);
dav_dma_out_mask_bit = (1 << 8);
dav_dma_in_mask_bit = (1 << 9);
scsi0_mask_bit = (1 << 12);
scca_mask_bit = (1 << 15);
sccb_mask_bit = (1 << 16);
davbus_mask_bit = (1 << 17);
cuda_mask_bit = (1 << 18);
nmi_mask_bit = (1 << 20);
}
else if (sys_type.compare("AMIC") == 0) {
LOG_F(WARNING, "Missing interrupt handling for %s!", sys_type.c_str());
}
else {
LOG_F(ERROR, "Cannot determine interrupt layout for %s!", sys_type.c_str());
}
}
uint32_t InterruptManager::ack_interrupts(){
}
uint32_t InterruptManager::clear_interrupts(){
}
void InterruptManager::call_ppc_handler(uint32_t device_bits) {
ppc_exception_handler(Except_Type::EXC_EXT_INT, device_bits);
}

View File

@ -0,0 +1,55 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef HWINTERRUPT_H
#define HWINTERRUPT_H
#include <cinttypes>
#include <memory>
class InterruptManager {
public:
InterruptManager(std::string sys_type = "None");
~InterruptManager() = default;
uint32_t ack_interrupts();
uint32_t clear_interrupts();
void call_ppc_handler(uint32_t device_bits);
private:
uint32_t int1_flags;
uint32_t int2_flags;
uint32_t scsi0_dma_mask_bit = 0;
uint32_t scca_dma_out_mask_bit = 0;
uint32_t scca_dma_in_mask_bit = 0;
uint32_t sccb_dma_out_mask_bit = 0;
uint32_t sccb_dma_in_mask_bit = 0;
uint32_t dav_dma_out_mask_bit = 0;
uint32_t dav_dma_in_mask_bit = 0;
uint32_t scsi0_mask_bit = 0;
uint32_t scca_mask_bit = 0;
uint32_t sccb_mask_bit = 0;
uint32_t davbus_mask_bit = 0;
uint32_t cuda_mask_bit = 0;
uint32_t nmi_mask_bit = 0;
};
#endif /* HWINTERRUPT_H */

View File

@ -129,6 +129,9 @@ uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size) {
case 0x10:
res = this->mesh->read((offset >> 4) & 0xF);
break;
case 0x11: // BMAC
LOG_F(WARNING, "Attempted to read from BMAC: %x \n", (offset - 0x11000));
break;
case 0x12: // ESCC compatible
return this->escc->read_compat((offset >> 4) & 0xF);
case 0x13: // ESCC MacRISC
@ -136,10 +139,17 @@ uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size) {
case 0x14:
res = this->screamer->snd_ctrl_read(offset - 0x14000, size);
break;
case 0x15: // BMAC
LOG_F(WARNING, "Attempted to read from SWIM3: %x \n", (offset - 0x15000));
break;
case 0x16:
case 0x17:
res = this->viacuda->read((offset - 0x16000) >> 9);
break;
case 0x20: // IDE
case 0x21:
LOG_F(WARNING, "Attempted to read from IDE: %x \n", (offset - 0x20000));
break;
default:
if (sub_addr >= 0x60) {
res = this->nvram->read_byte((offset - 0x60000) >> 4);
@ -166,6 +176,9 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
case 0x10:
this->mesh->write((offset >> 4) & 0xF, value);
break;
case 0x11: // BMAC
LOG_F(WARNING, "Attempted to write to BMAC: %x \n", (offset - 0x11000));
break;
case 0x12: // ESCC compatible
this->escc->write_compat((offset >> 4) & 0xF, value);
break;
@ -175,10 +188,17 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
case 0x14:
this->screamer->snd_ctrl_write(offset - 0x14000, value, size);
break;
case 0x15: // SWIM 3
LOG_F(WARNING, "Attempted to write to SWIM 3: %x \n", (offset - 0x15000));
break;
case 0x16:
case 0x17:
this->viacuda->write((offset - 0x16000) >> 9, value);
break;
case 0x20: // IDE
case 0x21:
LOG_F(WARNING, "Attempted to write to IDE: %x \n", (offset - 0x20000));
break;
default:
if (sub_addr >= 0x60) {
this->nvram->write_byte((offset - 0x60000) >> 4, value);
@ -192,28 +212,36 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
uint32_t res = 0;
switch (offset & 0xFC) {
case 0x10:
LOG_F(0, "read from MIO:Int_Events2 register \n");
res = this->int_events2;
break;
case 0x14:
LOG_F(9, "read from MIO:Int_Mask2 register \n");
LOG_F(0, "read from MIO:Int_Mask2 register \n");
res = this->int_mask2;
break;
case 0x18:
LOG_F(9, "read from MIO:Int_Clear2 register \n");
LOG_F(0, "read from MIO:Int_Clear2 register \n");
res = this->int_clear2;
break;
case 0x1C:
LOG_F(9, "read from MIO:Int_Levels2 register \n");
LOG_F(0, "read from MIO:Int_Levels2 register \n");
res = this->int_levels2;
break;
case 0x20:
LOG_F(0, "read from MIO:Int_Events1 register \n");
res = this->int_events2;
break;
case 0x24:
LOG_F(9, "read from MIO:Int_Mask1 register \n");
LOG_F(0, "read from MIO:Int_Mask1 register \n");
res = this->int_mask1;
break;
case 0x28:
LOG_F(9, "read from MIO:Int_Clear1 register \n");
LOG_F(0, "read from MIO:Int_Clear1 register \n");
res = this->int_clear1;
break;
case 0x2C:
LOG_F(9, "read from MIO:Int_Levels1 register \n");
LOG_F(0, "read from MIO:Int_Levels1 register \n");
res = this->int_levels1;
break;
case 0x34: /* heathrowIDs / HEATHROW_MBCR (Linux): media bay config reg? */
@ -234,28 +262,36 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
switch (offset & 0xFC) {
case 0x10:
LOG_F(0, "write %x to MIO:Int_Events2 register \n", value);
this->int_events2 = value;
break;
case 0x14:
LOG_F(9, "write %x to MIO:Int_Mask2 register \n", value);
LOG_F(0, "write %x to MIO:Int_Mask2 register \n", value);
this->int_mask2 = value;
break;
case 0x18:
LOG_F(9, "write %x to MIO:Int_Clear2 register \n", value);
LOG_F(0, "write %x to MIO:Int_Clear2 register \n", value);
this->int_clear2 = value;
break;
case 0x1C:
LOG_F(9, "write %x to MIO:Int_Levels2 register \n", value);
LOG_F(0, "write %x to MIO:Int_Levels2 register \n", value);
this->int_levels2 = value;
break;
case 0x20:
LOG_F(0, "write %x to MIO:Int_Events1 register \n", value);
this->int_events1 = value;
break;
case 0x24:
LOG_F(9, "write %x to MIO:Int_Mask1 register \n", value);
LOG_F(0, "write %x to MIO:Int_Mask1 register \n", value);
this->int_mask1 = value;
break;
case 0x28:
LOG_F(9, "write %x to MIO:Int_Clear1 register \n", value);
LOG_F(0, "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);
LOG_F(0, "write %x to MIO:Int_Levels1 register \n", value);
this->int_levels1 = value;
break;
case 0x34:
@ -276,7 +312,7 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
void HeathrowIC::feature_control(const uint32_t value)
{
LOG_F(9, "write %x to MIO:Feat_Ctrl register \n", value);
LOG_F(0, "write %x to MIO:Feat_Ctrl register \n", value);
this->feat_ctrl = value;

View File

@ -143,9 +143,11 @@ private:
0x00 // unknown defaults
};
uint32_t int_events2 = 0;
uint32_t int_mask2 = 0;
uint32_t int_clear2 = 0;
uint32_t int_levels2 = 0;
uint32_t int_events1 = 0;
uint32_t int_mask1 = 0;
uint32_t int_clear1 = 0;
uint32_t int_levels1 = 0;