예제 #1
0
        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!");
            }
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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;
            }
        }