How to create variable with ASM6?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

How to create variable with ASM6?

Post by MartsINY »

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?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to create variable with ASM6?

Post by tokumaru »

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.
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

Re: How to create variable with ASM6?

Post by MartsINY »

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?
User avatar
pubby
Posts: 583
Joined: Thu Mar 31, 2016 11:15 am

Re: How to create variable with ASM6?

Post by pubby »

Variables are defined for addresses only. They aren't for the addressing mode (the ", x" part).

Like this:

Code: Select all

actionCounter = $0468

LDA actionCounter, x
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

Re: How to create variable with ASM6?

Post by MartsINY »

thank you!! much appreciated!!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to create variable with ASM6?

Post by tokumaru »

Just don't include the index register in the variable definition:

Code: Select all

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:

Code: Select all

.enum $0400
  healthPoints .dsb 1
  frameCounter .dsb 2
  actionCounter .dsb 1
.ende
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.
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

Re: How to create variable with ASM6?

Post by MartsINY »

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
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to create variable with ASM6?

Post by tokumaru »

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.
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

How to write in an existing file at specific addresses?

Post by MartsINY »

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?
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: How to create variable with ASM6?

Post by Dwedit »

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.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
MartsINY
Posts: 66
Joined: Sun Jun 11, 2017 5:39 pm

Re: How to create variable with ASM6?

Post by MartsINY »

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.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to create variable with ASM6?

Post by tokumaru »

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:

Code: Select all

  .incbin "before.bin"
  .org $8367 ;this is where your code will be mapped in CPU space
  ;NEW CODE HERE
  .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.
Post Reply