News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

SM ASM question

Started by TobiMikami, September 02, 2014, 07:39:28 PM

Previous topic - Next topic

TobiMikami

So, I know it's possible to set a say, Super Missile door with an index of just for an example, 01, if a perma-shut door is set to index 01, it will open when the Super Missile door is opened, my question is, can this function be replicated in ASM? The idea I have in mind would involve when Samus touches said block, it would trigger the same event as the door being opened, I'm assuming it would be a matter of LDA the door index, then STA it at the location in RAM where the data would be if the door was opened? Is that possible?

Jordan5

Yes, i do think it is possible. You should browse through the RAM Map to find the location of set door bits. I'm not sure how the bits work so it may not be as simple as storing a value, but rather adding to a value, like how current items are stored? I don't really know enough to say.

You could, however, go the route of Mockingbird Station and having door cap PLMs at the end of a room with the same index as a grey door so when the player opens the door cap it unlocks the door - this would hint to the player that they've unlocked something rather than a random block.

Or you could make a key PLM and use the item events patch to alter the room state in the room with the locked door to a state where there is no grey door PLM.

TobiMikami

Thanks for the advice, I figured it would be useful in the sense of like in Prime where they have a spot you morph ball into and a door opens, mainly just a space drawn up into the floor that you would morph roll into in like a duct or something that would trip an ASM to open the door above, however, the idea of a PLM also serves just as good of a purpose, so thank you very much!

personitis

Indeed it is and you've the correct idea behind it as well. You should note though, that I don't believe the door will "open" if it is located in the same room as the BTS that activates its index. You should fine this address from the RAM map very useful aswell:
7E:D8B0 - 7E:D8EF    Opened door bit array. D0-EF are never used
I like the idea of a PLM better myself as, like I've said before (I think?), it's more of a universal and flexible solution. I myself haven't dove into writing PLMs, but if you do, more power to ya!

I may also note that you'll find the above linked RAM map more useful than the one Jordan linked as it's more up to date, though not recent.

TobiMikami

I had noticed that bit when I did a search through Kej's RAM map, I just didn't know if it was set up like Samus's energy where it was a matter of adding a set of data to another set of data, or if it was like Items where it's an on or off bit that has to be changed on with an ORA function, thank you to both of you, much help c:

P.JBoy

Let's not forget that you can use a pick up to unlock a door by setting its high to 02.

If you do want to make a new PLM to do it, you can unlock the door with:

LDA.W #${DoorIndex}+$480
JSL $8081FA


If you want the door to unlock instantly (and start flashing), I think this will work (in bank $84):

LDX.W #${DoorIndex}*2
JSR $BDB2

personitis

Yes Tobi, the door bit array is bits. There shouldn't be any issue if you were to load/store values like 02, A0, 7B, and such.

TobiMikami

So I wrote this code and it runs through Xkas fine, but in game it freezes whenever Samus touches anything, is this a quickmet thing or is there something wrong with the code? If someone could let me know if there's an error with it, it would be much obliged.
lorom
;Defines:

!value = $0001
!damage = $0A4E

org $9498B2

DW $B300

org $94B300

LDA $09A2 ;checks, if gravity suit is equipped
AND #$0020
CMP #$0020
BNE nogravitysuit ;does damage if true
RTS

nogravitysuit:
LDA !value
CLC
ADC !damage
RTS

Quote58

#8
you're loading an address for 'value'. Idk what's at $7E0001, but it's probably not what you want.
Add a # to make 'value' an actual value
Also AND #$0020 : CMP #$0020 does not need to be a thing. Use this instead:
LDA $09A2 : BIT #$0020 : BEQ nogravitysuit : RTS

Edit: Actually $7E0001 is in direct page memory (which can be loaded with LDA $01 instead btw), and since the value in that address is not consistent across routines, you could get some bad results (like that crashing you mentioned).

P.JBoy

Whilst we're talking about optimisations, you could even change the branch destination to bring the code size down to this:

lorom
;Defines:

!value = 1
!damage = $0A4E

org $9498B2
DW $B300

org $94B300
LDA $09A2 ; checks, if gravity suit is equipped
BIT #$0020
BEQ nogravitysuit ; does damage if true
LDA #0000 + !value
CLC
ADC !damage

nogravitysuit:
RTS


I do like to make sure to do that sort of thing with immediates to make sure xkas assembles correctly

JAM

#10
Quote from: Quote58 on September 07, 2014, 10:36:09 PM
you're loading an address for 'value'. Idk what's at $7E0001, but it's probably not what you want.
Add a # to make 'value' an actual value
That's why I prefer to work in pure hex. I forgot to add # where necessary several times, but I wrote A9 instead of AD only once.


And I'll optimize this a bit more.


lorom
;Defines:

!damage = $0A4E

org $9498B2
DW $B300

org $94B300
LDA $09A2 ; checks, if gravity suit is equipped
BIT #$0020
BEQ nogravitysuit ; does damage if true
INC !damage

nogravitysuit:
RTS


Because there is no reason to use ADC for adding a 1.

Quote58

That's what I was originally going to do, but I thought he may have a reason for adding a specific amount (possibly having it change based on other factors and such).

Quote from: JAM on September 09, 2014, 07:17:37 PM
That's why I prefer to work in pure hex.

Oh Jam, I'll never understand you and you're hex only coding :P (does this mean you never write comments??)

JAM

Quote from: Quote58 on September 09, 2014, 08:28:45 PM
Quote from: JAM on September 09, 2014, 07:17:37 PM
That's why I prefer to work in pure hex.

Oh Jam, I'll never understand you and you're hex only coding :P
It have an advances sometimes. For example, I used the byte "60" twice. As RTS for a code and as beginning of array. Something like that:

9C DF 07 60 01 40 01 20 01 00 01 E0 00 ...



(does this mean you never write comments??)
[/quote]

Sometimes I do... =)

This is most angry one I put to SMILE. =)

When making ASM files too (which I'm work on rare -- when the code is too big, complex or repeating).

TobiMikami

How exactly would I go about making a routine run when a button was pressed? Like if you pressed whatever your emulator was representing as the A button it would make whatever the code is happen.

Smiley

You choose a suitable hijack point and then write code that checks button input, then branches accordingly. For pressing A, you could do, for example:
LDA $8B
BIT #$0080
BNE PressingA
RTS

PressingA:
Whatever

This document by Grime has a bunch of breakpoints you can use. If nothing else works, you can always hijack the main game loop, but you shouldn't do so too much.

Jordan5

i guess it would involve checking the ram for controller input.


LDA $4218        ;load controller input
BIT #$0080       ;check if A button is pressed
BNE ROUTINE      ;If A is pressed, jump to subroutine 'ROUTINE'
RTS

ROUTINE:


You could either check for which button (A, X etc.) or check for the action of that button (run, jump etc.) - my example is for the button on a controller. I think that's right, you'll just have to find a highjack point for this code, it depends if you want it to be run every frame or just during specific times or whatever. I hope this helps a bit :^_^:

Oh, here's the controller input stuff so you know what to check for what button you want.

EDIT: Smiley beat me to it, and that document is pretty handy, i'll have to use that sometime :grin: