Требуется нарисовать график y=sinx*cosx с использование функций математического сопроцессора. Уже несколько дней не могу найти ошибку: график выводится прямой линией
Использую TASM c опцией /r + TLink. Пишу под DOS
Алгоритм работы: нарисовать оси. на каждую Х-координату вычислить её масштабное значение и по нему найти значание функции. Пересчитать значание У-координаты с учётом мастабных коефициентов. Вывести график попиксельно на экран.
Код:
.386
DATA segment use16
min_x dq -3.6
max_x dq 3.6
max_crt_x dw 320 ;max count of pixels o screen
crt_x dw ? ;screen coordinate X
scale_x dq ?
min_y dq -1.1
max_y dq 1.1
max_crt_y dw 200
crt_y dw ?
scale_y dq 0.011
sin_x dq ?
cos_x dq ?
temp dq ?
temp2 dq ?
step dq 100
DATA ends
scale macro p1
;computing scale range
; (max_x - min_x) / max_crt_x
; top=0
fld max_&p1 ; st0=max_&p1; top=7
fsub min_&p1 ; st0=max_&p1 - min_&p1; ;top=7
fild max_crt_&p1 ; st0=max_crt_&p1,
; st1=max_&p1-min_&p1; top=6
fdivp st (1), st (0) ; 1st step st1=st1/st0
; 2nd step st1 ---> st0; top=7
fstp scale_&p1 ; top=0
endm
code segment use16
assume cs:code, ds:data
main:
;init graphical mode
mov ax, 13h
int 10h
;init coprocessor
finit
;coord lines
;Ox
mov crt_x,0
mov crt_y,100
mov bx,320
@loop1:
dec bx
mov dx,crt_y
mov cx,crt_x
mov ah,0ch
mov al,0111B
int 10h
inc crt_x
cmp bx,0
jne @loop1
;Oy
mov crt_x,160
mov crt_y,0
mov bx,200
@loop2:
dec bx
mov dx,crt_y
mov cx,crt_x
mov ah,0ch
mov al,0111B
int 10h
inc crt_y
cmp bx,0
jne @loop2
;comutation of scale range
scale x
scale y
;compution X and Y
mov bx,0
@loop3:
mov crt_x,bx ;screen X coord
; convert real X coord to scree X coord
; computing real Y value and converting
; to screen Y value
; top=0
fld scale_x ; st0 - scale
fild crt_x ; st0=crt_x, st1-scale
; top=6
fmulp st (1),st (0) ; top=7
fadd min_x ; st0 - real Х coord; top=7
fst temp ;temp=real X
fsin ;st(0)=sin x
fld temp ;st(0)=real X st(1)=sin x
fcos ;st(0)=cos x st(1)=sinx
fmulp st (1), st (0) ;st(0)=sin x * cos x
;now st(0) holds real Y value
;st(0)=real Y
;check coordintes (const top)
fcom min_y ;compare ST (0) and min_y
fstsw ax ;result is in ax
sahf ;ST (0) and min_y is in Flags register
jc @minus ; st0 < min_y
; out of visible range
; after @minus top=0 and crt_y=max_crt_y
fcom max_y ; compare ST (0) and max_y
fstsw ax
sahf
ja @plus ; st0 > max_y (zf=cf=0)
; out of visible range
; after @plus top=0 and crt_y=0
fsub min_y;
fdiv scale_y
frndint ; round to integer
fistp crt_y ; TOP=0!!!
mov ax,max_crt_y
sub ax,crt_y
mov crt_y,ax ; mirror (copy)
jmp @skip
@minus:
fstp temp2 ;top=0
push max_crt_y
pop crt_y ;crt_y=max_crt_y
jmp @skip
@plus:
fstp temp2 ;top=0
mov crt_y,0
@skip:
;now crt_y 100% holds screen Y coord
mov dx,crt_y ;Y-coord
mov cx,crt_x ;X-coord
mov ah,0ch ;cofig for output interrupt
mov al,0100B ;color properties
int 10h ;interrupt and pixel output
inc bx
cmp bx,320
jne @loop3 ;move X 0 --> 320
;wait for keypressed
xor ax,ax
mov ah,01h
int 21h
;exit DOS
mov ax,4c00h
int 21h
code ends
end main