gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > 8-bit writes to VRAM

#17287 - poslundc - Fri Mar 05, 2004 9:13 pm

I've been playing around a little, investigating the rule that you can only write 16 bits at a time to VRAM.

It seems that when I issue a strb command, the bottom 8 bits get repeated for the top 8 bits of the halfword as well. Does anyone care to confirm my findings here?

I'm curious about what happens when you attempt to access a character array from C that's located in VRAM. Does it behave the same way that the strb command behaves? What about when reading from VRAM?

Thanks,

Dan.

#17291 - torne - Fri Mar 05, 2004 9:23 pm

It should behave just the same in C, as the compiler does not know that 8-bit accesses are not possible. This is why you need to declare VRAM as an array of wider types =)

#17292 - tepples - Fri Mar 05, 2004 9:25 pm

poslundc wrote:
It seems that when I issue a strb command [with a VRAM destination address], the bottom 8 bits get repeated for the top 8 bits of the halfword as well.

Correct. When telling the memory controller to write a byte value ('strb'), the ARM7 core duplicates the byte through D0-D31 of its data bus. A memory controller that doesn't support byte writes (such as the GBA memory controller in address range 0x05000000-0x0dffffff) will pick up D0-D15 or D16-D31 and treat it as a 16-bit word.

Quote:
I'm curious about what happens when you attempt to access a character array from C that's located in VRAM. Does it behave the same way that the strb command behaves?

Given that accessing a 'char' array from C compiles to 'strb' instructions, yes.

Quote:
What about when reading from VRAM?

Given how the ARM7 data bus works, I would take an educated guess that reading VRAM should work as one would naively expect. Remember that ROM has the same restriction of no 8-bit writes because the cart's write enable isn't split into low-byte and high-byte lines, yet 'ldrb' and 'ldrsb' from ROM work fine.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#17295 - tepples - Fri Mar 05, 2004 9:39 pm

torne wrote:
It should behave just the same in C, as the compiler does not know that 8-bit accesses are not possible. This is why you need to declare VRAM as an array of wider types =)

I'll reproduce the bits of my header file that deal with VRAM:
Code:

typedef unsigned short u16;
typedef unsigned int   u32;

#define VRAM   ((u16 *)0x06000000)  /* 0xc000 words */

/* Pattern tables */

#define PATRAM(x) ((u32 *)(0x06000000 | ((x) << 14)))
#define PATRAM4(x, c) ((u32 *)(0x06000000 | (((x) << 14) + ((c) << 5)) ))
#define PATRAM8(x, c) ((u32 *)(0x06000000 | (((x) << 14) + ((c) << 6)) ))
#define SPR_VRAM(x) ((u32 *)(0x06010000 | ((x) << 5)))

/* Nametables */
typedef u16 NAMETABLE[32][32];

#define MAP ((NAMETABLE *)0x06000000)

For example, tile 137 of pattern table 2 is PATRAM4(2, 137)[] or PATRAM8(2, 137)[] depending on the bitdepth, and location (15, 10) of non-rot/scale map 31 is MAP[31][10][15].
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#17298 - Miked0801 - Fri Mar 05, 2004 9:52 pm

I have found the same thing (8-bit writes get repeated to 16-bits). I wasn't able to use it for an optimization though. Doesn't happen on reads though