Hello, I'm back, still need assistences

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

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

Re: Hello, I'm back, still need assistences

Post by tokumaru »

DocWaluigean wrote: Wed Jun 10, 2020 4:52 pmTXY Transfer numbers from Register X into Register Y. ??? I do not see this opcode in the Documnentations.
Yeah, it doesn't exist. You can do this through a temporary variable, though:

Code: Select all

stx temp
ldy temp
Or trough the accumulator, if you're not using it for anything else:

Code: Select all

txa
tay
ADC Adds number into Register A. If overflow, Carry Flag turns on and adds 1 more extra into Register A.
The way you're wording this still sounds confusing to me, like the "add one extra" happens right away, which's not the case.
BCS Jump to specific label or Address ONLY IF the Carry Flag is 1 or on. [The question is, how does Carry Flag turn on? Does it turn on if overflow in Register? Or overflow in Address? or overflow in ANYTHING??]
It turns on in various situations (read the documentation to see which instructions affect the carry flag and how), but as far as BCS is concerned, it doesn't matter at all. If C is set, the branch will happen, regardless of what caused C to be set.
BEQ Jumps to specific label or Address ONLY IF the Zero Flag is 1 or on.
BNE Jumps to specific label or Address ONLY IF the Zero Flag is 0 or off.
[Another question is. What type of actions need. If the Zero Flag turns on? or if the Zero Flag IS on while the code reaches this destination?]
Branch instructions test the flags BEFORE jumping, in order to decide whether to jump or not. They don't change the state of the flags though, so if a flag is on BEFORE the jump, it will remain on AFTER the jump.
SBC Subtracts number from Register A. The polar opposite of ADC.
[This one is different. If it goes below the 0 and Carry Flag is set to zero, does it turn on Negative Flag?
It does set the N flag, but this is a bit tricky. For example: $02 - $85 = $7D. You'd think that $85 (decimal 133) is larger than $02 (decimal 2), causing the result to be negative. However, the N flag is supposed to be used in the context of signed numbers, and if you interpret $85 as signed, it actually means decimal -123, instead of 133. As we learned in school, two minus signs become a plus, so 2 - (-123) equals 125, which's a positive number, so the N flag is in fact clear after this operation. This whole unsigned vs. signed thing can be a bit complicated, so I wouldn't worry too much about it at this point. You can code entire games for the NES without ever using signed numbers, so really, don't waste any time focusing on that for now.
FOR ALL THE FLAGS, would the opcode triggers IF the flag turns on/off or WHILE the flag is on/off? I'm guessing that it's an "Is, and while" the flag is on/off, the opcode executes.
Branch instructions simply check the current state of the flags at the moment when they execute. It doesn't matter what happened before or what will happen after, only the current state of the flags matters.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

DocWaluigean wrote: Wed Jun 10, 2020 5:22 pmBut the CPU calculates the target addresses by reading from top to bottom, no?
Programs do execute from top to bottom, yes, but I don't know what you mean by "calculates the target address".
STX Temp - Store #### from Register X into an Address ,labelled "Temp", that's specialty for RAM.

CMP Temp - ????????????? Compare the number from Register A to Register X.
Even though what you wrote is in fact what's happening, it looks wrong to say that CMP is comparing A to X, because that's not really what CMP does. To avoid this kind of confusion, you can simply change the way you're writing the comment, so that the comment explains and entire block of instructions instead of each individual instruction:

Code: Select all

;compare A to X
stx temp
cmp temp
Then it doesn't look wrong anymore, since that's in fact what the 2 instructions TOGETHER are doing. Most programmers don't comment every single line of code anyway... comments explaining the overall purpose of groups of instructions are much more useful, and you can still use line by line comments if you feel like specific steps in the sequence need clarification. Don't waste time writing comments like CLC ;clear the carry flag though... this is obvious from the documentation, there's no point in repeating that over and over in your own program.
BNE Label - If the Zero Flag is set to Zero, then jump to Label.
Correct, only the wording is weird. since "set" is synonymous with "1", the expression "set to zero" can sound a bit confusing. I'd avoid writing it like that.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, I'm back, still need assistences

Post by DocWaluigean »

tokumaru wrote: Wed Jun 10, 2020 5:26 pm
DocWaluigean wrote: Wed Jun 10, 2020 4:52 pmTXY Transfer numbers from Register X into Register Y. ??? I do not see this opcode in the Documnentations.
Yeah, it doesn't exist. You can do this through a temporary variable, though:

Code: Select all

stx temp
ldy temp
Or trough the accumulator, if you're not using it for anything else:

Code: Select all

txa
tay
ADC Adds number into Register A. If overflow, Carry Flag turns on and adds 1 more extra into Register A.
The way you're wording this still sounds confusing to me, like the "add one extra" happens right away, which's not the case.
BCS Jump to specific label or Address ONLY IF the Carry Flag is 1 or on. [The question is, how does Carry Flag turn on? Does it turn on if overflow in Register? Or overflow in Address? or overflow in ANYTHING??]
It turns on in various situations (read the documentation to see which instructions affect the carry flag and how), but as far as BCS is concerned, it doesn't matter at all. If C is set, the branch will happen, regardless of what caused C to be set.
BEQ Jumps to specific label or Address ONLY IF the Zero Flag is 1 or on.
BNE Jumps to specific label or Address ONLY IF the Zero Flag is 0 or off.
[Another question is. What type of actions need. If the Zero Flag turns on? or if the Zero Flag IS on while the code reaches this destination?]
Branch instructions test the flags BEFORE jumping, in order to decide whether to jump or not. They don't change the state of the flags though, so if a flag is on BEFORE the jump, it will remain on AFTER the jump.
SBC Subtracts number from Register A. The polar opposite of ADC.
[This one is different. If it goes below the 0 and Carry Flag is set to zero, does it turn on Negative Flag?
It does set the N flag, but this is a bit tricky. For example: $02 - $85 = $7D. You'd think that $85 (decimal 133) is larger than $02 (decimal 2), causing the result to be negative. However, the N flag is supposed to be used in the context of signed numbers, and if you interpret $85 as signed, it actually means decimal -123, instead of 133. As we learned in school, two minus signs become a plus, so 2 - (-123) equals 125, which's a positive number, so the N flag is in fact clear after this operation. This whole unsigned vs. signed thing can be a bit complicated, so I wouldn't worry too much about it at this point. You can code entire games for the NES without ever using signed numbers, so really, don't waste any time focusing on that for now.
FOR ALL THE FLAGS, would the opcode triggers IF the flag turns on/off or WHILE the flag is on/off? I'm guessing that it's an "Is, and while" the flag is on/off, the opcode executes.
Branch instructions simply check the current state of the flags at the moment when they execute. It doesn't matter what happened before or what will happen after, only the current state of the flags matters.
The way you're wording this still sounds confusing to me, like the "add one extra" happens right away, which's not the case.
I mean like, If the Carry Flag is on because of overflow, it will always add 1 extra to the A Register.

C = 0
A = #$50
ADC #$20
=
A = #$70

And this one with Flag

C = 1
A = #$25
ADC #20
=
[EITHER]
A = #$46
[OR/AND]
$#### = #$46

---
"It turns on in various situations (read the documentation to see which instructions affect the carry flag and how), but as far as BCS is concerned, it doesn't matter at all. If C is set, the branch will happen, regardless of what caused C to be set."
Oooh, so it's a WHILE C = 0/1 stuff.

---
Branch instructions test the flags BEFORE jumping, in order to decide whether to jump or not. They don't change the state of the flags though, so if a flag is on BEFORE the jump, it will remain on AFTER the jum
p.

So it's a WHILE mode, not IF mode. And the flag stays on/off like that.

---
It does set the N flag, but this is a bit tricky. For example: $02 - $85 = $7D. You'd think that $85 (decimal 133) is larger than $02 (decimal 2), causing the result to be negative. However, the N flag is supposed to be used in the context of signed numbers, and if you interpret $85 as signed, it actually means decimal -123, instead of 133. As we learned in school, two minus signs become a plus, so 2 - (-123) equals 125, which's a positive number, so the N flag is in fact clear after this operation. This whole unsigned vs. signed thing can be a bit complicated, so I wouldn't worry too much about it at this point. You can code entire games for the NES without ever using signed numbers, so really, don't waste any time focusing on that for now.
That's some what good to know not to worry about it. But I want to learn EVERYTHING and missing out details like this could mean lost opportunity to do something so amazing, and loosing opportunity to teach NES stuff that even Kindergarten would understand so greatly about N Flag...
Branch instructions simply check the current state of the flags at the moment when they execute. It doesn't matter what happened before or what will happen after, only the current state of the flags matters.
I understand, and it's a WHILE mode. "While the Flag is On..." "While the Flag is Off.." stuff. Alongside, I'm guessing the Flag on/off is permanent!


================================================================================================================

Programs do execute from top to bottom, yes, but I don't know what you mean by "calculates the target address".
About what you said about this?
"we don't have to concern ourselves with how the CPU calculates the target address."
Even though what you wrote is in fact what's happening, it looks wrong to say that CMP is comparing A to X, because that's not really what CMP does. To avoid this kind of confusion, you can simply change the way you're writing the comment, so that the comment explains and entire block of instructions instead of each individual instruction:
CODE: SELECT ALL

;compare A to X
stx temp
cmp temp
Then it doesn't look wrong anymore, since that's in fact what the 2 instructions TOGETHER are doing. Most programmers don't comment every single line of code anyway... comments explaining the overall purpose of groups of instructions are much more useful, and you can still use line by line comments if you feel like specific steps in the sequence need clarification. Don't waste time writing comments like CLC ;clear the carry flag though... this is obvious from the documentation, there's no point in repeating that over and over in your own program.

This one seems challenging. :? I'm going to write the CMP part.
BNE Label - If the Zero Flag is set to Zero, then jump to Label.
Correct, only the wording is weird. since "set" is synonymous with "1", the expression "set to zero" can sound a bit confusing. I'd avoid writing it like that.
It's beautiful to know that if I'm right about this, I'm finally learning something. Also, it's a curse of my vocabulary. I can't explain well or beautifully or stuff like that.
Sometimes "set" could mean a lot of words like "Setting up the PC" this and "Ready, Set, Go!" that.

=================================================================================================================
Anyway, writing this after I saw those new comments:

So I'm guessing CMP is one of the MOST trickiest opcodes out there?
The cmp instruction sets up the flags such that the following instructions (which replace b?? above) do the following:

For bcc (branch if carry clear): Jump if the value at address firstVar is less than the value at secondVar as an unsigned number
For bcs (branch if carry set): Jump if the value at address firstVar is greater than or equal to the value at secondVar as an unsigned number
For bne (branch if not equal): Jump if the value at address firstVar is not equal to the value at secondVar
For beq (branch if not equal): Jump if the value at address firstVar is not equal to the value at secondVar
For bpl (branch if plus): Jump if the value at address firstVar is greater than or equal to the value at secondVar as a signed number
For bmi (branch if minus): Jump if the value at address firstVar is less than the value at secondVar as a signed number
So if CMP is used, all 6 of these opcodes we know temporary transformed into these kind for one code after CMP???????

Re-reading your words, CMP is can only be used by A-Register FIRST before X/Y/S?
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: Hello, I'm back, still need assistences

Post by Garth »

I think "if" is a better term than "while." "While" implies a condition that persists, usually in a loop, where you continue looping and looping until that condition ends. The C flag may be changing many, many times in that loop though, and the branch only sees if it's set at the moment the conditional branch instruction is executed, which is a narrow time frame.

CMP takes the accumulator's value minus whatever the operand and addressing mode specify; but unlike SBC, it starts with an implied SEC, and does not keep the numerical result, only the flags result. If you want to do this with X or Y instead of A, use CPX or CPY. (In that sense, you can subtract using X or Y, not just A.) You can do the conditional branches with all of these, because as tokumaru said, the conditional-branch instructions don't care how the status of a flag was reached, or which registers or instructions were used in the process.

The term "overflow" is not very appropriate for referring to the Carry flag. The overflow flag is separate, and has a different function, namely that in signed numbers, it's telling you that bit 7 does not correctly tell you the sign. For example, $70+$70=$E0, or 11010000B. Since $70 is positive, adding it to itself would also produce a positive result; but with the high bit set, it appears to be negative, which is incorrect. The V (oVerflow) flag tells you that. Note that there was no carry; but the result overflowed the range of positive numbers. The same goes for negative numbers.
http://WilsonMinesCo.com/ lots of 6502 resources
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, I'm back, still need assistences

Post by DocWaluigean »

Garth wrote: Thu Jun 11, 2020 2:15 pm I think "if" is a better term than "while." "While" implies a condition that persists, usually in a loop, where you continue looping and looping until that condition ends. The C flag may be changing many, many times in that loop though, and the branch only sees if it's set at the moment the conditional branch instruction is executed, which is a narrow time frame.

CMP takes the accumulator's value minus whatever the operand and addressing mode specify; but unlike SBC, it starts with an implied SEC, and does not keep the numerical result, only the flags result. If you want to do this with X or Y instead of A, use CPX or CPY. (In that sense, you can subtract using X or Y, not just A.) You can do the conditional branches with all of these, because as tokumaru said, the conditional-branch instructions don't care how the status of a flag was reached, or which registers or instructions were used in the process.

The term "overflow" is not very appropriate for referring to the Carry flag. The overflow flag is separate, and has a different function, namely that in signed numbers, it's telling you that bit 7 does not correctly tell you the sign. For example, $70+$70=$E0, or 11010000B. Since $70 is positive, adding it to itself would also produce a positive result; but with the high bit set, it appears to be negative, which is incorrect. The V (oVerflow) flag tells you that. Note that there was no carry; but the result overflowed the range of positive numbers. The same goes for negative numbers.
Hmmm. You do have a point. It may take me a while to adapt the term changes for this..

Now this got confusing. How do I know if I'm comparing X with A or Y? Do I have to load Register or Store Address...???

LDA #20
LDX #10
STX $10
CMP $10

It's now comparing Register A with Register X? With STX, it's now carrying Zero since it "drops" the number into the Address $0010? Or it just "copy and paste" X Register $10 into Address $0010? I could read my previous post, but every question needs to be understand.

So if the addition overflows, the V Flag turns on ALONG with the Carry Flag?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

DocWaluigean wrote: Thu Jun 11, 2020 3:47 pmLDA #20
LDX #10
STX $10
CMP $10

It's now comparing Register A with Register X?
I think you just have to be more careful with how you word things, because even though the final effect is that you're in fact comparing A to X, the accurate thing to say here is that you're comparing the value in A to a copy you've made of the value in X.
With STX, it's now carrying Zero since it "drops" the number into the Address $0010? Or it just "copy and paste" X Register $10 into Address $0010?
Storing doesn't alter the value in the register. When you do STX $10 the same number is now in X and in memory address $10. The same is true for the "transfer" instructions: TAX doesn't remove the value in A, it copies the value in A to X, since you're not accessing X itself with the CMP instruction, just a copy you made of it.
So if the addition overflows, the V Flag turns on ALONG with the Carry Flag?
Those flags work independently from each other. The carry flag signals unsigned overflows and underflows (results larger than 255 or smaller than 0), while the V flag signals signed overflows and underflows (results larger than 127 or smaller than -128).
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, I'm back, still need assistences

Post by DocWaluigean »

tokumaru wrote: Thu Jun 11, 2020 4:06 pm
DocWaluigean wrote: Thu Jun 11, 2020 3:47 pmLDA #20
LDX #10
STX $10
CMP $10

It's now comparing Register A with Register X?
I think you just have to be more careful with how you word things, because even though the final effect is that you're in fact comparing A to X, the accurate thing to say here is that you're comparing the value in A to a copy you've made of the value in X.
With STX, it's now carrying Zero since it "drops" the number into the Address $0010? Or it just "copy and paste" X Register $10 into Address $0010?
Storing doesn't alter the value in the register. When you do STX $10 the same number is now in X and in memory address $10. The same is true for the "transfer" instructions: TAX doesn't remove the value in A, it copies the value in A to X, since you're not accessing X itself with the CMP instruction, just a copy you made of it.
So if the addition overflows, the V Flag turns on ALONG with the Carry Flag?
Those flags work independently from each other. The carry flag signals unsigned overflows and underflows (results larger than 255 or smaller than 0), while the V flag signals signed overflows and underflows (results larger than 127 or smaller than -128).
I know. I am not good with English despite born English speaking.
the accurate thing to say here is that you're comparing the value in A to a copy you've made of the value in X.
Explain how? You mean the X Register made a COPY to the Address, and I'm comparing the Value A to copy I made FROM the Value of X Register?

---

Oooh, like this:

LDA #50 ; Load number 50 into Register A.
STA $0100 ; StoreCOPY number 50 from Register A directly into Address $0100.

Address $0100 now has number 50, and A Register STILL have number 50 on them even after storing?

---

So
Signed Numbers = Larger than 127 [128, 129...] or smaller than -128 [-129, -130..]?
Unsigned Numbers = Larger than 255 or smaller than 0?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

If you're really interested in doing operations between A, X and Y without using temporary variables in RAM, there's a trick you can use: Have one page (256 bytes) in ROM memory hold all the values from 0 to 255:

Code: Select all

bytetable:
  .db $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0a, $0b, $0c, $0d, $0e, $0f
  .db $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f
  (...)
  .db $f0, $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9, $fa, $fb, $fc, $fd, $fe, $ff
Now you can use X and Y as indices into this table, and since index 0 contains the value 0, index 1 contains the value 1, and so on, it will be like you're accessing the actual values of X and Y. Here are some operations you can do using this table:

Code: Select all

;add A and X together
clc
adc bytetable, x

;transfer X to Y
ldy bytetable, x

;compare A to Y
cmp bytetable, y
I think this is really cool because you can get a little bit of extra functionality out of the 6502 without having to worry about managing temporary variables, not to mention that this is usually faster than using temporary variables (e.g. stx temp + cmp temp takes 6 cycles at best, while cmp bytetable, x takes 4 cycles, so it's 33% faster). Some people think that using 256 bytes of ROM for this is just a waste of memory though.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

DocWaluigean wrote: Thu Jun 11, 2020 4:19 pmOooh, like this:

LDA #50 ; Load number 50 into Register A.
STA $0100 ; StoreCOPY number 50 from Register A directly into Address $0100.

Address $0100 now has number 50, and A Register STILL have number 50 on them even after storing?
Yes, exactly.
Signed Numbers = Larger than 127 [128, 129...] or smaller than -128 [-129, -130..]?
Unsigned Numbers = Larger than 255 or smaller than 0?
If you're talking overflows and underflows, yes. But like I said before, don't get too sidetracked with signed numbers for now. There are lots of little "gotchas" in working with signed numbers in assembly, and going through them right now would only make things needlessly confusing for you. I know you want to learn EVERYTHING, but if you focus on the most important, basic stuff first, then the more complicated things will be easier to grasp in the future.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, I'm back, still need assistences

Post by DocWaluigean »

tokumaru wrote: Thu Jun 11, 2020 4:26 pm If you're really interested in doing operations between A, X and Y without using temporary variables in RAM, there's a trick you can use: Have one page (256 bytes) in ROM memory hold all the values from 0 to 255:

Code: Select all

bytetable:
  .db $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0a, $0b, $0c, $0d, $0e, $0f
  .db $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f
  (...)
  .db $f0, $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9, $fa, $fb, $fc, $fd, $fe, $ff
Now you can use X and Y as indices into this table, and since index 0 contains the value 0, index 1 contains the value 1, and so on, it will be like you're accessing the actual values of X and Y. Here are some operations you can do using this table:

Code: Select all

;add A and X together
clc
adc bytetable, x

;transfer X to Y
ldy bytetable, x

;compare A to Y
cmp bytetable, y
I think this is really cool because you can get a little bit of extra functionality out of the 6502 without having to worry about managing temporary variables, not to mention that this is usually faster than using temporary variables (e.g. stx temp + cmp temp takes 6 cycles at best, while cmp bytetable, x takes 4 cycles, so it's 33% faster). Some people think that using 256 bytes of ROM for this is just a waste of memory though.
That looks VERY advanced for me to do it! Let me see:

I don't know what .DB/.db is in forms of usages, or how to use it yet. I'm guessing it's "Database" and I thought it's used for importing sprites and music.

From that, it seems to be creating numbers from 0 through 15 in a row.
With the period, I'm guessing using ALL the numbers from 0 through 255!!!

-
CLC - Turn off Carry Flag
ADC bytetable, x - Add numbers from label "bytetable" to Register X. Which means it uses ALL the numbers!?
-
LDY bytetable, x - Load numbers from "bytetable" into Register Y, and with the ", x" stuff, it means Load numbers from "bytetable" directly into Register X.
-
CMP bytetable, y - Compare numbers from "bytetable" that's currently inside Register A with "a copy I've made of the value in Register Y."???
[ or in different term, compare Register Y with "bytetable" label of numbers with Register Y... ]??
Doesn't sound right, but not sure what better ways to explain it...

Not sure how do I used it yet, although it's almost time for me to start programming on NES?

=============================================================================================================
DocWaluigean wrote: ↑Thu Jun 11, 2020 6:19 pm
Oooh, like this:

LDA #50 ; Load number 50 into Register A.
STA $0100 ; StoreCOPY number 50 from Register A directly into Address $0100.

Address $0100 now has number 50, and A Register STILL have number 50 on them even after storing?
Yes, exactly.
Signed Numbers = Larger than 127 [128, 129...] or smaller than -128 [-129, -130..]?
Unsigned Numbers = Larger than 255 or smaller than 0?
If you're talking overflows and underflows, yes. But like I said before, don't get too sidetracked with signed numbers for now. There are lots of little "gotchas" in working with signed numbers in assembly, and going through them right now would only make things needlessly confusing for you. I know you want to learn EVERYTHING, but if you focus on the most important, basic stuff first, then the more complicated things will be easier to grasp in the future.
Ah.. so like a copy machine with numbers, instead of "dropping numbers into Address, and no longer carrying it anymore." I'll keep that in mind!
---

That sounds very important, I need to know what you mean on the "most important, basic stuff first."?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

DocWaluigean wrote: Thu Jun 11, 2020 4:43 pmI don't know what .DB/.db is in forms of usages, or how to use it yet. I'm guessing it's "Database" and I thought it's used for importing sprites and music.
Stop guessing, this only puts wrong ideas in your head. Go read the documentation. DB means "define byte". This is not a CPU instruction, it's an assembler directive. It varies from assembler to assembler (e.g. some call it .byte, for example), but it's always present. It simply outputs raw data to the final ROM image.
From that, it seems to be creating numbers from 0 through 15 in a row.
With the period, I'm guessing using ALL the numbers from 0 through 255!!!
Yes, it's a 256-byte long table containing all values from 0 to 255.
ADC bytetable, x - Add numbers from label "bytetable" to Register X. Which means it uses ALL the numbers!?
No. address, x is another way of accessing RAM. It's called indexed addressing, because an index (either X or Y) is automatically added to the base address (address) to calculate the final address that will be accessed. If you do:

Code: Select all

ldx #4
lda $8001, x
The value at address $8005 will be loaded into the accumulator (because $8001 + 4 = $8005). This allows program to manipulate lists, so you're not stuck with lone variables. Many things in a game are represented as lists: lists of enemies, items, levels, etc., so that's what this kind of addressing is normally used for.

The trick here is that index 0 contains the value 0. Index 1 contains the value 1. Index 2 contains the value 2. And so on. When you do:

Code: Select all

ldx #0
lda bytetable, x
You are reading the first element of the table, which is 0. If you do:

Code: Select all

ldx #1
lda bytetable, x
You are reading the second element of the table, which is 1. No matter what number you put in X, the address bytetable + X will contain that same number. This means that you're indirectly getting the value of X.

This addressing mode isn't normally used like this, it's normally used to access lists with all kinds of data formed by bytes of various values, but by storing the numbers sequentially we create an equivalence between the index and the data stored at that index, basically allowing us to indirectly access the value of the index registers (X and Y).
Not sure how do I used it yet, although it's almost time for me to start programming on NES?
If you can follow the first few Nerdy Nights lessons, you can totally make a basic NES ROM, like something that displays a solid color, using little more than LDA and STA instructions. But I personally can't guide you through the assembler directives (.ORG, etc.) that you need to use in order to generate a valid NES ROM. Please read the tutorial and ask here about the parts you don't understand.
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: Hello, I'm back, still need assistences

Post by Garth »

At least 6502 jargon does not use the term "move" like many processors do, which I'm glad for, because "move" wrongly suggests it's no longer in the source. "Copy" is good. "Transfer" (like TAY, TYA, TAX, TXA, TXS, and TSX), "load," and "store" are still better than "move."
http://WilsonMinesCo.com/ lots of 6502 resources
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, I'm back, still need assistences

Post by DocWaluigean »

Garth wrote: Thu Jun 11, 2020 6:49 pm At least 6502 jargon does not use the term "move" like many processors do, which I'm glad for, because "move" wrongly suggests it's no longer in the source. "Copy" is good. "Transfer" (like TAY, TYA, TAX, TXA, TXS, and TSX), "load," and "store" are still better than "move."
So...

In forms of
LDA
LDX
LDY
LDS
into...
STA
STX
STY
STS - Store into Stack Pointer Register?

It's count as copy and NOT moving.

BUT

TAY
TYA
TAX
TXA
TXS
TSX

It count as MOVING and NOT copying?

I don't know which more opcode is moving numbers, and which more opcodes is COPYING numbers from itself to others.
User avatar
Gilbert
Posts: 564
Joined: Sun Dec 12, 2010 10:27 pm
Location: Hong Kong
Contact:

Re: Hello, I'm back, still need assistences

Post by Gilbert »

In either case, they're copy, not move.

Example 1:
The code:

Code: Select all

LDA #5
STA mem1
where mem1 is a label corresponding to a certain memory location, is equivalent to, in higher level language terms:

Code: Select all

A = 5
mem1 = A
Which after storing the value of A (5) into mem1, A still carries the value 5, so STA just copies the value of A to a memory location.

Example 2:
The code:

Code: Select all

LDA #7
TAX
is equivalent to, in higher level language terms:

Code: Select all

A = 7
X = A
Which after transferring the value of A (7) into X, A still carries the value 7, so TAX just copies the value of A to a X.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, I'm back, still need assistences

Post by tokumaru »

Yeah, there's no transferring or moving, ever. Every LD*, ST* and T** is a copy.
Post Reply