From c978b673759d9ec4680a30ac2566fb1e94baeb35 Mon Sep 17 00:00:00 2001 From: Christian Johannesen Date: Fri, 16 Oct 2026 12:40:40 +0200 Subject: [PATCH] Stabilize Neon Rift graphics --- README.md | 2 +- neon-rift/neon-rift.asm | 142 +++++++++++++++++++++++++--------------- neon-rift/neon-rift.prg | Bin 1993 -> 2110 bytes programs.json | 2 +- 4 files changed, 93 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 17e53cf..472466e 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Browse and run the collection at [c64.p20.dev](https://c64.p20.dev). | PETSCII Aquarium | 2026-10-16 | Simulation | Machine Code | `F`, `1`-`3`, `Q` | Watch a tiny animated aquarium and feed its roaming fish. | [ASM](petscii-aquarium/petscii-aquarium.asm) | [Run](https://c64.p20.dev/program/petscii-aquarium) | | Fifteen Puzzle | 2026-10-16 | Puzzle | Machine Code | `W`, `A`, `S`, `D`, `R`, `Q` | Slide numbered tiles until the classic four-by-four board is restored. | [ASM](fifteen-puzzle/fifteen-puzzle.asm) | [Run](https://c64.p20.dev/program/fifteen-puzzle) | | Plasma Grid | 2026-10-16 | Demo | Machine Code | `1`-`3`, `C`, Space, `Q` | Fill the screen with a flowing field of color generated in real time. | [ASM](plasma-grid/plasma-grid.asm) | [Run](https://c64.p20.dev/program/plasma-grid) | -| Neon Rift | 2026-10-16 | Demo | Machine Code | `1`-`3`, `C`, `M`, Space, `Q` | Enter a raster-lit world of orbiting sprites, smooth scrolling, and a three-voice SID score. | [ASM](neon-rift/neon-rift.asm) | [Run](https://c64.p20.dev/program/neon-rift) | +| Neon Rift | 2026-10-16 | Demo | Machine Code | `1`-`3`, `C`, `M`, Space, `Q` | Enter a neon-colored world of orbiting sprites, a scrolling message, and a three-voice SID score. | [ASM](neon-rift/neon-rift.asm) | [Run](https://c64.p20.dev/program/neon-rift) | ## Running the programs diff --git a/neon-rift/neon-rift.asm b/neon-rift/neon-rift.asm index a51a5c1..aa5d7ee 100644 --- a/neon-rift/neon-rift.asm +++ b/neon-rift/neon-rift.asm @@ -1,8 +1,8 @@ !cpu 6510 ; NEON RIFT -; Raster bands, eight sine-orbiting sprites, a split fine scroller and a -; three-voice SID sequence. All state touched by the demo is restored on Q. +; Stable extended-color bands, eight sine-orbiting sprites, a character +; scroller and a three-voice SID sequence. All touched state is restored on Q. ; Self-starting BASIC line: 10 SYS2061 * = $0801 !word basic_end @@ -53,6 +53,14 @@ save_state: sta old_sprite_enable lda $d016 sta old_d016 + lda $d011 + sta old_d011 + lda $d022 + sta old_background_2 + lda $d023 + sta old_background_3 + lda $d024 + sta old_background_4 lda $d01c sta old_multicolor lda $d025 @@ -106,8 +114,15 @@ initialize_demo: sta motion_speed lda #7 sta scroll_fine + lda old_d011 + ora #$40 + sta $d011 + lda old_d016 + and #$f8 + sta $d016 jsr copy_sprite jsr prepare_screen + jsr apply_palette lda #$ff sta $d015 lda #6 @@ -160,12 +175,34 @@ clear_last_page: cpx #232 bne clear_last_page ldx #0 +paint_band_rows: + lda band_screen_codes,x + sta band_code + lda row_addresses_lo,x + sta $fb + lda row_addresses_hi,x + sta $fc + ldy #0 +paint_band_columns: + lda band_code + sta ($fb),y + iny + cpy #40 + bne paint_band_columns + inx + cpx #24 + bne paint_band_rows + ldx #0 draw_stars: lda star_positions_lo,x sta $fb lda star_positions_hi,x sta $fc ldy #0 + lda star_rows,x + tay + lda band_screen_codes,y + sta band_code txa and #1 beq use_dot @@ -174,6 +211,8 @@ draw_stars: use_dot: lda #46 store_star: + ora band_code + ldy #0 sta ($fb),y inx cpx #28 @@ -204,6 +243,7 @@ control_color: lda palette and #3 sta palette + jsr apply_palette jmp controls_done control_mute: cmp #77 @@ -266,16 +306,10 @@ update_motion: update_scroll: inc scroll_tick lda scroll_tick - cmp #2 + cmp #4 bcc motion_done lda #0 sta scroll_tick - dec scroll_fine - lda scroll_fine - and #7 - sta scroll_fine - cmp #7 - bne motion_done jsr shift_scroller motion_done: rts @@ -443,46 +477,32 @@ silence_sid: sta $d418 rts -draw_raster_frame: - ; Keep the KERNAL IRQ from interrupting a color change halfway through a - ; raster line. It is enabled again before returning to the main loop. - sei - lda #45 - jsr wait_raster - lda old_d016 - and #$f8 - sta $d016 +apply_palette: lda palette asl - asl - asl - tax - stx palette_base - ldx #0 -raster_band_loop: - stx band_index - lda raster_lines,x - jsr wait_raster - ldx band_index - txa clc - adc palette_base - tay - lda raster_colors,y - sta $d021 - ldx band_index + adc palette + tax + lda background_palettes,x + sta $d022 inx - cpx #8 - bne raster_band_loop - lda #232 - jsr wait_raster + lda background_palettes,x + sta $d023 + inx + lda background_palettes,x + sta $d024 lda #0 sta $d021 - lda old_d016 - and #$f8 - ora scroll_fine - sta $d016 - cli + rts + +draw_raster_frame: + ; The background is built from VIC-II extended-color character cells. + ; No registers are changed while the frame is being drawn, so the image + ; remains stable in browsers, recordings and the built-in pause mode. + lda old_d011 + ora #$40 + sta $d011 + jsr apply_palette rts wait_raster: @@ -527,6 +547,14 @@ restore_sid: sta $d015 lda old_d016 sta $d016 + lda old_d011 + sta $d011 + lda old_background_2 + sta $d022 + lda old_background_3 + sta $d023 + lda old_background_4 + sta $d024 lda old_multicolor sta $d01c lda old_sprite_mc0 @@ -565,7 +593,7 @@ splash_text: !text " NEON RIFT" !byte 13,13 !byte 5 -!text " RASTER LIGHT, SPRITES AND SID MUSIC" +!text " NEON COLOR, SPRITES AND SID MUSIC" !byte 13,13,13 !byte 153 !text " CONTROLS" @@ -624,12 +652,19 @@ sine_y: !byte 126,120,114,108,102,96,91,86,81,77,73,70,67,65,63,62 !byte 62,62,63,65,67,70,73,77,81,86,91,96,102,108,114,120 -raster_lines: !byte 56,78,100,122,144,166,188,210 -raster_colors: -!byte 6,11,4,14,3,13,1,13 -!byte 0,9,2,8,7,1,7,8 -!byte 0,6,14,3,1,3,14,6 -!byte 0,11,12,15,1,15,12,11 +background_palettes: +!byte 6,11,4 +!byte 9,2,8 +!byte 6,14,3 +!byte 11,12,15 +band_screen_codes: +!byte 96,96,96,160,160,160,224,224 +!byte 96,96,160,160,224,224,96,96 +!byte 160,160,224,224,96,96,160,160 +row_addresses_lo: +!for row,0,23 { !byte <($0400+row*40) } +row_addresses_hi: +!for row,0,23 { !byte >($0400+row*40) } sprite_colors: !byte 3,14,1,13,7,10,8,2 scroller_colors: !byte 3,14,7,10,13,1,8,2 @@ -640,7 +675,7 @@ bass_notes: !byte 0,0,0,0,3,3,3,3,5,5,5,5,3,3,1,1 drum_steps: !byte 1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0 scroll_message: -!text " NEON RIFT RASTER LIGHT MEETS EIGHT ORBITING SPRITES AND THREE VOICES OF SID GREETINGS FROM C64.P20.DEV " +!text " NEON RIFT NEON COLOR MEETS EIGHT ORBITING SPRITES AND THREE VOICES OF SID GREETINGS FROM C64.P20.DEV " !byte 0 star_positions_lo: @@ -664,6 +699,7 @@ position_temp: !byte 0 palette: !byte 0 palette_base: !byte 0 band_index: !byte 0 +band_code: !byte 0 scroll_tick: !byte 0 scroll_fine: !byte 0 scroll_position: !byte 0 @@ -677,6 +713,10 @@ old_border: !byte 0 old_background: !byte 0 old_sprite_enable: !byte 0 old_d016: !byte 0 +old_d011: !byte 0 +old_background_2: !byte 0 +old_background_3: !byte 0 +old_background_4: !byte 0 old_multicolor: !byte 0 old_sprite_mc0: !byte 0 old_sprite_mc1: !byte 0 diff --git a/neon-rift/neon-rift.prg b/neon-rift/neon-rift.prg index 872874ef221c5dd8a86cb30d77d92dfd69ce8bcc..5e5792f978793ebd76f0e939b7cf1fc387563964 100644 GIT binary patch delta 1171 zcmY*YO>7%g5MJAx-L*H}+4LtE2;#MInz#~(zanv>RY6b`no>9*A;BIv08*vifRh1H z2~`Yo`A+G5$B9=D_* z?0`H-xDE0E;SR`A!Y;@W!d;Mu2=9O#C%g-?K-dF0MyR=Rf-vRE!-Q#9x`Y{bRtq)q z^^zMmTx#>*B>DT@uw(jTY_e!gIYfSee;%f`7ih?dIV)f0h%10GU=wf)unl+{FacZ# z+yLB!AdRaKn0O21E@Y442+1xKJ2*<>`K)*;E3Vi<4-Zga;KVou4j!giEvWe&Gra8h zlcdroVxKL(%z0eJ4;44{Lg}1?YY=|robQHJ=lpI}lWTCXyHuN^t+jL~&YDEyikn11c=xG_byJh9wMKCQn&Mv&t7 zc=Z!B(rSWiLNUV+EpgG)XL9w|X_WhMGR3bZgKK1)Sm+~y9_5ZPqS~f<_Qe0-r^yO* z=0yd0hR=#4b$*tHIN>UItr%nsS689DkI9aqwE}VliZ3$POhl=bfJ~sSmn}vU5Z4tq z-~0m?a=Bdota6+Wm-paJxTI`z@+N$zQU5%^^B=m(rQqCmS-S6|2>(@4eTC^T}K zewPc~fJ>|g4fP1^2=_+eU(Vd(l7m{bNDii=;5b8J%tmrvLn~tJBQ&F6gx$lAlR$73 zohZm7M8W5LzqJW+6N*Y@N|N`&Vm|UzLHV;ycy2y?-@!u^t8IL+6^NY=l6Oy!+)VH4 zUZO64lCBqgU%8eUEe#E`2I_*g`6V{9QE+`N>dRm50PB@i%o^qxO3`Qa(F_Cfh_!+PrN&*rEj gUOo4%K3GHjWek?dtMZERUhaWJ3&umKO4%Ix7c_th*Z=?k delta 1060 zcmY*YU1%It6rR~#cXoHO^TkM#troqtH0cTzve-pL)gKu0}7q{++m5lsDTyw=#RxP5N9PhYl0ooP6Wz{L@r0C_u2k!Xpj1rno zL+#RZ25L~#S*RgR6{ww>&OzPf@MMOO(Twzm2 zzjE6I#NlPW?a&*(w1^9Eb_R3CDNqSC16lx`0xg09&>W}?nuko#G^9hb5N=lN$kt&G z55C}qquONdit9PCKj(A)$@(+)(}9D9&1g3k{=8&Wigq_8AJGZ<=!cu_)=vH7vL!`$ z)saqk_4{^ful~gsKi%mbZN8?{(&oB;^EvHxW}s$JOmaixzh;}S>LKRlfX$uhG*@Gr zc-u7|p&wxO*kdR({OuFhga7y+(;1oK=1uJ5d^Ura^L~8~SDS|4DM6KRa~ie#n2{1X zQ&3YVKFfsgOq~EKKr>MrW@mtJXQ5_MG(8W$Cm(752~%q44S4(fu}9IK_9 zZ(d0hAEKX~4x46>TZ;~Q%ho?+_I&20KAe0aC_|OeOxGs4@iNx=4J}H=}=!5jX~0j)Rr*WL8xME$SiQ1G40is6_4-3-foT}EidTcTEHL4yWvN}mJk zS}lS0XhonAt*T(LGvGV}Sh;uCh5jFtA1cG62* UZXay)x%Ec+t^dOxc82Z00pftNaR2}S diff --git a/programs.json b/programs.json index 40675b8..a5d2f6f 100644 --- a/programs.json +++ b/programs.json @@ -187,7 +187,7 @@ }, { "title": "Neon Rift", "category": "Demo", "language": "machine-code", "releaseDate": "2026-10-16", - "description": "Enter a raster-lit world of orbiting sprites, smooth scrolling, and a three-voice SID score.", + "description": "Enter a neon-colored world of orbiting sprites, a scrolling message, and a three-voice SID score.", "controls": [{"keys":["1","2","3"],"description":"Select slow, medium, or fast motion"},{"keys":["C"],"description":"Change the visual palette"},{"keys":["M"],"description":"Mute or restore the SID track"},{"keys":["SPACE"],"description":"Pause or resume the demo"},{"keys":["Q"],"description":"Return to BASIC"}], "path": "neon-rift/neon-rift.prg", "source": "neon-rift/neon-rift.asm" }