13

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 .

2
  • 3
    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.
    – LawrenceC
    Jul 20, 2020 at 13:06
  • 1
    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

4 Answers 4

25

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...

12
  • 2
    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
  • 10
    I believe BASIC uses colons, not semicolons, to separate sentences. Jul 20, 2020 at 13:32
  • 5
    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
  • 2
    @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
  • 1
    @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
21

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.

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

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!

Ready

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

Ready

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

Ready

print fnstuff.happens for i = 1 to 3

Working on stuff...
 .204935

Working on stuff...
 .229581

Working on stuff...
 .533074

Ready

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.

6
  • 1
    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
  • 2
    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.
    – mannaggia
    Jul 21, 2020 at 14:06
  • 2
    BASIC-PLUS-2 allowed this also. I think that they removed if for VAX BASIC though. Jul 22, 2020 at 0:26
  • 1
    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
  • 1
    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
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .