Koruna by Řrřola [web]
; _) "\__ Koruna
;( ( \___/ ' (crown, treetop, corolla, fermata)
; \___/ \_) a 128-byte intro by rrrola <rrrola@gmail.com>
; /, \_) / ,
; / \_/ \__/ greets to everyone who's ever planted a tree
;/ \_,
org 100h ; assume ax=0 bx=0 si=0x100 di=-2
TIME:
cwd ;99 dx=0
mov al,0x13 ;b0 13 graphics mode 320x200
inc di ;47 t = float[0x100] = 37808.6, eps = 2^(15-23)
; Set 320x200 mode and two-channel palette (4 orange + 4 cyan bits).
ZOOM:
P int 0x10 ;CD 10 on init: set graphics mode, later: set palette
xchg ax,cx ;91 <- can be 90 "nop" (for zoom = 1.1255)
aas ;3F zoom = float[0x104] = 1.1333
mov bp,dx ; bp=4 after loop
dec bx ; next index: 255..1 (0 stays black)
dec dx
mov ax,0x1010 ; set palette: bl=index dh=red ch=green cl=blue
and dx,0x3c3c ; dx: ..RRRR.. ..BBBB.. (easier when decrementing dx)
mov cx,dx ; ch=R cl=B
add ch,cl
shr cx,1 ; ch=green=(R+B)/2 cl=blue=B/2
jnz P
; cx=dx=0 bx=0xff00 bp=4 di=-1 ax=0x1010
mov bh,0xa0
mov es,bx ; es = screen segment
; Frame loop: advance time and prepare coefficients.
;M inc dword[si] ; t += 1/256, double speed every 2^23 frames
M inc word[si] ; t += 1/256, 65536 frames (jump at frame 20325)
; Scale * rotation: c = zoom*cos(t), s = zoom*sin(t)
fld dword[si] ; t
fsincos ; cos(t) sin(t)
fdiv st1,st0 ; cos(t) s/c ; assume cos(t) is never exactly 0
fmul dword[bp+si]; c=cos(t)*zoom s/c
fstp qword[bx] ; qword[bx]=c (only the most significant 4 bytes)
fstp dword[bx] ; dword[bx]=s/c
; Translation: t * sin([U*t, V*t])^2
fldln2
db 0x3d ;= cmp ax,0xecd9; cf=1 (ax was 0x1010 or 0x80xx)
U fldlg2 ;D9 EC ; skip on first run
fmul dword[si] ; ln(2)*t = 0.693*t ; log10(2)*t = 0.301*t
fsin ; sin(ln(2)*t) ; sin(log10(2)*t)
fmul st0 ; v=t*sin(ln(2)*t)^2 ; u=t*sin(log10(2)*t)^2
fmul dword[si]
cmc
jnc U ; loop 2x ; u v
; Pixel loop.
L mov ax,0xcccd ; convert width=320 to width=65536 (-32768..32767)
mul di ; but x=0 on the left edge of the screen
add dx,bx ; center y
push dx
push ax ; store [-4]=dx=y, [-5]=dl:ah=x
fild word[bp-4-4] ; y u v
fild word[bp-4-5] ; x y u v
xor ax,ax ; al=loop counter, ah=0
; Iterate (x, y) <- zoom * rotate2D(|x|-u, |y|-v).
I fld st1 ; y x _ u v ; x sy _ cy u v
fabs
fsub st4 ; y=|y|-v x _ u v ; x=|x|-u sy _ cy u v
fmul qword[bx] ; cy x _ u v ; cx sy _ cy u v
fst st2 ; cy x cy u v ; cx sy cx cy u v
fmul dword[bx] ; sy x cy u v ; sx sy cx cy u v
add al,0x82 ; cycle: 00 82 04 86 08 8a ... 7c fe [80]
jnc I ; loop 2x ; nc c nc c nc ... c nc c
faddp st3,st0 ; sy cx cy+sx u v
fsubp st1,st0 ; x=cx-sy y=cy+sx u v
jns I ; loop 32x
; ax=0x80
; Draw pixel: combine orange and blue channel.
; ax=0x80
S fabs ; [bx+si]=|x| ; [bx+si]=|y|
fistp word[bx+si] ; if it's > 0x7fff, store 0x8000
imul dx,[bx+si],2 ; double, set carry if it was > 0x3fff
sbb dh,bl ; dh -= carry (0xff on overflow)
shld ax,dx,4 ; accumulate color in al, set sign flag
pop dx ; also clean up the stack
jns S ; loop 2x
stosb ; draw pixel
loop L ; loop 65536x
fcompp ; drop u, v
; Exit on ESC.
in al,0x60
cmp al,1
jne M
ret
[ back to the prod ]
