mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 21:29:28 +00:00
AMIC: implement periodic VBL (60.15 Hz) interrupt.
This commit is contained in:
parent
0899186ffc
commit
3bdc6f915a
@ -24,6 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
Author: Max Poliakovski
|
Author: Max Poliakovski
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <core/timermanager.h>
|
||||||
#include <cpu/ppc/ppcemu.h>
|
#include <cpu/ppc/ppcemu.h>
|
||||||
#include <cpu/ppc/ppcmmu.h>
|
#include <cpu/ppc/ppcmmu.h>
|
||||||
#include <devices/common/scsi/ncr53c94.h>
|
#include <devices/common/scsi/ncr53c94.h>
|
||||||
@ -46,19 +47,12 @@ AMIC::AMIC() : MMIODevice()
|
|||||||
{
|
{
|
||||||
this->name = "Apple Memory-mapped I/O Controller";
|
this->name = "Apple Memory-mapped I/O Controller";
|
||||||
|
|
||||||
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
|
||||||
(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
|
||||||
|
|
||||||
/* add memory mapped I/O region for the AMIC control registers */
|
|
||||||
if (!mem_ctrl->add_mmio_region(0x50F00000, 0x00040000, this)) {
|
|
||||||
LOG_F(ERROR, "Couldn't register AMIC registers!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// register I/O devices
|
// register I/O devices
|
||||||
this->scsi = std::unique_ptr<Ncr53C94> (new Ncr53C94());
|
this->scsi = std::unique_ptr<Ncr53C94> (new Ncr53C94());
|
||||||
this->escc = std::unique_ptr<EsccController> (new EsccController());
|
this->escc = std::unique_ptr<EsccController> (new EsccController());
|
||||||
this->mace = std::unique_ptr<MaceController> (new MaceController(MACE_ID));
|
this->mace = std::unique_ptr<MaceController> (new MaceController(MACE_ID));
|
||||||
this->viacuda = std::unique_ptr<ViaCuda> (new ViaCuda());
|
this->viacuda = std::unique_ptr<ViaCuda> (new ViaCuda());
|
||||||
|
gMachineObj->add_subdevice("ViaCuda", this->viacuda.get());
|
||||||
|
|
||||||
// initialize sound HW
|
// initialize sound HW
|
||||||
this->snd_out_dma = std::unique_ptr<AmicSndOutDma> (new AmicSndOutDma());
|
this->snd_out_dma = std::unique_ptr<AmicSndOutDma> (new AmicSndOutDma());
|
||||||
@ -73,6 +67,26 @@ AMIC::AMIC() : MMIODevice()
|
|||||||
this->swim3 = std::unique_ptr<Swim3::Swim3Ctrl> (new Swim3::Swim3Ctrl());
|
this->swim3 = std::unique_ptr<Swim3::Swim3Ctrl> (new Swim3::Swim3Ctrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AMIC::device_postinit()
|
||||||
|
{
|
||||||
|
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
||||||
|
(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
||||||
|
|
||||||
|
// add memory mapped I/O region for the AMIC control registers
|
||||||
|
if (!mem_ctrl->add_mmio_region(0x50F00000, 0x00040000, this)) {
|
||||||
|
LOG_F(ERROR, "Couldn't register AMIC registers!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// AMIC drives the VIA CA1 internally to generate 60.15 Hz interrupts
|
||||||
|
this->pseudo_vbl_tid = TimerManager::get_instance()->add_cyclic_timer(
|
||||||
|
static_cast<uint64_t>((1.0f/60.15) * NS_PER_SEC + 0.5f),
|
||||||
|
[this]() {
|
||||||
|
this->viacuda->assert_ctrl_line(ViaLine::CA1);
|
||||||
|
});
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t AMIC::read(uint32_t reg_start, uint32_t offset, int size)
|
uint32_t AMIC::read(uint32_t reg_start, uint32_t offset, int size)
|
||||||
{
|
{
|
||||||
uint32_t phase_val;
|
uint32_t phase_val;
|
||||||
|
@ -142,10 +142,13 @@ public:
|
|||||||
AMIC();
|
AMIC();
|
||||||
~AMIC() = default;
|
~AMIC() = default;
|
||||||
|
|
||||||
|
// HWComponent methods
|
||||||
bool supports_type(HWCompType type) {
|
bool supports_type(HWCompType type) {
|
||||||
return (type == HWCompType::MMIO_DEV) || (type == HWCompType::INT_CTRL);
|
return (type == HWCompType::MMIO_DEV) || (type == HWCompType::INT_CTRL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int device_postinit();
|
||||||
|
|
||||||
/* MMIODevice methods */
|
/* MMIODevice methods */
|
||||||
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
|
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
|
||||||
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
|
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
|
||||||
@ -168,6 +171,8 @@ private:
|
|||||||
uint8_t int_ctrl = 0;
|
uint8_t int_ctrl = 0;
|
||||||
uint8_t dev_irq_lines = 0; // state of the IRQ lines
|
uint8_t dev_irq_lines = 0; // state of the IRQ lines
|
||||||
|
|
||||||
|
uint32_t pseudo_vbl_tid; // ID for the pseudo-VBL timer
|
||||||
|
|
||||||
// AMIC subdevices instances
|
// AMIC subdevices instances
|
||||||
std::unique_ptr<Ncr53C94> scsi;
|
std::unique_ptr<Ncr53C94> scsi;
|
||||||
std::unique_ptr<EsccController> escc;
|
std::unique_ptr<EsccController> escc;
|
||||||
|
Loading…
Reference in New Issue
Block a user