VOGONS


First post, by llm

User metadata
Rank Member
Rank
Member

im reversing a game that sends these bytes to an MT32/Munt
beware: im a first time Midi/MT32 "user" - all i want is to understand what these bytes are for so i can document it cleanly in the reversed code

Sysex message size 8,   data: F0 41 10 16 12   03                                 00   F7 
Sysex message size 11, data: F0 41 10 16 12 03 00 04 18 61 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 14 00 69 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 24 00 59 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 34 00 49 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 44 00 39 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 44 02 37 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 54 00 29 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 54 70 39 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 64 00 19 F7
Sysex message size 11, data: F0 41 10 16 12 03 00 74 02 07 F7

what i've know so far

[F0] Sysex-Start
[41] Roland ID
[10] Device ID
[16] Model ID (MT-32)
[12] Send
(03 00 04 18) Content ??? ???
(61) Checksum
[F7] Sysex-End

but i can find the meaning of the 03 ... content - any good documentation available

Last edited by llm on 2021-06-08, 08:38. Edited 2 times in total.

Reply 1 of 14, by llm

User metadata
Rank Member
Rank
Member

according to http://www.youngmonkey.ca/nose/audio_tech/syn … oland-MT32.html

the 4 bytes are:
(03) Address MSB
(00) Address
(04) Address LSB
(18) Data?

but the first example does not contain the 3 address bytes, is that sysex message illformed?

the only 03 00 addresses i find on the website are these

Whole Part (accessible on unit#)
Start Address Description
------------- ----------------------------
03 00 00 Patch Temp Area (part 1)
03 00 10 Patch Temp Area (part 2)
:
03 00 60 Patch Temp Area (part 7)
03 00 70 Patch Temp Area (part 8)
03 01 10 Set up Temp Area (rhythm part)

does that address targets the "Patch Temp Area" (whatever that is)?

so [03 00 44 02] sets the forth byte of the "Patch Temp Area (part 5)" to the value 02 - but what does that mean?

if found a reference to the Patch Temp Area on this page http://www.muzines.co.uk/articles/enhancing-y … oland-mt32/3500

Bytes 6,7,8: 03 00 06 Hex (or 3, 0, 6 Decimal). These three bytes form the address within the MT32's memory of the particular parameter we wish to alter. In our example you will see that page 9 of the MT32 MIDI Implementation Chart shows that the reverb switch is at offset 00 06 within the 'Patch Temp' area. Page 7 shows us that the Patch Temp area for Instrument part 1 has a base address of 03 00 00. Add together this base address and the offset address and you obtain 03 00 06.

so the question is: where can i find this: "MT32 MIDI Implementation Chart"

Reply 3 of 14, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
F0 41 10 16 12 03 00          F7	Incomplete message
F0 41 10 16 12 03 00 04 18 61 F7 Patch Temporary Area (part 1), BENDER RANGE = 24
F0 41 10 16 12 03 00 14 00 69 F7 Patch Temporary Area (part 2), BENDER RANGE = 0
F0 41 10 16 12 03 00 24 00 59 F7 Patch Temporary Area (part 3), BENDER RANGE = 0
F0 41 10 16 12 03 00 34 00 49 F7 Patch Temporary Area (part 4), BENDER RANGE = 0
F0 41 10 16 12 03 00 44 00 39 F7 Patch Temporary Area (part 5), BENDER RANGE = 0
F0 41 10 16 12 03 00 44 02 37 F7 Patch Temporary Area (part 5), BENDER RANGE = 2
F0 41 10 16 12 03 00 54 00 29 F7 Patch Temporary Area (part 6), BENDER RANGE = 0
F0 41 10 16 12 03 00 54 70 39 F7 Patch Temporary Area (part 6), BENDER RANGE = 112 <- This is not a valid setting
F0 41 10 16 12 03 00 64 00 19 F7 Patch Temporary Area (part 7), BENDER RANGE = 0
F0 41 10 16 12 03 00 74 02 07 F7 Patch Temporary Area (part 8), BENDER RANGE = 2

Reply 4 of 14, by llm

User metadata
Rank Member
Rank
Member
F0 41 10 16 12 03 00          F7	Incomplete message

incomplete means wrong here ?- does the MT32 just ignores such messages?

... F0 41 10 16 12 03 00 54 00 29 F7 Patch Temporary Area (part 6), BENDER RANGE = 0 F0 41 10 16 12 03 00 54 70 39 F7 Patch Te […]
Show full quote

...
F0 41 10 16 12 03 00 54 00 29 F7 Patch Temporary Area (part 6), BENDER RANGE = 0
F0 41 10 16 12 03 00 54 70 39 F7 Patch Temporary Area (part 6), BENDER RANGE = 112 <- This is not a valid setting
...

thanks for more details - now i can see how the information from http://www.youngmonkey.ca/nose/audio_tech/syn … oland-MT32.html gets combined
its from this table

Patch Temp […]
Show full quote

Patch Temp

Offset Address Description
-------------- -----------
00 00H 0000 00aa TIMBRE GROUP 0-3
(group A, group B, Memory, Rhythm)
00 01H 0000 00aa TIMBRE NUMBER 0-63
00 02H 00aa aaaa KEY SHIFT 0-48 (-24 - +24)
00 03H 00aa aaaa FINE TUNE 0-100 (-50 - +50)
00 04H 0aaa aaaa BENDER RANGE 0-24 <--------------
00 05H 000a aaaa ASSIGN MODE 0-3

and the valid values range is 0-24

00 04H              0aaa aaaa     BENDER RANGE 0-24

i see the range of 0-24 but the bit mask there is "0aaa aaaa" = 7 useable bits, that would mean a 0-127
in this (non searchable) https://www.deepsonic.ch/deep/docs_manuals/ro … t-32_manual.pdf on page 44 is the bender range also 0-24 with bitmask 000aaaaa so 0-31 according to the bits, maybe original dev just got it wrong

any idea how the MT32 reacts to the 112 value?

is there any other source than http://www.youngmonkey.ca/nose/audio_tech/syn … oland-MT32.html - to recheck the given information?

Reply 5 of 14, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
llm wrote on 2021-06-08, 18:21:
incomplete means wrong here ?- does the MT32 just ignores such messages? […]
Show full quote
F0 41 10 16 12 03 00          F7	Incomplete message

incomplete means wrong here ?- does the MT32 just ignores such messages?

Correct. The MT-32 will throw an "Exc. Checksum error" message, but the SysEx string is otherwise non-actionable.

F0 41 10 16 12 03 00 54 70 39 F7 Patch Temporary Area (part 6), BENDER RANGE = 112 <- This is not a valid setting

any idea how the MT32 reacts to the 112 value?

The maximum valid bender range value of 18h, or 24 is applied.

Reply 6 of 14, by llm

User metadata
Rank Member
Rank
Member

your feedback helped alot, thanks!

time to understand why the game sends this wrong value and the incomplete message

replay question: would it be enough to trace all the send sysex messages + timestamp to replay the music with Munt (using some code for the timing and calling Munt)?

Reply 7 of 14, by sergm

User metadata
Rank Oldbie
Rank
Oldbie
llm wrote on 2021-06-09, 06:59:

time to understand why the game sends this wrong value and the incomplete message

Not sure this is possible 😀
But a few common reasons do exist. Typically, the composer works with a different hardware that may send some bogus data. It may happily remain unnoticed unless it disturbs the audio composition, as in this case.

replay question: would it be enough to trace all the send sysex messages + timestamp to replay the music with Munt (using some code for the timing and calling Munt)?

If you mean timestamping of the short MIDI messages, then yes, it works fine in most cases. Albeit when it comes to reversing, some want to re-create the exact music file format utilised in the game. An easy way that always works is to capture each game track to a separate MIDI file, and then play with a MIDI player. Standard MIDI files contain all sysex and short MIDI messages timestamped already.

Reply 8 of 14, by llm

User metadata
Rank Member
Rank
Member
sergm wrote on 2021-06-10, 07:37:
llm wrote on 2021-06-09, 06:59:

time to understand why the game sends this wrong value and the incomplete message

Not sure this is possible 😀
But a few common reasons do exist. Typically, the composer works with a different hardware that may send some bogus data. It may happily remain unnoticed unless it disturbs the audio composition, as in this case.

this case seem to be easy - there is a simple algorithm that creates PatchTemporaryArea/Bender-range set msgs - and it seems that the calculation is just buggy - sometimes the msg size is wrong
and the wrong value is also calculated inside - seem to be some sort of overflow of the logic

sergm wrote on 2021-06-10, 07:37:
llm wrote on 2021-06-09, 06:59:

replay question: would it be enough to trace all the send sysex messages + timestamp to replay the music with Munt (using some code for the timing and calling Munt)?

If you mean timestamping of the short MIDI messages, then yes, it works fine in most cases. Albeit when it comes to reversing, some want to re-create the exact music file format utilised in the game. An easy way that always works is to capture each game track to a separate MIDI file, and then play with a MIDI player. Standard MIDI files contain all sysex and short MIDI messages timestamped already.

how can i caputer each track to a separated MIDI file - is that possible with Munt? or do i need to added some sort of midi logging to the dosbox source code?

Reply 9 of 14, by sergm

User metadata
Rank Oldbie
Rank
Oldbie
llm wrote on 2021-06-10, 08:11:

this case seem to be easy - there is a simple algorithm that creates PatchTemporaryArea/Bender-range set msgs - and it seems that the calculation is just buggy - sometimes the msg size is wrong
and the wrong value is also calculated inside - seem to be some sort of overflow of the logic

Oh, yeah. Such things may happen too 😀

how can i caputer each track to a separated MIDI file - is that possible with Munt? or do i need to added some sort of midi logging to the dosbox source code?

You can easily do that either using DOSBox MIDI capture function or the "Record" button in the mt32emu-qt. Still, you likely have to edit the end result to start-stop at sane positions, to be playable in a loop, etc.

Reply 12 of 14, by llm

User metadata
Rank Member
Rank
Member
Spikey wrote on 2021-06-12, 12:32:

Obvious question - which game is this?

Stunts: https://www.mobygames.com/game/dos/stunts

im reverse engineering and porting the MT15.DRV file (the MT32 sound plugin) of stunts to C source - because there a differences/bugs between the game versions and i want to build a unified/bug free version

http://forum.stunts.hu/index.php?topic=3767.m … g80408#msg80408: the documented and combined versions DRV asm source + build description
http://forum.stunts.hu/index.php?topic=3767.m … g80433#msg80433: my first partially C ported version

Reply 13 of 14, by llm

User metadata
Rank Member
Rank
Member

MT32 Patch Memory address

i've got a problem to understand a address jump in the Patch Memory address calculation

the problem is that the Stunts game does not trigger that code - just not enough midi stream in a data file
maybe old, maybe for another game of the company

can anyone explain why there is this address jump at {0x05, 0x00, 0x78}

  • is the Patch Memory address not just linear?
  • some sort of 128 byte segments in the MT32?
  • just wrong code (that, based on the given data, can never get called)?
  • any "musical/sound" intention - different sound results etc.?

these are the addresses generated by the calculation (if there where enough data to trigger the address jump) - in hex

05 00 00
05 00 08
05 00 10
05 00 18
05 00 20
05 00 28
05 00 30
05 00 38
05 00 40
05 00 48
05 00 50
05 00 58
05 00 60
05 00 68
05 00 70
05 00 78
<-----------------------------
05 01 00
05 01 08
05 01 10

my assembler code which produces the exact same binary

mt32_patch_memory_t struc ; (sizeof=0x08)
timbre_group db ? ; 0:group A, 1:group B, 2:Memory, 3:Rhythm
timbre_number db ? ; 0-63
key_shift db ? ; 0-48 [-24...+24]
fine_tune db ? ; 0-100 [-50...+50]
bender_range db ? ; 0-24
assign_mode db ? ; 0:POLY1, 1:POLY2, 2:POLY3, 3:POLY4
reverb_switch db ? ; 0-1 (OFF,ON)
dummy db ?
mt32_patch_memory_t ends

...

label0:
; bytes forming a Patch Memory address
; address = {5, patch_memory_address_byte1, patch_memory_address_byte2}

; ...

mov al, patch_memory_address_byte2
add al, sizeof mt32_patch_memory_t
mov patch_memory_address_byte2, al

and al, 80h
jz short label1

xor al, al
mov cs:patch_memory_address_byte2, al
inc cs:patch_memory_address_byte1

label1:

; ...

jmp label0