pouët.net

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