Exemple #1
0
        private static void InstructionHandler(Match lineReg)
        {
            string opcode   = lineReg.Groups["opcode"].Value;
            string operands = lineReg.Groups["operands"].Value;

            if (macros.ContainsKey(opcode))
            {
                Match macroReg = Regex.Match($"{opcode} {operands}", CPUDef.macroReg);
                CallMacroHandler(macroReg);
                return;
            }
            string label = lineReg.Groups["label"].Value;

            ushort opcodeAddr = currentAddr;

            opcode = lineReg.Groups["opcode"].Value.ToUpper();
            if (!string.IsNullOrWhiteSpace(label))
            {
                Symbol lSymb = new Symbol {
                    Type = SymbolType.WORD, Value = currentAddr
                };
                AddSymbol(label, lSymb);
            }

            Byte[]           addrModesValues = CPUDef.OPC_TABLE[opcode];
            CPUDef.AddrModes addrMode        = CPUDef.AddrModes.NO;
            List <byte>      instBytes       = new List <byte>();

            CPUDef.InstructionInfo instInfo = new CPUDef.InstructionInfo();
            bool syntaxError = true;

            if (string.IsNullOrWhiteSpace(operands))
            {
                syntaxError = false;
                // 1 byte opcode
                if (Array.Exists(CPUDef.ACC_OPC, opc => opc.Equals(opcode)))
                {
                    addrMode = CPUDef.AddrModes.ACC;
                }
                else
                {
                    addrMode = CPUDef.AddrModes.IMP;
                }
                instInfo = new CPUDef.InstructionInfo {
                    addrMode = addrMode, nbrBytes = 1
                };
                instBytes.Add(addrModesValues[(int)addrMode]);
            }
            else
            {
                string expr = string.Empty;
                // 2 bytes opcode
                if (Array.Exists(CPUDef.REL_OPC, opc => opc.Equals(opcode)))
                {
                    syntaxError = false;
                    expr        = operands;
                    instInfo    = new CPUDef.InstructionInfo {
                        addrMode = CPUDef.AddrModes.REL, nbrBytes = 2
                    };
                }
                else
                {
                    instInfo    = CPUDef.GetInstructionInfo(operands);
                    syntaxError = false;
                    expr        = instInfo.expr;
                }
                if (syntaxError)
                {
                    AddError(Errors.OPERANDS);
                }
                else
                {
                    addrMode = instInfo.addrMode;
                    ExprResult exprRes = ResolveExpr(expr, addrMode);
                    if (exprRes.undefinedSymbs.Count == 0)
                    {
                        // convert to zero page if symbol is a single byte
                        if (CPUDef.isAbsoluteAddr(addrMode) && exprRes.Type == SymbolType.BYTE)
                        {
                            addrMode          = addrMode + 3;
                            instInfo.nbrBytes = 2;
                        }
                        instBytes.Add(addrModesValues[(int)addrMode]);
                        if (instInfo.nbrBytes == 2)
                        {
                            instBytes.Add((byte)exprRes.Result);
                        }
                        else
                        {
                            instBytes.AddRange(GetWordBytes((ushort)exprRes.Result));
                        }
                    }
                    else
                    {
                        instBytes.Add(addrModesValues[(int)addrMode]);
                        SymbolType typeExpr;
                        if (instInfo.nbrBytes == 2)
                        {
                            instBytes.AddRange(new byte[1] {
                                0
                            });
                            typeExpr = SymbolType.BYTE;
                        }
                        else // 3 bytes instr
                        {
                            instBytes.AddRange(new byte[2] {
                                0, 0
                            });
                            typeExpr = SymbolType.WORD;
                        }

                        ushort         position = (ushort)(opcodeAddr - originAddr + 1);
                        UnresolvedExpr exprObj  = new UnresolvedExpr
                        {
                            Position         = position,
                            Type             = typeExpr,
                            addrMode         = addrMode,
                            NbrUndefinedSymb = exprRes.undefinedSymbs.Count,
                            Expr             = expr
                        };
                        unsolvedExprList.Add(position, exprObj);

                        foreach (string symb in exprRes.undefinedSymbs)
                        {
                            UnresolvedSymbol unResSymb = new UnresolvedSymbol();
                            unResSymb.DependingList = new List <string>();
                            unResSymb.ExprList      = new List <ushort>();
                            unResSymb.ExprList.Add(position);
                            AddUnsolvedSymbol(symb, unResSymb);
                        }
                    }
                }
            }
            if (!syntaxError)
            {
                currentAddr += instInfo.nbrBytes;
                fileOutMemory.AddRange(instBytes.ToArray());
                MainConsole.WriteLine($"{opcode} mode {addrMode.ToString()}");
            }
        }
Exemple #2
0
        private static ExprResult ResolveExpr(string exprIn, CPUDef.AddrModes addrMode = CPUDef.AddrModes.NO, bool isLogical = false)
        {
            List <Token> tokens = Tokenizer.Tokenize(exprIn);
            string       expr   = string.Empty;
            Symbol       symb;
            ExprResult   exprRes = new ExprResult();

            exprRes.undefinedSymbs = new List <string>();
            foreach (Token token in tokens)
            {
                switch (token.Type)
                {
                case "HB":
                    expr = $"{expr} {Byte.Parse(token.Value, NumberStyles.HexNumber)}";
                    break;

                case "HW":
                    expr = $"{expr} {ushort.Parse(token.Value, NumberStyles.HexNumber)}";
                    break;

                case "binByte":
                    expr = $"{expr} {Convert.ToByte(token.Value, 2)}";
                    break;

                case "DEC":
                    int val = int.Parse(token.Value);
                    if (val <= 255)
                    {
                        expr = $"{expr} {(byte)val}";
                    }
                    else
                    {
                        expr = $"{expr} {(ushort)val}";
                    }
                    break;

                case "label":
                    symb = GetSymbolValue(token.Value);
                    if (symb != null)
                    {
                        expr = $"{expr} {symb.Value}";
                    }
                    else
                    {
                        exprRes.undefinedSymbs.Add(token.Value);
                    }
                    break;

                case "loLabel":
                    symb = GetSymbolValue(token.Value);
                    if (symb != null)
                    {
                        expr = $"{expr} {GetLowByte((ushort)symb.Value)}";
                    }
                    else
                    {
                        exprRes.undefinedSymbs.Add(token.Value);
                    }
                    break;

                case "hiLabel":
                    symb = GetSymbolValue(token.Value);
                    if (symb != null)
                    {
                        expr = $"{expr} {GetHighByte((ushort)symb.Value)}";
                    }
                    else
                    {
                        exprRes.undefinedSymbs.Add(token.Value);
                    }
                    break;

                case "loHW":
                    expr = $"{expr} {GetLowByte(ushort.Parse(token.Value, NumberStyles.HexNumber))}";
                    break;

                case "hiHW":
                    expr = $"{expr} {GetHighByte(ushort.Parse(token.Value, NumberStyles.HexNumber))}";
                    break;

                default:
                    expr = $"{expr} {token.Value}";
                    break;
                }
            }
            if (exprRes.undefinedSymbs.Count == 0)
            {
                if (isLogical)
                {
                    exprRes.Result = EvaluateLogicalExpression(expr);
                }
                else
                {
                    DataTable dt = new DataTable();
                    exprRes.Result = dt.Compute(expr, "");
                    exprRes.Type   = exprRes.Result <= 255 ? SymbolType.BYTE : SymbolType.WORD;
                    if (addrMode == CPUDef.AddrModes.REL && exprRes.Type == SymbolType.WORD)
                    {
                        int  delta = (ushort)exprRes.Result - (currentAddr + 1);
                        byte res;
                        if (delta > 127 || delta < -128)
                        {
                            AddError(Errors.REL_JUMP);
                        }
                        else
                        {
                            if (delta < 0)
                            {
                                res = (byte)(255 + delta);
                            }
                            else
                            {
                                res = (byte)(delta - 1);
                            }
                            exprRes.Result = res;
                            exprRes.Type   = SymbolType.BYTE;
                        }
                    }
                }
            }
            return(exprRes);
        }