I remember programming a ZX spectrum in 128 basic (about 20 years ago). I remember I was able to save a third of the screen into a variable. Something like this:

10 LET A$ = [16384 BYTES starting at 16384]

But I can't remember the syntax I used. I remember then being able to store the whole screen memory in three strings. And being able to use these to store and play animations.

I have tried things like

LET A$ = CODE 16384,16384


LET A$ = SCREEN$(0 to 10, 0 to 32)

But I can't for the life of me remember what it was. And I can't even find it in the documentation. Since there doesn't seem to be a way to read and store strings at memory addresses.

I've been able to do something similar just by using a RAM disk like this:

SAVE! "picture" SCREEN$

But I am sure I was able to store the screen pixels inside a string. But all I can find in the documentation is peeking and poking one byte at a time. And ideas?

  • By the way, the reason why it would only store a third of the screen was I seem to remember this was like a memory restriction of the strings. – zooby Aug 28 '19 at 16:04

Did you, by any chance, use Beta Basic for the Spectrum?

There you could assign memory ranges to strings and vice versa like

10 REM Move memory to a string
20 LET a$=MEMORY$()(16384 TO 22527)
30 REM Move back
40 POKE 16384,a$

I doubt standard Sinclair BASIC would have allowed anything like that.

With a bit of machine code, you could, however, easily implement stream input and output to and from memory. I remember having a piece of code somewhere that implemented an "M" stream type that could do that.

  • Was that POKE <adr>,string really in there and would poke the whle strinc byte by byte? That seams like an extreme cool extension for POKE I never thought of. Cool. – Raffzahn Aug 28 '19 at 9:32
  • 1
    @Raffzahn Yes. You could poke a whole string to memory - That was a Beta Basic Extension to POKE. There are some other BASIC variants in Sinclair Basics, for the QL, for example, that implement the same thing using a POKE$ command. – tofro Aug 28 '19 at 9:37
  • Cool. Ok, so I have missed it because I never had them/read about. Nonetheless. it's such an awesome idea. Simple and quite intriguing. I feel an urge to implement that right away :)) Thinking of it, the other way around is maybe not as straight forward. Strings are variable in BASIC, so the interpreter can't take the desired length for a PEEK from there. Maybe a PEEK(<adr> [,<len>])needs to be made (the memory$ syntax from above is way too Sinclair specific). Do you know of other solutions? – Raffzahn Aug 28 '19 at 9:42
  • 1
    @Raffzahn In BetaBasic, you always had to slice the string (i.e, had to know up-front how long the string in memory was) - But you could POKE the string length just in front of it and retrieve it afterwards. My QL knows PEEK$ in two variants: Either you give it the length to PEEK as a second argument, or, if you omit that, it assumes the string is in internal format in memory where the first word is the length. – tofro Aug 28 '19 at 10:04
  • Quite interesting. Your Answer really did make my brain jump. I love that PEEK thing. Result: One of the rare occasions I had to setup a question regarding this. Would you mind to add your knowledge there? I'd really appreciate that. - And finally: Now I really need to get me a SAM COUPE. – Raffzahn Aug 28 '19 at 10:47

Three strings sounds odd, as a picture is either two regions (of 6 KiB for pixels and 0.75 KiB for colour) or one 6.75 KiB chunk. See this great answer for details.

As standard Spectrum basic only allowed saving the whole screen (SAVE "x" SCREEN$) or a memory section (SAVE "x" CODE 16384,6912), I assume you used some machine language routine, or a BASIC extension to do your animation.

  • 1
    The ZX Spectrum screen area (the pixels) is actually spread into three non-linear address ranges due to its weird memory layout ("0 1 0 Y7 Y6 Y2 Y1 Y0 Y5 Y4 Y3 X4 X3 X2 X0"). In the linked answer's animated GIF you can easily identify the three blocks. – tofro Aug 28 '19 at 9:14
  • 1
    @tofro not realy. The screen is one continuous range of memory, not three. Within the screen memory the lines are not assigned in a straight continuous fashion. They are assigned in steps of 8 and 64 (the later maybe being what you consider 3 sections, but rather the effect of having 6 KiB to fit the 192 lines). Having such an internal structure doesn't make it less of a continuous screen memory, unlike the Apple II, which also carried 'Venetian blinds', but also had 'holes' within the memory - still it was my most applications seen as 8 KiB of continuous screen memory. – Raffzahn Aug 28 '19 at 9:30
  • 1
    @tofro Well, I'd disagree who is making up artificial divisions. After all, is it one continuous blob of memory that can be stored as one, or are there any things inbetween to be skipped and this making it necessary to make it 3 blocks? Cause if it's just about the linearity of lines, then you'll get 192 blocks, right? – Raffzahn Aug 28 '19 at 9:37
  • 1
    I seem to remember at the time it was due to a memory constraint of the the string which could only store up to a certain size. Weird I know. But that's my memory of it. – zooby Aug 28 '19 at 16:12
  • 1
    On the Spectrum, a string can be (space permitting - free memory never is that large) 64KBytes long. A newly started Spectrum 48k with no extensions and no program loaded should be having >20k of free space. This should easily suffice for a screen. On a Spectrum 128, there should be plenty more memory, although you could only access the expanded memory in chunks of 16k – tofro Aug 29 '19 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.