Автор: Simon Lane
Год: 1984
Издатели: Your Spectrum
Языки:
Английский
Формат:
TAP лента
Требования:
ZX Spectrum 48K
Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing
Скриншоты:
Год: 1984
Издатели: Your Spectrum
Языки:
Формат:
Требования:
Ссылки:
Скриншоты:
!0.......^.........^.........^..
!B
\H11\H07\H10\H02 B A N G
\H11\H07\H10\H00 GOES YOUR CODE
!2.......^.........^.........^.........^.........^.........^....
Has the razzle-dazzle gone out of your programs? Simon Lane's
got some explosive ideas to stun you ...
!1.......^.........^.........^.........^........
Have you ever had that feeling of anti-climax
when, having successfully obliterated an alien
(or whatever) in some otherwise superbly written
Basic program, it simply disappears into thin
air without any kind of graphic reward? Well,
now you'll be able to remedy this omission by
simply calling one of these interrupt-driven
machine code explosion routines at the approp-
riate point in your program. Just read the
instructions, type in the object code, and off
you go.
The assembly language listings have been
produced using the Hisoft GENS assembler, which
uses a '#' symbol to denote Hex numbers. If you
have an assembler you can type in the source
code and assemble it yourself. This will allow
you the added joy of making your own alterations
to the programs - certainly, it's a lot less
boring than entering the object code straight.
However, without an assembler this is exactly
what you will have to do - using either a suit-
able monitor program, or the short Hex loader
provided as a last resort.
To use the Hex loader, first you'll have to
enter the start address (in decimal) as given in
the instructions for each routine; that has to
be followed by all the Hex object code given in
column two of the assembler listing. For
example, to enter
!0.......^.........^.........^..
!B
10 REM ***********************
20 REM HEX LOADER
30 REM ***********************
40 DEF FN d(h$)=CODE h$-48-(32
AND h$>="a")-(7 AND h$>="A")
50 INPUT "Start address:";l
60 INPUT (l);">";h$
70 POKE l,FN d(h$(1))*16+FN d(
h$(2))
80 LET l=l+1: LET h$=h$(3 TO )
90 IF h$>"" THEN GO TO 70
100 GO TO 60
!2.......^.........^.........^.........^.........^.........^....
Those without an assembler can use the above program to type in
the Hex code.
!1.......^.........^.........^.........^........
the Missile Command routine, you would type
65023 (Enter), 16FE (Enter), AF (Enter), 32D2FE
... 00FF (Enter). Once that's out of the way,
you can break out of the program by deleting one
of the quotes and typing STOP.
!0.......^.........^.........^..
!B
MISSILE COMMAND
EXPLOSION (MCEXP)
!1.......^.........^.........^.........^........
Anyone who's ever been in an amusement arcade
must surely have come across the Missile Command
game at some time or other. There the explosions
are displayed as circles which get larger and
larger and then shrink away to nothing; my first
routine is an attempt to simulate this effect.
The object code should be entered into memory
starting at 65023 (FDFF Hex) and, just as a
check, the first address at which no object code
should be entered (that is, the address at which
you STOP the Hex loader) should be 65256 (FEEB
Hex).
The routine works by drawing a series of octa-
gons on the screen, starting at the coordinates
stored in XPOS and YPOS (see below). When a
'radius' equal to the contents of LIMIT is
reached, the octagons are 'undrawn', but this
time in reverse order. This gives an effect very
similar to a circle growing and then
!0.......^.........^.........^..
10 REM ***********************
20 REM MCEXP DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET xpos=65236
80 LET ypos=65237
90 LET limit=65238
100 LET speed=65239
110 LET done=65240
120 REM
130 REM INITIALISE MCEXP
140 REM
150 POKE xpos,128
160 POKE ypos,88
170 POKE limit,87
180 POKE speed,1
190 REM
200 REM CALL MCEXP
210 REM
220 RANDOMIZE USR 65025
230 REM
240 REM FLASH BORDER UNTIL END
250 REM
260 BORDER RND*7
270 IF PEEK done THEN STOP
280 GO TO 260
!2.......^.........^.........^.........^.........^.........^....
The Missile Command demo: produces an explosion at the centre of
the screen.
!1.......^.........^.........^.........^........
!B
shrinking away - without the problems associated
with drawing circles (slowness and/or large
look-up tables). Note that when the octagons are
drawn on the screen, XOR plotting is used. This
gives the same effect as using PLOT OVER 1 from
Basic.
Once you've typed in the object code it's
advisable to save it immediately, just in case
you inadvertently manage to crash the program.
Enter SAVE "mcexp" CODE 65023,233 to save to
tape, and SAVE *"m";1;"mcexp" CODE 65023,233 to
save to Microdrive cartridge. Then, type in and
run the MCEXP DEMO program; if everything is as
it should be, and explosion should be produced
that starts at the centre of the screen and then
fills it.
To use the routine in your own programs, you
just have to POKE the locations below with the
appropriate values and then use the command
RANDOMIZE USR 65025. The variables used in the
program are as follows:
!0.......^.........^.........^..
XPOS: 65236 (FED4 Hex)
YPOS: 65237 (FED5 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the x and y coord-
inates of the point where the centre of the
explosion is required.
!0.......^.........^.........^..
LIMIT: 65238 (FED6 Hex)
!1.......^.........^.........^.........^........
The radius of the required explosion. Note XPOS
- LIMIT 0, XPOS + LIMIT 255, YPOS - LIMIT 0,
YPOS + LIMIT 175,
!0.......^.........^.........^..
SPEED: 65239 (FED7 Hex)
!1.......^.........^.........^.........^........
The speed of the explosion. Note that one is
fast, 255 is slow. Total time of explosion =
(LIMIT * SPEED + 1)/25 seconds (approx). Large
explosions take considerably longer.
!0.......^.........^.........^..
DONE: 65240 (FED8 Hex)
!1.......^.........^.........^.........^........
This location can be PEEKed to determine whether
or not the explosion has been completed (since
the routine is interrupt-driven, the Basic
program continues to run while the machine code
is executed). A zero indicates that the explos-
ion is still taking place and a one indicates
that it has finished. Note that commands of the
form "IF PEEK done ..." can therefore be used in
your programs.
It's advisable to assign the values above to
Basic variables at the start of your program.
This approach is used in each of the demon-
stration programs.
!2.......^.........^.........^.........^.........^.........^....
!B
FDFF ORG #FDFF
FDFF 16FE DEFW MCEXP
;Initialise variables and interrupts
FE01 AF GO XOR A
FE02 32D8FE LD (DONE),A
FE05 32DAFE LD (SIZE),A
FE08 32DFFE LD (INOUT),A
FE0B 3C INC A
FE0C 32D9FE LD (COUNT),A
FE0F 3EFD LD A,#FD ;This makes Z80 jump to the sub-
FE11 ED47 LD I,A ;routine whose address is stored
FE13 ED5E IM 2 ;at FDFF on each interrupt
FE15 C9 RET
;This code is executed every 0.02 secs
FE16 C5 MCEXP PUSH BC
FE17 D5 PUSH DE
FE18 E5 PUSH HL
FE19 F5 PUSH AF
FE1A DDE5 PUSH IX
;Draw an octagon every (SPEED)/50 secs
FE1C 21D9FE LD HL,COUNT
FE1F 35 DEC (HL)
FE20 C2A4FE JP NZ,RET
FE23 3AD7FE LD A,(SPEED)
FE26 77 LD (HL),A
FE27 2AD4FE LD HL,(XPOS)
FE2A 3ADAFE LD A,(SIZE)
FE2D A7 AND A
FE2E 2005 JR NZ,NOT0
;If (SIZE)=0 then plot a single point ...
FE30 CDADFE CALL PLOT
FE33 1848 JR ENDPLT
;otherwise draw an octagon of the appropriate size
FE35 5F NOT0 LD E,A
FE36 57 LD D,A
FE37 CB3A SRL D
FE39 19 ADD HL,DE
FE3A 1100FF LD DE,#FF00 ;Down
FE3D DD21E0FE LD IX,DIRTAB
FE41 0E04 LD C,#04
FE43 FE01 MLOOP CP #01
FE45 2809 JR Z,NOGO
FE47 47 LD B,A
FE48 CB80 RES 0,B
;Draw straight line
FE4A 19 STRT ADD HL,DE
FE4B CDADFE CALL PLOT
FE4E 10FA DJNZ STRT
FE50 47 NOGO LD B,A
FE51 04 INC B
FE52 CB38 SRL B
FE54 ED53DBFE LD (DE1),DE
FE58 DD5E00 LD E,(IX+#00)
FE5B DD5601 LD D,(IX+#01)
FE5E ED53DDFE LD (DE2),DE
;Draw diagonal line
FE62 19 DIAG ADD HL,DE
FE63 CB47 BIT 0,A
FE65 CCADFE CALL Z,PLOT
FE68 ED5BDBFE LD DE,(DE1)
FE6C 19 ADD HL,DE
FE6D CDADFE CALL PLOT
FE70 ED5BDDFE LD DE,(DE2)
FE74 10EC DJNZ DIAG
FE76 DD23 INC IX ;Point to next
FE78 DD23 INC IX ;entry in DIRTAB
FE7A 0D DEC C
FE7B 20C6 JR NZ,MLOOP
FE7D 3ADFFE MLOOP LD A,(INOUT)
FE80 A7 AND A
FE81 21DAFE LD HL,SIZE
FE84 2010 JR NZ,IN
FE86 3AD6FE LD A,(LIMIT)
FE89 BE CP (HL)
FE8A 2803 JR Z,CHANGE
FE8C 34 INC (HL) ;Grow
FE8D 1815 JR RET
;Change from growing to shrinking
FE8F 3E01 CHANGE LD A,#01
FE91 32DFFE LD (INOUT),A
FE94 180E JR RET
FE96 3D IN DEC A
FE97 BE CP (HL)
FE98 2009 JR NZ,INOK
;Explosion complete
FE9A 3E01 LD A,#01
FE9C 32D8FE LD (DONE),A
FE9F ED56 IM 1
FEA1 1801 JR RET
FEA3 35 INOK DEC (HL) ;Shrink
;Restore registers & jump to ROM interrupt routine
FEA4 DDE1 RET POP IX
FEA6 F1 POP AF
FEA7 E1 POP HL
FEA8 D1 POP DE
FEA9 C1 POP BC
FEAA C33800 JP #0038
;Invert point if growing, unplot if shrinking
FEAD E5 PLOT PUSH HL
FEAE F5 PUSH AF
FEAF 3ADFFE LD A,(INOUT)
FEB2 A7 AND A
FEB3 2008 JR NZ,UNPLOT
;Invert point
FEB5 CDC5FE PLOTX CALL PIXAD
FEB8 2F CPL
FEB9 AE XOR (HL)
FEBA 77 LD (HL),A
FEBB 1805 JR PLTRET
;Unplot point
FEBD CDC5FE UNPLOT CALL PIXAD
FEC0 A6 AND (HL)
FEC1 77 LD (HL),A
FEC2 F1 PLTRET POP AF
FEC3 E1 POP HL
FEC4 C9 RET
;Convert x,y coords into d.file address & bit map
FEC5 C5 PIXAD PUSH BC
FEC6 44 LD B,H
FEC7 4D LD C,L
FEC8 CDAA22 CALL #22AA
FECB 47 LD B,A
FECC 04 INC B
FECD 3EFE LD A,#FE
FECF 0F PIXEL RRCA
FED0 10FD DJNZ PIXEL
FED2 C1 POP BC
FED3 C9 RET
;Variables
FED4 64 XPOS DEFB 100 ;X,Y coordinates of centre
FED5 64 YPOS DEFB 100 ;of explosion on screen
FED6 0A LIMIT DEFB 10 ;Max. radius of explosion
FED7 05 SPEED DEFB 5 ;Speed of explosion
FED8 00 DONE DEFB 0 ;Flag to indicate end of explosion
FED9 00 COUNT DEFB 0 ;Interrupts before next octagon
FEDA 00 SIZE DEFB 0 ;Current radius of explosion
FEDB 0000 DE1 DEFW 0 ;Horizontal and vertical
FEDD 0000 DE2 DEFW 0 ;components of diagonal
FEDF 00 INOUT DEFB 0 ;0=growing; 1=shrinking
;Table of directions
FEE0 FFFF DIRTAB DEFW #FFFF ;Left
FEE2 0001 DEFW #0100 ;Up
FEE4 0100 DEFW #0001 ;Right
FEE6 000F DEFW #FF00 ;Down
!0.......^.........^.........^..
!B
DOT FADE EXPLOSION (FADE)
!1.......^.........^.........^.........^........
Technically this isn't really an explosion at
all. What happens here is that the object to be
"de-materialised" fades away dot-by-dot. The
start address for the object code is 64767 (FCFF
Hex), and the first unused address should be
64922 (FD9A Hex). When you've entered the code,
save using SAVE "fade" CODE 64767,155 or SAVE
!0.......^.........^.........^..
10 REM ***********************
20 REM FADE DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET dpos=64914
80 LET apos=64915
90 LET dlim=64916
100 LET alim=64917
110 LET speed=64918
120 LET done=64919
130 REM
140 REM FILL SCREEN
150 REM
160 FOR i=1 TO 704
170 PRINT CHR$ (RND*95+32);
180 NEXT i
190 REM
200 REM INITIALISE FADE
210 REM
220 POKE dpos,0
230 POKE apos,0
240 POKE dlim,22
250 POKE alim,32
260 POKE speed,10
270 REM
280 REM CALL FADE
290 REM
300 RANDOMIZE USR 64769
310 REM
320 REM WAIT UNTIL END
330 REM
340 IF PEEK done THEN STOP
350 GO TO 340
!2.......^.........^.........^.........^.........^.........^....
The Dot Fade demo: fills an area of the screen with random
characters and erases them pixel-by-pixel.
!1.......^.........^.........^.........^........
!B
*"m";1;"fade" CODE 64767,155 - for tape or
Microdrive respectively.
If everything has gone OK so far, then try out
the FADE DEMO program. This will (hopefully)
fill the screen with random characters and then
erase them pixel-by-pixel. To use the routine
from your own programs, just POKE the locations
shown below with the appropriate values and then
use the command RANDOMIZE USR 64769. The
variables used are:
!0.......^.........^.........^..
DPOS: 64914 (FD92 Hex)
APOS: 64915 (FD93 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the down and across
coordinates of the top left character square in
the area to be exploded. Note that this is a
different approach to the one used in MCEXP
which uses x,y coordinates (this is, pixel
coordinates).
!0.......^.........^.........^..
DLIM: 64916 (FD94 Hex)
ALIM: 64917 (FD95 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the size of the area
in character squares, down and across respec-
tively.
!0.......^.........^.........^..
SPEED: 64918 (FD96 Hex)
!1.......^.........^.........^.........^........
The speed of the explosion. Again, one is fast,
255 is slow. Total time of explosion = SPEED/3
seconds (approx). Large areas may take consider-
ably longer.
!0.......^.........^.........^..
DONE: 64919 (FD97 Hex)
!1.......^.........^.........^.........^........
The same as for MCEXP.
!2.......^.........^.........^.........^.........^.........^....
!B
FCFF ORG #FCFF
FCFF 15FD DEFW FADE
;Initialise variables and interrupts
FD01 AF GO XOR A
FD02 3297FD LD (DONE),A
FD05 3C INC A
FD06 3298FD LD (COUNT),A
FD09 3E08 LD A,#08
FD0B 3299FD LD (ROUND),A
FD0E 3EFC LD A,#FC ;This makes Z80 jump to the sub-
FD10 ED47 LD I,A ;routine whose address is stored
FD12 ED5E IM 2 ;at FCFF on each interrupt
FD14 C9 RET
;This code is executed every 0.02 secs
FD15 C5 FADE PUSH BC
FD16 D5 PUSH DE
FD17 E5 PUSH HL
FD18 F5 PUSH AF
;Erase some dots every (SPEED)/50 secs
FD19 2198FD LD HL,COUNT
FD1C 35 DEC (HL)
FD1D 2047 JR NZ,RET
FD1F 3A96FD LD A,(SPEED)
FD22 77 LD (HL),A
FD23 ED5B92FD LD DE,(DPOS)
FD27 ED4B94FD LD BC,(DLIM)
FD2B CB21 SLA C ;Convert number of
FD2D CB21 SLA C ;rows to number of
FD2F CB21 SLA C ;hires screen lines
FD31 2199FD LD HL,ROUND
FD34 35 DEC (HL)
FD35 2816 JR Z,END
;Erase some dots in the specified area
FD37 CD6DFD CALL CHRADR
FD3A 50 MLOOP1 LD D,B
FD3B 5D LD E,L
FD3C ED5F BYTE1 LD A,R ;Reasonably random number
FD3E A6 AND (HL)
FD3F 77 LD (HL),A
FD40 2C INC L
FD41 10F9 DJNZ BYTE1
FD43 42 LD B,D
FD44 6B LD L,E
FD45 CD7CFD CALL NXTLIN
FD48 0D DEC C
FD49 20EF JR NZ,MLOOP1
FD4B 1819 JR RET
;Clear the specified area
FD4D CD6DFD END CALL CHRADR
FD50 50 MLOOP2 LD D,B
FD51 5D LD E,L
FD52 AF XOR A
FD53 77 BYTE2 LD (HL),A
FD54 2C INC L
FD55 10FC DJNZ BYTE2
FD57 42 LD B,D
FD58 6B LD L,E
FD59 CD7CFD CALL NXTLIN
FD5C 0D DEC C
FD5D 20F1 JR NZ,MLOOP2
FD5F 3E01 LD A,#01
FD61 3297FD LD (DONE),A
FD64 ED56 IM 1
;Restore registers & jump to ROM interrupt routine
FD66 F1 RET POP AF
FD67 E1 POP HL
FD68 D1 POP DE
FD69 C1 POP BC
FD6A C33800 JP #0038
;Convert d,a character position to d.file address
FD6D 7B CHRADR LD A,E
FD6E 0F RRCA
FD6F 0F RRCA
FD70 0F RRCA
FD71 E6E0 AND #E0
FD73 82 ADD A,D
FD74 6F LD L,A
FD75 7B LD A,E
FD76 E618 AND #18
FD78 F640 OR #40
FD7A 67 LD H,A
FD7B C9 RET
;Find address of next line from address of present
FD7C 7C NXTLIN LD A,H
FD7D 0F RRCA
FD7E 0F RRCA
FD7F 0F RRCA
FD80 C620 ADD A,#20
FD82 3009 JR NC,DONE2
FD84 67 LD H,A
FD85 7D LD A,L
FD86 C620 ADD A,#20
FD88 6F LD L,A
FD89 3001 JR NC,DONE1
FD8B 24 INC H
FD8C 7C DONE1 LD A,H
FD8D 07 DONE2 RLCA
FD8E 07 RLCA
FD8F 07 RLCA
FD90 67 LD H,A
FD91 C9 RET
;Variables
FD92 00 DPOS DEFB 0 ;Down and across position
FD93 00 APOS DEFB 0 ;of explosion on screen
FD94 05 DLIM DEFB 5 ;Size of explosion
FD95 20 ALIM DEFB 32 ;in character squares
FD96 32 SPEED DEFB 50 ;Speed of explosion
FD97 00 DONE DEFB 0 ;Flag to indicate end of explosion
FD98 00 COUNT DEFB 0 ;Interrupts to go before next fade
FD99 00 ROUND DEFB 0 ;Number of fades to go
!0.......^.........^.........^..
!B
COLOUR FLASH EXPLOSION (FLASH)
!1.......^.........^.........^.........^........
In this explosion, various different patterns of
random dots flash up onto the screen in many
colours and then disappear. The routine itself
is very similar to the FADE routine, and using
it is exactly the same except that the numbers
are different. Therefore I'll just give you the
!0.......^.........^.........^..
10 REM ***********************
20 REM FLASH DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET dpos=64706
80 LET apos=64707
90 LET dlim=64708
100 LET alim=64709
110 LET speed=64710
120 LET done=64711
130 REM
140 REM FILL SCREEN
150 REM
160 FOR i=1 TO 704
170 PRINT CHR$ (RND*95+32);
180 NEXT i
190 REM
200 REM INITIALISE FLASH
210 REM
220 POKE dpos,0
230 POKE apos,0
240 POKE dlim,22
250 POKE alim,32
260 POKE speed,5
270 REM
280 REM CALL FLASH
290 REM
300 RANDOMIZE USR 64513
310 REM
320 REM WAIT UNTIL END
330 REM
340 IF PEEK done THEN STOP
350 GO TO 340
!2.......^.........^.........^.........^.........^.........^....
The Colour Flash demo: flashes a number of random characters in
different colours and then erases them.
!1.......^.........^.........^.........^........
!B
numbers, as it were, and you can use the text
from FADE as a guide where necessary. But, there
is one other important difference - the demon-
stration program is called FLASH DEMO and it
fills the screen with random characters and then
explodes them appropriately. Here are the
various numbers:
Start address: 64511 (FBFF Hex)
First unused address: 64714 (FCCA Hex)
Saving: SAVE "flash" CODE 64511,203 or SAVE
*"m";1;"flash" CODE 64511,203 (for tape or
Microdrive respectively).
To use from Basic: RANDOMIZE USR 64513
Variables:
!0.......^.........^.........^..
DPOS: 64706 (FCC2 Hex)
APOS: 64707 (FCC3 Hex)
DLIM: 64708 (FCC4 Hex)
ALIM: 64709 (FCC5 Hex)
SPEED: 64710 (FCC6 Hex)
DONE: 64711 (FCC7 Hex)
!1.......^.........^.........^.........^........
Note that each of the routines occupies a diff-
erent area of memory (they don't overlap). It's
therefore possible to have all three routines in
memory at the same time - although you'll only
ever have one explosion occurring on the screen
at any one time. Also, the use of BEEP, LOAD or
SAVE while an interrupt is occurring will tempo-
rarily halt it. Happy zapping!
!2.......^.........^.........^.........^.........^.........^....
!B
FBFF ORG #FBFF
FBFF 15FC DEFW FLASH
;Initialise variables and interrupts
FC01 AF GO XOR A
FC02 32C7FC LD (DONE),A
FC05 3C INC A
FC06 32C8FC LD (COUNT),A
FC09 3E08 LD A,#08
FC0B 32C9FC LD (ROUND),A
FC0E 3EFB LD A,#FB ;This makes Z80 jump to the sub-
FC10 ED47 LD I,A ;routine whose address is stored
FC12 ED5E IM 2 ;at FBFF on each interrupt
FC14 C9 RET
;This code is executed every 0.02 secs
FC15 C5 FLASH PUSH BC
FC16 D5 PUSH DE
FC17 E5 PUSH HL
FC18 F5 PUSH AF
;Flash every (SPEED)/50 secs
FC19 21C8FC LD HL,COUNT
FC1C 35 DEC (HL)
FC1D 2077 JR NZ,RET
FC1F 3AC6FC LD A,(SPEED)
FC22 77 LD (HL),A
FC23 ED5BC2FC LD DE,(DPOS)
FC27 ED4BC4FC LD BC,(DLIM)
FC2B CB21 SLA C ;Convert number of
FC2D CB21 SLA C ;rows to number of
FC2F CB21 SLA C ;hires screen lines
FC31 21C9FC LD HL,ROUND
FC34 35 DEC (HL)
FC35 2846 JR Z,END
;Flash specified area
FC37 CD9DFC CALL CHRADR
FC3A 50 MLOOP1 LD D,B
FC3B 5D LD E,L
FC3C ED5F BYTE1 LD A,R
FC3E 77 LD (HL),A
FC3F ED5F LD A,R ;Reasonably random number
FC41 0F RRCA
FC42 0F RRCA
FC43 AE XOR (HL)
FC44 77 LD (HL),A
FC45 2C INC L
FC46 10F4 DJNZ BYTE1
FC48 42 LD B,D
FC49 6B LD L,E
FC4A CDACFC CALL NXTLIN
FC4D 0D DEC C
FC4E 20EA JR NZ,MLOOP1
FC50 2AC2FC LD HL,(DPOS)
;Convert d,a position to address in attribute file
FC53 7C LD A,H
FC54 2600 LD H,#00
FC56 0605 LD B,#05
FC58 29 DOUBLE ADD HL,HL
FC59 10FD DJNZ DOUBLE
FC5B B5 OR L
FC5C 6F LD L,A
FC5D 7C LD A,H
FC5E F658 OR #58
FC60 67 LD H,A
;Colour in specified area with (ROUND) ink
FC61 ED4BC4FC LD BC,(DLIM)
FC65 3AC9FC LD A,(ROUND)
FC68 57 LD D,A
FC69 5D ALINE LD E,L
FC6A C5 PUSH BC
FC6B 7E ABYTE LD A,(HL)
FC6C E6F8 AND #F8
FC6E B2 OR D
FC6F 77 LD (HL),A
FC70 2C INC L
FC71 10F8 DJNZ ABYTE
FC73 6B LD L,E
FC74 0E20 LD C,#20
FC76 09 ADD HL,BC
FC77 C1 POP BC
FC78 0D DEC C
FC79 20EE JR NZ,ALINE
FC7B 1819 JR RET
;Clear specified area
FC7D CD9DFC END CALL CHRADR
FC80 50 MLOOP2 LD D,B
FC81 5D LD E,L
FC82 AF XOR A
FC83 77 BYTE2 LD (HL),A
FC84 2C INC L
FC85 10FC DJNZ BYTE2
FC87 42 LD B,D
FC88 6B LD L,E
FC89 CDACFC CALL NXTLIN
FC8C 0D DEC C
FC8D 20F1 JR NZ,MLOOP2
FC8F 3E01 LD A,#01
FC91 32C7FC LD (DONE),A
FC94 ED56 IM 1
;Restore registers & jump to ROM interrupt routine
FC96 F1 RET POP AF
FC97 E1 POP HL
FC98 D1 POP DE
FC99 C1 POP BC
FC9A C33800 JP #0038
;Convert d,a character position to d.file address
FC9D 7B CHRADR LD A,E
FC9E 0F RRCA
FC9F 0F RRCA
FCA0 0F RRCA
FCA1 E6E0 AND #E0
FCA3 82 ADD A,D
FCA4 6F LD L,A
FCA5 7B LD A,E
FCA6 E618 AND #18
FCA8 F640 OR #40
FCAA 67 LD H,A
FCAB C9 RET
;Find address of next line from address of present
FCAC 7C NXTLIN LD A,H
FCAD 0F RRCA
FCAE 0F RRCA
FCAF 0F RRCA
FCB0 C620 ADD A,#20
FCB2 3009 JR NC,DONE2
FCB4 67 LD H,A
FCB5 7D LD A,L
FCB6 C620 ADD A,#20
FCB8 6F LD L,A
FCB9 3001 JR NC,DONE1
FCBB 24 INC H
FCBC 7C DONE1 LD A,H
FCBD 07 DONE2 RLCA
FCBE 07 RLCA
FCBF 07 RLCA
FCC0 67 LD H,A
FCC1 C9 RET
;Variables
FCC2 00 DPOS DEFB 0 ;Down and across position
FCC3 00 APOS DEFB 0 ;of explosion on screen
FCC4 05 DLIM DEFB 5 ;Size of explosion
FCC5 20 ALIM DEFB 32 ;in character squares
FCC6 32 SPEED DEFB 50 ;Speed of explosion
FCC7 00 DONE DEFB 0 ;Flag to indicate end of explosion
FCC8 00 COUNT DEFB 0 ;Interrupts to go before next fade
FCC9 00 ROUND DEFB 0 ;Number of fades to go
!1.......^.........^.........^.........^........
!B
--
from Your Spectrum #6 (Aug.1984)
--
!$
!B
\H11\H07\H10\H02 B A N G
\H11\H07\H10\H00 GOES YOUR CODE
!2.......^.........^.........^.........^.........^.........^....
Has the razzle-dazzle gone out of your programs? Simon Lane's
got some explosive ideas to stun you ...
!1.......^.........^.........^.........^........
Have you ever had that feeling of anti-climax
when, having successfully obliterated an alien
(or whatever) in some otherwise superbly written
Basic program, it simply disappears into thin
air without any kind of graphic reward? Well,
now you'll be able to remedy this omission by
simply calling one of these interrupt-driven
machine code explosion routines at the approp-
riate point in your program. Just read the
instructions, type in the object code, and off
you go.
The assembly language listings have been
produced using the Hisoft GENS assembler, which
uses a '#' symbol to denote Hex numbers. If you
have an assembler you can type in the source
code and assemble it yourself. This will allow
you the added joy of making your own alterations
to the programs - certainly, it's a lot less
boring than entering the object code straight.
However, without an assembler this is exactly
what you will have to do - using either a suit-
able monitor program, or the short Hex loader
provided as a last resort.
To use the Hex loader, first you'll have to
enter the start address (in decimal) as given in
the instructions for each routine; that has to
be followed by all the Hex object code given in
column two of the assembler listing. For
example, to enter
!0.......^.........^.........^..
!B
10 REM ***********************
20 REM HEX LOADER
30 REM ***********************
40 DEF FN d(h$)=CODE h$-48-(32
AND h$>="a")-(7 AND h$>="A")
50 INPUT "Start address:";l
60 INPUT (l);">";h$
70 POKE l,FN d(h$(1))*16+FN d(
h$(2))
80 LET l=l+1: LET h$=h$(3 TO )
90 IF h$>"" THEN GO TO 70
100 GO TO 60
!2.......^.........^.........^.........^.........^.........^....
Those without an assembler can use the above program to type in
the Hex code.
!1.......^.........^.........^.........^........
the Missile Command routine, you would type
65023 (Enter), 16FE (Enter), AF (Enter), 32D2FE
... 00FF (Enter). Once that's out of the way,
you can break out of the program by deleting one
of the quotes and typing STOP.
!0.......^.........^.........^..
!B
MISSILE COMMAND
EXPLOSION (MCEXP)
!1.......^.........^.........^.........^........
Anyone who's ever been in an amusement arcade
must surely have come across the Missile Command
game at some time or other. There the explosions
are displayed as circles which get larger and
larger and then shrink away to nothing; my first
routine is an attempt to simulate this effect.
The object code should be entered into memory
starting at 65023 (FDFF Hex) and, just as a
check, the first address at which no object code
should be entered (that is, the address at which
you STOP the Hex loader) should be 65256 (FEEB
Hex).
The routine works by drawing a series of octa-
gons on the screen, starting at the coordinates
stored in XPOS and YPOS (see below). When a
'radius' equal to the contents of LIMIT is
reached, the octagons are 'undrawn', but this
time in reverse order. This gives an effect very
similar to a circle growing and then
!0.......^.........^.........^..
10 REM ***********************
20 REM MCEXP DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET xpos=65236
80 LET ypos=65237
90 LET limit=65238
100 LET speed=65239
110 LET done=65240
120 REM
130 REM INITIALISE MCEXP
140 REM
150 POKE xpos,128
160 POKE ypos,88
170 POKE limit,87
180 POKE speed,1
190 REM
200 REM CALL MCEXP
210 REM
220 RANDOMIZE USR 65025
230 REM
240 REM FLASH BORDER UNTIL END
250 REM
260 BORDER RND*7
270 IF PEEK done THEN STOP
280 GO TO 260
!2.......^.........^.........^.........^.........^.........^....
The Missile Command demo: produces an explosion at the centre of
the screen.
!1.......^.........^.........^.........^........
!B
shrinking away - without the problems associated
with drawing circles (slowness and/or large
look-up tables). Note that when the octagons are
drawn on the screen, XOR plotting is used. This
gives the same effect as using PLOT OVER 1 from
Basic.
Once you've typed in the object code it's
advisable to save it immediately, just in case
you inadvertently manage to crash the program.
Enter SAVE "mcexp" CODE 65023,233 to save to
tape, and SAVE *"m";1;"mcexp" CODE 65023,233 to
save to Microdrive cartridge. Then, type in and
run the MCEXP DEMO program; if everything is as
it should be, and explosion should be produced
that starts at the centre of the screen and then
fills it.
To use the routine in your own programs, you
just have to POKE the locations below with the
appropriate values and then use the command
RANDOMIZE USR 65025. The variables used in the
program are as follows:
!0.......^.........^.........^..
XPOS: 65236 (FED4 Hex)
YPOS: 65237 (FED5 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the x and y coord-
inates of the point where the centre of the
explosion is required.
!0.......^.........^.........^..
LIMIT: 65238 (FED6 Hex)
!1.......^.........^.........^.........^........
The radius of the required explosion. Note XPOS
- LIMIT 0, XPOS + LIMIT 255, YPOS - LIMIT 0,
YPOS + LIMIT 175,
!0.......^.........^.........^..
SPEED: 65239 (FED7 Hex)
!1.......^.........^.........^.........^........
The speed of the explosion. Note that one is
fast, 255 is slow. Total time of explosion =
(LIMIT * SPEED + 1)/25 seconds (approx). Large
explosions take considerably longer.
!0.......^.........^.........^..
DONE: 65240 (FED8 Hex)
!1.......^.........^.........^.........^........
This location can be PEEKed to determine whether
or not the explosion has been completed (since
the routine is interrupt-driven, the Basic
program continues to run while the machine code
is executed). A zero indicates that the explos-
ion is still taking place and a one indicates
that it has finished. Note that commands of the
form "IF PEEK done ..." can therefore be used in
your programs.
It's advisable to assign the values above to
Basic variables at the start of your program.
This approach is used in each of the demon-
stration programs.
!2.......^.........^.........^.........^.........^.........^....
!B
FDFF ORG #FDFF
FDFF 16FE DEFW MCEXP
;Initialise variables and interrupts
FE01 AF GO XOR A
FE02 32D8FE LD (DONE),A
FE05 32DAFE LD (SIZE),A
FE08 32DFFE LD (INOUT),A
FE0B 3C INC A
FE0C 32D9FE LD (COUNT),A
FE0F 3EFD LD A,#FD ;This makes Z80 jump to the sub-
FE11 ED47 LD I,A ;routine whose address is stored
FE13 ED5E IM 2 ;at FDFF on each interrupt
FE15 C9 RET
;This code is executed every 0.02 secs
FE16 C5 MCEXP PUSH BC
FE17 D5 PUSH DE
FE18 E5 PUSH HL
FE19 F5 PUSH AF
FE1A DDE5 PUSH IX
;Draw an octagon every (SPEED)/50 secs
FE1C 21D9FE LD HL,COUNT
FE1F 35 DEC (HL)
FE20 C2A4FE JP NZ,RET
FE23 3AD7FE LD A,(SPEED)
FE26 77 LD (HL),A
FE27 2AD4FE LD HL,(XPOS)
FE2A 3ADAFE LD A,(SIZE)
FE2D A7 AND A
FE2E 2005 JR NZ,NOT0
;If (SIZE)=0 then plot a single point ...
FE30 CDADFE CALL PLOT
FE33 1848 JR ENDPLT
;otherwise draw an octagon of the appropriate size
FE35 5F NOT0 LD E,A
FE36 57 LD D,A
FE37 CB3A SRL D
FE39 19 ADD HL,DE
FE3A 1100FF LD DE,#FF00 ;Down
FE3D DD21E0FE LD IX,DIRTAB
FE41 0E04 LD C,#04
FE43 FE01 MLOOP CP #01
FE45 2809 JR Z,NOGO
FE47 47 LD B,A
FE48 CB80 RES 0,B
;Draw straight line
FE4A 19 STRT ADD HL,DE
FE4B CDADFE CALL PLOT
FE4E 10FA DJNZ STRT
FE50 47 NOGO LD B,A
FE51 04 INC B
FE52 CB38 SRL B
FE54 ED53DBFE LD (DE1),DE
FE58 DD5E00 LD E,(IX+#00)
FE5B DD5601 LD D,(IX+#01)
FE5E ED53DDFE LD (DE2),DE
;Draw diagonal line
FE62 19 DIAG ADD HL,DE
FE63 CB47 BIT 0,A
FE65 CCADFE CALL Z,PLOT
FE68 ED5BDBFE LD DE,(DE1)
FE6C 19 ADD HL,DE
FE6D CDADFE CALL PLOT
FE70 ED5BDDFE LD DE,(DE2)
FE74 10EC DJNZ DIAG
FE76 DD23 INC IX ;Point to next
FE78 DD23 INC IX ;entry in DIRTAB
FE7A 0D DEC C
FE7B 20C6 JR NZ,MLOOP
FE7D 3ADFFE MLOOP LD A,(INOUT)
FE80 A7 AND A
FE81 21DAFE LD HL,SIZE
FE84 2010 JR NZ,IN
FE86 3AD6FE LD A,(LIMIT)
FE89 BE CP (HL)
FE8A 2803 JR Z,CHANGE
FE8C 34 INC (HL) ;Grow
FE8D 1815 JR RET
;Change from growing to shrinking
FE8F 3E01 CHANGE LD A,#01
FE91 32DFFE LD (INOUT),A
FE94 180E JR RET
FE96 3D IN DEC A
FE97 BE CP (HL)
FE98 2009 JR NZ,INOK
;Explosion complete
FE9A 3E01 LD A,#01
FE9C 32D8FE LD (DONE),A
FE9F ED56 IM 1
FEA1 1801 JR RET
FEA3 35 INOK DEC (HL) ;Shrink
;Restore registers & jump to ROM interrupt routine
FEA4 DDE1 RET POP IX
FEA6 F1 POP AF
FEA7 E1 POP HL
FEA8 D1 POP DE
FEA9 C1 POP BC
FEAA C33800 JP #0038
;Invert point if growing, unplot if shrinking
FEAD E5 PLOT PUSH HL
FEAE F5 PUSH AF
FEAF 3ADFFE LD A,(INOUT)
FEB2 A7 AND A
FEB3 2008 JR NZ,UNPLOT
;Invert point
FEB5 CDC5FE PLOTX CALL PIXAD
FEB8 2F CPL
FEB9 AE XOR (HL)
FEBA 77 LD (HL),A
FEBB 1805 JR PLTRET
;Unplot point
FEBD CDC5FE UNPLOT CALL PIXAD
FEC0 A6 AND (HL)
FEC1 77 LD (HL),A
FEC2 F1 PLTRET POP AF
FEC3 E1 POP HL
FEC4 C9 RET
;Convert x,y coords into d.file address & bit map
FEC5 C5 PIXAD PUSH BC
FEC6 44 LD B,H
FEC7 4D LD C,L
FEC8 CDAA22 CALL #22AA
FECB 47 LD B,A
FECC 04 INC B
FECD 3EFE LD A,#FE
FECF 0F PIXEL RRCA
FED0 10FD DJNZ PIXEL
FED2 C1 POP BC
FED3 C9 RET
;Variables
FED4 64 XPOS DEFB 100 ;X,Y coordinates of centre
FED5 64 YPOS DEFB 100 ;of explosion on screen
FED6 0A LIMIT DEFB 10 ;Max. radius of explosion
FED7 05 SPEED DEFB 5 ;Speed of explosion
FED8 00 DONE DEFB 0 ;Flag to indicate end of explosion
FED9 00 COUNT DEFB 0 ;Interrupts before next octagon
FEDA 00 SIZE DEFB 0 ;Current radius of explosion
FEDB 0000 DE1 DEFW 0 ;Horizontal and vertical
FEDD 0000 DE2 DEFW 0 ;components of diagonal
FEDF 00 INOUT DEFB 0 ;0=growing; 1=shrinking
;Table of directions
FEE0 FFFF DIRTAB DEFW #FFFF ;Left
FEE2 0001 DEFW #0100 ;Up
FEE4 0100 DEFW #0001 ;Right
FEE6 000F DEFW #FF00 ;Down
!0.......^.........^.........^..
!B
DOT FADE EXPLOSION (FADE)
!1.......^.........^.........^.........^........
Technically this isn't really an explosion at
all. What happens here is that the object to be
"de-materialised" fades away dot-by-dot. The
start address for the object code is 64767 (FCFF
Hex), and the first unused address should be
64922 (FD9A Hex). When you've entered the code,
save using SAVE "fade" CODE 64767,155 or SAVE
!0.......^.........^.........^..
10 REM ***********************
20 REM FADE DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET dpos=64914
80 LET apos=64915
90 LET dlim=64916
100 LET alim=64917
110 LET speed=64918
120 LET done=64919
130 REM
140 REM FILL SCREEN
150 REM
160 FOR i=1 TO 704
170 PRINT CHR$ (RND*95+32);
180 NEXT i
190 REM
200 REM INITIALISE FADE
210 REM
220 POKE dpos,0
230 POKE apos,0
240 POKE dlim,22
250 POKE alim,32
260 POKE speed,10
270 REM
280 REM CALL FADE
290 REM
300 RANDOMIZE USR 64769
310 REM
320 REM WAIT UNTIL END
330 REM
340 IF PEEK done THEN STOP
350 GO TO 340
!2.......^.........^.........^.........^.........^.........^....
The Dot Fade demo: fills an area of the screen with random
characters and erases them pixel-by-pixel.
!1.......^.........^.........^.........^........
!B
*"m";1;"fade" CODE 64767,155 - for tape or
Microdrive respectively.
If everything has gone OK so far, then try out
the FADE DEMO program. This will (hopefully)
fill the screen with random characters and then
erase them pixel-by-pixel. To use the routine
from your own programs, just POKE the locations
shown below with the appropriate values and then
use the command RANDOMIZE USR 64769. The
variables used are:
!0.......^.........^.........^..
DPOS: 64914 (FD92 Hex)
APOS: 64915 (FD93 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the down and across
coordinates of the top left character square in
the area to be exploded. Note that this is a
different approach to the one used in MCEXP
which uses x,y coordinates (this is, pixel
coordinates).
!0.......^.........^.........^..
DLIM: 64916 (FD94 Hex)
ALIM: 64917 (FD95 Hex)
!1.......^.........^.........^.........^........
These should be POKEd with the size of the area
in character squares, down and across respec-
tively.
!0.......^.........^.........^..
SPEED: 64918 (FD96 Hex)
!1.......^.........^.........^.........^........
The speed of the explosion. Again, one is fast,
255 is slow. Total time of explosion = SPEED/3
seconds (approx). Large areas may take consider-
ably longer.
!0.......^.........^.........^..
DONE: 64919 (FD97 Hex)
!1.......^.........^.........^.........^........
The same as for MCEXP.
!2.......^.........^.........^.........^.........^.........^....
!B
FCFF ORG #FCFF
FCFF 15FD DEFW FADE
;Initialise variables and interrupts
FD01 AF GO XOR A
FD02 3297FD LD (DONE),A
FD05 3C INC A
FD06 3298FD LD (COUNT),A
FD09 3E08 LD A,#08
FD0B 3299FD LD (ROUND),A
FD0E 3EFC LD A,#FC ;This makes Z80 jump to the sub-
FD10 ED47 LD I,A ;routine whose address is stored
FD12 ED5E IM 2 ;at FCFF on each interrupt
FD14 C9 RET
;This code is executed every 0.02 secs
FD15 C5 FADE PUSH BC
FD16 D5 PUSH DE
FD17 E5 PUSH HL
FD18 F5 PUSH AF
;Erase some dots every (SPEED)/50 secs
FD19 2198FD LD HL,COUNT
FD1C 35 DEC (HL)
FD1D 2047 JR NZ,RET
FD1F 3A96FD LD A,(SPEED)
FD22 77 LD (HL),A
FD23 ED5B92FD LD DE,(DPOS)
FD27 ED4B94FD LD BC,(DLIM)
FD2B CB21 SLA C ;Convert number of
FD2D CB21 SLA C ;rows to number of
FD2F CB21 SLA C ;hires screen lines
FD31 2199FD LD HL,ROUND
FD34 35 DEC (HL)
FD35 2816 JR Z,END
;Erase some dots in the specified area
FD37 CD6DFD CALL CHRADR
FD3A 50 MLOOP1 LD D,B
FD3B 5D LD E,L
FD3C ED5F BYTE1 LD A,R ;Reasonably random number
FD3E A6 AND (HL)
FD3F 77 LD (HL),A
FD40 2C INC L
FD41 10F9 DJNZ BYTE1
FD43 42 LD B,D
FD44 6B LD L,E
FD45 CD7CFD CALL NXTLIN
FD48 0D DEC C
FD49 20EF JR NZ,MLOOP1
FD4B 1819 JR RET
;Clear the specified area
FD4D CD6DFD END CALL CHRADR
FD50 50 MLOOP2 LD D,B
FD51 5D LD E,L
FD52 AF XOR A
FD53 77 BYTE2 LD (HL),A
FD54 2C INC L
FD55 10FC DJNZ BYTE2
FD57 42 LD B,D
FD58 6B LD L,E
FD59 CD7CFD CALL NXTLIN
FD5C 0D DEC C
FD5D 20F1 JR NZ,MLOOP2
FD5F 3E01 LD A,#01
FD61 3297FD LD (DONE),A
FD64 ED56 IM 1
;Restore registers & jump to ROM interrupt routine
FD66 F1 RET POP AF
FD67 E1 POP HL
FD68 D1 POP DE
FD69 C1 POP BC
FD6A C33800 JP #0038
;Convert d,a character position to d.file address
FD6D 7B CHRADR LD A,E
FD6E 0F RRCA
FD6F 0F RRCA
FD70 0F RRCA
FD71 E6E0 AND #E0
FD73 82 ADD A,D
FD74 6F LD L,A
FD75 7B LD A,E
FD76 E618 AND #18
FD78 F640 OR #40
FD7A 67 LD H,A
FD7B C9 RET
;Find address of next line from address of present
FD7C 7C NXTLIN LD A,H
FD7D 0F RRCA
FD7E 0F RRCA
FD7F 0F RRCA
FD80 C620 ADD A,#20
FD82 3009 JR NC,DONE2
FD84 67 LD H,A
FD85 7D LD A,L
FD86 C620 ADD A,#20
FD88 6F LD L,A
FD89 3001 JR NC,DONE1
FD8B 24 INC H
FD8C 7C DONE1 LD A,H
FD8D 07 DONE2 RLCA
FD8E 07 RLCA
FD8F 07 RLCA
FD90 67 LD H,A
FD91 C9 RET
;Variables
FD92 00 DPOS DEFB 0 ;Down and across position
FD93 00 APOS DEFB 0 ;of explosion on screen
FD94 05 DLIM DEFB 5 ;Size of explosion
FD95 20 ALIM DEFB 32 ;in character squares
FD96 32 SPEED DEFB 50 ;Speed of explosion
FD97 00 DONE DEFB 0 ;Flag to indicate end of explosion
FD98 00 COUNT DEFB 0 ;Interrupts to go before next fade
FD99 00 ROUND DEFB 0 ;Number of fades to go
!0.......^.........^.........^..
!B
COLOUR FLASH EXPLOSION (FLASH)
!1.......^.........^.........^.........^........
In this explosion, various different patterns of
random dots flash up onto the screen in many
colours and then disappear. The routine itself
is very similar to the FADE routine, and using
it is exactly the same except that the numbers
are different. Therefore I'll just give you the
!0.......^.........^.........^..
10 REM ***********************
20 REM FLASH DEMO
30 REM ***********************
40 REM
50 REM ASSIGN VARIABLES
60 REM
70 LET dpos=64706
80 LET apos=64707
90 LET dlim=64708
100 LET alim=64709
110 LET speed=64710
120 LET done=64711
130 REM
140 REM FILL SCREEN
150 REM
160 FOR i=1 TO 704
170 PRINT CHR$ (RND*95+32);
180 NEXT i
190 REM
200 REM INITIALISE FLASH
210 REM
220 POKE dpos,0
230 POKE apos,0
240 POKE dlim,22
250 POKE alim,32
260 POKE speed,5
270 REM
280 REM CALL FLASH
290 REM
300 RANDOMIZE USR 64513
310 REM
320 REM WAIT UNTIL END
330 REM
340 IF PEEK done THEN STOP
350 GO TO 340
!2.......^.........^.........^.........^.........^.........^....
The Colour Flash demo: flashes a number of random characters in
different colours and then erases them.
!1.......^.........^.........^.........^........
!B
numbers, as it were, and you can use the text
from FADE as a guide where necessary. But, there
is one other important difference - the demon-
stration program is called FLASH DEMO and it
fills the screen with random characters and then
explodes them appropriately. Here are the
various numbers:
Start address: 64511 (FBFF Hex)
First unused address: 64714 (FCCA Hex)
Saving: SAVE "flash" CODE 64511,203 or SAVE
*"m";1;"flash" CODE 64511,203 (for tape or
Microdrive respectively).
To use from Basic: RANDOMIZE USR 64513
Variables:
!0.......^.........^.........^..
DPOS: 64706 (FCC2 Hex)
APOS: 64707 (FCC3 Hex)
DLIM: 64708 (FCC4 Hex)
ALIM: 64709 (FCC5 Hex)
SPEED: 64710 (FCC6 Hex)
DONE: 64711 (FCC7 Hex)
!1.......^.........^.........^.........^........
Note that each of the routines occupies a diff-
erent area of memory (they don't overlap). It's
therefore possible to have all three routines in
memory at the same time - although you'll only
ever have one explosion occurring on the screen
at any one time. Also, the use of BEEP, LOAD or
SAVE while an interrupt is occurring will tempo-
rarily halt it. Happy zapping!
!2.......^.........^.........^.........^.........^.........^....
!B
FBFF ORG #FBFF
FBFF 15FC DEFW FLASH
;Initialise variables and interrupts
FC01 AF GO XOR A
FC02 32C7FC LD (DONE),A
FC05 3C INC A
FC06 32C8FC LD (COUNT),A
FC09 3E08 LD A,#08
FC0B 32C9FC LD (ROUND),A
FC0E 3EFB LD A,#FB ;This makes Z80 jump to the sub-
FC10 ED47 LD I,A ;routine whose address is stored
FC12 ED5E IM 2 ;at FBFF on each interrupt
FC14 C9 RET
;This code is executed every 0.02 secs
FC15 C5 FLASH PUSH BC
FC16 D5 PUSH DE
FC17 E5 PUSH HL
FC18 F5 PUSH AF
;Flash every (SPEED)/50 secs
FC19 21C8FC LD HL,COUNT
FC1C 35 DEC (HL)
FC1D 2077 JR NZ,RET
FC1F 3AC6FC LD A,(SPEED)
FC22 77 LD (HL),A
FC23 ED5BC2FC LD DE,(DPOS)
FC27 ED4BC4FC LD BC,(DLIM)
FC2B CB21 SLA C ;Convert number of
FC2D CB21 SLA C ;rows to number of
FC2F CB21 SLA C ;hires screen lines
FC31 21C9FC LD HL,ROUND
FC34 35 DEC (HL)
FC35 2846 JR Z,END
;Flash specified area
FC37 CD9DFC CALL CHRADR
FC3A 50 MLOOP1 LD D,B
FC3B 5D LD E,L
FC3C ED5F BYTE1 LD A,R
FC3E 77 LD (HL),A
FC3F ED5F LD A,R ;Reasonably random number
FC41 0F RRCA
FC42 0F RRCA
FC43 AE XOR (HL)
FC44 77 LD (HL),A
FC45 2C INC L
FC46 10F4 DJNZ BYTE1
FC48 42 LD B,D
FC49 6B LD L,E
FC4A CDACFC CALL NXTLIN
FC4D 0D DEC C
FC4E 20EA JR NZ,MLOOP1
FC50 2AC2FC LD HL,(DPOS)
;Convert d,a position to address in attribute file
FC53 7C LD A,H
FC54 2600 LD H,#00
FC56 0605 LD B,#05
FC58 29 DOUBLE ADD HL,HL
FC59 10FD DJNZ DOUBLE
FC5B B5 OR L
FC5C 6F LD L,A
FC5D 7C LD A,H
FC5E F658 OR #58
FC60 67 LD H,A
;Colour in specified area with (ROUND) ink
FC61 ED4BC4FC LD BC,(DLIM)
FC65 3AC9FC LD A,(ROUND)
FC68 57 LD D,A
FC69 5D ALINE LD E,L
FC6A C5 PUSH BC
FC6B 7E ABYTE LD A,(HL)
FC6C E6F8 AND #F8
FC6E B2 OR D
FC6F 77 LD (HL),A
FC70 2C INC L
FC71 10F8 DJNZ ABYTE
FC73 6B LD L,E
FC74 0E20 LD C,#20
FC76 09 ADD HL,BC
FC77 C1 POP BC
FC78 0D DEC C
FC79 20EE JR NZ,ALINE
FC7B 1819 JR RET
;Clear specified area
FC7D CD9DFC END CALL CHRADR
FC80 50 MLOOP2 LD D,B
FC81 5D LD E,L
FC82 AF XOR A
FC83 77 BYTE2 LD (HL),A
FC84 2C INC L
FC85 10FC DJNZ BYTE2
FC87 42 LD B,D
FC88 6B LD L,E
FC89 CDACFC CALL NXTLIN
FC8C 0D DEC C
FC8D 20F1 JR NZ,MLOOP2
FC8F 3E01 LD A,#01
FC91 32C7FC LD (DONE),A
FC94 ED56 IM 1
;Restore registers & jump to ROM interrupt routine
FC96 F1 RET POP AF
FC97 E1 POP HL
FC98 D1 POP DE
FC99 C1 POP BC
FC9A C33800 JP #0038
;Convert d,a character position to d.file address
FC9D 7B CHRADR LD A,E
FC9E 0F RRCA
FC9F 0F RRCA
FCA0 0F RRCA
FCA1 E6E0 AND #E0
FCA3 82 ADD A,D
FCA4 6F LD L,A
FCA5 7B LD A,E
FCA6 E618 AND #18
FCA8 F640 OR #40
FCAA 67 LD H,A
FCAB C9 RET
;Find address of next line from address of present
FCAC 7C NXTLIN LD A,H
FCAD 0F RRCA
FCAE 0F RRCA
FCAF 0F RRCA
FCB0 C620 ADD A,#20
FCB2 3009 JR NC,DONE2
FCB4 67 LD H,A
FCB5 7D LD A,L
FCB6 C620 ADD A,#20
FCB8 6F LD L,A
FCB9 3001 JR NC,DONE1
FCBB 24 INC H
FCBC 7C DONE1 LD A,H
FCBD 07 DONE2 RLCA
FCBE 07 RLCA
FCBF 07 RLCA
FCC0 67 LD H,A
FCC1 C9 RET
;Variables
FCC2 00 DPOS DEFB 0 ;Down and across position
FCC3 00 APOS DEFB 0 ;of explosion on screen
FCC4 05 DLIM DEFB 5 ;Size of explosion
FCC5 20 ALIM DEFB 32 ;in character squares
FCC6 32 SPEED DEFB 50 ;Speed of explosion
FCC7 00 DONE DEFB 0 ;Flag to indicate end of explosion
FCC8 00 COUNT DEFB 0 ;Interrupts to go before next fade
FCC9 00 ROUND DEFB 0 ;Number of fades to go
!1.......^.........^.........^.........^........
!B
--
from Your Spectrum #6 (Aug.1984)
--
!$