Welcome! Log In Create A New Profile

Advanced

Writing to the XFB -- when is it doable properly?

Posted by Mega_Mario 
Writing to the XFB -- when is it doable properly?
March 23, 2013 06:00PM
This is about our SMG2.5 project again. We want to attach a debug screen to the game so we can diagnose crashes we encounter while designing levels.

The crash handler is hooked to the game's internal panic function (a function that enters an endless loop) and a few useful PPC exception vectors (ISI, DSI and two others).

When entered, the crash handler turns audio off (because in most crashes, the game is still playing sound, which ends up rather ear-raping). It then retrieves the address of the current XFB via the VI regs, and writes there to display the crash report.


I am currently testing the display aspect inside a Wii homebrew. It currently fills the XFB with blue, then writes some text. Getting the XFB address works fine, however writing to it is more problematic.

I have interrupts disabled during the whole process to prevent them from messing with stuff badly.

Of course, filling the XFB works fine under Dolphin because it's inaccurate. However, on a Wii, the first half of the screen is filled properly, and the bottom half is almost fully black, with a few blue lines/blocks here and there.

I figured that this happens because the XFB can't be written to while the VI is reading from it. However, I haven't found a way to either keep the VI from accessing the XFB at all, or detect the start of the VBlank without interrupts.

Bit0 of the VI control register (0xCC002002) supposedly controls 'video timing generation and data request'. However changing it has no effect. Setting the VI timing register (0xCC002000) has no effect either.

The Y position register also seems to work weirdly or not work at all.


Basically, is there a way to keep the VI from accessing the XFB? 'Forcing blank' like it's called on some consoles?
Re: Writing to the XFB -- when is it doable properly?
March 24, 2013 12:58AM
If it's for a crash log only, why not use a different area of memory to create your blue screen of death and then put the address in the XFB register when it's ready for display?
Re: Writing to the XFB -- when is it doable properly?
March 24, 2013 04:47AM
It sounds like you're using the cached address.
Re: Writing to the XFB -- when is it doable properly?
March 24, 2013 12:51PM
Quote
tueidj
If it's for a crash log only, why not use a different area of memory to create your blue screen of death and then put the address in the XFB register when it's ready for display?
I considered it. Only issue is that it'd take about 614K of RAM, and I want my debug screen code to be the smallest possible, to not steal too much RAM to the game itself.

One possibility, however, would be to take from the game's heap...

Quote
Extrems
It sounds like you're using the cached address.
I didn't think about the CPU cache, and hey it makes a whole lot of sense. I'm going to try with an uncached address.

I might also want to look into how to disable the cache, as I'm not sure that SMG2 uses the same cache setup as libogc...


Thanks for the replies anyway!


Edit- I changed my code to add 0xC0000000 to the physical XFB address instead of 0x80000000. The screen was properly filled, but not the right color, and the characters were half broken. As if the writes were still failing 1/4 of the time or something....

I figured that perhaps 8-bit writes don't work that well, and changed the code to use 32-bit writes. That resulted in a black screen.



Edited 1 time(s). Last edit at 03/24/2013 04:25PM by Mega_Mario.
Re: Writing to the XFB -- when is it doable properly?
March 25, 2013 01:24AM
Quote
Mega_Mario
I considered it. Only issue is that it'd take about 614K of RAM, and I want my debug screen code to be the smallest possible, to not steal too much RAM to the game itself.

One possibility, however, would be to take from the game's heap...
But if it's for a crash dump the memory doesn't need to be held in reserve, it can be taken from plenty of places since the game is no longer going to run...

Quote

I didn't think about the CPU cache, and hey it makes a whole lot of sense. I'm going to try with an uncached address.

I might also want to look into how to disable the cache, as I'm not sure that SMG2 uses the same cache setup as libogc...
You definitely don't want to disable either cache (instruction or data). Nearly all wii games use identical cache/BAT setup and libogc copied it so it shouldn't be an issue.

Quote

Edit- I changed my code to add 0xC0000000 to the physical XFB address instead of 0x80000000. The screen was properly filled, but not the right color, and the characters were half broken. As if the writes were still failing 1/4 of the time or something....

I figured that perhaps 8-bit writes don't work that well, and changed the code to use 32-bit writes. That resulted in a black screen.
You can only use 32-bit writes with uncached memory unless you really know what you're doing - basically any writes smaller than 32 bits will get repeated within their 8-byte region. It's also horribly slow.
Write to XFB cached memory then use DCFlushRange (when you've completed the entire XFB) to make sure the physical memory is updated.
Re: Writing to the XFB -- when is it doable properly?
March 25, 2013 08:35PM
Quote
tueidj
Quote
Mega_Mario
I considered it. Only issue is that it'd take about 614K of RAM, and I want my debug screen code to be the smallest possible, to not steal too much RAM to the game itself.

One possibility, however, would be to take from the game's heap...
But if it's for a crash dump the memory doesn't need to be held in reserve, it can be taken from plenty of places since the game is no longer going to run...
Right. I could take it, say, at the end of the game heap...

Quote
tueidj
Quote

I didn't think about the CPU cache, and hey it makes a whole lot of sense. I'm going to try with an uncached address.

I might also want to look into how to disable the cache, as I'm not sure that SMG2 uses the same cache setup as libogc...
You definitely don't want to disable either cache (instruction or data). Nearly all wii games use identical cache/BAT setup and libogc copied it so it shouldn't be an issue.
Indeed. I figured I wasn't going to take unneeded overcomplication unless SMG2 used a different cache/memory setup than other games. I was just considering it as one of the last-resort options.

Quote
tueidj
Quote

Edit- I changed my code to add 0xC0000000 to the physical XFB address instead of 0x80000000. The screen was properly filled, but not the right color, and the characters were half broken. As if the writes were still failing 1/4 of the time or something....

I figured that perhaps 8-bit writes don't work that well, and changed the code to use 32-bit writes. That resulted in a black screen.
You can only use 32-bit writes with uncached memory unless you really know what you're doing - basically any writes smaller than 32 bits will get repeated within their 8-byte region. It's also horribly slow.
Write to XFB cached memory then use DCFlushRange (when you've completed the entire XFB) to make sure the physical memory is updated.
That seems like a perfect idea! I'm going to try it out.


Edit- yes, the cache was the issue there. Thanks!



Edited 2 time(s). Last edit at 03/29/2013 12:54AM by Mega_Mario.
Sorry, only registered users may post in this forum.

Click here to login