' Gray Code — converts between binary and Gray code representations
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL binaryVal AS LONG
    LOCAL grayVal AS LONG
    LOCAL decodedVal AS LONG
    LOCAL testCount AS LONG
    LOCAL passCount AS LONG
    LOCAL failCount AS LONG
    LOCAL bitCount AS LONG
    LOCAL grayStr AS STRING
    LOCAL binStr AS STRING
    LOCAL lineStr AS STRING
    LOCAL numStr AS STRING
    testCount = 0
    passCount = 0
    failCount = 0
    PRINT "============================================"
    PRINT "     GRAY CODE / BINARY CONVERTER"
    PRINT "============================================"
    PRINT ""
    PRINT "Binary to Gray code conversion"
    PRINT ""
    bitCount = 4
    PRINT "4-bit Gray code table:"
    PRINT ""
    PRINT " Dec  Binary  Gray"
    FOR i = 0 TO 15
        binaryVal = i
        grayVal = binaryVal XOR (binaryVal / 2)
        binStr = ""
        FOR j = bitCount - 1 TO 0 STEP -1
            IF (binaryVal AND (2 ^ j)) <> 0 THEN
                binStr = binStr + "1"
            ELSE
                binStr = binStr + "0"
            END IF
        NEXT j
        grayStr = ""
        FOR j = bitCount - 1 TO 0 STEP -1
            IF (grayVal AND (2 ^ j)) <> 0 THEN
                grayStr = grayStr + "1"
            ELSE
                grayStr = grayStr + "0"
            END IF
        NEXT j
        numStr = STR$(i)
        DO WHILE LEN(numStr) < 3
            numStr = " " + numStr
        LOOP
        PRINT " " + numStr + "    " + binStr + "   " + grayStr
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     GRAY CODE TO BINARY"
    PRINT "============================================"
    PRINT ""
    PRINT "Verifying round-trip conversion:"
    PRINT ""
    FOR i = 0 TO 255
        binaryVal = i
        grayVal = binaryVal XOR (binaryVal / 2)
        decodedVal = grayVal
        j = grayVal / 2
        DO WHILE j > 0
            decodedVal = decodedVal XOR j
            j = j / 2
        LOOP
        testCount = testCount + 1
        IF decodedVal = binaryVal THEN
            passCount = passCount + 1
        ELSE
            failCount = failCount + 1
            PRINT "  FAIL at " + STR$(i) + ": gray=" + STR$(grayVal) + " decoded=" + STR$(decodedVal)
        END IF
    NEXT i
    PRINT "Round-trip: " + STR$(passCount) + " passed, " + STR$(failCount) + " failed"
    PRINT ""
    PRINT "============================================"
    PRINT "     8-BIT GRAY CODE TABLE"
    PRINT "============================================"
    PRINT ""
    bitCount = 8
    FOR i = 0 TO 255
        binaryVal = i
        grayVal = binaryVal XOR (binaryVal / 2)
        grayStr = ""
        FOR j = bitCount - 1 TO 0 STEP -1
            IF (grayVal AND (2 ^ j)) <> 0 THEN
                grayStr = grayStr + "1"
            ELSE
                grayStr = grayStr + "0"
            END IF
        NEXT j
        PRINT "G(" + STR$(i) + ") = " + grayStr + " (" + STR$(grayVal) + ")"
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     PROPERTIES OF GRAY CODE"
    PRINT "============================================"
    PRINT ""
    LOCAL prevGray AS LONG
    LOCAL diffCount AS LONG
    prevGray = 0
    PRINT "Adjacent Gray codes differ by exactly 1 bit:"
    PRINT ""
    FOR i = 0 TO 31
        binaryVal = i
        grayVal = binaryVal XOR (binaryVal / 2)
        diffCount = 0
        FOR j = 0 TO 7
            IF ((grayVal XOR prevGray) AND (2 ^ j)) <> 0 THEN
                diffCount = diffCount + 1
            END IF
        NEXT j
        IF diffCount = 1 THEN
            lineStr = "PASS"
        ELSE
            lineStr = "FAIL"
        END IF
        grayStr = ""
        FOR j = 4 TO 0 STEP -1
            IF (grayVal AND (2 ^ j)) <> 0 THEN
                grayStr = grayStr + "1"
            ELSE
                grayStr = grayStr + "0"
            END IF
        NEXT j
        PRINT " " + STR$(i - 1) + "->" + STR$(i) + ": " + grayStr + " diff_bits=" + STR$(diffCount) + " (" + lineStr + ")"
        prevGray = grayVal
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     N-BIT GRAY CODE SEQUENCE"
    PRINT "============================================"
    PRINT ""
    LOCAL nBits AS LONG
    FOR nBits = 1 TO 6
        PRINT "Gray code sequence (" + STR$(nBits) + " bits):"
        grayStr = ""
        FOR i = 0 TO (2 ^ nBits) - 1
            binaryVal = i
            grayVal = binaryVal XOR (binaryVal / 2)
            grayStr = ""
            FOR j = nBits - 1 TO 0 STEP -1
                IF (grayVal AND (2 ^ j)) <> 0 THEN
                    grayStr = grayStr + "1"
                ELSE
                    grayStr = grayStr + "0"
                END IF
            NEXT j
            PRINT grayStr + " "
        NEXT i
        PRINT ""
    NEXT nBits
    PRINT ""
    PRINT "============================================"
    PRINT "     BINARY REFLECTED GRAY CODE (BRGC)"
    PRINT "============================================"
    PRINT ""
    PRINT "BRGC property: G(n) = n XOR (n >> 1)"
    PRINT ""
    FOR i = 0 TO 20
        binaryVal = i
        grayVal = binaryVal XOR (binaryVal / 2)
        binStr = ""
        FOR j = 5 TO 0 STEP -1
            IF (binaryVal AND (2 ^ j)) <> 0 THEN
                binStr = binStr + "1"
            ELSE
                binStr = binStr + "0"
            END IF
        NEXT j
        grayStr = ""
        FOR j = 5 TO 0 STEP -1
            IF (grayVal AND (2 ^ j)) <> 0 THEN
                grayStr = grayStr + "1"
            ELSE
                grayStr = grayStr + "0"
            END IF
        NEXT j
        PRINT "n=" + STR$(i) + "  bin=" + binStr + "  G(n)=" + grayStr
    NEXT i
    PRINT ""
    PRINT "Gray code conversion complete"
    FUNCTION = 0
END FUNCTION
