The behavior of the += version of `add` is undefined if both registers are low registers. In this case, we need to patch the instruction to replace it with the more traditional 3 register version: a = a + b.
* When given 4 instructions, that's enough space to replace it with a load, a branch, and an address.
* If the 4 instructions are such that they don't have any external dependencies (they don't contain a branch or a load), they can be safely moved to a new address.
These two points together mean that we can arbitrarily (and safely) expand almost any function. This should be very useful for both users and prototyping.
* script repointing should during ?????? pointer resolution: make sure that the pointer resolves to a different address than the script repoints to. This happened because we were looking for freespace for the new pointer and the moved script at the same time.
* when auto-repointing a script, clear the old pointer format and update their anchors with the new destination. This is not happening automatically because scripts don't hold all their length like other runs do, so repointing them left their pointers behind.
When adding a thumb routine, we want to clear out any pointers within the data and write new pointer runs for the new pointers. But we want to keep any anchors that point to the start of the routine.
Replace the existing method with a pair of methods.
One method requires a token, so that it can make metadata changes.
The other returns a set of runs along with its set of compiled bytes, so that pointers can be adjusted.
Unmapped Constants are much like Unmapped Pointers: they're tracked by the Model, the metadata, and undo, but they don't have a spot in the file. This allows us to create constants using the existing syntax `@constant=value` which can then be referenced in thumb code using `.word`s.
* New test to show that we can save unmapped constants from the ViewModel to Metadata
* New test to show that we can load unmapped constants from Metadata to the Model
* New test to show that we can undo the adding of unmapped constants
* New test to show that unmapped constants can be used in thumb words
* ldr can only have positive offsets, no sign.
* During code search, don't follow conditional branch instructions if they're not preceded by a condition. This prevents going on wild chases of data that _looks_ like an instruction, but is actually pointer data. This matters for things like switch statements.
* Improve documentation for thumb registers.
Since we're looking for where the field of table is used, go ahead and put the code in ArrayRun. Then we only have to pass in an object that knows how to parse thumb code and the index of the field to find usages of.
Have each step just do a single search and return all results. This makes all the loops in one place, while all the searching is clearly separated.
Use a `FindAllCommands` method to handle watching for `mov` instructions and branch instructions, as well as watching for an instruction that uses the specified register and matches a predicate. This makes the algorithm more flexible and a bit easier to read, because it makes the top-level method fairly straightforward.
* ViewPort needs to be able to understand thumb directives. This means that .whatever must be interpreted as a directive and not as a constant. So constant names are required to *contain* at least one dot. For example, `.some.number`.
* When reading data that's been pasted in, if you find a `.thumb` directive, read until you find a `.end` directive, then interpret that whole thing as a thumb script, all at once.
* allow the `.end` directive to appear in thumb code
* `.align` directives should work in the viewport. Other directives that appear towards the top of thumb scripts before the `thumb` directive should be ignored.
* `ldr rn, #` requires an input to be a multiple of 4
* `ldrh rn, #` requires an input to be a multiple of 2
* `ldrb rn, #` requires an input to be a multiple of 1
* `add sp, #` and `sub sp, #` require the input to be a multiple of 4
* `add rd, sp, #` and `add rd, pc, #` require the input to be a multiple of 4
* Adding in the source / bin files for testing
* Added the "skip instruction" to handle macros that need have no meaning
* Added a "PatchInstruction" method to do some instruction conversions: add negative to subtract positive, etc
* Fixed a bug that prevented me from opening .bin files.
* Allow labels to be at the start of a line that has more stuff on it
* Allow words to start with the 0x hexadecimal prefix
* Allow pointer words to display the anchor during decompile
* Allow inline words to have a +1 modifier
example: ldr r0, =255
The instuction gets queued to be written later, and space is left for it in the form of a `nop`.
Then the next time we hit the end of a section (b, bx, or pop pc), we write the word and we go back and write the instruction, now that we know the location of the word.
Previously, the creating a new ViewPort loaded from 2 text files and creating a new HardcodeTablesMoel loaded from 1 text file. This is a lot of parsing!
Refactor to do the parsing once, in the EditorViewModel, using a Singleton class to hold the non-editable loaded data. Inject that data into the appropriate structers later on.
To prevent massive refactoring in the tests, not every ViewPort needs to be given a Singletons instance. Instead, allow a ViewPort to still do its own parsing. However, BaseViewModelTestClass has been updated to make this work for a majority of tests, along with changes to AutoSearchTests's fixture and several of the Setup methods that are used by multiple tests.
This is currently not a user-exposed feature, but it was very helpful while researching how to make the proper changes for move-expansion.
It shouldn't be exposed (CodeTool.IsReadOnly=false) until I figure out how to handle edge cases and compile error reporting better.
The code didn't quite do what I meant for it to do. Fixed the broken offsets, fixed the broken code, and made the operation use the undo system.
The code still doesn't have the effect I expected, but at least it's now making the changes I expected.
There's a bug in tutor expansion: if you try to use tutor 16 (0x10) in a script, it no longer asks what pokemon you want but just tries to teach it to the first. This is incorrect.
While looking into this, go ahead and update the tutor code to be easier to work with in the future.
decompiled thumb code for "mov r7, r8" was showing up as "mov r15, r0" because I was getting the high bit wrong. Added a test that showed how it should be, and fixed it. But writing the reverse test for the compiler found a similar bug in the compiler. That's also fixed.
There's likely still some bugs. But the code compiles, and the code it generates doesn't crash when generating. Code likely still does not generate correctly, let alone have the desired effect.
not only do I need the thumb compiler to work with basic commands: I also need it to work with branch commands that refer to a label, either elsewhere in the function or recalled by the model.
almost all thumb instructions are 2 bytes wide. But bl is 4 bytes wide. The first two bytes include the high half of where to jump, and the next two bytes contain the low half of where to jump. But when loading all 4 bytes at once, this gets reversed. bl allows you to jump to functions 22-bits away. (x*2+4 from current address, where x is a 22 bit signed int).
* push lists are the opposite order from pop lists
* if there's a 'push lr' command, that's an interesting address
* bl and blx commands have interesting stuff after them, so don't count those as range-enders
* show code even if the selection is backwards (end-to-start)