;=========================================================
; File:    Fcn.asm
; Purpose: Show how to plot an equation using graphics
;=========================================================

include 'emu8086.inc'

        org  100h           ; set location counter to 100h

        jmp  CodeStart

DataStart:

numX    dw   -60            ; min x value
numXmax dw   +60            ; max x value
xIncr   dw   4              ; display every 4th pixel
numY    dw   ?              ; numY = f(numX)
color   db   ?              ; color to use for display


; Plot a quadratic equation along with axes
CodeStart:

        mov  al, 13h        ; set video mode 320x200, 256 colors
        mov  ah, 0
        int  10h

        call Xaxis          ; draw x-axis
        call Yaxis          ; draw y-axis
        
; for (ax = numX; ax <= numXmax; ax += 5)
        mov  color, 52      ; set color for the curve
Lup:      
        mov  ax, numX       ; get x
        call Fcn            ; calculate f(x)
        mov  NumY, ax       ; save y = f(x)
        
        mov  ax, numX
        mov  bx, numY
        call Plot           ; plot (x,y)

        mov  ax, numX
        add  ax, xIncr      ; run x in steps of xIncr
        mov  numX, ax
        cmp  ax, numXmax
        jle  Lup            ; loop until done

        call Legend         ; draw legend
       
        ret                 ; return to caller


;========================================================== 
; Plots a pixel at (x,y); assumes that (x,y) are in (AX,BX)
; Uses AX (AH and AL), CX, DX
Plot    PROC
        mov  cx, ax
        add  cx, 160        ; translate for x origin
        mov  dx, bx
        neg  dx             ; invert for normal positive y "up"
        add  dx, 100        ; translate for y origin
        mov  al, color      ; set color
        mov  ah, 0ch        ; subfunction for drawing a pixel
        int  10h

        ret                 ; return to caller
Plot ENDP


;==========================================================
; Display x-axis
Xaxis   PROC
        mov  ax, xMax       ; set min/max for axis 
        neg  ax
        mov  x, ax
        mov  color, 40      ; set axis color

Xlup:   
        mov  ax, x
        mov  bx, 0
        call Plot
        add  x, 8           ; display every 8th pixel
        mov  ax, x
        cmp  ax, xMax
        jle  Xlup 

        ret                 ; return to caller
Xaxis   ENDP

x       dw   ?
xMax    dw   80             ; min/max x-axis coordinate


;==========================================================
; Display y-axis
Yaxis   PROC
        mov  ax, yMax       ; set min/max for axis
        neg  ax
        mov  y, ax
        mov  color, 40      ; set axis color
YLup:
        mov  ax, 0
        mov  bx, y
        call Plot
        add  y, 8           ; display every 8th pixel
        mov  ax, y
        cmp  ax, yMax
        jle  Ylup
 
        ret                 ; return to caller
Yaxis   ENDP

y       dw   ?
yMax    dw   72             ; min/max y-axis coordinate


;==========================================================
; y = f(x) = x^2 / 32 - 50  x is in AX; result in AX 

Fcn     PROC
        mov  dx, 0          ; prepare for multiplication
        mov  bx, ax
        imul bx             ; AX now contains x^2
        sar  ax, 5          ; AX now contains x^2/32
        sub  ax, 50         ; AX now contains x^2/32 - 50

        ret                 ; return to caller
Fcn     ENDP


;==========================================================
; Display the legend
; See www.emu8086.com/assembly_language_tutorial_assembler_reference/
;     for details on all the 8086 interrupts and color attributes
Legend  PROC
    	mov  al, 1
    	mov  bh, 0
    	mov  bl, 0011_1011b ; color attributes
    	mov  cx, msg1end - offset msg1 ; calculate message size 
    	mov  dl, 8          ; column
    	mov  dh, 23         ; row
    	push cs
    	pop  es
    	mov  bp, offset msg1
    	mov  ah, 13h        ; subfunction for display a string
    	int  10h
    	jmp  msg1end
msg1    db   " y = f(x) = x^2/32 - 50 "
msg1end:
        ret
Legend  ENDP
