Hello, new here, and need best recommandations.

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

Post Reply
User avatar
kocmoc
Posts: 9
Joined: Mon Aug 20, 2018 2:09 am
Location: Rus (PAL)

Re: Hello, new here, and need best recommandations.

Post by kocmoc »

By the way, my little observation:
when I dealt with banks, I saw a slight difference between nasasm3 and asm6:
nesasm3 - fills the unused space 0xFF (Undefined)
while asm6 - fills 0x00 (BRK)
:D
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Hello, new here, and need best recommandations.

Post by tepples »

It's conventional to fill with $FF because when programming UV EPROM, traditional EEPROM, or NOR flash, it's faster to program $FF than any other value.

In ASM6, try fillvalue $FF
(Source: README.txt)

In ca65, set fill=yes, fillval=$FF for each memory area in the linker script you pass to ld65.
(Source: ld65 Users Guide: 5.5 Other MEMORY area attributes)
User avatar
kocmoc
Posts: 9
Joined: Mon Aug 20, 2018 2:09 am
Location: Rus (PAL)

Re: Hello, new here, and need best recommandations.

Post by kocmoc »

tepples wrote:In ASM6, try fillvalue $FF
Ok, by default :)
PS "fillvalue" is useful, thanks
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Hello, new here, and need best recommandations.

Post by rainwarrior »

The use of $FF fill for EPROMs isn't really relevant for most people's workflow these days, though. I personally prefer filling with 0, because it creates a BRK opcode, which has more predictable behaviour in the accident that your program tries to execute an empty space.

$FF is some weird illegal opcode but it will keep executing, eventually try to execute the vector table, and then likely rolling over into ZP and start executing there where who knows what it's going to do.

BRK on the other hand goes straight to your interrupt handler.

You can even use the interrupt handler to trap errors this way. For me this was a big help for catching stack misuse errors (e.g. unpaired PHA/PLA). If you're using your IRQ for something else already, this may not be viable (you can detect the difference between a BRQ and a regular IRQ in the handler though), but even if you can't, I still think $00 fill is a vote for more predictable/detectable error conditions.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

There's WAAAYYY too many comments and I got lost. But thanks for giving me chance to try and speak up.

I'm going to draw a sketch so I could see if it's possible to even make children find value and learn NES much higher friendly. It's possible a cartoon would be made in favor for this.

So sadly, I have to start over...again. But I'm going too high level on asking about it.

obviously I understand HEX, binary, and "decimals", or normal numbers anyone knows what it means in much simpler terms, so I can skip this Week one. [No offense. I'm tired of seeing things so simple goes too complicated.]

Ironically, I understand Week 2, but many times I keep forgetting what it means or what it does and I had to go here to figure out what they mean sometimes.

Week 2:

-Is there the ENTIRE map of CPU overview? Where each address specifies what it does, like $3F10 is used for palette assignment in those specific screen? I didn't see PPU overview until just now, so that's off the question, but what about the rest of them?

-$800 - $1FFF = nothing. Is it the NES system flaw or is it only usable for mapper? or that's actually Famicom before removed toward release in US?

Week 3 is my "Forever broken tire" style, so I'm going to write it as I read it.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Hello, new here, and need best recommandations.

Post by koitsu »

DocWaluigean wrote:-Is there the ENTIRE map of CPU overview? Where each address specifies what it does, like $3F10 is used for palette assignment in those specific screen? I didn't see PPU overview until just now, so that's off the question, but what about the rest of them?
You're asking for a combination of 1) CPU memory map, and 2) list of MMIO registers (some call them "ports", for reasons unknown to mankind). You can find both here (refer to relevant links within wiki itself): https://wiki.nesdev.com/w/index.php/CPU_memory_map
DocWaluigean wrote: -$800 - $1FFF = nothing. Is it the NES system flaw or is it only usable for mapper? or that's actually Famicom before removed toward release in US?
See above.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

koitsu wrote:
DocWaluigean wrote:-Is there the ENTIRE map of CPU overview? Where each address specifies what it does, like $3F10 is used for palette assignment in those specific screen? I didn't see PPU overview until just now, so that's off the question, but what about the rest of them?
You're asking for a combination of 1) CPU memory map, and 2) list of MMIO registers (some call them "ports", for reasons unknown to mankind). You can find both here (refer to relevant links within wiki itself): https://wiki.nesdev.com/w/index.php/CPU_memory_map
DocWaluigean wrote: -$800 - $1FFF = nothing. Is it the NES system flaw or is it only usable for mapper? or that's actually Famicom before removed toward release in US?
See above.
- $0000-$07FF $0800 2KB internal RAM
So are these temporary memory where you place code that's being active? [I.E., equipping level 4 sword, being on World 3-6, no save data until world 4]

I would question more, but I could feel stern against me like that early comment, so I won't bother you much with it. Sorry...
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Hello, new here, and need best recommandations.

Post by koitsu »

DocWaluigean wrote:- $0000-$07FF $0800 2KB internal RAM
So are these temporary memory where you place code that's being active? [I.E., equipping level 4 sword, being on World 3-6, no save data until world 4]
It's exactly what it says it is: memory range $0000 to $07FF is RAM. You can use it for whatever purpose you want. Most people use it for exactly what you described. But if you want to put code there and run code out of RAM, you can do it (ex. jmp $0400 will work exactly like you think, but it's up to to put the code into RAM first :-) ).

Keep in mind that:

* $0000 to $00FF is zero page (you should know about this already, it's a 65xx architecture thing),
* $0100 to $01FF is for the stack.

The contents of said RAM are lost on power cycle, but retained on a soft reset (pressing the reset button).

It's up to you to decide how you want to lay out your RAM usage. Here's a model some people use, but you DO NOT have to follow it.

If you want persistent RAM (i.e. retained during power loss, like Zelda's save feature), then you want battery-backed RAM (sometimes called SRAM ("save RAM", not be confused with "static RAM")). That's different and unrelated to the RAM from $0000 to $07FF. Battery-backed RAM is on the cartridge, along with a battery (so it retains charge), and is mapped to $6000 to $7FFF (8KBytes) in CPU memory space. To use it in a ROM (.NES file), you need to set bit 1 of byte 6 of the header to 1. Don't ask me why the docs call it "PRG RAM". (Edit: people replying to this paragraph to hem and haw over NES 2.0, >8KByte, etc. should go away -- the guy is trying to learn basics, don't confuse him)

Edit 2: fixing up stack area description, thanks rainwarrior.
Last edited by koitsu on Mon Aug 20, 2018 10:50 pm, edited 2 times in total.
User avatar
kocmoc
Posts: 9
Joined: Mon Aug 20, 2018 2:09 am
Location: Rus (PAL)

Re: Hello, new here, and need best recommandations.

Post by kocmoc »

rainwarrior wrote:The use of $FF fill for EPROMs isn't really relevant for most people's workflow these days, though. I personally prefer filling with 0, because it creates a BRK opcode, which has more predictable behaviour in the accident that your program tries to execute an empty space.

$FF is some weird illegal opcode but it will keep executing, eventually try to execute the vector table, and then likely rolling over into ZP and start executing there where who knows what it's going to do.

BRK on the other hand goes straight to your interrupt handler.

You can even use the interrupt handler to trap errors this way. For me this was a big help for catching stack misuse errors (e.g. unpaired PHA/PLA). If you're using your IRQ for something else already, this may not be viable (you can detect the difference between a BRQ and a regular IRQ in the handler though), but even if you can't, I still think $00 fill is a vote for more predictable/detectable error conditions.
Here I agree more with
tepples wrote:It's conventional to fill with $FF because when programming UV EPROM, traditional EEPROM, or NOR flash, it's faster to program $FF than any other value.
If you want to debug, do this on the emulator (for example, fceux), if you want to catch errors, use the emulator with a breakpoint on "break on bad operation" =)
After full debugging, you can flash the PPU / CPU.

PS The device does not execute this command, $ FF is a bad operation, it will be a software reset.
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Hello, new here, and need best recommandations.

Post by Sumez »

Don't get too complex for someone who is just starting out :)

$0000-$07FF is just RAM, it's where you store any number you want to be able to retrieve again. The position of your player. The state of its movement. The stage you are on. Etc.
You could store code there, but it would serve no purpose unless you have something really clever planned out. Which you won't in your first project. ;)


$0800-$1FFF I guess is just a mirror because the NES only has 2KB RAM. It's easier for the hardware to mirror data than have an unusable address range.
Why is it unused? I'm sure someone here has a great, correct response, but one guess could be that Nintendo wanted the NES to potentially have (or be upgraded to have) 4KB RAM at some point during the design process.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Hello, new here, and need best recommandations.

Post by tepples »

kocmoc wrote:Here I agree more with
tepples wrote:It's conventional to fill with $FF because when programming UV EPROM, traditional EEPROM, or NOR flash, it's faster to program $FF than any other value.
If you want to debug, do this on the emulator (for example, fceux)
Provided the emulators for your platform even support debugging. Though Mesen and FCEUX do, I doubt that is true of most emulators built for, say, the ARM architecture seen on Pinebook, Raspberry Pi, and Android tablets. Even if your PC is x86-64, you might not want to spend a gigabyte of a small SSD on installing Wine and/or Mono, and you might not want to tolerate the mandatory telemetry and other annoyances of Windows 10. (We've been through this before.)
kocmoc wrote:PS The device does not execute this command, $ FF is a bad operation, it will be a software reset.
An authentic MOS 6502 will execute $FF as ISC aaaa,X, which performs INC aaaa,X then SBC aaaa,X. For example, FF 46 02 is ISC $0246,X, and FF FF FF is ISC $FFFF,X. The second source 6502 in the NES executes unofficial opcodes the same way as the original, given that it was cut from an identical mask with only the transistors enabling BCD addition and subtraction cut out. Or what external hardware did you have in mind for detecting that opcode and performing a soft reset?
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

It's my fault for not replying or read-and-think, and attempting to re-read it. But why is nearly every information has to be written so difficult? I obviously know off-topic and pretty ignorant to say, but Archimedes wouldn't make the coding very complex and this... "push-away" style. Like I said, the other countries like Japan has made coding really fun, and I feel we're really behind if lesser-grammar people can't understand the US style. [No offense. I really want to help make the guide and tutorial for 6502.]

What I'm getting on the past comment last time was the code I explained was exactly right, and then the another type is the stack, which I doubt it's a type of array. [Like list of fruits and what each gives points.] and $FF is the bad operation, which reset upon meeting to it's destination. And the advertising of Fecux or Mesen? I would go for Mesen if the Karilla wasn't complex...

So, Week 3:

-What are the entire beginner's code usages recommanded for the directives, if you were Bunnyboy? There's one for opcodes I'm guessing.

-So labels are like " Define CAKE" like this:

Code: Select all

***pseudocode***

DEF CAKE:

Milk = 1

Flour = 2

Eggs = 3

Sugar = 4

END DEF
Is this correct? or what's missing pieces?

-Nowthis one is really annoying. The opcodes..

---------------------------------------------------------
dougeff wrote:
JOE = 10
ROB = 5
JUMP = JOE + ROB
IF JOE == ROB
GOTO @NAME
In Assembly, JOE, ROB, and JUMP could be RAM address, and @NAME is a label that the assembler will give a value to at assembly time. (Omitting some assembly directives to make it easier)

LDA #10 ;load A with 10
STA JOE ;store it to JOE
LDA #5 ;load A with 5
STA ROB ;store it to ROB
LDA JOE ;load A with JOE
CLC ;clear the carry flag, for addition
ADC ROB ;add ROB to A
STA JUMP ;store the result to JUMP
LDA ROB ;load A with ROB
CMP JOE ;compare A with JOE
BEQ @NAME ;branch to the label @NAME if equal
-First, the @DEFAULT: is it a label where you jump or go to when certain requires meet? or labels is completely different between BASIC and 6502?

Now... this one will be strange or hilarious. Let say I change the words around, and change A into X or Y or other unmentioned register from BunnyBoy. From what I'm getting, this is a type of "individual cute calculators" where A is "Calculator A", X is "Calculator X", and Y is "Calculator Y", no? Each calculators is connected to the NES CPU blahs. And they only connected one way. And absolutely no way to connect the math "temporary holding" between X, Y, and A, right? The only way is through NES CPU blahs with the "SXY, SXA, SYA, SYX", correct?

And what if I change some of the letters around?

Code: Select all

[color=#00BF00]LDA #10[/color] ;load A with 10
[color=#00BF00]STA JOE[/color] ;store it to JOE
[color=#00BF00]LDX #5[/color] ;load A with 5
[color=#00BF00]STX ROB[/color] ;store it to ROB
[color=#00BF00]LDA JOE[/color] ;load A with JOE
[color=#00BF00]CLC[/color] ;clear the carry flag, for addition
[color=#00BF00]ADC ROB[/color] ;add ROB to A
[color=#00BF00]STY JUMP[/color] ;store the result to JUMP
[color=#00BF00]LDY ROB[/color] ;load A with ROB
[color=#00BF00]CMP JOE[/color] ;compare A with JOE
[color=#00BF00]BEQ @NAME[/color] ;branch to the label @NAME if equal
Is the one above correct or easily qualified into assembly? or each registers has their own limits?

and another example, if I completely ignore the A X Y law, as I were to think it's the same..

Code: Select all

[color=#00BF00]LDA #10[/color] ;load A with 10
[color=#00BF00]STX JOE[/color] ;store it to JOE
[color=#00BF00]LDY #5[/color] ;load A with 5
[color=#00BF00]STA ROB[/color] ;store it to ROB
[color=#00BF00]LDY JOE[/color] ;load A with JOE
[color=#00BF00]CLC[/color] ;clear the carry flag, for addition
[color=#00BF00]XDC ROB[/color] ;add ROB to A
[color=#00BF00]STA JUMP[/color] ;store the result to JUMP
[color=#00BF00]LDY ROB[/color] ;load A with ROB
[color=#00BF00]CMP JOE[/color] ;compare A with JOE
[color=#00BF00]BEQ @NAME[/color] ;branch to the label @NAME if equal
obviously something is wrong, but why? and what result would it give if you go Leeroy Jenkins and keep the code in? Explain it in original way, and in Elementary School way please, so maybe I could write it down for user-friendly guides.

-I know comments, but does it waste spaces? And by how much each character?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, new here, and need best recommandations.

Post by tokumaru »

DocWaluigean wrote:Is this correct? or what's missing pieces?
I have no idea what you're trying to do here.
-First, the @DEFAULT: is it a label where you jump or go to when certain requires meet?
Yes, labels mark places in the code where you can jump to. A label is just a "nickname" for a memory location, so they're used for variables too, they're not just for jumping.
Now... this one will be strange or hilarious. Let say I change the words around, and change A into X or Y or other unmentioned register from BunnyBoy.
You can change which registers are used for which task, but you have to be consistent (e.g. you can't use STX to write to memory a value that's in Y!) and you have to keep in mind that not all registers can do everything, all of them have different limitations.
LDA #10 ;load A with 10
STA JOE ;store it to JOE
This is correct.
LDX #5 ;load A with 5
STX ROB ;store it to ROB
This works fine too. If X isn't being used for anything else, you can use it as intermediate storage when writing a value to memory.
LDA JOE ;load A with JOE
CLC ;clear the carry flag, for addition
ADC ROB ;add ROB to A
STY JUMP ;store the result to JUMP
Now this doesn't make sense, because Y doesn't contain the result of the addition, A does. The result is always in A, that's just how the ADC operation works: A = A + MEMORY + C. That STY will just store whatever Y contains into the JUMP variable.
LDY ROB ;load A with ROB
CMP JOE ;compare A with JOE
BEQ @NAME ;branch to the label @NAME if equal
This also won't work, because CMP compares the accumulator against another value. There's another compare instruction for the Y register, CPY. If you use that instead of CMP, it'll work.
or each registers has their own limits?
Yes, they have limits. Math and bitwise operations can only be done with A. X and Y can only be incremented/decremented by 1, and are meant to be used as counters and indices (for accessing arrays and the like), with different addressing modes using them in different ways.
LDA #10 ;load A with 10
STX JOE ;store it to JOE
The number 10 is NOT being stored in JOE.
LDY #5 ;load A with 5
STA ROB ;store it to ROB
Number 5 is NOT being stored in ROB. ROB will actually be 10, which is what A contains at this point (remember the LDA #10 from before? so yeah, a still contains 10).
LDY JOE ;load A with JOE
CLC ;clear the carry flag, for addition
XDC ROB ;add ROB to A
STA JUMP ;store the result to JUMP
The "A" in ADC doesn't represent the accumulator. "ADC" is short for ADd with Carry. There's no instruction for adding X or Y to another value, only A can be added.
LDY ROB ;load A with ROB
CMP JOE ;compare A with JOE
BEQ @NAME ;branch to the label @NAME if equal
Again, change that CMP to CPY and it'll work.
obviously something is wrong, but why?
Because you're not routing the values to the places where you want them to go.
and what result would it give if you go Leeroy Jenkins and keep the code in?
The wrong values will go to the wrong variables, decisions will be made based on the wrong conditions, causing the logic you tried to implement to fail.
Explain it in original way, and in Elementary School way please, so maybe I could write it down for user-friendly guides.
You just have to understand what the CPU does, and think like the CPU. Here's a page with all the instructions the CPU supports. Those are all the commands you have to implement the logic in your game. That's your tool box, and you'll have to make do with just that.

Say you want to do VARIABLE = 30 like you do in basic. Tough luck, there's no instruction to save an arbitrary value to RAM. However, there are instructions to put values in CPU registers, and there are instructions to save the registers to RAM, so that's how you do it. Choose a register (A, X or Y) and put your value in it (using LDA, LDX or LDY). Then, save THAT SAME REGISTER to RAM using the respective store instruction (STA, STX or STY). You have to use the same register for loading and storing, otherwise you'll not put the value you want in the location you want, you'll just put something else there.

The same goes for CMP, CPX and CPY. If you put a number to compare in Y, and then do a CMP, that instruction will compare whatever was left in A from the code before, it will not use Y in any way. This means that the decision to jump or not to jump will be made based on the wrong result.

Stop trying to think like a human, and start thinking like the dumb CPU that the 6502 is. It only does stuff little by little, so complex operations will have to be broken down into several instructions. Whenever you need to do something, look at the instructions and see which ones can help you get the job done, and then use them in sequence until the task is done. In the beginning you'll be reading about the instructions a lot, but eventually you'll remember what they all do and you'll be able to write code faster.
-I know comments, but does it waste spaces? And by how much each character?
Comments are ignored by the assembler and don't take any space in the assembled binary. They exist to make the source code easier to comprehend, they don't affect the final ROM in any way.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Hello, new here, and need best recommandations.

Post by Kasumi »

Like I said, the other countries like Japan has made coding really fun, and I feel we're really behind if lesser-grammar people can't understand the US style.
I'm curious what makes you think this is true. If you know Japanese enough to understand they make coding fun, then you why not just follow the better, more fun ways to learn? If you don't know Japanese, how are you sure it's any different?

I realize I've mentioned it a dozen times already, but could you please try easy6502? It allows you to just try things and see what happens. Even if you don't even read it, you can still use it to look at exactly what happens with each instruction.
Image
The gif stops showing what happens with the mouse at stx $0704 because I didn't set up the memory viewer to go that far down. Still, it should demonstrate how one can run code instruction by instruction and follow along.

Edit: The reason I keep saying this is because rather than asking about abstract concepts, you can ask about exact behavior. The difference is between
"Does this do what I expect it to do?"
And,
"This doesn't do what I expected it to do, can you help me understand why?"
You're asking about the concepts which isn't exactly a problem, but tools exist to let you play directly with the CPU. Why aren't you trying them? I'm not asking to be snarky. Is there something about the tool you're having trouble with or don't understand?
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Hello, new here, and need best recommandations.

Post by Sumez »

DocWaluigean wrote:It's my fault for not replying or read-and-think, and attempting to re-read it. But why is nearly every information has to be written so difficult?
That's one major difference between coding assembly, and coding high level languages.
The high level languages (especially super abstracted stuff like C# and Java) is designed by humans to be read by humans. They are better at making sense at a more straight forward level.

When you are writing machine code, you are talking the computer's language. And when stuff is designed for computers to do it most effectively, it might not always be the straightforward way humans expect. For example, this is why the A register can do a lot of stuff that the X and Y registers can.

Honestly, it's not really that complex, you just need to get into it. Get some hands-on experience. Once you get used to the quirks and limitations, you'll be able to apply human logic to your project. :)
Post Reply