aboutsummaryrefslogtreecommitdiff
path: root/src/chips
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2025-03-29 00:44:52 +0300
committerWohlstand <admin@wohlnet.ru>2025-03-29 00:44:52 +0300
commite92a4d7285197ab2868aa36f975d73ceee915bea (patch)
treeb5e3af6e6c58145a62ec6394a40e9e65d26a5fcf /src/chips
parent7afda0483ab0af9db624052321b42c3d2a245e75 (diff)
downloadlibADLMIDI-e92a4d7285197ab2868aa36f975d73ceee915bea.tar.gz
libADLMIDI-e92a4d7285197ab2868aa36f975d73ceee915bea.tar.bz2
libADLMIDI-e92a4d7285197ab2868aa36f975d73ceee915bea.zip
Refactored DOS support
Diffstat (limited to 'src/chips')
-rw-r--r--src/chips/dos_hw_opl.cpp163
-rw-r--r--src/chips/dos_hw_opl.h48
2 files changed, 211 insertions, 0 deletions
diff --git a/src/chips/dos_hw_opl.cpp b/src/chips/dos_hw_opl.cpp
new file mode 100644
index 0000000..a9f4765
--- /dev/null
+++ b/src/chips/dos_hw_opl.cpp
@@ -0,0 +1,163 @@
+/*
+ * Interfaces over Yamaha OPL3 (YMF262) chip emulators
+ *
+ * Copyright (c) 2017-2025 Vitaly Novichkov (Wohlstand)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#ifdef __DJGPP__
+# include <pc.h>
+#endif
+
+#include "dos_hw_opl.h"
+
+static uint16_t s_OPLBase[2] = {0x388, 0x38A};
+static char s_devName[80] = {0};
+static OPLChipBase::ChipType s_type = OPLChipBase::CHIPTYPE_OPL3;
+static bool s_detected = false;
+
+static void s_updateDevName()
+{
+ const char *oplName = (s_type == OPLChipBase::CHIPTYPE_OPL3) ? "OPL3" : "OPL2";
+ memset(s_devName, 0, sizeof(s_devName));
+ snprintf(s_devName, 80, "%s at 0x%03X", oplName, s_OPLBase[0]);
+}
+
+static void s_detect()
+{
+ if(s_detected)
+ return;
+
+ const char *blaster = getenv("BLASTER");
+ if(blaster)
+ {
+ size_t len = strlen(blaster);
+ for(size_t i = 0; i < len - 1; ++i)
+ {
+ if(blaster[i] == 'T')
+ {
+ switch(blaster[i + 1])
+ {
+ case '1':
+ case '2':
+ s_type = OPLChipBase::CHIPTYPE_OPL2;
+ break;
+ case '3':
+ case '4':
+ case '6':
+ s_type = OPLChipBase::CHIPTYPE_OPL3;
+ break;
+ default:
+ s_type = OPLChipBase::CHIPTYPE_OPL2;
+ break;
+ }
+
+ // printf("-- Detected BLASTER T%c\n", blaster[i + 1]);
+
+ break;
+ }
+ }
+ }
+ else
+ s_type = OPLChipBase::CHIPTYPE_OPL2;
+
+ s_detected = true;
+}
+
+DOS_HW_OPL::DOS_HW_OPL()
+{
+ s_detect();
+ s_updateDevName();
+}
+
+void DOS_HW_OPL::setOplAddress(uint16_t address)
+{
+ s_OPLBase[0] = address;
+ s_OPLBase[1] = address + 2;
+ s_updateDevName();
+}
+
+void DOS_HW_OPL::setChipType(ChipType type)
+{
+ s_type = type;
+ s_detected = true; // Assignd manually, no need to detect
+}
+
+DOS_HW_OPL::~DOS_HW_OPL()
+{
+ DOS_HW_OPL::writeReg(0x0BD, 0);
+ if(s_type == CHIPTYPE_OPL3)
+ {
+ DOS_HW_OPL::writeReg(0x104, 0);
+ DOS_HW_OPL::writeReg(0x105, 0);
+ }
+}
+
+void DOS_HW_OPL::writeReg(uint16_t addr, uint8_t data)
+{
+ assert(m_id <= 1);
+ unsigned o = addr >> 8;
+ unsigned port = s_OPLBase[m_id] + o * 2;
+
+# ifdef __DJGPP__
+ outportb(port, addr);
+
+ for(unsigned c = 0; c < 6; ++c)
+ inportb(port);
+
+ outportb(port + 1, data);
+
+ for(unsigned c = 0; c < 35; ++c)
+ inportb(port);
+# endif
+
+# ifdef __WATCOMC__
+ outp(port, addr);
+
+ for(uint16_t c = 0; c < 6; ++c)
+ inp(port);
+
+ outp(port + 1, data);
+
+ for(uint16_t c = 0; c < 35; ++c)
+ inp(port);
+# endif//__WATCOMC__
+}
+
+void DOS_HW_OPL::nativeGenerate(int16_t *frame)
+{
+ frame[0] = 0;
+ frame[1] = 0;
+}
+
+const char *DOS_HW_OPL::emulatorName()
+{
+ return s_devName;
+}
+
+bool DOS_HW_OPL::hasFullPanning()
+{
+ return false;
+}
+
+OPLChipBase::ChipType DOS_HW_OPL::chipType()
+{
+ return s_type;
+}
diff --git a/src/chips/dos_hw_opl.h b/src/chips/dos_hw_opl.h
new file mode 100644
index 0000000..5e3750b
--- /dev/null
+++ b/src/chips/dos_hw_opl.h
@@ -0,0 +1,48 @@
+/*
+ * Interfaces over Yamaha OPL3 (YMF262) chip emulators
+ *
+ * Copyright (c) 2017-2025 Vitaly Novichkov (Wohlstand)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef DOS_HW_OPL_H
+#define DOS_HW_OPL_H
+
+#include "opl_chip_base.h"
+
+class DOS_HW_OPL : public OPLChipBaseT<DOS_HW_OPL>
+{
+public:
+ DOS_HW_OPL();
+ virtual ~DOS_HW_OPL() override;
+
+ static void setChipType(ChipType type);
+ static void setOplAddress(uint16_t address);
+
+ bool canRunAtPcmRate() const override { return false; }
+ void setRate(uint32_t /*rate*/) override {}
+ void reset() override {}
+ void writeReg(uint16_t addr, uint8_t data) override;
+ void nativePreGenerate() override {}
+ void nativePostGenerate() override {}
+ void nativeGenerate(int16_t *frame) override;
+ const char *emulatorName() override;
+ ChipType chipType() override;
+ bool hasFullPanning() override;
+};
+
+#endif // DOS_HW_OPL_H