pkg/{cpu,opcodes}: add some foundational work around the cpu and opcodes

Create some data structures to start building the CPU. Outside of some
new structures, the majority of the work in this CL was adding all
apple1 opcodes.
This commit is contained in:
Bradford Lamson-Scribner 2020-05-27 14:41:38 -06:00
parent b0bcd754d1
commit 366b4ce53e
2 changed files with 603 additions and 0 deletions

58
pkg/cpu/cpu.go Normal file
View File

@ -0,0 +1,58 @@
package cpu
// A .... Accumulator OPC A operand is AC (implied single byte instruction)
// abs .... absolute OPC $LLHH operand is address $HHLL *
// abs,X .... absolute, X-indexed OPC $LLHH,X operand is address; effective address is address incremented by X with carry **
// abs,Y .... absolute, Y-indexed OPC $LLHH,Y operand is address; effective address is address incremented by Y with carry **
// # .... immediate OPC #$BB operand is byte BB
// impl .... implied OPC operand implied
// ind .... indirect OPC ($LLHH) operand is address; effective address is contents of word at address: C.w($HHLL)
// X,ind .... X-indexed, indirect OPC ($LL,X) operand is zeropage address; effective address is word in (LL + X, LL + X + 1), inc. without carry: C.w($00LL + X)
// ind,Y .... indirect, Y-indexed OPC ($LL),Y operand is zeropage address; effective address is word in (LL, LL + 1) incremented by Y with carry: C.w($00LL) + Y
// rel .... relative OPC $BB branch target is PC + signed offset BB ***
// zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL)
// zpg,X .... zeropage, X-indexed OPC $LL,X operand is zeropage address; effective address is address incremented by X without carry **
// zpg,Y .... zeropage, Y-indexed OPC $LL,Y operand is zeropage address; effective address is address incremented by Y without carry **
// 16-bit address words are little endian, lo(w)-byte first, followed by the hi(gh)-byte.
// SR Flags (bit 7 to bit 0):
// N .... Negative
// V .... Overflow
// - .... ignored
// B .... Break
// D .... Decimal (use BCD for arithmetics)
// I .... Interrupt (IRQ disable)
// Z .... Zero
// C .... Carry
// Processor Stack:
// LIFO, top down, 8 bit range, 0x0100 - 0x01FF
// addressingMode is a type alias for a string, used below for defining addressing mode types
type addressingMode int
const (
accumulator addressingMode = iota
absolute
absoluteXIndexed
absoluteYIndexed
immediate
implied
indirect
indirectXIndexed
indirectYIndexed
relative
zeroPage
zeroPageXIndexed
zeroPageYIndexed
)
type mos6502cpu struct {
pc uint16 // program counter (16 bit)
ac uint8 // accumulator (8 bit)
x uint8 // X register (8 bit)
y uint8 // Y register (8 bit)
sr uint8 // status register [NV-BDIZC] (8 bit)
sp uint8 // stack pointer (8 bit)
}

545
pkg/cpu/opcodes.go Normal file
View File

@ -0,0 +1,545 @@
package cpu
type op struct {
name string
opcode uint8
size uint8
addressingMode addressingMode
}
func newOp(name string, opcode, size uint8, addressingMode addressingMode) op {
return op{
name: name,
opcode: opcode,
size: size,
addressingMode: addressingMode,
}
}
var opcodes = map[uint8]op{
// BRK Force Break
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied BRK 00 1 7
0x00: newOp("BRK", 0x00, 1, implied),
// RTI Return from Interrupt
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied RTI 40 1 6
0x40: newOp("RTI", 0x40, 1, implied),
// DEC Decrement Memory by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage DEC oper C6 2 5
// zeropage,X DEC oper,X D6 2 6
// absolute DEC oper CE 3 6
// absolute,X DEC oper,X DE 3 7
0xC6: newOp("DEC", 0xC6, 2, zeroPage),
0xD6: newOp("DEC", 0xD6, 2, zeroPageXIndexed),
0xCE: newOp("DEC", 0xCE, 3, absolute),
0xDE: newOp("DEC", 0xDE, 3, absoluteXIndexed),
// INC Increment Memory by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage INC oper E6 2 5
// zeropage,X INC oper,X F6 2 6
// absolute INC oper EE 3 6
// absolute,X INC oper,X FE 3 7
0xE6: newOp("INC", 0xE6, 2, zeroPage),
0xF6: newOp("INC", 0xF6, 2, zeroPageXIndexed),
0xEE: newOp("INC", 0xEE, 3, absolute),
0xFE: newOp("INC", 0xFE, 3, absoluteXIndexed),
// INX Increment Index X by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied INX E8 1 2
0xE8: newOp("INX", 0xE8, 1, implied),
// INY Increment Index Y by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied INY C8 1 2
0xC8: newOp("INY", 0xC8, 1, implied),
// TAX Transfer Accumulator to Index X
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TAX AA 1 2
0xAA: newOp("TAX", 0xAA, 1, implied),
// TAY Transfer Accumulator to Index Y
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TAY A8 1 2
0xA8: newOp("TAY", 0xA8, 1, implied),
// DEX Decrement Index X by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied DEC CA 1 2
0xCA: newOp("DEX", 0xCA, 1, implied),
// DEY Decrement Index Y by One
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied DEC 88 1 2
0x88: newOp("DEY", 0x88, 1, implied),
// LDA Load Accumulator with Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate LDA #oper A9 2 2
// zeropage LDA oper A5 2 3
// zeropage,X LDA oper,X B5 2 4
// absolute LDA oper AD 3 4
// absolute,X LDA oper,X BD 3 4*
// absolute,Y LDA oper,Y B9 3 4*
// (indirect,X) LDA (oper,X) A1 2 6
// (indirect),Y LDA (oper),Y B1 2 5*
0xA9: newOp("LDA", 0xA9, 2, immediate),
0xA5: newOp("LDA", 0xA5, 2, zeroPage),
0xB5: newOp("LDA", 0xB5, 2, zeroPageXIndexed),
0xAD: newOp("LDA", 0xAD, 3, absolute),
0xBD: newOp("LDA", 0xBD, 3, absoluteXIndexed),
0xB9: newOp("LDA", 0xB9, 3, absoluteYIndexed),
0xA1: newOp("LDA", 0xA1, 2, indirectXIndexed),
0xB1: newOp("LDA", 0xB1, 2, indirectYIndexed),
// LDX Load Index X with Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate LDX #oper A2 2 2
// zeropage LDX oper A6 2 3
// zeropage,Y LDX oper,Y B6 2 4
// absolute LDX oper AE 3 4
// absolute,Y LDX oper,Y BE 3 4*
0xA2: newOp("LDX", 0xA2, 2, immediate),
0xA6: newOp("LDX", 0xA6, 2, zeroPage),
0xB6: newOp("LDX", 0xB6, 2, zeroPageYIndexed),
0xAE: newOp("LDX", 0xAE, 3, absolute),
0xBE: newOp("LDX", 0xBE, 3, absoluteYIndexed),
// LDY Load Index Y with Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate LDY #oper A0 2 2
// zeropage LDY oper A4 2 3
// zeropage,X LDY oper,X B4 2 4
// absolute LDY oper AC 3 4
// absolute,X LDY oper,X BC 3 4*
0xA0: newOp("LDY", 0xA0, 2, immediate),
0xA4: newOp("LDY", 0xA4, 2, zeroPage),
0xB4: newOp("LDY", 0xB4, 2, zeroPageXIndexed),
0xAC: newOp("LDY", 0xAC, 3, absolute),
0xBC: newOp("LDY", 0xBC, 3, absoluteXIndexed),
// ADC Add Memory to Accumulator with Carry
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate ADC #oper 69 2 2
// zeropage ADC oper 65 2 3
// zeropage,X ADC oper,X 75 2 4
// absolute ADC oper 6D 3 4
// absolute,X ADC oper,X 7D 3 4*
// absolute,Y ADC oper,Y 79 3 4*
// (indirect,X) ADC (oper,X) 61 2 6
// (indirect),Y ADC (oper),Y 71 2 5*
0x69: newOp("ADC", 0x69, 2, immediate),
0x65: newOp("ADC", 0x65, 2, zeroPage),
0x75: newOp("ADC", 0x75, 2, zeroPageXIndexed),
0x6D: newOp("ADC", 0x6D, 3, absolute),
0x7D: newOp("ADC", 0x7D, 3, absoluteXIndexed),
0x79: newOp("ADC", 0x79, 3, absoluteYIndexed),
0x61: newOp("ADC", 0x61, 2, indirectXIndexed),
0x71: newOp("ADC", 0x71, 2, indirectYIndexed),
// SBC Subtract Memory from Accumulator with Borrow
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate SBC #oper E9 2 2
// zeropage SBC oper E5 2 3
// zeropage,X SBC oper,X F5 2 4
// absolute SBC oper ED 3 4
// absolute,X SBC oper,X FD 3 4*
// absolute,Y SBC oper,Y F9 3 4*
// (indirect,X) SBC (oper,X) E1 2 6
// (indirect),Y SBC (oper),Y F1 2 5*
0xE9: newOp("SBC", 0xE9, 2, immediate),
0xE5: newOp("SBC", 0xE5, 2, zeroPage),
0xF5: newOp("SBC", 0xF5, 2, zeroPageXIndexed),
0xED: newOp("SBC", 0xED, 3, absolute),
0xFD: newOp("SBC", 0xFD, 3, absoluteXIndexed),
0xF9: newOp("SBC", 0xF9, 3, absoluteYIndexed),
0xE1: newOp("SBC", 0xE1, 2, indirectXIndexed),
0xF1: newOp("SBC", 0xF1, 2, indirectYIndexed),
// STX Store Index X in Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage STX oper 86 2 3
// zeropage,Y STX oper,Y 96 2 4
// absolute STX oper 8E 3 4
0x86: newOp("STX", 0x86, 2, zeroPage),
0x96: newOp("STX", 0x96, 2, zeroPageYIndexed),
0x8E: newOp("STX", 0x8E, 3, absolute),
// STY Store Index Y in Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage STY oper 84 2 3
// zeropage,X STY oper,X 94 2 4
// absolute STY oper 8C 3 4
0x84: newOp("STY", 0x84, 2, zeroPage),
0x94: newOp("STY", 0x94, 2, zeroPageXIndexed),
0x8C: newOp("STY", 0x8C, 3, absolute),
// STA Store Accumulator in Memory
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage STA oper 85 2 3
// zeropage,X STA oper,X 95 2 4
// absolute STA oper 8D 3 4
// absolute,X STA oper,X 9D 3 5
// absolute,Y STA oper,Y 99 3 5
// (indirect,X) STA (oper,X) 81 2 6
// (indirect),Y STA (oper),Y 91 2 6
0x85: newOp("STA", 0x85, 2, zeroPage),
0x95: newOp("STA", 0x95, 2, zeroPageXIndexed),
0x8D: newOp("STA", 0x8D, 3, absolute),
0x9D: newOp("STA", 0x9D, 3, absoluteXIndexed),
0x99: newOp("STA", 0x99, 3, absoluteYIndexed),
0x81: newOp("STA", 0x81, 2, indirectXIndexed),
0x91: newOp("STA", 0x91, 2, indirectYIndexed),
// BEQ Branch on Result Zero
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BEQ oper F0 2 2**
0xF0: newOp("BEQ", 0xF0, 2, relative),
// BNE Branch on Result not Zero
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BNE oper D0 2 2**
0xD0: newOp("BNE", 0xD0, 2, relative),
// BVC Branch on Overflow Clear
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BVC oper 50 2 2**
0x50: newOp("BVC", 0x50, 2, relative),
// BVS Branch on Overflow Set
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BVC oper 70 2 2**
0x70: newOp("BVS", 0x70, 2, relative),
// BIT Test Bits in Memory with Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// zeropage BIT oper 24 2 3
// absolute BIT oper 2C 3 4
0x24: newOp("BIT", 0x24, 2, zeroPage),
0x2C: newOp("BIT", 0x2C, 3, absolute),
// BCC Branch on Carry Clear
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BCC oper 90 2 2**
0x90: newOp("BCC", 0x90, 2, relative),
// BMI Branch on Result Minus
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BMI oper 30 2 2**
0x30: newOp("BMI", 0x30, 2, relative),
// BPL Branch on Result Plus
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BPL oper 10 2 2**
0x10: newOp("BPL", 0x10, 2, relative),
// BCS Branch on Carry Set
// addressing assembler opc bytes cyles
// --------------------------------------------
// relative BCS oper B0 2 2**
0xB0: newOp("BCS", 0xB0, 2, relative),
// CPX Compare Memory and Index X
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate CPX #oper E0 2 2
// zeropage CPX oper E4 2 3
// absolute CPX oper EC 3 4
0xE0: newOp("CPX", 0xE0, 2, immediate),
0xE4: newOp("CPX", 0xE4, 2, zeroPage),
0xEC: newOp("CPX", 0xEC, 3, absolute),
// EOR Exclusive-OR Memory with Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate EOR #oper 49 2 2
// zeropage EOR oper 45 2 3
// zeropage,X EOR oper,X 55 2 4
// absolute EOR oper 4D 3 4
// absolute,X EOR oper,X 5D 3 4*
// absolute,Y EOR oper,Y 59 3 4*
// (indirect,X) EOR (oper,X) 41 2 6
// (indirect),Y EOR (oper),Y 51 2 5*
0x49: newOp("EOR", 0x49, 2, immediate),
0x45: newOp("EOR", 0x45, 2, zeroPage),
0x55: newOp("EOR", 0x55, 2, zeroPageXIndexed),
0x4D: newOp("EOR", 0x4D, 3, absolute),
0x5D: newOp("EOR", 0x5D, 3, absoluteXIndexed),
0x59: newOp("EOR", 0x59, 3, absoluteYIndexed),
0x41: newOp("EOR", 0x41, 2, indirectXIndexed),
0x51: newOp("EOR", 0x51, 2, indirectYIndexed),
// CMP Compare Memory with Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate CMP #oper C9 2 2
// zeropage CMP oper C5 2 3
// zeropage,X CMP oper,X D5 2 4
// absolute CMP oper CD 3 4
// absolute,X CMP oper,X DD 3 4*
// absolute,Y CMP oper,Y D9 3 4*
// (indirect,X) CMP (oper,X) C1 2 6
// (indirect),Y CMP (oper),Y D1 2 5*
0xC9: newOp("CMP", 0xC9, 2, immediate),
0xC5: newOp("CMP", 0xC5, 2, zeroPage),
0xD5: newOp("CMP", 0xD5, 2, zeroPageXIndexed),
0xCD: newOp("CMP", 0xCD, 3, absolute),
0xDD: newOp("CMP", 0xDD, 3, absoluteXIndexed),
0xD9: newOp("CMP", 0xD9, 3, absoluteYIndexed),
0xC1: newOp("CMP", 0xC1, 2, indirectXIndexed),
0xD1: newOp("CMP", 0xD1, 2, indirectYIndexed),
// CPY Compare Memory and Index Y
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate CPY #oper C0 2 2
// zeropage CPY oper C4 2 3
// absolute CPY oper CC 3 4
0xC0: newOp("CPY", 0xC0, 2, immediate),
0xC4: newOp("CPY", 0xC4, 2, zeroPage),
0xCC: newOp("CPY", 0xCC, 3, absolute),
// CLC Clear Carry Flag
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied CLC 18 1 2
0x18: newOp("CLC", 0x18, 1, implied),
// CLD Clear Decimal Mode
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied CLD D8 1 2
0xD8: newOp("CLD", 0xD8, 1, implied),
// CLI Clear Interrupt Disable Bit
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied CLI 58 1 2
0x58: newOp("CLI", 0x58, 1, implied),
// CLV Clear Overflow Flag
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied CLV B8 1 2
0xB8: newOp("CLV", 0xB8, 1, implied),
// SEC Set Carry Flag
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied SEC 38 1 2
0x38: newOp("SEC", 0x38, 1, implied),
// SED Set Decimal Flag
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied SED F8 1 2
0xF8: newOp("SED", 0xF8, 1, implied),
// SEI Set Interrupt Disable Status
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied SEI 78 1 2
0x78: newOp("SEI", 0x78, 1, implied),
// NOP No Operation
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied NOP EA 1 2
0xEA: newOp("NOP", 0xEA, 1, implied),
// JMP Jump to New Location
// addressing assembler opc bytes cyles
// --------------------------------------------
// absolute JMP oper 4C 3 3
// indirect JMP (oper) 6C 3 5
0x4C: newOp("JMP", 0x4C, 3, absolute),
0x6C: newOp("JMP", 0x6C, 3, indirect),
// PHA Push Accumulator on Stack
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied PHA 48 1 3
0x48: newOp("PHA", 0x48, 1, implied),
// TXA Transfer Index X to Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TXA 8A 1 2
0x8A: newOp("TXA", 0x8A, 1, implied),
// TYA Transfer Index Y to Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TYA 98 1 2
0x98: newOp("TYA", 0x98, 1, implied),
// TSX Transfer Stack Pointer to Index X
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TSX BA 1 2
0xBA: newOp("TSX", 0xBA, 1, implied),
// PLA Pull Accumulator from Stack
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied PLA 68 1 4
0x68: newOp("PLA", 0x68, 1, implied),
// PLP Pull Processor Status from Stack
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied PLP 28 1 4
0x28: newOp("PLP", 0x28, 1, implied),
// PHP Push Processor Status on Stack
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied PHP 08 1 3
0x08: newOp("PHP", 0x08, 1, implied),
// JSR Jump to New Location Saving Return Address
// addressing assembler opc bytes cyles
// --------------------------------------------
// absolute JSR oper 20 3 6
0x20: newOp("JSR", 0x20, 3, absolute),
// RTS Return from Subroutine
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied RTS 60 1 6
0x60: newOp("RTS", 0x60, 1, implied),
// LSR Shift One Bit Right (Memory or Accumulator)
// addressing assembler opc bytes cyles
// --------------------------------------------
// accumulator LSR A 4A 1 2
// zeropage LSR oper 46 2 5
// zeropage,X LSR oper,X 56 2 6
// absolute LSR oper 4E 3 6
// absolute,X LSR oper,X 5E 3 7
0x4A: newOp("LSR", 0x4A, 1, accumulator),
0x46: newOp("LSR", 0x46, 2, zeroPage),
0x56: newOp("LSR", 0x56, 2, zeroPageXIndexed),
0x4E: newOp("LSR", 0x4E, 3, absolute),
0x5E: newOp("LSR", 0x5E, 3, absoluteXIndexed),
// ROL Rotate One Bit Left (Memory or Accumulator)
// addressing assembler opc bytes cyles
// --------------------------------------------
// accumulator ROL A 2A 1 2
// zeropage ROL oper 26 2 5
// zeropage,X ROL oper,X 36 2 6
// absolute ROL oper 2E 3 6
// absolute,X ROL oper,X 3E 3 7
0x2A: newOp("ROL", 0x2A, 1, accumulator),
0x26: newOp("ROL", 0x26, 2, zeroPage),
0x36: newOp("ROL", 0x36, 2, zeroPageXIndexed),
0x2E: newOp("ROL", 0x2E, 3, absolute),
0x3E: newOp("ROL", 0x3E, 3, absoluteXIndexed),
// TXS Transfer Index X to Stack Register
// addressing assembler opc bytes cyles
// --------------------------------------------
// implied TXS 9A 1 2
0x9A: newOp("TXS", 0x9A, 1, implied),
// ROR Rotate One Bit Right (Memory or Accumulator)
// addressing assembler opc bytes cyles
// --------------------------------------------
// accumulator ROR A 6A 1 2
// zeropage ROR oper 66 2 5
// zeropage,X ROR oper,X 76 2 6
// absolute ROR oper 6E 3 6
// absolute,X ROR oper,X 7E 3 7
0x6A: newOp("ROR", 0x6A, 1, accumulator),
0x66: newOp("ROR", 0x66, 2, zeroPage),
0x76: newOp("ROR", 0x76, 2, zeroPageXIndexed),
0x6E: newOp("ROR", 0x6E, 3, absolute),
0x7E: newOp("ROR", 0x7E, 3, absoluteXIndexed),
// ASL Shift Left One Bit (Memory or Accumulator)
// addressing assembler opc bytes cyles
// --------------------------------------------
// accumulator ASL A 0A 1 2
// zeropage ASL oper 06 2 5
// zeropage,X ASL oper,X 16 2 6
// absolute ASL oper 0E 3 6
// absolute,X ASL oper,X 1E 3 7
0x0A: newOp("ASL", 0x0A, 1, accumulator),
0x06: newOp("ASL", 0x06, 2, zeroPage),
0x16: newOp("ASL", 0x16, 2, zeroPageXIndexed),
0x0E: newOp("ASL", 0x0E, 3, absolute),
0x1E: newOp("ASL", 0x1E, 3, absoluteXIndexed),
// AND AND Memory with Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate AND #oper 29 2 2
// zeropage AND oper 25 2 3
// zeropage,X AND oper,X 35 2 4
// absolute AND oper 2D 3 4
// absolute,X AND oper,X 3D 3 4*
// absolute,Y AND oper,Y 39 3 4*
// (indirect,X) AND (oper,X) 21 2 6
// (indirect),Y AND (oper),Y 31 2 5*
0x29: newOp("AND", 0x29, 2, immediate),
0x25: newOp("AND", 0x25, 2, zeroPage),
0x35: newOp("AND", 0x35, 2, zeroPageXIndexed),
0x2D: newOp("AND", 0x2D, 3, absolute),
0x3D: newOp("AND", 0x3D, 3, absoluteXIndexed),
0x39: newOp("AND", 0x39, 3, absoluteYIndexed),
0x21: newOp("AND", 0x21, 2, indirectXIndexed),
0x31: newOp("AND", 0x31, 2, indirectYIndexed),
// ORA OR Memory with Accumulator
// addressing assembler opc bytes cyles
// --------------------------------------------
// immidiate ORA #oper 09 2 2
// zeropage ORA oper 05 2 3
// zeropage,X ORA oper,X 15 2 4
// absolute ORA oper 0D 3 4
// absolute,X ORA oper,X 1D 3 4*
// absolute,Y ORA oper,Y 19 3 4*
// (indirect,X) ORA (oper,X) 01 2 6
// (indirect),Y ORA (oper),Y 11 2 5*
0x09: newOp("ORA", 0x09, 2, immediate),
0x05: newOp("ORA", 0x05, 2, zeroPage),
0x15: newOp("ORA", 0x15, 2, zeroPageXIndexed),
0x0D: newOp("ORA", 0x0D, 3, absolute),
0x1D: newOp("ORA", 0x1D, 3, absoluteXIndexed),
0x19: newOp("ORA", 0x19, 3, absoluteYIndexed),
0x01: newOp("ORA", 0x01, 2, indirectXIndexed),
0x11: newOp("ORA", 0x11, 2, indirectYIndexed),
}