heckmeck!

Nerd content and
cringe since 1999

Alexander Grupe
Losso/ATW

Fireworks!

A 256 byte intro for Amiga, made for ROMA.EXE 2026. A little fun production that even made it to the 3rd place of the compo! Well, why not, it’s pretty thrilling after all:

The name is a reference to a famous resp. funny scene from The Office US, the DVD logo opening.

So what I was thinking is: Maybe we should have some sort of graphic. Like, if we have a bad quarter, put in a storm cloud. And when we have a good quarter – fireworks!

By a weird coincidence, a production with a very similar name took part in the same competition. That one features actual fireworks, not some obscure reference, and it has sound!

The bytes

This isn’t the most optimized code ever, and I wasted a lot of bytes for pure text data (see below). The dekadence!

OS overhead

Amiga executable hunk structure

Code

68000 machine code

Strings

Escape sequences, a BEL character, and the closing message.

Data

Scroll variables and constants

00000000: 0000 03f3 0000 0000 0000 0001 0000 0000  ................
00000010: 0000 0000 0000 0037 0000 03e9 0000 0037  .......7.......7
00000020: 6142 0c9b 3136 759b 3574 9b34 333b 316d  aB..16u.5t.43;1m
00000030: 0c9b 3020 709b 3238 780a 7caf af5c 5c20  ..0 p.28x.|..\\ 
00000040: 202f 7caf af5c 0a7c 5f5f 2f20 5c2f 207c   /|..\.|__/ \/ |
00000050: 5f5f 2f0a 9b33 323b 336d 2056 2049 2044  __/..32;3m V I D
00000060: 2045 204f 7010 286a 00ac 221f 48e7 fffe   E Op.(j..".H...
00000070: 7442 4e95 2a6a 0170 2458 2c50 2c6e 009c  tBN.*j.p$X,P,n..
00000080: 2a6d 0038 49fa 0066 34bc 153f 4c9c 00ff  *m.8I..f4..?L...
00000090: 5347 6c06 3e02 4440 584b 5346 6c06 3c03  SGl.>.D@XKSFl.<.
000000a0: 4441 514b 48a4 ff00 43ed 0054 7403 760b  DAQKH...C..Tt.v.
000000b0: 4eae fe74 41ed 002c 7003 3213 4eae fee0  N..tA..,p.2.N...
000000c0: 5f52 66c8 4cdf 7fff 6118 1b63 576f 7721  _Rf.L...a..cWow!
000000d0: 0720 4974 2068 6170 7065 6e65 6421 203a  . It happened! :
000000e0: 290a 221f 7418 4e95 7000 4e75 0002 0001  ).".t.N.p.Nu....
000000f0: 00ec 008d 027d 00c6 0001 0000 0000 03f2  .....}..........

The code

Short and sweet, nothing fancy. But I did find an ancient bug in the process!

; vasmm68k_mot -Fhunkexe -o fireworks.exe fireworks.asm

SCROLL_X1 = 3
SCROLL_Y1 = 11
SCROLL_X2 = 637
SCROLL_Y2 = 198
AMOUNT_X  = (SCROLL_X2-SCROLL_X1-9*18)/2
AMOUNT_Y  = (SCROLL_Y2-SCROLL_Y1-9*5-1)

        bsr.b   .tend
.txt    dc.b    12              ; form feed = clear
        dc.b    $9b,'16u'       ; 16 chars wide window
        dc.b    $9b,'5t'        ; 5 rows high window
        dc.b    $9b,'43;1m'     ; bg #3, bold
        dc.b    12
        dc.b    $9b,'0 p'       ; cursor off
        dc.b    $9b,'28x'       ; left margin 28 px
        dc.b    10
        dc.b    '|¯¯\\  /|¯¯\',10 ; '¯' = $af (macron)
        dc.b    '|__/ \/ |__/',10
        dc.b    $9b,'32;3m'     ; fg #2, italics
        dc.b    ' V I D E O'
.tend   moveq   #16,d0          ; bcpl stack
        move.l  172(a2),a4      ; writeoutput
        move.l  (a7)+,d1        ; text (APTR)
        movem.l d0-a6,-(a7)     ; save for end msg
        moveq   #.tend-.txt,d2  ; length
        jsr     (a5)            ; a0 will be 0, a3 = next PC
        move.l  368(a2),a5      ; intuition
        move.l  (a0)+,a2        ; a2 = 0, a0 = 4
        move.l  (a0),a6         ; exec
        move.l  156(a6),a6      ; graphics
        move.l  56(a5),a5       ; intuition.ib_ActiveScreen
        lea     .data(pc),a4
        move.w  #777*7,(a2)     ; global countdown
.loop   movem.w (a4)+,d0-d7     ; fetch variables
        subq.w  #1,d7           ; x countdown
        bge.b   .norx           ; flip?
        move.w  d2,d7           ; AMOUNT_X
        neg.w   d0
        addq.w  #4,a3           ; change color
.norx   subq.w  #1,d6           ; y countdown
        bge.b   .nory           ; flip?
        move.w  d3,d6           ; AMOUNT_Y
        neg.w   d1
        subq.w  #8,a3           ; change color
.nory   movem.w d0-d7,-(a4)     ; write variables back
        lea     84(a5),a1       ; screen.sc_RastPort
        moveq   #SCROLL_X1,d2
        moveq   #SCROLL_Y1,d3
        jsr     -396(a6)        ; ScrollRaster
        lea     44(a5),a0       ; screen.sc_ViewPort
        moveq   #3,d0           ; color #3
        move.w  (a3),d1         ; d1 = red
        jsr     -288(a6)        ; SetRGB4
        subq.w  #7,(a2)
        bne.b   .loop
        movem.l (a7)+,d0-a6     ; restore BCPL env
        bsr.b   .t2end
.txt2   dc.b    $1b,'c'         ; terminal reset
        dc.b    'Wow!',7,' It happened! :)',10
.t2end  move.l  (a7)+,d1
        moveq   #.t2end-.txt2,d2
        jsr     (a5)            ; writeoutput
        moveq   #0,d0           ; clean exit
        rts
.data   dc.w    2               ; dx
        dc.w    1               ; dy
        dc.w    AMOUNT_X
        dc.w    AMOUNT_Y
        dc.w    SCROLL_X2       ; xmax
        dc.w    SCROLL_Y2       ; ymax
        dc.w    1               ; y to go
        dc.w    0               ; x to go

I’m using a new byte-saving trick I learned from STI’s VCCC 2024 code. Props and thanks to Saturnus the Invincible/SCA!

To load a PC-relative address into a non-address register, usually you do this:

        lea     .text(pc),a0    ; 41fa 000e
        move.l  a0,d1           ; 2208

.text   dc.b    'Text...',0

If your data has an even number of bytes you can use bsr to push its location onto the stack. Cram your data into the code and transfer the “return address” into the target data register – two bytes saved!

        bsr.b   .cont           ; 6108

.text   dc.b    'Text...',0

.cont   move.l  (a7)+,d1        ; 221f

Download and links

previous next close