Close

Patching Muhonmourn 3

danjovicdanjovic wrote 11/05/2022 at 19:59 • 8 min read • Like

The game Muhonmourn 3 is a multiplayer game developed developed by [hoge1e3] as an entry to MSXDev22 contest. The game allows up to 4 players, being two on keyboard (using arrow keys and WASD) and two on the joystick ports.

The game dynamics is simple but very addictive. On every match you have 60 seconds to control your player to cover as many ground as you can during 60 seconds.

 I wish this kind of game existed when I was young, on the occasion when we, our brothers and friends get together to play video-games.

Today this is a game that is perfect for retro meetings and that was my motivation to research about the obscure peripheral named Ninja Tap that allows to use up to 4 joysticks by port, in other words a multi-tap adapter.

At the beginning there was no much information about this peripheral, and I have started to look for information on how to reproduce such peripheral and find out how it works and how to write software for it. The whole story is on a series of pages here in hackaday.io (btw, thanks [Jipe] and [aoineko] )

Also there's two (long)  threads about the device:

Now the Ninja Tap is not an obscure peripheral anymore. It is being reproduced by a user from MSXVillage.

And there is also my Shinobi Tap prototype for "generic" NES controllers with DE-9,


Note: Both Shinobi Tap and an extended version of Ninja Tap named Ninja Towns are available at github in eagle 7 format.

Developing the patch

Having unearthed the peripheral now it is time to get back to the software side and build the patch

Disassembly

The first step to make the patch was to disassemble the game which is available at the MSXDev22 page. Oh, and it is possible to play online using a web emulator.

The game is a binary that is loaded from address 0x8000 up to the 0xD397. I have used inkland's dz80 to do the disassembly.

Next steps were to find references for the BIOS routines that read the keyboard and the joysticks.

Some games may also read the controllers directly using the Z80 instructions IN and OUT (that was not the case).

It was found a function starting at 0x865c that reads the eleven rows of the keyboard matrix using SNSMAT routine. The readings are inverted so a pressed key is represented by a "1".

Then the game reads both both joystick ports using GTSTCK and GTTRIG. The directionals are used on a table entry to convert the value read from bios in the range 0..8 to the four upper bits representing each directional with active level in  "1". Then the triggers A and B are added to the bits 0 and 1 respectively. The position of these bits corresponds to the row Y8 of the keyboard matrix.

The scan is stored into 13 consecutive bytes starting at 0x86b9

The Patch

The patch code consists of a jump to a function placed after the main game code that perform the following steps

  1. Check the presence of a Ninja/Shinobi Tap on joystick port 1 ( only port 1 to simplify the code)
  2. Return to execute original code if a tap is not detected, otherwise..
  3. Read the Taps
  4. Convert Tap 1 data to  "RG DW UP LF 0  0  TB TA" and store at 0x86c1 (row 8)
  5. Convert Tap 3 data to  "RG DW UP LF 0  0  TB TA" and store at 0x86c4 (Joystick 1)
  6. Convert Tap 4 data to  "RG DW UP LF 0  0  TB TA" and store at 0x86c5 (Joystick 2)
    steps 4,5,6 conversions are performed by a lookup table that uses the 4 least significant bits as the entry, followed by the bit test of the trigger buttons
  7. Get Tap 2 data an fulfill WASD positions at keyboard rows rows 2, 3 and 5

  8. finally return to the game.


The full code is available at Github.

Troubleshooting

During the debugging it was found that during the game execution, the area between 0xd400 and 0xDF92 was fullfilled with data, then the patch start address was changed to 0xE000 and it was compiled as a different module, to be loaded before the game.

The game patch itself consists in changing 3 bytes at offset 0x0670 wich is equal to 0x8669 minus 0x8000 that is the address at which the game is loaded and add 07 bytes for the header of the binary file.

And the Basic loader is presented below, considering "m" the MSX binary file for the patch and "q" the binary file of the patched game

A second "bug" that was found is that I have completely forgotten that I have considered to use the joystick port 2 to connect the Ninja/Shinobi tap, but the emulator I am running to perform the tests (openMSX) can only emulate the Ninja Tap at joystick port 1.

The fix is only change the value of DE register prior to call GETNIN function (step 3)

A third (and I hope) last bug that was fixed was related with the activation of the RIGHT direction on Tap 2, that should set the bit 1 to activate the  "D" key, but it was setting the bit 2. That was fixed too.


For the moment, that's all.

The sources and the disk image can be found at github.

Enjoy!

Like

Discussions