Skip to content

PicoMite V6.03.02b0

Latest

Choose a tag to compare

@UKTailwind UKTailwind released this 25 Aug 17:28

Beta for testing. This is 6.03.02b0, put out so the new array behaviour gets some
real use before 6.03.02 proper. Please report anything odd, especially in existing
programs that have nothing to do with the new feature.

New: single element array dimensions

An array dimension can now hold exactly one element. DIM a(0) under OPTION BASE 0,
and DIM a(1) under OPTION BASE 1, used to raise Dimensions.

That restriction meant DIM a(n) failed for exactly one value of n — the value an
edge case tends to produce — and it made a class of ordinary linear algebra
inexpressible, because a row vector, a column vector and a 1x1 result each need a
dimension of exactly one element:

Option base 0
Dim rowv(2,0)          ' 1 x 3   - was illegal
Dim colv(0,2)          ' 3 x 1   - was illegal
Dim dot(0,0)           ' 1 x 1   - was illegal
Math M_MULT rowv(), colv(), dot()    ' dot product

It works everywhere an array does: all types, any dimension of a multi-dimensional
array, LOCAL and STATIC, arrays passed to a SUB or FUNCTION as arr(), REDIM
and REDIM PRESERVE, structure member arrays, VAR SAVE/VAR RESTORE, and the MATH
functions including M_MULT, SLICE and INSERT.

Testfiles/single_element_matrix_demo.bas is a self-verifying demo of the matrix cases.

One behaviour change to be aware of

BOUND() now raises an error when asked for a dimension the array does not have, and
on a variable that is not an array. It previously returned 0.

This had to change: with a single element dimension a legitimate upper bound is 0
under OPTION BASE 0, so a returned 0 could no longer be told apart from "no such
dimension".

If you have code that probes rank like this, it will now error:

If Bound(a(), 2) = 0 Then ...   ' "is it 1-D?" - no longer works

Fixes

  • GUI TEXTBOX pop-up keyboard could not produce lower case. Its layout selector
    holds two bits - alt (&12) and shift - but was stored in a bool, so the shift
    key's value of 2 truncated to 1 and selected the &12 symbol page instead of
    shifting case. Neither lower case nor the alt-shift symbols
    (_ / < > : ; ^ ' - and [ ] { } | \) could be typed. Present since V6.03.01
    and well before it.
  • WEB TCP CLIENT REQUEST/READ/STREAM sized the receive buffer from the whole
    destination array, but the payload starts at element 1 (element 0 holds the length).
    The lwIP callback could write 8 bytes past the end of the array; in STREAM that
    value is also the ring buffer modulus, so the last 8 bytes of the ring were always
    out of bounds.
  • MATH CHI indexed its critical value table past the end for tables larger than
    about 8x8 (a 9x9 table needs 64 degrees of freedom; the table holds 50). It now
    reports the problem instead. Its degrees of freedom were also wrong under
    OPTION BASE 1.
  • MATH M_INVERSE leaked a row of both working matrices on every call.
  • JSON$ could read 8 bytes past the end of its source array under OPTION BASE 1.
  • WEB SCAN and the WEB TCP CLIENT receive commands now reject an array too small
    to hold any payload, rather than writing outside it.
  • UPDATE FIRMWARE is now available in every build. The USB host builds (PICOUSB,
    VGAUSB, HDMIUSB, HDMIWEB and so on) previously had no way to reach the bootloader
    from BASIC and needed the BOOTSEL button.
  • PicoCFunctions.h declared the wrong variable-table layout for RP2040, so a CSUB
    built from it against an RP2040 build read every variable's value from the wrong
    offset.
  • Assorted argument-checking corrections in the MATH array helpers.

What is worth testing

Existing programs, mainly. The array work touched the code that every array access goes
through, so the useful signal is whether anything that used to work now misbehaves —
particularly array-heavy code, the MATH functions, structures, and VAR SAVE/
VAR RESTORE.

The refactor was staged so that the first two thirds provably changed nothing: nine
variants were built before and after and the firmware images compared byte for byte.
Only the final step changes behaviour. If you do hit a regression, setting
DIM_DECODE_ENABLED to 0 in core/MMBasic.h restores the previous behaviour exactly,
which makes it easy to confirm whether the array change is responsible.

Notes

  • Full technical detail of the array change is in docs/dims_phase_a_audit.md.