25

I have a vague recollection from my earliest days that the ZX80 only shipped with 1K of RAM.

If this RAM was used to store both the program and the contents of the 32x24 screen, wouldn't that mean only about 256 bytes were available for programming?

Or was there some trick used for video memory, such as a separate section of memory dedicated to the screen, apart from the advertised 1K RAM?

cjs
  • 25,592
  • 2
  • 79
  • 179

2 Answers2

36

Both the ZX80 and the ZX81 had a variable-size display file (DFILE). They didn't store the complete screen contents, but rather only the characters per line up to a terminating newline. This collapsed DFILE is activated when the ZX detects less than 3 1/4kB of memory on startup. A collapsed DFILE can thus be as small as 24+1 bytes (initial HALT, 24 NEWLINEs, or HALT instructions) for an empty screen.

Because ZX-80 and ZX-81 "execute" the DFILE in the display output routine as NOPs, the terminating newline character has to be the opcode of a HALT instruction (76h). This stops the CPU fetching bytes from the DFILE and makes it internally execute NOPs until interrupted (which happens at the end of each scanline, 8 times per character line). The video hardware simply generates white space pixels for the rest of the line.

This results in much less screen memory used than the 768 bytes you would otherwise need for a full screen, at least if you did not fill the complete lines with 32 characters.

Here is a detailed description of how this works (on Grant Searle's great Z80 pages).

cjs
  • 25,592
  • 2
  • 79
  • 179
tofro
  • 34,832
  • 4
  • 89
  • 170
  • 5
    Wow, Grant has way too much time on his hands :-) That's an impressive set of pages, I especially liked the "how to build your own complete zx80/zx81/ace" stuff. The execution of the display file is rather bizarre ... –  Oct 15 '18 at 13:35
  • @paxdiablo execution of the display file is clever: why put an extra counter into the budget machine when you can just reuse the one that's right there inside the CPU? – Tommy Oct 15 '18 at 13:40
  • 5
    @paxdiablo bizarre is not the proper term, IMHO. Ingenious fits it better. – tofro Oct 15 '18 at 13:49
  • @Tommy Actually, it's at least three counters that run through the DFILE on the CPU: (1) the address lines that run over the DFILE on an instruction fetch (2) The R register that triggers the interrupt to get the Z80 out of HALT after each scanline, and (3) the IX register that addresses the ROM character. BTW It gets even more ingenious when you look how easy you can tweak the ZX-81 display routine to implement pixel-addressable Hi-res graphics in software only. – tofro Oct 15 '18 at 14:05
  • 2
    @tofro yeah, I've written one of only two emulators that score 100% timing accuracy to a real ZX81, I was just trying to keep it simple by sticking to the thing already being discussed. I don't think IX is involved though — probably you meant I, which contributes the top 8 bits of the refresh address and therefore the top 7 bits of the character lookup address? Nowhere near as good as Grant Searle's documentation, but my hardware summary is at https://github.com/TomHarte/CLK/wiki/The-ZX80-and-ZX81 – Tommy Oct 15 '18 at 14:54
  • 2
    The Atari 2600 Basic Programming cartridge manages to go one better than this--it generates a line of text from the tokenized source, then displays it, generates another line of text using the same buffer, displays that, etc.thus avoiding any duplication between memory used to store a tokenized program and memory used to display it as text. – supercat Oct 15 '18 at 15:33
  • 1
    @supercat but then again, re: "better", a program running on the ZX80 and ZX81 can output anything it wants over the whole screen, subject to available memory, whereas I think the Atari BASIC offers only two lines out of twelve for your own output? Which, admittedly, is still a superhuman feat with only 128 bytes of RAM. – Tommy Oct 15 '18 at 15:48
  • 1
    @Tommy: The total number of characters, including newlines, that can be output would be 64 minus the number of bytes used for other purposes. If more lines are output than will fit on the screen the remainder will not be displayed (there is no provision for scrolling, but one could maximize the number of display lines by turning off all the other windows). I don't think this trick would work on the ZX81 since much of the scan-line timing is hardware-controlled. Not sure about the ZX80. I'm not sure how many blank scan lines would generally be needed for each line of program. – supercat Oct 15 '18 at 15:54
  • @Tommy: If programs were stored in MS-basic style, I'd guess something like LD A,(HL) / INC HL / INC A / JP PO,x / MOV (DE),A / INC E / JP NZ,LP would be typical for bytes that aren't parts of tokens. 7+6+4+10+7+4+10 -- 48 cycles out of 256 per line, so 8 blank scan lines per each displayed line of program might be workable. Losing half of screen real estate might be annoying, but avoiding the need for a screen buffer might make it worthwhile, esp. if there wouldn't be enough memory for more than 12 lines of program anyway. – supercat Oct 15 '18 at 16:04
  • @tofro, don't get me wrong, I didn't mean "bizarre" in a bad way, just massively out of the ordinary (like extraordinary). I am impressed with the way it was done, in a way I haven't been since I first saw the Woz/Wig RWTS disk I/O code. –  Oct 16 '18 at 00:43
  • Rather inconveniently, the SCROLL command always created a blank line 21 even when you had enough memory to default to a full DFILE, so anyone doing serious scrolling wrote a quick memory copy in machine code to scroll instead. – Neil Oct 16 '18 at 00:47
  • The ZGrass and BASIC for the Bally was even crazier. They had four colors per pixel, so they set two of the colors the same as the other two and then put one bit of color and one bit of code in every screen location, with the high bit having no effect because the colors were the same. – Maury Markowitz Oct 16 '18 at 18:34
  • tofro, I see Grant has Z80 pages (amongst a great deal of other stuff I intend to read now that you've uncovered them for me) but I wonder whether this answer should actually be changed to read "Grant Searle's great Z*X*80 pages" since it (and the link) are specifically for the ZX80 rather than the Z80 in general. Normally, I'd just edit the answer but I don't want to step on your toes. – paxdiablo Feb 28 '22 at 00:30
  • @paxdiablo Grant's great home page provides a plethora of information on computers, some (minor) part actually covering the ZX80/81 and the very similar Jupiter Ace, but the majority really is on CP/M / Z80 and other retro CPUs. – tofro Feb 28 '22 at 11:32
-1

It did not (at least not without ugly tricks). In addition to tofro's answer, a simple program at ZX-81 looking something like this (writing from memory):

10 FOR Y=1 TO 24
20 FOR X=1 TO 32
30 PRINT AT Y,X;"X"
40 NEXT X
50 NEXT Y

... was enough to achieve Out-of-memory error, because there was not enough room in memory for this measly program, system variables and a full display.

Omar and Lorraine
  • 38,883
  • 14
  • 134
  • 274
Edheldil
  • 139
  • 3
  • 2
    Seems to be not true. At least not on ZX80 on this emulator http://nocanvas.zame-dev.org/0004/ – UncleBod Oct 16 '18 at 09:36
  • 4
    @UncleBod are you able to show the code you ran? The ZX 80 does not have an AT, like the ZX Spectrum does and like Edheldil's code shows. – Omar and Lorraine Oct 16 '18 at 11:15
  • I guess just PRINT "X"; would achieve what the author is trying to communicate? – Tommy Oct 16 '18 at 12:20
  • @wilson As above, except only PRINT "X"; instead of PRINT AT (Which ZX80 doesn't have). The program size might differ 4-5 bytes, not more. And really, to cram as much as possible into a computer was a sport in those days. Search for ZX81 1K Chess.... – UncleBod Oct 16 '18 at 12:28
  • 1
    ZX81 1K Chess only used 8 lines of the display for the same reason discussed here.

    I would guess the ZX80 emulator you used was set up to have expanded RAM. Sinclair sold a 3K RAM pack for it, but the initial machine came with only 1K. It could not store a full screen of characters.

    – Greenaum Sep 17 '19 at 04:56
  • 2
    I remember on my old 1K ZX80, as I typed in more and more program, it would seem to lose more and more of it from the end, "eating" its way from the bottom of the screen upwards. Presumably because the DFILE had to be sacrificed for the actual program. And ISTR the 3K expansion pack (when I finally got some money together as a poor student) was very flaky, prone to reboot as the slightest tremor. I'm pretty certain it was a good idea to leave the room if you had to cough :-) – paxdiablo Feb 28 '22 at 00:22