I don't know if anyone will be able to help me, but I will try to explain my problem as clearly, as possible. I am learning 8086 FPU with YASM. I want to draw y = cos(x^2+x+1) This is how this graph looks like. I am doing it in DosBox, and I am emulating 8086 processor.
My problem: How to normalize graph's(red) ratio, so it could be readable in DosBox.
So far, I managed to draw a coordinate plane. And I think I managed to draw this graph, but the ratio is too small to check if it is really good. This is how it looks so far GRAPH IMAGE](https://i.stack.imgur.com/0Hy6X.jpg).
I am using FPU, to calculate Y coordinates. I am using stack to calculate Y coordinate. X coordinate will go from 320 to 0 (with dec si), as you can see in my code.
In this code, I am trying to calculate Y (di) every with different X (si). And put the pixel in the spot, that it has to be in.
;------------------------------------------------------------------------
%include 'yasmmac.inc'
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text ; Code starts here
startas:
call procSetGraphicsMode
;;;;;;;;;;;;;;;;;;;;;;;;; COORDINATE PLANE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov di, 200
mov si, 160
.vertical:
mov cl, 15
call procPutPixel
dec di
jnz .vertical
mov si, 320
.horizontal:
mov di, 100
mov cl, 15 ; 15 = white color
call procPutPixel
dec si
jnz .horizontal
; y = di
; x = si
mov si, 320
mov di, 100
;;;;;;;;;;;;;;;;;;;;;;;; GRAPH ;;;;;;;;;;;;;;;;;;;;;;;;
.loop:
mov [value1], si
mov [value2], si
finit
fild dword [value1]
fild dword [value1]
fild dword [value3] ; move to stack 1
fmul dword [value1]
fadd st0, st1 ; add x in stack head
fadd st0, st3 ; add 1 in stack head
fcos ; cos(x^2 + x + 1)
frndint ; round
fistp word [y] ; Load rounded answer to [y] variable
add di, [y] ; Add [y] to di
mov cl, 4 ; 4 = Red color
call procPutPixel
dec si
jnz .loop
;;;;;;;;;;;;;;;;;;;;;;;; WAIT FOR ESC ;;;;;;;;;;;;;;;;;;;;;;;;
call procWaitForEsc
exit
%include 'yasmlib.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data ; data
value1:
dd 0.0
value2:
dd 0.0
value3:
dd 1.0
xc:
dw 160
yc:
dw 100
x:
dw 0
y:
dw 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss
yasmlib.asm If it helps
The axes are the easy part
Since you are working on a graphics screen that has a resolution of 320 x 200, the X coordinates range from 0 to 319 and the Y coordinates range from 0 to 199. Your code erroneously outputs in X's of 320 and y's of 200 and you don't use the X's of 0 or the Y's of 0.
The data definitions
Your FPU instructions are dealing with values stored in memory, but are doing so in incompatible ways! eg. value1 can't be both an integer dword and an single precision float at the same time. You primed this variable with the value from the 16-bit integer register SI, so deal with it as a 16-bit integer.
The calculation
finit(better use the non-waitingfninit) is best held outside of the loop.frndintis redundant sincefistp word [y]will automatically do the rounding for you.fmul st0can square the value from st0.fld1can load the value 1 to the FPU stack. No need for a memory based variable and also no need to reload it for every X.Getting the output readable
The cosine value that the FPU delivers ranges from -1 to +1, but storing this value in the integer memory variable y will produce but 3 discrete values -1, 0, and +1.
What is needed is scaling the cosine by some factor like say 60.
Add this to the data:
and at the ellipses you add
fimul word [scaleY], producing: