GP32 Wierd Screen Wrap Bug


pea

developer
Joined
Oct 3, 2004
Messages
1,089
Age
46
Location
New Zealand
Website
www.projectitis.com
Hi all,

I have heard mention of this before (though it was in DrMD I think), and am wondering if anyone knows the cause.

I have an image on the LCD, and am moving a couple of sprites across it in a loop. Randomly, only sometimes, the screen will sort of crap out for a split second with white and black lines, and then reappear with the screen position offset down and to the right, so that part of the right appears on the left, and part of the bottom appears at the top! Nothing crashes or freezes, but the screen remains like this until I reset the GP! I don't do ANY playing around with the framebuffer pointer...

e.g. Its a bit hard to illustrate, but something like this:
11112222
11112222
33334444
33334444
appears like this:
44333344
22111122
22111122
44333344

any ideas?
 
This happened to me sometimes with Dizzy Dice, but after compiling it with different cflags it disappeared... I dunno why....
 
my game had that bug aswell, very wierd as i wasn't doing anything out of the ordinary with the framebuffer. Now i think i changed something that made it go away, but then again it pretty rare so it might still be there.
(i'm using mirkos btw)
 
Hi all,

I have heard mention of this before (though it was in DrMD I think), and am wondering if anyone knows the cause.

I have an image on the LCD, and am moving a couple of sprites across it in a loop. Randomly, only sometimes, the screen will sort of crap out for a split second with white and black lines, and then reappear with the screen position offset down and to the right, so that part of the right appears on the left, and part of the bottom appears at the top! Nothing crashes or freezes, but the screen remains like this until I reset the GP! I don't do ANY playing around with the framebuffer pointer...

e.g. Its a bit hard to illustrate, but something like this:
11112222
11112222
33334444
33334444
appears like this:
44333344
22111122
22111122
44333344

any ideas?

Yes this is the "split-screen" bug that DrMD used to have. I found it was caused by messing with the LCD registers at the wrong time. When you say your not playing around with the frame buffer, does that mean you not currently double buffering the screen?
 
Last edited by a moderator:
Code:
void gp_setFramebuffer(void *add,int vsync) {
   u32 addr = (u32) add;
   u32 LCDBANK  =  addr >> 22;
   u32 LCDBASEU = (addr & 0x3FFFFF) >> 1;
   u32 LCDBASEL;

   u16 vidmode = ((rLCDCON1>>1) & 15)-8;   // result in 0,1,2,3,4
   const u16 faktor[]= {15,30,60,120,240,480,480};

   LCDBASEL  = LCDBASEU + 320*faktor[vidmode];

   // wait until lcd is in front porch or hsync before updating lcd regs
   // as screen will be distorted

   while(1==1)
   {
	if(((rLCDCON5>>17)&3)==2) break; // wait for active line 
   } 
   while(1==1)
   {
	if(((rLCDCON5>>17)&3)!=2) break; // wait for active line to end - start of front porch and hsync
   } 
   
   // now switch
   rLCDSADDR1 = (LCDBANK<<21) | (LCDBASEU<<0);
   rLCDSADDR2 = (LCDBASEL<<0);
   //rLCDSADDR3 = (OFFSIZE<<11) | (PAGEWIDTH<<0); // only update this once now when framebuffer is initialised
   if (vsync) gp_waitVsync();
}

Above is my modified version of mr.mirko's gp_setFramebuffer() function. As you can see I've added a wait for hblank. I've also removed the update of rLCDADDR3 as this does not need to be updated here as it only gets change in gp_initFramebuffer().

This seems to have fixed all of the split-screen bug problems I was having. I passed this tip onto Rlyeh as well and it seems to be working for his emulators as well.

Reesy
 
I'm using GPSDK to fondle the palette in 256 color mode and calling GpPaletteEntryChange() with GPC_PAL_SYNC_REALIZE
you can bet the screen goes from ...

11112222
11112222
33334444
33334444

and becomes ...

33334444
11112222
11112222
33334444

There is no double-buffering at the same time!
Is this 'porch waiting' a fix for this too?


btw. Does changing (((rLCDCON5>>17)&3)==2) to ((rLCDCON5&(3<<17))==(2<<17)) optimize it as the shifts become constants?
maybe GCC sees this and has already done it for you, but maybe not :huh:
maybe it doesn't need to as the ARM can load and shift :unsure:
Sorry! Just my 8-bit thinking :lol:
 
yep, that would be faster. I haven't bothered with optimizing , I've just been trying to find something that works, but thanks for the heads up.
 
Thanks heaps Reesy. will add this in right away

BTW:
btw. Does changing (((rLCDCON5>>17)&3)==2) to ((rLCDCON5&(3<<17))==(2<<17)) optimize it as the shifts become constants?
I thought this was quite amusing, as all the code is doing here is waiting anyway :) All it will do is wait a little faster :D :p haha!
 
LOL! Why did y'all focus on that bit :S (It may be applicable elsewhere and was a general pondering about ARM and GCC -- honest! :lol: )

Anyway! Do you think that the same fix can be welded in to sort out the screen 'rolling' when messing with the palette?
That is .. do the palette functions mess with those registers in the same way?
 
Anyway! Do you think that the same fix can be welded in to sort out the screen 'rolling' when messing with the palette?
That is .. do the palette functions mess with those registers in the same way?

Mr mirkos sdk does not allow palette updates while the VSTATUS is in active mode, I'm not sure if if this is to fix any problems.

I personally update the palette anytime I feel like it, in version 1.0 of DrMD the emulator updates each palette entry when ever the MD pal is modified. I've never noticed any problems with it, anybody else? Anybody else know the reason why mr mirko's sdk has this control, maybe I've missed something.
 
Last edited by a moderator:
The S3C2400 data sheet says that palette registers must not be updated during ACTIVE phase of the LCD controller, but (like so many other things) it doesn't say why, or what will happen if you break the rule.

It was very clever of Reesy to use HBlank instead of VBlank for updating the LCD registers! Waiting time is much reduced. A couple of things I can think of that might still trip it up:

1) Interrupts should be disabled while waiting and updating the registers, because an interrupt will disturb the timing and may allow the split-screen bug to happen;

2) What is the status of HSTATUS while VSTATUS is front porch / VSync / back porch states? If it doesn't update like it does during the vertical active phase, then if your wait happens to occur during the vertical inactive phase, you'll end up waiting longer.

Maybe some extensions could be made to the code to handle these cases, or then again it might be "good enough" as it is.

By the way, pea, where are you? I'm in Christchurch :)
 
Hmm, perhaps is the interrupts for you then kissbengt?

Robster - I'm in Palmy North. Not the nicest place in NZ, but home for now. CatMince (who was with us briefly) is from down your way (closer than me anyway), Dunedin, I think. He's currently selling his GP on trademe.

BTW, what are 'front porch' and 'back porch'?
 
Front Porch is the period after the LCD has finished drawing the current line just before the HSYNC period.

Back Porch is the period after HSYNC just before the LCD draws the current active line.

Have you had any more split-screen problems on your program since you applied this fix, I'm just interested to know.

Thanks

Reesy
 
Sorry Reesy, haven't been testing much to know if there is still a problem. In the process of drawing the level graphics for my current game. Will let you know. Thanks for the info BTW
 
Forget about this post.
Just read Reesys respones to another question.
Sorry.





Code:
void gp_setFramebuffer(void *add,int vsync) {
   u32 addr = (u32) add;
   u32 LCDBANK  =  addr >> 22;
   u32 LCDBASEU = (addr & 0x3FFFFF) >> 1;
   u32 LCDBASEL;

   u16 vidmode = ((rLCDCON1>>1) & 15)-8;   // result in 0,1,2,3,4
   const u16 faktor[]= {15,30,60,120,240,480,480};

[right][/right]
[/quote]


Out of curiousity, is there any reasn for using 
        ((rLCDCON1>>1) & 15)-8

instead of

        ((rLCDCON1>>1) & 7)   ?


Salut,
 CreatureXL
 
Last edited by a moderator:
Above is my modified version of mr.mirko's gp_setFramebuffer() function. As you can see I've added a wait for hblank. I've also removed the update of rLCDADDR3 as this does not need to be updated here as it only gets change in gp_initFramebuffer().

This seems to have fixed all of the split-screen bug problems I was having. I passed this tip onto Rlyeh as well and it seems to be working for his emulators as well.

Reesy


Split-screen? As in the whole screen is rolled vertically about 120 pixels?
AAAAA
BBBBB
CCCCC
DDDDD

is shown as:
CCCCC
DDDDD
AAAAA
BBBBB

I saw that a few times as well when I was playing around with Mr Mirko's SDK.
Is that the same thing you are talking about here?
 
Last edited by a moderator:
Forget about this post.
Just read Reesys respones to another question.
Sorry.
Pardon? What do you mean? Which post?

Split-screen? As in the whole screen is rolled vertically about 120 pixels?
Yip. I've had vertical rolling by 120 pixels, and also a variation where it also rolls horizontally by about 120 pixels as well.
 
Back
Top