Displaying numbers in hexadecimal in FemtoBasic
Duane C. Johnson
Posts: 955
Is there a way to print to the serial port in hex?
Also, can special characters be sent to the serial port.
Something like CHR$ in normal basic.
Actually this function could be used to implement printing hex to the serial port.
Duane
Also, can special characters be sent to the serial port.
Something like CHR$ in normal basic.
Actually this function could be used to implement printing hex to the serial port.
Duane
Comments
There's no built-in hexadecimal formatting in FemtoBasic. You can write a routine in Basic that does it. I've done that. I've also made a private version of DongleBasic that used a prefix operator like the HEX in PBasic to allow printing in hexadecimal.
OK, I'm cheating a bit by using a character conversion table in main memory. However, this is probably a bit faster than doing it with arithmetic. The table will probably be useful for printing characters in any BASE from base2 to baseZ as is done in forth language.
BTW, it's very cool how you can use a GOTO statement to construct the equivalent of a CASE statement. I was initially disappointed there was no CASE nor IF in FemtoBasic but am now quite impressed.
I like how one can INPUT numbers as decimal, HEX, or binary. This is very useful when testing code. This is a concept described in an obscure article in Dr. Dobbs Journal many years ago. They allowed one to use any arithmetic in INPUT statements. I have used this in many of my Basic programs. Yours is built in and can be used anywhere an expression is used. Bravo!!!
These are the two tables I put into my StickBasic version of DongleBasic.
$0279-$029F
dat
base byte "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"
$02A0-$02BF
dat
basec long $03020100,$07060504,$11100908,$15141312
long $19181716,$23221120,$27262524,$31302928
DUMP $0279,71
NEW
1 REM Test Converting Decimal To Hex
2 REM Character Data Table Starting at $0279
3 REM Long Number stored at $02A0
100 REM Setup
110 A = $0279 : B = $02A0 : C = 8
200 REM Number of Places
210 INPUT "Number of Characters ? "; C
300 REM Get the Number
310 INPUT "Number Decimal, HEX, or Binary ? "; D
320 LONG = D : REM Put the Number in basec
400 REM Convert and Print
410 GOSUB 1000
910 GOTO 300
1000 REM Print a HEX character
1001 PRINT "$" ;
1002 C = C & $F : C = C // 9 : REM Keep in bounds
1003 GOTO 1003 + 1 + 8 - C : REM The CASE Statement
1004 DISPLAY BYTE [A + BYTE [B + 3] / 16];
1005 DISPLAY BYTE [A + BYTE [B + 3] // 16];
1006 DISPLAY BYTE [A + BYTE [B + 2] / 16];
1007 DISPLAY BYTE [A + BYTE [B + 2] // 16];
1008 DISPLAY BYTE [A + BYTE [B + 1] / 16];
1009 DISPLAY BYTE [A + BYTE [B + 1] // 16];
1010 DISPLAY BYTE [A + BYTE / 16];
1011 DISPLAY BYTE [A + BYTE // 16];
1012 PRINT ""
1910 RETURN
RUN
Here is a Hex Displaying routine with a variable character length.
I noticed that some commands are not in the Femto manual such as "IF".
Anyway, can you give us a description of how to use "USING" and the format?
PRINT {USING "<format>";} ...
WRITE {USING "<format>";} ...
Duane
NEW
1 REM Test Converting Decimal To Hex
2 REM Character Data Table Starting at $0279
3 REM Long Number stored at $02A0
100 REM Setup
110 A = $0279 : B = $02A0 : C = 8
200 REM Number of Places
210 INPUT "Number of Characters ? "; C
300 REM Get the Number
310 INPUT "Number Decimal, HEX, or Binary ? "; D
320 LONG = D : REM Put the Number in the table
400 REM Convert and Print
410 GOSUB 1000
420 PRINT ""
910 GOTO 200
1000 REM Print a HEX character
1001 PRINT "$" ;
1002 C = C & $F : C = C // 9 : REM Keep in bounds
1003 GOTO 1003 + 1 + 8 - C : REM The CASE Statement
1004 DISPLAY BYTE [A + BYTE [B + 3] / 16];
1005 DISPLAY BYTE [A + BYTE [B + 3] // 16];
1006 DISPLAY BYTE [A + BYTE [B + 2] / 16];
1007 DISPLAY BYTE [A + BYTE [B + 2] // 16];
1008 DISPLAY BYTE [A + BYTE [B + 1] / 16];
1009 DISPLAY BYTE [A + BYTE [B + 1] // 16];
1010 DISPLAY BYTE [A + BYTE / 16];
1011 DISPLAY BYTE [A + BYTE // 16];
1910 RETURN
RUN
Here are 2 more sample routines to print HEX or BINARY with any desired number of characters and possibly insert separator commas.
Unlike my earlier versions these are written in pure FemtoBasic.
BTW I have found that FemtoBasic has the IF THEN command which is not in the manual.
Also, ( ) parenthesis can be used to change precedence, not in the manual.
Does anyone know how to use PRINT USING "FORMAT" command?
This appears in the spin file but I haven't been able to figure out it works.
FemtoBasic accepts the command, but I get is an error when it runns.
REM Convert Any Number Type to HEX
REM 0 to 32 characters my be displayed
NEW
90 C = 8 : E = 0 : G = 4
100 REM
200 REM Number of Places
210 INPUT "Number of Characters ? " ; C
300 REM Get the Number
310 INPUT "Number Decimal, HEX, or Binary ? "; E
320 G = 4 : GOSUB 2000
330 PRINT ""
910 GOTO 100
2000 REM Print a BINARY Number
2001 REM Pass C = # of Printed Characters, Value Unaffected
2002 REM Pass E = the Number to be Printed, Value Unaffected
2003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
2004 REM F = Scratch Variable
2005 REM T = Scratch Variable
2010 PRINT "$" ; : REM Possibly done in the calling routine
2020 FOR T = C // 9 TO 1 STEP -1
2030 F = ((E REV (T * 4)) REV 4) + 48
2040 IF F > 57 THEN F = F + 7
2050 DISPLAY F ;
2060 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
2070 NEXT T
2190 RETURN
RUN
REM Convert Any Number Type to BINARY
REM 0 to 32 characters my be displayed
NEW
90 C = 32 : E = 0 : G = 8
100 REM
200 REM Number of Places
210 INPUT "Number of Characters ? " ; C
300 REM Get the Number
310 INPUT "Number Decimal, HEX, or Binary ? "; E
320 G = 8 : GOSUB 3000
330 PRINT ""
910 GOTO 200
3000 REM Print a BINARY Number
3001 REM Pass C = # of Printed Characters, Value Unaffected
3002 REM Pass E = the Number to be Printed, Value Unaffected
3003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
3004 REM F = Scratch Variable
3005 REM T = Scratch Variable
3010 PRINT "%" ; : REM Possibly done in the calling routine
3020 C = C // 33 : REM Keep in bounds
3030 REM F = $1 : F = F ROL (C - 1) : REM Using ROL
3040 F = $1 : F = F REV C : REM Using REV
3050 FOR T = C // 33 TO 1 STEP -1
3060 IF E & F = 0 THEN PRINT "0" ; : REM "0"
3070 IF E & F <> 0 THEN PRINT "1" ; : REM "1"
3080 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
3090 F = F SHR 1
3100 NEXT T
3910 RETURN
RUN
Regarding INPUT ... note that the expression parser is used to read the input values. That means that you can enter any valid expression when an INPUT statement executes including variables.