• 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.
Quick question. Is there a fast method on moving an entire table to ram? Or would a simple halfword move loop be the best option? Length of 38 bytes btw.
 
Quick question. Is there a fast method on moving an entire table to ram? Or would a simple halfword move loop be the best option? Length of 38 bytes btw.

Why do you need to? It would probably be easier to just calculate the offset of an individual entry and load from the ROM, no?
 
Why do you need to? It would probably be easier to just calculate the offset of an individual entry and load from the ROM, no?

Well cause I saw THIS, and what he does is simply set the trainers pokemon intro ram and instead of the trainer data being pointed to somewhere in the ROM he points it to RAM. And I thought, why not do the same for wild Pokemon? And since idk where in RAM the wildpokemon table is read from, I could just do what he does, but with a different table.

If theres an easier way to do this I would love to know.:)
 
Well cause I saw THIS, and what he does is simply set the trainers pokemon intro ram and instead of the trainer data being pointed to somewhere in the ROM he points it to RAM. And I thought, why not do the same for wild Pokemon? And since idk where in RAM the wildpokemon table is read from, I could just do what he does, but with a different table.

If theres an easier way to do this I would love to know.:)

It would probably just be easier to create somewhere in the ROM, and then just supply the correct pointer, right? I can understand wanting to load the data from the RAM because it sounds like it would be easier to randomize that way, but consider this: if you're wanting random wild Pokemon generation, you'll still want to limit it some right (like no legendaries)? So, you could just create a table of pointers to different encounter data, and get a random pointer from said table to get the data. You could modify the wild loading routine so that it checks for a specific flag and if so goes to this table of potential encounter sets. It would allow for more control on your end of what you may encounter, despite taking a bit more work. But that's all my opinion, and I'm certainly no authority on ASM or anything.
 
It would probably just be easier to create somewhere in the ROM, and then just supply the correct pointer, right? I can understand wanting to load the data from the RAM because it sounds like it would be easier to randomize that way, but consider this: if you're wanting random wild Pokemon generation, you'll still want to limit it some right (like no legendaries)? So, you could just create a table of pointers to different encounter data, and get a random pointer from said table to get the data. You could modify the wild loading routine so that it checks for a specific flag and if so goes to this table of potential encounter sets. It would allow for more control on your end of what you may encounter, despite taking a bit more work. But that's all my opinion, and I'm certainly no authority on ASM or anything.

Yea that makes sense, but I dont want randomization, I just want specific tables, that way I wont have to make a new map for everytime I need to change the wild data. And I have no idea how I would go about editing that sorta thing.:)
 
Yea that makes sense, but I dont want randomization, I just want specific tables, that way I wont have to make a new map for everytime I need to change the wild data. And I have no idea how I would go about editing that sorta thing.:)

Then like I said, just modify the loader so that if a var/flag is set it will know to read a unique data set as opposed to the map's default. No need to waste RAM after all. Or, just go in with a hex editor and modify the wild data for each applicable map to point to a single data set.
 
Then like I said, just modify the loader so that if a var/flag is set it will know to read a unique data set as opposed to the map's default. No need to waste RAM after all. Or, just go in with a hex editor and modify the wild data for each applicable map to point to a single data set.

Yeah, this is pretty much it. Don't ever waste RAM space if you don't need to. I would make the table in ROM then have a switching variable to switch between the tables.

Some clarification on how Pokemon wild data is made, it's derived using the level and species. It uses the generic Pokemon generation routine (which is why the shiny routines, custom move routines all affect wild Pokemon and trainer Pokemon). These values are indeed fetched based on maps via a table.
 
Yeah, this is pretty much it. Don't ever waste RAM space if you don't need to. I would make the table in ROM then have a switching variable to switch between the tables.

Some clarification on how Pokemon wild data is made, it's derived using the level and species. It uses the generic Pokemon generation routine (which is why the shiny routines, custom move routines all affect wild Pokemon and trainer Pokemon). These values are indeed fetched based on maps via a table.

Ok, but if I'm to do that I would need to know where the offset is determined, which I do not. And since this is for Emerald idk if theres been much of any research into it.
 
Ok, but if I'm to do that I would need to know where the offset is determined, which I do not. And since this is for Emerald idk if theres been much of any research into it.

Start by setting a break point at the table. The table's location should be available to you via A-map. I'm unsure about Emerald's locations, I don't have an Emerald ROM.
 
Ok, but if I'm to do that I would need to know where the offset is determined, which I do not. And since this is for Emerald idk if theres been much of any research into it.

You could also check out Jambo51's work on Day/Night wild Pokemon switching. There should be stuff on Emerald, which should provide a starting point for research.
 
Hi, I tried to recreate the Bad Dreams ability in Emerald (the version doesn't really matter). I have a freeze when a pokémon is effectively asleep and there's a Bad Dream in battle.

I explained why I did this or that instruction, what I'm trying to do, being to most accurate possible, if anyone would like to take a look into that.

The place where I hooked is where the check for poisonning damages is done (which seemed to be appropriate to me, the effect being the same = -1/8 life).

I don't post directly here because the routine is pretty long, so it would be easier here : https://hastebin.com/xexiwavuwi.hs If anything seems wrong, if you have any clue, don't hesitate please :)



EDIT : Nevermind, there was stupid error and I found another way to do that anyway.
 
Last edited:
I'm back. I used the DNS of prime-dialga and linked it to my own time offset. Everything is working but currently im saving the time in the RAM at 02FFFF60 and this data is gone after reseting the game. So my question is if there is some free space of data where i can write to and is saved by saving the game?
 
I'm back. I used the DNS of prime-dialga and linked it to my own time offset. Everything is working but currently im saving the time in the RAM at 02FFFF60 and this data is gone after reseting the game. So my question is if there is some free space of data where i can write to and is saved by saving the game?

Yes - use one of the save blocks. But you would have to modify those routines so that they read from your new RAM location. Save blocks are DMA-protected so you need a pointer to a pointer to the block (fun). I believe HackMew's ASM tutorial is an example of how to use the player data save block. Also, I don't know if the source is available for those routines; if not, you're going to have to RE it.
 
Yes - use one of the save blocks. But you would have to modify those routines so that they read from your new RAM location. Save blocks are DMA-protected so you need a pointer to a pointer to the block (fun). I believe HackMew's ASM tutorial is an example of how to use the player data save block. Also, I don't know if the source is available for those routines; if not, you're going to have to RE it.

Is there a post about the save blocks (where they are) ? I will look in to this. Bypassing the DMA-protection would that mean:
ldr r0, .firstoffset #containing second offset
ldr r0, [r0]
ldr r0, [r0]

EDIT: I found it in HackMew's tutorial. Finally I know what DMA protection means. Thanks for giving me the link.
 
Last edited:
Is there a post about the save blocks (where they are) ? I will look in to this. Bypassing the DMA-protection would that mean:
ldr r0, .firstoffset #containing second offset
ldr r0, [r0]
ldr r0, [r0]

EDIT: I found it in HackMew's tutorial. Finally I know what DMA protection means. Thanks for giving me the link.

I don't know about a post, but it's in the IDBs (as long as you're working on FireRed or Emerald). You don't need the second "ldr r0, [r0]" unless you're loading the first word of the saveblock. You load the address of the pointer with "ldr r0, .firstoffset" then you get the pointer out of that with the first "ldr r0, [r0]". With the pointer you can then load/write tthe saveblock structure. There are 3 save blocks, so you shouldn't have trouble finding space.

Also, you said you're using 02FFFF60 currently? How is that possible :/
 
I don't know about a post, but it's in the IDBs (as long as you're working on FireRed or Emerald). You don't need the second "ldr r0, [r0]" unless you're loading the first word of the saveblock. You load the address of the pointer with "ldr r0, .firstoffset" then you get the pointer out of that with the first "ldr r0, [r0]". With the pointer you can then load/write tthe saveblock structure. There are 3 save blocks, so you shouldn't have trouble finding space.

Also, you said you're using 02FFFF60 currently? How is that possible :/

Everything should work now. I installed one of JPANS Memory extensions and ported it for my language (German). I'm going to use the 0203e000 adress now.
I don't know how that is possibly ... I know everybody says that you can only use specific RAM adresses, but I can only say ... It worked. Writing and reading from the location was no problem. I was thinking like: maybe that adress at the end isn't used yet.
 
Everything should work now. I installed one of JPANS Memory extensions and ported it for my language (German). I'm going to use the 0203e000 adress now.
I don't know how that is possibly ... I know everybody says that you can only use specific RAM adresses, but I can only say ... It worked. Writing and reading from the location was no problem. I was thinking like: maybe that adress at the end isn't used yet.

The RAM for a 02XXXXXX segment ends at 0203FFFF. After that there are mirrors of the same space. You probably wrote to one of the mirrors, so it ended up in the on-board RAM anyway. You shouldn't do this is it is unpredictable.
 
The RAM for a 02XXXXXX segment ends at 0203FFFF. After that there are mirrors of the same space. You probably wrote to one of the mirrors, so it ended up in the on-board RAM anyway. You shouldn't do this is it is unpredictable.

I thought it was save because there was nothing ever written to it. I'm using the save extension RAM now anyways.
 
I'm trying to create an ASM where, the value(half word) stored in Variable 8000 and 8001 will be written in offset 0x08800000
i tried loading the halfword of Var 8000 and 8001 and stored it in 0x08800000 and 0x08800002 but I couldn't make it correct, nothing happened in offset 0x08800000

here's my routine
Spoiler:
 
There are 3 problems with your code.
1. 08xxxxxx is ROM address (Read Only Memory). Consult GBATEK for available RAM address.
2. Assuming you have the correct RAM address,
Spoiler:

3. The number of pushed register should be the same as popped register. Getting out of the routine can be done with bx or pop pc. This is my example:
Spoiler:
 
Status
Not open for further replies.
Back
Top