diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7a9651b12..f71c66fe6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1316,7 +1316,7 @@ void DOSBOX_SetupConfigSections(void) { const char* irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 }; const char* dmasgus[] = { "3", "0", "1", "5", "6", "7", 0 }; const char* dmassb[] = { "1", "5", "0", "3", "6", "7", 0 }; - const char* oplemus[] = { "default", "compat", "fast", "nuked", "mame", "opl2board", 0 }; + const char* oplemus[] = { "default", "compat", "fast", "nuked", "mame", "opl2board","opl3duoboard" ,0 }; const char *qualityno[] = { "0", "1", "2", "3", 0 }; const char* tandys[] = { "auto", "on", "off", 0}; const char* ps1opt[] = { "on", "off", 0}; diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 247c1adbf..7c9501a9c 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -18,5 +18,5 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler snd_pc98/common/parts.c snd_pc98/generic/keydisp.c snd_pc98/sound/adpcmc.c snd_pc98/sound/adpcmg.c \ snd_pc98/sound/rhythmc.c snd_pc98/sound/sound.c snd_pc98/sound/getsnd/getwave.c snd_pc98/sound/getsnd/getsmix.c \ snd_pc98/sound/getsnd/getsnd.c snd_pc98/x11/dosio.c snd_pc98/sound/fmboard.c snd_pc98/sound/soundrom.c \ - snd_pc98/cbus/board86.c snd_pc98/sound/fmtimer.c snd_pc98/cbus/board26k.c 8255.cpp opl2board/opl2board.cpp + snd_pc98/cbus/board86.c snd_pc98/sound/fmtimer.c snd_pc98/cbus/board26k.c 8255.cpp opl2board/opl2board.cpp opl3duoboard/opl3duoboard.cpp diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index dc6277ee6..9b7315fd7 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -34,6 +34,7 @@ #include "mame/fmopl.h" #include "mame/ymf262.h" #include "opl2board/opl2board.h" +#include "opl3duoboard/opl3duoboard.h" #define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz #define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz @@ -384,6 +385,40 @@ namespace OPL2BOARD { }; } +namespace OPL3DUOBOARD { + Opl3DuoBoard opl3DuoBoard; + + struct Handler : public Adlib::Handler { + Handler(const char* port) { + opl3DuoBoard.connect(port); + } + virtual void WriteReg(uint32_t reg, uint8_t val) { + opl3DuoBoard.write(reg, val); + } + virtual uint32_t WriteAddr(uint32_t port, uint8_t val) { + uint32_t reg = val; + + if ((port&3)!=0) { + reg |= 0x100; + } + return reg; + } + + virtual void Generate(MixerChannel* chan, Bitu samples) { + int16_t buf[1] = { 0 }; + chan->AddSamples_m16(1, buf); + } + virtual void Init(Bitu rate) { + opl3DuoBoard.reset(); + } + ~Handler() { + opl3DuoBoard.reset(); + opl3DuoBoard.disconnect(); + } + }; +} + + #define RAW_SIZE 1024 @@ -1098,6 +1133,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) { oplmode = OPL_opl2; handler = new OPL2BOARD::Handler(oplport.c_str()); } + else if (oplemu == "opl3duoboard") { + oplmode = OPL_opl3; + handler = new OPL3DUOBOARD::Handler(oplport.c_str()); + } else if (oplemu == "mame") { if (oplmode == OPL_opl2) { handler = new MAMEOPL2::Handler(); diff --git a/src/hardware/opl3duoboard/opl3duoboard.cpp b/src/hardware/opl3duoboard/opl3duoboard.cpp new file mode 100644 index 000000000..9f10514bd --- /dev/null +++ b/src/hardware/opl3duoboard/opl3duoboard.cpp @@ -0,0 +1,61 @@ +#include "../serialport/libserial.h" +#include "setup.h" +#include "opl3duoboard.h" + +Opl3DuoBoard::Opl3DuoBoard() { +} + +void Opl3DuoBoard::connect(const char* port) { + printf("OPL3 Duo! Board: Connecting to port %s... \n", port); + + comport = 0; + if (SERIAL_open(port, &comport)) { + SERIAL_setCommParameters(comport, 115200, 'n', SERIAL_1STOP, 8); + printf("OK\n"); + } else { + printf("FAIL\n"); + } +} + +void Opl3DuoBoard::disconnect() { + #if OPL3_DUO_BOARD_DEBUG + printf("OPL3 Duo! Board: Disconnect\n"); + #endif + + if (comport) { + SERIAL_close(comport); + } +} + +void Opl3DuoBoard::reset() { + #if OPL3_DUO_BOARD_DEBUG + printf("OPL3 Duo! Board: Reset\n"); + #endif + + for (uint8_t i = 0x00; i < 0xFF; i++) { + if (i >= 0x40 && i <= 0x55) { + // Set channel volumes to minimum. + write(i, 0x3F); + } else { + write(i, 0x00); + } + } +} + +void Opl3DuoBoard::write(uint32_t reg, uint8_t val) { + if (comport) { + #if OPL3_DUO_BOARD_DEBUG + printf("OPL3 Duo! Board: Write %d --> %d\n", val, reg); + #endif + + uint8_t sendBuffer[3]; + + sendBuffer[0] = (reg >> 6) | 0x80; + sendBuffer[1] = ((reg & 0x3f) << 1) | (val >> 7); + sendBuffer[2] = (val & 0x7f); + + SERIAL_sendchar(comport, sendBuffer[0]); + SERIAL_sendchar(comport, sendBuffer[1]); + SERIAL_sendchar(comport, sendBuffer[2]); + } +} \ No newline at end of file diff --git a/src/hardware/opl3duoboard/opl3duoboard.h b/src/hardware/opl3duoboard/opl3duoboard.h new file mode 100644 index 000000000..23c014253 --- /dev/null +++ b/src/hardware/opl3duoboard/opl3duoboard.h @@ -0,0 +1,20 @@ +#include "../serialport/libserial.h" + +#ifndef OPL3_DUO_BOARD + #define OPL3_DUO_BOARD + + // Output debug information to the DosBox console if set to 1 + #define OPL3_DUO_BOARD_DEBUG 0 + + class Opl3DuoBoard { + public: + Opl3DuoBoard(); + void connect(const char* port); + void disconnect(); + void reset(); + void write(uint32_t reg, uint8_t val); + + private: + COMPORT comport; + }; +#endif \ No newline at end of file diff --git a/vs2015/dosbox-x.vcxproj b/vs2015/dosbox-x.vcxproj index 9f4c2d100..a5cdd7523 100644 --- a/vs2015/dosbox-x.vcxproj +++ b/vs2015/dosbox-x.vcxproj @@ -1215,6 +1215,7 @@ copy "$(SolutionDir)\..\contrib\windows\shaders\*.*" "$(OutputPath)\shaders\" + diff --git a/vs2015/dosbox-x.vcxproj.filters b/vs2015/dosbox-x.vcxproj.filters index 3af31d1d9..a0e93b9dc 100644 --- a/vs2015/dosbox-x.vcxproj.filters +++ b/vs2015/dosbox-x.vcxproj.filters @@ -1028,6 +1028,8 @@ Sources\hardware + + Sources\hardware Sources\libs\mt32 @@ -2317,6 +2319,8 @@ Sources\hardware + + Sources\hardware Sources\libs\mt32