!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) -- !$