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

SUB BinString(BYVAL n AS DWORD, BYVAL bits AS LONG, BYREF result AS STRING)
    LOCAL i AS LONG
    LOCAL bit AS DWORD
    LOCAL divVal AS DWORD
    result = ""
    FOR i = bits - 1 TO 0 STEP -1
        divVal = 1
        IF i = 1 THEN divVal = 2
        IF i = 2 THEN divVal = 4
        IF i = 3 THEN divVal = 8
        IF i = 4 THEN divVal = 16
        IF i = 5 THEN divVal = 32
        IF i = 6 THEN divVal = 64
        IF i = 7 THEN divVal = 128
        IF i = 8 THEN divVal = 256
        IF i = 9 THEN divVal = 512
        IF i = 10 THEN divVal = 1024
        IF i = 11 THEN divVal = 2048
        IF i = 12 THEN divVal = 4096
        IF i = 13 THEN divVal = 8192
        IF i = 14 THEN divVal = 16384
        IF i = 15 THEN divVal = 32768
        IF i = 16 THEN divVal = 65536
        bit = (n \ divVal) AND 1
        IF bit THEN
            result = result & "1"
        ELSE
            result = result & "0"
        END IF
    NEXT i
END SUB

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

SUB ByteWordDword()
    LOCAL b AS BYTE
    LOCAL w AS WORD
    LOCAL dw AS DWORD
    LOCAL s AS STRING
    b = &HD5
    w = &HAAAA
    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 \ 256) AND 255, 8, s)
    PRINT "Byte 1: " & s & " = " & STR$((dw \ 256) AND 255)
    CALL BinString((dw \ 65536) AND 255, 8, s)
    PRINT "Byte 2: " & s & " = " & STR$((dw \ 65536) AND 255)
    CALL BinString((dw \ 16777216) AND 255, 8, s)
    PRINT "Byte 3: " & s & " = " & STR$((dw \ 16777216) 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 STR$(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 \ 2)
        CALL BinString(i, 8, s1)
        CALL BinString(gray, 8, s2)
        PRINT STR$(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
    LOCAL bitVal AS LONG
    LOCAL divV AS LONG
    val = 45964
    rev = 0
    FOR i = 0 TO 15
        divV = 1
        IF i = 1 THEN divV = 2
        IF i = 2 THEN divV = 4
        IF i = 3 THEN divV = 8
        IF i = 4 THEN divV = 16
        IF i = 5 THEN divV = 32
        IF i = 6 THEN divV = 64
        IF i = 7 THEN divV = 128
        IF i = 8 THEN divV = 256
        IF i = 9 THEN divV = 512
        IF i = 10 THEN divV = 1024
        IF i = 11 THEN divV = 2048
        IF i = 12 THEN divV = 4096
        IF i = 13 THEN divV = 8192
        IF i = 14 THEN divV = 16384
        IF i = 15 THEN divV = 32768
        bitVal = (val \ divV) AND 1
        IF bitVal THEN
            IF (15 - i) = 0 THEN rev = rev OR 1
            IF (15 - i) = 1 THEN rev = rev OR 2
            IF (15 - i) = 2 THEN rev = rev OR 4
            IF (15 - i) = 3 THEN rev = rev OR 8
            IF (15 - i) = 4 THEN rev = rev OR 16
            IF (15 - i) = 5 THEN rev = rev OR 32
            IF (15 - i) = 6 THEN rev = rev OR 64
            IF (15 - i) = 7 THEN rev = rev OR 128
            IF (15 - i) = 8 THEN rev = rev OR 256
            IF (15 - i) = 9 THEN rev = rev OR 512
            IF (15 - i) = 10 THEN rev = rev OR 1024
            IF (15 - i) = 11 THEN rev = rev OR 2048
            IF (15 - i) = 12 THEN rev = rev OR 4096
            IF (15 - i) = 13 THEN rev = rev OR 8192
            IF (15 - i) = 14 THEN rev = rev OR 16384
            IF (15 - i) = 15 THEN rev = rev OR 32768
        END IF
    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
