; stereo.asm by Michael Kohn
; Started: April 27, 1995

.model tiny
.286

.data
mess1 db "Stereogram TSR - By Michael Kohn",13,10
      db "Press F10 to make stereogram",13,10
      db 10,'$'
sdepth db 16 
LocX dw 0
LocY dw 0
DEnd dw 0
color db 50 dup(0) 
depth db 0
OldKey label dword
  KeyIP dw 0
  KeyCS dw 0

CTable db 0,4,43,12,61,21,11,1,3,2,16,60,56,44,9,2,0,255
ColorQ db 1,1,256 dup(0)
CQPoint dw 0

.stack 256

.code

cut proc
  push di
again2:
  mov al, [di]+1
  mov [di], al 
  inc di
  cmp di, DEnd
  jc again2
  pop di
  dec DEnd
  ret
cut endp

inert proc
  push si
  inc DEnd
  mov si, DEnd 
ForA:
  mov al, [si]-1
  mov [si], al
  dec si
  cmp si, di
  jnz ForA
  mov al, 0
  out 43h, al
  in al, 40h
  and al, 15
  mov [di], al
  in al, 40h 
  pop si
  ret
inert endp

flush proc
fagain:
  cmp byte ptr [si], 0      ; flush ColorQ (really a stack :) 
  je fdone
  call inert
  dec si
  jmp fagain
fdone:
   mov CQPoint, si
   ret
flush endp

random proc
  mov al, 0 
  out 43h, al
  in al, 40h      ; picks a 1 byte number out of the system timer
  lea si, start
  mov ah, 0
  add si, ax      ; si = start + Timer 0 LSB = random numbers :)
  in al, 40h
  ret
random endp

pdot proc
  mov bh, 0
  mov cx, 300
  mov dx, 300
  mov al, 15 
  mov ah, 0ch
  int 10h
  ret
pdot endp

start:
  jmp installation

stereo:
  mov ax, @data 
  mov ds, ax

  push ds
  pop es

  mov ah, 10h
  mov al, 2
  lea dx, CTable
  int 10h

  mov LocY, 0             ;  For Y = 0 to 349 
ForY:
  mov cl, sdepth           ;  For Z = depth+1 to 1 step -1
  mov depth, cl 
  inc cl
  lea di, color 
  call random
  mov ax, 0
  mov es, ax 
ForZ:
  mov al, es:[si] ; make a pattern and put in color array
  and al, 15
  mov [di], al
  inc di
  inc si
  dec cl
  jnz ForZ                ; next Z
  lea si, ColorQ
  mov CQPoint, si
  mov ColorQ, 0           ; stick 0 onto stack 
  mov LocX, 0             ; For X = 0 to 639 
  lea di, color 
  mov DEnd, di
  mov cl, sdepth
  mov ch, 0
  inc cl
  add DEnd, cx 
ForX:
  mov bh, 0
  mov cx, LocX
  mov dx, LocY
  mov al, [di]
  mov ah, 0ch
  int 10h
  inc di                  ; next color
  cmp di, DEnd            ; if di <> depth+1 then goto skip1
  jc skip1
  lea di, color           ; di = 0
skip1:
  inc LocX
  mov ax, DEnd 
  lea bx, color 
  sub ax, bx
  and ax, 65532
  cmp ax, 0
  je nodep
  mov bh, 0
  mov ah, 0dh
  mov cx, LocX
  mov dx, LocY
  int 10h
  mov si, CQPoint
  mov ah, [si]
  cmp al, ah
  je nodep
  cmp al, 0
  jnz nobot
  call flush
  jmp nodep
nobot:
  mov ah, [si]-1
  cmp al, ah
  je QPop
  mov [si]+1, al
  call cut
  inc CQPoint 
  jmp nodep
QPop:
  call inert
  dec CQPoint  
nodep:
  cmp word ptr LocX, 640     ; next X (already incremented earlier)
  je EForX
  jmp ForX
EForX:
  inc word ptr LocY       ; next Y
  cmp word ptr LocY, 350
  jz skip4
  jmp ForY
     
skip4:
  pop es
  popa
  jmp cold

NewKey:
  cmp ah, 4fh
  jne cold

  cmp al, 44h
  jnz cold
  pusha
  push es  
  jmp stereo

 cold:
  jmp cs:OldKey

installation:
  push cs
  pop ds
  mov al, 15h 
  mov ah, 35h
  int 21h
  mov KeyIP, bx
  mov KeyCS, es
  lea dx, NewKey
  mov al, 15h
  mov ah, 25h
  int 21h 

  mov ah, 9 
  lea dx, mess1
  int 21h

  mov dx, 100h
  mov al, 0
  mov ah, 31h
  int 21h
end start



