DocWaluigean wrote:
TIRE = 0
STR = 0
...
LDX #0
LDY #0
STX TIRE
STY STR
INC STR ; [[ INC X??? ]]
ldx #0 means load a value of 0 into the X index register. Same goes for
ldy #0 but into the Y index register.
stx TIRE means store (write) the current X index register value into the memory location represented by
TIRE. If
TIRE was declared as being equivalent to memory location $1234, then this would become
stx $1234 (in English: write value 0 to memory location $1234).
But in your code, you've said
TIRE = 0, which essentially means
TIRE = $00 or
TIRE = $0000 (there's of a difference between these two, sort of, but don't worry about that right now), so in this case the result would be
stx 0, which is the same as
stx $00 (in English: write value 0 to memory location $0000).
Same situation for
sty STR but with the Y index register, etc..
Then, in the same code, you also say
STR = 0. So now literally
TIRE and
STR both refer to memory location 0. This is probably not what you want (see below).
inc STR increments the value at memory location
STR by 1. So this is the same as
inc $00 basically. Under the hood, the CPU does the equivalent of "read value from memory location $00, increment it by one, write it back to memory location $00" (but without using a register). You could do the exact same yourself in code by doing something like:
lda STR clc adc #1 sta STR.
I believe when you wrote
TIRE = 0 and
STR = 0, you were thinking "how can I pre-assign a value of a variable", because that's what other programming languages let you do -- they hide what goes on under the hood, instructions that are generated internally by the compiler or interpreter. In assembly language, these are called
EQUates, which is why you can say something like
TIRE = 0 or
TIRE EQU 0 -- they mean the same thing. Equates are only expanded at
assemble time, not at run-time. Understanding the difference is important!
Equates can be used in many different ways, not just as "memory locations". They can be used as literal values, or even pre-calculated values. I'll give an example below.
It just so happens that on the NES, memory location $00 happens to be RAM (in fact, it's something called zero page, but that's still advanced so ignore that for now).
RAM on the NES ranges from memory locations $0000 to $07FF (so that's 2KBytes).
If you wanted to give all of your variables their own unique memory locations, you'd do something like this:
Code: Select all
TIRE = $00 ; Memory location $00
STR = $01 ; Memory location $01
MAN = $02 ; Memory location $02
SNAKE = MAN+1 ; Memory location $03
; Initialise all the above variables to 0
lda #0
sta TIRE
sta STR
sta MAN
sta SNAKE
; Increment MAN by 1 (MAN now contains value 1)
inc MAN
; Load the literal address of SNAKE into the accumulator, i.e. lda #$03
lda #SNAKE
The last line will probably confuse you. Note the
# (hash mark). It indicates what's called an "immediate value" (a.k.a. literal value). This is how you tell the assembler what kind of access method to use, a.k.a. addressing mode. Here's a better way to demonstrate it with regards to what I said. Note the difference between the
lda lines:
Code: Select all
MYVAR = $1e
lda MYVAR ; Load the contents of memory location $1E into the accumulator (i.e. A = whatever memory location $1e contains)
lda #MYVAR ; Load literal value $1e into the accumulator (i.e. A = $1e)
These literally become the following lines:
...and as such, the assembler assembles these into two completely different results:
lda $1e assembles into bytes
a5 1e, while
lda #$1e assembles into bytes
a9 1e. See the difference? The instructions are identical (
lda), but the opcodes (due to addressing modes) differ. The former addressing mode is called "zero page addressing", while the latter is called "immediate addressing". That's how the CPU knows what to do with each subsequent byte (operand).
That's probably enough for one day. Real-time comparisons are a whole other subject (e.g. trying to do
if HEALTH == TIRE, but in 6502). I think understanding the above is more important, as well as understanding addressing modes (there are several, and many limitations! Some instructions can only use certain addressing modes or certain registers, for example).
Edit: lots of them.