コミットグラフ

3069 コミット

作成者 SHA1 メッセージ 日付
remutro ffccbc6e9c
librashader build on Linux (#1465)
Added a section for building librashader on Linux

Didn't want this to get too long or distro specific so these should be
the absolute minimal instructions for the platform.
2024-05-01 11:14:59 +01:00
jcm caecd0bca2
infra: update macOS build scripts and SDK, bump MoltenVK to 1.2.7 (#1463)
This PR does a few things:

- Updates ares to create macOS builds with the latest SDK. After
65264090b0
there are no longer any outstanding issues doing so. Importantly, we use
Xcode 15.2, since prior versions have issues with weak linking.
- Adds `macos-compat` to CI as a compatibility build that maintains
macOS 10.9 to 10.13 compatibility. The `macos-latest` runner will target
10.13 and above. The only difference with this build is the SDK version
used to build it (Xcode 13.4); macOS weak linking handles the rest.
- Increments the MoltenVK version to 1.2.7. The version ares was
building required a Python library `distutils` that is no longer
trivially available with newer Python versions.
- Refactors the `xcode-select` usage reserved for GitHub Actions out of
the SDL script and up to the top level, before any dependency scripts
are run. This is just tidying up.
- Improves the librashader build script warning to specify that you need
to add a target with the nightly toolchain to build librashader (from
@rasky)
- Unbreaks the build.

This PR has been tested and verified to build in a local branch, but to
be safe, it would probably be good to run it here as well.

Co-authored-by: jcm <butt@butts.com>
2024-05-01 11:14:45 +01:00
jcm 1b3e826575
n64: Unload and save before reset() on gamepad and disk (#1464)
7ad14ff6bf
inadvertently made it so that .pak saves (and other save data) are not
properly persisted to disk when unloading the n64 core. This PR resolves
that, calling `unload()`, which itself calls `save()`, before resetting
the gamepad and other memory.

Co-authored-by: jcm <butt@butts.com>
2024-04-30 10:43:07 +01:00
jcm a6d380fb57
ruby: Remove tight loops in SDL and OpenAL (#1458)
When we are synchronizing to audio and waiting for buffers to play back
before continuing in the emulation thread, the SDL and OpenAL audio
drivers currently wait inefficiently in tight loops that consume many
CPU cycles. This PR adds `usleep` calls to these loops.

In the case of the SDL driver, we sleep for ~~the time it takes one
quarter of our prescribed buffer size to play~~ precisely the amount of
time to play our queued audio that's in excess of our prescribed buffer
size.

For the OpenAL driver, it was more difficult for me to determine how to
see exactly how much time we should be waiting since the loop seems to
work slightly differently. One millisecond seemed reasonable given that
the minimum latency is 20 milliseconds, and was sufficient to introduce
significant savings without impacting performance.

Exactly how much CPU use this saves depends on a couple factors;
primarily, the host CPU and the guest core (more demanding cores will
spend a smaller share of time waiting in the audio driver). Reduction
seems independent of audio latency. Here are some sample figures for the
M1 Max:

SNES core (Super Mario World): 95-105% CPU use before, 40-50% CPU use
after with both OpenAL and SDL.
N64 core (Super Smash Bros): 100-110% CPU use before, 60-70% CPU use
after with both OpenAL and SDL.

(macOS's activity monitor measures activity as 'percent of one core',
hence the over-100% figures).

Less demanding cores and more powerful systems will benefit more from
this change, generally.

I tested this pretty thoroughly on my system to make sure that it did
not impact performance on even the lowest 10ms SDL latency on the most
demanding N64 core. However, other people putting this through its
paces, particularly on less powerful systems, would be a good idea, to
make sure that platform differences in `usleep` behavior don't have
unexpected results.

Co-authored-by: jcm <butt@butts.com>
2024-04-29 18:45:15 +01:00
png183 edf25196ee
gba: fix timing of initial DMA wait cycles (#1461)
DMAs on the GBA wait for two cycles before taking control of the bus.
While ares implements this behaviour, ticking these cycles before
running DMAs causes the DMA to run early in ares when the current call
to `CPU::step()` runs for a number of cycles equal to or greater than
the number of DMA wait cycles left.

This PR addresses the issue by ticking DMA wait cycles after running all
DMAs that are currently ready, fixing several timing test cases in the
mGBA test suite, and improving timings in the [Hades DMA start delay
tests](https://github.com/hades-emu/Hades-Tests/blob/master/source/dma-start-delay.c).
2024-04-25 08:47:34 +01:00
png183 de8f344b89
gba: improve handling of SRAM/Flash bus (#1459)
This PR accounts for using 16- or 32-bit accesses in the cartridge
backup region, which has an 8-bit bus, and accounts for reading from
said region when no SRAM or flash memory is present. Passes all of
[jsmolka's save
tests](https://github.com/jsmolka/gba-tests/tree/master/save).
2024-04-23 11:27:45 +01:00
Luke Usher 8498b95ab5 n64: manually tick cartridge rtc
Also moves dd daysInMonth to nall::chrono
2024-04-23 11:11:17 +01:00
Luke Usher 8a547cacc0 n64: use gmtime rather than localtime when incrementing rtc 2024-04-22 15:04:47 +01:00
Luke Usher 1bdfa3e21a Merge branch 'master' of https://github.com/ares-emulator/ares 2024-04-22 11:19:49 +01:00
jcm b5cd509a77
ruby: Add Metal VRR support, various Metal driver fixes (#1455)
Adds to the Metal backend from #1431, extending host VSync functionality
to variable refresh rate (VRR) displays, enabling the ability to sync to
guest and host refresh rates simultaneously, along with an assortment of
minor changes and code cleanups:

- Adds a threaded renderer option (technically a GCD queue) to the Metal
backend; essential for VRR at lower audio latencies. At higher audio
latencies, the synchronous rendering option may function better.
- Add easier debug capabilities, including a shell script to compile a
debug `.metallib` shader library which will be used at runtime if ares
is compiled in debug mode. The debug `.metallib` enables GPU frame
capture.
- Implement `clear()` for the Metal backend; the last displayed frame
will no longer stay on the screen if a core is explicitly unloaded.
- Implement fullscreen mode. Uses a borderless window that covers the
entire screen, rather than idiomatic fullscreen, primarily in order to
render around the camera housing. Normal macOS fullscreen behavior is
available via the main window title bar controls.
- Remove unused custom window code.
- Remove redundant copy of `Shaders.metal`.
- Miscellaneous small fixes and code cleanups to resolve compiler
warnings.


https://github.com/ares-emulator/ares/assets/6864788/1e2d594a-c84f-4b95-a792-cacdde2a09b0

## ares vs. VRR
As discussed in #1431, there are some challenges in implementing smooth
VRR support for ares on Metal. Briefly:

- ares lacked a mechanism to tell the display backend the core's desired
refresh rate, in order to sync to it.
- ares on macOS lacked an effective mechanism for receiving callbacks
when frames were presented, in order to keep track of whether we were
running fast or slow, because of the way ares monopolizes the main
thread on macOS.

The first issue has been resolved by a3c57b4 and ec0b625. Cores now tell
the `Screen` instance how often they want to present, and the screen
instance will tell the display backend if it implements the
`refreshRateHint` function. This enables the display backend to quickly
respond to changing guest refresh rates even during runtime.

The second issue is a bit trickier. As discussed, `MTKViewDelegate` and
`CAMetalDisplayLink` are both effectively unavailable until ares moves
its primary emulation work off of the main thread. There is, however,
one Metal callback mechanism that can still be used by ares;
[[MTLDrawable
addPresentedHandler:]](https://developer.apple.com/documentation/metal/mtldrawable/2806858-addpresentedhandler?language=objc),
because it calls back on a dedicated serial queue
(`com.apple.coreanimation.CAMachPortUtilReplyQueue`) rather than the
main thread.

Using this presented handler, ares can use `drawable.presentedTime` to
keep a running average of how long our frames are being presented for,
determine if we are running ahead or behind, and modify our subsequent
present intervals accordingly. That is what we do for this initial VRR
implementation.

## macOS VRR

> [!NOTE]
> The following applies to "ProMotion" displays, as those are the ones
most tightly integrated with macOS and most likely to be used by Mac
users on VRR displays.

Unfortunately, VRR sync is not as simple as just picking a present
interval and telling macOS to present each frame for the guest's
requested interval. macOS only pretends to offer this capability in
exclusive fullscreen mode, and even then, present intervals cannot be
completely arbitrary. Realistically, we seem to be able to get
consistent present intervals for some integer refresh rates between 40
Hz and 120 Hz, and certain rational present intervals (59.97, 23.976
among them). The spread of achievable consistent present intervals seems
to be arbitrary enough that there isn't any sense in targeting them
specifically. Even if we can theoretically present at the exact interval
the guest wants, we inevitably end up falling behind due to transient
load conditions.

> [!NOTE]
> For background, the landscape of guest refresh rates in ares is quite
wide. Many systems present near 60 Hz; 59.97, 60.01, 59.73, 59.92,
59.82, etc. Many of these systems have PAL modes that present near 50
with similar variations. The WonderSwan presents at a maximum of ~75.47
Hz, with per-game variations. The Atari 2600 can present at completely
arbitrary intervals during runtime owing to its CRT- and
processor-centric presentation strategies. In short, It is difficult to
narrow the range of expected guest present intervals if we wanted to
simplify this problem.

Rather, we have to pursue a more holistic strategy. The strategy ares
uses with this PR is as follows:

1. The output function sends frames into a FIFO dispatch queue that can
present asynchronously, to reduce the burden of needing to present
immediately if we are in danger of blocking the main thread.
2. If we are more than 0.5% off of the targeted present interval as
determined by a weighted rolling average, start "nudging" the system to
present at earlier intervals calculated according to the difference
between the rolling average and the target, multiplied by a constant
`kVRRCorrectiveForce`.
- This is done because we can often prod the system into presenting at
rational intervals close to the target interval, resulting in an overall
smoother presentation to the user than if we were to correct more
forcefully.
3. If more than `kVRRImmediatePresentThreshold = 3` frames are in the
queue to be presented, start telling the system to present immediately
instead of "nudging."
- This is a more forceful correction toward the target present interval,
and must be kept low for systems that want to present at intervals that
are far away from any achievable consistent present interval.
4. If the queue gets much deeper, `kMaxSourceBuffersInFlight = 6`, start
dropping frames.
- This is necessary for synchronizing to neither audio nor video, or
else in rare cases where the GPU is overloaded, such as for a shader
that the system is not capable of rendering in time each frame.

This system achieves decent results across most systems in my testing. I
considered allowing these constants to be twiddled with sliders, but was
wary of presenting too many esoteric options to the user. If it's
determined to be worth exposing these constants, that can be done in
future work (if a superior VRR presentation strategy entirely is not
discovered by that point).

## Miscellany

- The threaded renderer is necessary so that we do not ever block the
main thread in the worst case present interval conditions. However, it
only works well at relatively low audio latencies. At higher audio
latencies (as for users on lower-specced systems), the queue overflows
easily and it works better to render synchronously.
- The threaded renderer can also have unintuitive results when
exclusively syncing to host VSync or GPU sync, so for users that expect
particular behavior from that functionality, it is better left disabled.
- For PAL refresh intervals, players will get generally better results
in exclusive fullscreen. macOS likes to render things at 60Hz and will
struggle to render near 50 Hz with other elements onscreen.
- To view the present interval graph as in these debug shots, input
`defaults write -g MetalForceHudEnabled -bool YES` at the command line
before launching ares.

## Future Work

We could possibly achieve better VRR results utilizing something like
`CAMetalDisplayLink` after freeing up the macOS main thread. In my
testing it seems to have the same limitations in terms of achievable
consistent present intervals, but it may offer a more precise picture of
host vs. guest present timing.

Regardless of the viability of other strategies, it would still be
valuable to free up the main thread on macOS for the sake of other
system APIs that may be used in the future, plus benefits of being able
to use the UI consistently and smoothly concurrently with emulation.

N64 and PS1 also do not fully implement the `refreshRateHint` API, and
the API may be buggy for some platforms. Metal refresh rate hints
currently appear in stdout, so if you are seeing an issue with VRR sync,
check the console to see the guest's requested present interval first.

## Gallery 


https://github.com/ares-emulator/ares/assets/6864788/1022c24b-fd83-4ede-b1ac-3f0c3a207972


https://github.com/ares-emulator/ares/assets/6864788/7e36bd4a-7acd-4d37-a572-7550ba1ad2b2

(PAL Super Mario World)


https://github.com/ares-emulator/ares/assets/6864788/9655fcbe-28de-48b2-88b7-7fb864991ef0

Co-authored-by: jcm <butt@butts.com>
2024-04-21 19:27:16 +01:00
Zeck fb2cdd9b71
fix windows tcp timeout (#1457)
Gotta love questionable platform differences. On Windows the old code
causes a disconnect after recv times out in 1 second, because errno will
always be 0. [Windows does not use errno, or
EAGAIN](https://learn.microsoft.com/en-us/windows/win32/winsock/error-codes-errno-h-errno-and-wsagetlasterror-2).
Now when the platform is windows
[WSAGetLastError](https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsagetlasterror)
is checked for
[WSAETIMEDOUT](https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2).

I could maybe do some more improvements in the file, (probably in
another PR) but I don't know what the project is interested in.
I did not address other uses of errno in the file.
I also did not switch from strerror, which windows does not use, to
[FormatMessage](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage).
2024-04-21 19:26:55 +01:00
png183 eaab017b26
gba: handle ROM mirroring for Famicom Mini / Classic NES Series (#1456)
The 1MiB ROM chips used in most Famicom Mini carts and all Classic NES
series carts are mirrored, unlike with the larger ROM chips other carts
used. This PR implements the ROM mirroring behaviour and adds detection
for the affected games.

Closes #893
2024-04-21 19:26:29 +01:00
png183 74deb9351d
gba: last cycle of prefetcher cannot be interrupted (#1451)
If the prefetcher is interrupted with 1 cycle left in its fetching
operation, run the final cycle regardless. Improves mGBA test suite
timings from 1890/2020 to 1904/2020, and passes a [test in the AGBEEG
Aging Cartridge dedicated to this prefetcher edge
case](https://github.com/zaydlang/AGBEEG-Aging-Cartridge/blob/master/documentation/cartridge/rom_access_during_prefetch.md).
2024-04-16 17:52:22 +01:00
曾耿森 cfa7f123de
fix(fc-cpu): pass some test (#1454)
1. pass cpu_interrupts_v2/2-nmi_and_brk.nes
2. pass cpu_interrupts_v2/3-nmi_and_irq.nes
3. pass cpu_interrupts_v2/5-branch_delays_irq.nes
4. remove a26 some empty virtual function
5. add mos6502 some virtual function default impl
2024-04-16 17:52:09 +01:00
Luke Usher dd7fd4ea52 mia: load sfc boards from filesystem rather than embedding in mia 2024-04-12 14:54:01 +01:00
Luke Usher 5229e0f93a mia: include sha256 in generated sfc manifests 2024-04-12 10:29:21 +01:00
曾耿森 dc466a69f4
fix(fc-apu): fix framecounter write 4017 (#1452)
write $4017 need to clear irqPending and set cpu irq
2024-04-12 08:30:31 +01:00
Luke Usher 61a1304210 fc: some cleanup 2024-04-11 19:53:27 +01:00
Luke Usher 5b6899419c fc: remove WIP reset testing code 2024-04-11 16:44:31 +01:00
Luke Usher 9d1984a2bd mos6502: implement reset cycles 2024-04-11 16:43:08 +01:00
Luke Usher 99a87acdf2 ruby: really fix using linear rather than nearest in d3d driver 2024-04-11 16:38:26 +01:00
Luke Usher fd8e717707 ruby: fix using linear rather than nearest in d3d driver 2024-04-11 16:26:37 +01:00
Luke Usher 426947c0cb fc: don't call cartridge.main directly, handled by scheduler. 2024-04-11 15:39:46 +01:00
Luke Usher 043c5e0de1 fc: remove duplicate Thread::create in apu 2024-04-11 15:37:41 +01:00
Luke Usher 5104b34f2c fc: restore per-device co-threads
(Reverts 265ba002e6)
2024-04-11 15:34:20 +01:00
曾耿森 66ecd2e65c
fix(fc-apu): pass some test (#1450)
1. let the APU inherit the Thread
2. change the execution sequence of the apu and cpu

3. pass blargg_apu_2005.07.30/08.irq_timing.nes
4. pass blargg_apu_2005.07.30/09.reset_timing.nes
2024-04-11 08:53:35 +01:00
Luke Usher 7ad14ff6bf n64: fix savedata duplication issue
This fixes an issue where upon loading a game that doesn't use a controller pak after a game that does, a .pak file would be created using the previous games data.
2024-04-10 20:18:00 +01:00
曾耿森 feffcc22cf
fix(fc-apu): pass some apu test (#1449)
1. pass apu_reset/4015_cleared.nes
  2. pass apu_reset/4017_timing.nes
  3. pass apu_reset/4017_written.nes
  4. pass apu_reset/irq_flag_cleared.nes
  5. pass apu_reset/len_ctrs_enabled.nes
  6. pass apu_reset/works_immediately.nes
2024-04-10 17:55:18 +01:00
Luke Usher ca0044b663 desktop-ui: fix shaders not applying on startup 2024-04-10 10:39:40 +01:00
David DeGraw 35299b18d3
macOS: Implement mouse driver (#1446)
There are a few ways to get mouse position: GCMouse and using NSEvent.

GCMouse is newer and better, it reports mouse movement in raw x/y deltas
which is exactly what we need. The issue is that it expects you to set
up handlers for the movement events , but I couldn't figure out a way to
do that with the existing `poll()` paradigm where it passes the device
into the function. Ideally I'd be able to do
`assign(HID::Mouse::GroupID::Axis, 0, deltaX);` directly in the event
handler.

The other advantage to GCMouse is that we can use
`CGAssociateMouseAndMouseCursorPosition` and then we don't have to worry
about moving the hidden cursor over built in UI (such as the dock).

This implementation uses regular NSEvent for mouse data which works
pretty well with the current poll() paradigm. I had difficulty handing
mouse centering/zeroing so I left it out. It works pretty well both full
screen and windowed but it is possible to accidentally click the dock.

Open to feedback so please let me know what you think! I'd love to get
GCMouse working.

Demo:
https://www.youtube.com/watch?v=UwPyVNWP5hM
2024-04-09 18:05:54 +01:00
曾耿森 8316233b3e
fix(fc-apu): pass some apu test (#1445)
1. pass apu_test/apu_test.nes
  2. blargg_apu_2005.07.30/05.len_timing_mode0.nes
  3. blargg_apu_2005.07.30/06.len_timing_mode1.nes
  4. blargg_apu_2005.07.30/07.irq_flag_timing.nes
  5. pass blargg_apu_2005.07.30/10. len_halt_timing.nes
  6. pass blargg_apu_2005.07.30/11.len_reload_timing.nes
  
  7. inc the fc SerializerVersion version to v139
2024-04-09 15:10:27 +01:00
Adrian Siekierka 2ad5d0a562
ws: fix refresh rate hint using line count of 0 (#1448) 2024-04-09 15:06:47 +01:00
Luke Usher ec0b625ea5 ares: update cores to use refreshRateHint api
Most systems will use an accurate refresh rate calculated from display timing

N64, PS1, PC-Engine and Neo Geo Pocket use 50hz and 60hz until we determine how to calculate.
2024-04-09 11:23:29 +01:00
jcm a3c57b4fbd
screen/video: Add refresh rate hint mechanism (#1447)
This constitutes one puzzle piece that will help improve ares's frame
pacing, particularly for variable refresh rate displays.

While continued work on ares's audio drivers is likely to smooth the
pace at which ares generates video frames, transient changes in
application and system load inevitably means that frames will be
delivered earlier or later than expected. Additionally, relying on video
frames to be generated precisely when needed and presenting them
immediately is fairly demanding. If we can pace frames some distance in
advance, it can significantly lessen the burden on the CPU and GPU.

This PR is one tool to help the video backend deal with these issues.
Cores can now inform the screen of their expected rate of frame
generation at any given time, and the screen will inform the video
backend. The backend can then employ various strategies to perform
optimal frame pacing and drop frames when necessary.

The function is emphasized as a 'hint' to indicate that the rate is only
that which is expected, rather than certain. Unpredictable changes in
system conditions mean that we can never be entirely certain when a
frame will be generated or presented.

> [!NOTE]
> No concrete `refreshRateHint` implementations are added in this PR.
Given the variety of core refresh rates across ares, as well as the
consideration that for some cores refresh rates can change during
runtime, that work is left for separate PRs.

Co-authored-by: jcm <butt@butts.com>
2024-04-09 09:34:57 +01:00
曾耿森 e24e89b272
fix(apu): fix apu framecounter (#1442)
detail:
    1. Improve the emulational accuracy of apu framecounter
    2. pass the apu_test/4-jitter.nes

  todo:
    1. Does apu need to emulate blocking_write_4017?

  question:
1. A white screen will appear when running
blargg_apu_2005.07.30/04.clock_jitter.nes
2024-04-06 18:19:03 +01:00
Adrian Siekierka 6d3bc6044a
ws: implement sound test bits 1, 2, 3 (#1441)
Up to date with the current research status quo.
2024-04-06 18:17:16 +01:00
Luke Usher ae2ec42c60 a26: bump serializer version as changes were significant 2024-04-05 12:46:13 +01:00
Luke Usher 3288e476a0 a26: rework tia, fixes most (but not all) known issues 2024-04-05 12:44:53 +01:00
Luke Usher 3da6974ae4 a26: improve hmove handling slightly
Preparing for future work
2024-04-04 11:29:39 +01:00
Luke Usher ea7f9a8c0f desktop-ui: refactor menu gen/shader loading 2024-04-03 23:00:24 +01:00
Luke Usher 1ea995f78d arcade: use mame machine names for convenience
Update mame2bml to include mame romset version

Add script to update arcade rom database (requires a MAME installation)
2024-04-03 06:57:51 +01:00
David DeGraw 4782fa43a0
Fix readme typo (#1440)
Minor markdown formatting tweak
2024-04-03 05:33:58 +01:00
jcm 5ee8f117a1
UI: update shader location when initializing (#1439)
Fix an error when cherry picking changes from a local branch for #1438.
Use the new variable for the base shaders directory when loading the
program start shader. Unbreak the build.

Co-authored-by: jcm <butt@butts.com>
2024-04-03 05:33:21 +01:00
jcm f515ed15c5
UI: Expose all .slangp shaders available (#1438)
Previously, the `LoadShaders()` function in `desktop-ui` searched only
two levels deep, which did not find all `.slangp` shader presets
available. The entirety of "megabezel" was not exposed, for example.

Now we properly traverse the entire directory structure of `Shaders/`
looking for `.slangp` files, exposing all that are available.

This PR does a small amount of rudimentary pruning for paths that do not
contain `.slangp` shaders, but future work, perhaps undertaken by
someone who has more fun with recursive directory traversal, should
probably properly prune all paths not containing presets.

Co-authored-by: jcm <butt@butts.com>
2024-04-02 22:20:09 +01:00
Adrian Siekierka 39c73a89ff
ws: emulate 32KB SRAM for "8KB" cartridges (#1437)
Based on [ototo2009's PCB
scans](http://blog-imgs-131-origin.fc2.com/o/t/o/ototo2009/WS-2019-12b.html),
I have verified that every single cartridge that uses the value `0x01`
for its save type in the ROM header actually comes with 256 Kbit (or 32
KB) of SRAM.

In addition, WonderSwan ROM chips tend to use the notation of
`MHxxMyySzzzz` for a cartridge with `xx` megabits of ROM, `yy` kilobits
of SRAM (or `yyE` for EEPROM), and the ROM data ID `zzzz`. All of the
cartridges in question appear to use `256S`.

As such, it seems to me that Ares should similarly emulate 32KB of save
data for all such cartridges. It seems that this actually fixes a game,
for once.
2024-04-02 19:17:44 +01:00
曾耿森 feebb5b698
Mos6502 native (#1435)
1. fit mos6502 architecture
2. implment all mos6502 instruction
3. fc MDR using in base cpu
4. rename fc cpu.MDR to openBus
2024-04-02 15:34:46 +01:00
Luke Usher db2e0d45e1 nall: missing include 2024-04-02 13:18:19 +01:00
Luke Usher b145f0f000 screen: use condition_variable rather than polling for next frame
Use a timeout to prevent deadlocks when unloading games/if no frames are prevented.
2024-04-02 11:39:23 +01:00
Luke Usher 0af2690e50 ps1: blitter now uses a copy of the display area 2024-04-02 11:08:37 +01:00
Adrian Siekierka 7438418d97
v30mz: minor fixes (#1434)
Fixes some undefined behaviour handling and the BOUND opcode, in
accordance with [WSCpuTest](https://github.com/FluBBaOfWard/WSCpuTest/).
2024-04-02 10:25:12 +01:00