9

Having been raised on an 8-bit Commodore, I was never afraid of PEEKs and POKEs.

I remember trying to accomplish something on a computer, in BASIC, using PEEKs and POKEs, and discovering that this particular BASIC didn't allow use of a PEEK and a POKE on the same line of code. You could use a PEEK() or a POKE, but not both. So, for a read-and-modify operation, an intermediate variable was needed.

My recollection is that this was on a friend's TRS-80 Color Computer. However, I've tried this online on CoCo emulators and there is no such constraint, I can do POKE 5120, PEEK(5120)+1 without errors.

What other platform could it have been? Or did I dream all this? As a nerdy teenager with a few friends, I had access to many "home" computers around 1984-87, from a Radio Shack PC-2 pocket thingy to an IBM PC XT. I live in Canada, so it wasn't something exotic like a BBC or Oric.

2
  • I believe I've seen one or two small, simple implementations of BASIC that only allow one command per line, but I can't remember which ones and I doubt this is what you encountered.
    – Tim Locke
    Commented Sep 17, 2022 at 13:45
  • 2
    @TimLocke Which wouldn'T matter here, as PEEK isn't a command, but a function, so even Tiny-BASIC's that add PEEK/POKE allow to use PEEK existing on the same line as POKE, being used as parameter.
    – Raffzahn
    Commented Sep 17, 2022 at 14:03

3 Answers 3

8

The first version of Commodore Basic (the so called "old ROMs" or "original ROMs" or similar) did have a limitation that PEEK and POKE used the same temporary storage for the memory address. As a result it would POKE into the wrong location:

*** COMMODORE BASIC ***

 7167 BYTES FREE

READY.
POKE 0,3

READY.
POKE 1,PEEK(0)+1

READY.
? PEEK(0);PEEK(1)
 4  48

READY.

This problem would most likely also be present in other early Microsoft BASIC versions.

It is fixed in, at least, later versions from Commodore:

### COMMODORE BASIC ###

 31743 BYTES FREE

READY.
POKE 0,3

READY.
POKE 1,PEEK(0)+1

READY.
? PEEK(0);PEEK(1)
 3  4

READY.
1
  • I'm pretty sure this is what I remembered. Although I never used a 1977 PET, I may have read a programming book or article for Commodore machines that warned about this quirk and advised not to combine PEEK and POKE in the same statement to avoid surprises.
    – Nimloth
    Commented Nov 8, 2022 at 5:09
7

On the TI-99/4A in TI-BASIC with mini-memory module you couldn't put CALL LOAD (which includes the functionality of POKE even if it does more than that) and CALL PEEK on the same line as TI-BASIC didn't allow for multiple statements on one LINE. CALL PEEK was not a function as PEEK is on all other basics. Its syntax was CALL PEEK(adress, var1[,...,varn]). The same is true for the CALL POKEV/CALL PEEKV statements that did POKE/PEEK in video memory.

In TI-extended BASIC with memory expansion there also was CALL PEEK and CALL LOAD but as it lifted the 1 statement per line restriction of TI-BASIC there could be more than one CALL PEEK/LOAD per line.

2
1

POKE and PEEK prohibited on the same line?

No ...

There is no such restriction in any somewhat standard BASIC, as it would go against how BASIC works. Lines function only to handle source during editing, and to allow walking them at runtime for sequence and serve as GOTO / GOSUB targets. They do not form any construct of execution bracket.

Any language doing so would not be BASIC (*1).

Execution in BASIC rather simple and straightforward:

  • Lines are executed in sequence.
  • Statements in a line are executed in sequence.
  • POKE is a statement. It will be executed when parsed without any relations to prior (*2,3) or later statements, or any expressions within.
  • Any statement executed may have parameters.
  • All parameters will be evaluated in sequence left to right.
  • Parameters may be (and usually are) expressions.
  • PEEK is a function.
  • Functions can be used as (part of) an expression.

Thus when in a program like:

10 FOR I = 768 to 783
20 POKE I, PEEK(I+1)
30 NEXT I
40 POKE 784, 0

line 20 is executed, POKE will:

  • Evaluate the first parameter I as the target.
    • Evaluation returns the content of I.
  • Evaluate the second parameter as the value.
    • Doing so includes calling the function PEEK, which:
      • Evaluates I+1 as its target.
      • Fetches the content of that location.
      • Returns whatever that is.
  • Then POKE will use both (target, value) to store value at target.

As a result that program will move all bytes from 0301h..030Fh to 0300h..030Eh (*4). What else :)


... But

there is one somewhat known exceptional version of PEEK in TI Extended BASIC. TI BASIC did not implement any PEEK or POKE function or command, as the concept of that machine is more advanced than your average home computer, allowing a closer integration (*5). With Extended BASIC PEEKwas added in form of

  • CALL PEEK(<addr>, var [,var[,...]])

It was meant for speedy access binary data, loaded via CALL LOAD or some other means, for further use - such as sprite images or sound. As mentioned, TI BASIC was quite advanced, but thus 'special' as well.


*1 - I have a hard time finding any reason to implement such.

*2 - Of course statements may be conditioned by an IF / THEN clause.

*3 - Statements following a GOTO on the same line (and REM statements) will of course not be executed.

*4 - Yes, it's a 16-byte queue walking one step closer. :))

*5 - Machine programs could be loaded using CALL LOAD(<name>,<code>), which not only handled the usual DATA-read-loops, but also linked the result into BASIC (*6). Invocation with CALL LINK(<function>, <var>...) allowed exchange via standard BASIC variables, so no need to PEEK and POKE around. Just call it.

*6 - Which makes it quite different from a POKE or multi byte POKE of other implementations.

15
  • 1
    I agree that all this makes sense, and that the language semantics shouldn't prevent PEEK and POKE on the same line. Which is why I remember being surprised. However, I can imagine a BASIC interpreter that would use a common resource for PEEK and POKE (such as a precious pointer in zero page on a 6502). "POKE I," would set the pointer to the destination address, but evaluating the expression "PEEK(I+1)" would clobber the pointer. Trying to meet a deadline to finish the BASIC ROM, just disallow both keywords on the same line, problem solved.
    – Nimloth
    Commented Sep 17, 2022 at 13:16
  • 2
    @Nimloth Why on earth should any programmer of a ROM add code (remember space is scare) to prevent some hypothetical situation that can't be prevented anyway? Peek and poke is intended to handle RAM. What it does is not up to ROM developers. BASIC has no self awareness. Even more by adding a processing mechanic that is alien to the language? Unless you can come up with any BASIC that has this addition, I would think your memory rather mixed that up. Bottom line: With that restriction it wouldn't be BASIC.
    – Raffzahn
    Commented Sep 17, 2022 at 13:59
  • 1
    Any chance this was a timing issue? e.g. reading both paddles on an Apple II could cause interference if you issued the second request too soon after the first.
    – fadden
    Commented Sep 17, 2022 at 14:41
  • 3
    Early versions of BASIC were not only limited to one statement per line, but they also required that IF/THEN statements be conditional jumps, rather than allowing a statement following the THEN to be executed conditionally. It's possible that some version of BASIC had a PEEK statement rather than a function (vaguely analogous to an input statement), but I don't know of any in particular.
    – supercat
    Commented Sep 17, 2022 at 21:33
  • 2
    @Raffzahn: My pain point was that early versions of BASIC were definitely limited to one statement per limt. I recall reading that TI's Extended BASIC for the TI-994/a used CALL POKE, and CALL was statement rather than a function, but that dialect supported multiple statements per lime even though the non-Extended dialect did not.
    – supercat
    Commented Sep 18, 2022 at 13:51

You must log in to answer this question.

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