diff --git a/src/HexManiac.Core/Models/Code/ThumbParser.cs b/src/HexManiac.Core/Models/Code/ThumbParser.cs index ab307328..f2cb06e1 100644 --- a/src/HexManiac.Core/Models/Code/ThumbParser.cs +++ b/src/HexManiac.Core/Models/Code/ThumbParser.cs @@ -420,6 +420,10 @@ namespace HavenSoft.HexManiac.Core.Models.Code { } else if (part.Type == InstructionArgType.Numeric) { if (part.Code != 0) { instruction = CalculatePcRelativeAddress(instruction, pcAddress, part, bits); + } else if (instruction.Contains("#=#*")) { + var multiplierIndex = instruction.IndexOf("#=#*") + 4; + var multiplier = instruction[multiplierIndex] - '0'; + instruction = instruction.Replace("#=#*" + instruction[multiplierIndex], $"#{bits * multiplier}"); } else { instruction = instruction.Replace("#", $"#{bits}"); } @@ -584,6 +588,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code { // read a register if (template[0] == 'r') { + if (line.StartsWith("sp")) line = "r13" + line.Substring(2); if (line.StartsWith("lr")) line = "r14" + line.Substring(2); if (line.StartsWith("pc")) line = "r15" + line.Substring(2); if (line[0] != 'r') return false; @@ -627,6 +632,11 @@ namespace HavenSoft.HexManiac.Core.Models.Code { } template = template.Substring(1); line = line.Substring(numberAsText.Length + 1); + if (template.StartsWith("=#*")) { + var multiplier = template[3] - '0'; + template = template.Substring(4); + numeric /= multiplier; + } continue; } diff --git a/src/HexManiac.Core/Models/Code/armReference.txt b/src/HexManiac.Core/Models/Code/armReference.txt index f90e2f2b..bdb4438c 100644 --- a/src/HexManiac.Core/Models/Code/armReference.txt +++ b/src/HexManiac.Core/Models/Code/armReference.txt @@ -70,16 +70,16 @@ nv=1111 @ never 01100 # rn rd | str rd, [rn, #] 01101 # rn rd | ldr rd, [rn, #] 0110100000 rn rd | ldr rd, [rn] -01110 # rn rd | strb rd, [rn, #] @ #=#*4] -01111 # rn rd | ldrb rd, [rn, #] @ #=#*4] -10000 # rn rd | strh rd, [rn, #] @ #=#*4] -10001 # rn rd | ldrh rd, [rn, #] @ #=#*4] -10010 rd # | str rd, [sp, #] @ #=#*4] -10011 rd # | ldr rd, [sp, #] @ #=#*4] -10100 rd # | add rd, pc, # @ =#*4 @ rd = pc + #*4 -10101 rd # | add rd, sp, # @ =#*4 @ rd = sp + #*4 -101100000 # | add sp, # @ =#*4 @ sp += #*4 -101100001 # | sub sp, # @ =#*4 @ sp -= #*4 +01110 # rn rd | strb rd, [rn, #] +01111 # rn rd | ldrb rd, [rn, #] +10000 # rn rd | strh rd, [rn, #=#*2] +10001 # rn rd | ldrh rd, [rn, #=#*2] +10010 rd # | str rd, [sp, #=#*4] +10011 rd # | ldr rd, [sp, #=#*4] +10100 rd # | add rd, pc, #=#*4 @ rd = pc + #*4 +10101 rd # | add rd, sp, #=#*4 @ rd = sp + #*4 +101100000 # | add sp, #=#*4 @ sp += #*4 +101100001 # | sub sp, #=#*4 @ sp -= #*4 10110100 list | push {list} 10110101 list | push lr, {list} @ note: 'tsil' is a reverse 'list'. The bits are stored in the opposite order. 10111100 list | pop {list} diff --git a/src/HexManiac.Tests/Before_Baseclass/ScriptTests.cs b/src/HexManiac.Tests/Before_Baseclass/ScriptTests.cs index 1e95fc43..cfd69b60 100644 --- a/src/HexManiac.Tests/Before_Baseclass/ScriptTests.cs +++ b/src/HexManiac.Tests/Before_Baseclass/ScriptTests.cs @@ -86,7 +86,7 @@ namespace HavenSoft.HexManiac.Tests { Assert.Equal(5, parts.Length); } - // [Theory] + [Theory] [InlineData("Expand01_-_Move_Stats")] [InlineData("Expand02_-_Pokemon_Move_Learn_Table")] [InlineData("Expand03_-_Relearner_move_tutor")] diff --git a/src/HexManiac.Tests/Before_Baseclass/ToolTests.cs b/src/HexManiac.Tests/Before_Baseclass/ToolTests.cs index 43021075..b1541995 100644 --- a/src/HexManiac.Tests/Before_Baseclass/ToolTests.cs +++ b/src/HexManiac.Tests/Before_Baseclass/ToolTests.cs @@ -8,7 +8,6 @@ using HavenSoft.HexManiac.Core.ViewModels.Tools; using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Linq; using Xunit; @@ -399,7 +398,8 @@ namespace HavenSoft.HexManiac.Tests { [InlineData("bx lr", 0b010001110_1_110_000)] [InlineData("ldr r1, [r2]", 0b01101_00000_010_001)] [InlineData("lsl r1, r2, #0x4", 0b00000_00100_010_001)] - // [InlineData("sub sp, #4", 0b101100001_0000001)] + [InlineData("sub sp, #4", 0b101100001_0000001)] + [InlineData("mov r3, sp", 0x46_6B)] public void ThumbCompilerTests(string input, uint output) { var bytes = new List { (byte)output, (byte)(output >> 8) }; var model = new PokemonModel(new byte[0x200]); diff --git a/src/HexManiac.Tests/HexManiac.Tests.csproj b/src/HexManiac.Tests/HexManiac.Tests.csproj index e9d8bc01..6c74194c 100644 --- a/src/HexManiac.Tests/HexManiac.Tests.csproj +++ b/src/HexManiac.Tests/HexManiac.Tests.csproj @@ -112,13 +112,13 @@ - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always @@ -133,13 +133,13 @@ - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always diff --git a/src/HexManiac.Tests/test_compiled/Expand01_-_Move_Stats.bin b/src/HexManiac.Tests/test_compiled/Expand01_-_Move_Stats.bin index a3f54daa..5af2f845 100644 Binary files a/src/HexManiac.Tests/test_compiled/Expand01_-_Move_Stats.bin and b/src/HexManiac.Tests/test_compiled/Expand01_-_Move_Stats.bin differ diff --git a/src/HexManiac.Tests/test_compiled/Expand02_-_Pokemon_Move_Learn_Table.bin b/src/HexManiac.Tests/test_compiled/Expand02_-_Pokemon_Move_Learn_Table.bin index 32cde8d0..1c1c53ac 100644 Binary files a/src/HexManiac.Tests/test_compiled/Expand02_-_Pokemon_Move_Learn_Table.bin and b/src/HexManiac.Tests/test_compiled/Expand02_-_Pokemon_Move_Learn_Table.bin differ diff --git a/src/HexManiac.Tests/test_compiled/Expand03_-_Relearner_move_tutor.bin b/src/HexManiac.Tests/test_compiled/Expand03_-_Relearner_move_tutor.bin index 0374f28d..37d54213 100644 Binary files a/src/HexManiac.Tests/test_compiled/Expand03_-_Relearner_move_tutor.bin and b/src/HexManiac.Tests/test_compiled/Expand03_-_Relearner_move_tutor.bin differ