diff options
Diffstat (limited to 'cpu/opcodes.go')
| -rw-r--r-- | cpu/opcodes.go | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/cpu/opcodes.go b/cpu/opcodes.go new file mode 100644 index 0000000..c4ac911 --- /dev/null +++ b/cpu/opcodes.go @@ -0,0 +1,295 @@ +package cpu + +import "fmt" + +type opcodeEntry struct { + name string + mode AddrMode + cycles int + pageCrossPenalty bool + exec func(c *CPU, op operand) +} + +var opcodeTable [256]opcodeEntry + +func def(code uint8, name string, mode AddrMode, cycles int, pageCrossPenalty bool, exec func(*CPU, operand)) { + opcodeTable[code] = opcodeEntry{name, mode, cycles, pageCrossPenalty, exec} +} + +func init() { + for i := 0; i < 256; i++ { + code := uint8(i) + opcodeTable[i] = opcodeEntry{ + name: "???", + mode: ModeImplied, + exec: func(c *CPU, op operand) { + panic(fmt.Sprintf("cpu: unimplemented or illegal opcode 0x%02X", code)) + }, + } + } + + def(0xA9, "LDA", ModeImmediate, 2, false, ldaExec) + def(0xA5, "LDA", ModeZeroPage, 3, false, ldaExec) + def(0xB5, "LDA", ModeZeroPageX, 4, false, ldaExec) + def(0xAD, "LDA", ModeAbsolute, 4, false, ldaExec) + def(0xBD, "LDA", ModeAbsoluteX, 4, true, ldaExec) + def(0xB9, "LDA", ModeAbsoluteY, 4, true, ldaExec) + def(0xA1, "LDA", ModeIndirectX, 6, false, ldaExec) + def(0xB1, "LDA", ModeIndirectY, 5, true, ldaExec) + + def(0xA2, "LDX", ModeImmediate, 2, false, ldxExec) + def(0xA6, "LDX", ModeZeroPage, 3, false, ldxExec) + def(0xB6, "LDX", ModeZeroPageY, 4, false, ldxExec) + def(0xAE, "LDX", ModeAbsolute, 4, false, ldxExec) + def(0xBE, "LDX", ModeAbsoluteY, 4, true, ldxExec) + + def(0xA0, "LDY", ModeImmediate, 2, false, ldyExec) + def(0xA4, "LDY", ModeZeroPage, 3, false, ldyExec) + def(0xB4, "LDY", ModeZeroPageX, 4, false, ldyExec) + def(0xAC, "LDY", ModeAbsolute, 4, false, ldyExec) + def(0xBC, "LDY", ModeAbsoluteX, 4, true, ldyExec) + + def(0x85, "STA", ModeZeroPage, 3, false, staExec) + def(0x95, "STA", ModeZeroPageX, 4, false, staExec) + def(0x8D, "STA", ModeAbsolute, 4, false, staExec) + def(0x9D, "STA", ModeAbsoluteX, 5, false, staExec) + def(0x99, "STA", ModeAbsoluteY, 5, false, staExec) + def(0x81, "STA", ModeIndirectX, 6, false, staExec) + def(0x91, "STA", ModeIndirectY, 6, false, staExec) + + def(0x86, "STX", ModeZeroPage, 3, false, stxExec) + def(0x96, "STX", ModeZeroPageY, 4, false, stxExec) + def(0x8E, "STX", ModeAbsolute, 4, false, stxExec) + + def(0x84, "STY", ModeZeroPage, 3, false, styExec) + def(0x94, "STY", ModeZeroPageX, 4, false, styExec) + def(0x8C, "STY", ModeAbsolute, 4, false, styExec) + + def(0xAA, "TAX", ModeImplied, 2, false, taxExec) + def(0x8A, "TXA", ModeImplied, 2, false, txaExec) + def(0xA8, "TAY", ModeImplied, 2, false, tayExec) + def(0x98, "TYA", ModeImplied, 2, false, tyaExec) + def(0xBA, "TSX", ModeImplied, 2, false, tsxExec) + def(0x9A, "TXS", ModeImplied, 2, false, txsExec) + + def(0x48, "PHA", ModeImplied, 3, false, phaExec) + def(0x68, "PLA", ModeImplied, 4, false, plaExec) + def(0x08, "PHP", ModeImplied, 3, false, phpExec) + def(0x28, "PLP", ModeImplied, 4, false, plpExec) + + def(0x69, "ADC", ModeImmediate, 2, false, adcExec) + def(0x65, "ADC", ModeZeroPage, 3, false, adcExec) + def(0x75, "ADC", ModeZeroPageX, 4, false, adcExec) + def(0x6D, "ADC", ModeAbsolute, 4, false, adcExec) + def(0x7D, "ADC", ModeAbsoluteX, 4, true, adcExec) + def(0x79, "ADC", ModeAbsoluteY, 4, true, adcExec) + def(0x61, "ADC", ModeIndirectX, 6, false, adcExec) + def(0x71, "ADC", ModeIndirectY, 5, true, adcExec) + + def(0xE9, "SBC", ModeImmediate, 2, false, sbcExec) + def(0xE5, "SBC", ModeZeroPage, 3, false, sbcExec) + def(0xF5, "SBC", ModeZeroPageX, 4, false, sbcExec) + def(0xED, "SBC", ModeAbsolute, 4, false, sbcExec) + def(0xFD, "SBC", ModeAbsoluteX, 4, true, sbcExec) + def(0xF9, "SBC", ModeAbsoluteY, 4, true, sbcExec) + def(0xE1, "SBC", ModeIndirectX, 6, false, sbcExec) + def(0xF1, "SBC", ModeIndirectY, 5, true, sbcExec) + + def(0x29, "AND", ModeImmediate, 2, false, andExec) + def(0x25, "AND", ModeZeroPage, 3, false, andExec) + def(0x35, "AND", ModeZeroPageX, 4, false, andExec) + def(0x2D, "AND", ModeAbsolute, 4, false, andExec) + def(0x3D, "AND", ModeAbsoluteX, 4, true, andExec) + def(0x39, "AND", ModeAbsoluteY, 4, true, andExec) + def(0x21, "AND", ModeIndirectX, 6, false, andExec) + def(0x31, "AND", ModeIndirectY, 5, true, andExec) + + def(0x09, "ORA", ModeImmediate, 2, false, oraExec) + def(0x05, "ORA", ModeZeroPage, 3, false, oraExec) + def(0x15, "ORA", ModeZeroPageX, 4, false, oraExec) + def(0x0D, "ORA", ModeAbsolute, 4, false, oraExec) + def(0x1D, "ORA", ModeAbsoluteX, 4, true, oraExec) + def(0x19, "ORA", ModeAbsoluteY, 4, true, oraExec) + def(0x01, "ORA", ModeIndirectX, 6, false, oraExec) + def(0x11, "ORA", ModeIndirectY, 5, true, oraExec) + + def(0x49, "EOR", ModeImmediate, 2, false, eorExec) + def(0x45, "EOR", ModeZeroPage, 3, false, eorExec) + def(0x55, "EOR", ModeZeroPageX, 4, false, eorExec) + def(0x4D, "EOR", ModeAbsolute, 4, false, eorExec) + def(0x5D, "EOR", ModeAbsoluteX, 4, true, eorExec) + def(0x59, "EOR", ModeAbsoluteY, 4, true, eorExec) + def(0x41, "EOR", ModeIndirectX, 6, false, eorExec) + def(0x51, "EOR", ModeIndirectY, 5, true, eorExec) + + def(0x24, "BIT", ModeZeroPage, 3, false, bitExec) + def(0x2C, "BIT", ModeAbsolute, 4, false, bitExec) + + def(0x0A, "ASL", ModeAccumulator, 2, false, aslExec) + def(0x06, "ASL", ModeZeroPage, 5, false, aslExec) + def(0x16, "ASL", ModeZeroPageX, 6, false, aslExec) + def(0x0E, "ASL", ModeAbsolute, 6, false, aslExec) + def(0x1E, "ASL", ModeAbsoluteX, 7, false, aslExec) + + def(0x4A, "LSR", ModeAccumulator, 2, false, lsrExec) + def(0x46, "LSR", ModeZeroPage, 5, false, lsrExec) + def(0x56, "LSR", ModeZeroPageX, 6, false, lsrExec) + def(0x4E, "LSR", ModeAbsolute, 6, false, lsrExec) + def(0x5E, "LSR", ModeAbsoluteX, 7, false, lsrExec) + + def(0x2A, "ROL", ModeAccumulator, 2, false, rolExec) + def(0x26, "ROL", ModeZeroPage, 5, false, rolExec) + def(0x36, "ROL", ModeZeroPageX, 6, false, rolExec) + def(0x2E, "ROL", ModeAbsolute, 6, false, rolExec) + def(0x3E, "ROL", ModeAbsoluteX, 7, false, rolExec) + + def(0x6A, "ROR", ModeAccumulator, 2, false, rorExec) + def(0x66, "ROR", ModeZeroPage, 5, false, rorExec) + def(0x76, "ROR", ModeZeroPageX, 6, false, rorExec) + def(0x6E, "ROR", ModeAbsolute, 6, false, rorExec) + def(0x7E, "ROR", ModeAbsoluteX, 7, false, rorExec) + + def(0xE6, "INC", ModeZeroPage, 5, false, incExec) + def(0xF6, "INC", ModeZeroPageX, 6, false, incExec) + def(0xEE, "INC", ModeAbsolute, 6, false, incExec) + def(0xFE, "INC", ModeAbsoluteX, 7, false, incExec) + + def(0xC6, "DEC", ModeZeroPage, 5, false, decExec) + def(0xD6, "DEC", ModeZeroPageX, 6, false, decExec) + def(0xCE, "DEC", ModeAbsolute, 6, false, decExec) + def(0xDE, "DEC", ModeAbsoluteX, 7, false, decExec) + + def(0xE8, "INX", ModeImplied, 2, false, inxExec) + def(0xCA, "DEX", ModeImplied, 2, false, dexExec) + def(0xC8, "INY", ModeImplied, 2, false, inyExec) + def(0x88, "DEY", ModeImplied, 2, false, deyExec) + + def(0xC9, "CMP", ModeImmediate, 2, false, cmpExec) + def(0xC5, "CMP", ModeZeroPage, 3, false, cmpExec) + def(0xD5, "CMP", ModeZeroPageX, 4, false, cmpExec) + def(0xCD, "CMP", ModeAbsolute, 4, false, cmpExec) + def(0xDD, "CMP", ModeAbsoluteX, 4, true, cmpExec) + def(0xD9, "CMP", ModeAbsoluteY, 4, true, cmpExec) + def(0xC1, "CMP", ModeIndirectX, 6, false, cmpExec) + def(0xD1, "CMP", ModeIndirectY, 5, true, cmpExec) + + def(0xE0, "CPX", ModeImmediate, 2, false, cpxExec) + def(0xE4, "CPX", ModeZeroPage, 3, false, cpxExec) + def(0xEC, "CPX", ModeAbsolute, 4, false, cpxExec) + + def(0xC0, "CPY", ModeImmediate, 2, false, cpyExec) + def(0xC4, "CPY", ModeZeroPage, 3, false, cpyExec) + def(0xCC, "CPY", ModeAbsolute, 4, false, cpyExec) + + def(0x90, "BCC", ModeRelative, 2, false, bccExec) + def(0xB0, "BCS", ModeRelative, 2, false, bcsExec) + def(0xD0, "BNE", ModeRelative, 2, false, bneExec) + def(0xF0, "BEQ", ModeRelative, 2, false, beqExec) + def(0x10, "BPL", ModeRelative, 2, false, bplExec) + def(0x30, "BMI", ModeRelative, 2, false, bmiExec) + def(0x50, "BVC", ModeRelative, 2, false, bvcExec) + def(0x70, "BVS", ModeRelative, 2, false, bvsExec) + + def(0x4C, "JMP", ModeAbsolute, 3, false, jmpExec) + def(0x6C, "JMP", ModeIndirect, 5, false, jmpExec) + def(0x20, "JSR", ModeAbsolute, 6, false, jsrExec) + def(0x60, "RTS", ModeImplied, 6, false, rtsExec) + def(0x40, "RTI", ModeImplied, 6, false, rtiExec) + + def(0x18, "CLC", ModeImplied, 2, false, clcExec) + def(0x38, "SEC", ModeImplied, 2, false, secExec) + def(0x58, "CLI", ModeImplied, 2, false, cliExec) + def(0x78, "SEI", ModeImplied, 2, false, seiExec) + def(0xD8, "CLD", ModeImplied, 2, false, cldExec) + def(0xF8, "SED", ModeImplied, 2, false, sedExec) + def(0xB8, "CLV", ModeImplied, 2, false, clvExec) + + def(0xEA, "NOP", ModeImplied, 2, false, nopExec) + def(0x00, "BRK", ModeImplied, 7, false, brkExec) + + def(0x1A, "NOP", ModeImplied, 2, false, nopExec) + def(0x3A, "NOP", ModeImplied, 2, false, nopExec) + def(0x5A, "NOP", ModeImplied, 2, false, nopExec) + def(0x7A, "NOP", ModeImplied, 2, false, nopExec) + def(0xDA, "NOP", ModeImplied, 2, false, nopExec) + def(0xFA, "NOP", ModeImplied, 2, false, nopExec) + def(0x80, "NOP", ModeImmediate, 2, false, nopExec) + def(0x04, "NOP", ModeZeroPage, 3, false, nopExec) + def(0x44, "NOP", ModeZeroPage, 3, false, nopExec) + def(0x64, "NOP", ModeZeroPage, 3, false, nopExec) + def(0x14, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0x34, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0x54, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0x74, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0xD4, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0xF4, "NOP", ModeZeroPageX, 4, false, nopExec) + def(0x0C, "NOP", ModeAbsolute, 4, false, nopExec) + def(0x1C, "NOP", ModeAbsoluteX, 4, true, nopExec) + def(0x3C, "NOP", ModeAbsoluteX, 4, true, nopExec) + def(0x5C, "NOP", ModeAbsoluteX, 4, true, nopExec) + def(0x7C, "NOP", ModeAbsoluteX, 4, true, nopExec) + def(0xDC, "NOP", ModeAbsoluteX, 4, true, nopExec) + def(0xFC, "NOP", ModeAbsoluteX, 4, true, nopExec) + + def(0xEB, "SBC", ModeImmediate, 2, false, sbcExec) + + def(0xA7, "LAX", ModeZeroPage, 3, false, laxExec) + def(0xB7, "LAX", ModeZeroPageY, 4, false, laxExec) + def(0xAF, "LAX", ModeAbsolute, 4, false, laxExec) + def(0xBF, "LAX", ModeAbsoluteY, 4, true, laxExec) + def(0xA3, "LAX", ModeIndirectX, 6, false, laxExec) + def(0xB3, "LAX", ModeIndirectY, 5, true, laxExec) + + def(0x87, "SAX", ModeZeroPage, 3, false, saxExec) + def(0x97, "SAX", ModeZeroPageY, 4, false, saxExec) + def(0x8F, "SAX", ModeAbsolute, 4, false, saxExec) + def(0x83, "SAX", ModeIndirectX, 6, false, saxExec) + + def(0xC7, "DCP", ModeZeroPage, 5, false, dcpExec) + def(0xD7, "DCP", ModeZeroPageX, 6, false, dcpExec) + def(0xCF, "DCP", ModeAbsolute, 6, false, dcpExec) + def(0xDF, "DCP", ModeAbsoluteX, 7, false, dcpExec) + def(0xDB, "DCP", ModeAbsoluteY, 7, false, dcpExec) + def(0xC3, "DCP", ModeIndirectX, 8, false, dcpExec) + def(0xD3, "DCP", ModeIndirectY, 8, false, dcpExec) + + def(0x07, "SLO", ModeZeroPage, 5, false, sloExec) + def(0x17, "SLO", ModeZeroPageX, 6, false, sloExec) + def(0x0F, "SLO", ModeAbsolute, 6, false, sloExec) + def(0x1F, "SLO", ModeAbsoluteX, 7, false, sloExec) + def(0x1B, "SLO", ModeAbsoluteY, 7, false, sloExec) + def(0x03, "SLO", ModeIndirectX, 8, false, sloExec) + def(0x13, "SLO", ModeIndirectY, 8, false, sloExec) + + def(0x27, "RLA", ModeZeroPage, 5, false, rlaExec) + def(0x37, "RLA", ModeZeroPageX, 6, false, rlaExec) + def(0x2F, "RLA", ModeAbsolute, 6, false, rlaExec) + def(0x3F, "RLA", ModeAbsoluteX, 7, false, rlaExec) + def(0x3B, "RLA", ModeAbsoluteY, 7, false, rlaExec) + def(0x23, "RLA", ModeIndirectX, 8, false, rlaExec) + def(0x33, "RLA", ModeIndirectY, 8, false, rlaExec) + + def(0x47, "SRE", ModeZeroPage, 5, false, sreExec) + def(0x57, "SRE", ModeZeroPageX, 6, false, sreExec) + def(0x4F, "SRE", ModeAbsolute, 6, false, sreExec) + def(0x5F, "SRE", ModeAbsoluteX, 7, false, sreExec) + def(0x5B, "SRE", ModeAbsoluteY, 7, false, sreExec) + def(0x43, "SRE", ModeIndirectX, 8, false, sreExec) + def(0x53, "SRE", ModeIndirectY, 8, false, sreExec) + + def(0x67, "RRA", ModeZeroPage, 5, false, rraExec) + def(0x77, "RRA", ModeZeroPageX, 6, false, rraExec) + def(0x6F, "RRA", ModeAbsolute, 6, false, rraExec) + def(0x7F, "RRA", ModeAbsoluteX, 7, false, rraExec) + def(0x7B, "RRA", ModeAbsoluteY, 7, false, rraExec) + def(0x63, "RRA", ModeIndirectX, 8, false, rraExec) + def(0x73, "RRA", ModeIndirectY, 8, false, rraExec) + + def(0xE7, "ISC", ModeZeroPage, 5, false, iscExec) + def(0xF7, "ISC", ModeZeroPageX, 6, false, iscExec) + def(0xEF, "ISC", ModeAbsolute, 6, false, iscExec) + def(0xFF, "ISC", ModeAbsoluteX, 7, false, iscExec) + def(0xFB, "ISC", ModeAbsoluteY, 7, false, iscExec) + def(0xE3, "ISC", ModeIndirectX, 8, false, iscExec) + def(0xF3, "ISC", ModeIndirectY, 8, false, iscExec) +} |