Removed last references to PortTalk.

- Made hardopl.cpp use libpassthroughio, so it can now work for all platforms supported by libpassthroughio.
- Moved prototypes of interface from sblaster.cpp to new header hardopl.h.
- Made hardopl.cpp compile cleanly with Visual Studio 2019.
- Kept the functionality disabled, because I do not have access to the necessary hardware. The pass-through functionality itself has been successfully tested on Windows 10 and Linux 5.15. It can be enabled with a 1 character change to hardopl.h.
 + If it is to be officially enabled, we need a slightly more sophisticated handling of privileges on UNIX. No problem, but I will not touch that code unless OPL pass-through is actually desired. For now, either run as root (through sudo) or disable the call to dropPrivileges() in parport.cpp when running setuid root if OPL pass-through is desired.
This commit is contained in:
dbjh 2023-05-03 05:24:32 +09:00
parent 7510ed31fd
commit a71df02e8e
8 changed files with 145 additions and 181 deletions

View File

@ -72,8 +72,6 @@ FluidSynth synthesizer (Tom Moebert; GPLv2+) src/libs/fluidsynth/.c src/libs/flu
Framework-agnostic GUI toolkit (Jorg Walter; GPLv3+) src/libs/gui_tk/.cpp src/libs/gui_tk/.h
Porttalk library, to read/write I/O ports directly (Unknown source) src/libs/porttalk/.cpp src/libs/porttalk/.h
FLAC, MP3, WAV, and Vorbis libraries (David Reid, Kevin Croft, et al; GPLv2+) src/libs/decoders/mp3*.cpp src/libs/decoders/.c src/libs/decoders/.h
FreeDOS utilities as binary blobs (FreeDOS; no license) src/builtin/*.cpp

View File

@ -16,9 +16,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#ifndef DOSBOX_HARDWARE_H
#define DOSBOX_HARDWARE_H
#include <stdio.h> // for FILE*, for OpenCaptureFile()
class Section;
enum OPL_Mode {
@ -53,5 +53,3 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags,
void CAPTURE_AddMidi(bool sysex, Bitu len, uint8_t * data);
void CAPTURE_VideoStart();
void CAPTURE_VideoStop();
#endif

View File

@ -2,13 +2,13 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/aviwriter -I$(top_srcd
SUBDIRS = serialport parport reSID mame
EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h pci_devices.h voodoo_types.h voodoo_def.h voodoo_data.h \
EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h hardopl.h pci_devices.h voodoo_types.h voodoo_def.h voodoo_data.h \
voodoo_interface.h voodoo_emu.h voodoo_vogl.h voodoo_opengl.h
noinst_LIBRARIES = libhardware.a
libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \
memory.cpp mixer.cpp pcspeaker.cpp pci_bus.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
memory.cpp mixer.cpp pcspeaker.cpp pci_bus.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \
vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \
cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp ne2000.cpp hardopl.cpp dbopl.cpp innova.cpp dongle.cpp \
@ -19,12 +19,10 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
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/cbus/pcm86io.c snd_pc98/sound/fmtimer.c snd_pc98/cbus/board26k.c 8255.cpp opl2board/opl2board.cpp opl3duoboard/opl3duoboard.cpp \
RetroWaveLib/Board/OPL3.c \
RetroWaveLib/Platform/Win32_SerialPort.c \
RetroWaveLib/Platform/POSIX_SerialPort.c \
RetroWaveLib/Platform/Linux_SPI.c \
RetroWaveLib/Protocol/Serial.c \
RetroWaveLib/RetroWave_DOSBoX.cpp \
RetroWaveLib/RetroWave.c
RetroWaveLib/Board/OPL3.c \
RetroWaveLib/Platform/Win32_SerialPort.c \
RetroWaveLib/Platform/POSIX_SerialPort.c \
RetroWaveLib/Platform/Linux_SPI.c \
RetroWaveLib/Protocol/Serial.c \
RetroWaveLib/RetroWave_DOSBoX.cpp \
RetroWaveLib/RetroWave.c

205
src/hardware/hardopl.cpp Normal file → Executable file
View File

@ -1,179 +1,118 @@
#include "config.h"
//#include "../libs/porttalk/porttalk.h"
#include "hardopl.h"
#if HAS_HARDOPL
#if defined LINUX || defined BSD
#include <unistd.h>
#endif
#include "libs/passthroughio/passthroughio.h"
#include "hardware.h"
#include "inout.h"
#include "logging.h"
#include "pic.h"
#include "hardware.h"
#if defined (WIN32)
#include "windows.h"
#endif
#include <stdio.h>
#if defined (WIN32) && 0 //|| defined (LINUX)
/* prototype (function typedef) for DLL function Inp32: */
typedef short (_stdcall *inpfuncPtr)(short portaddr);
typedef void (_stdcall *oupfuncPtr)(short portaddr, short datum);
/* After successful initialization, these 2 variables
will contain function pointers.
*/
extern inpfuncPtr inp32fp;
extern oupfuncPtr oup32fp;
/* Wrapper functions for the function pointers
- call these functions to perform I/O.
*/
extern short Inp32 (short portaddr);
extern void Out32 (short portaddr, short datum);
static int16_t hardopldiff;
static bool isCMS;
static FILE * logfp = NULL;
static FILE* logfp = NULL;
static bool hwopl_dirty = false;
static IO_ReadHandleObject* hwOPL_ReadHandler[16];
static IO_WriteHandleObject* hwOPL_WriteHandler[16];
static const uint16_t oplports[] = {
0x0,0x1,0x2,0x3,0x8,0x9,
0x388,0x389,0x38A,0x38B
};
static void write_hwio(Bitu port,Bitu val,Bitu /*iolen*/) {
if(port<0x388) port += hardopldiff;
//LOG_MSG("write port %x",port);
//outportb(port, val);
Out32(port, val);
// LOG_MSG("write port %x",(unsigned)port);
outportb((uint16_t)port, (uint8_t)val);
}
static Bitu read_hwio(Bitu port,Bitu /*iolen*/) {
if(port<0x388) port += hardopldiff;
//LOG_MSG("read port %x",port);
//Bitu retval = inportb(port);
Bitu retval = Inp32(port);
// LOG_MSG("read port %x",(unsigned)port);
Bitu retval = inportb((uint16_t)port);
return retval;
}
// handlers for Gameblaster passthrough
// handlers for Gameblaster pass-through
static void write_hwcmsio(Bitu port,Bitu val,Bitu /*iolen*/) {
if(logfp) fprintf(logfp,"%4.3f w % 3x % 2x\r\n",PIC_FullIndex(),port,val);
//outportb(port + hardopldiff, val);
Out32(port + hardopldiff, val);
if(logfp) fprintf(logfp,"%4.3f w %3x %2x\r\n",(double)PIC_FullIndex(),(unsigned)port,(unsigned)val);
outportb((uint16_t)port + hardopldiff, (uint8_t)val);
}
static Bitu read_hwcmsio(Bitu port,Bitu /*iolen*/) {
//Bitu retval = inportb(port + hardopldiff);
Bitu retval = Inp32(port + hardopldiff);
if(logfp) fprintf(logfp,"%4.3f r\t\t% 3x % 2x\r\n",PIC_FullIndex(),port,retval);
Bitu retval = inportb((uint16_t)port + hardopldiff);
if(logfp) fprintf(logfp,"%4.3f r\t\t%3x %2x\r\n",(double)PIC_FullIndex(),(unsigned)port,(unsigned)retval);
return retval;
}
bool hwopl_dirty=false;
static IO_ReadHandleObject* hwOPL_ReadHandler[16] ;
static IO_WriteHandleObject* hwOPL_WriteHandler[16];
const uint16_t oplports[]={
0x0,0x1,0x2,0x3,0x8,0x9,
0x388,0x389,0x38A,0x38B};
void HARDOPL_Init(Bitu hardwareaddr, Bitu blasteraddr, bool isCMSp) {
isCMS = isCMSp;
int err=0;
HINSTANCE hLib;
short x;
int i;
/* Load the library for win 64 driver */
hLib = LoadLibrary("inpout32.dll");
if (hLib == NULL) {
LOG_MSG("LoadLibrary Failed.\n");
return ;
}
/* get the address of the function */
inp32fp = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
if (inp32fp == NULL) {
LOG_MSG("GetProcAddress for Inp32 Failed.\n");
return ;
}
oup32fp = (oupfuncPtr) GetProcAddress(hLib, "Out32");
if (oup32fp == NULL) {
LOG_MSG("GetProcAddress for Oup32 Failed.\n");
return ;
}
/*
if(!(hardwareaddr==0x210 || hardwareaddr==0x220 || hardwareaddr==0x230 ||
hardwareaddr==0x240 || hardwareaddr==0x250 || hardwareaddr==0x260 ||
hardwareaddr==0x280)) {
LOG_MSG("OPL passthrough: Invalid hardware base address. Aborting.");
return;
}
if(!initPorttalk()) {
#ifdef WIN32
LOG_MSG("OPL passthrough: Porttalk not loaded. Aborting.");
#endif
#ifdef LINUX
LOG_MSG("OPL passthrough: permission denied. Aborting.");
#endif
#if defined BSD || defined LINUX
// Make sure that privileges have not been dropped with a previous call to
// dropPrivileges(). You may have to disabled the call in parport.cpp.
if(geteuid() != (uid_t)0) {
LOG_MSG("OPL pass-through: Raw I/O requires root privileges. Pass-through I/O disabled.");
return;
}
*/
hardopldiff=hardwareaddr-blasteraddr;
hwopl_dirty=true;
#endif
if(!(hardwareaddr == 0x210 || hardwareaddr == 0x220 || hardwareaddr == 0x230 ||
hardwareaddr == 0x240 || hardwareaddr == 0x250 || hardwareaddr == 0x260 ||
hardwareaddr == 0x280)) {
LOG_MSG("OPL pass-through: Invalid hardware base address (0x%hx). Pass-through I/O disabled.",(unsigned short)hardwareaddr);
return;
}
if(!initPassthroughIO()) {
LOG_MSG("OPL pass-through: Pass-through I/O disabled."); // initPassthroughIO() itself prints why it fails
return;
}
hardopldiff = (uint16_t)(hardwareaddr - blasteraddr);
hwopl_dirty = true;
// map the port
LOG_MSG("Port mappings hardware -> DOSBox-X:");
LOG_MSG("OPL pass-through: Port mappings hardware -> DOSBox-X:");
if(isCMS) {
logfp=OpenCaptureFile("Portlog",".portlog.txt");
hwOPL_ReadHandler[0]=new IO_ReadHandleObject();
hwOPL_WriteHandler[0]=new IO_WriteHandleObject();
logfp = OpenCaptureFile("Portlog", ".portlog.txt");
hwOPL_ReadHandler[0] = new IO_ReadHandleObject();
hwOPL_WriteHandler[0] = new IO_WriteHandleObject();
hwOPL_ReadHandler[0]->Install(blasteraddr, read_hwcmsio, IO_MB, 16);
hwOPL_WriteHandler[0]->Install(blasteraddr, write_hwcmsio, IO_MB, 16);
//for(int i = 0; i < 0x10; i++) {
// addIOPermission(hardwareaddr+i);
//}
LOG_MSG("%x-%x -> %x-%x",hardwareaddr,hardwareaddr+15,blasteraddr,blasteraddr+15);
LOG_MSG("%x-%x -> %x-%x",(unsigned)hardwareaddr,(unsigned)hardwareaddr + 15,
(unsigned)blasteraddr,(unsigned)blasteraddr + 15);
} else {
for(int i = 0; i < 10; i++) {
hwOPL_ReadHandler[i]=new IO_ReadHandleObject();
hwOPL_WriteHandler[i]=new IO_WriteHandleObject();
uint16_t port=oplports[i];
if(i<6) port+=blasteraddr;
hwOPL_ReadHandler[i]->Install(port,read_hwio,IO_MB);
hwOPL_WriteHandler[i]->Install(port,write_hwio,IO_MB);
for(int i = 0; i < 10; i++) {
hwOPL_ReadHandler[i] = new IO_ReadHandleObject();
hwOPL_WriteHandler[i] = new IO_WriteHandleObject();
uint16_t port = oplports[i];
if(i < 6) port += (uint16_t)blasteraddr;
hwOPL_ReadHandler[i]->Install(port, read_hwio, IO_MB);
hwOPL_WriteHandler[i]->Install(port, write_hwio, IO_MB);
if(i<6) port+=hardopldiff;
LOG_MSG("%x -> %x",port,i<6?port-hardopldiff:port);
//addIOPermission(port);
if(i < 6) port += hardopldiff;
LOG_MSG("%x -> %x",(unsigned)port,i < 6 ? (unsigned)port - hardopldiff : (unsigned)port);
}
}
//setPermissionList();
}
void HWOPL_Cleanup() {
if(logfp) fclose(logfp);
if(hwopl_dirty) {
for(int i = 0; i < 10; i++) {
delete hwOPL_ReadHandler[i];
delete hwOPL_WriteHandler[i];
if(logfp) fclose(logfp);
if(isCMS) {
delete hwOPL_ReadHandler[0];
delete hwOPL_WriteHandler[0];
} else {
for(int i = 0; i < 10; i++) {
delete hwOPL_ReadHandler[i];
delete hwOPL_WriteHandler[i];
}
}
hwopl_dirty=false;
hwopl_dirty = false;
}
}
#else
void HWOPL_Cleanup() {}
void HARDOPL_Init(Bitu hardwareaddr, Bitu blasteraddr, bool isCMSp) {
(void)hardwareaddr;//UNUSED
(void)blasteraddr;//UNUSED
(void)isCMSp;//UNUSED
LOG_MSG("OPL passthrough is not supported on this operating system.");
}
#endif
#endif // HAS_HARDOPL

16
src/hardware/hardopl.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "config.h"
// NOTE: In order to make the code work on Linux and the BSDs, disable the call to dropPrivileges() in parport.cpp.
#if 0 && /* Replace the 0 with 1 in order to enable the OPL pass-through code. */ \
(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64) && \
(defined _WIN32 || defined BSD || defined LINUX || defined __CYGWIN__) // _WIN32 is not defined by default on Cygwin
#define HAS_HARDOPL 1
extern void HARDOPL_Init(Bitu hardwareaddr, Bitu sbbase, bool isCMS);
extern void HWOPL_Cleanup();
#else
#define HAS_HARDOPL 0
#endif

View File

@ -66,6 +66,7 @@
#include "setup.h"
#include "support.h"
#include "shell.h"
#include "hardopl.h"
using namespace std;
void MIDI_RawOutByte(uint8_t data);
@ -998,7 +999,7 @@ static void DMA_DAC_Event(Bitu val) {
if (!sb.single_sample_dma) {
// WARNING: This assumes Sound Blaster Pro emulation!
LOG(LOG_SB,LOG_NORMAL)("Goldplay mode unexpectedly switched off, normal DMA playback follows");
LOG(LOG_SB,LOG_NORMAL)("Goldplay mode unexpectedly switched off, normal DMA playback follows");
sb.dma_dac_mode = 0;
sb.dma_dac_srcrate = sb.freq / (sb.mixer.stereo ? 2 : 1);
sb.chan->SetFreq(sb.dma_dac_srcrate);
@ -1093,7 +1094,7 @@ static void CheckDMAEnd(void) {
LOG(LOG_SB,LOG_NORMAL)("Silent DMA Transfer scheduling IRQ in %.3f milliseconds",delay);
} else if (sb.dma.left<sb.dma.min) {
float delay=(sb.dma.left*1000.0f)/sb.dma.rate;
LOG(LOG_SB,LOG_NORMAL)("Short transfer scheduling IRQ in %.3f milliseconds",delay);
LOG(LOG_SB,LOG_NORMAL)("Short transfer scheduling IRQ in %.3f milliseconds",delay);
PIC_AddEvent(END_DMA_Event,delay,sb.dma.left);
}
}
@ -1123,7 +1124,7 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo,bool dontInit
* The way the hacked DMA mode works, is that the Sound Blaster is told the transfer
* length is 65536 or some other large value. Then, the DMA controller is programmed
* to point at a specific byte (or two bytes for stereo) and the counter value for
* that DMA channel is set to 0 (or 1 for stereo). This means that as the Sound Blaster
* that DMA channel is set to 0 (or 1 for stereo). This means that as the Sound Blaster
* fetches bytes to play, the DMA controller ends up sending the same byte value
* over and over again. However, the demo has the timer running at the desired sample
* rate (IRQ 0) and the interrupt routine is modifying the byte to reflect the latest
@ -1136,7 +1137,7 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo,bool dontInit
* The problem here in DOSBox is that the DMA block-transfer code here is not precise
* enough to handle that properly. When you run such a program in DOSBox 0.74 and
* earlier, you get a low-frequency digital "rumble" that kinda-sorta sounds like
* what the demo is playing (the same byte value repeated over and over again,
* what the demo is playing (the same byte value repeated over and over again,
* remember?). The only way to properly render such output, is to read the memory
* value at the sample rate and buffer it for output.
*
@ -2538,7 +2539,7 @@ static void DSP_DoWrite(uint8_t val) {
sb.dsp.cmd=val;
if (sb.type == SBT_16)
sb.dsp.cmd_len=DSP_cmd_len_sb16[val];
else if (sb.ess_type != ESS_NONE)
else if (sb.ess_type != ESS_NONE)
sb.dsp.cmd_len=DSP_cmd_len_ess[val];
else if (sb.reveal_sc_type != RSC_NONE)
sb.dsp.cmd_len=DSP_cmd_len_sc400[val];
@ -3104,7 +3105,7 @@ static uint8_t CTMIXER_Read(void) {
return ret;
case 0x82: /* IRQ Status */
return (sb.irq.pending_8bit ? 0x1 : 0) |
(sb.irq.pending_16bit ? 0x2 : 0) |
(sb.irq.pending_16bit ? 0x2 : 0) |
((sb.type == SBT_16) ? 0x20 : 0);
default:
if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */
@ -3191,7 +3192,7 @@ static Bitu read_sb(Bitu port,Bitu /*iolen*/) {
return busy ? 0xAA : 0x2A; /* observed return values on SB 2.0---any significance? */
else
return busy ? 0xFF : 0x7F; /* normal return values */
}
case DSP_S_RESET:
case DSP_S_RESET_WAIT:
@ -3563,7 +3564,6 @@ class ViBRA_PnP : public ISAPnPDevice {
};
bool JOYSTICK_IsEnabled(Bitu which);
extern void HARDOPL_Init(Bitu hardwareaddr, Bitu sbbase, bool isCMS);
std::string GetSBtype() {
switch (sb.type) {
@ -3859,8 +3859,9 @@ public:
sb.mixer.stereo=true;
}
#if HAS_HARDOPL
bool isCMSpassthrough = false;
#endif
switch (oplmode) {
case OPL_none:
if (!IS_PC98_ARCH)
@ -3877,17 +3878,25 @@ public:
// fall-through
case OPL_dualopl2:
assert(!IS_PC98_ARCH);
// fall-through
case OPL_opl3:
case OPL_opl3gold:
OPL_Init(section,oplmode);
break;
case OPL_hardwareCMS:
assert(!IS_PC98_ARCH);
#if HAS_HARDOPL
isCMSpassthrough = true;
#endif
// fall-through
case OPL_hardware:
assert(!IS_PC98_ARCH);
#if HAS_HARDOPL
Bitu base = (unsigned int)section->Get_hex("hardwarebase");
HARDOPL_Init(base, sb.hw.base, isCMSpassthrough);
#else
LOG_MSG("OPL pass-through is disabled. It may not be supported on this operating system.");
#endif
break;
}
if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
@ -4084,23 +4093,23 @@ public:
/* Reference: Command 0xF9 result map taken from Sound Blaster 16 with DSP 4.4 and ASP chip version ID 0x10:
*
* ASP> F9 result map:
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 07
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: f9 00 00 00 00 aa 96 00 00 00 00 00 00 00 00 00
30: f9 00 00 00 00 00 00 38 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 19 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ASP>
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 07
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: f9 00 00 00 00 aa 96 00 00 00 00 00 00 00 00 00
30: f9 00 00 00 00 00 00 38 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 19 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ASP>
* End reference */
memset(sb16_8051_mem,0x00,256);
sb16_8051_mem[0x0E] = 0xFF;
@ -4148,7 +4157,7 @@ ASP>
autoexecline.Install(temp.str());
}
}
~SBLASTER() {
switch (oplmode) {
case OPL_none:
@ -4172,8 +4181,6 @@ ASP>
}
}; //End of SBLASTER class
extern void HWOPL_Cleanup();
static SBLASTER* test = NULL;
void SBLASTER_DOS_Shutdown() {
@ -4185,7 +4192,9 @@ void SBLASTER_ShutDown(Section* /*sec*/) {
delete test;
test = NULL;
}
#if HAS_HARDOPL
HWOPL_Cleanup();
#endif
}
void SBLASTER_OnReset(Section *sec) {
@ -4196,7 +4205,9 @@ void SBLASTER_OnReset(Section *sec) {
delete test;
test = NULL;
}
#if HAS_HARDOPL
HWOPL_Cleanup();
#endif
if (test == NULL) {
LOG(LOG_MISC,LOG_DEBUG)("Allocating Sound Blaster emulation");
@ -4247,7 +4258,7 @@ void POD_Save_Sblaster( std::ostream& stream )
WRITE_POD( &pod_name, pod_name );
//*******************************************
//*******************************************
@ -4309,7 +4320,7 @@ void POD_Load_Sblaster( std::istream& stream )
uint8_t dma_idx;
MixerChannel *mixer_old;
// save static ptr
mixer_old = sb.chan;

View File

@ -1796,6 +1796,7 @@ for /d %%i in ($(SolutionDir)\..\contrib\translations\*) do copy %%i\*.lng "$(Ou
<ClInclude Include="..\src\gui\render_templates_sai.h" />
<ClInclude Include="..\src\hardware\adlib.h" />
<ClInclude Include="..\src\hardware\dbopl.h" />
<ClInclude Include="..\src\hardware\hardopl.h" />
<ClInclude Include="..\src\hardware\mame\emu.h" />
<ClInclude Include="..\src\hardware\mame\fmopl.h" />
<ClInclude Include="..\src\hardware\mame\saa1099.h" />

View File

@ -1730,6 +1730,9 @@
<ClInclude Include="..\src\hardware\dbopl.h">
<Filter>Sources\hardware</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\hardopl.h">
<Filter>Sources\hardware</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\nukedopl.h">
<Filter>Sources\hardware</Filter>
</ClInclude>