/BERGASMS/GBA/05

..

04/08/22 - Part 2

New Goal: I will respond to the user pressing a button

A pretty simple one. I just want to ensure I can read a button press. Key presses are represented by toggling bits in a register which we can read to see what is going on. The docs have the following summary.

GBA Keypad Input

The built-in GBA gamepad has 4 direction keys, and 6 buttons.

4000130h - KEYINPUT - Key Status (R)

  Bit   Expl.
  0     Button A        
  1     Button B        
  2     Select          
  3     Start           
  4     Right           
  5     Left            
  6     Up              
  7     Down            
  8     Button R        
  9     Button L        
  10-15 Not used
So to check if, for example, the left d-pad is pressed, we read the 16 bit value at 4000130, and check if the 6th bit is toggled or not. I updated the HI drawing code to draw from an x/y reference position. The process we then want is to check if the left d-pad button is toggled, and if it is we want to update the x position. We map the register to a pointer first.
pub const REG_KEY = @intToPtr(*volatile u16, @ptrToInt(MEM_IO) + 0x0130);
And then in our update loop we check the pointer as follows.

if (REG_KEY.* & (0x1 << 5) != 0) {
    xpos = xpos - 1;
}
If the bitwise AND of the register and the value 00000000001000000 is not zero, then the button is pressed. Simple, lets give it a run.
Hmm, ok. Actually this is what we would expect because as we move along we are filling the VRAM but never clearing it. The problem is, I didn't press a button to achieve this, it just did it on its own. The problem is I made the assumption that the bit would be set to 1 when the button was pressed, but in fact it's the opposite. The bit is 0 when pressed and 1 when it's not pressed. OK, that means i can get the correct outcome by just flipping the bits in the register.

    var keyValues: u16 = REG_KEY.*;
    if (~keyValues & (0x1 << 5) != 0) {
        xpos = xpos - 1;
    }
            

So that works. Awesome. Now it's time to move on from drawing directly to the VRAM, that's no way to treat a venerable old handheld game console. We're going to draw a sprite instead. You can discuss this post here

New Goal: I will draw a sprite from the sprite memory.