' 8-bit Checksum — computes various 8-bit checksum algorithms
#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 sum AS LONG
    LOCAL xorSum AS LONG
    LOCAL twoComp AS LONG
    LOCAL fletcher AS LONG
    LOCAL lrc AS LONG
    LOCAL addVal AS LONG
    LOCAL byteVal AS LONG
    LOCAL nibbleHigh AS LONG
    LOCAL nibbleLow AS LONG
    LOCAL testStr AS STRING
    LOCAL ch AS STRING
    LOCAL hexStr AS STRING
    LOCAL passes AS LONG
    LOCAL fails AS LONG
    LOCAL lineStr AS STRING
    passes = 0
    fails = 0
    PRINT "============================================"
    PRINT "         8-BIT CHECKSUM CALCULATOR"
    PRINT "============================================"
    PRINT ""
    PRINT "Checksum algorithms demonstrate"
    PRINT ""
    testStr = "The quick brown fox jumps over the lazy dog"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    xorSum = 0
    twoComp = 0
    fletcher = 0
    lrc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        sum = sum + byteVal
        xorSum = xorSum XOR byteVal
        lrc = lrc + byteVal
        fletcher = fletcher + byteVal
        IF fletcher > 255 THEN
            fletcher = fletcher - 255
        END IF
    NEXT i
    sum = sum AND 255
    twoComp = (256 - sum) AND 255
    lrc = (256 - (lrc AND 255)) AND 255
    PRINT "Simple sum (mod 256): " + STR$(sum)
    PRINT "XOR checksum: " + STR$(xorSum)
    PRINT "Two's complement: " + STR$(twoComp)
    PRINT "Fletcher-8: " + STR$(fletcher)
    PRINT "LRC: " + STR$(lrc)
    PRINT ""
    PRINT "Verification (sum + twosComp should be 0)"
    IF (sum + twoComp) AND 255 = 0 THEN
        passes = passes + 1
        lineStr = "PASS"
    ELSE
        fails = fails + 1
        lineStr = "FAIL"
    END IF
    PRINT "Sum + 2's complement = " + STR$((sum + twoComp) AND 255) + " (" + lineStr + ")"
    PRINT ""
    PRINT "============================================"
    PRINT "       CHECKSUM OF STRING VARIANTS"
    PRINT "============================================"
    PRINT ""
    testStr = "123456789"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    xorSum = 0
    lrc = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        sum = sum + byteVal
        xorSum = xorSum XOR byteVal
        lrc = lrc + byteVal
    NEXT i
    sum = sum AND 255
    lrc = (256 - (lrc AND 255)) AND 255
    PRINT "String: " + testStr
    PRINT "  Sum8: " + STR$(sum)
    PRINT "  XOR8: " + STR$(xorSum)
    PRINT "  LRC:  " + STR$(lrc)
    PRINT ""
    testStr = "abcdefghijklmnopqrstuvwxyz"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    xorSum = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        sum = sum + byteVal
        xorSum = xorSum XOR byteVal
    NEXT i
    sum = sum AND 255
    twoComp = (256 - sum) AND 255
    PRINT "String: " + testStr
    PRINT "  Sum8:   " + STR$(sum)
    PRINT "  XOR8:   " + STR$(xorSum)
    PRINT "  Sum8+1: " + STR$((sum + 1) AND 255)
    PRINT "  NegSum: " + STR$(twoComp)
    PRINT ""
    PRINT "============================================"
    PRINT "         NIBBLE-WISE CHECKSUM"
    PRINT "============================================"
    PRINT ""
    testStr = "Hello PBXB64 compiler"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    xorSum = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        nibbleHigh = byteVal / 16
        nibbleLow = byteVal AND 15
        sum = sum + nibbleHigh + nibbleLow
        xorSum = xorSum XOR nibbleHigh XOR nibbleLow
    NEXT i
    sum = sum AND 255
    PRINT "Nibble sum: " + STR$(sum)
    PRINT "Nibble XOR: " + STR$(xorSum)
    PRINT ""
    PRINT "============================================"
    PRINT "      WEIGHTED CHECKSUM (LRC variants)"
    PRINT "============================================"
    PRINT ""
    testStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        addVal = byteVal * (i + 1)
        sum = sum + addVal
    NEXT i
    sum = sum AND 255
    PRINT "Position-weighted sum: " + STR$(sum)
    sum = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        IF (i MOD 2) = 0 THEN
            sum = sum + byteVal
        ELSE
            sum = sum + (256 - byteVal)
        END IF
    NEXT i
    sum = sum AND 255
    PRINT "Alternating sum: " + STR$(sum)
    sum = 0
    FOR i = 0 TO dataLen - 1
        byteVal = data(i)
        sum = sum XOR (byteVal + i)
    NEXT i
    sum = sum AND 255
    PRINT "Position-XOR: " + STR$(sum)
    PRINT ""
    PRINT "============================================"
    PRINT "      BCC (Block Check Character)"
    PRINT "============================================"
    PRINT ""
    PRINT "BCC for various strings"
    PRINT ""
    testStr = "Hello"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    xorSum = 0
    FOR i = 0 TO dataLen - 1
        xorSum = xorSum XOR data(i)
    NEXT i
    hexStr = HEX$(xorSum)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "BCC of '" + testStr + "' = 0x" + hexStr
    testStr = "World"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    xorSum = 0
    FOR i = 0 TO dataLen - 1
        xorSum = xorSum XOR data(i)
    NEXT i
    hexStr = HEX$(xorSum)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "BCC of '" + testStr + "' = 0x" + hexStr
    testStr = "TestData"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    xorSum = 0
    FOR i = 0 TO dataLen - 1
        xorSum = xorSum XOR data(i)
    NEXT i
    hexStr = HEX$(xorSum)
    IF LEN(hexStr) = 1 THEN
        hexStr = "0" + hexStr
    END IF
    PRINT "BCC of '" + testStr + "' = 0x" + hexStr
    PRINT ""
    PRINT "============================================"
    PRINT "      COMPLEMENT CHECKSUM"
    PRINT "============================================"
    PRINT ""
    testStr = "The quick brown fox"
    dataLen = LEN(testStr)
    FOR i = 0 TO dataLen - 1
        ch = MID$(testStr, i + 1, 1)
        data(i) = ASC(ch)
    NEXT i
    sum = 0
    FOR i = 0 TO dataLen - 1
        sum = sum + data(i)
        IF sum > 127 THEN
            sum = sum - 127
        END IF
    NEXT i
    sum = sum AND 127
    PRINT "Complement sum: " + STR$(sum)
    PRINT ""
    PRINT "Summary: " + STR$(passes) + " passed, " + STR$(fails) + " failed"
    FUNCTION = 0
END FUNCTION
