Osi wrote:
Hi tius,
to calculate the instruction length for a 6502 CPU, here the code I'm using in one of my programs:
...
to calculate the instruction length for a 6502 CPU, here the code I'm using in one of my programs:
...
Code: Select all
instruction_size:
ldx #3
eor #$03
bit #$03
beq @one ; x3, x7, xB, xF
Code: Select all
x2: x3: x4: x7: xB: xC: xF:
----- ----- ----- ----- ----- ----- -----
0x: 2 2 . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
1x: . . . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
2x: 2 2 . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
3x: . . . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
4x: 2 2 . 1 1 . 2 3 g 1 1 a 1 1 . . . . 1 1 c
5x: . . . 1 1 . 2 4 h 1 1 a 1 1 . 3 8 j 1 1 c
6x: 2 2 . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
7x: . . . 1 1 . . . . 1 1 a 1 1 . . . . 1 1 c
8x: 2 2 . 1 1 . . . . 1 1 b 1 1 . . . . 1 1 d
9x: . . . 1 1 . . . . 1 1 b 1 1 . . . . 1 1 d
Ax: . . . 1 1 . . . . 1 1 b 1 1 . . . . 1 1 d
Bx: . . . 1 1 . . . . 1 1 b 1 1 . . . . 1 1 d
Cx: 2 2 . 1 1 . . . . 1 1 b 1 1 e . . . 1 1 d
Dx: . . . 1 1 . 2 4 h 1 1 b 1 1 f 3 4 i 1 1 d
Ex: 2 2 . 1 1 . . . . 1 1 b 1 1 . . . . 1 1 d
Fx: . . . 1 1 . 2 4 h 1 1 b 1 1 . 3 4 i 1 1 d
a) 1-cycle NOP on some older 65C02s; RMB instruction on Rockwell and on modern WDC 65C02s
b) 1-cycle NOP on some older 65C02s; SMB instruction on Rockwell and on modern WDC 65C02s
c) 1-cycle NOP on some older 65C02s; BBR instruction on Rockwell and on modern WDC 65C02s
d) 1-cycle NOP on some older 65C02s; BBS instruction on Rockwell and on modern WDC 65C02s
e) $CB is the WAI instruction on WDC 65C02
f) $DB is the STP instruction on WDC 65C02
g) $44 uses zp address mode to read memory
h) $54, $D4, and $F4 use zp,X address mode to read memory
i) $DC and $FC use absolute address mode to read memory
j) $5C reads from somewhere in the 64K range, using no known address mode
Code: Select all
op_length:
; given an opcode in A, return its length in Y (stomps A)
pha
and #$f
tay
lda _lengths,y ; lookup the length
bmi _special ; $x0 and $x9 are special
ply ; discard the opcode
tay ; return the length
rts
_lengths: .byte $80,2,2,1,2,2,2,2, 1,$81,1,1,3,3,3,3
_special:
ldy #1 ; guess length 1
ror ; test bit 0: C=0 means $x0, C=1 means $x9
pla ; recover the opcode
bcs _x9
; for $x0 length is two except $20 (3), $40 (1), $60 (1)
bit #%10011111 ; is opcode 0/20/40/60 ?
bne _two
asl ; test bit 6 by shifting to sign bit
bmi _one ; bit 6 set means $40 or $60
; otherwise we have A=$40 if op was $20 and $0 otherwise
; shift right twice to reuse bit 4 test
lsr
lsr
_x9:
; for $x9, bit 4 set means 3 bytes, clear means 2
and #$10
beq _two
_three: iny
_two: iny
_one: rts