From 7b82145a8c290ba985665cec20890fbf19e8720a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 5 Jun 2020 23:25:56 +0200 Subject: [PATCH] faster command jumptable handling in BASIC, added 65C02 optimized version --- c64/basic/basic_execute_line.s | 29 +- c64/basic/commands/command_jumptable.s | 566 +++++++++++++++++++------ 2 files changed, 457 insertions(+), 138 deletions(-) diff --git a/c64/basic/basic_execute_line.s b/c64/basic/basic_execute_line.s index f062b4a8..3120eb63 100644 --- a/c64/basic/basic_execute_line.s +++ b/c64/basic/basic_execute_line.s @@ -63,20 +63,31 @@ basic_execute_statement: cmp #$7f bcc not_a_token - // It is a token: So get the jump table entry for it, push it on the stack - // and then RTS to start it. - asl - tax - lda command_jumptable+1,x - pha - lda command_jumptable+0,x - pha - // Now consume the character + // It is a token - consume this character + jsr consume_character + +#if !HAS_OPCODES_65C02 + + // Get the jump table entry for it, push it on the stack, and then RTS to start it. + + tax + lda command_jumptable_hi - $80, x + pha + lda command_jumptable_lo - $80, x + pha rts +#else // HAS_OPCODES_65C02 + + asl + tax + jmp (command_jumptable, x) + +#endif + not_a_token: // Space, which we can also just ignore cmp #$20 diff --git a/c64/basic/commands/command_jumptable.s b/c64/basic/commands/command_jumptable.s index f45137cf..0f72c98c 100644 --- a/c64/basic/commands/command_jumptable.s +++ b/c64/basic/commands/command_jumptable.s @@ -7,149 +7,457 @@ // +#if !HAS_OPCODES_65C02 + + +command_jumptable_lo: + + // $80 - $8F + .byte <(cmd_end-1) + .byte <(cmd_for-1) + .byte <(cmd_next-1) + .byte <(cmd_data-1) + .byte <(cmd_inputhash-1) + .byte <(cmd_input-1) + .byte <(cmd_dim-1) + .byte <(cmd_read-1) + .byte <(cmd_let-1) + .byte <(cmd_goto-1) + .byte <(cmd_run-1) + .byte <(cmd_if-1) + .byte <(cmd_restore-1) + .byte <(cmd_gosub-1) + .byte <(cmd_return-1) + .byte <(cmd_rem-1) + + // $90-$9F + .byte <(cmd_stop-1) + .byte <(cmd_on-1) + .byte <(cmd_wait-1) + .byte <(cmd_load-1) + .byte <(cmd_save-1) + .byte <(cmd_verify-1) + .byte <(cmd_def-1) + .byte <(cmd_poke-1) + .byte <(cmd_printhash-1) + .byte <(cmd_print-1) + .byte <(cmd_cont-1) + .byte <(cmd_list-1) + .byte <(cmd_clr-1) + .byte <(cmd_cmd-1) + .byte <(cmd_sys-1) + .byte <(cmd_open-1) + + // $A0-$AF + .byte <(cmd_close-1) + .byte <(cmd_get-1) + .byte <(cmd_new-1) + .byte <(cmd_tab-1) + .byte <(cmd_to-1) + .byte <(cmd_fn-1) + .byte <(cmd_spc-1) + .byte <(cmd_then-1) + .byte <(cmd_not-1) + .byte <(cmd_step-1) + .byte <(cmd_plus-1) + .byte <(cmd_minus-1) + .byte <(cmd_mult-1) + .byte <(cmd_div-1) + .byte <(cmd_exponent-1) + .byte <(cmd_and-1) + + // $B0-$BF + .byte <(cmd_or-1) + .byte <(cmd_greater-1) + .byte <(cmd_equal-1) + .byte <(cmd_less-1) + .byte <(cmd_sgn-1) + .byte <(cmd_int-1) + .byte <(cmd_abs-1) + .byte <(cmd_usr-1) + .byte <(cmd_fre-1) + .byte <(cmd_pos-1) + .byte <(cmd_sqr-1) + .byte <(cmd_rnd-1) + .byte <(cmd_log-1) + .byte <(cmd_exp-1) + .byte <(cmd_cos-1) + .byte <(cmd_sin-1) + + // $C0-$CF + .byte <(cmd_tan-1) + .byte <(cmd_atn-1) + .byte <(cmd_peek-1) + .byte <(cmd_len-1) + .byte <(cmd_str-1) + .byte <(cmd_val-1) + .byte <(cmd_asc-1) + .byte <(cmd_chr-1) + .byte <(cmd_left-1) + .byte <(cmd_right-1) + .byte <(cmd_mid-1) + .byte <(cmd_go-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + + // $D0-$DF + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + + // $E0-$EF + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + + // $F0-$FF + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + .byte <(cmd_unimplemented-1) + + +command_jumptable_hi: + + // $80 - $8F + .byte >(cmd_end-1) + .byte >(cmd_for-1) + .byte >(cmd_next-1) + .byte >(cmd_data-1) + .byte >(cmd_inputhash-1) + .byte >(cmd_input-1) + .byte >(cmd_dim-1) + .byte >(cmd_read-1) + .byte >(cmd_let-1) + .byte >(cmd_goto-1) + .byte >(cmd_run-1) + .byte >(cmd_if-1) + .byte >(cmd_restore-1) + .byte >(cmd_gosub-1) + .byte >(cmd_return-1) + .byte >(cmd_rem-1) + + // $90-$9F + .byte >(cmd_stop-1) + .byte >(cmd_on-1) + .byte >(cmd_wait-1) + .byte >(cmd_load-1) + .byte >(cmd_save-1) + .byte >(cmd_verify-1) + .byte >(cmd_def-1) + .byte >(cmd_poke-1) + .byte >(cmd_printhash-1) + .byte >(cmd_print-1) + .byte >(cmd_cont-1) + .byte >(cmd_list-1) + .byte >(cmd_clr-1) + .byte >(cmd_cmd-1) + .byte >(cmd_sys-1) + .byte >(cmd_open-1) + + // $A0-$AF + .byte >(cmd_close-1) + .byte >(cmd_get-1) + .byte >(cmd_new-1) + .byte >(cmd_tab-1) + .byte >(cmd_to-1) + .byte >(cmd_fn-1) + .byte >(cmd_spc-1) + .byte >(cmd_then-1) + .byte >(cmd_not-1) + .byte >(cmd_step-1) + .byte >(cmd_plus-1) + .byte >(cmd_minus-1) + .byte >(cmd_mult-1) + .byte >(cmd_div-1) + .byte >(cmd_exponent-1) + .byte >(cmd_and-1) + + // $B0-$BF + .byte >(cmd_or-1) + .byte >(cmd_greater-1) + .byte >(cmd_equal-1) + .byte >(cmd_less-1) + .byte >(cmd_sgn-1) + .byte >(cmd_int-1) + .byte >(cmd_abs-1) + .byte >(cmd_usr-1) + .byte >(cmd_fre-1) + .byte >(cmd_pos-1) + .byte >(cmd_sqr-1) + .byte >(cmd_rnd-1) + .byte >(cmd_log-1) + .byte >(cmd_exp-1) + .byte >(cmd_cos-1) + .byte >(cmd_sin-1) + + // $C0-$CF + .byte >(cmd_tan-1) + .byte >(cmd_atn-1) + .byte >(cmd_peek-1) + .byte >(cmd_len-1) + .byte >(cmd_str-1) + .byte >(cmd_val-1) + .byte >(cmd_asc-1) + .byte >(cmd_chr-1) + .byte >(cmd_left-1) + .byte >(cmd_right-1) + .byte >(cmd_mid-1) + .byte >(cmd_go-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + + // $D0-$DF + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + + // $E0-$EF + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + + // $F0-$FF + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + .byte >(cmd_unimplemented-1) + + +#else // HAS_OPCODES_65C02 + +__before_command_jumptable: + +.if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary + command_jumptable: // $80 - $8F - .word cmd_end-1 - .word cmd_for-1 - .word cmd_next-1 - .word cmd_data-1 - .word cmd_inputhash-1 - .word cmd_input-1 - .word cmd_dim-1 - .word cmd_read-1 - .word cmd_let-1 - .word cmd_goto-1 - .word cmd_run-1 - .word cmd_if-1 - .word cmd_restore-1 - .word cmd_gosub-1 - .word cmd_return-1 - .word cmd_rem-1 + .word cmd_end + .word cmd_for + .word cmd_next + .word cmd_data + .word cmd_inputhash + .word cmd_input + .word cmd_dim + .word cmd_read + .word cmd_let + .word cmd_goto + .word cmd_run + .word cmd_if + .word cmd_restore + .word cmd_gosub + .word cmd_return + .word cmd_rem // $90-$9F - .word cmd_stop-1 - .word cmd_on-1 - .word cmd_wait-1 - .word cmd_load-1 - .word cmd_save-1 - .word cmd_verify-1 - .word cmd_def-1 - .word cmd_poke-1 - .word cmd_printhash-1 - .word cmd_print-1 - .word cmd_cont-1 - .word cmd_list-1 - .word cmd_clr-1 - .word cmd_cmd-1 - .word cmd_sys-1 - .word cmd_open-1 + .word cmd_stop + .word cmd_on + .word cmd_wait + .word cmd_load + .word cmd_save + .word cmd_verify + .word cmd_def + .word cmd_poke + .word cmd_printhash + .word cmd_print + .word cmd_cont + .word cmd_list + .word cmd_clr + .word cmd_cmd + .word cmd_sys + .word cmd_open // $A0-$AF - .word cmd_close-1 - .word cmd_get-1 - .word cmd_new-1 - .word cmd_tab-1 - .word cmd_to-1 - .word cmd_fn-1 - .word cmd_spc-1 - .word cmd_then-1 - .word cmd_not-1 - .word cmd_step-1 - .word cmd_plus-1 - .word cmd_minus-1 - .word cmd_mult-1 - .word cmd_div-1 - .word cmd_exponent-1 - .word cmd_and-1 + .word cmd_close + .word cmd_get + .word cmd_new + .word cmd_tab + .word cmd_to + .word cmd_fn + .word cmd_spc + .word cmd_then + .word cmd_not + .word cmd_step + .word cmd_plus + .word cmd_minus + .word cmd_mult + .word cmd_div + .word cmd_exponent + .word cmd_and // $B0-$BF - .word cmd_or-1 - .word cmd_greater-1 - .word cmd_equal-1 - .word cmd_less-1 - .word cmd_sgn-1 - .word cmd_int-1 - .word cmd_abs-1 - .word cmd_usr-1 - .word cmd_fre-1 - .word cmd_pos-1 - .word cmd_sqr-1 - .word cmd_rnd-1 - .word cmd_log-1 - .word cmd_exp-1 - .word cmd_cos-1 - .word cmd_sin-1 + .word cmd_or + .word cmd_greater + .word cmd_equal + .word cmd_less + .word cmd_sgn + .word cmd_int + .word cmd_abs + .word cmd_usr + .word cmd_fre + .word cmd_pos + .word cmd_sqr + .word cmd_rnd + .word cmd_log + .word cmd_exp + .word cmd_cos + .word cmd_sin // $C0-$CF - .word cmd_tan-1 - .word cmd_atn-1 - .word cmd_peek-1 - .word cmd_len-1 - .word cmd_str-1 - .word cmd_val-1 - .word cmd_asc-1 - .word cmd_chr-1 - .word cmd_left-1 - .word cmd_right-1 - .word cmd_mid-1 - .word cmd_go-1 - // Undefined tokens - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 + .word cmd_tan + .word cmd_atn + .word cmd_peek + .word cmd_len + .word cmd_str + .word cmd_val + .word cmd_asc + .word cmd_chr + .word cmd_left + .word cmd_right + .word cmd_mid + .word cmd_go + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented // $D0-$DF - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented // $E0-$EF - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented // $F0-$FF - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 - .word cmd_unimplemented-1 + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + .word cmd_unimplemented + + // Make sure routine size is always the same - build system limitation + +.if (__before_command_jumptable == command_jumptable) { brk } + +#endif