package com.dreamfabric.jac64; /** * Definitions for the MOS6510Core * * Defines the operations and their addressing modes * * Created: Mon Jun 26 16:17:19 2006 * * @author Joakim Eriksson * @version 1.0 */ public class MOS6510Ops { // Instructions in order of appearance in below table... public static final int BRK = 0; public static final int ORA = 1; public static final int TRP = 2; public static final int SLO = 3; public static final int NOP = 4; public static final int ASL = 5; public static final int PHP = 6; public static final int ANC = 7; public static final int BPL = 8; public static final int CLC = 9; public static final int JSR = 10; public static final int AND = 11; public static final int RLA = 12; public static final int BIT = 13; public static final int ROL = 14; public static final int PLP = 15; public static final int BMI = 16; public static final int SEC = 17; public static final int RTI = 18; public static final int EOR = 19; public static final int SRE = 20; public static final int LSR = 21; public static final int PHA = 22; public static final int ASR = 23; public static final int JMP = 24; public static final int BVC = 25; public static final int CLI = 26; public static final int RTS = 27; public static final int ADC = 28; public static final int RRA = 29; public static final int ROR = 30; public static final int PLA = 31; public static final int ARR = 32; public static final int BVS = 33; public static final int SEI = 34; public static final int SAX = 35; public static final int STA = 36; public static final int STY = 37; public static final int STX = 38; public static final int DEY = 39; public static final int TXA = 40; public static final int ANE = 41; public static final int BCC = 42; public static final int SHA = 43; public static final int TYA = 44; public static final int TXS = 45; public static final int SHS = 46; public static final int SHY = 47; public static final int SHX = 48; public static final int LDY = 49; public static final int LDA = 50; public static final int LDX = 51; public static final int LAX = 52; public static final int TAX = 53; public static final int LXA = 54; public static final int TAY = 55; public static final int BCS = 56; public static final int CLV = 57; public static final int TSX = 58; public static final int LAS = 59; public static final int CPY = 60; public static final int CMP = 61; public static final int DCP = 62; public static final int DEC = 63; public static final int INY = 64; public static final int DEX = 65; public static final int SBX = 66; public static final int BNE = 67; public static final int CLD = 68; public static final int CPX = 69; public static final int SBC = 70; public static final int ISB = 71; public static final int INC = 72; public static final int INX = 73; public static final int BEQ = 74; public static final int SED = 75; public static final int LOAD_FILE = 76; // Load at 256! public static final int SLEEP = 77; // Load at 256! public static final int OP_LOAD_FILE = 0x100; public static final int OP_SLEEP = 0x101; public static final int ADDRESSING_MASK = 0xf00; public static final int ADDRESSING_SHIFT = 8; public static final int OP_MASK = 0x0ff; public static final int IMMEDIATE = 0x100; public static final int ZERO = 0x200; public static final int ABSOLUTE = 0x300; public static final int ZERO_X = 0x400; public static final int ZERO_Y = 0x500; public static final int ABSOLUTE_X = 0x600; public static final int ABSOLUTE_Y = 0x700; public static final int RELATIVE = 0x800; public static final int INDIRECT_X = 0x900; // From zeropage public static final int INDIRECT_Y = 0xa00; // From zeropage public static final int ACCUMULATOR = 0xb00; public static final int INDIRECT = 0xc00; public static final int MODE_MASK = 0xf000; public static final int MODE_SHIFT = 12; public static final int READ = 0x1000; public static final int WRITE = 0x2000; public static final int RMW = 0x3000; public static final String[] INS_STR = { "BRK", "ORA", "TRP", "SLO", "NOP", "ASL", "PHP", "ANC", "BPL", "CLC", "JSR", "AND", "RLA", "BIT", "ROL", "PLP", "BMI", "SEC", "RTI", "EOR", "SRE", "LSR", "PHA", "ASR", "JMP", "BVC", "CLI", "RTS", "ADC", "RRA", "ROR", "PLA", "ARR", "BVS", "SEI", "SAX", "STA", "STY", "STX", "DEY", "TXA", "ANE", "BCC", "SHA", "TYA", "TXS", "SHS", "SHY", "SHX", "LDY", "LDA", "LDX", "LAX", "TAX", "LXA", "TAY", "BCS", "CLV", "TSX", "LAS", "CPY", "CMP", "DCP", "DEC", "INY", "DEX", "SBX", "BNE", "CLD", "CPX", "SBC", "ISB", "INC", "INX", "BEQ", "SED", "X-LOAD_FILE", "X-SLEEP" }; public static final String[] ADR_STR_PRE = { " ", " #", " Z ", " ", " Z ", " Z ", " ", " ", " ", " (", " (", " ACC", " (" }; public static final String[] ADR_STR_POST = { "", "", "", "", ",X", ",Y", ",X", ",Y", "", ",X)", "),Y", "", ")" }; public static final int[] ADR_LEN = { 1, 2, 2, 3, 2, 2, 3, 3, 2, 2, 2, 1, 3 }; // Instruction set table public static final int[] INSTRUCTION_SET = { BRK, ORA, TRP, SLO, NOP, ORA, ASL, SLO, PHP, ORA, ASL, ANC, NOP, ORA, ASL, SLO, BPL, ORA, TRP, SLO, NOP, ORA, ASL, SLO, CLC, ORA, NOP, SLO, NOP, ORA, ASL, SLO, JSR, AND, TRP, RLA, BIT, AND, ROL, RLA, PLP, AND, ROL, ANC, BIT, AND, ROL, RLA, BMI, AND, TRP, RLA, NOP, AND, ROL, RLA, SEC, AND, NOP, RLA, NOP, AND, ROL, RLA, RTI, EOR, TRP, SRE, NOP, EOR, LSR, SRE, PHA, EOR, LSR, ASR, JMP, EOR, LSR, SRE, BVC, EOR, TRP, SRE, NOP, EOR, LSR, SRE, CLI, EOR, NOP, SRE, NOP, EOR, LSR, SRE, RTS, ADC, TRP, RRA, NOP, ADC, ROR, RRA, PLA, ADC, ROR, ARR, JMP, ADC, ROR, RRA, BVS, ADC, TRP, RRA, NOP, ADC, ROR, RRA, SEI, ADC, NOP, RRA, NOP, ADC, ROR, RRA, NOP, STA, NOP, SAX, STY, STA, STX, SAX, DEY, NOP, TXA, ANE, STY, STA, STX, SAX, BCC, STA, TRP, SHA, STY, STA, STX, SAX, TYA, STA, TXS, SHS, SHY, STA, SHX, SHA, LDY, LDA, LDX, LAX, LDY, LDA, LDX, LAX, TAY, LDA, TAX, LXA, LDY, LDA, LDX, LAX, BCS, LDA, TRP, LAX, LDY, LDA, LDX, LAX, CLV, LDA, TSX, LAS, LDY, LDA, LDX, LAX, CPY, CMP, NOP, DCP, CPY, CMP, DEC, DCP, INY, CMP, DEX, SBX, CPY, CMP, DEC, DCP, BNE, CMP, TRP, DCP, NOP, CMP, DEC, DCP, CLD, CMP, NOP, DCP, NOP, CMP, DEC, DCP, CPX, SBC, NOP, ISB, CPX, SBC, INC, ISB, INX, SBC, NOP, SBC, CPX, SBC, INC, ISB, BEQ, SBC, TRP, ISB, NOP, SBC, INC, ISB, SED, SBC, NOP, ISB, NOP, SBC, INC, ISB, // 0x100, 0x101 LOAD_FILE, SLEEP }; public static final int[] READ_INS = { LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, CPX, CPY, BIT, LAX, LAS, NOP }; public static final int[] WRITE_INS = { STA, STX, STY, SAX, SHA, SHX, SHY, SHS }; public static final int[] RMW_INS = { ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP }; static { init(); } public static void init() { for (int i = 0, n = INSTRUCTION_SET.length; i < n; i++) { int mode = i & 0x1f; int pos = i >> 5; int instruction = INSTRUCTION_SET[i]; if (i < 256) { INSTRUCTION_SET[i] |= getAdrMode(pos, mode); INSTRUCTION_SET[i] |= getOpMode(instruction); } } } public static int lookup(String instr) { instr = instr.toUpperCase(); for (int i = 0, n = INS_STR.length; i < n; i++) { if (INS_STR[i].equals(instr)) return i; } return -1; } public static int lookup(int instr, int adrMode) { for (int i = 0, n = INSTRUCTION_SET.length; i < n; i++) { int op = INSTRUCTION_SET[i]; int adr = (op & ADDRESSING_MASK); op = op & OP_MASK; if (op == instr && adr == adrMode) return i; } return -1; } public static String modeString(int mode) { switch(mode) { case IMMEDIATE: return "immediate"; case ZERO: return "zero"; case ABSOLUTE: return "absolute"; case ZERO_X: return "zero,x"; case ZERO_Y: return "zero,y"; case ABSOLUTE_X: return "absolute,x"; case ABSOLUTE_Y: return "absolute,y"; case RELATIVE: return "relative"; case INDIRECT_X: return "indirect,x"; case INDIRECT_Y: return "indirect,y"; case ACCUMULATOR: return "accumulator"; case INDIRECT: return "indirect"; case 0: return "implied"; default: return ""; } } public static String toString(int instr) { int op = INSTRUCTION_SET[instr]; int adr = (op & ADDRESSING_MASK) >> 8; op = op & OP_MASK; return INS_STR[op] + ADR_STR_PRE[adr] + ADR_STR_POST[adr]; } public static String toString(int instr, boolean rmw) { int i = INSTRUCTION_SET[instr]; int adr = (i & ADDRESSING_MASK) >> 8; int op = i & OP_MASK; if (!rmw) return INS_STR[op] + ADR_STR_PRE[adr] + ADR_STR_POST[adr]; String s = INS_STR[op] + ADR_STR_PRE[adr] + ADR_STR_POST[adr]; int mode = i & MODE_MASK; if (mode == READ) return s + " read"; if (mode == WRITE) return s + " write"; if (mode == RMW) return s + " rmw"; return s; } private static int getAdrMode(int pos, int m) { switch(m) { case 0: case 2: if (pos > 4) return IMMEDIATE; return 0; case 1: case 3: return INDIRECT_X; case 4: case 5: case 6: case 7: return ZERO; case 9: case 0xb: return IMMEDIATE; case 0xa: if (pos < 4) return ACCUMULATOR; return 0; case 0xc: case 0xd: case 0xe: case 0xf: if (m == 0x0c && pos == 3) return INDIRECT;// Only instruction for this return ABSOLUTE; case 0x10: return RELATIVE; case 0x11: case 0x13: return INDIRECT_Y; case 0x14: case 0x15: return ZERO_X; case 0x16: case 0x17: if (pos == 4 || pos == 5) return ZERO_Y; return ZERO_X; case 0x19: case 0x1b: return ABSOLUTE_Y; case 0x1c: case 0x1d: return ABSOLUTE_X; case 0x1e: case 0x1f: if (pos == 4 || pos == 5) return ABSOLUTE_Y; return ABSOLUTE_X; } return 0; } private static int getOpMode(int i) { for (int j = 0, m = READ_INS.length; j < m; j++) { if (READ_INS[j] == i) return READ; } for (int j = 0, m = WRITE_INS.length; j < m; j++) { if (WRITE_INS[j] == i) return WRITE; } for (int j = 0, m = RMW_INS.length; j < m; j++) { if (RMW_INS[j] == i) return RMW; } //System.out.println("OP: " + i + " not found..."); return 0; } public static void main(String[] args) { init(); for (int i = 0, n = 256 + 2; i < n; i++) { System.out.println(Hex.hex2(i) + " => " + toString(i, true) + " IS:" + Hex.hex2(INSTRUCTION_SET[i])); } int b = lookup(BEQ, RELATIVE); System.out.println("BEQ # => " + b); } }