I'm not familiar with x86 and BIOS methods, so I hope this isn't a waste of attention; but since you're using the NMOS 6502, before the 65c02 came along with its JMP(abs,X) instruction, a way to do an indirect jump using a jump table with the NMOS 6502 was:
Code:
; Start with function (an even number) in X.
LDA TABLE+1,X ; Read high address byte from the actual table, and
PHA ; push it. Low byte comes next, below.
LDA TABLE,X ; Be sure to make the table reflect start addresses
PHA ; minus 1, since RTS increments the address by 1.
RTS ; RTS does the absolute indexed indirect jump.
Then to keep the performance up for true interrupts, you can avoid BRK altogether with its high overhead and do this:
Code:
LDX #<function_number>
JSR <BIOS>
<continue>
and "BIOS" is the label for the above starting with LDA TABLE+1,X. The routine you jump to will end with RTS, taking you back to where it says "<continue>". A particular function number can remain that number (which you'll probably give a meaningful name to), even if the addresses in the table have to change with later updates.
If you're using something like a Commodore 64 where you really can't use the CMOS version, you could still make a macro of the above routine, to get it on a single line, as BDD suggested with his example of "INT x" where "x" is the function number-- and actually I would give it a meaningful name. (You can read about the differences between the CMOS and NMOS 6502 in
this article.)
In the above piece of code, the table has two consecutive bytes for each entry. This means you can't have a table of more than 128 entries, and depending on what you start with, you might have to put the entry number in the accumulator and do ASL before putting it in X. (That's why the first comment line says you must start with an even number in X.) A way around that is to split the table into two halves, one half having the high bytes and one having the low bytes. Now each half, indexed by the same number in X or Y compared to the other half, can be up to 256 bytes, meaning you can have 256 entries, even though they're two bytes each. It would go like this instead:
Code:
LDA high-byte table, X ; Again, be sure to make the table reflect start addresses
PHA ; minus 1, since RTS increments the address by 1.
LDA low-byte table, X
PHA
RTS
This technique is useful for token threading which has been used in interpreted BASIC and other interpreted languages. There's more discussion on it in
this article in the 6502.org wiki.