# Could you create a loop in direct-mode with BASIC?

Were there any home computers before 1985, on which you could create a loop (finite or infinite) in direct-mode?

And if it was possible on some machines, what may it have been useful for? For example, some sort of program loader from tape or disk.

For example, by typing

``````    PRINT "TEXT" : RUN
``````

or

``````    PRINT "TEXT" : GOTO 0
``````

so that it would loop the printing of "TEXT", just as an example.

EDIT - Since I am completely blocked ( due to some unknown problem ) from commenting and now also from posting any answers, I just want to add that it seems that you can use a pre-user-defined function in direct-mode, by first defining the function in a program using line numbers ( e.g. 10 DEF FNADD(X,Y)=X+y ) and then using it in direct-mode, so then trying to do a recursion trick like FNADD(FNADD(X,Y),Y), to try and cause an infinite loop using recursion, would be interesting, and I wonder why pre-user-defined functions can be accessed through direct-mode .

• There was no virtual line number 0 in any BASIC I ever played with in the 80's. `GOTO X` would always jump to that line in the current program (essentially a RUN without clearing variables or unDIMing arrays)--and this might be something you really wanted to do if you stopped your program (either with BREAK key or STOP statement) and then didn't want to CONT at the breakpoint. Many BASICs allowed a line number `0`. One use of FOR/NEXT in direct mode is outputting the contents of an array for debugging. Jul 20, 2020 at 13:06
• As far as what it would be useful for, I used to write a simple game on any TRS-80 model I/III I found in a shop or school etc as a kid. I could write it in one line but had to compromise on the infinite loop by making it count to a very large number. I don't know that this toy use case is any less valid than other use cases. Jul 21, 2020 at 3:14

In the Microsoft BASIC variants (Commodore, Atari, Apple, others) you can specify a FOR/NEXT loop with a STEP size of 0, which never increments the loop.

``````FOR X = 0 TO 1 STEP 0: PRINT "TEXT": NEXT
``````

is how you'd write it as a one-liner.

Now, as to why it would be useful to do such a thing...

• You can write a multiline statement on a single line separated by semicolons as above. Thus you can write a complete FOR loop (with STEP 0) on the command line that never terminates.
– Joe
Jul 20, 2020 at 13:30
• I believe BASIC uses colons, not semicolons, to separate sentences. Jul 20, 2020 at 13:32
• You need the `STEP 0` to make it repeat forever just like OP's examples do. The OP doesn't explicitly state 'endless loop' but their examples do. Jul 20, 2020 at 14:13
• @GuntramBlohmsupportsMonica: if I'm not wrong, you don't need `STEP 0`. You can do `FOR X = 0 TO 1: PRINT "TEXT": X = -1: NEXT` Jul 21, 2020 at 13:41
• @MartinArgerami yours is the only one which can work in TI Extended BASIC as `FOR X = 0 TO 1 :: PRINT "TEXT" :: X = -1 :: NEXT X` Jul 21, 2020 at 16:28

In any BASIC variant that allows multiple statements on one line, the multiple statements that are required to implement a FOR-NEXT or REPEAT-UNTIL loop can be provided in immediate mode. Many 8-bit micros of circa 1980 could do this:

`REPEAT : PRINT "*"; : UNTIL FALSE`

Or this:

`X=1 : FOR Y=0 TO 30 : PRINT "2^";Y;" = ";X : X=X+X : NEXT Y`

Try these examples in jsBeeb.

By contrast, any looping technique that relies on `GOTO` would not work, because there is no line number associated with the immediate-mode command. `RUN` also would not work, because its function is to start a stored program, which the immediate-mode command is not.

• WHILE … WEND would have worked in more early machines. It was certainly present in MBASIC-80. REPEAT…UNTIL was more limited to Acorn machines. Jul 22, 2020 at 20:00

Using BASIC+ on RSTS/E you can do this:

``````Ready

print i%; "Hello!" for i% = 1 to 9
1 Hello!
2 Hello!
3 Hello!
4 Hello!
5 Hello!
6 Hello!
7 Hello!
8 Hello!
9 Hello!

``````

This has a variety of uses. A trivial one would be to start a long running program then enter `print chr\$(7) for i%=1 to 20` into the type ahead buffer. The terminal would then beep 20 times when the long-running program completed.

It's also useful for testing code:

``````Ready

old stuff

listnh
1000    def fnstuff.happens()
1010        a.number = rnd
1020        print &
\  print "Working on stuff..."
1030        fnstuff.happens = a.number
1040    fnend
3276    end

print fnstuff.happens for i = 1 to 3

Working on stuff...
.204935

Working on stuff...
.229581

Working on stuff...
.533074

``````

Not strictly speaking a "home computer" unless, like me, you used to run a PDP-11 in your spare room. The above output is copied from a RSTS/E V8.0-06 system running under the SIMH PDP-11 emulator.

• Upvoted - while not a home computer, RSTS is very RC! I used to program professionally on Systime systems in their very similar BASIC 500! Jul 20, 2020 at 18:09
• Ah, BASIC-PLUS! I learned programming on a PDP-11 running RSTS/E. BASIC-PLUS was a great basic dialect. Though I was envious of BASIC-PLUS 2. Also learned MACRO-11 and COBOL on that system. Jul 21, 2020 at 14:06
• BASIC-PLUS-2 allowed this also. I think that they removed if for VAX BASIC though. Jul 22, 2020 at 0:26
• For VAX BASIC, you could do immediate mode in the debugger, or by running just the BASIC command (I think, it’s been a long time). What was removed was the control-suffix syntax (IIRC), ie. `<statement> For ...` and `<statement> If <condition>`. Jul 22, 2020 at 22:54
• Yes, you're right. I dug out the VAX BASIC Reference Manual, it describes immediate mode in great detail. I can't see any mention of implied IF etc. I'm quite surprised, both by their absence and by forgetting such a key change. Though getting rid of nasty stuff like `goto 2300 if x% > 27` was surely a good thing. I did like BASIC_PLUS's support of `UNLESS`, `FOR` and `WHILE` as modifiers. Jul 22, 2020 at 23:26

In Microsoft-based BASIC interpreters, the primary limitation with direct mode was the fact that the same buffer is used for inputting BASIC lines as for input within a program (e.g. the `INPUT` statement and the `GET` statement). If one were to perform e.g. `INPUT A\$` in direct mode, then once the input was complete, the buffer would be left holding the text that was input, rather than the immediate-mode line. I don't think there would have been any particular difficulty designing `GET` to store the new character someplace else (since it would only be a single byte), but I suspect that `INPUT` and `GET` share a routine that takes a string stored in the input buffer and copies it to garbage-collected string space; sharing that routine wouldn't avoid the need to have the `GET` function set the length to a hard-coded value of 1, but would avoid the need have it include its own code to set the source address. Even with that design, `GET` could probably have been made to support immediate mode if it did something like:

``````lda InputBufferStart
pha
jsr handleGet
pla
sta InputBufferStart
rts
``````

but that would made the interpreter 12 bytes bigger for relatively minor benefit.

The `FOR` loop construct that saves the start-of-loop address doesn't need to use the input buffer, and thus has no difficulty with direct mode. Constructs that would need to GOTO the direct-mode line wouldn't work, of course, but otherwise the only constructs that are problematic in direct mode are those that would use the input buffer.