Initialising Wii filesystem contents should be done after Boot and
not in HW to ensure that we operate with the correct title context
and to make sure required title directories exist (so that Movie and
Netplay code can copy data from and to the temporary NAND).
Previously, given cases such as 0x80000000 / 0xFFFFFFFF we'd incorrectly
set the destination register value to zero. If the dividend is negative,
then the destination should be set to -1 (0xFFFFFFFF), however if the
dividend is positive, then the destination should be set to 0.
Note that the 750CL documents state that:
"If an attempt is made to perform either of the divisions --
0x80000000 / -1 or <anything> / 0, then the contents of rD are
undefined, as are the contents of the LT, GT, and EQ bits of the CR0
field (if Rc = 1). In this case, if OE = 1 then OV is set."
So this is a particular behavior of the hardware itself.
D3D11 cannot handle block compressed textures where the first mip level
is not a multiple of the block size. The simple fix for texture pack
authors: leave these textures uncompressed. You can still use a .dds
container.
Executing a supervisor-level instruction in user mode is supposed to
cause a program exception to occur.
The following supervisor instructions are present:
- dcbi
- mfmsr
- mfspr
- mfsr
- mfsrin
- mtmsr
- mtspr
- mtsr
- mtsrin
- rfi
- tlbie
- tlbsync
In 0337ca116a checks within mfspr and
mtspr were added. This change adds the trivial checks to the other
instructions.
Using 8-bit integer math here lead to precision loss for depth copies,
which broke various effects in games, e.g. lens flare in MK:DD.
It's unlikely the console implements this as a floating-point multiply
(fixed-point perhaps), but since we have the float round trip in our
EFB2RAM shaders anyway, it's not going to make things any worse. If we
do rewrite our shaders to use integer math completely, then it might be
worth switching this conversion back to integers.
However, the range of the values (format) should be known, or we should
expand all values out to 24-bits first.
Keeps signed values out of bit arithmetic (not that there's any issues
that could arise from it in these situations, but it does look more
consistent, and silences compiler warnings)
Also ensure that all members of the class are initialized on
construction as well. Previously the bool indicating if options are
dirty wouldn't be initialized, which could be read uninitialized if an
instance was constructed and then IsDirty() is called.
Keeps all of the interpreter-specific exception handling functions
together in a reusable way across translation units, similar to
FPUtils.h for reusable floating-point functions.
Given this is a base class, we should clearly state what the parameters
to the functions in its exposed interface actually mean or represent.
This avoids needing to hunt for the definition of the functions in cpp
files.
While we're at it, normalize said parameter names so they follow our
naming guidelines.
There's no reason to use int here as opposed to an unsigned value.
Video_AccessEFB() takes its arguments as u32 values, so we'd be doing
sign conversions for no reason here (along with causing avoidable
compiler warnings).
If a program executing in user mode tries to write to any SPRs other than
XER, LR, or CTR registers, then a program exception occurs. Similarly
this also applies for reading SPRs as well, however the upper and lower
timebase halves can also be read (but not written to).
If HID0.NOOPTI is set, then dcbt and dcbtst are no-oped globally. We
currently don't perform data cache emulation, but we put this in anyway
so this detail isn't forgotten about if data cache emulation is
introduced at some point in the future.
This implements ES_VerifySign which is notably used by the system menu
when importing saves.
Now *all* ES commands that are actually used by titles are implemented.
- Move all of the ec functions into the Common::ec namespace.
- Give the public functions better names and some usage information.
- Move all of the "elt" related functions into an "elt" class including
all of the arithmetic operations, so that the logic becomes clearer
and feels less like assembly.
This also makes it much more obvious what the parameters are, instead
of only using unsigned char* (which doesn't tell anything about what
the pointer is used for or the size).
- Similarly, add a new "Point" class and move point functions there.
Overload the arithmetic operators to make calculations easier to read
The loops relied on unsigned integer overflow, which is not immediately
obvious. Replace them with less clever variants that are clearer.
Also implement bn_compare using std::memcmp.
This function in both JITs is only ever called by passing the JIT's code
buffer into it. Given this is already accessible, since the functions
are part of the respective JIT class, we can just remove this parameter.
This also cleans up accesses with the new code buffer, as we don't need
to do janky looking dereference-then-index expressions.
This class effectively acted as a "discount vector", that would simply
allocate memory and then delete it in the destructor when it goes out of
scope.
We can just use a std::vector directly to reduce this boilerplate.
ImportTitleDone only checks if all required contents have been imported
for system titles.
This fixes the system menu not being able to recreate title directories
to copy a save back to the NAND by using title import functionality.
Given this is a bitmask, we should be using an unsigned type to store it
(especially given it's outside the range an int can represent properly
without being considered negative).
No behavior change is caused by this, it just silences a sign conversion
warning.
Because it wasn't parented properly, it would show briefly the widget in its own window when creating an ARCodeWidget or a GeckoCodeWidget which would occur when accessing the game properties page or when the state changes to pause/running.
PowerPC.h at this point is pretty much a general glob of stuff, and it's
unfortunate, since it means pulling in a lot of unrelated header
dependencies and a bunch of other things that don't need to be seen by
things that just want to read memory.
Breaking this out into its own header keeps all the MMU-related stuff
together and also limits the amount of header dependencies being
included (the primary motivation for this being the former reason).
This fixes 2 crashes with the pause function. One is when spamming the pause hotkey and the other is to press pause and step hotkeys at the same time. It does disable the screensaver getting disabled when the emulator is running, but paused, though, a better solution would have to be done without introducing these crashes.
Github didn't detect conflicts here, however, since the float handling
functions were moved into the Common namespace, this would cause a build
failure.
Ideally none of these macros would exist (long-term goal), however in
the meantime at least make sure expressions always evaluate correctly
(thankfully no current usages rely on this).
Given we're operating with flags and bit representations, lets avoid
signed values here. It lessens the amount of sign conversion warnings
and lessens the amount of things to think about screwing you over when
making changes to the interpreter among other things.
Hopefully this better matches the user's view of a texture - as large changes in
colour should be weighted higher than lots of very small changes
Note: This likely invalidates the current heuristic threshold default
These can be expressed in a slightly cleaner manner without so many
casts. While we're at it, also get rid of unnecessary indexing (we
already have the result nearby).
Extracts the self-contained code into its own function to clean up the
flow of Jit() a little more.
This also introduces a helper function to HLE.h that will be used to
reduce the boilerplate here and in the interpreter and Jit64 in the
following commits.
This function performs all of the preliminary checks required prior to
attempting to hook/replace a function at a given address. The function then
calls a provided object that satisfies the FunctionObject concept in the
C++ standard library. This can be a lambda, a regular function pointer,
an object with an overloaded function call operator, etc. The only
requirement is that the function return a bool, indicating whether or
not the function was replaced, and that it can take parameters in the
form: fn(u32 function, HLE::HookType type)
Gets rid of a second pair of ifdefs in the constructor. This also makes
sure the fd on Unix/BSD platforms is uniformly initialized. Previously
fd would be in an inconsistent state on FreeBSD or OpenBSD due to the
BSD OS checks not being present in the #elif within the constructor.
Previously, the entirety of CEXIETHERNET was exposed publically, which
wasn't necessary. We simply make the thread function part of the
internal interface, which gives it access to internal data members,
while keeping everything else outside of it.
Given these HLE classes inherit from a common base with a virtual
destructor, override is more appropriate here, as virtual propagates to
these destructors anyway.
This is also safer. If the base class' destructor is ever made
non-virtual, then these classes will cause a compilation error if they
aren't taken into account, as they'd be overriding a non-virtual
function (the destructor).
This is to avoid several issue with using 2 actions and switching between them. This commit will instead have one action get his property changed on pause and play.
Paired single (ps) instructions can call asm_routines that try to update
PowerPC::ppcState.pc. At the time the asm_routine is built, emulation has
not started and the PC is invalid (0). If the ps instruction causes an
exception (e.g. DSI), SRR0 gets clobbered with the invalid PC.
This change makes the relevant ps instructions store PC before calling out
to asm_routines, and prevents the asm_routine from trying to store PC
itself.
Moves the codebuffer access variables closer to their first use, and
gets rid of multiple indexing expressions. We already know which op
we're accessing in particular, so just make a reference to it and access
it instead of duplicating the expression all over the place.
A call like ReplaceAddress(address, 0) is pretty ambiguous; so is
ReplaceAddress(address, false), so use an enum class that tells people
straight-up what the replacer is.
This also gets rid of the really weird naming, where if 'blr' is true,
we'd be replacing the address with a NOP, rather than an actual BLR
instruction, so we invert that so it actually makes sense. There's no
actual bug fixed here though, considering the OnInsert functions
specified the correct values; it's literally just weird naming.
Without this macro, if any signals or slots were attempted to be used,
they wouldn't work; neither would various other features of the Qt
meta-object system. This can also lead to weird behavior in other
circumstances. Qt's documentation specifically states:
"Therefore, we strongly recommend that all subclasses of QObject use the
Q_OBJECT macro regardless of whether or not they actually use signals,
slots, and properties."
on its page for "The Meta-Object System", which can be seen here:
https://doc.qt.io/qt-5/metaobjects.html
Let's opt for "always do the right thing", and keep the code extensible
for the future and not have random things blow up on us.
Makes the enum strongly typed. A function for retrieving the string
representation of the enum is also added, which allows hiding the array
that contains all of the strings from view (i.e. we operate on the API,
not the exposed internals). This also allows us to bounds check any
querying for the strings.
Export and ExportAll now open a directory picker (that defaults to the
previous default directory, i.e. the Dolphin user dir).
Also removes the need to return the path in the export functions since
the user knows which path they chose.
This moves the result dialogs to DolphinQt2, since WiiSave should not
really be responsible for interacting with the user as a simple
Wii save importing/exporting class.
This also fixes Wii save import/export showing result dialogs twice,
once from WiiSave, and another time from DolphinQt2.
Move the import/export operation into separate functions, as it doesn't
really make sense for the constructor to do *everything*, including
printing success/failure message boxes.
The existing constructor was split into two: one that takes a path,
and another taking a title ID. This makes it more obvious what is
actually done when a path/TID is passed and also clarifies what
parameters should be passed. (No more magic 0 or "" value.)
It only needs to be updated when we changes the symbols, not every time the code widget updates and it does take a while to update them so this fixes some delay when updating the code window.
Putting the columns to resizeToContents causes way too much resizes per updates which can cause severe lags and even crashes. This only does one resize at the end of the columns.
One, which was also possible in Wx is to add an mbp after the core stopped which shouldn't be possible as it needs to add the memcheck on the core thread which wouldn't be running. The other fix is Qt specific where it doesn't clear the breakpoints on stop.
The items were editable while you cannot edit the breakpoints at the moment and the last breakpoint deleted would not cause the row count to change to 0.
This allows avoiding two copies of the executable data being created in
the following scenario (using pseudocode):
some_function()
{
std::vector<u8> data = ...;
DolReader reader{data};
...
}
In this scenario, if we only use the data for passing it to DolReader,
then we have to perform a copy, as the constructor takes the std::vector
as a constant reference -- you cannot move from a constant reference,
and so we copy data into the DolReader, and perform another copy in the
constructor itself when assigning the data to the m_bytes member
variable. However, we can do better.
Now, the following is allowable as well:
some_function()
{
std::vector<u8> data = ...;
DolReader reader{std::move(data)};
...
}
and now we perform no copy at any point in the reader's construction, as
we just std::move the data all the way through to m_bytes.
In the case where we *do* want to keep the executable data around after
constructing the reader, then we can just pass the vector without
std::move-ing it, and we only perform a copy once (as we'll std::move
said copy into m_bytes). Therefore, we get a more flexible interface
resource-wise out of it.
Not only it colors the entire row instead of just the address, but if the pc is the selected row, the pc color will overwrite the selection, this is done via a stylesheet.
This commit makes the colors hardcoded except when there is no symbols loaded, in which case, it uses the theme colors, except for the PC which is hardcoded to black on green. This makes a compromise between making use of the corespoinding theme color and the text being nicely readable on all themes.
This aligns the values to the right since It looks odd to be aligned to the left with any format other than hexadecimal. It also sets the font tot he debugger font and disallow selection as a previous commit made the selection pointless since it now relies on the current item.
It seemed impossible to SELECT an item, however, when right clicking, the CURRENT item is set to the appropriate cell, this commit makes the view use thta cell instead of the first selected one.
This makes it possible to use enums as the config type.
Default values are now clearer and there's no need for casts
when calling Config::Get/Set anymore.
In order to add support for enums, the common code was updated to
handle enums by using the underlying type when loading/saving settings.
A copy constructor is also provided for conversions from
`ConfigInfo<Enum>` to `ConfigInfo<underlying_type<Enum>>`
so that enum settings can still easily work with code that doesn't care
about the actual enum values (like Graphics{Choice,Radio} in DolphinQt2
which only treat the setting as an integer).
Dolphin doesn't use any of the WC24 files, so this can be done when
actually starting emulation in WiiRoot. The benefit of moving the
copy is that we don't need to handle temporary NANDs in a special way.
{Initialize,Shutdown}WiiRoot should only be responsible for setting the
SESSION_WII_ROOT or managing the temporary NAND directory.
Move all the content manipulation out of these functions to ensure
separation of concerns and call them after/before WiiRoot init/shutdown
to make sure they operate on the correct root.
If we don't flush the values, they persist in the register cache,
potentially resulting in the values being out of sync with PPCSTATE.
This was causing random crashes in games, mainly booting, when certain
JIT instructions were disabled, or forced to fall back to interpreter.
This excludes the second argument from template deduction.
Otherwise, it is required to manually cast the second argument to
the ConfigInfo type (because implicit conversions won't work).
e.g. to set the value for a ConfigInfo<std::string> from a string
literal, you'd need a ugly `std::string("yourstring")`.
This can be considered a hack, but it essentially neuter the bias applied on boot for both console on the RTC. This avoids having the time on boot be changes significantly while the user would want a specific RTC and it also avoids possible underflow of the RTC if it is near the epoch.
GetHandle() should really not even be part of IOFile's interface, but
since it is (for the time being), we can cull unnecessary usages of it.
In this case, the WriteBytes() function does what we need without using
the underlying handle directly.
This allows getting rid of casts. We can also leverage std::min to allow
making relevant variables const. Also make the "empty" table const to
allow it to be read-only.
Converts them from 0 == success, 1 == failure to using the built-in
standard bool. Also while we're at it, const qualify write_sector's
"sector" parameter, since nothing in the function modifies the data
being pointed to.
Avoids needing to iterate and append the characters in one case. This also
alters the function to not need to construct a temporary std::string
(QString's toUtf8() is sufficient, as QByteArray exposes iterators).
toStdString() is equivalent to retrieving the QString's underlying
QByteArray via calling QString's .toUtf8 member function and then
calling .toStdString() on the result of it (discarding the QByteArray
afterwords), so this just trims off an unnecessary step in the process.
This is also somewhat more indicative of the conversions going on:
toStdString() converts the underlying character sequence of a
QString to UTF-8, not strict ASCII, so we're really using a superset of
ASCII.
Also move it to MathUtils where it belongs with the rest of the
power-of-two functions. This gets rid of pollution of the current scope
of any translation unit with b<value> macros that aren't intended to be
used directly.
Change SettingsHandler to take a buffer instead of assuming that the
setting file to read is always on the host filesystem for more
flexibility and make it possible to use the new filesystem interface.
Given bit conversions between types are quite common in emulation
(particularly when it comes to floating-point among other things) it
makes sense to provide a utility function that keeps all the boilerplate
contained; especially considering it makes it harder to accidentally
misuse std::memcpy (such as accidentally transposing arguments, etc).
Another benefit of this function is that it doesn't require separating
declarations from assignments, allowing variables to be declared const.
This makes the scenario of of uninitialized variables being used less
likely to occur.
Keeps them all next to each other and deduplicates a few constants,
notably the PPC UIDs. Apparently I forgot that I already added them
for SetupStreamKey.
As of VS 15.7, these seem to have been removed. Given we shouldn't have
been using these for some time, just replace them with the standard
library equivalent.
This fixes building on Windows with VS 15.7
It was off by about 8 years because it was actually the same as the GC epoch, however, the reason it worked all this time was because the default RTC counter bias of the Wii was not 0, but a value that is about 8 years in seconds. This broke custom RTC as a custom RTC of the gc epoch was underflowing b ecause the wii epoch was thought to be much later.
The existing backend did not handle cases where the target exists
correctly.
This is a bug that has been around forever but was only recently
exposed when ES started to use our FS code.
Also adds some unit tests to make sure this won't get broken again.
Creating a file then opening it in read write mode is a pretty common
operation. This commit adds a helper function that makes it easier
to read and clearer.
Keeps all of the floating-point utility functions in their own file to
keep them all together. This also provides a place for other
general-purpose floating-point functions to be added in the future,
which will be necessary when improving the flag-setting within the
interpreter.
FPSCR.FEX is supposed to be a logical OR of all floating-point exception
bits masked by their respective enable bits.
Currently UpdateFPSCR() isn't called by anything in the interpreter
except for mcrfs and mffs, so this doesn't alter existing behavior that much.
However, this will be necessary in future PRs when making the interpreter more
accurate in how it sets flags.
Prevent implicit conversions to UReg_FPSCR. Given the semantics of a
random magic value and the FPSCR are different, make explicit
conversions a requirement to signify intent.
The MSR.LE bit is supposed to be set to the value of MSR.ILE upon
entering an exception vector to control whether the environment in said
vector operates as little endian or big endian. If this bit is ORed into
the LE bit, then the scenario of operating in little endian but wanting
to take exceptions in big endian will be incorrectly handled.
Analogous to File::CreateFullPath, but for the Wii filesystem so this
ensures that directories and files receive proper attributes.
(This function is technically not part of the FS sysmodule but it's in
an internal FS library that is reused in several IOS sysmodules.)
Prevents implicit construction of MSR instances from integral values.
This is beneficial, considering MSR values have an intended
representation while a regular magic value doesn't. So make these
conversions required to be explicit.
Gets rid of the need to construct UReg_MSR values around the the actual
member in order to query information from it (without using shifts and
masks). This makes it more concise in some areas, while helping with
readability in some other places (such as copying the ILE bit to the LE
bit in the exception checking functions).
The game Go Vacation (SGVEAF) currently stutters a lot because it keeps
overflowing the far code cache and all code needs to be re-jitted.
Logging this warning gives a useful hint as to what is causing the
stuttering.
Qt introduced a checkbox to toggle the debugger UI, this makes it work into a setting stored in the INI, it also makes the -d argument only in effect when enabled, in such case, it will override the INI by overriding it.
Since all FS access will go through the new FS interface (PR #6421)
in order to keep track of metadata properly, there is no need to return
absolute paths anymore.
In fact, returning host paths is a roadblock to using the FS interface.
This starts the migration work by adding a way to get paths that are
relative to the Wii NAND instead of always getting absolute paths
on the host FS.
To prepare for future changes, this commit also makes returned paths
canonical by removing the trailing slash when it's unneeded.
Eventually, once everything has been migrated to the new interface,
we can remove the "from" parameter.
Also makes y_scale a dynamic parameter for EFB copies, as it doesn't
make sense to keep it as part of the uid, otherwise we're generating
redundant shaders.
RE4's brightness screen is actually very good for spotting these.
Bug 1: Colors at the end of the scanlines are clamped, instead of a black
border
Bug 2: U and V color channels share coordinates, instead of being offset
by a pixel.
Use the newly added GetSystemDefaultInterfaceOrFallback() to return
actual information for the default interface, not just dummy
interface details.
This also fixes GetInterfaceOpt(0x4003) and gethostid() returning
inconsistent information. Prior to this change, GetInterfaceOpt(0x4003)
would return 10.0.1.30 and gethostid would give a totally unrelated IP.
These aren't dependent on calling order so we can just organize all of the statics together
instead of splitting them up over the file. This also allows us to organize a common spot for
file static variables as well.
This adds unit tests for the Wii filesystem now that the filesystem
interface is neatly separated from the IPC code.
Basic FS functionality is tested, in addition to problematic usages and
edge cases that Dolphin used to handle incorrectly (which of course
broke emulated software).
These tests should make it quite a bit harder to introduce regressions.
Issues that are covered by the tests in particular:
* Metadata: issue 10234 (though tests are commented out for now because
Dolphin doesn't support NAND images yet so it can't track metadata);
* EOF seeks/reads: https://github.com/dolphin-emu/dolphin/pull/4942
* Read/write operations from multiple handles: see issue 2917, 5232 and
8702 and https://github.com/dolphin-emu/dolphin/pull/2649
Xlib has really terrible headers that declare non-namespaced
macros and typedefs for common words.
Just wasted 10 minutes trying to figure out why a unit test failed
to build before I remembered it was Xrandr.h conflicting with our
enum class members again.
To fix the issue, this removes the Display* parameter from the
EnableScreensaver function (which was unused) so we don't have
to include Xrandr.h anymore.
Allows us to bring includes and relevant libraries into scope by explicitly declaring linkage against the target
as opposed to using a variable. Also removes the dumping of OProfile includes into the top-level directory.
Just re-disassembled STM and found out I have made a mistake when
I changed STM stuff back in 2016.
I accidentally made STM reset the event hook on close when it should
have been done in the destructor (i.e. when IOS gets reset on console).
Verified in IDA that STM just `IOS_ResourceReply(request, IOS_OK)`
without ever resetting the hook.
Some button names should be translated, for instance Up, Left and such.
At the same time, some other button names shouldn't be translated,
for reasons that might be less obvious. In 0146456af, I removed the
_trans markers for button names that never need to be translated
(such as A and B), but that isn't actually enough to ensure that
DolphinWX won't try to translate them anyway. This commit adds a bool
that explicitly tells the GUI whether a button name should be translated.
Otherwise we'll have problems like the GUI treating the button name "B"
(which isn't supposed to be translated) as matching the translatable
string "B" (being an abbreviation of "bytes"), meaning that the button
"B" will be labeled "o" when running Dolphin in French (after
translations get pulled from Transifex the next time).
By the way, while it turned out that DolphinWX translated all button
names, it also turned out that DolphinQt2 translated *no* button names.
Go figure. This commit makes them consistent with each other.
If FPSCR[VE] is set, a result isn't supposed to be written to the destination,
just the FPSCR[VXSNAN] bit gets set, and FPSCR[FR] and FPSCR[FI] get set to zero.
If FPSCR[VE] isn't set, then we do write out a result, however, the FPSCR[FPRF]
field is updated to signify a QNaN (yes, a QNaN, the FPRF field doesn't have
a bit configuration for SNaNs).
There's no real requirement to make this const, and this should also
be decided by the calling code, considering we had places that would
simply cast away the const and carry on.
It's not common code that could be reused for, say, Citra;
it's absolutely specific to Wii emulation and only used by the Dolphin
core, so let's move it there.
Another reason for doing this is to avoid having Common depend on Core.
It was discovered that some titles rely on filesystem metadata to work
properly. Currently, in master they either simply won't find their
save files (for example Bolt) or will complain about the Wii system
memory being corrupted (on first use or every time depending on
the title).
In order to even be able to keep track of file metadata, we first need
to eliminate all direct accesses to the NAND and make all kinds of
operations go through the filesystem code added in PR 6421.
This commit starts the migration process by making SysConf use
the new FS interface.
This used to be necessary for properly cleaning up the FS state because
the old FS implementation used static state and only performed cleanup
in the close function, not in the destructor.
Now that the static state is gone, we do not need to close devices
manually anymore.
After 3a83ebc, the Show System Clock feature started using the
unfortunate combination of MM/DD/YY dates (rare outside of the US)
and 24-hour time (rare in the US) regardless of the user's locale
settings. This commit makes it use the configured locale again.
I've noticed one minor difference in behavior between now and
before 3a83ebc: The new way of setting the C/C++ locale seems to
treat "en" as "en-US", but the wx way of setting the C locale
treated it as "en-GB" (at least on Windows).
Migrates the state to be instance-based as opposed to being a flat
namespace. This keeps behavior localized to its own instantiable unit
(and forces uses of the class to also be localized, lest they cart around
an instance all over the place).
This was necessary to work around a FS timing issue which caused small
writes to take much longer than they should.
Now that we emulate timings for the FS module including its file cache,
we don't need to maintain this workaround anymore.
Everything that links in core doesn't need to see anything related to bochs, because it's only used internally.
Anything else that relies on bochs should be linking it in explicitly.
The general convention is to return a reference to the object that was
acted on, otherwise you can get into situations with errors because the
type wasn't being propagated properly
Using this in its current form would invoke undefined behavior, as it's
using a union to type pun between data types. It's also, well, unused,
so we don't need to keep it around.
We already read the necessary information with the
HostRead_Instruction() call. Internally, it calls HostRead_U32() as
well, so there's no difference in behavior.
If the locked cache isn't enabled, dcbz_l is illegal to execute
(locked cache is off, locked cache instructions don't work, makes sense)
This makes exception handling more accurate. It was previously possible to hit the DSI exception
handler when HID2[LCE] is set to zero, which isn't correct.
With this change we no longer hit the DSI handler, however we still have a lingering issue elsewhere
likely to do with exception precedence, we seem to hit the Floating Point exception handler instead
in some cases. This isn't due to the instruction itself directly however, so this is just another bug
to fix elsewhere.