2

I am currently working on a NES(6502) assembly game but I don't understand how to make a sprite move. Here's how I think its supposed to works:

(loop)
LDA $200 ;will load into the A register the content of address $200,wich contain the Y position of my sprite
INA ;Increment the A register which would increment the content of A which is the Y position of my sprite..?

However it seems that you cannot increment the A register accumulator because I get an error when trying to assemble with the INA instruction. So I'm a bit lost into that. Should I use STA instead of LDA? But I want to use the content of the address $200 and not place a value that I choose in it. I don't get how to make my sprite move.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
J.Wilson
  • 51
  • 7
  • 1
    Incrementing a register means adding one to it. There's no increment A instruction, but there is an add to A instruction. You could also use the X or Y registers for which there are increment instructions for. – Ross Ridge Oct 19 '15 at 19:42
  • You can *INC* a memory address directly, e.g. `INC $0200.` – LawrenceC Dec 13 '16 at 19:15

3 Answers3

5

There's indeed no INA available on the variant of 6502 used in the NES. You can increment A by 1 using the following pair of instructions:

CLC     ; Clear carry
ADC #1  ; A = A + 1 + carry = A + 1

Or, if either of the index registers are free you can use:

LDX $200  ; or LDY
INX       ; or INY

Keep in mind, though, that the other arithmetic operations like ADC, SBC, LSR, etc, can't be performed on X or Y.

Michael
  • 57,169
  • 9
  • 80
  • 125
  • Don't forget you have to store it back with ```STX $200``` if you do this. ```INC $0200``` is probably an easier way. – puppydrum64 Jul 22 '22 at 13:24
4

If the graphics chip looks for the sprite position in $200, then you will need to write back the modified value after computing it. If all you want to do is increment it, you can do it directly by using the absolute addressing mode of INC:

INC $200

will increment whatever value is stored in $200, without changing any of the register values.

Cactus
  • 27,075
  • 9
  • 69
  • 149
  • well I want to make my sprite move, so yes I need to change it/write it back in the register so it moves(I didnt thought about that).Im not quite sure on how to do that though?thank you – J.Wilson Oct 21 '15 at 22:46
  • If you use `INC $200`, it happens in-place: the current value of $200 is read, and one more (mod 256) is written back to $200, so you're done. If you load it to A, then after modifying it, you have to write it back to $200 using `STA`, so your code will be: `LDA $200; compute new value in A; STA $200`. – Cactus Oct 22 '15 at 07:24
  • Thanks for your answer.I dont know whats wrong. I tried that and still nothing moves.The sprite Y position are always wrote at $200 address right?I dont get why it doesnt increment it and make it move.Im writing the code in the "NMI:" part – J.Wilson Oct 22 '15 at 21:46
  • I think you're using the wrong memory address -- according to [this memory map](https://en.wikibooks.org/wiki/NES_Programming#NES_2A03_CPU_memory_map), $200 is squarely in normal CPU RAM. Maybe you need to look around [$2000](https://en.wikibooks.org/wiki/NES_Programming#PPU)? – Cactus Oct 23 '15 at 01:46
  • I should add that I've never programmed a NES so the above is based on just a cursory glance through the NES dev wikibook. – Cactus Oct 23 '15 at 01:47
  • 1
    @Cactus The sprite cache needs to be in normal RAM, so that its high byte can be fed to the DMA controller which will go to the address with that high byte and copy the page to the PPU. So `$0200` is correct assuming that in NMI the code stores `#$02` to `OAMADDR` (or wherever it goes, I can't remember the exact register) – puppydrum64 Feb 06 '23 at 15:43
2

Keep in mind that usually games don't directly edit sprites. The common way of updating sprite position is first updating the object's position and then use a sprite constructor subroutine to assemble each 8x8 sprite to the correct position relative to the object's position. You can have a table to list all sprites. The list specifies the tile and relative offset for that sprite so you can just add it to the object position to get the position of the sprite you write to the next free OAM slot.

Then at the start of NMI you use OAMDMA to copy the "shadow OAM" (usually on page 2) to the PPU. Games don't generally use OAMADDR and OAMDATA as they are likely to corrupt OAM data.

NMITIMEN
  • 75
  • 1
  • 7