' CRC-8 — computes 8-bit cyclic redundancy check
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL data(1000) AS LONG
    LOCAL dataLen AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL crc AS LONG
    LOCAL byteVal AS LONG
    LOCAL bitVal AS LONG
    LOCAL poly AS LONG
    LOCAL refIn AS LONG
    LOCAL refOut AS LONG
    LOCAL xorOut AS LONG
    LOCAL checkVal AS LONG
    LOCAL inputStr AS STRING
    LOCAL tempStr AS STRING
    LOCAL ch AS STRING
    LOCAL hexStr AS STRING
    LOCAL nibble AS LONG
    LOCAL expected AS LONG
    LOCAL testPassed AS LONG
    LOCAL testFailed AS LONG
    LOCAL lineStr AS STRING
    poly = 7
    refIn = 1
    refOut = 1
    xorOut = 0
    dataLen = 0
    PRINT "============================================"
    PRINT "            CRC-8 CALCULATOR"
    PRINT "============================================"
    PRINT ""
    PRINT "Polynomial: 0x07 (CRC-8 standard)"
    PRINT ""
    inputStr = "Hello World"
    dataLen = LEN(inputStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(inputStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    crc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        IF refIn = 1 THEN
            tempStr = ""
            FOR j = 0 TO 7
                IF (byteVal AND (2 ^ j)) <> 0 THEN
                    tempStr = "1" + tempStr
                ELSE
                    tempStr = "0" + tempStr
                END IF
            NEXT j
            byteVal = 0
            FOR j = 0 TO 7
                IF MID$(tempStr, j + 1, 1) = "1" THEN
                    byteVal = byteVal + (2 ^ (7 - j))
                END IF
            NEXT j
        END IF
        crc = crc XOR byteVal
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR poly
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
    NEXT i
    IF refOut = 1 THEN
        tempStr = ""
        FOR j = 0 TO 7
            IF (crc AND (2 ^ j)) <> 0 THEN
                tempStr = "1" + tempStr
            ELSE
                tempStr = "0" + tempStr
            END IF
        NEXT j
        crc = 0
        FOR j = 0 TO 7
            IF MID$(tempStr, j + 1, 1) = "1" THEN
                crc = crc + (2 ^ (7 - j))
            END IF
        NEXT j
    END IF
    crc = crc XOR xorOut
    crc = crc AND 255
    hexStr = HEX$(crc)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    expected = 171
    testPassed = 0
    testFailed = 0
    IF crc = expected THEN
        testPassed = testPassed + 1
        lineStr = "PASS"
    ELSE
        testFailed = testFailed + 1
        lineStr = "FAIL"
    END IF
    PRINT "CRC-8 of '" + inputStr + "' = 0x" + hexStr + " (" + lineStr + ")"
    PRINT ""
    inputStr = "123456789"
    dataLen = LEN(inputStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(inputStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    crc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        IF refIn = 1 THEN
            tempStr = ""
            FOR j = 0 TO 7
                IF (byteVal AND (2 ^ j)) <> 0 THEN
                    tempStr = "1" + tempStr
                ELSE
                    tempStr = "0" + tempStr
                END IF
            NEXT j
            byteVal = 0
            FOR j = 0 TO 7
                IF MID$(tempStr, j + 1, 1) = "1" THEN
                    byteVal = byteVal + (2 ^ (7 - j))
                END IF
            NEXT j
        END IF
        crc = crc XOR byteVal
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR poly
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
    NEXT i
    IF refOut = 1 THEN
        tempStr = ""
        FOR j = 0 TO 7
            IF (crc AND (2 ^ j)) <> 0 THEN
                tempStr = "1" + tempStr
            ELSE
                tempStr = "0" + tempStr
            END IF
        NEXT j
        crc = 0
        FOR j = 0 TO 7
            IF MID$(tempStr, j + 1, 1) = "1" THEN
                crc = crc + (2 ^ (7 - j))
            END IF
        NEXT j
    END IF
    crc = crc XOR xorOut
    crc = crc AND 255
    hexStr = HEX$(crc)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    expected = 222
    IF crc = expected THEN
        testPassed = testPassed + 1
        lineStr = "PASS"
    ELSE
        testFailed = testFailed + 1
        lineStr = "FAIL"
    END IF
    PRINT "CRC-8 of '" + inputStr + "' = 0x" + hexStr + " (" + lineStr + ")"
    PRINT ""
    PRINT "Testing various CRC-8 variants"
    PRINT ""
    poly = 7
    refIn = 1
    refOut = 1
    xorOut = 0
    PRINT "CRC-8 (standard): poly=0x07, refIn=1, refOut=1, xorOut=0"
    inputStr = "PBXBCD compiler test"
    dataLen = LEN(inputStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(inputStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    crc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        IF refIn = 1 THEN
            tempStr = ""
            FOR j = 0 TO 7
                IF (byteVal AND (2 ^ j)) <> 0 THEN
                    tempStr = "1" + tempStr
                ELSE
                    tempStr = "0" + tempStr
                END IF
            NEXT j
            byteVal = 0
            FOR j = 0 TO 7
                IF MID$(tempStr, j + 1, 1) = "1" THEN
                    byteVal = byteVal + (2 ^ (7 - j))
                END IF
            NEXT j
        END IF
        crc = crc XOR byteVal
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR poly
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
    NEXT i
    IF refOut = 1 THEN
        tempStr = ""
        FOR j = 0 TO 7
            IF (crc AND (2 ^ j)) <> 0 THEN
                tempStr = "1" + tempStr
            ELSE
                tempStr = "0" + tempStr
            END IF
        NEXT j
        crc = 0
        FOR j = 0 TO 7
            IF MID$(tempStr, j + 1, 1) = "1" THEN
                crc = crc + (2 ^ (7 - j))
            END IF
        NEXT j
    END IF
    crc = crc XOR xorOut
    crc = crc AND 255
    hexStr = HEX$(crc)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "CRC-8: 0x" + hexStr
    PRINT ""
    poly = 9
    refIn = 0
    refOut = 0
    xorOut = 0
    PRINT "CRC-8/ITU: poly=0x09, refIn=0, refOut=0, xorOut=0"
    crc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        crc = crc XOR byteVal
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR poly
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
    NEXT i
    crc = crc XOR xorOut
    crc = crc AND 255
    hexStr = HEX$(crc)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "CRC-8/ITU: 0x" + hexStr
    PRINT ""
    poly = 13
    refIn = 0
    refOut = 0
    xorOut = 0
    PRINT "CRC-8/ROHC: poly=0x0D, refIn=0, refOut=0, xorOut=0"
    crc = 255
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        crc = crc XOR byteVal
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR poly
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
    NEXT i
    crc = crc XOR xorOut
    crc = crc AND 255
    hexStr = HEX$(crc)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "CRC-8/ROHC: 0x" + hexStr
    PRINT ""
    PRINT "============================================"
    PRINT "       CRC-8 LOOKUP TABLE GENERATION"
    PRINT "============================================"
    PRINT ""
    PRINT "CRC-8 lookup table for poly 0x07"
    PRINT ""
    FOR i = 0 TO 255
        crc = i
        FOR j = 0 TO 7
            IF (crc AND 128) <> 0 THEN
                crc = (crc * 2) XOR 7
            ELSE
                crc = crc * 2
            END IF
            crc = crc AND 255
        NEXT j
        hexStr = HEX$(crc)
        IF LEN(hexStr) = 1 THEN
            hexStr = "0" + hexStr
        END IF
        PRINT "0x" + hexStr + " "
        IF (i + 1) MOD 16 = 0 THEN
            PRINT ""
        END IF
    NEXT i
    PRINT ""
    PRINT "Verification: " + STR$(testPassed) + " passed, " + STR$(testFailed) + " failed"
    FUNCTION = 0
END FUNCTION
