' Hex dump utility: offset, hex bytes, ASCII side
#COMPILE EXE
#DIM ALL

FUNCTION ByteToHex(BYVAL b AS LONG) AS STRING
    LOCAL hexChars AS STRING
    hexChars = "0123456789ABCDEF"
    FUNCTION = MID$(hexChars, (b / 16) + 1, 1) + MID$(hexChars, (b MOD 16) + 1, 1)
END FUNCTION

SUB HexDumpLine(BYVAL offset AS LONG, data AS STRING, BYVAL startPos AS LONG, BYVAL count AS LONG)
    LOCAL i  AS LONG
    LOCAL b  AS LONG
    LOCAL printed  AS LONG
    LOCAL hexPart  AS STRING
    LOCAL ascPart  AS STRING
    hexPart = ""
    ascPart = ""
    printed = 0
    FOR i = startPos TO startPos + count - 1
        IF i <= LEN(data) THEN
            b = ASC(MID$(data, i, 1))
            hexPart = hexPart + ByteToHex(b) + " "
            IF b >= 32 AND b <= 126 THEN
                ascPart = ascPart + CHR$(b)
            ELSE
                ascPart = ascPart + "."
            END IF
            printed = printed + 1
        ELSE
            hexPart = hexPart + "   "
            ascPart = ascPart + " "
        END IF
    NEXT i
    PRINT RIGHT$("00000000" + HEX$(offset), 8) + "  " + hexPart + " " + ascPart
END SUB

SUB HexDump(BYVAL data AS STRING, BYVAL bytesPerLine AS LONG)
    LOCAL i  AS LONG
    LOCAL total  AS LONG
    PRINT "Offset    Hex" + SPACE$(bytesPerLine * 3) + "ASCII"
    PRINT "------    ---" + SPACE$(bytesPerLine * 3) + "-----"
    i = 1
    total = LEN(data)
    DO WHILE i <= total
        CALL HexDumpLine(i - 1, data, i, bytesPerLine)
        i = i + bytesPerLine
    LOOP
END SUB

SUB HexDumpString(BYVAL s AS STRING, BYVAL label AS STRING)
    PRINT label + " (" + FORMAT$(LEN(s)) + " bytes):"
    CALL HexDump(s, 16)
    PRINT
END SUB

FUNCTION PBMAIN() AS LONG
    LOCAL testStr AS STRING
    PRINT "=== Hex Dump Utility ==="
    PRINT
    CALL HexDumpString("Hello World! This is PBXB64 compiler.", "Text")
    testStr = CHR$(0) + CHR$(1) + CHR$(2) + CHR$(255) + CHR$(128) + CHR$(64)
    testStr = testStr + "Text" + CHR$(13) + CHR$(10) + "More text"
    CALL HexDumpString(testStr, "Binary mix")
    CALL HexDumpString("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "Alphabet (8 bytes/line)")
    PRINT
    PRINT "Hex dump tests complete."
    FUNCTION = 0
END FUNCTION
