First post, by aitotat

User metadata
Rank Member

Many of the older General Midi games are hardcoded to use port 330h. It is not a problem if you have only one MIDI device. But if you do have more, wouldn't it be nice if you could choose what device to use?

MIDIto tries to do just that. It uses EMM386 or QEMM to trap ports and redirect data elsewhere, to user defined destination. EMM386 and QEMM have limitations, such as this approach does not work with protected mode games. Fortunately many of them allow to define MIDI port (but not all).

MIDIto can do other things as well. It can add delays for OPL port accesses so OPL2 cards could be used on faster systems. MIDIto can also make your CMS equipped Sound Blaster 1.x and 2.0 cards to be fully Game Blaster compatible when needed. And there is more. MIDIto can lock Sound Blaster Pro and 16 mixer so games cannot mess with volumes and inputs. And last, MIDIto makes Sound Blaster 16/32/AWE Sound Blaster Pro compatible by fixing support for stereo samples in Sound Blaster Pro mode (but are there such games that would not support SB16 as well?).

How to use MIDIto? I tried to make things as simple as possible:

MIDIto TSR - Release 12 - 2022.4.26
(C) 2021-2022 by Tomi Tilli
Released under GNU GPL v2
Uses assembly libraries from XTIDE Universal BIOS and Associated Tools
Copyright (C) 2009-2010 by Tomi Tilli, 2011-2021 by XTIDE Universal BIOS Team.

Redirect MIDI data meant for port 330h to another MIDI device. OPL redirection,
delay and dual OPL emulation for better FM experience. Make SB with CMS fully
Game Blaster compatible. Fix some SB16/32/AWE related DSP issues, like SB Pro
compatibility. Lock SB Pro/16/32/AWE or ESS mixer against unwanted changes.


-midi=a# or /midi=a#: Redirects MIDI from port 330h to port #h
-fm,-fma,-fms,-fm2,-fml,-fmr: OPL port control (delay, redirection and mixer)
-fm=a#_,d*,m%: a# defines destination OPL port, optional _ defines type of
mixer support (L=Line-IN, X=no mixer), optional d* sets OPL write delay and
optional m% sets stereo mix for dual OPL mode. See readme for more info
-fma=off or /fma=off: Adlib - Disable Adlib ports
-cms or /cms: Emulate CT-1302 for full CMS / Game Blaster support
-dsp or /dsp: Fixes for SB16/32/AWE DSP issues
-lock or /lock: Lock SB Pro, SB16 or ESS mixer. See readme for more info
-sb=a# or /sb=a#: a# overrides port set by SET BLASTER environment string
-u or /u: Uninstall - Uninstalls MIDIto TSR from memory
-v or /v: Verbose - Prints extra install or uninstall information

More detailed description about the options

-cms or /cms will place Sound Blaster 1.x and 2.0 to a full Game Blaster
emulation mode. It does all the -a=off parameter does but in addition CT-1302
will be emulated. It is a chip on a Game Blaster that is used to detect the
card (since CMS chips are write only and cannot be detected). Some games will
require CT-1302 for CMS sounds. CT-1302 conflicts with Sound Blaster DSP so
Sound Blaster cannot be accessed when Game Blaster emulation mode is enabled.
Some games also require that the Game Blaster is at port 220h. That is not
necessary anymore since MIDIto will always map the virtual Game Blaster to 220h
even if you have a real Game Blaster on another address. This way you can use
real Game Blaster at any address and use Sound Blaster at port 220h without
loss of game compatibility. If you have CMS capable Sound Blaster and a Game
Blaster on a same system, MIDIto will always prefer real Game Blaster.
One more thing to note is that MIDIto will always trap CMS ports (so it can be
relocated to 220h when necessary). Port trapping will always have some delay.
That is likely a good thing since MIDIto requires a 386 and CMS games are
usually made for slower systems.

Some games will require the GBC-CMS.COM (for Game Blaster) or SBC-CMS.COM
(for Sound Blaster) driver. You must use the GBC-CMS.COM since the Sound
Blaster will be detected as a real Game Blaster.

-dsp or /dsp will provide some fixes for SB16/32/AWE. Fixes at the moment
* Fix Turn On/OFF Speaker commands by setting voice volume to zero when
Turn OFF Speaker command is sent. Volume will be restored by Turn On Speaker
* Force enable FIFO
Show last 308 lines
* Fix 44100, 22050 and 11025 Hz sample rates by converting Time Constant
(SB/SB Pro command 40h) to proper output sampling rate (SB16 command 41h)
* Sound Blaster Pro compatibility for playing stereo samples

-fm, -fma, -fms, -fm2 ,-fml, -fmr: OPL port control for redirecting Adlib
and Sound Blaster FM ports to another address.

Adlib was first PC sound card with OPL2. It has two ports that can be accessed
from 388h and 389h. Basically every Sound Blaster and clones with some
sort of OPL capability also supports those ports for Adlib compatibility.
But Sound Blasters (and compatibles) up to 2.0 also provide access to the same
OPL chip from Sound Blaster address space with ports 2x8h and 2x9h (If your
Sound Blaster is set to 220h, then they are at 228h and 229h). Some games use
Adlib address space even when configured to SB but some games use the SB
OPL2 ports instead. But that is not all, Sound Blaster Pro 1 has two OPL2 chips
and they can be accessed from 2x0h..2x1h and 2x2h..2x3h (those are CMS
addresses on SB 2.0 and older). Sound Blaster Pro 2 and later has one OPL3
chip. It uses 4 ports from 2x0h...2x3h so Creative was able to easily replace
two OPL2s with single OPL3.

So there are three locations in total where single OPL chip can be accessed.
With PnP cards (and Unisound) it is possible to disable Adlib addresses and
leave them enabled only to one card. But MIDIto can remap all three locations
and also emulate dual OPL2 mode if you have two Sound Cards with OPL2 or OPL3.

-fm, -fma, -fms and -fm2 are all used in the same way. The difference is that
-fm traps all three OPL locations to a single destination you specify. -fma
only traps Adlib address space, -fms traps OPL3 and OPL2 locations from Sound
Blaster address space but does not trap Adlib address space. -fm2 traps only
OPL2 locations: Adlib address space and 2x8h...2x9h from Sound Blaster
address space. This leaves OPL3 address space as it is. That makes -fm2 perfect
for using OPL2 card, like Sound Blaster 2.0, with CQM Sound Blasters: OPL2
games will always use the real OPL2 on a SB 2.0 and only the OPL3 games will
use (OPL3 compatible) CQM.

Destination address is specified with =a#####, like -fm=a240. Note the 'A' just
like when using SET BLASTER string in autoexec.bat. But you can also specify
mixer, just add 'L' or 'X' after the destination address. If you don't specify
anything, that means that the destination is Sound Blaster Pro compatible and
FM volume changes will be redirected there (so you must use the SB base port
for the destination address).

For example -fm=a240 would mean there is SB Pro compatible card at address 240h
and you want to use its OPL3 and mixer.
-fm2=a248x would mean that you want to use OPL2 from Sound Blaster at address
240h. Note that we had to use address 248h since 240h...243h would be reserved
for CMS on a Sound Blaster 2.0 and older. You could also use Adlib address:
-fm2=a388x since that would likely be easier. But both do the same thing
assuming you don't have any Adlib conflicts when using multiple cards.

L means Line-IN, for example -fm=a240l. That would mean that you have any OPL3
card at 240h and it is connected to Line-IN on your SET BLASTER card. This way
the OPL3 card does not have to be Sound Blaster Pro compatible. Any FM volume
changes will now be redirected to Line-IN volume. Note that mixer locking
(-lock) is highly recommended since if anything messes with Line-IN volume, it
will also mess FM volume.

By default, the Line-IN mixer mode assumes that the Line-IN is on your SET
BLASTER card (or card overridden by -sb). If your setup is different, then you
need to specify the card with Line-IN. Just append 'A' and port number after
'L'. For example -fm=a240la230. This would mean that OPL at 240h will be used
for FM playback and it is connected to Line-IN on card located at 230h. For
better readability, you can also write -fm=a240 l a230.

But there is more. Especially OPL2 is very speed sensitive but you can have
problems with OPL3 on fast systems as well. You can add ,d##### after
specifying port to specify delay. For example -fm=a240l,d3 would set delay of
3 jumps after writing to OPL data port. You can also specify just 'd', like
-fm=a220,d. If 220h is your SET BLASTER card, then only data ports are trapped
for minimal possible delay.

The delay value is number of jumps for the CPU. Full specified delay is waited
after every write to OPL data port. Delay after writing to index port is one
eight of the specified delay. There are no extra jumps after reading from index

If you want minimal delay (trap Data ports only) to both Adlib and SB address
space, then you have to specify both -fms and -fma parameters. For example:
"-fms=a220,d -fma=a388x,d". Note that it is necessary to specify x to -fma
since there is no mixer at 388h but there is on 220h. But likely in this case
the 388h is simply the Adlib address for the SB pro compatible at 220h. So in
practice any volume change will also affect Adlib volume as well. But if the
388h is some other card, then volume change will not affect it. It is highly
unlikely that it ever matters.

-fma can be specified with 'OFF' instead of destination port. For example
-fma=off will disable Adlib address range. This is useful for games that don't
allow CMS support if Adlib is detected. Also check the -cms flag for even
better CMS/Game Blaster support.

Sound Blaster PRO1 dual OPL2 emulation is specified with -fml and -fmr
parameters. Mixer modes and delays work just the same as written above. But
you should never specify 'X' for mixer since SB Pro games need mixer for
panning effects. -fml specify left OPL2 and -fmr specify right. You only need
one of them if the other is your SET BLASTER card. For example -fmr=a240l will
set right OPL to address 240h and to use Line-IN mixer from your SET BLASTER
card. Left OPL will be your SET BLASTER card.

For dual OPL mode you can specify stereo mix with 'M'. For example
-fmr=a240l,m25 will set 25% stereo mix. You only need to specify stereo mix for
one channel. Highest specified will be used for both. Zero means no stereo mix
(best stereo separation like on real SB Pro 1) and 100 means you will lose
stereo completely (don't use it). Note that Sound Blaster Pro mixer is only
3 bits! This will seriously limit stereo mix. SB16 mixer is 5 bits. You likely
don't have two SB16 compatible cards on the same system but if your SET BLASTER
card is SB16/32/AWE, then you should use Line-IN mixer mode since that will
give you 5 bits for stereo mix volume. If Line-IN mode is not possible for your
setup, you can use SB16 and SBpro but the SB16 will then be limited to SB Pro
mixer only.

Adlib address space is always trapped in dual OPL mode and it will work just
like on a real SB Pro 1: both OPLs will play the same thing, the other goes to
right speaker and the other to the left. MIDIto will also emulate SB Pro 1
FM Control Register (mixer register 06h) to enable/disable those channels when

Note that OPL3 is not available in dual OPL mode. So the dual OPL mode should
only be used for games that actually support two OPLs.

Another important thing in dual OPL mode is to configure FM volumes to be close
to the same on the two cards. Play mono OPL2 games without using stereo mix to
help adjusting the volumes.
If you use Line-IN mixer, MIDIto will copy SET BLASTER
FM volume to Line-IN volume. So you need to adjust FM and/or Master volume from
the other card.
If you direct FM mixer to the other card, MIDIto will copy SET BLASTER cards FM
volume to the other card. So you only have Master volume control on the other
card. But if it is connected to Line-IN, then you can adjust your SET BLASTER
Line-IN. So you don't need to use the Line-IN mixer mode even if you have the
other card connected to Line-IN. You only need to use the Line-IN mixer mode
when the other card does not support SB Pro compatible mixer.

-lock or /lock will lock SB Pro, SB16 and ESS mixer to prevent unwanted
changes. Some games modify volumes and even disables inputs and leaves them
like that after game quits. These modified volumes might even cause clipping so
it affect the audio quality as well. Mixer locking will fix these issues.
By default, Master, MIDI for ESS, CD, Line In, MIC and PC-speaker
(SB16/ESS PC-speaker input) are locked to whatever levels they happen to be
when you start MIDIto. Voice (DAC) is not locked by default since games can
need it for effects (like stereo sound in Wolfenstein 3D). FM is also unlocked
bacause it can be used for effects as well (does any game actually use it?).

MIDIto stores all mixer values during initialization and unlocked mixer values
are restored when game does mixer reset (normally that would restore hardware
defaults) or game exits. MIDIto will also hook interrupt 13h (BIOS disk I/O) so
volumes can be restored for protected mode games when they load data from hard
disk. Normal port trapping method does not work with protected mode games.
Interrupt 13h can be disabled if it causes any issues.

You can customize what is locked with -lock=XX,YY,ZZ. Just separate locks with
commas and you can speficy as many as you need. For example -lock=MA,LI,LPE
would lock MAster volume, LIne in volume and force Low Pass filter Enabled.

Here are all the locks:
DEF Sets all default locks (MA, CD, LI, MIC, SP, MI for ESS)
MA Locks MAster Volume
VO Locks VOice (DAC)
MI Locks MIdi volume (ESS only, for SB Pro / SB16 this is same as FM)
FM Locks FM volume
CD Locks CD volume
LI Locks Line In volume
MIC Locks MICrophone volume
SP Locks pc SPeaker volume (SB16 PC speaker input)
LPE Forces output Low Pass filter Enabled (only on Sound Blaster Pro)
LPD Forces output Low Pass filter Disabled (only on Sound Blaster Pro)
YMF Enables Yamaha YMF71x Master Volume fix
NO13 Does not hook interrupt 13h

Low Pass Filter is not available on Sound Blaster 16/32/AWE cards. It is also
not available on most SB Pro compatibles but some do have it (like YMF71x).

FM and MI are the same for Sound Blaster 16 since that is how it is implemented
on Sound Blaster 16/32/AWE:
FM volume and Waveblaster MIDI shares the same volume control. In some future
release of MIDIto that can be separated. Since games either use MIDI or FM,
it would be possible to set one volume when midi port (defined by SET BLASTER
P3xx) is accessed and switch to other volume level when FM port is accessed.

ESS Audiodrives separate FM and MIDI volumes. The MIDI volume is the volume
from waveblaster daughter board. In ESS documentation this is known as AuxB

YMF enables fix for Yamaha YMF71x based cards. It's unknown if all YMF71x chips
require this fix but some have hardware bug where setting SB Pro master volume
to anything above 1 breaks volume controls. You can't hear stereo sounds on
Wolfenstein 3D for example. YMF-lock locks SB Master volume to 1 and redirects
SB master volume control to master volume available on YMF71x control ports.
This way you can have working volume controls. YMF-lock alone won't lock volume
controls. It justs sets the fix by hiding the problematic real SB master volume
control. If you also want to lock the controls, just specify the locks you want
or use "-lock=YMF, DEF" to set up default locks.

By default the YMF-fix uses control port 370h that is the default. If you have
set the control port to another address, you need to set R### to the end of
SET BLASTER string on autoexec.bat. This is the Unisound way to set the control
port so if you use Unisound to initialize the card, then nothing needs to be
done. For example to set the control port to 380h, make sure SET BLASTER string
contains R380.

-midi=a##### or /midi=a##### enables MIDI redirection from port 330h to #####h.
Note that you need to use the 'A' just line on -fm parameters.

-sb=a# or /sb=a# will override the card selected by SET BLASTER environment
string. This is useful when you have more than one Sound Blaster compatible
cards on your system and SET BLASTER points to a different card than what the
game is configured for. # is the base port for the selected card. For example
-sb=a240 will select Sound Blaster at port 240h.

Version information
Release 12 - 2022.4.26
* Now works with VIDE-CDD.SYS. Previously only modified VIDE-CDD.SYS v2.14a
allowed MIDIto to work.
* -dsp now works properly (was broken in r10 and r11)
* -lock now stores Line-IN volume the same way as MIC volume. Panic demo, and
maybe others, try to write Line-IN volume and then read it back (to check if
mixer is available?).

Release 11 - 2022.4.2
* Mixer reset now properly maintains emulated FM volumes for Line-IN mixer
mode. Note that -lock is still needed to protect Line-IN volume if you
don't use Line-IN mixer mode.
* Added -sb command line parameter to select other than SET BLASTER card
* -fml should now properly work if it points to other than SET BLASTER card
* You can now specify destination card for Line-In mixer mode

Release 10 - 2022.3.30
* You now need to use -midi=a##### command line parameter for specifying
destination MIDI port (##### is the destination port).
* Added FM redirection and Sound Blaster Pro 1 compatible dual OPL emulation.
* Removed -a=##### and /a=##### command line parameters since that
functionality is now part of FM redirection.
* midito.com is now compressed with UPX.

Release 9 - 2022.1.21
* YMF master volume is now restored on exit when using YMF lock
* Voice volume is now properly restored on exit when -dsp is used
* INT 13h handler now restores locked volumes only (unlocked are not restored)
* INT 13h handler restores volumes once per every 64kB of data read

Release 8 - 2021.12.23
* Added INT 13h handler to mixer locking. This allows limited protected mode
support (volumes are restored when reading data from hard disk).
* Added ESS detection (at least for ES18xx models, not sure about ES16xx and
ES17xx) and support for AuxB (MIDI) volume
* Added -dsp command line parameter for SB16/32/AWE DSP fixes (Sound Blaster Pro
support etc.)

Release 7 - 2021.11.23
* Fixed some uninstall error strings that were not correctly displayed
* Added mixer lock to fix Yamaha YMF71x SB Pro Master Volume control
* Fixes mixer locking for Star Trek: Judgment Rites by returning last written
MIC volume so MIC volume appears to be unlocked (but it is really locked).

Release 6 - 2021.11.19
* Optimizations to reduce TSR size, especially for QEMM
* MIDIto now automatically uninstalls if you try to reinstall with new options
* QEMM handler for Adlib delay with extra jumps no longer corrupt AH register.
That was the cause why QEMM was slower than EMM386 on Wolfenstein 3D.
* Added -lock command line parameter for Sound Blaster Pro and 16 mixer locking

Release 5 - 2021.10.20
* Two (instead of four) OPL ports are now trapped from Adlib address 388h
* Added Sound Blaster and Game Blaster detection
* AUTO and NOEMS parameters are now supported for EMM386
* Adlib zero delay now traps only data ports for as little delay as possible
* Specified Adlib delay is now for output only. Full specified delay is for data ports
and index ports will have 1/8 delay. Inputs do not have extra delay.
* Added -cms command line parameter for full Game Blaster emulation to
maximize CMS compatibility

Release 4 - 2021.10.01
* EMM386/QEMM version check now accepts versions with greater major number
but lesser minor number than supported minimum version numbers.
* Adlib delay can now be specified and default value is set to zero. The extra
delay is for Adlib DATA port only. Address/Status port is trapped but
with minimum delay.
* Adlib ports can now be disabled completely

Release 3 - 2021.9.24
* Added support for QEMM 7.03 and later
* Destination MIDI port is now optional
(so it is possible to only trap Adlib ports)

Release 2 - 2021.9.17
* Extended destination port range from 100h-FFEh to 100h-FFFEh

Release 1 - 2021.9.16
* First release

Known issues
* EMM386 cannot be set to OFF (Cannot be fixed. Use AUTO parameter instead)
* -dsp and QEMM combination makes Star Control 2 very slow. Reason unknown.
SC2 Does not support SB Pro so no need to use -dsp anyway.
* -dsp and EMM386 combination can be slow as well but seems a certain crack
causes it. Play uncracked version if possible, or try another crack. But it
is not necessary to use -dsp at all with Star Control 2.
* QEMM seems to use more stack than EMM386. You might need to set STACKS=9,256
to config.sys if there are any crashes etc.
* When using -fm line-in mode: Adjusting line-in volume messes FM volume
emulation. Fix is to use mixer locking (-lock).
* MIDIto displays wrong IRQ and DMA values when using -sb to override
SET BLASTER card. This is not a bug. MIDIto does not use IRQ and DMA so it
just displays default values when they are not read from SET BLASTER.

I took the same approach as mt32-pi control program. When there are no errors, there won't be any text output. Things just work silently. You can use the -v parameter to display what MIDIto tries to do. If you execute MIDIto without parameters or unsupported parameter, you get the instructions displayed above.

MIDIto can be downloaded here. Source codes are included in the zip file.
Old releases can be found here.

Last edited by aitotat on 2022-04-26, 15:58. Edited 12 times in total.

Reply 1 of 64, by Gmlb256

User metadata
Rank l33t

This reminds me of a special version of SoftMPU which does a similar thing with virtual MPU ports and was done by a certain user which I don't want to talk about. Unlike that version though, your software has the source code available. 😀

Nice that you added an AdLib delay option there for people that are nostalgic about using FM synth for MIDI music. 😁

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 3 of 64, by Kamerat

User metadata
Rank Oldbie

Make the mapping range four didgit so it also can map into the PCI I/O range. Some PCI sound cards can have their MPU-401 interface accessed that way without even initializing the card, see the spreadsheet in my signature for sound cards that allow this.

DOS Sound Blaster compatibility: PCI sound cards vs. PCI chipsets
YouTube channel

Reply 4 of 64, by Gmlb256

User metadata
Rank l33t

I've noticed that MIDIto doesn't get loaded if EMM386 has the NOEMS parameter, is EMS required for port-trapping to work? I'm not using just the AUTO parameter.

It would also be interesting to have QEMM support.

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 5 of 64, by aitotat

User metadata
Rank Member

Release 2 now extends port range for PCI cards. I didn't know ports that high would be required but I've avoided PCI cards on DOS so no wonder.

I suppose the NOEMS parameter just can't be used then. EMM386 should be better documented. EMS memory does not have anything to do with port trapping but maybe port trapping functionality is just internally part of the EMS code or something. EMM386 can be strange. If you use the AUTO parameter and try to trap ports it will fail. But if you do mem /c /p (or likely mem without parameters is enough) and try port trapping again then it will work. It took me a lot of time to figure out why port trapping didn't work at the beginning.

I don't use QEMM myself but I'll see what I can do.

Reply 7 of 64, by Gmlb256

User metadata
Rank l33t

Thanks for the QEMM support!

Edit: MIDIto refuses to install with QEMM 97 (v9.00). The verbose says it's "too old" which isn't.

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 8 of 64, by aitotat

User metadata
Rank Member

I didn't see that edit until now but I already found the bug. Now the version check should work properly.

Release 4 adds a new feature: It is now possible to disable Adlib ports completely. Idea is to force CMS support for games that do now allow it if Adlib is found. However, only Adlib-ports are disabled. Next version will also trap FM ports from Sound Blaster address space.

Adlib delay value can now be adjusted and it is zero by default. Zero means only the delay caused by port trapping itself. However I think I should improve it by trapping only Adlib Data port.

The adjustable delay could be better as well. Now it will be added to all Adlib port accesses. I think it would be best if specified delay would be added only after data port write. Other writes should have less delay and reads only minimum possible delay. So next version will be even better.

Reply 9 of 64, by jmarsh

User metadata
Rank Oldbie
aitotat wrote on 2021-09-17, 18:18:

I suppose the NOEMS parameter just can't be used then. EMM386 should be better documented. EMS memory does not have anything to do with port trapping but maybe port trapping functionality is just internally part of the EMS code or something.

It sort of makes sense if you consider that EMM386 only has to care about monitoring port accesses for the purposes of catching DMA transfers to/from the "fake" EMS page frame that is actually remapped XMS memory. If there's no EMS it has no reason to trap any ports.

Reply 10 of 64, by aitotat

User metadata
Rank Member

There was an error in release 4 version information (it is fixed now). I had code to add the user defined delay to data port only but I removed it and forgot to update the TXT that I had already written. The implementation was insufficient so I removed it completely for now.

Reply 11 of 64, by Gmlb256

User metadata
Rank l33t
jmarsh wrote on 2021-10-01, 14:16:

It sort of makes sense if you consider that EMM386 only has to care about monitoring port accesses for the purposes of catching DMA transfers to/from the "fake" EMS page frame that is actually remapped XMS memory. If there's no EMS it has no reason to trap any ports.

I was able to get QEMM with NOEMS parameter working with the new version of MIDIto. 😉

And SoftMPU works with EMM386 and EMS disabled, however it still doesn't work with MIDIto though.

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 12 of 64, by aitotat

User metadata
Rank Member
jmarsh wrote on 2021-10-01, 14:16:

If there's no EMS it has no reason to trap any ports.

That makes perfect sense. I'm sure that is the reason.

I did a lot of testing with EMM386 and port trapping since it is not so well documented. My findings can be read from ResCode.asm if anyone else is interested in port trapping. I compared EMM386 versions 4.46 (DOS 6.22), 4.50 (PC-DOS 2000) and 4.95 (Windows 9x) and the port trap handler works just the same in all versions. There seems to be no way to identify if 8-, 16- or 32-bit I/O call was made. QEMM API is much better, it even tells if the program had interrupts enabled or disabled when port access was made.

But back to EMM386 versions. 4.50 from PC-DOS 2000 is the only one that can trap 32-bit port accesses. MS EMM will crash, even the latest 4.95. The 95 most likely just means Windows 95 so the version number cannot be directly compared. But for port trapping the EMM386 4.50 from PC-DOS 2000 is the best. That is great since PC-DOS 2000 is my favorite DOS version (I would really like FAT32 support however).

One note about QEMM. I have only tested v7.53 and it has slower port trapping than EMM386. I need to test it more and other versions as well.

Reply 13 of 64, by aitotat

User metadata
Rank Member
Gmlb256 wrote on 2021-10-01, 17:54:

And SoftMPU works with EMM386 and EMS disabled, however it still doesn't work with MIDIto though.

Strange. Maybe I should read SoftMPU sources to see if EMM386 port trapping is setup somewhat differently.

Reply 14 of 64, by aitotat

User metadata
Rank Member

New release (5).

EMM386 can now be used with NOEMS and AUTO parameters and the Adlib delay is much better now and Sound Blaster OPL ports are included.

First I decided it would be enough to just read the SET BLASTER string and determine ports from there. But future releases in mind I decided to implement auto detection. Then I started to think more about the -a=0ff option. It is supposed to disable Adlib ports so some games would not force Adlib instead of allowing to use CMS.

I decided I can do better than that and added -cms option. It emulates the Game Blaster detection chip that the Sound Blaster does not have. Some games require it for CMS support. So basically the -cms option now turns your Sound Blaster 1.x or 2.0 to a Game Blaster (and disables the Sound Blaster DSP because of address conflicts).

Reply 15 of 64, by Dominus

User metadata
Rank DOSBox Moderator
DOSBox Moderator

Even though I'm never gonna use it as I have no old PC anymore... this is an awesome idea (and I guess implementation) of a program!

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox
DOSBox SVN snapshot for macOS (10.4-11.x ppc/intel 32/64bit) notarized for gatekeeper

Reply 16 of 64, by aitotat

User metadata
Rank Member

Release 6 now brings optimizations to reduce memory usage especially for QEMM (previously EMM386 code needed to be loaded to resident part of the program when QEMM was used). But this release is mainly about mixer locking.

Please, read the first post of this thread or readme included in the zip file for more details. By default the -lock parameter locks Master audio, CD, Line in, MIC and PC speaker (Sound Blaster 16 input) but what is locked or not can be user defined. It is also possible to force enable or disable Sound Blaster pro Low pass filter (Sound Blaster 16 does not have it).

There is one known issue with mixer locking. Star Trek: Judgment Rites requires MIC to be unlocked or it will not play digital sound. I'll need to investigate. Let me know if you find other problematic games. There is a possible problem since reading locked register will return the locked value. So if a game reads back what it wrote and does a comparison there will be a conflict. I suspect that it the case with Judgment Rites. It can be fixed by storing bytes written to locked register and then returning those stored values when register is read. Maybe the MIC just happens to be part of Judgment Rites SB Pro detection code.

Reply 17 of 64, by badmojo

User metadata
Rank l33t

This looks awesome thankyou! That mixer lock interests me in particular - no more .bat files "fixing the mixer" after those games that crank the volume right up.

I'll give it a try.

Life? Don't talk to me about life.

Reply 18 of 64, by aitotat

User metadata
Rank Member

Release 7 has some bug fixes.

First Star Trek: Judgment Rites with mixer locking has been fixed by storing MIC value it writes and then returning the expected value when read. So MIC volume appears to be unlocked but it is actually locked.

Next there is a workaround for Yamaha YMF71x based cards. It has a hardware bug (not sure if all the YMF71x has it) that SB mixer master volume must be set to 1 or the volume controls won't work like supposed to. For example Wolfenstein 3D plays with mono sounds since mixer does not work.

To enable the fix, MIDIto must be started with "-lock=ymf" parameter. This won't lock the mixers, it will just enable the fix. If you want to lock the mixers, use "-lock=ymf,def". This will enable the YMF fix and set mixer locks to defaults (master, FM, CD, line-in and MIC) . You can specify what it locked or not if needed. More info in readme.

How the YMF fix works? It sets the SB master volume to 1 and locks it. Then any accesses to master volume will be directed to another master volume control available at YMF control port. So you will have fix for the hardware bug and working master volume control at the same time. See the readme if you have set YMF to another control port than the default 370h. I believe it is possible to later implement autodetection and maybe set the fix automatically without the ymf-lock but better to test it first since I don't know if all the YMF71x chips really need the fix or not.

Finally I found and fixed a couple of bugs related to uninstall strings.

But then I found a new issue and there is no fix for it, at least not at the moment: For some reason EMM386 port trapping does not work (tested with EMM386 4.95) if I have vide-cdd.sys CD-ROM driver loaded. I don't know the reason. I use pcem to test the code before testing with real hardware but with my pcem setup vide-cdd.sys did not cause any problems. I'll need to test different emm386 versions next since I have no other ideas at the moment.

Reply 19 of 64, by Falcosoft

User metadata
Rank Oldbie

Can you add ESS cards special AuxB mixer source to locked/preserved mixer sources? The problem is that ESS 1868/1869 etc. accepts Sound Blaster compatible mixer resets and after a reset the AuxB volume is 0. So in games such as Gabriel Knight that first sends a reset and then adjusts SB mixer volumes you cannot hear Midi music from attached Waveblaster compatible cards. Here is a topic about the problem:
Re: Gabriel Knight 1 - General Midi/MT-32 Not Working.

According to ESS documentation the AuxB address is 3Ah (page 55 of attached document).

Currently Midito preserves all other volumes (Master/Voice/FM etc.) but AuxB is still reset to 0 by the game.
Thanks in advance!


  • Filename
    File size
    1.39 MiB
    File license
    Public domain

Website, Facebook, Youtube
Falcosoft Soundfont Midi Player + Munt VSTi + BassMidi VSTi
VST Midi Driver Midi Mapper