• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
  • 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.
Wait, you're trying to test Psystrike's battle effect in the OW with a signpost script? Really?

This should be put in a battlescript which is then attached to an attack. Then used in a battle. Wow.

I know, it is to test the swap. It will work in a script and in a battle script, no ?


So it is "callasm 0xOffset +1", thank you.
 
I know, it is to test the swap. It will work in a script and in a battle script, no ?


So it is "callasm 0xOffset +1", thank you.

You don't seem to understand..
It's a code for a move. There is no battle scene on the overworld. You can't just "callasm 0xmovescript" and make psystrike happen on the overworld. It doesn't make sense lol
 
You don't seem to understand..
It's a code for a move. There is no battle scene on the overworld. You can't just "callasm 0xmovescript" and make psystrike happen on the overworld. It doesn't make sense lol

This routine is not the move's script. It just swaps two "double bytes". I can swap two bytes when I want, in battle or not.
It will be call in the psystrike's battlescript.

But I have another question ! How to port the Jambo's callasm command ? I compile the routine with the address 0x02024214 for the scriptlocation (because I am on Emerald). Ok, but I have to repoint and extend the battle script command table to had the new command F9 XX XX XX 08. Where is this table ? And how do you find it ?
 
Do you have battle script pro?
You can use that to compile battle scripts.
Yes of course, i know how to create a battlescript.
I want to insert an ASM routine in my battlescript using Jambo's callasm command. I'm on Emerald so i have to use the address 0x02024214 as scriptlocation. But I also have to repoint and extend the battle script command table. I don't find it.

Edit : I found it! The table is at 0x31BD10 and its length is 0x3E4.
 
Last edited:
I would like to know, if it's possible, the offset of two routines :

- First, the one which creates an OW on the map when we come on this map ;
- And also, the one which check if there is an OW next to the player before walking.

Can someone help me ? Thanks ^^

Hi, unfortunately I don't know where the overworld is created. Though I do know that there's a collision check which occurs when the player tries to use surf or waterfall.

This sub routine is at 0x805C8B0. More specifically, the check to see if an NPC is blocking the way is done at 0x80636AC, it's used for stuff like ledge hopping and stuff too.
 
Hello,

I don't understand why this doesn't work :
Spoiler:


Whereas this works :
Spoiler:


With the first routine I want to switch some bytes and with the second i switch some "double bytes".
 
Hello,

I don't understand why this doesn't work :
Spoiler:


Whereas this works :
Spoiler:


With the first routine I want to switch some bytes and with the second i switch some "double bytes".

Hi, it looks like it would do the same. I don't know which base you're using, but the offsets of the symbols from routine #1 don't match the offsets of the symbols in routine #2. Other than that, swapping a byte instead of a half word shouldn't be a problem (actually the halfword one has more limitations than the byte swapping, but that's besides the point).
 
Hi, it looks like it would do the same. I don't know which base you're using, but the offsets of the symbols from routine #1 don't match the offsets of the symbols in routine #2. Other than that, swapping a byte instead of a half word shouldn't be a problem (actually the halfword one has more limitations than the byte swapping, but that's besides the point).

The first one is to swap stat changes, and the second one is to swap stats. So it is normal that the offsets are not the same. Yes it shouldn't be a problem, that's why i don't understand why the game resets with the first routine.

Edit: Well, i'm stupid, I forgot a "0":
.CDEFA2:
.word 0x202414E

.CDEFA2:
.word 0x0202414E
 
Last edited:
Hi, unfortunately I don't know where the overworld is created. Though I do know that there's a collision check which occurs when the player tries to use surf or waterfall.

This sub routine is at 0x805C8B0. More specifically, the check to see if an NPC is blocking the way is done at 0x80636AC, it's used for stuff like ledge hopping and stuff too.

Thanks a lot ;)

I found something : the result given by the routine at 0x80636AC is stored in r0.

Code:
[U][B]Value of r0[/B][/U]	|	[U][B]Obstacle[/B][/U]
0 		|	Nothing
2 		|	Solid block (buildings, trees...)
3 		|	Walking : water / Surfing : ground
4 		|	NPC
 
Thanks a lot ;)

I found something : the result given by the routine at 0x80636AC is stored in r0.

Code:
[U][B]Value of r0[/B][/U]	|	[U][B]Obstacle[/B][/U]
0 		|	Nothing
2 		|	Solid block (buildings, trees...)
3 		|	Walking : water / Surfing : ground
4 		|	NPC

Awesome. Did you figure out if it takes a player's X-Y? If it does perhaps it can be used to check if something is present on another part of the map the player isn't in currently.
 
I haven't studied the routine more, I used this data to make a Follow Me (https://vid.me/ynwf / https://vid.me/hSBA).

However, I noticed that before the execution of this routine, r1, r5 and r7 correspond to the player's X + 7. In the same way, r2, r4 and r9 correspond to the player's Y + 7.
 
NOOB HERE! o/

If this (from Shiny Quagsire's tutorial) saves a byte to a variable...

Spoiler:


Then would switching "ldr r0, pokemon_data" to "ldr r0, var" (ldr r1, var too) then store whatever the value of 0x800D in the data? Or is life not that simple : <.
 
Last edited:
NOOB HERE! o/

If this (from Shiny Quagsire's tutorial) saves a byte to a variable...

Spoiler:


Then would switching "ldr r0, pokemon_data" to "ldr r0, var" (ldr r1, var too) then store whatever the value of 0x800D in the data? Or is life not that simple : <.

You'll notice that he saves the value in r0 into the address in r1 (the variable).
So all you need to do is this:

Code:
push {r0-r1, lr}
mov r0, #0xValue
ldr r1, .var
strh r0, [r1]
pop {r0-r1, pc}
 
You'll notice that he saves the value in r0 into the address in r1 (the variable).
So all you need to do is this:

Code:
push {r0-r1, lr}
mov r0, #0xValue @changes r0 to 0xValue?
ldr r1, .var @loads variable value to r1
strh r0, [r1] @stores r0's value to the var
pop {r0-r1, pc}

All this lingo still confuses me XD.

Sorry I'm not sure what you mean :<. Your code doesn't have any locations other than the var, so how can it set a byte to the value of the var? It might have just been I wasn't clear in my last post >< haha.

Also in regards to your tutorial (and our VMs) how do you know when you need to 'hook' and things?


Latest attempt of a routine. Think I must have oversimplified something? I get nothing ><. It runs but obviously not doing what I'd like it to XD. Vague comments about what I think ought to be happenin on the side :').

Spoiler:

It now tells me 55 - which is correct! :o 50+5 power. How can I then extend this routine to replace the 50 (0x32) in the ROM with 55 (0x37)?

IM SO SORRY FOR ALL THE NOTIFICATIONS ;-; /thousanth edit
 
Last edited:
Code:
push {r0-r1, lr}
mov r0, #0xValue @changes r0 to 0xValue?
ldr r1, .var @loads variable value to r1
strh r0, [r1] @stores r0's value to the var
pop {r0-r1, pc}

All this lingo still confuses me XD.

Sorry I'm not sure what you mean :<. Your code doesn't have any locations other than the var, so how can it set a byte to the value of the var? It might have just been I wasn't clear in my last post >< haha.

Also in regards to your tutorial (and our VMs) how do you know when you need to 'hook' and things?


Latest attempt of a routine. Think I must have oversimplified something? I get nothing ><. It runs but obviously not doing what I'd like it to XD. Vague comments about what I think ought to be happenin on the side :').

Spoiler:

It now tells me 55 - which is correct! :o 50+5 power. How can I then extend this routine to replace the 50 (0x32) in the ROM with 55 (0x37)?

IM SO SORRY FOR ALL THE NOTIFICATIONS ;-; /thousanth edit

OK, so when you do "ldr r0, move_data" you don't load it as a byte. move_data is a symbol which represents a pointer (in this case 0x8250CB8 + 1). We want a byte at that pointer so we do:
ldr r0, move_data @load the actual pointer
ldrb r0, [r0] @load a byte from the value of the pointer

If you did ldrb r0, move_data, it would just take move_data as a hex value and load the first byte of it, rather than the first byte of the value it's pointing to (power).

The rest of this is right. Also you seem to be confusing yourself with the names on the bottom. They're just definitions. It's the same thing to do ldr r0, move_data as it is to do ldr r0, =(0x8250CB8 +1).

Addressing your questions about what I've said last time, 0xValue is just a name I came up with. It's supposed to be some arbitrary, valid, constant. Replace it with 0xA or 0x50 or whatever your favorite hex value is.

mov r0, #0x50 @Sets r0 to be 0x50
ldr r1, =(0x20370D0) @loads address of Lastresult into r1. I.e pointer to the value in 0x800D (last result)
strh r0, [r1] @stores 2 bytes of whatever is in r0 into the address/location specified by r1. In this case stores 0x50 in the last result

I hope you see what we're doing with the pointers/symbols/storing now. With that out of the way I can address hooking.
I'm going to explain assuming you already know what a hook is. You basically know that a hook is required when you're reworking or adding additional features to existing game code. In this case you're changing the damage of a move's power based on badges. Thus you're added a feature to existing game code. If you were to just paste your code over the existing code at that region, then obviously you would be overwriting some other important code. This is why we place a hook.

Sometimes it's possible that the game code lends itself to be easily reworked and thus you just overwrite some existing bytes to do that (an example would be my "catch trainer's pokemon" thing). In these cases you don't need hooks (though it's kind of rare in comparison).
I should warn you, to hook successfully into some routines are harder than others. You need to analyze the code at said routine and note to yourself which registers are free, which registers contain information you need after you hook and of course which register you will use for the hook. In complex functions you often don't have a lot of resources, so you need to draw conclusions based on what the analyzed code is like.

Worst case scenario is usually that there's no registers you can use for the hook at the place you want to hook from. If that's the case you just hook early enough to a point where there are registers available and just derive their values and do your code from where you wanted to hook. OK, that last part doesn't make sense unless you've experienced what I'm talking about :P
This last paragraph isn't that important anyways, just me rambling, lol.
 
OK, so when you do "ldr r0, move_data" you don't load it as a byte. move_data is a symbol which represents a pointer (in this case 0x8250CB8 + 1). We want a byte at that pointer so we do:
ldr r0, move_data @load the actual pointer
ldrb r0, [r0] @load a byte from the value of the pointer

If you did ldrb r0, move_data, it would just take move_data as a hex value and load the first byte of it, rather than the first byte of the value it's pointing to (power).

The rest of this is right. Also you seem to be confusing yourself with the names on the bottom. They're just definitions. It's the same thing to do ldr r0, move_data as it is to do ldr r0, =(0x8250CB8 +1).

Addressing your questions about what I've said last time, 0xValue is just a name I came up with. It's supposed to be some arbitrary, valid, constant. Replace it with 0xA or 0x50 or whatever your favorite hex value is.

mov r0, #0x50 @Sets r0 to be 0x50
ldr r1, =(0x20370D0) @loads address of Lastresult into r1. I.e pointer to the value in 0x800D (last result)
strh r0, [r1] @stores 2 bytes of whatever is in r0 into the address/location specified by r1. In this case stores 0x50 in the last result

I hope you see what we're doing with the pointers/symbols/storing now. With that out of the way I can address hooking.
Spoiler:

Ok thanks, I'll fix up those bits about ldr :). I think I'm clearer on what's happening now after rereading SQ's and your tutorials (in particular, looking at definitions and patterns of coding).

With the hook, I was worried exactly where I'd be needing it. In my head I still think in terms of scripts I'm afraid >< checking flags is easy in scripts, so I didn't see any need to hook. I think I'm going to drop the badges thing for now and instead focus on getting the change done.

So my routine so far does half it's job, once I've added the 0x5 how do I get it to store at the location? Storing at the variable seemed easy enough, but then again that's RAM location not ROM, I tried using strb to get it back to 8250cb9, but that seems illogical anyway (and didn't work).
 
Status
Not open for further replies.
Back
Top