/*
 * This work was originally done by Fred Taft (fred@hp-pcd.cv.hp.com).
 * Please forward any comments, corrections or additions back to Fred.
 *
 * Mine Storm
 */


      .org 0xE000;

MS_header:
       .word #MS_music;  /* Mine Storm music block pointer */
       .byte 0xF8;    /* height = -8 */
       .byte 0x50;    /* width = 80 */
       .byte 0x30;    /* rel y = 48 */
       .byte 0xE8;    /* rel x = -24 */
       .byte "MINE",0x80;
       .byte 0xF8;    /* height = -8 */
       .byte 0x50;    /* width = 80 */
       .byte 0x00;    /* rel y = 0 */
       .byte 0xDE;    /* rel x = -34 */
       .byte "STORM",0x80,0x00;

/* Start of the Mine Storm game */
MS_start:
       ldx   #0xC883;        /* Clear C883 - CBC5 */          
PE019: clr   ,x+;                                            
       cmpx  #0xCBC5;                                        
       bne   PE019;                                          

       jsr   $init_motion_dots;                              
       inc   $C824;                                          
       lda   #0xBB;                                          
       sta   $C880;          /* Store console enable flags in C880 */
       ldx   #0x0101;                                        
       stx   $C881;          /* Store jstick mak in C881 */  

restart_game:
       ldx   #0xC883;        /* Clear C883 - CB70 */         
PE034: clr   ,x+;                                            
       cmpx  #0xCB70;                                        
       bne   PE034;                                          
       bra   PE03D;                                          

PE03D: jsr   $dptoC8;                                        
       ldd   #0x0200;        /* Ask for number of players */ 
       jsr   $get_players_game;                              
       dec   0x79;           /* C879 contains # of players selected */
       clr   0x56;                                           
       clr   0x9B;           /* C89B specifies which player is active */

       ldx   #0xC8A8;                                        
       jsr   $set_dft_score; /* Initialize player 1 score */ 
       ldx   #0xC8AF;                                        
       jsr   $set_dft_score; /* Initialize player 2 score */ 
       ldx   #0xC8F9;                                        
       jsr   $set_dft_score; /* Initialize mine field # for player 1 */ 
       ldd   #0x0001;                                        
       jsr   $add_d_to_x_in_bcd;                             
       ldx   #0xC900;                                        
       jsr   $set_dft_score; /* Initialize mine field # for player 2 */
       ldd   #0x0001;                                        
       jsr   $add_d_to_x_in_bcd;                             

       ldx   #mines_at_level_x; /* Initialize player 1 & 2's pointers */
       stx   0xC4;              /* into the structure describing which */
       stx   0xC6;              /* mines are at which level. */ 

       lda   #0x05;                                          
       sta   0xD9;       /* Initialize # of ships for active player */
       sta   0xDA;       /* Initialize # of ships for player 1 */
       sta   0xDB;       /* Initialize # of ships for player 2 */
       bra   restart_same_level;                             


start_next_mine_level:
       jsr   $bring_ship_to_center;                          
       ldy   #0xC8C4;    /* Increment the pointer into the struct */
       lda   0x9B;       /* describing which mines are at which */
       ldx   a,y;        /* level, for the active player. */  
       leax  4,x;                                            
       stx   a,y;                                            

       ldx   #mine_field_level_pointers;                     
       lda   0x9B;           /* Check the mine field level for */
       ldx   a,x;            /* the active player, and if it is */
       lda   5,x;            /* a multiple of 4, then award that */
       anda  #0x03;          /* player a bonus ship.           */
       bne   goto_next_mine_level;                           
       inc   0xD9;                                           

goto_next_mine_level:
       ldd   #0x0001;              /* Increment active players mine */
       jsr   $add_d_to_x_in_bcd;   /* field level indicator. */
restart_same_level:
       jsr   $init_RAM_for_new_level;                        
       ldx   #0xC8C4;        /* Use the pointer in C8C4 (player 1) */
       lda   0x9B;           /* or C8C6 (player 2) to determine */
       ldx   a,x;            /* which mines are at this level. */
       lda   ,x;                                             
       bmi   check_4_end_of_game; /* After level 13, skip any level whose */
       jsr   $seed_the_screen;    /* first byte is negative.              */
       bra   main_loop;                                      

check_4_end_of_game:
       ldd   0xF0;           /* If C8F0 counts down to 0, then */
       subd  #0x0001;        /* start a new game; used as a delay */
       std   0xF0;           /* after a game is over.          */
       beq   start_a_new_game;                               

       /* Display 'game over' string, & both scores */
       pshs  dp;                                             
       jsr   $dptoD0;                                        
       jsr   $display_both_scores;                           
       ldu   #game_over;                                     
       jsr   $MS_print_1_string7F;                           
       puls  dp;                                             

       lda   0x0F;          /* If no buttons pressed, then see if */
       beq   main_loop;     /* we should goto advanced levels. */

       /*
        * Find out if a new hi score is available,
	* and then start up a new game.
	*/
start_a_new_game:
       ldx   #0xC8A8;        /* See if player 1 has new hi score */
       ldu   #0xCBEB;                                        
       jsr   $check_4_new_hi_score;                          
       ldx   #0xC8AF;        /* See if player 2 has new hi score */
       ldu   #0xCBEB;                                        
       jsr   $check_4_new_hi_score;                          
       ldd   0xF0;                                           
       lbne  restart_game;   /* Just start a new game */     
       jsr   $reinit;                                        
       clr   0x3B;           /* Flag that a hi score should be displayed */
       lds   #0xCBEA;                                        
       jmp   $powerup_loop;  /* Go thru a complete reset sequence */

/*
 * This is the main loop during a players turn.  Control will
 * remain in this loop, until either a player clears a level,
 * or has his ship destroyed.
 */
main_loop:
       pshs  dp;                                             
       jsr   $process_indirect_jumps;                        
       jsr   $draw_non_dead_mines;                           
       jsr   $process_jstick_and_buttons;                     
       jsr   $process_bullets;                                
       jsr   $reseed_screen;                                 
       puls  dp;                                             
       jsr   $check_bullets_for_hits;                        
       jsr   $check_ship_4_mine_collision;                   
       jsr   $check_ship_4_enemy_collision;                  
       jsr   $display_explosion_pattern;                     
       blo   main_loop;                                      
       lda   0xBD;           /* See if cmd ship is disabled */
       lbeq  start_next_mine_level;                          
       lda   0xBE;           /* See if the game is over */   
       lbne  check_4_end_of_game;                            
       jmp   $restart_same_level;                            


/*
 * This block of code is responsible for seeding the screen
 * at the beginning of play.  It will draw the enemy ship
 * as it moves from the top of the screen to the bottom.
 * After the field has been completely seeded, the mine
 * field number will be displayed.
 * I think that the x register, at entry, points to a
 * structure describing the types of mines for this level.
 */
seed_the_screen:
       stx   0xC2;           /* Save pointer to mine info */ 
       ldd   #0x7F00;                                        
       std   0xDC;           /* C8DC contains enemy ship coords */
       sta   0xB7;           /* C8B7 is used as loop cntr (0x7F) */
       lda   #0x20;                      
       sta   0x9C;                   /* Set up 1 of the indirect */
       ldx   #generate_mine_coords;  /* jump ptrs, to generate some */
       stx   0x9D;                   /* mine coordinates.        */
       ldx   #0xC933;        /* Load mine buf addr into C8B9-C8BA */
       stx   0xB9;                                           
       lda   #0x1D;          /* Load # of mines into C8B8 */ 
       sta   0xB8;                                           
       clr   0x56;                                           
       ldu   #MS_music;                                      
       jsr   $init_sound2;                                   
continue_seeding_screen:
       pshs  dp;                                             
       jsr   $PE711;         /* Draw active players ship count */
       jsr   $init_sound;                                    
       lda   0x26;           /* Decrement our loop counter, C8B7 */
       bita  #0x01;          /* every other pass.                */
       bne   PE15C;                                          
       dec   0xB7;                                           
PE15C: jsr   $process_indirect_jumps;                        

       /* This block draws the enemy ship */
       jsr   $display_both_scores;                           
       jsr   $do_sound;                                      
       jsr   $draw_non_dead_mines;                           
       jsr   $intensity_to_5F;                               
       ldb   $C8B7;             /* Wait until screen is seeded, */
       beq   activate_4_mines;  /* then activate 1st 4 mines.   */
       ldx   #enemy_ship_pt1;                                
       ldy   $C8DC;                                          
       jsr   $move_y_draw_x;    /* Draw the enemy ship */    
       ldx   #enemy_ship_pt2;                                
       jsr   $move_y_draw_x;                                 
       ldx   #enemy_ship_pt3;                                
       jsr   $move_y_draw_x;                                 
       puls  dp;                                             
       dec   0xDC;              /* Decrement y coord for enemy ship */
       bra   continue_seeding_screen;                        

/*
 * This routine is called at the beginning of a turn for the
 * active player.  It will activate the first 4 mines for
 * the level.  The type of mines activated are controlled
 * by the array whose pointer is contained in C8C2.
 */
activate_4_mines:
       puls  dp;                                             
       clr   0x9C;                                           
       lda   #0x04;          /* Use C8B7 as a loop counter */
       sta   0xB7;           /* Use C8B8 as a delay counter; when it */
       lda   #0x7F;          /* = 0, stop displaying the mine field */
       sta   0xB8;           /* level, and activate 1st 4 mine. */
PE198: lda   0xB7;                                           
       beq   PE1E6;          /* Exit when loop counter = 0 */
       ldb   0xB8;                                           
       beq   PE1A4;       /* Don't activate the mines until the */
       dec   0xB8;        /* counter in C8B8 = 0; this allows the */
       bra   PE1B6;       /* mine field level to stay displayed awhile */
PE1A4: ldb   0x26;                                           
       andb  #0x1F;          /* After every 31 times thru waitrecal(), */
       bne   PE1B6;          /* activate another mine. */
       deca;                                                 
       sta   0xB7;           /* Decrement loop counter */    
       ldx   0xC2;                                           
       lda   a,x;            /* Determine what type mine this should be */
       ldb   #0x03;          /* Set generation number to 'largest'. */
       jsr   $activate_a_mine;                               
PE1B6: pshs  dp;                                             
       jsr   $process_indirect_jumps;                        

       /* Tell user what mine field number this is */
       jsr   $intensity_to_7F;                               
       ldu   #mine_field;                                    
       jsr   $MS_print_1_string7F;                           
       ldy   #0xE0F8;                                        
       ldu   #mine_field_level_pointers;                     
       lda   $C89B;                                          
       ldu   a,u;                                            
       jsr   $move_y_print_string;                           

       jsr   $draw_non_dead_mines;                           
       jsr   $process_jstick_and_buttons;                    
       jsr   $process_bullets;                                
       puls  dp;                                             
       jsr   $check_bullets_for_hits;                        
       jsr   $display_explosion_pattern;                     
       bra   PE198;                                          
PE1E6: rts;                                                  


/* 
 * This block of code generates random coordinates
 * for a single mine.  C8B9 contains a pointer to
 * the appropriate entry in the mine structure.
 * Before exiting, this routine will update the
 * pointer in C8B9 to point to the next entry.
 */
generate_mine_coords:
       dec   0xB8;           /* Decrement the mine counter (C8B8) */
       beq   PE239;          /* and exit when it equals 0. */ 
       inc   0xED;           /* Inc mine dot counter */      
       jsr   $get_random_a;                                  
       anda  #0x07;          /* Reset the ind jump counter, to */
       adda  #0x04;          /* generate the next set of mine  */
       sta   0x9C;           /* coordinates.                   */
       ldu   0xB9;           /* Load u register w/ mine structure ptr */
       lda   #0x80;          /* Flag that a mine is in this slot */
       sta   ,u;             /* Get the coordinates of enemy ship */
       ldd   0xDC;                                           
       adda  #0x08;                                          
       sta   4,u;            /* Save y coordinate in 4th slot */
       clr   5,u;                                            
       stb   6,u;            /* Save x coordinate in 6th slot */
       clr   7,u;                                            
generate_final_x_for_mine:
       jsr   $get_random_a;  /* Generate the final x position for */
       tsta;                 /* this mine.                        */
       bmi   PE21A;                                          
       cmpa  #0x10;                                          
       bge   PE214;                                          
       adda  #0x0C;                                          
PE214: cmpa  #0x60;                      
       ble   PE226;                                          
       bra   generate_final_x_for_mine;                      
PE21A: cmpa  #0xF0;                                          
       ble   PE220;                                          
       suba  #0x0C;                                          
PE220: cmpa  #0xA0;                                          
       bge   PE226;                                          
       bra   generate_final_x_for_mine;                      

PE226: sta   0x11,u;                                           
       tfr   a,b;            /* Determine what the delta movement    */
       sex;                  /* value will be for this mine: -1 or 1 */
       ora   #0x01;                                          
       sta   0x10,u;                                           
       clr   2,u;            /* Start with a scale factor of 0 */
       leay  0x12,u;         /* Update C8B9 to point to next entry */
       sty   0xB9;                                           
PE239: rts;                                                  

final_mine_scale_factor:
       .byte 0x00; 
       .byte 0x02;           /* Small */
       .byte 0x07;           /* Medium */
       .byte 0x10;           /* Large */

mine_velocity:
       .byte 0x00; 
       .byte 0x20;           /* Small */
       .byte 0x18;           /* Medium */
       .byte 0x10;           /* Large */

mine_values:
       .byte 0x01;           /* dumb mine = BCD 100 */
       .byte 0x00; 
       .byte 0x05;           /* magnetic mine = BCD 500 */
       .byte 0x00; 
       .byte 0x03;           /* fireball mine = BCD 325 */
       .byte 0x25; 
       .byte 0x07;           /* magnetic fireball mine = BCD 750 */
       .byte 0x50; 

extra_mine_value:
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x01;           /* Small (100) */
       .byte 0x00; 
       .byte 0x00;           /* Medium (35) */
       .byte 0x35; 
       .byte 0x00;           /* Large (0) */
       .byte 0x00; 

mine_sizes:
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x04;           /* Small */
       .byte 0x04; 
       .byte 0x08;           /* Medium */
       .byte 0x08; 
       .byte 0x0D;           /* Large */
       .byte 0x0D; 

/* Table of pointers to mine vectors */
mine_vector_ptrs:
       .word #dumb_mine;    
       .word #magnetic_mine;
       .word #fireball_mine; 
       .word #magnetic_fireball_mine;


/*
 * This block of code processe the hyperspace and move
 * buttons.  It also checks the state of the joystick,
 * and updates the command ship rotation value, kept
 * in C8D4, if the joystick is not centered.  If the
 * joystick is left, then the rotation value is 
 * incremented; if it is to the right, then the rotation
 * value is decremented.  After updating the rotation
 * value, the command ship will be redrawn at its
 * current position (specified in C8C8-C8C9).
 */
process_jstick_and_buttons:
       pshs  dp;                                             
       lda   #0xC8;                                          
       tfr   a,dp;                                           
       lda   0xBD;           /* Skip if cmd ship disabled */ 
       lbne  PE30A;                                          
       lda   0xEE;           /* Continue hyperspace, if active */
       lbne  continue_hyperspace;                            
       lda   0x13;           /* Check the hyperspace button (2) */
       lbne  hyperspace;                                     
       lda   0x14;           /* Check the move button (3) */ 
       beq   no_ship_movement;                               

       /*
        * The following block of code takes care of
	* generating the new command coordinates,
	* because it is moving.  It attempts to make
	* all turns into smooth motion.
	*/
       lda   0xD4;                                           
       cmpa  0xD6;                                           
       beq   PE2A0;                                          
       cmpa  0xD8;                                           
       beq   PE290;                                          
       lda   0xD5;                                           
       beq   PE2A0;                                          
       lda   0xD7;                                           
       bne   no_ship_movement;                               
PE290: lda   0xD7;                                           
       adda  #0x0C;                                          
       cmpa  #0x7F;                                          
       bhi   no_ship_movement;                               
       sta   0xD7;                                           
       lda   0xD4;                                           
       sta   0xD8;                                           
       bra   PE2AE;                                          
PE2A0: lda   0xD5;                                           
       adda  #0x0C;                                          
       cmpa  #0x7F;                                          
       bhi   no_ship_movement;                               
       sta   0xD5;                                           
       lda   0xD4;                                           
       sta   0xD6;                                           
PE2AE: inc   0xF2;           /* Flag that a sound should be made */

no_ship_movement:
       lda   0xD5;                                           
       beq   PE2C2;                                          
       suba  #0x02;                                          
       sta   0xD5;                                           
       ldb   0xD6;                                           
       jsr   $calc_rise_run1;                                
       sty   0xCC;                                           
       stx   0xCE;                                           
PE2C2: lda   0xD7;                                           
       beq   PE2D4;                                          
       suba  #0x02;                                          
       sta   0xD7;                                           
       ldb   0xD8;                                           
       jsr   $calc_rise_run1; /* Generate new rise & run */   
       sty   0xD0;                                           
       stx   0xD2;                                           
PE2D4: ldd   0xC8;           /* Update cmd ships y coord */  
       addd  0xCC;                                           
       addd  0xD0;                                           
       std   0xC8;                                           
       ldd   0xCA;           /* Update cmd ships x coord */  
       addd  0xCE;                                           
       addd  0xD2;                                           
       std   0xCA;                                           

       /* Check joystick state (in C81B) */
       lda   0x1B;                                           
       beq   draw_cmd_ship1; /* Joystick is centered */      
       bmi   PE2EE;                                          
       dec   0xD4;           /* Joystick to right */         
       bra   draw_cmd_ship2;                                 
PE2EE: inc   0xD4;           /* Joystick to left */         
       bra   draw_cmd_ship2;                                 
PE2F2: pshs  dp;                                             

/*
 * draw_cmd_ship2() runs the command ships coordinates
 * thru a rotation transformation, and then draws the
 * command ship using the transforms coordinates.
 * draw_cmd_ship1() draws the command ship using the
 * current transformed ship coordinates.
 */
draw_cmd_ship2:
       jsr   $rotate_cmd_ship; /* Rotate the command ship */   
draw_cmd_ship1:
       lda   #0xD0;                                          
       tfr   a,dp;                                           
       jsr   $intensity_to_5F;                               
       ldb   #0x0C;                                          
       ldy   #0xC8C8;        /* Draw the xformed command ship */
       ldx   #0xCB89;                                        
       jsr   $move_y_draw_x2;                                
PE30A: puls  dp,pc;                                          


/* This routine handles the hyperspace request */
hyperspace:
       lda   #0x80;                                          
       sta   0xEE;                                           
       jsr   $get_random_a;                                  
       anda  #0x03;                                          
       adda  #0x03;                                          
       sta   0xEF;                                           
       inc   0xF6;                                           
continue_hyperspace:
       lda   0xEE;                                           
       bpl   process_hyperspace_dots;                        
       dec   0xEF;                                           
       beq   PE330;                                          
       jsr   $MS_get_2_random_nums;                          
       sta   0xC8;                                           
       clr   0xC9;           /* Generate new coordinates */  
       stb   0xCA;           /* for the command ship.    */  
       clr   0xCB;                                           
       puls  dp,pc;                                          
PE330: lsr   0xEE;                                           
       lda   #0x1F;                                          
       sta   0xEF;                                           
       puls  dp,pc;                                          


/*
 * This code draws the ever decreasing hyperspace dots
 * during an active hyperspace.  The scale factor for
 * the hyperspace dots, stored in C8EF, is decremented,
 * and when it finally reaches a minimum value, the
 * hyperspace is complete.
 */
process_hyperspace_dots:
       ldb   0xEF;           /* See if scale factor has reached */
       cmpb  #0xE0;          /* the limit.                      */
       ble   hyperspace_complete;                            
       lda   0xEF;                                           
       suba  #0x04;          /* Decrement the scale factor      */
       sta   0xEF;                                           
       clra;                                                 
       jsr   $draw_hyperspace_motion_dots;                   
       puls  dp,pc;                                          

hyperspace_complete:
       clr   0xEF;                                           
       clr   0xEE;                                           
       jsr   $clear_cmd_ship_xformation;                     
       puls  dp,pc;                                          


/*
 * After the player has cleared all but the small mines
 * from a layer, the enemy ship will again appear, and
 * attempt to reseed the screen.  This code checks to
 * see if the enemy ship is visible (C8E7), and if it
 * is, then it generates new coordinates for it, and
 * then moves it.
 */
reseed_screen:
       lda   $C8E7;                                          
       beq   PE383;          /* Do only if ship is visible */
       pshs  dp;                                             
       lda   #0xC8;                                          
       tfr   a,dp;                                           
       lda   0xE7;                                           
       beq   PE383;                                          
       ldd   0xDE;                                           
       addd  0xE2;                                           
       std   0xDE;                                           
       sta   0xDC;           /* New y coordinate */          
       ldd   0xE0;                                           
       addd  0xE4;                                           
       std   0xE0;                                           
       sta   0xDD;           /* New x coordinate */          
       puls  dp;                                             
       jsr   $intensity_to_5F;                               
       ldb   #0x08;                                          
       ldy   $C8DC;                                          
       ldx   #simple_enemy_ship;                             
       jsr   $move_y_draw_x;  /* Draw the enemy ship */       
PE383: rts;                                                  


/*
 * This procedure is invoked only through the indirect jump
 * pointers.  After only small mines are left, this routine
 * will eventually be called.  It will determine which way
 * the enemy ship will move, and will also set up another
 * indirect jump to the routine which does the actual
 * reseeding of the screen.
 */
ind_init_screen_reseeding:
       ldx   #ind_reseed_screen;                             
       stx   0xA3;           /* Set up next indirect jump ptr */
       jsr   $get_random_a;                                  
       ldx   #0xE448;        /* Determine where enemy ship will move */
       anda  #0x06;                                          
       ldx   a,x;                                            
       ldd   ,x++;                                           
       std   0xDC;           /* Save enemy ships new coordinates */
       sta   0xDE;                                           
       clr   0xDF;                                           
       stb   0xE0;                                           
       clr   0xE1;                                           
       bra   PE3F9;                                          


/*
 * This routine is invoked only through the indirect jump
 * mechanism.  It will continue to be called, until either
 * the enemy ship is destroyed, or until the screen has
 * been reseeded.  It will reseed upto 7 new mines.
 */
ind_reseed_screen:
       lda   0xBF;           /* See if all mines have been seeded */
       bne   PE3BE;                                          
PE3A5: jsr   $get_random_a;                                  
       anda  #0x7F;                                          
       adda  #0x30;          /* Set up the indirect jump counter 4 */
       sta   0xA2;           /* the next pass.                     */
       jsr   $get_random_a;                                  
       anda  #0x3F;                      
       sta   0xE6;                                           
       jsr   $get_random_a;                                  
       adda  #0x10;                                          
       sta   0xE7;                                           
       bra   PE407;                                          
PE3BE: lda   0xBD;                                           
       bne   PE3A5;                                          

       /* 
	* Load the b register with the number of mines (28),
	* and load the u register with the pointer to the
	* mine structure.  Then look through the mine structure
	* for an available slot, and fill it with the newly
	* seeded mine.
	*/
       ldb   #0x1C;                                          
       ldu   #0xC933;                                        
PE3C7: lda   ,u;             /* Look for an unused mine */   
       beq   found_avail_mine;                               
       leau  0x12,u;                                           
       decb;                                                 
       bne   PE3C7;                                          
       bra   PE407;                                          

found_avail_mine:
       inc   0xED;           /* Incr the # of mines which R dots */
       dec   0xBF;           /* Decrement the reseed counter */
       ldx   0xDE;                                           
       stx   4,u;            /* Set y coordinate for mine */ 
       ldx   0xE0;                                           
       stx   6,u;            /* Set x coordinate for mine */ 
       lda   #0x40;  
       sta   ,u;             /* Flag that mine is a stationary dot. */
       lda   0xC0;           /* See if this is 1st mine activated. */
       bne   PE3F7;                                          
       ldx   #ind_start_large_mine;                          
       stx   0x9D;                  /* Set things up to eventually */
       jsr   $get_random_a;         /* activate 1 large mine.      */
       anda  #0x7F;                                          
       adda  #0x40;  
       sta   0x9C;                                           
       inc   0xC0;           /* Flag that 1st mine has been activated */
PE3F7: ldx   0xE8;                                           
PE3F9: lda   ,x+;                                            
       sta   0xA2;                                           
       lda   ,x+;                                            
       sta   0xE6;                                           
       lda   ,x+;                                            
       sta   0xE7;                                           
       stx   0xE8;                                           
PE407: ldb   0xE6;                                           
       jsr   $calc_rise_run1; /* Generate rise & run for mine */
       sty   0xE2;                                           
       stx   0xE4;                                           
       rts;                                                  

/*
 * This routine is called only thru the indirect jump
 * handler.  It is responsible for activating a single
 * large mine.  The type of mine is indicated by the
 * first entry in the table of mines for this level.
 */
ind_start_large_mine:
       ldu   #0xC8C4;                                        
       lda   0x9B;                                           
       ldu   a,u;                                            
       lda   ,u;             /* Determine the type of mine */
       ldb   #0x03;          /* Set generation to 'largest' */
       jsr   $activate_a_mine;                               
       ldx   #ind_activate_rangen_mine;                      
       stx   0x9D;                                           
       rts;                                                  

/*
 * This routine decrements the counter in C8C1, and if
 * it equal 0, then it activates a mine with a random
 * generation number; else, it sets the indirect counter
 * in C89C to -1, and returns.  This routine is called
 * only thru the indirect jump handler.
 */
ind_activate_rangen_mine:
       dec   0xC1;                                           
       beq   PE430;                                          
       lda   #0xFF;                                          
       sta   0x9C;                                           
       bra   PE447;                                          
PE430: jsr   $get_random_a;                                  
       tfr   a,b;                                            
       andb  #0x03;                                          
       bne   PE43B;                                          
       addb  #0x01;                                          
PE43B: ldu   #0xC8C4;                                        
       lda   0x9B;                                           
       ldu   a,u;                                            
       lda   ,u;                                             
       jsr   $activate_a_mine;                               
PE447: rts;                                                  


/* Some sort of pointer table */
SE448: .word #SE450;           
       .word #SE46A;           
       .word #SE484;           
       .word #SE49E;           

SE450: .byte 0x7F;
       .byte 0x00;
       .byte 0x28;
       .byte 0x20;
       .byte 0x30;
       .byte 0x40;
       .byte 0x28;
       .byte 0x30;
       .byte 0x28;
       .byte 0x00;
       .byte 0x10;
       .byte 0x30;
       .byte 0x10;
       .byte 0x40;
       .byte 0x18;
       .byte 0x20;
       .byte 0x50;
       .byte 0x40;
       .byte 0x30;
       .byte 0x28;
       .byte 0x30;
       .byte 0x08;
       .byte 0x60;
       .byte 0x7F;
       .byte 0x38;
       .byte 0x70;

SE46A: .byte 0x80;
       .byte 0x00;
       .byte 0x40;
       .byte 0x00;
       .byte 0x30;
       .byte 0x20;
       .byte 0x10;
       .byte 0x50;
       .byte 0x20;
       .byte 0x28;
       .byte 0x40;
       .byte 0x30;
       .byte 0x3E;
       .byte 0x70;
       .byte 0x18;
       .byte 0x30;
       .byte 0x60;
       .byte 0x20;
       .byte 0x18;
       .byte 0x40;
       .byte 0x30;
       .byte 0x24;
       .byte 0x50;
       .byte 0x7F;
       .byte 0x06;
       .byte 0x70;

SE484: .byte 0x00;
       .byte 0x7F;
       .byte 0x40;
       .byte 0x10;
       .byte 0x60;
       .byte 0x28;
       .byte 0x38;
       .byte 0x30;
       .byte 0x28;
       .byte 0x08;
       .byte 0x40;
       .byte 0x30;
       .byte 0x28;
       .byte 0x7F;
       .byte 0x20;
       .byte 0x18;
       .byte 0x30;
       .byte 0x30;
       .byte 0x08;
       .byte 0x68;
       .byte 0x40;
       .byte 0x20;
       .byte 0x50;
       .byte 0x7F;
       .byte 0x38;
       .byte 0x70;

SE49E: .byte 0x00;
       .byte 0x80;
       .byte 0x40;
       .byte 0x30;
       .byte 0x60;
       .byte 0x38;
       .byte 0x18;
       .byte 0x30;
       .byte 0x30;
       .byte 0x20;
       .byte 0x18;
       .byte 0x20;
       .byte 0x38;
       .byte 0x40;
       .byte 0x28;
       .byte 0x10;
       .byte 0x60;
       .byte 0x20;
       .byte 0x00;
       .byte 0x30;
       .byte 0x40;
       .byte 0x38;
       .byte 0x50;
       .byte 0x7F;
       .byte 0x1C;
       .byte 0x70;


/*
 * This routine is responsible for displaying any active
 * bullets, and also for firing new bullets, when an
 * available spot in the bullet structure becomes available.
 * The maximum number of active bullets is 4.  The 40 byte
 * bullet structure starts at C90B.  A bullet will remain
 * 'active' for at most 0x18 passes thru this routine.
 */
process_bullets:
       lda   #0x04;          /* Loop counter = 4 */          
       ldu   #0xC90B;        /* Bullet buffer */             
       ldx   #0xC815;        /* State of fire button (4) */  
       sta   $C88F;                                          
       jsr   $intensity_to_7F;                               
next_bullet:
       lda   ,u;                /* If the current spot is empty, then */
       beq   check_fire_button; /* see if a new bullet should be fired */
       dec   9,u;            /* Decrement the cycle counter for the */
       beq   erase_bullet;   /* and erase bullet if it = 0.  */
       ldd   5,u;                                            
       addd  1,u;    /* y */                                 
       std   5,u;            /* Increment bullet coordinates */
       ldd   7,u;                                            
       addd  3,u;    /* x */                                 
       std   7,u;                                            
       leay  5,u;                                            
       jsr   $draw_dot7F_ptr_in_y;     /* Draw bullet */         
update_bufr_ptr:
       leau  10,u;                                           
       dec   $C88F;          /* Point to next entry */       
       bne   next_bullet;                                    
       rts;                                                  

erase_bullet:
       clr   ,u;                                             
       dec   $C8EA;          /* Decrement active bullet counter */
check_fire_button:
       lda   $C8BD;                                          
       bne   update_bufr_ptr;                                
       lda   $C8EE;                                          
       bne   update_bufr_ptr;                                
       lda   ,x;             /* Check the 'fire' button state */
       beq   update_bufr_ptr;                                

       /*
	* This code 'fires' a new bullet, and fills the
	* available spot in the bullet structure.
	*/
       clr   ,x;                                             
       inc   $C8B6;          /* Flag that a bullet sound should be made */
       inc   ,u;                                             
       ldd   $C8C8;          /* Get ships coordinates */     
       std   5,u;                                            
       ldd   $C8CA;                                          
       std   7,u;                                            
       ldd   $C907;          /* Get ship rise */    
       std   1,u;                                            
       ldd   $C909;          /* Get ship run */    
       std   3,u;                                            
       lda   #0x18;          /* # of passes before bullet expires */
       sta   9,u;                                            
       inc   $C8EA;          /* Increment active bullet counter */
       bra   update_bufr_ptr;                                


/*
 * This procedure processes each mine which has not been
 * destroyed.  If the mine is a moving dot, then its position
 * is updated; if the mine is a dot, then it is draw in its
 * appropriate place; if the mine is active, then the appropriate
 * mine is drawn; if it is a fireball, then the fireball is drawn.
 * The state of the mine is determined by the first byte in the
 * mine structure.  The following values are valid:
 *
 *	0x00 - Mine is dead.
 *  	0x01 - Mine is in process of being destroyed.
 *	0x08 - Mine is visible and moving.
 *	0x10 - Mine is visible, but not moving.
 *	0x20 - Mine is just becoming visible.
 *	0x40 - Mine is a stationary dot.
 *	0x80 - Mine is still moving to final resting place.
 *
 */
draw_non_dead_mines:
       lda   #0x1C;                                          
       sta   $C88F;          /* Use C88F as a loop counter */
       ldu   #0xC933;        /* Put mine pointer into u register */
PE526: lda   ,u;                                             
       bne   non_dead_mine;                                  
update_mine_ptr:
       leau  0x12,u;                                           
       dec   $C88F;                                          
       bne   PE526;                                          
       rts;                                                  

non_dead_mine:
       lbmi  move_mine_dot;                                  
       bita  #0x40;  
       lbne  draw_mine_as_dot;
       bita  #0x20;  
       lbne  mine_becoming_visible;                          
       bita  #0x10;                                          
       lbne  delay_B4_moving_mine;                           
       bita  #0x01;                                          
       lbne  process_destroyed_mine;                         
       lda   1,u;                                            
       cmpa  #0x04;          /* See if this is a fireball */ 
       beq   process_fireball;                               
       bita  #0x01;          /* Code below moves visible mine */
       beq   non_magnetic_mine;                              
       lda   $C8EE;          /* Skip below if hyperspace active */
       bne   non_magnetic_mine;                              
       lda   $C8BD;          /* Skip below if cmd ship disabled */
       bne   non_magnetic_mine;                              
       pshs  dp;                                             
       jsr   $dptoC8;                                        
       lda   0xC8;           /* Draw the mine towards the cmd ship */
       suba  4,u;                                            
       ldb   0xCA;                                           
       subb  6,u;                                            
       jsr   $PF593;                                         
       suba  #0x10;                                          
       sta   0x83;                                           
       ldx   #mine_velocity;                                 
       ldb   3,u;                                            
       lda   b,x;                                            
       ldb   0x83;                                           
       jsr   $calc_rise_run1; /* Calculate new rise and run values */
       sty   8,u;                                            
       stx   10,u;                                           
       puls  dp;                                             
non_magnetic_mine:
       ldd   4,u;            /* This block update mine coordinates */
       addd  8,u;                                            
       std   4,u;                                            
       ldd   6,u;                                            
       addd  10,u;                                           
       std   6,u;                                            

/*
 * This block of code draws a mine, using information in
 * the mine structure element pointed to by the u register.
 */
draw_a_visible_mine:
       jsr   $intensity_to_5F;                               
       ldx   #mine_vector_ptrs;                              
       lda   1,u;            /* byte 1 = mine type */        
       asla;                                                 
       ldx   a,x;            /* Set x = ptr to mine vector list */
       leay  4,u;            /* Set y = mine coordinates. */ 
       ldb   2,u;            /* Set b = scale factor.     */ 
       jsr   $move_y_draw_x2;                                
       jmp   $update_mine_ptr;                               

/*
 * This routine appears to be processing a fireball.
 * It checks to see if the fireball has reached the 
 * edge of the display, and if it has, then the 
 * fireball is removed; else, the fireball is drawn
 * on the display.
 */
process_fireball:
       ldd   4,u;            /* See if the fireball has */   
       addd  8,u;            /* reached the edge of the */   
       bvs   remove_fireball;  /* display. */                  
       std   4,u;                                            
       ldd   6,u;                                            
       addd  10,u;                                           
       bvs   remove_fireball;                                
       std   6,u;                                            
       jsr   $intensity_to_7F;                               
       leay  4,u;            /* Draw the fireball */         
       ldx   #0xCBA7;                                        
       ldb   #0x04;                                          
       jsr   $move_y_draw_x2;                                
       jmp   $update_mine_ptr;                               

remove_fireball:
       clr   ,u;             /* Flag that the fireball has */
       dec   $C8EB;          /* been removed. */             
       jmp   $update_mine_ptr;                               


/*
 * move_mine_dot () does some sort of processing on the
 * mine's coordinates, and then draws the mine as
 * a dot.  I believe that the processing being done
 * is the movement of the dot in the x direction,
 * after the mine field has been seeded, but before
 * the mine dot has reached it's final place.
 * draw_mine_as_dot() draws a mine as a dot.
 *
 * For both these routines, the u register must
 * point to a structure element describing the
 * mine.
 */
move_mine_dot:
       lda   6,u;              /* Update the mines x coordinate, */
       adda  0x10,u;           /* and check to see if it has reached */
       sta   6,u;              /* its final resting place.       */
       cmpa  0x11,u;                                           
       bne   draw_mine_as_dot; /* Flag that the mine dot is at its */
       lsr   ,u;               /* final resting place. */      
draw_mine_as_dot:
       jsr   $intensity_to_5F;                               
       leay  4,u;                                            
       jsr   $draw_dot7F_ptr_in_y;                               
       jmp   $update_mine_ptr;                               


/*
 * This procedure is called when a mine first becomes visible.
 * If the mine is not a large mine, then the mine is drawn at
 * full scale factor; otherwise, if the mine is a large mine,
 * then it will be drawn with a steadily increasing scale factor.
 * This gives the effect of the mine 'popping' up.
 */
mine_becoming_visible:
       lda   3,u;                                            
       cmpa  #0x03;          /* See if this is a large mine */
       bne   use_max_scale_factor;                           
       lda   2,u;                                            
       cmpa  0x10,u;                                           
       bge   use_max_scale_factor;                           
       adda  #0x08;                                          
       sta   2,u;            /* Increment the scale factor */
       bra   PE61A;                                          
use_max_scale_factor:
       lsr   ,u;             /* Flag that mine is full size & visible */
       lda   0x10,u;                                           
       sta   2,u;            /* Set final scale factor */    
       lda   #0x18;                                          
       sta   0x10,u;         /* Set up a delay */              
       lda   $C8ED;                                          
       bne   PE61A;          /* Check to see if any more mine dots left */
       lda   $C8C0;                                          
       bne   PE61A;          /* See if re-seeding already in progress. */
       lda   #0x7F;          /* Set up indirect counter for reseeding */
       sta   $C8A2;          /* since only small mines are left. */
PE61A: jmp   $draw_a_visible_mine;                           


/*
 * This procedure is used to delay the movement of a mine
 * right after it become visible.  After the delay is over,
 * the mine will start moving.
 */
delay_B4_moving_mine:
       dec   0x10,u;         /* Decrement delay counter */     
       bne   PE624;                                          
       lsr   ,u;                                             
PE624: jmp   $draw_a_visible_mine;                           


/*
 * This procedure processes the activation of 2 new mines
 * after a mine has been destroyed.  If the destroyed mine
 * was a small mine, or a fireball, then 2 new mines will
 * not be activated.  At entry time, the 'a' register must
 * contain the type of mine to be started up.
 */
process_destroyed_mine:
       clr   ,u;             /* Flag that this mine is gone */
       lda   1,u;                                            
       cmpa  #0x04;          /* If this was a fireball, then don't */
       beq   PE644;          /* start up 2 new mines. */     
       ldb   3,u;                                            
       decb;                 /* If this was a small mine, then don't */
       beq   PE644;          /* start up 2 new mines. */     
       pshs  a,dp;                                           
       lda   #0xC8;                                          
       tfr   a,dp;                                           
       lda   ,s;             /* Get the type of mine */      
       jsr   $activate_a_mine;                               
       jsr   $activate_a_mine;                               
       puls  a,dp;                                           
PE644: jmp   $update_mine_ptr;                               


/*
 * This routine is responsible for displaying the explosion
 * pattern for all active explosions.  If the command ship
 * is sexploding, then it will also switch over to the
 * next player (eventually).
 */
display_explosion_pattern:
       pshs  dp;                                             
       jsr   $dptoD0;                                        
       jsr   $intensity_to_7F;                               
       ldu   #0xCB2B;        /* Get pointer to the explosion struct */
       lda   #0x0E;                                          
       sta   $C88F;          /* Use C88F as a loop counter */
check_next_explosion:
       lda   ,u;                                             
       lbeq  inc_expl_ptr;                                   
       ldb   4,u;            /* If the scale factor for the explosion */
       cmpb  1,u;            /* has not surpassed the max value, then */
       bhs   chk_4_cmd_ship_explosion;    /* increment it.   */           
       addb  #0x03;                                          
       stb   4,u;                                            
       ldy   2,u;                                            
       ldx   #explosion;     /* Draw the explosion pattern */
       jsr   $move_y_draw_x;                                 

chk_4_cmd_ship_explosion:
       tsta;                 /* This is a cmd ship explosion if bit */
       lbpl  check_4_expired_explosion; /* 0x80 is set. */         
       dec   $C8F7;          /* Stop displaying explosion when C8F7 */
       lbeq  dead_ship;      /* reaches zero. */             
       lda   $C826;                                          
       anda  #0x01;              /* Every other pass through the loop, */
       bne   draw_expl_cmd_ship; /* increment the scale factor used to */
       inc   $C8F8;              /* draw the destroyed command ship. */

draw_expl_cmd_ship:
       lda   $C8F8;          /* Draw the cmd ship in pieces. */
       ldy   #0x7F00;                                        
       ldx   #cmd_ship_pt1;                                  
       jsr   $draw_cmd_ship_fragment;                        
       ldy   #0x6080;                                        
       ldx   #cmd_ship_pt2;                                  
       jsr   $draw_cmd_ship_fragment;                        
       ldy   #0x8050;                                        
       ldx   #cmd_ship_pt3;                                  
       jsr   $draw_cmd_ship_fragment;                        
       ldy   #0xA080;                                        
       ldx   #cmd_ship_pt4;                                  
       jsr   $draw_cmd_ship_fragment;                        
       bra   inc_expl_ptr;                                   

/*
 * This routine is called after a ship has been destroyed.
 * The number of ships for the active player, kept in C8D9,
 * will be decremented.  If more than one player is playing,
 * then save the active players ship count in a memory
 * location (C8DA for player 1, and C8DB for player 2),
 * and then determine who's turn it now is.
 */
dead_ship:
       dec   $C8D9;          /* Decrement the number of ships */
       clr   $C8EB;                                          
       clr   $C8ED;                                          

       lda   $C879;            /* If more than 1 player is playing, */
       beq   check_ship_count; /* then save the active players ship */
       lda   $C89B;            /* ship count in RAM.                */
       lsra;                                                 
       ldx   #0xC8DA;                                        
       ldb   $C8D9;                                          
       stb   a,x;                                            

       lda   $C8DA;          /* See who's turn it is.  Skip a player */
       bne   next_player;    /* if he has no more ships.             */
       lda   $C8DB;                                          
       beq   flag_no_ships_left;                             

next_player:
       lda   $C89B;          /* Increment active player indicator */
       adda  #0x02;                                          
       anda  #0x02;                                          
       sta   $C89B;                                          

       lsra;                 /* Load the ship count for new player */
       ldx   #0xC8DA;                                        
       ldb   a,x;                                            
       stb   $C8D9;                                          
       beq   next_player;                                    

/*
 * This routine checks to see if the active player has any ships
 * left, after the command ship has exploded.
 */
check_ship_count:
       lda   $C8D9;                                          
       bne   explosion_expired;                             
flag_no_ships_left:
       lda   #0x01;                                          
       sta   $C8BE;          /* Set C8BE when no ships left */
       bra   explosion_expired;                             

/*
 * This routine checks to see if the explosion has expired.
 * An explosion expires when its scale factor surpasses a
 * preset maximum value.
 */
check_4_expired_explosion:
       ldb   4,u;            /* See if scale factor has reached */
       cmpb  1,u;            /* the maximum value allowed. */        
       blo   inc_expl_ptr;                                   
explosion_expired:
       clr   ,u;                                             
       dec   $C8EC;          /* Flag completion of cmd ship explosion */

inc_expl_ptr:
       leau  5,u;                                            
       dec   $C88F;                                          
       lbne  check_next_explosion;                           
       jsr   $make_misc_sounds;                              
       bra   draw_tiny_ships;                                

/* Draw the tiny ships in lower righthand corner */
PE711: pshs  dp;                                             
       jsr   $dptoD0;                                        
draw_tiny_ship:
       jsr   $intensity_to_5F;                               
       ldx   #0x8038;                                        
       stx   $C890;                   /* Position for first ship */   
       lda   $C8D9;                   /* Don't bother, if the active */
       beq   rotate_fireball_vectors; /* player has no ships left. */ 
       sta   $C88F;                                          
PE727: dec   $C88F;                                          
       beq   rotate_fireball_vectors; /* Exit when all ships drawn */ 
       lda   $C891;                                          
       adda  #0x06;          /* Increment x coordinate */    
       sta   $C891;                                          
       ldb   #0x04;                                          
       ldy   $C890;                                          
       ldx   #command_ship;                                  
       jsr   $move_y_draw_x; /* Draw the tiny command ship */
       bra   PE727;                                          

/*
 * This routine rotates the fireball vector list.  Also,
 * it checks to see whether this level has been cleared.
 */
rotate_fireball_vectors:
       puls  dp;                                             
       lda   0x26;                                           
       anda  #0x01;                                          
       asla;                                                 
       asla;                                                 
       asla;                                                 
       ldx   #fireball;                                      
       ldu   #0xCBA7;                                        
       jsr   $rotate_vector_list1;                           

       /*
	* This block of code determines whether or not the main
	* loop should be exited.  If the cmd ship is disabled, or
	* if the player has cleared the level, then the main loop
	* will be exited (this is flagged by clearing the carry bit.
	*/
       ldb   0xEC;           /* See if cmd ship is being exploded */
       bne   PE767;                                          
       lda   0xBD;           /* See if cmd ship is disabled */
       bne   PE764;                                          
       ldb   0xEB;           /* check # of active mines */   
       bne   PE767;                                          
       ldb   0xED;           /* check # of dot mines */   
       bne   PE767;                                          
PE764: andcc #0xFE;          /* Says 'exit main loop' */     
       rts;                                                  
PE767: orcc  #0x01;          /* Says 'do not exit main loop' */
       rts;                                                  


/*
 * This routine is responsible for drawing a single fragment
 * of the exploding command ship.  At entry, 'a' = scale factor,
 * 'y' = pen position, and 'x' = ptr to vector list.
 */
draw_cmd_ship_fragment:
       pshs  a,x,y;                                          
       ldx   #0xC8C8;        /* Move pen to cmd ships location */
       jsr   $move_pen7F_no_inc;                             
       lda   ,s;                                             
       sta   0x04;           /* Set scale factor = a register */
       tfr   y,d;                                            
       jsr   $move_pen_d;    /* Move pen to position in y register */
       ldb   #0x0C;                                          
       ldx   1,s;                                            
       jsr   $drawl1b;       /* Draw vector list pointed to by x reg */
       puls  a,x,y,pc;                                       


/*
 * This routine is called after a bullet has hit something,
 * or the command ship collides with something.  It will
 * search through the explosion structure, looking for an
 * empty slot.  When it finds one, it will fill it with the
 * information passed in.  At entry time, 'a' = type of explosion
 * and the scale factor to use, 'b' = the max scale factor to
 * be used, and 'x' contains the position for the explosion.
 * If the hi bit of 'a' is set, then that flags that it is the
 * command ship exploding; the lower 7 bits are used to specify
 * the initial scale factor.
 */
add_an_explosion:
     : pshs  a,b,x;                                          
       ldx   #0xCB2B;                                        
       lda   #0x0E;                                          
PE78B: ldb   ,x;             /* Find an empty spot in structure */
       beq   found_empty_exp_slot;                           
       leax  5,x;                                            
       deca;                                                 
       bne   PE78B;                                          
       bra   PE7B3;                                          

found_empty_exp_slot:
       lda   ,s;             /* Save the explosion type */   
       anda  #0x80;                                          
       inca;                                                 
       sta   ,x;             /* See if this is a cmd ship explosion */
       bpl   PE7A1;                                          
       inc   0xBD;           /* Flag that cmd ship is disabled */
PE7A1: lda   ,s;                                             
       anda  #0x7F;                                          
       sta   4,x;            /* Save starting scale factor */
       lda   1,s;                                            
       sta   1,x;                                            
       ldd   2,s;                                            
       std   2,x;            /* Save maximum scale factor */ 
       inc   0xEC;           /* Flag that cmd ship is exploding */
       inc   0xF3;           /* Flag that explosion sound should be made */
PE7B3: puls  a,b,x,pc;                                       


/*
 * This routine is responsible for calculating a rise and run
 * for an object whose angle of travel is in the 'b' register,
 * and whose velocity is in the 'a' register.
 * The rise is returned in the 'y' register, and the run is
 * returned in the 'x' register.
 */
calc_rise_run1:
       pshs  a,b,x,y;                                        
       jsr   $rotate_1_coordinate;                           
       sta   4,s;                                            
       sex;                                                  
       aslb;                                                 
       rola;                                                 
       aslb;                                                 
       rola;                                                 
       aslb;                                                 
       rola;                                                 
       std   2,s;                                            
       ldb   4,s;                                            
       sex;                                                  
       aslb;                                                 
       rola;                                                 
       aslb;                                                 
       rola;                                                 
       aslb;                                                 
       rola;                                                 
       std   4,s;                                            
       puls  a,b,x,y,pc;                                     


/*
 * This routine also calculates some sort of rise & run pair.
 * The same parameters are expected at entry time, and the
 * values are returned in the same registers.
 */
calc_rise_run2:
       pshs  a,b,x,y;                                        
       bsr   calc_rise_run1;                                 
       ldd   -4,s;                                           
       aslb;                                                 
       rola;                                                 
       std   4,s;                                            
       ldd   -6,s;                                           
       aslb;                                                 
       rola;                                                 
       std   2,s;                                            
       puls  a,b,x,y,pc;                                     


/*
 * This routine is called each time a new mine level is
 * started.  It initializes everything necessary.
 */
init_RAM_for_new_level:
       lda   #0xD0;                                          
       tfr   a,dp;                                           
       jsr   $clear_sound_chip;                              
       lda   #0xC8;                                          
       tfr   a,dp;                                           
       clr   0x9C;           /* Clear all 4 indirect jump counters */
       clr   0x9F;                                           
       clr   0xA2;                                           
       clr   0xA5;                                           
       ldx   #0xC90B;        /* Clear C90B - CB71 */         
PE7FA: clr   ,x+;                                            
       cmpx  #0xCB71;                                        
       bne   PE7FA;                                          
       ldd   #0x0000;                                        
       std   0xDE;                                           
       std   0xE0;                                           
       std   0xE2;                                           
       std   0xE4;                                           
       sta   0xE7;                                           
       sta   0xBD;           /* Clear cmd ship disabled flag */
       sta   0xBE;           /* Clear 'no more ships' flag */
       sta   0xEA;           /* Clear active bullet counter */
       sta   0xEB;                                           
       sta   0xEC;           /* Clear cmd ship exploding flag */
       sta   0xF8;           /* Clear destroyed cmd ship scale factor */
       ldb   #0x40;  
       stb   0xF7;           /* Init cmd ship exploding loop counter */
       sta   0xED;           /* Clear # of dot mines */   
       sta   0xC0;           /* Clear mine activated during reseeding flag */
       ldx   #0x0800;                                        
       stx   0xF0;           /* Set end of game loop counter */
       lda   #0x07;                                          
       sta   0xBF;           /* Init # of mines to be reseeded */
       ldx   #ind_init_screen_seeding;                       
       stx   0xA3;           /* Init indirect jump location for reseeding */
       ldd   #0x0000;                                        
       std   0xC8;           /* Clear the command ship's */  
       std   0xCA;           /* position indicators. */      

clear_cmd_ship_xformation:
       ldd   #0x0000;                                        
       sta   0xD4;           /* Clear rotation counter */    
       std   0xCC;                                           
       std   0xCE;                                           
       sta   0xD5;           /* Clear cmd ships velocity */  
       sta   0xD6;                                           
       std   0xD0;                                           
       std   0xD2;                                           
       sta   0xD7;                                           
       sta   0xD8;                                           

/*
 * This block of code takes the vector list describing the
 * command ship, and applies a rotation transformation to
 * them.  The current rotation value is in C8D4, and the
 * transformed vector list is stored in the buffer
 * starting at CB89.
 */
rotate_cmd_ship:
       lda   0xD4;                                           
       ldx   #command_ship;                                  
       ldu   #0xCB89;                                        
       jsr   $rotate_vector_list1;                           

       lda   #0x7F;                                          
       ldb   0xD4;                                           
       jsr   $calc_rise_run2;                                
       sty   $C907;                                          
       stx   $C909;                                          
       rts;                                                  


/*
 * This routine is called after the active player clears
 * a mine field level.  This routine will slowly bring the
 * command ship back to the center of the screen.  As this
 * is being done, a series of dots will be drawn to simulate
 * motion.
 */
bring_ship_to_center:
       pshs  x,y;                                            
       pshs  dp;                                             
       jsr   $dptoD0;                                        
       jsr   $clear_sound_chip;                              
       puls  dp;                                             
       lda   #0xA0;                                          
       sta   0x8F;           /* Use C88F as a loop counter */

PE876: lda   0xC8;                                           
       beq   PE884;          /* Modify the y coordinate for the */
       bmi   PE87F;          /* command ship, in an effort to */
       deca;                 /* force it back to 0. */       
       bra   PE880;                                          
PE87F: inca;                                                 
PE880: sta   0xC8;                                           
       clr   0xC9;                                           

PE884: lda   0xCA;           /* Modify the x coordinate for the */
       beq   PE892;          /* command ship, in an effort to */
       bmi   PE88D;          /* force it back to 0. */       
       deca;                                                 
       bra   PE88E;                                          
PE88D: inca;                                                 
PE88E: sta   0xCA;                                           
       clr   0xCB;                                           

PE892: lda   0xD4;           /* Modify the rotation value for the */
       beq   PE8A2;          /* command ship, in an effort to */
       cmpa  #0x1F;          /* force it back to 0. */       
       bgt   PE89D;                                          
       deca;                                                 
       bra   PE89E;                                          
PE89D: inca;                                                 
PE89E: anda  #0x3F;                      
       sta   0xD4;                                           

PE8A2: jsr   $PE2F2;         /* This loop, repeated 8 times (once */
       ldx   #0xCB81;        /* for each scale factor in the array) */
       ldb   #0x08;          /* increments each of the scale factors */
PE8AA: lda   ,x;             /* for the motion dots, by 3. */
       adda  #0x03;                                          
       sta   ,x+;                                            
       decb;                                                 
       bne   PE8AA;                                          

       pshs  dp;                                             
       jsr   $dptoD0;                                        
       jsr   $display_both_scores;                           
       clrb;                                                 
       lda   #0x20; /* " " */                                
       jsr   $simulate_motion1;                              
       jsr   $modify_motion_scales;                          
       puls  dp;                                             

       /* Repeat the above until the ship is centered. */
       lda   0xC8;                                           
       lbne  PE876;                                          
       lda   0xCA;                                           
       lbne  PE876;                                          
       lda   0xD4;                                           
       lbne  PE876;                                          
       dec   0x8F;                                           
       lbne  PE876;                                          
       jsr   $init_RAM_for_new_level;                        
       puls  x,y,pc;                                         


/*
 * This routine initializes the two arrays
 * (CB71 and CB81) which contain the data
 * needed to produce the motion dots (the
 * dots displayed as the ship moves from
 * one level to the next).  The 8 entries
 * in CB71 are pointers to the 8 sets of
 * required dots.  The 8 entries in CB81
 * are the corresponding scale factors.
 */
init_motion_dots:
       ldx   #motion_dots;                                   
       ldy   #0xCB71;                                        
       ldu   #0xCB81;                                        
       ldb   #0x08;                                          
       lda   #0x16;                                          
PE8F1: stx   ,y++;                                           
       leax  8,x;                                            
       sta   ,u+;                                            
       adda  #0x0F;                                          
       decb;                                                 
       bne   PE8F1;                                          
       rts;                                                  


/*
 * modify_motion_scales() increments each of the 8 motion
 * scale factors, and then draws the new motion dots.
 * simulate_motion1() and simulate_motion2() both
 * draw the current motion dots.  The motion dots will
 * only be drawn if the scale factor is > the value specified
 * in the 'a' register, and if (scale - 'b') > 0.
 */
modify_motion_scales:
       pshs  a,b,dp,x;                                       
       ldx   #0xCB81;                                        
       lda   #0x08;                                          
PE904: inc   ,x+;            /* Increment each of the scale factors */
       deca;                                                 
       bne   PE904;                                          
       bra   simulate_motion2;                               

simulate_motion1:
       pshs  a,b,dp,x;                                       
simulate_motion2:
       lda   #0xD0;                                          
       tfr   a,dp;                                           
       lda   #0x09;          /* Use 'a' as a loop counter */ 
       pshs  a;                                              
PE915: dec   ,s;                                             
       bne   PE920;                                          
       jsr   $reset0ref;                                     
       puls  a;                                              
       puls  a,b,dp,x,pc;                                    
PE920: jsr   $reset0ref;                                     
       lda   #0x03;          /* Use C823 to hold # of dots */
       sta   $C823;          /* to be drawn (4).  */         
       lda   ,s;                                             
       deca;                                                 
       ldx   #0xCB81;                                        
       ldb   a,x;                                            
       andb  #0x7F;                                          
       cmpb  1,s;            /* Make sure scale factor is */ 
       bls   PE915;          /* within the specified range */
       subb  2,s;                                            
       ble   PE915;                                          
       stb   0x04;           /* Set the hardware scale factor */

       ldx   #0xCB71;        /* Draw the dot list */         
       asla;                 /* Convert loop cntr to a word offset */
       ldx   a,x;                                            
       jsr   $intensity_to_7F;                               
       jsr   $dot_list;                                     
       bra   PE915;                                          


/*
 * This routine is responsible for drawing the hyperspace dot
 * during a hyperspace.  It draws the 8 sets of motion dots,
 * using a decreasing scale factor.  At entry, the 'b' register
 * contains the minimum scale factor to be used.
 */
draw_hyperspace_motion_dots:
       pshs  a,b,dp,x;                                       
       lda   #0xD0;                                          
       tfr   a,dp;                                           
       lda   #0x09;          /* Push the loop cntr on the stack */
       pshs  a;                                              
next_set_of_dots:
       dec   ,s;                                             
       bne   draw_the_dots;                                  
       jsr   $reset0ref;                                     
       puls  a;                                              
       puls  a,b,dp,x,pc;                                    

draw_the_dots:
       jsr   $reset0ref;                                     
       lda   #0x03;                                          
       sta   $C823;          /* Use C823 to hold # of dots to draw */
       ldx   #0xC8C8;                                        
       jsr   $move_pen7F_no_inc;                             
       ldb   ,s;                                             
       aslb;                                                 
       aslb;                                                 
       addb  2,s;            /* Calculate the scale factor */
       ble   next_set_of_dots;                               
       andb  #0x7F;                                          
       stb   0x04;           /* Set scale factor */          
       ldx   #0xCB71;                                        
       lda   ,s;             /* Draw the appropriate set of dots */
       deca;                                                 
       asla;                                                 
       ldx   a,x;                                            
       jsr   $intensity_to_7F;                               
       jsr   $dot_list;                                     
       bra   next_set_of_dots;                               


/*
 * Generate 2 random numbers (1 byte each), and return
 * them in a and b.  The range for the two numbers is:
 *
 *	0x80 <= first #  <= 0x7F     (a register)
 *	0xA0 <= second # <= 0x60     (b register)
 */
MS_get_2_random_nums:
       pshs  a,b;                                            
       jsr   $get_random_a;                                  
       sta   ,s;                                             
PE991: jsr   $get_random_a;                                  
       cmpa  #0x60;                      
       bgt   PE991;                                          
       cmpa  #0xA0;                                          
       blt   PE991;                                          
       sta   1,s;                                            
       puls  a,b;                                            
       rts;                                                  


/*
 * This routine randomly activates a single mine.
 * At entry, the 'a' register must contain the
 * type of mine to be activated, while the 'b'
 * register must contain the generation number
 * for the mine (i.e. large, medium, or small).
 */
activate_a_mine:
       pshs  a,b,x,y,u;                                      
       lda   0xED;           /* Check C8ED to see if there are any */
       lbeq  PEA3C;          /* dot mines; if not, then return. */
       dec   0xED;           

       jsr   $get_random_a;  /* Generate a random index into the */
       anda  #0x1F;          /* mine array. */               
PE9B0: sta   0x8B;                                           
       cmpa  #0x1B;                                          
       bls   PE9BA;                                          
       suba  #0x04;                                          
       bra   PE9B0;                                          

PE9BA: ldb   #0x12;          /* Multiple offset by element size */
       mul;                                                  
       addd  #0xC933;                                        
       tfr   d,u;                                            
       lda   ,u;                  /* Check to see if this mine is already */
       anda  #0xC0;               /* being used.  If it is, then check */
       bne   init_a_visible_mine; /* the next mine in the structure; else */
       inc   0x8B;                /* use this mine.  */           
       lda   0x8B;                                           
       cmpa  #0x1B;                                          
       ble   PE9BA;                                          
       clr   0x8B;                                           
       clra;                                                 
       bra   PE9BA;                                          

init_a_visible_mine:
       lda   ,s;             /* Store the mine type */       
       sta   1,u;                                            
       ldx   #mine_values;                                   
       asla;                                                 
       ldy   a,x;                                            
       sty   0x89;           /* Store mine's value in C889 */
       ldb   #0x20;
       stb   ,u;                                             
       ldx   #mine_velocity;                                 
       lda   1,s;            /* Save mine's velocity */      
       ldb   a,x;                                            
       stb   0x8B;                                           
       ldx   #final_mine_scale_factor;                       
       ldb   a,x;                                            
       stb   0x10,u;         /* Save mine's max scale factor */  
       sta   3,u;            /* Save mine's generation number */
       ldx   #mine_sizes;                                    
       asla;                                                 
       ldy   a,x;                                            
       sty   0x12,u;         /* Save mine's size */            
       ldx   #extra_mine_value;                              
       ldy   a,x;                                            
       sty   0x87;           /* Get any extra value for mine's size */
       cmpa  #0x06;                                          
       bne   PEA13;                                          
       inc   0xF4;           /* Flag that a sound should be made */
PEA13: lda   0x88;                                           
       adda  0x8A;                                           
       daa;                                                  
       sta   0x15,u;         /* Generate lo byte of score */   
       lda   0x87;                                           
       adca  0x89;                                           
       daa;                                                  
       sta   0x14,u;        /* Generate hi byte of score */    
       lda   0x8B;                                           
       jsr   $MS_random_num_4_to_3C;                         
       jsr   $calc_rise_run1;                                
       sty   8,u;           /* Save the rise */              
       stx   10,u;          /* Save the run */               
       inc   0xEB;          /* Increment 'active mine' counter */
       lda   0xC0;                                           
       beq   PEA3C;                                          
       lda   #0xFF;                                          
       sta   0x9C;                                           
       lda   #0x03;                                          
       sta   0xC1;                                           
PEA3C: puls  a,b,x,y,u,pc;                                   


/*
 * Generate a random number between 4 and 0x3C.  The
 * result is returned in the b register.
 */
MS_random_num_4_to_3C:
       pshs  a,b;                                            
       jsr   $get_random_a;                                  
       tfr   a,b;                                            
       anda  #0x30; /* "0" */                                
       sta   1,s;                                            
       andb  #0x0F;                                          
       cmpb  #0x04;                                          
       bhs   PEA51;                                          
       addb  #0x04;                                          
PEA51: cmpb  #0x0C;                                          
       bls   PEA57;                                          
       subb  #0x04;                                          
PEA57: addb  1,s;                                            
       stb   1,s;                                            
       puls  a,b,pc;                                         


/*
 * Force the scale factor to 0x7F, then
 * draw a dot at the position contained
 * in the y register.
 */
draw_dot7F_at_y:
       pshs  a,b;                                            
       lda   #0x7F;                                          
       sta   0x04;                                           
       tfr   y,d;                                            
       jsr   $dot;                                           
       jsr   $reset0ref;                                     
       puls  a,b,pc;                                         


/*
 * Force the scale factor to 0x7F, then draw a
 * dot at the position pointed to by the y
 * register (y coord = (0,y), x coord = (2,y)).
 */
draw_dot7F_ptr_in_y:
       pshs  a,b;                                            
       lda   #0x7F;                                          
       sta   0x04;                                           
       lda   ,y;                                             
       ldb   2,y;                                            
       jsr   $dot;                                           
       jsr   $reset0ref;                                     
       puls  a,b,pc;                                         


/*
 * Move the pen to the position specified
 * in the y register, then draw the vector
 * list pointed to by the x register; the
 * scale factor is in the b register. 
 */
move_y_draw_x:
       pshs  a,b,x;                                          
       tfr   y,d;                                            
       jsr   $move_pen7F_to_d;                               
       ldb   1,s;                                            
       jsr   $drawl1b;                                       
       puls  a,b,x,pc;                                       


/*
 * Move the pen to the position specified in the y
 * register, and draw the list of vectors pointed to
 * by the x register; the scale factor to be used is
 * in the b register. (y coord = (0,y), x coord = (x,y))
 */
move_y_draw_x2:
       pshs  a,b,x;                                          
       tfr   y,x;                                            
       jsr   $move_pen7F_no_inc;                             
       ldb   1,s;                                            
       ldx   2,s;                                            
       jsr   $drawl1b;                                       
       puls  a,b,x,pc;                                       


/*
 * Force the scale factor to 0x7F, then print
 * a single string (upto a 0x80).  The pointer
 * to the string block is contained in the 
 * u register.
 */
MS_print_1_string7F:
       pshs  a,b,x,u;                                        
       lda   #0x7F;                                          
       sta   0x04;                                           
       jsr   $print_1_string;                                
       puls  a,b,x,u,pc;                                     


/*
 * Move the pen to the position specified in the
 * y register, then print a string.  The pointer
 * to the string (not a string block) is in the
 * u register.
 */
move_y_print_string:
       pshs  a,b,x,u;                                        
       tfr   y,d;                                            
       jsr   $move_pen7F_to_d;                               
       jsr   $display_string;                                
       puls  a,b,x,y,pc;                                     


/*
 * Use the value in C89B (the active player) to 
 * determine which players score to display,
 * and then display the score string.
 */
display_active_players_score:
       jsr   $intensity_to_7F;                               
       ldd   #0xFC38;                                        
       std   $C82A;          /* Specify height and width */  
       lda   $C89B;                                          
       ldy   #score_string_positions;                        
       ldy   a,y;            /* Load string position into y */
       ldu   #score_string_pointers;                         
       ldu   a,u;            /* Load score string into u */  
       bsr   move_y_print_string;                            
       rts;                                                  


/*
 * Display the score for both players 
 */
display_both_scores:
       jsr   $intensity_to_7F;                               
       ldd   #0xFC38;                                        
       std   $C82A;          /* Specify height and width */  
       ldy   #0x7FA0;        /* Load y with y&x positions */ 
       ldu   #0xC8A8;        /* Load u with player 1 score */
       bsr   move_y_print_string;                            
       lda   $C879;          /* See if we need to display player 2 score */
       beq   PEAEF;                                          
       ldy   #0x7F10;        /* Load y with y&x positions */ 
       ldu   #0xC8AF;        /* Load u with player 2 score */
       bsr   move_y_print_string;                            
PEAEF: rts;                                                  


/* 
 * This routine is responsible for reading the current
 * states of the joystick and buttons.  Next, it will
 * check each of the four indirect jump counters, and
 * if any of them equal 0 after being decremented, then
 * the appropriate indirect handling routine will be
 * called.  The four indirect counters, and their corresponding
 * handler routines are shown below:
 *
 *         counter          handler
 *         -------          -------
 *           C89C           C89D-C89E
 *           C89F           C8A0-C8A1
 *           C8A2           C8A3-C8A4
 *           C8A5           C8A6-C8A7
 *
 */
process_indirect_jumps:
       jsr   $waitrecal;                                     
       pshs  dp;                                             
       jsr   $PF2E6;                                         
       jsr   $display_active_players_score;                  

       /* Set mask (in C880) and read the switches */
       lda   $C880;                                          
       jsr   $read_switches;                                 

       /* Set enable flags (in C881) and read joystick */
       ldd   $C881;                                          
       std   $C81F;                                          
       std   $C821;                                          
       jsr   $read_jstick;                                   

       lda   #0xC8;                                          
       tfr   a,dp;                                           
       lda   0x9C;                                           
       beq   PEB1D;                                          
       dec   0x9C;                                           
       bne   PEB1D;                                          
       jsr   [C89D];   /* (UNKNOWN JUMP) */                  
PEB1D: lda   0x9F;                                           
       beq   PEB29;                                          
       dec   0x9F;                                           
       bne   PEB29;                                          
       jsr   [C8A0];   /* (UNKNOWN JUMP) */                  
PEB29: lda   0xA2;                                           
       beq   PEB35;                                          
       dec   0xA2;                                           
       bne   PEB35;                                          
       jsr   [C8A3];   /* (UNKNOWN JUMP) */                  
PEB35: lda   0xA5;                                           
       beq   PEB41;                                          
       dec   0xA5;                                           
       bne   PEB41;                                          
       jsr   [C8A6];   /* (UNKNOWN JUMP) */                  
PEB41: puls  dp,pc;                                          


/*
 * This routine check to see if any of the
 * bullets have hit a mine or a fireball or
 * the enemy ship.  If something is hit, then
 * the active player's score will be modified.
 */
check_bullets_for_hits:
       lda   0xEA;           /* Don't bother checking if there are */
       beq   PEB59;          /* no active bullets. (C8EA = 0) */
       ldy   #0xC90B;                                        
       lda   #0x04;                                          
       sta   0x8F;           /* Use C88F as a loop counter */
check_for_active_bullet:
       tst   ,y;             /* See if this bullet is active */
       bne   check_enemy_ship_4_hit;                         
inc_bullet_ptr2:
       leay  10,y;           /* Increment ptr to next bullet */
       dec   0x8F;                                           
       bne   check_for_active_bullet;                        
PEB59: rts;                                                  

check_enemy_ship_4_hit:
       lda   0xE7;                 /* Only check for a hit on the enemy */
       beq   check_mines_for_hits; /* ship if it is showing (C8E7 > 0). */
       pshs  y;                                              
       lda   5,y;                                            
       ldb   7,y;                                            
       tfr   d,x;                   /* bullets position */          
       ldd   #0x0616;               /* height/2 and width/2 of enemy ship */
       ldy   0xDC;                  /* position of enemy ship */    
       jsr   $check_bullet_for_hit; /* See if the enemy ship was hit */
       puls  y;                                              
       bhs   check_mines_for_hits;                           
       clr   ,y;             /* HIT - flag that bullet is dead */
       clr   0xE7;           /* Flag that enemy ship no longer there */
       clr   0xA2;           /* Clear 1 indirect jump counter */
       ldx   #score_string_pointers;                         
       lda   0x9B;                                           
       ldx   a,x;                                            
       ldd   #0x1000;        /* Inc players score by 1000 */ 
       jsr   $add_d_to_x_in_bcd;                             
       lda   #0x30;  
       ldb   #0x70;  
       ldx   0xDC;                                           
       jsr   $add_an_explosion;                              
       dec   0xEA;           /* Decrement the # of active bullets */
       bra   PEB59;                                          

/*
 * This routine checks to see if a bullet hit 
 * any of the active mines or fireballs.
 */
check_mines_for_hit:
       ldu   #0xC933;        /* Load 'u' with ptr to mine info */
       lda   #0x1C;                                          
       sta   0x90;           /* Use C890 as a counter */     
check_for_active_mine:
       lda   ,u;                                             
       anda  #0x3F;          /* Make sure mine is active */
       bne   check_this_mine;                                
inc_mine_ptr2:
       leau  0x12,u;           /* Inc ptr into mine structure */
       dec   0x90;                                           
       bne   check_for_active_mine;                          
       bra   inc_bullet_ptr2;                                

check_this_mine:
       pshs  y;                                              
       lda   5,y;                                            
       ldb   7,y;                                            
       tfr   d,x;                   /* bullet coordinates */        
       lda   4,u;                                            
       ldb   6,u;                   /* mine coordinates */          
       tfr   d,y;                                            
       ldd   12,u;                  /* height & width of mine */    
       jsr   $check_bullet_for_hit; /* returns: carry set = hit, else miss */
       puls  y;                                              
       bhs   inc_mine_ptr2;                                  
       lda   1,u;            /* Check if this is a fireball mine */
       anda  #0x02;                                          
       beq   not_a_fireball_mine;                            
       ldx   #score_string_pointers;                         
       lda   0x9B;                                           
       ldx   a,x;                                            
       ldd   14,u;           /* Add mines value to players score */
       jsr   $add_d_to_x_in_bcd;                             
       inc   0xF5;                                           
       lda   4,u;                                            
       ldb   6,u;                                            
       tfr   d,x;                                            
       lda   2,u;                                            
       ldb   #0x20;                      
       jsr   $add_an_explosion;                              
       ldd   #0x0110;        /* Init score for the fireball */
       std   14,u;                                           
       lda   0xC8;                                           
       suba  4,u;                                            
       ldb   0xCA;                                           
       subb  6,u;                                            
       jsr   $PF593;                                         
       suba  #0x10;                                          
       tfr   a,b;                                            
       pshs  y;                                              
       lda   #0x3F;  
       jsr   $calc_rise_run1;                                
       sty   8,u;            /* Calculate rise & run for fireball */
       stx   10,u;                                           
       puls  y;                                              
       clr   ,y;             /* Flag that the bullet is dead */
       ldd   #0x0404;                                        
       std   12,u;           /* Set height/2 & width/2 for fireball */
       lda   1,u;                                            
       ldb   3,u;            /* Decrement the generation for this mine */
       decb;                 /* and don't start any more if it = 0 */
       beq   start_a_fireball;                               
       jsr   $activate_a_mine;                               
       jsr   $activate_a_mine;                               
start_a_fireball:
       lda   #0x04;          /* Flag that this is a fireball */
       sta   1,u;                                            
       dec   0xEA;           /* Decrement active bullet counter */
       jmp   $inc_bullet_ptr2;                               

/*
 * This processes a hit on a non-fireball type mine.
 */
not_a_fireball_mine:
       lda   #0x01;                                          
       sta   ,u;                                             
       clr   ,y;             /* Flag that the bullet is dead */
       ldx   #score_string_pointers;                         
       lda   0x9B;                                           
       ldx   a,x;            /* Add mines value to players score */
       ldd   14,u;                                           
       jsr   $add_d_to_x_in_bcd;                             
       lda   4,u;                                            
       ldb   6,u;                                            
       tfr   d,x;                                            
       lda   2,u;                                            
       ldb   #0x40;  
       jsr   $add_an_explosion;                              
       dec   0xEB;           /* Decrement active mine counter */
       dec   0xEA;           /* Decrement the active bullet counter */
       jmp   $inc_bullet_ptr2;                               


/*
 * This routine check each active mine to see if it has
 * collided with the command ship.
 */
check_ship_4_mine_collision:
       lda   0xBD;                                           
       bne   PEC63;          /* Do only if cmd ship not already dead */
       lda   0xEE;                                           
       bne   PEC63;          /* Do only if hyperspace not active */
       ldy   #0xC933;                                        
       lda   #0x1C;                                          
       sta   0x8F;           /* Set up a loop counter */     
PEC56: lda   ,y;                                             
       anda  #0x3F;  
       bne   check_this_active_mine;                         
inc_mine_ptr3:
       leay  0x12,y;                                           
       dec   0x8F;                                           
       bne   PEC56;                                          
PEC63: rts;                                                  

check_this_active_mine:
       pshs  y;                                              
       lda   0xC8;                                           
       ldb   0xCA;                                           
       tfr   d,x;            /* Load cmd ship's position */  
       lda   4,y;                                            
       ldb   6,y;                                            
       ldy   12,y;           /* Load mine's position */      
       exg   y,d;                                            
       jsr   $check_bullet_for_hit;                          
       puls  y;                                              
       bhs   inc_mine_ptr3;                                  
       clr   ,y;             /* Flag that the mine is dead */
       clr   0xED;                                           
       lda   0xC8;                                           
       ldb   0xCA;                                           
       tfr   d,x;                                            
       lda   2,y;                                            
       ora   #0x80;                                          
       ldb   #0x30;
       jsr   $add_an_explosion;                              
       inc   0xF3;           /* Flag for an explosion sound */
       dec   0xEB;           /* Decrement active mine counter */
       bra   PEC63;                                          


/*
 * This routine checks to see if the command ship has collided
 * with the enemy ship during reseeding.
 */
check_ship_4_enemy_collision:
       lda   0xBD;           /* Do only if cmd ship not disabled */
       bne   PECB2;                                          
       lda   0xEE;           /* Don't do if hyperspace active */
       bne   PECB2;                                          
       lda   0xE7;           /* Check only if enemy ship visible */
       beq   PECB2;                                          
       lda   0xC8;                                           
       ldb   0xCA;                                           
       tfr   d,x;            /* Command ship location */     
       ldd   #0x0616;        /* Size of enemy ship */        
       ldy   0xDC;           /* Enemy ship's location */     
       jsr   $check_bullet_for_hit;                          
       blo   cmd_and_enemy_ship_collision;                   
PECB2: rts;                                                  

cmd_and_enemy_ship_collision:
       clr   0xE7;           /* Flag that enemy ship no longer visible */
       clr   0xA2;
       lda   0xC8;
       ldb   0xCA;
       tfr   d,x; 
       lda   #0x08;
       ora   #0x80;
       ldb   #0x30;
       jsr   $add_an_explosion;                              
       inc   0xF3;           /* Enable explosion sound */    
       rts;                                                  

/*
 * This routine is responsible for making miscellaneous sound,
 * such as when an explosion occurs, or a bullet is fired.
 */
make_misc_sounds:
PECC9: lda   $C8F2;                                          
       beq   PECD6;                                          
       clr   $C8F2;                                          
       ldu   #cmd_ship_movement_sound; /* Make cmd ship movement sound */
       bra   make_the_misc_sound;                            
PECD6: lda   $C8F3;                                          
       beq   PECE3;                                          
       clr   $C8F3;                                          
       ldu   #explosion_sound; /* Make explosion sound */      
       bra   make_the_misc_sound;                            
PECE3: lda   $C8B6;                                          
       beq   PECF0;                                          
       clr   $C8B6;                                          
       ldu   #bullet_sound;  /* Make bullet firing sound */  
       bra   make_the_misc_sound;                            
PECF0: lda   $C8F4;                                          
       beq   PED00;                                          
PECF5: clr   $C8F4;                                          
       clr   $C8F6;                                          
       ldu   #mine_pop_sound; /* Make sound of mine 'popping' up */
       bra   make_the_misc_sound;                            
PED00: lda   $C8F6;                                          
       bne   PECF5;          /* Make hyperspace sound */     
       bra   PED0A;                                          

make_the_misc_sound:
       jsr   $copy_bytes_2_sound_chip;                       
PED0A: ldb   $C800;                                          
       addb  #0x10;                                          
       cmpb  #0xA0;                                          
       bhs   PED1A;                                          
       lda   #0x00;                                          
       jsr   $byte_to_sound_chip;                            
       bra   PED20;                                          
PED1A: ldd   #0x0800;                                        
       jsr   $byte_to_sound_chip;                            
PED20: ldb   $C802;                                          
       addb  #0x20;
       cmpb  #0xF0;                                          
       bhs   PED30;                                          
       lda   #0x02;                                          
       jsr   $byte_to_sound_chip;                            
       bra   PED36;                                          
PED30: ldd   #0x0900;                                        
       jsr   $byte_to_sound_chip;                            
PED36: rts;                                                  


cmd_ship_movement_sound:
       .byte 0x00;           
       .byte 0x10;           
       .byte 0x01;           
       .byte 0x00;           
       .byte 0x06;           
       .byte 0x1F;           
       .byte 0x07;           
       .byte 0x06;           
       .byte 0x08;           
       .byte 0x0F;           
       .byte 0xFF;           

bullet_sound:
       .byte 0x02;           
       .byte 0x39; /* "9" */ 
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x06;           
       .byte 0x1F;           
       .byte 0x07;           
       .byte 0x05;           
       .byte 0x09;           
       .byte 0x0F;           
       .byte 0xFF;           

explosion_sound:
       .byte 0x06;           
       .byte 0x1F;           
       .byte 0x07;           
       .byte 0x07;           
       .byte 0x0A;           
       .byte 0x10;           
       .byte 0x0B;           
       .byte 0x00;           
       .byte 0x0C;           
       .byte 0x38; /* "8" */ 
       .byte 0x0D;           
       .byte 0x00;           
       .byte 0xFF;           

mine_pop_sound:
SED5A: .byte 0x00;           
       .byte 0x00;           
       .byte 0x01;           
       .byte 0x00;           
       .byte 0x02;           
       .byte 0x30; /* "0" */ 
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x04;           
       .byte 0x00;           
       .byte 0x05;           
       .byte 0x00;           
       .byte 0x06;           
       .byte 0x1F;           
       .byte 0x07;           
       .byte 0x3D; /* "=" */ 
       .byte 0x08;           
       .byte 0x00;           
       .byte 0x09;           
       .byte 0x0F;           
       .byte 0x0A;           
       .byte 0x00;           
       .byte 0x0B;           
       .byte 0x00;           
       .byte 0x0C;           
       .byte 0x00;           
       .byte 0x0D;           
       .byte 0x00;           
       .byte 0xFF;           

/* Start of Mine Storm music block */
MS_music:
       .word MS_music_header1; 
       .word music_header2_a;  
       .byte 0x00;           
       .byte 0x19;           
       .byte 0x01;           
       .byte 0x19;           
       .byte 0x00;           
       .byte 0x19;           
       .byte 0x01;           
       .byte 0x32;
       .byte 0x00;           
       .byte 0x19;           
       .byte 0x01;           
       .byte 0x19;           
       .byte 0x00;           
       .byte 0x19;           
       .byte 0x06;           
       .byte 0x19;           
       .byte 0x05;           
       .byte 0x19;           
       .byte 0x00;           
       .byte 0x80;           

MS_music_header1:
       .byte 0xFF;
       .byte 0xEE;
       .byte 0xDD;
       .byte 0xCC;
       .byte 0xBB;
       .byte 0xAA;
       .byte 0x99;
       .byte 0x88;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;
       .byte 0x77;

score_string_pointers:
       .word 0xC8A8;         /* Pointer to player 1 score string */
       .word 0xC8AF;         /* Pointer to player 2 score string */

score_string_positions:
       .byte 0x7F;           /* Player 1 rel y score position */
       .byte 0xA0;           /* Player 1 rel x score position */
       .byte 0x7F;           /* Player 2 rel y score position */
       .byte 0x10;           /* Player 2 rel x score position */

mine_field_level_pointers:
       .word 0xC8F9;         /* Pointer to player 1 mine field # string */
       .word 0xC900;         /* Pointer to player 2 mine field # string */

/*
 * This contains the information describing which mines
 * are to appear at the first 13 mine field levels.  The
 * values map a follows:
 *
 *  0 = dumb mine
 *  1 = magnetic mine
 *  2 = fireball mine
 *  3 = magnetic fireball mine
 *
 */
mines_at_level_x:
       .byte 0x00;           /* level 1 */
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x02;           /* level 2 */
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x01;           /* level 3 */
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x03;           /* level 4 */
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x02;           /* level 5 */
       .byte 0x01;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x02;           /* level 6 */
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x01;           /* level 7 */
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x02;           /* level 8 */
       .byte 0x02;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x01;           /* level 9 */
       .byte 0x01;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x03;           /* level 10 */
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x02;           /* level 11 */
       .byte 0x02;           
       .byte 0x02;           
       .byte 0x00;           
       .byte 0x01;           /* level 12 */
       .byte 0x01;           
       .byte 0x01;           
       .byte 0x00;           
       .byte 0x03;           /* level 13 */
       .byte 0x03;           
       .byte 0x03;           
       .byte 0x00;           
       .byte 0x80;           

motion_dots:
       .byte 0xC8;
       .byte 0x40; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x80; 
       .byte 0x10; 
       .byte 0x1F; 
       .byte 0x3F; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0xBF; 
       .byte 0xBF; 
       .byte 0xBF; 
       .byte 0xC0; 
       .byte 0x20; 
       .byte 0x48; 
       .byte 0x08; 
       .byte 0xF8; 
       .byte 0x30; 
       .byte 0xA8; 
       .byte 0x10; 
       .byte 0xD0; 
       .byte 0xA0; 
       .byte 0xBF; 
       .byte 0xBF; 
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x3F; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0x80; 
       .byte 0x00; 
       .byte 0xB0; 
       .byte 0x48; 
       .byte 0x38; 
       .byte 0xFB; 
       .byte 0x38; 
       .byte 0x80; 
       .byte 0x28; 
       .byte 0x30; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x80; 
       .byte 0x45; 
       .byte 0xF0; 
       .byte 0x28; 
       .byte 0x7F; 
       .byte 0x3F; 
       .byte 0xBF; 
       .byte 0xA5; 
       .byte 0x00; 
       .byte 0xD0; 
       .byte 0x60; 
       .byte 0x20; 
       .byte 0x28; 
       .byte 0xB8; 
       .byte 0x40; 
       .byte 0x15; 
       .byte 0x80; 
       .byte 0x40; 
       .byte 0xF8; 
       .byte 0x40; 
       .byte 0x18; 

mine_field:
       .byte 0xFA;    /* height = -6 */
       .byte 0x38;    /* width = 56 */
       .byte 0xE0;    /* rel y = -32 */
       .byte 0xC8;    /* rel x =     */
       .byte "MINE FIELD", 0x80;

game_over:
       .byte 0xFA;    /* height = -6 */
       .byte 0x38;    /* width = 56 */
       .byte 0xE0;    /* rel y = -32 */
       .byte 0xD8;    /* rel x =     */
       .byte "GAME OVER",0x80;

dumb_mine:
       .byte 0x00;
       .byte 0x10; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0xA0; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x90; 
       .byte 0x20; 
       .byte 0xFF; 
       .byte 0x70; 
       .byte 0x20; 
       .byte 0xFF; 
       .byte 0x50; 
       .byte 0x50; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0x90; 
       .byte 0x01; 

magnetic_mine:
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x30; 
       .byte 0xB0; 
       .byte 0xFF; 
       .byte 0xB0; 
       .byte 0x30; 
       .byte 0xFF; 
       .byte 0xB0; 
       .byte 0xD0; 
       .byte 0xFF; 
       .byte 0x30; 
       .byte 0x50; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0x50; 
       .byte 0xFF; 
       .byte 0x50; 
       .byte 0xD0; 
       .byte 0xFF; 
       .byte 0x50; 
       .byte 0x30; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0xB0; 
       .byte 0x01; 

fireball_mine:
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x30; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x10; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0x10; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0xF0; 
       .byte 0xFF; 
       .byte 0x10; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x40; 
       .byte 0xF0; 
       .byte 0xFF; 
       .byte 0x40; 
       .byte 0x10; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0xC0; 
       .byte 0x01; 

magnetic_fireball_mine:
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0xF0; 
       .byte 0xD0; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x40; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xE0; 
       .byte 0xFF; 
       .byte 0x40; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0xE0; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x01; 

fireball:  
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x80; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x3F; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x80; 
       .byte 0x01; 

explosion:
       .byte 0xFF; 
       .byte 0x7F; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0xC0; 
       .byte 0x10; 
       .byte 0xFF; 
       .byte 0xC0; 
       .byte 0xD0; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0x7F; 
       .byte 0x00; 
       .byte 0xE0; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0xE0; 
       .byte 0x30; 
       .byte 0x00; 
       .byte 0xC0; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x60; 
       .byte 0xCD; 
       .byte 0xFF; 
       .byte 0xA0; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0xD0; 
       .byte 0xFF; 
       .byte 0x3C; 
       .byte 0x30; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x82; 
       .byte 0x00; 
       .byte 0x30; 
       .byte 0x30; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0x50; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0xF0; 
       .byte 0x01; 

command_ship:
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xC4; 
       .byte 0x08; 
       .byte 0xFF; 
       .byte 0xD8; 
       .byte 0xD8; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0xE0; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x28; 
       .byte 0xD8; 
       .byte 0xFF; 
       .byte 0x3C; 
       .byte 0x08; 
       .byte 0x01; 

cmd_ship_pt1:
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xC4; 
       .byte 0x08; 
       .byte 0x01; 

cmd_ship_pt2:
       .byte 0x00; 
       .byte 0x04; 
       .byte 0x08; 
       .byte 0xFF; 
       .byte 0xD8; 
       .byte 0xD8; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x01; 

cmd_ship_pt3:
       .byte 0x00; 
       .byte 0x3F; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xC4; 
       .byte 0xF8; 
       .byte 0x01; 

cmd_ship_pt4:
       .byte 0x00; 
       .byte 0x04; 
       .byte 0xF8; 
       .byte 0xFF; 
       .byte 0xD8; 
       .byte 0x28; 
       .byte 0xFF; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x01; 

enemy_ship_pt1:
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xD8; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0xA8; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x18; 
       .byte 0xFF; 
       .byte 0x18; 
       .byte 0xF0; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0xB8; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0x48; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xE8; 
       .byte 0x10; 
       .byte 0xFF; 
       .byte 0xF8; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x06; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0xFA; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xF0; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0x18; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0x08; 
       .byte 0x01; 

enemy_ship_pt2:
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x28; 
       .byte 0xFF; 
       .byte 0xD0; 
       .byte 0x58; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0xC0; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0xE8; 
       .byte 0xFF; 
       .byte 0x18; 
       .byte 0x10; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0x48; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0xB8; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0xE8; 
       .byte 0xF0; 
       .byte 0xFF; 
       .byte 0xF8; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xFA; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0x06; 
       .byte 0xFF; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0xE8; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0xF8; 
       .byte 0x01; 

enemy_ship_pt3:
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xD8; 
       .byte 0xFF; 
       .byte 0xE8; 
       .byte 0x08; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0x18; 
       .byte 0x08; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xD8; 
       .byte 0x00; 
       .byte 0x08; 
       .byte 0xE0; 
       .byte 0xFF; 
       .byte 0x10; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0xFF; 
       .byte 0xF0; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xC0; 
       .byte 0x01; 

simple_enemy_ship:  
       .byte 0x00; 
       .byte 0x18; 
       .byte 0x00; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0xFF; 
       .byte 0xC8; 
       .byte 0x70; 
       .byte 0xFF; 
       .byte 0x10; 
       .byte 0xA0; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0xA0; 
       .byte 0xFF; 
       .byte 0xEC; 
       .byte 0xA4; 
       .byte 0xFF; 
       .byte 0x39; 
       .byte 0x6D; 
       .byte 0xFF; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x01; 

/* The following is spare space in the ROM */
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           

/*
 * The executive starts executing here, each time the system is reset
 * or powered up.
 */
start: lds   #0xCBEA;         /* Set up the stack pointer */    
       jsr   $reinit;                                        
       ldd   #0x7321;         /* Cold start only if CBFE != 0x7321 */
       cmpd  $CBFE;                                          
       beq   PF06C;                                          
       std   $CBFE;           /* Start the cold start here */   
       inc   $C83B;           /* Flag not to display score */
       ldx   #0xCBEB;                                        
       jsr   $set_dft_score;  /* Initialize the score string */ 
powerup_loop:
       jsr   $dptoC8;                                        
       ldd   0x25;            /* Signal that it is OK to start playing */
       cmpd  #0x0101;         /* the music (set C856), after waitrecal() */
       bne   PF029;           /* has been called 257 times.            */
       stb   0x56;                                           
PF029: asrb;                  /* Determine which line pattern to use */
       andb  #0x03;           /* for drawing the boundary lines.     */

       /* Load the line drawing pattern */
       ldx   #line_patterns;                                 
       ldb   b,x;                                            
       stb   0x29;                                           
       ldb   #0x02;                                          
       stb   0x24;           /*Set intro box redraw count to 2 */

       /* Play the introductory song */
       ldu   #intro_music;                                   
       jsr   $init_sound;                                    
       jsr   $waitrecal;                                     
       jsr   $do_sound;                                      
       jsr   $intensity_to_7F;                               

       /* Display the power-up Vectrex message */
       lda   $C826;                                          
       ldu   #vectrex_string; /* Determine if we should show the double  */
       bita  #0x20;           /* or single high VECTREX message.  Double */
       beq   PF052;           /* if bit 0x20 of waitrecal() counter is 0 */
       leau  12,u;                                           
PF052: jsr   $printu;                                        
       ldx   #intro_box;      /* Draw a 4 sided box */       
PF058: jsr   $move_penFF;                                   
       lda   #0x03;                                          
       jsr   $dwp_with_count;                                
       dec   $C824;                                          
       bne   PF058;          /* Keep drawing box, until C824 = 0 */
       lda   $C825;          /* Keep performing the above, as long as */
       cmpa  #0x01;          /* the lower byte of the waitrecal() counter */
       bls   powerup_loop;   /* is <= 0.                                  */
PF06C: jsr   $dptoC8;                                        
       lda   #0xCC;                                          
       sta   0x29;           /* Set line blanking pattern to 11001100 */
       ldd   #gce_string;                                    
       std   0x39;           /* Save pointer to gce string in C839 */
       clr   0x25;                                           
       clr   0x26;           /* Clear the waitrecal() counter. */

       /* See if a valid rom is installed */
       ldu   #0x0000;                                        
       ldx   #gce_string;                                    
       ldb   #0x0B;                                          
PF084: lda   ,u+;                                            
       cmpa  ,x+;                                            
       beq   PF097;                                          
       cmpb  #0x01;                                          
       beq   PF092;                                          
       cmpb  #0x05;                                          
       bls   PF097;                                          

	/* Boot with the MineStorm rom */
PF092: ldu   #MS_header;                                      
       bra   PF09E;                                          

PF097: decb;                                                 
       bne   PF084;                                          
       stb   0x39;           /* Clear C839-C83A, if using a plug-in */
       stb   0x3A;                                           

	/* Prepare to start a new sound (C856 = 1) */
	/* Load music block pointer for game into u register */
PF09E: inc   0x56;                                           
       stu   0x37;                                           
       ldu   ,u;                                             
PF0A4: jsr   $dptoC8;                                        
       ldd   #0xF848;                                        
       std   0x2A;                                           

       /* Produce the specified tune */
       jsr   $init_sound;                                    
       jsr   $waitrecal;                                     
       jsr   $do_sound;                                      

       /* Print the 'gce' copyright message */
       jsr   $intensity_to_7F;                               
       ldd   #0xC0C0;                                        
       ldu   $C839;                                          
       jsr   $print_at_d;                          

       /* Display the current high score, if any */
       lda   $C83B;                                          
       bne   PF0D2;                                          
       deca;                                                 
       ldu   #0xCBEB;                                        
       sta   6,u;                                            
       ldd   #0x68D0;                                        
       jsr   $print_at_d;                          

       /* Display the name of the game cartridge */
PF0D2: ldu   $C837;                                          
       leau  2,u;                                            
       jsr   $printu;                                        

       /* Keep playing,until C856 is cleared */
       lda   $C856;                                          
       bne   PF0A4;                                          
       ldx   $C825;                                          
       cmpx  #0x007D;                                        
       bls   PF0A4;                                          

       /* Jump to the start of the game */
       jmp   1,u;      /* (UNKNOWN JUMP) */                  


intro_box:
       .byte 0x40; /* "@" */ 
       .byte 0xD6;           
       .byte 0x00;           
       .byte 0x56; /* "V" */ 
       .byte 0x81;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xA9;           
       .byte 0x7E; /* "~" */ 
       .byte 0x00;           

box2:
       .byte 0x39; /* "9" */ 
       .byte 0xDC;           
       .byte 0x8E;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x4A; /* "J" */ 
       .byte 0x72; /* "r" */ 
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xB6;           

  	/* Line patterns */
line_patterns:
       .byte 0xE0;  /* Dashes = 11100000 */
       .byte 0x38;  /* Dashes = 00111000 */
       .byte 0x0E;  /* Dashes = 00001110 */
       .byte 0x03;  /* Dashes = 00000011 */

gce_string:
       .byte "g GCE 1982",0x80;

vectrex_string:
       .byte 0xF1;  /* height = -15 */
       .byte 0x60;  /* width = 96 */
       .byte 0x27;  /* rel y = 39 */
       .byte 0xCF;  /* rel x =    */
       .byte "VECTREX",0x80;
       .byte 0xF3;  /* height = -13 */
       .byte 0x60;  /* width = 96 */
       .byte 0x26;  /* rel y = 38 */
       .byte 0xCF;  /* rel x =    */
       .byte "VECTREX",0x80;
       .byte 0xFC;  /* height = -4 */
       .byte 0x60;  /* width = 96 */
       .byte 0xDF;  /* rel y =    */
       .byte 0xE9;  /* rel x =    */
       .byte "GCE",0x80;
       .byte 0xFC;  /* height = -4 */
       .byte 0x38;  /* width = 56 */
       .byte 0xCC;  /* rel y =    */
       .byte 0xD1;  /* rel x =    */
       .byte "ENTERTAINING",0x80;
       .byte 0xFC;  /* height = -4 */
       .byte 0x38;  /* width = 56 */
       .byte 0xBC;  /* rel y =    */
       .byte 0xDC;  /* rel x =    */
       .byte "NEW IDEAS",0x80,0x00;


init_PIA_chip:
       bsr   dptoD0;                                         
       ldd   #0x9FFF;                                        
       std   0x02;                                           
       ldd   #0x0100;                                        
       std   0x00;                                           
       ldd   #0x987F;                                        
       sta   0x0B;                                           
       stb   0x04;                                           
       jsr   $reset0ref;                                     
       bra   set_refresh;                                    


/* Clear RAM locations C800-C87A */
clear_C800_C87A:
       bsr   dptoC8;                                         
       ldb   #0x7A; /* "z" */                                
       ldx   #0xC800;                                        
       jsr   $clear_blockxb;                                   
       ldd   #0xC87D;                                        
       std   0x7B;                                           

/*
 * Delay until contents of C87D = 0, then
 * Initialize dot dwell time, refresh timer & joystick enable flags
 */
init_flags1:
       inc   0x7D;         /* Delay */                       
       beq   PF173;                                          
       lda   #0x05;                                          
       sta   0x28;         /* Set dot dwell time to 5 */     
       ldd   #0x3075;                                        
       std   0x3D;         /* Set refresh time to 0x3075 */    
       ldd   #0x0103;                                        
       std   0x1F;         /* Set joystick enable flags */   
       ldd   #0x0507;                                        
       std   0x21;         /* Set joystick enable flags */   
       rts;                                                  


reinit:
       bsr   clear_C800_C87A;                                
       bsr   init_PIA_chip;                                  
       jmp   $clear_sound_chip;                              

/*
 * Wait for t2 (the refresh timer) to timeout, then restart
 * it using the value in C83D.  Then, recalibrate the vector
 * generators to the origin (0,0).  This routine MUST be called
 * once every refresh cycle, or your vectors will get out of
 * whack.  This routine calls reset0ref, so the integrators
 * are left in zero mode.  Dp will be set to D0.
 */
waitrecal:
       ldx   $C825;                                          
       leax  1,x;                                            
       stx   $C825;          /* Increment the waitrecal() call counter */
       bsr   dptoD0;                                         
       lda   #0x20;                                          
PF19E: bita  0x0D;           /* Wait for the refresh timer to expire */
       beq   PF19E;                                          

/*
 * This routine loads the refresh timer (t2), with the value in
 * C83D-C83E, and recalibrates the vector generators, thus
 * causing the pen to be left at the origin (0,0). The high
 * order byte for the timer is loaded from C83E, and the low
 * order byte is loaded from C83D.  The refresh rate is calculated
 * as follows:   rate = 1.5 mhz * (C83E)(C83D).
 * Dp must be D0.
 */
set_refresh:
       ldd   $C83D;                                          
       std   0x08;                                           
       jmp   $PF2E6;                                         

/*
 * Sets the dp register to D0, so that all direct addresses
 * will start at D000 (the hardware I/O area).  The a
 * register is trashed.
 */
dptoD0:
       lda   #0xD0;                                          
       tfr   a,dp;                                           
       rts;                                                  

/*
 * Sets the Dp register to C8, so that all direct addresses
 * start at C800.  The a register is trashed.
 */
dptoC8:
       lda   #0xC8;                                          
       tfr   a,dp;                                           
       rts;                                                  

/*
 * Read the switch values for the two consoles.  The switch values
 * are returned in the following locations:
 *
 *	console 1, switch 1:	C812
 *		   switch 2:    C813
 *		   switch 3:    C814
 *		   switch 4:    C815
 *	console 2, switch 1:	C816
 *		   switch 2:	C817
 *		   switch 3:	C818
 *		   switch 4:	C819
 *
 * Before this routine is called, the a register must be set to
 * contain a mask, having the following format:
 *
 * 	bit 0 = console 1, switch1;  etc.
 *
 * If a bit is 0, then the current state of the switch is to be
 * returned in the appropriate ram location (0 = up, 1 = down).  
 *
 * If a bit is 1, then the appropriate ram location is set to 1
 * only on the depression transition of the button; additional
 * calls will return 0, until the switch is release and then
 * depressed again.
 *
 * Dp must be set to D0.
 */
read_switches:
       anda  $C80F;                                          
       sta   $C80F;                                          
       ldx   #0xC812;                                        
       lda   -3,x;                                           
       sta   -2,x;                                           
       lda   #0x0E;                                          
       sta   0x01;                                           
       ldd   #0x1901;                                        
       sta   0x00;                                           
       nop;                                                  
       stb   0x00;                                           
       clr   0x03;                                           
       ldd   #0x0901;                                        
       sta   0x00;                                           
       nop;                                                  
       lda   0x01;                                           
       coma;                                                 
       sta   -3,x;                                           
       stb   0x00;                                           
       ldb   #0xFF;                                          
       stb   0x03;                                           
       coma;                                                 
       ora   -2,x;                                           
       coma;                                                 
       sta   -1,x;                                           
       pshs  a;                                              
       ldb   #0x01;                                          
PF1EA: tfr   b,a;                                            
       anda  ,s;                                             
       sta   ,x+;                                            
       aslb;                                                 
       bne   PF1EA;                                          
       puls  a,pc;                                           


PF1F5: dec $C823;

/*
 * Read the joystick positions of the two consoles.  This routine
 * requires some setup before it should be called.  First, C81F-C822
 * are enable flags, and all must be set to one of the following:
 *
 *	0  ignore.
 *	1  pot 0 (console 1 left/right)
 *	3  pot 1 (console 1 up/down)
 *	5  pot 2 (console 2 left/right)
 *	7  pot 3 (console 2 up/down)
 *
 * Locations C81B-C81E will be set with the pot values corresponding
 * to the enable flags.
 *
 * Location C823 is used to determine what kind of input conversion
 * should be performed.  The valid choices are:
 *
 *	>= 0    The return value will be:
 *		 	< 0 if joystick is left or down of center.
 *			= 0 if joystick is centered.
 *			> 0 if joystick is right or up of center.
 *
 *	< 0	A successive approximation algorithm is used to
 *		read the actual value of the joystick pot, a
 *		signed value.  In this case, C81A must be set to
 *		power of 2, to control conversion resolution;
 *		0x80 i sleast accurate, and 0x00 is most accurate.
 *
 * Dp must be set to D0.
 * C823 is cleared before this routine returns.
 *
 */
read_jstick:
       ldx   #0xC81F;                                        
next_pot:
       lda   ,x+;                                            
       bne   process_a_pot;                                  
check_4_done:
       cmpx  #0xC823;                                        
       bne   next_pot;                                       
       clr   ,x;                                             
       lda   #0x01;                                          
       sta   0x00;                                           
       rts;                                                  
process_a_pot:
       sta   0x00;                                           
       clr   0x01;                                           
       dec   0x00;                                           
       ldb   #0x60;
PF213: incb;                                                 
       bpl   PF213;          /* Delay */                     
       lda   $C823;          /* Get the joystick mode */     
       bmi   use_approx;     /* Use successive approximation */
       lda   #0x20;
       inc   0x00;                                           
       bita  0x00;                                           
       beq   l_or_d;                                         
       ldb   #0x40;
       stb   0x01;                                           
       bita  0x00;                                           
       bne   save_jstick_state;  /* joystick is right or up */
       bra   centered;           /* joystick is centered */  
l_or_d:
       ldb   #0xC0;                                          
       stb   0x01;                                           
       bita  0x00;                                           
       beq   save_jstick_state;  /* joystick is left or down */
centered:
       clrb;                                                 
save_jstick_state:
       stb   -5,x;                                           
       bra   check_4_done;                                   


try_again:
       tfr   b,a;                                            
       ora   0x01;                                           
       sta   0x01;                                           
use_approx:
       lda   #0x20;
       bita  0x00;                                           
       bne   check_resolution;                               
       tfr   b,a;                                            
       eora  0x01;                                           
       sta   0x01;                                           
check_resolution:
       lsrb;                                                 
       cmpb  $C81A;          /* Get the approximation resolution */
       bne   try_again;                                      
       ldb   0x01;                                           
       bra   save_jstick_state;                              


/*
 * These routines cause a byte to be added to a sound
 * buffer.  At entry, 'x' = base address of RAM area of where to
 * store the sound byte.  'a' = offset into the 'x' register as
 * to where to store the byte.  'b' = byte to be processed.
 */
byte_2_sound_chip:
       ldx   #0xC800;                                        
byte_2_sound_chip2:
       stb   a,x;                                            
       sta   0x01;                                           
       lda   #0x19;                                          
       sta   0x00;                                           
       lda   #0x01;                                          
       sta   0x00;                                           
       lda   0x01;                                           
       stb   0x01;                                           
       ldb   #0x11;                                          
       stb   0x00;                                           
       ldb   #0x01;                                          
       stb   0x00;                                           
       rts;                                                  


/*
 * This routine clear out the 15 byte sound buffer.
 */
clear_sound_chip:
       ldd   #0x0E00;                                        
PF275: bsr   byte_to_sound_chip;                             
       deca;                                                 
       bpl   PF275;                                          
       jmp   $init_music_buf;                      


/*
 * This routine copies a group of sound information into the
 * sound chip buffer, at C800.  At entry, 'u' = a pointer to
 * a list of sound pairs.  If the first byte >= 0, then it is
 * used as an index into the sound chip buffer as to where to
 * save the 2nd byte (the sound data).  If the 1st byte is < 0,
 * then the copy stops; dp must by D0.
 */
copy_bytes_2_sound_chip:
       ldx   #0xC800;                                        
       bra   PF284;                                          
PF282: bsr   byte_2_sound_chip2;                             
PF284: ldd   ,u++;                                           
       bpl   PF282;                                          
       rts;                                                  

/*
 * This will start making the sound which was set up by your
 * call to init_sound().  This should be called right after
 * your call to waitrecal().
 */
do_sound:
       ldx   #0xC800;                                        
       ldu   #0xC83F;                                        
       lda   #0x0D;                                          
PF291: ldb   ,u+;                                            
       cmpb  a,x;                                            
       beq   PF299;                                          
       bsr   byte_2_sound_chip2;                             
PF299: deca;                                                 
       bpl   PF291;                                          
       rts;                                                  

/*
 * Sets the intensity (the z axis) to 1F, 3F, 5F or 7F, depending
 * upon which entry point is called.  The intensity must be 
 * reloaded at least every refresh cycle.  However, it may be
 * changed on the fly, if desired.  The current intensity value
 * is saved in C827.  Dp must be D0.
 */
intensity_to_1F:
       lda   #0x1F;                                          
       bra   intensity_to_a;                                 

intensity_to_3F:
       lda   #0x3F; /* "?" */                                
       bra   intensity_to_a;                                 

intensity_to_5F:
       lda   #0x5F; /* "_" */                                
       bra   intensity_to_a;                                 

intensity_to_7F:
       lda   #0x7F;                                          

intensity_to_a:
       sta   0x01;                                           
       sta   $C827;                                          
       ldd   #0x0504;                                        
       sta   0x00;                                           
       stb   0x00;                                           
       stb   0x00;                                           
       ldb   #0x01;                                          
       stb   0x00;                                           
       rts;                                                  

/*
 * Draw a dot at the relative y and relative x coordinates pointed
 * to by the x register, with an intensity proportional to the
 * value in the b register.  The x register is incremented by 2
 * afterwards.  The Dp must be D0.
 */
dotixb:
       stb   $C828;                                          
dotix: ldd   ,x++;           /* Use current intensity value */
dot:   bsr   move_pen_d;     /* Use x&y already in d reg */  
       lda   #0xFF;                                          
       sta   0x0A;                                           
       ldb   $C828;                                          
PF2CC: decb;                 /* Use b (intensity) as loop counter */
       bne   PF2CC;                                          
       clr   0x0A;                                           
       rts;                                                  


/*
 * Draw a series of dots.  The x register points to a list of
 * relative y and relative x location pairs.  The number of
 * dots to be drawn is specified in RAM location C823.
 */
next_dot:
       dec   $C823;                                          
dot_list:
       bsr   dotix;                                          
       lda   $C823;                                          
       bne   next_dot;                                       
       bra   reset0ref;                                      


/* Draw a series of dots.  The x register points to the array
 * of points.  The array has the following format:
 *
 *	mode, relative y position, relative x position
 *
 * If mode > 0, then the drawing ceases, and the integrators are reset.
 */
dotix_then_reset:
       lda   ,x+;                                            
       bgt   reset0ref;                                      
       bsr   dotix;                                          
       bra   dotix_then_reset;                               


PF2E6: ldx   #0xF9F0;                                        
       bsr   move_penFF;                                    
       jsr   $PF36B;                                         
       bsr   move_pen;                                       
       bra   reset0ref;                                      


/*
 * Set the scale factor to 0x7F, then move the pen to the location
 * pointed to by the x register (y coord = (0,x) x coord = (2,x)).
 * The x register is not incremented afterwards.
 */
move_pen7F_no_inc:
       ldb   #0x7F;                                          
       stb   0x04;                                           
       lda   ,x;                                             
       ldb   2,x;                                            
       bra   move_pen_d;                                     


/*
 * Force the scale factor to 0x7F, then move the pen to the
 * position specified in the d register.
 */
move_pen7F_to_d:
       sta   0x01;           /* Set height for string */     
       pshs  a,b;                                            
       lda   #0x7F;                                          
       sta   0x04;           /* Set scale factor to 0x7F */  
       clr   0x00;                                           
       bra   PF318;                                          

/*
 * Move the pen to the relative y and relative x positions
 * pointed to by the x register.  The scale factor is set to
 * 0xFF (170 usec), and then left at this value at exit time.
 * Dp must be D0.  The x register is incremented by 2 before
 * exiting.
 */
move_penFF:
       ldb   #0xFF;                                          
       bra   set_scale_factor;                               

/* Same as above, except scale factor is set to 0x7F (85 usec). */
move_pen7F:
       ldb   #0x7F;                                          
set_scale_factor:
       stb   0x04;                                           

/* Same as above, except the scale factor is not changed */
move_pen:
       ldd   ,x++;                                           

/* Move pen to relative y (in a) and relative x (in b) */
move_pen_d:
       sta   0x01;                                           
       clr   0x00;                                           
       pshs  a,b;                                            
PF318: lda   #0xCE;                                          
       sta   0x0C;                                           
       clr   0x0A;                                           
       inc   0x00;                                           
       stb   0x01;                                           
       clr   0x05;                                           
       puls  a,b;                                            
       jsr   $check_ab_for_overflow;                            
       stb   -1,s;                                           
       ora   -1,s;                                           
       ldb   #0x40; /* "@" */                                
       cmpa  #0x40; /* "@" */                                
       bls   PF345;                                          
       cmpa  #0x64; /* "d" */                                
       bls   PF33B;                                          
       lda   #0x08;                                          
       bra   PF33D;                                          
PF33B: lda   #0x04;                                          
PF33D: bitb  0x0D;                                           
       beq   PF33D;                                          
PF341: deca;                                                 
       bne   PF341;                                          
       rts;                                                  
PF345: bitb  0x0D;                                           
       beq   PF345;                                          
       rts;                                                  


/* Set the dp to D0, then reset the integrators */
set_dp_and_reset0ref:
       jsr   $dptoD0;                                        
       bra   reset0ref;                                      

/*
 * If 0xC824 is non-zero, call reset0ref, else return.
 * Dp must be D0.
 */
check0ref:
       lda   $C824;                                          
       beq   rtn1;                                           

/*
 * This routine zeros the integrators. It resets the origin to
 * (0,0).  This routine leaves the integrators in zero mode, so
 * nothing can be drawn until a move is done, or 0xD00C is set
 * to 0xCE.  Dp must be D0.  This routine should be called
 * every once in awhile, to make sure your vectors don't get off.
 */
reset0ref:
       ldd   #0x00CC;                                        
       stb   0x0C;                                           
       sta   0x0A;                                           
       ldd   #0x0302;                                        
       clr   0x01;                                           
       sta   0x00;                                           
       stb   0x00;                                           
       stb   0x00;                                           
       ldb   #0x01;                                          
       stb   0x00;                                           
rtn1:  rts;                                                  


PF36B: ldd   #0x00CC;                                        
       stb   0x0C;                                           
       sta   0x0A;                                           
       rts;                                                  


/*
 * The following are a series of subroutines which may be used to
 * accomplish several different methods of printing a string.
 * Each one expects the string (and parameter block) to be pointed
 * to by the u register.
 *
 *   print_1_string() - Prints a string (upto a 0x80).  The
 *                      header for the string must include the
 *                      height and width for the string, and
 *                      also the relative y & x positions.
 *
 *   print_with_dft_hw()- Prints a string (upto a 0x80).  The
 *                      header for the string must include
 *                      only the relative y & x positions.  The
 *                      current height & width is used.
 *
 *   print_at_d()      -Prints a string (upto a 0x80).  The
 *                      string contains no header.  The current
 *                      height & width are used. The rely & rel x
 *                      are specified in the d register.
 */
print_1_string:
       ldd   ,u++;           /* Save height and width */     
       std   $C82A;                                          
print_with_dft_hw:
       ldd   ,u++;           /* Get the rel y & rel x positions */
print_at_d:
       jsr   $move_pen7F_to_d; /* Move pen to starting positions */
       jsr   $delay_b_1;                                     
       jmp   $display_string;/* Print string, until 0x80 encountered */
initiate_printing:
       bsr   print_1_string;                                 

/*
 * Display the string whose block is pointed to by the u register.
 * Dp must be D0.  The block for the string must have the following
 * format:
 *
 *  string height, string width,
 *  rel y, rel x, STRING, 0x80,
 *  rel y, rel x, STRING, 0x80,
 *  0x00
 */
printu:
       lda   ,u;                                             
       bne   initiate_printing;    /* Keep printing till 0x00 found */
       rts;                                                  


/*
 * Display  the string whose block is pointed to by the u register.
 * Dp must be D0.  The current height and width values for which
 * the hardware is set are used.  The block for the string must
 * have the following format:
 *
 *  rel y, rel x, STRING, 0x80, 
 *  rel y, rel x, STRING, 0x80,
 *  0x00
 */
printu2:
       bsr   print_with_dft_hw:                              
       lda   ,u;             /* Stop when 0x00 encountered */
       bne   printu2;                                        
       rts;                                                  


PF391: ldx   ,x;                                             
       pshs  b;                                              
       ldb   #0x80;                                          
       leau  -8,s;                                           
       pshu  a,b;                                            
       puls  a;                                              
       cmpa  #0x09;                                          
       bls   PF3A3;                                          
       lda   #0x3C; /* "<" */                                
PF3A3: adda  #0x30; /* "0" */                                
       ldb   #0x2D; /* "-" */                                
       pshu  a,b;                                            
       pshu  x;                                              
       bra   print_with_dft_hw:                              


PF3AD: lda   ,x+;                                            
       bra   PF3B9;                                          


PF3B1: stb   0x04;                                           
       bra   move_to_pt;                                     


PF3B5: ldd   ,x++;                                           
       stb   0x04;                                           
PF3B9: sta   $C823;                                          

move_to_pt:
       ldd   ,x;                                             
       sta   0x01;                                           
       clr   0x00;                                           
       leax  2,x;                                            
       nop;                                                  
       inc   0x00;                                           
       stb   0x01;                                           
       ldd   #0x0000;    /* Set line pattern to invisible */ 
       bra   PF3ED;                                          


PF3CE: lda   ,x+;                                            
       bra   PF3DA;                                          


PF3D2: stb   0x04;                                           
       bra   draw_to_pt;                                     


PF3D6: ldd   ,x++;                                           
       stb   0x04;                                           
PF3DA: sta   $C823;                                          

draw_to_pt:
       ldd   ,x;                                             
       sta   0x01;                                           
       clr   0x00;                                           
       leax  2,x;                                            
       nop;                                                  
       inc   0x00;                                           
       stb   0x01;                                           
       ldd   #0xFF00;    /* Set line pattern to solid line */
PF3ED: sta   0x0A;                                           
       stb   0x05;                                           
       ldd   #0x0040;                                        
PF3F4: bitb  0x0D;                                           
       beq   PF3F4;                                          
       nop;                                                  
       sta   0x0A;                                           
       lda   $C823;                                          
       deca;                                                 
       bpl   PF3DA;                                          
       jmp   $check0ref;                                     


PF404: ldb   #0xFF;                                          
       bra   drawl1b;                                        
PF408: ldb   #0x7F;                                          
       bra   drawl1b;                                        

/*
 * Draw a list of vectors.  The x register contains the pointer
 * to the vector list.  The form for the vector list is a follows:
 *
 *	.byte   scale factor
 *	.byte	mode, relative y, relative x
 *	  .
 *	  .
 *	.byte	mode, relative y, relative x
 *
 * where mode means the following:
 *
 *	< 0  visible vector.
 *	= 0  invissible vector.
 *	> 0  end of list.
 *
 */
drawl1:
       ldb   ,x+;                                            

/* Same as drawl1, except scale factor is in b register */
drawl1b:
       stb   0x04;                                           
next_pt:
       ldd   1,x;            /* Load d register with endpoints */ 
       sta   0x01;                                           
       clr   0x00;                                           
       lda   ,x;             /* Get the mode for this vector */
       leax  3,x;            /* Increment pointer to next pair */
       inc   0x00;                                           
       stb   0x01;                                           
       sta   0x0A;                                           
       clr   0x05;                                           
       ldd   #0x0040;                                        
PF425: bitb  0x0D;                                           
       beq   PF425;                                          
       nop;                                                  
       sta   0x0A;                                           
       lda   ,x;                                             
       ble   next_pt;                                        
       jmp   $check0ref;                                     


/*
 * Draw a series of patterned vectors.  The x register points to
 * the list of endpoints, and the list has the following format:
 *
 *	relative y, relative x
 *
 * dwp_with_count() uses the value in the a register to determine
 * how many vectors to draw (number = a + 1), while draw_with_pattern()
 * uses the value in RAM location C823 to determine this.
 */
dwp_loop:
       deca;                                                 
dwp_with_count:
       sta   $C823;                                          
draw_with_pattern:
       ldd   ,x;                                             
       sta   0x01;                                           
       clr   0x00;                                           
       leax  2,x;                                            
       inc   0x00;                                           
       stb   0x01;                                           
       lda   $C829;  /* Retrieve the line pattern */         
       ldb   #0x40; 
       sta   0x0A;                                           
       clr   0x05;                                           
       bitb  $D00D;                                          
       beq   PF45C;                                          
       clr   0x0A;                                           
       lda   $C823;                                          
       bne   dwp_loop;                                       
       rts;                                                  
PF459: lda   $C829;                                          
PF45C: sta   0x0A;                                           
       nop;                                                  
       bitb  0x0D;                                           
       beq   PF459;                                          
       lda   $C823;                                          
       clr   0x0A;                                           
       tsta;                                                 
       bne   dwp_loop;                                       
       jmp   $check0ref;                                     

/*
 * Draw a list of vectors, pointed to by the x register.
 * The scale factor is not changed, and whatever the current
 * value is is used.  The list is organized as follows:
 *
 *	.byte	mode, relative y, relative x;
 *
 * where mode has the following meaning:
 *
 *	< 0  use mode value in 0xC829 ( 0 = invis; 0xFF is visible).
 *	= 0  invisible vector.
 *	= 1  end of list, so return.
 *	> 1  visible vector.
 *
 */
drawl2:
       lda   $C824;                                          
       pshs  a;                                              
       clr   $C824;    /* Temporarily clear check0ref() enable flag */
PF476: lda   ,x+;      /* Grab the drawing mode desired */   
       bpl   move_or_draw;                                   
       bsr   draw_with_pattern;                              
       bra   PF476;                                          
move_or_draw:
       bne   draw_or_end;                                    
       jsr   $move_to_pt;                                    
       bra   PF476;                                          
draw_or_end:
       deca;                                                 
       beq   end_drawl2;                                     
       jsr   $draw_to_pt;                                    
       bra   PF476;                                          
end_drawl2:
       puls  a;                                              
       sta   $C824;   /* Restore the check0ref() enable flag */
       jmp   $check0ref;                                     


/*
 * This is the routine which does the actual printing of a string
 * onto the display.  The u register points to the start of the
 * string.  The end of the string is designated by the 0x80 byte.
 * The string is displayed by drawing 6 horizontal rows of dots.
 * The first row is drawn for each character, then the second, etc.
 * The character generation table is located at 0xF9D4 + 0x20.
 * NOTE: only characters 0x20 - 0x6F are defined, and lower case
 *       characters a-o produce special icons.
 */
display_string:
       stu   $C82C;          /* Save pointer to start of string */
       ldx   #0xF9D4;        /* Actual character table is at F9F4 */
       ldd   #0x1883;                                        
       clr   0x01;                                           
       sta   0x0B;                                           
       ldx   #0xF9D4;                                        
PF4A5: stb   0x00;                                           
       dec   0x00;                                           
       ldd   #0x8081;                                        
       nop;                                                  
       inc   0x00;                                           
       stb   0x00;                                           
       sta   0x00;                                           
       tst   $C800;                                          
       inc   0x00;                                           
       lda   $C82B;          /* Set the width */             
       sta   0x01;                                           
       ldd   #0x0100;                                        
       ldu   $C82C;          /* Set u to point to 1st char */
       sta   0x00;                                           
       bra   PF4CB;                                          


PF4C7: lda   a,x;                                            
       sta   0x0A;                                           
PF4CB: lda   ,u+;                                            
       bpl   PF4C7;          /* Display next row of pixels */
       lda   #0x81;                                          
       sta   0x00;                                           
       neg   0x01;                                           
       lda   #0x01;                                          
       sta   0x00;                                           
       cmpx  #0xFBB4;        /* If we have not reached the end of the char */
       beq   PF50A;          /* table, then proceed to next row of pixels. */
       leax  0x50,x;                                           
       tfr   u,d;                                            
       subd  $C82C;          /* Point u back to the 1st character */
       subb  #0x02;                                          
       aslb;                                                 
       brn   PF4EB;                                          
PF4EB: lda   #0x81;          /* Timing loop */               
       nop;                                                  
       decb;                                                 
       bne   PF4EB;                                          
       sta   0x00;                                           
       ldb   $C82A;          /* Grab the height */           
       stb   0x01;                                           
       dec   0x00;                                           
       ldd   #0x8101;                                        
       nop;                                                  
       sta   0x00;                                           
       clr   0x01;                                           
       stb   0x00;                                           
       sta   0x00;                                           
       ldb   #0x03;                                          
       bra   PF4A5;          /* Repeat, using next row pixel patterns */
PF50A: lda   #0x98;                                          
       sta   0x0B;           /* Done with this string */     
       jmp   $reset0ref;                                     


/*
 * Generate a random number, and place it into the a register.
 * This uses a different seed (contained in register b) than
 * get_random_a().
 */
get_random_a2:
       pshs  b,x;                                            
       ldb   #0x02;                                          
       bra   ran_start;                                      

/*
 * Generate a random number, and place it into the a register.
 */
get_random_a:
       pshs  b,x;                                            
       clrb;                                                 
ran_start:
       ldx   $C87B;                                          
ran_loop:
       lda   1,x;                                            
       rola;                                                 
       rola;                                                 
       rola;                                                 
       rola;                                                 
       eora  2,x;                                            
       rora;                                                 
       rol   ,x;                                             
       rol   1,x;                                            
       rol   2,x;                                            
       decb;                                                 
       bpl   ran_loop;                                       
       lda   ,x;                                             
       puls  b,x,pc;                                         

/* Clear the block of memory C83F - C84C, then set C845 = 0x3F */
init_music_buf:
       ldb   #0x0D;                                          
       ldx   #0xC83F;                                        
       bsr   clear_blockxb;                                    
       lda   #0x3F;
       sta   6,x;                                            
       rts;                                                  

/*
 * Clear a block of memory.  The x register points to the
 * start of the memory block to be cleared, while the b
 * register specifies the number of bytes to be cleared.
 * The a register is altered.
 */
clear_blockxb:
       clra;                                                 
       bra   clear_block;                                    

clear_C8_ram:
       ldx   #0xC800;                                        
       ldd   #0x00FF;                                        

clear_block:
       clr   d,x;                                            
       subd  #0x0001;                                        
       bpl   PF548;                                          
       rts;                                                  

/*
 * Set the block of memory pointed to by the x register to 0x80.
 * The number of memory locations to be set is specified by the
 * b register + 1.
 */
clear_block_to_0x80:
       lda   #0x80;                                          
PF552: sta   b,x;                                            
       decb;                                                 
       bne   PF552;                                          
       sta   ,x;                                             
       rts;                                                  


/*
 * Decrement the specified counters
 */
decrement_counters_C82E_C830:
       ldb   #0x02;                                          
       bra   PF560;                                          
decrement_counters_C82E_C833:
       ldb   #0x05;                                          
PF560: ldx   #0xC82E;                                        
PF563: tst   b,x;                                            
       beq   PF569;                                          
       dec   b,x;                                            
PF569: decb;                                                 
       bpl   PF563;                                          
       rts;                                                  


/* Delay until the b register < 0 */
delay_b_3:
       ldb   #0x03;                                          
       bra   start_b_delay;                                  
delay_b_2:
       ldb   #0x02;                                          
       bra   start_b_delay;                                  
delay_b_1:
       ldb   #0x01;                                          
       bra   start_b_delay;                                  
delay_b_0:
       clrb;                                                 
start_b_delay:
       decb;                                                 
       bpl   start_b_delay;                                  
       rts;                                                  


/*
 * On entry, the a register equals the bits number for which
 * a mask is desired.  On exit, the a register equals the
 * requested bit mask. For example:
 *
 *	Entry		Exit
 *	-----		----
 *	  0		0x01
 *	  1		0x02
 *	 etc		etc
 */
get_bit_mask:
       ldx   #bit_masks;                                     
       lda   a,x;                                            
       rts;                                                  


/*
 * If a is negative, then negate it and check to see if the
 * overflow bit is set; if it is, then decrement a.  Repeat for
 * the b register.  ( Overflow is set only if the # = 0x80).
 */
check_ab_for_overflow:
       tsta;                                                 
       bpl   PF58B;                                          
       nega;                                                 
       bvc   PF58B;                                          
       deca;                                                 
PF58B: tstb;                                                 
       bpl   PF592;                                          
       negb;                                                 
       bvc   PF592;                                          
       decb;                                                 
PF592: rts;                                                  


PF593: pshs  x;                                              
       std   0x34;                                           
       rolb;                                                 
       ldb   #0x00;                                          
       rolb;                                                 
       rola;                                                 
       rolb;                                                 
       aslb;                                                 
       stb   0x36;                                           
       ldd   0x34;                                           
       bsr   check_ab_for_overflow;                             
       sta   0x34;                                           
       cmpb  0x34;                                           
       bls   PF5B2;                                          
       inc   0x36;                                           
       exg   a,b;                                            
       bra   PF5B2;                                          
PF5B0: lsra;                                                 
       lsrb;                                                 
PF5B2: cmpa  #0x09;                                          
       bhi   PF5B0;                                          
       std   0x34;                                           
       ldb   0x36;                                           
       ldx   #0xFC24;                                        
       ldb   b,x;                                            
       ldx   #0xFC2C;                                        
       lda   a,x;                                            
       adda  0x35;                                           
       adda  #0x0A;                                          
       bitb  #0x01;                                          
       bne   PF5D0;                                          
       addb  a,x;                                            
       bra   PF5D3;                                          
PF5D0: decb;                                                 
       subb  a,x;                                            
PF5D3: stb   0x36;                                           
       lda   0x36;                                           
       puls  x,pc;                                           


/*
 * get_2nd_index_pair() and get_1st_index_pair() are used
 * by the rotation algorithm.  They expect the rotation
 * value to be specified in the 'a' register.  Upon exit,
 * the rotation index pair is returned in the 'd' register.
 */
get_2nd_index_pair:
       adda  #0x10;  
get_1st_index_pair:
       ldx   #0xFC6D;
       clrb;         
       bita  #0x20; 
       beq   PF5E5;
       ldb   #0x80;  
PF5E5: anda  #0x1F;
       cmpa  #0x10;
       bne   PF5EC;
       incb;      
PF5EC: lda   a,x;
       rts;     


/*
 * This routine is called at at the beginning of the
 * rotation transformation process.  It is responsible
 * for generating the 2 rotation index pairs.  The
 * first rotation pair is saved in C837-C838, and the
 * second pair is aved in C839-C83A.  This routine 
 * expects the rotation value to be stored in C836.
 */
get_rotation_index_pairs:
       pshs  x;                                              
       lda   0x36;           /* get rotation value */        
       bsr   get_1st_index_pair;                             
       std   0x37;           /* Save first rotation index pair */
       lda   0x36;           /* get rotation value */        
       bsr   get_2nd_index_pair;                             
       std   0x39;           /* Save second rotation index pair */
       puls  x,pc;                                           



/*
 * This routine is responsible for rotating a single 
 * coordinate.  At entry, the 'b' register must contain
 * the rotation value, and the 'a' register must contain
 * the coordinate.  The value is returned in the 'd' register.
 */
PF5FF: subb  #0x10;                                          
rotate_1_coordinate:
       stb   0x36;           /* Save rotation value */       
       sta   0x3B;           /* Save the coordinate */       
       bsr   get_rotation_index_pairs;                       
       bsr   xform_1a;                                       
       nega;                                                 
       pshs  a;                                              
       bsr   xform_2a;                                       
       puls  b,pc;                                           


/*
 * This routine rotates a vector list of length 'n', where
 * 'n' is specified by the 'b' register.  The 'a' register
 * contains the rotation value; the 'x' register contains
 * a pointer to the vector list to be transformed; and
 * the 'u' register containss a pointer to a buffer into
 * which the transformed points are to be saved.
 * The vector list is composed of only y,x pairs.
 */
rotate_vector_list2:
       sta   $C836;          /* Save the rotation value */   
       stb   $C823;          /* Save the byte counter */     
       pshs  dp;                                             
       jsr   $dptoC8;                                        
       bsr   get_rotation_index_pairs;                       
       bra   rotate_a_pt:    /* Process the vector list */   


/*
 * This procedure is responible for rotating a vector list
 * having the following format:
 *
 *       mode, relative y, relative x,
 *                .
 *                .
 *       1
 *
 * At entry, the 'a' register must contain the rotation value,
 * the 'x' register must point to the vector list to be
 * transformed, and the 'u' register must point to a buffer
 * which is to be used to store the transformed coordinates.
 */
rotate_vector_list1:
       sta   $C836;          /* Save rotation value */       
       pshs  dp;                                             
       jsr   $dptoC8;                                        
       sta   0x23;                                           
       bsr   get_rotation_index_pairs;                       
process_next_point:
       lda   ,x+;            /* Copy the mode, and process the */
       sta   ,u+;            /* next point if mode <= 0.       */
       ble   rotate_a_pt:                                    
       clr   0x23;                                           
       puls  dp,pc;                                          


dec_vl_counter:
       dec   0x23;           /* Decrement the vector list counter */
rotate_a_pt:
       lda   ,x+;            /* Load 'a' reg with the y coord */
       bsr   xform_2;                                        
       sta   ,u;                                             
       lda   ,x;             /* Load 'a' reg with the x coord */
       bsr   xform_1;                                        
       adda  ,u;             /* Save transformed y coord */  
       sta   ,u+;                                            
       lda   -1,x;           /* Load 'a' reg with the y coord */
       bsr   xform_1;                                        
       sta   ,u;                                             
       lda   ,x+;            /* Load 'a' reg with the x coord */
       bsr   xform_2;                                        
       suba  ,u;                                             
       sta   ,u+;            /* Save transformed x coord */  
       lda   0x23;                                           
       bmi   process_next_point;                             
       bne   dec_vl_counter;                                 
       puls  dp,pc;                                          


/*
 * The following routines all do a transformation of a
 * point.  xform_1() and xform_2() expect the coordinate
 * to be specified in the 'a' register.  xform_1a() and
 * xform_2a() expect the coordinate to already be stored
 * in C83B.
 */
xform_1:
       sta   0x3B;                                           
xform_1a:
       ldd   0x37;           /* Use table index values 1 */ 
       bra   PF665;                                          
xform_2:
       sta   0x3B;                                           
xform_2a:
       ldd   0x39;           /* Use table index values 2 */  
PF665: stb   0x3C;                                           
       bitb  #0x01;                                          
       beq   PF66F;                                          
       lda   0x3B;                                           
       bra   PF679;                                          
PF66F: ldb   0x3B;                                           
       bpl   PF676;                                          
       com   0x3C;                                           
       negb;                                                 
PF676: mul;                                                  
       adca  #0x00;                                          
PF679: ldb   0x3C;                                           
       bpl   PF67E;                                          
       nega;                                                 
PF67E: rts;                                                  


/*
 * Move a block of memory, starting at hi memory, and
 * working down to low memory.  The source address is
 * specified in the u register, and the destination is
 * specified in the x register.  The number of bytes
 * moved is equal to the value in the a register + 1.
 * The maximum value which can be specified in the a
 * register is 0x80.
 */
move_block:
       ldb   a,u;                                            
       stb   a,x;                                            
       deca;                                                 
       bpl   move_block;                                     
rtn2:  rts;                                                  

/*
 * This should be called before you attempt to make a sound.
 * It should be called every refresh cycle, just before you
 * call waitrecal().  If you want to start a new sound, then
 * you must set C856 to 1, and point the u register to the
 * sound block.  If no sound is in progress (C856 = 0), then
 * it returns immediately.  While a sound is in progress, C856
 * will be set to 0x80. 
 * This routine processes a single note at a time, and calculates
 * the amplitude and course/fine tuning values for the 3 sound
 * channels.  The values calculated are stored in the array located
 * at C83F-C84C; C83F = reg D, C840 = regC, C841 = regB, etc....
 * Dp must be set to C8.
 */
init_sound:
       lda   0x56;                /* See if a sound is in progress */
       bmi   continue_sound;      /* or if we should start a new one */
       beq   rtn2;                                           
init_sound2:
       ldx   #music_stuff3;                                  
       stx   0x4D;                                           
       lda   #0x80;                                          
       sta   0x56;           /* Flag that init_sound was called */
       ldd   ,u++;                                           
       std   0x4F;           /* Save 1st param in music block */
       ldd   ,u++;                                           
       std   0x51;           /* Save 2nd param in music block */
       stu   0x53;           /* Save ptr to block of music */
       jsr   $init_music_buf;                      
       ldd   #0x1F1F;                                        
       std   0x5F;                                           
       ldd   #0x0000;                                        
       std   0x63;                                           
       std   0x65;                                           
       sta   0x55;                                           
       bra   PF6EC;                                          
continue_sound:
       ldu   #0xC85E;     /* Continue current sound */
       ldb   #0x02;                                          
PF6B8: lda   b,u;                                            
       cmpa  #0x1F;                                          
       beq   PF6C0;                                          
       inc   b,u;                                            
PF6C0: decb;                                                 
       bpl   PF6B8;                                          
       ldx   0x51;                                           
       ldu   #0xC858;                                        
       lda   #0x07;                                          
PF6CA: inc   ,u;                                             
       cmpa  ,u;                                             
       bge   PF6D2;                                          
       clr   ,u;                                             
PF6D2: ldb   ,u+;                                            
       andb  #0x07;                                          
       ldb   b,x;                                            
       stb   ,u+;                                            
       inca;                                                 
       cmpa  #0x09;                                          
       bls   PF6CA;                                          
       dec   0x57;                                           
       bne   PF74E;                                          
music_delay:
       lda   0x55;           /* This does something like changing */
       deca;                 /* octives! I really am quessing */
       bpl   PF6EA;                                          
       lda   #0x02;                                          
PF6EA: sta   0x55;                                           
PF6EC: ldb   [C853];              /* Load the next music note */
       ldu   #0xC85E;                                        
       clr   a,u;                                            
       bitb  #0x40; /* "@" */                                
       beq   PF712;                                          
       ldx   #music_stuff1;                                  
       lda   a,x;                                            
       anda  0x45;                                           
       sta   0x45;                                           
       lda   0x55;                                           
       adda  #0x03;                                          
       lda   a,x;                                            
       ora   0x45;                                           
       sta   0x45;                                           
       andb  #0x1F;                                          
       stb   0x46;                                           
       bra   PF735;                                          
PF712: ldx   #music_stuff2;                                  
       lda   a,x;                                            
       anda  0x45;                                           
       sta   0x45;                                           
       lda   0x55;                                           
       adda  #0x03;                                          
       lda   a,x;                                            
       ora   0x45;                                           
       sta   0x45;                                           
       lda   0x55;                                           
       asla;                                                 
       adda  #0x03;                                          
       leau  a,u;                                            
       andb  #0x3F; /* "?" */                                
       aslb;                                                 
       ldx   0x4D;                                           
       ldd   b,x;                                            
       std   ,u;                                             
PF735: ldx   0x53;           /* Grab next note, & update ptr */
       ldb   ,x+;                                            
       stx   0x53;                                           
       tstb;                                                 
       bmi   music_delay;    /* Negative note = ?? */     
       ldb   ,x+;            /* Grab the duration */         
       bpl   PF748;                                          
       jsr   $init_music_buf;                      
       clr   0x56;           /* All done when duration = 0x80 */ 
       rts;                                                  
PF748: stx   0x53;                                           
       andb  #0x3F; /* "?" */                                
       stb   0x57;                                           
PF74E: ldy   0x4F;                                           
       ldu   #0xC85E;                                        
       ldx   #0xC842;                                        
       lda   #0x02;                                          
PF759: ldb   ,u+;                                            
       bitb  #0x01;                                          
       beq   PF766;                                          
       lsrb;                                                 
       ldb   b,y;                                            
       andb  #0x0F;                                          
       bra   PF76D;                                          
PF766: lsrb;                                                 
       ldb   b,y;                                            
       lsrb;                                                 
       lsrb;                                                 
       lsrb;                                                 
       lsrb;                                                 
PF76D: stb   a,x;                                            
       deca;                                                 
       bpl   PF759;                                          
       ldu   #0xC867;                                        
       ldx   #0xC847;                                        
PF778: ldd   ,--u;                                           
       tst   -8,u;                                           
       bpl   PF788;                                          
       neg   -8,u;                                           
       subb  -8,u;                                           
       sbca  #0x00;                                          
       neg   -8,u;                                           
       bra   PF78C;                                          
PF788: addb  -8,u;                                           
       adca  #0x00;                                          
PF78C: std   ,x++;                                           
       cmpx  #0xC84D;        /* Temporarily stop when we have filled */
       bne   PF778;          /* the music buffer completely.         */
PF793: rts;                                                  


player_string:
       .byte 0x20;  /* rel y = 32  (for score) */
       .byte 0xC0;  /* rel x = -64 (for score) */
       .byte 0x40;  /* rel y = 64  (player string) */
       .byte 0xC0;  /* rel x = -64 (player string) */
       .byte "PLAYER",0x80;

game_string:
       .byte 0xE0;  /* rel y  = -32 (for game #) */
       .byte 0xC0;  /* rel x = -64  (for game #) */
       .byte 0x01;  /* rel y = 1    (for game string) */
       .byte 0xC0;  /* rel x = -64  (for game string) */
       .byte " GAME",0x80;

/*
 * Ask the player for the number of players, and the game
 * desired to play.  The maximum number of players allowed
 * should be specified in the a register, and the maximum
 * game number should be specified in the b register.  If
 * either a or b is zero, then that question will not be
 * asked.  The number of players selected is returned in
 * C879, and the game number selected is returned in C87A.
 */
get_players_game:
       std   $C84F;                                          
       tsta;                                                 
       beq   PF7B1;                                          
       lda   #0x01;                                          
PF7B1: tstb;                                                 
       beq   PF7B6;                                          
       ldb   #0x01;                                          
PF7B6: std   $C879;                                          
       jsr   $dptoC8;                                        
       ldd   #0xF850;                                        
       std   0x2A;           /* Set string height & width */ 
       sta   0x3C;                                           
       bra   handle_buttons;                                 


/*
 * This routine allows the user a given amount of time to modiy
 * the game # and number of players.  Each time a button is pressed,
 * the timer will be reset.  Control will be relinquished when the
 * timer finally expires.
 */
button_handler_loop:
       jsr   $waitrecal;                                     
       clra;                                                 
       jsr   $read_switches;  /* Read switches, & decrement loop counter */
       jsr   $decrement_counters_C82E_C830;                               

       jsr   $intensity_to_7F;                               
       lda   $C879;                                          
       ldy   #player_string;                                   
       bsr   display_option_string; /* Ask user for the number of players */ 
       lda   $C87A;                                          
       ldy   #game_string;                                   
       bsr   display_option_string; /* Ask user for the game number */       

       jsr   $dptoC8;                                        
       lda   0x3C;                                           
       beq   check_loop_counter;                             
       lda   0x0F;                                           
       bne   handle_buttons;                                 
       clr   0x3C;           /* Reset loop counter when button pressed */

check_loop_counter:
       lda   0x2F;           /* Check counter in C82F and exit */
       beq   PF793;          /* when it reaches zero.          */
       lda   0x2E;                                           
       bne   button_handler_loop;                            
       lda   0x15;           /* Start the game, if switch 4 has */
       bne   PF793;          /* been presses.                   */
       lda   0x12;                                           
       beq   check_button2;  /* Increment the number of players */
       lda   0x79;           /* if switch 1 has been pressed. Be*/
       beq   check_button2;  /* sure to handle wrap.            */
       inca;                                                 
       cmpa  0x4F;                                           
       bls   PF80C;                                          
       lda   #0x01;                                          
PF80C: sta   0x79;                                           
       bra   handle_buttons;                                 
check_button2:
       lda   0x7A;                /* If multiple games can be selected, */
       beq   button_handler_loop; /* then increment the game number if  */
       ldb   0x13;                /* switch 2 has been pressed.         */
       beq   check_button3;                                  
       inca;                                                 
       cmpa  0x50;                                           
       bls   PF82A;                                          
       lda   #0x01;                                          
       bra   PF82A;                                          
check_button3:
       ldb   0x14;                /* Decrement the game number, if */
       beq   button_handler_loop; /* switch 3 has been pressed.    */
       deca;                                                 
       bne   PF82A;                                          
       lda   0x50;                                           
PF82A: sta   0x7A;                                           

handle_buttons:
       lda   #0xF3;               /* Reset the loop counters.     */
       sta   0x2F;                                           
       coma;                                                 
       sta   0x2E;                                           
       bra   button_handler_loop;  /* Go back to start of loop.    */


/*
 * Display the player or game string, and the current
 * value for that option.  The a register must contain
 * the value of the option, and the y register must
 * point to a block of the following form:
 *
 *	rel y and rel x for value string
 *	rel y and rel x for player/game string
 *	player/game string
 *	0x80
 */
display_option_string:
       ldx   #0xC85E;        /* C85E is a temp work variable */
       pshs  a;                                              
       bsr   set_dft_score;                                  
       lda   ,s+;                                            
       beq   dos_rtn;                                        
       bsr   convert_a_to_bcd_and_add;                               
       tfr   x,u;                                            
       ldd   ,y++;                                           
       jsr   $print_at_d;               
       tfr   y,u;                                            
       jsr   $print_with_dft_hw:                             
dos_rtn:
       rts;                                                  


/*
 * Initialize the score string, pointed to by the x register,
 * to the string "     0",0x80 .
 */
set_dft_score:
       ldd   #0x2020;                                        
       std   ,x;                                             
       std   2,x;                                            
       sta   4,x;                                            
       ldd   #0x3080;                                        
       std   5,x;                                            
       rts;                                                  


/*
 * convert_a_to_bcd_and_add() takes the value in the a register, and
 * converts it to a string of BCD characters, which are then
 * added to the BCD string in the buffer pointed to by the x register.
 */
convert_a_to_bcd_and_add:
       ldu   #0x0000;                                        
PF861: cmpa  #0x63;    /* 99 */                                
       bls   PF86D;                                          
       suba  #0x64;    /* 100 */                                
       leau  0x0100,u;                                         
       bra   PF861;                                          
PF86D: cmpa  #0x09;    /*  9  */                                
       bls   PF878;                                          
       suba  #0x0A;    /* 10  */                                
       leau  0x10,u;                                           
       bra   PF86D;                                          
PF878: leau  a,u;                                            
       tfr   u,d;                                            

/* Add the BCD value in d register to ascii string stored in x reg */
add_d_to_x_in_bcd:
       pshs  a;                                              
       pshs  b;                                              
       ldb   #0x05;                                          
PF882: clra;                                                 
       cmpb  #0x01;                                          
       bls   PF897;                                          
       bitb  #0x01;                                          
       beq   PF88F;                                          
       lda   ,s;                                             
       bra   PF895;                                          
PF88F: lda   ,s+;                                            
       lsra;                                                 
       lsra;                                                 
       lsra;                                                 
       lsra;                                                 
PF895: anda  #0x0F;                                          
PF897: adda  $C823;                                          
       clr   $C823;                                          
       adda  b,x;                                            
       cmpa  #0x2F; /* "/" */                                
       bgt   PF8A5;                                          
       adda  #0x10;                                          
PF8A5: cmpa  #0x39; /* "9" */                                
       bls   PF8AE;                                          
       suba  #0x0A;                                          
       inc   $C823;                                          
PF8AE: sta   b,x;            /* Strip leading 0's */         
       decb;                                                 
       bpl   PF882;                                          
       clr   $C823;                                          
       clrb;                                                 
PF8B7: lda   b,x;                                            
       cmpa  #0x30;          /* Replace leading 0 with */    
       bne   PF8C6;          /* a space.               */    
       lda   #0x20;
       sta   b,x;                                            
       incb;                                                 
       cmpb  #0x05;                                          
       blt   PF8B7;                                          
PF8C6: rts;                                                  


/*
 * This procedure compares the two score strings pointed to by the
 * x and u registers.  It returns one of the following values,
 * depending upon which score was higher:
 *
 *	1) The scores are the same: a = 0;
 *	2) x score > u score:       a = 1;
 *     	3) x score <= u score:      a = 2;
 */
compare_scores:
       pshs  x,u;                                            
       clra;                                                 
PF8CA: ldb   ,x+;                                            
       bmi   PF8D6;                                          
       cmpb  ,u+;                                            
       beq   PF8CA;                                          
       bhi   PF8D5;                                          
       inca;                                                 
PF8D5: inca;                                                 
PF8D6: puls  x,u,pc;                                         


/*
 * This procedure compares the two score string arrays pointed to
 * by the u and x registers.  The u register points to the current
 * hi score.  If the score pointed to by the x register is greater
 * than the current hi score, then it will be copies into the 
 * array pointed to by the u register.
 */
check_4_new_hi_score:
       bsr   compare_scores;                                 
       cmpa  #0x01;                                          
       bne   PF8E4;                                          
PF8DE: lda   ,x+;                                            
       sta   ,u+;                                            
       bpl   PF8DE;                                          
PF8E4: rts;                                                  


/*
 * This routine modifies the position of the target,
 * before it checks to see if a bullet has hit it.
 * It takes the position of the target, in 'y', and
 * adds 0,u to the y position, and 1,u to the x position.
 * At entry, 'y' should contain the targets (y,x) position,
 * 'x' should contain the bullets (y,x) position, and 'd'
 * should contain the (height/2,width/2) of the target.
 * 'u' points to the modification values.
 */
PF8E5: pshs  y;                                              
       pshs  a,b,x,y;                                        
       ldd   4,s;                                            
       adda  ,u;                                             
       addb  1,u;                                            
PF8EF: std   4,s;                                            
       bra   check_bullet_for_hit2;                          


/*
 * This routine modifies the position of the target,
 * before it checks to see if a bullet has hit it.
 * It takes the position of the target, in 'y', and
 * adds to it the value in the 'u' register.
 * At entry, 'y' should contain the targets (y,x) position,
 * 'x' should contain the bullets (y,x) position, and 'd'
 * should contain the (height/2,width/2) of the target.
 * 'u' contains the modification values.
 */
PF8F3: pshs  y;                                              
       pshs  a,b,x,y;                                        
       tfr   u,d;                                            
       adda  4,s;                                            
       addb  5,s;                                            
       bra   PF8EF;                                          

/*
 * This routine checks to see if a bullet has hit a
 * target.  If the bullet has hit the target, then
 * the carry bit will be set; else, the carry bit
 * will be cleared.  A hit is checked for in the
 * following fashion:
 *
 *    if (target y - height/2) <= bullet y <= (target y + height/2)
 *                              and
 *       (target x - width/2)  <= bullet x <= (target x + width/2)
 *
 *    then the bullet hit, else it missed.
 *
 * At entry, 'x' must contain the bullet position, 'y' must contain
 * the target position, and 'd' must contain the (height/2,width/2)
 * pair.
 */
check_bullet_for_hit:
       pshs  y;
       pshs  a,b,x,y;
check_bullet_for_hit2:
       tfr   sp,x;                                           
       clrb;                 /* Start by checking the y coordinate */
check_bullet_loop:
       abx;                                                  
       lda   4,x;            /* Add target y to height/2 (if b = 0) */  
       adda  ,x;             /* Add target x to width/2 (if b = 1)  */
       bvc   check_bullet_pt1;                                 
       lda   #0x7F;          /* Only goto edge of screen */  
check_bullet_pt1:
       cmpa  2,x;            /* See if bullet is close enough */
       blt   flag_a_miss;                                    
       lda   4,x;                                            
       suba  ,x;                                             
       bvc   check_bullet_pt2;                                
       lda   #0x80;          /* Only goto edge of screen */  
check_bullet_pt2:
       cmpa  2,x;                                            
       bgt   flag_a_miss;                                    
       incb;                 /* go back and check the x coordinate */
       cmpb  #0x02;                                          
       blo   check_bullet_loop;                              
       orcc  #0x01;          /* Flag a hit; set carry bit */ 
       bra   PF92A;                                          
flag_a_miss:
       andcc #0xFE;          /* Flag a miss; clear carry bit */
PF92A: puls  a,b,x,y;                                        
       puls  y,pc;                                           


PF92E: lda   0x67;                                           
       bpl   PF95B;                                          
       anda  #0x7F;                                          
       sta   0x67;                                           
       ldx   #0xC858;                                        
       lda   #0x04;                                          
       jsr   $PF683;                                         
       lsrb;                                                 
       lsrb;                                                 
       lsrb;                                                 
       orb   0x58;                                           
       andb  #0x07;                                          
       stb   0x54;                                           
       ldb   0x58;                                           
       andb  #0x38; /* "8" */                                
       stb   0x53;                                           
       ldb   0x58;                                           
       andb  #0x07;                                          
       stb   0x5D;                                           
       ldb   #0x02;                                          
       stb   0x5C;                                           
       lda   #0x7F;                                          
       bra   PF968;                                          
PF95B: lda   0x77;                                           
       beq   PF9C9;                                          
       suba  0x5B;                                           
       bpl   PF968;                                          
       clrb;                                                 
       stb   0x77;                                           
       bra   PF9CA;                                          
PF968: sta   0x77;                                           
       lsra;                                                 
       lsra;                                                 
       ldb   0x53;                                           
       beq   PF97D;                                          
       sta   0x46;                                           
       ldb   0x59;                                           
       bmi   PF97B;                                          
       beq   PF97D;                                          
       tfr   a,b;                                            
       coma;                                                 
PF97B: stb   0x46;                                           
PF97D: lsra;                                                 
       cmpa  #0x07;                                          
       bls   PF987;                                          
       cmpa  #0x0F;                                          
       beq   PF987;                                          
       inca;                                                 
PF987: ldb   0x5A;                                           
       bmi   PF991;                                          
       beq   PF98F;                                          
       eora  #0x0F;                                          
PF98F: tfr   a,b;                                            
PF991: bsr   PF9CA;                                          
       ldb   0x5D;                                           
       beq   PF9C2;                                          
PF997: lda   0x5C;                                           
       deca;                                                 
       bpl   PF99E;                                          
       lda   #0x02;                                          
PF99E: sta   0x5C;                                           
       jsr   $get_bit_mask;                                  
       bita  0x5D;                                           
       beq   PF997;                                          
       ldb   0x5C;                                           
       aslb;                                                 
       negb;                                                 
       ldx   #0xC84B;                                        
       leax  b,x;                                            
       jsr   $PF517;                                         
       anda  #0x0F;                                          
       cmpa  #0x05;                                          
       bhi   PF9BC;                                          
       asla;                                                 
       adda  #0x05;                                          
PF9BC: sta   ,x;                                             
       lda   0x7E;                                           
       sta   1,x;                                            
PF9C2: lda   0x58;                                           
       coma;                                                 
       anda  0x45;                                           
       sta   0x45;                                           
PF9C9: rts;                                                  
PF9CA: lda   0x54;                                           
       ldx   #0xC845;                                        
PF9CF: tsta;                                                 
       beq   PF9DB;                                          
       leax  -1,x;                                           
PF9D4: lsra;                                                 
       bhs   PF9CF;                                          
       stb   ,x;                                             
       bra   PF9CF;                                          
PF9DB: rts;                                                  


bit_masks:
       .byte 0x01;           
       .byte 0x02;           
       .byte 0x04;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x20;
       .byte 0x40;
       .byte 0x80;           

music_stuff1:
       .byte 0xF7;           
       .byte 0xEF;           
       .byte 0xDF;           
       .byte 0x01;           
       .byte 0x02;           
       .byte 0x04;           

music_stuff2:
       .byte 0xFE;           
       .byte 0xFD;           
       .byte 0xFB;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x20;

SF9F0: .byte 0x7F;           
       .byte 0x7F;           
       .byte 0x80;           
       .byte 0x80;           

/* This is the start of the character generation table used by
 * the string printing routine.  The table starts at F9F4,  
 * and goes for the next 480 bytes.
 */
character_table:
       .byte 0x00; 
       .byte 0x20;
       .byte 0x50;
       .byte 0x50;
       .byte 0x20;
       .byte 0xC8;
       .byte 0x20;
       .byte 0x10; 
       .byte 0x10; 
       .byte 0x40; 

       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x08; 
       .byte 0x30; 
       .byte 0x20; 
       .byte 0x70; 
       .byte 0x70; 

       .byte 0x10; 
       .byte 0xF8; 
       .byte 0x30; 
       .byte 0xF8; 
       .byte 0x70; 
       .byte 0x70; 
       .byte 0x00; 
       .byte 0x60; 
       .byte 0x00; 
       .byte 0x00; 

       .byte 0x00; 
       .byte 0x70; 
       .byte 0x70; 
       .byte 0x20; 
       .byte 0xF0; 
       .byte 0x70; 
       .byte 0xF0; 
       .byte 0xF8; 
       .byte 0xF8; 
       .byte 0x78; 

       .byte 0x88; 
       .byte 0x70; 
       .byte 0x08; 
       .byte 0x88; 
       .byte 0x80; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0xF8; 
       .byte 0xF0; 
       .byte 0x70; 

       .byte 0xF0; 
       .byte 0x70; 
       .byte 0xF8; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0xF8; 
       .byte 0x70; 

       .byte 0x80; 
       .byte 0x70; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 

       .byte 0x00; 
       .byte 0x38; 
       .byte 0x10; 
       .byte 0x20; 
       .byte 0x44; 
       .byte 0x44; 
       .byte 0x00; 
       .byte 0xFE; 
       .byte 0xFF; 
       .byte 0xFE; 

       .byte 0x00; 
       .byte 0x70; 
       .byte 0x50; 
       .byte 0x50; 
       .byte 0x78; 
       .byte 0xC8; 
       .byte 0x50; 
       .byte 0x20; 
       .byte 0x20; 
       .byte 0x20; 

       .byte 0xA8; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x08; 
       .byte 0x48; 
       .byte 0x60; 
       .byte 0x88; 
       .byte 0x88; 

       .byte 0x30; 
       .byte 0x80; 
       .byte 0x40; 
       .byte 0x08; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x60; 
       .byte 0x60; 
       .byte 0x10; 
       .byte 0x00; 

       .byte 0x40; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x50; 
       .byte 0x48; 
       .byte 0x88; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x80; 
       .byte 0x80; 

       .byte 0x88; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0x90; 
       .byte 0x80; 
       .byte 0xD8; 
       .byte 0xC8; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 

       .byte 0x88; 
       .byte 0x88; 
       .byte 0xA8; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x08; 
       .byte 0x40; 

       .byte 0x80; 
       .byte 0x08; 
       .byte 0x50; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x70; 
       .byte 0x0C; 
       .byte 0x20; 
       .byte 0x70; 
       .byte 0x70; 

       .byte 0x00; 
       .byte 0x44; 
       .byte 0x10; 
       .byte 0x70; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x6C; 
       .byte 0x82; 
       .byte 0xFF; 
       .byte 0xFE; 

       .byte 0x00; 
       .byte 0x70; 
       .byte 0x50; 
       .byte 0xF8; 
       .byte 0xA0; 
       .byte 0x10; 
       .byte 0x50; 
       .byte 0x40; 
       .byte 0x40; 
       .byte 0x10; 

       .byte 0x70; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x10; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0x08; 

       .byte 0x50; 
       .byte 0xF0; 
       .byte 0x80; 
       .byte 0x10; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x60; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x78; 

       .byte 0x20; 
       .byte 0x08; 
       .byte 0xA8; 
       .byte 0x88; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x80; 
       .byte 0x80; 

       .byte 0x88; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0xA0; 
       .byte 0x80; 
       .byte 0xA8; 
       .byte 0xA8; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 

       .byte 0x88; 
       .byte 0x40; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x50; 
       .byte 0x50; 
       .byte 0x10; 
       .byte 0x40; 

       .byte 0x40; 
       .byte 0x08; 
       .byte 0x88; 
       .byte 0x00; 
       .byte 0x70; 
       .byte 0xA8; 
       .byte 0x0A; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0xF8; 

       .byte 0x60; 
       .byte 0xBA; 
       .byte 0x38; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x92; 
       .byte 0x82; 
       .byte 0xFF; 
       .byte 0xFE; 

       .byte 0x00; 
       .byte 0x20; 
       .byte 0x00; 
       .byte 0x50; 
       .byte 0x70; 
       .byte 0x20; 
       .byte 0x60; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0x10; 

       .byte 0xA8; 
       .byte 0xF8; 
       .byte 0x00; 
       .byte 0x70; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0x70; 
       .byte 0x30; 

       .byte 0x90; 
       .byte 0x08; 
       .byte 0xF0; 
       .byte 0x20; 
       .byte 0x70; 
       .byte 0x78; 
       .byte 0x00; 
       .byte 0x60; 
       .byte 0x40; 
       .byte 0x00; 

       .byte 0x10; 
       .byte 0x10; 
       .byte 0xB8; 
       .byte 0x88; 
       .byte 0x70; 
       .byte 0x80; 
       .byte 0x48; 
       .byte 0xE0; 
       .byte 0xE0; 
       .byte 0x98; 

       .byte 0xF8; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0xC0; 
       .byte 0x80; 
       .byte 0xA8; 
       .byte 0x98; 
       .byte 0x88; 
       .byte 0xF0; 
       .byte 0x88; 

       .byte 0xF0; 
       .byte 0x20; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0x50; 
       .byte 0xA8; 
       .byte 0x20; 
       .byte 0x20; 
       .byte 0x20; 
       .byte 0x40; 

       .byte 0x20; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0xFE; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0xF8; 

       .byte 0xF0; 
       .byte 0xA2; 
       .byte 0x38; 
       .byte 0xF8; 
       .byte 0x82; 
       .byte 0x38; 
       .byte 0x92; 
       .byte 0x82; 
       .byte 0xFF; 
       .byte 0xFE; 

       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0xF8; 
       .byte 0x70; 
       .byte 0x40; 
       .byte 0xA8; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0x10; 

       .byte 0xA8; 
       .byte 0x20; 
       .byte 0x40; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x40; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0x80; 
       .byte 0x08; 

       .byte 0xF8; 
       .byte 0x08; 
       .byte 0x88; 
       .byte 0x40; 
       .byte 0x88; 
       .byte 0x08; 
       .byte 0x60; 
       .byte 0x60; 
       .byte 0x20; 
       .byte 0x78; 

       .byte 0x20; 
       .byte 0x20; 
       .byte 0xB0; 
       .byte 0xF8; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x80; 
       .byte 0x88; 

       .byte 0x88; 
       .byte 0x20; 
       .byte 0x08; 
       .byte 0xA0; 
       .byte 0x80; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x80; 
       .byte 0xA8; 

       .byte 0xA0; 
       .byte 0x10; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0x50; 
       .byte 0xA8; 
       .byte 0x50; 
       .byte 0x20; 
       .byte 0x40; 
       .byte 0x40; 

       .byte 0x10; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0xFE; 
       .byte 0x20; 
       .byte 0x78; 
       .byte 0xA8; 
       .byte 0x88; 
       .byte 0xF8; 

       .byte 0xF0; 
       .byte 0xBA; 
       .byte 0x7C; 
       .byte 0x20; 
       .byte 0x44; 
       .byte 0x44; 
       .byte 0x6C; 
       .byte 0x82; 
       .byte 0xFF; 
       .byte 0xFE; 

       .byte 0x00; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x50; 
       .byte 0x28; 
       .byte 0x98; 
       .byte 0x90; 
       .byte 0x00; 
       .byte 0x20; 
       .byte 0x20; 

       .byte 0x00; 
       .byte 0x20; 
       .byte 0x40; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x80; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0x80; 
       .byte 0x88; 

       .byte 0x10; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x80; 
       .byte 0x88; 
       .byte 0x10; 
       .byte 0x60; 
       .byte 0x20; 
       .byte 0x10; 
       .byte 0x00; 

       .byte 0x40; 
       .byte 0x00; 
       .byte 0x80; 
       .byte 0x88; 
       .byte 0x48; 
       .byte 0x88; 
       .byte 0x48; 
       .byte 0x80; 
       .byte 0x80; 
       .byte 0x88; 

       .byte 0x88; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0x90; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x88; 
       .byte 0x80; 
       .byte 0x90;           

       .byte 0x90; 
       .byte 0x88; 
       .byte 0x20; 
       .byte 0x88; 
       .byte 0x20; 
       .byte 0xA8; 
       .byte 0x88; 
       .byte 0x20; 
       .byte 0x80; 
       .byte 0x40; 

       .byte 0x08; 
       .byte 0x08; 
       .byte 0x00; 
       .byte 0x00; 
       .byte 0x48; 
       .byte 0x20; 
       .byte 0xF0; 
       .byte 0x70; 
       .byte 0x70; 
       .byte 0x70; 

       .byte 0x60; 
       .byte 0x44; 
       .byte 0x6C; 
       .byte 0x50; 
       .byte 0x38; 
       .byte 0x82; 
       .byte 0x00; 
       .byte 0x82; 
       .byte 0xFF; 
       .byte 0xFE; 
/* End of character generation table */

       .byte 0x00;           
       .byte 0x20; /* " " */ 
       .byte 0x00;           
       .byte 0x50; /* "P" */ 
       .byte 0xF8;           
       .byte 0x98;           
       .byte 0x68; /* "h" */ 
       .byte 0x00;           
       .byte 0x10;           
       .byte 0x40; /* "@" */ 
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x80;           
       .byte 0x00;           
       .byte 0x80;           
       .byte 0x80;           
       .byte 0x30; /* "0" */ 
       .byte 0x70; /* "p" */ 
       .byte 0xF8;           
       .byte 0x70; /* "p" */ 
       .byte 0x10;           
       .byte 0x70; /* "p" */ 
       .byte 0x70; /* "p" */ 
       .byte 0x80;           
       .byte 0x70; /* "p" */ 
       .byte 0x60; /* "`" */ 
       .byte 0x00;           
       .byte 0x40; /* "@" */ 
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x20; /* " " */ 
       .byte 0x78; /* "x" */ 
       .byte 0x88;           
       .byte 0xF0;           
       .byte 0x70; /* "p" */ 
       .byte 0xF0;           
       .byte 0xF8;           
       .byte 0x80;           
       .byte 0x78; /* "x" */ 
       .byte 0x88;           
       .byte 0x70; /* "p" */ 
       .byte 0x70; /* "p" */ 
       .byte 0x88;           
       .byte 0xF8;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0xF8;           
       .byte 0x80;           
       .byte 0x68; /* "h" */ 
       .byte 0x88;           
       .byte 0x70; /* "p" */ 
       .byte 0x20; /* " " */ 
       .byte 0x70; /* "p" */ 
       .byte 0x20; /* " " */ 
       .byte 0x50; /* "P" */ 
       .byte 0x88;           
       .byte 0x20; /* " " */ 
       .byte 0xF8;           
       .byte 0x70; /* "p" */ 
       .byte 0x08;           
       .byte 0x70; /* "p" */ 
       .byte 0x00;           
       .byte 0xF8;           
       .byte 0x00;           
       .byte 0x20; /* " " */ 
       .byte 0x60; /* "`" */ 
       .byte 0x20; /* " " */ 
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x38; /* "8" */ 
       .byte 0x82;           
       .byte 0x88;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0xFF;           
       .byte 0xFE;           
SFC24: .byte 0x00;           
       .byte 0x11;           
       .byte 0x41; /* "A" */ 
       .byte 0x30; /* "0" */ 
       .byte 0x21; /* "!" */ 
       .byte 0x10;           
       .byte 0x20; /* " " */ 
       .byte 0x31; /* "1" */ 
SFC2C: .byte 0x00;           
       .byte 0x01;           
       .byte 0x03;           
       .byte 0x06;           
       .byte 0x0A;           
       .byte 0x0F;           
       .byte 0x15;           
       .byte 0x1C;           
       .byte 0x24; /* "$" */ 
       .byte 0x2D; /* "-" */ 
       .byte 0x08;           
       .byte 0x10;           
SFC38: .byte 0x08;           
       .byte 0x10;           
       .byte 0x0B;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0D;           
       .byte 0x0A;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0E;           
       .byte 0x0B;           
       .byte 0x09;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0E;           
       .byte 0x0C;           
       .byte 0x0A;           
       .byte 0x09;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0E;           
       .byte 0x0D;           
       .byte 0x0B;           
       .byte 0x0A;           
       .byte 0x09;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0F;           
       .byte 0x0D;           
       .byte 0x0C;           
       .byte 0x0B;           
       .byte 0x0A;           
       .byte 0x09;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0F;           
       .byte 0x0E;           
       .byte 0x0C;           
       .byte 0x0B;           
       .byte 0x0A;           
       .byte 0x09;           
       .byte 0x09;           
       .byte 0x08;           
       .byte 0x10;           
       .byte 0x0F;           
       .byte 0x0E;           
       .byte 0x0D;           
       .byte 0x0C;           
       .byte 0x0B;           
       .byte 0x0A;           
       .byte 0x09;           
       .byte 0x09;           
       .byte 0x08;           
SFC6D: .byte 0x00;           
       .byte 0x19;           
       .byte 0x32; /* "2" */ 
       .byte 0x4A; /* "J" */ 
       .byte 0x62; /* "b" */ 
       .byte 0x79; /* "y" */ 
       .byte 0x8E;           
       .byte 0xA2;           
       .byte 0xB5;           
       .byte 0xC6;           
       .byte 0xD5;           
       .byte 0xE2;           
       .byte 0xED;           
       .byte 0xF5;           
       .byte 0xFB;           
       .byte 0xFF;           
       .byte 0xFF;           
       .byte 0xFF;           
       .byte 0xFB;           
       .byte 0xF5;           
       .byte 0xED;           
       .byte 0xE2;           
       .byte 0xD5;           
       .byte 0xC6;           
       .byte 0xB5;           
       .byte 0xA2;           
       .byte 0x8E;           
       .byte 0x79; /* "y" */ 
       .byte 0x62; /* "b" */ 
       .byte 0x4A; /* "J" */ 
       .byte 0x32; /* "2" */ 
       .byte 0x19;           

music_stuff3;
SFC8D: .byte 0x03;           
       .byte 0xBD;           
       .byte 0x03;           
       .byte 0x87;           
       .byte 0x03;           
       .byte 0x54; /* "T" */ 
       .byte 0x03;           
       .byte 0x24; /* "$" */ 
       .byte 0x02;           
       .byte 0xF7;           
       .byte 0x02;           
       .byte 0xCD;           
       .byte 0x02;           
       .byte 0xA4;           
       .byte 0x02;           
       .byte 0x7E; /* "~" */ 
       .byte 0x02;           
       .byte 0x5B; /* "[" */ 
       .byte 0x02;           
       .byte 0x39; /* "9" */ 
       .byte 0x02;           
       .byte 0x19;           
       .byte 0x01;           
       .byte 0xFB;           
       .byte 0x01;           
       .byte 0xDE;           
       .byte 0x01;           
       .byte 0xC3;           
       .byte 0x01;           
       .byte 0xAA;           
       .byte 0x01;           
       .byte 0x92;           
       .byte 0x01;           
       .byte 0x7C; /* "|" */ 
       .byte 0x01;           
       .byte 0x66; /* "f" */ 
       .byte 0x01;           
       .byte 0x52; /* "R" */ 
       .byte 0x01;           
       .byte 0x3F; /* "?" */ 
       .byte 0x01;           
       .byte 0x2D; /* "-" */ 
       .byte 0x01;           
       .byte 0x1C;           
       .byte 0x01;           
       .byte 0x0C;           
       .byte 0x00;           
       .byte 0xFD;           
       .byte 0x00;           
       .byte 0xEF;           
       .byte 0x00;           
       .byte 0xE2;           
       .byte 0x00;           
       .byte 0xD5;           
       .byte 0x00;           
       .byte 0xC9;           
       .byte 0x00;           
       .byte 0xBE;           
       .byte 0x00;           
       .byte 0xB3;           
       .byte 0x00;           
       .byte 0xA9;           
       .byte 0x00;           
       .byte 0xA0;           
       .byte 0x00;           
       .byte 0x97;           
       .byte 0x00;           
       .byte 0x8E;           
       .byte 0x00;           
       .byte 0x86;           
       .byte 0x00;           
       .byte 0x7F;           
       .byte 0x00;           
       .byte 0x78; /* "x" */ 
       .byte 0x00;           
       .byte 0x71; /* "q" */ 
       .byte 0x00;           
       .byte 0x6B; /* "k" */ 
       .byte 0x00;           
       .byte 0x65; /* "e" */ 
       .byte 0x00;           
       .byte 0x5F; /* "_" */ 
       .byte 0x00;           
       .byte 0x5A; /* "Z" */ 
       .byte 0x00;           
       .byte 0x55; /* "U" */ 
       .byte 0x00;           
       .byte 0x50; /* "P" */ 
       .byte 0x00;           
       .byte 0x4B; /* "K" */ 
       .byte 0x00;           
       .byte 0x47; /* "G" */ 
       .byte 0x00;           
       .byte 0x43; /* "C" */ 
       .byte 0x00;           
       .byte 0x3F; /* "?" */ 
       .byte 0x00;           
       .byte 0x3C; /* "<" */ 
       .byte 0x00;           
       .byte 0x38; /* "8" */ 
       .byte 0x00;           
       .byte 0x35; /* "5" */ 
       .byte 0x00;           
       .byte 0x32; /* "2" */ 
       .byte 0x00;           
       .byte 0x2F; /* "/" */ 
       .byte 0x00;           
       .byte 0x2D; /* "-" */ 
       .byte 0x00;           
       .byte 0x2A; /* "*" */ 
       .byte 0x00;           
       .byte 0x28; /* "(" */ 
       .byte 0x00;           
       .byte 0x26; /* "&" */ 
       .byte 0x00;           
       .byte 0x24; /* "$" */ 
       .byte 0x00;           
       .byte 0x22; /* """ */ 
       .byte 0x00;           
       .byte 0x20; /* " " */ 
       .byte 0x00;           
       .byte 0x1E;           
       .byte 0x00;           
       .byte 0x1C;           
       .byte 0x00;           
       .byte 0x1B;           
       .byte 0x00;           
       .byte 0x00;           

/* Vectrex introduction music */
intro_music:
       .word #intro_header_1;  
       .word #music_header2_a; 
       .byte 0x93;       /* delay */
       .byte 0x1F;           
       .byte 0x0C;           
       .byte 0x93;       /* delay */
       .byte 0x1F;           
       .byte 0x06;           
       .byte 0x98;       /* delay */
       .byte 0x9F;       /* delay */
       .byte 0x24;
       .byte 0x3C;
       .byte 0x11;
       .byte 0x80;       /* end of music block */

       .byte 0xFD;           
       .byte 0x69; /* "i" */ 
       .byte 0xFD;           
       .byte 0x79; /* "y" */ 
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x0E;           
       .byte 0x99;           
       .byte 0x9F;           
       .byte 0x24; /* "$" */ 
       .byte 0x0E;           
       .byte 0x95;           
       .byte 0x9B;           
       .byte 0x20; /* " " */ 
       .byte 0x0E;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x21; /* "!" */ 
       .byte 0x07;           
       .byte 0x9D;           
       .byte 0xA3;           
       .byte 0x28; /* "(" */ 
       .byte 0x0E;           
       .byte 0xA0;           
       .byte 0xA6;           
       .byte 0x2B; /* "+" */ 
       .byte 0x0E;           
       .byte 0x22; /* """ */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x2D; /* "-" */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x22; /* """ */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x2D; /* "-" */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x22; /* """ */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x2D; /* "-" */ 
       .byte 0x02;           
       .byte 0x28; /* "(" */ 
       .byte 0x02;           
       .byte 0x2E; /* "." */ 
       .byte 0x02;           
       .byte 0x2D; /* "-" */ 
       .byte 0x28; /* "(" */ 
       .byte 0x21; /* "!" */ 
       .byte 0x80;           
       .byte 0xEF;           
       .byte 0xFF;           
       .byte 0xFE;           
       .byte 0xDC;           
       .byte 0xBA;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x01;           
       .byte 0x02;           
       .byte 0x01;           
       .byte 0x00;           
       .byte 0xFF;           
       .byte 0xFE;           
       .byte 0xFF;           
       .byte 0xFD;           
       .byte 0xC3;           
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x51; /* "Q" */ 
       .byte 0x24; /* "$" */ 
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x0C;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x18;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x0C;           
       .byte 0x50; /* "P" */ 
       .byte 0x0C;           
       .byte 0x50; /* "P" */ 
       .byte 0x24; /* "$" */ 
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x0C;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x06;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x18;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x04;           
       .byte 0x50; /* "P" */ 
       .byte 0x0C;           
       .byte 0x50; /* "P" */ 
       .byte 0x18;           
       .byte 0x26; /* "&" */ 
       .byte 0x80;           
       .byte 0xFD;           
       .byte 0xBA;           
       .byte 0x98;           
       .byte 0x76; /* "v" */ 
       .byte 0x55; /* "U" */ 
       .byte 0x44; /* "D" */ 
       .byte 0x33; /* "3" */ 
       .byte 0x22; /* """ */ 
       .byte 0x11;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0x28; /* "(" */ 
       .byte 0xFD;           
       .byte 0x79; /* "y" */ 
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x10;           
       .byte 0x3F; /* "?" */ 
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x04;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x04;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x10;           
       .byte 0x3F; /* "?" */ 
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x04;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x04;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x9C;           
       .byte 0x1F;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x9C;           
       .byte 0x1F;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x9C;           
       .byte 0x1F;           
       .byte 0x08;           
       .byte 0x98;           
       .byte 0x1C;           
       .byte 0x08;           
       .byte 0x93;           
       .byte 0x18;           
       .byte 0x08;           
       .byte 0x9C;           
       .byte 0x1F;           
       .byte 0x30; /* "0" */ 
       .byte 0x1A;           
       .byte 0x80;           
       .byte 0xFF;           
       .byte 0xFE;           
       .byte 0xDC;           
       .byte 0xBA;           
       .byte 0x98;           
       .byte 0x76; /* "v" */ 
       .byte 0x54; /* "T" */ 
       .byte 0x32; /* "2" */ 
       .byte 0x10;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0x66; /* "f" */ 
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x11;           
       .byte 0x18;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x11;           
       .byte 0x18;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x11;           
       .byte 0x18;           
       .byte 0x0C;           
       .byte 0x12;           
       .byte 0x0C;           
       .byte 0x06;           
       .byte 0x11;           
       .byte 0x18;           
       .byte 0x9D;           
       .byte 0x21; /* "!" */ 
       .byte 0x18;           
       .byte 0x9F;           
       .byte 0x23; /* "#" */ 
       .byte 0x18;           
       .byte 0xA1;           
       .byte 0x24; /* "$" */ 
       .byte 0x18;           
       .byte 0xA3;           
       .byte 0x26; /* "&" */ 
       .byte 0x18;           
       .byte 0x9F;           
       .byte 0xA4;           
       .byte 0x28; /* "(" */ 
       .byte 0x18;           
       .byte 0x07;           
       .byte 0x12;           
       .byte 0x07;           
       .byte 0x06;           
       .byte 0x00;           
       .byte 0x3C; /* "<" */ 
       .byte 0x18;           
       .byte 0x80;           
       .byte 0xDE;           
       .byte 0xEF;           
       .byte 0xFE;           
       .byte 0xDC;           
       .byte 0xBA;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0xB2;           
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x1A;           
       .byte 0x06;           
       .byte 0x1C;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x0C;           
       .byte 0x1A;           
       .byte 0x24; /* "$" */ 
       .byte 0x23; /* "#" */ 
       .byte 0x18;           
       .byte 0x17;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x1A;           
       .byte 0x0C;           
       .byte 0x17;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x24; /* "$" */ 
       .byte 0x24; /* "$" */ 
       .byte 0x18;           
       .byte 0xA4;           
       .byte 0x28; /* "(" */ 
       .byte 0x0C;           
       .byte 0xA3;           
       .byte 0x26; /* "&" */ 
       .byte 0x0C;           
       .byte 0xA1;           
       .byte 0x24; /* "$" */ 
       .byte 0x0C;           
       .byte 0x9F;           
       .byte 0x23; /* "#" */ 
       .byte 0x0C;           
       .byte 0x9D;           
       .byte 0x21; /* "!" */ 
       .byte 0x18;           
       .byte 0x9A;           
       .byte 0x1F;           
       .byte 0x18;           
       .byte 0x17;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x1A;           
       .byte 0x0C;           
       .byte 0x17;           
       .byte 0x0C;           
       .byte 0x18;           
       .byte 0x24; /* "$" */ 
       .byte 0x24; /* "$" */ 
       .byte 0x24; /* "$" */ 
       .byte 0x18;           
       .byte 0x80;           
       .byte 0xFF;           
       .byte 0xEE;           
       .byte 0xDD;           
       .byte 0xCC;           

music_header2_a:
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0xE8;           
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x96;           
       .byte 0x9A;           
       .byte 0x1D;           
       .byte 0x1E;           
       .byte 0x91;           
       .byte 0x95;           
       .byte 0x18;           
       .byte 0x1E;           
       .byte 0x94;           
       .byte 0x98;           
       .byte 0x1B;           
       .byte 0x1E;           
       .byte 0x8F;           
       .byte 0x94;           
       .byte 0x18;           
       .byte 0x14;           
       .byte 0x16;           
       .byte 0x0A;           
       .byte 0x8C;           
       .byte 0x91;           
       .byte 0x15;           
       .byte 0x14;           
       .byte 0x16;           
       .byte 0x0A;           
       .byte 0x91;           
       .byte 0x95;           
       .byte 0x18;           
       .byte 0x32; /* "2" */ 
       .byte 0x18;           
       .byte 0x80;           

intro_header1:
       .byte 0xEE;           
       .byte 0xFF;           
       .byte 0xFF;           
       .byte 0xEE;           
       .byte 0xEE;           
       .byte 0xDD;           
       .byte 0xCC;           
       .byte 0xBB;           
       .byte 0xAA;           
       .byte 0x99;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0x88;           
       .byte 0xFF;           
       .byte 0x16;           
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x1C;           
       .byte 0x06;           
       .byte 0x1F;           
       .byte 0x06;           
SFF00: .byte 0x1C;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x1A;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x15;           
       .byte 0x06;           
       .byte 0x13;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x06;           
       .byte 0x13;           
       .byte 0x06;           
       .byte 0x17;           
       .byte 0x06;           
       .byte 0x18;           
       .byte 0x1E;           
       .byte 0x18;           
       .byte 0x80;           
       .byte 0xFF;           
       .byte 0xFF;           
       .byte 0xEE;           
       .byte 0xEE;           
       .byte 0xDD;           
       .byte 0xDD;           
       .byte 0xCC;           
       .byte 0xCC;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0x00;           
       .byte 0xFE;           
       .byte 0x28; /* "(" */ 
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x16;           
       .byte 0x0F;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x1A;           
       .byte 0x0F;           
       .byte 0x16;           
       .byte 0x0F;           
       .byte 0x1D;           
       .byte 0x0F;           
       .byte 0x1D;           
       .byte 0x05;           
       .byte 0x1D;           
       .byte 0x05;           
       .byte 0x1D;           
       .byte 0x05;           
       .byte 0x21; /* "!" */ 
       .byte 0x0F;           
       .byte 0x1D;           
       .byte 0x32; /* "2" */ 
       .byte 0x1D;           
       .byte 0x80;           
       .byte 0xFE;           
       .byte 0x28; /* "(" */ 
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x16;           
       .byte 0x06;           
       .byte 0x16;           
       .byte 0x02;           
       .byte 0x16;           
       .byte 0x02;           
       .byte 0x16;           
       .byte 0x02;           
       .byte 0x1A;           
       .byte 0x06;           
       .byte 0x16;           
       .byte 0x06;           
       .byte 0x1D;           
       .byte 0x06;           
       .byte 0x1D;           
       .byte 0x02;           
       .byte 0x1D;           
       .byte 0x02;           
       .byte 0x1D;           
       .byte 0x02;           
       .byte 0x21; /* "!" */ 
       .byte 0x06;           
       .byte 0x1D;           
       .byte 0x32; /* "2" */ 
       .byte 0x11;           
       .byte 0x80;           
       .byte 0xFE;           
       .byte 0x28; /* "(" */ 
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x1B;           
       .byte 0x0F;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x17;           
       .byte 0x30; /* "0" */ 
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x16;           
       .byte 0x05;           
       .byte 0x17;           
       .byte 0x30; /* "0" */ 
       .byte 0x16;           
       .byte 0x80;           
       .byte 0xFD;           
       .byte 0x69; /* "i" */ 
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0xA0;           
       .byte 0x23; /* "#" */ 
       .byte 0x12;           
       .byte 0xA0;           
       .byte 0x23; /* "#" */ 
       .byte 0x0C;           
       .byte 0x9C;           
       .byte 0x20; /* " " */ 
       .byte 0x06;           
       .byte 0x9E;           
       .byte 0x21; /* "!" */ 
       .byte 0x12;           
       .byte 0x9C;           
       .byte 0x20; /* " " */ 
       .byte 0x32; /* "2" */ 
       .byte 0x13;           
       .byte 0x80;           
       .byte 0xFD;           
       .byte 0xC3;           
       .byte 0xFE;           
       .byte 0xB6;           
       .byte 0x16;           
       .byte 0x04;           
       .byte 0x16;           
       .byte 0x04;           
       .byte 0x16;           
       .byte 0x04;           
       .byte 0x16;           
       .byte 0x04;           
       .byte 0x1A;           
       .byte 0x08;           
       .byte 0x1C;           
       .byte 0x80;           
       .byte 0xA6;           
       .byte 0xA0;           
       .byte 0x20; /* " " */ 
       .byte 0x08;           
       .byte 0xBD;           
       .byte 0xF3;           
       .byte 0xBE;           
       .byte 0xB6;           
       .byte 0xC8;           
       .byte 0x80;           
       .byte 0x84;           
       .byte 0x7F;           
       .byte 0xB7;           
       .byte 0xC8;           
       .byte 0x80;           
       .byte 0x7A; /* "z" */ 
       .byte 0xC8;           
       .byte 0x80;           
       .byte 0xA6;           
       .byte 0xA4;           
       .byte 0x47; /* "G" */ 
       .byte 0x84;           
       .byte 0xF8;           
       .byte 0xE6;           
       .byte 0xA0;           
       .byte 0x58; /* "X" */ 
       .byte 0x58; /* "X" */ 
       .byte 0x58; /* "X" */ 
       .byte 0x58; /* "X" */ 
       .byte 0x57; /* "W" */ 
       .byte 0xC4;           
       .byte 0xF8;           
       .byte 0x7D; /* "}" */ 
       .byte 0xC8;           
       .byte 0x80;           
       .byte 0x2B; /* "+" */ 
       .byte 0xDF;           
       .byte 0xBD;           
       .byte 0xF3;           
       .byte 0xDF;           
       .byte 0xB6;           
       .byte 0xC8;           
       .byte 0x80;           
       .byte 0x85;           
       .byte 0x0F;           
       .byte 0x26; /* "&" */ 
       .byte 0xE0;           
       .byte 0x85;           
       .byte 0x20;
       .byte 0x27; /* "'" */ 
       .byte 0xCD;           
       .byte 0x39; /* "9" */ 
       .byte 0x4B; /* "K" */ 
       .byte 0x41; /* "A" */ 
       .byte 0x52; /* "R" */ 
       .byte 0x52; /* "R" */ 
       .byte 0x53; /* "S" */ 
       .byte 0x4F; /* "O" */ 
       .byte 0x46; /* "F" */ 
       .byte 0x54; /* "T" */ 
       .byte 0x38; /* "8" */ 
       .byte 0x32; /* "2" */ 
       .byte 0x4C; /* "L" */ 
       .byte 0x44; /* "D" */ 
       .byte 0x4D; /* "M" */ 
       .byte 0x43; /* "C" */ 
       .byte 0x42; /* "B" */ 
       .byte 0x43; /* "C" */ 
       .byte 0x4A; /* "J" */ 
       .byte 0x54; /* "T" */ 
       .byte 0x38; /* "8" */ 
       .byte 0x32; /* "2" */ 
       .byte 0x4C; /* "L" */ 
       .byte 0x44; /* "D" */ 
       .byte 0x4D; /* "M" */ 
       .byte 0x43; /* "C" */ 
       .byte 0x42; /* "B" */ 
       .byte 0x43; /* "C" */ 
       .byte 0x4A; /* "J" */ 

       /* 6809 interrupt and startup vectors */
       .word 0x0000;
       .word 0x0000;
       .word 0xCBF2;
       .word 0xCBF2;
       .word 0xCBF5;
       .word 0xCBF8;
       .word 0xCBFB;
       .word 0xCBFB;
       .word #start;

