New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MS-DOS] Timing-sensitive issues sending SysEx via Music Quest PC-MIDI/Orpheus "Intelligent" MPUs #2
Comments
Hi @dwhinham ! That's interesting... and somewhat confusing. :D Actually, mt32-pi.exe does a waitwrite (busy waiting on the MPU's STATUS register) every time before it writes anything to it. It is a bit weird that waitread would work here because a real MPU401 is not supposed to actively ACK a switch to UART mode AFAIK. After switching it will just transparently make any incoming bytes available, i.e. waitread would (should?) block until an actual MIDI message gets sent to the PC. As a semi-technical reference I had a look at this: http://midi.teragonaudio.com/tech/mpu.htm The whole MPU-401 interface code is basically 'stolen' from DOSMID (http://dosmid.sourceforge.net/). Can you check if you get similar problems playing a midi file with that program? If not, then I apparently added some really weird bug along the way. Unfortunately, I am unable to reproduce the bug either in DOSBox or on a real K6-2 450MHz with a dumb ESS1868 and an intelligent HardMPU (based on an AVR). This doesn't mean anything of course as HardMPU is basically the DOSBox MPU-emulation put on a microcontroller. So it's not authoritative on real MPU behavior. Is the PC-MIDI supposed to be a 1:1 HW clone? In any case, if adding a delay after switch to UART mode fixes it, there's nothing really wrong with having that. This happens only once every program run. So it wouldn't hurt throughput of longer SYX-files or anything else. But I guess I'd go lower than 1s, probably 100-200ms or something like that. I am reluctant to add a waitread because I am pretty sure it will lock up on many cards which send no reply. Would be better to find the root cause though ofc. |
Yes, this makes no sense to me either :)
DOSMID is working just fine over here, although looking at its sources, it does the MPU reset/UART switch, then loads the MIDI file, and then begins to output the bytes. The file I/O it does could be having the same effect as a delay (like how using -Y to load a sysex file also works fine with no delay on mt32-pi-control).
I don't think it's a 1:1 clone; it has a Z80 CPU on board with some firmware to do the "intelligent" stuff, so differences in the implementation compared to a real Roland MPU could be at play here. In other words, another "non-authoritative" MPU implementation, though a pretty good/compatible one nonetheless according to considerable testing on VOGONS.
I agree, and I don't think the waitread is a good idea at all, was more of a blind "let's see what happens" :) Keropi (one of the creators of the Orpheus and PC-MIDI clone cards) has offered to do some testing as he has a big collection of MPUs. He has an mt32-pi, but has not tried your tool yet, so we could wait and see if he can reproduce it too if you like. Cheers! |
So, after a bit of searching I had a look at the MPU-401 Technical Reference.
The DRR=0/1 polling is what This might not crop up with other programs/games due to the timing stuff you outline, like loading a file or something else and it would cause issues only for the first few sent notes/commands anyway. It may well be that the original MPU also has this timing issue and they didnt bother to write about it as PCs in 1985 simply weren't fast enough to cause the problem. Nevertheless it's all a bit academical. If there are cards in the wild that need a hard 100ms delay after the UART switch, then that's the fix and I'll do a small bugfix release for the MS-DOS version probably later today. 🙂 If you have contact with him, I'd be happy to hear keropi's thoughts on this and how he implemented the intelligent/UART switch in firmware, especially the handling/timing of the DRR Bit in this case. |
Thanks to both of you for looking into this, really appreciate it. I'd be more than happy to assist with testing debug/fix builds. |
Thanks for this! You've basically just confirmed my thoughts from briefly reading some of the MPU401 technical reference yesterday; the code does seem to be doing the right thing, or if it's not, I can't see it either.
This appears to be true - we now have some evidence to support this from keropi:
So on a 386, with either a genuine Roland SCC-1 (which has an intelligent MPU) or the PC-MIDI clone, he gets the problem, and a delay fixes it on both. He's tested with both a 1 second delay version and a 100ms delay, both apparently working fine, so I think 100ms should be a safe bet! @appiah4 If you want to confirm that a 100ms delay works for you too, here's a binary:
Great!
My understanding is that keropi has re-used the original Music Quest firmware blob cloned from the official cards' EPROMS released in the 80s, so we won't be able to understand this unless someone fancies doing some Z80 disassembly. 🙂 |
@dwhinham I will check the build and report later tonight! |
Alrighty, added a 100ms delay after |
Tested working, LGTM! |
Timing fix for intelligent MPU401s (Issue #2)
Hi @gmcn42, hope you are well!
@appiah4 has encountered problems using mt32-pi-control to send SysEx from MS-DOS via a Music Quest PC-MIDI "Intelligent" MPU clone card from keropi - there's a (long!) thread here: dwhinham/mt32-pi#127 (reply in thread)
I have an Orpheus card which has the same MIDI hardware/"intelligent" MPU as the PC-MIDI clone, and was able to reproduce this.
The problem is that the MPU emits no data at all when using
mt32-pi.exe -g
ormt32-pi.exe -m
, for example, and so the Pi of course receives nothing.DUMP.EXE
, on the other hand, works fine with an equivalent .SYX file; games and other intelligent-mode aware software also works fine.The issue is timing-sensitive, because:
-v
seems to "fix" it - but not for me. Theprintf()
caused by-v
appears to add just enough of a delay between putting the MPU into UART mode and sending the data to allow it to work.-Y
and providing a .SYX file works too; I think the delay caused by reading the file from disk allows it to work too.As a hack, I added a call to
delay_ms(1000);
here, just after thempu401_uart(mpubase)
line:mt32-pi-control/dos_src/midi_dev.c
Line 18 in bb63181
mpu401_waitread(mpubase);
instead of the delay also appears to work, but I don't think this is correct.I'm not sure of the true fix, as I'm not experienced with programming the MPU-401, but this knowledge may help narrow things down.
I'm guessing there's a sequencing problem with the checking and waiting of the MPU read/write status bits, but I can't see it.
The text was updated successfully, but these errors were encountered: