Hi Daryl,
I thought of a way to speed up processing speed of at least some instructions. In your case you have to use a table with "jmp" instructions as a table with "rjmp" would not work as they don't reach far enough. However a "rjmp" table would not require the "lsl" and "adc" in the EXEC macro.
So I did the following:
- removed "lsl" and "adc" from EXEC
- replaced the "jmp" with "rjmp" in opctbl: and changed the destination to a label starting with __ (2) instead _ (1) and placed it strategically in the middle of the 6502 instruction emulation code (I use the align macro of Klaus to make sure the table starts at a 256word boundary)
- added a buch of lines with "__label: jmp _label" near the opctbl
- moved the more common instruction code near the opctbl (ADC, BEQ, BNE, CMP, JMP, JSR, LDA, LDX, LDY, STA, STX, STY, SBC, RTS) and changed the destination in the opctbl to the label with a single _
- I do not delete the added lines with the "jmp" instructions, even if they are not used, so I can easily switch back and forth just be changing the destination of "rjmp" in the opctbl
Now it would be interesting to know how you bencharked your emulator to see if this effort is worth it. Here just some excerpts of the changed code
align 8
opctbl:
rjmp __BRK_IMP ;00
rjmp __ORA_INDX ;01
.
.
.
rjmp __STY_ABS ;8C
rjmp _STA_ABS ;8D
rjmp __STX_ABS ;8E
rjmp __BBS0_REL ;8F
rjmp __BCC_REL ;90
rjmp _STA_INDY ;91
rjmp _STA_IND ;92
rjmp __INV ;93
rjmp __STY_ZPGX ;94
rjmp _STA_ZPGX ;95 <--- sample of abbreviation
rjmp __STX_ZPGY ;96
rjmp __SMB1_ZPG ;97
rjmp __TYA_IMP ;98
rjmp _STA_ABSY ;99 <--- sample of abbreviation
rjmp __TXS_IMP ;9A
rjmp __INV ;9B
rjmp __STZ_ABS ;9C
rjmp _STA_ABSX ;9D <--- sample of abbreviation
rjmp __STZ_ABSX ;9E
.
.
.
rjmp __INV ;E3
rjmp __CPX_ZPG ;E4
rjmp __SBC_ZPG ;E5
rjmp __INC_ZPG ;E6
rjmp __SMB6_ZPG ;E7
rjmp __INX_IMP ;E8
rjmp __SBC_IMM ;E9
rjmp __NOP_IMP ;EA
rjmp __INV ;EB
rjmp __CPX_ABS ;EC
rjmp __SBC_ABS ;ED
rjmp __INC_ABS ;EE
rjmp __BBS6_REL ;EF
rjmp __BEQ_REL ;F0
rjmp __SBC_INDY ;F1
rjmp __SBC_IND ;F2
rjmp __INV ;F3
rjmp __INV2 ;F4
rjmp __SBC_ZPGX ;F5
rjmp __INC_ZPGX ;F6
rjmp __SMB7_ZPG ;F7
rjmp __SED_IMP ;F8
rjmp __SBC_ABSY ;F9
rjmp __PLX_IMP ;FA
rjmp __INV ;FB
rjmp __INV3 ;FC
rjmp __SBC_ABSX ;FD
rjmp __INC_ABSX ;FE
rjmp __BBS7_REL ;FF
__INV2: jmp _INV2 ;02
__INV: jmp _INV ;03
__INV3: jmp _INV3 ;5C
__BRK_IMP: jmp _BRK_IMP ;00
__ORA_INDX: jmp _ORA_INDX ;01
__TSB_ZPG: jmp _TSB_ZPG ;04
__ORA_ZPG: jmp _ORA_ZPG ;05
__ASL_ZPG: jmp _ASL_ZPG ;06
__RMB0_ZPG: jmp _RMB0_ZPG ;07
__PHP_IMP: jmp _PHP_IMP ;08
__ORA_IMM: jmp _ORA_IMM ;09
__ASL_IMP: jmp _ASL_IMP ;0A
__TSB_ABS: jmp _TSB_ABS ;0C
__ORA_ABS: jmp _ORA_ABS ;0D
__ASL_ABS: jmp _ASL_ABS ;0E
__BBR0_REL: jmp _BBR0_REL ;0F
__BPL_REL: jmp _BPL_REL ;10
__ORA_INDY: jmp _ORA_INDY ;11
__ORA_IND: jmp _ORA_IND ;12
__TRB_ZPG: jmp _TRB_ZPG ;14
__ORA_ZPGX: jmp _ORA_ZPGX ;15
__ASL_ZPGX: jmp _ASL_ZPGX ;16
__RMB1_ZPG: jmp _RMB1_ZPG ;17
__CLC_IMP: jmp _CLC_IMP ;18
__ORA_ABSY: jmp _ORA_ABSY ;19
__INC_IMP: jmp _INC_IMP ;1A
__TRB_ABS: jmp _TRB_ABS ;1C
__ORA_ABSX: jmp _ORA_ABSX ;1D
__ASL_ABSX: jmp _ASL_ABSX ;1E
__BBR1_REL: jmp _BBR1_REL ;1F
__JSR_ABS: jmp _JSR_ABS ;20
For the fast Instructions you save 3 cycles: no "lsl zl" and "adc zh,adc" and a "rjmp" from opcode table instead of "jmp".
For legacy Instructions you save/lose nothing, you just replace the "lsl zl" and "adc zh,adc" with a "rjmp".
Now one could think of some "intermediate" instructions, that would be those that could be made reachable with 2 x "rjmp" instead a "rjmp" and a "jmp"
Regards
Peter
P.S.: Now added the SRAM to my hardware, I use only portc together with an address latch so I need only 9 instead of 16 pins for the address bus (the 9th is the clock of the latch), I'm currently using your emulator to run memory tests