diff --git a/CREDITS.md b/CREDITS.md index 720c55d52..25161a78b 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -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 diff --git a/include/hardware.h b/include/hardware.h index ed5e588ae..3b189bad7 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -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 // 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 diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index bd1f9bb79..d2d3e3c2d 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -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 diff --git a/src/hardware/hardopl.cpp b/src/hardware/hardopl.cpp old mode 100644 new mode 100755 index 03f804501..511fd7559 --- a/src/hardware/hardopl.cpp +++ b/src/hardware/hardopl.cpp @@ -1,179 +1,118 @@ -#include "config.h" -//#include "../libs/porttalk/porttalk.h" +#include "hardopl.h" + +#if HAS_HARDOPL +#if defined LINUX || defined BSD +#include +#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 - -#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 diff --git a/src/hardware/hardopl.h b/src/hardware/hardopl.h new file mode 100644 index 000000000..743a048a1 --- /dev/null +++ b/src/hardware/hardopl.h @@ -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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 8fc31408a..f94d46c7f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -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.leftGet_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; diff --git a/vs/dosbox-x.vcxproj b/vs/dosbox-x.vcxproj index 4b354f2b7..8e5a68432 100644 --- a/vs/dosbox-x.vcxproj +++ b/vs/dosbox-x.vcxproj @@ -1796,6 +1796,7 @@ for /d %%i in ($(SolutionDir)\..\contrib\translations\*) do copy %%i\*.lng "$(Ou + diff --git a/vs/dosbox-x.vcxproj.filters b/vs/dosbox-x.vcxproj.filters index 0c7dfd57e..2d56cee55 100644 --- a/vs/dosbox-x.vcxproj.filters +++ b/vs/dosbox-x.vcxproj.filters @@ -1730,6 +1730,9 @@ Sources\hardware + + Sources\hardware + Sources\hardware