;-------------------------------------- ; Temba, seine Arme weit ;-------------------------------------- ; ; Losso/AttentionWhore @ Nordlicht 2025 ; https://heckmeck.de/demoscene/temba-seine-arme-weit/ ; ; Expects to be unpacked at UNPACK_TARGET, and assumes ; some register contents (see below). Assembles with: ; ; vasmm68k_mot -no-opt -m68000 -Fbin -nosym -o temba.bin temba-inlined.asm ; ; Maximum size with the slightly modified ZX0 compressor ; and unpack routine I used: 388 bytes (raw size: 2122 bytes) ; ;-------------------------------------- UNPACK_TARGET = $5e14e ; $56c22; $56722 ; see decrunch_zx0.asm, this comes from the unpack opcodes SINTAB = $58000 ifd UNPACK_TARGET org UNPACK_TARGET endif ;-------------------------------------- global @sintab equr a0 @wav equr a3 ; initial value = end of data -- no need to initialize @blink equr d4 ; initial value 00000001 @oldcop equr a5 ;-------------------------------------- gen sine @a equr d0 @b equr d1 ;-------------------------------------- interpol @deltas equr a2 ; table of variable deltas @vars equr a1 ; current variables @v equr d0 ;-------------------------------------- output sample @sinpos equr d5 @p equr d1 ; copy of @sinpos while adding harmonics @q equr d2 ; @p clamped to a valid sine word offset @s equr d3 ; sample value ;-------------------------------------- main: move.l #64<<16,$dff0a8 ; aud0vol+aud0dat, vol=64 move.l #copper,$dff080 ; cop1lc move.l @wav,$dff0a0 ; aud0pt move.l 4.w,@oldcop move.l 156(@oldcop),@oldcop ; 156 = IVBLIT = gfxbase move.l 38(@oldcop),@oldcop ; 38 = ? ; ; gen sine ; move.l #SINTAB,@sintab neg.b @a ; assume @a == d0 == $00000001 sloop move.w @a,@b sub.w #128,@b muls.w @b,@b sub.w #$4000,@b move.w @b,512(@sintab) not.w @b move.w @b,-(@sintab) dbf @a,sloop ; ; main loop ; ; 0 1 2 3 4 5 6 7 8 9 ; ; @vars = h1.l h2.l h3.l h4.l h5.l h6.l h6.l h8.l sinstep.l ticks.l ; @deltas = dh1.l dh2.l dh3.l dh4.l dh5.l dh6.l dh7.l dh8.l dsinstep.l dticks.l<-- advances whenever ticks.l == 0 ; ; move.l #deltas,@deltas loop move.l #vars,@vars ; current variable values move.l (@deltas)+,@v ; h1 += delta_h1 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h2 += delta_h2 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h3 += delta_h3 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h4 += delta_h4 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h5 += delta_h5 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h6 += delta_h6 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h7 += delta_h7 add.l @v,(@vars)+ move.l (@deltas)+,@v ; h8 += delta_h8 add.l @v,(@vars)+ move.l (@deltas)+,@v ; sine step size += delta_step add.l @v,(@vars)+ move.l (@deltas)+,@v ; ticks += delta_ticks bne.b noexi ; move.w #$0001,$dff096 ; clr aud0 move.l #0,$dff0a8 ; aud0vol+aud0dat, vol=64 move.l @oldcop,$dff080 ; cop1lc move.l #$8020,$dff094 ; set spr ; move.l @v,d0 ; @v = d0 is 0 already rts noexi add.l @v,(@vars)+ ; ; tick count == 0 --> roll through next deltas entry, otherwise reset @deltas ; beq.b next_deltas sub.w #10*4,@deltas next_deltas ; ; wave output or show ; move.l #vars,@vars tst.w 8*4(@vars) ; is sine step negative? blt.w show ; ; render a sample byte ; subq.w #2,@vars ; point to [garbage.w] [h1_HI.w] move.l @sinpos,@p ; sinpos := global_sinpos moveq #0,@s ; new sample rept 8 move.l @p,@q ; sinpos_tmp := sinpos swap @q and.w #1024-2,@q move.w (@sintab,@q.w),@q ; sinval(sinpos_tmp) (+/- $00003fff) move.l (@vars)+,@v ; only uses lower word for harmonics_amount delta muls @v,@q ; sinval * harmonics_amount (+/- $007fffe0) add.l @q,@s ; sample += sinval add.l @sinpos,@p ; sinpos_tmp += sinpos (next harmonic) endr swap @s ; sample: $007fff00 --> $007f move.b @s,(@wav)+ addq.w #2,@vars ; point to step.l move.l (@vars)+,@v add.l @v,@sinpos ; global_sinpos += step jmp loop ; ; use variables for display effects ; show ; h1: sinpos ; h2: sinamp ; h3: audper move.w (@vars)+,@q ; h1 HI = sinpos and.w #1024-2,@q move.w (@sintab,@q.w),@q ; sinval(sinpos_tmp) (+/- $00003fff) move.l (@vars)+,@v ; h1 LO h2 HI muls @v,@q ; sinval * harmonics_amount (+/- $007fffe0) swap @q add.w #$f8,@q cmp.w #$f8,@q blt.b noyf moveq #-1,@q noyf move.b @q,cwt move.l (@vars)+,@v move.w @v,$dff0a6 ; (h2 LO h3 HI).w = audper wait0 tst.b $dff006 ; triggers at vpos $100 and possibly $000 bne.b wait0 moveq #-1,@q add.w #$9f,@blink blt.b nobli moveq #0,@q nobli move.l @q,bitmap-12*16+6 move.w #$8001,$dff096 ; dmacon |= AUD0 jmp loop ;-------------------------------------- __ = 0 XX = $ff ; .. .. .. .. :: :: :: :: .. .. .. .. :: :: :: :: dc.b __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__ dc.b __,__,__,__,__,XX,XX,XX,XX,XX,XX,__,__,__,__,__ dc.b __,__,__,XX,XX,__,__,__,__,__,__,XX,XX,__,__,__ dc.b __,__,XX,__,__,__,__,__,__,__,__,__,__,XX,__,__ dc.b __,XX,__,__,__,XX,XX,XX,XX,XX,XX,__,__,__,XX,__ dc.b __,XX,__,__,XX,__,__,__,__,__,__,__,__,__,XX,__ dc.b __,XX,XX,__,__,__,__,__,XX,__,XX,__,__,__,XX,__ dc.b __,XX,__,__,__,XX,XX,XX,__,__,__,XX,XX,XX,__,__ dc.b XX,__,__,__,XX,__,XX,__,XX,__,XX,__,XX,__,XX,__ dc.b XX,__,__,__,XX,__,__,__,XX,__,XX,__,__,__,XX,__ dc.b XX,__,__,__,__,XX,XX,XX,__,__,__,XX,XX,XX,__,__ dc.b __,XX,__,__,__,__,__,__,__,XX,__,__,__,__,XX,__ dc.b __,XX,__,__,XX,__,__,__,__,XX,__,__,__,XX,__,__ dc.b __,__,XX,XX,XX,__,__,__,XX,__,__,XX,XX,__,__,__ dc.b __,__,__,__,__,XX,XX,XX,XX,XX,XX,__,__,__,__,__ bitmap: dc.b __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__ ;-------------------------------------- vars: dc.l $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000, $00064000, $00000000 ; initial = 0, 0, 0, 0, 0, 0, 0, 0, 6 deltas: ; delta h1, h2, h3, ... delta sinstep ticks dc.l $00000300,$00000180,$00000000,$00000000,$00000000,$00000000,$00000300,$00000280, $00000008, $00080000 ; J = 96, 48, 0, 0, 0, 0, 96, 80, 7 in 8192 steps dc.l $00000000,$00000180,$00000300,$00000300,$00000180,$00000180,$00000000,$00000000, $00000000, $00080000 ; O = 96, 96, 96, 96, 48, 48, 96, 80, 7 in 8192 steps dc.l $ffffffa0,$ffffffe0,$00000000,$ffffff40,$ffffffa0,$ffffffa0,$ffffff40,$ffffff60, $00000008, $00020000 ; A = 48, 80, 96, 0, 0, 0, 0, 0, 11 in 32768 steps dc.l $ffffff40,$fffffec0,$fffffe80,$00000000,$00000000,$00000000,$00000000,$00000000, $00000004, $00040000 ; fadeout = 0, 0, 0, 0, 0, 0, 0, 0, 11 in 16384 steps dc.l $00800000,$00000000,$00780000,$00000000,$00000000,$00000000,$00000000,$00000000, $40000000, $80000000 ; show = 256, 0,240, 0, 0, 0, 0, 0, 32779 in 2 steps ; sinpos sinamp audper ticks dc.l $0001c000,$00004000,$fffff100,$00000000,$00000000,$00000000,$00000000,$00000000, $00000000, $00200000 ; weg1 = 3840,512,120, 0, 0, 0, 0, 0, 32779 in 2048 steps dc.l $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000, $00000000, $00200000 ; end = 3840,512,120, 0, 0, 0, 0, 0, 32779 in 1342177280 steps dc.l $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000, $00000000, $00000000 ; end = 3840,512,120, 0, 0, 0, 0, 0, 32779 in 1342177280 steps ;-------------------------------------- copper: dc.w $008e,$81e1 ; diwstrt dc.w $0090,$0161 ; diwstop dmac: dc.w $0096,$0020 ; dmacon dc.w $0094,$ffa0 ; ddfstop dc.w $0180,$ffa0 dc.w $0108,-16 dc.w $0182,$ff40 dc.w $00e0,(bitmap>>16) dc.w $00e2,(bitmap&$ffff) dc.w $0100,$1200 dc.w $0092,$0068 ; ddfstrt cwt: dc.w $ff01,$fffe ; $01..$81 = visible, $82..$f8 = partially visible, $f9..$00 = invisible rept 16 ; only 16 necessary? rept 7 dc.w $80df,$00fe,$0108,-16 endr dc.w $80df,$00fe,$0108,-32 endr ;--------------------------------------