/* * 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; /* ";" */