SPECTRUM TOOLKIT
from Your Computer, February 1983

Bobby Rao offers some handy hints to would-be machine-code
users. Here are some useful off-the-peg routines.

HERE ARE ABOUT 20 machine-code graphics routines, any combination of which
may be used in your programs to enhance the screen displays, or to give them
that extra touch of elegance that comes only from the usc of machine code.
Also included are renumber and memory-left routines which may be used to aid
your programming.

No understanding of machine code is necessary to use the routines - just a
good working knowledge of the Spectrum and its manual. Machine code is the
computer's first language - it only speaks BASIC out of courtesy to humans -
and its use results in greater speed, flexibility and more economical use of
memory than does the use of BASIC.

To get the machine code into the computer a hex loader must be used - see
program 1. Type this in and SAVE it. Machine code can either be stored above
RAMTOP or in a REM statement at the beginning of a program. I prefer the
latter method, for each different routine may be stored in a REM statement
with a different line number and then MERGEd into a program as required.
However, if you wish to use the first method then change line 5 as shown
underneath the program listing. [I changed the loader and DATA statements
because the format used in the magazine was too time-consuming to type in.
JimG]

Here is an example of how you go about loading in the memory-left routine,
see listing 1. Firstly LOAD in the hex loader and type in a REM statement as
line 1. This REM statement should consist of 14 full stops because the
memory-left routine is 14 bytes - characters - long. If you are using the
RAMTOP method then you will not need to do this - just CLEAR yourself enough
memory space above RAMTOP. Now carefully type in the DATA line in listing 1
and after checking this line RUN the program. LISTing it will show that line
1 is now a meaningless jumble - if you have a line 1, that is - but do not
worry, for this is supposed to happen. Also it is likely that LISTing the
program when the REM line is in this state will cause the computer to stop
with an error report. To avoid this and view the rest of the program you must
always use LIST - line number of first line after REM line - so that the
Spectrum does not try to LIST the unlistable REM line.

Now the routine is ready to be SAVEd. Erase all of the hex loader except the
REM line - do not use NEW whatever you do - and SAVE this with a filename
like "Mem Left". Now NEW the computer and reload the hex loader. Repeat the
above process for the rest of the routines, but make sure you never use the
same REM line number for two different routines because this will cause
trouble when you come to merging routines together.

RAMTOP-method users may SAVE their routines by using the SAVE "filename" CODE
method detailed in the manual on pages 143 and 180.

Once the tedious task of typing in and saving the routines has been
accomplished you are ready to use the routines. If you wish to use some of
the routines in one of your programs then start that program at, for example,
line 100, leaving the earlier line numbers free for the machine-code REM
lines. After typing in the program, MERGE in the routines you require. To run
machine code rather than BASIC the USR function must be used.

The argument of this function is the address of the first byte of the
machine-code routine you want to run, and this may be found, if you are using
the REM method, by using program 2. On running this program - whilst the
machine-code routines are in the computer - line numbers and the start
addresses of the routines in those lines are printed until the computer finds
a non-REM line when it will STOP. Note these start addresses down, or better
still, define variables equal to these values by placing a lot of LET
statements somewhere in your program, for example:
		LET INV=23760
Now just typing PRINT INV will tell you the address of the first byte of the
invert-screen routine.

RAMTOP-method users will not need to use program 2 because they will already
know the addresses of their routines or they would not have been able to get
them above RAMTOP in the first place.

To use the routines use the command RANDOMIZE 0*USR X, where X is the
address of the routine you are using. The result of the USR function is
multiplied by 0 to keep RND truly random; that is, it acts like a RANDOMIZE 0
command.

Below there is a description of all the routines and how to use them. In
these descriptions the variable X stands for the address of the first byte of
the routine in question. All numbers are in decimal and unless otherwise
stated all the screen routines operate on all 24 lines of the screen.

Where you are told to POKE something somewhere the POKEs must be done before
you use the routines and they may be entered as a series of direct commands
before you RUN the program or they may be built into the program.

MEMORY LEFT: running this - listing 1 - using PRINT USR X will tell you the
exact number of free bytes of memory you have left.

HI-RES UP SCROLL: this - listing 2 - routine scrolls the screen up by one
high-res pixel, replacing the bottom line of pixels with blanks.

HI-RES DOWN SCROLL: as in listing 2, but this - listing 3 - scrolls down,
blanking the top line of pixels.

HI-RES LEFT SCROLL: this scrolls the screen left one pixel, replacing the
rightmost column of pixels with blanks - see listing 4.

HI-RES RIGHT SCROLL: as in listing 4, but the screen scrolls right, blanking
the leftmost column of pixels.

ONE CHARACTER LEFT SCROLL: the listing 6 routine scrolls the screen left one
character, replacing the rightmost column with either blanks - for this
effect POKE X+16,54 - or the previous leftmost column - a wrap-around
effect - for this POKE X+16,119.

ONE CHARACTER RIGHT SCROLL: the listing 7 routine scrolls right. POKE X+16,54
causes the leftmost column to be blanked and POKE X+16,119 replaces this
column with the previous rightmost column.

These last two routines are adjustable in which part of the screen they
scroll but you only have five options. The table below tells you how to
adjust the routines. The first column tells you which part of the screen is
to be scrolled. The next two columns tell you what to POKE in X+1 and in X+4
respectively for the left scroll routine. The last two columns tell you what
to POKE in X+1 and X+4 respectively for the right scroll routine.
	Top one-third       64  64   64  71
	Middle one-third    64  72   64  79
	Bottom one-third    64  80   64  87
	Top two-thirds     128  64  128  79
	Bottom two-thirds  128  72  128  87

INVERT SCREEN: the listing 8 routine inverts the actual pixels on the screen;
that is, all pixels on are turned off and all pixels off are turned on, and so
it is different from the INVERSE function on the Spectrum which only inverts
the INK and PAPER colours - which this routine does not alter.

SCREEN FILL: this routine - listing 9 - fills in a box of height a, width b,
and a top left-hand corner at a point c,d - where c and d are coordinates
used by the PRINT AT system - with any character of your choice.
		POKE X+1,character-code
		POKE X+3,a POKE X+4,c
		POKE X+6,b POKE X+7,d
So if a=22, b=32, c=0 and d=0 then the normal 22-line screen is filled. You
must have PRINTed something somewhere before using this routine or it will
not work properly. Also note that you cannot PRINT on line 24 with this
routine.

INK CHANGE: this - see listing 10 - changes the INK colour of the screen
without altering anything else. POKE X+1 the number of the colour you want
to change the INK to.

PAPER CHANGE: as listing 10 but changes the PAPER colour. POKE X+1 the
number of the colour you want to change the PAPER to - see listing 11.

FLASH ON/OFF: this routine - listing 12 - sets the whole screen flashing -
for this POKE X+9,254 - or returns the screen to normal non-flashing mode -
for this POKE X+9,190.

BRIGHT ON/OFF: the routine shown in listing 13 makes the whole screen bright
- POKE X+9,246 - or returns it to normal brightness - POKE X+9,182.

ATTR FILL: the 14th listing changes the attributes for a box height a,
width b, and of top left-hand corner at a point c,d where c and d are
co-ordinates used by the PRINT AT system to denote a point on the screen.
   		POKE X+3,d POKE X+4,c
		POKE X+6,b POKE X+7,a
POKE X+1 the value you want to change the attributes to. This value may be
calculated thus: first assume the new ATTR value is Y and initially Y=0. If
FLASH is on add 128 to Y, if off add 0. If BRIGHT is on add 64 to Y, if off
add 0. Add eight times the number of the PAPER colour to Y. Add the number of
the INK colour to Y. This means that an attribute of FLASHing, BRIGHT blue
INK on yellow PAPER would be 128+64+(1*8)+6=206. With this routine you can
change the attributes of the whole 24-line screen.

ATTR UP SCROLL: this routine - listing 15 - allows you to scroll up the
attributes for a box height a, width b, and top left-hand corner at a point
c,d. The bottom line of the box is replaced with an attribute of value Y -
see ATTR FILL for how to calculate Y.
		POKE X+1,n
		POKE X+3,d POKE X+4,c
		POKE X+6,b POKE X+7,a

ATTR DOWN SCROLL: listing 16 scrolls down replacing the top line of the box
with the new attribute. The POKEs arc the same as for the previous routine.

ATTR LEFT SCROLL: as listing 16 but scrolls left replacing the rightmost
column of the box with either a new attribute - for this POKE X+36,0 - or
with what was previously in the leftmost column of the box - for this POKE
X+36,26. This last effect - wrap-around - allows this routine to be used
fully with the one character left scroll routine given above -see listing 17.

ATTR RIGHT SCROLL: the routine shown in listing 18 scrolls right, replacing
the leftmost column of the box with either a new attribute - for this POKE
X+43,0 - or with what was previously in the rightmost column of the box -
for this POKE X+43,26. This last effect allows this routine to be used fully
with the one character right scroll given previously.

The next three routines allow you to store screens currently being displayed
in spare memory and then recall them onto the display, either making them
swap memory position with the screen currently being displayed, or
overprinting them on to the current display. To store screens you must
firstly CLEAR some memory space so you can store the screens there. Each
screen - with attributes - is 6,912 bytes long so this much space is required
for each screen. [The SWAP and OVERPRINT routines were swapped around in the
listing; ie. each appeared under the other's title.]

The memory location of RAMTOP - the last byte of the computer's memory - can
be found by using PRINT PEEK 23730+256*PEEK 23731. If this number is W
then W-Q*6912 - where Q is the number of screens to be stored - will tell
you the address to CLEAR RAMTOP to - see manual page 168. You must have
cleared this space or the routines will not function correctly.

If you only have 16K of memory then space exists for storing only one screen
so CLEAR 25685 is all you need to use. In order that the routines know where
in the memory a screen is to be fetched from or sent to you must do the
following for all the routines:
		POKE X+1,W-INT (W/256)*256
		POKE X+2,INT (W/256)
If you have 48K and you wish to store more than one screen then it might be
advisable to leave a gap of a few bytes in-between screens so as to lower the
risk of one screen running over onto another by accident.

If you are using the RAMTOP method for storing the machine-code routines then
be extra careful, or you will end up ruining the routines and crashing the
computer. Make sure you take into account the length of the routines when
deciding where you CLEAR RAMTOP to.

STORE SCREEN: This replaces the current display with one already in the
memory - see listing 19.

SWAP SCREENS: This routine swaps the current display with one higher up in
the memory so that the screen that was being displayed is stored in the
memory and the screen that was in memory is now displayed - see listing 20.

OVERPRINT SCREENS: This overprints a screen from higher up in the memory onto
the current display. The old display is lost in its original form - it is not
stored anywhere by this routine before it is altered - but the screen used to
overprint the old display still remains intact higher up in the memory. The
attributes are not changed by this routine so after the routine has been used
the attributes being displayed are those of the old display - see listing 21.

RENUMBER: this routine - listing 22 - instantly renumbers all the line numbers
of your program starting the first line at a specified value and increasing
this value by a specified amount as it renumbers the rest of the lines. Note
that this does not change the GOTOs and GOSUBs so you will have to alter
these manually. If the first line is renumbered L and the value by which L is
increased is M then:
		POKE X+5,M-INT (M/256)*256
		POKE X+6,INT (M/256)
		POKE X+8,L-INT (L/256)*256
		POKE X+9,INT (L/256)
For fun you might try renumbering all lines 0 or try using a starting value
greater than 9999.

The uses of these routines are many and varied, limited only by the
imagination of the user. For example, the left and right scrolls with
wrap-around may be used to create a constantly moving background for a space
game. Any of the scrolling routines may be used to clear all or part of the
screen in a novel way.

The INK and PAPER changing routines may be used to create a surprise effect
by first drawing a picture on the screen using the same INK and PAPER colour
and then altering either so that the picture appears instantly. Animated
cartoon effects are possible using the screen swapping routines and stunning
explosion effects may be simulated by using the Invert Screen routine
repeatedly - in a loop. The list is endless and these are just a few broad
guidelines that you can experiment with and doubtless improve on.

Just as a bit of fun try the following POKE next time you have a program in
your Spectrum - POKE 23606,8. This makes the computer speak Russian - nearly.
POKE 23606,0 restores normality.

