• 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
    • 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
    • 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
    • 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
    • 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
    • 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