home *** CD-ROM | disk | FTP | other *** search
- ; CURVEFIT.ASM - Sample program for ASMLIB
- ; Programmer: Douglas Herr
- ; date: 5/24/1992
- ;
- ; CURVEFIT displays a series of points on the screen and calculates
- ; the equations for curves to fit the data.
- ; CURVEFIT has not been optimized particularly, so it's likely
- ; that much could be done to make it smaller and/or faster.
- ; CURVEFIT is intended as an illustration of ASMLIB use.
-
- include asm.inc
-
- public curvefit
-
- ; non-library external subroutines
- extrn graphmode:proc, textmode:proc
-
- ; standard library external subroutines
- extrn ucinit:proc, uc2sys:proc, viewlimit:proc
- extrn drawline:proc, drawbox:proc, fillbox:proc
- extrn gcenter:proc, gprintup:proc, smalltext:proc
- extrn gprint:proc, stdtext:proc, mathchip:proc
- extrn getkey:proc, gcolor:proc, fillpattern:proc
- extrn maxi2:proc, mini2:proc, strlen:proc
- extrn linefiti2:proc, quadfiti2:proc, cubefiti2:proc
- extrn psolvef4:proc
-
-
- .data
- ; bar graph data for y-axis
- ; any integers from -32768 to 32767 may be used
- bardata dw 0,50,150,140,160,100,50,60,150,210,420,450,520
- npoints equ ($-bardata) shr 1
-
- extrn x0:word ; xmin
- extrn y0:word ; ymin
- extrn x1:word ; xmax
- extrn y1:word ; ymax
-
- a dd 0
- b dd 0
- c dd 0
- d dd 0
-
- fit_data label word
- dw (npoints shl 1) dup ('■■')
-
- color dw 1
- star db '*',0
-
-
- ; titles
-
- extrn teenager:byte
- extrn subtitle:byte
- extrn xaxis:byte
- extrn cost:byte
-
- no_mathchip db 'Math coprocessor required',0Dh,0Ah,7,'$'
- linefit db ' linear fit',0
- quadfit db ' quadratic fit',0
- cubefit db ' cubic fit',0
- measured db ' measured data',0
-
- .code
- curvefit proc
- cld
- call mathchip
- or ax,ax
- jnz c0
- lea dx,no_mathchip
- jmp short c1
- c0: call graphmode
- jnc b0 ; continue if no error
- c1: mov ah,9 ; else use DOS to write error message
- int 21h
- jmp exit ; & exit
-
- b0: push ds
- pop es
- lea di,bardata
- mov cx,npoints
- call maxi2
- shl ax,1
- mov bx,di
- add bx,ax
- mov ax,[bx] ; get maximum value
- mov y1,ax
-
- call mini2
- shl ax,1
- mov bx,di
- add bx,ax
- mov ax,[bx] ; get minimum value
- or ax,ax ; use 0 if min > 0
- js b1
- xor ax,ax
- b1: mov y0,ax
-
- mov x0,0
- mov x1,npoints
-
- push x0
- push y0
- push x1
- push y1
-
- ; establish coordinates, leaving room at edges for titles
- mov cl,3
- call set_coordinates
-
- lea bx,x0
- call ucinit
-
- ; plot the data
- mov ax,15
- call gcolor
- mov x0,0
- mov x1,1
- mov y1,0
- lea si,bardata
- mov cx,npoints ; number of data points
- call smalltext
- point: push cx
- lodsw
- push si
- mov y0,ax
- lea bx,x0
- call uc2sys
- mov ax,4[bx]
- sub ax,[bx]
- shr ax,1
- sub ax,4 ; center the marker on the point
- add [bx],ax
- sub word ptr 2[bx],4
-
- mov dx,bx ; DS:[DX] points to position data
- lea si,star
- call gprint
- inc x0
- inc x1
- pop si
- pop cx
- loop point
-
- pop y1
- pop x1
- pop y0
- pop x0
-
- ; draw the graph axes
- mov ax,15
- call gcolor
- push y0
- push y1
- mov ax,0
- mov y0,ax
- mov y1,ax
- lea bx,x0
- call uc2sys
- call drawline
- pop y1
- pop y0
- mov ax,x0
- mov x1,ax
- lea bx,x0
- call uc2sys
- call drawline
-
- ; a simple descriptive legend
- mov ax,9 ; linear fit color
- call gcolor
- mov ax,2[bx] ; y0
- cmp ax,6[bx]
- jb c5
- mov ax,6[bx]
- c5: add ax,4
- mov 2[bx],ax
- mov 6[bx],ax
- mov ax,[bx]
- cmp ax,4[bx]
- jb c6
- mov ax,4[bx]
- c6: add ax,10
- mov [bx],ax ; line length
- add ax,30
- mov 4[bx],ax
- call drawline
-
- lea si,linefit
- call print_label
-
- ; quadratic label
- mov ax,12
- call gcolor
- mov ax,2[bx]
- add ax,12
- mov 2[bx],ax
- mov 6[bx],ax
- call drawline
-
- mov ax,4[bx]
- lea si,quadfit
- call print_label
-
- ; cubic label
- mov ax,14
- call gcolor
- mov ax,2[bx]
- add ax,12
- mov 2[bx],ax
- mov 6[bx],ax
- call drawline
-
- mov ax,4[bx]
- lea si,cubefit
- call print_label
-
- ; label for measured data
- mov ax,2[bx]
- add ax,12
- mov 2[bx],ax
- add word ptr [bx],4
- sub word ptr 2[bx],4
- mov dx,bx
- lea si,star
- call gprint
-
- add word ptr 2[bx],4
- mov ax,4[bx]
- lea si,measured
- call print_label
-
- ; print main title
- mov ax,15 ; bright white
- call gcolor
- call stdtext ; larger text if not CGA
- mov y0,0
- lea dx,x0
- lea si,teenager
- call gcenter
-
- ; print subtitle
- call smalltext ; 8x8 character size
- lea si,subtitle
- mov y0,16
- call gcenter
-
- ; print x-axis label
- call viewlimit
- mov ax,2[bx] ; maximum y
- push ax
- sub ax,10
- mov y0,ax
- lea si,xaxis
- call gcenter
-
- ; print y-axis label
- lea bx,cost
- call strlen
- mov si,bx
- mov bx,cx
- mov cl,3
- shl bx,cl ; length of string in pixels
- pop ax ; maximum y
- add ax,bx ; maximum y plus len(string)
- shr ax,1
- mov y0,ax
- mov x0,0
- call gprintup
-
- ; convert data to linefit format
- lea di,fit_data
- mov bx,di ; save for LineFit
- push ds
- pop es
- mov ax,1
- mov cx,npoints
- lea si,bardata
- c9: stosw
- movsw
- inc ax
- loop c9
-
- ; calculate line equation
- mov cx,npoints
- call linefiti2
-
- fstp a
- fstp b
-
- ; solve for y given x
- mov ax,9
- call gcolor ; bright blue
- mov dx,1 ; 1st order equation
- call solve0
-
- ; calculate quadratic equation
- lea bx,fit_data
- mov cx,npoints
- call quadfiti2
- fstp a
- fstp b
- fstp c
-
- ; solve for y given x
- mov ax,12 ; bright red
- call gcolor
- mov dx,2 ; 2nd order equation
- call solve0
-
- ; calculate cubic equation
- lea bx,fit_data
- mov cx,npoints
- call cubefiti2
- fstp a ; save equation coefficients
- fstp b
- fstp c
- fstp d
-
- ; solve for y given x
- mov ax,14 ; yellow
- call gcolor
- mov dx,3 ; 3rd order equation
- call solve0
-
- ; wait for any keypress, then return to text mode
- call getkey
- call textmode
- exit: ret
-
- curvefit endp
-
- ; SET_COORDINATES is outside MYMAIN because it'a always a near call
- ; this subroutine adjusts the user-defined coordinates to allow
- ; room on all sides for titles, etc.
- set_coordinates:
- lea si,x0 ; adjust x-coordinates
- call s0
- add si,2 ; now do it for y
- s0: mov ax,4[si]
- sub ax,[si] ; delta x
- shr ax,cl
- sub [si],ax
- add 4[si],ax
- ret
-
- ; SOLVE0 is outside MYMAIN because it's always a near call
- solve0: lea si,a
- mov cx,npoints+1
- mov x0,0
- mov y0,0
- mov x1,0
- solve1: push cx
- mov cx,dx
- finit
- fild x1
- call psolvef4
- fistp y1
- cmp x1,0
- je solve2
- lea bx,x0
- call uc2sys
- call drawline
- solve2: push x1
- push y1
- pop y0
- pop x0
- inc x1
- pop cx
- loop solve1
- ret
-
- print_label:
- push [bx]
- push 2[bx]
-
- add ax,3
- mov [bx],ax
- mov ax,15
- call gcolor
- sub word ptr 2[bx],3
- mov dx,bx
- call gprint
-
- pop 2[bx]
- pop [bx]
- ret
-
- end