├── README.md ├── cart.s ├── compile.bat └── rom.chr /README.md: -------------------------------------------------------------------------------- 1 | # NESGuide 2 | 3 | This repository is related to the [video](https://www.youtube.com/watch?v=V5uWqdK92i0), a tutorial for how to program the Nintendo Entertainment System (NES) and the Family Computer (Famicom). The final assembly file is given as an example of what a basic starter program should look like. 4 | 5 | To compile this program, please download [CC65](https://github.com/cc65/cc65) 6 | 7 | Then run the following commands: 8 | ``` 9 | C:\PathTo\cc65\bin\ca65 C:\PathTo\cart.s -o C:\PathTo\cart.o -t nes 10 | C:\PathTo\cc65\bin\ld65 C:\PathTo\cart.o -o C:\PathTo\cart.nes -t nes 11 | ``` 12 | 13 | Where **C:\PathTo** is the path to where your cc65 folder is located and then for the files, to wherever your cart.s file is located at. The output (**-o**) of the object and NES files can be changed to whatever destination is desired. 14 | 15 | The result will be a .NES file located at C:\PathTo\cart.nes which can then be run using an NES Emulator. 16 | -------------------------------------------------------------------------------- /cart.s: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | .byte "NES" ;identification string 3 | .byte $1A 4 | .byte $02 ;amount of PRG ROM in 16K units 5 | .byte $01 ;amount of CHR ROM in 8K units 6 | .byte $00 ;mapper and mirroing 7 | .byte $00, $00, $00, $00 8 | .byte $00, $00, $00, $00, $00 9 | .segment "ZEROPAGE" 10 | VAR: .RES 1 ;reserves 1 byte of memory for a variable named VAR 11 | .segment "STARTUP" 12 | 13 | RESET: 14 | SEI ;disables interupts 15 | CLD ;turn off decimal mode 16 | 17 | LDX #%1000000 ;disable sound IRQ 18 | STX $4017 19 | LDX #$00 20 | STX $4010 ;disable PCM 21 | 22 | ;initialize the stack register 23 | LDX #$FF 24 | TXS ;transfer x to the stack 25 | 26 | ; Clear PPU registers 27 | LDX #$00 28 | STX $2000 29 | STX $2001 30 | 31 | ;WAIT FOR VBLANK 32 | : 33 | BIT $2002 34 | BPL :- 35 | 36 | ;CLEARING 2K MEMORY 37 | TXA 38 | CLEARMEMORY: ;$0000 - $07FF 39 | STA $0000, X 40 | STA $0100, X 41 | STA $0300, X 42 | STA $0400, X 43 | STA $0500, X 44 | STA $0600, X 45 | STA $0700, X 46 | LDA #$FF 47 | STA $0200, X 48 | LDA #$00 49 | INX 50 | CPX #$00 51 | BNE CLEARMEMORY 52 | 53 | ;WAIT FOR VBLANK 54 | : 55 | BIT $2002 56 | BPL :- 57 | 58 | ;SETTING SPRITE RANGE 59 | LDA #$02 60 | STA $4014 61 | NOP 62 | 63 | LDA #$3F ;$3F00 64 | STA $2006 65 | LDA #$00 66 | STA $2006 67 | 68 | LDX #$00 69 | LOADPALETTES: 70 | LDA PALETTEDATA, X 71 | STA $2007 72 | INX 73 | CPX #$20 74 | BNE LOADPALETTES 75 | 76 | ;LOADING SPRITES 77 | LDX #$00 78 | LOADSPRITES: 79 | LDA SPRITEDATA, X 80 | STA $0200, X 81 | INX 82 | CPX #$20 ;16bytes (4 bytes per sprite, 8 sprites total) 83 | BNE LOADSPRITES 84 | 85 | ;LOADING BACKGROUND 86 | 87 | LOADBACKGROUND: 88 | LDA $2002 ;read PPU status to reset high/low latch 89 | LDA #$21 90 | STA $2006 91 | LDA #$00 92 | STA $2006 93 | LDX #$00 94 | LOADBACKGROUNDP1: 95 | LDA BACKGROUNDDATA, X 96 | STA $2007 97 | INX 98 | CPX #$00 99 | BNE LOADBACKGROUNDP1 100 | LOADBACKGROUNDP2: 101 | LDA BACKGROUNDDATA+256, X 102 | STA $2007 103 | INX 104 | CPX #$00 105 | BNE LOADBACKGROUNDP2 106 | 107 | ;LOAD BACKGROUND PALETTEDATA 108 | LDA #$23 ;$23D0 109 | STA $2006 110 | LDA #$D0 111 | STA $2006 112 | LDX #$00 113 | LOADBACKGROUNDPALETTEDATA: 114 | LDA BACKGROUNDPALETTEDATA, X 115 | STA $2007 116 | INX 117 | CPX #$20 118 | BNE LOADBACKGROUNDPALETTEDATA 119 | 120 | ;RESET SCROLL 121 | LDA #$00 122 | STA $2005 123 | STA $2005 124 | 125 | ;ENABLE INTERUPTS 126 | CLI 127 | 128 | LDA #%10010000 129 | STA $2000 ;WHEN VBLANK OCCURS CALL NMI 130 | 131 | LDA #%00011110 ;show sprites and background 132 | STA $2001 133 | 134 | INFLOOP: 135 | JMP INFLOOP 136 | NMI: 137 | 138 | LDA #$02 ;LOAD SPRITE RANGE 139 | STA $4014 140 | 141 | RTI 142 | 143 | PALETTEDATA: 144 | .byte $00, $0F, $00, $10, $00, $0A, $15, $01, $00, $29, $28, $27, $00, $34, $24, $14 ;background palettes 145 | .byte $31, $0F, $15, $30, $00, $0F, $11, $30, $00, $0F, $30, $27, $00, $3C, $2C, $1C ;sprite palettes 146 | 147 | SPRITEDATA: 148 | ;Y, SPRITE NUM, attributes, X 149 | ;76543210 150 | ;|||||||| 151 | ;||||||++- Palette (4 to 7) of sprite 152 | ;|||+++--- Unimplemented 153 | ;||+------ Priority (0: in front of background; 1: behind background) 154 | ;|+------- Flip sprite horizontally 155 | ;+-------- Flip sprite vertically 156 | 157 | .byte $40, $00, $00, $40 158 | .byte $40, $01, $00, $48 159 | .byte $48, $10, $00, $40 160 | .byte $48, $11, $00, $48 161 | 162 | ;sword 163 | .byte $50, $08, %00000001, $80 164 | .byte $50, $08, %01000001, $88 165 | .byte $58, $18, %00000001, $80 166 | .byte $58, $18, %01000001, $88 167 | 168 | 169 | BACKGROUNDDATA: ;512 BYTES 170 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$02,$03,$04,$05,$00,$00,$00,$00,$00,$00,$00,$06,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00 171 | .byte $00,$00,$00,$00,$00,$00,$00,$08,$09,$0a,$0b,$0b,$0b,$0c,$0d,$0e,$0f,$10,$11,$56,$13,$14,$0b,$15,$00,$00,$00,$00,$00,$00,$00,$00 172 | .byte $00,$00,$00,$00,$00,$00,$00,$16,$17,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$18,$19,$00,$00,$00,$00,$00,$00,$00 173 | .byte $00,$00,$00,$00,$00,$1a,$1b,$1c,$1d,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$1e,$06,$1f,$00,$00,$00,$00,$00 174 | .byte $00,$00,$20,$21,$22,$23,$18,$24,$25,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$26,$27,$28,$00,$29,$2a,$00,$00,$00,$00,$00 175 | .byte $00,$00,$2b,$2c,$2d,$0b,$11,$2e,$2f,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$30,$31,$32,$33,$34,$35,$00,$00,$00,$00,$00 176 | .byte $00,$00,$00,$00,$36,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$18,$37,$38,$39,$3a,$00,$00,$00,$00,$00,$00 177 | .byte $00,$00,$00,$00,$3b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$3c,$3d,$3e,$00,$00,$00,$00,$00,$00,$00,$00 178 | .byte $00,$00,$00,$00,$3f,$40,$0b,$0b,$0b,$41,$42,$43,$44,$0b,$0b,$45,$0b,$0b,$0b,$0b,$46,$47,$48,$00,$00,$00,$00,$00,$00,$00,$00,$00 179 | .byte $00,$00,$00,$00,$00,$49,$0b,$0b,$4a,$4b,$00,$4c,$4d,$0b,$4e,$4f,$50,$0b,$0b,$51,$00,$52,$53,$00,$00,$00,$00,$00,$00,$00,$00,$00 180 | .byte $00,$00,$00,$00,$00,$3f,$54,$55,$12,$00,$00,$00,$57,$58,$59,$00,$5a,$5b,$5c,$5d,$00,$5e,$5f,$00,$00,$00,$00,$00,$00,$00,$00,$00 181 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$60,$61,$00,$00,$62,$63,$64,$65,$00,$66,$67,$68,$00,$00,$00,$00,$00,$00,$00,$00 182 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$69,$00,$00,$6a,$6b,$6c,$00,$6d,$6e,$6f,$70,$00,$00,$00,$00,$00,$00,$00,$00 183 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$71,$72,$73,$0b,$74,$75,$76,$77,$78,$00,$00,$00,$00,$00,$00 184 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$79,$7a,$7b,$7c,$7d,$7e,$7f,$80,$81,$82,$00,$00,$00,$00,$00 185 | .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$4c,$83,$84,$85,$86,$35,$87,$00,$00,$00,$00,$00,$00 186 | 187 | BACKGROUNDPALETTEDATA: ;32 bytes 188 | .byte $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55 189 | .byte $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55, $55 190 | 191 | .segment "VECTORS" 192 | .word NMI 193 | .word RESET 194 | ; specialized hardware interurpts 195 | .segment "CHARS" 196 | .incbin "rom.chr" -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | cd D:\ 2 | 3 | cc65\bin\ca65 program\cart.s -o program\cart.o -t nes 4 | cc65\bin\ld65 program\cart.o -o program\cart.nes -t nes 5 | 6 | cd D:\program -------------------------------------------------------------------------------- /rom.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InkboxSoftware/NESGuide/0f093301e747904bbba1ad7b664e512cb15cf463/rom.chr --------------------------------------------------------------------------------