;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ Spaze Invaders ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ ; Spaze Invaders v1.1 by Hannes Edfeldt ; Here's the source code to my game Spaze Invaders. I've released it to help ; other budding TI-83 asm programmers to get started. Don't forget to give me ; some credit if you use anything from my code. Have a nice day! =) ; Hannes Edfeldt * movax@algonet.se * http://www.algonet.se .org 9327h ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ MAIN ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ START: call INIT ; Init call INTRO ; Intro call MENU01 ; Menu, wait for 2nd call MENU02 ; Menu, choose difficulty call LVINIT ; Level init MAIN: ; Normal level call KEYS ; Read keys call SHIP ; Update ship call LASER ; Update laser call ALIENS ; Move the aliens call ALASR ; Alien laser call COLDT1 ; Collision detection between alien and laser call COLDT2 ; Collision detection between player and laser call COLDT3 ; Collision detection between barrier and laser call BUFCOPY ; Copy graphbuf to LCD call ALIENY ; Check if aliens has moved down to the bottom jp MAIN MBOSS: ; Boss level call KEYS ; Read keys call BOSS ; Manage boss an related stuff call SHIP ; Update ship call COLDT2 ; Collision detection between player and laser call BUFCOPY ; Copy graphbuf to LCD ld a,(BOSSf) ; Check if boss still is alive cp 1 jp z,MBOSS call BOSSKILL ; If not, call boss killed routine ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ PROCEDURES ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß NEWGAME ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Init for a new game ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ NEWGAME: inc sp ; Don't return to GAMEOVER inc sp inc sp ; Don't return to ALIENY/COLDT2 inc sp inc sp ; Don't return to MAIN/MBOSS inc sp ld hl,858fh+100 ; -- Restore the variables start values ld de,SHIPx ld bc,DBYTES ldir ld a,0 ld (SCOREb),a ld (SCOREb+1),a ld (STARTy),a ld a,'0' ld (SCR1),a ld (SCR2),a ld (SCR3),a ld (SCR4),a ld a,'1' ld (LEVELa),a ld a,1 ld (LEVELb),a ld (TIME),a ld a,3 ld (LIVESb),a ld a,'3' ld (LIVESa),a ld hl,START ; Make program ret to START push hl ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ NEWGAME ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß INTRO ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Intro ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ INTRO: ;ÛÛÛÛ Initiate for intro ÛÛÛÛ call BUFCLR ; Clear the graphbuf call BUFCOPY ; Copy graphbuf to LCD ld hl,8e29h ; Clear safe ram area ld de,8265h ld bc,768 ldir ld hl,8e29h ; Clear top of safe ram area 2 ld de,858fh ld bc,80 ldir ;ÛÛÛÛ Alien Code text ÛÛÛÛ res 7,(iy+20) ld hl,0191eh ; Print "Alien Code" ld (08252H),hl ; Update cursorslocation ld hl,TXT6 call 04781h ; Vputs ld hl,01f22h ; Print "presents" ld (08252H),hl ; Update cursorslocation ld hl,TXT7 call 04781h ; Vputs ld b,4 WAITL6: push bc ld hl,65535 call WAIT pop bc djnz WAITL6 ;ÛÛÛÛ Copy logo to graphbuf ÛÛÛÛ LOGO: ld hl,SPZLOGO ; Copy logo to graphbuf ld de,8e29h+38 ld b,17 YLOP1: push bc ld b,8 XLOP1: ld a,(hl) ld (de),a inc hl inc de djnz XLOP1 pop bc inc de inc de inc de inc de djnz YLOP1 ;ÛÛÛÛ Do logo fx ÛÛÛÛ LOGOFX: set 7,(iy+20) ld hl,01413h ; Print "By Hannes Edfeldt" ld (08252H),hl ; Update cursorslocation ld hl,TXT1 call 04781h ; Vputs ld hl,8e29h ; Copy graphbuf to safe ram area ld de,8265h ld bc,768 ldir ld b,27 FXLOP2: push bc ld a,(LOGOl) ; Get line number ld e,a ld d,0 ld hl,0 ; Do hl=de*12 add hl,de add hl,de add hl,de add hl,hl add hl,hl push hl ld bc,8e29h add hl,bc ld (TEMP),hl ld de,(TEMP) ; de->graphbuf pop hl ld bc,8265h add hl,bc ; hl->spzlogo ld a,(LOGOl) ; Calculate how many lines to draw ld c,a ld a,64 sub c ld b,a FXLOP1: push bc ; Copy one line ld bc,12 ldir ld bc,-12 add hl,bc pop bc djnz FXLOP1 ld hl,LOGOl ; Update logoline counter inc (hl) call BUFCOPY ld hl,12500 call WAIT pop bc djnz FXLOP2 ld hl,01e10h+7 ; - Print highscore text ld (08252H),hl ; Update cursorslocation ld hl,HSCORE call 04781h ; Vputs ld hl,01e34h+7 ; - Print highscore number ld (08252H),hl ; Update cursorslocation ld hl,HSCR4 call 04781h ; Vputs ld hl,03a51h ; Print "vX.X" (version number) ld (08252H),hl ; Update cursorslocation ld hl,VERt call 04781h ; Vputs ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ INTRO ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß MENU01 ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Menu part 1 ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ MENU01: ;ÛÛÛÛ Prepare for textflash ÛÛÛÛ ld hl,8e29h ; Copy graphbuf to safe ram area ld de,8265h ld bc,768 ldir ld hl,00011h ; - Print "PRESS 2nd TO START" ld (08252H),hl ; Update cursorlocation ld hl,TXT2 call 04781h ; Vputs ld hl,8e29h ; Copy top of graphbuf to safe ram area 2 ld de,858fh ld bc,72 ldir ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir ;ÛÛÛÛÛÛÛÛ Menu loop ÛÛÛÛ MENUL: ;ÛÛÛÛ Textflash ÛÛÛÛ ld a,(FLASHt) ; Time to flash text? inc a ld (FLASHt),a cp 32 jp nz,SKP13 ld a,0 ld (FLASHt),a ld a,(FLASHf) ; Get flashflag cp 1 jp z,ERASE1 DRAW1: ld hl,858fh ld de,8e29h+540 ld bc,72 ldir ld a,1 ld (FLASHf),a jp SKP13 ERASE1: ld hl,8e29h+612 ld de,8e29h+540 ld bc,72 ldir ld a,0 ld (FLASHf),a SKP13: call BUFCOPY SKP29: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0bfh ; Enable the row with 2nd out (1),a in a,(1) cp 223 ; Has anyone pressed 2nd? jp nz,MENUL ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ MENU01 ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß MENU02 ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Menu part 2 ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ MENU02: ;ÛÛÛÛ Prepare for diff. menu ÛÛÛÛ call READKEY ; Fetch last 2nd press ld hl,9009h ; Erase "PRESS 2nd TO START" msg ld de,8e29h+540 ld bc,72 ldir ld hl,02629h ; - Print "EASY" ld (08252H),hl ; Update cursorlocation ld hl,TXT3 call 04781h ; Vputs ld hl,02d25h ; - Print "MEDIUM" ld (08252H),hl ; Update cursorlocation ld hl,TXT4 call 04781h ; Vputs ld hl,03429h ; - Print "HARD" ld (08252H),hl ; Update cursorlocation ld hl,TXT5 call 04781h ; Vputs ld hl,38*12+8e29h ld b,7 INVL2: ld de,4 ; Invert loop add hl,de ld a,(hl) cpl and 01111111b ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a ld de,5 add hl,de djnz INVL2 call BUFCOPY ;ÛÛÛÛÛÛÛÛ Menu loop 2 ÛÛÛÛ MENUL2: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0fdh ; Enable the row with clear out (1),a in a,(1) cp 191 ; Check for clear jp nz,NOCLR_3 inc sp inc sp call XIT NOCLR_3: ld hl,MENUt ; Time to check for new arrowpress? ld a,(hl) cp 12 jp nz,SKP33 ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0feh ; Enable the arrows out (1),a in a,(1) cp 247 ; Pressed up? jp nz,NOUP ld hl,MENUt ; Reset timer ld (hl),0 ld a,(MENUc) ; Update old menu choice ld (MENUoc),a ld hl,MENUc ; Move bar dec (hl) ld a,(hl) cp 0 jp nz,NOUP ld (hl),3 ; Warp NOUP: cp 254 ; Pressed down? jp nz,NODOWN ld hl,MENUt ; Reset timer ld (hl),0 ld a,(MENUc) ; Update old menu choice ld (MENUoc),a ld hl,MENUc ; Move bar inc (hl) ld a,(hl) cp 4 jp nz,NODOWN ld (hl),1 ; Warp NODOWN: ld a,(MENUt) ; Has the bar moved? cp 0 jp nz,SKP33 ld hl,MENUc ld b,2 ; Loop to do two inverts (old and new bar) BARL1: ld a,(hl) dec a ld l,a ld h,84 push bc call HTIMESL pop bc ld de,(38*12)+8e29h add hl,de push bc ld b,7 ; Invert loop BARL2: ld de,4 add hl,de ld a,(hl) cpl and 01111111b ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a ld de,5 add hl,de djnz BARL2 pop bc ld hl,MENUc inc hl djnz BARL1 SKP33: call BUFCOPY ld hl,MENUt ld a,(hl) cp 12 jp z,SKP32 inc (hl) SKP32: call READKEY ; Look for a 2nd press call OP2TOP1 call CONVOP1 cp 21 jp nz,MENUL2 ld a,(MENUc) ; Set difficulty after menu choice ld (DIFF),a ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ MENU02 ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß OUTRO ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Outro ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ OUTRO: call BUFCLR ; Clear the graphbuf call BUFCOPY set 7,(iy+20) ld hl,00010h ; - Print "CONGRATULATIONS!!!" ld (08252h),hl ; Update cursorslocation ld hl,MSG06 call 04781h ; Vputs ld hl,0070ch ; - Print "You have saved all the" ld (08252h),hl ; Update cursorslocation ld hl,MSG07 call 04781h ; Vputs ld hl,00d09h ; - Print "hamsters on earth from" ld (08252h),hl ; Update cursorslocation ld hl,MSG08 call 04781h ; Vputs ld hl,0130dh ; - Print "the evil aliens' claws" ld (08252h),hl ; Update cursorslocation ld hl,MSG09 call 04781h ; Vputs ld hl,01c16h+7 ; - Print score text ld (08252H),hl ; Update cursorslocation ld hl,SCORE call 04781h ; Vputs ld hl,01c2dh+7 ; - Print score number ld (08252H),hl ; Update cursorslocation ld hl,SCR4 call 04781h ; Vputs ld hl,02417h ; - Print "Have a nice day!" ld (08252h),hl ; Update cursorslocation ld hl,MSG10 call 04781h ; Vputs ld hl,02d1eh ; - Print "ALIEN CODE" ld (08252h),hl ; Update cursorslocation ld hl,TXT6 call 04781h ; Vputs ld hl,03311h ; - Print "movax@algonet.se" ld (08252h),hl ; Update cursorslocation ld hl,MSG11 call 04781h ; Vputs ld hl,03905h ; - Print "www.algonet.se/~movax" ld (08252h),hl ; Update cursorslocation ld hl,MSG12 call 04781h ; Vputs ld hl,8e29h ; Copy graphbuf to safe ram area ld de,8265h ld bc,768 ldir call BUFCLR ; Clear the graphbuf ld hl,0 ; Bytes to write ld (TEMP),hl ld hl,8e29h+768 ; Destination ld (TEMP2),hl ld b,64 YSCRLL: push bc ld bc,12 ; - Update bytes to write ld hl,(TEMP) add hl,bc ld (TEMP),hl ld bc,-12 ; - Update destination ld hl,(TEMP2) add hl,bc ld (TEMP2),hl ld de,(TEMP2) ld hl,8265h ld bc,(TEMP) ldir ld b,8 ; Wait for a while WAITL5: push bc call BUFCOPY pop bc djnz WAITL5 pop bc djnz YSCRLL call WAIT2ND call GAMEOVER ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ OUTRO ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß BOSS ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Manage the boss and related stuff ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ BOSS: ;ÛÛÛÛ Boss shot part 1 ÛÛÛÛ ld a,(ALASRt) ; Is timer 0 yet? cp 0 jp z,SKP56 ld hl,ALASRt ; Nope, update timer dec (hl) jp SKP57 SKP56: ld hl,BOSSlt inc (hl) ld a,(ALASRf) ; Look for boss shot cp 1 jp z,UPBLSR1 ; Jump to update shot if there already is one ld a,(SHIPx) ; Move ship x value to boss shot destination add a,6 ld (BOSSld),a ld a,1 ; Set laserflag ld (ALASRf),a ld a,(BOSSx) ; Boss shot init x-coordinate add a,12 ld (ALASRx),a ld a,40 ; Boss shot init y-coordinate ld (ALASRy),a jp SKP57 UPBLSR1: ld a,(ALASRy) ; Erase old laserbeam ld e,a ld a,(ALASRx) ld hl,25*8+SPRITES call CLRSPR ld a,(ALASRy) ; Update boss shot y-coordinate ld b,a ld a,(BOSSlt) and 00000001b cp 0 jp nz,SKP59 ld a,b inc a ld (ALASRy),a cp 57 ; Has boss shot reached the bottom? jp nz,SKP59 ld a,0 ; Reset laserflag ld (ALASRf),a ld a,16 ld (ALASRt),a jp SKP57 SKP59: ld a,(BOSSlt) and 00000001b cp 1 jp nz,SKP57 ld a,(BOSSld) ; -- Update boss shot x-coordinate ld b,a ld a,(ALASRx) cp b jp nz,SKP61 jp SKP57 SKP61: cp b jp c,SKP60 dec a ld (ALASRx),a jp SKP57 SKP60: inc a ld (ALASRx),a SKP57: ;ÛÛÛÛ Ship laser part 1 ÛÛÛÛ ld a,(LTIMER) ; Has timer reached zero yet? cp 0 jp z,SKP50 ld hl,LTIMER ; Update laser timer dec (hl) SKP50: ld a,(SLASRy) ; Is there a laserbeam to update? cp 252 jp z,SKP52 ld a,(SLASRy) ; Erase old laserbeam ld e,a ld a,(SLASRx) ld hl,80+SPRITES call CLRSPR SKP52: ;ÛÛÛÛ Boss movement ÛÛÛÛ ld hl,BOSSmc ; Time to move boss? inc (hl) ld a,(hl) cp 4 jp nz,SKP41 ld (hl),0 ld hl,BOSSxc ; Time to change direction? inc (hl) ld a,(hl) cp 64 jp nz,SKP40 ld (hl),0 ; Change direction ld a,(BOSSmd) neg ld (BOSSmd),a SKP40: ld a,(BOSSmd) cp 1 jp nz,MOVLEFT MOVRGTH: ld hl,8e29h+96 ; Move right ld b,32 BMOVL1: push bc ld b,12 and a BMOVL2: ld a,(hl) rr a ld (hl),a inc hl djnz BMOVL2 pop bc djnz BMOVL1 ld hl,BOSSx inc (hl) jp SKP41 MOVLEFT: ld hl,8e29h+383+96 ; Move left ld b,32 BMOVL3: push bc ld b,12 and a BMOVL4: ld a,(hl) rl a ld (hl),a dec hl djnz BMOVL4 pop bc djnz BMOVL3 ld hl,BOSSx dec (hl) SKP41: ;ÛÛÛÛ Boss and laser collision ÛÛÛÛ ld a,(SLASRy) ; Check y cp 41 jp nc,SKP54 ld a,(SLASRx) ; Check x left edge ld b,a inc b ld a,(BOSSx) cp b jp nc,SKP54 add a,32 ; Check x right edge cp b jp c,SKP54 ld hl,BOSShl dec (hl) ld a,(hl) cp 0 jp nz,SKP55 ld a,(DIFF) ld (hl),a ld b,3 ; Three pixels wide health point to erase HPL4: push bc ld hl,8e29h+23 ; Erase health point ld b,4 HPL2: push bc and a ld b,12 HPL3: ld a,(hl) rl a ld (hl),a dec hl djnz HPL3 ld bc,24 add hl,bc pop bc djnz HPL2 pop bc djnz HPL4 ld hl,BOSShp ; Update boss health points dec (hl) ld a,(hl) cp 0 jp nz,SKP55 ld a,0 ld (BOSSf),a SKP55: ld a,240 ; Make boss freeze for a while ld (BOSSmc),a ld a,32 ; Initiate laser timer ld (LTIMER),a ld a,252 ; Stop shiplaserbeam ld (SLASRy),a call USCORE ; Update score SKP54: ;ÛÛÛÛ Ship laser part 2 ÛÛÛÛ ld a,(SLASRy) ; Is there a laserbeam to update? cp 252 jp z,SKP53 ld a,(SLASRy) ; Has the laserbeam reached the top yet? cp 6 jp nz,SKP51 ld a,252 ld (SLASRy),a jp SKP53 SKP51: ld hl,SLASRy ; Move laserbeam two pixels up dec (hl) dec (hl) ld a,(SLASRy) ; Draw new laserbeam ld e,a ld a,(SLASRx) ld hl,80+SPRITES call SPRITE SKP53: ;ÛÛÛÛ Boss shot part 2 ÛÛÛÛ ld a,(ALASRf) cp 1 jp nz,SKP58 ld a,(ALASRy) ; Draw new laserbeam ld e,a ld a,(ALASRx) ld hl,25*8+SPRITES call SPRITE SKP58: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ BOSS ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß BOSSKILL ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Boss killed ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ BOSSKILL: ld ix,BOSSkr ; Get pointer to boss kill random ld b,16 BKILL2: ; Loop to erase boss with cross sprite ld a,(BOSSx) add a,(ix+0) inc ix ld e,(ix+0) inc ix push ix push bc push af push de ld hl,SPRITES call CLRSPR ; Clear a 8x8 part of the boss pop de pop af push af push de ld hl,SPRITES+72 call SPRITE ; Put the cross call BUFCOPY ld hl,24000 call WAIT ; Wait for a while pop de pop af ld hl,SPRITES call CLRSPR ; Clear cross pop bc pop ix djnz BKILL2 call BUFCOPY ld hl,40000 call WAIT ; Wait for a while call STGCLR ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ BOSSKILL ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß ALIENY ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Check if aliens has reached the last line ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ALIENY: ld a,(ALIENmy) ; Look for alien movement change cp 0 ret nz ld c,26 ; Get right y-value to compare with ld hl,ALIENr4 ld b,3 GETYL: ld a,(hl) cp 0 jp nz,LXIT01 ld a,c add a,10 ld c,a dec hl djnz GETYL LXIT01: ld a,(ALIENli) cp c jp nz,DONE9 ;ÛÛÛÛ Aliens has reached bottom ÛÛÛÛ ld b,6 INVL5: push bc call INVERT pop bc djnz INVL5 ld a,0 ld (LIVESb),a ld a,'0' ld (LIVESa),a call STAT ; Show stats in a box and wait for 2nd ld hl,02621h ; - Print msg to press 2nd ld (08252h),hl ; Update cursorslocation ld hl,MSG01 call 04781h ; Vputs call WAIT2ND ; Wait for 2nd to be pressed ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir call GAMEOVER DONE9: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ ALIENY ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß MATH ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Mathsteacher key ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ MATH: ld hl,8e29h ; Copy graphbuf to safe ram area ld de,8265h ld bc,768 ldir call BUFCLR ; Clear graphbuf call BUFCOPY call HOMEUP ld hl,MSG05 call STRING call READKEY ; Fetch first MATH press KEYL3: call READKEY ; Wait for MATH press call OP2TOP1 call CONVOP1 cp 41 jp nz,KEYL3 ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir call BUFCOPY ld hl,65000 call WAIT ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ MATH ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß STGCLR ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Stage cleared ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ STGCLR: inc sp ; Don't return to ALIENS/BOSSKILL inc sp inc sp ; Don't return to MAIN/MBOSS inc sp ;ÛÛÛÛ Draw a box and print info ÛÛÛÛ ld a,20 ; Draw a box ld e,12 ld b,5 ld c,2 call BOX set 7,(iy+20) ld hl,01018h ; - Print Stage Cleared! ld (08252H),hl ; Update cursorslocation ld hl,MSG04 call 04781h ; Vputs ld hl,01920h ; - Print "BONUS:" ld (08252H),hl ; Update cursorslocation ld hl,BONUS call 04781h ; Vputs ld hl,01935h ; - Print bonus points ld (08252H),hl ; Update cursorslocation ld hl,BONUS3 call 04781h ; Vputs call BUFCOPY ;ÛÛÛÛ Bonus counter ÛÛÛÛ ld a,(BONUSt2) ; Get number of bonus points cp 0 jp z,SKP84 ld b,a SCRL4: push bc ld hl,(SCOREb) ; Give player one point inc hl ld (SCOREb),hl ld hl,SCR1 ; -- Update the ascii score inc (hl) ld b,3 ; Look for overflow loop SCRL3: ld a,(hl) cp ':' jp nz,SKP80 ld (hl),'0' dec hl inc (hl) djnz SCRL3 SKP80: ld hl,BONUS1 ; -- Update the bonus score inc (hl) ld b,3 ; Look for overflow loop SCRL5: ld a,(hl) cp ':' jp nz,SKP81 ld (hl),'0' dec hl inc (hl) djnz SCRL5 SKP81: ld hl,01935h ; - Print bonus points ld (08252H),hl ; Update cursorslocation ld hl,BONUS3 call 04781h ; Vputs call BUFCOPY pop bc djnz SCRL4 SKP84: ld hl,02221h ; - Print msg to press 2nd ld (08252H),hl ; Update cursorslocation ld hl,MSG01 call 04781h ; Vputs call BUFCOPY call WAIT2ND ;ÛÛÛÛ Update variables ÛÛÛÛ ld hl,858fh+100 ; Restore the variables start values ld de,SHIPx ld bc,DBYTES ldir ld hl,TIME ; Time for a boss level? inc (hl) ld a,(hl) cp 3 jp nz,SKP70 ld (hl),0 ld a,1 ld (BOSSf),a jp SKP71 SKP70: ld a,(STARTy) add a,2 ld (STARTy),a ld c,a ld ix,ALIENd1+2 ; - Update aliens y-coordinates ld (ALIENli),a ; Update nr of lines aliens has moved down ld de,3 ld b,32 LOOP01: ld a,(ix+0) add a,c ld (ix+0),a add ix,de djnz LOOP01 SKP71: ld hl,LEVELa ; Increase level inc (hl) ld hl,LEVELb inc (hl) ld a,(hl) ; Last level? cp 10 jp nz,SKP75 call OUTRO ; Then call outro SKP75: call LVINIT ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ STGCLR ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß COLDT3 ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Collision detection between barrier and laser ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ COLDT3: ;ÛÛÛÛ Alien laser and barrier ÛÛÛÛ ld a,(ALASRf) ; Is there an alien laser beam? cp 0 jp z,SKP20 ld a,(ALASRy) ; Has the laserbeam reached the barriersection? add a,7 cp 47 jp c,SKP20 ld a,(ALASRy) ; Has the laserbeam left the barriersection? add a,7 cp 55 jp nc,SKP20 ld a,(ALASRy) ; Get laser y-coordinate add a,7 ld e,a ld hl,0 ; Do y*12 ld d,0 add hl,de add hl,de add hl,de add hl,hl add hl,hl ld a,(ALASRx) ; Get laser x-coordinate ld e,a ld d,0 ; Do x/8 srl e srl e srl e add hl,de ld bc,8e29h+12 ; Add graphbuf address + one line add hl,bc ld c,10000000b ; Initiate laserpoint ld a,(ALASRx) ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is the beam aligned to 8*n,y? jp z,SKP21 ld b,a SHLOP3: srl c ; Shift the point to get right pixel bit djnz SHLOP3 SKP21: ld a,(hl) ; Get barrier byte and c ; And with laser point cp 0 jp z,SKP20 ld a,(hl) xor c ld (hl),a ld a,(ALASRy) ; Erase alien laser ld e,a ld a,(ALASRx) ld hl,80+SPRITES call CLRSPR ld ix,(ALASRp) ; Redraw alien ld l,(ix+0) ld a,0 cp l jp z,SKP27 ld h,0 ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) call SPRITE SKP27: ld a,0 ; Reset the alien laser flag ld (ALASRf),a SKP20: ;ÛÛÛÛ Player laser and barrier ÛÛÛÛ ld a,(SLASRy) ; Is there an alien laser beam? cp 252 jp z,SKP22 ld a,(SLASRy) ; Has the laserbeam reached the barriersection? cp 57 jp nc,SKP22 ld a,(SLASRy) ; Has the laserbeam left the barriersection? cp 48 jp c,SKP22 ld a,(SLASRy) ; Get laser y-coordinate ld e,a ld hl,0 ; Do y*12 ld d,0 add hl,de add hl,de add hl,de add hl,hl add hl,hl ld a,(SLASRx) ; Get laser x-coordinate ld e,a ld d,0 ; Do x/8 srl e srl e srl e add hl,de ld bc,8e29h-12 ; Add graphbuf address - one line add hl,bc ld c,10000000b ; Initiate laserpoint ld a,(SLASRx) ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is the beam aligned to 8*n,y? jp z,SKP23 ld b,a SHLOP4: srl c ; Shift the point to get right pixel bit djnz SHLOP4 SKP23: ld a,(hl) ; Get barrier byte and c ; And with laser point cp 0 jp z,SKP22 ld a,(hl) xor c ld (hl),a ld a,(SLASRy) ; Erase player laser ld e,a ld a,(SLASRx) ld hl,80+SPRITES call CLRSPR ld a,16 ; Initiate laser timer ld (LTIMER),a ld a,252 ; Reset the alien laser flag ld (SLASRy),a SKP22: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ COLDT3 ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß GAMEOVER ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Game Over ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ GAMEOVER: ld a,24 ld e,24 ld b,4 ld c,0 call BOX set 7,(iy+20) ; Enable text-direct-to-lcd ld hl,01d1fh ; - Print Game Over ld (08252H),hl ; Update cursorslocation ld hl,MSG02 call 04781h ; Vputs ld a,(SCOREb+1) ; Check for new highscore ld b,a ld a,(HSCOREb+1) cp b jp c,HIGH jp z,NXT03 jp NOHIGH NXT03: ld a,(SCOREb) ld b,a ld a,(HSCOREb) cp b jp c,HIGH jp NOHIGH HIGH: ; Update highscore ld hl,(SCOREb) ld (HSCOREb),hl ld a,(SCR1) ld (HSCR1),a ld a,(SCR2) ld (HSCR2),a ld a,(SCR3) ld (HSCR3),a ld a,(SCR4) ld (HSCR4),a NOHIGH: ld b,100 ; Wait for a while WAITL7: push bc call BUFCOPY pop bc djnz WAITL7 call NEWGAME ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ GAMEOVER ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß STAT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Print player status in a box and wait for 2nd ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ STAT: ld hl,8e29h ; Copy graphbuf to safe ram area ld de,8265h ld bc,768 ldir ld a,16 ; Draw a box ld e,8 ld b,6 ld c,3 call BOX res 7,(iy+20) ; Print text to LCD only ld hl,00b16h ; - Print title text ld (08252H),hl ; Update cursorslocation ld hl,PRGNAME call 04781h ; Vputs ld hl,01316h+7 ; - Print score text ld (08252H),hl ; Update cursorslocation ld hl,SCORE call 04781h ; Vputs ld hl,0132dh+7 ; - Print score number ld (08252H),hl ; Update cursorslocation ld hl,SCR4 call 04781h ; Vputs ld hl,01916h+7 ; - Print level text ld (08252H),hl ; Update cursorslocation ld hl,LEVEL call 04781h ; Vputs ld hl,01939h+7 ; - Print level number ld (08252H),hl ; Update cursorslocation ld hl,LEVELa call 04781h ; Vputs ld hl,01f16h+7 ; - Print lives text ld (08252H),hl ; Update cursorslocation ld hl,LIVES call 04781h ; Vputs ld hl,01f39h+7 ; - Print lives number ld (08252H),hl ; Update cursorslocation ld hl,LIVESa call 04781h ; Vputs ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ STAT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß COLDT2 ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Collision detection between alien laser and player ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ COLDT2: ld a,(ALASRf) ; Is there an alien laser beam? cp 0 ret z ;ÛÛÛÛ Scan in y ÛÛÛÛ ld a,(BOSSf) cp 1 jp nz,SKP64 ld a,(ALASRy) ; Reached the player in y-level yet? add a,7 cp 59 ret c jp SKP65 SKP64: ld a,(ALASRy) ; Reached the player in y-level yet? add a,7 cp 59 ret c SKP65: ;ÛÛÛÛ Scan in x ÛÛÛÛ ld a,(BOSSf) cp 1 jp nz,SKP66 ld a,(ALASRx) ; Get boss shot x-coordinate add a,7 ld c,a ld a,(SHIPx) ; Get player x-coordinate cp c ret nc ; Return if not above jp SKP67 SKP66: ld a,(ALASRx) ; Get alien laserbeam x-coordinate inc a ld c,a ld a,(SHIPx) ; Get player x-coordinate cp c ret nc ; Return if not above SKP67: ld a,(ALASRx) ; Get alien laserbeam x-coordinate inc a ld c,a ld a,(SHIPx) ; Get player x-coordinate+13 add a,13 cp c ret c ; Return if above ;ÛÛÛÛ !!! HIT !!! ÛÛÛÛ ld a,(BOSSf) cp 1 jp z,SKP62 ld a,(ALASRy) ; Erase alien laser ld e,a ld a,(ALASRx) ld hl,80+SPRITES call CLRSPR ld a,128 ; Init alien laser timer ld (ALASRt),a jp SKP63 SKP62: ld a,(ALASRy) ; Erase alien laser ld e,a ld a,(ALASRx) ld hl,25*8+SPRITES call CLRSPR ld a,32 ld (ALASRt),a SKP63: ld a,0 ; Reset the alien laser flag ld (ALASRf),a ld e,56 ld a,(OSHIPx) ; Load x-coordinate ld hl,88+SPRITES call CLRSPR ; Erase ship ld e,56 ld a,(OSHIPx) ; Load x-coordinate add a,8 ld hl,96+SPRITES call CLRSPR ; Erase ship ld e,56 ld a,(SHIPx) ; Load x-coordinate ld hl,176+SPRITES call SPRITE ; Draw wreck ld e,56 ld a,(SHIPx) ; Load x-coordinate add a,8 ld hl,184+SPRITES call SPRITE ; Draw wreck ld a,(BOSSf) ; Don't redraw alien if it was a boss shot cp 1 jp z,SKP26 ld ix,(ALASRp) ; Redraw alien ld l,(ix+0) ld a,0 cp l jp z,SKP26 ld h,0 ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) call SPRITE SKP26: ld hl,LIVESa ; Decrement lives left dec (hl) ld hl,LIVESb dec (hl) call INVERT call INVERT call STAT ; Show stats in a box and wait for 2nd ld hl,02621h ; - Print msg to press 2nd ld (08252h),hl ; Update cursorslocation ld hl,MSG01 call 04781h ; Vputs call WAIT2ND ; Wait for 2nd to be pressed ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir ld hl,LIVESb ; Last life? ld a,(hl) cp 0 jp nz,SKP18 call GAMEOVER SKP18: ld a,16 ; Initiate laser timer ld (LTIMER),a ld a,0 ld (SHIPx),a DONE8: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ COLDT2 ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß ALASR ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Alien laser ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ALASR: ld a,(ALASRt) ; Alien laser timer = 0 yet? cp 0 jp z,SKP24 ld hl,ALASRt ; Update alien laser timer dec (hl) ret SKP24: ld a,(ALASRf) ; Look for alien laserbeam cp 1 jp z,UPLASR ; Jump to update laser if there already is one ld a,(DIFF) ; If DIFF=3, shoot now cp 3 jp z,SKP74 ld a,(ALIENc) ; Has every single alien moved yet? cp 0 ret nz SKP74: ;ÛÛÛÛ Look for ship in alien x area ÛÛÛÛ ld ix,ALAST SCNX1: ; Scan x ld b,32 ; 32 possible aliens SCNXL1: ld a,(ix) ; Pointer to the alien line data cp 0 ; Is the alien dead? jp z,NXT02 ld a,(SHIPx) ; Get player x-coordinate add a,4 ld c,(ix+1) ; Get alien x-coordinate cp c jp c,NXT02 ; Jump if below ld a,(ix+1) ; Get alien x-coordinate+8 add a,8 ld c,a ld a,(SHIPx) ; Get player x-coordinate cp c jp nc,NXT02 ; Jump if not below jp CFREE NXT02: dec ix ; Next alien in datalist dec ix dec ix djnz SCNXL1 jp DONE6 ; No ship in any alien x area CFREE: ld (TEMP),ix ld hl,(TEMP) ld de,-ALIENd1 add hl,de ld (TEMP2),hl ld de,(TEMP2) ld c,e ld hl,(TEMP) ld de,24 ld b,4 ; Check if there's an alien under FREEL: ld a,c add a,24 cp 96 jp nc,LXIT02 ld c,a add hl,de ld a,(hl) cp 0 jp nz,NOFREE djnz FREEL NOFREE: jp DONE6 ; There's at least one alien under, don't shoot LXIT02: ; No alien under, shoot! ;ÛÛÛÛ Initiate alien laser ÛÛÛÛ FIRE: ld a,r ; Init alien laser srl a and 00000001b ld b,a ld a,(ix+1) add a,4 add a,b ld (ALASRx),a ld a,(ix+2) ld (ALASRy),a ld a,1 ld (ALASRf),a ld (ALASRp),ix jp DONE6 ;ÛÛÛÛ Update alien laser ÛÛÛÛ UPLASR: ld a,(ALASRy) ; Erase old alien laser ld e,a ld a,(ALASRx) ld hl,80+SPRITES call CLRSPR ld a,(ALASRy) ; Update alien laser y-coordinate inc a ld (ALASRy),a cp 57 ; Has alien laser reached the bottom? jp nz,SKP16 ld a,0 ; If so, reset the alien laser flag ld (ALASRf),a jp DONE6 SKP16: ld e,a ; Draw new alien laser ld a,(ALASRx) ld hl,80+SPRITES call SPRITE ld ix,(ALASRp) ; Draw alien over laser ld a,(ix) cp 0 jp z,DONE6 ld h,0 ld l,(ix) ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) call SPRITE DONE6: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ ALASR ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß ALIENS ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Move the aliens ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ALIENS: ;ÛÛÛÛ Check if alien is RIP'ing ÛÛÛÛ ld a,(RIPt) cp 0 jp z,NXT01 cp 1 jp nz,SKP14 ld ix,(RIPp) ; Erase RIP ld (ix+0),0 ld a,(ix+1) ; Get x-coordinate for alien ld e,(ix+2) ; Get y-coordinate for alien ld hl,72+SPRITES call CLRSPR ld a,(ALIENk) ; Last alien? cp 32 jp nz,SKP14 call STGCLR SKP14: ld a,(RIPt) dec a ld (RIPt),a ret ;ÛÛÛÛ Calculate pointer to alien data ÛÛÛÛ NXT01: ld ix,ALIENd1 ; Get pointer to alien data ld a,(ALIENc) ; Get current offset in alien data ld c,a ; Do c*3 add a,c add a,c ld c,a ld b,0 add ix,bc ;ÛÛÛÛ Check if alien is dead ÛÛÛÛ ld a,(ix+0) ; Check if alien is dead cp 0 jp nz,SKP11 ld hl,ALIENc ; Update alien counter inc (hl) ld a,(hl) cp 32 ; Time to reset counter? jp nz,NXT01 jp RESC1 ; Reset counter and return to main ;ÛÛÛÛ Erase old alien ÛÛÛÛ SKP11: ld l,a ; Erase old alien ld h,0 ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) push ix call CLRSPR pop ix ;ÛÛÛÛ Update alien data ÛÛÛÛ ld a,(ALIENa) ; Anim frame add a,(ix+0) ld (ix+0),a ld a,(ALIENmy) ; Y-coordinate add a,(ix+2) ld (ix+2),a ld a,(ALIENmy) ; Skip x movement if y movement cp 0 jp nz,NOXMOV ld a,(ALIENm) ; X-coordinate add a,(ix+1) ld (ix+1),a cp 88 ; Aliens reached the right edge? jp nz,SKP9 ld a,1 ld (ALIENmc),a jp SKP10 SKP9: cp 0 ; Aliens reached the left edge? jp nz,SKP10 ld a,1 ld (ALIENmc),a ; Set movement change flag NOXMOV: ;ÛÛÛÛ Draw new alien ÛÛÛÛ SKP10: ld l,(ix+0) ; Draw new alien ld h,0 ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) call SPRITE ;ÛÛÛÛ Update alien counter ÛÛÛÛ SKP8: ld hl,ALIENc ; Update alien counter inc (hl) ld a,(hl) cp 32 ; Time to reset counter? jp nz,DONE3 RESC1: ld (hl),0 ; Reset alien counter ld a,(ALIENa) ; Change anim frame add neg ld (ALIENa),a ld a,0 ld (ALIENmy),a ; Reset alien y movement flag ;ÛÛÛÛ Look for alien movement change ÛÛÛÛ ld a,(ALIENmc) ; Look for alien movement change cp 1 jp nz,DONE3 ld a,(ALIENm) ; Change direction in movement neg ld (ALIENm),a ld a,(ALIENys) ; Get alien y speed ld (ALIENmy),a ; Set alien y movement flag ld b,a ld a,(ALIENli) add a,b ld (ALIENli),a ; Increase lines alien has moved down ld a,0 ; Reset alien movement change flag ld (ALIENmc),a DONE3: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ ALIENS ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß COLDT1 ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Collision detection between alien and laser ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ COLDT1: ld a,(SLASRy) ; Is there a laserbeam on screen? cp 252 ret z ;ÛÛÛÛ Scan y-coordinates ÛÛÛÛ TROW1: ld a,(ALIENli) ; Get number of lines the aliens has moved down add a,8 ld b,a ld a,(SLASRy) ; Get laserbeam y-coordinate cp b jp nc,TROW2 ; Jump if not below ld ix,ALIENd1 ld hl,ALIENr1 jp SCAN1 TROW2: ld a,(ALIENli) ; Get number of lines the aliens has moved down add a,18 ld b,a ld a,(SLASRy) ; Get laserbeam y-coordinate cp b jp nc,TROW3 ; Jump if not below ld ix,ALIENd2 ld hl,ALIENr2 jp SCAN1 TROW3: ld a,(ALIENli) ; Get number of lines the aliens has moved down add a,28 ld b,a ld a,(SLASRy) ; Get laserbeam y-coordinate cp b jp nc,TROW4 ; Jump if not below ld ix,ALIENd3 ld hl,ALIENr3 jp SCAN1 TROW4: ld a,(ALIENli) ; Get number of lines the aliens has moved down add a,38 ld b,a ld a,(SLASRy) ; Get laserbeam y-coordinate cp b jp nc,DONE2 ; Jump if not below ld ix,ALIENd4 ld hl,ALIENr4 jp SCAN1 ;ÛÛÛÛ Scan x-coordinates ÛÛÛÛ SCAN1: ld b,8 ; Eight possible aliens SCAN1L: ld a,(ix) ; Pointer to the alien line data cp 0 ; Is the alien dead? jp z,NXT0 ld a,(SLASRx) ; Get laserbeam x-coordinate ld c,(ix+1) ; Get alien x-coordinate cp c jp c,NXT0 ; Jump if below ld a,(ix+1) ; Get alien x-coordinate+8 add a,8 ld c,a ld a,(SLASRx) ; Get laserbeam x-coordinate cp c jp nc,NXT0 ; Jump if not below jp HIT NXT0: inc ix inc ix inc ix djnz SCAN1L jp DONE2 ;ÛÛÛÛ Erase the alien and the laserbeam ÛÛÛÛ HIT: dec (hl) ; ALIENrX=ALIENrX-1 ld h,0 ; -- Erase the alien and the laserbeam ld l,(ix+0) ld bc,SPRITES add hl,bc ld (ix+0),72 ; Erase alien in alien datalist (72=RIP) ld a,(ix+1) ; Get x-coordinate for alien ld e,(ix+2) ; Get y-coordinate for alien push ix call CLRSPR pop ix ld a,(SLASRy) ; Erase laserbeam ld e,a ld a,(SLASRx) ld hl,80+SPRITES push ix call CLRSPR pop ix ld a,252 ld (SLASRy),a call USCORE ld hl,ALIENk ; Update number of killed aliens inc (hl) ld a,16 ; Initiate laser timer ld (LTIMER),a ;ÛÛÛÛ R.I.P. alien ÛÛÛÛ ld a,(ix+1) ; Get x-coordinate for alien ld e,(ix+2) ; Get y-coordinate for alien ld hl,72+SPRITES push ix call SPRITE ; Blit RIP pop ix ld (RIPp),ix ; Init pointer and counter ld a,16 ld (RIPt),a DONE2: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ COLDT1 ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß SCORE ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Update score ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ USCORE: ;ÛÛÛÛ Update score ÛÛÛÛ ld a,(DIFF) ld b,a POINTL: push bc ; Point loop based on DIFF ld hl,(SCOREb) ; Give player point(s) inc hl ld (SCOREb),hl ld hl,SCR1 ; -- Update the ascii score inc (hl) ld b,3 ; Look for overflow loop SCRL: ld a,(hl) cp ':' jp nz,SKP17 ld (hl),'0' dec hl inc (hl) djnz SCRL SKP17: pop bc djnz POINTL ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ SCORE ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß LASER ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Update the ship's laserbeam ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ LASER: ld a,(LTIMER) ; Has timer reached zero yet? cp 0 jp z,SKP12 ld hl,LTIMER ; Update laser timer dec (hl) SKP12: ld a,(SLASRy) ; Is there a laserbeam to update? cp 252 ret z ld a,(SLASRy) ; Erase old laserbeam ld e,a ld a,(SLASRx) ld hl,80+SPRITES call CLRSPR ld a,(SLASRy) ; Has the laserbeam reached the top yet? cp 0 jp nz,SKP01 ld a,252 ld (SLASRy),a ret SKP01: ld hl,SLASRy ; Move laserbeam two pixels up dec (hl) dec (hl) ld a,(SLASRy) ; Draw new laserbeam ld e,a ld a,(SLASRx) ld hl,80+SPRITES call SPRITE DONE4: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ LASER ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß SHIP ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Update the ship ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ SHIP: ;ÛÛÛÛ Update the ship ÛÛÛÛ ld e,56 ld a,(OSHIPx) ; Load old x-coordinate ld hl,88+SPRITES call CLRSPR ; Erase last ship ld e,56 ld a,(OSHIPx) ; Load old x-coordinate add a,8 ld hl,96+SPRITES call CLRSPR ; Erase last ship ld e,56 ld a,(SHIPx) ; Load x-coordinate ld hl,88+SPRITES call SPRITE ; Draw new ship ld e,56 ld a,(SHIPx) ; Load x-coordinate add a,8 ld hl,96+SPRITES call SPRITE ; Draw new ship ld a,(SHIPx) ; Update coordinates ld (OSHIPx),a ;ÛÛÛÛ Update bonus ÛÛÛÛ ld a,(BONUSt2) ; If bonus = 0, don't dec any more cp 0 jp z,SKP83 ld hl,BONUSdc dec (hl) ld a,(hl) cp 0 jp nz,SKP83 ld a,(DIFF) ld (BONUSdc),a ld hl,BONUSt1 ; Dec lower byte dec (hl) ld a,(hl) cp 0 jp nz,SKP83 ld (hl),20 inc hl ; Dec higher byte (the actual bonus score) dec (hl) SKP83: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ SHIP ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß KEYS ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Look for keypress ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ KEYS: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0feh ; Enable the arrows out (1),a in a,(1) cp 253 ; Has anyone pressed left? jp nz,NOLEFT ld hl,SHIPx ld a,(hl) cp 0 ; Check for left edge jp z,NOLEFT dec (hl) ; Decrease SHIPx NOLEFT: cp 251 ; Has anyone pressed right? jp nz,NORIGHT ld hl,SHIPx ld a,(hl) cp 83 ; Check for right edge jp z,NORIGHT inc (hl) ; Increase SHIPx NORIGHT: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0bfh ; Enable the row with 2nd out (1),a in a,(1) cp 223 ; Has anyone pressed 2nd jp nz,NO2nd ld a,(SLASRy) ; Check if there already is a laserbeam cp 252 jp nz,NO2nd ld a,(LTIMER) ; Ok to fire laser? cp 0 jp nz,NO2nd ld a,(SHIPx) ; Initiate laser add a,6 ld (SLASRx),a ld a,58 ld (SLASRy),a NO2nd: cp 191 ; Has anyone pressed MODE? jp nz,NOMODE call PAUSE NOMODE: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0fdh ; Enable the row with CLEAR out (1),a in a,(1) cp 191 ; Check for CLEAR jp nz,NOCLR ; Exit if clear is pressed inc sp ; Adjust stack inc sp call XIT NOCLR: ld a,0ffh ; Reset the keyport (kinda) out (1),a ld a,0dfh ; Enable the row with MATH out (1),a in a,(1) cp 191 ; Has anyone pressed MATH jp nz,NOMATH call MATH NOMATH: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ KEYS ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß WAIT2ND ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Wait for 2nd to be pressed ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ WAIT2ND: call READKEY ; Fetch first 2nd press KEYL2: call READKEY ; Wait for 2nd press call OP2TOP1 call CONVOP1 cp 21 jp nz,KEYL2 ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ WAIT2ND ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß INVERT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Inverts the graphbuf ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ INVERT: ld de,8e29h ; Invert graphbuf ld hl,768 ld bc,-1 INVL1: ld a,(de) cpl ld (de),a inc de add hl,bc jp c,INVL1 ld b,8 WAITL2: push bc call BUFCOPY pop bc djnz WAITL2 ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ INVERT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß PAUSE ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Pause and show stats ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PAUSE: call STAT ld hl,0261fh ; - Print msg to press MODE ld (08252H),hl ; Update cursorslocation ld hl,MSG03 call 04781h ; Vputs call READKEY ; Fetch first mode press KEYL1: call READKEY ; Wait for mode press call OP2TOP1 call CONVOP1 cp 22 jp nz,KEYL1 ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir ld b,16 ; Wait for a while WAITL1: push bc call BUFCOPY pop bc djnz WAITL1 ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ PAUSE ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß BOX ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Draws a box @ a,e with size b,c ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ BOX: ld (BOXx),a ld (TEMP),a ld a,e ld (BOXy),a ld a,b ld (BOXxs),a ld a,c ld (BOXys),a ld bc,13*8 ; - Left upper corner ld (BOXp),bc call DBOX ld a,(BOXx) add a,8 ld (BOXx),a ld bc,14*8 ; - Middle of first row ld (BOXp),bc ld a,(BOXxs) ld b,a BOXL1: push bc call DBOX pop bc ld a,(BOXx) add a,8 ld (BOXx),a djnz BOXL1 ld bc,15*8 ; - Right upper corner ld (BOXp),bc call DBOX ld a,(TEMP) ld (BOXx),a ld a,(BOXy) add a,8 ld (BOXy),a ld a,(BOXys) cp 0 jp z,SKP19 ld b,a BOXL2: push bc ld bc,16*8 ; - Left edge ld (BOXp),bc call DBOX ld a,(BOXx) add a,8 ld (BOXx),a ld bc,21*8 ; - Middle of box ld (BOXp),bc ld a,(BOXxs) ld b,a BOXL3: push bc call DBOX pop bc ld a,(BOXx) add a,8 ld (BOXx),a djnz BOXL3 ld bc,17*8 ; - Right edge ld (BOXp),bc call DBOX ld a,(TEMP) ld (BOXx),a ld a,(BOXy) add a,8 ld (BOXy),a pop bc djnz BOXL2 SKP19: ld bc,18*8 ; - Left lower corner ld (BOXp),bc call DBOX ld a,(BOXx) add a,8 ld (BOXx),a ld bc,19*8 ; - Middle of last row ld (BOXp),bc ld a,(BOXxs) ld b,a BOXL4: push bc call DBOX pop bc ld a,(BOXx) add a,8 ld (BOXx),a djnz BOXL4 ld bc,20*8 ; - Right lower corner ld (BOXp),bc call DBOX jp DONE7 DBOX: ld a,(BOXy) ; -- Erase area under and draw boxsprite ld e,a ld a,(BOXx) ld hl,SPRITES call CLRSPR ld a,(BOXy) ld e,a ld a,(BOXx) ld hl,(BOXp) ld bc,SPRITES add hl,bc call SPRITE ret DONE7: call BUFCOPY ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ BOX ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß SPRITE ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Blit or erase sprite þ a=x, e=y, hl=sprite address ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ SPRITE: push hl ; Save sprite address ;ÛÛÛÛ Calculate the address in graphbuf ÛÛÛÛ ld hl,0 ; Do y*12 ld d,0 add hl,de add hl,de add hl,de add hl,hl add hl,hl ld d,0 ; Do x/8 ld e,a srl e srl e srl e add hl,de ld de,8e29h add hl,de ; Add address to graphbuf ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is this sprite aligned to 8*n,y? jp z,ALIGN ;ÛÛÛÛ Non aligned sprite blit starts here ÛÛÛÛ pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,8 ; Line loop LILOP: ld b,(ix+0) ; Get sprite data ld c,0 ; Shift loop push de SHLOP: srl b rr c dec d jp nz,SHLOP pop de ld a,b ; Write line to graphbuf or (hl) ld (hl),a inc hl ld a,c or (hl) ld (hl),a ld bc,11 ; Calculate next line address add hl,bc inc ix ; Inc spritepointer dec e jp nz,LILOP ; Next line jp DONE1 ;ÛÛÛÛ Aligned sprite blit starts here ÛÛÛÛ ALIGN: ; Blit an aligned sprite to graphbuf pop de ; de->sprite ld b,8 ALOP1: ld a,(de) or (hl) ; xor=erase/blit ld (hl),a inc de push bc ld bc,12 add hl,bc pop bc djnz ALOP1 DONE1: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ SPRITE ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß CLRSPR ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Blit or erase sprite þ a=x, e=y, hl=sprite address ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CLRSPR: push hl ; Save sprite address ;ÛÛÛÛ Calculate the address in graphbuf ÛÛÛÛ ld hl,0 ; Do y*12 ld d,0 add hl,de add hl,de add hl,de add hl,hl add hl,hl ld d,0 ; Do x/8 ld e,a srl e srl e srl e add hl,de ld de,8e29h add hl,de ; Add address to graphbuf ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is this sprite aligned to 8*n,y? jp z,ALIGN2 ;ÛÛÛÛ Non aligned sprite erase starts here ÛÛÛÛ pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,8 ; Line loop LILOP2: ld b,(ix+0) ; Get sprite data ld c,0 ; Shift loop push de SHLOP2: srl b rr c dec d jp nz,SHLOP2 pop de ld a,b ; Write line to graphbuf cpl and (hl) ld (hl),a inc hl ld a,c cpl and (hl) ld (hl),a ld bc,11 ; Calculate next line address add hl,bc inc ix ; Inc spritepointer dec e jp nz,LILOP2 ; Next line jp DONE5 ;ÛÛÛÛ Aligned sprite erase starts here ÛÛÛÛ ALIGN2: ; Erase an aligned sprite in graphbuf pop de ; de->sprite ld b,8 ALOP2: ld a,(de) cpl and (hl) ld (hl),a inc de push bc ld bc,12 add hl,bc pop bc djnz ALOP2 DONE5: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ CLRSPR ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß WAIT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Wait for a while þ hl=times to do waitloop ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ WAIT: push bc ld bc,-1 WAITL: ld (TEMP),bc ; This instruction takes 20 cycles to execute add hl,bc jp c,WAITL pop bc ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ WAIT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß LVINIT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Level init ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ LVINIT: call BUFCLR ; Clear the graphbuf ld a,'0' ; - Init bonus variables ld (BONUS1),a ld (BONUS2),a ld (BONUS3),a ld a,20 ld (BONUSt1),a ld a,128 ld (BONUSt2),a ld a,(DIFF) ld (BONUSdc),a ld a,(BOSSf) cp 1 jp z,BOSSINI ;ÛÛÛÛ Initiate barrier ÛÛÛÛ ld a,8 ; Initiate barrier 1 ld e,48 ld hl,SPRITES+8 call SPRITE ld a,16 ld e,48 ld hl,SPRITES+16 call SPRITE ld a,40 ; Initiate barrier 2 ld e,48 ld hl,SPRITES+8 call SPRITE ld a,48 ld e,48 ld hl,SPRITES+16 call SPRITE ld a,72 ; Initiate barrier 3 ld e,48 ld hl,SPRITES+8 call SPRITE ld a,80 ld e,48 ld hl,SPRITES+16 call SPRITE ;ÛÛÛÛ Initiate aliens ÛÛÛÛ ld a,8 ; -- Initiate aliens ld e,0 ld ix,ALIENd1 ALIENL: ld a,(ix+0) cp 255 jp z,SKP25 ld l,(ix+0) ld h,0 ld bc,SPRITES add hl,bc ld a,(ix+1) ld e,(ix+2) push ix call SPRITE pop ix inc ix inc ix inc ix jp ALIENL jp SKP25 ;ÛÛÛÛ Initiate boss ÛÛÛÛ BOSSINI: ld a,(LEVELb) ; Initiate values for current boss cp 3 jp z,BOSSNR1 cp 6 jp z,BOSSNR2 jp BOSSNR3 BOSSNR1: ; Init for boss number 1 ld hl,56 ld a,9 ld (BOSShp),a ld a,3 ld (BOSShs),a ld a,160 ld (BONUSt2),a jp ENLARGE BOSSNR2: ; Init for boss number 2 ld hl,40 ld a,18 ld (BOSShp),a ld a,6 ld (BOSShs),a ld a,192 ld (BONUSt2),a jp ENLARGE BOSSNR3: ; Init for boss number 3 ld hl,24 ld a,27 ld (BOSShp),a ld a,9 ld (BOSShs),a ld a,255 ld (BONUSt2),a ENLARGE: ld bc,SPRITES ; hl contains sprite_nr*8 to enlarge add hl,bc ld de,8265h ld b,8 BINIL2: push bc ld c,10000000b ld b,4 BINIL1: ld a,(hl) ; x-enlarge loop and c cp 0 jp z,SKP43 ld a,11110000b ld (de),a jp SKP44 SKP43: ld a,0 ld (de),a SKP44: srl c ld a,(hl) and c cp 0 jp z,SKP45 ld a,(de) or 00001111b ld (de),a jp SKP46 SKP45: ld a,(de) and 11110000b ld (de),a SKP46: srl c inc de djnz BINIL1 pop bc inc de inc de inc de inc de inc de inc de inc de inc de inc hl djnz BINIL2 ld hl,8265h ld ix,8e29h+96+4 ld b,8 BINIL4: push bc ld b,4 BINIL3: ld a,(hl) ; y-enlarge loop ld (ix+0),a ld (ix+12),a ld (ix+24),a ld (ix+36),a inc ix inc hl djnz BINIL3 ld bc,44 add ix,bc ld bc,8 add hl,bc pop bc djnz BINIL4 ld hl,24*8+SPRITES ld a,(BOSShs) ld b,a ld a,0 HPL: ld e,0 ; Blit out boss health points push af push bc push hl call SPRITE pop hl pop bc pop af add a,9 djnz HPL ld a,(DIFF) ld (BOSShl),a ld a,32 ld (ALASRt),a ;ÛÛÛÛ Print stats and wait for 2nd ÛÛÛÛ SKP25: call STAT ld hl,02621h ; - Print msg to press 2nd ld (08252H),hl ; Update cursorslocation ld hl,MSG01 call 04781h ; Vputs call WAIT2ND ld de,8e29h ; Copy safe ram area to graphbuf ld hl,8265h ld bc,768 ldir ;ÛÛÛÛ Init variables ÛÛÛÛ ld a,16 ; Initiate laser timer ld (LTIMER),a ld a,(DIFF) ; Set right difficulty and 00000010b srl a ld b,a ld a,(ALIENys) add a,b ld (ALIENys),a inc sp ; Adjust stack inc sp ld a,(BOSSf) cp 1 jp nz,SKP73 ld hl,MBOSS push hl jp DONE0 SKP73: ld hl,MAIN push hl DONE0: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ LVINIT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß INIT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ INIT: call RINDOFF ; Runindicator off call BUFCLR ; Clear the graphbuf res 0,(iy+20) ; Reset G-T mode and hor. split mode res 1,(iy+20) ld de,858fh+100 ; Make backup of the variables start values ld hl,SHIPx ld bc,DBYTES ldir ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ INIT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß XIT ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Exit program and clean up ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ XIT: ld bc,HSCR4 ld a,c sub 27h ld c,a ld a,b sbc a,93h ld b,a ld hl,(PROGPTR) add hl,bc ld a,(HSCR4) ld (hl),a inc hl ld a,(HSCR3) ld (hl),a inc hl ld a,(HSCR2) ld (hl),a inc hl ld a,(HSCR1) ld (hl),a inc hl inc hl ld a,(HSCOREb) ld (hl),a inc hl ld a,(HSCOREb+1) ld (hl),a call CLRTSHD ; Clear textshadow call GOHOME ; Leave graphscreen and go to homescreen call BUFCLR ; Clear the graphbuf call READKEY ; Catch the clear press call HOMEUP ; Place cursor at home inc sp ; Adjust stack inc sp res 7,(iy+20) ; Enable text-direct-to-lcd res 6,(iy+9) ; Reset statsvalid (I've used safe ram area 2) ei ; Enable interrupts ret ; Exit program ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ XIT ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ EQUALS ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ WAITKEY .equ 4CFEh ; Wait for a key and read BUFCLR .equ 515Bh ; Clear the graph backup BUFCOPY .equ 5164h ; Copy the graph backup to the screen RINDOFF .equ 4795h ; Turn off runindicator PRINTHL .equ 4709h ; Print HL in dec. on the screen OP2TOP1 .equ 41C2h ; Move OP2 to OP1 CONVOP1 .equ 4EFCh ; Convert fp value in OP1 to a 2 byte hex READKEY .equ 4A18h ; Read key and place it in OP2 as a fp value GOHOME .equ 47A1h ; Go to home screen (finish gfx program) CLRTSHD .equ 4765h ; Clear text shadow HOMEUP .equ 4775h ; Place cursor at home STRING .equ 470Dh ; Print 0 terminated string to screen (hl->string) HTIMESL .equ 4382h ; hl=h*l ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ DATA ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ .include sprites.db .include spzlogo.db PRGNAME .db "Spaze Invaders",0 PROGPTR .dw 0 DIFF .db 1 ; Difficulty (1=easy, 2=medium, 3=hard) HSCORE .db "HighScore:",0 ; HighScore text HSCR4 .db "0" ; Multiples of thousand in ascii HSCR3 .db "3" ; Multiples of hundred in ascii HSCR2 .db "0" ; Multiples of ten in ascii HSCR1 .db "3",0 ; Multiples of one in ascii HSCOREb .dw 303 ; HighScore in binary MSG01 .db "Press 2nd",0 MSG02 .db "Game Over",0 MSG03 .db "Press MODE",0 MSG04 .db "Stage Cleared!",0 MSG05 .db "cos(42)*sin(303)",0 MSG06 .db "CONGRATULATIONS!!!",0 MSG07 .db "You have saved all the",0 MSG08 .db "hamsters on earth from",0 MSG09 .db "the evil aliens",39," claws",0 MSG10 .db "Have a nice day!",0 MSG11 .db "movax@algonet.se",0 MSG12 .db "www.algonet.se/~movax",0 TXT1 .db "By Hannes Edfeldt",0 TXT2 .db "PRESS 2nd TO START",0 TXT3 .db "EASY",0 TXT4 .db "MEDIUM",0 TXT5 .db "HARD",0 TXT6 .db "ALIEN CODE",0 TXT7 .db "presents",0 VERt .db "v1.0" ; Version text LEVEL .db "Level:",0 ; Level text LEVELa .db "1",0 ; Level in ascii LEVELb .db 1 ; Level in binary SCORE .db "Score:",0 ; Score text SCR4 .db "0" ; Multiples of thousand in ascii SCR3 .db "0" ; Multiples of hundred in ascii SCR2 .db "0" ; Multiples of ten in ascii SCR1 .db "0",0 ; Multiples of one in ascii SCOREb .dw 0 ; Player score in binary LIVES .db "Lives:",0 ; Lives text LIVESa .db "3",0 ; Lives in ascii LIVESb .db 3 ; Lives left in binary BONUS .db "Bonus:",0 ; Bonus text BONUS3 .db "0" BONUS2 .db "0" BONUS1 .db "0",0 BONUSt1 .db 20 ; Bonus timer 1 BONUSt2 .db 128 ; Bonus timer 2 (the actual bonus to get) BONUSdc .db 0 ; Bonus decrement timer BOXx .db 0 ; Box x-coordinate BOXy .db 0 ; Box y-coordinate BOXxs .db 0 ; Box x-size BOXys .db 0 ; Box y-size BOXp .dw 0 ; Box sprite ptr TEMP .db 0 ; Temp store .db 0 ; Extra temp byte TEMP2 .db 0 ; Temp store 2 .db 0 ; Extra temp byte TIME .db 1 ; Time for a boss level? STARTy .db 0 ; y-coordinate for aliens to start at SHIPx .db 0 ; Ship x-coordinate OSHIPx .db 0 ; Old ship x-coordinate SLASRx .db 0 ; Ship laser x-coordinate SLASRy .db 252 ; Ship laser y-coordinate (252=no laserbeam) LTIMER .db 0 ; 0=ok to fire laser, >0=wait ALIENm .db 2 ; Alien x movement speed ALIENys .db 1 ; Alien y movement speed (based on DIFF) ALIENmy .db 0 ; Alien movement y (0=no movement, 1=movement) ALIENmc .db 0 ; Alien movement change (0=no change, 1=time to change) ALIENli .db 0 ; How many lines down has aliens moved yet ALIENc .db 0 ; Alien counter (which alien to move) ALIENa .db 8 ; Alien anim frame add ALIENk .db 0 ; Number of aliens killed ALIENr1 .db 8 ; Aliens left in row 1 ALIENr2 .db 8 ; Aliens left in row 2 ALIENr3 .db 8 ; Aliens left in row 3 ALIENr4 .db 8 ; Aliens left in row 4 RIPt .db 0 ; RIP timer RIPp .dw 0 ; RIP pointer ALASRx .db 0 ; Alien laser x coordinate ALASRy .db 0 ; Alien laser y coordinate ALASRf .db 0 ; Alien laser flag ALASRt .db 0 ; Alien laser timer ALASRp .dw 0 ; Pointer to the alien who shot the last beam BOSSx .db 32 ; Boss x-coordinate BOSSmd .db 1 ; Boss movement direction BOSSxc .db 31 ; Boss x-movement counter BOSSmc .db 0 ; Boss "time-to-move?" counter BOSSf .db 0 ; Is this a boss level? / Boss alive? BOSShp .db 03 ; Boss health points BOSShs .db 01 ; Boss health point sprites BOSSld .db 0 ; Boss shot destination BOSSlt .db 0 ; Boss shot timer BOSShl .db 0 ; Hits left before boss lose on hp BOSSkr .db 16,8,8,32,16,24,24,8 ; Boss kill random .db 0,16,24,32,0,8,16,16 .db 24,24,8,8,0,32,8,24 .db 24,16,16,32,8,16,0,24 MENUc .db 1 ; Menu choice (1=easy, 2=medium, 3=hard) MENUoc .db 1 ; Menu old choice MENUt .db 12 ; Menu timer FLASHt .db 16 ; Flash timer FLASHf .db 0 ; Flash flag LOGOl .db 0 ; Logo line in fx process ALIENd1 .db 24,8,0 ; First line of alien data (sprite address,x,y) .db 24,18,0 .db 24,28,0 .db 24,38,0 .db 24,48,0 .db 24,58,0 .db 24,68,0 .db 24,78,0 ALIENd2 .db 40,8,10 ; Second line of alien data (sprite address,x,y) .db 40,18,10 .db 40,28,10 .db 40,38,10 .db 40,48,10 .db 40,58,10 .db 40,68,10 .db 40,78,10 ALIENd3 .db 56,8,20 ; Third line of alien data (sprite address,x,y) .db 56,18,20 .db 56,28,20 .db 56,38,20 .db 56,48,20 .db 56,58,20 .db 56,68,20 .db 56,78,20 ALIENd4 .db 56,8,30 ; Fourth line of alien data (sprite address,x,y) .db 56,18,30 .db 56,28,30 .db 56,38,30 .db 56,48,30 .db 56,58,30 .db 56,68,30 ALAST: .db 56,78,30 .db 255 ; End of alien data DBYTES .equ ($-SHIPx-1) .end ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ Spaze Invaders ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ