Welcome, Guest. Please Login or Register
To the NESWORLD news page
   
  HomeHelpSearchLoginRegisterAwards  
 
Page Index Toggle Pages: 1
Send Topic Print
Learning 6502 Assembly (Read 8819 times)
JJM07
Forum Newbie
*

Offline



Project "Bions"

Posts: 5

Gender: male
Learning 6502 Assembly
19. Jan 2010 at 00:02
 
I read that in order to make an NES game (.rom file), you have to learn 6502 assembly. I've been trying to look something accessable online where I can learn assembly. The books and sources focusing on 6502 focus on Atari, Apple II, and C64, but not on NES... AND they have to be purchased online. I'm kinda confused and I need a place to start. Any starting tips, help or advice?
Back to top
 
WWW  
IP Logged
 
albailey
Senior Member
****

Offline



My NES collecting is getting
out of hand

Posts: 496
Ottawa

Re: Learning 6502 Assembly
Reply #1 - 19. Jan 2010 at 18:40
 
Here's some helpful tools and links:

1) 6502 Macroassembler and simulator:
http://home.pacbell.net/michal_k/

Its a little painful to use, but basically if you want to try out a small snippet of code, you can open an existing example, and put in your code to see if what you have written seems OK.   It also supports contextual help for most instructions, so you can type  CMP    and see some examples, flags affected, etc..

2) Online docs
http://www.obelisk.demon.co.uk/6502/
This site is pretty good.  It mentions the different instructions and addressing modes, what flags are affected, etc..  

3) CA65
Everyone has their own personal favorite assembler.  A lot of people like nesasm.  A few like ASM65 or TASM.  My favorite is CA65.   However it is a bit difficult to get going (actually a lot difficult)
http://www.cc65.org
http://www.cc65.org/doc/ca65.html

4) FCEUX (emulator)
http://fceux.com/web/home.html
The debugger, nametable viewer etc.. is very useful.  I find I generally use the earlier one (FCEU) since I like the memory viewer better.

5) www.nesdev.com (FORUM)
Detailed info, lots of active homebrewers, good place to ask technical and specific questions once you get going.

Al
Back to top
« Last Edit: 19. Jan 2010 at 18:41 by albailey »  
WWW  
IP Logged
 
JJM07
Forum Newbie
*

Offline



Project "Bions"

Posts: 5

Gender: male
Re: Learning 6502 Assembly
Reply #2 - 22. Jan 2010 at 17:29
 
@albailey - Thank you very much! I will definitely check it out.
Back to top
 
WWW  
IP Logged
 
JJM07
Forum Newbie
*

Offline



Project "Bions"

Posts: 5

Gender: male
Re: Learning 6502 Assembly
Reply #3 - 22. Jan 2010 at 17:30
 
@albailey - Thank you very much! I will definitely check it out.
Back to top
 
WWW  
IP Logged
 
albailey
Senior Member
****

Offline



My NES collecting is getting
out of hand

Posts: 496
Ottawa

Re: Learning 6502 Assembly
Reply #4 - 22. Jan 2010 at 20:25
 
If you do decide to use  CA65 as your assembler,  setup is very difficult.  I will attempt to help with a very basic linker file for you.  This linker file assumes you are creating a simple NROM game.   NROM are the simplest games, they have essentially no mapper.  You get 2 PRG banks to hold your data, which is plenty for most starting projects (sudoku only used 1).

Copy this chunk into a file called nes.ini


MEMORY {
 HEADER: start = $00,  size = $0010, type = ro, file = "tmp/lightgun.hed";
 ZP:         start = $00,    size = $100,    type = rw, file = "";
 RAM:        start = $200,   size = $400,    type = rw, file = "";
 PRG0:  start = $8000, size = $4000, type = ro, file = "tmp/bank0.prg";
 PRG1:  start = $C000, size = $4000, type = ro, file = "tmp/bank1.prg";
}

SEGMENTS {
 INES_HEADER:  load = HEADER, type = ro, align = $10;

 ZEROPAGE:   load = ZP,  type = zp;
 BSS:        load = RAM, type = bss, define = yes;

 BANK0:     load = PRG0, type = ro, align = $100;
 TITLE_REGION:     load = PRG0, type = ro, start= $8000;

 BANK0_END:     load = PRG0, type = ro, start= $C000;

 BANK1:     load = PRG1, type = ro, start = $C000;
 VECTORS:  load = PRG1, type = ro, start = $FFFA;
}




Now you need a simple makefile.   I use cygwin since I have a Unix background.  I suspect that if you are not familiar with makefiles, this will be difficult to read and understand.
Copy these contents into  file called "makefile"

# To build the NES ROM  just type: make
# To run the NES ROM  just type: make run
# Note: as with any make system, if any of the files have been updated they will
# be rebuilt along with any parts that are dependant on them

# Tools required. You should set these defines in your environment rather than update the makefile
# ie: Control Panel -> System -> Advanced -> Environment Variables -> (New) User Variable
# Three environment variables are required
#
ifndef CA65
       CA65 = C:\Personal\NES\Dev\Compilers\cc65\bin\ca65.exe
endif

ifndef LD65
       LD65 = C:\Personal\NES\Dev\Compilers\cc65\bin\ld65.exe
endif

ifndef EMU
       EMU  = C:\Personal\NES\Dev\Emulators\fceu-0.98.15-rerecording\fceu.exe
endif


# Change the MAIN from "example" to whatever your project is going to be called.
# This means you need a file called "example.asm" and a tiles file called "example.chr"
MAIN = example

INTER = tmp

# intermediate files
OBJS = $(MAIN).o
HEADER = $(INTER)/header.hed
ALL_PRG = $(INTER)/bank0.prg  $(INTER)/bank1.prg
ALL_CHR = resources/$(MAIN).chr


# the part that does the compiling, assembling, linking etc..

all: $(MAIN).nes

clean:
       rm -f $(OBJS) $(HEADER_OBJS) $(BANK_OBJS) $(HEADER) $(MAIN).nes $(ALL_PRG)
       rm -Rf $(INTER)

run: $(MAIN).nes
       $(EMU)  $(MAIN).nes

# For making the PRG (including header)
$(OBJS): %.o: %.asm
       $(CA65) $(CFLAGS) $< -o $@


$(ALL_PRG): $(OBJS)
       mkdir -p $(INTER)
       $(LD65) $(OBJS)  -C nes.ini


# For making the final iNES ROM
$(MAIN).nes: $(ALL_PRG) $(HEADER)
       cat $(HEADER) $(ALL_PRG) $(ALL_CHR) > $(MAIN).nes



Back to top
 
WWW  
IP Logged
 
albailey
Senior Member
****

Offline



My NES collecting is getting
out of hand

Posts: 496
Ottawa

Re: Learning 6502 Assembly
Reply #5 - 22. Jan 2010 at 20:26
 
Now the last step (actually not even close to the last step)  is a simple  ASM file that makes use of those values in the nes.ini file to properly align the vectors, banks, header, etc..  so that if you run the makefile with "make run"  and have your environment setup, you can almost see something working.  Since I am limited to the number of chars per post, I'll leave the reset handler blank. You can fill it with the sample reset handler on nesdev's wiki


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; HEADER
; This could be in a separate file

.segment "INES_HEADER"
  .byt "NES", 26
  .byt 2  ; number of 16 KB program segments
  .byt 1  ; number of 8 KB chr segments
  .byt 1 ; The upper byte is the mapper number, the lower byte is the mapper info ( mirroring, etc)
  .byt 0  ; extended mapper info
  .byt 0,0,0,0,0,0,0,0  ; the rest of the header is empty


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Constants
; Declaring that Sprites are located in page 2

SPRITE_DMA      = $02
SPRITE_MEMORY      = $0200


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; BANK 0
; Typically I put data in bank 0, and code in bank 1
.segment "BANK0"

; Add data here....


.segment "BANK0_END"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; BANK 1

.segment "BANK1"


resetHandler:
     ; Insert reset handler code

     ; From this point onward, the NMI handles everything so lets make the reset Handler run in an infinite loop
infiniteLoop:

     jmp infiniteLoop
     rti ; Never get here.


; -----------------------------------------------------------
nmiHandler:
     ; Standard start of NMI code
     ; NMIs can be called anywhere at any time, so lets protect A,X,Y by putting them on the stack
     PHA ; 3 cycles
     TXA ; 2 cycles
     PHA ; 3 cycles
     TYA ; 2 cycles
     PHA ; 3 cycles  so 13 CPU cycle setup cost to protect A,X,Y (and another 16 to restore things back at the end of the RTI)

     LDA $2002 ; reset address latch

     ; Invoke Sprite dma (uses lots of cycles)
     LDA SPRITE_DMA
     STA $4014


     ; All done. Restore from NMI (A,X,Y. This costs 16 cycles since PLA cost 4 while PHA only cost 3)
     PLA
     TAY
     PLA
     TAX
     PLA
     RTI





irqHandler:
     JMP resetHandler
     rti

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.segment "VECTORS"

  .addr nmiHandler, resetHandler, irqHandler

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



Al
Back to top
 
WWW  
IP Logged
 
albailey
Senior Member
****

Offline



My NES collecting is getting
out of hand

Posts: 496
Ottawa

Re: Learning 6502 Assembly
Reply #6 - 22. Jan 2010 at 20:28
 
You'll need to make a resources folder, with an 8K file called example.chr (just use one from SMB or something) in order for this to build.
It wont do anything though, just display a boring screen.  You'll need to fill in the reset handler from the wiki, and fill in the nmiHandler with whatever code you want to run each screen.  It is best to code based on the nmiHandler instead of the infiniteLoop section of the resetHandler, otherwise timing gets weird.

Good luck.
Al
Back to top
 
WWW  
IP Logged
 
Dutch nes gamer
God Member
*****

Offline




Posts: 598
holland

Gender: male
Re: Learning 6502 Assembly
Reply #7 - 18. Mar 2010 at 19:56
 
I learned some nes programming last year.
Learned about now it all worked etc.
But i only got to making backgrounds/demo screens.
The hardest thing to find information about is making a game.
Not much info on that point.
Back to top
 
 
IP Logged
 
Page Index Toggle Pages: 1
Send Topic Print