diff --git a/devices/common/nubus/houdini2.cpp b/devices/common/nubus/houdini2.cpp
new file mode 100644
index 0000000..2e70611
--- /dev/null
+++ b/devices/common/nubus/houdini2.cpp
@@ -0,0 +1,92 @@
+/*
+DingusPPC - The Experimental PowerPC Macintosh emulator
+Copyright (C) 2018-22 divingkatae and maximum
+ (theweirdo) spatium
+
+(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+/** Houdini2 PC Compatibility card emulation. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+HoudiniCard::HoudiniCard()
+{
+ supports_types(HWCompType::PDS_DEV);
+
+ this->pl_obj = std::unique_ptr (new PretzelLogic());
+
+ auto mem_crtl = dynamic_cast(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
+ mem_crtl->add_mmio_region(0xE0000000, 0x10000, this->pl_obj.get());
+
+ // load card's declaration ROM
+ if (load_declaration_rom("Houdini2_DeclROM.bin", 0xE)) {
+ LOG_F(ERROR, "Could not load declaration ROM, the card won't work!");
+ }
+}
+
+PretzelLogic::PretzelLogic()
+{
+ supports_types(HWCompType::MMIO_DEV);
+
+ // tell the world we got some own memory
+ // (shared memory will be disabled)
+ this->air3 = Air3Bits::SIMM_INSTALLED;
+
+ this->air_reset = 1; // tell the world our PC is not currently running
+}
+
+uint32_t PretzelLogic::read(uint32_t rgn_start, uint32_t offset, int size)
+{
+ switch (offset) {
+ case PretzelLogicReg::AIR_RESET:
+ return this->air_reset;
+ case PretzelLogicReg::AIR3:
+ return this->air3;
+ default:
+ LOG_F(WARNING, "PretzelLogic: reading from unimplemented reg at 0x%X", offset);
+ }
+
+ return 0xFF;
+}
+
+void PretzelLogic::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size)
+{
+ switch (offset) {
+ case PretzelLogicReg::MAIN_IER:
+ this->main_ier = value;
+ if (!value) {
+ LOG_F(INFO, "PretzelLogic: all interrupts disabled");
+ }
+ break;
+ default:
+ LOG_F(WARNING, "PretzelLogic: writing to unimplemented reg at 0x%X", offset);
+ }
+}
+
+static const DeviceDescription Houdini_Descriptor = {
+ HoudiniCard::create, {}, {}
+};
+
+REGISTER_DEVICE(Houdini2, Houdini_Descriptor);
diff --git a/devices/common/nubus/houdini2.h b/devices/common/nubus/houdini2.h
new file mode 100644
index 0000000..09277ea
--- /dev/null
+++ b/devices/common/nubus/houdini2.h
@@ -0,0 +1,75 @@
+/*
+DingusPPC - The Experimental PowerPC Macintosh emulator
+Copyright (C) 2018-22 divingkatae and maximum
+ (theweirdo) spatium
+
+(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+/** Houdini2 PC Compatibility card definitions. */
+
+#ifndef HOUDINI2_H
+#define HOUDINI2_H
+
+#include
+
+#include
+#include
+
+enum PretzelLogicReg {
+ MAIN_IER = 0xE0,
+ MAIN_ISR = 0xE4,
+ AIR_RESET = 0xE8,
+ AIR3 = 0x8004,
+};
+
+enum Air3Bits {
+ SIMM_INSTALLED = 1 << 7, // if set, on-card memory SIMM is installed
+};
+
+// Pretzel Logic ASIC
+class PretzelLogic : public MMIODevice {
+public:
+ PretzelLogic();
+ ~PretzelLogic() = default;
+
+ uint32_t read(uint32_t rgn_start, uint32_t offset, int size);
+ void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size);
+
+private:
+ uint8_t air_reset;
+ uint8_t air_status;
+ uint8_t air2;
+ uint8_t air3;
+ uint8_t port_AB_dir;
+ uint8_t port_AB_data;
+ uint8_t main_ier; // main interrupt enable register
+};
+
+class HoudiniCard : public HWComponent {
+public:
+ HoudiniCard();
+ ~HoudiniCard() = default;
+
+ static std::unique_ptr create() {
+ return std::unique_ptr(new HoudiniCard());
+ };
+
+private:
+ std::unique_ptr pl_obj;
+};
+
+#endif // HOUDINI2_H