Versions of BASIC that allowed hex/oct/binary to be typed in as constants?

I’m considering adding the ability to type in hex constants in source, and may as well do oct and bin as well. So something like…

A = 0hFFFF

I know there were a couple of dialects of BASIC on micros that allowed this - BBC seems to tweak my memory?

If you know of one that did, do you mind replying with examples of how it was typed in? And perhaps any limits - could you 0hFFEEDD for instance?

2 Likes

I recently wrote a TinyBasic for the 6502[*] and I included hex constant entry using the Acorn “standard” of prefixing with an ampersand:

> A = &CAFE

Printing again uses the Acorn standard with a twiddle:

> PRINT ~A
CAFE

Whatever prefix you pick will never please everyone - 0h is a typical Intel style prefix, $ may be more MOS/Motorola style. 0x more for C programmers and so on… And a leading zero without a modifier? Well, that’s Octal, isn’t it?

Tiny Basic uses $ for string variables (as a prefix) so overloading it would be problematic and using 2 characters is just a waste of time (as in execution time - TinyBasic is slow enough already!)

My other BASIC (RTB - written in C, runs under Linux and standalone on a Pi) uses the “C” stadard of 0x for hex and 0b for binary.

-Gordon

[*] A New Tiny Basic for the 6502 | Gordons Projects

2 Likes

Indeed, BBC Basic uses & as a hex prefix. There’s some subtle special handling to allow it to be unsigned, even though integers are signed.
A%=&FFFFFFFE
for example is legal, and A% has the expected value, which Basic will normally treat as -2.

Note that ~ for hex output can also be used in other contexts, such as STR$~var

Acorn’s Atom Basic used # for hex constants, I believe.

I do think supporting hex in and out is a very good idea, both for practical and for teaching (or learning.) I think the exact syntax is not too important.

1 Like

I learned on Locomotive BASIC on the Amstrad CPC. It’s somewhere between BBC BASIC and Microsoft MBASIC in syntax.

  • Hexadecimal constants are specified like &1A2B and binary &X1101000101011 (= 6699 decimal).
  • Conversion to hex and binary strings were via HEX$ (unsigned integer expression, [field width]) and BIN$ (unsigned integer expression, [field width]). So HEX$(3053,4) would return the string “0BED”.
  • Arguments were limited to 16-bit integers.
  • There was no support for octal at all.
  • The usual method for converting from hex was to use something like VAL("&"+h$).
  • (TIL that Locomotive BASIC 1.1 had DEC$(numeric expression, format template) — a little like sprintf() except using IBM’s PRINT USING syntax. DEC$(PI*10^7,"££########,.##")would return the string “£31,415,926.50”. My Amstrad CPC464 only had BASIC 1.0, so I never knew about this.)
1 Like

This is confirmed by “Atomic Theory and Practice” by David Johnson Davies.

Atom BASIC also uses a somewhat interesting approach to strings, rather using a string operator “$” than a dedicated name space. It’s actually closer to C than to other BASICs.

10 DIM A(11)
20 $A = "HELLO WORLD"

Here, DIM A(11) reserves memory and $A points to the start address of this. (Meaning, it’s really an indirection.)
However, in PRINT statements, if the $ operator is followed by a value less than 256, this is interpreted as a literal character value.
E.g., here used for encoding cursor movements (also demonstrating # for hex values):

 1 REM Random Walk
10 DO
20 PRINT $ABS(RND)%4+8, $(#A0+ABS(RND)%#40), $8
30 UNTIL 0

This may be an interesting idea for any BASIC.
(However, this also means that the entire expression has to be evaluated first, in order to determine, whether this is a literal character value or a start address in memory, from which to print a string. It also means that with regular strings, in an expression like “$A”, “A” returns the base address of the respective array in memory. I guess, this also suggests a C-like termination, but I don’t know the details.)

I’ve read that Atom BASIC was inspired by a TinyBasic variant called NIBL - which was used on the SC/MP or INS8060 systems in the mid-late 70s… It has a similar approach although no DIM statement as such, but you did have a keyword that told you where the start of free RAM was:

A = TOP
$A = "Hello, world!"

And if you wanted another string - well, allocation is left as an exercise to the user, ie.

B = A + 20 : REM $A can be 19 characters long
$B = "Hi there"

There wasn’t a way to print characters in NIBL though - well, not easily. You can pluck a character out of a string, insert it into another string, add on a CR and print that string… (The CR was the string terminator in NIBL and wouldn’t be printed).

-Gordon

1 Like

Apparently, Atom BASIC allows for pointer arithmetic and accessing random slices in a string.
The following program suggests termination by ASCII 13 (value of the empty string “”, in the following example “;” is the statement separator):

For example:, if the following is executed:

10 DIM A(10)
20 $A="ATOMBASIC"
30 $A+5=""; $A=$A+1
40 END

then string A will have the value “TOMB”.

I’ve no idea, if this is any different from NIBL.
Just for completeness sake, the “?” operator allows us to read a spcific character inside a string, as in “A?3”. (“LEN()” and string comparison work as usual.)
On a more abstract level, this should allow us to pack arbitrary structures into a string and to access random slices of memory (both read and write). Which is actually quite powerful.

1 Like

Microsoft BASIC on the Kaypro and GWBASIC on my MS-DOS systems work.

A=&hFF
PRINT A
displays “255”

Going back in time…
Level II BASIC on the TRS-80 Model I and BASIC 4.0 on the Commodore PET does not allow this.

My Commodore Plus/4 does not allow it, however it has two functions:
HEX$ and DEC

HEX$(integer) returns a string representing the hex representation of “integer”.
ex: HEX$(255) returns “FF”
DEC(string) goes the other way. DEC(“FF”) returns 255

1 Like

I think that will work in NIBL - I don’t have a working system to test it on, however my own TinyBasic, GIBL was written after many hours pouring over the NIBL sources and is in-parts, a direct translation to 6502 code (and in many other parts a complete re-write) and yes, ? is byte-indirection. (I added ! for word indirection too) I’ll try it later tonight.

-Gordon

2 Likes

We can stop the plague together - please stop using the bare leading zero as the sign of octal.

1 Like

That is very clever syntax!

1 Like

I fear it is too late for that. … but do feel free to re-write every unix/unix-like utility, re-write the man pages, the system libraries and re-educate everyone who came from the PDP-8 era into the PDP-11 era …

and excuse me while I chmod 0644 filename.txt …

Or 08644 … or 0o644 … or … ?

-Gordon

chmod 644 - it assumes octal.

1 Like

I teach a second-year University programming course that uses C. Almost every semester I run into at least one student who gets into trouble because they have a leading zero on a decimal number. (Admittedly this is out of hundreds of students, but for every one I see there is almost assuredly a handful who figured it out without me.)

I do find this to be a regrettable choice. It was, however, an improvement on most of the DEC tools for the PDP-11, which simply assume that numbers are octal unless you follow them by a bare . (period).

4 Likes

Oh, didn’t we fix octal notation, as in 0O777? :wink:

(Forgoing octal notation completely, isn’t a great option, either. There were a few years, when the leading zero notation was illegal in JS in strict mode, but the 0o… notation wasn’t yet in the standard or, as it finally was, not implemented. Which was actually quite an issue, if you were dealing with vintage software and emulation.)

1 Like

A little bit of quote just to give context, but I tried this in my implementation:

Atom Basic has more “stuff” than mine, even though it still fits inside 4KB (IIRC) I have room to add in stuff like string length, etc. but … maybe not.

-Gordon

2 Likes

Old habits and all that.

-Gordon

A=TOP

In Atom BASIC, this is

 DIM A(-1)

Meaning, “A” is pointing at the current top of stack.

1 Like

A=TOP also works in Atom BASIC.

Dave

1 Like

TRS-80 Model 1 Disk BASIC adds hexadecimal constants with a &H prefix and octal ones with &O both representing signed 16-bit integers - so &HFFFF = -1. For octal constants, the O can be omitted so &77777 = 32767.

Oddly, these constants can’t be used in DATA statements.

1 Like