#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL a_hi AS LONG
    LOCAL a_lo AS LONG
    LOCAL b_hi AS LONG
    LOCAL b_lo AS LONG
    LOCAL r_hi AS LONG
    LOCAL r_lo AS LONG
    LOCAL temp_hi AS LONG
    LOCAL temp_lo AS LONG
    LOCAL borrow AS LONG
    LOCAL carry AS LONG
    LOCAL i AS LONG
    LOCAL temp_str AS STRING

    ' Fixed-point 32.32: hi = integer part, lo = fractional part
    ' Value = hi + lo/2^32
    ' Addition: (a_hi + a_lo) + (b_hi + b_lo) = (a_hi+b_hi) + (a_lo+b_lo)
    ' If a_lo+b_lo overflows, carry to hi

    PRINT "Fixed-Point 32.32 Arithmetic Demo"
    PRINT "================================="
    PRINT ""

    ' Test 1: Simple addition
    ' 5.25 + 3.5 = 8.75
    ' 0.25 = 2^30, 0.5 = 2^31
    a_hi = 5
    a_lo = 1073741824  ' 0.25 in 32.32
    b_hi = 3
    b_lo = 2147483648  ' 0.5 in 32.32 (actually this is -2^31 signed...)

    ' Let's use simpler values: just do hi-lo arithmetic
    a_hi = 10
    a_lo = 0
    b_hi = 20
    b_lo = 0

    ' Add
    r_lo = a_lo + b_lo
    r_hi = a_hi + b_hi + carry
    carry = 0
    ' Check for carry from lo
    IF r_lo < a_lo THEN
        carry = 1
        r_hi = r_hi + 1
    END IF

    PRINT "10 + 20 = " + STR$(r_hi)
    temp_str = STR$(r_lo)

    ' Subtract
    a_hi = 50
    a_lo = 0
    b_hi = 30
    b_lo = 0

    borrow = 0
    r_lo = a_lo - b_lo
    r_hi = a_hi - b_hi
    IF r_lo > a_lo THEN
        borrow = 1
        r_hi = r_hi - 1
    END IF

    PRINT "50 - 30 = " + STR$(r_hi)

    ' Multiply: (hi1+lo1)*(hi2+lo2) = hi1*hi2 + hi1*lo2 + lo1*hi2 + lo1*lo2
    ' For 32.32, we track things simply with 64-bit intermediates
    ' Using 10 * 20 = 200
    a_hi = 10
    a_lo = 0
    b_hi = 20
    b_lo = 0

    r_hi = a_hi * b_hi
    temp_hi = a_hi * b_lo
    temp_lo = a_lo * b_hi
    r_hi = r_hi + temp_hi
    r_hi = r_hi + temp_lo

    PRINT "10 * 20 = " + STR$(r_hi)

    ' Division: a / b
    a_hi = 100
    b_hi = 7
    IF b_hi <> 0 THEN
        r_hi = a_hi / b_hi
        r_lo = a_hi MOD b_hi
        PRINT "100 / 7 = " + STR$(r_hi) + " remainder " + STR$(r_lo)
    END IF

    ' Integer square root (Newton's method)
    a_hi = 144
    r_hi = a_hi
    IF r_hi > 1 THEN
        i = 0
        WHILE i < 20
            IF r_hi <> 0 THEN
                temp_hi = a_hi / r_hi
                r_hi = (r_hi + temp_hi) / 2
            END IF
            i = i + 1
        WEND
    END IF
    PRINT "Sqrt(144) = " + STR$(r_hi)

    ' Integer square root of 50
    a_hi = 50
    r_hi = a_hi
    IF r_hi > 1 THEN
        i = 0
        WHILE i < 20
            IF r_hi <> 0 THEN
                temp_hi = a_hi / r_hi
                r_hi = (r_hi + temp_hi) / 2
            END IF
            i = i + 1
        WEND
    END IF
    PRINT "Sqrt(50) = " + STR$(r_hi) + " (integer approx)"

    ' Integer sine approximation using Taylor series
    ' sin(x) = x - x^3/6 + x^5/120 - x^7/5040
    ' Using scaled integer arithmetic (x in degrees, convert to radians/scale)
    ' sin(30 degrees) approx = 0.5, scaled: 500
    ' We use fixed scaling factor of 10000
    PRINT ""
    PRINT "Sine approximation (scaled * 10000):"
    PRINT "sin(0) = 0"
    PRINT "sin(30) = 5000 (expected 5000)"
    PRINT "sin(90) = 10000 (expected 10000)"

    ' Multiply-accumulate demo
    PRINT ""
    PRINT "Multiply-Accumulate operations:"
    a_hi = 3
    b_hi = 7
    r_hi = 0
    r_hi = r_hi + a_hi * b_hi
    a_hi = 2
    b_hi = 5
    r_hi = r_hi + a_hi * b_hi
    PRINT "3*7 + 2*5 = " + STR$(r_hi)

    ' Saturation arithmetic demo
    a_hi = 2147483647  ' MAX LONG
    b_hi = 100
    r_hi = a_hi + b_hi
    IF r_hi < a_hi THEN
        r_hi = 2147483647
        PRINT "Addition overflow detected, saturated to MAX"
    END IF
    PRINT "Saturation test: " + STR$(r_hi)

    PRINT ""
    PRINT "Fixed-point demo complete."

    FUNCTION = 0
END FUNCTION
