Meta [ Title: "Mortal Coil Atari 8-bit demo" Version: 13-Feb-2022 Author: ["Freddy Offenga" "Kaj de Vos"] Rights: "Copyright (c) 2017,2018 Freddy Offenga, 2020-2022 Kaj de Vos" License: { PD/CC0 http://creativecommons.org/publicdomain/zero/1.0/ } Purpose: "Kind of rotating starfield using one missile and DMA off!" Notes: { Ported by Kaj de Vos from the original in assembly by Freddy Offenga: https://github.com/FreddyOffenga/mortal-coil The original won first place in the 128 bytes compo at Outline 2017. https://outlinedemoparty.nl } ] ; Define fixed memory addresses Unsafe!!! constant reference volatile byte! [ ; Operating system software addresses RTCLOK3= ~14 SDMCTL= ~022F ; Hardware addresses ; GTIA HPOSM0= ~D004 COLPM0= ~D012 GRACTL= ~D01D ; POKEY AUDC1= ~D201 RANDOM= ~D20A ; ANTIC WSYNC= ~D40A VCOUNT ] ; Declare byte arrays Let [wave shifts colours] binary! ~100 Byte! [byte index reverse] GRACTL: %11 SDMCTL: 0 ; Switch off display DMA ; Give the compiler the opportunity to reuse 0 ; Fill SHIFTS and COLOURS with random values. ; Use indexing instead of series references for arrays upto length 256 on 6502. ; Shift the indexing to 0-based to make the index fit in a byte. ; We don't need that here in pre-computation for speed, but the generated code will be smaller. For index [0 (count shifts) - 1] [ poke next shifts index RANDOM poke next colours index RANDOM ] ; Pre-compute a base sine WAVE ; Quarter sine wave Let [sine step] natural! 0 ; Set to zero for Atari 400/800 ; Give the compiler the opportunity to reuse 0 Index: 0 ; Have this loop count down to 1, to generate an efficient end test for 0 For reverse [~40 1] [ Increment index ; Don't use intermediate variables with CC65 if possible. ; But don't use complex expressions as value to store into indexed series with CC65. Byte: second-of sine: sine + step ; Quarter sine wave Poke skip wave ~C0 index byte Poke skip wave ~80 reverse byte ; Mirror the sine wave Byte: byte x-or %0111'1111 ; Mirror the sine wave again Poke skip wave ~40 index byte Poke wave reverse byte Step: step + 8 ] ; Animate the coil Forever [ Until is-zero VCOUNT [] ; Wait for vertical sync Index: RTCLOK3 ; Scroll the coil Repeat 254 overflow [ ; Scanlines (minus 1); limit for NTSC ; Don't use complex expressions as indexes with CC65 Byte: (pick next shifts index) ; Scatter the sine wave into a column + RTCLOK3 ; Rotate the coil AUDC1: ; Sound control HPOSM0: ; Missile position WSYNC: ; Wait a scanline (pick next wave index) + (pick next wave byte) ; Wave the wave >> 1 ; Shrink the coil + ~40 ; Centre the coil COLPM0: pick next colours index ; Colour the missile Increment index ; Scatter the sine wave into a coil ] ]