• PicŪ Basic


  • Space Invader Game - written by Les Johnson

    Developed on a PROTON Develoment board using a Graphic LCD. This version uses the LCDWRITE and PLOT commands to produce the graphics Which allows smooth movements on a pixel by pixel basis.

    References: Supporting documentation, http://users.picbasic.org/projects/S...e_invaders.htm,

    ' 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 shorts.
    '
    ' 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 moving 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 also
    ' 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 accordingly
    ' Still a problem with the invader's missile hitting the base, sometimes destroys it with one blow
    ' Game now detects whether the invaders have reached the bottom of the screen. In 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 for bottom row
    ' Saucer scores 100 points if hit
    ' A small animation of the points scored is also included if the saucer or invaders 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 channel) 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 two characters.
    ' Created new user defined shape for saucer and ship.
    ' Saucer now scores 100+ points if hit. More points gained the closer to the right hand side of the screen.
    ' Added levels to the game. After level 10 the invaders start firing two missiles.
    '
    ' * Revision 1.9 01 October 2003
    '
    ' Invader to Ship missile collision detection is now implemented
    ' Each time the ship is hit a life is decremented.
    ' After three lives the game is over.
    ' 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 dramatically
    ' When all the ship's lives are lost, a large circular explosion occurs.
    '
    '
    '
    ' See if thare are any improvements you can make, and report them on the Forum!
    '

    Include "PROTON_G8.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.0
    Dim MISSILE_SOUND_ENABLE as NOTE_STATUS.1
    Dim SAUCER_SOUND_ENABLE as NOTE_STATUS.2
    Dim INTERNAL_INVADER_SOUND_ENABLE as NOTE_STATUS.4

    Dim INTERRUPT_COUNTER1 as Byte SYSTEM
    Dim INVADER_SOUND_COUNTER as Byte SYSTEM
    Dim INVADER_FREQ as Byte SYSTEM
    Dim INVADER_SOUND_DURATION as Byte SYSTEM
    Dim INVADER_SOUND_DURATION_COUNTER as Byte SYSTEM

    Dim MISSILE_SOUND_COUNTER as Byte SYSTEM
    Dim MISSILE_FREQ as Byte SYSTEM
    Dim SAUCER_SOUND_COUNTER as Byte SYSTEM
    Dim 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 had
    Dim INVADER_XPOS[18] as Byte' at 400 ' Array to hold the space invader's X position
    Dim INVADER_YPOS[18] as Byte' at 418 ' Array to hold the space invader's Y position
    Dim INVADER_ENABLED[18] as Byte' at 436 ' Array to hold the space invader' config. i.e. hit or active

    Dim SHIP_XPOS as Byte ' X position of BASE ship
    Dim MISSILE_YPOS as Byte ' Y position of Ship's MISSILE
    Dim MISSILE_XPOS as Byte ' X position of Ship's MISSILE
    Dim MISSILE_STATUS as Byte SYSTEM
    Dim MISSILE_FIRED as MISSILE_STATUS.0 ' TRUE if Ship's MISSILE in the air
    Dim MISSILE_HIT as MISSILE_STATUS.1 ' Set if Ship's missile has hit something
    Dim TIME_TO_MOVE_INVADERS as MISSILE_STATUS.7 ' Indicate time to move the invaders
    Dim BASE_HIT as MISSILE_STATUS.2 ' Indicates whether a BASE has been hit by a missile
    Dim TIME_TO_MOVE_SHIP_MISSILE as MISSILE_STATUS.3 ' Indicate time to move the ship'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.4 ' Indicate time to move the invader's missile
    Dim INVADER_MISSILE_FIRED as MISSILE_STATUS.5 ' TRUE if Invader's MISSILE in the air
    Dim INVADER_MISSILE_HIT as MISSILE_STATUS.6 ' Set if Invader's missile has hit something
    Dim TIME_TO_MOVE_INVADERS_DOWN as Bit ' Signal that the invaders need to move down
    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. This slows 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 second 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 something
    Dim INVADER_MISSILE2_SPEED as Byte ' The speed of the invader's second missile. This slows down as invader near the bottom of the screen


    Dim SAUCER_XPOS as Byte
    Dim SAUCER_HIT as Bit
    Dim TIME_TO_MOVE_SAUCER as Bit
    Dim SAUCER_SPEED as Byte
    Dim SAUCER_ENABLED as Bit
    Dim SCORE as Dword ' Holds the games score
    Dim LEVEL as Word ' Game level
    Dim LIVES as Byte ' Amount of lives left for the base

    ' Define some constants and alias's
    Symbol L_BUTTON = PORTB.0
    Symbol R_BUTTON = PORTB.1
    Symbol FIRE_BUTTON = PORTB.2
    Symbol SPEAKER = PORTB.3

    Symbol SHIP_WIDTH = 9 ' The width of the ship in pixels. This does not include the two blanks
    Symbol INVADER_WIDTH = 10 ' The width of the invaders. minus the two outside blanks
    Symbol INVADER_RIGHT_LIMIT = 127 - INVADER_WIDTH ' The right most limit for the invaders before they need to move down
    Symbol SAUCER_WIDTH = 14

    Symbol TRUE = 1
    Symbol FALSE = 0
    Symbol FORWARD = 1
    Symbol BACKWARD = 0

    Symbol T0IF INTCON.2 ' Timer0 Overflow Interrupt Flag
    Symbol GIE INTCON.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 MISSILE_SOUND_COUNTER,F
    Incf SAUCER_SOUND_COUNTER,F

    Incf INTERRUPT_COUNTER1,F
    Btfss INTERRUPT_COUNTER1,6 ' If INTERRUPT_COUNT.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 <= INVADER_SOUND_DURATION) && (INVADER_SOUND_ENABLE == 1))
    Subwf INVADER_SOUND_DURATION,W
    Btfss STATUS,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,C
    Jump MISSILE_SOUND_LOOP

    Clrw
    Btfsc INTERNAL_INVADER_SOUND_ENABLE
    Movlw 1 ' Set for tone generation on PORTA.0
    Xorwf PORTA,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,W
    Btfss STATUS,C
    Jump SAUCER_SOUND_LOOP

    Clrw
    Btfsc MISSILE_SOUND_ENABLE
    Movlw 2 ' Set for tone generation on 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,W
    Btfss STATUS,C
    Jump EXIT_INTERRUPT

    Clrw
    Btfsc SAUCER_SOUND_ENABLE
    Movlw 4 ' Set for tone generation on PORTA.2
    Xorwf 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, INVADER_MISSILE_XPOS + 1
    UnPlot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS
    UnPlot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS + 1
    UnPlot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS
    UnPlot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS + 1
    Return
    DRAW_INVADER_MISSILE:
    UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS
    UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS + 1
    Plot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS
    Plot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS + 1
    Plot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS
    Plot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS + 1
    Return

    '----------------------------------------------------------------------------
    ' Draw or clear the second Invader's missile
    CLEAR_INVADER_MISSILE2:
    UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS
    UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS + 1
    UnPlot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS
    UnPlot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS + 1
    UnPlot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS
    UnPlot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS + 1
    Return
    DRAW_INVADER_MISSILE2:
    UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS
    UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS + 1
    Plot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS
    Plot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS + 1
    Plot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS
    Plot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS + 1
    Return
    '----------------------------------------------------------------------------
    ' Re-Draw the bases
    UPDATE_BASES:
    Print at 6,2,2 + BASE_HITS#0,8 + BASE_HITS#1,14 + BASE_HITS#2,_
    at 6,9,2 + BASE_HITS#3,8 + BASE_HITS#4,14 + BASE_HITS#5,_
    at 6,15,2 + BASE_HITS#6,8 + BASE_HITS#7,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, ELEMENT 0
    If BASE_HITS#0 < 5 AND BASE_ENABLED#0 = TRUE Then ' Is the base element enabled, 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, ELEMENT 1
    If BASE_HITS#1 < 5 AND BASE_ENABLED#1 = TRUE Then ' Is the base element enabled, 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, 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#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 3
    If BASE_HITS#3 < 5 AND BASE_ENABLED#3 = 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
    Case 60 to 65 ' Has the missile XPOS hit BASE 2, ELEMENT 4
    If BASE_HITS#4 < 5 AND BASE_ENABLED#4 = TRUE Then ' Is the base element enabled, 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, 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#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, ELEMENT 6
    If BASE_HITS#6 < 5 AND BASE_ENABLED#6 = 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, 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#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 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#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 missile ?
    Gosub DRAW_INVADER_MISSILE
    Inc INVADER_MISSILE_YPOS
    Endif
    If INVADER_MISSILE_YPOS >= 63 OR INVADER_MISSILE_HIT = TRUE Then ' Has the invader's missile reached the bottom of the display or hit something ?
    INVADER_MISSILE_FIRED = FALSE ' Yes. So signal the invader's missile is finished
    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,
    ' 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 missile ?
    Gosub DRAW_INVADER_MISSILE2
    Inc INVADER_MISSILE2_YPOS
    Endif
    If INVADER_MISSILE2_YPOS >= 63 OR INVADER_MISSILE2_HIT = TRUE Then ' Has the invader's missile reached the bottom of the display or hit something ?
    INVADER_MISSILE2_FIRED = FALSE ' Yes. So signal the invader's missile is finished
    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...
    ' If the invader is enabled, then check if it is over the ship.
    ' If it is then enable a missile to be fired.
    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.
    ' Scan all the invaders...
    ' If the invader is enabled, then check if it is over the ship.
    ' If it is then enable a missile to be fired.
    Dim RANDOM_VALUE as Byte
    FIRE_INVADER_MISSILE2:
    If INVADER_MISSILE2_FIRED = FALSE Then ' Is it OK to fire an invader second missile ?
    'If INVADER_MISSILE_XPOS < SHIP_XPOS Then
    Select SHIP_XPOS
    Case > INVADER_MISSILE_XPOS + RANDOM_VALUE , < INVADER_MISSILE_XPOS - RANDOM_VALUE
    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 the 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 something
    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 actually 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 missile 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 - 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 something
    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 XPOS 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 second 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 - 1 To SHIP_XPOS + SHIP_WIDTH
    Gosub DRAW_SHIP
    INVADER_MISSILE2_HIT = TRUE ' Indicate the invader's second missile has hit something
    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
    UnPlot MISSILE_YPOS, MISSILE_XPOS + 1
    UnPlot MISSILE_YPOS + 1, MISSILE_XPOS
    UnPlot MISSILE_YPOS + 1, MISSILE_XPOS + 1
    UnPlot MISSILE_YPOS + 2, MISSILE_XPOS
    UnPlot MISSILE_YPOS + 2, MISSILE_XPOS + 1
    Return
    DRAW_MISSILE:
    Plot MISSILE_YPOS, MISSILE_XPOS
    Plot MISSILE_YPOS, MISSILE_XPOS + 1
    Plot MISSILE_YPOS + 1, MISSILE_XPOS
    Plot MISSILE_YPOS + 1, MISSILE_XPOS + 1
    UnPlot MISSILE_YPOS + 2, MISSILE_XPOS
    UnPlot MISSILE_YPOS + 2, MISSILE_XPOS + 1
    Return
    '----------------------------------------------------------------------------
    ' Draw the ship
    DRAW_SHIP:
    LCDWRITE 7,SHIP_XPOS,[$00,$E0,$F0,$F0,$F8,$FC,$F8,$F0,$F0,$E0,$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
    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_YPOS 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,SAUCER_XPOS,[$8C,$C5,$6B,$36,$0C,$20,$68,$CC,$96,$33,$69,$CC,$8 6,$02]
    Delayms 10
    LCDWRITE 0,SAUCER_XPOS,[$7F,$08,$08,$08,$7F,$00,$00,$41,$7F,$41,$00,$00,$0 1,$01,$7F,$01,$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 the 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 enabled
    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],INVADER_XPOS[INVADER_LOOP],[$42,$61,$51,$49,$46,$00,$3E,$51,$49,$45,$3E,$00]
    SCORE = SCORE + 20
    Case 6 to 11 ' Middle layer of invaders score 10
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$42,$7F,$40,$00,$00,$3E,$51,$49,$45,$3E,$00]
    SCORE = SCORE + 10
    Case 12 to 17 ' Bottom layer of invaders score 5
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$3E,$51,$49,$45,$3E,$00, $27,$45,$45,$45,$39,$00]
    SCORE = SCORE + 5
    EndSelect
    Delayms 10
    MISSILE_FREQ = 20
    Delayms 10
    MISSILE_FREQ = 10
    Delayms 20
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$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 invader left
    INVADER_SPEED = 5
    Else if INVADERS_ENABLED = 2 Then
    INVADER_SPEED = 10 ' Increase the speed to fast if there are only two invaders left
    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 - 3 ' Yes.. So increase their speed by a factor of three
    Else
    Dec INVADER_SPEED ' Otherwise.. 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,
    ' 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
    MISSILE_FREQ = 63 - 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. So signal the missile is finished
    Gosub CLEAR_MISSILE ' Clear the missile
    MISSILE_YPOS = 63 - 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 screen
    TEMP_LOOP = 18
    Repeat
    Dec TEMP_LOOP
    If INVADER_ENABLED[TEMP_LOOP] = TRUE Then
    LCDWRITE INVADER_YPOS[TEMP_LOOP],INVADER_XPOS[TEMP_LOOP],[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$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,0,0,0,0,0,0,0,0 ' Yes.. So disable them all
    Str BASE_HITS = 5,5,5,5,5,5,5,5,5 ' And move their hit counters to past their thresholds
    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],INVADER_XPOS[TEMP_LOOP],[$00,$06,$0C,$9C,$EA,$36,$36,$EA,$9C,$0C,$06,$00]
    Endif
    Until TEMP_LOOP = 0
    Inc INVADER_MISSILE_SPEED ' Slow down the invader's missile speed as they approach the bottom of the screen
    If INVADER_SPEED >= 3 Then Dec INVADER_SPEED ' Increase the speed of the invaders
    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)
    ' 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 - 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.. 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 increment its XPOS
    If INVADER_XPOS[INVADER_LOOP] >= INVADER_RIGHT_LIMIT Then ' Have we hit the right side of the screen ?
    INVADERS_DIRECTION = BACKWARD ' 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 been 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] - 1 ' Yes.. So decrement its XPOS
    If INVADER_XPOS[INVADER_LOOP] <= 1 Then ' Have we hit the left side of the screen ?
    INVADERS_DIRECTION = FORWARD ' 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 been 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 INVADER_CHARACTER
    ' Each row of invaders is a different character
    'INVADER TOP ROW character 1 $00,$18,$4C,$2E,$5B,$2F,$2F,$5B,$2E,$4C,$18,$00
    'INVADER TOP ROW character 2 $00,$08,$2C,$5E,$0B,$1F,$1F,$0B,$5E,$2C,$08,$00

    'INVADER MIDDLE ROW character 1 $00,$38,$0D,$3E,$5A,$1E,$1E,$5A,$3E,$0D,$38,$00
    'INVADER MIDDLE ROW character 2 $00,$06,$48,$7F,$1A,$1E,$1E,$1A,$7F,$48,$06,$00

    'INVADER BOTTOM ROW character 1 $00,$4C,$6E,$3A,$1B,$2F,$2F,$1B,$3A,$6E,$4C,$00
    'INVADER BOTTOM ROW character 2 $00,$0C,$0E,$3A,$4B,$1F,$1F,$4B,$3A,$0E,$0C,$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],INVADER_XPOS[INVADER_LOOP],[$00,$18,$4C,$2E,$5B,$2F,$2F,$5B,$2E,$4C,$18,$00]
    Case 6 to 11
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$38,$0D,$3E,$5A,$1E,$1E,$5A,$3E,$0D,$38,$00]
    Case 12 to 17
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$4C,$6E,$3A,$1B,$2F,$2F,$1B,$3A,$6E,$4C,$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],INVADER_XPOS[INVADER_LOOP],[$00,$08,$2C,$5E,$0B,$1F,$1F,$0B,$5E,$2C,$08,$00]
    Case 6 to 11
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$06,$48,$7F,$1A,$1E,$1E,$1A,$7F,$48,$06,$00]
    Case 12 to 17
    LCDWRITE INVADER_YPOS[INVADER_LOOP],INVADER_XPOS[INVADER_LOOP],[$00,$0C,$0E,$3A,$4B,$1F,$1F,$4B,$3A,$0E,$0C,$00]
    EndSelect
    INVADER_SOUND_ENABLE = 1
    Endif
    Endif
    Inc INVADER_LOOP
    Until INVADER_LOOP > 17
    Return
    '----------------------------------------------------------------------------
    ' Clear the saucer located at the top of the screen
    CLEAR_SAUCER:
    Lcdwrite 0,SAUCER_XPOS,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    Return
    '----------------------------------------------------------------------------
    ' Draw the saucer located at the top of the screen
    DRAW_SAUCER:

    Lcdwrite 0,SAUCER_XPOS,[$00,$04,$0E,$3A,$1B,$0F,$1B,$1B,$0F,$1B,$3A,$0E,$0 4,$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 of the display or been hit ?
    SAUCER_ENABLED = FALSE ' Yes. So signal the sacucer is finished
    Gosub CLEAR_SAUCER ' Clear the saucer
    SAUCER_XPOS = 127 - SAUCER_WIDTH ' Reset the saucer to the right of the display
    Print at 0,0,Dec LEVEL, " ",Dec SCORE,at 0,20,LIVES ' And display the score because it was erased by the saucer
    Endif
    Else
    SAUCER_SOUND_ENABLE = 0 ' Disable the saucer's sound channel
    Endif
    Return
    '----------------------------------------------------------------------------
    ' Determine whether a missile, ship, 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)
    Inc INVADER_MISSILE_TICK
    TIME_TO_MOVE_INV_MISSILE = FALSE
    If INVADER_MISSILE_TICK >= INVADER_MISSILE_SPEED Then ' Set the speed for the invader'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, LEVEL, 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,INVADER_LOOP,[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,1,"PRESS FIRE TO START"
    While FIRE_BUTTON = 1 : Wend
    While FIRE_BUTTON = 0 : Wend
    Delayms 50

    Cls
    Print at 0,7,"Scoring"
    Lcdwrite 2,0,[$00,$04,$0E,$3A,$1B,$0F,$1B,$1B,$0F,$1B,$3A,$0E,$0 4,$00]
    Print at 2,2," = 100+ Points"

    LCDWRITE 3,0,[$00,$18,$4C,$2E,$5B,$2F,$2F,$5B,$2E,$4C,$18,$00]
    Print at 3,2," = 20 Points"
    LCDWRITE 4,0,[$00,$38,$0D,$3E,$5A,$1E,$1E,$5A,$3E,$0D,$38,$00]
    Print at 4,2," = 10 Points"
    LCDWRITE 5,0,[$00,$4C,$6E,$3A,$1B,$2F,$2F,$1B,$3A,$6E,$4C,$00]
    Print at 5,2," = 5 Points"
    Print at 7,1,"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, 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 - SAUCER_WIDTH ' Position saucer at top tight of the screen
    MISSILE_XPOS = 0
    MISSILE_YPOS = 63 - 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
    TIME_TO_MOVE_INV_MISSILE2 = FALSE ' Indicate time to move the invader's second missile
    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 the 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,0,Dec LEVEL, " ",Dec SCORE,at 0,20,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.. 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


    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,19,Dec2 INVADERS_ENABLED," " ' Display the INVADER hits count
    Print at 0,0,Dec LEVEL, " ",Dec SCORE,at 0,20,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 anything

    If INVADERS_ENABLED = 0 Then ' Have all the invaders been destroyed ?
    INVADERS_ENABLED = 18 ' Yes.. So enable them all again
    If INVADER_SPEED >= 3 Then Dec INVADER_SPEED ' Increase the speed of the invaders
    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 anything
    Endif

    If SHIP_HIT = TRUE Then ' Has the ship been hit ?
    SHIP_HIT = FALSE

    SAUCER_SOUND_ENABLE = 1 ' Yes. 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,SHIP_XPOS,[$10,$24,$AC,$F8,$F0,$E0,$F0,$F8,$AC,$24,$10] ' Draw first 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,SHIP_XPOS,[$00,$20,$28,$F0,$A8,$C0,$E0,$F0,$28,$04,$00] ' Draw second 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,$00,$30,$60,$80,$C0,$60,$30,$00,$00,$00] ' Draw third part of ship exploding
    Delayms 100
    LCDWRITE 7,SHIP_XPOS,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00] ' Clear the ship graphic
    Delayms 100 ' Leave the graphic on the screen for 100ms
    LIVES = LIVES - 1 ' Decrement the lives counter
    MISSILE_SOUND_ENABLE = 0 ' Disable the MISSILE sound channel
    SAUCER_SOUND_ENABLE = 0 ' Disable the SAUCER sound channel
    If LIVES > "0" Then ' Do we have any lives left ?
    LCDWRITE 7,SHIP_XPOS,[$00,$E0,$F0,$F0,$F8,$FC,$F8,$F0,$F0,$E0,$00] ' Yes. So Re-draw the ship and carry on
    Print at 0,20,LIVES ' Update the Display for the amount of lives
    Else ' Otherwise, 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,0,Dec LEVEL, " ",Dec SCORE,at 0,20,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 - TEMP_LOOP
    SAUCER_FREQ = SAUCER_FREQ - TEMP_LOOP
    Delayms 10 + TEMP_LOOP
    Circle 1,SHIP_XPOS + 5,63,TEMP_LOOP
    If TEMP_LOOP > 10 Then
    Circle 0,SHIP_XPOS + 5,63,TEMP_LOOP - 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,SHIP_XPOS + 5,63,TEMP_LOOP
    TEMP_LOOP = TEMP_LOOP + 2
    Until TEMP_LOOP > 24
    'Cls
    Print at 3,6,INVERSE 1,"GAME OVER", INVERSE 0
    Delayms 500
    Print at 4,1,"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:- CData $00,$00,$00,$00,$00,$00 'Graphic Character 0
    CData $FF,$FF,$FF,$FF,$FF,$FF 'Graphic Character 1
    CData $E0,$F0,$F8,$FC,$FC,$FE ' Left side of base complete (Character 2)
    CData $C0,$B0,$B0,$70,$EC,$F8 ' Left side of base after hit 1 (Character 3)
    CData $C0,$A0,$B0,$70,$AC,$28 ' Left side of base after hit 2 (Character 4)
    CData $40,$A0,$B0,$70,$A0,$20 ' Left side of base after hit 3 (Character 5)
    CData $40,$80,$80,$40,$A0,$20 ' Left side of base after hit 4 (Character 6)
    CData $00,$00,$00,$00,$00,$00 ' Left side of base after hit 5 (Character 7)

    CData $FE,$FE,$FE,$FE,$FE,$FE ' Middle of base complete (Character 8)
    CData $FE,$DE,$EC,$F0,$F8,$FE ' Middle of base after hit 1 (Character 9)
    CData $F8,$DE,$E4,$F0,$D8,$9E ' Middle of base after hit 2 (Character 10)
    CData $B8,$DE,$A4,$B0,$48,$B4 ' Middle of base after hit 3 (Character 11)
    CData $34,$58,$A4,$B8,$48,$34 ' Middle of base after hit 4 (Character 12)
    CData $00,$00,$00,$00,$00,$00 ' Middle of base after hit 5 (Character 13)

    CData $FE,$FC,$FC,$F8,$F0,$E0 ' Right side of base complete (Character 14)
    CData $C0,$B0,$B0,$70,$EC,$F8 ' Right side of base after hit 1 (Character 15)
    CData $C0,$A0,$B0,$70,$AC,$28 ' Right side of base after hit 2 (Character 16)
    CData $40,$A0,$B0,$70,$A0,$20 ' Right side of base after hit 3 (Character 17)
    CData $40,$80,$80,$40,$A0,$20 ' Right side of base after hit 4 (Character 18)
    CData $00,$00,$00,$00,$00,$00 ' Right side of base after hit 5 (Character 19)

    CData $FF,$00,$00,$00,$00,$00 'Graphic character 20
    CData $00,$00,$00,$00,$00,$FF 'Graphic character 21
    CData $FF,$01,$01,$01,$01,$01 'Graphic character 22
    CData $01,$01,$01,$01,$01,$FF 'Graphic character 23
    CData $FF,$80,$80,$80,$80,$80 'Graphic character 24
    CData $80,$80,$80,$80,$80,$FF 'Graphic character 25
    CData $00,$00,$00,$00,$F0,$F0 'User defined character 26
    CData $00,$00,$00,$00,$0F,$0F 'User defined character 27
    CData $00,$00,$00,$00,$00,$00 'User defined character 28
    CData $00,$00,$00,$00,$00,$00 'User defined character 29
    CData $00,$00,$00,$00,$00,$00 'User defined character 30
    CData $00,$00,$00,$00,$00,$00 'User defined character 31
    CData $00,$00,$00,$00,$00,$00 '32 - - 20
    CData $00,$00,$4F,$00,$00,$00 '33 - ! - 21
    CData $00,$07,$00,$07,$00,$00 '34 - " - 22
    CData $14,$7F,$14,$7F,$14,$00 '35 - # - 23
    CData $24,$2A,$7F,$2A,$12,$00 '36 - $ - 24
    CData $23,$13,$08,$64,$62,$00 '37 - % - 25
    CData $36,$49,$55,$22,$50,$00 '38 - & - 26
    CData $00,$05,$03,$00,$00,$00 '39 - ' - 27
    CData $1C,$22,$41,$00,$00,$00 '40 - ( - 28
    CData $00,$00,$41,$22,$1C,$00 '41 - ) - 29
    CData $14,$08,$3E,$08,$14,$00 '42 - * - 2A
    CData $08,$08,$3E,$08,$08,$00 '43 - + - 2B
    CData $00,$50,$30,$00,$00,$00 '44 - , - 2C
    CData $08,$08,$08,$08,$08,$00 '45 - - - 2D
    CData $00,$60,$60,$00,$00,$00 '46 - . - 2E
    CData $20,$10,$08,$04,$02,$00 '47 - / - 2F
    CData $3E,$51,$49,$45,$3E,$00 '48 - 0 - 30
    CData $00,$42,$7F,$40,$00,$00 '49 - 1 - 31
    CData $42,$61,$51,$49,$46,$00 '50 - 2 - 32
    CData $21,$41,$45,$4B,$31,$00 '51 - 3 - 33
    CData $18,$14,$12,$7F,$10,$00 '52 - 4 - 34
    CData $27,$45,$45,$45,$39,$00 '53 - 5 - 35
    CData $3C,$4A,$49,$49,$30,$00 '54 - 6 - 36
    CData $01,$71,$09,$05,$03,$00 '55 - 7 - 37
    CData $36,$49,$49,$49,$36,$00 '56 - 8 - 38
    CData $06,$49,$49,$49,$3E,$00 '57 - 9 - 39
    CData $00,$36,$36,$00,$00,$00 '58 - : - 3A
    CData $00,$56,$36,$00,$00,$00 '59 - ; - 3B
    CData $08,$14,$22,$41,$00,$00 '60 - < - 3C
    CData $14,$14,$14,$14,$14,$00 '61 - = - 3D
    CData $00,$41,$22,$14,$08,$00 '62 - > - 3E
    CData $02,$01,$51,$09,$06,$00 '63 - ? - 3F
    CData $32,$49,$79,$41,$3E,$00 '64 - @ - 40
    CData $7E,$11,$11,$11,$7E,$00 '65 - A - 41
    CData $7F,$49,$49,$49,$36,$00 '66 - B - 42
    CData $3E,$41,$41,$41,$22,$00 '67 - C - 43
    CData $7F,$41,$41,$22,$1C,$00 '68 - D - 44
    CData $7F,$49,$49,$49,$41,$00 '69 - E - 45
    CData $7F,$09,$09,$09,$01,$00 '70 - F - 46
    CData $3E,$41,$49,$49,$7A,$00 '71 - G - 47
    CData $7F,$08,$08,$08,$7F,$00 '72 - H - 48
    CData $00,$41,$7F,$41,$00,$00 '73 - I - 49
    CData $20,$40,$41,$3F,$01,$00 '74 - J - 4A
    CData $7F,$08,$14,$22,$41,$00 '75 - K - 4B
    CData $7F,$40,$40,$40,$40,$00 '76 - L - 4C
    CData $7F,$02,$0C,$02,$7F,$00 '77 - M - 4D
    CData $7F,$04,$08,$10,$7F,$00 '78 - N - 4E
    CData $3E,$41,$41,$41,$3E,$00 '79 - O - 4F
    CData $7F,$09,$09,$09,$06,$00 '80 - P - 50
    CData $3E,$41,$51,$21,$5E,$00 '81 - Q - 51
    CData $7F,$09,$19,$29,$46,$00 '82 - R - 52
    CData $46,$49,$49,$49,$31,$00 '83 - S - 53
    CData $01,$01,$7F,$01,$01,$00 '84 - T - 54
    CData $3F,$40,$40,$40,$3F,$00 '85 - U - 55
    CData $1F,$20,$40,$20,$1F,$00 '86 - V - 56
    CData $3F,$40,$38,$40,$3F,$00 '87 - W - 57
    CData $63,$14,$08,$14,$63,$00 '88 - X - 58
    CData $07,$08,$70,$08,$07,$00 '89 - Y - 59
    CData $61,$51,$49,$45,$43,$00 '90 - Z - 5A
    CData $7F,$41,$41,$00,$00,$00 '91 - [ - 5B
    CData $02,$04,$08,$10,$20,$00 '92 - \ - 5C
    CData $00,$00,$41,$41,$7F,$00 '93 - ] - 5D
    CData $04,$02,$01,$02,$04,$00 '94 - ^ - 5E
    CData $40,$40,$40,$40,$40,$00 '95 - _ - 5F
    CData $00,$01,$02,$04,$00,$00 '96 - ` - 60
    CData $20,$54,$54,$54,$78,$00 '97 - a - 61
    CData $7F,$48,$44,$44,$38,$00 '98 - b - 62
    CData $38,$44,$44,$44,$20,$00 '99 - c - 63
    CData $38,$44,$44,$48,$7F,$00 '100 d - 64
    CData $38,$54,$54,$54,$18,$00 '101 e - 65
    CData $08,$7E,$09,$01,$02,$00 '102 f - 66
    CData $0C,$52,$52,$52,$3E,$00 '103 g - 67
    CData $7F,$08,$04,$04,$78,$00 '104 h - 68
    CData $00,$44,$7D,$40,$00,$00 '105 i - 69
    CData $00,$20,$40,$44,$3D,$00 '106 j - 6A
    CData $7F,$10,$28,$44,$00,$00 '107 k - 6B
    CData $00,$41,$7F,$40,$00,$00 '108 l - 6C
    CData $7C,$04,$18,$04,$78,$00 '109 m - 6D
    CData $7C,$08,$04,$04,$78,$00 '110 n - 6E
    CData $38,$44,$44,$44,$38,$00 '111 o - 6F
    CData $7C,$14,$14,$14,$08,$00 '112 p - 70
    CData $08,$14,$14,$18,$7C,$00 '113 q - 71
    CData $7C,$08,$04,$04,$08,$00 '114 r - 72
    CData $48,$54,$54,$54,$20,$00 '115 s - 73
    CData $04,$3F,$44,$40,$20,$00 '116 t - 74
    CData $3C,$40,$40,$20,$7C,$00 '117 u - 75
    CData $1C,$20,$40,$20,$1C,$00 '118 v - 76
    CData $3C,$40,$30,$40,$3C,$00 '119 w - 77
    CData $44,$28,$10,$28,$44,$00 '120 x - 78
    CData $0C,$50,$50,$50,$3C,$00 '121 y - 79
    CData $44,$64,$54,$4C,$44,$00 '122 z - 7A
    CData $08,$36,$41,$00,$00,$00 '123 { - 7B
    CData $00,$00,$7F,$00,$00,$00 '124 | - 7C
    CData $00,$00,$41,$36,$08,$00 '125 } - 7D
    CData $00,$08,$04,$08,$04,$00 '126 ~ - 7E


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

    RGV250-614

    Pulse counter memory problem

    Thread Starter: amod

    Please tell me my faults.My pulse counter memory does not store.When i switch on device after 5 second ,memory exist by after 30 seconds it is washed...

    RGV250 Today, 14:34 Go to last post