Page 1 of 1

In-Game Trigger & Multitap

Posted: 26 Apr 2018, 19:30
by Pharfetchd
Hi Guys

I can get In-Game Trigger to work just fine when the controller is connected directly to the PC Engine but when using a multitap (PI-PD003 model) it doesn't work.

Has anyone else had any luck using the same multitap or perhaps a different model? just trying to narrow it down to whether it's an issue with my own multitap or just a feature that doesn't work when using one.

Re: In-Game Trigger & Multitap

Posted: 26 Apr 2018, 22:01
by Syn
I posted about it in games with issues and an explanation was given.

Hopefully an update down the road will fix it. As of right now, no it doesn't work.

EditThe in game trigger will improve in following firmwares, it currently doesn't work with multitap because it's making a lot of assumptions on the state the game leaves the gamepad controller. I wrote a small summary on how the trigger works and why it sometimes fails, and how we are working on fixing it, on some weeks ago, but it's probably worth copying it here for reference:

Let me explain how in game trigger works and why there is a big warning and it may cause issues.
In order for the trigger to work, custom code must be executed on the cpu. At first, I thought I could trap the gamepad read & writes on the fpga and do that transparently, without any extra code executed, but as the gamepad ports are directly connected to the cpu, their read and written valuew don't appear on the bus, so we had to move to a neosd like mode.
The fpga periodically signals the NMI line of the cpu right after vsync rises (end of vsync). No games or accesories use the NMI signal, so it was 'safe' to use. When the fpga sees an access to the nmi handler address (source of issues 1) that is logical address FFFC, if I remember correctly, that is physical address 1FFC (source of issues 2), it swaps the first memory bank to an internal one containing a piece of code that reads the input port (source of issues 3), checks if start+select are pressed and if it isn't just jumps back to the original vector (source of issues 4), disabling the overlay.

So, in well behaved games, it works as intended, but there are several sources of issues:

1) games unintentionally reading from physical address 1FFC will erroneously trigger the overlay, their bank 0 will get replaced, but because it was not an actual nmi trigger, the code won't be executed, the overlay will ne kept on and game will crash if trying to run code from bank 0. The fpga has no way of knowinf hf the access was a data read or a handler address read.

2) in order for nmi be at physical 1FFC, the address bank 7 must be set to memory bank 0. That's the default behavior, but some games change it (I think the NES xxx in 1 do). That makes the trigger code never be executed.

3) in order to keep the executed code to the bare minimum, if expects the gamepad state to be the 'buttons' state, and not the 'dpad' state. That's why the nmi is executed at the end of vblank, as games normally leave the port in that state. If game resets the port, the trigger won't work.

4) jumping back to the original game vector requires it to be implemented and do nothing that interferes with actual game working. Games that have code in the nmi handler that is not just an IRET may fail, as that code was never meant to be executed in user normal working. Why we return to the game code instead of doing an IRET? In some cases, when executing the IRET, the cpu reads from the address twice, so if then fpga disabled the overlay on the first read, the 2nd ond will read garbage and game will crash.

I've been thinking on ways to fix it, and these are the results:
Fixing 1 could be done by injecting the overlay directly into game code, patching the nmi to jump to an area that is always mapped and that has unused space so the fpga could inject its overlay (about 30 bytes) when it's accessed. It's not easy, but it's doable.

About 2, I'm afraid there is no way to fix it, games that remap page 0 won't work.

Fixing 3 is easy, just needs more code to be run on the trap to set the gamepad port to the right state.

Fixing 4 is also doable, the game just needs to jump back to a IRET in a page that is always mapped (like issue 1, but we just need 1 byte)

I think most crashes come from issue 1) but we've never been able to reliably reproduce it so I could capture it in the logic analyzer.

The main problem is that it will need a lot of time to make and test, but we can do that in future firmware updates.

Re: In-Game Trigger & Multitap

Posted: 27 Apr 2018, 14:39
by Pharfetchd
Thanks for the reply, I didn't think to look in that thread, Interesting explanation of how it all works.