Last active
November 19, 2016 21:24
-
-
Save hikari-no-yume/fe099f8ac3effb1f426f555bc3b971e1 to your computer and use it in GitHub Desktop.
Minimal Famicom assembly example using cc65 which (in PAL mode only, apparently?) flips the screen colour every 256 frames
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PPUMASK = $2001 | |
PPUSTATUS = $2002 | |
; The iNES header which makes this into an actual “rom” | |
.segment "INESHDR" | |
.byt "NES", $1A ; magic number! | |
.byt 1 ; program ROM size in multiples of 16384 | |
.byt 1 ; character ROM size in multiples of 8192 | |
.byt 0, 0 ; flags including mapper (which in this case is 0 for NROM) | |
.byt 2 ; program ROM size in multiples of 8192 | |
.byt 1 ; PAL flag | |
; Interrupt addresses | |
.segment "VECTORS" | |
.addr nmi, reset, irq | |
; Self-explanatory :p | |
.segment "CODE" | |
.proc reset | |
; Init code time! I'll admit this is very much “cargo cult”. | |
; Following some of http://wiki.nesdev.com/w/index.php/Init_code | |
sei ; ignore IRQs (why?) | |
cld ; disable decimal mode (which is redundant actually) | |
ldx #$40 | |
stx $4017 ; disable APU frame IRQ (…so we don't get interrupted?) | |
ldx #$ff | |
txs ; set up stack | |
stx $2000 ; disable NMI | |
stx $2001 ; disable rendering | |
stx $4010 ; disable DMC IRQs | |
; We want to use the PPU, so we can draw stuff! Let's wait for it. | |
; http://wiki.nesdev.com/w/index.php/PPU_power_up_state#Best_practice | |
bit PPUSTATUS ; clears the VBL flag if it was set at reset time | |
vwait1: | |
bit PPUSTATUS | |
bpl vwait1 ; at this point, about 27384 cycles have passed | |
vwait2: | |
bit PPUSTATUS | |
bpl vwait2 ; at this point, about 57165 cycles have passed | |
; video works now! let's do an effect or something | |
lda #$00 ; initial value of toggle | |
sta $0100 | |
lda #%11111000 ; set PPU state to something less silly | |
sta PPUMASK | |
forever: | |
jmp forever | |
.endproc | |
.proc nmi | |
lda $0100 | |
tay | |
bne skip | |
lda PPUMASK ; flip emphasise RGB bits | |
eor #%1110000 | |
sta PPUMASK | |
skip: | |
iny | |
sty $0100 | |
rti | |
.endproc | |
.proc irq | |
rti | |
.endproc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
game.nes: game.o | |
ld65 -C nrom128.x game.o -o game.nes | |
game.o: game.s | |
ca65 game.s -o game.o | |
clean: | |
rm *.o *.nes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Taken from http://bin.smwcentral.net/u/1780/ex.zip | |
MEMORY { | |
ZP: start = $10, size = $f0, type = rw; | |
# use first $10 zeropage locations as locals | |
HEADER: start = $7f00, size = $0010, type = ro, file = %O, fill = yes, fillval = $00; | |
RAM: start = $0300, size = $0500, type = rw; | |
PRG0: start = $C000, size = $4000, type = ro, file = %O, fill = yes, fillval = $FF; | |
CHR0: start = $0000, size = $2000; | |
} | |
SEGMENTS { | |
INESHDR: load = HEADER, type = ro, align = $10; | |
ZEROPAGE: load = ZP, type = zp; | |
BSS: load = RAM, type = bss, define = yes, align = $100; | |
CODE: load = PRG0, type = ro, align = $100; | |
RODATA: load = PRG0, type = ro, align = $100; | |
DMC: load = PRG0, type = ro, align = $40, optional = yes; | |
VECTORS: load = PRG0, type = ro, start = $FFFA; | |
CHR: load = CHR0, type = ro; | |
} | |
FILES { | |
%O: format = bin; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment