Compare commits

...
1054 Commits
Author SHA1 Message Date
Luke Usher 39025af1fe release ares v136 2024-02-23 17:02:48 +00:00
Luke Usher 5cdefb088d desktop-ui: cleanup resource search paths
As well as simplifying the code a little, this also  fixes an oversight where users could not override application resources on macOS.
2024-02-21 17:49:12 +00:00
Giovanni Bajo d0253599a6 n64: fix corner case in FPU exception handling (#1400)
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.
2024-02-20 23:34:38 +00:00
Luke Usher 1e83da0241 md: implement subchannel processing for mcd (CD+G) 2024-02-19 14:19:56 +00:00
Luke Usher ed0a1c8852 cheats: only create a cheat file when cheats are added
This also cleans up empty cheat files on unload.
2024-02-18 08:41:56 +00:00
Luke Usher dd9c728a12 ares: preliminary cheat support
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".
2024-02-16 19:01:57 +00:00
Luke Usher 7ec1e1430c fc: reduce overscan cropping similar to ms 2024-02-15 17:35:47 +00:00
Luke Usher 16379aabff ruby: use PRESENTINTERVAL_ONE rather than GetRasterStatus for VBlank with d3d9 2024-02-15 17:34:30 +00:00
Luke Usher 11f24b47c3 ms: adjust overscan cropping, it was a little too agressive 2024-02-15 17:33:51 +00:00
Luke Usher 32f205975c md: add CD PCM RAM to debug memory viewer/editor 2024-02-14 17:45:50 +00:00
png183 21ca9cf76e gba: timer 0 count-up bit cannot be set (#1392)
The count-up bit for timer 0 cannot be set on hardware ([test
ROM](https://github.com/png183/gba-tests/blob/master/timer/timer_check_count_up_presence.gba)).
This PR implements said behaviour in ares, preventing timer 0 from
incorrectly halting if this bit is written.
2024-02-14 10:14:39 +00:00
Giovanni Bajo d32b3ffe45 n64: revert previous commit (add HLE RDRAM initialization) (#1391)
This is actually still required as we still skip RDRAM initialization
anyway and proprietary IPL3 doesn't initialize the RAM size in this
case.
2024-02-14 10:14:20 +00:00
Luke Usher 5864382c67 ps1: various fixes to GPUSTAT register behavior 2024-02-13 22:34:03 +00:00
Luke Usher f392e4f428 libchdr: disable asm optimisation for zstd
Should fix the Ubuntu build.
2024-02-11 19:51:28 +00:00
Luke Usher d0075978f8 libchdr: rollback lzma to 19.00
This version still exists in the repo for libchdr
22.01 fails compilation on many platforms right now
2024-02-11 19:37:46 +00:00
Luke Usher c1e5777dc1 thirdparty: fix compilation after libchdr update 2024-02-11 19:16:41 +00:00
Luke Usher ec6c9fc330 Merge commit '9bc95db1f0c5591dfbcec23c8e326aa6c2bb3b29' 2024-02-11 19:16:32 +00:00
Luke Usher 9bc95db1f0 Squashed 'thirdparty/libchdr/' changes from 9108f34a8..2648c221c
2648c221c Merge pull request #108 from herbymachine/master
f7729588b Update libchdr_huffman.c
26d27ca49 Merge pull request #106 from zakk4223/zstd
d6f59e748 Add zstd codec

git-subtree-dir: thirdparty/libchdr
git-subtree-split: 2648c221c9ce6b49600ed7d2eb45c9e6e593790f
2024-02-11 19:16:32 +00:00
Luke Usher 6d80a8e940 Merge commit '2a0f9651b976a5431510222e04077fd360415d69' 2024-02-11 19:16:30 +00:00
Luke Usher 2a0f9651b9 Squashed 'thirdparty/sljit/' changes from c1cbaf09e..607158516
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
2024-02-11 19:16:29 +00:00
Giovanni Bajo 51a10b0bd0 n64: avoid HLE-ish memory init (#1388)
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.
2024-02-11 11:09:07 +00:00
png183 7e2f490fd0 gba: improve horizontal sprite mosaic (#1387)
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).
2024-02-11 11:08:41 +00:00
Luke Usher 2063393f20 sfc: fix SGB2 clocking issue
This fixes an issue where the SGB2 would reconfigure to SGB1 clock speeds when writing to the control port.
2024-02-06 00:15:49 +00:00
Giovanni Bajo 4c15ed753e n64: fix PI DMA implementation to handle a newly discovered behavior (#1385)
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).
2024-02-05 16:14:07 +00:00
Luke Usher 704fc91b9c desktop-ui: 'hide until ready' for Windows only 2024-02-01 18:58:50 +00:00
Luke Usher 757d74bac0 desktop-ui: hide window until startup completes
This also avoids calling inode::exists on every recent game at load time, reducing initial wait time.
2024-02-01 18:40:45 +00:00
Luke Usher ff36889d47 desktop-ui: exclude rumble inputs from poll timeout
Fixes rumble issues in many games, notably, OOT
2024-01-29 13:12:06 +00:00
Luke Usher 3d10cd34d6 ruby: differentiate devices in SDL2 driver 2024-01-28 21:00:36 +00:00
Luke Usher acaa1cabb5 ares: border and overscan overhaul
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.
2024-01-28 15:38:47 +00:00
png183 e8f38d15f7 gba: reset prefetch buffer on ROM accesses from CPU (#1377)
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.
2024-01-27 11:47:44 +00:00
Luke Usher 527aaefef1 ruby: use wglSwapInterval rather than DwmFlush
Despite GFWL, and other sources recommending the DwmFlush approach, actual users are setting better results the old way.
2024-01-25 16:11:57 +00:00
Dragorn421 a938ef8aa8 Fixup *nix SDL info and makefile indentation (#1376)
The readme references `libsdl2-0.0` which does not exist:
https://packages.ubuntu.com/search?suite=default&section=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.
2024-01-25 13:37:32 +00:00
Luke Usher 91658b989a ares: bump version to v135 2024-01-23 10:47:43 +00:00
Steveice10 801eaa4088 desktop-ui: Fix broken firmware path setting. (#1374)
* 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.
2024-01-22 14:20:27 +00:00
Steveice10 d6b2ca53e2 nall: Account for macOS app bundles in program path. (#1373)
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.
2024-01-22 14:20:14 +00:00
png183 d823641ccc gba: improve ROM to ROM DMA timings (#1372)
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.
2024-01-22 14:19:45 +00:00
Giovanni Bajo dec675896d n64: reenable isviewer even outside of homebrew mode (#1370)
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.
2024-01-22 14:18:53 +00:00
Giovanni Bajo e2caf175d6 nall: make gdb server accept only one connection at a time. (#1369)
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.
2024-01-22 14:18:42 +00:00
Giovanni Bajo 322c99ca75 nall: correctly handle TCP peer disconnections in tcp-socket.cpp (#1365)
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).
2024-01-18 09:27:23 +00:00
png183 b28bb3dbd7 gba: improve save type detection for homebrew (#1367)
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)).
2024-01-18 09:27:02 +00:00
Giovanni Bajo 3f4334e5ff n64: implement undocumented accesses in FPU half-mode (#1364)
Fixes most of the remaining failures in n64-systemtest
2024-01-16 11:59:04 +00:00
png183 99a40e43ef arm7tdmi: fix additional instructions that require offset when reading PC (#1363)
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.
2024-01-13 19:00:42 +00:00
png183 9bbe36d73c arm7tdmi: Improved ldmia and stmia timings in Thumb mode (#1362)
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.
2024-01-08 10:46:27 +00:00
Luke Usher 4bae7965f9 ps1: fix broken controller when sideloading ps-exe 2024-01-03 13:46:52 +00:00
jcmandjcm 9e4b3795f1 build: add macOS SDL to thirdparty, add .dylib to bundle (#1345)
### 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]>
2023-12-28 09:24:04 +00:00
shinra-electric a82913c1f9 macOS: Add minimum macOS version and copyright to ares.plist (#1350)
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.
2023-12-28 09:19:47 +00:00
Jasmine Minter b7db1c074b macOS: various UI fixes (#1355)
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 :)
2023-12-28 09:19:24 +00:00
Giovanni Bajo 1478637209 n64: support ROMs bigger than 63.9375 MiB (#1354)
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.
2023-12-28 09:17:52 +00:00
Giovanni Bajo 432c4e3b2a z80: add newly discovered behavior of inir/indr/otir/otdr (#1353)
See https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555
2023-12-21 15:30:24 +00:00
Giovanni Bajo 18c84a83e4 n64: improve PIF HLE emulation by reducing latency (#1351)
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.
2023-12-17 14:27:57 +00:00
remutro c4bc588082 Correct prefetch order for M68000 ASR instruction (#1347)
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.
2023-12-16 08:21:04 +00:00
Giovanni Bajo ed3083db8a Implement N64 register mirroring (#1344)
Also slightly improve PI latch emulation.
2023-12-14 11:13:55 +00:00
invertego 6d5ef628e8 ci: disable sdl2 on macOS to unbreak the build (#1343)
More work is required to support building universal binaries.
2023-12-12 23:38:21 +00:00
Luke Usher 6e8f4f224a cv: fix the build 2023-12-12 13:47:08 +00:00
png183 4bdeb3727f gba: unmapped i/o fixes (#1342)
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.
2023-12-12 12:30:51 +00:00
NoxyMeandLuke Usher 20a3aac83b cv: add "XIn1" and "MegaCart" mappers (#1327)
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]>
2023-12-11 17:44:19 +00:00
invertego 2950d3fe44 md: various i/o port improvements (#1341)
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)
2023-12-11 08:28:36 +00:00
jcmandjcm b55c5010f3 ruby: add SDL to macOS (#1313)
### 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]>
2023-12-09 22:03:16 +00:00
invertego f893afca89 nall: ensure utf-8 string encoding in cl builds (#1339)
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.
2023-12-09 21:46:17 +00:00
invertego 0d131bf4d8 build: improve pkg-config support on windows (#1337)
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
2023-12-08 11:55:43 +00:00
remutro 7e99155f8e Mega Mouse support for 32X + CD (#1336)
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.
2023-12-08 11:55:16 +00:00
Giovanni Bajo c95dc1bad7 n64: improve and extend cache coherency checks (#1314)
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.
2023-12-07 17:14:18 +00:00
invertego b85395fe7b hiro: make gtk2/gtk3/qt5 backends build (again) on windows (#1335) 2023-12-07 16:50:49 +00:00
encoded-byte 91c46dbad4 fc: improve fds timer irq generation (#1333)
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.
2023-12-07 16:23:15 +00:00
invertego 6a253b17af nall: define new type traits (#1334)
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.
2023-12-07 16:19:40 +00:00
invertego 4116855924 build: take care of some macOS build warnings (#1332)
- 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
2023-12-07 16:17:03 +00:00
invertego 1146c0def3 build: remove -fomit-frame-pointer (#1331)
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.
2023-12-06 10:33:34 +00:00
invertego e176d8b3ee build: always pass -arch on macOS (#1325)
Use the arch derived from -dumpmachine if none was specified to make.
Passing -arch seems to be required to get full debug information on
arm64.
2023-12-04 18:44:35 +00:00
Giovanni Bajo 9b5e339cc1 n64: improve SI emulation (#1326)
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.
2023-12-04 18:44:16 +00:00
invertego 8f626e304a ci: build resiliency tweaks (#1322)
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.
2023-12-04 12:02:26 +00:00
remutro bbe9a9b0a4 Make it more obvious that the apply button for drivers needs to be used (#1320)
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.
2023-12-04 12:02:05 +00:00
invertego c00e402eeb build: enable strict standards conformance with cl (msvc) (#1317)
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.
2023-12-04 12:01:50 +00:00
invertego 5e6afeaa5e hiro: prevent exception originating from appkit (#1324)
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.
2023-12-04 12:01:37 +00:00
Luke Usher a3222abe79 md: remove 32x dreq debug printing 2023-12-04 11:21:32 +00:00
Tomás Domínguez Bolaño b0ee66d4ad fc: use hkrom for mmc6 (#1316)
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".
2023-12-02 17:54:09 +00:00
invertego 6567d9dcf0 desktop-ui: destroy timers on system unload (#1315)
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.
2023-12-02 14:11:26 +00:00
invertego 9a8e7f8b6e recompiler: allow jitprotect() calls to be nested (#1306)
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.
2023-11-30 09:38:32 +00:00
Giovanni Bajo 1c9d38895d n64: simulate SysAD freezes when accessing non-RDRAM areas via cache (#1299)
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.
2023-11-29 21:43:52 +00:00
invertego cd11421d72 recompiler: enable instruction tracing w/recompilers (#1301)
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.
2023-11-29 21:43:30 +00:00
remutro 079295e2ca Enable/Disable N64 Expansion Pak (#1302)
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
2023-11-29 21:43:20 +00:00
Luke Usher 2a819403db ci: pass local=false and build=optimised to macos builds
Fixes an issue where release builds for macOS were optimised for the compiling machine rather than for distribution.
2023-11-29 16:23:36 +00:00
Luke Usher df031a7d4c desktop-ui: rename FPS to VPS (VBlanks Per Second) to better represent what it is really showing 2023-11-28 21:52:55 +00:00
Luke Usher 0dd3edebe0 desktop-ui: fix an issue where "Deep Black Boost" did not save 2023-11-28 21:25:43 +00:00
Luke Usher f9d38f5daf desktop-ui: rename "Reload" to "Apply" in driver settings to clarify it's function 2023-11-28 21:24:09 +00:00
Luke Usher d381bb4678 v134 2023-11-22 10:49:33 +00:00
LuigiBlood 3392783359 n64: optimize DD RTC checks (#1300) 2023-11-22 00:47:58 +00:00
Giovanni Bajo 67c6bfa4a5 mia: improve CIC detection algorithm (#1296)
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).
2023-11-21 10:34:53 +00:00
invertego 8cea0b8329 ps1: initialize _active member in peripherals (#1298)
Discovered using Clang's undefined behavior sanitizer which detects
non-0/1 values in bools.
2023-11-21 07:50:57 +00:00
invertego 4f7feeafd7 build: fix level 2 msvc warnings (#1297)
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).
2023-11-20 09:26:35 +00:00
Luke Usher bcb60a6e1b n64: fix an oops in rtc init 2023-11-19 22:22:48 +00:00
Luke Usher af0713858c n64: initialize rtc to unix epoch (timestamp 0) 2023-11-19 22:12:34 +00:00
Adrian Siekierka d3b11e4339 ws: Adjust ROM/SRAM bus timings. (#1212)
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.
2023-11-19 15:39:00 +00:00
invertego 7faebad713 build: fix level 1 msvc warnings (#1295)
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.
2023-11-19 14:59:02 +00:00
invertego 92c1c2ec44 ruby: queue no more than "latency" samples in wasapi driver (#1292)
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
2023-11-18 13:44:36 +00:00
Luke Usher bff2738163 ares: fix copy/past error in i8080 header 2023-11-17 22:18:37 +00:00
LuigiBlood 8a4bf9d82c n64: fix dd rtc skipping december + validity checks to avoid glitchy rtc (#1290)
- 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
2023-11-15 22:28:43 +00:00
LuigiBlood 4537145d24 n64: clamp x/y values for n64 mouse (#1289)
Avoid the mouse movement to be jittery especially when it's very fast.
2023-11-15 20:39:33 +00:00
invertego 4544e1df69 desktop-ui: disable color bleed for HD content (#1287)
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.
2023-11-15 11:04:43 +00:00
LuigiBlood 30cc370e40 n64: put dd rtc into a struct + serialize rtc + update serializer version (#1288)
I seperated the RTC into its own struct as it can be easily seperated,
and added serialization for it for save states.
Tested working.
2023-11-15 11:04:23 +00:00
Luke Usher 4a48753ea3 a26: riot timer improvements
Fixes "bang!" demoscene demo running too fast

Most effects in that demo are still broken, however.
2023-11-14 12:28:37 +00:00
Luke Usher 52df41a709 Squashed 'thirdparty/sljit/' changes from bc844c90a..c1cbaf09e
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
2023-11-14 12:17:40 +00:00
Luke Usher dc385dbe6e Merge commit '52df41a709917bc8d55a5fe8d9848d15ed3941e4' 2023-11-14 12:17:40 +00:00
Luke Usher df8d5a6157 mia: .rom => rom 2023-11-14 00:20:27 +00:00
Luke Usher de1c12737a mia: remove support for loading ".smd" extension
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.
2023-11-13 23:39:01 +00:00
Luke Usher da9c82956a mia allow loading .rom files for MSX/MSX2 2023-11-13 23:39:01 +00:00
hackgrid 4dd837ae41 mia: implement n64 controller config (Advanced Homebrew ROM Header) (#1286)
This PR implements the n64 controller config from the Advanced Homebrew
ROM Header:

https://n64brew.dev/wiki/ROM_Header#Advanced_Homebrew_ROM_Header

Only applies to Controller 1 at the moment, because ares only checks
globally for tpak/cpak/rpak:


https://github.com/ares-emulator/ares/blob/fa0f9a715fc9e14d48220ba2339ca1273b9d5d5b/desktop-ui/emulator/nintendo-64.cpp#L148
2023-11-13 23:34:04 +00:00
LuigiBlood fa0f9a715f n64: emulate disk change status bit behavior correctly + fix 64dd reset + fix DD debugger IO output (#1283) 2023-11-10 10:10:24 +00:00
LuigiBlood 87ae65a094 n64: add 64dd disk swapping + safety checks + change manufacture timestamp (#1280)
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
2023-11-08 20:09:27 +00:00
Luke Usher 0ceaf17be6 desktop-ui: emulator::construct must be called *before* settings are loaded
BIOS settings depend on being able to iterate through Emulators.
2023-11-08 10:46:39 +00:00
LuigiBlood e7760bfc51 n64: Add D64 file format support (#1279)
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.
2023-11-07 13:12:22 +00:00
Adrian SiekierkaandLuke Usher c27f369e31 fc: Initial EPSM implementation. (#1274)
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]>
2023-11-07 12:09:15 +00:00
Giovanni Bajo 020410ea0b Add homebrew mode (with a few checks to N64 core) (#1278)
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.
2023-11-07 10:53:12 +00:00
Luke Usher 6fbea44d3d ci: install setuptools in macos environment
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.
2023-11-07 10:22:54 +00:00
Luke Usher d2e20f0d05 mia: use SMS mode when loading .sms roms on gamegear 2023-11-07 09:27:44 +00:00
Adrian Siekierka e589f8d9cf wdc65816: fix PLB wrapping in emulation mode (#1277)
>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
2023-10-29 19:16:41 +00:00
remutro d201d6a547 N64 Mia Update - Chameleon Twist 2 (#1272)
Update Mia DB to include US/EU Ids for Chameleon Twist 2. The Japanese
Id starts with NV2 while the other regions have an Id that starts with
N2V.
2023-10-26 13:48:30 +01:00
Luke Usher 7dc11a1c39 ms: check for TMR-SEGA header
Games that lack this header are incompatible with non-japanese systems
2023-10-25 22:15:04 +01:00
Luke Usher 89e0001275 ares: preliminary Intel 8080 cpu implementation + test harness
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
2023-10-25 17:56:09 +01:00
Luke Usher 5b744c324d nall/hiro: shlwapi is a dependancy of nall, not hiro 2023-10-25 11:21:05 +01:00
Luke Usher a47bbea7a2 desktop-ui: surround sg1000a with CORE_SG ifdef 2023-10-25 09:42:13 +01:00
Luke Usher 414c205256 desktop-ui: surround sg1000a with CORE_SG ifdef 2023-10-25 09:40:16 +01:00
Luke Usher f1fb33af8e ms: add color emulation for non-linear blue 2023-10-24 17:52:23 +01:00
Luke Usher 84e3663e80 pce: add color emulation (non-linear rgb)
Palette is derived from the one used in the Mister project
2023-10-24 16:39:26 +01:00
TascoDLX 77bfad91d8 md: refresh & bus timing fixes (#1269)
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).
2023-10-24 09:14:44 +01:00
Luke Usher cd8d84ed5b all: create a system for generic arcade boards 2023-10-23 23:08:21 +01:00
Luke Usher 44b0c2c532 Revert "md: increase synchronizaton between audio related components"
This reverts commit 939617aad9.
2023-10-23 11:33:49 +01:00
Luke Usher 02dcc63431 md: remove extra bus arbitration delays
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.
2023-10-23 11:22:20 +01:00
Luke Usher 864bc6e6d6 md: increase bus arbiter delays for z80->m68k communication 2023-10-23 10:37:09 +01:00
invertego a572a97d10 build: restore rule for ym2612 (#1267) 2023-10-22 08:30:16 +01:00
Luke Usher 939617aad9 md: increase synchronizaton between audio related components 2023-10-21 23:38:13 +01:00
Luke Usher ca6ada73ab ng: use ymfm for ym2610 rather than (badly) hacking together ym2612 with the YM2149 2023-10-21 19:56:05 +01:00
Luke Usher d8e462035d Merge commit 'e457e05c8b14079c1d87d96a47cea6c56dea7796' as 'thirdparty/ymfm' 2023-10-21 19:52:18 +01:00
Luke Usher e457e05c8b Squashed 'thirdparty/ymfm/' content from commit d641a8063
git-subtree-dir: thirdparty/ymfm
git-subtree-split: d641a80631fe1fa5a3689fa5b6def07685772424
2023-10-21 19:52:18 +01:00
Luke Usher da3adb4daa ym2612: update key state on phase tick 2023-10-21 10:37:37 +01:00
Luke Usher 3ebfb4433e Revert "ym2612: immediately update key state on keyOn/keyOff"
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.
2023-10-21 10:26:09 +01:00
Luke Usher 0bea9d3a2e md: add 32x framebuffer mirror (fix SoulStar X) 2023-10-20 14:48:06 +01:00
Luke Usher 785edf60c8 ym2612: immediately update key state on keyOn/keyOff
Fixes Puyo Puyo Tsuu theme
2023-10-20 12:18:13 +01:00
Luke Usher 62f5c36c17 desktop-ui: rename SG-1000 (Arcade) to "SG-1000 Arcade System"
Fixes an issue where settings get destroyed due to () characters.
2023-10-19 11:28:43 +01:00
Luke Usher ed35f2249b desktop-ui: arcade systems have their own category 2023-10-19 10:50:00 +01:00
Luke Usher 3fa22458f4 sg: fix serialization 2023-10-19 00:39:27 +01:00
Luke Usher 708247ab38 sg: preliminary support for sg1000 based arcade games
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
2023-10-19 00:32:33 +01:00
Luke Usher 88a14fb5f2 msx: fix conflicts between rom and scc with KonamiSCC mapper 2023-10-18 20:00:23 +01:00
Luke Usher 5f55b6cf27 md: fix hang in "The Terminator (USA)" 2023-10-18 19:34:44 +01:00
Luke Usher 74e10c45f3 mia: improve system autodetect of cd-rom based games 2023-10-18 19:04:48 +01:00
Luke Usher 5984867fce md: pass "CDC REGS" test in mcd-verificator 2023-10-18 18:43:59 +01:00
Luke Usher dd01cf762b mia: identify FDS bios by copyright string rather than digest
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
2023-10-18 17:30:15 +01:00
Luke Usher bfa1eeafde md: fix "After Burner Complete (32x)" 2023-10-18 12:58:47 +01:00
Luke Usher 0661e9858c md: 32x performance tuning 2023-10-18 12:51:10 +01:00
Luke Usher 7b433f305f md: fix sh2 thread restart behavior 2023-10-18 10:39:44 +01:00
invertego 1c61fc95e6 md: implement opn2 restart w/out resetting the thread clock (#1260)
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.
2023-10-18 10:18:33 +01:00
Luke Usher 401df969b0 fc: serialize controller state 2023-10-17 10:45:17 +01:00
Luke Usher 5deec7ede5 Revert "fc: allow "ppu direct color" to function, fixes full palette test roms"
This reverts commit 6a7de62674.
2023-10-10 13:38:00 +01:00
Luke Usher 6a7de62674 fc: allow "ppu direct color" to function, fixes full palette test roms 2023-10-10 09:39:36 +01:00
Luke Usher b7be6612b9 ares: prevent rebuilding the entire project if only version constants change 2023-10-07 18:12:36 +01:00
Luke Usher f976cdc3a8 md: set color bleed width per frame 2023-10-02 08:58:24 +01:00
invertego e369049d0a nall, libco: add support for risc-v arch (#1249)
Tested with qemu-system-riscv64 and Ubuntu as the guest OS.
2023-10-02 08:45:43 +01:00
jcmandjcm 72d8179bf0 Add "Games" app category to bundle .plist on macOS to facilitate Sonoma's Game Mode (#1248)
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.


![image](https://github.com/ares-emulator/ares/assets/6864788/5c5727f9-88da-423e-af19-9fd08ed8eb91)

Co-authored-by: jcm <[email protected]>
2023-09-29 22:14:07 +01:00
invertego 8ed4af8b57 recompiler: avoid overallocation in code buffer (#1247)
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.
2023-09-29 14:14:32 +01:00
Luke Usher bcddb7a68f fc: implement ppu open bus
Passes blargg's test_ppu_read_buffer and ppu_open_bus
2023-09-28 14:00:02 +01:00
Luke Usher 5c9f5419b0 gdb: disable some debug prints 2023-09-28 11:59:03 +01:00
invertego 4b3b78b77e recompiler: more robust code cache allocation (#1242)
- 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
2023-09-28 10:12:39 +01:00
invertego 07c320e55a 32x: maintain code cache allocation across resets (#1243)
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.
2023-09-28 10:12:17 +01:00
PikaSamus 506820bac7 Modified weave deinterlacing description (#1240)
Corrected horizontal to vertical, and changed comma to semicolon.
2023-09-27 10:18:00 +01:00
invertego 46ddcac339 recompiler: revert "avoid overallocation in code buffer" (#1241)
Turns out the overallocation was masking some bugs in sljit. Will take
this upstream and revert the ares change in the meantime.
2023-09-27 10:08:47 +01:00
invertego 1349d45a51 recompiler: avoid overallocation in code buffer (#1239)
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.
2023-09-26 22:22:55 +01:00
Luke Usher ff11f77f92 desktop-ui: revert "enable color bleed by default" 2023-09-26 16:28:11 +01:00
Luke Usher f9c110cd49 desktop-ui: enable color bleed by default 2023-09-26 11:27:57 +01:00
Luke Usher 379091bada md: fix color bleed 2023-09-26 11:25:50 +01:00
Luke Usher ba475a7a59 desktop-ui: expose "color bleed" option to all cores 2023-09-26 10:28:14 +01:00
Luke Usher 06e1ac13ef sfc: separate black level crush from color emulation 2023-09-26 10:18:57 +01:00
Luke Usher 675026ffdd fc: remove gamma adjustment in color emulation 2023-09-26 10:18:39 +01:00
Luke Usher f0449e36ff md: sync every cycle when 32x is not in use
We should strive to fully remove this hack, but we're not there yet for 32X.
2023-09-25 11:00:17 +01:00
Adrian Siekierka 0f265028f2 fc: add self-flashing support to UNROM-512, GTROM (#1237)
Tested with https://github.com/SourMesen/Mesen/issues/753
2023-09-24 14:45:22 +01:00
Adrian Siekierka 0b2544a6cf gdb/server: implmment NoAckMode (#1230)
I have verified that it works with LLDB; please don't merge until
@HailToDodongo verifies it with GDB.
2023-09-19 10:02:26 +01:00
Adrian Siekierka 99afcff4c7 fc: Fully utilize NES 2.0 extended PRG/CHR size variables. (#1229)
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.
2023-09-19 10:02:12 +01:00
Luke Usher a652e85069 Squashed 'thirdparty/libchdr/' changes from 54bfb871c..9108f34a8
9108f34a8 Merge pull request #104 from invertego/huff_dec_err
1fb0c62a5 Fix huff_codec_decompress returned error code

git-subtree-dir: thirdparty/libchdr
git-subtree-split: 9108f34a892272f61c3ed3bff4bee728d4c1dd57
2023-09-18 21:30:46 +01:00
Luke Usher 51061e16af Merge commit 'a652e85069d83d8430730fb66fb96a7f31f72389' 2023-09-18 21:30:46 +01:00
Luke Usher 4e66bc0b32 Squashed 'thirdparty/sljit/' changes from aa71425db..bc844c90a
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
2023-09-18 21:30:41 +01:00
Luke Usher 0c6784294c Merge commit '4e66bc0b32f63b6e3ada74f2d85e3dbdc0b3490e' 2023-09-18 21:30:41 +01:00
Luke Usher 2a6454a710 Merge commit '4f5b5da64f07bd730f37ae842d3404a3189ac13f' 2023-09-18 21:30:31 +01:00
Luke Usher 4f5b5da64f Squashed 'ares/n64/vulkan/parallel-rdp/' changes from c38ea4c21..37bf2967e
37bf2967e Remove dead wsi_timing code.
a8ee1ddac Update to afc61e1050a79b9ab7bb53b8880b055324f7b4a2.

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 37bf2967e3dd18e059cf5563717bb6c88c261f33
2023-09-18 21:30:31 +01:00
invertego 562bcd7b20 build: miscellaneous fixes (#1233)
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.
2023-09-18 10:13:20 +01:00
Adrian Siekierka db5f7d7867 fc: Fix MMC5 program mode 1. (#1228) 2023-09-17 16:19:57 +01:00
Adrian Siekierka 3e9ee7423d fc: Implement mapper 31, 218. (#1227)
Resolves https://github.com/ares-emulator/ares/issues/751
2023-09-17 16:19:37 +01:00
Stuff is on GitLab 1215b37448 GDB Server (#1223)
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.
2023-09-17 16:19:13 +01:00
Adrian Siekierka 85488a7404 fc: Implement Action53 mapper. 2023-09-16 15:38:35 +01:00
Adrian Siekierka 5eccee8457 fc: Implement UNROM-512 mapper. 2023-09-16 10:49:43 +01:00
Adrian Siekierka 671669b209 v30mz: Fix interrupt return address on division by zero. 2023-09-16 10:38:50 +01:00
Luke Usher fe9a80b9eb readme: update windows build instructions to add sdl2 2023-09-16 08:43:00 +01:00
Adrian Siekierka 4216a0c2c4 v30mz: fix ENTER/PREPARE opcode implementation, timing 2023-09-14 20:40:42 +01:00
Adrian Siekierka 8ba3bd6348 ws: Properly load trimmed cartridge ROMs - starting from the end of the address space. 2023-09-14 20:40:30 +01:00
Luke Usher 546aed6852 sfc: report PAL and NTSC support for SGB1, allowing it to run at 50hz if "Europe" is the users preferred region. 2023-09-02 22:34:09 +01:00
Adrian Siekierka b11ff923b9 ws: fix sound DMA source/length shadowing 2023-09-02 14:28:48 +01:00
Adrian Siekierka 4509471ce2 ws: fix sound DMA readout values when disabled 2023-09-02 10:49:39 +01:00
NoxyMe 72cd3c5a65 Update master-system.cpp 2023-09-01 16:18:37 +01:00
NoxyMe 929ad45380 Cleaned up some stuff 2023-09-01 16:18:37 +01:00
NoxyMe bb67742864 Added K188in1 Mapper and fixed missleading names
Added K188in1 Mapper
Changed "msx.cpp" to "zemina" as lots of MSX ports dont use the mapper and its only used by ports by Zemina.
2023-09-01 16:18:37 +01:00
NoxyMe b439a0d90a Cleaning up code based on LukeUsher's nits. 2023-09-01 16:18:37 +01:00
NoxyMe a96395a1c1 Added 2 Hap in 1 - David-2 ~ Moai-ui bomul 2023-09-01 16:18:37 +01:00
NoxyMe 70675c0644 Removed some leftovers 2023-09-01 16:18:37 +01:00
NoxyMe 950d9a1967 Added Pak4 (4 PAK All Action) and Hicom Mappers to the SMS core. 2023-09-01 16:18:37 +01:00
Adrian Siekierka 2682e929d8 ws: implement sound DMA hold 2023-09-01 16:16:08 +01:00
PikaSamus cd924569d2 Update README.md: Fixed typo
Fixed typo (descendent → descendant)
2023-08-30 20:29:54 +01:00
Adrian Siekierka 0d27a86e01 ws: fix INT_BASE bit order 2023-08-30 17:50:55 +01:00
Adrian Siekierka 38628f9c85 ws: properly implement INT_BASE port 2023-08-30 17:50:55 +01:00
PikaSamus 405ac8289c fc: Lowered saturation
Lowered saturation value from 2.0 to 1.5 to match other implementations of NTSC (Nintendulator, puNES, Nestopia, etc.)
2023-08-29 09:24:57 +01:00
invertego b29fb91777 nall: move cdrom loading to separate thread
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.
2023-08-28 10:12:01 +01:00
invertego 9280622d29 nall: fix relative time in pregap subchannel q 2023-08-28 07:53:15 +01:00
Luke Usher 714ecc1322 ruby: use DwmFlush on Windows rather than OpenGL Swap Interval
DwmFlush is implemented by windows at DWM Driver level, and bypasses OpenGL driver bugs, this should lead to a more stable vsync.
2023-08-24 15:51:55 +01:00
Luke Usher 04525a7426 readme: fix missing a26 core 2023-08-23 20:50:22 +01:00
Luke Usher cc3f4543b1 readme: update core list 2023-08-23 20:30:22 +01:00
Luke Usher 2f65f315e1 desktop-ui: fix build on older compiler versions 2023-08-23 16:38:01 +01:00
Luke Usher de57072f83 ci: switch to wpilibsuite mirror of import-signing-certificate
We still make sure to use the same commit id, so that we don't get any unexpected changes in this transition.
2023-08-23 14:57:06 +01:00
invertego 9225847d40 build: prefer clang only on win/macos/bsd
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.
2023-08-23 10:03:02 +01:00
Luke Usher 6669e3e84b mos6502: make it more obvious that SLO is combined ASL and ORA 2023-08-22 23:07:18 +01:00
Luke Usher 703e2ea49a desktop-ui: add firmware "scan" function
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.
2023-08-22 20:59:08 +01:00
Luke Usher 40a6b8d36a mia: allow atari 2600 to load .bin format roms 2023-08-22 20:59:08 +01:00
Luke Usher d5381e47a2 mos6502: implement more undocumented opcodes 2023-08-22 10:56:58 +01:00
Luke Usher 7ea42e3201 Update issue templates 2023-08-22 10:08:28 +01:00
Luke Usher c7c80d07ee desktop-ui: restore ability to hide emulation cores from the menu 2023-08-22 09:56:58 +01:00
Luke Usher 5faa14b504 a26: check for PAL string in addition to Europe 2023-08-21 15:41:05 +01:00
Luke Usher 1647d3f4ef a26: fix RIOT timer 2023-08-21 14:40:34 +01:00
Luke Usher 62eadd89e0 a26: fix hmove when position < offset 2023-08-20 21:01:09 +01:00
Luke Usher 9fae1a48c2 a26: fix nusiz missile separation 2023-08-20 20:59:01 +01:00
Luke Usher 166856f4dd a26: better relative object positioning 2023-08-20 20:59:01 +01:00
Luke Usher 48e4ee55c0 a26: fix resmp + implement nusiz for missiles 2023-08-20 20:59:01 +01:00
remutro e8b85524d9 Add mouse support in GUI for Mega CD 2023-08-19 21:40:13 +01:00
Luke Usher 3854a1d1e8 a26 more timing/debugging tweaks
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
2023-08-18 12:07:17 +01:00
Luke Usher 090f8765c2 tracer: fix a crash when logging cpu instructions 2023-08-18 10:07:15 +01:00
Luke Usher 8ae96164ef a26: more timing improvements 2023-08-17 20:42:08 +01:00
Luke Usher 5a647e77ad a26: improve cpu timing with regards to wsync 2023-08-17 19:58:24 +01:00
Luke Usher 6c7bdf9c1a ps1: fix timer precision with recompiler 2023-08-17 13:42:01 +01:00
Luke Usher 21a730b037 n64: add is-viewer log channel rather than forced fputc 2023-08-17 13:18:32 +01:00
Luke Usher 5d38bd3744 ares: allow separate toggling of file/stdout per log channel 2023-08-17 12:57:27 +01:00
Luke Usher 3d3838d8b4 ares: refactor trace/notification logging 2023-08-17 01:43:01 +01:00
Luke Usher d1ddbd504a wip: allowing for separate log channels 2023-08-17 00:23:48 +01:00
Luke Usher c88f26230e ps1: various timing tweaks; passes more tests! 2023-08-16 20:06:13 +01:00
Luke Usher ecab4fdca0 ps1: simulate infinite cpu write fifo
This was causing a lot of software to run too slow; can be restored once we properly emulate that fifo.
2023-08-16 17:15:49 +01:00
Luke Usher 3581be3c44 ps1: prevent fastload exe hook from running more than once
Previously, if *any* title jumped to address 0x80030000, it would crash or reboot or worse.
2023-08-16 11:46:28 +01:00
Luke Usher 2950cef605 ps1: perform color modulation in rgb555 space
fixes Silent Hill loading screen
2023-08-16 10:06:03 +01:00
Luke Usher aab3b447e7 ps1: implement rumble/force feedback for DualShock pads 2023-08-15 22:06:38 +01:00
Luke Usher ea665be25a ruby: fix an issue where weak/strong rumble motors were swapped 2023-08-15 22:06:22 +01:00
Luke Usher e8f4554f24 ps1: use q-sub channel to prevent playing data as cd-da 2023-08-15 19:30:19 +01:00
Luke Usher 0ba0e5f85e ps1: update adsr envelopes immediately on write
fixes broken alert sound in Metal Gear Solid
2023-08-15 18:33:41 +01:00
Luke Usher 7dea8162db ps1: support half sample rate xa-adpcm 2023-08-15 14:33:58 +01:00
Luke Usher d4fd326630 md: sega cd disc swapping 2023-08-15 13:57:00 +01:00
Luke Usher cb19cdbf90 ps1: disc swapping support 2023-08-15 13:35:57 +01:00
Luke Usher ec12ccc6ff ps1: fix l3 and r3 on dualshock controllers 2023-08-14 23:08:08 +01:00
Luke Usher 59deec8b45 ps1: partial dual-shock implementaton
Still missing a few commands + no force feedback
but it is enough to play Ape Escape!
2023-08-14 22:56:15 +01:00
Luke Usher ef53e87b31 ps1: log and recover from premature device transmit
Fixes input in most (all?) titles that don't currently work
Requires more research
2023-08-14 21:17:21 +01:00
Luke Usher 631085f1e6 ps1: separate /ack and transfer delays into two counters 2023-08-14 21:16:43 +01:00
Luke Usher 543dec41b8 ps1: improve controller /ack behavior
fixes controller input in Crash 3 and probably more titles
2023-08-14 19:56:55 +01:00
Luke Usher 72ab5278b2 ps1: digital pad should deassert /ack on invalid command 2023-08-14 14:29:53 +01:00
Luke Usher 93937e8603 ruby: preliminary SDL2 audio driver 2023-08-13 18:55:06 +01:00
invertego 8476c880bc ruby: use pkg-config to link SDL2
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).
2023-08-11 18:24:27 +01:00
Luke Usher e39efe170b n64: fix tlb tests 2023-08-11 18:24:13 +01:00
Luke Usher 133044afa9 fix build, oops 2023-08-10 21:06:04 +01:00
Luke Usher c78f06e208 n64: fallback to other paks when gb game is not inserted 2023-08-10 20:26:29 +01:00
Luke Usher f5dc3bbd48 n64: enable transfer pack for all known supported games 2023-08-10 20:26:16 +01:00
Luke Usher ea688c7721 n64: preliminary support for the transfer pak; only enabled for Pokemon Stadium for now 2023-08-10 20:08:28 +01:00
Luke Usher 35c8f5f760 ares: update rumble api to support non-binary vibration 2023-08-09 22:18:19 +01:00
Luke Usher 97aa37f040 ruby: another udev oversight 2023-08-09 22:06:40 +01:00
Luke Usher 8752695b4d ruby: fix oversight in udev driver 2023-08-09 21:54:24 +01:00
Luke Usher cea1adcb44 ruby: fix typo in udev driver 2023-08-09 21:47:53 +01:00
Luke Usher 91b6c7ac14 ruby: update rumble api to support setting weak/strong motors independently 2023-08-09 21:45:20 +01:00
Luke Usher 862bfec9e9 ruby: add rumble support to sdl driver 2023-08-09 21:34:51 +01:00
Luke Usher dad3db5498 ruby: fix keyboard on Windows when using SDL driver 2023-08-09 21:17:05 +01:00
invertego f396a9cf60 recompiler: allocate code cache early in main
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.
2023-08-09 20:10:02 +01:00
Luke Usher beaab1791a build: include pkg-config for package detection on CI 2023-08-09 20:06:44 +01:00
Luke Usher cc6b26c8d7 build: attempt to fix aarch64 windows builds 2023-08-09 20:03:04 +01:00
Luke Usher a5319fdc07 build: attempt to fix aarch64 windows builds 2023-08-09 20:01:35 +01:00
Luke Usher c2c3c0f0f8 ruby: enable SDL2 input driver on all platforms
NOTE: This currently only works for mingw/msys environments on Windows;
building in a Windows CLI/visual studio will currently not use SDL2.
2023-08-09 19:54:37 +01:00
remutro 3c773a90eb Add audio hotkeys 2023-08-08 22:35:52 +01:00
invertego 8574a5879b n64: advance virtual address in recompiler 2023-08-08 08:04:18 +01:00
invertego 3fd03e7a32 n64: improve idle loop detection
We should compare the virtual address, not physical, to the jump target.
This fixes idle loop detection in games like Turok 2 & 3.
2023-08-08 07:15:31 +01:00
invertego 0130187f82 n64: detect idle loops using jump instruction
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.
2023-08-07 12:29:13 +01:00
invertego fde1f55f42 n64: begin implementing fpu delays
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.
2023-08-07 12:29:13 +01:00
invertego 5337a4bfb8 n64: step one less cycle per mul/div instruction
ares already steps one cycle by default per instruction.
2023-08-07 12:29:13 +01:00
invertego 6bf0d1ffcd n64: step just one cycle per instruction in icache 2023-08-07 12:29:13 +01:00
invertego aff3513931 n64: raise vi line interrupt post-increment
The interrupt should be raised while the current line still equals the
comparison value.
2023-08-06 10:07:48 +01:00
Mastergatto 9fb87dc0c9 Add support for system-wide installation of Ares on Linux, this fixes databases and shaders not loading 2023-08-05 20:46:03 +01:00
invertego a10b9ce0e9 n64: implement rdp clock counter 2023-08-05 13:47:07 +01:00
invertego ffcce5823c n64: track cpu clocks at system rate 2023-08-05 13:47:07 +01:00
invertego 78f439dad1 n64: refactor thread step 2023-08-05 13:47:07 +01:00
Luke Usher 251ea7c0de fix build 2023-08-04 10:23:44 +01:00
hackgrid 12b4530f39 desktop-ui: save settings when closing the settings dialogue 2023-08-04 10:00:38 +01:00
kev4cards c4a5fcea9a n64: clamp to octagon edge instead of scale 2023-08-01 09:54:25 +01:00
Giovanni Bajo ef3d784ae4 n64: update after Granite API change 2023-07-31 16:57:52 +01:00
Luke Usher 14552167a2 Squashed 'thirdparty/sljit/' changes from 51538f102..aa71425db
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
2023-07-31 16:56:54 +01:00
Luke Usher 8593f3e980 Merge commit '14552167a2a2b7f73cb7037cd18e81cbd97281db' 2023-07-31 16:56:54 +01:00
Luke Usher a617f2160d Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 8da2be35a..c38ea4c21
c38ea4c21 Add missing file.
f0314a231 Update to 860050d2bf187f1dc215a59df3b2c4f01cada33e.

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: c38ea4c2188719798b81337cd74d4cdb19b819da
2023-07-31 16:56:48 +01:00
Luke Usher a18ad47482 Merge commit 'a617f2160da0e9806a95fe2ebc59edb108dc62d6' 2023-07-31 16:56:48 +01:00
Luke Usher e6c0c15114 n64: prevent segfault when parallel-rdp is unsupported by the host gpu 2023-07-31 16:49:22 +01:00
invertego 2cfb4a98ec n64: implement dual issue conflicts from "fake" uses 2023-07-25 08:43:37 +01:00
invertego 8a89b5a53a n64: fix rsp zero register locking 2023-07-25 08:43:37 +01:00
Luke Usher 352f2202e2 ps1: cd-rom setLoc command should not reset reading flag 2023-07-24 20:30:30 +01:00
Luke Usher 7233efbc39 ps1: implement GTE interrupt quirk 2023-07-24 20:09:11 +01:00
invertego dbd779376a n64: implement rsp dual issue restrictions for cfc2/ctc2 2023-07-24 12:10:49 +01:00
Adrian Siekierka ecba464a58 Revert "ws: fix off-by-one in line IRQ handling"
This reverts commit fb711deb0d.
2023-07-23 20:15:30 +01:00
Adrian Siekierka fb711deb0d ws: fix off-by-one in line IRQ handling 2023-07-23 19:41:26 +01:00
invertego d901f4e336 mia: fix a few n64 serials
- 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.
2023-07-23 17:51:59 +01:00
invertego 631b0f6452 n64: implement rsp vu pipeline timings
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.
2023-07-23 17:51:24 +01:00
jcm 3de3f99ad1 Update MoltenVK dependency to version 1.2.4 2023-07-23 10:20:25 +01:00
Adrian Siekierka d201c4827a gb: fix MBC3 RAM bank register width 2023-07-21 22:42:37 +01:00
Adrian Siekierka 2ccd7ba670 gb: fix MBC3 RTC overflow/register handling 2023-07-21 22:42:37 +01:00
Luke Usher 8e62cd8162 ares: bump version number to v133 2023-07-21 09:13:51 +01:00
Giovanni Bajo 8b45d04288 n64: correct implementation of out of bounds RDRAM reads and writes 2023-07-21 09:02:43 +01:00
NoxyMe c94c7a9b85 Added My vision Core 2023-07-20 19:22:50 +01:00
Luke Usher ee6a7fe78d desktop-ui: fix an issue where the game browser would crash the emulator if medium::create failed 2023-07-19 13:36:04 +01:00
Luke Usher d3a71803ed mame2bml: mame machine list uses hex without a prefix for offset 2023-07-19 13:36:04 +01:00
Luke Usher 1e5eed8f21 mia: fix indentation of loadRoms 2023-07-19 13:36:04 +01:00
Luke Usher 697b3b6503 mame2bml: add support for extracting databases from machine lists (mame --listxml) 2023-07-19 13:36:04 +01:00
Giovanni Bajo 7812cc1818 n64: implement accurate PI DMA timings
The previous formula was a decent approximation, but it looks like 6105
antipiracy protection requires a better one (in addition to better RSP
timings that already went in).

Fixes #129 (Jet Force Gemini and Mickey Speedway USA)
2023-07-19 13:31:48 +01:00
Luke Usher 499c964986 mia: split arcade rom loading from neo-geo.cpp into generic mame.cpp 2023-07-19 10:10:40 +01:00
Giovanni Bajo 49fac42e69 n64: remove debug printf 2023-07-18 17:54:28 +01:00
invertego 2b746cd26c n64: implement rsp su pipeline stalls
Implement pipeline stall conditions for the RSP's scalar unit (SU).
Tested against real hardware with a random instruction stream generator.

Vector unit (VU) timing, including dual issue with the SU, is not yet
implemented.
2023-07-18 16:47:13 +01:00
Luke Usher dafb57010c cli: support loading multiple roms at once and surpressing file dialogs 2023-07-17 20:26:06 +01:00
remutro cab7096e0f Update weave label text, address additional ways weave & supersampling could be manipulated 2023-07-17 09:46:26 +01:00
remutro a3d6392e1c actually disable supersampling setting, not just the control 2023-07-17 09:46:26 +01:00
remutro b4221bcaaf weave default true, disable supersampling when weave enabled 2023-07-17 09:46:26 +01:00
SpookyIluha feab2746da Add weave deinterlacing support to N64
When an interlaced output is made by the game, an N64 emulator right now only allows "Bob" deinterlacing, this commit also adds a "Weave" deinterlace option
2023-07-14 13:39:04 +01:00
Luke Usher eccd72d17f msx2: add some entries to game database 2023-07-14 10:55:18 +01:00
Luke Usher d3228ea52d msx2: minor background tweaks 2023-07-14 10:55:18 +01:00
remutro bff8a1413f Use nall print instead of printf, adjust message 2023-07-14 09:50:38 +01:00
remutro d6f216928c Don't silently fail loading a rom if it is too small 2023-07-14 09:50:38 +01:00
Luke Usher 92099bec6f msx: stub just enough of the RTC for MSX2 bios to boot, remove c-bios.
Implementation of RTC will be fleshed out further in the future.
2023-07-13 22:19:02 +01:00
Luke Usher 1b148ab9cb msx2: fix serialization of v9938 2023-07-13 22:15:42 +01:00
Luke Usher d3e7ced3b4 msx2: vscroll + text1 + graphics5 2023-07-13 22:14:52 +01:00
Luke Usher 9cf118a72f msx2: fix mode2 sprite rendering 2023-07-13 20:48:20 +01:00
Luke Usher cc81fd1015 hiro: use modern file browser dialog on Windows
This is supported on Vista+, meaning that Hiro no longer supports Windows XP
2023-06-29 13:14:16 +01:00
remutro da45ad792b Update GTK info and app terminal options 2023-06-29 12:00:33 +01:00
Luke Usher 8feff4afa3 build: default to gtk3 on linux
gtk2 is aging now and not available out of the box on many current distros
2023-06-29 11:30:25 +01:00
Alexandre Detiste 104e4bd66d make cross-building somewhat easier
part of this:
  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=866070
2023-06-28 16:54:05 +01:00
Seth Junot 5f891de18a Fix: replace deprecated CGDisplayIOServicePort on macOS
This patch resolves a deprecation warning raised at compile time on macOS.
Note the replacement functions have been available since macOS 10.4.
2023-06-28 16:51:33 +01:00
invertego 83b43e8405 libchdr: redo fseeko/ftello fix 2023-06-27 10:31:12 +01:00
Luke Usher 682fc36ac7 spec: minor tweaks to TZXFile loading - fixed Jet Pac 2023-06-25 13:47:18 +01:00
noabody d7fd2ccba8 correct for case sensitive file system 2023-06-24 17:54:54 +01:00
Luke Usher 66e01e02cc spec: add support for .tap and .tzx format tapes
This uses code extracted from https://github.com/MrReeMachine/TzxTool
2023-06-23 18:27:01 +01:00
Luke Usher 76cf49834a msx: preliminary support for loading cassette tapes
like all of these computers, loading cassette tape games is awkward,
requiring the user to know what format data the tape contains.

The following basic commands are used to load cassette tapes:

Binary Data: `BLOAD"CAS:",R`
Tokenized Basic: `CLOAD`
ASCII `RUN"CAS:"`
2023-06-23 13:53:19 +01:00
Luke Usher f8f1729cbe n64: fix tlb after cache implementation 2023-06-23 12:28:34 +01:00
Luke Usher 181570e50d n64: add cache to speed up the lookup of the 4 most active pages 2023-06-23 12:28:34 +01:00
Luke Usher 878419da0e n64: avoid unnecessary pbase writes in devirtualizeFast and hint as alwaysinline 2023-06-23 12:28:33 +01:00
Luke Usher fbaf7d8118 n64: use devirtualizeFast for faster lookups of cached code blocks 2023-06-23 12:28:33 +01:00
Luke Usher 345a7cb89f n64: clear devirtualize cache on TLB changes rather than memory writes 2023-06-23 12:28:33 +01:00
Giovanni Bajo 2650062d70 n64: implement correct audio frequency for PAL consoles
Fixes #1120
2023-06-23 12:26:08 +01:00
Jeff Linahan 2b0c91e3c3 sfc: bank -> page 2023-06-23 12:16:56 +01:00
Jeff Linahan 15bb0e0593 sfc: noise linear feedback shift register state constructed with or not xor 2023-06-23 12:16:56 +01:00
Alexandre Detiste 2e472e8401 fix FTFBS with GCC-13
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1037580
2023-06-21 14:35:09 +01:00
Luke Usher 53af7cbbcc n64: mask pbase to fix incorrect offsets 2023-06-20 21:52:23 +01:00
Luke Usher bafa58534a ci: package ares-windows build 2023-06-20 09:05:17 +01:00
Luke Usher 495803ea63 n64: remove erroneous devirtualize cache writes in non-fast variant
This was causing data accesses to overwrite the cached recompiler block mapping
2023-06-19 22:07:29 +01:00
Luke Usher 7f09b67df9 n64: speed up recompiler icache lookup
This introduces a faster version of tlb.Load which omits exception and debug checks in
instructionEpilogue; as it is assumed these checks are handled sufficiently by the recompiler
instruction fetch phase before execution.

Additionally, this also introduces a simple cache that caches the virtual to physical mapping
for a single 4k page; this prevents per-instruction lookups within recompiled block; and is
cleared when the TLB is written to, so should never become stale.
2023-06-19 21:56:40 +01:00
Luke Usher 8ddd630850 build: default to ares-windows builds
These have tested as higher performance than other builds as of late
2023-06-19 21:53:30 +01:00
Luke Usher 5f9804fb65 n64: remove MAME RDP
It is too slow to be usable with the rest of ares,

Now that macOS can run Parallel-RDP with MoltenVK, there is little reason
to keep this around.

We can just say that Vulkan is *required* for the N64 core going forward.
2023-06-15 20:23:14 +01:00
Luke Usher e142c3be5a n64: slight performance boost by moving exit logic to components rather than system
This reduces the total number of function calls made in each loop of system->run()

n64: add fast variant of devirtualize; fix remaining task from PR #1069
2023-06-15 19:52:22 +01:00
Luke Usher 6e367916da n64: add fast variant of devirtualize; fix remaining task from PR #1069 2023-06-15 19:52:12 +01:00
Adrian Siekierka c4863ef672 v30mz: improve timing accuracy
Still not perfect, but a little closer here and there.
2023-06-11 09:45:26 +01:00
Luke Usher ad978f3daf mia: fix location of game database on posix systems 2023-06-02 20:12:09 +01:00
kev4cards fbdd42beb6 n64: add epsilon to axis values
prior to casting to s8
2023-06-01 10:42:16 +01:00
kev4cards a349770472 n64: change linear response
to scale according to cardinalMax, rename startCardinalMax and others for better clarity, and reformulate startCardinalMax based on new response equation.
2023-06-01 10:42:16 +01:00
Jeff Linahan 08c00d186a sfc: master volume -> main volume 2023-06-01 10:42:06 +01:00
Luke Usher 4c3786b067 a26: fix reset of tia audio for real this time 2023-05-25 10:23:27 +01:00
Luke Usher a8f3e353cd a26: fix reset of tia audio 2023-05-25 10:22:06 +01:00
Luke Usher 98dc6faefb a26: better vertical resolution handling 2023-05-25 10:19:14 +01:00
Luke Usher 41157ad555 thirdparty: fix build after libchdr update 2023-05-22 23:02:55 +01:00
Luke Usher 3e9ce82ccb Squashed 'thirdparty/libchdr/' changes from a20e04c12..54bfb871c
54bfb871c Merge pull request #99 from scribam/dr_libs
5cd76b97e Revert "deps: add dr_libs as a header-only library"
903f2f5cc Merge pull request #93 from scribam/deps
1ccead153 deps: add dr_libs as a header-only library
3c6e0e47a deps: add zlib-1.2.13
8e04476eb deps: remove zlib 1.2.11 and zlib 1.2.12
468490000 Merge pull request #97 from scribam/github-workflows
b2996c832 Add basic GitHub Actions
688759416 Merge pull request #96 from scribam/malloc
10c340c5a Check mem alloc failures triggered by invalid chd
37a5c0f3c Merge pull request #94 from scribam/auxv
026969b6d Merge pull request #95 from scribam/division
179f02553 Avoid division by zero
5f3927dc3 Declare hardware capabilities for the Nintendo Switch and PlayStation Vita
fec8ab942 Merge pull request #89 from jpd002/huff_codec
4ddae00e5 Merge pull request #91 from flyinghead/master
de740535f Avoid huffman tree buffer overrun in huffman_import_tree_rle
571507743 Add support for 'huff' codec.

git-subtree-dir: thirdparty/libchdr
git-subtree-split: 54bfb871ccae31903b95a8feb7f2bf7121f304be
2023-05-22 22:39:36 +01:00
Luke Usher 43cfbd629c Merge commit '3e9ce82ccbad370ac0da38a7cdf0e2f98b62239c' 2023-05-22 22:39:36 +01:00
Luke Usher 509d749663 Squashed 'thirdparty/sljit/' changes from 4f7d8ec54..51538f102
51538f102 documentation: refactor registers and function signatures (#169)
47ed75d0b Improve copy between float and general regs on x86-32
91798631a Fix uint to float conversion on x86, ppc, mips
6a8dc94e0 Implement unsigned to float conversion on ppc, mips
61736a11a Implement unsigned to float conversion on s390x
ec6d52516 Implement unsigned to float conversion on x86, arm, riscv
f368bb254 arm64: use MOV instead of ORR for readability (#166)
07a556181 arm64: implement atomics using CAS for CPUs with LSE (#164)
1a4d5f229 Improve atomic operation constraints (#165)
b7fed8e11 x86: correctly detect mode32 for atomic_store (#163)
a0e16b14f arm64: avoid undefined behaviour with signed shifts (#161)
7f2886127 Implement operations on s390x
c54325fee Improve atomic instructions
3499aba93 Set armv6 as the minimum arm version
53d5a2252 Implement set f32/f64 on x86, arm, riscv, ppc, mips
03bb5347f Improve atomic operations
b91921e24 Increase max stack to 1 Mbyte
af4ca5da5 Add atomic instructions (#157)
e37ec3253 macos: allow runtime detection if target is older than BigSur (#127)
5ed7e00a1 Remove functions for unsupported architecture
fa1881b57 Implement operations on s390x
cf5a17b77 Implement fselect operation on x86
e5c75cd73 Implement rev.u32 and rev.s32 on x86, arm, riscv, ppc, mips
d1f287bec Implement select, rev.u16 and rev.s16 on s390x
7efd60de8 Implement rev.u16 and rev.s16 on x86, arm, riscv, ppc, mips
63e307e4a Implement select operation on x86, arm, riscv, ppc, mips
3cc2b0fb2 Improve floating point comparison

git-subtree-dir: thirdparty/sljit
git-subtree-split: 51538f102dd342a6246e98acafc00ceebbab4618
2023-05-22 22:39:31 +01:00
Luke Usher 71d5a59c19 Merge commit '509d749663ed8811c3b0b6e32130833fb5ffff76' 2023-05-22 22:39:31 +01:00
Luke Usher bf9caa706c Merge commit '8bac0decbe7b265594b3589b1542766f69fae1ba' 2023-05-22 22:39:21 +01:00
Luke Usher 8bac0decbe Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 3abd43776..8da2be35a
8da2be35a Update to d95cf9b09c31e1b239eb7e90255e048ffa184360.
141d253c4 Update to 85363ec733561ab545103888f440dec500cbb96a.
101d5a2bb Update to 7375ad2d83f744cf0236ad181f23b3d4b6903857.

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 8da2be35abbbf503a485993c717e4917a1560324
2023-05-22 22:39:20 +01:00
Tim Allen 4e73783cc1 mia: Extend the Super Famicom LOROM-RAM#A memory map.
Although Nintendo made many different cartridge circuit boards with different
memory mappings, ROMs do not indicate which specific board they are intended
to work with. Super Famicom emulators traditionally group mutually-compatible
mappings together and use heuristics to guess which family of mappings the
game expects.

There's one family of mappings that maps ROM data to the top half ($8000-$FFFF)
of memory banks in the Super Famicom address space. For historical reasons,
this family is called "LoROM" and has three main variants:

1. ROM only, mapped to the top half of every possible bank.
   The boards database calls this "LOROM".
2. ROM mapped to the top half of every possible bank,
   RAM mapped to the bottom half of banks 70-7d,f0-ff.
   The boards database calls this "LOROM-RAM"
3. ROM mapped to the top half of low-numbered banks,
   RAM mapped to both halves of banks 70-7d,f0-ff.
   The boards database calls this "LOROM-RAM#A"

The largest official game that used variant 3 was 1MiB, so a common heuristic
is "if the ROM is 2MiB or less, use variant 3, otherwise use variant 2".
2MiB is used as the threshold instead of 1MiB, perhaps so somebody can expand a
commercial ROM that uses variant 3 without having to rework it to suit a
different mapping.

Since v107 or so, higan (and by extension, ares) has implemented variant 3 by
mapping ROM to banks 00-3f,80-bf, which exactly fits a 2MiB ROM. However,
other emulators like Mesen, snes9x and higan v106 implement it by mapping ROM
to banks 00-6f,80-ef, all the space that is left after the RAM is mapped.

This doesn't affect any verified games in the `Super Famicom.bml` database,
since those have specific, accurate memory maps. It also won't affect
well-written games that only read from memory addresses they have populated.
However, homebrew games and ROM hacks that have never existed on a real circuit
board depend on these heuristics across all devices that read Super Famicom
ROMs, including software emulators, flash-carts, and FPGA implementations, so
ares should match what other emulators do.
2023-05-22 13:20:10 +01:00
Tim Allen 257a6db658 Regenerate mia resources to include updated board data.
In commit 93e89446e2, the board database was
updated without mia's resource file being rebuilt.
2023-05-22 13:20:10 +01:00
aquova e02938c23f Add support for IPS patching
Adds support for patching ROMs on the fly with a corresponding IPS patch
file. Functions in a similar manner to the pre-existing BPS support. If
a *.ips file is found with the same name as the ROM, it attempts to
apply the patch. If both a BPS and IPS file are found, the BPS patch
takes priority. This patch implements the IPS format as described here:
https://zerosoft.zophar.net/ips.php
2023-05-21 14:19:49 +01:00
encoded-byte f0fe40d5da fc: slightly adjust fds output level
make clear where the magic number comes from
2023-05-12 15:39:27 +00:00
encoded-byte 990fd4e21c fc: fix fds sound pitch
modulator output needs to be updated after changing speed / gain
2023-05-12 15:39:27 +00:00
encoded-byte 6769031bfb fc: fix fds sound enable address 2023-05-12 15:39:27 +00:00
Luke Usher 013b4f2645 gb: stop instruction resets div to 0 2023-05-09 19:03:40 +01:00
Luke Usher 75821d404b gba: implement upper bounds for background fetch, fixes Monster Gate 2023-05-06 21:48:40 +01:00
invertego 0311d1ca56 libchdr: instruct glibc to declare fseeko/ftello 2023-05-05 06:14:25 +00:00
invertego 6a7898396a nall: add needed #include <stdexcept> 2023-05-03 07:15:06 +00:00
kev4cards a4dbeb45d1 n64: increase initial circle radius
to encircle octagon fully
2023-04-30 08:14:56 +00:00
sdebian d13715d8bb Adds fallback for situations where a single montior is detected but it is not
primary.
2023-04-29 21:51:06 +00:00
encoded-byte 03bfe5a3ab fc: support for mmc3 multicards 2023-04-25 15:59:07 +00:00
Luke Usher 9b32ef7faa pc-engine: don't hard code multitap, allow multitap selection
Note that this still has an issue where infinitely nesting multitaps
can cause ui issues, but it's functionally complete.
2023-04-24 10:58:00 +01:00
invertego c05d7b2070 pce: fix off-by-one error for scanline interrupts 2023-04-24 08:24:29 +00:00
Giovanni Bajo 239a902a77 n64: fix BADVADDR in TLB miss exception raised by SWR
SWL/SWR do not raise address errors (it's their whole reason of
being), but they can still raise TLB misses if they access an unmapped
memory area. In that case, the COP0 BADVADDR register is expected to
contain *exactly* the address passed to them.

This happened to be true (by luck) for SWL but not for SWR: SWR in fact
needs to write *before* the address passed to it, so the opcode itself
was adjusting the address before calling the memory function.

Fixed by passing the misaligned address to CPU::write and telling it
to skip address errors. It's not pretty: the code in CPU::write/read is
a bit of a mess and it would require some refactoring but that's for
another day.

Verified on real hardware by adding a new test to n64-systemtest, which
is has been submitted upstream (https://github.com/lemmy-64/n64-systemtest/pull/50).
2023-04-23 10:40:53 +00:00
Luke Usher b7da32113f chd: fix an incorrect assumption that the first track will always be data for game media 2023-04-21 21:57:21 +01:00
Luke Usher cbc3acada1 chd: fix an issue where mia would read from the start of a disc rather than the first data sector 2023-04-21 21:56:29 +01:00
TascoDLX 75e17ca213 m68000: fix instruction timings & cycle order 2023-04-17 06:38:44 +00:00
TascoDLX 0d376ddb24 m68000: fix privilege violation behavior 2023-04-17 06:38:44 +00:00
TascoDLX cff8b55310 z80: fix undocumented instructions & flags behavior 2023-04-17 06:38:44 +00:00
invertego acff6a93ad fc: support ave nina-03/06 boards 2023-04-15 13:27:22 +00:00
Luke Usher fdea53cad4 6502: fix nes/fc initial state/reset tests 2023-04-14 22:59:13 +01:00
Luke Usher ca03794534 sh2: make timers update at correct frequency with recompiler 2023-04-14 20:25:34 +01:00
Luke Usher 4c646c539e sh2: fix typo in WDT frequency table (2096 -> 4096) 2023-04-14 11:36:13 +01:00
invertego 7c74821b78 sh2: boost sync on pending interrupt
Interrupts are deferred when the CPU is in a branch delay slot. If the
recompiler repeatedly exits the code cache in a delay slot (much more
likely with "min cycles between syncs" optimization active) then
interrupts will be deferred indefinitely.

This is now avoided by resetting the "cycles until sync" count when
interrupts are deferred due to a branch delay slot.

An alternate and possibly more robust solution would be to single step
the next instruction with the interpreter. One side effect would be the
generation of more compiled blocks.
2023-04-13 07:39:52 +00:00
invertego 019ceea8d6 readme: mention lld requirement with clang 2023-04-10 07:50:14 +00:00
Luke Usher 33a406701e fc: implement submapper types for VRC2/VRC4; pass VRC2/4 test roms 2023-04-09 10:24:03 +01:00
Giovanni Bajo 9bfa1fe7ce n64: fix cache line selection
VR4300 icache/dcache use both the virtual address and the physical
address: the former one is used to select the cacheline (just like
the key to a hashtable), while the latter is used to check that the
cacheline contains the correct line of memory and not another one
that happens to have the same hash key.

So any access to the cache requires both addresses. This commit makes
this explicit, and make sure to call the functions correctly.

The only exception where we leave a FIXME is the icache.step call
in the recompiler, as we can't possibly devirtualize the PC for each
opcode. This will have to be fixed in another way.
2023-04-09 06:59:00 +00:00
invertego 21c24b31ad pce: prevent destruction of bram on non-CD load
With PC Engine, ares always emulates the presence of CD-ROM drive so
games can use its backup RAM for save data. However, it was not properly
loading the backup RAM file when loading a non-CD game, causing the file
to be subsequently filled with FFs on save.
2023-04-09 06:05:22 +00:00
invertego 98b3c8ef7b pce: fix bram size detection in BIOS
The BIOS format procedure detects the size of backup RAM by sweeping
bank $f7 while writing zero and reading back the result. It stops when
the read back value is nonzero, proving that the 2 KiB backup RAM is not
intended to be mirrored across the 8 KiB address range. With this
corrected in ares the BIOS writes the correct header indicating the end
of the backup RAM is at 0x8800 rather than 0xA000.
2023-04-09 06:05:22 +00:00
invertego f514327594 pce: zero bram when formatting
The BIOS format procedure does this and Rondo of Blood relies upon it.
2023-04-09 06:05:22 +00:00
minneyar 4c3b7b636f Add "Reset System" hotkey
This adds a hotkey that can be used to reset the active system.

Although this is similar to the existing "Reload Current Game" hotkey, it does have a functional difference, since a soft reset can result in the state of a system being slightly different than a cold boot.  It also does not result in resizing the emulator window and is slightly faster due to not needing to reload various resources.
2023-04-07 06:39:53 +00:00
TascoDLX 2c867d37e6 ng: bump serializer version for ym fix 2023-04-06 21:25:03 +00:00
TascoDLX 901cfd7e52 md: bump serializer version for ym2612 fix 2023-04-06 21:25:03 +00:00
TascoDLX 7565591cf8 ym2612: include crossover distortion 2023-04-06 21:25:03 +00:00
TascoDLX 6502327ad2 ym2612: delay operators due to pipelining 2023-04-06 21:25:03 +00:00
invertego d5cba61203 sh2: mirror cache control register 2023-04-03 09:34:15 +00:00
TascoDLX 3ae339ae14 sn76489: fix freq counters & output 2023-03-31 08:25:09 +00:00
Luke Usher 26d63dd04a desktop-ui: fix an issue where the game browser would sometimes load the wrong title 2023-03-30 13:30:07 +01:00
Luke Usher f9d54ebbb0 desktop-ui: add game browser for arcade roms
This makes arcade systems with strict rom requirements, such as neo geo much easier to manage
2023-03-30 13:25:47 +01:00
invertego 1508f6b488 nall: split main.cpp into separate translation unit
When using nall as a header-only library it was possible to opt out of
nall taking over main() by simply not including main.hpp. There was no
mechanism to opt out when building nall as a separate translation unit
because nall.cpp unconditionally pulled in main.cpp. Now, users of nall
must specifically opt in by including main.cpp in their build (though
header-only users still only need to include main.hpp).
2023-03-30 06:43:04 +00:00
invertego 146bc3764d sh2: fix hashing max size blocks 2023-03-30 06:42:10 +00:00
invertego 4cfa728413 sh2: fold cached interpreter into recompiler 2023-03-29 06:37:34 +00:00
invertego 600964d722 sh2: reuse previously recompiled blocks 2023-03-29 06:37:34 +00:00
invertego 241f0e9a36 sh2: precise recompiler block invalidation
- Update dirty bit field on invalidate so overlapping blocks can be lazily evicted
- Track "generation" to allow entire cached memory area to be lazily evicted
- Invalidate appropriate cache line/memory area on cache purge
2023-03-29 06:37:34 +00:00
Luke Usher 462afe89f8 md: undo reduce vdp sync when emulating 32x
While a significant performance increase, it broke Metal Head and some other titles; not worth the trade off.
2023-03-28 14:27:18 +01:00
TascoDLX 7e237528b4 md: bump serializer version 2023-03-27 14:10:04 +00:00
TascoDLX 076d73fafb mcd: handle empty drive state 2023-03-27 14:10:04 +00:00
TascoDLX 9ab140b289 md: latch vdp window params 2023-03-27 14:10:04 +00:00
TascoDLX 4418470316 md: allow invalid link to terminate sprite list 2023-03-27 14:10:04 +00:00
TascoDLX fda7c79b51 m32x: sync to fix vdp render issue 2023-03-27 14:10:04 +00:00
Luke Usher 4713fb37cc mia: add database entries for two more games with bad header information 2023-03-24 11:33:41 +00:00
Jeff Linahan 84b5222332 removed auto-generated qt.moc 2023-03-24 10:06:56 +00:00
Jeff Linahan f11ad490cd discord invite link 2023-03-22 17:48:20 +00:00
invertego 4b2b00a834 nall: use llvm's lld linker with clang
Using lld is required to support advanced scenarios like incremental
ThinLTO and PDB symbol output. macOS has its own linker (ld64) and we
can continue to use that there.
2023-03-20 10:38:37 +00:00
invertego 608556e0a9 nall: remove c++20 diagnostic for gcc
This diagnostic is unrecognized until GCC 12 and even then it doesn't
seem to actually do anything. We can rely on Clang for coverage here.
2023-03-20 10:38:37 +00:00
remutro f2ca7a973c Feature: undo last save or load state 2023-03-20 10:38:26 +00:00
remutro be869f9772 don't rely on extended header for region if present 2023-03-16 16:07:56 +00:00
remutro 5a4d333734 include make file changes 2023-03-15 11:10:12 +00:00
remutro 81692a076c Fix previous RTC properly as well as GDB symbol generation on Windows 2023-03-15 11:10:12 +00:00
Luke Usher b6350b3c0f md: (performance) reduce vdp sync when emulating 32x 2023-03-14 13:57:09 +00:00
invertego 0734768955 mia: respect iNES 2.0 NTSC timing setting
If the iNES 2.0 header specifies NTSC timing, ares should not emulate a
PAL console even if the user region setting is "prefer Europe".

This change also embeds the iNES header in manifests to simplify user
bug reporting.
2023-03-14 09:28:14 +00:00
Luke Usher 4aa3b27de2 build: remove msvc/msbuild for now
While I am happy we did the work to support this, having multiple
build systems does make it harder for contributions to be made

We can restore msbuild CI tests once (if) we eventually switch
to cmake.
2023-03-13 20:56:59 +00:00
invertego 89b3e5a20b build: a couple minor makefile fixes
Apply -march tuning for x86 (not just x86-64) and correctly pass
the ThinLTO cache path through the non-CL Clang frontend on Windows.

The move to CMake can't come soon enough.
2023-03-13 18:17:41 +00:00
invertego 65a3d38a2a build: enable clang ThinLTO
With ThinLTO and an incremental LTO cache, incremental link time (with
LTO, of course) goes down from tens of seconds to less than a second.

For whatever reason, ThinLTO needs libco's co_swap_function to have
external linkage. Who am I to argue?
2023-03-13 15:38:39 +00:00
invertego aa9c641083 mcd: always allocate cartridge slot
When booting the MD core from a CD a board is allocated on demand in
Cartridge::power(), and this is critical for Mega CD 32X games to
function. However, it also puts the cartridge into an inconsistent state
in which allocate() was never called and therefore catridge.node is
null, causing disconnect() and save() to be short-circuited. This means
the board never gets cleaned up, which also means it never gets
recreated in power() on subsequent loads. One consequence is that
loading a MCD game followed by a MCD 32X game will cause the 32X to not
actually be connected.

Given that all of these system configurations contain a cartridge slot,
it follows that one should always be allocated. This implies
cartridge.node will always be non-null so it cannot be used to determine
if a cartridge is actually connected. This change corrects one such
usage.
2023-03-13 15:38:11 +00:00
invertego b178d3d51a build: support 32-bit x86, arm 2023-03-13 11:21:26 +00:00
invertego 32bfb2ed08 ci: add builds for make+cl and msbuild 2023-03-13 11:21:26 +00:00
invertego 7f7cc868c4 build: add vs project + solution for desktop-ui 2023-03-13 11:21:26 +00:00
invertego 334101d599 build: support arm64 msvc build 2023-03-13 11:21:26 +00:00
invertego 65e6d0a397 nall: implement platform.hpp macros for msvc 2023-03-13 11:21:26 +00:00
invertego fff03a3d56 nall: assume sse4.1 support building with msvc
MSVC does not define architectural levels in between /arch:SSE2 and
/arch:AVX. For now, let's just assume SSE4.1 support.
2023-03-13 11:21:26 +00:00
invertego bbbd621130 n64: do not require __builtin_clz
Use MSVC intrinsic as an alternative when possible, otherwise fall back
to standard C++.
2023-03-13 11:21:26 +00:00
invertego fc50ad03ae md, n64: do not require __int128 extension
Avoid hard dependency on __int128 type suppport. For extended
multiplication, use MSVC intrinsics as an alternative when possible.
If neither are supported, fall back on the u128 type defined in
nall/arithmetic.hpp (which incidentally also works when building as
32-bit).
2023-03-13 11:21:26 +00:00
invertego b7a1fe926a a26: avoid narrowing conversion in default member initializer
MSVC applies the same narrowing rules to these as it does to list
initializers, and while I don't know if that's justified by the standard
it's easy to avoid narrowing conversions. In this case, basically every
other core already defines System::frequency as a double so the a26 core
was the odd one out.
2023-03-13 11:21:26 +00:00
invertego c4588ee4f4 libco: fix section overrides with msvc
MSVC doesn't seem to support string literal concatenation in a
__declspec attribute, but that's fine because we only care about adding
to the .text section. It also requires an explicit pragma to define the
.text section before it can be referenced. Clang is fine with or without
these changes.
2023-03-13 11:21:26 +00:00
invertego 21d5bf4183 nall: msvc build fix for Node::sort
MSVC doesn't think the lambda in the default parameter has access to the
members it reads from. I'm not sure if's right but it's easily avoided.
2023-03-13 11:21:26 +00:00
invertego e38b7e586d nall: add move constructors to BitField/Range
MSVC wants these to compile certain experessions, and while I'm not 100%
sure if it technically should require them, I see no reason for these
classes not to have any.
2023-03-13 11:21:26 +00:00
invertego e01d5c1866 build: rearrange calling convention overrides
MSVC is more strict about the ordering of these than GCC/Clang.
2023-03-13 11:21:26 +00:00
invertego 4e96e39ab2 build: add makefile support for cl, clang-cl 2023-03-13 11:21:26 +00:00
invertego 9fce98f7d7 build: avoid narrowing conversions in initialization lists
Narrowing conversions in initialization lists are disallowed by the
standard, but nall was supressing this diagnostic (which is actually
an error by default). MSVC doesn't let you supress errors so easily, so
we'd do well to abide by the standard and perform explicit casts as
needed. For nall::shared_pointer::create() we can simply avoid the
uniform initialization syntax to bypass these extra rules, which is the
same strategy taken by implementations of std::make_shared().
2023-03-13 11:21:26 +00:00
invertego 91c0844f19 build: avoid use of GNU case range extension 2023-03-13 11:21:26 +00:00
invertego b872687145 build: avoid use of operator name keywords 2023-03-13 11:21:26 +00:00
invertego 8914915b31 build: avoid use of variable length arrays
Variable length arrays are a C language feature (one of many, actually)
that does not exist in any version of the C++ standard. GCC supports
them in C++ with improvised semantics defined by no standards body, and
Clang follows suit for compatiblity with GCC.
2023-03-13 11:21:26 +00:00
invertego 188171b49d build: avoid use of GNU statement expression extension 2023-03-13 11:21:26 +00:00
invertego 4befb14e47 build: avoid use of non-standard escape character '\e'
Unfortunately there's no way to enable warnings for this without turning
on a bunch of others (with -Wpedantic).
2023-03-13 11:21:26 +00:00
invertego 42118b22e4 build: avoid use of c++20 extensions
We are already specifying `-std=c++17`, but apparently GCC and Clang
treat that as more of suggestion than a command...
2023-03-13 11:21:26 +00:00
remutro 8af10a6816 Add missing cast resulting in truncated timestamp 2023-03-13 09:19:16 +00:00
remutro 6dd3fdca68 Don't use rom hash to allow for homebrew 2023-03-13 09:18:31 +00:00
remutro 56a848b59d Fix save for Sonic 3 & Knuckles 2023-03-13 09:18:31 +00:00
Giovanni Bajo ac06c41145 desktop-ui: add CLI options to manage settings
Now a setting can be changed from command line using --setting.
The list of settings can be dumped with --dump-all-settings, so that
it is easy to find out how a certain setting is exactly spelled.
2023-03-12 22:39:43 +00:00
invertego 267b6e0f21 n64: make out-of-range shift deterministic in MAME RDP
Matches the SSE and VMX implementation.

Fixes obvious rendering artefacts with the N64 RDP on AArch64 targets.
2023-03-12 22:39:31 +00:00
remutro 164775e4a7 force PAL region for Alisia Dragoon (E) 2023-03-10 13:26:09 +00:00
Luke Usher c2004f6ad5 ruby: remove ghost Direct3D 11.0 driver 2023-03-08 19:30:34 +00:00
Luke Usher 832a2ada10 ares: bump version to v132 2023-03-08 10:06:59 +00:00
TascoDLX 383d2db303 md: fix vdp port mirroring 2023-03-07 23:02:26 +00:00
TascoDLX 358985e8c1 md: fix realtec mapper 2023-03-07 23:02:26 +00:00
remutro 41b6147ca7 add shader command line option to help 2023-03-07 18:46:44 +00:00
TascoDLX 6868f1bf1d mcd: fix cdc counter register 2023-03-06 10:54:35 +00:00
TascoDLX 4d43b2ce1f mcd: fix timer update 2023-03-06 10:54:35 +00:00
TascoDLX c41666fee6 mcd: implement peripheral reset 2023-03-06 10:54:35 +00:00
TascoDLX 768a4724af mcd: avoid early pcm address update 2023-03-06 10:54:35 +00:00
TascoDLX 2ed64ef858 md: fix sync logic 2023-03-06 10:54:35 +00:00
remutro b269647a9f console option, we never knew you 2023-03-06 10:53:26 +00:00
remutro db97949965 Updates based on feedback 2023-03-06 10:53:26 +00:00
remutro 81a67475dd add option for building cores 2023-03-06 10:53:26 +00:00
remutro 92211c78ec Updated build instructions 2023-03-06 10:53:26 +00:00
invertego 1359f36703 md: add realtec mapper support 2023-03-06 10:52:31 +00:00
invertego ae9c3ae728 desktop-ui: improve terminal support on windows
Previously, terminal (console) support on Windows required opting in at
compile time. Now, the runtime behavior is largely the same regardless
of how ares is compiled.

- ares will attach to the terminal of the parent process (if present) by
  default and redirect any unset stdio streams.
- If the --terminal argument is provided, ares will always create a new
  terminal window and stdio will be redirected to it.
- Otherwise, if stdio handles were already valid on launch they will be
  left alone (to support redirection to/from files).
2023-03-04 20:41:24 +00:00
Giovanni Bajo d61664e724 n64: complete generation of address errors
This also handles the fetch and devirtualize case, that cover also
the situation where the CPU jumps to a misaligned PC.
2023-03-03 19:08:48 +00:00
Giovanni Bajo ec21b9f44c n64: fix PC address at exception
Use always a 64-bit address (even if the context is 32-bit: it gets
sign-extended there anyway).
2023-03-03 19:08:48 +00:00
remutro 6822628135 Resetting the screen isn't necessary 2023-03-01 09:13:24 +00:00
remutro 0a6147c177 Fix for Peter Lemon's CPU reset test 2023-03-01 09:13:24 +00:00
invertego 9b521dd87b desktop-ui: optimize for x86-64-v2 in non-local builds
This is a more generic way of declaring an Intel Nehalem -like set of
ISA extensions in newer versions of GCC (11) and Clang (12).
2023-02-28 15:43:24 +00:00
invertego e4fee670ad desktop-ui: check for SSE4.2 support in non-local builds
By default, builds are "local", meaning they are optimized specifically
for the host machine. For non-local builds such as our CI builds, we
enforce a minimum CPU spec to allow the compiler to use instructions
beyond the base AMD64 ISA. ares may also make use of SSE4 instructions
via intrinsics in the N64 core. On AMD64, the capabilities of the host
CPU are now checked at runtime and an error message will be displayed to
inform users if their machine does not meet the CPU requirements of that
build.
2023-02-28 15:43:24 +00:00
invertego 3a6113846f ci: simplify mingw arm64 build setup
- Because clangarm64 is now a default enabled package source, there is
  no need to edit pacman.conf.
- Because there is no need to edit pacman.conf, there is no need to sync
  the package database.
- Because there is no need to sync the package database, there is no
  need to update the initial set of installed packages to prevent
  version mismatches.
- Install the "clang" package in favor of the "toolchain" package group
  as none of the extra packages are needed by ares.
2023-02-28 10:25:43 +00:00
invertego a0c7b3bf6a ruby: in wasapi driver, force silence in channels after first 2
The other audio drivers in ares read exactly two samples from the buffer
passed to output(), but the WASAPI driver was reading the number of
channels supported by the device. ares only ever passes in two samples
so ruby was reading beyond the extent of the array. This caused garbage
to be piped through and resulted in silence on certain systems and build
configurations (likely because of NaNs).
2023-02-28 10:25:19 +00:00
TascoDLX 11003eb5f1 mcd: handle subcpu wordram access when unavailable 2023-02-26 09:48:36 +00:00
TascoDLX dadf0d4228 mcd: fix subcpu reset behaviors 2023-02-26 09:48:36 +00:00
invertego 4fede70705 nall: stop defining NOMINMAX in makefile
This was only needed for parallel-rdp and that's been fixed upstream
which is now causing redefinition warnings. It's still defined by nall
headers so most of ares is unaffected either way.
2023-02-26 08:03:58 +00:00
TascoDLX b984bb52e9 md: implement io latch behavior & serial registers 2023-02-25 20:23:42 +00:00
TascoDLX b6bdd06c4e mcd: protect against illegal memory access 2023-02-25 20:23:42 +00:00
TascoDLX c57130a4bf mcd: fix various gate array registers 2023-02-25 20:23:42 +00:00
invertego 7a9a99f62c mcd: add missing cdc irq serialization 2023-02-24 08:02:30 +00:00
invertego 8156a7b760 sh2: elide runtime delay slot check when possible 2023-02-24 08:01:53 +00:00
invertego ff5c8acd9a sh2: implement illegal slot exceptions in recompiler 2023-02-24 08:01:53 +00:00
invertego 6584f6e691 sh2: fix illegal slot exceptions in interpreter
When in a delay slot, instructions that modify PC should immediately
trigger an illegal slot instruction exception. This exception is not
predicated on the branch condition (in the case of BF/S or BT/S) of the
instruction in the slot. Furthermore, it should trigger before any side
effects of the instruction are observed.
2023-02-24 08:01:53 +00:00
Luke Usher 662c1f7b66 desktop-ui: disable color bleed by default 2023-02-23 14:52:40 +00:00
invertego 4b70e4e891 mcd/32x: default to single gamepad for Corpse Killer (E) 2023-02-23 10:22:12 +00:00
Luke Usher 2e6531a036 ps1: rename sio acknowledgeInputLevel to ackknowledgeAsserted, fix io.readWord 2023-02-21 15:20:18 +00:00
Luke Usher a79a9f0fbf nall: support mode1/2048 tracks in CHD files 2023-02-20 19:32:26 +00:00
Adrian Siekierka 326616f936 ws: fix APU not emitting channel 2 output when only voice enabled 2023-02-20 17:29:20 +00:00
Adrian Siekierka d213010a72 ws: add stub KARNAK emulation 2023-02-20 17:29:20 +00:00
invertego 8b80201d16 ps1: automatically format memory cards 2023-02-20 17:28:50 +00:00
invertego c23d842a90 ps1: actually persist memory cards to disk 2023-02-20 17:28:50 +00:00
TascoDLX 8b93f57293 mcd: bypass cdd tracking command to support v1 bios 2023-02-19 17:33:51 +00:00
remutro a0f46b4dac fix ws save states 2023-02-16 15:41:23 +00:00
Giovanni Bajo d4f9caee65 n64: improve boot timeout handling
Raise the timeout to make Start Wars: Shadows of the Empire boot again.
Also improve simulation of CPU halt; the real PIF does toggle the NMI
line but it does so extremely quickly. We don't emulate PIF that often,
so it's more accurate to simply keep the NMI line asserted forever,
as the final effect on the CPU is the same.
2023-02-16 09:36:50 +00:00
Luke Usher 5e48762c48 desktop-ui: base multiplayer from actual framebuffer size
Previously, it was just based on a base size of 320x240.
2023-02-15 22:38:38 +00:00
Luke Usher 0ba4f49e04 desktop-ui: remove multiplier debug print 2023-02-15 22:31:53 +00:00
Luke Usher cc8cf2539f desktop-ui: fix rounding issues in multiplier calculation 2023-02-15 22:18:55 +00:00
Luke Usher 663e341584 ruby: rename Direct3D driver to Direct3D9
Allows for development of Direct3D11/12 drivers in future
2023-02-15 22:18:54 +00:00
invertego b4f6912d68 hiro: fix macOS open/save panels allowing all file types 2023-02-15 11:33:31 +00:00
Luke Usher 9f6a1548d1 desktop-ui: rework scaling settings
The multiplier scale settings are now radio buttons, allowing the
user to see which option is selected.

Available scale sizes are no longer bound by the current monitor
size, avoiding the situation where a selected option disappears
when moving a portable configuration to a different computer,
instead, the actual resizing code prevents the window from growing
larger than the display size.

The window resizing logic now avoids un-maximizing the window, if
the user has manually done so, even when adaptive sizing is
enabled.

Scale options have been renamed to better describe their function
and two new scaling modes have been added:

"Center" has been renamed to "Scale (Integer)"
"Scale" has been renamed to "Scale (Best Fit)"

New setting: "Pixel Perfect" which will always display a 1x scale
image in the center of the display, regardless of the window size

New setting: "Scale (Fixed)" which will always display an image
matching the users selected scale factor (1x, 2x, etc) regardless
of screen size.
2023-02-15 11:08:53 +00:00
Luke Usher 2e8ac93a42 a26: fix scale (thanks FitzRoyX) 2023-02-15 09:27:40 +00:00
Luke Usher 41b0a55af3 ng: fix overscan and scale (thanks FitzRoyX) 2023-02-15 09:27:27 +00:00
Luke Usher a6d4fd7c3e ng: fix issue where adpcm-a steps may be processed late 2023-02-14 18:31:51 +00:00
Luke Usher 99d711497e Revert "Radio the scale settings and allow 1x #945"
This reverts pull-request #945 as it made ares rather frustrating
to use in non-1x situations for most users.

A more robust scaling solution will be worked on soon.
2023-02-14 15:01:05 +00:00
Giovanni Bajo 518666b18a n64: increase boot timeout in PIF HLE
Allow Turok to boot again. This probably points to a problem in our
CPU timings, but the boot timeout number is made up anyway and doesn't
really help anyone to keep it short, so bump it.

Thanks to kev4cards for the analysis
2023-02-13 09:36:36 +00:00
Giovanni Bajo 6d6c058d25 n64: fix savestates by serializing cic object 2023-02-13 09:36:36 +00:00
Giovanni Bajo 48e7bdc3b4 n64: add more support for 64DD on PIF HLE 2023-02-13 09:36:36 +00:00
Giovanni Bajo c46abdf02e n64: improve support for 64DD 2023-02-13 09:36:36 +00:00
Giovanni Bajo 0cbac7df02 n64: avoid usage of localtime_r 2023-02-13 09:36:36 +00:00
Giovanni Bajo 9355fc2228 n64: add savefile for RTC and detect Animal Forest 2023-02-13 09:36:36 +00:00
Giovanni Bajo 08b48cec4c n64: add support for joybus RTC 2023-02-13 09:36:36 +00:00
Giovanni Bajo 0480285fa7 gamepad: improve accuracy of controller pak and rumble pak emulation
Controller paks only accept writes in range 0-7FFF (without mirroring),
and return 0 when reading out of range.

Rumble paks return the ID only in range 0x8000-???? (TBC)
and accept writes only in range 0xC000-???? (TBC).

Fixes Milo's Astro Lanes saves, and Goldeneye initial rumbling.
2023-02-13 09:36:36 +00:00
Giovanni Bajo 7770327d3c n64: fix an off-by-one causing buffer overflow 2023-02-13 09:36:36 +00:00
Giovanni Bajo e57e77cb11 n64: complete PIF serializer 2023-02-13 09:36:36 +00:00
Giovanni Bajo 4c73d18494 n64: fix seed prefix on the wire (which is not random at all) 2023-02-13 09:36:36 +00:00
Giovanni Bajo 1918c912c5 n64: increase the HLE steps as it shouldn't matter much anyway 2023-02-13 09:36:36 +00:00
Giovanni Bajo e6912d4514 n64: change PIF/CIC fifo queue to be bit-based instead of "frame-based" 2023-02-13 09:36:36 +00:00
Giovanni Bajo 12dbcb1b40 n64: emulate dummy challenge algo on non-6105 CICs 2023-02-13 09:36:36 +00:00
Giovanni Bajo 45a4f1a366 n64: move 6105 challenge code from PIF to CIC (where it belongs) 2023-02-13 09:36:36 +00:00
Giovanni Bajo a51a52263a n64: correct some more details around the osinfo byte in PIF-RAM 2023-02-13 09:36:36 +00:00
Giovanni Bajo b395886327 n64: fix a couple of bugs in PIF HLE 2023-02-13 09:36:36 +00:00
Giovanni Bajo 95215dec1d n64: add accuracy option to activate region lock 2023-02-13 09:36:36 +00:00
Giovanni Bajo b697623c13 n64: in PIF HLT, move Rn state check to the top and mark it likely 2023-02-13 09:36:36 +00:00
Giovanni Bajo d965cc8f13 n64: boot timeout fix 2023-02-13 09:36:36 +00:00
Giovanni Bajo 00de20af93 n64: rewrite PIF HLE emulation to be very accurate to the SM5 firmware 2023-02-13 09:36:36 +00:00
Giovanni Bajo 8097ae3ae5 n64: add NMI emulation to the CPU 2023-02-13 09:36:36 +00:00
invertego a63d20c0d1 ares: support disconnecting controller from emulated device
Selecting "nothing" for a controller port from the UI only consistently
blocked input from the host, and it did not reliably do the extra work
required to actually disconnect the controller from the perspective of
the emulated device.

This was handled only by the MD and N64 cores, but now all cores are
standardized on the disconnection method originally implemented for MD.
2023-02-13 09:30:29 +00:00
Adrian Siekierka 5c05e80c48 ws: fix rtc typo 2023-02-11 19:24:37 +00:00
Luke Usher f9b5a8a3a6 nall: add bcd encode/decode 2023-02-10 19:40:46 +00:00
Adrian Siekierka 5db4443529 ws: rewrite RTC emulation 2023-02-10 18:37:39 +00:00
Giovanni Bajo 2f27d00d60 n64: unbreak 64dd after recent changes
It got broken in the large refactoring in ad16c4a6
2023-02-08 17:48:33 +00:00
Adrian Siekierka c03099fa51 nall, sh2, n64: update to latest sljit 2023-02-07 21:26:32 +00:00
Luke Usher ba3b00cd05 Squashed 'thirdparty/sljit/' changes from 4b8798e4d2..4f7d8ec545
4f7d8ec545 Improve code generation on x86
09cad66bc0 Change tmp1 to ebx on x86-32
2de5e04919 Allow negated comparison
5040a3caa1 Test84 fix
1811f1dcea Rework sljit_emit_shift_into on s390x
ba08667852 Rework sljit_emit_shift_into on x86, arm, ppc, riscv, mips
95d2d320ed Add define for masked shifts
dc79333621 Implement fcopy on ppc, mips
c9e58a4806 Implement fcopy on s390x
03f68fea46 Implement fcopy on x86, arm, riscv
ac6c7b307f Implement byte reverse on ppc
f4d1b06e9d Implement byte reverse on s390x
5ed842e093 Implement byte reverse on x68, arm, mips, riscv
fba2206b40 freebsd: implement system specific execallocator (#155)
0a0ab41d03 test: update test15 for 4 arguments (#149)
1942237bda config: really improve autodetection for arm (#153)
7de0fee9a7 Move allocators to separate files (#151)
7de1a4356d On x86_32, check for virtual registers in conversions to and from floating point (#152)
c2f9c138a6 riscv: disable FPU when using soft-float ABI (#147)
3b89155a25 config: improve autodetection for ARM (#145)
0a313731b9 Implement new features on s390x
26213dadc4 Introduce op_dst
faecd2b12f Implement sljit_get_return_address
8b491d0ade Replace not with xor
88e0dcf360 Add allocator data getters

git-subtree-dir: thirdparty/sljit
git-subtree-split: 4f7d8ec545f58ebe93a08f137fcb9a6dd2bb170f
2023-02-07 21:25:29 +00:00
Luke Usher 9ccab8b676 Merge commit 'ba3b00cd057bbf4ecb1915aea6debde2461a5a6e' 2023-02-07 21:25:29 +00:00
Luke Usher 188bda9259 Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 4c3129f71a..3abd437761
3abd437761 Update to 7d75aa31e42da166a00604fdfcc29fa26bd3543c.
c6f79549e7 Update to 65f4f4da2ec11cf3485318dbb4ccd41d35d72a36.

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 3abd4377618cce89ad8aea524dc2f93a5d7637dd
2023-02-07 21:24:49 +00:00
Luke Usher d749af17db Merge commit '188bda9259346020e60d262eb5bd917cc694a5f0' 2023-02-07 21:24:49 +00:00
Adrian Siekierka 539cd5cc15 ws: implement PTS-0101 flash chip emulation 2023-02-05 22:31:08 +00:00
Adrian Siekierka 1ad25e180c ws: fix line compare interrupt not being emitted for line 0 2023-02-05 20:36:46 +00:00
invertego 5220b1483e sfc: fix debugger memory view for cx4, sa1, superfx 2023-02-04 12:30:27 +00:00
kev4cards 6869bbb971 n64: Do not use maximum dead-zone value in scaling
The maximum dead-zone value should be set to 0 like all other numbers in the dead-zone.
2023-02-04 08:18:45 +00:00
remutro 458e4f6ca5 Memory paks for N64 don't exist 2023-02-04 08:18:18 +00:00
Adrian Siekierka e9bcabf693 ws: fix IRQ, PPU timer emulation edge cases 2023-02-03 09:47:12 +00:00
remutro a1adfbba22 Misc fixes to N64 Mia DB 2023-02-03 09:47:01 +00:00
Giovanni Bajo 1d8dc20148 n64: unbreak isviewer after recent change
A few mistakes prevented ISViewer from working after ad16c4a67
2023-02-02 18:27:25 +00:00
Giovanni Bajo 7f9346e5ec n64: add approximate timings on PI and RCP reads 2023-02-01 08:21:27 +00:00
Giovanni Bajo ad16c4a67a n64: large refactoring to introduce timing in memory handlers
This very boring commit should basically produce no changes. It just
make sure all devices can now step the CPU while the I/O is in
progress, if needed.
2023-02-01 08:21:27 +00:00
Giovanni Bajo 21c985b3da n64: implement correct timing for SI (PIF) direct word writes 2023-02-01 08:21:27 +00:00
Giovanni Bajo cb01795df6 n64: initial estimation of PIF timings
Numbers are based on this test ROM:
https://github.com/rasky/n64-systembench

There are still many other cases to handle but this should provide
the initial framework for further experimentation with PIF timings.
2023-02-01 08:21:27 +00:00
FitzRoyX ec87c304fa Update presentation.cpp 2023-02-01 08:20:08 +00:00
FitzRoyX 8eb2ff3eab Update lspc.hpp 2023-02-01 08:20:08 +00:00
FitzRoyX de24f56cba Update lspc.cpp 2023-02-01 08:20:08 +00:00
FitzRoyX 90b0b19bf5 Update tia.cpp 2023-02-01 08:20:08 +00:00
FitzRoyX 142ae1be99 Update lspc.cpp 2023-02-01 08:20:08 +00:00
FitzRoyX e57c241424 Update presentation.cpp 2023-02-01 08:20:08 +00:00
FitzRoyX 1888b2934b Update presentation.hpp 2023-02-01 08:20:08 +00:00
FitzRoyX 3af6f1bf59 Update settings.hpp 2023-02-01 08:20:08 +00:00
FitzRoyX f088cfc31c Update settings.cpp 2023-02-01 08:20:08 +00:00
invertego 3eff1d2efb ruby: fix hang on loading rom from command line
Fix a regression introduced by my last change. The pattern of checking
ready() at the top doesn't work for clear() because it's called from
iniatialize(). This was obscured by the fact that other code calls
clear() again after initialization *unless* you are loading a ROM
directly from the command line.
2023-02-01 08:18:53 +00:00
invertego 88c347fdaa ruby: fix wasapi and xaudio2 crashes
The WASAPI driver should now gracefully handle machines that don't have
any available output devices. The XAudio2 driver probably still won't,
but more importantly it won't crash machines that don't have a specific
DirectX redist from 2008 (!). It needs a rework but for now I'm leaving
it a little better than I found it.
2023-01-28 23:45:24 +00:00
remutro 8f69189429 Fix save info for International Track & Field 2000 2023-01-28 23:44:51 +00:00
Luke Usher 95ed00c0d2 ng: implement mslugx protection asic 2023-01-27 14:56:38 +00:00
Luke Usher 463c52afe6 ng: add support for jockey-gp board type
The rom viewer debug window is a casualty of moving
to the board system, but as NES/Master System and
others with multiple board types don't have it,
it's not a big loss.
2023-01-27 13:27:31 +00:00
FitzRoyX e39a4d979d Update neo-geo-crypt.hpp 2023-01-27 10:09:55 +00:00
Luke Usher 6092f2bcff ng: coin inputs are active low 2023-01-26 13:44:05 +00:00
Luke Usher 7bafe50098 ng: fix unibios MVS/AES detection 2023-01-26 13:42:32 +00:00
Luke Usher fe50e29827 ng: fix horizontal scaling 2023-01-26 10:20:22 +00:00
Luke Usher d862eeaf79 mia: default neo-geo to english language bios + allow non-zipped bios
Allows for people to select a bios version manually if required (eg: unibios)
2023-01-25 21:44:24 +00:00
Luke Usher f08e7c66b3 ym2610: implement status/sample end registers and masking 2023-01-24 13:26:15 +00:00
Luke Usher 7d1d5d1e68 mia: fix case sensitivity in neo-geo rom loading 2023-01-23 12:12:50 +00:00
Luke Usher f333f28cea mia: add support for neo-cmc encryption (type 42 and type 50) 2023-01-23 10:09:12 +00:00
Luke Usher a370a0eb5a ares: use core-specific serializer version 2023-01-21 23:40:43 +00:00
Luke Usher 5018755374 ng: serialize sram 2023-01-21 23:33:01 +00:00
Luke Usher 3d4db007a9 ng: fix inverted dip switches (0 = on, 1 = off) 2023-01-21 23:32:50 +00:00
Luke Usher 706a5850a1 desktop-ui: show system name next to the game in "Recent Games" 2023-01-21 23:14:29 +00:00
Luke Usher 0a9a6b58c2 ng: add board type detection from feature flags 2023-01-21 22:54:06 +00:00
Luke Usher 0d588e0c0a mame2bml: support 'feature' tags 2023-01-21 22:47:18 +00:00
Luke Usher 9b74e87507 ng: support "fill" type loadflags
Fixes segfaults when loading Metal Slug 3 and others

Note that these games still won't boot due to missing protection
emulation.
2023-01-21 22:37:44 +00:00
Luke Usher 6b15519c9d mame2bml: support "fill" type loadflags 2023-01-21 22:31:40 +00:00
Luke Usher e655b3c096 ng: implement standard PROM bank switching 2023-01-21 22:05:32 +00:00
Luke Usher f3f1e4adcb ng: fix a (new) bug where voice-a rom was loaded instead of voice-b 2023-01-21 21:22:23 +00:00
Luke Usher 516c2c6eba mia: fix code comment 2023-01-21 21:21:39 +00:00
Luke Usher 131e353b9b ng: support loading mame format roms without guess-based heuristics
NOTE: This requires 'non merged' type roms, with all files related to
the game in a single zip file, ares does NOT resolve parent/child
relationships between roms.
2023-01-21 21:18:38 +00:00
Luke Usher 6d1a3a420c ng: fix an issue where sprite/fixed rom were swapped in the debug view 2023-01-21 20:44:00 +00:00
Luke Usher 7b1a58aa47 mame2bml: also convert load type flags 2023-01-20 21:44:03 +00:00
Luke Usher ef1f05848e mia: update neo geo database 2023-01-20 17:17:27 +00:00
Luke Usher 89718ab50a mame2bml: fix issue where invalid characters were inserted into node names 2023-01-20 17:16:28 +00:00
Luke Usher 21cf7c99bf mia: add initial Neo Geo rom database 2023-01-20 16:27:36 +00:00
Luke Usher dabc688b26 tools: add too lool to convert mame software lists from xml to bml
The use case here is quickly importing metadata about Neo Geo roms,
rather than hard-coding everything or using unreliable heuristics
2023-01-20 16:27:24 +00:00
Luke Usher ae179fef67 tools: move genius and sourcery to tools subdirectory 2023-01-20 14:55:04 +00:00
Luke Usher ec055dafcc scripts: add script to split nall/hiro/ruby/libco to their upstream repos
Assumes that the local environment has remotes set up for each library.
2023-01-20 13:42:13 +00:00
Luke Usher 8a71af4be1 n64: fix is-viewer debug output in commercial games + libdragon
This is a little bit hacky, because the debugging code in libdragon
is not compatible with actual IS-Viewer hardware, so we emulate
a 'quirky' version that satisfies both libraries.
2023-01-20 13:38:10 +00:00
invertego c47afd5c76 build: fix gcc-only fallthrough warnings 2023-01-17 11:16:42 +00:00
Luke Usher f037be9248 spec: preliminary ZX Spectrum core
This emulates the ZX Spectrum 48k and 128k models and should be fairly accurate
although imperfect; it is considered experimental for now. Save States are not
fully implemented, you may wish to avoid using them for this core.

No controller interface is currently exposed, meaning games must be played with
the keyboard at this time. It is planned to support the Kempston interface,
while supported by the underlying core, the UI interface for attaching expansion
port devices has not yet been implemented.

You must map a "Keyboard Capture" hotkey to allow ares to emulate the keyboard.

Ares maps most ZX Spectrum keys 1:1 with the same key on the host keyboard.
CAPS SHIFT is mapped to Left Shift, and Symbol shift is mapped to Left Control.

For special characters, it may be beneficial to look up the ZX Spectrum
keyboard layout. For the 48K it is necessary, as BASIC uses hot keys
rather than typed commands, for example, to load a game on the 48k,you must
type `J <symbol shift> PP` and then hit enter, which results in `LOAD ""`
being entered on the screen.

For the ZX Spectrum 128k, you can just use the Tape Loader menu option.

The emulator only implements support for raw WAV dumps right now; this is
because the TZX format is over-complicated, and I did wish to implement it at
this time.

There are many tools available for converting TZX to WAV, for all platforms,
so this isn't really seen as a blocking issue.
2023-01-15 22:32:31 +00:00
invertego 48fa446eeb gba: fix eeprom saves, fate willing 2023-01-08 17:55:41 +00:00
invertego 3fd666c583 Revert "gba: fix eeprom saves for real this time"
This reverts commit 972495df89.
2023-01-08 17:55:41 +00:00
invertego 9eb14aea6f nall: enable switch case fallthrough warnings
Enable these warnings in nall so they apply to all of ares and annotate
legitimate fallthrough with C++17 standard [[fallthrough]] attribute.
This type of mistake is just too easy to make.
2023-01-04 08:48:54 +00:00
invertego 3db5740bd3 mia: stop reporting famicom mapper 0 as unknown 2023-01-04 08:48:54 +00:00
invertego 3c226ed0ca ym2610, v9938: fix accidental switch case fallthrough 2023-01-04 08:48:54 +00:00
invertego 191393445e build: guard usage of sse4.1 round instructions
Guard usage of round_ss/sd intrinsics with a preprocessor check just as
we do with other SSE4.1 instructions.
2023-01-04 08:47:35 +00:00
remutro 621301990a Fix NeoGeo Save States 2023-01-03 08:12:53 +00:00
remutro d40b890d83 Add ability to set shader from command line 2023-01-02 09:37:28 +00:00
invertego 1891477e12 hiro: account for menu wrapping on Windows 2023-01-02 09:36:29 +00:00
Luke Usher 86207ff3a3 hiro: fix compilation with qt5 2023-01-02 08:42:45 +00:00
Adrian Siekierka 72956e4ba0 v30mz: fix disassembler adding CPU cycle overhead 2023-01-01 21:26:26 +00:00
Adrian Siekierka 1256987e9c ws: fix blocking APU writes to Color-mode only I/O ports in Mono mode 2023-01-01 10:44:44 +00:00
Adrian Siekierka 517dd3efc6 ws: return open bus for unavailable RAM in mono mode on WonderSwan Color 2023-01-01 10:44:44 +00:00
Adrian Siekierka 9176ed7418 v30mz, ws: implement SRAM/ROM waitstates 2023-01-01 10:44:44 +00:00
Adrian Siekierka 4f4ec10cdf ws: fix debugger cartridge ROM wait information 2023-01-01 10:44:44 +00:00
Adrian Siekierka 14db9f1ead v30mz: fix behaviour of undefined opcodes 0xC0F0, 0xC0F1, 0xFFF8 2023-01-01 10:44:44 +00:00
Adrian Siekierka 81be3393dc v30mz: fix JL/JGE emulation bug 2023-01-01 10:44:44 +00:00
Adrian Siekierka d15439a292 v30mz: fix AAA, AAS flags 2023-01-01 10:44:44 +00:00
Adrian Siekierka 7514b29e31 v30mz: fix DAA, DAS flags 2023-01-01 10:44:44 +00:00
Adrian Siekierka 0afef3389a v30mz: fix SAL, SAR, SHL, SHR flags 2023-01-01 10:44:44 +00:00
Adrian Siekierka 2dadc1e899 v30mz: fix RCL, RCR, ROL, ROR flags 2023-01-01 10:44:44 +00:00
Adrian Siekierka b07423749a v30mz: fix ADC, SBB, MUL, IMUL, AAD flags 2023-01-01 10:44:44 +00:00
Adrian Siekierka 1120921a1b v30mz: improve timing of two-register effective address calculation 2023-01-01 10:44:44 +00:00
Adrian Siekierka 9a826fd416 v30mz: fix undefined opcodes 0xD8-0xDF 2023-01-01 10:44:44 +00:00
Adrian Siekierka edd062c76f v30mz: fix opcode 0x0F, remove outdated/inaccurate comments 2023-01-01 10:44:44 +00:00
Adrian Siekierka 2429999b3c v30mz: implement BRK flag handling 2023-01-01 10:44:44 +00:00
Adrian Siekierka 8cb9a4a9c9 v30mz: more cycle-accurate memory fetching 2023-01-01 10:44:44 +00:00
Adrian Siekierka a2bd8a46f5 v30mz: fix opcode INTO implementation, implement distinct interrupt type timings 2023-01-01 10:44:44 +00:00
invertego 1dcaf2d2c1 fc: use database for unheadered roms 2023-01-01 10:43:31 +00:00
invertego e7f4d8cd2b fc: support ave nina-001 board
Add support for American Video Entertainment's NINA-001 board which was
used only by the unlicensed NES port of Impossible Mission II developed
by Novotrade.

iNES mapper 34 is assigned to two unrelated boards, so detection must
rely on the NES 2.0 header or use the CHR ROM size as a heuristic.
2022-12-31 09:44:08 +00:00
invertego 0ad3a7d8da fc: fix scanline check on ppudata access
Calculate the pre-render scanline from vlines() intead of hardcoding
the NTSC value. Also allow access on the post-render scanline (240).
2022-12-31 09:23:03 +00:00
Adrian Siekierka 92bf0c6669 v30mz: emulate PUSH SP bug 2022-12-28 01:33:01 +00:00
Luke Usher e536ff34a8 gb: expose color emulation options in the ui 2022-12-27 23:30:21 +00:00
Luke Usher 519423fa68 z80: oops 2022-12-27 23:30:21 +00:00
Adrian Siekierka 3f31de661d ws: accurate PPU OAM synchronization 2022-12-27 22:52:11 +00:00
Luke Usher 7c57dfa7bc z80: LD_rr_inn should set WZ to addr + 1 2022-12-27 22:37:41 +00:00
Luke Usher 3b7e0d440b bump version to v131 2022-12-27 20:02:27 +00:00
Adrian Siekierka 1e97bd6a8b ws: fix interrupt base handling on WSC, add missing cartridge/interrupt debugger properties 2022-12-27 18:41:11 +00:00
Adrian Siekierka 4b43bbf853 v30mz: fix opcode 0xF7:1 to match hardware 2022-12-27 18:41:11 +00:00
Adrian Siekierka b2a240b335 v30mz: fix opcode 0xD6 implementation 2022-12-27 18:41:11 +00:00
Adrian Siekierka 709afef820 ws: clean up level-triggered interrupt code, more accurate keypad interrupt logic 2022-12-27 18:41:11 +00:00
Adrian Siekierka 6b70091f6c ws: support pixel inaccuracy mode, for per-scanline PPU and fast APU processing - ~65% speedup on my machine 2022-12-27 18:41:11 +00:00
Adrian Siekierka 7a71b7e98f apu: more accurate timing model 2022-12-27 18:41:11 +00:00
Adrian Siekierka 7b9d8e9232 ws: add missing apu clock serialization 2022-12-27 18:41:11 +00:00
Adrian Siekierka de219e37e8 ws: expose headphone/speaker toggle 2022-12-27 18:41:11 +00:00
Adrian Siekierka 052f486793 ws: fix ppu timer behaviour on reload=1 to match hardware, add ppu timers to debugger properties 2022-12-27 18:41:11 +00:00
Adrian Siekierka 0b3f87c97d ws: fix screen regression from debugger change 2022-12-27 18:41:11 +00:00
Adrian Siekierka 35b5a4cf0a v30mz: disassembler: fix IN/OUT immediate 2022-12-27 18:41:11 +00:00
Adrian Siekierka 669fb4a433 v30mz: fix timing of opcodes 0x63-0x67, IMUL, POLL, INS, OUTS 2022-12-27 18:41:11 +00:00
Adrian Siekierka 418666dd20 ws: add serial, SoC/CPU debug properties 2022-12-27 18:41:11 +00:00
Adrian Siekierka e44cf2e956 ws: add apu, cartridge debugger properties 2022-12-27 18:41:11 +00:00
Adrian Siekierka a421550477 ws: add PPU screen1/screen2 layer support to debugger, fix 4bpp packed tiles view 2022-12-27 18:41:11 +00:00
Adrian Siekierka 1474f1001d ws: add PPU tiles to graphics debugger 2022-12-27 18:41:11 +00:00
Adrian Siekierka 3d2f8e0633 ws: minor apu hotfix 2022-12-27 18:41:11 +00:00
Adrian Siekierka dcbce15b24 ws: serial fixes 2022-12-27 18:41:11 +00:00
Adrian Siekierka 08c75e6e55 ws: appropriately gate WSC-mode-specific registers 2022-12-27 18:41:11 +00:00
Adrian Siekierka 018e07945a ws: stub serial implementation with interrupt/flag support 2022-12-27 18:41:11 +00:00
Adrian Siekierka 0355ef08ed ws: apu improvements - properly emit 24000 Hz digital samples, fix headphone output, fix channel 2 "half volume" flag 2022-12-27 18:41:11 +00:00
Adrian Siekierka c95a27d66a ws: support setting NMI register 0xB7 (no implementation), more accurate Bandai 2003 mapper emulation (>16MB ROM support) 2022-12-27 18:41:11 +00:00
Adrian Siekierka a46ab04e47 gb: fix MBC1 mapper style 2022-12-27 18:32:59 +00:00
Adrian Siekierka b8f6aeb52c gb: fix MBC1 mapper implementation for 8/16Mbit cartridges 2022-12-27 18:32:59 +00:00
invertego d46f7a3445 ares: fix console build option on Windows
The -mconsole and -mwindows flags don't seem to do much of anything when
Clang isn't targeting MinGW. On the other hand, directly overriding the
subsystem with a linker flag results in a bunch of unresolved symbols.
However, if the right entry point exists (either WinMain or main),
some apparent magic goes on under the hood to ensure that everything
links as expected, so we can just take advantage of that.
2022-12-21 07:52:37 +00:00
Giovanni Bajo 4524f9d188 n64: fix 32bit / 64bit address space confusion
context.physMask is only used for TLBs. In directly-mapped memory
segments (either cached or uncached), the virtual-to-physical conversion
uses a hardcoded mask that depends on the exact address space segment,
and is not contextful. In 32-bit, segments only use 29 bits of the
virtual address. In 64-bit, some segments (xkphys*) use the full 32 bits.

Besides 64-bit direct-mapped segments correctness, this also fixes
the devirtualize function that is used as part of the CACHE/LL/SC
opcodes, which were misbehaving when used with a uncached segment
(0xa000'0000) in 32-bit mode. This might actually affect also games.
2022-12-20 14:35:54 +00:00
invertego 67d1647d6e build: prefer clang on all platforms
Use clang++ if it exists on the path, otherwise fall back to g++.
2022-12-20 14:35:41 +00:00
invertego 619415d7dc normalize whitespace
Replace tabs with spaces and CRLF newlines with LF.
2022-12-20 09:22:06 +00:00
invertego 2daf9f5908 nall: define _WIN32_WINNT in makefile
We build third party dependencies that do not include nall, so defining
the target Windows version (currently Win7) in a header is unreliable.
2022-12-19 20:06:34 +00:00
Luke Usher 68fe9514bf ci: fix packaging of new msvc zips 2022-12-19 16:23:21 +00:00
Luke Usher 67a9b0ec1a ci: publish msvc compiled artifacts 2022-12-19 15:39:57 +00:00
invertego 0d02303de6 ci: add Clang + MSVC builds 2022-12-19 15:35:57 +00:00
invertego 91d4fb70ec build: support Clang + MSVC/WinSDK libraries
This change makes it possible to build ares using Clang without
MinGW-w64. All that is required is a copy of Visual Studio (or Build
Tools for Visual Studio) and Clang (also available through the VS
installer) along with GNU Make.

To build, just open an x64 Native Tools command prompt and run
`make compiler=clang++` as usual.
2022-12-19 15:35:57 +00:00
invertego 90af756e3c thirdparty: add glext.h and khrplatform.h
Unlike gl.h, these aren't distributed with the Windows SDK.

https://github.com/KhronosGroup/OpenGL-Registry
https://github.com/KhronosGroup/EGL-Registry
2022-12-19 15:35:57 +00:00
invertego e1e11cf75e nall: split implementation into .cpp files
Begin the process of splitting nall into separate translation units.
It can now be used in two ways:

1) as a header-only library by defining NALL_HEADER_ONLY
2) by compiling nall/nall.cpp

sourcery has been updated to demonstrate the header-only use and
everything else now builds nall.cpp.

So far the only things moved into .cpp files are implementations that
call Windows APIs. This allows most of ares to build without including
windows.h and enables the removal of the abomination that was
windows/guard.hpp. The things that actually need windows.h (hiro, ruby)
must avoid using names reserved by Windows headers, but the rest of ares
is free to use names like "far", "boolean", and "interface" with
reckless abandon.

This work is done in preparation for building against MSVC and Windows
SDK headers/libraries an an alternative to MinGW-w64.
2022-12-18 09:18:52 +00:00
invertego 8f60efcb20 nall: move lowercase primitive types to namespace
Avoid conflicts with the "boolean" type added to the global namespace by
Windows headers.
2022-12-18 09:18:52 +00:00
invertego 5ff724427a huc6280: adc/sbc decimal mode fixes
This only impacts cases with inputs that are not valid BCD. This change
was verified against hardware test roms in the Mednafen repo.
2022-12-15 23:02:48 +00:00
Luke Usher c60f91e5d5 gb: fix secondary obj palettes in dmg mode on a gbc 2022-12-14 23:46:10 +00:00
invertego b6919cd118 6502: fix adc/sbc flags in decimal mode 2022-12-14 18:57:32 +00:00
Luke Usher 1294fdb679 md: fix template naming conflicts 2022-12-12 23:20:36 +00:00
Luke Usher d4b67a92d2 hiro: store windows settings in app directory, making ares truely portable 2022-12-12 22:18:05 +00:00
Luke Usher b442ef4624 md: use templating to reduce if statements in tight inner loops
This boosts performance enough to get 80-90fps in 32X doom on my machine.
2022-12-12 21:56:20 +00:00
Luke Usher 4da6316d1d desktop-ui: make LTO default again
I know we play with this a lot; but it is the difference between barely scraping 50-55fps on 32x core to getting constant 60-70fps on my machine.

This does increase compilation time with GCC, clang fares a lot better.
2022-12-12 21:52:13 +00:00
Luke Usher 27bc5bc2bf md: reduce sync between components
Since the cpu does a full system sync on each clock cycle, there's no need to do the extra work per-component here.
2022-12-11 15:51:16 +00:00
Luke Usher 3051af6e21 md: make sure bus functions are always inlined as intended 2022-12-09 22:45:03 +00:00
Giovanni Bajo 489ac87a1c Squashed 'ares/n64/vulkan/parallel-rdp/' changes from fc3121239..4c3129f71
4c3129f71 Add missing files.
a2037e284 Update to 95b1176f929570996a4c8fa41934095f14103d32.

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 4c3129f71a5d9c8865bf7aa3365ccccdcb083a9d
2022-12-08 00:41:14 +01:00
Giovanni Bajo ecb8d30b69 Merge commit '489ac87a1cbd75e44e48f15f362eafdd6f52f3bc' into n64_load_block_limit 2022-12-08 00:41:14 +01:00
Giovanni Bajo adacb0be02 n64: implement hardware limit of LOAD_BLOCK RDP command (mame RDP)
This is a documented limit of the hardware that I have personally
re-verified on real hardware. The same bug exists in parallel-RDP.
2022-12-07 11:26:17 +01:00
Giovanni Bajo 29cdd17113 nall: use snprintf to avoid warnings 2022-12-07 11:25:28 +01:00
invertego 5866a1b9f1 recompiler: implement masked shifts 2022-12-06 03:34:24 +00:00
invertego 5e8277b290 recompiler: implement bit rotates 2022-12-06 03:34:24 +00:00
Luke Usher a1bd8e63eb ps1: reduce pause command duration 2022-12-03 21:08:08 +00:00
Luke Usher 265ba002e6 fc: merge apu/cpu/cartridge into one cothread
This brings a significant performance increase to the NES/FC core with no accuracy or maintainability impact;

This is possible only because they share the same base clock, and always step at the same rate.
2022-12-03 19:18:20 +00:00
Luke Usher 88879890fb Squashed 'thirdparty/libchdr/' changes from e02b3d68eb..a20e04c12c
a20e04c12c Merge pull request #88 from irixxxx/master
04d631b0de fix double file close if opening failed
10938cbd97 Merge pull request #87 from mjunix/patch-1
b25a4c36aa Fix potential NULL dereference
50f58600ec Merge pull request #86 from jpd002/fseek_int64
678434c447 Fix fseek offset type.
464044e6cc Merge pull request #85 from scribam/patch-1
89338e7840 cmake: fix compilation with bundled zlib

git-subtree-dir: thirdparty/libchdr
git-subtree-split: a20e04c12c0c20048bf771da6df7aa2e51f5e0cb
2022-12-02 16:29:45 +00:00
Luke Usher af3e42515c Merge commit '88879890fb343037e38938b8ce2e6228418ea86d' 2022-12-02 16:29:45 +00:00
Luke Usher 8ed3b44f0b Squashed 'thirdparty/sljit/' changes from 4de967acd0..4b8798e4d2
4b8798e4d2 config: simplify use of external allocator (#143)
d598b86d81 Add tcc to the list of compilers using AT&T syntax (#142)
c8e664c73b Fix x86 inline asm register clobbers (#141)
b65c854289 Add conditional exit for clz/ctz on riscv, mips
f55425dac8 riscv: typo in detect_jump_type (#140)
0148e65576 Implement ctz and improve clz on riscv, mips
e8eb434b2e Implement ctz on s390x
51d3c96183 arm: add missing check sljit_emit_mem_update in aarch64 (#139)
cd2a31e199 Implement ctz on x86, arm, and ppc
c0286016cf Improve rotate on mips, riscv
fded9f7823 Implement rotate on s390x
35764edc9e Implement rotate on mips, riscv
ea49b3f52e Implement rotate on x86, arm, and ppc
da180ae7e1 Implement sljit_emit_shift_into on s390x
05f5980620 Implement sljit_emit_shift_into on ppc, mips, riscv
84c0bc3614 Implement sljit_emit_shift_into on x86 and arm
8da3b39558 Label odd numbered tests (#134)
06e13ac7cc Label even numbered tests (#133)
1501371fad Split emit_mem to emit_mem and emit_mem_update
89965887cc Implement return_to on mips, ppc, riscv
e21f485cb4 Implement return_to on s390x
a122423a40 Implement return_to on x86, ARM
4672d4f6cb Improve cmov on s390x
06e9864247 Change SLJIT_32 flag passing to cmov
29af0267ce Update documentation
190313fcc2 Fix spelling of 'subtract' (#132)
4325440b0b Support floating point return
ba0f935c9a Implement recent features on s390x
12e6cb055b Implement always masked shift
f22f976060 Support memory moving of register pairs on riscv, mips, and ppc

git-subtree-dir: thirdparty/sljit
git-subtree-split: 4b8798e4d2fe8f8e8fb82b28e2dda9d71a00b27f
2022-12-02 16:29:39 +00:00
Luke Usher 9c53d97491 Merge commit '8ed3b44f0bd1e872d5e02cb106da30d732549e5d' 2022-12-02 16:29:39 +00:00
Lior Halphon 6415c3a853 Prevent AppKit from handling file opens, fixes #665 2022-12-02 13:17:18 +00:00
Adrian Siekierka 09aa6346c7 v30mz, ws: emulation fixes
* The NEC V30MZ does not ignore the immediate operand in AAD/AAM calls.
  This is contrary to NEC V20/V30 behaviour, as well as many existing
  emulators. It is, broadly speaking, important to remember that the
  V30MZ is much closer to "an 80186-compatible CPU with much better
  opcode timings" than "a V20/V30 derivative". A test ROM is provided
  for this.
* The sprite base location register's access to 0x4000-0x7FFF memory
  is gated by the color mode bit, not by the 4bpp mode bit. A test
  ROM is provided for this.
* The PPU can address 1024 tiles in 2bpp color mode, simply by
  following the consecutive addresses (so 0x2000-0x5FFF total). This
  has been verified independently.
* The planar(), packed(), depth() and grayscale() functions have been
  reworked to accurately reflect what the hardware does. This has been
  verified independently.
2022-11-23 08:13:26 +00:00
Luke Usher 98ea150bce ci: remove libgtksourceview2.0-dev
This is no longer present in ubuntu 22.04.
2022-11-23 08:12:16 +00:00
Giovanni Bajo d1847c9cd3 n64: improve behavior in case of RDP crash
We want to make sure to really stop processing other commands
afterwards. Tested now with both parallelRDP and mameRDP.
2022-11-21 09:39:14 +00:00
Giovanni Bajo 9c9d7d4bf3 n64: implement correct PI openbus behavior
This is correct for direct I/O only, not for DMA. Better than nothing.
2022-11-21 09:39:14 +00:00
Giovanni Bajo 48454fe53a n64: add PC address to FPU exception logs 2022-11-21 09:39:14 +00:00
encoded-byte 6d17f38be4 fc: shift apu triangle sequence
First step is step 16 in that sequence
2022-11-21 09:38:58 +00:00
encoded-byte 9819f2f967 fc: boots audio output levels 2022-11-21 09:38:58 +00:00
invertego 3088c4942c desktop-ui: enable debugging self-signed builds on macOS
The get-task-allow entitlement is required to enable attaching a
debugger to a hardened runtime process.
2022-11-20 11:59:39 +00:00
invertego 353272a1db desktop-ui: bind analog inputs only on motion away from center
Currently, analog inputs are bound when crossing the threshold in either
direction halfway between zero and full positive/negative. This logic
doesn't work for triggers that are mapped to the full range of an axis
(as opposed to half the range) which makes them impossible to bind
correctly unless they are initially half pulled when pressing the assign
button. I'm not convinced there is much utility in binding any axis on
motion toward the center position, so this change triggers binding only
on motion away from the center.
2022-11-20 11:59:17 +00:00
invertego f42258bf9f n64: fix analog stick inputs on arm64
Converting a negative floating-point value to an unsigned integer is
undefined behavior and just happens to do the desired thing when
compiling for x86-64. Convert to a signed integer first to avoid UB and
guarantee the expected result on arm64.
2022-11-20 11:59:17 +00:00
invertego 6bd57e790e recompiler: simplify carry flag usage
Using the host carry flag is a bit tricky because on ARM64 (and most
other non-x86 architectures) the meaning of the flag is inverted for
subtraction. There were some helpers in the recompiler to deal with this
but they performed explicit architecture checks which ran counter to the
goals of a generic recompiler.

Reading back the carry flag is now handled directly by sljit. This
feature had been removed from sljit but was recently added back. It
internally tracks whether the setting operation was an add or a subtract
so that x86 semantics are observed on all architectures.

Loading the carry flag is now handled with an explicit add or subtract
that matches the subsequent usage. This results in expected behavior on
all architectures.
2022-11-15 16:06:55 +00:00
invertego 7ea6cf76e4 build: add mame rgb utils for all architectures
Pull in the files necessary to build MAME RDP for any architecture.
2022-11-15 16:06:55 +00:00
invertego 50dd52bb47 build: guard SSE usage with preprocessor
Reinstate preprocessor guards for SSE code. Constexpr if statements
don't really work because the compiler still requires declarations for
the SSE types and intrinsics even if the body is ultimately discarded.
2022-11-15 16:06:55 +00:00
invertego baccd50410 libco: fix powerpc64 LTO build 2022-11-15 16:06:55 +00:00
invertego e3323e248f nall: detect powerpc64 target 2022-11-15 16:06:55 +00:00
Derek "Turtle" Roe 1622ac00a5 Move Star Fox EX to an unlicensed section 2022-11-11 08:08:58 +00:00
Derek "Turtle" Roe 03462690b1 Update Super Famicom.bml
Add Star Fox EX to the Super Famicom database
2022-11-11 08:08:58 +00:00
Luke Usher 69e5025e7a desktop-ui: implement reload game hotkey/menu option 2022-11-08 13:18:53 +00:00
Luke Usher aa9abd7f68 fc: boost apu output 2022-11-05 22:53:43 +00:00
Luke Usher cc792b71fe desktop-ui: move audio driver/device settings onto a new line
prevents overflowing the window with large device names
2022-11-05 18:19:23 +00:00
encoded-byte 98ccd3c31f fc: namco163 expansion audio 2022-11-03 15:12:04 +00:00
Giovanni Bajo 98bd18757b n64: do not clear FPU flags on LWC1/LDC1/SWC1/SDC1
This commit fixes the remaining failing tests in n64-systemtest.
2022-10-31 07:22:30 +00:00
invertego 4fe7c7d82d n64: replace lround -> round and lrint -> rint
When building with clang for ARM64, the cmath round functions that
return floats compile to a single FRINT instruction. The ones that
return ints are provided by the C runtime, which is problematic on
Windows because the mingw implementations don't set the desired
status bits.
2022-10-30 21:38:48 +00:00
invertego 4e36ce7ad5 n64: raise unimpl instead of invalid for fpu conversions 2022-10-30 21:38:48 +00:00
Giovanni Bajo ba862a2508 n64: FMOVs do not clear flags 2022-10-30 21:38:48 +00:00
Giovanni Bajo fc425940b6 n64: fix conversion bounds off by ones in FPU 2022-10-30 21:38:48 +00:00
encoded-byte c756ae6ea3 fc: increment scanline before comparing on mmc5 2022-10-24 09:31:18 +01:00
encoded-byte 22e71d1d21 fc: correct mmc5 scanline detection behavior 2022-10-24 09:31:18 +01:00
invertego feff5bf56c build: add windows arm64 CI build
Two things are making this a bit more complicated than it ought to be:
- The msys2 clangarm64 package repository is not enabled by default
  because it is still considered 'experimental'
- Cross-compiling requires that you manually override the runtime
  library directory for the 'builtins' lib to be located

Both of these issues are known and should be addressed eventually.
2022-10-21 09:32:44 +01:00
invertego bcb7713415 thirdparty: update sse2neon.h (2b8615319) 2022-10-21 09:32:44 +01:00
invertego 9b1648f6b2 build: pick up windres from environment if defined 2022-10-21 09:32:44 +01:00
Giovanni Bajo f1df1db489 n64: remove spurious round mode change in FPU implementation on arm64 2022-10-19 09:21:04 +01:00
invertego 94764b7fd7 n64: improve unimplemented exceptions on underflow 2022-10-19 09:21:04 +01:00
invertego fbc921ade9 n64: replace cmath functions with arch-specific intrinsics
We cannot rely on specific status flags being set by C standard math
functions.
2022-10-19 09:21:04 +01:00
invertego 6bff023264 n64: prevent compiler reordering with noinline lambda 2022-10-19 09:21:04 +01:00
Giovanni Bajo ac005568be n64: implement correct denormal flush (depending on rounding mode) 2022-10-19 09:21:04 +01:00
Giovanni Bajo 299f25b8d1 n64: correct denormals handling in FCTV_S_D 2022-10-19 09:21:04 +01:00
Giovanni Bajo 0d73fb47d6 n64: reset fpu cause bits for every FPU operation 2022-10-19 09:21:04 +01:00
Giovanni Bajo c0d96da45a n64: add DCTC1/DCTFC1 2022-10-19 09:21:04 +01:00
Giovanni Bajo 0f50ac2810 n64: fix FPU round-to-even using intrinsics 2022-10-19 09:21:04 +01:00
Giovanni Bajo 1c169602dc n64: fix correct roundings and flags for conversion functions 2022-10-19 09:21:04 +01:00
Giovanni Bajo 9e8255d213 n64: implement FPU flags/exceptions for FCVT_* 2022-10-19 09:21:04 +01:00
Giovanni Bajo 9151cf66fc n64: trigger FPU exceptions also via CTC1 2022-10-19 09:21:04 +01:00
Giovanni Bajo 494068fd9d n64: improve generation of FPU flags/exceptions for comparisons 2022-10-19 09:21:04 +01:00
Giovanni Bajo bd65032a88 n64: improve generations of FPU flags/exceptions 2022-10-19 09:21:04 +01:00
encoded-byte d973a52e99 fc: don't reset scanline on nmi 2022-10-18 07:37:42 +01:00
encoded-byte 726ca11ea3 fc: fix mmc5 expansion sound 2022-10-18 07:37:42 +01:00
encoded-byte 3049510000 mia: updated fc mapper 5 default 2022-10-16 21:22:15 +01:00
encoded-byte 84cd3ccd46 fc: code refactoring 2022-10-16 21:22:15 +01:00
encoded-byte 927b9f16aa fc: fix ram banking on mmc5 2022-10-16 21:22:15 +01:00
TascoDLX 0b739bfd36 ares: bump serializer version to 130.3 2022-10-16 15:01:39 +01:00
TascoDLX b49dd6a4ca md: fix cart rom banking (support rom up to 32MB) 2022-10-16 15:01:39 +01:00
TascoDLX c0e8b64b68 m32x: fix rle render 2022-10-16 15:01:39 +01:00
TascoDLX bcfcbd6735 m32x: implement dreq1 & fix irq for pwm 2022-10-16 15:01:39 +01:00
TascoDLX 92424dc97d m32x: fix pwm fifo 2022-10-16 15:01:39 +01:00
Giovanni Bajo e73ec4cac9 n64: emulate VI guardband
There's a "hardware bug" in VI that hides 8 pixels on beginning/end
of each scanline if the scanout begins within the active area.
It is emulated by parallel-RDP but not by our VI implementation.

In a CRT, this is all within the border so it's not visible, and most
games will also respect an even smaller "safe area" anyway. It becomes
visible once the horizontal scanout start is pushed right into the
central area of the screen.
2022-10-12 09:07:32 +01:00
invertego 480343bb98 ares: bump serializer version to 130.2 2022-10-12 09:07:00 +01:00
invertego 477e4c6f12 ms: serialize cartridge ram 2022-10-12 09:07:00 +01:00
Giovanni Bajo 40b8728b1f Avoid codesigning/notarization when building from PRs 2022-10-12 09:04:37 +01:00
Giovanni Bajo 2db3a09162 n64: fix 1-bit precision error in mame RDP
This is another regression introduced to mame RDP wrt upstream
angrylion and parallel-RDP. The color combiner slot "ONE" should use
the value 0x100 for the color components, not 0xff. Notice that
"ONE" in the blender is indeed 0xFF, instead.
2022-10-12 09:04:31 +01:00
invertego ed43ab72b2 nall: fix various hashset issues
- Fix copy assignment operator
- Prevent reserve() from reallocating/rehashing unless capacity is increasing
- Prevent insert() from inserting duplicate entries
- Disable remove() as needs some work and is currently unused
2022-10-09 22:54:33 +01:00
invertego f1b7eb0589 debugger: use hashset to track visited addresses
The "mask" feature in the instruction tracer broke when the N64 address
space was increased to 64 bits. This change fixes it by switching from a
vector to a hashset for tracking visited addresses.
2022-10-09 21:49:23 +01:00
invertego 148eac9346 debugger: store 64-bit address in trace history 2022-10-09 21:49:23 +01:00
invertego 5a58ebdad6 debugger: set per-processor trace history depth
The instruction tracer's default history depth (4) is much too low to
reliably filter out hot loops in processors clocked above a few
megahertz.

Assuming a correlation between processor speed and the path length of
code written for that processor, this change sets the history depth to
the processor's clock speed in megahertz rounded to the nearest power of
two.

This choice is arbitrary, but in practice I've nearly always had to
manually adjust the trace depth to values in the 16-64 range when
dealing with faster processors, so this seems like a good enough
heuristic.
2022-10-09 21:49:23 +01:00
encoded-byte 45667df0f1 fc: fix mmc5 compilation 2022-10-09 21:49:16 +01:00
encoded-byte 817317c5b3 mia: updated famicom database 2022-10-09 21:49:16 +01:00
encoded-byte f3cc8ff52f fc: mmc5 ram management 2022-10-09 21:49:16 +01:00
encoded-byte 6986881a94 fc: improve mmc5 frame detection 2022-10-09 21:49:16 +01:00
invertego 4e4c50be19 gb: fix rtc emulation
- Detect RTC with MBC30 mapper (Pocket Monsters - Crystal Version)
- Read current time before saving it to disk, not after
- Don't clear RTC in power()
2022-10-07 08:30:39 +01:00
Luke Usher f757d496ce Update game-issue-report.md 2022-10-05 09:23:32 +01:00
Luke Usher ef62807b77 a26: fix pixel aspect ratio 2022-10-04 21:44:39 +01:00
PikaSamus 7c17727d1a Correct Game Gear PAR again 2022-10-04 16:00:01 +01:00
PikaSamus 22f2d060d1 Correct Game Gear PAR to 8:7 2022-10-04 16:00:01 +01:00
PikaSamus faf195eba7 Correct ColecoVision PAR to 8:7 2022-10-04 16:00:01 +01:00
PikaSamus 6d22c9e368 Change MSX PAR to 8:7 2022-10-04 16:00:01 +01:00
Luke Usher 97cd14960f ares: release v130.1 (hotfix) 2022-10-03 18:45:51 +01:00
Giovanni Bajo 543111c151 n64: handle vstart/vend RDP coordinate wraparound
Fix Perfect Dark copyright screen in mame RDP. parallel-RDP has the
same bug, but requires a separate fix (to be sent upstream).
2022-10-03 15:49:40 +01:00
Luke Usher 66b60d67d1 recompiler: further tweaks for Intel macOS 2022-10-03 14:24:33 +01:00
Luke Usher 3c99afc0c0 nall: use MAP_JIT on Intel macOS 2022-10-02 23:29:46 +01:00
invertego acc4597407 ruby: improve downscaling with gdi
GDI's default mode of operation for downscaling is optimized for
monochrome images (!) and produces strange artifacts on color images.
This change selects the GDI mode that is essentially nearest-neighbor,
which is not great but is at parity with how it does upscaling.
2022-10-02 22:08:36 +01:00
Luke Usher 19593e157f build: fix broken package detection after the switch to pkg-config 2022-10-02 21:57:40 +01:00
Luke Usher 0c917f3803 ng: read hshrink after sticky-bit parsing 2022-09-30 21:09:48 +01:00
Luke Usher 86db200a23 ares: update version number to v130 2022-09-30 16:09:39 +01:00
Luke Usher 2781365ac3 LICENSE: add MoltenVK license text 2022-09-30 15:57:45 +01:00
Giovanni Bajo a238a7e754 ci: cache MoltenVK builds to speed up CI 2022-09-30 15:12:35 +01:00
Giovanni Bajo 299d211ab1 ci: add signing on Windows 2022-09-30 15:12:35 +01:00
Giovanni Bajo fc2278486e ci: reactivate moltenvk build 2022-09-29 23:12:43 +01:00
Giovanni Bajo f7d5a87667 ci: add macOS notarization 2022-09-29 22:52:27 +01:00
Giovanni Bajo 3e2934529e desktop-ui: fix ares.plist by specifying the package type 2022-09-29 22:52:27 +01:00
Luke Usher ff9afca894 mia: GTROM has 16k chr-ram 2022-09-29 19:42:25 +01:00
Giovanni Bajo 3f002928ed n64: in vulkan backend, fix DP_START.
DP_START shouldn't change after a RDP DMA transfer. This was correct
in the mame-RDP backend but it was wrong in the Vulkan backend.
2022-09-29 14:07:11 +01:00
Giovanni Bajo b124e8a8f0 n64: fix option name in settings change 2022-09-29 14:07:11 +01:00
TascoDLX 0f965050b1 md: support Triple Play cart mappers 2022-09-29 08:24:53 +01:00
Luke Usher b9cd02ddee ng: fix loading of roms with different v-rom naming, fixes aof.
Note that this will cause ADPCM-B roms to be appended to ADPCM-A roms,
 but it's the best we can do without a game database with per-game mappings.
2022-09-28 22:56:03 +01:00
Luke Usher b7198a2334 ng: fix ADPCM-B serialization 2022-09-28 22:48:37 +01:00
Luke Usher 8967e05524 ng: allow ADPCM-B samples to be silenced early 2022-09-28 22:45:33 +01:00
Luke Usher 1b1e7f8f2c ng: implement ADPCM-B audio 2022-09-28 22:45:33 +01:00
TascoDLX 00eb27681e m32x-cd: workaround for Corpse Killer 32X CD gamepad bug 2022-09-28 09:17:48 +01:00
TascoDLX 9ad4b27681 md: add eeprom support for Wonder Boy V (J) 2022-09-28 09:17:48 +01:00
TascoDLX 060eaba2ea sh2: (sh7604) fix serial comm 2022-09-28 09:17:48 +01:00
TascoDLX d75a495fc1 m32x: clear adapter control reg unused bits 2022-09-28 09:17:48 +01:00
Luke Usher f593b12416 ci: switch exclusively to clang for windows builds 2022-09-27 22:24:10 +01:00
Luke Usher 2f3385776d a26: increase scale factor for consistency with other cores 2022-09-27 14:12:05 +01:00
Luke Usher fe8afe05de mia: auto-detect and load common msu-1 filename schemes 2022-09-27 11:57:13 +01:00
Luke Usher 3545360033 Squashed 'thirdparty/libchdr/' changes from b3c1651d0f..e02b3d68eb
e02b3d68eb Merge pull request #84 from scribam/dr_flac
146f076ca7 dr_flac: Version 0.12.39
9882eeaaa2 Bump dr_flac to latest, bump libchdr version to 0.2
44c91c96d4 Bump LZMA SDK to 22.01, need to implement asm optimizations
8cd08c0752 Upgrade to zlib 1.2.12
2781322c4a Merge pull request #78 from snickerbockers/virtual_core_file
40ec221c8a use virtual file i/o API which defaults to a stdio wrapper

git-subtree-dir: thirdparty/libchdr
git-subtree-split: e02b3d68eb759793ab8142376594c840c1194b3e
2022-09-26 18:23:51 +01:00
Luke Usher bd9f52cf8c Merge commit '35453600333f47f6173bf43228e8bc01c2df5a6e' 2022-09-26 18:23:51 +01:00
Luke Usher 3d3513e365 Squashed 'thirdparty/sljit/' changes from 7c37b7ebcf..4de967acd0
4de967acd0 Support memory moving of register pairs on x86 and arm.

git-subtree-dir: thirdparty/sljit
git-subtree-split: 4de967acd03499e7def404eab861e83a0689579b
2022-09-26 18:23:47 +01:00
Luke Usher 5c61c3acbd Merge commit '3d3513e365437e5b16d6c015f55d79d0d2eb2def' 2022-09-26 18:23:47 +01:00
Luke Usher 6a0f2eaf1a ng: tweak overscan 2022-09-26 15:23:12 +01:00
Luke Usher 9422ea5905 md: implement 32x reset register and remove adapterEnable hack 2022-09-26 15:01:30 +01:00
invertego 582fc8f846 sh2: store correct pc in exception frame
The value of PC indicates the fourth byte (second instruction) after the
current instruction. The value stored when an exception raised does not
maintain this four byte offset. Consequently, the RTE instruction must
offset the value it reads back by four bytes.

ares was storing the offset value (and not applying one in RTE) and this
went unnoticed until an encounter with code that manually sets up an
exception frame (in an interrupt handler common to CD 32X games).

This change also fixes the PC stored in the event of an illegal slot
exception, which should be the delayed branch target.
2022-09-26 10:34:27 +01:00
Giovanni Bajo 73893352f7 desktop-ui: show status messages on console too 2022-09-26 00:43:45 +01:00
Giovanni Bajo 47c9ec1f80 desktop-ui: add entitlement to allow JIT as a signed application on mac
Also disable library validation to allow MoltenVK to load. It seems
this is required even if the library is signed. This requires more
investigation.
2022-09-26 00:43:45 +01:00
Giovanni Bajo b482344691 Build universal macOS app on CI 2022-09-26 00:43:45 +01:00
Giovanni Bajo cbdedc9f9c Move update-subtrees.sh into scripts subdirectory 2022-09-26 00:43:45 +01:00
Giovanni Bajo 12a1585ee2 Add script to build an universal binary on mac 2022-09-26 00:43:45 +01:00
Giovanni Bajo 4644bb4494 nall: allow cross-compilation on macOS 2022-09-26 00:43:45 +01:00
Giovanni Bajo a54b551e4d desktop-ui: activate Vulkan by default on all platforms 2022-09-26 00:43:45 +01:00
Giovanni Bajo 30724164be Build MoltenVK on mac builders 2022-09-26 00:43:45 +01:00
Giovanni Bajo 517e0cc454 desktop-ui: mention "GPU acceleration" rather than Vulkan 2022-09-26 00:43:45 +01:00
Giovanni Bajo 2c489cdadd desktop-ui: allow building and bundling libMoltenVK on mac
build
2022-09-26 00:43:45 +01:00
invertego 28a956111d build: ignore -Wdeprecated-non-prototype in zlib 2022-09-25 23:04:25 +01:00
Luke Usher 7115ed9ab5 ng: clip overscan
this will be improved/made configurable later, but for now,
it removes screen-edge artifacts in many games.
2022-09-25 22:30:10 +01:00
invertego 566184f669 md: connect 32x to cart slot in cd+32x mode
This is required for register reads/writes and h/vblank signals to be
handled by the 32x.
2022-09-25 21:42:58 +01:00
TascoDLX 8b5fbf511f md: combine banked & linear carts into standard mapper 2022-09-25 09:57:38 +01:00
TascoDLX c6a6972a75 ym2612: fix volume floor 2022-09-25 09:56:14 +01:00
Luke Usher 59713ea9b1 ng: show the full frame + fix top/bottom blanking 2022-09-24 22:39:08 +01:00
Luke Usher 4e1e3e02bb ng: position sprites relative to the top border rather than line 0. 2022-09-24 16:14:56 +01:00
Luke Usher a26e1ae006 md: apply 32:35 aspect ratio 2022-09-24 15:03:40 +01:00
Luke Usher 160ddb4457 Merge remote-tracking branch 'upstream/master' 2022-09-23 17:17:52 +01:00
invertego 8dda1836ac m32x: expose cart sram through 0x900000... range
The functional part of this change is just a few additional lines in
bus-external.cpp. The rest is refactoring to model the game cart as a
separate entity from the 32x, making it possible to delegate reads and
writes through the 0x900000... range to the cart implementation.

This fixes the corrupted menus and crashes in  Golf Magazine: 36 Great
Holes Starring Fred Couples.
2022-09-23 16:13:30 +01:00
Giovanni Bajo 18884d6aa2 Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 428884dea..fc3121239
fc3121239 Update to 0f7cc6c3a13494a575dbbb977ff4424743b688d7.
d37cf0ed0 Update to 93dfb98643d0dd8094c5739300dfed818502304e.
d433bc4d2 Update to 93d77f713ba0fbcf6bb9e654924e89f808b04398.
22f03bb13 Update to 0f0f9446470f4d0aa018b88ff6280bbc4137b6f6.
482a41deb Update to 07c3d161dbeb78121be5eebdab7c810b72af822a

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: fc3121239716e3cd99ec63175c9ce5c9d088c033
2022-09-23 12:28:00 +01:00
Giovanni Bajo 1e9c07c803 n64: add RDP crash support to Vulkan backend
Like #769, but for Vulkan.
2022-09-23 12:28:00 +01:00
kev4cards 2c463d0322 n64: fix control stick dead-zone scaling
Scale axially instead of radially
2022-09-23 12:27:40 +01:00
TascoDLX 2c3963c24e z80: fix extended/prefixed instruction timings + behavior
* timing info based on Z80 netlist analysis by Floh

1. Corrected cycle counts for DDCB & FDCB prefixed opcode fetches (was 17, now 16). Instructions cycle counts were increased to compensate for the lost cycle, though this corrects wrong cycle counts for corresponding instructions without a DD or FD prefix (+1 cycle).
2. Removed redundant code for instructions fixed in 1.
3. Changed BIT instructions in DDCB & FDCB blocks to not modify registers (ref: "The Undocumented Z80 Documented").
2022-09-22 07:48:04 +01:00
TascoDLX 3d57bf7914 z80: fix various instruction timings
* based on Z80 netlist analysis by Floh

1. Corrected cycle counts for EX (SP),rr (was 16, now 19) & IM n (was 12, now 8).
2. Reordered cycles for ADD/ADC/SBC HL,rr, RLD/RRD, & LD (rr),n.
3. Removed redundant code for CALL nn & IN (C).
2022-09-22 07:48:04 +01:00
Luke Usher 9fa501cc3a ps1: add simple idle loop detection 2022-09-20 11:10:31 +01:00
Luke Usher c66e3471e0 z80: fix IM0 and simplify IRQ implementation 2022-09-19 10:53:36 +01:00
Giovanni Bajo 17924254a1 GNUmakefile: add error message for incompatible GNU make
While testing parallel-RDP on macOS via MoltenVK, I found out that
a special syntax used in the N64 Makefile to compile parallel-RDP
requires a version of GNU make which is newer than the one that comes
with macOS. To avoid confusion, just error out for now.
2022-09-19 10:24:55 +01:00
invertego 27fe06917e n64: fix numerical instability in Gamepad::read() 2022-09-18 16:33:54 +01:00
invertego 164ef7b678 ps1: clamp f32 to u8 color conversions 2022-09-18 16:33:54 +01:00
invertego 2ad30215df build: fix missing override warning 2022-09-18 16:33:54 +01:00
invertego d4ae964be4 v30mz: fix shift behavior
The presence of undefined behavior (in C++) revealed several
bugs in various shift and rotate instructions. These are
deceptively hard get right without resorting to iteration.
Rather than complicate the implementation further, a few more
are now implemented wtih loops like RCL/RCR.
2022-09-18 16:33:54 +01:00
invertego 228105e6de nall: fix hashset new[]/delete mismatch 2022-09-18 16:33:54 +01:00
Giovanni Bajo 6c5e8ed49e n64: add rdp.command.crashed to serialization 2022-09-18 07:33:21 +01:00
remutro 019287a648 Why did my line endings change 2022-09-17 18:28:42 +01:00
remutro 719dac2dc1 Add missing disc command 0xf - GetParam 2022-09-17 18:28:42 +01:00
Giovanni Bajo abf2ef5832 n64: fix buffer overflows in mame RDP
RDP supports pixel coordinates in range -2048..2047, so we need to
account for up to 4096 spans.
2022-09-17 15:34:56 +01:00
Giovanni Bajo 953a50d827 n64: fix support for interlaced resolutions
The new code was completely wrong for interlaced resolutions, fix it
by changing into a simple filter on the current field.
Moreover, for some reason, the screen was only updated at 30fps.
Do it at 60fps, as both Vulkan and the native Ares screen knows how
to handle that.
2022-09-17 15:34:56 +01:00
Giovanni Bajo 7c116300bc n64: add RDP crash support
There a handful of sequences of invalid commands that can
cause the RDP to crash (it will stop processing commands until hard
reboot). Mame RDP already knows about them and reacts by throwing an
exception, that currently kills Ares because it is not caught.

This commit lets Ares actually emulate the crashed RDP by basically
freezing its command processor. A log is also emitted on console.

This is useful to homebrew developers that can do mistakes while
coding.
2022-09-17 15:34:20 +01:00
invertego cbfd7ed270 m32x: unify interpreter/recompiler sync timing 2022-09-17 15:33:52 +01:00
invertego 78d926b31d m32x: synchronize sh2 processors w/ each other 2022-09-17 15:33:52 +01:00
invertego a4d03c263f sh2: break min_cycles loop on uncached writes 2022-09-17 15:33:52 +01:00
Luke Usher 5283135a49 ps1: fix input issues in many titles 2022-09-16 22:47:19 +01:00
invertego 2c9cf460f3 sh2: initial emulation of sh7604 internal bus
Fix DMA in Metal Head and recompiler implementation of TAS instruction.
2022-09-16 09:13:49 +01:00
LuigiBlood 2bcb236dd6 n64: add dd serialization 2022-09-14 14:14:46 +01:00
LuigiBlood 77ff400bb1 n64: adjust access times as it prevented certain games to work properly 2022-09-14 14:14:46 +01:00
LuigiBlood c87166f9c5 n64: accurate ERR_SECTOR and CUR_SECTOR register info 2022-09-14 14:14:46 +01:00
LuigiBlood 6827540f11 n64: adjust seek times to be more accurate 2022-09-14 14:14:46 +01:00
LuigiBlood 0615773904 n64: finetune disk access times to be closer to real hardware tests 2022-09-14 14:14:46 +01:00
LuigiBlood c73e19bdf2 n64: only start motor state timer after seek is complete 2022-09-14 14:14:46 +01:00
LuigiBlood c0cac55065 n64: use dd command busy state 2022-09-14 14:14:46 +01:00
LuigiBlood e45e82bd19 n64: implement dd motor state management and adjust timings 2022-09-14 14:14:46 +01:00
LuigiBlood 26a7ac35ca n64: change dd seek timings 2022-09-14 14:14:46 +01:00
LuigiBlood 9748b37532 n64: rely on hardcoded block sizes (for retail and development disks) 2022-09-14 14:14:46 +01:00
LuigiBlood 0feacdc6a5 n64: recognize 64dd cic on connect using iplrom and set dd id between retail and dev 2022-09-14 14:14:46 +01:00
LuigiBlood be2495b253 n64: properly recognize and convert development disks 2022-09-14 14:14:46 +01:00
Luke Usher 24762209aa n64: support NTSC-U/NTSC-J/DEV 64DD variants 2022-09-14 14:14:46 +01:00
LuigiBlood 74ec42e889 n64: check and analyze disk region and disk ID 2022-09-14 14:14:46 +01:00
LuigiBlood fa76d1fb16 n64: map DD bus only if DD is enabled 2022-09-14 14:14:46 +01:00
LuigiBlood c437bc2d25 n64: detect errors in disk with heuristics for system disk data and return errors if attempting to read it 2022-09-14 14:14:46 +01:00
LuigiBlood 86ec0d1226 n64: redo drive controller error management 2022-09-14 14:14:46 +01:00
LuigiBlood 12c771e5c9 n64: make sure disk is present before performing disk access commands 2022-09-14 14:14:46 +01:00
LuigiBlood 451d562186 n64: support combo n64 & dd emulation 2022-09-14 14:14:46 +01:00
LuigiBlood aa5efe67ef n64: perform basic system disk area check for conversion 2022-09-14 14:14:46 +01:00
LuigiBlood 1749d4bd9b n64: support already converted mame ndd files 2022-09-14 14:14:46 +01:00
LuigiBlood d21820dab7 n64: add mouse to Nintendo 64DD emulator core 2022-09-14 14:14:46 +01:00
LuigiBlood 51474d86e7 n64: make sure cartridge.rom exists before accessing it 2022-09-14 14:14:46 +01:00
LuigiBlood 7fc641c787 n64: working dd disk save 2022-09-14 14:14:46 +01:00
LuigiBlood 1059725734 n64: add timer to mecha dd commands 2022-09-14 14:14:45 +01:00
LuigiBlood 6396c8c9ac n64: fix disk writing and add comments 2022-09-14 14:14:45 +01:00
LuigiBlood 57647bf62b n64: working 64DD disk conversion, drive read/write, 64DD real time clock 2022-09-14 14:14:45 +01:00
LuigiBlood 5176bfead1 n64: Change PIF ROM loading based on Console Region 2022-09-14 14:14:45 +01:00
LuigiBlood 91281a8247 n64: implement more DD commands including previously undocumented features 2022-09-14 14:14:45 +01:00
LuigiBlood c46beaff32 n64: add rtc.cpp and implement rtc timestamp 2022-09-14 14:14:45 +01:00
LuigiBlood b3c49a4636 n64: working rtc save 2022-09-14 14:14:45 +01:00
LuigiBlood 7ae217bc79 n64: add rtc file pak + commands 2022-09-14 14:14:45 +01:00
LuigiBlood 5d37682c6b n64: Add basic DD interface 2022-09-14 14:14:45 +01:00
LuigiBlood d70cb368de n64: add DD interrupts 2022-09-14 14:14:45 +01:00
Luke Usher 4fcfa471a4 n64: refactor to allow 64dd ipl to work
hard-coded to Retail - Japan for now.
2022-09-14 14:14:45 +01:00
LuigiBlood 01da5ed20d n64: handle 64dd cic in pif power on 2022-09-14 14:14:45 +01:00
LuigiBlood 433f230c9c n64: recognize 64dd ipl rom and cic 2022-09-14 14:14:45 +01:00
Luke Usher 91e49ab940 Revert "gb: correct oam dma startup delay"
This reverts commit e464f45605 as while allowing the test to not crash, it caused regressions in games.
2022-09-14 09:10:29 +01:00
Luke Usher e464f45605 gb: correct oam dma startup delay
from mooneye/acceptance/oam_dma_start
```
 Expected timing (fresh DMA):
; M = 0: write to $FF46 happens
; M = 1: nothing (OAM still accessible)
; M = 2: new DMA starts, OAM reads will return $FF
```

The test still fails, likely due to bad restart behavior,
but it no longer hangs.
2022-09-13 17:41:55 +01:00
Luke Usher e062350552 desktop-ui: check for game load failure for Sega Master System 2022-09-13 17:41:55 +01:00
Giovanni Bajo 74d6e885f6 Implement overflow exception in TRUNC 2022-09-13 15:08:16 +01:00
invertego ec34c02e4f Add nall/float-env.hpp 2022-09-13 15:08:16 +01:00
Giovanni Bajo 0aa84312c5 n64: improve generation of FPU exceptions.
Hook at least standard IEEE-754 exceptions on basic operations. This
should already catch most mistakes done while developing home-brew
games.
2022-09-13 15:08:16 +01:00
invertego 17a654cfc4 32x: reduce recompiler min_cycles 22 -> 19
Required by After Burner Complete
2022-09-13 11:41:49 +01:00
invertego 027a3db94c sh2: fix pc-relative moves in branch delay slots 2022-09-13 11:41:49 +01:00
invertego 38a7c74f28 build: qualify std::move/forward calls 2022-09-13 09:44:41 +01:00
Luke Usher 3147c3c996 6502: fix more SLO variants 2022-09-12 23:04:03 +01:00
Luke Usher d6605625bc 6502: implement remaining undocumented immediate addressing opcodes 2022-09-12 23:02:51 +01:00
Luke Usher e534e56002 sh2: fix broken illegal instruction debug logging
Illegal instructions were being logged after jumping to the exception handler,
causing almost useless debug output
2022-09-11 23:05:41 +01:00
TascoDLX cf9c02e571 ym2612: fix pm vibrato effect 2022-09-10 23:41:21 +01:00
Giovanni Bajo 0483193439 n64: rewrite VI resolution scaling
This should fix all games that had broken resolutions when not using
Vulkan. It also fix garbled graphics appearing on screen during scene
changes, usually at boot.
2022-09-10 17:56:15 +01:00
TascoDLX 6112bcaced ares: bump serializer version (ym2612 fix) 2022-09-10 17:12:19 +01:00
TascoDLX 64ae531ead ym2612: fix the envelope update logic 2022-09-10 17:12:19 +01:00
Luke Usher e90c318c0e md: 32X interrupt control register returns 0 in the upper bits 2022-09-09 00:22:04 +01:00
Luke Usher a4551216e9 md: better fix for 32x overscan: this one fixes bottom border also 2022-09-08 21:08:53 +01:00
Luke Usher 2e38fa5fc6 md: prevent 32x from incorrectly writing over megadrive borders
fixes overscan issues in a few titles
2022-09-08 20:50:01 +01:00
Raphael Assenat e2b96c8bab ms: Add support for the Mega Mouse
This pull request adds support for the Sega Mega Mouse. As the name implies,
this mouse was released for the MegaDrive, but as it is the case for 3/6 Button
controllers, the Mega Mouse can be safely connected to a Master System console and
even used, provided that the game software is programmed accordingly.

To my knowledge there are no official games on the SMS with mouse support, but there
is one demo I released (SMS-A-Sketch) which supports the Mega Mouse, and I have
an unreleased game that also supports it. I think it would be great to have ares
support the Mega Mouse on SMS as the only alternative at this point is to use
real hardware.
2022-09-08 09:19:53 +01:00
Raphael Assenat 4c3c07eb38 md: Fix a typo 2022-09-08 09:19:25 +01:00
Luke Usher 3e7ca5baec ms: fix incorrect hcount calculation
The VDPTEST still doesn't pass for any hcounter tests.
Inserting debug prints to print the hcounter value for every possible x coord shows correct output.
I suspect there are still some core timing issues in the z80...
2022-09-07 23:00:17 +01:00
TascoDLX c74700f35d z80: proper reset logic + implement for md 2022-09-07 08:15:52 +01:00
TascoDLX 368578d736 z80: correct timings for RET, LD (IX+d),n & LD (IY+d),n 2022-09-07 08:15:52 +01:00
TascoDLX 65d9640b20 ym2612: various improvements & fixes
1. Envelope gen clean-up + emulation of odd behaviors (see inline comments)
2. SSG-EG fixes -- mode 7, control register behavior
3. LFO PM (vibrato) fix + calc tweak
4. Clock fixes for envelope, LFO, timer B
2022-09-07 08:15:52 +01:00
Luke Usher 836f3fc976 msx: add database entry for Batman (Japan) 2022-09-06 22:24:19 +01:00
Luke Usher 5636e2b0f6 ruby: use glXSwapIntervalEXT where available 2022-09-06 18:53:45 +01:00
Luke Usher 37bc375c64 msx: distinguish between ASC16 and the r-type specific variant 2022-09-06 14:25:12 +01:00
Luke Usher 50467b7e6d Update README.md 2022-09-06 10:04:40 +01:00
Raphael Assenat dc37e934e6 md: Add support for the Mega Mouse 2022-09-06 09:10:24 +01:00
Raphael Assenat 21e5daebfc N64: Make the "Nothing" controller type in the menu work as expected
At the moment, the game sees a controller in all ports, even after
the controller type is changed from Gamepad to Nothing. (the Gamepad
instance still lives and still gets called...)

I worked around this by making sure that port->allocate gets called,
even when the selection is "Nothing". The code in port.cpp simply
does not allocate anything in this case.

For most systems and in most practical cases this probably does
not matter. But now the raphnet N64 adapter manager ROM correctly
reports "Not conneted" in ports set to Nothing.
2022-09-06 09:08:25 +01:00
Raphael Assenat 8f579b1993 n64: Leave PIF RAM as-is when no data was received
When the ->comm method returns with the invalid bit set, it means no
data was received. This happens for instance when sending invalid
or proprietary commands to a standard controller which does not answer.

When there is no answer, the PIF emulation code sets bit 7 of the receive
length byte to flag this error.

Since no data was received, the original (filler) bytes should be left
as-is in PIF RAM. This is what the hardware appears to do.

This fixes code that checks if the receive buffer got overwritten instead of
inspecting bit 7 for errors.
2022-09-06 09:08:25 +01:00
Raphael Assenat ed336af513 Fix indentation 2022-09-06 09:01:34 +01:00
Raphael Assenat 03186eb4d3 desktop-ui: Document command-line options and add --help
Ideally I think one should not need to read the source code to learn
that ares accepts command-line options and what those options are.

I wish I had known earlier that I could pass --system MSX when loading
a ROM directly, it would have saved me a lot of time. I had tried --help,
but it just opened the application window...
2022-09-06 09:01:34 +01:00
Luke Usher 972495df89 gba: fix eeprom saves for real this time 2022-09-05 23:46:59 +01:00
Luke Usher 3366b1dc6c mia: if no size is specified in the manifest, use on-disk size 2022-09-05 23:46:30 +01:00
Luke Usher 2c86419dd8 Revert "gba: fix eeprom saves (no longer zero bytes)"
This reverts commit d5c094e9e8.
2022-09-05 22:40:41 +01:00
Luke Usher 0e30732950 Revert "gba: eeprom size must only come from manifest or auto-detect, not file size"
This reverts commit f0598aaeb3.
2022-09-05 22:40:41 +01:00
Luke Usher 0fb5569c6b Revert "gba: don't re-create the eeprom array: it's already large enough"
This reverts commit f289cdd08a.
2022-09-05 22:40:40 +01:00
Luke Usher f289cdd08a gba: don't re-create the eeprom array: it's already large enough 2022-09-05 22:19:40 +01:00
Luke Usher f0598aaeb3 gba: eeprom size must only come from manifest or auto-detect, not file size
fixes #717
2022-09-05 19:46:02 +01:00
Luke Usher 1a498d64c9 ci: remove broken subtree split workflow 2022-09-05 15:48:39 +01:00
Luke Usher c2f58d1c79 Update split-subtrees.yml 2022-09-05 15:43:27 +01:00
invertego 3d826f5b26 nall: always pass by reference to make_string()
Many specializations of stringify store a reference to the wrapped
value. Therefore, passing arguments to make_string() by value can be
disastrous if the compiler does not perform copy elision and stringify
stores a reference to a variable that goes out of scope when
make_string() returns.
2022-09-05 14:20:55 +01:00
invertego 2bb95a13cb build: detect when gcc is an alias for clang
Detect build environments where 'g++' is just an alias for 'clang++'.
Example: MSYS2's Clang64 environment. This avoids the need to manually
override compiler detection.
2022-09-05 09:04:39 +01:00
invertego 1de21e178c build: pass through target from top-level makefile 2022-09-05 09:04:11 +01:00
Raphael Assenat cde0e1603d ms: Implement megadrive 3 and 6 buttons pads
Master system ports are compatible with megadrive controllers and
those can be used directly to play many original master system
games.

However MD controllers can be fully supported (i.e all buttons
working) if the game software is programmed to do so.

While really only useful on real hardware, there are game patches to
enable the Start button on MD controllers. But it's also possible
to make patches that use additional buttons or code full support
for Megadrive controllers in a homebrew title.
2022-09-04 10:44:34 +01:00
invertego 6fe063815c n64, ps1: stop video thread immediately on unload
The N64 and PS1 cores set custom Screen:refresh() callbacks that run on
the video thread and have meaningful dependencies on core state. It's
not safe to unload components from beneath them, so the video thread
should be stopped before any unloading occurs.
2022-09-04 10:44:03 +01:00
invertego b527a33b85 nall: make posix impl of thread::join idempotent
ares uses nall::thread with the assumption that calling join() multiple
times on the same thread will have no harmful effects. This was true of
the Windows implementation but not of the POSIX one.
2022-09-04 08:55:44 +01:00
Raphael Assenat 29a9c53a62 ms: Fix writes to controller port 2
Corrects an error in the original pull request which sent incorrect
data to port 2. The Sports Pad now also works in port 2.
2022-09-04 08:55:00 +01:00
CasualPokePlayer 56fe0d8269 Correct types for screen.hpp
Fixes some memory leaks due to delete being used instead of delete[]
2022-09-03 23:47:11 +01:00
invertego dc28723d52 nall: fix assignment operators
Almost all of the assignment operators in nall leaked resources, failed
to handle self assignment, or both.
2022-09-03 12:32:01 +01:00
Luke Usher 36af497fdf nall: add support for ccache
Use ccache ccache=true is passed to make
See https://ccache.dev/ for further details.

On msys/mingw, the ccache package is `mingw-w64-x86_64-ccache`
2022-09-02 22:56:48 +01:00
Luke Usher d5c094e9e8 gba: fix eeprom saves (no longer zero bytes)
mia cannot save a file when the manifest size is zero.
instead, use the largest known eeprom size + 1 as a default.

The +1 signifies that we should auto-detect the real size of the eeprom
and the large size makes sure mia creates a file on disk large enough.

For games without a database entry, the eeprom size be larger on disk
than is actually used, but it's better than completely broken saves.

Note that even with this, some games will require database entries,
but most should work now.
2022-09-02 22:38:36 +01:00
Luke Usher 6adc70cbc8 input: prevent polling more than necessary
This prevents slowdown in games that poll games multiple times per-frame.
5ms was chosen as ares already has a 5ms limit higher up the chain.

For me, Advanced Wars 2 (GBA) jumped from 50-55fps to 65-68 with this change
2022-09-02 20:51:03 +01:00
invertego 2e385844d0 sfc: fix performance ppu override detection 2022-09-02 00:03:14 +01:00
invertego 7e48079a46 pce: performance vdp timing overrides
Following the precedent set by the SFC performance PPU, override the
timing of the PCE performance VDP for a handful of problematic games.

All of these games already work fine with the accuracy VDP (enabled with
the "pixel accuracy mode" video setting) which does not and never will
contain contain game specific logic.

Affected games:
- Kore ga Pro Yakyuu '89
- Kore ga Pro Yakyuu '90
- TV Sports Baseball
- TV Sports Football
- TV Sports Hockey
- Valkyrie no Densetsu
- Victory Run
2022-09-01 16:16:56 +01:00
Giovanni Bajo f9eb9304f0 README: simplify build instructions 2022-09-01 08:13:48 +01:00
Giovanni Bajo c3eb8bc49e n64: improve exceptions for invalid instructions in cop1/cop2
Also implement MFC2/MTC2 and friends which seems to exist at some
level (though they just access a latch).

Fixes new set of tests in n64-systemtest.
2022-09-01 07:39:55 +01:00
invertego 8759a7d3e8 n64: precise rsp block invalidation
- The primary lookup table is direct addressed
- The secondary lookup table is indexed by hash of code block contents
- IMEM invalidation is tracked at 64-byte granularity and used to
  evict primary lookup table entries
- The secondary lookup table is only pruned on a full code cache flush
- Only executed instructions are hashed, so the code cache no longer
  experiences unbounded growth
- Code blocks can now wrap around the end of IMEM
- generic::recompiler now supports aborting recompilation (required by
  by an earlier version of this change)
2022-08-30 09:28:37 +01:00
Raphael Assenat a785ce924b msx: auto-connect the Arkanoid Vaus Paddle 2022-08-30 09:17:40 +01:00
Raphael Assenat 938b1647b0 msx: Implement the Arkanoid Vaus Paddle
This adds support for the Taito Arkanoid Vaus Paddle.
2022-08-30 09:17:40 +01:00
Raphael Assenat 6abe6bfb19 msx: Implement joystick port 2
On MSX, both joysticks are read through a common port (PSG port 14).
Which joystick is being accessed is selected through bit 6 in PSG
port 15. In other words, the ports inputs are multiplexed.

This pull request adds a simple concept of controller multiplexer
which the PSG IO code can call whenever port 14 is read.

PSG port 15 also controls the level and direction of some joystick
pins, but those are not multiplexed. This pull request corrects how
writes to port 15 are handled and organizes output bits in a predefined
order so controller implementation do not need to know which port they
are connected to. This paves the way for more advanced peripherals
controlled through those outputs, such as the Taito Arkanoid Vaus Paddle.
2022-08-30 09:17:21 +01:00
Raphael Assenat d22fae0cae ay38910: Keep a copy of the last data written to IO ports 2022-08-30 09:17:21 +01:00
Luke Usher 4effa2b6d2 ms: auto-connect sports pad for games that require it 2022-08-29 23:28:10 +01:00
Luke Usher e6dfd5ee74 ms: auto-connect paddle controller for the games that require it 2022-08-29 23:00:35 +01:00
Raphael Assenat a5966490c9 ms: Add support for the Sports Pad
This adds support for the Sports Pad, a trackball controller for Master System. Input
is done using a Mouse or a trackball (best).

Tested with Sports Pad Soccer and a homebrew test ROM.
2022-08-29 22:08:11 +01:00
Raphael Assenat f5f75cdeef ms: Expose output signals to controller port
The write method is now actually called when TR/TH level and direction
IO port is written to. Also redefined the write method bit width (4) and
document which bit is used for what.

This will allow emulation of controllers which uses the TH line as a
control output. This includes the Export Paddle, the Sports Pad, and
Megadrive controllers.
2022-08-29 22:08:11 +01:00
Raphael Assenat a6209af97b ruby: xlib mouse double event workaround
When the mouse is grabbed, the current implementation hides the
pointer and centers it on the screen.

When the mouse is polled, its relative motion is determined by how far it
has moved from the center of the screen, then it is moved back to the
center by calling XWarpPointer().

XWarpPointer generates an event resulting in an additional poll, which then
sees no movement at all (since the pointer is now centered) and therefore
resets the relative motion values to zero.

If the above reset occurs before the controller code has had the chance to
access the relative motion values, the motion never reach the game. This
works around this issue using a flag to ignore the next event if the
mouse is still centered on the screen.
2022-08-29 22:07:06 +01:00
Luke Usher 93e24926ae mia: add partial iNES 2.0 support
just enough to detect additional mapper types and games with additional CHR RAM for now.
2022-08-27 14:04:04 +01:00
Luke Usher 6f3997dc38 ms: fix an issue where the GG bios failed to detect SMS mode. 2022-08-25 23:17:52 +01:00
Luke Usher b380834c0e ms: fix Game Gear bios support (bios is optional) 2022-08-25 23:00:32 +01:00
Luke Usher 9e551be17a ps1: improve gamepad behavior when receiving invalid commands 2022-08-25 21:47:31 +01:00
Luke Usher d77c6f0788 ms: various vdp improvements
1. Nametable address is not a latched register, it takes effect immediately
2. Sprites should still be processed & overflow is still set during display disable
3. Hcounter -94 offset is incorrect for ares, as we already have clock 0 = pixel 0.
2022-08-25 14:16:38 +01:00
Luke Usher a1df486779 ms: fully decode port $3e on GameGear + allow $3f writes (latches h-counter)
Despite the Game Gear having no physical controller ports, writes to the IO control register still need to be emulated, and thus the ports need to be present in ares, such that latching h-counter on 0-1 transition is still possible.
2022-08-25 09:51:06 +01:00
Luke Usher cdedb9b0f5 sn76489: fix additional data writes to noise channel
fixes broken audio in Micro Machines on the Master System
2022-08-24 23:44:23 +01:00
Luke Usher 9ff41ed45a ms: initialize ram to zero
Fixes hang in Shanghai II (Japan) for Game Gear
2022-08-24 22:01:32 +01:00
Luke Usher 56aa5dac0d ms: fix precision loss when latching hcounter
Internal Hcounter values (actually clock cycles) are larger than the range of a u8.

The actual Master System h-counter (0x00-0xff range) is calculated later.
2022-08-24 16:36:07 +01:00
Luke Usher ebde92c891 mia: add database entry for Chase H.Q (USA)
This is another Game Gear release that targets SMS mode.
2022-08-24 16:21:39 +01:00
Luke Usher 7dc55eeb54 mia: add database entry for Taito Chase H.Q (Japan)
This is another Game Gear release that targets SMS mode.
2022-08-24 14:10:01 +01:00
Luke Usher ec4e0050e7 sms: fix a crash when using a Game Gear in SMS mode. 2022-08-23 20:25:15 +01:00
Luke Usher 306d23f38b mia: game-gear doesn't support PAL/50hz mode, use NTSC-U instead 2022-08-23 16:49:50 +01:00
Luke Usher fa3dfa38cd ps1: [SPU] increase precision of volume input to amplify function
fixes pitch modulation, especially obvious in J-E-N-O-V-A from FF7.
2022-08-22 23:36:56 +01:00
Luke Usher a0601f1c79 Update issue templates 2022-08-22 15:29:37 +01:00
Luke Usher 19b56bc118 Update issue templates 2022-08-22 15:28:14 +01:00
Luke Usher 2f12a72cad Update issue templates 2022-08-22 15:26:23 +01:00
Luke Usher ed0fe5599f desktop-ui: allow hotkeys when unfocused if "allow input while focus is lost" is enabled 2022-08-20 21:33:26 +01:00
invertego 081408e961 md: latch bus request on reset 2022-08-20 19:44:10 +01:00
Luke Usher 56d6488b3d 6502: add some undocumented opcode variants
fixes Aladdin and Super Cards on nes/fc
2022-08-20 00:05:55 +01:00
Luke Usher 85f1fb6b7f gb: more DMG mode fixes;
fixes titlescreen in Pokemon Red/Blue/Yellow on GBC in DMG mode.
2022-08-18 22:40:57 +01:00
Luke Usher 34d6d465c4 gb: handle differences with bgEnable in DMG mode on CGB 2022-08-18 22:40:56 +01:00
Parashoe fcef806553 n64 setting: "Disable Video Interface Processing" 2022-08-18 13:54:49 +01:00
Luke Usher 61258a7063 gb: fix an oops in KEY0 2022-08-17 11:35:48 +01:00
Luke Usher b1d216b8af gb: allow CGB to run in DMG mode
This is not fully hardware accurate yet (lots of CGB only registers remain enabled)
but most of the rendering issues should be resolved now.
2022-08-17 11:16:22 +01:00
Luke Usher c53023e6c8 gb: fixes to mbc2
1. ram is mirrored between 0xa000-0xbfff, not 0xa000-0xa1ff
2. ram & bank registers are mapped through 0x0000-0x3fff, using only bit.8 to select between them
2022-08-17 00:23:00 +01:00
Luke Usher 637aa19a72 gb: display is disabled while stopped 2022-08-17 00:10:43 +01:00
Luke Usher 2cf4d8cac8 gb: don't increment div when stopped 2022-08-17 00:10:29 +01:00
Luke Usher 0071e8a7d4 gb: fix div initial value (validated via mooneye tests) 2022-08-17 00:10:15 +01:00
Luke Usher d546f147c3 hiro: remove DirectDraw backend
DirectDraw has not been updated by Microsoft since DirectX7.
It has been deprecated/not recommended for use since DirectX8, released in 2000.
2022-08-16 22:01:05 +01:00
Luke Usher b03a942bf4 desktop-ui: simplify some code paths by removing lesser-used functions
1. Grouping systems by vendor in the system menu can no longer be disabled.
2. It is no longer possible to hide emulator cores from the menu
3. It is no longer possible to use the higan file select dialog; only the native OS file picker is available.
2022-08-16 21:57:29 +01:00
Raphael Assenat 23416eae32 Add support for the Japanese HPD-200 Paddle
This makes games requiring a Paddle, such as Megumi Rescue,
playable with an analog stick, or using adapters USB adapters
supporting the HPD-200 Paddle.

"Prefer Japan" should be selected in tools->Boot Options before load
otherwise the game will expect the "Export Paddle" which is not
compatible.
2022-08-16 10:30:47 +01:00
invertego 2ade0e39de m68000: fix memory read order for A/SBCD, ADD/SUBX
This is especially important when both operands reference the same
register, as the first predecrement should affect the second read.
2022-08-15 13:11:26 +01:00
Chris Jalbert 62930f8da8 accidentally excluded two important components - fixed 2022-08-14 18:21:33 +01:00
Tobias Jakobi be1f424398 build: use pkg-config in ruby Makefile
Checking for libraries in /usr/lib does not work reliably, e.g.
on a x86-64 Gentoo the 64-bit libraries are located in /usr/lib64.

Use pkg-config to detect libraries, which should work much better
on any modern Linux distro and also covers Debian's multi-arch
setup.
2022-08-14 17:21:18 +01:00
invertego 003afbbb58 m68000: fix divs/divu negative flag 2022-08-14 16:58:39 +01:00
Chris Jalbert 3010c8a8c9 Issue 521: Basic Build Instructions 2022-08-14 16:58:28 +01:00
invertego 4a935893d2 md: preserve bank register on apu reset 2022-08-14 16:56:25 +01:00
Giovanni Bajo 32096b8e85 n64: use Neon instructions also in mame RDP 2022-08-11 22:23:43 +01:00
Luke Usher 3142bd3aef n64: change rsp.ipu.pc to u16 from u12
Using a native data type significantly improves performance of ares::Nintendo64::RSP::instructionEpilogue, making it jump from ~9-10% of cpu time to 5-6% of cpu time during execution
2022-08-06 23:56:51 +01:00
Luke Usher 9985c693bd n64: use xxh3 instead of crc32 for rsp cache
This is a significantly faster and stronger algorithm than crc32
2022-08-06 23:37:08 +01:00
Luke Usher 81e15695c8 n64: a little more performance tuning 2022-08-06 17:38:48 +01:00
Luke Usher f486867292 n64: move some function implementations from icache.cpp to cpu.hpp
Identified via profiling: this improves performance due to better compiler optimisation.
2022-08-06 17:38:48 +01:00
Giovanni Bajo ffa7040b6f n64: use sse2neon to emulate RSP with SIMD instructions on ARM64 2022-08-06 14:43:05 +01:00
Giovanni Bajo 247a269054 thirdparty: vendor sse2neon.h (a951d8760) 2022-08-06 14:43:05 +01:00
invertego 50b2a8f3ab mia: fix 32x eeprom 2022-08-05 09:27:59 +01:00
Luke Usher f1e36f2775 n64: split rsp recompiler cache into 256-byte sized blocks
Significantly increases the cache hit ratio due to games utilising multiple small ucode programs.
2022-08-04 20:14:36 +01:00
FitzRoyX 997fda03fe md: add sram entry for psy-o-blade 2022-08-04 15:52:19 +01:00
Luke Usher c6ecbe81b2 n64: restore old recompiler invalidate behavior 2022-08-04 09:13:49 +01:00
Luke Usher 9c9ef927d7 desktop-ui: re-order systems by vendor in the menu 2022-08-02 23:04:07 +01:00
Luke Usher 029ae18514 Squashed 'thirdparty/libchdr/' changes from 045f2a7f23..b3c1651d0f
b3c1651d0f Merge pull request #80 from scribam/vita
e802754335 vita: fix core_fseek/core_ftell

git-subtree-dir: thirdparty/libchdr
git-subtree-split: b3c1651d0fee6543968d916cb4e39c9b184c231f
2022-08-02 20:53:54 +01:00
Luke Usher dcfce18d7f Merge commit '029ae18514c23e538f79126326e4244e79f648ff' 2022-08-02 20:53:54 +01:00
Luke Usher 295c729ecf Merge commit '43e0dd770d5e32ec2b4794a19281e2aa22f45bd1' 2022-08-02 20:52:59 +01:00
Luke Usher 43e0dd770d Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 808a89d23a..428884deab
428884deab Update to e6cf0e5ca257135acbcacfbdacd7cd3fdf3fb408
6879314041 Update to 9dacdc9d73c5febda2448fec9b393034fa5d9fe3

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 428884deab9571cc04be756960e3649f678c8f63
2022-08-02 20:52:59 +01:00
Luke Usher 6e9c08b491 n64: fix an issue where invalidateRange was called with incorrect inputs 2022-08-02 19:50:11 +01:00
Luke Usher 1808e3f50c n64: make the recompiler invalidate single blocks rather than entire pools 2022-08-02 09:40:25 +01:00
Luke Usher 8f39e06900 Squashed 'thirdparty/libchdr/' changes from 6eeb6abc4..045f2a7f2
045f2a7f2 Merge pull request #74 from 2weak2live/raw
e23f32f37 Add support for reading LZMA and FLAC hunks in non-CD CHDs.

git-subtree-dir: thirdparty/libchdr
git-subtree-split: 045f2a7f23f5ac10c0122f6f56e42023dfb71e2a
2022-08-01 16:12:29 +01:00
Luke Usher 7742b49289 Merge commit '8f39e06900d298526f86b9c808520bd6236d4475' 2022-08-01 16:12:29 +01:00
Luke Usher 4750a7f224 Squashed 'thirdparty/sljit/' changes from 761d48d2b..7c37b7ebc
7c37b7ebc Rework x86-32 stack layout
09a58361f Improve sljit abi calling convention
58e36c06a Change skip checks to a macro
ac445a3ef Add sljit specific register argument calling convention
a6c8e5bf7 Remove fast call support on x86-32
a3785b330 Fix x86 mem address encoding
2f8e5c2f2 Implement ARM unaligned support
3e86c50e9 Fix PPC logical or/xor with flag set
d8af3f91b Remove sparc support
3055f116b Fix test50 alignment
41cb888d8 Start supporting unaligned memory access

git-subtree-dir: thirdparty/sljit
git-subtree-split: 7c37b7ebcf17a80f606100ae88e744dff22befe6
2022-08-01 16:12:20 +01:00
Luke Usher ff78815e90 Merge commit '4750a7f224641df4c98038c32a50fb92e8facc11' 2022-08-01 16:12:20 +01:00
Luke Usher 00a5c6864e Squashed 'ares/n64/vulkan/parallel-rdp/' changes from af9b4b00f..808a89d23
808a89d23 Update to f187ecba0df48e3185ac61e5516c34f903c7a095
8a2986a64 Update to a691960e8d4f72fea6a384fd89881cbdb8a78a0b
31e97d2f2 Update to 4137ff0771ca473b7610a1c8ea307d7a5141aee4

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 808a89d23ae193e003b3e54de61a8172582168d1
2022-08-01 16:12:13 +01:00
Luke Usher a38572199d Merge commit '00a5c6864e20cd9c3a556e477abd2eb063c750a2' 2022-08-01 16:12:13 +01:00
Giovanni Bajo bcd501edf6 n64: fix AI DMA enable bit handling
Fix again Twisted Edge, that was recently broken when we reworked AI DMA
2022-08-01 09:05:40 +01:00
Giovanni Bajo 8d1ad79fdb n64: refactor AI::sample to always return a sample 2022-08-01 09:05:40 +01:00
invertego b2db7f16f6 ng: clean up screen thread on unload 2022-08-01 09:05:05 +01:00
Luke Usher 080b53a652 Revert "desktop-ui: optimize for generic x86-64-v2 rather than nehalem"
because Ubuntu 20.04 still has outdated GCC that doesn't support this flag;
people who get a performance hit from optimising for nehalem will just need to
self compile.

This reverts commit f7657dca4f.
2022-07-31 23:31:38 +01:00
Luke Usher 2b9fcab30f ci/desktop-ui: disable lto by default
The added compile time is not worth it when for many users this harms performance, rather than improving it.

TODO: Why?
2022-07-31 22:11:42 +01:00
Luke Usher 5565d2def4 attempt to fix ci builds for macOS 2022-07-31 11:27:09 +01:00
Luke Usher 9aa05bcbe3 nall: more LTO tuning 2022-07-30 19:26:51 +01:00
Simon Eriksson e0434ca82b n64: Add missing variables in RDP serialization 2022-07-29 23:53:52 +01:00
Luke Usher 9c5ecf52ce nall: tweak LTO settings for better performance in compiled builds
GameBoy core +10 FPS on average in my testing
2022-07-29 23:19:03 +01:00
Luke Usher 6d890244c1 desktop-ui: enable lto by default but allow it to be disabled with lto=false 2022-07-29 23:18:18 +01:00
Luke Usher f7657dca4f desktop-ui: optimize for generic x86-64-v2 rather than nehalem 2022-07-29 23:03:33 +01:00
Luke Usher eda2918f58 ng: fix games with non-power-of-two croms 2022-07-28 23:33:48 +01:00
Luke Usher d75c13107c ng: avoid syncing with the YM2610 more than necessary 2022-07-27 22:10:35 +01:00
Luke Usher 1a5984be70 ng: preliminary support for ADPCM-A channel 2022-07-27 14:53:39 +01:00
FitzRoyX e1711eb28a sfc: fix typo that broke bg4 2022-07-27 09:20:41 +01:00
Giovanni Bajo 1a564fa93e n64: fix AI IRQ
The AI IRQ should be generated when a buffer starts playing, not when
it finishes playing, as verified by hardware tests.

Fixes the audio in Hey Pikachu and possibly other games.
2022-07-26 22:22:15 +01:00
Luke Usher 6118facaf2 ng: refactor rom loading
Fixes Twinkle Star Sprites + possibly others
2022-07-23 22:34:39 +01:00
Luke Usher d52a3b9dfc ng: fix loading of roms that use .ep instead of .p for program roms 2022-07-22 23:16:26 +01:00
Luke Usher 38495197d2 ng: remove leftover debug logging 2022-07-22 23:09:44 +01:00
Luke Usher dd6a448bc4 ng: fix FM/SSG audio playback
ADPCM playback is still unsupported, so a lot of audio will be missing.
2022-07-22 22:56:57 +01:00
Luke Usher 1cea9ad1d9 mia: cleanup old famicom-disk source file 2022-07-22 20:02:56 +01:00
remutro 14c9dc04fd Rename all instances of Famicom Disk to Famicom Disk System 2022-07-22 14:35:15 +01:00
remutro 9e983e720f match emulator name with expected mia media definition to fix auto-detection of fds 2022-07-22 14:35:15 +01:00
Luke Usher b2dd52c0a4 ps1: fix a crash when using out of range vram co-ordinates 2022-07-21 22:24:36 +01:00
Luke Usher 9a3d949fc2 ms: implement support for NTSC-U/NTSC-J Game Gear variants 2022-07-21 21:43:46 +01:00
invertego 00819b70c0 a26: fix buffer overflows 2022-07-18 01:31:27 +01:00
Ralakimus cd83a939e8 32X: Implement preliminary Sega/SSF2 mapper support (see #628) 2022-07-15 13:51:32 +01:00
2366 changed files with 468495 additions and 176511 deletions

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
---
name: Bug report
about: Report a bug *not* relating to game compatibility
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
@@ -0,0 +1,22 @@
---
name: Game Issue Report
about: Report an issue running a specific game in ares
title: "[system] Game"
labels: bug
assignees: ''
---
Before submitting an issue, please use the search to make sure an issue doesn't already exist, you should also make sure your rom is not a bad dump, by comparing against the hashes in the No-Intro (Cartridges) or Redump (CD-ROM) databases.
**Describe the issue**
A clear and concise description of what the bug is.
**Rom Information**
Specify the impacted rom filename and any associated hashes (sha256 preferred);.
The easiest way to do this is to open the game in ares, and go to "Tools -> Manifest" and copy/paste the contents.
```
file: Some Game (REGION).ext
sha256: <hash>
```
+120 -16
View File
@@ -8,22 +8,49 @@ on:
jobs:
build:
strategy:
fail-fast: false
matrix:
program:
- ares
platform:
- name: windows
os: windows-latest
compiler: g++
shell: 'msys2 {0}'
msystem: mingw64
msys-env: x86_64
- name: windows-clang
os: windows-latest
compiler: clang++
windres: windres
shell: 'msys2 {0}'
msystem: clang64
msys-env: clang-x86_64
install: mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-SDL2
- name: windows-arm64
os: windows-latest
compiler: clang++ --target=aarch64-w64-windows-gnu --sysroot=/clangarm64 -resource-dir=/clangarm64/lib/clang/$(basename "$(clang++ -print-resource-dir)")
windres: windres --target=aarch64-w64-windows-gnu
shell: 'msys2 {0}'
msystem: clang64
install: mingw-w64-clang-x86_64-clang mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-pkgconf mingw-w64-clang-aarch64-SDL2
- name: windows-msvc-x64
os: windows-latest
compiler: clang++
windres: llvm-rc
shell: bash
msvc-arch: x64
- name: windows-msvc-arm64
os: windows-latest
compiler: clang++ --target=aarch64-w64-windows-msvc
windres: llvm-rc
shell: bash
msvc-arch: x64_arm64
- name: windows-cl-x64
os: windows-latest
compiler: cl
windres: rc
shell: bash
msvc-arch: x64
- name: windows-cl-arm64
os: windows-latest
compiler: cl
windres: rc
shell: bash
msvc-arch: x64_arm64
- name: macos
os: macos-latest
compiler: clang++
@@ -43,15 +70,88 @@ jobs:
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.platform.msystem }}
install: make mingw-w64-${{ matrix.platform.msys-env }}-toolchain
install: make ${{ matrix.platform.install }}
- name: Install Linux Dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update -y -qq
sudo apt-get install libsdl2-dev libgtksourceview2.0-dev libgtk2.0-dev libao-dev libopenal-dev
- uses: actions/checkout@v2
sudo apt-get install libsdl2-dev libgtk-3-dev libao-dev libopenal-dev
- name: "macOS: Import Certificate"
if: runner.os == 'macOS' && github.event_name != 'pull_request'
continue-on-error: ${{ github.repository != 'ares-emulator/ares' }}
uses: wpilibsuite/import-signing-certificate@2ac4f44d28045073d23153256efbb4c4b2d8aa22 # Don't use rolling branch for security reasons
with:
certificate-data: ${{ secrets.MACOS_CERTIFICATE_DATA }}
certificate-passphrase: ${{ secrets.MACOS_CERTIFICATE_PASSPHRASE }}
keychain-name: ares-macos-keychain
keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
- name: Checkout source code
uses: actions/checkout@v2
- name: "macOS: recover MoltenVK cache"
if: runner.os == 'macOS'
uses: actions/cache@v3
env:
cache-name: moltenvk
with:
path: thirdparty/MoltenVK/MoltenVK
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('thirdparty/MoltenVK/HEAD') }}
- name: "macOS: recover SDL cache"
if: runner.os == 'macOS'
uses: actions/cache@v3
env:
cache-name: sdl
with:
path: thirdparty/SDL/SDL
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('thirdparty/SDL/HEAD') }}
- name: Install macOS Dependencies
if: runner.os == 'macOS'
run: |
brew install make ninja cmake
pip install --no-input setuptools
echo "MAKE=gmake" >> $GITHUB_ENV
pushd thirdparty/SDL
./build-SDL.sh
popd
pushd thirdparty/MoltenVK
./build-moltenvk.sh
popd
- name: Set up MSVC environment
if: matrix.platform.msvc-arch != ''
uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.platform.msvc-arch }}
- name: Make
run: make -j4 -C desktop-ui build=optimized local=false lto=true compiler=${{ matrix.platform.compiler }}
if: runner.os != 'macOS'
run: ${MAKE:-make} -j4 -C desktop-ui build=optimized local=false compiler="${{ matrix.platform.compiler }}" windres="${{ matrix.platform.windres }}"
- name: "macOS: Make universal app"
if: runner.os == 'macOS'
run: scripts/macos-make-universal.sh build=optimized local=false
env:
MAKEFLAGS: -j3
MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }}
MACOS_KEYCHAIN_NAME: ares-macos-keychain
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
- name: "Windows: sign"
if: runner.os == 'Windows' && github.event_name != 'pull_request'
uses: DanaBear/code-sign-action@98c79121b376beab8d6a9484f445089db4461bca
with:
certificate: '${{ secrets.WIN_CERTIFICATE }}'
password: '${{ secrets.WIN_PASSWORD }}'
certificatesha1: '${{ secrets.WIN_CERTHASH }}'
certificatename: '${{ secrets.WIN_CERTNAME }}'
folder: 'desktop-ui/out'
timestampUrl: 'http://timestamp.digicert.com'
- name: "macOS: notarize"
if: runner.os == 'macOS' && github.event_name != 'pull_request'
continue-on-error: ${{ github.repository != 'ares-emulator/ares' }}
run: |
ditto -c -k --keepParent desktop-ui/out/ares.app /tmp/ares.zip
xcrun notarytool submit /tmp/ares.zip --apple-id "$MACOS_NOTARIZATION_USERNAME" --password "$MACOS_NOTARIZATION_PASSWORD" --team-id "$MACOS_NOTARIZATION_TEAMID" --wait
xcrun stapler staple desktop-ui/out/ares.app
env:
MACOS_NOTARIZATION_USERNAME: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
MACOS_NOTARIZATION_PASSWORD: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
MACOS_NOTARIZATION_TEAMID: ${{ secrets.MACOS_NOTARIZATION_TEAMID }}
- name: Upload
uses: actions/upload-artifact@v2
with:
@@ -87,16 +187,16 @@ jobs:
# Hack: Workaround for GitHub artifacts losing attributes.
chmod +x ${bindir}/ares-macos/ares.app/Contents/MacOS/ares
for os in windows macos
for package in windows windows-msvc-arm64 macos
do
mkdir "${os}"
cd "${os}"
mkdir "${package}"
cd "${package}"
# Package ares.
outdir=ares${suffix}
mkdir ${outdir}
cp -ar ${bindir}/ares-${os}/* ${outdir}
zip -r ../ares-${os}.zip ${outdir}
cp -ar ${bindir}/ares-${package}/* ${outdir}
zip -r ../ares-${package}.zip ${outdir}
cd -
done
@@ -183,6 +283,10 @@ jobs:
uses: actions/upload-release-asset@v1
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-windows.zip', asset_name: 'ares-windows.zip', asset_content_type: 'application/zip' }
- name: Upload ares-windows-msvc-arm64
uses: actions/upload-release-asset@v1
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-windows-msvc-arm64.zip', asset_name: 'ares-windows-msvc-arm64.zip', asset_content_type: 'application/zip' }
- name: Upload ares-macos
uses: actions/upload-release-asset@v1
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
-30
View File
@@ -1,30 +0,0 @@
name: 'Split Subtrees'
on:
push:
branches:
- master
tags:
- '*'
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
jobs:
packages_split:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package:
- nall
- hiro
- ruby
- libco
steps:
- uses: actions/checkout@v2
- if: "!startsWith(github.ref, 'refs/tags/')"
uses: "symplify/[email protected]"
with:
package_directory: '${{ matrix.package }}'
repository_organization: 'ares-emulator'
repository_name: '${{ matrix.package }}'
user_name: "Luke Usher"
user_email: "[email protected]"
+10
View File
@@ -1,2 +1,12 @@
*.moc
*.user
.vs/
.vscode/
.idea/
cmake-*/
obj/
out/
obj-amd64/
obj-arm64/
out-amd64/
out-arm64/
+4 -4
View File
@@ -1,6 +1,6 @@
all: desktop
targets = all clean install uninstall verbose
desktop:
$(MAKE) -C desktop-ui
$(targets):
@$(MAKE) -C desktop-ui $@
.PHONY: all desktop
.PHONY: $(targets)
+357 -33
View File
@@ -45,38 +45,6 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
----------------------------------------------------------------------
MAME
Copyright (c) 1997-2021 MAMEdev and contributors
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
----------------------------------------------------------------------
libchdr
@@ -145,4 +113,360 @@ Gailly and Mark Adler; it does not include third-party code.
If you redistribute modified sources, we would appreciate that you include in
the file ChangeLog history information documenting your changes. Please read
the FAQ for more information on the distribution of modified source versions.
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
xxHash - Extremely Fast Hash algorithm
Header File
Copyright (C) 2012-2021 Yann Collet
BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at:
- xxHash homepage: https://www.xxhash.com
- xxHash source repository: https://github.com/Cyan4973/xxHash
----------------------------------------------------------------------
MoltenVK
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------
----------------------------------------------------------------------
OpenGL API and Extension Registry
https://github.com/KhronosGroup/OpenGL-Registry
Copyright 2013-2020 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
----------------------------------------------------------------------
----------------------------------------------------------------------
EGL API and Extension Registry
https://github.com/KhronosGroup/EGL-Registry
Copyright (c) 2008-2018 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
----------------------------------------------------------------------
----------------------------------------------------------------------
TZXFile
MIT License
Copyright (c) 2020 MrReeMachine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
----------------------------------------------------------------------
----------------------------------------------------------------------
ymfm
BSD 3-Clause License
Copyright (c) 2021, Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
+136 -2
View File
@@ -1,9 +1,9 @@
![ares logo](https://ares-emulator.github.io/images/logo.png)
![ares logo](https://github.com/ares-emulator/ares/blob/master/ares/ares/resource/logo.png)
[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://github.com/higan-emu/ares/blob/master/LICENSE)
**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.
Official Releases
-----------------
@@ -16,3 +16,137 @@ 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).
Only the latest nightly build is kept.
Prerequisites
-------------
### *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 (e.g. for using a controller), you will need to install the `libsdl2-dev` and `libsdl2-2.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 clang is detected on Windows/macOS/BSD, it will be selected by default. On Linux and other platforms, g++ remains the default if present. To build 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:
```
pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-SDL2
```
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 mingw-w64-clang-x86_64-SDL2
```
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:
```
git clone https://github.com/ares-emulator/ares.git
```
From the root of the project directory run:
```
make -j4
```
`-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 myvision 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/*`.
Command-line options
--------------------
When started from the command-line, ares accepts a few options.
```
Usage: ./ares [options] game(s)
--help Displays available options and exit
--fullscreen Start in full screen mode
--system system Specify the system name
--shader shader Specify GLSL shader name to load (requires OpenGL driver)
--setting name=value Specify a value for a setting
--dump-all-settings Show a list of all existing settings and exit
--no-file-prompt Do not prompt to load (optional) additional roms (eg: 64DD)
```
The --system option is useful when the system type cannot be auto-detected.
--fullscreen will only have an effect if a game is also passed in argument.
Example:
`ares --system MSX examples.rom --fullscreen`
Specifying multiple games allows for multi-cart support. For example, to load
the Super GameBoy BIOS and a game in one command (to avoid a file prompt), you
can do:
`ares "Super GameBoy.sfc" "Super Mario Land.gb"`
The --no-file-prompt option is useful if you wish to launch a game from CLI
without being prompted to load additional roms. For example, some Nintendo 64
games optionally support 64DD expansion disks, so this option can be used to
suppress the "64DD Disk" file dialog, and assume any secondary content is
disconnected.
High-level Components
---------------------
* __ares__: emulator cores and component implementations
* __desktop-ui__: main GUI implementation for this project
* __hiro__: cross-platform GUI toolkit that utilizes native APIs on supported platforms
* __nall__: Near's alternative to the C++ standard library
* __ruby__: interface between a hiro application and platform-specific APIs for emulator video, audio, and input
* __mia__: internal ROM database and ROM/image loader
* __libco__: cooperative multithreading library
Contributing
------------
Please join our discord to chat with other ares developers: https://discord.com/invite/gz2quhk2kv
+9 -3
View File
@@ -1,7 +1,5 @@
ifeq ($(platform),windows)
options += -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32
options += -Wl,-enable-auto-import
options += -Wl,-enable-runtime-pseudo-reloc
options += $(call lib,uuid kernel32 user32 gdi32 comctl32 comdlg32 shell32)
else ifeq ($(platform),macos)
else ifneq ($(filter $(platform),linux bsd),)
options += -Wl,-export-dynamic
@@ -75,6 +73,10 @@ ifneq ($(filter $(cores),cv),)
include $(ares.path)/cv/GNUmakefile
endif
ifneq ($(filter $(cores),myvision),)
include $(ares.path)/myvision/GNUmakefile
endif
ifneq ($(filter $(cores),gb),)
include $(ares.path)/gb/GNUmakefile
endif
@@ -95,6 +97,10 @@ ifneq ($(filter $(cores),ngp),)
include $(ares.path)/ngp/GNUmakefile
endif
ifneq ($(filter $(cores),spec),)
include $(ares.path)/spec/GNUmakefile
endif
include $(ares.path)/component/GNUmakefile
flags += $(foreach c,$(call strupper,$(cores)),-DCORE_$c)
File diff suppressed because it is too large. Load diff
+15 -15
View File
@@ -1,16 +1,16 @@
#version 150
in vec4 position;
in vec2 texCoord;
out Vertex {
vec2 vTexCoord;
};
uniform vec4 targetSize;
uniform vec4 sourceSize[];
void main() {
gl_Position = position;
vTexCoord = texCoord;
#version 150
in vec4 position;
in vec2 texCoord;
out Vertex {
vec2 vTexCoord;
};
uniform vec4 targetSize;
uniform vec4 sourceSize[];
void main() {
gl_Position = position;
vTexCoord = texCoord;
}
+11 -11
View File
@@ -1,12 +1,12 @@
input
filter: nearest
program
filter: nearest
vertex: lottes.vs
fragment: lottes.fs
output
height: 0
width: 0
input
filter: nearest
program
filter: nearest
vertex: lottes.vs
fragment: lottes.fs
output
height: 0
width: 0
filter: linear
@@ -32,18 +32,18 @@ out vec4 fragColor;
#ifdef LuminanceLUT
#define LUT_SizeLum 16.0
// Code taken from RetroArch's LUT shader
// Code taken from RetroArch's LUT shader
float luminancelut(vec4 org)
{
vec4 imgColorLum = org;
float redLum = ( imgColorLum.r * (LUT_SizeLum - 1.0) + 0.4999 ) / (LUT_SizeLum * LUT_SizeLum);
float greenLum = ( imgColorLum.g * (LUT_SizeLum - 1.0) + 0.4999 ) / LUT_SizeLum;
float blue1Lum = (floor( imgColorLum.b * (LUT_SizeLum - 1.0) ) / LUT_SizeLum) + redLum;
float blue2Lum = (ceil( imgColorLum.b * (LUT_SizeLum - 1.0) ) / LUT_SizeLum) + redLum;
float mixerLum = clamp(max((imgColorLum.b - blue1Lum) / (blue2Lum - blue1Lum), 0.0), 0.0, 32.0);
float color1Lum = texture(pixmap[1], vec2( blue1Lum, greenLum )).x;
float color2Lum = texture(pixmap[1], vec2( blue2Lum, greenLum )).x;
return mix(color1Lum, color2Lum, mixerLum);
vec4 imgColorLum = org;
float redLum = ( imgColorLum.r * (LUT_SizeLum - 1.0) + 0.4999 ) / (LUT_SizeLum * LUT_SizeLum);
float greenLum = ( imgColorLum.g * (LUT_SizeLum - 1.0) + 0.4999 ) / LUT_SizeLum;
float blue1Lum = (floor( imgColorLum.b * (LUT_SizeLum - 1.0) ) / LUT_SizeLum) + redLum;
float blue2Lum = (ceil( imgColorLum.b * (LUT_SizeLum - 1.0) ) / LUT_SizeLum) + redLum;
float mixerLum = clamp(max((imgColorLum.b - blue1Lum) / (blue2Lum - blue1Lum), 0.0), 0.0, 32.0);
float color1Lum = texture(pixmap[1], vec2( blue1Lum, greenLum )).x;
float color2Lum = texture(pixmap[1], vec2( blue2Lum, greenLum )).x;
return mix(color1Lum, color2Lum, mixerLum);
}
#endif
@@ -52,48 +52,48 @@ float luminancelut(vec4 org)
vec4 TrinitronD50(vec4 org)
{
vec4 imgColorTrinitron = org;
float redTrinitron = ( imgColorTrinitron.r * (LUT_SizeTrinitron - 1.0) + 0.4999 ) / (LUT_SizeTrinitron * LUT_SizeTrinitron);
float greenTrinitron = ( imgColorTrinitron.g * (LUT_SizeTrinitron - 1.0) + 0.4999 ) / LUT_SizeTrinitron;
float blue1Trinitron = (floor( imgColorTrinitron.b * (LUT_SizeTrinitron - 1.0) ) / LUT_SizeTrinitron) + redTrinitron;
float blue2Trinitron = (ceil( imgColorTrinitron.b * (LUT_SizeTrinitron - 1.0) ) / LUT_SizeTrinitron) + redTrinitron;
float mixerTrinitron = clamp(max((imgColorTrinitron.b - blue1Trinitron) / (blue2Trinitron - blue1Trinitron), 0.0), 0.0, 32.0);
vec4 color1Trinitron = texture(pixmap[2], vec2( blue1Trinitron, greenTrinitron ));
vec4 color2Trinitron = texture(pixmap[2], vec2( blue2Trinitron, greenTrinitron ));
vec4 fragColorTrinitron = mix(color1Trinitron, color2Trinitron, mixerTrinitron);
return vec4(pow(fragColorTrinitron.rgb,vec3(GammaCorrection,GammaCorrection,GammaCorrection)),1.0);
vec4 imgColorTrinitron = org;
float redTrinitron = ( imgColorTrinitron.r * (LUT_SizeTrinitron - 1.0) + 0.4999 ) / (LUT_SizeTrinitron * LUT_SizeTrinitron);
float greenTrinitron = ( imgColorTrinitron.g * (LUT_SizeTrinitron - 1.0) + 0.4999 ) / LUT_SizeTrinitron;
float blue1Trinitron = (floor( imgColorTrinitron.b * (LUT_SizeTrinitron - 1.0) ) / LUT_SizeTrinitron) + redTrinitron;
float blue2Trinitron = (ceil( imgColorTrinitron.b * (LUT_SizeTrinitron - 1.0) ) / LUT_SizeTrinitron) + redTrinitron;
float mixerTrinitron = clamp(max((imgColorTrinitron.b - blue1Trinitron) / (blue2Trinitron - blue1Trinitron), 0.0), 0.0, 32.0);
vec4 color1Trinitron = texture(pixmap[2], vec2( blue1Trinitron, greenTrinitron ));
vec4 color2Trinitron = texture(pixmap[2], vec2( blue2Trinitron, greenTrinitron ));
vec4 fragColorTrinitron = mix(color1Trinitron, color2Trinitron, mixerTrinitron);
return vec4(pow(fragColorTrinitron.rgb,vec3(GammaCorrection,GammaCorrection,GammaCorrection)),1.0);
}
#endif
void main() {
//Source Image
vec4 org = texture(source[0], texCoord);
vec4 org = texture(source[0], texCoord);
#ifdef LuminanceLUT
// Use a 3DLUT instead of an equation so that it can use any arbitrary mess you can come up with.
float luminance = luminancelut(org);
float luminance = luminancelut(org);
#elif defined LuminanceDawnbringer
// Dawnbringer's brightness equation from Dawnbringer's Toolbox scripts for Grafx2
float luminance = sqrt(org.r*org.r*0.0676 + org.g*org.g*0.3025 + org.b*org.b*0.0361) * 1.5690256395005606;
float luminance = sqrt(org.r*org.r*0.0676 + org.g*org.g*0.3025 + org.b*org.b*0.0361) * 1.5690256395005606;
#else
// Plain, standard, fine; slightly faster
float luminance = ((0.299*org.r) + (0.587*org.g) + (0.114*org.b));
float luminance = ((0.299*org.r) + (0.587*org.g) + (0.114*org.b));
#endif
// Don't let it exceed 1.0
luminance = clamp(luminance, 0.0, 1.0);
luminance = clamp(luminance, 0.0, 1.0);
// Scanline Mapping, based on the Phosphor LUT shader's method of tiling a texture over the screen
vec2 LUTeffectiveCoord = vec2(luminance,fract((texCoord.y*targetSize.y)/4.0));
vec2 LUTeffectiveCoord = vec2(luminance,fract((texCoord.y*targetSize.y)/4.0));
// Scanline Layer
vec4 screen = texture(pixmap[0], LUTeffectiveCoord);
vec4 screen = texture(pixmap[0], LUTeffectiveCoord);
// Output multiplying the scanlines into the original image, with control over opacity
#ifdef TrinitronColors
org = TrinitronD50(org);
org = TrinitronD50(org);
#endif
fragColor = ((screen*ScanlinesOpacity)+(1.0 - ScanlinesOpacity)) * (org);
fragColor = ((screen*ScanlinesOpacity)+(1.0 - ScanlinesOpacity)) * (org);
}
+10 -10
View File
@@ -1,11 +1,11 @@
input
filter: nearest
program
filter: nearest
height: 100%
fragment: pal-r57shell.fs
output
height: 0
input
filter: nearest
program
filter: nearest
height: 100%
fragment: pal-r57shell.fs
output
height: 0
filter: linear
+367 -367
View File
@@ -1,368 +1,368 @@
#version 150
// NES PAL composite signal simulation for RetroArch
// shader by r57shell
// thanks to feos & HardWareMan & NewRisingSun
// also TV subpixels and scanlines
// LICENSE: PUBLIC DOMAIN
// NOTE: for nice TV subpixels and scanlines I recommend to
// disable this features here and apply CRT-specialized shader.
// Quality considerations
// there are three main options:
// USE_RAW (R), USE_DELAY_LINE (D), USE_COLORIMETRY (C)
// here is table of quality in decreasing order:
// RDC, RD, RC, DC, D, C
// compatibility macros
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define frac(c) fract(c)
#define saturate(c) clamp(c, 0.0, 1.0)
#define fmod(x,y) mod(x,y)
#define mul(x,y) (y*x)
#define float2x2 mat2
#define float3x3 mat3
#define float4x4 mat4
#define bool2 bvec2
#define bool3 bvec3
#define bool4 bvec4
#define static
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 outputSize;
uniform int phase;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
// TWEAKS start
// use delay line technique
// without delay line technique, color would interleave
// to avoid this, set HueRotation to zero.
#define USE_DELAY_LINE
// use this if you need to swap even/odd V sign.
// sign of V changes each scanline
// so if some scanline is positive, then next is negative
// and if you want to match picture
// to actual running PAL NES on TV
// you may want to have this option, to change signs
// if they don't match
//#define SWAP_VSIGN
// rough simulation of scanlines
// better if you use additional shader instead
// if you still use it, make sure that SizeY
// is at least twice lower than output height
#define USE_SCANLINES // FIXME: scanlines are broken and I'm too lazy to fix it right now
// to change gamma of virtual TV from 2.2 to something else
#define USE_GAMMA
// use sampled version. it's much more slower version of shader.
// because it is computing x4 more values. NOT RECOMMENDED.
//#define USE_SAMPLED
#ifndef PARAMETER_UNIFORM
// NTSC standard gamma = 2.2
// PAL standard gamma = 2.8
// according to many sources, very unlikely gamma of TV is 2.8
// most likely gamma of PAL TV is in range 2.4-2.5
const float Gamma_static = 2.8; // gamma of virtual TV
const float Brightness_static = 0.25;
const float Contrast_static = 1.1;
const float Saturation_static = 1.1;
const int
Ywidth_static = 12,
Uwidth_static = 23,
Vwidth_static = 23;
#define Brightness Brightness_static
#define Gamma Gamma_static
#define Ywidth Ywidth_static
#define Uwidth Uwidth_static
#define Vwidth Vwidth_static
#define SCANLINE_MUL (sw.x*dark_scanline+sw.y)
int Mwidth = int(max(float(Ywidth), max(float(Uwidth), float(Vwidth))));
// correct one is -2.5
// works only with USE_RAW
const float HueShift = -2.5;
// rotation of hue due to luma level.
const float HueRotation = 2.;
// touch this only if you know what you doing
const float Phase_Y = 2.; // fmod(341*10,12)
const float Phase_One = 0.; // alternating phases.
const float Phase_Two = 8.;
// screen size, scanlines = y*2; y one field, and y other field.
const int SizeX = 256;
const int SizeY = 240;
// count of pixels of virtual TV.
// value close to 1000 produce small artifacts
const int TV_Pixels = 400;
const float dark_scanline = 0.5; // half
#endif
// this is using following matrixes.
// it provides more scientific approach
// by conversion into linear XYZ space
// and back to sRGB.
// it's using Gamma setting too.
// define USE_GAMMA is not required.
#define USE_COLORIMETRY
const float3x3 RGB_to_XYZ =
mat3(
0.4306190, 0.3415419, 0.1783091,
0.2220379, 0.7066384, 0.0713236,
0.0201853, 0.1295504, 0.9390944
);
const float3x3 XYZ_to_sRGB =
mat3(
3.2406, -1.5372, -0.4986,
-0.9689, 1.8758, 0.0415,
0.0557, -0.2040, 1.0570
);
// TWEAKS end
const float YUV_u = 0.492;
const float YUV_v = 0.877;
const mat3 RGB_to_YUV =
mat3(
float3( 0.299, 0.587, 0.114), //Y
float3(-0.299,-0.587, 0.886)*YUV_u, //B-Y
float3( 0.701,-0.587,-0.114)*YUV_v //R-Y
);
#ifdef USE_DELAY_LINE
const float comb_line = 1.;
#else
const float comb_line = 2.;
#endif
static const float Voltage_0 = 0.518;
static const float Voltage_1 = 1.962;
static const float DeltaV = (Voltage_1-Voltage_0);
float RGB_y = Contrast_static/Ywidth_static/DeltaV;
float RGB_u = comb_line*Contrast_static*Saturation_static/YUV_u/Uwidth_static/DeltaV;
float RGB_v = comb_line*Contrast_static*Saturation_static/YUV_v/Vwidth_static/DeltaV;
mat3 YUV_to_RGB =
mat3(
float3(1., 1., 1.)*RGB_y,
float3(0., -0.114/0.587, 1.)*RGB_u,
float3(1., -0.299/0.587, 0.)*RGB_v
);
const float pi = 3.1415926535897932384626433832795;
float sinn(float x)
{
return sin(/*fmod(x,24)*/x*(pi*2./24.));
}
float coss(float x)
{
return cos(/*fmod(x,24)*/x*(pi*2./24.));
}
float3 monitor(sampler2D tex, float2 p)
{
float2 size = sourceSize[0].xy;//float2(SizeX,SizeY);
// align vertical coord to center of texel
float2 uv = float2(
p.x,
(floor(p.y*sourceSize[0].y)+0.5)/sourceSize[0].y);
#ifdef USE_DELAY_LINE
float2 sh = (sourceSize[0].xy/sourceSize[0].xy/size)*float2(14./10.,-1.0);
#endif
float2 pc = uv*sourceSize[0].xy/sourceSize[0].xy*size*float2(10.,1.);
float alpha = dot(floor(float2(pc.x,pc.y)),float2(2.,Phase_Y*2.));
alpha += Phase_One*2.;
// 1/size.x of screen in uv coords = sourceSize[0].x/sourceSize[0].x/size.x;
// then 1/10*size.x of screen:
float ustep = sourceSize[0].x/sourceSize[0].x/size.x/10.;
float border = sourceSize[0].x/sourceSize[0].x;
float ss = 2.0;
#ifdef SWAP_VSIGN
#define PAL_SWITCH(A) A < 1.
#else
#define PAL_SWITCH(A) A > 1.
#endif
if (PAL_SWITCH(fmod(uv.y*sourceSize[0].y/sourceSize[0].y*size.y,2.0)))
{
// cos(pi-alpha) = -cos(alpha)
// sin(pi-alpha) = sin(alpha)
// pi - alpha
alpha = -alpha+12012.0;
ss = -2.0;
}
float ysum = 0., usum = 0., vsum = 0.;
for (int i=0; i<Mwidth; ++i)
{
float4 res = texture(tex, uv);
float3 yuv = mul(RGB_to_YUV, res.xyz);
float a1 = alpha+(HueShift+2.5)*2.-yuv.x*ss*HueRotation;
float sig = yuv.x+dot(yuv.yz,sign(float2(sinn(a1),coss(a1))));
#ifdef USE_DELAY_LINE
float4 res1 = texture(tex, uv+sh);
float3 yuv1 = mul(RGB_to_YUV, res1.xyz);
float a2 = (HueShift+2.5)*2.+12012.0-alpha+yuv.x*ss*HueRotation;
float sig1 = yuv1.x+dot(yuv1.yz,sign(float2(sinn(a2),coss(a2))));
#endif
if (i < Ywidth)
ysum += sig;
#ifdef USE_DELAY_LINE
if (i < Uwidth)
usum += (sig+sig1)*sinn(alpha);
if (i < Vwidth)
vsum += (sig-sig1)*coss(alpha);
#else
if (i < Uwidth)
usum += sig*sinn(alpha);
if (i < Vwidth)
vsum += sig*coss(alpha);
#endif
alpha -= ss;
uv.x -= ustep;
}
float3 rgb = mul(float3(ysum+Brightness*Ywidth_static,usum,vsum), YUV_to_RGB);
#if defined(USE_GAMMA) && !defined(USE_COLORIMETRY)
float3 rgb1 = saturate(rgb);
rgb = pow(rgb1, Gamma/2.2);
#endif
#ifdef USE_COLORIMETRY
float3 rgb1 = saturate(rgb);
rgb = pow(rgb1, float3(Gamma, Gamma, Gamma));
#endif
#if (defined(USE_SCANLINES))
float2 q = (p*sourceSize[0].xy/sourceSize[0].xy)*float2(TV_Pixels*3.,size.y*2.);
#endif
#ifdef USE_SCANLINES
float scanlines = size.y * outputSize.z;
float top = fmod(q.y-0.5*scanlines*2.,2.);
float bottom = top+frac(scanlines)*2.;
float2 sw = saturate(min(float2(1.,2.),float2(bottom, bottom))
-max(float2(0.,1.),float2(top)))
+saturate(min(float2(3.,4.),float2(bottom, bottom))
-max(float2(2.,3.),float2(top)))
+floor(scanlines);
rgb = rgb*SCANLINE_MUL/(sw.x+sw.y);
/*
//old stupid method
float z =
#ifdef ANIMATE_SCANLINE
fmod(phase,2.0)+
#endif
0.5;
if (abs(fmod(q.y+0.5,2)-z)<0.5)
rgb *= dark_scanline;
*/
#endif
// size of pixel screen in texture coords:
//float output_pixel_size = sourceSize[0].x/(outputSize.x*sourceSize[0].x);
// correctness check
//if (fmod(p.x*output_pixel_size,2.0) < 1.0)
// rgb = float3(0.,0.,0.);
#ifdef USE_COLORIMETRY
float3 xyz1 = mul(RGB_to_XYZ,rgb);
float3 srgb = saturate(mul(XYZ_to_sRGB,xyz1));
float3 a1 = 12.92*srgb;
float3 a2 = 1.055*pow(srgb,float3(1./2.4))-0.055;
float3 ssrgb;
ssrgb.x = (srgb.x<0.0031308?a1.x:a2.x);
ssrgb.y = (srgb.y<0.0031308?a1.y:a2.y);
ssrgb.z = (srgb.z<0.0031308?a1.z:a2.z);
return ssrgb;
#else
return rgb;
#endif
}
// pos (left corner, sample size)
float4 monitor_sample(sampler2D tex, float2 p, float2 sample_)
{
// linear interpolation was...
// now other thing.
// http://imgur.com/m8Z8trV
// AT LAST IT WORKS!!!!
// going to check in retroarch...
float2 size = sourceSize[0].xy;
float2 next = float2(.25,1.)/size;
float2 f = frac(float2(4.,1.)*size*p);
sample_ *= float2(4.,1.)*size;
float2 l;
float2 r;
if (f.x+sample_.x < 1.)
{
l.x = f.x+sample_.x;
r.x = 0.;
}
else
{
l.x = 1.-f.x;
r.x = min(1.,f.x+sample_.x-1.);
}
if (f.y+sample_.y < 1.)
{
l.y = f.y+sample_.y;
r.y = 0.;
}
else
{
l.y = 1.-f.y;
r.y = min(1.,f.y+sample_.y-1.);
}
float3 top = mix(monitor(tex, p), monitor(tex, p+float2(next.x,0.)), r.x/(l.x+r.x));
float3 bottom = mix(monitor(tex, p+float2(0.,next.y)), monitor(tex, p+next), r.x/(l.x+r.x));
return float4(mix(top,bottom, r.y/(l.y+r.y)),1.0);
}
void main() {
#ifdef USE_SAMPLED
fragColor = vec4(monitor_sample(source[0], texCoord, outputSize.zw).rgb, 1.0);
#else
fragColor = float4(monitor(source[0], texCoord), 1.);
#endif
#version 150
// NES PAL composite signal simulation for RetroArch
// shader by r57shell
// thanks to feos & HardWareMan & NewRisingSun
// also TV subpixels and scanlines
// LICENSE: PUBLIC DOMAIN
// NOTE: for nice TV subpixels and scanlines I recommend to
// disable this features here and apply CRT-specialized shader.
// Quality considerations
// there are three main options:
// USE_RAW (R), USE_DELAY_LINE (D), USE_COLORIMETRY (C)
// here is table of quality in decreasing order:
// RDC, RD, RC, DC, D, C
// compatibility macros
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define frac(c) fract(c)
#define saturate(c) clamp(c, 0.0, 1.0)
#define fmod(x,y) mod(x,y)
#define mul(x,y) (y*x)
#define float2x2 mat2
#define float3x3 mat3
#define float4x4 mat4
#define bool2 bvec2
#define bool3 bvec3
#define bool4 bvec4
#define static
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 outputSize;
uniform int phase;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
// TWEAKS start
// use delay line technique
// without delay line technique, color would interleave
// to avoid this, set HueRotation to zero.
#define USE_DELAY_LINE
// use this if you need to swap even/odd V sign.
// sign of V changes each scanline
// so if some scanline is positive, then next is negative
// and if you want to match picture
// to actual running PAL NES on TV
// you may want to have this option, to change signs
// if they don't match
//#define SWAP_VSIGN
// rough simulation of scanlines
// better if you use additional shader instead
// if you still use it, make sure that SizeY
// is at least twice lower than output height
#define USE_SCANLINES // FIXME: scanlines are broken and I'm too lazy to fix it right now
// to change gamma of virtual TV from 2.2 to something else
#define USE_GAMMA
// use sampled version. it's much more slower version of shader.
// because it is computing x4 more values. NOT RECOMMENDED.
//#define USE_SAMPLED
#ifndef PARAMETER_UNIFORM
// NTSC standard gamma = 2.2
// PAL standard gamma = 2.8
// according to many sources, very unlikely gamma of TV is 2.8
// most likely gamma of PAL TV is in range 2.4-2.5
const float Gamma_static = 2.8; // gamma of virtual TV
const float Brightness_static = 0.25;
const float Contrast_static = 1.1;
const float Saturation_static = 1.1;
const int
Ywidth_static = 12,
Uwidth_static = 23,
Vwidth_static = 23;
#define Brightness Brightness_static
#define Gamma Gamma_static
#define Ywidth Ywidth_static
#define Uwidth Uwidth_static
#define Vwidth Vwidth_static
#define SCANLINE_MUL (sw.x*dark_scanline+sw.y)
int Mwidth = int(max(float(Ywidth), max(float(Uwidth), float(Vwidth))));
// correct one is -2.5
// works only with USE_RAW
const float HueShift = -2.5;
// rotation of hue due to luma level.
const float HueRotation = 2.;
// touch this only if you know what you doing
const float Phase_Y = 2.; // fmod(341*10,12)
const float Phase_One = 0.; // alternating phases.
const float Phase_Two = 8.;
// screen size, scanlines = y*2; y one field, and y other field.
const int SizeX = 256;
const int SizeY = 240;
// count of pixels of virtual TV.
// value close to 1000 produce small artifacts
const int TV_Pixels = 400;
const float dark_scanline = 0.5; // half
#endif
// this is using following matrixes.
// it provides more scientific approach
// by conversion into linear XYZ space
// and back to sRGB.
// it's using Gamma setting too.
// define USE_GAMMA is not required.
#define USE_COLORIMETRY
const float3x3 RGB_to_XYZ =
mat3(
0.4306190, 0.3415419, 0.1783091,
0.2220379, 0.7066384, 0.0713236,
0.0201853, 0.1295504, 0.9390944
);
const float3x3 XYZ_to_sRGB =
mat3(
3.2406, -1.5372, -0.4986,
-0.9689, 1.8758, 0.0415,
0.0557, -0.2040, 1.0570
);
// TWEAKS end
const float YUV_u = 0.492;
const float YUV_v = 0.877;
const mat3 RGB_to_YUV =
mat3(
float3( 0.299, 0.587, 0.114), //Y
float3(-0.299,-0.587, 0.886)*YUV_u, //B-Y
float3( 0.701,-0.587,-0.114)*YUV_v //R-Y
);
#ifdef USE_DELAY_LINE
const float comb_line = 1.;
#else
const float comb_line = 2.;
#endif
static const float Voltage_0 = 0.518;
static const float Voltage_1 = 1.962;
static const float DeltaV = (Voltage_1-Voltage_0);
float RGB_y = Contrast_static/Ywidth_static/DeltaV;
float RGB_u = comb_line*Contrast_static*Saturation_static/YUV_u/Uwidth_static/DeltaV;
float RGB_v = comb_line*Contrast_static*Saturation_static/YUV_v/Vwidth_static/DeltaV;
mat3 YUV_to_RGB =
mat3(
float3(1., 1., 1.)*RGB_y,
float3(0., -0.114/0.587, 1.)*RGB_u,
float3(1., -0.299/0.587, 0.)*RGB_v
);
const float pi = 3.1415926535897932384626433832795;
float sinn(float x)
{
return sin(/*fmod(x,24)*/x*(pi*2./24.));
}
float coss(float x)
{
return cos(/*fmod(x,24)*/x*(pi*2./24.));
}
float3 monitor(sampler2D tex, float2 p)
{
float2 size = sourceSize[0].xy;//float2(SizeX,SizeY);
// align vertical coord to center of texel
float2 uv = float2(
p.x,
(floor(p.y*sourceSize[0].y)+0.5)/sourceSize[0].y);
#ifdef USE_DELAY_LINE
float2 sh = (sourceSize[0].xy/sourceSize[0].xy/size)*float2(14./10.,-1.0);
#endif
float2 pc = uv*sourceSize[0].xy/sourceSize[0].xy*size*float2(10.,1.);
float alpha = dot(floor(float2(pc.x,pc.y)),float2(2.,Phase_Y*2.));
alpha += Phase_One*2.;
// 1/size.x of screen in uv coords = sourceSize[0].x/sourceSize[0].x/size.x;
// then 1/10*size.x of screen:
float ustep = sourceSize[0].x/sourceSize[0].x/size.x/10.;
float border = sourceSize[0].x/sourceSize[0].x;
float ss = 2.0;
#ifdef SWAP_VSIGN
#define PAL_SWITCH(A) A < 1.
#else
#define PAL_SWITCH(A) A > 1.
#endif
if (PAL_SWITCH(fmod(uv.y*sourceSize[0].y/sourceSize[0].y*size.y,2.0)))
{
// cos(pi-alpha) = -cos(alpha)
// sin(pi-alpha) = sin(alpha)
// pi - alpha
alpha = -alpha+12012.0;
ss = -2.0;
}
float ysum = 0., usum = 0., vsum = 0.;
for (int i=0; i<Mwidth; ++i)
{
float4 res = texture(tex, uv);
float3 yuv = mul(RGB_to_YUV, res.xyz);
float a1 = alpha+(HueShift+2.5)*2.-yuv.x*ss*HueRotation;
float sig = yuv.x+dot(yuv.yz,sign(float2(sinn(a1),coss(a1))));
#ifdef USE_DELAY_LINE
float4 res1 = texture(tex, uv+sh);
float3 yuv1 = mul(RGB_to_YUV, res1.xyz);
float a2 = (HueShift+2.5)*2.+12012.0-alpha+yuv.x*ss*HueRotation;
float sig1 = yuv1.x+dot(yuv1.yz,sign(float2(sinn(a2),coss(a2))));
#endif
if (i < Ywidth)
ysum += sig;
#ifdef USE_DELAY_LINE
if (i < Uwidth)
usum += (sig+sig1)*sinn(alpha);
if (i < Vwidth)
vsum += (sig-sig1)*coss(alpha);
#else
if (i < Uwidth)
usum += sig*sinn(alpha);
if (i < Vwidth)
vsum += sig*coss(alpha);
#endif
alpha -= ss;
uv.x -= ustep;
}
float3 rgb = mul(float3(ysum+Brightness*Ywidth_static,usum,vsum), YUV_to_RGB);
#if defined(USE_GAMMA) && !defined(USE_COLORIMETRY)
float3 rgb1 = saturate(rgb);
rgb = pow(rgb1, Gamma/2.2);
#endif
#ifdef USE_COLORIMETRY
float3 rgb1 = saturate(rgb);
rgb = pow(rgb1, float3(Gamma, Gamma, Gamma));
#endif
#if (defined(USE_SCANLINES))
float2 q = (p*sourceSize[0].xy/sourceSize[0].xy)*float2(TV_Pixels*3.,size.y*2.);
#endif
#ifdef USE_SCANLINES
float scanlines = size.y * outputSize.z;
float top = fmod(q.y-0.5*scanlines*2.,2.);
float bottom = top+frac(scanlines)*2.;
float2 sw = saturate(min(float2(1.,2.),float2(bottom, bottom))
-max(float2(0.,1.),float2(top)))
+saturate(min(float2(3.,4.),float2(bottom, bottom))
-max(float2(2.,3.),float2(top)))
+floor(scanlines);
rgb = rgb*SCANLINE_MUL/(sw.x+sw.y);
/*
//old stupid method
float z =
#ifdef ANIMATE_SCANLINE
fmod(phase,2.0)+
#endif
0.5;
if (abs(fmod(q.y+0.5,2)-z)<0.5)
rgb *= dark_scanline;
*/
#endif
// size of pixel screen in texture coords:
//float output_pixel_size = sourceSize[0].x/(outputSize.x*sourceSize[0].x);
// correctness check
//if (fmod(p.x*output_pixel_size,2.0) < 1.0)
// rgb = float3(0.,0.,0.);
#ifdef USE_COLORIMETRY
float3 xyz1 = mul(RGB_to_XYZ,rgb);
float3 srgb = saturate(mul(XYZ_to_sRGB,xyz1));
float3 a1 = 12.92*srgb;
float3 a2 = 1.055*pow(srgb,float3(1./2.4))-0.055;
float3 ssrgb;
ssrgb.x = (srgb.x<0.0031308?a1.x:a2.x);
ssrgb.y = (srgb.y<0.0031308?a1.y:a2.y);
ssrgb.z = (srgb.z<0.0031308?a1.z:a2.z);
return ssrgb;
#else
return rgb;
#endif
}
// pos (left corner, sample size)
float4 monitor_sample(sampler2D tex, float2 p, float2 sample_)
{
// linear interpolation was...
// now other thing.
// http://imgur.com/m8Z8trV
// AT LAST IT WORKS!!!!
// going to check in retroarch...
float2 size = sourceSize[0].xy;
float2 next = float2(.25,1.)/size;
float2 f = frac(float2(4.,1.)*size*p);
sample_ *= float2(4.,1.)*size;
float2 l;
float2 r;
if (f.x+sample_.x < 1.)
{
l.x = f.x+sample_.x;
r.x = 0.;
}
else
{
l.x = 1.-f.x;
r.x = min(1.,f.x+sample_.x-1.);
}
if (f.y+sample_.y < 1.)
{
l.y = f.y+sample_.y;
r.y = 0.;
}
else
{
l.y = 1.-f.y;
r.y = min(1.,f.y+sample_.y-1.);
}
float3 top = mix(monitor(tex, p), monitor(tex, p+float2(next.x,0.)), r.x/(l.x+r.x));
float3 bottom = mix(monitor(tex, p+float2(0.,next.y)), monitor(tex, p+next), r.x/(l.x+r.x));
return float4(mix(top,bottom, r.y/(l.y+r.y)),1.0);
}
void main() {
#ifdef USE_SAMPLED
fragColor = vec4(monitor_sample(source[0], texCoord, outputSize.zw).rgb, 1.0);
#else
fragColor = float4(monitor(source[0], texCoord), 1.);
#endif
}
+1
View File
@@ -10,6 +10,7 @@ auto ControllerPort::load(Node::Object parent) -> void {
port->setType("Controller");
port->setHotSwappable(true);
port->setAllocate([&](auto name) { return allocate(name); });
port->setDisconnect([&] { device.reset(); });
port->setSupported({"Gamepad"});
}
+1
View File
@@ -24,6 +24,7 @@ auto CPU::main() -> void {
}
auto CPU::step(u32 clocks) -> void {
if(io.rdyLine == 1) io.scanlineCycles += clocks;
Thread::step(clocks);
Thread::synchronize();
}
+1
View File
@@ -42,6 +42,7 @@ struct CPU : MOS6502, Thread {
//protected:
struct IO {
n1 rdyLine = 1;
n32 scanlineCycles = 0;
} io;
};
+1 -1
View File
@@ -5,7 +5,7 @@ auto CPU::Debugger::load(Node::Object parent) -> void {
auto CPU::Debugger::instruction() -> void {
if(tracer.instruction->enabled() && tracer.instruction->address(cpu.PC)) {
tracer.instruction->notify(cpu.disassembleInstruction(), cpu.disassembleContext());
tracer.instruction->notify(cpu.disassembleInstruction(), {cpu.disassembleContext(), " [c:", cpu.io.scanlineCycles, " l:", tia.io.vcounter, " p:", tia.io.hcounter, "]"});
}
}
+2
View File
@@ -1,5 +1,7 @@
inline auto CPU::readBus(n16 address) -> n8 {
address &= 0x1fff;
if(auto result = platform->cheat(address)) return *result;
n8 data = cartridge.read(address);
if(address.bit(12) == 0 && address.bit(7) == 0) {
+3 -2
View File
@@ -1,6 +1,8 @@
auto CPU::read(n16 address) -> n8 {
step(1);
if(io.rdyLine == 0) {
while (io.rdyLine == 0) {
while(io.rdyLine == 0) {
step(1);
}
@@ -8,7 +10,6 @@ auto CPU::read(n16 address) -> n8 {
return MDR;
}
step(1);
MDR = readBus(address);
return MDR;
}
+13 -4
View File
@@ -7,12 +7,18 @@ auto RIOT::writeRam(n8 address, n8 data) -> void {
}
auto RIOT::readIo(n8 address) -> n8 {
switch(address) {
switch(address.bit(0, 2)) {
case 0x00: return readPortA();
case 0x01: return port[0].direction;
case 0x02: return readPortB();
case 0x03: return port[1].direction;
case 0x04: return timer.counter;
case 0x04: timer.interruptFlag = address.bit(3); return timer.counter;
case 0x05: case 0x07: {
n8 output = 0;
output.bit(6) = 0; //TODO: PA7 IRQ Flag
output.bit(7) = timer.interruptFlag;
return output;
}
}
debug(unimplemented, "[RIOT] IO read ", hex(address));
@@ -25,11 +31,14 @@ auto RIOT::writeIo(n8 address, n8 data) -> void {
case 0x01: port[0].direction = data; return;
case 0x02: writePortB(data); return;
case 0x03: port[1].direction = data; return;
case 0x14: case 0x15: case 0x16: case 0x17: {
case 0x14: case 0x15: case 0x16: case 0x17:
case 0x1c: case 0x1d: case 0x1e: case 0x1f: {
const n16 intervals[] = {1, 8, 64, 1024};
timer.counter = data;
timer.interval = intervals[address - 0x14];
timer.interval = intervals[address.bit(0, 1)];
timer.reload = timer.interval;
timer.interruptFlag = 0;
timer.interruptEnable = address.bit(3);
return; }
}
+9 -13
View File
@@ -19,18 +19,12 @@ auto RIOT::unload() -> void {
}
auto RIOT::main() -> void {
decrementTimer();
step(1);
}
auto RIOT::decrementTimer() -> void {
if(--timer.interval == 0) {
if(--timer.counter == 0xff) {
timer.reload = 1;
}
timer.interval = timer.reload;
if(--timer.counter == 0xff) {
timer.interval = 1;
timer.interruptFlag = 1;
}
step(timer.interval);
}
auto RIOT::step(u32 clocks) -> void {
@@ -41,8 +35,10 @@ auto RIOT::step(u32 clocks) -> void {
auto RIOT::power(bool reset) -> void {
Thread::create(system.frequency() / 3, {&RIOT::main, this});
timer = {};
port[0] = {.data = 0xff};
port[1] = {.data = 0xff};
port[0] = {};
port[0].data = 0xff;
port[1] = {};
port[1].data = 0xff;
leftDifficulty = 1;
rightDifficulty = 1;
tvType = 1;
+2
View File
@@ -30,6 +30,8 @@ struct RIOT : Thread {
u8 counter;
n16 interval;
n16 reload;
n1 interruptEnable;
n1 interruptFlag;
} timer;
struct Port {
+2
View File
@@ -6,6 +6,8 @@ auto RIOT::serialize(serializer& s) -> void {
s(timer.counter);
s(timer.interval);
s(timer.reload);
s(timer.interruptEnable);
s(timer.interruptFlag);
for(auto n : range(2)) {
s(port[n].data);
+2
View File
@@ -1,3 +1,5 @@
static const string SerializerVersion = "v132";
auto System::serialize(bool synchronize) -> serializer {
if(synchronize) scheduler.enter(Scheduler::Mode::Synchronize);
serializer s;
+2 -2
View File
@@ -20,7 +20,7 @@ struct System {
auto name() const -> string { return information.name; }
auto region() const -> Region { return information.region; }
auto frequency() const -> u32 { return information.frequency; }
auto frequency() const -> f64 { return information.frequency; }
//system.cpp
auto game() -> string;
@@ -39,7 +39,7 @@ private:
struct Information {
string name = "Atari 2600";
Region region = Region::NTSC;
u32 frequency = Constants::Colorburst::NTSC;
f64 frequency = Constants::Colorburst::NTSC;
} information;
//serialization.cpp
+10 -16
View File
@@ -33,9 +33,9 @@ auto TIA::write(n8 address, n8 data) -> void {
case 0x0a: ctrlpf(data); return; // CTRLPF
case 0x0b: writeQueue.add(address, data, 1); return; // REFP0
case 0x0c: writeQueue.add(address, data, 1); return; // REFP1
case 0x0d: writeQueue.add(address, data, 6); return; // PF0
case 0x0e: writeQueue.add(address, data, 6); return; // PF1
case 0x0f: writeQueue.add(address, data, 6); return; // PF2
case 0x0d: writeQueue.add(address, data, 2); return; // PF0
case 0x0e: writeQueue.add(address, data, 2); return; // PF1
case 0x0f: writeQueue.add(address, data, 2); return; // PF2
case 0x10: resp(0); return; // RESP0
case 0x11: resp(1); return; // RESP1
case 0x12: resm(0); return; // RESM0
@@ -47,8 +47,8 @@ auto TIA::write(n8 address, n8 data) -> void {
case 0x18: audio[1].frequency = data; return; // AUDF1
case 0x19: audio[0].volume = data; return; // AUDV0
case 0x1a: audio[1].volume = data; return; // AUDV1
case 0x1b: writeQueue.add(address, data, 3); return; // GRP0
case 0x1c: writeQueue.add(address, data, 3); return; // GRP1
case 0x1b: writeQueue.add(address, data, 1); return; // GRP0
case 0x1c: writeQueue.add(address, data, 1); return; // GRP1
case 0x1d: writeQueue.add(address, data, 1); return; // ENAM0
case 0x1e: writeQueue.add(address, data, 1); return; // ENAM1
case 0x1f: writeQueue.add(address, data, 1); return; // ENAB1
@@ -72,9 +72,9 @@ auto TIA::write(n8 address, n8 data) -> void {
auto TIA::vsync(n1 state) -> void {
if(io.vsync && !state) {
io.vcounter = 0;
if(!io.vsync && state) {
frame();
tia.io.vcounter = 0;
}
io.vsync = state;
@@ -125,23 +125,17 @@ auto TIA::grp(n1 index, n8 data) -> void {
}
auto TIA::resp(n1 index) -> void {
player[index].position = (io.hcounter < 68 ? 3 : io.hcounter - 68 + 8) % 160;
player[index].position = (io.hcounter - 68 + 5) % 160;
}
auto TIA::resm(n1 index) -> void {
missile[index].position = (io.hcounter < 68 ? 2 : io.hcounter - 68 + 7) % 160;
missile[index].position = (io.hcounter - 68 + 4) % 160;
}
auto TIA::resmp(n1 index, n8 data) -> void {
missile[index].reset = data.bit(1);
if(missile[index].reset) {
auto offset = 3;
if(player[index].size == 5) offset = 6;
if(player[index].size == 7) offset = 10;
missile[index].position = player[index].position + offset;
}
}
auto TIA::resbl() -> void {
ball.position = (io.hcounter < 68 ? 2 : io.hcounter - 68 + 7);
ball.position = (io.hcounter - 68 + 4) % 160;
}
+66 -17
View File
@@ -13,12 +13,12 @@ TIA tia;
auto TIA::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("TIA");
screen = node->append<Node::Video::Screen>("Screen", 160, vlines());
screen = node->append<Node::Video::Screen>("Screen", 180, displayHeight());
screen->colors(1 << 7, {&TIA::color, this});
screen->setSize(160, vlines());
screen->setSize(180, displayHeight());
screen->setScale(2.0, 1.0);
screen->setAspect(1.0, 1.0);
screen->setViewport(0, 0, 160, vlines());
Region::PAL() ? screen->setAspect(38.0, 45.0) : screen->setAspect(4.0, 5.0);
screen->setViewport(0, 0, 180, displayHeight());
stream = node->append<Node::Audio::Stream>("Audio");
stream->setChannels(1);
@@ -35,24 +35,35 @@ auto TIA::unload() -> void {
}
auto TIA::main() -> void {
scanline();
io.vcounter++;
io.hmoveTriggered = 255;
scanline();
io.vcounter++;
io.hmoveTriggered = 255;
}
auto TIA::scanline() -> void {
cpu.rdyLine(1);
cpu.io.scanlineCycles = 0;
for(io.hcounter = 0; io.hcounter < 228; io.hcounter++) {
auto x = io.hcounter - 68;
if(x >= 0) pixel(x);
writeQueue.step();
auto x = io.hcounter - 68;
auto y = io.vcounter - voffset();
if(x >= 0 && y > 0 && y < vlines()) pixel(x);
runAudio();
step();
if(io.hcounter == 0) cpu.io.rdyLine = 1;
}
// Prevent an infinite emulator hang when games miss vblank
if(io.vcounter > vlines()) {
scheduler.exit(Event::Frame);
io.vcounter = 0;
}
}
auto TIA::pixel(n8 x) -> void {
auto output = screen->pixels().data() + (io.vcounter * 160);
auto y = io.vcounter - voffset();
auto output = screen->pixels().data() + (y * 180) + 10;
if(y >= displayHeight()) return;
// Output only black during vblank, or for the first 8px of a scanline where hmove was triggered
if (io.vblank || (io.hmoveTriggered == io.vcounter && x < 8)) {
@@ -92,10 +103,13 @@ auto TIA::pixel(n8 x) -> void {
}
auto TIA::runPlayfield(n8 x) -> n1 {
auto pos = x >> 2;
if((x % 4) == 0) {
auto pos = x >> 2;
playfield.pixel = (!playfield.mirror || pos < 20) ? playfield.graphics.bit(pos % 20)
: playfield.graphics.bit(19 - (pos % 20));
}
if(!playfield.mirror || pos < 20) return playfield.graphics.bit(pos % 20);
return playfield.graphics.bit(19 - (pos % 20));
return playfield.pixel;
}
auto TIA::runPlayer(n8 x, n1 index) -> n1 {
@@ -130,10 +144,45 @@ auto TIA::runPlayer(n8 x, n1 index) -> n1 {
auto TIA::runMissile(n8 x, n1 index) -> n1 {
auto& missile = this->missile[index];
if (!missile.enable || missile.reset) return 0;
auto& player = this->player[index];
auto position = missile.position;
if(missile.reset) {
auto offset = 3;
if(player.size == 5) offset = 6;
if(player.size == 7) offset = 10;
missile.position = player.position + offset;
return 0;
}
if(!missile.enable) return 0;
const int missileSizes[4] = {1, 2, 4, 8};
return x >= missile.position && x < missile.position + missileSizes[missile.size];
// Handle player stretch capability
auto width = missileSizes[missile.size];
auto repeatWidth = width;
if(player.size == 5) repeatWidth *= 2;
if(player.size == 7) repeatWidth *= 4;
// Handle repeat capability
auto repeat = 1;
if(player.size == 1 || player.size == 2 || player.size == 4) repeat = 2;
if(player.size == 3 || player.size == 6) repeat = 3;
auto spacing = 8;
if(player.size == 2 || player.size == 6) spacing = 24;
if(player.size == 4 ) spacing = 56;
for(int i = 0; i < repeat; i++) {
if (x >= position && x < position + width) {
return 1;
}
position = (position + (spacing + repeatWidth)) % 160;
}
return 0;
}
auto TIA::runBall(n8 x) -> n1 {
@@ -163,7 +212,7 @@ auto TIA::power(bool reset) -> void {
ball = {};
collision = {};
for(auto n : range(writeQueue.maxItems)) writeQueue.items[n] = {};
audio[0] = {}; audio[1] = {};
for(u32 level : range(15)) {
volume[level] = pow(2, level * -2.0 / 6.0);
}
+3
View File
@@ -4,6 +4,8 @@ struct TIA : Thread {
Node::Audio::Stream stream;
auto vlines() const -> u32 { return Region::NTSC() ? 262 : 312; }
auto displayHeight() const -> u32 { return Region::PAL() ? 243 : 228; }
auto voffset() const -> s32 { return Region::PAL() ? 40 : 20; }
//tia.cpp
auto load(Node::Object) -> void;
@@ -78,6 +80,7 @@ struct TIA : Thread {
struct {
n20 graphics;
n1 pixel;
n1 mirror;
n1 scoreMode;
n1 priority;
+10
View File
@@ -1,5 +1,6 @@
#include <ares/ares.hpp>
#include <ares/debug/debug.cpp>
#include <nall/gdb/server.cpp>
#include <ares/node/node.cpp>
#include <ares/resource/resource.cpp>
@@ -8,4 +9,13 @@ namespace ares {
Platform* platform = nullptr;
bool _runAhead = false;
const string Name = "ares";
const string Version = "136";
const string Copyright = "ares team, Near";
const string License = "ISC";
const string LicenseURI = "https://opensource.org/licenses/ISC";
const string Website = "ares-emu.net";
const string WebsiteURI = "https://ares-emu.net/";
const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
}
+11 -11
View File
@@ -8,10 +8,12 @@
#include <nall/any.hpp>
#include <nall/array.hpp>
#include <nall/bump-allocator.hpp>
#include <nall/case-range.hpp>
#include <nall/chrono.hpp>
#include <nall/directory.hpp>
#include <nall/dl.hpp>
#include <nall/endian.hpp>
#include <nall/hashset.hpp>
#include <nall/image.hpp>
#include <nall/literals.hpp>
#include <nall/priority-queue.hpp>
@@ -35,19 +37,17 @@
#include <nall/hash/crc32.hpp>
#include <nall/hash/sha256.hpp>
using namespace nall;
using namespace nall::primitives;
namespace ares {
static const string Name = "ares";
static const string Version = "129";
static const string Copyright = "ares team, Near";
static const string License = "ISC";
static const string LicenseURI = "https://opensource.org/licenses/ISC";
static const string Website = "ares-emu.net";
static const string WebsiteURI = "https://ares-emu.net/";
//incremented only when serialization format changes
static const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
static const string SerializerVersion = "129";
extern const string Name;
extern const string Version;
extern const string Copyright;
extern const string License;
extern const string LicenseURI;
extern const string Website;
extern const string WebsiteURI;
extern const u32 SerializerSignature;
namespace VFS {
using Pak = shared_pointer<vfs::directory>;
+4 -4
View File
@@ -4,19 +4,19 @@ struct Debug {
auto reset() -> void;
template<typename... P> auto unhandled(P&&... p) -> void {
return _unhandled({forward<P>(p)...});
return _unhandled({std::forward<P>(p)...});
}
template<typename... P> auto unimplemented(P&&... p) -> void {
return _unimplemented({forward<P>(p)...});
return _unimplemented({std::forward<P>(p)...});
}
template<typename... P> auto unusual(P&&... p) -> void {
return _unusual({forward<P>(p)...});
return _unusual({std::forward<P>(p)...});
}
template<typename... P> auto unverified(P&&... p) -> void {
return _unverified({forward<P>(p)...});
return _unverified({std::forward<P>(p)...});
}
private:
+22 -8
View File
@@ -1,18 +1,32 @@
#include <ares/ares.hpp>
#if !defined(PLATFORM_MACOS)
#define STATIC_ALLOCATION
#endif
namespace ares::Memory {
#if defined(PLATFORM_MACOS) && defined(ARCHITECTURE_ARM64)
//stub for unsupported platforms
FixedAllocator::FixedAllocator() {
}
#else
alignas(4096) u8 fixedBuffer[128_MiB];
constexpr u32 fixedBufferSize = 128_MiB;
#if defined(STATIC_ALLOCATION)
u8 fixedBuffer[fixedBufferSize + 64_KiB];
#endif
FixedAllocator::FixedAllocator() {
_allocator.resize(sizeof(fixedBuffer), 0, fixedBuffer);
u8* buffer = nullptr;
#if defined(STATIC_ALLOCATION)
//align to 64 KiB (maximum page size of any supported OS)
auto offset = -(uintptr)fixedBuffer % 64_KiB;
//set protection to executable
if(memory::protect(fixedBuffer + offset, fixedBufferSize, true)) {
//use static allocation
buffer = fixedBuffer + offset;
}
#endif
_allocator.resize(fixedBufferSize, bump_allocator::executable, buffer);
}
#endif
auto FixedAllocator::get() -> bump_allocator& {
static FixedAllocator allocator;
+14 -14
View File
@@ -1,14 +1,14 @@
#pragma once
namespace ares::Memory {
struct FixedAllocator {
static auto get() -> bump_allocator&;
private:
FixedAllocator();
bump_allocator _allocator;
};
}
#pragma once
namespace ares::Memory {
struct FixedAllocator {
static auto get() -> bump_allocator&;
private:
FixedAllocator();
bump_allocator _allocator;
};
}
+1 -1
View File
@@ -25,7 +25,7 @@ struct Stream : Audio {
template<typename... P>
auto frame(P&&... p) -> void {
if(runAhead()) return;
f64 samples[sizeof...(p)] = {forward<P>(p)...};
f64 samples[sizeof...(p)] = {f64(std::forward<P>(p))...};
write(samples);
}
+35 -20
View File
@@ -18,13 +18,14 @@ struct Instruction : Tracer {
auto setMask(bool mask) -> void {
_mask = mask;
_masks.reset();
}
auto setDepth(u32 depth) -> void {
_depth = depth;
_history.reset();
_history.resize(depth);
for(auto& history : _history) history = ~0;
for(auto& history : _history) history = ~0ull;
}
auto address(u64 address) -> bool {
@@ -32,9 +33,10 @@ struct Instruction : Tracer {
_address = address;
address >>= _addressMask; //clip unneeded alignment bits (to reduce _masks size)
if(_mask && updateMasks()) {
if(_masks[address >> 3] & 1 << (address & 7)) return false; //do not trace twice
_masks[address >> 3] |= 1 << (address & 7);
if(_mask) {
auto mask = _masks.find(address);
if(!mask) mask = _masks.insert(address);
if(mask->visit(address)) return false; //do not trace twice
}
if(_depth) {
@@ -56,10 +58,12 @@ struct Instruction : Tracer {
//mark an already-executed address as not executed yet for trace masking.
//call when writing to executable RAM to support self-modifying code.
auto invalidate(u64 address) -> void {
if(unlikely(_mask && updateMasks())) {
if(unlikely(_mask)) {
address &= ~0ull >> (64 - _addressBits);
address >>= _addressMask;
_masks[address >> 3] &= ~(1 << (address & 7));
auto mask = _masks.find(address);
if(mask) mask->unvisit(address);
}
}
@@ -67,9 +71,7 @@ struct Instruction : Tracer {
if(!enabled()) return;
if(_omitted) {
PlatformLog({
"[Omitted: ", _omitted, "]\n"}
);
PlatformLog(shared(), {"[Omitted: ", _omitted, "]"});
_omitted = 0;
}
@@ -80,7 +82,7 @@ struct Instruction : Tracer {
context, " ",
extra
};
PlatformLog({output.strip(), "\n"});
PlatformLog(shared(), {output.strip()});
}
auto serialize(string& output, string depth) -> void override {
@@ -103,14 +105,27 @@ struct Instruction : Tracer {
}
protected:
auto updateMasks() -> bool {
auto size = 1ull << (_addressBits - _addressMask - 3);
if(!_mask || !size) return _masks.reset(), false;
if(_masks.size() == size) return true;
_masks.reset();
_masks.resize(size);
return true;
}
struct VisitMask {
VisitMask(u64 address) : upper(address >> 6), mask(0) {}
auto operator==(const VisitMask& source) const -> bool { return upper == source.upper; }
auto hash() const -> u32 { return upper; }
auto visit(u64 address) -> bool {
const u64 bit = 1ull << (address & 0x3f);
if(mask & bit) return true;
mask |= bit;
return false;
}
auto unvisit(u64 address) -> void {
const u64 bit = 1ull << (address & 0x3f);
mask &= ~bit;
}
private:
u64 upper;
u64 mask;
};
u32 _addressBits = 32;
u32 _addressMask = 0;
@@ -120,6 +135,6 @@ protected:
//unserialized:
n64 _address = 0;
n64 _omitted = 0;
vector<u32> _history;
vector<u08> _masks;
vector<u64> _history;
hashset<VisitMask> _masks;
};
@@ -6,12 +6,7 @@ struct Notification : Tracer {
auto notify(const string& message = {}) -> void {
if(!enabled()) return;
if(message) {
PlatformLog({_component, " ", _name, ": ", message, "\n"});
} else {
PlatformLog({_component, " ", _name, "\n"});
}
PlatformLog(shared(), message);
}
protected:
+21 -5
View File
@@ -6,24 +6,40 @@ struct Tracer : Debugger {
}
auto component() const -> string { return _component; }
auto enabled() const -> bool { return _enabled; }
auto enabled() const -> bool { return file() || terminal(); }
auto prefix() const -> bool { return _prefix; }
auto terminal() const -> bool { return _terminal; }
auto file() const -> bool { return _file; }
auto autoLineBreak() const -> bool { return _autoLineBreak; }
auto setToggle(function<void ()> toggle) -> void { _toggle = toggle; }
auto setComponent(string component) -> void { _component = component; }
auto setEnabled(bool enabled) -> void { _enabled = enabled; }
auto setPrefix(bool prefix) -> void { _prefix = prefix; }
auto setTerminal(bool terminal) -> void { _terminal = terminal; if(_toggle) _toggle(); }
auto setFile(bool file) -> void { _file = file; if(_toggle) _toggle(); }
auto setAutoLineBreak(bool autoLineBreak) -> void { _autoLineBreak = autoLineBreak; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
output.append(depth, " component: ", _component, "\n");
output.append(depth, " enabled: ", _enabled, "\n");
output.append(depth, " prefix: ", _prefix, "\n");
output.append(depth, " terminal: ", _terminal, "\n");
output.append(depth, " file: ", _file, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
_component = node["component"].string();
_enabled = node["enabled"].boolean();
_prefix = node["prefix"].boolean();
_terminal = node["terminal"].boolean();
_file = node["file"].boolean();
}
protected:
function<void ()> _toggle;
string _component;
bool _enabled = false;
bool _prefix = false;
bool _terminal = false;
bool _file = false;
bool _autoLineBreak = true;
};
+1
View File
@@ -1,4 +1,5 @@
struct Input : Object {
DeclareClass(Input, "input")
using Object::Object;
u64 lastPoll;
};
+11 -3
View File
@@ -2,9 +2,17 @@ struct Rumble : Input {
DeclareClass(Rumble, "input.rumble")
using Input::Input;
auto enable() const -> bool { return _enable; }
auto setEnable(bool enable) -> void { _enable = enable; }
auto weakValue() const -> u16 { return _weak; }
auto strongValue() const -> u16 { return _strong; }
auto setValues(u16 strong, u16 weak) -> void { _weak = weak; _strong = strong; }
auto setWeak(u16 weak) -> void { _weak = weak; }
auto setStrong(u16 strong) -> void { _strong = strong; }
// For systems with binary motors
auto enable() const -> bool { return _weak > 0 || _strong > 0; }
auto setEnable(bool enable) -> void { _weak = enable ? 65535 : 0; _strong = enable ? 65535 : 0; }
protected:
bool _enable = 0;
u16 _weak = 0;
u16 _strong = 0;
};
+1 -1
View File
@@ -94,7 +94,7 @@ namespace ares::Core {
// <ares/platform.hpp> forward declarations
static auto PlatformAttach(Node::Object) -> void;
static auto PlatformDetach(Node::Object) -> void;
static auto PlatformLog(string_view) -> void;
static auto PlatformLog(Node::Debugger::Tracer::Tracer tracer, string_view) -> void;
#include <ares/node/attribute.hpp>
#include <ares/node/class.hpp>
+2 -2
View File
@@ -33,7 +33,7 @@ struct Object : shared_pointer_this<Object> {
template<typename T, typename... P>
auto prepend(P&&... p) -> Node::Object {
using Type = typename T::type;
return prepend(shared_pointer<Type>::create(forward<P>(p)...));
return prepend(shared_pointer<Type>::create(std::forward<P>(p)...));
}
auto append(Node::Object node) -> Node::Object {
@@ -47,7 +47,7 @@ struct Object : shared_pointer_this<Object> {
template<typename T, typename... P>
auto append(P&&... p) -> Node::Object {
using Type = typename T::type;
return append(shared_pointer<Type>::create(forward<P>(p)...));
return append(shared_pointer<Type>::create(std::forward<P>(p)...));
}
auto remove(Node::Object node) -> void {
+20 -6
View File
@@ -76,6 +76,11 @@ auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
_viewportHeight = height;
}
auto Screen::setOverscan(bool overscan) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_overscan = overscan;
}
auto Screen::setSize(u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_width = width;
@@ -122,6 +127,11 @@ auto Screen::setColorBleed(bool colorBleed) -> void {
_colorBleed = colorBleed;
}
auto Screen::setColorBleedWidth(u32 width) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colorBleedWidth = width;
}
auto Screen::setInterframeBlending(bool interframeBlending) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interframeBlending = interframeBlending;
@@ -228,14 +238,18 @@ auto Screen::refresh() -> void {
}
}
if(_colorBleed) {
if (_colorBleed) {
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(u32 y : range(height)) {
for (u32 y : range(height)) {
auto target = output + y * width;
for(u32 x : range(width)) {
auto a = target[x];
auto b = target[x + (x != width - 1)];
target[x] = (a + b - ((a ^ b) & mask)) >> 1;
for (u32 x : range(0, width, _colorBleedWidth)) {
for (u32 offset = 0; offset < _colorBleedWidth && (x + offset) < width; ++offset) {
u32 next = x + _colorBleedWidth;
if (next + offset >= width) next = x;
auto a = target[x + offset];
auto b = target[next + offset];
target[x + offset] = (a + b - ((a ^ b) & mask)) >> 1;
}
}
}
}
+9 -4
View File
@@ -16,6 +16,7 @@ struct Screen : Video {
auto scaleY() const -> f64 { return _scaleY; }
auto aspectX() const -> f64 { return _aspectX; }
auto aspectY() const -> f64 { return _aspectY; }
auto overscan() const -> bool { return _overscan; }
auto colors() const -> u32 { return _colors; }
auto pixels(bool frame = 0) -> array_span<u32>;
@@ -37,6 +38,7 @@ struct Screen : Video {
auto setSize(u32 width, u32 height) -> void;
auto setScale(f64 scaleX, f64 scaleY) -> void;
auto setAspect(f64 aspectX, f64 aspectY) -> void;
auto setOverscan(bool overscan) -> void;
auto setSaturation(f64 saturation) -> void;
auto setGamma(f64 gamma) -> void;
@@ -44,6 +46,7 @@ struct Screen : Video {
auto setFillColor(u32 fillColor) -> void;
auto setColorBleed(bool colorBleed) -> void;
auto setColorBleedWidth(u32 width) -> void;
auto setInterframeBlending(bool interframeBlending) -> void;
auto setRotation(u32 rotation) -> void;
@@ -78,14 +81,16 @@ protected:
f64 _luminance = 1.0;
u32 _fillColor = 0;
bool _colorBleed = false;
bool _colorBleedWidth = 1;
bool _interframeBlending = false;
bool _overscan = true;
u32 _rotation = 0; //counter-clockwise (90 = left, 270 = right)
function<n64 (n32)> _color;
unique_pointer<u32> _inputA;
unique_pointer<u32> _inputB;
unique_pointer<u32> _output;
unique_pointer<u32> _rotate;
unique_pointer<u32[]> _inputA;
unique_pointer<u32[]> _inputB;
unique_pointer<u32[]> _output;
unique_pointer<u32[]> _rotate;
unique_pointer<u32[]> _palette;
vector<Node::Video::Sprite> _sprites;
+3 -2
View File
@@ -15,11 +15,12 @@ struct Platform {
virtual auto detach(Node::Object) -> void {}
virtual auto pak(Node::Object) -> shared_pointer<vfs::directory> { return {}; }
virtual auto event(Event) -> void {}
virtual auto log(string_view message) -> void {}
virtual auto log(Node::Debugger::Tracer::Tracer, string_view message) -> void {}
virtual auto status(string_view message) -> void {}
virtual auto video(Node::Video::Screen, const u32* data, u32 pitch, u32 width, u32 height) -> void {}
virtual auto audio(Node::Audio::Stream) -> void {}
virtual auto input(Node::Input::Input) -> void {}
virtual auto cheat(u32 addr) -> maybe<u32> { return nothing; }
};
extern Platform* platform;
@@ -30,5 +31,5 @@ namespace ares::Core {
// <ares/node/node.hpp> forward declarations
auto PlatformAttach(Node::Object node) -> void { if(platform && node->name()) platform->attach(node); }
auto PlatformDetach(Node::Object node) -> void { if(platform && node->name()) platform->detach(node); }
auto PlatformLog(string_view text) -> void { if(platform) platform->log(text); }
auto PlatformLog(Node::Debugger::Tracer::Tracer node, string_view text) -> void { if(platform) platform->log(node, text); }
}
+1 -1
View File
@@ -41,7 +41,7 @@ private:
vector<Thread*> _threads;
bool _synchronize = false;
friend class Thread;
friend struct Thread;
};
extern Scheduler scheduler;
+1 -1
View File
@@ -92,7 +92,7 @@ inline auto Thread::synchronize(Thread& thread, P&&... p) -> void {
co_switch(thread.handle());
}
//convenience: allow synchronizing multiple threads with one function call.
if constexpr(sizeof...(p) > 0) synchronize(forward<P>(p)...);
if constexpr(sizeof...(p) > 0) synchronize(std::forward<P>(p)...);
}
inline auto Thread::serialize(serializer& s) -> void {
+1 -1
View File
@@ -46,5 +46,5 @@ protected:
u64 _scalar = 0;
u64 _clock = 0;
friend class Scheduler;
friend struct Scheduler;
};
+10 -1
View File
@@ -12,10 +12,13 @@ ares.objects += $(if $(findstring ym2612,$(ares.components)),ares-audio-ym2612)
ares.objects += $(if $(findstring m24c,$(ares.components)),ares-eeprom-m24c)
ares.objects += $(if $(findstring m93lcx6,$(ares.components)),ares-eeprom-m93lcx6)
ares.objects += $(if $(findstring i8255,$(ares.components)),ares-io-i8255)
ares.objects += $(if $(findstring arm7tdmi,$(ares.components)),ares-processor-arm7tdmi)
ares.objects += $(if $(findstring gsu,$(ares.components)),ares-processor-gsu)
ares.objects += $(if $(findstring hg51b,$(ares.components)),ares-processor-hg51b)
ares.objects += $(if $(findstring huc6280,$(ares.components)),ares-processor-huc6280)
ares.objects += $(if $(findstring i8080,$(ares.components)),ares-processor-i8080)
ares.objects += $(if $(findstring m68hc05,$(ares.components)),ares-processor-m68hc05)
ares.objects += $(if $(findstring m68000,$(ares.components)),ares-processor-m68000)
ares.objects += $(if $(findstring mos6502,$(ares.components)),ares-processor-mos6502)
@@ -30,6 +33,8 @@ ares.objects += $(if $(findstring v30mz,$(ares.components)),ares-processor-v30mz
ares.objects += $(if $(findstring wdc65816,$(ares.components)),ares-processor-wdc65816)
ares.objects += $(if $(findstring z80,$(ares.components)),ares-processor-z80)
ares.objects += $(if $(findstring sst39sf0x0,$(ares.components)),ares-flash-sst39sf0x0)
ares.objects += $(if $(findstring tms9918,$(ares.components)),ares-video-tms9918)
ares.objects += $(if $(findstring v9938,$(ares.components)),ares-video-v9938)
@@ -39,16 +44,18 @@ $(object.path)/ares-audio-sn76489.o: $(ares.path)/component/audio/sn76489/s
$(object.path)/ares-audio-t6w28.o: $(ares.path)/component/audio/t6w28/t6w28.cpp
$(object.path)/ares-audio-ym2149.o: $(ares.path)/component/audio/ym2149/ym2149.cpp
$(object.path)/ares-audio-ym2413.o: $(ares.path)/component/audio/ym2413/ym2413.cpp
$(object.path)/ares-audio-ym2610.o: $(ares.path)/component/audio/ym2610/ym2610.cpp
$(object.path)/ares-audio-ym2612.o: $(ares.path)/component/audio/ym2612/ym2612.cpp
$(object.path)/ares-eeprom-m24c.o: $(ares.path)/component/eeprom/m24c/m24c.cpp
$(object.path)/ares-eeprom-m93lcx6.o: $(ares.path)/component/eeprom/m93lcx6/m93lcx6.cpp
$(object.path)/ares-io-i8255.o: $(ares.path)/component/io/i8255/i8255.cpp
$(object.path)/ares-processor-arm7tdmi.o: $(ares.path)/component/processor/arm7tdmi/arm7tdmi.cpp
$(object.path)/ares-processor-gsu.o: $(ares.path)/component/processor/gsu/gsu.cpp
$(object.path)/ares-processor-hg51b.o: $(ares.path)/component/processor/hg51b/hg51b.cpp
$(object.path)/ares-processor-huc6280.o: $(ares.path)/component/processor/huc6280/huc6280.cpp
$(object.path)/ares-processor-i8080.o: $(ares.path)/component/processor/i8080/i8080.cpp
$(object.path)/ares-processor-m68hc05.o: $(ares.path)/component/processor/m68hc05/m68hc05.cpp
$(object.path)/ares-processor-m68000.o: $(ares.path)/component/processor/m68000/m68000.cpp
$(object.path)/ares-processor-mos6502.o: $(ares.path)/component/processor/mos6502/mos6502.cpp
@@ -63,5 +70,7 @@ $(object.path)/ares-processor-v30mz.o: $(ares.path)/component/processor/v30mz
$(object.path)/ares-processor-wdc65816.o: $(ares.path)/component/processor/wdc65816/wdc65816.cpp
$(object.path)/ares-processor-z80.o: $(ares.path)/component/processor/z80/z80.cpp
$(object.path)/ares-flash-sst39sf0x0.o: $(ares.path)/component/flash/sst39sf0x0/sst39sf0x0.cpp
$(object.path)/ares-video-tms9918.o: $(ares.path)/component/video/tms9918/tms9918.cpp
$(object.path)/ares-video-v9938.o: $(ares.path)/component/video/v9938/v9938.cpp
+2
View File
@@ -196,9 +196,11 @@ auto AY38910::write(n8 data) -> void {
envelope.output = !envelope.attacking ? 15 : 0;
break;
case 14:
portA.data = data;
writeIO(0, data);
break;
case 15:
portB.data = data;
writeIO(1, data);
break;
}
+7 -3
View File
@@ -20,17 +20,17 @@ auto SN76489::clock() -> array<n4[4]> {
}
auto SN76489::Tone::clock() -> void {
if(!counter--) {
if(!counter || !--counter) {
counter = pitch;
output ^= 1;
}
}
auto SN76489::Noise::clock() -> void {
if(!counter--) {
if(!counter || !--counter) {
counter = array<n10[4]>{0x10, 0x20, 0x40, pitch}[rate];
if(flip ^= 1) { //0->1 transition
output = !lfsr.bit(0);
output = lfsr.bit(0);
lfsr = (lfsr.bit(0) ^ lfsr.bit(3) & enable) << 15 | lfsr >> 1;
}
}
@@ -63,6 +63,10 @@ auto SN76489::write(n8 data) -> void {
case 0: tone0.pitch.bit(4,9) = data.bit(0,5); break;
case 1: tone1.pitch.bit(4,9) = data.bit(0,5); break;
case 2: tone2.pitch.bit(4,9) = data.bit(0,5); noise.pitch = tone2.pitch; break;
case 3: noise.rate = data.bit(0,1);
noise.enable = data.bit(2);
noise.lfsr = 0x8000;
break;
}
}
}
-47
View File
@@ -1,47 +0,0 @@
auto YM2610::read(n2 address) -> n8 {
switch(address) {
case 0: return fm.readStatus();
}
return 0;
}
auto YM2610::write(n2 address, n8 data) -> void {
switch(address) {
case 0: register = 0x000 | data; return;
case 1: return writeLower(data);
case 2: register = 0x100 | data; return;
case 3: return writeUpper(data);
}
}
auto YM2610::writeLower(n8 data) -> void {
switch(register) {
case 0x000 ... 0x00f:
ssg.select(register);
ssg.write(data);
return;
case 0x010 ... 0x01b:
//ADPCM-B
return;
case 0x01c:
//EOS
return;
case 0x01d ... 0x1ff:
fm.writeAddress(register);
fm.writeData(data);
return;
}
unreachable;
}
auto YM2610::writeUpper(n8 data) -> void {
switch(register) {
case 0x000 ... 0x12f:
//ADPCM-A
return;
case 0x130 ... 0x1ff:
fm.writeAddress(register);
fm.writeData(data);
return;
}
}
@@ -1,5 +0,0 @@
auto YM2610::serialize(serializer& s) -> void {
s(register);
s(fm);
s(ssg);
}
-14
View File
@@ -1,14 +0,0 @@
#include <ares/ares.hpp>
#include "ym2610.hpp"
namespace ares {
#include "io.cpp"
#include "serialization.cpp"
auto YM2610::power() -> void {
fm.power();
ssg.power();
}
}
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include <component/audio/ym2612/ym2612.hpp>
#include <component/audio/ym2149/ym2149.hpp>
namespace ares {
//Yamaha YM2610 (OPNB)
struct YM2610 {
//ym2610.cpp
auto power() -> void;
//io.cpp
auto read(n2 address) -> n8;
auto write(n2 address, n8 data) -> void;
auto writeLower(n8 data) -> void;
auto writeUpper(n8 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
protected:
n9 register;
YM2612 fm;
YM2149 ssg;
};
}
+33 -31
View File
@@ -1,9 +1,6 @@
auto YM2612::Channel::Operator::trigger(bool state) -> void {
if(keyOn == state) return; //no change
keyOn = state;
envelope.state = Release;
updateEnvelope();
auto YM2612::Channel::Operator::updateKeyState() -> void {
if(keyOn == keyLine) return; //no change
keyOn = keyLine;
if(keyOn) {
//restart phase and envelope generators
@@ -13,64 +10,69 @@ auto YM2612::Channel::Operator::trigger(bool state) -> void {
updateEnvelope();
if(envelope.rate >= 62) {
//skip attack and possibly decay stages
//skip attack phase
envelope.value = 0;
envelope.state = envelope.sustainLevel ? Decay : Sustain;
updateEnvelope();
}
} else if(ssg.enable && ssg.attack != ssg.invert) {
//SSG-EG key-off
envelope.value = 0x200 - envelope.value;
} else {
envelope.state = Release;
updateEnvelope();
if(ssg.enable && ssg.attack != ssg.invert) {
//SSG-EG key-off
envelope.value = 0x200 - envelope.value;
}
}
updateLevel();
}
auto YM2612::Channel::Operator::runEnvelope() -> void {
u32 sustain = envelope.sustainLevel < 15 ? envelope.sustainLevel << 5 : 0x3f0;
if(ym2612.envelope.clock & (1 << envelope.divider) - 1) return;
u32 value = ym2612.envelope.clock >> envelope.divider;
u32 step = envelope.steps >> ((~value & 7) << 2) & 0xf;
if(ssg.enable) step <<= 2; //SSG results in a 4x faster envelope
u32 sustain = envelope.sustainLevel < 15 ? envelope.sustainLevel << 5 : 0x1f << 5;
if(envelope.state == Attack) {
u32 next = envelope.value + (~u16(envelope.value) * step >> 4) & 0x3ff;
if(next <= envelope.value) {
envelope.value = next;
} else {
envelope.value = 0;
envelope.state = envelope.value < sustain ? Decay : Sustain;
if(envelope.value == 0) {
envelope.state = Decay;
updateEnvelope();
} else if(envelope.rate < 62) {
// will stop updating if attack rate is increased to upper threshold during attack phase (confirmed behavior)
envelope.value += ~u16(envelope.value) * step >> 4;
}
} else if(!ssg.enable || envelope.value < 0x200) {
envelope.value = min(envelope.value + step, 0x3ff);
}
if(envelope.state != Attack) {
if(envelope.state == Decay && envelope.value >= sustain) {
envelope.state = Sustain;
updateEnvelope();
}
if(ssg.enable) step = envelope.value < 0x200 ? step << 2 : 0; //SSG results in a 4x faster envelope
envelope.value = min(envelope.value + step, 0x3ff);
}
updateLevel();
}
auto YM2612::Channel::Operator::runPhase() -> void {
updateKeyState();
phase.value += phase.delta; //advance wave position
if(!(ssg.enable && envelope.value >= 0x200)) return; //SSG loop check
if(!ssg.hold && !ssg.alternate) phase.value = 0;
if(!ssg.hold || ssg.attack == ssg.invert) ssg.invert ^= ssg.alternate;
if(!(ssg.hold && ssg.invert)) ssg.invert ^= ssg.alternate;
if(envelope.state == Attack) {
//do nothing; SSG is meant to skip the attack phase
} else if(envelope.state != Release && !ssg.hold) {
//if still looping, reset the envelope
envelope.state = Attack;
if(envelope.attackRate >= 62) {
envelope.value = 0;
envelope.state = envelope.sustainLevel ? Decay : Sustain;
}
updateEnvelope();
if(envelope.rate >= 62) {
//skip attack phase
envelope.value = 0;
}
} else if(envelope.state == Release || (ssg.hold && ssg.attack == ssg.invert)) {
//clear envelope once finished
envelope.value = 0x3ff;
@@ -115,11 +117,9 @@ auto YM2612::Channel::Operator::updatePhase() -> void {
u32 tuning = detune & 3 ? detunes[(detune & 3) - 1][ksr & 7] >> (3 - (ksr >> 3)) : 0;
u32 lfo = ym2612.lfo.clock >> 2 & 0x1f;
u32 pm = 4 * vibratos[channel.vibrato][lfo & 15] * (-lfo >> 4);
u32 msb = 10;
while(msb > 4 && ~pitch.value & 1 << msb) msb--;
s32 pm = (pitch.value * vibratos[channel.vibrato][lfo & 15] >> 9) * (lfo > 15 ? -1 : 1);
phase.delta = pitch.value + (pm >> 10 - msb) << 6 >> 7 - octave.value;
phase.delta = pitch.value + pm << 6 >> 7 - octave.value;
phase.delta = (!detune.bit(2) ? phase.delta + tuning : phase.delta - tuning) & 0x1ffff;
phase.delta = (multiple ? phase.delta * multiple : phase.delta >> 1) & 0xfffff;
}
@@ -147,6 +147,7 @@ auto YM2612::Channel::power() -> void {
for(auto& op : operators) {
op.keyOn = 0;
op.keyLine = 0;
op.lfoEnable = 0;
op.detune = 0;
op.multiple = 0;
@@ -155,6 +156,7 @@ auto YM2612::Channel::power() -> void {
op.outputLevel = 0x1fff;
op.output = 0;
op.prior = 0;
op.priorBuffer = 0;
op.pitch.value = 0;
op.pitch.reload = 0;
+15 -10
View File
@@ -14,6 +14,8 @@ auto YM2612::writeData(n8 data) -> void {
case 0x022: {
lfo.rate = data.bit(0,2);
lfo.enable = data.bit(3);
lfo.clock = 0;
lfo.divider = 0;
break;
}
@@ -37,11 +39,12 @@ auto YM2612::writeData(n8 data) -> void {
//timer control
case 0x027: {
//d6,d7 = mode (unimplemented; treated as mode 0 always)
//reload period on 0->1 transition
if(!timerA.enable && data.bit(0)) timerA.counter = timerA.period;
if(!timerB.enable && data.bit(1)) timerB.counter = timerB.period;
if(!timerB.enable && data.bit(1)) {
timerB.counter = timerB.period;
timerB.divider = 0;
}
timerA.enable = data.bit(0);
timerB.enable = data.bit(1);
@@ -51,6 +54,7 @@ auto YM2612::writeData(n8 data) -> void {
if(data.bit(4)) timerA.line = 0;
if(data.bit(5)) timerB.line = 0;
//d7 is enable bit for CSM mode (not yet implemented)
channels[2].mode = data.bit(6,7);
for(auto& op : channels[2].operators) op.updatePitch();
@@ -64,10 +68,10 @@ auto YM2612::writeData(n8 data) -> void {
if(index == 3 || index == 7) break;
if(index >= 4) index--;
channels[index][0].trigger(data.bit(4));
channels[index][1].trigger(data.bit(5));
channels[index][2].trigger(data.bit(6));
channels[index][3].trigger(data.bit(7));
channels[index][0].keyLine = data.bit(4);
channels[index][1].keyLine = data.bit(5);
channels[index][2].keyLine = data.bit(6);
channels[index][3].keyLine = data.bit(7);
break;
}
@@ -145,10 +149,11 @@ auto YM2612::writeData(n8 data) -> void {
//SSG-EG
case 0x090: {
op.ssg.hold = data.bit(0);
op.ssg.alternate = data.bit(1);
op.ssg.attack = data.bit(2);
op.ssg.enable = data.bit(3);
op.ssg.hold = op.ssg.enable ? data.bit(0) : 0;
op.ssg.alternate = op.ssg.enable ? data.bit(1) : 0;
op.ssg.attack = op.ssg.enable ? data.bit(2) : 0;
channel[index].updateLevel();
break;
}
@@ -42,6 +42,7 @@ auto YM2612::Channel::serialize(serializer& s) -> void {
auto YM2612::Channel::Operator::serialize(serializer& s) -> void {
s(keyOn);
s(keyLine);
s(lfoEnable);
s(detune);
s(multiple);
@@ -49,6 +50,7 @@ auto YM2612::Channel::Operator::serialize(serializer& s) -> void {
s(outputLevel);
s(output);
s(prior);
s(priorBuffer);
s(pitch.value);
s(pitch.reload);
+21 -7
View File
@@ -27,16 +27,20 @@ auto YM2612::clock() -> array<i16[2]> {
auto wave = [&](u32 n, u32 modulation) -> s32 {
s32 x = (modulation >> 1) + (op[n].phase.value >> 10);
s32 y = sine[x & 0x3ff] + op[n].outputLevel;
return y < 0x2000 ? pow2[y & 0x1ff] << 2 >> (y >> 9) : 0;
return y < 0x1a00 ? pow2[y & 0x1ff] << 2 >> (y >> 9) : 0; // -78 dB floor
};
s32 feedback = modMask & op[0].output + op[0].prior >> 9 - channel.feedback;
s32 feedback = modMask & op[0].prior + op[0].priorBuffer >> 9 - channel.feedback;
s32 accumulator = 0;
op[0].priorBuffer = op[0].prior; // only need to buffer the output for feedback
for(auto n : range(4)) op[n].prior = op[n].output;
op[0].output = wave(0, feedback * (channel.feedback > 0));
// Note: Despite not emulating per cycle, operator pipelining has been accounted for.
// Given the op order 0-2-1-3, newly generated output is not available for the following op.
if(channel.algorithm == 0) {
//0 -> 1 -> 2 -> 3
op[1].output = wave(1, mod(0));
@@ -48,7 +52,7 @@ auto YM2612::clock() -> array<i16[2]> {
if(channel.algorithm == 1) {
//(0 + 1) -> 2 -> 3
op[1].output = wave(1, 0);
op[2].output = wave(2, mod(0) + old(1));
op[2].output = wave(2, old(0) + old(1));
op[3].output = wave(3, mod(2));
accumulator += out(3);
}
@@ -65,7 +69,7 @@ auto YM2612::clock() -> array<i16[2]> {
//(0 -> 1) + 2 -> 3
op[1].output = wave(1, mod(0));
op[2].output = wave(2, 0);
op[3].output = wave(3, mod(1) + mod(2));
op[3].output = wave(3, old(1) + mod(2));
accumulator += out(3);
}
@@ -104,8 +108,18 @@ auto YM2612::clock() -> array<i16[2]> {
s32 voiceData = sclamp<14>(accumulator) & outMask;
if(dac.enable && (&channel == &channels[5])) voiceData = (s32)dac.sample - 0x80 << 6;
if(channel.leftEnable ) left += voiceData;
if(channel.rightEnable) right += voiceData;
// DAC output + voltage offset (crossover distortion)
if(voiceData < 0) {
left += channel.leftEnable * (voiceData + (1<<5)) - (4<<5);
right += channel.rightEnable * (voiceData + (1<<5)) - (4<<5);
} else {
left += channel.leftEnable * (voiceData + (0<<5)) + (4<<5);
right += channel.rightEnable * (voiceData + (0<<5)) + (4<<5);
}
// DAC output (ym3438 fix)
//if(channel.leftEnable ) left += voiceData;
//if(channel.rightEnable) right += voiceData;
}
timerA.run();
@@ -124,7 +138,7 @@ auto YM2612::clock() -> array<i16[2]> {
if(++envelope.divider == 3) {
envelope.divider = 0;
envelope.clock++;
if(!++envelope.clock) ++envelope.clock; // 12-bit counter: 1..4095 - zero-value is skipped (confirmed behavior)
}
for(auto& channel : channels) {
+4 -2
View File
@@ -36,7 +36,7 @@ protected:
} dac;
struct Envelope {
n32 clock = 0;
n12 clock = 0;
n32 divider = 0;
} envelope;
@@ -91,7 +91,7 @@ protected:
Operator(Channel& channel) : channel(channel), ym2612(channel.ym2612) {}
//channel.cpp
auto trigger(bool) -> void;
auto updateKeyState() -> void;
auto runEnvelope() -> void;
auto runPhase() -> void;
@@ -105,6 +105,7 @@ protected:
auto serialize(serializer&) -> void;
n1 keyOn = 0;
n1 keyLine = 0;
n1 lfoEnable = 0;
n3 detune = 0;
n4 multiple = 0;
@@ -113,6 +114,7 @@ protected:
n16 outputLevel = 0x1fff;
i16 output = 0;
i16 prior = 0;
i16 priorBuffer = 0;
struct Pitch {
n11 value = 0;
@@ -0,0 +1,76 @@
#include <ares/ares.hpp>
#include "sst39sf0x0.hpp"
namespace ares {
auto SST39SF0x0::reset() -> void {
mode = Mode::Data;
unlockStep = UnlockStep::Unlock0;
}
auto SST39SF0x0::read(n32 address) -> n8 {
if(mode == Mode::ID) {
if(address == 0x00) return 0xBF; /* Manufacturer ID */
if(address == 0x01) { /* Device ID */
if(flash.size() <= 128 * 1024) return 0xB5;
if(flash.size() <= 256 * 1024) return 0xB6;
return 0xB7;
}
return 0xFF;
}
return flash.read(address);
}
auto SST39SF0x0::write(n32 address, n8 data) -> void {
if(mode == Mode::Program) {
flash.write(address, data);
mode = Mode::Data;
} else if (mode == Mode::EraseBlock) {
address &= ~0xFFF;
for(u32 i = 0; i < 4096; i++) {
flash.write(address + i, 0xFF);
}
mode = Mode::Data;
} else if(mode == Mode::ID && data == 0xF0) {
unlockStep = UnlockStep::Unlock0;
mode = Mode::Data;
} else {
if(unlockStep == UnlockStep::Unlock0) {
if((address & 0x7FFF) == 0x5555 && (data & 0xFF) == 0xAA) unlockStep = UnlockStep::Unlock1;
} else if(unlockStep == UnlockStep::Unlock1) {
unlockStep = UnlockStep::Unlock0;
if((address & 0x7FFF) == 0x2AAA && (data & 0xFF) == 0x55) unlockStep = UnlockStep::Unlock2;
} else {
unlockStep = UnlockStep::Unlock0;
if((address & 0x7FFF) == 0x5555) {
switch(data) {
case 0xA0:
mode = Mode::Program;
break;
case 0x80:
mode = Mode::Erase;
break;
case 0x10:
if(mode != Mode::Erase) return;
for(u32 i = 0; i < flash.size(); i++) {
flash.write(i, 0xFF);
}
break;
case 0x30:
if(mode != Mode::Erase) return;
mode = Mode::EraseBlock;
break;
case 0x90:
mode = Mode::ID;
break;
case 0xF0:
default:
mode = Mode::Data;
break;
}
}
}
}
}
};
@@ -0,0 +1,29 @@
#pragma once
//Generic flash
namespace ares {
struct SST39SF0x0 {
auto reset() -> void;
auto read(n32 address) -> n8;
auto write(n32 address, n8 data) -> void;
Memory::Writable<n8> flash;
enum class Mode : u32 {
Data,
ID, /* 0x90 */
Program, /* 0xA0 */
Erase, /* 0x80 */
EraseBlock /* 0x80 0x30 */
} mode;
enum class UnlockStep : u32 {
Unlock0, /* 0xF0 */
Unlock1,
Unlock2
} unlockStep;
};
}
+72
View File
@@ -0,0 +1,72 @@
#include <ares/ares.hpp>
#include "i8255.hpp"
namespace ares {
auto I8255::power() -> void {
io.portCLowerInput = 1;
io.portBInput = 1;
io.groupBMode = 0;
io.portCHigherInput = 1;
io.portAInput = 1;
io.groupAMode = 0;
io.ioMode = 0;
state.portA = 0xff;
state.portB = 0xff;
state.portC = 0xff;
}
auto I8255::read(n2 port) -> n8 {
switch(port) {
case 0: return io.portAInput ? readPortA() : state.portA;
case 1: return io.portBInput ? readPortB() : state.portB;
case 2: {
n8 result = readPortC();
if(!io.portCLowerInput) result.bit(0,3) = state.portC.bit(0,3);
if(!io.portCHigherInput) result.bit(4,7) = state.portC.bit(4,7);
return result;
}
case 3: return 0xff;
}
unreachable;
}
auto I8255::write(n2 port, n8 data) -> void {
switch(port) {
case 0: state.portA = data; return writePortA(data);
case 1: state.portB = data; return writePortB(data);
case 2: state.portC = data; return writePortC(data);
case 3: return writeControl(data);
}
unreachable;
}
auto I8255::writeControl(n8 data) -> void {
io.portCLowerInput = data.bit(0);
io.portBInput = data.bit(1);
io.groupBMode = data.bit(2);
io.portCHigherInput = data.bit(3);
io.portAInput = data.bit(4);
io.groupAMode = data.bit(5,6);
io.ioMode = data.bit(7);
if(!io.ioMode) debug(unimplemented, "[I8255] BSR Mode");
if(io.groupAMode != 0) debug(unimplemented, "[I8255] Group A Mode != 0");
if(io.groupBMode != 0) debug(unimplemented, "[I8255] Group B Mode != 0");
}
auto I8255::serialize(serializer& s) -> void {
s(io.portCLowerInput);
s(io.portBInput);
s(io.groupBMode);
s(io.portCHigherInput);
s(io.portAInput);
s(io.groupAMode);
s(io.ioMode);
s(state.portA);
s(state.portB);
s(state.portC);
}
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
namespace ares {
struct I8255 {
//i8255.cpp
auto power() -> void;
auto read(n2 port) -> n8;
auto write(n2 port, n8 data) -> void;
auto writeControl(n8 data) -> void;
auto serialize(serializer&) -> void;
virtual auto readPortA() -> n8 { return 0xff; };
virtual auto readPortB() -> n8 { return 0xff; };
virtual auto readPortC() -> n8 { return 0xff; };
virtual auto writePortA(n8 data) -> void {};
virtual auto writePortB(n8 data) -> void {};
virtual auto writePortC(n8 data) -> void {};
struct IO {
n1 portCLowerInput;
n1 portBInput;
n1 groupBMode;
n1 portCHigherInput;
n1 portAInput;
n2 groupAMode;
n1 ioMode;
} io;
struct State {
n8 portA;
n8 portB;
n8 portC;
} state;
};
}
@@ -62,7 +62,7 @@ struct ARM7TDMI {
auto thumbInitialize() -> void;
//instructions-arm.cpp
auto armALU(n4 mode, n4 target, n4 source, n32 data) -> void;
auto armALU(n4 mode, n4 target, n32 source, n32 data) -> void;
auto armMoveToStatus(n4 field, n1 source, n32 data) -> void;
auto armInstructionBranch(i24, n1) -> void;
@@ -1,6 +1,4 @@
auto ARM7TDMI::armALU(n4 mode, n4 d, n4 n, n32 rm) -> void {
n32 rn = r(n);
auto ARM7TDMI::armALU(n4 mode, n4 d, n32 rn, n32 rm) -> void {
switch(mode) {
case 0: r(d) = BIT(rn & rm); break; //AND
case 1: r(d) = BIT(rn ^ rm); break; //EOR
@@ -64,14 +62,16 @@ auto ARM7TDMI::armInstructionBranchExchangeRegister
auto ARM7TDMI::armInstructionDataImmediate
(n8 immediate, n4 shift, n4 d, n4 n, n1 save, n4 mode) -> void {
n32 rn = r(n);
n32 data = immediate;
carry = cpsr().c;
if(shift) data = ROR(data, shift << 1);
armALU(mode, d, n, data);
armALU(mode, d, rn, data);
}
auto ARM7TDMI::armInstructionDataImmediateShift
(n4 m, n2 type, n5 shift, n4 d, n4 n, n1 save, n4 mode) -> void {
n32 rn = r(n);
n32 rm = r(m);
carry = cpsr().c;
@@ -82,12 +82,13 @@ auto ARM7TDMI::armInstructionDataImmediateShift
case 3: rm = shift ? ROR(rm, shift) : RRX(rm); break;
}
armALU(mode, d, n, rm);
armALU(mode, d, rn, rm);
}
auto ARM7TDMI::armInstructionDataRegisterShift
(n4 m, n2 type, n4 s, n4 d, n4 n, n1 save, n4 mode) -> void {
n8 rs = r(s) + (s == 15 ? 4 : 0);
n32 rn = r(n) + (n == 15 ? 4 : 0);
n32 rm = r(m) + (m == 15 ? 4 : 0);
carry = cpsr().c;
@@ -98,7 +99,7 @@ auto ARM7TDMI::armInstructionDataRegisterShift
case 3: if(rs) rm = ROR(rm, rs & 31 ? u32(rs & 31) : 32); break;
}
armALU(mode, d, n, rm);
armALU(mode, d, rn, rm);
}
auto ARM7TDMI::armInstructionLoadImmediate
@@ -167,7 +168,7 @@ auto ARM7TDMI::armInstructionMoveHalfRegister
auto ARM7TDMI::armInstructionMoveImmediateOffset
(n12 immediate, n4 d, n4 n, n1 mode, n1 writeback, n1 byte, n1 up, n1 pre) -> void {
n32 rn = r(n);
n32 rd = r(d);
n32 rd = r(d) + (d == 15 ? 4 : 0);
if(pre == 1) rn = up ? rn + immediate : rn - immediate;
if(mode == 1) rd = load((byte ? Byte : Word) | Nonsequential, rn);
@@ -201,7 +202,7 @@ auto ARM7TDMI::armInstructionMoveMultiple
for(u32 m : range(16)) {
if(!list.bit(m)) continue;
if(mode == 1) r(m) = read(Word | sequential, rn);
if(mode == 0) write(Word | sequential, rn, r(m));
if(mode == 0) write(Word | sequential, rn, r(m) + (m == 15 ? 4 : 0));
rn += 4;
sequential = Sequential;
}
@@ -126,17 +126,23 @@ auto ARM7TDMI::thumbInstructionMoveMultiple
(n8 list, n3 n, n1 mode) -> void {
n32 rn = r(n);
u32 sequential = Nonsequential;
for(u32 m : range(8)) {
if(!list.bit(m)) continue;
switch(mode) {
case 0: write(Word | Nonsequential, rn, r(m)); break; //STMIA
case 1: r(m) = read(Word | Nonsequential, rn); break; //LDMIA
case 0: write(Word | sequential, rn, r(m)); break; //STMIA
case 1: r(m) = read(Word | sequential, rn); break; //LDMIA
}
rn += 4;
sequential = Sequential;
}
if(mode == 0 || !list.bit(n)) r(n) = rn;
if(mode == 1) idle();
if(mode == 1) {
idle();
} else {
pipeline.nonsequential = true;
}
}
auto ARM7TDMI::thumbInstructionMoveRegisterOffset
@@ -30,20 +30,6 @@ auto GSU::disassembleOpcode(char* output) -> void {
while(length++ < 20) strcat(output, " ");
}
#define case4(id) \
case id+ 0: case id+ 1: case id+ 2: case id+ 3
#define case6(id) \
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5
#define case12(id) \
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
case id+ 8: case id+ 9: case id+10: case id+11
#define case15(id) \
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14
#define case16(id) \
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14: case id+15
#define op0 regs.pipeline
#define op1 read((regs.pbr << 16) + regs.r[15] + 0)
#define op2 read((regs.pbr << 16) + regs.r[15] + 1)
+10 -14
View File
@@ -1,17 +1,15 @@
auto HuC6280::algorithmADC(n8 i) -> n8 {
i16 o;
i16 o = A + i + C;
if(!D) {
o = A + i + C;
C = o.bit(8);
V = ~(A ^ i) & (A ^ o) & 0x80;
} else {
idle();
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
if(o > 0x09) o += 0x06;
C = o > 0x0f;
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
n8 l = (A & 0x0f) + (i & 0x0f) + C;
if(l > 0x09) o += 0x06;
if(o > 0x9f) o += 0x60;
C = o > 0xff;
}
C = o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
return o;
@@ -125,19 +123,17 @@ auto HuC6280::algorithmROR(n8 i) -> n8 {
auto HuC6280::algorithmSBC(n8 i) -> n8 {
i ^= 0xff;
i16 o;
i16 o = A + i + C;
if(!D) {
o = A + i + C;
C = o.bit(8);
V = ~(A ^ i) & (A ^ o) & 0x80;
} else {
idle();
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
if(o <= 0x0f) o -= 0x06;
C = o > 0x0f;
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
n8 l = (A & 0x0f) + (i & 0x0f) + C;
C = o > 0xff;
if(o <= 0xff) o -= 0x60;
if(l <= 0x0f) o -= 0x06;
}
C = o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
return o;
@@ -0,0 +1,85 @@
auto I8080::ADD(n8 x, n8 y, bool c) -> n8 {
n9 z = x + y + c;
CF = z.bit(8);
PF = parity(z);
HF = n8(x ^ y ^ z).bit(4);
ZF = n8(z) == 0;
SF = z.bit(7);
return z;
}
auto I8080::AND(n8 x, n8 y) -> n8 {
n8 z = x & y;
CF = 0;
HF = n8(x | y).bit(3);
PF = parity(z);
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto I8080::CP(n8 x, n8 y) -> void {
SUB(x, y, 0);
}
auto I8080::DEC(n8 x) -> n8 {
n8 z = x - 1;
PF = parity(z);
HF = x.bit(0,3) != 0x00;
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto I8080::INC(n8 x) -> n8 {
n8 z = x + 1;
PF = parity(z);
HF = x.bit(0,3) == 0x0f;
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto I8080::OR(n8 x, n8 y) -> n8 {
n8 z = x | y;
CF = 0;
PF = parity(z);
HF = 0;
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto I8080::SUB(n8 x, n8 y, bool c) -> n8 {
n9 z = x + ~y + !c; // internally implemented as negated ADD
CF = z.bit(8);
PF = parity(z);
HF = n8(x ^ ~y ^ z).bit(4);
ZF = n8(z) == 0;
SF = z.bit(7);
return z;
}
auto I8080::XOR(n8 x, n8 y) -> n8 {
n8 z = x ^ y;
CF = 0;
HF = 0;
PF = parity(z);
ZF = z == 0;
SF = z.bit(7);
return z;
}
@@ -0,0 +1,410 @@
no_optimize
auto I8080::disassembleInstruction(maybe<n16> _pc) -> string {
auto pc = _pc ? *_pc : PC;
string s, output;
n8 prefix = 0x00;
auto code = bus->read(pc++);
if(code == 0xdd || code == 0xfd) {
prefix = code;
code = bus->read(pc++);
if(code == 0xdd || code == 0xfd) {
if(prefix == 0xdd) {
s.append("ix:");
goto finish;
}
if(prefix == 0xfd) {
s.append("iy:");
goto finish;
}
}
}
output = disassemble(pc, prefix, code);
finish:
return pad(output, -18L);
}
no_optimize
auto I8080::disassembleContext() -> string {
string s;
s.append("AF:", hex(af.word, 4L), " ");
s.append("BC:", hex(bc.word, 4L), " ");
s.append("DE:", hex(de.word, 4L), " ");
s.append("HL:", hex(hl.word, 4L), " ");
s.append("IX:", hex(ix.word, 4L), " ");
s.append("IY:", hex(iy.word, 4L), " ");
s.append("SP:", hex(SP, 4L), " ");
return s;
}
#define op(id, name, ...) case id: return {name, " ", vector<string>{__VA_ARGS__}.merge(",")};
#define N string{"$", hex(byte(), 2L)}
#define IN string{"(", N, ")"}
#define NN string{"$", hex(word(), 4L)}
#define INN string{"(", NN, ")"}
#define REL string{"$", hex(branch(), 4L)}
#define A "a"
#define F "f"
#define B "b"
#define C "c"
#define D "d"
#define E "e"
#define H prefix == 0xdd ? "ixh" : prefix == 0xfd ? "iyh" : "h"
#define L prefix == 0xdd ? "ixl" : prefix == 0xfd ? "iyl" : "l"
#define _H "h"
#define _L "l"
#define _HL "hl"
#define AF "af"
#define BC "bc"
#define DE "de"
#define HL prefix == 0xdd ? "ix" : prefix == 0xfd ? "iy" : "hl"
#define AF_ "af'"
#define BC_ "bc'"
#define DE_ "de'"
#define HL_ "hl'"
#define SP "sp"
#define PC "pc"
#define I "i"
#define R "r"
#define IC "(c)"
#define IBC "(bc)"
#define IDE "(de)"
#define IHL "(hl)"
#define ISP "(sp)"
no_optimize
auto I8080::disassemble(n16 pc, n8 prefix, n8 code) -> string {
auto byte = [&] {
return bus->read(pc++);
};
auto word = [&] {
n16 data = byte() << 0;
return data | byte() << 8;
};
auto branch = [&] {
auto d = byte();
return pc + (i8)d;
};
auto displace = [&] {
if(!prefix) return string{};
auto d = (i8)byte();
return d >= 0 ? string{"+$", hex(d, 2L)} : string{"-$", hex(-d, 2L)};
};
switch(code) {
op(0x00, "nop ")
op(0x01, "ld ", BC, NN)
op(0x02, "ld ", IBC, A)
op(0x03, "inc ", BC)
op(0x04, "inc ", B)
op(0x05, "dec ", B)
op(0x06, "ld ", B, N)
op(0x07, "rlca")
op(0x08, "ex ", AF, AF_)
op(0x09, "add ", HL, BC)
op(0x0a, "ld ", A, IBC)
op(0x0b, "dec ", BC)
op(0x0c, "inc ", C)
op(0x0d, "dec ", C)
op(0x0e, "ld ", C, N)
op(0x0f, "rrca")
op(0x10, "djnz", REL)
op(0x11, "ld ", DE, NN)
op(0x12, "ld ", IDE, A)
op(0x13, "inc ", DE)
op(0x14, "inc ", D)
op(0x15, "dec ", D)
op(0x16, "ld ", D, N)
op(0x17, "rla ")
op(0x18, "jr ", REL)
op(0x19, "add ", HL, DE)
op(0x1a, "ld ", A, IDE)
op(0x1b, "dec ", DE)
op(0x1c, "inc ", E)
op(0x1d, "dec ", E)
op(0x1e, "ld ", E, N)
op(0x1f, "rra ")
op(0x20, "jr ", "nz", REL)
op(0x21, "ld ", HL, NN)
op(0x22, "ld ", INN, HL)
op(0x23, "inc ", HL)
op(0x24, "inc ", H)
op(0x25, "dec ", H)
op(0x26, "ld ", H, N)
op(0x27, "daa ")
op(0x28, "jr ", "z", REL)
op(0x29, "add ", HL, HL)
op(0x2a, "ld ", HL, INN)
op(0x2b, "dec ", HL)
op(0x2c, "inc ", L)
op(0x2d, "dec ", L)
op(0x2e, "ld ", L, N)
op(0x2f, "cpl ")
op(0x30, "jr ", "nc", REL)
op(0x31, "ld ", SP, NN)
op(0x32, "ld ", INN, A)
op(0x33, "inc ", SP)
op(0x34, "inc ", IHL)
op(0x35, "dec ", IHL)
op(0x36, "ld ", IHL, N)
op(0x37, "scf ")
op(0x38, "jr ", "c", REL)
op(0x39, "add ", HL, SP)
op(0x3a, "ld ", A, INN)
op(0x3b, "dec ", SP)
op(0x3c, "inc ", A)
op(0x3d, "dec ", A)
op(0x3e, "ld ", A, N)
op(0x3f, "ccf ")
op(0x40, "ld ", B, B)
op(0x41, "ld ", B, C)
op(0x42, "ld ", B, D)
op(0x43, "ld ", B, E)
op(0x44, "ld ", B, H)
op(0x45, "ld ", B, L)
op(0x46, "ld ", B, IHL)
op(0x47, "ld ", B, A)
op(0x48, "ld ", C, B)
op(0x49, "ld ", C, C)
op(0x4a, "ld ", C, D)
op(0x4b, "ld ", C, E)
op(0x4c, "ld ", C, H)
op(0x4d, "ld ", C, L)
op(0x4e, "ld ", C, IHL)
op(0x4f, "ld ", C, A)
op(0x50, "ld ", D, B)
op(0x51, "ld ", D, C)
op(0x52, "ld ", D, D)
op(0x53, "ld ", D, E)
op(0x54, "ld ", D, H)
op(0x55, "ld ", D, L)
op(0x56, "ld ", D, IHL)
op(0x57, "ld ", D, A)
op(0x58, "ld ", E, B)
op(0x59, "ld ", E, C)
op(0x5a, "ld ", E, D)
op(0x5b, "ld ", E, E)
op(0x5c, "ld ", E, H)
op(0x5d, "ld ", E, L)
op(0x5e, "ld ", E, IHL)
op(0x5f, "ld ", E, A)
op(0x60, "ld ", H, B)
op(0x61, "ld ", H, C)
op(0x62, "ld ", H, D)
op(0x63, "ld ", H, E)
op(0x64, "ld ", H, H)
op(0x65, "ld ", H, L)
op(0x66, "ld ", _H, IHL)
op(0x67, "ld ", H, A)
op(0x68, "ld ", L, B)
op(0x69, "ld ", L, C)
op(0x6a, "ld ", L, D)
op(0x6b, "ld ", L, E)
op(0x6c, "ld ", L, H)
op(0x6d, "ld ", L, L)
op(0x6e, "ld ", _L, IHL)
op(0x6f, "ld ", L, A)
op(0x70, "ld ", IHL, B)
op(0x71, "ld ", IHL, C)
op(0x72, "ld ", IHL, D)
op(0x73, "ld ", IHL, E)
op(0x74, "ld ", IHL, _H)
op(0x75, "ld ", IHL, _L)
op(0x76, "halt")
op(0x77, "ld ", IHL, A)
op(0x78, "ld ", A, B)
op(0x79, "ld ", A, C)
op(0x7a, "ld ", A, D)
op(0x7b, "ld ", A, E)
op(0x7c, "ld ", A, H)
op(0x7d, "ld ", A, L)
op(0x7e, "ld ", A, IHL)
op(0x7f, "ld ", A, A)
op(0x80, "add ", A, B)
op(0x81, "add ", A, C)
op(0x82, "add ", A, D)
op(0x83, "add ", A, E)
op(0x84, "add ", A, H)
op(0x85, "add ", A, L)
op(0x86, "add ", A, IHL)
op(0x87, "add ", A, A)
op(0x88, "adc ", A, B)
op(0x89, "adc ", A, C)
op(0x8a, "adc ", A, D)
op(0x8b, "adc ", A, E)
op(0x8c, "adc ", A, H)
op(0x8d, "adc ", A, L)
op(0x8e, "adc ", A, IHL)
op(0x8f, "adc ", A, A)
op(0x90, "sub ", A, B)
op(0x91, "sub ", A, C)
op(0x92, "sub ", A, D)
op(0x93, "sub ", A, E)
op(0x94, "sub ", A, H)
op(0x95, "sub ", A, L)
op(0x96, "sub ", A, IHL)
op(0x97, "sub ", A, A)
op(0x98, "sbc ", A, B)
op(0x99, "sbc ", A, C)
op(0x9a, "sbc ", A, D)
op(0x9b, "sbc ", A, E)
op(0x9c, "sbc ", A, H)
op(0x9d, "sbc ", A, L)
op(0x9e, "sbc ", A, IHL)
op(0x9f, "sbc ", A, A)
op(0xa0, "and ", A, B)
op(0xa1, "and ", A, C)
op(0xa2, "and ", A, D)
op(0xa3, "and ", A, E)
op(0xa4, "and ", A, H)
op(0xa5, "and ", A, L)
op(0xa6, "and ", A, IHL)
op(0xa7, "and ", A, A)
op(0xa8, "xor ", A, B)
op(0xa9, "xor ", A, C)
op(0xaa, "xor ", A, D)
op(0xab, "xor ", A, E)
op(0xac, "xor ", A, H)
op(0xad, "xor ", A, L)
op(0xae, "xor ", A, IHL)
op(0xaf, "xor ", A, A)
op(0xb0, "or ", A, B)
op(0xb1, "or ", A, C)
op(0xb2, "or ", A, D)
op(0xb3, "or ", A, E)
op(0xb4, "or ", A, H)
op(0xb5, "or ", A, L)
op(0xb6, "or ", A, IHL)
op(0xb7, "or ", A, A)
op(0xb8, "cp ", A, B)
op(0xb9, "cp ", A, C)
op(0xba, "cp ", A, D)
op(0xbb, "cp ", A, E)
op(0xbc, "cp ", A, H)
op(0xbd, "cp ", A, L)
op(0xbe, "cp ", A, IHL)
op(0xbf, "cp ", A, A)
op(0xc0, "ret ", "nz")
op(0xc1, "pop ", BC)
op(0xc2, "jp ", "nz", NN)
op(0xc3, "jp ", NN)
op(0xc4, "call", "nz", NN)
op(0xc5, "push", BC)
op(0xc6, "add ", A, N)
op(0xc7, "rst ", "$0000")
op(0xc8, "ret ", "z")
op(0xc9, "ret ")
op(0xca, "jp ", "z", NN)
op(0xcb, "cb: ")
op(0xcc, "call", "z", NN)
op(0xcd, "call", NN)
op(0xce, "adc ", A, N)
op(0xcf, "rst ", "$0008")
op(0xd0, "ret ", "nc")
op(0xd1, "pop ", DE)
op(0xd2, "jp ", "nc", NN)
op(0xd3, "out ", IN, A)
op(0xd4, "call", "nc", NN)
op(0xd5, "push", DE)
op(0xd6, "sub ", A, N)
op(0xd7, "rst ", "$0010")
op(0xd8, "ret ", "c")
op(0xd9, "exx ")
op(0xda, "jp ", "c", NN)
op(0xdb, "in ", A, IN)
op(0xdc, "call", "c", NN)
op(0xdd, "ix: ")
op(0xde, "sbc ", A, N)
op(0xdf, "rst ", "$0018")
op(0xe0, "ret ", "po")
op(0xe1, "pop ", HL)
op(0xe2, "jp ", "po", NN)
op(0xe3, "ex ", ISP, HL)
op(0xe4, "call", "po", NN)
op(0xe5, "push", HL)
op(0xe6, "and ", A, N)
op(0xe7, "rst ", "$0020")
op(0xe8, "ret ", "pe")
op(0xe9, "jp ", HL) //officially jp (hl); but as read is not indirect, use jp hl
op(0xea, "jp ", "pe", NN)
op(0xeb, "ex ", DE, _HL)
op(0xec, "call", "pe", NN)
op(0xed, "ed: ")
op(0xee, "xor ", A, N)
op(0xef, "rst ", "$0028")
op(0xf0, "ret ", "p")
op(0xf1, "pop ", AF)
op(0xf2, "jp ", "p", NN)
op(0xf3, "di ")
op(0xf4, "call", "p", NN)
op(0xf5, "push", AF)
op(0xf6, "or ", A, N)
op(0xf7, "rst ", "$0030")
op(0xf8, "ret ", "m")
op(0xf9, "ld ", SP, HL)
op(0xfa, "jp ", "m", NN)
op(0xfb, "ei ")
op(0xfc, "call", "m", NN)
op(0xfd, "iy: ")
op(0xfe, "cp ", A, N)
op(0xff, "rst ", "$0038")
}
unreachable;
}
#undef op
#undef N
#undef IN
#undef NN
#undef INN
#undef REL
#undef A
#undef F
#undef B
#undef C
#undef D
#undef E
#undef H
#undef L
#undef _H
#undef _L
#undef _HL
#undef AF
#undef BC
#undef DE
#undef HL
#undef AF_
#undef BC_
#undef DE_
#undef HL_
#undef SP
#undef PC
#undef I
#undef R
#undef IC
#undef IBC
#undef IDE
#undef IHL
#undef ISP
+81
View File
@@ -0,0 +1,81 @@
#include <ares/ares.hpp>
#include "i8080.hpp"
namespace ares {
#include "disassembler.cpp"
#include "registers.hpp"
#include "memory.cpp"
#include "instruction.cpp"
#include "algorithms.cpp"
#include "instructions.cpp"
#include "serialization.cpp"
auto I8080::power() -> void {
prefix = Prefix::hl;
af.word = 0xffd7; af_.word = 0x0000;
bc.word = 0x0000; bc_.word = 0x0000;
de.word = 0x0000; de_.word = 0x0000;
hl.word = 0x0000; hl_.word = 0x0000;
ix.word = 0x0000;
iy.word = 0x0000;
ir.word = 0x0000;
wz.word = 0x0000;
SP = 0xffff;
PC = 0x0000;
EI = 0;
P = 0;
Q = 0;
HALT = 0;
INTE = 0;
}
auto I8080::reset() -> void {
prefix = Prefix::hl;
ir.word = 0x0000;
WZ = PC = 0x0000;
EI = 0;
HALT = 0;
INTE = 0;
}
auto I8080::irq(n8 extbus) -> bool {
//do not execute maskable interrupts if disabled or immediately after EI instruction
if(!INTE || EI) return false;
WZ = extbus;
wait(6);
instruction(WZ);
INTE = 0;
HALT = 0;
if(P) PF = 0;
P = 0;
Q = 0;
return true;
}
auto I8080::nmi() -> bool {
push(PC);
WZ = 0x66;
wait(5);
PC = WZ;
INTE = 0;
HALT = 0;
if(P) PF = 0;
P = 0;
Q = 0;
return true;
}
auto I8080::parity(n8 value) const -> bool {
value ^= value >> 4;
value ^= value >> 2;
value ^= value >> 1;
return !(value & 1);
}
}
+160
View File
@@ -0,0 +1,160 @@
#pragma once
//Intel 8080
namespace ares {
struct I8080 {
struct Bus {
virtual auto read(n16 address) -> n8 = 0;
virtual auto write(n16 address, n8 data) -> void = 0;
virtual auto in(n16 address) -> n8 = 0;
virtual auto out(n16 address, n8 data) -> void = 0;
};
virtual auto step(u32 clocks) -> void = 0;
virtual auto synchronizing() const -> bool = 0;
//i8080.cpp
auto power() -> void;
auto reset() -> void;
auto irq(n8 extbus = 0xff) -> bool;
auto nmi() -> bool;
auto parity(n8) const -> bool;
//memory.cpp
auto wait(u32 clocks = 1) -> void;
auto opcode() -> n8;
auto operand() -> n8;
auto operands() -> n16;
auto push(n16) -> void;
auto pop() -> n16;
auto read(n16 address) -> n8;
auto write(n16 address, n8 data) -> void;
auto in(n16 address) -> n8;
auto out(n16 address, n8 data) -> void;
//instruction.cpp
auto instruction() -> void;
auto instruction(n8 code) -> void;
//algorithms.cpp
auto ADD(n8, n8, bool = false) -> n8;
auto AND(n8, n8) -> n8;
auto CP (n8, n8) -> void;
auto DEC(n8) -> n8;
auto INC(n8) -> n8;
auto OR (n8, n8) -> n8;
auto SUB(n8, n8, bool = false) -> n8;
auto XOR(n8, n8) -> n8;
//instructions.cpp
auto instructionADC_a_irr(n16&) -> void;
auto instructionADC_a_n() -> void;
auto instructionADC_a_r(n8&) -> void;
auto instructionADD_a_irr(n16&) -> void;
auto instructionADD_a_n() -> void;
auto instructionADD_a_r(n8&) -> void;
auto instructionADD_hl_rr(n16&) -> void;
auto instructionAND_a_irr(n16&) -> void;
auto instructionAND_a_n() -> void;
auto instructionAND_a_r(n8&) -> void;
auto instructionCALL_c_nn(bool c) -> void;
auto instructionCCF() -> void;
auto instructionCP_a_irr(n16& x) -> void;
auto instructionCP_a_n() -> void;
auto instructionCP_a_r(n8& x) -> void;
auto instructionCPL() -> void;
auto instructionDAA() -> void;
auto instructionDEC_irr(n16&) -> void;
auto instructionDEC_r(n8&) -> void;
auto instructionDEC_rr(n16&) -> void;
auto instructionDI() -> void;
auto instructionEI() -> void;
auto instructionEX_irr_rr(n16&, n16&) -> void;
auto instructionEX_rr_rr(n16&, n16&) -> void;
auto instructionHALT() -> void;
auto instructionIN_a_in() -> void;
auto instructionINC_irr(n16&) -> void;
auto instructionINC_r(n8&) -> void;
auto instructionINC_rr(n16&) -> void;
auto instructionJP_c_nn(bool) -> void;
auto instructionJP_rr(n16&) -> void;
auto instructionLD_a_inn() -> void;
auto instructionLD_a_irr(n16& x) -> void;
auto instructionLD_inn_a() -> void;
auto instructionLD_inn_rr(n16&) -> void;
auto instructionLD_irr_a(n16&) -> void;
auto instructionLD_irr_n(n16&) -> void;
auto instructionLD_irr_r(n16&, n8&) -> void;
auto instructionLD_r_n(n8&) -> void;
auto instructionLD_r_irr(n8&, n16&) -> void;
auto instructionLD_r_r(n8&, n8&) -> void;
auto instructionLD_rr_inn(n16&) -> void;
auto instructionLD_rr_nn(n16&) -> void;
auto instructionLD_sp_rr(n16&) -> void;
auto instructionNOP() -> void;
auto instructionOR_a_irr(n16&) -> void;
auto instructionOR_a_n() -> void;
auto instructionOR_a_r(n8&) -> void;
auto instructionOUT_in_a() -> void;
auto instructionPOP_rr(n16&) -> void;
auto instructionPUSH_rr(n16&) -> void;
auto instructionRET() -> void;
auto instructionRET_c(bool c) -> void;
auto instructionRLA() -> void;
auto instructionRLCA() -> void;
auto instructionRRA() -> void;
auto instructionRRCA() -> void;
auto instructionRST_o(n3) -> void;
auto instructionSBC_a_irr(n16&) -> void;
auto instructionSBC_a_n() -> void;
auto instructionSBC_a_r(n8&) -> void;
auto instructionSCF() -> void;
auto instructionSUB_a_irr(n16&) -> void;
auto instructionSUB_a_n() -> void;
auto instructionSUB_a_r(n8&) -> void;
auto instructionXOR_a_irr(n16&) -> void;
auto instructionXOR_a_n() -> void;
auto instructionXOR_a_r(n8&) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
//disassembler.cpp
noinline auto disassembleInstruction(maybe<n16> pc = {}) -> string;
noinline auto disassembleContext() -> string;
auto disassemble(n16 pc, n8 prefix, n8 code) -> string;
enum class Prefix : u32 { hl, ix, iy } prefix = Prefix::hl;
union Pair {
Pair() : word(0) {}
n16 word;
struct Byte { n8 order_msb2(hi, lo); } byte;
};
Pair af, af_;
Pair bc, bc_;
Pair de, de_;
Pair hl, hl_;
Pair ix;
Pair iy;
Pair ir;
Pair wz;
n16 SP;
n16 PC;
b1 EI; //"ei" executed last
b1 P; //"ld a,i" or "ld a,r" executed last
b1 Q; //opcode that updated flag registers executed last
b1 HALT; //"halt" instruction executed
b1 INTE; //interrupt enable
Bus* bus = nullptr;
};
}
@@ -0,0 +1,273 @@
auto I8080::instruction() -> void {
EI = 0;
P = 0;
if(HALT) {
return wait(1);
}
n8 code;
while(true) {
code = opcode();
if(code == 0xdd) { prefix = Prefix::ix; continue; }
if(code == 0xfd) { prefix = Prefix::iy; continue; }
break;
}
instruction(code);
prefix = Prefix::hl;
}
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
auto I8080::instruction(n8 code) -> void {
switch(code) {
op(0x00, NOP)
op(0x01, LD_rr_nn, BC)
op(0x02, LD_irr_a, BC)
op(0x03, INC_rr, BC)
op(0x04, INC_r, B)
op(0x05, DEC_r, B)
op(0x06, LD_r_n, B)
op(0x07, RLCA)
op(0x09, ADD_hl_rr, BC)
op(0x0a, LD_a_irr, BC)
op(0x0b, DEC_rr, BC)
op(0x0c, INC_r, C)
op(0x0d, DEC_r, C)
op(0x0e, LD_r_n, C)
op(0x0f, RRCA)
op(0x11, LD_rr_nn, DE)
op(0x12, LD_irr_a, DE)
op(0x13, INC_rr, DE)
op(0x14, INC_r, D)
op(0x15, DEC_r, D)
op(0x16, LD_r_n, D)
op(0x17, RLA)
op(0x19, ADD_hl_rr, DE)
op(0x1a, LD_a_irr, DE)
op(0x1b, DEC_rr, DE)
op(0x1c, INC_r, E)
op(0x1d, DEC_r, E)
op(0x1e, LD_r_n, E)
op(0x1f, RRA)
op(0x21, LD_rr_nn, HL)
op(0x22, LD_inn_rr, HL)
op(0x23, INC_rr, HL)
op(0x24, INC_r, H)
op(0x25, DEC_r, H)
op(0x26, LD_r_n, H)
op(0x27, DAA)
op(0x29, ADD_hl_rr, HL)
op(0x2a, LD_rr_inn, HL)
op(0x2b, DEC_rr, HL)
op(0x2c, INC_r, L)
op(0x2d, DEC_r, L)
op(0x2e, LD_r_n, L)
op(0x2f, CPL)
op(0x31, LD_rr_nn, SP)
op(0x32, LD_inn_a)
op(0x33, INC_rr, SP)
op(0x34, INC_irr, HL)
op(0x35, DEC_irr, HL)
op(0x36, LD_irr_n, HL)
op(0x37, SCF)
op(0x39, ADD_hl_rr, SP)
op(0x3a, LD_a_inn)
op(0x3b, DEC_rr, SP)
op(0x3c, INC_r, A)
op(0x3d, DEC_r, A)
op(0x3e, LD_r_n, A)
op(0x3f, CCF)
op(0x40, LD_r_r, B, B)
op(0x41, LD_r_r, B, C)
op(0x42, LD_r_r, B, D)
op(0x43, LD_r_r, B, E)
op(0x44, LD_r_r, B, H)
op(0x45, LD_r_r, B, L)
op(0x46, LD_r_irr, B, HL)
op(0x47, LD_r_r, B, A)
op(0x48, LD_r_r, C, B)
op(0x49, LD_r_r, C, C)
op(0x4a, LD_r_r, C, D)
op(0x4b, LD_r_r, C, E)
op(0x4c, LD_r_r, C, H)
op(0x4d, LD_r_r, C, L)
op(0x4e, LD_r_irr, C, HL)
op(0x4f, LD_r_r, C, A)
op(0x50, LD_r_r, D, B)
op(0x51, LD_r_r, D, C)
op(0x52, LD_r_r, D, D)
op(0x53, LD_r_r, D, E)
op(0x54, LD_r_r, D, H)
op(0x55, LD_r_r, D, L)
op(0x56, LD_r_irr, D, HL)
op(0x57, LD_r_r, D, A)
op(0x58, LD_r_r, E, B)
op(0x59, LD_r_r, E, C)
op(0x5a, LD_r_r, E, D)
op(0x5b, LD_r_r, E, E)
op(0x5c, LD_r_r, E, H)
op(0x5d, LD_r_r, E, L)
op(0x5e, LD_r_irr, E, HL)
op(0x5f, LD_r_r, E, A)
op(0x60, LD_r_r, H, B)
op(0x61, LD_r_r, H, C)
op(0x62, LD_r_r, H, D)
op(0x63, LD_r_r, H, E)
op(0x64, LD_r_r, H, H)
op(0x65, LD_r_r, H, L)
op(0x66, LD_r_irr, H, HL)
op(0x67, LD_r_r, H, A)
op(0x68, LD_r_r, L, B)
op(0x69, LD_r_r, L, C)
op(0x6a, LD_r_r, L, D)
op(0x6b, LD_r_r, L, E)
op(0x6c, LD_r_r, L, H)
op(0x6d, LD_r_r, L, L)
op(0x6e, LD_r_irr, L, HL)
op(0x6f, LD_r_r, L, A)
op(0x70, LD_irr_r, HL, B)
op(0x71, LD_irr_r, HL, C)
op(0x72, LD_irr_r, HL, D)
op(0x73, LD_irr_r, HL, E)
op(0x74, LD_irr_r, HL, H)
op(0x75, LD_irr_r, HL, L)
op(0x76, HALT)
op(0x77, LD_irr_r, HL, A)
op(0x78, LD_r_r, A, B)
op(0x79, LD_r_r, A, C)
op(0x7a, LD_r_r, A, D)
op(0x7b, LD_r_r, A, E)
op(0x7c, LD_r_r, A, H)
op(0x7d, LD_r_r, A, L)
op(0x7e, LD_r_irr, A, HL)
op(0x7f, LD_r_r, A, A)
op(0x80, ADD_a_r, B)
op(0x81, ADD_a_r, C)
op(0x82, ADD_a_r, D)
op(0x83, ADD_a_r, E)
op(0x84, ADD_a_r, H)
op(0x85, ADD_a_r, L)
op(0x86, ADD_a_irr, HL)
op(0x87, ADD_a_r, A)
op(0x88, ADC_a_r, B)
op(0x89, ADC_a_r, C)
op(0x8a, ADC_a_r, D)
op(0x8b, ADC_a_r, E)
op(0x8c, ADC_a_r, H)
op(0x8d, ADC_a_r, L)
op(0x8e, ADC_a_irr, HL)
op(0x8f, ADC_a_r, A)
op(0x90, SUB_a_r, B)
op(0x91, SUB_a_r, C)
op(0x92, SUB_a_r, D)
op(0x93, SUB_a_r, E)
op(0x94, SUB_a_r, H)
op(0x95, SUB_a_r, L)
op(0x96, SUB_a_irr, HL)
op(0x97, SUB_a_r, A)
op(0x98, SBC_a_r, B)
op(0x99, SBC_a_r, C)
op(0x9a, SBC_a_r, D)
op(0x9b, SBC_a_r, E)
op(0x9c, SBC_a_r, H)
op(0x9d, SBC_a_r, L)
op(0x9e, SBC_a_irr, HL)
op(0x9f, SBC_a_r, A)
op(0xa0, AND_a_r, B)
op(0xa1, AND_a_r, C)
op(0xa2, AND_a_r, D)
op(0xa3, AND_a_r, E)
op(0xa4, AND_a_r, H)
op(0xa5, AND_a_r, L)
op(0xa6, AND_a_irr, HL)
op(0xa7, AND_a_r, A)
op(0xa8, XOR_a_r, B)
op(0xa9, XOR_a_r, C)
op(0xaa, XOR_a_r, D)
op(0xab, XOR_a_r, E)
op(0xac, XOR_a_r, H)
op(0xad, XOR_a_r, L)
op(0xae, XOR_a_irr, HL)
op(0xaf, XOR_a_r, A)
op(0xb0, OR_a_r, B)
op(0xb1, OR_a_r, C)
op(0xb2, OR_a_r, D)
op(0xb3, OR_a_r, E)
op(0xb4, OR_a_r, H)
op(0xb5, OR_a_r, L)
op(0xb6, OR_a_irr, HL)
op(0xb7, OR_a_r, A)
op(0xb8, CP_a_r, B)
op(0xb9, CP_a_r, C)
op(0xba, CP_a_r, D)
op(0xbb, CP_a_r, E)
op(0xbc, CP_a_r, H)
op(0xbd, CP_a_r, L)
op(0xbe, CP_a_irr, HL)
op(0xbf, CP_a_r, A)
op(0xc0, RET_c, ZF == 0)
op(0xc1, POP_rr, BC)
op(0xc2, JP_c_nn, ZF == 0)
op(0xc3, JP_c_nn, 1)
op(0xc4, CALL_c_nn, ZF == 0)
op(0xc5, PUSH_rr, BC)
op(0xc6, ADD_a_n)
op(0xc7, RST_o, 0)
op(0xc8, RET_c, ZF == 1)
op(0xc9, RET)
op(0xca, JP_c_nn, ZF == 1)
op(0xcc, CALL_c_nn, ZF == 1)
op(0xcd, CALL_c_nn, true)
op(0xce, ADC_a_n)
op(0xcf, RST_o, 1)
op(0xd0, RET_c, CF == 0)
op(0xd1, POP_rr, DE)
op(0xd2, JP_c_nn, CF == 0)
op(0xd3, OUT_in_a)
op(0xd4, CALL_c_nn, CF == 0)
op(0xd5, PUSH_rr, DE)
op(0xd6, SUB_a_n)
op(0xd7, RST_o, 2)
op(0xd8, RET_c, CF == 1)
op(0xda, JP_c_nn, CF == 1)
op(0xdb, IN_a_in)
op(0xdc, CALL_c_nn, CF == 1)
op(0xde, SBC_a_n)
op(0xdf, RST_o, 3)
op(0xe0, RET_c, PF == 0)
op(0xe1, POP_rr, HL)
op(0xe2, JP_c_nn, PF == 0)
op(0xe3, EX_irr_rr, SP, HL)
op(0xe4, CALL_c_nn, PF == 0)
op(0xe5, PUSH_rr, HL)
op(0xe6, AND_a_n)
op(0xe7, RST_o, 4)
op(0xe8, RET_c, PF == 1)
op(0xe9, JP_rr, HL)
op(0xea, JP_c_nn, PF == 1)
op(0xeb, EX_rr_rr, DE, HL)
op(0xec, CALL_c_nn, PF == 1)
op(0xee, XOR_a_n)
op(0xef, RST_o, 5)
op(0xf0, RET_c, SF == 0)
op(0xf1, POP_rr, AF)
op(0xf2, JP_c_nn, SF == 0)
op(0xf3, DI)
op(0xf4, CALL_c_nn, SF == 0)
op(0xf5, PUSH_rr, AF)
op(0xf6, OR_a_n)
op(0xf7, RST_o, 6)
op(0xf8, RET_c, SF == 1)
op(0xf9, LD_sp_rr, HL)
op(0xfa, JP_c_nn, SF == 1)
op(0xfb, EI)
op(0xfc, CALL_c_nn, SF == 1)
op(0xfe, CP_a_n)
op(0xff, RST_o, 7)
}
}
#undef op
@@ -0,0 +1,364 @@
//legend:
// a = register A
// c = condition
// e = relative operand
// in = (operand)
// inn = (operand-word)
// irr = (register-word)
// o = opcode bits
// n = operand
// nn = operand-word
// r = register
auto I8080::instructionADC_a_irr(n16& x) -> void { Q = 1;
A = ADD(A, read(x), CF);
}
auto I8080::instructionADC_a_n() -> void { Q = 1;
A = ADD(A, operand(), CF);
}
auto I8080::instructionADC_a_r(n8& x) -> void { Q = 1;
A = ADD(A, x, CF);
}
auto I8080::instructionADD_a_irr(n16& x) -> void { Q = 1;
A = ADD(A, read(x));
}
auto I8080::instructionADD_a_n() -> void { Q = 1;
A = ADD(A, operand());
}
auto I8080::instructionADD_a_r(n8& x) -> void { Q = 1;
A = ADD(A, x);
}
auto I8080::instructionADD_hl_rr(n16& x) -> void { Q = 1;
WZ = HL + 1;
bool pf = PF, zf = ZF, sf = SF, hf = HF;
wait(3);
auto lo = ADD(HL >> 0, x >> 0);
wait(4);
auto hi = ADD(HL >> 8, x >> 8, CF);
HL = hi << 8 | lo << 0;
PF = pf, ZF = zf, SF = sf, HF = hf; //restore unaffected flags
}
auto I8080::instructionAND_a_irr(n16& x) -> void { Q = 1;
A = AND(A, read(x));
}
auto I8080::instructionAND_a_n() -> void { Q = 1;
A = AND(A, operand());
}
auto I8080::instructionAND_a_r(n8& x) -> void { Q = 1;
A = AND(A, x);
}
auto I8080::instructionCALL_c_nn(bool c) -> void { Q = 0;
WZ = operands();
if(!c) return;
wait(1);
push(PC);
PC = WZ;
}
auto I8080::instructionCCF() -> void {
CF = !CF;
Q = 1;
}
auto I8080::instructionCP_a_irr(n16& x) -> void { Q = 1;
CP(A, read(x));
}
auto I8080::instructionCP_a_n() -> void { Q = 1;
CP(A, operand());
}
auto I8080::instructionCP_a_r(n8& x) -> void { Q = 1;
CP(A, x);
}
auto I8080::instructionCPL() -> void { Q = 1;
A = ~A;
}
auto I8080::instructionDAA() -> void { Q = 1;
auto a = A;
if(CF || (A.bit(0,7) > 0x99)) { A += 0x60; CF = 1; }
if(HF || (A.bit(0,3) > 0x09)) { A += 0x06; }
PF = parity(A);
HF = n8(A ^ a).bit(4);
ZF = A == 0;
SF = A.bit(7);
}
auto I8080::instructionDEC_irr(n16& x) -> void { Q = 1;
auto addr = x;
auto data = read(addr);
wait(1);
write(addr, DEC(data));
}
auto I8080::instructionDEC_r(n8& x) -> void { Q = 1;
x = DEC(x);
}
auto I8080::instructionDEC_rr(n16& x) -> void { Q = 0;
wait(2);
x--;
}
auto I8080::instructionDI() -> void { Q = 0;
INTE = 0;
}
auto I8080::instructionEI() -> void { Q = 0;
INTE = 1;
EI = 1; //ignore maskable interrupts until after the next instruction
}
auto I8080::instructionEX_irr_rr(n16& x, n16& y) -> void { Q = 0;
WZL = read(x + 0);
WZH = read(x + 1);
wait(1);
write(x + 0, y >> 0);
write(x + 1, y >> 8);
wait(2);
y = WZ;
}
auto I8080::instructionEX_rr_rr(n16& x, n16& y) -> void { Q = 0;
swap(x, y);
}
auto I8080::instructionHALT() -> void { Q = 0;
HALT = 1;
}
auto I8080::instructionIN_a_in() -> void { Q = 0;
WZL = operand();
WZH = A;
A = in(WZ++);
}
auto I8080::instructionINC_irr(n16& x) -> void { Q = 1;
auto addr = x;
auto data = read(addr);
wait(1);
write(addr, INC(data));
}
auto I8080::instructionINC_r(n8& x) -> void { Q = 1;
x = INC(x);
}
auto I8080::instructionINC_rr(n16& x) -> void { Q = 0;
wait(2);
x++;
}
auto I8080::instructionJP_c_nn(bool c) -> void { Q = 0;
WZ = operands();
if(c) PC = WZ;
}
auto I8080::instructionJP_rr(n16& x) -> void { Q = 0;
PC = x;
}
auto I8080::instructionLD_a_inn() -> void { Q = 0;
WZ = operands();
A = read(WZ++);
}
auto I8080::instructionLD_a_irr(n16& x) -> void { Q = 0;
WZ = x;
A = read(x);
WZ++;
}
auto I8080::instructionLD_inn_a() -> void { Q = 0;
WZ = operands();
write(WZ++, A);
WZH = A;
}
auto I8080::instructionLD_inn_rr(n16& x) -> void { Q = 0;
WZ = operands();
write(WZ + 0, x >> 0);
write(WZ + 1, x >> 8);
WZ++;
}
auto I8080::instructionLD_irr_a(n16& x) -> void { Q = 0;
WZ = x;
write(x, A);
WZL++;
WZH = A;
}
auto I8080::instructionLD_irr_n(n16& x) -> void { Q = 0;
auto addr = x;
auto data = operand();
if(&x == &ix.word || &x == &iy.word) wait(2);
write(addr, data);
}
auto I8080::instructionLD_irr_r(n16& x, n8& y) -> void { Q = 0;
write(x, y);
}
auto I8080::instructionLD_r_n(n8& x) -> void { Q = 0;
x = operand();
}
auto I8080::instructionLD_r_irr(n8& x, n16& y) -> void { Q = 0;
x = read(y);
}
auto I8080::instructionLD_r_r(n8& x, n8& y) -> void { Q = 0;
x = y;
}
auto I8080::instructionLD_rr_inn(n16& x) -> void { Q = 0;
WZ = operands();
x.byte(0) = read(WZ);
WZ++;
x.byte(1) = read(WZ);
}
auto I8080::instructionLD_rr_nn(n16& x) -> void { Q = 0;
x = operands();
}
auto I8080::instructionLD_sp_rr(n16& x) -> void { Q = 0;
wait(2);
SP = x;
}
auto I8080::instructionNOP() -> void { Q = 0;
}
auto I8080::instructionOR_a_irr(n16& x) -> void { Q = 1;
A = OR(A, read(x));
}
auto I8080::instructionOR_a_n() -> void { Q = 1;
A = OR(A, operand());
}
auto I8080::instructionOR_a_r(n8& x) -> void { Q = 1;
A = OR(A, x);
}
auto I8080::instructionOUT_in_a() -> void { Q = 0;
WZL = operand();
WZH = A;
out(WZ, A);
WZL++;
}
//note: even though "pop af" affects flags, it does not set Q
auto I8080::instructionPOP_rr(n16& x) -> void { Q = 0;
x = pop();
if(&x == &af.word) F = (F & 0xd7) | 2;
}
auto I8080::instructionPUSH_rr(n16& x) -> void { Q = 0;
wait(1);
if(&x == &af.word) F = (F & 0xd7) | 2;
push(x);
}
auto I8080::instructionRET() -> void { Q = 0;
WZ = pop();
PC = WZ;
}
auto I8080::instructionRET_c(bool c) -> void { Q = 0;
wait(1);
if(!c) return;
WZ = pop();
PC = WZ;
}
auto I8080::instructionRLA() -> void { Q = 1;
bool c = A.bit(7);
A = A << 1 | CF;
CF = c;
}
auto I8080::instructionRLCA() -> void { Q = 1;
bool c = A.bit(7);
A = A << 1 | c;
CF = c;
}
auto I8080::instructionRRA() -> void { Q = 1;
bool c = A.bit(0);
A = CF << 7 | A >> 1;
CF = c;
}
auto I8080::instructionRRCA() -> void { Q = 1;
bool c = A.bit(0);
A = c << 7 | A >> 1;
CF = c;
}
auto I8080::instructionRST_o(n3 vector) -> void { Q = 0;
wait(1);
push(PC);
WZ = vector << 3;
PC = WZ;
}
auto I8080::instructionSBC_a_irr(n16& x) -> void { Q = 1;
A = SUB(A, read(x), CF);
}
auto I8080::instructionSBC_a_n() -> void { Q = 1;
A = SUB(A, operand(), CF);
}
auto I8080::instructionSBC_a_r(n8& x) -> void { Q = 1;
A = SUB(A, x, CF);
}
auto I8080::instructionSCF() -> void {
CF = 1;
Q = 1;
}
auto I8080::instructionSUB_a_irr(n16& x) -> void { Q = 1;
A = SUB(A, read(x));
}
auto I8080::instructionSUB_a_n() -> void { Q = 1;
A = SUB(A, operand());
}
auto I8080::instructionSUB_a_r(n8& x) -> void { Q = 1;
A = SUB(A, x);
}
auto I8080::instructionXOR_a_irr(n16& x) -> void { Q = 1;
A = XOR(A, read(x));
}
auto I8080::instructionXOR_a_n() -> void { Q = 1;
A = XOR(A, operand());
}
auto I8080::instructionXOR_a_r(n8& x) -> void { Q = 1;
A = XOR(A, x);
}
+48
View File
@@ -0,0 +1,48 @@
auto I8080::wait(u32 clocks) -> void {
step(clocks);
}
auto I8080::opcode() -> n8 {
step(4);
return bus->read(PC++);
}
auto I8080::operand() -> n8 {
step(3);
return bus->read(PC++);
}
auto I8080::operands() -> n16 {
n16 data = operand() << 0;
return data | operand() << 8;
}
auto I8080::push(n16 x) -> void {
write(--SP, x >> 8);
write(--SP, x >> 0);
}
auto I8080::pop() -> n16 {
n16 data = read(SP++) << 0;
return data | read(SP++) << 8;
}
auto I8080::read(n16 address) -> n8 {
step(3);
return bus->read(address);
}
auto I8080::write(n16 address, n8 data) -> void {
step(3);
return bus->write(address, data);
}
auto I8080::in(n16 address) -> n8 {
step(3);
return bus->in(address);
}
auto I8080::out(n16 address, n8 data) -> void {
step(3);
return bus->out(address, data);
}
@@ -0,0 +1,22 @@
#define AF af.word
#define BC bc.word
#define DE de.word
#define HL hl.word
#define WZ wz.word
#define WZH wz.byte.hi
#define WZL wz.byte.lo
#define A af.byte.hi
#define F af.byte.lo
#define B bc.byte.hi
#define C bc.byte.lo
#define D de.byte.hi
#define E de.byte.lo
#define H hl.byte.hi
#define L hl.byte.lo
#define CF af.byte.lo.bit(0)
#define PF af.byte.lo.bit(2)
#define HF af.byte.lo.bit(4)
#define ZF af.byte.lo.bit(6)
#define SF af.byte.lo.bit(7)
@@ -0,0 +1,22 @@
auto I8080::serialize(serializer& s) -> void {
s((u32&)prefix);
s(af.word);
s(bc.word);
s(de.word);
s(hl.word);
s(af_.word);
s(bc_.word);
s(de_.word);
s(hl_.word);
s(ix.word);
s(iy.word);
s(ir.word);
s(wz.word);
s(SP);
s(PC);
s(EI);
s(P);
s(Q);
s(HALT);
s(INTE);
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -66,7 +66,7 @@ auto M68000::exception(u32 exception, u32 vector, u32 priority) -> void {
if(exception == Exception::Interrupt) {
// IACK vector number acquisition (+4 cyc normal or +10 to +18 cyc autovectored)
// & justify vector number (+4 cyc)
idle(16+4); // assuming autovector cycles (approximated for Megadrive)
idle(14+4); // assuming autovector cycles (approximated for Megadrive)
r.i = priority;
}
+101 -9
View File
@@ -1,19 +1,32 @@
auto MOS6502::algorithmADC(n8 i) -> n8 {
i16 o;
i16 o = A + i + C;
if(!BCD || !D) {
o = A + i + C;
C = o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
V = ~(A ^ i) & (A ^ o) & 0x80;
} else {
idle();
Z = n8(o) == 0;
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
if(o > 0x09) o += 0x06;
C = o > 0x0f;
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
N = o.bit(7);
V = ~(A ^ i) & (A ^ o) & 0x80;
if(o > 0x9f) o += 0x60;
C = o > 0xff;
}
C = o.bit(8);
Z = n8(o) == 0;
return o;
}
auto MOS6502::algorithmALR(n8 i) -> n8 {
n8 o = A & i;
C = o.bit(0);
o >>= 1;
Z = o == 0;
N = o.bit(7);
return o;
}
@@ -24,6 +37,29 @@ auto MOS6502::algorithmAND(n8 i) -> n8 {
return o;
}
auto MOS6502::algorithmANC(n8 i) -> n8 {
n8 o = A & i;
Z = o == 0;
N = o.bit(7);
C = N;
return o;
}
auto MOS6502::algorithmARR(n8 i) -> n8 {
n8 o = A & i;
Z = o == 0;
N = o.bit(7);
bool c = C;
o = c << 7 | o >> 1;
Z = o == 0;
N = o.bit(7);
C = o.bit(6);
V = o.bit(6) ^ o.bit(5);
return o;
}
auto MOS6502::algorithmASL(n8 i) -> n8 {
C = i.bit(7);
i <<= 1;
@@ -32,6 +68,23 @@ auto MOS6502::algorithmASL(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmATX(n8 i) -> n8 {
A |= 0xff; //TODO: OR value may differ on non-NES platforms
n8 o = A & i;
X = o;
Z = o == 0;
N = o.bit(7);
return o;
}
auto MOS6502::algorithmAXS(n8 i) -> n8 {
n9 o = (A & X) - i;
C = !o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
return o;
}
auto MOS6502::algorithmBIT(n8 i) -> n8 {
Z = (A & i) == 0;
V = i.bit(6);
@@ -70,6 +123,12 @@ auto MOS6502::algorithmDEC(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmDCP(n8 i) -> n8 {
auto value = algorithmDEC(i);
A = algorithmCMP(value);
return value;
}
auto MOS6502::algorithmEOR(n8 i) -> n8 {
n8 o = A ^ i;
Z = o == 0;
@@ -84,6 +143,12 @@ auto MOS6502::algorithmINC(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmISC(n8 i) -> n8 {
auto value = algorithmINC(i);
A = algorithmSBC(value);
return value;
}
auto MOS6502::algorithmLD(n8 i) -> n8 {
Z = i == 0;
N = i.bit(7);
@@ -98,6 +163,12 @@ auto MOS6502::algorithmLSR(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmSRE(n8 i) -> n8 {
auto value = algorithmLSR(i);
A = algorithmEOR(value);
return value;
}
auto MOS6502::algorithmORA(n8 i) -> n8 {
n8 o = A | i;
Z = o == 0;
@@ -114,6 +185,12 @@ auto MOS6502::algorithmROL(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmRLA(n8 i) -> n8 {
auto value = algorithmROL(i);
A = algorithmAND(value);
return value;
}
auto MOS6502::algorithmROR(n8 i) -> n8 {
bool c = C;
C = i.bit(0);
@@ -123,22 +200,37 @@ auto MOS6502::algorithmROR(n8 i) -> n8 {
return i;
}
auto MOS6502::algorithmRRA(n8 i) -> n8 {
auto value = algorithmROR(i);
A = algorithmADC(value);
return value;
}
auto MOS6502::algorithmSBC(n8 i) -> n8 {
i = ~i;
i16 o;
i16 o = A + i + C;
if(!BCD || !D) {
o = A + i + C;
C = o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
V = ~(A ^ i) & (A ^ o) & 0x80;
} else {
idle();
Z = n8(o) == 0;
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
if(o <= 0x0f) o -= 0x06;
C = o > 0x0f;
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
N = o.bit(7);
V = ~(A ^ i) & (A ^ o) & 0x80;
if(o <= 0xff) o -= 0x60;
C = o > 0xff;
}
C = o.bit(8);
Z = n8(o) == 0;
N = o.bit(7);
return o;
}
auto MOS6502::algorithmSLO(n8 i) -> n8 {
auto value = algorithmASL(i);
A = algorithmORA(value);
return value;
}
@@ -23,89 +23,114 @@ auto MOS6502::instruction() -> void {
op(0x04, NoOperationZeroPage)
op(0x05, ZeroPageRead, fp(ORA), A)
op(0x06, ZeroPageModify, fp(ASL))
op(0x07, ZeroPageModify, fp(SLO))
op(0x08, PushP)
op(0x09, Immediate, fp(ORA), A)
op(0x0a, Implied, fp(ASL), A)
op(0x0b, Immediate, fp(ANC), A)
op(0x0c, NoOperationAbsolute)
op(0x0d, AbsoluteRead, fp(ORA), A)
op(0x0e, AbsoluteModify, fp(ASL))
op(0x0f, AbsoluteModify, fp(SLO))
op(0x10, Branch, N == 0)
op(0x11, IndirectYRead, fp(ORA), A)
op(0x14, NoOperationZeroPage, X)
op(0x15, ZeroPageRead, fp(ORA), A, X)
op(0x16, ZeroPageModify, fp(ASL), X)
op(0x17, ZeroPageModify, fp(SLO), X)
op(0x18, Clear, C)
op(0x19, AbsoluteRead, fp(ORA), A, Y)
op(0x1a, NoOperation)
op(0x1b, AbsoluteModify, fp(SLO), Y)
op(0x1c, NoOperationAbsolute, X)
op(0x1d, AbsoluteRead, fp(ORA), A, X)
op(0x1e, AbsoluteModify, fp(ASL), X)
op(0x1f, AbsoluteModify, fp(SLO), X)
op(0x20, CallAbsolute)
op(0x21, IndirectXRead, fp(AND), A)
op(0x24, ZeroPageRead, fp(BIT), A)
op(0x25, ZeroPageRead, fp(AND), A)
op(0x26, ZeroPageModify, fp(ROL))
op(0x27, ZeroPageModify, fp(RLA))
op(0x28, PullP)
op(0x29, Immediate, fp(AND), A)
op(0x2a, Implied, fp(ROL), A)
op(0x2b, Immediate, fp(ANC), A)
op(0x2c, AbsoluteRead, fp(BIT), A)
op(0x2d, AbsoluteRead, fp(AND), A)
op(0x2e, AbsoluteModify, fp(ROL))
op(0x2f, AbsoluteModify, fp(RLA))
op(0x30, Branch, N == 1)
op(0x31, IndirectYRead, fp(AND), A)
op(0x34, NoOperationZeroPage, X)
op(0x35, ZeroPageRead, fp(AND), A, X)
op(0x36, ZeroPageModify, fp(ROL), X)
op(0x37, ZeroPageModify, fp(RLA), X)
op(0x38, Set, C)
op(0x39, AbsoluteRead, fp(AND), A, Y)
op(0x3a, NoOperation)
op(0x3b, AbsoluteModify, fp(RLA), Y)
op(0x3c, NoOperationAbsolute, X)
op(0x3d, AbsoluteRead, fp(AND), A, X)
op(0x3e, AbsoluteModify, fp(ROL), X)
op(0x3f, AbsoluteModify, fp(RLA), X)
op(0x40, ReturnInterrupt)
op(0x41, IndirectXRead, fp(EOR), A)
op(0x43, IndirectXRead, fp(SRE), X)
op(0x44, NoOperationZeroPage)
op(0x45, ZeroPageRead, fp(EOR), A)
op(0x46, ZeroPageModify, fp(LSR))
op(0x47, ZeroPageModify, fp(SRE))
op(0x48, Push, A)
op(0x49, Immediate, fp(EOR), A)
op(0x4a, Implied, fp(LSR), A)
op(0x4b, Immediate, fp(ALR), A)
op(0x4c, JumpAbsolute)
op(0x4d, AbsoluteRead, fp(EOR), A)
op(0x4e, AbsoluteModify, fp(LSR))
op(0x4f, AbsoluteModify, fp(SRE))
op(0x50, Branch, V == 0)
op(0x51, IndirectYRead, fp(EOR), A)
op(0x54, NoOperationZeroPage, X)
op(0x55, ZeroPageRead, fp(EOR), A, X)
op(0x56, ZeroPageModify, fp(LSR), X)
op(0x57, ZeroPageModify, fp(SRE), X)
op(0x58, Clear, I)
op(0x59, AbsoluteRead, fp(EOR), A, Y)
op(0x5a, NoOperation)
op(0x5b, AbsoluteModify, fp(SRE), Y)
op(0x5c, NoOperationAbsolute, X)
op(0x5d, AbsoluteRead, fp(EOR), A, X)
op(0x5e, AbsoluteModify, fp(LSR), X)
op(0x5f, AbsoluteModify, fp(SRE), X)
op(0x60, ReturnSubroutine)
op(0x61, IndirectXRead, fp(ADC), A)
op(0x64, NoOperationZeroPage)
op(0x65, ZeroPageRead, fp(ADC), A)
op(0x66, ZeroPageModify, fp(ROR))
op(0x67, ZeroPageModify, fp(RRA))
op(0x68, Pull, A)
op(0x69, Immediate, fp(ADC), A)
op(0x6a, Implied, fp(ROR), A)
op(0x6b, Immediate, fp(ARR), A)
op(0x6c, JumpIndirect)
op(0x6d, AbsoluteRead, fp(ADC), A)
op(0x6e, AbsoluteModify, fp(ROR))
op(0x6f, AbsoluteModify, fp(RRA))
op(0x70, Branch, V == 1)
op(0x71, IndirectYRead, fp(ADC), A)
op(0x74, NoOperationZeroPage, X)
op(0x75, ZeroPageRead, fp(ADC), A, X)
op(0x76, ZeroPageModify, fp(ROR), X)
op(0x77, ZeroPageModify, fp(RRA), X)
op(0x78, Set, I)
op(0x79, AbsoluteRead, fp(ADC), A, Y)
op(0x7a, NoOperation)
op(0x7b, AbsoluteModify, fp(RRA), Y)
op(0x7c, NoOperationAbsolute, X)
op(0x7d, AbsoluteRead, fp(ADC), A, X)
op(0x7e, AbsoluteModify, fp(ROR), X)
op(0x7f, AbsoluteModify, fp(RRA), X)
op(0x80, NoOperationImmediate)
op(0x81, IndirectXWrite, A)
op(0x82, NoOperationImmediate)
@@ -136,11 +161,13 @@ auto MOS6502::instruction() -> void {
op(0xa8, Transfer, A, Y, 1)
op(0xa9, Immediate, fp(LD), A)
op(0xaa, Transfer, A, X, 1)
op(0xab, Immediate, fp(ATX), A)
op(0xac, AbsoluteRead, fp(LD), Y)
op(0xad, AbsoluteRead, fp(LD), A)
op(0xae, AbsoluteRead, fp(LD), X)
op(0xb0, Branch, C == 1)
op(0xb1, IndirectYRead, fp(LD), A)
op(0xb3, IndirectYRead, fp(LD), A, X)
op(0xb4, ZeroPageRead, fp(LD), Y, X)
op(0xb5, ZeroPageRead, fp(LD), A, X)
op(0xb6, ZeroPageRead, fp(LD), X, Y)
@@ -156,49 +183,62 @@ auto MOS6502::instruction() -> void {
op(0xc4, ZeroPageRead, fp(CPY), Y)
op(0xc5, ZeroPageRead, fp(CMP), A)
op(0xc6, ZeroPageModify, fp(DEC))
op(0xc7, ZeroPageModify, fp(DCP))
op(0xc8, Implied, fp(INC), Y)
op(0xc9, Immediate, fp(CMP), A)
op(0xca, Implied, fp(DEC), X)
op(0xcb, Immediate, fp(AXS), X)
op(0xcc, AbsoluteRead, fp(CPY), Y)
op(0xcd, AbsoluteRead, fp(CMP), A)
op(0xce, AbsoluteModify, fp(DEC))
op(0xcf, AbsoluteModify, fp(DCP))
op(0xd0, Branch, Z == 0)
op(0xd1, IndirectYRead, fp(CMP), A)
op(0xd4, NoOperationZeroPage, X)
op(0xd5, ZeroPageRead, fp(CMP), A, X)
op(0xd6, ZeroPageModify, fp(DEC), X)
op(0xd7, ZeroPageModify, fp(DCP), X)
op(0xd8, Clear, D)
op(0xd9, AbsoluteRead, fp(CMP), A, Y)
op(0xda, NoOperation)
op(0xdb, AbsoluteModify, fp(DCP), Y)
op(0xdc, NoOperationAbsolute, X)
op(0xdd, AbsoluteRead, fp(CMP), A, X)
op(0xde, AbsoluteModify, fp(DEC), X)
op(0xdf, AbsoluteModify, fp(DCP), X)
op(0xe0, Immediate, fp(CPX), X)
op(0xe1, IndirectXRead, fp(SBC), A)
op(0xe2, NoOperationImmediate)
op(0xe4, ZeroPageRead, fp(CPX), X)
op(0xe5, ZeroPageRead, fp(SBC), A)
op(0xe6, ZeroPageModify, fp(INC))
op(0xe7, ZeroPageModify, fp(ISC))
op(0xe8, Implied, fp(INC), X)
op(0xe9, Immediate, fp(SBC), A)
op(0xea, NoOperation)
op(0xeb, Immediate, fp(SBC), A)
op(0xec, AbsoluteRead, fp(CPX), X)
op(0xed, AbsoluteRead, fp(SBC), A)
op(0xee, AbsoluteModify, fp(INC))
op(0xef, AbsoluteModify, fp(ISC))
op(0xf0, Branch, Z == 1)
op(0xf1, IndirectYRead, fp(SBC), A)
op(0xf4, NoOperationZeroPage, X)
op(0xf5, ZeroPageRead, fp(SBC), A, X)
op(0xf6, ZeroPageModify, fp(INC), X)
op(0xf7, ZeroPageModify, fp(ISC), X)
op(0xf8, Set, D)
op(0xf9, AbsoluteRead, fp(SBC), A, Y)
op(0xfa, NoOperation)
op(0xfb, AbsoluteModify, fp(ISC), Y)
op(0xfc, NoOperationAbsolute, X)
op(0xfd, AbsoluteRead, fp(SBC), A, X)
op(0xfe, AbsoluteModify, fp(INC), X)
op(0xff, AbsoluteModify, fp(ISC), X)
}
//unimplemented instruction
debug(unusual, "[6502] unimplemented opcode ", hex(code));
return instructionNoOperation();
}
@@ -112,6 +112,11 @@ auto MOS6502::instructionIndirectYRead(fp alu, n8& data) -> void {
L data = ALU(read(absolute + Y));
}
auto MOS6502::instructionIndirectYRead(fp alu, n8& data, n8& data2) -> void {
instructionIndirectYRead(alu, data);
data2 = data;
}
auto MOS6502::instructionIndirectYWrite(n8& data) -> void {
auto zeroPage = operand();
n16 absolute = load(zeroPage + 0);
+8 -2
View File
@@ -32,11 +32,17 @@ namespace ares {
#undef N
#undef L
auto MOS6502::power() -> void {
auto MOS6502::power(bool reset) -> void {
if(reset) {
S-=3;
P.i = 1;
return;
}
A = 0x00;
X = 0x00;
Y = 0x00;
S = 0xff;
S = 0xfd;
P = 0x04;
MDR = 0x00;
}
+13 -1
View File
@@ -14,7 +14,7 @@ struct MOS6502 {
virtual auto readDebugger(n16 addr) -> n8 { return 0; }
//mos6502.cpp
auto power() -> void;
auto power(bool reset = false) -> void;
//memory.cpp
auto idle() -> void;
@@ -31,20 +31,31 @@ struct MOS6502 {
using fp = auto (MOS6502::*)(n8) -> n8;
auto algorithmADC(n8) -> n8;
auto algorithmAND(n8) -> n8;
auto algorithmANC(n8) -> n8;
auto algorithmARR(n8) -> n8;
auto algorithmASL(n8) -> n8;
auto algorithmATX(n8) -> n8;
auto algorithmALR(n8) -> n8;
auto algorithmAXS(n8) -> n8;
auto algorithmBIT(n8) -> n8;
auto algorithmCMP(n8) -> n8;
auto algorithmCPX(n8) -> n8;
auto algorithmCPY(n8) -> n8;
auto algorithmDEC(n8) -> n8;
auto algorithmDCP(n8) -> n8;
auto algorithmEOR(n8) -> n8;
auto algorithmINC(n8) -> n8;
auto algorithmISC(n8) -> n8;
auto algorithmLD (n8) -> n8;
auto algorithmLSR(n8) -> n8;
auto algorithmSRE(n8) -> n8;
auto algorithmORA(n8) -> n8;
auto algorithmROL(n8) -> n8;
auto algorithmRLA(n8) -> n8;
auto algorithmROR(n8) -> n8;
auto algorithmRRA(n8) -> n8;
auto algorithmSBC(n8) -> n8;
auto algorithmSLO(n8) -> n8;
//instruction.cpp
auto interrupt() -> void;
@@ -66,6 +77,7 @@ struct MOS6502 {
auto instructionIndirectXRead(fp alu, n8& data) -> void;
auto instructionIndirectXWrite(n8& data) -> void;
auto instructionIndirectYRead(fp alu, n8& data) -> void;
auto instructionIndirectYRead(fp, n8& data, n8& data2) -> void;
auto instructionIndirectYWrite(n8& data) -> void;
auto instructionJumpAbsolute() -> void;
auto instructionJumpIndirect() -> void;
+2 -1
View File
@@ -2,7 +2,8 @@ struct Accuracy {
//enable all accuracy flags
static constexpr bool Reference = 0;
static constexpr bool Interpreter = 0 | Reference;
static constexpr bool Interpreter = 0 | Reference | !recompiler::generic::supported;
static constexpr bool CachedInterpreter = 0 & !Interpreter;
static constexpr bool Recompiler = !Interpreter;
//exceptions when the CPU or DMA accesses unaligned memory addresses
-71
View File
@@ -1,71 +0,0 @@
auto SH2::Recompiler::invalidate(u32 address) -> void {
auto pool = pools[address >> 8 & 0xffffff];
if(!pool) return;
memory::jitprotect(false);
pool->blocks[address >> 1 & 0x7f] = nullptr;
memory::jitprotect(true);
}
auto SH2::Recompiler::pool(u32 address) -> Pool* {
auto& pool = pools[address >> 8 & 0xffffff];
if(!pool) pool = (Pool*)allocator.acquire(sizeof(Pool));
return pool;
}
auto SH2::Recompiler::block(u32 address) -> Block* {
if(auto block = pool(address)->blocks[address >> 1 & 0x7f]) return block;
auto block = emit(address);
pool(address)->blocks[address >> 1 & 0x7f] = block;
memory::jitprotect(true);
return block;
}
alwaysinline auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
#define op(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 0;
#define br(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 1;
#include "decoder.hpp"
#undef op
#undef br
return 0;
}
#define CCR mem(sreg(1), offsetof(Registers, CCR))
auto SH2::Recompiler::emit(u32 address) -> Block* {
if(unlikely(allocator.available() < 1_MiB)) {
print("SH2 allocator flush\n");
memory::jitprotect(false);
allocator.release(bump_allocator::zero_fill);
memory::jitprotect(true);
reset();
}
auto block = (Block*)allocator.acquire(sizeof(Block));
beginFunction(2);
bool hasBranched = 0;
while(true) {
u16 instruction = self.readWord(address);
bool branched = emitInstruction(instruction);
add64(CCR, CCR, imm(1));
call(&SH2::instructionEpilogue);
address += 2;
if(hasBranched || (address & 0xfe) == 0) break; //block boundary
hasBranched = branched;
testJumpEpilog();
}
jumpEpilog();
memory::jitprotect(false);
block->code = endFunction();
return block;
}
#undef CCR
+64 -64
View File
@@ -6,68 +6,68 @@
#define d8 (opcode >> 0 & 0x0ff)
#define d12 (opcode >> 0 & 0xfff)
switch(opcode >> 8 & 0x00f0 | opcode & 0x000f) {
op(0x04, MOVBS0, m, n); //MOV.B Rm,@(R0,Rn)
op(0x05, MOVWS0, m, n); //MOV.W Rm,@(R0,Rn)
op(0x06, MOVLS0, m, n); //MOV.L Rm,@(R0,Rn)
op(0x07, MULL, m, n); //MUL.L Rm,Rn
op(0x0c, MOVBL0, m, n); //MOV.B @(R0,Rm),Rn
op(0x0d, MOVWL0, m, n); //MOV.W @(R0,Rm),Rn
op(0x0e, MOVLL0, m, n); //MOV.L @(R0,Rm),Rn
op(0x0f, MACL_, m, n); //MAC.L @Rm+,@Rn+
op(0x10 ... 0x1f, MOVLS4, m, d4, n); //MOV.L Rm,@(disp,Rn)
op(0x20, MOVBS, m, n); //MOV.B Rm,@Rn
op(0x21, MOVWS, m, n); //MOV.W Rm,@Rn
op(0x22, MOVLS, m, n); //MOV.L Rm,@Rn
op(0x24, MOVBM, m, n); //MOV.B Rm,@-Rn
op(0x25, MOVWM, m, n); //MOV.W Rm,@-Rn
op(0x26, MOVLM, m, n); //MOV.L Rm,@-Rn
op(0x27, DIV0S, m, n); //DIV0S Rm,Rn
op(0x28, TST, m, n); //TST Rm,Rn
op(0x29, AND, m, n); //AND Rm,Rn
op(0x2a, XOR, m, n); //XOR Rm,Rn
op(0x2b, OR, m, n); //OR Rm,Rn
op(0x2c, CMPSTR, m, n); //CMP/STR Rm,Rn
op(0x2d, XTRCT, m, n); //XTRCT Rm,Rn
op(0x2e, MULU, m, n); //MULU Rm,Rn
op(0x2f, MULS, m, n); //MULS Rm,Rn
op(0x30, CMPEQ, m, n); //CMP/EQ Rm,Rn
op(0x32, CMPHS, m, n); //CMP/HS Rm,Rn
op(0x33, CMPGE, m, n); //CMP/GE Rm,Rn
op(0x34, DIV1, m, n); //DIV1 Rm,Rn
op(0x35, DMULU, m, n); //DMULU.L Rm,Rn
op(0x36, CMPHI, m, n); //CMP/HI Rm,Rn
op(0x37, CMPGT, m, n); //CMP/GT Rm,Rn
op(0x38, SUB, m, n); //SUB Rm,Rn
op(0x3a, SUBC, m, n); //SUBC Rm,Rn
op(0x3b, SUBV, m, n); //SUBV Rm,Rn
op(0x3c, ADD, m, n); //ADD Rm,Rn
op(0x3d, DMULS, m, n); //DMULS.L Rm,Rn
op(0x3e, ADDC, m, n); //ADDC Rm,Rn
op(0x3f, ADDV, m, n); //ADDV Rm,Rn
op(0x4f, MACW, m, n); //MAC.W @Rm+,@Rn+
op(0x50 ... 0x5f, MOVLL4, m, d4, n); //MOV.L @(disp,Rm),Rn
op(0x60, MOVBL, m, n); //MOV.B @Rm,Rn
op(0x61, MOVWL, m, n); //MOV.W @Rm,Rn
op(0x62, MOVLL, m, n); //MOV.L @Rm,Rn
op(0x63, MOV, m, n); //MOV Rm,Rn
op(0x64, MOVBP, m, n); //MOV.B @Rm+,Rn
op(0x65, MOVWP, m, n); //MOV.W @Rm+,Rn
op(0x66, MOVLP, m, n); //MOV.L @Rm+,Rn
op(0x67, NOT, m, n); //NOT Rm,Rn
op(0x68, SWAPB, m, n); //SWAP.B Rm,Rn
op(0x69, SWAPW, m, n); //SWAP.W Rm,Rn
op(0x6a, NEGC, m, n); //NEGC Rm,Rn
op(0x6b, NEG, m, n); //NEG Rm,Rn
op(0x6c, EXTUB, m, n); //EXTU.B Rm,Rn
op(0x6d, EXTUW, m, n); //EXTU.W Rm,Rn
op(0x6e, EXTSB, m, n); //EXTS.B Rm,Rn
op(0x6f, EXTSW, m, n); //EXTS.W Rm,Rn
op(0x70 ... 0x7f, ADDI, i, n); //ADD #imm,Rn
op(0x90 ... 0x9f, MOVWI, d8, n); //MOV.W @(disp,PC),Rn
br(0xa0 ... 0xaf, BRA, d12); //BRA disp
br(0xb0 ... 0xbf, BSR, d12); //BSR disp
op(0xd0 ... 0xdf, MOVLI, d8, n); //MOV.L @(disp.PC),Rn
op(0xe0 ... 0xef, MOVI, i, n); //MOV #imm,Rn
op(0x04, MOVBS0, m, n); //MOV.B Rm,@(R0,Rn)
op(0x05, MOVWS0, m, n); //MOV.W Rm,@(R0,Rn)
op(0x06, MOVLS0, m, n); //MOV.L Rm,@(R0,Rn)
op(0x07, MULL, m, n); //MUL.L Rm,Rn
op(0x0c, MOVBL0, m, n); //MOV.B @(R0,Rm),Rn
op(0x0d, MOVWL0, m, n); //MOV.W @(R0,Rm),Rn
op(0x0e, MOVLL0, m, n); //MOV.L @(R0,Rm),Rn
op(0x0f, MACL_, m, n); //MAC.L @Rm+,@Rn+
op(range16(0x10, 0x1f), MOVLS4, m, d4, n); //MOV.L Rm,@(disp,Rn)
op(0x20, MOVBS, m, n); //MOV.B Rm,@Rn
op(0x21, MOVWS, m, n); //MOV.W Rm,@Rn
op(0x22, MOVLS, m, n); //MOV.L Rm,@Rn
op(0x24, MOVBM, m, n); //MOV.B Rm,@-Rn
op(0x25, MOVWM, m, n); //MOV.W Rm,@-Rn
op(0x26, MOVLM, m, n); //MOV.L Rm,@-Rn
op(0x27, DIV0S, m, n); //DIV0S Rm,Rn
op(0x28, TST, m, n); //TST Rm,Rn
op(0x29, AND, m, n); //AND Rm,Rn
op(0x2a, XOR, m, n); //XOR Rm,Rn
op(0x2b, OR, m, n); //OR Rm,Rn
op(0x2c, CMPSTR, m, n); //CMP/STR Rm,Rn
op(0x2d, XTRCT, m, n); //XTRCT Rm,Rn
op(0x2e, MULU, m, n); //MULU Rm,Rn
op(0x2f, MULS, m, n); //MULS Rm,Rn
op(0x30, CMPEQ, m, n); //CMP/EQ Rm,Rn
op(0x32, CMPHS, m, n); //CMP/HS Rm,Rn
op(0x33, CMPGE, m, n); //CMP/GE Rm,Rn
op(0x34, DIV1, m, n); //DIV1 Rm,Rn
op(0x35, DMULU, m, n); //DMULU.L Rm,Rn
op(0x36, CMPHI, m, n); //CMP/HI Rm,Rn
op(0x37, CMPGT, m, n); //CMP/GT Rm,Rn
op(0x38, SUB, m, n); //SUB Rm,Rn
op(0x3a, SUBC, m, n); //SUBC Rm,Rn
op(0x3b, SUBV, m, n); //SUBV Rm,Rn
op(0x3c, ADD, m, n); //ADD Rm,Rn
op(0x3d, DMULS, m, n); //DMULS.L Rm,Rn
op(0x3e, ADDC, m, n); //ADDC Rm,Rn
op(0x3f, ADDV, m, n); //ADDV Rm,Rn
op(0x4f, MACW, m, n); //MAC.W @Rm+,@Rn+
op(range16(0x50, 0x5f), MOVLL4, m, d4, n); //MOV.L @(disp,Rm),Rn
op(0x60, MOVBL, m, n); //MOV.B @Rm,Rn
op(0x61, MOVWL, m, n); //MOV.W @Rm,Rn
op(0x62, MOVLL, m, n); //MOV.L @Rm,Rn
op(0x63, MOV, m, n); //MOV Rm,Rn
op(0x64, MOVBP, m, n); //MOV.B @Rm+,Rn
op(0x65, MOVWP, m, n); //MOV.W @Rm+,Rn
op(0x66, MOVLP, m, n); //MOV.L @Rm+,Rn
op(0x67, NOT, m, n); //NOT Rm,Rn
op(0x68, SWAPB, m, n); //SWAP.B Rm,Rn
op(0x69, SWAPW, m, n); //SWAP.W Rm,Rn
op(0x6a, NEGC, m, n); //NEGC Rm,Rn
op(0x6b, NEG, m, n); //NEG Rm,Rn
op(0x6c, EXTUB, m, n); //EXTU.B Rm,Rn
op(0x6d, EXTUW, m, n); //EXTU.W Rm,Rn
op(0x6e, EXTSB, m, n); //EXTS.B Rm,Rn
op(0x6f, EXTSW, m, n); //EXTS.W Rm,Rn
op(range16(0x70, 0x7f), ADDI, i, n); //ADD #imm,Rn
op(range16(0x90, 0x9f), MOVWI, d8, n); //MOV.W @(disp,PC),Rn
br(range16(0xa0, 0xaf), BRA, d12); //BRA disp
br(range16(0xb0, 0xbf), BSR, d12); //BSR disp
op(range16(0xd0, 0xdf), MOVLI, d8, n); //MOV.L @(disp.PC),Rn
op(range16(0xe0, 0xef), MOVI, i, n); //MOV #imm,Rn
}
#undef n
#undef m
@@ -94,7 +94,7 @@
op(0xc0, MOVBSG, d8); //MOV.B R0,@(disp,GBR)
op(0xc1, MOVWSG, d8); //MOV.W R0,@(disp,GBR)
op(0xc2, MOVLSG, d8); //MOV.L R0,@(disp,GBR)
op(0xc3, TRAPA, i); //TRAPA #imm
br(0xc3, TRAPA, i); //TRAPA #imm
op(0xc4, MOVBLG, d8); //MOV.B @(disp,GBR),R0
op(0xc5, MOVWLG, d8); //MOV.W @(disp,GBR),R0
op(0xc6, MOVLLG, d8); //MOV.L @(disp,GBR),R0
@@ -174,7 +174,7 @@
br(0x000b, RTS); //RTS
op(0x0018, SETT); //SETT
op(0x0019, DIV0U); //DIV0U
op(0x001b, SLEEP); //SLEEP
br(0x001b, SLEEP); //SLEEP
op(0x0028, CLRMAC); //CLRMAC
br(0x002b, RTE); //RTE
}
+11 -13
View File
@@ -1,11 +1,11 @@
template<typename... P>
auto SH2::hint(P&&... p) const -> string {
if(1) return {};
if(1) return {"\e[0m\e[37m", forward<P>(p)..., "\e[0m"};
return {forward<P>(p)...};
if(1) return {terminal::csi, "0m", terminal::csi, "37m", std::forward<P>(p)..., terminal::csi, "0m"};
return {std::forward<P>(p)...};
}
auto SH2::disassembleInstruction() -> string {
auto SH2::disassembleInstruction(u16 opcode) -> string {
vector<string> s;
auto registerName = [&](u32 r) -> string {
@@ -48,8 +48,6 @@ auto SH2::disassembleInstruction() -> string {
return {"0x", hex(PC + (i12)d * 2, 8L)};
};
u16 opcode = readWord(PC - 4);
#define n (opcode >> 8 & 0x00f)
#define m (opcode >> 4 & 0x00f)
#define i (opcode >> 0 & 0x0ff)
@@ -81,7 +79,7 @@ auto SH2::disassembleInstruction() -> string {
case 0x0f: //MAC.L @Rm+,@Rn+
s = {"mac.l", postincrementIndirectRegister(m), postincrementIndirectRegister(n)};
break;
case 0x10 ... 0x1f: //MOV.L Rm,@(disp,Rn)
case range16(0x10, 0x1f): //MOV.L Rm,@(disp,Rn)
s = {"mov.l", registerValue(m), indirectRegisterDisplacement(n, d4, 4)};
break;
case 0x20: //MOV.B Rm,@Rn
@@ -174,7 +172,7 @@ auto SH2::disassembleInstruction() -> string {
case 0x4f: //MAC.W @Rm+,@Rn+
s = {"mac.w", postincrementIndirectRegister(m), postincrementIndirectRegister(n)};
break;
case 0x50 ... 0x5f: //MOV.L @(disp,Rm),Rn
case range16(0x50, 0x5f): //MOV.L @(disp,Rm),Rn
s = {"mov.l", indirectRegisterDisplacement(m, d4, 4), registerName(n)};
break;
case 0x60: //MOV.B @Rm,Rn
@@ -225,22 +223,22 @@ auto SH2::disassembleInstruction() -> string {
case 0x6f: //EXTS.W Rm,Rn
s = {"exts.w", registerValue(m), registerName(n)};
break;
case 0x70 ... 0x7f: //ADD #imm,Rn
case range16(0x70, 0x7f): //ADD #imm,Rn
s = {"add", immediate(i), registerValue(n)};
break;
case 0x90 ... 0x9f: //MOV.W @(disp,PC),Rn
case range16(0x90, 0x9f): //MOV.W @(disp,PC),Rn
s = {"mov.w", pcRelativeDisplacement(d8, 2), registerName(n)};
break;
case 0xa0 ... 0xaf: //BRA disp
case range16(0xa0, 0xaf): //BRA disp
s = {"bra", branch12(d12)};
break;
case 0xb0 ... 0xbf: //BSR disp
case range16(0xb0, 0xbf): //BSR disp
s = {"bsr", branch12(d12)};
break;
case 0xd0 ... 0xdf: //MOV.L @(disp,PC),Rn
case range16(0xd0, 0xdf): //MOV.L @(disp,PC),Rn
s = {"mov.l", pcRelativeDisplacement(d8, 4), registerName(n)};
break;
case 0xe0 ... 0xef: //MOV #imm,Rn
case range16(0xe0, 0xef): //MOV #imm,Rn
s = {"mov", immediate(i), registerName(n)};
break;
}
+8 -14
View File
@@ -1,6 +1,6 @@
auto SH2::exceptionHandler() -> void {
if(!exceptions) return;
if(inDelaySlot()) return;
if(inDelaySlot()) { cyclesUntilRecompilerExit = 0; return; }
if(exceptions & ResetCold) {
exceptions &= ~ResetCold;
@@ -34,22 +34,16 @@ auto SH2::push(u32 data) -> void {
auto SH2::interrupt(u8 level, u8 vector) -> void {
push(SR);
push(PC);
push(PC - 4);
jump(readLong(VBR + vector * 4) + 4);
SR.I = level;
}
auto SH2::exception(u8 vector) -> void {
push(SR);
push(PC - 2);
jump(readLong(VBR + vector * 4) + 4);
}
auto SH2::addressErrorCPU() -> void {
static constexpr u8 vector = 0x09;
SP &= ~3; //not accurate; but prevents infinite recursion
push(SR);
push(PC);
push(PC - 4);
jump(readLong(VBR + vector * 4) + 4);
}
@@ -57,23 +51,23 @@ auto SH2::addressErrorDMA() -> void {
static constexpr u8 vector = 0x0a;
SP &= ~3; //not accurate; but prevents infinite recursion
push(SR);
push(PC);
push(PC - 4);
jump(readLong(VBR + vector * 4) + 4);
}
auto SH2::illegalInstruction() -> void {
if(inDelaySlot()) return illegalSlotInstruction();
debug(unusual, "[SH2] illegal instruction: 0x", hex(busReadWord(PC - 4), 4L), " @ 0x", hex(PC - 4));
static constexpr u8 vector = 0x04;
push(SR);
push(PC);
push(PC - 4);
jump(readLong(VBR + vector * 4) + 4);
debug(unusual, "[SH2] illegal instruction: 0x", hex(busReadWord(PC - 4), 4L), " @ 0x", hex(PC - 4));
}
auto SH2::illegalSlotInstruction() -> void {
debug(unusual, "[SH2] illegal slot instruction: 0x", hex(busReadWord(PC - 4), 4L));
static constexpr u8 vector = 0x06;
push(SR);
push(PC - 2);
push(PPC - 4);
jump(readLong(VBR + vector * 4) + 4);
debug(unusual, "[SH2] illegal slot instruction: 0x", hex(busReadWord(PC - 4), 4L));
}
+5 -3
View File
@@ -4,13 +4,11 @@ auto SH2::jump(u32 pc) -> void {
}
auto SH2::branch(u32 pc) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
PPC = pc;
PPM = Branch::Take;
}
auto SH2::delaySlot(u32 pc) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
PPC = pc;
PPM = Branch::Slot;
}
@@ -25,6 +23,7 @@ auto SH2::instruction() -> void {
}
ID = 0;
u16 opcode = readWord(PC - 4);
instructionPrologue(opcode);
execute(opcode);
instructionEpilogue();
}
@@ -37,7 +36,10 @@ auto SH2::instruction() -> void {
do {
auto block = recompiler.block(PC - 4);
block->execute(*this);
} while (CCR <= recompiler.min_cycles);
} while (CCR < cyclesUntilRecompilerExit);
// Reset the count as it may have been set to 0 for an early exit
cyclesUntilRecompilerExit = recompilerStepCycles;
step(CCR);
CCR = 0;
+25 -12
View File
@@ -43,6 +43,7 @@ auto SH2::ANDM(u32 i) -> void {
//BF disp
auto SH2::BF(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
if(SR.T == 0) {
branch(PC + 4 + (s8)d * 2);
}
@@ -50,6 +51,7 @@ auto SH2::BF(u32 d) -> void {
//BF/S disp
auto SH2::BFS(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
if(SR.T == 0) {
delaySlot(PC + 4 + (s8)d * 2);
}
@@ -57,28 +59,33 @@ auto SH2::BFS(u32 d) -> void {
//BRA disp
auto SH2::BRA(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
delaySlot(PC + 4 + (i12)d * 2);
}
//BRAF disp
auto SH2::BRAF(u32 m) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
delaySlot(PC + 4 + R[m]);
}
//BSR disp
auto SH2::BSR(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
PR = PC;
delaySlot(PC + 4 + (i12)d * 2);
}
//BSRF Rm
auto SH2::BSRF(u32 m) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
PR = PC;
delaySlot(PC + 4 + R[m]);
}
//BT disp
auto SH2::BT(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
if(SR.T == 1) {
branch(PC + 4 + (s8)d * 2);
}
@@ -86,6 +93,7 @@ auto SH2::BT(u32 d) -> void {
//BT/S disp
auto SH2::BTS(u32 d) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
if(SR.T == 1) {
delaySlot(PC + 4 + (s8)d * 2);
}
@@ -221,11 +229,13 @@ auto SH2::ILLEGAL() -> void {
//JMP @Rm
auto SH2::JMP(u32 m) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
delaySlot(R[m] + 4);
}
//JSR @Rm
auto SH2::JSR(u32 m) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
PR = PC;
delaySlot(R[m] + 4);
}
@@ -503,18 +513,21 @@ auto SH2::MOVI(u32 i, u32 n) -> void {
}
//MOV.W @(disp,PC),Rn
auto SH2::MOVWI(u32 d, u32 n) -> void {
R[n] = (s16)readWord(PC + d * 2);
noinline auto SH2::MOVWI(u32 d, u32 n) -> void {
u32 pc = inDelaySlot() ? PPC - 2 : PC;
R[n] = (s16)readWord(pc + d * 2);
}
//MOV.L @(disp,PC),Rn
auto SH2::MOVLI(u32 d, u32 n) -> void {
R[n] = readLong((PC & ~3) + d * 4);
noinline auto SH2::MOVLI(u32 d, u32 n) -> void {
u32 pc = inDelaySlot() ? PPC - 2 : PC;
R[n] = readLong((pc & ~3) + d * 4);
}
//MOVA @(disp,PC),R0
auto SH2::MOVA(u32 d) -> void {
R[0] = (PC & ~3) + d * 4 - inDelaySlot() * 2;
noinline auto SH2::MOVA(u32 d) -> void {
u32 pc = inDelaySlot() ? PPC - 2 : PC;
R[0] = (pc & ~3) + d * 4;
}
//MOVT Rn
@@ -602,13 +615,15 @@ auto SH2::ROTR(u32 n) -> void {
//RTE
auto SH2::RTE() -> void {
delaySlot(readLong(SP + 0));
if(inDelaySlot()) return illegalSlotInstruction();
delaySlot(readLong(SP + 0) + 4);
SR = readLong(SP + 4);
SP += 8;
}
//RTS
auto SH2::RTS() -> void {
if(inDelaySlot()) return illegalSlotInstruction();
delaySlot(PR + 4);
}
@@ -800,18 +815,16 @@ auto SH2::TAS(u32 n) -> void {
) return (void)(exceptions |= AddressErrorCPU);
}
auto cacheEnable = cache.enable;
cache.enable = 0;
u8 b = readByte(R[n]);
cache.enable = cacheEnable;
u8 b = readByte<Bus::Internal>(R[n]);
SR.T = b == 0;
writeByte(R[n], b | 0x80);
}
//TRAPA #imm
auto SH2::TRAPA(u32 i) -> void {
if(inDelaySlot()) return illegalSlotInstruction();
push(SR);
push(PC + 2);
push(PC - 2);
branch(readLong(VBR + i * 4) + 4);
}
File diff suppressed because it is too large. Load diff
+9 -3
View File
@@ -1,3 +1,6 @@
#define XXH_INLINE_ALL
#include <xxhash.h>
#include <ares/ares.hpp>
#include "sh2.hpp"
@@ -45,11 +48,12 @@ auto SH2::power(bool reset) -> void {
ET = 0;
ID = 0;
exceptions = !reset ? ResetCold : ResetWarm;
cyclesUntilRecompilerExit = 0;
cache = {*this};
intc = {*this};
dmac = {*this};
sci = {*this};
sci = {*this, reset ? sci.link : maybe<SH2&>()};
wdt = {};
ubc = {};
frt = {*this};
@@ -60,8 +64,10 @@ auto SH2::power(bool reset) -> void {
cache.power();
if constexpr(Accuracy::Recompiler) {
auto buffer = ares::Memory::FixedAllocator::get().tryAcquire(64_MiB);
recompiler.allocator.resize(64_MiB, bump_allocator::executable | bump_allocator::zero_fill, buffer);
if(!reset) {
auto buffer = ares::Memory::FixedAllocator::get().tryAcquire(64_MiB);
recompiler.allocator.resize(64_MiB, bump_allocator::executable, buffer);
}
recompiler.reset();
}
}
+35 -5
View File
@@ -7,6 +7,7 @@
namespace ares {
struct SH2 {
virtual auto instructionPrologue(u16 instruction) -> void = 0;
virtual auto step(u32 clocks) -> void = 0;
virtual auto busReadByte(u32 address) -> u32 = 0;
virtual auto busReadWord(u32 address) -> u32 = 0;
@@ -29,7 +30,6 @@ struct SH2 {
auto exceptionHandler() -> void;
auto push(u32 data) -> void;
auto interrupt(u8 level, u8 vector) -> void;
auto exception(u8 vector) -> void;
auto addressErrorCPU() -> void;
auto addressErrorDMA() -> void;
auto illegalInstruction() -> void;
@@ -190,7 +190,7 @@ struct SH2 {
//disassembler.cpp
template<typename... P> auto hint(P&&...) const -> string;
auto disassembleInstruction() -> string;
auto disassembleInstruction(u16 opcode) -> string;
auto disassembleContext() -> string;
static constexpr u32 undefined = 0;
@@ -246,6 +246,9 @@ struct SH2 {
};
u32 exceptions = 0; //delayed exception flags
s32 cyclesUntilRecompilerExit = 0;
s32 recompilerStepCycles = 0;
struct Recompiler : recompiler::generic {
SH2& self;
Recompiler(SH2& self) : self(self), generic(allocator) {}
@@ -256,27 +259,54 @@ struct SH2 {
}
u8* code;
u8 size;
};
struct Pool {
u32 generation;
u64 dirty;
Block* blocks[1 << 7];
};
struct BlockHashPair {
auto operator==(const BlockHashPair& source) const -> bool { return hashcode == source.hashcode; }
auto hash() const -> u32 { return hashcode; }
Block* block;
u64 hashcode;
};
auto reset() -> void {
generation = 0;
blocks.reset();
for(u32 index : range(1 << 24)) pools[index] = nullptr;
}
auto invalidate(u32 address) -> void;
auto invalidateCached() -> void {
generation++;
}
auto invalidate(u32 address, u8 size) -> void;
auto pool(u32 address) -> Pool*;
auto block(u32 address) -> Block*;
auto measure(u32 address) -> u8;
auto hash(u32 address, u8 size) -> u64;
auto emit(u32 address) -> Block*;
auto emitInstruction(u16 opcode) -> bool;
auto emitInstruction(u16 opcode) -> u32;
auto getSR(reg dst) -> void;
auto setSR(reg src) -> void;
template<typename F> auto checkDelaySlot(F body) -> void;
auto isTerminal(u16 instruction) -> bool;
static auto mask(u8 address, u8 size) -> u64;
bool callInstructionPrologue = false;
bool inDelaySlot;
u32 generation;
bump_allocator allocator;
hashset<BlockHashPair> blocks;
u16 instructions[1 << 7];
Pool* pools[1 << 24];
int min_cycles = 0;
} recompiler{*this};
#include "sh7604/sh7604.hpp"
+74 -27
View File
@@ -1,8 +1,10 @@
auto SH2::readByte(u32 address) -> u32 {
template<u32 Origin> auto SH2::readByte(u32 address) -> u32 {
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) return cache.read<Byte>(address);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) return cache.read<Byte>(address);
}
return busReadByte(address & 0x1fff'ffff);
}
@@ -11,7 +13,10 @@ auto SH2::readByte(u32 address) -> u32 {
}
case Area::Data: {
return cache.readData<Byte>(address);
if constexpr(Origin == Bus::Cache) {
return cache.readData<Byte>(address);
}
break;
}
case Area::IO: {
@@ -28,7 +33,7 @@ auto SH2::readByte(u32 address) -> u32 {
return 0;
}
auto SH2::readWord(u32 address) -> u32 {
template<u32 Origin> auto SH2::readWord(u32 address) -> u32 {
if constexpr(Accuracy::AddressErrors) {
if(unlikely(address & 1)) return exceptions |= AddressErrorCPU, 0;
}
@@ -36,7 +41,9 @@ auto SH2::readWord(u32 address) -> u32 {
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) return cache.read<Word>(address);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) return cache.read<Word>(address);
}
return busReadWord(address & 0x1fff'fffe);
}
@@ -45,7 +52,10 @@ auto SH2::readWord(u32 address) -> u32 {
}
case Area::Data: {
return cache.readData<Word>(address);
if constexpr(Origin == Bus::Cache) {
return cache.readData<Word>(address);
}
break;
}
case Area::IO: {
@@ -60,7 +70,7 @@ auto SH2::readWord(u32 address) -> u32 {
return 0;
}
auto SH2::readLong(u32 address) -> u32 {
template<u32 Origin> auto SH2::readLong(u32 address) -> u32 {
if constexpr(Accuracy::AddressErrors) {
if(unlikely(address & 3)) return exceptions |= AddressErrorCPU, 0;
}
@@ -68,7 +78,9 @@ auto SH2::readLong(u32 address) -> u32 {
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) return cache.read<Long>(address);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) return cache.read<Long>(address);
}
return busReadLong(address & 0x1fff'fffc);
}
@@ -77,11 +89,17 @@ auto SH2::readLong(u32 address) -> u32 {
}
case Area::Address: {
return cache.readAddress(address);
if constexpr(Origin == Bus::Cache) {
return cache.readAddress(address);
}
break;
}
case Area::Data: {
return cache.readData<Long>(address);
if constexpr(Origin == Bus::Cache) {
return cache.readData<Long>(address);
}
break;
}
case Area::IO: {
@@ -104,28 +122,37 @@ auto SH2::readLong(u32 address) -> u32 {
return 0;
}
auto SH2::writeByte(u32 address, u32 data) -> void {
template<u32 Origin> auto SH2::writeByte(u32 address, u32 data) -> void {
if constexpr(Accuracy::Recompiler) {
recompiler.invalidate(address);
recompiler.invalidate(address, 1);
}
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) cache.write<Byte>(address, data);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) cache.write<Byte>(address, data);
}
return busWriteByte(address & 0x1fff'ffff, data);
}
case Area::Uncached: {
cyclesUntilRecompilerExit = 0;
return busWriteByte(address & 0x1fff'ffff, data);
}
case Area::Purge: {
return cache.purge(address);
if constexpr(Origin == Bus::Cache) {
return cache.purge(address);
}
break;
}
case Area::Data: {
return cache.writeData<Byte>(address, data);
if constexpr(Origin == Bus::Cache) {
return cache.writeData<Byte>(address, data);
}
break;
}
case Area::IO: {
@@ -140,32 +167,41 @@ auto SH2::writeByte(u32 address, u32 data) -> void {
}
}
auto SH2::writeWord(u32 address, u32 data) -> void {
template<u32 Origin> auto SH2::writeWord(u32 address, u32 data) -> void {
if constexpr(Accuracy::AddressErrors) {
if(unlikely(address & 1)) return (void)(exceptions |= AddressErrorCPU);
}
if constexpr(Accuracy::Recompiler) {
recompiler.invalidate(address);
recompiler.invalidate(address, 2);
}
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) cache.write<Word>(address, data);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) cache.write<Word>(address, data);
}
return busWriteWord(address & 0x1fff'fffe, data);
}
case Area::Uncached: {
cyclesUntilRecompilerExit = 0;
return busWriteWord(address & 0x1fff'fffe, data);
}
case Area::Purge: {
return cache.purge(address);
if constexpr(Origin == Bus::Cache) {
return cache.purge(address);
}
break;
}
case Area::Data: {
return cache.writeData<Word>(address, data);
if constexpr(Origin == Bus::Cache) {
return cache.writeData<Word>(address, data);
}
break;
}
case Area::IO: {
@@ -177,37 +213,48 @@ auto SH2::writeWord(u32 address, u32 data) -> void {
}
}
auto SH2::writeLong(u32 address, u32 data) -> void {
template<u32 Origin> auto SH2::writeLong(u32 address, u32 data) -> void {
if constexpr(Accuracy::AddressErrors) {
if(unlikely(address & 3)) return (void)(exceptions |= AddressErrorCPU);
}
if constexpr(Accuracy::Recompiler) {
recompiler.invalidate(address + 0);
recompiler.invalidate(address + 2);
recompiler.invalidate(address, 4);
}
switch(address >> 29) {
case Area::Cached: {
if(likely(cache.enable)) cache.write<Long>(address, data);
if constexpr(Origin == Bus::Cache) {
if(likely(cache.enable)) cache.write<Long>(address, data);
}
return busWriteLong(address & 0x1fff'fffc, data);
}
case Area::Uncached: {
cyclesUntilRecompilerExit = 0;
return busWriteLong(address & 0x1fff'fffc, data);
}
case Area::Purge: {
return cache.purge(address);
if constexpr(Origin == Bus::Cache) {
return cache.purge(address);
}
break;
}
case Area::Address: {
return cache.writeAddress(address, data);
if constexpr(Origin == Bus::Cache) {
return cache.writeAddress(address, data);
}
break;
}
case Area::Data: {
return cache.writeData<Long>(address, data);
if constexpr(Origin == Bus::Cache) {
return cache.writeData<Long>(address, data);
}
break;
}
case Area::IO: {
@@ -88,12 +88,20 @@ auto SH2::Cache::purge(u32 address) -> void {
if(tags[Way1 | entry] == tag) tags[Way1 | entry] |= Invalid;
if(tags[Way2 | entry] == tag) tags[Way2 | entry] |= Invalid;
if(tags[Way3 | entry] == tag) tags[Way3 | entry] |= Invalid;
if constexpr(Accuracy::Recompiler) {
self->recompiler.invalidate(address & 0x1fff'fff0, 0x10);
}
}
template<u32 Ways>
auto SH2::Cache::purge() -> void {
for(auto index : range(64)) lrus[index] = 0;
for(auto index : range(64 * Ways)) tags[index] |= Invalid;
if constexpr(Accuracy::Recompiler) {
self->recompiler.invalidateCached();
}
}
auto SH2::Cache::power() -> void {
+12 -8
View File
@@ -4,12 +4,16 @@ auto SH2::DMAC::run() -> void {
if(chcr[c].ar) {
transfer(c);
} else if(drcr[c] == 0) {
if(dreq) transfer(c);
if(dreq[c]) transfer(c);
// Note: DACK is not implemented (not used by 32X)
} else if(drcr[c] == 1) {
debug(unimplemented, "[SH2] DMA RXI");
} else if(drcr[c] == 2) {
debug(unimplemented, "[SH2] DMA TXI");
} else {
continue;
}
break; // ignoring cycle-steal mode for now
}
}
}
@@ -18,7 +22,7 @@ auto SH2::DMAC::transfer(bool c) -> void {
switch(chcr[c].ts) {
case 0: //8-bit
self->writeByte(dar[c], self->readByte(sar[c]));
self->writeByte<Bus::Internal>(dar[c], self->readByte<Bus::Internal>(sar[c]));
break;
case 1: //16-bit
if constexpr(Accuracy::AddressErrors) {
@@ -27,7 +31,7 @@ auto SH2::DMAC::transfer(bool c) -> void {
break;
}
}
self->writeWord(dar[c], self->readWord(sar[c]));
self->writeWord<Bus::Internal>(dar[c], self->readWord<Bus::Internal>(sar[c]));
break;
case 2: //32-bit
if constexpr(Accuracy::AddressErrors) {
@@ -36,7 +40,7 @@ auto SH2::DMAC::transfer(bool c) -> void {
break;
}
}
self->writeLong(dar[c], self->readLong(sar[c]));
self->writeLong<Bus::Internal>(dar[c], self->readLong<Bus::Internal>(sar[c]));
break;
case 3: //32-bit x4
if constexpr(Accuracy::AddressErrors) {
@@ -45,10 +49,10 @@ auto SH2::DMAC::transfer(bool c) -> void {
break;
}
}
self->writeLong(dar[c] + 0, self->readLong(sar[c] + 0));
self->writeLong(dar[c] + 4, self->readLong(sar[c] + 4));
self->writeLong(dar[c] + 8, self->readLong(sar[c] + 8));
self->writeLong(dar[c] + 12, self->readLong(sar[c] + 12));
self->writeLong<Bus::Internal>(dar[c] + 0, self->readLong<Bus::Internal>(sar[c] + 0));
self->writeLong<Bus::Internal>(dar[c] + 4, self->readLong<Bus::Internal>(sar[c] + 4));
self->writeLong<Bus::Internal>(dar[c] + 8, self->readLong<Bus::Internal>(sar[c] + 8));
self->writeLong<Bus::Internal>(dar[c] + 12, self->readLong<Bus::Internal>(sar[c] + 12));
sar[c] += 16; //always increments regardless of chcr[c].sm
tcr[c] -= 3; //always decrements by four instead of by one
break;
Loaded 100 of 2366 files, more files were not shown because too many files have changed in this diff. Show more