diff --git a/devices/common/hwcomponent.h b/devices/common/hwcomponent.h
index cb3aab2..4e2c8fd 100644
--- a/devices/common/hwcomponent.h
+++ b/devices/common/hwcomponent.h
@@ -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. */
diff --git a/devices/floppy/swim3.cpp b/devices/floppy/swim3.cpp
index dd045c8..66413b4 100644
--- a/devices/floppy/swim3.cpp
+++ b/devices/floppy/swim3.cpp
@@ -22,6 +22,7 @@ along with this program. If not, see .
/** @file Sander-Wozniak Machine 3 (SWIM3) emulation. */
#include
+#include
#include
#include
#include
@@ -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(
+ 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()
diff --git a/devices/floppy/swim3.h b/devices/floppy/swim3.h
index c0bbebb..ccfffcb 100644
--- a/devices/floppy/swim3.h
+++ b/devices/floppy/swim3.h
@@ -24,7 +24,9 @@ along with this program. If not, see .
#ifndef SWIM3_H
#define SWIM3_H
-#include "superdrive.h"
+#include
+#include
+#include
#include
#include
@@ -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
diff --git a/devices/ioctrl/amic.cpp b/devices/ioctrl/amic.cpp
index d1e7f5c..e240526 100644
--- a/devices/ioctrl/amic.cpp
+++ b/devices/ioctrl/amic.cpp
@@ -70,6 +70,7 @@ AMIC::AMIC() : MMIODevice()
// intialize floppy disk HW
this->swim3 = std::unique_ptr (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);
}