VOGONS


IBM Music Feature Card/Yamaha FB-01

Topic actions

Reply 160 of 263, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
Scali wrote:
I think I may have found another unsupported, or at least undocumented SysEx on the FB-01... If you look at page 6-20 in the IMF […]
Show full quote

I think I may have found another unsupported, or at least undocumented SysEx on the FB-01...
If you look at page 6-20 in the IMFC Technical Reference, it describes Node Messages.
They have the form F0 43 75 0s 00 0f 0d ... F7

The bolded '00' is what I can't seem to find in the FB-01 documentation (only in their documentation of the data you can receive from a dump, but not sending it... then again, I suppose the idea of a dump would be that you can save it back as-is).

This is better described in the FB-01 service notes, but "00" in this particular context identifies the string as being a "Bulk Data System Message," where the following byte then defines a particular "Operation." For whatever reason, the terminology is different with the IMFC, where it's a "Node Message," followed by a "Format Number," but the usage is the same, except for the "Configuration-2" discrepancy.

It looks like the following four bulk (receive) operations pertaining to the "00" message are compatible with both the FB-01 and IMFC:

F0 43 75 0s 00 00 0x <data> F7 - Voice Bank x (x = 0 - 1)
F0 43 75 0s 00 01 00 <data> F7 - Current Configuration Buffer
F0 43 75 0s 00 02 xx <data> F7 - Configuration Memory (xx = 0 - 15)
F0 43 75 0s 00 03 00 <data> F7 - All Configuration Memory

Reply 162 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
carlostex wrote:

Somewhat unrelated, but anyone thinks that IMFC drivers for Sierra games (that don't have a FB-01 driver) could be patched to work with the FB-01?

Possible, yes, but probably quite a bit of work.
For 386+ we could do something SoftMPU-like: virtualize the IMFC interface and output the MIDI data to an MPU-401 or SB MIDI port.
Or you could just use DOSBox, which already does that currently. It's how I am testing the FB-01 emulator, and comparing to a real IMFC (connecting the MIDI out of DOSBox to the MIDI in of a real IMFC).

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 163 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
Cloudschatze wrote:

This is better described in the FB-01 service notes, but "00" in this particular context identifies the string as being a "Bulk Data System Message," where the following byte then defines a particular "Operation." For whatever reason, the terminology is different with the IMFC, where it's a "Node Message," followed by a "Format Number," but the usage is the same, except for the "Configuration-2" discrepancy.

Yes, it's very annoying that the two manuals use vastly different ways to name and describe the SysEx commands.

Cloudschatze wrote:
It looks like the following four bulk (receive) operations pertaining to the "00" message are compatible with both the FB-01 and […]
Show full quote

It looks like the following four bulk (receive) operations pertaining to the "00" message are compatible with both the FB-01 and IMFC:

F0 43 75 0s 00 00 0x <data> F7 - Voice Bank x (x = 0 - 1)
F0 43 75 0s 00 01 00 <data> F7 - Current Configuration Buffer
F0 43 75 0s 00 02 xx <data> F7 - Configuration Memory (xx = 0 - 15)
F0 43 75 0s 00 03 00 <data> F7 - All Configuration Memory

Yes, this was more or less my assumption. Thanks for the verification.

I am now studying the code in the ROM to see which values it sends to the YM2164, and when.
First focus is to get the voice data working correctly (the note frequencies and volumes seem to be 'okay' at this point, based on the VFB-01 code). Once the voice data works, I will study the remaining YM2164 commands, which should be the note on/off commands and related things. To see if we can get all the code I currently borrowed from VFB-01 as accurate as possible.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 164 of 263, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie

Not particularly significant, but here's an undocumented FB-01 bulk request message:

F0 43 75 0s 20 05 00 F7

It returns a 16-byte, "rel. M002.00.009" ASCII string on one of my units, presumably relating to the ROM version.

Reply 165 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
Cloudschatze wrote:

Not particularly significant, but here's an undocumented FB-01 bulk request message:

F0 43 75 0s 20 05 00 F7

It returns a 16-byte, "rel. M002.00.009" ASCII string on one of my units, presumably relating to the ROM version.

I suppose.
In the IMFC rom there are these strings:
YAMAHA IBM MUSIC
rel. M102.00.010

The FB-01 rom has these strings in the same place:
rel. M002.00.009
YAMAHA COM FB-01

Note that the order of the two is reversed, which makes me wonder whether there are SysEx commands to get both strings, and if so, if the IMFC would return them in reverse order as well.
Does it return "YAMAHA COM FB-01" for the identification number command? (F0 43 75 0s 20 05 00 F7).
In the IMFC ROM I also find this one: F0 43 75 0s 20 06 00 F7
I don't think I see that particular one in the FB-01 ROM.

So if Yamaha did proper version management, then the FB-01 ROM we are examining is exactly the one in your unit.
The IMFC rom implies that it is a newer revision. I wonder if we should read the '102' as the '1' signaling it's an IMFC, and the remaining number is the 'regular' revision.
That would make sense, as in, perhaps Yamaha was planning to include the extra parameter list in newer FB-01 models anyway. In fact, perhaps there are newer units that do. But we only have 'old' manuals, by the looks of things.

Interestingly enough, as I reverse engineered further, I think I found a part in the ROM that lists the SysEx messages.
lchiocca had already found the voice ROM banks, and I've also found the 4 ROM configurations now. Slowly but surely, the ROM is starting to reveal its secrets.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 166 of 263, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie

F0 43 75 0s 20 04 00 F7 does indeed return the 16-byte "identification" string, as documented for both the IMFC and FB-01 in their respective technical manuals. I was specifically testing the FB-01 for the "Source 06," "Configuration-2" function/operation specific to the IMFC though, which led to checking for the in-between, but undocumented "05" string.

I've looked/hoped for a newer FB-01 that might incorporate some of the IMFC additions, but have yet to come across one.

lchiocca wrote:

It's really amazing how many bugs I already found! How could it have been that complicated?! There's a sysex command to dump a source memory (Node Dump Request Message with Source 1 and 6). Source 1 and 6 represent the configuration buffer 1 and 2. It's nice to see that DumpSource1 and DumpSource6 actually point to the same config!

This doesn't seem like a bug. The way the IMFC manual describes it, there is a single configuration buffer, but two separate means of sending bulk data to it, differing in the application of settings relative to the Combine function. This being the case, it makes sense that the same configuration buffer data would be sent for the separate corresponding dump requests (perhaps just leaving the question of why a specific dump request for "Source 06" exists at all, if perhaps only to maintain consistency).

Reply 167 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I have found one instance already where the code writes to register 0, which is in the undocumented range of the YM2151, and presumably also of the YM2164 (well, everything is undocumented there).
I suppose I'll have to figure out when exactly it calls that particular code, then perhaps we can deduce what it is trying to achieve there. My first impression is that it was only called at initialization time, so perhaps it's not something to worry about.

I also saw that it writes to the noise register at initialization time, it seems to disable the noise (if I understand correctly, the 32nd operator can be set to noise... so operator 4 of voice 8 ). I don't think there's anything in the SysEx messages to change this setting, so the noise feature can't be used. In which case it means you can't play every possible YM2151 song on an IMFC or FB-01. But I hope I'm wrong about that 😀

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 168 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Still reverse-engineering the ROM. I did find a few small flaws in the structures of my C code. The layout should now be 1:1 with the real thing.
Looking at the way the ROM handles the voice data and such, it does things mostly 1:1 as well.
That is, on startup the configurations and voice banks are copied 1:1 to RAM, with only the names replaced as 'user 1' etc.
SysEx also seems to mostly just read/write these buffers 1:1, merely encoding and decoding them because of the 7-bit value requirement of MIDI.

I'm now trying to piece together how it actually selects a voice and initializes the YM2164 chip for that. But my first impression is that mostly the voice data is just sent to registers in batches. I haven't seen a lot of extensive bit juggling and such.
So I will need to map out each byte in the voice data and figure out which YM2164 register it goes to.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 169 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I thought I had already posted this yesterday, but apparently not.
I've now located where the instrument and configuration parameters are set, so that gives clues for more of the internal structure.
I haven't quite had that 'aha-moment' yet where I see "Oh, here's the note data coming in, and this is where it sends it to the YM2164".
But I suspect that is because it is decoupled.
I suspect that there is some kind of timer interrupt, and the chip registers are just updated at every tick (this is more or less also how VFB-01 works). The MIDI data is processed asynchronously, and merely stored into the state machine as it comes in, but does not necessarily lead directly to reprogramming of the YM2164 (only in special cases).

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 170 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I think I've unraveled all the low-hanging fruit in terms of reverse-engineering... That is, code and data that could be explained either by what values were written to the YM2164 registers, or by what data was received or sent via a known SysEx command.

What is left is a lot of state-information where it isn't immediately apparent where the code stores what (it appears to use a few arrays of internal structs, loading the address into the ix or iy register, and then indexing off that).
It will take a lot of time to decypher everything.
But the primary focus at this point should be the voice data I suppose. I'll have to see if I know enough about that for now to get it working.
So far the theory that the voice data is a 1:1 mapping to the YM2164 registers seems to hold. It is also apparent that the SysEx commands to update individual values will reformat the value and combine it with the rest of the register value (there are often 2 or more values packed into a single 8-bit register value).

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 171 of 263, by lchiocca

User metadata
Rank Newbie
Rank
Newbie

Scali, I've gotten further as well in terms of reverse-engineering. I'm not completely done, but I've got a big portion as well. In the google drive https://drive.google.com/drive/folders/0B-ppg … WEMta3RxeDdTX2M you'll find the "01-CODE (original clean enhanced).asm". It's a auto-gererated file based on the original disasm'ed version that's run through a python code analyser that I wrote for this purpose (imf-parser.py). I've got most of the functions and the data variables although there are still some things that are unclear. Just out of curiosity: could you send me your version? You probably found things I haven't yet and that I could merge in.

I'm still going to continue on. I'm in the mood to generate a full C-version of the ROM code 😀

Reply 172 of 263, by lchiocca

User metadata
Rank Newbie
Rank
Newbie

Did you know: The (undocumented) system command message 1F6 allows you to write to the card memory (RAM - not the standard buffers). That also includes code! It's even intended to have code in 0xc000 that can be executed - Nice! But not emulatable 🙁.

Reply 173 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I have made an experimental TSR named SoftIMFC: https://www.dropbox.com/s/tnlrda2j3sfwhy6/SoftIMFC.zip?dl=0
It is similar in nature to SoftMPU: it uses EMM386 or QEMM386 to virtualize the ports of the IMFC and intercept and reads and writes.
It then runs these through the same emulation routines I had already made for DOSBox, and outputs the raw MIDI data to a UART MPU401 at address 330h.
This TSR should allow anyone with a 386+ and a Yamaha FB-01 to play games with IMFC music on real hardware.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 174 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

That first build of SoftIMFC was massively bugged.
I now have a proper way to test it, via the DreamBlaster S2P.
I got it working on that, tested with Laura Bow, Larry 2 and Larry 3. It should also work fine with an MPU-401, but I don't have a machine to test it on.
Here it is: https://www.dropbox.com/s/tnlrda2j3sfwhy6/SoftIMFC.zip?dl=0

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 175 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I think I have the 8253 on the IMFC implemented. Apparently the IMFC uses a feature of the 8253 that I never noticed: each of the 3 counters can run on its own clock.
Counter 0 runs on a 500 kHz clock.
Counter 2 runs on a 2 MHz clock.
Counter 2 runs in square wave mode, and its out is connected to the clk in for counter 1.
This means that counter 1 effectively runs at a speed of 2/(counter 2) MHz.

Counter 0 is known as 'timer A' on the IMFC, and counter 1 + counter 2 is known as 'timer B'. Both can generate interrupts.

My emulation can now generate and mask these interrupts. It seems to work okay, because I can now pass the next check in PlayRec and Compose (but only if you set the cycles low enough, around 1000, because else the check loop gives up before the interrupt can fire).
They now send some new commands. After that, Compose gets stuck during "Now loading programs"... and PlayRec fails some additional test, and reports "I/O error".

But I'm taking it one test at a time, eventually it should all work 😀

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 176 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I've reached the point where PlayRec sends the following SysEx command:
F0 43 75 0D 20 00 00 F7
Then it waits for an answer (which never comes, since I have no actual MIDI device connected to answer this).
The SysEx message appears to be an instrument dump message.
I'm not entirely sure why PlayRec would want to dump the instruments at startup, but it probably has its reasons.
It gets stuck currently since it polls the midi input and nothing comes in.
So at this point it looks like I'll be needing my FB-01 emulator to answer the SysEx messages, and extend my DOSBox code to get data from midi in, and re-route it to the application.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 177 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Hum, this may be more difficult than I initially thought... apparently Windows specifically splits MIDI input and MIDI output drivers.
So I can't just easily add MIDI input to my existing FB-01Emu driver. No, it needs to become a 'dual-standard' driver, somewhat of a two-headed monster, so that it can be both loaded as an input and an output MIDI driver.
What's worse, for some reason only the MIDI output info is on MSDN, the MIDI input info is not there, so I need to find some old MMDDK documentation and hopefully examples to see how that works.
In fact, I hope I can make a single driver work both ways at all (I suppose so, since I don't recall MIDI drivers having two separate files in general).
If not, I'll have to have two separate drivers which communicate together, since they both need to be used by the single FB-01 emulator instance.

Oh well, I suppose I'll have to worry about adding MIDI input to DOSBox itself first (amazing that they've come all this way without ever implementing any MIDI input whatsoever). Else I can't receive any data from my driver anyway.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 178 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Here is the latest build of my custom DOSBox with IMFC support: https://www.dropbox.com/s/dlk84chf35jzr2m/DOS … oxIMFC.zip?dl=0
A first quick-and-dirty version of MIDI In has been added, and I can get data from a real IMFC connected to a USB MIDI device into DOSBox.
If you were to use a Yamaha FB-01, you should at the very least get the Sierra games running via their IMFC driver (which is less buggy than the FB-01 one).

So that mainly leaves the driver for now... and studying lots of details later, to get the emulation just right in all cases.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 179 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Another update for SoftIMFC: https://www.dropbox.com/s/1qorqr9ppyorod6/SoftIMFC.zip?dl=0
This time it should really work on MPU-401. In the earlier version the init code was never called, so it never switched the MPU-401 into UART mode. Which meant it only worked if the MPU-401 was already in UART-mode, which it isn't on powerup.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/