pouët.net

Fontána by Řrřola [web]

; FON  ,
;    TA
;      N
;       A
; a 128-byte intro by rrrola <rrrola@gmail.com>
; greets to everyone who waits for the glitchy part

; DS (old) and ES (new) are arrays of max 16384 particles.
; Each particle is stored in 4 bytes: { s16 Y; s8 dY,dX; };
; If Y==0, the particle is uninitialized (also implies dX:dY==0).
; X is the address - there's only one particle per column.

;TODO: backbuffer could be ss, saves fs: prefix with [bp+di]
; do I even need a backbuffer?
; swap+clear could be copy+clear

org 100h ; assume ax=bx=0 cl=0xFF si=0x100 sp=di=-2 dx=cs<=0x50E4

  les  cx,[si+2]           ; particles1: es=0x7B64 cx=0x8E02 ; C4 4C 02
  mov  fs,[byte si+E-100h] ; backbuffer: fs=0x60E4           ; 8E 64 7B
  lds  bp,[si]             ; particles2: ds=0x8E02 bp=0x4CC4
  rep  stosw      ; clear particles1
  mov  al,13h
  int  10h        ; 320x200, 256 colors

;main loop: add a new particle  ; al=keypress
M:mov  ax,0xBDF9  ; steady stream
  xor  di,di      ; X=0 (center) Y=0xBDF9 (near the visible top)
  stosw           ; dY=0xF9 (slightly up) dX=0xBD (left)

;swap+clear particles1 and 2, copy+clear backbuffer ; di=2
  push es
C:stosw           ; clear particles2 (first pass: new particle's dX:dY)
  push 0xA000
  pop  es         ; screen: es = 0xA000
  xchg ax,[fs:di]
  stosw           ; copy backbuffer to screen and clear it
  dec  di
  dec  di
  push ds
  pop  es
  mov  ax,bx ;0
  jnz  C ;flags from "dec di"
  pop  ds

;for all particles1:  ; si=X=index
P:mov  di,si      ; di=X
  lodsw
  or   ax,ax      ; ax=Y; if ==0, skip (uninitialized)
  jz   S          ; (the dX:dY part is skipped next cycle)

; - add gravity
  mov  cx,0x0908  ; ch = color = blue, cl=8
  inc  word[si]   ; dY++, can overflow to dX

; - for each neighbor: pull particle up  ; bx=0
  mov  bl,256-2   ; bx = Xdiff; look only to the right
R:push ax
  sub  ax,[si+bx] ; ax = Ydiff = Y-Y2
  cmp  ax,[di]    ; if Ydiff==Y, skip (uninitialized)
  je   F
  or   ah,ah      ; if Ydiff>256, skip (too far)
  jnz  F
  mov  ch,0xF     ; pull up: color = white
  dec  word[si]   ; dY--, can overflow to dX
F:add  bx,sp ;-4
  pop  ax
  jns  R

; - move particle, bounce if needed  ; bx=-2
X:xchg ax,di      ; 2 passes: first X, then Y
  ror  word[si],cl; swap bytes
  xchg ax,bp
  mov  al,8
  imul byte[si]
  add  ax,bp      ; X += 8*dX, Y += 8*dY
  jno  B
  mov  al,[si]    ; bounce, lose 1/4 speed
  sar  byte[si],2
  sub  [si],al
  xchg ax,bp      ; restore old position
B:inc  bx
  jnz  X

; - find a free column, store new position and speed  ; bx=0
H:scasw           ; X+=4; X was already quantized to 4 bytes
  scasw
  cmp  [es:di],bx
  jnz  H          ; repeat until column is free
  stosw           ; store new Y
  movsw           ; store new dX:dY

; - plot particle
  sar  ax,cl      ; ax = Yscreen (-128..127)
  imul bp,ax,320  ; bp = Yadr
  sar  di,cl      ; di = Xadr = Xscreen (-128..127)
  mov  [fs:bp+di+320*(100-28)+160],ch  ; ch = blue or white

S:or   si,si ; ah=0 if skipped (unitialized)
  jnz  P

;esc?
E:in   al,60h     ; E4 60
  dec  ax
  jnz  M
  ret