mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-11 04:29:37 +00:00
Initial work on setting up for interrupts
This commit is contained in:
parent
84ded9fc7a
commit
49a5951647
65
devices/common/hwinterrupt.cpp
Normal file
65
devices/common/hwinterrupt.cpp
Normal 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);
|
||||
}
|
55
devices/common/hwinterrupt.h
Normal file
55
devices/common/hwinterrupt.h
Normal 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 */
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user