The following information (and the ROM) are available at my website: http://daifukkat.su/hacks/grdforcel/ There is also a donation link, but don't feel obligated!
Success's hidden gem Guardian Force is a truly amazing game, but has one very unfortunate flaw: the program is extremely poorly optimized in terms of input latency. Even on the ST-V arcade hardware, the game has somewhere on the order of 6 to 7 frames of input lag. This is beyond the point of uncomfortable, and makes the game almost unbearably hard to control.
So, I had a feeling there would be some low-hanging fruit here. You don't get 6 to 7 frames of input lag if you're even remotely paying attention to how your inputs are handled. So, time to pop open IDA and MAME and get cracking. Turns out, yes there are at least 2 frames of easy-to-fix lag in software.
Here's a little tutorial on setting up the patch, since it's a little different from most things. But hopefully it should be obviously easier than most.
Installing
Burn the binary file (available on my website) to any 8-bit ROM with a similar pinout to the 27C010. The file size is very small, and this is the only ROM size required. So you could use a 27C020, 040, 080, etc. You don't need to even repeat the file for those ROMs, it's very forgiving.
Once your ROM is burned, open up the cart. You will see an empty EPROM socket on the cart's board, as shown below.
Simply put the ROM you've burned in that socket, and close it back up. That's it! Sega was very clever when they designed their carts, weren't they?
Dev Log
So with this, I had to figure out how the patch EPROM worked on the ST-V. It turns out it's really simple, all I really had to do was take the beginning of the regular ROM data and work some patching code into it. From there, I needed to find the sources of input lag and devise how to remove them. So, it's watchpoint time.
In the end, I traced the input data coming from the hardware through 2 interstitial buffers which were implemented by Success. We'll name the points here as:
We can look at these buffers in two ways: who fills them, and what order are they filled? If the buffers are used optimally (in a way which does not increase latency), these should essentially flow the exact same way. In Guardian Force's case, they literally flow the opposite.
For those paying attention, each one of these fills is introducing another frame of lag. The player's input code reads from smpc_parsed which isn't updated until after, meaning the data it is using is from the previous frame. The smpc_parsed buffer reads from smpc_buffer, which also isn't updated until after, meaning that too is reading the previous frame's buffer. smpc_buffer is the only one that isn't itself lagged, since hw_inp is always the current frame's data.
The obvious fix here is to invert the order of fills. In this way, each buffer reads from the buffer that was just filled, meaning it's still along the same frame's data. Thus, we remove 2 frames of input lag.
I'm sure there are more dumb sources of lag (it's still somewhere around 4 frames on hardware!), but this is such a massive improvement already that I figured it was worth posting.
Success's hidden gem Guardian Force is a truly amazing game, but has one very unfortunate flaw: the program is extremely poorly optimized in terms of input latency. Even on the ST-V arcade hardware, the game has somewhere on the order of 6 to 7 frames of input lag. This is beyond the point of uncomfortable, and makes the game almost unbearably hard to control.
So, I had a feeling there would be some low-hanging fruit here. You don't get 6 to 7 frames of input lag if you're even remotely paying attention to how your inputs are handled. So, time to pop open IDA and MAME and get cracking. Turns out, yes there are at least 2 frames of easy-to-fix lag in software.
Here's a little tutorial on setting up the patch, since it's a little different from most things. But hopefully it should be obviously easier than most.

Installing
Burn the binary file (available on my website) to any 8-bit ROM with a similar pinout to the 27C010. The file size is very small, and this is the only ROM size required. So you could use a 27C020, 040, 080, etc. You don't need to even repeat the file for those ROMs, it's very forgiving.

Once your ROM is burned, open up the cart. You will see an empty EPROM socket on the cart's board, as shown below.
Simply put the ROM you've burned in that socket, and close it back up. That's it! Sega was very clever when they designed their carts, weren't they?

Dev Log
So with this, I had to figure out how the patch EPROM worked on the ST-V. It turns out it's really simple, all I really had to do was take the beginning of the regular ROM data and work some patching code into it. From there, I needed to find the sources of input lag and devise how to remove them. So, it's watchpoint time.
In the end, I traced the input data coming from the hardware through 2 interstitial buffers which were implemented by Success. We'll name the points here as:
- hw_inp, the input data exposed directly from the hardware
- smpc_buffer, the input data which would normally come from Saturn pads
- smpc_parsed, the input data which is derived from smpc_buffer
We can look at these buffers in two ways: who fills them, and what order are they filled? If the buffers are used optimally (in a way which does not increase latency), these should essentially flow the exact same way. In Guardian Force's case, they literally flow the opposite.
Code:
Who fills who?
Hardware -fills-> hw_inp -fills-> smpc_buffer -fills-> smpc_parsed -fills-> Player's Input Code
What order are they filled?
Frame Start -> hw_inp -> Player's Input Code -> smpc_parsed -> smpc_buffer -> Frame End
The obvious fix here is to invert the order of fills. In this way, each buffer reads from the buffer that was just filled, meaning it's still along the same frame's data. Thus, we remove 2 frames of input lag.
I'm sure there are more dumb sources of lag (it's still somewhere around 4 frames on hardware!), but this is such a massive improvement already that I figured it was worth posting.
Last edited: