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 > numeric value to memory location... what truly happen?

#89184 - king501 - Fri Jun 23, 2006 1:27 pm

I would like to understand what?s actually happening to a line like this one.

Code:
*(unsigned int*)0x04000000 = 0x0403;


Or a line like;

Code:
((unsigned short*) 0x6000000)[5678] = 0xFFFF;


So far I know that it?s a a poiter to a memory location, and a numeric value is set in that memory location?

I know that 0x3 is for mode 3 and 0x400 is for bg2.

I know there?s a bit layout for REG_DISPCNT

But I don?t understand how 0x403 is combined with 0x4000000?

It?s the same with:

((unsigned short*) 0x6000000)[5678] = 0xFFFF;

I know that 0x6000000 is a memory array for the screen display, and I know that 0xFFFF is a color (white in this case), but I don?t know the mechanic that make them combined together?

Tonc and Jharbour tutorial are very vague on this subject, or I missed something.

Someone can help me please.

Thank you (sorry if I'm a slow learner, but I'm really trying to understand this proccess)

#89185 - tepples - Fri Jun 23, 2006 1:33 pm

king501 wrote:
I would like to understand what?s actually happening to a line like this one.

Code:
*(unsigned int*)0x04000000 = 0x0403;

The address bus (a set of signal lines in the CPU) is set to 0x04000000, the data bus (another set of signal lines) is set to 0x0403, and the control lines are set up for "memory data write". The GBA's memory controller interprets this combination of signal states as a write to the given I/O register.

Quote:
But I don?t understand how 0x403 is combined with 0x4000000?

Why do you feel the need to "understand" this? Do you need an electrical engineer's perspective on how memory controllers and memory-mapped I/O work?

Quote:
Tonc and Jharbour tutorial are very vague on this subject, or I missed something.

TONC and the like are geared for software developers, who don't need to understand how memory controllers work. Software developers can just write the data to the address and assume that the rest is "magic".
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#89188 - king501 - Fri Jun 23, 2006 1:55 pm

I?m sorry, maybe my question wasn?t correctly asked. I?m trying to figure out how bit layouts are working.

For instance, REG_DISPCNT (0400:0000h ) has a bit layout.

Bit A is supposed to be for BG2.
Mode 3 is supposed to be somewhere between 0-2

So how 0x400 and 0x3 are associated to this bit layout?

I just want to know how stuff are controlled if I want to control stuff on my own. Let's say I know that bg1 is at bit position 9 from REG_DISPCNT, so how do I know how to activate it?

#89189 - tepples - Fri Jun 23, 2006 2:02 pm

May or may not help:
Code:
Bit0 = 1 <<  0 == 0x0001
Bit1 = 1 <<  1 == 0x0002
Bit2 = 1 <<  2 == 0x0004
Bit3 = 1 <<  3 == 0x0008
Bit4 = 1 <<  4 == 0x0010
Bit5 = 1 <<  5 == 0x0020
Bit6 = 1 <<  6 == 0x0040
Bit7 = 1 <<  7 == 0x0080
Bit8 = 1 <<  8 == 0x0100
Bit9 = 1 <<  9 == 0x0200
BitA = 1 << 10 == 0x0400
BitB = 1 << 11 == 0x0800
BitC = 1 << 12 == 0x1000
BitD = 1 << 13 == 0x2000
BitE = 1 << 14 == 0x4000
BitF = 1 << 15 == 0x8000

The << operator performs a bit shift, and if you can't guess what a "bit shift" is from the table, you need to go look up more about binary and hexadecimal numerals systems.

Generally, people don't use addresses directly; they use constants and macros.
Code:

#define DISPCNT (*(volatile u16 *)0x04000000)
#define DISP_MODE(x) x
#define BG2_ON 0x0400

DISPCNT = DISP_MODE(3) | BG2_ON;
// expands inside the preprocessor to
(*(volatile u16 *)0x04000000) = 3 | 0x0400;
// which the compiler simplifies to
(*(volatile u16 *)0x04000000) = 0x0403;

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#89191 - king501 - Fri Jun 23, 2006 2:13 pm

thank you very much, now I should be on the right track.

of course I'm planning to use macros, just wanted to understand what I was doing.

most people simply content to copy/paste, I want to do better than that.

#90023 - king501 - Tue Jun 27, 2006 10:54 pm

I'm reading J Harbour tutorial too, and I was trying to figure out why he was using this specific number 57984;


Code:
DMAFastCopy((void*)background_Tiles, (void*)CHAR_BLOCK(0), [color=red]57984/4[/color], DMA_32NOW);


I know there's 4 char base, but I can't tell what the 57984 stand for...

The only thing that popped in my mind was: 16364 bytes (memory of one Char_Base) * 4, but the result is 65536.

#90052 - shen3 - Wed Jun 28, 2006 2:50 am

hi;

That parameter of DMAFastCopy is the size.

he is loading some background tiles into memory, and the size of those tiles is 57984 bytes.

Becasue he is using DMA to copy 32 bytes at a time, he needs to move 57984/4 chunks of 32 bytes.

Shen

#90057 - wintermute - Wed Jun 28, 2006 3:10 am

king501 wrote:
I'm reading J Harbour tutorial too, and I was trying to figure out why he was using this specific number 57984;


Code:
DMAFastCopy((void*)background_Tiles, (void*)CHAR_BLOCK(0), [color=red]57984/4[/color], DMA_32NOW);


I know there's 4 char base, but I can't tell what the 57984 stand for...

The only thing that popped in my mind was: 16364 bytes (memory of one Char_Base) * 4, but the result is 65536.


This is just one of many reasons why you shouldn't read that %$&?%% J Harbour book. Throw it away and read Tonc instead.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#123211 - king501 - Mon Mar 26, 2007 7:13 am

It has been a long time since I played with GBA hardware due to my dayjob... I forgot a lot of stuff since then :(

So I'm making tons of tests to understand fundamental stuff with memory and data type.

Question: can VRAM deal properly with 8bit data type under mode0? During my tests it worked fine with U32 and u16, but not correctly with u8.

here's a minor example;

I used mode0, 4bpp tiles, and created some colors.

Code:

((u32*)(MEM_VRAM + 0x0000))[8] = 0x1F1F1F1F;


work fine, draw the top row of a tile with two colors in the following pattern (RED, BLUE, RED, BLUE, RED, BLUE, RED, BLUE).

Code:

((u16*)(MEM_VRAM + 0x0000))[16] = 0x1F1F;


work fine, draw haft of the top row of a tile with two colors in the following pattern. (RED, BLUE, RED, BLUE)

Code:
((u8*)(MEM_VRAM + 0x0000))[32] = 0x1F;

doesn't work nicely, pixels are duplicated. (RED, RED, BLUE, BLUE) I expected only two pixels in the following pattern (RED, BLUE)

#123218 - sgeos - Mon Mar 26, 2007 8:47 am

king501 wrote:
Question: can VRAM deal properly with 8bit data type under mode0? During my tests it worked fine with U32 and u16, but not correctly with u8.

I believe that this is a hardware limitation. You might want to double check with gbatek.

-Brendan

#123224 - HyperHacker - Mon Mar 26, 2007 9:04 am

I know DS VRAM doesn't accept 8-bit writes, so I doubt GBA VRAM does either.
_________________
I'm a PSP hacker now, but I still <3 DS.

#123230 - sgeos - Mon Mar 26, 2007 10:25 am

HyperHacker wrote:
I know DS VRAM doesn't accept 8-bit writes, so I doubt GBA VRAM does either.

The DS has improved features. If it can't handle 8-bit writes, then the GBA certainly can't. Hardware limitation; you will have to combine two pixels into one 16bit write by either using 16bit blitting routines or a read, mask, write routine.

-Brendan