├── .gitignore ├── part1 ├── build.sh └── src │ ├── macros.inc │ ├── main.asm │ ├── header.asm │ ├── init.asm │ ├── lorom.cfg │ └── registers.inc ├── part2 ├── build.sh └── src │ ├── macros.inc │ ├── header.asm │ ├── init.asm │ ├── charset.asm │ ├── lorom.cfg │ ├── main.asm │ └── registers.inc ├── part3 ├── build.sh └── src │ ├── macros.inc │ ├── header.asm │ ├── init.asm │ ├── charset.asm │ ├── lorom.cfg │ ├── main.asm │ └── registers.inc ├── part4 ├── build.sh └── src │ ├── macros.inc │ ├── header.asm │ ├── init.asm │ ├── charset.asm │ ├── lorom.cfg │ ├── main.asm │ └── registers.inc ├── part5 ├── build.sh └── src │ ├── macros.inc │ ├── header.asm │ ├── init.asm │ ├── charset.asm │ ├── lorom.cfg │ ├── main.asm │ └── registers.inc ├── part6 ├── build.sh └── src │ ├── macros.inc │ ├── header.asm │ ├── init.asm │ ├── lorom.cfg │ ├── main.asm │ ├── charset.asm │ └── registers.inc └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | -------------------------------------------------------------------------------- /part1/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part2/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part3/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part4/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part5/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part6/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")" 6 | 7 | mkdir -p out 8 | ca65 ./src/main.asm -o ./out/main.o -g 9 | ld65 -C ./src/lorom.cfg -o ./out/main.sfc ./out/main.o 10 | -------------------------------------------------------------------------------- /part1/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part2/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part3/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part4/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part5/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part6/src/macros.inc: -------------------------------------------------------------------------------- 1 | .macro setA8 2 | sep #$20 3 | .endmacro 4 | 5 | .macro setA16 6 | rep #$20 7 | .endmacro 8 | 9 | .macro setAXY8 10 | sep #$30 11 | .endmacro 12 | 13 | .macro setAXY16 14 | rep #$30 15 | .endmacro 16 | 17 | .macro setXY8 18 | sep #$10 19 | .endmacro 20 | 21 | .macro setXY16 22 | rep #$10 23 | .endmacro 24 | -------------------------------------------------------------------------------- /part1/src/main.asm: -------------------------------------------------------------------------------- 1 | .p816 2 | .smart 3 | 4 | .include "macros.inc" 5 | .include "registers.inc" 6 | 7 | .include "header.asm" 8 | 9 | .segment "CODE" 10 | 11 | start: 12 | .include "init.asm" 13 | 14 | ; Set up the color palette 15 | stz CGADD 16 | ; Set color zero to red 17 | ; $001f = %0000000000011111 18 | ; bbbbbgggggrrrrr 19 | lda #$1f 20 | sta CGDATA 21 | lda #$00 22 | sta CGDATA 23 | 24 | lda #$0f 25 | sta INIDISP 26 | 27 | busywait: 28 | bra busywait 29 | 30 | nmi: 31 | bit RDNMI 32 | _rti: 33 | rti 34 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # SNES Development 2 | 3 | This is the example code for my series of tutorials on SNES development. I recommend reading the [accompanying tutorials](https://blog.wesleyac.com/posts/snes-dev-1-getting-started) on my blog. 4 | 5 | Please note: 6 | 7 | > The example code will be kept brutally simple, to the point of maybe even being a little gross. This is to encourage you to make your own copy of it, edit it, and make it your own. I recommend copying the code from part one, and then applying the changes in each new part manually, so that you can clean things up and move things around as you go. In each section, I'll link both to the complete code, and to a diff from the previous part. 8 | -------------------------------------------------------------------------------- /part1/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part2/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part3/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part4/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part5/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part6/src/header.asm: -------------------------------------------------------------------------------- 1 | .segment "HEADER" 2 | 3 | .byte "EXAMPLE ROM " ; ROM name, must be 21 chars 4 | .byte $30 ; Map Mode: 3.58MHz LoROM 5 | .byte $00 ; Cartridge Type: ROM only 6 | .byte $08 ; ROM Size 7 | .byte $00 ; RAM size 8 | .byte $01 ; Destination Code: USA 9 | .byte $33 ; Fixed value 10 | .byte $00 ; Mask ROM Version 11 | .word $0000 ; Complement Check 12 | .word $0000 ; Check Sum 13 | 14 | ; native mode vectors 15 | .word 0, 0 16 | .addr _rti ; COP 17 | .addr _rti ; BRK 18 | .addr _rti ; ABORT 19 | .addr nmi ; NMI 20 | .addr start ; RST 21 | .addr _rti ; IRQ 22 | 23 | ; emulation mode vectors - largely unused, since we run in native mode 24 | .word 0, 0 25 | .addr 0 26 | .addr 0 27 | .addr 0 28 | .addr 0 29 | .addr start ; RST 30 | .addr 0 31 | -------------------------------------------------------------------------------- /part1/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part2/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part3/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part4/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part5/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part6/src/init.asm: -------------------------------------------------------------------------------- 1 | ; A very simple SNES init routine 2 | ; For serious use, you probably want to do more than this 3 | ; This is simple and understandable, though 4 | ; Will leave you in A8 XY16 mode 5 | 6 | ; Disable interrupts and enable native mode 7 | sei 8 | clc 9 | xce 10 | cld 11 | 12 | setAXY16 13 | 14 | ; ZeroCPU registers NMITIMEN through MEMSEL 15 | stz $4200 16 | stz $4202 17 | stz $4204 18 | stz $4206 19 | stz $4208 20 | stz $420A 21 | stz $420C 22 | 23 | lda #$0080 24 | sta INIDISP ; Turn off screen ("forced blank") 25 | 26 | ; Zero some registers used for rendering 27 | stz OAMADDL 28 | stz BGMODE 29 | stz BG1SC 30 | stz BG3SC 31 | stz BG12NBA 32 | stz VMADDL 33 | stz W12SEL 34 | stz WH0 35 | stz WH2 36 | stz WBGLOG 37 | stz TM 38 | stz TMW 39 | 40 | ; Disable color math / etc 41 | ldx #$0030 42 | stx CGWSEL 43 | ldy #$00E0 44 | sty COLDATA 45 | 46 | setA8 47 | 48 | ; Zero window masks 49 | stz WOBJSEL 50 | -------------------------------------------------------------------------------- /part2/src/charset.asm: -------------------------------------------------------------------------------- 1 | charset: 2 | 3 | ; tile 0x00 4 | .byte %00000000 5 | .byte %00000000 6 | .byte %00000000 7 | .byte %00000000 8 | .byte %00000000 9 | .byte %00000000 10 | .byte %00000000 11 | .byte %00000000 12 | .byte %00000000 13 | .byte %00000000 14 | .byte %00000000 15 | .byte %00000000 16 | .byte %00000000 17 | .byte %00000000 18 | .byte %00000000 19 | .byte %00000000 20 | 21 | ; tile 0x01 22 | .byte %11111111 ; row 0, color 0 23 | .byte %00000000 ; row 0, color 1 24 | .byte %10000001 ; row 1, color 0 25 | .byte %00000000 ; row 1, color 1 26 | .byte %10000001 ; row 2, color 0 27 | .byte %00000000 ; row 2, color 1 28 | .byte %10000001 ; row 3, color 0 29 | .byte %00001000 ; row 3, color 1 30 | .byte %10011001 ; row 4, color 0 31 | .byte %00001000 ; row 4, color 1 32 | .byte %10000001 ; row 5, color 0 33 | .byte %00000000 ; row 5, color 1 34 | .byte %10000001 ; row 6, color 0 35 | .byte %00000000 ; row 6, color 1 36 | .byte %11111111 ; row 7, color 0 37 | .byte %00000000 ; row 7, color 1 38 | 39 | charset_end: 40 | -------------------------------------------------------------------------------- /part3/src/charset.asm: -------------------------------------------------------------------------------- 1 | charset: 2 | 3 | ; tile 0x00 4 | .byte %00000000 5 | .byte %00000000 6 | .byte %00000000 7 | .byte %00000000 8 | .byte %00000000 9 | .byte %00000000 10 | .byte %00000000 11 | .byte %00000000 12 | .byte %00000000 13 | .byte %00000000 14 | .byte %00000000 15 | .byte %00000000 16 | .byte %00000000 17 | .byte %00000000 18 | .byte %00000000 19 | .byte %00000000 20 | 21 | ; tile 0x01 22 | .byte %11111111 ; row 0, color 0 23 | .byte %00000000 ; row 0, color 1 24 | .byte %10000001 ; row 1, color 0 25 | .byte %00000000 ; row 1, color 1 26 | .byte %10000001 ; row 2, color 0 27 | .byte %00000000 ; row 2, color 1 28 | .byte %10000001 ; row 3, color 0 29 | .byte %00001000 ; row 3, color 1 30 | .byte %10011001 ; row 4, color 0 31 | .byte %00001000 ; row 4, color 1 32 | .byte %10000001 ; row 5, color 0 33 | .byte %00000000 ; row 5, color 1 34 | .byte %10000001 ; row 6, color 0 35 | .byte %00000000 ; row 6, color 1 36 | .byte %11111111 ; row 7, color 0 37 | .byte %00000000 ; row 7, color 1 38 | 39 | charset_end: 40 | -------------------------------------------------------------------------------- /part4/src/charset.asm: -------------------------------------------------------------------------------- 1 | charset: 2 | 3 | ; tile 0x00 4 | .byte %00000000 5 | .byte %00000000 6 | .byte %00000000 7 | .byte %00000000 8 | .byte %00000000 9 | .byte %00000000 10 | .byte %00000000 11 | .byte %00000000 12 | .byte %00000000 13 | .byte %00000000 14 | .byte %00000000 15 | .byte %00000000 16 | .byte %00000000 17 | .byte %00000000 18 | .byte %00000000 19 | .byte %00000000 20 | 21 | ; tile 0x01 22 | .byte %11111111 ; row 0, color 0 23 | .byte %00000000 ; row 0, color 1 24 | .byte %10000001 ; row 1, color 0 25 | .byte %00000000 ; row 1, color 1 26 | .byte %10000001 ; row 2, color 0 27 | .byte %00000000 ; row 2, color 1 28 | .byte %10000001 ; row 3, color 0 29 | .byte %00001000 ; row 3, color 1 30 | .byte %10011001 ; row 4, color 0 31 | .byte %00001000 ; row 4, color 1 32 | .byte %10000001 ; row 5, color 0 33 | .byte %00000000 ; row 5, color 1 34 | .byte %10000001 ; row 6, color 0 35 | .byte %00000000 ; row 6, color 1 36 | .byte %11111111 ; row 7, color 0 37 | .byte %00000000 ; row 7, color 1 38 | 39 | charset_end: 40 | -------------------------------------------------------------------------------- /part5/src/charset.asm: -------------------------------------------------------------------------------- 1 | charset: 2 | 3 | ; tile 0x00 4 | .byte %00000000 5 | .byte %00000000 6 | .byte %00000000 7 | .byte %00000000 8 | .byte %00000000 9 | .byte %00000000 10 | .byte %00000000 11 | .byte %00000000 12 | .byte %00000000 13 | .byte %00000000 14 | .byte %00000000 15 | .byte %00000000 16 | .byte %00000000 17 | .byte %00000000 18 | .byte %00000000 19 | .byte %00000000 20 | 21 | ; tile 0x01 22 | .byte %11111111 ; row 0, color 0 23 | .byte %00000000 ; row 0, color 1 24 | .byte %10000001 ; row 1, color 0 25 | .byte %00000000 ; row 1, color 1 26 | .byte %10000001 ; row 2, color 0 27 | .byte %00000000 ; row 2, color 1 28 | .byte %10000001 ; row 3, color 0 29 | .byte %00001000 ; row 3, color 1 30 | .byte %10011001 ; row 4, color 0 31 | .byte %00001000 ; row 4, color 1 32 | .byte %10000001 ; row 5, color 0 33 | .byte %00000000 ; row 5, color 1 34 | .byte %10000001 ; row 6, color 0 35 | .byte %00000000 ; row 6, color 1 36 | .byte %11111111 ; row 7, color 0 37 | .byte %00000000 ; row 7, color 1 38 | 39 | charset_end: 40 | -------------------------------------------------------------------------------- /part1/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part2/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part3/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part4/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part5/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part6/src/lorom.cfg: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZEROPAGE: start = $000000, size = $0100; 3 | STACK: start = $000100, size = $0100; 4 | BSS: start = $000200, size = $1E00; 5 | BSS7E: start = $7E2000, size = $E000; 6 | BSS7F: start = $7F0000, size =$10000; 7 | 8 | ROM0: start = $808000, size = $8000, fill = yes; 9 | ROM1: start = $818000, size = $8000, fill = yes; 10 | ROM2: start = $828000, size = $8000, fill = yes; 11 | ROM3: start = $838000, size = $8000, fill = yes; 12 | ROM4: start = $848000, size = $8000, fill = yes; 13 | ROM5: start = $858000, size = $8000, fill = yes; 14 | ROM6: start = $868000, size = $8000, fill = yes; 15 | ROM7: start = $878000, size = $8000, fill = yes; 16 | } 17 | 18 | SEGMENTS { 19 | CODE: load = ROM0, align = $100; 20 | HEADER: load = ROM0, start = $80FFC0; 21 | CODE1: load = ROM1, align = $100, optional=yes; 22 | CODE2: load = ROM2, align = $100, optional=yes; 23 | CODE3: load = ROM3, align = $100, optional=yes; 24 | CODE4: load = ROM4, align = $100, optional=yes; 25 | CODE5: load = ROM5, align = $100, optional=yes; 26 | CODE6: load = ROM6, align = $100, optional=yes; 27 | CODE7: load = ROM7, align = $100, optional=yes; 28 | 29 | ZEROPAGE: load = ZEROPAGE, type = zp, define=yes; 30 | BSS: load = BSS, type = bss, align = $100, optional=yes; 31 | BSS7E: load = BSS7E, type = bss, align = $100, optional=yes; 32 | BSS7F: load = BSS7F, type = bss, align = $100, optional=yes; 33 | } 34 | -------------------------------------------------------------------------------- /part2/src/main.asm: -------------------------------------------------------------------------------- 1 | .p816 2 | .smart 3 | 4 | .include "macros.inc" 5 | .include "registers.inc" 6 | 7 | .include "header.asm" 8 | 9 | .segment "CODE" 10 | 11 | VRAM_CHARS = $0000 12 | VRAM_BG1 = $1000 13 | 14 | start: 15 | .include "init.asm" 16 | 17 | ; Set up the color palette 18 | stz CGADD 19 | ; Color 0 = black 20 | lda #$00 21 | sta CGDATA 22 | lda #$00 23 | sta CGDATA 24 | ; Color 1 = red 25 | lda #$1f 26 | sta CGDATA 27 | lda #$00 28 | sta CGDATA 29 | ; Color 2 = blue 30 | lda #$e0 31 | sta CGDATA 32 | lda #$03 33 | sta CGDATA 34 | ; Color 3 = green 35 | lda #$00 36 | sta CGDATA 37 | lda #$7c 38 | sta CGDATA 39 | 40 | ; Set Graphics Mode 0, 8x8 tiles 41 | stz BGMODE 42 | 43 | ; Set BG1 and tile map and character data 44 | lda #>VRAM_BG1 45 | sta BG1SC 46 | lda #VRAM_CHARS 47 | sta BG12NBA 48 | 49 | ; Load character data into VRAM 50 | lda #$80 51 | sta VMAIN 52 | ldx #VRAM_CHARS 53 | stx VMADDL 54 | ldx #0 55 | @charset_loop: 56 | lda charset,x 57 | sta VMDATAL 58 | inx 59 | lda charset,x 60 | sta VMDATAH 61 | inx 62 | cpx #(charset_end - charset) 63 | bne @charset_loop 64 | 65 | ; Write a tile to position (1, 1) 66 | TILE_X = 1 67 | TILE_Y = 1 68 | ldx #(VRAM_BG1 + (TILE_Y * 32) + TILE_X) 69 | stx VMADDL 70 | lda #$01 ; tile number 71 | sta VMDATAL 72 | stz VMDATAH 73 | 74 | ; Show BG1 75 | lda #%00000001 76 | sta TM 77 | 78 | lda #$0f 79 | sta INIDISP 80 | 81 | busywait: 82 | bra busywait 83 | 84 | nmi: 85 | bit RDNMI 86 | _rti: 87 | rti 88 | 89 | .include "charset.asm" 90 | -------------------------------------------------------------------------------- /part3/src/main.asm: -------------------------------------------------------------------------------- 1 | .p816 2 | .smart 3 | 4 | .include "macros.inc" 5 | .include "registers.inc" 6 | 7 | .include "header.asm" 8 | 9 | .segment "CODE" 10 | 11 | VRAM_CHARS = $0000 12 | VRAM_BG1 = $1000 13 | 14 | start: 15 | .include "init.asm" 16 | 17 | ; Set up the color palette 18 | stz CGADD 19 | ; Color 0 = black 20 | lda #$00 21 | sta CGDATA 22 | lda #$00 23 | sta CGDATA 24 | ; Color 1 = red 25 | lda #$1f 26 | sta CGDATA 27 | lda #$00 28 | sta CGDATA 29 | ; Color 2 = blue 30 | lda #$e0 31 | sta CGDATA 32 | lda #$03 33 | sta CGDATA 34 | ; Color 3 = green 35 | lda #$00 36 | sta CGDATA 37 | lda #$7c 38 | sta CGDATA 39 | 40 | ; Set Graphics Mode 0, 8x8 tiles 41 | stz BGMODE 42 | 43 | ; Set BG1 and tile map and character data 44 | lda #>VRAM_BG1 45 | sta BG1SC 46 | lda #VRAM_CHARS 47 | sta BG12NBA 48 | 49 | ; Load character data into VRAM 50 | lda #$80 51 | sta VMAIN 52 | ldx #VRAM_CHARS 53 | stx VMADDL 54 | ldx #0 55 | @charset_loop: 56 | lda charset,x 57 | sta VMDATAL 58 | inx 59 | lda charset,x 60 | sta VMDATAH 61 | inx 62 | cpx #(charset_end - charset) 63 | bne @charset_loop 64 | 65 | ; Show BG1 66 | lda #%00000001 67 | sta TM 68 | 69 | lda #$0f 70 | sta INIDISP 71 | 72 | lda #%00000001 73 | sta NMITIMEN 74 | 75 | mainloop: 76 | lda JOY1H 77 | bit #%00000100 ; Down button 78 | beq @down_not_pressed 79 | ldx #(VRAM_BG1 + (1 * 32) + 1) 80 | stx VMADDL 81 | lda #$01 ; tile number 82 | sta VMDATAL 83 | stz VMDATAH 84 | @down_not_pressed: 85 | 86 | bra mainloop 87 | 88 | nmi: 89 | bit RDNMI 90 | _rti: 91 | rti 92 | 93 | .include "charset.asm" 94 | -------------------------------------------------------------------------------- /part4/src/main.asm: -------------------------------------------------------------------------------- 1 | .p816 2 | .smart 3 | 4 | .include "macros.inc" 5 | .include "registers.inc" 6 | 7 | .include "header.asm" 8 | 9 | .segment "ZEROPAGE" 10 | nmi_count: .res 2 11 | 12 | .segment "CODE" 13 | 14 | VRAM_CHARS = $0000 15 | VRAM_BG1 = $1000 16 | 17 | start: 18 | .include "init.asm" 19 | 20 | ; Set up the color palette 21 | stz CGADD 22 | ; Color 0 = black 23 | lda #$00 24 | sta CGDATA 25 | lda #$00 26 | sta CGDATA 27 | ; Color 1 = red 28 | lda #$1f 29 | sta CGDATA 30 | lda #$00 31 | sta CGDATA 32 | ; Color 2 = blue 33 | lda #$e0 34 | sta CGDATA 35 | lda #$03 36 | sta CGDATA 37 | ; Color 3 = green 38 | lda #$00 39 | sta CGDATA 40 | lda #$7c 41 | sta CGDATA 42 | 43 | ; Set Graphics Mode 0, 8x8 tiles 44 | stz BGMODE 45 | 46 | ; Set BG1 and tile map and character data 47 | lda #>VRAM_BG1 48 | sta BG1SC 49 | lda #VRAM_CHARS 50 | sta BG12NBA 51 | 52 | ; Load character data into VRAM 53 | lda #$80 54 | sta VMAIN 55 | ldx #VRAM_CHARS 56 | stx VMADDL 57 | ldx #0 58 | @charset_loop: 59 | lda charset,x 60 | sta VMDATAL 61 | inx 62 | lda charset,x 63 | sta VMDATAH 64 | inx 65 | cpx #(charset_end - charset) 66 | bne @charset_loop 67 | 68 | ; Show BG1 69 | lda #%00000001 70 | sta TM 71 | 72 | lda #$0f 73 | sta INIDISP 74 | 75 | lda #%10000001 76 | sta NMITIMEN 77 | 78 | mainloop: 79 | 80 | lda nmi_count 81 | @nmi_check: 82 | wai 83 | cmp nmi_count 84 | beq @nmi_check 85 | 86 | lda JOY1H 87 | bit #%00000100 ; Down button 88 | beq @down_not_pressed 89 | ldx #(VRAM_BG1 + (1 * 32) + 1) 90 | stx VMADDL 91 | lda #$01 ; tile number 92 | sta VMDATAL 93 | stz VMDATAH 94 | @down_not_pressed: 95 | 96 | bra mainloop 97 | 98 | nmi: 99 | bit RDNMI 100 | inc nmi_count 101 | _rti: 102 | rti 103 | 104 | .include "charset.asm" 105 | -------------------------------------------------------------------------------- /part5/src/main.asm: -------------------------------------------------------------------------------- 1 | .p816 2 | .smart 3 | 4 | .include "macros.inc" 5 | .include "registers.inc" 6 | 7 | .include "header.asm" 8 | 9 | .segment "ZEROPAGE" 10 | nmi_count: .res 2 11 | 12 | .segment "CODE" 13 | 14 | VRAM_CHARS = $0000 15 | VRAM_BG1 = $1000 16 | 17 | start: 18 | .include "init.asm" 19 | 20 | ; Set up the color palette 21 | stz CGADD 22 | ; Color 0 = black 23 | lda #$00 24 | sta CGDATA 25 | lda #$00 26 | sta CGDATA 27 | ; Color 1 = red 28 | lda #$1f 29 | sta CGDATA 30 | lda #$00 31 | sta CGDATA 32 | ; Color 2 = blue 33 | lda #$e0 34 | sta CGDATA 35 | lda #$03 36 | sta CGDATA 37 | ; Color 3 = green 38 | lda #$00 39 | sta CGDATA 40 | lda #$7c 41 | sta CGDATA 42 | 43 | ; Set Graphics Mode 0, 8x8 tiles 44 | stz BGMODE 45 | 46 | ; Set BG1 and tile map and character data 47 | lda #>VRAM_BG1 48 | sta BG1SC 49 | lda #VRAM_CHARS 50 | sta BG12NBA 51 | 52 | ; Load character data into VRAM 53 | lda #$80 54 | sta VMAIN 55 | ldx #VRAM_CHARS 56 | stx VMADDL 57 | lda #%00000001 58 | sta DMAP0 59 | lda #VRAM_BG1 62 | sta BG1SC 63 | lda #VRAM_CHARS 64 | sta BG12NBA 65 | 66 | ; Load character data into VRAM 67 | lda #$80 68 | sta VMAIN 69 | ldx #VRAM_CHARS 70 | stx VMADDL 71 | lda #%00000001 72 | sta DMAP0 73 | lda #