Possibly, though that is not necesarily verified.About Valkyrie Profile 2: Silmeria
So that seems that titles like this one install their own service routines, therefore overwriting our 'DisplayHandler' one, huh!
You'd get much the same effect if most of the code is executed with all traps disabled, so that we can't trap the register accesses when they occur. This could happen because they've moved the code for vmode changes inside trap code of their own, in much the same way as our own register writes inside our own trap code do not cause any additional trapping (a necessary block to prevent eternal recursion).
So even if they leave our trap code untouched, they may still have inhibited the trapping, simply by executing the vmode changes in such a trapped state.
----- snip ----- re: additional trap to protect DisplayHandler linkWell, how we could deal with this issue?
Here an another idea: Maybe we could extend our service routine features to avoid be overwritten (a self-protection code)!
I too have though on the lines of code to either protect the DisplayHandler link or repair it after interference, but then I thought of that other possibility I mentioned, that both link and codes are intact though blocked from execution by the current CPU trap state at the time the game writes to the GS registers. And I can't see any cure at all for that variation...So, every time that a code from the User Mem Area range (i.e. from 0x00100000 until 0x01FFFFFF) tries to remove or disable the GSM access trap link, we could put "nop" (no operation) into these offensive addresses. This extension of trap service routine could be turned off after n execution cycles, in order to avoid to freeze that game or reduces its speed.
Also, even if it is a simple case of unlinking, the game probably does that for some reason, which could mean that the game code needs to use that trap for some purpose of the game engine. In that case our interfering with such a link could completely ruin the intended effect, by preventing that game engine code from working as it should.
One solution to this would be if we instead found a way of 'chaining' their trap routine to our own, so that ours gets executed first, but if not affecting the registers we guard we then pass the trap call on to the routines of the game, in exactly the same state as if they had been called directly. This should allow all game engine work that depends on this trap to work normally, while still allowing us to catch the GS register accesses.
But of course, we must also be aware of yet another possible complication, which is that a game engine might have more than one such trap routine, alternating between them depending on current in-game needs. So we must be ready for new 'traplinking' even after we have dealt with one, and patch read and writes accordingly.
So for reads we should return whatever value the game wrote previously to that traplink, as stored in a local variable and for writes we should save it internally to the same variable for use in 'chaining' from our DisplayHandler routine to the game's register trap code whenever we are done with our register trap processing.
This could solve many of the potential problem cases, though a few remain.
The foremost problem of that kind is the one I mentioned above, of us needing to trap accesses made with traps disabled. But like I said, that's one problem I don't see any way to solve.
Another problem is if register or address trap code used by a game also modifies GS registers. For such cases the method I mentioned above, of jumping to the game's trap handler after DisplayHandler work could malfunction, as the other trap handler can then overwrite GS register changes directly after we make them. And this too is a problem I see no solution to, as what we'd need is to reverse the order so the other trap handler executes before our DisplayHandler, and if done that way the other trap would just terminate the trap without chaining to ours. So to get any chaining at all, we'd have to put our DisplayHandler first in the chain, meaning that the other one 'gets the last word' if/when patching the same registers. (Hmmm. On second thought, a variation of the chaining method could possibly fix this. Using a simulated return address leading to part2 of our own handler, with part1 simply chaining to the trap code of the game after preparing the simulated return address. That should work.)
These problems are worth thinking about some more, and also worth making some experiments to determine which of these potential cases we really have to deal with, for this and some other problematic games. (A large proportion of which come from Square-Enix.)
Best regards: dlanor