Obligatory newbie questions

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

Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Obligatory newbie questions

Post by Bellum »

Hiya. I ran into this site awhile back and really got interested in learning 6502 asm. I've written a little C++ and a little Java and Python, but nothing too big. I've been reading a book here and a tutorial there and now I've given myself a nice big headache. :lol:

This low level stuff is seriously complicated! It seems to be a very different process from writing in a higher language, and I'm having trouble penetrating all the new vocabulary and hardware concepts.

Not at all helping the problem is that different tools seem to handle things radically different. Do I use macros? Labels? What's the syntax? Are there pre-existing libraries I can load and use? Continue ad infinitum. There's almost too much 6502 info out there and I'm having trouble finding a place to start.

I'm thinking the wisest thing to do is use the CC65 assembler, and I have CC65 installed and working. It's convenient that it compiles to any of the 6502 platforms. However, I don't know the peculiarities of that assembler, and I'm not sure where to find them.

Right now, I'm basically stuck using the 6502 simulator writing very simple programs that don't do anything but store and add numbers at some arbitrary address. That's after several days. I figure by now it's time to ask for some help. :P
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Macros are not unlike inline functions in C++. Labels are like function names or variable names. The syntax for both depends on the assembler: asm6 does it one way and ca65 does it another. You mentioned that you use ca65, the assembler in the cc65 distribution; reading its manual will probably be worth your while.

There aren't a lot of NES-specific reusable libraries, but I've written libraries for controller reading, pseudorandom number generation, multiplication, division, basic trig (enough for aiming in a video game), number printing, and sound playback that I'll let you use. PM me for details.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Obligatory newbie questions

Post by tokumaru »

Bellum wrote:Right now, I'm basically stuck using the 6502 simulator writing very simple programs that don't do anything but store and add numbers at some arbitrary address. That's after several days. I figure by now it's time to ask for some help. :P
That's the best way to start IMO, and I suggest you continue doing that for a while longer, until you're more comfortable with the 6502. If you try to code something for the NES knowing little more than how to load and store values you might even succeed (after all, all it takes to display something on the NES is a few loads and stores), but because you'll be dealing not only with the CPU but the PPU as well the concepts might end up getting mixed in your head.

I suggest that you gradually increase the complexity of the programs you are writing in the simulator. Even if you have pointless goals like filling a page of RAM with numbers from 1 to 255, you'll end up mastering loops, subroutines, addressing modes, and other essential concepts of 6502 assembly. You can also try making subroutines for useful tasks, like multiplying and dividing, moving blocks of memory, compressing and decompressing RLE... That way the learning will not feel like a waste of time, because you'll be able to use the code later in actual projects.
Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Post by Bellum »

tepples wrote:Macros are not unlike inline functions in C++. Labels are like function names or variable names. The syntax for both depends on the assembler: asm6 does it one way and ca65 does it another. You mentioned that you use ca65, the assembler in the cc65 distribution; reading its manual will probably be worth your while.

There aren't a lot of NES-specific reusable libraries, but I've written libraries for controller reading, pseudorandom number generation, multiplication, division, basic trig (enough for aiming in a video game), number printing, and sound playback that I'll let you use. PM me for details.
Ah. Much thanks. I saw the manual for compiling C to ASM, but missed that. Thanks. The way things are going, it'll probably be awhile before I'm skilled enough to do anything practical, but I'll keep that stuff in mind! Are there any libraries that make manipulating characters easier? Do I seriously have to encode every character by hand? xD

Also, thanks, Dwedit. That'll come in handy. A big list of three letter acronyms is a bit hard to remember, so I imagine I'll be using it a lot. :P
Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Re: Obligatory newbie questions

Post by Bellum »

tokumaru wrote:
Bellum wrote:Right now, I'm basically stuck using the 6502 simulator writing very simple programs that don't do anything but store and add numbers at some arbitrary address. That's after several days. I figure by now it's time to ask for some help. :P
That's the best way to start IMO, and I suggest you continue doing that for a while longer, until you're more comfortable with the 6502. If you try to code something for the NES knowing little more than how to load and store values you might even succeed (after all, all it takes to display something on the NES is a few loads and stores), but because you'll be dealing not only with the CPU but the PPU as well the concepts might end up getting mixed in your head.

I suggest that you gradually increase the complexity of the programs you are writing in the simulator. Even if you have pointless goals like filling a page of RAM with numbers from 1 to 255, you'll end up mastering loops, subroutines, addressing modes, and other essential concepts of 6502 assembly. You can also try making subroutines for useful tasks, like multiplying and dividing, moving blocks of memory, compressing and decompressing RLE... That way the learning will not feel like a waste of time, because you'll be able to use the code later in actual projects.
Ah, thanks. I was feeling kind of stupid, as slowly as I was progressing. I definitely intend on continuing to use the simulator, it's really nice for getting quick results.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

About encoding characters: NES graphics works much like text mode on an old 8-bit microcomputer such as a Commodore 64 or MSX. The background can be thought of as a 32x30-cell grid of character cells. If you draw tiles 32 to 95 in ASCII order, you can have the assembler do your text encoding for you:

Code: Select all

  .byt "Hello World"
As an intermediate step between the simulator and actual NES programming, you can treat the Windows version of FCEUX as a simulator. Make an iNES program that puts its variables in $0000-$07FF, and then examine the memory in the hex editor.
Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Post by Bellum »

Thanks for the tip! Is FCEUX more accurate than Nestopia, I wonder?

I wont be able to test anything I write on a real NES anyway; haven't had one for a looong time. I think it's broken by now, anyway. The machines, alas, are not as indestructible as the SNES. Especially when forced to deal with kids. :P
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Bellum wrote:Thanks for the tip! Is FCEUX more accurate than Nestopia, I wonder?
No way! AFAIK, Nestopia and Nintendulator are currently the most accurate emulators. FCEUX is fairly inaccurate actually... It just happens to have the best debugging features. Nintendulator has a few debugging features too.
3gengames
Formerly 65024U
Posts: 2284
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

I'd start reading Nerdy Nights (HERE), start at beginners, despite your knowledge. It should help you through and clear up the confusion of instructions, and explain them in more detail. You'll get the hang of it.

Also, those tutorials use NESASM3, it's a windows appliction ran from the command prompt [Batch file] so you'll have to download that and set that up, too. Just post if you have more problems and questions. To find NESASM3, just google it.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

3gengames wrote:To find NESASM3, just google it.
The guy said he already has ca65 working, please don't make him downgrade to NESASM! Nerdy Nights is indeed a decent tutorial, but if you can follow it and use another assembler that would be better.
Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Post by Bellum »

tepples wrote:

Code: Select all

  .byt "Hello World"
Can you loop through this somehow to store each character in memory? I think I've got the looping syntax down ok, but I can't store a string into a,x,y (Is there a practical difference between these?) if it's larger than one character.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

I'll work with you on this example. Let me know each thing you don't understand.

Code: Select all

PPUADDR = $2006  ; PPU video memory address port
PPUDATA = $2007  ; PPU video memory data port

.segment "RODATA"
  .byt "HELLO WORLD",0
  ; the 0 at the end is a NUL terminator, denoting the end of the string

.segment "CODE"
say_hello:

  ; point the video memory address at a nametable location
  ; near the center of the screen
  lda #$21
  sta PPUADDR
  lda #$CA
  sta PPUADDR

  ; loop over the characters in the string, indexed by Y
  ldy #0
loop:
  lda hello_str,y  ; load a character
  beq done  ; if we loaded a NUL terminator, stop writing characters
  sta PPUDATA  ; write the character to video memory
  iny  ; go to the next character in the string
  bne loop
done:
  rts
Now about how to allocate registers, here are rules of thumb:
  • A is best for arithmetic and bitwise logic operations. Because load/store instructions LDA/STA support more addressing modes than LDX/STX and LDY/STY, it's also good for data transfer.
  • X is useful for indexing through an array, and works with a few more instructions than Y, such as the read-modify-write instructions (DEC, INC, ASL, LSR, ROL, ROR).
  • Y is better when a string can start at any of several addresses or is bigger than 256 bytes, as it allows for storing the starting address in a 2-byte variable on zero page and then using the (d),y indirect indexed addressing mode to step through the array.
Bellum
Posts: 17
Joined: Sat Jun 04, 2011 8:04 pm

Post by Bellum »

Hmm, not sure what segment does at all, actually. :P

I understand what say_hello does, but I don't understand why you store the numbers $21 and $CA in memory.

I think I'm pretty clear on how the main loop works, wooo!

So, for instance, I could say...

Code: Select all

astring				.byt "This is a string!"
						LDA astring,0				;loads astring[0] into a
Except with correct formatting because it somehow messed up my notepad++ example. :/

EDIT:
Oh. I think I may have to use x or y directly for indexing?
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Post by thefox »

tepples wrote:If you draw tiles 32 to 95 in ASCII order, you can have the assembler do your text encoding for you:

Code: Select all

  .byt "Hello World"
I'll just add that CA65 also allows using custom character maps with the .charmap control command.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Post Reply