Search code examples
assemblygraphx86fpuyasm

How to draw a graph within the intervals in YASM 8086


I have to draw a graph y = cos(x2+x+1) interval: [-π/2,π/2]. I have the graph without the interval, just making calculations with the screen resolution 320 x 200.

This is my code so far:

;------------------------------------------------------------------------
%include 'yasmmac.inc'  
org 100h                       

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text                   ; code starts here
   startas:
      call procSetGraphicsMode

     xor  di, di     ; Y
   .vertical:
     mov  si, 160    ; X
     mov  cl, 15     ; Color
     call procPutPixel
     inc  di
     cmp  di, 199    ; MaxY
     jbe  .vertical

     xor  si, si     ; X
   .horizontal:        
     mov  di, 100    ; Y
     mov  cl, 15     ; Color
     call procPutPixel
     inc  si
     cmp  si, 319    ; MaxX
     jbe  .horizontal

  ; y = di
  ; x = si
  mov si, 320
  mov di, 100

      xor   si, si          ; X
    fninit
    fld1                  ; CONST 1
.loop:
    mov   [valueX], si    ; X
    fild  word [valueX]   ; st0 = X
    fmul  st0             ; st0 = X^2
    fiadd word [valueX]   ; st0 = X^2 + X
    fadd  st0, st1        ; st0 = X^2 + X + 1
    fcos                  ; st0 = cos(X^2 + X + 1)         [-1,+1]
    fimul word [scaleY]
    fistp word [y]        ; {-1,0,+1}
    mov   di, 100         ; Y
    add   di, [y]         ; -> Y={99,100,101}
    mov   cl, 4           ; Color
    call  procPutPixel
    inc   si
    cmp   si, 319
    jbe   .loop


   call procWaitForEsc 
  exit
      

%include 'yasmlib.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data                   ; data
     R:
     dd  50.0

   value1: 
      dd  0.0
   value2:
      dd  0.0
   value3:
      dd 1.0

   valueX:  
      dw 0
   
   scaleY: 
       dw 60
          
     x: 
     dw  0
     y:
     dw 0
     
     N:
     dw 360  
     
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss            

This code section draws a coordinate plane and the graph, not in the given interval [-π/2,π/2]. This is how it draws a graph (not in the interval)

What I want the program to do is to draw that interval within the interval [-π/2,π/2]. So it would look something like this: Needed graph

I need somehow scale my X so that the graph would be within the intervals.

I was thinking to make the starting point of X in the center (160), but I can't imagine, how to move to both sides (negative - towards -π/2 and positive - towards π/2). I have tried to explain that as clearly as I could.

If more information is needed, I will try to edit the question.


Solution

  • graph y = cos(x2+x+1)

    I am confused now: is it cos(x2 + x + 1) or cos(x^2 + x + 1) that you want to draw? The link in your previous question (but not the text in the question) and the picture in this question are showing the former, but my answers then and now are about the latter.
    A case for being x^2 + x + 1 is that x2 + x + 1 would sooner be written as 3x + 1.

    I have included a picture that confines the graph to a rectangle that has a width of 289 pixels and an height of 181 pixels.
    Because the rectangle is centered on the screen, its coordinates in X will range from 16 to 304 and its coordinates in Y will range from 10 to 190.
    Because X=0 is in the middle of the X-axis, the physical range [16,304] corresponds to the logical range [-144, +144]. You have asked for -144 to align with -π/2 and +144 to align with +π/2. The rule of three to the rescue:

    144 .. (π/2)
      1 .. (π/2) / 144
      n .. (π/288) * n
    

    So (π/288) will be the factor to apply to all the logical X's that you feed the code.

      ORG   256             ; cos(X^2 + X + 1)
    
      mov   ax, 0013h       ; Set 320x200 256-color screen
      int   10h
    
      mov   dx, 100         ; Y
      mov   cx, 11          ; X
      mov   bh, 0           ; DisplayPage
    X:
      mov   ax, 0C07h       ; BIOS.WritePixel White
      int   10h
      inc   cx              ; X++
      cmp   cx, 309
      jbe   X
    
      mov   dx, 5           ; Y
      mov   cx, 160         ; X
    Y:
      mov   ax, 0C07h       ; BIOS.WritePixel White
      int   10h
      inc   dx              ; Y++
      cmp   dx, 195
      jbe   Y
    
      fninit
      fldpi
      fidiv word [DeltaX]   ; CONST (π/288)
      fld1                  ; CONST 1
      mov   si, -144        ; LogicalX
    work:
      mov   [Temp], si
      fild  word [Temp]     ; st0 = LogicalX
      fmul  st2             ; st0 = LogicalX * (π/288) = X        [-π/2,+π/2]
      fld1                  ; st1 = X, st0 = 1
      fadd  st1             ; st1 = X, st0 = X + 1
      fmulp                 ; st0 = X * (X + 1) = X^2 + X
      fadd  st1             ; st0 = X^2 + X + 1
      fcos                  ; st0 = cos(X^2 + X + 1)              [-1,+1]
      fimul word [ScaleY]   ; st0 = cos(X^2 + X + 1) * 90         [-90,+90]
      fistp word [Temp]
      mov   dx, 100         ; Position of the X-axis
      sub   dx, [Temp]      ; DX is PhysicalY
      lea   cx, [si+160]    ; CX is PhysicalX
      mov   ax, 0C0Fh       ; BIOS.WritePixel BrightWhite
      int   10h
    
      mov   [Temp], si
      fild  word [Temp]     ; st0 = LogicalX
      fmul  st2             ; st0 = LogicalX * (π/288) = X        [-π/2,+π/2]
      fcos                  ; st0 = cos(X^2 + X + 1)              [-1,+1]
      fimul word [ScaleY]   ; st0 = cos(X^2 + X + 1) * 90         [-90,+90]
      fistp word [Temp]
      mov   dx, 100         ; Position of the X-axis
      sub   dx, [Temp]      ; DX is PhysicalY
      lea   cx, [si+160]    ; CX is PhysicalX
      mov   ax, 0C0Eh       ; BIOS.WritePixel Yellow
      int   10h
    
      inc   si
      cmp   si, 144
      jle   work
      fninit                ; Remove constants
    
      mov   ah, 00h
      int   16h
      mov   ax, 0003h
      int   10h
      ret
    ; ----------------------
    DeltaX: dw 288
    ScaleY: dw 90
    Temp:   dw 0
    

    I have added the cosine graph in yellow for verification purposes. That's a trick I've picked up over the years when dealing with expressions for which the graph does not have an obvious shape.

    8Graph