; demon.asm
;
; by rick vannorman  22 august 1989
;
; genie mail r.vannorman4
;
; based on the computer recreations column by a. k. dewdney in
; scientific american august 1989
;
;
; note: this program is for vga only.  it uses mode 13h and may
; damage other video cards/monitors.  use at your own risk!
;
; assembled by turbo assembler
;
         dosseg
        .model  small

        .stack  100h

states  =       15

        .code

start:
        call    init
x001:
        call    quit
        call    copy
        call    gobble
        jmp     x001

init:
        mov     ax,13h          ; set video mode for vga
        int     10h

        mov     ax,cs           ; where are we?
        add     ax,100h         ; use memory 4k above the program
        mov     es,ax           ; for the new (extra) segment
        mov     cx,0            ; count= 64kbytes

        mov     ax,0
        mov     ds,ax
        mov     dx,[ds:046ch]      ; seed
ini001:
        mov     bx,cx
        call    random
        and     al,states
        mov     es:[bx],al
        loop    ini001

        mov     ax,0a000h       ; and the video page for data page
        mov     ds,ax

        ret

random:                         ; seed contained in dx
        mov     ax,dx
        mov     dx,31421
        imul    dx
        add     ax,13
        push    ax              ; save seed for later
        mov     dx,states+1
        imul    dx
        mov     ax,dx
        pop     dx
        ret

quit:
        mov     ah,01
        int     16h
        jnz     done
        ret
done:
        mov     ax,03           ; set text mode, later use save
        int     10h
        mov     ah,4ch
        int     21h

copy:
        mov     ax,ds           ; ds, es are constant, but reversed
        mov     bx,es
        mov     ds,bx
        mov     es,ax
        mov     si,0            ; always copy the data page
        mov     di,0            ; to the video ram
        mov     cx,8000h        ; count= 64kbytes
        rep
        movsw
        mov     ax,ds           ; swap back
        mov     bx,es
        mov     ds,bx
        mov     es,ax
        ret

gobble:                         ; assuming that ds points to video
        mov     cx,0
gob001:
        mov     bx,cx           ; bx is cell pointer

        mov     al,[bx]         ; read cell
        mov     ah,al           ; save cell's value
        dec     al              ; and get value to gobble with
        and     al,states           ; mod the number of states

        add     bx,-320         ; point to cell above
        cmp     al,[bx]         ; check for gobble condition
        jne     gob002
        mov     es:[bx],ah      ; gobble this cell in video(new)

gob002:
        add     bx,319          ; point to cell left
        cmp     al,[bx]         ; check for gobble condition
        jne     gob003
        mov     es:[bx],ah      ; gobble this cell in video(new)

gob003:
        add     bx,2            ; point to cell right
        cmp     al,[bx]         ; check for gobble condition
        jne     gob004
        mov     es:[bx],ah      ; gobble this cell in video(new)

gob004:
        add     bx,319          ; point to cell below
        cmp     al,[bx]         ; check for gobble condition
        jne     gob005
        mov     es:[bx],ah      ; gobble this cell in video(new)

gob005:
        loop    gob001

        ret

        end












