Polar Beat by Řrřola [web]
; o .
; o888. .o8o. 8 .88 88o.
; 8K 8 8" 8 8 .8 8 .8 "8
; "8o8" 8. 8 8 .8__8 88oK"
; "8. "8o8" 888 8"""8 o8 "8
; "8 8
; 88o. ..oo88
; .8 "8 oooo 88."""8
; 88oK".8__ 8 8. 8.
; o8 "o 8""" 8__8. "8
; "8o" 8oooo 8"""8 8
;
; a 256-byte intro by Řrřola
; <rrrola@gmail.com>
; Greets to everyone
; who likes polar bears!
org 100h ; assume ax=bx=0 ch=0 si=0x100 sp=di=-2 cs<=0x2f54
;execute a few harmless floats
C5div6 equ $-2
db 0x54,0x3f ; 5/6 ; push sp; aas
C3_5 equ $-2 ;=[si]
db 0x5f,0x40 ; 3.5 ; pop di; inc ax
C4_5 equ $-2
db 0x90,0x40 ; 4.5 ; nop; inc ax
C2PIdiv6 equ $-2
db 0x85,0x3f ; 2π/6 ≈ 1.047 ; test [bx],di
;init
xchg ax,cx ; cx=2: tick (goes up), miss first beat
mov fs,[si] ; backbuffer for postprocessing = 0x3f54
mov al,13h
int 10h ; 320x200 mode, default palette
mov bp,0xa000-70-6
mov es,bp ; aligned screen
;main loop = pixel loop
X mov ax,0xcccd
mul di ;)
add dx,bp
push dx ; +2 bytes: X with full precision
pusha ; stack: [... -6-5-4]
; cx ax dx
; TTTT YYYY
; XXXX
;polar coordinates the hacky way
;assume cos(angle) isn't 0 anywhere on screen
fild word[bx-4]
fild word[bx-5]
fld st1 ; y x y
fpatan ; a=atan(x/y) y ; -π..π, 0=vertical
fld st0 ; a a y
fcos ; cos(a) a y
fimul word[byte si-100h+C295]
fdivp st2,st0 ; a r=y/(-295*cos(a)) ; r=√(x²+y²)
;base color: 24 = 3*8 rainbow shades
;mov ax,7*256 + 32+24+24+24+24+19
;and ah,ch
;aad 3 ; al += 3*ah ; aad is slow to emulate
mov al,ch ; +2 bytes: faster
and al,7
lea ax,[byte eax + 2*eax + 32+24+24+24+24+19]
;pick one of 8 formulas based on tick/256
shl ch,6 ; 00000uvw -> flags: cf=u sf=v pf=v^w
jnc A ; fpu instructions don't touch flags
;Clover: 3.5 / (3.5 - cos(4.5 sin(2a)));
C jnp G
fadd st0 ; 2a r
jns D
C295:
fsin
;Flower / Butterfly: 3.5 / (3.5 + f(cos(4.5 a)))
G fmul dword[byte si-100h+C4_5]
fcos
fchs ; Butterfly (4.5 points): f(x) = -x
js I
fabs ; Flower (9 points): f(x) = |x|
jmp I
;Gear: 3.5 / (3.5 + sin(cos(7a) + π/4)) ; 7 mod 2π ≈ π/4
B fmul dword[si] ; Gear (7 points)
jns F ; Sun (22 points) ; π ≈ 22/7
fadd st0
fcos
fadd dword[si] ; "fabs" will be a no-op
;Heart: 3.5 / (3.5 + sin(|2a| + 3.5))
D fabs ; |2a| r
fadd dword[si]
fsin ; s=sin(|2a|+3.5) r
I fadd dword[si]
fdivr dword[si] ; 3.5/(3.5+s) r
jmp J
;Hexagon / Star / Sun (or circular saw)
A jnp B ; a/h r ; h = 2π/6
fdiv dword[byte si-100h+C2PIdiv6]
jns F ; Star: 5 points instead of 6
fmul dword[byte si-100h+C5div6]
F fist word[bp+si]; Sun
fisub word[bp+si]; fract(a/h)-0.5 r
jns E
fadd st0 ; Star or sun: more pointy
E fmul dword[byte si-100h+C2PIdiv6]
fcos ; cos(h*(fract(a/h)-0.5)) r
J fmulp ; modulate radius
P fistp word[bp+si]
xor cl,16 ; 16 ticks: jump to the beat
add cl,[bp+si]
shr cl,6 ; cf = (tick + round(modded radius)) >> 5
jnc Q
add al,72 ; background color
;shading: top/left bevel
Q mov bh,-5 ; -1280 = -320*4: 4px tall, 5px wide
mov [fs:di],al
Y cmp al,[fs:di+bx]
jae Z ; compare with top or left pixel
sub al,48 ; bevel color (-48 or -96)
Z sar bx,8 ; -1280/256 = -5
jnp Y
;draw pixel, loop
stosb
popa
pop dx
inc di
M jnz X ; trampoline to make a jump shorter
;vsync
mov dx,0x3da
V in al,dx
test al,8
jz V
;music
pusha
mov ah,ch ; for melody
mov bl,cl ; for bass ; bh=0
and cx,7
jnz S ; play every 8 ticks
mov si,MIDI ; assume UART mode
mov dl,0x30 ; send to MIDI data port: dx=0x330
mov cl,9 ; ch=0 from "and"
xor byte[si+6],36^42 ; flip bass drum <-> closed hi-hat
rep outsb
;bass: pick from a table, flip ┬▒32 (bass or low drone)
shr bx,5
xor byte[bx+si+5],32
mov al,[bx+si+5]
out dx,al
outsb
;melody: loop the same 8 notes, gradually make louder
ror dword[si],4
lodsb
and al,0xf
add al,32+24
out dx,al
shr ax,4
out dx,al
S popa
inc cx ; tick++
in al,60h ; esc check
cmp al,1
jnz M
MIDI:
ret ; 0xc3 = ch4 instrument change
db 81 ; ch4: change to saw wave
db 0xb3, 123, 0 ; ch4: all notes off
db 0x99, 36, 0x7f ; play bass drum or closed hi-hat
db 0x93, 0x7f ; play notes; bass velocity
dd 0x8507587F ; 4-bit melody
db 0x20,0x21,0x21,0x21,0x25,0x25,0x23,0x23 ; bass
[ back to the prod ]
