Personal Computer News


Full Display

 
Published in Personal Computer News #076

It's possible to print on the Spectrum screen's bottom two lines with John Lettice's program.

Full Display

It's possible to print on the Spectrum screen's bottom two lines with John Lettice's program

Every now and again you'll run across a problem that would be solved if you could print on the bottom two lines of the Spectrum's screen. You might, for example, be writing a graphics program, where you need the whole screen for drawing on, or you might just grudge losing the extra two lines space.

You can get an image on the bottom two lines of the screen by POKEing numbers into the relevant parts of the display file, so the logical way of dealing with the problem is to find some mechanism that allows you to do this. Try:

 10 FOR N=16384 TO 22527
 20 POKE N,255
 30 NEXT N

As this one flashes by, you'll see the whole screen filled, then the INK on the bottom two lines will be wiped out by the appearance of the OK prompt. Add:

 40 GO TO 40

and you should have proved to yourself that it's possible to get an image on the report lines.

The Spectrum's display file runs from memory locations 16384 tpo 22527, so what you're doing is POKEing 255 into each of these. But think about the disadvantage: run the program again, and you'll see that the screen is actually built up in a very bizarre way. First the top line of pixels in the first row of character positions is INKed in, then the top line of the second row, and so on until it doubles back to the second row of pixels, then onto the next part of the screen, and then the next.

POKEs

Line Start of Line End of Line
0 16384 16415
1 16416 16447
2 16448 16479
3 16480 16511
4 16512 16543
5 16544 16575
6 16576 16607
7 16608 16639
8 18432 18463
9 18464 18495
10 18496 18527
11 18528 18559
12 18560 18591
13 18592 18623
14 18624 18655
15 18656 18687
16 20480 20511
17 20512 20543
18 20544 20575
19 20576 20607
20 20608 20639
21 20640 20671
22 20672 20703
23 20704 20735
 
Table 1. Display Memory Map

Table 1 illustrates the full awful truth about the Spectrum's screen layout, and shows you that using POKEs to print at any one character position isn't exactly straightforward.

Don't panic, though, because there's a system behind it, and all you need to do is work out the formula. The next thing you need to do is work out the dot patterns you POKE into the character positions using this formula. If you want to produce user-defined characters in the report lines, then you're pretty much on your own, although it would be fairly easy to copy user-defined graphics you'd already produced into the correct memory locations.

If you want to use the Spectrum's own character set, life's quite easy, as you just have to copy the dot patterns for the character set across from ROM into the screen locations. This is less of a headache, since the dot patterns for each character are held in eight consecutive addresses.

What we want, then, is a routine that will PEEK the values held in ROM for the character set dot patterns, then POKE them into the screen addresses for the relevant character position. The routine presented here is slower than printing on the screen normally, mainly because the program is in Basic, but it's quite adequate for static displays you're not likely to want to change too often.

Turning the text you want printed into DATA statements would be marginally faster, but would lose you the advantage of having a universally applicable formula. Another alternative would be to store the memory locations in DATA statements or in an array, then PEEK the ROM pattern and POKE that into the location, but although this would be faster, you'd lose the advantage of the formula.

If you want to put your own message at the bottom of the screen then it's just a matter of changing a$, making sure you use 64 characters for it.

Program Notes

10 Dimensions an array of 64 characters
20 Defines the array
30-90 Main loop of the program
40 Defines B as the CODE of each of the characters in A$, one at a time
50 Determines the address of the first line of each character in ROM in the following way. The dot patterns of the character set start at 15360, and the CODEs of the characters increase in steps of 1, i.e. A is 65 and B is 66. As each character occupies eight addresses, its start address is 8* (its CODE).
60 Determines the address of the first line of each of the 64 character positions to be POKEd into
80 Loops through the eight pixel lines of each character position. Each character position's start address is 256 below the address of the line of pixels immediately below it, so 256*P gives you each address. It then PEEKs the address of the correct dot pattern and POKEs it in.

Code

 10 DIM A$(64)
 20 LET A$="THE BOTTOM LINE IS THIS 12345678901234567890123456789012"
 30 FOR N=1 TO 61
 40 LET B=CODE A$(N)
 50 LET C=15360+B*8
 60 LET D=20671+N
 70 FOR P=0 TO 7
 80 POKE D+(256*P),PEEK (C+P)
 90 NEXT P:NEXT N
100 PAUSE 0

John Lettice