//
// MegaFlash FPU Test Program
// Demonstrates hardware-accelerated floating point operations
//
include "inc/cmdsys.plh"
import fpu_mf
import console

byte[80] strBuf

//
// Print a floating point value
//
def printFP(label)
    fpu_mf:pullStr(@strBuf, 1, 8, FPSTR_FIXED)
    puts(label)
    puts(@strBuf)
    putln
end

//
// Test basic arithmetic operations
//
def testArithmetic
    puts("\n=== Testing Arithmetic ===\n")

    // Test multiplication: 3.14159 * 2.0
    puts("3.14159 * 2.0 = ")
    fpu_mf:pushStr("3.14159")
    fpu_mf:pushStr("2.0")
    fpu_mf:mul
    printFP("")

    // Test division: 10.0 / 3.0
    puts("10.0 / 3.0 = ")
    fpu_mf:pushStr("10.0")
    fpu_mf:pushStr("3.0")
    fpu_mf:div
    printFP("")

    // Test square root: sqrt(2.0)
    puts("sqrt(2.0) = ")
    fpu_mf:pushStr("2.0")
    fpu_mf:sqrt
    printFP("")

    // Test squared: 7.0^2
    puts("7.0^2 = ")
    fpu_mf:pushStr("7.0")
    fpu_mf:squared
    printFP("")
end

//
// Test trigonometric functions
//
def testTrig
    puts("\n=== Testing Trigonometry ===\n")

    // Test sine: sin(PI/2) should be 1.0
    puts("sin(PI/2) = ")
    fpu_mf:constPi
    fpu_mf:pushStr("2.0")
    fpu_mf:div
    fpu_mf:sin
    printFP("")

    // Test cosine: cos(0) should be 1.0
    puts("cos(0) = ")
    fpu_mf:pushStr("0.0")
    fpu_mf:cos
    printFP("")

    // Test tangent: tan(PI/4) should be 1.0
    puts("tan(PI/4) = ")
    fpu_mf:constPi
    fpu_mf:pushStr("4.0")
    fpu_mf:div
    fpu_mf:tan
    printFP("")

    // Test arctangent: atan(1.0) should be PI/4
    puts("atan(1.0) = ")
    fpu_mf:pushStr("1.0")
    fpu_mf:atan
    printFP("")

    puts("(should be ~0.785398)")
end

//
// Test logarithmic and exponential functions
//
def testLogExp
    puts("\n=== Testing Log/Exp ===\n")

    // Test natural log: ln(e) should be 1.0
    puts("ln(e) = ")
    fpu_mf:constE
    fpu_mf:lnX
    printFP("")

    // Test exponential: e^1 should be e
    puts("e^1 = ")
    fpu_mf:pushStr("1.0")
    fpu_mf:powEX
    printFP("")
    puts("(should be ~2.71828)")

    // Test e^0 should be 1.0
    puts("e^0 = ")
    fpu_mf:pushStr("0.0")
    fpu_mf:powEX
    printFP("")
end

//
// Test constants
//
def testConstants
    puts("\n=== Testing Constants ===\n")

    puts("PI = ")
    fpu_mf:constPi
    printFP("")

    puts("E = ")
    fpu_mf:constE
    printFP("")
end

//
// Performance benchmark
//
def testPerformance
    word i, startTime, endTime, iterations
    byte[10] timeStr

    iterations = 100

    puts("\n=== Performance Test ===\n")
    puts("Running ")
    puti(iterations)
    puts(" iterations of sin(x)...\n")

    // Note: This is a simple timing test
    // On real hardware with MegaFlash, you'll see significant speedup

    for i = 0 to iterations - 1
        fpu_mf:pushStr("1.5707963")  // PI/2
        fpu_mf:sin
        fpu_mf:shiftDown  // Drop result
    next

    puts("Complete!\n")
end

//
// Main program
//
def main
    byte key

    // Initialize FPU
    puts("\nMegaFlash FPU Test Program\n")
    puts("==========================\n")

    if fpu_mf:reset
        puts("ERROR: Failed to initialize FPU\n")
        return 1
    fin

    // Run all tests
    testConstants
    testArithmetic
    testTrig
    testLogExp
    testPerformance

    puts("\n=== All Tests Complete ===\n")
    puts("\nPress any key to continue...")
    key = getc

    return 0
end

// Run the main program
main
done
