Example #1
0
        public static ErrorInfo RefactorMoveByteFieldInTable(ThumbParser parser, IDataModel model, ModelDelta token, string tableName, string fieldName, int newOffset)
        {
            // setup
            var table = model.GetTable(tableName) as ArrayRun;

            if (table == null)
            {
                return(new ErrorInfo($"Couldn't find table {tableName}."));
            }
            var segToMove = table.ElementContent.FirstOrDefault(seg => seg.Name == fieldName);

            if (segToMove == null)
            {
                return(new ErrorInfo($"Couldn't find field {fieldName} in {tableName}."));
            }
            if (segToMove.Length != 1)
            {
                return(new ErrorInfo($"{fieldName} must be a 1-byte field to refactor."));
            }
            if (newOffset >= table.ElementLength)
            {
                return(new ErrorInfo($"Trying to move {fieldName} to offset {newOffset}, but the table is only {table.ElementLength} bytes wide."));
            }
            var oldFieldIndex   = table.ElementContent.IndexOf(segToMove);
            var newFieldIndex   = 0;
            var remainingOffset = newOffset;

            while (remainingOffset > 0)
            {
                remainingOffset -= table.ElementContent[newFieldIndex].Length;
                newFieldIndex   += 1;
            }
            var segToReplace = table.ElementContent[newFieldIndex];

            if (segToReplace.Length != 1)
            {
                return(new ErrorInfo($"{segToReplace.Name} must be a 1-byte field to be replaced."));
            }
            int oldOffset = table.ElementContent.Until(seg => seg == segToMove).Sum(seg => seg.Length);

            // update table format
            var format = table.FormatString;

            format = format.ReplaceOne(segToMove.SerializeFormat, "#invalidtabletoken#");
            format = format.ReplaceOne(segToReplace.SerializeFormat, segToMove.SerializeFormat);
            format = format.ReplaceOne("#invalidtabletoken#", segToReplace.SerializeFormat);
            var error = ArrayRun.TryParse(model, format, table.Start, table.PointerSources, out var newTable);

            if (error.HasError)
            {
                return(new ErrorInfo($"Failed to create a table from new format {format}: {error.ErrorMessage}."));
            }

            // update code
            var ldrbWriter = new TupleSegment(default, 5);
Example #2
0
 public static IReadOnlyList <byte> Compile(this ThumbParser parser, IDataModel model, int start, params string[] lines)
 {
     // added for compatibility: tests are allowed to call the old version of the method.
     return(parser.Compile(model, start, out var _, lines));
 }
Example #3
0
 static ToolTests()
 {
     parser = new ThumbParser(File.ReadAllLines("Models/Code/armReference.txt"));
 }
Example #4
0
        public static async Task <ErrorInfo> ExpandMoveEffects(ThumbParser parser, IEditableViewPort viewPort, ModelDelta token, double targetLoadingPercent)
        {
            // make move effects 2 bytes instead of 1 byte
            var model      = viewPort.Model;
            var table      = model.GetTable(MoveDataTable);
            var fieldNames = table.ElementContent.Select(seg => seg.Name).ToArray();

            async Task <ErrorInfo> shiftField(int i)
            {
                var result = RefactorMoveByteFieldInTable(parser, model, token, MoveDataTable, fieldNames[i], i + 1);
                await viewPort.UpdateProgress((9 - i) / 9.0 *targetLoadingPercent);

                return(result);
            }

            // effect. power. type. accuracy. pp. effectAccuracy. target. priority. info. unused. unused:
            ErrorInfo error;

            error = await shiftField(8); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(7); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(6); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(5); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(4); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(3); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(2); if (error.HasError)
            {
                return(error);
            }
            error = await shiftField(1); if (error.HasError)
            {
                return(error);
            }
            error = RefactorByteToHalfWordInTable(parser, model, token, MoveDataTable, fieldNames[0]); if (error.HasError)
            {
                return(error);
            }
            await viewPort.UpdateProgress(targetLoadingPercent);

            // update offset pointers (because the PP field moved)
            foreach (OffsetPointerRun pointerRun in table.PointerSources
                     .Select(address => model.GetNextRun(address))
                     .Where(pointer => pointer is OffsetPointerRun)
                     )
            {
                model.ClearFormat(token, pointerRun.Start, 4);
                model.WritePointer(token, pointerRun.Start, table.Start + 5);
                model.ObserveRunWritten(token, new OffsetPointerRun(pointerRun.Start, 5));
            }

            return(ErrorInfo.NoError);
        }
 static ToolTests()
 {
     singletons = new Singletons();
     parser     = new ThumbParser(singletons);
 }