diff --git a/asm/disasm.go b/asm/disasm.go index 7379589..2f402ae 100644 --- a/asm/disasm.go +++ b/asm/disasm.go @@ -5,8 +5,6 @@ package asm import ( "fmt" - - "github.com/zellyn/go6502/cpu" ) // bytesString takes three bytes and a length, returning the formatted @@ -29,31 +27,31 @@ func addrString(pc uint16, byte1, byte2 byte, length int, mode int) string { addr16 := uint16(byte1) + uint16(byte2)<<8 addrRel := uint16(int32(pc+2) + int32(int8(byte1))) switch mode { - case cpu.MODE_IMPLIED: + case MODE_IMPLIED: return " " - case cpu.MODE_ABSOLUTE: + case MODE_ABSOLUTE: return fmt.Sprintf("$%04X ", addr16) - case cpu.MODE_INDIRECT: + case MODE_INDIRECT: return fmt.Sprintf("($%04X)", addr16) - case cpu.MODE_RELATIVE: + case MODE_RELATIVE: return fmt.Sprintf("$%04X ", addrRel) - case cpu.MODE_IMMEDIATE: + case MODE_IMMEDIATE: return fmt.Sprintf("#$%02X ", byte1) - case cpu.MODE_ABS_X: + case MODE_ABS_X: return fmt.Sprintf("$%04X,X", addr16) - case cpu.MODE_ABS_Y: + case MODE_ABS_Y: return fmt.Sprintf("$%04X,Y", addr16) - case cpu.MODE_ZP: + case MODE_ZP: return fmt.Sprintf("$%02X ", byte1) - case cpu.MODE_ZP_X: + case MODE_ZP_X: return fmt.Sprintf("$%02X,X ", byte1) - case cpu.MODE_ZP_Y: + case MODE_ZP_Y: return fmt.Sprintf("$%02X,Y ", byte1) - case cpu.MODE_INDIRECT_Y: + case MODE_INDIRECT_Y: return fmt.Sprintf("($%02X),Y", byte1) - case cpu.MODE_INDIRECT_X: + case MODE_INDIRECT_X: return fmt.Sprintf("($%02X,X)", byte1) - case cpu.MODE_A: + case MODE_A: return " " } panic(fmt.Sprintf("Unknown op mode: %d", mode)) @@ -64,11 +62,11 @@ func addrString(pc uint16, byte1, byte2 byte, length int, mode int) string { // instruction and address, and the length. If it cannot find the // instruction, it returns a 1-byte "???" instruction. func Disasm(pc uint16, byte0, byte1, byte2 byte) (string, string, int) { - op, ok := cpu.Opcodes[byte0] + op, ok := Opcodes[byte0] if !ok { - op = cpu.NoOp + op = NoOp } - length := cpu.ModeLengths[op.Mode] + length := ModeLengths[op.Mode] bytes := bytesString(byte0, byte1, byte2, length) addr := addrString(pc, byte1, byte2, length, op.Mode) return bytes, op.Name + " " + addr, length diff --git a/asm/opcodes.go b/asm/opcodes.go new file mode 100644 index 0000000..c7f7c4f --- /dev/null +++ b/asm/opcodes.go @@ -0,0 +1,236 @@ +package asm + +// Opcode addressing modes. +const ( + MODE_IMPLIED = iota + MODE_ABSOLUTE + MODE_INDIRECT + MODE_RELATIVE + MODE_IMMEDIATE + MODE_ABS_X + MODE_ABS_Y + MODE_ZP + MODE_ZP_X + MODE_ZP_Y + MODE_INDIRECT_Y + MODE_INDIRECT_X + MODE_A +) + +// Lengths of instructions for each addressing mode. +var ModeLengths = map[int]int{ + MODE_IMPLIED: 1, + MODE_ABSOLUTE: 3, + MODE_INDIRECT: 3, + MODE_RELATIVE: 2, + MODE_IMMEDIATE: 2, + MODE_ABS_X: 3, + MODE_ABS_Y: 3, + MODE_ZP: 2, + MODE_ZP_X: 2, + MODE_ZP_Y: 2, + MODE_INDIRECT_Y: 2, + MODE_INDIRECT_X: 2, + MODE_A: 1, +} + +// Opcode stores information about instructions. +type Opcode struct { + Name string + Mode int +} + +// Fake NoOp instruction used when disassembling. +var NoOp = Opcode{"???", MODE_IMPLIED} + +// The list of Opcodes. +var Opcodes = map[byte]Opcode{ + // BUG(zellyn): Add 65C02 instructions. + + // Flag set and clear + 0x18: {"CLC", MODE_IMPLIED}, // CLC + 0xD8: {"CLD", MODE_IMPLIED}, // CLD + 0x58: {"CLI", MODE_IMPLIED}, // CLI + 0xB8: {"CLV", MODE_IMPLIED}, // CLV + 0x38: {"SEC", MODE_IMPLIED}, // SEC + 0xF8: {"SED", MODE_IMPLIED}, // SED + 0x78: {"SEI", MODE_IMPLIED}, // SEI + + // Very simple 1-opcode instructions + 0xEA: {"NOP", MODE_IMPLIED}, + 0xAA: {"TAX", MODE_IMPLIED}, + 0xA8: {"TAY", MODE_IMPLIED}, + 0xBA: {"TSX", MODE_IMPLIED}, + 0x8A: {"TXA", MODE_IMPLIED}, + 0x9A: {"TXS", MODE_IMPLIED}, + 0x98: {"TYA", MODE_IMPLIED}, + + // Slightly more complex 1-opcode instructions + 0xCA: {"DEX", MODE_IMPLIED}, + 0x88: {"DEY", MODE_IMPLIED}, + 0xE8: {"INX", MODE_IMPLIED}, + 0xC8: {"INY", MODE_IMPLIED}, + 0x48: {"PHA", MODE_IMPLIED}, + 0x08: {"PHP", MODE_IMPLIED}, + 0x68: {"PLA", MODE_IMPLIED}, + 0x28: {"PLP", MODE_IMPLIED}, + + // Jumps, returns, etc. + 0x4C: {"JMP", MODE_ABSOLUTE}, + 0x6C: {"JMP", MODE_INDIRECT}, + 0x20: {"JSR", MODE_ABSOLUTE}, + 0x60: {"RTS", MODE_IMPLIED}, + 0x40: {"RTI", MODE_IMPLIED}, + 0x00: {"BRK", MODE_IMPLIED}, + + // Branches + 0x90: {"BCC", MODE_RELATIVE}, // BCC + 0xB0: {"BCS", MODE_RELATIVE}, // BCS + 0xF0: {"BEQ", MODE_RELATIVE}, // BEQ + 0x30: {"BMI", MODE_RELATIVE}, // BMI + 0xD0: {"BNE", MODE_RELATIVE}, // BNE + 0x10: {"BPL", MODE_RELATIVE}, // BPL + 0x50: {"BVC", MODE_RELATIVE}, // BVC + 0x70: {"BVS", MODE_RELATIVE}, // BVS + + // 2-opcode, 2-cycle immediate mode + 0x09: {"ORA", MODE_IMMEDIATE}, + 0x29: {"AND", MODE_IMMEDIATE}, + 0x49: {"EOR", MODE_IMMEDIATE}, + 0x69: {"ADC", MODE_IMMEDIATE}, + 0xC0: {"CPY", MODE_IMMEDIATE}, + 0xC9: {"CMP", MODE_IMMEDIATE}, + 0xA0: {"LDY", MODE_IMMEDIATE}, + 0xA2: {"LDX", MODE_IMMEDIATE}, + 0xA9: {"LDA", MODE_IMMEDIATE}, + 0xE0: {"CPX", MODE_IMMEDIATE}, + 0xE9: {"SBC", MODE_IMMEDIATE}, + + // 3-opcode, 4-cycle absolute mode + 0x8D: {"STA", MODE_ABSOLUTE}, + 0x8E: {"STX", MODE_ABSOLUTE}, + 0x8C: {"STY", MODE_ABSOLUTE}, + 0x6D: {"ADC", MODE_ABSOLUTE}, + 0x2D: {"AND", MODE_ABSOLUTE}, + 0x2C: {"BIT", MODE_ABSOLUTE}, + 0xCD: {"CMP", MODE_ABSOLUTE}, + 0xEC: {"CPX", MODE_ABSOLUTE}, + 0xCC: {"CPY", MODE_ABSOLUTE}, + 0x4D: {"EOR", MODE_ABSOLUTE}, + 0xAD: {"LDA", MODE_ABSOLUTE}, + 0xAE: {"LDX", MODE_ABSOLUTE}, + 0xAC: {"LDY", MODE_ABSOLUTE}, + 0x0D: {"ORA", MODE_ABSOLUTE}, + 0xED: {"SBC", MODE_ABSOLUTE}, + + // 2-opcode, 3-cycle zero page + 0x05: {"ORA", MODE_ZP}, + 0x24: {"BIT", MODE_ZP}, + 0x25: {"AND", MODE_ZP}, + 0x45: {"EOR", MODE_ZP}, + 0x65: {"ADC", MODE_ZP}, + 0x84: {"STY", MODE_ZP}, + 0x85: {"STA", MODE_ZP}, + 0x86: {"STX", MODE_ZP}, + 0xA4: {"LDY", MODE_ZP}, + 0xA5: {"LDA", MODE_ZP}, + 0xA6: {"LDX", MODE_ZP}, + 0xC4: {"CPY", MODE_ZP}, + 0xC5: {"CMP", MODE_ZP}, + 0xE4: {"CPX", MODE_ZP}, + 0xE5: {"SBC", MODE_ZP}, + + // 3-opcode, 4*-cycle abs,X/Y + 0x1D: {"ORA", MODE_ABS_X}, + 0x19: {"ORA", MODE_ABS_X}, + 0x39: {"AND", MODE_ABS_X}, + 0x3D: {"AND", MODE_ABS_X}, + 0x59: {"EOR", MODE_ABS_X}, + 0x5D: {"EOR", MODE_ABS_X}, + 0x79: {"ADC", MODE_ABS_X}, + 0x7D: {"ADC", MODE_ABS_X}, + 0xBD: {"LDA", MODE_ABS_X}, + 0xB9: {"LDA", MODE_ABS_X}, + 0xD9: {"CMP", MODE_ABS_X}, + 0xDD: {"CMP", MODE_ABS_X}, + 0xF9: {"SBC", MODE_ABS_X}, + 0xFD: {"SBC", MODE_ABS_X}, + 0xBE: {"LDX", MODE_ABS_X}, + 0xBC: {"LDY", MODE_ABS_X}, + + // 3-opcode, 5-cycle abs,X/Y + 0x99: {"STA", MODE_ABS_Y}, + 0x9D: {"STA", MODE_ABS_X}, + + // 2-opcode, 4-cycle zp,X/Y + 0x15: {"ORA", MODE_ZP_X}, + 0x35: {"AND", MODE_ZP_X}, + 0x55: {"EOR", MODE_ZP_X}, + 0x75: {"ADC", MODE_ZP_X}, + 0x95: {"STA", MODE_ZP_X}, + 0xB5: {"LDA", MODE_ZP_X}, + 0xD5: {"CMP", MODE_ZP_X}, + 0xF5: {"SBC", MODE_ZP_X}, + 0x96: {"STX", MODE_ZP_Y}, + 0xB6: {"LDX", MODE_ZP_Y}, + 0x94: {"STY", MODE_ZP_X}, + 0xB4: {"LDY", MODE_ZP_X}, + + // 2-opcode, 5*-cycle zero-page indirect Y + 0x11: {"ORA", MODE_INDIRECT_Y}, + 0x31: {"AND", MODE_INDIRECT_Y}, + 0x51: {"EOR", MODE_INDIRECT_Y}, + 0x71: {"ADC", MODE_INDIRECT_Y}, + 0x91: {"STA", MODE_INDIRECT_Y}, + 0xB1: {"LDA", MODE_INDIRECT_Y}, + 0xD1: {"CMP", MODE_INDIRECT_Y}, + 0xF1: {"SBC", MODE_INDIRECT_Y}, + + // 2-opcode, 6-cycle zero-page X indirect + 0x01: {"ORA", MODE_INDIRECT_X}, + 0x21: {"AND", MODE_INDIRECT_X}, + 0x41: {"EOR", MODE_INDIRECT_X}, + 0x61: {"ADC", MODE_INDIRECT_X}, + 0x81: {"STA", MODE_INDIRECT_X}, + 0xA1: {"LDA", MODE_INDIRECT_X}, + 0xC1: {"CMP", MODE_INDIRECT_X}, + 0xE1: {"SBC", MODE_INDIRECT_X}, + + // 1-opcode, 2-cycle, accumulator rmw + 0x0A: {"ASL", MODE_A}, + 0x2A: {"ROL", MODE_A}, + 0x4A: {"LSR", MODE_A}, + 0x6A: {"ROR", MODE_A}, + + // 2-opcode, 5-cycle, zp rmw + 0x06: {"ASL", MODE_ZP}, + 0x26: {"ROL", MODE_ZP}, + 0x46: {"LSR", MODE_ZP}, + 0x66: {"ROR", MODE_ZP}, + 0xC6: {"DEC", MODE_ZP}, + 0xE6: {"INC", MODE_ZP}, + + // 3-opcode, 6-cycle, abs rmw + 0x0E: {"ASL", MODE_ABSOLUTE}, + 0x2E: {"ROL", MODE_ABSOLUTE}, + 0x4E: {"LSR", MODE_ABSOLUTE}, + 0x6E: {"ROR", MODE_ABSOLUTE}, + 0xCE: {"DEC", MODE_ABSOLUTE}, + 0xEE: {"INC", MODE_ABSOLUTE}, + + // 2-opcode, 6-cycle, zp,X rmw + 0x16: {"ASL", MODE_ZP_X}, + 0x36: {"ROL", MODE_ZP_X}, + 0x56: {"LSR", MODE_ZP_X}, + 0x76: {"ROR", MODE_ZP_X}, + 0xD6: {"DEC", MODE_ZP_X}, + 0xF6: {"INC", MODE_ZP_X}, + + // 3-opcode, 7-cycle, abs,X rmw + 0x1E: {"ASL", MODE_ABS_X}, + 0x3E: {"ROL", MODE_ABS_X}, + 0x5E: {"LSR", MODE_ABS_X}, + 0x7E: {"ROR", MODE_ABS_X}, + 0xDE: {"DEC", MODE_ABS_X}, + 0xFE: {"INC", MODE_ABS_X}, +} diff --git a/cpu/cpu.go b/cpu/cpu.go index a589a33..59c0776 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -132,8 +132,8 @@ func (c *cpu) Step() error { c.r.PC++ c.t.Tick() - if op, ok := Opcodes[i]; ok { - op.function(c) + if f, ok := Opcodes[i]; ok { + f(c) return nil } diff --git a/cpu/opcodes.go b/cpu/opcodes.go index aea4592..5160e31 100644 --- a/cpu/opcodes.go +++ b/cpu/opcodes.go @@ -1,241 +1,193 @@ package cpu -import ( - _ "fmt" -) - -// Opcode addressing modes. -const ( - MODE_IMPLIED = iota - MODE_ABSOLUTE - MODE_INDIRECT - MODE_RELATIVE - MODE_IMMEDIATE - MODE_ABS_X - MODE_ABS_Y - MODE_ZP - MODE_ZP_X - MODE_ZP_Y - MODE_INDIRECT_Y - MODE_INDIRECT_X - MODE_A -) - -// Lengths of instructions for each addressing mode. -var ModeLengths = map[int]int{ - MODE_IMPLIED: 1, - MODE_ABSOLUTE: 3, - MODE_INDIRECT: 3, - MODE_RELATIVE: 2, - MODE_IMMEDIATE: 2, - MODE_ABS_X: 3, - MODE_ABS_Y: 3, - MODE_ZP: 2, - MODE_ZP_X: 2, - MODE_ZP_Y: 2, - MODE_INDIRECT_Y: 2, - MODE_INDIRECT_X: 2, - MODE_A: 1, -} - -// Opcode stores information about instructions. -type Opcode struct { - Name string - Mode int - function func(*cpu) -} - -// Fake NoOp instruction used when disassembling. -var NoOp = Opcode{"???", MODE_IMPLIED, nil} - // The list of Opcodes. -var Opcodes = map[byte]Opcode{ +var Opcodes = map[byte]func(*cpu){ // BUG(zellyn): Add 65C02 instructions. // Flag set and clear - 0x18: {"CLC", MODE_IMPLIED, clearFlag(FLAG_C)}, // CLC - 0xD8: {"CLD", MODE_IMPLIED, clearFlag(FLAG_D)}, // CLD - 0x58: {"CLI", MODE_IMPLIED, clearFlag(FLAG_I)}, // CLI - 0xB8: {"CLV", MODE_IMPLIED, clearFlag(FLAG_V)}, // CLV - 0x38: {"SEC", MODE_IMPLIED, setFlag(FLAG_C)}, // SEC - 0xF8: {"SED", MODE_IMPLIED, setFlag(FLAG_D)}, // SED - 0x78: {"SEI", MODE_IMPLIED, setFlag(FLAG_I)}, // SEI + 0x18: clearFlag(FLAG_C), // CLC + 0xD8: clearFlag(FLAG_D), // CLD + 0x58: clearFlag(FLAG_I), // CLI + 0xB8: clearFlag(FLAG_V), // CLV + 0x38: setFlag(FLAG_C), // SEC + 0xF8: setFlag(FLAG_D), // SED + 0x78: setFlag(FLAG_I), // SEI // Very simple 1-opcode instructions - 0xEA: {"NOP", MODE_IMPLIED, nop}, - 0xAA: {"TAX", MODE_IMPLIED, tax}, - 0xA8: {"TAY", MODE_IMPLIED, tay}, - 0xBA: {"TSX", MODE_IMPLIED, tsx}, - 0x8A: {"TXA", MODE_IMPLIED, txa}, - 0x9A: {"TXS", MODE_IMPLIED, txs}, - 0x98: {"TYA", MODE_IMPLIED, tya}, + 0xEA: nop, + 0xAA: tax, + 0xA8: tay, + 0xBA: tsx, + 0x8A: txa, + 0x9A: txs, + 0x98: tya, // Slightly more complex 1-opcode instructions - 0xCA: {"DEX", MODE_IMPLIED, dex}, - 0x88: {"DEY", MODE_IMPLIED, dey}, - 0xE8: {"INX", MODE_IMPLIED, inx}, - 0xC8: {"INY", MODE_IMPLIED, iny}, - 0x48: {"PHA", MODE_IMPLIED, pha}, - 0x08: {"PHP", MODE_IMPLIED, php}, - 0x68: {"PLA", MODE_IMPLIED, pla}, - 0x28: {"PLP", MODE_IMPLIED, plp}, + 0xCA: dex, + 0x88: dey, + 0xE8: inx, + 0xC8: iny, + 0x48: pha, + 0x08: php, + 0x68: pla, + 0x28: plp, // Jumps, returns, etc. - 0x4C: {"JMP", MODE_ABSOLUTE, jmpAbsolute}, - 0x6C: {"JMP", MODE_INDIRECT, jmpIndirect}, - 0x20: {"JSR", MODE_ABSOLUTE, jsr}, - 0x60: {"RTS", MODE_IMPLIED, rts}, - 0x40: {"RTI", MODE_IMPLIED, rti}, - 0x00: {"BRK", MODE_IMPLIED, brk}, + 0x4C: jmpAbsolute, + 0x6C: jmpIndirect, + 0x20: jsr, + 0x60: rts, + 0x40: rti, + 0x00: brk, // Branches - 0x90: {"BCC", MODE_RELATIVE, branch(FLAG_C, 0)}, // BCC - 0xB0: {"BCS", MODE_RELATIVE, branch(FLAG_C, FLAG_C)}, // BCS - 0xF0: {"BEQ", MODE_RELATIVE, branch(FLAG_Z, FLAG_Z)}, // BEQ - 0x30: {"BMI", MODE_RELATIVE, branch(FLAG_N, FLAG_N)}, // BMI - 0xD0: {"BNE", MODE_RELATIVE, branch(FLAG_Z, 0)}, // BNE - 0x10: {"BPL", MODE_RELATIVE, branch(FLAG_N, 0)}, // BPL - 0x50: {"BVC", MODE_RELATIVE, branch(FLAG_V, 0)}, // BVC - 0x70: {"BVS", MODE_RELATIVE, branch(FLAG_V, FLAG_V)}, // BVS + 0x90: branch(FLAG_C, 0), // BCC + 0xB0: branch(FLAG_C, FLAG_C), // BCS + 0xF0: branch(FLAG_Z, FLAG_Z), // BEQ + 0x30: branch(FLAG_N, FLAG_N), // BMI + 0xD0: branch(FLAG_Z, 0), // BNE + 0x10: branch(FLAG_N, 0), // BPL + 0x50: branch(FLAG_V, 0), // BVC + 0x70: branch(FLAG_V, FLAG_V), // BVS // 2-opcode, 2-cycle immediate mode - 0x09: {"ORA", MODE_IMMEDIATE, immediate2(ora)}, - 0x29: {"AND", MODE_IMMEDIATE, immediate2(and)}, - 0x49: {"EOR", MODE_IMMEDIATE, immediate2(eor)}, - 0x69: {"ADC", MODE_IMMEDIATE, immediate2(adc)}, - 0xC0: {"CPY", MODE_IMMEDIATE, immediate2(cpy)}, - 0xC9: {"CMP", MODE_IMMEDIATE, immediate2(cmp)}, - 0xA0: {"LDY", MODE_IMMEDIATE, immediate2(ldy)}, - 0xA2: {"LDX", MODE_IMMEDIATE, immediate2(ldx)}, - 0xA9: {"LDA", MODE_IMMEDIATE, immediate2(lda)}, - 0xE0: {"CPX", MODE_IMMEDIATE, immediate2(cpx)}, - 0xE9: {"SBC", MODE_IMMEDIATE, immediate2(sbc)}, + 0x09: immediate2(ora), + 0x29: immediate2(and), + 0x49: immediate2(eor), + 0x69: immediate2(adc), + 0xC0: immediate2(cpy), + 0xC9: immediate2(cmp), + 0xA0: immediate2(ldy), + 0xA2: immediate2(ldx), + 0xA9: immediate2(lda), + 0xE0: immediate2(cpx), + 0xE9: immediate2(sbc), // 3-opcode, 4-cycle absolute mode - 0x8D: {"STA", MODE_ABSOLUTE, absolute4w(sta)}, - 0x8E: {"STX", MODE_ABSOLUTE, absolute4w(stx)}, - 0x8C: {"STY", MODE_ABSOLUTE, absolute4w(sty)}, - 0x6D: {"ADC", MODE_ABSOLUTE, absolute4r(adc)}, - 0x2D: {"AND", MODE_ABSOLUTE, absolute4r(and)}, - 0x2C: {"BIT", MODE_ABSOLUTE, absolute4r(bit)}, - 0xCD: {"CMP", MODE_ABSOLUTE, absolute4r(cmp)}, - 0xEC: {"CPX", MODE_ABSOLUTE, absolute4r(cpx)}, - 0xCC: {"CPY", MODE_ABSOLUTE, absolute4r(cpy)}, - 0x4D: {"EOR", MODE_ABSOLUTE, absolute4r(eor)}, - 0xAD: {"LDA", MODE_ABSOLUTE, absolute4r(lda)}, - 0xAE: {"LDX", MODE_ABSOLUTE, absolute4r(ldx)}, - 0xAC: {"LDY", MODE_ABSOLUTE, absolute4r(ldy)}, - 0x0D: {"ORA", MODE_ABSOLUTE, absolute4r(ora)}, - 0xED: {"SBC", MODE_ABSOLUTE, absolute4r(sbc)}, + 0x8D: absolute4w(sta), + 0x8E: absolute4w(stx), + 0x8C: absolute4w(sty), + 0x6D: absolute4r(adc), + 0x2D: absolute4r(and), + 0x2C: absolute4r(bit), + 0xCD: absolute4r(cmp), + 0xEC: absolute4r(cpx), + 0xCC: absolute4r(cpy), + 0x4D: absolute4r(eor), + 0xAD: absolute4r(lda), + 0xAE: absolute4r(ldx), + 0xAC: absolute4r(ldy), + 0x0D: absolute4r(ora), + 0xED: absolute4r(sbc), // 2-opcode, 3-cycle zero page - 0x05: {"ORA", MODE_ZP, zp3r(ora)}, - 0x24: {"BIT", MODE_ZP, zp3r(bit)}, - 0x25: {"AND", MODE_ZP, zp3r(and)}, - 0x45: {"EOR", MODE_ZP, zp3r(eor)}, - 0x65: {"ADC", MODE_ZP, zp3r(adc)}, - 0x84: {"STY", MODE_ZP, zp3w(sty)}, - 0x85: {"STA", MODE_ZP, zp3w(sta)}, - 0x86: {"STX", MODE_ZP, zp3w(stx)}, - 0xA4: {"LDY", MODE_ZP, zp3r(ldy)}, - 0xA5: {"LDA", MODE_ZP, zp3r(lda)}, - 0xA6: {"LDX", MODE_ZP, zp3r(ldx)}, - 0xC4: {"CPY", MODE_ZP, zp3r(cpy)}, - 0xC5: {"CMP", MODE_ZP, zp3r(cmp)}, - 0xE4: {"CPX", MODE_ZP, zp3r(cpx)}, - 0xE5: {"SBC", MODE_ZP, zp3r(sbc)}, + 0x05: zp3r(ora), + 0x24: zp3r(bit), + 0x25: zp3r(and), + 0x45: zp3r(eor), + 0x65: zp3r(adc), + 0x84: zp3w(sty), + 0x85: zp3w(sta), + 0x86: zp3w(stx), + 0xA4: zp3r(ldy), + 0xA5: zp3r(lda), + 0xA6: zp3r(ldx), + 0xC4: zp3r(cpy), + 0xC5: zp3r(cmp), + 0xE4: zp3r(cpx), + 0xE5: zp3r(sbc), // 3-opcode, 4*-cycle abs,X/Y - 0x1D: {"ORA", MODE_ABS_X, absx4r(ora)}, - 0x19: {"ORA", MODE_ABS_X, absy4r(ora)}, - 0x39: {"AND", MODE_ABS_X, absy4r(and)}, - 0x3D: {"AND", MODE_ABS_X, absx4r(and)}, - 0x59: {"EOR", MODE_ABS_X, absy4r(eor)}, - 0x5D: {"EOR", MODE_ABS_X, absx4r(eor)}, - 0x79: {"ADC", MODE_ABS_X, absy4r(adc)}, - 0x7D: {"ADC", MODE_ABS_X, absx4r(adc)}, - 0xBD: {"LDA", MODE_ABS_X, absx4r(lda)}, - 0xB9: {"LDA", MODE_ABS_X, absy4r(lda)}, - 0xD9: {"CMP", MODE_ABS_X, absy4r(cmp)}, - 0xDD: {"CMP", MODE_ABS_X, absx4r(cmp)}, - 0xF9: {"SBC", MODE_ABS_X, absy4r(sbc)}, - 0xFD: {"SBC", MODE_ABS_X, absx4r(sbc)}, - 0xBE: {"LDX", MODE_ABS_X, absy4r(ldx)}, - 0xBC: {"LDY", MODE_ABS_X, absx4r(ldy)}, + 0x1D: absx4r(ora), + 0x19: absy4r(ora), + 0x39: absy4r(and), + 0x3D: absx4r(and), + 0x59: absy4r(eor), + 0x5D: absx4r(eor), + 0x79: absy4r(adc), + 0x7D: absx4r(adc), + 0xBD: absx4r(lda), + 0xB9: absy4r(lda), + 0xD9: absy4r(cmp), + 0xDD: absx4r(cmp), + 0xF9: absy4r(sbc), + 0xFD: absx4r(sbc), + 0xBE: absy4r(ldx), + 0xBC: absx4r(ldy), // 3-opcode, 5-cycle abs,X/Y - 0x99: {"STA", MODE_ABS_Y, absy5w(sta)}, - 0x9D: {"STA", MODE_ABS_X, absx5w(sta)}, + 0x99: absy5w(sta), + 0x9D: absx5w(sta), // 2-opcode, 4-cycle zp,X/Y - 0x15: {"ORA", MODE_ZP_X, zpx4r(ora)}, - 0x35: {"AND", MODE_ZP_X, zpx4r(and)}, - 0x55: {"EOR", MODE_ZP_X, zpx4r(eor)}, - 0x75: {"ADC", MODE_ZP_X, zpx4r(adc)}, - 0x95: {"STA", MODE_ZP_X, zpx4w(sta)}, - 0xB5: {"LDA", MODE_ZP_X, zpx4r(lda)}, - 0xD5: {"CMP", MODE_ZP_X, zpx4r(cmp)}, - 0xF5: {"SBC", MODE_ZP_X, zpx4r(sbc)}, - 0x96: {"STX", MODE_ZP_Y, zpy4w(stx)}, - 0xB6: {"LDX", MODE_ZP_Y, zpy4r(ldx)}, - 0x94: {"STY", MODE_ZP_X, zpx4w(sty)}, - 0xB4: {"LDY", MODE_ZP_X, zpx4r(ldy)}, + 0x15: zpx4r(ora), + 0x35: zpx4r(and), + 0x55: zpx4r(eor), + 0x75: zpx4r(adc), + 0x95: zpx4w(sta), + 0xB5: zpx4r(lda), + 0xD5: zpx4r(cmp), + 0xF5: zpx4r(sbc), + 0x96: zpy4w(stx), + 0xB6: zpy4r(ldx), + 0x94: zpx4w(sty), + 0xB4: zpx4r(ldy), // 2-opcode, 5*-cycle zero-page indirect Y - 0x11: {"ORA", MODE_INDIRECT_Y, zpiy5r(ora)}, - 0x31: {"AND", MODE_INDIRECT_Y, zpiy5r(and)}, - 0x51: {"EOR", MODE_INDIRECT_Y, zpiy5r(eor)}, - 0x71: {"ADC", MODE_INDIRECT_Y, zpiy5r(adc)}, - 0x91: {"STA", MODE_INDIRECT_Y, zpiy6w(sta)}, - 0xB1: {"LDA", MODE_INDIRECT_Y, zpiy5r(lda)}, - 0xD1: {"CMP", MODE_INDIRECT_Y, zpiy5r(cmp)}, - 0xF1: {"SBC", MODE_INDIRECT_Y, zpiy5r(sbc)}, + 0x11: zpiy5r(ora), + 0x31: zpiy5r(and), + 0x51: zpiy5r(eor), + 0x71: zpiy5r(adc), + 0x91: zpiy6w(sta), + 0xB1: zpiy5r(lda), + 0xD1: zpiy5r(cmp), + 0xF1: zpiy5r(sbc), // 2-opcode, 6-cycle zero-page X indirect - 0x01: {"ORA", MODE_INDIRECT_X, zpxi6r(ora)}, - 0x21: {"AND", MODE_INDIRECT_X, zpxi6r(and)}, - 0x41: {"EOR", MODE_INDIRECT_X, zpxi6r(eor)}, - 0x61: {"ADC", MODE_INDIRECT_X, zpxi6r(adc)}, - 0x81: {"STA", MODE_INDIRECT_X, zpxi6w(sta)}, - 0xA1: {"LDA", MODE_INDIRECT_X, zpxi6r(lda)}, - 0xC1: {"CMP", MODE_INDIRECT_X, zpxi6r(cmp)}, - 0xE1: {"SBC", MODE_INDIRECT_X, zpxi6r(sbc)}, + 0x01: zpxi6r(ora), + 0x21: zpxi6r(and), + 0x41: zpxi6r(eor), + 0x61: zpxi6r(adc), + 0x81: zpxi6w(sta), + 0xA1: zpxi6r(lda), + 0xC1: zpxi6r(cmp), + 0xE1: zpxi6r(sbc), // 1-opcode, 2-cycle, accumulator rmw - 0x0A: {"ASL", MODE_A, acc2rmw(asl)}, - 0x2A: {"ROL", MODE_A, acc2rmw(rol)}, - 0x4A: {"LSR", MODE_A, acc2rmw(lsr)}, - 0x6A: {"ROR", MODE_A, acc2rmw(ror)}, + 0x0A: acc2rmw(asl), + 0x2A: acc2rmw(rol), + 0x4A: acc2rmw(lsr), + 0x6A: acc2rmw(ror), // 2-opcode, 5-cycle, zp rmw - 0x06: {"ASL", MODE_ZP, zp5rmw(asl)}, - 0x26: {"ROL", MODE_ZP, zp5rmw(rol)}, - 0x46: {"LSR", MODE_ZP, zp5rmw(lsr)}, - 0x66: {"ROR", MODE_ZP, zp5rmw(ror)}, - 0xC6: {"DEC", MODE_ZP, zp5rmw(dec)}, - 0xE6: {"INC", MODE_ZP, zp5rmw(inc)}, + 0x06: zp5rmw(asl), + 0x26: zp5rmw(rol), + 0x46: zp5rmw(lsr), + 0x66: zp5rmw(ror), + 0xC6: zp5rmw(dec), + 0xE6: zp5rmw(inc), // 3-opcode, 6-cycle, abs rmw - 0x0E: {"ASL", MODE_ABSOLUTE, abs6rmw(asl)}, - 0x2E: {"ROL", MODE_ABSOLUTE, abs6rmw(rol)}, - 0x4E: {"LSR", MODE_ABSOLUTE, abs6rmw(lsr)}, - 0x6E: {"ROR", MODE_ABSOLUTE, abs6rmw(ror)}, - 0xCE: {"DEC", MODE_ABSOLUTE, abs6rmw(dec)}, - 0xEE: {"INC", MODE_ABSOLUTE, abs6rmw(inc)}, + 0x0E: abs6rmw(asl), + 0x2E: abs6rmw(rol), + 0x4E: abs6rmw(lsr), + 0x6E: abs6rmw(ror), + 0xCE: abs6rmw(dec), + 0xEE: abs6rmw(inc), // 2-opcode, 6-cycle, zp,X rmw - 0x16: {"ASL", MODE_ZP_X, zpx6rmw(asl)}, - 0x36: {"ROL", MODE_ZP_X, zpx6rmw(rol)}, - 0x56: {"LSR", MODE_ZP_X, zpx6rmw(lsr)}, - 0x76: {"ROR", MODE_ZP_X, zpx6rmw(ror)}, - 0xD6: {"DEC", MODE_ZP_X, zpx6rmw(dec)}, - 0xF6: {"INC", MODE_ZP_X, zpx6rmw(inc)}, + 0x16: zpx6rmw(asl), + 0x36: zpx6rmw(rol), + 0x56: zpx6rmw(lsr), + 0x76: zpx6rmw(ror), + 0xD6: zpx6rmw(dec), + 0xF6: zpx6rmw(inc), // 3-opcode, 7-cycle, abs,X rmw - 0x1E: {"ASL", MODE_ABS_X, absx7rmw(asl)}, - 0x3E: {"ROL", MODE_ABS_X, absx7rmw(rol)}, - 0x5E: {"LSR", MODE_ABS_X, absx7rmw(lsr)}, - 0x7E: {"ROR", MODE_ABS_X, absx7rmw(ror)}, - 0xDE: {"DEC", MODE_ABS_X, absx7rmw(dec)}, - 0xFE: {"INC", MODE_ABS_X, absx7rmw(inc)}, + 0x1E: absx7rmw(asl), + 0x3E: absx7rmw(rol), + 0x5E: absx7rmw(lsr), + 0x7E: absx7rmw(ror), + 0xDE: absx7rmw(dec), + 0xFE: absx7rmw(inc), }