aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/1.s176
1 files changed, 157 insertions, 19 deletions
diff --git a/src/1.s b/src/1.s
index 2980951..202c3ee 100644
--- a/src/1.s
+++ b/src/1.s
@@ -2,13 +2,8 @@
;; Day 1 https://adventofcode.com/2023/day/1
;;
;; This program then iterates over the array on `data` and computes the value on
-;; each row, then accumulating it into a sum variable. This variable is stored
-;; as a 16-bit number on $08-$09. In order to see the actual result, in FCEUX,
-;; for example, you need to go to `Tools -> RAM Watch`, and set a watch on
-;; address $08 which is unsigned and 2-bytes long. This will show you the end
-;; result after a couple of seconds (yes, it's a big ass computation for poor
-;; old NES, and it's quite fast considering that we are not rendering anything
-;; on screen!). The result must be: `54953`.
+;; each row, then accumulating it into a sum variable. The end result will be
+;; printed to the screen, which must be `54953`.
;; Luckily for us, good ol' NROM can fit the data set for this exercise :D
.segment "HEADER"
@@ -24,6 +19,8 @@
.addr nmi, reset, irq
.segment "CHARS"
+ .incbin "../assets/alphanum.chr"
+
.segment "STARTUP"
.segment "CODE"
@@ -32,6 +29,7 @@
.include "../include/ppu.s"
.include "../include/reset.s"
.include "../include/globals.s"
+.include "../vendor/bcd16.s"
;; "Variables" used by this program.
.scope Vars
@@ -80,23 +78,24 @@
;; The main function will be called at the end of the `reset` vector as defined
;; in `include/reset.s`.
.proc main
- cli
-
- lda #%10010000
- sta PPU::CONTROL
- lda #%00011110
- sta PPU::MASK
-
- ;; Initialize variables being used for this program.
+ ;; Initialize palettes and variables being used for this program.
+ jsr init_palettes
jsr Vars::init
;; This program uses two flags:
- ;; - 7 (`render`): whether NMI-code can render stuff on screen. Unused but
- ;; reserved out of habit.
+ ;; - 7 (`render`): whether NMI-code can render stuff on screen.
;; - 6 (`done`): whether the computation has been done.
- lda #0
+ ;; Note that we are setting the render flag so the initial message is
+ ;; shown.
+ lda #%10000000
sta Globals::m_flags
+ cli
+
+ lda #%10010000
+ sta PPU::CONTROL
+ lda #%00011110
+ sta PPU::MASK
@loop:
jsr compute_next
jmp @loop
@@ -187,6 +186,17 @@
lda #%01000000
ora Globals::m_flags
sta Globals::m_flags
+
+ ;; Now that we are done, convert the 16-bit number into separate bytes so it
+ ;; can be rendered on NMI-code.
+ lda Vars::m_sum + 1
+ sta bcdNum
+ lda Vars::m_sum
+ sta bcdNum + 1
+ jsr bcdConvert
+
+ ;; Because of the previous, we can set the `render` flag again.
+ SET_RENDER_FLAG
@end:
rts
.endproc
@@ -221,8 +231,136 @@
rts
.endproc
-;; Unused.
+;; init_palettes copies all the palettes into the proper PPU address.
+.proc init_palettes
+ PPU_ADDR $3F00
+
+ ldx #0
+@load_palettes_loop:
+ lda palettes, x
+ sta PPU::DATA
+ inx
+ cpx #$20
+ bne @load_palettes_loop
+ rts
+palettes:
+ ;; Background (only first one used)
+ .byte $0F, $30, $10, $00
+ .byte $0F, $00, $00, $00
+ .byte $0F, $00, $00, $00
+ .byte $0F, $00, $00, $00
+
+ ;; Foreground (unused)
+ .byte $0F, $00, $00, $00
+ .byte $0F, $00, $00, $00
+ .byte $0F, $00, $00, $00
+ .byte $0F, $00, $00, $00
+.endproc
+
+;; Non-Maskable Interrupts handler.
nmi:
+ bit PPU::STATUS
+
+ ;; Skip rendering if the `render` flag is not set.
+ bit Globals::m_flags
+ bpl @nmi_next
+
+ ;; Backup registers.
+ pha
+ txa
+ pha
+ tya
+ pha
+
+ ;; If the result is not there yet, then we just print an initial message.
+ ;; Otherwise print the given result.
+ bit Globals::m_flags
+ bvs :+
+ jsr print_message
+ jmp :++
+:
+ jsr print_result
+:
+
+ ;; Reset the scroll.
+ bit PPU::STATUS
+ lda #$00
+ sta PPU::SCROLL
+ sta PPU::SCROLL
+
+ ;; And unset the render flag so the `main` code is unblocked.
+ UNSET_RENDER_FLAG
+
+ ;; Restore registers.
+ pla
+ tay
+ pla
+ tax
+ pla
+@nmi_next:
+ rti
+
+;; Simply print "Please wait..." to the screen.
+.proc print_message
+ WRITE_PPU_DATA $2129, $2A
+ WRITE_PPU_DATA $212A, $26
+ WRITE_PPU_DATA $212B, $1F
+ WRITE_PPU_DATA $212C, $1B
+ WRITE_PPU_DATA $212D, $2D
+ WRITE_PPU_DATA $212E, $1F
+
+ WRITE_PPU_DATA $2130, $31
+ WRITE_PPU_DATA $2131, $1B
+ WRITE_PPU_DATA $2132, $23
+ WRITE_PPU_DATA $2133, $2E
+ WRITE_PPU_DATA $2134, $36
+ WRITE_PPU_DATA $2135, $36
+ WRITE_PPU_DATA $2136, $36
+
+ rts
+.endproc
+
+;; Print the result on screen. This assumes that `bcdResult` already contains
+;; the proper data.
+.proc print_result
+ ;; Clear tiles that were written by `print_message` and that are not re-used
+ ;; here.
+ WRITE_PPU_DATA $2129, $00
+ WRITE_PPU_DATA $212A, $00
+ WRITE_PPU_DATA $212B, $00
+ WRITE_PPU_DATA $212C, $00
+ WRITE_PPU_DATA $212D, $00
+ WRITE_PPU_DATA $2133, $00
+ WRITE_PPU_DATA $2134, $00
+ WRITE_PPU_DATA $2135, $00
+ WRITE_PPU_DATA $2136, $00
+
+ ;; And loop so PPU::ADDRESS $2E21-$2E32 has the data as stored on bcdResult,
+ ;; which is the binary to decimal conversion result when the final
+ ;; computation was done.
+ ldx #4
+ ldy #$2E
+@loop:
+ ;; PPU address.
+ bit PPU::STATUS
+ lda #$21
+ sta PPU::ADDRESS
+ sty PPU::ADDRESS
+
+ ;; PPU data.
+ lda bcdResult, x
+ clc
+ adc #$10
+ sta PPU::DATA
+ dex
+ iny
+ cpy #$33
+ bne @loop
+
+ rts
+.endproc
+
+;; Unused.
irq:
rti