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); }