AMIC: handle SWIM3 interrupts.

This commit is contained in:
Maxim Poliakovski 2022-02-07 23:04:13 +01:00
parent c77155199b
commit 9f3f46603f
4 changed files with 35 additions and 3 deletions

View File

@ -43,7 +43,8 @@ enum HWCompType {
SCSI_HOST = 1ULL << 21, /* SCSI host adapter */
SCSI_DEV = 1ULL << 22, /* SCSI device */
SND_SERVER = 1ULL << 31, /* host sound server */
FLOPPY_DRV = 1ULL << 32, /* floppy disk drive */
FLOPPY_CTRL = 1ULL << 32, /* floppy disk controller */
FLOPPY_DRV = 1ULL << 33, /* floppy disk drive */
};
/** Base class for HW components. */

View File

@ -22,6 +22,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
/** @file Sander-Wozniak Machine 3 (SWIM3) emulation. */
#include <core/timermanager.h>
#include <devices/common/hwinterrupt.h>
#include <devices/floppy/superdrive.h>
#include <devices/floppy/swim3.h>
#include <loguru.hpp>
@ -34,6 +35,9 @@ using namespace Swim3;
Swim3Ctrl::Swim3Ctrl()
{
this->name = "SWIM3";
this->supported_types = HWCompType::FLOPPY_CTRL;
this->setup_reg = 0;
this->mode_reg = 0;
this->int_reg = 0;
@ -49,6 +53,15 @@ Swim3Ctrl::Swim3Ctrl()
gMachineObj->add_subdevice("Superdrive", this->int_drive.get());
}
int Swim3Ctrl::device_postinit()
{
this->int_ctrl = dynamic_cast<InterruptCtrl*>(
gMachineObj->get_comp_by_type(HWCompType::INT_CTRL));
this->irq_id = this->int_ctrl->register_dev_int(IntSrc::SWIM3);
return 0;
};
uint8_t Swim3Ctrl::read(uint8_t reg_offset)
{
uint8_t status_addr, old_int_flags;
@ -134,6 +147,11 @@ void Swim3Ctrl::write(uint8_t reg_offset, uint8_t value)
void Swim3Ctrl::update_irq()
{
uint8_t new_irq = !!(this->int_flags & this->int_mask);
if (new_irq != this->irq) {
this->irq = new_irq;
this->int_ctrl->ack_int(this->irq_id, new_irq);
}
}
void Swim3Ctrl::do_step()

View File

@ -24,7 +24,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef SWIM3_H
#define SWIM3_H
#include "superdrive.h"
#include <devices/common/hwcomponent.h>
#include <devices/common/hwinterrupt.h>
#include <devices/floppy/superdrive.h>
#include <cinttypes>
#include <memory>
@ -62,11 +64,13 @@ enum {
INT_STEP_DONE = 0x02,
};
class Swim3Ctrl {
class Swim3Ctrl : public HWComponent {
public:
Swim3Ctrl();
~Swim3Ctrl() = default;
int device_postinit();
// SWIM3 registers access
uint8_t read(uint8_t reg_offset);
void write(uint8_t reg_offset, uint8_t value);
@ -94,6 +98,11 @@ private:
uint8_t xfer_cnt;
int step_timer_id = 0;
// Interrupt related stuff
InterruptCtrl* int_ctrl = nullptr;
uint32_t irq_id = 0;
uint8_t irq = 0;
};
}; // namespace Swim3

View File

@ -70,6 +70,7 @@ AMIC::AMIC() : MMIODevice()
// intialize floppy disk HW
this->swim3 = std::unique_ptr<Swim3::Swim3Ctrl> (new Swim3::Swim3Ctrl());
gMachineObj->add_subdevice("SWIM3", this->swim3.get());
}
int AMIC::device_postinit()
@ -129,6 +130,7 @@ uint32_t AMIC::read(uint32_t reg_start, uint32_t offset, int size)
case AMICReg::Snd_Out_DMA:
return this->snd_out_dma->read_stat();
}
break;
case 0x16: // SWIM3 registers
case 0x17:
return this->swim3->read((offset >> 9) & 0xF);
@ -327,6 +329,8 @@ uint32_t AMIC::register_dev_int(IntSrc src_id) {
return 1;
case IntSrc::SCSI1:
return 0x800;
case IntSrc::SWIM3:
return 0x2000;
default:
ABORT_F("AMIC: unknown interrupt source %d", src_id);
}