Apathy by Red Sector Inc. [web]
; Apathy : 128-byte intro with sound (fasm 1.70.03/WinXP 5.1.2600)
; credit : olivier.poudade.free.fr 2013 aka baudsurfer
; credit : inspired by frag^fsqrt's cubeland (fsqrt.blogspot.com)
; greets : Adok, Frag, lordKelvin, Pirx, Rudi, sensenstahl, y0bi
; shouts : dark bit factory forum users (www.dbfinteractive.com)
org 100h ; start after psp
mov al,13h ; fun change mode/mode chained 320x200x8
int 10h ; video bios api
les si,[bx] ; es=09fffh si=020cdh
mov dx,3c9h ; vga dac data register
palette: shrd ax,cx,9 ; smooth grayscale scheme
neg al ; invert gray gradient
out dx, al ; red palette index value
out dx, al ; green palette index value
out dx, al ; blue palette index value
loop palette ; assumed cx=ffh at start
mov dl,031h ; mov dx,0331h=midi command port
mov al,03fh ; set midi mode status command (03fh=set UART mode on)
out dx,al ; output midi command
dec dx ; dx=midi data/status port 330h
dec si ; opportunistic address
mov dword [si],159a5bcah ; in little endian order ; cah=program change, 5bh=program number (ie:choir) 9ah=channel select (ie:11), 15h=note value (ie:A0)
mov cl,7 ; cl=length-1 of midi data message (nb : [si+5] note volume thus must >0)
rep outsb ; output data/status to midi ; nb: last 3 outs are opportunitic
allrays: push dx ; save midi status port
mov si,320 ; absolute to ordinate divisor
raystart:mov cl,255 ; cx goes from 255 (maximum viewing distance) to 1
rayscan: mov bl,cl ; bx=z (ie: distance)
not bl ; bx goes from 1 to 255
shr bl,1 ; divide distance to get abscissas for [200;320] when inverting x and y coordinates
sub bl,128 ; bl goes from -128 to 127
mov ax,di ; ax is absolute screen coordinate
xor dx,dx ; clear multiplication recipient
div si ; divide by 320 to get abscissa ax=y, dx=x
imul dx,bx ; dh=x*r/256
mul bl ; ah=y*r/256
xchg dx,ax ; invert x and y coordinates
add ax,bp ; move camera horizontally
and ah,bl ; y=ah, z=bl (VARIATION COMMENT ME!)
cmp di,256*100 ; which half of screen ?
jc upper ; drawing lower half of screen !
not ah ; inverse y value
and ah,dh ; x=dh
jmp lower ; drawing lower half of screen ?
upper: xor ah,dh ; x=dh / drawing upper half of screen !
lower: and ah,64 ; if x & y & z & 64 = 64 then plot offset is part of cube
loopz rayscan ; loop until ray hit
mov ax,cx ; pixel color value=distance
push di ; save plot offset before displacement
add di,256*100+16 ; compensate for 09fffh vs. 0a000h
stosb ; plot pixel
pop di ; restore plot offset after displacement
inc di ; screen filled entirely ?
jnz raystart ; if not continue plotting
mov al,0eah ; midi pitch bend command byte
test byte [gs:46dh],1 ; test bios timer tick dword lsw
jz moveleft ; sign flag on half of the time
neg si ; else move camera right
moveleft:add bp,si ; move camera left
pop dx ; restore dx=330h midi status port
out dx,ax ; send status message to midi
mov al,byte [es:35440] ; get screen byte for pitch value
out dx,al ; output pitch value msb
out dx,al ; output pitch value lsb
in ax,60h ; get keyboard buffer status
dec ax ; test for escape key
jnz allrays ; if not continue to next frame
ret ; return to caller (opcode=0cfh)[ back to the prod ]
