' Experimental software to reproduce the classic Space Invaders game ' For version 2.

1 of the PROTON+ BASIC Compiler ' Written by Les Johnson 2003. ' ' This version uses the LCDWRITE and PLOT commands to produce the graphics ' Which allows smooth movements on a pixel by pixel basis ' ' Use an 8MHz crystal ' ' BUTTON CONNECTIONS ' LEFT Button connects to PORTB.0 ' RIGHT Button connects to PORTB.1 ' FIRE Button connects to PORTB.2 ' ' SOUND CHANNEL CONNECTIONS ' Each channel is output from PORTA.0,1,2 ' Channel 1. PORTA.0 is the INVADER noise ' Channel 2. PORTA.1 is the MISSILE noise ' Channel 3. PORTA.2 is the SAUCER noise ' Each pin should have a current limiting resistor in order to stop pin to pin s horts. ' ' 1uF ' 220 +| |' PORTA.0 --/\/\/\----| |--- To SPEAKER ' | | | ' 330 | ' PORTA.1 --/\/\/\--| ' | ' 330 | ' PORTA.2 --/\/\/\--| ' ' ' * Revision 1.0 10 September 2003 ' ' Ship moving smoothly and missile working correctly ' ' * Revision 1.1 10 September 2003 ' ' Invaders moving left to right and down (got a problem with alignment when movi ng down) ' Invaders become faster as they move down ' Invader erased when missile hits, and hit counter incremented ' Bases require five hits per section before they dissapear ' There are 9 sections, three in each base ' A new sheet of invaders is created when all of them are hit ' The new sheet is slightly faster than the previous one ' ' * Revision 1.2 11 September 2003 ' ' Invaders now move down the screen without alignment problems ' Started placing subroutines to enable the invaders to fire back at the ship ' Placed the base hit check as a subroutine so that the invader's missile can al so ' be checked for a base hit. ' Invaders can now fire back, but cannot detect any hits yet. ' Both the ship's and the invader's missiles are slowed down but still need some work. ' ' * Revision 1.3 12 September 2003

' ' Both the ship's and the invaders missiles have independant speed controls ' Invader's missile now detect whether it has hit a base, and alters the base ac cordingly ' Still a problem with the invader's missile hitting the base, sometimes destroy s it with one blow ' Game now detects whether the invaders have reached the bottom of the screen. I n which case, GAME OVER ' If the invaders reach the bases, then the bases are disabled ' Invaders now have animated characters ' Bases also have animated characters that destroy with every hit with a missile ' The ship now only moves one pixel at a time instead of two. This slow the ship to a reasonable speed ' The invaders speed up whenever one is hit, and also speed up by a factor of 3 when there are 4 or less invaders left ' Invaders also speed up whenever they move down the screen ' Added simple sound effects when invaders move. This will be altered later. ' ' * Revision 1.4 13 September 2003 ' ' Flying saucer now moves right to left at the top of the screen ' Missile to missile collisions are now detected ' ' * Revision 1.5 14 September 2003 ' ' Missiles are now implemented using the PLOT command for smooth movement ' As the invaders move down the screen their missile speed slows down slightly ' Game now detects a hit on the flying saucer at the top of the screen ' There is still a problem with the invaders and the ship hitting the bases ' The base counter is decremented too quickly, or destroyed with a single hit ' ' * Revision 1.6 18 September 2003 ' ' Added scoring for invaders and saucer ' Invaders score 20 points for top row, 10 points for middle row, and 5 points f or bottom row ' Saucer scores 100 points if hit ' A small animation of the points scored is also included if the saucer or invad ers are hit. ' Added simple sound effects for invaders, saucer and missile shot. ' ' * Revision 1.7 27 September 2003 ' ' Added second missile for space invaders, but still requires some work ' because the spread of missiles is uneven. ' ' * Revision 1.8 28 September 2003 ' ' Replaced sound using the SOUND command with interrupt driven sounds ' There are three independant sound channels from PORTA0,1,2 ' Each is capable of producing a different frequency, and channel one (INVADER c hannel) also has a duration. ' With the interrupt driven sound, I have had to increase the crystal to 8MHz. ' Each layer of invader now has a different invader sprite, each consisting of t wo characters. ' Created new user defined shape for saucer and ship. ' Saucer now scores 100+ points if hit. More points gained the closer to the rig ht hand side of the screen. ' Added levels to the game. After level 10 the invaders start firing two missile s.

4 Dim Dim Dim Dim Dim Dim Dim Dim Dim INTERRUPT_COUNTER1 as Byte SYSTEM INVADER_SOUND_COUNTER as Byte SYSTEM INVADER_FREQ as Byte SYSTEM INVADER_SOUND_DURATION as Byte SYSTEM INVADER_SOUND_DURATION_COUNTER as Byte SYSTEM MISSILE_SOUND_COUNTER as Byte SYSTEM MISSILE_FREQ as Byte SYSTEM SAUCER_SOUND_COUNTER as Byte SYSTEM SAUCER_FREQ as Byte SYSTEM ' Space invader variables Dim BASE_ENABLED[9] as Byte ' Whether or not the section of the BASE is enabled Dim BASE_HITS[9] as Byte ' Holds the amount of hits each part of the bases has h ad Dim INVADER_XPOS[18] as Byte' at 400 ' Array to hold the space invader's X posit ion Dim INVADER_YPOS[18] as Byte' at 418 ' Array to hold the space invader's Y posit ion Dim INVADER_ENABLED[18] as Byte' at 436 ' Array to hold the space invader' confi g. ' After three lives the game is over. ' ' ' ' See if thare are any improvements you can make.0 Dim MISSILE_SOUND_ENABLE as NOTE_STATUS.9 01 October 2003 ' ' Invader to Ship missile collision detection is now implemented ' Each time the ship is hit a life is decremented. hit or active Dim Dim Dim Dim Dim Dim SHIP_XPOS as Byte ' X position of MISSILE_YPOS as Byte ' Y position MISSILE_XPOS as Byte ' X position MISSILE_STATUS as Byte SYSTEM MISSILE_FIRED as MISSILE_STATUS.0 MISSILE_HIT as MISSILE_STATUS.1 Dim SAUCER_SOUND_ENABLE as NOTE_STATUS. and report them on the Forum! ' Include "PROTON_G8. a large circular explosion occurs.e.1 ' BASE ship of Ship's MISSILE of Ship's MISSILE ' TRUE if Ship's MISSILE in the air Set if Ship's missile has hit something . ' Added a splash screen when the game first starts ' ' * Revision 2 04 October 2003 ' ' Score increases by one if a missile hits a missile ' If there are only 1 or 2 invaders left on the screen their speed increases dra matically ' When all the ship's lives are lost.INT" ' Game created on the PROTON board ' Set up some Variables ' Interrupt driven sound channel variables Dim NOTE_STATUS as Byte SYSTEM Dim INVADER_SOUND_ENABLE as NOTE_STATUS. i.' ' * Revision 1.2 Dim INTERNAL_INVADER_SOUND_ENABLE as NOTE_STATUS.

4 ' Indicate time to move the inv ader's missile Dim INVADER_MISSILE_FIRED as MISSILE_STATUS.Dim TIME_TO_MOVE_INVADERS as MISSILE_STATUS.6 ' Set if Invader's missile has hit s omething Dim TIME_TO_MOVE_INVADERS_DOWN as Bit ' Signal that the invaders need to move do wn Dim INVADERS_REACHED_BOTTOM as Bit ' Set if the invaders reach the botton of the screen Dim INVADER_MISSILE_SPEED as Byte ' The speed of the invader's missile.3 ' Indicate time to move the sh ip's missile Dim TIME_TO_MOVE_BASE as Bit Dim SHIP_SPEED as Byte Dim INVADER_TICK as Byte ' Constant tick within program Dim INVADER_LOOP as Byte SYSTEM ' Scans the invader arrays Dim INVADER_MISSILE_TICK as Byte Dim SHIP_MISSILE_TICK as Byte Dim TEMP_LOOP as Byte Dim INVADERS_DIRECTION as Bit Dim INVADERS_ENABLED as Byte ' Count the INVADERS enabled Dim INVADER_SPEED as Byte ' The speed of the invaders Dim BASE_XPOS_TEST as Byte ' Used for detecting a missile hit on a BASE Dim SHIP_HIT as Bit ' TRUE if ship hit by missile Dim INVADER_MISSILE_YPOS as Byte ' Y position of Invader's MISSILE Dim INVADER_MISSILE_XPOS as Byte ' X position of Invader's MISSILE Dim TIME_TO_MOVE_INV_MISSILE as MISSILE_STATUS.0 Symbol R_BUTTON = PORTB. This slows down as invader near the bottom of the screen Dim Dim Dim Dim Dim Dim Dim Dim SAUCER_XPOS as Byte SAUCER_HIT as Bit TIME_TO_MOVE_SAUCER as Bit SAUCER_SPEED as Byte SAUCER_ENABLED as Bit SCORE as Dword ' Holds the games score LEVEL as Word ' Game level LIVES as Byte ' Amount of lives left for the base ' Define some constants and alias's Symbol L_BUTTON = PORTB.2 ' Indicates whether a BASE has been hit by a mi ssile Dim TIME_TO_MOVE_SHIP_MISSILE as MISSILE_STATUS.1 .7 ' Indicate time to move the invade rs Dim BASE_HIT as MISSILE_STATUS. This slo ws down as invader near the bottom of the screen Dim DEFAULT_INVADER_SPEED as Byte ' Saves the initial speed of the invaders Dim INVADER_CHARACTER as Bit ' Determines the character to use for the invader Dim INVADER_MISSILE2_TICK as Byte Dim INVADER_MISSILE2_YPOS as Byte ' Y position of Invader's second MISSILE Dim INVADER_MISSILE2_XPOS as Byte ' X position of Invader's second MISSILE Dim TIME_TO_MOVE_INV_MISSILE2 as Bit ' Indicate time to move the invader's secon d missile Dim INVADER_MISSILE2_FIRED as Bit ' TRUE if Invader's second MISSILE in the air Dim INVADER_MISSILE2_HIT as Bit ' Set if Invader's second missile has hit someth ing Dim INVADER_MISSILE2_SPEED as Byte ' The speed of the invader's second missile.5 ' TRUE if Invader's MISSILE in the air Dim INVADER_MISSILE_HIT as MISSILE_STATUS.

minus the two outside bla nks Symbol INVADER_RIGHT_LIMIT = 127 .6 = 1 Jump INVADER_SOUND_LOOP Clrf INTERRUPT_COUNTER1 ' INTERRUPT_COUNT = 0 Bcf INTERNAL_INVADER_SOUND_ENABLE ' INTERNAL_INVADER_SOUND_ENABLE = 0 Movfw INVADER_SOUND_DURATION_COUNTER ' If((INVADER_SOUND_DURATION_COUNTER <= INV ADER_SOUND_DURATION) && (INVADER_SOUND_ENABLE == 1)) Subwf INVADER_SOUND_DURATION.W .7 ' Global Interrupt Enable ON_INTERRUPT Goto NOTE_INT '---------------------------------------------------------------------------Input L_BUTTON Input R_BUTTON Input FIRE_BUTTON Delayms 200 ' Wait for the PIC® micro to stabilise PORTB_PULLUPS = ON Cls ' Clear the LCD Goto MAIN_PROGRAM_LOOP ' Jump over any subroutines '----[NOTE GENERATING INTERRUPT HANDLER]-------------------------------------------------NOTE_INT: TMR0 = 200 Incf INVADER_SOUND_COUNTER.F Incf SAUCER_SOUND_COUNTER.INVADER_WIDTH ' The right most limit for the invaders before they need to move down Symbol SAUCER_WIDTH = 14 Symbol Symbol Symbol Symbol TRUE = 1 FALSE = 0 FORWARD = 1 BACKWARD = 0 Symbol T0IF INTCON.C Jump FINISH_NOTE1 Btfss INVADER_SOUND_ENABLE Jump FINISH_NOTE1 Incf INVADER_SOUND_DURATION_COUNTER.F ' INVADER_SOUND_DURATION_COUNTER++ Bsf INTERNAL_INVADER_SOUND_ENABLE ' INTERNAL_INVADER_SOUND_ENABLE = 1 Jump INVADER_SOUND_LOOP ' Otherwise FINISH_NOTE1: BCF INVADER_SOUND_ENABLE ' INVADER_SOUND_ENABLE = 0 CLRF INVADER_SOUND_DURATION_COUNTER ' INVADER_SOUND_DURATION_COUNTER = 0 INVADER_SOUND_LOOP: Movfw INVADER_FREQ ' If INVADER_SOUND_COUNTER >= INVADER_FREQ Subwf INVADER_SOUND_COUNTER.W Btfss STATUS.F Btfss INTERRUPT_COUNTER1.3 Symbol SHIP_WIDTH = 9 ' The width of the ship in pixels.6 ' If INTERRUPT_COUNT. This does not include t he two blanks Symbol INVADER_WIDTH = 10 ' The width of the invaders.F Incf INTERRUPT_COUNTER1.F Incf MISSILE_SOUND_COUNTER.Symbol FIRE_BUTTON = PORTB.2 ' Timer0 Overflow Interrupt Flag Symbol GIE INTCON.2 Symbol SPEAKER = PORTB.

INVADER_MISSILE_XPOS Plot INVADER_MISSILE_YPOS + 2. INVADER_MISSILE_XPOS + 1 Plot INVADER_MISSILE_YPOS + 1.W Btfss STATUS. INVADER_MISSILE_XPOS + 1 UnPlot INVADER_MISSILE_YPOS + 2. INVADER_MISSILE2_XPOS . INVADER_MISSILE_XPOS Plot INVADER_MISSILE_YPOS + 1.F ' PORTA = PORTA ^ 1 Clrf INVADER_SOUND_COUNTER ' INVADER_SOUND_COUNTER = 0 MISSILE_SOUND_LOOP: Movfw MISSILE_FREQ ' If MISSILE_SOUND_COUNTER >= MISSILE_FREQ Subwf MISSILE_SOUND_COUNTER.2 Xorwf PORTA.W Btfss STATUS. INVADER_MISSILE_XPOS + 1 Return '---------------------------------------------------------------------------' Draw or clear the second Invader's missile CLEAR_INVADER_MISSILE2: UnPlot INVADER_MISSILE2_YPOS. INVADER_MISSILE_XPOS UnPlot INVADER_MISSILE_YPOS.C Jump EXIT_INTERRUPT Clrw Btfsc SAUCER_SOUND_ENABLE Movlw 4 ' Set for tone generation on PORTA. INVADER_MISSILE_XPOS + 1 Plot INVADER_MISSILE_YPOS + 2.0 Xorwf PORTA.1 Xorwf PORTA.F ' PORTA = PORTA ^ 2 Clrf MISSILE_SOUND_COUNTER ' MISSILE_SOUND_COUNTER = 0 SAUCER_SOUND_LOOP: Movfw SAUCER_FREQ ' If SAUCER_SOUND_COUNTER >= SAUCER_FREQ Subwf SAUCER_SOUND_COUNTER.C Jump SAUCER_SOUND_LOOP Clrw Btfsc MISSILE_SOUND_ENABLE Movlw 2 ' Set for tone generation on PORTA. INVADER_MISSILE_XPOS + 1 Return DRAW_INVADER_MISSILE: UnPlot INVADER_MISSILE_YPOS. INVADER_MISSILE_XPOS UnPlot INVADER_MISSILE_YPOS.Btfss STATUS. INVADER_MISSILE_XPOS UnPlot INVADER_MISSILE_YPOS + 1.C Jump MISSILE_SOUND_LOOP Clrw Btfsc INTERNAL_INVADER_SOUND_ENABLE Movlw 1 ' Set for tone generation on PORTA.F ' PORTA = PORTA ^ 4 Clrf SAUCER_SOUND_COUNTER ' SAUCER_SOUND_COUNTER = 0 EXIT_INTERRUPT: T0IF = 0 Context Restore '---------------------------------------------------------------------------' Draw or clear the Invader's missile CLEAR_INVADER_MISSILE: UnPlot INVADER_MISSILE_YPOS. INVADER_MISSILE_XPOS UnPlot INVADER_MISSILE_YPOS + 2. INVADER_MISSILE_XPOS + 1 UnPlot INVADER_MISSILE_YPOS + 1.

INVADER_MISSILE2_XPOS + 1 Return '---------------------------------------------------------------------------' Re-Draw the bases UPDATE_BASES: Print at 6.8 + BASE_HITS#4.2 + BASE_HITS#0.2.UnPlot INVADER_MISSILE2_YPOS. INVADER_MISSILE2_XPOS Plot INVADER_MISSILE2_YPOS + 1.2 + BASE_HITS#3. ELEMENT 0 If BASE_HITS#0 < 5 AND BASE_ENABLED#0 = TRUE Then ' Is the base element enabled. INVADER_MISSILE2_XPOS + 1 Return DRAW_INVADER_MISSILE2: UnPlot INVADER_MISSILE2_YPOS.15. INVADER_MISSILE2_XPOS + 1 UnPlot INVADER_MISSILE2_YPOS + 2. ELEMENT 1 If BASE_HITS#1 < 5 AND BASE_ENABLED#1 = TRUE Then ' Is the base element enabled._ at 6.9.2 + BASE_HITS#6. and has had less than 5 hits ? Inc BASE_HITS#2 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#2 = FALSE ' Disable the base element Endif Case 54 to 59 ' Has the missile XPOS hit BASE 2. ELEMENT 2 If BASE_HITS#2 < 5 AND BASE_ENABLED#2 = TRUE Then ' Is the base element enabled. and has had less than 5 hits ? Inc BASE_HITS#3 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#3 = FALSE ' Disable the base element Endif . INVADER_MISSILE2_XPOS UnPlot INVADER_MISSILE2_YPOS + 1. INVADER_MISSILE2_XPOS + 1 UnPlot INVADER_MISSILE2_YPOS + 1. INVADER_MISSILE2_XPOS Plot INVADER_MISSILE2_YPOS + 2. INVADER_MISSILE2_XPOS UnPlot INVADER_MISSILE2_YPOS + 2._ at 6.14 + BASE_HITS#8 Return '---------------------------------------------------------------------------' Check if BASE hit by a missile ' Each base is built from three elements (characters) ' Returns with BASE_HIT set if a hit was detected CHECK_BASE_HIT: BASE_HIT = FALSE ' Default to no hit detected Select BASE_XPOS_TEST Case 12 to 17 ' Has the missile XPOS hit BASE 1.14 + BASE_HITS#2.8 + BASE_HITS#1. and has had less than 5 hits ? Inc BASE_HITS#0 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#0 = FALSE ' Disable the base element Endif Case 18 to 23 ' Has the missile XPOS hit BASE 1.8 + BASE_HITS#7.14 + BASE_HITS#5. ELEMENT 3 If BASE_HITS#3 < 5 AND BASE_ENABLED#3 = TRUE Then ' Is the base element enabled. INVADER_MISSILE2_XPOS UnPlot INVADER_MISSILE2_YPOS. and has had less than 5 hits ? Inc BASE_HITS#1 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#1 = FALSE ' Disable the base element Endif Case 24 to 29 ' Has the missile XPOS hit BASE 1. INVADER_MISSILE2_XPOS + 1 Plot INVADER_MISSILE2_YPOS + 2. INVADER_MISSILE2_XPOS + 1 Plot INVADER_MISSILE2_YPOS + 1.

ELEMENT 8 If BASE_HITS#8 < 5 AND BASE_ENABLED#8 = TRUE Then ' Is the base element enabled. and has had less than 5 hits ? Inc BASE_HITS#6 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#6 = FALSE ' Disable the base element Endif Case 96 to 101 ' Has the missile XPOS hit BASE 3.Case 60 to 65 ' Has the missile XPOS hit BASE 2. ELEMENT 6 If BASE_HITS#6 < 5 AND BASE_ENABLED#6 = TRUE Then ' Is the base element enabled. ELEMENT 5 If BASE_HITS#5 < 5 AND BASE_ENABLED#5 = TRUE Then ' Is the base element enabled. and has had less than 5 hits ? Inc BASE_HITS#7 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#7 = FALSE ' Disable the base element Endif Case 102 to 107 ' Has the missile XPOS hit BASE 3. ELEMENT 7 If BASE_HITS#7 < 5 AND BASE_ENABLED#7 = TRUE Then ' Is the base element enabled. and has had less than 5 hits ? Inc BASE_HITS#5 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#5 = FALSE ' Disable the base element Endif Case 90 to 95 ' Has the missile XPOS hit BASE 3. and has had less than 5 hits ? Inc BASE_HITS#4 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#4 = FALSE ' Disable the base element Endif Case 66 to 71 ' Has the missile XPOS hit BASE 2. and has had less than 5 hits ? Inc BASE_HITS#8 ' Increment the amount of hits the base element has sustained BASE_HIT = TRUE ' Indicate a missile has hit a target Else BASE_ENABLED#8 = FALSE ' Disable the base element Endif End Select If BASE_HIT = TRUE Then Gosub UPDATE_BASES ' Update the base shapes if a hit was detected Return '---------------------------------------------------------------------------' Move the invader's missile ' The missile can only be fired if the flag INVADER_MISSILE_FIRED is false. ' otherwise there is already a missile in the air MOVE_INVADER_MISSILE: If INVADER_MISSILE_FIRED = TRUE Then ' Don't enter the routine if the invader's missile is already flying If TIME_TO_MOVE_INV_MISSILE = TRUE Then ' Is it time to move the invader's missi le ? Gosub DRAW_INVADER_MISSILE Inc INVADER_MISSILE_YPOS Endif If INVADER_MISSILE_YPOS >= 63 OR INVADER_MISSILE_HIT = TRUE Then ' Has the invad er's missile reached the bottom of the display or hit something ? INVADER_MISSILE_FIRED = FALSE ' Yes. ELEMENT 4 If BASE_HITS#4 < 5 AND BASE_ENABLED#4 = TRUE Then ' Is the base element enabled. So signal the invader's missile is finished .

. ' If the invader is enabled. ' If it is then enable a missile to be fired. ' If the invader is enabled. Dim RANDOM_VALUE as Byte . So signal the invader's missile is finishe d Gosub CLEAR_INVADER_MISSILE2 ' Clear the invader's missile INVADER_MISSILE2_HIT = FALSE Endif Endif Return '---------------------------------------------------------------------------' Fire an invader missile if possible ' The logic is: ' Make sure a missile is not already in flight.. ' Scan all the invaders. then check if it is over the ship.Gosub CLEAR_INVADER_MISSILE ' Clear the invader's missile INVADER_MISSILE_HIT = FALSE Endif Endif Return '---------------------------------------------------------------------------' Move the invader's second missile ' The missile can only be fired if the flag INVADER_MISSILE2_FIRED is false. ' If it is then enable a missile to be fired. ' otherwise there is already a missile in the air MOVE_INVADER_MISSILE2: If INVADER_MISSILE2_FIRED = TRUE Then ' Don't enter the routine if the invader's missile is already flying If TIME_TO_MOVE_INV_MISSILE2 = TRUE Then ' Is it time to move the invader's miss ile ? Gosub DRAW_INVADER_MISSILE2 Inc INVADER_MISSILE2_YPOS Endif If INVADER_MISSILE2_YPOS >= 63 OR INVADER_MISSILE2_HIT = TRUE Then ' Has the inv ader's missile reached the bottom of the display or hit something ? INVADER_MISSILE2_FIRED = FALSE ' Yes.. ' Scan all the invaders. then check if it is over the ship. FIRE_INVADER_MISSILE: If INVADER_MISSILE_FIRED = FALSE Then ' Is it OK to fire an invader missile ? INVADER_LOOP = 0 Repeat ' Create a loop for all the invaders If INVADER_ENABLED[INVADER_LOOP] = TRUE Then ' Is this invader enabled ? Select INVADER_XPOS[INVADER_LOOP] + 5 Case SHIP_XPOS to SHIP_XPOS + 8 ' Is the invader over the ship ? INVADER_MISSILE_FIRED = TRUE ' Signal that an invader's missile is in the air INVADER_MISSILE_XPOS = INVADER_XPOS[INVADER_LOOP] + 5 ' Move missile XPOS to the middle of the invader INVADER_MISSILE_YPOS = (INVADER_YPOS[INVADER_LOOP] * 8) + 8 ' Move missile YPOS to below the invader End Select Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 ' Close the loop when all invaders have been scanned Endif Return '---------------------------------------------------------------------------' Fire an invader second missile if possible ' The logic is: ' Make sure a missile is not already in flight..

RANDOM_VAL UE INVADER_LOOP = 0 Repeat ' Create a loop for all the invaders If INVADER_ENABLED[INVADER_LOOP] = TRUE Then ' Is this invader enabled ? Select INVADER_XPOS[INVADER_LOOP] + 5 Case SHIP_XPOS to SHIP_XPOS + 8 ' Is the invader over the ship ? INVADER_MISSILE2_FIRED = TRUE ' Signal that an invader's missile is in the air INVADER_MISSILE2_XPOS = INVADER_XPOS[INVADER_LOOP] + 5 ' Move missile XPOS to th e middle of the invader INVADER_MISSILE2_YPOS = (INVADER_YPOS[INVADER_LOOP] * 8) + 8 ' Move missile YPOS to below the invader End Select Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 ' Close the loop when all invaders have been scanned EndSelect Endif Return '---------------------------------------------------------------------------' Check if the invader's missile has hit something ' Returns with INVADER_MISSILE_HIT set if the invader's missile has hit somethin g CHECK_FOR_INVADER_MISSILE_HIT: INVADER_MISSILE_HIT = FALSE ' Default to not hit If INVADER_MISSILE_FIRED = TRUE Then ' First make sure that a missile is actuall y launched ' Check if the invader's missile has hit a BASE If INVADER_MISSILE_YPOS >= 45 Then BASE_XPOS_TEST = INVADER_MISSILE_XPOS ' Transfer the invader's missile XPOS for testing Gosub CHECK_BASE_HIT ' Check if a base was hit If BASE_HIT = TRUE Then INVADER_MISSILE_HIT = TRUE ' Transfer the hit detector into the invader's missil e detector Return ' Return from the subroutine prematurely Endif Endif ' Check if the invader's missile has hit the ship If INVADER_MISSILE_YPOS >= 56 Then Select INVADER_MISSILE_XPOS Case SHIP_XPOS . < INVADER_MISSILE_XPOS .FIRE_INVADER_MISSILE2: If INVADER_MISSILE2_FIRED = FALSE Then ' Is it OK to fire an invader second miss ile ? 'If INVADER_MISSILE_XPOS < SHIP_XPOS Then Select SHIP_XPOS Case > INVADER_MISSILE_XPOS + RANDOM_VALUE .1 To SHIP_XPOS + SHIP_WIDTH Gosub DRAW_SHIP INVADER_MISSILE_HIT = TRUE ' Indicate the invader's missile has hit something SHIP_HIT = TRUE ' Indicate that it is the ship that has been hit End Select Endif Endif Return '---------------------------------------------------------------------------' Check if the invader's second missile has hit something ' Returns with INVADER_MISSILE2_HIT set if the invader's missile has hit somethi ng .

MISSILE_XPOS Plot MISSILE_YPOS + 1.$F0. MISSILE_XPOS + 1 Return '---------------------------------------------------------------------------' Draw the ship DRAW_SHIP: LCDWRITE 7.$00] Return '---------------------------------------------------------------------------' Check if the ship's missile has hit something ' Returns with MISSILE_HIT set if the ship's missile has hit something CHECK_FOR_MISSILE_HIT: MISSILE_HIT = FALSE ' Default to not hit SAUCER_HIT = FALSE ' Default to saucer not hit If MISSILE_FIRED = TRUE Then ' First make sure a missile is actually launched ' Check if the ship's missile has hit a BASE If MISSILE_YPOS = 53 Then . MISSILE_XPOS + 1 UnPlot MISSILE_YPOS + 1.$F0.$F8.$F8.$FC.$E0. MISSILE_XPOS + 1 Plot MISSILE_YPOS + 1. MISSILE_XPOS Plot MISSILE_YPOS.1 To SHIP_XPOS + SHIP_WIDTH Gosub DRAW_SHIP INVADER_MISSILE2_HIT = TRUE ' Indicate the invader's second missile has hit some thing SHIP_HIT = TRUE ' Indicate that it is the ship that has been hit End Select Endif Endif Return '---------------------------------------------------------------------------' Draw or clear the Ship's missile CLEAR_MISSILE: UnPlot MISSILE_YPOS. MISSILE_XPOS + 1 UnPlot MISSILE_YPOS + 2. MISSILE_XPOS UnPlot MISSILE_YPOS.$F0.$F0.CHECK_FOR_INVADER_MISSILE2_HIT: INVADER_MISSILE2_HIT = FALSE ' Default to not hit If INVADER_MISSILE2_FIRED = TRUE Then ' First make sure that a second missile is actually launched ' Check if the invader's second missile has hit a BASE If INVADER_MISSILE2_YPOS >= 45 Then BASE_XPOS_TEST = INVADER_MISSILE2_XPOS ' Transfer the invader's second missile X POS for testing Gosub CHECK_BASE_HIT ' Check if a base was hit If BASE_HIT = TRUE Then INVADER_MISSILE2_HIT = TRUE ' Transfer the hit detector into the invader's secon d missile detector Return ' Return from the subroutine prematurely Endif Endif ' Check if the invader's missile has hit the ship If INVADER_MISSILE2_YPOS >= 56 Then Select INVADER_MISSILE2_XPOS Case SHIP_XPOS . MISSILE_XPOS UnPlot MISSILE_YPOS + 2. MISSILE_XPOS UnPlot MISSILE_YPOS + 2. MISSILE_XPOS UnPlot MISSILE_YPOS + 1.$E0. MISSILE_XPOS + 1 UnPlot MISSILE_YPOS + 2. MISSILE_XPOS + 1 Return DRAW_MISSILE: Plot MISSILE_YPOS.[$00.SHIP_XPOS.

$20.$41.SAUCER_XPOS.$68.$8 6.[$7F.$08.$49.$96.$41.$0C.$00.$33.$00.$69.$02 ] Delayms 10 LCDWRITE 0.$01.INVADER_XPOS[INVADER_LOOP].$36.$08.$00.$61.$C5.$01] ' Display text HIT SAUCER_FREQ = 20 Delayms 5 SAUCER_FREQ = 10 Delayms 10 SCORE = SCORE + (100 + SAUCER_XPOS) ' Add 100 + xpos to the score for hitting th e saucer SAUCER_SOUND_ENABLE = FALSE Return EndSelect Endif Endif ' Check if the ship's missile has hit an INVADER INVADER_LOOP = 0 Repeat If INVADER_ENABLED[INVADER_LOOP] = TRUE Then ' Only check if the invader is enab led If INVADER_YPOS[INVADER_LOOP] = MISSILE_YPOS / 8 Then Select MISSILE_XPOS Case INVADER_XPOS[INVADER_LOOP] to INVADER_XPOS[INVADER_LOOP] + INVADER_WIDTH INVADER_ENABLED[INVADER_LOOP] = FALSE MISSILE_HIT = TRUE ' Indicate the ship's missile has hit a target MISSILE_SOUND_ENABLE = 1 MISSILE_FREQ = 30 Select INVADER_LOOP ' Decide on the score depending on which invader is hit Case 0 to 5 ' Top layer of invaders score 20 LCDWRITE INVADER_YPOS[INVADER_LOOP].BASE_XPOS_TEST = MISSILE_XPOS ' Transfer the ship's missile XPOS for testing Gosub CHECK_BASE_HIT ' Check if a base was hit If BASE_HIT = TRUE Then MISSILE_SOUND_ENABLE = 0 ' Disable the missile's sound MISSILE_HIT = TRUE ' Transfer the hit detector into the missile detector Return ' And return from the subroutine prematurely Endif Endif ' Check if the ship's missile has hit an invader's missile If MISSILE_XPOS = INVADER_MISSILE_XPOS Then If MISSILE_YPOS = INVADER_MISSILE_YP OS Then MISSILE_SOUND_ENABLE = 0 ' Disable the missile's sound MISSILE_HIT = TRUE ' Indicate the ship's missile has hit a target INVADER_MISSILE_HIT = TRUE ' Indicate the invader's missile has also been hit Inc SCORE ' Increment the score by one Return ' And return from the subroutine prematurely Endif ' Check if the ship's missile has hit the saucer If SAUCER_ENABLED = TRUE Then If MISSILE_YPOS < 7 Then Select MISSILE_XPOS Case SAUCER_XPOS To SAUCER_XPOS + SAUCER_WIDTH MISSILE_HIT = TRUE ' Indicate the ship's missile has hit a target SAUCER_HIT = TRUE SAUCER_SOUND_ENABLE = TRUE SAUCER_FREQ = 30 LCDWRITE 0.$7F.$51.$CC.SAUCER_XPOS.$CC.$7F.[$8C.$0 1.$08.$01 . .$00.[$42.$7F.$6B.

INVADER_XPOS[INVADER_LOOP].$46.$40.INVADER_XPOS[INVADER_LOOP].$00.$00.$49. Increase the speed of the remaining invaders Endif Endif Endif MISSILE_SOUND_ENABLE = 0 ' Disable the missile's sound Return ' And return from the subroutine prematurely Endselect Endif Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 Endif Return '---------------------------------------------------------------------------' Move the ship's missile ' The missile can only be fired if the flag MISSILE_FIRED is false.$3E.INVADER_XPOS[INVADER_LOOP].$45.$45.$00.$45. $27.$00.$45.$00.$00] ' Erase the INVADER that was hit Dec INVADERS_ENABLED ' Decrement the hits counter If INVADERS_ENABLED = 1 Then ' Increase the speed substantially if only one inva der left INVADER_SPEED = 5 Else if INVADERS_ENABLED = 2 Then INVADER_SPEED = 10 ' Increase the speed to fast if there are only two invaders l eft Else If INVADER_SPEED >= 3 Then ' Is the inveders speed greater than 3 ? If INVADERS_ENABLED <= 4 Then ' Are there 4 or less invaders left ? INVADER_SPEED = INVADER_SPEED .$45.$00.[$00. $00.$51.$3E.. $3E.[$3E.$51.$49.$42.$00.$00..$51.$3E.[$00.$7F.$00.$45.3 ' Yes.$49.$00] SCORE = SCORE + 5 EndSelect Delayms 10 MISSILE_FREQ = 20 Delayms 10 MISSILE_FREQ = 10 Delayms 20 LCDWRITE INVADER_YPOS[INVADER_LOOP]. $00.$3E.$39.$00] SCORE = SCORE + 20 Case 6 to 11 ' Middle layer of invaders score 10 LCDWRITE INVADER_YPOS[INVADER_LOOP].$00. ' otherwise there is already a missile in the air ' MOVE_MISSILE: If MISSILE_FIRED = TRUE Then ' Don't enter the routine if the ship's missile is already flying If TIME_TO_MOVE_SHIP_MISSILE = TRUE Then ' Is it time to move the ship's missile ? Gosub DRAW_MISSILE Dec MISSILE_YPOS .$00.$00] SCORE = SCORE + 10 Case 12 to 17 ' Bottom layer of invaders score 5 LCDWRITE INVADER_YPOS[INVADER_LOOP]. So increase their speed by a factor of three Else Dec INVADER_SPEED ' Otherwise.$00.

$36.0.$00.9 ' Reset the missile to the bottom of the display Endif Endif Return '---------------------------------------------------------------------------' Move the ship right SHIP_RIGHT: If SHIP_XPOS > 117 Then Return Gosub DRAW_SHIP Inc SHIP_XPOS Return '---------------------------------------------------------------------------' Move the ship left SHIP_LEFT: If SHIP_XPOS = 0 Then Return Gosub DRAW_SHIP Dec SHIP_XPOS Return '---------------------------------------------------------------------------' Move the INVADERS down a line ' And check whether they have reached the bottom of the screen ' Flag INVADERS_REACHED_BOTTOM will be set if they have MOVE_INVADERS_DOWN: INVADERS_REACHED_BOTTOM = FALSE ' Default to the invaders not at bottom of the s creen TEMP_LOOP = 18 Repeat Dec TEMP_LOOP If INVADER_ENABLED[TEMP_LOOP] = TRUE Then LCDWRITE INVADER_YPOS[TEMP_LOOP].5.5.0.$3 6.$06.$0 0.5.$00] INVADER_YPOS[TEMP_LOOP] = INVADER_YPOS[TEMP_LOOP] + 1 If INVADER_YPOS[TEMP_LOOP] = 6 Then ' Have the invaders hit the bases ? Str BASE_ENABLED = 0..$00.$00.$EA.$EA.0.$00. So disable them all Str BASE_HITS = 5.0.$00.$0C. So signal the missile is finished Gosub CLEAR_MISSILE ' Clear the missile MISSILE_YPOS = 63 .5.$0C.$00] Endif Until TEMP_LOOP = 0 Inc INVADER_MISSILE_SPEED ' Slow down the invader's missile speed as they approa ch the bottom of the screen If INVADER_SPEED >= 3 Then Dec INVADER_SPEED ' Increase the speed of the invader s Return '---------------------------------------------------------------------------' Reset the invaders positions ' Each element of the arrays hold coordinates for the invaders ' Bit-0 of INVADER_ENABLED determines whether the invader is active or not (has been hit) .[$00.$00.$00.$9C.$00.0.MISSILE_FREQ = 63 .INVADER_XPOS[TEMP_LOOP].$9C.INVADER_XPOS[TEMP_LOOP].0.$06.0 ' Yes.MISSILE_YPOS Endif If MISSILE_YPOS = 0 OR MISSILE_HIT = TRUE Then ' Has the missile reached the top of the display or hit something ? MISSILE_SOUND_ENABLE = 0 MISSILE_FIRED = FALSE ' Yes.5 ' And move their hit counters to past their th resholds Endif If INVADER_YPOS[TEMP_LOOP] >= 7 Then INVADERS_REACHED_BOTTOM = TRUE ' Set a flag if the invaders have reached the bottom LCDWRITE INVADER_YPOS[TEMP_LOOP].5.5.[$00.5.$00.0.

..5) * 16 INVADER_YPOS[INVADER_LOOP] = 2 Case 12 to 17 INVADER_XPOS[INVADER_LOOP] = (INVADER_LOOP .11) * 16 INVADER_YPOS[INVADER_LOOP] = 3 End Select Inc INVADER_LOOP Until INVADER_LOOP > 17 Return '---------------------------------------------------------------------------' Move the INVADERS MOVE_INVADERS: 'If TIME_TO_MOVE_INVADERS = TRUE Then TIME_TO_MOVE_INVADERS_DOWN = FALSE If INVADERS_DIRECTION = FORWARD Then ' Are the invaders to move forward (right) ? INVADER_LOOP = 0 ' Yes.1 ' Yes. So indicate that we need to go backwards SAUCER_ENABLED = TRUE TIME_TO_MOVE_INVADERS_DOWN = TRUE ' and signal that we need to move the invaders down Endif Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 ' Close the loop after all the invader elements have bee n scanned Else ' Otherwise we go backwards (left) INVADER_LOOP = 0 ' Reset the invader loop Repeat ' Create a loop for all the invaders If INVADER_ENABLED[INVADER_LOOP] = TRUE Then ' Is this invader enabled ? INVADER_XPOS[INVADER_LOOP] = INVADER_XPOS[INVADER_LOOP] . So increment its XPOS If INVADER_XPOS[INVADER_LOOP] >= INVADER_RIGHT_LIMIT Then ' Have we hit the righ t side of the screen ? INVADERS_DIRECTION = BACKWARD ' Yes. So indicate that we need to go forwards TIME_TO_MOVE_INVADERS_DOWN = TRUE ' and signal that we need to move the invaders down Endif Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 ' Close the loop after all the invader elements have bee . So reset the invader loop Repeat ' Create a loop for all the invaders If INVADER_ENABLED[INVADER_LOOP] = TRUE Then ' Is this invader enabled ? INVADER_XPOS[INVADER_LOOP] = INVADER_XPOS[INVADER_LOOP] + 1 ' Yes.. So decrement its XPOS If INVADER_XPOS[INVADER_LOOP] <= 1 Then ' Have we hit the left side of the scree n ? INVADERS_DIRECTION = FORWARD ' Yes..' Bit-1 of INVADER_ENABLED sets which graphic to use for the invader ' INVADER_XPOS holds the X position of the invader ' INVADER_YPOS holds the Y position of the invader RESET_INVADERS: INVADER_LOOP = 0 Repeat INVADER_ENABLED[INVADER_LOOP] = TRUE ' Set all invaders to active and image 1 Select INVADER_LOOP Case 0 to 5 INVADER_XPOS[INVADER_LOOP] = (INVADER_LOOP + 1) * 16 INVADER_YPOS[INVADER_LOOP] = 1 Case 6 to 11 INVADER_XPOS[INVADER_LOOP] = (INVADER_LOOP ..

$0E.$5E.$3A.$4B.$1F.$4C.$5E.$1F. $1B.$2F.$00 'INVADER MIDDLE ROW character 1 $00.$1E.INVADER_XPOS[INVADER_LOOP]. $4B.$3A.$2F.$18.$2C.$0B.$3E.$0B.[$00. $1A.$1A.[$00.$2E.$4C.$1E.$08.$0E.$0C.$5B.$7F.$3A.$1E.$38.$00] Case 12 to 17 LCDWRITE INVADER_YPOS[INVADER_LOOP].$3A.$00] EndSelect INVADER_SOUND_ENABLE = 1 Endif Endif Inc INVADER_LOOP Until INVADER_LOOP > 17 Return '---------------------------------------------------------------------------- .$0E. $0B.$2C.[$00.$4C.$1F.$1B.$18. $5A.$4C.INVADER_XPOS[INVADER_LOOP].$4C.$00] Case 12 to 17 LCDWRITE INVADER_YPOS[INVADER_LOOP].$48.$08.$1B.$2F.$5A.$06.$08.$5B.$3E.$00] Case 6 to 11 LCDWRITE INVADER_YPOS[INVADER_LOOP].$0C.$2E.$3E.$5E.$0C.$48.INVADER_XPOS[INVADER_LOOP].$1E.$1E.$6E.$00 'INVADER BOTTOM ROW character 1 $00.$18.$0D.$4C.$2F.$3A. $5B.[$00.$2F.$00] EndSelect INVADER_SOUND_ENABLE = 1 Else INVADER_SOUND_ENABLE = 0 INVADER_FREQ = 105 Select INVADER_LOOP ' Decide on the score depending on which invader is hit Case 0 to 5 LCDWRITE INVADER_YPOS[INVADER_LOOP].$4B.$1A.$06.$5E.$1B.$4C.INVADER_XPOS[INVADER_LOOP].$7F.$6E.$0D.$38.INVADER_XPOS[INVADER_LOOP].$4C.$1F.$00] Case 6 to 11 LCDWRITE INVADER_YPOS[INVADER_LOOP].$0D.$00 'INVADER BOTTOM ROW character 2 $00.$38.$0D.$2C.$3E.$00 'INVADER MIDDLE ROW character 2 $00.$5A.$3A.$38.$0B.$2E.$1F.$1E.$3A.$3A.$1E.$6E.$00 DRAW_INVADERS: INVADER_LOOP = 0 Repeat If INVADER_ENABLED[INVADER_LOOP] = TRUE Then If INVADER_CHARACTER = 0 Then INVADER_SOUND_ENABLE = 0 INVADER_FREQ = 90 Select INVADER_LOOP ' Decide on the score depending on which invader is hit Case 0 to 5 LCDWRITE INVADER_YPOS[INVADER_LOOP].$1F.$4B.$5B.$7F.$2F.$1A.[$00.$48.$1E.$0C.$06.$2F.n scanned Endif If TIME_TO_MOVE_INVADERS_DOWN = TRUE Then Gosub MOVE_INVADERS_DOWN ' Do we need to move the invaders down ? 'Endif ' Fall through to DRAW_THE_INVADERS '---------------------------------------------------------------------------' Draw the invaders ' Draws one of two invader shapes depending on the contents of BIT variable INVA DER_CHARACTER ' Each row of invaders is a different character 'INVADER TOP ROW character 1 $00.$00 'INVADER TOP ROW character 2 $00.$2E.$2F.$1F.$6E.$08.[$00.INVADER_XPOS[INVADER_LOOP].$7F.$06.$2C.$0E.$48.$18.$1F.$5A.

0.$0E.SAUCER_XPOS.0.$0F.LIVES ' And display the score beca use it was erased by the saucer Endif Else SAUCER_SOUND_ENABLE = 0 ' Disable the saucer's sound channel Endif Return '---------------------------------------------------------------------------' Determine whether a missile.at 0.0.$1B.' Clear the saucer located at the top of the screen CLEAR_SAUCER: Lcdwrite 0. saucer or base should move ' governed by their individual speed controls GOVERN_SPEEDS: ' Advance the saucers's tick (governs its speed) Dec SAUCER_SPEED TIME_TO_MOVE_SAUCER = FALSE If SAUCER_SPEED = 0 Then TIME_TO_MOVE_SAUCER = TRUE SAUCER_SPEED = 3 Endif ' Advance the ship's tick (governs its speed) Dec SHIP_SPEED TIME_TO_MOVE_BASE = FALSE If SHIP_SPEED = 0 Then TIME_TO_MOVE_BASE = TRUE SHIP_SPEED = 3 Endif ' Advance the invader's missile tick (governs its speed) .Dec LEVEL.$0F.0.$1B.$3A.0.$0E. So signal the sacucer is finished Gosub CLEAR_SAUCER ' Clear the saucer SAUCER_XPOS = 127 .0.$00 ] Return '---------------------------------------------------------------------------' Move the saucer if it is not already flying MOVE_SAUCER: If SAUCER_ENABLED = TRUE Then ' Don't enter the routine if the saucer is already flying SAUCER_SOUND_ENABLE = 1 ' Enable the saucer's sound channel If TIME_TO_MOVE_SAUCER = TRUE Then ' Is it time to move the saucer ? Dec SAUCER_XPOS ' Move the saucer accross the screen if SAUCER_XPOS // 2 = 0 Then SAUCER_FREQ = 10 Else SAUCER_FREQ = 12 Endif Gosub DRAW_SAUCER ' Display the saucer Endif If SAUCER_XPOS = 0 OR SAUCER_HIT = TRUE Then ' Has the saucer reached the left o f the display or been hit ? SAUCER_ENABLED = FALSE ' Yes.0.0.$1B.0. " ".0. ship.0.0.0.$1B.0] Return '---------------------------------------------------------------------------' Draw the saucer located at the top of the screen DRAW_SAUCER: Lcdwrite 0.$0 4.0.0.$3A.0.[0.Dec SCORE.[$00.SAUCER_WIDTH ' Reset the saucer to the right of the display Print at 0.$04.SAUCER_XPOS.0.20.

[LEVEL] Inc SCORE Inc INVADER_LOOP Until INVADER_LOOP > 127 Inc TEMP_LOOP Until TEMP_LOOP > 7 Return '---------------------------------------------------------------------------MAIN_PROGRAM_LOOP: Gosub DISPLAY_SPASH_SCREEN Delayms 1000 Print at 4.$5B.0. and INVADER_LOOP DISPLAY_SPASH_SCREEN: Cls SCORE = 0 TEMP_LOOP = 0 Repeat INVADER_LOOP = 0 Repeat LEVEL = CREAD INVADER_SPLASH_SCREEN + SCORE LcdWrite TEMP_LOOP.$18.INVADER_LOOP.$00] Print at 2.$1B.$4C.$0 4.$3A.0.$4C. LEVEL.7."Scoring" Lcdwrite 2.$3A.$5B.$1B."PRESS FIRE TO START" While FIRE_BUTTON = 1 : Wend While FIRE_BUTTON = 0 : Wend Delayms 50 Cls Print at 0.$1B." = 20 Points" .$2E.$2F.$1B.$0F.$2E.$00] Print at 3.$2F.$04.2.$0E.2.$0E.[$00.$18." = 100+ Points" LCDWRITE 3.$0F.1.Inc INVADER_MISSILE_TICK TIME_TO_MOVE_INV_MISSILE = FALSE If INVADER_MISSILE_TICK >= INVADER_MISSILE_SPEED Then ' Set the speed for the in vader's missile TIME_TO_MOVE_INV_MISSILE = TRUE INVADER_MISSILE_TICK = 0 Endif ' Advance the invader's second missile tick (governs its speed) Inc INVADER_MISSILE2_TICK TIME_TO_MOVE_INV_MISSILE2 = FALSE If INVADER_MISSILE2_TICK >= INVADER_MISSILE2_SPEED Then ' Set the speed for the invader's second missile TIME_TO_MOVE_INV_MISSILE2 = TRUE INVADER_MISSILE2_TICK = 0 Endif ' Advance the ship's missile tick (governs its speed) Dec SHIP_MISSILE_TICK TIME_TO_MOVE_SHIP_MISSILE = FALSE If SHIP_MISSILE_TICK = 0 Then ' Set the speed for the ship's missile TIME_TO_MOVE_SHIP_MISSILE = TRUE SHIP_MISSILE_TICK = 2 Endif Return '---------------------------------------------------------------------------' Display the spash screen ' The subroutine re-uses some of the variables ' TEMP_LOOP.[$00.

$38.$1B." = 5 Points" Print at 7.LCDWRITE 4.9 INVADER_MISSILE_XPOS = 0 INVADER_MISSILE_YPOS = 0 MISSILE_STATUS = 0 INVADER_MISSILE2_YPOS = 0 ' Y position of Invader's second MISSILE INVADER_MISSILE2_XPOS = 0 ' X position of Invader's second MISSILE .2.$5A.$3A.$38." = 10 Points" LCDWRITE 5.$00] Print at 4."PRESS FIRE TO START" While FIRE_BUTTON = 1 : Wend While FIRE_BUTTON = 0 : Wend Delayms 50 LEVEL = 0 ' Start at level 0 LIVES = "3" ' Set the initial lives counter to 3 SHIP_SPEED = 3 SCORE = 0 SHIP_XPOS = 64 SAUCER_SPEED = 7 ' Speed of the saucer INVADER_SPEED = 70 ' The initial speed of the invaders DEFAULT_INVADER_SPEED = INVADER_SPEED TEMP_LOOP = 0 Repeat BASE_ENABLED[TEMP_LOOP] = TRUE BASE_HITS[TEMP_LOOP] = 0 Inc TEMP_LOOP Until TEMP_LOOP > 8 Output PORTA ' Set all of PORTA to outputs (for sound channels) INTERRUPT_COUNTER1 = 0 NOTE_STATUS = 0 INVADER_SOUND_COUNTER = 0 MISSILE_SOUND_COUNTER = 0 SAUCER_SOUND_COUNTER = 0 INVADER_SOUND_DURATION_COUNTER = 0 GIE = 0 ' Disable interrupts OPTION_REG = %00000000 ' TMR0 prescaler 1:1.$0D.$1E.$3E.[$00.2.$6E.$2F.$2F.0.$4C.$00] Print at 5.$3A.$0D.$5A.0.$6E.SAUCER_WIDTH ' Position saucer at top tight of the screen MISSILE_XPOS = 0 MISSILE_YPOS = 63 .$3E.$1B.$1E.1.[$00. PORTB pullups ON TMR0 = 0 ' Reset TMR0 INTCON = %10100000 ' Enable TMR0 Interrupt INVADER_SOUND_ENABLE = 1 ' Enable the Invaders sound channel INVADER_SOUND_DURATION = 20 ' Set the note duration to 20 ' Main program loop starts here ' Jump to this location to implement a new sheet of invaders NEW_SHEET: Inc LEVEL Cls Gosub UPDATE_BASES ' Draw the bases (or what's left of them) SHIP_HIT = FALSE ' Default to no hit on the ship by a missile SAUCER_ENABLED = FALSE ' Disable the saucer SAUCER_XPOS = 127 .$4C.

at 0.Dec SCORE. " ".LIVES While 1 = 1 RANDOM_VALUE = RANDOM RANDOM_VALUE = RANDOM_VALUE & %00111000 Inc INVADER_TICK TIME_TO_MOVE_INVADERS = FALSE If INVADER_TICK > INVADER_SPEED Then INVADER_TICK = 0 'TIME_TO_MOVE_INVADERS = TRUE 'If TIME_TO_MOVE_INVADERS = TRUE Then Gosub MOVE_INVADERS Gosub MOVE_INVADERS INVADER_CHARACTER = ~INVADER_CHARACTER ' Use a new invader character If INVADERS_REACHED_BOTTOM = TRUE Then GAME_OVER Endif Gosub MOVE_SAUCER ' Move the flying saucer (if required) Gosub GOVERN_SPEEDS ' Check whether a piece should be moving If L_BUTTON = 0 Then Gosub SHIP_LEFT ' Move ship left if LEFT button pressed If R_BUTTON = 0 Then Gosub SHIP_RIGHT ' Move ship right if RIGHT button pressed If FIRE_BUTTON = 0 Then If MISSILE_FIRED = FALSE Then ' Has the FIRE button been pressed and the ship's missile not already flying ? SEED INVADER_SOUND_COUNTER MISSILE_FIRED = TRUE ' Yes.0.. So signal we need the ship's missile FIRED MISSILE_XPOS = SHIP_XPOS + 4 ' Place the ship's missile's xpos at the middle of the ship's shape MISSILE_SOUND_ENABLE = 1 ' Enable the missile's sound Endif .TIME_TO_MOVE_INV_MISSILE2 = FALSE ' Indicate time to move the invader's second m issile INVADER_MISSILE2_FIRED = FALSE ' TRUE if Invader's second MISSILE in the air INVADER_MISSILE2_HIT = FALSE ' Default to not hit anything TIME_TO_MOVE_BASE = FALSE Gosub CLEAR_INVADER_MISSILE Gosub CLEAR_MISSILE Gosub DRAW_SHIP ' Draw the initial ship Dec DEFAULT_INVADER_SPEED ' Speed up the invaders every new sheet INVADER_SPEED = DEFAULT_INVADER_SPEED ' Transfer the speed into the actual speed altering variable Clear INVADER_TICK Clear INVADER_MISSILE_TICK Clear INVADER_MISSILE2_TICK SHIP_MISSILE_TICK = 2 INVADERS_REACHED_BOTTOM = FALSE ' Default to the invaders not at the bottom of t he screen INVADER_CHARACTER = 0 INVADER_MISSILE_SPEED = 5 ' Default speed of the invader's missile INVADER_MISSILE2_SPEED = 4 INVADERS_DIRECTION = FORWARD ' Default to the invaders moving right INVADERS_ENABLED = 18 ' All 18 invaders are enabled Gosub RESET_INVADERS ' Reset all the invaders positions Gosub DRAW_INVADERS ' Place all the invaders on the screen Print at 0.Dec LEVEL.20.

$00.0.$00.$80." " ' Display the INVADER hits count Print at 0.$04.$F0.$30.$E0.$60.at 0.$60.Gosub MOVE_MISSILE ' Move the ship's missile if OK to do so Gosub CHECK_FOR_MISSILE_HIT ' Check if the ship's missile has hit anything If MISSILE_HIT = TRUE OR SAUCER_HIT = TRUE Then If BASE_HIT = FALSE Then 'Print at 0.SHIP_XPOS.$24.[$10.$00.$10] part of ship exploding Delayms 40 ' Leave the graphic on the screen for 40ms SAUCER_FREQ = 100 ' Increase the SAUCER channel's frequency MISSILE_FREQ = 120 ' Increase the MISSILE channel's frequency LCDWRITE 7.$20.19.$F8.$00.$00.$F0.$00.$A8.SHIP_XPOS.$28. " ".LIVES Endif Endif If INVADER_CHARACTER = 1 Then Gosub FIRE_INVADER_MISSILE ' Fire an invader missile is possible Endif Gosub MOVE_INVADER_MISSILE ' Move the invader's missile (if fired) Gosub CHECK_FOR_INVADER_MISSILE_HIT ' Check if the invader's missile has hit any thing If INVADERS_ENABLED = 0 Then ' Have all the invaders been destroyed ? INVADERS_ENABLED = 18 ' Yes.$00.$00] part of ship exploding Delayms 40 ' Leave the graphic on the screen for 40ms SAUCER_FREQ = 150 ' Increase the SAUCER channel's frequency MISSILE_FREQ = 135 ' Increase the MISSILE channel's frequency LCDWRITE 7.SHIP_XPOS..[$00.$F8.$00] part of ship exploding Delayms 100 LCDWRITE 7.Dec SCORE. So enable SAUCER sound channel MISSILE_SOUND_ENABLE = 1 ' Enable MISSILE sound channel MISSILE_FREQ = 70 ' Set MISSILE channel frequency to 70 SAUCER_FREQ = 90 ' Set SAUCER channel frequency to 90 LCDWRITE 7.$00.$F0.[$00.$00.$00] hip graphic Delayms 100 ' Leave the graphic on the screen for 100ms LIVES = LIVES .$00.20.$C0. So enable them all again If INVADER_SPEED >= 3 Then Dec INVADER_SPEED ' Increase the speed of the invader s Goto NEW_SHEET ' and start a new sheet Endif If LEVEL > 10 Then ' Add a second invader missile after level 10 If INVADER_CHARACTER = 0 then Gosub FIRE_INVADER_MISSILE2 ' Fire an invader missile is possible Endif Gosub MOVE_INVADER_MISSILE2 ' Move the invader's missile (if fired) Gosub CHECK_FOR_INVADER_MISSILE2_HIT ' Check if the invader's missile has hit an ything Endif If SHIP_HIT = TRUE Then ' Has the ship been hit ? SHIP_HIT = FALSE SAUCER_SOUND_ENABLE = 1 ' Yes.1 ' Decrement the lives counter MISSILE_SOUND_ENABLE = 0 ' Disable the MISSILE sound channel SAUCER_SOUND_ENABLE = 0 ' Disable the SAUCER sound channel ' Draw first ' Draw second ' Draw third ' Clear the s .Dec2 INVADERS_ENABLED.SHIP_XPOS.Dec LEVEL.$00.$30.[$00.$AC.$00.$24.$C0.$28.$AC.$E0.$F0.

$A0.63.$A0.SHIP_XPOS + 5.SHIP_XPOS + 5.$FC.$D8.$E0.TEMP_LOOP TEMP_LOOP = TEMP_LOOP + 2 Until TEMP_LOOP > 24 'Cls Print at 3.$28 ' Left side of base after hit 2 (Character CData $40.$B0.$B0.$F8.$FE ' Middle of base after hit 1 (Character 9) CData $F8.$B0.$FE ' Left side of base complete (Character 2) CData $C0.$F0. So Redraw the ship and carry on Print at 0.[$00.LIVES SAUCER_SOUND_ENABLE = TRUE ' Enable SAUCER sound channel MISSILE_SOUND_ENABLE = TRUE ' Enable MISSILE sound channel MISSILE_FREQ = 70 ' Set MISSILE channel frequency to 70 SAUCER_FREQ = 90 ' Set SAUCER channel frequency to 90 TEMP_LOOP = 1 Repeat MISSILE_FREQ = MISSILE_FREQ .$00.$DE.$F8 ' Left side of base after hit 1 (Character CData $C0.$EC.$F0.$70.$EC.$E4.0."PRESS FIRE TO START" While FIRE_BUTTON = 1 : Wend Delayms 50 While FIRE_BUTTON = 0 : Wend Delayms 50 Goto MAIN_PROGRAM_LOOP '-------------------------------------------------------------------' Font CDATA table for space invaders game FONT:."GAME OVER".$A0.SHIP_XPOS + 5.$80.TEMP_LOOP If TEMP_LOOP > 10 Then Circle 0.$FE.$E0.at 0.$00] ' Yes. INVERSE 0 Delayms 500 Print at 4.$FC.$20 ' Left side of base after hit 3 (Character CData $40.$9E ' Middle of base after hit 2 (Character 10) 3) 4) 5) 6) 7) .Dec SCORE.TEMP_LOOP SAUCER_FREQ = SAUCER_FREQ .1.TEMP_LOOP .$00 ' Left side of base after hit 5 (Character CData $FE.$FF 'Graphic Character 1 CData $E0.$F0.10 Endif TEMP_LOOP = TEMP_LOOP + 2 Until TEMP_LOOP > 24 SAUCER_SOUND_ENABLE = FALSE ' Disable SAUCER sound channel MISSILE_SOUND_ENABLE = FALSE ' Disable MISSILE sound channel TEMP_LOOP = 1 Repeat Circle 0.$20 ' Left side of base after hit 4 (Character CData $00.$00.63.$B0.INVERSE 1.$FF.TEMP_LOOP Delayms 10 + TEMP_LOOP Circle 1.$70.$70.$00.LIVES ' Update the Display for the amount of lives Else ' Otherwise.$DE.If LIVES > "0" Then ' Do we have any lives left ? LCDWRITE 7.$AC.$00.$FF.$FE.$F8.$F0.$00. we don't have any lives left Goto GAME_OVER ' So game over Endif Endif Delayms 6 ' Main game speed setting Wend '-------------------------------------------------------------------' Explode the ship when the game is over GAME_OVER: Print at 0.$FC.SHIP_XPOS.$F8.$00.$00.$F0. " ".$F8.$00 'Graphic Character 0 CData $FF.63.$FE.$00.$FE ' Middle of base complete (Character 8) CData $FE.$F0.CData $00.$FF.Dec LEVEL.20.$F0.6.$40.20.$FE.$A0.$80.$FF.

$80.$30.$13.$14.$70.$FF $FF.$3E.$B0.$01.$60.2E '47 .$00 $00.$45.21 '34 .$30.$41.$80.$00.22 '35 .$00.$56.$14.$00.41 '66 .+ .$00.? .$A4.$00 $36.0 .$36.$00.36 '55 .$22.$00.$10.1 .$45.$00.2D '46 .$FF $00.$00 $08.$4B.$A4.$00.$00 $7F.$00.$00.$11.3E '63 .2C '45 .$08.$01.2A '43 .$00 $00.$14.$10.$7F.$41.$06.$00.$ .$00.37 '56 .$41.3 .38 '57 .$00.$05.$3E.$00 $32.$00.8 .$08.$00.42 '67 .$F8.A .$7F.$00.$08.$49.$46.$00.$00.& .$00.$49.$00.$A0.7 .$40.$48.$FC.3A '59 .$1C.$00 $1C.$03.$08.$A0.$80.$51.< .$1C.$28 $40.$12.35 '54 .$00 $21.$80.$00.CData $B8.$3E.$00." .$09.6 .$00 $00.$A0.$49.25 '38 .$80.$B0.$49.$08.$04.40 '65 .$00.! .$80.$00.$7F.3F '64 .$22.$00 $20.$36.$22.$B0.$00 $00.23 '36 .$00..$00 $08.$2A.$70.$49.$AC.$00 $01.$00.$EC.$41.> .$00 $00.2F '48 .$0F $00.$00.9 .$00.$00.$50.$55.$50.$01.$00.$4F.$41.$01.$E0 $C0.$08.3C '61 .$00 $42.$31.43 '68 .$02.$00 $00.$00 $23.$49.$00.$00 ' Middle of base after hit 5 (Character 13) CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData $FE.$00 $14.$39.$00.$00.$00.$B8.$FC.$00 $3E.$00.$00.$4A.$00 $14.$F0.$00 $27.$20 $00.$64.$00.$00.$20 $40.$00.$00.$80 $80..$00 $7F.# .$79.* .$49.28 '41 .) ./ .$00 $00.$49.32 '51 .$00 $3C.20 '33 .3B '60 .: .= .$08.$F0.$49.39 '58 ..$61.$42.$51.$08.D .$00 $00.$00.$49.$14.$00 $02.$08.$45.$00.$08.B .$49.$80.$A0.$80.$80.27 '40 .$00.$22.$DE.$7F.3D '62 .29 '42 .$14.$41.$36.$22.$7F.$F8 $C0.$00.$03.$09.$00 $3E..$41.$2A.$41.4 .$14.5 .$00.$08.$01.@ .$36.$49.$00 $00.30 '49 .$58. .$22.44 26 27 28 29 30 31 .$00 $24.24 '37 .$F0 $00.$01.$14.$0F.$00.$00 $36.$40.$07.$00.$08.$60.$01.$49.$00.$00 $00.$00 $08.$00 $00.$00.$12.$3E.$01.$07.$00 $14.$80.33 '52 .31 '50 .$05.$14.$00 $FF.$00.$00.$00.$49.$B0.$B4 ' Middle of base after hit 3 (Character 11) CData $34.$45.$00 $18.$00 $7E.$48.$00 $06.$00.$3E.$00.$14. .$14.$22.$41.$00 $00.2 .$45.$01.C .% .34 '53 .$00.$11.$11..$00.$00.$00..$71.$34 ' Middle of base after hit 4 (Character 12) CData $00.' .$41.$00.$00.$7E.$36.$49.26 '39 .$00 $00.$00 ' ' ' ' ' ' Right Right Right Right Right Right side side side side side side of of of of of of base base base base base base complete (Character 14) after hit 1 (Character 15) after hit 2 (Character 16) after hit 3 (Character 17) after hit 4 (Character 18) after hit 5 (Character 19) 'Graphic character 20 'Graphic character 21 'Graphic character 22 'Graphic character 23 'Graphic character 24 'Graphic character 25 'User defined character 'User defined character 'User defined character 'User defined character 'User defined character 'User defined character '32 .$B0.( .$01 $01.$51.$FF $FF.$62. .$00.$41.$00.$70.$00 $00.2B '44 .$00 $00.

$04.$04.$20.67 '104 h .$1F.$00.$08.$14.$44.$44.$50.$08.$00 $7F.I .$44.T .$20.$04.$50.R .$00 $07.$00 $00.6C '109 m .$00 $3F.$40.6E '111 o ._ .$10.$00.$44.K .a .$00.4D '78 .5E '95 .$14.$7F.$01.$44.$48.$04.$20.$02.$40.$00 $44.$08.$36.$14.Q .V .$00.$00.$7F.$63.$44.$04.] .$00 $00.$20.$08.$14.$49.$3F.O .$4C.$44.54 '85 .$7F.$08.$40.$00 $00.$3C.$00.$28.$09.$40.$44.$00 $7F.69 '106 j .$10.$21.$00 $00.$36.$40.$14.^ .J .7C '125 } .$7A.5B '92 .$78.$20.$44.74 '117 u .N .$40.$00 $00.$00 $63.$28.$54.5C '93 .65 '102 f .$44.$00 $3E.$14.$00 $0C.L .$06.$08.$38.$00.$78.$00 $7F.$7F.$01.$7C.71 '114 r .$00 $3C.7D '126 ~ .$10.$51.49 '74 .6F '112 p .$00 $1F.$40.$41.$41.$00 $00.$45.$54.[ .$00 $08.$00 $00.5F '96 .$01.$49.$09.76 '119 w .$00 $08.M .4E '79 .$04.$41.$08.5D '94 .$20.$00.$40.$20.$00 $3E.52 '83 .77 '120 x .P .$7E.$78.48 '73 .73 '116 t .$40.$08.$00 $7C.H .$41.$7D.$3F.$00 $7F.$14.$00.$00 $08.$7F.$70.$52.$49.c .$04.$02.$49.$01.$40.$41.75 '118 v .$7F.$08.$00 $61.$41.$29.59 '90 .$54.64 '101 e .$00 $20.$54.45 '70 .$40.$00 $00.$48.$54.$40.$3D.$02.$54.$50.$41.$5E.$00 $38.$41.$01.50 '81 .$09.$22.$09.$54.$04.$44.5A '91 .$19.7E .$3C.$08.$40.$49.$09.$09.63 '100 d .E .$01.78 '121 y .$40.$00 $7C.$1C.$20.$00.G .$41.56 '87 .$40.$46.$40.$00 $7F.$7F.\ .X .$00 $46.$7C.$54.$38.$00 $7F.$41.66 '103 g .S .$00 $04.$00 $7F.$44.$52.$49.$00 $02.$00 $01.$00 $38.$0C.$00 $3C.U .$04.$10.$00 '69 .62 '99 .$20.$18.4A '75 .F .60 '97 .W .$40.$00 $7F.$41.$08.6D '110 n .68 '105 i .$00 $7F.72 '115 s .$7F.$00 $00.$3E.$52.$02.$44.$01.79 '122 z .CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData CData $7F.4F '80 .$04.$28.$00 $20.$00 $7F.$64.b .$78.$08.Z .61 '98 .$38.$00 $38.$41.$51.$41.$49.47 '72 .$08.$01.$30.$08.$40.$40.$08.$44.$04.$41.6A '107 k .$41.$00.$09.$14.$00 $7F.$54.$08.$43.$00 $40.$7F.$04.55 '86 .$20.6B '108 l .$09.$07.$00 $0C.4C '77 .$00 $44.70 '113 q .$3F.$02.$04.$44.$49.$02.$40.$40.58 '89 .$41.$40.$00 $04.4B '76 .$3F.$08.$00 $7C.$41.$00 $7C.46 '71 .$54.53 '84 .$44.` .7A '123 { .57 '88 .$40.$18.$00.$00 $38.$40.$00 $7F.$18.Y .$00.$31.$00.$3E.$00 $3E.$49.$00 $48.$04.7B '124 | .$00 $3F.51 '82 .$00 $1C.

$0D.$FF.$3F.$02.$00._ $28.$7C.$3C.$80.$7C.$F3.$0 1.$08.$70.$00.$61.$C3.$88.$C3.$00.$FF.$00.$C7._ $86.$02.$0 0._ $00.$00.$FF.$3 B.$F9._ $00.$00.$F0.$00.$F E.$F8.$00.$07.$00.$7C._ $00.$06.$1E.$7C.$00.$00.$00.$70.$00.$3C.$00._ $7C.$00.$E8.$3F.$00._ $18.$00.$7C.$40.$00.$E1.$1C.$F1.$01.$C3.$FF.$00.$00._ $00.$01.$00.$00.$00.$FF.$60._ $40.$E0.$08.$00.$00.$00.$E0.$00.$00.$00.$02._ $00.$03.$01.$00.$08.$00.$FE.$D0.$82.$F8.$F 8.$C3.$A6.$3E.$38._ $00.$00.$0C._ $00.$82.$E1.$0 0.$00.$00.$00._ $82.$C0.$4E.$00.$CC.$00.$3 C.$FF.$FB.$C0.$00.$03.$02.$00.$3C.$00.$01.$FC.$31.$A0.$61.$C1.$38.$07.$0 7.$00.$F8.$01.$00.$01.$3E.$01.$6E.$00.$FF.$58.$00.$C1.$0C.$00.$7D.$00.$C1.$00.$00.$F0.$FE.$C3.$00.$02.$28.$00.$83.$E8.$40.$00.$00.$3F._ $FF.$00._ $BE._ $0F.$00.$C0.$02.$40.$3F.$00.$00.$80._ $7C.$00.$E0.$00.$03.$C0.$00.$00.$30.$C0.$FF.$83.$A1.$21.$00.$70.$03.$2C.$C3.$00.$FC.$00.$7F.$00.$F8.$02.$00.$5E.$00._ $7C.$C3.$9 F._ $FF.$40.$43.$02.$02.$0 0.$02.$00.$3 8.$02._ $00._ $00.$38.$38.$01.$7C.$0C.$00.$00._ $9C.$00.$00.$0 0.$02.$1E.$00.$F C._ $00.$00.$7C.$3C.$03.$1C.$00.$00.$FF.$F8.$08.$86.$8C.$00.$02.$00.$83.$F8.$6C.$3E.$47._ $06.$00._ $00.$02.$00.$33.$30.$0 0.$01.$C0.$00.$01.$00.$0 0._ $C1.$30.$00.$1E.$E0.$00.$1F.$06.$36.$00.$00.$0 8.$00.$00.$8F.$07.$0F.$30.$7 F.$C7.$8 0.$00.$F8.$1C.$19.$3C.$38.$0 0.$00.$00.$C 0.$2 7.$00.$00._ $00.$00.$00.$00.$00.$00.$40.$07.$3F.$00.$00.$00.$00.$01.$F8.$3F.$00.$82.$20.$07.$FE.$02.$1F.$F0.$3C.$02.$7C.$8 F.$00.$0C.$80.$01.$01.$01.$E3.$30.$00.$F8.$0F.$7C.$E7.$7C.$FF.$01.$3F.$00.$00.$18.$7C.$00.$00.$F3.$5C.$FF.$06._ .$E3.$3C.$00.$C3.$82.$00.$00.$7E.$00.$7 F._ $78.$00.$00._ $00.$7C.$7C.$03.$8F.$E0.$C6.$00.$00.$3E.$06.$00.$00.$00.$00.$7E.$F F.$E0._ $00.$3E.$0 0.$00.$03.$9B.$38.$FC.$F3.$00.$00.$7C.$06.$00.$00.$00.$0E.$80.$0 2.$FF.$07.$00.$8 0.$3E.$00._ $00.$00.$02.$00.$00.$00.$E1.$FC.$00._ $3E.$E0._ $78.$01.$00._ $02.$07.$00.$0 0.$82.$3E._ $0C.$3E.$7C.$00._ $00.$00.$06.$00.$E4.$00.$CE.$73.$19.$00.$06.$F8.$7C.$00.$0F.$7C.$83.$38.$26.$0C.$08.$00.$00.$18.$FF.$FC.$0 0.$C6.$03.$38.$7C.$80.$01.$C0.$A1.$03.$00.$01.$07.$00.$C 0.$0F.$40.$3F.$0C.$00.$3C.$00.$A1.$FE.$FB.$0 0.$02.$00.$3E.$00.$7 C.$0C.$3C.$00.$00.$00.$06.$03.$0B.$00.$C8.$8F.$00.$00.'-------------------------------------------------------------------INVADER_SPLASH_SCREEN: CDATA $00.$98.$00.$38.$86.$00.$01.$00._ $70.$38.$F0.$3E.$02.$00.$00.$60.$C0.$07.$C3.$1E.$3E.$00.$80.$00._ $8F.$0C.$A7.$38.$3F.$00.$0 3.$00.$7C.$3C.$60.$00.$F0.$70.$00.$00.$3E.$00.$00.$08.$B1.$7F.$3F.$FF.$31.$00.$1E.$03.$E1._ $FF.$3E.$03.$00._ $3C.$00.$0 1.$00.$07.$00.$03.$C0.$FC._ $FF.$01.$3F.$F 0.$00.$3E.$1E.$3F.$F0.$01.$7C.$C F.$F0.$73.$00.$07.$00._ $02.$00.$0 0.$00.$06.$0E.$00.$3F.$00.$C6.$8F.$7C.$E6.$61.$00.$00.$00.$E 1.$3 0.$82.$C 0.$00.$00.$C1.$3E.$3F.$00.$00.$83.$39.$0 6.$FF.$30.$F1.$00.$00.$3E._ $FC.$FF.$00.$00.$00.$FF.$1E.$7C.$00.$0C.$0F._ $FF.$00.$0 0.$00.$0 0.$10.$0 C.$58.$00.$1F.$01.$43.$8 1.$F2.$3C.$0F.$8 0.$00.$E1.$00.$F8.$07.$76.$00.$80.$82.$83.$C6.$03.$FF.$06.$0C.$0A.$68.$00.$F8.$E1.$00.$02.$60.$FF._ $01.$02.$30._ $00.$FC.$00.$00.$C0.$03.$C1.$C8.$68.$03.$30.$00.$0 0.$00.$00.$E0.$02.$FF._ $3E.$00.$30.$3E.$3D.$F7.$00.$31.$7C.$1 F.$00.$00.$00.$E8.$00.$E3.$02.$00.$2C.$C3.$78.$38.$FE.$00.$00.$4C.$1E.$F0.$00.$00.$FC.$03.$03.$06.$06.$DF.$3E.$71.$99.$E0.$00.$80.$03.$38.$BF.$00.$01.$18.$03.$0C.$02.$03.$06.$F8.$00.$21.$00.$82._ $03._ $7C.$3E._ $00.$02.$58._ $FE._ $F8.$00.$00.$20.$7E.$00.$7 F.$0 0.$07.$63.$00.$00.$F8.$3E.$00.$00.$00.$08.$00.$40.$00.$7C.$02.$00.$03.$00.$F1.$00.$00.$30.$00.$00.$03.$00.$5E.$00.$3E.$F0.$F3.$00.$06.$73.$FF.$82.$FC.$00.$00.$3E.$00.$07.$C0.$20.$80.$01.$38.$F F.$7E.$F8.$00.$C0.$F1.$08.$00.$00.$00.$40.$01.$07.$00.$0 6.$FC.$0 0.$00.$83.$00.$07._ $1E.$E1.$00.$00.$00.$00.$00.$3E.$01.$00.$03.$FF.$5D.$00.$00.$00.$3C.$00.$A6.$7 1.$7C.$F0.$00.$00.$40.$7F.$E0.$00.$00.$00.$18.$00.$00.$0 1.$00.$00.$58.$3F.$0 F.$FF.$0E.$FE.$99.$FE.$FF.$80.$7C.$3C.$E C.$82.$3E.$3E.$00.$1E.$40._ $02.$F C.$21.$00.$FE.$C3.$06.$00.$06.$71._ $0E.$09._ $03.$0C.$02.$3E.$FC.$7F._ $00.$00.$03.$00.$00.

$00.$6F.$05.$03.$40.$40._ 0.$40.$40.$47.$46.$00 .$40.$40.$04.$00.$4 $38.$40.$40.$44.$20.$70.$70.$48.$61.$07.$48.$40.$00.$74.$40.$40.$01.$69.$40.$79.$18.$40.$7F.$41.$40.$70.$1C.$40.$00._ 1.$61.$4 $7F._ 0.$7B.$41.$1C.$09.$09.$40.$74.$47.$10.$40.$00.$66.$00.$10.$61.$40.$43.$40.$03.$47.$7E.$40.$4 $6D.$5E._ 1.$0F.$40.$07.$47.$08.$4F.$78.$4F.$0 0.$06.$7F.$06.$0 $40.$60._ 3.$70.$30.$48.$5E.$4 $01.$3E.$40.