Thursday, 23 March 2017

Peeking into the ZX81s Screen Maze

While thinking about some possibilities of how to approach various projects in my to-do list, I realised that these were going to need some screen reading elements, or rather I'd need to PEEK into the display file to see what was going on. This lead to some re-research into how the ZX81 handles its screen output. While some excellent information on the subject is not hard to find, I figure a poke into this might be of use to others.

What's being displayed by the ZX81 on a monitor at any given time is not exactly a mystery, nor is how it got there. What  can be mystery is how to retrieve that information for (re)usage in an application. Actually that's not much of a puzzle either, though possibly a little ambiguous at first.

The ZX81 stores screen related information in a area of memory known as the "display file" or DFILE for short, this is outlined briefly in chapters 27 of the ZX81 manual. What's not made quite so clear is how to access that area of memory, or how that area is configured at any given moment by the machine. This last part is particularly crucial if your ZX81 has less than 4k of RAM (Not of any real concern these days I suppose, but you never know.)

The relationship between the ZX81 Display File and D_File system variables laid out for easy reference.

First off we need to know where the DFILE resides. The location is not static (unlike the ZX Spectrum's DFILE) and moves up or down depending on the size the BASIC program listing. Thankfully there is a system variable, D_FILE, which stores this starting location. What we need to do is PEEK the address of the D_FILE variable to ascertain the location of the actual DFILE. Note that address is stored in 2 bytes.

PRINT PEEK 16396 + PEEK 16397 * 256

On a freshly booted system the result of  the above should be 16509. You might notice that this is also the starting address for the "Program" memory area, which indicates that there is currently no program stored.

Next we can determine how large the DFILE is by reading the system variable VARS. This is where a non expanded ZX81 will differ from one with a RAM pack attached. The returned value will give you the starting location of the user Variables memory allocation area. Again note that the returned listed values from PEEKing the VARS system variable assume there in no program loaded.

PRINT PEEK 16400 + PEEK 16401 * 256

Variables starting address on a 1k ZX81 (or 2k Timex 1000) is: 16534
On a ZX81 with 4k or more expanded memory: 17302


If we subtract the value of D_FILE from VARS, the byte allocation or size of the DFILE is revealed. What we notice is that on a 1k ZX81 the default size of the DFILE is 25 bytes, and on a 4k plus system the DFILE is allocated 793 bytes. The massive (overstatement) size difference between an expanded and unexpaned machine comes down to how the ZX81 handles the DFILE. On a 2k or less machine the DFILE is expanded as it is required, while on a 4k plus computer the DFILE is always fully extended.

On a 1k or 2k ZX81, each of those 25 bytes contains a CHR$ 118, the Newline Character. One CHR$ 118 marks the start of the DFILE , and when a line is printed to, the DFILE is expanded to a maximum of 32 characters per line, with each line always being terminated by a Newline.

A ZX81 with 4k or more always has a fully expanded DFILE, containing 25 CHR$ 118, marking the start of the DFILE and end of each line, plus 32 * 24 characters, which are initially CHR$ 0, the space character, yielding a 793 byte total.

Putting the above into practice, two programs below demonstrate how to POKE to the screen directly, instead of PRINTing. The key lines in both applications are 80 (highlighted), where the second PEEK address is adjusted for either the expanded or collapsed DFILE.


1) Program For a 1K ZX81. If using an emulator make sure it's set for 1K
10 PRINT "POKE MY SCREEN 1K"
20 PRINT AT 2,8;"+++"
30 PRINT TAB 8;"+ +"
40 PRINT TAB 8;"+++"
50 PRINT AT 6,0;"ENTER A CHARACTER AND NEWLINE","OR JUST NEWLINE TO STOP"
60 INPUT A$
70 IF A$="" THEN STOP
80 POKE PEEK 16396+PEEK 16397*256+41,CODE A$
90 GOTO 60

2) Program For a 4K and up ZX81. If using an emulator make sure it's set for 4K or more
10 PRINT "POKE MY SCREEN 4K AND UP"
20 PRINT AT 2,8;"+++"
30 PRINT TAB 8;"+ +"
40 PRINT TAB 8;"+++"
50 PRINT AT 6,0;"ENTER A CHARACTER AND NEWLINE","OR JUST NEWLINE TO STOP"
60 INPUT A$
70 IF A$="" THEN STOP
80 POKE PEEK 16396+PEEK 16397*256+109,CODE A$
90 GOTO 60

The programs above have been modified from listings originally published in the September / October 1981 issue of Sync Magazine, which is available from the Internet Archive. It's well worth trawling through the entire Sync back catalogue for all manner of useful insights.

Using the information above you can see how easy it is to read or write to the ZX81s screen, and then take that into more complex programs. For a deeper insights into the ZX81s display, you can't go past Wilf Rigters' extensive write up The ZX81 Video Display System.

Finally, yes you really can do something interesting with this information, the below maze is generated by a program written in C for the Z88DK compiler. The Maze generator relies heavily on being able to read the Screen / DFILE (that and a maze algorithm). Feel free to download The Maze C source and ZX81 P file for perusal.

Output of the ZX81 Maze Program.