12 ->
^^
vv
List results:
Search options:
Use \ before commas in usernames
InsomniaDMX just recently posted a bit of code that made Air: Fool X-ray blocks with a BTS of 03 hurt you like lava does. I've read a few articles on ASM, and I know Java, so I figured I would try to use my knowledge decipher it. I've looked for some simple asm examples, and I think this is just what I am looking for. I am just looking for some clarification to see if I am on the right track. I didn't see any other topics were like this, so hopefully this is in the right spot.  I wrote my comments in red.


lorom  //Not sure what this does, but I think I've heard something about loroms and hiroms? Maybe header, no header?
;Lava style damage block hack
;by Insom
;
;ONCE AGAIN... USE XKAS V.06 TO COMPILE...
;
;Not a whole lot to say about this one...
;To use, set the tiles you want to have this effect
;to block type $02 ("Air. Fool X-RAY.")
;with a BTS value of $03. There are PLENTY of blank
;spaces in the lookup table that I mention, so take
;advantage if you want to add other blocks. Just add
;another DW $xxxx after the first one to point to new
;code. For example, $94:98B2's pointer corresponds to
;the BTS value of $03, and $94:98B4's pointer would
;correspond to the BTS value of $04.
;
;Good luck!
;
;__________________________________________________
;
;Defines:

!value = #$7000  //Defining a variable named value with the value of 7000 in hex? I think the "#" means the number is a number and not an address, but how is 7000 a very small number (or fractional number), since the comment below says a whole number would be way too much damage.
;Fractional damage per frame. I didn't include whole
;number damages, because even a whole number damage
;of $0001 would seem ridiculous. Feel free to experiment
;with this value.

!damage = $0A4E //Defines a new variable named damage, and according to the comment this variable holds the address in the rom that the damage(or "value" variable) value should be stored at.
;The address to store the damage value to.

;__________________________________________________


;Change the entry for this block type in the appropiate
;lookup table to point to where our code will be.

org $9498B2  //Not really sure about this one, but it must the code to the right position in the rom or something.

    DW $B300 //Same as above.



;Now that we've got our entry point, write the code.

org $94B300  //Don't know.
 

    LDA !value  //Okay, this must load the variable "value" into the processor.
    STA !damage //This must store what is in the processor (in this case the "value" variable) at the location of the "damage" variable.
    RTS //This piece returns the flow of the code back to wherever it branched off at. I don't see any JMP, or BRK command, so it must have something to do with those ORG commands.


Any help is appreciated.
Thread title: 
Quote from Shadow34370:
lorom  //Not sure what this does, but I think I've heard something about loroms and hiroms? Maybe header, no header?


Lorom is the mapping layout or data structure of the ROM itself. There's a topic somewhere on RHDN that discusses it in detail. Emulators usually tell you what type a game is when you start it up, Super Metroid is a fast LoROM.

Quote:
!value = #$7000  //Defining a variable named value with the value of 7000 in hex? I think the "#" means the number is a number and not an address, but how is 7000 a very small number (or fractional number), since the comment below says a whole number would be way too much damage.


These defines basically mean every time he uses "!value" in this document, Xkas will read it as "#$7000". You're right about "#" meaning a value and not an address, but we'll get to why it's small in a minute.

Quote:
!damage = $0A4E //Defines a new variable named damage, and according to the comment this variable holds the address in the rom that the damage(or "value" variable) value should be stored at.



You can't store stuff to ROM, $0A4E is a location in RAM. Let's look it up in Kejardon's RAM map.

7E:0A4E - 7E:0A4F    Deal damage to Samus (1/65536th)

Now you can see why "7000" is small. Because it's really $7000/$FFFF. What he meant by "whole number" was storing a value to 7E:0A50, which would do 65536 times more damage for the same number >_>

Quote:
org $9498B2  //Not really sure about this one, but it must the code to the right position in the rom or something.

    DW $B300 //Same as above.



org $94B300  //Don't know.

    LDA !value  //Okay, this must load the variable "value" into the processor.
    STA !damage //This must store what is in the processor (in this case the "value" variable) at the location of the "damage" variable.
    RTS //This piece returns the flow of the code back to wherever it branched off at. I don't see any JMP, or BRK command, so it must have something to do with those ORG commands.[/spoiler]


org is not a SNES command, but rather tells Xkas where exactly in the ROM to put the SNES commands. "org $94B300" means it's putting the code in bank 94 starting at B300.

LDA is used for loading a value into the A register, also called the accumulator. There are other registers, X and Y, but A is the one most commonly used.

STA Correct.

RTS is what you use to return from a JSR, which is basically a jump to data within the same bank. You don't see the JSR in the document, because the JSR already exists in the game's coding.
Where can I find a Binary Win version of Xkas and not a Dos version?
Edit history:
P.JMan: 2009-02-23 02:43:45 pm
I like Big Butts and I can not lie
Quote from Deep_Space_Observer:
Because it's really 7000/65536

You mean 28672/65536 (or 7/16)

Quote from Polo:
Where can I find a Binary Win version of Xkas and not a Dos version?

xkas isn't made for DOS
Edit history:
InsomniaDMX: 2009-02-23 05:48:46 pm
--Lawrence of Arrakis--
DSO: Everything very well said. I couldn't have put it any better.

Yeah, 28672/65536 is right, but that's the same as 7000/over 9000.




Polo: Like PJ said, it's not DOS. If you really dislike command line so much, make a batch file (that's what I do).

A batch file is just a text file with the extention ".bat", and the usage of xkas is
"xkas blahblahblah.asm blahblahblah.smc"

You can throw an "@pause" at the end to stop it from closing automatically, that way you can see if you've made any errors.

An example of a batch file I use to compile the boostball hack:
Code:
xkas ASM/boostball.asm ROM/SM.smc
Okay, one more question.

According to the comments in the file to add a new value to BTS 04 I would have to add some new code like the following.

org $9498B4

    DW $B400?? (Have no real clue about this one)

My question is how do you know that 9498B4 holds the info for BTS 04, and how do you know what to set DW to?
Its not that I don't like Command lines. I find them really comfortable to use most of the time.

It's just that when I try to run the program it closes immediately. aiwebs_008
--Lawrence of Arrakis--
Polo:

Add an "@pause" after everything.


Shadow:

DW is not a real instruction. It stands for Data Word (word, like the size of a variable), which simply changes the word at the current address to the operand specified. It's just a notation used by the compiler.

You could also use DB (data byte) DD (data doubleword) etc...


At the location, $94:98B4, is an entry of a jump table for the BTS value $04. Likewise, at $94:98B6, there's an entry for the BTS value $05. These entries are simply pointers. I used the DW to set a pointer for $94:B400, which is where my code is stored.

I hope that made sense.

Those DW and DD and such things are specific to xkas as far as I know. Other compilers might use that same notation, but I wouldn't count on it.
Hey I actually made a piece of ASM that works! I feel like I could rule the world.  Dancing
Couple more questions though.  Very Happy

I effectively made a Air Fool X-ray tile that works like a treadmill. I used this code.
Code:
!distance = #$7000
!move = $0B56

org $9498B4

	DW $B400

org $94B400

	LDA !distance
	STA !move
	RTS


Now this just moves Samus to the right, slowly. My question is how can a switch directions? At first I thought I would use 0B57 instead of 0B56, but that just makes Samus move extremely fast to the right. One other question. Is it possible to use negative numbers? That way I could use a negative number so instead of damaging Samus I could make areas that would heal her?

Thanks for all the help so far!
Edit history:
P.JMan: 2009-02-23 06:47:44 pm
I like Big Butts and I can not lie
For healing Samus, you'd just add a value to her health
Code:
LDA !subhealth ; this would be $0A4C
CLC           ; always used before ADC
ADC !subvalue  ; adds value to current subhealth
STA !subhealth
RTS

If you want to add whole units of energy:
LDA !health ; $09C2 for natural health
CLC
ADC !value
STA !health
CMP !maxhealth ; check that it's <= to max health
BCC OK ; skips to OK: if true
LDA !maxhealth
STA !health ; store max health to health, solving the problem
OK:
RTS


As for making her move left:
Code:
LDA !distance ; this would be $0B56
SEC           ; always used before SBC
SBC !value  ; subtracts value from distance
STA !distance
RTS
Maybe the question about healing Samus is answered, but when I seen this...
http://forum.metroid2002.com/index.php/topic,8006.msg247643.html#msg247643
And where it has the choices of damage and healing effect....  *shrugs*  Eh?

I guess...  Stay tuned.
--Lawrence of Arrakis--
Quote from Gaius_4:
Maybe the question about healing Samus is answered, but when I seen this...
http://forum.metroid2002.com/index.php/topic,8006.msg247643.html#msg247643
And where it has the choices of damage and healing effect....  *shrugs*  Eh?

I guess...  Stay tuned.


Those are radio buttons. So yeah, you won't be able to pick both...
He-he.  Damage OR Healing Effects.  Razz
Embarrasing Fact: Power suit made by lowest bidder
Quote from P.JMan:
For healing Samus, you'd just add a value to her health
Code:
LDA !subhealth ; this would be $0A4C
CLC           ; always used before ADC
ADC !subvalue  ; adds value to current subhealth
STA !subhealth
RTS

This would actually not quite work... and the reason why is actually something you learn in elementary school. >_<
You can kind of think of the accumulator as a single digit to a computer. We count 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, and then we run out of numbers and need a second digit to hold 10. The SNES can go 0 1 2 3 4 ... 65530 65531 65532 65533 65534 65535 and THEN it runs out of numbers and needs another 'digit' to go to 65536 (often it can only count up to 255 but usually it goes up to 65535. Look at the processor status register for more about this if you want).
When we add two numbers (let's say 6 and 7), we sometimes need more digits for the result than in either one number (13 is two digits). So what we do is say "6 + 7 is 3 + 10, I'll put 3 here and add one to the next higher digit". Computers can do exactly the same thing (and it's even still called carry). When the SNES adds two numbers together and the result is too big for it to handle, the carry bit is set and remains set until something clears it, and the next addition operation will result in a number that's actually one bigger than what you'd normally get (1 + 1 = 3, okay I can forget about carrying now ... OR ... 6 + 7 = 14, 4 goes here and I need to carry AGAIN).
Before I get TOO side-tracked, this ultimately means you need to add 0 to the next 'digit' of Samus's health. So even if you're going to stick to adding subhealth, you still need the code to add to the full unit health at the end of PJ's example:
Code:
LDA !health ; $09C2 for natural health
ADC #$0000 ; Note that we DON'T CLC before this addition!
CMP !maxhealth ; check that it's <= to max health
BCC OK ; skips to OK: if true
LDA !maxhealth ; If we're over the limit, go with the limit instead.
OK:
STA !health
RTS

Also I optimized it just because I'm obsessive like that. Slightly harder to understand though, but when you start doing a lot small tricks like that can be invaluable.
This is also why you have to CLC before starting every addition and SEC before every subtraction: The computer doesn't just forget about carrying because the last addition was a long time ago (or any of the other many operations that can change the carry bit), so you have to TELL it to forget about carrying. Also, the carry bit is also used to indicate if borrowing is needed: It's set if borrow is NOT needed, which is slightly counter-intuitive at first. Best I can suggest is to remember that 'Carry is NotBorrow' or 'Carry == !Borrow'. If that isn't enough of a headache yet, then learn about CMP and BCC: CMP stands for CoMPare accumulator, which effectively does 'Accumulator - argument' but doesn't actually put the result anywhere (SBC puts the result back in the accumulator). What it does do is keep track if borrow was required (set carry if it wasn't, clear it if it was), if the result was zero (set equal bit / zero bit if it was, clear the bit if it wasn't), if the result was negative (I'll explain this in a minute), and overflow (again in a minute) - which is also everything SBC (and ADC) does. BCC is Branch if Carry Clear, (branch basically means GoTo, but it uses relative addressing. Don't worry about relative addressing too much yet) and since Carry is NotBorrow, this could also be called 'Branch if Borrow Used', or 'Branch if Greater Than' (BGT, some assemblers WILL recognize this so you can use it instead of BCC, not sure about xkas though, I've never tried it).

Incidentally, this is kind of what is referred to when the processor 'size' is talked about. The SNES is a 16-bit processor, so it counts up to 65535. In the last few decades or so PCs have been 32-bit, so computers can count up to 4 million something. Now 64-bit computers are becoming common and can count up to some ridiculous number (whatever 2^64 - 1 is) with a single 'digit'. As kind of mentioned though, processors can often use smaller 'digits' when they want to; the SNES can switch between 8-bits (0-255) and 16-bits (0-65535).

Quote from P.JMan:
As for making her move left:
Code:
LDA !distance ; this would be $0B56
SEC           ; always used before SBC
SBC !value  ; subtracts value from distance
STA !distance
RTS

Again, this doesn't work because of the same thing. :<
Code:
LDA !distanceLow ; this would be $0B56
SEC           ; always used before SBC
SBC !value  ; subtracts value from distance
STA !distanceLow
LDA !distanceHigh ;$0B58 now
SBC #$0000
STA !distanceHigh
RTS


And since this is such a handy place to talk about it, Positive and Negative numbers. There isn't really a bit anywhere for numbers that especially says if they're positive or negative numbers, you just have numbers from 0 - 65535. But there's a certain quirk about counting like this you probably already realize: When you add 1 to 65535, you get 0. So you could kind of think of 65535 as -1, since -1 + 1 = 0. And then one less than 65535 is 65534, so let's call that -2. And so on down halfway through the available numbers. So we have -32768 (8000 in hex) that goes up to 0 (0000 in hex) and then up to 32767 (7FFF in hex).
Computers have been built especially to take advantage of this quirk, in which subtracting and adding numbers is the EXACT SAME THING (subtracting is nothing more than adding a negative number, and in this system a negative number is just a positive number interpreted differently). The highest bit is essentially the same as the sign of the number with this system (but keep in mind that -0001 is FFFF, not 8001), and thus the negative bit I mentioned so long ago is set to the same as the high bit of any result.
And now for the overflow bit. This is a really handy system, we can now work with negative numbers with ease, but there's still one last concern (Keep in mind all these numbers are hexadecimal): What if we add 5000 and 5000? We get A000, but the high bit is now set, so it's actually a negative number... -6000. We just added two positive numbers and got a negative result. The Overflow bit is set SPECIFICALLY when this happens, and also when we add two negative numbers and get a positive result, or do a subtraction that also doesn't make sense. If we do an addition or subtraction that DOES make sense, the overflow bit will be cleared instead.
One last useful tidbit of information you'll actually use very often: To switch a number from positive to negative (or vice verca, it works both ways), all you have to do is toggle all the bits, and then add 1. Or in assembly terms:
Code:
EOR #$FFFF ; Toggle all the bits in the accumulator
INC ; Add 1 (INCrement) the accumulator

So to loop this back to the previous example of moving Samus left, you could instead do this:
Code:
LDA !value
EOR #$FFFF
INC
STA !distanceLow
LDA #$FFFF
STA !distanceHigh

Remember that distance is really two digits, so if you just put the negative number (let's say Value is 0800, so -Value is F800) into Low, you'd have (0000 F800) or something, which is actually a positive distance: +F800. You'd want (FFFF F800) which is -800.

... I've apparently been in a bit of a tutorial mood today.
I like Big Butts and I can not lie
Bleh, I thought at the time that the subenergy and subposition was used the same way as the damage to Samus
OK, I've read over Kejardon's reply quite a few times now, and I think I've gained some understanding. I sat playing with the code for about 2 hours last night, but would have never figured out why it wasn't working. Now I got it working, and I am trying to apply to something I can actually use. I decided to try and create blocks that will give the player the illusion of a wind tunnel. In other words tiles the move Samus up from air blowing or some other force. I created a youtube video of my attempt. (Located below) My problem is that I wanted to make Samus's pose to change from just standing there to her "falling" pose. Obviously, it is harder than I thought. Here is my three different code attempts. Code is in spoiler.

Attempt 1:

Code:
;This code works exactly like it should as Kejardon explained it his previous post. I just use $0B5A, and $0B5C instead of $0B56, and
;$0B58
LDA !distanceLow
SEC 
SBC !value2
STA !distanceLow
	
LDA !distanceHigh
SBC #$0000
STA !distanceHigh
RTS


Attempt 2:
Code:
	
LDA !distanceLow
SEC 
SBC !value2
STA !distanceLow
	
LDA !distanceHigh
SBC #$0000
STA !distanceHigh

LDA !SamusValue  ;SamusValue = #$0001
STA !SamusPose  ;SamusPose = $0B37

;According to the RAMmap.txt if $0B37 = #$0001 than "Samus is moving up". I figured if I used that it would change Samus's pose,
;but that didn't do anything except to make the top of my BTS blocks "bouncing". (As shown in the video below)

RTS



Attempt 3:
Code:
LDA !distanceLow
SEC 
SBC !value2
STA !distanceLow
	
LDA !distanceHigh
SBC #$0000
STA !distanceHigh

LDA !SamusValue    ; SamusValue = #$002A
STA !SamusPose    ; SamusValue = $0A1C

;I was trying to just change Samus's pose manually to 2A, which according to Kejardon's TransitionTable.txt is "Falling facing left,
;normal pose". I don't think this is really how it was supposed to be applied though, because it crashes Samus as seen in the video.

RTS



Edit history:
P.JMan: 2009-02-24 04:07:16 pm
I like Big Butts and I can not lie
You'll want to try speed:
Code:
LDA #5; 5 seems like a reasonable speed
STA $0B2E
RTS


You'll want the speed to be constant while you're in the blocks, so you just write the same value every time (if not, do a small addition to vertical acceleration), it'll give you a small hop at the top too
*sigh* Okay, so I've confused myself.
Well, I know what I want to do, its doing it which is the problem.

XKas is going to be my assembler and I'm going to use notepad++ to edit the files, however, its the files I don't have. I gathered that I had to disassemble the rom in order to get the ASM files. I download a disassembler and disassembled, yet no files to be found. I open up the .smc in notepad++ wandering if it had been converted, it hadn't.

So, here are my questions:

What disassembler should I use?
Do I even need one?
Where would I find the files to edit?
Am I doing something incredibly wrong?
Is there some place which will tell me everything I need to know so I can stop bugging you guys so much? laugh new

I want to learn assembly so that I have no limitations in what I have to do. I'm skilled enough with smile as it is, but its just not enough for me. I must learn!
I like Big Butts and I can not lie
You might wanna try and find a SNES hacking tutorial, I never used one so I can't point you out to one, but yeah
Quote from P.JMan:
You'll want to try speed:
Code:
LDA #5; 5 seems like a reasonable speed
STA $0B2E
RTS


This is pretty much all I want, but is there a way to force Samus to start moving up without the player having to start the vertical momentum, and change her pose to the falling pose, so it looks more natural and not just standing on air. I just want to create the illusion that she is getting carried away by air blowing from underneath. Speaking of which. Is it difficult to create tiles that animate? For instance I created a tile shown below. Would it be difficult to make the fan (yellow and while things in the center) look like its spinning?

¯\_(ツ)_/¯
Based on #jzd conversations, animating tiles would apparently be extremely difficult and require a very in-depth knowledge of the way Super Metroid works. You might be able to create a new sprite for that, though, if you know what you're doing.
Edit history:
Shadow34370: 2009-02-27 07:10:58 pm
In the code I've been playing with it states that the information for air fool x-ray blocks with a BTS of 03 is located at $9498B2. How do you find where other information is located? Say... if I wanted to find where the information for Solid blocks with a BTS of 07 is at how would I find the right address to insert the code at? Also, what if I wanted to find the where the code is located for when Samus shinesparks, or the code that controls how gravity suit works?

Edit: (I pressed post than I thought of this.  laugh new) Is it possible to tell the game to run certain sounds while your are touching a block. For example: With my air tubes could I put in a piece of code that causes you to hear a sound while your touching one of the blocks?)
I have a new idea for an ASM hack, but I need to know how the "electrifying Samus in a save capsule" animation is called in the code. Does anyone know where the code that is ran whenever you load a game from a save capsule is located? Or how to display that animation in ASM?  Think
Embarrasing Fact: Power suit made by lowest bidder
I want to say the code that sets that up is in 91E00D, but I'm not entirely sure about that.
Hi  i was wondering where the asm address values that need to be changed are to prevent the screen from fading to black when going through a door