home *** CD-ROM | disk | FTP | other *** search
- title Biomorph
- page 58,132
- ; Biomorphs (assembler portion) Version 1.0 By Fred Dunlap from Bert Tyler program
- ; Bert Tyler (btyler on BIX)
-
- .MODEL small,c
-
- .386
- .387
- .DATA
- dotcount dd 0 ; dot-counter: 0 to a*b
- dotwrite dw 0 ; write-a-dot routine: mode-specific
- dotread dw 0 ; read-a-dot routine: mode-specific
- x dw 0 ; x-axis: 0 to (xdots-1)
- y dw 0 ; y-axis: 0 to (ydots-1)
-
- ; ; Zoom-Box values (2K x 2K screens max)
- boxcount dw 0 ; (previous) box pt counter: 0 if none.
- boxpoints dd 1028 dup(0) ; (previous) box data points
- boxvalues db 1028 dup(0) ; (previous) box color values
-
- three dd 3.0
- .DATA?
- limit_sq dq ?
- cur_x dq ?
- cur_y dq ?
- k dw ? ; local counter: 1 to maxit
- kbdcount dw ? ; keyboard counter: nnnnn to 0
- kbdflag dw ? ; keyboard hit flag: 0 if no, 1 if yes
- temp dt ?
-
- extrn dotmode: word ; video mode: 1 = use the BIOS (yuck)
- ; 2 = use EGA/VGA style
- ; 3 = use MCGA style
-
- ; ************************ External variables *****************************
-
- extrn xmin:qword, ymax:qword
- extrn c_r:qword, c_i:qword
- extrn delx:qword, dely:qword, limit:qword
- extrn xdots:word, ydots:word ; number of dots across and down
- extrn maxit:word, colors:word ; maximum iterations, colors
- extrn ixmin:word, ixmax:word ; for zoom/pan: x and y limits
- extrn iymin:word, iymax:word ; for the local zoom-box
-
- .CODE
- ; ***************** Function calcdots() **********************************
- calcdots_b3 proc
- push es ; save the original ES value
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- xor eax,eax ; initialize dot counter
- dec eax ; (to -1: it gets incremented later)
- mov dotcount,eax ; ...
-
- mov kbdcount,ax ; initialize keyboard counter (to -1)
- mov kbdflag,0 ; initialize keyboard int flag: nope
-
- ; prepare special video-mode speedups
- cmp dotmode,3 ; MCGA mode?
- je short mcgamode ; yup.
- cmp dotmode,2 ; EGA/VGA mode?
- je short vgamode ; yup.
-
- dullnormalmode:
- mov ax,offset normalwrite ; set up the BIOS write-a-dot routine
- mov bx,offset normalread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- mcgamode:
- mov ax,offset mcgawrite ; set up MCGA write-a-dot routine
- mov bx,offset mcgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- egamode:
- vgamode:
- mov ax,offset vgawrite ; set up EGA/VGA write-a-dot routine.
- mov bx,offset vgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- videomode:
- mov dotwrite,ax ; save the results
- mov dotread,bx ; ...
- fld limit
- fmul st,st
- fstp limit_sq
- fld ymax
- fstp cur_y
-
- fld three ; Often used constants kept on the stack
- fld c_i
- fld c_r
- mov y,0
-
- yloop: ; for (y = 0; y < ydots; y++)
- fld xmin ; initialize inner loop
- fstp cur_x
- mov x,0
-
- xloop: ; for (x = 0; x < xdots; x++)
- mov ax,maxit ; setup k = maxit
- mov k,ax ; (decrementing to 0 is faster)
-
- inc dotcount ; increment the dot-counter
-
- dec kbdcount ; decrement the keyboard counter
- jns maxittest ; skip keyboard test if still positive
- mov kbdcount,5000 ; else, stuff an appropriate count val
- mov ah,1 ; check the keyboard
- int 16h ; has it been hit?
- jz maxittest ; nope. proceed
- mov kbdflag,1 ; yup. reset kbd-hit flag: yes.
- jmp wedone ; so, bail out!
-
- maxittest:
- fld cur_y ; zi(0) - y
- fld cur_x ; zr(0) - x
- ; timing check: avoid the main
- cmp maxit,1 ; processing loop if maxit <= 1
- jg kloop ; ...
- mov maxit,1 ; avoid divides by zero
- mov k,0 ; pretend we have done 1 loop
- jmp kloopend ; and bail out
-
- ; This is the main processing loop. Here, every T-state counts...
-
- kloop: ; for (k = 0; k <= maxit; k++)
- fld st(1)
- fmul st,st
- fld st(1)
- fmul st,st
- fld st(1)
- fadd st,st(1)
- fcomp limit_sq
- fstsw ax
- sahf
- ja short gt_limit
- fld st(1)
- fmul st,st(7) ; *3
- fsubr st,st(1)
- fmul st,st(3)
- fadd st,st(5) ; add Cr
- fstp st(3) ; save as new Zr
-
- fmul st,st(6) ; Zr*Zr*3
- fsubrp st(1),st
- fmul st,st(2)
- fadd st,st(4) ; add Ci
- fstp st(2) ; new Zi
-
- dec k ; while (k < maxit) (dec to 0 is faster)
- jz short kloopend ; while (k < maxit) ...
- jmp kloop
-
- gt_limit:
- fstp st
- fstp st
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short fred1
- fstp st
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
- fred1:
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short kloopend1
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
-
-
- kloopend:
- fstp st ; pop z off the stack
- fstp st
- kloopend1:
- mov ax,maxit ; compute color
- sub ax,k ; (first, re-compute "k")
- sub kbdcount,ax ; adjust the keyboard count
- cmp ax,0 ; convert any "outlier" region
- jne coloradjust1 ; (where abs(x) > 2 or abs(y) > 2)
- mov ax,1 ; to look like we ran through
- coloradjust1: ; at least one loop.
- cmp ax,maxit ; did we max out on iterations?
- jne coloradjust2 ; nope.
- mov ax,1 ; reset max-out color to border color
- coloradjust2: ; (it just looks better, somehow)
- mov dx,0 ; convert to a 32-bit value
- div colors ; ...
- mov al,dl ; result in al
-
- call dotwrite ; invoke the appropriate write-a-dot
-
- loopchecks:
- fld cur_x
- inc x ; check for end of xloop
- fadd delx
- mov ax,xdots ; ...
- cmp x,ax ; ...
- fstp cur_x
- jb xloop ; more to go
-
- fld cur_y
- inc y ; check for end of yloop
- fsub dely
- mov ax,ydots ; ...
- cmp y,ax ; ...
- fstp cur_y
- jb yloop ; more to go
-
- wedone: ; restore everything and return.
- fstp st ; pop Cr off the stack
- fstp st ; pop Ci off the stack
- fstp st ; pop three off the tos
- mov ax,dotwrite ; check: were we in EGA/VGA mode?
- cmp ax,offset vgawrite ; ...
- jne wereallydone ; nope. no adjustments
- mov ax,0ff08h ; restore the default bit mask
- out dx,ax ; ...
- mov ax,0003h ; restore the function select
- out dx,ax ; ...
- mov ax,0001h ; restore the enable set/reset
- out dx,ax ; ...
- wereallydone:
- pop es ; restore the original ES value
- mov ax,kbdflag ; return the keyboard-interrupt flag
- mov boxcount,0 ; indicate no boxes drawn yet.
- ret ; and return.
-
- calcdots_b3 endp
-
- page
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- calcdots_f proc
- push es ; save the original ES value
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- mov eax,0 ; initialize dot counter
- dec eax ; (to -1: it gets incremented later)
- mov dotcount,eax ; ...
-
- mov kbdcount,ax ; initialize keyboard counter (to -1)
- mov kbdflag,0 ; initialize keyboard int flag: nope
-
-
- ; prepare special video-mode speedups
- cmp dotmode,3 ; MCGA mode?
- je mcgamode ; yup.
- cmp dotmode,2 ; EGA/VGA mode?
- je vgamode ; yup.
- dullnormalmode:
- mov ax,offset normalwrite ; set up the BIOS write-a-dot routine
- mov bx,offset normalread ; set up the BIOS read-a-dot routine
- jmp videomode ; return to common code
- mcgamode:
- mov ax,offset mcgawrite ; set up MCGA write-a-dot routine
- mov bx,offset mcgaread ; set up the BIOS read-a-dot routine
- jmp videomode ; return to common code
- egamode:
- vgamode:
- mov ax,offset vgawrite ; set up EGA/VGA write-a-dot routine.
- mov bx,offset vgaread ; set up the BIOS read-a-dot routine
- jmp videomode ; return to common code
- videomode:
- mov dotwrite,ax ; save the results
- mov dotread,bx ; ...
-
- fld limit
- fld ymax ; initialize outer loop
- mov y,0
-
- yloop: ; for (y = 0; y < ydots; y++)
- fld xmin ; initialize inner loop
- mov x,0
-
- xloop: ; for (x = 0; x < xdots; x++)
- mov ax,maxit ; setup k = maxit
- mov k,ax ; (decrementing to 0 is faster)
-
- inc dotcount ; increment the dot-counter
-
- dec kbdcount ; decrement the keyboard counter
- jns maxittest ; skip keyboard test if still positive
- mov kbdcount,5000 ; else, stuff an appropriate count val
- mov ah,1 ; check the keyboard
- int 16h ; has it been hit?
- jz maxittest ; nope. proceed
- mov kbdflag,1 ; yup. reset kbd-hit flag: yes.
- fstp st
- jmp wedone ; so, bail out!
-
- maxittest:
- fld st(1) ; dup ci into zi - y
- fld st(1) ; dup cr into zr - x
- ; timing check: avoid the main
- cmp maxit,1 ; processing loop if maxit <= 1
- jg kloop ; ...
- mov maxit,1 ; avoid divides by zero
- mov k,0 ; pretend we have done 1 loop
- jmp kloopend ; and bail out
-
- ; This is the main processing loop. Here, every T-state counts...
-
- kloop: ; for (k = 0; k <= maxit; k++)
- fld st(1)
- fmul st,st
- fld st(1)
- fmul st,st
- ; check against limit
- fld st
- fadd st,st(2)
- fcomp st(7)
- fstsw ax
-
- dec k ; while (k < maxit) (dec to 0 is faster)
- jz short kloopend ; while (k < maxit) ...
-
- sahf
- jae short kloopend
-
- fld st(3)
- fmul st,st(3)
- fadd st,st ; 2*Zi*Zr
- fadd st,st(6) ; add Ci
- fstp st(4) ; new Zi stored
-
- fsubrp st(1),st
- fadd st,st(3)
- fstp st(1) ; (x*x - y*y) + Cr
-
- jmp kloop ; ...
-
- kloopend:
- fstp st ; pop z*2
- fstp st ;
- fstp st ; pop z off the stack
- fstp st
-
- mov ax,maxit ; compute color
- sub ax,k ; (first, re-compute "k")
- sub kbdcount,ax ; adjust the keyboard count
- cmp ax,0 ; convert any "outlier" region
- jne coloradjust1 ; (where abs(x) > 2 or abs(y) > 2)
- mov ax,1 ; to look like we ran through
- coloradjust1: ; at least one loop.
- cmp ax,maxit ; did we max out on iterations?
- jne coloradjust2 ; nope.
- mov ax,1 ; reset max-out color to border color
- coloradjust2: ; (it just looks better, somehow)
- mov dx,0 ; convert to a 32-bit value
- div colors ; ...
- mov al,dl ; result in al
-
- call dotwrite ; invoke the appropriate write-a-dot
-
- loopchecks:
- inc x ; check for end of xloop
- fadd delx
- mov ax,xdots ; ...
- cmp x,ax ; ...
- jb xloop ; more to go
-
- inc y ; check for end of yloop
- fstp st
- fsub dely
- mov ax,ydots ; ...
- cmp y,ax ; ...
- jb yloop ; more to go
-
- wedone: ; restore everything and return.
- fstp st ; pop Ci off the stack
- fstp st ; pop limit off the tos
- mov ax,dotwrite ; check: were we in EGA/VGA mode?
- cmp ax,offset vgawrite ; ...
- jne wereallydone ; nope. no adjustments
- mov ax,0ff08h ; restore the default bit mask
- out dx,ax ; ...
- mov ax,0003h ; restore the function select
- out dx,ax ; ...
- mov ax,0001h ; restore the enable set/reset
- out dx,ax ; ...
- wereallydone:
- pop es ; restore the original ES value
- mov ax,kbdflag ; return the keyboard-interrupt flag
- mov boxcount,0 ; indicate no boxes drawn yet.
- ret ; and return.
-
- calcdots_f endp
-
- page
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- calcdots_b5 proc
-
- push es ; save the original ES value
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- xor eax,eax ; initialize dot counter
- dec eax ; (to -1: it gets incremented later)
- mov dotcount,eax ; ...
-
- mov kbdcount,ax ; initialize keyboard counter (to -1)
- mov kbdflag,0 ; initialize keyboard int flag: nope
-
- ; prepare special video-mode speedups
- cmp dotmode,3 ; MCGA mode?
- je short mcgamode ; yup.
- cmp dotmode,2 ; EGA/VGA mode?
- je short vgamode ; yup.
-
- dullnormalmode:
- mov ax,offset normalwrite ; set up the BIOS write-a-dot routine
- mov bx,offset normalread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- mcgamode:
- mov ax,offset mcgawrite ; set up MCGA write-a-dot routine
- mov bx,offset mcgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- egamode:
- vgamode:
- mov ax,offset vgawrite ; set up EGA/VGA write-a-dot routine.
- mov bx,offset vgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- videomode:
- mov dotwrite,ax ; save the results
- mov dotread,bx ; ...
- fld limit
- fmul st,st
- fstp limit_sq
- fld ymax
- fstp cur_y
-
- fld three ; Often used constants kept on the stack
- fld c_i
- fld c_r
- mov y,0
-
- yloop: ; for (y = 0; y < ydots; y++)
- fld xmin ; initialize inner loop
- fstp cur_x
- mov x,0
-
- xloop: ; for (x = 0; x < xdots; x++)
- mov ax,maxit ; setup k = maxit
- mov k,ax ; (decrementing to 0 is faster)
-
- inc dotcount ; increment the dot-counter
-
- dec kbdcount ; decrement the keyboard counter
- jns maxittest ; skip keyboard test if still positive
- mov kbdcount,3000 ; else, stuff an appropriate count val
- mov ah,1 ; check the keyboard
- int 16h ; has it been hit?
- jz maxittest ; nope. proceed
- mov kbdflag,1 ; yup. reset kbd-hit flag: yes.
- jmp wedone ; so, bail out!
-
- maxittest:
- fld cur_y ; zi(0) - y
- fld cur_x ; zr(0) - x
- ; timing check: avoid the main
- cmp maxit,1 ; processing loop if maxit <= 1
- jg kloop ; ...
- mov maxit,1 ; avoid divides by zero
- mov k,0 ; pretend we have done 1 loop
- jmp kloopend ; and bail out
-
- ; This is the main processing loop. Here, every T-state counts...
-
- kloop: ; for (k = 0; k <= maxit; k++)
- fld st(1)
- fmul st,st
- fld st(1)
- fmul st,st
- fld st(1)
- fadd st,st(1)
- fcomp limit_sq
- fstsw ax
- sahf
- ja short gt_limit
- fld st(1)
- fmul st,st(7) ; *3
- fsubr st,st(1)
- fmul st,st(3)
- fadd st,st(5) ; add Cr
- fstp st(3) ; save as new Zr
-
- fmul st,st(6) ; Zr*Zr*3
- fsubrp st(1),st
- fmul st,st(2)
- fadd st,st(4) ; add Ci
- fstp st(2) ; new Zi
-
- dec k ; while (k < maxit) (dec to 0 is faster)
- jz short kloopend ; while (k < maxit) ...
- jmp kloop
-
- gt_limit:
- fstp st
- fstp st
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short fred1
- fstp st
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
- fred1:
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short kloopend1
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
-
-
- kloopend:
- fstp st ; pop z off the stack
- fstp st
- kloopend1:
- mov ax,maxit ; compute color
- sub ax,k ; (first, re-compute "k")
- sub kbdcount,ax ; adjust the keyboard count
- cmp ax,0 ; convert any "outlier" region
- jne coloradjust1 ; (where abs(x) > 2 or abs(y) > 2)
- mov ax,1 ; to look like we ran through
- coloradjust1: ; at least one loop.
- cmp ax,maxit ; did we max out on iterations?
- jne coloradjust2 ; nope.
- mov ax,1 ; reset max-out color to border color
- coloradjust2: ; (it just looks better, somehow)
- mov dx,0 ; convert to a 32-bit value
- div colors ; ...
- mov al,dl ; result in al
-
- call dotwrite ; invoke the appropriate write-a-dot
-
- loopchecks:
- fld cur_x
- inc x ; check for end of xloop
- fadd delx
- mov ax,xdots ; ...
- cmp x,ax ; ...
- fstp cur_x
- jb xloop ; more to go
-
- fld cur_y
- inc y ; check for end of yloop
- fsub dely
- mov ax,ydots ; ...
- cmp y,ax ; ...
- fstp cur_y
- jb yloop ; more to go
-
- wedone: ; restore everything and return.
- fstp st ; pop Cr off the stack
- fstp st ; pop Ci off the stack
- fstp st ; pop three off the tos
- mov ax,dotwrite ; check: were we in EGA/VGA mode?
- cmp ax,offset vgawrite ; ...
- jne wereallydone ; nope. no adjustments
- mov ax,0ff08h ; restore the default bit mask
- out dx,ax ; ...
- mov ax,0003h ; restore the function select
- out dx,ax ; ...
- mov ax,0001h ; restore the enable set/reset
- out dx,ax ; ...
- wereallydone:
- pop es ; restore the original ES value
- mov ax,kbdflag ; return the keyboard-interrupt flag
- mov boxcount,0 ; indicate no boxes drawn yet.
- ret ; and return.
-
- calcdots_b5 endp
-
- page
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- calcdots_sin proc
-
- push es ; save the original ES value
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- xor eax,eax ; initialize dot counter
- dec eax ; (to -1: it gets incremented later)
- mov dotcount,eax ; ...
-
- mov kbdcount,ax ; initialize keyboard counter (to -1)
- mov kbdflag,0 ; initialize keyboard int flag: nope
-
- ; prepare special video-mode speedups
- cmp dotmode,3 ; MCGA mode?
- je short mcgamode ; yup.
- cmp dotmode,2 ; EGA/VGA mode?
- je short vgamode ; yup.
-
- dullnormalmode:
- mov ax,offset normalwrite ; set up the BIOS write-a-dot routine
- mov bx,offset normalread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- mcgamode:
- mov ax,offset mcgawrite ; set up MCGA write-a-dot routine
- mov bx,offset mcgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- egamode:
- vgamode:
- mov ax,offset vgawrite ; set up EGA/VGA write-a-dot routine.
- mov bx,offset vgaread ; set up the BIOS read-a-dot routine
- jmp short videomode ; return to common code
- videomode:
- mov dotwrite,ax ; save the results
- mov dotread,bx ; ...
- fld limit
- fmul st,st
- fstp limit_sq
- fld ymax
- fstp cur_y
-
- mov y,0
-
- yloop: ; for (y = 0; y < ydots; y++)
- fld xmin ; initialize inner loop
- fstp cur_x
- mov x,0
-
- xloop: ; for (x = 0; x < xdots; x++)
- mov ax,maxit ; setup k = maxit
- mov k,ax ; (decrementing to 0 is faster)
-
- inc dotcount ; increment the dot-counter
-
- dec kbdcount ; decrement the keyboard counter
- jns maxittest ; skip keyboard test if still positive
- mov kbdcount,2000 ; else, stuff an appropriate count val
- mov ah,1 ; check the keyboard
- int 16h ; has it been hit?
- jz maxittest ; nope. proceed
- mov kbdflag,1 ; yup. reset kbd-hit flag: yes.
- jmp wedone ; so, bail out!
-
- maxittest:
- fld cur_y ; zi(0) - y
- fld cur_x ; zr(0) - x
- ; timing check: avoid the main
- cmp maxit,1 ; processing loop if maxit <= 1
- jg kloop ; ...
- mov maxit,1 ; avoid divides by zero
- mov k,0 ; pretend we have done 1 loop
- jmp kloopend ; and bail out
-
- ; This is the main processing loop. Here, every T-state counts...
-
- kloop: ; for (k = 0; k <= maxit; k++)
- fld st(1)
- fxam
- fstsw ax
- fmul st,st
- fld st(1)
- fxam
- fstsw ax
- fmul st,st
- fadd
- fcomp limit_sq
- fstsw ax
- sahf
- ja gt_limit
- ; put handy things on the stack like sin(a), cos(a), exp(b)/2, exp(-b)/2
- ;
- fld st(1)
- fsincos
- fldl2e
- fmul st,st(3)
- fld st ; save for exp(-b)
-
- fld st
- frndint
- fxch st(1)
- fsub st,st(1)
- f2xm1
- fld1
- fsub st(2),st ; divide by 2
- fadd
- fscale
- fstp st(1)
- fxch st(1)
-
- fchs
- fld st
- frndint
- fxch st(1)
- fsub st,st(1)
- f2xm1
- fld1
- fsub st(2),st ; divide by 2
- fadd
- fscale
- fstp st(1)
- ; stack should now have a, b, sin(a), cos(a), exp(b)/2, exp(-b)/2
-
- ; calc new a = (aa-bb)+sin(a)cosh(b)
- fld st(5)
- fmul st,st
- fld st(5)
- fmul st,st
- fsub
- fld st(2)
- fadd st,st(2)
- fmul st,st(5)
- fadd
- fld st
- fstp temp
- fadd c_r
- fxam
- fstsw ax
- and ax,4500h
- cmp ax,0
- jne short ok
- out 0e4h,ax
- fstp temp
- fstp temp
- fstp temp
- fstp temp
- fstp temp
- fstp temp
- fstp temp
- ok: fxch st(6)
- ; calc new b = 2ab + cos(a)sinh(b)
- fmul st,st(5)
- fadd st,st ;*2
- fstp st(5)
- fsub
- fmul
- fadd c_i
- faddp st(2),st
-
- dec k ; while (k < maxit) (dec to 0 is faster)
- fstp st
- jz short kloopend ; while (k < maxit) ...
- jmp kloop
-
- gt_limit:
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short fred1
- fstp st
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
- fred1:
- fabs
- fcomp limit ; compare to limit
- fstsw ax
- sahf
- ja short kloopend1
- mov ax,0 ; reset max-out color to border color
- jmp short coloradjust2
-
-
- kloopend:
- fstp st ; pop z off the stack
- fstp st
- kloopend1:
- mov ax,maxit ; compute color
- sub ax,k ; (first, re-compute "k")
- sub kbdcount,ax ; adjust the keyboard count
- cmp ax,0 ; convert any "outlier" region
- jne coloradjust1 ; (where abs(x) > 2 or abs(y) > 2)
- mov ax,1 ; to look like we ran through
- coloradjust1: ; at least one loop.
- cmp ax,maxit ; did we max out on iterations?
- jne coloradjust2 ; nope.
- mov ax,1 ; reset max-out color to border color
- coloradjust2: ; (it just looks better, somehow)
- mov dx,0 ; convert to a 32-bit value
- div colors ; ...
- mov al,dl ; result in al
-
- call dotwrite ; invoke the appropriate write-a-dot
-
- loopchecks:
- fld cur_x
- inc x ; check for end of xloop
- fadd delx
- mov ax,xdots ; ...
- cmp x,ax ; ...
- fstp cur_x
- jb xloop ; more to go
-
- fld cur_y
- inc y ; check for end of yloop
- fsub dely
- mov ax,ydots ; ...
- cmp y,ax ; ...
- fstp cur_y
- jb yloop ; more to go
-
- wedone: ; restore everything and return.
- mov ax,dotwrite ; check: were we in EGA/VGA mode?
- cmp ax,offset vgawrite ; ...
- jne wereallydone ; nope. no adjustments
- mov ax,0ff08h ; restore the default bit mask
- out dx,ax ; ...
- mov ax,0003h ; restore the function select
- out dx,ax ; ...
- mov ax,0001h ; restore the enable set/reset
- out dx,ax ; ...
- wereallydone:
- pop es ; restore the original ES value
- mov ax,kbdflag ; return the keyboard-interrupt flag
- mov boxcount,0 ; indicate no boxes drawn yet.
- ret ; and return.
-
- calcdots_sin endp
-
-
- ; **************** internal Read/Write-a-dot routines ***********************
-
- normalwrite proc near ; generic write-a-dot routine
- push ax ; save the AX register for a tad
- mov eax,dotcount ; determine the row and cloumn
- mov edx,dotcount ; need it in a DX:AX pair
- ror edx,16 ; now we have it
- div xdots ; perform the divide
- mov cx,dx ; this is the x-coord
- mov dx,ax ; this is the y-coord
- pop ax ; now retrieve the AX register
- mov ah,12 ; write the dot (al == color)
- mov bx,0 ; this page
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- normalwrite endp
-
- normalread proc near ; generic read-a-dot routine
- mov eax,dotcount ; determine the row and cloumn
- mov edx,dotcount ; need it in a DX:AX pair
- ror edx,16 ; now we have it
- div xdots ; perform the divide
- mov cx,dx ; this is the x-coord
- mov dx,ax ; this is the y-coord
- mov ah,13 ; read the dot (al == color)
- mov bx,0 ; this page
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- normalread endp
-
- mcgawrite proc near ; MCGA 320*200, 246 colors
- mov ebx,dotcount ; load up an offset register
- mov es:[bx],al ; write the dot
- ret ; we done.
- mcgawrite endp
-
- mcgaread proc near ; MCGA 320*200, 246 colors
- mov ebx,dotcount ; load up an offset register
- mov al,es:[bx] ; retrieve the previous value
- ret ; we done.
- mcgaread endp
-
- vgawrite proc near ; EGA/VGA write mode 0
- mov bh,al ; save the color value for a bit
- mov esi,dotcount ; compute the buffer offset
- mov cx,si ; and bit mask
- shr esi,3 ; (buffer offset == dotcount / 8)
- and cx,7 ; bit-mask shift calculation
- xor cl,7 ; ...
- mov dx,03ceh ; graphics controller address
- mov ax,0108h ; set up controller bit mask register
- shl ah,cl ; ...
- out dx,ax ; ...
- mov ah,bh ; set set/reset registers
- mov al,0 ; ...
- out dx,ax ; ...
- mov ax,0f01h ; enable set/reset registers
- out dx,ax ; ...
- or es:[si],al ; update all bit planes
- ret ; we done.
- vgawrite endp
-
- vgaread proc near ; EGA/VGA read mode 0
- mov esi,dotcount ; compute the buffer offset
- mov cx,si ; and bit mask
- shr esi,3 ; (buffer offset == dotcount / 8)
- and cx,7 ; bit-mask shift calculation
- xor cl,7 ; ...
- mov ch,01h ; bit mask to shift
- shl ch,cl ; ...
- mov bx,0 ; initialize bits-read value (none)
- mov dx,03ceh ; graphics controller address
- mov ax,0304h ; set up controller address register
- vgareadloop:
- out dx,ax ; do it
- mov bh,es:[si] ; retrieve the old value
- and bh,ch ; mask one bit
- neg bh ; set bit 7 correctly
- rol bx,1 ; rotate the bit into bl
- dec ah ; go for another bit?
- jge vgareadloop ; sure, why not.
- mov al,bl ; returned pixel value
- ret ; we done.
- vgaread endp
-
- ; ******************** Function drawbox() *******************************
-
- drawbox proc
- local fluff7:dword ; stack fluff for safety's sake
- local loc_xmax:dword ; double-word copies of x and y
- local loc_xmin:dword ; zoom-box minimums and maximums
- local loc_ymax:dword ; ...
- local loc_ymin:dword ; ...
- local dxdots:dword ; double-word versions of total
- local dydots:dword ; number of x, y dots on screen
- local xstep:dword ; box drawing: x-step increments
- local ystep:dword ; box drawing: y-step increments
- local fluff8:dword ; stack fluff for safety's sake
- local boxcolor:byte ; box drawing: box color
- local fluff9:dword ; stack fluff for safety's sake
-
- mov eax,0 ; move word min, max values to dwords
- mov ax,ixmin ; ...
- mov loc_xmin,eax ; ...
- mov ax,ixmax ; ...
- mov loc_xmax,eax ; ...
- mov ax,iymin ; ...
- mov loc_ymin,eax ; ...
- mov ax,iymax ; ...
- mov loc_ymax,eax ; ...
- mov ax,xdots ; move xdots, ydots values to dwords
- mov dxdots,eax ; ...
- mov ax,ydots ; ...
- mov dydots,eax ; ...
-
- mov eax,1 ; default x-step: every pixel
- mov xstep,eax ; ...
- mov eax,dxdots ; default y-step: every row
- mov ystep,eax ; ...
- mov eax,loc_xmax ; just how big is this zoom-box?
- sub eax,loc_xmin ; this many dots,...
- shl eax,3 ; an eighth of the screen or less?
- cmp eax,dxdots ; ...
- jb short solidbox ; yup. keep the box solid.
- mov xstep,2 ; nope. make the box every other pixel
- mov edx,ystep ; ...
- add ystep,edx ; ...
- solidbox:
- shr eax,1 ; a quarter of the screen or less?
- cmp eax,dxdots ; ...
- jb short solidbox2 ; yup. keep the box (semi) solid.
- mov xstep,4 ; nope. make the box every 4th pixel
- add ystep,edx ; ...
- solidbox2:
-
- mov ax,colors ; define the zoom-box color
- dec al ; ...
- cmp al,15 ; do we have 16 colors?
- jbe short whitebox ; nope. use what we can get.
- mov al,15 ; force a white zoom box
- whitebox:
- mov boxcolor,al ; save the box color
-
- push es ; save the original ES value
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- mov bx,boxcount ; load up a counter: # points to clear
- dec bx ; switch to an offset value
- js short calcnewbox ; oops. no old box to clear.
- eraseoldbox:
- shl bx,2 ; switch to double-word counter
- mov edx,boxpoints[bx] ; get the (previous) point location
- mov dotcount,edx ; save it for the subroutine call
- shr bx,2 ; switch back to character counter
- mov al,boxvalues[bx] ; get the (previous) color
- push bx ; save the counter
- call dotwrite ; adjust the dot.
- pop bx ; restore the counter
- dec bx ; are we done yet?
- jns eraseoldbox ; nope. try again.
- calcnewbox:
- mov eax,loc_ymin ; calculate top-left point
- mul dxdots ; == yoffset * dots/xline
- add eax,loc_xmin ; + xoffset
- mov boxpoints,eax ; save it.
- sub eax,loc_xmin ; now calculate top-right point
- add eax,loc_xmax ; ...
- mov boxpoints+4,eax ; save it.
- mov eax,loc_ymax ; calculate bottom-left point
- mul dxdots ; == yoffset * dots/xline
- add eax,loc_xmin ; + xoffset
- mov boxpoints+8,eax ; save it.
- sub eax,loc_xmin ; now calculate bot-right point
- add eax,loc_xmax ; ...
- mov boxpoints+12,eax ; save it.
- mov boxcount,4 ; set flag: new box drawn.
- mov bx,boxcount ; get set to draw lines
- shl bx,2 ; switch to double-word pointers
- starttop:
- mov eax,boxpoints ; now, draw the top line.
- mov edx,xstep ; draw every 'step'th dot
- topline:
- add eax,edx ; calculate the next dot address
- cmp eax,boxpoints+4 ; gone past the end-of-line?
- jae short startbottom ; yup. bail out.
- mov boxpoints[bx],eax ; save this point.
- add bx,4 ; bump up the pointer offsets
- inc boxcount ; and counters
- jmp topline ; and try again.
- startbottom:
- mov eax,boxpoints+8 ; now, draw the bottom line.
- bottomline:
- add eax,edx ; calculate the next dot address
- cmp eax,boxpoints+12 ; gone past the end-of-line?
- jae short startleft ; yup. bail out.
- mov boxpoints[bx],eax ; save this point.
- add bx,4 ; bump up the pointer offsets
- inc boxcount ; and counters
- jmp bottomline ; and try again.
- startleft:
- mov eax,boxpoints ; now, draw the left line.
- mov edx,ystep ; draw every 'step'th dot
- leftline:
- add eax,edx ; calculate the next dot address
- cmp eax,boxpoints+8 ; gone past the end-of-line?
- jae short startright ; yup. bail out.
- mov boxpoints[bx],eax ; save this point.
- add bx,4 ; bump up the pointer offsets
- inc boxcount ; and counters
- jmp leftline ; and try again.
- startright:
- mov eax,boxpoints+4 ; now, draw the right line.
- rightline:
- add eax,edx ; calculate the next dot address
- cmp eax,boxpoints+12 ; gone past the end-of-line?
- jae short endlines ; yup. bail out.
- mov boxpoints[bx],eax ; save this point.
- add bx,4 ; bump up the pointer offsets
- inc boxcount ; and counters
- jmp rightline ; and try again.
- endlines:
- mov bx,boxcount ; load up a counter: # points to draw
- dec bx ; switch to an offset
- readnewbox:
- shl bx,2 ; switch to double-word counter
- mov edx,boxpoints[bx] ; get the (new) point location
- mov dotcount,edx ; save it for the subroutine call
- shr bx,2 ; switch back to character counter
- push bx ; save the counter
- call dotread ; read the (previous) dot value
- pop bx ; restore the counter
- mov boxvalues[bx],al ; get the (previous) color
- dec bx ; are we done yet?
- jns readnewbox ; nope. try again.
- mov bx,boxcount ; load up a counter: # points to draw
- dec bx ; switch to an offset
- drawnewbox:
- shl bx,2 ; switch to double-word counter
- mov edx,boxpoints[bx] ; get the (new) point location
- mov dotcount,edx ; save it for the subroutine call
- shr bx,2 ; switch back to character counter
- push bx ; save the counter
- mov al,boxcolor ; set the (new) box color
- call dotwrite ; adjust the dot.
- pop bx ; restore the counter
- dec bx ; are we done yet?
- jns drawnewbox ; nope. try again.
-
- mov ax,dotwrite ; check: were we in EGA/VGA mode?
- cmp ax,offset vgawrite ; ...
- jne short dotsdone ; nope. no adjustments
- mov ax,0ff08h ; restore the default bit mask
- out dx,ax ; ...
- mov ax,0003h ; restore the function select
- out dx,ax ; ...
- mov ax,0001h ; restore the enable set/reset
- out dx,ax ; ...
- dotsdone:
- pop es ; restore ES register
- ret ; we done.
-
- drawbox endp
-
- ; **************** Function setvideomode(ax, bx, cx, dx) ****************
-
- ; This function sets the (alphanumeric or graphic) video mode
- ; of the monitor. Called with the proper values of AX thru DX.
- ; No returned values, as there is no particular standard to
- ; adhere to in this case.
-
- setvideomode proc argax:word, argbx:word, argcx:word, argdx:word
- push ax ; save registers
- push bx ; ...
- push cx ; ...
- push dx ; ...
- push bp ; ...
- mov ax,argax ; load up for the interrupt call
- mov bx,argbx ; ...
- mov cx,argcx ; ...
- mov dx,argdx ; ...
- int 10h ; do it.
- pop bp ; restore registers
- pop dx ; ...
- pop cx ; ...
- pop bx ; ...
- pop ax ; ...
- ret
- setvideomode endp
-
-
- ; ****************** Function getakey() *****************************
-
- ; This function gets a key from either a "normal" or an enhanced
- ; keyboard. Returns either the vanilla ASCII code for regular
- ; keys, or 1000+(the scan code) for special keys (like F1, etc)
- ; Use of this routine permits the Control-Up/Down arrow keys on
- ; enhanced keyboards.
- ;
- ; The concept for this routine was "borrowed" from the MSKermit
- ; SCANCHEK utility
-
- getakey proc
- push es ; save ES for a tad
- mov ax,40h ; reload ES with BIOS data seg
- mov es,ax ; ...
- mov ah,es:96h ; get the keyboard byte
- pop es ; restore ES
- and ah,10h ; isolate the Enhanced KBD bit
- int 16h ; now get a key
- cmp al,0e0h ; check: Enhanced Keyboard key?
- jne short getakey1 ; nope. proceed
- cmp ah,0 ; part 2 of Enhanced Key check
- je short getakey1 ; failed. normal key.
- mov al,0 ; Turn enhanced key "normal"
- jmp short getakey2 ; jump to common code
- getakey1:
- cmp ah,0e0h ; check again: Enhanced Key?
- jne short getakey2 ; nope. proceed.
- mov ah,al ; Turn Enhanced key "normal"
- mov al,0 ; ...
- getakey2:
- cmp al,0 ; Function Key?
- jne short getakey3 ; nope. proceed.
- mov al,ah ; klooge into ASCII Key
- mov ah,0 ; clobber the scan code
- add ax,1000 ; + 1000
- jmp short getakey4 ; go to common return
- getakey3:
- mov ah,0 ; clobber the scan code
- getakey4:
- ret
- getakey endp
-
- end
-
-