v6502
The MOS 6502 Virtual Machine and Toolchain Infrastructure
|
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | adc m16 | 0x6D 0xLL 0xHH |
Absolute + X | adc m16, X | 0x7D 0xLL 0xHH |
Absolute + Y | adc m16, Y | 0x79 0xLL 0xHH |
Immediate | adc #imm8 | 0x69 0xLL |
Indirect + X | adc (m16, X) | 0x61 0xLL 0xHH |
Indirect + Y | adc (m16), Y | 0x71 0xLL 0xHH |
Zeropage | adc *m8 | 0x65 0xLL |
Zeropage + X | adc *m8, X | 0x75 0xLL |
Implementation |
---|
uint8_t a = cpu->ac; cpu->ac += operand + ((cpu->sr & v6502_cpu_status_carry) ? 1 : 0); FLAG_OVERFLOW_WITH_COMPARISON(a, operand, cpu->ac); FLAG_CARRY_WITH_COMPARISON(cpu->ac, operand); FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | and m16 | 0x2D 0xLL 0xHH |
Absolute + X | and m16, X | 0x3D 0xLL 0xHH |
Absolute + Y | and m16, Y | 0x39 0xLL 0xHH |
Immediate | and #imm8 | 0x29 0xLL |
Indirect + X | and (m16, X) | 0x21 0xLL 0xHH |
Indirect + Y | and (m16), Y | 0x31 0xLL 0xHH |
Zeropage | and *m8 | 0x25 0xLL |
Zeropage + X | and *m8, X | 0x35 0xLL |
Implementation |
---|
cpu->ac &= operand; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | asl m16 | 0x0E 0xLL 0xHH |
Absolute + X | asl m16, X | 0x1E 0xLL 0xHH |
Accumulator | asl A | 0x0A |
Zeropage | asl *m8 | 0x06 0xLL |
Zeropage + X | asl *m8, X | 0x16 0xLL |
Implementation |
---|
FLAG_CARRY_WITH_HIGH_BIT(operand); operand <<= 1; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); return operand; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bcc m8 | 0x90 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bcs m8 | 0xB0 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | beq m8 | 0xF0 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | bit m16 | 0x2C 0xLL 0xHH |
Zeropage | bit *m8 | 0x24 0xLL |
Implementation |
---|
uint8_t result = cpu->ac & operand; cpu->sr &= ~(v6502_cpu_status_overflow | v6502_cpu_status_negative); cpu->sr |= (operand & (v6502_cpu_status_overflow | v6502_cpu_status_negative)); FLAG_ZERO_WITH_RESULT(result); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bmi m8 | 0x30 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bne m8 | 0xD0 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bpl m8 | 0x10 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | brk | 0x00 |
Implementation |
---|
cpu->sr |= v6502_cpu_status_break; cpu->sr |= v6502_cpu_status_interrupt; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bvc m8 | 0x50 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Relative | bvs m8 | 0x70 0xLL |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | clc | 0x18 |
Implementation |
---|
cpu->sr &= ~v6502_cpu_status_carry; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | cld | 0xD8 |
Implementation |
---|
cpu->sr &= ~v6502_cpu_status_decimal; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | cli | 0x58 |
Implementation |
---|
cpu->sr &= ~v6502_cpu_status_interrupt; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | clv | 0xB8 |
Implementation |
---|
cpu->sr &= ~v6502_cpu_status_overflow; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | cmp m16 | 0xCD 0xLL 0xHH |
Absolute + X | cmp m16, X | 0xDD 0xLL 0xHH |
Absolute + Y | cmp m16, Y | 0xD9 0xLL 0xHH |
Immediate | cmp #imm8 | 0xC9 0xLL |
Indirect + X | cmp (m16, X) | 0xC1 0xLL 0xHH |
Indirect + Y | cmp (m16), Y | 0xD1 0xLL 0xHH |
Zeropage | cmp *m8 | 0xC5 0xLL |
Zeropage + X | cmp *m8, X | 0xD5 0xLL |
Implementation |
---|
uint8_t result = reg - operand; FLAG_CARRY_WITH_COMPARISON(operand, reg); FLAG_NEG_AND_ZERO_WITH_RESULT(result); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | cpx m16 | 0xEC 0xLL 0xHH |
Immediate | cpx #imm8 | 0xE0 0xLL |
Zeropage | cpx *m8 | 0xE4 0xLL |
Implementation |
---|
uint8_t result = reg - operand; FLAG_CARRY_WITH_COMPARISON(operand, reg); FLAG_NEG_AND_ZERO_WITH_RESULT(result); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | cpy m16 | 0xCC 0xLL 0xHH |
Immediate | cpy #imm8 | 0xC0 0xLL |
Zeropage | cpy *m8 | 0xC4 0xLL |
Implementation |
---|
uint8_t result = reg - operand; FLAG_CARRY_WITH_COMPARISON(operand, reg); FLAG_NEG_AND_ZERO_WITH_RESULT(result); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | dec m16 | 0xCE 0xLL 0xHH |
Absolute + X | dec m16, X | 0xDE 0xLL 0xHH |
Zeropage | dec *m8 | 0xC6 0xLL |
Zeropage + X | dec *m8, X | 0xD6 0xLL |
Implementation |
---|
operand--; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | dex | 0xCA |
Implementation |
---|
operand--; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | dey | 0x88 |
Implementation |
---|
operand--; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | eor m16 | 0x4D 0xLL 0xHH |
Absolute + X | eor m16, X | 0x5D 0xLL 0xHH |
Absolute + Y | eor m16, Y | 0x59 0xLL 0xHH |
Immediate | eor #imm8 | 0x49 0xLL |
Indirect + X | eor (m16, X) | 0x41 0xLL 0xHH |
Indirect + Y | eor (m16), Y | 0x51 0xLL 0xHH |
Zeropage | eor *m8 | 0x45 0xLL |
Zeropage + X | eor *m8, X | 0x55 0xLL |
Implementation |
---|
cpu->ac ^= operand; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | inc m16 | 0xEE 0xLL 0xHH |
Absolute + X | inc m16, X | 0xFE 0xLL 0xHH |
Zeropage | inc *m8 | 0xE6 0xLL |
Zeropage + X | inc *m8, X | 0xF6 0xLL |
Implementation |
---|
operand++; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | inx | 0xE8 |
Implementation |
---|
operand++; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | iny | 0xC8 |
Implementation |
---|
operand++; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | jmp m16 | 0x4C 0xLL 0xHH |
Indirect | jmp (m16) | 0x6C 0xLL 0xHH |
Implementation |
---|
case v6502_opcode_jmp_abs: { if (BOTH_BYTES == cpu->pc) { v6502_execute(cpu, v6502_opcode_wai, 0, 0); cpu->pc -= 3; // PC shift return; } cpu->pc = BOTH_BYTES; cpu->pc -= 3; // PC shift } return; case v6502_opcode_jmp_ind: { uint16_t address = BOTH_BYTES; low = v6502_read(cpu->memory, address, NO); high = v6502_read(cpu->memory, address + 1, NO); // Trap was already triggered by indirect memory classification in prior switch cpu->pc = BOTH_BYTES; cpu->pc -= 3; // PC shift } return; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | jsr m16 | 0x20 0xLL 0xHH |
Implementation |
---|
cpu->memory->bytes[v6502_memoryStartStack + cpu->sp--] = cpu->pc; // Low byte first cpu->memory->bytes[v6502_memoryStartStack + cpu->sp--] = (cpu->pc >> 8); // High byte second cpu->pc = BOTH_BYTES; cpu->pc -= 3; // To compensate for post execution shift |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | lda m16 | 0xAD 0xLL 0xHH |
Absolute + X | lda m16, X | 0xBD 0xLL 0xHH |
Absolute + Y | lda m16, Y | 0xB9 0xLL 0xHH |
Immediate | lda #imm8 | 0xA9 0xLL |
Indirect + X | lda (m16, X) | 0xA1 0xLL 0xHH |
Indirect + Y | lda (m16), Y | 0xB1 0xLL 0xHH |
Zeropage | lda *m8 | 0xA5 0xLL |
Zeropage + X | lda *m8, X | 0xB5 0xLL |
Implementation |
---|
cpu->ac = operand; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | ldx m16 | 0xAE 0xLL 0xHH |
Absolute + Y | ldx m16, Y | 0xBE 0xLL 0xHH |
Immediate | ldx #imm8 | 0xA2 0xLL |
Zeropage | ldx *m8 | 0xA6 0xLL |
Zeropage + Y | ldx *m8, Y | 0xB6 0xLL |
Implementation |
---|
cpu->x = operand; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | ldy m16 | 0xAC 0xLL 0xHH |
Absolute + X | ldy m16, X | 0xBC 0xLL 0xHH |
Immediate | ldy #imm8 | 0xA0 0xLL |
Zeropage | ldy *m8 | 0xA4 0xLL |
Zeropage + X | ldy *m8, X | 0xB4 0xLL |
Implementation |
---|
cpu->y = operand; FLAG_NEG_AND_ZERO_WITH_RESULT(operand); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | lsr m16 | 0x4E 0xLL 0xHH |
Absolute + X | lsr m16, X | 0x5E 0xLL 0xHH |
Accumulator | lsr A | 0x4A |
Zeropage | lsr *m8 | 0x46 0xLL |
Zeropage + X | lsr *m8, X | 0x56 0xLL |
Implementation |
---|
FLAG_CARRY_WITH_LOW_BIT(operand); operand >>= 1; FLAG_ZERO_WITH_RESULT(operand); return operand; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | nop | 0xEA |
Implementation |
---|
/* Do nothing */ |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | ora m16 | 0x0D 0xLL 0xHH |
Absolute + X | ora m16, X | 0x1D 0xLL 0xHH |
Absolute + Y | ora m16, Y | 0x19 0xLL 0xHH |
Immediate | ora #imm8 | 0x09 0xLL |
Indirect + X | ora (m16, X) | 0x01 0xLL 0xHH |
Indirect + Y | ora (m16), Y | 0x11 0xLL 0xHH |
Zeropage | ora *m8 | 0x05 0xLL |
Zeropage + X | ora *m8, X | 0x15 0xLL |
Implementation |
---|
cpu->ac |= operand; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | pha | 0x48 |
Implementation |
---|
cpu->memory->bytes[v6502_memoryStartStack + cpu->sp--] = cpu->ac; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | php | 0x08 |
Implementation |
---|
cpu->memory->bytes[v6502_memoryStartStack + cpu->sp--] = cpu->sr; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | pla | 0x68 |
Implementation |
---|
cpu->ac = cpu->memory->bytes[v6502_memoryStartStack + ++cpu->sp]; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | plp | 0x28 |
Implementation |
---|
cpu->sr = cpu->memory->bytes[v6502_memoryStartStack + ++cpu->sp]; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | rol m16 | 0x2E 0xLL 0xHH |
Absolute + X | rol m16, X | 0x3E 0xLL 0xHH |
Accumulator | rol A | 0x2A |
Zeropage | rol *m8 | 0x26 0xLL |
Zeropage + X | rol *m8, X | 0x36 0xLL |
Implementation |
---|
uint8_t carry = (cpu->sr & v6502_cpu_status_carry); FLAG_CARRY_WITH_HIGH_BIT(operand); operand = (operand << 1) | (carry); FLAG_NEG_AND_ZERO_WITH_RESULT(operand); return operand; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | ror m16 | 0x6E 0xLL 0xHH |
Absolute + X | ror m16, X | 0x7E 0xLL 0xHH |
Accumulator | ror A | 0x6A |
Zeropage | ror *m8 | 0x66 0xLL |
Zeropage + X | ror *m8, X | 0x76 0xLL |
Implementation |
---|
uint8_t carry = (cpu->sr & v6502_cpu_status_carry); FLAG_CARRY_WITH_LOW_BIT(operand); operand = (operand >> 1) | (carry << 7); FLAG_NEG_AND_ZERO_WITH_RESULT(operand); return operand; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | rti | 0x40 |
Implementation |
---|
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | rts | 0x60 |
Implementation |
---|
cpu->pc = (cpu->memory->bytes[v6502_memoryStartStack + ++cpu->sp] << 8); cpu->pc |= cpu->memory->bytes[v6502_memoryStartStack + ++cpu->sp]; cpu->pc += 2; // To compensate for post execution shift ( - 1 rts, + 3 jsr ) |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | sbc m16 | 0xED 0xLL 0xHH |
Absolute + X | sbc m16, X | 0xFD 0xLL 0xHH |
Absolute + Y | sbc m16, Y | 0xF9 0xLL 0xHH |
Immediate | sbc #imm8 | 0xE9 0xLL |
Indirect + X | sbc (m16, X) | 0xE1 0xLL 0xHH |
Indirect + Y | sbc (m16), Y | 0xF1 0xLL 0xHH |
Zeropage | sbc *m8 | 0xE5 0xLL |
Zeropage + X | sbc *m8, X | 0xF5 0xLL |
Implementation |
---|
_executeInPlaceADC(cpu, operand ^ BYTE_MAX); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | sec | 0x38 |
Implementation |
---|
cpu->sr |= v6502_cpu_status_carry; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | sed | 0xF8 |
Implementation |
---|
cpu->sr |= v6502_cpu_status_decimal; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | sei | 0x78 |
Implementation |
---|
cpu->sr |= v6502_cpu_status_interrupt; |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | sta m16 | 0x8D 0xLL 0xHH |
Absolute + X | sta m16, X | 0x9D 0xLL 0xHH |
Absolute + Y | sta m16, Y | 0x99 0xLL 0xHH |
Indirect + X | sta (m16, X) | 0x81 0xLL 0xHH |
Indirect + Y | sta (m16), Y | 0x91 0xLL 0xHH |
Zeropage | sta *m8 | 0x85 0xLL |
Zeropage + X | sta *m8, X | 0x95 0xLL |
Implementation |
---|
v6502_write(cpu->memory, ref, cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | stx m16 | 0x8E 0xLL 0xHH |
Zeropage | stx *m8 | 0x86 0xLL |
Zeropage + Y | stx *m8, Y | 0x96 0xLL |
Implementation |
---|
v6502_write(cpu->memory, ref, cpu->x); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Absolute | sty m16 | 0x8C 0xLL 0xHH |
Zeropage | sty *m8 | 0x84 0xLL |
Zeropage + X | sty *m8, X | 0x94 0xLL |
Implementation |
---|
v6502_write(cpu->memory, ref, cpu->y); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | tax | 0xAA |
Implementation |
---|
cpu->x = cpu->ac; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | tay | 0xA8 |
Implementation |
---|
cpu->y = cpu->ac; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | tsx | 0xBA |
Implementation |
---|
cpu->x = cpu->sp; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->sp); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | txa | 0x8A |
Implementation |
---|
cpu->ac = cpu->x; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | txs | 0x9A |
Implementation |
---|
cpu->sp = cpu->x; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->sp); |
Address Mode | Mnemonic | Opcode |
---|---|---|
Implied | tya | 0x98 |
Implementation |
---|
cpu->ac = cpu->y; FLAG_NEG_AND_ZERO_WITH_RESULT(cpu->ac); |