Article 1792 of rec.games.vectrex:
Path: mri-gw!psinntp!psinntp!psinntp!uunet!cs.utexas.edu!howland.reston.ans.net!torn!newshost.uwo.ca!gaul.csd.uwo.ca!magundi
From: magundi@gaul.csd.uwo.ca (john macdonald)
Newsgroups: rec.games.vectrex
Subject: Art Master Source
Date: 24 Aug 1994 14:28:07 GMT
Organization: Computer Science Dept., Univ. of Western Ontario, London, Canada
Lines: 3413
Distribution: world
Message-ID: <33fldn$1n1@falcon.ccs.uwo.ca>
NNTP-Posting-Host: obelix.gaul.csd.uwo.ca

From fred@hpcvusc.cv.hp.com Wed Aug 24 09:48 EDT 1994
Date: Wed, 24 Aug 1994 06:47:22 -0700
From: Fred Taft <fred@hpcvusc.cv.hp.com>
To: magundi@uwo.ca
Subject: Art Master source
Status: O

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


                        .org 0x0000;
0000   67               .byte "g GCE 1983",0x80;

000B   0EEE             .word #AM_music;
000D   F8               .byte 0xF8;/* height */
000E   40               .byte 0x40;/* width  */
000F   20               .byte 0x20;/* rel y  */
0010   EC               .byte 0xEC;/* rel x  */
0011   41               .byte "ART", 0x80;
0015   F8               .byte 0xF8;/* height */
0016   40               .byte 0x40;/* width  */
0017   04               .byte 0x04;/* rel y  */
0018   E0               .byte 0xE0;/* rel x  */
0019   4D               .byte "MASTER", 0x80, 0x00;

	 	 /*
		  * Art Master
		  *
		  * This is the entry point for the Art Master game.
		  * It initializes the RAM area used by the game, initializes
		  * the music buffer, sets up the indirect jump location
		  * in C8A7, and lastly, passes control to the main loop.
		  */
0021   12        start: nop;    
0022   BD01A2           jsr   $am_clear_game_RAM;   
0025   BDF18B           jsr   $reinit;    
0028   BDF533           jsr   $init_music_buf;
002B   7FC856           clr   $C856; 
002E   BDF289           jsr   $do_sound;
0031   8E009B           ldx   #display_main_menu;    
0034   BFC8A7           stx   $C8A7; 
0037   7FC81E           clr   $C81E; 

		 /*
		  * main_loop()
		  *
		  * This main loop is responsible for reading the buttons
		  * on the primary console, continuing any sounds which
		  * are in progress, and then calling whichever handling
		  * routine has been set up in the indirect jump location.
		  * After this, it recalibrates the integraters, and then
		  * repeats the above.
		  */
		 main_loop:
003A   BDF1BA           jsr   $read_switches2;
003D   BD0ECB           jsr   $check_for_end_of_sound;
0040   BDF289    P0040: jsr   $do_sound;
0043   B6C81B           lda   $C81B;     /* Keep track of the fact that */
0046   B7C81E           sta   $C81E;     /* a string was picked last pass */
0049   7FC81B           clr   $C81B;     /* thru the main loop.         */
004C   AD9FC8A7         jsr   [0xC8A7];
0050   BDF192    P0050: jsr   $waitrecal;
0053   7E003A           jmp   $main_loop;


		 SM_ERASE_STR:
0056   E8               .byte 0xE8;
0057   20               .byte 0x20;
0058   80               .byte 0x80;
0059   30               .byte 0x30;
005A   00               .word 0x005C;
005C   45               .byte "ERASE",0x80; 

		 SM_MENU_STR:
0062   E8               .byte 0xE8;
0063   20               .byte 0x20;
0064   80               .byte 0x80;
0065   50               .byte 0x50;
0066   00               .word 0x0068;
0068   4D               .byte "MENU", 0x80; 

		 SM_NEXT_STR:
006D   E8               .byte 0xE8;
006E   20               .byte 0x20;
006F   80               .byte 0x80;
0070   A0               .byte 0xA0;
0071   00               .word 0x0073;
0073   4E               .byte "NEXT", 0x80; 

		 SM_LAST_STR:
0078   E8               .byte 0xE8;
0079   20               .byte 0x20;
007A   80               .byte 0x80;
007B   C0               .byte 0xC0;
007C   00               .word 0x007E;
007E   4C               .byte "LAST", 0x80;

		 SM_PLAY_STR:
0083   E8               .byte 0xE8;
0084   20               .byte 0x20;
0085   80               .byte 0x80;
0086   E0               .byte 0xE0;
0087   00               .word 0x0089;
0089   50               .byte "PLAY", 0x80;

		 SM_CREATE_STR:
008E   E8               .byte 0xE8;
008F   20               .byte 0x20;
0090   80               .byte 0x80;
0091   28               .byte 0x28;
0092   00               .word 0x0094;
0094   43               .byte "CREATE", 0x80; 


		 /*
		  * The next 3 blocks of code cause the three main
		  * menu items (sketch, connect and animate) to be
		  * displayed, until one of them is picked by the
		  * lightpen (a pick is indicated by C89E != 0).  
		  * When a pick occurs, the counter in C888
		  * is set, and the jump location (C8A7) is set so that
		  * only the picked option is displayed.
		  */
		 display_main_menu:
009B   BDF2A9           jsr   $intensity_to_7F;
009E   CE0169           ldu   #MM_SKETCH_STR;    
00A1   BD0ACF           jsr   $print_with_pick_check;
00A4   7DC89E           tst   $C89E; 
00A7   270C             beq   disp_mm_connect_str; 
00A9   860A             lda   #0x0A; 
00AB   B7C888           sta   $C888; 
00AE   8E0102           ldx   #disp_only_mm_sketch_str;    
00B1   BFC8A7           stx   $C8A7; 
00B4   39               rts;    

		 disp_mm_connect_str:
00B5   CE0176           ldu   #MM_CONNECT_STR;    
00B8   BD0ACF           jsr   $print_with_pick_check;
00BB   7DC89E           tst   $C89E; 
00BE   270C             beq   disp_mm_animate_str; 
00C0   860A             lda   #0x0A; 
00C2   B7C888           sta   $C888; 
00C5   8E0127           ldx   #disp_only_mm_connect_str;    
00C8   BFC8A7           stx   $C8A7; 
00CB   39               rts;    

		 disp_mm_animate_str:
00CC   CE0184           ldu   #MM_ANIMATE_STR;    
00CF   BD0ACF           jsr   $print_with_pick_check;
00D2   7DC89E           tst   $C89E; 
00D5   270C             beq   P00E3; 
00D7   8E00E4           ldx   #disp_only_mm_animate_str;    
00DA   BFC8A7           stx   $C8A7; 
00DD   860A             lda   #0x0A; 
00DF   B7C888           sta   $C888; 
00E2   39               rts;    
00E3   39        P00E3: rts;    


		 /*
		  * Continue to display the ANIMATE main menu item,
		  * until either the loop counter (C888) decrements
		  * to zero (at which point the ANIMATE activity starts),
		  * or the string is no longer picked (then display the
		  * main menu again).
		  */
		 disp_only_mm_animate_str:
00E4   BDF2A9           jsr   $intensity_to_7F;
00E7   CE0184           ldu   #MM_ANIMATE_STR;    
00EA   BD0ACF           jsr   $print_with_pick_check;
00ED   7DC89E           tst   $C89E; 
00F0   2607             bne   P00F9; 
00F2   8E009B           ldx   #display_main_menu;    
00F5   BFC8A7           stx   $C8A7; 
00F8   39               rts;    

00F9   7AC888    P00F9: dec   $C888; 
00FC   2701             beq   P00FF; 
00FE   39               rts;    

00FF   7E01D6    P00FF: jmp   $start_of_animate;


		 /*
		  * Continue to display the SKETCH main menu item,
		  * until either the loop counter (C888) decrements
		  * to zero (at which point the SKETCH activity starts),
		  * or the string is no longer picked (then display the
		  * main menu again).
		  */
		 disp_only_mm_sketch_str:
0102   BDF2A9           jsr   $intensity_to_7F;
0105   CE0169           ldu   #MM_SKETCH_STR;    
0108   BD0ACF           jsr   $print_with_pick_check;
010B   7DC89E           tst   $C89E; 
010E   2607             bne   P0117; 
0110   8E009B           ldx   #display_main_menu;    
0113   BFC8A7           stx   $C8A7; 
0116   39               rts;    

0117   7AC888    P0117: dec   $C888; 
011A   2701             beq   P011D; 
011C   39               rts;    

011D   7FC8A6    P011D: clr   $C8A6;     /* Flag this is sketch mode */
0120   8E0BCF           ldx   #start_of_sketch_connect;    
0123   BFC8A7           stx   $C8A7; 
0126   39               rts;    


		 /*
		  * Continue to display the CONNECT main menu item,
		  * until either the loop counter (C888) decrements
		  * to zero (at which point the CONNECT activity starts),
		  * or the string is no longer picked (then display the
		  * main menu again).
		  */
		 disp_only_mm_connect_str:
0127   BDF2A9           jsr   $intensity_to_7F;
012A   CE0176           ldu   #MM_CONNECT_STR;    
012D   BD0ACF           jsr   $print_with_pick_check;
0130   7DC89E           tst   $C89E; 
0133   2607             bne   P013C; 
0135   8E009B           ldx   #display_main_menu;    
0138   BFC8A7           stx   $C8A7; 
013B   39               rts;    

013C   7AC888    P013C: dec   $C888; 
013F   2701             beq   P0142; 
0141   39               rts;    

0142   86FF      P0142: lda   #0xFF; 
0144   B7C8A6           sta   $C8A6;    /* CONNECT option */
0147   B7C8A5           sta   $C8A5;    /* Do dots first */
014A   8E0BCF           ldx   #start_of_sketch_connect;    
014D   BFC8A7           stx   $C8A7; 
0150   39               rts;    


		 HDR_CREATE_STR:
0151   E8               .byte 0xE8;
0152   40               .byte 0x40;
0153   7F               .byte 0x7F;
0154   E8               .byte 0xE8;
0155   01               .word 0x0157;
0157   43               .byte "CREATE", 0x80; 

		 HDR_EDIT_STR:
015E   E8               .byte 0xE8;
015F   40               .byte 0x40;
0160   7F               .byte 0x7F;
0161   F0               .byte 0xF0;
0162   01               .word 0x0164;
0164   45               .byte "EDIT", 0x80;

		 MM_SKETCH_STR:
0169   E0               .byte 0xE0;
016A   40               .byte 0x40;
016B   40               .byte 0x40;
016C   E0               .byte 0xE0;
016D   01               .word 0x016F;
016F   53               .byte "SKETCH", 0x80; 

		 MM_CONNECT_STR:
0176   E0               .byte 0xE0;
0177   40               .byte 0x40;
0178   00               .byte 0x00;
0179   DC               .byte 0xDC;
017A   01               .word 0x017C;
017C   43               .byte "CONNECT", 0x80;

		 MM_ANIMATE_STR:
0184   E0               .byte 0xE0;
0185   40               .byte 0x40;
0186   C0               .byte 0xC0;
0187   DC               .byte 0xDC;
0188   01               .word 0x018A;
018A   41               .byte "ANIMATE", 0x80;

		 /* 
		  * This is the vector list which describes the box
		  * which is sometimes drawn around a selected point.
		  * The list has the following format:
		  *
		  *	line pattern, rel y, rel x
		  *
		  * A line pattern of 1 signals the end.
		  */
		 box:
0192   00               .byte 0x00;
0193   20               .byte 0x20;
0194   20               .byte 0x20;
0195   FF               .byte 0xFF;
0196   00               .byte 0x00;
0197   C0               .byte 0xC0;
0198   FF               .byte 0xFF;
0199   C0               .byte 0xC0;
019A   00               .byte 0x00;
019B   FF               .byte 0xFF;
019C   00               .byte 0x00;
019D   40               .byte 0x40;
019E   FF               .byte 0xFF;
019F   40               .byte 0x40;
01A0   00               .byte 0x00;
01A1   01               .byte 0x01;

		 /*
		  * am_clear_game_RAM()
		  *
		  * Clear to zero, the block of RAM which is used
		  * by the Art Master game: C880 - CB7F
		  */
		 am_clear_game_RAM:
01A2   8EC880           ldx   #0xC880;    
01A5   6F80      P01A5: clr   ,x+;   
01A7   8CCB80           cmpx  #0xCB80;    
01AA   26F9             bne   P01A5; 
01AC   39               rts;    


		 /*
		  * draw_previous_frame()
		  *
		  * This routine gets information for the previous frame
		  * during ANIMATE mode.  It will then use the new
		  * frame number to index into the structure starting
		  * at C977 (the vectors for this frame), using the 
		  * following formula:
		  *
		  * C917 = (previous_frame_num * 64) + C977
		  * 
		  * Afterwards, it will draw the vectors associated with
		  * this frame, using a small intensity, thus allowing the
		  * user to see the previous frame he made.
		  */
		 draw_previous_frame:
01AD   B6C8A5           lda   $C8A5; 
01B0   2601             bne   P01B3; 
01B2   39               rts;    
01B3   4A        P01B3: deca;   
01B4   C620             ldb   #0x20;
01B6   58               aslb;   
01B7   3D               mul;    
01B8   8EC977           ldx   #0xC977;    
01BB   308B             leax  d,x;   
01BD   BFC917           stx   $C917; 
01C0   8648             lda   #0x48;
01C2   BDF2AB           jsr   $intensity_to_a;
01C5   BD053C           jsr   $draw_all_visible_lines;
01C8   BD0507           jsr   $draw_points_without_pick;
01CB   39               rts;    


		 /*
		  * select_a_frame (frame_num)
		  *
		  * This procedure selects a particular frame
		  * as the active frame, and returns a pointer
		  * to the vector list associated with that frame
		  * in the 'x' register.  At entry, the 'b' register
		  * specifies which frame is to be selected.
		  */
		 select_a_frame:
01CC   58               aslb;   
01CD   8620             lda   #0x20; /* " " */                                
01CF   3D               mul;    
01D0   8EC977           ldx   #0xC977;    
01D3   308B             leax  d,x;   
01D5   39               rts;    


		 /*
		  * This is the starting point for the
		  * ANIMATE main menu option.
		  */
		 start_of_animate:
01D6   BD01A2           jsr   $am_clear_game_RAM;   
01D9   BD056F           jsr   $init_animate_variables;
01DC   7FC8A3           clr   $C8A3; 
01DF   7FC8A6           clr   $C8A6; 
		 return_to_frame1:
01E2   7FC8A5           clr   $C8A5; 
01E5   CCFFFF           ldd   #0xFFFF;    
01E8   FDC910           std   $C910; 
01EB   8E0224           ldx   #animate_handler;    
01EE   BFC8A7           stx   $C8A7; 
01F1   39               rts;    


		 /*
		  * advance_to_next_frame()
		  *
		  * This procedure first checks to see if we will be
		  * entering a virgin frame (C8A5 == C8A6), and if we
		  * are, then it copies the data in the current frames
		  * vector list area into the area associated with the
		  * next frame.  In any case, the frame counter is
		  * incremented, and if this is a virgin frame, then
		  * C8A6 is updated to reflect the fact that we have
		  * now advanced into a new frame.
		  */
		 advance_to_next_frame:
01F2   F6C8A5           ldb   $C8A5;   /* If C8A5 == C8A6, then init */
01F5   F1C8A6           cmpb  $C8A6;   /* the new vector list area.  */
01F8   2615             bne   P020F; 
01FA   BD01CC           jsr   $select_a_frame;
01FD   5F               clrb;   
01FE   A600      P01FE: lda   0,x;     /* Copy vector list info from */
0200   A78840           sta   0x40,x;  /* current frame to new frame. */
0203   A601             lda   1,x;   
0205   A78841           sta   0x41,x;
0208   3002             leax  2,x;   
020A   5C               incb;   
020B   C120             cmpb  #0x20;
020D   26EF             bne   P01FE; 
020F   7CC8A5    P020F: inc   $C8A5;  /* Increment the frame counter, and */
0212   B6C8A5           lda   $C8A5;  /* update C8A6 if this is a virgin  */
0215   B1C8A6           cmpa  $C8A6;  /* frame being entered.             */
0218   2F03             ble   P021D; 
021A   B7C8A6           sta   $C8A6; 
021D   8E02C7    P021D: ldx   #edit_handler;    
0220   BFC8A7           stx   $C8A7; 
0223   39               rts;    


		 /*
		  * animate_handler()
		  *
		  * This procedure is responsible for overseeing the
		  * work done by the ANIMATE command.  It is invoked
		  * through the indirect jump location.
		  */
		 animate_handler:
0224   BD0306           jsr   $display_frame_num;
0227   BDF354           jsr   $reset0ref;
022A   8EC977           ldx   #0xC977;            /* Reset pointer to the */
022D   BFC917           stx   $C917;              /* first frame.         */
0230   7FC914           clr   $C914; 
0233   BDF2A9           jsr   $intensity_to_7F;
0236   BD048C           jsr   $find_lightpen_pick;
0239   BD053C           jsr   $draw_all_visible_lines;
023C   BDF354           jsr   $reset0ref;
023F   CE0151           ldu   #HDR_CREATE_STR;    
0242   BD0B19           jsr   $am_print_string;
0245   FCC915           ldd   $C915;         /* If a vector was picked, then */
0248   1083FFFF         cmpd  #0xFFFF;       /* highlight it, by redrawing   */
024C   271B             beq   P0269;         /* it several times.            */
024E   1F03             tfr   d,u;   
0250   BD055B           jsr   $draw_line_between_2_points;
0253   BD055B           jsr   $draw_line_between_2_points;
0256   BD055B           jsr   $draw_line_between_2_points;
0259   7DC815           tst   $C815;         /* If button 4 (delete) is  */
025C   270B             beq   P0269;         /* pressed, then remove the */
025E   1F31             tfr   u,x;           /* indexes for this line from */
0260   EC02      P0260: ldd   2,x;           /* the line array.          */
0262   ED81             std   ,x++;  
0264   8CC90D           cmpx  #0xC90D;    
0267   26F7             bne   P0260; 
0269   BD042D    P0269: jsr   $process_button1_and_2;
026C   4D               tsta;   
026D   270B             beq   disp_sm_erase_str; /* If button 2 was pressed, */
026F   7DC813           tst   $C813;             /* then add the indexes for */
0272   2706             beq   disp_sm_erase_str; /* the line endpoints to the*/
0274   FCC910           ldd   $C910;             /* line array (C8A9-C90E).  */
0277   BD057C           jsr   $add_a_new_line;

		 /*
		  * disp_sm_erase_str()
		  *
		  * Display the ERASE sub-menu string, while the
		  * ANIMATE option is in CREATE mode.  If the
		  * string is picked (C89E != 0) while button 3
		  * is pressed (C814 != 0), then jump to the routine
		  * which re_initializes the animate buffers and
		  * variables; this erases the all current frames.
		  */
		 disp_sm_erase_str:
027A   BD03C2           jsr   $check_for_move_request;
027D   CE0056           ldu   #SM_ERASE_STR;    
0280   BD0ACF           jsr   $print_with_pick_check;
0283   7DC814           tst   $C814; 
0286   2708             beq   disp_sm_next_str; 
0288   7DC89E           tst   $C89E; 
028B   2703             beq   disp_sm_next_str; 
028D   7E01D6           jmp   $start_of_animate;

		 /*
		  * disp_sm_next_str()
		  *
		  * Display the NEXT sub-menu string, while the
		  * ANIMATE option is in CREATE mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then advance to the next ANIMATE frame.
		  */
		 disp_sm_next_str:
0290   CE006D           ldu   #SM_NEXT_STR;    
0293   BD0ACF           jsr   $print_with_pick_check;
0296   7DC814           tst   $C814; 
0299   270F             beq   disp_sm_menu_str; 
029B   7DC89E           tst   $C89E; 
029E   270A             beq   disp_sm_menu_str; 
02A0   BD01F2           jsr   $advance_to_next_frame;
02A3   7FC913           clr   $C913; 
02A6   BD0ED8           jsr   $set_up_a_misc_sound1;
02A9   39               rts;    

		 /*
		  * disp_sm_menu_str()
		  *
		  * Display the MENU sub-menu string, while the
		  * ANIMATE option is in CREATE mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then exit from ANIMATE mode, and return
		  * to the main menu.
		  */
		 disp_sm_menu_str:
02AA   CE0062           ldu   #SM_MENU_STR;    
02AD   BD0ACF           jsr   $print_with_pick_check;
02B0   7DC814           tst   $C814; 
02B3   270B             beq   P02C0; 
02B5   7DC89E           tst   $C89E; 
02B8   2706             beq   P02C0; 
02BA   8E009B           ldx   #display_main_menu;    
02BD   BFC8A7           stx   $C8A7; 
02C0   39        P02C0: rts;    


02C1   E8               .byte 0xE8;   /* height of FR string */
02C2   40               .byte 0x40;   /* width of FR string */
02C3   7F               .byte 0x7F;   /* rel y of FR string */
02C4   40               .byte 0x40;   /* rel x of FR string */
02C5   C92A             .word 0xC92A; /* pointer to start of FR string */


		 /*
		  * edit_handler()
		  *
		  * This procedure is responsible for processing the
		  * buttons during the EDIT portion of ANIMATE mode.
		  * It also displays the EDIT header, and the sub-menu
		  * items (if they have not bee disabled).  This is
		  * invoked only through the indirect jump location.
		  */
		 edit_handler:
02C7   7DC913           tst   $C913;   /* See if a background image */
02CA   2703             beq   P02CF;   /* needs to be displayed.    */
02CC   BD01AD           jsr   $draw_previous_frame;
02CF   F6C8A5    P02CF: ldb   $C8A5; 
02D2   BD01CC           jsr   $select_a_frame;
02D5   BFC917           stx   $C917; 
02D8   BDF2A9           jsr   $intensity_to_7F;
02DB   F6C8A5           ldb   $C8A5; 
02DE   BD048C           jsr   $find_lightpen_pick;
02E1   BD053C           jsr   $draw_all_visible_lines;
02E4   BD03C2           jsr   $check_for_move_request;
02E7   7DC815           tst   $C815;   /* Check button 4 (background) */
02EA   2703             beq   P02EF; 
02EC   73C913           com   $C913;   /* Toggle state of background flag */
02EF   7DC812    P02EF: tst   $C812;   /* Check button 1 (foreground) */
02F2   2703             beq   P02F7; 
02F4   73C914           com   $C914;   /* Toggle state of foreground flag */
02F7   BDF354    P02F7: jsr   $reset0ref;
02FA   CE015E           ldu   #HDR_EDIT_STR;   /* Display EDIT screen header */
02FD   BD0B19           jsr   $am_print_string;
0300   7DC914           tst   $C914;   /* See if sub-menu should be displayed */
0303   2727             beq   disp_sm_menu_str2; 
0305   39               rts;    


		 /*
		  * display_frame_num()
		  *
		  * Display the frame number string:
		  *
		  *	"FR #",0x80
		  */
		 display_frame_num:
0306   8646             lda   #0x46; /* "F" */                                
0308   C652             ldb   #0x52; /* "R" */                                
030A   FDC92A           std   $C92A; 
030D   8620             lda   #0x20; /* " " */                                
030F   B7C92C           sta   $C92C; 
0312   8680             lda   #0x80; 
0314   B7C92E           sta   $C92E; 
0317   B6C8A5           lda   $C8A5; 
031A   8B31             adda  #0x31; /* "1" */                                
031C   B7C92D           sta   $C92D; 
031F   CE02C1           ldu   #0x02C1;    
0322   BDF354           jsr   $reset0ref;
0325   BDF56D           jsr   $delay_b_3;
0328   BD0B19           jsr   $am_print_string;
032B   39               rts;    


		 /*
		  * disp_sm_menu_str2()
		  *
		  * Display the MENU sub-menu string, while the
		  * ANIMATE option is in EDIT mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then exit from ANIMATE mode, and return
		  * to the main menu.
		  */
		 disp_sm_menu_str2:
032C   BD0306           jsr   $display_frame_num;
032F   CE0062           ldu   #SM_MENU_STR;    
0332   BD0ACF           jsr   $print_with_pick_check;
0335   7DC814           tst   $C814; 
0338   270C             beq   disp_sm_create_str; 
033A   7DC89E           tst   $C89E; 
033D   2707             beq   disp_sm_create_str; 
033F   8E009B           ldx   #display_main_menu;    
0342   BFC8A7           stx   $C8A7; 
0345   39        P0345: rts;    

		 /*
		  * disp_sm_create_str()
		  *
		  * Display the CREATE sub-menu string, while the
		  * ANIMATE option is in EDIT mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then exit from EDIT mode, and return
		  * to CREATE mode.
		  */
		 disp_sm_create_str:
0346   CE008E           ldu   #SM_CREATE_STR;    
0349   BD0ACF           jsr   $print_with_pick_check;
034C   7DC814           tst   $C814; 
034F   270E             beq   disp_sm_next_str2; 
0351   7DC89E           tst   $C89E; 
0354   2709             beq   disp_sm_next_str2; 
0356   CE0056           ldu   #SM_ERASE_STR;    
0359   FFC81C           stu   $C81C; 
035C   7E01E2           jmp   $return_to_frame1;

		 /*
		  * disp_sm_next_str2()
		  *
		  * Display the NEXT sub-menu string, while the
		  * ANIMATE option is in EDIT mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then advance to the next frame, and
		  * make a sound also.
		  */
		 disp_sm_next_str2:
035F   B6C8A5           lda   $C8A5;   /* Only display this label if we */
0362   8108             cmpa  #0x08;   /* are not already at last frame */
0364   271E             beq   disp_sm_last_str; 
0366   CE006D           ldu   #SM_NEXT_STR;    
0369   BD0ACF           jsr   $print_with_pick_check;
036C   7DC814           tst   $C814; 
036F   2713             beq   disp_sm_last_str; 
0371   7DC89E           tst   $C89E; 
0374   270E             beq   disp_sm_last_str; 
0376   B6C8A5           lda   $C8A5;   /* Increment the frame counter */
0379   8108             cmpa  #0x08; 
037B   2707             beq   disp_sm_last_str; 
037D   BD01F2           jsr   $advance_to_next_frame;
0380   BD0ED8           jsr   $set_up_a_misc_sound1;
0383   39               rts;    

		 /*
		  * disp_sm_last_str()
		  *
		  * Display the LAST sub-menu string, while the
		  * ANIMATE option is in EDIT mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then display the previous frame, and
		  * make a sound also.
		  */
		 disp_sm_last_str:
0384   7DC8A5           tst   $C8A5;      /* Only display this label if not */
0387   271F             beq   disp_sm_play_str;  /* already at first frame. */
0389   CE0078           ldu   #SM_LAST_STR;    
038C   BD0ACF           jsr   $print_with_pick_check;
038F   7DC814           tst   $C814; 
0392   2714             beq   disp_sm_play_str; 
0394   7DC89E           tst   $C89E; 
0397   270F             beq   disp_sm_play_str; 
0399   7DC8A5           tst   $C8A5; 
039C   270A             beq   disp_sm_play_str; 
039E   7AC8A5           dec   $C8A5;   /* Decrement frame counter */
03A1   CC0040           ldd   #0x0040;    
03A4   BD0EDB           jsr   $set_up_a_misc_sound2;
03A7   39               rts;   

		 /*
		  * disp_sm_play_str()
		  *
		  * Display the PLAY sub-menu string, while the
		  * ANIMATE option is in EDIT mode.  If the string
		  * is picked (C89E != 0) while button 3 is pressed
		  * (C814 != 0), then prepare to start playing through
		  * the current set of defined frames.
		  */
		 disp_sm_play_str:
03A8   CE0083           ldu   #SM_PLAY_STR;    
03AB   BD0ACF           jsr   $print_with_pick_check;
03AE   7DC814           tst   $C814; 
03B1   270E             beq   P03C1; 
03B3   7DC89E           tst   $C89E; 
03B6   2709             beq   P03C1; 
03B8   BD05D3           jsr   $init_play_variables;
03BB   8E059C           ldx   #play_handler;    
03BE   BFC8A7           stx   $C8A7; 
03C1   39        P03C1: rts;    


		 /*
		  * check_for_move_request()
		  *
		  * This routine is responsible for checking the state
		  * of button 3 (move a point) during ANIMATE mode.  This
		  * is called by the CREATE and EDIT handlers, for each
		  * pass through the handler loop.
		  *
		  * C912 indicates if a move request is currently active.
		  * C90F contains index of currently picked point.
		  * C917 points to the beginning of the vector list.
		  * 
		  */
		 check_for_move_request:
03C2   B6C80F           lda   $C80F;   /* Check for button 3 transition */
03C5   8404             anda  #0x04;   /* Button 3 = move a point.      */
03C7   2604             bne   process_move; 
03C9   7FC912           clr   $C912; 
03CC   39               rts;    

		 process_move:
03CD   7DC814           tst   $C814;   /* See if button 3 is now pressed */
03D0   2733             beq   continue_moving_point; 
03D2   7DC90F           tst   $C90F;   /* Make sure a point is picked */
03D5   2A04             bpl   start_moving_point; 
03D7   7FC912           clr   $C912; 
03DA   39               rts;    

		 start_moving_point:
03DB   86FF             lda   #0xFF; 
03DD   B7C912           sta   $C912;    /* Flag that move is active */
03E0   CC7F81           ldd   #0x7F81;    
03E3   FDC897           std   $C897;    /* Set up new cursor movement */
03E6   CC887F           ldd   #0x887F;  /* limits.                    */
03E9   FDC899           std   $C899; 
03EC   F6C90F           ldb   $C90F; 
03EF   58               aslb;   
03F0   F7C89D           stb   $C89D;    /* Save index of moving point */
03F3   BEC917           ldx   $C917;    
03F6   EC85             ldd   b,x;      /* Get point's coordinates */
03F8   FDC895           std   $C895; 
03FB   CEC889           ldu   #0xC889;  /* Move cursor to this point */  
03FE   8EC895           ldx   #0xC895;    
0401   BD08ED           jsr   $set_cursor_structure;
0404   39               rts;    

		 continue_moving_point:
0405   7DC912           tst   $C912; 
0408   2601             bne   update_moving_point; 
040A   39               rts;    

		 update_moving_point:
040B   CEC889           ldu   #0xC889;             /* Replace the location of */
040E   BD0901           jsr   $update_cursor_position; /* the picked point */
0411   F6C89D           ldb   $C89D;                   /* in the vector list. */
0414   BEC917           ldx   $C917; 
0417   FEC889           ldu   $C889; 
041A   EF85             stu   b,x;   
041C   BDF354           jsr   $reset0ref;
041F   1F30             tfr   u,d;   
0421   BD0EB2           jsr   $am_move_to_d;
0424   8E0192           ldx   #box;       /* Draw the lightpen box */
0427   C610             ldb   #0x10;      /* around the picked point */
0429   BD07D6           jsr   $draw_with_pick_check;
042C   39               rts;    


		 /*
		  * process_button1_and_2()
		  *
		  * This procedure checks to see if buttons 1 or 2 are
		  * during animate mode.  If neither button is pressed,
		  * then this routine returns without doing anything.  
		  * However, if either button is pressed, then this routine
		  * attempts to 'locate' the lightpen.  If C90F != 0xFF,
		  * then this implies that the lightpen is already at a
		  * known place (on an existing point); if C90F == 0xFF,
		  * then a series of horizontal scan lines will be drawn,
		  * until the lightpen is located, or the whole screen is
		  * scanned.
		  *
		  * At entry:
		  *	(C8A3)-1 contains index of next available spot
		  *		 in the vector list.
		  *
		  * At exit time:
		  *  	'a' register =  0 => lightpen not located.
		  *	'a' register = FF => lightpen located, and
		  *	    C910 is set to index of current point, and
		  *	    C911 is set to index of previous point.
		  */
		 process_button1_and_2:
042D   B6C812           lda   $C812;   /* Check if either button 1 or */
0430   BAC813           ora   $C813;   /* button 2 is pressed.        */
0433   2602             bne   P0437; 
0435   4F               clra;          /* Lightpen not located */
0436   39               rts;    

0437   B6C90F    P0437: lda   $C90F;   /* See if the lightpen is on an */
043A   2B0C             bmi   P0448;   /* existing point.              */
043C   F6C910           ldb   $C910;   /* YES it is, so save the index */
043F   F7C911           stb   $C911;   /* this point, and the previous */
0442   B7C910           sta   $C910;   /* point the lightpen picked.   */
0445   86FF             lda   #0xFF; 
0447   39               rts;    

0448   BD0460    P0448: jsr   $scan_screen_for_lightpen;
044B   4D               tsta;   
044C   2602             bne   P0450; 
044E   4F               clra;          /* Lightpen not located.        */
044F   39               rts;    

0450   B6C910    P0450: lda   $C910;   /* Lightpen located, so save new */
0453   B7C911           sta   $C911;   /* cursor position index, and the */
0456   B6C8A3           lda   $C8A3;   /* previous lightpen position.   */
0459   4A               deca;   
045A   B7C910           sta   $C910; 
045D   86FF             lda   #0xFF;   /* Lightpen located */
045F   39               rts;    


		 /*
		  * scan_screen_for_lightpen()
		  *
		  * If the current frame is not filled, then this routine
		  * will perform a full screen scan, in an attempt to 
		  * locate the lightpen.  If the lightpen is located, then
		  * its position is saved in the next location in the vector
		  * list for all 9 frames.
		  *
		  * At entry:
		  *	C917 points to the start of the vector list.
		  *	C8A3 contains index into next available place
		  *	     in the vector list.
		  *
		  * At exit:
		  *	'a' =    0 if lightpen was not located.
		  *	'a' = 0xFF if lightpen was located.
		  */
	 	 scan_screen_for_lightpen:
0460   B6C8A3           lda   $C8A3;   /* See if this frame is already full */
0463   8120             cmpa  #0x20;
0465   2602             bne   P0469; 
0467   4F               clra;   
0468   39               rts;    

0469   BD0721    P0469: jsr   $search_screen_for_lightpen;
046C   4D               tsta;   
046D   2602             bne   P0471; 
046F   4F               clra;          /* Lightpen not found */
0470   39               rts;    

0471   FEC917    P0471: ldu   $C917;   /* Lightpen was found */
0474   F6C8A3           ldb   $C8A3; 
0477   58               aslb;   
0478   AFC5             stx   b,u;     /* Save lightpen location. */
047A   7CC8A3           inc   $C8A3;   /* Increment vector list index. */
047D   8608             lda   #0x08; 
047F   33C5             leau  b,u;   
0481   33C840    P0481: leau  0x40,u;  /* Add this point to each of the */
0484   AF40             stx   0,u;     /* 8 other frames.               */
0486   4A               deca;   
0487   26F8             bne   P0481; 
0489   86FF             lda   #0xFF;   /* Lightpen was found */
048B   39               rts;    


		 /*
		  * find_lightpen_pick()
		  *
		  * This routine draws a dot at each endpoint for every
		  * vector currently defined in the frame vector list.
		  * if a lightpen pick is detected when a dot is drawn,
		  * box will be drawn around that endpoint.  The cross
		  * will be drawn at the last known cursor position.
		  *
		  * At entry:
		  *	C8A3 contains index of next available spot in
		  *	     the vector list.
		  *	C910 contains index of last known cursor position.
		  *
		  * At exit:
		  *	C90F contains index of picked point; 0xFF if
		  *	     no point was picked.
		  *
		  * Work variables:
		  *	C915 flags if a point was already picked.
		  *	C880 contains index into the vector list for the
		  *	     next endpoint to check.
		  *	C881 contains index of picked point.
		  */
		 find_lightpen_pick:
048C   7FC915           clr   $C915;   /* Clear 'point picked' flag */
048F   BDF2A9           jsr   $intensity_to_7F;
0492   7FC880           clr   $C880;   /* Init vector list index to 0 */
0495   86FF             lda   #0xFF; 
0497   B7C881           sta   $C881;   /* Init picked point index to 0 */
049A   B6C880    P049A: lda   $C880; 
049D   B1C8A3           cmpa  $C8A3;   /* See if we're at end of list */
04A0   2607             bne   check_next_endpoint; 
04A2   B6C881           lda   $C881; 
04A5   B7C90F           sta   $C90F;   /* Return index of picked point */
04A8   39               rts;    

		 check_next_endpoint:
04A9   FEC917           ldu   $C917; 
04AC   BDF354           jsr   $reset0ref;
04AF   F6C880           ldb   $C880; 
04B2   F1C910           cmpb  $C910;   /* Get the index for the next point */
04B5   2619             bne   P04D0;   /* to be checked, and see if it equals */
04B7   BEC8A7           ldx   $C8A7;   /* the index of the cursor position. */
04BA   8C0224           cmpx  #animate_handler;    
04BD   2611             bne   P04D0;   /* If so, then draw the cross at this */
04BF   58               aslb;          /* location.                          */
04C0   ECC5             ldd   b,u;   
04C2   BD0EB2           jsr   $am_move_to_d;
04C5   8E052F           ldx   #cross;    
04C8   C610             ldb   #0x10; 
04CA   BD07D6           jsr   $draw_with_pick_check;
04CD   BDF354           jsr   $reset0ref;
04D0   F6C880    P04D0: ldb   $C880; 
04D3   58               aslb;           /* Draw dot at this endpoint, and see */
04D4   ECC5             ldd   b,u;      /* if it was picked by the lightpen */
04D6   FDC882           std   $C882; 
04D9   BD0EB2           jsr   $am_move_to_d;
04DC   8E0A50           ldx   #dot_pattern;    
04DF   C608             ldb   #0x08; 
04E1   BD07D6           jsr   $draw_with_pick_check;
04E4   4D               tsta;           /* Check for a lightpen pick */
04E5   261B             bne   P0502; 
04E7   7DC915           tst   $C915;    /* Ignore, if previous pick occurred */
04EA   2616             bne   P0502; 
04EC   7DC912           tst   $C912;    /* Ignore, if a move is active */
04EF   2611             bne   P0502; 
04F1   8E0192           ldx   #box;     /* Draw a box around this endpoint */
04F4   C610             ldb   #0x10; 
04F6   BD07D6           jsr   $draw_with_pick_check;
04F9   F6C880           ldb   $C880; 
04FC   F7C881           stb   $C881;    /* Save index of picked point. */
04FF   7CC915           inc   $C915;    /* Flag that a pick occurred.  */
0502   7CC880    P0502: inc   $C880; 
0505   2093             bra   P049A;    /* Loop to next point */


		 /*
		  * draw_points_without_pick()
		  *
		  * This routine goes through the vector list for the
		  * current frame, and draws a dot at each endpoint.
		  * Lightpen picks are ignored.
		  */
		 draw_points_without_pick:
0507   7FC880           clr   $C880; 
050A   B6C880    P050A: lda   $C880;   /* Keep processing, until we reach */
050D   B1C8A3           cmpa  $C8A3;   /* the end of the vector list.     */
0510   2601             bne   P0513; 
0512   39               rts;    

0513   FEC917    P0513: ldu   $C917; 
0516   BDF354           jsr   $reset0ref;
0519   F6C880           ldb   $C880; 
051C   58               aslb;   
051D   ECC5             ldd   b,u;   
051F   BD0EB2           jsr   $am_move_to_d;  /* Move to next endpoint, and */
0522   8E0A50           ldx   #dot_pattern;   /* draw a dot there.          */
0525   C608             ldb   #0x08; 
0527   BD07D6           jsr   $draw_with_pick_check;
052A   7CC880           inc   $C880; 
052D   20DB             bra   P050A; 


		 /*
		  * This is a set of move and draw instructions,
		  * which result in a cross being displayed.
		  */
		 cross:
052F   00               .byte 0x00;  /* move */
0530   20               .byte 0x20;
0531   00               .byte 0x00;
0532   FF               .byte 0xFF;  /* draw */
0533   C0               .byte 0xC0;
0534   00               .byte 0x00;
0535   00               .byte 0x00;  /* move */
0536   20               .byte 0x20;
0537   E0               .byte 0xE0;
0538   FF               .byte 0xFF;  /* draw */
0539   00               .byte 0x00;
053A   40               .byte 0x40;
053B   01               .byte 0x01;  /* end of list */


		 /*
		  * draw_all_visible_lines()
		  *
		  * This routine draws all of the visible lines in
		  * the current animate frame.  While these lines are
		  * being drawn, any lightpen picks are saved for later
		  * use.
		  *
		  * 	C8A9 is start of array containing indexes of
		  *	     endpoints for each visible line.
		  *
		  * At exit:
		  *	C915 points to the index pair, in the line array
		  *	     (C8A9), of the vector which was picked; 0xFFFF
		  *	     if none were picked.
		  */
		 draw_all_visible_lines:
053C   CEC8A9           ldu   #0xC8A9;    /* Load addr of line index array */
053F   8EFFFF           ldx   #0xFFFF;    
0542   BFC915           stx   $C915;      /* Init picked vector pointer */
0545   E640      P0545: ldb   0,u;   
0547   2A01             bpl   P054A; 
0549   39               rts;    

054A   C17F      P054A: cmpb  #0x7F; 
054C   2709             beq   P0557; 
054E   BD055B           jsr   $draw_line_between_2_points;
0551   4D               tsta;   	 /* Check to see if a pick occurred, */
0552   2703             beq   P0557;     /* and save a pointer to the endpt  */
0554   FFC915           stu   $C915;     /* index pair in C915, if so.       */
0557   3342      P0557: leau  2,u;   
0559   20EA             bra   P0545; 


		 /*
		  * draw_line_between_2_points()
		  *
		  * Draw a line between the 2 endpoints whose index are
		  * pointed to by the 'u' registe.  These 2 indexes are then
		  * then used to index into the vector list array.  While
		  * drawing the line, check for a lightpen pick.
		  *
		  * At entry:
		  *	'u' points to the index pairs describing the
		  *	    starting and ending points for this line.
		  *	    The indexes are in the following format:
		  *		(ending pt index, starting pt index)
		  *
		  * At exit:
		  *	'a' = 0 => vector was not picked.
		  *	    otherwise, the vector was picked.
		  */
	  	 draw_line_between_2_points:
055B   E640             ldb   0,u;   
055D   58               aslb;   
055E   BEC917           ldx   $C917;  /* Load 'y' with coordinates for */
0561   3185             leay  b,x;    /* line's endpoint.              */
0563   E641             ldb   1,u;   
0565   58               aslb;   
0566   BEC917           ldx   $C917;  /* Load 'x' with coordinates for */
0569   3085             leax  b,x;    /* line's starting point.        */
056B   BD0840           jsr   $draw_vector_with_pick_check;
056E   39               rts;    


		 /*
		  * init_animate_variables()
		  *
		  * This procedure initializes the block of memory
		  * in the range C8A9-C90E to 0xFF.  It is called
		  * when ANIMATE mode is first entered.  This block
		  * of memory contains the line endpoint index pairs
		  * for all visible lines.
		  */
		 init_animate_variables:
056F   8EC8A9           ldx   #0xC8A9;    
0572   86FF             lda   #0xFF; 
0574   A780      P0574: sta   ,x+;   
0576   8CC90F           cmpx  #0xC90F;    
0579   26F9             bne   P0574; 
057B   39               rts;    


		 /*
		  * add_a_new_line()
		  *
		  * This routine adds the index pairs describing the
		  * starting and ending points for a line, to the line
		  * endpoint array, at C8A9-C90C.  If either of the
		  * indexes is 0xFF, or if the indexes are the same, then
		  * this point is not added to the array.  The indexes are
		  * added to the next available location.
		  *
		  * At entry:
		  *	a = ending point index
		  *	b = starting point index
		  *
		  */
		 add_a_new_line:
057C   8EC8A9           ldx   #0xC8A9;    
057F   8CC90D    P057F: cmpx  #0xC90D;    /* Don't bother, if array */
0582   2601             bne   P0585;      /* is full.		    */
0584   39        P0584: rts;    

0585   4D        P0585: tsta;   	  /* Verify that this is a */
0586   2BFC             bmi   P0584;      /* valid set of endpoint */
0588   5D               tstb;             /* indexes.              */
0589   2BF9             bmi   P0584; 
058B   3404             pshs  b;
058D   A1E0             cmpa  ,s+;   
058F   27F3             beq   P0584; 
0591   6D00             tst   0,x;        /* See if spot is empty */
0593   2A03             bpl   P0598; 
0595   ED00             std   0,x;   
0597   39               rts;    

0598   3002      P0598: leax  2,x;        /* Spot is taken, go onto */
059A   20E3             bra   P057F;      /* next entry location.   */


		 /*
		  * play_handler()
		  *
		  * This is the start of the PLAY command handler.
		  * It will cause all currently defined ANIMATE
		  * frames to be played in succession.
		  */
		 play_handler:
059C   B6C91D           lda   $C91D;      /* See if the current frame's */
059F   B1C91E           cmpa  $C91E;      /* display duration has been  */
05A2   2606             bne   P05AA;      /* reached.                   */
05A4   7FC91D           clr   $C91D;      /* Reset duration counter, & goto */
05A7   BD064A           jsr   $get_ptrs_to_playback_frames; /* next frame.  */
05AA   BD06A9    P05AA: jsr   $fill_playback_buffer; /* Display playback buf. */
05AD   8EC933           ldx   #0xC933;    
05B0   BFC917           stx   $C917; 
05B3   BDF2A9           jsr   $intensity_to_7F;
05B6   BD053C           jsr   $draw_all_visible_lines;
05B9   BD0507           jsr   $draw_points_without_pick;
05BC   7CC91D           inc   $C91D;      /* Increment duration counter */
05BF   BD05E8           jsr   $check_playback_speed_buttons;
05C2   BDF354           jsr   $reset0ref;
05C5   B6C80F           lda   $C80F;      /* If button 1 or 2 is pressed, */
05C8   8403             anda  #0x03;      /* then enter the EDIT portion  */
05CA   2706             beq   P05D2;      /* of the ANIMATE code.         */
05CC   8E02C7           ldx   #edit_handler;    
05CF   BFC8A7           stx   $C8A7; 
05D2   39        P05D2: rts;    


		 /*
		  * init_play_variables()
		  *
		  * This routine is invoked when the user initiates
		  * an animate 'PLAY' request.  It will initialize
		  * some of the globals used by the PLAY routines.
		  */
		 init_play_variables:
05D3   7FC91D           clr   $C91D;    /* Clear frame duration counter. */
05D6   8604             lda   #0x04; 
05D8   B7C929           sta   $C929;    /* Set default playback speed.   */
05DB   BD061D           jsr   $update_playback_variables;
05DE   7FC920           clr   $C920;    /* Set up to display 1st frame.  */
05E1   7FC921           clr   $C921;    /* Direction flag:0=>frwd,1=>bckwd */
05E4   BD064A           jsr   $get_ptrs_to_playback_frames;
05E7   39               rts;    


		 /*
		  * check_playback_speed_buttons()
		  *
		  * This routine monitors buttons 3 (slow) and
		  * 4 (fast) during the PLAY mode portion of the
		  * animate option.  The current playback speed is
		  * kept in C929; 0 = fastest, 7 = slowest.
		  */
		 check_playback_speed_buttons:
05E8   7DC814           tst   $C814; 
05EB   2606             bne   decrease_playback_speed; 
05ED   7DC815           tst   $C815; 
05F0   2617             bne   increase_playback_speed; 
05F2   39               rts;    

		 /*
		  * decrease_playback_speed()
		  *
		  * Decrease the playback speed (by incrementing C929)
		  */
		 decrease_playback_speed:
05F3   B6C929           lda   $C929; 
05F6   8107             cmpa  #0x07; 
05F8   2601             bne   P05FB; 
05FA   39               rts;    
05FB   7CC929    P05FB: inc   $C929; 
05FE   B6C91D           lda   $C91D; 
0601   48               asla;          /* Increase duration counter for */
0602   B7C91D           sta   $C91D;   /* this frame.                   */
0605   BD061D           jsr   $update_playback_variables;
0608   39               rts;    

		 /*
		  * increase_playback_speed()
		  *
		  * Increase the playback speed (by decrementing C929)
		  */
		 increase_playback_speed:
0609   7DC929           tst   $C929; 
060C   2601             bne   P060F; 
060E   39               rts;    
060F   7AC929    P060F: dec   $C929; 
0612   B6C91D           lda   $C91D; 
0615   47               ASRA;          /* Decrease duration counter */
0616   B7C91D           sta   $C91D;   /* for this frame.           */
0619   BD061D           jsr   $update_playback_variables;
061C   39               rts;    


		 /*
		  * update_playback_variables()
		  *
		  * This routine uses the current playback speed, in C929,
		  * to index into the structure at 0632 (playback_speed_info).
		  * From this structure, two values are obtained: a 1 byte bit
		  * pattern, and a two byte jump address.  These two
		  * values are used by the playback routines.
		  */
		 update_playback_variables:
061D   8E0632           ldx   #playback_speed_info;    
0620   F6C929           ldb   $C929; 
0623   8603             lda   #0x03; 
0625   3D               mul;    
0626   3A               abx;    
0627   A680             lda   ,x+;   
0629   B7C91E           sta   $C91E; 
062C   EC81             ldd   ,x++;  
062E   FDC922           std   $C922; 
0631   39               rts;    

		 /*
		  * Table with the following format:
		  *
		  *	1 byte value
		  *	2 byte subroutine address.
		  *
		  * The information here is used during the PLAY 
		  * mode of ANIMATE.  The playback speed (in C929)
		  * is used to index into this structure.  An index
		  * of 7 is for slowest playback, and an index of 0
		  * is for fastest playback.
		  */
		 playback_speed_info:
0632   01               .byte 0x01;
0633   07               .word 0x0720;
0635   02               .byte 0x02;
0636   07               .word 0x071E;
0638   04               .byte 0x04;
0639   07               .word 0x071C;
063B   08               .byte 0x08;
063C   07               .word 0x071A;
063E   10               .byte 0x10;
063F   07               .word 0x0718;
0641   20               .byte 0x20;
0642   07               .word 0x0716;
0644   40               .byte 0x40;
0645   07               .word 0x0714;
0647   80               .byte 0x80;
0648   07               .word 0x0712;


		 /*
		  * get_ptrs_to_playback_frames()
		  *
		  * This routine is used during the playback mode portion
		  * of animate.  If loads C924 with a pointer to the
		  * frame buffer for the current buffer, and C926 with a
		  * a pointer to the frame buffer for the next buffer to
		  * be displayed.  It will then increment the buffer index,
		  * in C920.
		  *
		  * At entry:
		  *	C920 contains the index of the current frame.
		  *
		  * At exit:
		  *	C920 is incremented to index next frame.
		  *	C924 points to frame buffer for current frame.
		  *	C926 points to frame buffer for next frame.
		  *
		  */
		 get_ptrs_to_playback_frames:
064A   B6C920           lda   $C920;   /* Load index of current frame. */
064D   B7C91F           sta   $C91F; 
0650   BD067F           jsr   $update_play_index_to_next_frame;
0653   8E0669           ldx   #frame_buf_pointers;    
0656   B6C91F           lda   $C91F; 
0659   48               asla;   
065A   EC86             ldd   a,x;     /* Load C924 with ptr to frame buf */
065C   FDC924           std   $C924;   /* for the current frame.          */
065F   B6C920           lda   $C920; 
0662   48               asla;   
0663   EC86             ldd   a,x;     /* Load C926 with ptr to frame buf */
0665   FDC926           std   $C926;   /* for the next frame.             */
0668   39               rts;    


		 /*
		  * This is an array of word pointers.  These point
		  * to the beginning of the buffer area associated
		  * with each of the animate frames.  Each frame is
		  * 64 bytes long.
		  */
		 frame_buf_pointers:
0669   C9               .word 0xC977;
066B   C9               .word 0xC9B7;
066D   C9               .word 0xC9F7;
066F   CA               .word 0xCA37;
0671   CA               .word 0xCA77;
0673   CA               .word 0xCAB7;
0675   CA               .word 0xCAF7;
0677   CB               .word 0xCB37;
0679   CB               .word 0xCB77;
067B   CB               .word 0xCBB7;
067D   CB               .word 0xCBF7;


		 /*
		  * update_play_index_to_next_frame()
		  *
		  * This routine updates the frame index (C920),
		  * to index the next frame to be displayed.  If we
		  * are currently displaying in the forward direction,
		  * then this will be incremented.  If we are currently
		  * displaying in the backward direction, then this will
		  * be decremented.  If we reach the first/last frame,
		  * then the direction will be changed.
		  */
		 update_play_index_to_next_frame:
067F   7DC921           tst   $C921;  /* Check 4 frwd/bkwd display order. */
0682   2615             bne   backward_order; 
0684   B6C920           lda   $C920;  /* Increment, if not at last frame. */
0687   B1C8A6           cmpa  $C8A6; 
068A   2704             beq   start_backwards; 
068C   7CC920           inc   $C920; 
068F   39               rts;    

		 start_backwards:
0690   86FF             lda   #0xFF;  /* Set direction flag to 'backwards'. */
0692   B7C921           sta   $C921; 
0695   7AC920           dec   $C920;  /* Decrement to previous frame. */
0698   39               rts;    

		 backward_order:
0699   7DC920           tst   $C920;  /* Decrement, if not at first frame. */
069C   2704             beq   start_forward; 
069E   7AC920           dec   $C920; 
06A1   39               rts;    

		 start_forward
06A2   7FC921           clr   $C921;  /* Set direction flag to 'forwards'. */
06A5   7CC920           inc   $C920;  /* Increment to next frame.          */
06A8   39               rts;    


		 /*
		  * fill_playback_buffer()
		  *
		  * This routine fills the playback buffer (C933-????)
		  * with the (y,x) coordinate pairs for the currently
		  * visible frame.  It does this by taking each coordinate
		  * in the current frame, and the corresponding coordinate
		  * in the next frame, and doing some sort of extrapolation
		  * on them, to end up with the final endpoint.
		  *
		  * At entry:
		  *	C924 points to frame buffer for current frame.
		  *	C926 points to frame buffer for next frame.
		  *	C933 is start of playback buffer.
		  *	C8A3 specifies number of defined points in a frame.
		  *
		  */
		 fill_playback_buffer:
06A9   BEC924           ldx   $C924;    /* Pointer to current frame. */
06AC   10BEC926         ldy   $C926;    /* Ptr to next (transition) frame. */
06B0   CEC933           ldu   #0xC933;  /* Addr of playback buffer.  */ 
06B3   B6C8A3           lda   $C8A3;    /* # of points in frame buffer. */
06B6   B7C880           sta   $C880; 
06B9   7DC880    P06B9: tst   $C880; 
06BC   271D             beq   P06DB; 
06BE   A680             lda   ,x+;      /* Load both 'y' coordinates. */
06C0   E6A0             ldb   ,y+;   
06C2   FDC82E           std   $C82E; 
06C5   BD06DC           jsr   $merge_coordinates;
06C8   E7C0             stb   ,u+;      /* Save final 'y' coordinate. */
06CA   A680             lda   ,x+;      /* Load both 'x' coordinates. */
06CC   E6A0             ldb   ,y+;   
06CE   FDC82E           std   $C82E; 
06D1   BD06DC           jsr   $merge_coordinates;
06D4   E7C0             stb   ,u+;      /* Save final 'x' coordinate. */
06D6   7AC880           dec   $C880; 
06D9   20DE             bra   P06B9; 
06DB   39        P06DB: rts;    


		 /*
		  * merge_coordinates()
		  *
		  * This routine takes a pair of coordinates (2 'x' or
		  * 2 'y') and extrapolates a new value.  This new coordinate
		  * is what is displayed by the playback routine.
		  *
		  * At entry:
		  *	C82E has coordinate for current frame.
		  *	C82F has coordinate for next frame.
		  *
		  * At exit:
		  *	'b' contains modified coordinate.
		  */
		 merge_coordinates:
06DC   F6C82E           ldb   $C82E;   /* Get coord for current frame. */
06DF   1D               sex;    
06E0   3406             pshs  a,b;   
06E2   F6C82F           ldb   $C82F;   /* Get coord for next frame. */
06E5   1D               sex;    
06E6   A3E1             subd  ,s++;  
06E8   2A17             bpl   P0701; 
06EA   50               negb;   
06EB   B6C91D           lda   $C91D; 
06EE   3D               mul;    
06EF   AD9FC922         jsr   [0xC922];
06F3   43               coma;   
06F4   53               comb;   
06F5   C30001           addd  #0x0001;    
06F8   3406             pshs  a,b;   
06FA   F6C82E           ldb   $C82E; 
06FD   1D               sex;    
06FE   E3E1             addd  ,s++;  
0700   39               rts;    

0701   B6C91D    P0701: lda   $C91D; 
0704   3D               mul;    
0705   AD9FC922         jsr   [0xC922];
0709   3406             pshs  a,b;   
070B   F6C82E           ldb   $C82E; 
070E   1D               sex;    
070F   E3E1             addd  ,s++;  
0711   39               rts;    


0712   47        P0712: ASRA;   
0713   56               rorb;   
0714   47        P0714: ASRA;   
0715   56               rorb;   
0716   47        P0716: ASRA;   
0717   56               rorb;   
0718   47        P0718: ASRA;   
0719   56               rorb;   
071A   47        P071A: ASRA;   
071B   56               rorb;   
071C   47        P071C: ASRA;   
071D   56               rorb;   
071E   47        P071E: ASRA;   
071F   56               rorb;   
0720   39        P0720: rts;    


		 /*
		  * search_screen_for_lightpen()
		  *
		  * This routine attempts to locate the location of the
		  * lightpen, by drawing a series of horizontal scan lines.
		  * Starting from the bottom of the display, a series of
		  * lines are drawn, until either a lightpen pick occurs,
		  * or the last scan line is drawn.  If a lightpen pick
		  * occurs, then that particular scan line will again be
		  * drawn, only this time, interrupts will be enabled, so
		  * that the exact location of the pick can be determined.
		  *
		  * At exit:
		  *	'a' =    0 if lightpen was not located.
		  *	'a' = 0xFF if lightpen was located.
		  *
		  * Work variables:
		  *	C881 contains the number of scan lines left to draw.
		  *	C882-C883 contain starting point for next scan line.
		  */
		 search_screen_for_lightpen:
0721   867A             lda   #0x7A;  
0723   B7C881           sta   $C881;    /* Init # of scan lines to draw */
0726   CC8880           ldd   #0x8880;    
0729   FDC882           std   $C882;    /* Init start pt for first scan line */
072C   7DC881    P072C: tst   $C881; 
072F   2605             bne   draw_scan_line; 
0731   BDF354           jsr   $reset0ref;
0734   4F               clra;           /* If we make it to here, then the */
0735   39               rts;            /* lightpen was not found.         */

		 draw_scan_line:
0736   BDF354           jsr   $reset0ref;
0739   FCC882           ldd   $C882;    /* Move to start of scan line */
073C   BDF2FC           jsr   $move_pen7F_to_d;
073F   0F01             clr   0x01;  
0741   0F00             clr   0x00;  
0743   C6FF             ldb   #0xFF; 
0745   D704             stb   0x04;  
0747   0C00             inc   0x00;  
0749   867F             lda   #0x7F; 
074B   9701             sta   0x01;  
074D   CCFF40           ldd   #0xFF40;    
0750   970A             sta   0x0A;     /* Use solid line pattern. */
0752   0F05             clr   0x05;  
0754   D50D      P0754: bitb  0x0D;  
0756   27FC             beq   P0754; 
0758   0F0A             clr   0x0A;  
075A   8602             lda   #0x02;    /* Check for a lightpen pick */
075C   950D             bita  0x0D;  
075E   260D             bne   find_point_of_intersection; 
0760   7AC881           dec   $C881;    /* No lightpen pick, so continue */
0763   B6C882           lda   $C882;    /* to draw the next scan line.   */
0766   8B02             adda  #0x02;    /* Draw on everyother horz line. */
0768   B7C882           sta   $C882; 
076B   20BF             bra   P072C; 


		 /*
		  * find_point_of_intersection()
		  *
		  * This routine is responsible for locating the exact
		  * location of the lightpen, after a pick has occurred
		  * while a scan line was being drawn.  It does this in
		  * the following manner:
		  *
		  *	The pen is moved back to the start of the previous
		  *	scan line, and lightpen interrupts are enabled.
		  *	Next, the scan line is redrawn; while this is going
		  *	on, a timing (counter) loop is executed.  If the
		  *	timing loop completes, then it implies that the
		  *	lightpen was not located; interrupts will be disabled,
		  *	and control will return to the procedure which had
		  *	originally invoked the scan line routine.
		  *	However, if the lightpen interrupts, then the timing
		  *	loop is interrupted, and the ISR handling routine is
		  *	called.  This handler will calculate the exact location
		  *	of the lightpen, using the value in the counter.  If
		  *	an interrupt occurs, control will never return to
		  *	this routine; control returns directly to the routine
		  *	which had invoked the scan line routine.  The location
		  *	of the 'pick' is returned in the 'x' register.
		  */
		 find_point_of_intersection:
076D   BDF354           jsr   $reset0ref;
0770   FCC882           ldd   $C882;   /* Move to start of scan line */
0773   BDF2FC           jsr   $move_pen7F_to_d;
0776   1CEF             andcc #0xEF;   /* Enable IRQ on 6809 */
0778   8682             lda   #0x82;   /* Enable CA1 on PIA  */
077A   970E             sta   0x0E;  
077C   867E             lda   #0x7E;   /* Set up IRQ handler */
077E   B7CBF8           sta   $CBF8; 
0781   CC07CE           ldd   #ISR_handler;    
0784   FDCBF9           std   $CBF9;  
0787   0F01             clr   0x01;    /* Redraw the scan line */
0789   0F00             clr   0x00;  
078B   0F04             clr   0x04;  
078D   12               nop;    
078E   0C00             inc   0x00;  
0790   8620             lda   #0x20;
0792   9701             sta   0x01;  
0794   86FF             lda   #0xFF; 
0796   970A             sta   0x0A;  
0798   C67F             ldb   #0x7F; 
079A   8605             lda   #0x05; 
079C   9705             sta   0x05;  
079E   5A        P079E: decb;          /* Wait for interrupt; counter loop */
079F   21FD             brn   P079E; 
07A1   26FB             bne   P079E; 
07A3   0F05             clr   0x05;  
07A5   BD07AA           jsr   $disable_interrupts;
07A8   4F               clra;          /* Lightpen not found */
07A9   39               rts;    


		 /*
		  * disable_interrupts()
		  *
		  * This routine is responsible for disabling lightpen
		  * interrupts.
		  */
07AA   4F               clra;   
07AB   970E             sta   0x0E;  /* Disable CA1 on PIA */
07AD   9701             sta   0x01;  
07AF   970D             sta   0x0D;  
07B1   1A10             orcc  #0x10; /* Disable IRQ on 6809 */
07B3   BDF354           jsr   $reset0ref;
07B6   39               rts;    


		 /*
		  * process_ISR()
		  *
		  * This procedure performs most of the work involved,
		  * whenever the lightpen generates an interrupt.  It
		  * uses the counter value, in the 'b' register, to 
		  * calculate the x coordinate of the lightpen.  The
		  * intersection point is returned in the 'x' register.
		  * This routine returns to the routine which invoked
		  * the scan line search routine.
		  */
		 process_ISR:
07B7   030A             com   0x0A;  
07B9   0F05             clr   0x05;  
07BB   C07F             subb  #0x7F;   /* Calculate x coordinate */
07BD   50               negb;   
07BE   58               aslb;   
07BF   1D               sex;    
07C0   830080           subd  #0x0080;    
07C3   B6C882           lda   $C882;   /* Retrieve y coordinate */
07C6   1F01             tfr   d,x;   
07C8   BD07AA           jsr   $disable_interrupts;
07CB   86FF             lda   #0xFF;   /* Lightpen found */
07CD   39               rts;    


		 /*
		  * ISR_handler()
		  *
		  * This is the entry point called by the OS, whenever the
		  * lightpen generates an IRQ interrupt.  This procedure
		  * discards the 12 bytes of saved state information
		  * placed on the stack by the 6809, including the return
		  * address for the interrupted routine.  Then it calls the
		  * process_ISR() routine, to process the IRQ request.
		  */
	         ISR_handler:
07CE   030A             com   0x0A;  
07D0   326C             leas  12,s;  
07D2   7E07B7           jmp   $process_ISR;
07D5   12               .byte 0x12;


		 /*
		  * draw_with_pick_check(vector_list, scale)
		  *
		  * This procedure will perform a series of move and
		  * draw requests, as specified in the passed in vector
		  * list.  The vector list must have the following format:
		  *
		  *	mode, rel y, rel x
		  *      |      |       |
		  *      |      |       relative x position
		  *      |      relative y positon
		  *      FF - draw
		  *       0 - move
		  *       1 - end o list
		  *
		  * NOTE: the mode also acts as the line pattern.
		  *
		  * At entry: 'x' contains pointer to the vector list.
		  *           'b' contains the scale factor to be used.
		  *
		  * At exit:  'a' contains the index of the point being
		  *               drawn when the lightpen detected a pick.
		  *               0xFF if no pick occurred.
		  */
		 draw_with_pick_check:
07D6   6F7F             clr   -1,s;   /* Temporary storage of current pt # */
07D8   86FF             lda   #0xFF; 
07DA   A77E             sta   -2,s;   /* Temporary storage of last pt picked */
07DC   D704             stb   0x04;  
07DE   EC01      P07DE: ldd   1,x;   
07E0   9701             sta   0x01;   /* Set rel y position. */
07E2   0F00             clr   0x00;  
07E4   A600             lda   0,x;    /* Get the mode. */
07E6   3003             leax  3,x;    /* Increment ptr to next entry. */
07E8   0C00             inc   0x00;  
07EA   D701             stb   0x01;   /* Set rel x position. */
07EC   970A             sta   0x0A;   /* Set line pattern.   */
07EE   0F05             clr   0x05;  
07F0   CC0040           ldd   #0x0040;    
07F3   D50D      P07F3: bitb  0x0D;  
07F5   27FC             beq   P07F3; 
07F7   1E11             exg   x,x;   
07F9   970A             sta   0x0A;  
07FB   960D             lda   0x0D;   /* Check for a lightpen pick  */
07FD   8402             anda  #0x02; 
07FF   2704             beq   P0805; 
0801   A67F             lda   -1,s;  
0803   A77E             sta   -2,s;   /* Save the current pt #.     */
0805   6C7F      P0805: inc   -1,s;   /* Increment the current pt # */
0807   A600             lda   0,x;   
0809   2FD3             ble   P07DE; 
080B   A67E             lda   -2,s;   /* Return index if any pt picked. */
080D   39               rts;    


		 /*
		  * This routine appears to not be used anywhere!!
		  */
080E   A77E      P080E: sta   -2,s;  
0810   6F7F             clr   -1,s;  
0812   D704             stb   0x04;  
0814   EC01      P0814: ldd   1,x;   
0816   9701             sta   0x01;  
0818   0F00             clr   0x00;  
081A   A600             lda   0,x;   
081C   3003             leax  3,x;   
081E   0C00             inc   0x00;  
0820   D701             stb   0x01;  
0822   E67E             ldb   -2,s;  
0824   E17F             cmpb  -1,s;  
0826   2702             beq   P082A; 
0828   5F               clrb;   
0829   4F               clra;   
082A   970A      P082A: sta   0x0A;  
082C   0F05             clr   0x05;  
082E   CC0040           ldd   #0x0040;    
0831   D50D      P0831: bitb  0x0D;  
0833   27FC             beq   P0831; 
0835   1E11             exg   x,x;   
0837   970A             sta   0x0A;  
0839   6C7F             inc   -1,s;  
083B   A600             lda   0,x;   
083D   2FD5             ble   P0814; 
083F   39               rts;    


		 /*
		  * draw_vector_with_pick_check()
		  *
		  * This routine draws a vector, starting at (y,x) endpoint
		  * pointed to by the 'x' register, to the (y,x) endpoint
		  * pointed to by the 'y' register.  A value is returned
		  * which indicates whether or not a lightpen pick occurred
		  * while the vector was being drawn.
		  *
		  * At entry:
		  *	'x' points to (y,x) pair for starting point.
		  *	'y' points to (y,x) pair for ending point.
		  *
		  * At exit:
		  *	'a' = 0 => no pick
		  *		   otherwise a pick occurred.
		  */
		 draw_vector_with_pick_check:
0840   BDF354           jsr   $reset0ref;
0843   86FF             lda   #0xFF; 
0845   B7C880           sta   $C880; 
0848   8601             lda   #0x01; 
084A   B7C883           sta   $C883; 
084D   A600             lda   0,x;     /* Move to starting point */
084F   9701             sta   0x01;  
0851   0F00             clr   0x00;  
0853   A601             lda   1,x;   
0855   C67F             ldb   #0x7F; 
0857   D704             stb   0x04;  
0859   C6CE             ldb   #0xCE; 
085B   D70C             stb   0x0C;  
085D   0C00             inc   0x00;  
085F   9701             sta   0x01;  
0861   0F05             clr   0x05;  
0863   BD0879           jsr   $calculate_vector_endpoint;
0866   8E08E7           ldx   #am_scale_factors;    
0869   E685             ldb   b,x;   
086B   8640             lda   #0x40;
086D   950D      P086D: bita  0x0D;  
086F   27FC             beq   P086D; 
0871   8EC880           ldx   #0xC880;    
0874   BD07D6           jsr   $draw_with_pick_check;
0877   43               coma;   
0878   39               rts;    


		 /*
		  * calculate_vector_endpoint()
		  *
		  * This routine takes an absolute starting point, and an
		  * absolute ending point, and calculates the relative
		  * (y,x) pair for the vector between these two points.
		  * It also returns an index into the scale factor array, 
		  * indicating which scale factor should be used when
		  * drawing the vector.
		  *
		  * At entry:
		  *	'y' points to (y,x) endpoint.
		  *	'x' points to (y,x) starting point.
		  *
		  * At exit:
		  *	C881-C882 contain relative (y,x) endpoint.
		  *	'b' contains the index of the scale factor to use.
		  */
		 calculate_vector_endpoint:
0879   A620             lda   0,y;    /* Determine delta y. */
087B   A000             suba  0,x;   
087D   10290039         lbvs  P08BA; 
0881   E621             ldb   1,y;    /* Determine delta x. */
0883   E001             subb  1,x;   
0885   10290031         lbvs  P08BA; 
0889   FDC881           std   $C881; 
088C   BDF584           jsr   $get_absolute_value_of_ab;
088F   3404             pshs  b;
0891   A1E0             cmpa  ,s+;   
0893   2402             bhs   P0897; 
0895   1F98             tfr   b,a;   
0897   813F      P0897: cmpa  #0x3F;
0899   2303             bls   P089E; 
089B   C602             ldb   #0x02; 
089D   39               rts;    

089E   811F      P089E: cmpa  #0x1F; 
08A0   230B             bls   P08AD; 
08A2   FCC881           ldd   $C881; 
08A5   48               asla;   
08A6   58               aslb;   
08A7   FDC881           std   $C881; 
08AA   C603             ldb   #0x03; 
08AC   39               rts;    

08AD   FCC881    P08AD: ldd   $C881; 
08B0   48               asla;   
08B1   48               asla;   
08B2   58               aslb;   
08B3   58               aslb;   
08B4   FDC881           std   $C881; 
08B7   C604             ldb   #0x04; 
08B9   39               rts;    

08BA   E600      P08BA: ldb   0,x;   
08BC   1D               sex;    
08BD   3406             pshs  a,b;   
08BF   E620             ldb   0,y;   
08C1   1D               sex;    
08C2   A3E1             subd  ,s++;  
08C4   3406             pshs  a,b;   
08C6   E601             ldb   1,x;   
08C8   1D               sex;    
08C9   3406             pshs  a,b;   
08CB   E621             ldb   1,y;   
08CD   1D               sex;    
08CE   A3E1             subd  ,s++;  
08D0   44               lsra;   
08D1   56               rorb;   
08D2   1F01             tfr   d,x;   
08D4   3506             puls  a,b;   
08D6   44               lsra;   
08D7   56               rorb;   
08D8   1F02             tfr   d,y;   
08DA   1F20             tfr   y,d;   
08DC   F7C881           stb   $C881; 
08DF   1F10             tfr   x,d;   
08E1   F7C882           stb   $C882; 
08E4   C601             ldb   #0x01; 
08E6   39               rts;    


		 am_scale_factors:
08E7   00               .byte 0x00;
08E8   FF               .byte 0xFF;
08E9   7F               .byte 0x7F;
08EA   3E               .byte 0x3E;
08EB   1E               .byte 0x1E;

08EC   0D               .byte 0x0D;

		 /*
		  * set_cursor_structure (cursor_ptr, data_ptr)
		  *
		  * This routine appears to copy the data pointer to
		  * by the 'x' register into the cursor structure, which
		  * is pointed to by the 'u' register.
		  * The cursor struct is 12 bytes long, and is laid out
		  * as follows:
		  *
		  *	************************
		  *     * cursor rel y pos     *
		  *     ************************
		  *     * cursor rel x pos     *
		  *     ************************
		  *     * found this pass flag *
		  *     ************************\
		  *     * cursor y delta       * \
		  *     ************************  > Used when moving cursor
		  *     * cursor x delta       * /  to follow light pen
		  *     ************************/
		  *     * found last pass flag *
		  *     ************************
		  *     * max y position       *
		  *     ************************
		  *     * min x position       *
		  *     ************************
		  *     * min y position       *
		  *     ************************
		  *     * max x position       *
		  *     ************************
		  *     * ptr to line pattern  *
		  *     ** array used when    **
		  *     * drawing search webs  *
		  *     ************************
		  */
		 set_cursor_structure:
08ED   EC81             ldd   ,x++;  
08EF   ED40             std   0,u;   
08F1   EC81             ldd   ,x++;  
08F3   ED46             std   6,u;   
08F5   EC81             ldd   ,x++;  
08F7   ED48             std   8,u;   
08F9   CC0A54           ldd   #whole_search_pattern;    
08FC   ED4A             std   10,u;  
08FE   6F45             clr   5,u;   
0900   39               rts;    


		 /*
		  * update_cursor_position()
		  *
		  * This routine attempts to move the cursor so that
		  * it 'stays' with  the lightpen.  First, it sees if
		  * the lightpen is still within 'sight' of the cursor.
		  * This is done by draw a series of 'spider web' patterns,
		  * until the lightpen is found, or the max web is drawn.
		  * Then it takes the deltas calculated by the search routine,
		  * adds them to the current cursor position, performs some
		  * bounds checks, and updates the line patterns used when
		  * drawing the search webs.
		  */
		 update_cursor_position:
0901   BD0984           jsr   $find_lightpen;  /* Try to find lightpen. */
0904   A642             lda   2,u;     /* Proceed only if the lightpen */
0906   81FF             cmpa  #0xFF;   /* is currently at the cursor. */
0908   2679             bne   P0983; 
090A   E640             ldb   0,u;     /* Get y position, & extend to 16 bits */
090C   1D               sex;    
090D   3406             pshs  a,b;   
090F   E643             ldb   3,u;     /* Get new y delta */
0911   1D               sex;    
0912   E3E1             addd  ,s++;    /* Add together */
0914   3406             pshs  a,b;   
0916   E646             ldb   6,u;     /* Compare new coordinate to max y */
0918   1D               sex;           /* value.  Use max y value, if new */
0919   10A360           cmpd  0,s;     /* coordinate is too big.          */
091C   2E0D             bgt   P092B; 
091E   3262             leas  2,s;   
0920   8E0A5E           ldx   #lower_search_pattern;    
0923   AF4A             stx   10,u;    /* Use lower search pattern */
0925   A646             lda   6,u;   
0927   A740             sta   0,u;   
0929   201E             bra   P0949; 

092B   E648      P092B: ldb   8,u;     /* Compare new coordinate to min y */
092D   1D               sex;           /* value.  Use min y value if new  */
092E   10A360           cmpd  0,s;     /* cordinate is too small.         */
0931   2D0D             blt   P0940; 
0933   3262             leas  2,s;   
0935   8E0A68           ldx   #upper_search_pattern;    
0938   AF4A             stx   10,u;    /* Use upper search pattern */
093A   A648             lda   8,u;   
093C   A740             sta   0,u;   
093E   2009             bra   P0949; 

0940   ECE1      P0940: ldd   ,s++;    /* Save new y coordinate in the */
0942   E740             stb   0,u;     /* cursor structure.            */
0944   8E0A54           ldx   #whole_search_pattern;    
0947   AF4A             stx   10,u;    /* Use whole search pattern. */
0949   E641      P0949: ldb   1,u;     /* Load current x coordinate, and */
094B   1D               sex;           /* extend it to 16 bits.          */
094C   3406             pshs  a,b;   
094E   E644             ldb   4,u;   
0950   1D               sex;    
0951   E3E1             addd  ,s++;    /* Add the new x delta. */
0953   3406             pshs  a,b;   
0955   E649             ldb   9,u;     /* Compare new x coordinate to max x */
0957   1D               sex;           /* value.  Use max value if new coord */
0958   10A360           cmpd  0,s;     /* is too big.                       */
095B   2E0D             bgt   P096A; 
095D   3262             leas  2,s;   
095F   8E0A7C           ldx   #left_search_pattern;    
0962   AF4A             stx   10,u;    /* Use left search pattern */
0964   A649             lda   9,u;   
0966   A741             sta   1,u;   
0968   2019             bra   P0983; 

096A   E647      P096A: ldb   7,u;     /* Compare new coordinate to min x */
096C   1D               sex;           /* value.  Use min value, if new   */
096D   10A360           cmpd  0,s;     /* coordinate is too small.        */
0970   2D0D             blt   P097F; 
0972   3262             leas  2,s;   
0974   8E0A72           ldx   #right_search_pattern;    
0977   AF4A             stx   10,u;    /* Use right search pattern */
0979   A647             lda   7,u;   
097B   A741             sta   1,u;   
097D   2004             bra   P0983; 

097F   ECE1      P097F: ldd   ,s++;    /* Save new x coordinate */
0981   E741             stb   1,u;   
0983   39        P0983: rts;    


		 /*
		  * find_lightpen()
		  *
		  * This routine is used by a portion of the animate code
		  * to locate the lightpen, so that the cursor may track
		  * it.  It does this in the following manner:
		  *
		  *	Firstly, it moves to the last known location of
		  *	the cursor, and draws a dot.  It a lightpen pick
		  *	occurs, then no further searching is needed; the
		  *	lightpen has not moved.  However, if the lightpen
		  *	has moved, then we must perform a more extensive
		  *	search.  However, if the lightpen was not found
		  *	the last time we searched for it, then we won't
		  *	bother searching for it now; we don't want to 
		  *	continually clutter the screen with our search
		  *	patterns!
		  *
		  *	Secondly, we will draw a series of ever increasing
		  *	8 sided spider webs.  If, while drawing one of these
		  *	search patterns, a lightpen pick is detected, then
		  *	we will determine which vector of the pattern was
		  *	picked, and we will calculate a cursor movement
		  *	delta dependent upon the scale factor used and the
		  *	vector picked.
		  *
		  *	Depending upon the vector picked, the base delta
		  *	value will be either -1, 0, or +1.  This will then
		  *	be multiplied by a scale value, which is obtained
		  *	by using the scale factor index to index into a
		  *	multiplier array.  The new deltas are saved in the
		  *	cursor structure.
		  */
		 find_lightpen:
0984   6F42             clr   2,u;     /* Clear "found this pass" flag */
0986   BDF2A9           jsr   $intensity_to_7F;
0989   BDF354           jsr   $reset0ref;
098C   EC40             ldd   0,u;     /* Move to last known location */
098E   BDF2FC           jsr   $move_pen7F_to_d;
0991   8E0A50           ldx   #dot_pattern; /* Draw a dot; check for pick */
0994   C604             ldb   #0x04; 
0996   BD07D6           jsr   $draw_with_pick_check;
0999   4D               tsta;   
099A   2607             bne   search_4_lightpen; 
099C   6C42             inc   2,u;     /* Lightpen was found */
099E   86FF             lda   #0xFF; 
09A0   A745             sta   5,u;   
09A2   39               rts;    

		 search_4_lightpen:
09A3   6D45             tst   5,u;     /* Don't bother searching if lightpen */
09A5   2601             bne   continue_lightpen_search;   /* wasn't found */
09A7   39               rts;                              /* last pass. */

		 continue_lightpen_search:
09A8   BDF354           jsr   $reset0ref;  /* Draw the spider web, with an */
09AB   8E0A86           ldx   #small_search_pattern_vl; /* increasing scale */
09AE   A642             lda   2,u;         /* factor, until either the light */
09B0   8104             cmpa  #0x04;       /* pen is found, or the last scale */
09B2   2D03             blt   P09B7;       /* factor is reached.           */
09B4   8E0A98           ldx   #large_search_pattern_vl;    
09B7   EC40      P09B7: ldd   0,u;   
09B9   BDF2FC           jsr   $move_pen7F_to_d;
09BC   108E0AC4         ldy   #search_pattern_scale_factors;    
09C0   A642             lda   2,u;   
09C2   E6A6             ldb   a,y;   
09C4   2608             bne   draw_search_pattern; 
09C6   BDF354           jsr   $reset0ref;
09C9   6F42             clr   2,u;          /* Flag that cursor is 'lost' */
09CB   6F45             clr   5,u;          /* to the lightpen.           */
09CD   39               rts;    

		 draw_search_pattern:
09CE   10AE4A           ldy   10,u;    /* Get line pattern array pointer */
09D1   BD0A13           jsr   $display_search_pattern;
09D4   81FF             cmpa  #0xFF;   /* Check for a pick. */
09D6   2604             bne   lightpen_found; 
09D8   6C42             inc   2,u;     /* Increment the scale factor. */
09DA   20C7             bra   search_4_lightpen; 

		 lightpen_found:
09DC   8E0AAA           ldx   #cursor_deltas;    
09DF   4A               deca;          /* Decrement the index of the picked */
09E0   48               asla;          /* point, & convert to word index.   */
09E1   EC86             ldd   a,x;     /* Load x & y delta values, and save */
09E3   ED43             std   3,u;     /* in the cursor structure.          */
09E5   8E0ABA           ldx   #delta_multipliers;    
09E8   E642             ldb   2,u;     /* Use the scale factor index to get */
09EA   A685             lda   b,x;     /* the correct delta multiplier.     */
09EC   3402             pshs  a;
09EE   E643             ldb   3,u;     /* Generate new y delta. */
09F0   BD0A05           jsr   $generate_new_cursor_coordinate;
09F3   E743             stb   3,u;   
09F5   3502             puls  a;
09F7   E644             ldb   4,u;     /*  Generate new x delta. */
09F9   BD0A05           jsr   $generate_new_cursor_coordinate;
09FC   E744             stb   4,u;   
09FE   86FF             lda   #0xFF;   /* Flag that the cursor is picked */
0A00   A742             sta   2,u;   
0A02   A745             sta   5,u;   
0A04   39               rts;    


		 /*
		  * generate_new_cursor_coordinate()
		  *
		  * This routine calulates the new cursor delta,
		  * by multiplying a delta value (-1, 0, +1) by
		  * a scale multiplier.
		  *
		  * At entry:
		  *	'b' = coordinate delta.
		  *	'a' = scale multiplier.
		  */
		 generate_new_cursor_coordinate:
0A05   3404             pshs  b;
0A07   5D               tstb;   
0A08   2A01             bpl   P0A0B; 
0A0A   50               negb;   
0A0B   3D        P0A0B: mul;    
0A0C   3502             puls  a;
0A0E   4D               tsta;   
0A0F   2A01             bpl   P0A12; 
0A11   50               negb;   
0A12   39        P0A12: rts;    


		 /*
		  * display_search_pattern()
		  *
		  * This routine draws the series of vectors, specified in
		  * the structure pointed to by they 'x' register.  The 'y'
		  * 'y' register points to an array of line patterns 
		  * associated with each vector.  The scale factor to be used
		  * is specified in 'b'.  A pattern of '1' terminates this
		  * routine.  If a pick is detected, then the index of the
		  * vector being drawn is returned in the 'a' register;
		  * if no pick occurred, then 0xFF is returned.  This is used
		  * when drawing the spider web search patterns.
		  *
		  * At entry:
		  *	'b' = scale factor
		  *	'x' = vector list ptr (rel y, rel x)
		  *	'y' = line pattern array ptr
		  *
		  * At exit:
		  *	'a' = 0xFF => no pick occurred.
		  *	      otherwise, indicates which vector was picked.
		  */
		 display_search_pattern:
0A13   86FF             lda   #0xFF; 
0A15   B70000           sta   $0000; 
0A18   6F7F             clr   -1,s;    /* Keeps track of current vector index */
0A1A   86FF             lda   #0xFF; 
0A1C   A77E             sta   -2,s;    /* Keeps index of picked vector */
0A1E   D704             stb   0x04;  
0A20   EC00      P0A20: ldd   0,x;   
0A22   9701             sta   0x01;  
0A24   0F00             clr   0x00;  
0A26   3002             leax  2,x;   
0A28   0C00             inc   0x00;  
0A2A   D701             stb   0x01;  
0A2C   A6A0             lda   ,y+;   
0A2E   970A             sta   0x0A;  
0A30   0F05             clr   0x05;  
0A32   CC0040           ldd   #0x0040;    
0A35   D50D      P0A35: bitb  0x0D;  
0A37   27FC             beq   P0A35; 
0A39   1E11             exg   x,x;   
0A3B   970A             sta   0x0A;  
0A3D   960D             lda   0x0D;    /* Check for a lightpen pick */
0A3F   8402             anda  #0x02; 
0A41   2704             beq   P0A47; 
0A43   A67F             lda   -1,s;  
0A45   A77E             sta   -2,s;    /* Save index of picked vector. */
0A47   6C7F      P0A47: inc   -1,s;    /* Increment index. */
0A49   A620             lda   0,y;   
0A4B   2FD3             ble   P0A20; 
0A4D   A67E             lda   -2,s;    /* Return index of picked vector. */
0A4F   39               rts;    


		 dot_pattern:
0A50   FF               .byte 0xFF;
0A51   00               .byte 0x00;
0A52   00               .byte 0x00;
0A53   01               .byte 0x01;

		 /*
		  * The following 5 arrays contain the line patterns
		  * used when drawing the spider web search pattern.
		  * Depending upon which set of line patterns are used,
		  * either the whole pattern, the left side, or right side,
		  * or upper portion, or lower portion will be drawn.
		  */
		 whole_search_pattern:
0A54   00               .byte 0x00;
0A55   FF               .byte 0xFF;
0A56   FF               .byte 0xFF;
0A57   FF               .byte 0xFF;
0A58   FF               .byte 0xFF;
0A59   FF               .byte 0xFF;
0A5A   FF               .byte 0xFF;
0A5B   FF               .byte 0xFF;
0A5C   FF               .byte 0xFF;
0A5D   01               .byte 0x01;

		 lower_search_pattern:
0A5E   00               .byte 0x00;
0A5F   00               .byte 0x00;
0A60   FF               .byte 0xFF;
0A61   FF               .byte 0xFF;
0A62   FF               .byte 0xFF;
0A63   FF               .byte 0xFF;
0A64   FF               .byte 0xFF;
0A65   00               .byte 0x00;
0A66   00               .byte 0x00;
0A67   01               .byte 0x01;

		 upper_search_pattern:
0A68   00               .byte 0x00;
0A69   FF               .byte 0xFF;
0A6A   FF               .byte 0xFF;
0A6B   00               .byte 0x00;
0A6C   00               .byte 0x00;
0A6D   00               .byte 0x00;
0A6E   FF               .byte 0xFF;
0A6F   FF               .byte 0xFF;
0A70   FF               .byte 0xFF;
0A71   01               .byte 0x01;

		 right_search_pattern:
0A72   00               .byte 0x00;
0A73   FF               .byte 0xFF;
0A74   FF               .byte 0xFF;
0A75   FF               .byte 0xFF;
0A76   FF               .byte 0xFF;
0A77   00               .byte 0x00;
0A78   00               .byte 0x00;
0A79   00               .byte 0x00;
0A7A   FF               .byte 0xFF;
0A7B   01               .byte 0x01;

		 left_search_pattern:
0A7C   00               .byte 0x00;
0A7D   00               .byte 0x00;
0A7E   00               .byte 0x00;
0A7F   00               .byte 0x00;
0A80   FF               .byte 0xFF;
0A81   FF               .byte 0xFF;
0A82   FF               .byte 0xFF;
0A83   FF               .byte 0xFF;
0A84   FF               .byte 0xFF;
0A85   01               .byte 0x01;

		 small_search_pattern_vl:
0A86   10               .byte 0x10;
0A87   08               .byte 0x08;
0A88   F8               .byte 0xF8;
0A89   08               .byte 0x08;
0A8A   F0               .byte 0xF0;
0A8B   00               .byte 0x00;
0A8C   F8               .byte 0xF8;
0A8D   F8               .byte 0xF8;
0A8E   00               .byte 0x00;
0A8F   F0               .byte 0xF0;
0A90   08               .byte 0x08;
0A91   F8               .byte 0xF8;
0A92   10               .byte 0x10;
0A93   00               .byte 0x00;
0A94   08               .byte 0x08;
0A95   08               .byte 0x08;
0A96   00               .byte 0x00;
0A97   10               .byte 0x10;

		 large_search_pattern_vl:
0A98   40               .byte 0x40;
0A99   20               .byte 0x20;
0A9A   E0               .byte 0xE0;
0A9B   20               .byte 0x20;
0A9C   C0               .byte 0xC0;
0A9D   00               .byte 0x00;
0A9E   E0               .byte 0xE0;
0A9F   E0               .byte 0xE0;
0AA0   00               .byte 0x00;
0AA1   C0               .byte 0xC0;
0AA2   20               .byte 0x20;
0AA3   E0               .byte 0xE0;
0AA4   40               .byte 0x40;
0AA5   00               .byte 0x00;
0AA6   20               .byte 0x20;
0AA7   20               .byte 0x20;
0AA8   00               .byte 0x00;
0AA9   40               .byte 0x40;

		 /*
		  * These are (y,x) delta pairs, which are added
		  * to the cursor position, to line the cursor up
		  * with the lightpen.  The pair used depends upon
		  * which vector of the search pattern was picked.
		  */
		 cursor_deltas:
0AAA   01               .byte 0x01;
0AAB   01               .byte 0x01;
0AAC   00               .byte 0x00;
0AAD   01               .byte 0x01;
0AAE   FF               .byte 0xFF;
0AAF   01               .byte 0x01;
0AB0   FF               .byte 0xFF;
0AB1   00               .byte 0x00;
0AB2   FF               .byte 0xFF;
0AB3   FF               .byte 0xFF;
0AB4   00               .byte 0x00;
0AB5   FF               .byte 0xFF;
0AB6   01               .byte 0x01;
0AB7   FF               .byte 0xFF;
0AB8   01               .byte 0x01;
0AB9   00               .byte 0x00;

		 /*
		  * This is an array of multiplier values, used when
		  * updating the cursors position so that is tracks
		  * the lightpen.  The scale factor index used to
		  * draw the search pattern is also used to index into
		  * this byte array.  As the scale factor increases, so
		  * does the multiplier value.
		  */
		 delta_multipliers:
0ABA   01               .byte 0x01;
0ABB   02               .byte 0x02;
0ABC   03               .byte 0x03;
0ABD   05               .byte 0x05;
0ABE   08               .byte 0x08;
0ABF   0B               .byte 0x0B;
0AC0   0E               .byte 0x0E;
0AC1   12               .byte 0x12;
0AC2   16               .byte 0x16;
0AC3   1C               .byte 0x1C;

		 /*
		  * This array contains the scale factors to be used
		  * when drawing the search patterns.
		  */
		 search_pattern_scale_factors:
0AC4   08               .byte 0x08;
0AC5   12               .byte 0x12;
0AC6   1E               .byte 0x1E;
0AC7   2C               .byte 0x2C;
0AC8   0E               .byte 0x0E;
0AC9   14               .byte 0x14;
0ACA   1A               .byte 0x1A;
0ACB   22               .byte 0x22;
0ACC   2C               .byte 0x2C;
0ACD   38               .byte 0x38;
0ACE   00               .byte 0x00;


		 /*
		  * print_with_pick_check(string_ptr)
		  *
		  * This procedure checks to see if a pick occurred
		  * on the previous pass through the main loop (C81E != 0).
		  * If a pick did not occur, then the passed in string
		  * is displayed.  However, if a pick did occur on the
		  * previous pass, then a check is made to see if this
		  * is the string which was picked (the string address
		  * is compared against that which was saved in C81C).
		  * If this is not the string which was last picked, then
		  * this string will not be displayed.  If this was the
		  * string which was picked, then we will display it.
		  * If we do display the string, then afterwards, we will
		  * check to see if a pick occurred, and if so, then we
		  * will hi-light the string, and save its address in C81C.
		  *
		  * This routine is useful for display menus with multiple
		  * choices.  When one choice is selected, the others will
		  * not be displayed.  Once a string is no longer selected,
		  * then all of the choices will once again be displayed.
		  *
		  * At entry: 'u' must point to the string block.
		  */
		 print_with_pick_check:
0ACF   7CC820           inc   $C820; 
0AD2   BDF354           jsr   $reset0ref;
0AD5   FFC880           stu   $C880; 
0AD8   7DC81E           tst   $C81E; 
0ADB   2707             beq   P0AE4; 
0ADD   1F31             tfr   u,x;   
0ADF   BCC81C           cmpx  $C81C; 
0AE2   2608             bne   P0AEC; 
0AE4   BD0B19    P0AE4: jsr   $am_print_string;
0AE7   7DC89E           tst   $C89E; 
0AEA   2601             bne   hilite_string; 
0AEC   39        P0AEC: rts;    


		 /*
		  * hilite_string()
		  *
		  * This routine is used by print_with_pick_check() to
		  * hi-lite a string once it is picked, and to set several
		  * globals, so that other routine will know a pick occurred.
		  * The address of the string block is in C880.  A copy of
		  * this address will then be saved in C81C, and C89E and
		  * C81B will be set to one (to flag that a pick occurred).
		  */
		 hilite_string:
0AED   FFC882           stu   $C882; 
0AF0   FEC880           ldu   $C880; 
0AF3   FFC81C           stu   $C81C; 
0AF6   BD0B19           jsr   $am_print_string;
0AF9   FEC880           ldu   $C880; 
0AFC   BD0B19           jsr   $am_print_string;
0AFF   FEC880           ldu   $C880; 
0B02   BD0B19           jsr   $am_print_string;
0B05   FEC880           ldu   $C880; 
0B08   BD0B19           jsr   $am_print_string;
0B0B   8601             lda   #0x01; 
0B0D   B7C89E           sta   $C89E; 
0B10   B7C81B           sta   $C81B; 
0B13   FEC882           ldu   $C882; 
0B16   1F31             tfr   u,x;   
0B18   39               rts;    


		 /*
 		  * am_print_string()
		  *
		  * Prints a string of character, terminated by 0x80.
		  * At entry, the 'u' register must point to a block
		  * having the following format:
		  *
		  *	1 byte height of string
		  *	1 byte width of string
		  *	1 byte rel y location
		  *	1 byte rel x location
		  *	2 byte pointer to start of string
		  *
		  * At exit: C89E will be set if a pick occurred.
		  */
		 am_print_string:
0B19   ECC1             ldd   ,u++;  
0B1B   FDC82A           std   $C82A; 
0B1E   ECC1             ldd   ,u++;  
0B20   BDF2FC           jsr   $move_pen7F_to_d;
0B23   EE40             ldu   0,u;   
0B25   FFC82C           stu   $C82C; 
0B28   335F             leau  -1,u;  
0B2A   FFC84F           stu   $C84F; 
0B2D   0F0D             clr   0x0D;  
0B2F   7FC89E           clr   $C89E; 
0B32   8EF9D4           ldx   #0xF9D4;    
0B35   CC1883           ldd   #0x1883;    
0B38   0F01             clr   0x01;  
0B3A   970B             sta   0x0B;  
0B3C   D700      P0B3C: stb   0x00;  
0B3E   0A00             dec   0x00;  
0B40   CC8081           ldd   #0x8081;    
0B43   12               nop;    
0B44   0C00             inc   0x00;  
0B46   D700             stb   0x00;  
0B48   9700             sta   0x00;  
0B4A   7DC800           tst   $C800; 
0B4D   0C00             inc   0x00;  
0B4F   B6C82B           lda   $C82B; 
0B52   9701             sta   0x01;  
0B54   CC0100           ldd   #0x0100;    
0B57   FEC82C           ldu   $C82C; 
0B5A   9700             sta   0x00;  
0B5C   2004             bra   P0B62; 
0B5E   A686      P0B5E: lda   a,x;   
0B60   970A             sta   0x0A;  
0B62   A6C0      P0B62: lda   ,u+;   
0B64   2AF8             bpl   P0B5E; 
0B66   960D             lda   0x0D;    /* Record any picks. */
0B68   8402             anda  #0x02; 
0B6A   BAC89E           ora   $C89E; 
0B6D   B7C89E           sta   $C89E; 
0B70   12               nop;    
0B71   8681             lda   #0x81; 
0B73   9700             sta   0x00;  
0B75   0001             neg   0x01;  
0B77   8601             lda   #0x01; 
0B79   9700             sta   0x00;  
0B7B   8CFBB4           cmpx  #0xFBB4;    
0B7E   272D             beq   P0BAD; 
0B80   308850           leax  0x50,x;
0B83   1F30             tfr   u,d;   
0B85   B3C84F           subd  $C84F; 
0B88   C002             subb  #0x02; 
0B8A   58               aslb;   
0B8B   2100             brn   P0B8D; 
0B8D   8681      P0B8D: lda   #0x81; 
0B8F   12               nop;    
0B90   5A               decb;   
0B91   26FA             bne   P0B8D; 
0B93   9700             sta   0x00;  
0B95   F6C82A           ldb   $C82A; 
0B98   D701             stb   0x01;  
0B9A   0A00             dec   0x00;  
0B9C   CC8101           ldd   #0x8101;    
0B9F   12               nop;    
0BA0   9700             sta   0x00;  
0BA2   0F01             clr   0x01;  
0BA4   D700             stb   0x00;  
0BA6   9700             sta   0x00;  
0BA8   C683             ldb   #0x83; 
0BAA   7E0B3C           jmp   $P0B3C;
0BAD   8698      P0BAD: lda   #0x98; 
0BAF   970B             sta   0x0B;  
0BB1   7EF354           jmp   $reset0ref;


		 SM_DOT_STR:
0BB4   E8               .byte 0xE8;
0BB5   20               .byte 0x20;
0BB6   80               .byte 0x80;
0BB7   C0               .byte 0xC0;
0BB8   0B               .byte 0x0B;
0BB9   BA               .byte 0xBA;
0BBA   44               .byte "DOT", 0x80;

		 SM_LINE_STR:
0BBE   E8               .byte 0xE8;
0BBF   20               .byte 0x20;
0BC0   80               .byte 0x80;
0BC1   C0               .byte 0xC0;
0BC2   0B               .byte 0x0B;
0BC3   C4               .byte 0xC4;
0BC4   4C               .byte LINE", 0x80;


		 /*
		  * This describes the initial cursor state.
		  */
		 initial_cursor_state:
0BC9   00               .byte 0x00;
0BCA   00               .byte 0x00;
0BCB   78               .byte 0x78;
0BCC   88               .byte 0x88;
0BCD   90               .byte 0x90;
0BCE   78               .byte 0x78;


		 /*
		  * start_of_sketch_connect()
		  *
		  * This is the starting point for the SKETCH and
		  * the CONNECT main menu items.
		  */
		 start_of_sketch_connect:
0BCF   BD0E1F           jsr   $init_sketch_connect_variables;
0BD2   CEC889           ldu   #0xC889;    
0BD5   8E0BC9           ldx   #initial_cursor_state;    
0BD8   BD08ED           jsr   $set_cursor_structure;
0BDB   8E0BE1           ldx   #sketch_connect_handler;    
0BDE   BFC8A7           stx   $C8A7; 

		 /*
		  * sketch_connect_handler()
		  *
		  * This is the real main loop routine for the sketch
		  * and connect operatons.  It takes care of reading 
		  * the buttons, and calling any button handlers, as
		  * needed.  It is invoked only through the indirect
		  * jump location, by the main loop.
		  */
		 sketch_connect_handler:
0BE1   7FC82E           clr   $C82E; 
0BE4   7DC8A6           tst   $C8A6;   /* Check button 4, iff in connect mode */
0BE7   2708             beq   P0BF1;   
0BE9   7DC815           tst   $C815;   /* Check button 4;(dot/lines) */
0BEC   2703             beq   P0BF1; 
0BEE   73C8A5           com   $C8A5;   /* Complement dot/connect flag */
0BF1   BD0D27    P0BF1: jsr   $display_sc_menu;
0BF4   BD0E38           jsr   $sketch_connect_draw_vector_list;
0BF7   8E0C95           ldx   #fan_handler;    
0BFA   7DC812           tst   $C812;   /* Check button 1;(draw) */
0BFD   2610             bne   sc_start_draw; 
0BFF   7DC8A6           tst   $C8A6;   /* Check button 4, iff in sketch mode */
0C02   2605             bne   P0C09; 
0C04   7DC815           tst   $C815;   /* Check button 4;(fan) */
0C07   2609             bne   sc_start_fan; 
0C09   7DC813    P0C09: tst   $C813;   /* Check button 2;(rubber band line) */
0C0C   2638             bne   sc_start_rubber_band_line; 
0C0E   39               rts;    

		 /*
		  * sc_start_draw()
		  * sc_start_fan()
		  *
		  * These two entry points are responsible for initializing
		  * things when either button 1 (draw) or button 4 (fan)
		  * are pressed during SKETCH or CONNECT modes.  They will
		  * set up a new indirect jump handler, save the current
		  * cursor position, and initialize some variables.
		  */
		 sc_start_draw:
0C0F   8E0C5B           ldx   #sc_draw_handler;    
		 sc_start_fan:
0C12   B6C8A3           lda   $C8A3;   /* Don't bother, if the vector */
0C15   81FB             cmpa  #0xFB;   /* list is already full.       */
0C17   2501             blo   P0C1A; 
0C19   39               rts;    

0C1A   BFC8A7    P0C1A: stx   $C8A7;   /* Save new indirect jump handler. */
0C1D   C603             ldb   #0x03; 
0C1F   8EC8A9           ldx   #0xC8A9; /* Load 'x' with pointer to next */
0C22   3D               mul;           /* free spot in the vector list  */
0C23   308B             leax  d,x;     /* buffer.                       */
0C25   6F00             clr   0,x;   
0C27   FCC889           ldd   $C889;   /* Fill this spot, using the current */
0C2A   ED01             std   1,x;     /* cursor position.              */
0C2C   7CC8A3           inc   $C8A3;   /* Increment the vector counter. */
0C2F   8605             lda   #0x05;   /* # of pts to draw relative 2 starting*/
0C31   B7C8A4           sta   $C8A4;   /* pt, be4 forcing new absolute ref pt.*/
0C34   FCC889           ldd   $C889;   /* Save current cursor position. */
0C37   FDC89B           std   $C89B; 
0C3A   FDC82F           std   $C82F; 
0C3D   8608             lda   #0x08; 
0C3F   B7C896           sta   $C896;   /* Stores reset value for counter. */
0C42   B7C895           sta   $C895;   /* Active counter; endpoint is fixed */
0C45   39               rts;           /* when this goes to 0.            */


		 /*
		  * sc_start_rubber_band_line()
		  *
		  * This entry point is responsible for setting up the
		  * indirect jump location, and initializing variables
		  * when button 2 (rubber band line) is pressed during
		  * either SKETCH or CONNECT mode.
		  */
		 sc_start_rubber_band_line:
0C46   FCC889           ldd   $C889;   /* Save current cursor position. */
0C49   FDC89B           std   $C89B; 
0C4C   8E0CDA           ldx   #rubber_band_line_handler;    
0C4F   B6C8A3           lda   $C8A3;   /* Don't bother if the vector list */
0C52   81FB             cmpa  #0xFB;   /* is already full.              */
0C54   2501             blo   P0C57; 
0C56   39               rts;    
0C57   BFC8A7    P0C57: stx   $C8A7;   /* Save new indirect jump handler. */
0C5A   39               rts;    


		 /*
		  * sc_draw_handler()
		  *
		  * This is the routine which draws lines/dots when 
		  * button 1 is depressed.  It is invoked only through
		  * the indirect jump location.  It is used only when
		  * either SKETCH or CONNECT modes are active.
		  */
		 sc_draw_handler:
0C5B   BD0D27           jsr   $display_sc_menu;
0C5E   BD0E38           jsr   $sketch_connect_draw_vector_list;
0C61   B6C80F           lda   $C80F;   /* Check if button 1 is still pressed. */
0C64   8401             anda  #0x01; 
0C66   260A             bne   P0C72; 
0C68   BD0DFA           jsr   $get_new_endpoint;
0C6B   8E0BE1           ldx   #sketch_connect_handler;    
0C6E   BFC8A7           stx   $C8A7; 
0C71   39               rts;    

0C72   FCC89B    P0C72: ldd   $C89B;  /* Don't continue, if the cursor has */
0C75   10B3C889         cmpd  $C889;  /* not moved since last point.       */
0C79   2601             bne   fix_endpoint; 
0C7B   39               rts;    

		 fix_endpoint:
0C7C   7DC895           tst   $C895;  /* Wait for counter (C895) to decrement */
0C7F   2704             beq   P0C85;  /* to zero, before fixing endpoint.  */
0C81   7AC895           dec   $C895; 
0C84   39               rts;    

0C85   BD0DFA    P0C85: jsr   $get_new_endpoint;
0C88   FCC889           ldd   $C889;  /* Move the starting point for next */
0C8B   FDC89B           std   $C89B;  /* vector to previous vectors endpt.*/
0C8E   B6C896           lda   $C896; 
0C91   B7C895           sta   $C895;  /* Reset 'fix endpoint' counter.    */
0C94   39               rts;    


		 /*
		  * fan_handler()
		  *
		  * As long as the user has button 4 pressed, a fan
		  * pattern will be drawn.  Once button 4 is released,
		  * control will return to the sketch/connect handler.
		  */
		 fan_handler:
0C95   86FF             lda   #0xFF;   /* Flag that 'fan' is being done. */
0C97   B7C82E           sta   $C82E; 
0C9A   7FC8A4           clr   $C8A4; 
0C9D   BD0D27           jsr   $display_sc_menu;
0CA0   BD0E38           jsr   $sketch_connect_draw_vector_list;
0CA3   B6C80F           lda   $C80F;   /* Check if button 4 is still pressed */
0CA6   8408             anda  #0x08; 
0CA8   260D             bne   continue_drawing_fan; 
0CAA   BD0DFA           jsr   $get_new_endpoint;
0CAD   8E0BE1           ldx   #sketch_connect_handler;    
0CB0   BFC8A7           stx   $C8A7; 
0CB3   7FC82E           clr   $C82E; 
0CB6   39               rts;    

		 continue_drawing_fan:
0CB7   FCC89B           ldd   $C89B;   /* Don't add a new line, unless */
0CBA   10B3C889         cmpd  $C889;   /* the cursor position has changed. */
0CBE   2601             bne   P0CC1; 
0CC0   39               rts;    

0CC1   7DC895    P0CC1: tst   $C895;   /* Don't fix next fan endpt, until */
0CC4   2704             beq   P0CCA;   /* 'fix point' counter has decremented */
0CC6   7AC895           dec   $C895;   /* to zero.                        */
0CC9   39               rts;    

0CCA   BD0DFA    P0CCA: jsr   $get_new_endpoint;
0CCD   FCC889           ldd   $C889;   /* Set starting point for next vector */
0CD0   FDC89B           std   $C89B;   /* equal to last vectors endpoint. */
0CD3   B6C896           lda   $C896; 
0CD6   B7C895           sta   $C895;   /* Reset 'fix endpoint' counter.  */
0CD9   39               rts;    


		 /*
		  * rubber_band_line_handler()
		  *
	  	  * This is the handler routine while the user is
		  * drawing a rubber band line during sketch or connect
		  * modes.  The rubber band line will continue until the
		  * user stops pressing button 2.  This routine is only
		  * invoked through the indirect jump location.
		  */
		 rubber_band_line_handler:
0CDA   BD0D27           jsr   $display_sc_menu;
0CDD   BD0E38           jsr   $sketch_connect_draw_vector_list;
0CE0   B6C80F           lda   $C80F;   /* See if button 2 still depressed */
0CE3   8402             anda  #0x02; 
0CE5   260D             bne   continue_rb_line; 
0CE7   7FC8A4           clr   $C8A4;   /* Clear the relative point counter. */
0CEA   BD0DFA           jsr   $get_new_endpoint;
0CED   8E0BE1           ldx   #sketch_connect_handler;    
0CF0   BFC8A7           stx   $C8A7; 
0CF3   39               rts;    

		 continue_rb_line:
0CF4   7DC8A6           tst   $C8A6;  /* Draw the rubber band line from the */
0CF7   2705             beq   P0CFE;  /* originat point to the current cursor */
0CF9   7DC8A5           tst   $C8A5;  /* position, unless in DOT mode.      */
0CFC   260D             bne   P0D0B; 
0CFE   BDF2A9    P0CFE: jsr   $intensity_to_7F;
0D01   8EC89B           ldx   #0xC89B;    
0D04   108EC889         ldy   #0xC889;    
0D08   BD0840           jsr   $draw_vector_with_pick_check;
0D0B   39        P0D0B: rts;    


		 HDR_CONNECT_STR:
0D0C   E8               .byte 0xE8;
0D0D   40               .byte 0x40;
0D0E   7F               .byte 0x7F;
0D0F   E8               .byte 0xE8;
0D10   0D               .byte 0x0D;
0D11   12               .byte 0x12;
0D12   43               .byte "CONNECT", 0x80;

		 HDR_SKETCH_STR:
0D1A   E8               .byte 0xE8;
0D1B   40               .byte 0x40;
0D1C   7F               .byte 0x7F;
0D1D   E8               .byte 0xE8;
0D1E   0D               .byte 0x0D;
0D1F   20               .byte 0x20;
0D20   53               .byte "SKETCH", 0x80;


		 /*
		  * display_sc_menu()
		  *
		  * This procedure displays either the SKETCH or CONNECT
		  * header (as an unpickable string), and then also displays
		  * the ERASE, MENU and DOT/LINE sub-items (as pickable strings)
		  * It then checks to see if any of these items were picked,
		  * and handles them is they were. Also displays the cursor.
		  */
		 display_sc_menu:
0D27   BDF2A9           jsr   $intensity_to_7F;
0D2A   BDF354           jsr   $reset0ref;
0D2D   7DC8A6           tst   $C8A6;   /* See if in sketch or connect mode */
0D30   2716             beq   P0D48; 
0D32   CE0D0C           ldu   #HDR_CONNECT_STR;    /* CONNECT mode */
0D35   BD0B19           jsr   $am_print_string;
0D38   CE0BB4           ldu   #SM_DOT_STR;   /* Display DOT or LINE item */
0D3B   7DC8A5           tst   $C8A5; 
0D3E   2603             bne   P0D43; 
0D40   CE0BBE           ldu   #SM_LINE_STR;    
0D43   BD0B19    P0D43: jsr   $am_print_string;
0D46   2006             bra   P0D4E; 

0D48   CE0D1A    P0D48: ldu   #HDR_SKETCH_STR;    /* SKETCH mode */ 
0D4B   BD0B19           jsr   $am_print_string;
0D4E   8660      P0D4E: lda   #0x60;           /* Draw cursor at current */
0D50   BDF2AB           jsr   $intensity_to_a; /* position.              */
0D53   FCC889           ldd   $C889; 
0D56   BD0EB2           jsr   $am_move_to_d;
0D59   8E052F           ldx   #cross;    
0D5C   C60A             ldb   #0x0A; 
0D5E   BD07D6           jsr   $draw_with_pick_check;
0D61   BDF2A9           jsr   $intensity_to_7F;
0D64   CEC889           ldu   #0xC889;         /* If cursor is picked, then */
0D67   6D42             tst   2,u;             /* draw it brighter.         */
0D69   2711             beq   P0D7C; 
0D6B   BDF354           jsr   $reset0ref;
0D6E   FCC889           ldd   $C889; 
0D71   BD0EB2           jsr   $am_move_to_d;
0D74   C60A             ldb   #0x0A; 
0D76   8E052F           ldx   #cross;    
0D79   BD07D6           jsr   $draw_with_pick_check;
0D7C   BD0901    P0D7C: jsr   $update_cursor_position;
0D7F   CE0056           ldu   #SM_ERASE_STR;    /* Print ERASE item */
0D82   BD0ACF           jsr   $print_with_pick_check;
0D85   B6C80F           lda   $C80F;            /* Check if button 3 */
0D88   8404             anda  #0x04;            /* is pressed and item is */
0D8A   270C             beq   P0D98;            /* picked. */
0D8C   7DC89E           tst   $C89E; 
0D8F   2707             beq   P0D98; 
0D91   8E0BCF           ldx   #start_of_sketch_connect;    
0D94   BFC8A7           stx   $C8A7; 
0D97   39               rts;    

0D98   CE0062    P0D98: ldu   #SM_MENU_STR;     /* Print MENU item */
0D9B   BD0ACF           jsr   $print_with_pick_check;
0D9E   B6C80F           lda   $C80F;            /* Check if button 3 is */
0DA1   8404             anda  #0x04;            /* pressed and item is picked */
0DA3   270B             beq   P0DB0; 
0DA5   7DC89E           tst   $C89E; 
0DA8   2706             beq   P0DB0; 
0DAA   8E009B           ldx   #display_main_menu;    
0DAD   BFC8A7           stx   $C8A7; 
0DB0   39        P0DB0: rts;    


0DB1   39               .byte 0x39; /* "9" */ 


		 /*
		  * generate_vector_endpoint_and_recalibrate()
		  *
		  * This routine generates an endpoint for a vector.
		  * If the relative point counter (C8A4) has decremented
		  * to zero, then we will add an absolute reference point
		  * to the vector list, to prevent our vectors from getting
		  * too far out of whack; this is done after every 5 points.
		  *
		  * At entry:
		  *	C8A4 contains the relative point counter.
		  *	'a' has index of next available spot in vector list.
		  *	C89B contains starting point for this vector.
		  *	C82F contains starting point for the fan.
		  *	C82E flags DRAW .vs. FAN mode.
		  *	C8A3 has index of next available spot in vector list.
		  *
		  * At exit:
		  *	C881-C882 contains new vector endpoint.
		  *	'u' points to next available spot in vector list.
		  */
		 generate_vector_endpoint_and_recalibrate:
0DB2   7DC8A4           tst   $C8A4;  /* If the relative pt counter has gone */
0DB5   261F             bne   P0DD6;  /* to zero, then force another absolute*/
0DB7   C603             ldb   #0x03;  /* ref point.                          */
0DB9   8EC8A9           ldx   #0xC8A9;    
0DBC   3D               mul;    
0DBD   308B             leax  d,x;   
0DBF   6F00             clr   0,x;    /* Flag an absolute reference point. */
0DC1   FCC89B           ldd   $C89B;  /* Get starting pt for this vector; if */
0DC4   7DC82E           tst   $C82E;  /* DRAW mode, then use last cursor   */
0DC7   2703             beq   P0DCC;  /* position; else, use cursor position */
0DC9   FCC82F           ldd   $C82F;  /* for beginning of fan.             */
0DCC   ED01      P0DCC: std   1,x;    /* Save abs ref point.               */
0DCE   7CC8A3           inc   $C8A3;  /* Increment vector counter.         */
0DD1   8605             lda   #0x05;  /* Reset the relative point counter. */
0DD3   B7C8A4           sta   $C8A4; 
0DD6   CEC8A9    P0DD6: ldu   #0xC8A9;    
0DD9   B6C8A3           lda   $C8A3;  /* Load 'u' with pointer to current  */
0DDC   C603             ldb   #0x03;  /* work spot in the vector list.     */
0DDE   3D               mul;    
0DDF   33CB             leau  d,u;   
0DE1   8EC89B           ldx   #0xC89B; /* Calculate endpt for this vector. */   
0DE4   108EC889         ldy   #0xC889;    
0DE8   7DC82E           tst   $C82E; 
0DEB   2703             beq   P0DF0; 
0DED   8EC82F           ldx   #0xC82F;    
0DF0   BD0879    P0DF0: jsr   $calculate_vector_endpoint;
0DF3   7CC8A3           inc   $C8A3;  /* Increment vector list counter. */
0DF6   7AC8A4           dec   $C8A4;  /* Decrement relative point counter. */
0DF9   39               rts;    


		 /*
		  * get_new_endpoint()
		  *
		  * This routine checks to see how many vectors or dots
		  * we have available for use.  The current number of
		  * vectors or dots drawn is stored in C8A3.  If we
		  * have already reached the limit, then return without
		  * doing anything.  Otherwise, if we are close to the
		  * limit, then make a sound, and flag that we are close,
		  * by setting C829; this flag will prevent us from making
		  * the sound more than once.  Also, it will generate the
		  * scale factor and coordinates for the current vector.
		  * These pieces of information are then stored in the
		  * vector list.
		  */
		 get_new_endpoint:
0DFA   B6C8A3           lda   $C8A3;   /* See if we have surpassed limit */
0DFD   81FD             cmpa  #0xFD; 
0DFF   2501             blo   P0E02; 
0E01   39               rts;    
0E02   7DC829    P0E02: tst   $C829;   /* Don't make sound more than once */
0E05   260D             bne   P0E14; 
0E07   81EE             cmpa  #0xEE;   /* See if we're near limit */
0E09   2509             blo   P0E14; 
0E0B   7CC829           inc   $C829; 
0E0E   BD0ED8           jsr   $set_up_a_misc_sound1;
0E11   B6C8A3           lda   $C8A3; 
0E14   BD0DB2    P0E14: jsr   $generate_vector_endpoint_and_recalibrate;
0E17   E740             stb   0,u;     /* Save scale factor. */
0E19   FCC881           ldd   $C881; 
0E1C   ED41             std   1,u;     /* Save vector endpoints. */
0E1E   39               rts;    


		 /*
		  * init_sketch_connect_variables()
		  *
		  * This routine is invoked when the sketch/connect
		  * handler is first called.  It is responsible for
		  * initializing the vector list residing in RAM at
		  * C8A9-CBA5 to 0xFF.  It also initializes some RAM
		  * locations to 0.
		  */
		 init_sketch_connect_variables:
0E1F   8EC8A9           ldx   #0xC8A9;    
0E22   86FF             lda   #0xFF; 
0E24   A780      P0E24: sta   ,x+;   
0E26   8CCBA6           cmpx  #0xCBA6;    
0E29   26F9             bne   P0E24; 
0E2B   7FC8A3           clr   $C8A3;   /* Vector counter. */
0E2E   7FC8A4           clr   $C8A4;   /* Relative point counter. */
0E31   7FC829           clr   $C829;   /* Buffer almost full flag. */
0E34   7FC856           clr   $C856;   /* Sound duration. */
0E37   39               rts;    


		 /*
		  * sketch_connect_draw_vector_list()
		  *
		  * This routine goes through the vector list, performing
		  * all of the move and draw requests currently therein.
		  * It does this by drawing all of the points relative to
		  * to the last absolute reference point, until a new
		  * absolute reference point is encountered.  At this point
		  * it will recalibrate things, and then move to the new
		  * absolute reference point, and continue drawing.  This
		  * will continue until the end of the vector list is
		  * encountered.  The vector list has the following format:
		  *
		  *   scale, rel y, rel x
		  *
		  * If 'scale' is 0xFF, then this is the end of the list.
		  * If 'scale' is 0x00, then the corresponding (y,x) are
		  *	really a new absolute reference point, not relative
		  *	points.
		  * If 'scale' is positive, then draw to new point.
		  * If 'scale' is negative, then move to new point.
		  */
		 sketch_connect_draw_vector_list:
0E38   8660             lda   #0x60;    /* Set up vector intensity. */
0E3A   BDF2AB           jsr   $intensity_to_a;
0E3D   8EC8A9           ldx   #0xC8A9;  /* Start drawing vector list. */
0E40   BD0E54    P0E40: jsr   $draw_relative_points;
0E43   4D               tsta;   
0E44   2704             beq   move_to_abs_ref_point; 
0E46   BDF354           jsr   $reset0ref;
0E49   39               rts;    

		 move_to_abs_ref_point:
0E4A   BDF354           jsr   $reset0ref;  /* Reset zero reference.  */
0E4D   EC81             ldd   ,x++;        /* Move to abs ref point. */
0E4F   BD0EB2           jsr   $am_move_to_d;
0E52   20EC             bra   P0E40; 


		 /*
		  * draw_relative_points()
		  *
		  * This routine draw all of the vector in the vector
		  * list, which are relative to the current absolute
		  * reference point.  When the end of the vector list
		  * or a new absolute reference point is encountered,
		  * this routine will return.
		  *
		  * At entry:
		  *	'x' points to the vector list.
		  *
		  * At exit:
		  *	'a' contains scale factor for terminating point.
		  */
		 draw_relative_points:
0E54   A680             lda   ,x+;    /* Load scale factor; return if it */
0E56   2601             bne   P0E59;  /* flags a new abs reference point.*/
0E58   39               rts;    

0E59   81FF      P0E59: cmpa  #0xFF;  /* Check 4 the end of the vector list. */
0E5B   2601             bne   P0E5E; 
0E5D   39               rts;    

0E5E   7DC8A6    P0E5E: tst   $C8A6;  /* Check for LINE or DOT mode. */
0E61   2705             beq   sc_draw_to_point; 
0E63   7DC8A5           tst   $C8A5; 
0E66   260D             bne   sc_move_to_point; 
		 sc_draw_to_point:
0E68   4D               tsta;         /* Check for move/draw operation. */
0E69   2B0A             bmi   sc_move_to_point; 
0E6B   C6FF             ldb   #0xFF; 
0E6D   F7C880           stb   $C880; 
0E70   BD0E8F           jsr   $am_draw_with_pattern;
0E73   20DF             bra   draw_relative_points; 
		 sc_move_to_point:
0E75   030A             com   0x0A;  
0E77   1E11             exg   x,x;   
0E79   1E11             exg   x,x;   
0E7B   030A             com   0x0A;  
0E7D   847F             anda  #0x7F; 
0E7F   7FC880           clr   $C880;   /* Clear vector pattern. */
0E82   BD0E8F           jsr   $am_draw_with_pattern;
0E85   030A             com   0x0A;  
0E87   1E11             exg   x,x;   
0E89   1E11             exg   x,x;   
0E8B   0F0A             clr   0x0A;  
0E8D   20C5             bra   draw_relative_points; 


		 /*
		  * am_draw_with_pattern (point, scale_index, pattern)
		  *
		  * This moves the cursor to a particular point,
		  * using one of several scale factors, and a line
		  * pattern specified in C880.
		  * At entry:	'x' points to vector list of rel y, relx.
		  *		'a' has index into scale factor array.
		  *		C880 has line pattern.
		  */
		 am_draw_with_pattern:
0E8F   CE08E7           ldu   #am_scale_factors;    
0E92   A6C6             lda   a,u;     /* Load the scale factor */
0E94   9704             sta   0x04;  
0E96   EC81             ldd   ,x++;    /* Load vector endpoints */
0E98   9701             sta   0x01;  
0E9A   0F00             clr   0x00;  
0E9C   B6C880           lda   $C880;   /* Load line pattern from C880 */
0E9F   0C00             inc   0x00;  
0EA1   D701             stb   0x01;  
0EA3   0F05             clr   0x05;  
0EA5   970A             sta   0x0A;  
0EA7   8640             lda   #0x40;
0EA9   950D      P0EA9: bita  0x0D;  
0EAB   27FC             beq   P0EA9; 
0EAD   12               nop;    
0EAE   12               nop;    
0EAF   0F0A             clr   0x0A;    /* Clear the line pattern */ 
0EB1   39               rts;    


		 /*
		  * am_move_to_d()
		  *
		  * This routine does a quick move to the point
		  * specified in the 'd' register (a = rel y,
		  * b = rel x).  A scale factor of 0x7F is used.
		  */	
		 am_move_to_d:
0EB2   9701             sta   0x01;  
0EB4   0F00             clr   0x00;  
0EB6   867F             lda   #0x7F; 
0EB8   9704             sta   0x04;  
0EBA   86CE             lda   #0xCE; 
0EBC   970C             sta   0x0C;  
0EBE   8640             lda   #0x40; /* "@" */                                
0EC0   0C00             inc   0x00;  
0EC2   D701             stb   0x01;  
0EC4   0F05             clr   0x05;  
0EC6   950D      P0EC6: bita  0x0D;  
0EC8   27FC             beq   P0EC6; 
0ECA   39               rts;    


		 /*
		  * check_for_end_of_sound()
		  *
		  * This routine checks to see if the current
		  * miscellaneous sound has completed, by checking
		  * the value in C856.  When it reaches zero, the
		  * sound is done.
		  */
		 check_for_end_of_sound:
0ECB   7DC856           tst   $C856; 
0ECE   2604             bne   P0ED4; 
0ED0   BDF533           jsr   $init_music_buf;
0ED3   39               rts;    
0ED4   7AC856    P0ED4: dec   $C856; 
0ED7   39               rts;    


		 /*
		  * set_up_a_misc_sound1()
		  * set_up_a_misc_sound2(sound)
		  *
		  * Both of these routines cause a sound to be
		  * made.  If set_up_a_misc_sound1() is used,
		  * then the sound to be made is defined by
		  * writing the value 0x0050 to reg 0 & reg 1
		  * on the sound chip.  If set_up_a_misc_sound2()
		  * is used, then the value passed in in the 'd'
		  * register defines the sound.  The duration of
		  * the sound is stored in C856.
		  */
		 set_up_a_misc_sound1:
0ED8   CC0050           ldd   #0x0050;    
	 	 set_up_a_misc_sound2:
0EDB   FDC84B           std   $C84B; 
0EDE   863E             lda   #0x3E; /* ">" */                                
0EE0   B7C845           sta   $C845; 
0EE3   860A             lda   #0x0A; 
0EE5   B7C844           sta   $C844; 
0EE8   8605             lda   #0x05; 
0EEA   B7C856           sta   $C856; 
0EED   39               rts;    


		AM_music:
0EEE   FE               .word 0xFE28;
0EF0   FE               .word 0xFEB6;
0EF2   A6               .byte 0xA6;
0EF3   0A               .byte 0x0A;
0EF4   10               .byte 0x10;
0EF5   98               .byte 0x98;
0EF6   0A               .byte 0x0A;
0EF7   0C               .byte 0x0C;
0EF8   96               .byte 0x96;
0EF9   0A               .byte 0x0A;
0EFA   04               .byte 0x04;
0EFB   98               .byte 0x98;
0EFC   0C               .byte 0x0C;
0EFD   10               .byte 0x10;
0EFE   96               .byte 0x96;
0EFF   0C               .byte 0x0C;
0F00   0C               .byte 0x0C;
0F01   95               .byte 0x95;
0F02   0C               .byte 0x0C;
0F03   04               .byte 0x04;
0F04   96               .byte 0x96;
0F05   07               .byte 0x07;
0F06   10               .byte 0x10;
0F07   95               .byte 0x95;
0F08   07               .byte 0x07;
0F09   0C               .byte 0x0C;
0F0A   93               .byte 0x93;
0F0B   07               .byte 0x07;
0F0C   04               .byte 0x04;
0F0D   95               .byte 0x95;
0F0E   1A               .byte 0x1A;
0F0F   10               .byte 0x10;
0F10   92               .byte 0x92;
0F11   1A               .byte 0x1A;
0F12   10               .byte 0x10;
0F13   3F               .byte 0x3F; /* "?" */ 
0F14   80               .byte 0x80;

0F15   3B               .byte 0x3B; /* ";" */ 
0F16   00               .byte 0x00;
0F17   3B               .byte 0x3B; /* ";" */ 
0F18   00               .byte 0x00;
0F19   3B               .byte 0x3B; /* ";" */ 
0F1A   00               .byte 0x00;
0F1B   3B               .byte 0x3B; /* ";" */ 
0F1C   00               .byte 0x00;
0F1D   3B               .byte 0x3B; /* ";" */ 
0F1E   00               .byte 0x00;
0F1F   3B               .byte 0x3B; /* ";" */ 
0F20   00               .byte 0x00;
0F21   3B               .byte 0x3B; /* ";" */ 
0F22   00               .byte 0x00;
0F23   3B               .byte 0x3B; /* ";" */ 
0F24   00               .byte 0x00;
0F25   3B               .byte 0x3B; /* ";" */ 
0F26   00               .byte 0x00;
0F27   3B               .byte 0x3B; /* ";" */ 
0F28   00               .byte 0x00;
0F29   3B               .byte 0x3B; /* ";" */ 
0F2A   00               .byte 0x00;
0F2B   3B               .byte 0x3B; /* ";" */ 
0F2C   00               .byte 0x00;
0F2D   3B               .byte 0x3B; /* ";" */ 
0F2E   00               .byte 0x00;
0F2F   3B               .byte 0x3B; /* ";" */ 
0F30   00               .byte 0x00;
0F31   3B               .byte 0x3B; /* ";" */ 
0F32   00               .byte 0x00;
0F33   3B               .byte 0x3B; /* ";" */ 
0F34   00               .byte 0x00;
0F35   3B               .byte 0x3B; /* ";" */ 
0F36   00               .byte 0x00;
0F37   3B               .byte 0x3B; /* ";" */ 
0F38   00               .byte 0x00;
0F39   3B               .byte 0x3B; /* ";" */ 
0F3A   00               .byte 0x00;
0F3B   3B               .byte 0x3B; /* ";" */ 
0F3C   00               .byte 0x00;
0F3D   3B               .byte 0x3B; /* ";" */ 
0F3E   00               .byte 0x00;
0F3F   3B               .byte 0x3B; /* ";" */ 
0F40   00               .byte 0x00;
0F41   3B               .byte 0x3B; /* ";" */ 
0F42   00               .byte 0x00;
0F43   3B               .byte 0x3B; /* ";" */ 
0F44   00               .byte 0x00;
0F45   3B               .byte 0x3B; /* ";" */ 
0F46   00               .byte 0x00;
0F47   3B               .byte 0x3B; /* ";" */ 
0F48   00               .byte 0x00;
0F49   3B               .byte 0x3B; /* ";" */ 
0F4A   00               .byte 0x00;
0F4B   3B               .byte 0x3B; /* ";" */ 
0F4C   00               .byte 0x00;
0F4D   3B               .byte 0x3B; /* ";" */ 
0F4E   00               .byte 0x00;
0F4F   3B               .byte 0x3B; /* ";" */ 
0F50   00               .byte 0x00;
0F51   3B               .byte 0x3B; /* ";" */ 
0F52   00               .byte 0x00;
0F53   3B               .byte 0x3B; /* ";" */ 
0F54   00               .byte 0x00;
0F55   3B               .byte 0x3B; /* ";" */ 
0F56   00               .byte 0x00;
0F57   3B               .byte 0x3B; /* ";" */ 
0F58   00               .byte 0x00;
0F59   3B               .byte 0x3B; /* ";" */ 
0F5A   00               .byte 0x00;
0F5B   3B               .byte 0x3B; /* ";" */ 
0F5C   00               .byte 0x00;
0F5D   3B               .byte 0x3B; /* ";" */ 
0F5E   00               .byte 0x00;
0F5F   3B               .byte 0x3B; /* ";" */ 
0F60   00               .byte 0x00;
0F61   3B               .byte 0x3B; /* ";" */ 
0F62   00               .byte 0x00;
0F63   3B               .byte 0x3B; /* ";" */ 
0F64   00               .byte 0x00;
0F65   3B               .byte 0x3B; /* ";" */ 
0F66   00               .byte 0x00;
0F67   3B               .byte 0x3B; /* ";" */ 
0F68   00               .byte 0x00;
0F69   3B               .byte 0x3B; /* ";" */ 
0F6A   00               .byte 0x00;
0F6B   3B               .byte 0x3B; /* ";" */ 
0F6C   00               .byte 0x00;
0F6D   3B               .byte 0x3B; /* ";" */ 
0F6E   00               .byte 0x00;
0F6F   3B               .byte 0x3B; /* ";" */ 
0F70   00               .byte 0x00;
0F71   3B               .byte 0x3B; /* ";" */ 
0F72   00               .byte 0x00;
0F73   3B               .byte 0x3B; /* ";" */ 
0F74   00               .byte 0x00;
0F75   3B               .byte 0x3B; /* ";" */ 
0F76   00               .byte 0x00;
0F77   3B               .byte 0x3B; /* ";" */ 
0F78   00               .byte 0x00;
0F79   3B               .byte 0x3B; /* ";" */ 
0F7A   00               .byte 0x00;
0F7B   3B               .byte 0x3B; /* ";" */ 
0F7C   00               .byte 0x00;
0F7D   3B               .byte 0x3B; /* ";" */ 
0F7E   33               .byte 0x33; /* "3" */ 
0F7F   00               .byte 0x00;
0F80   69               .byte 0x69; /* "i" */ 
0F81   84               .byte 0x84;
0F82   00               .byte 0x00;
0F83   69               .byte 0x69; /* "i" */ 
0F84   84               .byte 0x84;
0F85   3B               .byte 0x3B; /* ";" */ 
0F86   00               .byte 0x00;
0F87   3B               .byte 0x3B; /* ";" */ 
0F88   00               .byte 0x00;
0F89   3B               .byte 0x3B; /* ";" */ 
0F8A   00               .byte 0x00;
0F8B   3B               .byte 0x3B; /* ";" */ 
0F8C   00               .byte 0x00;
0F8D   3B               .byte 0x3B; /* ";" */ 
0F8E   00               .byte 0x00;
0F8F   3B               .byte 0x3B; /* ";" */ 
0F90   00               .byte 0x00;
0F91   3B               .byte 0x3B; /* ";" */ 
0F92   00               .byte 0x00;
0F93   3B               .byte 0x3B; /* ";" */ 
0F94   00               .byte 0x00;
0F95   3B               .byte 0x3B; /* ";" */ 
0F96   00               .byte 0x00;
0F97   3B               .byte 0x3B; /* ";" */ 
0F98   00               .byte 0x00;
0F99   3B               .byte 0x3B; /* ";" */ 
0F9A   00               .byte 0x00;
0F9B   3B               .byte 0x3B; /* ";" */ 
0F9C   00               .byte 0x00;
0F9D   3B               .byte 0x3B; /* ";" */ 
0F9E   00               .byte 0x00;
0F9F   3B               .byte 0x3B; /* ";" */ 
0FA0   00               .byte 0x00;
0FA1   3B               .byte 0x3B; /* ";" */ 
0FA2   00               .byte 0x00;
0FA3   3B               .byte 0x3B; /* ";" */ 
0FA4   00               .byte 0x00;
0FA5   3B               .byte 0x3B; /* ";" */ 
0FA6   00               .byte 0x00;
0FA7   3B               .byte 0x3B; /* ";" */ 
0FA8   00               .byte 0x00;
0FA9   3B               .byte 0x3B; /* ";" */ 
0FAA   00               .byte 0x00;
0FAB   3B               .byte 0x3B; /* ";" */ 
0FAC   00               .byte 0x00;
0FAD   3B               .byte 0x3B; /* ";" */ 
0FAE   00               .byte 0x00;
0FAF   3B               .byte 0x3B; /* ";" */ 
0FB0   00               .byte 0x00;
0FB1   3B               .byte 0x3B; /* ";" */ 
0FB2   00               .byte 0x00;
0FB3   3B               .byte 0x3B; /* ";" */ 
0FB4   00               .byte 0x00;
0FB5   3B               .byte 0x3B; /* ";" */ 
0FB6   00               .byte 0x00;
0FB7   3B               .byte 0x3B; /* ";" */ 
0FB8   00               .byte 0x00;
0FB9   3B               .byte 0x3B; /* ";" */ 
0FBA   00               .byte 0x00;
0FBB   3B               .byte 0x3B; /* ";" */ 
0FBC   00               .byte 0x00;
0FBD   3B               .byte 0x3B; /* ";" */ 
0FBE   00               .byte 0x00;
0FBF   3B               .byte 0x3B; /* ";" */ 
0FC0   00               .byte 0x00;
0FC1   3B               .byte 0x3B; /* ";" */ 
0FC2   00               .byte 0x00;
0FC3   3B               .byte 0x3B; /* ";" */ 
0FC4   00               .byte 0x00;
0FC5   3B               .byte 0x3B; /* ";" */ 
0FC6   00               .byte 0x00;
0FC7   3B               .byte 0x3B; /* ";" */ 
0FC8   00               .byte 0x00;
0FC9   3B               .byte 0x3B; /* ";" */ 
0FCA   00               .byte 0x00;
0FCB   3B               .byte 0x3B; /* ";" */ 
0FCC   00               .byte 0x00;
0FCD   3B               .byte 0x3B; /* ";" */ 
0FCE   00               .byte 0x00;
0FCF   3B               .byte 0x3B; /* ";" */ 
0FD0   00               .byte 0x00;
0FD1   3B               .byte 0x3B; /* ";" */ 
0FD2   00               .byte 0x00;
0FD3   3B               .byte 0x3B; /* ";" */ 
0FD4   00               .byte 0x00;
0FD5   3B               .byte 0x3B; /* ";" */ 
0FD6   00               .byte 0x00;
0FD7   3B               .byte 0x3B; /* ";" */ 
0FD8   00               .byte 0x00;
0FD9   3B               .byte 0x3B; /* ";" */ 
0FDA   00               .byte 0x00;
0FDB   3B               .byte 0x3B; /* ";" */ 
0FDC   00               .byte 0x00;
0FDD   3B               .byte 0x3B; /* ";" */ 
0FDE   00               .byte 0x00;
0FDF   3B               .byte 0x3B; /* ";" */ 
0FE0   00               .byte 0x00;
0FE1   3B               .byte 0x3B; /* ";" */ 
0FE2   00               .byte 0x00;
0FE3   3B               .byte 0x3B; /* ";" */ 
0FE4   00               .byte 0x00;
0FE5   3B               .byte 0x3B; /* ";" */ 
0FE6   00               .byte 0x00;
0FE7   3B               .byte 0x3B; /* ";" */ 
0FE8   00               .byte 0x00;
0FE9   3B               .byte 0x3B; /* ";" */ 
0FEA   00               .byte 0x00;
0FEB   3B               .byte 0x3B; /* ";" */ 
0FEC   00               .byte 0x00;
0FED   3B               .byte 0x3B; /* ";" */ 
0FEE   00               .byte 0x00;
0FEF   3B               .byte 0x3B; /* ";" */ 
0FF0   00               .byte 0x00;
0FF1   3B               .byte 0x3B; /* ";" */ 
0FF2   00               .byte 0x00;
0FF3   3B               .byte 0x3B; /* ";" */ 
0FF4   00               .byte 0x00;
0FF5   3B               .byte 0x3B; /* ";" */ 
0FF6   00               .byte 0x00;
0FF7   3B               .byte 0x3B; /* ";" */ 
0FF8   00               .byte 0x00;
0FF9   3B               .byte 0x3B; /* ";" */ 
0FFA   00               .byte 0x00;
0FFB   3B               .byte 0x3B; /* ";" */ 
0FFC   00               .byte 0x00;
0FFD   3B               .byte 0x3B; /* ";" */ 
0FFE   00               .byte 0x00;
0FFF   3B               .byte 0x3B; /* ";" */ 




