• 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 Trading Card Game 2 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.
Hm it still ended up with the same error, I'm guessing it's still a register clash - at least its not just aborting now though I suppose!

Code:
.text
.align 2
.thumb
.thumb_func

main: 
	lsr r7, r0, #0x18
	mov r0, r9
	ldrb r1, [r0] /*replacements for bits my hook overwrites*/
	push {r0-r3}
	mov r2, #0xFF
	lsl r2, r0, #0x6
	add r2, #0xC0
	ldr r3, =(0x806E454 +1)
	bl linker
	ldrh r3, [r0]
	add r3, #0x4
	strh r3, [r0]
	pop {r0-r3}
	ldr r0, =(0x80d83f0 +1)
	bx r0

.align 2
linker:
	bx r3
Oh wow, I see now. The original code does a "bl" to 0x80D83F0 +1. You're doing a bx.

Code:
.text
.align 2
.thumb
.thumb_func

main: 
	lsr r7, r0, #0x18
	mov r0, r9
	ldrb r1, [r0] /*replacements for bits my hook overwrites*/
	push {r0-r3}
	mov r2, #0xFF
	lsl r2, r0, #0x6
	add r2, #0xC0
	ldr r3, =(0x806E454 +1)
	bl linker
	ldrh r3, [r0]
	add r3, #0x4
	strh r3, [r0]
	pop {r0-r3}
	ldr r0, =(0x80d83f0 +1)
	bl linker2
	ldr r2, =(0x80D788A +1)
	bx r2

.align 2
linker:
	bx r3

linker2:
	bx r0
 
Back again! :) Less of a problem now, slightly different routine too - this one is trying to add 0x1 to variable 0x4080

If my read variable / write to variable section written correctly? In game the rest works (including the strb r1, [r2] - which goes to RAM) and there are no bad effects, but var 0x4080 doesn't gain 1.

Spoiler:
 
Back again! :) Less of a problem now, slightly different routine too - this one is trying to add 0x1 to variable 0x4080

If my read variable / write to variable section written correctly? In game the rest works (including the strb r1, [r2] - which goes to RAM) and there are no bad effects, but var 0x4080 doesn't gain 1.

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main: 
	push {r2, r3}
[B]	mov r0, #0xFF
	lsl r0, r0, #0x6
	add r0, #0xC0
	ldr r3, =(0x806E454 +1)
	bl linker
	ldrh r1, [r0]
	add r1, r1, #0x1
	strh r1, [r0][/B]
	pop {r2, r3}
	mov r1, #0x1
	strb r1, [r2]
	ldr r0, =(0x8022498 +1)
	bx r0

.align 2
linker:
	bx r3

The var address getting takes only one paramater, the var number. So, by definition of how these functions are made, r0 must contain the var number before the call. You're setting r1 to 0x4080, when it should be r0.

Secondly, you need to push r2 and r3 before the the modifications. While r1 and r0 are safe to modify (in this specific case), r2 and r3 are not. That means you need to push them, so you can recall their values for after the hook.
 
Welcome to the Magic is a noob thread

Reading bytes is straight forward, but some data is stored differently. I'm looking to read data that is stored in the style of what I assume everyone is calling little endian these days? :P idk.

Anyway, map tiles are stored with the tile number and the permissions combined. So... tile 0x10C with no permission (0x1) is stored as 0C 02. How can I account for this in a routine that is trying to find the tile number only?
 
Welcome to the Magic is a noob thread

Reading bytes is straight forward, but some data is stored differently. I'm looking to read data that is stored in the style of what I assume everyone is calling little endian these days? :P idk.

Anyway, map tiles are stored with the tile number and the permissions combined. So... tile 0x10C with no permission (0x1) is stored as 0C 02. How can I account for this in a routine that is trying to find the tile number only?

What you want is called masking. Essentially, the permission and tile number are stored together in a 16 bit word. The tile number is stored in the lower 10 bits of this word, and the meta data (permissions) are in the upper 6. To get the 10 bits out, you use what is called a bit mask. Say for example I have 0x1253 and want the lower ten bits. 0x1253 in binary (padded to 16 bits) is

Code:
0001 0010 0101 0011

Now, we select a mask. Everywhere we want a bit to "pass through" we put a 1, and everywhere we want to ignore a bit we put 0. So a mask for the lower 10 bits is

Code:
0000 0011 1111 1111

This is 3FF in hex.

Now we do logical AND:
0x1253 & 0x3FF = 0x253

What's happening is very clear when you look at the binary

Code:
     0001 0010 0101 0011
AND  0000 0011 1111 1111
------------------------
=    0000 0010 0101 0011

You can use the THUMB op AND to do this. It looks like
Code:
and Rd, Rs
and there are no variations, so you'll have to MOV in (or LDR if its is bigger than 8 bits) your mask.
 
Wow, masking is very logical. May I ask why this won't work:

lsl 0x6
lsr 0x6

then you will have the same result?
 
Wow, masking is very logical. May I ask why this won't work:

lsl 0x6
lsr 0x6

then you will have the same result?

That won't work because a register is 32 bits. You would need to

Code:
lsl Rd, #0x16 @ (16 + 6)
lsr Rd, #0x16

However, I was just trying to introduce a common concept to extract bits rather than show the most efficient way. Masking is more useful when you have non-consecutive bits that you want to extract.
 
Ok so I'm having... issues....
This is my first actual routine so be nice.:P
Spoiler:


All it's supposed to do is get the value stored in 0x8000
multiply it by 0x1c then add 0x14 and then add 0x1 to read both bytes of a pokemons egg group into 2 seperate variables to be buffered.

This is what I'm getting as a result:
Spoiler:


What am I doing wrong??
 
All it's supposed to do is get the value stored in 0x8000
multiply it by 0x1c then add 0x14 and then add 0x1 to read both bytes of a pokemons egg group into 2 seperate variables to be buffered.

What am I doing wrong??

Hey, I'm lead to believe your script is what's wrong here. The routine does what you say it should do, though inefficiently. Try posting your script here or in the script help thread. Anyways, here's the body of a more efficient version.

Code:
ldr r2, =(0x20370B8)
ldrh r0, [r2]
mov r1, #0x1C
mul r0, r0, r1
ldr r1, =(0x8254784 +0x14)
add r0, r0, r1
ldrb r1, [r0, #0x1]
ldrb r0, [r0]
ldr r3, =(0x20370BA)
strb r0, [r2]
strb r1, [r3]

0x8000: group 1
0x8001: group 2
 
Hey, I'm lead to believe your script is what's wrong here. The routine does what you say it should do, though inefficiently. Try posting your script here or in the script help thread. Anyways, here's the body of a more efficient version.

Code:
ldr r2, =(0x20370B8)
ldrh r0, [r2]
mov r1, #0x1C
mul r0, r0, r1
ldr r1, =(0x8254784 +0x14)
add r0, r0, r1
ldrb r1, [r0, #0x1]
ldrb r0, [r0]
ldr r3, =(0x20370BA)
strb r0, [r2]
strb r1, [r3]

0x8000: group 1
0x8001: group 2
Wow yea that's wy smaller and way neater.
but the script is super simple so that's why I thought it was the asm:
Spoiler:
 
Hi,
I found the routine of the battle command C1 (hidden power), I wanted to write a far more simple routine to just return the type of the user (wich I think I have), and, if it is needed, the power (fixe)

Here is the hidden power routine :
Spoiler:



I don't want to someone translate the routine, but, does someone know what it returns ? I mean, It supposed to determine type and power, but in the end it pop five register. So how they're used ?
Or there only R0 that is used ? If so, how the data are stored in ?
I know there's a lot of question but I read tutorials since hours but I am not able to understand this one x)
 
Hi,
I found the routine of the battle command C1 (hidden power), I wanted to write a far more simple routine to just return the type of the user (wich I think I have), and, if it is needed, the power (fixe)

Here is the hidden power routine :
Spoiler:



I don't want to someone translate the routine, but, does someone know what it returns ? I mean, It supposed to determine type and power, but in the end it pop five register. So how they're used ?
Or there only R0 that is used ? If so, how the data are stored in ?
I know there's a lot of question but I read tutorials since hours but I am not able to understand this one x)

What ROM base? This isn't FireRed :o
 
Yeah indeed. Forgot to mention this is Emerald x)

Well, taking a look at this code atm, I can tell that it doesn't have a return value. Instead, it seems to write into some sort of data structure/RAM pointer.

You'd be best off setting break points at these hard coded RAM offsets and seeing what they are. When they're written directly like this, rather than loaded from pointers, it means the RAM addresses are static. So if you can see what they hold, you can generalize what that RAM offset will always hold (in 99% of cases).
 
Ok now I have other question, see this post in the spoiler. I would like to adapt the following routine to emerald but if only I could understand why it exactly doing in Firered it would be very very useful. So, the routine :

Spoiler:

My question are principally for the first routine, I mean transform type/get base power. Not the table item.
In all likelihood I'll have question for the second one but for the moment, I'm sure the first one doesn't work correctly for me.
The most important to me is understand what is happening, so I put my question/how I understand in bold.

Last thing, I tried to find the RAM address for emerald and this is what I have

.BattleData: .word 0x02024084
.UserBank: .word 0x0202420B
.BasePower: .word 0x020244E0
.MemAddress: .word 0x0202449C
.CurrentScript: .word 0x02024214
.FailScript: .word 0x082D9F1C
.Outcome: .word 0x0202427C
.BattleData: .word 0x02024084
.TargetBank: .word 0x0202420C

I know this is not the topic but the routine doesn't works for me. Perhaps simply because I don't have the correct offset.

Thank's in advance whoever answer me :)

I tried to make a routine that take my type and transform my attack into this type :

Spoiler:


It does absolutly nothing, the attack remind regular

There is one good thing in this one, it actually change the type of the attack, but it's a little bit random. Didn't manage to do super effective damages.
EDIT : Actually damages are always neutral, and it's not a question of string displayed. I tested the damage and they are really neutral. I guess it load a value that is too high but can't figured out how to load the good (primary type of my poke) :

Spoiler:


I don't know why, but this one works :

Spoiler:


Change attack in user's primary type
 
Last edited:
What I'm trying to do is remake the rematch system in an extremely basic way, and here's the code I made for it.
Spoiler:
I'm only trying to add five levels to the Pokémon's levels(in this instance youngster ben), but after running the script it wasn't working, and his levels remained what they were before. Any idea what's going wrong?
 
What I'm trying to do is remake the rematch system in an extremely basic way, and here's the code I made for it.
Spoiler:
I'm only trying to add five levels to the Pokémon's levels(in this instance youngster ben), but after running the script it wasn't working, and his levels remained what they were before. Any idea what's going wrong?

I can't even tell what you are trying to do, but I'll do my best. It looks as though you are loading a ROM offset rather than an address. ROM is prefixed by 08/09, you have prefixed it with 00 (BIOS). In fact this address is invalid and will be ignored by VBA - the bios is only 16kb. Hardware will do weird things.

Next, you load two half words, add 5, then load the addresses again? Why? I think what you are trying to do is store to those addresses, but you'd need str, strh or strb to do that. If I'm right about these being ROM offsets, then you clearly don't understand the concept of ROM. You can't right to it. Ever. There are a few bytes of ROM address space reserved for GPIO for sensors, and this is the only exception.

Lastly, you're wasting stack space. Neither R0, R1 or LR need to be pushed.

I suggest you read some tutorials and look at existing code so you actually understand what you're doing, rather than fumbling around in the dark.
 
Status
Not open for further replies.
Back
Top