Classic Computer Magazine Archive COMPUTE! ISSUE 38 / JULY 1983 / PAGE 216

Timex/Sinclair Screenscrolls

Glen Martin

As anyone who has worked with a ZX-81 or TS-1000 knows, the scroll facility could be expanded and improved. It cuts down the display file, and screen POKEs (which are difficult at best) are made nearly impossible. This article provides the solution.

Here are four machine language routines which provide left, right, up, and down scrolls. The scrolls may be used singularly or in any combination. When entered together, they occupy a mere 106 bytes, including the six bytes needed for the REM statement they are stored in.

These utilities will keep the display file expanded to its maximum size, making screen POKEs possible. If preferred, the programs could be assembled above RAMTOP so they would not be affected by NEW or LOAD. Note: These programs will not work with less than 3¼K of RAM, because of the unexpanded display file.

The programs are POKEd in by a short BASIC hex loader, which can also be used for your own machine language routines. Although no previous knowledge of machine language is required to use these programs, I have included mnemonics as well as hex listings. This will be helpful to those readers who understand the Z-80 instruction set and wish to modify or disassemble the programs.

Step-by-step Instructions

The first step in using these scrolls is to type in a REM statement to store them in. The REM statement must be at least 100 characters long, preferably a few bytes longer, so if a mistake is made the program won't POKE up into BASIC. After you have entered the REM statement, enter POKE 16510,0 in the direct mode. This POKEs the first line number to 0 so that it cannot be accidentally edited or deleted. Next, type in this hex loader program:

5 LET A = 16514
15 FOR X = l TO LEN A$-l STEP 2
20 POKE A, 16* CODE A$(X)+ CODE A$ (X + D - 476
25 LET A = A + 1

Now comes the tricky part. Type in 10 LET A$ = " and the hex listing of Program 1 (Upscroll) (e.g., 10 LET A$ = "2A0C40...10FBC9"), ending with quotation marks. Be extremely careful here, since any mistake could crash the computer. Note: There are no spaces in line 10; the hex codes are simply typed in one after the other.

After you have entered line 10 and double-checked for errors, run the program. When it has finished, enter "PRINT A" in direct mode. This should return a value of 16538. If it does not, reenter line 10 and rerun the program.

The variable "A" is simply a pointer to the address at which the next block of code is to be assembled. Therefore, to enter the next block into your computer you must change line 5 to 5 LET A = 16538. Then enter the hex listing for Program 2 (Downscroll) into line 10 and rerun the program. This time, A should be equal to 16567.

Change line 5 to 5 LET A = 16567 and enter the listing for Program 3 (Rightscroll) into line 10. Run the program and check that A is 16588. Change line 5 again to 5 LET A = 16588 and enter the code for Program 4 (Leftscroll). Run the program; A should now equal 16614.

Test Program

Now that the machine language has been entered, lines 5 through 30 can be deleted and a short test program can be run. Enter the test program shown below and run it:

10 LET L = LEN A$
15 IF L>31 THEN GOTO 520 PRINT AT 11,(31-L)/2;A$
25 IF INKEY$="5" THEN RAND USR 16588
30 IF INKEY$="6" THEN RAND USR 16538
35 IF INKEY$="7" THEN RAND USR 16514
40 IF INKEY$="8" THEN RAND USR 16567
45 GOTO 25

The program will wait for an input, so enter a string of less than 32 characters. The string will be printed in the middle of the screen. You should be able to move it around using the arrow keys (5-8).

This program was written as a simple test; the scrolls could certainly be put to better use in programs for games, word processors, or anything else you might come up with. I have used variations of these scrolls in a machine language arcade-type game I am working on and have found that they work quite well. If you want to convert the code listings into decimal, but are not familiar with hexadecimal, the codes from 00 to FF are given beside their decimal equivalent in Appendix A (p. 137) of the Sinclair BASIC Manual.

Let's take a brief overview of the techniques used in these scroll routines. In the horizontal scrolls, everything is shifted up or down one byte, and the first/last column is filled with spaces. A POKE can be entered so that the empty column is filled with a different character. The accumulator is used as a temporary store variable, as in a bubble sort.

In the vertical scrolls, the main instruction is Idir/Iddr. With this instruction, the hl register pair is loaded with the start address of the block to be transferred. The de register pair is loaded with the address the block is to be moved to, and the be register pair is loaded with the length of the block. With these scrolls, everything is shifted up/down 33 bytes (the length of one line + one byte for the "enter" character). The empty line is filled with spaces, but a POKE can also be used here to fill the empty line with another character.

Program 1: upscroII

	2A 0C 40	ld hl,(400C)
	23		inc hl
	E5		push hl
	11 21 00	Id de,0021
	19		add hl, de
	Dl		pop de
	01 B5 02	ld bc, 02B5
	ED B0		ldir
	EB		ex de, hl
	06 20		ld b,20
Blnk    36 00		ld (hl), 00
	23		lnc (hl)
	10 FB		djnz Blnk
	C9		ret.

Program 2: Down scroll

	2A 10 40	ld   hl,(4010)
	11 43 00	ld  de,	0043
	ED 52		sbc  hl, de
	E5		push  hl
	11 21 00	ld  de, 0021
	ED 52		sbc  hl,de
	Dl		pop  de
	01 B5 02	ld  bc, 02B5
	ED B8		lddr
	EB		ex  de,hl
	06 20		ld  b, 20
Blnk    2B		dec  hl
	36 00		ld (hl),00
	10 FB		djnz  Blnk
	C9		ret

Program 3: Rightscroll

	2A 0C 40	ld   hl,(400C)
	06 16		ld  b,16
Lp1     C5		push bc
	06 20		ld  b, 20
	3E 00		ld  a, 00
Lp2     23		inc  hl
	4F		ld  c, a
	7E		ld  a, (hl)
	71		ld (hl), c
	10 FA		djnz  Lp2
	23		inc  hl
        Cl		pop  bc
	10 Fl		djnz  Lpl
        C9		ret

Program 4: Leftscroll

	2A 10 40	ld  hl,(4010)
	11 43 00	ld  de,	0043
	ED 52		sbc hl, de
	06 16		ld b,16
Lp1     C5		push bc
	06 20		ld  b,20
	3E 00		ld  a,00
Lp2     2B		dec  hl
	4F		ld  c,a
	7E		ld  a, hl
	71		ld (hl), c
	10 FA		djnz  Lp2
	2B		dec  hl
	Cl		pop bc
	10 Fl		djnz  Lp1
	C9		ret