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 30 NEXT X
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:
5 INPUT A$ 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