Volatile now required for access to SRAM/VRAM unlike past versions
Posted: Mon May 23, 2022 7:36 pm
I just wanted to give a heads up to anyone experiencing this. I only caught this because of warnings from the NO$GBA debugger.
In past versions of DevKitArm, you could write code like this:
In past versions of DevKitArm, this code would compile so that only 8 bit memory access would be performed to that memory, so you could use such code for the SRAM memory area.
This is no longer the case. The compiler will now either replace this with a call to "memset", or will generate code that does 32-bit writes to memory. So this code can no longer be used as-is to access the SRAM memory area.
You now need to use "volatile" on your pointer to prevent the compiler from being allowed to use a larger read or write size.
This even applies to VRAM, in some cases, the compiler will decide to perform 8-bit writes, even if your code did not use any such writes.
A snippet of some code:
In this snippet, the compiler detected a series of writes in a loop, and changed it to memset. The code inside memset saw that the pointer was not aligned to a dword boundary, so it performed 8 bit writes to VRAM.
So now all access to VRAM or SRAM must be done through volatile pointers, otherwise the compiler is free to pick memory access that is incompatible with the actual hardware.
In past versions of DevKitArm, you could write code like this:
Code: Select all
void ByteSet(char *p, char value, int size)
{
while (size)
{
*p++ = value;
size--;
}
}
This is no longer the case. The compiler will now either replace this with a call to "memset", or will generate code that does 32-bit writes to memory. So this code can no longer be used as-is to access the SRAM memory area.
You now need to use "volatile" on your pointer to prevent the compiler from being allowed to use a larger read or write size.
This even applies to VRAM, in some cases, the compiler will decide to perform 8-bit writes, even if your code did not use any such writes.
A snippet of some code:
Code: Select all
u16 *here=(u16*)0x06000000+(row&0x1F)*32;
int i = 0;
u16 space;
...
for(;i<29;i++)
{
here[i] = space;
}
So now all access to VRAM or SRAM must be done through volatile pointers, otherwise the compiler is free to pick memory access that is incompatible with the actual hardware.