!0.......^.........^.........^..
!B
\H10\H07     MOVING GRAPHICS OF THE     
\H10\H00\H11\H07  H  O  R  I  Z  O  N  T  A  L  
\H10\H07              KIND              

!2.......^.........^.........^.........^.........^.........^....
Every now and again you may feel an uncontrollable urge to write
some sort of computer program. (There is no known cure for this
compulsion, although it has been suggested that long holidays in
the countryside might possibly do the trick.) But for instance,
 what do you do if you want to scroll the screen side- ways and
 haven't the foggiest idea where to start? Well, forget phoning
the Samaritans, because Toni Baker is about to suggest that one
     answer to many of your problems lies in machine code.
!1.......^.........^.........^.........^........

I'll tell you what - type in this Basic program,
which is adapted from a program out of Mastering
Machine  Code  on  Your ZX Spectrum (written  by
some looney not a million miles from these pages
- plug! - and published by Interface).
!0.......^.........^.........^..
10 INPUT "Machine Code Address";
   x
20 LET a$=""
30 IF a$="" THEN INPUT a$
40 LET y=CODE a$-48: IF y>9 THEN
   LET y=y-7
50 LET z=CODE a$(2)-48: IF z>9
   THEN LET z=z-7
60 POKE x,16*y+z
70 LET x=x+1
80 LET a$=a$(3 TO)
90 GO TO 30
!1.......^.........^.........^.........^........
!B
(Note that in the book, if you have it, there is
a mistake on page 13 whereby line 60 should have
a plus sign instead of an equal sign.)
  The  program  above  asks first of all for  an
address  somewhere in RAM which you must  input.
Run  the program and input the number 28801.  In
hexadecimal this is the number 7081h. The reason
that  I  have  chosen this address is because  I
intend to use all of the addresses from 7000h to
7080h to store various bits and pieces of  data,
all  to  be explained in a moment. First  though
the  program.  Listed  below  is a machine  code
program.  All  you  need  to  do is type in  the
letters and numbers in the left-hand column. For
instance,  you start off by inputting  '3A87070'
and then '3C' and then 'E67F'. When you have got
through the entire listing you should press EDIT
(CAPS  SHIFT  and 1) to delete the quote  marks,
and  then STOP (SYMBOL SHIFT A) without  quotes,
and  then ENTER, and this will break out of  the
program.
  For those of you who understand machine  code,
I  have  also  included  in the middle column  a
listing of the machine code program itself,  and
in  the right-hand column some comments on  what
the   program  does.  If  you  don't  understand
machine code it doesn't really matter - all  you
need to do is type in the stuff in the left-hand
column  only. OK, here we go. Note that all  the
'0's are in fact zeros, and all the '1's are  in
fact ones.
  Now  we  have to fill up those areas of  data.
Erase the Basic program one line at a time  (not
by  typing  NEW)  and  now  enter  this  program
instead:
!0.......^.........^.........^..
10 FOR i=28672 TO 28800
20 POKE i,INT (9*RND)
30 NEXT i
!1.......^.........^.........^.........^........
This  serves  the  purpose  of storing a  random
number  between  zero and eight in each  address
from  7000h to 7080h. Now erase those lines  and
input this Basic program:
!0.......^.........^.........^..
10 FOR i=1 TO 200
20 RANDOMIZE USR 28801
30 NEXT i
40 FOR i=1 TO 100
50 RANDOMIZE USR 28826
60 NEXT i
70 GO TO 10
!1.......^.........^.........^.........^........
When you now run this program you should get  an
interesting effect. Line 20 actually scrolls the
screen  to  the  left,  and line 50 scrolls  the
screen  to  the  right. Both of these will  also
draw  in  a  new  left-  or  right-hand edge  as
required.  The data in addresses 7000h to  707Fh
store   the   heights   of  the  various  ground
features,  and  address 7080h is used to keep  a
record of whereabouts the screen is in  relation
to  the  horizon.  If you add two more lines  of
Basic:
!0.......^.........^.........^..
25 PRINT AT 10,10;" -+- "
55 PRINT AT 10,10;" -+- "
!1.......^.........^.........^.........^........
you will see that you have the start of a simple
game.  To  work  out in Basic the height of  the
ground  feature in column X of the screen  (with
the  leftmost  column being 0 and the  rightmost
being  31) I suggest you use the following  sub-
routine which returns the height as Y:
!0.......^.........^.........^..
2000 LET y=28672+PEEK 28800
2010 IF y>28799 THEN LET y=y-128
2020 LET y=PEEK(x+y)
2030 RETURN
!1.......^.........^.........^.........^........
And  to change the height of column X to  height
A:
!0.......^.........^.........^..
3000 LET y=28672+PEEK 28800
3010 IF y>28799 THEN LET y=y-128
3020 POKE x+y,a
3030 RETURN
!1.......^.........^.........^.........^........
Do  have fun. What you make out of this  routine
is  entirely  up to you but it should  certainly
keep you amused.

!2.......^.........^.........^.........^.........^.........^....
!B
Machine code       Assembler          Comments
---------.---------.------------------.-------------------------
3A8070   LEFT      LD   A,(POSITION)  A:=coordinate of left-hand
                                      edge of screen
3C                 INC  A           
E67F               AND  #7F         
328070             LD   (POSITION),A  Move screen R along data
F5                 PUSH AF          
210140             LD   HL,#4001      HL:=second byte on screen
110040             LD   DE,#4000      DE:=first byte on screen
01FF1A             LD   BC,#1AFF      BC:=# of bytes in screen
                                      less one
EDB0               LDIR               Scroll screen left
0E1F               LD   C,#1F         C:=coordinate of Rmost col
1815               JR   CONT
---------.---------.------------------.-------------------------
3A8070   RIGHT     LD   A,(POSITION)  A:=coordinate of left-hand
                                      edge of screen
3D                 DEC  A           
E67F               AND  #7F         
328070             LD   (POSITION),A  Move screen L along data
F5                 PUSH AF          
21FE5A             LD   HL,#5AFE      HL:=second to last byte on
                                      screen
11FF5A             LD   DE,#5AFF      DE:=last byte on screen
01FF1A             LD   BC,#1AFF      BC:=# of bytes in screen
                                      less one
EDB8               LDDR               Scroll screen right; C:=00
---------.---------.------------------.-------------------------
2640     CONT      LD   H,#40       
69                 LD   L,C           HL:=address of first row
                                      segment to erase
112000             LD   DE,#0020    
06C0               LD   B,#C0         B:=# of rows in screen
---------.---------.------------------.-------------------------
3600     ERASE     LD   (HL),#00      Erase next row segment
19                 ADD  HL,DE         Point to next row segment
                                      to erase
10FB               DJNZ ERASE         Repeat for all rows
0618               LD   B,#18         B:=# of lines in screen
3A8D5C             LD   A,(ATTR_P)    A:=attribute byte
---------.---------.------------------.-------------------------
77       NEW_ATTRS LD   (HL),A        Change next attribute byte
19                 ADD  HL,DE         Point to nxt attribute pos
10FC               DJNZ NEW_ATTRS     Repeat for all attributes
                                      in column
F1                 POP  AF            A:=coord of left of screen
81                 ADD  A,C         
E67F               AND  #7F           A:=coord of column erased
6F                 LD   L,A         
2670               LD   H,DATA high   HL:=to corresponding
                                      data byte
46                 LD   B,(HL)        B:=height of ground
3EE0               LD   A,#E0       
81                 ADD  A,C         
6F                 LD   L,A         
2657               LD   H,#57         Point HL to last row 
                                      segment in column
04                 INC  B           
05                 DEC  B           
C8                 RET  Z             Return if height = zero
11E007             LD   DE,#07E0    
---------.---------.------------------.-------------------------
3E08     GROUND_1  LD   A,#08         A:=number of row segments
                                      per square
---------.---------.------------------.-------------------------
36FF     GROUND_2  LD   (HL),#FF      Draw in ground
25                 DEC  H             HL:=to next row segment
3D                 DEC  A           
20FA               JR   NZ,GROUND_2   Draw whole square
19                 ADD  HL,DE         To bottom row segment
                                      of next square
10F5               DJNZ GROUND_1      Repeat for required number
                                      of squares
C9                 RET              
!1.......^.........^.........^.........^........

!B
--
from Your Spectrum #1 (Jan.1984)
--
!$
