Fix envelope timing and key-on delay, jump to the repeat address on sample end.
Capture CD audio before volume processing,
Fix sign handling for cd-rom volume and pitch modulation
ref: https://psx-spx.consoledev.net/soundprocessingunitspu/
Devices are now in charge of their own timing, fix Memory Card and Controller timing to be closer to hardware.
Fixes an infinite loop polling for memory cards in Ace Combat 3 (USA)
Clearing DPC_FREEZE calls flushCommands even when END equals CURRENT. Previously, this set pipeBusy and startGclk without executing any commands, leaving an initially idle RDP reporting busy.
Return before setting the busy flags when no forward command range is available. Preserve existing busy state for starved pipelines and leave START/END latching unchanged.
The following are new behavoirs in the python tooling:
Extract DIP switch definitions, input mappings, and other metadata by parsing tables directly from the MAME source tree; this lifts metadata (such as dip switch names and bit-values and button labels) into Arcade.bml, no code is lifted.
Support custom overrides for information that is missing or insufficient in MAME's database.
Allow ROMs to be excluded from the generated database, including incomplete dumps, unsupported bootlegs, and non-game software.
Extend the existing per-system input override functionality to support game-specific controller mappings.
The intended workflow is for users to configure their Virtual Pad once. The Virtual Pad attempts to map inputs to each system's controller based on the physical position of its buttons.
Users can then customize mappings by adding overrides for specific inputs per-system, or per-game. Per-game overrides can only be configured while the relevant game is loaded.
ares attempts to strip common Disc, Disk, Side and Part suffixes from game titles, allowing multi-disc games to share the same input configuration.
Introduce a shared DIP switch implementation for arcade systems, replacing system-specific implementations.
Neo Geo:
Implement the NEC uPD4990A real-time clock.
Implement the MVS hardware watchdog.
Fix IRQ acknowledgement register handling to that only pending IRQs can be acknowledged
Move ROM decryption and protection handling into runtime PCB emulation, more closely reflecting the behaviour of original hardware.
Add support for additional protection schemes and game-specific memory mappers.
SG-1000A:
Add support for the encrypted Z80 variant used by Championship Wrestling.
Introduce separate opcode fetch and data read paths for the Z80, allowing accurate emulation of hardware-dependent decryption.
Portions of the ROM decryption and protection implementations are derived from MAME. Only code distributed under permissive licences, including the BSD 3-Clause License, has been incorporated.
All MAME-derived implementations are explicitly identified in the source code, with the applicable copyright notices and licence terms preserved in the project's LICENSE file.
To measure texture cache timing, textured draws previously waited for
the renderer to catch up before emulation could continue.
Now we wait only when the GPU becomes ready for another draw.
draw timing observed by the game is unaffected.
Moon Patrol's HSCROL write was landing too early in ares, corrupting the mountains
Altirra Hardware Reference Manual was used to determine correct behavoir, which I believe to be trustworthy as the introduction specifies that "This document attempts to describe the hardware in detail as the target to which the emulator aspires to imitate"
Weave (default): combines the current field with the previous field. this preserves detail but may introduce combing during motion. This is how ares behaved historically.
Bob: displays the current field and interpolates missing lines. This prevents motion combing but causes a noticable loss of vertical detail and may flicker thin lines.
Blend: displays an average of consecutive bobbed fields. Behaves similar to bob, but swaps flicker for motion blur.
Phosphor: displays only the currently displaying field while simulating phosphor decay. This Produces a darker image with visible scanlines and may flicker, but is closer to how a real CRT handles interlaced video.
nocash DIAG's hardware cache tests measure miss penalties of ~60 CPU
clocks for eight entries and ~120 clocks for sixteen entries. This is
approximately 12 GPU clocks per 8-byte refill.
We use 13 clocks here as it better fits JaCzekanski's GPU bandwidth
test; textured drawing timings now measure within ~1-2% of the hardware
baseline.
- prevent discarded polygons from counting in draw timing calculations
- fix depth mode changes applying one frame too late
- fix cd-rom stop command
- prevent MDEC output fifo from losing data when full and reduce output size to a more realistic 32 words-
Rationale is that the clang64 ci is resulting in a build that drops as low as 40vps in FMV sequences in the PS1 core, vs 90vps in the same scene for clang-cl
Pinning a known-performant version of clang was considered (local testing proved clang22 produces more performant builds than clang20), but this is not viable with how msys2 is managed. Investigation concluded that we cannot reliably update the clang msys environment; just running 'update:true' breaks the build due to a ymfm issue with the clang23 runtime, and installing the 'clang22' packages still uses the clang23 runtimes, it only pins the compiler itself.
A block can end before an instruction that has a gdb breakpoint. Its
last instruction can then be straight-line code, which does not commit
the pipeline PC. The block exited with ipu.pc at the last commit point,
so the CPU ran the instructions after that point a second time. If that
point was an internal entry of the same block, the CPU looped forever
and the breakpoint never hit.
Commit the pipeline PC on the last instruction of every block. All other
block ends already commit there, so code without breakpoints is
unchanged.
- more accurately model the CPU bus, write buffering and cache behavior
- improve DMA arbitration, chopping, transfer timing, and interaction with CPU
- rework CD-ROM command timing, deferred responses, interrupts, sector delivery, subchannel data, and disc session handling
- implement the GPU command FIFO, busy timing, texture caches, rasterization, and improve scanout accuracy
- improve timer synchronization, reset, interrupt, and blanking behavior
- improve peripheral, SPU, MDEC, and memory-mapped I/O timing
- add support for Datel Action Replay and Blaze Xplorer cartridges
- add support for the Pixel Accuracy toggle to enable per-pixel scanout (required by tajmiing demo)
These changes were validated against psxtest_cpx, psxtest_gpu, nocash diag.exe, JaCzekanski's tests, and the pcsx-redux CD-ROM torture tests.
Most of tests now pass, and known problematic games such as Monkey Hero are working.
Framebuffer output matches expected hardware output pixel-for-pixel in the nocash diagnostics and psxtest_gpu primitive tests.
Timer test results generally remain within a small margin of hardware baseline results (when compared against the psx.log reference point shipped with the tests)
psxtest_cpx and psxtest_gpu do not initialize controllers correctly when launched directly from the BIOS. You must run them them through software that initializes the hardware first, such as a Datel Action Replay or Blaze Xplorer cartridge. These devices can be configured in Core settings. This issue exists on real hardware and is correct behavoir.
ares can now run the tajmiing demo and all its effects end-to-end.
tajmiing changes display registers at individual-pixel boundaries, so it requires the Pixel Accuracy option in Video settings. Scanline-level synchronization remains the default as oridnary software does not depend on mid-scanline register changes.
Latch the left and right edge matches independently until the next scanline, preserving the inclusive right edge. This prevents mid-line bounds writes from reopening a stopped window, as demonstrated by Mickey Magic and MiSTer SNES PR #508.
Serialize the latches and bump the SNES state format. Fixesares-emulator/ares#2645.
With FreeBSD 15.0 going EOL very soon, it is time to update the runner
in the CI to FreeBSD 15.1. This version is supported by Cross-Platform
GitHub Actions since version 1.3.0, and the runner is updated to the
currently newest version 1.6.0, which corresponds to the commit
https://github.com/cross-platform-actions/action/commit/e0b9770014ba65d5e0815f15b74031c3a635f641.
Using the operating system's shell for running commands inside steps is
deprecated. Cross-Platform GitHub Actions provides and recommends the
new custom shell cpa.sh instead, which the runner is now using.
This requires to split the "Build: FreeBSD" step into at least one
separate step for setting up the VM before executing commands in the
following steps. This opens up the opportunity to be more in line with
the Linux runner by installing the build dependencies in its own step,
"Install FreeBSD Dependencies".
Before installing dependencies, the runner now updates the preinstalled
packages in the VM via pkg upgrade -y. This ensures that the whole VM is
cohesively up-to-date.
Last but not least, the TARGET_PRESET environment variable must be set
in the "Build: FreeBSD" step with the --environment-variables option of
cpa.sh, or else it won't be propagated to the build environment.
Ported directly from bsnes PRs 377 and 401.
- When triggering a cache preload by writing to $7f48, update the pb register with the prepared program page
- When preloading a page, ignore all runtime checks and reload the page immediately
- Step 1+WS on both reads for cache, not just one
- Remove extra cycle on bus reads/writes
- Remove extra cycle on DMA to internal RAM (fixes excessive slowdown in Morph Moth fight)
On macoS, a binary executed directly by another process (e.g. a frontend
spawning and emulator) starts as an unregistered background process. It
must be promoted to a regular GUI application to reclaim focus.
Generic port menu callbacks could mutate scheduler threads and audio streams while the emulator worker was active. Route both disconnect and connect actions through one Program::Guard-protected helper and add a deterministic concurrent regression test.
The CPU keeps a free-running cycle counter (COUNT) that guest software
reads to measure elapsed time. Internally the emulator does not update
that counter after every instruction: cycles are accumulated in a
running clock and only folded into COUNT when the CPU synchronizes with
the rest of the machine. Reading the register returned the folded value
only, ignoring any cycles accumulated since the last fold, so the value
handed back to software could be stale.
How stale depends on how often synchronization happens, which is why
this was mostly invisible with the interpreter and clearly wrong with
the recompiler. The interpreter synchronizes after every instruction, so
at most one instruction worth of cycles was missing. The recompiler
translates a whole run of instructions into a single unit of host code
and only folds the accumulated cycles at its boundaries, so several
consecutive reads of COUNT inside one such unit all returned the exact
same number. Code that reads the counter repeatedly to check that time
is moving forward would see it standing still; the test_timer_ticks test
in the libdragon test suite fails this way, with two successive readings
comparing equal.
Track how many cycles have already been folded into COUNT in a separate
countClock field, so the cycles accumulated since then can be recovered
at any point. Reading COUNT now folds those pending cycles in first,
which both returns an up-to-date value and evaluates the COMPARE match
at the same moment, keeping the register and the timer interrupt
consistent with each other. Writing COUNT or COMPARE folds them in as
well, so the pending cycles are attributed to the old value rather than
being added on top of the newly written one.
The CPU has a free-running cycle counter (COUNT) and a programmable
target register (COMPARE); an interrupt is raised whenever the counter
reaches the target. The check for that event was written as
"count < compare && count + elapsed >= compare", which assumes the
target always lies ahead of the current counter value in plain
arithmetic order. Since both registers are unsigned, that assumption
breaks as soon as the target is behind the counter, and it breaks
permanently when the target is exactly zero: no unsigned value is ever
less than zero, so the first half of the condition is never true and the
interrupt is never raised at all.
That is not a corner case in practice. The counter is only 32 bits wide
and wraps around roughly every 90 seconds, so software that wants to
maintain a wider timestamp typically arms the target at zero in order to
be notified on every wrap. libdragon did exactly this: timer_init()
programs COMPARE to zero and used the resulting interrupt to increment
the high half of a 64-bit tick counter. Under ares that interrupt never
arrived, so the high half was never incremented and timer_ticks() went
backwards across a wrap, which is what the test_timer_ticks test in the
libdragon test suite reports.
Replace the ordered comparison with a modular distance computed over the
counter's full range: the number of ticks remaining until the target is
(compare - count) truncated to the counter width, and the interrupt
fires when at least that many ticks elapse. This behaves identically
when the target is ahead of the counter and additionally handles the
wrap-around case, including a target of zero. The counter update, the
crossing check and the cycle profiling counters are moved together into
a new stepCount() helper so that a single implementation stays
authoritative.
The client can now ask the stub to deliver chosen signals without stopping
or reporting (gdb sends QPassSignals automatically for signals configured
'handle <sig> nostop noprint pass'). Advertised in qSupported; the pass set
is client state, cleared on connect/disconnect like breakpoints.
## Overview
Adds Nintendo Vs. UniSystem support to the ares FC core. Games remain in
MAME
ZIP format and load through the existing Arcade path, without going
through
the iNES detection path used by regular Famicom software.
The implementation covers MAME metadata generation, parent ZIP lookup,
Vs. PPU
and palette behavior, cartridge boards, protection logic, cabinet I/O,
DIP
switches, controller wiring, Zapper input, and save states. A total of
41 Vs.
UniSystem sets have been validated. Vs. DualSystem, non-standard bootleg
hardware, and other configurations that have not yet been implemented
are
explicitly marked as unsupported instead of being started with the
UniSystem
model.
## Why `vsnes.py` is separate
MAME groups three substantially different hardware families in
`nintendo/vsnes.cpp`:
- Vs. UniSystem with one CPU and one PPU;
- Vs. DualSystem with two CPUs and two PPUs;
- non-standard bootleg hardware built around a Z80 and SN76489.
The generic MAME parser reads common data such as machine entries, ROM
regions,
and DIP switches. Those fields alone are not enough to determine which
Vs.
hardware model a game requires. The three families have different
runtime
structures and cannot share a single emulation path.
Configurations also differ between Vs. UniSystem games. The PPU,
palette,
cartridge board, protection logic, controller wiring, Zapper support,
and DIP
settings may all vary by set. The core needs explicit configuration data
rather than inferring hardware from a game title.
`vsnes.py` reuses the MAME XML and ROM-region information produced by
the
generic parser, then adds hardware classification and per-game
configuration.
It generates a deterministic `VsSystem.bml` database. At runtime,
supported
sets select the corresponding FC hardware model from this metadata,
while
DualSystem and bootleg sets are rejected with a clear explanation.
## Video
The combined video shows the attract modes of all 41 supported games.
Each
game is shown for approximately ten seconds, with its name in the
upper-right corner.
https://github.com/user-attachments/assets/46a59b2b-f64a-40ce-a870-1351d5df3948https://github.com/user-attachments/assets/7927d1d0-4349-4f4b-9092-feeb7b0ac127https://github.com/user-attachments/assets/d162c834-b227-497b-afe7-2f766f3ab42ahttps://github.com/user-attachments/assets/12d7b58e-7cd5-4bbf-b040-9d615e654e0chttps://github.com/user-attachments/assets/a8708059-4369-48e1-be1f-42d15099d7a8
## Screenshots
The contact sheet contains one attract-mode screenshot for each game,
composed
at the original capture resolution.
<img width="3920" height="5328" alt="contact-sheet"
src="https://github.com/user-attachments/assets/e111cf05-4a49-4b0d-9719-082b2b925342"
/>
## Supported sets
The following 41 Vs. UniSystem MAME sets have been validated for loading
and
attract-mode operation:
| No. | MAME short name | Game |
| ---: | --- | --- |
| 1 | `btlecity` | Vs. Battle City |
| 2 | `cluclu` | Vs. Clu Clu Land |
| 3 | `cstlevna` | Vs. Castlevania |
| 4 | `drmario` | Vs. Dr. Mario |
| 5 | `duckhunt` | Vs. Duck Hunt (set DH3 E) |
| 6 | `excitebk` | Vs. Excitebike (set EB4-3 E) |
| 7 | `excitebkj` | Vs. Excitebike (set EB4-4 A) |
| 8 | `excitebko` | Vs. Excitebike (set EB4-3 ?) |
| 9 | `goonies` | Vs. The Goonies (set E) |
| 10 | `hogalley` | Vs. Hogan's Alley (set HA4-1 E-1) |
| 11 | `iceclimb` | Vs. Ice Climber (set IC4-4 B-1) |
| 12 | `iceclimba` | Vs. Ice Climber (set IC4-4 ?) |
| 13 | `jajamaru` | Vs. Ninja Jajamaru Kun (Japan) |
| 14 | `ladygolf` | Vs. Stroke & Match Golf (Ladies Version, set LG4 ?)
|
| 15 | `ladygolfe` | Vs. Stroke & Match Golf (Ladies Version, set LG4 E)
|
| 16 | `nvs_machrider` | Vs. Mach Rider (Endurance Course Version) |
| 17 | `nvs_machridera` | Vs. Mach Rider (Fighting Course Version, set
MR4-1 A) |
| 18 | `nvs_mightybj` | Vs. Mighty Bomb Jack (Japan) |
| 19 | `nvs_platoon` | Vs. Platoon |
| 20 | `rbibb` | Vs. Atari R.B.I. Baseball (set 1) |
| 21 | `rbibba` | Vs. Atari R.B.I. Baseball (set 2) |
| 22 | `skatekds` | Vs. Skate Kids. (Graphic hack of Super Mario Bros.)
|
| 23 | `smgolf` | Vs. Stroke & Match Golf (Men Version, set GF4-2 F) |
| 24 | `smgolfb` | Vs. Stroke & Match Golf (Men Version, set GF4-2 ?) |
| 25 | `smgolfj` | Vs. Stroke & Match Golf (Men Version) (Japan, set GF3
B) |
| 26 | `starlstr` | Vs. Star Luster |
| 27 | `suprmrio` | Vs. Super Mario Bros. (set SM4-4 E) |
| 28 | `suprmrioa` | Vs. Super Mario Bros. (set ?, harder) |
| 29 | `supxevs` | Vs. Super Xevious |
| 30 | `tkoboxng` | Vs. T.K.O. Boxing |
| 31 | `topgun` | Vs. Top Gun |
| 32 | `vsfdf` | Vs. Freedom Force |
| 33 | `vsgradus` | Vs. Gradius (US, set GR E) |
| 34 | `vsgshoe` | Vs. Gumshoe (set GM5) |
| 35 | `vspinbal` | Vs. Pinball (US, set PN4 E-1) |
| 36 | `vspinbalj` | Vs. Pinball (Japan, set PN3 B) |
| 37 | `vsskykid` | Vs. Super SkyKid |
| 38 | `vsslalom` | Vs. Slalom |
| 39 | `vssoccer` | Vs. Soccer (set SC4-2 A) |
| 40 | `vssoccera` | Vs. Soccer (set SC4-3 ?) |
| 41 | `vstetris` | Vs. Tetris |
## Changes
- Accumulate relative mouse movement until it is read and consumed by an
input mapping.
- Maintain an independent read position for each `InputRelative`
binding.
- Synchronize relative input positions when input bindings or mouse
capture state changes.
- Apply the same relative-motion handling to the Raw Input, NSEvent, and
Xlib mouse drivers.
## Motivation
In my testing, `InputManager::poll()` is called approximately once every
8ms on my system, with observed intervals generally no shorter than 5ms.
At 60Hz, each frame lasts approximately 16.67ms, so input is normally
polled twice per frame.
Each poll retrieves the mouse-axis movement accumulated during the
preceding approximately 8ms. However, emulator cores generally read
relative input only once per frame. This means that `InputManager` may
complete its second poll before the core reads the movement value.
The previous implementation retained only the mouse-axis movement
reported by the most recent poll. The second poll therefore overwrote
the result of the first, allowing the core to observe only the movement
from the latest approximately 8ms. Mouse movement from the earlier
approximately 8ms of the frame was lost.
This change accumulates all relative mouse movement produced between
consecutive core input reads. As a result, even when
`InputManager::poll()` runs multiple times within a single frame, the
core can still retrieve the complete mouse-axis movement accumulated
during that period.
## Abstract
Support the absolute mouse movement events in the native input driver
for Windows.
Modifications:
- Convert the absolute original input coordinates to relative motion
increments;
- Handle the coordinate spaces of the main desktop and virtual desktop
while maintaining independent absolute coordinate positions;
- Add locking in the `poll` function to prevent partial data loss in the
event of multi-threaded competition.
## Reasons
When I used 'Windows Remote Desktop Connection' for remote debugging, I
found that 'win raw input' did not provide the corresponding 'relative
mouse event'. Since 'ruby' ignored the 'absolute mouse event', the input
relying on the mouse (such as the crosshair of a gun sight) could
receive key operations, but it was unable to move.
Fixes a video mixing issue which affected graphics in the "Demon's
Judgement" LDRom2 game for the Pioneer LaserActive with the NEC PAC.
---------
Co-authored-by: Roger Sanders <[email protected]>
This uses all the latest research on the exact behavior of flash chips,
including quirks of specific models, as documented on n64brew.
Thanks to the new PI bus emulation, it is now possible to correctly
implement many quirks "naturally", because of the simple way flash
chips interact with the bus.
PIDevice is now a generic device sitting on the PI bus that is able
to reply to addresses in any range. Now each device knows the addresses
it is listening to, which is how the hardware works.
PI accesses are only 16-bit wide, and both DMA and CPU I/O are built
upon it. There is no more code to mimic the weird access patterns for
misaligned addresses or different access sizes, as everything descends
naturally from the way the bus works (as it should be).
Open bus is simulated by latching the last value on the bus, which is
what happens on hardware.
This opens the door to more accurate emulation of chips which abuse the
bus in weird ways (like flash memories).
We always update hidden bits on memory writes. Given that in most cases
this is done during dcache flushes, we use SIMD to optimize that code
path and update a whole cacheline's worth with a few opcodes.
Also take the chance to add a mi/bus.hpp that implements the special
MI modes (ebus, repeat, upper), so that they naturally only apply
to CPU-issued reads.
This finally allows Ares to fully run through the IPL3 to fully initialize
the RAM chips. It tries to simulate also all the various non-working
conditions so that a change in a IPL3 that results in failure to boot,
should also fail in Ares. Obviously this would be a very long journey,
but at least all major failures are covered here.
Default RDRAM linear mapping is still kept as default as a fast path
in the recompiler to avoid slowdowns in normal situations. Given
that parallel-RDP doesn't support non-linear mappings, we just emit
a warning in that case.
Invalid current values will result in degraded RAM accesses like on real
hardware. This is also necessary to fully pass the current calibration
algorithm and to provide entropy (collected by libdragon's IPL3).
If we hit the final branch of the if in the read hook and `byteCount` is
not a multiple of 4, the remaining bytes are never read, but the buffer
is still sent back with unset data. This adds one more iteration to the
loop if necessary to read another word, and then shrinks the string to
the correct size.
In the write hook, the simple cases will do a write and then break the
switch and end up in the conditionals, potentially writing twice. So I
switched the breaks to returns.
The final conditional code in the write hook also cannot handle data
sizes that aren't multiples of 4 bytes, but I'm less confident about how
to fix that. Happy to add it to this PR if someone who knows what
they're doing advises.
Also trimmed some trailing whitespace.
Before we were drawing the frame according to the VI registers at line
0. After a recent change (I believe
https://github.com/ares-emulator/ares/commit/31526ded9196b046b0b5ce1769f14335eba9cc33
), we now draw it according to VI registers when display area begins.
This means that we take into account the vblank interrupt that normally
changes the registers so the field swapping workaround is not needed
anymore.
Some platforms experienced very poor performance with the SDL3 audio
driver, especially in combination with a demanding core like the N64.
It is assumed that SDL couldn't keep up filling the output device buffer
with the audio data from the input queue buffer. Increasing the amount
of generated input data before feeding it to the device buffer has shown
to greatly improve the performance.
This sparked the following idea and change to how the SDL3 audio driver
fills its buffers: request a fixed-sized 10ms device buffer and apply
the latency to the input buffer, i.e. the input buffer holds a multiple
of 10ms worth of audio. This allows SDL to steadily consume audio from
the input buffer and feed it into the 10ms device buffer, while the user
can still control the latency.
Additionally add the value 30 to the possible latency options. This
allows users to specify a lower latency than 40 if 20 is just a tiny bit
shy of being good enough.
The renderSettingsLabel identifier isn't declared anymore after the
recent structural changes, but it's still referenced conditionally in
desktop-ui/settings/cores.cpp and breaks the build if the N64 core is
disabled:
/tmp/ares/desktop-ui/settings/cores.cpp:108:3: error: use of undeclared identifier 'renderSettingsLabel'
108 | renderSettingsLabel.setCollapsible(true).setVisible(false);
| ^
Remove it to fix the build.
Remove the build dependencies of the removed audio and input drivers,
now that SDL3 is the only supported driver.
Additional cleanup on FreeBSD:
- libX* and libglvnd are dependencies of sdl3 itself and can reasonable
be expected to continue to be so. This allows to remove them from the
list of explicit bulid dependencies.
- vulkan-loader provides libvulkan.so which is a dlopen'ed runtime
dependency of parallel-rdp used in the N64 core. It is not a build
dependency and can be removed (though it gets installed anyway as a
dependency of sdl3).
We were telling Vulkan to display a frame as per the VI configuration
at vblank (line 0). This is wrong since all games will actually use
vblank to configure VI for the new frame. Vulkan would thus draw the
*previous* frame, rather than the new one that was just created, causing
one full frame of latency. The correct point where to kick Vulkan is at
vstart, when the active display begins.
With CPU-based rendering in a double-buffering scenario (rather than
triple buffering), this means that the wrong framebuffer would always
be shown: the one that was just going to be drawn upon. Thus, we would
basically get a race between the emulated CPU writing to RDRAM and the
host Vulkan reading RDRAM.
The bug was hidden when using RDP rendering because RDP emulation also
goes through Vulkan, so it would basically be queued *after* the VI
drawing rather than *during* it.
Use the application stream format rather than the physical device format.
Some outputs, such as HDMI/TV devices with Dolby processing enabled,
may expose a multichannel device format even though ares is submitting
stereo float audio to SDL. Using the device format for queue sizing and
drain timing could make the blocking sync path sleep for the wrong
amount of time, causing the emulator to run too slowly.
General cleanup:
- avoid heap allocation for every audio packet
- add proper failure checks
- correctly teardown SDL_Audio on shutdown
Replace the old fixed multiplier window sizing model with configurable
viewport sizing.
Window sizes are now stored as target viewport dimensions rather than
being derived from the emulated screen. Standard presets have been
provided, as well as the option to specify a custom size.
Adaptive sizing has been reworked to treat the window size as target
bounds, the actual window will dynamically grow or shrink within this
boundary to preserve the correct aspect ratio.
Oversized window recovery has been changed to respect aspect ratio
and available workspace rather than a hardcoded reducton from the
monitors geometry.
Add an optional stable text identifier to HID devices and use it for
persisted input mappings when available.
SDL joypads now expose a GUID/slot identifier, so newly saved controller
mappings no longer depend on SDL serial or device path values that can
change across disconnects, reconnects, or app launches. This keeps
multiplayer controllers distinguishable by assigning slots per matching
GUID while avoiding unstable path-derived IDs.
The input mapping parser remains backward compatible with existing
numeric 0x<deviceID>/<group>/<input> mappings. Drivers that do not set a
stable identifier continue to save and load mappings using the existing
numeric HID device ID format.
Uncovered by new tests in n64-systemtest. The JIT wasn't tested because
little-endian is only supported in user-mode for now (RE=1), where
memory accesses must go through TLBs so they currently are not JIT'd.
Anyway the fix should be correct if we eventually uncover full
little-endian mode (with BE=0).
This is a mode available only in the user mode, activated when RE=0. It
facilitates running MIPS binary code that was build for a little-endian
architecture, assuming that the code/data was 8-byte swapped in memory
before running it.
It passes the new RE tests in n64-systemtest
Avoid keeping the dirty-byte mask live across store fast paths in
jitMemoryOpcode. Compute it at the end from Rs+i16 so temporary
register clobbers (eg. SDC1/SWL/SWR) cannot corrupt dirty tracking and
lead to stale cache data.
Terminals are now only hard jumps and the special opcodes that change
state key, timers, etc.
Internal branch targets in each block are also registered as JIT
entrypoints.
Opportunistic branch linking is now removed as not useful anymore.
While provably useful, the implementation is completely confusing. We
need to rework it from scratch at some point. The way it is written
now, it impedes further progress in other areas.
Emit loads and stores directly against fpu state via sreg(2), using the same
full- versus half-mode register layout as the interpreter (word selection and
pairing). COProcessor-unusable blocks still call the C++ helpers. Skip GPR
writes when MFC1/DMFC1 targets $zero. FPU word offsets use CPU::r64 in offsetof
to avoid colliding with the host Real type at file scope.
Add generic LMUL and DIVMOD helpers (32/64, signed/unsigned) and emit fast paths for MULT/MULTU, DIV/DIVU, DMULT/DMULTU, DDIV/DDIVU. Reserved-instruction and divide-by-zero cases stay on interpreter slow paths; DDIV avoids host INT64_MIN/-1 idiv overflow. Decoder no longer marks these opcodes as JitUseCallf or JitAddsExtraCyclesInternally.
Move callf synchronization to the paths that actually emit helper calls, and keep slow-path callf state restoration explicit. Rename jitMayCallf to jitUseCallf so the flag name matches its eager-call semantics.
Route opcode helper calls through a shared setup path that materializes PC and flushes deferred state on demand, so callf overhead is emitted where calls actually occur.
Move trap exception cases to deferred slow paths and generate direct JIT code for the remaining 64-bit shift immediates, keeping reserved-instruction handling and R0 writeback behavior on the fast path.
Expand CPU JIT codegen for DADDIU, DSLLV/DSRLV/DSRAV, DADDU, DSUB, and DSUBU while preserving exact overflow and reserved-instruction behavior through helper fallbacks. Factor 64-bit reserved-instruction gating into a shared helper and collapse duplicated slow-path conditions to keep hot paths compact.
Move ADD/ADDI/DADD/DADDI hot paths to direct codegen with deferred slow-path helpers so overflow and reserved-instruction behavior stay exact without polluting the hot block body. Centralize state-key bit semantics in a typed accessor wrapper so JIT-time folding no longer depends on hardcoded bit masks.
Emit state test/update and endblock jumps only when branch/helper pipeline semantics are active, removing these control-flow overhead ops from the linear hot path.
Accumulate linear nextpc advances and flush only when current PC is needed, removing per-opcode nextpc materialization on the fast path. Also rematerialize helper call PC directly from vaddr in the linear non-delay-slot case.
Commit architectural PC only for branch/helper/terminal paths while preserving exception PC correctness for helper calls and delay slots. This removes unconditional per-opcode ipu.pc stores on the linear hot path.
Keep pipeline pc writes on branch/helper paths, and commit linear opcode ipu.pc from nextpc-4 to reduce per-opcode JIT overhead while preserving n64-systemtest behavior.
Skip per-opcode deferred-cycle flushes for straight-line instructions while keeping EndBlock checks unchanged, reducing hot-loop helper-call overhead without regressing system tests.
Skip emitting EndBlock test/jump in straight-line instructions where state cannot request block termination, reducing hot-loop overhead while preserving control-flow correctness.
Drop JIT metrics counters and reporting from the CPU recompiler to keep the hot-path code easier to read while preserving runtime behavior. This also keeps the architectural state commit path in emit() minimal by removing duplicated commit emission.
Model taken and not-taken link edges per block so conditional branches can be linked by final PC, and add finer diagnostics for no-direct-link causes. Also inline BC1 JIT branch handling with deterministic cause clearing layout checks to reduce unsupported FPU branch cases without regressing exception behavior.
Link JIT blocks lazily within sections with state-key matching and pending backpatches to cut dispatcher overhead. Gate linked jumps on dirty sections, clock/queue budget checks, and unsafe delay slots while adding detailed diagnostics on link misses and candidate coverage.
Convert all remaining integer branch and branch-likely opcodes to direct JIT emission and update decoder JIT flags, while intentionally keeping BC1 on the callf path.
Convert BGTZ, JR, BLTZ, and BGEZ to direct JIT branch emission and update decoder Jit flags accordingly, then extend invalid-offsetof suppression across cpu/recompiler.cpp to match the RSP pattern.
Verbose refactoring to only use decoder.cpp for extracting information
from opcodes (removing isTerminal and the return value of emit functions).
Added tracing to the cache index so that we basically version the JIT
blocks depending on whether it is enabled or not. This allows to
implement support for emux tracing without overhead.
This generates optimized codepaths for lqv and sqv. It also relies on
constant tracking to optimize situations where the base address is
know at JIT time (very common) and we can thus prove its alignment.
The JIT now tracks constant registers within each recompiled blocks.
This is currently unused in the generated code, will be useful to
improve code generation for vector load/stores opcodes.
This is non trivial because input arguments might mistakenly override
ABI registers. Prevent register argument clobber by resolving move
dependencies and breaking cycles with a temporary register.
Move UsesDmem and MayHalt traits into OpInfo so decoder metadata directly drives recompiler decisions, and simplify the JIT loop by unifying delay-slot state while documenting the current architecture and optimizations.
Drop the JIT write-sink indirection and skip code emission when the destination is R0, while keeping side-effecting C++ helpers and guarding their writeback to preserve R0 semantics.
Emit status.halted exit checks only for instructions that can mutate halt state (BREAK and MTC0 to SP_STATUS), reducing per-opcode overhead in the main JIT loop.
Do not classify VU opcodes as callf preflush candidates so deferred clocks are only synchronized for paths that actually require clock-visible C++ calls.
Track deferred clock progress for slow-path entries so memory fast paths avoid callf-triggered flushes while preserving correct timing when deferred fallbacks execute.
Emit direct fast paths for LB/LBU/LH/LHU/LWU/SB/SH/SW and keep unaligned half/word cases in deferred slow paths, reducing callf overhead while preserving interpreter behavior.
Keep deferred slow-path records minimal and re-enter opcode emission in slow mode, reducing per-opcode slow-path boilerplate while preserving the compact LW fast path.
Implement DMEM read/write paths with MSB-first word semantics and byte-accurate unaligned wrapping. Adjust RSP DMA DMEM transfers to use word paths consistent with the new DMEM representation while preserving IMEM behavior.
Replace the delay-slot call to instructionEpilogue<1> with explicit clock flush plus instructionBranchEpilogue, removing wrapper overhead while preserving delay-slot branch semantics.
Replace the JIT call to RSP::step with a direct thread clock increment while keeping deferred clock flushing behavior, reducing hot-path call overhead without changing interpreter behavior.
Defer fixed clock stepping across pure inlined opcodes and flush before callf paths, delay-slot handling, halts, and block exit to preserve observable timing while reducing hot-path step calls.
Emit the DelaySlot|EndBlock mask directly into branch state destinations for conditional branches, removing temporary state move instructions in the hot path.
Emit branch state updates directly in non-delay-slot branch paths and avoid copying nstate into state in the non-delay-slot epilogue, reducing branch-state traffic in the hot path.
Pass delay-slot phase into EXECUTE/SPECIAL/REGIMM emitters so branch-like ops can write the active destination directly and remove redundant delay-slot branch.begin state traffic.
Use compile-time next-PC values for non-delay-slot commits and avoid per-op branch.begin updates outside delay slots, reducing hot-path branch state traffic while preserving delay-slot behavior.
Use a compact xor-mask select for conditional branch target/fallthrough selection, reducing generated hot-path instructions while preserving existing branch semantics.
Replace runtime fallthrough reads from branch.nextpc with compile-time PC+8 immediates for REGIMM and EXECUTE conditional branches to remove extra hot-path memory dependencies.
Include block base address in the RSP JIT hash and use compile-time branch targets for conditional branches so generated code stays correct while removing extra runtime target math.
Pass the current block PC into RSP JIT emitters and use compile-time PC+8 immediates for JAL/JALR/BLTZAL/BGEZAL link register writes while keeping existing branch flow unchanged.
Skip branch state/pc commit work for non-branch non-terminal opcodes and simplify branch begin emission, and fix BLTZAL/BGEZAL when Rs aliases RA by deferring link write until after condition evaluation.
Emit BEQ/BNE/BLEZ/BGTZ and REGIMM conditional branches directly in JIT to remove per-opcode C++ calls while preserving delay-slot and link-register behavior.
Drop the fastInstructionEpilogue runtime toggle now that the specialized JIT epilogue path is stable. Keep the delay-slot fallback path while making the optimized path the only code path.
Choose the fast epilogue path at compile time for non-delay-slot instructions and keep the legacy path only for delay slots. This removes per-opcode branch-state dispatch in the hot path while preserving behavior.
Replace the slow-path JIT epilogue call with direct step/clocksTotal updates and a call to instructionBranchEpilogue, keeping branch exit semantics unchanged. This reduces call overhead while preserving behavior under the fast epilogue toggle.
Store RSP IPU PC as 32-bit so JIT word-sized accesses cannot clobber adjacent state. This keeps the fast epilogue path behaviorally stable while preserving 12-bit address masking semantics.
Add an A/B switch for a fast JIT epilogue path while preserving the legacy path as fallback, and widen branch pc storage so JIT word-sized accesses are safe. This gives a stable way to compare behavior and performance during further tuning.
Model RSP branch flow with pc/nextpc and latched state/nstate so interpreter and JIT follow the same delay-slot and end-block semantics. This stabilizes branch behavior while keeping stall and dual-issue logic unchanged.
Refactor reset handling to align with project architecture by removing the
'resetting' flag from the MOS6502 core. The reset state is now managed via
'resetPending' within the specific A2600 and Famicom CPU implementations.
- MOS6502: Remove resetting flag and internal reset logic from power().
- CPU: Introduce io.resetPending to handle reset triggers in the main loop.
- Debugger: Add interrupt/reset notification support for better tracing.
- Serialization: Update A26 (v140) and FC (v152) versions for state changes.
- Implement Dendy-specific timings: CPU divider 15, 312 total scanlines, and vblank starting at scanline 291.
- Refactor CPU/APU rate calculation to use a dynamic system divider instead of hardcoded PAL/NTSC checks.
- Add Dendy to the system region enumeration and UI emulator list.
- Handle Dendy-specific hardware differences: disable microphone input and adjust PPU aspect ratio/pixel output offset to match PAL-like characteristics.
- Clean up controller and system unloading logic to prevent memory leaks.
This implements a first subset of the emux extensions on the RSP. The
implementation is similar to the CPU one, and forwards to it things
that have to be identical.
Emux is a spec for emulator extensions to help homebrew development.
The spec can be found here at the time of writing:
https://hackmd.io/@rasky/r1k7na6Jn
Usage of emux is gated behind the "homebrew development mode" setting.
This commit introduces support for several extensions on the CPU, but
none on the RSP yet.
For homebrew profiling features, we need to track what hardware device
is accessing the shared RDRAM. We do have this already for debugging
purposes as a string. This commit changes that to an enum.
Normally, cores shouldn't be able to request the emulator to shut down
on the host computer, but this might be required for some homebrew
development features.
Previously the condition checked for MINGW, treating MSVC and all other
toolchains as a single "no detection needed" case. This inverts the
guard to MSVC, so that MSVC correctly skips detection (Windows SDK
provides xaudio2 directly) while MinGW and other non-MSVC toolchains
go through the CheckCXXSourceCompiles probe as intended.
Add cmake/finders/FindXAudio2.cmake to replace the ad-hoc XAudio2
link logic in os-windows.cmake. On MinGW, the module uses
check_cxx_source_compiles to probe for xaudio2_9 and xaudio2_8 in
the sysroot; on MSVC and other toolchains the Windows SDK umbrella
library is used directly. An imported target XAudio2::XAudio2 is
exported so call sites need no platform conditionals.
Replace the generator-expression-based -gcodeview selection in
compilerconfig.cmake with an explicit check_cxx_compiler_flag probe
at configure time (ARES_COMPILER_SUPPORTS_GCODEVIEW). This avoids
passing -gcodeview to toolchains that do not support it and makes
the fallback to DWARF visible in the configure log rather than
silently resolved at build time.
- ruby/cmake/os-windows.cmake: call find_package(XAudio2) and
consume XAudio2::XAudio2 via a generator expression; remove the
old MSVC/else block that unconditionally linked xaudio2/xaudio2_9
- cmake/windows/compilerconfig.cmake: add -gcodeview capability
probe; rewrite Clang and GCC debug-symbol blocks to branch on the
cached result instead of a generator expression
We were rendering background and sprites in burst mode, which shouldn't
happen.
I'm not the author, I'm just upstreaming changes done a member in our
team.
- Implementation of JY Company (Mapper 90, 209, 211) with support for
complex PRG/CHR banking, IRQ counter modes, and math registers.
- Implementation of SC-127 (Wario Land II Kirby hack) with A12-based
IRQ filtering.
- Enhanced CPU with `isWriting()` check and PPU with `isRenderingRead()`
status to support advanced mapper timing.
- Updated MIA database to recognize iNES mappers 35, 90, 209, and 211.
Currently Ares implements an infinitely fast EEPROM, but alas real
EEPROMs can take even 20 ms to save a single block of 8 bytes.
This commit implement approximate timings and the related flag to
notify the CPU that the EEPROM is busy writing data.
Introduce a `--batch` command-line option to run with a minimal presentation for frontend-driven launches (eg EmulationStation, arcade cabinets etc).
Behavior
- `--batch` implies `--no-file-prompt`
- Requires at least one valid game path (otherwise exits with a clear error)
- Uses a minimal presentation:
- hides menu bar
- removes status bar
- black background / centered viewport
- keeps file-open and drag/drop support
- Skips constructing settings/tools/game-browser windows in batch
Runtime safety
- Batch mode avoids UI-only flows where possible (logs messages instead)
- Driver and load/identify failures trigger a clean batch exit path
- Runtime defocus checks now use `settings.input.defocus` instead of `driverSettings.*.checked()`:
- avoids dereferencing non-constructed UI widgets in batch
- fixes batch crash from UI-state reads on non-UI code paths
`Program::quit()` could call `unlock()` on a `unique_lock` that did not own
the mutex, triggering `std::system_error` ("Operation not permitted")
and terminating the process on exit.
Guard the `unlock()` call with `owns_lock()`.
Call scheduler.setSynchronize(synchronize) during PS1 serialization
to match the behavior used by other cores.
Without synchronized serialization, coroutine/thread state may be
captured inconsistently, which can lead to crashes or undefined
behavior when loading savestates after relaunch.
Bump serializer version to v147 to invalidate incompatible v146
savestates created without scheduler synchronization.
The multi-byte read handler for the RCP/PI address range
(0xA4000000-0xBFFFFFFF) correctly fills the result buffer via
bus.read<Word> but then falls through to `return {}` instead
of returning the result. This causes GDB memory reads from ROM
cartridge addresses to return empty responses.
CMake install(DIRECTORY "path") without a trailing slash copies the
directory itself, creating an extra shaders_slang/ level under Shaders/.
Adding a trailing slash makes it copy the contents directly, consistent
with macOS (ditto) and Windows (copy_directory) which both copy contents.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
On a real console, when the AI DMA ends, even if the volume is not zero,
there is a decay happening on the analog path that doesn't cause any
audible pops. This can happen in games when they fail to meet the
audio deadline and schedule a new buffer before the previous one ends.
When the homebrew header was first introduced, in its first limited
spec, Ares defaulted to enable both rumble pak and controller pak:
https://github.com/ares-emulator/ares/commit/bc8c308ee96162f5a7068001a0ece83e5f821e16
Back at the time, there wasn't any way to specify that a controller pak
was needed by the ROM, and Ares didn't even provide a GUI to install it.
So basically this was the only way to allow a homebrew game to use
the controller pak at all.
Fast forward 4 years and now we have a GUI to select which pak to install
on each controller, and the homebrew header allows to pre-install whatever
you want into each port.
In case the user doesn't specify a suggested controller configuration
in the homebrew header, the default of using a controller pak has the
annoying side effect of creating a useless .sav file next to any ROM.
CPak is not very common in homebrew ROMs anyway, so enabling it by
default now seems to create more hassle than it solves.
The advanced homebrew header (https://n64brew.dev/wiki/ROM_Header)
specifies a bit to mark a ROM as "region free", meaning that it can be
booted in all regions. Ares now has a region preference option, so
that option can be respected for the region free ROMs.
- cpu: implemented memory timing/control registers
- cpu: update bus accesses to obey memory timing registers
- cdrom: incorrect 150lba offset in command 0x14
- cdrom: fix behavior when a command is issued before the previous has completed
- cdrom: implement behavior where a new command cannot be executed until pending IRQ are acknowledged
- cdrom: implement 'command/parameter busy' register
- dma: update bus accesses to obey memory timing registers
- dma: improve chopping/allowing the cpu to run between blocks of a long transfer
- mdec: implement basic decode timing
- mdec: implement correct input fifo behavior
- mdec: fix behavior when an incomplete block is transferred via the input fifo
- mdec: fix dma request registers, input/output full/empty registers, busy register
- gpu: use correct clock frequency for PAL and NTSC
- timer: improve behavior around timer overflow/target reached irq
When placing co_swap_function byte array into the text section, libco
uses the trick of appending a # to the section name. This name string is
passed directly to the generated assembly and the # is treated as
comment token by the GNU assembler. This is a hack to avoid a warning
about changed section attributes.
This hack doesn't work with other compilers like Clang or TinyCC, but
unlike GCC they don't require such hacks. I've added some compile time
checks around the hack to try to isolate it to GCC and allow other
compilers to see the unmodified section name.
Validated on the following OSes/architectures/compilers:
- Windows/amd64: gcc, clang, cl, clang-cl, tcc
- Windows/aarch64: clang, cl, clang-cl
- Linux/amd64: gcc, clang, tcc[1]
- Linux/aarch64: gcc, clang, tcc[1]
- macOS/aarch64: gcc, clang
[1] TCC only works with a fix to glibc headers that was only made very
recently. Without it, you have to #undef __attribute__ after including
glibc headers.
This is required on amd64 due to the aligned moves in co_swap. While
note technically needed on aarch64, I found information online that
suggested ldp/stp perform better on certain microarchitectures with
16-byte alignment.
VI_H_TOTAL is defined as the number of cycles per scanline *minus 1*.
We forgot to add that 1 back. Besides the minor inaccuracy in timing,
we could hit a race condition during initial VI config: if the Ares
VI thread ran when the display was turned on (VI_CTRL configured) but
VI_H_TOTAL wasn't already configured (and thus defaulted to 0), the
thread would spinloop forever because it would step by 0 cycles.
While fixing this, I also noticed that I wasn't properly taking into
account leap timings because of a typo; this means that PAL timings
were very slightly off.
Fixes#2293
When beginning to execute a joybus frame, PIF clears the RX flags before
the transaction begins, so that errors notified in previous transactions
don't accumulate.
This is only visible in the where an application performs multiple
transactions (SI DMA reads) on the same frame layout (sent via a single
SI DMA write), while controllers are being hotplugged. This is not very
common in Ares, which is probably why it was not noticed before.
- Replace all nall::vector declarations with std::vector in desktop-ui
- Update API calls: .append() -> .push_back(), .reset() -> .clear()
- Replace .takeFirst()/.takeLast() with .front()/.back() + .erase()/.pop_back()
- Convert .find() to std::ranges::find() and std::ranges::find_if()
- Replace .sort() with std::ranges::sort()
- Fix boolean conversions: if(!vector) -> if(vector.empty())
- Migrate all emulator-specific files and core desktop-ui components
- Use direct assignments between std::vector instead of manual loops
- Maintain compatibility with nall::split() by using auto type deduction
genius can't build with Qt as it uses ComboEdit, but it is currently
enabled in the ubuntu-ci-qt as it inherits the base ubuntu-ci (which is
GTK-based).
GCC evaluated the always failing assert before the constexprs leading
to it, resulting in a compilation failure. As a workaround, we can move
the 'imm64' case inside the else block and check for the type there,
which also catches unhandled types at compile time.
Uses the new 'callf' function instead of 'call' in generated code. In
the n64-systemtest ROM, this change shaves off 6% and 10% of the
respective VR4300 and RSP median block sizes:
VR4300 block size statistics
min max mean median
before 113 6369 893.93 573
after 104 5937 881.17 537
RSP block size statistics
min max mean median
before 97 19196 3941.95 5336
after 88 17044 3414.06 4606
Also, on a benchmark with an RSP-intensive homebrew libdragon ROM, this
change gave about 1% actual runtime speedup.
When ares switched to SLJIT, some tiny overhead was introduced in every call
from guest to host code on 64-bit Linux. This was due to the argument register
mapping differing between SLJIT's own convention and the System V AMD64 ABI.
This commit makes the recompiler put function arguments directly in the correct
registers.
This commit introduces a new 'callf' template function that accepts recompiler's
'mem' and 'imm' argument types. It abstracts away the register setup so that
different host platforms can implement their optimized function calls. This also
results in slightly shorter code in the recompiler (see the followup commit).
The SLJIT_CALL_REG_ARG type of call is actually meant for SLJIT's own, optimized
calling convention, but since it assumes function arguments are placed in
correct registers, it works here. The only other option I could think would've
been emitting x64 machine code directly.
A simple implementation that is only accurate for 4-byte or 8-byte
aligned writes. Smaller accesses will require a full implementation of
write masking to be accurate.
ubsan on Mac caught an issue in this method: all geometry coordinates
are floats out and into Cocoa, but intermediate calculations were
being performed with u32 that caused undefined behavior when negative
numbers were involved.
- Use std::erase and ranges::find where shorter.
- Replace ranges::distance with iterator subtraction.
- Enable <ranges> in hiro core/extension; use views::reverse for reverse-destruction loops.
- Minor cleanups (array_view ctor from vector, build fixes).
- array-view/span: include <vector> so std::vector constructors are visible on stricter compilers
- directory (Windows): make ufolders/ufiles return std::vector<string>; update locals accordingly to match headers
Build verified locally with ninja.
- Add Pak::append(std::vector<u8>&, string) overload to accept std::vector without wrappers
- Convert remaining callers to pass std::vector directly; remove redundant array_view wrappers
- Replace nall::vector truthiness/foreach assumptions with std::vector equivalents (!empty(), range-for)
- Use std::vector APIs consistently (push_back; insert with begin()/end() when merging)
- Align medium analyze signatures/callers to std::vector where required; no semantic changes intended
- Keep explicit array_view only for subspans (pointer+length) where necessary
Build verified with ninja.
- directory, zip, mmi, cue: switch public APIs to std::vector; fix sort/find/append
- vfs/cdrom: use std::vector buffers and wrap into array_view when needed
- hid: replace inheritance from nall::vector with std::vector-backed fields
- instruction-set: use std::vector for cpuid data blocks
- windows/registry: contents() returns std::vector<string>
- set: iterator internals use std::vector stack
- tcptext socket/server: move buffers and onData() to std::vector<u8>
- remove umbrella includes of <nall/vector.hpp>
Callers fixed accordingly (ares/mcd, mia, desktop-ui).
Qt 5 introduces QScreen, which can be used to implement most of the
functionality needed by Monitor, although some of it probably won't make
sense when using Wayland.
Qt 6 no longer allows us to poll for the status of the event loop.
However, Qt 6 does still have a processEvents function, and the version
with the timeout actually spins the event loop and returns as early as
there are no more events in it. That's basically what we want to do. We
could run this with a really huge timeout, but that would just make it
more likely that hiro freezes up, so instead let's mirror hiro/gtk3 and
use a 50ms timeout.
This does not seem to be used anywhere in bsnes, higan or ares. It's not
really possible to implement with Qt 6, which has stop exposing this
detail of the event loop. It turns out this is actually OK, since we
don't *really* need it anyway, and in the case of hiro/qt, the
replacement should be more robust anyways.
Qt 5.0 adds the QScreen API, which exposes enough information that
Desktop::{size,workspace} no longer needs to fall back to Win32/Xlib. I
manually tested that this seems to give the same exact answers as the
Xlib path (though it technically goes a different route for
Desktop::size.)
Qt 4.8 LTS was released on December 15th, 2011. It hit its official
end-of-life on December 31st, 2015. It has been dead for nearly 10
years. Qt 4 is now so old, that it has been removed from Debian long
enough that "qt4" doesn't show up in *any* of the indexed package suites
in Debian's online package search service.
The CMake build of ares never supported Qt 4 in the first place, so this
code should all be dead anyway.
Now that the usage issues with string_view have been resolved it can be
safely used to wrap a vector<u8>. I'll note that passing a vector<u8>
directly to the string constructor would work as well (thanks to a
stringify overload) but I'm preserving the wishes of the author of the
MegaLD code to keep the type conversions explicit.
I'll also note that we're still constructing a string from the
string_view when we call JSON::unserialize(). Ideally, it would take a
string_view instead of a const string& and we could avoid the copy.
Unfortunately, all of the markup decoders currently require the input to
be null-terminated, which is only guaranteed by the string class.
Previously, string_view had a constuctor that allocated a new string and
forwarded all arguments to the string constructor. Among other things,
this allowed construction of string_view objects using any of the
various stringify overloads. However, there were drawbacks:
1. The constructor string_view(const char*, u32) shadowed the
forwarding constructor, leading to very different behavior. In the
forwarding version, the first parameter would be treated as a
null-terminated string, and the second parameter would be formatted
as a string and concatenated with the first.
2. Having both owning and non-owning modes makes it difficult for
someone reading the code to reason about lifetimes, as they depend
on how the object was constructed. It also deviates from the
behavior of the identically-named standard C++ string_view.
This commit splits the PI DMA-Write transfers (that is, loads from ROM)
in multiple blocks, following what happens on real hardware. Moreover,
it tries to more accurately reflect timing that each block takes. This
is easier to be done at the block granularity, otherwise the timing
algorithm would need to figure it out again the whole block splitting
logic.
From the point of view of the running application, now a ROM con see
the two hardware registers PI_CART_ADDR and PI_RDRAM_ADDR increment
one block at a time during the transfer, which more accurately reflect
what happens on real hardware.
This commit is validated with n64_pi_dma_test test ROM
(https://github.com/rasky/n64_pi_dma_test) which we now pass in full,
including timing tests with the default 10% tolerance.
This allows callbacks for repeated events (rescheduled at each callback)
to not have additional latency caused by the latency with which we call
step().
The homebrew header supports configuring a different controller and pak
for each port, but mia couldn't represent that in the manifest. The
required change is trivial though.
For backward compatibility, if the homebrew header doesn't declare
anything (which is the same as asking for a standard controller in all
four ports with no paks), we install a cpak in port 1 and a rpak in
port 2, which is also what we have been doing forever with commercial
games.
Controller pak formatting had two bugs: checksum calculation was wrong
(didn't really iterate on all bugs), and the FAT backup copy was in the
wrong position.
Pixel perfect (1.1 PAR) can still be achieved "Scale:Integer" combined with "Aspect: No correction"; this works better than the 'Pixel Perfect' setting ever did.
Currently, Ares has an "Aspect Correction" checkbox that allows to
disable the PAR (pixel aspect ratio) configuration made by each core,
to basically display the framebuffer without any additional scaling,
with host PC aspect ratio.
In addition to this, it is common for people to request an
"anamorphic 16:9" option, to correctly display games the way they would
appear on a 16:9 TV when stretched. Sometimes, homebrew games are even
designed to be viewed like this.
This PR changes the aspect mode from a boolean to a 3-value option.
The standard option is now named "Standard (4:3 TV)", and a new
option called "Anamorphic (16:9 TV)" is added.
Currently, we render PAL games as 640x480 which is wrong because PAL has
more vertical resolution. This causes PAL graphics to be reduced in
quality compared to a real output.
This commit renders PAL at 640x576 which is the commonly used active
display area used by PAL games, and then configure the aspect ratio to
make sure the output is correct.
/Oi, /Ob2, and /Ot are implied by /O2, which CMake adds by default in
Release and RelWithDebInfo builds. In RelWithDebInfo builds CMake also
downgrades inlining by adding in /Ob1, but we already have a workaround
for this. MinSizeRel builds may see a change in behavior, where CMake
passes /O1 instead, but in any case that is the recommended flag for
minimizing binary size.
The removal of /GL is especially important for MSVC builds. CMake will
add it when IPO is enabled, and forcing it on for all non-debug builds
was not simply redundant; it was overriding the user preference
expressed with ENABLE_IPO. ClangCL requires other flags to enable the
equivalent LTO feature, and this is already addressed elsewhere.
The CPU serialization logic would sometimes write pointers to save
states. Needless to say, this was not very compatible with saving and
loading states across separate runs of the ares process.
The topmost bit of the DICR (DMA Interrupt) register should not
influenced by the per-channel interrupt enable bits. This flaw was
masked in fast boot mode, as it allows title code to begin execution in
a pristine state unlike what the BIOS leaves behind.
With this change, the titles that were "fixed" by enabling fast boot
mode can now be launched with it disabled.
Allows bit 1 of R15 to be set in ARM mode.
The updated LDM/STM implementations are functionally identical to the
previous versions, but are significantly shorter and require less
special-casing.
Fixed a bug where the prefetcher was restarting too early upon being
emptied, and implemented a timing edge case involving simultaneous
accesses from the CPU and prefetcher.
* Acquire the program mutex when updating audio sync settings to prevent
a possible crash in some audio drivers
* Pause emulation while showing driver confirmation modals to prevent
interference from the UI thread calling `ruby::audio.clear()` during the
modal state, and also because pausing the application for a modal is a
normal pattern
* Restore a workaround when loading Arcade systems via the game browser
window that prevented a crash
When loading a ROM via a startup argument, `Program` requires access to
elements that are initialized as part of the Tools window. Thus, make
sure the Tools window is fully loaded before creating `Program`.
This restores the load order prior to the threading rework. An earlier
version of the threading rework created the program mutex differently,
which is why the load order was modified in the first place
(incidentally rather than intentionally).
Fixes#2043
- Adds instruction encodings for BX with bit 21 clear, and for an
undocumented `mov rd, rn` instruction
- Uses specific encodings for undefined instructions, rather than
binding them to unused encodings, and then asserts that all encodings
have been bound
Removes a speedup in the GBA core that was detrimental to accuracy.
Testing on Linux, the performance cost is more than offset by the recent
UI threading rework.
Rearranges ares's main run loop, putting emulation in its own dedicated
thread that is separate from the main/GUI thread. This updates ares to
somewhat more modern application practices. This rework should have an
array of benefits, including increased UI responsiveness, improved
energy efficiency/performance, and increased compatibility with various
modern APIs and frameworks for rendering, input, and audio.
## Details
Generally, this PR implements a fairly simple approach to threading,
using `nall::thread`'s pthread-like semantics and several basic
recursive mutexes. For this initial implementation, we use very coarse
locking on the emulation thread, combined with very limited access to
the emulator state from the main and other ares threads, allowed to
occur between emulator run loop iterations. Synchronization on the
emulator state is managed via `programMutex`.
Since this mutex is held for the duration of the primary work loop,
including while the thread is suspended, the GUI thread should try to
never acquire the program mutex unless absolutely necessary. Doing so
with regularity will incur a severe UI responsiveness penalty. For
destructive updates like driver settings updates, memory writes, and
game loads/unloads, we acquire it. For other cross-thread communication,
we try to synchronize using other methods that do not incur a
significant performance penalty.
Window resizes triggered via the emulation loop synchronize with the
`_needsResize` atomic. Status messages are passed by acquiring the
`messageMutex`. `vBlanksPerSecond` is also now an `atomic<u64>`.
Input continues to poll on the main thread for compatibility with
existing code. Access to the input system is managed via `inputMutex`.
### Known Issues
Draft status as this is still a work in progress, but PRing now for
visibility, feedback, and to consolidate any issue tracking. There are
likely kinks left to work out; testing is appreciated.
~~- Cores are loaded on the main thread before being run on the emulator
thread; this causes issues for paraLLEl-RDP, which expects that the
thread to initialize Vulkan is also the thread that will make RDP
calls.~~ Addressed.
~~- Memory editor currently does not have access to the program mutex;
reads and writes are unsynchronized.~~ Addressed; memory editor
synchronizes on writes but reads occur in a thread-unsafe fashion.
~~- The Clang thread sanitizer still reports a couple data races in
Metal and OpenGL; further testing with other Ruby drivers is needed to
make sure resource access is properly managed, particularly with respect
to the output framebuffers.~~ A larger examination of locking in other
parts of ares is probably necessary, but I think out of scope for the
first iteration of this rework.
- The gdb server seems to still be working fine, but could probably use
more testing.
The SD/HD/UHD options represent scaling the internal N64 resolution to
1x/2x/4x. Even for a title running at 640x480, this results in 1280x960
and 2560x1920 which doesn't match the meaning of HD/UHD. Games running
at lower resolutions give even more out of whack results. New label
communicates more explicitly what the option actually does.
I didn't change the string used to serialize this option in
`settings.bml`. Feedback welcome on whether I should do that.
Metal checks whether librashader handles are non-null during
deinitialization to determine whether to call librashader's `free`
functions on them.
If the handles are initialized to contain junk data, they will be
non-null but `free` will fail, causing a crash during the deinit that
occurs prior to any initialization of the video driver.
On Apple Silicon, the system malloc implementation provides something of
a guarantee that heap allocations are zero-initialized, but this proves
to not always be the case in practice. There are also no (or fewer) such
guarantees on x86_64.
On OpenGL, these pointers were already being zero-initialized.
When the CPSR mode field is set to an invalid mode, SP (R13), LR (R14),
and SPSR are not mapped to any register. Therefore, writes to them
should fail, and reading them should return zero (or 0x00000010 in the
case of SPSR).
Update: Also implemented a new edge case for BX instructions, where
setting bit 22 causes SPSR to be modified rather than CPSR.
* Fix a regression where the application manifest was not embedding
properly on Windows, leading to various problems including incorrect UI
styling and DPI settings
* Fix an issue where we would fail to parse a canonical version from a
`git describe` string without a suffix
* Update SDL to 3.2.14, containing miscellaneous bugfixes
* Update librashader to 0.8.1, which should address a rare crash with
bad shader caches on Windows
* Update slang-shaders to its master branch contents as of 5-21
(8c630e0d3234d93b6c2bc847371f86aa4e535686)
* Update MoltenVK to version 1.3.0
Add explicit support for CMake 4.0 version policies; the only change
required is to remove a superfluous/invalid POST_BUILD designation from
Linux bundling code.
Also add .DS_Store to the .gitignore, since developers may possibly
still be on systems old enough to litter these everywhere.
Fixed an issue where an undefined opcode was being treated as an
unconditional branch in Thumb mode, and added a destination register
field to ARM mode BX instructions.
- Fixes an edge case involving overflowing audio FIFOs
- Slight FIFO channel timing improvements
- Prevents most APU registers from being written while audio is disabled
- Fixes writing to wave RAM while audio is disabled
ares' build system tries to always have version information available
for debuggability and build tracking. It depends upon the presence of
Git to provide version information, since Git is the version control
system used by the project.
When distributing tarballs of ares, however, no `.git` directory and no
inherent version information is included in-tree, which causes the build
to fail with a vague fatal error after failing to derive a version for
itself.
Since we would like building a tarball to be at least possible with
minimal fuss, we should provide some version information inside a tar
archive served by GitHub. This PR uses Git's
[export-subst](https://git-scm.com/docs/gitattributes#_export_subst)
attribute to automatically bundle version information when `git-archive`
is run against the repository, as is done when the GitHub API serves a
tar archive of a given release, branch or commit. The build system will
check for the presence of this file if it finds that there is no `.git`
directory at the root of the repository.
This PR also improves the version handling in general to better support
semantic version strings of the form `v123.x.y`, in case future releases
of ares require hotfixes or minor versions.
The [Windows signing action used by
ares](https://github.com/Dana-Prajea/code-sign-action) fails under
clangarm64 due to having the wrong path for `signtool.exe`.
This PR swaps the clang-cl arm64 Windows build back into the
primary/nightly workflow until we have a fix for clangarm64 codesigning.
Includes:
* Stop vendoring the librashader header on Linux
* deps.windows: Update librashader to 0.6.3
* deps.macos: Update librashader to 0.6.3
* Update slang-shaders to ref 25311dc
* Pin Rust nightly to version contemporary with librashader version
* Establish macOS deployment targets
* deps.macos: Update SDL to 3.2.10
* deps.windows: Update SDL to 3.2.10
Serialization for the MD, specific to the ym2612 audio implementation was changed, but there wasn't a version bump. This corrects this missing contribution.
As part of the boot security, IPL2 (run by CPU), PIF and CIC collaborate
to verify that the IPL3 (stored at the beginning of the ROM) is valid
and not tampered, by running a checksum. If the checksum is invalid,
the console is halted immediately.
Ares emulates this behavior correctly. Sometimes, though, it might be
useful for development purposes to let some ROM boot even with a failing
checksum. Given that disabling the check was non-obvious, I'm adding
an accuracy compile-time flag for now.
- the noise LFSR reset bit takes effect immediately
- channel period counters tick only when they're enabled, including
if channel 2 is in voice mode or channel 4 is in noise mode
- the noise LFSR only ticks if channel 4 is enabled in noise mode
All commercial ROMs in N64 have the value 0x80371240 in the first 4
bytes. This has long been used by emulators both as a magic number to
"detect a N64 rom", and as a way to detect endianess of the dump.
In reality, the first byte (0x80) is unused/ignored by the console, while
the other 3 (0x371240) are just parameters used to configure cartridge
access (basically, ROM speed). There's absolutely nothing that prevents
a ROM with other values to boot. Ares currently fails to honor this
by refusing booting ROMs with different values, but this is just wrong.
To fix this, we change approach and use the CIC detection algorithm to
also detect the endianess, given that it's based on a checksum match.
If we can't find a match, we tried the two common types of byteswaps,
hoping to find a match. Eventually, we fallback to assume it's a
big-endian dump, and needs the common CIC-6102.
This means that analyze() will now only reject ROMs with size lower
than 4 KiB, but that's correct. Given that 4 KiB are loaded by the
IPL2, we assume that minimum size is required. Besides that, there is
nothing else in the ROM that can be used to "detect" a N64 ROM, so
it's correct to just let it boot and see what happens.
Fixes using the same rom file on both GB and GBC hardware without losing save-data between them
Fixes Pokemon Stadium when loading a .gbc rom (the Transfer Pak only used the GB path)
Existing users using a custom save game path will have to manually move their saves from "Game Boy Color" to "Game Boy"
Users using the default "Save alongside rom files" will not have to take any action.
- SH2 memory windows have been adjusted. The framebuffer areas must be mirrored up to 0x5ffffff -- fixes Toughman Contest backgrounds.
- VDP FEN & PEN flags are closer to accurate but still missing some finer timing details.
- FEN/PEN status may block vdp memory accesses. The docs seem to indicate that accesses may be held in wait until a status change, but thats not totally clear (nor validated?). For now, these accesses are blocked and logged in debug.
- FM setting (framebufferAccess) only allows vdp access by either 68k or SH2-side, so additional guards have been inserted for cram/framebuffer accesses. VDP reg accesses should be blocked as well according to docs, but this aspect needs to be reviewed.
- VDP reg latching has been implemented. The timing isnt completely accurate, but should be decent enough for now. Fixes Mars Check image test (corrupt lines from mode switching).
- Autofill timing has been implemented according to the docs. For now, this is just signaling via the FEN flag. Fixes MK II glitching et al.
Minor changes:
- Run CI for pushes to any branch, not just master. This is mostly
relevant for forks, where you will often want CI on WIP branches.
Releases still check that they are on the master branch and won't be
generated for other branches.
- The GCC `stringop-overflow` heuristic still seems to be buggy,
tripping in seemingly irrelevant areas, and in different areas depending
on toolchain/OS. Hence, just disable it for now; conforms with legacy
behavior.
- Fix a macro redefinition in the GTK CMake code
- Add a missing "included" source to the desktop-ui CMake code so it
shows up in IDEs
- `gersemi` formatting pass
Lastly:
Allow generating DWARF symbols in MSYS2/MinGW environments. This is
controlled by the cache variable `ARES_MINGW_USE_DWARF_SYMBOLS` (on by
default only for GCC, inoperable under MSVC/Clang-CL). This allows for
easier use of gdb or lldb for debugging on Windows. The support here is
considered incomplete but functional for debugging the main ares
executable.
In particular, we do not generate DWARF symbols on Windows in ares-deps,
so debugging dynamic dependency issues with gdb or lldb will require
self-compiling dependencies. DWARF symbols are also embedded and this PR
does not ship them with releases. The "primary" Windows clang build will
continue to use CodeView symbols so that releases may be debugged with
WinDbg, Visual Studio, etc.
I am not satisfied with this level of support, but I am also not sure
whether "full support" for two independent debugging symbol formats on
one platform is a reasonable thing or a good idea to maintain. For one
thing, ares-deps targets the MSVC ABI for portability, where DWARF
symbol availability is limited. Targeting the GNU ABI in ares-deps would
mean reconciling multiple independent components' dependence on libc++
that would eventually need to be linked together. This might
theoretically be possible but in any case is not undertaken here. Also
not undertaken is the extant PDB functionality for stripping into
separate files, bundling, copying to the rundir, etc.
1. Revised pwm emulation, mostly to align with documentation. Not likely
to affect much except for rare edge cases. Also, added a dc filter to
prevent audio popping in certain situations (like window losing focus),
but pops on init are correct behavior. Fixes#937 by implementing
byte-wide fifo writes from the SH2 side.
2. Various fixups to 32x io access by the 68k. Fixes#1196 and missing
music in Brutal.
3. Follow-up to a previous PR: cram dots were not limited properly, and
line buffer adjustment was crashing 32x in certain cases (as reported in
the discord).
targeted 192 for ntsc and 224 for pal. Framing on top and sides is now
precise to active display. Sadly, only a few codemasters pal games
utilized 224.
In its current form, all games that use standard Aleck64 hardware should
function correctly, using the current MAME romset at the time of writing
(0.273)
The following games are known to be working:
- Eleven Beat
- Hanabi de Doon! - Don-chan Puzzle
- Hi Pai Paradise
- Hi Pai Paradise 2
- Kurukuru Fever
- Mayjinsen 3
- Star Soldier: Vanishing Earth
- Super Real Mahjong VS
- Super Real Mahjong VS (Rev A)
- Tower & Shaft
- Vivid Dolls
The following games are known to be non-working:
- Magical Tetris Challenge (981009 Japan): Requires custom video
hardware: boots but unplayable.
Known Issues:
- Games using EEPROM do not currently save their settings between
executions.|
---------
Co-authored-by: Darren Thompson <[email protected]>
At some point it might be worth going through the list of widgets to
understand which ones require WM_KEYDOWN messages to be forwarded by
Application_keyboardProc. For the time being, it's clear the HexEdit
widget is not among them, so this change disables forwarding for that
widget type.
As an added bonus, this change also makes the number pad functional.
- Fixes the nightly release so that the release body will contain the
latest commit message (only the first line). Tagged releases will now
also contain a description.
- Ignore a benign warning in sljit that was popping up in build
annotations.
- Fix a warning about a conflict in the `mia-ui` domain string on macOS.
> [!NOTE]
> Seeking testers on this to validate that errors appear correctly, are
accurate, and we didn't break anything.
### Description
Adds the `LoadResult` type, used to identify and propagate upwards
errors encountered when loading ROMs and systems.
Modifies the `mia` and `desktop-ui` load routines to use this type
instead of generic booleans, so that if we have a load failure, we can
propagate a precise and useful error to the user rather than a vague and
possibly mismatched one.
Currently the scope of the error handling is just `mia` and
`desktop-ui`; errors encountered when loading in `ares` itself are
currently generic "`otherError`"s. `LoadResult` is placed in
`mia/mia.hpp` so it is accessible to both `mia` and `desktop-ui`. If
LoadResult is added to ares loading in the future, the LoadResult type
may need to be moved.
This is a minor reorganization of the new CI to be more modular and use
more organized patterns. Rather than one large all-in-one workflow,
items are now split slightly into discrete parts. Namely, there is a now
a PR workflow called for PRs, and a push workflow called for pushes to
the master branch, which in turn call constituent workflows for builds
and releases.
This enables a few conveniences:
- Workflows are split into concurrency groups that will automatically
cancel themselves. For example, if a PR is pushed multiple times in
succession, CI will be automatically canceled for all but the most
recent push.
- Permissions are applied discretely and in a somewhat more organized
way. The PR workflow simply has the "read" permission, while the master
push workflow has the "write" permission.
While the existing all-in-one workflow was not insecure, it relied on
GitHub Actions failsafes (such as pulls from public forks not being
granted write permissions nor secrets) in order to work properly, which
has the side effect of making the workflow's logic somewhat more
difficult to understand.
- New workflows can hopefully be more easily created based on
constituent parts. For example, the PR flow simply executes "build",
while the push workflow simply executes "build" as well as "release".
Future workflows could, for example, "build" and then call a new "test"
workflow to execute the test harnesses using the built artifacts and
report results. This can now be done without requiring as much delicate
attention to the existing workflow logic.
Future work:
- Ideally our "build" workflow could be refactored into a composite
action rather than a workflow. This would enable it to use defines
created in the initial "pull" or "push" workflows more easily, allowing
us to cleanly separate, for example, codesigning-related steps that
install secrets on the build machine, from actual build steps/jobs.
> [!NOTE]
> This was tested on a local fork, but several minor changes were made,
so it's opened as a draft until it can be double checked that nothing
broke.
While looking at something else I noticed that we were not respecting
the stored value of the "Force sRGB" option on startup. As a result we
would always output in sRGB unless the user explicitly modified the
option during the session.
There are numerous headers in Mega Drive & 32X games that are not
correct resulting in PAL games to run at 60Hz instead of 50Hz. This
corrects this issue by using the same technique the Atari 2600 core uses
which is to look for "(PAL)" or "(Europe)" in the ROM name which will
then force the game to run as a PAL game.
This also addresses the 32X game Shadow Squadron - Stellar Assault which
is supposed to be an NTSC-U and PAL game, but only has PAL in the header
so it could only run at 50Hz. This adds NTSC-U as an option (leaving PAL
as the default), but can be selected using the "Prefer US" boot option
so it can run at 60Hz.
Addresses issues:
https://github.com/ares-emulator/ares/issues/1066https://github.com/ares-emulator/ares/issues/1067
And yes, I'm aware I submitted an additional commit cause I spelled
Assault wrong in the comment, and managed to spell it wrong again in the
commit message. 🤦♂️
Fix macOS CI on pull requests by persisting if we fail to import the
certificate (as expected). Notarization should expectedly fail as well
on pull requests, if it tries to run.
(Whether CI succeeds on this is the testing)
It's already expected that nall/main.hpp will only be included in a
single file, so we may as well define main at the same time. This allows
the console/Windows subsystem distinction to be controlled on a
per-target basis instead of being compiled into nall.
Targets that should always build as console applications now set a
CONSOLE variable in their CMakeLists.txt, overriding the cache variable
of the same name. The remaining targets can still be controlled at
configure time by passing -DCONSOLE=1, which will compile everything as
a console application.
1. The cycle update order needed clean up, mostly to fix feedback.
2. Envelope update function was also reordered to avoid double update
issue.
3. LFO behavior was corrected (should apply proper attenuation when
disabled).
4. To avoid potential update issue, rate scaling was lightly refactored.
Avoids recalc of key scale factor and renames keyScale to rateScaling
(RS) for clarity.
Related issues: #1159, #1112
Run the new CI on pull requests (and not just the old one) so we can
catch bugs and failures, take advantage of new inline annotations, etc.
Working on a slight refactor of CI in general to make it
better-organized, but seems worth PRing this first before that is
complete.
For each emulator core with a `.bml` file in the Database folder
packaged with ares, this PR adds a separate check in their mia `load`
functions to verify that their database file exists on disk. If it does
not, we bail out of the loading process.
Meanwhile, in desktop-ui, if loading failed, we will now throw up an
error.
This PR stops short of adding fully robust error handling to the load
routines; the error message we throw up is generalized, and will appear
for anything that causes loading to fail, not just specifically database
files not being found. I think that the database files should be by far
the most common cause of load failure, so this seems OK to me for now,
but could certainly be improved in the future to provide more specific
errors. I obviously welcome feedback on how to handle any aspect of this
better.
Changes the regex used to determine our macOS SDK version to match on
Command Line Tools install paths and not just Xcode install paths, since
we do not require Xcode to build ares, just the Xcode Command Line
Tools.
Also fixes up how we handle the macOS deployment target.
(boring details below)
CMake is meant to transparently derive and pass appropriate compiler
options for our minimum deployment target. It does this via the
`CMAKE_OSX_DEPLOYMENT_TARGET` variable. This variable can be initialized
either by the project (which must happen before the `project()` call),
or else as part of the `project()` call, CMake will inherit it from the
`MACOSX_DEPLOYMENT_TARGET` environment variable, or else "compute it
based on the host platform" (whatever that means).
Our desired behavior is to set it to 10.13, except for local builds,
where we should respect the MACOSX_DEPLOYMENT_TARGET environment
variable (if it is set). This PR enables that behavior.
---------
Co-authored-by: invertego <[email protected]>
By default the SDL audio driver would initialize with a latency value of
0; this doesn't crash, but it ends up causing an unpleasant stuttering
and hitching, which is a bad default.
Also makes Metal the default driver on macOS.
> [!IMPORTANT]
> This alters default behavior for configuration on Linux that
maintainers should be aware of.
Introduces `ARES_BUILD_LOCAL` on Linux, enabled by default, that will
pass `-march=native` if enabled. Maintainers will probably want to
disable this. Also adds `ARES_ENABLE_MINIMUM_CPU`, `ON` by default, that
compiles with the previously enforced `x86-64-v2` minimum on x86_64.
Maintainers should do whatever they want with this option.
(@bsdcode @Mastergatto)
These changes are intended to give Linux users building from source a
better experience. Enabling x86-64-v2 compared to compiling without any
SSE functionality is a 10%+ performance loss locally in the N64 core,
and may be higher on actual x86_64 machines.
> [!NOTE]
> It is worth noting that even though we do not explicitly define a
minimum SSE functionality on arm64, in practice nall will still [define
`__SSE4_1__`](https://github.com/ares-emulator/ares/blob/e808d2c5ab5be91d3e1035063892e8c5115d25e2/nall/intrinsics.hpp#L232)
and take advantage of SIMD on that platform via sse2neon.
### Other changes
* Adds `-march=native` on macOS builds under the control of
`ARES_BUILD_LOCAL`, and fixes `ARES_BUILD_LOCAL` on Windows so that
`-march=native` is added under gcc and not just clang.
* Removes warning in the N64 core related to the issue caused by strict
aliasing under GCC.
* Fixed an issue where macOS would always generate for arm64 rather than
the host architecture.
* Ran a formatter pass that was previously missed on the CMake code, so
there are a couple miscellaneous formatting changes.
This change corrects two regressions introduced by my last change.
1. The purge() call in SH2::Cache::power() was, through a call to
Recompiler::invalidate(), accessing the pool array before it was
allocated.
This purge call was erronous for two reasons:
- It was purging a single line, though it *appears* the intent was
to purge the entire cache.
- According to the SH7604 manual, the cache is not initialized on
reset.
Therefore, I simply removed the call.
2. The size of the recompiler code cache for both of the two SH2s is now
halved to fit within the recently halved fixed code cache buffer. The
SH2 recompiler is good at reusing previously compiled blocks, so flushes
should not be especially common even with this reduced capacity.
- Reduce the code cache allocation from 128 MiB to 64 MiB. The CPU/RSP
split is now 63/1 instead of 64/64 (which was egregiously generous to
the RSP) so this should have little practical impact on cache flushes.
- Convert some larger static allocations to heap allocations to shrink
the ares executable's data section.
These changes increase the likelihood of the entire code cache being
within 128 MiB of the ares executable's text section, allowing for more
efficient branch encodings on ARM64 and better performance from the host
CPU's branch predictor.
Non-strict aliasing is found to resolve
https://github.com/ares-emulator/ares/issues/1737.
We also use signed integer overflow around ares, so we want to allow the
compiler to optimize for that if it wants to; essentially everywhere
ares runs is two's complement.
Couple quirks: Xcode has its own declaration for strict aliasing, so use
that. Clang-CL doesn't transparently accept `-fwrapv`, so it's passed
with `/clang:-fwrapv`.
`_ares_gcc_common_options` will eventually see more development to make
warnings consistent across platforms where possible.
(Fixes https://github.com/ares-emulator/ares/issues/1737)
Cmake based builds don't disable as many checks as the old make files,
so there were a few new warnings clang was showing during the Windows
build about unreachable code in mia.cpp & desktop-ui.cpp that are now
fixed (it would fall through properly on other OSes). Note that there
are still two remaining warnings about unreachable code during the build
but this is within zstd included in libchdr so this needs to be
addressed upstream.
A user trying to compile ares made a single post in the ares Discord
channel about a warning they were receiving during the link phase about
an overflow. I've never seen the warning or remember anyone bringing it
up so I asked about OS/compiler (I know it was Linux flavored cause they
mentioned working on an AppImage) but they never responded. I think they
were using openSUSE, but it is interesting this wasn't flagged anywhere
else. We were assigning an enum value to a Color struct in
table-view-cell.cpp which wasn't correct, so this has been fixed.
Finally, SuperMikeMan100 pointed out that when the controller combobox
in Settings > Input didn't fit entirely on the screen, you couldn't
scroll to the bottom of the list (Windows issue). They also pointed out
the fix needed in combo-button.cpp which I've tested and have included
the fix for it here.
First commit stops notarizing the legacy build; for some reason
notarization currently
[fails](https://github.com/ares-emulator/ares/actions/runs/12626365618/job/35179407527)
only with the legacy build, despite us not having modified the legacy
workflow. In any case it seems fine to no longer notarize this artifact.
Second commit allows the new build CI to continue if the repository it
is being run on does not have macOS codesigning set up. This means CI
won't automatically fail on your fork if you do not have macOS
codesigning set up on your repository.
Many parts of ares are compiled as a single translation unit in a "unity
build". Targets such as `hiro` and `ruby` directly compile only one
file, `hiro.cpp` or `ruby.cpp` (or `hiro.mm` and `ruby.mm` on macOS),
which `#include`s all other files beneath it in a branching fashion. By
contrast, in the `ares` target, each area of each core is generally
compiled as a separate translation unit, with lots of redundant
inclusion of common headers. This allows for faster "development cycle"
build times; if a small change to one part of the core is made, we do
not need to recompile the entire core.
Despite slower incremental build times, compiling each ares core instead
as a single translation unit has some benefits.
We can lower build times by a decent amount:
| Build | Build time (multiple units) | Build time (single unit) |
|-----------|-------------|-----|
| `ares-windows-x64` | 9m16s | 6m47s |
| `ares-windows-clang-cl-x64` | 11m3s | 8m23s |
| `ares-windows-clang-cl-arm64` | 12m29s | 9m20s |
| `ares-macos-universal` | 13m33s | 8m12s |
Not only that, but single-unit builds also seem to confer a minor
performance benefit, presumably due to more effective link-time
optimization.
On macOS arm64:
| Game (core) | VPS (multiple units) | VPS (single unit) |
|-----------|-------------|-----|
| Knuckles Chaotix (Mega Drive) | 101-102 | 108-109 |
| Snowboard Kids (N64) | 66-67 | 69-70 |
Last but not least, we can actually arrange for single-unit builds
without any code-level changes to existing ares source files. We can
simply add a `<core>.cpp` file for each core that includes each
'primary' `.cpp` file that would otherwise be directly compiled; due to
the magic of the `#pragma once` compiler directive, redundant header
inclusions are eliminated in the unity build, but compiling still works
normally if we are compile as multiple units.
Given that there were no significant issues adapting existing code to
compile this way, it seems worth considering adding this functionality.
It can disabled for default configurations transparently (to enable
faster incremental builds during development), but enabled on CI for
faster builds and a modest performance benefit.
* Fix a bunch of miscellaneous name deprecations
* Fix deprecated modal file handling patterns; use the `URL` properties
rather than the ones for paths
* Remove the Gatekeeper bypass menu item
* While the idea here was quaint, it's very dated, the approach doesn't
work at all on modern macOS (and would be a significant exploit surface
if it did), and the functionality is somewhat outside the scope of the
ares application in the first place. It won't remove Gatekeeper
restrictions on ares itself, since if we're using the menu item, we've
already made it past Gatekeeper. Functionality to disable Gatekeeper in
general for other applications is, again, maybe nice in an abstract way,
but well outside our scope.
* Suppress OpenGL symbol resolver deprecation warnings
* Fix protocol warnings in `CocoaMenu` that revealed a mistaken design
pattern:
* We had both a protocol and an interface called `CocoaMenu`, and our
Cocoa hiro menu subclasses were declaring that they adopted the
`CocoaMenu` protocol, rather than what was almost certainly intended, to
be subclasses of `CocoaMenu` which would itself conform to the protocol
by virtue of being an `NSMenuItem`.
* In effect, this meant that each CocoaMenu subclass interface was
telling the compiler it wanted to reimplement the `NSObject` protocol
rather than be an `NSObject` subclass. This may have resulted in various
typical properties of `NSObject`s not being present, and various methods
(such as Accessibility) entirely not working.
Linking was failing under MinGW gcc because of a link order issue
between `libares` and `mingw32`. Establishing a direct link relationship
between `desktop-ui` and `mingw32` means that our `WinMain` definition
will not be discarded by `ld` before it's needed.
We also here add a Linux gcc runner and a Windows gcc runner; these do
not upload artifacts, but will allow us to detect build failures on CI.
At the moment, gcc support in general under CMake will still rougher
edges than clang or MSVC support, but it is intended that building with
`gcc` and `ld` should always at least work, even if `clang` remains
recommended and achieves superior performance.
This PR also adds a warning in the N64 core to acknowledge
https://github.com/ares-emulator/ares/issues/1737 until that issue can
be fixed.
Co-authored-by: John Tur <[email protected]>
`fetch-tags: true` only works within the specified fetch depth.
`fetch-depth: 0` fetches more than necessary, but seems to be the
simplest way to guarantee we actually fetch the latest release tag
needed by CI.
See also: https://github.com/actions/checkout/issues/338
For various reasons, OpenAL on Windows is not supported. If we do manage
to find it and link against it, the build we produce is unlikely to work
outside of an MSYS2 command line environment, so we should just disable
it.
If we ever want OpenAL support on Windows, we would need to either
locate a version that depends only on Windows system libraries (i.e.
does not dynamically load libc++ or other MSYS2 libraries), or else
build and provide OpenAL ourselves as part of `ares-deps`.
- Completes #1498 -- dots should be clearly visible in overscan areas
normally. If you notice odd dots appearing on top of games irregularly
(inbounds, non-overscan), please mention it. The Direct Color DMA demos
(https://gendev.spritesmind.net/forum/viewtopic.php?f=8&t=1203) should
be stable for the most part (note, they are very timing sensitive).
- VDPFIFOTesting rom should run without any failures. Previously,
16-FIFO Wait States was the only failed test.
- Both Titan Overdrive demos should run cleanly. There were a few minor
wrinkles that needed to be ironed out.
- Fixes#1075 -- there was a minor adjustment for a window edge case in
H32 mode. Unlikely to affect other games.
- Fixes#1061 -- looks pretty clean now.
- Fixes#626 -- I don't notice anything weird currently, just some minor
fringe in the left border, not visible when overscan is disabled.
- Review #1675 wrt md -- there are no parts of the active display area
that are currently cropped out. There was an unreported issue with Exo
Squad (E) that had clipped the topmost lines in PAL V30 mode (observed
on the copyright screen) but that has been fixed.
- Fixes an unreported bug in 32X PWM sound (right channel was missing),
typo from previous commit d7dfae7a7a.
* Remove version overrides from CMakePresets.json
* These were necessary for CI to run when CMake existed on the forked
branch, but *should* no longer be necessary
* Disable release flows for the legacy build
* Keep legacy builds running for the time being, but disable the release
flow so it does not conflict with the new CI
On some Linux and BSD distribution, Ares from the repositories may not
come with shaders preinstalled. Instead, these one may come from another
package, for example on Archlinux the package `libretro-shaders-slang`
installs the shaders in the following path:
`/usr/share/libretro/shaders/shaders_slang/` .
This will make Ares fail to load any shaders on these distro. So to fix
it, this PR adds the aforementioned location as another path to search
for, as a fallback.
I know, the two dots are a bit ugly, given that locate() normally
doesn't search for files or directories outside of those of
Ares...Ideally, locate() should be expanded to search the entire file
system, but I'm afraid the required changes may be a bit more far
reaching than expected.
This PR introduces a new CMake-based build system for ares.
Broadly, the goals of this build system are to:
* Modernize the build process somewhat, and make ares more approachable
for new developers
* Improve ares's dependency handling
* Expand and standardize platform/compiler/architecture support for ares
* Improve project code quality
* Improve build performance
* Lay groundwork for easier support of more platforms in the future
There are a few notable changes that this PR brings about. Briefly:
* Dynamic dependencies (librashader, MoltenVK, SDL, slang-shaders) are
no longer built in-tree
* Build system generation and building now take place as two separate
steps
Other notes:
* The legacy build system is deprecated, but is planned to still
function until such time as it is removed in a later PR
# New Features
* ares can now generate projects for Xcode and Visual Studio 17 2022.
Xcode is the recommended generator on macOS, supporting universal
binaries, advanced profiling and GPU debugging. Visual Studio projects
can be configured with either Clang-CL or MSVC, and may be generated for
either x86_64 or arm64.
* On macOS and Windows, dynamic dependencies are now built by
[ares-deps](https://github.com/jcm93/ares-deps) and fetched at
configure-time. This is to reduce build requirements for development,
define explicit versioning for dependencies, reduce build times
generally, and streamline CI workflows.
* Builds can now be configured through the default Windows command line
rather than requiring an MSYS2/MinGW shell.
* Ccache is also now universally supported to improve build performance.
Compile times should be further reduced with the addition of
precompilation of certain headers.
* A variety of other build system generators are now supported on all
platforms, including multi-configuration Ninja and applicable types of
Makefiles.
* Compiler diagnostic flags with clang have been standardized across all
platforms where possible[^1]. Currently, diagnostic flags have rough
parity with the old build system, but one goal of the new build system
is to introduce more strict compiler settings, to eliminate certain
classes of bugs and generally increase code quality.
# Supported Platforms
ARM64 and x86_64 architectures are officially supported across macOS,
Windows, Linux, and BSD[^1]. clang, Clang-CL, gcc, and MSVC are all
supported on applicable platforms. MSYS2/MinGW is supported along with
configuration and builds via the default Windows shell.
32-bit builds have not been tested.
# Current Status
Builds across all three of macOS, Windows, Linux, and BSD are generally
expected to work. Detailed build instructions can be found on the new
[ares wiki](https://github.com/ares-emulator/ares/wiki). CI workflows
are present and implemented but are still a work in progress. More
complete documentation is also a work in progress.
#### macOS
* Xcode, Ninja, Ninja Multi-Config, and Makefile generators are
functional
* Unlike Windows, multi-architecture builds are supported; pass
`-DCMAKE_OSX_ARCHITECTURES` as appropriate.
* Builds should generate a fully functional and relocatable app bundle
within the build directory, with relative rpaths; `install` rules are
placeholders.
#### Windows
* Visual Studio 17 2022, Ninja, Ninja Multi-Config, and Makefile
generators are functional
* Only single-architecture builds are currently supported
* Similarly to macOS, the build step generates a fully functional and
relocatable rundir with placeholder `install` commands.
#### Linux / BSD
* Unlike on macOS and Windows, it is required that the developer have
packages installed for libraries ares links against. A list of required
and optional libraries is found in the README.
* Build will output to a staging directory `rundir`; ares only uses
system libraries so this rundir should be fully relocatable
* `install` will perform a standard installation as CMake deems
appropriate for your distribution; you may pass the `--prefix` argument
as needed
* Maintainers may package as appropriate; a new Flatpak may be created
as part of this process, but has not yet
> [!IMPORTANT]
> These tasks should be completed before this PR moves out of the draft
state:
>
> * ~~CI workflows~~ - incomplete
> * ~~BSD support~~
> * ~~Windows SDL added to ares-deps~~
> * ~~ares-deps should probably be migrated to the ares-emulator
organization~~
> * More documentation
> * Miscellaneous cleanup, fixing issues found in testing, incorporating
general feedback
Nevertheless, now that builds are functioning on all three platforms, I
wanted to get this PR out there in a draft state to solicit testing and
feedback, as well as to give Linux package maintainers a head start in
terms of packaging.
> [!NOTE]
> While the PR is in a draft state, there may be breaking changes,
things may temporarily stop functioning, commits may be squashed, etc.
Thank you for testing and please report any issues you encounter!
* More detailed documentation on the internals of the build system is
available
[here](https://github.com/jcm93/ares/blob/cmake/cmake/README.md).
### Miscellaneous changes/points
* .gitignore is reorganized
* [gersemi](https://github.com/BlankSpruce/gersemi) is used for CMake
formatting, hence the presence of a `.gersemirc` file
* SDL on Windows is now a dynamic dependency.
* macOS asset files are reworked into .xcassets archives
* new macOS local build script introduced
* CI will include debug symbols for easier crash debugging
[^1]: Indicates something that might not be finished yet, or is subject
to change
---------
Co-authored-by: invertego <[email protected]>
Co-authored-by: Stefan Schlosser <[email protected]>
Co-authored-by: John Tur <[email protected]>
This commit ensures that changes to the FDS disk get saved when the
Famicom system saves (similar to how the 64DD works already). Without
this, changes to the FDS disk were only written back to the pak in
FDS::disconnect, _after_ the save on unloading/exit or any periodic
autosaves.
This PR adds the hex editor widget to Cocoa hiro and enables the memory
editor in Tools. The widget is a cell-based NSTableView with data source
the core hex editor widget and supports editing of memory (but not of
the encoded ANSI).
---------
Co-authored-by: jcm <[email protected]>
This commit implements correct VI timings using VI registers rather than
hardcoding the behavior for the default presets made by commercial
games. This makes Ares behaves correctly, timing-wise, also with non
standard timing like eg: the so-called PAL60 mode.
Moreover, it fixes VI interrupts in interlaced mode to happen on the
exact scanline they happen on the hardware, including known hardware
bugs.
The pixel accuracy setting will now emulate the sub-pixel timing
behaviours for bitmap and affine backgrounds described in [fleroviux's
PPU
docs](https://github.com/nba-emu/hw-docs/blob/main/src/ppu/background.md).
This PR also splits the PPU into two separate libco threads: one for
rendering and one for raising IRQs and starting DMAs. This allows the
CPU and PPU to be run more asynchronously, which helps mitigate the
performance cost of finer-grained PPU emulation.
Instead of advancing RSP DMA only after each CPU basic block, allow it
to run between each RSP block. This prevents the RSP from racing with
the DMAs it initiates in the event of a long running CPU block (which
can trigger multiple consecutive blocks of RSP execution).
This fixes hangs in Tarzan and possibly other games that use MusyX.
Another observable side effect of this change is that when the RSP is
halted, it no longer risks falling increasingly behind the CPU, because
ares will now step multiple times if needed instead of just once.
The "Type" column in the Settings > Firmware table view was being set to
false by default. As there is no visibility handling for columns in hiro
for Windows or Cocoa, this column would always be visible. But in the
hiro GTK table view definition (there is also a visibility
implementation for Qt) it did contain a function to disable/enable a
specific column so this column would be absent on Linux distros making
it look like there were duplicate entries in the table. This PR removes
removes the call setting visibility by default so that the column is
always visible.
Co-authored-by: remutro <remulationtro.gmail.com>
* Remove `macos-compat`, since the macOS 12 runner is no longer in
GitHub Actions, so we can no longer target macOS 10.9
* Rename the macOS build to "macos-universal", reflecting the OS and
arch
* Don't install `make` via brew any more, since it isn't necessary
* Establish the macOS version minimum as 10.13
* 10.9 was not a proper target, because of `fstatat` usage, which isn't
available on macOS 10.9. On a code level, we may technically be
compatible with macOS 10.10, but because no available build environment
can target this macOS version, it makes no sense to support it without
being able to test it. Since we can deploy for macOS 10.13, just
establish this version as the minimum. If someone wants to compile
themselves for lower macOS versions, they should still be able to.
* Increment the macOS runner for the primary macOS build to macOS 15,
and the Xcode version to Xcode 16.1.
* Better to explicitly pick the macOS and Xcode version rather than
using `macos-latest` as the runner, even though they refer to the same
thing, just so that we have explicit versioning wherever possible.
Not tested; CI run needed.
If you choose to select a new driver without pressing the Apply button,
and then go ahead and update related options for the currently loaded
driver then the combo box will revert to the currently loaded driver but
leave the Apply button enabled indicating the user has to do something
when they do not. This changes this behavior so that if options are
changed and the driver is reverted back to the current driver the Apply
button will be disabled again.
Brings back the Pseudo Full Screen option present in bsnes as a
configurable hotkey.
I'm also including the type mistake pointed out for the colorWidthBleed
value someone pointed out so we don't lose track of it.
Fixes test cases in the dma_speed_test rom.
1. "*VRAM TO ROM" is a dma load to a VRAM read target, which doesn't
have any effect. Though, for timing purposes, it's similar to a VRAM
write (1 byte access per slot) so fifo throughput is the limiting
factor.
2. A VDP refresh blocks bus access for 2 consecutive slots, slightly
affecting dma load transfer rates.
Random fix from CMake work.
Precompiled headers under CMake are currently buggy and unreliable on
Windows, largely because the precompiled `<ares/ares.hpp>` header
includes `<ares/resource/resource.hpp>`, which is generated by
`sourcery` as part of the build process.
While sourcery will almost never meaningfully change the contents of
this `resource.hpp` file, Windows may insert its own line endings
depending on the user's environment, and despite enforcing uniform line
endings as part of our `.gitattributes` file, some compilers will throw
a fit about the precompiled header being modified from underneath it.
Since the `resource.hpp` file is simple, short, and not included in that
many places, we can just refactor it out of `<ares/ares.hpp>` without
issue, and precompiled headers will work again regardless of system line
ending convention or environment.
Tested to build locally on macOS; CI run definitely recommended.
Fixes a few issues relating to open bus emulation:
- Accounts for cases where the last memory access was not an instruction
fetch
- For most memory regions, 8-bit and 16-bit accesses should be mirrored
along bus (except in IWRAM, where only part of the open bus value gets
overwritten, and the rest is carried over from the last IWRAM access)
- Open bus read alignment was not being respected in all regions
Following up on #1688 and #1575; removes the ARES_PREFIX preprocessor
variable and its use in `prefixSharedData()` in favor of a relative
path.
Passing a preprocessor argument to the program to define an install
prefix, which is then used to locate application data, is awkward and
overall not an ideal approach. Wherever possible, ares should have the
same behavior on the same classes of OS. Further, if we are to cleanly
separate ares's build and install steps, we shouldn't be defining
anything related to install locations at build-time. After building
ares, it should be able to be installed wherever the user wishes without
any unexpected changes in behavior.
Following the standard paradigm here means that on *nix systems, the
prefix's data directory would be, relative to the executable, in
`../share/ares/`. Hence, define `prefixSharedData()` from #1688 to
return this relative path appended to the executable path (given by
nall's `Path::program()`), instead of doing the preprocessor prefix
hooplah.
Tested on aarch64 Fedora; made sure ares can still locate the database
and shaders.
#1688 broke the build, and also did not actually perform one of the main
intended changes; reverting `sharedData()` to return "/usr/share/".
Second time's the charm!
### Context
https://github.com/ares-emulator/ares/pull/1575 ended up defining the
`sharedData` directory on Unix-like systems as `~/.local/share` if a
build prefix was not defined. This is not exactly correct; the meaning
of a "shared data" directory on a Unix-like system is variously
`/usr/share`, `/usr/local/share`, or else the `share` directory of a
given install prefix.
### Changes
This PR allows us to respect normal Unix conventions while also
respecting the option to build and install with a given prefix. This is
done by defining two more functions in nall's `path`:
* `localSharedData()` for `/usr/local/share`
* `prefixSharedData()` for `${ARES_PREFIX}/share`
`sharedData()` is changed back to the old behavior and returns
`/usr/share`.
Then, the `locate` logic in desktop-ui (and uh, mia) is adjusted to now
search (in order):
1. the prefix's shared data if the prefix exists
2. local shared data
3. system shared data
82bfc2d576 deps: update deps
7d7536f9fd rt(wgpu): approximate clamp-to-border with clamp-to-edge if not supported
9039a7c040 reflect: use FastHashMap for linkinputs pass
d8e35d4374 preprocess: add a test for include_optional
76347f63ac preprocess: add support for pragma include_optional
git-subtree-dir: thirdparty/librashader
git-subtree-split: 82bfc2d576d4c1a90339dcfba6c0163d5345b9c3
DDA was incorrectly capped at 16 bits instead of 24, making DMAs to
BWRAM banks 0x41-43 be sent to the corresponding spot in 0x40 instead.
See [the corresponding bug in
bsnes](https://github.com/bsnes-emu/bsnes/issues/309) for some more
context.
While checking out minimum requirements for the new build system, found
a couple small issues worth fixing:
* librashader was not operable on systems pre-macOS 12 with a linker
issue; it can be resolved by setting a minimum deployment target; here
we do that by setting an environment variable on CI.
* While investigating this, I found that librashader's minimum required
macOS seems to be 10.15; this is because `glslang` seems to require
macOS 10.15.
* It wasn't possible to build the Metal driver because of the older SDK
lacking some definitions; however, we can fall back to the
`__MAC_OS_X_VERSION_MAX_ALLOWED` compile definition which we do here.
* Not sure if building on these older systems should really be
considered "supported", but since the fix here was simple enough it
seems fine to throw it in.
paraLLEl-RDP and MoltenVK seem to have [a lot of
issues](https://github.com/user-attachments/assets/088879a9-9153-4b05-a207-212cfac7f831)
on my older system's GeForce 650M. I was able to compile debug MoltenVK
locally, but Xcode GPU capture just hung, so I was unable to figure out
what was going on. Either a driver issue or a MoltenVK issue seems like
the probable culprit. In any case, performance wasn't really good enough
to make me want to investigate further. Other cores seem to work well.
Tested [on my fork's
CI](https://github.com/jcm93/ares/actions/runs/11554703214) to make sure
everything still works.
The CACHE opcode does not work correctly when the specified virtual
address is in an uncached segment. The exact hardware behavior has not
been reversed yet (we know for instance that when doing cache
invalidation, some other cacheline is invalidated instead, but we do not
know the relation yet).
Nonetheless, the behavior is really obscure and all usages should be
considered bugs. Add a debug unusual warning for now (mainly to help
developers, as this is a known instance where Ares doesn't yet follow
hardware behavior).
Similarly to how the S-CPU and S-SMP are handled in the SFC core, it's
possible to run the GBA CPU and APU more asychronously as long as
synchronization is performed on FIFO or APU I/O accesses. From my
testing on Linux, this performs comparably to the performance profile
but without the accuracy downsides, so the performance/accuracy profiles
have been removed (the more accurate behaviour is now always used).
This PR also adds an option to disable pixel accuracy in the GBA core in
exchange for ~10-15% performance benefits, and makes some small PPU
timing improvements that were not feasible to implement in the
performance profile.
We want to allow arbitrary writes through the GDB server to the RDRAM
area. This was done in #1620, but that version has a subtle issue where
the server will still refuse to write or change writes that happen to be
of size `Byte|Half|Word|Dual` if the addressed is not aligned to that
size.
This PR fixes the issue by checking if the write is to RDRAM first,
allowing arbitrary and possibly unaligned writes. Otherwise, the write
is handled through the normal machinery where these issues may be
semantically important.
This pull request allows for all pak swapping on controller port 1 only.
It also enables support for the transfer pak for the 64DD which was
previously missing.
It is being added for port 1 only now because there is additional work
to manage all the different saves, and gameboy games/saves with the
transfer pak which is a larger effort, and Luke is currently looking
into modifying settings in a more complete manner. So other ports can be
added later. For most people, being able to swap for the first
controller is likely good enough.
This pull request doesn't change any of the current initialization logic
regarding default pak selection that already existed.
This is a change spun off from continuing build system work.
There, we've found that precompiling the `ares/ares.hpp` header can
speed up compile times for the emulator cores by 30-35%. Doing so,
however, leads to a few collisions:
* Several files in parallel-rdp use the `Hash` type, which variously
resolves to a `Hash` in its own namespace as well as nall's namespace.
* Also in the N64 core, nall's `noinline` macro conflicts with similar
definitions present in `xxhash`.
For parallel-rdp, we can simply skip precompiled headers for the
conflicting files; parallel-rdp does not use anything in the
`ares/ares.hpp` header, so including it there is unnecessary anyway.
This change resolves the second set of collisions by putting nall's
noinline preprocessor macro into its own namespace.
There are many macros remaining that are not namespaced. I did not
proceed in namespacing them for this PR, because there are a lot of
them, and it would be a fairly significant code style change that
probably merits further discussion (not to mention, it will be a decent
amount of work). However, in this instance, there is (or will be) a
material benefit that probably trumps the minor style issue.
Implements a couple improvements to OBJ-related timings:
- OBJs are now rendered one scanline in advance, as on hardware
- OBJ palette RAM accesses are now performed in `PPU::Objects::run`
rather than `PPU::Objects::scanline`, bringing OBJ PRAM access timings
closer to matching hardware
40 Winks was released aftermarket on physical media, and support has
been added for this (does NOT include prototypes). The US version was
tested, but was unable to test the EU release (game Id and pak options
should be the same and should theoretically work).
Additionally, looks like ares was missing some region descriptions, so
these have been added as well based on info located at:
https://n64brew.dev/wiki/ROM_Header#Advanced_Homebrew_ROM_Header
When debugging homebrew with gdb, it might be annoying if gdb stops at
exceptions that are correctly handled by the running application. This
is a bit hard to know so, besides providing some (debatable) default, we
need a way to selectively ignore specific exceptions.
This commit generates different GDB signals for different families of
exceptions. The mapping between MIPS exceptions and UNIX signals is
completely arbitrary; it tries to "sort of" match the meaning of the
exception where possible, and otherwise just use a random signal.
The GDB client can configure which signals should be logged, which
should cause the application to stop, and which should be ignored, using
the "handle" command.
By default, we want to ignore exceptions generated by interrupts (as
those are normally handled by the application) and those handled by the
operating system (like the COP1 exception which both libultra and
libdragon use to speed up context switching). To do so, we assign to
them signals that are ignored by default by gdb (SIGWINCH and SIGURG
respectively).
d334ab1a95 Fix left-shift signed overflows (UB) (#62)
434e793dc4 Assert that only valid timer numbers are passed to engine_timer_expired().
16e1d4281a Use snprintf instead of sprintf to fix#59. Use std::array for operators to remove the need for array_size.
4e654a3e8f Add virtual destructors to all base abstract classes, to prevent memory leaks (#55)
1a5cc66cb6 Keyon all ops on CSM mode (#56)
git-subtree-dir: thirdparty/ymfm
git-subtree-split: d334ab1a957351ce2a0aa2777b8c704664be3189
cbdbdafecd chore: Release
ffcb8ba1d1 doc: Update BROKEN_SHADERS.md
941275199b build: unpin cc
525c311844 cli: allow raw-id for spirv output
2fe66d958f reflect: put vars to end with running link pass to fix naga ordering
ed8bf637a9 cli: size_of not in prelude
7555bb9024 build: make librashader-reflect features-table more consistent
562e1e5f18 doc(msrv): bump msrv to 1.78
13b44e1639 cargo: revert lockfile version
240aae1bcf chore: Release
95a489ee12 cli(render): allow specifying output dimensions
git-subtree-dir: thirdparty/librashader
git-subtree-split: cbdbdafecdfd6113ef1cdc15e0a4140b46420f0b
We elect to just remove all usage of libra_viewport_t for Metal, since the current rendering path conforms better to recommended Metal patterns than passing the drawable texture directly to librashader would.
The libra_gl_init_context function has been removed. The OpenGL loader used to
create the filter chain, previously passed to libra_gl_init_context, is now
passed as a parameter to the libra_gl_filter_chain_create function.
The libra_output_framebuffer_gl_t and libra_source_image_gl_t structs have been
replaced with libra_image_gl_t.
The position of the viewport parameter in libra_gl_filter_chain_frame has moved
to after the output parameter, and its type has changed from libra_viewport_t to
libra_viewport_t *.
In order to retain the behaviour in ABI 1, output holds the width and height of
the previously used viewport and the viewport itself is removed and replaced
with NULL in the call to _libra.gl_filter_chain_frame.
4abd48eb24 capi(presets): support `d3d9_hlsl` VID-DRV
0007bd6d98 doc: update preset_ctx_set_runtime doc
72c72dafa0 capi(d3d12): remove unintentional IMAGE_TYPE infix for LIBRA_D3D12_IMAGE_TYPE
0fde712f3c doc: update librashader::reflect docs
2323b18710 capi(ld): add `LIBRA_RUNTIME_D3D9` define commented out
5978f95f76 reflect: make `ShaderPassArtifact` simpler as `PassResource` already includes the source data
3ee5e66c0d presets: make naming more consistent
f189468f6d ci: don't build cli for windows 7
fc47fb4c5a doc: typo
fc7739d9ab ci: update github actions
4a8a9ee444 chore: Release
756cbe63d9 cli: fix cli Cargo.toml
796b03b42b test: rework tests to work with ShaderPresetPack
742a1c8658 dep: update glslang
7c03a7e3fe doc(pack): reword doc on `ShaderPresetPack`
4ba6effc2f rt(mtl): fix test
32c99d9f4a rt: implement filter chain loading in terms of pack
75b70cc0e6 cli: add `pack` command to create a preset pack
828464c351 rt(image): helper to load image from shaderpack `TextureBuffer`
c19593e289 pack: implement shader pack library to preload resources from disk
1bbbd784d8 preset: make ShaderPassConfig and TextureConfig type aliases to PathReference
4273a833e8 pack: add librashader-pack
f14f45b3b1 rt: separate out meta information for textures
859d16e64e rt: separate out meta information to its own struct
b395b94a40 doc(abi2): add migration details for `libra_source_image_d3d12_t` layout
90a9ee754d doc: fix migration api typo
34b50059ca doc(d3d12,vk): clear up language for barriers
7a13136f9a capi(d3d12): allow d3d12 to optionally use a resource handle with chain-managed descriptors
0cb3880d7f rt(d3d12): allow construction of D3D12InputImage without a descriptor handle
c526b7043a capi(d3d12): change the layout so that descriptor is first in libra_source_image_d3d12_t
33d95ac399 rt(d3d12): allow creating input view without a CPU handle
40691cc406 rt(d3d12): allow creating output view from a resource ref
3c20c83bc9 rt(d3d12): use InterfaceRef for D3D12InputImage to avoid refcount for input image
b123f63a6e doc(reflect): fix link
4285ad2bd1 rt(d3d12): allow a pipeline to be available for multiple formats without recompilation
c57e502b78 rt(d3d12): make images with OwnedFramebuffer provenance use ManuallyDrop
7edff0ae35 rt(d3d12): allow manually specifying the strategy to get a manuallydrop for luts
dedde05c83 rt(d3d12): move update subresources to lut
7d483f2e08 rt(d3d9): take viewport by reference to avoid AddRef/Release
7b7fd99b92 rt(d3d11): take viewport by reference to avoid AddRef/Release
28931ae50a rt(d3d12): update d3d12-descriptor-heap
2fe7702957 rt(d3d11): avoid QueryInterface in GetSize
a5c8fcf4f8 doc: missing period
629070ea2f ci: build cli
da53c3df59 cli(render): make frame inclusive to ensure correct feedback and history behaviour
84e78f4e48 cli(render): add ability to specify frame options
91f8089277 cli(render): add ability to specify params and passes enabled
3993f57271 doc(cli): document CLI
55ff7a93f2 cli: rename librashader-test -> librashader-cli
227757a221 cli: parse transpile versions
a72a593029 reflect: allow indexed and non-indexed semantics to be serialized and deserialized as strings
1537c1bcd7 cli: ensure shaders are validated before compile
5573f13227 test: add CLI with multiple functions
bac09ad2a3 reflect: allow validation of shaders without reflecting against semantics
31ece05246 reflect: allow more reflection objects to be serializable
5ede061975 preprocess: allow shadersource to be serializable with serde
1676150858 presets: allow presets to be serializable with serde
eeda0d02d0 test: make RenderTest trait object safe
f7a938a00d deps: update dependencies
6394b28d40 deps: update dependencies
443fa20d22 test: clean up imports and features
5c726efe21 test(d3d12): Add D3D12 render test
d33c2a84b2 test(d3d9): Add Direct3D 9 render test
5a35a2bd1e test(render): reenable cache
41034330a7 test(mtl): Add Metal render test
a7836923d7 test: split test harnesses into features
20039b9347 test: abstract test framework
799d409ddb test(gl): Add OpenGL render test
79513a301e test(vk): Add Vulkan render test
6de2de8d12 test(wgpu): Add WGPU render test
2904a2ac10 test(d3d11): Add D3D11 triangle test to image
341fbceb82 rt(d3d12): derive clone on D3D12InputImage
c54747d398 deps: update dependencies
3888b56c83 rt(d3d9): accept input image by reference
b0df631651 rt(d3d9): load LUTS as BGRA8
dbfa822f7c rt(d3d9): disable alpha blending
e7fe96520e rt(gl): ensure framebuffers are bound
97ad0d64bf rt(gl): make FilterChain::load_from argument order consistent with other runtimes
feaebc5f44 fmt(gl): cargo fmt
ef35e2a620 presets: rename to_hashmap -> into_hashmap
987e967269 doc(capi): add error doc for infallible error
c3469520f9 examples(d3d11): fix d3d11 examples
45b98a2bdd rt(gl): use array_init instead of manually doing it with MaybeUninit
2ee9eca854 ci: ignore .DS_Store
59937aced5 fmt: cargo fmt
e4eed34c10 capi: const qualify chain in `_filter_chain_get_param` and `_filter_chain_get_active_pass_count`"
7abd679bd7 doc: add migration docs
41353ac9c4 rt(gl): remove need for explicit external FBO object
4d790e7a7b doc: update ABI versions in version.rs and readme
aeb0a16cfb rt(vk): allow specifying the queue to use
16108838b1 rt(d3d11): remove unneeded transmutes
7cfbca7755 rt(wgpu): remove unnecessary output move
8467e5cd97 rt(mtl): remove unnecessary output move
1e33b4cc03 capi: make viewport optional, defaulting to a viewport that is the entire size of the render target
eb53699590 capi(include): update headers
0cbf8024a7 build: update soname
7e354a56a1 capi: upgrade cbindgen to fix syn bug
0a87bcc657 rt: respect viewport extents when rendering
f0a7970b44 rt: add viewport extent separate from output texture dimensions
e7e6ed8fb8 capi: remove _internal_alloc from libra_preset_param_list_t
61fdaeea14 capi(gl): update to take opengl context in constructor
2552d4321b capi(gl): set output in libra_output_image_gl_t, not viewport
eaf939c861 capi(vk): set output in libra_output_image_vk_t, not viewport
14abb0362b capi(d3d12): set output in libra_output_image_d3d12_t, not viewport
e064f8d0be capi(d3d12): remove ignored fields from libra_source_image_d3d12_t
f18c22a95a capi(d3d11): take ManuallyDrop<ID3D11ShaderResourceView> directly in libra_d3d11_filter_chain_t
763c05755d rt: mark error types as non_exhaustive
e6d23f1d8f doc: update opengl example
2f9df143cf deps: consolidate and update dependencies
1bdadaa449 rt(gl): port to OpenGL runtime to glow
77b957bf5e reflect: stop adding null bytes to uniform names
1e0727f89d chore: Release
60d2c3f177 chore: Release
72a98272f3 doc(capi): document all C API members
7d0b135710 rt(mtl): remove unused 'pass lifetime
4ba5aefafc capi: don't export wrap_ok macro
6edfaed91f test: update slang-shaders
cd877d7883 build: respect CARGO env in build script
d56d92ea0f test: update slang-shaders
f49e3b58d8 doc(capi): fix rotation integer docs
1f4f1b6c12 capi: Fix Metal error message, function header
57f2dabf0c reflect: fix `CurrentSubFrame` being parsed as `TotalSubFrames`
81840a9e9c reflect: insert alias semantics for shader name through pragma
87e0405675 presets: properly trim shader name if given through pragma
e0c97f77b4 build: nicer build script messages
6e60dd6fa0 test: update slang-shaders
d55d0e4839 rt(mtl): use f32::MAX for lodMaxClamp
6cdd9247de presets: trim aliases and shader parameter names
cbe6510f76 preprocess: the step argument is optional according to slang-shaders spec
d6f8950bdc rt: only draw last pass twice if the last pass is needed as feedback
0fe5bbd57b rt: do reflection to see if the final pass is needed as feedback
eace595ebb chore: Release
66561ad2ed doc: fix header image
05d48841ad doc: update docs for stable build instructions
927740433c build: remove unneeded image dependency
316e92dc09 build: allow building stable with --stable flag
e930f90a9c capi: allow building on stable by gating #[doc] comments
2f988d5b1d rt: add stable feature to build ShaderPassArtifacts via Box<dyn CompileReflectShader>
e0a5c90103 reflect: implement stable FromCompilation
4cc3c875bf reflect: allow compilation of boxed trait objects
805854b94b reflect: simplify FromCompilation output signature
c291d9d85f capi: remove dependency on `try_blocks`
8b2ff57ee8 reflect: replace `let_chains` with `Option::filter`
3d9139b4e0 rt(d3d11): replace `let_chains` with stable alternatives
b432a1e02d rt(d3d12): replace `let_chains` with stable alternatives
ab9ab6fe68 rt(gl): use `Option::filter` instead of `let_chains`
0ba4c482b3 rt(vk): use `Option::filter` instead of `let_chains`
57f9a13ee7 rt(wgpu): use `Option::filter` instead of `let_chains`
2661effab4 chore: Release
02288554b9 rt(mtl): fix history buffer off-by-one by buffering the history read.
98d8d91c66 capi: undo const qualification of chain in `_filter_chain_get_param` and `_filter_chain_get_active_pass_count`
6f5b342c1b build: fix dev-dependencies on non-apple
bec0482513 ci: trigger ci
e24beede0b rt(mtl): draw final pass to output targets
22b2118e97 rt(mtl): don't resize if the requested format differs from optimal format
856f69113d rt(mtl): don't make mipmapper for history if not needed
477d0ae67c rt(wgpu): draw final pass to output targets
e68da7b984 rt(gl): draw final pass to output targets
666588ef0d rt(vk): draw final pass to output targets
336f540ce9 rt(d3d9): draw final pass to output targets
894d19eb81 rt(d3d12): draw final pass to output targets
1bf5d7efca rt(d3d11): draw final pass to output targets
c9205bc922 rt(mtl): remove internal_frame_count
cebc7a939a rt(mtl): fix faulty history but only copying one mipmap slice of texture
fe48fd03a5 test(mtl): update the metal test
50580cfc3b chore: Release
075a2981e1 rt(gl): fix `glShaderSource` going past the buffer
a7dd40a79f ci: allow c_str_literals to maintain a lower MSRV
fd8d6f6ab8 chore: Release
c5fdffa6aa dep: update cargo.lock
090e268c4a doc: improve docs
8856a78eb8 api: expose `FastHashMap` and `ShortString`
ec3add1616 rt(params): rename get_parameter -> parameter_value
f83fd1e98f ci: debug is broken on windows 7
c3033cfbbf reflect: port to spirv-cross2
820fb69328 reflect: remove get_prefix from get_texture_semantic/get_unique_semantic
c9a6411394 deps: consolidate and update dependencies
40a56bf165 reflect/preprocess/presets: use SmallString where it makes sense
c447e40583 rt: redesign parameters to be thread-safe across FFI using arcswap and atomicusize
ae76bf9cc1 rt(d3d12): pull out descriptor heap implementation into its own crate
e934f175ef rt(d3d12): stop leaking transition barriers
2e7c3b3273 rt(d3d12): use gpu_allocator instead of CreateCommittedResource
e90c27ebbd rt(vk): use manuallydrop for VulkanBuffer rather than Option
8fb5d48a1e chore: Release
b7fd3bc507 runtime: fix image swizzle for remainder
af05cc5bd8 ci: build for windows 7
2f0a3356d9 rel([email protected]): doc fix
0efaf2b8a0 doc: fix docsrs build on macos
436d1fe3cd chore: Release
0ce11bac71 doc: promote d3d9 to secondary support
bc269c270c rt(d3d9): remove backtrace from Direct3DError
db3d5d05a6 presets: use crate for extract_if with fully qualified syntax to avoid name collision with unstable std
1957f576ca reflect: further improve link i/o pass by ensuring that the output SPIR-V is valid according to Vulkan 1.0 semantics
5560c1ed09 runtime: use a more efficient swizzling implementation without array_chunks_mut
f8c055524b doc(readme): document shader pre-linkage
fee92113f1 ci: remove PR full test
45c3c876f4 reflect: remove explicit compile function in favour of TryFrom
28f5674a80 presets: remove rustc 1.74 compatibility
bffad12ea2 doc(presets): add docstring for ContextItem::key
321e30a0f1 capi: extend config_struct macro to handle overrides
9b40c10466 reflect: improve inout link algorithm
cd14bca23a Revert "reflect: improve inout link algorithm"
1ac78695c6 reflect: improve inout link algorithm
d1e49b7eb4 rt(d3d9): search "global" namespace for register assignments
5ef0055e05 rt(d3d9): fix vertex assignments accidentally searching fragment
1c6581d737 rt(d3d9): set colorwritemask to all
ac66b1b6f6 style: fix warnings
977975f4c7 doc: document naga reflect
3b9514ad38 doc: allow wgpu doc on apple
899fb50da6 chore: Release
162226ce44 ci: don't build locally
039fdfd41a ci: update OBS build platform
e13bb88df2 doc: update MSRV due to naga
7b375658c5 dep: update cargo.lock
3fb6e3843e dep: update to windows 0.58
3cda5b706d rt(d3d12): get rid of size in inputview
4d6793d305 rt(d3d11): get rid of input/output view wrappers
35f499f5e1 wgpu: enable pipeline caching
6ce711db26 ci: don't build Arch
d4b4366836 dep: update ash to 0.38
c646086df4 dep: update wgpu
f6cf642e50 chore: Release
98958dfb5e dep: update rustc_hash
b5d523e9f3 rt(mtl): move icrate definitions to objc2-metal
5e9ce1207c Revert "ci: temporarily remove deny-deprecated on ctypes to unblock ares"
1b0574c140 presets: show file name and details on io error
b84e104212 capi: fix malformed vulkan include
git-subtree-dir: thirdparty/librashader
git-subtree-split: 4abd48eb244e15ca40307f28fce0061627ff0143
aaca599e18 Merge pull request #130 from notaz/release_lzma_init_buffers
2099836c2b release lzma init buffers
9b6ff6c3c2 Merge pull request #128 from scribam/zstd-legacy
85dd19217a Merge pull request #129 from scribam/arm-neon
71e57f533d lzma: extends neon support when hwcap is not available
a6c474ddee zstd: disable legacy support
git-subtree-dir: thirdparty/libchdr
git-subtree-split: aaca599e18e43933fc193bd1b715c368c306208b
f6326087b3 Improve op flags operation on x86
2a79c59737 Fix sign conversion warning on Windows arm64 (#270)
7a6ceb3e03 Fix examples (#269)
2c105e2461 Fixed a compare logical case on s390x
4c4802dd4c Emit brk #0xf000 for breakpoint opcode on arm64 (#267)
3b9c0c8925 Enable public usage of SLJIT_LOCALS_OFFSET (#264)
4dd388a736 loongarch: add memory fence & support tmp register for atomic (#263)
8c089bd584 Implement m,emory fence
d21a5448f6 Fix compiler warning
f9f512c080 Support tmp register for atomic
883118537c Add action (#259)
8099661b54 Add SLJIT_ATOMIC_USE_LS/CAS support to LoongArch (#261)
728db2007a riscv: only enable SIMD if supported by toolchain (#260)
8727735933 Bitmanipulation instructions on RISC-V (#258)
c85dd1dd97 Rework sljit_emit_enter argument passing
3e5568bfcc Add more tmp reg tests
bd056ab1df Add control flags to atomic operations
ee8861243f loongarch: Implement ll/sc support for atomic operations (#254)
d3a10d1986 x86: avoid SIGILL in CPUs with AVX but without AVX2 (#256)
460f02a1b8 x86: check for extended function availability before using (#255)
0a74f16bea x86: improve execute_cpuid() portability (#251)
7b0fd86bd5 test: avoid leaking compiler on early exit (#253)
31cfa2fef2 Add shuffle support for LoongArch (#252)
06a5bafd7c Initial implementation of riscv simd
5ad2541117 x86: improve execute_get_xcr0_low() portability (#250)
6128486813 Implement atomic store on ppc and mips
fcade55c27 Update atomic on s390x
8bcd711708 Rework atomic load/store
bd221f0e86 Support non-overlaping vector registers
git-subtree-dir: thirdparty/sljit
git-subtree-split: f6326087b3404efb07c6d3deed97b3c3b8098c0c
256KB of SRAM is possible on hardware and many hacks use it (Super
Metroid Practice ROM, Super Mario Bros. Maker, etc.). It could be
implemented in Ares in many ways, but I limited the ramSize to 1-8 with
a wrap-around as values higher than 8 wrap-around when used (9 is the
same as 1, 10 is the same as 2, etc. verified by
[kandowontu](https://github.com/kandowontu)).
Implements the following changes:
- Bits 8-11 of SIOCNT should be read/write
- Mode specified by SIOCNT uses 2 bits rather than 1
- Lower 3 bits of JOYCNT are cleared when 1's are written
Needs to merge #1654 first.
Enables loading folders instead files from cmd line.
Removes loading firmware files from rom folders in sfc mia (firmware
data would be loaded twice, db hashes would not match anymore).
Adds a 2-cycle synchronizer delay to IRQs. Unhalting the CPU also
appears to be delayed by 2 cycles.
The GBA CPU core currently steps in increments of 16 cycles when halted
or stopped to reduce emulation overhead. Since this optimization can
cause unhalt timings to be off by a few cycles, this PR reduces the step
size for halt mode and removes the optimization for stop mode.
Performance impact should be minimal in cases where performance is a
concern.
Minor code cleanup. clang reports that it's possible under some
circumstances these variables are uninitialized when used.
Overall motivation is to utilize some stricter compiler settings in the
future and error on `-Wuninitialized`.
This change contains a large refactoring with no functional changes,
plus a small functional change that will help speeding up the JIT.
The refactoring allows CPU::devirtualize to return all the information
regarding the memory access. This in turn allows to simplify all memory
ops (which contained lots of duplicated code) to use devirtualize,
reducing code duplication.
The functional change is that we now use JIT only when running code from
icache (which is 99.9999% of the times). Running code without icache is
extremely slow on real hardware and only happens in specific situations
(eg: during boot when RDRAM is not initialized). By limiting the JIT to
run from icache, we open the door to implement proper icache support in
the JIT and finish remove the instruction epilogue with its slow
"instruction cache stepper" (which in addition to being slow, is also
inaccurate and make us fail cache test ROMs).
Currently, gdb hooks in n64 doesn't allow for large sizes of writes
because it wouldn't be obvious which data size use on the bus. While
this is true, it doesn't really matter for RDRAM where all data sizes
work in the obvious, correct way. So relax the constraint to allow
writing large portions of RDRAM with a single gdb command.
Co-authored-by: Chase Meadors <[email protected]>
Co-authored-by: Luke Usher <[email protected]>
Originally, to run ares on Linux after building it, you'd `make install`
which copied everything into the right places in your home directory.
Windows and macOS don't have the same traditions about installing apps,
so on those platforms the makefile staged a "portable" installation in
the output directory.
Since then, `make install` was modified to install ares system-wide.
It's possible to use it to install ares into your home directory, but a
bit overkill. For consistency, let's also stage a "portable"
installation in the output directory on Linux and the BSDs, so it's
easier to test on those platforms.
Essentially a revert of fbaf7d8118
This optimization was found to compromise correctness due to the lack of
alignment checks. If something like this proves truly beneficial for
performance, we can bring it back.
If you like to slow down booting into your game and want to read the
same old text each time on the Mega Drive, the option is yours now! This
is available as a choice in Settings > Options now. By default, this
will not be enabled (same behavior as existed prior to this PR). You
don't need to specify anything in the firmware section, ares had the
plumbing in place all along, it was just hardcoded to not load the tmss
boot rom.
The Sufami Turbo base cartridge is listed in the Super Famicom verified
dump database, so it did not use the heuristics. It turns out the
heuristic detection wouldn't have worked anyway - although the game's
header does contain the serial A9PJ, the heuristic revision() method
does not report that serial at all.
Meanwhile, the serial A9PJ is *also* used by the game Bishoujo Senshi
Sailor Moon SuperS - Fuwafuwa Panic, so loading this game would prompt
for Sufami Turbo mini-cartridges even though the game could not make use
of them.
I have used mia to generated heuristic manifests for every SNES/SFC game
in the No-Intro set, and the only difference introduced by this change
is that the Sufami Turbo base cartridge is now detected as having Sufami
Turbo slots, and Fuwafuwa Panic is not.
It took me a little messing around to find a syntax for comparing an
`array_view<u8>` that the compiler would accept; if there's some more
concise or idiomatic way to do it, please let me know.
Of the other emulators I surveyed, bsnes works just like ares did,
MesenS doesn't seem to support the Sufami Turbo, and snes9x uses a
slightly stricter check than I implemented:
https://github.com/snes9xgit/snes9x/blob/85591435763dede7ef111aab8070cdf2d5a7da49/memmap.cpp#L1016-L1023
MSVC build logs are complaining [very
loudly](https://github.com/ares-emulator/ares/actions/runs/10524248801/job/29160592080#step:10:835)
about unknown pragmas.
Only clang complains about these code areas currently, so for now, just
put these diagnostic pragmas behind a check for clang. If MSVC pragmas
end up being a good idea, could look into compiler-agnostic pragma
macros, but that doesn't seem necessary at present.
Removed `__VA_ARGS__` from line 6 of interpreter.cpp, since it appears
to be unused and was causing compiler issues. Tested on Ubuntu with g++
and clang++ with both interpreter and recompiler running a default build
of n64-systemtest.
---------
Co-authored-by: invertego <[email protected]>
This will bloat generated code in the short term, but some of that can
be elided with future optimizations.
Passes [n64-systemtest](https://github.com/lemmy-64/n64-systemtest) with
both the interpreter and recompiler.
---------
Co-authored-by: Giovanni Bajo <[email protected]>
A better fix for the problem discussed in
https://github.com/ares-emulator/ares/pull/1412.
Also unbreaks CI.
Changing `clipsToBounds` was fine, but the property isn't exposed on
older SDKs (that are still used by ares to maintain backwards
compatibility), and exposing it manually when building with an older SDK
was not great practice (and may have just been a noop anyway).
Instead, we should just not draw on the dirtyRect, when we intend to
draw on the view's `bounds`. Apple's documentation on this subject is
pretty thin on the ground, not to mention contradictory, especially
pre-macOS 14. But it seems pretty clear that in any case, a view's
`bounds` will always be the area we intend to draw on, while the view's
`dirtyRect` may or may not be. So here we make every element in hiro's
Cocoa implementation that does manual drawing always draw using
`bounds`.
More code cleanup for the new build system along with
https://github.com/ares-emulator/ares/pull/1602,
https://github.com/ares-emulator/ares/pull/1603, and
https://github.com/ares-emulator/ares/pull/1604.
This one is fairly mysterious. clang thinks that all paths through this
particular signature of the `square()` function call itself. This area
of nall is a mass of templating and operator overloads, and figuring out
exactly what's going on here would be a good one to unravel for a
large-brained, C++-enjoying individual.
For now, just ignore this warning locally so that we can compile the
rest of ares while still warning about infinite recursion elsewhere.
Enforce newlines at end-of-file in the codebase.
While every modern compiler is able to deal with not having EOF
newlines, it is still a good idea to enforce this.
ParaLLEl-RDP has a few files without EOF newlines, so I surrounded the
n64 Vulkan `include` with a diagnostic pragma to ignore it. This avoids
having to deal with compiler errors if ParaLLEl-RDP is updated, pending
newlines added upstream.
Fixes several issues and compiler warnings with hiro's Cocoa
implementation. Among them:
* We were technically declaring `clipsToBounds` incorrectly; properties
in subclasses aren't correct and can conflict with the system version;
rather, implement it as an instance method.
* Fix some non-strict pointer aliasing in menu-separator.cpp;
* Remove a couple blatant unused variables from desktop.cpp and
monitor.cpp;
* Fix an instance passing nil to a function that requires a non-null
argument in popup-menu.cpp;
* Some ancient C functions in Cocoa don't pass -Wwritable-strings; for
now, just surround the function that uses them with a clang diagnostic
pragma.
In C++ land:
* Various C++ functions were `override`s but were not declared as such.
Lastly, the second commit:
* In Objective-C, you declare subclasses in the `@interface` header, but
not in the implementation. hiro was including the superclasses in the
`@implementation` block, which isn't correct. For some reason, clang was
only erroring on one instance of this, but we go ahead and fix it
everywhere.
Removes apparently dead, unused functions in the OpenGL backend.
### Context
Work continues on the new build system. Among its goals are to start
compiling ares with stricter settings, where applicable, to increase
code quality. This includes removing unused functions, to satisfy
`-Wunused-function`.
Some systems report target-triples below i686, although they target i686
in reality. One such system is FreeBSD since version 13.0. It reports
i386 but targets i686. Without accepting target-triples below i686 such
systems can't compile ares on the x86 architecture.
Currently, the prefetcher halts whenever DMAs are running. However, on
hardware the prefetcher is able to keep running until DMA accesses
cartridge ROM. This PR implements said behaviour, allowing ares to fully
pass the mGBA test suite timing tests as shown below:

Added missing serialized fields to N64 save state, one in AI and one in
PI (both added in same commit).
Scanned the other sections looking for other missing fields so we don't
need to invalidate save states frequently and I didn't spot others that
were missing right now.
The 2 DMA idle cycles currently processed before running a DMA channel
should instead run for 1 cycle when DMAs start, and 1 cycle when the
DMAs have all finished.
The OSS audio backend was very limited in its capabilities and its error
handling. Essentially it supported only the initial parameters for
channels, format and frequency, e.g. 48000Hz 16bit stereo. If the audio
device didn't support these parameters, the backend would keep using the
initial values although OSS had probably adjusted the parameters to
supported values. Be aware, there are possible configurations for the
system and the audio devices which don't support the above mentioned
standard values, e.g. on FreeBSD it's possible to configure an audio
device to only accept 96000Hz 32bit 7.1 surround sound.
Now the OSS backend takes the changed parameters for channels, format
and frequency into account, updates the resampler accordingly and feeds
the audio data into the audio device with the right format.
It appears the datasheet was not entirely conclusive with regard to how
the CPU handles chains of more than 7 consecutive instruction prefixes;
in addition, Ares was incorrectly using the *first* rather than *last*
segment override in the chain.
This doesn't affect well-formed code (duplicate instruction prefixes
should never happen, nor should more than one segment override), but
brings Ares up from 2/7 to 7/7 in
[ws-test-suite](https://github.com/asiekierka/ws-test-suite)'s new
`mono/cpu/prefixes` test.
Replace deprecated elements with suggested replacements.
QApplication::hasPendingEvents() and QWidget::paintEngine() are still in
use, their replacement is way out of scope for this PR.
The Superampling option in the Video category isn't visible in QT5
builds, the settings window is too small. Therefore increase the height
of the window by 20 to unhide the setting. This also gives the setting a
little bit more distance to the bottom edge in GTK3 builds.
Currently a per-instruction epilogue is needed to make sure the
read-only register r0 stays as the value 0. To improve performance of
the generated code, we'd like to move this operation to be done only
when needed.
This commit solves the above problem in two ways: simple instructions
are never emitted if their destination register is r0, and more complex
instructions now emit a clear operation right after. This way exceptions
are still thrown when needed.
Address some edge cases of LDM/STM instructions (also affects Thumb mode
PUSH/POP):
- Using an empty register list will cause R15 to still be accessed, but
the base register will be modified as if all 16 registers were accessed
- Writeback does not occur in LDM if the base register is in the
register list
The hardcoded `/usr/share` for the sharedData location doesn't respect
the given prefix, e.g. `~/.local` or `/usr/local`. This results in the
emulator not finding the shaders or databases in case the emulator is
not installed under `/usr` and the files are not found in the
application or user data directory.
Now the build script defines a preprocessor constant `ARES_PREFIX` which
is set to the requested prefix. With the help of the C preprocessor
stringize operator, this prefix is then used as the root of the
sharedData location.
Fixes https://github.com/ares-emulator/ares/issues/1179
These commits improve the compatibility with FreeBSD. Among some
cosmetic changes is a commit to unbreak the build on FreeBSD and two
commits adding an audio and an input backend to FreeBSD builds.
There's still a change needed to make ares completely buildable on
FreeBSD:
use of `CLOCK_MONOTONIC` in
`ares/n64/vulkan/parallel-rdp/util/timer.cpp`, see
https://github.com/Themaister/Granite/pull/135. This change will
propagate to ares if/when Granite upstream merges the PR, parallel-rdp
adopts the updated Granite and ares updates its parallel-rdp.
Provides a getDebugger function for the ARM debugger to read memory
without advancing CPU state, fixing a bug where GBA core CPU timings
were impacted by debugger use.
Automatically detect the (clang-)cl target architecture instead of
assuming amd64. Note that -print-target-triple is now used in favor of
-dumpmachine for all versions of clang. This option has been around for
ages in the regular clang driver but is only supported by clang-cl as of
LLVM 18, which isn't yet available via the Visual Studio installer but
is available through a standalone installer on GitHub.
This commit also adds a compiler flag to the command line when targeting
arm64 with cl to work around an optimizer bug.
On versions of make prior to 3.82, pattern matching rules are applied in
the order they were first defined, as opposed to the probably-desired
order of most specific to least specific. In ares, `nall`'s pattern
matching rule comes fairly early on and is thus used to build most of
ares. The parallel-rdp build code in ares defines its own pattern
matching rule, which caused building with 3.81 to not work since the
more specific rule is not used, and the less specific rule cannot be
applied successfully.
For other fun reasons, macOS still ships with make 3.81 (released in
2006).
This PR just allows building on macOS's stock `make`, which means a bit
less effort in building, as well as easier integration with IDEs (in my
testing so far, what few IDEs on macOS support direct Make integration,
seem to require or expect the stock toolchain).
There may be slightly more elegant ways to do this, but this pattern
conforms with how object paths are defined for other third party
dependencies around ares.
Eventually™, if ares migrates to CMake, there could much better cross
platform build tool integration (generating Xcode or other OS project
files as desired, for example). Until that point, it is convenient to
support the stock toolchain on all operating systems if possible.
Co-authored-by: jcm <[email protected]>
### OpenGL rendering (all platforms)
- librashader specifies that the output viewport should be the same size
as the output framebuffer texture. This was not the case for the OpenGL
render code.
* Previously, librashader under OpenGL would render onto an intermediate
framebuffer sized to the "output" size (the entire window view size),
rather than the "target" size (the final composited size of the game
area within the output area). The `libra_viewport_t` would be sized to
the target size, but the underlying buffer would be larger.
* Now, we size the intermediate framebuffer to the "target" size, let
librashader render onto it with a `libra_viewport_t` that matches that
size. In the final pass we sample this buffer within an area of the
"output"-sized buffer as appropriate.
This prior behavior would lead to scaling issues with shaders in the
Metal backend. The same issues did not seem to be obviously present in
OpenGL in my testing, but we should nevertheless probably fix this in
case it is causing any of the subtle issues with shaders that have been
reported, and also in case something breaks in the future as a result of
not following this recommendation.
(The above is also unrelated to the scaling issues addressed by
https://github.com/ares-emulator/ares/pull/1508)
### CGL fix-ups (macOS)
- Backports the native fullscreen and monitor selection options to
OpenGL, and removes unnecessary custom window code from the OpenGL
driver.
- Removes a seemingly unnecessary output call from `reshape` that would
cause flickering during resizes.
This has been tested on macOS but should probably be tested on other
platforms as well to make sure nothing breaks.
Co-authored-by: jcm <[email protected]>
This originally added the N64, but after inspecting remaining
cartridge/card/fixed ROM based systems I have also added the additional
four so that hash is available in manifest. This should complete adding
this info for these types of consoles.
N64
Gameboy Advance
MyVision
SG-1000
Sufami-Turbo
Testing some games on Coleco Vision & Atari 2600 and noticed that the
SHA256 ROM hash was missing from the manifest for these two, which I
have now added.
c2e49625e Fix incorrect argument order in x86 sljit_emit_simd_lane_mov
68bb7c7cc Support shuffle on s390x
b3f492960 Support simd shuffle operation
git-subtree-dir: thirdparty/sljit
git-subtree-split: c2e49625e4be2f1e62263044527fe83cce88d2f2
1. pass mmc3/3-a12_clocking.nes
2. refactor the ppu/var and ppu/scroll
3. fix ppu var and scroll read/write($2005/$2006/$2007)
4. inc serialization to v144
5. fix the color generator
6. fix the game Burai Fighter (USA)
7. pass issue #151
Currently, gdb is polled once per frame, which seems enough for
interactive usage. Some ROM hacks would like to use the gdb interface to
provide additional emulation-only features such as online multiplayer,
but that requires a faster turnaround.
A quick solution is to poll gdb more frequently within the n64 core.
This patch does that once per screen line, approximately. Notice that
the poll is only scheduled and run if there is a gdb client connected so
it should not cause any performance impact on normal users.
Just a small fix to account for the new video settings in Metal; the
threaded renderer, native fullscreen behavior and color space option.
These options were not fully persistent because the `videoDriverUpdate`
function (run on startup, among other times) did not account for them.
They would be set correctly in `settings.bml` and the settings object,
but would never actually be set correctly on the driver struct.
Co-authored-by: jcm <[email protected]>
* The behaviour of bits 0-3 and 7 in the control/status port were a
complete guess and had no reflection in hardware testing. They have been
adjusted to match hardware.
* The EEPROM interface always writes and reads out 16 bits to/from the
EEPROM, including the initial zeroes in the command value. The M93LCx6
code has been updated to support this case in line with the datasheet.
* The read and write data port have been separated. This was a detail
which every community documentation in existence got wrong, so no
worries about that one ^^
* Internal EEPROM protection has been implemented.
* The handling of invalid control commands (more than one bit set) has
been fixed.
* Emulation of the 93C46-family internal EEPROM on SPHINX in ASWAN mode
has been implemented. In particular, this fixes running any mono
WonderSwan game which takes advantage of the internal EEPROM on the
WonderSwan Color system's compatibility mode.
All of these changes pass the relevant tests in
[ws-test-suite](https://github.com/asiekierka/ws-test-suite)
(mono/eeprom/internal.ws) both as a WonderSwan and a WonderSwan Color.
This isn't 100% accurate (particularly, timing is not reflected; but
there are also some questions about more edge case-y behaviour), but
it's much closer.
The paraLLEl-RDP build was broken on macOS because of a change from
February to Granite in regarding platform ifdefs for pthreads.
A PR that applies a fix has been opened
[upstream](https://github.com/Themaister/Granite/pull/131), but until an
upstream fix lands, this PR will unbreak the build for ares without
needing to roll back the recent paraLLEl-RDP update entirely.
Co-authored-by: jcm <[email protected]>
Reduces the synchronization interval between the GBA CPU and other
components from 64 to 16 cycles, which significantly improves PPU
timings in the performance profile. These PPU timing improvements can be
observed in
[status-irq-dma.gba](https://github.com/nba-emu/hw-test/tree/master/ppu/status-irq-dma),
which now frequently gets results within a few cycles of the correct
values in situations which were previously off by dozens of cycles.
While this does impact performance by ~5-10%, in my testing this is
still faster than versions from before [commit
b145f0f](https://github.com/ares-emulator/ares/commit/b145f0f000c4e0ddedf25a62cdcfe713deea1f6a).
This PR improves handling of BIOS open bus edge cases that previously
were handled incorrectly, such as unaligned 8-bit and 16-bit accesses,
and cases where the last value read from BIOS was not a 32-bit value.
Compiling with GCC 14.1 in MSYS2 caused a lot of warnings of the
`-Wcast-user-defined` variety. This PR adresses that.
Note: This PR does not address
https://github.com/ares-emulator/ares/issues/1399 . Those warnings
happen at the link stage, they don't seem to be GCC-only (since issue OP
also reports them with clang), and they don't appear at lower
optimization settings (I tested `build=debug` and `build=stable` which
compiled cleanly).
pass blargg_ppu_tests_2005.09.15b/power_up_palette.nes
pass "Hello World" PPU test:
https://github.com/PeterLemon/NES/tree/master/HelloWorld
In https://forums.nesdev.org/viewtopic.php?t=567#top,
blargg say: "The power-up values of the palette are what my test program
reads back after powering the NES. I have one of the older units that
shows a green screen (I think newer front-loading ones had a gray
screen). These values probably vary slightly from one console to the
next."
Palette at power-up
0x09,0x01,0x00,0x01,
0x00,0x02,0x02,0x0D,
0x08,0x10,0x08,0x24,
0x00,0x00,0x04,0x2C,
0x09,0x01,0x34,0x03,
0x00,0x04,0x00,0x14,
0x08,0x3A,0x00,0x02,
0x00,0x20,0x2C,0x08,
To read/write a cgram, it needs to and 0x03, not 0x13
In https://www.nesdev.org/wiki/PPU_palettes#Memory_Map
$3F00 Universal background color
$3F10 Mirror of universal background color
$3F04 Normally unused color 1
$3F14 Mirror of unused color 1
$3F08 Normally unused color 2
$3F18 Mirror of unused color 2
$3F0C Normally unused color 3
$3F1C Mirror of unused color 3
For IPS patches that extend the original ROM beyond its initial size, we
will now resize the target buffer when patches extend the size of the
original.
Originally found testing out the Shin Megami Tensei patch by Orden
(https://www.romhacking.net/translations/2616/), which will now work
correctly.
Latches writes to timer registers for 1 cycle. This fixes common
off-by-one errors with precise timer use, which for example positively
impacts the test cases in #154.
This PR applies several minor fixes and improvements to macOS driver
settings and the driver settings pane.
#### Remove the "exclusive mode" video option on macOS.
* There is no real notion of exclusive presentation on macOS beyond what
already exists in normal fullscreen. If an application is covering the
screen and no other application or window is visible, the system
automatically switches to a "direct" presentation mode that optimizes
for single-application presentation performance. There is not a good
reason to show this option on macOS, even disabled.
* By contrast, it is possible (though not implemented by ares) to enter
exclusive mode on the audio device with CoreAudio, so leave that option
there, just disabled.
#### Add a "use native fullscreen" option on macOS.
* There are various good reasons to prefer either native platform
fullscreen behavior, or a custom borderless windowed fullscreen. Rather
than guess what the user wants, offer an option.
* If unchecked, make the window title bar enlarge the window rather than
fullscreen it, so we don't mix behaviors.
#### Implement fullscreen monitor selection behavior for Metal, and
correctly enumerate the user's monitor names.
* Fullscreen display on the selected monitor in the settings pane was
previously not implemented on macOS. This implementation only works if
"Use native fullscreen" is disabled, since the macOS fullscreen idiom
doesn't feature selecting a specific display.
* Additionally, the old function to retrieve the monitor's localized
name did not work reliably on newer macOS versions. Use the modern
property `localizedName` on NSScreen for macOS versions above 10.15, and
fall back to the old implementation otherwise.
* Implementing this meant adding a `uintptr` handle to the NSScreen
instance in the `Monitor` struct in ruby that uses a bridged cast to
interface with Objective-C. I would have preferred not to do this, but I
didn't see another good way to handle getting the `NSScreen` instance
that didn't involve a serious refactor.
#### (all platforms) Disable monitor selection if the video driver's
`hasMonitor()` is false.
* Just a minor fixup; the existing behavior is that the dropdown list
can be navigated and selected, but the selection does not persist. It
makes more sense to just disable it if the driver doesn't support it.
Co-authored-by: jcm <[email protected]>
- v2 will be unavailable from the end of June 2024
- v4 can be up to 98% faster than previous versions according to
[Github's
notification](https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/)
This PR only changes the version number, and I'm submitting it to see if
it works.
It is possible that further changes are necessary, as there were some
[breaking
changes](https://github.com/actions/upload-artifact?tab=readme-ov-file#breaking-changes),
but I don't think any of them apply to ares.
Testing:
- See if CI passes
- See if warnings regarding using v2 of `upload-artifact` and
`download-artifact` are gone (There will still be other warnings
regarding `checkout` and `cache`)
- (Optional) Compare times for the tasks using `upload-artifact` and
`download-artifact` with previous CI runs
Turns out the problem some folks experienced trying to load 64DD games
was due to run ahead not being disabled by default. An exception for
this system has been added.
#1463 renamed the `macos` build to `macos-latest` and introduced
`macos-compat`. We need to address the rename in the release workflow. I
believe this PR accounts for every use of the package name. Also adds
macos-compat to the release (for now).
Co-authored-by: jcm <[email protected]>
clear() in Metal was implemented by outputting a (1, 1) sized output
buffer. This was very quick and dirty though generally worked.
With librashader introduced in the render output chain, outputting a (1,
1) sized buffer can sometimes, depending on the shader, introduce an
intermediate pass that involves a (0, 0) sized MTLTexture, which can
lead to assertion failures and possible crashes.
This PR adds an actual clear() implementation that just does a blank
render pass. the clear color on the drawable is already defined during
initialization so we do not need to redefine it here.
Co-authored-by: jcm <[email protected]>
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.
This PR does a few things:
- Updates ares to create macOS builds with the latest SDK. After
https://github.com/ares-emulator/ares/commit/65264090b06853f3d831f507a3335d9c42e8a198
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 <[email protected]>
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 <[email protected]>
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).
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).
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-3f0c3a207972https://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 <[email protected]>
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
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
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.
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
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.
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 <[email protected]>
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
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 <[email protected]>
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 <[email protected]>
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.
This PR adds a Metal display backend to ares.
<img width="1482" alt="Screenshot 2024-03-31 at 7 02 40 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/48718f19-9916-491b-8301-c16b95f95c19">
*ares N64 core on a 60Hz P3 display. Shader: "crt-maximus-royale".*
## Context
With ares's recent introduction of librashader, ares users have enjoyed
access to the sizable library of shaders in the slang format, such as
those used by the RetroArch frontend. Simultaneously, up to now, the CGL
OpenGL backend shipped by ares for Mac users has offered enough
functionality to do the (relatively) simple job of an ares display
backend; display software-rendered frame buffers and pace them
appropriately.
librashader's advanced postprocessing, however, has asked a bit more of
the display backend, and in the case of OpenGL, has laid bare various
deficiencies in macOS's OpenGL driver. These deficiencies can kneecap
ares's librashader support on macOS with compiler errors and broken
shader behavior.
Rather than chase down these errors and try to work around what is
fundamentally a broken driver shipped by Apple, we take advantage of
librashader's native Metal support by adding a Metal backend to ares.
This greatly increases baseline shader compatibility, with the added
benefit of documentation and greater platform debugging information when
issues arise. The Metal backend will also generally future-proof ares on
macOS, with OpenGL's uncertain future on macOS.
## Basics
The first iteration of this Metal driver mostly offers feature parity
with the OpenGL driver. More advanced features, particularly in the
realm of frame pacing on ProMotion displays, will arrive in future
iterations. The priority with this PR is to start getting the driver in
the hands of users with basic features and greater librashader
compatibility.
Host refresh rate sync is still a work in progress and in this iteration
will only be enabled for users above 10.15.4 on non-VRR displays
(discussed more below).
Explicit sRGB color matching is offered as a new option for those on
wide gamut displays (by default, the Metal driver will map to the native
color space, conforming to OpenGL driver behavior). This option is only
exposed on macOS, since other operating systems lack per-surface color
matching.
<img width="400" alt="Screenshot 2024-03-31 at 6 37 38 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/e177a256-bba2-4a02-ad5b-9ad84cb09740">
<img width="400" alt="Screenshot 2024-03-31 at 6 37 46 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/dd517394-e97e-40f6-98de-4562d62bda98">
*Left: ares presenting in Display P3. Right: ares presenting more
accurately in sRGB with "Force sRGB" enabled. Shader: crt-hyllian.*
A simple vertex and fragment shader are compiled at runtime, so we avoid
the need to add another compiler toolchain to the ares build process.
There is unfortunately some code duplicated at present; `metal.cpp` and
`Shaders.metal` both include types defined in `ShaderTypes.h`, but we
also need to place `Shaders.metal` inside the .app bundle for runtime
compilation, making for awkward `#include`s. Presently, we just bundle a
copy of `Shaders.metal` appended with `ShaderTypes.h`, inside
`desktop-ui/resource`. This will be cleaned up in future work.
The driver's draw implementation itself is fairly simple; one render
pass renders to an offscreen texture, librashader performs its work on
that offscreen texture, and a second ares Metal render pass composites
the finished texture inside ares's viewport. Since we do not use
`MTKViewDelegate`, our output function finishes with a `[view draw]`
call and the system presents at the earliest opportunity.
## Details
When it came to the details of implementing this driver, there were some
nontrivial issues encountered. Some of these will need solving in
separate PRs before this driver is feature-complete.
### ares vs. VRR
Users on fixed refresh rate displays should enjoy good frame pacing with
this driver. Unfortunately, users of more recent Mac machines with
"ProMotion" refresh rates will not have an ideal experience in terms of
pacing. To understand why, we need to take a brief detour into how ares
works and then discuss some current limitations with ares's macOS
integration.
In ares "synchronize to audio" mode, ares creates and delivers video
frames as audio frames are created. This means that the video frame
timing is completely dependent on when exactly the audio driver
processes audio frames. For display modes with a refresh rate at or
close to the core refresh rate, this is mostly no problem; the system
seems to naturally present frames in a FIFO-esque fashion, and every
once in awhile the system will just drop or duplicate a frame if two or
no draw calls fall within one refresh interval.
For recent more advanced Mac displays with "up to 120Hz" refresh rate,
the story is more complicated. We have to explicitly tell the system
when we want it to draw the frame once available. It is tempting to
answer "now"; after all, if our audio timings are correct, then video
frames should be generated precisely when they need to be shown.
Unfortunately, in higher latency modes of OpenAL or with SDL audio in
general on macOS, audio frames are processed in large batches. That
means that we end up emitting several video frames in quick succession
at 8ms intervals on a 120Hz display, then waiting as long as 75ms for a
new batch of audio (and thus video) frames:
<img width="265" alt="Screenshot 2024-03-31 at 4 55 25 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/69f887a0-8ded-4f47-ac4c-4cf2b58283a7">
<img width="265" alt="Screenshot 2024-03-31 at 4 55 35 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/2f7a417a-0378-44b5-b0c0-f894542c0371">
<img width="265" alt="Screenshot 2024-03-31 at 4 55 56 PM"
src="https://github.com/ares-emulator/ares/assets/6864788/13b471d9-3e77-45cd-baf4-0d786ae83e22">
*VRR macOS frame pacing across audio driver settings in v0.1 of the
Metal driver. The graph in blue shows frame present intervals over time;
the values in red show the minimum and maximum present intervals over
the graph duration.*
If we do not answer "now," we have to decide when to present.
Unfortunately, currently, there is not a satisfying way to answer that
question. Core refresh rates vary somewhat widely, sometimes during
runtime, and there is no mechanism in ares by which to inform the
graphics driver of a core's desired refresh rate.
We could elect to just duplicate the behavior for a fixed display
refresh rate and pick, e.g. 60 Hz, but unfortunately even that option is
not available, because we currently have no way of receiving callbacks
when a frame is actually presented. Why not `CAMetalDisplayLink` or even
`MTKViewDelegate` you ask? Well...
### ares vs. macOS
For most of its cores, ares performs much of its work on a single
dedicated main thread that blocks for audio and video presentation to
drive hardware-accurate timing. Unfortunately, all of this work occurs
on the macOS main thread, with lots of blocking and CPU-intensive
activity. This interferes with the macOS application run loop's ability
to perform its callbacks and call out to observers.
In practice, this means that if we try to employ delegates that
interface with macOS, that could send a callback when a frame is
presented, or tell ares the exact moment a frame needs to be presented,
these system delegates cannot actually make these calls in time in
between ares's main thread activity; upwards of 50% of `MTKViewDelegate`
callbacks are lost, for example.
This means that tools like `MTKViewDelegate` or `CAMetalDisplayLink`
that would help us solve the frame pacing problem are, unfortunately,
useless to us. We cannot leverage these tools as ares is currently
architected.
To get around these issues, we will need one of: less main thread
blocking, so delegates can interface with ares on the main thread, or an
audio driver with a processing tolerance that falls within the display's
minimum refresh interval. Our best bet for now is to emit frames to the
system within ares's main thread work as they come available, let the
system draw them as it will, and hope that our audio driver is doing a
good job pacing them.
In practice, for Metal driver users on VRR displays you cannot set to a
fixed rate, this means you should use the OpenAL driver, and set the
latency to the lowest value possible.
## Future Work
The future for the Metal driver in ares takes us down a few different
paths.
The main issue at present is making macOS system delegates work well
with ares, which is the ideal path forward. Ideally, we could move all
of the emulation-intensive work off of the main thread in macOS and into
a high priority dedicated thread, reserving the main thread for actual
UI and rendering, giving the system plenty of overhead with which to
communicate.
For the future of VRR in ares, it would be good to create a mechanism to
tell the graphics driver what refresh rate the core wants to present at.
This would be one way to pace draw calls appropriately in the absence of
reliable feedback from the system about the state of the display.
It has gone without mentioning so far due to the other issues, but long
term, it would also be good for ares or librashader to have some way of
utilizing the entire viewport for shaders; currently, shaders are
limited to the output width and height area rather than the entire
window view size. This is limiting for "bezel"-style shaders that want
to use the entire screen in fullscreen, for example.
Co-authored-by: jcm <[email protected]>
5c598c2df3 Merge pull request #115 from notaz/gitignore
4cbba6df03 add a basic .gitignore
7239eab39c Merge pull request #114 from bslenul/windows-case-include
e2589a612c Make sure all windows.h includes are lowercase
git-subtree-dir: thirdparty/libchdr
git-subtree-split: 5c598c2df3a7717552a76410d79f5af01ff51b1d
e8ffd8fdf3 chore: Release
d893b6ec97 doc: update supported runtime table to include D3D9 and clarify wgpu status
8c8e386a6c capi(d3d9): expose d3d9 in capi
b7071958bd rt(d3d9): add a runtime for direct3d 9
5feac91af2 runtime: add ARGB8 pixel format
9c895caa51 wgpu: fix format mismatch for copies
7593f9f9b5 rt: pass device context to uniform binder if needed
af3ea252ba rt(d3d11): split luts out to own module
9dc0cf26fd chore: Release
2550bf7ed5 test: update shaders_slang
35fc21bbef capi: fix mtl noop free fn name
89b620a7c1 rt(gl46): fix invalid framebuffer copies
66a0ee21e3 Revert "rt(gl): account for flipped coordinate space when blitting to output"
31b7a6f33f chore: Release
ed7216990a test: update slang_shaders
623c6776f7 rt(gl): account for flipped coordinate space when blitting to output
bacfbf0791 cache: delete cache if corrupted
e02e1ae26a rt(gl): load luts with topleft origin due to MVP changes
d72519b9fd chore: Release
752417f320 rt(vk): switch from an rwlock to a mutex for allocator
10ad2d927c rt(d3d12): make descriptor heap lockfree
8a9adebb96 rt(d3d12): upgrade to windows 0.52
7719b939f9 rt(d3d11): upgrade to windows 0.52
a849f5e745 dep: unify on windows 0.52.0
f61bed3a22 vk: remove unneeded device arcs
git-subtree-dir: thirdparty/librashader
git-subtree-split: e8ffd8fdf31f29e35f0c367ef2c3c40c19088971
Resubmission of https://github.com/ares-emulator/ares/pull/1389 with
improvements.
Now the SDL build script will not call `xcode-select`, which can have
undesired effects on the user build environment, unless it is on CI
(detected with the `$GITHUB_ACTIONS` env var).
It will also not call ``cmake --install .``, which would previously
replace the user's SDL installation.
This second change required some minor changes to ruby's makefile. We
now include the header directory from the cloned SDL source, and inform
the linker correctly of the location of the SDL .dylib.
Also added the cloned SDL repository and .dylib to the .gitignore for
easier development workflow.
To ensure compatibility with
https://github.com/ares-emulator/ares/pull/1390, the
`MACOS_COMPILED_SDL` flag is added so we can include the proper "SDL.h"
header for compiled builds and `<SDL2/SDL.h>` header for system builds.
Co-authored-by: jcm <[email protected]>
When an instruction is already present in the prefetch buffer, fetching
the instruction should take only one cycle in both ARM and Thumb modes.
Currently, ares uses 1 cycle for each halfword read from the prefetch
buffer, which is correct for Thumb but not ARM. Fixing this discrepancy
allows ares to pass 1890/2020 of the timing tests in the mGBA test suite
(up from 1760/2020).
Exposes the option to use SDL's audio backend on macOS. The wiring for
this is already fully present, just needs to be added to builds.
Good to have another option for Mac audio for anyone having issues with
the OpenAL backend.
Tested locally and verified to work in the Metal dev branch.
Co-authored-by: jcm <[email protected]>
Addresses a minor issue with driver change confirmation logic and the
"Apply" button in the UI.
Previously, if the player changed the video, audio, or input driver with
a title loaded and clicked "No" at the confirmation dialog, the "Apply"
button would be disabled as if the player had changed the driver, when
they had not.
With this PR the "Apply" button state correctly reflects the driver
state and the result of the confirmation modal.
Co-authored-by: jcm <[email protected]>
* Significantly improved Hyper Voice implementation accuracy (verified,
at least for Sound DMA writes, with a test ROM)
* Implemented emulation of unused/undocumented debug ports (0x64-0x67,
0x69, 0x95-0x9B)
* Improved cycle accuracy of APU channel handling
* Added slightly faster "inaccurate" APU emulation mode (for most games,
output should be essentially identical; debug ports will not match up,
though)
For some reason, on macOS, debug symbols do not seem to be available for
lldb if link-time optimization is enabled. I do not know exactly why
that's the case, but it seems safe and without downsides to just disable
LTO if we're doing a debug build.
Co-authored-by: jcm <[email protected]>
Use the Games Express system card for the games that require it
Use System Card 1.0 for Altered Beast (this game is broken on other bios versions, even on hardwar
Fix CD-ROM pregap offset (Fixes Super Air Zonk, allows Games Express games to boot)
Fix PC-Engine Duo/Super CD-ROM Ram Enable Register
e)
This PR adjusts PPU timings as follows:
- There is a 46-cycle wait period between the start of a scanline and
the first pixel drawn, instead of a 32-cycle period between clearing
io.hblank and incrementing io.vcounter
- io.hblank is set for 226 cycles instead of 240
- Video capture DMAs occur on scanlines 2-161, instead of scanlines
0-159
These changes can be observed in
[status-irq-dma.gba](https://github.com/nba-emu/hw-test/tree/master/ppu/status-irq-dma).
When using the accuracy profile, ares now gets within 5 cycles of the
correct value for all tests except video capture DMA.
Fixes CI failing to build after #1412.
`clipsToBounds` is available as far back as 10.9 but not exposed until
14.0, so we have to expose it manually if we're building on an earlier
SDK.
In future, ares should of course be built with the current SDK, but
should support building with earlier SDKs.
Co-authored-by: jcm <[email protected]>
### Status Bar
When building with the macOS SDK included with macOS Sonoma, ares has
had a regression involving an overly large status bar that rendered over
the game viewport, causing confusion as well as being tricky to debug.
It turns out that this was due to a breaking change in AppKit in macOS
14 where an `NSView`'s `dirtyRect` was no longer clipped to its bounds
by default. In short, a view's `dirtyRect` is now often much larger than
its `bounds` if `clipsToBounds` is not defined explicitly. This creates
problems in views that draw by calling `NSFillRect` on the dirtyRect, a
common pattern, as it will fill a rect that is much larger than the
actual bounds.
This PR sets the `clipsToBounds` property for NSView to `true` for views
in ares that draw by filling `dirtyRect`. Accordingly these views'
`dirtyRect` will now always be the same size as their `bounds`.
This was true of `canvas.cpp`, `viewport.cpp`, and `label.cpp`. To avoid
making the change overly broad, and to enable macOS to perform whatever
optimizations it wants to perform, other view types are left alone.
### Splash Screen
This PR also addresses logo clipping issues in macOS on the splash
screen. The dimensions for the logo on the splash screen, as defined,
seemed to be a bit off previously, with the square logo rendering into a
non-square canvas area. For whatever reason, this only clipped the logo
rendering on macOS. The size and padding are adjusted slightly by this
PR. It should not result in regressions on other platforms, but should
be tested to make sure.
> [!IMPORTANT]
> Pwease test on Windows and Linux to make sure the splash screen looks
OK.
macOS screenshot of adjusted splash screen and fixed status bar, built
with Xcode 15:
<img width="1072" alt="Screenshot 2024-03-02 at 1 43 20 AM"
src="https://github.com/ares-emulator/ares/assets/6864788/83504592-03dd-4881-8f3d-0db1fb771f44">
---------
Co-authored-by: jcm <[email protected]>
This PR is a change to pass the [SA-1 RAM protection
test](https://github.com/absindx/SNES-TestRoms/tree/main/SA1RamProtectionTest).
---
242e2fd1a1
BW-RAM protection was not implemented to make Kirby's Dream Land 3 work.
[Reference: Near's post
(nesdev)](https://forums.nesdev.org/viewtopic.php?p=237733#p237733)
This commit implements the conditions under which BW-RAM protection
works as determined from hardware testing.
* BW-RAM Protection will not be reflected unless protection is enabled
on both SNES and SA-1.
* KDL3 sets `CWEN=0`, but `SWEN=80`. not protected.
* `$2228 BWPA` is a register for the SNES CPU, but it also affects the
SA-1 protection area.
---
654f5f02ce
Change the BW-RAM mapping range from $400000-$4FFFFF to $400000-$5FFFFF.
[Reference: SA-1 Hardware Behavior -
SnesLab](https://sneslab.net/wiki/SA-1_Hardware_Behavior#BW-RAM)
---
aa1da58d8b
Initialize the following at SA-1 reset. (change `$2200 CCNT.RESB` 1 to
0)
* CPU data bank register
* CPU stop flag
* IO `$222A CIWP` register
NOTE: The timing of when these registers are reset is unknown because
they cannot be observed in a stopped SA-1 CPU.
I include todo as a reminder that there are many unknown behaviors. I'll
delete it if it's not needed.
KDL3 restarts the SA-1 CPU several times on the title screen.
Before this change, KDL3(JPN: Hoshi no Kirby 3, SHA-1:
`5038596a1ec450d8f1d7cc07759737bfd996e87f`) was not restarting properly:
```log
SA1 008294 sei A:0000 X:0000 Y:0000 S:01ff D:0000 B:00 nv1BdIzc
SA1 008295 clc A:0000 X:0000 Y:0000 S:01ff D:0000 B:00 nv1BdIzc
SA1 008296 xce A:0000 X:0000 Y:0000 S:01ff D:0000 B:00 nv1BdIzc
# (snip)
SA1 0082b1 lda #$ff A:0000 X:0000 Y:0000 S:01ff D:0000 B:00 nvMXdIZC
SA1 0082b3 sta $222a [00222a] A:00ff X:0000 Y:0000 S:01ff D:0000 B:00 NvMXdIzC # B:00 ... write to CIWP
# (snip)
SA1 0082cf pea $4040 [004040] A:3600 X:37ff Y:3800 S:37ff D:3600 B:00 nvmxdIzC
SA1 0082d2 plb A:3600 X:37ff Y:3800 S:37fd D:3600 B:00 nvmxdIzC
SA1 0082d3 plb A:3600 X:37ff Y:3800 S:37fe D:3600 B:40 nvmxdIzC
# (snip)
[Omitted: 3303247]
# reboot from SNES CPU (CCNT.RESB)
SA1 008294 sei A:0000 X:37ff Y:3800 S:37ff D:3600 B:40 nvmxdIZC
SA1 008295 clc A:0000 X:37ff Y:3800 S:37ff D:3600 B:40 nvmxdIZC
SA1 008296 xce A:0000 X:37ff Y:3800 S:37ff D:3600 B:40 nvmxdIZc
SA1 008297 sep #$20 A:0000 X:37ff Y:3800 S:37ff D:3600 B:40 nvmxdIZc
# (snip)
SA1 0082b1 lda #$ff A:0000 X:37ff Y:3800 S:37ff D:3600 B:40 nvMxdIZc
SA1 0082b3 sta $222a [40222a] A:00ff X:37ff Y:3800 S:37ff D:3600 B:40 NvMxdIzc # B:40 ... write to incorrect address ($40222a = BW-RAM)
```
The data bank register `B` has not been reset and an access to a
different address is occurring.
Although not related to BW-RAM protection, other registers probably need
to be reset as well.
Further hardware testing is required.
---
These commits boot KDL3 with BW-RAM protection implemented.
2a1119c68 Merge pull request #113 from scribam/ci-switch-vita
51bd8e969 Add GitHub Actions for Switch and Vita
bd19fbd6f Merge pull request #110 from scribam/zlib-1.3
577f3276c Merge pull request #111 from scribam/c90
5f04e2fdf Merge pull request #109 from scribam/actions-checkout
16ebde42b Merge pull request #112 from scribam/dr_libs
647f42b27 dr_flac: Version 0.12.42
5fd516519 Compilation fix when using C90 with GCC
ea2da72d3 Bump zlib to 1.3.1
4e0aa45a7 Update actions/checkout to v4
git-subtree-dir: thirdparty/libchdr
git-subtree-split: 2a1119c686eb07033d02f8c6d12406f8fd373775
5420f8bee Update README
5c0a2c232 Support recent changes on s390x
ebe11bab4 Support target address for mov_addr operations
a5503d6dd Merge jumps and put_labels
b6b79d5c2 Remove JUMP_LABEL flag
e453c820e Refactor serial numbers of tests (#233)
f63755091 Improve sljit_generate_code on several cpus
9ee290982 Improve code generation on s390x
git-subtree-dir: thirdparty/sljit
git-subtree-split: 5420f8bee8f954fa11c72e4402bb1b9b32a2b11f
Ares checked each of the two input arguments to three-ops functions
separately, but this is not correct. Conditions causing unimplemented
operation on either input (sNAN, subnormal) take precedence on
conditions causing invalid operation on either input (qNAN).
After this fix, Ares passes n64-systemtest COP1 stress test.
Adds a cheat editor to Tools->Cheats when a game is loaded.
The cheat editor should work for all systems except N64 and PS1: support for these will come later.
The code has currently only been tested for MS, MD and SFC but it is assumed all the other systems are also functioning; the code paths are the same.
Code format is standard patch codes in the format X:Y where X is a memory address and Y is a value to place there; most emulators also support this format.
You can use multiple codes in a single cheat by separating codes with a + sign.
Cheats that require memory comparisons are not currently supported, only replacements
Cheats are saved alongside the roms, eg "Game.sfc" will create "Game.cheats.bml".
607158516 Improve serialize interface
dd73cb873 Implement serialization interface
5d2d7cd59 Improve PPC branch support
8b8b6b442 Improve ARM32 branch support
2cfed9ce4 Improve x86, ARM-T2 branch support
6c75e773c Improve riscv branch support
dfeb8cf68 Add extraction macros for operands
dc52b334e Fix typo (#229)
7a821cd71 Add LoongArch float to integer conversion special cases (#226)
cbde0bea6 regex: allow building with a C++ compiler (#224)
40680870e Fix masked shift on arm32
a0643952a Fix sljit_get_register_index on x86-32
80bdff333 Support temporary registers in sljit_get_register_index
4629814f8 riscv: fix getput_arg and load_addr_to_reg (#223)
a26427a6e define float to integer conversion special cases
42128180d build: make code mostly ANSI C89 compatible (#221)
57c212f58 loongarch: fix FTBFS when building pcre2test as part of PCRE2 (#220)
3faacd431 Optimize certain fop1 operations on x86
4f33321c1 Move float/call/simd tests to separate files
230429241 Add another temp register on s390x
fbf9c47f3 Support access to temporary registers
8c5c50463 Implement simd on s390x
02e76fb14 s390x: fix FTBFS with clang (#219)
0bd5147fc Implement simd2 operations
git-subtree-dir: thirdparty/sljit
git-subtree-split: 6071585164d9a38a8890cfd2722ca9d8492528bb
Not required anymore, possibly for a long time. IPL3 does that, plus
this creates correctness issues with open source IPL3 which *doesn't*
initialize those memory locations.
Addresses a few cases where the current horizontal sprite mosaic
implementation is incorrect:
- Transparent pixels should be affected by horizontal sprite mosaic
effects
- If the latched pixel does not have the sprite mosaic effect enabled,
the next pixel should always be latched
- Mosaic offset should not be reset to 0 at the start of a new
horizontal mosaic effect
Accounting for these cases improves visual accuracy of sprite mosaic
effects. This is easily visible in test cases such as
[sprite-hmosaic.gba](https://github.com/nba-emu/hw-test/tree/master/ppu/sprite-hmosaic),
and [Tonc's mosaic demo](https://www.coranac.com/projects/#tonc)
(mos_demo.gba, from tonc-bin.zip v1.4.2).
I've lately discovered that misaligned PI DMA is also affected by RDRAM
writes that must cross RDRAM row boundaries (2048 bytes). It is obvious
in retrospect that the DMA implementation cannot generate a write burst
across different rows, so its internal buffering must be segmented on
RDRAM row boundaries.
The PI DMA testsuite has been updated to cover this edge case as well:
https://github.com/rasky/n64_pi_dma_test
Ares now passes the updated testsuite in full (timing aside, which is
close but not perfect).
This updates most pre-32bit systems to have hardware accurate borders and
aspect ratio where known, reasonable estimates are used where not known.
This also means that PAL games will use the correct PAL aspect rather than
using the NTSC pixel aspect ratio.
All TMS9918 VDP based consoles are thought to be be correct, as are Master
System, Mega Drive, and NES, while SNES and PC-Engine are (educated)
estimates.
The overscan option has been reworked to crop all non-desirable edges of the
screen, including borders and areas that often contain garbage data, previously
this option only cropped the bottom 16 lines of active display.
The reworked overscan is not yet implemented for Atari 2600, PC-Engine, N64 or
PlayStation.
According to NanoBoyAdvance author fleroviux, the prefetch buffer should
be reset on any ROM accesses from the CPU or DMA. This PR implements
this behaviour for CPU ROM accesses. This allows ares to pass 1760/2020
of the timing tests in the mGBA test suite (up from 1608/2020).
Allowing DMA ROM accesses to clear the prefetch buffer seems to worsen
timings at the moment, possibly due to some other timing issues that
also come into effect in these situations. I've left comments to make a
note of the issue, so that resetting the prefetch buffer on ROM accesses
from DMA can be implemented once it becomes beneficial to do so.
The readme references `libsdl2-0.0` which does not exist:
https://packages.ubuntu.com/search?suite=default§ion=all&arch=any&keywords=libsdl2-0.0&searchon=names
I'm not sure it's even useful mentioning `libsdl2-2.0-0` since
`libsdl2-dev` depends on it. Maybe for distributing ares you would then
know people have to install `libsdl2-2.0-0` I guess
Also added a note that SDL2 input allows using a controller on *nix as I
haven't seen that documented anywhere
And I fixed a random makefile indentation issue that messed with my
head.
* Fix the firmware search path not being saved or loaded from the
settings file.
* Fix `FirmwareSettings::findFirmware` not using the right casing when
locating the firmware directory.
Contains three main changes:
* In `Path::program()`, account for the macOS app bundle, so that
portable config support works with the app bundle.
* Create a new function `Path::resources()` for the resources path,
since `Path::program()` can no longer trivially be used to construct the
bundle resources path (no guarantee what the .app is named). On macOS
this returns the path to "ares.app/Contents/Resources", on other
platforms (in case they use it in the future) it just returns the same
as `Path::program()`.
* Fix an issue where, if Ares is stored in a sub-directory of the
desktop, the path settings UI will display paths next to the program as
relative to the desktop instead of relative to the program directory.
When performing a DMA with source and destination addresses both in
cartridge memory, the first write should use sequential access timings.
Implementing this in ares gives more accurate timings for ROM to ROM
DMAs than the previous approach, which instead removed the 2-cycle DMA
starting delay in these cases.
ISViewer is currently gated by the homebrew mode flag. It seems like
this is not ideal for rom hackers because they would still need a way to
log but homebrew mode is too verbose for them and hide the ISViewer
messages in streams of actual problems in game code that they don't
intend to fix. So restore ISViewer functionality without homebrew mode.
This closes the socket server after each successful connection so that
new connections are immediately refused. Before, given that the server
socket was always in listen mode, one additional connection could always
be estabilished at the TCP level, even though the server wouldn't accept
it right away.
Currently, when a client disconnects, the server in Ares fails to notice
and to call the onDisconnect hook, which in turns cause the server to
stop responding (it won't accept a new client, and will never receive
more data from the disconnected one).
This commit fixes it by correctly handling the recv() return code to
detect peer disconnections (return value 0) and any other kind of error
(return value < 0).
Commercial GBA games contain strings in the ROM that correspond to a
save type (e.g. SRAM, flash memory, EEPROM), followed by 3 digits. These
strings are used by ares to detect what save type to use. However, when
running [jsmolka's SRAM and flash memory save
tests](https://github.com/jsmolka/gba-tests/tree/master/save), ares does
not detect a save type, since the programs lack the 3 digits at the end
of the save type string. This PR ignores the trailing digits during save
type detection, since it's likely that many other homebrew programs are
affected by the same issue ([GBATEK even advises developers to not add
digits when including save type
strings](https://problemkaputt.de/gbatek-gba-cart-backup-ids.htm)).
Depending on which cycle they read values from registers, instructions
will read a different PC value. This is handled in ares by adding an
offset to the program counter (r15) value in affected cases. This PR
applies the offset in a few instructions that are affected by this
behaviour, but were previously not covered.
ARM and Thumb mode variants of the ldmia and stmia instructions use a
shared pattern of sequential and nonsequential memory accesses. The
correct pattern was already implemented in ARM mode, and this PR applies
the same pattern to Thumb mode, making the timings of these instructions
more accurate.
### Description
Adds SDL (properly) to Mac builds.
This time, it has been added as a fully fledged optional dependency in
`thirdparty`, à la MoltenVK, and built from source before ares. We build
from source because brew installations are both single-architecture and
not fully portable.
The .dylib is copied inside the app bundle when linking, at the same
stage as MoltenVK.
The initialization of `ares.dylibs` has been moved from ares's Makefile
to the `desktop-ui` Makefile so that it's initialized when building
ruby, which it wasn't previously.
The SDL build is also added to CI, with the same caching methods as used
for MVK.
### Relevant Details
`HEAD` points at SDL 2.28.5 currently, which is the most recent stable
release. This should probably be periodically incremented as
appropriate.
~~SDL is currently built with the macOS deployment target of 10.13.
While SDL's minimum supported macOS version is 10.11, ares CI is using
Xcode 14.2, which has a minimum deployment target of 10.13. I am
currently testing to see if I can get the deployment target lower
without breaking other parts of ares's CI.~~ resolved, per below; SDL
supporting 10.11 is built + bundled.
### Testing
This has been tested to build properly locally and via GitHub CI. The
.dylib is packaged inside the bundle correctly and SDL functions
correctly in my testing, even if the user does not have SDL installed
elsewhere on their system.
This is seeking tests from other Mac users, especially on older
operating systems, to verify that SDL works correctly there.
Co-authored-by: jcm <[email protected]>
Added the minimum macOS version key, but kept it at 10.9 which is what
macOS currently reports it as.
Now that the key is here, it will be easier to update it in the future.
Also added the copyright line attributing the ares team and
contributors.
Some issues I noticed while playing with this on macOS. Took a bit of a
deep dive and attempted to fix them up:
- changing the tracer settings did not seem to change what was logged.
seems to be the row isn't selected when the `onToggle` callback is
called. solution was to instead use the toggled `cell` to get the row
its in. this caused some C++ template issues but removing the `auto`
fixes them all (the alternative being adding `template` to a few method
calls, I should add I'm not a C++ programmer so from my limited
understanding this was the best solution)
- text in text fields were invisible. this was due to
`setForegroundColor` in the macOS backend not properly handling a
0,0,0,0 color. changed to perform the ternary on the `Color` rather than
the `NSColor` (`SystemColor` did not support the ternary)
merry christmas :)
Currently, the n64 core is limited to ROMs whose size is 63.9375 MiB
(also known as 64 MiB - 64 KiB). The reason is twofold: first, only 64
MiB are actually mapped in the PI bus; second, the last 64 KiB are
shadowed by the ISViewer debugging device.
ISViewer addresses sit in the last 64 KiB of the 64th MiB, so when the
ROM is larger than that (for instance, it is exactly 64 MiB), we should
simply disable ISViewer. In the long run, there will be a better
debugging solution which doesn't sit in the PI address space anyway.
Moreover, N64 supports basically ROM of unlimited size, there is no 64
MiB limit. This commit also allows that by simply mapping the whole ROM
into the PI address bus, whatever the actual size is.
When doing PIF HLE emulation, we run the HLE state machine just once per
frame. This is OK in general, but there can be a few situations where
this can cause PIF to miss one command from CPU. For instance, a ROM
might send the PIF boot termination command (0x8) and then shortly after
issue a SI DMA to identify controllers. If the two happen within the
same frame, our HLE emulation would miss the boot termination command.
This commit updates the HLE state machine also after each write to PIF
RAM.
Originally found by vmicka72, so credits to them. Documented as issue:
https://github.com/ares-emulator/ares/issues/1275 and confirmed by
TascoDLX.
Since it is easy and straightforward, no sense in letting it hang
around.
Some unmapped I/O registers on the GBA always return 0 when read. This
pull request implements the required behaviour on six registers that
previously used open bus behaviour instead, allowing ares to pass all
remaining I/O read tests in the mGBA test suite.
Added "Xin1" mapper for the ColecoVision, this mapper supports:
- 31-in-1 (v1.1) ( 2013 )
- 63-in-1 (v1.0) ( 2013/0 1)
Both carts are by "Buzz and ZX-81", and i tested all games for both
multis and they all at least boot perfectly fine
And the "MegaCart" mapper, this mapper automaticly triggers for any rom
over 32k that isnt known to be another mapper (like the "xin1" mapper).
it all should be well with all homebrew games that requite the MegaCart
hardware.
If anyone knows of any other ColecoVision carts like these let me know
and I'll try to add them.
---------
Co-authored-by: Luke Usher <[email protected]>
General fixes:
- model data lines separately from output data latches
- update data lines after control register writes
- distinguish between driven and floating data lines
- remove redundant data latch state from devices
- separate host input polling from data line synthesis
6 button/fighting pad fixes:
- reset timeout only on TH 0->1 transitions
- remain in last phase until timeout (don't wrap)
- read back C/B button state along with M/X/Y/Z
Mega mouse:
- remove erroneous thread synchronize on attach which could crash ares
Affected titles:
- Decap Attack (MD)
- Trouble Shooter/Battle Mania (MD)
- WWF Raw (32X)
### Description
Up to this point, SDL as an input library has not been present in macOS
builds. The plumbing was already in place for macOS to make use of SDL,
but SDL was not actually linked. This PR rectifies that. Seemingly
unnecessary references to the IOKit joypad are also removed from
`sdl.cpp`.
To facilitate adding SDL to ruby for macOS, a stubbed out macOS mouse
driver, `gcmouse.cpp`, has been added, to avoid needing to make numerous
modifications to `sdl.cpp` to work around mouse-related code.
### Motivation
The legacy macOS input uses raw values from IOKit, which are not
available for all supported controllers, and where present, are
uncalibrated and generally not ideal. SDL's input support is much more
advanced comparatively, properly handling and interpolating input from a
wide variety of controllers where raw IOKit input values aren't
sufficient. This should resolve a number of situations where ares won't
recognize input from controllers connected to macOS machines, among
other macOS input-related issues.
### Discussion
I am not super well-acquainted with ares's code and build system, and
it's entirely probable that I missed something here or went about this
not-quite-correctly; I did so as straightforwardly as possible and may
have missed something, for example fallbacks if SDL is not present at
build-time; I am not sure if this is currently handled. I encourage any
and all edits from maintainers if I broke something or went about
something incorrectly.
### Testing?
Tested locally on my Apple Silicon machine on macOS Sonoma. SDL can now
be selected and used successfully as an input driver for all supported
connected controllers.
Co-authored-by: jcm <[email protected]>
As a bonus, use the Unicode ellipsis character in the ares UI on all
platforms instead of just macOS. In addition to looking nicer, it will
make regressions in this area very obvious.
Allow ares to be more easily built against external dependencies on
Windows outside of MSYS2 and using the MSVC ABI.
For example, dependencies can now acquired via vcpkg by installing the
relevant packages (pkgconf, gtk3, qt5, sdl2) and setting up the
environment appropriately before building.
```
CMD:
set PKG_CONFIG=C:\src\vcpkg\installed\x64-windows\tools\pkgconf\pkgconf.exe
set PKG_CONFIG_PATH=C:\src\vcpkg\installed\x64-windows\lib\pkgconfig
Bash:
export PKG_CONFIG=/c/src/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
export PKG_CONFIG_PATH=/c/src/vcpkg/installed/x64-windows/lib/pkgconfig
```
Changes:
- hiro: fix building against gtk/qt with cl
- build: improve pkg-config detection and use with cl
- nall: support dynamic crt with clang-msvc/cl
Doom Resurrection patch version 3.0 (currently at version 3.1) added
support for the Mega Mouse, as well as making use of Mega CD hardware if
available. When I added mouse support for the Mega CD, the patch for
Doom Resurrection was at version 2.2, and since there was no licensed
32X software that supported the Mega Mouse I declined to add support at
the time. But leave it to homebrew, especially one as comprehensive as
this patch to add support.
This adds Mega Mouse support for both the 32X and 32X/CD combo, so it is
now available for all Mega * consoles.
To make sure to intercept all possible errors, the check are now
performed by the RDRAM module, whenever a RDRAM read/write behind a
cacheline happens.
CPU writes to cache is now tracking dirtyness at the byte level rather
than whole cacheline level, so that hardware accessing memory does not
trigger a false positive for false-shared variables. An initial round of
testing has shown that the check would trigger far too much otherwise.
Error reporting is also much improved to provide more context to analyze
the issue, including tracking the PC at which the hardware DMA was
triggered.
For RSP DMA, we do even more: instead of reporting an issue when area of
a cached memory is DMA into RSP DMEM/IMEM, we actually just mark those
memory locations as tainted, and emit the warning only if RSP later
reads them. This is necessary because it is extremely common for RSP
ucode to read data beyond the actual buffers it cares about, even though
that data is then never accesses.
Some of the warnings issues by Ares have been analyzed on Super Mario 64
and Zelda OOT and in both cases they have been confirmed to as real bugs
in cache management made by the game.
For instance, in Mario 64, the programmers forgot to invalidate the
cache before loading data for the initial Mario head animation, as
reported by Ares now:
```
[unusual] PI DMA writing to RDRAM address 0x390650 which is cached (missing cache invalidation?)
Cacheline was loaded at CPU PC: 0xffffffff80183b38
PI DMA started at CPU PC: 0xffffffff80328558
```
The game just happens to work because after loading, the game does
something else and manages to get the cache invalidated by touching
other locations, but otherwise it would be a real bug.
As another example, in Zelda OOT, we get these warnings at boot:
```
[unusual] AI reading from RDRAM address 190820 which is modified in the cache (missing cache writeback?)
Cacheline was loaded at CPU PC: ffffffff800b54fc
Cacheline was last written at CPU PC: ffffffff800b5528
[unusual] RSP reading from DMEM address fe0 which contains a value which is not cache coherent
Current RSP PC: d10
The value read was previously written by RSP DMA from RDRAM address 00199e40
RSP DMA started at RSP PC: abc
The relative CPU cacheline was dirty (missing cache writeback?)
Cacheline was loaded at CPU PC: ffffffff800b5244
Cacheline was last written at CPU PC: ffffffff800b5264
```
These warnings appear to be real bugs in the audio library. Quoting
Thar0:
```
* AudioHeap_ClearCurrentAiBuffer/AudioHeap_ResetStep wipe the AI buffers with CPU writes and
then don't write back the cache, and I guess an AI DMA is either in progress or starts before it can
be properly flushed. On boot this shouldn't matter as gAudioHeap is BSS and is already zero, but
if the driver is reset later it might cause some minor issues?
* The RSP cache coherency problems is from loading filters in AudioHeap_LoadLowPassFilter.
The heap allocator returns a pointer to which the CPU writes the filter data.. but the allocator
writes back the cache before the CPU writes the data 😂
```
Moreover, this PR also implements all the known SysAD-related CPU
freezes that cause the console to crash. We now pass the
[n64-systemcrash](https://github.com/rasky/n64-systemcrash) testsuite in
full.
Improvements to fds irq generation logic, to match description at
https://www.nesdev.org/wiki/Family_Computer_Disk_System#Timer_IRQ_control_($4022)
- Fixed "i/o enable" register address
- Correctly acknowledge interrupts in writes to $4022 / $4023
- Improve irq generation logic
The changes are based on the discusion on this thread:
https://forums.nesdev.org/viewtopic.php?t=16507
With this pr ares passes all 21 tests on FdsIrqTestsV7 (many failed
before), which can be downloaded at
https://forums.nesdev.org/download/file.php?id=10240
In addition to passing the tests this pr also fixes Kaettekita Mario
Bros. (Japan): this game has 3 random opening animations before
requesting to switch to side B, two of these openings will display a
glitchy screen with old irq logic. This can be tested by just resetting
if the game shows the animation that works.
Instead of directly specializing std traits classes (which would result
in undefined behavior) define our own traits classes that inherit from
the std types.
This allows us to remove a hack in the serializer class and paves the
way for building ares with Qt on Windows.
- remove -stdlib=libc++ as it caused warnings when applied to C files
and has been the default on macOS for something like a decade
- add -Wno-deprecated-declarations to the command line to silence
warnings about things like sprintf in thirdparty
This option is usually enabled by default by GCC/Clang with -O1 and
above. This is not true on some targets like macOS/arm64, and there we
are better off deferring to the compiler anyway.
This became an issue because Xcode 15 shipped with a new linker that, at
least when LTO is enabled, appears to mess up metadata that is used to
unwind the stack during exception handling. Without a frame pointer to
fall back on, unwinding fails completely and causes ares to terminate.
In addition to approximating the correct values in SI STATUS fields,
this commit also fixes a bug: I/O writes to PIF RAM do trigger an
interrupt just like DMA does.
Disable "fast fail" so jobs will run to completion even if others fail.
The workflow as a whole will still fail, but the jobs that succeed will
produce downloadable artifacts.
Secondly, allow the "macOS: Import Certificate" step to fail on forks.
This allows CI to function on forks without any other setup, though the
produced macOS builds won't run actually run unless you re-sign them.
We frequently get issue reports in GitHub and Discord about driver
settings not being saved. This is due to the fact that changes to
drivers requires using the Apply (formerly Reload) button for changes to
stick, which is different than other options in the settings window.
With this change, the Apply button is grayed out until a different
driver is selected, hopefully making it more obvious that the buttons
need to be used. A small note was also added at the bottom explicitly
stating that they Apply buttons must be used in order to switch/change
updates to driver selection.
From the MSVC docs: "You can use the /permissive- compiler option to
specify standards-conforming compiler behavior. This option disables
permissive behaviors, and sets the /Zc compiler options for strict
conformance."
While generally a positive thing, this does make MSVC stricter than
GCC/Clang in some cases. A couple of things popped out:
- nall::multiFactorImage had a busted constructor. I fixed this and did
some other cleanup while I was at it.
- nall::string has an implicit conversion operator to const char*. This
is honestly really ugly and creates ambiguity and allows for all kinds
of surprising silent conversions. Unfortunately, fixing that (by making
it explicit) will require touching hundreds of lines of code so I opted
not to deal with it now. Instead I fixed the much smaller number of
ambigous cases relating to string literals.
As noted in the Chromium source, the value for
NSTreatUnknownArgumentsAsOpen needs to be of type string despite being a
boolean setting.
If the type is boolean, AppKit throws an exception (which is caught),
but if unwinding fails (observed on some arm64 systems in certain build
configurations when ares is compiled with LTO and -fomit-frame-pointer)
it terminates the whole application.
I've confirmed the behavior the original commit was designed to correct
is still fixed with this change.
MMC3 and MMC6 share the same mapper in the iNES format. To disambiguate
MMC6 from the MMC3 mapper the NES 2.0 submapper 004:1 should be used:
https://www.nesdev.org/wiki/MMC6
Code for using the MMC6 was actually commented in mia/medium/famicom.cpp
up to commit bed4ce3659, where it was deleted. This commit
reintroduces this code to use it with the NES 2.0 submapper 004:1. This
adds compatibility with the games "StarTropics" and "Zoda's Revenge:
StarTropics II".
Fix two issues caused by disc swap timers:
1. Crash on exit in certain build configurations
2. Crash on system unload shortly after disc swap
Because these timers were simply members of Emulator derived classes
(which are in turn owned by a global variable), they were being
destructed after main() along with other static lifetime objects. This
was problematic because hiro also has global state that the timer
implementation depends on, at least on Windows. Whether this manifested
in a crash depended on a few factors, object destruction order among
them (which is at the mercy of the linker).
The second crash would reliably reproduce simply by initiating a disc
swap and unloading the emulated system (such as by closing the emulator)
within the next 3 seconds.
The following applies only to macOS when JIT page protection is enforced
(namely on Apple silicon).
A sequence of jitprotect(false) calls must now be followed by an equal
number of jitprotect(true) calls to restore executable protection. A
further assumption is that nesting always starts with (false), which is
only logical because you have to write something before you have
anything to execute. This is explicitly checked in debug builds.
The N64 and PS1 recompilers have needed this since commit 8ed4af8 in
order to handle the path taken on recompiler cache flushes. It's subtle,
but emit() will evict all pools and so the second call to pool() from
block() will reallocate the pool and unexpectedly toggle the protection
out from under it.
Technically the SH2 recompiler has needed this since commit 241f0e9
(from 8 months ago!) but that same commit made cache flushes practically
nonexistent, so it's likely not impacting the retail title library.
The CPU will freeze until power-off if a cached access is performed to a
non RDRAM area. This obviously never happens with games, but it is a not
so uncommon error when doing very low level development on the system.
This patch emulates the freeze for the data cache, and for the
instruction cache when using the interpreter. Implementation for
instruction cache and recompiler is left as a followup.
To prevent undue performance losses, the extra codegen only occurs when
tracing is enabled. To support toggling tracing on/off during execution,
the recompiler cache is flushed on setting changes.
Flushing the recompiler cache has its own side effects, but that's
already an issue, and it seemed the least bad way to isolate the impact
of this feature.
Add ability to enable/disable N64 4MB expansion pak.
Similarly to the video settings window, I've added a Nintendo 64
specific section in the options window, which was mostly empty. Existing
options fall under a generic "Emulator Options" section. Seems like a
reasonable place to add a few console specific options.
Addresses issue: https://github.com/ares-emulator/ares/issues/939
Currently, we detect the CIC to emulate by calculating a CRC32 over IPL3
bootcode in ROM, and keeping a database of the known IPL3s. This works
because right now there are only a handful of IPL3 variants (exactly one
per CIC).
In preparation for libdragon releasing an open source IPL3 that could
evolve and be forked an unbounded number of times, we must stop keeping
a database of IPL3s.
This commit changes strategy: it simulates the IPL2 checksum hash over
IPL3 (which is exactly what a real N64 does at boot) and verifies if the
checksum matches that expected by any of the known CIC variants. This
works because open source IPL3 variants must anyway have a checksum that
collides with that of CICs (which must be obtained via a second preimage
attack, bruteforced on GPUs), otherwise they would not work on real
hardware nor on Ares itself (which correctly simulates the boot sequence
and would refuse to boot an "unsigned" IPL3).
Level 2 warnings are considered "significant" and turning them on
revealed one issue that could, in the future, have affected MSVC-ABI
builds using either CL or Clang.
MSVC's C++ name mangling distinguishes between classes and structs, and
throughout the ares codebase there were friend declarations using
"class" to refer to types that were defined with "struct".
I don't see any value in retaining this inconsistency, especially
considering that ares otherwise avoids the "class" keyword (though I
spotted a few uses that crept in from recent commits).
Implements port 0x60 bit 1 and 3, a newly-discovered way to change the
cartridge SRAM and I/O bus speed. Also fixes a regression, and adjusts
the ROM bus speed to match a test ROM.
~~Marked as draft as validation on ASWAN ("mono" system) is required.~~
Nobody stepped up for 3 months, so, ehh. It's still more accurate than
it was.
Level 1 warnings are considered "severe" and, unsurprisingly, turning
them on revealed some true bugs.
- file-buffer.hpp: What should have been a zero extend followed by a
complement was instead a complement followed by a zero extend,
inadvertently truncating the file seek offset to 32 bits.
- file-map.cpp: What should have been a nullptr check after
CreateFileMapping() was instead a check for INVALID_HANDLE_VALUE. The
warning pointing me toward this was not technically about the misuse but
rather the redefinition of INVALID_HANDLE_VALUE in nall. I've removed
this and any reference to INVALID_HANDLE_VALUE except for error checks
immediately after calls to the few APIs that return it.
The WASAPI driver in ruby is a bit of an oddball. It has a fixed length
circular queue for samples, and before this commit there was no logic to
prevent queuing more than the requested "latency" number of samples or
even to prevent the queue from overflowing entirely.
In practice this wasn't much of an issue when audio or video
synchronization were enabled and therefore bounding the rate of audio
generation. It did not, however, play nice with the fast-forward
feature, and it caused a noticeable pause after returning to normal
speed as the queue drained from whatever level of fullness it had
wrapped around to (effectively random but averaging over half a second).
Now the length of the sample queue is (mostly) bounded to the "latency"
parameter which is more consistent with the other drivers.
Fixes#958
- add more details to the dd time.rtc format as comments for readability
- fix dd rtc skipping december entirely (wrong comparison)
- I feel really dumb for this one.
- add validity checks on every rtc second tick to avoid glitchy rtc time
& date
- This also avoids the user to be able to skip the time & date error
into a glitchy rtc by simply restarting.
- add validity check on load if the time is valid or not, if not valid,
destroy the rtc info to get the user to input new rtc info
This effect runs on the CPU, which is expensive for HD content and
incredibly so for UHD content. It doesn't make much sense to apply to
non-SD content, in any case.
Currently this only affects the N64 core in HD and UHD modes.
c1cbaf09e x86: avoid clobbering ebx register during CPU detection (#217)
62c91605a cpuid on x86 clobbers memory
856fce15d loongarch: sljit_emit_atomic_load/store implementation using LoongArch V1.10 (#216)
44cee7aa5 allocator: add support for PowerPC in Apple (#214)
e09319736 Improve Windows compatiblity
112fd4119 Add AVX detection
2713dda05 config: use standard interface to detect macOS version (#213)
029327875 Fix addc and subc on arm32
6a718f07d Improve simd lane mov on x86
292bf2e63 The bug is in the generation of a call relative instruction (because this is PIC code). Call relative of 0 will run the next instruction. So call relative is relative to the next instruction, not the current instruction. (#208)
b6f010324 s390x: make sljit_generated_code_size() accurate (#209)
e2c460881 Improve simd lane replicate on x86
73e84319c arm: small improvements for atomics with LSE (#210)
0436b57a6 Improve sljit_emit_simd_extend
ff4c77263 mips: improve FPU detection also for MIPS64 (#205)
6d1376f84 Improve x86 code generation
a443763e4 build: clear warnings with gcc12 and improve Makefile (#191)
d78063a88 ppc: correctly implement SLJIT_REV in 64bit little endian (#193)
git-subtree-dir: thirdparty/sljit
git-subtree-split: c1cbaf09e995d4d2ab87a85b2ed6a27f4e123754
This incorrectly implies that we support the old .smd rom format that used to be standard prior to .bin/.md;
This format is an interleaved format designed for the Super Magic Drive copier and ares does not support it
To prevent confusing users who may sill have legacy .smd files around, I'm removing the extension from mia.
This adds:
- 64DD Disk Swapping for both 64DD standalone games and N64 Combo games
(only if a disk is loaded).
- Safety checks to prevent corruptions.
- Change manufacture timestamp and line to differenciate different disk
files from each other to avoid confusion
Adds D64 file format support, which is the official master 64DD data
file format, which is basically NDD but a lot of the useless data
trimmed out and disk formatting data kept to a minimum.
Works in this way:
- Adds *.d64 file extension to the list.
- Redo code that uses clearer variables to keep track of recognized 64DD
disk file format.
- Add a file size check to do a proper format recognition and avoid
errors.
- Additional data validity checks.
- D64 conversion to the internal disk format (I refer to it as MAME
format) by reusing the same algorithm as NDD while ignoring blocks of
data that are not present.
More information:
https://www.nesdev.org/wiki/Expansion_Port_Sound_Module
While this is a homebrew device, it has already shipped to consumers in
this manner.
TODO (I'm not sure how to fix these issues myself):
- [x] Switching from EPSM back to another peripheral (None or Family
Keyboard) unloads not just the additional EPSM-provided audio streams,
but seems to break *all* audio from the NES core.
- [x] NES 2.0 cartridges can declare that they wish to have the EPSM
peripheral installed by default (Extended Console Type 0x04), but I'm
not sure how to hook this nicely from the pak data to the expansion port
node.
- [ ] Missing serialization, but this affects the Family Keyboard to
some limited extent already, so...
Not urgent at all. It has shipped to consumers, but the amount of
software using it is still lacking.
---------
Co-authored-by: Luke Usher <[email protected]>
This PR adds a new general setting called "homebrew mode", that can be
used as an umbrella setting for all kind of developer-related aids in
the emulator. This will also allow resource intensives checks to be
added (eg: N64 RDP command list validation).
For now, we hook this to the N64 core only in two ways:
* ISVIewer emulation is now only performed in homebrew mode. This is
obviously not resource intensive, but it would have naturally been an
homebrew mode feature, if it existed at the time. Normally, games should
behave exactly like on a real N64, where there is no ISViewer peripheral
plugged in into the PI bus.
* A new cache coherency check is added to PI DMA. If a DMA is performed
to/from RDRAM locations for which the CPU holds a valid cacheline, a
warning is emitted to the console as the game is probably buggy.
Slightly unrelated, a commit also adds a new "DCache" memory viewer, to
see the memory from the point of view of the CPU (so with data cache
taken into account). This is useful to ROM hackers which don't care
about the physical RDRAM contents but rather the memory contents as
written by the CPU.
The latest macOS runner updated the version of python to 3.12.0.
This removes the deprecated distutils core module, requiring the "setuptools" package to be installed to provide it.
distutils is a dependency of MoltenVK.
>Regarding PLB, it looks like it reads from $200 and snes9x, mesen,
bsnes, and the official CPU manual all got it wrong.
Reproduced and verified on real hardware via
https://github.com/gilyon/snes-tests
This implementation was based on our Z80 implementation and as such, has the following quirks:
1. Z80 style opcode mnemonics rather than intel style
2. Has an internal WZ register than a real 8080 lacks
3. May not have fully accurate timing
Despite this, it passes every test in this harness and is correctly detected by CPUTEST.COM as an 8080 rather than a Z80.
The remaining quirks can be addressed as needed
1. Bus refreshes needed a clean up and readjustment. Timings were
compared against US Model 1 VA3 via Ti_'s test_inst_speed rom. Yellow
values are ok, as they normally skew lower due to refresh. Some reds
still remain (of the regular instruction tests) that appear to be off by
1.
2. Basic implementation of delays incurred on both main 68k and z80.
Delay values are tuned according to Ti_'s misc_test rom tests ("Z80
DELAY ON ROM READ", "M68K DELAY ON Z80 ROM READ"). Hardware tests
indicate that z80 delay may skew lower towards 170, while m68k delay
typically sticks to 460. This change puts ares at ~178 z80 delay & ~461
68k delay. Fixes#255.
3. Trivial readjustment of m68000 interrupt timing. Approx'd autovector
delay changed to 14 cycles, which happens to be the median of the
expected range (10-18).
Commit history shows that these were initially added to get audio working in OverDrive 2, but now it works better without them.
Having these additional delays present caused audio to stop working late in overdrive 2's execution, most likely due to causing extended delays and confusing timing sensitive code.
While fixing the observed behavior in games, it also fixed things that are known to be broken on hardware; needs further work.
This reverts commit 785edf60c8.
Compatible with the current MAME romset at time of writing.
This system only has three games:
- Champion Boxing [cboxing]
- Champion Pro Wrestling [chwrestl]
- Doki Doki Penguin Land [dokidoki]
Known Issues:
- No support for configuring DIP switches
- Champion Pro Wrestling [chwrestl] is not working due to encryption
A file is regarded as a Famicom Disk System Bios when
1. It is 8KiB in size, AND
2. it contains the Famicom License DRM/Trademark security string at offset 0xd37
Before this change, the OPN2 thread had to play catch-up, generating a
bunch of samples and potentially overflowing the resampler queue in the
audio stream, as observed in Shining Force.
macOS 14 (Sonoma)'s Game Mode offers some small benefits for ares,
including lower latency for bluetooth peripherals and potential minor
performance gains. The system has various ways of detecting that an
application is a game and enabling game mode, but ares does not
currently engage it. Adding the "Games" app category key value pair to
the bundle .plist is one way of hinting to macOS that Game Mode should
be enaged. In my testing, adding this key to ares's bundle .plist
successfully activates Game Mode when ares is fullscreened.

Co-authored-by: jcm <[email protected]>
sljit performs a single (potentially) oversized executable memory
allocation before generating code. Instead of reserving the requested
amount of space, we can reserve only the used amount and eliminate some
dead space between code blocks.
In some cases sljit may write extra data beyond the generated code.
Because of this, it is no longer safe to assume the remainder of the
code cache is zero initialized. In practice, this assumption only
affected pools which can easily zeroed on demand. This also saves time
on code cache flushes, as we no longer zero the entire cache at once.
- align static code cache to 64 KiB (up from 4 KiB)
- remove dependency on alignas() and associated build workaround
- check for mprotect() failure and fall back on dynamic allocation
- perform dynamic allocation (if needed) at top of main on all platforms
Commit 9422ea5905 introduced support for
resetting the 32x SH2 CPUs from the MD 68k CPU, and it also created a
couple of new issues.
1. SH2::power() tries to allocate from a fixed bump allocator, but that
allocator is only reset from M32X::power(), which is not called in
response to a reset register write. In practice this meant we were
falling back on dynamic allocation, creating performance issues when the
allocation is distant from the ares executable.
2. The code cache could be released out from under a running SH2 libco
thread we switched away from to run the 68k thread.
This change fixes#1 and partially addresses #2, but it doesn't address
the issue of an already executing SH2 code block resuming where it left
off after a reset. I don't currently have a test for this case, so I'll
leave it for a later change.
sljit performs a single (potentially) oversized executable memory
allocation before generating code. Instead of reserving the requested
amount of space, we can reserve only the used amount and eliminate some
dead space between code blocks.
This PR may necessitate more third-party verification than usual. It
also allows for detection of the correct MMC5 board based on NES 2.0
header alone.
bc844c90a Implement vex prefix encoding on x86
3551015c7 mips: enable SLJIT_HAVE_REV for SLJIT_MIPS_REV >= 2 (#203)
3dcdb2575 mips: allow detection of StatusFR with prctl() (#202)
03d40019b mips: fix little endian (#197)
8dcad370c loongarch: implement sljit_emit_fop2r() (#201)
90df876ec mips: correctly detect valid FPU and support StatusFR=1 in 32bit (#200)
5628f9065 Implement full f32 register access on arm32 and mips32
2e0a7b9b7 Double the range available for register indicies
ce85ea911 mips: fix SLJIT_COPYSIGN in 32bit (#199)
2d177ccdc mips: fix sljit_emit_fcopy() for 32bit (#198)
0aed5d4dd s390x: sanitize warnings with clang 15 (#192)
831ea3ec4 mips: fix implementation of sljit_emit_fset64 in 32bit mips (BE) (#196)
abda1b90f mips: add missing ADJUST_LOCAL_OFFSET for sljit_emit_select (#195)
bf5e9a145 atomic: avoid unused checks if not implemented (#194)
c4dc1c8a7 Implement sign extraction on x86, arm
1eaeac321 arm: fix unaligned REG_PAIR thumb2 operations (#190)
63de0d9f6 arm: restrict NEON/VFPv3 code in sljit_emit_fset{32,64} (#189)
108a4b410 arm: restore emulation for SLJIT_CTZ in armv6 (#187)
abe5001d8 arm: use armv6 compatible instructions for thumb2 in atomic (#186)
0821be0b6 simd: prevent SIGILL with armv6 (#184)
be7b02a41 Better simd checking in the tests
299ae4ae7 Implement element extension on x86, arm
976e5d813 Be explicit about OS version (#179)
351d9afc7 x86: really detect SSE41 (#181)
8a3c0d1d8 x86: correctly detect SSE41 (#180)
dfff60447 Implement simd zero before lane set on x86, arm
0e4cbc9a8 Rename SLJIT_INT_REGISTER to SLJIT_GP_REGISTER
12d36226e simd: avoid unused parameter warnings (#178)
5c15decbf Implement sign extended lane store on x86, arm
44d8136d1 Implement lane replication on x86, arm
31556f80e Implement lane replication on x86, arm
750987e45 Implement simd mov reg on x86, arm
d17bf952d Implement simd source duplication on x86, arm
d9c74c990 Remove MEM prefix from several simd constants
a2c65c3c7 Implement simd lane transfer on x86, arm
38d96705b Fix incorrect branch offset calculation (#177)
87f9e7791 Rework sljit_get_register_index
git-subtree-dir: thirdparty/sljit
git-subtree-split: bc844c90ac79e7d56c04182e010c6aa8e5957b24
Fix various recently introduced build issues.
Some background for the string indexing thing: using operator[] to index
nall::string causes some ambiguous overload errors in 32-bit builds.
This isn't the first time it's come up, but since it's so easy to work
around (using operator() instead) I haven't bothered to try to fix it.
This PR adds a generic GDB server to ares with the ability to be used by
all systems.
For now only the N64 systems was implemented here.
Most documentation on how the server/TCP socket works can be found in
comments.
A detailed documentation for ares developers on how to add this to other
systems is included in the `Readme.md` file.
The feature itself was also already tested by a few people on both linux
and windows (with WSL) and seems to be stable now.
The data is still loaded sequentially and accesses will block until the
data at a given address is available. In the worst case (an immediate
read at the end of the last track) things are no faster than before, but
it still feels better because the UI responds immediately to the user's
load request.
This could be further refined by skipping ahead to serve incoming reads.
Up until 67d1647d6e, clang was the assumed
compiler on macOS and BSD, and g++ was the default everywhere else.
After that commit, we defaulted to clang on all platforms if it was
found in the user's path. It has since become clear that while a number
of Linux users have clang in their path, many have not installed
critical packages necessary to build C++ software and are completely
unaware of this state of affairs or which packages need installing.
To simplify matters, we will revert to the default of g++ on systems
other than Windows, macOS, and BSD. Additionally, the `verbose` target
will now print the compiler in use, as this is pretty relevant
information for diagnosing build issues.
This allows for firmware to be set from a user selectable firmware directory at the click of a single "Scan" button on the firmware configuration screen.
1. Fix timing relationship between cpu and tia,
2. Implement latching of current playfield pixel
3. include "current cycle on this scanline" counts in cpu trace output
Instead of assuming pkg-config is available with bash, test for its
presence. This allows the build to function if using bash without
pkg-config or using cmd with pkg-config.
Instead of assuming the sdl2-config is available if pkg-config indicates
that SDL2 is present, just use pkg-config directly to acquire the
compile and link arguments. Again, this allows the build to work with
cmd (since sdl2-config is a bash script) and if your copy of SDL2 just
didn't come with sdl2-config (for example, from vcpkg).
On Windows and Linux, ares uses a buffer in the bss section for the
recompiler code cache. On macOS this buffer must be dynamically
allocated for security reasons. The distance between the code cache and
the rest of the ares executable has a large influence on performance on
all platforms because there are microarchitecural thresholds beyond
which branches will never be correctly predicted by the CPU.
To make performance more consistent on macOS, we can make this dynamic
allocation sooner, at the top of main(), before the address space has
become too cluttered with allocations made by other code.
In addition to detecting the pattern `beq 0,0,<pc>` for idle loops,
detect the pattern `j <pc>`.
From a selection of about 60 games, about half used beq, a quarter used
jump, and a quarter had nontrivial idle loops.
Additionally, this commit returns the step time for idle loop
acceleration to 64 CPU cycles (128 system cycles). This was accidentally
halved in commit ffcce5823c.
Some instructions should complete faster for simple inputs (notably
mul), but this is not yet implemented. The extra cycle delay imposed by
the next instruction depending on the output of the previous is also not
implemented, as there is currently no framework for emulating pipeline
effects in the main CPU.
aa71425db Improve info provided about simd
b5f214edb Implement simd load/store on x86, arm
dd683ab67 build: add barebones cmake for Windows (#123)
13d577046 Implement copysign on ppc, mips
9637d82c9 loongarch: implement copysign (#176)
7c78ea2e1 Implement copysign on s390x
9764568d0 Implement copysign on x86, arm, riscv
d2363accc s390x: fix atomic store emulation when offset in higher int (#175)
18fc38fe3 config: allow CPU specific configurations (#174)
818706a80 loongarch: fixes and other cleanup for portability (#171)
db433181a add base support for LoongArch 64bit (#170)
git-subtree-dir: thirdparty/sljit
git-subtree-split: aa71425db565916d1ebaef107df295d66626e963
- Beetle Adventure Racing (J): Replace "NBB" with "NB8" (fix substitution).
- J.League Live 64: Replace "NLJ" with "NJL" (fix transposition).
- Quake 64: Replace "NKQ" with "NQK" (fix transposition).
- Star Fox 64: Remove "NFP" variant. This was printed on the box/manual
in some regions but only "NFX" appears in the ROM.
Implement vector unit (VU) timing including dual issue with the SU.
Tested against real hardware with a random instruction stream generator.
Known limitations:
- Invalid/missing instruction timings not implemented.
- CFC2/CTC2 dual issue restrictions not implemented.
- Some corner-case dual issue restrictions (e.g. LTV + VNOP) not implemented.
On real hardware, VU instructions with a DE operand are sometimes prevented
from dual issuing with vector loads under seemingly erroneous conditions.
**ares** is a multi-system emulator that began development on October 14th, 2004.
It is a descendent of [higan](https://github.com/higan-emu/higan) and [bsnes](https://github.com/bsnes-emu/bsnes/), and focuses on accuracy and preservation.
It is a descendant of [higan](https://github.com/higan-emu/higan) and [bsnes](https://github.com/bsnes-emu/bsnes/), and focuses on accuracy and preservation.
It's worth noting that ares takes some uncommon design approaches that essentially trade speed for code clarity. We avoid state machines and bitmasks (when possible). Most cores end up being half the amount of code, but slower. The code is clearer and less spaghettified, especially for systems with lots of processors. C bitfields being non-portable incurs a speedhit. Windows also has a speedhit over Linux due to its ABI needing more instructions to switch contexts.
Official Releases
-----------------
@@ -14,90 +16,18 @@ Official releases are available from
Nightly Builds
--------------
Automated, untested builds of ares are available for Windows and macOS as a [pre-release](https://github.com/higan-emu/ares/releases/tag/nightly).
Automated, untested builds of ares are available for Windows and macOS as a [pre-release](https://github.com/ares-emulator/ares/releases/tag/nightly).
Only the latest nightly build is kept.
Prerequisites
Building ares
-------------
### *nix building
###### Minimum required packages:
```
g++ make pkg-config libgtk-3-dev libcanberra-gtk-module libgl-dev libasound2-dev
```
###### Additional Audio Drivers
ares supports additional audio drivers besides the ALSA drivers included above. Installing these additional packages will allow them to be selected in Settings > Drivers:
`libao-dev libopenal-dev'
###### GTK2 & GTK3
By default, GTK3 is used, but support for GTK2 is available. You will need to install the additional package `libgtk2.0-dev` as well as specifying the command line option `hiro=gtk2` at compile time.
###### SDL2 for input
If you would like to use SDL for input, you will need to install the following the `libsdl2-dev` and `libsdl2-0.0` packages and perform a clean build of ares. You should then be able to select SDL for input in the Settings > Drivers menu.
##### Building with clang
clang++ is now the preferred compiler for ares. If it is detected, the build will default to building with clang. It is necessary to install both the `clang` and `lld` packages. If you would like to manually specify a compiler, you can use the following option: `compiler=[g++|clang++]`
--------------
### Windows building
To build on Windows, using MSYS2 is recommended which can be download [here](https://www.msys2.org/). Follow the instructions
on this page to install and setup an appropriate MINGW64 environment. Running the command:
from the MSYS2 MSYS terminal should setup everything you need to compile ares. Note that in order to compile, you will want to be in a MINGW64 terminal window after install and setup is complete.
##### Building with clang
clang is available through Visual Studio (or Build Tools for Visual Studio) through its installer and can be used to build ares. You will still need to supply GNU make in this instance. MSYS2 also offers a clang environment. You will want to make sure you select the clangw64 option during installation of MSYS2 which should provide and additional CLANG64 pre-configured environment. Install the clang toolchain package from the MSYS2 terminal:
```
pacman -S mingw-w64-clang-x86_64-toolchain
```
Once complete, open a CLANG64 terminal window and proceed with building ares.
###### Debug Symbols
When building with clang, by default symbols will be generated for debug builds using an MSVC compatible format (CodeView) for use with Windows debugging tools. In order to generate GDB compatible symbols, specify the following option: `symformat=gdb`
Compilation
-----------
Check out the source code by running this command:
`-j#` indicates number of parallel build processes, and shouldn't be set higher than N-1 cores on your processor. Specifying this option can significantly decrease the time to build this project. There are multiple build types available and it defaults to an 'optimized' build. Build types can be specified using: `build=[debug|stable|release|minified|optimized]`
Build options can be found in the following two make files: nall/GNUmakefile desktop-ui/GNUmakefile
To start compilation from the beginning, run the following prior to compiling:
```
make clean
```
#### Building specific cores
If you would like to build a subset of cores, you can specify the `cores="core1 core2"` option. Currently available cores:
```
a26 fc sfc n64 sg ms md ps1 pce ng msx cv gb gba ws ngp spec
```
Build Output
------------
There is a single binary produced at the end of compilation which can be found in `desktop-ui/out`. On OS's besides Linux, the `Database` & `Shader` directories are copied over here as well. On Linux, running `make install` after compilation will copy these directories and binary into suitable locations (see desktop-ui/GNUmakefile for details). Alternatively, these directories can be copied from `ares/Shaders/*` and `mia/Database/*`.
ares supports building on Windows, macOS, and various Linux/BSD distributions. See buildinstructions for:
Loaded 100 of 2903 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.