This is just a (hopefully) short article following up on some tangents I went on while learning about Color BASIC string memory and VARTPR and other related (and nonrelated) items.
The story so far…
Color BASIC has reserved string memory that is located at the very top of the 32K that is accessible by BASIC. There are three 16-bit pointers maintained by BASIC that contain the starting address for this memory, the address where the next string will be inserted (sorta), and the end of this memory.
The Color BASIC Unraveled book called them FRETOP, STRTAB and MEMSIZ.
You can get the address in BASIC by using PEEK(x)*256+PEEK(y) with these memory locations:
- FRETOP – 33 and 34
- STRTAB – 35 and 36
- MEMSIZ – 39 and 40
When digging in to this, I noticed the the MEMSIZ location returned on a 32K CoCo was 32766, and on a 16K it was 16382, and on a 4K CoCo it was 4094. The actual last byte of RAM was one byte higher (32767, 16383, and 4095), making me wonder if this was a mistake.
Indeed, when I checked on a CoCo 3, which had newer patches to BASIC done by Microware, the 32K value “correctly” reported 32767 as would have expected.
Will the real MEMSIZ please stand up?
… That missing byte is needed so VAL can work on a string stored at the very top of string space. It needs to temporarily put a NUL byte after the string so the number parser knows when to stop. After executing, VAL restores the byte to its original value. Things would fail if the byte after the string data was ROM though. On the Coco3, that byte is in RAM so it didn’t need an extra reserved byte. I suspect, however, that Microware didn’t know that, or thought it was a bug in the original, or just didn’t notice when they replaced the now useless memory scan with a simple LDX. So, it’s not a bug in the original ROM and, accidental or not, … the behavior on the Coco3 [is] also correct.– William Astle, 7/14/2022
This led me back to the ROM disassembly, where I did indeed locate where the VAL command will load a byte, store 0 there, then restore the original value later.
Prove it or lose it.
Since Man cannot code on faith alone, Art “ADOS” Flexser provided a simple way to prove this to be true:
You can demonstrate the need for the extra byte on a 32/64K CoCo 1/2 by the following:Art Flexser, 7/17/2022
Change the top of string space to $7FFF rather than the usual $7FFE by POKE 40, 255:CLEAR, upping the LSB of MEMSIZ by one.
Then try PRINT VAL(“&H5”) and you get the rather surprising answer of 94! Why 94? Because that’s decimal for hex 5E, and the “E” has arisen from the first byte of Extended Basic at $8000.
On a CoCo 3, the top of string space is already at $7FFF, so you just need to put it into ROM/RAM mode with POKE&HFFDE,0 before entering PRINT VAL(“&H5”) to get the answer of 94.
And there you have it — the reason why MEMSIZE is not actually pointing to the end of usable BASIC memory on a CoCo 1 or 2, and why it still works on a CoCo 3 after being changed to actually point to the end of usable BASIC memory.
The more you know …
Thanks, William and Art. Your knowledge is greatly apprecaited.
Until next time…