' Bit Manipulation — BYTE/WORD/DWORD with AND/OR/XOR masks
#COMPILE EXE
#DIM ALL

SUB BinString(n AS DWORD, bits AS LONG, BYREF result AS STRING)
    LOCAL i AS LONG
    LOCAL bit AS DWORD
    result = ""
    FOR i = bits - 1 TO 0 STEP -1
        bit = (n SHR i) AND 1
        result = result & STR$(bit)
        IF i MOD 4 = 0 AND i > 0 THEN result = result & " "
    NEXT i
END SUB

SUB BasicBitOps()
    LOCAL a AS DWORD
    LOCAL b AS DWORD
    LOCAL result AS DWORD
    LOCAL s AS STRING
    a = &B10101010
    b = &B11001100
    PRINT "=== BASIC BIT OPERATIONS ==="
    CALL BinString(a, 8, s)
    PRINT "a     = " & s & "  (" & FORMAT$(a, "&H") & ")"
    CALL BinString(b, 8, s)
    PRINT "b     = " & s & "  (" & FORMAT$(b, "&H") & ")"
    result = a AND b
    CALL BinString(result, 8, s)
    PRINT "a AND b = " & s & "  (" & FORMAT$(result, "&H") & ")"
    result = a OR b
    CALL BinString(result, 8, s)
    PRINT "a OR b  = " & s & "  (" & FORMAT$(result, "&H") & ")"
    result = a XOR b
    CALL BinString(result, 8, s)
    PRINT "a XOR b = " & s & "  (" & FORMAT$(result, "&H") & ")"
    result = NOT a
    CALL BinString(result, 8, s)
    PRINT "NOT a   = " & s & "  (" & FORMAT$(result, "&H") & ")"
    PRINT
END SUB

SUB ByteWordDword()
    LOCAL b AS BYTE
    LOCAL w AS WORD
    LOCAL dw AS DWORD
    LOCAL s AS STRING
    b = &B11010101
    w = &B1010101010101010
    dw = 2882400001
    PRINT "=== BYTE / WORD / DWORD ==="
    CALL BinString(b, 8, s)
    PRINT "BYTE  b  = " & s & "  val=" & STR$(b)
    CALL BinString(w, 16, s)
    PRINT "WORD  w  = " & s & "  val=" & STR$(w)
    CALL BinString(dw, 32, s)
    PRINT "DWORD dw = " & s & "  val=" & STR$(dw)
    PRINT
    PRINT "Extracting bytes from DWORD:"
    CALL BinString(dw AND 255, 8, s)
    PRINT "Byte 0: " & s & " = " & STR$(dw AND 255)
    CALL BinString((dw SHR 8) AND 255, 8, s)
    PRINT "Byte 1: " & s & " = " & STR$((dw SHR 8) AND 255)
    CALL BinString((dw SHR 16) AND 255, 8, s)
    PRINT "Byte 2: " & s & " = " & STR$((dw SHR 16) AND 255)
    CALL BinString((dw SHR 24) AND 255, 8, s)
    PRINT "Byte 3: " & s & " = " & STR$((dw SHR 24) AND 255)
    PRINT
END SUB

SUB MaskDemo()
    LOCAL flags AS DWORD
    LOCAL bit0 AS DWORD
    LOCAL bit3 AS DWORD
    LOCAL bit7 AS DWORD
    LOCAL s AS STRING
    flags = 0
    bit0 = 1
    bit3 = 8
    bit7 = 128
    PRINT "=== BIT MASK DEMO ==="
    CALL BinString(flags, 8, s)
    PRINT "Initial flags: " & s
    flags = flags OR bit0
    CALL BinString(flags, 8, s)
    PRINT "Set bit 0:     " & s
    flags = flags OR bit3
    CALL BinString(flags, 8, s)
    PRINT "Set bit 3:     " & s
    flags = flags OR bit7
    CALL BinString(flags, 8, s)
    PRINT "Set bit 7:     " & s
    flags = flags XOR bit0
    CALL BinString(flags, 8, s)
    PRINT "Toggle bit 0:  " & s
    flags = flags AND (NOT bit3)
    CALL BinString(flags, 8, s)
    PRINT "Clear bit 3:   " & s
    IF (flags AND bit7) THEN PRINT "Bit 7 is SET"
    IF (flags AND bit3) = 0 THEN PRINT "Bit 3 is CLEAR"
    PRINT
END SUB

SUB ParityHammingWeight()
    LOCAL i AS LONG
    LOCAL val AS DWORD
    LOCAL count AS LONG
    LOCAL parity AS LONG
    LOCAL s1 AS STRING
    LOCAL s2 AS STRING
    LOCAL s3 AS STRING
    PRINT "=== PARITY & HAMMING WEIGHT ==="
    PRINT "Value     Binary           Weight  Parity"
    PRINT "--------------------------------------------------"
    FOR i = 0 TO 15
        val = i
        count = 0
        DO WHILE val > 0
            val = val AND (val - 1)
            count = count + 1
        LOOP
        parity = count MOD 2
        CALL BinString(i, 8, s1)
        PRINT FORMAT$(i, "###") & "       " & s1 & "     " & STR$(count) & "      " & STR$(parity)
    NEXT i
    PRINT
END SUB

SUB GrayCode()
    LOCAL i AS LONG
    LOCAL gray AS DWORD
    LOCAL s1 AS STRING
    LOCAL s2 AS STRING
    PRINT "=== GRAY CODE ==="
    PRINT "Dec  Binary   Gray     Gray->Dec"
    PRINT "--------------------------------------------------"
    FOR i = 0 TO 15
        gray = i XOR (i SHR 1)
        CALL BinString(i, 8, s1)
        CALL BinString(gray, 8, s2)
        PRINT FORMAT$(i, "###") & "  " & s1 & "  " & s2 & "  " & STR$(gray)
    NEXT i
    PRINT
END SUB

SUB BitReverse()
    LOCAL val AS DWORD
    LOCAL rev AS DWORD
    LOCAL i AS LONG
    LOCAL s1 AS STRING
    LOCAL s2 AS STRING
    val = 45964
    rev = 0
    FOR i = 0 TO 15
        rev = rev OR (((val SHR i) AND 1) SHL (15 - i))
    NEXT i
    CALL BinString(val, 16, s1)
    CALL BinString(rev, 16, s2)
    PRINT "=== BIT REVERSE (16-bit) ==="
    PRINT "Original: " & s1
    PRINT "Reversed: " & s2
    PRINT
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "=========================="
    PRINT " Bit Manipulation Demo"
    PRINT "=========================="
    PRINT
    CALL BasicBitOps()
    CALL ByteWordDword()
    CALL MaskDemo()
    CALL ParityHammingWeight()
    CALL GrayCode()
    CALL BitReverse()
    PRINT "Bit manipulation complete."
    FUNCTION = 0
END FUNCTION
