This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

How to create variable with ASM6?

How to create variable with ASM6?
by on (#197979)
I'd like to do something like this:

actionCounter = $0468,X

so I can do

LDA actionCounter

which will be equivalent to LDA $0468,X

Is there a way to do this?
Re: How to create variable with ASM6?
by on (#197981)
I'm pretty sure ASM6 can't do that (ca65 could, using .define), but why would you want to include the index register in the variable like that? That'd make your code horrible to follow!

If you want to hide operations like that (for whatever reason), it would maybe be better to use macros, where you can optionally manage the value of X as well and make the behavior more consistent.
Re: How to create variable with ASM6?
by on (#197982)
thanks for your really quick answer!!

I would like to do this to work with variable instead of hex address, so it's simple to understand what is going on.

But then what is a variable? I though this was it?
Re: How to create variable with ASM6?
by on (#197985)
Variables are defined for addresses only. They aren't for the addressing mode (the ", x" part).

Like this:
actionCounter = $0468

LDA actionCounter, x
Re: How to create variable with ASM6?
by on (#197987)
thank you!! much appreciated!!
Re: How to create variable with ASM6?
by on (#197988)
Just don't include the index register in the variable definition:

actionCounter = $0468

;so you can do:

LDA actionCounter, X

Indexing is something you do when using the variable, not when declaring it.

But even then, using hardcoded addresses is not advisable because rearranging variables at a later time is time consuming and error-prone (accidental overlaps and stuff like that). The best practice is to start defining variables from a base address and reserve space for each variable:

.enum $0400
  healthPoints .dsb 1
  frameCounter .dsb 2
  actionCounter .dsb 1

This will result in:
healthPoints = $0400
frameCounter = $0401
actionCounter = $0403

And you can easily move the definitions around without having to change any numbers manually or worrying about overlaps.
Re: How to create variable with ASM6?
by on (#197990)
wow!! thanks a lot again!! this is really well explained!!

however for now I'm modifying an ASM for a boss in MM4, so I guess the first way you showed would be the best?

I will also post another question, which maybe you will know. I'll post it in few minutes on the same forum, then I'll be able to complete the ASM
Re: How to create variable with ASM6?
by on (#197992)
Ah, if this is just a patch/hack then yeah, simply using the hardcoded value is OK, since you'll probably only going to use a few variables. A full disassembly would benefit from the method of reserving space though, so it's modifiable.
How to write in an existing file at specific addresses?
by on (#198133)
I have my ASM I created for a boss in a ROM.

I would need to write it directly in a ROM (megaman4.nes) at adress 76030

how can I do this?
Re: How to create variable with ASM6?
by on (#198136)
You use incbin tricks to patch existing roms with ASM6.

I posed an example for Contra in a thread 5 years ago.

You will need to stop thinking in terms of ROM file address, and start thinking in terms of actual memory address and bank number of your rom code.
MMC3 uses 8k banks rather than MMC1's 16k banks.
Address 0x76030 would be in bank # 0x3B, and 0x20 bytes within that page.
Game appears to treat the last 16K as if it's a fixed bank, so the code you're modifying could be either mapped to bank 8000 or A000. Probably bank A000. If your new code is position independent (ie. no JSR or JMP into the bank), it won't even matter.

edit: that ROM area isn't blank.
Re: How to create variable with ASM6?
by on (#198139)
thanks for quick reply!!! still have a lot to learn, I though bank where attributed by ROM, didn't know they were proper to MMC stuff.
Re: How to create variable with ASM6?
by on (#198146)
The NES itself has no concept of banks, it just sees a linear 32KB area for PRG and a linear 8KB area for CHR. It's the mapper that decides how to break up that space into banks.

Anyway, one way to patch an existing ROM is to use an hex editor to copy the newly assembled code and paste it at the correct position in the ROM file (be careful to overwrite the old contents, because inserting the data and expanding the ROM would result in an invalid file).

Copying and pasting is not such a good idea if you have to do it repeatedly though, which might be the case when you're writing/debugging the new code. One way to do it would be to write a tool that can patch files like this, if one doesn't already exist. Another option is to open the original ROM in an hex editor and create 2 new files from it: one with everything that comes before the new code, and another with everything that comes after. Then you can just combine the 3 files using the command prompt (newcode.bin must be an exact size in order to not affect the final size of the ROM, so you might need to pad it):

copy /b before.bin + newcode.bin + after.bin rom.nes

Or you could also .incbin the two file inside the source code for the new code, like this:

  .incbin "before.bin"
  .org $8367 ;this is where your code will be mapped in CPU space
  .org $850B ;this is as far as your code can go without expanding the ROM
  .incbin "after.bin"

Just some ideas to complement what Dwedit said, but I like his method better because it's more versatile and doesn't need temporary files.