VOGONS

Common searches


First post, by TheLazy1

User metadata
Rank Member
Rank
Member

The googles do nothing, has anyone else gotten the megabuild OPL passthrough to work under linux?

lsmod:

Module Size Used by snd_seq_midi 3120 0 snd_opl3_synth 7522 0 snd_seq_midi_emul […]
Show full quote

Module Size Used by
snd_seq_midi 3120 0
snd_opl3_synth 7522 0
snd_seq_midi_emul 3313 1 snd_opl3_synth
snd_es1938 11463 0
snd_opl3_lib 5598 2 snd_opl3_synth,snd_es1938
snd_hwdep 3742 1 snd_opl3_lib
snd_mpu401_uart 3647 1 snd_es1938
snd_rawmidi 11288 2 snd_seq_midi,snd_mpu401_uart
ath5k 111470 0
intel_agp 19476 1
rtc_cmos 6157 0
rtc_core 8173 1 rtc_cmos
ath 6068 1 ath5k
led_class 1495 1 ath5k
rtc_lib 1198 1 rtc_core
agpgart 17825 1 intel_agp

dosbox output:

DOSBox version SVN Copyright 2002-2010 DOSBox Team, published under GNU GPL. --- SVN build compiled on Feb 25 2011 - http://home […]
Show full quote

DOSBox version SVN
Copyright 2002-2010 DOSBox Team, published under GNU GPL.
---
SVN build compiled on Feb 25 2011 - http://home.arcor.de/h-a-l-9000
featuring:
Try not to exit on unsupported fullscreen mode
\a bell support
Paging patch - Later Win9x becomes more stable
Reduced CPU usage when idling in command line
Timer and interrupt latency patch, fixes certain games
Add the 'IMGMAKE' command (creates disk images)
Make vgaonly features availible to other graphics cards - see [render]
Free choice wether 9-pixel wide characters should be used
Add DATE and TIME commands, midnight overflow, and host time synchronization
NE2000 Ethernet passthrough
OPL chip passthrough
Parallel Port passthrough and Virtual Printer patch, logging enabled
Parallel Port data redircetion to file/device
Add restart capability, Win95 can shutdown DOSBox through APM
Serial logging capability enabled
Increase maximum resolution to 1600x1200, add lot's of highres VESA modes
Add back selection of video memory size - up to 8MB = 1600x1200@32bpp
EGA / SVGA_S3 compatibility, enable LDGFXROM
CGA video memory slowdown
DOSBox can load while the splash screen displays
FILES= adjustable by Kippesoep
Restart capability - ctrl+alt+POS1 or config -r [params] or FJMP F000:FFF0
---
CONFIG:Loading primary settings from config file /root/.dosbox/dosbox-SVN.conf
ALSA:Client initialised [17:0]
MIDI:Opened device:alsa
Port mappings hardware -> DOSBox:
220 -> 220
221 -> 221
222 -> 222
223 -> 223
228 -> 228
229 -> 229
388 -> 388
389 -> 389
38a -> 38a
38b -> 38b

I'm running it as root (I know, I know) because the OPL passthrough errors out as a user.
Here, it seems to say it's going to work but wolf3d does not detect any adlib hardware.

Update:
Sound appears to be completely gone after setting the opl to hwopl.
Wolf3d will detect nothing if hwopl mode is set, works fine if left default.

Update 2:
It appears that reading from the port 0x388 will always return 0xFF.

Reply 3 of 11, by TheLazy1

User metadata
Rank Member
Rank
Member
00:08.0 Multimedia audio controller: ESS Technology ES1969 Solo-1 Audiodrive (rev 02) Subsystem: ESS Technology Device 8 […]
Show full quote

00:08.0 Multimedia audio controller: ESS Technology ES1969 Solo-1 Audiodrive (rev 02)
Subsystem: ESS Technology Device 8898
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32 (500ns min, 6000ns max)
Interrupt: pin A routed to IRQ 5
Region 0: I/O ports at 7000
Region 1: I/O ports at 7080
Region 2: I/O ports at 70c0
Region 3: I/O ports at 7400
Region 4: I/O ports at 7440
Capabilities: [c0] Power Management version 1
Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: ESS ES1938 (Solo-1)
Kernel modules: snd-es1938

Well, there's the problem - and another one as well.
ioperm() Can only allow up to 0x3FF, so either iopl() or a kernel module is required.

Any thoughts?

Reply 5 of 11, by TheLazy1

User metadata
Rank Member
Rank
Member

Interesting stuff, I haven't really done any linux programming but it doesn't look to be a simple job.
I'm going to try a few things and see if I can talk to the OPL hardware outside of dosbox using /dev/port.

[Edit]
May not be possible this way either.
🙁

Reply 6 of 11, by TheLazy1

User metadata
Rank Member
Rank
Member

Oddly enough using a YMF-724 ioperm() works because you can map the fm port to 0x388. However, /dev/port does not.
Meanwhile, in the ES1938 audio module:

        /* disable legacy audio */
pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);

It may be there for a reason though.

Reply 7 of 11, by TheLazy1

User metadata
Rank Member
Rank
Member

Maybe some of you can give this quick hack a try:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/io.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#ifdef USE_DEVPORT
static int Portfd = -1;
#endif

void alWrite( int Port, int Register, unsigned char Value ) {
#ifndef USE_DEVPORT
outb( Register, Port );
usleep( 4 );
outb( Value, Port + 1 );
usleep( 24 );
#else
if ( Portfd != -1 ) {
lseek( Portfd, Port, SEEK_SET );
write( Portfd, &Register, 1 );
usleep( 4 );

lseek( Portfd, Port + 1, SEEK_SET );
write( Portfd, &Value, 1 );
usleep( 24 );
}
#endif
}

unsigned char alRead( int Port ) {
unsigned char Value = 0;

#ifndef USE_DEVPORT
Value = inb( Port );
usleep( 4 );
#else
if ( Portfd != -1 ) {
lseek( Portfd, Port, SEEK_SET );
read( Portfd, &Value, 1 );
usleep( 4 );
}
#endif

return Value;
}

int DetectAdlib( int Port ) {
unsigned char R1, R2;

alWrite( Port, 0x04, 0x60 ); // Reset both timers
alWrite( Port, 0x04, 0x80 ); // Enable interrupts
R1 = alRead( Port ); // Read status register

alWrite( Port, 0x02, 0xFF ); // Timer 1
alWrite( Port, 0x04, 0x21 ); // Start timer 1
usleep( 80 ); // Delay for 80us

R2 = alRead( Port ); // Read status register
Show last 57 lines
	alWrite( Port, 0x04, 0x60 );
alWrite( Port, 0x04, 0x80 );

printf( "%X %X\n", R1, R2 );

R1&= 0xE0;
R2&= 0xE0;

return ( R1 == 0x00 && R2 == 0xC0 ) ? 1 : 0;
}

int main( int Argc, char** Argv ) {
int Port = 0;

if ( Argc < 2 ) {
printf( "usage: adlib [port hex]\n" );
return 1;
}

sscanf( Argv[ 1 ], "%x", &Port );

if ( Port < 0 ) {
printf( "Invalid port 0x%X\n", Port );
return 1;
}

#ifndef USE_DEVPORT
if ( ioperm( Port, 2, 1 ) == 0 ) {
printf( "Got io permissions...\n" );

if ( DetectAdlib( Port ) == 0 ) {
printf( "No adlib at 0x%X\n", Port );
} else {
printf( "Found adlib at 0x%X\n", Port );
}
}
#else
Portfd = open( "/dev/port", O_RDWR );

if ( Portfd > 0 ) {
printf( "Opened /dev/port...\n" );

if ( DetectAdlib( Port ) == 0 ) {
printf( "No adlib at 0x%X\n", Port );
} else {
printf( "Found adlib at 0x%X\n", Port );
}

close( Portfd );
} else {
printf( "Failed to open /dev/port.\n" );
}
#endif

return 0;
}

Compile with either -O2 for ioperm mode or -DUSE_DEVPORT for using /dev/port.
Note that this is a quick hack and only tests for one chip, at least here both methods detect at 0x388.

Edit:
This is really, really hacky.
Though maybe /dev/port can allow using the OPL hardware that uses ports beyond what ioperm can give.

Success!
On my laptop the ESFM is located at 0x7080h!

Does the passthrough also handle the SB completely in hardware?
Maybe we need a separate option to only pass through the OPL chip.

Reply 9 of 11, by tauro

User metadata
Rank Member
Rank
Member

Hello people,

I'm trying to accomplish this too. I can't find a DOSBox build that supports hardware OPL under GNU/Linux nor I don't know how to apply any of what is described in this thread.

How could I apply the hack by TheLazy1 to the source code and what should I change?

Thank you in advance.

This is my hardware:

# lspci -vvv

04:01.0 Multimedia audio controller: C-Media Electronics Inc CMI8738/CMI8768 PCI Audio (rev 10)
Subsystem: C-Media Electronics Inc CMI8738/C3DX PCI Audio Device
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32 (500ns min, 6000ns max)
Interrupt: pin A routed to IRQ 19
Region 0: I/O ports at e000 [size=256]
Capabilities: [c0] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: snd_cmipci
Kernel modules: snd_cmipci

$ cat /proc/asound/hwdep
02-00: OPL3 FM
$ pmidi -l
Port Client name Port name
24:0 C-Media CMI8738 C-Media CMI8738 MIDI
25:0 OPL3 FM synth OPL3 FM Port

I can set up and the FM synth correctly with:

$ sbiload -D /dev/snd/hwC2D0 --opl3 std.o3 drums.o3

PS: I don't know if this is the right procedure or if I should create a new thread.

Reply 10 of 11, by tauro

User metadata
Rank Member
Rank
Member

Pretty please.

I already managed to compile the megabuild6 in Ubuntu 16.04 amd64.

I also had to use root to run it, otherwise I got:
OPL passthrough: permission denied. Aborting.

Tried different configs to no avail.

My ports are

snd_cmipci: mpu_port=0x330 fm_port=0x388

Any help would be appreciated!