Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Wave effect. Disable music for now.

  • Loading branch information...
commit 13c8cacbf6f2b4401b2195dd147224c9656aa4da 1 parent 42bca2f
Andy Hefner authored

Showing 1 changed file with 165 additions and 45 deletions. Show diff stats Hide diff stats

  1. +165 45 hacks/ryden.lisp
210 hacks/ryden.lisp
@@ -30,6 +30,8 @@
30 30
31 31 (let* ((global (make-instance 'basic-context :address #x8000))
32 32 (*context* global)
  33 + (num-wavy-lines (* 3 26)) ; Must be multiple of 3 !
  34 + (log2-wavy-period 6)
33 35 ;; Music:
34 36 (music (binary-file (merge-pathnames "noisejam.nsf" *path*)))
35 37 (music-init (mem #x8080)) ; Hardcoding these..
@@ -39,10 +41,15 @@
39 41 (table-x #x0200)
40 42 (table-y #x0240)
41 43 (countdown (zp #x58))
  44 + (wave (zp #x59))
  45 + (wt-lsb (zp #x60))
  46 + (wt-msb (zp #x61))
  47 + (wt-get (indi #x60))
42 48 (fill-count (zp #x91))
43 49 (scroll-x (zp #x92))
44 50 (phase (zp #x93))
45 51 (ntaddr (zp #x95))
  52 + (top-ntaddr (zp #x97))
46 53 (vblank-flag (zp #x96))) ; Set by NMI handler.
47 54
48 55 (emit music)
@@ -80,8 +87,8 @@
80 87
81 88 ;; Program palette.
82 89 (ppuaddr #x3F00)
83   - (dolist (color '(#x3F #x2D #x3D #x30 #x3F #x05 #x15 #x25
84   - #x3F #x2D #x3D #x30 #x3F #x03 #x13 #x23
  90 + (dolist (color '(#x3F #x2D #x3D #x30 #x3F #x03 #x13 #x23
  91 + #x3F #x2D #x3D #x30 #x3F #x05 #x15 #x25
85 92 #x3F #x3F #x27 #x37))
86 93 (poke color +vram-io+))
87 94
@@ -89,11 +96,14 @@
89 96 (sta scroll-x)
90 97 (lda (imm 0))
91 98 (sta ntaddr)
  99 + (sta wave)
92 100 (lda (imm 160))
93 101 (sta phase)
94 102
95 103 (jsr 'initialize-sprites)
96 104
  105 + (jsr 'update-sprites)
  106 +
97 107 (align 256 #xEA) ; Pad with NOPs to next page
98 108 (poke #b10001000 +ppu-cr1+) ; Enable NMI
99 109
@@ -121,9 +131,17 @@
121 131 (repeat 3
122 132 (repeat 128 split-by-4)
123 133 (repeat 128 linearly))
  134 + ;; Compare/contrast:
  135 + (repeat 2
  136 + (repeat 128
  137 + (jsr 'spin-apart)
  138 + (jsr 'linearly))
  139 + (repeat 128 linearly)
  140 + (repeat 128 split-by-4)
  141 + (repeat 128 linearly))
124 142 (repeat 64 split-by-4)
125 143 (repeat 96 linearly)
126   - ;; Time to change the effect.
  144 + ;; Change it up.
127 145 (repeat 256 spin-apart)
128 146 (repeat 96 linearly)
129 147 ;; A little more intense..
@@ -138,15 +156,16 @@
138 156 ;; Rest and repeat. Come a little unglued.
139 157 (repeat 256 spin-apart)
140 158 (repeat 253 spin-apart)
  159 +
141 160 (jmp (mem 'mainloop)))))
142 161
  162 + (align 256)
143 163 (procedure framestep
144   - (jsr 'update-sprites)
145 164 (jsr 'wait-for-vblank)
146   -
147 165 (lda (mem +ppu-status+)) ; Reset PPU address latch.
148 166 (lda (imm (msb sprite-table))) ; Sprite DMA transfer.
149 167 (sta (mem +sprite-dma+))
  168 +
150 169 (lda (mem +ppu-status+)) ; Reset address latch, to be safe.
151 170 (ldx phase) ; 'phase' steps through rate-pattern
152 171 (inx)
@@ -155,28 +174,108 @@
155 174 (clc) ; Update scroll-x by rate-pattern
156 175 (adc (abx 'rate-pattern)) ; Add. Use the carry-out below!
157 176 (sta scroll-x)
158   - (sta (mem +vram-scroll+)) ; Set scroll registers
159 177 (lda ntaddr) ; Carry into ntaddr
160 178 (adc (imm 0)) ; ** Carry in from ADC above. **
161   - (anda (imm 1)) ; Carry toggles $2000/$2400
  179 + (anda (imm #b00000001)) ; Carry toggles $2000/$2400
  180 + ;; (*) Subtle: I had to bum an instruction out of the scanline kernel, so
  181 + ;; I store this with bit 4 inverted, as the bottom half of the screen
  182 + ;; requires.
  183 + (eor (imm #b10011000)) ; NMI on, invert BG Pattern address! (*)
162 184 (sta ntaddr)
163   - (ora (imm #b10001000)) ; NMI on, BG Pattern table $0000
  185 +
  186 + ;; This got a little messy. Arithmetic for the bottom half of the screen
  187 + ;; is biased by 128, because it's easier than screwing with the overflow
  188 + ;; flag (the wave offsets are signed). Must adjust the top half to match.
  189 + ;; There's also the issue of the gap between the screen split and the wave
  190 + ;; effect, which also needs the correct value from here ("top-ntaddr").
  191 + (lda scroll-x)
  192 + (clc)
  193 + (adc (imm 128))
  194 + (sta (mem +vram-scroll+))
  195 + (lda ntaddr) ; Carry into NT address.
  196 + (adc (imm 0)) ; (okay if it carries again)
  197 + (eor (imm #b00010000)) ; Flip pattern table address.
  198 + (sta top-ntaddr) ; Reuse this after the split.
164 199 (sta (mem +ppu-cr1+))
  200 +
165 201 (poke #b00011110 +ppu-cr2+) ; BG and sprites on.
166 202 (lda (imm 0))
167 203 (sta (mem +vram-scroll+))
  204 +
  205 + (jsr 'update-sprites)
  206 +
168 207 ;; Switch pattern tables mid-frame:
169   - (emit-delay (+ (* 114 143) -15))
170   - (lda ntaddr)
171   - (ora (imm #b10011000)) ; NMI on, BG Pattern table $1000
  208 + (emit-delay (+ (* 114 107) 40))
  209 + (lda top-ntaddr)
  210 + (eor (imm #b10010000)) ; Invert pattern bank.
172 211 (sta (mem +ppu-cr1+))
173 212
174   - (jsr music-step)
  213 + ;; In theory, the music player will run here.
  214 + (emit-delay (round (* 113.66 14)))
  215 +
  216 + ;; Wavy effect
  217 + (flet ((kernel ()
  218 + (poke #b00011110 +ppu-cr2+)
  219 + (clc)
  220 + (lda wt-get) ; Get wave offset
  221 + (adc scroll-x) ; Add to BG scroll position
  222 + (sta (mem +vram-scroll+))
  223 + (lda (imm 0))
  224 + (sta (mem +vram-scroll+))
  225 + (lda ntaddr) ; Carry in. Effectively, scroll-x and
  226 + (adc (imm 0)) ; ntaddr.0 form a 9-bit field.
  227 + (sta (mem +ppu-cr1+))
  228 + (poke #b00011110 +ppu-cr2+)))
  229 +
  230 + ;; Setup for wave effect.. load table pointer into zero page.
  231 + (lda (imm (lsb (label 'wave-offsets))))
  232 + (sta wt-lsb)
  233 + (ldx wave) ; Increment wave counter..
  234 + (inx)
  235 + (stx wave)
  236 + (txa)
  237 + (anda (imm (1- (expt 2 log2-wavy-period)))) ; Modulo cycle length..
  238 + (clc)
  239 + (adc (imm (msb (label 'wave-offsets)))) ; Step MSB each frame..
  240 + (sta wt-msb)
  241 +
  242 + (emit-delay 48) ; Realign with hblank
  243 +
  244 + (ldy (imm num-wavy-lines))
  245 +
  246 + (loop repeat (/ num-wavy-lines 3) do
  247 + (print (list :kernel-cycles (counting-cycles (kernel) (dey))))
  248 + (loop repeat 14 do (inc (zp 0)))
  249 + (print (list :kernel-cycles (counting-cycles (kernel) (dey))))
  250 + (nop)
  251 + (loop repeat 14 do (inc (zp 0)))
  252 + (print (list :kernel-cycles (counting-cycles (kernel) (dey))))
  253 + (loop repeat 14 do (inc (zp 0))))
  254 +
  255 + ;; This version works okay, but unrolling it as above works better.
  256 + #+(or)
  257 + (with-label loop
  258 + (timed-section (114) (kernel) (dey))
  259 + (timed-section (114) (kernel) (dey))
  260 + (timed-section (108) (kernel))
  261 + ;; Fun fact: timed-section is a piece of crap.
  262 + (cmp (zp 0)) ; Burn 3 cycles.
  263 +
  264 + (dey)
  265 + (bne 'loop)))
  266 +
  267 + ;; Shut the screen off. Need a few extra scanlines here to update
  268 + ;; the sprite tables, and if I didn't shut it off, you'd notice
  269 + ;; the background stopped waving.
  270 + (loop repeat 10 do (nop)) ; Realign with hblank.. again.
  271 + (poke 0 +ppu-cr2+)
175 272
176 273 (rts))
177 274
178 275 ;; This table controls the scrolling.
179 276 (with-label rate-pattern
  277 +; (loop repeat 256 do (db 0))
  278 +
180 279 (let* ((tr '(1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1))
181 280 (pattern (subseq
182 281 (append (loop repeat (- 128 (reduce '+ tr))
@@ -245,42 +344,62 @@
245 344 (jsr 'framestep)
246 345 (ldx (imm 63))
247 346 (as/until :negative
248   - (inc (abx table-x))
249   - (inc (abx table-y))
250   - (dex))
  347 + (print
  348 + (counting-cycles
  349 + (inc (abx table-x))
  350 + (inc (abx table-y))
  351 + (dotimes (i 7) (nop))
  352 + (dex))))
251 353 (rts))
252 354
253 355 (procedure spin-apart
254 356 (jsr 'framestep)
255 357 (ldx (imm 63))
256 358 (as/until :negative
257   - (inc (abx table-x))
258   - (txa)
259   - (anda (imm 1))
260   - (clc)
261   - (adc (abx table-x))
262   - (sta (abx table-x))
263   - (dex))
  359 + (print
  360 + (counting-cycles
  361 + (inc (abx table-x))
  362 + (txa)
  363 + (anda (imm 1))
  364 + (clc)
  365 + (adc (abx table-x))
  366 + (sta (abx table-x))
  367 + (dotimes (i 3) (nop))
  368 + (dex))))
264 369 (rts))
265 370
266 371 (procedure split-by-4
267 372 (jsr 'framestep)
268 373 (ldx (imm 63))
269 374 (as/until :negative
270   - (inc (abx table-y))
271   - (txa)
272   - (anda (imm 16))
273   - (lsr)
274   - (lsr)
275   - (lsr)
276   - (clc)
277   - (adc (abx table-x))
278   - (sta (abx table-x))
279   - (dex))
  375 + (print
  376 + (counting-cycles
  377 + (inc (abx table-y))
  378 + (txa)
  379 + (anda (imm 16))
  380 + (lsr)
  381 + (lsr)
  382 + (lsr)
  383 + (clc)
  384 + (adc (abx table-x))
  385 + (sta (abx table-x))
  386 + (dex))))
  387 + (rts))
  388 +
  389 + (procedure wait-for-vblank
  390 + (as/until :not-zero (lda vblank-flag))
  391 + (lda (imm 0))
  392 + (sta vblank-flag)
280 393 (rts))
281 394
  395 + (procedure brk-handler (rti))
  396 +
  397 + (procedure vblank-handler
  398 + (inc vblank-flag)
  399 + (rti))
  400 +
  401 + (align 256)
282 402 (procedure update-sprites
283   - (brk) (db 1)
284 403 (ldx (imm 63))
285 404 (as/until :negative
286 405 (ldy (abx table-x)) ; Push sin[table_x[X]]
@@ -307,23 +426,24 @@
307 426 (dex)) ; Decrememnt sprite index
308 427 (rts))
309 428
310   - (procedure wait-for-vblank
311   - (as/until :not-zero (lda vblank-flag))
312   - (lda (imm 0))
313   - (sta vblank-flag)
314   - (rts))
315   -
316   - (procedure brk-handler (rti))
317   -
318   - (procedure vblank-handler
319   - (inc vblank-flag)
320   - (rti))
321   -
322 429 (align 256)
323 430 (with-label sine-table
324 431 (loop for i from 0 below 256
325 432 do (db (round (+ 124 (* 99 (sin (* 2 pi i 1/256))))))))
326 433
  434 + (with-label wave-offsets
  435 + (loop with nframes = (expt 2 log2-wavy-period)
  436 + for frame from (1- nframes) downto 0 do
  437 + (align 256)
  438 + (emit
  439 + ;; The wave loop counts from num-wavy-lines to 1. So, one extra here.
  440 + (loop for line from num-wavy-lines downto 0
  441 + with amp = 3
  442 + collect (mod (round ( + 128 ; bias to fix carry
  443 + (* amp (/ line 80)
  444 + (sin (* 2 pi (/ (+ (* 0.3 (expt line 1.54)) frame)
  445 + nframes))))))
  446 + 256)))))
327 447
328 448 ;; Interrupt vectors:
329 449 (advance-to +nmi-vector+)

0 comments on commit 13c8cac

Please sign in to comment.
Something went wrong with that request. Please try again.