Go Back   The PokéCommunity Forums > ROM Hacking > ROM Hacking Hub
Reload this Page ASM Workshop

Notices
For all updates, view the main page.

ROM Hacking Hub General discussions about ROM Hacking and Emulation. Not sure where to start? This is the place for you.
Posting links to ROMs is illegal and is not tolerated anywhere on the forum.
New threads in this forum are to be approved by a moderator before they are displayed.



Reply
 
Thread Tools
  #1    
Old March 28th, 2015 (06:50 AM). Edited March 30th, 2015 by FBI agent.
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818

Introduction


Hey, I decided to make a thread for ASM workshops and such. Hopefully we can get this thing rolling and help people who are interested in ASM hacking to learn how. In the early phases of this thread, the problems and discussion will likely be basic. However, in a couple of weeks, I hope to touch on topics of much more complication.

We'll be running this thread in a combination of a Skype Room and thread, so posting on whichever you're comfortable with is fine.


Some things you'll need to get the best benefit from this room:
- Skype. Add fbi.agent7
- VBA-SDL-H
- IDA (I'll link you if you ask me on skype)
- Knizz's idb (see his signature)

So far ...



Week One:
Spoiler:

Mainly I want to get people onboard this week and see how it goes.

This week we're going to do some simple RAM reading and writing, and getting people familiar with using Pointers in ASM. We'll be operating with the Pokemon RAM data structure, as well as the Save data structure.

Tasks:
We're writing three simple routines.
1) Give the slot number of first Pokemon who isn't full HP
2) Make the Player's name "Baka"
3) Make all Pokemon Shiny - Removed because too hard for now

Challenge task:
4) Can you delete a Pokemon?

I know these all actually seem pretty hard, but they're actually VERY easy. So easy, I'd say the starting ASM hacker can do them. At the same time, these are pretty cool routines too :)

Hints
Task 1: http://www.pokecommunity.com/showpost.php?p=8681207&postcount=4
Task 2/Challenge: http://www.pokecommunity.com/showpost.php?p=8681344&postcount=8

Solutions:
Comming after the week.


Posting rules



I'd just like to impose a few rules about posting your solutions here or on the Skype chat. Basically I don't want people openly posting their solutions on this thread and spoiling the fun for others who are still working on it. So if you've finished any of the above routines (fully or partially) and feel like sharing, go ahead and post them, but put spoiler tags.

I'd also like posted routines to be of this format:
Quote:
Partial solution for Task 2; Week 1
Spoiler:

Code:
Your solution here.
Your comments about your solution here.
Replace the "Partial" with "Full" if your solution is complete. Outside the spoilers, you can have whatever you want that isn't solution code itself, or doesn't describe solution code.

That's all for the rules. Oh, don't break any PC rules of course :P

People Participating



Mentors: FBI, ...maybe more soon?
Students: -a lot, removed names because FBI is lazy to maintain :)
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #2    
Old March 28th, 2015 (09:10 PM).
Percy's Avatar
Percy Percy is offline
Sceptile ftw
 
Join Date: Sep 2014
Location: Somewhere in the world, obviously
Age: 18
Gender: Male
Nature: Gentle
Posts: 1,509
Do I need to ask permission to sign up, too?
__________________
Pokémon Ranger Academy
Status: Coming Soon ...
Credit

Pair

Reply With Quote
  #3    
Old March 28th, 2015 (09:29 PM).
GoGoJJTech's Avatar
GoGoJJTech GoGoJJTech is offline
http://GoGoJJTech.com (WIP!)
Silver Tier
 
Join Date: Nov 2012
Location: Earth
Age: 16
Gender: Male
Nature: Quiet
Posts: 1,969
Quote originally posted by Percy:
Do I need to ask permission to sign up, too?
Nope, you only need to hide your solutions as FBI said in the OP.
Send them to his skype at fbi.agent7
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
The SoulSilver Music Patch - The Black Music Patch - Mega-Huge Sappy Tutorial
Romhack.me Profile - Pokecommunity Profile - Pokemonhackersonline Profile - Youtube Channel

Join us in the romhacking chat
Pokémon Platinum Red and Blue
Reply With Quote
  #4    
Old March 30th, 2015 (07:11 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Percy:
Do I need to ask permission to sign up, too? :P
You don't need permission. You just need to know about the things I mentioned in the first post.
ex: What is a pointer, basic hex editing, how to insert a routine, ect.

Quote originally posted by GoGoJJTech:
Nope, you only need to hide your solutions as FBI said in the OP.
Send them to his skype at fbi.agent7
No! Please don't PM me solutions lol. I'll make a skype chat room, and you can discuss in a more irc-esque environment there. This thread is probably going to be handled exactly the same as the Skype chat, a big discussion and such.


We're going to be starting the workshops now. Lets try task #1-2 first.

Task #1

1) Give the slot number of first Pokemon who isn't full HP

First of all, each Pokemon is stored in the RAM. There's a specific data structure in which they're stored in. Here's a picture I took from Bulbapedia of how it looks like in RAM:


The above is obviously the structure for a single Pokemon. There will be six in your party and their data will be stored in succession. Like this

[0x64 bytes (First Pokemon data)]
[0x64 bytes (Second Pokemon data)]
[0x64 bytes (Third Pokemon data)]
[0x64 bytes (Fourth Pokemon data)]
[0x64 bytes (Fifth Pokemon data)]
[0x64 bytes (Sixth Pokemon data)]

If you have less than 6 Pokemon in your party, say you have five, then the last 64 bytes will be zeros.

Getting back to the above picture of the data structure, you'll notice that
Code:
Current HP	word	86
Total HP	word	88
The Current HP for a Pokemon and the Total HP of a Pokemon is 2 bytes long. It is also the 86-88th byte (for current HP) and 88-90th byte (for total HP).

The Pokemon Data structure for the first Pokemon starts at 0x2024284.So if we add 86 bytes (0x56 in hex) to 0x2024284, we get the current HP of the first Pokemon at 0x20242DA. Add 2 more bytes to the address to get the total HP of course.

Here's a screen shot of the Current HP and Total HP highlighted in RAM of my Anorith:


Now, we know how to get the current HP and Max HP of the first Pokemon, but what about the rest? Well, you just add 0x64 to the address 0x2024284. Since they're right beside each other and the size of each Pokemon is 0x64 bytes.

Here's some basic starter code you can use to help ease the process:

Code:
.text
.align 2
.thumb
.thumb_func

@First of all, our routine will return 0x6 if no Pokemon is less than full HP
@In the case that a Pokemon is found with less than full HP, we return it's slot number
@ Slot numbers are 0 - 5. 0 = first 'mon, 1 = second 'mon, ect...

main:
	push {r0-r3, lr}
	@first step: Load into a register the Pokemon Table
	@The above should be one instruction only. 
	@set slot number to zero (pick a register to be the loop counter)
	
loop:
	@If slot number of the Pokemon we're looking at is < 6 continue, else branch end:
	@Second step: Load a half-word at Pokemon table + 0x56 for current HP
	@Third step: Load a half-word at Pokemon table + 0x58 for total HP
	@In the case Current hp != total HP, branc to section "retVal" and write to lastresult the slot number of the current Pokemon
	@this part of the code is reached if the Pokemon's Current HP = total HP.
	@If current HP == Total HP either the Pokemon is full HP, or there isn't a POkemon here
	@In the above case, we check the next Pokemon. Increment slot number and branch loop
	
nextMon:
	@increment slot counter
	@branch to loop
	
retVal:
	@store in lastResult the current Pokemon's slot number

end:
	pop {r0-r3, pc}
	
.align 2

.PokemonTable:
	.word 0x2024284
	
.lastResult:
	.word 0x20370D0
Fill in the comments with appropriate code. If you have questions ASK! Either in the Skype room or over here.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #5    
Old March 30th, 2015 (07:14 AM). Edited March 30th, 2015 by Magic.
Magic's Avatar
Magic Magic is offline
キュウコン
Moderator
CS
 
Join Date: Jan 2009
Location: UK
Age: 23
Gender: Male
Posts: 5,316
MAGIC TASK 1
Give the slot number of first Pokemon who isn't full HP


Partial Solution:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}
	ldr r0, CURRENT /*1st pokemon's current HP take 0x64*/ 
	ldr r1, TOTAL /*1st pokemon's total HP take 0x64*/ 
	
add64:	
	add r0, #0x64
	add r1, #0x64
	add r4, #0x1 /*keeps track of position in party*/
	ldrh r2, [r0]
	ldrh r3, [r1]
	cmp r4, #0x7 /*no party members with full health*/
	beq none
	cmp r2, r3
	bne add64	
	sub r4, r4, #0x1 /*account for starting on 0x1*/
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put position in last result*/
	pop {r0-r4, pc}

none:
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put 7 in last result, 'no pokemon'*/
	pop {r0-r4, pc}

CURRENT:
	.word 0x2024276

TOTAL:
	.word 0x2024278
My compiler says its not word aligned and that 0x00000022 is too big or something o__-. My brain.

Anywho, I hear there are hints coming so I shall tweak afterwards and then cry for help.
__________________
Looking for spriters/pixel artists for a ROM hacking project.
Join in Hack-a-long #1

Moderator of The Roleplay Corner
Reply With Quote
  #6    
Old March 30th, 2015 (07:44 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Magic:
MAGIC TASK 1
Give the slot number of first Pokemon who isn't full HP


Partial Solution:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}
	ldr r0, CURRENT /*1st pokemon's current HP take 0x64*/ 
	ldr r1, TOTAL /*1st pokemon's total HP take 0x64*/ 
	
add64:	
	add r0, #0x64
	add r1, #0x64
	add r4, #0x1 /*keeps track of position in party*/
	ldrh r2, [r0]
	ldrh r3, [r1]
	cmp r4, #0x7 /*no party members with full health*/
	beq none
	cmp r2, r3
	bne add64	
	sub r4, r4, #0x1 /*account for starting on 0x1*/
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put position in last result*/
	pop {r0-r4, pc}

none:
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put 7 in last result, 'no pokemon'*/
	pop {r0-r4, pc}

CURRENT:
	.word 0x2024276

TOTAL:
	.word 0x2024278
My compiler says its not word aligned and that 0x00000022 is too big or something o__-. My brain.

Anywho, I hear there are hints coming so I shall tweak afterwards and then cry for help.
A few things really quickly.
Code:
CURRENT:
	.word 0x2024276

TOTAL:
	.word 0x2024278
Current HP and Total HP's offsets can be derived from the data structure offset. They're 0x56 and 0x58 bytes from the start of the structure. So if I were to convert your routine from FR -> EM for example, there's more pointers which need changing. Minor, but still a problem. Back to the routine!

Magic's Routine /w comments:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}

	@interesting start, Works :)
	ldr r0, CURRENT
	ldr r1, TOTAL
	
add64:	

	@so adding 64 to the addresses below gets you the
	@CHP and THP (currentHP, totalHP); this is good
	add r0, #0x64
	add r1, #0x64

	@this is not so good. Although you're pushed R4, r4's value is still arbitrary
	@pushing a register doesn't set the register to 0. You need to set it before the "add64" section
	add r4, #0x1

	@loading hwords to get CHP and THP is correct!
	ldrh r2, [r0]
	ldrh r3, [r1]

	@So wait, all the above calculations would have been avoided if we noticed that we were on the 6th mon
	@if this check was at the start of add64, you could make the routine more efficient
	@ofcourse this means that we haven't added 1 to r4. So you'd have to check 0x6 rather than 0x7 (which is better)
	cmp r4, #0x7 /*no party members with full health*/
	beq none

	@Comparing the HP states here is correct, but "bne" means CHP != THP.
	@If this is the case, then the Pokemon isn't at full HP. So we'd have the first Pokemon who's not full
	@in reality, we'd be returning the slot number now, not going back to the loop.
	@think of when we want to look at the next Pokemon
	cmp r2, r3
	bne add64

	@could avoid, as I explained before
	sub r4, r4, #0x1 /*account for starting on 0x1*/

	@correct, but we want this to happen if CHP != THP
	@also right below, "none:" is exactly the same. So if you delete this chunk here
	@the code will go to the next instruction which is at the label "none:"
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put position in last result*/
	pop {r0-r4, pc}

@see note above
none:
	ldr r1, =(0x20370D0) 
	strh r4, [r1] /*put 7 in last result, 'no pokemon'*/
	pop {r0-r4, pc}


@Explained before why this is a little bit of a pain :P
CURRENT:
	.word 0x2024276

TOTAL:
	.word 0x2024278


Pretty close Magic! There's a few things with the algorithm that can use improvement, but the gist of it is good.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #7    
Old March 30th, 2015 (08:13 AM).
Magic's Avatar
Magic Magic is offline
キュウコン
Moderator
CS
 
Join Date: Jan 2009
Location: UK
Age: 23
Gender: Male
Posts: 5,316
MAGIC TASK 1
Give the slot number of first Pokemon who isn't full HP


Partial Solution/Final Solution?:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}
	ldr r0, CURRENT /*1st pokemon's current HP take 0x64*/ 
	ldr r1, TOTAL /*1st pokemon's total HP take 0x64*/
	mov r4, #0x0 
	
add64:	
	add r0, #0x64
	add r1, #0x64
	ldrh r2, [r0]
	ldrh r3, [r1]
	cmp r2, r3
	bne done	

link:
	add r4, #0x1 /*keeps track of position in party*/
	cmp r4, #0x6 /*whole party checked*/
	beq done
	b add64

done:
	ldr r1, =(0x20370D0)
	strh r4, [r1] /*places position 1-6 or puts 6 in last result, 'no pokemon'*/
	pop {r0-r4, pc}


.align 2

CURRENT:
	.word 0x202401E

TOTAL:
	.word 0x2024020
I think I'm done? Fixed the counting issue a bit and... simplified? do we get gold stars?
__________________
Looking for spriters/pixel artists for a ROM hacking project.
Join in Hack-a-long #1

Moderator of The Roleplay Corner
Reply With Quote
  #8    
Old March 30th, 2015 (08:55 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Task #2
2) Make the Player's name "Baka-san"

First of all, like the Pokemon data structure the Player also has it's own data structure. Here's something from HackMew's knowledge tutorial:

Code:
[Name (8 bytes)] 
[Gender (1 byte)] 
[??? (1 byte)]
[Trainer ID (2 bytes)]
[Secret ID (2 bytes)]
[Hours of play (2 bytes)]
[Minutes (1 byte)]
[Seconds (1 byte)]
[Frames (1 byte)]
[??? (1 byte)]
[Options (2 bytes)]
Clearly, the name is the first 8 bytes of the data structure. However, the Player's data structure is a little more peculiar than the Pokemon's data structure. This is because it's dynamic, the game uses a pseudo random algorithm which moves the location of this table to a different location every time it's accessed. That means that there isn't a static address we can use to access the player's name, like we did to access a party Pokemon's current HP.

However, the game itself needs retrieve things like the player's name, gender, ID ect, all the time. So then, the game needs a way to keep track of where it even put this data. This offset is at 0x300500C. At 0x300500C, the game stores a pointer to where the player's data is currently located.

You will need to go to 0x300500C, and load the 4 byte address. From there, go to that address, and insert:
"BCD5DFD5FF" - which is Baka in hex. You'll notice that "Baka" is 4 letters, but it's taking 5 bytes. That is because every string (i.e words) in FR/LG/R/S/E are 0xFF terminated. So you need to add that "FF" ending to tell the game that this is the end of the name.

Here's some starter code:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	@load the playerData symbol
	@load 4 byte pointer from playerData

	@OK, looping through 0xFF terminated strings are a little hard
	@Especially if the string is arbitrary, so we'll just hard code it
	
	@store byte BC 
	@add one to current offset
	@store byte D5
	@add one to current offset
	@store byte DF
	@add one to current offset
	@store byte D5
	@add one to current offset
	@store byte FF
	
	pop {r0-r1, pc}
	
.align 2

.playerData:
	.word 0x300500C
Task #3
3) Make all Pokemon Shiny

-Task removed-
I now see that this is more complicated than what should be covered this week. In time, we'll come back to the famous, "Shiny Pokemon" problem :)


Challenge task:
4) Can you delete a Pokemon?

Recall from task #1's hint, that I said if a Pokemon slot is empty, then that 0x64 chunk of RAM will be set to 00s.
Basically all we want to do is set an 0x64 block of RAM to 0x0s. No more hints on this one. I think I've made it super easy now. Anyways, there will be a bug, when you open the Pokemon Menu, the missing slot will look weird. We'll fix this problem in a coming session. For now, just try and set the RAM byte using the str command.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #9    
Old March 30th, 2015 (09:20 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Magic:
MAGIC TASK 1
Give the slot number of first Pokemon who isn't full HP


Partial Solution/Final Solution?:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}
	ldr r0, CURRENT /*1st pokemon's current HP take 0x64*/ 
	ldr r1, TOTAL /*1st pokemon's total HP take 0x64*/
	mov r4, #0x0 
	
add64:	
	add r0, #0x64
	add r1, #0x64
	ldrh r2, [r0]
	ldrh r3, [r1]
	cmp r2, r3
	bne done	

link:
	add r4, #0x1 /*keeps track of position in party*/
	cmp r4, #0x6 /*whole party checked*/
	beq done
	b add64

done:
	ldr r1, =(0x20370D0)
	strh r4, [r1] /*places position 1-6 or puts 6 in last result, 'no pokemon'*/
	pop {r0-r4, pc}


.align 2

CURRENT:
	.word 0x202401E

TOTAL:
	.word 0x2024020
I think I'm done? Fixed the counting issue a bit and... simplified? do we get gold stars?
Some minor changes to Magic's solution:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r4, lr}
	ldr r0, party
	add r1, r0, #0x56
	add r0, r0, #0x58
	mov r4, #0x0 
	
add64:	
	ldrh r2, [r0]
	ldrh r3, [r1]
	cmp r2, r3
	bne done	

next:
	add r0, r0, #0x64
	add r1, r1, #0x64
	add r4, #0x1 /*keeps track of position in party*/
	cmp r4, #0x6 /*whole party checked*/
	bne add64

done:
	ldr r1, =(0x20370D0)
	strh r4, [r1] /*places position 1-6 or puts 6 in last result, 'no pokemon'*/
	pop {r0-r4, pc}


.align 2

party:
	.word 0x2024284


Some things to keep in mind:
Code:
bne somewhere
b somewhereElse
Code like this is always able to be simplified. Double branching (one branch right next to another), unless they're branch links ("bl") statements, should never be together.

Code:
bne somewhere
b somewhereElse

somewhere:
	@code here

somewhereElse:
	@code here
is the same as

Code:
...
beq somewhereElse
@"somewhere" code here

somewhere Else:
	@code here
Save yourself some easy bytes :)


Alright Magic, I approve you to move on to the next task. Also, if you don't mind, I'd like to use your solution for a solutions post I'll make in the future. Yours is a good example of a do while loop, I hope someone makes one of a regular while loop soon too.


EDIT: I've added some links to some heavy hint posts in the first post~

Is this week a little too hard? I think it might be, we are doing RAM pointer handling, looping, and writing to RAM.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #10    
Old March 31st, 2015 (04:36 AM).
Magic's Avatar
Magic Magic is offline
キュウコン
Moderator
CS
 
Join Date: Jan 2009
Location: UK
Age: 23
Gender: Male
Posts: 5,316
MAGIC TASK 2
Make the Player's name "Baka"


Partial Solution:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, =(0x300500C) /*player data/load four bytes*/
	ldr r1, [r0] /*does this load the pointer to r1?*/
	mov r0, #0xBC
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xD5
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xDF
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xD5
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xFF
	strb r0, [r1]
	pop {r0-r1, pc}
Does this work? I wasn't sure how to load the pointer from 300500C.
__________________
Looking for spriters/pixel artists for a ROM hacking project.
Join in Hack-a-long #1

Moderator of The Roleplay Corner
Reply With Quote
  #11    
Old March 31st, 2015 (07:20 AM). Edited 4 Weeks Ago by FBI agent.
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Magic:
MAGIC TASK 2
Make the Player's name "Baka"


Partial Solution:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, =(0x300500C) /*player data/load four bytes*/
	ldr r1, [r0] /*does this load the pointer to r1?*/
	mov r0, #0xBC
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xD5
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xDF
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xD5
	strb r0, [r1]
	add r1, r1, #0x1
	mov r0, #0xFF
	strb r0, [r1]
	pop {r0-r1, pc}
Does this work? I wasn't sure how to load the pointer from 300500C.
Yeah that's right, though I would switch the registers here.

Code:
@Here it's clear that r0 is the address
@and that r1 is the byte being stored
@it's just a minor readability thing that I'm nitpicking :P

ldr r0, [r0]
mov r1, #0xByte
strb r1, [r0, #0x1]
...
You're ready for task #3 Magic :P
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #12    
Old April 1st, 2015 (02:33 AM). Edited 4 Weeks Ago by jiangzhengwenjzw.
jiangzhengwenjzw's Avatar
jiangzhengwenjzw jiangzhengwenjzw is offline
 
Join Date: Sep 2012
Gender: Male
Posts: 92
UPDATED
TASK 3
MAKE POKEMON SHINY
This is an uncomplete solution because I haven't done the trainer and egg part (I really don't have much time). I have only shinyzed wild pokemon.

Solution so far tested: (If you want it to activate in game, I think it's possibly simple because you can use a variable to do conditional branch, to either run the function or not)
Spoiler:

This is at 0x080406c4
Code:
.thumb
ldrh r1, [r4, #0x0]
ldrh r0, [r4, #0x2]
lsl r0, r0, #0x10
add r1, r1, r0
ldr r0, label
str r1, [r7, #0x4]
bx r0


.align 2
label:
.word 0x08800071
This is at 0x08800070 as free space:
Code:
.thumb
ldr r0, pidaddr
str r1, [r0, #0x0]
ldr r0, backaddr
bx r0

.align 2
pidaddr:
.word 0x0202402C
backaddr:
.word 0x08040adb


The new solution which also work for givepokemon:

Spoiler:
Code:
.thumb
@080406b4
ldr r0, label
bx r0

.align 2
label: .word 0x08800071‏

Code:
.thumb
@08800070 as free space
originalcode:
ldrb r0, [r4, #0x2]
lsl r0, r0, #0x10
add r1, r1, r0
ldrb r0, [r4, #0x3]
lsl r0, r0, #0x18
add r1, r1, r0
push {r2-r5}

getpiddata:
mov r3, r1
lsr r3, r3, #0x10 @PID1

loop:
ldr r1, playerdata
ldr r1, [r1, #0x0]
ldrh r4, [r1, #0xA] @TID
ldrh r5, [r1, #0xC] @SID
bl prng @PID2 in r0
mov r1, r0
eor r0, r3
eor r4, r5
eor r0, r4
cmp r0, #0x8
bhs loop
lsl r3, r3, #0x10
add r1, r3, r1
str r1, [r7, #0x0]
pop {r2-r5}
ldr r0, backaddr
bx r0

prng:
ldr r0, prngaddr
bx r0

.align 2
playerdata: 
.word 0x0300500C
prngaddr:
.word 0x08044EC9
backaddr:
.word 0x080406C1‏


Reference: Hackmew
Reply With Quote
  #13    
Old April 1st, 2015 (04:12 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Sorry, I can't see anything. I'll come back tomorrow when this website becomes browsable again.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #14    
Old 4 Weeks Ago (04:13 AM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 275
Alrighty, this is happening, thanks FBI firstly. Here I go:

Spoiler:
Task 1
Spoiler:
Quote:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r2,lr}
ldr r0, pkmnData

loop:
ldrh r1, [r0, #0x56]
ldrh r2, [r0, #0x58]
cmp r1, r2
beq done
add r0, #0x64

done:
pop {r0-r2,pc}

.align2

pkmnData: .word 0x02024284


Task 2
Spoiler:
Quote:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r1}
ldr r0, Player
ldr r0, [r0]
mov r1, #0xBC
strb r1, [r0]
mov r1, #0xD5
strb r1, [r0, #0x1]
mov r1, #0xDF
strb r1, [r0, #0x2]
mov r1, #0xD5
strb r1, [r0, #0x3]
mov r1, #0xFF
strb r1, [r0, #0x4]
pop {r0-r1}

.align2

Player: .word 0x0300500C


Task 3
Spoiler:
Normal
Quote:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r2}
ldr r0, pkmnData

loop:
ldr r1, [r0, r2]
lsl r1, r1, #0x20
add r2, #0x4
cmp r2, #0x64
beq done
b loop

done:
pop {r0-r2}

.align2

pkmnData: .word 0x02024284
Fancy (special 0x9F or something)
Quote:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r2}
ldr r0, pkmnData
ldr r1, lastresult
ldrb r1, [r1]
mul r1, #0x64
add r0, r1

loop:
ldr r1, [r0, r2]
lsl r1, r1, #0x20
add r2, #0x4
cmp r2, #0x64
beq done
b loop

done:
pop {r0-r2}

.align2

pkmnData: .word 0x02024284
lastresult: .word 0x020270B6 + (0x800D * 2)


I tried to get maximum efficiency for these routines and minimal register use. Any comment on deletion strategy?

May I ask:

- When do we need to push lr and pop pc? It is taught in most tutorials but I never have used them.

- Also I pushed r2 and assumed this register was 0. Is this correct to assume so or would I have to mov r2, #0x0 at the start?
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #15    
Old 4 Weeks Ago (05:58 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by kearnseyboy6:
Alrighty, this is happening, thanks FBI firstly. Here I go:
Task 1: This loop isn't a loop! It only runs once, because as you can see there's no "b loop" command inside the loop. Another thing is that you're branching to the wrong part of code.

Remember, that if a Pokemon is not full HP, we return their slot number. Here, you're jumping to the end if they are full HP. Instead of:
Code:
cmp r1, r2
beq done
You would need to "beq loop". Because if the current HP = Total HP, then the Pokemon is full HP. So we need to go to the next Pokemon. You're also going to need another register to keep track of how many times the loop will execute (it's useful also because this "counter" register will act as a slot identifier for our return. Right now, assuming you fix the non-looping issue, it will loop way past your six Pokemon.
Finally, the last thing to think about in your solution for task one is this part:
Code:
cmp r1, r2
beq done @obviously you will fix this to beq loop
add r0, #0x64
Above, when the branch is changed to beq loop, we'll be stuck in an infinite loop because "add r0" isn't going to happen before the loop. I.E you need to move it to the best location.


Task number 2 looks very well done. Good job. But you're forgetting to push {lr} and pop {pc}. This routine is going to be called by another routine using bl or a linker. So you need to push the link register and pop pc. Otherwise, as it is now, it will not return and instructions in the next line (beyond this routine) will continue to execute until the whole thing crashes.

There some things wrong with task 3 in your solution while I will address now. First of all, when you're storing bytes in RAM, you need to use str or strb. In both of your solutions you are trying to load 4 bytes at a time from pkmnData, then you're setting the register to 0 (by using lsl and bit shifting all 32 bits), but you could use mov instead. Anyways, the point is, you're setting the register to zero, not the actual RAM at the offset. You'd need to use str/strh/strb for this. I recommend using strb first, and then expanding your solution.

Again like the last routine you've forgotten to push/pop lr and pc. Look at the explanation I gave for your task 2 for more info.
Finally, like Magic had, you also have double branching statements.

Note that:
Code:
cmp r2, #0x64
beq done
b loop

done:
...
code
...
is the same as

Code:
cmp r2, #0x64
bne loop

done:
...
code
...
Now to address your questions.

Quote:
-When do we need to push lr and pop pc? It is taught in most tutorials but I never have used them.
Pretty much all the time, except when you're hooking. That's the simple explanation, but in more complication, you should push lr every time you're anticipating your function to be called and expected to be returned from after being called.

Quote:
- Also I pushed r2 and assumed this register was 0. Is this correct to assume so or would I have to mov r2, #0x0 at the start?
No, that is not correct. You need to set r2 to 0.
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #16    
Old 4 Weeks Ago (05:18 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 204
Quote originally posted by FBI agent:
- Knizz's idb (see his signature)
Wait wait wait. You mean that that link now works?
Reply With Quote
  #17    
Old 4 Weeks Ago (05:41 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Touched:
Wait wait wait. You mean that that link now works?
Did he reupload? I'm not sure I'm allowed to upload a mirror without his permission :c
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #18    
Old 4 Weeks Ago (03:42 PM).
Percy's Avatar
Percy Percy is offline
Sceptile ftw
 
Join Date: Sep 2014
Location: Somewhere in the world, obviously
Age: 18
Gender: Male
Nature: Gentle
Posts: 1,509
Quote originally posted by Touched:
Wait wait wait. You mean that that link now works?
It works as far as I know because I just downloaded it last week.
__________________
Pokémon Ranger Academy
Status: Coming Soon ...
Credit

Pair

Reply With Quote
  #19    
Old 4 Weeks Ago (08:42 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Alright, that was week one. Last week we didn't really need to do much "finding", debugging or searching. I tried to keep stuff simple, if you knew the OP codes and how to use them, last weeks tasks should've been rather simple. In the case you were unable to finish, and would like more time, then go ahead and try finishing. There's really no due date, as everything is archived so you can attempt/look at hints/solutions whenever you need to.

Moving on, I will now post solutions of last weeks tasks. Explanations will follow some time tomorrow when I have time for breaking and analyzing thought processes for writing these.

Task #1: Slot number of a Pokemon who isn't full HP

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

@put in variable 0x800D the slot of a Pokemon who
@isn't full HP. Slot numbers are 0-5, and 6 for all full.

main:
	push {r0-r3, lr}
	ldr r0, =(0x2024284 + 0x56)
	mov r3, #0x0
	
loop:
	cmp r3, #0x6
	beq retval
	ldrh r1, [r0]
	ldrh r2, [r0, #0x2]
	cmp r2, r1
	bne retval
	add r3, r3, #0x1
	add r0, r0, #0x64
	b loop
	
retval:
	ldr r0, =(0x20370D0)
	strh r3, [r0]
	
end:
	pop {r0-r3, pc}

.align 2



Task #2: Setting the Player's name

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, =(0x300500C)
	ldr r0, [r0]
	mov r1, #0xBC
	strb r1, [r0]
	mov r1, #0xD5
	strb r1, [r0, #0x1]
	mov r1, #0xDF
	strb r1, [r0, #0x2]
	mov r1, #0xD5
	strb r1, [r0,#0x3]
	pop {r0-r1, pc}

.align 2


Challenge task:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r2, lr}
	ldr r2, =(0x20370B8)
	ldrb r2, [r2]
	ldr r0, =(0x2024284)
	mov r1, #0x64
	mul r2, r2, r1
	add r0, r0, r2
	
eraseLoop:
	mov r2, #0x0
	strb r2, [r0]
	cmp r1, #0x1
	beq end
	sub r1, r1, #0x1
	add r0, r0, #0x1
	b eraseLoop
	
end:
	pop {r0-r2, pc}

.align 2



Challenge task stmia/ldmia edition:

OK, you don't need to do it this way, and this way is slightly more complicated too. Though faster. We'll look at memcpy, memset, strcpy and such at a later time.

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r7, lr}
	
	@figure out which 'mon to delete
	ldr r0, =(0x2024284)
	ldr r1, =(0x20370B8)
	ldrb r1, [r1]
	mov r2, #0x64
	mul r1, r1, r2
	add r0, r0, r1
	
	@memset r1, #0x0
	mov r1, #0x0
	
	@end offset.
	add r2, r2, r0
	sub r2, r2, #0x14
	
memset:
	@set first 20 bytes #0x0
	stmia r0!, {r1}@4
	stmia r0!, {r1}@8
	stmia r0!, {r1}@C
	stmia r0!, {r1}@10
	stmia r0!, {r1} @14
	sub r0, r0, #0x14
	
memcpy:
	@copy previous 20 bytes and overwrite current bytes
	cmp r2, r0
	beq end
	ldmia r0!, {r3-r7}
	stmia r0!, {r3-r7}
	sub r0, r0, #0x14
	b memcpy
	
	
end:
	pop {r0-r7, pc}

.align 2
I'll put up a new set of tasks soon too. I need to first finish a mini-tutorial post for explanations for how to do these tasks above. If you're done and just waiting for the next task, take a look at the solutions. There are probably differences between your version and mine. Who's is better, and why?
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #20    
Old 3 Weeks Ago (12:39 PM).
DarkPsychic's Avatar
DarkPsychic DarkPsychic is offline
 
Join Date: Jul 2012
Gender: Male
Posts: 68
So I practice at task 1 all night (literally haven't went to sleep).

To no avail I still can't seem to figure out how you would loop it and
do the comparison of 6 possible Pokemon's CHP and THP.
Nor could I understand just how to keep track of the slot of the Pokemon ergo 0-5.

Here is what I came up with
Partial Routine(if it can be called even that)
Spoiler:

.text
.align 2
.thumb
.thumb_func


main:
push {r0-r4, lr}
ldr r0, .PokemonTable
ldrh r0, [r0]
ldr r1, [r0]
ldrh r1, [r0]
cmp r0, #0x5
bgt end

firstpokemontable:
add r0, #0x56
add r1, #0x58
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq secondpokemontable
cmp r2, r3
bne scriptvar1
bgt end





secondpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq thirdpokemontable
cmp r2, r3
bne scriptvar2
bgt end

thirdpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fourthpokemontable
cmp r2, r3
bne scriptvar3
bgt end

fourthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fifthpokemontable
cmp r2, r3
bne scriptvar4
bgt end

fifthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq sixthpokemontable
cmp r2, r3
bne scriptvar5
bgt end

sixthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq end
cmp r2, r3
bne scriptvar6
bgt end

scriptvar1:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne secondpokemontable
bgt end

scriptvar2:
ldr r4, .SCRIPT_VAR_8001
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne thirdpokemontable
bgt end

scriptvar3:
ldr r4, .SCRIPT_VAR_8002
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fourthpokemontable
bgt end

scriptvar4:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fifthpokemontable
bgt end

scriptvar5:
ldr r4, .SCRIPT_VAR_8003
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne sixthpokemontable
bgt end

scriptvar6:
ldr r4, .SCRIPT_VAR_8004
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bgt end


end:
pop {r0-r4, pc}





.align 2


.PokemonTable:
.word 0x2024284


.SCRIPT_VAR_8000:
.word 0x020370B8

.SCRIPT_VAR_8001:
.word 0x020370BA

.SCRIPT_VAR_8002:
.word 0x020370BC

.SCRIPT_VAR_8003:
.word 0x020370BE

.SCRIPT_VAR_8005:
.word 0x020370C2

.SCRIPT_VAR_8004:
.word 0x020370c0

.Last_Result_800D:
.word 0x020370D0


I tested it in a clean rom as well and it does not work in any sense... I couldn't even get the game to bug out or freeze >_< sadly hahahaha

Well any advice and help is much appreciated an thank you for your time

Ps also thank you FBI Agent for this thread
Reply With Quote
  #21    
Old 3 Weeks Ago (09:03 AM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by DarkPsychic:
So I practice at task 1 all night (literally haven't went to sleep).

To no avail I still can't seem to figure out how you would loop it and
do the comparison of 6 possible Pokemon's CHP and THP.
Nor could I understand just how to keep track of the slot of the Pokemon ergo 0-5.

Here is what I came up with
Partial Routine(if it can be called even that)
Spoiler:

.text
.align 2
.thumb
.thumb_func


main:
push {r0-r4, lr}
ldr r0, .PokemonTable
ldrh r0, [r0]
ldr r1, [r0]
ldrh r1, [r0]
cmp r0, #0x5
bgt end

firstpokemontable:
add r0, #0x56
add r1, #0x58
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq secondpokemontable
cmp r2, r3
bne scriptvar1
bgt end





secondpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq thirdpokemontable
cmp r2, r3
bne scriptvar2
bgt end

thirdpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fourthpokemontable
cmp r2, r3
bne scriptvar3
bgt end

fourthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fifthpokemontable
cmp r2, r3
bne scriptvar4
bgt end

fifthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq sixthpokemontable
cmp r2, r3
bne scriptvar5
bgt end

sixthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq end
cmp r2, r3
bne scriptvar6
bgt end

scriptvar1:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne secondpokemontable
bgt end

scriptvar2:
ldr r4, .SCRIPT_VAR_8001
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne thirdpokemontable
bgt end

scriptvar3:
ldr r4, .SCRIPT_VAR_8002
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fourthpokemontable
bgt end

scriptvar4:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fifthpokemontable
bgt end

scriptvar5:
ldr r4, .SCRIPT_VAR_8003
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne sixthpokemontable
bgt end

scriptvar6:
ldr r4, .SCRIPT_VAR_8004
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bgt end


end:
pop {r0-r4, pc}





.align 2


.PokemonTable:
.word 0x2024284


.SCRIPT_VAR_8000:
.word 0x020370B8

.SCRIPT_VAR_8001:
.word 0x020370BA

.SCRIPT_VAR_8002:
.word 0x020370BC

.SCRIPT_VAR_8003:
.word 0x020370BE

.SCRIPT_VAR_8005:
.word 0x020370C2

.SCRIPT_VAR_8004:
.word 0x020370c0

.Last_Result_800D:
.word 0x020370D0


I tested it in a clean rom as well and it does not work in any sense... I couldn't even get the game to bug out or freeze >_< sadly hahahaha

Well any advice and help is much appreciated an thank you for your time

Ps also thank you FBI Agent for this thread
Oh man there's quite a bit wrong here. I think that looking at the solution video will probably be much more clearer as to how to achieve the routine's functionality.

Speaking of solution videos, I made a solution video for task #1. I'm thinking the video is too long, and too indept. Would you guys prefer briefer and less detailed versions for the rest of the tasks?

__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #22    
Old 3 Weeks Ago (09:17 AM). Edited 3 Weeks Ago by Touched.
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 204
Quote originally posted by DarkPsychic:
So I practice at task 1 all night (literally haven't went to sleep).

To no avail I still can't seem to figure out how you would loop it and
do the comparison of 6 possible Pokemon's CHP and THP.
Nor could I understand just how to keep track of the slot of the Pokemon ergo 0-5.

Here is what I came up with
Partial Routine(if it can be called even that)
Spoiler:

.text
.align 2
.thumb
.thumb_func


main:
push {r0-r4, lr}
ldr r0, .PokemonTable
ldrh r0, [r0]
ldr r1, [r0]
ldrh r1, [r0]
cmp r0, #0x5
bgt end

firstpokemontable:
add r0, #0x56
add r1, #0x58
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq secondpokemontable
cmp r2, r3
bne scriptvar1
bgt end





secondpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq thirdpokemontable
cmp r2, r3
bne scriptvar2
bgt end

thirdpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fourthpokemontable
cmp r2, r3
bne scriptvar3
bgt end

fourthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq fifthpokemontable
cmp r2, r3
bne scriptvar4
bgt end

fifthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq sixthpokemontable
cmp r2, r3
bne scriptvar5
bgt end

sixthpokemontable:
add r0, #0x64
add r1, #0x64
ldr r2, [r0]
ldrh r2, [r0]
ldr r3, [r0]
ldrh r3, [r1]
cmp r2, r3
beq end
cmp r2, r3
bne scriptvar6
bgt end

scriptvar1:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne secondpokemontable
bgt end

scriptvar2:
ldr r4, .SCRIPT_VAR_8001
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne thirdpokemontable
bgt end

scriptvar3:
ldr r4, .SCRIPT_VAR_8002
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fourthpokemontable
bgt end

scriptvar4:
ldr r4, .SCRIPT_VAR_8000
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne fifthpokemontable
bgt end

scriptvar5:
ldr r4, .SCRIPT_VAR_8003
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bne sixthpokemontable
bgt end

scriptvar6:
ldr r4, .SCRIPT_VAR_8004
ldr r2, [r2]
ldrh r2, [r2]
str r2, [r4]
bgt end


end:
pop {r0-r4, pc}





.align 2


.PokemonTable:
.word 0x2024284


.SCRIPT_VAR_8000:
.word 0x020370B8

.SCRIPT_VAR_8001:
.word 0x020370BA

.SCRIPT_VAR_8002:
.word 0x020370BC

.SCRIPT_VAR_8003:
.word 0x020370BE

.SCRIPT_VAR_8005:
.word 0x020370C2

.SCRIPT_VAR_8004:
.word 0x020370c0

.Last_Result_800D:
.word 0x020370D0


I tested it in a clean rom as well and it does not work in any sense... I couldn't even get the game to bug out or freeze >_< sadly hahahaha

Well any advice and help is much appreciated an thank you for your time

Ps also thank you FBI Agent for this thread
Please COMMENT your code so that your intention is clear. If you add comments, we can at least try to understand your reasoning and be of greater assistance.
Also, some life advice: sleep. A good night's rest can make the solution yesterday's impossible problem clear. The same goes for taking regular breaks - your mind works out solutions even when you're not actively thinking about something.

Now, lets get onto your problem. From glancing at your code, it's clear you are missing the point of task one, which I'm guessing was to teach you how to use a loop. You are just copying and pasting code for each of the 6 Pokemon. A loop is perfect for this kind of problem, as you just reuse code perform one action to perform that action multiple times. Below is the anatomy of a basic loop to help you understand the concept.

Code:
@ Basic loop (FOR loop)

@ Set r0 to 0. We're keeping track of how many iterations we've done, 
@ starting from 0
@ This is the INITIALISATION phase

mov r0, #0

@ Use a label to mark the start of the loop so the assembler knows where
@ to jump back to
loop_start:
@ The BODY of the loop goes here. This is the code we will be repeating.
@ typically we will use the counter in r0 in conjunction with some 
@ basic arithmetic to keep track of a memory address or something

@ Now we INCREMENT the counter to mark that ONE iteration is complete
add r0, #1

@ Now comes the CONDITION
@ The condition tells the loop when it can exit. Without the condition, 
@ the loop would repeat indefinitely. This is (in most cases) undesirable 
@ as it would cause the game to freeze
cmp r0, #6

@ Repeat the loop if the counter is LESS THAN 6
blt loop_start

@ We are now out of the loop
@ Code to execute after the loop is complete
EDIT:
Quote originally posted by FBI agent:
Oh man there's quite a bit wrong here. I think that looking at the solution video will probably be much more clearer as to how to achieve the routine's functionality.

Speaking of solution videos, I made a solution video for task #1. I'm thinking the video is too long, and too indept. Would you guys prefer briefer and less detailed versions for the rest of the tasks?

That video seems to be private?
Reply With Quote
  #23    
Old 3 Weeks Ago (01:29 PM).
FBI agent's Avatar
FBI agent FBI agent is offline
If my PM box is full, VM instead :x
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 818
Quote originally posted by Touched:
Please COMMENT your code so that your intention is clear. If you add comments, we can at least try to understand your reasoning and be of greater assistance.
Also, some life advice: sleep. A good night's rest can make the solution yesterday's impossible problem clear. The same goes for taking regular breaks - your mind works out solutions even when you're not actively thinking about something.

Now, lets get onto your problem. From glancing at your code, it's clear you are missing the point of task one, which I'm guessing was to teach you how to use a loop. You are just copying and pasting code for each of the 6 Pokemon. A loop is perfect for this kind of problem, as you just reuse code perform one action to perform that action multiple times. Below is the anatomy of a basic loop to help you understand the concept.

Code:
@ Basic loop (FOR loop)

@ Set r0 to 0. We're keeping track of how many iterations we've done, 
@ starting from 0
@ This is the INITIALISATION phase

mov r0, #0

@ Use a label to mark the start of the loop so the assembler knows where
@ to jump back to
loop_start:
@ The BODY of the loop goes here. This is the code we will be repeating.
@ typically we will use the counter in r0 in conjunction with some 
@ basic arithmetic to keep track of a memory address or something

@ Now we INCREMENT the counter to mark that ONE iteration is complete
add r0, #1

@ Now comes the CONDITION
@ The condition tells the loop when it can exit. Without the condition, 
@ the loop would repeat indefinitely. This is (in most cases) undesirable 
@ as it would cause the game to freeze
cmp r0, #6

@ Repeat the loop if the counter is LESS THAN 6
blt loop_start

@ We are now out of the loop
@ Code to execute after the loop is complete
EDIT:

That video seems to be private?
idk why its private by default. I've fixed it now, sorry :c
__________________
...

My name forum name is FBI Agent, though you can call me FBI because it's shorter.

Some of my stuff:
ASM request/resource thread
ASM tutorials thread
ASM Workshop
Reply With Quote
  #24    
Old 3 Weeks Ago (07:24 AM).
DizzyEgg's Avatar
DizzyEgg DizzyEgg is offline
 
Join Date: Feb 2014
Age: 17
Gender: Male
Nature: Quiet
Posts: 62
This thread seems very promising. Thanks FBI!
Earlier, I did two first tasks, but I made some mistakes in them and looked up solutions. That's why I tried to do the challenge task on my own and I think I got it right. I tested my routine and it works fine but after deleting a pokemon weird things happen. I can't do anything about it though.
My code:
Spoiler:
Code:
 .text
.align 2
.thumb
.thumb_func

main:
    push {r0-r2,lr}
    ldr r1, =(0x020370D0) @var 0x800D aka LastResult
    ldr r1, [r1]@we get the value of that var
    
check_which_one: @check which mon we wanna delete
    cmp r1, #0x0 
    beq first_slot
    cmp r1, #0x1
    beq second_slot
    cmp r1, #0x2
    beq third_slot
    cmp r1, #0x3
    beq fourth_slot
    cmp r1, #0x4 @if it's not 0-4 it's gotta be 5
    beq fifth_slot
    
sixth_slot:
    ldr r0, =(0x02024284 + 500) @we load pokemon data
    b delete
    
first_slot:
    ldr r0, =(0x02024284 + 400)
    b delete
    
fourth_slot:
    ldr r0, =(0x02024284 + 300)
    b delete
    
third_slot:
    ldr r0, =(0x02024284 + 200)
    b delete
    
second_slot:
    ldr r0, =(0x02024284 + 100)
    b delete

fifth_slot:
    ldr r0, =(0x02024284)

delete:
    mov r1, #0x0 @container of zeros 0000
    mov r2, #0x0 @counter
    
loop:
    cmp r2, #0x64 @if counter == 64 == all data has been altered
    beq end
    strb r1, [r0, r2] @store one zero at address r0 + r2
    add r2, r2, #0x1 @counter up
    b loop @repeat that action 64 - r2 times
    
end:
    pop {r0-r2,pc}

.align 2


I know that my code could be smaller but I don't have any idea how that could be done without messing it up.
__________________
Please excuse my poor English. I'm still learning
Reply With Quote
  #25    
Old 3 Weeks Ago (02:34 AM). Edited 3 Weeks Ago by Touched.
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 204
Quote originally posted by DizzyEgg:
This thread seems very promising. Thanks FBI!
Earlier, I did two first tasks, but I made some mistakes in them and looked up solutions. That's why I tried to do the challenge task on my own and I think I got it right. I tested my routine and it works fine but after deleting a pokemon weird things happen. I can't do anything about it though.
My code:
Spoiler:
Code:
 .text
.align 2
.thumb
.thumb_func

main:
    push {r0-r2,lr}
    ldr r1, =(0x020370D0) @var 0x800D aka LastResult
    ldr r1, [r1]@we get the value of that var
    
check_which_one: @check which mon we wanna delete
    cmp r1, #0x0 
    beq first_slot
    cmp r1, #0x1
    beq second_slot
    cmp r1, #0x2
    beq third_slot
    cmp r1, #0x3
    beq fourth_slot
    cmp r1, #0x4 @if it's not 0-4 it's gotta be 5
    beq fifth_slot
    
sixth_slot:
    ldr r0, =(0x02024284 + 500) @we load pokemon data
    b delete
    
first_slot:
    ldr r0, =(0x02024284 + 400)
    b delete
    
fourth_slot:
    ldr r0, =(0x02024284 + 300)
    b delete
    
third_slot:
    ldr r0, =(0x02024284 + 200)
    b delete
    
second_slot:
    ldr r0, =(0x02024284 + 100)
    b delete

fifth_slot:
    ldr r0, =(0x02024284)

delete:
    mov r1, #0x0 @container of zeros 0000
    mov r2, #0x0 @counter
    
loop:
    cmp r2, #0x64 @if counter == 64 == all data has been altered
    beq end
    strb r1, [r0, r2] @store one zero at address r0 + r2
    add r2, r2, #0x1 @counter up
    b loop @repeat that action 64 - r2 times
    
end:
    pop {r0-r2,pc}

.align 2


I know that my code could be smaller but I don't have any idea how that could be done without messing it up.
Good job and congratulations on completing your first ASM challenge

What weird things happen? To make your code neater (and more maintainable) you can calculate the amount to add to the party address instead of the whole "check_which_one" thing. Since you have the slot number in r1 and r0 is free:
Code:
mov r0, #100
mul r1, r0 @ Multiply slot by 100
Then you can load the base address (0x02024284) and add this value to it:
Code:
ldr r0, =0x02024284
add r0, r1

@ Continue
b delete
Note I use MUL only because 100 is not trivially computable. MUL is an expensive operation and thus should only be used where necessary (otherwise use bitshifts and addition/subtraction).

Other optimizations include:
  • You don't need the push and pop. You never need to push r0-r3 to the stack at the start of a function.
  • 100 is divisible by 4. Use str instead of strb to conserve write operations.

EDIT: I noticed one error:
At the top you do:
Code:
    ldr r1, =(0x020370D0) @var 0x800D aka LastResult
    ldr r1, [r1]@we get the value of that var
That second ldr should be a ldrh. Variables are always halfwords. You're going to read too much data into r1 rather than just the data in 0x800D like you intended.
Reply With Quote
Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are UTC -8. The time now is 07:20 AM.