• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Help Thread: ASM & Disassembly

Status
Not open for further replies.

miksy91

Dark Energy is back in action! ;)
1,480
Posts
15
Years
Ok... You kind of made me both less and more confused at the same time. I assumed jr z was something like "jump if equal to" but seeing as it means "jump if zero" makes more sense.

So, as I want it to be 0 if the values are the same, would my code example
ld a,[wcf91] cp a,GREAT_BALL ld a,8 jr z,.skip1 ld a,[wcf91] cp a,ULTRA_BALL ld a,4 jr z,.skip1 ld a,12be what I want to use to make it work properly?
P.S. The .skip1 is right after "ld a,12", so that thing about being near in bytes I don't need to worry about.
In that case when the CPU starts executing code starting at address ".skip1", register a would have value 0x8 if you had Great Ball, 0x4 if you had Ultra Ball and 0x12 otherwise. In case that's what you're intending to do, surely works :)

Better programming style would probably be storing the value of [wcf91] in some other register while this code is run though. You could for example push one of the other register pairs onto stack (which is for example a memory area in work ram between $DF00-$DFFF in Gold and Silver) and then use one of its registers for storing the value.
Basically, you could do the following:

Code:
push bc
ld a,[wcf91]
ld b, a
cp a, GREAT BALL
ld a, 8
jr z, .skip1
ld a, b
cp a, ULTRA BALL
...
and so on. At ".skip1" you could simply make the game execute pop bc to get the value back from stack. This would make registers b and c get their original values back and set the stack pointer (= SP register pair) to point to the value that was originally at the top of the stack.

In case you're wondering what stack (in GB/C hardware) is, it's a data structure that is used for storing values of register pairs for further usage. One good example of stack usage is calling subroutines.

Whenever "call" command is executed, the address of the instruction that is "after" the call command is pushed onto stack, and "jump" to the called address is executed. Now a subroutine is called. When the subroutine finally ends (after possibly calling several other subroutines which could have also called other subroutines and so on) by "ret" command, two bytes are popped out of the top of the stack and "jump code is executed to the address these bytes refer/point to". This "jump" basically means setting the those bytes as the new 16-bit (or 2-byte) value of program counter (= PC register pair which tells where the next instruction to be executed is loaded from). Now because the address of the instruction after call command was pushed onto stack (when the subroutine was called), this address is put into PC and the next instruction to be executed is that (and this is how call command works).

Similarly you can push other register pairs onto stack as well, save their original values there, and pop them out of the stack when you don't need to use them "for your own purposes" anymore. Doing stuff like this might be "cleaner" in the code you're writing.
 
Last edited:
130
Posts
8
Years
  • Age 28
  • Seen Jun 14, 2023
In that case when the CPU starts executing code starting at address ".skip1", register a would have value 0x8 if you had Great Ball, 0x4 if you had Ultra Ball and 0x12 otherwise. In case that's what you're intending to do, surely works :)

Yes that's exactly what I'm trying to do. That's all I needed to know, if it works or not. I didn't want to use b (or any other letter) because a was already being used in that section by the value of the Pokeball and then the ball factor. So at the small chance that by changing b, I could be changing a value already set, I could ultimately be creating another bug (but then I read again that you said push and pop. nvm). But thanks anyway. My first GAMEFREAK bug squashed ^_^ (and without any prior knowledge of ASM).

[EDIT] I posted on the ASM resource thread but totally forgot about this help thread which I should have put my post on. I want to make abilities like Overgrow, Torrent, Blaze, and Swarm that power up moves when the user is 33% HP or less.

But could someone please... (for Fire Red)
1. Provide an offset to change to hook a new routine off of to make a new ability.
2. Provide something similar to the original "power up" ability that has notes to what can be changed.
3. And provide a bit of code to allow the routine to return to the original routine.

So, for instance.
Spoiler:

Hopefully someone with the knowledge can understand what I typed.
 
Last edited:

AkameTheBulbasaur

Akame Marukawa of Iyotono
409
Posts
10
Years
I'm trying to make the Ability Aerilate be an item instead of an ability. I used Mr.DollSteak's Aerilate routine as a base.

I'm using an item called the Flame Orb to be a Fire Type version of Aerilate (where it turns Normal Type moves into Fire Type moves and boosts their power).

Here's what I did:

Spoiler:


I want to know if this would actually work before I put it in the game. Thanks in advance for any help!
 
4
Posts
10
Years
  • Age 26
  • Seen Oct 1, 2016
Hi, i get a bug with this routine:
.align 2
.thumb


So:
push {r4-r6, lr}
ldr r1, .VAR_8001
ldrb r1,[r1]
mov r2,#0x8
mul r2,r1
ldr r0, .OFF_TABLE
add r6,r0,r2
ldr r1,[r6]
ldr r3, =0x80086DD @gpu_tile_obj_alloc_tag_and_upload
bl bx_r3
add r6,#0x4
ldr r1,[r6]
ldr r3, =0x8008929 @gpu_pal_obj_alloc_tag_and_apply
bl bx_r3
LDR R5, =0x203AD40 @TEMPLATE
LDR R0, =0X08453184 @OAM
STR R0, [R5,#0x4]
LDR R0, ANIMATION
STR R0, [R5,#0x8]
ldr r0, =0x8231CFC @Rotscale
str r0, [r5, #0x10]
ldr r0, =0x810BB89 @Callback
str r0, [r5, #0x14]
@posx
ldr r1, =0x20370BC
ldrh r1, [r1]
LSL R1, R1, #0x14
mov r2, #0x80
lsl r2, r2, #0x11
add r1, r1, r2
lsr r1, r1, #0x10
mov r2, #0x0
@PosY
ldr r6, =0x20370BE
ldrh r2, [r6, #0x0]
lsl r2, r2, #0x14
mov r3, #0x80
lsl r3, r3, #0x11
add r2,r2,r3
lsr r2, r2, #0x10
@right
ldr r4, =0x8006F8D
bl bx_r4
pop {r4-r6}
POP {R1}
BX R1

bx_r3:
bx r3

bx_r4:
bx r4

.align 2
.VAR_8001:
.word 0x020370ba

.OFF_TABLE:
.word 0x08800000

.align 2
ANIMATION: .word OAMANIM + 0x08F00000
OAMANIM:
.hword 0x201
.hword 0xA
.hword 0xFFFE
.hword 0x0

My problem is with the:
POP {R1}
BX R1
If you see the routine In the NOGBA debugger says this:
CPU BAD OPERATION:
Undefined opcode - with no debug vector defined.
So, i can´t know what is the problem.
 
16
Posts
9
Years
So I have an error regarding the player's PC in their bedroom. Whenever the player uses the PC, and tries to turn it off, the blue screen stays on and the text box that says "What would you like to do" stays up. However, you aren't locked into the PC and can walk around, reuse the PC, and leave the room. Leaving the room turns off the PC, however if you go back and turn it on, the problem will occur again. I'm using the exact same script from normal FireRed, and I don't understand why this is happening. I did use the JPAN cleaning patch to wipe out some scripts, so I'm not sure if that's causing an issue. Anywho, here's the script.

Spoiler:


Hope someone can help me fix this, as why it doesn't affect gameplay at all, it's pretty annoying.
 

BluRose

blu rass
811
Posts
10
Years
so um
i have an extremely simple question
basically, how does one remove an item from a pokémon in-battle?
Spoiler:
EDIT2: i'm stupid, don't read the above
Spoiler:

the code above doesn't seem to work for making an item's index 0x0, effectively removing it
EDIT3: when in VBA's RAM-viewer, the two bytes that represent the hold items don't change at all despite the above code happening...
 
Last edited:
130
Posts
8
Years
  • Age 28
  • Seen Jun 14, 2023
What bytes are basically nop for asm? is it C0 46 or C0 49? It may be the difference between a bug in my hack.
 

mkarthick98

Tensai
44
Posts
9
Years
Hi, i get a bug with this routine:
.align 2
.thumb


So:
push {r4-r6, lr}
ldr r1, .VAR_8001
ldrb r1,[r1]
mov r2,#0x8
mul r2,r1
ldr r0, .OFF_TABLE
add r6,r0,r2
ldr r1,[r6]
ldr r3, =0x80086DD @gpu_tile_obj_alloc_tag_and_upload
bl bx_r3
add r6,#0x4
ldr r1,[r6]
ldr r3, =0x8008929 @gpu_pal_obj_alloc_tag_and_apply
bl bx_r3
LDR R5, =0x203AD40 @TEMPLATE
LDR R0, =0X08453184 @OAM
STR R0, [R5,#0x4]
LDR R0, ANIMATION
STR R0, [R5,#0x8]
ldr r0, =0x8231CFC @Rotscale
str r0, [r5, #0x10]
ldr r0, =0x810BB89 @Callback
str r0, [r5, #0x14]
@posx
ldr r1, =0x20370BC
ldrh r1, [r1]
LSL R1, R1, #0x14
mov r2, #0x80
lsl r2, r2, #0x11
add r1, r1, r2
lsr r1, r1, #0x10
mov r2, #0x0
@PosY
ldr r6, =0x20370BE
ldrh r2, [r6, #0x0]
lsl r2, r2, #0x14
mov r3, #0x80
lsl r3, r3, #0x11
add r2,r2,r3
lsr r2, r2, #0x10
@right
ldr r4, =0x8006F8D
bl bx_r4
pop {r4-r6}
POP {R1}
BX R1

bx_r3:
bx r3

bx_r4:
bx r4

.align 2
.VAR_8001:
.word 0x020370ba

.OFF_TABLE:
.word 0x08800000

.align 2
ANIMATION: .word OAMANIM + 0x08F00000
OAMANIM:
.hword 0x201
.hword 0xA
.hword 0xFFFE
.hword 0x0

My problem is with the:
POP {R1}
BX R1
If you see the routine In the NOGBA debugger says this:
CPU BAD OPERATION:
Undefined opcode - with no debug vector defined.
So, i can´t know what is the problem.

You haven't pushed r1, but it's used in the code. As an ASM beginner, how does that work?
 

miksy91

Dark Energy is back in action! ;)
1,480
Posts
15
Years
You haven't pushed r1, but it's used in the code. As an ASM beginner, how does that work?
That's most likely the reason the routine isn't working properly. When it "pops" R1 at the end of the routine, it takes the next value off the stack, loads that into R1, and adjusts the stack pointer to point to the value after that one. What probably happens here is that R1 gets the value where CPU is supposed to execute code next (because when your routine ended, it would return executing code to the location where this routine was called from. This happens by popping the next value off the stack onto PC (program counter) register (if that's what it is called in ARM/Thumb asm as well)).
CPU doesn't reach the point when this subroutine ends though because instruction "BX R1" seems to fail on "invalid" value that R1 has as NOGBA points out.

But simply pushing R1 before "push {r4-r6, lr}" ought to work. That way R1 gets its original value back before BX R1 is executed.
 
Last edited:

Lauthai

Lauthai
5
Posts
9
Years
  • Age 24
  • Seen Dec 14, 2021
Hello, I'm new to ASM and I am trying to understand this function contained inside the firered rom. It is the executeram function at offset, 0806A28C. What it does is it uses what appear to be checksums at [0x03005008] + 0x32E0 and [0x03005008] + 0x361C to validate data pointed to by pointers at [0x03005008] + 0x32E4 (target is 332 bytes) and [0x03005008] + 0x3620 (target is 1000 bytes). But the problem I am having is understanding what each of the calls in this function are, and then how I would run this function outside of this rom. Would I have to convert it to C and then pass in the data 332 and 1000 byte data?

i.imgur.com/QD7Fvt0.png (Sorry, couldn't hyperlink)
 
52
Posts
14
Years
  • Seen Apr 21, 2024
In Knizz's Firered IDB, there is the struct "exp_point_table" which is the length of 0x194 (or 404 bytes, OR 101 dwords) which is exactly the length of the 100 level cap. I need to extend this table to accomodate 200 levels. (0x324 / 804 bytes / 201 dwords)

Does anyone know how I could do that?
 

Kimonas

%string not found
91
Posts
13
Years
I'm trying to insert this asm script

Spoiler:


into the rom with the 'Project Template' way. But when I hit "python3 scripts/build" it gives me this error:

Spoiler:


Any ideas what's the issue here?

[S-HIGHLIGHT]edit:[/S-HIGHLIGHT] Just figured it out
 
Last edited:
794
Posts
10
Years
I'm trying to insert this asm script

Spoiler:


Any ideas what's the issue here?

The error log actually tells you what's the issue there. 'Immediate expressions' aka numbers like 20 or 0x14 require a '# prefix' aka you need to have that thingy '#' before the number. So, it should be:
cmp r0, #0x14
cmp r0, #0x16
add r13, #0x80
 

Geodude6

It's just me.
27
Posts
10
Years
  • Age 26
  • Seen Mar 16, 2024
Is there a tutorial somewhere for someone who is a beginner? I found Shiny Quagsire's tutorial but the ASM pack download link returns a 404 error and the tutorial itself has some missing images.
 

Lance32497

LanceKoijer of Pokemon_Addicts
792
Posts
9
Years
So I have an error regarding the player's PC in their bedroom. Whenever the player uses the PC, and tries to turn it off, the blue screen stays on and the text box that says "What would you like to do" stays up. However, you aren't locked into the PC and can walk around, reuse the PC, and leave the room. Leaving the room turns off the PC, however if you go back and turn it on, the problem will occur again. I'm using the exact same script from normal FireRed, and I don't understand why this is happening. I did use the JPAN cleaning patch to wipe out some scripts, so I'm not sure if that's causing an issue. Anywho, here's the script.

Spoiler:


Hope someone can help me fix this, as why it doesn't affect gameplay at all, it's pretty annoying.

Not sure if this is the right place to ask this question 'cuz a simple scripting command called special can solve this. Anyway, just put special 0xD7 at the end of the script.
 
534
Posts
11
Years
  • Age 26
  • Seen Jul 24, 2023
Hey I guys~! I was trying to implement FBI's BW HP Bars found at the community's hack section but after a few errors that I've fixed, a new error popped up that I do not know how to fix. Here's the error. :(
Code:
Where is: 8388608<class 'int'>
data is: <class 'bytes'>
Traceback (most recent call last):
File "scripts//insert", line 142, in <module>
array.append(int("0x" + hex(last)[7:], 0))
ValueError: invalid literal for int() with base 0: '0x
 

Blah

Free supporter
1,924
Posts
11
Years
Hey I guys~! I was trying to implement FBI's BW HP Bars found at the community's hack section but after a few errors that I've fixed, a new error popped up that I do not know how to fix. Here's the error. :(
Code:
Where is: 8388608<class 'int'>
data is: <class 'bytes'>
Traceback (most recent call last):
File "scripts//insert", line 142, in <module>
array.append(int("0x" + hex(last)[7:], 0))
ValueError: invalid literal for int() with base 0: '0x

Can you provide a paste of insert.py that you're using? That looks like a custom one I used a while back for changing a pointer in a script some time ago, might have been left over junk.
 
534
Posts
11
Years
  • Age 26
  • Seen Jul 24, 2023
Can you provide a paste of insert.py that you're using? That looks like a custom one I used a while back for changing a pointer in a script some time ago, might have been left over junk.
Well, here it is. :)
Spoiler:
 
Last edited:

Blah

Free supporter
1,924
Posts
11
Years
Well, here it is. :)
Spoiler:

I deleted a couple of lines, check the spoilers. Also make sure you are running python build and then python insert after the build.
 
Status
Not open for further replies.
Back
Top