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,7 +2,7 @@ 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
@ -26,5 +26,3 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
RetroWaveLib/Protocol/Serial.c \
RetroWaveLib/RetroWave_DOSBoX.cpp \
RetroWaveLib/RetroWave.c

187
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 ;
#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;
}
#endif
/* 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.");
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(!initPorttalk()) {
#ifdef WIN32
LOG_MSG("OPL passthrough: Porttalk not loaded. Aborting.");
#endif
#ifdef LINUX
LOG_MSG("OPL passthrough: permission denied. Aborting.");
#endif
if(!initPassthroughIO()) {
LOG_MSG("OPL pass-through: Pass-through I/O disabled."); // initPassthroughIO() itself prints why it fails
return;
}
*/
hardopldiff=hardwareaddr-blasteraddr;
hwopl_dirty=true;
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);
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) {
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);
@ -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;
@ -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");

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>