0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アセンブリでGBAプログラミング:ボタン判定

Posted at

初めに

開発環境の導入は以下の記事に記録しています。
アセンブリでGBAプログラミング:ARM7でVRAM塗り潰し

Aボタンが押されたら画面全体を赤くするだけの検証用プログラムを書きました。

ソース

コンパイル方法は以下の通り。

arm-none-eabi-as -mcpu=arm7tdmi -march=armv4t -g main.s -o main.o
arm-none-eabi-ld -nostdlib -Ttext=0x00000000 -o main.elf main.o
arm-none-eabi-objcopy -O binary main.elf main.gba
main.s
    .arm
    .section .text
    .global _start

/* --- 入口 --- */
    .org 0x00000000
_start:
    b ResetHandler       @ ResetHandlerへジャンプ

/* --- 任天堂ロゴ (0x0004〜0x009F, 156バイト) --- */
.byte 0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21
.byte 0x3d,0x84,0x82,0x0a,0x84,0xe4,0x09,0xad
.byte 0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21
.byte 0xa3,0x52,0xbe,0x19,0x93,0x09,0xce,0x20
.byte 0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec
.byte 0x58,0xc7,0xe8,0x33,0x82,0xe3,0xce,0xbf
.byte 0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1
.byte 0x94,0x56,0x8a,0xc0,0x13,0x72,0xa7,0xfc
.byte 0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61
.byte 0x58,0x97,0xa3,0x27,0xfc,0x03,0x98,0x76
.byte 0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56
.byte 0xbf,0x38,0x84,0x00,0x40,0xa7,0x0e,0xfd
.byte 0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1
.byte 0x97,0xfb,0xc0,0x85,0x60,0xd6,0x80,0x25
.byte 0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2
.byte 0xf9,0xa2,0x34,0xff,0xbb,0x3e,0x03,0x44
.byte 0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94
.byte 0x65,0xc0,0x7c,0x63,0x87,0xf0,0x3c,0xaf

/* --- タイトル・ゲームコード・メーカーコード (0x00A0〜0x00BF) --- */
.org 0x000000A0
.ascii "GBADEMO     "       @ タイトル 12文字
.byte 0x00,0x00,0x00,0x00     @ ゲームコード 4バイト
.byte 0x00,0x00               @ メーカーコード 2バイト
.byte 0x96                    @ 固定値
.byte 0x00                    @ メインユニットコード
.byte 0x00                    @ デバイスタイプ
.space 7                     @ 予約領域
.byte 0x00,0x00               @ 補完チェック・マスクROMバージョン
.space 2                     @ 残り予約領域

.align 2

ResetHandler:
    @ 画面モード設定 (Mode3 + BG2)
    ldr r0, =0x04000000
    ldr r1, =0x0403
    strh r1, [r0]

MainLoop:
    @ KEYINPUT 読み取り
    ldr r0, =0x04000130 @ 0x04000130(アドレス)をr0へ格納
    ldrh r1, [r0]       @ 0x04000130の値を → r1レジスタへビット読みこむ

    @ Aボタン(bit0)が押されたか確認 (押されると0)
    tst r1, #1         @ #1 = 0x00000001
    bne MainLoop       @ 押されてなければループ

    @ 押されたら塗り潰し
    bl FillScreenRed

WaitRelease:
    @ 離されるまで待つ
    ldr r0, =0x04000130
    ldrh r1, [r0]
    tst r1, #1
    beq WaitRelease
    b MainLoop


FillScreenRed:
    push {lr}

    @ VRAM = 0x06000000
    ldr r0, =0x06000000
    mov r1, #0x1F        @ 赤 (RGB15)
    ldr r2, =38400       @ 240*160

FillLoop:
    strh r1, [r0], #2
    subs r2, r2, #1
    bne FillLoop

    pop {lr}
    bx lr

解説

0x04000130にボタンが押されているかを記録するレジスタが対応しています。
それぞれのビットにボタンが対応しています。例えばAボタンなら第0ビット目が対応しています。
それぞれのビットが0なら押されている、1なら押されていない。

以下の2行を実行すると0x04000130から16ビットの値を取得してr1レジスタに格納します。

ldr r0, =0x04000130
ldrh r1, [r0]

0ビット目が0だとゼロフラグが立ち、bneでMainLoopに跳ばずbl FillScreenRedが実行される。

tst r1, #1
bne MainLoop 

動作確認

Aボタンを押すと画面全体が赤くなった

129f62e1bdc3d8.jpg
3cbcaf0d67f7b8.jpg

開発環境

ThinkPad x280
OS: Ubuntu 22.04.5 LTS (Jammy Jellyfish)
Kernel: Linux 6.8.0-84-generic
CPU: Intel Core i5-8250U, 4 cores, 8 threads, Little Endian
Architecture: x86_64

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?