First post, by aitotat
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.
USAGE: midito [PARAMETERS]
-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
* 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
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
-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.
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
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
* 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.