VOGONS


IBM Music Feature Card/Yamaha FB-01

Topic actions

Reply 140 of 263, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
Scali wrote:
Cloudschatze wrote:

And... validated. The FB-01's (inferior?) voice-assignment behavior is the same whether configured through SysEx, or by front-panel operations.

Meaning what exactly? That it just rejects the SysEx command if you try to allocate more voices than it has available?

Yes, basically. In other words, if Instrument #1 has all 8 notes of polyphony assigned, and I send a particular SysEx string assigning any number of notes of polyphony to Instrument #2, nothing happens - Instrument #1 retains all 8 notes, while Instrument #2 retains zero.

Per the earlier stuff we'd looked at, Sierra's IMFC and FB-01 drivers de-allocate all notes prior to configuring them for the playback sequence to follow.

Reply 141 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
Cloudschatze wrote:

Yes, basically. In other words, if Instrument #1 has all 8 notes of polyphony assigned, and I send a particular SysEx string assigning any number of notes of polyphony to Instrument #2, nothing happens - Instrument #1 retains all 8 notes, while Instrument #2 retains zero.

Okay, that part will be easy to emulate.
I suppose there's also a deeper problem here: what if you send an entire configuration with an incorrect voice allocation?
Will it reject the entire configuration, or will it store the configuration, but merely reject the voice allocation?

Cloudschatze wrote:

Per the earlier stuff we'd looked at, Sierra's IMFC and FB-01 drivers de-allocate all notes prior to configuring them for the playback sequence to follow.

Yes, I don't think this is too important in practice, I think it's reasonably safe to assume that games use valid configurations.
Still, it doesn't hurt to have sanity checks, and at the very least, set the note count to 0 whenever a potential problem arises. Because the way I intend to implement the MIDI note mapping and polyphony, it will crash when you go beyond 8 voices.
Namely, my idea is to allocate the YM2151 voices linearly.
So, if instrument 1 has 3 notes, it will get voices 0..2. Instrument 2 has 2 notes, it will get 2..3 etc.
The number of notes is already stored in the instrument data. I would merely have to keep track of the lowest voice to use for that instrument.

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

Reply 142 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I've made some progress with the new MIDI mapping.. A MIDI note can be active on multiple YM2164 voices at the same time (eg when doing 'dual' sound setups).
So what I've done is to make a function is_on_instrument(), where you pass a note and its MIDI channel, and it will tell you whether or not the note should be played on that instrument.
I simply loop through all 8 instruments, and whenever the is_on_instrument() function returns true, I perform the required logic.

I've only done a quick-and-dirty implementation for note_on/off right now, and made a simple default configuration where each instrument is mapped to a unique MIDI channel with full note range and a polyphony of 1.
The actual polyphony code still needs to be reimplemented (I'm moving it into a different place from where it was before), and more annoyingly, the entire codebase was designed to use the MIDI channel as a parameter, and have one YM2151 instance mapped to each MIDI channel.
I need to rewrite all of that to map to the individual voices of a single YM2151 instead.
The annoying part there is that it now makes a difference whether certain processing is 'chip-wide' or 'instrument-wide'.
Hopefully the polyphony code will make things trivial enough that you just get a voice number out of it, and not much else needing to be done on 'instrument-wide' level.

I can just say that I would be very happy once I can start LSL3, and it will initialize all MIDI channels and instrument polyphony correctly, and sound basically the same as it did before. Because that would mean the new MIDI mapping is done, and we 'only' have to solve the voices and any other remaining SysEx stuff.

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

Reply 144 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
lchiocca wrote:

In the emulation, should we also emulate all the stack overflows that are in the IMF code? 😉 Already found one "hidden" sysex command 😀

Hah, yes, we should go for total accuracy 😀

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

Reply 145 of 263, by lchiocca

User metadata
Rank Newbie
Rank
Newbie

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! Grrr...

Anyways... Here's a first draft of the ROM code. It's still assembler, but with a lot of function names and comments... Scali, you might be insterested at the functions sendToYM2151, some_ym2151_functionA, some_ym2151_functionB, sendBlaToYM2151, sendTransformedDataToYM2151, read_midi_byte, send_midi_byte and processMidiByte. I'm still strugelling with their internal state machine - it's really weird the way it's structured.
https://drive.google.com/open?id=0B-ppgg8G9MV … WEMta3RxeDdTX2M
The main file is 01-CODE.asm

Reply 146 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Thanks for your work so far, that should give us some answers to things we can't work out by just reasoning and interpreting the data.
I'd like to know how exactly it handles things like polyphony and portamento.

What are the different .bin files though? They look like the 5 different voice banks in ROM?
I suppose we'd also need the configuration ROM sets, but I guess both the voices and the configurations can be dumped to a SysEx file, and just uploaded to the unit at startup.
That way we don't have to distribute the original ROMs or any part of it with the emulator itself.

As for source 1 and 6... I noticed that this is something only documented for the IMFC. The FB-01 does not have a 'source 6' documented. Perhaps because it doesn't work 😀

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

Reply 147 of 263, by Stiletto

User metadata
Rank l33t++
Rank
l33t++
Scali wrote:

1) Do you know if this chip decapping project also takes the YM2164 into account? Nobody seems to know exactly what an YM2164 is, not even Yamaha (I asked them for documentation, they said they no longer had any available for such old discontinued chips). Common knowledge on the internet is that the YM2164 is identical to the YM2151, save for some undocumented registers.
I wonder if that's true... and I also wonder what these undocumented registers do, and what the differences are.
For now I'm assuming it's true, since I can get an YM2151 emulator, but there is no YM2164 emulator.

As far as I know, it will also be decapped. (It may be a few years! 😀 )

Scali wrote:

2) Do you happen to know what the status of OPL3 emulation is? I don't know what DOSBox uses, but if I run the TEST-SBP.EXE program, the 4-operator test sounds quite distorted and bad compared to the real thing.
Is DOSBox just using an outdated emulation core, or is the state-of-the-art in OPL3 emulation still not quite there yet?

My understanding is that the Nuked OPL3 core is better even than what's currently in MAME. It's not currently used in DOSBox AFAIK but might be used in a few forks. See this thread.
Nuked OPL3 emulator

"I see a little silhouette-o of a man, Scaramouche, Scaramouche, will you
do the Fandango!" - Queen

Stiletto

Reply 148 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
Scali wrote:
I've only done a quick-and-dirty implementation for note_on/off right now, and made a simple default configuration where each in […]
Show full quote

I've only done a quick-and-dirty implementation for note_on/off right now, and made a simple default configuration where each instrument is mapped to a unique MIDI channel with full note range and a polyphony of 1.
The actual polyphony code still needs to be reimplemented (I'm moving it into a different place from where it was before), and more annoyingly, the entire codebase was designed to use the MIDI channel as a parameter, and have one YM2151 instance mapped to each MIDI channel.
I need to rewrite all of that to map to the individual voices of a single YM2151 instead.
The annoying part there is that it now makes a difference whether certain processing is 'chip-wide' or 'instrument-wide'.
Hopefully the polyphony code will make things trivial enough that you just get a voice number out of it, and not much else needing to be done on 'instrument-wide' level.

I've done a first refactor of all the MIDI-channel stuff, and things should now be mapped to the correct instruments...
Tomorrow I'll do the logical thing and implement the SysEx commands that control the instrument voice allocation. If my code works correctly, then LSL3 should at least be able to play all its notes again (currently it boots up with 8 monophonic instruments, mapped to MIDI channels 1-8, and no way to change that).

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

Reply 149 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
Scali wrote:

Tomorrow I'll do the logical thing and implement the SysEx commands that control the instrument voice allocation. If my code works correctly, then LSL3 should at least be able to play all its notes again (currently it boots up with 8 monophonic instruments, mapped to MIDI channels 1-8, and no way to change that).

Did a quick-and-dirty implementation of the required SysEx commands and a simple voice allocation routine...
It sorta works, but the polyphony isn't working the way I expected it to. It seems to be related to the 'hold' function: it plays all notes 'legato', and the default instrument has a dropoff in volume, so your melodies slowly fade into the background.
Since this is an instrument parameter, it may be something they set with their custom voice bank and other parameters.
I think we may slowly be getting somewhere... perhaps trying to get the voice data to work would make the most sense at this moment.

The portamento is also broken, but I already sortof expected that: the VFB-01 code used a simple stepping algorithm, which performed one portamento step everytime it was called. That worked okay in the original scenario, where you always called it once every 10 ms to grab MIDI data and render a fixed block of samples.
The MUNT code however works in a different way: it timestamps all incoming MIDI and renders as many samples as required between MIDI commands, until the sample buffer is full.
Which means that our portamento steps now have random length. I suppose the easy way is to explicitly check how many samples have been rendered, and only perform a portamento step after X samples, as it did before.
A better way would be to rework the portamento code so that it doesn't depend on a fixed step size, but can adjust itself proportionally. But I'll go with the easy way first.

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

Reply 151 of 263, by Scali

User metadata
Rank l33t
Rank
l33t
jal wrote:

It seems the ROM code is Z80 assembly? If so, perhaps a Z80 emulator could be used to drive the ROM code that drives the YM?

Could be perhaps... But then you'd need the actual ROM to use the emulator. The code seems to be simple enough to re-implement it entirely. I think we already have about 70-80% working at the moment.
Once the voice data is done, we should be at about 90%, and the remaining 10% would be some details that we should be able to check against the ROM.
The emulator will not require a ROM, merely a SysEx dump of the instruments and configurations of a real FB-01 (which we can probably provide without any copyright issues).

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

Reply 153 of 263, by Great Hierophant

User metadata
Rank l33t
Rank
l33t
Scali wrote:
ih8registrations wrote:

FB01KING.ZIP is a TSR, with the source, that "converts" an IMFC to an FB-01. http://cd.textfiles.com/swextrav1993/disk4/pcspkr/

In retrospect, this FB01KING driver seems to do the same SysEx translation from IMFC to FB-01 as I added to DOSBox.

The FB01KING driver works with early KQ4, but not early LSL2 (even though the batch file suggests that it should work), with LSL3 or with KQ5. The offsets by which it injects code may change from driver to driver. It won't do as an IMFC interface emulator 😢

http://nerdlypleasures.blogspot.com/ - Nerdly Pleasures - My Retro Gaming, Computing & Tech Blog

Reply 154 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

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).
Sierra appears to use this to send their voice data.
However, if my patched DOSBox worked on the FB-01 with the correct voice data for LSL3 (which I believe it did), that would imply that the FB-01 actually supports it. Perhaps I'm just not reading the docs correctly...

Anyway, I'll implement it in my emulator for now, since it's the only easy way to get a known set of voice data into my emulator at this point.
When we get to the bottom of this later, we'll see if it actually has to be translated in the IMFC interface in DOSBox or not.

Last edited by Scali on 2017-07-09, 10:03. Edited 1 time in total.

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

Reply 155 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

I've obtained a ROM image that someone dumped from a real FB-01 back in the day. First impression is that it looks quite similar to the IMFC code.
It may be useful to compare the two if we want to study the differences/incompatibilities between the two units in detail.

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

Reply 156 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

Slowly but surely we're getting there...
I've got this when starting LSL3:

[37144] FB01: Voice bank data, length: 6208, destination: 0, checksum: 00, end: 00
[37144] Voice bank name: SIERRA
[37144] Voice name: Kick D.
[37144] Voice name: SnareDr
[37144] Voice name: RD Cymb
[37144] Voice name: Tom Tom
[37144] Voice name: HiHat
[37144] Voice name: DeepSnr
[37144] Voice name: BirdTwt
[37144] Voice name: Xylophn
[37144] Voice name: Banjo
[37144] Voice name: Timpani
[37144] Voice name: Piano2
[37144] Voice name: Piano3
[37144] Voice name: WtrBell
[37144] Voice name: EchoBel
[37144] Voice name: EPiano4
[37144] Voice name: Clav3
[37144] Voice name: Shakuha
[37144] Voice name: EchoPan
[37144] Voice name: Fantasy
[37144] Voice name: IceRain
[37144] Voice name: BottleB
[37144] Voice name: MonoSax
[37144] Voice name: Flute
[37144] Voice name: DrSolo

So, the names for the voice bank and the individual voices are decoded correctly from the SysEx data. Presumably that means the rest of the voice data is also correct, since it is stored in the same way.
I still need to build the structures for that, and wire them up to the YM2151 though. The VOICE_BANK struct that was taken from VFB-01 is not the same as the FB-01. VFB-01 stores all parameters in arrays of 4, for each operator. The real FB-01 instead stores the parameters for each operator sequentially, so it is more like an array of 4 structs. Which means the whole part that sends the voice data to the YM2151 registers has to be rewritten. I hope I don't break it 😀

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

Reply 157 of 263, by Great Hierophant

User metadata
Rank l33t
Rank
l33t

The ROM in both the IMFC anf FB-01 is 32KB. I understand that it has to hold the data for the built-in instruments (480), the built-in configurations (4) as well as initialize the module, interpret the MIDI commands and communicate with the YM2164. The FB-01 also must have code to drive the LCD. I wonder if they scrapped that code in the IMFC to make room for the new features. Otherwise, I would be interested in trying an IMFC ROM in an FB-01.

http://nerdlypleasures.blogspot.com/ - Nerdly Pleasures - My Retro Gaming, Computing & Tech Blog

Reply 158 of 263, by lchiocca

User metadata
Rank Newbie
Rank
Newbie

I made a quick decompile of the fb-01 code (it's in the google drive / file called "Yamaha_FB01 (original clean enhanced).asm"). Hadn't had time to find any names. But what you can certainly see is what is code and what is data. My post-processor sets the segment to ".code" if it was able to reach it (starting at 0x0000) or if not the segment is still ".data". What's also interesting is the both have the exact same voice configuration except for a typo in the name in the fb-01 ("HardBr1" vs "HradBr1").

From what I can see, there is a *lot* of common code. If someone has already reversed engineered the FB-01 then I guess it's almost the same. The FB-01 ROM also has a lot more debug text compared to the IMFC.

Reply 159 of 263, by Scali

User metadata
Rank l33t
Rank
l33t

My first attempt at using the voice data, using a quick-and-dirty conversion from FB-01 SysEx format to the internal VFB format was not very successful.
I guess I'll have to rewrite the YM2151 interfacing code to use the SysEx format directly (which seems to correspond quite directly to the registers). I guess studying the ROM code would be a good help at this point. Try to see where they load the voice data, and how they write it to the registers, then duplicate that.

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