pouët.net

Koridor by Řrřola [web]

;   _________
;  / Koridor \
; / a 256-byte\
; \  intro by / rrrola <rrrola@gmail.com>
;  \_________/
; greets to everyone who likes liminal spaces

  org 100h      ; assume ax=bx=0 cx=0xff si=0x100

%define DI_INIT 0xa000 - 255*2

; Unpack song data from nybbles.
  mov di,DI_INIT
U lodsb         ; unpack [si+N] to [di+2*N]
  aam 0x10      ; hhhhllll -> al=0000llll ah=0000hhhh
  stosw
  loop U        ; ah=0 after unpacking

; Set graphics mode and palette (black -> greenish cyan).
  mov al,13h
P imul cx,bx,0xc1
  xchg ch,cl
  int 10h       ; cl=blue = i, ch=green = i*0.75
  mov ax,0x1010
  dec bl        ; bl=i = 255 (index: we use 63..0)
  jnz P
  ; cx=c100 di=a000

  mov es,di

; Main loop:
M mov cx,12     ; 1 song tick = 12 video frames at 70Hz

; For each pixel:
ANIM:
X:mov ax,0xcccd
  mul di
  add dx,0xa080 ; dh=y dl=x (centered)

; Find octants: horizontal, vertical, diagonal
  xor ax,ax     ; al = octant index (0,4,...,28)
OX:
  xor al,7*4
  neg dl
  jl OX         ; absolute value: 0..128

OY:
  xor al,3*4
  neg dh
  jl OY

  cmp dl,dh
  jb OD
  xor al,1*4
  xchg dl,dh   ; dh=max coord, dl=min coord
OD:

; Slant vertical walls into hexagon.
  sub al,4
  test al,8
  jnz H
  shr dl,1
  add dh,dl
H:

; Draw animated pulses from the center.
  add dh,cl  ; animation frame (draw 0..11, skip 12..15)
  shr dh,4
  sub dh,bl  ; song timer
  add al,dh

  and al,0x1f  ; 1 highlight + 16 fading colors
  jnz E
  mov al,0x3f
E stosb
  test di,di
  jnz X

; Wait for vertical retrace.
  mov dx,0x3da
W in al,dx
  test al,8    ; cf=0
  jz W

  loop ANIM

MUSIC:
  mov dl,0x30  ; dx=0x330
;  clc         ; cf=0
  mov si,NOTES

; For all 3 channels:
CHN:
  pusha        ; bl = song timer (0..255)

  jb SKIPQ     ; melody is 4x slower than harmony/drums
  test bl,dh   ; dh=3
  jnz N
  shr bl,2
SKIPQ:

  lodsw        ; al = 0xc0 + channel (Program change)
  out dx,al    ; ah = transposition
  outsb
  add al,0x90-0xc0
  out dx,al    ; al = 0x90 + channel (Play/stop note)

  lodsb        ; al = timer mask
  and bl,al

  add si,si    ; point si to unpacked nybbles
  lea si,[si-0x200+bx+DI_INIT-1]

STOPLOOP:      ; stop old note, play new note
  lodsb        ; al = note event
  cmp al,0
  jz SKIP      ; rest => skip it
  add al,ah    ; note => transpose it
  out dx,al
  mov al,ch    ; note velocity (0 or 127)
  out dx,al
SKIP:
  xor ch,0x7f
  jnz STOPLOOP

N popa

  add si,32+4
  cmp si,DRUMS+1
  jb CHN

; Advance song timer and test for ESC.
  inc bl       ; song timer++
  in al,0x60
  dec al
  jnz M        ; TODO: fix long jump

NOTES:
  ret  ; 0xc3

; Song: each event has 4 bits: 0 = rest, 1..f = note
%define p(l,h) (l)+(h)*0x10

%define _ 0         ; rest
%define C 48   -47
%define D 50   -47
%define S 51   -47  ; German "es" = English D#
%define E 52   -47
%define F 53   -47
%define G 55   -47
%define A 57   -47
%define B 58   -47  ; German "b" = English Bb
%define H 59   -47  ; German "h" = English B
%define c 48+12-47
%define d 50+12-47

MELODY:
;db 0xc3  ; channel 4
db 47+12, 103, 0x3f  ; 1..f -> C4..D5, star theme, 64 notes
db p(_,H),p(_,d), p(c,B),p(A,G), p(_,F),p(_,c), p(B,A),p(G,F),
db p(_,E),p(_,H), p(B,_),p(c,d), p(A,_),p(_,F), p(C,_),p(G,A),
db p(H,_),p(_,c), p(d,_),p(_,G), p(A,_),p(_,B), p(c,_),p(D,F),
db p(G,_),p(d,c), p(G,_),p(F,S), p(D,F),p(c,B), p(A,_),p(_,_),

; TODO: harmony pattern "_ 01234 32104 01234"

HARMONY:
db 0xc1  ; channel 2
db 47, 90, 0x3f  ; 1..f -> C3..D4, polysynth, 64 notes
db p(_,E),p(G,H),p(c,d), p(c,H),p(G,E), p(d,E),p(G,H),p(c,d),  ; Cmaj/D
db p(_,S),p(G,B),p(c,d), p(c,B),p(G,S), p(d,S),p(G,B),p(c,d),  ; Cm7/D
db p(_,D),p(F,A),p(B,c), p(B,A),p(F,D), p(c,D),p(F,A),p(B,c),  ; Bmaj/C
db p(_,C),p(D,F),p(G,A), p(G,F),p(D,C), p(A,C),p(D,F),p(G,_),  ; G7sus4/A


%define b 36-35 ; bass drum 1
%define s 40-35 ; electric snare
%define h 44-35 ; pedal hi-hat
%define o 46-35 ; open hi-hat

DRUMS:
db 0xc9  ; channel 10 (= drum channel)
db 35, 16, 0x0f ; 1..f -> C2..D3, power kit, 16 notes
db p(b,h),p(o,b), p(s,h),p(o,b), p(h,b),p(b,h), p(s,h),p(o,s)

db 0,0,0,0