Gotta do a serious tutorial;
First, download these files:
http://www.mediafire.com/download/mjat5mj5yx278j4/ASM_Tutorial.zip
Part 1: Hello World
First, have a loom at Mario's behavior. Open the Behavior scripts.txt file.
21CCC0/002EC0 00 00 00 00
21CCC4/002EC4 10 05 00 00 <- irrelevant
21CCC8/002EC8 11 01 01 00 <- irrelevant
21CCCC/002ECC 11 03 00 01 <- irrelevant
21CCD0/002ED0 23 00 00 00 00 25 00 A0 <-collision sphere
21CCD8/002ED8 08 00 00 00 <-start of a loop, that gets called every frame
21CCDC/002EDC 0C 00 00 00 80 2C B1 C0 <-calls a function
21CCE4/002EE4 0C 00 00 00 80 29 CA 58 <-calls a function
21CCEC/002EEC 0C 00 00 00 80 2C B2 64 <-calls a function
21CCF4/002EF4 09 00 00 00 <- end of the loop
behavior script command 0x0C calls a function. that's what we need.
Luckily, Mario's behavior calls an useless debug menu, which we can override. For function, that are between 80 24 60 00 and 80 33 00 00, we can just sub 80245000 from it, to find the ROM offset.
(if you are looking into the .txt file, you'll notice, that the 0x0Cs are allready named)
So we've got to calculate 802CB1C0-80245000 = 861C0
Now, open LEM ASM, press F6 and F7 to get the correct view mode and go to this address. on top should be "ADDIU SP, SP, $FFD8"
Now, let's do the first code;
for the start, i won't explain, what exactly it does, but start every function with:
and end it with:
if you look into the functions.txt file, you'll see a list of functions. we need the "PrintXY" function.
PRINTXY: 802D66C0, A0 (xpos) a1(y pos), A2 (message location);
a function gets called through the command JAL. In our example, it would be
but we've got to be carefull with this command. It executes the next line after it, before it actually JALs the function. I'll show this later in the example.
In ASM, arguments are getting loaded into registers. so for this example, we will have to set a0, a1 and a2 with own commands too.
Commands to load immidiate values are:
LUI A0, $value - loads a value, that get's multiplied by $10000; so
would load 802C0000 into A0.
ORI A0, A0, $VALUE - ORs all bits, if at least 1 bit is 1, it will put the result to 1; example:
(imagine, A0 is allready 802C0000)
802C0000 <-A0
0000B23C <-immidiate Value
802CB23C <-Result
if you want to see this bitwise, look into win calculator.
We will just use these 2 operants to put arguments to our function.
Now you might wonder, how we can find out the "message location";
it works just as we found our ROM offset for the 0x0C command (except, that we have to calculate from ROM to RAM instead of from RAM to ROM. Write a text somewhere into the checksum area, where you have space and add 80245000 to it. in our example, i'd write it to 8623C, because it's still in the debug menu, which we are overwriting anyways.
to find the rom offset then: 8623C+80245000 = 802CB23C;
so we can extend our code to:
now we've just got to set A0 and A1, which is the position. the positions should be around $70. Note, that when using ORI, you'll have to give a register and an immidiate value. So the register has to have the value 0. For such cased, we got R0. This register can just contain 0, so doing anything with it won't change anything. So the codeline for these registers is:
well, you can change the immidiate value, if you want other printing positions, obviously.
now, i mentioned above, that the line after the JAL gets executes, before it actually JALs. so we have to put on of these 2 lines after the JAL.
So, the code looks like:
(to inser tit with LEM ASM, press f3, btw.)
next lesson will have ANDI, Branches and Loads!
This is how the result should look like, if you've entered the code correctly:
http://bin.smwcentral.net/u/21427/Project64%2B2013-09-08%2B12-42-34-79.png

First, download these files:
http://www.mediafire.com/download/mjat5mj5yx278j4/ASM_Tutorial.zip
Part 1: Hello World
First, have a loom at Mario's behavior. Open the Behavior scripts.txt file.
21CCC0/002EC0 00 00 00 00
21CCC4/002EC4 10 05 00 00 <- irrelevant
21CCC8/002EC8 11 01 01 00 <- irrelevant
21CCCC/002ECC 11 03 00 01 <- irrelevant
21CCD0/002ED0 23 00 00 00 00 25 00 A0 <-collision sphere
21CCD8/002ED8 08 00 00 00 <-start of a loop, that gets called every frame
21CCDC/002EDC 0C 00 00 00 80 2C B1 C0 <-calls a function
21CCE4/002EE4 0C 00 00 00 80 29 CA 58 <-calls a function
21CCEC/002EEC 0C 00 00 00 80 2C B2 64 <-calls a function
21CCF4/002EF4 09 00 00 00 <- end of the loop
behavior script command 0x0C calls a function. that's what we need.
Luckily, Mario's behavior calls an useless debug menu, which we can override. For function, that are between 80 24 60 00 and 80 33 00 00, we can just sub 80245000 from it, to find the ROM offset.
(if you are looking into the .txt file, you'll notice, that the 0x0Cs are allready named)
So we've got to calculate 802CB1C0-80245000 = 861C0
Now, open LEM ASM, press F6 and F7 to get the correct view mode and go to this address. on top should be "ADDIU SP, SP, $FFD8"
Now, let's do the first code;
for the start, i won't explain, what exactly it does, but start every function with:
Code
ADDIU SP, SP, $FFE8 SW RA, $0014 (SP)
and end it with:
Code
LW RA, $0014 (SP) JR RA ADDIU SP, SP, $0018
if you look into the functions.txt file, you'll see a list of functions. we need the "PrintXY" function.
PRINTXY: 802D66C0, A0 (xpos) a1(y pos), A2 (message location);
a function gets called through the command JAL. In our example, it would be
Code
;JAL $802D66C0
but we've got to be carefull with this command. It executes the next line after it, before it actually JALs the function. I'll show this later in the example.
In ASM, arguments are getting loaded into registers. so for this example, we will have to set a0, a1 and a2 with own commands too.
Commands to load immidiate values are:
LUI A0, $value - loads a value, that get's multiplied by $10000; so
Code
LUI A0, $802C
would load 802C0000 into A0.
ORI A0, A0, $VALUE - ORs all bits, if at least 1 bit is 1, it will put the result to 1; example:
(imagine, A0 is allready 802C0000)
Code
ORI A0, A0, $B23C
802C0000 <-A0
0000B23C <-immidiate Value
802CB23C <-Result
if you want to see this bitwise, look into win calculator.
We will just use these 2 operants to put arguments to our function.
Now you might wonder, how we can find out the "message location";
it works just as we found our ROM offset for the 0x0C command (except, that we have to calculate from ROM to RAM instead of from RAM to ROM. Write a text somewhere into the checksum area, where you have space and add 80245000 to it. in our example, i'd write it to 8623C, because it's still in the debug menu, which we are overwriting anyways.
to find the rom offset then: 8623C+80245000 = 802CB23C;
so we can extend our code to:
Code
ADDIU SP, SP, $FFE8 SW RA, $0014 (SP) LUI A2, $802C ORI A2, A2, $B23C JAL $802D66C0 LW RA, $0014 (SP) JR RA ADDIU SP, SP, $0018
now we've just got to set A0 and A1, which is the position. the positions should be around $70. Note, that when using ORI, you'll have to give a register and an immidiate value. So the register has to have the value 0. For such cased, we got R0. This register can just contain 0, so doing anything with it won't change anything. So the codeline for these registers is:
Code
ORI A0, R0, $0070 ORI A1, R0, $0070
well, you can change the immidiate value, if you want other printing positions, obviously.
now, i mentioned above, that the line after the JAL gets executes, before it actually JALs. so we have to put on of these 2 lines after the JAL.
So, the code looks like:
Code
ADDIU SP, SP, $FFE8 SW RA, $0014 (SP) LUI A2, $802C ORI A2, A2, $B23C ORI A0, R0, $0070 JAL $802D66C0 ORI A1, R0, $0070 LW RA, $0014 (SP) JR RA ADDIU SP, SP, $0018
(to inser tit with LEM ASM, press f3, btw.)
next lesson will have ANDI, Branches and Loads!
This is how the result should look like, if you've entered the code correctly:
http://bin.smwcentral.net/u/21427/Project64%2B2013-09-08%2B12-42-34-79.png
