home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Unsorted BBS Collection
/
thegreatunsorted.tar
/
thegreatunsorted
/
programming
/
asm_programming
/
ASM3DEMO.ZIP
/
CURVEFIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-06-04
|
7KB
|
391 lines
; 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