User Tools

Site Tools


base:dispatch_on_a_byte

Dispatching on a Byte

by White Flame and Krill

The need to dispatch to one of many possible routines based on the value of a byte comes up regularly if you're doing complex data-oriented routines like decompression or scripting, and most often needs to be as fast as possible.

All but the Stack Dispatch routine use self-modification, which will run 1 cycle faster and 1 byte leaner if the dispatch routine itself is in zeropage.

General Table Dispatch

  sta :+ +1
: jmp (table)
 
table:
  .word handler0, handler2, handler4, ...
  • 9 cycles, 8 if from zeropage
  • Align opcodes and table low-word, or use SBC/ASL to adjust
  • Maximum of 128 entries

More than 128 entries

  asl
  bcs :++
  ; Dispatch 0-127
  sta :+ +1
: jmp (table)
  ; Dispatch 128-255
: sta :+ +1
: jmp (table + $0100)
 
table: .word handler0, handler1, ..., handler127, handler128, ...
  • 13 cycles for 0-127, 14 cycles for 128-255. Subtract 1 cycle if from zeropage.

Stack Dispatch

  tax
  txs
  rts
  • 8 or 10 cycles, depending on if TAX is necessary
  • Table of vectors at $0100
  • Maximum of 128 entries
  • Handlers cannot use stack, or must reposition it to not trample the table

Low-Address Dispatch

  sta :+ +1
: jmp routine  ; Low byte is overwritten, high byte remains
  • 7 cycles, 6 if in zeropage
  • All handlers start in the same memory page
  • Byte codes match specific addresses with little flexibility

High-Address Dispatch

  sta :+ +2
: jmp $0000  ; High byte is overwritten, low byte remains
  • 7 cycles, 6 if in zeropage
  • All handlers start on their own page, at the same low byte
  • Byte codes constrained to ranges based on memory map

Relative Branch Dispatch

  sta :+ +1
: bne *  ; If Z corresponds to A, otherwise use appropriate BRA
  • 7 cycles, 6 if in zeropage
  • Similar to low-address dispatch but allows page-crosses at the cost of one cycle
  • Saves one cycle for the fall-through case
base/dispatch_on_a_byte.txt · Last modified: 2015-04-17 04:31 (external edit)