This has got to be one of the most obscure pieces of hardware I have covered so far. A sound card for the IBM PC, released in 1987. And by none other than Big Blue themselves! I am talking about the IBM Music Feature Card:
That is because the card features a full-blown MIDI sound module, with its own Z80 microprocessor. The MIDI sound module is based on the Yamaha FB-01:
The rest of the card contains a proprietary MIDI interface. In fact, the entire card is designed and built by Yamaha, for IBM. In concept, it is very similar to the later Roland LAPC-I, which is also a combination of a MIDI interface and a MIDI sound module on a single ISA card, except in that case, it is an MPU-401 MIDI interface and an MT-32 module.
For more background information, you can read the excellent coverage of the IMFC on Nerdly Pleasures.
So, it is an FM sound card then. Is it any good? Technically, yes. Where the AdLib uses the low-end YM3812 chip, with 9 voices and 2 operators in mono, this uses the more high-end YM2164, which has 8 voices and 4 operators, in full stereo. The entire card is well-made, and was quite expensive at the time, aiming more at semi-professional musicians than gamers. Here is an example of Sega’s Afterburner theme converted to FB-01/IMFC:
However, like the AdLib, the card suffers from the fact that most musicians couldn’t really be bothered to make the most of the FM synth, as discussed in an earlier blog.
Anyway, I was fascinated by this card. Firstly because it is so rare, and not supported by a lot of software. Secondly, because it is an official IBM expansion card. And lastly because apparently nobody had bothered to add support for it yet, in DOSBox. So I decided to give it a try.
Is it really a Yamaha FB-01?
The approach to emulating this card appeared to be straightforward: there is the MIDI interface, and then there is the MIDI module, which is allegedly a Yamaha FB-01. Well, as usual, with PCs, it depends on how you look at it.
The MIDI interface is reasonably simple, and it didn’t take me too long to emulate enough of it to get games to detect the card, initialize it, and send MIDI data, which I could intercept. I simply made use of the MIDI code that was already present in DOSBox for the MPU-401, and sent the MIDI data out via the same interface.
This worked, and the only way I could test it, was with a real IBM Music Feature Card, with its MIDI in connected to the MIDI out of my DOSBox machine. But when I sent out an early test-build of this DOSBox for people to test with a Yamaha FB-01, they reported problems. Some instruments were wrong or missing in Leisure Suit Larry 3. What was going on?
Different firmware, that’s what was going on. While the hardware is mostly the same (the IMFC is obviously missing the LCD display and the front panel buttons), the IMFC apparently has an updated version of the main firmware. We studied the manuals of the IMFC and FB-01 closely, and mapped out all SysEx commands. We found that the IMFC supports one command that the FB-01 does not, and Sierra was using this command.
The command in question is the “Parameter List” command. Yamaha implemented an interesting type of SysEx command, which will likely confuse a lot of modern MIDI software. They basically have variable-length SysEx commands, which effectively switch the device into a certain state, after which you can send it a variable (in theory endless) amount of custom commands within that SysEx command.
The FB-01 supports one type of this list command, which is the “Event List”. It basically switches to a Yamaha-specific proprietary extended MIDI mode, where you can send key on/off, control change, program change, after touch, pitch bender and parameter change events, which allow some fine-grained control that normal MIDI does not.
The “Parameter List” however was apparently added to the firmware after the FB-01 was released. Similar to the “Event List”, it allows a variable number of commands. These commands modify the parameters of instrument settings. The FB-01 does of course support changing instrument parameters via SysEx messages. It just does not support the list format, only individual SysEx messages.
So the fix was relatively simple: the state machine has to be implemented in the emulation code. Whenever it detects the start of a Parameter List command, it will go into the parameter list-state. Then every command is in the list is translated to an individual SysEx command on-the-fly (that last part is extremely important, the list could be virtually endless, and you do not want to buffer the whole list before you start converting it). When an end-of-SysEx is detected, it switches back out of the parameter list-state, and Bob’s yer uncle.
Funny enough, we found out that this difference between the IMFC and FB-01 was known in the old days. Firstly, apparently someone once wrote a TSR for King’s Quest 4 and related Sierra games that modified the IMFC driver to be used on a MPU-401 and FB-01 instead. When I inspected the code, I found that this driver also did the same SysEx translation for compatibility reasons.
Secondly, Sierra also provided their own FB-01 driver for some games. Ironically enough, this driver also fails with some games. Why does it fail? Because apparently they translated the IMFC parameter list incorrectly. Namely, the parameter list works on the basis of instrument number. Sierra however translated to parameter change commands based on MIDI channel (the FB-01 supports both variations). The problem here is that there is not necessarily a 1:1 mapping between MIDI channel and instrument, so some parameters are set incorrectly with the FB-01 driver.
What’s a YM2164?
Right, with the basic MIDI problems out of the way, the next big step was to actually emulate the synthesizer part, so that people would not need a real Yamaha FB-01. I wanted to go with a similar approach to Munt, which is an emulator for the Roland MT-32. A Windows driver, which installs itself as a MIDI input device, and outputs the emulated sound to your audio device in realtime. This means that you can use it as a standalone synthesizer as well, using Windows MIDI tools.
The Yamaha FB-01 is a reasonably straightforward device: it has a Z80 microprocessor, some firmware in a ROM, and a YM2164 chip. The firmware for the Z80 contains the MIDI interpreter, which takes care of all the MIDI events, manages the voice banks and configuration, and drives the actual YM2164 chip.
So I figured I could re-implement the MIDI interpreter part myself, based on the SysEx documentation. The biggest problem is the YM2164 itself. This is a very obscure chip, mainly because it was not a chip that was sold to third parties. It was only used in Yamaha’s own products, and a few Korg synthesizers. As a result, you cannot find any datasheets or manuals online, because they were never made public. I tried contacting Yamaha, but they could not provide me with the documentation for the chip either, so it seems to be lost forever.
However, we still have the internets! And as luck would have it, Yamaha actually built modules with the YM2164 chip for the MSX computer range, the SFG-05. BUT! The YM2164 is only used in the later revision of the SFG-05. Earlier revisions used the YM2151. And there is our clue!
Namely, people have studied these different modules, and they are basically identical in terms of sound and operation. Upon studying the firmware, they only found a few superficial differences, in terms of undocumented registers and timer resolution.
And unlike the YM2164, the YM2151 is a common chip, with available documentation, which was used in various arcade machines, and has proper emulation support in MAME. So we can just use the YM2151 emulation from MAME and hook it up to our MIDI interpreter, and it should be a good virtual FB-01!
This was the initial plan. However, due to other priorities, I never finished my own implementation. Recently someone pointed out that MAME actually includes an entire Yamaha FB-01 machine (which indeed uses the YM2151 emulation code to approximate the YM2164). And there is also the AMAME fork, which focuses on using MAME synthesizers, and wants to make them into VSTis.
So I tried experimenting with MAME and AMAME a bit, to see if the FB-01 actually worked. And indeed, it did! This was somewhat of a breakthrough for my IMFC emulation project. Namely, I can now offer full software emulation. There is no physical FB-01 required anymore. This makes the project a lot more interesting for the average DOSBox user.
Here is a quick video I made to demonstrate the whole thing:
So I have decided to put together a quick release of what I have so far. This is my custom DOSBox build with IMFC support, and a compiled version of AMAME to offer you an emulated FB-01 to complete the chain. You can donwload it here.
In order to set it up, you need to do 3 things:
- AMAME needs two ROMs for the FB-01 emulator, which I did not include because of copyright issues. You will have to find them yourself. One is the FB-01 firmware, which should be in a file called fb01.zip. The other is the firmware for the LCD controller, which should be in a file called hd44780_a00.zip. Place those two files in the ‘roms’ subdirectory under AMAME.
- DOSBox needs to be configured to output to the correct MIDI device. In this version, there is no IMFC-specific section in the dosbox.conf file yet. I am re-using the MPU-401 configuration. So set up the MPU-401 as usual: under the [midi] section, you use the midiconfig=n option, where n is the index of the MIDI output device you want to use.
- AMAME also needs to be configured to get input from the correct MIDI device. This is done by name. Run “amame64 -listmidi” to get a list of the names of the possible MIDI in and out devices. Then use the -midiin and -midiout parameters to pass these names. I have included an FB01.bat as example, just change the names to the name of your device, and you should be up and running.
A loopback will be required between the MIDI out-device that DOSBox uses and the MIDI in-device that AMAME uses. I have tried LoopBe1 and loopMIDI, but found problems with both. The first seems to filter SysEx commands, which effectively filters out custom voice data from games, which makes it rather useless. The second seems to crash the FB-01 on large SysEx commands. I ended up using my E-mu 0404 USB interface with a physical loopback cable between its MIDI out and MIDI in ports. This works perfectly.
You could also use a real Yamaha FB-01 instead of AMAME of course.
Make a demo about it
The emulation still needs some work (it currently does not fully emulate the 8253 timer on the IMFC yet, MIDI in is not working yet either, and not all commands are fully implemented yet). But in its current state it should be good enough for all Sierra games at least.
I also still want to complete my own virtual FB-01. Firstly, because it should be more convenient to use than AMAME. Secondly, because my code will be a clean reimplementation of the MIDI interpreter, and will not require any copyrighted ROMs.
But for now, I think it is most interesting that the IBM Music Feature Card is now available to a much wider audience. And the next thing I want to do is probably some simple demo/music disk, targeting an 8088 at 4.77 MHz with CGA and an IBM Music Feature Card.