!0.......^.........^.........^..

!B

\H11\H07      \H10\H04movin' \H10\H02& \H10\H04a'groovin'       



!2.......^.........^.........^.........^.........^.........^....

 Lights, action, music ... Our own top of the pops programmer,

  Andy Pennell, has brought to light a spectacular all-action

  program that'll knock your eyeballs for six. All you have to

                      supply is the music!

!1.......^.........^.........^.........^........



One million pounds - that's how much your  Spec-

trum  and  this  program  can  save you! No,  we

haven't   caught  Bingo  fever,  so  I'd  better

explain.  Have  you  ever  watched  the  graphic

effects on telly programmes like Top of the Pops

and wished you and your Speccy could match them?

Well,  now  you  can - well, almost - thanks  to

these  routines.  OK,  so they won't quite  turn

your  Spectrum  into a \H601,000,000 Quantel,  like

the  Beeb uses, but they'll certainly make  your

programs go with a swing.

  So, what's on offer that'll turn your programs

into chart-toppers? Well, all these routines put

on  picture  onto  the screen over another in  a

variety  of  spectacular ways. You can now  pan,

fade, zoom in, zoom out, corner zoom, horizontal

flip  and vertical flip. And if this all  sounds

like a sort of on-screen breakdance, right on!



!0.......^.........^.........^..

!B

!P\H11\H05\H10\H00\H13\H00

STAR TURNS                      

!1.......^.........^.........^.........^........

!P\H11\H05\H10\H00\H13\H00

Now  we've got to admit that these screen  shots

do  lack a certain something - movement  mostly!

So,  you'll  just have to take our word for  the

stunning visual effects that you can conjure  up

with these routines.



To  the  left  -  quick scroll. The new  picture

scrolls  in  from  the right to replace the  old

one. It's pantastic!



!Sscrollh



!1.......^.........^.........^.........^........

!P\H11\H05\H10\H00\H13\H00

Swoon  as  one picture fades away into  another.

You  can experiment with all different sorts  of

fades till you have the one that suits you.



!Sfade



!1.......^.........^.........^.........^........

!P\H11\H05\H10\H00\H13\H00

There are two zooms but only one picture, as you

wouldn't be able to tell the difference  between

them. Zoom Out zooms the new pic from the middle

of the old one and Zoom In reverses the process.



!Szoom



!1.......^.........^.........^.........^........

!P\H11\H05\H10\H00\H13\H00

Here the zoom service moves the new picture from

the top left corner over the old one.



!Szoomc



!1.......^.........^.........^.........^........

!P\H11\H05\H10\H00\H13\H00

And now you've finally flipped (vertically) and

turned the screen image on its head.



!Sflipv



!0.......^.........^.........^..



!B

\H11\H07\H10\H00THE BASIC LOADER                

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H07\H10\H00

For the brave, here is the Basic loader that POKEs the code into

place  and saves it onto Microdrive - change the syntax in  line

50 if you're using tape. For the not so brave, remember the com-

plete program is on this month's Dig'T'ape!

!3.......^.........^.........^.........^..



   1 CLEAR 59999

   5 RESTORE : LET z=0

  10 FOR i=60000 TO 60880

  20 READ a: LET z=z+a

  30 POKE i,a

  40 NEXT i

  45 IF z<>95823 THEN  PRINT "Data error":

 STOP

  50 SAVE *"m";1;"TP"CODE 60000,900

1000 DATA 1,176,234,24,40,1,166,234

1010 DATA 24,35,1,221,234,24,30,1

1020 DATA 26,235,24,25,1,244,235,24

1030 DATA 20,1,17,236,24,15,1,46

1040 DATA 236,24,10,195,23,237,0,0

1050 DATA 195,115,237,0,0,243,33,164

1060 DATA 234,229,197,42,11,92,35,126

1070 DATA 254,14,194,138,28,35,35,35

1080 DATA 94,35,86,201,251,201,235,17

1090 DATA 0,64,1,0,27,237,176,201

1100 DATA 33,0,64,24,245,14,31,33

1110 DATA 1,64,17,33,0,229,6,192

1120 DATA 126,43,119,25,16,250,225,229

1130 DATA 17,0,24,25,17,33,0,6

1140 DATA 32,126,43,119,25,16,250,225

1150 DATA 35,13,32,225,201,6,32,213

1160 DATA 221,225,197,205,181,234,221,229

1170 DATA 6,192,33,31,64,17,32,0

1180 DATA 221,126,0,119,25,221,25,16

1190 DATA 247,221,225,221,229,17,0,24

1200 DATA 221,25,33,31,88,17,32,0

1210 DATA 67,221,126,0,119,25,221,25

1220 DATA 16,247,221,225,221,35,193,16

1230 DATA 201,201,213,221,225,221,229,33

1240 DATA 0,64,1,0,24,17,7,0

1250 DATA 221,126,0,119,25,221,25,124

1260 DATA 254,88,56,8,38,64,221,124

1270 DATA 214,24,221,103,11,120,177,32

1280 DATA 231,225,17,0,24,25,17,0

1290 DATA 88,1,0,3,237,176,201,221

1300 DATA 94,0,221,86,1,221,70,4

1310 DATA 213,205,130,235,209,221,70,5

1320 DATA 205,164,235,221,94,2,221,86

1330 DATA 3,221,70,4,205,130,235,221

1340 DATA 126,0,221,86,1,221,134,4

1350 DATA 214,1,95,221,70,5,205,164

1360 DATA 235,201,14,8,213,197,213,42

1370 DATA 21,237,25,126,18,19,16,247

1380 DATA 209,193,20,13,32,239,209,205

1390 DATA 234,235,42,21,237,25,72,6

1400 DATA 0,237,176,201,72,120,167,40

1410 DATA 47,213,42,21,237,25,126,18

1420 DATA 205,217,235,16,245,209,221,229

1430 DATA 121,203,63,203,63,203,63,71

1440 DATA 205,234,235,42,21,237,25,213

1450 DATA 221,225,17,32,0,126,221,119

1460 DATA 0,25,221,25,16,247,221,225

1470 DATA 201,20,122,230,7,32,10,123

1480 DATA 198,32,95,63,159,230,248,130

1490 DATA 87,201,122,15,15,15,230,3

1500 DATA 246,88,87,201,235,17,0,64

1510 DATA 167,237,82,34,21,237,221,33

1520 DATA 181,236,6,16,197,205,79,235

1530 DATA 193,17,6,0,221,25,16,244

1540 DATA 201,235,17,0,64,167,237,82

1550 DATA 34,21,237,221,33,15,237,6

1560 DATA 16,197,205,79,235,193,17,250

1570 DATA 255,221,25,16,244,201,235,17

1580 DATA 0,64,167,237,82,34,21,237

1590 DATA 221,33,187,236,6,1,62,192

1600 DATA 221,150,5,203,63,198,8,79

1610 DATA 120,254,16,56,7,121,214,8

1620 DATA 221,134,5,79,197,17,0,64

1630 DATA 205,130,235,17,0,64,193,197

1640 DATA 65,205,164,235,193,197,120,254

1650 DATA 16,56,8,221,86,3,221,126

1660 DATA 2,24,6,221,86,1,221,126

1670 DATA 0,230,224,95,205,130,235,193

1680 DATA 197,221,126,0,230,31,95,120

1690 DATA 254,16,56,4,123,238,31,95

1700 DATA 22,64,65,205,164,235,193,17

1710 DATA 6,0,120,254,16,56,3,17

1720 DATA 250,255,221,25,4,120,254,32

1730 DATA 40,10,254,16,32,144,221,33

1740 DATA 15,237,24,138,201,0,64,224

1750 DATA 80,32,192,33,64,193,80,30

1760 DATA 176,66,64,162,80,28,160,67

1770 DATA 64,163,80,26,160,100,64,132

1780 DATA 80,24,144,133,64,101,80,22

1790 DATA 128,134,64,102,80,20,128,167

1800 DATA 64,71,80,18,112,200,64,40

1810 DATA 80,16,96,233,64,9,80,14

1820 DATA 80,10,72,234,72,12,64,11

1830 DATA 72,235,72,10,64,44,72,204

1840 DATA 72,8,48,77,72,173,72,6

1850 DATA 32,110,72,142,72,4,16,111

1860 DATA 72,143,72,2,16,0,0,33

1870 DATA 15,64,221,33,16,64,14,16

1880 DATA 229,221,229,17,32,0,6,192

1890 DATA 197,126,8,221,126,0,14,128

1900 DATA 23,203,25,48,251,113,8,14

1910 DATA 128,23,203,25,48,251,221,113

1920 DATA 0,25,221,25,16,227,193,221

1930 DATA 225,225,229,221,229,197,17,0

1940 DATA 24,25,221,25,17,32,0,6

1950 DATA 24,126,8,221,126,0,119,8

1960 DATA 221,119,0,25,221,25,16,241

1970 DATA 193,221,225,225,221,35,43,13

1980 DATA 32,174,201,221,33,128,72,33

1990 DATA 96,79,6,12,197,221,229,229

2000 DATA 14,8,221,229,229,6,32,126

2010 DATA 8,221,126,0,119,8,221,119

2020 DATA 0,35,221,35,16,241,225,221

2030 DATA 225,37,221,36,13,32,227,209

2040 DATA 193,197,213,205,234,235,98,107

2050 DATA 80,89,205,234,235,6,32,26

2060 DATA 8,126,18,8,119,35,19,16

2070 DATA 246,225,221,225,193,17,32,0

2080 DATA 221,125,254,224,32,3,17,32

2090 DATA 7,167,237,82,221,25,16,172

2100 DATA 201



!0.......^.........^.........^..

!B

!P\H11\H07\H10\H00

TOP OF THE POPS                 

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H07\H10\H00

Here  then are the routines that'll hype your Spectrum into  the

hippest hardware around. Let's begin by looking at how the Basic

functions  interact with the machine code. When a function  gets

called,  the  values of any parameters are stored in the DEF  FN

statement,  though you never actually see them in your  listing.

The following routines utilise this fact, along with the  system

variable  DEFADD  which points to the DEF FN statement, to  read

the integer parameter. But beware, it makes no checks to see  if

it's actually an integer, so if you pass it a string or a float-

ing point number it won't notice and may crash.

  After  the entry points, come the Load and Save routines  that

save  the  screen  image in memory and then load it from  memory

onto  the screen. They're really quite trivial, consisting of  a

quick LDIR to move the bytes.



!3.......^.........^.........^.........^..

;entry points

       LD   BC,SAVESC

       JR   START

       LD   BC,LOADSC

       JR   START

       LD   BC,ACROSS

       JR   START

       LD   BC,FADE

       JR   START

       LD   BC,ZOOMIN

       JR   START

       LD   BC,ZOOMOT

       JR   START

       LD   BC,TOPLZM

       JR   START

       JP   FLIPHO

       DEFB 0,0

       JP   FLIPVE

       DEFB 0,0

;general entry point

START  DI ;for speed

       LD   HL,ENDING

       PUSH HL

       PUSH BC ;the routine

;now get the parameter

       LD   HL,(23563) ;DEFADD

       INC  HL

       LD   A,(HL)

       CP   14 ;check +p marker

       JP   NZ,#1C8A

       INC  HL

       INC  HL

       INC  HL

       LD   E,(HL) ;read the integer

       INC  HL

       LD   D,(HL)

       RET

ENDING EI

       RET

;LOAD SCREEN from location DE

LOADSC EX   DE,HL

       LD   DE,#4000

MOVESC LD   BC,6912

       LDIR ;copy it all

       RET

;SAVE SCREEN to location DE

SAVESC LD   HL,#4000

       JR   MOVESC



!0.......^.........^.........^..

!B

!P\H11\H07\H10\H00

THE PAN                         

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H07\H10\H00

This  is a left to right horizontal scroll - SCRHOR scrolls  the

screen  one character square to the left as neatly as  possible.

Notice  that  I didn't say as fast as possible - for that  you'd

have to use LDIR but the disadvantage there is that the bit  map

moves  long before the attributes. They get visibly left  behind

during  the scroll and create one hell of an untidy mess on  the

screen.

  This  scroll  (and  all  the  other routines here) only  moves

sections  of  the  bit  map  at a time, closely followed by  the

attributes  'under'  the  section  of the bit map. That way  any

annoying  flicker is kept to the bare minimum. SCRHOR moves  the

screen column by column and so avoids the 'diagonal' effect  you

get  by  doing  it line by line. ACROSS is the main pan  routine

that  scrolls the screen 32 times - after each time, it draws  a

little bit more of the new screen on the right-hand column.



!3.......^.........^.........^.........^..

;horizontal scroll routine

SCRHOR LD   C,#1F ;columns

       LD   HL,#4001

       LD   DE,33

HORIZ  PUSH HL ;save top address

       LD   B,192

HORIZL LD   A,(HL)

       DEC  HL

       LD   (HL),A ;scroll it

       ADD  HL,DE ;next line

       DJNZ HORIZL

;now do the attrs

       POP  HL

       PUSH HL

       LD   DE,#1800

       ADD  HL,DE

       LD   DE,33

       LD   B,32

HATTR  LD   A,(HL)

       DEC  HL

       LD   (HL),A

       ADD  HL,DE

       DJNZ HATTR ;move a column

       POP  HL

       INC  HL ;next column

       DEC  C

       JR   NZ,HORIZ ;do all columns

       RET



;the horizontal scroll/mix routine

ACROSS LD   B,32 ;scrolls read

       PUSH DE

       POP  IX ;the other screen

ACLP   PUSH BC

       CALL SCRHOR ;scroll it

       PUSH IX

;now put the next bit of the other

;screen on RHS

       LD   B,192

       LD   HL,#4000+31 ;RHS

       LD   DE,32

HCOPY  LD   A,(IX+#00)

       LD   (HL),A ;copy it

       ADD  HL,DE

       ADD  IX,DE ;inc both

       DJNZ HCOPY ;do whole col

       POP  IX

;now copy attrs

       PUSH IX

       LD   DE,#1800

       ADD  IX,DE ;others attrs

       LD   HL,#5800+31

       LD   DE,32

       LD   B,E ;=32

HCPAT  LD   A,(IX+#00)

       LD   (HL),A

       ADD  HL,DE

       ADD  IX,DE

       DJNZ #EB09

       POP  IX

       INC  IX

       POP  BC

       DJNZ ACLP ;do all pict

       RET



!0.......^.........^.........^..

!B

!P\H11\H07\H10\H00

THE FADE                        

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H07\H10\H00

FADE  puts a piccy onto the screen by copying every seven  bytes

and wrapping around when it gets to the end of the screen. Seven

is the "fade factor" which I came up with after trial and error.

You're welcome to try other fade factors just so long as they're

odd numbers less than 256. That way you can pick your favourite,

but  be  warned,  some  look very boring. If you end up with  7,

don't say I didn't tell you!



!3.......^.........^.........^.........^..

;FADE one screen into another

FADE   PUSH DE

       POP  IX

       PUSH IX

       LD   HL,#4000

       LD   BC,6144

       LD   DE,7 ;fade factor

FADELP LD   A,(IX+#00)

       LD   (HL),A ;copy to screen

       ADD  HL,DE

       ADD  IX,DE ;next one

       LD   A,H

       CP   #58

       JR   C,ONS2

;gone past end of screen so wrap around

       LD   H,#40

       DEFB #DD

       LD   A,H

       SUB  #18

       DEFB #DD

       LD   H,A

ONS2   DEC  BC

       LD   A,B

       OR   C

       JR   NZ,FADELP ;do all the screen

;pic map done so copy attrs onto display

       POP  HL

       LD   DE,#1800

       ADD  HL,DE

       LD   DE,#5800

       LD   BC,768

       LDIR ;copy them

       RET



!0.......^.........^.........^..

!B

!P\H11\H07\H10\H00

THE ZOOMS                       

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H07\H10\H00

Like  all these routines, the zoom is an optical illusion.  ZOOM

takes  the data stored at IX in order to draw a box from one  of

your pictures onto the screen. It's used in both the zoom in and

zoom  out  routines,  where you'll see that the box it makes  is

formed  from a horizontal block for the top and bottom, and  two

vertical  blocks for the left and right. DOHORIZ and DOVERT  are

the  general  subroutines  that  draw  blocks from a picture  in

memory onto the screen. The subroutine DEDOWN alters DE so  that

it  points to the pixel directly below it on the screen.  DEATTR

converts DE from the bit map into the location of the  attribute

'under' it.



!3.......^.........^.........^.........^..

;DRAW BOX IX

ZOOM   LD   E,(IX+#00)

       LD   D,(IX+#01) ;start of top left

       LD   B,(IX+#04) ;width

       PUSH DE

       CALL DOHORI ;do the top

       POP  DE

       LD   B,(IX+#05) ;depth

       CALL DOVERT ;do the left

       LD   E,(IX+#02)

       LD   D,(IX+#03) ;start of bottom left

       LD   B,(IX+#04) ;width

       CALL DOHORI ;do bottom

       LD   A,(IX+#00)

       LD   D,(IX+#01)

       ADD  A,(IX+#04)

       SUB  #01

       LD   E,A ;DE=start address of RHS

       LD   B,(IX+#05)

       CALL DOVERT ;do right

       RET



;do a horizontal box

;with starting address

;in DE, width in B

DOHORI LD   C,#08 ;pixels high

       PUSH DE ;save address

HBOX   PUSH BC

       PUSH DE

HBOXLP LD   HL,(DISP)

       ADD  HL,DE

       LD   A,(HL)

       LD   (DE),A ;copy

       INC  DE ;go along

       DJNZ HBOXLP ;do a line

       POP  DE

       POP  BC

       INC  D ;DE down a line

       DEC  C

       JR   NZ,HBOX ;do 8 lines

;colour

       POP  DE

       CALL DEATTR

       LD   HL,(DISP)

       ADD  HL,DE

       LD   C,B

       LD   B,#00

       LDIR ;copy attrs to screen

       RET

;do a vertical box

;top at DE, B deep

DOVERT LD   C,B ;save for later

       LD   A,B

       AND  A

       JR   Z,NOVERT ;if no box required

       PUSH DE

DOVELP LD   HL,(DISP)

       ADD  HL,DE

       LD   A,(HL)

       LD   (DE),A ;copy to screen

       CALL DEDOWN ;next pixel down

       DJNZ DOVELP ;do the whole depth

;now do the colour

       POP  DE

       PUSH IX ;save it

       LD   A,C

       SRL  A

       SRL  A

       SRL  A

       LD   B,A ;height in chars

       CALL DEATTR

       LD   HL,(DISP)

       ADD  HL,DE

       PUSH DE

       POP  IX

       LD   DE,32

VBATTR LD   A,(HL)

       LD   (IX+#00),A ;copy vertical column

       ADD  HL,DE ;of attrs

       ADD  IX,DE

       DJNZ VBATTR

       POP  IX

NOVERT RET



;alter DE to pixel directly below

DEDOWN INC  D

       LD   A,D

       AND  #07

       JR   NZ,EASY

       LD   A,E ;straddles a 1/3 boundary

       ADD  A,32

       LD   E,A

       CCF

       SBC  A,A

       AND  #F8

       ADD  A,D

       LD   D,A

EASY   RET

;convert DE from bit map into attr file

DEATTR LD   A,D

       RRCA

       RRCA

       RRCA

       AND  #03

       OR   #58

       LD   D,A

       RET



!2.......^.........^.........^.........^.........^.........^....

!B

!P\H11\H07\H10\H00

ZOOMIN  and  ZOOMOT are the main zoom entry points that use  the

box  data  table and the ZOOM subroutine, though obviously in  a

different order to create their opposing effects.



!3.......^.........^.........^.........^..

;ZOOM IN

ZOOMIN EX   DE,HL

       LD   DE,#4000

       AND  A

       SBC  HL,DE

       LD   (DISP),HL ;screen difference

       LD   IX,ZDATA

       LD   B,16 ;no of boxes

ZINLP  PUSH BC

       CALL ZOOM ;do the box

       POP  BC

       LD   DE,6

       ADD  IX,DE

       DJNZ ZINLP

       RET

;ZOOM OUT

ZOOMOT EX   DE,HL

       LD   DE,#4000

       AND  A

       SBC  HL,DE

       LD   (DISP),HL

       LD   IX,ZDATEN

       LD   B,16

ZOUTLP PUSH BC

       CALL ZOOM

       POP  BC

       LD   DE,-6 ;go outwards

       ADD  IX,DE

       DJNZ ZOUTLP

       RET



!2.......^.........^.........^.........^.........^.........^....

!B

!P\H11\H07\H10\H00

TOPLZM  is the routine for a corner zoom from the top left.  I'd

intended to do zooms from the other three corners but found them

much  tougher than I'd bargained for. So, now it's up to you  to

come up with the goods!



!3.......^.........^.........^.........^..

;ZOOM FROM TOP LEFT

TOPLZM EX   DE,HL

       LD   DE,#4000

       AND  A

       SBC  HL,DE

       LD   (DISP),HL

       LD   IX,ZDATA+6

       LD   B,1

TOPLP  LD   A,192

       SUB  (IX+#05)

       SRL  A

       ADD  A,#08

       LD   C,A ;=x coord reflected

       LD   A,B

       CP   16

       JR   C,TOPZM

       LD   A,C

       SUB  #08

       ADD  A,(IX+#05) ;handle lower 1/2

       LD   C,A

TOPZM  PUSH BC

       LD   DE,#4000

       CALL DOHORI ;top box

       LD   DE,#4000

       POP  BC

       PUSH BC

       LD   B,C

       CALL DOVERT ;left box

       POP  BC

       PUSH BC

       LD   A,B

       CP   16

       JR   C,TOPZM2

       LD   D,(IX+#03) ;for lower half

       LD   A,(IX+#02)

       JR   TOPZM3

TOPZM2 LD   D,(IX+#01) ;for upper half

       LD   A,(IX+#00)

TOPZM3 AND  #E0 ;make it the very left

       LD   E,A

       CALL DOHORI ;do the bottom

       POP  BC

       PUSH BC

       LD   A,(IX+#00)

       AND  #1F

       LD   E,A ;x coord only

       LD   A,B

       CP   16

       JR   C,TOPPZM4

       LD   A,E

       XOR  #1F ;reflect lower half x pos

       LD   E,A

TOPZM4 LD   D,#40 ;top line of screen

       LD   B,C

       CALL DOVERT ;right

       POP  BC

       LD   DE,6

       LD   A,B

       CP   16

       JR   C,TOPZM5

       LD   DE,-6

TOPZM5 ADD  IX,DE ;go backwards or forwards

       INC  B

       LD   A,B

       CP   32

       JR   Z,QUITTZ

       CP   16

       JR   NZ,TOPLP

;now do the lower screen

       LD   IX,ZDATEN

       JR   TOPLP

QUITTZ RET



!2.......^.........^.........^.........^.........^.........^....

!B

!P\H11\H07\H10\H00

The ZDATA table is for the series of boxes that make up a  zoom.

I worked it out on squared paper. It's also used, though differ-

ently, in the TOPLZM routine.



!3.......^.........^.........^.........^..

;data for zoom boxes in the form

;top, left, bottom, right,

;width (chars), depth (pixels)

ZDATA  DEFW #4000,#50E0

       DEFB 32,192

       DEFW #4021,#50C1

       DEFB 30,176

       DEFW #4042,#50A2

       DEFB 28,160

       DEFW #4043,#50A3

       DEFB 26,160

       DEFW #4064,#5084

       DEFB 24,144

       DEFW #4085,#5065

       DEFB 22,128

       DEFW #4086,#5066

       DEFB 20,128

       DEFW #40A7,#5047

       DEFB 18,112

       DEFW #40C8,#5028

       DEFB 16,96

       DEFW #40E9,#5009

       DEFB 14,80

       DEFW #480A,#48EA

       DEFB 12,64

       DEFW #480B,#48EB

       DEFB 10,64

       DEFW #482C,#48CC

       DEFB 8,48

       DEFW #484D,#48AD

       DEFB 6,32

       DEFW #486E,#488E

       DEFB 4,16

ZDATEN DEFW #486F,#488F

       DEFB 2,16

DISP   DEFW #0000



!2.......^.........^.........^.........^.........^.........^....

!B

!P\H11\H07\H10\H00

The  horizontal flip is noticeably slower than the vertical  one

because it has to turn all the bits around for each byte.



!3.......^.........^.........^.........^..

;flip screen horizontal

FLIPHO LD   HL,#400F ;LHS

       LD   IX,#4010 ;RHS

       LD   C,16 ;width/2

FLIPH  PUSH HL

       PUSH IX

       LD   DE,32

       LD   B,192

       PUSH BC ;save C

FLIPH2 LD   A,(HL)

       EX   AF,AF'

       LD   A,(IX+#00)

       LD   C,128

SWITCH RLA

       RR   C

       JR   NC,SWITCH ;turn around

       LD   (HL),C

       EX   AF,AF'

       LD   C,128

SWIT2  RLA

       RR   C

       JR   NC,SWIT2 ;turn around

       LD   (IX+#00),C ;swap them over

       ADD  HL,DE

       ADD  IX,DE

       DJNZ FLIPH2 ;swap a column

;now do colour

       POP  BC

       POP  IX

       POP  HL

       PUSH HL

       PUSH IX

       PUSH BC

       LD   DE,#1800

       ADD  HL,DE

       ADD  IX,DE

       LD   DE,32

       LD   B,24

FLATTR LD   A,(HL)

       EX   AF,AF'

       LD   A,(IX+#00)

       LD   (HL),A

       EX   AF,AF'

       LD   (IX+#00),A ;swap attrs

       ADD  HL,DE

       ADD  IX,DE

       DJNZ FLATTR ;do a column

       POP  BC

       POP  IX

       POP  HL

       INC  IX ;more right

       DEC  HL ;move left

       DEC  C

       JR   NZ,FLIPH ;do all the columns

       RET

;FLIP VERTICAL

FLIPVE LD   IX,#4880

       LD   HL,#4F60

       LD   B,12

FVERT  PUSH BC

       PUSH IX

       PUSH HL

       LD   C,#08

;swap two rows

SWVER2 PUSH IX

       PUSH HL

       LD   B,32

SWVERT LD   A,(HL)

       EX   AF,AF'

       LD   A,(IX+#00)

       LD   (HL),A

       EX   AF,AF'

       LD   (IX+#00),A ;swap them

       INC  HL

       INC  IX

       DJNZ SWVERT ;swap a pixel line

       POP  HL

       POP  IX

       DEC  H ;up a pixel

       DEFB #DD

       INC  H ;down a pixel

       DEC  C

       JR   NZ,SWVER2 ;swap two rows

;colour now

       POP  DE ;HL

       POP  BC ;IX

       PUSH BC

       PUSH DE

       CALL DEATTR

       LD   H,D

       LD   L,E ;HL=one line

       LD   D,B

       LD   E,C

       CALL DEATTR ;DE=other

       LD   B,32

SVATTR LD   A,(DE)

       EX   AF,AF'

       LD   A,(HL)

       LD   (DE),A

       EX   AF,AF'

       LD   (HL),A ;swap attrs

       INC  HL

       INC  DE

       DJNZ SVATTR ;do the whole row

       POP  HL

       POP  IX

       POP  BC

;now make HL go up, IX down

       LD   DE,32

       DEFB #DD

       LD   A,L

       CP   #E0

       JR   NZ,EASYUP

       LD   DE,#0720 ;if over a boundary

EASYUP AND  A

       SBC  HL,DE ;up

       ADD  IX,DE ;down

       DJNZ FVERT ;do 12x2 lines

       RET

       END

!0.......^.........^.........^..



!B

\H11\H06\H10\H02SHOWIN' OFF                     

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Just  to get you going, here's a simple demo program. As all  of

the  routines, except the flips, need to be told the address  of

the  picture  to  be put onto the screen, they use User  Defined

functions in an unusual way - there are no POKEs or anything  to

use them. So, you'll have to use the following lines of Basic:

!0.......^.........^.........^..

!P\H11\H06\H10\H00

                                

Save Screen      RAND FN S(x)   

Load Screen      RAND FN L(x)   

Horizontal Pan   RAND FN H(x)   

Fade             RAND FN F(x)   

Zoom In          RAND FN I(x)   

Zoom Out         RAND FN O(x)   

Corner Zoom      RAND FN T(x)   

Flip Horizontal  RAND USR fh    

Flip Vertical    RAND USR fv    

                                

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

The  'x'  in  the  lines should be the address in memory of  the

screen  you  want  displayed  -  or in the case of FN L(x),  the

address where you want the screen saved.

  The  demo  program  loads  two pictures called S1 and S2  into

memory - you can change these to suit your favourite screens and

of  course,  remember  to change the syntax if you're not  using

microdrives. First, start the program with RUN 9999. After this,

a  RUN  will  do and after that a GO TO 1010 is all you need  to

warm  start  it. For the sake of simplicity, I've only used  two

screens  in  this  demo.  But just think what you could do  with

Chris Wood's Screen Scrunger from YS 13. That way you'd fit many

more  screens  into  memory  and get a really tremendous  moving

graphic display. A million quid! Who needs it?

!3.......^.........^.........^.........^..



!B

   1 CLEAR 38999

  10 DEF FN s(a)=USR 60000

  20 DEF FN l(a)=USR 60005

  30 DEF FN h(a)=USR 60010

  40 DEF FN f(a)=USR 60015

  50 DEF FN i(a)=USR 60020

  60 DEF FN o(a)=USR 60025

  70 DEF FN t(a)=USR 60030

  80 LET fh=60035

  90 LET fv=60040

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1-90       This is the basic set-up routine - you'll need

                 to put these lines at the start of all your own

                 programs.

!3.......^.........^.........^.........^..



1000 LET s1=46000: LET s2=53000: LET s3=39

000

1005 LOAD *"m";1;"S1"CODE s1

1006 LOAD *"m";1;"S2"CODE s2

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1000-1006  These lines initialise the start of the screen

                 addresses and load in the pictures from Micro-

                 drive (if you haven't got drives, replace lines

                 1005-1006 with the normal cassette loading

                 syntax).

!3.......^.........^.........^.........^..



1010 RANDOMIZE FN l(s1)

1020 LET a$="PANNING": GO SUB 8000

1030 RANDOMIZE FN h(s2)

1040 GO SUB 8000: RANDOMIZE FN h(s1)

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1010-1040  Panning. This routine simply performs a screen

                 trick, panning in this case, and then scrolls a

                 couple of times before moving onto the next

                 example.

!3.......^.........^.........^.........^..



1090 FOR i=1 TO 2

1100 LET a$="ZOOM OUT": GO SUB 8000

1110 RANDOMIZE FN o(s2)

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1090-1110  Zoom Out.

!3.......^.........^.........^.........^..



1120 LET a$="ZOOM IN": GO SUB 8000

1130 RANDOMIZE FN i(s1)

1140 NEXT i

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1120-1140  Zoom In.

!3.......^.........^.........^.........^..



1200 LET a$="CORNER ZOOM": GO SUB 8000

1210 RANDOMIZE FN t(s2)

1220 GO SUB 8000

1230 RANDOMIZE FN t(s1)

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1200-1230  Corner Zoom.

!3.......^.........^.........^.........^..



1300 LET a$="FADING": GO SUB 8000

1310 RANDOMIZE FN f(s2)

1320 GO SUB 8000

1330 RANDOMIZE FN f(s1)

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1300-1330  Fading.

!3.......^.........^.........^.........^..



1400 LET a$="FLIP HORIZONTAL": GO SUB 8000

1410 RANDOMIZE USR fh

1420 PAUSE 0

1430 RANDOMIZE USR fh

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1400-1430  Flip Horizontal.

!3.......^.........^.........^.........^..



1500 LET a$="FLIP VERTICAL": GO SUB 8000

1510 RANDOMIZE USR fv

1520 PAUSE 0

1530 RANDOMIZE USR fv

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1500-1530  Flip Vertical.

!3.......^.........^.........^.........^..



1600 LET a$="AND ALL OF THEM": GO SUB 8000

1610 LET d=25

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 1600-1610  Start of the demonstration loop.

!3.......^.........^.........^.........^..



2000 RANDOMIZE FN o(s1): PAUSE 0: RANDOMIZ

E FN i(s2): PAUSE 0

2010 RANDOMIZE USR fh: RANDOMIZE FN s(s3)

2020 RANDOMIZE USR fv: PAUSE 0: RANDOMIZE 

USR fv: PAUSE 0

2030 RANDOMIZE FN f(s1): PAUSE 0: RANDOMIZ

E FN f(s2): PAUSE 0: RANDOMIZE FN f(s1): P

AUSE 0

2040 RANDOMIZE USR fv: PAUSE 0

2050 RANDOMIZE FN h(s2): PAUSE 0

2060 RANDOMIZE USR fh: RANDOMIZE FN h(s2):

 PAUSE 0

2070 RANDOMIZE FN o(s3): PAUSE 0

2080 RANDOMIZE FN o(s2): PAUSE 0

2090 RANDOMIZE FN o(s3): PAUSE 0

2100 GO TO 2000

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 2000-2100  Demonstration loop.

!3.......^.........^.........^.........^..



8000 PRINT #0;AT 1,(32-LEN a$)/2;" ";a$;" 

";

8010 PAUSE 0: RETURN

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Lines 8000-8010  This is a short subroutine that prints the 

                 title on each screen.

!3.......^.........^.........^.........^..



9999 CLEAR 59999: LOAD *"m";1;"TP"CODE :

RUN

!2.......^.........^.........^.........^.........^.........^....

!P\H11\H06\H10\H00

Line 9999        Clears space in memory and loads in the Top of

                 the Pops routine. Use this line in all your

                 programs.

!1.......^.........^.........^.........^........



!B

--

from Your Spectrum #19 (Oct.1985)

--

!$

