git @ Cat's Eye Technologies JaC64 / master com / dreamfabric / jac64 / MOS6510Ops.java
master

Tree @master (Download .tar.gz)

MOS6510Ops.java @masterraw · history · blame

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);

  }

}