home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 13
/
af013.adf
/
DaveJones
/
MENACE.S
< prev
next >
Wrap
Text File
|
1978-04-15
|
73KB
|
2,894 lines
*****************************************************************************
* *
* Amiga system takeover framework *
* 1988 Dave Jones, DMA Design *
* *
* Allows killing of system, allowing changing of all display & blitter *
* hardware, restoring to normal after exiting. *
* Memory must still be properly allocated/deallocated upon entry/exit *
* DOS routines for loading must be called BEFORE killing the system *
* *
* Written using Devpac2 *
* *
*****************************************************************************
section Framework,code_c
incdir "fast:devpac/include/"
include libraries/dos_lib.i
include exec/exec_lib.i
include hardware/custom.i
Hardware equ $dff000
SystemCopper1 equ $26
SystemCopper2 equ $32
PortA equ $bfe001
ICRA equ $bfed01
LeftMouse equ 6
BackgroundWidth equ 100 100 bytes wide
ForegroundWidth equ 92 92 bytes wide
ScreenHeight equ 192 playing area 192 lines high (12 blocks)
NumberPlanes equ 3 3 planes in each playfield
BytesPerBackPlane equ BackgroundWidth*ScreenHeight
BytesPerForePlane equ ForegroundWidth*ScreenHeight
BackgroundMemory equ 2*NumberPlanes*BytesPerBackPlane
ForegroundMemory equ NumberPlanes*BytesPerForePlane
MemNeeded equ BackgroundMemory+ForegroundMemory
FullFirepower equ 0
aliensize equ 24<<6!3
firedelay equ 3
*******************************************************************************
start lea GraphicsName(pc),a1 open the graphics library purely
move.l _SysBase,a6 to find the system copper
clr.l d0
jsr _LVOOpenLibrary(a6)
move.l d0,GraphicsBase
lea DOSName(pc),a1 open the DOS library to allow
clr.l d0 the loading of data before
jsr _LVOOpenLibrary(a6) killing the system
move.l d0,DOSBase
move.l #MemNeeded,d0 properly allocate some chip
moveq.l #2,d1 memory for screens etc.
jsr _LVOAllocMem(a6) d1 = 2, specifies chip memory
tst.l d0 where screens,samples etc
beq MemError must be (bottom 512K)
move.l d0,MemBase
*******************************************************************************
lea variables(pc),a5 a5 is the variables pointer
lea rasters(a5),a0
lea displayraster(a5),a1
move.l d0,(a0)+ calculate the address of each plane
move.l d0,(a1)+ store them in the variables area,
add.l #BytesPerBackPlane,d0 twice for the background as it is
move.l d0,(a0)+ double buffered
move.l d0,(a1)+
add.l #BytesPerBackPlane,d0
move.l d0,(a0)+
move.l d0,(a1)+
add.l #BytesPerBackPlane,d0
move.l d0,(a0)+
add.l #BytesPerForePlane,d0
move.l d0,(a0)+
add.l #BytesPerForePlane,d0
move.l d0,(a0)+
add.l #BytesPerForePlane,d0
move.l d0,(a0)+
move.l d0,(a1)+
add.l #BytesPerBackPlane,d0
move.l d0,(a0)+
move.l d0,(a1)+
add.l #BytesPerBackPlane,d0
move.l d0,(a0)+
move.l d0,(a1)+
move.l #Hardware,a6
jsr TakeSystem
*******************************************************************************
move.l #$dff000,a6 a6 ALWAYS point to base of
move.l #-1,bltafwm(a6) custom chips
bsr GameInit
move.l #clist,cop1lc(a6)
move.w #$87e0,dmacon(a6) enable copper,sprite,blitter
move.w #$7fff,intreq(a6) clear all int request flags
move.w #$0c30,clxcon(a6)
*******************************************************************************
* Main game loop with the routines we are yet to cover commented out
*******************************************************************************
vloop bsr waitline223 interrupt set at vertical
not.b vcount(a5) position 223 (panel start)
beq twoblanks alternate every frame
lea copperlist(pc),a1 set up registers for routine
move.w pf2scroll(a5),d0 checkpf2
move.w pf1scroll(a5),d1
bsr checkpf2 and branch to it
bsr moveship
bsr check.collision
bsr erase.missiles
bsr levels.code
bsr update.missiles
bsr drawfgnds
* bsr print.score
* bsr check.keys
bsr check.path
bra vloop
twoblanks
bsr checkpf1 the following routines are only
bsr flipbgnd executed every second frame
bsr moveship
bsr restorebgnds restore backgrounds behind aliens
bsr process.aliens
bsr save.aliens save the backgrounds behind aliens
bsr draw.aliens and then draw the aliens
tst.b kill.game(a5)
beq vloop
bra alldone
**************************************************************************
waitline223
btst #4,intreqr+1(a6) wait for vertical line 223
beq waitline223 interrupt set by the
move.w #$10,intreq(a6) copperlist
return rts
**************************************************************************
checkpf1
cmp.w #3,level.end(a5) level.end = 3 means
beq return guardian on, so no scroll
lea copperlist(pc),a1
move.w pf2scroll(a5),d0 d0 = pf2 scroll value (0-15)
move.w pf1scroll(a5),d1 d1 = pf1 scroll value (0-15)
subq.w #1,d1 scroll a pixel
bcs resetpf1 reset back to 15
checkpf2
cmp.w #3,level.end(a5) as above
beq return
subq.w #1,d0 scroll a pixel
bcs resetpf2 reset to 15 and update pointers
storescroll
move.w d1,pf1scroll(a5) resave the values
move.w d0,pf2scroll(a5)
move.w pf1count(a5),d2
subq.w #1,d2 check if at the end of the two
or.w d1,d2 screens and flag for the sprite
move.w d2,screenend(a5) routine if true
lsl.w #4,d0
or.w d0,d1
move.w d1,54(a1) put the new scroll value into
rts the copper list
resetpf1
moveq #$f,d1 reset scroll to 15
subq.w #1,pf1count(a5) decrement words scrolled
bne storepf1 carry on if not zero
move.w #23,pf1count(a5) otherwise reset the number of
lea rasters(a5),a4 words to scroll and reset the
lea displayraster(a5),a3 display planes back to the very
move.l (a4)+,(a3)+ start.
move.l (a4)+,(a3)+
move.l (a4)+,(a3)+ six planes in all
add.w #12,a4
move.l (a4)+,(a3)+
move.l (a4)+,(a3)+
move.l (a4)+,(a3)+
bra checkpf2 now check pf2
storepf1
lea displayraster(a5),a3 increment the plane pointers
addq.l #2,(a3) by a word each
addq.l #2,4(a3) these are background planes
addq.l #2,8(a3) and are therefore double
addq.l #2,12(a3) buffered
addq.l #2,16(a3)
addq.l #2,20(a3)
bra checkpf2
resetpf2
lea rasters(a5),a4
moveq #$f,d0 reset scroll back to 15
subq.w #1,pf2count(a5) decrement the word scroll
bne respf2 value and reset if zero
move.w #23,pf2count(a5)
clr.w pf2offset(a5) offset is reverse of pf2count
cmp.w #1,level.end(a5) and is used for the copper
bne respf2 level.end = 1 when map finished
addq.w #1,level.end(a5) so start to draw guardian
bsr change.colours setup the guardian colours
move.w #6*72,guard.offset(a5) changes the missiles
respf2
move.l 12(a4),d2 get the foreground plane
move.l 16(a4),d3 pointers and add the offset to
move.l 20(a4),d4 them
addq.w #2,pf2offset(a5)
add.w pf2offset(a5),d2 store these in the copper list
add.w pf2offset(a5),d3
add.w pf2offset(a5),d4
storepf2
move.w d2,30(a1)
move.w d3,38(a1)
move.w d4,46(a1)
bra storescroll
**************************************************************************
flipbgnd
lea copperlist(pc),a1 swap the background displays
lea displayraster(a5),a3 every second frame
move.l (a3),d4
move.l 4(a3),d5
move.l 8(a3),d6
move.l 12(a3),(a3)
move.l 16(a3),4(a3)
move.l 20(a3),8(a3)
move.l d4,12(a3)
move.l d5,16(a3)
move.l d6,20(a3)
addq #4,d4 add 4 bytes (32 pixels) to the
addq #4,d5 pointers so that clipping can
addq #4,d6 be carried out on the left
move.w d4,6(a1) hand side
swap d4
move.w d4,2(a1) store the new ones in the copper
move.w d5,14(a1) list
swap d5
move.w d5,10(a1)
move.w d6,22(a1)
swap d6
move.w d6,18(a1)
not.b screen.num(a5)
rts
**************************************************************************
drawfgnds
cmp.w #3,level.end(a5) 3 for guardian fully on
beq return
cmp.w #2,level.end(a5) 2 for drawing guardian
beq draw.guardian
tst.w pf2scroll(a5) every 16 pixels a new strip
beq drawbegin of foreground graphics are
cmp.w #$e,pf2scroll(a5) drawn into a hidden part
beq drawend of the screen
rts
drawbegin
bsr setupblit
clr.l d6 d6 = offset into the screen
move.l fgndpointer(a5),a0 for the start of the screen
bsr drawfgnd this will be zero
subq #1,a0
move.l a0,fgndpointer(a5)
rts
drawend
bsr setupblit
moveq #46,d6 as the screen is 46 bytes
move.l fgndpointer(a5),a0 wide, this is the offset
cmp.b #$ff,(a0) at which to draw the strip
bne drawfgnd
sub.w #12,a0 the end of map is flagged
move.l a0,fgndpointer(a5) by an FF block number
move.w #1,level.end(a5) flag the end of the map
drawfgnd
clr.l d0
move.b (a0)+,d0 d0 = block number (0-254)
lea rasters(a5),a4 get the current foreground
move.l 12(a4),d1 plane pointers in d1,d2,d3
move.l 16(a4),d2
move.l 20(a4),d3
add.l d6,d1 add the offset passed
add.l d6,d2
add.l d6,d3
add.w pf2offset(a5),d1 add the scrolled words
add.w pf2offset(a5),d2 offset to each plane
add.w pf2offset(a5),d3
moveq #11,d7 12 blocks in height
move.l #graphics,a4 a4 = base address of the graphics
fgndloop
move.l a4,d4
mulu #96,d0 96 bytes per graphic blocks
ext.l d0 (2 bytes wide x 16 high
add.l d0,d4 x 3 planes)
bsr blitfgnd
add.l #ForegroundWidth*16,d1 work out address of 16 scanlines
add.l #ForegroundWidth*16,d2 down
add.l #ForegroundWidth*16,d3
clr.l d0
move.b (a0)+,d0 get next block number
dbf d7,fgndloop and repeat for all 12
rts
blitfgnd
move.l d1,bltdpt(a6) blit a 16x16 pixel block
move.l d4,bltapt(a6) into the foreground screen
move.w #$0401,bltsize(a6) unmasked with no shift
add.l #32,d4
move.l d2,bltdpt(a6)
move.l d4,bltapt(a6)
move.w #$0401,bltsize(a6)
add.l #32,d4
move.l d3,bltdpt(a6)
move.l d4,bltapt(a6)
move.w #$0401,bltsize(a6)
rts
setupblit
move.w #$09f0,bltcon0(a6) minterm for D = A
clr.w bltcon1(a6)
clr.w bltamod(a6) data is stored sequentially
move.w #ForegroundWidth-2,bltdmod(a6)
rts
**************************************************************************
buildbackgnd
lea rasters(a5),a0
move.l (a0),a1 get the background plane pointers
move.l 4(a0),a2 in a1-a4 (double buffered so 2 sets)
move.l 24(a0),a3 background graphics are only 4 colour
move.l 28(a0),a4 (2 planes) so third plane is ignored
addq #4,a1 skip the hidden words used for
addq #4,a2 clipping
addq #4,a3
addq #4,a4
move.l #backgroundtable,a0 a0 = the background map
move.w level.number(a5),d0
mulu #144,d0 144 bytes per background map
add.w d0,a0
moveq #11,d0 12 blocks high
build1 moveq #11,d1 24 blocks across
movem.l a1-a4,-(sp)
build2 move.b (a0),d2 this loop draws 2 across
lsr.b #4,d2 block number stored in 4 bits
bsr drawback
move.b (a0)+,d2
and.b #$f,d2
tst.w d1
beq skipit
bsr drawback
skipit dbf d1,build2 do all 24 across
movem.l (sp)+,a1-a4
add.l #BackgroundWidth*16,a1 next block down the way
add.l #BackgroundWidth*16,a2
add.l #BackgroundWidth*16,a3
add.l #BackgroundWidth*16,a4
dbf d0,build1 do all 12 high
move.l #$dff000,a6
rts
drawback
lea backgrounds,a6 a6 = the background graphics
move.w level.number(a5),d3
mulu #1024,d3 1024 bytes per level of background
add.w d3,a6 graphics (16 blocks)
and.w #$f,d2
mulu #64,d2 64 bytes per block
add.l d2,a6 (2 bytes x 16 high x 2 planes)
movem.l a1-a4,-(sp)
moveq #15,d3
drawb1 move.w (a6),(a1) draw into both the screens
move.w (a6),(a3)
move.w (a6),46(a1)
move.w (a6),46(a3)
move.w 32(a6),(a2)
move.w 32(a6),(a4)
move.w 32(a6),46(a4)
move.w 32(a6),46(a2)
add.w #BackgroundWidth,a1
add.w #BackgroundWidth,a2
add.w #BackgroundWidth,a3
add.w #BackgroundWidth,a4
addq #2,a6
dbf d3,drawb1
movem.l (sp)+,a1-a4
addq #2,a1 next block along
addq #2,a2
addq #2,a3
addq #2,a4
rts
**************************************************************************
GameInit
lea map,a0
move.l a0,fgndpointer(a5) set up the map index
move.w #23,pf1count(a5) width of the foreground in words
move.w #24,pf2count(a5) width of the background in words
move.w #15,pf1scroll(a5) initial scroll value
move.w #15,pf2scroll(a5)
move.w #100,xpos(A5) ships initial x,y & speed
move.w #80,ypos(a5)
move.w #2,ship.speed(a5)
move.w #1,mult.number(a5)
move.l #ship1.2,shipaddress(a5) setup address of initial ship
move.w #10,path.delay(a5)
move.w #5,bonus.count(a5)
move.w #128,ship.energy(a5)
move.w #$ffff,ship.count(a5)
move.w #324-12,d0
bsr max.energy
move.l #explosion.sequence,explosion.ptr(a5)
move.l #guardian+384,guardian.data(a5)
move.w #999,guardian.count(a5)
lea copperlist(pc),a1
lea rasters(a5),a0
move.w (a0),2(a1) copy the plane adresses into the
move.w 2(a0),6(a1) copperlist
move.w 4(a0),10(a1)
move.w 6(a0),14(a1)
move.w 8(a0),18(a1)
move.w 10(a0),22(a1)
move.w 12(a0),26(a1)
move.w 14(a0),30(a1)
move.w 16(a0),34(a1)
move.w 18(a0),38(a1)
move.w 20(a0),42(a1)
move.w 22(a0),46(a1)
addq.w #4,6(a1) skip the hidden words in the
addq.w #4,14(a1) background
addq.w #4,22(a1)
lea scroll.value(pc),a0
move.w #$ff,2(a0)
move.l #panel+32,d0 put the address of the panel
lea rastersplit2(pc),a1 graphics into the copper
moveq #3,d1 the panel is 4 planes
setup1 move.w d0,6(a1)
swap d0
move.w d0,2(a1)
swap d0
add.l #1408,d0 panel size is 352x32 (1408 bytes
addq #8,a1 per plane)
dbf d1,setup1
lea level.colours(pc),a0 copy the level colours into the
lea colours(pc),a1 copperlist
moveq #31,d0
.copy move.w (a0)+,2(a1)
addq #4,a1
dbf d0,.copy
lea panel.colours(pc),a0 copy the panel colours into the
lea colours2(pc),a1 copperlist
moveq #15,d0
.copy2 move.w (a0)+,2(a1)
addq #4,a1
dbf d0,.copy2
bsr ship.to.copper setup the hardware sprite pointers
bsr clear.screen
bsr buildbackgnd and draw the background
bsr setup.mouse
IFNE FullFirepower
st.b mult1.on(a5)
st.b mult2.on(a5)
st.b canons.on(a5)
st.b lasers.on(A5)
move.w #2,ship.speed(A5)
move.b #3,ship.status(a5)
bsr change.ship
ENDC
rts
clear.screen
move.l rasters(a5),a0 clear all the screen memory
move.w #MemNeeded/4-1,d0
clear.scr1
clr.l (a0)+
dbf d0,clear.scr1
rts
**************************************************************************
check.collision
tst.b ship.dead(a5) no action taken if he's dead
bne return
move.w clxdat(a6),d0 get collison value in d0
bsr collect.bonus check if bonus mode
and.w #$46,d0
beq return no collision, so return
tst.w field.count(a5) is force field on
bne return
cmp.b #3,last.path(a5) is guardian dead
beq return
move.w ship.count(a5),d2
and.w #$6,d0 bits 1 & 2 of clxdat for background
beq check3
tst.b last.path(a5)
beq normal.value decrease by 8 if guardian path
normal.value
lsr.w #5,d2
bcc shield.decrease
no.decrease
move.w d2,ship.count(a5)
rts
check3
cmp.w #2,level.end(a5)
bge foreground.hit guardian always deadly
tst.w difficulty(a5)
beq return no effect on easy level
foreground.hit
lsr.w #3,d2 on level. This is less than for
bcs no.decrease alien collisons
shield.decrease
subq.w #2,ship.energy(a5) bit 5 of clxdat for foreground
move.w ship.energy(a5),d1
bmi explode if shield <0 start the explosion
move.w #$ffff,ship.count(a5) reset secondary count
move.w #324-12,d0
bra decrease.energy
explode
st ship.dead(a5) flag ship dead
move.w xpos(a5),d4
move.w ypos(a5),d5
clr.l d0 return longword in do
add.w #44,d5 hardware offset vertical
lsl.w #8,d5 into bits 8-15
add.w #128,d4 horizontal offset
lsr.w #1,d4 /2 low bit into extend
or.w d5,d4 X intact
move.w d4,d0 X still intact
swap d0 ditto
roxl.w #1,d0 get low bit of hstart into bit 0
add.w #$1800,d5 calcualate vstop (+24 lines)
or.w d5,d0 low word set up
move.l d0,d1
move.l d0,d2
add.l #$00080000,d1 3 sprites for the explosion
add.l #$00100000,d2 so each is 16 pixels apart
lea ship.explosion,a1
moveq #9,d7
setup.sprite
move.l d0,(a1) store the new coords in the ten
move.l d1,104(a1) explosion animations
move.l d2,208(a1)
add.l #312,a1
dbf d7,setup.sprite
lea colours(pc),a0
move.w #$fd0,70(a0) copy the explosion colours into
move.w #$fd0,86(a0) the copper
move.w #$f80,74(a0)
move.w #$f80,90(a0)
move.w #$c21,78(a0)
move.w #$c21,94(a0)
explode.ship
addq.w #1,explosion.delay(a5)
and.w #%11,explosion.delay(a5)
bne return
move.l explosion.ptr(a5),a0 points to an animation sequence
clr.w d0 ended by 255
move.b (a0)+,d0
bmi game.over
move.l a0,explosion.ptr(a5)
move.l #ship.explosion,d1
mulu #312,d0 work out the next sprite address
add.l d0,d1
lea sprite(pc),a0
moveq #2,d0
explode1
move.w d1,6(a0) and put it in the copper
swap d1
move.w d1,2(a0)
swap d1
add.w #104,d1
addq.l #8,a0
dbf d0,explode1
clr.w 2(a0) make sure outriders are not
clr.w 6(a0) displayed
rts
game.over
st.b kill.game(a5)
rts
collect.bonus
move.w d0,d1
and.w #$6,d1 was it a foreground hit
beq return if so no bonus
tst.b bonus.mode(a5)
beq return
move.w bonus.num(a5),d1
beq bonus.score
cmp.w #1,d1
beq max.canons
cmp.w #2,d1
beq max.lasers
cmp.w #3,d1
beq increase.speed
cmp.w #4,d1
beq attach.mult
cmp.w #5,d1
beq force.field
addq.b #1,num.shields(a5)
move.w #324-12,d0 final one is full shields
move.w #128,ship.energy(a5)
bsr max.energy
bra collect.end
bonus.score
move.l #$1000,score.add(a5)
bra collect.end
max.canons
addq.b #1,num.canons(a5)
tst.b canons.on(a5) attach canons or power them up
beq attach1
move.w #676-12,d0
move.w #128,canon.energy(a5)
bsr max.energy
bra collect.end
attach1
st canons.on(a5) activate canons
addq.b #1,ship.status(a5)
bsr change.ship
bra collect.end
max.lasers
addq.b #1,num.lasers(a5)
tst.b lasers.on(a5)
beq attach2
move.w #1028-12,d0
move.w #128,laser.energy(a5)
bsr max.energy
bra collect.end
attach2
st lasers.on(a5)
addq.b #2,ship.status(a5)
bsr change.ship
bra collect.end
increase.speed
cmp.w #8,ship.speed(a5)
beq collect.end
addq.b #1,num.speedups(a5)
addq.w #1,ship.speed(a5) pixel speed between
bra collect.end 1 & 7 only
force.field
addq.b #1,num.fields(a5)
move.w #768,field.count(a5) set up the force field count
move.w #$f,colours+74 make ship outline blue
bra collect.end
attach.mult
tst.b mult1.on(a5) attach outriders
bne attach.mult2
st mult1.on(a5)
addq.b #1,num.outriders(a5)
bra collect.end
attach.mult2
addq.b #1,num.outriders(a5)
st mult2.on(a5)
collect.end
clr.w d0 no collison
move.l #path.buffer,a0
clr.w x.pos(a0) reset the bonus path
clr.b bonus.mode(a5)
move.w #$ffff,ship.count(a5)
rts
max.energy
move.l #panel,a0 d0 = offset
add.w d0,a0
moveq #7,d1
max.loop
or.w #$5555,(a0) set all energy bits
or.w #$5555,44(a0)
or.w #$5555,88(a0)
addq #2,a0
dbf d1,max.loop
rts
moveship
tst.b ship.dead(a5)
bne explode.ship
tst.w field.count(a5)
beq no.field
move.w #$f,colours+74
subq.w #1,field.count(a5) decrement the force field
bne no.field
clr.w colours+74 outline back to black
no.field
btst #1,field.count+1(a5) check lsb
beq no.field2
move.w #$00c,colours+74
no.field2
bsr joy read joystick & mouse
tst.w ypos(a5) upper y limit of 0
bge up.ok
clr.w d0 reset up flag if not allowed
clr.w yvector(a5) and no y movement
up.ok cmp.w #150,ypos(a5) maximum y value is 150
ble down.ok
clr.w d1 if at max signal down no more
clr.w yvector(a5)
down.ok tst.w xpos(a5) minimum x position is 0
bge left.ok
clr.w d3
clr.w xvector(a5)
left.ok cmp.w #266,xpos(a5) maximum x position is 266
ble right.ok
clr.w d2
clr.w xvector(a5)
right.ok
move.w ship.speed(a5),d4 d4 = ship speed
move.w d4,d5 d5 = -ve ship speed
neg.w d5
clr.w up.down(a5) make ship untilt
move.w yvector(a5),d7 change the y vector first
up tst.w d0 are we going up?
beq down no, so check down
move.w #-560,up.down(a5) yes, so tilt ship up (anims 560 bytes apart)
cmp.w d7,d5 are we at max y speed
beq right yes, so go and check x movement
subq.w #1,d7 no, so decrease the vector
bra right
down tst.w d1 are we going down?
beq right no, so check right
move.w #560,up.down(a5) yes, so tilt the ship down
cmp.w d7,d4 are we at max y speed
beq right yes, so check x movement
addq.w #1,d7 no, so increase the y vector
right move.w d7,yvector(a5) store the new y vector
move.w xvector(a5),d7
clr.w d6 now do the x vector which is
tst.w d2 virtually identical to the y above
beq left
moveq #1,d6
cmp.w d7,d4
beq add.vectors
addq #1,d7
bra add.vectors
left tst.w d3
beq add.vectors
moveq #-1,d6
cmp.w d7,d5
beq add.vectors
subq #1,d7
add.vectors
move.w d7,xvector(a5)
or.w d2,d3 if we have moved left or right we
bne checky may have to alter the animation
move.w #4,mult.delay(a5) of the multiples
moveq #1,d7 if the ship is not being moved but
tst.w xvector(a5) still has some inertia then decrease
beq checky the x & y vectors until they hit 0
bmi xto0
neg.w d7
xto0 add.w d7,xvector(a5)
checky or.w d0,d1
bne add.vectors2
moveq #1,d7
tst.w yvector(a5)
beq add.vectors2
bmi yto0
neg.w d7
yto0 add.w d7,yvector(a5)
add.vectors2
move.w xpos(a5),d4 finally add the new vectors to
move.w ypos(a5),d5 the x & y coordinates
add.w xvector(a5),d4
add.w yvector(a5),d5
move.w d4,xpos(a5)
move.w d5,ypos(a5)
bsr xytosprite convert the xy coords into
move.l shipaddress(a5),a0 hardware sprite format
add.w up.down(a5),a0 add the up/down offset
* now set up the four hardware sprite control words
move.l d0,(a0) ship 1.1 (rear end)
bset #7,d0
move.l d0,184(a0) ship 1.2 with attach bit set
add.l #$0b080000,d0 add 11 to vstart & 16 to hstart
bclr #7,d0 reset attach bit
sub.w #$0b00,d0 vstop is 11 less
move.l d0,2*184(a0) ship 1.3 (front)
bset #7,d0 set attach
move.l d0,2*184+96(a0) ship 1.4
bsr ship.to.copper put the address of the current
subq.w #1,mult.delay(a5) ship in the copper
bne same.outrider and finally work out which multiple
move.w #4,mult.delay(a5) to display
add.w d6,mult.number(a5) outriders must be between
bne max.mult 1 & 5
move.w #1,mult.number(a5)
max.mult
cmp.w #6,mult.number(a5)
bne same.outrider
move.w #5,mult.number(a5)
same.outrider
bsr draw.outrider draw the multiple into the sprite
bra check.firekey
**************************************************************************
xytosprite
* d4 = x coordinate
* d5 = y coordinate
* returns d0.l as the control words
clr.l d0 return longword in do
add.w #44-11,d5 hardware offset vertical
lsl.w #8,d5 into bits 8-15
add.w #128,d4 horizontal offset
lsr.w #1,d4 /2 low bit into extend
or.w d5,d4 X intact
move.w d4,d0 X still intact
swap d0 ditto
roxl.w #1,d0 get low bit of hstart into bit 0
add.w #$2c00,d5 calcualate vstop (+44 lines)
or.w d5,d0 low word set up
rts
**************************************************************************
draw.outrider
move.w mult.number(a5),d0 get the animation number
tst.b mult1.on(a5) for the multiple
bne mult1ok
clr.w d0
mult1ok
lea outriders,a0 base address of outriders
mulu #44,d0 44 bytes per plane for pair
add.w d0,a0
move.l a0,a1 a0 = plane 1
add.w #264,a1 a1 = plane 2
move.l shipaddress(a5),a2 current ship address
add.w up.down(a5),a2
addq #4,a2 get past sprite header
movem.l a0-a2,-(sp)
moveq #10,d7 11 lines high
out1 move.w (a0)+,(a2)+
move.w (a1)+,(a2)+
dbf d7,out1
tst.b mult2.on(a5)
bne mult2ok
lea outriders,a0 if mult 2 not on then
move.l a0,a1 point the data to zeroes
mult2ok
add.w #22*2*2,a2 pass the ship graphics
moveq #10,d7 and draw the bottom one
out2 move.w (a0)+,(a2)+
move.w (a1)+,(a2)+
dbf d7,out2 planes 1 & 2 done
movem.l (sp)+,a0-a2 get back pointers
add.w #528,a0 a0 = plane 3
add.w #528,a1 a1 = plane 4
add.w #44*4+8,a2 next sprite
moveq #10,d7 11 lines high
out3 move.w (a0)+,(a2)+
move.w (a1)+,(a2)+
dbf d7,out3
tst.b mult2.on(a5)
bne mult3ok
lea outriders,a0 if mult 2 not on then
move.l a0,a1 point the data to zeroes
mult3ok
add.w #22*2*2,a2 pass the ship graphics
moveq #10,d7 and draw the bottom one
out4 move.w (a0)+,(a2)+
move.w (a1)+,(a2)+
dbf d7,out4 planes 3 & 4 done
rts
**************************************************************************
check.firekey
bsr get.firekey
bne fire
clr.b firekey(a5)
rts
fire tst.w fire.delay(a5)
bne fire.end
move.w #firedelay,fire.delay(a5)
tst.b firekey(a5)
beq test.missiles
rts
fire.end
move.w #firedelay,fire.delay(a5)
rts
get.firekey
move.b PortA,d0
not.b d0
and.b #$c0,d0
rts
shift.coords
lea xpos(a5),a2
move.w 16(a2),20(a2)
move.w 18(a2),22(a2)
move.w 12(a2),16(a2)
move.w 14(a2),18(a2)
move.w 8(a2),12(a2)
move.w 10(a2),14(a2)
move.w 4(a2),8(a2)
move.w 6(a2),10(a2)
move.w (a2),4(a2)
move.w 2(a2),6(a2)
rts
test.missiles
st firekey(a5)
clr.w d0 0 for missile sound only
tst.w canon.energy(a5)
sne d1
and.w #1,d1 1 for canons only
tst.w laser.energy(a5)
sne d2
and.w #2,d2 2 for lasers only
add.w d1,d0
add.w d2,d0 3 for all
; lea effects(pc),a0
; move.b 0(a0,d0.w),d0
; jsr initfx
moveq #3,d7
fire3 btst d7,activemissiles(a5)
beq initmissile
dbf d7,fire3
test.canon
tst.b canons.on(a5)
beq test.lasers
tst.w canon.energy(a5)
beq test.lasers
moveq #2,d7
fire1 btst d7,activecanons(a5)
beq initcanon
dbf d7,fire1
test.lasers
tst.b lasers.on(a5)
beq test.mult1
tst.w laser.energy(a5)
beq test.mult1
moveq #2,d7
fire4 btst d7,activelasers(a5)
beq initlaser
dbf d7,fire4
test.mult1
tst.b mult1.on(a5)
beq test.mult2
moveq #1,d7
fire5 btst d7,activemult1(a5)
beq init.mult1
dbf d7,fire5
test.mult2
tst.b mult2.on(a5)
beq fire7
moveq #1,d7
fire6 btst d7,activemult2(a5)
beq init.mult2
dbf d7,fire6
fire7
rts
init.mult1
bset d7,activemult1(a5)
lea mult1data(a5),a0
lsl.w #3,d7
add.w d7,a0
move.w xpos(a5),d0
add.w #38,d0
move.w d0,(a0)+
move.w ypos(a5),d0
addq #6,d0
move.w d0,(a0)+
move.w mult.number(a5),d0
subq.w #1,d0
lsl.w #1,d0
lea mult1offsets(pc),a1
move.b 0(a1,d0.w),(a0)+
move.b 1(a1,d0.w),(a0)+
move.w #16,(a0)+
bra test.mult2
init.mult2
bset d7,activemult2(a5)
lea mult2data(a5),a0
lsl.w #3,d7
add.w d7,a0
move.w xpos(a5),d0
add.w #38,d0
move.w d0,(a0)+
move.w ypos(a5),d0
add.w #40,d0
move.w d0,(a0)+
move.w mult.number(a5),d0
subq.w #1,d0
lsl.w #1,d0
lea mult2offsets(pc),a1
move.b 0(a1,d0.w),(a0)+
move.b 1(a1,d0.w),(a0)+
move.w #16,(a0)+
rts
initmissile
bset d7,activemissiles(a5)
lea missiledata(a5),a0
lsl.w #3,d7
add.w d7,a0
move.w xpos(a5),d0
add.w #58,d0
move.w d0,(a0)+
move.w ypos(a5),d0
add.w #24,d0
move.w d0,(a0)+
move.w #16,(a0)+
bra test.canon
initcanon
bset d7,activecanons(a5)
lea canondata(a5),a0
lsl.w #3,d7
add.w d7,a0
move.w xpos(a5),d0
add.w #53,d0
move.w d0,(a0)+
move.w ypos(a5),d0
add.w #30,d0
move.w d0,(a0)+
move.w #12,(a0)+
move.w #676,d0
subq.w #2,canon.energy(a5)
move.w canon.energy(a5),d1
bsr decrease.energy
bra test.lasers
initlaser
bset d7,activelasers(a5)
lea laserdata(a5),a0
lsl.w #3,d7
add.w d7,a0
move.w xpos(a5),d0
add.w #42,d0
move.w d0,(a0)+
move.w ypos(a5),d0
add.w #14,d0
move.w d0,(a0)+
move.w #32,(a0)+
move.w #1028,d0
subq.w #2,laser.energy(a5)
move.w laser.energy(a5),d1
bsr decrease.energy
bra test.mult1
decrease.energy
move.l #panel,a1 d0 = offset
add.w d0,a1 d1 = energy value (0-128)
; 324 for ship energy
; 676 for canons
lsr.w #4,d1 1028 for lasers
lsl.w #1,d1 a1 = plane1
add.w d1,a1
move.w (a1),d1
move.w d1,d2
and.w #$5555,d1 get energy bits only
and.w #$aaaa,d2 preserve panel bits
lsl.w #2,d1 shift into next space
or.w d1,d2
move.w d2,(a1)
add.w #44,a1
move.w (a1),d2
and.w #$aaaa,d2
or.w d1,d2 new energy into panel
move.w d2,(a1)
add.w #44,a1
move.w (a1),d2
and.w #$aaaa,d2
or.w d1,d2
move.w d2,(a1)
rts
**************************************************************************
setup.mouse
move.w joy0dat(a6),d4 read the mouse x,y position so
move.w d4,-(sp)
and.w #$ff,d4 the ship doesnt jump when we
move.w d4,oldmousex(a5) start
move.w (sp)+,d4
lsr.w #8,d4
move.w d4,oldmousey(a5)
rts
joy move.w #$0100,d0 setup the mask for each bit in
move.w #$0001,d1 the joystick register
move.w #$0002,d2 the routine returns left/right
move.w #$0200,d3 /up/down in d0..d3
move.w joy1dat(a6),d4 if the corresponding data register
and.w d4,d0 is not = 0 then the joystick
and.w d4,d1 had been pressed in that direction
and.w d4,d2
and.w d4,d3
lsl.w #1,d0
lsl.w #1,d1
eor.w d2,d1
eor.w d3,d0
move.w joy0dat(a6),d4 read the mouse counters, if a move
move.w d4,-(sp) has been detected then set the
and.w #$ff,d4 appropiate joystick registers
sub.w oldmousex(a5),d4 to mimick a joystick move
beq noxmove
bmi leftmove this is not a proper proportional
moveq #1,d2 read but a simple up/dowm/left/right
bra noxmove check
leftmove
moveq #1,d3
noxmove move.w (sp),d4
lsr.w #8,d4
sub.w oldmousey(a5),d4
beq joyend
bmi upmove
moveq #1,d1
bra joyend
upmove moveq #1,d0
joyend move.w (sp),d4
and.w #$ff,d4
move.w d4,oldmousex(a5) save the mouse values for comparison
move.w (sp)+,d4 next time around
lsr.w #8,d4
move.w d4,oldmousey(a5)
rts
**************************************************************************
ship.to.copper
move.l shipaddress(a5),a1 get the current ship address
add.w up.down(a5),a1 and update the four sprite
move.l a1,d0 pointers in the copperlist
move.l a1,d1
move.l a1,d2
move.l a1,d3
add.w #184,d1 work out the address of each
add.w #184*2,d2 hardware sprite
add.w #184*2+96,d3
lea sprite(pc),a0
move.w d0,6(a0)
swap d0
move.w d0,2(a0)
move.w d1,14(a0)
swap d1
move.w d1,10(a0)
move.w d2,22(a0)
swap d2
move.w d2,18(a0)
move.w d3,30(a0)
swap d3
move.w d3,26(a0)
rts
**************************************************************************
change.ship
clr.w d0
move.b ship.status(a5),d0 1 = canons, 2 = lasers, 3 = both
lea ship1.2(pc),a0
mulu #1680,d0 968 bytes for the four sprites
add.l d0,a0 per ship
move.l a0,shipaddress(a5) store the ship address
rts
**************************************************************************
restorebgnds
bsr getscreeninfo
clr.w bltamod(a6)
move.l d0,bltapt(a6) set blitter A channel to the saved
clr.w bltcon1(a6) background data
restoreloop
move.w (a0)+,d1 fetch the blit size
beq return once zero all have been replaced
move.w d1,d3
addq #2,a0
and.w #$3f,d1 work out the length in bytes
lsl.w #1,d1
move.w #100,d2 subtract from the screen width
sub.w d1,d2 to give the destination modulo
move.w d2,bltdmod(a6)
move.w #$09f0,bltcon0(a6) use D = A for the blit
move.l (a0)+,bltdpt(a6) and do all three planes.
move.w d3,bltsize(a6)
move.l (a0)+,bltdpt(a6)
move.w d3,bltsize(a6)
move.l (a0)+,bltdpt(a6)
move.w d3,bltsize(a6)
bra restoreloop
savebgnds
bsr check.end.screen watch out for screen wraparound
bsr coords.to.pf1offsets convert pixel coords to byte offsets
move.w #aliensize,d3
move.w #94,bltamod(a6)
clr.w bltdmod(a6)
clr.w bltcon1(a6)
move.w #$09f0,bltcon0(a6) use D = A for the blit
bsr setup.addresses save the blitsize and addresses
bsr blit.to.buffer and save the background data
rts
**************************************************************************
drawbobs
move.w #94,bltdmod(a6) set up the destination modulos
move.w #94,bltcmod(a6)
clr.l d6 d6 will hold an offset if the
tst.b upsidedown(a5) bob is drawn upside down
beq normal
move.w #-106,bltdmod(a6) draw from the bottom up by using
move.w #-106,bltcmod(a6) a negative modulo
move.l #23*100,d6
normal move.w (a0),d3 get the blitsize in d3
move.w 2(a0),d1 the scroll value in d1 (0-15)
ror.w #4,d1
move.w d1,bltcon1(a6) set up the B scroll value
or.w #$0fca,d1 set up the A scroll value and the
move.w d1,bltcon0(a6) minterm for D = notA.C + B
move.w #-2,bltbmod(a6)
move.w #-2,bltamod(a6)
move.l a1,bltbpt(a6)
bsr blit.to.backgnd draw to the screen
rts
**************************************************************************
getscreeninfo
* returns the address in a0 of the data listing the screeen locations
* where the backgrounds have to be replaced
* d0 points to the buffer containing the saved backgrounds
tst.b screen.num(a5) double buffering means we have
bne getscreen1 to have two lists running
move.l #buffer0,d0
move.l #screen0bgnds,a0
rts
getscreen1
move.l #buffer1,d0
move.l #screen1bgnds,a0
rts
**************************************************************************
process.aliens
clr.w all.coords(a5)
move.l #path.buffer,a0
lea alien.buffer(a5),a1 where to store the info
moveq #11,d7 12 aliens max
process.loop
move.w table.offset(a0),d0 get offset in d0
move.b mode(a0),d6 d6 contains the mode byte
move.w x.pos(a0),d1
beq finished alien dead
clr.w last.x(a5)
clr.w last.y(a5)
move.w y.pos(a0),d2
subq.b #1,anim.delay(a0)
bne same.anim
move.b num.anims(a0),d3
beq same.anim
btst #3,d6
beq up.only
btst #4,d6
bne down.anim
addq.b #1,anim.num(a0) increase anim num
cmp.b anim.num(a0),d3
bne process1
bchg #4,d6
bra process1
down.anim
subq.b #1,anim.num(a0)
bpl process1
move.b #1,anim.num(a0)
bchg #4,d6
bra process1
up.only
addq.b #1,anim.num(a0) next animation
addq.b #1,d3
cmp.b anim.num(a0),d3 wrap around anims
bne process1
clr.b anim.num(a0)
tst.b sprite.num(a0) was it an explosion
bne process1
clr.w x.pos(a0) yes so
move.w d1,last.x(a5) store its coords
move.w d2,last.y(a5)
clr.w d1 kill this alien
bra finished
process1
move.b anim.delay2(a0),anim.delay(a0) restore the delay
same.anim
tst.b sprite.num(a0)
beq finished dont move explosions
tst.b pause.count(a0)
beq no.pause no pause
cmp.b #$ff,pause.count(a0)
beq finished ff means pause forever...
subq.b #1,pause.count(a0)
beq update if zero update the offset
bra finished not zero so do nufink
no.pause
clr.w d3
clr.w d4
clr.w d5
move.b speed(a0),d5 speed in d5
move.b 0(a0,d0.w),d3 d3 is the x coord to go to
move.b 1(a0,d0.w),d4 d4 is the y coord to go to
bsr check.seek check all seek bits
tst.b sprite.num(a0)
beq store.coords a heat seeker may have exploded
btst #0,d6 test for offset mode
bne add.offsets
tst.w d3 if x goto is minus then
bmi check.y leave x coord alone
lsl.w #1,d3 even coord only
cmp.w d3,d1 check difference between the
sne x.equal(a5) two x coords
beq check.y
blt increase.x if d1<d3 then increase x
sub.w d5,d1 else decrease it
cmp.w d3,d1 has it now passed
bgt check.y the x coord
move.w d3,d1 if so, make it equal to the x
sf x.equal(a5)
bra check.y
increase.x
add.w d5,d1
cmp.w d3,d1
blt check.y is it still less than x
move.w d3,d1
sf x.equal(a5)
check.y tst.w d4
bmi store.coords check wether to leave y alone
lsl.w #1,d4
cmp.w d4,d2 compares d2 to d4
sne y.equal(a5)
beq store.coords
blt increase.y if d2<d4 then increase y
sub.w d5,d2
cmp.w d4,d2
bgt store.coords
move.w d4,d2
sf y.equal(a5)
bra store.coords
increase.y
add.w d5,d2
cmp.w d4,d2
blt store.coords
move.w d4,d2
sf y.equal(a5)
bra store.coords
add.offsets
ext.w d3
ext.w d4
add.w d3,d1 add the offsets
add.w d4,d2
clr.b x.equal(a5) signal to update table
clr.b y.equal(a5)
store.coords
move.w d1,x.pos(a0) restore the new coords
move.w d2,y.pos(a0)
move.b x.equal(a5),d3
or.b d3,y.equal(a5) is the alien there
bne finished no, so dont update the table
btst #5,d6 heat seeker ?
beq update
bsr explode.alien heat seekers explode when they
bra finished hit their target
update
btst #1,d6 check for seek mode
beq new.offset
bsr copy.coords
subq.b #1,seek.count(a0)
bne finished
bclr #1,d6 reset seek mode
new.offset
addq.w #2,d0
move.w d0,table.offset(a0) new offset
tst.w 0(a0,d0.w)
beq path.finished path finished, so branch
move.b 0(a0,d0.w),d4 get code in d4 & d3
move.w d4,d3
and.w #$f0,d4 get upper 4 bits
cmp.w #$e0,d4 hex E for a code
bne finished no code so carry on
and.w #$f,d3 otherwise get code number in d3
lsl.w #2,d3 x4
lea vector.table(pc),a2 get table base
move.l 0(a2,d3.w),a2 get routine address in a2
jmp (a2) and jump to it
vector.table
dc.l init.pause
dc.l loop.back
dc.l toggle.offset
dc.l change.speed
dc.l change.sprite
dc.l seek.mode
dc.l reload.coords
dc.l new.table
dc.l restore.offset
dc.l fire.heatseeker
dc.l change.anim
dc.l restart.table
dc.l start.xy
dc.l start.seekx
dc.l start.seeky
dc.l return 16 codes maximum
finished
or.w d1,all.coords(a5)
move.w d1,(a1)+
move.w d2,(a1)+ store it all in the
move.b sprite.num(a0),(a1)+ buffer
move.b anim.num(a0),(a1)+
move.b d6,mode(a0) save the mode byte
add.w next.path(a0),a0
dbf d7,process.loop
rts
path.finished
clr.w d1 make x = 0
clr.w x.pos(a0)
btst #2,d6
seq no.bonus(a5)
bra finished
check.seek
btst #6,d6 bit 6 for seek on ship x
beq check.seeky
st y.equal(a5) make sure it never updates table
move.w xpos(a5),d3 get new x coord to goto
moveq #-1,d4 signal to leave y alone
add.w #54,d3 hardware sprite offset
lsr.w #1,d3 even coords only
subq.b #1,seek.count(a0) check count
bne check.seeky
bclr #6,d6 reset if count zero
check.seeky
btst #7,d6 bit 7 for seek on ship y
beq check.heat
st x.equal(a5) make sure it never updates table
move.w ypos(a5),d4 get new y coord to goto
moveq #-1,d3 signal to leave x alone
add.w #14,d4 hardware sprite offset
lsr.w #1,d4 even coords only
subq.b #1,seek.count(a0) check count
bne check.heat
bclr #7,d6 reset if count zero
check.heat
btst #5,d6 bit 5 for a heat seeking mine
beq return all finished
move.w xpos(a5),d3 get new x coord to goto
move.w ypos(a5),d4 get new y coord to goto
add.w #56,d3 hardware sprite offset
add.w #16,d4 hardware sprite offset
lsr.w #1,d3 even coords only
lsr.w #1,d4 even coords only
subq.b #1,seek.count(a0) check count
bne return
bsr explode.alien kill mine if count zero
rts
init.pause
move.b 1(a0,d0.w),pause.count(a0) setup the pause
bra finished
loop.back
clr.w d3
move.b loop.offset(a0),d3 get the loop offset in words
lsl.w #1,d3 convert to bytes
subq.b #1,loop.count(a0) reduce the loop counter
beq update
sub.w d3,table.offset(a0) and work out the new path PC
bra finished
toggle.offset
bchg #0,d6 start or end offset mode
bra update get the next path value
seek.mode
bset #1,d6 set the seek mode bit
move.b 1(a0,d0.w),seek.count(a0) copy the count
addq.w #2,d0
move.w d0,table.offset(a0)
bsr copy.coords
bra finished
start.seekx
bset #6,d6 set the seek on X bit
move.b 1(a0,d0.w),seek.count(a0) copy the count
addq.w #2,d0
move.w d0,table.offset(a0)
bra finished
start.seeky
bset #7,d6 set the seek on Y bit
move.b 1(a0,d0.w),seek.count(a0) copy the count
addq.w #2,d0
move.w d0,table.offset(a0)
bra finished
copy.coords
move.w xpos(a5),d3 copy the ship coords
move.w ypos(a5),d4 for the seek functions
add.w #54,d3 into the path table
add.w #14,d4
lsr.w #1,d3
lsr.w #1,d4
move.b d3,0(a0,d0.w)
move.b d4,1(a0,d0.w)
rts
change.speed
move.b 1(a0,d0.w),speed(a0) copy the new speed byte
bra update
change.sprite
addq.w #2,d0
move.b 0(a0,d0.w),sprite.num(a0) new sprite number
move.b 1(a0,d0.w),num.anims(a0) new max anims
clr.b anim.num(a0)
move.b anim.delay2(a0),anim.delay(a0) new anim delay
bra update
reload.coords
addq #2,d0
clr.w d1 copy a new x,y position
clr.w d2 into the sprite structure
move.b 0(a0,d0.w),d1
move.b 1(a0,d0.w),d2
lsl.w #1,d1
lsl.w #1,d2
move.w d1,x.pos(a0)
move.w d2,y.pos(a0)
bra update
new.table
addq.w #2,d0 setup a new path PC
move.w d0,d4 saving the old one in the
move.b d4,loop.offset+1(a0) loop.offset word
lsr.w #8,d4
move.b d4,loop.offset(a0)
move.w 0(a0,d0.w),d0
subq.w #2,d0
bra new.offset
restore.offset
move.b loop.offset(a0),d0 restore the old path PC
lsl.w #8,d0
move.b loop.offset+1(a0),d0
bra new.offset
fire.heatseeker
move.l #path.buffer,a2 start a new path at the
moveq #11,d5 present paths x,y coord
addq #2,d0
heat1 btst #5,mode(a2) only if a free path entry
beq heat2 can be found
tst.w x.pos(a2)
bne heat2
move.w d1,x.pos(a2)
move.w d2,y.pos(a2)
move.b 0(a0,d0.w),seek.count(a2)
move.b 1(a0,d0.w),hits.num(a2)
move.b #2,sprite.num(a2)
move.b #2,anim.delay(a2)
clr.b anim.num(a2)
move.b #3,num.anims(a2)
bra new.offset
heat2 add.w (a2),a2
dbf d5,heat1
bra new.offset
change.anim
move.b 1(a0,d0.w),anim.num(a0) new animation number
bra new.offset
restart.table
move.w #table.size-2,d0 restart the path from the
bra update beginning
start.xy
move.b 1(a0,d0.w),d4 get path number to start
subq.b #2,d4 cant use path 0
move.l a0,-(sp) save path pointer
move.l #path.buffer,a0
find.num
add.w next.path(a0),a0
dbf d4,find.num get the path
move.w d1,x.pos(a0) new one starts at present x & y
move.w d2,y.pos(a0)
move.w d1,d4
lsr.w #1,d4
move.b d4,table.size(a0) set up the first xy coord to
move.w d2,d4 goto. Must be the same as
lsr.w #1,d4 the present xy
move.b d4,table.size+1(a0)
move.w #table.size,table.offset(a0) start of path
move.b #128,hits.num(a0) indistrutable
move.b #2,anim.delay(a0)
clr.b pause.count(a0)
clr.b anim.num(a0) reset anim info
move.l (sp)+,a0
bra new.offset
**************************************************************************
save.aliens
lea alien.buffer+66(a5),a4 the buffer contains
moveq #11,d7 word x-cord
bsr getscreeninfo word y-cord
save.alien1
move.w (a4),d1 byte sprite number
beq save.next byte animation number
move.w 2(a4),d2
bsr savebgnds
save.next
subq #6,a4
dbf d7,save.alien1
rts
**************************************************************************
draw.aliens
clr.w bltalwm(a6)
moveq #11,d7
bsr getscreeninfo
lea alien.buffer+66(a5),a4 work DOWN through
draw.alien2
tst.w (a4) the buffer so that the first
beq draw.next2 sprite is drawn first and
clr.w d1 therefore hit first.
clr.w d2
move.b 4(a4),d1 d1 = sprite number
bclr #7,d1
sne upsidedown(a5)
move.b 5(a4),d2 d2 = animation number
move.l #alien.pointers,a1
move.w level.number(a5),d3
mulu #24*4,d3
ext.l d3
add.l d3,a1
lsl.w #2,d1
add.w d1,a1
move.l (a1),a1 get the sprite pointer in a1
mulu #384,d2 from the lookup table
ext.l d2 and then work out the animation
add.l d2,a1 number address
move.l a1,a2
add.w #288,a2 a2 = mask address
bsr drawbobs
draw.next2
subq #6,a4
dbf d7,draw.alien2
move.w #$ffff,bltalwm(a6)
rts
**************************************************************************
blit.to.backgnd
addq #4,a0 skip the hidden words
move.l (a0)+,d5 get the screen offset
add.l d6,d5
move.l d5,bltcpt(a6) setup the screen pointers
move.l d5,bltdpt(a6)
move.l a2,bltapt(a6) setup the bob mask
move.w d3,bltsize(a6) and blit the bob to the screen
move.l (a0)+,d5
add.l d6,d5
move.l d5,bltcpt(a6)
move.l d5,bltdpt(a6)
move.l a2,bltapt(a6)
move.w d3,bltsize(a6) plane 2
move.l (a0)+,d5
add.l d6,d5
move.l d5,bltcpt(a6)
move.l d5,bltdpt(a6)
move.l a2,bltapt(a6)
move.w d3,bltsize(a6) plane 3
rts
**************************************************************************
blit.to.buffer
tst.l d6 copy the background where a
beq no.blit bob is to be drawn into
move.l d0,bltdpt(a6) the buffer
addq #4,a0
move.l (a0)+,bltapt(a6)
move.w d3,bltsize(a6)
move.l (a0)+,bltapt(a6)
move.w d3,bltsize(a6)
addq #4,a0
no.blit clr.w (a0)
add.l #3*6*24,d0
rts
**************************************************************************
coords.to.pf1offsets
* convert the x,y coordinate in d1,d2 into a byte offset
* in d1 and a scroll offset (0-15) in d2
add.w #16,d1
sub.w pf1scroll2(a5),d1 d2 = y coord
mulu #100,d2 d1 = x coord
swap d2
move.w d1,d2
and.w #$f,d2
swap d2
lsr.w #3,d1
add.w d2,d1
swap d2 d2 = scroll value
ext.l d1 d1 = offset
rts
**************************************************************************
coords.to.pf2offsets
* As the above routine but for the front playfield which is only
* 92 bytes wide
sub.w pf2scroll(a5),d1
mulu #92,d2
swap d2
move.w d1,d2
and.w #$f,d2
swap d2
lsr.w #3,d1
add.w d2,d1
swap d2
ror.w #4,d2
add.w pf2offset(a5),d1
ext.l d1
rts
**************************************************************************
setup.addresses
* setup the list of addresses to which bobs are to be blitted
move.w d3,(a0) d3 = blitsize
move.w d2,2(a0) d2 = scroll value
move.l (a2),d6 d1 = offset
add.l d1,d6 stores the addresses
cmp.l 4(a0),d6
beq dont.save
move.l d6,4(a0) without updating the
move.l 4(a2),d6 pointer
add.l d1,d6
move.l d6,8(a0)
move.l 8(a2),d6
add.l d1,d6
move.l d6,12(a0)
rts
dont.save
clr.l d6
add.w #16,a0
rts
**************************************************************************
check.end.screen
tst.w screenend(a5)
bne notend
lea rasters(a5),a2
move.w #16,pf1scroll2(a5)
rts
notend lea displayraster(a5),a2
move.w pf1scroll(a5),pf1scroll2(a5)
rts
**************************************************************************
check.path
cmp.b #1,last.path(a5)
beq decrement.counter
tst.w all.coords(a5) wait until all the x coords are 0
bne check.end before a new path can start
not.b bonus.delay(a5)
bne check.end a small delay before the bonus
tst.b last.path(a5) path can start
bne start.path
clr.b bonus.mode(a5)
move.w last.x(a5),d1
beq start.path if all the aliens had been killed
tst.b no.bonus(a5) then we will start the bonus path
bne start.path
move.w #10,path.delay(a5)
move.w last.y(a5),d2
move.l paths,a0
st bonus.mode(a5)
clr.w bonus.num(a5)
move.w #5,bonus.count(a5) setup the bonus path coordinates
move.w d1,x.pos+2(a0)
move.w d2,y.pos+2(a0)
clr.b anim.num+2(a0)
lsr.w #1,d2
move.w #$0200,d1
or.w d2,d1
move.w d1,table.size+2(a0)
bra copy.path
check.end
rts
start.path
cmp.w #1,level.end(a5) start a new path, providing
beq return the guardian is not scrolling on
cmp.w #2,level.end(a5)
beq return
cmp.w #3,level.end(a5)
beq check.all
subq.w #1,path.delay(a5)
beq start.path1
rts
start.path1
move.w #10,path.delay(a5) start a normal path
move.w path.number(a5),d0
lea paths,a0
add.w d0,a0
move.l (a0),d1
bne start1
moveq #4,d0
lea paths,a0
move.l 4(a0),d1
start1
addq #4,d0
move.w d0,path.number(a5)
move.l d1,a0
copy.path
clr.w d0 copy the new path data
lea colours(pc),a2 and set up the new alien colours
move.b sprite.num+2(a0),d0 get sprite num
and.b #$7f,d0
subq.w #1,d0
lea alien.colours(pc),a1 get colour table
move.w level.number(a5),d3
mulu #384,d3
add.w d3,a1
lsl.w #4,d0 16 bytes per alien
add.w d0,a1
move.w (a1)+,2(a2) copy 8 colours
move.w (a1)+,6(a2)
move.w (a1)+,10(a2)
move.w (a1)+,14(a2)
move.w (a1)+,18(a2)
move.w (a1)+,22(a2)
move.w (a1)+,26(a2)
move.w (a1)+,30(a2)
move.w (a0)+,d0
move.l #path.buffer,a1
lsr.w #2,d0
copyloop
move.l (a0)+,(a1)+
dbf d0,copyloop
clr.b no.bonus(a5)
rts
**************************************************************************
update.missiles
tst.w fire.delay(a5)
beq .skip
subq.w #1,fire.delay(a5)
.skip move.l #missiletable,a0 used for erasing
move.w level.number(a5),d0
mulu #72,d0 72 bytes per missile graphics
lea missiles1(pc),a1 base address
add.w d0,a1 level missiles
add.w #32,a1 cannon offset
add.w guard.offset(a5),a1 different for guardian
lea missilemask+32(pc),a3
lea rasters(a5),a2
lea canondata+24(a5),a4
move.l #fgnd.buffer,d6
move.w #%101000010,d3 size for canon
moveq #3,d7
update1 btst d7,activecanons(a5) check canons first
beq update2
move.w (a4),d1 x coordinate in d1
move.w 2(a4),d2 y coordinate in d2
subq.w #1,4(a4) check range
beq killcanon it's dead
addq.w #8,d1 move 8 pixels
cmp.w #360,d1
bcc killcanon is it offscreen
move.w d1,(a4) restore it
bsr draw.missile and draw it
bne update2
move.w (a4),d1
move.w 2(a4),d2
add.w #12,d1 canon tip
addq.w #4,d2 middle of canon
bsr kill.alien
beq update2 zero, so it was'nt an alien
bclr d7,activecanons(a5) canon hit alien, so kill it
update2 subq #8,a4 work down thru buffer
dbf d7,update1 check for 4
move.w level.number(a5),d0
mulu #72,d0 72 bytes per missile graphics
lea missiles1(pc),a1 base address
add.w d0,a1 level missiles
add.w #16,a1 missile offset
add.w guard.offset(a5),a1 different for guardian
lea missilemask+16(pc),a3
lea missiledata+24(a5),a4
move.w #%10000010,d3 size for missiles
moveq #3,d7
update3 btst d7,activemissiles(a5)
beq update4
move.w (a4),d1 x coordinate in d1
move.w 2(a4),d2 y coordinate in d2
subq.w #1,4(a4) check range
beq killmissile it's dead
add.w #10,d1 move 10 pixels
cmp.w #360,d1
bcc killmissile is it offscreen
move.w d1,(a4) restore it
bsr draw.missile and draw it
bne update4
move.w (a4),d1
move.w 2(a4),d2
addq.w #8,d1 missile tip
addq.w #2,d2 middle of missile
bsr kill.alien
beq update4 zero, so it was'nt an alien
bclr d7,activemissiles(a5) missile hit alien, so kill it
update4 subq #8,a4 work down thru buffer
dbf d7,update3 check for 4
move.w level.number(a5),d0
mulu #72,d0 72 bytes per missile graphics
lea missiles1(pc),a1 base address
add.w d0,a1 level missiles
add.w guard.offset(a5),a1 different for guardian
lea missilemask(pc),a3
lea laserdata+24(a5),a4
move.w #%10000010,d3 size for lasers
moveq #3,d7
update5 btst d7,activelasers(a5)
beq update6
move.w (a4),d1 x coordinate in d1
move.w 2(a4),d2 y coordinate in d2
subq.w #1,4(a4) check range
beq killlaser it's dead
add.w #16,d1 move 16 pixels!
cmp.w #360,d1
bcc killlaser is it offscreen
move.w d1,(a4) restore it
bsr draw.missile and draw it
bne update6
move.w (a4),d1 dont kill lasers
move.w 2(a4),d2
add.w #16,d1 laser tip
bsr kill.alien
beq update6
move.b bonus.mode(a5),d5
or.b last.path(a5),d5
beq update6 kill lasers when guardian on
bclr d7,activelasers(a5)
update6 subq #8,a4 work down thru buffer
dbf d7,update5 check for 4
lea mult(pc),a1 finally check mults
lea multmask(pc),a3
lea mult1data+8(a5),a4
move.w #%11000010,d3 size for mults
moveq #1,d7
update7 btst d7,activemult1(a5)
beq update8
move.w (a4),d1 x coordinate in d1
move.w 2(a4),d2 y coordinate in d2
subq.w #1,6(a4) check range
beq killmult1 it's dead
move.b 4(a4),d4
ext.w d4
add.w d4,d1
cmp.w #360,d1
bge killmult1 is it offscreen
cmp.w #16,d1
blt killmult1
move.w d1,(a4) restore it
move.b 5(a4),d4
ext.w d4
add.w d4,d2
cmp.w #186,d2
bge killmult1 is it offscreen
cmp.w #9,d2
blt killmult1
move.w d2,2(a4) restore it
bsr draw.missile and draw it
bne update8
move.w (a4),d1
move.w 2(a4),d2
addq #1,d1 mult middle
addq #1,d2
bsr kill.alien
beq update8
bclr d7,activemult1(a5)
update8 subq #8,a4 work down thru buffer
dbf d7,update7 check for 4
lea mult2data+8(a5),a4
moveq #1,d7
update9 btst d7,activemult2(a5)
beq update10
move.w (a4),d1 x coordinate in d1
move.w 2(a4),d2 y coordinate in d2
subq.w #1,6(a4) check range
beq killmult2 it's dead
move.b 4(a4),d4
ext.w d4
add.w d4,d1
cmp.w #360,d1
bge killmult2 is it offscreen
cmp.w #16,d1
blt killmult2
move.w d1,(a4) restore it
move.b 5(a4),d4
ext.w d4
add.w d4,d2
cmp.w #184,d2
bge killmult2 is it offscreen
cmp.w #9,d2
blt killmult2
move.w d2,2(a4) restore it
bsr draw.missile and draw it
bne update10
move.w (a4),d1
move.w 2(a4),d2
addq #1,d1 mult middle
addq #1,d2
bsr kill.alien
beq update10
bclr d7,activemult2(a5)
update10
subq #8,a4 work down thru buffer
dbf d7,update9 check for 4
rts all finished.
killcanon
bclr d7,activecanons(a5) kill a canon etc.
bra update2
killmissile
bclr d7,activemissiles(a5)
bra update4
killlaser
bclr d7,activelasers(a5)
bra update6
killmult1
bclr d7,activemult1(a5)
bra update8
killmult2
bclr d7,activemult2(a5)
bra update10
kill.alien
move.l a0,-(sp)
tst.b bonus.mode(a5)
bne hit.bonus
move.l #path.buffer,a0
moveq #11,d5
kill.alien.loop
tst.b sprite.num(a0)
beq try.next dont check explosions
move.w x.pos(a0),d4
beq try.next alien's dead
sub.w #16,d4
cmp.w d4,d1 is d1 > xpos
blt try.next
add.w #32,d4
cmp.w d4,d1 is d1 < xpos+32
bgt try.next
move.w y.pos(a0),d4
cmp.w d4,d2 is d2 > ypos
blt try.next
add.w #24,d4
cmp.w d4,d2 is d2 < ypos+24
bgt try.next
btst #7,hits.num(a0)
bne no.more indistructable ?
cmp.b #3,sprite.num(a0)
seq hit.guardian(a5)
subq.b #1,hits.num(a0) found an alien
beq check.which not dead yet though!
move.w #$0106,d0 not dead sound!
; jsr initfx
bra no.more
check.which
cmp.b #3,sprite.num(a0)
bne not.guardian
move.b #2,last.path(a5)
not.guardian
bsr explode.alien
move.l alien.score(a5),score.add(a5) the score
move.w kills.what(a0),d0
move.l #path.buffer,a0
moveq #11,d5
kill.more
lsr.w #1,d0
bcc kill.next
bsr explode.alien
move.l #$0750,score.add(a5)
kill.next
tst.w next.path(a0)
beq resetz
add.w next.path(a0),a0
dbf d5,kill.more
resetz
and.b #0,ccr z reset = a hit
bra no.more
try.next
add.w next.path(a0),a0
dbf d5,kill.alien.loop
or.b #4,ccr z set = no hit
no.more
move.l (sp)+,a0
rts
explode.alien
clr.b anim.num(a0) start the explosion
clr.b sprite.num(a0)
move.b #7,num.anims(a0)
move.b #2,anim.delay(a0)
move.b #2,anim.delay2(a0)
bclr #3,mode(a0) up animate only
move.w d0,-(sp)
move.w #$0101,d0
; jsr initfx
move.w (sp)+,d0
rts
hit.bonus
movem.l a1-a2/d0,-(sp)
move.w #$0113,d0
; jsr initfx
subq.w #1,bonus.count(a5)
bne hit.end
move.w #5,bonus.count(a5)
move.w bonus.num(a5),d1
cmp.w #6,d1
beq hit1
addq #1,d1
hit1 move.w d1,bonus.num(a5)
move.l #path.buffer,a0
move.b d1,anim.num(a0)
hit.end
movem.l (sp)+,a1-a2/d0
move.l (sp)+,a0
rts
draw.missile
movem.w d1-d2,-(sp) save for later
bsr coords.to.pf2offsets convert to ofsset
bsr or.foregnds a1 = missile sprite
move.l d6,d5 a3 = mask
move.w d3,d0 d5 & d6 = foreground buffer
lsr.w #4,d0 height*4 = number of bytes in
add.w d0,d6 a an or'd foreground
clr.w bltcmod(a6)
clr.w bltamod(a6)
clr.w bltdmod(a6)
clr.w bltbmod(a6)
move.l a1,bltapt(a6) a = sprite
move.l a3,bltbpt(a6) b = mask
move.l d6,bltdpt(a6) dest = buffer+height*4
move.w d2,bltcon1(a6) c = buffer
or.w #$0f40,d2 use D = A.B.notC
move.w d2,bltcon0(a6) which shows only where missile
move.l d5,bltcpt(a6) can be drawn
move.w d3,bltsize(a6)
move.l d5,bltcpt(a6)
move.w d3,bltsize(a6)
move.w #88,bltdmod(a6)
move.w #88,bltbmod(a6)
clr.w bltcon1(a6)
move.w #$0dfc,bltcon0(a6) D = A or B
move.l d6,bltapt(a6) the new buffer being the mask only
move.l (a0),bltbpt(a6) drawing where there is no
move.l (a0)+,bltdpt(a6) foreground
move.w d3,bltsize(a6)
move.l (a0),bltbpt(a6)
move.l (a0)+,bltdpt(a6)
move.w d3,bltsize(a6)
clr.w (a0)
movem.w (sp)+,d1-d2
add.w #16,d1
move.w pf1scroll(a5),pf1scroll2(a5) copy scroll
bsr coords.to.pf1offsets get pf1 offset
ror.w #4,d2 shift the scroll value
or.w #$aa0,d2 use D = A.C
move.w d2,bltcon0(a6) with D turned off
move.l a1,bltapt(a6) a1 = sprite
move.l a0,-(sp)
lea displayraster(a5),a0
move.l 20(a0),d0
move.l (sp)+,a0
add.l d1,d0
move.l d0,bltcpt(a6) d0 = background
move.w #96,bltcmod(a6)
move.w d3,bltsize(a6) d3 = blitsize
btst #5,dmaconr(a6)
rts
or.foregnds
move.w #88,bltamod(a6) or the two foregrounds together
move.w #88,bltbmod(a6)
clr.w bltdmod(a6)
move.w d3,(a0)+ store the blitsize in the buffer
move.l 12(a2),d0
add.l d1,d0
move.l d0,(a0) store the plane 2 address
move.l d0,bltapt(a6)
move.l 16(a2),d0
add.l d1,d0
move.l d0,4(a0) store the plane 4 address
move.l d0,bltbpt(a6)
clr.w bltcon1(a6)
move.w #$0ffc,bltcon0(a6) use D = A or B
move.l d6,bltdpt(a6) d6 = foreground buffer
move.w d3,bltsize(a6)
rts
erase.missiles
move.l #missiletable,a0
move.l #fgnd.buffer,a1
clr.w bltcon1(a6)
clr.w bltamod(a6) a = or'd fgnd
move.w #$0dc0,bltcon0(a6) D=A.B
move.w #88,bltbmod(a6) b = foreground
move.w #88,bltdmod(a6) d = foreground
eraseloop
move.w (a0),d0 d0 = blitsize
beq eraseend zero if end
clr.w (a0)+
move.w d0,d1
lsr.w #4,d1
move.l (a0),bltbpt(a6)
move.l (a0)+,bltdpt(a6)
move.l a1,bltapt(a6)
move.w d0,bltsize(a6)
move.l (a0),bltbpt(a6)
move.l (a0)+,bltdpt(a6)
move.l a1,bltapt(a6)
move.w d0,bltsize(a6)
add.w d1,a1
bra eraseloop
eraseend
rts
**************************************************************************
draw.guardian
cmp.w #$e,pf2scroll(a5)
bne no.draw
move.w guardian.frame(a5),d0
cmp.w #16,d0
beq no.draw
mulu #24,d0
ext.l d0
move.l #guardian,a0
add.l d0,a0
move.l guardian.data(a5),a1
lea rasters+12(a5),a4
move.l (a4)+,a2
move.l (a4)+,a3
move.l (a4),a4
moveq #46,d6
add.l d6,a2
add.l d6,a3
add.l d6,a4
add.w pf2offset(a5),a2
add.w pf2offset(a5),a3
add.w pf2offset(a5),a4
moveq #92,d5
moveq #23,d7
drawg1 moveq #7,d6
move.b (a0)+,d0
drawg2 btst d6,d0
bne draw.data
clr.w (a2)
clr.w (a3)
clr.w (a4)
bra donext
draw.data
move.w (a1)+,(a2)
move.w (a1)+,(a3)
move.w (a1)+,(a4)
donext add.l d5,a2
add.l d5,a3
add.l d5,a4
dbf d6,drawg2
dbf d7,drawg1
move.l a1,guardian.data(a5)
addq.w #1,guardian.frame(a5)
no.draw cmp.w #6,pf2count(a5)
bne return
cmp.w #8,pf2scroll(a5)
bne return
addq.w #1,level.end(a5)
rts
change.colours
lea colours+32(pc),a2
moveq #7,d7
lea guard.colours,a3
move.w level.number(a5),d2
lsl.w #4,d2
add.w d2,a3
change1 move.w (a3)+,2(a2)
addq #4,a2
dbf d7,change1
rts
levels.code
tst.b hit.guardian(a5)
beq return
lea colours+50(pc),a0
tst.b colour.updown(a5)
bne colour.down
add.w #$100,(a0)
cmp.w #$f00,(a0)
seq colour.updown(a5)
rts
colour.down
sub.w #$100,(a0)
cmp.w #$700,(a0)
bne return
not.b colour.updown(a5)
clr.b hit.guardian(a5)
rts
decrement.counter
tst.w guardian.count(a5)
beq death.path
subq.w #1,guardian.count(a5)
rts
death.path
move.l #path.buffer,a0
add.w next.path(a0),a0
tst.b sprite.num(a0)
beq wait.explosion
moveq #10,d7
ex.loop bsr explode.alien
move.w next.path(a0),d0
beq return
add.w d0,a0
dbf d7,ex.loop
rts
wait.explosion
tst.w x.pos(a0)
bne return
move.l #paths,a0
find.path3
tst.l (a0)+
bne find.path3
addq #8,a0
move.l (a0),a0
move.b #$ff,last.path(a5)
bra copy.path
check.all
tst.b last.path(a5)
beq start.guard.path
cmp.b #2,last.path(a5)
beq explosion.path
cmp.b #3,last.path(a5)
seq.b kill.game(a5)
rts
start.guard.path
move.l #paths,a0
; moveq #0,d0
; jsr Initune
find.path
tst.l (a0)+
bne find.path
move.l (a0),a0
move.b #1,last.path(a5)
bra copy.path
explosion.path
move.l #paths,a0
find.path2
tst.l (a0)+
bne find.path2
addq #4,a0
move.l (a0),a0
move.b #3,last.path(a5)
; jsr Turnoff
bra copy.path
**************************************************************************
clist DC.W $0A01,$FF00
copperlist DC.W bplpt+0,$0000,bplpt+2,$0000
DC.W bplpt+8,$0000,bplpt+10,$0000
DC.W bplpt+16,$0000,bplpt+18,$0000
DC.W bplpt+4,$0000,bplpt+6,$0000
DC.W bplpt+12,$0000,bplpt+14,$0000
DC.W bplpt+20,$0000,bplpt+22,$0000
DC.W bplcon0,$6600
scroll.value DC.W bplcon1,$00FF,bpl1mod,$0036
DC.W bpl2mod,$002E,bplcon2,$0044
DC.W ddfstrt,$0028,ddfstop,$00D8
DC.W diwstrt,$1F78,diwstop,$FFC6
colours DC.W color+0,$0000,color+2,$0000
DC.W color+4,$0000,color+6,$0000
DC.W color+8,$0000,color+10,$0000
DC.W color+12,$0000,color+14,$0000
DC.W color+16,$0000,color+18,$0000
DC.W color+20,$0000,color+22,$0000
DC.W color+24,$0000,color+26,$0000
DC.W color+28,$0000,color+30,$0000
DC.W color+32,$0000,color+34,$0000
DC.W color+36,$0000,color+38,$0000
DC.W color+40,$0000,color+42,$0000
DC.W color+44,$0000,color+46,$0000
DC.W color+48,$0000,color+50,$0000
DC.W color+52,$0000,color+54,$0000
DC.W color+56,$0000,color+58,$0000
DC.W color+60,$0000,color+62,$0000
sprite DC.W sprpt+0,$0000,sprpt+2,$0000
DC.W sprpt+4,$0000,sprpt+6,$0000
DC.W sprpt+8,$0000,sprpt+10,$0000
DC.W sprpt+12,$0000,sprpt+14,$0000
DC.W sprpt+16,$0000,sprpt+18,$0000
DC.W sprpt+20,$0000,sprpt+22,$0000
DC.W sprpt+24,$0000,sprpt+26,$0000
DC.W sprpt+28,$0000,sprpt+30,$0000
DC.W $DF01,$FF00
DC.W bplcon1,$0000,bplcon0,$4200,ddfstrt,$0030
rastersplit2 DC.W bplpt+0,$0000,bplpt+2,$0000
DC.W bplpt+4,$0000,bplpt+6,$0000
DC.W bplpt+8,$0000,bplpt+10,$0000
DC.W bplpt+12,$0000,bplpt+14,$0000
colours2 DC.W color+20,$0000,color+30,$0000
DC.W color+2,$0000,color+4,$0000
DC.W color+6,$0000,color+8,$0000
DC.W color+10,$0000,color+12,$0000
DC.W color+14,$0000,color+16,$0000
DC.W color+18,$0000,color+22,$0000
DC.W color+24,$0000,color+26,$0000
DC.W color+28,$0000,color+0,$0000
DC.W bpl1mod,$0000,bpl2mod,$0000
DC.W $DF01,$FF00,intreq,$8010
DC.W $FFFF,$FFFE
panel.colours DC.W $0600,$0333,$0fb3,$0d00,$0b00,$0720,$0fc2,$0c90
DC.W $0a40,$0eb0,$0eca,$0456,$0577,$0252,$0444,$0000
mult1offsets
DC.B 5,0,5,-5,0,-5,-5,-5,-5,0
mult2offsets
DC.B 5,0,5,5,0,5,-5,5,-5,0
explosion.sequence
dc.b 0,1,2,3,4,5,6,7,8,9,10,-1
rsreset
screen.num RS.B 1
vcount RS.B 1 vertical blank counter
mult1.on RS.B 1 byte set if a multiple is attached to ship
mult2.on RS.B 1 same for another multiple (2 max)
canons.on RS.B 1 bytes are set to signify what weapons
lasers.on RS.B 1 are attached
ship.status RS.B 1 values to indicate which ship to draw
activecanons RS.B 1
activemissiles RS.B 1
activelasers RS.B 1
activemult1 RS.B 1
activemult2 RS.B 1
firekey RS.B 1
ship.dead RS.B 1
num.speedups RS.B 1
num.outriders RS.B 1
num.fields RS.B 1
num.canons RS.B 1
num.lasers RS.B 1
num.shields RS.B 1
kill.game RS.B 1
hit.guardian RS.B 1
colour.updown RS.B 1
ship.speed RS.W 1 speed in pixels
xpos RS.W 1 ship x position
ypos RS.W 1 ship y position
mult.number RS.W 1 multiple animation number
mult.delay RS.W 1 multiple animation delay
xvector RS.W 1 inertia vectors for the ship
yvector RS.W 1
oldmousex RS.W 1 store the old mouse values to reference
oldmousey RS.W 1 the new ones to
up.down RS.W 1 this holds the graphic offset for a ship tilt
pf1count RS.W 1 number of background words to scroll
pf2count RS.W 1 number of foreground words to scroll
pf1scroll RS.W 1 pixel scroll value (0-15) background
pf2scroll RS.W 1 pixel scroll value (0-15) foreground
pf1scroll2 RS.W 1
pf2offset RS.W 1
screenend RS.W 1
level.end RS.W 1
level.number RS.W 1
canon.energy RS.W 1
laser.energy RS.W 1
fire.delay RS.W 1
ship.energy RS.W 1
ship.count RS.W 1
field.count RS.W 1
difficulty RS.W 1
guard.offset RS.W 1
path.delay RS.W 1
last.x RS.W 1 x coord of last killed alien
last.y RS.W 1 y coord of last killed alien
path.number RS.W 1
all.coords RS.W 1 zero if all aliens are dead
x.equal RS.B 1
y.equal RS.B 1
upsidedown RS.B 1 draw alien upside down
no.bonus RS.B 1 alien finished path so no bonus
last.path RS.B 1
bonus.mode RS.B 1 bonus icon on screen
bonus.num RS.W 1 current bonus
bonus.count RS.W 1 number of hits to change bonus
bonus.delay RS.B 1
explosion.delay RS.W 1
guardian.frame RS.W 1
guardian.count RS.W 1
missiledata RS.L 8
canondata RS.L 8
laserdata RS.L 8
mult1data RS.L 4
mult2data RS.L 4
score RS.L 1
score.add RS.L 1
alien.score RS.L 1
fgndpointer RS.L 1 foreground map pointer
displayraster RS.L 6 holds the addresses of the planes
rasters RS.L 9 updated plane addresses
shipaddress RS.L 1 ship animation address
alien.buffer RS.L 18
explosion.ptr RS.L 1
guardian.data RS.L 1
vars.length RS.B 0
variables DS.B vars.length
* *********************************
* * Data structures *
* *********************************
rsreset
next.path RS.W 1 offset to the next path
x.pos RS.W 1 current x position
y.pos RS.W 1 current y position
kills.what RS.W 1 kills others if dead (0-11)
table.offset RS.W 1 the current table offset
sprite.num RS.B 1 sprite number
anim.num RS.B 1 animation number
anim.delay RS.B 1 delay in 1/25 secs
anim.delay2 RS.B 1 static delay
speed RS.B 1 speed in pixels
pause.count RS.B 1 dynamic pause counter
mode RS.B 1 flags, see bleow
loop.offset RS.B 1 loop offset (-ve)
loop.count RS.B 1 dynamic loop count
hits.num RS.B 1 number of hits to kill
num.anims RS.B 1 no of animations
seek.count RS.B 1 dynamic seek count
table.size RS.B 0
* This is followed by x,y bytes to move to (always even) with the following
* special codes
* x = 0, path finished, terminate alien
* x = $e0, perform a pause (up to 10 secs), followed by the pause value, $ff forever
* x = $e1, perform the loop
* x = $e2, toggle the offset mode
* x = $e3, speed change, followed by new speed byte
* x = $e4, sprite change, followed by sprite num, max anims
* x = $e5, start seek mode, followed by count & two 0 bytes
* x = $e6, reload the aliens x,y coords, followed by two xy bytes
* x = $e7, reload the table offset, old one stored in loop.offset
* x = $e8, restore the old table offset
* x = $e9, fire a heat seeker, followed by count
* x = $ea, new animation number, followed by animation number
* x = $eb, repeat table indefinitely
* mode bit 0 = offset mode
* bit 1 = seek mode
* bit 2 =
* bit 3 = up/down animation type
* bit 4 = 0-animate up/1-animate down
* bit 5 = heat seeker path
backgroundtable DC.W $0123,$0123,$0123,$0123,$0123,$0123 background
DC.W $4567,$4567,$4567,$4567,$4567,$4567 map
DC.W $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
DC.W $0123,$0123,$0123,$0123,$0123,$0123
DC.W $4567,$4567,$4567,$4567,$4567,$4567
DC.W $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
DC.W $0123,$0123,$0123,$0123,$0123,$0123
DC.W $4567,$4567,$4567,$4567,$4567,$4567
DC.W $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
DC.W $0123,$0123,$0123,$0123,$0123,$0123
DC.W $4567,$4567,$4567,$4567,$4567,$4567
DC.W $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
backgrounds DC.W $1430,$0C30,$0C10,$0413,$8403,$4442,$2142,$3120
DC.W $3110,$2810,$141C,$1417,$140B,$0C71,$0A00,$DC08
DC.W $8A08,$9208,$0229,$8208,$4244,$2221,$12A1,$0891
DC.W $0888,$148A,$0A03,$2A48,$8A44,$9208,$8524,$2204
DC.W $0210,$0230,$1118,$0118,$8128,$414C,$314C,$10CA
DC.W $1005,$1013,$5103,$31C3,$5023,$D011,$3018,$6304
DC.W $0129,$0908,$0884,$0884,$4294,$22A2,$08A2,$0825
DC.W $0842,$0908,$2880,$C824,$2890,$2808,$0904,$1092
DC.W $0300,$4220,$0461,$0451,$0850,$08C8,$38C8,$1848
DC.W $0848,$0848,$0848,$08C8,$0148,$1050,$E060,$4041
DC.W $2084,$2110,$2210,$0228,$0429,$1424,$0424,$0424
DC.W $8424,$8424,$8424,$8424,$80A4,$8828,$1011,$2420
DC.W $1430,$0C08,$0800,$0413,$8083,$4442,$2242,$2120
DC.W $2110,$2810,$040C,$1487,$104B,$0C71,$0A10,$D908
DC.W $8A08,$9000,$042D,$8008,$4244,$2221,$1121,$0091
DC.W $0888,$048A,$0A03,$2240,$8220,$9208,$8124,$2004
DC.W $7028,$6218,$8218,$C208,$C210,$C210,$6420,$2420
DC.W $4820,$4820,$8843,$0882,$108C,$2118,$2220,$4421
DC.W $0914,$1104,$4104,$2504,$2508,$2508,$9250,$1250
DC.W $2450,$2410,$4420,$8441,$0840,$1080,$1110,$A210
DC.W $C60C,$C60A,$4609,$2209,$A201,$A223,$9011,$901F
DC.W $900C,$8C18,$0620,$060F,$0213,$0404,$1405,$1419
DC.W $2102,$2105,$2104,$5104,$5124,$5110,$4908,$4900
DC.W $4902,$4204,$8912,$0900,$2508,$0212,$4A02,$EA04
DC.W $0080,$0100,$0110,$0918,$0A14,$0A33,$8A31,$0621
DC.W $0220,$8204,$8204,$860D,$860A,$8A0C,$0108,$0101
DC.W $4940,$0888,$8888,$8484,$852A,$8508,$4508,$8110
DC.W $4911,$4902,$490A,$4102,$4905,$4502,$8084,$9088
DC.W $7028,$4318,$8298,$C248,$8250,$C210,$6120,$20A0
DC.W $5820,$4820,$8813,$188A,$108C,$2100,$2220,$4421
DC.W $0914,$1004,$4144,$2504,$4528,$2528,$9290,$1010
DC.W $2010,$2410,$4428,$8405,$0842,$1080,$1100,$A210
DC.W $8820,$0440,$0204,$1202,$8221,$8220,$8300,$8410
DC.W $C080,$0180,$20C0,$6040,$7060,$31A1,$2820,$2820
DC.W $4410,$8A24,$0122,$8921,$4910,$4110,$4090,$4208
DC.W $2448,$8048,$1020,$1220,$0910,$0850,$9492,$1412
DC.W $CE02,$4A02,$5402,$0442,$0844,$9048,$E148,$4150
DC.W $23A0,$31C4,$3185,$3842,$2820,$11A0,$23A0,$6322
DC.W $0101,$2501,$2A01,$9221,$9422,$68A4,$10A4,$A0A8
DC.W $1050,$0822,$0842,$04A1,$1412,$8850,$5051,$1091
DC.W $3100,$11C0,$10C1,$10E1,$4862,$8850,$9850,$88F0
DC.W $E830,$7031,$0028,$8248,$4088,$4018,$2018,$3018
DC.W $0881,$0821,$0820,$0810,$2411,$5429,$44A9,$4408
DC.W $0408,$0808,$8114,$4124,$2144,$2104,$1224,$0844
DC.W $C820,$4440,$2204,$1002,$8225,$8224,$8308,$8418
DC.W $C980,$1188,$20C4,$6040,$6260,$2121,$2820,$2820
DC.W $0410,$AA24,$1122,$8921,$4912,$0110,$4094,$4380
DC.W $2448,$8844,$1020,$1220,$0110,$0850,$9492,$1412
level.colours
DC.W $0332,$0055,$0543,$0000,$0000,$0000,$0000,$0000
DC.W $0000,$0F55,$0B05,$0700,$08A7,$0182,$0065,$0055
DC.W $0000,$0FF6,$0000,$0FD0,$0A00,$0BDF,$06AF,$004F
DC.W $0FFF,$0CDD,$0ABB,$0798,$0587,$0465,$0243,$0E32
alien.colours DC.W $0332,$0055,$0543,$0000,$0DFF,$06AC,$036A,$0038 level1
DC.W $0332,$0055,$0543,$0000,$0FE0,$0DA0,$0B62,$0900
DC.W $0332,$0055,$0543,$0000,$0FE0,$0DA0,$0B62,$0900
DC.W $0332,$0055,$0543,$0000,$0DE9,$0FE0,$0F90,$0D32
DC.W $0332,$0055,$0543,$0000,$0FE0,$0DA0,$0B62,$0900
DC.W $0332,$0055,$0543,$0000,$09E7,$06A0,$0D00,$0460
DC.W $0332,$0055,$0543,$0DDF,$099E,$0569,$0348,$0235
DC.W $0332,$0055,$0543,$0FFC,$0FF2,$0DE9,$0BC6,$09A4
DC.W $0332,$0055,$0543,$09FF,$0AF5,$03DF,$01BF,$008F
DC.W $0332,$0055,$0543,$0F77,$08A7,$0385,$0265,$0722
DC.W $0332,$0055,$0543,$0F66,$08A7,$0283,$0065,$0700
DC.W $0332,$0055,$0543,$0F66,$08A7,$0283,$0065,$0700
DC.W $0332,$0055,$0543,$0F66,$08A7,$0283,$0065,$0700
DC.W $0332,$0055,$0543,$0B85,$0DDA,$0C00,$0952,$0700
DC.W $0332,$0055,$0543,$0D8C,$0B5A,$000E,$0937,$0705
DC.W $0332,$0055,$0543,$0E00,$0A98,$0B60,$0832,$0733
DC.W $0332,$0055,$0543,$0E00,$0A98,$0B60,$0832,$0733
DC.W $0332,$0055,$0543,$0E00,$0A98,$0B60,$0832,$0733
DC.W 0,0,0,0,0,0,0,0
DC.W 0,0,0,0,0,0,0,0
DC.W 0,0,0,0,0,0,0,0
DC.W 0,0,0,0,0,0,0,0
DC.W 0,0,0,0,0,0,0,0
DC.W 0,0,0,0,0,0,0,0
guard.colours
DC.W $0000,$0A00,$0D22,$0E77,$0700,$0FDD,$0A73,$0C90
*******************************************************************************
*******************************************************************************
alldone
bsr FreeSystem
MemError
move.l _SysBase,a6
move.l MemBase,a1
move.l #MemNeeded,d0 free the memory we took
jsr _LVOFreeMem(a6)
move.l GraphicsBase,a1
jsr _LVOCloseLibrary(a6)
move.l DOSBase,a1 finally close the
jsr _LVOCloseLibrary(a6) libraries
clr.l d0
rts
*******************************************************************************
TakeSystem
move.w intenar(a6),SystemInts save system interupts
move.w dmaconr(a6),SystemDMA and DMA settings
move.w #$7fff,intena(a6) kill everything!
move.w #$7fff,dmacon(a6)
move.b #%01111111,ICRA kill keyboard
move.l $68,Level2Vector save these interrupt vectors
move.l $6c,Level3Vector as we will use our own
rts keyboard & vblank routines
FreeSystem
move.l Level2Vector,$68 restore the system vectors
move.l Level3Vector,$6c and interrupts and DMA
move.l GraphicsBase,a1 and replace the system
move.l SystemCopper1(a1),Hardware+cop1lc copper list
move.l SystemCopper2(a1),Hardware+cop2lc
move.w SystemInts,d0
or.w #$c000,d0
move.w d0,intena(a6)
move.w SystemDMA,d0
or.w #$8100,d0
move.w d0,dmacon(a6)
move.b #%10011011,ICRA keyboard etc back on
rts
*******************************************************************************
Level2Vector dc.l 0
Level3Vector dc.l 0
SystemInts dc.w 0
SystemDMA dc.w 0
MemBase dc.l 0
DOSBase dc.l 0
GraphicsBase dc.l 0
even
GraphicsName dc.b 'graphics.library',0
even
DOSName dc.b 'dos.library',0
*******************************************************************************
graphics incbin :foregrounds
shipbase include :ships.s
paths include :paths.s
map incbin :map
panel incbin :panel
aliens incbin :aliens
bonus.sprite include :bonus.s
mine include :mine.s
guardian incbin :guardian
missiletable ds.b 512
alien.pointers
explosion1 equ aliens
guardian.eye1 equ explosion1+(9*384)
tadpole equ guardian.eye1+(4*384)
eye equ tadpole+(4*384)
bubble equ eye+(15*384)
jellyfish1 equ bubble+(4*384)
jellyfish2 equ jellyfish1+(4*384)
bordertl equ jellyfish2+(4*384)
borderbl equ bordertl+(6*384)
bordertr equ borderbl+(6*384)
borderbr equ bordertr+(6*384)
mouth equ borderbr+(6*384)
slime equ mouth+(8*384)
snakebody equ slime+(9*384)
snakehead equ snakebody+(1*384)
dc.l explosion1
dc.l bonus.sprite
dc.l mine
dc.l guardian.eye1
dc.l explosion1
dc.l tadpole
dc.l eye
dc.l bubble
dc.l jellyfish1
dc.l jellyfish2
dc.l bordertl
dc.l borderbl
dc.l bordertr
dc.l borderbr
dc.l mouth
dc.l slime
dc.l snakebody
dc.l snakehead
ds.l 6
path.buffer ds.b 2048
buffer0 ds.b 6144
buffer1 ds.b 6144
screen0bgnds ds.b 256
screen1bgnds ds.b 256
fgnd.buffer ds.b 2048
end