helpline |
Andrew Hewson considers a number of problems involving the use of graphics on both the ZX-81 and the Spectrum
CAN ZX-81 characters be printed using POKES to make them bigger and easier to read? That is what John Kerr asks.
The answer is that there is a method, although it is not necessary to use POKE. The Basic program in table one PRINTs a character at eight times its normal size. The program is rather slow but it serves to illustrate the technique.
Both the ZX-81 and Spectrum construct characters by inking-in relevant squares in an 8x8 grid. No squares are inked-in for the space character, for example, and a star-shaped group of squares is inked-in to form the asterisk. An 8x8 grid is used because the form of each horizontal strip of squares can be stored using the eight bits which form a byte by inking-in a square if the corresponding bit is set to one. Thus eight bytes are used to store the form of each character. The ZX-81 character table is held in the ROM at locations 7680 onwards.
The program works by setting the variable A to the address of the first byte of the character selected by the user. Lines 150 to 270 are the beginning and end of a loop which cycles through each of the eight bytes in turn. The contents of the current byte are loaded into variable B and then compared to 2**7,2**6,2**5 and the like in turn.
That is equivalent to testing each of the eight bits. If B is greater than or equal to 2**I, the corresponding bit is set and so the program PRINTS a character. If B is less than 2**I, a space is PRINTed instead. Thus an image of the character is constructed which occupies not one but 8x8 PRINT locations.
|
|
The Basic program is rather slow to execute and so I have written the machine code routine listed in table two to do a similar task on the 16K ZX-81. The routine can be loaded using a simple hex loader, for example:
10 REM AT LEAST 46 CHARACTERS 20 FOR I=16517 TO 16552 30 INPUT Z$ 40 IF Z$="S" THEN STOP 50 PRINT Z$;" "; 60 POKE I,16*CODE Z$+CODE Z$(2)-476 70 NEXT I
The REM statement must contain at least 46 characters because the machine code routine is 43 bytes long and it uses another three bytes to hold variables. To load the routine run the hex loader and enter each pair of hex character codes in turn.
To use the routine, retain line 10 of the hex loader and enter the following:
20 PRINT "ENTER A CHARACTER" 30 INPUT Z$ 40 CLS 50 LET A=8*CODE Z$ 60 POKE 16514, A-256*INT(A/256) 70 POKE 16515, INT(A/256) 80 POKE 16516, CODE Z$ 90 RAND USR 16517 100 PAUSE 32768 110 CLS 120 GO TO 20
Paul Cooksley has a Spectrum. He writes: When I enter POKE 23607,50 the whole character set becomes spotty squares. Why?
The chapter on the system variables of ZX Spectrum Basic Programming shows that location 23607 contains one fewer than the high byte of the address of the Spectrum character table. The character table is held at 15616 and so locations 23606 and 23607 normally contain 0 and 60 respectively because
0+256*(60+1)=15616
Thus, noting that the first true character in the Spectrum character set has CODE 32 not CODE 0 as on the ZX-81, the ZX-81 program in table one can be adapted to run on the Spectrum by substituting
130 LET A=PEEK 23606+256*PEEK 23607+8*CODE Z$
It is also necessary to alter lines 190 and 240 as follows:
190 LET E=2↑I 240 PRINT CHR$ 32;
POKEing a new value into 23607 causes the Spectrum to look in a new place for the eight bytes which determine each character leading to the spotty squares effect which Cooksley noticed. The same effect can be generated on the ZX-81 because the high byte of the address of the character table is held in the I register. A short machine code routine can be used to alter the value in I as in this program sent by Roger Milton:
1 REM YO GO SUB? TAN 10 POKE 16517,71 20 INPUT A 30 POKE 16515,A 40 RAND USR 16514 50 IF A<>30 GO TO 20
The GO SUB and TAN in line one must be entered as tokens. To achieve that enter the line in reverse order, i.e.
TAN b GO SUB?bb 1 REM YO
where "b" represents back-space. The program transfers the value entered by the user to the I register and the spotty squares effect results. If the correct value is entered (30) the program halts.
Unfortunately it is not possible to use values greater than 63 which would point into the RAM area because the ZX-81 hardware misinterprets the resulting address. The only effect is to generate black or white squares.
One of the many extra features of the Spectrum is the facility to VERIFY tape copies of programs or data. Is it possible to verify the screen display? asks Michael Moses.
VERIFYing the display should be straightforward using the commands
VERIFY "" SCREEN$
or as an equivalent
VERIFY "" CODE 16384,6192
Unfortunately the ROM routine which searches the cassette PRINTs the name of the cassette file to be VERIFYed on the screen, thereby corrupting the Spectrum copy of the display.
There are two solutions. The first is to copy the display to an area above RAMTOP and VERIFY the copy of the display. That technique has the added advantage that the display can be restored from above RAMTOP if required.
The routine in table three copies the display above RAMTOP, SAVEs and VERIFYs the copy and restores the display on completion. It is written to run on the 48K machine. To run it on the 16K Spectrum, change 229 in each of the DATA statements to 101 and change 58624 in lines 290 and 310 to 25856. Space must be reserved above RAMTOP before the display is generated by entering
CLEAR 58624
on the 48K machine or
CLEAR 25856
on the 16K machine.
The routine works by loading two short machine code routines into the printer buffer from the DATA statements. The two routines copy and restore the display respectively by setting the HL register pair to the address to be copied from; the DE register pair to the address to be copied to; and the BC register pair to the number of bytes to be copied in this case 6912. The LDIR instruction then moves each byte in turn.
|
The CLS command in line 9880 is redundant. Its only purpose is to demonstrate that the routines are working correctly by clearing the display between copying and restoring it. The copy which has been SAVEd on tape can be LOADed in the usual way by entering
LOAD "" SCREENS
The disadvantage of the routine is that a great deal of space - almost 7K - is used to store the display above RAMTOP, which leaves very little space on the 16K Spectrum for anything else. Table four presents an alternative which uses much less space because it stores only the parts of the display which are corrupted by the Spectrum cassette search routine. A special routine must also be used to LOAD the cassette copy.
The program works by copying the first 17 characters on line one of the display into the printer buffer lines 9500 to 9560 - followed by the attributes of the 17 - characters lines 9570 to 9590. It then PRINTs on the display the message which the Spectrum cassette search routine will PRINT when it locates the cassette copy and SAVEs the display file, the attributes and the beginning of the printer buffer which can be used to restore the display to the correct condition. The routine then resets the PRINT position and VERIFYs the cassette copy - lines 9620 to 9630. Finally, lines 9640 to 9730 copy the contents of the printer buffer back to the display.
The VERIFY routine can also be used to LOAD the display by changing line 9630 to
9630 LOAD "" CODE 16384
It is important to note that the message PRINTed by line 9600 should be 17 characters long. Thus if the cassette copy is to be called "Display", three trailing blanks should be added after the word Display.
|