String space required. No exceptions.

Revisiting my Color BASIC String Theory series… Here is one to ponder…

CLEAR 0 can be used to reserve 0 bytes for string storage. With no string space, we obviously expect something like this to NOT work:


Indeed, that would give us “?OS ERROR” — Out of string space.

The exception to this rule are “constant strings” that are embedded inside the BASIC program itself. In a YouTube video I recently posted, I demonstrated how constant strings in a program do not use string space:

You can see twenty nine other short Color BASIC videos I posted to YouTube during the month of #SepTandy 2021.

But I digress…

Here are some other things that won’t work without string space, even if, at first glance, it seems like they would:

It seems you can’t SAVE, LOAD or even PRINT a “constant” string if there is no string space.

But why?

Consider this… The same thing happens with string functions such as LEFT$, RIGHT$, MID$ and even INSTR:

Looking at those, and recalling my String Theory article, we know LEFT$, RIGHT$ and MID$ are trying to create a new string. With no string space, there is no way to create it. That must be why they fail. This makes sense.

But INSTR does not create any strings. It merely returns the position where one string appears inside of another, or 0 if the string is not found. (Or 1 if you give it an empty string, which truly does seem like a bug but other flavors Microsoft BASIC behave the same way with their implementations of INSTR. But I digress…)

And SAVE, LOAD and PRINT are similar. They just print something, not create a string.

That does not make sense.

Let’s speculate a bit.

What’s all this, then?

Without consulting the Color BASIC Unravelled disassembly, my guess is that the ROM code for SAVE, LOAD, PRINT, etc. probably expects some register to be pointing to where the string exists in memory (a location pointer in the variable data). This might be code space, in the case of a constant string embedded in a BASIC line, or string space, in the case of a dynamic string.

But when you are entering a command directly in to BASIC, there is no program memory for that command (even though it seems like it could just point to the keyboard input buffer and then make the ROM call). BASIC needs to put that constant string data somewhere before jumping to the ROM call.

That’s weird, and quite possibly unnecessary, but would, at least, make sense.

I am going to add this to my “look this up in the disassembly to see what’s going on” list for future investigation.

In the meantime … I wonder what else won’t work without string space?

Until next time…

11 thoughts on “String space required. No exceptions.

  1. William Astle

    The reason constant strings need string space in immediate mode is actually quite straight forward and doesn’t need a deep dive into the ROM code, though you might find that exploration interesting nevertheless.

    At the time the string is being parsed, the parsing code has no knowledge of what is going to be done with the string. It doesn’t know if the string is going to be assigned to a variable in which case it can’t be left in the input buffer since that will be overwritten by subsequent commands. You might think some sort of flag could be set by things that won’t mutate the string at all or store it anywhere beyond the execution of a particular command, but that way leads to brain breakage as soon as you start working out how to deal with the fact that expressions can involve multiple strings at multiple levels in the expression. The code complexity likely wasn’t worth it when a simple default string allocation amount basically prevents the problem most of the time.

      1. jeekblog

        No, just in case the string (code where the string is embedded in) points into the input buffer. The expression evaluation routine takes the constant string and puts the descriptor of the string onto the string descriptor stack (may hold 3 elements). The descriptor containts the length of the string and the address to the string value. In RUN mode the string address points to the value pointing into the program code, in interactive mode the string is copied to the string space (as already stated).

        With my tests on ECB on a Dragon I could’nt proof the behavior seen in this article. INSTR() does no bail out with OS ERROR … On which version is this based on?

        1. Allen Huffman Post author

          It should be Extended Color BASIC 1.1. I just went to XRoar Online and selected “Tandy CoCo (NTSC)” and gave it a try. I do get the error from INSTR after a CLEAR 0.

  2. Luis Fernandez (luiscoco)

    The answer is very simple
    If it is saved as a program, the string is stored in the program space and does not use string space, only if the string is operated, increasing or decreasing it, it will be necessary to change the sctring site because the source cannot be modified.
    When operating in immediate mode, string space will always be used.
    This is an efficiency of data storage directly in the program

    1. Allen Huffman Post author

      If the parser sees the keyword SAVE, it would seem the next check would be for a variable string, or quoted text. I suppose if it did this, it would still run in to problems if I did SAVE”FILE”+EX$. I don’t think the parser can back up, so … everything in a string as we process?

      1. jeekblog

        (Nearly) all arguments are evaluated by a the expression evaluation routine. For strings a single term is put on the string descriptor stack (could take 3 elements) as preparation for further operations which will act on these. A string descriptor might contain a string pointing to the string space or in case of an constant string into the program text space. Just in interactive mode, if the constant string is just in the input buffer, the string is copied onto the string space or an operation produces a new string like STR$, MID$, LEFT$, RIGHT$ or the string concatenation operator “+”.

        I could not understand why this happens in your examples. My test on a Dragon ECB INSTR() has no problems with constant string or those coming from a variable (assigned with constant values) at all.

          1. jeekblog

            Just if in interactive mode. The reason has been discussed and stated in the comments above.
            If you are taking the program
            10 CLEAR0
            20 A=INSTR(“ABC”,”B”)
            30 PRINT A
            40 PRINT INSTR(“ABC”,”B”)

            it shows no error with output
            (as expected) ;)

  3. MiaM

    Who wrote the I/O code?

    At least for the 6502 version of Microsoft Basic it was up to the customer to write their own I/O, which also is why the I/O is so different between different versions.

    If the I/O were written by Tandy, they could had pulled the file name directly from screen memory but that would probably not had been worth the effort. For the older versions running on computers that don’t have built in video hardware some buffer would be needed anyways and I assume that it would be a regular text buffer to make it possible to use backspace from a connected terminal. That is kind of likely the reason that the input buffer survived on to the versions that runs on a computer with built in video hardware.

    For a command like PRINT, it could at least in theory overwrite parts of the command during execution if there weren’t an input buffer. Also by not having an input buffer there would be a need to keep track of where things scroll around the screen. If I/O can produce unlimited number of error messages (like abort/retry) it could also scroll off screen.

    Btw, re input buffer, at least in the 6502 version you can do some things that have weird results. IIRC you are allowed to use the DEF FN thingy and use it in subsequent immediate mode commands but the following commands must be short enough to not overwrite the definition…


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.