public Move(int lnum, uint tabs, char size, string ins, ArgumentPart[] parts) : base(lnum, tabs, parts) { this.size = size; this.ins = ins; if (!checkArgNums()) { return; } if (ins.EndsWith("a") && ArgEnum.get(parts[0]).Type != typeof(ArgAddressDirect) && ArgEnum.get(parts[1]).Type != typeof(ArgAddressDirect)) { Window.ShowParseError(lnum, "Either argument must be an address register direct!\nParsing will now terminate.", "Error!"); } if ((ArgEnum.get(parts[1]).Type == typeof(ArgAddressDirect) || ArgEnum.get(parts[0]).Type == typeof(ArgAddressDirect)) && (size == 'b' || size == '1')) { Window.ShowParseError(lnum, "Instruction size needs to be word or long when either argument is address register direct!\n" + "Parsing will now terminate.", "Error!"); } if (ArgEnum.get(parts[1]).Type == typeof(ArgImmediateValue)) { Window.ShowParseError(lnum, "Argument 2 can not be immediate value!\nParsing will now terminate.", "Error!"); } if (ArgEnum.get(parts[1]).Type == typeof(ArgPCRelativeWithIndex) || ArgEnum.get(parts[1]).Type == typeof(ArgPCRelativeWithOffset)) { Window.ShowParseError(lnum, "Argument 2 can not be PC relative!\nParsing will now terminate.", "Error!"); } try { int off = getOff(parts[1]) + (getOff(parts[0]) * 9); if (size == 'l' || size == '4') { cycles = cycleL[off]; write = readWriteL[off] & 0xF; read = (readWriteL[off] >> 4) & 0xF; } else { cycles = cycleBW[off]; write = readWriteBW[off] & 0xF; read = (readWriteBW[off] >> 4) & 0xF; } } catch (Exception) { Window.ShowParseError(lnum, "Illegal argument pair '" + ArgEnum.get(parts[0]).Type + "', '" + ArgEnum.get(parts[1]).Type + "'!", "Error!"); } }
public Jump(int lnum, uint tabs, string ins, ArgumentPart[] parts) : base(lnum, tabs, parts) { this.ins = ins; if (!checkArgNums()) { return; } int add = ins.Equals("jmp") ? 0 : 8, wa = ins.Equals("jmp") ? 0 : 2; switch (ArgEnum.get(parts[0]).Index) { case 2: cycles = 8 + add; read = 2; write = wa; break; case 5: case 7: case 10: cycles = 10 + add; read = 2; write = wa; break; case 9: case 16: cycles = 12 + add; read = 2; write = wa; break; case 6: case 8: cycles = 14 + add; read = 3; write = wa; break; default: Window.ShowParseError(lnum, "Illegal argument '" + parts[0] + "'!\nParsing will now terminate.", "Error!"); return; } }
private int getOff(ArgumentPart a) { switch (ArgEnum.get(a).Index) { case 7: case 8: return(ArgEnum.get(a).Index + 2); case 10: // xxx.w return(7); case 9: // xxx.l return(8); default: return(ArgEnum.get(a).Index); } }
private static Instruction getInstruction(string line, int lnum) { List <string> parts = new List <string>(); int x = 0, i; uint tabs = 0; bool haslable = false, hasRightParen = false; for (i = 0; i < line.Length && parse; i++) { char c = line.ElementAt(i); if (c == ';') { // this means its a comment if (parts.Count == 0) { return(new Comment(lnum, line)); } // if the last part is not split, split it if (i > x + 1) { parts.Add(line.Substring(x, i - x)); if (x == 0) { haslable = true; } } parts.Add(line.Substring(i - 1, line.Length - i + 1)); x = i = line.Length; } else if (!hasRightParen && (c == ' ' || c == '\t' || c == ',')) { // split a part if (i > x) { parts.Add(line.Substring(x, i - x)); if (x == 0) { haslable = true; } } if ((parts.Count == 0 || (haslable && parts.Count <= 1)) && c == '\t') { tabs++; } if (i <= x && c == ',') { ShowParseError(lnum, "Could not determine argument with length under 1!\nParsing will now terminate.", "Error!"); return(null); } x = i + 1; } else if (hasRightParen && c == ')') { hasRightParen = false; } else if (c == '(') { hasRightParen = true; } } // if the last part is not split, split it if (i > x && x + (i - x) <= line.Length) { parts.Add(line.Substring(x, i - x)); if (x == 0) { haslable = true; } } // if there are 0 parts, return a newline if (parts.Count == 0) { return(new NullInstruction(lnum)); } // if there is 1 part and a lable, return a lable if (haslable && parts.Count <= 1) { return(new Lable(lnum, parts[0])); } // else add lable to the list and then remove it from the parts list else if (haslable) { list.Add(new Lable(lnum, parts[0])); parts.RemoveAt(0); } string ins; char size = '\0'; // process the size and exact instruction if (parts[0].Contains('.')) { string xy = parts[0]; ins = parts[0].Substring(0, parts[0].IndexOf('.')); size = xy.Replace(ins, "").Replace(".", "").ElementAt(0); } else { ins = parts[0]; } // remove instruction parts.RemoveAt(0); switch (ins.ToLower()) { case "": ShowParseError(lnum, "Could not determine instruction with length 0!\nParsing will now terminate.", "Error!"); return(null); case "nop": return(new Nop(lnum, tabs, parseArgs(lnum, parts, size))); case "rts": case "rte": case "rtr": return(new Rtx(lnum, tabs, ins.ElementAt(2), parseArgs(lnum, parts, size))); case "illegal": return(new Illegal(lnum, tabs, parseArgs(lnum, parts, size))); case "reset": return(new Reset(lnum, tabs, parseArgs(lnum, parts, size))); case "trapv": return(new Trapv(lnum, tabs, parseArgs(lnum, parts, size))); case "trap": return(new Trap(lnum, tabs, parseArgs(lnum, parts, size))); case "stop": return(new Stop(lnum, tabs, parseArgs(lnum, parts, size))); case "unlk": return(new Unlink(lnum, tabs, parseArgs(lnum, parts, size))); case "link": return(new Link(lnum, tabs, parseArgs(lnum, parts, size))); case "swap": return(new Swap(lnum, tabs, parseArgs(lnum, parts, size))); case "ext": return(new Ext(lnum, tabs, size, parseArgs(lnum, parts, size))); case "jmp": case "jsr": return(new Jump(lnum, tabs, ins, parseArgs(lnum, parts, size))); case "clr": case "neg": case "not": case "negx": return(new Clr(lnum, tabs, size, ins, parseArgs(lnum, parts, size))); case "tas": return(new Tas(lnum, tabs, parseArgs(lnum, parts, size))); case "tst": return(new Tst(lnum, tabs, size, parseArgs(lnum, parts, size))); case "st": case "sf": case "svs": case "svc": case "scc": case "scs": case "smi": case "spl": case "seq": case "sne": case "sgt": case "sge": case "slt": case "sle": case "shs": case "shi": case "sls": case "slo": return(new Scc(lnum, tabs, ins, parseArgs(lnum, parts, size))); case "pea": return(new Pea(lnum, tabs, parseArgs(lnum, parts, size))); case "lea": return(new Lea(lnum, tabs, parseArgs(lnum, parts, size))); case "chk": return(new Chk(lnum, tabs, parseArgs(lnum, parts, size))); case "asr": case "asl": case "lsr": case "lsl": case "ror": case "rol": case "roxr": case "roxl": return(new BitShift(lnum, tabs, ins, size, parseArgs(lnum, parts, size))); case "btst": case "bclr": case "bchg": case "bset": return(new Bit(lnum, tabs, ins, parseArgs(lnum, parts, size))); case "exg": return(new Exg(lnum, tabs, parseArgs(lnum, parts, size))); case "subq": case "addq": return(new SAddq(lnum, tabs, size, ins, parseArgs(lnum, parts, size))); case "muls": case "mulu": case "divu": case "divs": return(new MulDiv(lnum, tabs, ins, size, parseArgs(lnum, parts, '\0'))); case "xor": case "eor": case "xori": case "eori": ArgumentPart[] p3 = parseArgs(lnum, parts, size); if (ArgEnum.get(p3[1]).Type == typeof(ArgCCR) || ArgEnum.get(p3[1]).Type == typeof(ArgSR)) { return(new AndOrEorCCRorSR(lnum, tabs, size, ins, p3)); } else { return(new Xor(lnum, tabs, size, ins, p3)); } case "cmp": case "cmpi": case "cmpa": return(new Cmp(lnum, tabs, size, ins, parseArgs(lnum, parts, size))); case "add": case "addi": case "adda": case "sub": case "subi": case "suba": return(new AddSub(lnum, tabs, size, ins, parseArgs(lnum, parts, size))); case "and": case "andi": case "or": case "ori": ArgumentPart[] p1 = parseArgs(lnum, parts, size); if (ArgEnum.get(p1[1]).Type == typeof(ArgCCR) || ArgEnum.get(p1[1]).Type == typeof(ArgSR)) { return(new AndOrEorCCRorSR(lnum, tabs, size, ins, p1)); } else { return(new AndOr(lnum, tabs, size, ins, p1)); } case "move": case "movea": ArgumentPart[] p2 = parseArgs(lnum, parts, size); if (p2.Length == 2 && !ins.EndsWith("a") && (ArgEnum.get(p2[1]).Type == typeof(ArgCCR) || ArgEnum.get(p2[1]).Type == typeof(ArgSR) || ArgEnum.get(p2[1]).Type == typeof(ArgUSP) || ArgEnum.get(p2[0]).Type == typeof(ArgSR) || ArgEnum.get(p2[0]).Type == typeof(ArgUSP))) { return(new MoveToCCRSRUSP(lnum, tabs, size, p2)); } else { return(new Move(lnum, tabs, size, ins, p2)); } case "moveq": return(new Moveq(lnum, tabs, parseArgs(lnum, parts, size))); case "movep": return(new MoveP(lnum, tabs, size, parseArgs(lnum, parts, size))); case "movem": return(new Movem(lnum, tabs, size, parseArgs(lnum, parts, size))); case "abcd": case "sbcd": return(new ASbcd(lnum, tabs, ins, parseArgs(lnum, parts, size))); case "subx": case "addx": return(new ASddx(lnum, tabs, ins, size, parseArgs(lnum, parts, size))); case "nbcd": return(new Nbcd(lnum, tabs, parseArgs(lnum, parts, size))); case "cmpm": return(new Cmpm(lnum, tabs, size, parseArgs(lnum, parts, size))); case "bra": case "bvs": case "bvc": case "bcc": case "bcs": case "bmi": case "bpl": case "beq": case "bne": case "bsr": case "bgt": case "bge": case "blt": case "ble": case "bhs": case "bhi": case "bls": case "blo": return(new Bcc(lnum, tabs, ins, size, parseArgs(lnum, parts, size))); case "dbt": case "dbf": case "dbra": case "dbvs": case "dbvc": case "dbcc": case "dbcs": case "dbmi": case "dbpl": case "dbeq": case "dbne": case "dbgt": case "dbge": case "dblt": case "dble": case "dbhs": case "dbhi": case "dbls": case "dblo": return(new Dbcc(lnum, tabs, ins, parseArgs(lnum, parts, size))); case "dc": case "dcb": return(new Data(lnum, tabs, ins, size, parseArgs(lnum, parts, size))); default: ShowParseError(lnum, "Could not recognize instruction '" + ins + "'!\nParsing will now terminate.", "Error!"); return(null); } }
public Movem(int lnum, uint tabs, char size, ArgumentPart[] parts) : base(lnum, tabs, parts) { this.lnum = lnum; this.tabs = tabs; this.size = size; if (!checkArgNums()) { return; } if (size != 'w' && size != 'l' && size != '2' && size != '4') { Window.ShowParseError(lnum, "Intruction size not supported '" + size + "'!\nParsing will now terminate.", "Error!"); return; } int[] a = { ArgEnum.get(parts[0]).Index, (int)ArgEnum.get(parts[1]).Index }; if (a[0] == ArgEnum.MOVEM.Index && a[1] != ArgEnum.MOVEM.Index) { // R -> M switch (a[1]) { case 2: case 4: cycles = 8 + parts[0].getCycles(); read = 2 + parts[0].getReadCycles(); write = parts[0].getWriteCycles(); break; case 5: case 10: cycles = 12 + parts[0].getCycles(); read = 3 + parts[0].getReadCycles(); write = parts[0].getWriteCycles(); break; case 6: cycles = 14 + parts[0].getCycles(); read = 3 + parts[0].getReadCycles(); write = parts[0].getWriteCycles(); break; case 9: cycles = 16 + parts[0].getCycles(); read = 4 + parts[0].getReadCycles(); write = parts[0].getWriteCycles(); break; default: Window.ShowParseError(lnum, "Illegal argument '" + parts[0] + "'!\nParsing will now terminate.", "Error!"); return; } } else if (a[1] == ArgEnum.MOVEM.Index) { // M -> R switch (a[0]) { case 2: case 3: cycles = 12 + parts[1].getCycles(); read = 3 + parts[1].getReadCycles(); write = parts[1].getWriteCycles(); break; case 5: case 7: case 10: cycles = 16 + parts[1].getCycles(); read = 4 + parts[1].getReadCycles(); write = parts[1].getWriteCycles(); break; case 6: case 8: cycles = 18 + parts[1].getCycles(); read = 3 + parts[1].getReadCycles(); write = parts[1].getWriteCycles(); break; case 9: cycles = 20 + parts[1].getCycles(); read = 5 + parts[1].getReadCycles(); write = parts[1].getWriteCycles(); break; default: Window.ShowParseError(lnum, "Illegal argument '" + parts[1] + "'!\nParsing will now terminate.", "Error!"); return; } } else { Window.ShowParseError(lnum, "MOVEM should have exactly one of its arguments be register collection!\nParsing will now terminate.", "Error!"); return; } }