コード例 #1
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void ConstantHandler(Match lineReg)
        {
            string     label = lineReg.Groups["label"].Value;
            string     value = lineReg.Groups["value"].Value;
            ExprResult res   = ResolveExpr(value);

            if (res.undefinedSymbs.Count == 0)
            {
                Symbol symb = new Symbol()
                {
                    Value = res.Result,
                    Type  = res.Type
                };
                AddSymbol(label, symb);
            }
            else
            {
                UnresolvedSymbol unResSymb = new UnresolvedSymbol();
                unResSymb.NbrUndefinedSymb = res.undefinedSymbs.Count;
                unResSymb.DependingList    = new List <string>();
                unResSymb.Expr             = value;
                unResSymb.ExprList         = new List <ushort>();

                foreach (string symb in res.undefinedSymbs)
                {
                    AddDependingSymb(symb, label);
                }

                AddUnsolvedSymbol(label, unResSymb);
            }
        }
コード例 #2
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void GenerateExprBytes(UnresolvedExpr expr, ExprResult exprRes)
        {
            byte[] bytes = null;
            switch (expr.Type)
            {
            case SymbolType.WORD:
                if (exprRes.Type == SymbolType.BYTE && !CPUDef.isAbsoluteAddr(expr.addrMode) && (expr.addrMode != CPUDef.AddrModes.IND))
                {
                    bytes = new byte[1] {
                        (byte)exprRes.Result
                    };
                }
                else
                {
                    if (expr.addrMode == CPUDef.AddrModes.REL)
                    {
                        int  delta = (ushort)exprRes.Result - (expr.Position + originAddr);
                        byte res;
                        if (delta > 127 || delta < -128)
                        {
                            AddError(Errors.REL_JUMP);
                        }
                        else
                        {
                            if (delta < 0)
                            {
                                res = (byte)(255 + delta);
                            }
                            else
                            {
                                res = (byte)(delta - 1);
                            }
                            bytes = new byte[1] {
                                res
                            };
                        }
                    }
                    else
                    {
                        bytes = GetWordBytes((ushort)exprRes.Result);
                    }
                }
                break;

            case SymbolType.BYTE:
                bytes = new byte[1] {
                    (byte)exprRes.Result
                };
                break;
            }
            if (bytes != null)
            {
                fileOutMemory.RemoveRange(expr.Position, bytes.Length);
                fileOutMemory.InsertRange(expr.Position, bytes);
            }
        }
コード例 #3
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void DataByteHandler(string bytesIn)
        {
            string[] bytes = bytesIn.Split(',');
            foreach (string db in bytes)
            {
                string data = db.Trim();
                if (CPUDef.isString(data)) // handle strings
                {
                    data = data.Substring(1, data.Length - 2);
                    foreach (char c in data)
                    {
                        fileOutMemory.Add(Convert.ToByte(c));
                        currentAddr++;
                    }
                }
                else
                {
                    ExprResult res = ResolveExpr(data);
                    if (res.undefinedSymbs.Count == 0)
                    {
                        fileOutMemory.Add((byte)res.Result);
                    }
                    else
                    {
                        fileOutMemory.Add(0);
                        ushort         position = (ushort)(currentAddr - originAddr);
                        UnresolvedExpr expr     = new UnresolvedExpr
                        {
                            Position         = position,
                            Type             = SymbolType.BYTE,
                            addrMode         = CPUDef.AddrModes.NO,
                            NbrUndefinedSymb = res.undefinedSymbs.Count,
                            Expr             = data
                        };

                        unsolvedExprList.Add(position, expr);

                        foreach (string symb in res.undefinedSymbs)
                        {
                            UnresolvedSymbol unResSymb = new UnresolvedSymbol();
                            unResSymb.DependingList = new List <string>();
                            unResSymb.ExprList      = new List <ushort>();
                            unResSymb.ExprList.Add(position);
                            AddUnsolvedSymbol(symb, unResSymb);
                        }
                    }

                    currentAddr++;
                }
            }
        }
コード例 #4
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void IfHandler(string value)
        {
            if (cAsm.inCondition)
            {
                AddError(Errors.NESTED_CONDITIONAL_ASSEMBLY);
                return;
            }
            ExprResult res = ResolveExpr(value.Trim(), CPUDef.AddrModes.NO, true);

            if (res.undefinedSymbs.Count > 0)
            {
                AddError(Errors.UNDEFINED_SYMBOL);
            }
            else
            {
                cAsm.inCondition = true;
                cAsm.val         = (bool)res.Result;
            }
        }
コード例 #5
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void MemResHandler(Match lineReg)
        {
            string     label = lineReg.Groups["label"].Value;
            string     value = lineReg.Groups["value"].Value;
            ExprResult res   = ResolveExpr(value);

            if (res.undefinedSymbs.Count == 0)
            {
                MemArea ma;
                Dictionary <string, Symbol> symbTable;
                if (localScope.isLocalScope)
                {
                    ma        = localScope.memArea;
                    symbTable = localScope.symbolTable;
                }
                else
                {
                    ma        = memArea;
                    symbTable = symbolTable;
                }
                Symbol variable = new Symbol()
                {
                    Type = ma.type, Value = ma.val
                };
                if (!symbTable.ContainsKey(label))
                {
                    AddSymbol(label, variable);
                    ma.val += res.Result;
                    ma.type = ma.val <= 255 ? SymbolType.BYTE : SymbolType.WORD;
                    MainConsole.WriteLine($"{label} {variable.Value.ToString("x")}");
                }
                else
                {
                    AddError(Errors.LABEL_EXISTS);
                }
            }
            else
            {
                AddError(Errors.UNDEFINED_SYMBOL);
            }
        }
コード例 #6
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void ResolveSymbolDepsAndExprs(UnresolvedSymbol unresSymb)
        {
            Dictionary <string, UnresolvedSymbol> unsolvedSymbs;

            if (localScope.isLocalScope)
            {
                unsolvedSymbs = localScope.unsolvedSymbols;
            }
            else
            {
                unsolvedSymbs = unsolvedSymbols;
            }
            // resolve depending symbols
            foreach (string dep in unresSymb.DependingList)
            {
                UnresolvedSymbol unresDep = unsolvedSymbs[dep];
                unresDep.NbrUndefinedSymb--;
                if (unresDep.NbrUndefinedSymb <= 0)
                {
                    ExprResult res = ResolveExpr(unresDep.Expr);
                    AddSymbol(dep, new Symbol()
                    {
                        Value = res.Result,
                        Type  = res.Type
                    });
                }
            }
            // resolve expressions
            foreach (ushort expr in unresSymb.ExprList)
            {
                UnresolvedExpr unresExp = unsolvedExprList[expr];
                unresExp.NbrUndefinedSymb--;
                if (unresExp.NbrUndefinedSymb <= 0)
                {
                    ExprResult res = ResolveExpr(unresExp.Expr, unresExp.addrMode);
                    GenerateExprBytes(unresExp, res);
                    unsolvedExprList.Remove(expr);
                }
            }
        }
コード例 #7
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void DataWordHandler(string wordsIn)
        {
            string[] words = wordsIn.Split(',');
            foreach (string dw in words)
            {
                string     data = dw.Trim();
                ExprResult res  = ResolveExpr(data);
                if (res.undefinedSymbs.Count == 0)
                {
                    fileOutMemory.AddRange(GetWordBytes((ushort)res.Result));
                }
                else
                {
                    fileOutMemory.AddRange(new byte[2] {
                        0, 0
                    });
                    ushort         position = (ushort)(currentAddr - originAddr);
                    UnresolvedExpr expr     = new UnresolvedExpr
                    {
                        Position         = position,
                        Type             = SymbolType.WORD,
                        addrMode         = CPUDef.AddrModes.NO,
                        NbrUndefinedSymb = res.undefinedSymbs.Count,
                        Expr             = data
                    };

                    unsolvedExprList.Add(position, expr);
                    foreach (string symb in res.undefinedSymbs)
                    {
                        UnresolvedSymbol unResSymb = new UnresolvedSymbol();
                        unResSymb.DependingList = new List <string>();
                        unResSymb.ExprList      = new List <ushort>();
                        unResSymb.ExprList.Add(position);
                        AddUnsolvedSymbol(symb, unResSymb);
                    }
                }
                currentAddr += 2;
            }
        }
コード例 #8
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        private static void MemAreaHandler(string value)
        {
            MemArea ma;

            if (!localScope.isLocalScope)
            {
                ma = memArea;
            }
            else
            {
                ma = localScope.memArea;
            }
            ExprResult res = ResolveExpr(value);

            if (res.undefinedSymbs.Count == 0)
            {
                ma.val  = res.Result;
                ma.type = res.Type;
            }
            else
            {
                AddError(Errors.UNDEFINED_SYMBOL);
            }
        }
コード例 #9
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        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()}");
            }
        }
コード例 #10
0
ファイル: Assembler.cs プロジェクト: CodewinBzn/WinASM65
        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);
        }