        dosseg
        model small
        .386

        .stack 100h

        .data
vgaseg  equ     0a000h          ; place of VGA memory
maxiter dd 200                  ; number of maximum iterations
ar      dd 0BA000000h            ; alpha real (-2.5)
ai      dd 0D1800000h            ; alpha imag (-1.5)
xi      dd 05C000000h            ; delta imag (3.0)
dfx     dw  0, 0,-5, 5, 0, 0,-1, 1  ; diff x for cursor keys
dfy     dw -5, 5, 0, 0,-1, 1, 0, 0  ; diff y for cursor keys
is      dd ?                    ; imag & real step
zr      dd ?                    ; Z real part
zi      dd ?                    ; Z imag part
i2      dd ?                    ; Z imag part^2 (well, not anymore...)
plx     dw ?                    ; counter for X-coordinate
ply     dw ?                      ; counter for Y-coordinate
cx1     dw ?                    ; x1-coord
cxd     dw ?                    ; xdiff
cy1     dw ?                    ;y1-coord
cyd     dw ?                    ;ydiff
xkeyt   db 256 dup (?)
arb     dd 50 dup (?)           ; 50 values for zoom buffer, should be 'nuff
aib     dd 50 dup (?)           ; at this 32-bit limitation and all...
xib     dd 50 dup (?)
bfpt    db ?                    ; pointer to buffer
sbuf    db 1040 dup (?)          ; save buffer for background


        .code
        mov ax, dgroup
        mov ds, ax
        mov es, ax
        mov ax, 0013h
        int 10h

        mov bfpt, 0

        lea di, xkeyt
        mov cx, 256                    ; initialize zoombox movement
        mov al, 0                       ; keyboard - table
        rep stosb
        mov xkeyt[72],1
        mov xkeyt[80],2
        mov xkeyt[75],3
        mov xkeyt[77],4
        mov xkeyt[141],5
        mov xkeyt[145],6
        mov xkeyt[115],7
        mov xkeyt[116],8
        mov ax, vgaseg
        mov es,ax

loopb:  mov ax, 320
        mov plx, ax
        mov ax, 200
        mov ply, ax
        mov eax, 147AEh           ; here begins DEEP MAGIC :->
        imul xi
        shrd eax, edx, 24
        mov is, eax
        mov di, 0
        mov esi, ai
loopy:  mov ebp, ar
loopx:  xor ecx, ecx
        mov zr, ecx
        mov eax, zr
        mov i2, eax
loopa:  mov eax, zr             ; zi = zr/2 * zi + ai
        shl eax, 1
        imul zi
        shrd eax, edx, 24
        add eax, esi
        mov zi, eax
        mov eax, i2             ; zr = i2 + ar
        add eax, ebp
        mov zr, eax
        mov ebx, eax            ; i2 = (zr+zi)(zr-zi)
        add eax, zi
        sub ebx, zi
        imul ebx
        shrd eax, edx, 24
        mov i2, eax
        inc ecx                 ; increment iteration counter
        cmp eax, 4000000h       ; test if over 4.0 already
        jg short notset               ; if, wasn't part of M-set, exit
        cmp ecx, maxiter        ; if not, test if already maxiter,
        jng loopa               ; if not, re-iterate,
        xor ecx, ecx            ; if maxiter, then part of M-set : pixel BLACK
notset: mov eax, ecx
        stosb                   ; put pixel on screen and return to main
        add ebp, is
        dec plx
        jnz loopx
        mov plx, 320
        add esi, is
        dec ply
        jnz loopy
eschk:  mov ah, 08
        int 21h
        cmp al, 0
        jne esc1
        call cs:zoom
        jc eschk
        jmp loopb
esc1:   cmp al, "+"
        jne esc2
        mov eax, maxiter
        add eax, 500
        mov maxiter, eax
        jmp loopb
esc2:   cmp al, 1Bh
        jne eschk
        mov ax, 0003h
        int 10h
        mov ax, 4c00h
        int 21h
        endp

zoom    proc near
        mov ah, 08
        int 21h
        cmp al, 73                      ;check for PageUp
        je Yes_Zoom
        cmp al, 71                      ; check for Home
        jne blah
        call cs:rest_loc                ; restore previous location
        clc
        ret                             ; go and calculate previous screen

blah:   stc
        ret
Yes_Zoom:
        call cs:save_loc                ; save zoom-box location & size

        mov ax, 0                       ; init zoom-box parameters
        mov cx1, ax
        mov cy1, ax
        mov ax, 320
        mov cxd, ax
        mov ax, 200
        mov cyd, ax
        call cs:drawbox
zl1:    mov ah, 08
        int 21h
        cmp al, 13
        jne no_cr
        movzx ebx, cx1
        mov eax, is
        imul ebx
        add eax, ar
        mov ar, eax
        movzx ebx, cy1
        mov eax, is
        imul ebx
        add eax, ai
        mov ai, eax
        movzx ebx, cyd
        mov eax, is
        imul ebx
        mov xi, eax
        clc
        ret
no_cr:  cmp al, 1Bh
        jne no_esc
        mov ax, 0003h
        int 10h
        mov ax, 4c00h
        int 21h
no_esc: cmp al, 0
        jne zl1
        mov ah, 08
        int 21h
        cmp al, 73              ; PageUp (zoom in)
        je pgup
        cmp al, 81              ; PageDown (zoom out)
        je pgdn
        lea bx, xkeyt
        xlatb
        cmp al, 0
        je zl1                 ; none of the above - test again...

        movzx bx, al
        dec bx
        shl bx, 1

        call cs:restscr
        mov ax, cy1
        add ax, dfy[bx]
        cmp ax, 0
        jnl crsr1
        mov ax, 0
crsr1:  mov cx, cyd
        add cx, ax
        cmp cx, 199
        jng crsr2
        mov ax, 200
        sub ax, cyd
crsr2:  mov cy1, ax
        mov ax, cx1
        add ax, dfx[bx]
        cmp ax, 0
        jnl crsr3
        mov ax, 0
crsr3:  mov cx, cxd
        add cx, ax
        cmp cx, 319
        jng crsr4
        mov ax, 320
        sub ax, cxd
crsr4:  mov cx1, ax
        call cs:drawbox
        jmp zl1

pgup:   call cs:restscr
        mov ax, cxd
        sub ax, 10
        cmp ax, 10
        jg pgup1
        mov ax, 10
        sub cx1, 5
        sub cy1, 3
pgup1:  mov cxd, ax
        movzx eax, ax
        lea eax, [eax+eax*4]
        shr eax, 3
        mov cyd, ax
        add cx1, 5
        add cy1, 3
        call cs:drawbox
        jmp zl1

pgdn:   call cs:restscr
        mov ax, cxd
        add ax, 10
        cmp ax, 310
        jl pgdn1
        mov ax, 310
        add cx1, 5
        add cy1, 3
pgdn1:  mov cxd, ax
        movzx eax, ax
        lea eax, [eax+eax*4]
        shr eax, 3
        mov cyd, ax
        sub cx1, 5
        sub cy1, 3
        call cs:drawbox
        jmp zl1



        endp

drawbox proc near                       ; draw the fucking zoom-box
        pushad
        mov ax, cy1
        lea eax, [eax+eax*4]
        shl eax, 6
        add ax, cx1
        mov di, ax                      ; but keep the background
        mov cx, cxd
        mov al, 15
drl1:   mov bl, es:[di]
        mov ds:[di][sbuf], bl
        stosb
        loop drl1
        add di, 320
        sub di, cxd
        mov cx, cyd
        sub cx, 2
drl2:   mov bl, es:[di]
        mov ds:[di][sbuf], bl
        stosb
        add di,cxd
        sub di,2
        mov bl, es:[di]
        mov ds:[di][sbuf], bl
        stosb
        add di, 320
        sub di, cxd
        loop drl2
        mov cx, cxd
drl3:   mov bl, es:[di]
        mov ds:[di][sbuf], bl
        stosb
        loop drl3
        popad
        ret
        endp

restscr proc near                       ; restore background screen
        pushad

        mov dx, 03dAh                ; check for vertical retrace
lbla:   in al, dx
        test al, 8
        jz lbla

        mov ax, cy1
        lea eax, [eax+eax*4]
        shl eax, 6
        add ax, cx1
        mov di, ax
        mov cx, cxd
        mov al, 15
rrl1:   mov bl, ds:[di][sbuf]
        mov es:[di], bl
        inc di
        loop rrl1
        add di, 320
        sub di, cxd
        mov cx, cyd
        sub cx, 2
rrl2:   mov bl, ds:[di][sbuf]
        mov es:[di], bl
        inc di
        add di,cxd
        sub di,2
        mov bl, ds:[di][sbuf]
        mov es:[di], bl
        inc di
        add di, 320
        sub di, cxd
        loop rrl2
        mov cx, cxd
rrl3:   mov bl, ds:[di][sbuf]
        mov es:[di], bl
        inc di
        loop rrl3
        popad
        ret
        endp

save_loc proc near
        pushad
        mov bl, bfpt
        cmp bl, 49
        jb no_flipflop
        mov cx, 150
        push es
        mov ax, ds
        mov es, ax
        lea di, arb
        mov si, di
        add si, 4
        rep movsd
        dec bl
        dec bfpt
no_flipflop:
        inc bfpt
        movzx ebx, bl
        shl bx, 2
        mov eax, ar
        mov arb[bx], eax
        mov eax, ai
        mov aib[bx], eax
        mov eax, xi
        mov xib[bx], eax
        popad
        ret
        endp

rest_loc proc near
        pushad
        mov bl, bfpt
        cmp bl, 0
        ja rest_1
        popad
        ret
rest_1: dec bfpt
        dec bl
        movzx ebx, bl
        shl bx, 2
        mov eax, arb[bx]
        mov ar, eax
        mov eax, aib[bx]
        mov ai, eax
        mov eax, xib[bx]
        mov xi, eax
        popad
        ret
        endp


        END
