aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-10-06 03:24:30 -0400
committerJesse Luehrs <doy@tozt.net>2014-10-06 03:24:30 -0400
commitfd6950b364ceb0f9f6e1516d1dbe460e5d2a0bf3 (patch)
tree23e272fa3aa60594ce9748e9f54cfa0ad7667ac7
downloadnes-project-skeleton-fd6950b364ceb0f9f6e1516d1dbe460e5d2a0bf3.tar.gz
nes-project-skeleton-fd6950b364ceb0f9f6e1516d1dbe460e5d2a0bf3.zip
initial commit
-rw-r--r--.gitignore3
-rw-r--r--Makefile29
-rw-r--r--header.binbin0 -> 16 bytes
-rw-r--r--linkfile2
-rw-r--r--main.s163
-rw-r--r--sprites.chrbin0 -> 8192 bytes
6 files changed, 197 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..880005c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.rom
+*.nes
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6c56e3d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+NAME =
+OBJS = main.o
+
+CC = wla-6502
+LD = wlalink
+
+CFLAGS =
+LDFLAGS =
+
+all: $(NAME).nes
+
+$(NAME).nes: $(NAME).rom header.bin
+ cat header.bin $< > $@
+
+$(NAME).rom: $(OBJS) linkfile
+ $(LD) $(LDFLAGS) linkfile $@
+
+%.o: %.s
+ $(CC) $(CFLAGS) -o $<
+
+main.o: sprites.chr
+
+run: $(NAME).nes
+ fceux $(NAME).nes
+
+clean:
+ rm -f $(OBJS) $(NAME).rom $(NAME).nes
+
+.PHONY: all clean run
diff --git a/header.bin b/header.bin
new file mode 100644
index 0000000..d5ba821
--- /dev/null
+++ b/header.bin
Binary files differ
diff --git a/linkfile b/linkfile
new file mode 100644
index 0000000..3dddda7
--- /dev/null
+++ b/linkfile
@@ -0,0 +1,2 @@
+[objects]
+main.o
diff --git a/main.s b/main.s
new file mode 100644
index 0000000..67dcb57
--- /dev/null
+++ b/main.s
@@ -0,0 +1,163 @@
+.MEMORYMAP
+DEFAULTSLOT 0
+SLOTSIZE $4000
+SLOT 0 $C000
+SLOTSIZE $2000
+SLOT 1 $0000 ; location doesn't matter, CHR data isn't in main memory
+.ENDME
+
+.ROMBANKMAP
+BANKSTOTAL 2
+BANKSIZE $4000
+BANKS 1
+BANKSIZE $2000
+BANKS 1
+.ENDRO
+
+
+.ENUM $0000
+buttons_pressed DB
+.ENDE
+
+
+ .bank 0
+ .org $0000
+; the ppu takes two frames to initialize, so we have some time to do whatever
+; initialization of our own that we want to while we wait. we choose here to
+; set up cpu flags in the first frame and clear out system ram in the second
+; frame (clearing out ram isn't at all necessary, but we can't do anything
+; useful at this point anyway, so we may as well in order to make things more
+; predictable). clearing out system ram actually takes quite a bit longer than
+; a frame (a frame is ~2273 cycles, or ~324-1136 opcodes), but we may as well
+; start the process while we wait.
+RESET:
+ SEI ; disable IRQs
+ CLD ; disable decimal mode
+ LDX #$40
+ STX $4017.w ; disable APU frame IRQ
+ LDX #$FF
+ TXS ; Set up stack (grows down from $FF to $00, at $0100-$01FF)
+ INX ; now X = 0
+ STX $2000.w ; disable NMI (we'll enable it later once the ppu is ready)
+ STX $2001.w ; disable rendering (same)
+ STX $4010.w ; disable DMC IRQs
+
+vblankwait1: ; First wait for vblank to make sure PPU is ready
+ BIT $2002 ; bit 7 of $2002 is reset once vblank ends
+ BPL vblankwait1 ; and bit 7 is what is checked by BPL
+
+ ; set everything in ram ($0000-$07FF) to $00, except for $0200-$02FF which
+ ; is conventionally used to hold sprite attribute data. we set that range
+ ; to $FE, since that value as a position moves the sprites offscreen, and
+ ; when the sprites are offscreen, it doesn't matter which sprites are
+ ; selected or what their attributes are
+clrmem:
+ LDA #$00
+ STA $0000, x
+ STA $0100, x
+ STA $0300, x
+ STA $0400, x
+ STA $0500, x
+ STA $0600, x
+ STA $0700, x
+ LDA #$FE
+ STA $0200, x
+ INX
+ BNE clrmem
+
+ ; initialize variables in ram
+ LDA #$00
+ STA buttons_pressed
+
+ LDA #$32
+ STA $0201 ; set the sprite number to display
+ LDA #$00
+ STA $0202 ; set the sprite attributes (palette, flipping, etc)
+
+ LDA #$33
+ STA $0205 ; set the sprite number to display
+ LDA #$00
+ STA $0206 ; set the sprite attributes (palette, flipping, etc)
+
+ LDA #$34
+ STA $0209 ; set the sprite number to display
+ LDA #$00
+ STA $020A ; set the sprite attributes (palette, flipping, etc)
+
+ LDA #$35
+ STA $020D ; set the sprite number to display
+ LDA #$00
+ STA $020E ; set the sprite attributes (palette, flipping, etc)
+
+vblankwait2: ; Second wait for vblank, PPU is ready after this
+ BIT $2002
+ BPL vblankwait2
+
+ ; now that the ppu is ready, we can start initializing it
+LoadPalettes:
+ LDA $2002 ; read PPU status to reset the high/low latch
+ LDA #$3F
+ STA $2006 ; write the high byte of $3F00 address
+ LDA #$00
+ STA $2006 ; write the low byte of $3F00 address
+ LDX #$00
+LoadPalettesLoop:
+ LDA palette.w, x ;load palette byte
+ STA $2007 ;write to PPU
+ INX ;set index to next byte
+ CPX #$20
+ BNE LoadPalettesLoop ;if x = $20, 32 bytes copied, all done
+
+ LDA #%00010000 ; enable sprites
+ STA $2001
+
+ LDA #%10000000 ; enable NMI interrupts
+ STA $2000
+
+loop:
+ JMP loop
+
+read_controller1:
+ ; latch
+ LDA #$01
+ STA $4016
+ LDA #$00
+ STA $4016
+
+ ; clock
+ LDX #$00
+read_controller1_values:
+ CPX #$08
+ BPL end_read_controller1
+
+ LDA $4016
+ AND #%00000001
+ ASL buttons_pressed
+ ORA buttons_pressed
+ STA buttons_pressed
+ INX
+ JMP read_controller1_values
+
+end_read_controller1:
+ RTS
+
+NMI:
+ JSR read_controller1
+ ; ...
+ RTI
+
+palette:
+ .db $0F,$31,$32,$33,$0F,$35,$36,$37,$0F,$39,$3A,$3B,$0F,$3D,$3E,$0F
+ .db $0F,$1C,$15,$14,$0F,$02,$38,$3C,$0F,$1C,$15,$14,$0F,$02,$38,$3C
+
+ .orga $FFFA ;first of the three vectors starts here
+ .dw NMI ;when an NMI happens (once per frame if enabled) the
+ ;processor will jump to the label NMI:
+ .dw RESET ;when the processor first turns on or is reset, it will jump
+ ;to the label RESET:
+ .dw 0 ;external interrupt IRQ is not used in this tutorial
+
+
+ .bank 1 slot 1
+ .org $0000
+ .incbin "sprites.chr"
diff --git a/sprites.chr b/sprites.chr
new file mode 100644
index 0000000..6d17cf9
--- /dev/null
+++ b/sprites.chr
Binary files differ