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_HOST = 1ULL << 21, /* SCSI host adapter */
SCSI_DEV = 1ULL << 22, /* SCSI device */ SCSI_DEV = 1ULL << 22, /* SCSI device */
SND_SERVER = 1ULL << 31, /* host sound server */ 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. */ /** 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. */ /** @file Sander-Wozniak Machine 3 (SWIM3) emulation. */
#include <core/timermanager.h> #include <core/timermanager.h>
#include <devices/common/hwinterrupt.h>
#include <devices/floppy/superdrive.h> #include <devices/floppy/superdrive.h>
#include <devices/floppy/swim3.h> #include <devices/floppy/swim3.h>
#include <loguru.hpp> #include <loguru.hpp>
@ -34,6 +35,9 @@ using namespace Swim3;
Swim3Ctrl::Swim3Ctrl() Swim3Ctrl::Swim3Ctrl()
{ {
this->name = "SWIM3";
this->supported_types = HWCompType::FLOPPY_CTRL;
this->setup_reg = 0; this->setup_reg = 0;
this->mode_reg = 0; this->mode_reg = 0;
this->int_reg = 0; this->int_reg = 0;
@ -49,6 +53,15 @@ Swim3Ctrl::Swim3Ctrl()
gMachineObj->add_subdevice("Superdrive", this->int_drive.get()); 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 Swim3Ctrl::read(uint8_t reg_offset)
{ {
uint8_t status_addr, old_int_flags; 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() 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() 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 #ifndef SWIM3_H
#define 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 <cinttypes>
#include <memory> #include <memory>
@ -62,11 +64,13 @@ enum {
INT_STEP_DONE = 0x02, INT_STEP_DONE = 0x02,
}; };
class Swim3Ctrl { class Swim3Ctrl : public HWComponent {
public: public:
Swim3Ctrl(); Swim3Ctrl();
~Swim3Ctrl() = default; ~Swim3Ctrl() = default;
int device_postinit();
// SWIM3 registers access // SWIM3 registers access
uint8_t read(uint8_t reg_offset); uint8_t read(uint8_t reg_offset);
void write(uint8_t reg_offset, uint8_t value); void write(uint8_t reg_offset, uint8_t value);
@ -94,6 +98,11 @@ private:
uint8_t xfer_cnt; uint8_t xfer_cnt;
int step_timer_id = 0; int step_timer_id = 0;
// Interrupt related stuff
InterruptCtrl* int_ctrl = nullptr;
uint32_t irq_id = 0;
uint8_t irq = 0;
}; };
}; // namespace Swim3 }; // namespace Swim3

View File

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