Closed socram8888 closed 3 years ago
The painting only affects the current drawing area.
If you want to fill a larger section of the vram, you'd need to first enlarge the clipping area:
https://github.com/nicolasnoble/pcsx-redux/blob/tiny-shell/src/mips/common/hardware/gpu.h#L132-L140 https://github.com/nicolasnoble/pcsx-redux/blob/tiny-shell/src/mips/shell/gpu.c#L38-L40
It's not happening on emulators because typically, emulators will only flip buffers when reaching an emulated vsync, so only a single buffer stays on.
I am not sure about that. The BIOS at that point has a drawing area configured to cover the entire viewfield, as it does not use double buffering:
E3 is X: 0 and Y: 0, while E4 is X: 639 Y: 479. Thus the fill would affect the entire image, not flicker like it does.
Oh, right. I've seen this actually. When the GPU is in 480i mode, and when it's not refreshing anymore properly, it'll still send the old frame on every other vsync.
One solution here would be to disable interlacing: https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gp108h-display-mode
Writing 0x08000000 to GP1 should suffice that is. We can do this in the second stage however, where we have more instructions to spare.
It's probably the best solution. I've spent since that message trying to come with solutions that would work in i480 and none has worked:
None has worked and the orange screen and tonyhax are totally bugged.
My current strategy in stage2 is just to reinitialize the GPU, really.
So in order to explain what's going on right now, I'm currently working on a 3-stage boot process:
stage 1 is the 128 bytes initial exploit payload stage 2 is a tiny bootstrap binary that's currently 8 frames long and would take about 300ms to load from stage 1, with the ability to reinitialize the GPU and has its own memory card routine that's much faster than the bios stage 3 is unirom that reboots the machine with the cop0 hook in order to properly reinitialize the kernel
For the record, I found the problem: the bit 10 of Texpage isn't set when the screen is painted orange. Setting texpage fixes the issue.
I'd recommend doing this instead of fully reinitializing the GPU issuing a command 0x00, as this will leave the GPU in the correct system's video standard (unless you remember this bit and set the correct standard also after reseting it).
int isPAL = (*((char *)0xbfc7ff52) == 'E');
Oh by the way, bit 10 of texpage is for interlace painting. The GPU is always in double buffer mode, that is. In 480i mode, the double buffering is done by masking every other line when drawing.
Not sure if it's worth adding or not, but if you use the backwards loading scheme I proposed we have enough space in the gpuWords array to fit in the texpage required to properly paint the screen in first stage:
diff --git a/builder/builder.cc b/builder/builder.cc
index 2c217eb..b455976 100755
--- a/builder/builder.cc
+++ b/builder/builder.cc
@@ -365,7 +365,7 @@ int main(int argc, char** argv) {
}
constexpr unsigned firstUsableFrame = 64;
- const bool backwards = args.get<bool>("bw", false);
+ const bool backwards = args.get<bool>("bw", true);
if (sp == 0) sp = 0x801ffff0;
unsigned frames = (tsize + 127) >> 7;
@@ -519,6 +519,7 @@ int main(int argc, char** argv) {
};
std::vector<uint32_t> gpuWords = {
+ 0xe1000400, // enable writing outside vsync
0x0200a5ff, // paint orange
0, // x, y
0x01ff03ff, // width, height
Tried it on the SCPH-102 and it works just fine.
So the stage2 now over in #14 is ready, and I'd say there is no longer any need for any visual feedback in stage1. On this branch, stage2 loads within ~400ms once stage1 starts its work, and stage2 will properly do a nice GPU reset and drawing, before loading stage3 using a custom method in ~7 seconds.
Alright, #11 has been merged, and all the fastload images have the new stage2 code. The non-fastload images are still there, but only in case something goes wrong. We'll probably just remove the non-fastload images eventually.
There's no longer any epilepsy-inducing flashes.
While the payload is loading, the screen is painted orange using the 0x02 GP0 command. This works perfectly fine on an emulator, but I got a very annoying flickering on real hardware which I am not sure what could be causing it.
This is also affecting tonyhax, which uses the same command for clearing the screen.