Compare commits

...
662 Commits
Author SHA1 Message Date
Luke Usher 443aabb89b bump version number to v129 2022-07-13 17:53:31 +01:00
Luke Usher 93275dba2c a26: preliminary atari 2600 emulation
This commit introduces preliminary Atari 2600 emulation.

In the current state, many games are working but with the following caveats

1. Only a small subset of mappers are supported
2. The TIA isn't cycle accurate yet; many games have rendering and/or collision issues.

There is currently little-to-no reason to use this over other Atari 2600 emulators at this time,
but the goal is to eventually have cycle-accurate atari emulation.
2022-07-13 16:56:52 +01:00
Giovanni Bajo 3767568cdb n64: fix RSP emulation on ARM
ARM computers fall back to the standard SISD code, where there were some
bugs. Fixed through n64-systemtest (which is now a clean pass on
Apple M1)
2022-07-07 16:46:23 +01:00
Giovanni Bajo 7cfb150be8 n64: improve freeze bit emulation
It looks like the DMA register latches are still working while RDP freeze
is set, so just the DMA itself is frozen.

Fix some tests in n64-systemtest.
2022-06-28 23:55:45 +01:00
Giovanni Bajo 049211abae n64: implement basic behavior of freeze bit
The exact behavior of the freeze bit hasn't been investigate yet, but
at the very least it stops the RDP command engine. This PR does a
basic approximation of it, pending more in-depth tests.

Fixes Banjo-Tooie.
2022-06-22 09:13:03 +01:00
Giovanni Bajo a7ce0c22fa n64: add region check to TLBP
This was missed in the 64-bit TLB series (the region check only makes
sense for 64-bit TLBs).

Fix one test in n64-systemtest
2022-06-19 22:45:51 +01:00
Giovanni Bajo 7205a39f23 n64: fix 64-bit TLB vaddr match
Fix several tests in n64-systemtest.
2022-06-16 16:40:24 +01:00
Giovanni Bajo 99b759b630 n64: improve 64-bit TLB exceptions
It looks like address exceptions and TLB exceptions always set the
same registers (though some are marked as undefined in the manual), so
we unify the two implementations.

Fix several tests in n64-systemtest.
2022-06-16 16:40:24 +01:00
Giovanni Bajo a9ced1175b n64: rename address variables to vaddr when they refer to a VA
There's a big confusion in the CPU core between virtual and physical
addresses, and we have been fixing many bugs around this. Now that the
situation seems stable, do a big sweep and rename all "address" variables
to "vaddr" when they refer to a virtual address, to simplify reading
the code.

"address" is kept for physical addresses, which is consistent to the
rest of the code outside the CPU that only talks about physical
addresses anyway.

No functional changes.
2022-06-16 16:40:24 +01:00
Giovanni Bajo aeb5bc4597 n64: fix 64-bit addressing
This commit do further fixes 64-bit addressing. In 64-bit mode, the bus
addressable range is 2Gb (instead of 512Mb), so we need to mask
appropriately all physical addresses.

Fix several tests in n64-systemtest.
2022-06-16 16:40:24 +01:00
Giovanni Bajo f031407a14 n64: more accurate RDP status bit management
This begins improving the RDP status bits to more accurately reflect
what it can be seen on real hardware. It also undoes a hack for RDP
freeze that was allowing Banjo-Tooie to boot. Being a game-specific
hack, I think it is better to simply disable and wait until we find
out how to properly fix the game.

Fix a few new tests in n64-systemtest.
2022-06-14 13:26:13 +01:00
Giovanni Bajo 3c42e12b75 n64: implement invalid COP0 register access
Fix a few tests in n64-systemtest
2022-06-13 09:22:53 +01:00
TascoDLX 2ce9d210af md: handle controller port disconnect 2022-06-11 14:41:02 +01:00
TascoDLX a038b2cf61 desktop-ui: omit null allocation call when disconnecting port device 2022-06-11 14:41:02 +01:00
TascoDLX cee2ea332f mcd: force workaround for Corpse Killer (CD) gamepad bug 2022-06-11 14:41:02 +01:00
TascoDLX b1e3d90790 mia: extract serial number from MCD header to id disc 2022-06-11 14:41:02 +01:00
TascoDLX f306d1223c md: enable controller port disconnect via deallocation 2022-06-11 14:41:02 +01:00
TascoDLX e90e6ab846 desktop-ui: allow disconnection from ports 2022-06-11 14:41:02 +01:00
Luke Usher 6a103ed073 md: add destructor to fighting pad 2022-06-11 14:39:08 +01:00
Luke Usher 96663687f2 thread: prevent switching to threads that were destroyed while a call to Thread::synchronize() was in progress 2022-06-11 14:32:06 +01:00
remutro 8d17ae1697 validate we found correct number of bios files for NeoGeo 2022-06-07 07:42:37 +01:00
Giovanni Bajo a2e4807810 n64: fix RSP opcode STV
Fix one test in n64-systemtest
2022-06-04 00:23:15 +01:00
Giovanni Bajo 803daf7642 n64: fix RSP opcode SFV
This one is the weirdest. The current implementation is unrolled, but
I can't find a pattern that works. Surely there must be one as the
hardware doesn't surely have a lookup table. Anyway for now this
implementation is completely accurate, albeit verbose.

Fix one test in n64-systemtest
2022-06-04 00:23:15 +01:00
remutro c88fb1155b Fix identifier for WCW Mayhem 2022-06-04 00:05:58 +01:00
Giovanni Bajo 246a5eee93 n64: fix LWL/LWR accesses over RCP ranges
On real hardware, LWL/LWR execute a SysAD 32-bit masked read. Ares
was emulating them with one or multiple shorter accesses, which is
not the correct behavior wrt RCP hardware registers and PI bus area,
where the RCP incorrectly ignores the access size causing several bugs.

After this commit, LWL/LWR always do a 32-bit access on the bus, which
makes sure that we replicate the exact behavior.

SWL/SWR have a similar problem but harder to fix, because the SysAD
bus can do 24-bit writes, which is not something that Ares memory
functions support. So that's for another day.
2022-06-04 00:05:48 +01:00
remutro 4607b40e23 Fix incorrect identifier for South Park Rally (USA) 2022-06-03 21:43:36 +01:00
Giovanni Bajo d0a963ab42 n64: fix RDP scissoring in copy/fill mode
This fixes a bug in mame RDP with respect to scissoring: the upper X
bound is inclusive in copy and fill modes (and exclusives in the others).

This seems another bug in Mame's refactorings that doesn't appear
in upstream angrylion, given the fact that both cen64 and parallel-RDP
emulates this correctly.
2022-06-03 21:43:30 +01:00
Luke Usher bb58366efd desktop-ui: support choosing which system to emulate from command line
examples:

`ares --system "PlayStation" game.cue`
`ares --system "Super Famicom" game.sfc`
2022-06-02 15:54:52 +01:00
CasualPokePlayer 0891a102e4 Update instruction.hpp 2022-06-01 13:36:51 +01:00
CasualPokePlayer 0e74d5c8e3 avoid u128 usage
Also adding in protection against another bad shift case. Can't use the same code here though... could avoid the branching if it can be safely assumed _addressBits is always at least 3
2022-06-01 13:36:51 +01:00
CasualPokePlayer 672940cf06 debugger: fix address masking in instruction tracer (for 64 bit addresses)
This is similar to https://github.com/ares-emulator/ares/commit/822186413c9274295e49b922297f0cc744921eda, but fixes masking for N64 as it has 64 bit addresses.
2022-06-01 13:36:51 +01:00
Luke Usher 9ecfbdbe76 gba: prevent window from blocking translucent sprite blending
fixes Pokemon fog effect.
2022-05-31 21:05:40 +01:00
Luke Usher 679dbaccc9 sh2: implement watchdog in interval timer mode 2022-05-31 11:43:04 +01:00
Giovanni Bajo 57b4d68298 n64: fix PI DMA timing calculation
329a8c9 had a bug: it moved the queue.insert line *after* dmaWrite;
but dmaWrite updates the io.writeLength to its post-transfer status,
so the calculated timing was incorrect.

Fix the regression in Cruisin' Exotica and possibly others.
2022-05-31 09:01:26 +01:00
Luke Usher 5d55f2b8e3 ps1: clear param fifo after command execution 2022-05-30 21:59:27 +01:00
Luke Usher f094529d6d ps1: stub 'motor-on' 2022-05-30 21:59:27 +01:00
Giovanni Bajo c2735c5c1c n64: use a stronger hash in RSP recompiler to avoid collisions
Luckily enough, n64-systemtest triggered an interesting bug in our
RSP recompiler: a hash collision of the IMEM contents. The used hash
is objectively very poor so a collision is well possible.

Switch to CRC32 that should be enough to our scope.

The idea of doing a full IMEM hash is probably a bit weak to begin with,
but that's for another time.

Fix a new test in n64-systemtest (that only failed because of this).
2022-05-27 13:13:03 +01:00
Giovanni Bajo e1f5ab8333 n64: fix marginal cases of SHV and SWV
Fix two new tests in n64-systemtest
2022-05-27 13:13:03 +01:00
Luke Usher cf0ef61c1f ps1: implement SCEX test commands used for anti-mod detection 2022-05-27 08:12:46 +01:00
Luke Usher 2b9907c8d0 ps1: implement ReadToc command 2022-05-27 08:12:46 +01:00
Luke Usher 2abe2286b2 ps1: data reads should stop cd-da reads 2022-05-27 08:12:46 +01:00
Luke Usher b6d8be087f ps1: seek commands are two-stage, not one-stage 2022-05-27 08:12:46 +01:00
Giovanni Bajo 49892159d5 n64: fix serialization
I broke it in 8236464.
2022-05-26 22:17:05 +01:00
Luke Usher e88e2cf032 sfc: lazily sync co-processors
Significant performance improvement for some users, especially on low-power machines such as laptops/tablets.
2022-05-26 22:16:22 +01:00
Giovanni Bajo bcf9cab22d n64: rework RSP DMA double buffering
This change implements RSP DMA double buffering in a more faithful
way, so that reads from the registers always return the current values
(ongoing transfer or finished transfer) rather than the pending ones.

Moreover, this also makes Ares transfer bytes in background a row at
a time, rather than all of them at the end. It is a bit more accurate,
and it was also easier to implement in the new architecture.

This also fixes several tests in n64-systemtest.
2022-05-26 12:57:23 +01:00
Giovanni Bajo 2973fa71e5 n64: reactivate 64-bit memory map
Ares used to have full 64-bit TLB support but it was removed at some
point because of some wrong testing that apparently made us believe
that the CPU didn't support that mode. It will have to be restored from
the git history in the future, though it's not very urgent because
nobody is using 64-bit pointers on N64 (there is no toolchain with
64-bit pointers, nor it seems useful).

Luckily, at least the segment parsing was left in and just commented out.
This allows to pass the last two remaining tests in n64-systemtest.
2022-05-25 09:04:55 +01:00
Giovanni Bajo 16f86afd9f n64: improve RSP DMA timing
RSP DMA runs at 8 bytes per RSP cycle, and each RSP cycle is 3 "ares cycles".
2022-05-24 07:49:28 +01:00
Giovanni Bajo 329a8c958b n64: improve PI DMA timings
PI DMA (at default PI configuration) is roughly 9 COP0 cycles per byte,
which is 18 CPU cycles, which is 36 "ares cycles".
2022-05-24 07:49:28 +01:00
Giovanni Bajo 91f3dfaf3d n64: run PI DMA immediately, and delay only the interrupt
This is less likely to create troubles to games, and matches what it
is being done for RSP DMA.

This makes DK64 boot.
2022-05-24 07:49:28 +01:00
Giovanni Bajo daa8d82f7b n64: implement more null opcodes in RSP
Fix several tests in n64-systemtest
2022-05-24 07:48:57 +01:00
Giovanni Bajo fb98870d56 n64: fix VMACQ and fix+simplify VMOV
Fix two tests in n64-systemtest.
2022-05-24 07:48:57 +01:00
Giovanni Bajo 07183d56f4 n64: fix clamping of RSP vrndn/vrndp opcodes
Fix some tests in n64-systemtest
2022-05-23 16:39:46 +01:00
LuigiBlood 232cb6fcf6 n64: remove readId from controller 2022-05-23 16:39:28 +01:00
LuigiBlood 320779a845 n64: implement per controller joybus pif communication 2022-05-23 16:39:28 +01:00
LuigiBlood 86e962bc13 n64: add n64 mouse emulation 2022-05-23 16:39:28 +01:00
Luke Usher 0cafaad19b sfc: alternate fix for voxel demo; restores SuperFX compatibility 2022-05-21 13:32:36 +01:00
Giovanni Bajo 043b4ffd37 n64: implement AI DMA hardware bug
Fix audio in Twisted Edge
2022-05-19 07:25:09 +01:00
Luke Usher 6174fa384e bump version number to v128 2022-05-17 19:45:05 +01:00
invertego e5d1f2dfea recompiler: update to latest SLJIT API 2022-05-13 18:48:45 +01:00
Luke Usher 54f6ea31f5 Merge commit '0d26512309d871d62972bfcd8e48f48528881332' 2022-05-13 18:47:17 +01:00
Luke Usher 1d26512309 Squashed 'thirdparty/sljit/' changes from d6a0fa61e..761d48d2b
761d48d2b Improve constant generation
1f32a9f23 Implement fpu operations for RISC-V
ad99f17a9 Improve x86 float compare
fb55788d0 Initial implementation of RISC-V port
7f08de6ff Improve jump code generator on MIPS
469c61db9 Improve mips code generator
a4e8e34ef Support unsaved registers on s390x
f404f3608 Support unsaved registers
88d4778b9 Add license file
160b6f99d windows: fix building in arm64 with clang (#126)
022482eeb wxexec: officially drop support for EOL NetBSD < 8 versions (#124)
beda74f07 Support reworked floating point compare on s390x
050215b22 Remove unnecessary checks
6b950049d Improve floating point compare.
6ace72c90 windows: allow building with MinGW64 gcc/clang (#125)
186b07064 mips: avoid sign conversion warnings with clang (#122)
e0b17f5a6 macos: fix recent regression breaking build in macos/arm64e (#121)
68d9b4bac misc: mostly to avoid warnings (#120)
76330309a Update s390x.
6807c7a8f Remove SLJIT_NEG.
ca530a4a7 Readd carry flag support.
5f60134b5 s390x: be explicit about cache coherence needs (#119)
75a555604 power: avoid bogus clear_cache builtin in gcc >= 10 (#118)
1448ef97c sparc: avoid NOP implementation for clear_cache with gcc (#117)
ad69ad87b sparc: build fixes (#116)
47646b943 Support incoming arguments in scratch registers for s390x.
4fbdd6953 Support incoming arguments in scratch registers.
86ebfbd50 Rework x86-32 function prologue/epilogue.
2f8cf7a08 Increase the number of floating point registers on ppc, mips, and sparc.
2737606ee Increase the number floating point registers on s390x.
03469c8e1 Rename tail call to call return and minor ARM improvements.
7cb8a5c24 Increase the number floating point registers on x86 and ARM.
b35ab5e7e Implement fpu support on s390x.
dcc8fc149 misc: fix -Wextra related errors (#114)
92fcb0fe5 Fix fallthrough errors.
d345a64b3 misc: build/documentation fixes from recent changes (#113)
ff6ec4f74 Implement tail call on MIPS.
eed28632f Implement tail call on ARM.
d7793570f Reduce signed comparison warnings.
30b2dcd83 Reduce value conversion warnings on s390x.
c783c1119 Reduce value conversion warnings on MIPS, PPC, SPARC.
335ee51f5 Reduce value conversion warnings on ARM.
8d0f668fa Improve value conversion warnings.
373163144 Implementing tail calls for x86.
9c8b6961b Improve argument sanity checks.
24c547b7e Swap f32 and f64 argument types.
7f0afb25e Rework function argument list descriptor macros.
585ac42bf Implement four argument support for emit enter.
b5e0b1234 Improve mov32 operation.
433294658 Fix incorrect function call (#112)
cf594d74d Change SLJIT_I32_OP and SLJIT_F32_OP to SLJIT_32.
ae5fff841 Improve arm code generator.
43538b877 Replace SLJIT_UNUSED with appropriate function calls.

git-subtree-dir: thirdparty/sljit
git-subtree-split: 761d48d2b89a048badbd9c5cf45da75336891cfe
2022-05-13 18:47:16 +01:00
Luke Usher 43f1e524e0 Merge commit '402c8acc5f30b9ec355deb52618d99eb69f58916' 2022-05-13 18:47:05 +01:00
Luke Usher 402c8acc5f Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 05136e3b4..af9b4b00f
af9b4b00f Update to b355d60aa32c8647670634d30ea1b107c3f78b05
0dcebe11e Update to e5efa5836cd43a597c706e07f04e79083d5ffb4f
e79d0cb77 Update to b3eeb49e708a215ee990415f303ce9936e55bd66

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: af9b4b00f0e6ec17cfd59f9e71c4976b5c3c40b0
2022-05-13 18:47:05 +01:00
Giovanni Bajo 2451fec704 n64: internal mask of physicalAddress register in TLB entries
Fix one test in n64-systemtest
2022-05-08 14:31:34 +01:00
Giovanni Bajo 8a70118446 n64: fix 64-bit pc calculation in J opcode
This was missed in the previous sweep on 64-bit PC. Fix one test
in n64-systemtest.
2022-05-08 14:31:34 +01:00
Giovanni Bajo fa017c26a5 n64: implement exceptions in non-taken delay slots
When an exception happen in a delay slot, it behaves the same whether
the branch was taken or not. In Ares, instead, the state "delay slot"
only applied to taken branches.

Fix several tests in n64-systemtest
2022-05-08 14:31:34 +01:00
Giovanni Bajo 670920a5a4 n64: increase a little the PI DMA timing.
These timings actually depend on the PI registers, even though they
are almost always set to fixed default values. We will get there
eventually and provide a more accurate figure, but for now this
allows to pass timing tests in n64-systemtest so that it can't be
more wrong than before.
2022-05-08 14:31:34 +01:00
Giovanni Bajo 82364646d3 n64: fix controller input after PIF refactoring
A last minute change in 741320e0be introduced a regression in controller
input.

Similar to what we did with PI DMA, SI DMA does not go through the main
bus (SysAD bus) but directly communicate with pif and rdram. This is not
just for the sake of correctness, but SysAD bus half-word writes are
now emulated with the same brokeness they have on real hardware, and
obviously DMA works instead. Moreover, since SI only reads/writes
32-bit words, also switch to word access.
2022-05-07 21:59:27 +01:00
Giovanni Bajo 40220a6ba1 n64: map domain 1 address 3 zone into main memory map
This was missed in the PI bus refactoring. All addresses up to
7fff'ffff are mapped to the PI bus.
2022-05-07 11:33:48 +01:00
Giovanni Bajo 96a6f98862 n64: refactor PIF chip into its own class
Currently, Ares does not model the PIF chip on its own: it looks like
there was an original mistake that conflated the PI (peripheral
interface, one of the components of RCP) with the PIF-NUS (a separate
chip, connected to SI component of RCP via a serial bus).

This refactor introduces a PIF class and moves all the related code
into it. Since the class implements the Memory::IO protocol for memory
accesses, it also fixes memory accesses with non standard sizes, as
tested by n64-systemtest.
2022-05-07 11:33:48 +01:00
Giovanni Bajo 3423bcf65e n64: improve TLB register masking
Fix a few tests from n64-systemtest
2022-05-07 11:33:48 +01:00
Giovanni Bajo a74ef69d86 n64: add address error for invalid 64bit address in 32bit mode
Fix a few tests from n64-systemtest
2022-05-07 11:33:48 +01:00
Giovanni Bajo 177475f053 n64: fix a few memory access opcodes that were using a 32-bit address 2022-05-07 11:33:48 +01:00
Giovanni Bajo 32ba2fe676 n64: activate address errors by default
These improve accuracy and help with homebrew development, while not
affecting performance much.
2022-05-07 11:33:48 +01:00
Giovanni Bajo 3aa1b3b738 n64: fix LL / SC / LLD / SCD opcodes
Updates #140.

Unfortunately this doesn't fix Gauntlet Legends.
2022-05-06 10:24:40 +01:00
Giovanni Bajo abf4c58ce6 n64: fix cache to use physical addresses
There is a bit confusion of virtual vs physical addresses in Ares,
so dcache/icache were sometimes using a virtual address, sometimes
a physical one. This is wrong: cache is based on physical addresses
only.

Moreover, the CACHE opcode was not even going through TLBs, while it
should. So a CACHE opcode on a TLB-mapped address wasn't working before.
2022-05-06 10:23:31 +01:00
Luke Usher 6b0a52fcb6 Merge commit 'c7e59d13fa1eaa6d6e19daec8dc22a3bdf7e0e70' 2022-05-03 18:02:47 +01:00
Luke Usher c7e59d13fa Squashed 'thirdparty/libchdr/' changes from a03e69319..6eeb6abc4
6eeb6abc4 Merge pull request #76 from invertego/zlib_codec_init_free
254cdaccc Remove erroneous free() call in zlib_codec_init()

git-subtree-dir: thirdparty/libchdr
git-subtree-split: 6eeb6abc4adc094d489c8ba8cafdcff9ff61251b
2022-05-03 18:02:47 +01:00
invertego ea2b6886b5 nall: handle CHD paths with non-ASCII chars on Windows 2022-05-03 09:11:15 +01:00
Giovanni Bajo 80e651741c n64: make sure TLB entries are correctly initialized at power
This bug has always been there, but was hidden by the incorrect TLB
matching logic. After fixing the logic in 0bf24b3, this bug was
uncovered.

Fixes Goldeneye.
2022-05-03 09:10:20 +01:00
Giovanni Bajo 6b70ae6d69 n64: fix RSP LTV opcode in its corner cases
Fix one test in n64-systemtest ROM.
2022-05-03 09:09:08 +01:00
Giovanni Bajo a3a777ef93 nall: optimize priority_queue remove function 2022-04-30 22:06:12 +01:00
Giovanni Bajo abaf7a82f3 n64: implement proper PI bus writes with IO busy bit
All writes through the PI bus are actually performed asynchronous by
the hardware, and the status is reflected in the PI IO busy bit.

This commit emulates this properly, and also emulates what happens while
the busy bit is set: further writes are ignored, and reads at any
address return the word being written.

This fixes A Bug's Life and Toy Story 2.
2022-04-30 22:06:12 +01:00
Giovanni Bajoandremutro 0bf24b3161 n64: fix (again) TLB logic in case of invalid TLBs
This is a revert of 56458d5b, while keeping b7f96b7109 which is the
real fix that should have been done all along. The former just papered
over the issue and actually introduced a regression (Goldeneye wouldn't
boot).

Co-Authored-By: remutro <[email protected]>
2022-04-29 22:02:24 +01:00
bigbass1997 a527ed6d1d n64: add separate CIC 7102 detection 2022-04-27 16:31:01 +01:00
Giovanni Bajo cf0582f607 n64: implement undocumented broken RSP opcodes
Fix several tests in n64-systemtest ROM.
2022-04-27 16:30:46 +01:00
Giovanni Bajo 02942aca6b n64: Fix RSP MTC2 and LFV opcodes
Fix several tests in n64-systemtest ROM.
2022-04-27 16:30:46 +01:00
Giovanni Bajo aae3caab38 n64: fix RSP BGEZAL/BLTZAL when RA is being tested
Fix several tests in n64-systemtest ROM.
2022-04-27 16:30:46 +01:00
Giovanni Bajo 2a71b978be n64: fix cop0 LL write mask
Fix one test in n64-systemtest ROM.
2022-04-27 16:30:46 +01:00
Giovanni Bajo 336af4c219 Revert "n64: update RSP DMA registers after transfers."
This reverts commit 5e4e64dbd7.

Reason: it breaks Zelda OOT. Requires more thinking.
2022-04-27 00:32:38 +01:00
Giovanni Bajo 1afbf893d7 n64: fix RSP DMEM/IMEM accesses with all access sizes
Like anything else, DMEM/IMEM need to go through the mangling performed
by Memory::IO.

Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 6bcab5e7ed n64: fix Dual accesses on MMIO regs
Those accesses are really broken beyond repair, and they just write
the upper half.

Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 5e4e64dbd7 n64: update RSP DMA registers after transfers.
Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 728db642f0 n64: fix RSP DMA wraparound
RSP DMA always wraps within the same region.

Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo e1f1cbbb4b rsp: small accuracy tweak to semaphore register
Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo b7f96b7109 n64: fix TLB logic for non-global entries
Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 32c15726ae n64: fix masking of COP0 context / xcontext
Fix several tests in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 6160a81368 n64: fix TLB random register when wired > 31
Also take the chance to remove the "hopefully accurate but then not
really" implementation which runs after every instruction in favor
of a real random.

Fix one test in n64-systemtest ROM.
2022-04-26 09:14:50 +01:00
Giovanni Bajo 523b6ce5cf n64: improve emulation of vector load opcodes in side cases
Fix several tests in n64-systemtest ROM.
2022-04-24 21:14:49 +01:00
Giovanni Bajo 95e407aae1 n64: implement LWU opcode in RSP
Fix one test in n64-systemtest ROM.
2022-04-24 21:14:49 +01:00
Giovanni Bajo 5e1d6d1aab n64: improve address exceptions with correct COP0 status
Fix several tests in n64-systemtest ROM.
2022-04-24 21:14:49 +01:00
Giovanni Bajo 9f0f4b3432 n64: implement buggy byte/half reads from cartridge space
Fix several tests in n64-systemtest ROM.
2022-04-24 21:14:49 +01:00
Giovanni Bajo f4a38d121d n64; implement correct behaviours of jumps within delay slots
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo abf454cecb n64: fix JALR when jumping to RA
Fix one test in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo 6c40a5b4c6 n64: fix handling of invalid pagemasks
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo 56458d5ba5 n64: fix exception kind in case of TLB invalid page and with nonmatching asid
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo 8d04515b5f n64: fix behavior of conflicting bits in writes to SP_STATUS
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo f66c93c0c2 n64: fix BGEZAL/BGEZALL opcodes when testing RA
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo f4c9c11596 n64: fix RSP PC to stay within 12 bits in all cases
Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo 906191ac45 n64: fix COP0 config initial status
Fix a test in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
Giovanni Bajo a0c063cabe n64: fix CPU core to correctly handle 64-bit PC
PC register in VR4300 is 64-bit but there were many places where
the register was incorrectly treated as a 32-bit one, effectively
discarding the higher half.

Fix several tests in n64-systemtest ROM.
2022-04-23 15:49:13 +01:00
invertego ebf41cb696 mia: update out of date resources 2022-04-23 15:49:02 +01:00
invertego c0dfad661b build: fix clean targets on Windows
To get clean makefile targets working robustly under a Windows command
prompt, allow the entire contents of obj/out directories to be deleted.
They are now recreated by the build as needed.
2022-04-23 15:49:02 +01:00
invertego 0b80107cdf build: fix building from Windows command prompt
Replace uses of Bourne shell commands (cp, mkdir) with shell-agnostic
versions that work from a Windows command prompt. Some Bourne shell
commands still remain in macOS and Linux specific makefile lines.
2022-04-23 15:49:02 +01:00
invertego f7eb4483b2 build: fix zlib include path 2022-04-23 15:49:02 +01:00
shinra-electric 9178761932 Fix typo: type --> typeStr
using `type` results in compiler warnings: `warning: result of comparison against a string literal is unspecified (use an explicit string comparison function instead)` 

Was informed by merryhime that `typeStr` was probably intended.
2022-04-16 20:28:18 +01:00
Luke Usher 235a04d54d nall: prevent chd memory leaks + don't allow unsupported track types 2022-04-16 09:43:33 +01:00
Luke Usher 75c0a5f36e mia: support for loading CHD compressed CD-ROM images 2022-04-16 01:09:02 +01:00
Luke Usher 6de4810ab7 Squashed 'thirdparty/libchdr/' content from commit a03e69319
git-subtree-dir: thirdparty/libchdr
git-subtree-split: a03e69319164f69d781ab8e453f8cf407387bd13
2022-04-15 09:58:55 +01:00
Luke Usher 1a5ab89cd4 Merge commit '6de4810ab78cbdc0f18863b9c3ee2a954c7bb4d5' as 'thirdparty/libchdr' 2022-04-15 09:58:55 +01:00
Luke Usher 4a80dbabcb desktop-ui: minor tweaks to msx keyboard map 2022-04-14 16:06:38 +01:00
Luke Usher 6399a5cd15 nall: sse42 -> sse41 2022-04-11 18:32:13 +01:00
Giovanni Bajo acd2130a4d n64: fix SIGILL at startup when SSE4.2 is not supported
The N64 core was forcing -msse4.2 for compilation of the whole Ares.
On host PCs without SSE 4.2, Ares would crash at startup with SIGILL
because GCC used SSE 4.2 instructions even in hiro, while building up
the UI.

RSP SIMD emulation requires SSE 4.1, but the solution here is to
fallback to SISD if SSE 4.1 is not supported. This can be checked
with a predefined macro, that will be set by GCC. We do compile with
-march=native, so this will reflect the host PC of the build process.
For non-local builds (eg: official CI builds), default to nehalem
(Core 2) which is the first architecture with SSE 4.1.

Since this is yet another compile-time flag that affects the N64 core
performance, add a status message warning if SIMD is disabled.

Fixes #193
2022-04-11 07:55:53 +01:00
Giovanni Bajo b3b32ef026 n64: add missing file for mame RDP SSE2 implementation
Mame RDP has two codepath: one for SSE4.1 and one for SSE2. The latter
relies on some static tables that weren't imported from upstream.
2022-04-11 07:55:53 +01:00
Luke Usher 4ce8290e49 sfc: pad bsx flash to minimum size of a memory cart
Fixes running BS-X content smaller than 1M
2022-04-11 00:00:33 +01:00
Luke Usher fd6698c5f6 sfc: fix a hang when loading Satallaview content 2022-04-10 23:22:49 +01:00
Luke Usher f92605cfbd desktop-ui: add support for using Supergrafx and CD together
The homebrew game "Space Ava 201" does this
2022-04-10 20:42:25 +01:00
Luke Usher 2c3c9fe25f desktop-ui: implement status queue + 'keyboard capture' notice 2022-04-09 10:17:39 +01:00
Luke Usher 18e013beda mia: formatting fixes 2022-04-07 21:55:13 +01:00
Luke Usher 1e26a8be76 msx: improve rom type detection and add more board types 2022-04-07 21:52:15 +01:00
Luke Usher 300fa4801f msx: fix a number of memory layout issues
The results of the "tinyslotchecker" rom are sane now;
it finally reports a valid configuration.
2022-04-07 20:25:28 +01:00
Luke Usher c5106a1982 msx: require a proper bios rom for msx1
This is because C-BIOS has significant compatibility issues, including
the ability to boot any software that uses BASIC.

The MSX2 emulation is still too preliminary to be able to boot the
official bios, so msx2 will continue to use C-BIOS for the time being.
2022-04-07 20:24:37 +01:00
Luke Usher 1d22db7e1c desktop-ui: fix an issue where settings would not persist after previous change 2022-04-06 22:08:45 +01:00
Luke Usher c986a14401 desktop-ui: remap all inputs based on physical controller layouts
Note: you will need to reconfigure your virtual pad after this commit.
2022-04-06 21:29:38 +01:00
Luke Usher a6d3a57df9 gba: slightly reduce red tint, to bring the display closer to my GBA SP 2022-04-06 09:47:33 +01:00
Luke Usher 8d04df1641 desktop-ui: add hotkey to toggle fast forward 2022-04-05 23:23:15 +01:00
Luke Usher 6baebd0f06 msx: update cbios to latest japanese revision
Fixes kana fonts in many games
2022-04-04 23:23:15 +01:00
Luke Usher e34bfc04e3 msx: fix linear cartridge rom mapping
This allows many titles that didn't boot previously to start
2022-04-04 22:07:11 +01:00
Luke Usher 0d7c70bdba tms9918: implement text mode 2022-04-04 21:51:09 +01:00
Luke Usher fccd73f8e3 gb: tweak display timing; fixes dmg-acid2 and cgb-acid2 2022-03-31 18:44:19 +01:00
kev4cards c52c7fd1bb Change inner dead-zone size and geometry
Replace the large, inner circular dead-zone of the N64 control stick with a small, inner square dead-zone; separate the inner and outer dead-zones; attach the scaling equation to the outer dead-zone; fixes https://github.com/ares-emulator/ares/issues/86 .
2022-03-31 09:53:11 +01:00
kev4cards 5210341ad3 Update gamepad.cpp 2022-03-31 09:53:11 +01:00
AmatCoder d7e456a46f hiro: fix menubar visibility with gtk3
Fixing issue #229
2022-03-23 11:31:06 +00:00
Luke Usher a3b126f079 pce: initialise bram for cd-rom system 2022-03-20 21:54:58 +00:00
Giovanni Bajo bc8c308ee9 n64: add support for homebrew-specific special header flag
Nintendo 64 homebrew community is standardizing on a convention to
declare the save memory type as a header flag. This convention has been
first introduced by EverDrive 64 as a way to handle games not present
in their DB, but it's been since adopted by libdragon as well.

With this commit, Ares will automatically configure the correct savetype
for homebrew ROMs using the special header flag.
2022-03-19 10:12:27 +00:00
TascoDLX 124a678c8e m68000: omit illegal addressing modes for CMPA & TST 2022-03-17 09:08:29 +00:00
TascoDLX 333dd85ba5 m68000: fixed group 2 exception prefetch (CHK, DIV by zero) 2022-03-17 09:08:29 +00:00
jbo-85 d08a9bdcc2 sfc: Add database entry for the "Super FX voxel demo" to specify a RAM size of 64k instead of 32k
Support ROM/RAM addressing for Super FX ROMs that are not a power of 2
2022-03-14 22:45:55 +00:00
Luke Usher f4a018036d ruby: fix typo (missing semicolon) in pulseaudio driver 2022-03-14 09:31:34 +00:00
AmatCoder 65f4e176c2 ruby: pulseaudio shouldn't block for events
Now it sets a timeout of one second
2022-03-14 09:14:59 +00:00
Luke Usher 3b8e9bbff5 msx: connect/fix up keyboard emulation
This is implemented via a 'keyboard capture' hotkey; this ensures that
users can switch between keyboard & gamepad emulation, even if they have
no physical gamepad.

When keyboard capture is enabled:
 - All non-hotkey key-presses are translated and dispatched to the guest
 - Virtual GamePad Inputs that are mapped to Keyboard no longer trigger
 - Virtual GamePad inputs that are mapped to Mouse or physical GamePads work normally.
2022-03-10 23:56:01 +00:00
Luke Usher 8f2c6eff9c desktop-ui: fix an issue where System directories were created incorrectly 2022-03-10 21:24:02 +00:00
Luke Usher 85a5292648 desktop-ui: default filter/shader to "None" rather than "Blur" 2022-03-10 19:57:57 +00:00
Luke Usher c8f261201c mia: recompile resources 2022-03-08 19:17:32 +00:00
Luke Usher e42c79677d Merge branch 'master' of https://github.com/ares-emulator/ares 2022-03-08 19:14:59 +00:00
Luke Usher de9ec5d83c mia: oops, title => label 2022-03-08 10:35:27 +00:00
Luke Usher 93e89446e2 mia: update sfc board database & heuristics 2022-03-08 10:04:22 +00:00
Luke Usher 2a28c46a41 desktop-ui: update locate to carry over old settings, explain choices. 2022-03-07 22:00:43 +00:00
Luke Usher 23fa258dfd nall: remove hardcoding of lto=true
This was overriding the given command line preference, making it difficult to build with lto disabled.
2022-03-07 09:59:30 +00:00
invertego e86a18f293 md/32x: add missing initialization during power-on
Nearly all state is initialized to a fixed or random value during
power-on, though a few things are deliberately left alone on soft reset.

A handful of fields weren't being initialized at all, save for the zero
initialization that occurs during process creation. This state would be
persisted from one ROM load to the next.

This fix is intended to address 32x PWM audio eventually going silent
after switching between multiple roms.
2022-03-07 09:32:22 +00:00
Giovanni Bajo 665229a892 macos: codesign binary after build
This is required on Apple Silicon and won't harm on Intel.
2022-03-07 09:21:05 +00:00
Giovanni Bajo 4d46be8344 Add top-level Makefile 2022-03-07 09:21:05 +00:00
Luke Usher 5a839f1010 Revert "sfc: slight ppu performance boost by templating arguments"
This reverts commit d01b8db441.

This was an experimental local change that should've never made it to master
2022-03-05 21:58:33 +00:00
Luke Usher d5dcc645e4 desktop-ui: ensure ares is 'portable' on Windows 2022-03-04 20:09:03 +00:00
Luke Usher 35f6a93713 nall: determine desktop path based on environment 2022-03-04 20:09:03 +00:00
Luke Usher d01b8db441 sfc: slight ppu performance boost by templating arguments 2022-03-04 20:09:03 +00:00
TascoDLX a8373002b5 ares: bump serializer version (md updates) 2022-03-04 20:08:15 +00:00
TascoDLX 5d192fb215 md/32x: readjust cpu sync after recent changes (Kolibri fix) 2022-03-04 20:08:15 +00:00
TascoDLX e13722870e m68000: adjust interrupt/exception timing
*based on Motorola app note AN1012/D. Timing for autovector action is approximated based on MegaDrive h/w tests.
2022-03-04 20:08:15 +00:00
TascoDLX 82e49616a2 md: reimplement refresh timings
*based on research by Mask of Destiny and approximations from h/w tests
2022-03-04 20:08:15 +00:00
TascoDLX 7d425dc5e7 md: vdp vscroll bug implemented 2022-03-04 20:08:15 +00:00
TascoDLX aa975f8f6c md: vdp dma transfer is delayed after bus is acquired 2022-03-04 20:08:15 +00:00
TascoDLX 7fcd6d1f5a md: vdp timing tweaks for accuracy
- vtick() shifted; can't be any later w/o breaking due to render alignment
- vblank flag update moved to vtick(); also updated on v28/v30 switch (per ekeeke's note re: Kabuto's findings)
- corrected apu irq timing
- readded extra refresh slot when display is disabled (confirmed after latest timing fixes)
2022-03-04 20:08:15 +00:00
Luke Usher 9d7c83aa39 Update README.md 2022-03-04 09:02:47 +00:00
Luke Usher 1d8aa3fc3f ares v127 released
ares v127 brings significant improvements to Mega Drive and Nintendo 64
emulation, as well as improvements to NES / Famicom and SNES / Super Famicom.

Other than the usual emulation improvements, there have been the following notable
changes:

**Apple Silicon Support**

ares v127 fixes the recompiler for aarch64 architecture, meaning that it is now
possible to create Apple Silicon/M1 native builds, without relying on Rosetta
and without losing support for the high performance JIT recompilers.

In order to be Apple Silicon Native, it is currently required to compile ares
from source code as automated builds have not yet been configured, but users
who wish to do so will no longer lose functionality or suffer poor performance
as a result.

**MAME RDP**

ares's Nintendo 64 core uses paraLLEl-RDP by default; this brings fast and
accurate RDP emulation as long as Vulkan is present on the users machine; this
meant that Nintendo 64 emulation was completely broken for all configurations
without Vulkan support, including macOS.

ares v127 adds support for MAME's RDP implementation as a fallback, allowing
Nintendo 64 emulation to be used when Vulkan is not present. This is handled
automatically, however, a new option has been added to video settings to allow
Vulkan support to be toggled, giving all users the ability to test the MAME
RDP, if they wish to do so.

Although MAME RDP is now an option, paraLLEl-RDP is still the recommended
choice, for both performance and accuracy.

**Pixel Accuracy Mode**

ares has contains two implementations of some of our emulated hardware; one
optimised for performance, and another optimised for accuracy.
Historically, the choice of which path to use has never been exposed to the
user; higan *always* used the 'accurate' profiles, with ares always opting for
the 'performance' profiles; any user wishing to change this would be required
to compile ares themselves from source.

As of ares v127, we now provide a new option in the emulator settings: "Pixel
Accuracy"; when this is enabled, any emulator core that supports a pixel
accurate mode will use it.

For 99% of games, the default fast profiles will be sufficient, but enabling
"Pixel Accuracy" allows games that require mid-scanline effects, such as the
infamous "Air Strike Patrol" to function properly.

The following systems are currently support the Pixel Accuracy setting:

* NEC - PC-Engine / TurboGrafx
* Nintendo - Super Famicom / SNES

**Changelog:**
* desktop-ui: hook up pc-engine 6-button pads to virtual pads [Luke Usher]
* desktop-ui: implement frame advance [Luke Usher]
* fc: add bus conflicts to cnrom [encoded-byte]
* fc: check for ram on mmc1 [encoded-byte]
* fc: check if ram exists on mmc3 [encoded-byte]
* fc: clear oam address on each scanline [encoded-byte]
* fc: improve mmc3 irq behavior [encoded-byte]
* fc: improve ppu skipped clock timing [encoded-byte]
* fc: use hkrom for mmc6 [encoded-byte]
* m68000: allow recovery from zero divide [TascoDLX]
* m68000: reimplement DBcc instruction with correct timing[TascoDLX]
* md: A few fixes to SRAM save game [rasky]
* md: correct overscan / output when display is off [TascoDLX]
* md: correct reads of CRAM and VSRAM [rasky]
* md: detect region 'K' as NTSC-J [invertego]
* md: fix APU port in [rasky]
* md: fix debug register sprite masking [rasky]
* md: fix high bits in control port read [rasky]
* md: fix misaligned reads from VRAM [rasky]
* md: fix register masked write in mode5 [rasky]
* md: fix vblank bit toggling horizontal timing [rasky]
* md: fix VSRAM out of bound accesses [rasky]
* md: ignore erroneous device string used by Codemasters [invertego]
* md: implement undocumented VDP VRAM 8-bit reading mode [rasky]
* md: persist VDP state on reset [invertego]
* md: restore vdp free slot lost to refresh [TascoDLX]
* mia: Correct save type for Premier Manager 64 (N64) [sp1187]
* mia: Correct save type for Transformers: Beast Wars Transmetals (N64) [sp1187]
* mia: correct type for pak attribute [encoded-byte]
* mia: fix 32x sram [Luke Usher]
* mia: properly pass MD eeprom details to ares [Luke Usher]
* mia: updated famicom database [encoded-byte]
* mos6502: add illegal nops [encoded-byte]
* ms: correct overscan inc. dynamic screen resizing [TascoDLX]
* n64: add MAME RDP as a fallback for parallel-RDP [invertego]
* n64: allow vulkan to be disabled [Luke Usher]
* n64: change PI DMA to use 16 bit fetches [CasualPokePlayer]
* n64: fix mult/div opcode timings [rasky]
* n64: fix RSP halt condition to be more accurate [rasky]
* n64: fix several RDP regressions [invertego]
* n64: fix small bug in VMACQ [rasky]
* n64: fix SRA/SRAV opcodes [rasky]
* n64: fix vulkan detection [Luke Usher]
* n64: improve rsp recompiler pool allocation [invertego]
* n64: swap RSP/RDP order [CasualPokePlayer]
* n64: templatize rsp vpu [invertego]
* n64: vulkan tweaks [Luke Usher]
* nall: fix many compilation warnings on macOS [Luke Usher]
* nall: fix page protection on Apple silicon [invertego]
* nall: rewrite recompiler for machine-independence using sljit [invertego]
* pce: runtime pixel accurate VDP setting [invertego]
* sfc: fix horizontal off-screen test for sprites [jbo-85]
* sfc: fix missing sprite tile on Super Conflict title screen [jbo-85]
* sfc: fix missing sprites in Jurassic Park that are partly offscreen [jbo-85]
* sfc: runtime pixel accurate PPU setting [invertego]
* sh2: move registers into POD struct [invertego]
2022-03-03 11:12:11 +00:00
invertego 7692f102e5 pce: runtime pixel accurate VDP setting 2022-03-03 09:31:59 +00:00
invertego 3be1ced3ef sfc: runtime pixel accurate PPU setting 2022-03-02 09:59:35 +00:00
Luke Usher c78d931e28 Revert "ares: remove performance renderers"
This reverts commit dc5ff13b5c.
2022-02-26 21:59:51 +00:00
TascoDLX e7f24c06d5 m68000: reimplement DBcc instruction with correct timing 2022-02-26 12:13:56 +00:00
Luke Usher dc5ff13b5c ares: remove performance renderers
Some systems in ares contained two implementations of video hardware;
these systems were Mega Drive / Genesis, Super Famicom / SNES, and
PC-Engine / TurboGrafx 16.

For the Mega Drive, we switched to the accuracy core quite some time ago,
SNES and PC-Engine we were still using the performance core.

Going forward, we wish to only maintain the accuracy focused renderers.
2022-02-23 13:04:45 +00:00
Luke Usher 7140b64b13 nall: fix many compilation warnings on macOS 2022-02-23 13:00:45 +00:00
Giovanni Bajo 4d4d3308b9 md: fix debug register sprite masking
VDP always writes transparent pixels to the internal sprite buffers,
overwriting previous transparent pixels; then the first non-transparent
pixel sticks and wins. This implementation detail only reveals itself
when sprite plane masking is activated using the VDP debug register:
in that case, the palette number of transparent pixels concurs in the
AND of the visible pixels, and thus the correct palette number should
be found in the buffer.

Fixes the logo effect of Overdrive 2 (ref #255)
2022-02-23 08:50:24 +00:00
Giovanni Bajo e02a7cc6fb md: fix APU port in
It's technically unused, but it must return 0xFF. Looks like some
game erroneously read it anyway.

Fixes #286
2022-02-23 08:50:13 +00:00
Giovanni Bajo ce981795f5 md: second attempt at vblank bit timing
After more analysis, it looks like the correct thing to do is to
check for vblank status on most of the raster line. Kabuto's doc says
that it is possibly to switch from V30 to V28 during line 224 and
still see the vblank triggered, which suggests that the hardware does
actually check it on most of the time.

This seems to fix #402 and does not seem to cause any immediate
regression in timing-sensitive ROMs.
2022-02-23 08:50:00 +00:00
Giovanni Bajo 51d16a58cd md: fix vblank bit toggling horizontal timing
Currently, the vblank bit is turned on/off at the same time vcounter
is incremented, which is a reasonable assumption, missing any real
data on this.

But it turns out this is responsible for most of the breakage of
Overdrive 1. I did some tests and it looks like anything in the
range >= 0xF0 (same line), or <= 0x80 (on next line) fixes those bugs.
I decided to bind it to vedge(), which means that vblank bit now is
triggered the same instant that VINT is raised, which also makes sense
when you think of it.

Updates #212
2022-02-22 11:05:19 +00:00
TascoDLX 89287dabf1 ms: correct overscan inc. dynamic screen resizing 2022-02-21 08:17:21 +00:00
TascoDLX 5b52f94aa1 md: correct overscan / output when display is off 2022-02-21 08:17:21 +00:00
Luke Usher f67373732c mia: properly pass MD eeprom details to ares 2022-02-21 08:00:10 +00:00
Luke Usher 8d43e67b96 fix eeprom after PR #357 2022-02-20 20:32:44 +00:00
Luke Usher 8a37b00fef mia: fix 32x sram 2022-02-20 20:20:49 +00:00
Luke Usher 80c2678930 desktop-ui: hook up pc-engine 6-button pads to virtual pads 2022-02-18 13:46:07 +00:00
TascoDLX 510cc55d76 m68000: allow recovery from zero divide 2022-02-18 09:15:28 +00:00
TascoDLX 5c285e3ce3 md: restore vdp free slot lost to refresh 2022-02-18 09:15:28 +00:00
Giovanni Bajo 21203b2401 md: fix misaligned reads from VRAM
VRAM misaligned addresses were implemented with partial slot reads.
This seems to be wrong, as proven by vdpfifotesting: once the slot is
read, the whole word is invalidated.
2022-02-17 19:04:06 +00:00
Giovanni Bajo 2c8f3ef84d md: implement undocumented VDP VRAM 8-bit reading mode
Using target 0xC, it is possible to do 8-bit reads from VRAM.
2022-02-17 19:04:06 +00:00
Giovanni Bajo 80348ae691 md: correct reads of CRAM and VSRAM
Reading unmapped bits in CRAM and VSRAM returns a copy of the same bits
in the top slot of the FIFO.
2022-02-17 19:04:06 +00:00
Giovanni Bajo 5e55f1a8a7 md: fix VSRAM out of bound accesses
VSRAM is actually made of 40 11-bit words, though the chip only accesses
the first 10 bits. The top bit on each word is still readable and writable
though, so they should be emulated.

Also, reading at addresses >= 40 returns a copy of the first word,
rather than 0.
2022-02-17 19:04:06 +00:00
Giovanni Bajo c63257029e md: fix register masked write in mode5
Mode5 (SMS compatibility mode) is unsupported and mostly undocumented,
but the vdpfifotesting ROM at least checks one know behavior: non-SMS
registers can't be written.
2022-02-17 19:04:06 +00:00
Giovanni Bajo 93d44072da md: fix high bits in control port read
Bits 10-15 in control port read (aka status register) are not fixed
as found in some online docs, but they are actually an open bus
that returns the instruction prefetched by m68k at that cycle.
2022-02-17 19:04:06 +00:00
Luke Usher 2cf921be41 desktop-ui: implement frame advance 2022-02-16 22:35:17 +00:00
Luke Usher cc8ccbf1bd point to the new ares website 2022-02-16 15:34:01 +00:00
Giovanni Bajo 10e589672f [MD] A few fixes to SRAM save game
* Allow MIA to declare address for mapping (typically from ROM header)
   rather than hardcoding 0x200000.
 * Autoenable SRAM if the ROM size is smaller. Also make the ramEnable
   I/O conditional to the same layout.
 * Add MIA entries for NBA Live 98, NHL 96 and NHL 98, which have a 8-bit
   SRAM not declared in the header.
2022-02-16 10:27:10 +00:00
jbo-85 3c28ecd8b6 sfc: fix missing sprites in Jurassic Park that are partly offscreen 2022-02-14 07:26:10 +00:00
jbo-85 cc64eb50c0 sfc: fix missing sprite tile on Super Conflict title screen; sprites that start on x==256 (offscreen) are considered for the range-tile-over checks 2022-02-14 07:26:10 +00:00
jbo-85 5cb877b49c sfc: fix horizontal off-screen test for sprites; fixes SNES test card Burn-In test, maybe others 2022-02-14 07:26:10 +00:00
CasualPokePlayer 275ba735de change PI DMA to use 16 bit fetches
Using the read<Byte> currently in use breaks DMAs from Flash (breaking Paper Mario, probably others), which always return 0. I assume 8 bit reads are just not allowed for Flash, although I can't verify this myself.
Checking https://github.com/n64dev/cen64/commit/8367698e20cca7eb262779f19c8c7847ae31bb29, it seems that fetches should always be 16 bits anyways, so I presume this is the correct behavior, and fixes DMAs from Flash.
No regressions with the original testrom have occured.
2022-02-12 10:15:37 +00:00
CasualPokePlayer 2b894add40 Swap RSP/RDP order, fixes #348 2022-02-11 12:13:33 +00:00
Luke Usher 58690cd5fc n64: fix vulkan detection 2022-02-09 07:22:20 +00:00
Luke Usher b03da384d8 n64: vulkan tweaks
- introduce a status api, so cores can report status messages to the UI
- avoid calling vulkan-related functions when vulkan is disabled
- show status messages so the user is aware of what RDP implementation is active
- Disabled 'loaded' status message, it prevented the Vulkan messages being shown
2022-02-08 20:34:05 +00:00
invertego f382a18d10 libco: update Windows thread information block
Update the stack base and limit in the thread information block. This is
required to support kernel stack unwinding, which is used for both C++
exception dispatch and setjmp/longjmp on Windows x64 and ARM64.

Add a cothread entry routine that consistently aborts when the user
supplied routine returns. Debugger stack backtraces now stop
consistently at this entry routine.
2022-02-07 08:56:29 +00:00
invertego f63cad6de9 md: ignore erroneous device string used by Codemasters 2022-02-06 16:09:57 +00:00
invertego 34d2c091c7 md: detect region 'K' as NTSC-J
The Korean release of Tiny Toon Adventures specifies its region with a
'K' and, like several other Korean releases, is region locked to
Japanese consoles. It may be the only one with a 'K' specifier, though.
2022-02-03 12:36:32 +00:00
invertego d845582d4a md: persist VDP state on reset
The game Skitchin' performs a fade out effect after reset with the
expectation that VDP state was persisted across the reset.
2022-02-02 09:55:28 +00:00
encoded-byte 9788752bc1 fc: check for ram on mmc1 2022-01-26 20:15:20 +00:00
encoded-byte 5f60ab2dde mia: updated fc database 2022-01-26 20:15:20 +00:00
encoded-byte 628432e75c fc: clear oam address on each scanline 2022-01-26 20:15:20 +00:00
Luke Usher 980e9ed687 n64: allow vulkan to be disabled 2022-01-19 19:52:19 +00:00
Giovanni Bajo e98a313ed6 n64: fix mult/div opcode timings
Taken from NEC VR4300 manual. These are easier than expected to
implement accurately as the CPU doesn't execute them in parallel but
stalls the entire pipeline while they are running.
2022-01-18 09:14:56 +00:00
Giovanni Bajo 90d42d1ea3 n64: fix SRA/SRAV opcodes
These two opcodes were incorrectly ignoring the higher part of the
register before shifting.
2022-01-18 08:02:23 +00:00
Giovanni Bajo 11d6b7c673 rsp: fix small bug in VMACQ
Real hardware testing showed that VMACQ does not modify the accumulator
if it is exactly zero. Fix it.

Also remove two "unconfirmed" comments which I have personally verified.
2022-01-13 08:41:58 +00:00
invertego c04bcf03e0 n64: fix several RDP regressions
- YUV texture fetch and color space conversion
- textured rectangle command parsing
- set primitive depth command parsing
2022-01-12 14:44:39 +00:00
Luke Usher c4d73cc427 Update split-subtrees.yml
Debugging CI action
2022-01-12 11:26:05 +00:00
Luke Usher 8634c11cff Update split-subtrees.yml 2022-01-12 11:22:37 +00:00
Luke Usher 8a5c48e3ed add split-subtrees github action 2022-01-12 11:18:27 +00:00
encoded-byte b22513a6e8 fc: check if ram exists on mmc3 2022-01-05 23:24:10 +00:00
Giovanni Bajo e5220e8fd0 n64: fix RSP halt condition to be more accurate
* Fix usage of break opcode in a delay slot. After unhalt, the
   RSP continues execution, taking the jump if needed. So the
   branch state should not be affected by the break opcode.
 * Reading from SP_PC produces garbage (open bus?) when the RSP is
   running. This fix is unlikely to fix game but may help homebrew
   developers.
 * Writing to SP_PC resets the RSP MIPS pipeline, so any pending branch
   is canceled.
2022-01-03 12:21:45 +00:00
encoded-byte 8099bf54fd mia: updated famicom database 2022-01-01 20:13:57 +00:00
encoded-byte bed4ce3659 fc: use hkrom for mmc6 2022-01-01 20:13:57 +00:00
encoded-byte f630a9418d fc: improve mmc3 irq behavior 2022-01-01 20:13:57 +00:00
invertego f9e4070b15 n64: improve rsp recompiler pool allocation
The existing implementation was allocating pools in the code cache only
to copy them to the heap. This was wasteful on multiple counts: the
space in the cache would go unused until the next allocator flush and
the data copied to the heap consisted almost entirely of zeroes. Best of
all, writing the hash code to the code cache was triggering a page
protection fault on Apple M1.

A small data structure refactor avoids the heap allocations, the copies,
the wasted space in the code cache, and the page protection issue.
2021-12-20 18:16:01 +00:00
invertego 5050d6c45d n64: add MAME RDP as a fallback for parallel-RDP
For systems that do not meet parallel-RDP's Vulkan requirements, use the
pure software RDP implementation from MAME as a fallback.

All of the source files taken from MAME are either BSD-3-Clause licensed
or public domain. Edits were kept to a minimum and guarded by ifdefs to
ease future integrations.
2021-12-20 18:16:01 +00:00
invertego b56dac15e9 recompiler: fix page protection on Apple silicon
- when dynamically allocating executable memory, use VirtualAlloc/mmap()
  for finer control over allocation flags (like MAP_JIT on macOS/arm64)
- toggle JIT memory protection around writes on macOS/arm64
- reduce recompiler code cache sizes to improve likelihood of dynamic
  allocations being close to ares image (affects branch perf)
- remove arch x86_64 override on macOS non-local builds; native arm64
  builds should now be at feature parity with x86_64
- sh2: prevent pollution of code cache with empty pools by invalidate()
2021-12-15 20:01:40 +00:00
invertego a8e35d0299 recompiler: rewrite for machine-independence 2021-12-14 09:02:52 +00:00
invertego 1462bac4c5 sljit: wire up to the build 2021-12-14 09:02:52 +00:00
invertego 5e2a8f08bf n64: templatize rsp vpu 2021-12-14 09:02:52 +00:00
invertego e88cb48f19 sh2: move registers into POD struct 2021-12-14 09:02:52 +00:00
invertego 70a669287b build: arm64 build fixes 2021-12-14 09:02:52 +00:00
invertego 9d3addc241 mia: fix build break 2021-12-14 09:02:52 +00:00
Luke Usher f22e1405dc Squashed 'thirdparty/sljit/' content from commit d6a0fa61e
git-subtree-dir: thirdparty/sljit
git-subtree-split: d6a0fa61e09266ad2e36d8ccd56f775e37b749e9
2021-12-11 19:43:23 +00:00
Luke Usher 4542ac5674 Merge commit 'f22e1405dc12ed4fdc05a3f6a9e5fa7ee966f627' as 'thirdparty/sljit' 2021-12-11 19:43:23 +00:00
encoded-byte 5c3ac88547 mia: updated famicom database 2021-12-10 15:55:35 +00:00
encoded-byte 85fcda5b42 mia: correct type for pak attribute 2021-12-10 15:55:35 +00:00
encoded-byte f512fdc969 fc: add bus conflicts to cnrom 2021-12-10 15:55:35 +00:00
encoded-byte 64286fbd46 fc: improve ppu skipped clock timing 2021-12-06 16:54:50 +00:00
Simon Eriksson e0c4cc76f2 mia: Correct save type for Transformers: Beast Wars Transmetals (N64) 2021-12-03 21:59:50 +00:00
encoded-byte 7b4a346336 component: add illegal nops to mos6502 cpu 2021-12-02 21:49:57 +00:00
Simon Eriksson 763f7da939 mia: Correct save type for Premier Manager 64 (N64) 2021-12-01 20:05:09 +00:00
Luke Usher ee188dcb31 ares: bump version number to v126 2021-11-28 08:00:14 +00:00
encoded-byte 1f8b3f86b9 fc: partial support for bandai datach 2021-11-27 14:30:51 +00:00
encoded-byte 18e334a6cf fc: support for bandai oeka board 2021-11-27 14:30:51 +00:00
encoded-byte 24675b0161 fc: fix saving on bandai lz93d50 + m24c02 2021-11-25 21:33:15 +00:00
encoded-byte f4caedcd5e component: fix eeprom m24c mode selection 2021-11-25 21:33:15 +00:00
encoded-byte bdc6313e46 fc: support for bandai karaoke board 2021-11-25 09:52:14 +00:00
encoded-byte fd3a56b0a2 fc: support for cprom board 2021-11-25 09:52:14 +00:00
encoded-byte 663b6951e3 fc: attach sunsoft 4 + ext rom 2021-11-25 09:52:14 +00:00
encoded-byte 554430276c fc: support for namco 163 board (no sound) 2021-11-22 20:47:23 +00:00
Luke Usher 3748baf8e8 Revert "libco: disable backing up SSE registers on Win64"
This reverts commit 32690bb6f0.

Skipping restoration of SSE registers turned out to be too fragile/risky
2021-11-22 15:11:28 +00:00
encoded-byte e1bd1bfdf9 fc: support txrom variants 2021-11-22 09:06:54 +00:00
encoded-byte 5f6b75a013 fc: support for cnrom with security 2021-11-22 09:06:54 +00:00
encoded-byte 2d6fe4aa16 fc: support for sxrom boards with mmc1a 2021-11-22 09:06:54 +00:00
encoded-byte b49e5496da fc: support for unrom variants 2021-11-22 09:06:54 +00:00
encoded-byte 645d481493 fc: support for bandai lz93d50 variant 2021-11-22 09:06:54 +00:00
Simon Eriksson bc14c35cb5 fc: Support for Action 52 board 2021-11-18 06:40:36 +00:00
encoded-byte 16210cf1bf fc: split bandai fcg / lz93d50 boards
To better describe chips and prepare support for other related boards
2021-11-17 09:04:23 +00:00
encoded-byte d34e54c808 fc: support for bandai 74161 boards 2021-11-17 09:04:23 +00:00
encoded-byte 76508d02bd mia: updated fc database
Games tested so far. Two new not working games discovered:
- Aladdin (Europe): Hangs after starting game
- Wizards & Warriors (Europe): Graphicals glitches on HUD, severe slowdowns. PAL timing related?
2021-11-17 09:04:23 +00:00
Luke Usher 32690bb6f0 libco: disable backing up SSE registers on Win64
For some users, this gives a dramatic performance boost, and finally
brings the Windows builds in-line with Linux/Mac builds in terms of
performance.

This technically goes against the Win64 ABI, which demands that SSE
registers are saved, however, in-practice, our testing has shown that
this has not caused any issues so far.
2021-11-16 11:10:41 +00:00
Simon Eriksson 9eca885d8b fc: Support for Color Dreams board 2021-11-16 06:28:36 +00:00
Luke Usher f9a53d2167 msx: remove rom debug print 2021-11-12 18:28:41 +00:00
Luke Usher fd5b22c5cd msx: use the slot layout and memory expected by cbios 2021-11-12 18:23:21 +00:00
Luke Usher 2f6edc7efe msx: add huristics for rom type detection 2021-11-12 18:22:48 +00:00
invertego 12ac1b5534 hiro: monitor activate messages for window focus
Monitor WM_ACTIVATE instead of WM_SETFOCUS/KILLFOCUS messages to avoid
responding to spurious notifications.
2021-11-11 09:09:50 +00:00
encoded-byte c8fa67ec39 mia: updated fc database
All entries tested and working (except for "Akira")
2021-11-10 22:17:27 +00:00
encoded-byte 5341d0d7d4 fc: support for namco 118 board 2021-11-10 22:17:27 +00:00
encoded-byte ad0105de25 fc: support for namco 175/340 boards 2021-11-10 22:17:27 +00:00
Luke Usher e3663a9eec bump version to v125.1 2021-11-10 21:34:06 +00:00
invertego a01ccb72f2 hiro: track window focus via messages, not polling
On Windows, track WM_SETFOCUS and WM_KILLFOCUS messages to determine
focused status rather than polling with GetForegroundWindow(). The
latter involves a syscall and causes noticeable slowdown when called
repeatedly, such as when GameBoy games poll joypad status in a loop.
2021-11-10 21:32:41 +00:00
Luke Usher 27996d81d4 fc: implement gtrom mapper 2021-11-10 21:01:42 +00:00
invertego 47af07c507 ms, sfc: fix light gun related crashes
Fix unloading systems with light gun peripherals active. The code
responsible for removing crosshair sprites was dereferencing a null
pointer. This cleanup now occurs in Screen::quit() when unloading.
2021-11-10 18:31:51 +00:00
invertego cc6ab702c0 mia: prefer known rom extensions in zip archives
Instead of just reading the first file from a zip archive, prefer files
that match known rom extensions. Extra files such as readmes should not
interfere with the loading of the game.
2021-11-10 11:08:33 +00:00
Luke Usher d633b92a57 v125 2021-11-09 20:20:53 +00:00
Luke Usher 579be2bb04 ms: pass "set VDPbuffer" tests in VDPTEST 2021-11-09 11:45:19 +00:00
Luke Usher 89db771c73 gg: add Mickey Mouse no Castle Illusion (Japan) to game database 2021-11-09 11:00:35 +00:00
invertego 33b95510cb sh2: fix several instructions, default to recompiler
Fix several correctness bugs in SH2 instructions in both the interpreter and
recompiler and switch the default implementation from the cached interpreter to
the recompiler. This brings the 32x games BC Racers and Zaxxon's
Motherbase 2000 to playable status. Fixed instructions:

Interpreter
- ADDC Rm,Rn
- ADDV Rm,Rn

Recompiler
- MAC.W @Rm+,@Rn+

Both
- CMP/STR Rm,Rn
- MOV.B Rm,@-Rn
- MOV.W Rm,@-Rn
- MOV.L Rm,@-Rn
- NEGC Rm,Rn
2021-11-09 08:50:44 +00:00
encoded-byte 31eee5f6f1 fc: pinout support for konami vrc7 2021-11-05 16:25:13 +00:00
encoded-byte 7ba1c2925d mia: add fc konami vrc2/4/6 to database 2021-11-05 16:25:13 +00:00
encoded-byte dbc1b4ccc6 fc: support for konami vrc2 variant 2021-11-05 16:25:13 +00:00
encoded-byte a3a1969775 fc: always check for ram presence
Some games without ram try to read this space, better be safe
2021-11-05 16:25:13 +00:00
encoded-byte ab67ec12cd fc: refactor of jaleco boards 2021-11-03 06:41:59 +00:00
encoded-byte 02cb1268e4 fc: support for jaleco jf13 board 2021-11-03 06:41:59 +00:00
encoded-byte 50994a2c60 fc: support for jaleco fc05 board 2021-11-03 06:41:59 +00:00
encoded-byte 9e099e9b15 fc: remove unneeded test
No need to test rom if board don't support ram
2021-11-03 06:41:59 +00:00
encoded-byte 16cbd8b149 fc: support for jaleco jf17/19 boards 2021-11-03 06:41:59 +00:00
encoded-byte 5491a6a9c8 fc: fix jaleco jf14 banking 2021-11-03 06:41:59 +00:00
encoded-byte d0a14c682d fc: support for irem if12 board 2021-11-01 13:01:30 +00:00
encoded-byte 4eb4b6cdb7 fc: support for irem lrog017 board 2021-11-01 13:01:30 +00:00
encoded-byte 9bc59159d0 fc: check for ram and simplify banking 2021-11-01 13:01:30 +00:00
encoded-byte f518f04ffa mia: database for fc 2021-11-01 13:01:30 +00:00
encoded-byte 2ce06bc4d1 fc: support for irem h3001 board 2021-11-01 13:01:30 +00:00
encoded-byte a3285b6959 fc: support for irem g101 board 2021-11-01 13:01:30 +00:00
jbo_85 8a7ac00d03 snes: Fix 'D-Port B+O+S' test in SPC7110 Check Program as reported in issue #228, this bug was introduced after the huge rewrite to the type system in v117 2021-10-27 08:15:35 +01:00
encoded-byte 38cf1b0f8e fc: fix address 2021-10-26 22:57:57 +01:00
encoded-byte d26ffccc9f fc: add chip type to manifest 2021-10-26 22:57:57 +01:00
encoded-byte 9ee4afd17f fc: support for taito x1-017 board 2021-10-26 22:57:57 +01:00
encoded-byte 61dbb64999 fc: support for taito x1-005 board 2021-10-26 22:57:57 +01:00
encoded-byte 2d5e1ba552 fc: support for taito tc0690 board 2021-10-26 22:57:57 +01:00
encoded-byte a31b0a7768 fc: support for taito tc0190 board 2021-10-26 22:57:57 +01:00
TascoDLX 7c9ff4ba6d md: sram support for Super Hydlide (J) 2021-10-25 09:14:15 +01:00
TascoDLX 0bc30dd26d md: fix interrupt ack special case 2021-10-25 09:14:15 +01:00
TascoDLX f73032e17f mcd: support for 3-button pad (as default) 2021-10-25 09:14:15 +01:00
TascoDLX 2eee9bcd4e mcd: autodetect disc region based on boot code 2021-10-25 09:14:15 +01:00
TascoDLX e3a3927e95 mcd: report error on unhandled cdd command 2021-10-25 09:14:15 +01:00
TascoDLX f04e55f863 mcd: allow continuous cd playback 2021-10-25 09:14:15 +01:00
TascoDLX 08aecccc5a mcd: clean up & fix graphics render 2021-10-25 09:14:15 +01:00
TascoDLX 3471756c06 mcd: reset timer on write 2021-10-25 09:14:15 +01:00
invertego d40e6e1cd3 n64: increase screen canvas to 576 lines
Certain PAL games require this. Affected games include:
- Michael Owen's WLS 2000
- Perfect Dark
- Top Gear Overdrive
2021-10-25 09:13:14 +01:00
encoded-byte 6a262e01ae fc: support for taito tc0690 board 2021-10-25 07:44:40 +01:00
encoded-byte 2f6a51b3ef fc: support for taito tc0190 board 2021-10-25 07:44:40 +01:00
TascoDLX ee3b764b8e ares: bump serializer version for MD changes 2021-10-22 19:16:39 +01:00
TascoDLX 4216d5ae0a md: improved timing/signaling for z80 busreq 2021-10-22 19:16:39 +01:00
TascoDLX 878efe0a05 md: fixed irq issues: timing, delays, ack 2021-10-22 19:16:39 +01:00
Luke Usher 98aee19e93 fc: support expanded bnrom & uxrom
These mappers are used in various homebrew/unlicenced titles
2021-10-21 20:08:23 +01:00
TascoDLX 7810a05b60 md: improved cpu open bus line accuracy 2021-10-21 15:57:15 +01:00
TascoDLX b83e868a6e md: fix z80 bus access & timing issues 2021-10-21 15:57:15 +01:00
TascoDLX ce3153b10e md: prevent sram from masking out high rom 2021-10-21 15:57:15 +01:00
TascoDLX 259642ae2a m68000: fix disassembly of pc-relative addresses 2021-10-21 15:57:15 +01:00
TascoDLX 30921061c7 m68000: restore TAS instruction for cpus other than MD main 2021-10-21 15:57:15 +01:00
TascoDLX 757da94463 m68000: avoid changing interrupt mask on exception 2021-10-21 15:57:15 +01:00
Sintendo 1c026f5edf libco/aarch64: Optimize co_swap_function
Improves thread-switching performance using the following techniques:

- Interleave stores/loads
- Restore the stack pointer and link register as early as possible
2021-10-19 12:15:56 +01:00
Sintendo 2d90b6343d libco/aarch64: Fix vector register handling
The calling convention specifies that d8-d15 (the lower 64 bits of
vector registers q8-q15) are callee-saved. However, libco was
erroneously saving and restoring general-purpose registers x8-x15
instead.
2021-10-19 12:15:56 +01:00
Giovanni Bajo 4c312ab2af Fix linking on old macOS toolchains
Ares JIT recently started to require the data segment to be executable
(see  https://github.com/ares-emulator/ares/pull/200 for details on why
this was done instead of allocating a new segment via mmap).

To do this, it uses mprotect() (bump_allocator::resize), but it also
needs to tell the linker that the data segment can be upgraded to
executable with -Wl,-segprot,__DATA,rwx,rw (nall/GNUmakefile).
Unfortunately, for quite some time, the clang LD had a bug and didn't
accept that option for the data segment.

The official CI has a newer linker without the bug, but for developers
compiling ares with an old toolchain, this small tool will patch the
binary to mark the data segment as potentially executable.
2021-10-19 11:00:23 +01:00
invertego 55d197fdc3 desktop-ui: fix file/folder browser dialog alignment
Align file/folder dialogs to the settings window when appropriate. The
absence of this alignment was triggering asserts in debug builds.
2021-10-19 10:59:51 +01:00
Kawa 53290b9c71 Add screenshot hotkey
As requested in #233
2021-10-17 22:55:49 +01:00
invertego 764a881d36 recompiler: on macOS allow data segment to be executable
Override the data segment's maximum protection from rw to rwx, allowing
mprotect() to be called on recompiler code blocks to make them
executable.
2021-10-17 12:38:14 +01:00
invertego a10e089100 ci: use MSYS2 on Windows, add Windows/Clang build
This change upgrades GCC from the version preinstalled by GitHub Actions
(8.1.0) to the latest MSYS2 version (10.3.0). It also adds a
Windows/Clang build configuration, though the release job still
grabs the GCC build.
2021-10-16 18:59:50 +01:00
TascoDLX 590ec4cb32 Various fixes to CD session handling 2021-10-16 18:59:14 +01:00
TascoDLX 30d143092d Tweak & fix generation of CD subchannel data 2021-10-16 18:59:14 +01:00
TascoDLX 2dbd5a43a0 Improved CD CUEsheet loading to handle PREGAPs & POSTGAPs 2021-10-16 18:59:14 +01:00
Shideravan 08c013dc46 Update README.md 2021-10-15 16:39:36 +01:00
Shideravan 0d169fe641 Adding the ares logo
The resource comes directly from https://ares-emulator.github.io/
This ends the editions in the readme page.
2021-10-15 16:39:36 +01:00
Luke Usher 1f73642031 ares v124
ares v124 brings the compatibility rating for the Famicom and Nintendo 64 cores
up to three stars. This means that at least 80% of the game library is working.

There have been notable improvements to Game Boy, Mega Drive, Sega Mega CD,
Sega 32X and Nintendo 64 emulation, and the PC-Engine multi-tap is now supported.

Finally, the dynamic recompiler now generates slightly more efficient code. You
may notice a slight performance boost in Nintendo 64, Sega 32X and Sony
PlayStation.

**Changelog:**
 * Famicom: Add support for Jaleco JF11/JF14 mapper [Shideravan]
 * Game Boy: Bring fast-boot closer to normal boot; Fixes Dr. Fraken [invertego]
 * Game Boy: Use stable sort for sprites; fixes speech bubbles in Crayon Shin-chan 3 [invertego]
 * Game Boy: Remove limit on window width; fixes pause screen in Heiankyo Alien [invertego]
 * Game Boy: Emulate serial transfers with no link; fixes input in Alleyway [invertego]
 * Game Boy: Improve handling of LCD/BG enable for DMG; fixes Hyper Lode Runner [invertego]
 * Game Boy: Resume from halt whenever (IE & IF) != 0; fies Amazing Penguin [invertego]
 * Mega Drive: Fix DMA transfer rate and H-Int signalling; fixes Another World, 3 Ninja's Kick Back, Virtua Racing, Burning Force [TascoDLX]
 * Mega Drive: Fix sprite masking and overflow; Fixes Mickey Mania [TascoDLX]
 * Mega Drive: Fix DMA fill; Fixes Demons of Asteborg [TascoDLX]
 * Mega Drive: Fix VRAM byte addressing; Fixes Contra Hard Corps, Musha [TascoDLX]
 * Mega Drive: Fix VDP control port writes [TascoDLX]
 * Mega Drive: Implement HV Counter Patching [TascoDLX]
 * Mega Drive: Implement STOP instruction; fixes Thunder Force IV [TascoDLX]
 * Mega Drive: Default to 3-button gamepad; fixes games that don't support 6-button pads [Shideravan]
 * Mega Drive/Mega CD: Fix detection of device rom header; allows Mode-1 to work [Luke Usher]
 * Mega CD: Fix word-ram 1M access pattern; Fixes Lethal Enforcers II [TascoDLX]
 * Mega CD: Fix H-Int vectoring; Fixes Microcosm, Silpheed, Wing Commander, and others [TascoDLX]
 * Mega CD: Implement full graphics/1M wordram translations; fixes Rebel Assault [TascoDLX]
 * Mega 32X: Tighten M68k sync; Fixes Kolibri and Fifa 96 [TascoDLX]
 * Neo Geo Pocket: Fix off-by-one error in LDAR instruction; fixes a crash in SNK Gals' Fighters [invertego]
 * Nintendo 64: Support controller ports 3 & 4 [LukeUsher]
 * Nintendo 64: Better Flash Ram support; Fixes Majora's Mask, Paper Mario, Derby Stallion 64 [jeltaqq]
 * Nintendo 64: Add mempack/rumble status to database; eliminates controller pak/rumble pak warnings [remutro]
 * Nintendo 64: Consume cycles to compensate for skipped RDRAM initialization; fixes Wave Race 64 Shindou Pak [invertego]
 * Nintendo 64: Fix PIF RAM init on cold boot, preserve RDRAM on warm reset; fixes Perfect Dark boot [invertego]
 * Nintendo 64: Default to 3 controllers for Jeopardy!, this game doesn't work with 4 controllers, even on hardware [invertego]
 * Nintendo 64: Fix FPU compare and divide exceptions; Turok is now able to play the entire Acclaim logo animation [invertego]
 * Nintendo 64: Decrease SI DMA delay; improves Turok, Donkey Kong 64, Forsaken 64, Hercules, Triple Play 2000 [invertego]
 * Nintendo 64: Implement perfect PI DMA write [rasky]
 * PC Engine: Support Multi-Tap [LukeUsher]
 * TMS9918: Widen vcounter to 9-bits; improves ColecoVision, SG-1000, MSX [invertego]
 * desktop-ui: Support up-to 5 virtual controllers (For PC-Engine) [LukeUsher]
 * desktop-ui: Fix window background with GTK3 [ghisvail]
 * desktop-ui: Install icons in freedesktop compliant locations [ghisvail]
 * desktop-ui/hiro: Improved macOS user experience [LIJI32]
 * ruby: Fix conflated keys on Windows; fixes some keyboard input issues [invertego]
 * nall: Use XDG base directories on *nix systems [ghisvail]
 * shaders: Include a selection of public-domain shaders [LukeUsher]
 * ares: Fix address masking in instruction tracer [invertego]
 * ares: Fix warnings reported by clang [invertego]
 * ares: Fix static init in node subclasses [invertego]
 * ares: Use 64-bit integers instead of 128-bit integers in the scheduler [invertego]
 * ares: Use IP relative direct branches in the recompiler, where possible [invertego]
 * ares: Emit only one epilog per block in the recompiler [invertego]
 * ares: add label API to recompiler to simplify branches [invertego]
 * ares: Use fixed BSS allocation for code cache; improves recompiler performance [invertego]
 * ares: Fix instructionEpilogue test [invertego]
 * ares: Directly emit code for target ABI; generates more efficient code in the recompiler [invertego]
 * ares: Avoid encoding absolute data addresses in the recompiler [invertego]
 * nall: allow mingw headers to define _MSVCRT_VERSION_ [invertego]
 * nall: generate PDB when building with clang on windows [invertego]
 * nall: allow generation of debug symbols with symbols=true [invertego]
 * nall: link with lld wen building with clang on Windows [invertego]
 * nall: Make thread movable but not copyable; fixes random UI hangs on Windows [invertego]
 * mia: Fix MSU-1 rom loading [Luke Usher]
2021-10-15 14:48:42 +01:00
invertego d31d5a9310 recompiler: avoid encoding absolute data addresses
Reference data members via offsets from nonvolatile registers instead of
directly encoded absolute memory addresses. This is the last change
required for generated code to be fully position independent.

The reduction in code size is generally 5-7%, with the exception of the
N64 RSP, which sees a reduction of nearly 40%. This is mostly a result
of moving the clock increment to instructionEpilogue().
2021-10-15 09:11:47 +01:00
Luke Usher 6b9844a4e4 mia: fix msu-1 rom loading 2021-10-14 20:14:04 +01:00
invertego 3ca1f9ebb4 recompiler: directly emit code for target ABI
Previously, the recompilers in ares would assume the System V calling
convention, then emit extra moves on Windows to handle the differences
in register usage. Now, they directly populate the registers used by the
target system for passing parameters to functions. This is achieved
with register aliases set for the appropriate ABI at compile time.

Furthermore, registers that are nonvolatile only on Windows - rsi and
rdi - are no longer used as temporaries, removing the need to save and
restore them in recompiled code blocks.

This accounts for roughly a 10% reduction in recompiled code size on
Windows while making functionally no difference to other systems.
2021-10-02 10:14:00 +01:00
TascoDLX 47545c7d01 mcd: implement full graphics / 1M-wordram translations 2021-10-01 09:00:52 +01:00
Shideravan d2df3a6b25 Fixing the typo 2021-09-29 09:00:33 +01:00
Shideravan 7b2ddaaab7 Adding ISC badge 2021-09-29 09:00:33 +01:00
invertego 84d4efe09f nall: make thread movable but not copyable
The thread class owns a resource and should have semantics akin to
std::unique_ptr. By allowing copying, the Windows implementation was
calling CloseHandle() when the original copy was destructed, meaning the
new copy would have no actual ownership of the handle. Once the thread
itself exited (dropping the last reference on the handle), later uses of
this handle in join() and ~thread() could end up operating on anything
or nothing depending on whether the handle value had been recycled.

This change modifies the POSIX implementation just enough to keep the
semantics the same as the Windows implementation for users of the class.
Otherwise, there is no functional change.

This fixes random UI hangs and other bad behavior on reset or unload.
2021-09-28 09:08:15 +01:00
invertego 67db4349d8 recompiler: fix instructionEpilogue() test
instructionEpilogue() returns a bool, but all recompilers were
performing a 64-bit test on the return value. If sizeof(bool) == 1, only
the bottom 8 bits are guaranteed to be valid.
2021-09-27 16:54:14 +01:00
TascoDLX bfca0dc6ca 32x: tighten 68k sync 2021-09-27 10:43:34 +01:00
TascoDLX 0ae31ab8a4 mcd: fix h-int vectoring 2021-09-27 10:43:34 +01:00
TascoDLX c4017ede21 mcd: correct wordram 1M access pattern 2021-09-27 10:43:34 +01:00
Shideravan 9f8838e4d9 ares and bsnes are now clickable links to the respective projects 2021-09-27 10:42:02 +01:00
invertego 2770c20007 recompiler: use fixed bss allocation for code caches
Place code caches in the bss section to guarantee proximity to the text
section in order to improve branch prediction and eventually so we can
reliably utilize IP-relative branch instructions.

There is now a fixed 1 GB buffer that is shared by all system cores with
recompilers (m32x, n64, ps1). Because the linker will place it in bss,
it will consume no space in the executable on disk, and operating
systems should be clever enough to avoid comitting physical pages until
it is actually in use. The buffer is defined in a separate translation
unit and only referenced from under compile-time recompiler checks, so
it should be left out by the linker when recompilers are disabled.
2021-09-27 10:41:38 +01:00
invertego 394da44a09 recompiler: add label API to simplify emitting branches 2021-09-27 10:41:24 +01:00
invertego 9b99a961f5 recompiler: emit one epilog per block 2021-09-27 10:41:24 +01:00
invertego d17a5ea045 recompiler: use IP-relative direct branches when possible 2021-09-27 10:41:24 +01:00
Luke Usher 741bfcda01 mia: fix detection of mega-drive device rom header 2021-09-22 11:41:50 +01:00
Lior Halphon ddf5ccadf5 Avoid unicode in files 2021-09-22 09:39:59 +01:00
Lior Halphon 9fc5072597 System colors API and Dark Mode support on macOS 2021-09-22 09:39:59 +01:00
Lior Halphon 151418da8d Hide the memory viewer tool in macOS because hiro on Cocoa lacks the hex editor widget 2021-09-22 09:39:59 +01:00
Lior Halphon 2ad3f3379c Update Tools UI 2021-09-22 09:39:59 +01:00
Lior Halphon e1ad2661a7 High DPI sources, redo CocoaCanvas rendering, improved About dialog 2021-09-22 09:39:59 +01:00
Lior Halphon c1f6d5702a Add HiDPI icons to hiro 2021-09-22 09:39:59 +01:00
Lior Halphon 41f7d14e75 High DPI APIs in hiro 2021-09-22 09:39:59 +01:00
Lior Halphon c6d6431e82 Invert ifdef 2021-09-22 09:39:59 +01:00
Lior Halphon b035ce9560 Proper ellipsis on macOS 2021-09-22 09:39:59 +01:00
Lior Halphon 6599155ad2 Revise the settings UI layouts 2021-09-22 09:39:59 +01:00
Lior Halphon ee61536d52 Cocoa bug fixes 2021-09-22 09:39:59 +01:00
Lior Halphon ff209f0f19 Accidentally ignored fonts 2021-09-22 09:39:59 +01:00
Lior Halphon cac6885bfb Update the look of the settings sidebar 2021-09-22 09:39:59 +01:00
Lior Halphon bdfc477b8a Improve table-view rendering code 2021-09-22 09:39:59 +01:00
Lior Halphon ce43723566 The settings window should not be resizable 2021-09-22 09:39:59 +01:00
Lior Halphon 04ea2a52ee Better handling of fullscreen 2021-09-22 09:39:59 +01:00
Lior Halphon 01a89c3db0 Implement missing window methods 2021-09-22 09:39:59 +01:00
Lior Halphon 2900376896 This convention is the most common on both Windows and Mac for "Recent" menus 2021-09-22 09:39:59 +01:00
Lior Halphon e812f9fdb9 Use the standard Mac term 2021-09-22 09:39:59 +01:00
Lior Halphon add71b87e8 Native file/folder icons 2021-09-22 09:39:59 +01:00
Lior Halphon a563083096 Disable menu icons for Cocoa 2021-09-22 09:39:59 +01:00
Lior Halphon 984d2d125f Proxy icons 2021-09-22 09:39:59 +01:00
Lior Halphon c50a8a0ebe Use consistent ifdefs 2021-09-22 09:39:59 +01:00
Lior Halphon 280bc39df4 Prevent calling output from 2 different threads at the same time (will crash) 2021-09-22 09:39:59 +01:00
Lior Halphon 878d111e52 Fix titlebar discoloration 2021-09-22 09:39:59 +01:00
Lior Halphon f9e755dd04 Fix filtering in dialogs, allow selecting game folders, allow opening game folder via the Dock/open with 2021-09-22 09:39:59 +01:00
Lior Halphon 35279ba28d Fix slider off-by-one 2021-09-22 09:39:59 +01:00
Lior Halphon 815ad9a73d Add onOpenFile to application, make the hiro's Cocoa frontend use it 2021-09-22 09:39:59 +01:00
Lior Halphon fb0d69e74b Add missing Hide shortcuts 2021-09-22 09:39:59 +01:00
Lior Halphon 80c14502f3 Remove excessive use of @autoreleasepools 2021-09-22 09:39:59 +01:00
Lior Halphon ae8f761f46 Switch to ARC 2021-09-22 09:39:59 +01:00
Lior Halphon 5b1cbdb542 Prepare for ARC 2021-09-22 09:39:59 +01:00
Lior Halphon 985e3c10fd Improve menu titles, add keyboard shorts to standard items 2021-09-22 09:39:59 +01:00
Lior Halphon eecdde4ee7 Improve compatibility and silence warnings 2021-09-22 09:39:59 +01:00
Lior Halphon 580b322313 Replace hardcoded Lucida Grande with the current system font 2021-09-22 09:39:59 +01:00
Shideravan 641ebdaca1 MD: Supporting default 3-button Control Pad
And defaulting it, as some older games depend on it to this kind of input to work properly.
eg.: Forgotten Worlds
https://youtu.be/ngHDIFQHFyQ

This also solves https://github.com/higan-emu/ares/issues/177

Fighting pad is still supported just need to be selected in Mega Drive->Controller Port
2021-09-22 09:03:11 +01:00
invertego ed4d21d7a3 scheduler: use 64-bit counters on all platforms
Currently ares is using 128-bit counters when the built-in __int128 type
is available. Near's notes on this topic conceded that it wasn't really
necessary, but defended it by stating there was no speed penalty on
64-bit architectures.

Unfortunately, LLVM's 128-bit integer support is buggy when compiling
for Windows targets. I've filed a bug report and am optimistic this will
eventually be fixed, but to prevent people from being burned when
compiling ares themselves, it would be safer to avoid the built-in
__int128 type entirely.

This change imposes 64-bit counters on all architectures for
consistency. It redefines the nall (u)intmax types to match the standard
(u)intmax_t types, though there is no longer anything in ares using them
at the moment.
2021-09-21 20:37:35 +01:00
Giovanni Bajo b050c5f04c n64: implement perfect PI DMA write
This commit implement perfect PI DMA write. The PI DMA is normally used
for 8-byte aligned transfers, which is where it constantly works. The
hardware does contain a half-baked, buggy support for 2-byte aligned
transfers and odd-size lengths. I have extensively investigated the
behavior of every single quirk, and produced a test ROM that Ares
passes after this commit (timing is still off, but that's for another
day):

https://github.com/rasky/n64_pi_dma_test

The implementation is the same that I've previously submitted to cen64,
adapted for the ares codebase.
2021-09-21 09:06:37 +01:00
invertego d1b00bfa6b link with lld when building with clang for Windows
The LLVM linker is required for both PDB generation and LTO support.
2021-09-21 09:05:26 +01:00
invertego d2ee5b9db9 generate PDB when building with clang for Windows
Also, you can now set symbols=true to forcibly generate debugging
information for any non-debug build configuration.
2021-09-21 09:05:26 +01:00
invertego f275f9f176 allow mingw headers to define __MSVCRT_VERSION__
Whatever defining this manually was intended to fix, today it is only
breaking things. The mingw headers define this as 0x700 if you are
linking against MSVCRT and 0xE00 if you are linking against UCRT. This
is a mingw-internal macro, and there is currently no comparison in the
headers that evaluates differently for 0x601 than for 0x700. However,
always forcing it to 0x601 as nall does breaks linking against UCRT.

We should let mingw define this appropriately.
2021-09-21 09:05:26 +01:00
invertego b069d68e05 fix static initialization in Node subclasses
When building with clang, two static inline members of Node subclasses -
identifier and register - were not consistently initialized in that
order during application startup. Because the constructor of register
depends on identifier, this poses a problem.

I'm not sure if clang is on the wrong or if the initialization order is
actually unspecified by the language standard, but this situation can be
easily avoided, so I opted to do just that.
2021-09-21 09:05:26 +01:00
invertego b6d95c838f enable clang warnings tautological-compare and shift-count-overflow
These warnings can often catch genuine bugs. The only tautological
compare warning I observed was reporting a real bug in the SFC core. The
shift count overflow warnings appeared to be for cases that were benign,
though only because I already fixed a significant one in the instruction
tracer. In general, such shifts are undefined behavior and require
surrendering to the whims of the compiler and the processor
architecture, so they are worth avoiding.

The large diff in ares/component/processor/tlcs900h/instruction.cpp is
mostly uninteresting. I had to make the control flow more explicit for
undefined instructions to stop the compiler from complaining about bad
template specializations. While I was at it, I enabled unused-value
warnings for that file, which only required adding a few void casts.
2021-09-21 09:05:26 +01:00
invertego 0976b64dd8 fix warnings reported by clang
Most of the warnings are from Windows specific code, as the rest of the
codebase is already fairly clean. This change fixes a couple of (benign)
bugs discovered by these warnings.

In hiro/windows/action/menu.cpp, menu-item.cpp:
A function pointer was being passed in place of a bool argument to
nall::image::scale(). At one point the name Interpolation::Linear
referred to an enum. In any case, the argument in question defaults to
true - specifying linear interpolation - so it is unneeded.

In hiro/windows/widget/widget.hpp:
The function minimumSize() was being overloaded instead of overridden
due to a missing const qualifier. It doesn't appear to have had any
negative side effects in ares.
2021-09-21 09:05:26 +01:00
Luke Usher 8639e306c7 Squashed 'ares/n64/vulkan/parallel-rdp/' changes from 464ab61fc..05136e3b4
05136e3b4 Update to 31ea5eb2d6fcb2d8f1df5f0951364322d09ac01a

git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 05136e3b4717fc78445e6c5b3085601151327eb3
2021-09-17 13:35:22 +01:00
Luke Usher c71f131b0c Merge commit '8639e306c77db691296adebcd6be33870fbec619' 2021-09-17 13:35:22 +01:00
invertego 822186413c debugger: fix address masking in instruction tracer
This change corrects masking for 32 bit addresses.

Per the C++ standard on shift operators: "The behavior is undefined if
the right operand is negative, or greater than or equal to the width of
the promoted left operand."
2021-09-15 15:16:04 +01:00
TascoDLX da53c2b905 ares: bump serializer version ahead of next point release 2021-09-13 09:01:12 +01:00
TascoDLX f09cddddd5 m68000: implement STOP'd state 2021-09-13 09:01:12 +01:00
TascoDLX 56ea29e244 md: implement HV-counter latching 2021-09-13 09:01:12 +01:00
TascoDLX e6231d4379 md: correct DMA fills (according to research by Nemesis) 2021-09-13 09:01:12 +01:00
TascoDLX 8ab3f79f6a md: fix VDP control port writes 2021-09-13 09:01:12 +01:00
TascoDLX 547d6658dd md: fix VRAM byte addressing 2021-09-13 09:01:12 +01:00
invertego 008486531d n64: decrease SI DMA delay
Reduce the (minimum) number of cycles between an SI DMA request and the
completion of said request from 131072 to 2304 cycles. This is the
duration used in other emulators, and it is in agreement with the
observed behavior of Turok, which can only tolerate a delay between 215
and 3888 cycles (subject to current timings in ares).

In addition to fixing input in Turok - Dinosaur Hunter, this change gets
the following games past the intro:
- Donkey Kong 64 (w/ major graphical issues)
- Forsaken 64
- Hercules - The Legendary Journeys
- Triple Play 2000
2021-09-12 22:46:25 +01:00
invertego 1e71f59bc0 n64: fix fpu compare and divide exceptions
On compare to NaN:
- do not raise an exception if exceptions are disabled
- do not update the csr condition bit if exceptions are enabled

On divide by zero:
- do update the destination fpr if exceptions are disabled

For both of the above:
- do set the csr cause bit
- do set the csr flag bit if exceptions are disabled

Turok is now able to play out the entire Acclaim logo animation. It was
previously resetting due to erroneously raised invalid operation
exceptions.
2021-09-12 22:46:02 +01:00
invertego 80bc2ad805 n64: default to 3 controllers for Jeopardy!
Jeopardy! only supports up to 3 players, and if four controllers are
plugged in when the game starts, it performs an out of bounds array
access that breaks further input logic. The only workaround is to unplug
a controller and reset the system. To make this game work well in ares
out of the box, we should connect no more than 3 controllers by default.

I opted to put a check specifically in desktop-ui because this is
fundamentally a mismatch between a specific game and a design choice (to
default to 4 controllers) in the desktop-ui frontend. It didn't feel
right to add a dedicated attribute to mia that did not describe a
feature of the cartridge itself and would not be generally applicable
other games (unlike rumble and memory pak support).

This change also brings the rumble and memory pak attributes in line
with the implementation of boolean attributes for other systems. There
is no functional change, though it will affect generated manifests if
they are/were persisted to disk.
2021-09-11 18:26:16 +01:00
invertego ae6cbb52ae n64: fix PIF RAM init on cold boot, preserve RDRAM on warm reset
A recent workaround for BattleTanx caused a regression in Perfect Dark.
Essentially, it was always telling games that they had been started by a
warm reset rather than a cold boot. Perfect Dark expects data to be
preserved in RDRAM across resets and fails to get as far as drawing
something on the screen if it isn't there.

This change reverts the workaround so that Perfect Dark will perform the
full initialization required after a cold boot. Luckily, this will not
regress the BattleTanx games, as they were fixed by my last change
(making sure IPL3 consumes a sufficient number of cycles). This change
also skips clearing RDRAM on resets, which is again required by Perfect
Dark and possibly other games.
2021-09-10 13:47:06 +01:00
invertego 3212ce0148 n64: consume cycles to compensate for skipped RDRAM initialization
The RI_SELECT register is read by IPL3 to check if RDRAM initialization
should be skipped. If we are forcing it to be skipped, we should also
consume enough cycles to not inadvertently speed up the boot process.

Wave Race 64 Shindou Pak Taiou Version will freeze on the N64 logo if
the SCC count register, which increments at half the CPU clock rate, has
too small a value.

The idea of using RI_SELECT reads as a cue to consume extra cycles was
borrowed from MAME.

Thanks to Rasky for measuring the timing on real hardware.
2021-09-09 21:48:37 +01:00
remutro e43902175c fix n64 controller detection/reporting 2021-09-09 21:15:07 +01:00
remutro 9065009045 add detection for shindou editions of wave race and mario 64 2021-09-09 21:15:07 +01:00
Luke Usher fe94e4046c docs: remove old docs directory 2021-09-08 09:48:31 +01:00
remutro a5d8289017 remove erroroneous Fifa entry, fix the world is not enough id - thanks simer 2021-09-06 09:04:41 +01:00
remutro 11a97f6cd1 Add mempak and rumble status to mia; elimiate most controller pak or rumble pak warnings in games 2021-09-05 20:29:35 +01:00
Luke Usher 4146f9df6d pc-engine: hide multitap and "controller port"
This means that it is not possible to disconnect the multi-tap, but it
avoids unsupported situations within ares, that lead to crashes.
2021-09-02 15:58:05 +01:00
remutro 530ce845c5 Workaround for Github issue: https://github.com/higan-emu/ares/issues/61 2021-09-02 09:02:42 +01:00
jeltaqq b199273635 n64: Better Flashram support
Fix Majora's Mask, Paper Mario, Derby Stallion 64
2021-09-01 21:05:04 +01:00
Shideravan 9e1402d437 Removing unnecessary address manipulation 2021-08-31 14:50:05 +01:00
Shideravan 1c2c5845e1 Removing programRAM 2021-08-31 14:50:05 +01:00
Shideravan fb10aba946 Removing CHR RAM 2021-08-31 14:50:05 +01:00
Shideravan 1d4b82f0d5 Creating support for Jaleco JF11/JF14 (Mapper 140) 2021-08-31 14:50:05 +01:00
Ghislain Antony Vaillant 40ce138196 Install icons in freedesktop compliant location
See https://specifications.freedesktop.org/icon-theme-spec

Same behavior as with bsnes and higan.
2021-08-31 13:05:18 +01:00
Ghislain Antony Vaillant 53c0e1c190 Fix window background with GTK3 2021-08-31 13:04:55 +01:00
Ghislain Antony Vaillant beea62f4c3 Use XDG base directories 2021-08-31 13:04:41 +01:00
invertego e6948d2c03 ruby: fix conflated keys on Windows
The flags returned by the Raw Input API have distinct meanings. The
lowest bit reflects the state of the key and the next two bits indicate
scan code prefixes. An oversimplified interpretation of these flags was
causing ruby to conflate events for keys that differ only by prefix.

Reference:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawkeyboard

The full set of conflated key pairs:
Return Enter
Keypad0 Insert
Keypad1 End
Keypad2 Down
Keypad3 PageDown
Keypad4 Left
Keypad6 Right
Keypad7 Home
Keypad8 Up
Keypad9 PageUp
LeftAlt RightAlt
LeftControl RightControl
Multiply PrintScreen
Point Delete
Slash Divide
2021-08-28 17:48:28 +01:00
TascoDLX 2c970caafe md: fix dma fill errors by synching trigger with fifo 2021-08-28 10:11:55 +01:00
TascoDLX 6017b3dd52 ares: resync serializer version to current release, v123 2021-08-28 10:11:55 +01:00
TascoDLX bb49f49373 md: fix sprite masking and overflow 2021-08-28 10:11:55 +01:00
invertego 206a87c82d ngp: fix off-by-one error in LDAR instruction
The TLCS-900 manual states the loaded address is relative to the start
of the instruction plus four bytes - in other words, one byte before the
end of the instruction.

This fixes crashes in SNK Gals' Fighters.
2021-08-28 10:10:01 +01:00
invertego b2e6f2b280 tms9918: widen vcounter to 9 bits
By using an 8 bit counter, the last 6 lines of every frame were being
skipped and the VDP was firing vblank interrupts ~2.3% faster than
intended in the ColecoVision, SG-1000, and MSX.

This also fixes the corrupted turtle graphics in Frogger for
ColecoVision, though this is mostly by chance. The game is buggy and
susceptible to graphics corruption if a vblank is raised between these
instructions:

1d09  out  ($bf),a      ; write low VRAM address byte
1d0b  ld   a,h
1d0c  out  ($bf),a      ; write high VRAM address byte

It could easily be regressed by any future change that impacts timing.
2021-08-27 10:06:30 +01:00
Luke Usher 4e8015b663 ares: add a selection of public domain shaders 2021-08-26 10:31:53 +01:00
invertego 1d4ac499e2 gb: resume from halt whenever (IE & IF) != 0
Normally, breaking out of the halt state is handled by CPU::raise(), but
there is an edge case:
    ; preconditions: IME = 0, IE = 1, IF.0 = 1, LCDC.7 = 0
    ei
    halt

In other words, a vblank interrupt was requested with IME disabled, then
the display was disabled (so no more vblank interrupts will follow),
then interrupts were enabled while entering the halt state. Once halted,
there is no logic in ares to service the requested vblank interrupt.

A better long term approach would be to refactor the SM83 implementation
of halt to be more like the Z80 core - eliminating the loop within the
halt instruction itself - but in the meantime this change offers an
incremental improvement.

This fix prevents Amazing Penguin from freezing immediately on load.
2021-08-26 07:34:00 +01:00
invertego 7ac40e85c6 gb: improve handling of LCD/BG enable bits on DMG
On DMG, when the LCD is toggled from off to on, the screen remains blank
until one frame after the PPU becomes operational.

Furthermore, when the BG is disabled, the window is also no longer
drawn, though the other window logic (like the incrementing window line
counter) seems to remain operational.

This cleans up the visuals of Hyper Lode Runner on level start, but many
more games will be affected by blanking the first frame after the LCD is
toggled on.
2021-08-26 07:07:24 +01:00
Luke Usher 2380e62c79 md: fix sync to be in terms of cpu cycles 2021-08-25 09:45:22 +01:00
Luke Usher 5f0baa9405 pce: remove debug print from multitap 2021-08-24 13:09:50 +01:00
Luke Usher 6f3a90b938 pce: support multi-tap 2021-08-24 12:54:18 +01:00
Luke Usher 99183728eb n64dd: implement all 4 ports 2021-08-24 12:46:35 +01:00
Luke Usher ab39fe00f0 n64: connect ports 3 & 4 2021-08-24 12:11:35 +01:00
Luke Usher 50d76e2657 desktop-ui: support up-to 5 virtual pads
This allows for all four n64 controllers to be used, while providing
capatbility to expand to five controllers for PC-Engine, once we
implement the multi/tubo-tap
2021-08-24 11:33:18 +01:00
Luke Usher d7c3f860f9 readme: remove compatibility/features table
These are best suited to the website, to avoid duplicating the effort of 
updating this information in multiple places.
2021-08-24 09:04:17 +01:00
invertego 8d8de9e328 gb: emulate serial transfers with no link
When a serial transfer is started using the internal clock and no second
device is connected via link cable, 1 bits are shifted into the SB
register. This behavior must be emulated for the game Alleyway;
otherwise, it does not accept player input.
2021-08-24 09:02:00 +01:00
invertego bd0d68a788 gb: remove limit on window width
I couldn't find any research to support this limit, nor does it match
the behavior of other emulators. Everything I could find indicates that
the window should be drawn to the end of the line.

This fixes the right edge of the pause screen in Heiankyo Alien.
2021-08-24 09:01:19 +01:00
TascoDLX d7b57ba411 md: fix h-int signaling 2021-08-24 06:52:15 +01:00
TascoDLX 13786dec7c md: fix dma transfer rate 2021-08-24 06:52:15 +01:00
invertego e5b521d4fb gb: use stable sort for sprites
On DMG, sprites are sorted by x value then by OAM address. As the sprite
array begins in OAM order, a stable sort on x can achieve the desired
result. Conveniently, nall already contains a stable sort implementation
that is optimized for small arrays.

This fixes ordering issues with speech bubbles in Crayon Shin-chan 3.
2021-08-23 09:11:43 +01:00
invertego b44f4b57a6 gb: bring fast boot closer to normal boot
The previous fast boot patch skipped the entire Nintendo logo animation
and sound. Unfortunately, this left a number of registers with different
values than they would otherwise have. The European release of the game
Dr. Franken does not initialize SCY, and fast boot was leaving it set to
100 instead of zero, causing the first logo to be shifted offscreen.

It would be easy enough to amend the patch to initialize SCY to 0, but
for most games this will cause the Nintendo logo to appear for a single
frame, which doesn't look so great.

This new patch skips the first ~4 seconds of the boot animation and
disables scrolling but otherwise leaves things alone. The result is a
a stationary Nintendo logo that appears centered on the screen,
accompanied by the usual sound, for ~1.5 seconds.
2021-08-23 08:52:44 +01:00
Luke Usher 5abc150d05 ares v123 released
ares v123 includes significant improvements to the emulation of the ColecoVision,
SG-1000 and the Game Boy/Game Boy Color.

This release brings the compatibility rating for ColecoVision and SG-1000 to
four stars.

This means that we have 100% compatiiblity with both of those libraries, with
the only exception being the few games that require additional peripherals
(driving controllers; touchpads, etc).

The Game Boy improvements are significant, but not quite enough to increase
the compatibility rating at the present time, even so, Many more games are
playable than before.

Finally, a few tweaks to MegaDrive emulation have improved compatibility,
reduced the occurance of video corruption, and improved performance of
the Sega 32X emulation.

**Changelog:**

 * ColecoVision: Initialize ram to 0; fixes a crash in The Heist [Luke Usher]
 * ColecoVision: Disable cartridge rom mirroring; fixes Sammy Lightfoot [invertego]
 * ColecoVision/MSX/SG-1000: Initialize VRAM to 0; fixes various games [invertego]
 * Game Boy: Check window x-coord instead of only y-coord; improves the Acid2 test rom [Luke Usher]
 * Game Boy: Only raise STAT interrupt when display is enabled; fixes Cool Hand [invertego]
 * Game Boy: Implement HALT hardware bug [Meepster99]
 * Game Boy: Fix relationship between LY and STAT interrupt; fixes Elite Soccer, Mouse Trap Hotel, Shantae [invertego]
 * Game Boy: Only trigger STAT interrupts at the start of OAM search; fixes Mortal Kombat 3 [invertego]
 * Game Boy Color: Fix HDMA5 bit.7 reads; improves a significant number of GBC games [invertego]
 * Game Boy Advance: Simulate standard GBA instead of Game Boy Player; fixes GBA Video titles [Luke Usher]
 * Mega Drive: Implement support for Sonic & Knuckles merged roms; fixes Sonic 2K, Sonic 3K [Luke Usher]
 * Mega Drive: Implement support for SRAM/EEPROM when using the SEGA Mapper; fixes Demons of Asteborg [Luke Usher]
 * Mega Drive: Default to 'accuracy' VDP; improves compatibility at the expense of performance [Luke Usher]
 * Mega Drive: Optimize how often the emulator synchronises between components; offsets the cost of the previous change [Luke Usher]
 * Nintendo 64: Maintain Parallel-RDP as a subtree; simplifies compilation [Luke Usher]
 * SG-1000: Implement support for roms greater than 32KB [Luke Usher]
 * SG-1000: Implement support for Taiwan Type-A/Type-B mappers; fixes unlicensed Taiwan releases [Luke Usher]
 * SM83: Fix DAA instruction [Meepster99]
 * TMS9918: Implement multicolor mode; fixes various SG-1000/ColecoVision games [invertego]
 * TMS9918/Master System/MSX: Allow sprites to bleed off top/left screen edges [invertego]
 * ares: Rename lucia to desktop-ui to better represent it's function [Luke Usher]
 * mia: Improve N64 save-type database [jeltaqq]
 * mia: Add support for UNF extension, alongside UNIF and NES [Shideravan]
 * nall: Add macOS deployment target flags; fixes ares on macOS 10.14 [MerryMage]
 * ruby: Give PulseAudio higher priority than ALSA on Linux Systems; ALSA was causing frame-rate issues [Luke Usher]
2021-08-22 14:32:04 +01:00
Luke Usher 91b1ef6837 readme: bump SG-1000 to four stars 2021-08-22 10:56:40 +01:00
invertego c1d8f2d873 gbc: invert HDMA5 bit 7 on read
A refactor in v116r07 replaced the variable dmaCompleted with dmaActive
but failed to update its usage on HDMA5 register reads. Bit 7 should
read 0 if HDMA is active and 1 if completed.

This change will affect many (most?) GBC games.
2021-08-22 09:46:05 +01:00
invertego 4ee6492d18 gb: only trigger STAT at start of OAM search
STAT interrupts triggered by mode 2 (OAM search) should only occur at the
start of the line. Crucially, writes to STAT in the midst of mode 2 that
enable OAM interrupts should not trigger a STAT interrupt. This is
especially important on DMG because of the hardware bug that causes STAT
writes to briefly enable all STAT interrupts. Spurious STAT interrupts
that would not have occurred on real hardware can violate the
assumptions of games that aren't expecting them. Mortal Kombat 3 is one
such game, and it is now playable.
2021-08-22 09:45:30 +01:00
Luke Usher 8bfef958aa ares: remove accidental vscode file 2021-08-21 21:19:37 +01:00
invertego d50e9d2f5d gb: reconcile LY with STAT interrupts
Previously, ares was emulating the coincidence flag in the the STAT
register with M-cycle accuracy but was much less accurate with the
timing of coincidence triggered STAT interrupts or with resetting the LY
register to 0 during vblank. This was breaking a pattern common to a
number of games that goes like this:

1) Write 0 to LYC and set the coincidence interrupt enable bit in STAT
2) In the STAT interrupt handler, read LY and increment by one
3) Loop until LY equals the incremented value

ares would trigger a STAT interrupt during line 153 but LY would
continue to read back as 153 instead of 0. A game incrementing this
value and waiting for it to appear in LY would become stuck in an
infinite loop, as there is no line 154.

This change brings M-cycle accuracy to the LY register and STAT
interrupts using "The Cycle-Accurate Game Boy Docs" by AntonioND as a
reference. It also stops resetting LY on write, as this erroneously
described behavior is not hardware accurate.

The following games should now be playable:
- Elite Soccer
- Mouse Trap Hotel
- Shantae
2021-08-21 12:44:53 +01:00
Luke Usher 8e94e664c5 md: optimize how often we sync the cpu with other components.
This significantly improves performance for md, cd, 32x and cd32x, with
minimal impact on accuracy.

Assuming 3420 cpu cycles per scanline, with a max horizontal resolution
of 320/342:

For MegaDrive/Mega-CD, we can sync every 10 cycles (approx 1 pixel),
since we're using a dot renderer, there is little point in synching more
often than that.

For 32X/CD32X, we sync once every 40 cycles (4 pixels), this provides
enough of a performance boost to make 32X emulation viable for modest
machines, but does not significantly impact compatibiltiy or accuracy;
it's still significantly better than with the scanline renderer we used
previously.
2021-08-20 10:49:46 +01:00
Luke Usher 9c7f114baf md: default to accuracy vdp
This improves compatibility with both MegaDrive and 32X titles at the
expense of performance.

On modest hardware, this still retains full-speed for MegaDrive titles, but 32X and MegaCD may struggle; this will be addressed in a later
commit.
2021-08-20 10:37:26 +01:00
Shideravan 0056a195b1 Adding .unf file support
Fix https://github.com/higan-emu/ares/issues/70
2021-08-20 08:55:00 +01:00
Meepster99 5072497629 Fix cpu.hpp 2021-08-19 20:50:44 +01:00
Meepster99 46675146ff Fixed halt bug
Halt bug fixed, albeit not elegantly
switched spacing to spaces instead of tabs
2021-08-19 20:50:44 +01:00
Luke Usher 65f3f507c8 ruby: shuffle order of optimal drivers
PulseAudio seems to perform better than ALSA when available.
2021-08-19 19:32:40 +01:00
Luke Usher 9f92c633ee md: fix sram/eeprom in banked cartridges
This fixes saving in Demons of Asteborg
2021-08-19 18:57:19 +01:00
Luke Usher faa4f1854a desktop-ui: use 'Game Boy Advance' instead of 'Game Boy Player'
This fixes compatibility with the GBA Video titles.
2021-08-19 11:23:45 +01:00
invertego 7a55003e5f gb: only raise stat interrupts if display enabled
This emulation bug, combined with the intentional emulation of the
hardware bug that causes spurious stat interrupts, was causing stat
interrupts to be raised when the display was disabled.

This stops the GB game Cool Hand from freezing after selecting cribbage.
2021-08-19 10:53:25 +01:00
Luke Usher 8574d0db24 gb: check window x-coord
This dramatically improves the acid-2 tests for DMG and CGB, but they are still imperfect.
2021-08-19 10:49:27 +01:00
Meepster99 c96f34ad02 Fix DAA instruction 2021-08-18 22:12:53 +01:00
Luke Usher 6b6b6027ec sg: fix all known taiwan type-a/type-b games 2021-08-18 21:40:14 +01:00
Luke Usher 0d8933988b sg: add support for Taiwan mappers
Currently only Bomberman Special and Knightmare are supported

The remaining games will be added to the database later.
2021-08-18 16:39:22 +01:00
Luke Usher 7f5be570cd md: fix Sonic & Knuckles
This removes the special casing for Sonic & Knuckles, treating it as a standard rom.

While not strictly correct from an accuracy/real world point of view, all existing
emulators and rom dumps assume the emulator will treat it as a single cart.
2021-08-18 09:27:40 +01:00
invertego 94de2e10d7 ms, v9938: allow sprites to bleed off top/left screen edge
Apply fixes to the Master System VDP and the V9938 (used by MSX 2) that
are analogous to the recent TMS9918 fix.
2021-08-18 09:09:22 +01:00
Luke Usher 862e94b49d ares: point to new website 2021-08-16 15:58:08 +01:00
Luke Usher ad51e37222 sg: support roms > 32k 2021-08-16 15:04:43 +01:00
Luke Usher b3a438b9eb readme: bump ColecoVision to 4 stars
In the most recent builds, all games that do not require additional peripherals are playable
2021-08-16 14:15:55 +01:00
invertego 9d2bd692f5 tms9918: allow sprites to bleed off top/left screen edge
The TMS9918 allows for sprites to, in the words of TI's VDP Programmer's
Guide, "bleed" off the top or left edge of the screen. Depending on the
edge, this is accomplished by different means.

Proper implementation of this behavior is known to affect the following
ColecoVision games:
- Frogger: some sprites should be hidden off the left edge of the screen
- The Heist: the player sprite crosses the left edge of the screen
- Bump 'N' Jump: car sprites cross the top edge of the screen

It looks as though the V9938 and SMS VDP will require similar fixes.
2021-08-16 07:02:32 +01:00
invertego 55f8a38d59 cv, msx, sg: init VRAM to zero on load
Initialize VRAM to zero on load for systems that use the TMS9918/V9938.
On real hardware this memory will be in a partially indeterminate state,
but as far as approximations go, 0x00 is much less problematic than
0xff. A sprite attribute table filled with 0xff is interpreted to have
valid entries for sprites in the top right corner of the screen. If the
pattern data is also filled with 0xff, a white square will be drawn in
the corner. On the other hand, a sprite entry of all 0x00 bytes will be
fully transparent (due to the color byte being zero) and therefore
invisible.

This is most noticeable in games that never get around to fully
initializing VRAM, such as the ColecoVision game Boulder Dash, which has
a permanent square in the corner.

SG-1000 games only seem to exhibit this problem briefly after booting,
and only for certain games, as they eventually get around to
initializing VRAM. Some homebrew is more seriously affected.

MSX compatibility is in too poor a state to test comprehensively, but a
survey of other emulators shows initializing VRAM to zero is the norm.

This change also allows VRAM to carry over across soft resets. This
should be closer to hardware behavior, though in reality it is possible
for some bits to be perturbed.
2021-08-16 07:02:06 +01:00
Luke Usher 3288fcce4e make 'update-subtrees' script executable 2021-08-15 08:36:15 +01:00
invertego 13e23df347 tms9918: implement multicolor mode
This mode is used by the ColecoVision games Cabbage Patch Kids Picture
Show and Smurf Paint 'n' Play Workshop.
2021-08-11 08:52:36 +01:00
invertego 409ea8d7cf cv: disable cart rom mirroring
ColecoVision carts contain up to 4 separate 8 KiB banks, and there is no
mirroring when some banks are absent. The existing mirroring behavior
was causing Sammy Lightfoot to freeze on load.
2021-08-07 09:16:05 +01:00
jeltaqq 7aa95db26c mia: Fix n64 save chip database
First Japanese revisions of Kirby 64 used sram.
2021-08-06 12:04:10 +01:00
Luke Usher c2fcacb331 n64: maintain parallel-rdp as a subtree 2021-08-06 10:52:33 +01:00
Luke Usher 60e135a71d Squashed 'ares/n64/vulkan/parallel-rdp/' content from commit 464ab61fc
git-subtree-dir: ares/n64/vulkan/parallel-rdp
git-subtree-split: 464ab61fce58b27a0e0ed9f0e366aa1113694965
2021-08-06 10:50:32 +01:00
Luke Usher b083b32836 Merge commit '60e135a71d50b583dc2bb2f4371f02c100c6a6ab' as 'ares/n64/vulkan/parallel-rdp' 2021-08-06 10:50:32 +01:00
Merry 7adfece675 nall: Add macOS deployment target flags 2021-08-05 18:45:48 +01:00
Luke Usher 8da4623d39 cv: initialize ram to 0; allows 'The Heist' to reach in-game 2021-08-04 22:31:54 +01:00
Luke Usher 189487a2ca rename lucia -> desktop-ui/ares
To avoid/reduce confusion, the ares gui (lucia) has been renamed  to
desktop-ui.

The executable name/install name/settings directory are named ares.
2021-08-04 21:50:08 +01:00
Luke Usher 82040066b2 ares: bump version number, start next dev cycle 2021-08-04 21:30:06 +01:00
Luke Usher e14b01fdc4 ares v122 released
This release primarily provides improved Neo Geo Pocket/Neo Geo Pocket Color and Sega 32X emulation.

The entire Neo Geo Pocket/Color library is now thought to be playable, with minor graphical issues in four titles.

A small number of SEGA 32X games are now playable, although most still experience graphical and/or audio issues.

Changelog:

ColecoVision: Clear top bit of controller port reads; fixes Defender [invertego]
Neo Geo Pocket: Allow BIOS to handle the boot process [invertego]
Neo Geo Pocket: Copy SNK logo from BIOS during fast boot; fixes Metal Slug: 2nd Mission [invertego]
Neo Geo Pocket: Fix address used to test ram initialization [invertego]
Neo Geo Pocket: Initialize Neo Geo Pocket port 1 to zero; fixes Dynamite Slugger [invertego]
Neo Geo Pocket: Many improvements to 'fast boot' [invertego]
Neo Geo Pocket: Re-enable savint ram to disk on unload [invertego]
Sega 32X: Implement FM/Framebuffer access bit; fixes Spiderman [Luke Usher]
Sega 32X: Implement RV bit [Luke Usher]
Sega 32X: Optimise SH7604 recompiler min-cycles for 32X; fixes Knuckles Choatix & Virtua Fighter [remutro]
Sega 32X: PWM DREQ and timer are different things; fixes PWM audio in many games [Luke Usher]
Sega 32X: Used cached interpreter instead of recompiler [Luke Usher]
TMS9918: Fix sprite size emulation; fixes many graphical issues in ColecoVision/MSX/SG-1000 [invertego]
TMS9918: fix interrupt behavior [invertego]
hiro: Fix browser dialog filters on macOS [Luke Usher]
hiro: Force GTK3 to use X11 backend; fixes a crash under Wayland [thrimbor]
lucia: Disable fast boot by default [Luke Usher]
lucia: Support digital presses from analog inputs [invertego]
mia: Add workaround for underdumped Delta Warp rom [Luke Usher]
mia: Improve Nintendo 64 save chip database; fixes saving in some titles [sp1187]
nall: Enable LTO by default on non-debug builds [Luke Usher]
nall: Speed up recompiler codegen [Luke Usher]
sh2: Allow cores to determine an ideal minimum recompiler block size [Luke Usher]
sh2: Optimised code-gen for the interpreter [Luke Usher]
sh2: Recompiler should invalidate single blocks, not entire pools [Luke Usher]
tlc2900h: Fix immediate mask in BIT #,r; fixes Pocket Tennis [invertego]
z80: Correct the effect of IE on the next instruction; fixes audio drop-out in Neo Geo Pocket games [invertego]
2021-08-02 20:05:24 +01:00
invertego 768d31d4dd tms9918: fix interrupt behavior
The existing implementation was very incorrect. Fortunately, this chip
is well documented and the correct behavior is quite easy to implement.
This fixes most of the remaining ColecoVision bugs that aren't related
to missing peripheral support.

The TMS9918 is also used by the SG-1000 and MSX cores. I don't have a
list of bugs for those platforms, so I couldn't do any targeted testing,
but I booted up a few games and did not see any new issues.
2021-08-02 15:56:48 +01:00
invertego 4304c1c108 TMS9918, V9938, SMS VDP: fix sprite size emulation
Commit 532aafe074 made some improvements
to sprite zoom (magnification) emulation. It also corrected sprite size
emulation in the SMS VDP in what is referred to as Mode 4 by most
sources ("graphics3" in ares). Unfortunately, it erroneously applied the
same changes to the TMS9918 and V9938 as well as the SMS VDP in TMS9918
compatible modes. This caused widespread regressions in ColecoVision,
SG-1000, MSX, and MSX2 emulation.

This commit reverts the changes made outside of SMS VDP Mode 4,
restoring the dimensions of double sized sprites from 8x16 to 16x16.
2021-08-02 09:28:43 +01:00
invertego 0054b5793e cv: clear top bit of controller port reads
I couldn't find any references describing the expected value of the top
bit of controller port reads, but some games require it to be cleared.
Here is an example from Defender when it is waiting a 1/2 button press:

in   a,($FC)    ; read controller 1
cp   $7D        ; compare 1 button
jr   z,$876D
cp   $77        ; compare 2 button
jr   z,$8773

Clearing it fixes input in games that depend on all the undefined bits.
2021-08-02 09:26:50 +01:00
Luke Usher b3fd78e6f4 readme: promote NGP/NGPC to 4 stars.
The only known issues are minor graphical glitches, not harming gameplay.
2021-07-29 14:02:54 +01:00
Luke Usher 8046515c7a mia: oops, whitespace
This is what happens when I use GitHub to make a commit, rather than locally. 
Lesson learned.
2021-07-29 13:37:27 +01:00
Luke Usher 76c4d09118 mia: add workaround for underdumped Delta Warp rom 2021-07-29 13:33:46 +01:00
invertego 4100ae0009 z80: correct the effect of IE on next instruction
The implementation of IE in the Z80 processor was incorrectly causing
nonmaskable interrupts raised before the next instruction to be dropped.
A correct implementation should do two things:
- set IFF1 and IFF2 to 1
- disable maskable interrupts until after the following instruction

This fixes the issue of audio dropping out of Neo Geo Pocket games
seemingly at random.

References:
Z80 CPU User Manual (http://www.zilog.com/docs/z80/UM0080.pdf)
Page 6: "NMI is always recognized at the end of the current instruction,
independent of the status of the interrupt enable flip-flop..."
Page 183: "During the execution of this instruction [EI] and the
following instruction, maskable interrupts are disabled."
2021-07-26 12:04:08 +01:00
Simon Eriksson ab9bc590a2 mia: Improve n64 save chip database
Use three first letters of game ID for mapping.
Add more entries (mostly Japanese games) and fix a few incorrect ones.
Handle some special cases involving different save chips for different
revisions and regions of the same game.

Change manifest generation to use whole four-letter ID and also output
the revision.
2021-07-26 10:02:24 +01:00
remutro 87d97af20a Optimize SH7604 Recompiler Min Cycles for 32X
modified:   ares/md/m32x/sh7604.cpp

Change the cached interpreter's recompiler min_cycles value from 23 to 22.
It's just ever so slightly too agressive.

This addresses problems with the bonus levels in Knuckles Chaotix,
as well as the hang in Virtua Fighter after selecting your character.

This appears to be the optimal value through lots of additional testing.
There were no other problems observed in the 32X library by lowering this
value to 22. Additionally, there were no further gains to be made by going
any lower (all the way to zero) such as correcting the hang at the end of
the match in Brutal: Above the Claw or NBA Jam failing to go in-game. Both
of these currently require using the full interpreter, and not the cached
interpreter enabled by default to correct timing issues.

This fixes 5% of games in the 32X library. :-)
2021-07-26 10:02:08 +01:00
invertego 544759dff7 lucia: support digital presses from analog inputs
lucia maps the N64 C-buttons to the right thumbstick of the virtual pad.
These are analog inputs on the virtual pad, so sampled analog values are
not converted to digital. This means any nonzero value is treated as
button press, which is not ideal when mapped to an analog input device.

This change introduces a helper to convert raw input values to a binary
"pressed" state at time of use, currently only defined for digital and
analog input mappings - for relative and absolute inputs this concept
would not make much sense.
2021-07-26 09:46:51 +01:00
invertego 595f87f3ac ngp: fix address used to test ram initialization
My last change indexed into the ram array by an absolute memory address,
but the array only covers a portion of the address space beginning at
0x4000. This was in fact indexing past the end of the array, but it
appeared to work as long as 1) something was mapped there and 2) that
something was nonzero. It's possible that booting from the shutdown
vector every time doesn't have any negative side effects, but booting
from the hardware reset vector the first time is still the more correct
thing to do from an accuracy perspective.
2021-07-22 18:35:31 +01:00
invertego 815f4b31d8 ngp: allow BIOS to handle the boot process
Neo Geo Pocket is an "always on" system. On first boot, it quickly
enters a low power state via a halt instruction. From there, the user
must press the power button to wake the sytem. At this point, the BIOS
setup is shown, requiring the user to pick a preferred language among
other choices. When power is pressed again, the system returns to a low
power state. This state is maintained by an internal battery should the
external batteries discharge or be removed. The hardware reset entry
point will not execute again until the internal battery fails.

The current design of ares appears to be motivated by a few goals:
- Avoid requiring the user to press the emulated power button
- Avoid showing the BIOS setup more times than necessary
- Enable "fast boot" mode to skip the boot animation

The required power button press is avoided by skipping the first boot
code entirely in CPU::power(). Emulation never begins at the hardware
reset vector, but rather at 0xFF1800, following MAME's lead. This entry
point appears to have been for development purposes only and is not
referenced by the BIOS itself. Crucially, it does not run some
bookkeeping logic that only occurs when entering a low power state
either after a cold boot, in response to a power button press, or after
a software requested shutdown. Skipping this logic can cause the BIOS
setup to be shown on next boot.

The BIOS setup is avoided by simulating the bookkeping done by the BIOS
in the emulator itself. This logic is located in CPU::load(), meaning
that it does not run between system resets. Therefore, resetting a game
can still cause the BIOS setup to be shown. The BIOS setup is also
skipped by fast boot mode.

Fast boot mode bypasses the BIOS entirely on boot, jumping straight to
the cartridge entry point. This means all of the many important side
effects of the boot process must be replicated by CPU::fastBoot().
Currently, it also gives the user no way to select Japanese as a
preferred language.

The existing solutions to these problems fall short of providing a
consistent user experience, tightly couple ares to the internals of the
BIOS rom, and (particularly with fast boot) have been a source of many
bugs. This change removes the existing solutions in favor of ones that
let the BIOS handle the entirety of the boot process.

The new code in this change does the following:
- Begin execution at the hardware reset vector on first boot
- Begin execution at the VECT_SHUTDOWN syscall on subsequent boots
- Simulate a power button press when entering a low power state
- Patch the BIOS to skip the boot animation in fast boot mode

Starting at the hardware reset vector ensures the BIOS setup will be
shown on first boot, affording the user the opportunity to pick a
preferred language. Subsequent boots will begin at the VECT_SHUTDOWN
system call. It may seem counterintuitive, but this allows the BIOS to
perform cleanup that would normally only occur when the user shuts off
the device before switching cartridges. In both of these cases, we can
avoid requiring the user to press the emulated power button by
simulating a button press on their behalf. It's a low tech solution to
be sure, but a reliable one.

Finally, the implementation of fast boot mode is replaced with a single
byte patch to the BIOS to immediately return from the routine that plays
the boot animation.
2021-07-21 13:00:05 +01:00
Luke Usher 657b0c0f5d sh2: invalidate single blocks, not entire pools 2021-07-16 22:09:18 +01:00
Luke Usher 934202c244 sh2: further optimize code gen for the cached interpreter 2021-07-16 22:08:58 +01:00
Luke Usher 99ef67b4a0 sh2: slight speed up 'call' generation 2021-07-16 22:00:25 +01:00
Luke Usher 1e4683fbac nall:: speed up recompiler codegen
agressive inlining allows for a slight performance increase when
emitting code.
2021-07-16 21:01:49 +01:00
Luke Usher 27d0826e30 sh2: use cached interpreter instead of recompiler
This improves compatibility as the full recompiler currently has some game
breaking issues, but is faster than using a pure interpreter solution
2021-07-16 20:53:20 +01:00
Luke Usher 5168ee4089 32x: implement 'RV' bit
The SH2 should stall when accessing rom while RV is set.
2021-07-15 18:17:54 +01:00
Luke Usher a9f2a301b4 32x: implement FM/framebufferAccess bit
When this bit is set to 0, any framebuffer or VDP access from the sh2 has to be ignored and when this bit is set to 1, any framebuffer or VDP access from the m68k should be ignored.

This fixes the rendering issues in Spiderman, likely others too.
2021-07-14 14:20:38 +01:00
Luke Usher 53dedb9a84 lucia: disable "fast boot" by default
The fastboot option is a nice to have, but it has potential to introduce serious bugs/glitches into emulation, as seen with Neo Geo Pocket, so it is safer to default this option to disabled.
2021-07-14 10:34:02 +01:00
invertego b73fb828c5 ngp: copy SNK logo from BIOS during fast boot
The game Metal Slug - 2nd Mission compares a region of character memory
to a copy of the SNK logo in the game rom. Normally this memory is
initialized for the boot animation played by the BIOS. If the logo isn't
an exact match, the game starts but you are unable to fire any weapons.

Conceptually, this is the reverse of what the Game Boy does on boot.
There, the boot rom validates a Nintendo logo on the cartridge.

Since we already have the BIOS loaded, we can copy the logo from there
during a fast boot, though some unpacking is required.
2021-07-14 09:30:09 +01:00
invertego 5f96077613 ngp: re-enable saving ram to disk on unload
This code was commented out in commit
4e82321182 which otherwise only affected
TLCS900/H timing. I believe this was left in by mistake. Uncommenting
this code restores the ability to persist BIOS settings across play
sessions.
2021-07-14 09:19:27 +01:00
Luke Usher a284722486 hiro: fix browser dialog filters on macOS 2021-07-12 16:18:49 +01:00
Luke Usher cb9f94ae34 nall: enable lto by default on non-debug builds 2021-07-12 10:28:48 +01:00
Luke Usher 10856348a3 nall: don't pass unsupported lto options to clang 2021-07-12 10:22:43 +01:00
Luke Usher 7b5026313e ci: include shaders + database in macOS builds 2021-07-12 10:22:16 +01:00
invertego 1cccbb67da Initialize Neo Geo Pocket port 1 to zero
In the game Dynamite Slugger, when your batter strikes out it loads a
16-bit word from 0x0000 and resets the game if anything but zero comes
back. The second byte, at address 0x0001, is mapped to internal port 1,
and currently almost all port values are initialized to 1 at power on.

In a 2019 nesdev post [1], Near stated that port emulation was incomplete
and likely incorrect. Without hardware tests, I'd rather not touch this
code more than necessary, but at the very least it seems more correct to
initialize the latched value in port 1 to zero.

There is a chance that the null dereference in Dynamite Slugger is
itself the result of an emulation bug, but all I have to compare against
is MAME, and the game behaves the same there. I believe this is decent
evidence that we are seeing a real game bug and that reading back zero
is what would have occurred on actual hardware.

[1] http://forums.nesdev.com/viewtopic.php?f=23&t=18579#p236069
"I added ports 1, 2, A, and B. Although ports 1 (d8-d15) and 2 (a16-a23)
are ... strange. They're likely emulated very wrong. I don't even
understand how one can change the direction of the data bus. I'm ...
suspecting that ports have their own latch values, but the manual isn't
very clear on this."
2021-07-11 19:17:20 +01:00
invertego 8b09014c67 Fixes for "Fast Boot" option for Neo Geo Pocket (Color)
Perform more initialization to match the side effects of booting from
the BIOS.

1) Initialize XIX register. Puyo Pop World relies on this (likely a game
   bug).
2) Initialize interrupt vector table. SNK Gals' Fighters and the Pocket
   Casino Series games rely on this.
3) Initialize interrupt request levels used by the VECT_INTLVSET system
   call. The Pocket Casino Series games rely on this.
2021-07-11 19:14:21 +01:00
Stefan Schmidt 19171c2723 hiro: Force Gtk3 to use X11 backend 2021-07-11 19:12:22 +01:00
Luke Usher e130f0297e 32x: reduce minimum recompiler block size
Fixes a hang in Virtua Racing Deluxe
2021-07-11 12:51:09 +01:00
Luke Usher 735f3ec902 32x: pwm dreq and timer are two different things
This fixes PWM audio playback in most titles.
2021-07-11 12:09:13 +01:00
Luke Usher 109ebc4683 32x: use min block size of 46 for sh2 rec 2021-07-10 20:34:59 +01:00
Luke Usher 3da4e20905 sh2: allow cores to set min recompiler block size 2021-07-10 20:34:42 +01:00
Luke Usher 963086edb5 mia: use database for msx 2021-07-10 00:39:11 +01:00
Luke Usher b0a0640089 ci: include shaders/database in Windows builds 2021-07-10 00:38:58 +01:00
Luke Usher 2e648ac845 restore genius, a .bml database editor 2021-07-09 17:55:41 +01:00
invertego 77110f15a3 tlcs900h: Fix immediate mask in BIT #,r
The BIT (imm, reg) instruction uses the low 4 bits of its immediate operand even
when the register operand is only 8 bits wide. When the register is 8 bits and
the immediate value is between 8 and 15, ZF will be always be set. ares was
erroneously using only the bottom 3 immediate bits in this case (so 15 would
behave the same as 7).

With this fix, sprites now render correctly in the Neo Geo Pocket game Pocket
Tennis.

This bug was discovered by comparing against an instruction trace from MAME.
This change is the functional equivalent of commit
57e42cda31430c75566403c5f27ec290dc123da3 in the MAME git repo.
2021-07-07 09:34:45 +01:00
Luke Usher 5c697600f7 ares: bump version to v121a 2021-07-06 11:14:47 +01:00
Tim Allen bf3b824a71 Fix building mia on Linux.
Although mia doesn't use threads itself, it includes `ares/ares.hpp` and ares
*does* use threads, so we need to build with `-pthread` in order to link
successfully.
2021-07-06 10:59:14 +01:00
Luke Usher cedfd160c4 readme: clarify nightly builds 2021-07-06 09:57:24 +01:00
Luke Usher 9ac22b34fa ci: disable Linux release publishing
We should still verify Linux builds are compiling, but Linux users should self-compile or use distro-specific packages.
2021-07-06 09:56:41 +01:00
Luke Usher fad4ef8908 docs: add README.md 2021-07-06 09:46:04 +01:00
Luke Usher cb4a79e8c1 ci: introduce ci + 'nightlies' 2021-07-06 01:54:06 +01:00
Luke Usher 8cca04113d hiro: fix table-view compilation on macOS 2021-07-06 01:20:53 +01:00
Luke Usher e4789472e3 sfc: default to 64KB VRAM when using ppu-performance 2021-07-06 01:16:42 +01:00
Luke Usher 11c818591b ares: fix the build with gcc 2021-07-06 01:16:17 +01:00
Luke Usher ea1eef8d22 add license (ISC) 2021-07-05 15:15:37 +01:00
Near 4428bb70e9 Update to ares v121 release.
I've released ares v121. Because it is not fully complete or stable, it is
released as source code only.

The license is now once again ISC instead of CC-BY-NC-ND.

Master System, WonderSwan, and WonderSwan Color compatibility have increased to
100%, with no remaining known bugs.

The Neo Geo Pocket is very close to 100% now with one issue remaining, where
sound effects sometimes mute in games.

Nintendo 64 compatibility has increased to above 80% thanks to corrections to
controller pak handling.

Several NES and Mega CD fixes have been added. EEPROM support has been added for
the Mega Drive.

Memory cards and paks now pre-format themselves, so you don't have to do so in-
game or in BIOS settings.

The new Neo Geo emulation is slowly improving, but it's still very preliminary
with only seven games fully playable so far.

The Nintendo 64 SM5K and PlayStation HC05 processor cores have been emulated,
but not connected yet due to a lack of information.

Added mouse input support and connected peripheral selection to the GUI, so mice
and light gun games can now be used.

There is now per-system input mapping overlays, so you can map controllers based
on the original system button names.

And lastly as promised, the SNES core has gained optional widescreen support.

Changelog (since v120):

  - Nintendo 64: added Windows ABI support to dynamic recompilers
  - PlayStation: added Windows ABI support to dynamic recompiler
  - Nintendo 64: temporarily disabled 64-bit addressing mode due to issues
  - Nintendo 64: corrected analog stick ranges and emulated octagonal
    boundaries
  - Nintendo 64: code cleanups around memory access functions
  - Nintendo 64: started to implement RDRAM broadcasting (very incomplete
    still)
  - Mega Drive: improved VDP scanline renderer timing
  - M68K: corrected clipping bug in ADD,CMP,SUB instructions
  - Nintendo 64: improved SI scanning of PIF RAM and emulated more flags
  - Nintendo 64: added very accurate controller pak initialization code
  - Nintendo 64: improved controller analog stick approximations [MerryMage]
  - Nintendo 64: added priority queue to delay SI and PI DMA transfers
  - Master System: added bit-perfect YM2413 instrument patch sets
  - Mega Drive: fixed a bug with LINEA and LINEF instructions (should not
    decrement PC)
  - Mega Drive: added EEPROM emulation
  - mia: added Mega Drive and Mega 32X EEPROM database entries
  - nall: added priority_queue::remove(T) support
  - Nintendo 64: reverted 64-bit TLB (not actually present)
  - Neo Geo: initial implementation
  - Neo Geo: many emulation improvements
  - nall: add workaround for compilers that lack __has_builtin
  - Nintendo 64: ignore A15 on controller pak reads and writes
  - Master System: implemented Codemasters, Korea, MSX, Janggun mappers
  - Master System: improved Sega mapper emulation
  - Master System: added initial emulation of port $3e
  - Master System: added support to load BIOSes
  - Master System: initialize stack pointer to 0xfffd when no BIOS loaded
    [Luke Usher]
  - Game Boy Advance: emulated BIOS swap register [MerryMage]
  - Mega Drive: cancel pending IRQs when they are disabled [Jonas Quinn]
  - Mega Drive: fixed handling of VDP field flag [Jonas Quinn]
  - Mega Drive: mask upper bit of VDP sprite Y value when in progressive
    display mode [Jonas Quinn]
  - X24C01, M24Cxx: improve emulation of EEPROM command sequences
  - Famicom: added database entries for Jajamaru Gekimaden and Mazase Top
    Pro PRG-RAM
  - M24Cx: rewrote emulation to be more complete; though still not working
    for Cxx/Cxxx sizes
  - Nintendo 64: try stopping SI polling on recv=0xfe
  - Mega Drive: improved EEPROM emulation
  - Nintendo 64: fixed CPU SCC counter rate [simer]
  - Nintendo 64: added initial emulation of the SM5K processor (not connected
    yet)
  - lucia: update frame rate from the main thread to prevent a race condition
    with GTK
  - Master System: emulated sprite zoom and fifth-sprite status flag
  - Master System: corrected VDP background emulation for mode 4 [fixes
    Codemasters games]
  - Master System: latch VDP background nametable address and scroll registers
    [fixes Desert Speedtrap]
  - Master System: mask CRAM reads to 6-bit in Master System mode [fixes Mercs]
  - Master System: refactored VDP code
  - Z80: swapped IND/INI to post-decrement B, and OUTD/OUTI to pre-decrement B
  - lucia: fixed a crash when loading Game Gear games due to stubbing out
    the BIOS
  - Nintendo 64: fixed cartridge flash memory support
  - Master System: VDP line coincidence should be initialized to $ff [fixes
    Shadow Dancer]
  - Master System: VDP sprite overflow index defaults to $1f, not $00 [fixes
    PGA Tour Golf]
  - SN76489: corrected port latching behavior and noise volume writes [fixes
    Micro Machines]
  - TMS9918: greatly refactored code
  - V9938: greatly refactored code
  - Z80: disassembler fixes
  - lucia: corrected mapping of Master System pause button [fixes Baku
    Baku Panic]
  - nall: disable -Wstringop-overflow for GCC due to compiler heuristics error
  - M68HC05: initial core implementation added
  - M68000: renamed core from M68K
  - Super Famicom: clearing $4200.d0 stops active joypad polling for the rest
    of the frame [Jonas Quinn]
  - Master System: don't evaluate sprites past active display area [fixes
    Rescue Mission]
  - Mega Drive: don't acknowledge VDP IRQs until the CPU triggers them [fixes
    Mega Lo Mania]
  - lucia: begin refactoring input mapping to allow per-system mappings and
    multiple controller types
  - Game Gear: set CPU::in() unmapped return value to MDR; fixes RoboCop 3
    [Jonas Quinn]
  - WonderSwan Color: do not mask screen tilemap base address; fixes Sorobang
    [FPGAzumSpass]
  - Mega Drive: set supervisor mode and clear trace mode for all exceptions;
    fixes Gouketsuji Ichizoku [Jonas Quinn]
  - Mega CD: format BRAM instead of leaving it uninitialized; fixes Popful Mail
    (US)
  - WonderSwan: add patch for Meitantei Conan: Nishi no Meitantei Saidai
    no Kiki!
  - Game Boy: add MBC1#M mapper database entries; fixes Bomber Man Collection,
    Genjin Collection, Momotarou Collection, and Mortal Kombat I & II
  - Neo Geo Pocket: $8118 background register exists even in the K1GE GPU;
    fixes Samurai Shodown
  - Neo Geo Pocket Color: return 0xFF acknowledge byte after flash erase
    command; fixes Puzzle Link 2 and Memories off: Pure
  - Neo Geo Pocket: clear watchdog timer counter on trigger to prevent
    infinite triggering; fixes Neo Baccarat, Neo Cherry Master Color, and
    Neo Mystery Bonus
  - TLCS900H: do not allow interrupts to run between CPDR, LDIR, LDDR
    instructions; fixes Fantastic Night Dreams Cotton
  - Neo Geo Pocket: add all remaining missing I/O registers (not emulated,
    but registers are readable and writable now)
  - Neo Geo Pocket Color: above changes also fixed in-game audio in Crush
    Roller and Dynamite Slugger
  - Mega CD: added 1M mode WRAM swap request flag; fxies AX-101, Earnest Evans,
    and Might & Magic III [TascoDLX]
  - lucia: added input mapping overlays for all remaining systems
  - lucia: added two-player support to all remaining systems
  - TLCS900H: refactored instruction decoder and disassembler using range-case
  - TLCS900H: improved emulation of (PC+d16) addressing mode (LDAR)
  - TMS9918, V9938, SMS VDP: corrected sprite zoom emulation [Jonas Quinn]
  - Neo Geo Pocket: added new debugging modules (flash ROM, I/O accesses,
    system calls)
  - Neo Geo Pocket: improved CPU interrupt logger (prints name of interrupt
    now)
  - Neo Geo Pocket: fixed a critical issue with interrupt priority levels;
    fixes many games
  - Neo Geo Pocket: added stubs for all remaining TMP95C061F I/O registers
    (not emulated yet)
  - Neo Geo Pocket: set CPU I/O port $b1.d2 reads to return 1 (fixes SNK
    Gals' Fighter)
  - Neo Geo Pocket: added stubs for undocumented CPU I/O ports $b6 and $b7
  - Super Famicom: PPU code restructuring
  - Super Famicom: added widescreen (16:9 and 21:9) support to the scanline
    renderer
  - WonderSwan: refactored I/O handlers to use switch/case instead of if tests
  - WonderSwan: rewrote PPU renderer to modularize each component (screen1,
    screen2, sprite, dac, etc)
  - WonderSwan: corrected timers to count down instead of up; fixes timing
    in many games [FPGAzumSpass]
  - WonderSwan: improved screen two window emulation [FPGAzumSpass]
  - hiro: TableView::onContext() is now TableView::onContext(TableViewCell)
    (not supported for Cocoa or Qt yet)
  - lucia: merged code to handle input assignment overlays and controller
    polling for each emulation core
  - lucia: added virtual mouse emulation and added mouse capture support
  - lucia: added support to change devices connected to controller ports
  - Neo Geo Pocket: added database workaround for underdumped Prize Game:
    PP-AA01 Pusher Program (Japan)
  - Neo Geo Pocket: fixed fast boot mode for Neo Cherry Pocket
  - nall/range: added new within() templates
  - V30MZ: emulated instruction prefetch
  - V30MZ: greatly improved instruction timings (thanks to FPGAzumSpass'
    test ROM)
  - WonderSwan: disabling an interrupt source does clear its pending status
    (fixes Digimon Tamers)
  - TLCS900H: improved prefetch handling and instruction timing (still
    imperfect)
  - TLCS900H: improved timing further (still imperfect)
2021-06-26 23:49:00 +00:00
Near 4e82321182 Update to ares v120r18 release.
Just slight 'improvements' to TLCS900/H timing.
2021-06-23 14:58:00 +00:00
Near b2fc626854 Update to ares v120r17 release.
- WonderSwan: disabling an interrupt source does clear its pending status
    (fixes Digimon Tamers)
  - TLCS900H: improved prefetch handling and instruction timing (still
    imperfect)
2021-06-20 21:35:00 +00:00
Near 189147fc31 Update to ares v120r16 release.
This gets a 100% pass on FPGAzumSpass' WonderSwan instruction timing tests, and
emulates CPU prefetch as well, but it seems to make games less stable rather
than more =(
2021-06-16 08:01:00 +00:00
Near 532aafe074 Update to ares v120r15 release.
- TLCS900H: refactored instruction decoder and disassembler using range-case
  - TLCS900H: improved emulation of (PC+d16) addressing mode (LDAR)
  - TMS9918, V9938, SMS VDP: corrected sprite zoom emulation [Jonas Quinn]
  - Neo Geo Pocket: added new debugging modules (flash ROM, I/O accesses,
    system calls)
  - Neo Geo Pocket: improved CPU interrupt logger (prints name of interrupt
    now)
  - Neo Geo Pocket: fixed a critical issue with interrupt priority levels;
    fixes many games
  - Neo Geo Pocket: added stubs for all remaining TMP95C061F I/O registers
    (not emulated yet)
  - Neo Geo Pocket: set CPU I/O port $b1.d2 reads to return 1 (fixes SNK
    Gals' Fighter)
  - Neo Geo Pocket: added stubs for undocumented CPU I/O ports $b6 and $b7
  - Super Famicom: PPU code restructuring
  - Super Famicom: added widescreen (16:9 and 21:9) support to the scanline
    renderer
  - WonderSwan: refactored I/O handlers to use switch/case instead of if tests
  - WonderSwan: rewrote PPU renderer to modularize each component (screen1,
    screen2, sprite, dac, etc)
  - WonderSwan: corrected timers to count down instead of up; fixes timing
    in many games [FPGAzumSpass]
  - WonderSwan: improved screen two window emulation [FPGAzumSpass]
  - hiro: TableView::onContext() is now TableView::onContext(TableViewCell)
    (not supported for Cocoa or Qt yet)
  - lucia: merged code to handle input assignment overlays and controller
    polling for each emulation core
  - lucia: added virtual mouse emulation and added mouse capture support
  - lucia: added support to change devices connected to controller ports
  - Neo Geo Pocket: added database workaround for underdumped Prize Game:
    PP-AA01 Pusher Program (Japan)
  - Neo Geo Pocket: fixed fast boot mode for Neo Cherry Pocket
  - nall/range: added new within() templates
2021-06-14 08:07:00 +00:00
Near eefd470752 Update to ares v120r14 release.
- Game Gear: set CPU::in() unmapped return value to MDR; fixes RoboCop 3
    [Jonas Quinn]
  - WonderSwan Color: do not mask screen tilemap base address; fixes Sorobang
    [FPGAzumSpass]
  - Mega Drive: set supervisor mode and clear trace mode for all exceptions;
    fixes Gouketsuji Ichizoku [Jonas Quinn]
  - Mega CD: format BRAM instead of leaving it uninitialized; fixes Popful Mail
    (US)
  - WonderSwan: add patch for Meitantei Conan: Nishi no Meitantei Saidai
    no Kiki!
  - Game Boy: add MBC1#M mapper database entries; fixes Bomber Man Collection,
    Genjin Collection, Momotarou Collection, and Mortal Kombat I & II
  - Neo Geo Pocket: $8118 background register exists even in the K1GE GPU;
    fixes Samurai Shodown
  - Neo Geo Pocket Color: return 0xFF acknowledge byte after flash erase
    command; fixes Puzzle Link 2 and Memories off: Pure
  - Neo Geo Pocket: clear watchdog timer counter on trigger to prevent
    infinite triggering; fixes Neo Baccarat, Neo Cherry Master Color, and
    Neo Mystery Bonus
  - TLCS900H: do not allow interrupts to run between CPDR, LDIR, LDDR
    instructions; fixes Fantastic Night Dreams Cotton
  - Neo Geo Pocket: add all remaining missing I/O registers (not emulated,
    but registers are readable and writable now)
  - Neo Geo Pocket Color: above changes also fixed in-game audio in Crush
    Roller and Dynamite Slugger
  - Mega CD: added 1M mode WRAM swap request flag; fxies AX-101, Earnest Evans,
    and Might & Magic III [TascoDLX]
  - Nintendo 64: added ISViewer support
  - lucia: added input mapping overlays for all remaining systems
  - lucia: added two-player support to all remaining systems
2021-06-07 09:45:00 +00:00
Near 9d6d3612a7 Update to ares v120r13 release.
- Game Gear: fix inputs
  - Master System: don't evaluate sprites past active display area [fixes
    Rescue Mission]
  - Mega Drive: don't acknowledge VDP IRQs until the CPU triggers them [fixes
    Mega Lo Mania]
  - lucia: begin refactoring input mapping to allow per-system mappings and
    multiple controller types
2021-06-04 09:21:00 +00:00
Near e867dbd380 Update to ares v120r12 release.
- M68HC05: initial core implementation added
  - M68000: renamed core from M68K
  - Super Famicom: clearing $4200.d0 stops active joypad polling for the rest
    of the frame [Jonas Quinn]
2021-06-03 03:21:00 +00:00
Near cf25b04854 Update to ares v120r11 release.
- Nintendo 64: fixed cartridge flash memory support
  - Master System: VDP line coincidence should be initialized to $ff [fixes
    Shadow Dancer]
  - Master System: VDP sprite overflow index defaults to $1f, not $00 [fixes
    PGA Tour Golf]
  - SN76489: corrected port latching behavior and noise volume writes [fixes
    Micro Machines]
  - TMS9918: greatly refactored code
  - V9938: greatly refactored code
  - Z80: disassembler fixes
  - lucia: corrected mapping of Master System pause button [fixes Baku
    Baku Panic]
  - nall: disable -Wstringop-overflow for GCC due to compiler heuristics error
2021-06-01 00:24:00 +00:00
Near 02028d8fe2 Update to ares v120r10 release.
- Master System: emulated sprite zoom and fifth-sprite status flag
  - Master System: corrected VDP background emulation for mode 4 [fixes
    Codemasters games]
  - Master System: latch VDP background nametable address and scroll registers
    [fixes Desert Speedtrap]
  - Master System: mask CRAM reads to 6-bit in Master System mode [fixes Mercs]
  - Master System: refactored VDP code
  - Z80: swapped IND/INI to post-decrement B, and OUTD/OUTI to pre-decrement B
  - lucia: fixed a crash when loading Game Gear games due to stubbing out
    the BIOS
2021-05-31 05:15:00 +00:00
Near 47c2fca103 Update to ares v120r09 release.
- Mega Drive: improved EEPROM emulation
  - Nintendo 64: fixed CPU SCC counter rate [simer]
  - Nintendo 64: added initial emulation of the SM5K processor (not connected
    yet)
  - lucia: update frame rate from the main thread to prevent a race condition
    with GTK
2021-05-29 23:42:00 +00:00
Near b8dfb68f6b Update to ares v120r08 release.
- Famicom: added database entries for Jajamaru Gekimaden and Mazase Top
    Pro PRG-RAM
  - M24Cx: rewrote emulation to be more complete; though still not working
    for Cxx/Cxxx sizes
  - Nintendo 64: try stopping SI polling on recv=0xfe
2021-05-27 00:12:00 +00:00
Near 960d8a8dcb Update to ares v120r07 release.
- Nintendo 64: ignore A15 on controller pak reads and writes
  - Master System: implemented Codemasters, Korea, MSX, Janggun mappers
  - Master System: improved Sega mapper emulation
  - Master System: added initial emulation of port $3e
  - Master System: added support to load BIOSes
  - Master System: initialize stack pointer to 0xfffd when no BIOS loaded
    [Luke Usher]
  - Game Boy Advance: emulated BIOS swap register [MerryMage]
  - Mega Drive: cancel pending IRQs when they are disabled [Jonas Quinn]
  - Mega Drive: fixed handling of VDP field flag [Jonas Quinn]
  - Mega Drive: mask upper bit of VDP sprite Y value when in progressive
    display mode [Jonas Quinn]
  - X24C01, M24Cxx: improve emulation of EEPROM command sequences
2021-05-24 16:24:00 +00:00
Near ca273d320e Update to ares v120r06 release.
Metal Slug should be fully playable in AES mode now, but still no sound.
2021-05-21 16:58:00 +00:00
Near 54159cf95e Update to ares v120r05 release.
- Nintendo 64: reverted 64-bit TLB (not actually present)
  - Neo Geo: initial implementation
2021-05-19 01:23:00 +00:00
Near 3cebf21a5e Update to ares 20210516a release.
This one is an experiment to ignore A15 on memory pak reads+writes. If possible,
I'd like to know if any games with controller pak issues start working with this
change that didn't before ^-^;
2021-05-16 17:05:00 +00:00
Near 28a57b9347 Update to ares v120r04 release.
- Mega Drive: fixed a bug with LINEA and LINEF instructions (should not
    decrement PC)
  - Mega Drive: added EEPROM emulation
  - mia: added Mega Drive and Mega 32X EEPROM database entries
  - nall: added priority_queue::remove(T) support
2021-05-16 16:49:00 +00:00
Near 64857906b3 Update to ares 20210516 release.
Fixes *Super Bubble Bobble (Taiwan) (En) (Unl)* for the Mega Drive3
2021-05-16 06:02:00 +00:00
Near c5583ade47 Update to ares 20210513 release.
This doesn't justify a new WIP release yet, but it changes the PI DMA delay
timing which seems to make Aidyn Chronicles work again, so let's see how it
does.
2021-05-13 09:09:00 +00:00
Near 8c7bad148c Update to ares v120r03 release.
- Nintendo 64: improved SI scanning of PIF RAM and emulated more flags
  - Nintendo 64: added very accurate controller pak initialization code
  - Nintendo 64: improved controller analog stick approximations [MerryMage]
  - Nintendo 64: added priority queue to delay SI and PI DMA transfers
  - Master System: added bit-perfect YM2413 instrument patch sets
2021-05-12 10:37:00 +00:00
Near a290c96899 Update to ares v120r02 release.
This fixes a major issue with the 68K ADD,CMP,SUB instructions not clipping, and
improves the VDP scanline renderer timing somewhat.

This fixes Alien Solder, and I also moved the DMA run below the FIFO/prefetch to
fix Comix Zone's graphics. It regresses several Titan Overdrive 2 screens, but
oh well.

I'm trying to track down a bug in Popful Mail (US) where the CPU crashes right
after the title screen. It seems like the CPU is getting stuck in a loop that
keeps calling the same function, so the stack keeps decrementing until it ends
up overwriting the currently executing code with a bad instruction.

Without an I/O tracer it's really difficult to try and understand what the CPU
is stuck waiting on and looping on. I'll have to add an I/O tracer to the Mega
CD registers.

The CPU fixes sadly didn't improve anything in the 32X space. Metal Head gets in
a loop until it overwrites the stack frame return address with 0x1fff1fff that
causes a return to an unaligned address that crashes the SH2 master.

After Burner Complete doesn't boot at all. Amazing Spider-Man still has screwed
up graphics priority ordering for the 32X VDP.

Space Harrier still shows a bunch of junk lines at the top and bottom of the
screen.

The scanline VDP can now run Lemmings 1&2, Alien Soldier, etc. But it still does
horrifically bad with Titan Overdrive, especially 2.
2021-05-10 13:31:00 +00:00
Near 034468c384 Update to ares v120r01 release.
I started to implement N64 RDRAM broadcasting with this WIP, but it's only about
1% complete.
2021-05-07 05:33:00 +00:00
Near 340f48d029 Update to ares v120 release.
This release provides improved Nintendo 64 and Mega Drive emulation, plus some
emulation speedups and new features like keyboard-mapping for all Nintendo 64
controls.

The infamous Titan Overdrive demos now run with the exception of one glitched
screen each, but you will need to compile with profile=accuracy to enable the
required cycle-based VDP renderer for this to work. I'll try in the future to
support as much of it as I can with the default scanline renderer as well.

Changelog (since v119):

  - SH2: added support for Windows ABI to the recompiler
  - SH2: MAC must increment R[n] before reading from R[m]; fixes Virtua
    Fighter and Toughman Contest
  - SH2: fixed dynarec MOV @Rm+,Rn to not increment when Rm==Rn
  - SH2: fixed dynarec TST instruction
  - SH2: improved dynarec accuracy by breaking blocks on delay slot branches
  - SH2: improved dynarec accuracy by decreasing the underclocking amount
  - Mega Drive: implemented undocumented VSRAM and CRAM DMA fill
  - Mega Drive: simplified scanline VDP renderer; fixes TMNT: Tournament
    Fighters graphics
  - Mega Drive: improved region detection; correctly identifies Alien Soldier
    region now
  - Mega CD: fixed crash on game load
  - Super Famicom: fixed direct color mode; fixes Secret of Mana world map
  - WonderSwan Color: fixed initial state for new EEPROMs plus EEPROM size;
    fixes missing sound
  - lucia: fixed saving RAM files when a manual save path was specified
  - ruby: fixed library dependency detection for Arch Linux and other
    distributions
  - SH2: additional correction for dynarec MOV @Rm+,Rn instructions
  - hiro/GTK3: added CSS stylesheet overrides to improve appearance [Screwtape]
  - N64: VMRG was not clearing VCO in C++ version [Rasky]
  - N64: fixed "ctc2" in the disassembler
  - Mega Drive: VDP address/command bits are set even for non-register writes
    [Eke]
  - Mega Drive: implemented VDP FIFO with approximated timings
  - Mega Drive: implemented CPU bus arbitrator
  - N64: fixed RSP vector unit register values in the disassembler
  - Mega Drive: implemented proper VDP FIFO timings for both reads and writes
    (hopefully)
  - Mega Drive: enabled external and RAM refresh timing
  - Mega Drive: added (Mega Drive | Mega 32X) + Mega CD mode 1 emulation
  - Mega Drive: refactored dot-based VDP renderer
  - ares: added Thread::restart() function to reset a thread without resetting
    its clock
  - Mega Drive: improved DRAM refresh timings
  - Mega Drive: added VDP I/O logger
  - Mega Drive: fixed VDP counter emulation (still inaccurate)
  - Mega Drive: improved VDP DMA and FIFO emulation
  - Nintendo 64: report 64DD as missing for now; fixes F-Zero X
  - Nintendo 64: improved TLB emulation; fixes Conker's Bad Fur Day
  - Nintendo 64: PI DMA from flash always reads data, never the status;
    fixes Paper Mario
  - Mega Drive: improved VDP FIFO emulation
  - Mega Drive: improved VDP dot-renderer
  - nall/bit-range: fixed bug with bit indexes >= 32
  - Mega Drive: fixed VDP read buffer indexing for VSRAM and CRAM
  - Mega Drive: fixed 68K to VDP DMA so that it instantly freezes the CPU
  - Mega Drive: emulated VDP left window hardware glitch where hscroll&15!=0
  - Mega Drive: improved CPU interrupt handling
  - Mega Drive: added APU bus mirrorings
  - Mega Drive: emulated the VDP debug register
  - Mega Drive: fixed VDP VRAM DMA copy
  - Mega Drive: improved 128KB VRAM mode support
  - Mega Drive: mask sprite attribute table address in H40 mode [Sik]
  - Mega Drive: VDP timing improvements
  - Nintendo 64: improved EEPROM support; fixes Perfect Dark
  - Nintendo 64: improved VI interrupt support; fixes Star Wars: Rogue Squadron
    title screen [nodev]
  - Nintendo 64: emulated CIC-NUS-6105 copy protection; fixes Banjo-Tooie
    [XScale]
  - Nintendo 64: added serrate (interlace) support and fixed bug when
    supersampling in serrate mode
  - Nintendo 64: emulated CPU instruction cache
  - Nintendo 64: emulated CPU data cache
  - Nintendo 64: emulated CPU CACHE instruction
  - Nintendo 64: fixed CPU TLB bug; fixes GoldenEye
  - Nintendo 64: began adapting CPU cached interpreter into a dynamic
    recompiler
  - Nintendo 64: began adapting RSP cached interpreter into a dynamic
    recompiler
  - Nintendo 64: added 64-bit addressing and TLB supporting
  - Nintendo 64: added endian support to [LS][WD][LR] instructions
  - Nintendo 64: improved dynamic recompiler
  - PlayStation: began adapting CPU cached interpreter into a dynamic
    recompiler
  - lucia: allow mapping analog axes separately (allows mapping sticks to
    the keyboard)
  - Nintendo 64: corrected analog stick ranges
  - Nintendo 64: emulate the analog stick as an octagon rather than a circle
    [YetAnotherEmuDev]

[This is actually the second release of v120; the change since the first release
is the N64 analog stick ranges and the octagon gate. -Ed.]
2021-05-06 02:14:00 +00:00
Near 1b574d0bb5 Update to ares v119r16 release.
- Mega Drive: VDP scanline renderer compiles once more
  - Nintendo 64: improved dynamic recompiler
  - PlayStation: began adapting CPU cached interpreter into a dynamic
    recompiler
  - lucia: allow mapping analog axes separately (allows mapping sticks to
    the keyboard)

All that's left now is fixing the call() function in the N64/PS1 to support >3
(4) arguments on Windows and we can release v120
2021-05-05 03:10:00 +00:00
Near 25771ba202 Update to ares v119r15 release.
- Nintendo 64: began adapting CPU cached interpreter into a dynamic
    recompiler
  - Nintendo 64: began adapting RSP cached interpreter into a dynamic
    recompiler
  - Nintendo 64: added 64-bit addressing and TLB supporting
  - Nintendo 64: added endian support to [LS][WD][LR] instructions

I could really use a hand with my CPU dynarec, n64/cpu/recompiler.cpp line 1335.

When calling an FPU instruction without SCC coprocessor 1 enabled, it throws an
exception.

If I call the exception function, the emulator crashes hard and I don't
understand why at all.

The stack is aligned, but it seems if I modify rbx/rbp/r13 as I do with the
RSP+SH2 just fine, it seems to die. Yet even if I make that code restore
rbx/rbp/r13 before calling the coprocessor exception function, it still dies.
Really at a loss >_>

Also, this will only work on Linux/BSD at the moment. The RSP vector functions
pass four parameters, and my Windows call wrapper can only handle 3 arguments
because after that the argument has to go on the stack. I'll fix that later.
2021-05-04 08:31:00 +00:00
Near 02180bad08 Update to ares v119r14 release.
Working Nintendo 64 data cache emulation (still don't know the memory access
timings for it) and improved Mega Drive VDP emulation (still can't run TO1&2)
2021-04-30 07:34:00 +00:00
Near 8b7daf3c26 Update to ares v119r13 release.
GoldenEye 007 and Jet Force Gemini run now. Right now, known N64 bugs are:
Donkey Kong 64 hangs when the EEPROM support is enabled, Indiana Jones doesn't
boot (probably anti-emulator code?), Blast Corps blinks a lot (though less than
it did before.)

This WIP has CPU instruction and data cache emulation, though I had to disable
the data cache as it's not working yet.
2021-04-28 04:17:00 +00:00
Near 32ce9a54db Update to ares v119r12 release.
Three N64 game fixes. Refactored Mega Drive profile=accuracy vdp more, still
can't pass Titan Overdrive 1 or 2 ._. Really getting demotivated on that one.
2021-04-25 22:48:00 +00:00
Near f80efd1c05 Update to ares 20210422 release.
This has really really really improved timings.
2021-04-22 04:52:00 +00:00
Near 88714763ca Update to ares v119r10 release.
[Previously, Near said "Now to fix sprite fetching on Y=-1"]

Should be substantially better now.

Titan Overdrive 2 shows distorted graphics on the "Overdrive 2" logo screen
(after the ship crash and maze run), and the only way to get that working is to
double the VDP FIFO speed. It already runs twice as fast in 128K VRAM mode. The
same FIFO speed doubling is required to not crash after the Titancade screen.

Unless I'm really fundamentally misunderstanding something, I'm not sure what's
going on here.
2021-04-20 07:10:00 +00:00
Near 1b67ca2b79 Update to ares v119r09 release.
This gets us a lot further with the Mega Drive, but still some major issues.
Lemmings 2 will sometimes crash when you load it (not threading related), and
Titan Overdrive 2 crashes after the arcade scene. Ran out of steam to work on
this more today though, 12 hours in already.
2021-04-18 06:10:00 +00:00
Near a657ddf23d Update to ares 20210418a release.
This has VDP debug register emulation, well one of the 16 debug registers anyway

I fixed sound in TO2, was mirroring like crazy in the APU space, also fixed
sprites not rendering all the way in the rain scene.

So what you'll see I'm doing is setting an irq.(vh)blank.pending=1 flag, and
then whenever you have hvirq enabled AND a pending flag, it sends an IRQ to the
CPU and clears the pending flag, and when the CPU triggers it, the CPU marks it
as acknowledged.

Apparently BlastEm links bit 7 of the control status register to the
vblank.pending flag, so I'm copying that.

[Near then posted a screenshot of Titan Overdrive 2 running inside ares. In
white text on a blue background, it says:

    0D2 B50D

    D0 00000001
    D1 00FF2700
    D2 93979301
    D3 40000002
    D4 0D12001C
    D5 00000000
    D6 00000001
    D7 0000FFFF
    A0 00C00004
    A1 00C00000
    A2 00000CBC
    A3 00000DEC
    A4 00FF1464
    A5 00FF0C1A
    A6 00FF0C1A
    A7 00FFFFFE

-Ed.]

Crashes here if I don't lower the CPU H/VIRQ lines on Vblank/Hblank=0

Also I am faking the Vcounter incrementing early when reading the Vcounter,
easier that way.
2021-04-18 01:59:00 +00:00
Near a986fafb69 Update to ares 20210418 release.
Here's a snapshot, gets Titan Overdrive 2 music playing.
2021-04-17 22:02:00 +00:00
Near f45ccd4b7d Update to ares v119r08 release.
Really substantial Mega Drive profile=accuracy timing improvements, but still
Titan Overdrive 2 performs much worse than the default performance profile, and
that fucking audio driver still won't play any sound.
2021-04-15 19:58:00 +00:00
Near 1b6b4f1ae2 Update to ares v119r06 release.
- Nintendo 64: report 64DD as missing for now; fixes F-Zero X
  - Nintendo 64: improved TLB emulation; fixes Conker's Bad Fur Day
  - Mega Drive: improved VDP FIFO emulation
2021-04-10 23:07:00 +00:00
Near bd8a1b5155 Update to ares v119r05 release.
- ares: added Thread::restart() function to reset a thread without resetting
    its clock
  - Mega Drive: improved DRAM refresh timings
  - Mega Drive: added VDP I/O logger
  - Mega Drive: fixed VDP counter emulation (still inaccurate)
  - Mega Drive: improved VDP DMA and FIFO emulation
2021-04-08 21:28:00 +00:00
Near 21d3983b4d Update to ares v119r04 release.
- N64: fixed RSP vector unit register values in the disassembler
  - Mega Drive: implemented proper VDP FIFO timings for both reads and writes
    (hopefully)
  - Mega Drive: enabled external and RAM refresh timing
  - Mega Drive: added (Mega Drive | Mega 32X) + Mega CD mode 1 emulation
  - Mega Drive: refactored dot-based VDP renderer
2021-04-06 16:38:00 +00:00
Near c9d2f41bdb Update to ares v119r03 release.
A working VDP FIFO implementation (write slots only), but probably wildly
inaccurate. Rough timing approximations for the slots.

This build fixes some issues in MD Sonic the Hedgehog (forgot to undo the
background color register bit twiddling when reverting some overly aggressive
VDP-performance optimizations) and also fixes MD Golden Axe II.

I spent a few hours trying to fix Lemmings 2 from locking up immediately. What
happens is I get a fourth Hblank IRQ before it clears a RAM value, whereas
Mednafen only gets three. And that desyncs something and it never gets out of a
loop.
2021-04-04 08:31:00 +00:00
Near 787417cf2b Update to ares v119r2 release.
Unfortunately a few critical issues crept in between v118 and v119, so here is a
bugfix release for all reported issues.

It also fixes some game bugs while I'm at it, and boosts 32X compatibility from
50% to a little over 60%.

Please do upgrade if you have v119, this one's important.

  - SH2: MAC must increment R[n] before reading from R[m]; fixes Virtua
    Fighter and Toughman Contest
  - SH2: fixed dynarec MOV @Rm+,Rn to not increment when Rm==Rn
  - SH2: fixed dynarec TST instruction
  - SH2: improved dynarec accuracy by breaking blocks on delay slot branches
  - SH2: improved dynarec accuracy by decreasing the underclocking amount
  - Mega Drive: implemented undocumented VSRAM and CRAM DMA fill
  - Mega Drive: simplified scanline VDP renderer; fixes TMNT: Tournament
    Fighters graphics
  - Mega Drive: improved region detection; correctly identifies Alien Soldier
    region now
  - Mega CD: fixed crash on game load
  - Super Famicom: fixed direct color mode; fixes Secret of Mana world map
  - WonderSwan Color: fixed initial state for new EEPROMs plus EEPROM size;
    fixes missing sound
  - lucia: fixed saving RAM files when a manual save path was specified
  - ruby: fixed library dependency detection for Arch Linux and other
    distributions
  - hiro/GTK3: added CSS stylesheet overrides to improve appearance [Screwtape]
2021-04-02 07:23:00 +00:00
Near b3aeb41ee5 Update to ares v119 release.
I'm releasing ares v119 today, which includes very preliminary Sega 32X
emulation support. Compatibility is currently at around 50% with the dynamic
recompiler, probably closer to 75% with the cached interpreter, and since the
system requirements were a bit too steep (on account of my Mega Drive core being
cycle/dot-accurate), I downclocked the SH2s a bit until I can speed up the
emulator more. You'll currently need about a Ryzen 5 2600 to hit 60fps reliably.
With the underclock, my Ryzen 7 5800X hits 120fps, and without it, 85fps.

Although the compatibility for the new 32X core is a bit low, this is mostly due
to pesky CPU bugs. The accuracy is quite high and I've emulated as much of the
32X and SH7604 peripheral functions as possible. I pass all 161 tests from the
Mars Check Program. It should not take much more work to reach 98% compatibility
in the future. Sega CD 32X emulation support is present, but is likely not
functional, as I haven't tested it yet.

Other major features in this release include Sega SVP support for Virtua Racing,
plus improved Nintendo 64, Mega Drive, and Mega CD emulation compatibility.

I'm going to start working on Sega Saturn emulation now, while Luke Usher works
on Neo Geo emulation. No promises as to when or if these cores will become
playable, I'm just giving you all a heads up since you'll see the skeletons for
these systems in the source code now.

Changelog:

  - Nintendo 64: improved Expansion Pak detection
  - Nintendo 64: fixed swapped L and R buttons [simer]
  - Nintendo 64: emulated the RST bit for gamepads
  - ruby: added library detection support for the Linux and BSD targets
  - lucia: gained support for game paks (custom file dialog only)
  - Super Famicom: added support for Super Game Boy, Sufami Turbo, and BS
    Memory packs
  - hiro: made SourceEdit optional for gtk2 and gtk3 targets (disabled
    for ares)
  - Nintendo 64: emulated 2048-byte EEPROM identifier and transfer protocol
  - Super Famicom: corrected ppu-performance widths table indexing to consider
    overscan
  - Mega CD: fixed a bug in register $ff8003; allows Popful Mail to boot
    [TascoDLX]
  - Mega Drive: fixed a bug with 256-width video modes
  - Mega Drive: improved VDP DMA emulation which should fix many games
  - Mega Drive: added SVP emulation
  - Mega Drive: added 32X emulation
  - Mega CD: fixed a bit-masking bug in register $ff8004; fixes Radical Rex
    [TascoDLX]
  - Nintendo 64: fixed C implementation of RSP VMACU instruction
  - Nintendo 64: use correct NTSC and PAL PIF ROM images based on the region
  - Mega Drive: fixed reset logic, Z80 interrupt timing + prefix timing +
    bus control [TascoDLX]
  - Mega CD: fixed word RAM access and CDC DMA word RAM transfers [TascoDLX]
  - Nintendo 64: improved RSP VMOV emulation [Rasky]
  - Nintendo 64: fixed RSP DMEM DMA alignment (&~7, not &~3) [Rasky]
  - Nintendo 64: upgraded to the latest version of ParaLLEl-RDP
  - nall: greatly expanded recompiler/amd64's supported intrinsics
  - mia: substantial refactoring around a new virtual filesystem implementation
    from nall
2021-03-31 04:38:00 +00:00
Near d0258c76e6 Update to ares v118r16 release.
My latest ares WIP hooked up 128KB VRAM mode to my fast SNES PPU.
2021-03-27 20:22:00 +00:00
Near fd4eb76bf5 Update to ares v118r15 release.
[This release was posted to the ares Discord after r16. That version introduced
128KB VRAM mode for the Super Famicom core, and somebody requested the previous
version so they could see the changes involved in implementing that feature.
-Ed.]
2021-03-25 05:31:00 +00:00
Near 8c1d9840c0 Update to ares v118r13 release.
Latest version with VMOV and RSP DMEM mask fix
2021-03-24 00:21:00 +00:00
Near fae7a763fa Update to ares v118r12 release.
With TascoDLX's Mega CD fix ❤️❤️
2021-03-22 09:36:00 +00:00
Near d6dfd20dd6 Update to ares v118r11 release.
That's as far as I can go with 32X support for now. I fully emulated the Sh2
cache but I still hang at Mars test 123. The Hblank (2) test fails because it
looks like I'm running a bit too fast. The DMA test fails because it expects
DREQ to become inactive when the DREQ length hits zero. If I do that, the test
hangs. If I don't do that, the test fails.

Virtua Fighter shows no graphics in-game, Virtua Racing shows no graphics
period.
2021-03-22 09:03:00 +00:00
Near 493a446168 Update to ares v118r09 release.
Knuckles Chaotix is now fully playable at glorious 20fps, heh.

Still a whole ton of issues but I really went to town with this WIP. I
implemented read/write functionality for all the SH7804 internal
registers/functional units, and added basic simulation of the free-range timer,
DMA controller (very basic) and interrupt controller.

On the 32X side, it should be functionally complete save for bugs now. VDP and
PWM are fully implemented.
2021-03-18 07:07:00 +00:00
Near 1ca28694f9 Update to ares 20210317 release.
I am getting my ass kicked by SH-2 delay slots >_>

The basic idea of them is simple, but the PR register and when to do the +4 or
+2 or not is not intuitive.
2021-03-17 09:23:00 +00:00
Near 382634e311 Update to ares v118r08 release.
Still too many bugs to run anything. Hopefully next time ...

Chaotix 68K writes to FIFO, then SH2s never read it or query FIFO status.
2021-03-15 06:33:00 +00:00
Near e6f5e75854 Update to ares v118r07 release.
SH-2 core finished, started connecting the 32X to it. It executes some
instructions and does some I/O register stuff before hanging. Still gotta
implement the 32X interrupts, PWM, and VDP stuff.
2021-03-14 03:57:00 +00:00
Near a17f29d4c4 Update to ares v118r05 release.
Here's the current build with working SVP support. Build with profile=accuracy
if you try it because my fast scanline renderer breaks soooo many games
including Virtua Racing ._.
2021-03-10 07:31:00 +00:00
Near a38a31e47a Update to ares v118r04 release.
This WIP has the new mia system. It's a pretty massive change ... I hope it will
go okay for you. Feel free to ping me and I'll walk you through it.

Essentially, we want to edit mia/system/neo-geo-(aes|mvs).cpp to load in the
necessary files from MAME's neogeo.zip that is given to it (I have a helper
Pak::read(zipfile, pattern) function to grab files out of the archive for you
into a vector<u8>), do endian conversion, add to the pak, then the Neo Geo core
can see it.

The Neo Geo cartridge support should be enough for Magician Lord and super early
games with no mappers or crypto, so we'll start there and work our way up.
2021-03-07 19:05:00 +00:00
Near 007b27704d Update to ares 20210303 release.
My tracer was crashing in v118 for the Mega CD due to the trace address not
being masked and the value underflowing, so here's a pre-v118.4 WIP with that
fixed.
2021-03-03 04:44:00 +00:00
Near c5759c503f Update to ares v118r02 release.
So, spoiler since you'll all see it: Luke and I are gonna be working on a
Neo*Geo core. Please keep that a secret for now until we can get some
screenshots to share with people.

Would appreciate feedack on the vfs redesign, still a work in progress. Right
now, the potential is there to have ares cores that don't use manifests at all.
So far, only the ColecoVision core actually does it. However, all cores are
ported to use the new Platform::pak() function instead of Platform::open() [now
removed.]

Lots of stuff is broken right now: N64/PS1 memory cards, PC Engine CD / Mega CD
internal save memory, Mega CD can't play any games, FDS and NGP don't save, etc.
2021-03-01 19:28:00 +00:00
Near c72292ef4b Update to ares v118r01 release.
[No official changelog available for this version. -Ed.]
2021-02-26 19:33:00 +00:00
Near 44bdc531bb Update to ares v118 release.
I'm excited to launch ares v118 today, the first release featuring playable,
full-speed Nintendo 64 emulation!

The new Nintendo 64 emulation is made possible thanks to [Themaister] very
graciously porting his Vulkan-based ParaLLEl-RDP graphics renderer to ares. With
its default settings, it is nearly pixel-perfect to real hardware, and it
optionally supports upscaling to 2x or 4x the original Nintendo 64 resolution,
plus optional supersampling back down to the original resolution (for enhanced
anti-aliasing) if desired. The Vulkan support requires an appropriate graphics
card, and either Windows or Linux. At this time, Vulkan is not available for
macOS nor the BSDs.

Also new for the Nintendo 64 core in this release is Rumble Pak, Cartridge Pak,
SRAM, EEPROM, and Flash save support. Note that for right now, the Rumble Pak
will only be enabled for games which use internal saves (SRAM, EEPROM, and
Flash.) That does not cover all Rumble Pak-capable games. The option to choose
between Rumble Paks and Cartridge Paks will be added to a future release.

For the PlayStation core, [Luke Usher] provided two rendering fixes that allow
Final Fantasy VII and Tony Hawk's Pro Skater to be fully playable!

Right now, approximately 33% of the Nintendo 64 library is fully playable, and
about 67% of the PlayStation library is fully playable. Each core has only been
under active development for about one month each, so they both have a long way
to go. Please treat these early releases as tech samples, rather than finished
emulation cores.

Further, note that the Nintendo 64 and PlayStation cores employ cached
interpreters. This is a middle-ground between the accuracy of interpreters and
the performance of dynamic recompilers. As such, ares' system requirements will
be a bit higher than traditional emulators for these systems. Presuming no
background task interference or CPU throttling, generally speaking, a Ryzen 5
2600 or better CPU should get you to around ~120fps in the average case, and
~60fps in the worst case.

The source code has also been released under the terms of the Creative Commons
BY-NC-ND 4.0 license.

[Themaister]: http://github.com/Themaister/
[Luke Usher]: https://twitter.com/LukeUsher1
2021-02-20 23:51:00 +00:00
Near 43af5c298b Update to ares v117r03 release.
[No official changelog available for this version. -Ed.]
2021-02-18 16:27:00 +00:00
Near 1e577f56e7 Update to ares v117r01 release.
[No official changelog available for this version. -Ed.]
2021-02-15 23:04:00 +00:00
Near 7656765f30 Update to ares v117 release.
[No official changelog available for this version. -Ed.]
2021-02-08 09:11:00 +00:00
Near fabde308e9 Update to ares v116r08 release.
[No official changelog available for this version. -Ed.]
2021-01-18 21:03:00 +00:00
Near 4af59c63f1 Update to ares v116r07 release.
[No official changelog available for this version. -Ed.]
2021-01-14 21:00:00 +00:00
Near 70cdb5b199 Update to ares v115a release.
[No official changelog available for this version. -Ed.]
2020-07-26 17:29:00 +00:00
Near 01184dc6bd Update to ares v115 release.
[No official changelog available for this version. -Ed.]
2020-07-24 21:18:00 +00:00
Near 17f1f24dc2 Update to ares v114r25 release.
- PlayStation: implemented all GTE instructions (though certainly with
    many serious bugs remaining)
  - ares: improved Debug class notifications
2020-07-23 03:48:00 +00:00
Near e2a5547ae7 Update to ares v114r24 release.
Ridge Racer now boots and gets in-game, but likely GTE errors prevent it
from being very playable yet.

  - PlayStation: added DMA IRQ support
  - PlayStation: added more GTE instructions
  - ares: started on a new Debug class for notifications (unimplemented
    features, etc.)
2020-07-19 19:53:00 +00:00
Near 6447903966 Update to ares v114r23 release.
- PlayStation: improved timer support
  - PlayStation: added more GPU GP0 rendering commands
  - lucia: split the emulator list and emulator options into separate
    settings panels
  - lucia: added fast boot option for PlayStation and Neo Geo Pocket
    cores
2020-07-17 20:14:00 +00:00
Near f97a1f954e Update to ares v114r22 release.
- PlayStation: fixed masking bug in LWL and LWR instructions
  - PlayStation: improved timer support
  - PlayStation: added EXE side-loading support
  - PlayStation: added fast boot support
  - PlayStation: added libc putchar logging support
2020-07-17 00:07:00 +00:00
Near 5c6ef3eb4d Update to ares v114r21 release.
- PlayStation: improved GTE support
  - PlayStation: improved CD-ROM support
2020-07-15 19:50:00 +00:00
Near ce2abced51 Update to ares v114r20 release.
- PlayStation: implemented CD-DA support
  - PlayStation: implemented CD data seeking and reading support
  - PlayStation: implemented CD-ROM DMA support
2020-07-12 15:18:00 +00:00
Near 50b62604a8 Update to ares v114r19 release.
- PlayStation: started implementing controller support
  - PlayStation: improved texture semi-transparency support
  - PlayStation: fixed a bug in render clipping
2020-07-10 18:43:00 +00:00
Near fb855d62af Update to ares v114r18 release.
- PlayStation: implemented free-running timer mode
  - PlayStation: implemented draw rectangle commands
2020-07-09 19:43:00 +00:00
Near 5f035496bb Update to ares v114r17 release.
- PlayStation: started implementing timers
  - MSX: added more cartridge mappers (Konami SCC, ASCII 8kbit, ASCII
    16kbit, etc)
2020-07-08 11:59:00 +00:00
Near bfdb287505 Update to ares v114r16 release.
- Super Famicom: mosaic fix wasn't exactly right before; now it should
    be
  - PlayStation: started implementing CD interface
  - PlayStation: started implementing GTE coprocessor
2020-07-04 19:46:00 +00:00
Near a37e5ba378 Update to ares v114r15 release.
- PlayStation: added reverb support
2020-07-03 14:37:00 +00:00
Near b12ac07464 Update to ares v114r14 release.
- Super Famicom: fixed bugs in hires + interlaced mosaic rendering
  - PlayStation: started implementing the SPU (no DMA, CD-DA, reverb, or
    sweep support yet)
2020-07-02 11:18:00 +00:00
Near 46bba9b798 Update to ares v114r13 release.
- PlayStation: added I/O handling for the SPU (no emulation yet)
  - PlayStation: added gaussian interpolation table generation
  - Super Famicom: replaced hard-coded constants with gaussian
    interpolation table generation
2020-07-01 08:09:00 +00:00
Near b1b4452d23 Update to ares v114r12 release.
- PlayStation: added dithering, shaded texture, and partial semi-
    transparency rendering support
2020-06-29 12:31:00 +00:00
Near 60bddfc33f Update to ares v114r11 release.
- PlayStation: added gouraud shaded and textured triangle rendering
2020-06-28 06:47:00 +00:00
Near c2a9cc9fbc Update to ares v114r10 release.
- PlayStation: started on GPU renderer (solid triangles only so far)
2020-06-27 08:02:00 +00:00
Near f376ce8499 Update to ares v114r09 release.
- PlayStation: improved DMA support somewhat
  - PlayStation: implemented some GP0 and GP1 commands
2020-06-25 19:31:00 +00:00
Near 0ed46cc2b1 Update to ares v114r08 release.
- PlayStation: fixed a bug in the SLLV instruction
  - PlayStation: implemented interrupts
2020-06-24 09:25:00 +00:00
Near d9ea05c4c4 Update to ares v114r07 release.
- PlayStation: started implementing the CPU SCC (missing some
    registers still)
  - PlayStation: implemented basic DMA support
2020-06-22 21:49:00 +00:00
Near a4caa85c0b Update to ares v114r06 release.
- PlayStation: implemented all core CPU instructions (no SCC or GTE
    instructions yet)
2020-06-19 00:12:00 +00:00
Near 8b0359aa78 Update to ares v114r05 release.
I've started on a Sony PlayStation emulation core with this WIP. The
goal is to work on the MIPS CPU core while I am still well-versed with
the MIPS ISA. The Nintendo 64 core will remain my primary focus,
however.

  - PlayStation: implemented initial driver skeleton (no emulation code
    yet)
  - lucia: added option to group the load menu options into submenus by
    manufacturer
  - lucia: connected Cocoa-specific application menu options to their
    appropriate callbacks
  - hiro/Cocoa: fixed compilation issues for HexEdit (the widget is not
    implemented, however)
  - hiro/Cocoa: fixed a subpixel precision rendering issue causing
    blurry fonts [LIJI]
2020-06-18 15:02:00 +00:00
Near ba05897d75 Update to ares v114r04 release.
This WIP adds non-SIMD implementations of all RSP vector unit
functionality. This allows compiling without SSE, but was mainly added
for debugging SSE issues. It's also useful for documenting in code what
the SSE instructions are doing in C++ code.

  - Nintendo 64: added non-SSE implementation of RSP vector unit
2020-06-16 03:45:00 +00:00
Near 6cd757dae8 Update to ares v114r03 release.
- nall: added bump_allocator class
  - Nintendo 64: restructured dynamic recompilers to be cleaner
2020-06-13 20:40:00 +00:00
Near fb9859ad2f Update to ares v114r02 release.
The new recompilers increase the framerate in Namco Museum from 60fps to
160fps, and in Zelda: Ocarina of Time from 55fps to 135fps (presuming no
RDP renderer.)

  - Nintendo 64: completed basic CPU dynamic recompiler
  - Nintendo 64: completed basic RSP dynamic recompiler
2020-06-12 17:27:00 +00:00
Near f518bcb374 Update to ares v114r01 release.
- Nintendo 64: started work on CPU dynamic recompiler
2020-06-11 21:07:00 +00:00
Near 20469c66e9 Update to ares v114 release.
First public release of ares. Bumped the version number early for the
milestone.

  - SFC: added missing SA1 board definition (for boards without BWRAM)
2020-06-07 14:38:00 +00:00
Near 3559a7659b Update to ares v113r05 release.
- N64: added FPU support for ordered and unordered comparisons
  - N64: reduced red tape in the CPU and RSP instruction decoder switch
    tables
2020-06-01 13:57:00 +00:00
Near 1f45125d45 Update to ares v113r04 release.
Initial required work to attempt implementing a cached interpreter ...

  - N64: moved all CPU and RSP instruction decoding out of opcode
    handlers
2020-05-30 17:32:00 +00:00
Near 03f7fe2b25 Update to ares v113r03 release.
- N64: redesigned the bus handler
  - N64: execute eight CPU instructions per synchronization event
  - N64: range test the CPU Compare register
  - N64: decode more RDP display list commands
2020-05-28 14:24:00 +00:00
Near a05937bfa4 Update to ares v113r02 release.
- ruby: added new FreeBSD UHID driver (to support hotplugging and the
    Xbox 360 D-pad properly)
  - N64: started on Nintendo 64DD support
2020-05-27 11:01:00 +00:00
Near d9d208d615 Update to ares v113r01 release.
- N64: better input mapping for C-buttons
  - lucia: improved input mapping code
  - ruby: disabled FreeBSD SDL joypad hotplugging hack (causes input
    issues in games)
2020-05-26 02:58:00 +00:00
Near 842ea44b90 Update to ares v113 release.
- N64: improved TLB emulation (Super Mario 64 is now fully playable)
  - lucia: implement analog axis support
2020-05-24 05:01:00 +00:00
Near e67dfac166 Update to ares v112r30 release.
Many N64 games are now playable.

  - N64: VSUB should clear VCO
  - N64: corrected VRCP(L) and VRSQ(L) instructions
  - N64: many other smaller various fixes
2020-05-21 15:17:00 +00:00
Near a5d2ee5e5f Update to ares v112r29 release.
- N64: added missing BLTZAL, BGEZAL instructions
  - N64: added missing SLT, SLTI instructions (they were erroneously
    aliased to SLTU, SLTIU)
  - N64: mask low two bits of PC when writing to SP_PC_REG
  - N64: refactored RSP DMA; only mask the low two bits SP_PBUS_ADDRESS
  - N64: RSP DMA seemingly updates SP_PBUS_ADDRESS and SP_DRAM_ADDRESS
2020-05-20 05:13:00 +00:00
Near bef70d2550 Update to ares v112r28 release.
- N64: implemented missing RSP vector load/store instructions
  - N64: fixed RSP MFC2 and MTC2 instructions
  - N64: rewrote and simplified CPU TLB handling
2020-05-20 00:51:00 +00:00
Near f656e317c8 Update to ares v112r27 release.
- N64: improved CPU disassembler
  - N64: added RSP disassembler
  - N64: corrected reads from SP_SEMAPHORE
  - N64: improved PIF joypad polling functionality
  - N64: added I/O logging to trace logger
2020-05-18 23:35:00 +00:00
Near 494b1cb0ba Update to ares v112r26 release.
- N64: CPU and RSP instruction improvements
  - N64: improved CPU and RSP branch handling
2020-05-18 03:37:00 +00:00
Near be25bb110c Update to ares v112r25 release.
- N64: added skeleton I/O reading and writing for DPS registers
  - N64: added skeleton RDP renderer
2020-05-17 06:27:00 +00:00
Near 1f59ef7457 Update to ares v112r24 release.
- N64: added PIF boot ROM emulation
  - N64: detected NUS-CIC revision based on ROM bootcode checksum
  - N64: added skeleton I/O reading and writing for all VI and PI
    registers
2020-05-17 04:15:00 +00:00
Near 74e6d389a6 Update to ares v112r23 release.
This WIP separates the RSP SCC registers so that RDP rendering commands
are not processed inside of the RSP. The register interface is shared
between the SCC and the CPU bus, so there is no technically correct
location for these handlers.

  - N64: moved RSP SCC registers to outer RSP and RDP I/O handlers
2020-05-16 00:53:00 +00:00
Near 9449b78675 Update to ares v112r22 release.
- N64: added RDRAM and interrupt sources to debugger
  - N64: emulated basic RDP commands to detect sync commands for DP IRQ
    generation
2020-05-15 01:40:00 +00:00
Near 388f555304 Update to ares v112r21 release.
- N64: emulated FPU FR=0 mode; fixes intro sound in Namco Museum
2020-05-14 22:51:00 +00:00
Near 4cf677063c Update to ares v112r20 release.
- N64: improved AI FIFO emulation
  - N64: emulated VT[e] addressing in RSP vector unit
2020-05-13 14:59:00 +00:00
Near 890b56f84d Update to ares v112r19 release.
- N64: improved TLB emulation and made it much faster (but limited to
    32-bit mode without ASIDs)
2020-05-13 02:23:00 +00:00
Near ddd3a439ff Update to ares v112r18 release.
- N64: improved audio playback (AI_LENGTH &=~ 7, not (AI_LENGTH | 7) +
    1)
  - N64: improved exception handling (ERL bit isn't set on standard
    exceptions)
  - N64: added very incomplete, inital TLB emulation
  - N64: various improvements to the disasssembler (including FPU
    instruction support)
  - N64: improved SI emulation (Namco Museum input now works)
2020-05-12 10:13:00 +00:00
Near 318beb509f Update to ares v112r17 release.
This WIP boots the first official Nintendo 64 title, Namco Museum. It
remains to be playable, however.

  - N64: improved interrupt handling
  - N64: implemented basic state machine handling for PI serial data
    transfers
  - N64: resume previously executed instruction after ERET for non-
    interrupt exceptions
  - N64: various other improvements
2020-05-11 06:56:00 +00:00
Near 6f6e2ea260 Update to ares v112r16 release.
- N64: skip delay slot when executing ERET instruction
  - N64: improve IRQ handling (always update CPU SCC Cause bits when
    toggling MI IRQs)
  - N64: audio emulation improvements
2020-05-10 19:57:00 +00:00
Near 67cf63b532 Update to ares v112r15 release.
- N64: implemented SI DMA
  - N64: implemented basic AI audio emulation
  - N64: various improvements and bugfixes
2020-05-10 04:26:00 +00:00
Near a427fe2a71 Update to ares v112r14 release.
- N64: implemented CPU SCC ERET instruction
  - N64: improved interrupt support slightly
  - N64: rewrote CPU disassembler to be more sophisticated
2020-05-09 00:52:00 +00:00
Near e6c42199aa Update to ares v112r13 release.
- N64: RSP vector instruction fixes
  - N64: started on initial exception and interrupt support
2020-05-07 22:51:00 +00:00
Near b224caf4bd Update to ares v112r12 release.
- N64: implemented all official RSP vector instructions
  - N64: implemented reserved RSP vector instructions VMULQ, VMACQ,
    VRNDP, VRNDN
  - N64: implemented RSP instructions MFC2 and MFC2
2020-05-07 07:49:00 +00:00
Near bd565eb982 Update to ares v112r11 release.
- N64: core now requires SSE 4.1 support (for vector instructions)
  - N64: implemented VABS, VADD, VADDC, VAND, VCL, VCH, VMOV, VNAND,
    VNOP, VSAR, VSUB, VSUBC instructions
2020-05-05 22:51:00 +00:00
Near f149b5d2a5 Update to ares v112r10 release.
- N64: removed libco completely, using direct cycle counters now
    instead
  - N64: emulated RSP DMA between IRAM/DRAM and RDRAM
  - N64: emulated RSP core R4000 instructions
  - N64: started working on RSP COP2 vector instructions
2020-05-05 03:30:00 +00:00
Near 32d8abd372 Update to ares v112r09 release.
Emulation is now far enough along to complete the boot loading code and
begin executing game code. The "hello world" CPU rendering demo now runs
correctly in both 15bpp and 24bpp output modes.

  - N64: implemented skeleton interfaces (MI, VI, AI, PI, RI, SI)
  - N64: implemented PI DMA
  - N64: added basic frame buffer rendering (320x240 only)
2020-05-03 17:30:00 +00:00
Near 5ef188c876 Update to ares v112r08 release.
- N64: correct JAL and JALR instructions
2020-05-02 17:41:00 +00:00
Near 590773508e Update to ares v112r07 release.
- N64: redesigned CPU register casting (use a union class instead of
    #defines)
  - N64: completed CPU coprocessor 1 FPU
2020-05-02 15:11:00 +00:00
Near 2f24221be9 Update to ares v112r06 release.
- N64: much faster endian decoding
  - N64: implemented CPU coprocessor 0 skeleton (excluding MMU)
  - N64: implemented CPU coprocessor 1 skeleton (excluding FPU)
2020-05-01 21:17:00 +00:00
Near e7b120f2e5 Update to ares v112r05 release.
- N64: implemented bus skeleton
  - N64: simulated the PIF boot ROM (partially)
2020-04-30 18:58:00 +00:00
Near 4a1084179b Update to ares v112r04 release.
- N64: merged the VR4300 core into the CPU class
  - mia: added N64 deinterleaving support
2020-04-30 13:30:00 +00:00
Near e9bd3dda68 Update to ares v112r03 release.
- VR4300: implemented most of the general instructions
2020-04-29 19:19:00 +00:00
Near c1f9897a03 Update to ares v112r02 release.
- VR4300: implemented register-immediate instructions
  - VR4300: implemented half of the general instructions
  - ares: added Port::supported() -> vector<string> API
  - nall: improve checks in directory::exists() and directory::create()
2020-04-29 15:52:00 +00:00
Near 291a0ea8de Update to ares v112r01 release.
- VR4300: implemented special instructions
2020-04-28 19:20:00 +00:00
3018 changed files with 479166 additions and 56996 deletions

No files matched your search

+194
View File
@@ -0,0 +1,194 @@
name: Build
on:
push:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]
jobs:
build:
strategy:
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++
shell: 'msys2 {0}'
msystem: clang64
msys-env: clang-x86_64
- name: macos
os: macos-latest
compiler: clang++
shell: sh
- name: ubuntu
os: ubuntu-latest
compiler: g++
shell: sh
name: ${{ matrix.program }}-${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
defaults:
run:
shell: ${{ matrix.platform.shell }}
steps:
- name: Install MSYS2 Dependencies
if: matrix.platform.shell == 'msys2 {0}'
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.platform.msystem }}
install: make mingw-w64-${{ matrix.platform.msys-env }}-toolchain
- 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
- name: Make
run: make -j4 -C desktop-ui build=optimized local=false lto=true compiler=${{ matrix.platform.compiler }}
- name: Upload
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.program }}-${{ matrix.platform.name }}
path: desktop-ui/out/*
release:
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
needs:
- build
steps:
- uses: actions/checkout@v2
with:
path: 'src'
- name: Download Artifacts
uses: actions/download-artifact@v2
with:
path: 'bin'
- name: Package Artifacts
run: |
set -eu
case ${GITHUB_REF} in
refs/tags/*) suffix="-${GITHUB_REF#refs/tags/}" ;;
refs/heads/master) suffix="-nightly" ;;
*) suffix="" ;;
esac
srcdir="${GITHUB_WORKSPACE}/src"
bindir="${GITHUB_WORKSPACE}/bin"
# Hack: Workaround for GitHub artifacts losing attributes.
chmod +x ${bindir}/ares-macos/ares.app/Contents/MacOS/ares
for os in windows macos
do
mkdir "${os}"
cd "${os}"
# Package ares.
outdir=ares${suffix}
mkdir ${outdir}
cp -ar ${bindir}/ares-${os}/* ${outdir}
zip -r ../ares-${os}.zip ${outdir}
cd -
done
- name: Create Release
id: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eu
github_rest()
{
local method="${1}"
local url="https://api.github.com${2}"
shift 2
>&2 echo "${method} ${url}"
curl \
--fail \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${GITHUB_TOKEN}" \
-X "${method}" \
"${url}" \
"$@"
}
github_get_release_id_for_tag()
{
payload=$(github_rest GET "/repos/${GITHUB_REPOSITORY}/releases/tags/${1}") || return
echo "${payload}" | jq .id
}
github_delete_release_by_id()
{
github_rest DELETE "/repos/${GITHUB_REPOSITORY}/releases/${1}"
}
github_create_release()
{
local payload="{
\"tag_name\": \"${1}\",
\"target_commitish\": \"${2}\",
\"name\": \"${3}\",
\"body\": \"${4}\",
\"draft\": ${5},
\"prerelease\": ${6}
}"
github_rest POST "/repos/${GITHUB_REPOSITORY}/releases" -d "${payload}"
}
make_nightly_release()
{
github_create_release \
nightly \
"${GITHUB_SHA}" \
"ares nightly $(date +"%Y-%m-%d")" \
"Auto-generated nightly release on $(date -u +"%Y-%m-%d %T %Z")" \
false \
true
}
make_version_release()
{
github_create_release \
"${1}" \
"${GITHUB_SHA}" \
"ares ${1}" \
"This is ares ${1}, released on $(date +"%Y-%m-%d")." \
false \
false
}
case ${GITHUB_REF} in
refs/tags/*)
# Create a new version release using the current revision.
echo "UPLOAD_URL=$(make_version_release ${GITHUB_REF#refs/tags/} | jq -r .upload_url)" >> $GITHUB_ENV
;;
refs/heads/master)
# Check for an existing nightly release.
{ release_id=$(github_get_release_id_for_tag nightly); status=$?; } || true
# Delete existing nightly release if it exists.
case ${status} in
0) github_delete_release_by_id "${release_id}" ;;
22) >&2 echo "No current nightly release; skipping tag deletion." ;;
*) >&2 echo "API call failed unexpectedly." && exit 1 ;;
esac
# Create a new nightly release using the current revision.
echo "UPLOAD_URL=$(make_nightly_release | jq -r .upload_url)" >> $GITHUB_ENV
;;
esac
- name: Upload ares-windows
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-macos
uses: actions/upload-release-asset@v1
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-macos.zip', asset_name: 'ares-macos.zip', asset_content_type: 'application/zip' }
# - name: Upload ares-ubuntu
# uses: actions/upload-release-asset@v1
# env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
# with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-ubuntu.zip', asset_name: 'ares-ubuntu.zip', asset_content_type: 'application/zip' }
+30
View File
@@ -0,0 +1,30 @@
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]"
+2
View File
@@ -0,0 +1,2 @@
obj/
out/
+6
View File
@@ -0,0 +1,6 @@
all: desktop
desktop:
$(MAKE) -C desktop-ui
.PHONY: all desktop
+148
View File
@@ -0,0 +1,148 @@
----------------------------------------------------------------------
ares
Copyright (c) 2004-2021 ares team, Near et al
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------------------------------------
----------------------------------------------------------------------
Stack-less Just-In-Time compiler
Copyright Zoltan Herczeg ([email protected]). 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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(S) 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.
----------------------------------------------------------------------
----------------------------------------------------------------------
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
Copyright Romain Tisserand
All rights reserved.
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.
* Neither the name of the <organization> 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 <COPYRIGHT HOLDER> 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
----------------------------------------------------------------------
----------------------------------------------------------------------
LZMA SDK is placed in the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute
the original LZMA SDK code, either in source code form or as a compiled binary,
for any purpose, commercial or non-commercial, and by any means.
----------------------------------------------------------------------
----------------------------------------------------------------------
zlib
(C) 1995-2017 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
[email protected] [email protected]
If you use the zlib library in a product, we would appreciate *not* receiving
lengthy legal documents to sign. The sources are provided for free but without
warranty of any kind. The library has been entirely written by Jean-loup
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.
----------------------------------------------------------------------
+18
View File
@@ -0,0 +1,18 @@
![ares logo](https://ares-emulator.github.io/images/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.
Official Releases
-----------------
Official releases are available from
[the ares website](https://ares-emu.net).
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.
+23 -2
View File
@@ -7,12 +7,17 @@ else ifneq ($(filter $(platform),linux bsd),)
options += -Wl,-export-dynamic
options += -lX11 -lXext
else
$(error "unsupported platform")
$(error "ares is a library and cannot be built directly.")
endif
ares.objects := ares
ares.objects := ares ares-fixed-allocator
$(object.path)/ares.o: $(ares.path)/ares/ares.cpp
$(object.path)/ares-fixed-allocator.o: $(ares.path)/ares/memory/fixed-allocator.cpp
ifeq ($(vulkan),true)
flags += -DVULKAN
endif
ifeq ($(profile),accuracy)
flags += -DPROFILE_ACCURACY
@@ -22,6 +27,10 @@ ifeq ($(profile),performance)
flags += -DPROFILE_PERFORMANCE
endif
ifneq ($(filter $(cores),a26),)
include $(ares.path)/a26/GNUmakefile
endif
ifneq ($(filter $(cores),fc),)
include $(ares.path)/fc/GNUmakefile
endif
@@ -46,6 +55,14 @@ ifneq ($(filter $(cores),md),)
include $(ares.path)/md/GNUmakefile
endif
ifneq ($(filter $(cores),saturn),)
include $(ares.path)/saturn/GNUmakefile
endif
ifneq ($(filter $(cores),ps1),)
include $(ares.path)/ps1/GNUmakefile
endif
ifneq ($(filter $(cores),pce),)
include $(ares.path)/pce/GNUmakefile
endif
@@ -70,6 +87,10 @@ ifneq ($(filter $(cores),ws),)
include $(ares.path)/ws/GNUmakefile
endif
ifneq ($(filter $(cores),ng),)
include $(ares.path)/ng/GNUmakefile
endif
ifneq ($(filter $(cores),ngp),)
include $(ares.path)/ngp/GNUmakefile
endif
+81
View File
@@ -0,0 +1,81 @@
#version 150
//anti-aliased nearest-neighbor
precision highp float;
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec4 vpow(vec4 n, float e) {
return vec4(pow(n.x, e), pow(n.y, e), pow(n.z, e), pow(n.w, e));
}
vec4 toLQV(vec3 c) {
return vec4(c.r, c.g, c.b, c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
}
vec3 fromLQV(vec4 c) {
float f = c.w / (c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
return vec3(c.rgb) * f;
}
vec3 percent(float ssize, float tsize, float coord) {
float minfull = (coord * tsize - 0.5) / tsize * ssize;
float maxfull = (coord * tsize + 0.5) / tsize * ssize;
float realfull = floor(maxfull);
if(minfull > realfull) {
return vec3(
1,
(realfull + 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
return vec3(
(maxfull - realfull) / (maxfull - minfull),
(realfull - 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
void main() {
float srgb = 2.1;
float gamma = 3.0;
vec3 x = percent(sourceSize[0].x, targetSize[0].x, texCoord.x);
vec3 y = percent(sourceSize[0].y, targetSize[0].y, texCoord.y);
//get points to interpolate across in linear RGB
vec4 a = toLQV(vpow(texture(source[0], vec2(x[1], y[1])), srgb).rgb);
vec4 b = toLQV(vpow(texture(source[0], vec2(x[2], y[1])), srgb).rgb);
vec4 c = toLQV(vpow(texture(source[0], vec2(x[1], y[2])), srgb).rgb);
vec4 d = toLQV(vpow(texture(source[0], vec2(x[2], y[2])), srgb).rgb);
//use perceptual gamma for luminance component
a.w = pow(a.w, 1 / gamma);
b.w = pow(b.w, 1 / gamma);
c.w = pow(c.w, 1 / gamma);
d.w = pow(d.w, 1 / gamma);
//interpolate
vec4 gammaLQV =
(1.0 - x[0]) * (1.0 - y[0]) * a +
(0.0 + x[0]) * (1.0 - y[0]) * b +
(1.0 - x[0]) * (0.0 + y[0]) * c +
(0.0 + x[0]) * (0.0 + y[0]) * d;
//convert luminance gamma back to linear
gammaLQV.w = pow(gammaLQV.w, gamma);
//convert color back to sRGB
fragColor = vpow(vec4(fromLQV(gammaLQV), 1), 1 / srgb);
}
+8
View File
@@ -0,0 +1,8 @@
input
filter: nearest
program
fragment: AANN.fs
output
filter: nearest
@@ -0,0 +1,10 @@
input
filter: nearest
program
filter: nearest
wrap: border
fragment: shadertoy.fs
output
filter: nearest
+145
View File
@@ -0,0 +1,145 @@
//
// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
//
// by Timothy Lottes
//
// This is more along the style of a really good CGA arcade monitor.
// With RGB inputs instead of NTSC.
// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
//
// Left it unoptimized to show the theory behind the algorithm.
//
// It is an example what I personally would want as a display option for pixel art games.
// Please take and use, change, or whatever.
//
#version 150
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform int phase;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
// Emulated input resolution.
vec2 res=sourceSize[0].xy;
// Hardness of scanline.
// -8.0 = soft
// -16.0 = medium
float hardScan=-8.0;
// Hardness of pixels in scanline.
// -2.0 = soft
// -4.0 = hard
float hardPix=-3.0;
// Display warp.
// 0.0 = none
// 1.0/8.0 = extreme
vec2 warp=vec2(1.0/32.0,1.0/24.0);
// Amount of shadow mask.
float maskDark=0.5;
float maskLight=1.5;
//------------------------------------------------------------------------
// sRGB to Linear.
// Assuing using sRGB typed textures this should not be needed.
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
// Linear to sRGB.
// Assuing using sRGB typed textures this should not be needed.
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
// Nearest emulated sample given floating point position and texel offset.
// Also zero's off screen.
vec3 Fetch(vec2 pos,vec2 off){
pos=(floor(pos*res+off)+vec2(0.5,0.5))/res;
return ToLinear(1.2 * texture(source[0],pos.xy,-16.0).rgb);}
// Distance in emulated pixels to nearest texel.
vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
// 1D Gaussian.
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
// 3-tap Gaussian filter along horz line.
vec3 Horz3(vec2 pos,float off){
vec3 b=Fetch(pos,vec2(-1.0,off));
vec3 c=Fetch(pos,vec2( 0.0,off));
vec3 d=Fetch(pos,vec2( 1.0,off));
float dst=Dist(pos).x;
// Convert distance to weight.
float scale=hardPix;
float wb=Gaus(dst-1.0,scale);
float wc=Gaus(dst+0.0,scale);
float wd=Gaus(dst+1.0,scale);
// Return filtered sample.
return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
// 5-tap Gaussian filter along horz line.
vec3 Horz5(vec2 pos,float off){
vec3 a=Fetch(pos,vec2(-2.0,off));
vec3 b=Fetch(pos,vec2(-1.0,off));
vec3 c=Fetch(pos,vec2( 0.0,off));
vec3 d=Fetch(pos,vec2( 1.0,off));
vec3 e=Fetch(pos,vec2( 2.0,off));
float dst=Dist(pos).x;
// Convert distance to weight.
float scale=hardPix;
float wa=Gaus(dst-2.0,scale);
float wb=Gaus(dst-1.0,scale);
float wc=Gaus(dst+0.0,scale);
float wd=Gaus(dst+1.0,scale);
float we=Gaus(dst+2.0,scale);
// Return filtered sample.
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
// Return scanline weight.
float Scan(vec2 pos,float off){
float dst=Dist(pos).y;
return Gaus(dst+off,hardScan);}
// Allow nearest three lines to effect pixel.
vec3 Tri(vec2 pos){
vec3 a=Horz3(pos,-1.0);
vec3 b=Horz5(pos, 0.0);
vec3 c=Horz3(pos, 1.0);
float wa=Scan(pos,-1.0);
float wb=Scan(pos, 0.0);
float wc=Scan(pos, 1.0);
return a*wa+b*wb+c*wc;}
// Distortion of scanlines, and end of screen alpha.
vec2 Warp(vec2 pos){
pos=pos*2.0-1.0;
pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
return pos*0.5+0.5;}
// Shadow mask.
vec3 Mask(vec2 pos){
pos.x+=pos.y*3.0;
vec3 mask=vec3(maskDark,maskDark,maskDark);
pos.x=fract(pos.x/6.0);
if(pos.x<0.333)mask.r=maskLight;
else if(pos.x<0.666)mask.g=maskLight;
else mask.b=maskLight;
return mask;}
void main() {
vec2 pos = texCoord.xy * 1.0001;
hardScan=-12.0;
// maskDark=maskLight;
pos=Warp(pos.xy);
fragColor.rgb=Tri(pos)*Mask(gl_FragCoord.xy);
fragColor.a=1.0;
fragColor = vec4(ToSrgb(fragColor.rgb), fragColor.a);
}
+609
View File
@@ -0,0 +1,609 @@
#version 150
//_____________________________/\_______________________________
//==============================================================
//
//
// [CRTS] PUBLIC DOMAIN CRT-STYLED SCALAR - 20180120b
//
// by Timothy Lottes
// https://www.shadertoy.com/view/MtSfRK
// adapted for quark syntax by hunterk
//
//
//==============================================================
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//_____________________________/\_______________________________
//==============================================================
//
// WHAT'S NEW
//
//--------------------------------------------------------------
// Evolution of prior shadertoy example
//--------------------------------------------------------------
// This one is semi-optimized
// - Less texture fetches
// - Didn't get to instruction level optimization
// - Could likely use texture fetch to generate phosphor mask
//--------------------------------------------------------------
// Added options to disable unused features
//--------------------------------------------------------------
// Added in exposure matching
// - Given scan-line effect and mask always darkens image
// - Uses generalized tonemapper to boost mid-level
// - Note this can compress highlights
// - And won't get back peak brightness
// - But best option if one doesn't want as much darkening
//--------------------------------------------------------------
// Includes option saturation and contrast controls
//--------------------------------------------------------------
// Added in subtractive aperture grille
// - This is a bit brighter than prior
//--------------------------------------------------------------
// Make sure input to this filter is already low-resolution
// - This is not designed to work on titles doing the following
// - Rendering to hi-res with nearest sampling
//--------------------------------------------------------------
// Added a fast and more pixely option for 2 tap/pixel
//--------------------------------------------------------------
// Improved the vignette when WARP is enabled
//--------------------------------------------------------------
// Didn't test HLSL or CPU options
// - Will incorportate patches if they are broken
// - But out of time to try them myself
//==============================================================
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//_____________________________/\_______________________________
//==============================================================
//
// LICENSE = UNLICENSE (aka PUBLIC DOMAIN)
//
//--------------------------------------------------------------
// This is free and unencumbered software released into the
// public domain.
//--------------------------------------------------------------
// Anyone is free to copy, modify, publish, use, compile, sell,
// or distribute this software, either in source code form or as
// a compiled binary, for any purpose, commercial or
// non-commercial, and by any means.
//--------------------------------------------------------------
// In jurisdictions that recognize copyright laws, the author or
// authors of this software dedicate any and all copyright
// interest in the software to the public domain. We make this
// dedication for the benefit of the public at large and to the
// detriment of our heirs and successors. We intend this
// dedication to be an overt act of relinquishment in perpetuity
// of all present and future rights to this software under
// copyright law.
//--------------------------------------------------------------
// 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 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.
//--------------------------------------------------------------
// For more information, please refer to
// <http://unlicense.org/>
//==============================================================
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
#define MASK 1.0
#define MASK_INTENSITY 0.5
#define SCANLINE_THINNESS 0.5
#define SCAN_BLUR 2.5
#define CURVATURE 0.02
#define TRINITRON_CURVE 0.0
#define CORNER 3.0
#define CRT_GAMMA 2.4
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 outputSize;
in Vertex {
vec2 vTexCoord;
};
out vec4 FragColor;
//_____________________________/\_______________________________
//==============================================================
//
// GAMMA FUNCTIONS
//
//--------------------------------------------------------------
//--------------------------------------------------------------
// Since shadertoy doesn't have sRGB textures
// And we need linear input into shader
// Don't do this in your code
float FromSrgb1(float c){
return (c<=0.04045)?c*(1.0/12.92):
pow(c*(1.0/1.055)+(0.055/1.055),CRT_GAMMA);}
//--------------------------------------------------------------
vec3 FromSrgb(vec3 c){return vec3(
FromSrgb1(c.r),FromSrgb1(c.g),FromSrgb1(c.b));}
// Convert from linear to sRGB
// Since shader toy output is not linear
float ToSrgb1(float c){
return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
//--------------------------------------------------------------
vec3 ToSrgb(vec3 c){return vec3(
ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
//--------------------------------------------------------------
//_____________________________/\_______________________________
//==============================================================
//
// DEFINES
//
//--------------------------------------------------------------
// CRTS_CPU - CPU code
// CRTS_GPU - GPU code
//--------------------------------------------------------------
// CRTS_GLSL - GLSL
// CRTS_HLSL - HLSL (not tested yet)
//--------------------------------------------------------------
// CRTS_DEBUG - Define to see on/off split screen
//--------------------------------------------------------------
// CRTS_WARP - Apply screen warp
//--------------------------------------------------------------
// CRTS_2_TAP - Faster very pixely 2-tap filter (off is 8)
//--------------------------------------------------------------
// CRTS_MASK_GRILLE - Aperture grille (aka Trinitron)
// CRTS_MASK_GRILLE_LITE - Brighter (subtractive channels)
// CRTS_MASK_NONE - No mask
// CRTS_MASK_SHADOW - Horizontally stretched shadow mask
//--------------------------------------------------------------
// CRTS_TONE - Normalize mid-level and process color
// CRTS_CONTRAST - Process color - enable contrast control
// CRTS_SATURATION - Process color - enable saturation control
//--------------------------------------------------------------
#define CRTS_STATIC
#define CrtsPow
#define CRTS_RESTRICT
//==============================================================
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//==============================================================
// SETUP FOR CRTS
//--------------------------------------------------------------
//==============================================================
//#define CRTS_DEBUG 1
#define CRTS_GPU 1
#define CRTS_GLSL 1
//--------------------------------------------------------------
//#define CRTS_2_TAP 1
//--------------------------------------------------------------
#define CRTS_TONE 1
#define CRTS_CONTRAST 0
#define CRTS_SATURATION 0
//--------------------------------------------------------------
#define CRTS_WARP 1
//--------------------------------------------------------------
// Try different masks -> moved to runtime parameters
//#define CRTS_MASK_GRILLE 1
//#define CRTS_MASK_GRILLE_LITE 1
//#define CRTS_MASK_NONE 1
//#define CRTS_MASK_SHADOW 1
//--------------------------------------------------------------
// Scanline thinness
// 0.50 = fused scanlines
// 0.70 = recommended default
// 1.00 = thinner scanlines (too thin)
#define INPUT_THIN (0.5 + (0.5 * SCANLINE_THINNESS))
//--------------------------------------------------------------
// Horizonal scan blur
// -3.0 = pixely
// -2.5 = default
// -2.0 = smooth
// -1.0 = too blurry
#define INPUT_BLUR (-1.0 * SCAN_BLUR)
//--------------------------------------------------------------
// Shadow mask effect, ranges from,
// 0.25 = large amount of mask (not recommended, too dark)
// 0.50 = recommended default
// 1.00 = no shadow mask
#define INPUT_MASK (1.0 - MASK_INTENSITY)
//--------------------------------------------------------------
#define INPUT_X sourceSize[0].x
#define INPUT_Y sourceSize[0].y
//--------------------------------------------------------------
// Setup the function which returns input image color
vec3 CrtsFetch(vec2 uv){
// For shadertoy, scale to get native texels in the image
uv*=vec2(INPUT_X,INPUT_Y)/sourceSize[0].xy;
// Move towards intersting parts
// uv+=vec2(0.5,0.5);
// Non-shadertoy case would not have the color conversion
return FromSrgb(texture(source[0],uv.xy,-16.0).rgb);}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//_____________________________/\_______________________________
//==============================================================
//
// GPU CODE
//
//==============================================================
#ifdef CRTS_GPU
//_____________________________/\_______________________________
//==============================================================
// PORTABILITY
//==============================================================
#ifdef CRTS_GLSL
#define CrtsF1 float
#define CrtsF2 vec2
#define CrtsF3 vec3
#define CrtsF4 vec4
#define CrtsFractF1 fract
#define CrtsRcpF1(x) (1.0/(x))
#define CrtsSatF1(x) clamp((x),0.0,1.0)
//--------------------------------------------------------------
CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){
return max(a,max(b,c));}
#endif
//==============================================================
#ifdef CRTS_HLSL
#define CrtsF1 float
#define CrtsF2 float2
#define CrtsF3 float3
#define CrtsF4 float4
#define CrtsFractF1 frac
#define CrtsRcpF1(x) (1.0/(x))
#define CrtsSatF1(x) saturate(x)
//--------------------------------------------------------------
CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){
return max(a,max(b,c));}
#endif
//_____________________________/\_______________________________
//==============================================================
// TONAL CONTROL CONSTANT GENERATION
//--------------------------------------------------------------
// This is in here for rapid prototyping
// Please use the CPU code and pass in as constants
//==============================================================
CrtsF4 CrtsTone(
CrtsF1 contrast,
CrtsF1 saturation,
CrtsF1 thin,
CrtsF1 mask){
//--------------------------------------------------------------
if(MASK == 0.0) mask=1.0;
//--------------------------------------------------------------
if(MASK == 1.0){
// Normal R mask is {1.0,mask,mask}
// LITE R mask is {mask,1.0,1.0}
mask=0.5+mask*0.5;
}
//--------------------------------------------------------------
CrtsF4 ret;
CrtsF1 midOut=0.18/((1.5-thin)*(0.5*mask+0.5));
CrtsF1 pMidIn=pow(0.18,contrast);
ret.x=contrast;
ret.y=((-pMidIn)+midOut)/((1.0-pMidIn)*midOut);
ret.z=((-pMidIn)*midOut+pMidIn)/(midOut*(-pMidIn)+midOut);
ret.w=contrast+saturation;
return ret;}
//_____________________________/\_______________________________
//==============================================================
// MASK
//--------------------------------------------------------------
// Letting LCD/OLED pixel elements function like CRT phosphors
// So "phosphor" resolution scales with display resolution
//--------------------------------------------------------------
// Not applying any warp to the mask (want high frequency)
// Real aperture grille has a mask which gets wider on ends
// Not attempting to be "real" but instead look the best
//--------------------------------------------------------------
// Shadow mask is stretched horizontally
// RRGGBB
// GBBRRG
// RRGGBB
// This tends to look better on LCDs than vertical
// Also 2 pixel width is required to get triad centered
//--------------------------------------------------------------
// The LITE version of the Aperture Grille is brighter
// Uses {dark,1.0,1.0} for R channel
// Non LITE version uses {1.0,dark,dark}
//--------------------------------------------------------------
// 'pos' - This is 'fragCoord.xy'
// Pixel {0,0} should be {0.5,0.5}
// Pixel {1,1} should be {1.5,1.5}
//--------------------------------------------------------------
// 'dark' - Exposure of of masked channel
// 0.0=fully off, 1.0=no effect
//==============================================================
CrtsF3 CrtsMask(CrtsF2 pos,CrtsF1 dark){
if(MASK == 2.0){
CrtsF3 m=CrtsF3(dark,dark,dark);
CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0));
if(x<(1.0/3.0))m.r=1.0;
else if(x<(2.0/3.0))m.g=1.0;
else m.b=1.0;
return m;
}
//--------------------------------------------------------------
if(MASK == 1.0){
CrtsF3 m=CrtsF3(1.0,1.0,1.0);
CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0));
if(x<(1.0/3.0))m.r=dark;
else if(x<(2.0/3.0))m.g=dark;
else m.b=dark;
return m;
}
//--------------------------------------------------------------
if(MASK == 0.0){
return CrtsF3(1.0,1.0,1.0);
}
//--------------------------------------------------------------
if(MASK == 3.0){
pos.x+=pos.y*2.9999;
CrtsF3 m=CrtsF3(dark,dark,dark);
CrtsF1 x=CrtsFractF1(pos.x*(1.0/6.0));
if(x<(1.0/3.0))m.r=1.0;
else if(x<(2.0/3.0))m.g=1.0;
else m.b=1.0;
return m;
}
}
//_____________________________/\_______________________________
//==============================================================
// FILTER ENTRY
//--------------------------------------------------------------
// Input must be linear
// Output color is linear
//--------------------------------------------------------------
// Must have fetch function setup: CrtsF3 CrtsFetch(CrtsF2 uv)
// - The 'uv' range is {0.0 to 1.0} for input texture
// - Output of this must be linear color
//--------------------------------------------------------------
// SCANLINE MATH & AUTO-EXPOSURE NOTES
// ===================================
// Each output line has contribution from at most 2 scanlines
// Scanlines are shaped by a windowed cosine function
// This shape blends together well with only 2 lines of overlap
//--------------------------------------------------------------
// Base scanline intensity is as follows
// which leaves output intensity range from {0 to 1.0}
// --------
// thin := range {thick 0.5 to thin 1.0}
// off := range {0.0 to <1.0},
// sub-pixel offset between two scanlines
// --------
// a0=cos(min(0.5, off *thin)*2pi)*0.5+0.5;
// a1=cos(min(0.5,(1.0-off)*thin)*2pi)*0.5+0.5;
//--------------------------------------------------------------
// This leads to a image darkening factor of roughly:
// {(1.5-thin)/1.0}
// This is further reduced by the mask:
// {1.0/2.0+mask*1.0/2.0}
// Reciprocal of combined effect is used for auto-exposure
// to scale up the mid-level in the tonemapper
//==============================================================
CrtsF3 CrtsFilter(
//--------------------------------------------------------------
// SV_POSITION, fragCoord.xy
CrtsF2 ipos,
//--------------------------------------------------------------
// inputSize / outputSize (in pixels)
CrtsF2 inputSizeDivOutputSize,
//--------------------------------------------------------------
// 0.5 * inputSize (in pixels)
CrtsF2 halfInputSize,
//--------------------------------------------------------------
// 1.0 / inputSize (in pixels)
CrtsF2 rcpInputSize,
//--------------------------------------------------------------
// 1.0 / outputSize (in pixels)
CrtsF2 rcpOutputSize,
//--------------------------------------------------------------
// 2.0 / outputSize (in pixels)
CrtsF2 twoDivOutputSize,
//--------------------------------------------------------------
// inputSize.y
CrtsF1 inputHeight,
//--------------------------------------------------------------
// Warp scanlines but not phosphor mask
// 0.0 = no warp
// 1.0/64.0 = light warping
// 1.0/32.0 = more warping
// Want x and y warping to be different (based on aspect)
CrtsF2 warp,
//--------------------------------------------------------------
// Scanline thinness
// 0.50 = fused scanlines
// 0.70 = recommended default
// 1.00 = thinner scanlines (too thin)
// Shared with CrtsTone() function
CrtsF1 thin,
//--------------------------------------------------------------
// Horizonal scan blur
// -3.0 = pixely
// -2.5 = default
// -2.0 = smooth
// -1.0 = too blurry
CrtsF1 blur,
//--------------------------------------------------------------
// Shadow mask effect, ranges from,
// 0.25 = large amount of mask (not recommended, too dark)
// 0.50 = recommended default
// 1.00 = no shadow mask
// Shared with CrtsTone() function
CrtsF1 mask,
//--------------------------------------------------------------
// Tonal curve parameters generated by CrtsTone()
CrtsF4 tone
//--------------------------------------------------------------
){
//--------------------------------------------------------------
#ifdef CRTS_DEBUG
CrtsF2 uv=ipos*rcpOutputSize;
// Show second half processed, and first half un-processed
if(uv.x<0.5){
// Force nearest to get squares
uv*=1.0/rcpInputSize;
uv=floor(uv)+CrtsF2(0.5,0.5);
uv*=rcpInputSize;
CrtsF3 color=CrtsFetch(uv);
return color;}
#endif
//--------------------------------------------------------------
// Optional apply warp
CrtsF2 pos;
#ifdef CRTS_WARP
// Convert to {-1 to 1} range
pos=ipos*twoDivOutputSize-CrtsF2(1.0,1.0);
// Distort pushes image outside {-1 to 1} range
pos*=CrtsF2(
1.0+(pos.y*pos.y)*warp.x,
1.0+(pos.x*pos.x)*warp.y);
// TODO: Vignette needs optimization
CrtsF1 vin=(1.0-(
(1.0-CrtsSatF1(pos.x*pos.x))*(1.0-CrtsSatF1(pos.y*pos.y)))) * (0.998 + (0.001 * CORNER));
vin=CrtsSatF1((-vin)*inputHeight+inputHeight);
// Leave in {0 to inputSize}
pos=pos*halfInputSize+halfInputSize;
#else
pos=ipos*inputSizeDivOutputSize;
#endif
//--------------------------------------------------------------
// Snap to center of first scanline
CrtsF1 y0=floor(pos.y-0.5)+0.5;
#ifdef CRTS_2_TAP
// Using Inigo's "Improved Texture Interpolation"
// http://iquilezles.org/www/articles/texture/texture.htm
pos.x+=0.5;
CrtsF1 xi=floor(pos.x);
CrtsF1 xf=pos.x-xi;
xf=xf*xf*xf*(xf*(xf*6.0-15.0)+10.0);
CrtsF1 x0=xi+xf-0.5;
CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y);
// Coordinate adjusted bilinear fetch from 2 nearest scanlines
CrtsF3 colA=CrtsFetch(p);
p.y+=rcpInputSize.y;
CrtsF3 colB=CrtsFetch(p);
#else
// Snap to center of one of four pixels
CrtsF1 x0=floor(pos.x-1.5)+0.5;
// Inital UV position
CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y);
// Fetch 4 nearest texels from 2 nearest scanlines
CrtsF3 colA0=CrtsFetch(p);
p.x+=rcpInputSize.x;
CrtsF3 colA1=CrtsFetch(p);
p.x+=rcpInputSize.x;
CrtsF3 colA2=CrtsFetch(p);
p.x+=rcpInputSize.x;
CrtsF3 colA3=CrtsFetch(p);
p.y+=rcpInputSize.y;
CrtsF3 colB3=CrtsFetch(p);
p.x-=rcpInputSize.x;
CrtsF3 colB2=CrtsFetch(p);
p.x-=rcpInputSize.x;
CrtsF3 colB1=CrtsFetch(p);
p.x-=rcpInputSize.x;
CrtsF3 colB0=CrtsFetch(p);
#endif
//--------------------------------------------------------------
// Vertical filter
// Scanline intensity is using sine wave
// Easy filter window and integral used later in exposure
CrtsF1 off=pos.y-y0;
CrtsF1 pi2=6.28318530717958;
CrtsF1 hlf=0.5;
CrtsF1 scanA=cos(min(0.5, off *thin )*pi2)*hlf+hlf;
CrtsF1 scanB=cos(min(0.5,(-off)*thin+thin)*pi2)*hlf+hlf;
//--------------------------------------------------------------
#ifdef CRTS_2_TAP
#ifdef CRTS_WARP
// Get rid of wrong pixels on edge
scanA*=vin;
scanB*=vin;
#endif
// Apply vertical filter
CrtsF3 color=(colA*scanA)+(colB*scanB);
#else
// Horizontal kernel is simple gaussian filter
CrtsF1 off0=pos.x-x0;
CrtsF1 off1=off0-1.0;
CrtsF1 off2=off0-2.0;
CrtsF1 off3=off0-3.0;
CrtsF1 pix0=exp2(blur*off0*off0);
CrtsF1 pix1=exp2(blur*off1*off1);
CrtsF1 pix2=exp2(blur*off2*off2);
CrtsF1 pix3=exp2(blur*off3*off3);
CrtsF1 pixT=CrtsRcpF1(pix0+pix1+pix2+pix3);
#ifdef CRTS_WARP
// Get rid of wrong pixels on edge
pixT*=vin;
#endif
scanA*=pixT;
scanB*=pixT;
// Apply horizontal and vertical filters
CrtsF3 color=
(colA0*pix0+colA1*pix1+colA2*pix2+colA3*pix3)*scanA +
(colB0*pix0+colB1*pix1+colB2*pix2+colB3*pix3)*scanB;
#endif
//--------------------------------------------------------------
// Apply phosphor mask
color*=CrtsMask(ipos,mask);
//--------------------------------------------------------------
// Optional color processing
#ifdef CRTS_TONE
// Tonal control, start by protecting from /0
CrtsF1 peak=max(1.0/(256.0*65536.0),
CrtsMax3F1(color.r,color.g,color.b));
// Compute the ratios of {R,G,B}
CrtsF3 ratio=color*CrtsRcpF1(peak);
// Apply tonal curve to peak value
#ifdef CRTS_CONTRAST
peak=pow(peak,tone.x);
#endif
peak=peak*CrtsRcpF1(peak*tone.y+tone.z);
// Apply saturation
#ifdef CRTS_SATURATION
ratio=pow(ratio,CrtsF3(tone.w,tone.w,tone.w));
#endif
// Reconstruct color
return ratio*peak;
#else
return color;
#endif
//--------------------------------------------------------------
}
#endif
void main() {
vec2 warp_factor;
warp_factor.x = CURVATURE;
warp_factor.y = (3.0 / 4.0) * warp_factor.x; // assume 4:3 aspect
warp_factor.x *= (1.0 - TRINITRON_CURVE);
FragColor.rgb = CrtsFilter(vTexCoord.xy * outputSize.xy,
sourceSize[0].xy * outputSize.zw,
sourceSize[0].xy * vec2(0.5,0.5),
sourceSize[0].zw,
outputSize.zw,
2.0 * outputSize.zw,
sourceSize[0].y,
warp_factor,
INPUT_THIN,
INPUT_BLUR,
INPUT_MASK,
CrtsTone(1.0,0.0,INPUT_THIN,INPUT_MASK));
// Shadertoy outputs non-linear color
FragColor.rgb = ToSrgb(FragColor.rgb);
}
+16
View File
@@ -0,0 +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;
}
@@ -0,0 +1,12 @@
input
filter: nearest
program
filter: nearest
vertex: lottes.vs
fragment: lottes.fs
output
height: 0
width: 0
filter: linear
@@ -0,0 +1,21 @@
#version 150
#define distortion 0.2
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec2 radialDistortion(vec2 coord) {
vec2 cc = coord - vec2(0.5);
float dist = dot(cc, cc) * distortion;
return coord + cc * (1.0 - dist) * dist;
}
void main() {
fragColor = texture(source[0], radialDistortion(texCoord));
}
@@ -0,0 +1,4 @@
program
filter: linear
wrap: border
fragment: curvature.fs
@@ -0,0 +1,25 @@
#version 150
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec3 grayscale(vec3 color) {
return vec3(dot(color, vec3(0.3, 0.59, 0.11)));
}
void main() {
vec2 offset = fract(texCoord * sourceSize[0].xy) - 0.5;
offset /= sourceSize[0].xy;
vec3 cx = texture(source[0], texCoord - offset).xyz;
vec3 cy = texture(source[0], texCoord).xyz;
vec3 cz = vec3(5.0 * grayscale(abs(cx - cy)));
fragColor = vec4(clamp(cz, 0.0, 1.0), 1.0);
}
@@ -0,0 +1,4 @@
program
filter: linear
wrap: edge
fragment: edge-detection.fs
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,99 @@
#version 150
// GritsScanlines by torridgristle
// license: public domain (https://forums.libretro.com/t/lightweight-lut-based-scanline-glow-concept-prototype-glsl/18336/7)
/* Runtime parameters
#in LuminanceDawnbringer
#in LuminanceLUT
#in ScanlinesOpacity
#in GammaCorrection
#in TrinitronColors
*/
// static parameters
//#define LuminanceDawnbringer
#define LuminanceLUT
//#define TrinitronColors
#define ScanlinesOpacity 0.9
//#define GammaCorrection 1.2
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize;
uniform sampler2D pixmap[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
#ifdef LuminanceLUT
#define LUT_SizeLum 16.0
// 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);
}
#endif
#ifdef TrinitronColors
#define LUT_SizeTrinitron 32.0
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);
}
#endif
void main() {
//Source Image
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);
#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;
#else
// Plain, standard, fine; slightly faster
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);
// 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));
// Scanline Layer
vec4 screen = texture(pixmap[0], LUTeffectiveCoord);
// Output multiplying the scanlines into the original image, with control over opacity
#ifdef TrinitronColors
org = TrinitronD50(org);
#endif
fragColor = ((screen*ScanlinesOpacity)+(1.0 - ScanlinesOpacity)) * (org);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

@@ -0,0 +1,35 @@
settings
LuminanceDawnbringer
active: false
LuminanceLUT
active: false
TrinitronColors
active: true
ScanlinesOpacity: 0.9
min: 0.0
max: 1.0
step: 0.05
GammaCorrection: 1.2
min: 0.5
max: 2.0
step: 0.1
program
filter: nearest
wrap: edge
width: 100%
height: 400%
fragment: GritsScanlines.fs
pixmap: Scanline-LUT-4px.png
filter: linear
wrap: edge
pixmap: Fake-Self-Illumination.png
filter: linear
wrap: edge
pixmap: Trinitron D50 Absolute Colorimetric - LUT.png
filter: linear
wrap: edge
output1
filter: linear
@@ -0,0 +1,39 @@
#version 150
/*
Interlacing
Author: hunterk
License: Public domain
Note: This shader is designed to work with the typical interlaced output from an emulator, which displays both even and odd fields twice.
This shader will un-weave the image, resulting in a standard, alternating-field interlacing.
*/
uniform sampler2D source[];
uniform vec2 targetSize;
uniform vec4 sourceSize[];
uniform int phase;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
// This controls how bright the intermediate lines are; 0.0 = totally black
#define percent 0.0
void main()
{
vec4 res = texture(source[0], texCoord);
float y = 0.0;
// assume anything with a vertical resolution greater than 400 lines is interlaced
if (sourceSize[0].y > 400.0) y = sourceSize[0].y * texCoord.y + phase;
else
y = 2.00001 * sourceSize[0].y * texCoord.y;
if (mod(y, 2.0) > 0.99999) fragColor = res;
else
fragColor = vec4(percent) * res;
}
@@ -0,0 +1,6 @@
input
filter: nearest
program
fragment: interlace.fs
modulo: 2
@@ -0,0 +1,11 @@
input
filter: nearest
program
filter: nearest
height: 100%
fragment: pal-r57shell.fs
output
height: 0
filter: linear
@@ -0,0 +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
}
@@ -0,0 +1,2 @@
program
fragment: phosphorish.fs
@@ -0,0 +1,56 @@
/* Phosphorish
Copyright (C) 2011 Themaister
This program is licensed in the public domain
*/
#version 150
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec3 to_focus(float pixel)
{
pixel = mod(pixel + 3.0, 3.0);
if (pixel >= 2.0) // Blue
return vec3(pixel - 2.0, 0.0, 3.0 - pixel);
else if (pixel >= 1.0) // Green
return vec3(0.0, 2.0 - pixel, pixel - 1.0);
else // Red
return vec3(1.0 - pixel, pixel, 0.0);
}
void main()
{
float y = mod(texCoord.y * sourceSize[0].y, 1.0);
float intensity = exp(-0.2 * y);
vec2 one_x = vec2(1.0 / (3.0 * sourceSize[0].x), 0.0);
vec3 color = texture(source[0], texCoord.xy - 0.0 * one_x).rgb;
vec3 color_prev = texture(source[0], texCoord.xy - 1.0 * one_x).rgb;
vec3 color_prev_prev = texture(source[0], texCoord.xy - 2.0 * one_x).rgb;
float pixel_x = 3.0 * texCoord.x * sourceSize[0].x;
vec3 focus = to_focus(pixel_x - 0.0);
vec3 focus_prev = to_focus(pixel_x - 1.0);
vec3 focus_prev_prev = to_focus(pixel_x - 2.0);
vec3 result =
0.8 * color * focus +
0.6 * color_prev * focus_prev +
0.3 * color_prev_prev * focus_prev_prev;
result = 2.3 * pow(result, vec3(1.4));
fragColor = vec4(intensity * result, 1.0);
}
@@ -0,0 +1,4 @@
program
filter: linear
wrap: border
fragment: scanline.fs
+20
View File
@@ -0,0 +1,20 @@
#version 150
uniform sampler2D source[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
void main() {
vec4 rgba = texture(source[0], texCoord);
vec4 intensity;
if(fract(gl_FragCoord.y * (0.5 * 4.0 / 3.0)) > 0.5) {
intensity = vec4(0);
} else {
intensity = smoothstep(0.2, 0.8, rgba) + normalize(rgba);
}
fragColor = intensity * -0.25 + rgba * 1.1;
}
@@ -0,0 +1,8 @@
input
filter: linear
program
fragment: sharp-bilinear.fs
output
filter: linear
@@ -0,0 +1,33 @@
#version 150
// Sharp Bilinear
// Author: Themaister
// License: Public Domain
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize;
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
void main() {
float prescale = floor(targetSize.y / sourceSize[0].y);
vec2 texel = texCoord.xy * sourceSize[0].xy;
vec2 texel_floored = floor(texel);
vec2 s = fract(texel);
float region_range = 0.5 - 0.5 / prescale;
// Figure out where in the texel to sample to get correct pre-scaled bilinear.
// Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
vec2 center_dist = s - 0.5;
vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * prescale + 0.5;
vec2 mod_texel = texel_floored + f;
fragColor = texture(source[0], mod_texel / sourceSize[0].xy);;
}
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
+12 -4
View File
@@ -1,5 +1,5 @@
database
revision: 2020-01-21
revision: 2020-11-09
//Boards (Production)
@@ -587,7 +587,7 @@ board: SHVC-YJ0N-01
//Boards (Generic)
database
revision: 2020-01-01
revision: 2020-11-09
board: ARM-LOROM-RAM
memory type=ROM content=Program
@@ -706,7 +706,6 @@ board: EXHIROM-RAM
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
map address=70-7d:0000-7fff
board: EXHIROM-RAM-SHARPRTC
memory type=ROM content=Program
@@ -716,7 +715,6 @@ board: EXHIROM-RAM-SHARPRTC
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
map address=70-7d:0000-7fff
rtc manufacturer=Sharp
map address=00-3f,80-bf:2800-2801
memory type=RTC content=Time manufacturer=Sharp
@@ -887,6 +885,16 @@ board: OBC1-LOROM-RAM
map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000
memory type=RAM content=Save
board: SA1
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SA1-RAM
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
+15
View File
@@ -0,0 +1,15 @@
ares.components += mos6502
ares.objects += ares-a26-system
ares.objects += ares-a26-controller
ares.objects += ares-a26-cartridge
ares.objects += ares-a26-cpu
ares.objects += ares-a26-tia
ares.objects += ares-a26-riot
$(object.path)/ares-a26-system.o: $(ares.path)/a26/system/system.cpp
$(object.path)/ares-a26-controller.o: $(ares.path)/a26/controller/controller.cpp
$(object.path)/ares-a26-cartridge.o: $(ares.path)/a26/cartridge/cartridge.cpp
$(object.path)/ares-a26-cpu.o: $(ares.path)/a26/cpu/cpu.cpp
$(object.path)/ares-a26-tia.o: $(ares.path)/a26/tia/tia.cpp
$(object.path)/ares-a26-riot.o: $(ares.path)/a26/riot/riot.cpp
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <ares/ares.hpp>
#include <component/processor/mos6502/mos6502.hpp>
namespace ares::Atari2600 {
#include <ares/inline.hpp>
auto enumerate() -> vector<string>;
auto load(Node::System& node, string name) -> bool;
struct Region {
static inline auto NTSC() -> bool;
static inline auto PAL() -> bool;
static inline auto SECAM() -> bool;
};
#include <a26/controller/controller.hpp>
#include <a26/system/system.hpp>
#include <a26/cartridge/cartridge.hpp>
#include <a26/cpu/cpu.hpp>
#include <a26/tia/tia.hpp>
#include <a26/riot/riot.hpp>
}
+58
View File
@@ -0,0 +1,58 @@
struct Atari16k : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
Memory::Writable<n8> ram;
n2 bank;
bool hasRam;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address == 0x1ff6) bank = 0;
if(address == 0x1ff7) bank = 1;
if(address == 0x1ff8) bank = 2;
if(address == 0x1ff9) bank = 3;
if(address.bit(12)) {
if(hasRam && address >= 0x1080 && address <= 0x10ff) return ram.read(address & 0x7f);
return rom.read((bank * 0x1000) + (address & 0xfff));
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address == 0x1ff6) bank = 0;
if(address == 0x1ff7) bank = 1;
if(address == 0x1ff8) bank = 2;
if(address == 0x1ff9) bank = 3;
if(address >= 0x1000 && address <= 0x107f) {
hasRam = true;
ram.write(address & 0x7f, data);
return true;
}
return false;
}
auto power() -> void override {
bank = 0;
hasRam = 0;
ram.allocate(128);
}
auto serialize(serializer& s) -> void override {
s(bank);
s(hasRam);
s(ram);
}
};
+66
View File
@@ -0,0 +1,66 @@
struct Atari32k : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
Memory::Writable<n8> ram;
n3 bank;
bool hasRam;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address == 0x1ff4) bank = 0;
if(address == 0x1ff5) bank = 1;
if(address == 0x1ff6) bank = 2;
if(address == 0x1ff7) bank = 3;
if(address == 0x1ff8) bank = 4;
if(address == 0x1ff9) bank = 5;
if(address == 0x1ffa) bank = 6;
if(address == 0x1ffb) bank = 7;
if(address.bit(12)) {
if(hasRam && address >= 0x1080 && address <= 0x10ff) return ram.read(address & 0x7f);
return rom.read((bank * 0x1000) + (address & 0xfff));
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address == 0x1ff4) bank = 0;
if(address == 0x1ff5) bank = 1;
if(address == 0x1ff6) bank = 2;
if(address == 0x1ff7) bank = 3;
if(address == 0x1ff8) bank = 4;
if(address == 0x1ff9) bank = 5;
if(address == 0x1ffa) bank = 6;
if(address == 0x1ffb) bank = 7;
if(address >= 0x1000 && address <= 0x107f) {
hasRam = true;
ram.write(address & 0x7f, data);
return true;
}
return false;
}
auto power() -> void override {
bank = 0;
hasRam = 0;
ram.allocate(128);
}
auto serialize(serializer& s) -> void override {
s(bank);
s(hasRam);
s(ram);
}
};
+54
View File
@@ -0,0 +1,54 @@
struct Atari8k : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
Memory::Writable<n8> ram;
n1 bank;
bool hasRam;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address == 0x1ff8) bank = 0;
if(address == 0x1ff9) bank = 1;
if(address.bit(12)) {
if(hasRam && address >= 0x1080 && address <= 0x10ff) return ram.read(address & 0x7f);
return rom.read((bank * 0x1000) + (address & 0xfff));
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address == 0x1ff8) bank = 0;
if(address == 0x1ff9) bank = 1;
if(address >= 0x1000 && address <= 0x107f) {
hasRam = true;
ram.write(address & 0x7f, data);
return true;
}
return false;
}
auto power() -> void override {
bank = 0;
hasRam = 0;
ram.allocate(128);
}
auto serialize(serializer& s) -> void override {
s(bank);
s(hasRam);
s(ram);
}
};
+37
View File
@@ -0,0 +1,37 @@
namespace Board {
#include "linear.cpp"
#include "atari8k.cpp"
#include "atari16k.cpp"
#include "atari32k.cpp"
#include "commavid.cpp"
#include "parker-bros.cpp"
#include "tigervision.cpp"
auto Interface::load(Memory::Readable<n8>& memory, string name) -> bool {
if(auto fp = pak->read(name)) {
memory.allocate(fp->size());
memory.load(fp);
return true;
}
return false;
}
auto Interface::load(Memory::Writable<n8>& memory, string name) -> bool {
if(auto fp = pak->read(name)) {
memory.allocate(fp->size());
memory.load(fp);
return true;
}
return false;
}
auto Interface::save(Memory::Writable<n8>& memory, string name) -> bool {
if(auto fp = pak->write(name)) {
memory.save(fp);
return true;
}
return false;
}
}
+23
View File
@@ -0,0 +1,23 @@
namespace Board {
struct Interface {
VFS::Pak pak;
Interface(Cartridge& cartridge) : cartridge(cartridge) {}
virtual ~Interface() = default;
virtual auto load() -> void {}
virtual auto save() -> void {}
virtual auto unload() -> void {}
virtual auto read(n16 address) -> n8 { return 0xff; }
virtual auto write(n16 address, n8 data) -> bool { return false; }
virtual auto power() -> void {}
virtual auto serialize(serializer&) -> void {}
auto load(Memory::Readable<n8>&, string name) -> bool;
auto load(Memory::Writable<n8>&, string name) -> bool;
auto save(Memory::Writable<n8>&, string name) -> bool;
Cartridge& cartridge;
};
}
+41
View File
@@ -0,0 +1,41 @@
struct Commavid : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
Memory::Writable<n8> ram;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address.bit(12)) {
if(address >= 0x1000 && address <= 0x13ff) return ram.read(address & 0x3ff);
return rom.read(address & 0xfff);
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address >= 0x1400 && address <= 0x17ff) {
ram.write(address & 0x3ff, data);
return true;
}
return false;
}
auto power() -> void override {
ram.allocate(1_KiB);
}
auto serialize(serializer& s) -> void override {
s(ram);
}
};
+45
View File
@@ -0,0 +1,45 @@
struct Linear : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
Memory::Writable<n8> ram;
bool hasRam;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address.bit(12)) {
if(hasRam && address >= 0x1080 && address <= 0x10ff) return ram.read(address & 0x7f);
return rom.read(address & 0xfff);
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address >= 0x1000 && address <= 0x107f) {
hasRam = true;
ram.write(address & 0x7f, data);
return true;
}
return false;
}
auto power() -> void override {
hasRam = 0;
ram.allocate(128);
}
auto serialize(serializer& s) -> void override {
s(hasRam);
s(ram);
}
};
+51
View File
@@ -0,0 +1,51 @@
struct ParkerBros : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
n3 banks[3];
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
bankswitch(address);
if(address.bit(12)) {
if(address >= 0x1000 && address <= 0x13ff) return rom.read((banks[0] * 0x400) + (address & 0x3ff));
if(address >= 0x1400 && address <= 0x17ff) return rom.read((banks[1] * 0x400) + (address & 0x3ff));
if(address >= 0x1800 && address <= 0x1bff) return rom.read((banks[2] * 0x400) + (address & 0x3ff));
if(address >= 0x1c00 && address <= 0x1fff) return rom.read(( 7 * 0x400) + (address & 0x3ff));
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
bankswitch(address);
return false;
}
auto bankswitch(n16 address) -> void {
if(address >= 0x1fe0 && address <= 0x1fe7) banks[0] = address - 0x1fe0;
if(address >= 0x1fe8 && address <= 0x1fef) banks[1] = address - 0x1fe8;
if(address >= 0x1ff0 && address <= 0x1ff7) banks[2] = address - 0x1ff0;
}
auto power() -> void override {
banks[0] = 0;
banks[1] = 1;
banks[2] = 2;
}
auto serialize(serializer& s) -> void override {
s(banks[0]);
s(banks[1]);
s(banks[2]);
}
};
+42
View File
@@ -0,0 +1,42 @@
struct Tigervision : Interface {
using Interface::Interface;
Memory::Readable<n8> rom;
n8 bank;
n8 nextBank;
auto load() -> void override {
Interface::load(rom, "program.rom");
}
auto save() -> void override {
}
auto unload() -> void override {
}
auto read(n16 address) -> n8 override {
if(address.bit(12)) {
if(bank != nextBank) bank = nextBank;
if(address <= 0x17ff) return rom.read((bank * 0x800) + (address & 0x7ff));
return rom.read((rom.size() - 0x800) + (address & 0x7ff));
}
return 0xff;
}
auto write(n16 address, n8 data) -> bool override {
if(address.bit(12) && bank != nextBank) bank = nextBank;
if(address <= 0x3f) nextBank = data;
return false;
}
auto power() -> void override {
bank = 0;
nextBank = 0;
}
auto serialize(serializer& s) -> void override {
s(bank);
s(nextBank);
}
};
+66
View File
@@ -0,0 +1,66 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
Cartridge& cartridge = cartridgeSlot.cartridge;
#include "board/board.cpp"
#include "slot.cpp"
#include "serialization.cpp"
auto Cartridge::allocate(Node::Port parent) -> Node::Peripheral {
return node = parent->append<Node::Peripheral>(string{system.name(), " Cartridge"});
}
auto Cartridge::connect() -> void {
if(!node->setPak(pak = platform->pak(node))) return;
information = {};
information.title = pak->attribute("title");
information.region = pak->attribute("region");
information.board = pak->attribute("board");
if(information.board == "Linear") board = new Board::Linear{*this};
if(information.board == "Atari8k") board = new Board::Atari8k{*this};
if(information.board == "Atari16k") board = new Board::Atari16k{*this};
if(information.board == "Atari32k") board = new Board::Atari32k{*this};
if(information.board == "Commavid") board = new Board::Commavid{*this};
if(information.board == "ParkerBros8k") board = new Board::ParkerBros{*this};
if(information.board == "Tigervision") board = new Board::Tigervision{*this};
if(!board) board = new Board::Interface{*this};
board->pak = pak;
board->load();
power();
}
auto Cartridge::disconnect() -> void {
if(!node || !board) return;
board->unload();
board->pak.reset();
board.reset();
node.reset();
}
auto Cartridge::save() -> void {
if(!node) return;
if(board) board->save();
}
auto Cartridge::power() -> void {
if(board) board->power();
}
auto Cartridge::read(n16 address) -> n8 {
if(!node) return 0xff;
if(board) return board->read(address);
return 0xff;
}
auto Cartridge::write(n16 address, n8 data) -> bool {
if(!node) return false;
if(board) return board->write(address, data);
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
struct Cartridge;
#include "board/board.hpp"
struct Cartridge {
Node::Peripheral node;
VFS::Pak pak;
auto title() const -> string { return information.title; }
auto region() const -> string { return information.region; }
//cartridge.cpp
auto allocate(Node::Port) -> Node::Peripheral;
auto connect() -> void;
auto disconnect() -> void;
auto save() -> void;
auto power() -> void;
auto read(n16 address) -> n8;
auto write(n16 address, n8 data) -> bool;
//serialization.cpp
auto serialize(serializer&) -> void;
unique_pointer<Board::Interface> board;
//private:
struct Information {
string title;
string region;
string board;
} information;
};
#include "slot.hpp"
extern Cartridge& cartridge;
+3
View File
@@ -0,0 +1,3 @@
auto Cartridge::serialize(serializer& s) -> void {
if(board) s(*board);
}
+18
View File
@@ -0,0 +1,18 @@
CartridgeSlot cartridgeSlot{"Cartridge Slot"};
CartridgeSlot::CartridgeSlot(string name) : name(name) {
}
auto CartridgeSlot::load(Node::Object parent) -> void {
port = parent->append<Node::Port>(name);
port->setFamily(system.name());
port->setType("Cartridge");
port->setAllocate([&](auto name) { return cartridge.allocate(port); });
port->setConnect([&] { return cartridge.connect(); });
port->setDisconnect([&] { return cartridge.disconnect(); });
}
auto CartridgeSlot::unload() -> void {
cartridge.disconnect();
port = {};
}
+13
View File
@@ -0,0 +1,13 @@
struct CartridgeSlot {
Node::Port port;
Cartridge cartridge;
//slot.cpp
CartridgeSlot(string name);
auto load(Node::Object) -> void;
auto unload() -> void;
const string name;
};
extern CartridgeSlot cartridgeSlot;
+8
View File
@@ -0,0 +1,8 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
#include "port.cpp"
#include "gamepad/gamepad.cpp"
}
+11
View File
@@ -0,0 +1,11 @@
struct Controller {
Node::Peripheral node;
virtual ~Controller() = default;
virtual auto read() -> n8 { return 0xff; }
virtual auto write(n8 data) -> void {}
};
#include "port.hpp"
#include "gamepad/gamepad.hpp"
+37
View File
@@ -0,0 +1,37 @@
Gamepad::Gamepad(Node::Port parent) {
node = parent->append<Node::Peripheral>("Gamepad");
up = node->append<Node::Input::Button>("Up");
down = node->append<Node::Input::Button>("Down");
left = node->append<Node::Input::Button>("Left");
right = node->append<Node::Input::Button>("Right");
fire = node->append<Node::Input::Button>("Fire");
}
auto Gamepad::read() -> n8 {
platform->input(up);
platform->input(down);
platform->input(left);
platform->input(right);
platform->input(fire);
if(!(up->value() & down->value())) {
yHold = 0, upLatch = up->value(), downLatch = down->value();
} else if(!yHold) {
yHold = 1, swap(upLatch, downLatch);
}
if(!(left->value() & right->value())) {
xHold = 0, leftLatch = left->value(), rightLatch = right->value();
} else if(!xHold) {
xHold = 1, swap(leftLatch, rightLatch);
}
n8 data = 0xff;
data.bit(0) = !upLatch;
data.bit(1) = !downLatch;
data.bit(2) = !leftLatch;
data.bit(3) = !rightLatch;
data.bit(4) = !fire->value();
return data;
}
+19
View File
@@ -0,0 +1,19 @@
struct Gamepad : Controller {
Node::Input::Button up;
Node::Input::Button down;
Node::Input::Button left;
Node::Input::Button right;
Node::Input::Button fire;
Gamepad(Node::Port);
auto read() -> n8 override;
private:
b1 yHold;
b1 upLatch;
b1 downLatch;
b1 xHold;
b1 leftLatch;
b1 rightLatch;
};
+28
View File
@@ -0,0 +1,28 @@
ControllerPort controllerPort1{"Controller Port 1"};
ControllerPort controllerPort2{"Controller Port 2"};
ControllerPort::ControllerPort(string name) : name(name) {
}
auto ControllerPort::load(Node::Object parent) -> void {
port = parent->append<Node::Port>(name);
port->setFamily(system.name());
port->setType("Controller");
port->setHotSwappable(true);
port->setAllocate([&](auto name) { return allocate(name); });
port->setSupported({"Gamepad"});
}
auto ControllerPort::unload() -> void {
device = {};
port = {};
}
auto ControllerPort::allocate(string name) -> Node::Peripheral {
if(name == "Gamepad") device = new Gamepad(port);
if(device) return device->node;
return {};
}
auto ControllerPort::serialize(serializer& s) -> void {
}
+20
View File
@@ -0,0 +1,20 @@
struct ControllerPort {
Node::Port port;
unique_pointer<Controller> device;
//port.cpp
ControllerPort(string name);
auto load(Node::Object) -> void;
auto unload() -> void;
auto allocate(string name) -> Node::Peripheral;
auto read() -> n8 { if(device) return device->read(); return 0xff; }
auto write(n8 data) -> void { if(device) return device->write(data); }
auto serialize(serializer&) -> void;
const string name;
};
extern ControllerPort controllerPort1;
extern ControllerPort controllerPort2;
+42
View File
@@ -0,0 +1,42 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
CPU cpu;
#include "memory.cpp"
#include "timing.cpp"
#include "debugger.cpp"
#include "serialization.cpp"
auto CPU::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("CPU");
debugger.load(node);
}
auto CPU::unload() -> void {
debugger = {};
node = {};
}
auto CPU::main() -> void {
debugger.instruction();
instruction();
}
auto CPU::step(u32 clocks) -> void {
Thread::step(clocks);
Thread::synchronize();
}
auto CPU::power(bool reset) -> void {
MOS6502::BCD = 1;
MOS6502::power();
Thread::create(system.frequency() / 3, {&CPU::main, this});
PC.byte(0) = readBus(0xfffc);
PC.byte(1) = readBus(0xfffd);
io = {};
}
}
+48
View File
@@ -0,0 +1,48 @@
struct CPU : MOS6502, Thread {
Node::Object node;
struct Debugger {
//debugger.cpp
auto load(Node::Object) -> void;
auto instruction() -> void;
struct Tracer {
Node::Debugger::Tracer::Instruction instruction;
} tracer;
} debugger;
//cpu.cpp
auto load(Node::Object) -> void;
auto unload() -> void;
auto main() -> void;
auto step(u32 clocks) -> void;
auto power(bool reset) -> void;
//memory.cpp
auto readBus(n16 address) -> n8;
auto writeBus(n16 address, n8 data) -> void;
auto readIO(n16 address) -> n8;
auto writeIO(n16 address, n8 data) -> void;
auto readDebugger(n16 address) -> n8 override;
auto serialize(serializer&) -> void;
//timing.cpp
auto read(n16 address) -> n8 override;
auto write(n16 address, n8 data) -> void override;
auto lastCycle() -> void override;
auto nmi(n16& vector) -> void override;
auto rdyLine(bool) -> void;
//protected:
struct IO {
n1 rdyLine = 1;
} io;
};
extern CPU cpu;
+12
View File
@@ -0,0 +1,12 @@
auto CPU::Debugger::load(Node::Object parent) -> void {
tracer.instruction = parent->append<Node::Debugger::Tracer::Instruction>("Instruction", "CPU");
tracer.instruction->setAddressBits(16);
}
auto CPU::Debugger::instruction() -> void {
if(tracer.instruction->enabled() && tracer.instruction->address(cpu.PC)) {
tracer.instruction->notify(cpu.disassembleInstruction(), cpu.disassembleContext());
}
}
+40
View File
@@ -0,0 +1,40 @@
inline auto CPU::readBus(n16 address) -> n8 {
address &= 0x1fff;
n8 data = cartridge.read(address);
if(address.bit(12) == 0 && address.bit(7) == 0) {
return tia.read(address & 0xf);
}
if(address.bit(12) == 0 && address.bit(9) == 0 && address.bit(7) == 1) {
return riot.readRam(address & 0x7f);
}
if(address.bit(12) == 0 && address.bit(9) == 1 && address.bit(7) == 1) {
return riot.readIo((address - 0x80) & 0x1f);
}
return data;
}
inline auto CPU::writeBus(n16 address, n8 data) -> void {
address &= 0x1fff;
cartridge.write(address, data);
if(address.bit(12) == 0 && address.bit(7) == 0) {
return tia.write(address & 0x3f, data);
}
if(address.bit(12) == 0 && address.bit(9) == 0 && address.bit(7) == 1) {
return riot.writeRam(address & 0x7f, data);
}
if(address.bit(12) == 0 && address.bit(9) == 1 && address.bit(7) == 1) {
return riot.writeIo((address - 0x80) & 0x1f, data);
}
}
auto CPU::readDebugger(n16 address) -> n8 {
return readBus(address);
}
+5
View File
@@ -0,0 +1,5 @@
auto CPU::serialize(serializer& s) -> void {
MOS6502::serialize(s);
Thread::serialize(s);
s(io.rdyLine);
}
+30
View File
@@ -0,0 +1,30 @@
auto CPU::read(n16 address) -> n8 {
if(io.rdyLine == 0) {
while (io.rdyLine == 0) {
step(1);
}
MDR = readBus(address);
return MDR;
}
step(1);
MDR = readBus(address);
return MDR;
}
auto CPU::write(n16 address, n8 data) -> void {
step(1);
writeBus(address, MDR = data);
}
auto CPU::lastCycle() -> void {
}
auto CPU::nmi(n16& vector) -> void {
}
auto CPU::rdyLine(bool line) -> void {
io.rdyLine = line;
}
+87
View File
@@ -0,0 +1,87 @@
auto RIOT::readRam(n8 address) -> n8 {
return ram[address];
}
auto RIOT::writeRam(n8 address, n8 data) -> void {
ram[address] = data;
}
auto RIOT::readIo(n8 address) -> n8 {
switch(address) {
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;
}
debug(unimplemented, "[RIOT] IO read ", hex(address));
return 0xff;
}
auto RIOT::writeIo(n8 address, n8 data) -> void {
switch(address) {
case 0x00: writePortA(data); return;
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: {
const n16 intervals[] = {1, 8, 64, 1024};
timer.counter = data;
timer.interval = intervals[address - 0x14];
timer.reload = timer.interval;
return; }
}
debug(unimplemented, "[RIOT] IO write ",hex(address), " = ", hex(data));
}
auto RIOT::readPortA() -> n8 {
n8 data;
// TODO: Handle when configured as outputs
data.bit(0, 3) = controllerPort2.read().bit(0, 4);
data.bit(4, 7) = controllerPort1.read().bit(0, 4);
return data;
}
auto RIOT::writePortA(n8 data) -> void {
port[0].data = data;
}
auto RIOT::readPortB() -> n8 {
system.controls.poll();
n8 data;
for(auto n : range(8)) if(port[1].direction.bit(n)) { data.bit(n) = port[1].data.bit(n); }
// Atari hard-wires these bits as input
data.bit(0) = !system.controls.reset->value();
data.bit(1) = !system.controls.select->value();
// These are toggle switches; flip the values on the rising edge
if(system.controls.tvType->value() && !tvTypeLatch) {
tvType = !tvType;
}
tvTypeLatch = system.controls.tvType->value();
if(system.controls.leftDifficulty->value() && !leftDifficultyLatch) {
leftDifficulty = !leftDifficulty;
}
leftDifficultyLatch = system.controls.leftDifficulty->value();
if(system.controls.rightDifficulty->value() && !rightDifficultyLatch) {
rightDifficulty = !rightDifficulty;
}
rightDifficultyLatch = system.controls.rightDifficulty->value();
data.bit(3) = tvType;
data.bit(6) = leftDifficulty;
data.bit(7) = rightDifficulty;
return data;
}
auto RIOT::writePortB(n8 data) -> void {
port[1].data = data;
}
+51
View File
@@ -0,0 +1,51 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
RIOT riot;
#include "io.cpp"
#include "serialization.cpp"
auto RIOT::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("RIOT");
ram.allocate(128);
}
auto RIOT::unload() -> void {
ram.reset();
node.reset();
}
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;
}
}
auto RIOT::step(u32 clocks) -> void {
Thread::step(clocks);
Thread::synchronize();
}
auto RIOT::power(bool reset) -> void {
Thread::create(system.frequency() / 3, {&RIOT::main, this});
timer = {};
port[0] = {.data = 0xff};
port[1] = {.data = 0xff};
leftDifficulty = 1;
rightDifficulty = 1;
tvType = 1;
}
}
+48
View File
@@ -0,0 +1,48 @@
struct RIOT : Thread {
Node::Object node;
Memory::Writable<n8> ram;
//riot.cpp
auto load(Node::Object) -> void;
auto unload() -> void;
auto main() -> void;
auto step(u32 clocks) -> void;
auto power(bool reset) -> void;
auto decrementTimer() -> void;
//io.cpp
auto readRam(n8 address) -> n8;
auto writeRam(n8 address, n8 data) -> void;
auto readIo(n8 address) -> n8;
auto writeIo(n8 address, n8 data) -> void;
auto readPortA() -> n8;
auto readPortB() -> n8;
auto writePortA(n8 data) -> void;
auto writePortB(n8 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
struct {
u8 counter;
n16 interval;
n16 reload;
} timer;
struct Port {
n8 data;
n8 direction;
} port[2];
n1 leftDifficulty;
n1 leftDifficultyLatch;
n1 rightDifficulty;
n1 rightDifficultyLatch;
n1 tvType;
n1 tvTypeLatch;
};
extern RIOT riot;
+21
View File
@@ -0,0 +1,21 @@
//serialization.cpp
auto RIOT::serialize(serializer& s) -> void {
Thread::serialize(s);
s(ram);
s(timer.counter);
s(timer.interval);
s(timer.reload);
for(auto n : range(2)) {
s(port[n].data);
s(port[n].direction);
}
s(leftDifficulty);
s(leftDifficultyLatch);
s(rightDifficulty);
s(rightDifficultyLatch);
s(tvType);
s(tvTypeLatch);
}
+17
View File
@@ -0,0 +1,17 @@
auto System::Controls::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("Controls");
reset = node->append<Node::Input::Button>("Reset");
select = node->append<Node::Input::Button>("Select");
leftDifficulty = node->append<Node::Input::Button>("Left Difficulty");
rightDifficulty = node->append<Node::Input::Button>("Right Difficulty");
tvType = node->append<Node::Input::Button>("TV Type");
}
auto System::Controls::poll() -> void {
platform->input(reset);
platform->input(select);
platform->input(leftDifficulty);
platform->input(rightDifficulty);
platform->input(tvType);
}
+46
View File
@@ -0,0 +1,46 @@
auto System::serialize(bool synchronize) -> serializer {
if(synchronize) scheduler.enter(Scheduler::Mode::Synchronize);
serializer s;
u32 signature = SerializerSignature;
char version[16] = {};
char description[512] = {};
memory::copy(&version, (const char*)SerializerVersion, SerializerVersion.size());
s(signature);
s(synchronize);
s(version);
s(description);
serialize(s, synchronize);
return s;
}
auto System::unserialize(serializer& s) -> bool {
u32 signature = 0;
bool synchronize = true;
char version[16] = {};
char description[512] = {};
s(signature);
s(synchronize);
s(version);
s(description);
if(signature != SerializerSignature) return false;
if(string{version} != SerializerVersion) return false;
if(synchronize) power(/* reset = */ false);
serialize(s, synchronize);
return true;
}
auto System::serialize(serializer& s, bool synchronize) -> void {
scheduler.setSynchronize(synchronize);
s(cartridge);
s(cpu);
s(tia);
s(riot);
s(controllerPort1);
s(controllerPort2);
}
+105
View File
@@ -0,0 +1,105 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
auto enumerate() -> vector<string> {
return {
"[Atari] Atari 2600 (NTSC)",
"[Atari] Atari 2600 (PAL)",
"[Atari] Atari 2600 (SECAM)",
};
}
auto load(Node::System& node, string name) -> bool {
if(!enumerate().find(name)) return false;
return system.load(node, name);
}
Random random;
Scheduler scheduler;
System system;
#include "controls.cpp"
#include "serialization.cpp"
auto System::game() -> string {
if(cartridge.node) {
return cartridge.title();
}
return "(no cartridge connected)";
}
auto System::run() -> void {
scheduler.enter();
}
auto System::load(Node::System& root, string name) -> bool {
if(node) unload();
information = {};
if(name.find("NTSC")) {
information.name = "Atari 2600";
information.region = Region::NTSC;
information.frequency = 3579546;
}
if(name.find("PAL")) {
information.name = "Atari 2600";
information.region = Region::PAL;
information.frequency = 3546894;
}
if(name.find("SECAM")) {
information.name = "Atari 2600";
information.region = Region::SECAM;
information.frequency = 3546894;
}
node = Node::System::create(information.name);
node->setGame({&System::game, this});
node->setRun({&System::run, this});
node->setPower({&System::power, this});
node->setSave({&System::save, this});
node->setUnload({&System::unload, this});
node->setSerialize({&System::serialize, this});
node->setUnserialize({&System::unserialize, this});
root = node;
scheduler.reset();
controls.load(node);
riot.load(node);
cpu.load(node);
tia.load(node);
cartridgeSlot.load(node);
controllerPort1.load(node);
controllerPort2.load(node);
return true;
}
auto System::save() -> void {
if(!node) return;
cartridge.save();
}
auto System::unload() -> void {
if(!node) return;
save();
riot.unload();
cpu.unload();
tia.unload();
cartridgeSlot.unload();
controllerPort1.unload();
controllerPort2.unload();
node = {};
}
auto System::power(bool reset) -> void {
for(auto& setting : node->find<Node::Setting::Setting>()) setting->setLatch();
random.entropy(Random::Entropy::Low);
cartridge.power();
riot.power(reset);
cpu.power(reset);
tia.power(reset);
scheduler.power(cpu);
}
}
+53
View File
@@ -0,0 +1,53 @@
extern Random random;
struct System {
Node::System node;
struct Controls {
Node::Object node;
Node::Input::Button reset;
Node::Input::Button select;
Node::Input::Button leftDifficulty;
Node::Input::Button rightDifficulty;
Node::Input::Button tvType;
//controls.cpp
auto load(Node::Object) -> void;
auto poll() -> void;
} controls;
enum class Region : u32 { NTSC, PAL, SECAM };
auto name() const -> string { return information.name; }
auto region() const -> Region { return information.region; }
auto frequency() const -> u32 { return information.frequency; }
//system.cpp
auto game() -> string;
auto run() -> void;
auto load(Node::System& node, string name) -> bool;
auto save() -> void;
auto unload() -> void;
auto power(bool reset) -> void;
//serialization.cpp
auto serialize(bool synchronize) -> serializer;
auto unserialize(serializer&) -> bool;
private:
struct Information {
string name = "Atari 2600";
Region region = Region::NTSC;
u32 frequency = Constants::Colorburst::NTSC;
} information;
//serialization.cpp
auto serialize(serializer&, bool synchronize) -> void;
};
extern System system;
auto Region::NTSC() -> bool { return system.region() == System::Region::NTSC; }
auto Region::PAL() -> bool { return system.region() == System::Region::PAL; }
auto Region::SECAM() -> bool { return system.region() == System::Region::SECAM; }
+64
View File
@@ -0,0 +1,64 @@
auto TIA::runAudio() -> void {
if(io.hcounter == 9 || io.hcounter == 81) {
audio[0].phase0();
audio[1].phase0();
}
if(io.hcounter == 37 || io.hcounter == 149) {
auto a = audio[0].phase1();
auto b = audio[1].phase1();
double output = 0;
output += volume[a];
output += volume[b];
stream->frame(output / 2.0);
}
}
auto TIA::AudioChannel::phase0() -> void {
if (enable) {
switch (control.bit(0, 1)) {
case 0x00: case 0x01: pulseCounterPaused = 0; break;
case 0x02: pulseCounterPaused = noiseCounter.bit(1, 4) != 1; break;
case 0x03: pulseCounterPaused = !noiseCounter.bit(0); break;
}
noiseFeedback = (noiseCounter.bit(2) ^ noiseCounter.bit(0)) || noiseCounter == 0;
if(control.bit(0, 2) == 0) {
noiseFeedback = !(control.bit(2, 3)) ||
!(noiseCounter || (pulseCounter != 0x0a)) ||
(pulseCounter.bit(0) ^ noiseCounter.bit(0));
}
}
enable = divCounter == frequency;
if (divCounter == frequency || divCounter == 0x1f) {
divCounter = 0;
return;
}
divCounter++;
}
auto TIA::AudioChannel::phase1() -> u8 {
if(!enable) return pulseCounter.bit(0) * volume;
pulseFeedback = 0;
switch(control.bit(2, 3)) {
case 0x00: pulseFeedback = pulseCounter != 0x0a && control.bit(0, 2) && (pulseCounter.bit(1) ^ pulseCounter.bit(0)); break;
case 0x01: pulseFeedback = !pulseCounter.bit(3); ; break;
case 0x02: pulseFeedback = !noiseCounter.bit(0); ; break;
case 0x03: pulseFeedback = !(pulseCounter.bit(1) || !pulseCounter.bit(1, 3)); ; break;
}
noiseCounter >>= 1;
if (noiseFeedback) noiseCounter.bit(4) = 1;
if(!pulseCounterPaused) {
pulseCounter = ~(pulseCounter >> 1) & 7;
if (pulseFeedback) pulseCounter.bit(3) = 1;
}
return pulseCounter.bit(0) * volume;
}
+42
View File
@@ -0,0 +1,42 @@
auto TIA::color(n32 color) -> n64 {
u64 ntscColors[128] = {
0x0000'0000'0000ull, 0x4040'4040'4040ull, 0x6c6c'6c6c'6c6cull, 0x9090'9090'9090ull, 0xb0b0'b0b0'b0b0ull, 0xc8c8'c8c8'c8c8ull, 0xdcdc'dcdc'dcdcull, 0xecec'ecec'ececull,
0x4444'4444'0000ull, 0x6464'6464'1010ull, 0x8484'8484'2424ull, 0xa0a0'a0a0'3434ull, 0xb8b8'b8b8'4040ull, 0xd0d0'd0d0'5050ull, 0xe8e8'e8e8'5c5cull, 0xfcfc'fcfc'6868ull,
0x7070'2828'0000ull, 0x8484'4444'1414ull, 0x9898'5c5c'2828ull, 0xacac'7878'3c4cull, 0xbcbc'8c8c'4c4cull, 0xcccc'a0a0'5c5cull, 0xdcdc'b4b4'6868ull, 0xecec'c8c8'7878ull,
0x8484'1818'0000ull, 0x9898'3434'1818ull, 0xacac'5050'3030ull, 0xc0c0'6868'4848ull, 0xd0d0'8080'5c5cull, 0xe0e0'9494'7070ull, 0xecec'a8a8'8080ull, 0xfcfc'bcbc'9494ull,
0x8888'0000'0000ull, 0x9c9c'2020'2020ull, 0xb0b0'3c3c'3c3cull, 0xc0c0'5858'5858ull, 0xd0d0'7070'7070ull, 0xe0e0'8888'8888ull, 0xecec'a0a0'a0a0ull, 0xfcfc'b4b4'b4b4ull,
0x7878'0000'5c5cull, 0x8c8c'2020'7474ull, 0xa0a0'3c3c'8888ull, 0xb0b0'5858'9c9cull, 0xc0c0'7070'b0b0ull, 0xd0d0'8484'c0c0ull, 0xdcdc'9c9c'd0d0ull, 0xecec'b0b0'e0e0ull,
0x4848'0000'7878ull, 0x6060'2020'9090ull, 0x7878'3c3c'a4a4ull, 0x8c8c'5858'b8b8ull, 0xa0a0'7070'ccccull, 0xb4b4'8484'dcdcull, 0xc4c4'9c9c'ececull, 0xd4d4'b0b0'fcfcull,
0x1414'0000'8484ull, 0x3030'2020'9898ull, 0x4c4c'3c3c'acacull, 0x6868'5858'c0c0ull, 0x7c7c'7070'd0d0ull, 0x9494'8888'e0e0ull, 0xa8a8'a0a0'ececull, 0xbcbc'b4b4'fcfcull,
0x0000'0000'8888ull, 0x1c1c'2020'9c9cull, 0x3838'4040'b0b0ull, 0x5050'5c5c'c0c0ull, 0x6868'7474'd0d0ull, 0x7c7c'8c8c'e0e0ull, 0x9090'a4a4'ececull, 0xa4a4'b8b8'fcfcull,
0x0000'1818'7c7cull, 0x1c1c'3838'9090ull, 0x3838'5454'a8a8ull, 0x5050'7070'bcbcull, 0x6868'8888'ccccull, 0x7c7c'9c9c'dcdcull, 0x9090'b4b4'ececull, 0xa4a4'c8c8'fcfcull,
0x0000'2c2c'5c5cull, 0x1c1c'4c4c'7878ull, 0x3838'6868'9090ull, 0x5050'8484'acacull, 0x6868'9c9c'c0c0ull, 0x7c7c'b4b4'd4d4ull, 0x9090'cccc'e8e8ull, 0xa4a4'e0e0'fcfcull,
0x0000'3c3c'2c2cull, 0x1c1c'5c5c'4848ull, 0x3838'7c7c'6464ull, 0x5050'9c9c'8080ull, 0x6868'b4b4'9494ull, 0x7c7c'd0d0'acacull, 0x9090'e4e4'c0c0ull, 0xa4a4'fcfc'd4d4ull,
0x0000'3c3c'0000ull, 0x2020'5c5c'2020ull, 0x4040'7c7c'4040ull, 0x5c5c'9c9c'5c5cull, 0x7474'b4b4'7474ull, 0x8c8c'd0d0'8c8cull, 0xa4a4'e4e4'a4a4ull, 0xb8b8'fcfc'b8b8ull,
0x1414'3838'0000ull, 0x3434'5c5c'1c1cull, 0x5050'7c7c'3838ull, 0x6c6c'9898'5050ull, 0x8484'b4b4'6868ull, 0x9c9c'cccc'7c7cull, 0xb4b4'e4e4'9090ull, 0xc8c8'fcfc'a4a4ull,
0x2c2c'3030'0000ull, 0x4c4c'5050'1c1cull, 0x6868'7070'3434ull, 0x8484'8c8c'4c4cull, 0x9c9c'a8a8'6464ull, 0xb4b4'c0c0'7878ull, 0xcccc'd4d4'8888ull, 0xe0e0'ecec'9c9cull,
0x4444'2828'0000ull, 0x6464'4848'1818ull, 0x8484'6868'3030ull, 0xa0a0'8484'4444ull, 0xb8b8'9c9c'5858ull, 0xd0d0'b4b4'6c6cull, 0x8e8c'cccc'7c7cull, 0xfcfc'c0c0'8c8cull,
};
u64 palColors[128] = {
0x0000'0000'0000ull, 0x2828'2828'2828ull, 0x5050'5050'5050ull, 0x7474'7474'7474ull, 0x9494'9494'9494ull, 0xb4b4'b4b4'b4b4ull, 0xd0d0'd0d0'd0d0ull, 0xecec'ecec'ececull,
0x0000'0000'0000ull, 0x2828'2828'2828ull, 0x5050'5050'5050ull, 0x7474'7474'7474ull, 0x9494'9494'9494ull, 0xb4b4'b4b4'b4b4ull, 0xd0d0'd0d0'd0d0ull, 0xecec'ecec'ececull,
0x8080'5858'0000ull, 0x9494'7070'2020ull, 0xa8a8'8484'3c3cull, 0xbcbc'9c9c'5858ull, 0xcccc'acac'7070ull, 0xdcdc'c0c0'8484ull, 0xecec'd0d0'9c9cull, 0xfcfc'e0e0'b0b0ull,
0x4444'5c5c'0000ull, 0x5c5c'7878'2020ull, 0x7474'9090'3c3cull, 0x8c8c'acac'5858ull, 0xa0a0'c0c0'7070ull, 0xb0b0'd4d4'8484ull, 0xc4c4'e8e8'9c9cull, 0xd4d4'fcfc'b0b0ull,
0x7070'3434'0000ull, 0x8888'5050'2020ull, 0xa0a0'6868'3c3cull, 0xb4b4'8484'5858ull, 0xc8c8'9898'7070ull, 0xdcdc'acac'8484ull, 0xecec'c0c0'9c9cull, 0xfcfc'd4d4'b0b0ull,
0x0000'6464'1414ull, 0x2020'8080'3434ull, 0x3c3c'9898'5050ull, 0x5858'b0b0'6c6cull, 0x7070'c4c4'8484ull, 0x8484'd8d8'9c9cull, 0x9c9c'e8e8'b4b4ull, 0xb0b0'fcfc'c8c8ull,
0x7070'0000'1414ull, 0x8888'2020'3434ull, 0xa0a0'3c3c'5050ull, 0xb4b4'5858'6c6cull, 0xc8c8'7070'8484ull, 0xdcdc'8484'9c9cull, 0xecec'9c9c'b4b4ull, 0xfcfc'b0b0'c8c8ull,
0x0000'5c5c'5c5cull, 0x2020'7474'7474ull, 0x3c3c'8c8c'8c8cull, 0x5858'a4a4'a4a4ull, 0x7070'b8b8'b8b8ull, 0x8484'c8c8'c8c8ull, 0x9c9c'dcdc'dcdcull, 0xb0b0'ecec'ececull,
0x7070'0000'5c5cull, 0x8484'2020'7474ull, 0x9494'3c3c'8888ull, 0xa8a8'5858'9c9cull, 0xb4b4'7070'b0b0ull, 0xc4c4'8484'c0c0ull, 0xd0d0'9c9c'd0d0ull, 0xe0e0'b0b0'e0e0ull,
0x0000'3c3c'7070ull, 0x1c1c'5858'8888ull, 0x3838'7474'a0a0ull, 0x5050'8c8c'b4b4ull, 0x6868'a4a4'c8c8ull, 0x7c7c'b8b8'dcdcull, 0x9090'cccc'ececull, 0xa4a4'e0e0'fcfcull,
0x5858'0000'7070ull, 0x6c6c'2020'8888ull, 0x8080'3c3c'a0a0ull, 0x9494'5858'b4b4ull, 0xa4a4'7070'c8c8ull, 0xb4b4'8484'dcdcull, 0xc4c4'9c9c'ececull, 0xd4d4'b0b0'fcfcull,
0x0000'2020'7070ull, 0x1c1c'3c3c'8888ull, 0x3838'5858'a0a0ull, 0x5050'7474'b4b4ull, 0x6868'8888'c8c8ull, 0x7c7c'a0a0'dcdcull, 0x9090'b4b4'ececull, 0xa4a4'c8c8'fcfcull,
0x3c3c'0000'8080ull, 0x5454'2020'9494ull, 0x6c6c'3c3c'a8a8ull, 0x8080'5858'bcbcull, 0x9494'7070'ccccull, 0xa8a8'8484'dcdcull, 0xb8b8'9c9c'ececull, 0xc8c8'b0b0'fcfcull,
0x0000'0000'8888ull, 0x2020'2020'9c9cull, 0x3c3c'3c3c'b0b0ull, 0x5858'5858'c0c0ull, 0x7070'7070'd0d0ull, 0x8484'8484'e0e0ull, 0x9c9c'9c9c'ececull, 0xb0b0'b0b0'fcfcull,
0x0000'0000'0000ull, 0x2828'2828'2828ull, 0x5050'5050'5050ull, 0x7474'7474'7474ull, 0x9494'9494'9494ull, 0xb4b4'b4b4'b4b4ull, 0xd0d0'd0d0'd0d0ull, 0xecec'ecec'ececull,
0x0000'0000'0000ull, 0x2828'2828'2828ull, 0x5050'5050'5050ull, 0x7474'7474'7474ull, 0x9494'9494'9494ull, 0xb4b4'b4b4'b4b4ull, 0xd0d0'd0d0'd0d0ull, 0xecec'ecec'ececull,
};
return Region::PAL() ? palColors[color & 0x7f] : ntscColors[color & 0x7f];
}
+147
View File
@@ -0,0 +1,147 @@
auto TIA::read(n8 address) -> n8 {
n8 value;
switch(address) {
case 0x00: value.bit(7) = collision.M0P1; value.bit(6) = collision.M0P0; return value; // CXM0P
case 0x01: value.bit(7) = collision.M1P0; value.bit(6) = collision.M1P1; return value; // CXM1P
case 0x02: value.bit(7) = collision.P0PF; value.bit(6) = collision.P0BL; return value; // CX0FB
case 0x03: value.bit(7) = collision.P1PF; value.bit(6) = collision.P1BL; return value; // CX1FB
case 0x04: value.bit(7) = collision.M0PF; value.bit(6) = collision.M0BL; return value; // CXM0FB
case 0x05: value.bit(7) = collision.M1PF; value.bit(6) = collision.M1BL; return value; // CXM1FB
case 0x06: value.bit(7) = collision.BLPF; return value; // CXBLPF
case 0x07: value.bit(7) = collision.P0P1; value.bit(6) = collision.M0M1; return value; // CXPPMM
case 0x0c: value.bit(7) = controllerPort1.read().bit(4); return value; // INPT4
case 0x0d: value.bit(7) = controllerPort2.read().bit(4); return value; // INPT5
}
debug(unimplemented, "[TIA] read ", hex(address));
return 0xff;
}
auto TIA::write(n8 address, n8 data) -> void {
switch(address) {
case 0x00: vsync(data.bit(1)); return; // VSYNC
case 0x01: writeQueue.add(address, data, 1); return; // VBLANK
case 0x02: cpu.rdyLine(0); return; // WSYNC
case 0x03: io.hcounter = 0; return; // RSYNC
case 0x04: player[0].size = data.bit(0,2); missile[0].size = data.bit(4, 5); return; // NUSIZ1
case 0x05: player[1].size = data.bit(0,2); missile[1].size = data.bit(4, 5); return; // NUSIZ1
case 0x06: io.p0Color = data.bit(1, 7); return; // COLUP0
case 0x07: io.p1Color = data.bit(1, 7); return; // COLUP1
case 0x08: io.fgColor = data.bit(1, 7); return; // COLUPF
case 0x09: io.bgColor = data.bit(1, 7); return; // COLUBK
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 0x10: resp(0); return; // RESP0
case 0x11: resp(1); return; // RESP1
case 0x12: resm(0); return; // RESM0
case 0x13: resm(1); return; // RESM1
case 0x14: resbl(); return; // RESBL
case 0x15: audio[0].control = data; return; // AUDC0
case 0x16: audio[1].control = data; return; // AUDC1
case 0x17: audio[0].frequency = data; return; // AUDF0
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 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
case 0x20: writeQueue.add(address, data, 2); return; // HMP0
case 0x21: writeQueue.add(address, data, 2); return; // HMP1
case 0x22: writeQueue.add(address, data, 2); return; // HMM0
case 0x23: writeQueue.add(address, data, 2); return; // HMM1
case 0x24: writeQueue.add(address, data, 2); return; // HMBL
case 0x25: player[0].delay = data.bit(0); return; // VDELP0
case 0x26: player[1].delay = data.bit(0); return; // VDELP1
case 0x27: ball.delay = data.bit(0); return; // VDELBL
case 0x28: resmp(0, data); return; // RESMP0
case 0x29: resmp(1, data); return; // RESMP1
case 0x2a: writeQueue.add(address, data, 6); return; // HMOVE
case 0x2b: writeQueue.add(address, data, 2); return; // HMCLR
case 0x2c: cxclr(); return; // CXCLR
}
debug(unimplemented, "[TIA] write ",hex(address), " = ", hex(data));
}
auto TIA::vsync(n1 state) -> void {
if(io.vsync && !state) {
io.vcounter = 0;
frame();
}
io.vsync = state;
}
auto TIA::ctrlpf(n8 data) -> void {
playfield.mirror = data.bit(0);
playfield.scoreMode = data.bit(1);
playfield.priority = data.bit(2);
ball.size = data.bit(4, 5);
}
auto TIA::cxclr() -> void {
collision.M0P0 = 0;
collision.M0P1 = 0;
collision.M1P0 = 0;
collision.M1P1 = 0;
collision.P0PF = 0;
collision.P0BL = 0;
collision.P1PF = 0;
collision.P1BL = 0;
collision.M0PF = 0;
collision.M0BL = 0;
collision.M1PF = 0;
collision.M1BL = 0;
collision.BLPF = 0;
collision.P0P1 = 0;
collision.M0M1 = 0;
}
auto TIA::hmove() -> void {
for(auto& p : player) p.position = (p.position - p.offset + 160) % 160;
for(auto& m : missile) m.position = (m.position - m.offset + 160) % 160;
ball.position = (ball.position - ball.offset + 160) % 160;
io.hmoveTriggered = io.vcounter;
}
auto TIA::hmclr() -> void {
for(auto& p : player) p.offset = 0;
for(auto& m : missile) m.offset = 0;
ball.offset = 0;
}
auto TIA::grp(n1 index, n8 data) -> void {
player[index].graphics[0] = data;
player[!index].graphics[1] = player[!index].graphics[0];
if(index) ball.enable[1] = ball.enable[0];
}
auto TIA::resp(n1 index) -> void {
player[index].position = (io.hcounter < 68 ? 3 : io.hcounter - 68 + 8) % 160;
}
auto TIA::resm(n1 index) -> void {
missile[index].position = (io.hcounter < 68 ? 2 : io.hcounter - 68 + 7) % 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);
}
+85
View File
@@ -0,0 +1,85 @@
//serialization.cpp
auto TIA::serialize(serializer& s) -> void {
Thread::serialize(s);
for(auto n : range(writeQueue.maxItems)) {
s(writeQueue.items[n].active);
s(writeQueue.items[n].address);
s(writeQueue.items[n].data);
s(writeQueue.items[n].delay);
}
s(io.vcounter);
s(io.hcounter);
s(io.hmoveTriggered);
s(io.vsync);
s(io.vblank);
s(io.bgColor);
s(io.p0Color);
s(io.p1Color);
s(io.fgColor);
s(playfield.graphics);
s(playfield.mirror);
s(playfield.scoreMode);
s(playfield.priority);
for(auto n : range(2)) {
s(player[n].graphics[0]);
s(player[n].graphics[1]);
s(player[n].reflect);
s(player[n].size);
s(player[n].offset);
s(player[n].position);
s(player[n].delay);
}
for(auto n : range(2)) {
s(missile[n].enable);
s(missile[n].reset);
s(missile[n].size);
s(missile[n].offset);
s(missile[n].position);
}
for(auto n : range(2)) {
s(ball.enable[0]);
s(ball.enable[1]);
s(ball.size);
s(ball.offset);
s(ball.position);
}
s(collision.M0P0);
s(collision.M0P1);
s(collision.M1P0);
s(collision.M1P1);
s(collision.P0PF);
s(collision.P0BL);
s(collision.P1PF);
s(collision.P1BL);
s(collision.M0PF);
s(collision.M0BL);
s(collision.M1PF);
s(collision.M1BL);
s(collision.BLPF);
s(collision.P0P1);
s(collision.M0M1);
for(auto n : range(26)) {
s(volume[n]);
}
for(auto n : range(2)) {
s(audio[n].enable);
s(audio[n].divCounter);
s(audio[n].noiseCounter);
s(audio[n].noiseFeedback);
s(audio[n].pulseCounter);
s(audio[n].pulseCounterPaused);
s(audio[n].pulseFeedback);
s(audio[n].volume);
s(audio[n].control);
s(audio[n].frequency);
}
}
+173
View File
@@ -0,0 +1,173 @@
#include <a26/a26.hpp>
namespace ares::Atari2600 {
TIA tia;
#include "audio.cpp"
#include "color.cpp"
#include "io.cpp"
#include "serialization.cpp"
#include "write-queue.cpp"
auto TIA::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("TIA");
screen = node->append<Node::Video::Screen>("Screen", 160, vlines());
screen->colors(1 << 7, {&TIA::color, this});
screen->setSize(160, vlines());
screen->setScale(2.0, 1.0);
screen->setAspect(1.0, 1.0);
screen->setViewport(0, 0, 160, vlines());
stream = node->append<Node::Audio::Stream>("Audio");
stream->setChannels(1);
stream->setFrequency(31'403);
stream->addHighPassFilter( 20.0, 1);
stream->addLowPassFilter (2840.0, 1);
}
auto TIA::unload() -> void {
screen->quit();
node->remove(screen);
screen.reset();
node.reset();
}
auto TIA::main() -> void {
scanline();
io.vcounter++;
io.hmoveTriggered = 255;
}
auto TIA::scanline() -> void {
cpu.rdyLine(1);
for(io.hcounter = 0; io.hcounter < 228; io.hcounter++) {
auto x = io.hcounter - 68;
if(x >= 0) pixel(x);
writeQueue.step();
runAudio();
step();
}
}
auto TIA::pixel(n8 x) -> void {
auto output = screen->pixels().data() + (io.vcounter * 160);
// 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)) {
output[x] = 0;
return;
}
output[x] = io.bgColor;
auto pf = runPlayfield(x);
auto bl = runBall(x);
auto p0 = runPlayer(x, 0);
auto p1 = runPlayer(x, 1);
auto m0 = runMissile(x, 0);
auto m1 = runMissile(x, 1);
if(!playfield.priority && (pf || bl)) output[x] = io.fgColor;
if(p1 || m1) output[x] = io.p1Color;
if(p0 || m0) output[x] = io.p0Color;
if(playfield.priority && (pf || bl)) output[x] = io.fgColor;
// Update Collision
if(m0 && p1) collision.M0P1 = 1;
if(m0 && p0) collision.M0P0 = 1;
if(m1 && p0) collision.M1P0 = 1;
if(m1 && p1) collision.M1P1 = 1;
if(p0 && pf) collision.P0PF = 1;
if(p0 && bl) collision.P0BL = 1;
if(p1 && pf) collision.P1PF = 1;
if(p1 && bl) collision.P1BL = 1;
if(m0 && pf) collision.M0PF = 1;
if(m0 && bl) collision.M0BL = 1;
if(m1 && pf) collision.M1PF = 1;
if(m1 && bl) collision.M1BL = 1;
if(bl && pf) collision.BLPF = 1;
if(p0 && p1) collision.P0P1 = 1;
if(m0 && m1) collision.M0M1 = 1;
}
auto TIA::runPlayfield(n8 x) -> n1 {
auto pos = x >> 2;
if(!playfield.mirror || pos < 20) return playfield.graphics.bit(pos % 20);
return playfield.graphics.bit(19 - (pos % 20));
}
auto TIA::runPlayer(n8 x, n1 index) -> n1 {
auto& player = this->player[index];
auto position = player.position;
// Handle player stretch capability
auto width = 8;
if(player.size == 5) width = 16;
if(player.size == 7) width = 32;
// 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) {
auto bit = player.reflect ? (x - position) / (width / 8) : 7 - ((x - position) / (width / 8));
return player.graphics[player.delay].bit(bit);
}
position = (position + (spacing + width)) % 160;
}
return 0;
}
auto TIA::runMissile(n8 x, n1 index) -> n1 {
auto& missile = this->missile[index];
if (!missile.enable || missile.reset) return 0;
const int missileSizes[4] = {1, 2, 4, 8};
return x >= missile.position && x < missile.position + missileSizes[missile.size];
}
auto TIA::runBall(n8 x) -> n1 {
if(!ball.enable[ball.delay]) return 0;
const int ballSizes[4] = {1, 2, 4, 8};
return x >= ball.position && x < ball.position + ballSizes[ball.size];
}
auto TIA::frame() -> void {
screen->frame();
scheduler.exit(Event::Frame);
}
auto TIA::step(u32 clocks) -> void {
Thread::step(clocks);
Thread::synchronize();
}
auto TIA::power(bool reset) -> void {
Thread::create(system.frequency(), {&TIA::main, this});
screen->power();
io = {};
playfield = {};
for(auto& p : player) p = {};
for(auto& m : missile) m = {};
ball = {};
collision = {};
for(auto n : range(writeQueue.maxItems)) writeQueue.items[n] = {};
for(u32 level : range(15)) {
volume[level] = pow(2, level * -2.0 / 6.0);
}
volume[15] = 0;
}
}
+147
View File
@@ -0,0 +1,147 @@
struct TIA : Thread {
Node::Object node;
Node::Video::Screen screen;
Node::Audio::Stream stream;
auto vlines() const -> u32 { return Region::NTSC() ? 262 : 312; }
//tia.cpp
auto load(Node::Object) -> void;
auto unload() -> void;
auto main() -> void;
auto step(u32 clocks = 1) -> void;
auto power(bool reset) -> void;
auto frame() -> void;
auto scanline() -> void;
auto pixel(n8 x) -> void;
auto runPlayfield(n8 x) -> n1;
auto runBall(n8 x) -> n1;
auto runPlayer(n8 x, n1 index) -> n1;
auto runMissile(n8 x, n1 index) -> n1;
auto runCollision() -> void;
//io.cpp
auto read(n8 address) -> n8;
auto write(n8 address, n8 data) -> void;
auto vsync(n1 state) -> void;
auto ctrlpf(n8 data) -> void;
auto cxclr() -> void;
auto hmove() -> void;
auto hmclr() -> void;
auto grp(n1 index, n8 data) -> void;
auto resp(n1 index) -> void;
auto resm(n1 index) -> void;
auto resmp(n1 index, n8 data) -> void;
auto resbl() -> void;
// audio.cpp
auto runAudio() -> void;
//color.cpp
auto color(n32) -> n64;
//serialization.cpp
auto serialize(serializer&) -> void;
// write-queue.cpp
struct WriteQueue {
inline auto add(u8 address, n8 data, i8 delay) -> void;
inline auto step() -> void;
struct QueueItem {
inline auto commit() -> void;
n1 active;
i8 address;
n8 data;
i8 delay;
};
QueueItem items[16];
const int maxItems = 16;
} writeQueue;
struct {
u9 vcounter;
u8 hcounter;
u8 hmoveTriggered;
n1 vsync;
n1 vblank;
n7 bgColor;
n7 p0Color;
n7 p1Color;
n7 fgColor;
} io;
struct {
n20 graphics;
n1 mirror;
n1 scoreMode;
n1 priority;
} playfield;
struct {
n8 graphics[2];
n1 reflect;
n3 size;
i4 offset;
n8 position;
n1 delay;
} player[2];
struct {
n1 enable;
n1 reset;
n2 size;
i4 offset;
n8 position;
} missile[2];
struct {
n1 enable[2];
n2 size;
i4 offset;
n1 delay;
n8 position;
} ball;
struct {
n1 M0P0;
n1 M0P1;
n1 M1P0;
n1 M1P1;
n1 P0PF;
n1 P0BL;
n1 P1PF;
n1 P1BL;
n1 M0PF;
n1 M0BL;
n1 M1PF;
n1 M1BL;
n1 BLPF;
n1 P0P1;
n1 M0M1;
} collision;
struct AudioChannel {
auto phase0() -> void;
auto phase1() -> u8;
n1 enable;
n8 divCounter;
n8 noiseCounter;
n1 noiseFeedback;
n8 pulseCounter;
n1 pulseCounterPaused;
n1 pulseFeedback;
n4 volume;
n4 control;
n5 frequency;
} audio[2];
f64 volume[16];
};
extern TIA tia;
+46
View File
@@ -0,0 +1,46 @@
auto TIA::WriteQueue::add(u8 address, n8 data, i8 delay) -> void {
for(auto n : range(maxItems)) {
if(!items[n].active) {
items[n].address = address;
items[n].data = data;
items[n].delay = delay;
items[n].active = 1;
return;
}
}
}
auto TIA::WriteQueue::step() -> void {
auto& items = tia.writeQueue.items;
for(auto n : range(maxItems)) {
if(items[n].active && --items[n].delay == 0) {
items[n].commit();
items[n].active = 0;
}
}
}
auto TIA::WriteQueue::QueueItem::commit() -> void {
switch(address) {
case 0x01: tia.io.vblank = data.bit(1); return; // VBLANK
case 0x0b: tia.player[0].reflect = data.bit(3); return; // REFP0
case 0x0c: tia.player[1].reflect = data.bit(3); return; // REFP1
case 0x0d: tia.playfield.graphics.bit(0, 3) = data.bit(4, 7); return; // PF0
case 0x0e: for(auto n : range(8)) tia.playfield.graphics.bit(4 + n) = data.bit(7 - n); return; // PF1
case 0x0f: tia.playfield.graphics.bit(12, 19) = data; return; // PF2
case 0x1b: tia.grp(0, data); return; // GRP0
case 0x1c: tia.grp(1, data); return; // GRP1
case 0x1d: tia.missile[0].enable = data.bit(1); return; // ENAM0
case 0x1e: tia.missile[1].enable = data.bit(1); return; // ENAM1
case 0x1f: tia.ball.enable[0] = data.bit(1); return; // ENABL
case 0x20: tia.player[0].offset = data.bit(4, 7); return; // HMP0
case 0x21: tia.player[1].offset = data.bit(4, 7); return; // HMP1
case 0x22: tia.missile[0].offset = data.bit(4, 7); return; // HMM0
case 0x23: tia.missile[1].offset = data.bit(4, 7); return; // HMM1
case 0x24: tia.ball.offset = data.bit(4, 7); return; // HMBL
case 0x2a: tia.hmove(); return; // HMOVE
case 0x2b: tia.hmclr(); return; // HMCLR
}
debug(unimplemented, "[TIA] writeQueue: ",hex(address), " = ", hex(data));
}
+1
View File
@@ -1,4 +1,5 @@
#include <ares/ares.hpp>
#include <ares/debug/debug.cpp>
#include <ares/node/node.cpp>
#include <ares/resource/resource.cpp>
+31 -16
View File
@@ -1,22 +1,28 @@
#pragma once
#include <libco/libco.h>
#include <sljit.h>
#include <nall/platform.hpp>
#include <nall/adaptive-array.hpp>
#include <nall/any.hpp>
#include <nall/array.hpp>
#include <nall/bump-allocator.hpp>
#include <nall/chrono.hpp>
#include <nall/directory.hpp>
#include <nall/dl.hpp>
#include <nall/endian.hpp>
#include <nall/image.hpp>
#include <nall/literals.hpp>
#include <nall/priority-queue.hpp>
#include <nall/queue.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>
#include <nall/set.hpp>
#include <nall/shared-pointer.hpp>
#include <nall/string.hpp>
#include <nall/terminal.hpp>
#include <nall/thread.hpp>
#include <nall/traits.hpp>
#include <nall/unique-pointer.hpp>
#include <nall/variant.hpp>
@@ -31,36 +37,45 @@
using namespace nall;
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";
namespace VFS {
using Pak = shared_pointer<vfs::directory>;
using File = shared_pointer<vfs::file>;
}
namespace Video {
static constexpr bool Threaded = true;
}
namespace Constants {
namespace Colorburst {
static constexpr double NTSC = 315.0 / 88.0 * 1'000'000.0;
static constexpr double PAL = 283.75 * 15'625.0 + 25.0;
static constexpr f64 NTSC = 315.0 / 88.0 * 1'000'000.0;
static constexpr f64 PAL = 283.75 * 15'625.0 + 25.0;
}
}
//nall/vfs shorthand constants
namespace File {
static const auto Read = vfs::file::mode::read;
static const auto Write = vfs::file::mode::write;
static const auto Optional = false;
static const auto Required = true;
}
namespace Shared {
using File = shared_pointer<vfs::file>;
}
extern bool _runAhead;
inline auto runAhead() -> bool { return _runAhead; }
inline auto setRunAhead(bool runAhead) -> void { _runAhead = runAhead; }
}
#include <ares/information.hpp>
#include <ares/types.hpp>
#include <ares/random.hpp>
#include <ares/debug/debug.hpp>
#include <ares/node/node.hpp>
#include <ares/platform.hpp>
#include <ares/interface.hpp>
#include <ares/memory/fixed-allocator.hpp>
#include <ares/memory/readable.hpp>
#include <ares/memory/writable.hpp>
#include <ares/resource/resource.hpp>
+45
View File
@@ -0,0 +1,45 @@
namespace ares {
Debug _debug;
auto Debug::reset() -> void {
_totalNotices = 0;
_unhandledNotices.reset();
_unimplementedNotices.reset();
_unusualNotices.reset();
_unverifiedNotices.reset();
}
auto Debug::_unhandled(const string& text) -> void {
if(_unhandledNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unhandledNotices.append(text);
print(terminal::color::yellow("[unhandled] "), text, "\n");
}
auto Debug::_unimplemented(const string& text) -> void {
if(_unimplementedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unimplementedNotices.append(text);
print(terminal::color::magenta("[unimplemented] "), text, "\n");
}
auto Debug::_unusual(const string& text) -> void {
if(_unusualNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unusualNotices.append(text);
print(terminal::color::cyan("[unusual] "), text, "\n");
}
auto Debug::_unverified(const string& text) -> void {
if(_unverifiedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unverifiedNotices.append(text);
print(terminal::color::gray("[unverified] "), text, "\n");
}
}
+39
View File
@@ -0,0 +1,39 @@
namespace ares {
struct Debug {
auto reset() -> void;
template<typename... P> auto unhandled(P&&... p) -> void {
return _unhandled({forward<P>(p)...});
}
template<typename... P> auto unimplemented(P&&... p) -> void {
return _unimplemented({forward<P>(p)...});
}
template<typename... P> auto unusual(P&&... p) -> void {
return _unusual({forward<P>(p)...});
}
template<typename... P> auto unverified(P&&... p) -> void {
return _unverified({forward<P>(p)...});
}
private:
auto _unhandled(const string&) -> void;
auto _unimplemented(const string&) -> void;
auto _unusual(const string&) -> void;
auto _unverified(const string&) -> void;
u64 _totalNotices = 0;
vector<string> _unhandledNotices;
vector<string> _unimplementedNotices;
vector<string> _unusualNotices;
vector<string> _unverifiedNotices;
};
extern Debug _debug;
}
#define debug(function, ...) if constexpr(1) ares::_debug.function(__VA_ARGS__)
-11
View File
@@ -1,11 +0,0 @@
#pragma once
namespace ares {
static const string Name = "ares";
static const string Version = "112";
static const string License = "GPLv3+";
static const string Website = "https://ares.dev";
//incremented only when serialization format changes
static const string SerializerVersion = "112";
}
-28
View File
@@ -1,28 +0,0 @@
#pragma once
namespace ares {
struct Interface {
virtual ~Interface() = default;
//information
virtual auto name() -> string { return {}; }
virtual auto game() -> string { return {}; }
//system interface
virtual auto root() -> Node::Object { return {}; }
virtual auto load(Node::Object&) -> void {}
virtual auto power() -> void {}
virtual auto run() -> void {}
virtual auto save() -> void {}
virtual auto unload() -> void {}
//state functions
virtual auto serialize(bool synchronize = true) -> serializer { return {}; }
virtual auto unserialize(serializer&) -> bool { return false; }
//debugging functions
virtual auto exportMemory() -> bool { return false; }
};
}
+22
View File
@@ -0,0 +1,22 @@
#include <ares/ares.hpp>
namespace ares::Memory {
#if defined(PLATFORM_MACOS) && defined(ARCHITECTURE_ARM64)
//stub for unsupported platforms
FixedAllocator::FixedAllocator() {
}
#else
alignas(4096) u8 fixedBuffer[128_MiB];
FixedAllocator::FixedAllocator() {
_allocator.resize(sizeof(fixedBuffer), 0, fixedBuffer);
}
#endif
auto FixedAllocator::get() -> bump_allocator& {
static FixedAllocator allocator;
return allocator._allocator;
}
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
namespace ares::Memory {
struct FixedAllocator {
static auto get() -> bump_allocator&;
private:
FixedAllocator();
bump_allocator _allocator;
};
}
+5 -5
View File
@@ -2,10 +2,10 @@
namespace ares::Memory {
inline auto mirror(uint address, uint size) -> uint {
inline auto mirror(u32 address, u32 size) -> u32 {
if(size == 0) return 0;
uint base = 0;
uint mask = 1 << 31;
u32 base = 0;
u32 mask = 1 << 31;
while(address >= size) {
while(!(address & mask)) mask >>= 1;
address -= mask;
@@ -18,9 +18,9 @@ inline auto mirror(uint address, uint size) -> uint {
return base + address;
}
inline auto reduce(uint address, uint mask) -> uint {
inline auto reduce(u32 address, u32 mask) -> u32 {
while(mask) {
uint bits = (mask & -mask) - 1;
u32 bits = (mask & -mask) - 1;
address = address >> 1 & ~bits | address & bits;
mask = (mask & mask - 1) >> 1;
}
+18 -23
View File
@@ -15,7 +15,7 @@ struct Readable {
self.mask = 0;
}
auto allocate(uint size, T fill = ~0ull) -> void {
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
@@ -25,33 +25,32 @@ struct Readable {
}
auto fill(T fill = ~0ull) -> void {
for(uint address : range(self.size)) {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->read(self.data, min(fp->size(), self.size * sizeof(T)));
for(uint address = self.size; address <= self.mask; address++) {
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->write(self.data, self.size * sizeof(T));
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> uint { return self.size; }
auto mask() const -> uint { return self.mask; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](uint address) const -> T { return self.data[address & self.mask]; }
auto read(uint address) const -> T { return self.data[address & self.mask]; }
auto write(uint address, T data) const -> void {}
auto program(uint address, T data) const -> void { self.data[address & self.mask] = data; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) const -> void {}
auto program(u32 address, T data) const -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
@@ -60,18 +59,14 @@ struct Readable {
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
const uint size = self.size;
s.integer(self.size);
s.integer(self.mask);
if(self.size != size) allocate(self.size);
s.array(self.data, self.size);
s(array_span<T>{self.data, self.size});
}
private:
//private:
struct {
T* data = nullptr;
uint size = 0;
uint mask = 0;
u32 size = 0;
u32 mask = 0;
} self;
};
+18 -23
View File
@@ -15,7 +15,7 @@ struct Writable {
self.mask = 0;
}
auto allocate(uint size, T fill = ~0ull) -> void {
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
@@ -25,35 +25,34 @@ struct Writable {
}
auto fill(T fill = ~0ull) -> void {
for(uint address : range(self.size)) {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->read(self.data, min(fp->size(), self.size * sizeof(T)));
for(uint address = self.size; address <= self.mask; address++) {
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->write(self.data, self.size * sizeof(T));
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() -> T* { return self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> uint { return self.size; }
auto mask() const -> uint { return self.mask; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](uint address) -> T& { return self.data[address & self.mask]; }
auto operator[](uint address) const -> T { return self.data[address & self.mask]; }
auto read(uint address) const -> T { return self.data[address & self.mask]; }
auto write(uint address, T data) -> void { self.data[address & self.mask] = data; }
auto program(uint address, T data) -> void { self.data[address & self.mask] = data; }
auto operator[](u32 address) -> T& { return self.data[address & self.mask]; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto program(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
@@ -62,18 +61,14 @@ struct Writable {
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
const uint size = self.size;
s.integer(self.size);
s.integer(self.mask);
if(self.size != size) allocate(self.size);
s.array(self.data, self.size);
s(array_span<T>{self.data, self.size});
}
private:
struct {
T* data = nullptr;
uint size = 0;
uint mask = 0;
u32 size = 0;
u32 mask = 0;
} self;
};
+4
View File
@@ -0,0 +1,4 @@
struct Audio : Object {
DeclareClass(Audio, "audio")
using Object::Object;
};
+24 -22
View File
@@ -1,14 +1,14 @@
auto Stream::setChannels(uint channels) -> void {
auto Stream::setChannels(u32 channels) -> void {
_channels.reset();
_channels.resize(channels);
}
auto Stream::setFrequency(double frequency) -> void {
auto Stream::setFrequency(f64 frequency) -> void {
_frequency = frequency;
setResamplerFrequency(_resamplerFrequency);
}
auto Stream::setResamplerFrequency(double resamplerFrequency) -> void {
auto Stream::setResamplerFrequency(f64 resamplerFrequency) -> void {
_resamplerFrequency = resamplerFrequency;
for(auto& channel : _channels) {
@@ -18,12 +18,12 @@ auto Stream::setResamplerFrequency(double resamplerFrequency) -> void {
if(_frequency >= _resamplerFrequency * 2) {
//add a low-pass filter to prevent aliasing during resampling
double cutoffFrequency = min(25000.0, _resamplerFrequency / 2.0 - 2000.0);
f64 cutoffFrequency = min(25000.0, _resamplerFrequency / 2.0 - 2000.0);
for(auto& channel : _channels) {
uint passes = 3;
for(uint pass : range(passes)) {
u32 passes = 3;
for(u32 pass : range(passes)) {
DSP::IIR::Biquad filter;
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.nyquist.append(filter);
}
@@ -41,9 +41,9 @@ auto Stream::resetFilters() -> void {
}
}
auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -> void {
auto Stream::addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(uint pass : range(passes)) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::LowPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::LowPass, cutoffFrequency, _frequency);
@@ -51,7 +51,7 @@ auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowPass, Filter::Order::Second};
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -59,9 +59,9 @@ auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -
}
}
auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes) -> void {
auto Stream::addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(uint pass : range(passes)) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::HighPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::HighPass, cutoffFrequency, _frequency);
@@ -69,7 +69,7 @@ auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes)
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighPass, Filter::Order::Second};
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -77,22 +77,22 @@ auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes)
}
}
auto Stream::addLowShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void {
auto Stream::addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowShelf, Filter::Order::Second};
double q = DSP::IIR::Biquad::shelf(gain, slope);
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
auto Stream::addHighShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void {
auto Stream::addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighShelf, Filter::Order::Second};
double q = DSP::IIR::Biquad::shelf(gain, slope);
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -103,14 +103,16 @@ auto Stream::pending() const -> bool {
return _channels && _channels[0].resampler.pending();
}
auto Stream::read(double samples[]) -> uint {
for(uint c : range(_channels.size())) samples[c] = _channels[c].resampler.read() * !muted();
auto Stream::read(f64 samples[]) -> u32 {
for(u32 c : range(_channels.size())) {
samples[c] = _channels[c].resampler.read() * !muted();
}
return _channels.size();
}
auto Stream::write(const double samples[]) -> void {
for(uint c : range(_channels.size())) {
double sample = samples[c] + 1e-25; //constant offset used to suppress denormals
auto Stream::write(const f64 samples[]) -> void {
for(u32 c : range(_channels.size())) {
f64 sample = samples[c] + 1e-25; //constant offset used to suppress denormals
for(auto& filter : _channels[c].filters) {
switch(filter.mode) {
case Filter::Mode::OnePole: sample = filter.onePole.process(sample); break;
+22 -22
View File
@@ -1,39 +1,39 @@
struct Stream : Object {
DeclareClass(Stream, "Stream")
using Object::Object;
struct Stream : Audio {
DeclareClass(Stream, "audio.stream")
using Audio::Audio;
auto channels() const -> uint { return _channels.size(); }
auto frequency() const -> double { return _frequency; }
auto resamplerFrequency() const -> double { return _resamplerFrequency; }
auto channels() const -> u32 { return _channels.size(); }
auto frequency() const -> f64 { return _frequency; }
auto resamplerFrequency() const -> f64 { return _resamplerFrequency; }
auto muted() const -> bool { return _muted; }
auto setChannels(uint channels) -> void;
auto setFrequency(double frequency) -> void;
auto setResamplerFrequency(double resamplerFrequency) -> void;
auto setChannels(u32 channels) -> void;
auto setFrequency(f64 frequency) -> void;
auto setResamplerFrequency(f64 resamplerFrequency) -> void;
auto setMuted(bool muted) -> void;
auto resetFilters() -> void;
auto addLowPassFilter(double cutoffFrequency, uint order, uint passes = 1) -> void;
auto addHighPassFilter(double cutoffFrequency, uint order, uint passes = 1) -> void;
auto addLowShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void;
auto addHighShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void;
auto addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto pending() const -> bool;
auto read(double samples[]) -> uint;
auto write(const double samples[]) -> void;
auto read(f64 samples[]) -> u32;
auto write(const f64 samples[]) -> void;
template<typename... P>
auto sample(P&&... p) -> void {
auto frame(P&&... p) -> void {
if(runAhead()) return;
double samples[sizeof...(p)] = {forward<P>(p)...};
f64 samples[sizeof...(p)] = {forward<P>(p)...};
write(samples);
}
protected:
struct Filter {
enum class Mode : uint { OnePole, Biquad } mode;
enum class Type : uint { None, LowPass, HighPass, LowShelf, HighShelf } type;
enum class Order : uint { None, First, Second } order;
enum class Mode : u32 { OnePole, Biquad } mode;
enum class Type : u32 { None, LowPass, HighPass, LowShelf, HighShelf } type;
enum class Order : u32 { None, First, Second } order;
DSP::IIR::OnePole onePole;
DSP::IIR::Biquad biquad;
};
@@ -43,7 +43,7 @@ protected:
DSP::Resampler::Cubic resampler;
};
vector<Channel> _channels;
double _frequency = 48000.0;
double _resamplerFrequency = 48000.0;
f64 _frequency = 48000.0;
f64 _resamplerFrequency = 48000.0;
bool _muted = false;
};
+2 -2
View File
@@ -13,8 +13,8 @@ struct Class {
}
template<typename T> static auto register() -> void {
if(!classes().find([&](auto instance) { return instance.identifier == T::identifier; })) {
classes().append({T::identifier, &T::create});
if(!classes().find([&](auto instance) { return instance.identifier == T::identifier(); })) {
classes().append({T::identifier(), &T::create});
} else {
throw;
}
@@ -1,4 +1,4 @@
struct Component : Object {
DeclareClass(Component, "Component")
DeclareClass(Component, "component");
using Object::Object;
};
@@ -0,0 +1,30 @@
struct RealTimeClock : Component {
DeclareClass(RealTimeClock, "component.real-time-clock")
using Component::Component;
auto update() -> void { if(_update) return _update(); }
auto timestamp() const -> u64 { return _timestamp; }
auto setUpdate(function<void ()> update) -> void { _update = update; }
auto setTimestamp(u64 timestamp) -> void { _timestamp = timestamp; }
auto synchronize(u64 timestamp = 0) -> void {
if(!timestamp) timestamp = chrono::timestamp();
_timestamp = timestamp;
update();
}
auto serialize(string& output, string depth) -> void override {
Component::serialize(output, depth);
output.append(depth, " timestamp: ", _timestamp, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Component::unserialize(node);
_timestamp = node["timestamp"].natural();
}
protected:
function<void ()> _update;
u64 _timestamp;
};
-26
View File
@@ -1,26 +0,0 @@
struct Graphics : Object {
DeclareClass(Graphics, "Graphics")
Graphics(string name = {}) : Object(name) {
}
auto width() const -> uint { return _width; }
auto height() const -> uint { return _height; }
auto capture() const -> vector<uint32_t> { if(_capture) return _capture(); return {}; }
auto setSize(uint width, uint height) -> void { _width = width, _height = height; }
auto setCapture(function<vector<uint32_t> ()> capture) -> void { _capture = capture; }
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
}
protected:
uint _width = 0;
uint _height = 0;
function<vector<uint32_t> ()> _capture;
};
Loaded 100 of 3018 files, more files were not shown because too many files have changed in this diff. Show more