Repository navigation
UltimateBasic 64 1.6.6
ltimate Basic v1.6.6 – Release Notes
2026-10-18 – Unreleased (after 1.6.6)
New
- option strings n [, m]: a computed string variable holds up to n
characters (1-255, default 80), a string-array element up to m
(default 31). Each variable keeps its own buffer. - Compile-time warnings: a byte variable that gets a constant it
cannot hold (b = 300, b = a + 1000) is reported with its line.
Warnings never stop the build. - With --basic-print, STR$ gives the C64 BASIC text for every number
(" 7", "-42", " 3.5"); without it a byte keeps "007". - Struct types: field defaults (var hp: word = 100 - the array's
contents at program start), nested struct fields (e[i].pos.x),
fixed-length string fields (var name: string * 20), struct
parameters (sub heal(p AS TEntity) ... heal(e[i])), and the QBasic
form TYPE ... name AS type ... END TYPE. A struct element can be at
most 256 bytes (a compile error says so).
Changed - In a SUB / FUNCTION closed by END SUB / END FUNCTION, END alone on
its line ends the program, as in QBasic (also inside IF ... END IF).
Blocks in such routines are closed QBasic-style.
Fixed - / with a WORD, INTEGER or negative divisor used only the low byte
of the divisor: -700 / -7 gave 0, 50000 / (v + 0) was wrong. It is
a 16-bit division now, truncated toward zero. - END and BYE inside a sub or function returned to the caller
instead of ending the program. - A variable index into a struct array was multiplied in 8 bits, so
elements beyond byte offset 255 were read and written wrongly. - Word struct fields were cut to 8 bits inside expressions, and
word + x / word - x dropped the high byte of a 16-bit x (a word
array element, a word function).
2026-10-17 – Release 1.6.6: PRINT USING, string order, floats
New
- PRINT USING "format"; values (QBasic subset): numeric fields with
digits, . point, , thousands separators, a leading + (always a
sign) and a trailing - (sign after the number); a number that
does not fit is printed with a % in front. String fields & (whole
string), ! (first character) and \ \ (as wide as the field);
_ prints the next character as it is. Values cycle through the
fields; a trailing ; or , keeps the cursor on the line. The format
must be a string literal. - Strings can be ordered: < > <= >= compare in PETSCII order, a
shorter string first when it starts the other ("AB" < "ABC"). - RND as a floating-point number: in a statement that computes in
floating point, rnd / rnd() is 0 <= x < 1 (d = rnd, x = rnd() * 6).
rnd(n) and integer statements keep the 0-255 / 0..n-1 generator. - MOD with a SINGLE / DOUBLE operand works in floating point, like
VB / C fmod: 7.5 mod 2 = 1.5, -7.5 mod 2 = -1.5; x mod 0 = x. - Floating point in IRQ / NMI handlers: a handler sub (irq, nmi,
cia_timer) that uses SINGLE / DOUBLE saves and restores the
runtime state, so it no longer disturbs the main program. Handlers
without floating point cost nothing extra. - --basic-print (or a line "option basic print" in the program):
C64 BASIC PRINT spacing - numbers print with a leading space (or
their minus sign) and a trailing space (print 5 gives " 5 "), a ,
between items moves to the next 10-column zone, a trailing , keeps
the line. Without it the output is unchanged.
Changed - Programs carry only the floating-point routines they use: a small
program with + * and PRINT went from 4603 to 2293 bytes,
examples/float_demo.ub from 6319 to 5660. - MOD with a WORD or INTEGER operand is a real 16-bit remainder with
the sign of the dividend, like QBasic: -7 mod 3 = -1, 7 mod -3 = 1,
(w + 5) mod 7 is no longer cut to 8 bits. - SHR of an INTEGER is an arithmetic shift: -8 shr 1 = -4. WORD and
byte SHR stay logical.
Fixed - A literal from 32768 to 65535 in a floating-point statement was
read as a negative 16-bit pattern: d = 40000 gave -25536. It keeps
its value now; integer statements are unchanged.