define instruction set and opcode decoding tables
This commit is contained in:
@@ -0,0 +1,150 @@
|
|||||||
|
pub const AddressingMode = enum {
|
||||||
|
implied,
|
||||||
|
accumulator,
|
||||||
|
immediate,
|
||||||
|
zero_page,
|
||||||
|
zero_page_x,
|
||||||
|
zero_page_y,
|
||||||
|
relative,
|
||||||
|
absolute,
|
||||||
|
absolute_x,
|
||||||
|
absolute_y,
|
||||||
|
indirect,
|
||||||
|
indexed_indirect_x,
|
||||||
|
indirect_indexed_y,
|
||||||
|
|
||||||
|
// 65C02 additions
|
||||||
|
zero_page_indirect,
|
||||||
|
absolute_indexed_indirect,
|
||||||
|
zero_page_relative,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Operation = enum {
|
||||||
|
adc,
|
||||||
|
@"and",
|
||||||
|
asl,
|
||||||
|
bcc,
|
||||||
|
bcs,
|
||||||
|
beq,
|
||||||
|
bit,
|
||||||
|
bmi,
|
||||||
|
bne,
|
||||||
|
bpl,
|
||||||
|
brk,
|
||||||
|
bvc,
|
||||||
|
bvs,
|
||||||
|
clc,
|
||||||
|
cld,
|
||||||
|
cli,
|
||||||
|
clv,
|
||||||
|
cmp,
|
||||||
|
cpx,
|
||||||
|
cpy,
|
||||||
|
dec,
|
||||||
|
dex,
|
||||||
|
dey,
|
||||||
|
eor,
|
||||||
|
inc,
|
||||||
|
inx,
|
||||||
|
iny,
|
||||||
|
jmp,
|
||||||
|
jsr,
|
||||||
|
lda,
|
||||||
|
ldx,
|
||||||
|
ldy,
|
||||||
|
lsr,
|
||||||
|
nop,
|
||||||
|
ora,
|
||||||
|
pha,
|
||||||
|
php,
|
||||||
|
pla,
|
||||||
|
plp,
|
||||||
|
rol,
|
||||||
|
ror,
|
||||||
|
rti,
|
||||||
|
rts,
|
||||||
|
sbc,
|
||||||
|
sec,
|
||||||
|
sed,
|
||||||
|
sei,
|
||||||
|
sta,
|
||||||
|
stx,
|
||||||
|
sty,
|
||||||
|
tax,
|
||||||
|
tay,
|
||||||
|
tsx,
|
||||||
|
txa,
|
||||||
|
txs,
|
||||||
|
tya,
|
||||||
|
|
||||||
|
// Undocumented NMOS 6502 instructions
|
||||||
|
ahx,
|
||||||
|
alr,
|
||||||
|
anc,
|
||||||
|
arr,
|
||||||
|
axs,
|
||||||
|
dcp,
|
||||||
|
isc,
|
||||||
|
kil,
|
||||||
|
las,
|
||||||
|
lax,
|
||||||
|
rla,
|
||||||
|
rra,
|
||||||
|
sax,
|
||||||
|
shx,
|
||||||
|
shy,
|
||||||
|
slo,
|
||||||
|
sre,
|
||||||
|
tas,
|
||||||
|
xaa,
|
||||||
|
|
||||||
|
// 65C02 CMOS additions
|
||||||
|
bra,
|
||||||
|
phx,
|
||||||
|
phy,
|
||||||
|
plx,
|
||||||
|
ply,
|
||||||
|
stz,
|
||||||
|
trb,
|
||||||
|
tsb,
|
||||||
|
rmb0,
|
||||||
|
rmb1,
|
||||||
|
rmb2,
|
||||||
|
rmb3,
|
||||||
|
rmb4,
|
||||||
|
rmb5,
|
||||||
|
rmb6,
|
||||||
|
rmb7,
|
||||||
|
smb0,
|
||||||
|
smb1,
|
||||||
|
smb2,
|
||||||
|
smb3,
|
||||||
|
smb4,
|
||||||
|
smb5,
|
||||||
|
smb6,
|
||||||
|
smb7,
|
||||||
|
bbr0,
|
||||||
|
bbr1,
|
||||||
|
bbr2,
|
||||||
|
bbr3,
|
||||||
|
bbr4,
|
||||||
|
bbr5,
|
||||||
|
bbr6,
|
||||||
|
bbr7,
|
||||||
|
bbs0,
|
||||||
|
bbs1,
|
||||||
|
bbs2,
|
||||||
|
bbs3,
|
||||||
|
bbs4,
|
||||||
|
bbs5,
|
||||||
|
bbs6,
|
||||||
|
bbs7,
|
||||||
|
stp,
|
||||||
|
wai,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Instruction contains strictly operation and addressing mode; cycles are dynamically accounted for by bus accesses.
|
||||||
|
const Instruction = @This();
|
||||||
|
|
||||||
|
operation: Operation,
|
||||||
|
mode: AddressingMode,
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
const Instruction = @import("../instruction.zig");
|
||||||
|
|
||||||
|
pub const instructions: [256]Instruction = .{
|
||||||
|
// 0x00 - 0x0f
|
||||||
|
.{ .operation = .brk, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .slo, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page },
|
||||||
|
.{ .operation = .ora, .mode = .zero_page },
|
||||||
|
.{ .operation = .asl, .mode = .zero_page },
|
||||||
|
.{ .operation = .slo, .mode = .zero_page },
|
||||||
|
.{ .operation = .php, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .immediate },
|
||||||
|
.{ .operation = .asl, .mode = .accumulator },
|
||||||
|
.{ .operation = .anc, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .absolute },
|
||||||
|
.{ .operation = .ora, .mode = .absolute },
|
||||||
|
.{ .operation = .asl, .mode = .absolute },
|
||||||
|
.{ .operation = .slo, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0x10 - 0x1f
|
||||||
|
.{ .operation = .bpl, .mode = .relative },
|
||||||
|
.{ .operation = .ora, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .slo, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .ora, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .asl, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .slo, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .clc, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .slo, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .ora, .mode = .absolute_x },
|
||||||
|
.{ .operation = .asl, .mode = .absolute_x },
|
||||||
|
.{ .operation = .slo, .mode = .absolute_x },
|
||||||
|
|
||||||
|
// 0x20 - 0x2f
|
||||||
|
.{ .operation = .jsr, .mode = .absolute },
|
||||||
|
.{ .operation = .@"and", .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .rla, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .bit, .mode = .zero_page },
|
||||||
|
.{ .operation = .@"and", .mode = .zero_page },
|
||||||
|
.{ .operation = .rol, .mode = .zero_page },
|
||||||
|
.{ .operation = .rla, .mode = .zero_page },
|
||||||
|
.{ .operation = .plp, .mode = .implied },
|
||||||
|
.{ .operation = .@"and", .mode = .immediate },
|
||||||
|
.{ .operation = .rol, .mode = .accumulator },
|
||||||
|
.{ .operation = .anc, .mode = .immediate },
|
||||||
|
.{ .operation = .bit, .mode = .absolute },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute },
|
||||||
|
.{ .operation = .rol, .mode = .absolute },
|
||||||
|
.{ .operation = .rla, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0x30 - 0x3f
|
||||||
|
.{ .operation = .bmi, .mode = .relative },
|
||||||
|
.{ .operation = .@"and", .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .rla, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .@"and", .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rol, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rla, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sec, .mode = .implied },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .rla, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute_x },
|
||||||
|
.{ .operation = .rol, .mode = .absolute_x },
|
||||||
|
.{ .operation = .rla, .mode = .absolute_x },
|
||||||
|
|
||||||
|
// 0x40 - 0x4f
|
||||||
|
.{ .operation = .rti, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .sre, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page },
|
||||||
|
.{ .operation = .eor, .mode = .zero_page },
|
||||||
|
.{ .operation = .lsr, .mode = .zero_page },
|
||||||
|
.{ .operation = .sre, .mode = .zero_page },
|
||||||
|
.{ .operation = .pha, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .immediate },
|
||||||
|
.{ .operation = .lsr, .mode = .accumulator },
|
||||||
|
.{ .operation = .alr, .mode = .immediate },
|
||||||
|
.{ .operation = .jmp, .mode = .absolute },
|
||||||
|
.{ .operation = .eor, .mode = .absolute },
|
||||||
|
.{ .operation = .lsr, .mode = .absolute },
|
||||||
|
.{ .operation = .sre, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0x50 - 0x5f
|
||||||
|
.{ .operation = .bvc, .mode = .relative },
|
||||||
|
.{ .operation = .eor, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .sre, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .eor, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .lsr, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sre, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .cli, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .sre, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .eor, .mode = .absolute_x },
|
||||||
|
.{ .operation = .lsr, .mode = .absolute_x },
|
||||||
|
.{ .operation = .sre, .mode = .absolute_x },
|
||||||
|
|
||||||
|
// 0x60 - 0x6f
|
||||||
|
.{ .operation = .rts, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .rra, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page },
|
||||||
|
.{ .operation = .adc, .mode = .zero_page },
|
||||||
|
.{ .operation = .ror, .mode = .zero_page },
|
||||||
|
.{ .operation = .rra, .mode = .zero_page },
|
||||||
|
.{ .operation = .pla, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .immediate },
|
||||||
|
.{ .operation = .ror, .mode = .accumulator },
|
||||||
|
.{ .operation = .arr, .mode = .immediate },
|
||||||
|
.{ .operation = .jmp, .mode = .indirect },
|
||||||
|
.{ .operation = .adc, .mode = .absolute },
|
||||||
|
.{ .operation = .ror, .mode = .absolute },
|
||||||
|
.{ .operation = .rra, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0x70 - 0x7f
|
||||||
|
.{ .operation = .bvs, .mode = .relative },
|
||||||
|
.{ .operation = .adc, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .rra, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .adc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .ror, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rra, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sei, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .rra, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .adc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .ror, .mode = .absolute_x },
|
||||||
|
.{ .operation = .rra, .mode = .absolute_x },
|
||||||
|
|
||||||
|
// 0x80 - 0x8f
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .sta, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .sax, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .sty, .mode = .zero_page },
|
||||||
|
.{ .operation = .sta, .mode = .zero_page },
|
||||||
|
.{ .operation = .stx, .mode = .zero_page },
|
||||||
|
.{ .operation = .sax, .mode = .zero_page },
|
||||||
|
.{ .operation = .dey, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .txa, .mode = .implied },
|
||||||
|
.{ .operation = .xaa, .mode = .immediate },
|
||||||
|
.{ .operation = .sty, .mode = .absolute },
|
||||||
|
.{ .operation = .sta, .mode = .absolute },
|
||||||
|
.{ .operation = .stx, .mode = .absolute },
|
||||||
|
.{ .operation = .sax, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0x90 - 0x9f
|
||||||
|
.{ .operation = .bcc, .mode = .relative },
|
||||||
|
.{ .operation = .sta, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .ahx, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .sty, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sta, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .stx, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .sax, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .tya, .mode = .implied },
|
||||||
|
.{ .operation = .sta, .mode = .absolute_y },
|
||||||
|
.{ .operation = .txs, .mode = .implied },
|
||||||
|
.{ .operation = .tas, .mode = .absolute_y },
|
||||||
|
.{ .operation = .shy, .mode = .absolute_x },
|
||||||
|
.{ .operation = .sta, .mode = .absolute_x },
|
||||||
|
.{ .operation = .shx, .mode = .absolute_y },
|
||||||
|
.{ .operation = .ahx, .mode = .absolute_y },
|
||||||
|
|
||||||
|
// 0xa0 - 0xaf
|
||||||
|
.{ .operation = .ldy, .mode = .immediate },
|
||||||
|
.{ .operation = .lda, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .ldx, .mode = .immediate },
|
||||||
|
.{ .operation = .lax, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .ldy, .mode = .zero_page },
|
||||||
|
.{ .operation = .lda, .mode = .zero_page },
|
||||||
|
.{ .operation = .ldx, .mode = .zero_page },
|
||||||
|
.{ .operation = .lax, .mode = .zero_page },
|
||||||
|
.{ .operation = .tay, .mode = .implied },
|
||||||
|
.{ .operation = .lda, .mode = .immediate },
|
||||||
|
.{ .operation = .tax, .mode = .implied },
|
||||||
|
.{ .operation = .lax, .mode = .immediate },
|
||||||
|
.{ .operation = .ldy, .mode = .absolute },
|
||||||
|
.{ .operation = .lda, .mode = .absolute },
|
||||||
|
.{ .operation = .ldx, .mode = .absolute },
|
||||||
|
.{ .operation = .lax, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0xb0 - 0xbf
|
||||||
|
.{ .operation = .bcs, .mode = .relative },
|
||||||
|
.{ .operation = .lda, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .lax, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .ldy, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .lda, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .ldx, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .lax, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .clv, .mode = .implied },
|
||||||
|
.{ .operation = .lda, .mode = .absolute_y },
|
||||||
|
.{ .operation = .tsx, .mode = .implied },
|
||||||
|
.{ .operation = .las, .mode = .absolute_y },
|
||||||
|
.{ .operation = .ldy, .mode = .absolute_x },
|
||||||
|
.{ .operation = .lda, .mode = .absolute_x },
|
||||||
|
.{ .operation = .ldx, .mode = .absolute_y },
|
||||||
|
.{ .operation = .lax, .mode = .absolute_y },
|
||||||
|
|
||||||
|
// 0xc0 - 0xcf
|
||||||
|
.{ .operation = .cpy, .mode = .immediate },
|
||||||
|
.{ .operation = .cmp, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .dcp, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .cpy, .mode = .zero_page },
|
||||||
|
.{ .operation = .cmp, .mode = .zero_page },
|
||||||
|
.{ .operation = .dec, .mode = .zero_page },
|
||||||
|
.{ .operation = .dcp, .mode = .zero_page },
|
||||||
|
.{ .operation = .iny, .mode = .implied },
|
||||||
|
.{ .operation = .cmp, .mode = .immediate },
|
||||||
|
.{ .operation = .dex, .mode = .implied },
|
||||||
|
.{ .operation = .axs, .mode = .immediate },
|
||||||
|
.{ .operation = .cpy, .mode = .absolute },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute },
|
||||||
|
.{ .operation = .dec, .mode = .absolute },
|
||||||
|
.{ .operation = .dcp, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0xd0 - 0xdf
|
||||||
|
.{ .operation = .bne, .mode = .relative },
|
||||||
|
.{ .operation = .cmp, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .dcp, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .cmp, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .dec, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .dcp, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .cld, .mode = .implied },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .dcp, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute_x },
|
||||||
|
.{ .operation = .dec, .mode = .absolute_x },
|
||||||
|
.{ .operation = .dcp, .mode = .absolute_x },
|
||||||
|
|
||||||
|
// 0xe0 - 0xef
|
||||||
|
.{ .operation = .cpx, .mode = .immediate },
|
||||||
|
.{ .operation = .sbc, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .isc, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .cpx, .mode = .zero_page },
|
||||||
|
.{ .operation = .sbc, .mode = .zero_page },
|
||||||
|
.{ .operation = .inc, .mode = .zero_page },
|
||||||
|
.{ .operation = .isc, .mode = .zero_page },
|
||||||
|
.{ .operation = .inx, .mode = .implied },
|
||||||
|
.{ .operation = .sbc, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .sbc, .mode = .immediate },
|
||||||
|
.{ .operation = .cpx, .mode = .absolute },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute },
|
||||||
|
.{ .operation = .inc, .mode = .absolute },
|
||||||
|
.{ .operation = .isc, .mode = .absolute },
|
||||||
|
|
||||||
|
// 0xf0 - 0xff
|
||||||
|
.{ .operation = .beq, .mode = .relative },
|
||||||
|
.{ .operation = .sbc, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .kil, .mode = .implied },
|
||||||
|
.{ .operation = .isc, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sbc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .inc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .isc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sed, .mode = .implied },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .isc, .mode = .absolute_y },
|
||||||
|
.{ .operation = .nop, .mode = .absolute_x },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .inc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .isc, .mode = .absolute_x },
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pub const nmos6502 = @import("nmos6502.zig");
|
||||||
|
pub const wdc65c02 = @import("wdc65c02.zig");
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
const Instruction = @import("../instruction.zig");
|
||||||
|
|
||||||
|
pub const instructions: [256]Instruction = .{
|
||||||
|
// 0x00 - 0x0f
|
||||||
|
.{ .operation = .brk, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .tsb, .mode = .zero_page },
|
||||||
|
.{ .operation = .ora, .mode = .zero_page },
|
||||||
|
.{ .operation = .asl, .mode = .zero_page },
|
||||||
|
.{ .operation = .rmb0, .mode = .zero_page },
|
||||||
|
.{ .operation = .php, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .immediate },
|
||||||
|
.{ .operation = .asl, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .tsb, .mode = .absolute },
|
||||||
|
.{ .operation = .ora, .mode = .absolute },
|
||||||
|
.{ .operation = .asl, .mode = .absolute },
|
||||||
|
.{ .operation = .bbr0, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x10 - 0x1f
|
||||||
|
.{ .operation = .bpl, .mode = .relative },
|
||||||
|
.{ .operation = .ora, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .ora, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .trb, .mode = .zero_page },
|
||||||
|
.{ .operation = .ora, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .asl, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rmb1, .mode = .zero_page },
|
||||||
|
.{ .operation = .clc, .mode = .implied },
|
||||||
|
.{ .operation = .ora, .mode = .absolute_y },
|
||||||
|
.{ .operation = .inc, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .trb, .mode = .absolute },
|
||||||
|
.{ .operation = .ora, .mode = .absolute_x },
|
||||||
|
.{ .operation = .asl, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbr1, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x20 - 0x2f
|
||||||
|
.{ .operation = .jsr, .mode = .absolute },
|
||||||
|
.{ .operation = .@"and", .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .bit, .mode = .zero_page },
|
||||||
|
.{ .operation = .@"and", .mode = .zero_page },
|
||||||
|
.{ .operation = .rol, .mode = .zero_page },
|
||||||
|
.{ .operation = .rmb2, .mode = .zero_page },
|
||||||
|
.{ .operation = .plp, .mode = .implied },
|
||||||
|
.{ .operation = .@"and", .mode = .immediate },
|
||||||
|
.{ .operation = .rol, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .bit, .mode = .absolute },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute },
|
||||||
|
.{ .operation = .rol, .mode = .absolute },
|
||||||
|
.{ .operation = .bbr2, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x30 - 0x3f
|
||||||
|
.{ .operation = .bmi, .mode = .relative },
|
||||||
|
.{ .operation = .@"and", .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .@"and", .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .bit, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .@"and", .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rol, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rmb3, .mode = .zero_page },
|
||||||
|
.{ .operation = .sec, .mode = .implied },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute_y },
|
||||||
|
.{ .operation = .dec, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .bit, .mode = .absolute_x },
|
||||||
|
.{ .operation = .@"and", .mode = .absolute_x },
|
||||||
|
.{ .operation = .rol, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbr3, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x40 - 0x4f
|
||||||
|
.{ .operation = .rti, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page },
|
||||||
|
.{ .operation = .eor, .mode = .zero_page },
|
||||||
|
.{ .operation = .lsr, .mode = .zero_page },
|
||||||
|
.{ .operation = .rmb4, .mode = .zero_page },
|
||||||
|
.{ .operation = .pha, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .immediate },
|
||||||
|
.{ .operation = .lsr, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .jmp, .mode = .absolute },
|
||||||
|
.{ .operation = .eor, .mode = .absolute },
|
||||||
|
.{ .operation = .lsr, .mode = .absolute },
|
||||||
|
.{ .operation = .bbr4, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x50 - 0x5f
|
||||||
|
.{ .operation = .bvc, .mode = .relative },
|
||||||
|
.{ .operation = .eor, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .eor, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .eor, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .lsr, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rmb5, .mode = .zero_page },
|
||||||
|
.{ .operation = .cli, .mode = .implied },
|
||||||
|
.{ .operation = .eor, .mode = .absolute_y },
|
||||||
|
.{ .operation = .phy, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .absolute },
|
||||||
|
.{ .operation = .eor, .mode = .absolute_x },
|
||||||
|
.{ .operation = .lsr, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbr5, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x60 - 0x6f
|
||||||
|
.{ .operation = .rts, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .stz, .mode = .zero_page },
|
||||||
|
.{ .operation = .adc, .mode = .zero_page },
|
||||||
|
.{ .operation = .ror, .mode = .zero_page },
|
||||||
|
.{ .operation = .rmb6, .mode = .zero_page },
|
||||||
|
.{ .operation = .pla, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .immediate },
|
||||||
|
.{ .operation = .ror, .mode = .accumulator },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .jmp, .mode = .indirect },
|
||||||
|
.{ .operation = .adc, .mode = .absolute },
|
||||||
|
.{ .operation = .ror, .mode = .absolute },
|
||||||
|
.{ .operation = .bbr6, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x70 - 0x7f
|
||||||
|
.{ .operation = .bvs, .mode = .relative },
|
||||||
|
.{ .operation = .adc, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .adc, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .stz, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .adc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .ror, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .rmb7, .mode = .zero_page },
|
||||||
|
.{ .operation = .sei, .mode = .implied },
|
||||||
|
.{ .operation = .adc, .mode = .absolute_y },
|
||||||
|
.{ .operation = .ply, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .jmp, .mode = .absolute_indexed_indirect },
|
||||||
|
.{ .operation = .adc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .ror, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbr7, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x80 - 0x8f
|
||||||
|
.{ .operation = .bra, .mode = .relative },
|
||||||
|
.{ .operation = .sta, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .sty, .mode = .zero_page },
|
||||||
|
.{ .operation = .sta, .mode = .zero_page },
|
||||||
|
.{ .operation = .stx, .mode = .zero_page },
|
||||||
|
.{ .operation = .smb0, .mode = .zero_page },
|
||||||
|
.{ .operation = .dey, .mode = .implied },
|
||||||
|
.{ .operation = .bit, .mode = .immediate },
|
||||||
|
.{ .operation = .txa, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .sty, .mode = .absolute },
|
||||||
|
.{ .operation = .sta, .mode = .absolute },
|
||||||
|
.{ .operation = .stx, .mode = .absolute },
|
||||||
|
.{ .operation = .bbs0, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0x90 - 0x9f
|
||||||
|
.{ .operation = .bcc, .mode = .relative },
|
||||||
|
.{ .operation = .sta, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .sta, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .sty, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sta, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .stx, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .smb1, .mode = .zero_page },
|
||||||
|
.{ .operation = .tya, .mode = .implied },
|
||||||
|
.{ .operation = .sta, .mode = .absolute_y },
|
||||||
|
.{ .operation = .txs, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .stz, .mode = .absolute },
|
||||||
|
.{ .operation = .sta, .mode = .absolute_x },
|
||||||
|
.{ .operation = .stz, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbs1, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xa0 - 0xaf
|
||||||
|
.{ .operation = .ldy, .mode = .immediate },
|
||||||
|
.{ .operation = .lda, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .ldx, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .ldy, .mode = .zero_page },
|
||||||
|
.{ .operation = .lda, .mode = .zero_page },
|
||||||
|
.{ .operation = .ldx, .mode = .zero_page },
|
||||||
|
.{ .operation = .smb2, .mode = .zero_page },
|
||||||
|
.{ .operation = .tay, .mode = .implied },
|
||||||
|
.{ .operation = .lda, .mode = .immediate },
|
||||||
|
.{ .operation = .tax, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .ldy, .mode = .absolute },
|
||||||
|
.{ .operation = .lda, .mode = .absolute },
|
||||||
|
.{ .operation = .ldx, .mode = .absolute },
|
||||||
|
.{ .operation = .bbs2, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xb0 - 0xbf
|
||||||
|
.{ .operation = .bcs, .mode = .relative },
|
||||||
|
.{ .operation = .lda, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .lda, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .ldy, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .lda, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .ldx, .mode = .zero_page_y },
|
||||||
|
.{ .operation = .smb3, .mode = .zero_page },
|
||||||
|
.{ .operation = .clv, .mode = .implied },
|
||||||
|
.{ .operation = .lda, .mode = .absolute_y },
|
||||||
|
.{ .operation = .tsx, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .ldy, .mode = .absolute_x },
|
||||||
|
.{ .operation = .lda, .mode = .absolute_x },
|
||||||
|
.{ .operation = .ldx, .mode = .absolute_y },
|
||||||
|
.{ .operation = .bbs3, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xc0 - 0xcf
|
||||||
|
.{ .operation = .cpy, .mode = .immediate },
|
||||||
|
.{ .operation = .cmp, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .cpy, .mode = .zero_page },
|
||||||
|
.{ .operation = .cmp, .mode = .zero_page },
|
||||||
|
.{ .operation = .dec, .mode = .zero_page },
|
||||||
|
.{ .operation = .smb4, .mode = .zero_page },
|
||||||
|
.{ .operation = .iny, .mode = .implied },
|
||||||
|
.{ .operation = .cmp, .mode = .immediate },
|
||||||
|
.{ .operation = .dex, .mode = .implied },
|
||||||
|
.{ .operation = .wai, .mode = .implied },
|
||||||
|
.{ .operation = .cpy, .mode = .absolute },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute },
|
||||||
|
.{ .operation = .dec, .mode = .absolute },
|
||||||
|
.{ .operation = .bbs4, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xd0 - 0xdf
|
||||||
|
.{ .operation = .bne, .mode = .relative },
|
||||||
|
.{ .operation = .cmp, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .cmp, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .cmp, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .dec, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .smb5, .mode = .zero_page },
|
||||||
|
.{ .operation = .cld, .mode = .implied },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute_y },
|
||||||
|
.{ .operation = .phx, .mode = .implied },
|
||||||
|
.{ .operation = .stp, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .absolute },
|
||||||
|
.{ .operation = .cmp, .mode = .absolute_x },
|
||||||
|
.{ .operation = .dec, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbs5, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xe0 - 0xef
|
||||||
|
.{ .operation = .cpx, .mode = .immediate },
|
||||||
|
.{ .operation = .sbc, .mode = .indexed_indirect_x },
|
||||||
|
.{ .operation = .nop, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .cpx, .mode = .zero_page },
|
||||||
|
.{ .operation = .sbc, .mode = .zero_page },
|
||||||
|
.{ .operation = .inc, .mode = .zero_page },
|
||||||
|
.{ .operation = .smb6, .mode = .zero_page },
|
||||||
|
.{ .operation = .inx, .mode = .implied },
|
||||||
|
.{ .operation = .sbc, .mode = .immediate },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .cpx, .mode = .absolute },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute },
|
||||||
|
.{ .operation = .inc, .mode = .absolute },
|
||||||
|
.{ .operation = .bbs6, .mode = .zero_page_relative },
|
||||||
|
|
||||||
|
// 0xf0 - 0xff
|
||||||
|
.{ .operation = .beq, .mode = .relative },
|
||||||
|
.{ .operation = .sbc, .mode = .indirect_indexed_y },
|
||||||
|
.{ .operation = .sbc, .mode = .zero_page_indirect },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .sbc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .inc, .mode = .zero_page_x },
|
||||||
|
.{ .operation = .smb7, .mode = .zero_page },
|
||||||
|
.{ .operation = .sed, .mode = .implied },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute_y },
|
||||||
|
.{ .operation = .plx, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .implied },
|
||||||
|
.{ .operation = .nop, .mode = .absolute },
|
||||||
|
.{ .operation = .sbc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .inc, .mode = .absolute_x },
|
||||||
|
.{ .operation = .bbs7, .mode = .zero_page_relative },
|
||||||
|
};
|
||||||
+53
-7
@@ -1,3 +1,6 @@
|
|||||||
|
const _opcode = @import("opcode/root.zig");
|
||||||
|
const Instruction = @import("instruction.zig");
|
||||||
|
|
||||||
pub const Status = packed struct(u8) {
|
pub const Status = packed struct(u8) {
|
||||||
carry: bool = false,
|
carry: bool = false,
|
||||||
zero: bool = false,
|
zero: bool = false,
|
||||||
@@ -30,13 +33,6 @@ pub const Registers = struct {
|
|||||||
sp: u8 = 0xfd,
|
sp: u8 = 0xfd,
|
||||||
pc: u16 = 0,
|
pc: u16 = 0,
|
||||||
status: Status = .{},
|
status: Status = .{},
|
||||||
|
|
||||||
pub fn dumpRegisters(self: Registers) void {
|
|
||||||
const std = @import("std");
|
|
||||||
std.debug.print("A:{X:02} X:{X:02} Y:{X:02} SP:{X:02} PC:{X:04}\n", .{
|
|
||||||
self.a, self.x, self.y, self.sp, self.pc,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Model = enum {
|
pub const Model = enum {
|
||||||
@@ -49,22 +45,26 @@ pub const Model = enum {
|
|||||||
r65c02,
|
r65c02,
|
||||||
|
|
||||||
pub fn features(self: Model) CpuFeatures {
|
pub fn features(self: Model) CpuFeatures {
|
||||||
|
// group variants sharing exact feature sets to eliminate duplication
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
.mos6502, .mos6507, .mos6510 => .{
|
.mos6502, .mos6507, .mos6510 => .{
|
||||||
.decimal_arithmetic = true,
|
.decimal_arithmetic = true,
|
||||||
.undocumented_opcodes = true,
|
.undocumented_opcodes = true,
|
||||||
.indirect_jump_bug = true,
|
.indirect_jump_bug = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.ricoh2a03, .ricoh2a07 => .{
|
.ricoh2a03, .ricoh2a07 => .{
|
||||||
.undocumented_opcodes = true,
|
.undocumented_opcodes = true,
|
||||||
.indirect_jump_bug = true,
|
.indirect_jump_bug = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.wdc65c02 => .{
|
.wdc65c02 => .{
|
||||||
.decimal_arithmetic = true,
|
.decimal_arithmetic = true,
|
||||||
.cmos_instructions = true,
|
.cmos_instructions = true,
|
||||||
.fixed_indirect_jump = true,
|
.fixed_indirect_jump = true,
|
||||||
.wait_and_stop = true,
|
.wait_and_stop = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.r65c02 => .{
|
.r65c02 => .{
|
||||||
.decimal_arithmetic = true,
|
.decimal_arithmetic = true,
|
||||||
.cmos_instructions = true,
|
.cmos_instructions = true,
|
||||||
@@ -72,6 +72,24 @@ pub const Model = enum {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn instructionTable(self: Model) *const [256]Instruction {
|
||||||
|
return switch (self) {
|
||||||
|
.mos6502, .mos6507, .mos6510, .ricoh2a03, .ricoh2a07 => &_opcode.nmos6502.instructions,
|
||||||
|
.wdc65c02, .r65c02 => &_opcode.wdc65c02.instructions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn instruction(self: Model, opcode: u8) Instruction {
|
||||||
|
return self.instructionTable()[opcode];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addressMask(self: Model) u16 {
|
||||||
|
return switch (self) {
|
||||||
|
.mos6507 => 0x1fff,
|
||||||
|
else => 0xffff,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CpuFeatures = packed struct(u8) {
|
pub const CpuFeatures = packed struct(u8) {
|
||||||
@@ -82,5 +100,33 @@ pub const CpuFeatures = packed struct(u8) {
|
|||||||
fixed_indirect_jump: bool = false,
|
fixed_indirect_jump: bool = false,
|
||||||
wait_and_stop: bool = false,
|
wait_and_stop: bool = false,
|
||||||
|
|
||||||
|
// remaining bit fields reserved for packed struct byte layout
|
||||||
_reserved: u2 = 0,
|
_reserved: u2 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test "CPU Model Features & Opcode Map Verification" {
|
||||||
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
|
// MOS 6502 family
|
||||||
|
try testing.expect(Model.mos6502.features().decimal_arithmetic);
|
||||||
|
try testing.expect(Model.mos6507.features().decimal_arithmetic);
|
||||||
|
try testing.expect(Model.mos6510.features().decimal_arithmetic);
|
||||||
|
try testing.expect(Model.mos6502.features().undocumented_opcodes);
|
||||||
|
|
||||||
|
// Ricoh family (No BCD)
|
||||||
|
try testing.expect(!Model.ricoh2a03.features().decimal_arithmetic);
|
||||||
|
try testing.expect(!Model.ricoh2a07.features().decimal_arithmetic);
|
||||||
|
try testing.expect(Model.ricoh2a07.features().undocumented_opcodes);
|
||||||
|
try testing.expect(Model.ricoh2a07.features().indirect_jump_bug);
|
||||||
|
|
||||||
|
// CMOS family
|
||||||
|
try testing.expect(Model.wdc65c02.features().cmos_instructions);
|
||||||
|
try testing.expect(Model.r65c02.features().cmos_instructions);
|
||||||
|
try testing.expect(Model.wdc65c02.features().wait_and_stop);
|
||||||
|
try testing.expect(!Model.r65c02.features().wait_and_stop);
|
||||||
|
|
||||||
|
// Opcode mapping sanity checks
|
||||||
|
try testing.expectEqual(Model.mos6502.instruction(0xEA).operation, .nop);
|
||||||
|
try testing.expectEqual(Model.ricoh2a07.instruction(0xEA).operation, .nop);
|
||||||
|
try testing.expectEqual(Model.r65c02.instruction(0x80).operation, .bra);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user