Odyssea by Řrřola [web]
; .--. .--. .--. Odyssea /\ /\ /\
; `--' `--' `--' `--' \/ \/ \/ \/
; a 64-byte intro by rrrola <rrrola@gmail.com>
; greets to everyone who thinks in ancient Greek
; I've wanted to make a 64-byte plasma for a long time.
; The cosine generator from Florame made it possible.
; Thank you, Optimus!
; How it works:
; Start with A=X, B=5*cos(Y) and D=cos(Y)
; and transform them into A=f(A,B,D), B=g(A,B,D) and D=h(A,B,D)
; where f, g, and h depend on the current part (frame number / 128).
; This process is usually done once on one half of the screen
; and twice on the other half, but there are parts where we can recurse.
; Finally compute color = triangle_wave(A + D + cos(B + pixel address)).
; The reason for the intro's name is the epic journey of the first word
; loading itself into BP and travelling to be negated and put into [C+1],
; where it's finally executed again inside the "add" instruction
; to shape the whole effect.
; Also cuz plasma is wavy and there be some waves on dis sea.
org 100h ; assume ah=0 cx=0xff si=0x100 [0xfd..ff]=0 cs<=0x5d2c
;c5 2c
lds bp,[si] ; bp=0x2cc5 ds=0x6d2c for cosine table
;2c 6d
sub al,0x6d ; al=0x93: 320x200 mode without clearing the screen
push 0xa000
pop es
nop ; align label D
; Start of overlap
;cd
db 0xcd ; init: cd 10 int 10h ; set 320x200
; d0 2a shr byte[bp+si],1
; 01 78 02 add [bx+si+2],di
;10 d0 ;
M db 0x10,0xd0; later: 10 d0 adc al,dl (we need this variant)
;2a 01
sub al,[bx+di] ; subtract another cosine
;78 02
js T
; End of overlap
; Triangle wave /\/\/
not ax ; al = 0..255 -> 255..128,128..255
T shr al,3 ; -> 31..16,16..31
stosb ; draw pixel
; Cosine table (harmonic oscillator) from "Florame" by Optimus
; init: cx=C=255, si=S=256
mov ax,24
imul cx
sub si,dx ; S -= C/2730.66
mov [di],ch ; cos[adr] = C/256 (continues below)
; Convert pixel address to X,Y
xor dx,dx
mov ax,di
mov bx,320
inc bp ; on init: di goes from -2 up to 0xd339 = -0x2cc7
jnz D-1 ; jump to "idiv bx"
; bp=0 ax=di=T(0xd339, 0xd33b, ..., 0xd401, ...)
hlt ; limit to 18.2 fps
scasw ; di+=2 (now it's time)
;36 88 67 f7 ; mov [ss:bx-9],ah ; last byte must be 0xf7 for "idiv"
mov [byte ss:bx-320+C+1],ah ; overwrite instruction at C every frame
;f7 fb ; idiv bx(320): X(0..319)@dx = adr%320, Y(0..200)@ax = adr/320
; fb ; sti
D sti
; Plasma
xlat ; Y = cos(Y)
cbw
X xchg ax,dx ; X<->Y
imul bx,dx,5 ; bx = X*5, test sign later
C add al,[bx+si] ;<- changed to: add dl,bl (0xd3), add dl,ah (0xd4), ...
; I use al,[bx+si] because I want the 0x02 opcode
;f7 db
neg bx ;<- can become a part of the previous instruction
jg X ; loop once, twice, or recurse
add cx,si ; C += S (part of cosine table)
jmp M
[ back to the prod ]
