Jump to content

Minimal Demo


Recommended Posts

So, my final result of 32 byte demo coding is now available here: https://xayax.net/hard2632/

More discussion after the demo party! :)

That is so cool! And on a dip-switch re-configurable 32b circuit board!


Good luck at the demo party!


Now how much sound can be made if you don't have to worry about keeping a display?

Some of those simple math equations can create very intricate "songs".

Link to comment
Share on other sites

Nice! Now I need one of those dip-switch boards...


I haven't looked at your code yet, but I noticed the angled border lines are spaced by 9 scanlines, which makes me suspect you are ROLing the value in PF1.


Edit: That's some tight code! How do the NMI/BRK/RESET vectors work?

Edited by JeremiahK
Link to comment
Share on other sites

I tried the following idea: bne is $D0, if the I find a loop that's 16 bytes back or less, this encodes as $D0, $Fx, or as a word $FxD0.


So I utilized the mirroring and rotated the code to have a BNE at the reset vector. With the second BNE the trick worked: $F9D0 now is inside the reset routine. All I needed to do there was to reorder the code there, so the BNE there will always branch after reset.


This is something that won't work without the help of an assembler and Stella. I want to code a slightly simpler demo just using the first table from http://www.oxyron.de/html/opcodes02.html and assemble the code to hex/binary/dipswitches not using any "computer-based" tooling.

  • Like 1
Link to comment
Share on other sites

I made a new demo, Animatrix 2. I like it a little better than the original Animatrix.

; 32 byte demo, Animatrix 2
; by Omegamatrix

; last update Oct 08, 2018

    processor 6502
    include vcs.h

    ORG $F800
    .byte $FF

    ORG $FFE0


;SP=$FD at startup

    bne    .loopClear

;RIOT ram $80-$F6 clear, TIA clear, SP=$FF, A=0, X=0, carry is clear

    lda    #$38         ; does two lines (non-Vsync), and then the regular 3 lines of VSYNC
    sta    GRP0
    sta    WSYNC
    sta    VSYNC
    bne    .loopVSYNC

    sty    HMP0

    sta    WSYNC
    sta    HMOVE
    sty    COLUP0
    bne    .loopKernel
                          ; X=0
    ORG $FFFC             ; CPX #$FF
    .word Start
    bne   .doVSYNC        ; always branch

Animatrix 2.bin

Edited by Omegamatrix
  • Like 4
Link to comment
Share on other sites

  • 2 months later...

I guess I'm a bit late to the party, but here goes -- I finally got around to doing this challenge at 35C3 last week.

My approach is a little unorthodox in that the hardware initialisation happens in a single byte at the bottom of the screen loop. This comes at the cost of an up to approximately four seconds long "boot" period during which the VCS may (but rarely does, at least in randomly initialized Stella) show garbage in addition to the effect because only one zero byte is pushed per screen. I consider this acceptable given the space constraints, but YMMV.

SvOlli calls this "precomputation," so I guess there's a VCS demo that does that now.

Details are in the source code comments. It's possible more can be squeezed from this that I don't see; I'm afraid I'm nowhere near as experienced with the VCS as some (most? all?) people here. ;-)

   processor 6502

   list off
   include vcs.h
   list on

; reset vector at OFFSET - 4

   seg code
   org $f3c1

; upon reset expected: SP = $fd
; also expected: mirroring every 32 bytes

; Look, ma, no init routine! 
; Except not really, of course. I'm doing HW init in one pha at the bottom of the screen loop.
; This is a trade-off: I get only one zero-byte per screen in exchange for four extra bytes
; of machine code that I (desperately) need, especially since I also need to cld in order to
; be able to use adc #1 (which takes one more byte than inx, iny).
; Depending on the initial state, the demo may show nonsense during the first ~4 seconds. This
; can be random garbage in PF0, a strange background color, a sprite or anything else. It's
; surprisingly rare at least in Stella with random initial state, though.

   lda   #$3b              ;  0 -- Bit of luck: this pattern looks nice in PF1,2 and works well
   sta   PF1               ;  2 -- in CTRLPF: reflect | score | unimportant stuff. Weirdly, even
   sta   PF2               ;  4 -- the usually frustrating mirroring of PF1 that makes horizontal
   sta   CTRLPF            ;  6 -- scrolling such a pain works to my advantage.
   	 		   ;       Feel free to try other patterns. It's only important that
			   ;       SCORE is set, PFP is not set, and possibly that three consecutive
			   ;       bits are set so that the sync block works, although I'm unsure
			   ;       of the exact semantics there. It works in Stella with #$0b, which
			   ;       kinda surprised me.
   lsr                     ;  8 -- this part inspired by (lifted from) SvOlli
   sta   WSYNC             ;  9
   sta   VSYNC             ; 11
   bne   sync              ; 13 -- Reset vector no longer here, though; this points between
                           ;       instructions now. See below.

   tsx                     ; 15 -- S doubles as counter for the right topmost color.
   dex                     ; 16 -- Walk through the rainbow, one color every line.
   dey                     ; 17 -- Variation: iny instead of dey here. I like dey better. iny
                           ;       feels like inconsistent shadows to me.
   sta   WSYNC             ; 18
   sty   COLUP0            ; 20 -- set new colors
   stx   COLUP1            ; 22
   cld                     ; 24 -- Having cld close to the adc instruction keeps the invalid region
                           ;       for the reset vector small. Doesn't matter that it's execd often.
   adc   #1                ; 25 -- A from 0 to 0, carry set at outset => 255 scanlines per screen.
                           ;       This means that Y increases by 1 each screen (dey 255 times)
   bne   line              ; 27 -- doubles as reset vector (f3d0), happens to point at 15: tsx.
                           ;       Any instruction except the adc would be fine, though. The reason
			   ;       adc is not fine is that the CPU could be in BCD mode after reset.
			   ;       On that note, whoever invented BCD ought to be clipped round the ear.
   pha                     ; 29 -- A is 0 here, so this will eventually init hw.
   beq   screen            ; 30



Edited by Wintermute
  • Like 4
Link to comment
Share on other sites

  • 3 months later...

After Revision, I finally did some experiments too. For a maximal effect, I went for Cosmic Ark stars. The code provides some alternative effects, named A..G, personally I like E most.


Note that the demos have no initialization, so they behave somewhat random, sometimes with quite different results. This randomness will not work via Harmony etc. because they initialize the registers. But with real cart or with Stella's Options/Developer/Emulation/Randomize CPU enabled, you can recreate the effect.


Have fun experimenting!




  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...