Ported task.c and others from pokeruby

This commit is contained in:
Diegoisawesome 2016-10-31 03:14:22 -05:00
parent 6874afafe5
commit 4df1937738
30 changed files with 3274 additions and 2216 deletions

View File

@ -51,7 +51,6 @@ asm/main_menu.o \
asm/rom_8032654.o \
asm/tileset_animation.o \
asm/rom_80A18F4.o \
asm/task.o \
asm/rom_80A92F4.o \
asm/multiboot.o \
asm/rom_81BAD84.o \

View File

@ -8,7 +8,7 @@
@ void CB2_MainMenu()
CB2_MainMenu: @ 802F6B0
push {lr}
bl RunActiveTasks
bl RunTasks
bl CallObjectCallbacks
bl PrepareSpritesForOamLoad
bl fade_and_return_progress_probably
@ -127,7 +127,7 @@ InitMainMenu: @ 802F6F4
movs r2, 0x20
bl gpu_pal_apply
bl remove_some_task
bl clear_tasks
bl ResetTasks
bl ResetAllObjectData
bl ResetObjectPaletteAllocator
cmp r4, 0
@ -216,7 +216,7 @@ _0802F7FE:
bl HideBg
ldr r0, =Task_MainMenuCheckSaveFile
movs r1, 0
bl AddTask
bl CreateTask
movs r0, 0
add sp, 0xC
pop {r4,r5}
@ -1502,7 +1502,7 @@ _08030488:
_0803048A:
bl SetMainCallback2
adds r0, r6, 0
bl remove_task
bl DestroyTask
b _08030514
.pool
_0803049C:
@ -1610,7 +1610,7 @@ _08030578:
ldr r0, =c2_title_screen_1
bl SetMainCallback2
adds r0, r5, 0
bl remove_task
bl DestroyTask
_0803058C:
pop {r4,r5}
pop {r0}
@ -2292,7 +2292,7 @@ _08030B7C:
cmp r0, 0x5F
ble _08030BBA
adds r0, r4, 0
bl remove_task
bl DestroyTask
ldrb r1, [r7]
lsls r0, r1, 2
adds r0, r1
@ -2941,7 +2941,7 @@ task_new_game_prof_birch_speech_17: @ 8031090
lsrs r0, 24
bl set_default_player_name
adds r0, r4, 0
bl remove_task
bl DestroyTask
ldr r0, =0x03005d90
ldr r1, [r0]
ldrb r2, [r1, 0x8]
@ -3591,7 +3591,7 @@ task_new_game_prof_birch_speech_part2_12: @ 8031630
ldr r0, =CB2_NewGame
bl SetMainCallback2
adds r0, r4, 0
bl remove_task
bl DestroyTask
_08031666:
pop {r4}
pop {r0}
@ -3692,10 +3692,10 @@ new_game_prof_birch_speech_part2_start: @ 8031678
movs r1, 0x1
movs r2, 0x10
bl gpu_pal_apply
bl clear_tasks
bl ResetTasks
ldr r0, =task_new_game_prof_birch_speech_part2_1
movs r1, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r5, r0, 24
ldr r1, =0x03005e00
@ -4035,7 +4035,7 @@ sub_8031A5C: @ 8031A5C
movs r0, 0x1
strh r0, [r1, 0x12]
adds r0, r3, 0
bl remove_task
bl DestroyTask
b _08031AC4
.pool
_08031A94:
@ -4100,7 +4100,7 @@ sub_8031ACC: @ 8031ACC
strh r6, [r0, 0x12]
ldr r0, =sub_8031A5C
movs r1, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
lsls r1, r0, 2
@ -4145,7 +4145,7 @@ sub_8031B3C: @ 8031B3C
movs r0, 0x1
strh r0, [r1, 0x12]
adds r0, r3, 0
bl remove_task
bl DestroyTask
b _08031BA4
.pool
_08031B74:
@ -4211,7 +4211,7 @@ sub_8031BAC: @ 8031BAC
strh r6, [r0, 0x12]
ldr r0, =sub_8031B3C
movs r1, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
lsls r1, r0, 2
@ -4258,7 +4258,7 @@ _08031C40:
cmp r0, 0x8
bne _08031C52
adds r0, r2, 0
bl remove_task
bl DestroyTask
b _08031C7C
_08031C52:
ldrh r2, [r1, 0x10]
@ -4300,7 +4300,7 @@ sub_8031C88: @ 8031C88
lsrs r5, 24
ldr r0, =sub_8031C1C
movs r1, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -4347,7 +4347,7 @@ _08031CEC:
cmp r0, 0
bne _08031CFE
adds r0, r2, 0
bl remove_task
bl DestroyTask
b _08031D28
_08031CFE:
ldrh r2, [r1, 0x10]
@ -4389,7 +4389,7 @@ sub_8031D34: @ 8031D34
lsrs r5, 24
ldr r0, =sub_8031CC8
movs r1, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -5163,7 +5163,7 @@ sub_80323A0: @ 80323A0
strb r0, [r1]
ldr r0, =sub_8030A70
movs r1, 0
bl AddTask
bl CreateTask
_080323C0:
pop {r0}
bx r0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2560,7 +2560,7 @@ sub_80A2C44: @ 80A2C44
lsrs r5, 24
mov r8, r5
ldr r0, =sub_80A2D54
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r5, r0, 24
ldr r1, =0x03005e00
@ -2600,7 +2600,7 @@ _080A2CC4:
adds r0, r5, 0
movs r1, 0x5
mov r2, r10
bl set_word_task_arg
bl SetWordTaskArg
ldr r0, =0x03005e00
adds r1, r4, r5
lsls r1, 3
@ -2661,10 +2661,10 @@ sub_80A2D34: @ 80A2D34
push {lr}
b _080A2D3C
_080A2D38:
bl remove_task
bl DestroyTask
_080A2D3C:
ldr r0, =sub_80A2D54
bl get_task_id_by_function
bl FindTaskIdByFunc
lsls r0, 24
lsrs r0, 24
cmp r0, 0xFF
@ -2686,7 +2686,7 @@ sub_80A2D54: @ 80A2D54
adds r4, r0, r1
adds r0, r5, 0
movs r1, 0x5
bl get_word_task_arg
bl GetWordTaskArg
adds r3, r0, 0
ldrh r0, [r4, 0x8]
adds r0, 0x1
@ -2712,7 +2712,7 @@ sub_80A2D54: @ 80A2D54
cmp r0, r2
bne _080A2DAC
adds r0, r5, 0
bl remove_task
bl DestroyTask
b _080A2DCC
.pool
_080A2DAC:
@ -3128,7 +3128,7 @@ _080A311A:
task_is_not_running_overworld_fanfare: @ 80A3120
push {lr}
ldr r0, =task50_overworld_fanfare
bl is_function_an_active_task
bl FuncIsActiveTask
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
@ -3160,7 +3160,7 @@ _080A3158:
ldr r0, =0x03007420
bl m4aMPlayContinue
adds r0, r4, 0
bl remove_task
bl DestroyTask
_080A3164:
pop {r4}
pop {r0}
@ -3174,14 +3174,14 @@ task_add_50_overworld_fanfare_if_not_running: @ 80A3170
push {r4,lr}
ldr r4, =task50_overworld_fanfare
adds r0, r4, 0
bl is_function_an_active_task
bl FuncIsActiveTask
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
beq _080A318A
adds r0, r4, 0
movs r1, 0x50
bl AddTask
bl CreateTask
_080A318A:
pop {r4}
pop {r0}
@ -3786,7 +3786,7 @@ _080A365E:
sub_80A3678: @ 80A3678
push {lr}
ldr r0, =sub_80A370C
bl is_function_an_active_task
bl FuncIsActiveTask
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
@ -3887,7 +3887,7 @@ _080A3724:
lsls r2, 1
bl MPlayVolumeControl
adds r0, r4, 0
bl remove_task
bl DestroyTask
_080A3742:
pop {r4}
pop {r0}
@ -3900,14 +3900,14 @@ sub_80A3754: @ 80A3754
push {r4,lr}
ldr r4, =sub_80A370C
adds r0, r4, 0
bl is_function_an_active_task
bl FuncIsActiveTask
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
beq _080A376E
adds r0, r4, 0
movs r1, 0x50
bl AddTask
bl CreateTask
_080A376E:
pop {r4}
pop {r0}
@ -4432,7 +4432,7 @@ move_anim_task_del: @ 80A3C1C
push {lr}
lsls r0, 24
lsrs r0, 24
bl remove_task
bl DestroyTask
ldr r1, =0x020383fe
ldrb r0, [r1]
subs r0, 0x1
@ -4447,7 +4447,7 @@ move_anim_related_task_del: @ 80A3C38
push {lr}
lsls r0, 24
lsrs r0, 24
bl remove_task
bl DestroyTask
ldr r1, =0x020383ff
ldrb r0, [r1]
subs r0, 0x1
@ -4804,7 +4804,7 @@ _080A3F04:
_080A3F1C:
adds r0, r6, 0
adds r1, r7, 0
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
bl _call_via_r6
@ -5053,7 +5053,7 @@ sub_80A40F4: @ 80A40F4
_080A4148:
ldr r0, =task_pA_ma0A_obj_to_bg_pal
movs r1, 0xA
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r2, r0, 24
mov r1, r8
@ -5164,7 +5164,7 @@ _080A4232:
bl sub_80A438C
ldr r0, =sub_80A40F4
movs r1, 0xA
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r2, r0, 24
ldr r1, =0x020383fe
@ -5216,7 +5216,7 @@ _080A42A6:
bl sub_80A438C
ldr r0, =sub_80A40F4
movs r1, 0xA
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r2, r0, 24
ldr r1, =0x020383fe
@ -5971,7 +5971,7 @@ _080A4948:
_080A494A:
ldr r0, =sub_80A4980
movs r1, 0x5
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -6035,7 +6035,7 @@ _080A49C6:
adds r0, r4, 0
bl sub_80A477C
ldrb r0, [r6]
bl remove_task
bl DestroyTask
movs r0, 0xFF
strb r0, [r6]
_080A49DE:
@ -6053,12 +6053,12 @@ _080A49DE:
adds r0, r4, 0
bl sub_80A477C
ldrb r0, [r6, 0x1]
bl remove_task
bl DestroyTask
movs r0, 0xFF
strb r0, [r6, 0x1]
_080A4A04:
adds r0, r5, 0
bl remove_task
bl DestroyTask
_080A4A0A:
pop {r4-r6}
pop {r0}
@ -6250,7 +6250,7 @@ _080A4B78:
_080A4B7A:
ldr r0, =sub_80A4BB0
movs r1, 0x5
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -6338,7 +6338,7 @@ _080A4C0C:
bl sub_80A477C
_080A4C38:
adds r0, r6, 0
bl remove_task
bl DestroyTask
_080A4C3E:
pop {r4-r6}
pop {r0}
@ -6600,7 +6600,7 @@ ma14_load_background: @ 80A4E18
str r0, [r1]
ldr r0, =task_p5_load_battle_screen_elements
movs r1, 0x5
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -6635,7 +6635,7 @@ sub_80A4E5C: @ 80A4E5C
str r1, [r2]
ldr r0, =task_p5_load_battle_screen_elements
movs r1, 0x5
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r4, r0, 24
adds r5, r4, 0
@ -6780,7 +6780,7 @@ _080A4F94:
cmp r0, 0x3
bne _080A4FBC
adds r0, r5, 0
bl remove_task
bl DestroyTask
ldr r0, =0x02038433
strb r4, [r0]
_080A4FBC:
@ -6895,7 +6895,7 @@ ma15_load_battle_screen_elements: @ 80A50AC
str r0, [r1]
ldr r0, =task_p5_load_battle_screen_elements
movs r1, 0x5
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7324,7 +7324,7 @@ ma1B_8073C2C: @ 80A53B8
lsrs r4, 24
ldr r0, =c3_08073CEC
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7421,7 +7421,7 @@ _080A54E0:
_080A54E4:
lsrs r4, r2, 16
adds r0, r5, 0
bl remove_task
bl DestroyTask
ldr r1, =0x020383ff
ldrb r0, [r1]
subs r0, 0x1
@ -7464,7 +7464,7 @@ sub_80A5508: @ 80A5508
mov r10, r1
ldr r0, =c3_08073CEC
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7553,7 +7553,7 @@ sub_80A559C: @ 80A559C
lsrs r4, 24
ldr r0, =c3_08073CEC
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7619,7 +7619,7 @@ ma1C_8073ED0: @ 80A565C
lsrs r4, 24
ldr r0, =sub_80A56E4
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7689,7 +7689,7 @@ sub_80A56E4: @ 80A56E4
cmp r4, 0
bne _080A5732
adds r0, r5, 0
bl remove_task
bl DestroyTask
ldr r1, =0x020383ff
ldrb r0, [r1]
subs r0, 0x1
@ -7724,7 +7724,7 @@ ma1D_08073FB4: @ 80A5740
lsrs r4, 24
ldr r0, =sub_80A57B4
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
ldr r2, =0x03005e00
@ -7774,7 +7774,7 @@ sub_80A57B4: @ 80A57B4
ldrsb r1, [r2, r1]
bl audio_play_and_stuff
adds r0, r4, 0
bl remove_task
bl DestroyTask
ldr r1, =0x020383ff
ldrb r0, [r1]
subs r0, 0x1
@ -7829,7 +7829,7 @@ _080A582A:
_080A5842:
adds r0, r6, 0
movs r1, 0x1
bl AddTask
bl CreateTask
lsls r0, 24
lsrs r0, 24
bl _call_via_r6

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,528 +0,0 @@
.include "asm/macros.s"
.syntax unified
.text
thumb_func_start clear_tasks
@ void clear_tasks()
clear_tasks: @ 80A8F50
push {r4-r7,lr}
movs r4, 0
ldr r6, =0x03005e00
adds r7, r6, 0
adds r7, 0x8
_080A8F5A:
lsls r0, r4, 2
adds r0, r4
lsls r0, 3
adds r2, r0, r6
movs r1, 0
strb r1, [r2, 0x4]
ldr r1, =nullsub_4
str r1, [r2]
strb r4, [r2, 0x5]
adds r4, 0x1
strb r4, [r2, 0x6]
movs r1, 0x1
negs r1, r1
adds r5, r1, 0
movs r1, 0xFF
strb r1, [r2, 0x7]
adds r0, r7
movs r1, 0
movs r2, 0x20
bl memset
lsls r4, 24
lsrs r4, 24
cmp r4, 0xF
bls _080A8F5A
ldr r0, =0x03005e00
movs r1, 0xFE
strb r1, [r0, 0x5]
ldr r1, =0x0000025e
adds r0, r1
ldrb r1, [r0]
orrs r1, r5
strb r1, [r0]
pop {r4-r7}
pop {r0}
bx r0
.pool
thumb_func_end clear_tasks
thumb_func_start AddTask
@ int AddTask(void ( *func)(int task_id), u8 priority)
AddTask: @ 80A8FB0
push {r4-r7,lr}
adds r2, r0, 0
lsls r1, 24
lsrs r1, 24
movs r6, 0
ldr r7, =0x03005e00
_080A8FBC:
lsls r0, r6, 2
adds r0, r6
lsls r5, r0, 3
adds r4, r5, r7
ldrb r0, [r4, 0x4]
cmp r0, 0
bne _080A8FF0
str r2, [r4]
strb r1, [r4, 0x7]
adds r0, r6, 0
bl insert_task_in_order_by_priority
adds r0, r7, 0
adds r0, 0x8
adds r0, r5, r0
movs r1, 0
movs r2, 0x20
bl memset
movs r0, 0x1
strb r0, [r4, 0x4]
adds r0, r6, 0
b _080A8FFC
.pool
_080A8FF0:
adds r0, r6, 0x1
lsls r0, 24
lsrs r6, r0, 24
cmp r6, 0xF
bls _080A8FBC
movs r0, 0
_080A8FFC:
pop {r4-r7}
pop {r1}
bx r1
thumb_func_end AddTask
thumb_func_start insert_task_in_order_by_priority
@ void insert_task_in_order_by_priority(int task_id)
insert_task_in_order_by_priority: @ 80A9004
push {r4-r7,lr}
mov r7, r8
push {r7}
lsls r0, 24
lsrs r4, r0, 24
bl get_first_active_task
lsls r0, 24
lsrs r1, r0, 24
cmp r1, 0x10
bne _080A9034
ldr r1, =0x03005e00
lsls r0, r4, 2
adds r0, r4
lsls r0, 3
adds r0, r1
movs r1, 0xFE
strb r1, [r0, 0x5]
movs r1, 0xFF
strb r1, [r0, 0x6]
b _080A9090
.pool
_080A9034:
ldr r6, =0x03005e00
lsls r0, r4, 2
mov r12, r0
mov r8, r6
adds r0, r4
lsls r0, 3
adds r2, r0, r6
_080A9042:
lsls r0, r1, 2
adds r0, r1
lsls r5, r0, 3
mov r7, r8
adds r3, r5, r7
ldrb r0, [r2, 0x7]
ldrb r7, [r3, 0x7]
cmp r0, r7
bcs _080A9074
ldrb r0, [r3, 0x5]
strb r0, [r2, 0x5]
strb r1, [r2, 0x6]
ldrb r0, [r3, 0x5]
cmp r0, 0xFE
beq _080A906C
adds r1, r0, 0
lsls r0, r1, 2
adds r0, r1
lsls r0, 3
add r0, r8
strb r4, [r0, 0x6]
_080A906C:
strb r4, [r3, 0x5]
b _080A9090
.pool
_080A9074:
ldrb r0, [r3, 0x6]
cmp r0, 0xFF
beq _080A907E
adds r1, r0, 0
b _080A9042
_080A907E:
mov r2, r12
adds r0, r2, r4
lsls r0, 3
adds r0, r6
strb r1, [r0, 0x5]
adds r2, r5, r6
ldrb r1, [r2, 0x6]
strb r1, [r0, 0x6]
strb r4, [r2, 0x6]
_080A9090:
pop {r3}
mov r8, r3
pop {r4-r7}
pop {r0}
bx r0
thumb_func_end insert_task_in_order_by_priority
thumb_func_start remove_task
@ void remove_task(int task_id)
remove_task: @ 80A909C
push {r4,lr}
lsls r0, 24
lsrs r0, 24
ldr r4, =0x03005e00
lsls r1, r0, 2
adds r1, r0
lsls r1, 3
adds r2, r1, r4
ldrb r0, [r2, 0x4]
cmp r0, 0
beq _080A9106
movs r0, 0
strb r0, [r2, 0x4]
ldrb r3, [r2, 0x5]
cmp r3, 0xFE
bne _080A90D4
ldrb r0, [r2, 0x6]
cmp r0, 0xFF
beq _080A9106
adds r1, r0, 0
lsls r0, r1, 2
adds r0, r1
lsls r0, 3
adds r0, r4
strb r3, [r0, 0x5]
b _080A9106
.pool
_080A90D4:
ldrb r3, [r2, 0x6]
adds r0, r3, 0
cmp r0, 0xFF
bne _080A90EC
ldrb r0, [r2, 0x5]
lsls r1, r0, 2
adds r1, r0
lsls r1, 3
adds r1, r4
movs r0, 0xFF
strb r0, [r1, 0x6]
b _080A9106
_080A90EC:
ldrb r1, [r2, 0x5]
lsls r0, r1, 2
adds r0, r1
lsls r0, 3
adds r0, r4
strb r3, [r0, 0x6]
ldrb r1, [r2, 0x6]
lsls r0, r1, 2
adds r0, r1
lsls r0, 3
adds r0, r4
ldrb r1, [r2, 0x5]
strb r1, [r0, 0x5]
_080A9106:
pop {r4}
pop {r0}
bx r0
thumb_func_end remove_task
thumb_func_start RunActiveTasks
@ void RunActiveTasks()
RunActiveTasks: @ 80A910C
push {r4,r5,lr}
bl get_first_active_task
lsls r0, 24
lsrs r0, 24
cmp r0, 0x10
beq _080A9130
ldr r5, =0x03005e00
_080A911C:
lsls r4, r0, 2
adds r4, r0
lsls r4, 3
adds r4, r5
ldr r1, [r4]
bl _call_via_r1
ldrb r0, [r4, 0x6]
cmp r0, 0xFF
bne _080A911C
_080A9130:
pop {r4,r5}
pop {r0}
bx r0
.pool
thumb_func_end RunActiveTasks
thumb_func_start get_first_active_task
@ int get_first_active_task()
get_first_active_task: @ 80A913C
push {lr}
movs r2, 0
ldr r0, =0x03005e00
ldrb r1, [r0, 0x4]
adds r3, r0, 0
cmp r1, 0x1
bne _080A9150
ldrb r0, [r3, 0x5]
cmp r0, 0xFE
beq _080A916E
_080A9150:
adds r0, r2, 0x1
lsls r0, 24
lsrs r2, r0, 24
cmp r2, 0xF
bhi _080A916E
lsls r0, r2, 2
adds r0, r2
lsls r0, 3
adds r1, r0, r3
ldrb r0, [r1, 0x4]
cmp r0, 0x1
bne _080A9150
ldrb r0, [r1, 0x5]
cmp r0, 0xFE
bne _080A9150
_080A916E:
adds r0, r2, 0
pop {r1}
bx r1
.pool
thumb_func_end get_first_active_task
thumb_func_start nullsub_4
nullsub_4: @ 80A9178
bx lr
thumb_func_end nullsub_4
thumb_func_start set_task_function_and_args_14_15
set_task_function_and_args_14_15: @ 80A917C
push {r4,r5,lr}
lsls r0, 24
lsrs r0, 24
ldr r5, =0x03005e00
lsls r3, r0, 2
adds r3, r0
lsls r3, 3
adds r0, r3, 0
adds r0, 0x1C
adds r4, r5, 0
adds r4, 0x8
adds r0, r4
strh r2, [r0]
adds r0, r3, 0
adds r0, 0x1E
adds r0, r4
lsrs r2, 16
strh r2, [r0]
adds r3, r5
str r1, [r3]
pop {r4,r5}
pop {r0}
bx r0
.pool
thumb_func_end set_task_function_and_args_14_15
thumb_func_start set_task_function_to_args_14_15
set_task_function_to_args_14_15: @ 80A91B0
push {r4,lr}
lsls r0, 24
lsrs r0, 24
ldr r3, =0x03005e00
lsls r1, r0, 2
adds r1, r0
lsls r1, 3
adds r4, r1, r3
adds r0, r1, 0
adds r0, 0x1C
adds r3, 0x8
adds r0, r3
ldrh r2, [r0]
adds r1, 0x1E
adds r1, r3
movs r3, 0
ldrsh r0, [r1, r3]
lsls r0, 16
orrs r2, r0
str r2, [r4]
pop {r4}
pop {r0}
bx r0
.pool
thumb_func_end set_task_function_to_args_14_15
thumb_func_start is_function_an_active_task
@ int is_function_an_active_task(void ( *func)(int task_id))
is_function_an_active_task: @ 80A91E4
push {r4,lr}
adds r3, r0, 0
movs r2, 0
ldr r4, =0x03005e00
_080A91EC:
lsls r0, r2, 2
adds r0, r2
lsls r0, 3
adds r1, r0, r4
ldrb r0, [r1, 0x4]
cmp r0, 0x1
bne _080A9208
ldr r0, [r1]
cmp r0, r3
bne _080A9208
movs r0, 0x1
b _080A9214
.pool
_080A9208:
adds r0, r2, 0x1
lsls r0, 24
lsrs r2, r0, 24
cmp r2, 0xF
bls _080A91EC
movs r0, 0
_080A9214:
pop {r4}
pop {r1}
bx r1
thumb_func_end is_function_an_active_task
thumb_func_start get_task_id_by_function
@ int get_task_id_by_function(void ( *func)(int task_id))
get_task_id_by_function: @ 80A921C
push {lr}
adds r3, r0, 0
movs r2, 0
ldr r1, =0x03005e00
_080A9224:
ldrb r0, [r1, 0x4]
cmp r0, 0x1
bne _080A923C
ldr r0, [r1]
cmp r0, r3
bne _080A923C
lsls r0, r2, 24
lsrs r0, 24
b _080A9246
.pool
_080A923C:
adds r1, 0x28
adds r2, 0x1
cmp r2, 0xF
ble _080A9224
movs r0, 0xFF
_080A9246:
pop {r1}
bx r1
thumb_func_end get_task_id_by_function
thumb_func_start sub_80A924C
sub_80A924C: @ 80A924C
push {lr}
movs r2, 0
movs r1, 0
ldr r3, =0x03005e00
_080A9254:
lsls r0, r1, 2
adds r0, r1
lsls r0, 3
adds r0, r3
ldrb r0, [r0, 0x4]
cmp r0, 0x1
bne _080A9268
adds r0, r2, 0x1
lsls r0, 24
lsrs r2, r0, 24
_080A9268:
adds r0, r1, 0x1
lsls r0, 24
lsrs r1, r0, 24
cmp r1, 0xF
bls _080A9254
adds r0, r2, 0
pop {r1}
bx r1
.pool
thumb_func_end sub_80A924C
thumb_func_start set_word_task_arg
set_word_task_arg: @ 80A927C
push {r4,r5,lr}
adds r5, r2, 0
lsls r0, 24
lsrs r4, r0, 24
lsls r1, 24
lsrs r3, r1, 24
cmp r3, 0xE
bhi _080A92AA
ldr r2, =0x03005e00
lsls r0, r3, 1
lsls r1, r4, 2
adds r1, r4
lsls r1, 3
adds r0, r1
adds r2, 0x8
adds r0, r2
strh r5, [r0]
adds r0, r3, 0x1
lsls r0, 1
adds r0, r1
adds r0, r2
lsrs r1, r5, 16
strh r1, [r0]
_080A92AA:
pop {r4,r5}
pop {r0}
bx r0
.pool
thumb_func_end set_word_task_arg
thumb_func_start get_word_task_arg
get_word_task_arg: @ 80A92B4
push {r4,lr}
lsls r0, 24
lsrs r4, r0, 24
lsls r1, 24
lsrs r1, 24
cmp r1, 0xE
bls _080A92C6
movs r0, 0
b _080A92E8
_080A92C6:
ldr r3, =0x03005e00
lsls r0, r1, 1
lsls r2, r4, 2
adds r2, r4
lsls r2, 3
adds r0, r2
adds r3, 0x8
adds r0, r3
ldrh r0, [r0]
adds r1, 0x1
lsls r1, 1
adds r1, r2
adds r1, r3
movs r2, 0
ldrsh r1, [r1, r2]
lsls r1, 16
orrs r0, r1
_080A92E8:
pop {r4}
pop {r1}
bx r1
.pool
thumb_func_end get_word_task_arg
.align 2, 0 @ Don't pad with nop.

View File

@ -1814,7 +1814,7 @@ sub_80A1818: @ 80A1818
movs r1, 0x10
bl pal_fade_1
ldr r0, =sub_8149DFC
bl get_task_id_by_function
bl FindTaskIdByFunc
lsls r0, 24
lsrs r0, 24
cmp r0, 0xFF
@ -1846,7 +1846,7 @@ sub_80A1884: @ 80A1884
movs r2, 0x10
bl CpuSet
ldr r0, =sub_8149DFC
bl get_task_id_by_function
bl FindTaskIdByFunc
lsls r0, 24
lsrs r0, 24
cmp r0, 0xFF

137
data/cry_id_table.s Normal file
View File

@ -0,0 +1,137 @@
.align 1
gSpeciesIdToCryId:: @ 831F61C
.2byte 273 @ TREECKO
.2byte 274 @ GROVYLE
.2byte 275 @ SCEPTILE
.2byte 270 @ TORCHIC
.2byte 271 @ COMBUSKEN
.2byte 272 @ BLAZIKEN
.2byte 276 @ MUDKIP
.2byte 277 @ MARSHTOMP
.2byte 278 @ SWAMPERT
.2byte 359 @ POOCHYENA
.2byte 360 @ MIGHTYENA
.2byte 378 @ ZIGZAGOON
.2byte 375 @ LINOONE
.2byte 290 @ WURMPLE
.2byte 291 @ SILCOON
.2byte 292 @ BEAUTIFLY
.2byte 293 @ CASCOON
.2byte 294 @ DUSTOX
.2byte 283 @ LOTAD
.2byte 284 @ LOMBRE
.2byte 285 @ LUDICOLO
.2byte 286 @ SEEDOT
.2byte 287 @ NUZLEAF
.2byte 288 @ SHIFTRY
.2byte 301 @ NINCADA
.2byte 302 @ NINJASK
.2byte 303 @ SHEDINJA
.2byte 266 @ TAILLOW
.2byte 267 @ SWELLOW
.2byte 374 @ SHROOMISH
.2byte 373 @ BRELOOM
.2byte 269 @ SPINDA
.2byte 280 @ WINGULL
.2byte 279 @ PELIPPER
.2byte 310 @ SURSKIT
.2byte 311 @ MASQUERAIN
.2byte 377 @ WAILMER
.2byte 381 @ WAILORD
.2byte 312 @ SKITTY
.2byte 313 @ DELCATTY
.2byte 251 @ KECLEON
.2byte 329 @ BALTOY
.2byte 330 @ CLAYDOL
.2byte 306 @ NOSEPASS
.2byte 253 @ TORKOAL
.2byte 362 @ SABLEYE
.2byte 318 @ BARBOACH
.2byte 319 @ WHISCASH
.2byte 368 @ LUVDISC
.2byte 320 @ CORPHISH
.2byte 321 @ CRAWDAUNT
.2byte 333 @ FEEBAS
.2byte 334 @ MILOTIC
.2byte 289 @ CARVANHA
.2byte 260 @ SHARPEDO
.2byte 324 @ TRAPINCH
.2byte 325 @ VIBRAVA
.2byte 326 @ FLYGON
.2byte 304 @ MAKUHITA
.2byte 305 @ HARIYAMA
.2byte 254 @ ELECTRIKE
.2byte 255 @ MANECTRIC
.2byte 316 @ NUMEL
.2byte 317 @ CAMERUPT
.2byte 338 @ SPHEAL
.2byte 339 @ SEALEO
.2byte 340 @ WALREIN
.2byte 327 @ CACNEA
.2byte 328 @ CACTURNE
.2byte 383 @ SNORUNT
.2byte 307 @ GLALIE
.2byte 331 @ LUNATONE
.2byte 332 @ SOLROCK
.2byte 262 @ AZURILL
.2byte 322 @ SPOINK
.2byte 323 @ GRUMPIG
.2byte 308 @ PLUSLE
.2byte 309 @ MINUN
.2byte 363 @ MAWILE
.2byte 336 @ MEDITITE
.2byte 337 @ MEDICHAM
.2byte 263 @ SWABLU
.2byte 264 @ ALTARIA
.2byte 258 @ WYNAUT
.2byte 256 @ DUSKULL
.2byte 361 @ DUSCLOPS
.2byte 252 @ ROSELIA
.2byte 298 @ SLAKOTH
.2byte 299 @ VIGOROTH
.2byte 300 @ SLAKING
.2byte 314 @ GULPIN
.2byte 315 @ SWALOT
.2byte 376 @ TROPIUS
.2byte 382 @ WHISMUR
.2byte 380 @ LOUDRED
.2byte 379 @ EXPLOUD
.2byte 341 @ CLAMPERL
.2byte 342 @ HUNTAIL
.2byte 343 @ GOREBYSS
.2byte 335 @ ABSOL
.2byte 282 @ SHUPPET
.2byte 281 @ BANETTE
.2byte 259 @ SEVIPER
.2byte 261 @ ZANGOOSE
.2byte 367 @ RELICANTH
.2byte 364 @ ARON
.2byte 365 @ LAIRON
.2byte 366 @ AGGRON
.2byte 356 @ CASTFORM
.2byte 357 @ VOLBEAT
.2byte 358 @ ILLUMISE
.2byte 344 @ LILEEP
.2byte 345 @ CRADILY
.2byte 346 @ ANORITH
.2byte 347 @ ARMALDO
.2byte 295 @ RALTS
.2byte 296 @ KIRLIA
.2byte 297 @ GARDEVOIR
.2byte 351 @ BAGON
.2byte 352 @ SHELGON
.2byte 372 @ SALAMENCE
.2byte 348 @ BELDUM
.2byte 349 @ METANG
.2byte 350 @ METAGROSS
.2byte 353 @ REGIROCK
.2byte 354 @ REGICE
.2byte 355 @ REGISTEEL
.2byte 370 @ KYOGRE
.2byte 369 @ GROUDON
.2byte 371 @ RAYQUAZA
.2byte 257 @ LATIAS
.2byte 384 @ LATIOS
.2byte 385 @ JIRACHI
.2byte 386 @ DEOXYS
.2byte 387 @ CHIMECHO

View File

@ -1645,8 +1645,8 @@ gUnknown_0831C7B4:: @ 831C7B4
@ 831F5CA
.include "data/trainer_class_name_indices.s"
gUnknown_0831F61C:: @ 831F61C
.incbin "baserom.gba", 0x31f61c, 0x110
@ 831F61C
.include "data/cry_id_table.s"
@ 831F72C
.include "data/experience_tables.s"

View File

@ -716,14 +716,23 @@ gUnknown_08DC3A0C:: @ 8DC3A0C
gUnknown_08DC3CD4:: @ 8DC3CD4
.incbin "baserom.gba", 0xdc3cd4, 0x80
gUnknown_08DC3D54:: @ 8DC3D54
.incbin "baserom.gba", 0xdc3d54, 0x20
gIntroCopyright_Pal:: @ 8DC3D54
.incbin "graphics/intro/copyright.gbapal"
gUnknown_08DC3D74:: @ 8DC3D74
.incbin "baserom.gba", 0xdc3d74, 0x260
.align 2
gUnknown_08DC3FD4:: @ 8DC3FD4
.incbin "baserom.gba", 0xdc3fd4, 0x16c
gIntroCopyright_Gfx:: @ 8DC3D74
.incbin "graphics/intro/copyright.4bpp.lz"
.align 2
gIntroCopyright_Tilemap:: @ 8DC3FD4
.incbin "graphics/intro/copyright.bin.lz"
.align 2
gUnknown_08DC4120:: @ 8DC4120
.incbin "baserom.gba", 0xdc4120, 0x20
gUnknown_08DC4140:: @ 8DC4140
.incbin "baserom.gba", 0xdc4140, 0x1d8

Binary file not shown.

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 32 32
24 57 57
49 82 82
82 106 106
106 131 131
139 156 156
164 180 180
197 205 205
222 230 230
255 255 255

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

View File

@ -2,6 +2,7 @@ monstillfrontdir := graphics/pokemon/front_pics
monbackdir := graphics/pokemon/back_pics
monfrontdir := graphics/pokemon/anim_front_pics
monpaldir := graphics/pokemon/palettes
INTROGFXDIR := graphics/intro
$(monstillfrontdir)/castform_still_front_pic.4bpp: $(monstillfrontdir)/castform_normal_form_still_front_pic.4bpp \
$(monstillfrontdir)/castform_sunny_form_still_front_pic.4bpp \
@ -267,3 +268,6 @@ $(fontdir)/unused_frlg_female.fwjpnfont: $(fontdir)/unused_japanese_frlg_female_
graphics/title_screen/pokemon_logo.gbapal: graphics/title_screen/pokemon_logo.pal
$(GFX) $< $@ -num_colors 224
$(INTROGFXDIR)/copyright.4bpp: $(INTROGFXDIR)/copyright.png
$(GFX) $< $@ -num_tiles 39

61
include/gba/defines.h Normal file
View File

@ -0,0 +1,61 @@
#ifndef GUARD_GBA_DEFINES
#define GUARD_GBA_DEFINES
#include <stddef.h>
#define TRUE 1
#define FALSE 0
#define IWRAM_DATA __attribute__((section("iwram_data")))
#define EWRAM_DATA __attribute__((section("ewram_data")))
#define ALIGNED(n) __attribute__((aligned(n)))
#define SOUND_INFO_PTR (*(struct SoundInfo **)0x3007FF0)
#define INTR_CHECK (*(u16 *)0x3007FF8)
#define INTR_VECTOR (*(void **)0x3007FFC)
#define PLTT 0x5000000
#define PLTT_SIZE 0x400
#define BG_PLTT PLTT
#define BG_PLTT_SIZE 0x200
#define OBJ_PLTT (PLTT + 0x200)
#define OBJ_PLTT_SIZE 0x200
#define VRAM 0x6000000
#define VRAM_SIZE 0x18000
#define BG_VRAM VRAM
#define BG_VRAM_SIZE 0x10000
#define BG_CHAR_ADDR(n) (BG_VRAM + (0x4000 * (n)))
#define BG_SCREEN_ADDR(n) (BG_VRAM + (0x800 * (n)))
// text-mode BG
#define OBJ_VRAM0 (VRAM + 0x10000)
#define OBJ_VRAM0_SIZE 0x8000
// bitmap-mode BG
#define OBJ_VRAM1 (VRAM + 0x14000)
#define OBJ_VRAM1_SIZE 0x4000
#define OAM 0x7000000
#define OAM_SIZE 0x400
#define DISPLAY_WIDTH 240
#define DISPLAY_HEIGHT 160
#define TILE_SIZE_4BPP 32
#define TILE_SIZE_8BPP 64
#define TOTAL_OBJ_TILE_COUNT 1024
#define RGB(r, g, b) ((r) | ((g) << 5) | ((b) << 10))
#define RGB_BLACK RGB(0, 0, 0)
#define RGB_WHITE RGB(31, 31, 31)
#define WIN_RANGE(a, b) (((a) << 8) | (b))
#endif // GUARD_GBA_DEFINES

View File

@ -0,0 +1,76 @@
#ifndef GUARD_GBA_FLASH_INTERNAL_H
#define GUARD_GBA_FLASH_INTERNAL_H
#define FLASH_BASE ((u8 *)0xE000000)
#define FLASH_WRITE(addr, data) ((*(vu8 *)(FLASH_BASE + (addr))) = (data))
#define FLASH_ROM_SIZE_1M 131072 // 1 megabit ROM
#define SECTORS_PER_BANK 16
struct FlashSector
{
u32 size;
u8 shift;
u16 count;
u16 top;
};
struct FlashType {
u32 romSize;
struct FlashSector sector;
u16 wait[2]; // game pak bus read/write wait
// TODO: add support for anonymous unions/structs if possible
union {
struct {
u8 makerId;
u8 deviceId;
} separate;
u16 joined;
} ids;
};
struct FlashSetupInfo
{
u16 (*programFlashByte)(u16, u32, u8);
u16 (*programFlashSector)(u16, u8 *);
u16 (*eraseFlashChip)(void);
u16 (*eraseFlashSector)(u16);
u16 (*WaitForFlashWrite)(u8, u8 *, u8);
const u16 *maxTime;
struct FlashType type;
};
extern u16 gFlashNumRemainingBytes;
extern u16 (*ProgramFlashByte)(u16, u32, u8);
extern u16 (*ProgramFlashSector)(u16, u8 *);
extern u16 (*EraseFlashChip)(void);
extern u16 (*EraseFlashSector)(u16);
extern u16 (*WaitForFlashWrite)(u8, u8 *, u8);
extern const u16 *gFlashMaxTime;
extern const struct FlashType *gFlash;
extern u8 (*PollFlashStatus)(u8 *);
extern u8 gFlashTimeoutFlag;
extern const struct FlashSetupInfo MX29L010;
extern const struct FlashSetupInfo LE26FV10N1TS;
extern const struct FlashSetupInfo DefaultFlash;
void SwitchFlashBank(u8 bankNum);
u16 ReadFlashId(void);
void StartFlashTimer(u8 phase);
void SetReadFlash1(u16 *dest);
void StopFlashTimer(void);
u16 WaitForFlashWrite_Common(u8 phase, u8 *addr, u8 lastData);
u16 EraseFlashChip_MX(void);
u16 EraseFlashSector_MX(u16 sectorNum);
u16 ProgramFlashByte_MX(u16 sectorNum, u32 offset, u8 data);
u16 ProgramFlashSector_MX(u16 sectorNum, u8 *src);
#endif // GUARD_GBA_FLASH_INTERNAL_H

10
include/gba/gba.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef GUARD_GBA_GBA_H
#define GUARD_GBA_GBA_H
#include "gba/defines.h"
#include "gba/io_reg.h"
#include "gba/types.h"
#include "gba/syscall.h"
#include "gba/macro.h"
#endif // GUARD_GBA_GBA_H

View File

@ -24,16 +24,20 @@
#define REG_OFFSET_BG2PB 0x22
#define REG_OFFSET_BG2PC 0x24
#define REG_OFFSET_BG2PD 0x26
#define REG_OFFSET_BG2X 0x28
#define REG_OFFSET_BG2X_L 0x28
#define REG_OFFSET_BG2X_H 0x2a
#define REG_OFFSET_BG2Y 0x2c
#define REG_OFFSET_BG2Y_L 0x2c
#define REG_OFFSET_BG2Y_H 0x2e
#define REG_OFFSET_BG3PA 0x30
#define REG_OFFSET_BG3PB 0x32
#define REG_OFFSET_BG3PC 0x34
#define REG_OFFSET_BG3PD 0x36
#define REG_OFFSET_BG3X 0x38
#define REG_OFFSET_BG3X_L 0x38
#define REG_OFFSET_BG3X_H 0x3a
#define REG_OFFSET_BG3Y 0x3c
#define REG_OFFSET_BG3Y_L 0x3c
#define REG_OFFSET_BG3Y_H 0x3e
#define REG_OFFSET_WIN0H 0x40
@ -47,45 +51,49 @@
#define REG_OFFSET_BLDALPHA 0x52
#define REG_OFFSET_BLDY 0x54
#define REG_OFFSET_SOUND1CNT 0x60
#define REG_OFFSET_SOUND1CNT_L 0x60
#define REG_OFFSET_NR10 0x60
#define REG_OFFSET_SOUND1CNT_H 0x62
#define REG_OFFSET_NR11 0x62
#define REG_OFFSET_NR12 0x63
#define REG_OFFSET_SOUND1CNT_X 0x64
#define REG_OFFSET_SOUND2CNT 0x68
#define REG_OFFSET_NR13 0x64
#define REG_OFFSET_NR14 0x65
#define REG_OFFSET_SOUND2CNT_L 0x68
#define REG_OFFSET_NR21 0x68
#define REG_OFFSET_NR22 0x69
#define REG_OFFSET_SOUND2CNT_H 0x6c
#define REG_OFFSET_SOUND3CNT 0x70
#define REG_OFFSET_NR23 0x6c
#define REG_OFFSET_NR24 0x6d
#define REG_OFFSET_SOUND3CNT_L 0x70
#define REG_OFFSET_NR30 0x70
#define REG_OFFSET_SOUND3CNT_H 0x72
#define REG_OFFSET_NR31 0x72
#define REG_OFFSET_NR32 0x73
#define REG_OFFSET_SOUND3CNT_X 0x74
#define REG_OFFSET_SOUND4CNT 0x78
#define REG_OFFSET_NR33 0x74
#define REG_OFFSET_NR34 0x75
#define REG_OFFSET_SOUND4CNT_L 0x78
#define REG_OFFSET_NR41 0x78
#define REG_OFFSET_NR42 0x79
#define REG_OFFSET_SOUND4CNT_H 0x7c
#define REG_OFFSET_SOUNDCNT 0x80
#define REG_OFFSET_NR43 0x7c
#define REG_OFFSET_NR44 0x7d
#define REG_OFFSET_SOUNDCNT_L 0x80
#define REG_OFFSET_NR50 0x80
#define REG_OFFSET_NR51 0x81
#define REG_OFFSET_SOUNDCNT_H 0x82
#define REG_OFFSET_SOUNDCNT_X 0x84
#define REG_OFFSET_NR52 0x84
#define REG_OFFSET_SOUNDBIAS 0x88
#define REG_OFFSET_WAVE_RAM 0x90
#define REG_OFFSET_SOUNDBIAS_L 0x88
#define REG_OFFSET_SOUNDBIAS_H 0x89
#define REG_OFFSET_WAVE_RAM0 0x90
#define REG_OFFSET_WAVE_RAM0_L 0x90
#define REG_OFFSET_WAVE_RAM0_H 0x92
#define REG_OFFSET_WAVE_RAM1 0x94
#define REG_OFFSET_WAVE_RAM1_L 0x94
#define REG_OFFSET_WAVE_RAM1_H 0x96
#define REG_OFFSET_WAVE_RAM2 0x98
#define REG_OFFSET_WAVE_RAM2_L 0x98
#define REG_OFFSET_WAVE_RAM2_H 0x9a
#define REG_OFFSET_WAVE_RAM3 0x9c
#define REG_OFFSET_WAVE_RAM3_L 0x9c
#define REG_OFFSET_WAVE_RAM3_H 0x9e
#define REG_OFFSET_FIFO 0xa0
#define REG_OFFSET_FIFO_A 0xa0
#define REG_OFFSET_FIFO_A_L 0xa0
#define REG_OFFSET_FIFO_A_H 0xa2
#define REG_OFFSET_FIFO_B 0xa4
#define REG_OFFSET_FIFO_B_L 0xa4
#define REG_OFFSET_FIFO_B_H 0xa6
#define REG_OFFSET_DMA0 0xb0
#define REG_OFFSET_DMA0SAD 0xb0
@ -128,6 +136,7 @@
#define REG_OFFSET_DMA3CNT_L 0xdc
#define REG_OFFSET_DMA3CNT_H 0xde
#define REG_OFFSET_TMCNT 0x100
#define REG_OFFSET_TM0CNT 0x100
#define REG_OFFSET_TM0CNT_L 0x100
#define REG_OFFSET_TM0CNT_H 0x102
@ -192,16 +201,20 @@
#define REG_ADDR_BG2PB (REG_BASE + REG_OFFSET_BG2PB)
#define REG_ADDR_BG2PC (REG_BASE + REG_OFFSET_BG2PC)
#define REG_ADDR_BG2PD (REG_BASE + REG_OFFSET_BG2PD)
#define REG_ADDR_BG2X (REG_BASE + REG_OFFSET_BG2X)
#define REG_ADDR_BG2X_L (REG_BASE + REG_OFFSET_BG2X_L)
#define REG_ADDR_BG2X_H (REG_BASE + REG_OFFSET_BG2X_H)
#define REG_ADDR_BG2Y (REG_BASE + REG_OFFSET_BG2Y)
#define REG_ADDR_BG2Y_L (REG_BASE + REG_OFFSET_BG2Y_L)
#define REG_ADDR_BG2Y_H (REG_BASE + REG_OFFSET_BG2Y_H)
#define REG_ADDR_BG3PA (REG_BASE + REG_OFFSET_BG3PA)
#define REG_ADDR_BG3PB (REG_BASE + REG_OFFSET_BG3PB)
#define REG_ADDR_BG3PC (REG_BASE + REG_OFFSET_BG3PC)
#define REG_ADDR_BG3PD (REG_BASE + REG_OFFSET_BG3PD)
#define REG_ADDR_BG3X (REG_BASE + REG_OFFSET_BG3X)
#define REG_ADDR_BG3X_L (REG_BASE + REG_OFFSET_BG3X_L)
#define REG_ADDR_BG3X_H (REG_BASE + REG_OFFSET_BG3X_H)
#define REG_ADDR_BG3Y (REG_BASE + REG_OFFSET_BG3Y)
#define REG_ADDR_BG3Y_L (REG_BASE + REG_OFFSET_BG3Y_L)
#define REG_ADDR_BG3Y_H (REG_BASE + REG_OFFSET_BG3Y_H)
#define REG_ADDR_WIN0H (REG_BASE + REG_OFFSET_WIN0H)
@ -215,87 +228,76 @@
#define REG_ADDR_BLDALPHA (REG_BASE + REG_OFFSET_BLDALPHA)
#define REG_ADDR_BLDY (REG_BASE + REG_OFFSET_BLDY)
#define REG_ADDR_SOUND1CNT (REG_BASE + REG_OFFSET_SOUND1CNT)
#define REG_ADDR_SOUND1CNT_L (REG_BASE + REG_OFFSET_SOUND1CNT_L)
#define REG_ADDR_NR10 (REG_BASE + REG_OFFSET_NR10)
#define REG_ADDR_SOUND1CNT_H (REG_BASE + REG_OFFSET_SOUND1CNT_H)
#define REG_ADDR_NR11 (REG_BASE + REG_OFFSET_NR11)
#define REG_ADDR_NR12 (REG_BASE + REG_OFFSET_NR12)
#define REG_ADDR_SOUND1CNT_X (REG_BASE + REG_OFFSET_SOUND1CNT_X)
#define REG_ADDR_SOUND2CNT (REG_BASE + REG_OFFSET_SOUND2CNT)
#define REG_ADDR_NR13 (REG_BASE + REG_OFFSET_NR13)
#define REG_ADDR_NR14 (REG_BASE + REG_OFFSET_NR14)
#define REG_ADDR_SOUND2CNT_L (REG_BASE + REG_OFFSET_SOUND2CNT_L)
#define REG_ADDR_NR21 (REG_BASE + REG_OFFSET_NR21)
#define REG_ADDR_NR22 (REG_BASE + REG_OFFSET_NR22)
#define REG_ADDR_SOUND2CNT_H (REG_BASE + REG_OFFSET_SOUND2CNT_H)
#define REG_ADDR_SOUND3CNT (REG_BASE + REG_OFFSET_SOUND3CNT)
#define REG_ADDR_NR23 (REG_BASE + REG_OFFSET_NR23)
#define REG_ADDR_NR24 (REG_BASE + REG_OFFSET_NR24)
#define REG_ADDR_SOUND3CNT_L (REG_BASE + REG_OFFSET_SOUND3CNT_L)
#define REG_ADDR_NR30 (REG_BASE + REG_OFFSET_NR30)
#define REG_ADDR_SOUND3CNT_H (REG_BASE + REG_OFFSET_SOUND3CNT_H)
#define REG_ADDR_NR31 (REG_BASE + REG_OFFSET_NR31)
#define REG_ADDR_NR32 (REG_BASE + REG_OFFSET_NR32)
#define REG_ADDR_SOUND3CNT_X (REG_BASE + REG_OFFSET_SOUND3CNT_X)
#define REG_ADDR_SOUND4CNT (REG_BASE + REG_OFFSET_SOUND4CNT)
#define REG_ADDR_NR33 (REG_BASE + REG_OFFSET_NR33)
#define REG_ADDR_NR34 (REG_BASE + REG_OFFSET_NR34)
#define REG_ADDR_SOUND4CNT_L (REG_BASE + REG_OFFSET_SOUND4CNT_L)
#define REG_ADDR_NR41 (REG_BASE + REG_OFFSET_NR41)
#define REG_ADDR_NR42 (REG_BASE + REG_OFFSET_NR42)
#define REG_ADDR_SOUND4CNT_H (REG_BASE + REG_OFFSET_SOUND4CNT_H)
#define REG_ADDR_SOUNDCNT (REG_BASE + REG_OFFSET_SOUNDCNT)
#define REG_ADDR_NR43 (REG_BASE + REG_OFFSET_NR43)
#define REG_ADDR_NR44 (REG_BASE + REG_OFFSET_NR44)
#define REG_ADDR_SOUNDCNT_L (REG_BASE + REG_OFFSET_SOUNDCNT_L)
#define REG_ADDR_NR50 (REG_BASE + REG_OFFSET_NR50)
#define REG_ADDR_NR51 (REG_BASE + REG_OFFSET_NR51)
#define REG_ADDR_SOUNDCNT_H (REG_BASE + REG_OFFSET_SOUNDCNT_H)
#define REG_ADDR_SOUNDCNT_X (REG_BASE + REG_OFFSET_SOUNDCNT_X)
#define REG_ADDR_NR52 (REG_BASE + REG_OFFSET_NR52)
#define REG_ADDR_SOUNDBIAS (REG_BASE + REG_OFFSET_SOUNDBIAS)
#define REG_ADDR_WAVE_RAM (REG_BASE + REG_OFFSET_WAVE_RAM)
#define REG_ADDR_SOUNDBIAS_L (REG_BASE + REG_OFFSET_SOUNDBIAS_L)
#define REG_ADDR_SOUNDBIAS_H (REG_BASE + REG_OFFSET_SOUNDBIAS_H)
#define REG_ADDR_WAVE_RAM0 (REG_BASE + REG_OFFSET_WAVE_RAM0)
#define REG_ADDR_WAVE_RAM0_L (REG_BASE + REG_OFFSET_WAVE_RAM0_L)
#define REG_ADDR_WAVE_RAM0_H (REG_BASE + REG_OFFSET_WAVE_RAM0_H)
#define REG_ADDR_WAVE_RAM1 (REG_BASE + REG_OFFSET_WAVE_RAM1)
#define REG_ADDR_WAVE_RAM1_L (REG_BASE + REG_OFFSET_WAVE_RAM1_L)
#define REG_ADDR_WAVE_RAM1_H (REG_BASE + REG_OFFSET_WAVE_RAM1_H)
#define REG_ADDR_WAVE_RAM2 (REG_BASE + REG_OFFSET_WAVE_RAM2)
#define REG_ADDR_WAVE_RAM2_L (REG_BASE + REG_OFFSET_WAVE_RAM2_L)
#define REG_ADDR_WAVE_RAM2_H (REG_BASE + REG_OFFSET_WAVE_RAM2_H)
#define REG_ADDR_WAVE_RAM3 (REG_BASE + REG_OFFSET_WAVE_RAM3)
#define REG_ADDR_WAVE_RAM3_L (REG_BASE + REG_OFFSET_WAVE_RAM3_L)
#define REG_ADDR_WAVE_RAM3_H (REG_BASE + REG_OFFSET_WAVE_RAM3_H)
#define REG_ADDR_FIFO (REG_BASE + REG_OFFSET_FIFO)
#define REG_ADDR_FIFO_A (REG_BASE + REG_OFFSET_FIFO_A)
#define REG_ADDR_FIFO_A_L (REG_BASE + REG_OFFSET_FIFO_A_L)
#define REG_ADDR_FIFO_A_H (REG_BASE + REG_OFFSET_FIFO_A_H)
#define REG_ADDR_FIFO_B (REG_BASE + REG_OFFSET_FIFO_B)
#define REG_ADDR_FIFO_B_L (REG_BASE + REG_OFFSET_FIFO_B_L)
#define REG_ADDR_FIFO_B_H (REG_BASE + REG_OFFSET_FIFO_B_H)
#define REG_ADDR_DMA0 (REG_BASE + REG_OFFSET_DMA0)
#define REG_ADDR_DMA0SAD (REG_BASE + REG_OFFSET_DMA0SAD)
#define REG_ADDR_DMA0SAD_L (REG_BASE + REG_OFFSET_DMA0SAD_L)
#define REG_ADDR_DMA0SAD_H (REG_BASE + REG_OFFSET_DMA0SAD_H)
#define REG_ADDR_DMA0DAD (REG_BASE + REG_OFFSET_DMA0DAD)
#define REG_ADDR_DMA0DAD_L (REG_BASE + REG_OFFSET_DMA0DAD_L)
#define REG_ADDR_DMA0DAD_H (REG_BASE + REG_OFFSET_DMA0DAD_H)
#define REG_ADDR_DMA0CNT (REG_BASE + REG_OFFSET_DMA0CNT)
#define REG_ADDR_DMA0CNT_L (REG_BASE + REG_OFFSET_DMA0CNT_L)
#define REG_ADDR_DMA0CNT_H (REG_BASE + REG_OFFSET_DMA0CNT_H)
#define REG_ADDR_DMA1 (REG_BASE + REG_OFFSET_DMA1)
#define REG_ADDR_DMA1SAD (REG_BASE + REG_OFFSET_DMA1SAD)
#define REG_ADDR_DMA1SAD_L (REG_BASE + REG_OFFSET_DMA1SAD_L)
#define REG_ADDR_DMA1SAD_H (REG_BASE + REG_OFFSET_DMA1SAD_H)
#define REG_ADDR_DMA1DAD (REG_BASE + REG_OFFSET_DMA1DAD)
#define REG_ADDR_DMA1DAD_L (REG_BASE + REG_OFFSET_DMA1DAD_L)
#define REG_ADDR_DMA1DAD_H (REG_BASE + REG_OFFSET_DMA1DAD_H)
#define REG_ADDR_DMA1CNT (REG_BASE + REG_OFFSET_DMA1CNT)
#define REG_ADDR_DMA1CNT_L (REG_BASE + REG_OFFSET_DMA1CNT_L)
#define REG_ADDR_DMA1CNT_H (REG_BASE + REG_OFFSET_DMA1CNT_H)
#define REG_ADDR_DMA2 (REG_BASE + REG_OFFSET_DMA2)
#define REG_ADDR_DMA2SAD (REG_BASE + REG_OFFSET_DMA2SAD)
#define REG_ADDR_DMA2SAD_L (REG_BASE + REG_OFFSET_DMA2SAD_L)
#define REG_ADDR_DMA2SAD_H (REG_BASE + REG_OFFSET_DMA2SAD_H)
#define REG_ADDR_DMA2DAD (REG_BASE + REG_OFFSET_DMA2DAD)
#define REG_ADDR_DMA2DAD_L (REG_BASE + REG_OFFSET_DMA2DAD_L)
#define REG_ADDR_DMA2DAD_H (REG_BASE + REG_OFFSET_DMA2DAD_H)
#define REG_ADDR_DMA2CNT (REG_BASE + REG_OFFSET_DMA2CNT)
#define REG_ADDR_DMA2CNT_L (REG_BASE + REG_OFFSET_DMA2CNT_L)
#define REG_ADDR_DMA2CNT_H (REG_BASE + REG_OFFSET_DMA2CNT_H)
#define REG_ADDR_DMA3 (REG_BASE + REG_OFFSET_DMA3)
#define REG_ADDR_DMA3SAD (REG_BASE + REG_OFFSET_DMA3SAD)
#define REG_ADDR_DMA3SAD_L (REG_BASE + REG_OFFSET_DMA3SAD_L)
#define REG_ADDR_DMA3SAD_H (REG_BASE + REG_OFFSET_DMA3SAD_H)
#define REG_ADDR_DMA3DAD (REG_BASE + REG_OFFSET_DMA3DAD)
#define REG_ADDR_DMA3DAD_L (REG_BASE + REG_OFFSET_DMA3DAD_L)
#define REG_ADDR_DMA3DAD_H (REG_BASE + REG_OFFSET_DMA3DAD_H)
#define REG_ADDR_DMA3CNT (REG_BASE + REG_OFFSET_DMA3CNT)
#define REG_ADDR_DMA3CNT_L (REG_BASE + REG_OFFSET_DMA3CNT_L)
#define REG_ADDR_DMA3CNT_H (REG_BASE + REG_OFFSET_DMA3CNT_H)
#define REG_ADDR_TMCNT (REG_BASE + REG_OFFSET_TMCNT)
#define REG_ADDR_TM0CNT (REG_BASE + REG_OFFSET_TM0CNT)
#define REG_ADDR_TM0CNT_L (REG_BASE + REG_OFFSET_TM0CNT_L)
#define REG_ADDR_TM0CNT_H (REG_BASE + REG_OFFSET_TM0CNT_H)
@ -344,11 +346,152 @@
#define REG_DISPCNT (*(vu16 *)REG_ADDR_DISPCNT)
#define REG_DISPSTAT (*(vu16 *)REG_ADDR_DISPSTAT)
#define REG_VCOUNT (*(vu16 *)REG_ADDR_VCOUNT)
#define REG_BG0CNT (*(vu16 *)REG_ADDR_BG0CNT)
#define REG_BG1CNT (*(vu16 *)REG_ADDR_BG1CNT)
#define REG_BG2CNT (*(vu16 *)REG_ADDR_BG2CNT)
#define REG_BG3CNT (*(vu16 *)REG_ADDR_BG3CNT)
#define REG_BG0HOFS (*(vu16 *)REG_ADDR_BG0HOFS)
#define REG_BG0VOFS (*(vu16 *)REG_ADDR_BG0VOFS)
#define REG_BG1HOFS (*(vu16 *)REG_ADDR_BG1HOFS)
#define REG_BG1VOFS (*(vu16 *)REG_ADDR_BG1VOFS)
#define REG_BG2HOFS (*(vu16 *)REG_ADDR_BG2HOFS)
#define REG_BG2VOFS (*(vu16 *)REG_ADDR_BG2VOFS)
#define REG_BG3HOFS (*(vu16 *)REG_ADDR_BG3HOFS)
#define REG_BG3VOFS (*(vu16 *)REG_ADDR_BG3VOFS)
#define REG_BG2PA (*(vu16 *)REG_ADDR_BG2PA)
#define REG_BG2PB (*(vu16 *)REG_ADDR_BG2PB)
#define REG_BG2PC (*(vu16 *)REG_ADDR_BG2PC)
#define REG_BG2PD (*(vu16 *)REG_ADDR_BG2PD)
#define REG_BG2X (*(vu32 *)REG_ADDR_BG2X)
#define REG_BG2X_L (*(vu16 *)REG_ADDR_BG2X_L)
#define REG_BG2X_H (*(vu16 *)REG_ADDR_BG2X_H)
#define REG_BG2Y (*(vu32 *)REG_ADDR_BG2Y)
#define REG_BG2Y_L (*(vu16 *)REG_ADDR_BG2Y_L)
#define REG_BG2Y_H (*(vu16 *)REG_ADDR_BG2Y_H)
#define REG_BG3PA (*(vu16 *)REG_ADDR_BG3PA)
#define REG_BG3PB (*(vu16 *)REG_ADDR_BG3PB)
#define REG_BG3PC (*(vu16 *)REG_ADDR_BG3PC)
#define REG_BG3PD (*(vu16 *)REG_ADDR_BG3PD)
#define REG_BG3X (*(vu32 *)REG_ADDR_BG3X)
#define REG_BG3X_L (*(vu16 *)REG_ADDR_BG3X_L)
#define REG_BG3X_H (*(vu16 *)REG_ADDR_BG3X_H)
#define REG_BG3Y (*(vu32 *)REG_ADDR_BG3Y)
#define REG_BG3Y_L (*(vu16 *)REG_ADDR_BG3Y_L)
#define REG_BG3Y_H (*(vu16 *)REG_ADDR_BG3Y_H)
#define REG_WIN0H (*(vu16 *)REG_ADDR_WIN0H)
#define REG_WIN1H (*(vu16 *)REG_ADDR_WIN1H)
#define REG_WIN0V (*(vu16 *)REG_ADDR_WIN0V)
#define REG_WIN1V (*(vu16 *)REG_ADDR_WIN1V)
#define REG_WININ (*(vu16 *)REG_ADDR_WININ)
#define REG_WINOUT (*(vu16 *)REG_ADDR_WINOUT)
#define REG_MOSAIC (*(vu16 *)REG_ADDR_MOSAIC)
#define REG_BLDCNT (*(vu16 *)REG_ADDR_BLDCNT)
#define REG_BLDALPHA (*(vu16 *)REG_ADDR_BLDALPHA)
#define REG_BLDY (*(vu16 *)REG_ADDR_BLDY)
#define REG_SOUND1CNT_L (*(vu16 *)REG_ADDR_SOUND1CNT_L)
#define REG_NR10 (*(vu8 *)REG_ADDR_NR10)
#define REG_SOUND1CNT_H (*(vu16 *)REG_ADDR_SOUND1CNT_H)
#define REG_NR11 (*(vu8 *)REG_ADDR_NR11)
#define REG_NR12 (*(vu8 *)REG_ADDR_NR12)
#define REG_SOUND1CNT_X (*(vu16 *)REG_ADDR_SOUND1CNT_X)
#define REG_NR13 (*(vu8 *)REG_ADDR_NR13)
#define REG_NR14 (*(vu8 *)REG_ADDR_NR14)
#define REG_SOUND2CNT_L (*(vu16 *)REG_ADDR_SOUND2CNT_L)
#define REG_NR21 (*(vu8 *)REG_ADDR_NR21)
#define REG_NR22 (*(vu8 *)REG_ADDR_NR22)
#define REG_SOUND2CNT_H (*(vu16 *)REG_ADDR_SOUND2CNT_H)
#define REG_NR23 (*(vu8 *)REG_ADDR_NR23)
#define REG_NR24 (*(vu8 *)REG_ADDR_NR24)
#define REG_SOUND3CNT_L (*(vu16 *)REG_ADDR_SOUND3CNT_L)
#define REG_NR30 (*(vu8 *)REG_ADDR_NR30)
#define REG_SOUND3CNT_H (*(vu16 *)REG_ADDR_SOUND3CNT_H)
#define REG_NR31 (*(vu8 *)REG_ADDR_NR31)
#define REG_NR32 (*(vu8 *)REG_ADDR_NR32)
#define REG_SOUND3CNT_X (*(vu16 *)REG_ADDR_SOUND3CNT_X)
#define REG_NR33 (*(vu8 *)REG_ADDR_NR33)
#define REG_NR34 (*(vu8 *)REG_ADDR_NR34)
#define REG_SOUND4CNT_L (*(vu16 *)REG_ADDR_SOUND4CNT_L)
#define REG_NR41 (*(vu8 *)REG_ADDR_NR41)
#define REG_NR42 (*(vu8 *)REG_ADDR_NR42)
#define REG_SOUND4CNT_H (*(vu16 *)REG_ADDR_SOUND4CNT_H)
#define REG_NR43 (*(vu8 *)REG_ADDR_NR43)
#define REG_NR44 (*(vu8 *)REG_ADDR_NR44)
#define REG_SOUNDCNT_L (*(vu16 *)REG_ADDR_SOUNDCNT_L)
#define REG_NR50 (*(vu8 *)REG_ADDR_NR50)
#define REG_NR51 (*(vu8 *)REG_ADDR_NR51)
#define REG_SOUNDCNT_H (*(vu16 *)REG_ADDR_SOUNDCNT_H)
#define REG_SOUNDCNT_X (*(vu16 *)REG_ADDR_SOUNDCNT_X)
#define REG_NR52 (*(vu8 *)REG_ADDR_NR52)
#define REG_SOUNDBIAS (*(vu16 *)REG_ADDR_SOUNDBIAS)
#define REG_SOUNDBIAS_L (*(vu8 *)REG_ADDR_SOUNDBIAS_L)
#define REG_SOUNDBIAS_H (*(vu8 *)REG_ADDR_SOUNDBIAS_H)
#define REG_WAVE_RAM0 (*(vu32 *)REG_ADDR_WAVE_RAM0)
#define REG_WAVE_RAM1 (*(vu32 *)REG_ADDR_WAVE_RAM1)
#define REG_WAVE_RAM2 (*(vu32 *)REG_ADDR_WAVE_RAM2)
#define REG_WAVE_RAM3 (*(vu32 *)REG_ADDR_WAVE_RAM3)
#define REG_FIFO_A (*(vu32 *)REG_ADDR_FIFO_A)
#define REG_FIFO_B (*(vu32 *)REG_ADDR_FIFO_B)
#define REG_DMA0SAD (*(vu32 *)REG_ADDR_DMA0SAD)
#define REG_DMA0DAD (*(vu32 *)REG_ADDR_DMA0DAD)
#define REG_DMA0CNT (*(vu32 *)REG_ADDR_DMA0CNT)
#define REG_DMA0CNT_L (*(vu16 *)REG_ADDR_DMA0CNT_L)
#define REG_DMA0CNT_H (*(vu16 *)REG_ADDR_DMA0CNT_H)
#define REG_DMA1SAD (*(vu32 *)REG_ADDR_DMA1SAD)
#define REG_DMA1DAD (*(vu32 *)REG_ADDR_DMA1DAD)
#define REG_DMA1CNT (*(vu32 *)REG_ADDR_DMA1CNT)
#define REG_DMA1CNT_L (*(vu16 *)REG_ADDR_DMA1CNT_L)
#define REG_DMA1CNT_H (*(vu16 *)REG_ADDR_DMA1CNT_H)
#define REG_DMA2SAD (*(vu32 *)REG_ADDR_DMA2SAD)
#define REG_DMA2DAD (*(vu32 *)REG_ADDR_DMA2DAD)
#define REG_DMA2CNT (*(vu32 *)REG_ADDR_DMA2CNT)
#define REG_DMA2CNT_L (*(vu16 *)REG_ADDR_DMA2CNT_L)
#define REG_DMA2CNT_H (*(vu16 *)REG_ADDR_DMA2CNT_H)
#define REG_DMA3SAD (*(vu32 *)REG_ADDR_DMA3SAD)
#define REG_DMA3DAD (*(vu32 *)REG_ADDR_DMA3DAD)
#define REG_DMA3CNT (*(vu32 *)REG_ADDR_DMA3CNT)
#define REG_DMA3CNT_L (*(vu16 *)REG_ADDR_DMA3CNT_L)
#define REG_DMA3CNT_H (*(vu16 *)REG_ADDR_DMA3CNT_H)
#define REG_TMCNT(n) (*(vu16 *)(REG_ADDR_TMCNT + ((n) * 4)))
#define REG_TM0CNT (*(vu32 *)REG_ADDR_TM0CNT)
#define REG_TM0CNT_L (*(vu16 *)REG_ADDR_TM0CNT_L)
#define REG_TM0CNT_H (*(vu16 *)REG_ADDR_TM0CNT_H)
#define REG_TM1CNT (*(vu32 *)REG_ADDR_TM1CNT)
#define REG_TM1CNT_L (*(vu16 *)REG_ADDR_TM1CNT_L)
#define REG_TM1CNT_H (*(vu16 *)REG_ADDR_TM1CNT_H)
#define REG_TM2CNT (*(vu32 *)REG_ADDR_TM2CNT)
#define REG_TM2CNT_L (*(vu16 *)REG_ADDR_TM2CNT_L)
#define REG_TM2CNT_H (*(vu16 *)REG_ADDR_TM2CNT_H)
#define REG_TM3CNT (*(vu32 *)REG_ADDR_TM3CNT)
#define REG_TM3CNT_L (*(vu16 *)REG_ADDR_TM3CNT_L)
#define REG_TM3CNT_H (*(vu16 *)REG_ADDR_TM3CNT_H)
#define REG_SIOCNT (*(vu16 *)REG_ADDR_SIOCNT)
#define REG_SIODATA8 (*(vu16 *)REG_ADDR_SIODATA8)
#define REG_SIODATA32 (*(vu32 *)REG_ADDR_SIODATA32)
#define REG_SIOMLT_SEND (*(vu16 *)REG_ADDR_SIOMLT_SEND)
#define REG_SIOMLT_RECV (*(vu64 *)REG_ADDR_SIOMLT_RECV)
#define REG_SIOMULTI0 (*(vu16 *)REG_ADDR_SIOMULTI0)
#define REG_SIOMULTI1 (*(vu16 *)REG_ADDR_SIOMULTI1)
#define REG_SIOMULTI2 (*(vu16 *)REG_ADDR_SIOMULTI2)
#define REG_SIOMULTI3 (*(vu16 *)REG_ADDR_SIOMULTI3)
#define REG_KEYINPUT (*(vu16 *)REG_ADDR_KEYINPUT)
#define REG_KEYCNT (*(vu16 *)REG_ADDR_KEYCNT)
#define REG_RCNT (*(vu16 *)REG_ADDR_RCNT)
#define REG_IME (*(vu16 *)REG_ADDR_IME)
#define REG_IE (*(vu16 *)REG_ADDR_IE)
#define REG_IF (*(vu16 *)REG_ADDR_IF)
#define REG_WAITCNT (*(vu16 *)REG_ADDR_WAITCNT)
// I/O register fields
// DISPCNT
@ -360,6 +503,15 @@
#define DISPCNT_MODE_5 0x0005
#define DISPCNT_OBJ_1D_MAP 0x0040
#define DISPCNT_FORCED_BLANK 0x0080
#define DISPCNT_BG0_ON 0x0100
#define DISPCNT_BG1_ON 0x0200
#define DISPCNT_BG2_ON 0x0400
#define DISPCNT_BG3_ON 0x0800
#define DISPCNT_BG_ALL_ON 0x0F00
#define DISPCNT_OBJ_ON 0x1000
#define DISPCNT_WIN0_ON 0x2000
#define DISPCNT_WIN1_ON 0x4000
#define DISPCNT_OBJWIN_ON 0x8000
// DISPSTAT
#define DISPSTAT_VBLANK 0x0001 // in V-Blank
@ -369,6 +521,102 @@
#define DISPSTAT_HBLANK_INTR 0x0010 // H-Blank interrupt enabled
#define DISPSTAT_VCOUNT_INTR 0x0020 // V-Count interrupt enabled
// SOUNDCNT_H
#define SOUND_CGB_MIX_QUARTER 0x0000
#define SOUND_CGB_MIX_HALF 0x0001
#define SOUND_CGB_MIX_FULL 0x0002
#define SOUND_A_MIX_HALF 0x0000
#define SOUND_A_MIX_FULL 0x0004
#define SOUND_B_MIX_HALF 0x0000
#define SOUND_B_MIX_FULL 0x0008
#define SOUND_ALL_MIX_FULL 0x000E
#define SOUND_A_RIGHT_OUTPUT 0x0100
#define SOUND_A_LEFT_OUTPUT 0x0200
#define SOUND_A_TIMER_0 0x0000
#define SOUND_A_TIMER_1 0x0400
#define SOUND_A_FIFO_RESET 0x0800
#define SOUND_B_RIGHT_OUTPUT 0x1000
#define SOUND_B_LEFT_OUTPUT 0x2000
#define SOUND_B_TIMER_0 0x0000
#define SOUND_B_TIMER_1 0x4000
#define SOUND_B_FIFO_RESET 0x8000
// SOUNDCNT_X
#define SOUND_1_ON 0x0001
#define SOUND_2_ON 0x0002
#define SOUND_3_ON 0x0004
#define SOUND_4_ON 0x0008
#define SOUND_MASTER_ENABLE 0x0080
// DMA
#define DMA_DEST_INC 0x0000
#define DMA_DEST_DEC 0x0020
#define DMA_DEST_FIXED 0x0040
#define DMA_DEST_RELOAD 0x0060
#define DMA_SRC_INC 0x0000
#define DMA_SRC_DEC 0x0080
#define DMA_SRC_FIXED 0x0100
#define DMA_REPEAT 0x0200
#define DMA_16BIT 0x0000
#define DMA_32BIT 0x0400
#define DMA_DREQ_ON 0x0800
#define DMA_START_NOW 0x0000
#define DMA_START_VBLANK 0x1000
#define DMA_START_HBLANK 0x2000
#define DMA_START_SPECIAL 0x3000
#define DMA_START_MASK 0x3000
#define DMA_INTR_ENABLE 0x4000
#define DMA_ENABLE 0x8000
// timer
#define TIMER_1CLK 0x00
#define TIMER_64CLK 0x01
#define TIMER_256CLK 0x02
#define TIMER_1024CLK 0x03
#define TIMER_INTR_ENABLE 0x40
#define TIMER_ENABLE 0x80
// serial
#define SIO_8BIT_MODE 0x0000 // Normal 8-bit communication mode
#define SIO_32BIT_MODE 0x1000 // Normal 32-bit communication mode
#define SIO_MULTI_MODE 0x2000 // Multi-player communication mode
#define SIO_UART_MODE 0x3000 // UART communication mode
#define SIO_9600_BPS 0x0000 // baud rate 9600 bps
#define SIO_38400_BPS 0x0001 // 38400 bps
#define SIO_57600_BPS 0x0002 // 57600 bps
#define SIO_115200_BPS 0x0003 // 115200 bps
#define SIO_MULTI_SI 0x0004 // Multi-player communication SI terminal
#define SIO_MULTI_SD 0x0008 // SD terminal
#define SIO_ERROR 0x0040 // Detect error
#define SIO_START 0x0080 // Start transfer
#define SIO_ENABLE 0x0080 // Enable SIO
#define SIO_INTR_ENABLE 0x4000
#define SIO_MULTI_SI_SHIFT 2
#define SIO_MULTI_SI_MASK 0x1
#define SIO_MULTI_DI_SHIFT 3
#define SIO_MULTI_DI_MASK 0x1
// keys
#define A_BUTTON 0x0001
#define B_BUTTON 0x0002
#define SELECT_BUTTON 0x0004
#define START_BUTTON 0x0008
#define DPAD_RIGHT 0x0010
#define DPAD_LEFT 0x0020
#define DPAD_UP 0x0040
#define DPAD_DOWN 0x0080
#define R_BUTTON 0x0100
#define L_BUTTON 0x0200
#define KEYS_MASK 0x03FF
#define KEY_INTR_ENABLE 0x0400
#define KEY_OR_INTR 0x0000
#define KEY_AND_INTR 0x8000
// interrupt flags
#define INTR_FLAG_VBLANK (1 << 0)
#define INTR_FLAG_HBLANK (1 << 1)
@ -385,4 +633,49 @@
#define INTR_FLAG_KEYPAD (1 << 12)
#define INTR_FLAG_GAMEPAK (1 << 13)
// WAITCNT
#define WAITCNT_SRAM_4 (0 << 0)
#define WAITCNT_SRAM_3 (1 << 0)
#define WAITCNT_SRAM_2 (2 << 0)
#define WAITCNT_SRAM_8 (3 << 0)
#define WAITCNT_SRAM_MASK (3 << 0)
#define WAITCNT_WS0_N_4 (0 << 2)
#define WAITCNT_WS0_N_3 (1 << 2)
#define WAITCNT_WS0_N_2 (2 << 2)
#define WAITCNT_WS0_N_8 (3 << 2)
#define WAITCNT_WS0_N_MASK (3 << 2)
#define WAITCNT_WS0_S_2 (0 << 4)
#define WAITCNT_WS0_S_1 (1 << 4)
#define WAITCNT_WS1_N_4 (0 << 5)
#define WAITCNT_WS1_N_3 (1 << 5)
#define WAITCNT_WS1_N_2 (2 << 5)
#define WAITCNT_WS1_N_8 (3 << 5)
#define WAITCNT_WS1_N_MASK (3 << 5)
#define WAITCNT_WS1_S_4 (0 << 7)
#define WAITCNT_WS1_S_1 (1 << 7)
#define WAITCNT_WS2_N_4 (0 << 8)
#define WAITCNT_WS2_N_3 (1 << 8)
#define WAITCNT_WS2_N_2 (2 << 8)
#define WAITCNT_WS2_N_8 (3 << 8)
#define WAITCNT_WS2_N_MASK (3 << 8)
#define WAITCNT_WS2_S_8 (0 << 10)
#define WAITCNT_WS2_S_1 (1 << 10)
#define WAITCNT_PHI_OUT_NONE (0 << 11)
#define WAITCNT_PHI_OUT_4MHZ (1 << 11)
#define WAITCNT_PHI_OUT_8MHZ (2 << 11)
#define WAITCNT_PHI_OUT_16MHZ (3 << 11)
#define WAITCNT_PHI_OUT_MASK (3 << 11)
#define WAITCNT_PREFETCH_ENABLE (1 << 14)
#define WAITCNT_AGB (0 << 15)
#define WAITCNT_CGB (1 << 15)
#endif // GUARD_GBA_IO_REG_H

462
include/gba/m4a_internal.h Normal file
View File

@ -0,0 +1,462 @@
#include "gba/gba.h"
// ASCII encoding of 'Smsh' in reverse
// This is presumably short for SMASH, the developer of MKS4AGB.
#define ID_NUMBER 0x68736D53
#define C_V 0x40 // center value for PAN, BEND, and TUNE
#define SOUND_MODE_REVERB_VAL 0x0000007F
#define SOUND_MODE_REVERB_SET 0x00000080
#define SOUND_MODE_MAXCHN 0x00000F00
#define SOUND_MODE_MAXCHN_SHIFT 8
#define SOUND_MODE_MASVOL 0x0000F000
#define SOUND_MODE_MASVOL_SHIFT 12
#define SOUND_MODE_FREQ_05734 0x00010000
#define SOUND_MODE_FREQ_07884 0x00020000
#define SOUND_MODE_FREQ_10512 0x00030000
#define SOUND_MODE_FREQ_13379 0x00040000
#define SOUND_MODE_FREQ_15768 0x00050000
#define SOUND_MODE_FREQ_18157 0x00060000
#define SOUND_MODE_FREQ_21024 0x00070000
#define SOUND_MODE_FREQ_26758 0x00080000
#define SOUND_MODE_FREQ_31536 0x00090000
#define SOUND_MODE_FREQ_36314 0x000A0000
#define SOUND_MODE_FREQ_40137 0x000B0000
#define SOUND_MODE_FREQ_42048 0x000C0000
#define SOUND_MODE_FREQ 0x000F0000
#define SOUND_MODE_FREQ_SHIFT 16
#define SOUND_MODE_DA_BIT_9 0x00800000
#define SOUND_MODE_DA_BIT_8 0x00900000
#define SOUND_MODE_DA_BIT_7 0x00A00000
#define SOUND_MODE_DA_BIT_6 0x00B00000
#define SOUND_MODE_DA_BIT 0x00B00000
#define SOUND_MODE_DA_BIT_SHIFT 20
struct WaveData
{
u16 type;
u16 status;
u32 freq;
u32 loopStart;
u32 size; // number of samples
s8 data[1]; // samples
};
#define TONEDATA_TYPE_CGB 0x07
#define TONEDATA_TYPE_FIX 0x08
#define TONEDATA_TYPE_SPL 0x40 // key split
#define TONEDATA_TYPE_RHY 0x80 // rhythm
#define TONEDATA_P_S_PAN 0xc0
#define TONEDATA_P_S_PAM TONEDATA_P_S_PAN
struct ToneData
{
u8 type;
u8 key;
u8 length; // sound length (compatible sound)
u8 pan_sweep; // pan or sweep (compatible sound ch. 1)
struct WaveData *wav;
u8 attack;
u8 decay;
u8 sustain;
u8 release;
};
struct CgbChannel
{
u8 sf;
u8 ty;
u8 rightVolume;
u8 leftVolume;
u8 at;
u8 de;
u8 su;
u8 re;
u8 ky;
u8 ev;
u8 eg;
u8 ec;
u8 echoVolume;
u8 echoLength;
u8 d1;
u8 d2;
u8 gt;
u8 mk;
u8 ve;
u8 pr;
u8 rp;
u8 d3[3];
u8 d5;
u8 sg;
u8 n4;
u8 pan;
u8 panMask;
u8 mo;
u8 le;
u8 sw;
u32 fr;
u32 wp;
u32 cp;
u32 tp;
u32 pp;
u32 np;
u8 d4[8];
};
struct MusicPlayerTrack;
struct SoundChannel
{
u8 status;
u8 type;
u8 rightVolume;
u8 leftVolume;
u8 attack;
u8 decay;
u8 sustain;
u8 release;
u8 ky;
u8 ev;
u8 er;
u8 el;
u8 echoVolume;
u8 echoLength;
u8 d1;
u8 d2;
u8 gt;
u8 mk;
u8 ve;
u8 pr;
u8 rp;
u8 d3[3];
u32 ct;
u32 fw;
u32 freq;
struct WaveData *wav;
u32 cp;
struct MusicPlayerTrack *track;
u32 pp;
u32 np;
u32 d4;
u16 xpi;
u16 xpc;
};
#define MAX_DIRECTSOUND_CHANNELS 12
#define PCM_DMA_BUF_SIZE 1584 // size of Direct Sound buffer
struct SoundInfo
{
// This field is normally equal to ID_NUMBER but it is set to other
// values during sensitive operations for locking purposes.
// This field should be volatile but isn't. This could potentially cause
// race conditions.
u32 ident;
vu8 pcmDmaCounter;
// Direct Sound
u8 reverb;
u8 maxChans;
u8 masterVolume;
u8 freq;
u8 mode;
u8 c15;
u8 pcmDmaPeriod; // number of V-blanks per PCM DMA
u8 maxLines;
u8 gap[3];
s32 pcmSamplesPerVBlank;
s32 pcmFreq;
s32 divFreq;
struct CgbChannel *cgbChans;
u32 func;
u32 intp;
void (*CgbSound)(void);
void (*CgbOscOff)(u8);
u32 (*MidiKeyToCgbFreq)(u8, u8, u8);
u32 MPlayJumpTable;
u32 plynote;
u32 ExtVolPit;
u8 gap2[16];
struct SoundChannel chans[MAX_DIRECTSOUND_CHANNELS];
s8 pcmBuffer[PCM_DMA_BUF_SIZE * 2];
};
struct SongHeader
{
u8 trackCount;
u8 blockCount;
u8 priority;
u8 reverb;
struct ToneData *tone;
u8 *part[1];
};
struct PokemonCrySong
{
u8 trackCount;
u8 blockCount;
u8 priority;
u8 reverb;
struct ToneData *tone;
u8 *part[2];
u8 gap;
u8 part0; // 0x11
u8 tuneValue; // 0x12
u8 gotoCmd; // 0x13
u32 gotoTarget; // 0x14
u8 part1; // 0x18
u8 tuneValue2; // 0x19
u8 cont[2]; // 0x1A
u8 volCmd; // 0x1C
u8 volumeValue; // 0x1D
u8 unkCmd0D[2]; // 0x1E
u32 unkCmd0DParam; // 0x20
u8 xreleCmd[2]; // 0x24
u8 releaseValue; // 0x26
u8 panCmd;
u8 panValue; // 0x28
u8 tieCmd; // 0x29
u8 tieKeyValue; // 0x2A
u8 tieVelocityValue; // 0x2B
u8 unkCmd0C[2]; // 0x2C
u16 unkCmd0CParam; // 0x2E
u8 end[2]; // 0x30
};
#define MPT_FLG_VOLSET 0x01
#define MPT_FLG_VOLCHG 0x03
#define MPT_FLG_PITSET 0x04
#define MPT_FLG_PITCHG 0x0C
#define MPT_FLG_START 0x40
#define MPT_FLG_EXIST 0x80
struct MusicPlayerTrack
{
u8 flags;
u8 wait;
u8 patternLevel;
u8 repN;
u8 gateTime;
u8 key;
u8 velocity;
u8 runningStatus;
u8 keyM;
u8 pitM;
s8 keyShift;
s8 keyShiftX;
s8 tune;
u8 pitX;
s8 bend;
u8 bendRange;
u8 volMR;
u8 volML;
u8 vol;
u8 volX;
s8 pan;
s8 panX;
s8 modM;
u8 mod;
u8 modT;
u8 lfoSpeed;
u8 lfoSpeedC;
u8 lfoDelay;
u8 lfoDelayC;
u8 priority;
u8 echoVolume;
u8 echoLength;
struct SoundChannel *chan;
struct ToneData tone;
u8 gap[10];
u16 unk_3A;
u32 unk_3C;
u8 *cmdPtr;
u8 *patternStack[3];
};
#define MUSICPLAYER_STATUS_TRACK 0x0000ffff
#define MUSICPLAYER_STATUS_PAUSE 0x80000000
#define MAX_MUSICPLAYER_TRACKS 16
#define TEMPORARY_FADE 0x0001
#define FADE_IN 0x0002
#define FADE_VOL_MAX 64
#define FADE_VOL_SHIFT 2
struct MusicPlayerInfo
{
struct SongHeader *songHeader;
u32 status;
u8 trackCount;
u8 priority;
u8 cmd;
u8 unk_B;
u32 clock;
u8 gap[8];
u8 *memAccArea;
u16 tempoD;
u16 tempoU;
u16 tempoI;
u16 tempoC;
u16 fadeOI;
u16 fadeOC;
u16 fadeOV;
struct MusicPlayerTrack *tracks;
struct ToneData *tone;
u32 ident;
u32 func;
u32 intp;
};
struct MusicPlayer
{
struct MusicPlayerInfo *info;
struct MusicPlayerTrack *track;
u8 unk_8;
u16 unk_A;
};
struct Song
{
struct SongHeader *header;
u16 ms;
u16 me;
};
extern const struct MusicPlayer gMPlayTable[];
extern const struct Song gSongTable[];
extern u8 gMPlayMemAccArea[];
//u8 gPokemonCrySong[52];
//u8 gPokemonCrySongs[52 * MAX_POKEMON_CRIES];
#define MAX_POKEMON_CRIES 2
extern struct PokemonCrySong gPokemonCrySong;
extern struct PokemonCrySong gPokemonCrySongs[];
extern struct MusicPlayerInfo gPokemonCryMusicPlayers[];
extern struct MusicPlayerTrack gPokemonCryTracks[];
extern char SoundMainRAM[];
extern void *gMPlayJumpTable[];
typedef void (*XcmdFunc)(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
extern const XcmdFunc gXcmdTable[];
extern struct CgbChannel gCgbChans[];
extern const u8 gScaleTable[];
extern const u32 gFreqTable[];
extern const u16 gPcmSamplesPerVBlankTable[];
extern const u8 gCgbScaleTable[];
extern const s16 gCgbFreqTable[];
extern const u8 gNoiseTable[];
extern const struct PokemonCrySong gPokemonCrySongTemplate;
extern const struct ToneData voicegroup_842FC88;
extern char gNumMusicPlayers[];
extern char gMaxLines[];
#define NUM_MUSIC_PLAYERS ((u16)gNumMusicPlayers)
#define MAX_LINES ((u32)gMaxLines)
u32 umul3232H32(u32 multiplier, u32 multiplicand);
void SoundMain(void);
void SoundMainBTM(void);
void TrackStop(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track);
void MPlayMain(void);
void RealClearChain(void *x);
void MPlayContinue(struct MusicPlayerInfo *mplayInfo);
void MPlayStart(struct MusicPlayerInfo *mplayInfo, struct SongHeader *songHeader);
void m4aMPlayStop(struct MusicPlayerInfo *mplayInfo);
void FadeOutBody(struct MusicPlayerInfo *mplayInfo);
void TrkVolPitSet(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track);
void MPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed);
void ClearChain(void *x);
void Clear64byte(void *addr);
void SoundInit(struct SoundInfo *soundInfo);
void MPlayExtender(struct CgbChannel *cgbChans);
void m4aSoundMode(u32 mode);
void MPlayOpen(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track, u8 a3);
void CgbSound(void);
void CgbOscOff(u8);
u32 MidiKeyToCgbFreq(u8, u8, u8);
void DummyFunc(void);
void MPlayJumpTableCopy(void **mplayJumpTable);
void SampleFreqSet(u32 freq);
void m4aSoundVSyncOn(void);
void m4aSoundVSyncOff(void);
void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo);
void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume);
void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 pitch);
void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan);
void ClearModM(struct MusicPlayerTrack *track);
void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth);
void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed);
struct MusicPlayerInfo *SetPokemonCryTone(struct ToneData *tone);
void SetPokemonCryVolume(u8 val);
void SetPokemonCryPanpot(s8 val);
void SetPokemonCryPitch(s16 val);
void SetPokemonCryLength(u16 val);
void SetPokemonCryRelease(u8 val);
void SetPokemonCryProgress(u32 val);
int IsPokemonCryPlaying(struct MusicPlayerInfo *mplayInfo);
void SetPokemonCryChorus(s8 val);
void SetPokemonCryStereo(u32 val);
void SetPokemonCryPriority(u8 val);
// sound command handler functions
void ply_fine(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_goto(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_patt(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_pend(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_rept(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_memacc(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_prio(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_tempo(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_keysh(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_voice(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_vol(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_pan(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_bend(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_bendr(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_lfos(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_lfodl(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_mod(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_modt(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_tune(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_port(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xcmd(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_endtie(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_note(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
// extended sound command handler functions
void ply_xxx(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xwave(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xtype(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xatta(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xdeca(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xsust(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xrele(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xiecv(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xiecl(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xleng(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xswee(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xcmd_0C(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
void ply_xcmd_0D(struct MusicPlayerInfo *, struct MusicPlayerTrack *);

View File

@ -1,15 +1,85 @@
#ifndef GUARD_GBA_MACRO_H
#define GUARD_GBA_MACRO_H
#define CPU_FILL(dest, value, size, bit) \
do { \
#define CPU_FILL(value, dest, size, bit) \
{ \
vu##bit tmp = (vu##bit)(value); \
CpuSet((void *)&tmp, \
dest, \
CPU_SET_##bit##BIT | CPU_SET_SRC_FIXED | ((size)/(bit/8) & 0x1FFFFF)); \
} while (0)
}
#define CpuFill16(dest, value, size) CPU_FILL(dest, value, size, 16)
#define CpuFill32(dest, value, size) CPU_FILL(dest, value, size, 32)
#define CpuFill16(value, dest, size) CPU_FILL(value, dest, size, 16)
#define CpuFill32(value, dest, size) CPU_FILL(value, dest, size, 32)
#define CPU_COPY(src, dest, size, bit) CpuSet(src, dest, CPU_SET_##bit##BIT | ((size)/(bit/8) & 0x1FFFFF))
#define CpuCopy16(src, dest, size) CPU_COPY(src, dest, size, 16)
#define CpuCopy32(src, dest, size) CPU_COPY(src, dest, size, 32)
#define CpuFastFill(value, dest, size) \
{ \
vu32 tmp = (vu32)(value); \
CpuFastSet((void *)&tmp, \
dest, \
CPU_FAST_SET_SRC_FIXED | ((size)/(32/8) & 0x1FFFFF)); \
}
#define CpuFastCopy(src, dest, size) CpuFastSet(src, dest, ((size)/(32/8) & 0x1FFFFF))
#define DmaSet(dmaNum, src, dest, control) \
{ \
vu32 *dmaRegs = (vu32 *)REG_ADDR_DMA##dmaNum; \
dmaRegs[0] = (vu32)(src); \
dmaRegs[1] = (vu32)(dest); \
dmaRegs[2] = (vu32)(control); \
dmaRegs[2]; \
}
#define DMA_FILL(dmaNum, value, dest, size, bit) \
{ \
vu##bit tmp = (vu##bit)(value); \
DmaSet(dmaNum, \
&tmp, \
dest, \
(DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_FIXED | DMA_DEST_INC) << 16 \
| ((size)/(bit/8))); \
}
#define DmaFill16(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 16)
#define DmaFill32(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 32)
// Note that the DMA clear macros cause the DMA control value to be calculated
// at runtime rather than compile time. The size is divided by the DMA transfer
// unit size (2 or 4 bytes) and then combined with the DMA control flags using a
// bitwise OR operation.
#define DMA_CLEAR(dmaNum, dest, size, bit) \
{ \
vu##bit *_dest = (vu##bit *)(dest); \
u32 _size = size; \
DmaFill##bit(dmaNum, 0, _dest, _size); \
}
#define DmaClear16(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 16)
#define DmaClear32(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 32)
#define DMA_COPY(dmaNum, src, dest, size, bit) \
DmaSet(dmaNum, \
src, \
dest, \
(DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_INC | DMA_DEST_INC) << 16 \
| ((size)/(bit/8)))
#define DmaCopy16(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 16)
#define DmaCopy32(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 32)
#define DmaStop(dmaNum) \
{ \
vu16 *dmaRegs = (vu16 *)REG_ADDR_DMA##dmaNum; \
dmaRegs[5] &= ~(DMA_START_MASK | DMA_DREQ_ON | DMA_REPEAT); \
dmaRegs[5] &= ~DMA_ENABLE; \
dmaRegs[5]; \
}
#endif // GUARD_GBA_MACRO_H

View File

@ -1,10 +1,32 @@
#ifndef GUARD_GBA_SYSCALL_H
#define GUARD_GBA_SYSCALL_H
#define RESET_EWRAM 0x01
#define RESET_IWRAM 0x02
#define RESET_PALETTE 0x04
#define RESET_VRAM 0x08
#define RESET_OAM 0x10
#define RESET_SIO_REGS 0x20
#define RESET_SOUND_REGS 0x40
#define RESET_REGS 0x80
#define RESET_ALL 0xFF
void SoftReset(u32 resetFlags);
void RegisterRamReset(u32 resetFlags);
void VBlankIntrWait(void);
#define CPU_SET_SRC_FIXED 0x01000000
#define CPU_SET_16BIT 0x00000000
#define CPU_SET_32BIT 0x04000000
extern void CpuSet(void *src, void *dest, u32 controlData);
void CpuSet(const void *src, void *dest, u32 control);
#define CPU_FAST_SET_SRC_FIXED 0x01000000
void CpuFastSet(const void *src, void *dest, u32 control);
void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset);
#endif // GUARD_GBA_SYSCALL_H

108
include/gba/types.h Normal file
View File

@ -0,0 +1,108 @@
#ifndef GUARD_GBA_TYPES_H
#define GUARD_GBA_TYPES_H
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
typedef float f32;
typedef double f64;
typedef u8 bool8;
typedef u16 bool16;
typedef u32 bool32;
struct PlttData
{
u16 r:5; // red
u16 g:5; // green
u16 b:5; // blue
u16 unused_15:1;
};
struct OamData
{
/*0x00*/ u32 y:8;
/*0x01*/ u32 affineMode:2;
u32 objMode:2;
u32 mosaic:1;
u32 bpp:1;
u32 shape:2;
/*0x02*/ u32 x:9;
u32 matrixNum:5; // bits 3/4 are h-flip/v-flip if not in affine mode
u32 size:2;
/*0x04*/ u16 tileNum:10;
u16 priority:2;
u16 paletteNum:4;
/*0x06*/ u16 affineParam;
};
#define ST_OAM_OBJ_NORMAL 0
#define ST_OAM_OBJ_BLEND 1
#define ST_OAM_OBJ_WINDOW 2
#define ST_OAM_AFFINE_OFF 0
#define ST_OAM_AFFINE_NORMAL 1
#define ST_OAM_AFFINE_ERASE 2
#define ST_OAM_AFFINE_DOUBLE 3
#define ST_OAM_AFFINE_ON_MASK 1
#define ST_OAM_AFFINE_DOUBLE_MASK 2
#define ST_OAM_4BPP 0
#define ST_OAM_8BPP 1
#define ST_OAM_SQUARE 0
#define ST_OAM_H_RECTANGLE 1
#define ST_OAM_V_RECTANGLE 2
struct ObjAffineSrcData
{
s16 xScale;
s16 yScale;
u16 rotation;
};
// Multi-player SIO Control Structure
struct SioMultiCnt
{
u16 baudRate:2; // baud rate
u16 si:1; // SI terminal
u16 sd:1; // SD terminal
u16 id:2; // ID
u16 error:1; // error flag
u16 enable:1; // SIO enable
u16 unused_11_8:4;
u16 mode:2; // communication mode (should equal 2)
u16 intrEnable:1; // IRQ enable
u16 unused_15:1;
u16 data; // data
};
#define ST_SIO_MULTI_MODE 2 // Multi-player communication mode
// baud rate
#define ST_SIO_9600_BPS 0 // 9600 bps
#define ST_SIO_38400_BPS 1 // 38400 bps
#define ST_SIO_57600_BPS 2 // 57600 bps
#define ST_SIO_115200_BPS 3 // 115200 bps
#endif // GUARD_GBA_TYPES_H

View File

@ -1,34 +1,6 @@
#ifndef GUARD_GLOBAL_H
#define GUARD_GLOBAL_H
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef float f32;
typedef double f64;
typedef u8 bool8;
typedef u16 bool16;
typedef u32 bool32;
#define NULL (void *)0
#define TRUE 1
#define FALSE 0
#include "gba/io_reg.h"
#include "gba/syscall.h"
#include "gba/macro.h"
#include "gba/gba.h"
#endif // GUARD_GLOBAL_H

29
include/task.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef GUARD_TASK_H
#define GUARD_TASK_H
typedef void (*TaskFunc)(u8 taskId);
struct Task
{
TaskFunc func;
bool8 isActive;
u8 prev;
u8 next;
u8 priority;
s16 data[16];
};
extern struct Task gTasks[];
void ResetTasks();
u8 CreateTask(TaskFunc func, u8 priority);
void DestroyTask(u8 taskId);
void RunTasks();
void TaskDummy(u8 taskId);
void SetTaskFuncWithFollowupFunc(u8 taskId, TaskFunc func, TaskFunc followupFunc);
void SwitchTaskToFollowupFunc(u8 taskId);
bool8 FuncIsActiveTask(TaskFunc func);
u8 FindTaskIdByFunc(TaskFunc func);
u8 GetTaskCount();
#endif // GUARD_TASK_H

View File

@ -10,3 +10,5 @@ gGpuRegWaitingList = 0x03000878;
gGpuRegBufferLocked = 0x030008D8;
gShouldSyncRegIE = 0x030008D9;
gRegIE = 0x030008DA;
gTasks = 0x3005E00;

View File

@ -43,7 +43,7 @@ SECTIONS {
asm/rom_8032654.o(.text);
asm/tileset_animation.o(.text);
asm/rom_80A18F4.o(.text);
asm/task.o(.text);
src/task.o(.text);
asm/rom_80A92F4.o(.text);
asm/multiboot.o(.text);
asm/rom_81BAD84.o(.text);

View File

@ -135,7 +135,7 @@ void *AllocZeroedInternal(void *heapStart, u32 size)
if (size & 3)
size = 4 * ((size / 4) + 1);
CpuFill32(mem, 0, size);
CpuFill32(0, mem, size);
}
return mem;

313
src/task.c Normal file
View File

@ -0,0 +1,313 @@
#include "global.h"
#include "task.h"
#define NUM_TASKS 16
#define HEAD_SENTINEL 0xFE
#define TAIL_SENTINEL 0xFF
struct Task gTasks[NUM_TASKS];
static void InsertTask(u8 newTaskId);
static u8 FindFirstActiveTask();
void ResetTasks()
{
u8 i;
for (i = 0; i < NUM_TASKS; i++)
{
gTasks[i].isActive = FALSE;
gTasks[i].func = TaskDummy;
gTasks[i].prev = i;
gTasks[i].next = i + 1;
gTasks[i].priority = -1;
memset(gTasks[i].data, 0, sizeof(gTasks[i].data));
}
gTasks[0].prev = HEAD_SENTINEL;
gTasks[NUM_TASKS - 1].next = TAIL_SENTINEL;
}
u8 CreateTask(TaskFunc func, u8 priority)
{
u8 i;
for (i = 0; i < NUM_TASKS; i++)
{
if (!gTasks[i].isActive)
{
gTasks[i].func = func;
gTasks[i].priority = priority;
InsertTask(i);
memset(gTasks[i].data, 0, sizeof(gTasks[i].data));
gTasks[i].isActive = TRUE;
return i;
}
}
return 0;
}
#ifdef NONMATCHING
static void InsertTask(u8 newTaskId)
{
u8 taskId = FindFirstActiveTask();
if (taskId == NUM_TASKS)
{
// The new task is the only task.
gTasks[newTaskId].prev = HEAD_SENTINEL;
gTasks[newTaskId].next = TAIL_SENTINEL;
return;
}
for (;;)
{
if (gTasks[newTaskId].priority < gTasks[taskId].priority)
{
// We've found a task with a higher priority value,
// so we insert the new task before it.
gTasks[newTaskId].prev = gTasks[taskId].prev;
gTasks[newTaskId].next = taskId;
if (gTasks[taskId].prev != HEAD_SENTINEL)
gTasks[gTasks[taskId].prev].next = newTaskId;
gTasks[taskId].prev = newTaskId;
return;
}
if (gTasks[taskId].next != TAIL_SENTINEL)
taskId = gTasks[taskId].next;
else
break;
}
// We've reached the end.
gTasks[newTaskId].prev = taskId;
gTasks[newTaskId].next = gTasks[taskId].next;
gTasks[taskId].next = newTaskId;
}
#else
__attribute__((naked))
static void InsertTask(u8 newTaskId)
{
asm("push {r4, r5, r6, r7, lr}\n\
mov r7, r8\n\
push {r7}\n\
lsl r0, r0, #24\n\
lsr r4, r0, #24\n\
bl FindFirstActiveTask\n\
lsl r0, r0, #24\n\
lsr r1, r0, #24\n\
cmp r1, #16\n\
bne .LInsertTask_foundActiveTask\n\
ldr r1, .LInsertTask_gTasks1\n\
lsl r0, r4, #2\n\
add r0, r0, r4\n\
lsl r0, r0, #3\n\
add r0, r0, r1\n\
mov r1, #254\n\
strb r1, [r0, #5]\n\
mov r1, #255\n\
strb r1, [r0, #6]\n\
b .LInsertTask_done\n\
.align 2, 0\n\
.LInsertTask_gTasks1:\n\
.word gTasks\n\
.LInsertTask_foundActiveTask:\n\
ldr r6, .LInsertTask_gTasks2\n\
lsl r0, r4, #2\n\
mov r12, r0\n\
mov r8, r6\n\
add r0, r0, r4\n\
lsl r0, r0, #3\n\
add r2, r0, r6\n\
.LInsertTask_loop:\n\
lsl r0, r1, #2\n\
add r0, r0, r1\n\
lsl r5, r0, #3\n\
mov r7, r8\n\
add r3, r5, r7\n\
ldrb r0, [r2, #7]\n\
ldrb r7, [r3, #7]\n\
cmp r0, r7\n\
bcs .LInsertTask_next\n\
ldrb r0, [r3, #5]\n\
strb r0, [r2, #5]\n\
strb r1, [r2, #6]\n\
ldrb r0, [r3, #5]\n\
cmp r0, #254\n\
beq .LInsertTask_insertAtHead\n\
add r1, r0, #0\n\
lsl r0, r1, #2\n\
add r0, r0, r1\n\
lsl r0, r0, #3\n\
add r0, r0, r8\n\
strb r4, [r0, #6]\n\
.LInsertTask_insertAtHead:\n\
strb r4, [r3, #5]\n\
b .LInsertTask_done\n\
.align 2, 0\n\
.LInsertTask_gTasks2:\n\
.word gTasks\n\
.LInsertTask_next:\n\
ldrb r0, [r3, #6]\n\
cmp r0, #255\n\
beq .LInsertTask_insertAtTail\n\
add r1, r0, #0\n\
b .LInsertTask_loop\n\
.LInsertTask_insertAtTail:\n\
mov r2, r12\n\
add r0, r2, r4\n\
lsl r0, r0, #3\n\
add r0, r0, r6\n\
strb r1, [r0, #5]\n\
add r2, r5, r6\n\
ldrb r1, [r2, #6]\n\
strb r1, [r0, #6]\n\
strb r4, [r2, #6]\n\
.LInsertTask_done:\n\
pop {r3}\n\
mov r8, r3\n\
pop {r4, r5, r6, r7}\n\
pop {r0}\n\
bx r0\n");
}
#endif // NONMATCHING
void DestroyTask(u8 taskId)
{
if (gTasks[taskId].isActive)
{
gTasks[taskId].isActive = FALSE;
if (gTasks[taskId].prev == HEAD_SENTINEL)
{
if (gTasks[taskId].next != TAIL_SENTINEL)
gTasks[gTasks[taskId].next].prev = HEAD_SENTINEL;
}
else
{
if (gTasks[taskId].next == TAIL_SENTINEL)
{
gTasks[gTasks[taskId].prev].next = TAIL_SENTINEL;
}
else
{
gTasks[gTasks[taskId].prev].next = gTasks[taskId].next;
gTasks[gTasks[taskId].next].prev = gTasks[taskId].prev;
}
}
}
}
void RunTasks()
{
u8 taskId = FindFirstActiveTask();
if (taskId != NUM_TASKS)
{
do
{
gTasks[taskId].func(taskId);
taskId = gTasks[taskId].next;
} while (taskId != TAIL_SENTINEL);
}
}
static u8 FindFirstActiveTask()
{
u8 taskId;
for (taskId = 0; taskId < NUM_TASKS; taskId++)
if (gTasks[taskId].isActive == TRUE && gTasks[taskId].prev == HEAD_SENTINEL)
break;
return taskId;
}
void TaskDummy(u8 taskId)
{
}
#define TASK_DATA_OP(taskId, offset, op) \
{ \
u32 tasksAddr = (u32)gTasks; \
u32 addr = taskId * sizeof(struct Task) + offset; \
u32 dataAddr = tasksAddr + offsetof(struct Task, data); \
addr += dataAddr; \
op; \
}
void SetTaskFuncWithFollowupFunc(u8 taskId, TaskFunc func, TaskFunc followupFunc)
{
TASK_DATA_OP(taskId, 28, *((u16 *)addr) = (u32)followupFunc)
TASK_DATA_OP(taskId, 30, *((u16 *)addr) = (u32)followupFunc >> 16)
gTasks[taskId].func = func;
}
void SwitchTaskToFollowupFunc(u8 taskId)
{
s32 func;
gTasks[taskId].func = NULL;
TASK_DATA_OP(taskId, 28, func = *((u16 *)addr))
TASK_DATA_OP(taskId, 30, func |= *((s16 *)addr) << 16)
gTasks[taskId].func = (TaskFunc)func;
}
bool8 FuncIsActiveTask(TaskFunc func)
{
u8 i;
for (i = 0; i < NUM_TASKS; i++)
if (gTasks[i].isActive == TRUE && gTasks[i].func == func)
return TRUE;
return FALSE;
}
u8 FindTaskIdByFunc(TaskFunc func)
{
s32 i;
for (i = 0; i < NUM_TASKS; i++)
if (gTasks[i].isActive == TRUE && gTasks[i].func == func)
return (u8)i;
return -1;
}
u8 GetTaskCount()
{
u8 i;
u8 count = 0;
for (i = 0; i < NUM_TASKS; i++)
if (gTasks[i].isActive == TRUE)
count++;
return count;
}
void SetWordTaskArg(u8 taskId, u8 dataElem, u32 value)
{
if (dataElem <= 0xE)
{
gTasks[taskId].data[dataElem] = value;
gTasks[taskId].data[dataElem + 1] = value >> 16;
}
return;
}
u32 GetWordTaskArg(u8 taskId, u8 dataElem)
{
if (dataElem <= 0xE)
return (u16)gTasks[taskId].data[dataElem] | (gTasks[taskId].data[dataElem + 1] << 16);
else
return 0;
}