Relax by Řrřola [web]
; RELAX
; a 256-byte intro by Rrrola
; greets to everyone who's used MIDI in a tiny intro
; music algorithm: "Molecular music box" by Dr Duncan Lockerby
; setting: 18D29
org 100h ; assume ax=bx=0 si=100h sp=-2
T equ $-2
mov fs,ax ; fs=0 (for timer)
scasw ; di=0
pusha ; adr: -18 -16 -14 -12 -10 -8 -6 -4 -2
; stack: di si bp sp bx dx cx ax 0
; data: 0 100 9?? -2 0 cs FF 0
; [-16]: SONGPOS
; Set video mode
mov al,13h
CZ equ $-1 ; -13037
int 10h
mov dx,3c8h
salc
out dx,al
inc dx
; Palette: red and green imitate smoothstep
P:push ax
mul al ; x*x 12 bits
imul bx,ax,10
shr ax,5 ; 7 bits
mul al ; x*x*x*x (14)
sub bx,ax
mov al,bh
out dx,al
out dx,al
pop ax
out dx,al
add ah,2Eh
adc al,ch ; al:ah += 0x002E
C126: ; -11.994
loop P
MIDI:
db 0x3F ; aas
db 0xC1,122,90h,42 ; sar word[bp+si-0x70],42
db 91h ; xchg ax,cx
push 0a000h
C7: pop es
fninit
xor cx,cx
M:
; Play notes for the current tick?
mov al,[fs:0x46c]
jz F ; first
push ax
sub al,4
sub al,[si]
pop ax
js SKIP_MUSIC
F:mov [si],al
pusha
mov si,MIDI
mov dx,331h
outsb ; 0x3F: UART simple mode
dec dx
outsb ; 0xC1: Program change, channel 2
outsb ; 122: Seashore (channel 1 is the default Grand Piano)
mov cl,31 ; max piano polyphony = 31
xor ebp,ebp ; the cycle has 32 ticks: which ticks have played a note?
mov ax,18 ; number of ticks between notes = initially +18
C18 equ $-2 ; D.F.A.c. eE.G.B.d (melody then switches to +29)
mov di,[bx-16] ; song position
inc word[bx-16]
N:pusha ; bx = initially 0 (current note time)
lea ax,[bx+di] ; song time minus note time
and ax,801Fh ; should it play yet? and on this tick?
jnz O
imul ax,cx,-12 ; 12 notes in octave
add ax,34*7+12*31+5 ; first note is D
div byte[byte si-MIDI-3+C7] ; 7 notes in scale
outsb ; 0x90: Note On, channel 1
out dx,al ; note
outsb ; velocity 42
cmp al,38 ; new seashore sound on lowest two notes
ja O
outsb ; Note On, channel 2
out dx,al ; note 37 or 38
out dx,al ; velocity 37 or 38
O:popa
bts ebp,ebx
jnc B
xor al,29^18; if there's a note on this tick, switch 18<->29
B:sub bx,ax ; note time += 18 or 29
loop N
popa
SKIP_MUSIC:
; Draw the moon and the sea.
xor di,di ; loop: di=0
mov cl,200
Y:mov bx,320
; Compute the perturbed Y after the reflection.
mov ax,cx
sub ax,100 ; y - 100
push ax
fild word[byte si-100h+CZ]
fidiv word[-4-16]
fiadd word[byte si-100h+T]
fidiv word[byte si-100h+C18] ; a = (c / (y-100) + t) / 18
fsin
fmul dword[byte si-100h+C126]
fistp word[-4-16] ; dy = round(-12 * sin(a))
pop dx
X:
pusha
xchg ax,bx ; (x-160)^2 -> xx
sub al,160
imul al
xchg ax,cx ; reflection? (y<100)
cmp al,100
ja R
neg al ; y_new = 200-y + dy
add al,200
add al,dl
R:
mov bl,-200 ; color gradient: (y_new-200)/2
add bl,al
sar bl,1
sub al,150 ; (y_new-150)^2 -> yy
imul al
add cx,ax ; 0x1000000 / (512 + xx + yy)
mov dx,si
add ch,2
div cx
shr bp,6 ; noise
add ax,bp
shr ax,7
cmp ax,185 ; really bright?
jb Z
sub al,80 ; it's the moon
add ax,ax ; make it even brighter
or ah,ah
jz Q
mov al,254 ; clamp to 254
db 0x3D ; cmp ax,NN: skip two bytes
; jmp Q
Z:
; cmp di,32000 ; stars didn't make it ;-)
; jae K
; xor cx,di
; ror cx,cl
; imul cx,5+96
; test ch,ch
; jnz K
; shr ax,1
; add al,96
;K:
sub ax,bx ; no moon: add gradient
Q:stosb
popa
inc di ; new pixel, update noise
add bp,di
dec bx
jnz X
loop Y
inc word[byte si-100h+T]
in al,60h
cmp al,1
jnz M
I:
ret
[ back to the prod ]
