Compare commits

...
198 Commits
Author SHA1 Message Date
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 c71f131b0c Merge commit '8639e306c77db691296adebcd6be33870fbec619' 2021-09-17 13:35:22 +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
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
694 changed files with 183668 additions and 4821 deletions

No files matched your search

+170
View File
@@ -0,0 +1,170 @@
name: Build
on:
push:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]
jobs:
build:
strategy:
matrix:
program:
- ares
os:
- name: windows
version: latest
- name: macos
version: latest
- name: ubuntu
version: latest
runs-on: ${{ matrix.os.name }}-${{ matrix.os.version }}
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
if: matrix.os.name == 'ubuntu'
run: |
sudo apt-get update -y -qq
sudo apt-get install libsdl2-dev libgtksourceview2.0-dev libgtk2.0-dev libao-dev libopenal-dev
- name: Make
run: make -j4 -C desktop-ui build=optimized local=false lto=true
- name: Upload
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.program }}-${{ matrix.os.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' }
+15
View File
@@ -0,0 +1,15 @@
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.
+18
View File
@@ -0,0 +1,18 @@
# ares
[![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-emulator.github.io).
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.
+2 -1
View File
@@ -10,9 +10,10 @@ else
$(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
@@ -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
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,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);;
}
+6 -5
View File
@@ -37,16 +37,16 @@ using namespace nall;
namespace ares {
static const string Name = "ares";
static const string Version = "121";
static const string Copyright = "Near";
static const string Version = "124";
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.dev";
static const string WebsiteURI = "https://ares.dev";
static const string Website = "ares-emulator.github.io";
static const string WebsiteURI = "https://ares-emulator.github.io";
//incremented only when serialization format changes
static const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
static const string SerializerVersion = "121";
static const string SerializerVersion = "123.1";
namespace VFS {
using Pak = shared_pointer<vfs::directory>;
@@ -74,6 +74,7 @@ namespace ares {
#include <ares/debug/debug.hpp>
#include <ares/node/node.hpp>
#include <ares/platform.hpp>
#include <ares/memory/fixed-allocator.hpp>
#include <ares/memory/readable.hpp>
#include <ares/memory/writable.hpp>
#include <ares/resource/resource.hpp>
+16
View File
@@ -0,0 +1,16 @@
#include <ares/ares.hpp>
namespace ares::Memory {
alignas(4096) u8 fixedBuffer[1_GiB];
FixedAllocator::FixedAllocator() {
_allocator.resize(sizeof(fixedBuffer), 0, fixedBuffer);
}
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;
};
}
+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;
}
@@ -28,7 +28,7 @@ struct Instruction : Tracer {
}
auto address(u32 address) -> bool {
address &= (1u << _addressBits) - 1; //mask upper bits of address
address &= (1ull << _addressBits) - 1; //mask upper bits of address
_address = address;
address >>= _addressMask; //clip unneeded alignment bits (to reduce _masks size)
@@ -57,7 +57,7 @@ struct Instruction : Tracer {
//call when writing to executable RAM to support self-modifying code.
auto invalidate(u32 address) -> void {
if(unlikely(_mask && updateMasks())) {
address &= (1u << _addressBits) - 1;
address &= (1ull << _addressBits) - 1;
address >>= _addressMask;
_masks[address >> 3] &= ~(1 << (address & 7));
}
+5 -5
View File
@@ -1,14 +1,14 @@
//identifier is static, allowing template<typename T> to access via T::identifier
//identifier() is static, allowing template<typename T> to access via T::identifier()
//identity() is virtual, allowing T* to access via T->identity()
#define DeclareClass(Type, Name) \
static inline const string identifier = Name; \
static auto identifier() -> string { return Name; } \
static auto create() -> Node::Object { return new Type; } \
auto identity() const -> string override { return Name; } \
private: static inline Class::Register<Type> register; public: \
struct Object : shared_pointer_this<Object> {
static inline const string identifier = "Object";
static auto identifier() -> string { return "Object"; }
static auto create() -> Node::Object { return new Object; }
virtual auto identity() const -> string { return "Object"; }
private: static inline Class::Register<Object> register; public:
@@ -112,7 +112,7 @@ struct Object : shared_pointer_this<Object> {
for(auto& node : _nodes) {
if(node->_name != name) continue;
if(path) return node->find<T>(path.merge("/"));
if(node->identity() == Type::identifier) return node;
if(node->identity() == Type::identifier()) return node;
}
return {};
}
@@ -121,7 +121,7 @@ struct Object : shared_pointer_this<Object> {
auto scan(string name) -> T {
using Type = typename T::type;
for(auto& node : _nodes) {
if(node->identity() == Type::identifier && node->_name == name) return node;
if(node->identity() == Type::identifier() && node->_name == name) return node;
if(auto result = node->scan<T>(name)) return result;
}
return {};
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+4 -2
View File
@@ -1,7 +1,9 @@
namespace name=Resource
namespace name=Ares
binary name=Icon file=icon.png
binary name=Logo file=logo.png
binary name=Icon1x file=icon.png
binary name=Icon2x file=icon@2x.png
binary name=Logo1x file=logo.png
binary name=Logo2x [email protected]
namespace name=Sprite
namespace name=SuperFamicom
binary name=CrosshairBlue file=sprite/sfc/crosshair-blue.png
+902 -2
View File
@@ -2,7 +2,7 @@
namespace Resource {
namespace Ares {
const unsigned char Icon[6562] = {
const unsigned char Icon1x[6562] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,128,0,0,0,128,8,6,0,0,0,195,62,97,
203,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0,
@@ -210,7 +210,311 @@ const unsigned char Icon[6562] = {
45,50,53,84,48,51,58,48,48,58,50,49,43,48,57,58,48,48,84,98,58,187,0,0,0,0,73,69,78,68,174,66,
96,130,
};
const unsigned char Logo[11533] = {
const unsigned char Icon2x[9662] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,0,0,0,1,0,8,6,0,0,0,92,114,168,
102,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,5,26,105,84,88,116,88,77,
76,58,99,111,109,46,97,100,111,98,101,46,120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,
103,105,110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104,105,72,122,114,101,83,122,78,84,
99,122,107,99,57,100,34,63,62,32,60,120,58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100,
111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116,107,61,34,65,100,111,98,101,32,88,77,80,
32,67,111,114,101,32,53,46,54,45,99,49,52,53,32,55,57,46,49,54,51,52,57,57,44,32,50,48,49,56,47,48,
56,47,49,51,45,49,54,58,52,48,58,50,50,32,32,32,32,32,32,32,32,34,62,32,60,114,100,102,58,82,68,70,
32,120,109,108,110,115,58,114,100,102,61,34,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,
57,57,47,48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34,62,32,60,114,100,102,58,68,
101,115,99,114,105,112,116,105,111,110,32,114,100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109,
112,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,34,
32,120,109,108,110,115,58,100,99,61,34,104,116,116,112,58,47,47,112,117,114,108,46,111,114,103,47,100,99,47,101,108,
101,109,101,110,116,115,47,49,46,49,47,34,32,120,109,108,110,115,58,112,104,111,116,111,115,104,111,112,61,34,104,116,
116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,112,104,111,116,111,115,104,111,112,47,49,46,48,47,
34,32,120,109,108,110,115,58,120,109,112,77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,
111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120,109,108,110,115,58,115,116,69,118,116,61,34,104,116,116,
112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101,47,82,
101,115,111,117,114,99,101,69,118,101,110,116,35,34,32,120,109,112,58,67,114,101,97,116,111,114,84,111,111,108,61,34,
65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,67,32,50,48,49,57,32,40,77,97,99,105,110,116,111,
115,104,41,34,32,120,109,112,58,67,114,101,97,116,101,68,97,116,101,61,34,50,48,50,49,45,48,56,45,50,55,84,
50,48,58,49,49,58,52,52,43,48,51,58,48,48,34,32,120,109,112,58,77,111,100,105,102,121,68,97,116,101,61,34,
50,48,50,49,45,48,57,45,48,51,84,50,49,58,53,53,43,48,51,58,48,48,34,32,120,109,112,58,77,101,116,97,
100,97,116,97,68,97,116,101,61,34,50,48,50,49,45,48,57,45,48,51,84,50,49,58,53,53,43,48,51,58,48,48,
34,32,100,99,58,102,111,114,109,97,116,61,34,105,109,97,103,101,47,112,110,103,34,32,112,104,111,116,111,115,104,111,
112,58,67,111,108,111,114,77,111,100,101,61,34,51,34,32,112,104,111,116,111,115,104,111,112,58,73,67,67,80,114,111,
102,105,108,101,61,34,115,82,71,66,32,73,69,67,54,49,57,54,54,45,50,46,49,34,32,120,109,112,77,77,58,73,
110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,57,57,49,53,52,98,56,52,45,100,100,54,48,
45,52,100,101,54,45,97,54,57,101,45,54,55,49,49,100,54,48,49,57,98,57,55,34,32,120,109,112,77,77,58,68,
111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,57,57,49,53,52,98,56,52,45,100,100,54,48,
45,52,100,101,54,45,97,54,57,101,45,54,55,49,49,100,54,48,49,57,98,57,55,34,32,120,109,112,77,77,58,79,
114,105,103,105,110,97,108,68,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,57,57,49,53,52,
98,56,52,45,100,100,54,48,45,52,100,101,54,45,97,54,57,101,45,54,55,49,49,100,54,48,49,57,98,57,55,34,
62,32,60,120,109,112,77,77,58,72,105,115,116,111,114,121,62,32,60,114,100,102,58,83,101,113,62,32,60,114,100,102,
58,108,105,32,115,116,69,118,116,58,97,99,116,105,111,110,61,34,99,114,101,97,116,101,100,34,32,115,116,69,118,116,
58,105,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,57,57,49,53,52,98,56,52,45,100,100,
54,48,45,52,100,101,54,45,97,54,57,101,45,54,55,49,49,100,54,48,49,57,98,57,55,34,32,115,116,69,118,116,
58,119,104,101,110,61,34,50,48,50,49,45,48,56,45,50,55,84,50,48,58,49,49,58,52,52,43,48,51,58,48,48,
34,32,115,116,69,118,116,58,115,111,102,116,119,97,114,101,65,103,101,110,116,61,34,65,100,111,98,101,32,80,104,111,
116,111,115,104,111,112,32,67,67,32,50,48,49,57,32,40,77,97,99,105,110,116,111,115,104,41,34,47,62,32,60,47,
114,100,102,58,83,101,113,62,32,60,47,120,109,112,77,77,58,72,105,115,116,111,114,121,62,32,60,47,114,100,102,58,
68,101,115,99,114,105,112,116,105,111,110,62,32,60,47,114,100,102,58,82,68,70,62,32,60,47,120,58,120,109,112,109,
101,116,97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,63,62,126,10,193,94,0,0,32,74,
73,68,65,84,120,218,237,157,7,120,85,69,250,198,79,122,51,64,2,9,65,136,161,44,144,64,64,8,1,130,139,64,
32,148,16,52,20,19,66,2,1,87,141,96,89,89,117,109,8,130,178,128,168,43,118,212,85,97,117,45,232,95,220,181,
128,53,161,153,32,189,151,132,14,2,162,20,197,10,100,254,243,221,51,147,76,46,9,105,183,156,115,238,251,62,207,251,
60,130,64,206,61,231,251,126,119,206,204,55,223,104,140,49,13,134,97,207,52,110,2,12,3,0,48,12,3,0,48,12,
3,0,48,12,3,0,48,12,3,0,48,12,3,0,48,12,3,0,48,12,3,0,48,12,3,0,48,12,3,0,48,12,
3,0,48,12,3,0,48,12,91,29,0,144,169,228,195,237,47,28,200,29,36,28,40,28,160,252,154,254,76,4,183,47,
110,155,121,4,0,64,142,212,25,238,2,238,111,133,183,136,95,47,226,126,130,251,54,238,97,220,29,185,67,112,187,0,
0,200,98,241,36,124,150,123,21,247,73,229,247,42,51,65,226,83,238,185,220,185,220,93,197,72,2,2,0,32,19,170,
192,46,193,127,108,210,56,48,191,109,235,6,103,3,3,125,88,53,48,144,62,199,189,134,123,30,119,38,247,229,184,173,
0,0,100,30,253,153,251,43,53,169,189,189,189,142,253,109,82,231,229,59,86,103,94,248,124,113,26,251,215,211,125,216,
180,123,18,88,214,200,54,172,83,135,112,230,239,231,93,29,20,246,113,47,228,30,195,221,24,183,24,0,128,140,175,193,
226,155,188,44,145,27,134,250,111,89,186,104,232,246,211,251,39,48,213,39,74,114,89,225,167,233,236,229,167,250,176,219,
243,226,89,207,110,145,44,192,191,202,17,195,121,238,66,238,105,220,221,185,189,112,171,1,0,200,152,162,228,204,224,62,
160,36,240,133,132,43,155,44,63,188,53,231,172,61,8,84,31,223,61,142,45,125,111,40,155,113,95,34,75,29,24,205,
66,47,243,171,10,8,251,185,31,227,78,196,237,6,0,32,99,42,148,123,54,247,111,50,113,253,252,188,15,46,120,174,
239,186,75,65,192,126,148,240,225,91,67,216,29,19,227,89,199,216,176,170,96,176,135,123,22,119,28,110,57,0,0,25,
79,109,237,231,7,58,180,15,91,249,237,246,177,103,107,10,2,233,29,69,153,236,177,135,147,216,85,61,154,210,28,67,
101,48,88,161,233,43,11,193,184,237,0,0,100,172,215,130,60,77,175,25,176,37,107,64,128,247,158,207,254,47,109,71,
109,33,32,189,115,117,38,155,243,80,79,150,148,24,201,188,188,46,2,193,41,238,231,52,189,246,0,2,0,32,131,40,
134,123,185,146,168,191,229,229,198,22,212,21,2,210,219,11,51,216,244,123,187,177,22,151,135,84,54,42,88,201,125,13,
38,14,1,0,200,24,242,230,190,131,251,119,153,164,237,218,52,88,85,151,87,2,123,127,207,231,12,222,120,177,63,27,
148,220,162,178,87,132,245,220,57,220,126,0,0,0,0,185,95,61,52,125,54,223,150,160,129,129,190,187,87,127,49,124,
127,125,33,32,189,105,197,117,108,226,245,113,44,56,216,183,178,21,4,122,29,241,5,0,0,0,200,189,162,2,159,79,
101,114,242,119,249,211,175,207,239,191,222,81,16,32,31,220,146,205,230,76,235,193,46,111,118,209,235,193,94,1,2,31,
0,0,0,128,220,59,65,120,47,247,5,145,152,231,38,79,234,180,220,145,16,144,53,6,143,63,146,196,154,69,5,219,
131,96,51,119,42,0,0,0,64,238,213,104,238,95,69,82,150,166,167,198,228,159,218,55,161,212,209,32,248,174,56,151,
205,155,117,21,139,138,12,178,7,193,231,220,241,0,0,0,0,185,79,73,220,199,101,82,82,245,224,201,189,227,47,56,
26,2,100,62,233,104,91,57,104,216,192,95,133,192,31,220,79,114,55,2,0,0,0,200,61,162,194,161,98,77,41,26,
250,97,207,248,243,206,128,0,185,100,125,22,187,62,187,61,243,241,169,176,106,240,157,166,175,24,0,0,0,0,228,6,
69,105,122,99,17,91,66,182,140,9,45,60,94,156,251,187,179,32,64,94,253,197,8,150,210,183,185,253,107,193,18,77,
175,93,0,0,0,0,200,197,10,227,46,146,201,24,19,29,90,196,215,249,207,57,19,2,228,133,207,247,179,159,31,248,
73,211,235,22,124,0,0,0,0,114,173,26,106,122,151,33,253,117,32,54,108,165,179,230,4,84,31,216,156,205,114,179,
218,217,151,24,83,69,97,43,0,0,0,128,92,171,6,154,210,99,160,115,199,240,21,206,88,29,168,204,75,22,165,242,
42,197,134,42,4,104,47,67,30,0,0,0,64,174,85,19,117,78,96,120,90,203,124,87,0,128,124,108,231,56,118,243,
132,56,251,209,192,155,154,137,87,10,0,0,200,140,106,198,93,34,18,176,116,234,221,221,86,186,10,2,228,119,23,12,
100,77,35,130,236,75,138,19,1,0,0,0,114,157,218,104,250,18,157,109,205,190,54,205,69,28,181,100,72,157,138,20,
8,252,102,198,87,2,0,0,50,179,122,107,162,98,144,15,203,79,57,114,3,81,77,204,231,31,108,123,11,252,124,43,
52,53,125,73,211,15,76,1,0,0,0,200,5,162,178,225,82,77,236,34,116,196,86,226,186,76,16,218,189,18,172,214,
76,210,206,28,0,128,172,160,89,154,210,79,192,213,0,32,23,175,203,98,87,247,138,82,33,112,68,211,15,58,1,0,
0,0,200,201,162,194,156,207,100,242,229,77,136,43,112,7,4,104,115,209,95,114,218,219,47,21,14,2,0,0,0,200,
249,10,215,244,125,253,182,9,185,47,22,167,237,114,7,4,200,52,47,160,116,33,162,115,12,38,1,0,0,0,228,124,
245,212,244,163,197,88,96,128,79,49,95,183,255,197,93,16,248,247,11,201,204,238,56,180,105,0,0,0,0,57,95,83,
101,210,93,213,35,106,153,187,0,64,254,242,191,195,88,100,147,10,147,131,116,8,170,23,0,0,65,206,157,15,88,33,
18,174,116,225,11,253,214,187,19,2,212,143,48,38,250,50,21,2,243,53,189,25,42,0,0,65,78,82,75,238,31,41,
190,249,193,163,7,142,238,24,251,179,59,33,176,101,213,117,172,117,203,6,42,4,94,211,12,178,163,16,0,128,172,170,
219,101,194,245,239,211,188,192,157,0,32,239,94,59,154,118,48,170,16,88,104,132,145,0,0,0,89,85,148,92,95,139,
100,59,199,15,26,221,225,110,8,236,225,229,195,124,7,163,10,129,103,1,0,8,114,158,98,53,113,32,41,29,77,238,
170,173,195,213,65,32,182,93,35,21,2,79,2,0,16,228,60,205,145,201,54,227,129,196,85,238,6,128,60,203,208,110,
78,96,42,0,0,65,206,17,29,77,254,45,197,58,111,246,121,212,29,123,5,42,243,54,126,134,225,21,45,42,172,14,
76,2,0,32,200,57,186,94,38,218,136,97,173,242,141,0,0,242,218,252,145,172,73,120,160,218,134,124,16,0,0,65,
206,153,16,92,171,233,219,134,207,236,221,48,230,164,81,32,240,21,47,22,10,10,42,59,179,144,150,46,175,4,0,32,
200,241,74,149,163,128,212,148,104,195,140,2,100,247,97,101,239,192,65,205,133,91,137,1,0,200,147,180,92,36,217,217,
93,107,70,159,48,18,4,30,190,63,81,157,15,160,22,232,1,0,0,4,57,86,253,101,146,13,78,110,97,168,81,0,
121,66,118,59,251,146,97,0,0,130,156,49,10,160,227,199,15,109,205,254,201,72,0,56,81,146,203,122,245,104,170,66,
224,6,0,0,130,28,171,107,101,130,221,148,27,91,96,180,81,0,127,53,97,81,77,203,142,45,167,126,135,137,0,0,
4,57,78,180,29,119,59,197,190,175,143,215,97,87,28,49,86,91,127,194,123,12,250,150,55,26,165,38,39,13,1,0,
8,114,156,242,228,40,96,238,140,158,133,70,3,0,121,214,212,238,234,171,192,27,0,0,4,57,78,65,220,63,80,252,
71,69,4,175,53,34,0,168,229,248,144,1,21,206,29,200,6,0,32,200,113,122,90,36,214,133,13,5,35,15,25,17,
2,116,248,136,210,110,252,180,166,247,57,0,0,32,200,1,234,36,191,93,211,83,99,242,141,8,0,242,162,215,82,212,
179,8,169,211,145,55,0,0,65,142,81,161,166,111,18,58,98,132,173,194,85,57,111,124,156,250,42,112,59,0,0,65,
142,209,68,153,88,252,192,207,205,70,5,0,157,74,172,108,31,166,253,2,87,0,0,16,84,127,209,81,227,182,54,226,
189,147,162,10,140,10,0,242,71,111,15,81,95,5,62,1,0,32,200,49,178,157,40,196,55,227,28,255,97,207,248,243,
70,134,192,216,204,182,234,171,192,24,0,0,130,234,175,27,101,82,45,122,37,101,147,145,1,176,127,83,182,186,42,112,
92,115,64,129,16,0,0,225,53,128,47,5,106,6,221,32,100,239,87,159,237,171,142,2,30,7,0,32,168,254,162,227,
188,169,49,199,78,163,3,128,204,231,43,212,46,66,237,1,0,8,170,159,166,139,132,42,229,189,250,142,25,29,0,43,
151,92,75,75,151,18,2,31,2,0,16,84,63,37,201,97,245,148,59,187,172,48,195,40,96,252,152,10,189,3,134,0,
0,16,84,119,209,49,93,167,40,31,58,119,8,55,5,0,138,215,101,177,6,161,254,18,0,155,181,58,86,8,2,0,
16,164,139,214,214,153,191,191,247,62,51,0,128,60,237,158,4,117,20,144,1,0,64,80,221,53,69,206,3,24,173,95,
96,85,230,103,28,176,136,198,101,109,197,183,105,117,56,112,20,0,128,32,93,125,229,183,233,188,217,189,138,204,50,10,
152,57,165,66,223,128,28,0,0,130,234,166,96,77,148,5,167,13,140,206,55,11,0,104,159,64,84,100,89,113,208,110,
110,95,0,0,130,234,38,91,171,176,22,205,67,86,155,5,0,228,71,167,247,172,115,137,48,0,0,65,229,122,155,114,
130,247,227,59,100,38,0,28,223,61,78,45,17,94,11,0,64,80,61,39,2,247,111,26,115,218,76,16,120,224,206,174,
234,40,32,25,0,128,160,218,171,172,101,248,251,175,15,218,98,38,0,236,219,56,134,5,7,151,157,49,248,17,0,0,
65,181,87,7,9,128,25,15,36,174,50,19,0,200,55,142,139,149,0,40,21,159,5,0,128,160,90,40,72,36,15,203,
24,222,38,223,108,0,88,95,48,82,61,100,244,89,0,0,130,106,175,99,148,23,93,59,55,89,110,54,0,144,83,250,
54,87,187,8,7,3,0,16,84,59,125,77,121,17,209,56,104,189,25,1,240,250,252,100,117,50,112,28,0,0,65,181,
211,187,148,23,129,1,62,37,102,4,0,63,234,76,45,12,90,6,0,64,80,237,68,199,114,211,187,244,119,102,4,0,
121,242,164,78,234,40,32,14,0,128,160,154,235,31,34,113,206,25,249,172,128,234,38,3,149,14,194,51,1,0,8,170,
185,238,148,223,158,102,43,6,82,221,35,33,66,2,160,4,0,128,160,154,107,130,4,192,186,130,145,7,205,10,128,217,
211,122,168,175,1,9,0,0,4,213,76,89,50,113,120,239,189,61,102,5,192,206,111,70,171,53,1,143,2,0,16,84,
51,141,144,0,248,98,113,218,46,179,2,128,156,212,189,169,4,192,1,110,47,0,0,130,170,215,80,9,128,143,223,30,
178,205,204,0,176,219,38,220,13,0,128,160,234,53,64,38,205,123,11,140,125,82,80,117,230,45,206,85,0,60,8,0,
64,144,7,1,128,28,219,174,145,4,192,74,0,0,130,60,232,21,128,124,123,94,188,4,192,121,238,112,0,0,130,60,
100,18,144,252,223,255,12,86,95,3,50,1,0,8,186,180,44,177,12,40,253,93,113,46,11,9,241,147,0,120,21,0,
128,160,75,107,130,102,129,66,32,213,131,251,183,168,178,42,16,0,128,160,138,186,75,2,224,192,150,236,51,86,0,192,
67,247,118,83,95,3,154,1,0,16,84,181,102,137,68,249,195,172,155,129,236,189,100,81,170,10,128,81,0,0,4,85,
173,23,53,125,59,240,113,43,36,191,108,27,30,224,239,35,1,240,79,0,0,130,170,150,108,8,82,108,21,0,144,187,
119,45,219,29,248,13,0,0,65,85,171,80,51,113,75,176,170,124,219,77,29,37,0,254,224,246,7,0,32,168,114,153,
186,41,104,85,126,241,201,171,213,121,128,206,0,0,4,93,172,178,182,224,163,71,152,175,45,248,165,188,106,105,186,10,
128,177,0,0,4,93,44,83,31,12,114,41,159,224,205,66,253,253,188,47,234,15,0,0,64,80,185,202,142,6,251,224,
205,193,91,172,4,0,114,135,216,48,9,128,37,0,0,4,93,172,169,34,65,74,15,109,201,249,209,106,0,200,28,222,
90,2,224,48,0,0,65,23,107,17,229,132,159,159,247,65,171,37,63,249,193,187,19,212,179,3,131,1,0,8,170,168,
29,148,19,209,205,67,138,172,8,128,151,230,245,81,39,2,99,1,0,8,42,23,125,35,210,158,121,54,108,112,76,190,
21,1,176,244,189,161,42,0,82,1,0,8,42,87,178,76,142,103,30,237,189,218,138,0,216,185,58,83,5,192,45,0,
0,4,85,50,1,184,123,109,214,247,86,4,0,223,220,68,37,206,18,0,115,1,0,8,42,215,82,202,135,0,127,239,
189,86,76,126,233,182,173,27,74,0,188,3,0,64,144,46,31,238,211,148,15,157,59,134,175,176,50,0,122,245,40,59,
43,224,75,0,0,130,116,245,146,239,198,15,222,149,96,105,0,164,13,186,66,2,96,19,0,0,65,186,30,150,239,255,
188,151,254,49,43,3,32,55,171,157,4,192,17,0,0,130,116,209,30,121,22,18,228,187,195,202,201,79,158,60,169,147,
4,192,111,238,2,128,15,226,13,50,144,34,184,47,80,46,12,25,16,157,111,117,0,60,124,127,162,186,20,232,227,14,
0,248,35,230,32,3,233,38,205,66,39,1,85,231,167,102,95,165,2,32,192,29,0,8,64,204,65,6,18,205,134,83,
15,192,99,39,247,142,191,96,117,0,204,127,162,66,99,144,32,119,0,32,16,49,7,25,104,248,127,142,146,161,119,175,
168,2,171,39,63,249,213,103,251,170,0,8,118,7,0,130,16,119,144,65,116,139,76,134,247,95,31,184,217,19,0,240,
198,139,253,85,0,92,230,14,0,4,35,238,32,131,104,53,37,130,143,143,215,17,171,156,1,80,157,23,189,150,162,2,
32,20,35,0,200,83,213,73,38,194,240,180,150,249,158,144,252,149,28,22,218,16,0,128,60,85,207,136,36,184,176,97,
217,168,195,0,0,38,1,33,207,17,125,9,157,164,36,136,138,8,94,235,41,201,143,87,0,8,210,117,179,76,130,199,
31,73,42,244,36,0,24,97,18,16,35,0,200,157,242,210,68,235,47,95,95,239,67,223,151,228,158,243,36,0,188,242,
140,251,151,1,81,8,4,185,83,195,101,2,228,77,136,43,240,164,228,55,74,33,16,21,95,156,17,23,80,128,120,132,
92,172,149,20,123,94,94,218,169,195,91,115,206,122,26,0,140,80,10,236,43,18,95,94,68,50,98,18,114,145,82,100,
220,121,194,198,159,202,60,227,62,247,111,6,34,29,229,254,73,92,196,74,196,37,228,34,21,138,111,255,179,187,214,140,
62,225,137,0,184,99,98,188,76,254,95,233,134,184,19,0,249,10,137,6,33,54,33,39,43,77,198,155,85,219,126,215,
196,99,51,219,86,56,29,200,93,0,216,162,233,235,176,63,138,139,89,195,237,141,24,133,156,36,138,173,245,226,219,255,
244,190,141,217,167,60,21,0,67,7,150,181,4,219,232,78,0,216,190,253,155,52,14,84,71,1,19,16,167,144,147,116,
163,140,179,235,210,91,121,236,183,63,57,169,123,89,83,208,47,220,9,128,119,233,103,243,22,197,191,208,70,12,113,65,
199,184,27,32,86,33,7,43,84,188,114,218,54,253,28,221,49,246,103,79,6,192,159,90,53,48,68,91,240,39,232,103,
7,6,250,208,172,228,74,101,20,48,11,241,10,57,88,143,203,248,154,61,173,199,215,158,156,252,118,7,131,60,234,78,
0,220,46,31,10,159,141,45,109,212,208,127,147,248,245,239,220,29,16,179,144,131,68,59,254,254,160,216,226,49,182,217,
83,182,252,214,240,104,176,73,238,4,192,48,121,33,159,47,78,99,75,23,13,221,174,137,131,25,53,125,89,16,19,130,
80,125,69,205,103,139,68,76,157,251,124,241,208,157,158,156,252,70,59,28,52,94,94,8,213,38,211,197,37,95,221,172,
64,185,184,91,17,191,80,61,53,89,198,211,224,228,22,249,158,158,252,228,23,159,188,218,48,199,131,135,200,11,153,118,
79,130,237,226,104,114,198,207,207,251,160,248,125,90,30,140,65,12,67,117,84,43,77,20,154,249,251,123,239,63,182,115,
220,47,0,192,4,54,229,174,174,50,249,75,53,177,43,215,157,7,131,124,75,63,63,107,100,155,178,11,92,240,92,223,
117,226,226,232,15,46,215,112,134,0,84,123,81,169,249,42,25,232,175,207,239,191,30,201,175,59,35,189,181,4,192,33,
121,179,220,9,0,219,105,172,157,58,132,87,184,200,158,137,145,203,148,97,202,20,196,51,84,75,77,151,241,211,59,41,
170,0,137,95,238,184,246,97,50,175,62,54,2,0,230,218,134,104,126,222,236,187,226,220,178,139,164,225,26,95,170,40,
17,23,74,51,184,61,16,211,80,13,117,149,38,218,124,243,37,230,226,99,187,198,253,138,196,215,77,57,70,185,38,242,
106,182,17,0,48,78,146,186,240,211,244,10,23,91,240,191,97,197,154,190,89,129,254,255,1,238,38,136,109,168,26,53,
230,222,39,98,230,183,47,22,167,237,66,226,151,123,229,146,107,213,9,192,108,35,0,224,74,121,65,47,63,213,231,162,
11,206,203,141,85,87,5,62,195,124,0,84,205,123,255,151,50,94,110,189,161,195,50,36,189,93,35,144,127,86,88,1,
136,55,2,0,2,196,16,159,253,245,230,248,74,47,186,67,108,24,170,4,161,154,104,174,140,147,246,127,106,180,10,9,
127,177,111,187,169,163,204,35,42,182,243,55,2,0,72,182,99,153,147,18,35,43,189,232,111,183,143,61,75,239,114,202,
210,69,22,98,29,178,83,182,92,57,10,10,242,221,229,233,181,254,85,57,177,75,132,4,64,161,122,243,220,13,128,39,
233,26,2,252,125,24,159,176,169,244,194,139,62,27,190,143,182,112,106,229,77,12,122,35,230,33,161,62,154,126,206,189,
173,197,215,154,47,71,30,64,178,95,108,62,177,174,78,0,62,110,36,0,100,200,161,219,167,255,55,180,202,15,240,214,
191,250,111,148,15,154,251,123,238,118,136,125,143,87,27,238,239,228,106,209,194,23,250,97,189,191,10,127,252,206,16,245,
253,127,132,145,0,112,185,188,176,135,239,79,188,116,21,211,157,93,86,104,229,69,66,244,90,16,133,28,240,88,81,220,
236,145,175,134,15,221,211,109,37,18,189,106,79,253,123,130,10,128,40,35,1,64,147,75,55,169,3,163,171,253,32,233,
169,49,106,3,145,45,98,233,7,242,44,209,146,240,86,25,7,163,174,105,133,58,255,106,60,40,185,5,83,190,56,53,
163,1,96,1,93,71,232,101,126,236,68,73,110,117,251,153,75,123,36,68,168,149,130,27,184,195,144,19,30,163,134,154,
222,62,206,246,252,169,106,20,9,126,105,31,223,61,142,133,132,248,201,124,121,197,136,0,24,35,31,40,189,171,84,247,
129,78,238,29,127,161,67,251,10,203,131,171,68,96,64,214,86,35,238,175,229,115,239,24,23,182,130,98,1,73,126,105,
127,240,198,32,117,248,127,157,17,1,16,174,137,94,0,127,155,212,169,70,31,234,135,61,227,207,243,214,70,95,43,31,
108,157,134,106,65,43,139,98,100,181,124,222,49,209,161,69,158,118,164,151,3,214,255,207,139,251,104,56,0,104,98,109,
146,197,199,133,215,124,104,83,156,251,123,203,152,208,66,187,57,129,102,200,21,75,78,248,109,147,207,185,85,76,131,66,
122,246,72,238,154,57,182,93,35,153,31,43,42,187,185,70,1,192,52,177,150,203,118,20,101,214,248,195,209,72,192,174,
90,176,4,75,132,150,82,123,101,182,223,54,236,167,103,142,196,174,153,183,21,102,168,195,255,41,70,6,64,162,86,126,
92,115,109,27,29,150,210,182,79,229,131,254,192,221,23,185,99,122,245,210,202,215,249,89,247,174,17,203,240,206,95,59,
63,58,189,167,10,128,174,70,6,128,151,92,14,252,115,207,168,186,116,59,45,29,158,214,146,150,8,101,157,0,21,13,
161,108,216,188,202,214,202,11,191,74,177,212,87,55,247,236,22,41,147,127,143,200,49,195,2,128,100,219,208,225,237,237,
85,171,215,128,10,5,15,119,119,163,215,129,223,181,242,189,3,79,105,250,78,49,200,28,162,29,159,211,21,144,255,62,
237,239,40,242,169,235,240,159,94,169,181,106,54,210,25,9,0,101,175,1,115,30,234,89,231,15,78,45,160,148,189,3,
114,43,49,86,8,140,47,58,54,190,108,75,47,127,134,39,169,4,28,201,92,55,207,156,210,93,29,254,119,49,3,0,
72,182,157,127,85,237,14,172,169,87,127,49,124,127,96,160,239,110,229,6,236,231,238,137,28,51,172,168,147,143,108,8,
107,219,213,135,141,61,245,115,194,149,77,100,236,239,186,212,141,55,26,0,102,203,213,128,13,203,70,213,111,7,20,111,
7,21,223,33,124,133,2,1,106,21,53,135,219,15,249,102,168,33,255,189,154,232,11,161,137,253,252,216,210,91,63,175,
249,106,132,58,252,159,105,38,0,180,151,239,127,119,222,210,217,33,55,35,111,66,92,129,50,161,36,215,67,91,34,247,
220,46,106,221,189,74,121,46,191,222,150,23,143,210,94,7,152,26,236,104,118,253,255,205,2,0,146,109,93,191,105,68,
80,181,123,3,106,234,101,31,93,91,76,195,74,229,166,252,44,190,121,208,102,204,245,162,83,159,242,180,242,163,225,233,
188,186,18,244,240,115,140,41,103,40,119,196,189,45,168,238,97,24,17,0,227,101,96,252,231,165,254,142,107,138,192,95,
9,6,38,183,160,27,114,65,1,1,149,19,119,68,78,186,76,212,139,78,173,222,44,229,239,170,203,49,228,119,156,23,
62,223,79,253,246,207,49,35,0,232,196,146,147,116,109,180,141,209,225,55,136,55,142,224,221,81,14,40,55,233,119,49,
247,16,138,252,116,154,104,179,214,99,234,187,62,157,216,243,198,139,3,54,32,105,29,235,148,190,205,101,92,159,226,14,
54,35,0,72,207,105,250,121,238,245,158,12,172,162,69,210,47,162,112,232,15,5,4,39,184,239,192,107,129,195,135,251,
185,220,199,212,201,88,170,220,164,126,143,72,88,199,122,93,254,72,91,29,141,184,207,79,215,228,1,25,21,0,29,229,
100,224,77,185,177,206,60,45,117,7,29,27,173,4,39,121,45,247,16,228,110,189,53,148,123,189,122,111,195,26,249,111,
194,41,189,206,243,13,99,99,213,179,255,98,205,12,0,210,39,98,77,152,237,89,159,229,212,27,247,236,220,222,171,125,
125,189,15,217,129,128,222,85,175,65,30,215,90,189,197,228,83,217,189,228,35,185,163,84,165,73,37,219,72,84,231,120,
239,134,49,44,56,216,87,222,243,255,214,244,97,25,25,0,3,100,0,61,120,119,130,211,111,32,77,68,141,24,214,42,
159,175,159,158,177,3,1,29,82,122,173,24,206,66,85,15,245,211,229,10,142,86,94,205,119,250,186,244,86,249,56,157,
215,249,190,111,114,23,53,102,251,88,1,0,36,106,244,193,34,26,7,86,217,54,220,9,36,61,153,154,18,77,32,56,
107,7,130,157,98,249,42,8,249,94,97,194,246,102,77,175,54,83,19,255,167,97,131,99,242,247,109,204,62,133,228,116,
65,219,111,158,27,145,77,202,150,254,214,212,230,1,26,29,0,57,50,168,158,152,153,228,210,155,186,123,109,214,247,131,
147,91,228,219,237,43,96,98,133,130,54,25,117,242,224,196,239,44,38,153,78,218,37,254,41,130,103,241,218,209,63,32,
49,93,231,57,211,122,168,241,153,97,37,0,80,217,174,237,164,224,102,81,193,46,27,5,168,62,180,53,251,39,62,17,
89,224,235,227,117,216,14,4,114,158,96,162,166,111,100,177,186,34,185,111,209,148,214,92,210,52,127,66,103,57,30,222,
154,131,153,125,23,155,191,186,170,133,63,59,107,187,138,101,116,0,104,98,25,73,223,37,200,73,231,174,27,77,61,232,
230,206,232,89,24,21,17,188,214,174,152,72,246,91,163,93,135,55,106,214,218,121,72,96,187,137,251,115,241,25,213,207,
124,33,170,105,240,26,222,192,165,16,253,249,220,103,58,79,67,121,38,181,238,129,97,6,0,16,209,182,211,181,54,9,
15,100,71,182,229,184,253,166,243,218,132,195,116,70,1,159,221,62,82,201,168,224,130,248,150,156,206,157,100,178,186,2,
186,86,234,196,51,67,211,207,109,180,7,29,205,232,31,161,26,138,141,43,174,59,130,4,116,175,41,23,104,126,76,60,
155,173,117,153,168,54,3,0,52,65,54,219,7,157,126,111,55,67,61,132,165,139,134,110,167,194,22,94,128,113,172,18,
24,144,127,20,223,160,211,197,178,162,145,90,152,7,139,101,59,218,23,241,161,166,183,83,187,232,51,120,121,121,253,64,
37,187,239,45,72,217,132,165,60,227,120,202,93,93,213,231,52,170,46,1,96,22,0,16,217,54,106,226,0,145,93,107,
70,27,238,97,80,191,186,119,94,29,176,145,38,14,121,237,194,78,173,188,171,13,171,228,117,97,7,247,59,154,222,168,
145,150,24,59,56,121,117,33,72,252,140,116,241,51,23,137,107,56,95,197,53,150,134,4,249,238,24,50,32,58,159,146,
30,189,248,140,231,221,107,71,219,114,65,60,175,205,117,93,166,54,11,0,72,41,50,64,175,207,110,111,248,7,180,189,
40,243,24,157,103,72,61,9,120,221,251,190,42,18,205,222,71,53,125,131,210,123,220,47,104,250,94,238,191,137,121,144,
12,225,65,226,94,164,136,255,150,191,63,94,252,217,153,226,239,190,39,38,41,143,214,228,103,7,248,123,239,237,204,175,
245,193,187,18,86,236,92,157,121,28,73,102,108,231,100,180,85,159,223,160,186,38,149,153,0,80,86,29,72,245,206,5,
31,94,99,170,7,198,71,45,39,230,205,238,85,68,203,100,45,154,135,84,86,121,232,50,251,249,121,31,164,107,160,107,
121,102,206,159,139,104,201,19,73,101,30,47,255,248,90,181,230,127,113,125,18,202,108,0,136,149,27,120,248,123,183,233,
31,228,129,45,217,103,62,120,115,240,150,25,247,39,174,204,24,222,38,255,202,78,225,203,35,26,7,173,167,253,241,252,
1,83,75,236,115,117,72,240,115,244,119,249,191,81,76,255,86,215,206,77,150,211,191,61,227,129,196,85,244,179,14,109,
201,249,17,73,100,94,243,57,24,214,171,71,83,117,39,107,91,79,2,0,105,158,12,246,5,207,245,179,252,3,223,191,
105,204,105,222,226,233,224,215,159,166,239,165,9,71,50,205,53,144,229,175,233,255,209,159,33,160,32,73,172,237,151,230,
245,81,97,63,183,190,201,100,70,0,208,105,192,182,3,35,162,34,131,120,130,100,35,48,96,143,217,240,163,44,251,209,
220,78,3,79,4,0,105,156,164,96,110,86,59,4,7,236,17,206,26,213,70,253,246,207,116,68,34,153,21,0,164,255,
137,250,115,219,17,200,8,16,216,202,254,240,173,33,106,167,223,143,29,149,68,102,6,64,75,238,159,232,51,180,105,217,
128,186,252,32,80,96,203,214,251,183,188,34,84,38,63,109,87,143,6,0,116,77,150,67,162,137,215,199,33,88,96,171,
119,250,33,223,234,200,4,50,59,0,124,100,19,10,26,30,189,187,96,32,2,6,182,148,223,254,215,0,117,232,95,224,
232,198,52,102,7,0,169,149,24,22,217,102,72,141,88,38,12,195,117,113,241,186,44,181,209,7,117,249,141,113,116,242,
88,1,0,21,86,5,168,45,50,21,75,32,128,96,179,23,252,12,238,223,66,29,250,143,113,70,226,88,5,0,164,55,
141,208,55,0,134,157,176,207,127,161,179,146,198,74,0,104,164,233,167,0,51,63,95,111,182,100,81,42,2,9,54,237,
146,31,223,43,34,147,191,196,17,5,63,158,0,0,82,23,238,95,232,115,209,187,211,142,162,76,4,20,108,42,111,43,
204,80,171,253,126,229,238,230,204,132,177,26,0,42,204,7,116,239,26,193,190,43,206,69,96,193,166,48,29,236,153,148,
24,169,14,253,39,56,59,89,172,8,0,210,75,242,38,254,37,167,61,130,11,54,133,199,141,174,176,199,255,89,87,36,
138,85,1,224,167,41,135,84,204,156,210,29,1,6,27,218,211,238,73,176,239,54,237,15,0,212,79,205,184,15,200,6,
34,255,126,33,25,129,6,27,210,180,173,93,105,240,65,237,231,155,187,42,73,172,12,0,82,71,81,64,193,120,131,12,
246,217,251,105,8,56,216,88,77,101,223,77,181,197,166,82,231,223,217,149,9,98,117,0,104,162,95,218,31,178,82,144,
142,80,70,224,193,70,240,55,95,142,96,141,195,3,213,238,62,253,93,157,28,158,0,0,210,13,242,253,234,242,102,33,
108,211,138,235,16,128,176,91,189,245,235,12,22,221,252,50,245,56,239,9,238,72,12,79,1,0,105,154,132,64,107,190,
125,120,231,55,216,51,0,187,199,84,159,162,108,239,37,223,239,174,164,240,36,0,144,102,203,155,222,182,117,67,91,111,
117,4,36,236,74,151,172,207,98,177,109,27,169,201,255,15,119,38,132,167,1,192,75,172,175,218,110,126,231,142,225,108,
15,127,32,8,76,216,85,187,251,226,227,194,213,228,127,218,221,9,225,105,0,144,16,120,89,62,132,118,109,26,162,100,
24,118,186,105,155,122,92,251,48,251,13,62,222,0,128,123,68,141,68,94,83,231,4,182,172,194,196,32,236,28,211,164,
115,76,244,101,106,242,191,170,25,228,208,88,79,5,128,28,9,60,41,31,74,115,190,58,176,22,75,132,176,131,205,207,
107,176,173,60,41,201,255,188,17,190,249,1,128,114,205,144,15,39,60,44,0,219,136,97,135,249,243,197,105,182,35,237,
149,228,159,99,180,224,7,0,116,77,149,15,41,48,208,135,45,124,190,31,2,24,174,151,95,125,182,175,90,225,87,234,
206,165,62,0,160,102,186,94,86,12,82,19,198,251,38,119,65,32,195,117,50,117,164,82,106,251,233,124,199,60,163,6,
61,0,112,113,217,240,25,57,26,152,144,221,14,253,4,224,26,251,248,238,113,246,91,122,105,31,202,0,35,7,60,0,
112,177,226,53,209,90,140,220,165,83,99,172,16,192,53,170,238,163,6,52,74,242,211,174,190,43,141,30,236,0,64,229,
186,156,187,72,62,76,106,47,246,9,38,7,225,75,244,240,179,155,236,91,197,29,101,134,64,7,0,170,86,0,247,124,
249,80,169,73,227,172,169,221,209,114,28,174,208,186,155,186,247,42,13,60,101,39,31,127,179,4,57,0,80,189,198,114,
255,44,31,112,242,213,151,179,157,171,81,57,136,178,222,44,251,190,253,212,192,243,47,102,11,110,0,160,102,162,206,172,
251,212,87,130,69,175,165,32,17,60,212,111,189,60,192,126,200,79,173,187,187,152,49,176,1,128,154,171,33,247,27,242,
161,211,82,97,222,248,56,156,74,236,65,166,83,122,169,201,172,146,248,178,166,191,129,89,131,26,0,168,189,50,184,79,
202,0,160,125,221,139,95,31,132,4,177,184,63,126,103,8,251,83,171,6,106,226,159,17,175,135,166,22,0,80,55,181,
228,94,161,142,6,198,102,182,101,251,55,101,35,89,44,230,189,27,198,176,172,81,109,236,191,245,151,113,95,97,133,64,
6,0,234,46,218,208,241,87,238,159,212,185,129,87,158,233,139,196,177,200,12,255,203,79,245,81,79,233,33,255,200,125,
155,102,160,205,60,0,128,49,106,6,222,87,191,33,18,187,68,216,54,130,32,145,204,233,101,31,93,195,122,245,104,106,
255,173,255,145,85,190,245,1,0,231,40,155,251,184,12,24,170,5,31,63,166,157,109,185,8,73,101,158,166,29,244,42,
167,212,241,147,143,114,103,90,53,104,1,0,199,170,17,247,19,154,216,84,68,110,16,234,111,59,245,229,200,182,28,36,
153,65,125,152,63,155,41,119,117,101,151,133,248,169,137,255,27,247,163,102,158,225,7,0,220,167,182,220,139,212,33,36,
245,127,159,126,111,55,219,82,18,146,206,56,203,122,180,115,175,105,68,144,253,112,255,115,238,56,79,8,84,0,192,185,
26,204,189,81,13,174,168,200,32,54,119,70,79,118,108,23,234,7,220,101,170,221,168,34,241,215,115,167,120,82,128,2,
0,206,23,181,30,187,134,123,131,26,108,84,73,70,61,7,208,149,216,117,166,123,77,163,176,168,166,193,246,137,191,141,
59,215,74,179,251,0,128,49,151,13,169,136,104,151,26,124,1,254,62,44,107,100,27,219,49,81,72,82,231,120,227,242,
81,108,226,245,113,44,40,200,215,62,241,247,106,122,179,14,31,79,13,74,0,192,245,242,229,206,226,94,171,6,35,205,
60,15,236,215,156,189,62,63,153,157,40,65,19,146,250,154,238,33,157,8,157,210,183,185,253,172,62,249,27,49,179,239,
227,233,193,8,0,184,87,189,185,63,212,244,158,113,101,1,74,5,69,244,141,85,248,105,58,146,185,150,166,195,95,39,
79,234,100,187,135,118,73,95,42,38,247,174,65,216,1,0,70,83,7,77,223,71,126,74,13,90,42,49,166,46,51,179,
249,132,213,246,194,12,36,120,21,222,198,239,205,63,30,236,110,43,192,162,123,102,151,248,180,111,227,105,79,153,213,7,
0,204,173,32,49,25,181,220,46,136,109,195,216,164,238,77,109,43,8,128,129,126,186,238,156,135,122,178,164,196,200,202,
146,158,190,237,11,184,115,184,3,17,86,0,128,25,21,171,233,7,71,22,219,195,128,220,33,54,140,253,245,230,120,246,
191,55,7,123,68,227,82,106,184,249,193,27,131,216,109,55,117,180,63,92,83,53,77,176,62,162,233,117,24,16,0,96,
25,37,104,122,85,218,222,202,2,63,132,87,176,13,25,16,205,30,226,75,92,116,176,137,21,106,12,104,173,158,250,48,
78,253,123,2,27,148,220,130,5,7,251,86,149,244,116,79,232,212,231,174,8,19,0,192,19,68,221,137,166,112,175,228,
62,95,89,82,248,251,121,179,158,221,34,109,223,150,47,205,235,195,86,45,77,55,244,202,2,141,96,86,46,185,150,189,
248,228,213,236,214,27,59,218,230,61,252,42,246,217,83,125,78,124,246,41,2,140,16,0,224,177,10,211,244,229,44,58,
108,178,164,138,132,177,153,18,170,35,127,109,200,28,222,218,86,247,78,96,88,250,222,80,151,245,55,164,237,181,244,179,
232,103,82,162,211,53,100,164,183,182,189,202,92,34,217,165,233,53,232,21,77,175,163,8,195,99,7,0,160,202,69,173,
168,71,113,255,83,211,219,154,255,81,77,98,233,199,161,241,35,172,232,152,116,218,2,155,54,232,10,219,225,22,180,148,
246,200,3,137,108,222,172,171,216,252,39,174,102,11,158,235,103,51,117,63,162,119,113,50,253,183,252,125,250,51,244,103,
233,239,220,49,49,222,246,111,208,191,69,19,151,109,91,55,180,21,60,213,228,90,196,53,23,137,207,48,82,51,73,123,
109,0,0,0,48,162,252,184,59,139,217,112,154,67,88,194,125,168,134,137,232,10,31,228,254,68,211,15,205,204,17,215,
234,135,199,6,0,64,206,21,45,55,210,186,248,80,238,91,184,31,227,126,155,251,43,238,205,220,71,52,125,59,108,93,
19,251,55,241,111,108,18,255,230,91,220,115,197,207,74,21,63,27,203,115,0,0,100,112,249,136,68,37,96,4,115,135,
10,55,18,150,191,14,22,127,38,80,67,121,45,0,0,195,176,181,141,155,0,195,0,0,12,195,0,0,12,195,0,0,
12,195,0,0,12,195,0,0,12,195,0,0,12,195,0,0,12,195,0,0,12,195,0,0,12,195,0,0,12,195,0,0,
12,195,0,0,12,195,38,241,255,3,73,49,223,76,174,54,46,60,0,0,0,0,73,69,78,68,174,66,96,130,
};
const unsigned char Logo1x[11533] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,94,0,0,0,85,8,6,0,0,0,1,155,140,
109,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0,
@@ -573,6 +877,602 @@ const unsigned char Logo[11533] = {
105,102,121,0,50,48,50,48,45,48,56,45,49,48,84,48,57,58,50,49,58,49,53,43,48,57,58,48,48,32,103,176,
44,0,0,0,0,73,69,78,68,174,66,96,130,
};
const unsigned char Logo2x[18991] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,188,0,0,0,170,8,6,0,0,0,79,170,156,
236,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,6,132,105,84,88,116,88,77,
76,58,99,111,109,46,97,100,111,98,101,46,120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,
103,105,110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104,105,72,122,114,101,83,122,78,84,
99,122,107,99,57,100,34,63,62,32,60,120,58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100,
111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116,107,61,34,65,100,111,98,101,32,88,77,80,
32,67,111,114,101,32,53,46,54,45,99,49,52,53,32,55,57,46,49,54,51,52,57,57,44,32,50,48,49,56,47,48,
56,47,49,51,45,49,54,58,52,48,58,50,50,32,32,32,32,32,32,32,32,34,62,32,60,114,100,102,58,82,68,70,
32,120,109,108,110,115,58,114,100,102,61,34,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,
57,57,47,48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34,62,32,60,114,100,102,58,68,
101,115,99,114,105,112,116,105,111,110,32,114,100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109,
112,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,34,
32,120,109,108,110,115,58,100,99,61,34,104,116,116,112,58,47,47,112,117,114,108,46,111,114,103,47,100,99,47,101,108,
101,109,101,110,116,115,47,49,46,49,47,34,32,120,109,108,110,115,58,112,104,111,116,111,115,104,111,112,61,34,104,116,
116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,112,104,111,116,111,115,104,111,112,47,49,46,48,47,
34,32,120,109,108,110,115,58,120,109,112,77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,
111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120,109,108,110,115,58,115,116,69,118,116,61,34,104,116,116,
112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101,47,82,
101,115,111,117,114,99,101,69,118,101,110,116,35,34,32,120,109,112,58,67,114,101,97,116,111,114,84,111,111,108,61,34,
65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,67,32,50,48,49,57,32,40,77,97,99,105,110,116,111,
115,104,41,34,32,120,109,112,58,67,114,101,97,116,101,68,97,116,101,61,34,50,48,50,49,45,48,56,45,50,55,84,
50,48,58,49,49,58,52,52,43,48,51,58,48,48,34,32,120,109,112,58,77,111,100,105,102,121,68,97,116,101,61,34,
50,48,50,49,45,48,57,45,48,51,84,50,50,58,49,51,58,53,52,43,48,51,58,48,48,34,32,120,109,112,58,77,
101,116,97,100,97,116,97,68,97,116,101,61,34,50,48,50,49,45,48,57,45,48,51,84,50,50,58,49,51,58,53,52,
43,48,51,58,48,48,34,32,100,99,58,102,111,114,109,97,116,61,34,105,109,97,103,101,47,112,110,103,34,32,112,104,
111,116,111,115,104,111,112,58,67,111,108,111,114,77,111,100,101,61,34,51,34,32,112,104,111,116,111,115,104,111,112,58,
73,67,67,80,114,111,102,105,108,101,61,34,115,82,71,66,32,73,69,67,54,49,57,54,54,45,50,46,49,34,32,120,
109,112,77,77,58,73,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,97,98,54,101,100,57,50,
102,45,50,49,53,102,45,52,55,56,53,45,97,98,100,101,45,57,52,97,55,54,99,53,53,56,97,53,48,34,32,120,
109,112,77,77,58,68,111,99,117,109,101,110,116,73,68,61,34,97,100,111,98,101,58,100,111,99,105,100,58,112,104,111,
116,111,115,104,111,112,58,98,99,101,99,53,54,54,98,45,52,101,97,57,45,101,49,52,57,45,98,50,97,101,45,48,
100,56,52,51,101,102,48,50,55,57,56,34,32,120,109,112,77,77,58,79,114,105,103,105,110,97,108,68,111,99,117,109,
101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,102,50,99,97,50,51,102,99,45,53,49,57,99,45,52,56,55,
54,45,97,57,101,101,45,100,50,51,100,52,99,50,51,50,99,51,51,34,62,32,60,112,104,111,116,111,115,104,111,112,
58,84,101,120,116,76,97,121,101,114,115,62,32,60,114,100,102,58,66,97,103,62,32,60,114,100,102,58,108,105,32,112,
104,111,116,111,115,104,111,112,58,76,97,121,101,114,78,97,109,101,61,34,97,114,101,115,34,32,112,104,111,116,111,115,
104,111,112,58,76,97,121,101,114,84,101,120,116,61,34,97,114,101,115,34,47,62,32,60,47,114,100,102,58,66,97,103,
62,32,60,47,112,104,111,116,111,115,104,111,112,58,84,101,120,116,76,97,121,101,114,115,62,32,60,120,109,112,77,77,
58,72,105,115,116,111,114,121,62,32,60,114,100,102,58,83,101,113,62,32,60,114,100,102,58,108,105,32,115,116,69,118,
116,58,97,99,116,105,111,110,61,34,99,114,101,97,116,101,100,34,32,115,116,69,118,116,58,105,110,115,116,97,110,99,
101,73,68,61,34,120,109,112,46,105,105,100,58,102,50,99,97,50,51,102,99,45,53,49,57,99,45,52,56,55,54,45,
97,57,101,101,45,100,50,51,100,52,99,50,51,50,99,51,51,34,32,115,116,69,118,116,58,119,104,101,110,61,34,50,
48,50,49,45,48,56,45,50,55,84,50,48,58,49,49,58,52,52,43,48,51,58,48,48,34,32,115,116,69,118,116,58,
115,111,102,116,119,97,114,101,65,103,101,110,116,61,34,65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,
67,32,50,48,49,57,32,40,77,97,99,105,110,116,111,115,104,41,34,47,62,32,60,114,100,102,58,108,105,32,115,116,
69,118,116,58,97,99,116,105,111,110,61,34,115,97,118,101,100,34,32,115,116,69,118,116,58,105,110,115,116,97,110,99,
101,73,68,61,34,120,109,112,46,105,105,100,58,97,98,54,101,100,57,50,102,45,50,49,53,102,45,52,55,56,53,45,
97,98,100,101,45,57,52,97,55,54,99,53,53,56,97,53,48,34,32,115,116,69,118,116,58,119,104,101,110,61,34,50,
48,50,49,45,48,57,45,48,51,84,50,50,58,49,51,58,53,52,43,48,51,58,48,48,34,32,115,116,69,118,116,58,
115,111,102,116,119,97,114,101,65,103,101,110,116,61,34,65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,
67,32,50,48,49,57,32,40,77,97,99,105,110,116,111,115,104,41,34,32,115,116,69,118,116,58,99,104,97,110,103,101,
100,61,34,47,34,47,62,32,60,47,114,100,102,58,83,101,113,62,32,60,47,120,109,112,77,77,58,72,105,115,116,111,
114,121,62,32,60,47,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,62,32,60,47,114,100,102,58,82,68,70,
62,32,60,47,120,58,120,109,112,109,101,116,97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,
63,62,255,127,105,182,0,0,67,81,73,68,65,84,120,218,237,157,7,120,85,197,182,199,79,26,36,129,4,72,232,189,
133,222,33,244,222,123,9,45,33,141,174,128,34,2,42,130,52,169,10,34,138,229,42,118,164,40,98,3,20,203,179,87,
64,20,148,98,232,82,165,43,234,149,139,48,111,173,157,217,97,115,76,224,156,228,156,147,153,125,254,235,251,126,223,125,
79,66,216,123,102,205,204,127,207,172,89,203,33,132,112,0,0,0,0,0,0,96,87,208,8,0,0,0,0,0,0,130,
23,0,0,0,0,0,0,8,94,0,0,0,0,0,0,32,120,1,0,0,0,0,0,128,224,5,0,0,0,0,0,0,
130,23,0,0,0,0,0,0,8,94,0,0,0,0,0,0,193,139,70,0,0,0,0,0,0,126,47,120,97,55,180,64,
34,15,145,151,8,35,66,37,97,242,191,69,17,65,104,166,172,13,3,17,0,0,0,0,16,188,122,219,255,17,105,196,
65,249,191,95,19,175,18,11,137,209,68,15,34,150,40,79,228,131,224,5,0,0,0,0,128,224,213,205,158,35,174,18,
127,133,4,7,30,47,93,34,223,217,144,144,64,110,84,147,203,196,5,226,40,177,155,88,39,133,112,25,8,94,0,0,
0,0,0,8,94,93,172,29,177,145,184,24,16,16,112,113,120,82,181,3,235,87,119,253,253,173,149,157,197,67,115,155,
137,17,73,85,69,251,214,37,69,237,26,81,162,112,116,168,8,12,8,48,197,48,239,8,63,78,244,39,106,218,117,7,
24,3,17,0,0,0,0,16,188,246,48,142,233,109,78,124,31,16,224,184,82,178,120,248,95,179,167,52,76,59,119,32,
245,202,133,67,67,197,169,180,20,113,240,135,4,177,227,139,1,98,195,154,174,226,206,177,117,68,141,234,133,68,96,96,
128,185,11,124,138,255,46,49,141,40,5,193,11,0,0,0,0,0,193,171,170,241,69,182,201,196,1,218,237,189,20,31,
87,233,208,103,27,123,95,56,127,112,232,85,22,190,86,206,31,76,21,91,63,142,19,15,206,110,34,122,117,45,39,42,
87,140,20,65,65,134,0,254,75,238,24,167,16,149,228,197,57,8,94,0,0,0,0,0,8,94,165,50,59,148,36,94,
34,254,137,42,148,247,252,154,103,58,28,112,22,188,86,206,238,79,21,123,191,139,23,239,175,235,46,18,250,87,18,121,
210,227,128,121,231,247,4,177,86,134,60,64,240,2,0,0,0,0,64,240,42,183,219,123,59,177,159,197,235,232,212,106,
251,127,249,49,241,210,141,132,175,201,225,29,9,98,209,236,166,162,101,211,226,34,50,34,143,25,243,251,46,209,83,166,
66,131,224,5,0,0,0,0,128,224,85,198,98,136,173,20,175,251,15,133,45,252,146,182,117,240,57,87,68,47,115,124,
87,146,248,230,253,190,34,53,33,70,200,236,15,127,19,59,137,100,93,66,29,48,16,1,0,0,0,0,193,235,31,22,
46,51,50,252,55,166,98,129,179,27,215,116,59,225,170,232,53,217,246,73,127,49,102,120,13,81,190,108,132,185,227,203,
57,127,251,17,145,16,188,0,0,0,0,128,224,133,224,85,193,66,228,69,180,203,17,249,67,254,251,228,226,150,123,221,
21,189,116,249,77,252,188,117,176,152,125,111,35,145,47,60,152,59,239,146,20,190,53,32,120,1,0,0,0,0,193,11,
193,171,138,245,33,142,231,203,23,252,219,99,15,182,56,158,89,6,7,87,248,238,163,126,34,121,112,140,40,28,21,202,
157,248,15,177,132,168,8,193,11,0,0,0,0,8,94,8,94,21,178,56,240,142,236,9,170,206,118,105,218,164,6,7,
178,43,122,41,207,175,248,246,131,126,162,77,139,18,220,145,92,241,237,52,145,10,193,11,0,0,0,0,8,94,8,94,
21,44,150,216,155,55,111,208,197,165,243,155,31,203,142,224,181,66,187,197,130,226,131,205,116,102,171,137,218,16,188,0,
0,0,0,128,224,133,224,205,77,11,32,202,18,191,4,211,78,239,188,251,98,15,228,68,240,114,124,239,161,237,67,196,
168,148,106,230,165,182,95,137,33,16,188,0,0,0,0,128,224,133,229,182,113,73,226,99,209,81,121,47,172,95,221,245,
120,78,119,122,57,204,225,217,101,173,69,213,202,5,204,48,135,199,136,194,16,188,0,0,0,0,128,224,133,229,230,78,
111,61,226,98,190,240,144,191,190,120,183,247,209,156,138,94,102,207,230,193,162,93,171,146,220,193,87,120,23,153,168,5,
193,11,0,0,0,0,8,94,88,110,90,18,241,223,122,181,163,207,80,104,194,223,158,16,189,28,230,48,227,174,6,34,
44,204,72,97,118,136,24,32,211,163,65,240,2,0,0,0,0,130,23,230,115,11,34,102,115,24,66,253,218,209,219,60,
33,120,205,16,135,111,62,232,43,74,149,8,55,243,246,78,133,224,5,0,0,0,0,4,47,44,55,83,150,173,100,209,
123,223,228,250,135,73,172,94,245,148,240,253,252,157,222,162,73,195,162,220,225,255,35,30,242,85,92,47,6,34,0,0,
0,0,32,120,97,206,86,138,51,44,132,133,6,93,216,253,205,160,63,61,37,120,153,227,187,146,68,183,142,101,205,203,
108,235,32,120,1,0,0,0,0,193,11,203,45,107,71,92,40,91,58,226,192,190,109,241,23,61,41,122,15,239,24,34,
70,36,85,19,121,242,4,114,231,191,67,148,129,224,5,0,0,0,0,4,47,44,55,108,26,239,196,142,25,94,253,215,
236,86,98,203,138,179,251,83,197,109,163,106,154,249,122,63,149,241,195,16,188,0,0,0,0,128,224,133,249,212,74,16,
187,11,20,200,115,97,243,135,253,206,120,82,240,50,191,166,37,139,73,183,213,17,97,161,193,166,232,45,3,193,11,0,
0,0,0,8,94,152,175,141,203,3,95,46,86,56,108,151,167,119,121,141,157,94,202,224,48,113,92,29,115,167,119,19,
4,47,0,0,0,0,32,120,97,185,97,92,41,237,234,195,243,154,29,243,180,224,53,118,122,127,78,22,183,143,174,41,
242,132,24,49,189,124,145,45,26,130,23,0,0,0,0,16,188,48,95,90,13,226,98,149,74,5,142,30,223,157,116,217,
27,162,247,236,254,20,49,52,161,170,185,211,251,16,4,47,0,0,0,0,32,120,97,190,52,46,61,60,151,248,231,225,
249,205,210,188,33,120,25,170,238,70,41,203,202,176,67,92,38,166,56,60,84,145,13,3,17,0,0,0,0,16,188,48,
87,140,11,82,236,15,12,12,184,120,228,167,196,63,188,37,122,143,82,158,222,70,245,138,152,21,217,250,67,240,2,0,
0,0,0,130,23,230,75,187,139,184,114,223,164,250,199,188,37,120,205,138,108,37,138,25,101,136,15,202,112,10,8,94,
0,0,0,0,64,240,194,124,98,149,136,63,106,215,136,58,114,242,231,228,127,188,41,122,191,122,191,143,8,15,51,210,
149,29,118,228,176,4,49,6,34,0,0,0,0,32,120,97,238,216,19,1,1,142,75,111,175,234,114,196,155,130,151,11,
83,76,191,171,1,59,199,21,226,81,8,94,0,0,0,0,64,240,194,124,101,97,196,159,197,139,132,125,239,77,193,203,
80,222,95,209,182,101,73,51,115,67,31,8,94,0,0,0,0,64,240,194,124,101,171,56,47,239,7,175,119,63,238,109,
209,251,243,230,193,162,74,229,130,236,36,191,18,181,32,120,1,0,0,0,0,193,11,243,133,13,230,20,101,227,111,169,
117,193,219,130,151,121,246,209,214,230,46,239,42,8,94,0,0,0,0,64,240,194,124,97,165,136,223,27,214,43,114,252,
244,222,148,43,222,22,188,231,168,252,240,176,196,170,102,126,222,84,8,94,0,0,0,0,64,240,194,124,97,111,208,229,
181,63,143,252,152,248,63,95,236,242,114,81,138,202,21,35,217,89,78,17,21,33,120,1,0,0,0,0,193,11,243,182,
53,225,56,222,59,111,173,189,217,23,130,151,47,176,45,123,160,5,59,203,85,135,155,165,135,49,16,1,0,0,0,0,
193,11,203,174,29,10,11,11,222,235,11,193,107,210,44,182,40,59,204,63,68,21,8,94,0,0,0,0,64,240,194,188,
109,47,179,158,252,250,253,62,39,125,37,120,233,223,18,209,81,161,236,52,95,16,145,16,188,0,0,0,0,128,224,133,
121,211,110,231,16,131,249,211,27,31,242,149,224,61,75,23,216,146,6,199,176,211,92,34,250,66,240,2,0,0,0,0,
130,23,230,77,235,200,153,19,198,142,168,241,59,197,216,94,245,149,232,221,250,81,63,179,236,240,199,68,32,4,47,0,
0,0,0,32,120,97,222,178,210,196,223,109,91,150,56,78,165,128,175,248,50,150,247,158,9,245,204,220,188,253,33,120,
1,0,0,0,0,193,11,243,150,241,238,234,129,98,69,194,142,158,74,75,246,169,224,221,67,21,216,202,151,137,96,231,
249,145,136,130,224,5,0,0,0,0,4,47,204,91,246,92,96,96,192,197,147,123,124,43,120,57,77,217,232,161,213,217,
121,254,38,186,67,240,2,0,0,0,0,130,23,230,45,75,102,77,249,209,91,61,15,249,82,240,50,223,126,216,79,132,
132,4,178,3,173,131,224,5,0,0,0,0,4,47,204,91,198,249,112,197,212,73,245,191,246,181,224,101,146,6,197,152,
197,40,106,120,83,240,194,96,48,24,12,6,131,101,165,43,32,38,236,111,193,28,86,208,170,69,137,207,115,67,240,126,
245,94,31,17,25,17,194,78,180,214,145,69,198,6,8,94,24,12,6,131,193,96,16,188,176,156,218,193,232,66,161,219,
115,67,240,30,223,149,40,90,54,41,198,78,116,130,168,104,83,193,91,155,120,2,184,196,163,196,195,196,98,98,30,49,
141,184,131,72,33,122,58,210,75,98,151,32,2,48,108,125,242,49,92,146,104,70,244,34,82,137,9,178,79,230,203,62,
90,74,44,83,200,127,38,18,97,154,180,47,251,112,17,162,14,209,142,136,39,198,16,147,137,153,196,66,71,122,25,118,
213,218,56,39,227,154,223,105,186,244,163,4,249,222,149,137,32,63,30,103,236,175,49,142,244,52,161,131,137,177,196,189,
196,28,57,198,30,33,30,195,218,144,35,120,45,41,13,193,11,99,219,18,28,28,120,44,55,4,47,51,119,90,44,59,
209,101,41,106,188,46,120,71,189,247,155,207,112,164,87,147,19,192,43,252,74,124,79,108,144,11,195,16,162,130,47,251,
87,119,200,194,137,214,82,104,241,162,250,190,35,61,115,202,105,141,253,98,162,66,237,27,34,63,120,135,72,31,125,93,
250,236,113,140,223,127,241,11,241,161,20,199,131,136,80,27,141,179,0,249,97,51,212,50,206,118,17,231,209,239,62,37,
8,130,23,198,147,204,229,115,7,134,94,201,13,193,187,239,187,120,145,39,253,242,218,122,27,10,94,222,201,16,181,250,
141,21,45,110,95,2,110,66,243,177,15,138,102,183,46,16,77,70,207,21,177,67,103,136,250,9,147,169,237,198,136,152,
142,9,162,108,147,174,162,104,181,70,34,60,170,248,205,38,53,22,107,95,200,93,200,88,94,108,32,110,13,95,12,146,
139,238,120,226,77,98,239,205,22,136,240,232,18,162,88,245,198,162,108,211,110,162,74,167,33,134,31,115,159,196,14,155,
105,244,81,179,91,23,138,230,227,22,41,227,63,242,185,215,228,98,27,243,233,195,72,98,21,241,195,205,218,55,180,64,
97,17,85,161,166,40,89,183,149,168,212,182,191,168,209,115,132,168,51,96,188,104,144,52,69,52,30,49,91,52,29,61,
79,185,54,206,201,184,230,119,106,144,120,183,225,71,149,218,13,48,222,59,178,100,197,27,181,17,127,124,205,37,202,106,
54,214,248,116,164,141,220,157,255,242,102,126,80,160,84,37,81,170,126,91,81,177,77,156,168,209,107,164,168,23,63,81,
52,74,189,47,125,140,141,121,64,180,24,183,24,235,67,206,231,133,181,216,225,133,177,113,150,4,241,203,143,67,46,230,
214,46,239,224,126,149,216,145,254,146,11,134,45,4,175,220,221,49,6,91,159,165,31,10,250,111,192,67,12,223,112,74,
36,189,178,79,196,61,241,133,232,50,231,85,99,97,168,220,110,160,136,40,94,46,171,69,101,141,35,61,253,93,144,159,
137,220,0,185,187,184,54,171,197,182,68,237,22,134,208,226,69,181,251,130,55,197,128,167,190,22,201,175,30,16,35,54,
158,209,198,31,70,190,123,206,250,78,227,124,60,198,187,16,203,137,35,153,181,47,11,90,246,77,246,209,78,51,94,54,
124,54,113,245,207,98,216,91,39,48,150,205,241,188,254,87,49,228,229,93,162,251,194,183,13,113,92,177,117,191,204,124,
149,133,99,146,226,31,148,92,72,233,157,172,252,160,74,231,196,140,113,54,112,249,102,145,186,238,23,49,106,211,5,248,
128,183,160,182,181,244,65,123,8,94,24,219,74,238,255,159,55,15,62,155,91,130,247,253,215,123,136,160,160,0,33,99,
151,236,34,120,235,154,131,45,113,77,26,38,31,31,193,98,173,247,146,247,140,93,200,34,85,26,100,182,112,190,66,12,
228,227,124,155,10,220,58,114,119,123,75,102,11,111,173,190,183,138,206,179,86,137,193,207,127,47,134,189,125,210,30,125,
190,246,160,245,29,155,123,185,141,43,200,56,219,77,153,181,111,181,110,169,162,253,148,103,69,220,147,95,66,212,230,240,
163,150,63,190,26,13,157,238,220,198,219,136,91,136,188,10,140,183,104,185,163,191,225,95,31,146,117,90,26,187,243,189,
31,126,95,164,190,126,4,125,154,11,36,174,218,99,246,199,49,217,95,16,188,48,199,243,220,255,63,126,49,224,84,110,
9,222,189,91,227,69,229,10,145,66,198,183,133,219,68,240,142,49,39,191,17,27,79,99,2,202,37,120,23,165,195,212,
231,69,153,198,157,51,19,191,83,237,176,235,203,241,142,196,157,153,9,48,222,93,236,120,223,75,34,97,197,79,98,196,
59,103,109,217,199,125,31,253,200,250,206,225,94,218,189,227,75,147,27,157,219,183,116,163,14,162,213,132,71,197,144,149,
187,109,219,190,185,13,127,152,241,238,120,38,254,221,57,151,198,91,121,226,1,231,231,169,208,178,183,232,58,247,53,145,
242,218,33,244,155,2,88,124,230,117,8,94,152,105,79,115,255,111,253,184,223,137,220,18,188,103,247,167,136,158,93,140,
227,232,83,68,77,155,8,222,215,248,241,59,78,95,129,201,71,37,241,59,237,5,58,50,237,235,188,112,222,170,169,208,
229,16,160,251,157,23,94,222,221,238,187,236,19,191,217,97,172,209,123,148,215,194,25,100,72,200,117,237,203,113,182,221,
230,189,142,157,59,31,195,27,7,113,143,127,238,60,118,199,251,112,188,113,86,141,5,206,59,250,28,86,53,244,205,227,
232,35,149,124,133,62,62,157,195,156,32,120,97,108,207,112,255,127,255,89,220,201,220,18,188,204,194,153,141,205,108,13,
113,54,17,188,251,248,241,7,191,240,3,38,32,5,233,189,244,3,17,211,33,222,58,41,62,160,203,110,175,12,93,248,
215,142,238,128,167,191,241,187,93,70,22,245,150,54,136,240,96,27,255,107,71,151,63,94,237,18,6,162,51,28,179,93,
187,255,109,214,126,31,235,131,241,54,142,248,201,252,55,235,15,185,75,164,172,59,140,254,80,56,180,205,226,31,205,32,
120,97,166,189,196,253,191,235,235,129,167,115,83,240,110,249,168,159,8,8,48,226,120,151,233,46,120,201,90,92,11,103,
56,131,9,72,97,218,76,122,220,121,199,104,128,226,98,247,58,161,91,119,208,4,227,194,143,191,94,126,225,120,89,217,
22,175,122,168,125,107,202,212,81,25,109,220,250,206,101,8,87,80,16,206,252,96,233,167,78,94,26,111,29,173,190,192,
23,60,113,39,67,125,56,134,222,210,111,97,16,188,48,211,248,6,187,216,183,45,254,124,110,10,222,243,7,135,138,234,
85,10,178,67,237,177,129,224,125,153,31,157,83,203,96,242,209,96,114,164,155,243,78,162,119,178,130,66,119,172,76,211,
100,60,35,167,9,235,243,200,255,249,253,237,126,75,159,181,243,192,46,222,146,235,66,67,40,53,30,118,116,181,201,206,
193,180,244,240,152,155,229,188,195,143,118,215,3,78,125,39,251,237,78,75,127,66,240,194,140,99,187,171,191,166,37,95,
202,77,193,203,76,24,83,219,116,210,210,186,10,94,249,236,198,123,224,200,75,175,248,192,6,137,247,88,23,207,4,133,
196,238,92,235,37,180,94,15,109,66,159,17,124,17,207,210,95,101,115,184,171,155,241,187,216,15,16,159,171,143,232,173,
217,231,150,235,138,11,120,96,188,229,147,39,141,198,239,228,76,17,252,113,133,246,214,231,174,134,197,31,66,33,120,97,
86,251,146,66,9,46,228,182,216,101,54,172,233,106,134,53,140,212,88,240,14,51,7,27,118,135,180,206,219,200,116,207,
101,161,203,85,208,86,155,207,211,238,158,229,232,35,107,28,54,165,159,203,105,252,46,31,133,91,251,156,99,187,209,182,
154,9,28,250,56,177,244,97,151,28,142,185,8,98,145,249,251,122,46,218,136,54,214,55,76,237,57,167,190,133,224,133,
57,126,10,15,11,78,83,65,240,110,255,124,128,40,28,29,42,100,134,3,237,4,175,60,22,53,6,91,219,187,159,194,
228,163,169,232,173,29,55,206,186,128,6,228,146,216,77,176,10,49,44,188,255,134,211,129,201,246,89,158,211,54,230,252,
196,248,64,213,23,142,179,150,125,249,76,14,198,92,21,71,122,105,99,227,119,197,191,176,29,109,171,97,254,102,203,188,
217,6,130,23,230,108,103,171,84,46,248,141,10,130,247,192,15,9,162,86,245,40,118,170,157,14,153,143,87,51,193,155,
215,28,108,200,206,160,55,28,58,32,251,114,84,46,136,221,137,25,41,176,250,223,110,28,219,162,79,254,13,151,60,150,
237,212,43,27,109,60,195,250,65,129,138,87,122,51,240,153,45,102,95,238,206,65,138,191,12,127,136,127,233,71,180,171,
222,197,38,152,24,8,94,152,213,34,57,126,55,113,96,204,103,42,8,222,83,105,41,162,125,235,146,236,84,92,166,179,
156,134,130,183,169,57,216,32,82,244,134,227,100,45,19,103,17,31,138,221,165,25,98,119,224,29,232,139,44,251,231,93,
107,255,4,103,87,236,114,122,41,136,93,219,237,236,85,117,211,31,194,173,98,151,127,23,218,84,79,250,44,253,208,234,
7,145,16,188,48,171,181,229,190,127,102,89,155,31,84,16,188,204,176,196,42,236,84,231,137,88,13,5,239,115,252,200,
28,67,132,201,199,86,241,188,115,125,36,118,231,155,255,102,167,153,43,209,7,55,160,82,187,1,102,223,220,237,102,27,
47,206,136,137,190,251,105,180,165,141,136,29,62,203,244,137,165,110,248,67,32,241,184,233,19,156,191,21,109,169,47,205,
199,62,104,250,192,163,153,244,53,4,175,159,27,167,93,185,114,96,91,194,31,170,8,222,197,247,55,53,11,80,116,215,
80,240,242,206,180,81,102,20,147,143,254,112,126,91,95,237,242,90,51,49,224,226,212,205,146,202,239,207,214,173,124,107,
14,99,142,255,69,91,218,139,1,79,125,109,250,196,143,110,248,196,36,132,161,217,135,18,181,91,152,62,208,26,130,23,
230,108,159,210,133,181,83,148,146,236,138,42,130,247,141,151,187,152,14,59,82,39,193,75,86,151,31,55,186,98,45,76,
60,54,130,11,59,72,127,156,225,69,223,153,105,46,186,92,166,20,237,126,99,58,207,90,237,246,165,66,178,17,230,223,
233,58,103,45,218,209,134,112,121,95,139,95,132,184,224,19,29,28,150,42,133,104,67,91,133,161,5,64,240,194,172,198,
113,75,127,84,175,90,232,200,233,189,41,202,8,222,109,159,246,55,29,118,190,46,130,215,154,157,161,217,152,7,48,249,
216,243,50,140,71,75,215,90,124,231,30,248,78,182,99,53,39,184,216,198,183,155,127,167,97,202,52,180,163,77,225,44,
27,22,223,40,119,19,159,104,136,75,139,182,13,65,187,39,139,62,135,224,245,99,171,79,92,162,11,107,191,157,59,48,
244,170,42,130,151,196,183,8,9,54,114,241,174,209,72,240,22,49,7,91,255,255,124,133,201,199,70,36,189,178,207,58,
145,54,240,176,223,220,237,176,148,175,69,123,187,144,115,245,141,163,89,166,29,202,162,141,107,155,63,223,120,196,108,180,
161,255,8,222,218,174,108,80,112,209,10,136,93,59,20,161,217,105,237,251,188,16,188,48,103,139,39,254,185,123,124,221,
83,170,136,93,147,10,229,34,216,177,190,214,72,240,54,48,7,27,31,171,97,2,178,211,49,233,49,235,68,218,211,131,
62,83,197,252,189,124,217,6,109,157,173,248,221,40,23,218,249,9,236,226,65,240,58,249,68,23,243,231,80,81,207,30,
116,152,250,252,77,227,250,33,120,253,219,22,114,191,175,124,186,253,65,213,4,111,243,216,98,236,88,123,53,18,188,19,
248,81,185,126,55,38,31,91,31,161,15,243,116,8,12,199,8,163,157,93,167,253,148,103,205,190,120,203,157,112,17,20,
149,240,59,193,91,249,6,126,193,133,141,68,199,233,43,208,110,54,128,203,194,91,250,125,210,13,250,29,130,215,143,237,
139,192,192,128,191,142,238,74,252,75,53,193,219,183,71,121,118,172,11,26,9,222,119,141,203,48,243,214,97,2,178,33,
13,18,239,241,232,197,53,178,169,72,131,148,61,138,215,106,110,246,69,215,155,180,113,95,132,139,248,181,224,141,202,194,
47,110,193,105,156,205,250,253,173,19,46,149,150,246,148,224,13,132,118,212,206,10,16,127,197,214,47,242,141,106,98,151,
185,37,181,58,59,214,85,246,45,213,5,47,89,24,142,199,252,102,87,113,149,7,252,101,188,3,229,167,179,5,199,199,
203,182,219,225,66,59,191,135,80,6,191,142,183,207,236,150,126,65,243,207,249,35,22,109,230,95,97,78,158,18,188,121,
160,31,181,51,46,93,122,101,195,234,46,251,84,20,188,83,38,212,203,8,62,215,64,240,142,229,103,173,209,107,36,38,
31,155,210,115,241,59,166,63,126,154,67,95,41,136,140,12,217,131,43,23,90,22,181,59,93,201,105,92,189,199,112,136,
93,127,26,167,139,54,154,254,241,113,22,126,113,175,233,67,124,12,142,54,179,7,77,70,222,111,246,251,242,155,204,11,
30,17,188,161,208,143,90,89,94,226,64,225,232,208,19,39,247,36,93,81,81,240,206,158,210,208,116,224,112,149,5,47,
89,176,57,129,114,169,83,76,62,246,36,238,241,207,77,127,220,150,67,127,25,154,17,83,74,199,112,104,91,119,118,113,
14,88,5,111,51,87,46,3,218,34,99,10,9,118,62,57,26,184,124,179,241,225,213,121,214,42,163,66,92,235,137,143,
137,86,119,60,34,90,142,95,234,21,248,119,183,189,235,63,162,239,163,31,105,19,255,28,59,108,102,70,74,203,81,55,
40,31,60,96,249,183,24,83,182,137,223,61,227,114,22,29,79,9,222,48,104,72,173,172,41,241,247,224,126,21,207,156,
59,144,170,164,224,93,56,179,177,233,192,249,21,23,188,53,205,193,150,184,106,143,72,93,247,11,176,66,11,53,103,57,
208,125,55,133,23,72,217,207,59,115,224,43,92,42,251,91,254,61,44,92,176,88,101,59,156,33,203,124,200,124,59,219,
252,153,250,9,147,245,91,188,223,57,43,226,95,250,81,180,191,247,57,81,103,192,120,81,162,78,75,235,59,231,42,92,
178,85,245,246,43,90,61,214,124,222,166,55,250,216,196,174,191,125,232,247,248,103,102,159,127,231,194,28,12,193,235,135,
54,157,227,99,151,204,107,118,88,69,177,203,44,157,159,113,49,165,128,226,130,55,89,149,5,73,117,194,10,22,17,165,
27,182,23,77,70,207,53,118,171,120,113,215,101,82,181,20,159,216,157,211,172,12,53,122,142,192,66,149,13,120,215,81,
182,225,127,110,208,206,83,204,118,78,121,237,144,86,185,133,121,71,245,6,227,135,47,240,238,226,144,26,226,77,98,5,
241,44,241,20,183,135,151,224,223,253,162,249,145,198,12,122,110,155,14,249,153,127,203,194,55,140,247,232,52,115,165,222,
59,154,52,111,242,142,59,159,16,129,19,46,101,103,128,224,245,95,227,11,134,223,231,9,9,252,253,200,143,137,127,64,
240,122,68,244,222,79,156,38,206,131,127,193,11,245,239,89,45,228,9,43,126,210,109,119,113,123,54,125,36,197,46,177,
131,156,166,141,203,176,242,69,190,134,201,247,138,106,221,82,69,153,216,78,198,110,100,145,42,13,188,138,108,195,238,89,
180,113,136,217,198,124,228,175,75,86,1,222,57,205,100,108,172,38,38,19,109,57,238,123,148,151,74,90,143,114,179,26,
96,237,184,113,234,158,194,144,79,202,182,251,41,147,231,111,198,127,86,172,122,99,173,82,109,241,59,181,24,183,88,84,
233,52,196,40,89,159,55,127,65,108,158,100,77,27,8,94,152,179,245,224,203,106,99,71,212,216,162,170,216,213,41,164,
1,184,181,195,89,148,232,76,44,182,78,84,221,23,190,165,252,226,211,119,217,199,230,243,110,206,198,187,135,154,239,218,
109,254,27,218,22,223,232,114,255,43,162,124,243,158,42,44,108,33,89,180,115,42,255,57,139,3,29,218,148,219,211,233,
189,120,71,181,94,102,217,5,20,24,191,202,183,109,151,217,107,204,118,124,59,171,211,21,29,178,162,112,40,24,87,4,
188,129,255,95,38,254,36,254,0,6,39,92,77,23,137,75,107,254,101,252,97,178,51,34,34,207,249,195,59,134,92,86,
89,240,206,210,228,210,26,200,246,2,26,73,44,114,104,146,15,147,69,185,124,214,15,178,241,174,213,117,60,102,55,143,
137,235,37,76,202,108,209,253,137,83,180,17,179,120,72,17,221,120,135,69,198,41,123,147,172,196,110,94,243,217,122,60,
184,65,249,75,104,78,130,102,45,209,94,241,241,122,159,17,23,61,228,46,101,219,213,210,166,11,157,158,189,172,14,33,
25,12,159,76,100,50,206,30,147,31,28,117,137,66,88,63,114,228,199,30,17,188,81,196,255,201,152,34,152,186,198,139,
210,165,248,126,149,206,157,61,144,122,85,101,193,171,83,90,50,144,237,201,39,84,23,145,210,97,218,11,166,63,190,146,
141,247,124,148,255,110,163,212,251,52,218,209,61,110,45,182,97,178,222,145,94,204,33,88,65,95,138,207,248,168,88,119,
88,105,177,235,212,166,115,53,25,171,111,168,28,255,234,20,203,25,239,244,236,29,205,63,227,112,28,85,253,162,94,252,
68,235,59,112,21,212,10,88,39,212,20,188,124,51,54,205,145,94,40,160,35,116,165,178,246,10,241,207,154,103,59,252,
162,178,216,101,70,167,232,83,120,2,228,104,2,154,199,115,79,236,208,25,106,231,121,28,53,199,92,136,22,185,249,126,
67,116,139,221,109,57,254,97,103,81,198,33,40,229,20,247,35,190,204,101,196,21,171,220,182,53,123,143,182,182,235,8,
77,198,104,94,213,63,38,134,188,188,203,218,174,165,156,158,255,9,254,239,45,110,95,162,203,71,208,61,88,27,212,22,
188,108,7,137,191,136,119,16,211,171,164,53,230,84,100,77,99,139,109,59,187,95,205,84,100,86,250,116,47,39,228,165,
39,7,4,175,173,39,160,145,220,197,124,241,73,147,130,7,99,220,120,183,252,230,223,235,56,125,133,22,98,215,41,83,
0,135,156,84,212,192,135,238,118,152,69,38,20,110,91,167,29,188,86,26,141,209,97,70,252,110,231,36,117,243,239,210,
7,179,108,215,71,50,121,254,221,252,103,156,105,69,197,103,79,88,177,211,234,23,189,176,46,232,33,120,127,14,9,9,
60,78,255,123,145,104,13,125,169,148,69,16,223,133,135,7,95,220,253,237,160,223,85,23,187,76,179,216,98,236,88,123,
33,120,109,63,1,25,59,160,149,219,13,84,250,38,189,101,65,74,114,227,221,90,153,127,143,99,97,85,23,187,13,146,
166,88,223,115,170,38,254,19,225,208,160,200,4,135,236,88,218,182,171,70,227,51,92,245,176,163,225,235,127,181,182,109,
181,172,158,95,213,112,134,54,147,30,183,62,127,16,214,5,61,4,239,55,165,74,230,59,31,24,24,192,191,117,167,60,
6,129,169,97,44,42,46,199,199,85,58,165,195,238,46,83,161,108,4,59,214,215,16,188,182,159,128,140,116,93,49,29,
19,116,200,239,153,101,74,172,44,222,237,33,254,59,77,71,207,83,94,236,246,122,104,147,245,29,167,104,228,63,157,148,
255,168,184,254,200,58,69,179,241,57,214,161,120,101,64,75,118,134,141,153,60,255,32,254,179,138,173,251,41,59,246,44,
233,246,90,97,77,208,71,240,190,26,18,18,32,198,141,172,121,32,32,192,113,69,230,16,12,132,214,204,117,227,99,213,
239,131,131,3,47,126,181,169,207,73,29,196,238,233,189,41,34,36,56,192,204,69,9,193,107,239,9,232,118,238,226,154,
125,110,81,184,164,237,126,171,96,137,117,183,208,4,199,23,170,44,118,57,115,132,229,253,102,104,230,63,75,204,103,231,
208,19,13,226,51,3,52,106,219,140,139,128,29,166,62,175,195,233,75,207,76,222,225,101,35,47,243,61,203,85,207,239,
189,3,235,129,94,130,151,111,21,138,13,171,187,254,94,178,120,62,206,17,119,136,131,199,161,55,115,213,120,209,93,206,
121,119,31,154,219,52,77,7,177,203,108,251,180,127,70,61,116,8,94,219,79,64,115,141,12,6,67,167,43,43,8,157,
98,236,74,187,179,51,86,173,251,80,229,119,119,107,244,26,105,190,219,3,154,249,78,25,179,95,146,94,217,167,124,254,
102,87,63,150,20,105,219,140,10,146,181,251,223,166,172,239,14,126,225,7,235,216,44,63,42,139,66,36,92,192,65,197,
231,111,122,203,124,243,217,151,96,61,208,75,240,222,194,191,227,173,85,93,196,131,179,155,252,76,187,188,151,100,158,198,
60,208,157,185,102,124,220,247,87,195,122,69,142,159,216,157,124,89,23,193,251,250,138,206,230,36,48,18,130,215,246,19,
208,51,220,197,173,239,92,166,67,89,97,35,77,158,59,233,214,226,158,248,66,105,177,219,102,242,147,89,222,110,215,192,
119,30,84,249,116,192,105,247,113,152,70,237,58,217,186,43,205,187,212,170,250,111,167,25,47,91,219,56,56,171,252,187,
170,86,116,172,59,104,2,50,51,104,42,120,185,130,215,63,75,230,52,19,231,15,166,94,29,28,87,137,119,120,175,200,
35,75,152,239,45,72,238,42,92,125,123,85,151,35,186,136,93,102,209,236,166,102,53,153,238,118,20,188,100,209,68,23,
57,54,248,72,246,53,226,19,226,71,121,50,114,210,145,94,146,151,171,200,252,151,115,39,203,246,176,35,198,132,223,117,
222,58,133,115,240,190,104,46,74,175,186,216,191,29,50,226,74,169,106,146,202,185,118,45,98,97,136,102,11,87,9,213,
219,56,254,197,29,214,246,205,175,248,197,191,214,50,69,224,110,243,153,57,171,132,202,98,151,41,85,191,173,217,190,61,
50,121,175,122,25,39,0,107,246,42,249,252,252,161,47,159,145,63,252,139,66,148,234,35,120,185,10,206,249,225,73,85,
13,209,242,229,166,62,23,10,71,229,61,39,23,240,170,208,159,62,53,190,48,248,31,218,101,255,223,216,225,53,126,210,
73,236,50,195,134,84,49,83,146,53,178,131,224,37,43,196,183,251,137,55,137,99,14,212,60,255,23,42,47,172,229,154,
245,48,159,179,143,139,253,253,31,29,222,171,207,210,15,173,125,80,80,179,133,235,126,213,219,152,11,141,56,174,21,236,
80,141,15,136,111,137,95,50,27,143,92,104,69,249,172,34,215,10,163,188,156,133,143,180,83,253,163,200,233,20,64,200,
44,87,92,42,247,176,38,176,190,219,207,89,186,56,14,153,248,138,120,143,88,41,195,92,199,201,13,128,130,118,19,188,
229,136,35,29,90,151,20,167,210,82,104,151,119,232,213,117,47,116,60,44,119,113,182,18,249,160,67,125,102,124,51,245,
239,54,45,74,156,57,185,39,233,178,78,98,247,87,242,157,246,228,67,114,34,46,171,171,224,149,199,218,3,137,143,50,
91,80,74,55,234,96,28,197,114,12,23,231,104,237,185,104,163,24,240,212,215,198,209,27,239,70,164,190,126,196,184,21,
205,41,119,184,96,193,136,119,206,218,22,149,69,33,47,148,238,164,12,178,94,86,75,126,245,128,210,130,161,86,223,91,
205,247,26,175,153,216,205,72,69,214,123,233,7,186,164,34,83,154,18,181,91,24,185,108,57,124,103,196,198,51,202,139,
93,167,66,19,45,178,240,147,94,142,140,210,229,199,212,125,151,149,187,141,242,221,97,5,139,216,125,99,227,8,177,129,
83,30,18,49,186,11,94,22,180,187,106,215,136,18,7,127,72,184,86,49,43,181,218,126,74,85,246,15,253,217,147,136,
231,245,137,213,34,142,230,207,23,114,238,195,55,122,28,215,109,119,247,0,249,78,173,234,81,66,166,182,11,215,77,240,
146,21,225,155,238,206,131,189,114,135,193,162,243,172,85,34,113,213,158,116,145,167,73,137,89,127,199,18,35,184,206,197,
254,55,202,152,242,81,171,202,239,149,188,246,160,213,63,195,53,19,188,25,177,153,137,107,210,148,110,103,22,189,93,238,
127,69,57,186,47,124,75,244,125,244,35,67,56,234,82,1,208,221,204,23,100,253,84,79,169,150,89,152,17,251,52,95,
148,213,131,159,68,252,11,219,197,160,103,191,51,50,78,240,7,104,183,249,111,136,118,83,158,17,141,71,204,22,53,122,
143,162,185,176,77,86,2,120,167,220,5,46,167,163,224,101,123,173,72,225,80,177,227,243,1,25,2,230,200,79,137,151,
42,87,140,100,101,255,55,49,20,122,212,171,198,183,150,211,130,130,2,127,223,248,74,215,51,186,137,93,102,59,249,78,
225,168,80,35,94,242,70,142,169,162,224,37,155,238,60,168,187,47,120,211,56,182,130,120,212,15,167,10,107,131,93,244,
129,231,249,231,219,76,122,66,233,119,179,92,150,89,160,107,238,102,101,83,145,1,239,22,154,160,2,18,150,113,217,246,
6,126,18,167,155,224,181,43,188,201,195,59,217,93,230,188,106,236,102,103,34,126,57,12,172,174,110,130,119,84,64,64,
128,88,191,166,235,117,34,38,109,203,224,179,49,149,34,207,210,159,255,79,126,117,33,63,175,231,45,159,20,137,87,238,
25,95,247,132,46,5,38,156,161,11,118,130,125,136,222,99,184,46,130,87,166,160,250,209,28,188,117,250,223,46,18,87,
255,172,252,133,15,112,99,56,180,196,50,33,215,112,43,247,46,77,238,234,238,34,29,179,190,87,73,13,5,47,23,164,
49,22,79,248,169,255,81,103,224,29,46,133,25,113,94,94,29,66,26,252,85,0,15,88,254,173,53,206,221,100,161,55,
179,197,120,90,240,150,230,223,51,105,108,157,127,9,153,77,175,117,63,17,25,17,194,55,206,185,252,112,13,232,83,143,
90,152,188,233,127,101,104,66,149,237,191,254,156,124,89,71,177,203,220,113,75,173,140,20,73,170,11,94,25,43,253,177,
57,88,171,247,24,38,226,158,252,18,19,154,77,224,184,106,203,68,28,230,78,118,6,142,189,86,245,189,186,205,123,61,
203,84,78,26,136,221,94,58,92,8,4,94,10,49,154,185,210,229,204,34,50,243,132,241,179,92,92,5,237,167,104,225,
155,117,135,141,60,236,78,194,247,238,156,204,19,195,222,253,205,49,232,237,11,142,30,235,206,59,218,172,57,231,104,180,
226,172,163,218,179,103,60,46,120,217,210,106,84,43,196,151,214,254,37,102,158,88,220,114,111,254,252,33,191,201,91,136,
77,229,142,8,44,103,22,34,243,81,254,211,190,85,201,95,142,237,74,210,86,236,158,59,152,42,170,85,41,200,14,181,
231,102,142,153,219,130,151,108,162,57,56,171,116,78,52,226,225,48,121,217,139,216,225,179,92,62,246,183,238,238,170,44,
198,248,66,146,67,195,18,194,178,141,131,204,103,231,139,158,240,81,255,130,47,242,90,124,247,14,23,252,165,138,14,39,
46,224,90,197,71,203,69,90,102,236,205,250,56,121,227,5,71,220,155,231,29,157,215,158,115,180,88,117,214,81,239,197,
179,142,152,229,103,28,101,254,115,58,83,188,33,120,31,227,35,233,109,159,196,101,42,106,30,91,212,226,56,149,185,229,
188,162,251,100,102,7,88,206,196,238,83,156,9,163,66,185,136,29,135,182,39,92,210,85,236,50,91,254,175,159,25,206,
240,168,202,130,87,62,159,49,40,27,38,223,139,201,202,166,148,109,218,205,156,120,123,185,147,57,32,238,241,207,149,125,
39,142,101,180,44,40,61,52,19,188,25,2,134,47,204,192,71,253,11,203,241,247,90,23,253,37,204,244,151,129,203,55,
163,13,53,161,245,196,199,172,115,84,223,17,155,126,115,196,175,191,224,232,245,250,121,71,251,87,206,57,26,191,124,214,
81,243,185,51,142,242,79,157,206,82,216,250,82,240,114,160,248,229,69,179,155,100,42,106,56,93,217,244,187,26,28,200,
155,55,232,119,153,166,162,57,118,122,179,101,156,246,234,1,110,235,58,181,162,143,238,223,22,255,183,206,98,151,89,48,
179,177,89,112,34,206,155,130,151,191,6,251,190,113,222,49,100,195,5,7,15,38,55,22,220,162,142,244,114,199,198,96,
228,129,137,9,202,47,46,198,20,114,193,55,90,100,92,144,81,248,146,162,83,154,181,178,154,9,222,65,25,33,35,212,
63,240,83,255,129,243,2,91,252,182,189,27,62,243,18,255,157,86,119,60,130,118,84,57,166,119,19,165,103,219,112,65,
208,186,44,104,125,22,37,187,141,177,246,119,35,119,133,173,47,5,111,77,226,116,239,174,229,196,217,253,41,153,139,222,
67,67,175,46,93,208,156,119,122,249,18,219,81,162,62,244,171,219,23,212,214,113,24,67,249,242,17,59,14,124,175,247,
206,46,195,190,210,179,75,57,118,166,83,206,49,222,158,22,188,214,1,80,150,168,242,204,25,227,40,164,249,202,179,142,
142,175,158,115,244,38,49,156,64,95,148,195,55,93,55,113,118,177,30,89,115,124,39,38,42,251,194,41,117,100,95,175,
116,113,97,125,153,127,190,233,232,121,74,191,87,203,241,75,205,247,122,79,195,203,106,90,100,192,0,94,45,31,60,215,
77,159,105,102,254,93,164,131,204,229,77,4,18,181,180,174,10,90,95,5,173,179,130,214,91,65,235,174,160,245,87,208,
58,44,202,56,17,209,126,212,117,37,221,85,21,188,156,59,245,251,152,138,5,196,222,239,226,111,40,114,30,154,211,108,
95,116,84,232,5,250,249,63,137,100,25,163,5,187,121,234,177,87,248,130,90,59,138,217,61,184,93,127,177,203,236,221,
26,47,42,85,136,100,103,218,102,230,223,245,133,224,189,25,28,15,36,159,199,24,120,229,187,142,16,125,86,164,9,10,
138,199,36,102,83,156,170,31,181,116,97,81,45,168,197,206,227,245,249,75,251,106,40,120,185,162,147,145,247,19,126,234,
31,196,191,244,163,213,103,103,102,211,111,182,169,30,106,100,155,185,147,214,197,193,36,106,41,252,64,116,120,229,156,104,
70,162,182,238,11,103,4,173,163,255,18,180,55,163,244,35,135,173,125,223,70,85,193,203,54,53,40,40,64,188,247,90,
247,155,10,157,245,171,187,30,207,159,47,152,5,239,127,229,229,43,164,44,203,218,170,57,210,75,248,93,73,165,108,12,
58,95,80,115,230,221,181,221,4,21,40,97,103,186,199,249,165,115,83,240,202,65,178,40,163,66,218,178,35,25,3,178,
210,242,211,162,214,243,103,68,227,21,103,69,155,213,231,68,215,215,206,139,126,111,158,55,142,102,248,136,6,19,160,158,
240,194,232,78,81,6,178,62,252,179,92,130,88,229,247,226,42,90,242,157,118,107,40,118,235,32,247,174,95,231,193,94,
146,3,223,25,143,204,30,158,13,61,224,117,142,215,59,94,247,120,253,227,117,144,215,67,119,69,237,205,136,74,93,102,
246,255,243,42,11,222,146,196,95,241,113,149,92,18,59,95,109,234,123,180,126,157,104,206,211,123,149,88,37,211,155,193,
174,89,94,78,124,207,225,31,244,33,113,113,202,29,245,78,80,9,94,219,136,93,102,64,159,138,66,238,244,23,87,73,
240,202,56,105,99,208,21,159,241,185,203,3,149,143,104,98,232,168,166,14,125,221,54,125,249,172,104,187,230,156,232,70,
19,68,28,4,177,45,170,56,57,45,168,198,7,81,147,81,115,116,9,211,88,168,161,224,125,210,104,227,209,115,225,163,
254,32,172,174,207,38,194,68,140,242,64,101,190,62,75,63,68,251,186,32,104,121,157,226,245,138,215,173,38,180,126,241,
58,22,147,69,232,129,55,41,185,112,135,217,255,71,85,22,188,108,27,243,132,4,138,125,219,226,93,18,60,135,119,12,
185,212,184,97,209,173,82,244,158,36,186,66,231,26,198,59,222,203,136,191,105,39,252,28,87,80,59,119,64,207,162,18,
89,145,182,117,176,8,33,95,161,119,92,159,89,3,228,150,224,37,27,109,78,148,69,110,91,237,241,193,92,153,142,121,
106,211,151,113,44,125,33,183,166,47,101,14,214,239,67,241,77,131,223,190,32,82,222,193,78,132,2,225,12,125,93,88,
76,243,234,16,215,237,148,157,33,78,51,177,91,16,233,165,252,7,46,218,227,36,118,155,120,192,135,238,228,223,21,211,
49,193,184,184,233,183,169,191,104,93,225,245,165,143,188,28,198,235,14,175,63,188,14,85,206,70,216,129,47,8,41,93,
211,244,131,186,42,11,94,142,201,189,60,119,90,172,91,226,135,50,56,28,14,11,11,62,79,127,247,130,44,213,234,175,
187,189,156,185,162,29,177,37,32,192,113,185,109,139,146,103,62,124,179,199,9,59,9,93,147,57,83,27,153,217,25,146,
85,17,188,178,237,141,129,86,248,150,231,115,101,160,151,123,234,180,17,208,207,95,215,148,138,37,67,20,115,208,255,32,
41,138,71,98,129,244,236,98,187,106,143,187,197,38,50,142,218,19,215,164,233,242,94,181,53,19,188,253,29,40,17,235,
23,88,46,85,154,233,41,171,121,208,143,158,176,171,31,141,148,98,150,215,133,222,22,49,219,88,238,206,242,58,194,235,
137,138,130,246,102,20,140,155,97,250,195,3,42,11,222,74,92,96,162,101,211,226,226,248,238,36,215,139,15,28,72,189,
186,251,219,65,127,86,174,88,96,191,220,237,229,34,4,117,253,76,236,230,39,150,115,88,8,183,193,136,164,170,59,79,
236,78,250,159,29,197,238,177,93,137,162,69,147,98,66,86,224,171,168,130,224,181,22,17,200,223,110,164,210,147,65,217,
167,174,133,78,112,44,85,43,154,228,58,209,100,199,151,6,6,190,117,65,36,179,40,70,248,132,203,180,189,235,63,230,
228,250,162,139,139,232,36,135,44,39,173,116,92,242,19,95,92,119,227,89,51,193,107,228,189,110,62,246,65,248,168,141,
105,144,52,197,234,163,124,159,167,176,135,253,168,140,117,231,88,151,75,108,60,127,243,60,206,243,57,207,235,60,191,183,
146,177,179,25,161,6,154,138,89,87,40,58,121,189,217,103,159,169,44,120,249,40,126,109,100,68,30,241,245,251,125,221,
22,66,20,10,113,113,236,240,26,167,162,11,229,61,47,119,255,30,151,233,203,2,108,46,116,147,228,173,210,43,245,106,
71,31,127,123,85,215,163,118,20,186,25,241,219,239,245,17,84,114,154,157,232,213,172,46,44,230,130,224,53,68,76,254,
54,195,108,49,97,148,149,225,19,148,172,91,52,120,233,172,113,115,182,29,197,102,117,89,123,222,56,218,26,248,54,132,
177,9,95,60,147,147,107,31,23,23,209,239,141,197,147,4,165,202,239,21,59,108,166,249,94,243,53,140,223,253,136,159,
189,199,131,27,32,12,109,72,223,101,31,83,181,202,36,183,42,108,229,192,151,120,83,101,169,249,111,117,95,248,86,238,
11,89,25,98,192,243,49,207,203,60,63,243,60,205,243,181,170,97,6,190,164,248,204,235,62,214,195,84,21,188,102,78,
222,171,201,131,99,178,37,134,184,72,5,85,223,58,83,172,104,216,46,185,219,251,7,231,225,179,105,38,135,88,226,59,
22,247,20,207,250,251,146,121,77,211,104,103,252,178,157,197,46,147,56,48,70,200,190,173,158,85,195,248,82,240,202,76,
24,233,151,212,166,127,230,119,147,75,37,154,96,171,211,68,203,249,17,249,178,130,177,99,76,57,19,169,38,185,113,145,
129,42,222,136,84,155,198,23,15,125,243,152,91,187,160,156,42,71,135,204,1,78,23,128,202,106,40,120,143,32,126,215,
102,151,163,40,39,46,103,13,105,144,120,143,213,55,63,240,85,124,185,220,65,54,254,221,90,253,198,138,65,207,126,231,
185,226,46,52,63,242,60,201,243,37,207,155,60,127,242,60,202,243,41,207,171,60,191,86,130,144,117,153,18,247,127,107,
245,145,104,149,5,47,219,27,124,33,233,219,15,251,229,72,24,61,254,96,203,99,49,149,10,112,145,138,127,136,67,92,
7,62,171,35,112,141,140,75,31,118,147,73,235,255,155,47,60,248,34,101,182,56,243,217,198,222,39,236,46,116,153,111,
62,232,107,94,86,91,123,163,70,242,177,224,125,132,255,201,2,125,166,97,178,185,201,174,177,41,142,235,190,112,214,184,
248,208,98,213,57,209,238,21,222,57,78,15,169,232,79,71,112,9,82,32,235,16,107,108,169,230,244,138,139,139,230,26,
29,142,218,59,76,123,209,124,175,13,26,138,221,140,143,10,22,238,16,139,154,95,10,165,216,89,222,85,117,186,148,198,
204,206,5,223,154,97,125,134,210,13,219,139,78,51,87,94,231,103,35,165,128,229,121,172,191,12,41,224,249,141,231,57,
158,239,120,222,227,249,207,20,177,101,177,54,120,94,240,206,217,108,245,147,162,170,11,222,238,156,97,96,84,74,117,222,
177,205,145,64,226,29,207,165,243,155,165,113,106,46,62,242,151,59,190,79,74,225,168,91,230,133,30,4,239,92,115,181,
185,127,154,198,22,251,110,247,183,131,47,114,12,179,63,136,93,246,133,81,169,213,217,121,254,150,62,146,235,130,87,102,
6,73,159,252,30,253,69,253,201,224,201,83,162,228,162,221,162,200,248,87,69,161,33,139,68,100,215,9,34,127,235,161,
34,95,203,100,229,136,236,49,89,148,95,188,83,84,127,54,61,222,184,145,33,144,211,211,181,241,5,139,158,150,29,228,
228,141,23,140,170,60,185,152,157,97,144,11,139,101,49,29,50,7,56,149,72,238,161,161,224,53,62,42,154,141,121,0,
130,81,227,50,221,28,182,16,59,116,70,102,66,151,69,103,105,95,249,19,87,207,164,249,197,65,243,140,131,230,27,179,
168,208,100,231,231,138,238,50,78,148,186,103,131,30,235,128,127,237,240,70,169,46,120,163,136,159,42,148,141,16,63,111,
25,236,17,177,116,116,103,210,159,247,77,170,127,172,118,141,168,163,148,193,224,146,204,223,186,82,230,170,45,165,112,46,
221,166,114,128,115,220,223,149,136,252,33,231,105,71,247,220,43,207,118,248,229,172,205,82,141,221,140,61,223,14,18,229,
202,228,103,231,217,65,20,202,109,193,43,171,252,25,131,170,64,223,251,148,158,0,74,47,61,104,77,200,173,13,44,122,
221,205,82,193,49,108,166,72,110,72,113,109,156,211,184,149,101,39,153,133,114,223,55,211,227,144,57,127,100,234,59,191,
101,107,55,153,69,171,229,89,43,185,32,196,90,155,63,159,178,238,176,178,98,99,240,243,223,91,223,171,180,102,98,55,
212,124,246,212,55,142,66,60,106,146,214,47,97,197,78,35,69,95,179,91,23,136,138,109,226,50,155,11,56,116,97,16,
17,146,29,191,160,241,237,160,113,238,160,241,238,160,113,239,160,241,239,160,121,192,65,243,129,131,230,5,7,205,15,14,
154,39,28,52,95,56,104,222,112,208,252,225,160,121,196,65,243,201,205,46,42,115,1,153,77,206,207,155,183,74,115,81,
160,215,20,81,120,220,42,35,158,180,212,210,3,198,102,3,196,168,143,98,120,103,125,101,237,143,252,170,11,94,135,116,
110,49,237,206,250,30,21,77,191,254,156,252,207,250,85,93,142,20,47,18,246,189,140,3,229,112,7,222,253,125,131,115,
247,41,34,116,35,101,14,192,131,114,55,243,106,158,60,65,191,143,29,81,115,203,47,59,134,252,207,95,118,116,157,185,
123,124,93,211,129,251,221,172,1,125,36,120,155,152,131,170,212,162,61,106,14,254,39,78,24,59,185,153,44,32,239,201,
147,142,123,137,91,137,81,138,49,213,16,188,221,38,248,172,173,42,60,157,158,210,173,166,140,71,230,163,71,174,221,206,
169,122,58,72,177,204,241,117,124,89,132,143,42,91,207,122,205,108,203,119,93,20,99,195,51,202,9,175,255,85,89,1,
210,121,214,106,171,159,4,107,38,120,59,168,30,35,109,94,184,42,219,180,155,255,209,164,171,40,19,219,73,148,168,211,
82,68,87,172,37,194,10,21,189,209,7,239,102,98,30,81,142,251,118,232,187,191,57,146,104,167,149,202,208,58,104,252,
57,104,28,58,122,72,209,74,227,211,65,227,212,65,227,213,65,227,214,65,227,215,65,227,216,65,227,217,65,227,58,199,
197,7,92,16,69,165,229,174,239,231,55,250,128,231,252,176,97,117,186,136,124,205,19,68,68,135,91,68,100,247,137,70,
40,28,167,209,42,24,55,83,61,6,206,17,81,73,75,140,52,155,188,107,90,250,241,227,122,8,222,105,31,95,87,8,
72,7,193,203,71,248,159,80,126,93,177,245,163,56,175,8,168,15,94,239,113,124,252,45,181,126,107,220,160,232,9,218,
245,253,83,10,224,67,50,62,150,75,11,118,150,49,191,65,94,142,201,173,35,119,154,23,202,1,195,169,197,174,20,42,
152,247,228,160,190,21,207,44,153,215,236,240,145,159,18,255,244,71,145,107,66,23,17,69,56,249,130,188,125,29,160,136,
224,125,196,28,84,42,126,189,151,92,240,131,243,132,251,2,209,156,69,140,183,23,128,28,78,48,25,133,25,138,76,88,
167,236,164,26,86,191,167,217,174,253,249,185,121,97,165,250,239,142,106,180,59,68,101,51,141,69,151,194,48,140,157,35,
138,221,227,247,122,214,184,240,50,102,153,33,156,123,191,158,30,146,193,169,131,184,150,124,226,198,244,60,201,180,176,231,
110,170,167,107,151,130,102,104,24,206,48,83,245,146,176,78,217,5,64,58,135,121,189,39,30,150,107,97,36,143,35,30,
79,190,16,172,94,152,191,56,142,252,126,142,129,39,118,18,191,217,165,175,114,43,199,188,59,112,200,158,185,177,163,114,
90,50,103,227,227,130,75,137,3,43,139,179,251,83,189,38,166,78,239,75,185,114,244,167,196,203,119,142,169,253,45,9,
236,52,217,80,87,101,106,51,222,97,61,32,197,2,23,57,136,97,193,144,195,221,219,182,50,76,225,83,25,83,124,73,
198,23,139,192,192,128,63,99,235,23,249,102,195,234,46,251,78,236,73,254,199,95,119,115,173,80,232,134,72,28,84,89,
200,118,234,235,74,35,123,91,240,74,63,72,143,221,125,228,144,114,3,190,80,226,98,231,137,170,183,70,11,70,57,243,
185,75,204,217,162,228,132,202,113,208,238,236,32,144,229,49,127,190,228,131,187,92,14,207,168,40,119,157,57,68,163,230,
243,233,59,207,156,126,136,119,159,57,21,17,95,130,225,218,244,237,105,7,186,35,221,236,230,90,245,44,166,249,162,12,
215,174,143,147,161,27,92,41,41,97,67,186,168,78,150,162,122,88,22,194,186,88,205,166,230,123,181,208,53,156,161,235,
188,117,170,87,4,227,28,226,189,252,144,158,242,210,117,27,153,43,191,88,78,119,224,52,154,215,10,202,119,230,118,24,
70,76,32,238,147,187,216,15,200,44,16,170,177,132,120,154,120,141,72,83,121,205,187,174,240,196,192,185,230,56,123,88,
39,193,27,65,124,89,56,42,84,124,185,169,143,175,46,70,93,253,230,253,190,39,231,79,143,61,56,118,100,141,223,219,
181,44,113,188,104,145,176,163,36,68,47,90,22,184,255,202,112,3,46,107,252,161,116,134,21,196,243,210,57,150,203,255,
127,181,252,194,227,93,219,159,136,51,150,223,113,133,118,44,79,85,139,41,248,11,9,250,223,238,25,95,247,244,202,167,
219,31,60,190,43,233,47,127,23,184,206,124,73,121,119,163,10,133,26,73,164,165,79,168,32,120,151,164,103,102,152,170,
222,113,206,125,159,88,197,216,98,158,104,53,91,24,154,94,155,88,15,43,57,161,70,143,122,214,108,223,87,93,124,167,
73,170,22,37,225,91,226,44,172,153,74,15,95,87,93,45,136,227,25,121,167,154,68,182,113,84,76,85,152,140,99,99,
134,210,38,57,218,72,72,112,59,58,188,154,14,93,40,116,144,240,54,232,78,71,206,36,190,51,224,216,201,56,11,3,
232,104,154,196,248,53,232,184,154,68,121,166,208,205,119,227,88,59,43,172,151,2,227,95,216,238,217,244,115,239,102,13,
223,200,231,15,137,204,224,157,251,193,111,95,163,213,172,117,102,219,110,226,247,231,246,176,182,15,183,151,217,118,220,142,
102,155,114,251,154,109,221,74,30,221,51,220,31,220,47,220,63,220,79,220,95,244,97,228,168,65,199,249,85,159,73,63,
210,167,126,53,40,235,7,162,18,120,125,110,254,138,253,183,216,221,239,40,45,120,195,27,245,51,199,89,188,78,130,151,
173,42,199,217,54,107,84,52,119,118,23,247,167,94,57,149,150,114,229,228,158,228,43,31,175,239,117,120,234,196,250,95,
181,106,86,252,243,232,66,161,219,131,131,3,143,201,93,224,27,29,1,92,13,8,8,184,64,226,54,173,106,229,130,223,
12,25,16,243,217,51,203,218,108,63,176,45,225,143,95,211,146,175,242,238,242,249,131,216,197,189,81,102,134,198,13,139,
154,101,132,43,187,234,52,222,20,188,214,157,164,18,115,191,83,235,114,218,178,35,215,165,237,209,116,82,157,145,157,11,
107,190,36,127,171,20,179,141,71,187,240,62,25,151,27,75,204,254,90,233,133,130,219,92,62,235,28,13,253,38,70,245,
140,41,28,23,105,86,5,131,128,2,26,142,177,109,134,224,157,246,145,210,243,88,80,161,146,25,151,110,117,19,188,14,
25,215,115,245,177,7,91,228,56,77,153,231,5,89,234,213,195,59,134,252,78,217,36,206,254,248,197,128,83,20,107,122,
252,135,207,250,159,252,233,203,129,167,246,125,23,127,158,68,237,37,8,215,236,139,221,71,22,52,55,195,75,22,187,227,
48,94,22,188,113,170,238,64,22,74,124,200,99,233,88,114,113,82,221,159,254,49,177,85,201,201,180,212,146,189,214,54,
174,231,194,251,52,207,240,23,250,32,81,54,147,7,29,83,90,222,171,164,134,126,195,151,89,69,88,189,30,202,166,4,
180,180,111,42,4,20,208,108,124,101,124,184,151,90,178,79,217,121,172,212,67,105,230,24,59,235,161,247,246,185,224,173,
68,156,166,34,18,226,208,246,33,16,131,126,194,193,237,9,162,82,133,8,118,150,83,68,5,21,4,175,117,208,171,22,
188,207,226,219,178,160,78,208,116,82,77,52,68,11,93,8,83,182,78,251,93,239,88,219,57,226,38,239,19,96,61,241,
41,243,196,73,117,47,122,76,88,119,93,118,6,13,125,199,168,132,197,187,168,74,126,80,92,127,250,210,11,34,10,104,
54,190,140,204,57,249,219,142,80,122,119,183,232,228,13,230,24,251,92,87,193,203,150,194,161,13,67,19,170,8,186,200,
5,65,104,115,184,143,135,13,169,106,134,50,164,184,235,44,94,20,188,13,84,13,220,143,74,94,106,14,244,103,116,223,
65,40,114,199,107,234,30,251,119,189,195,108,231,41,46,188,83,152,249,78,69,39,189,173,238,238,238,99,215,149,72,158,
168,169,255,188,103,248,14,221,208,86,53,23,182,165,141,59,65,68,1,141,198,86,121,211,119,139,207,248,92,105,193,203,
57,241,229,179,46,208,89,240,102,84,208,121,238,177,214,16,133,54,103,249,35,173,77,167,93,153,29,71,241,162,224,93,
174,98,124,169,211,238,81,55,77,39,213,218,215,50,25,236,84,54,175,177,165,157,203,186,240,78,81,25,241,187,243,183,
41,93,152,196,242,94,117,52,245,31,227,22,57,231,11,213,160,141,59,66,72,1,141,198,214,194,107,167,84,39,212,21,
188,79,92,87,253,178,187,238,130,151,23,196,83,85,40,180,97,55,85,221,130,48,180,105,69,181,205,131,5,247,49,245,
245,73,162,150,42,130,87,150,148,84,50,118,183,228,130,237,214,129,94,93,211,73,117,88,70,251,210,142,163,138,19,106,
212,176,199,205,54,254,196,197,119,106,173,250,59,25,165,56,233,50,157,124,206,61,26,47,202,191,27,237,76,194,82,205,
24,233,195,218,127,148,2,191,19,186,33,86,177,203,241,177,42,239,238,150,124,224,71,235,24,139,209,93,240,102,92,24,
162,76,9,202,93,96,3,158,185,168,214,182,69,137,140,220,177,217,117,18,47,9,94,101,47,197,240,173,89,203,64,47,
168,233,228,186,194,168,73,63,236,9,53,5,11,85,25,178,180,241,96,23,223,105,181,17,87,74,121,33,149,206,91,73,
149,158,228,123,61,160,169,239,112,165,43,227,118,182,186,187,79,215,157,14,140,132,160,2,138,143,169,4,235,253,131,130,
253,103,171,95,112,226,182,235,170,68,134,218,65,240,178,45,227,60,182,51,238,106,224,213,130,20,192,231,41,224,196,180,
73,245,133,44,194,177,52,39,14,226,37,193,203,126,39,10,197,47,80,48,80,127,189,199,74,41,230,226,4,187,55,189,
216,196,102,53,119,15,174,175,92,23,233,194,251,148,208,97,119,215,41,123,64,140,166,190,211,195,248,24,173,221,73,233,
5,185,216,61,155,204,118,254,134,40,12,97,5,20,220,209,237,107,198,195,155,185,195,139,207,250,74,139,146,194,225,141,
251,155,227,107,136,7,219,36,215,5,111,52,151,0,14,11,13,22,95,188,219,27,98,209,38,124,254,78,47,17,22,26,
100,150,153,44,172,146,224,37,203,159,113,249,136,196,165,122,11,233,187,86,209,18,162,225,68,91,67,117,113,200,151,206,
220,217,61,32,187,155,127,54,162,243,237,74,47,18,252,129,33,223,105,175,198,11,245,56,29,110,144,27,57,156,219,12,
211,62,94,90,99,63,105,68,140,2,6,163,137,241,178,218,219,115,196,22,231,58,2,5,7,220,175,133,208,77,159,199,
182,88,159,61,175,157,4,47,91,53,22,189,197,138,132,145,80,130,232,213,157,207,54,246,18,197,139,133,11,89,198,185,
122,78,157,195,11,130,183,66,198,133,170,133,59,212,219,125,164,75,94,150,193,62,69,195,234,106,198,238,121,129,94,83,
116,216,5,189,233,46,186,220,41,73,207,56,113,231,235,126,83,134,51,23,253,103,129,225,63,116,67,91,245,133,185,228,
3,63,57,251,18,239,166,77,151,101,119,185,244,108,73,89,134,54,18,100,74,120,54,125,164,251,77,138,68,1,115,206,
162,208,0,85,139,183,100,69,68,167,177,230,243,223,239,225,185,69,9,193,107,198,84,94,138,173,95,68,28,219,149,4,
225,168,41,71,119,37,138,6,245,10,179,83,92,146,49,218,14,5,5,111,155,140,29,72,138,229,84,113,192,23,26,178,
200,121,226,186,32,115,24,159,212,128,244,143,137,69,187,117,200,161,26,239,194,36,89,74,135,234,106,78,153,3,122,106,
44,120,141,236,41,81,73,15,107,177,56,151,94,118,148,118,122,135,67,92,101,159,112,55,253,35,216,252,187,249,90,38,
3,130,171,69,70,180,31,37,34,187,79,20,81,41,143,138,98,247,126,144,94,80,130,62,238,117,18,186,70,177,9,122,
238,236,250,134,78,130,151,119,81,238,34,254,215,173,67,25,113,240,7,20,165,208,174,184,196,15,9,162,43,245,157,204,
183,59,69,246,169,138,130,247,73,35,126,151,68,165,202,3,191,248,244,207,156,143,76,181,66,213,194,12,188,171,239,106,
177,9,57,73,54,209,161,42,17,199,230,89,222,43,90,99,193,251,170,113,225,113,212,179,122,45,212,15,239,55,242,6,
71,246,152,68,241,199,157,69,72,233,154,34,168,64,113,17,24,94,64,4,134,70,128,76,144,190,122,135,155,254,17,126,
173,28,252,86,237,4,29,184,201,101,53,202,219,238,173,162,57,42,9,94,211,30,226,103,225,66,5,103,246,167,64,72,
106,115,73,45,69,164,198,87,49,75,7,63,232,73,135,240,130,224,253,57,125,183,238,27,61,118,144,104,23,154,23,211,
82,139,246,80,184,195,46,229,41,181,248,103,165,171,144,69,116,190,205,156,76,239,115,113,146,156,108,196,239,118,26,135,
236,12,190,17,188,111,27,213,15,199,190,12,1,96,83,120,46,179,136,154,60,110,250,71,83,213,79,232,128,71,138,230,
140,243,194,220,162,156,224,229,75,108,175,135,132,4,138,113,35,107,138,95,127,78,134,160,84,156,147,212,71,220,87,220,
103,212,119,107,101,130,126,85,5,111,94,45,110,219,3,95,228,79,141,114,113,146,220,110,84,37,154,254,169,46,73,218,
203,107,46,120,55,24,130,119,220,42,248,172,77,225,82,238,210,87,95,203,134,127,188,168,67,122,64,144,227,82,239,81,
254,32,120,77,51,38,189,59,110,169,45,206,162,252,176,186,59,187,212,55,19,199,214,49,29,244,109,111,56,130,135,5,
111,67,254,149,121,202,214,197,4,227,143,199,101,19,214,153,190,250,161,139,19,100,91,213,67,52,236,146,157,193,210,230,
175,27,130,247,214,23,224,179,246,223,197,27,239,166,111,68,168,90,48,8,120,32,21,89,147,129,110,157,190,217,73,240,
114,242,241,143,56,93,217,157,99,106,27,187,136,16,152,106,241,107,90,178,184,115,92,29,17,74,125,68,125,245,169,236,
51,213,5,239,80,227,178,67,179,120,76,48,56,46,115,101,130,124,37,61,95,243,66,165,223,141,243,73,203,247,90,102,
3,193,251,130,113,105,45,117,25,252,214,142,225,12,215,95,74,106,235,166,111,220,110,230,147,69,91,218,108,215,255,214,
23,77,159,88,239,197,185,69,89,193,203,22,196,101,63,249,217,110,27,85,147,98,122,177,211,171,10,220,23,99,135,215,
204,40,205,42,251,202,161,129,224,157,101,164,60,234,121,55,38,25,127,91,104,169,148,166,101,161,109,227,194,228,88,57,
35,227,4,149,185,212,68,200,183,181,129,224,53,202,159,22,232,55,29,126,107,67,156,46,141,70,185,225,23,97,25,249,
211,39,190,137,182,180,211,220,76,119,84,44,62,209,221,95,5,175,153,18,232,45,142,15,77,73,168,34,14,124,159,0,
193,153,219,217,24,182,15,17,169,212,23,50,102,119,35,23,47,243,166,3,120,88,240,42,91,97,13,248,180,186,90,41,
23,38,199,33,25,199,167,10,231,177,228,155,234,150,247,42,103,3,193,123,171,177,139,215,122,40,252,214,134,68,143,92,
110,250,234,58,55,253,162,138,14,31,160,32,199,101,132,35,253,89,240,154,182,142,51,0,112,202,178,163,59,19,33,60,
115,9,206,145,220,165,125,25,51,27,195,171,190,232,120,15,11,222,231,113,92,234,167,23,34,174,175,174,22,224,194,228,
248,136,113,57,102,208,124,181,143,2,199,174,240,90,26,159,92,18,188,45,248,93,242,86,106,12,191,181,33,121,171,52,
55,125,181,163,155,126,209,87,135,120,122,144,163,11,183,99,189,60,183,104,35,120,249,230,255,98,206,211,91,175,118,52,
85,243,66,69,54,95,243,233,134,94,162,73,195,162,220,225,255,35,22,201,140,26,186,9,222,21,70,142,207,97,79,96,
162,241,51,56,110,91,78,170,169,46,78,142,159,167,151,159,222,160,118,121,91,218,9,149,239,117,107,25,123,148,140,13,
67,218,41,123,82,98,238,119,166,175,30,200,134,95,60,101,156,206,37,62,132,182,180,17,145,61,38,155,62,241,164,15,
230,22,109,4,175,105,92,156,226,82,145,232,80,241,9,9,48,100,112,240,77,38,134,47,222,237,45,184,244,179,172,160,
54,197,151,29,238,97,193,251,156,177,195,75,213,104,48,217,248,109,220,96,176,11,19,99,104,70,177,9,138,47,211,228,
2,80,164,29,4,175,108,255,221,70,42,56,42,166,1,255,181,9,215,151,244,158,154,13,159,56,144,94,108,226,59,180,
165,109,66,25,214,88,125,162,14,4,111,230,21,217,250,19,7,57,131,195,244,187,26,136,243,7,33,74,189,5,183,237,
125,147,26,136,208,188,65,66,78,56,113,178,180,163,174,130,247,1,227,152,154,146,244,99,194,241,163,93,132,158,119,153,
147,234,204,50,238,20,155,160,114,157,154,188,215,124,187,136,93,217,254,79,167,151,23,94,2,255,181,203,71,39,149,26,
183,136,155,134,110,250,131,81,237,48,79,133,134,104,75,27,125,0,133,213,233,98,250,195,112,31,205,43,218,9,94,211,
170,177,232,37,174,52,111,82,76,236,254,118,16,4,170,135,217,179,121,176,104,211,188,4,119,240,21,226,48,81,35,55,
58,218,195,130,247,22,227,66,76,171,84,76,56,254,121,3,56,214,133,73,49,40,163,116,233,253,223,170,155,157,97,217,
17,235,123,149,177,153,224,237,201,239,197,37,122,225,195,246,160,216,189,31,88,253,53,63,82,213,97,183,95,242,148,15,
231,21,109,5,47,91,97,226,81,190,64,85,165,114,1,241,236,163,173,197,57,132,56,228,24,110,195,167,151,182,18,49,
21,11,152,151,211,150,122,186,122,26,10,79,0,95,81,252,190,79,172,147,107,17,87,47,77,25,49,164,36,42,149,141,
135,156,179,197,250,94,161,54,19,188,37,51,110,228,47,216,14,63,182,1,81,201,75,77,95,125,198,77,95,40,146,241,
1,74,62,143,182,180,149,216,101,234,65,240,186,103,61,136,147,252,14,169,241,49,226,16,165,205,66,152,67,246,194,23,
14,109,79,16,35,146,170,154,142,248,43,209,47,183,59,215,195,130,55,0,169,109,176,208,222,96,66,12,176,78,198,42,
223,6,47,60,230,37,91,101,103,200,106,151,221,232,7,90,36,225,203,154,87,209,106,216,219,236,207,129,217,205,206,80,
250,145,67,104,75,221,195,203,186,221,105,157,183,6,248,120,94,177,133,224,101,171,69,172,34,46,87,166,157,201,71,23,
54,135,136,117,83,236,62,178,160,185,168,88,33,146,59,244,50,177,146,168,169,66,199,122,88,240,34,142,215,223,22,218,
216,56,115,114,77,112,97,66,140,52,39,227,226,211,63,211,165,216,196,61,118,18,187,150,190,168,102,190,99,212,176,199,
225,203,58,87,57,164,60,214,22,127,13,119,211,15,144,89,199,38,112,138,71,139,31,140,206,133,57,197,54,130,215,180,
4,130,223,236,106,253,58,133,197,23,239,244,70,152,195,77,50,48,124,185,169,143,136,77,79,55,198,225,11,167,136,20,
149,58,212,11,130,183,182,14,55,240,129,199,143,207,74,186,48,33,198,92,11,103,56,170,174,128,88,122,208,250,94,13,
236,40,120,101,127,220,159,209,31,36,242,225,211,154,158,178,208,7,139,236,199,181,110,246,255,181,19,57,186,244,134,182,
180,197,197,97,230,206,92,154,79,108,39,120,217,42,18,15,17,255,68,71,133,138,164,65,49,98,203,71,253,32,112,157,
216,252,127,253,196,144,1,149,69,116,161,188,230,174,46,231,214,45,175,90,103,122,65,240,134,103,148,168,188,243,13,76,
70,118,78,123,51,97,157,57,193,110,118,113,66,156,100,100,103,232,52,86,237,184,228,105,31,187,85,68,67,115,209,251,
158,177,203,59,244,49,248,180,142,187,187,215,159,70,180,119,179,239,155,167,23,33,137,69,91,234,188,179,219,127,118,174,
139,93,59,11,94,211,42,19,159,112,238,216,176,176,32,49,249,182,58,148,121,96,144,95,199,247,242,187,239,161,140,22,
83,39,214,23,249,194,131,205,188,186,95,203,227,67,37,205,211,130,87,58,254,29,233,105,167,70,99,66,178,49,97,245,
123,154,147,236,48,23,39,196,79,140,15,161,137,111,169,93,108,162,85,138,249,94,99,236,44,118,157,99,56,11,14,156,
11,191,214,173,216,4,101,58,177,136,157,104,55,251,126,73,122,191,207,65,91,106,26,202,18,209,113,140,181,255,39,228,
242,92,98,107,193,107,198,228,245,38,222,231,119,44,95,38,66,140,76,174,38,190,249,160,175,95,238,232,222,58,172,134,
40,87,38,191,233,124,159,17,125,136,8,149,59,208,75,130,55,191,57,8,85,207,181,10,178,185,208,206,219,102,157,104,
35,220,185,13,206,19,181,178,249,76,233,178,165,229,189,130,236,46,120,157,67,27,32,126,180,190,145,31,228,70,159,7,
95,203,206,176,25,109,169,91,24,11,157,200,56,245,253,56,5,230,17,219,11,94,235,237,124,22,190,59,136,191,131,130,
2,69,255,94,21,140,248,213,99,187,146,108,43,114,249,221,190,126,191,175,72,77,136,17,193,193,129,220,89,127,19,59,
137,100,34,80,135,142,243,134,224,149,206,63,50,99,17,165,96,122,76,82,254,189,208,202,10,130,34,178,235,29,186,92,
252,120,196,31,196,110,25,167,98,32,230,71,42,226,239,181,11,103,232,238,102,127,183,65,118,6,13,243,158,83,245,199,
252,109,134,89,251,125,25,231,240,87,100,14,241,27,193,107,26,231,147,237,78,188,198,151,180,34,35,242,136,22,77,139,
139,89,83,26,26,71,253,118,17,186,251,182,14,22,115,166,54,18,45,154,20,23,252,142,242,66,218,6,249,238,133,116,
234,48,111,9,94,57,0,70,152,3,179,80,226,98,76,88,118,89,104,233,194,153,101,194,77,118,97,34,204,40,37,92,
116,210,219,186,20,155,24,236,79,130,87,246,211,40,235,135,76,225,113,43,149,78,29,7,241,179,215,234,175,121,221,236,
235,57,215,210,3,158,64,123,170,62,231,210,71,73,129,62,211,172,253,189,149,215,87,197,230,15,191,19,188,86,227,202,
97,175,18,39,248,210,86,72,72,160,24,220,175,146,216,244,90,55,177,247,187,120,113,102,127,138,54,2,247,204,190,20,
177,119,107,188,120,151,158,125,96,159,74,130,223,69,94,68,59,33,223,177,186,174,157,228,77,193,43,7,193,84,115,144,
22,232,53,197,184,1,143,9,204,86,213,213,138,186,48,17,214,208,33,63,115,169,69,123,172,239,213,196,223,4,175,236,
171,178,78,187,247,70,22,0,163,223,32,126,213,202,21,61,110,149,217,71,27,220,236,227,188,58,124,128,98,7,255,152,
40,118,207,187,206,185,117,133,76,253,89,70,193,185,195,175,5,175,67,30,235,87,146,71,252,188,3,250,87,80,80,128,
168,92,49,82,244,236,82,86,60,48,171,137,145,225,225,252,65,245,82,155,157,163,103,218,66,113,185,11,103,54,54,158,
181,18,229,208,13,12,12,224,14,249,147,88,79,36,201,140,21,129,58,119,144,183,5,175,28,8,51,172,3,182,64,191,
233,244,197,122,24,147,154,174,217,25,238,88,107,246,229,251,46,78,132,183,233,80,108,162,248,172,175,172,139,74,164,63,
10,94,75,186,170,209,196,247,206,226,55,122,212,179,40,42,163,202,165,209,122,61,204,126,233,231,102,255,54,187,22,206,
128,121,88,41,145,251,248,113,81,236,238,119,140,76,54,206,99,79,150,128,110,162,240,188,225,247,130,215,217,74,16,247,
18,219,100,78,218,203,1,1,1,162,122,213,66,98,194,152,218,98,253,234,46,98,199,23,3,196,193,31,18,196,169,52,
223,237,0,159,74,75,22,7,232,223,220,254,249,0,177,126,85,23,49,254,214,90,162,90,76,65,193,207,38,119,114,79,
201,103,158,34,223,193,54,230,11,193,43,7,3,239,130,63,106,29,192,124,195,180,248,244,79,149,206,201,10,254,77,190,
102,241,102,31,166,186,56,17,238,52,138,77,204,248,92,237,248,93,202,82,32,223,107,169,191,138,221,76,250,174,53,177,
218,121,241,205,83,161,161,113,196,90,228,142,215,140,157,113,84,107,243,241,105,196,67,63,103,59,117,30,217,75,40,14,
164,206,46,46,95,26,140,30,254,164,181,136,143,21,206,242,52,141,55,14,53,152,43,32,120,179,176,112,121,204,217,79,
6,93,239,225,54,10,8,160,184,177,232,80,81,187,70,148,104,223,186,164,24,54,164,170,88,124,127,83,241,198,203,157,
197,182,79,227,196,233,189,57,23,193,252,59,248,119,189,177,162,147,88,68,191,155,255,141,246,173,74,138,90,213,163,68,
97,202,43,204,207,32,29,109,143,20,104,253,228,179,134,219,177,35,124,37,120,45,131,162,5,241,178,243,192,206,215,60,
129,226,124,31,18,69,239,218,40,74,62,184,19,34,88,143,56,87,87,178,51,148,119,232,80,194,150,118,158,45,239,85,
21,98,55,211,114,196,237,100,8,87,102,11,51,237,56,118,23,5,122,223,43,162,71,46,167,113,252,142,40,49,127,155,
113,201,6,49,162,94,45,125,253,166,155,253,24,134,221,93,223,95,242,45,245,80,26,9,219,45,162,232,228,245,34,42,
233,97,218,193,29,39,242,86,105,33,178,24,75,95,201,156,229,197,52,155,35,32,120,221,176,82,242,102,255,90,185,35,
116,132,56,47,119,88,13,71,8,161,76,8,21,203,71,138,102,177,197,68,223,30,229,197,45,67,171,139,41,19,234,137,
251,239,109,36,22,76,143,21,75,23,52,51,224,255,155,255,27,255,25,255,12,255,44,255,157,138,229,34,69,112,80,160,
213,177,46,203,127,227,136,252,55,215,202,139,86,165,252,165,209,125,45,120,157,210,84,113,168,195,246,172,22,208,192,136,
104,17,82,178,154,200,83,49,86,132,86,111,43,194,106,119,18,97,117,187,25,11,43,200,61,100,255,124,225,98,63,79,
48,197,144,38,239,181,21,2,215,165,144,135,38,196,60,226,131,172,198,175,243,88,14,46,90,81,228,41,91,135,10,29,
52,22,161,213,90,139,208,90,29,105,76,119,198,152,206,190,175,50,99,221,236,187,118,70,177,137,170,45,209,142,158,164,
78,23,242,231,14,198,58,149,183,74,115,242,243,186,34,184,88,37,17,20,81,88,184,48,62,246,202,77,160,4,119,115,
41,67,240,218,103,7,184,28,17,43,51,31,240,237,225,5,196,26,249,245,179,143,184,32,179,35,220,204,153,174,202,159,
221,39,255,46,255,142,249,242,119,118,35,26,201,127,43,220,31,27,58,183,4,175,211,64,225,236,30,195,136,167,88,72,
201,203,128,2,40,77,162,139,125,91,67,179,247,26,1,81,155,45,1,92,218,145,94,196,98,142,156,99,191,36,14,201,
13,5,140,23,239,81,200,205,190,42,141,54,203,21,206,74,13,194,249,249,151,203,52,128,109,57,31,178,141,230,1,8,
94,31,92,138,11,149,98,149,11,60,20,144,68,200,255,22,170,251,165,50,221,4,175,7,45,72,238,2,215,148,151,44,
58,17,61,28,233,197,60,250,130,92,165,74,54,50,182,232,240,94,49,152,17,188,98,193,114,44,115,251,54,144,97,77,
29,228,102,70,79,140,233,108,145,147,20,152,165,209,126,30,167,151,220,64,227,117,138,115,28,55,148,243,100,81,233,255,
126,175,43,60,34,54,0,200,109,96,48,24,12,6,131,193,32,120,1,4,47,12,6,131,193,96,48,8,94,0,0,0,
0,0,0,108,183,49,134,70,0,0,0,0,0,0,16,188,0,0,0,0,0,0,64,240,2,0,0,0,0,0,0,193,
11,0,0,0,0,0,0,4,47,0,0,0,0,0,0,16,188,0,0,0,0,0,0,184,192,255,3,116,155,54,6,4,
95,45,50,0,0,0,0,73,69,78,68,174,66,96,130,
};
}
namespace Sprite {
namespace SuperFamicom {
+4 -2
View File
@@ -1,7 +1,9 @@
namespace Resource {
namespace Ares {
extern const unsigned char Icon[6562];
extern const unsigned char Logo[11533];
extern const unsigned char Icon1x[6562];
extern const unsigned char Icon2x[9662];
extern const unsigned char Logo1x[11533];
extern const unsigned char Logo2x[18991];
}
namespace Sprite {
namespace SuperFamicom {
+4 -4
View File
@@ -23,8 +23,8 @@ inline auto Scheduler::uniqueID() const -> u32 {
}
//find the clock time of the furthest behind thread.
inline auto Scheduler::minimum() const -> uintmax {
uintmax minimum = (uintmax)-1;
inline auto Scheduler::minimum() const -> u64 {
u64 minimum = (u64)-1;
for(auto& thread : _threads) {
minimum = min(minimum, thread->_clock - thread->_uniqueID);
}
@@ -32,8 +32,8 @@ inline auto Scheduler::minimum() const -> uintmax {
}
//find the clock time of the furthest ahead thread.
inline auto Scheduler::maximum() const -> uintmax {
uintmax maximum = 0;
inline auto Scheduler::maximum() const -> u64 {
u64 maximum = 0;
for(auto& thread : _threads) {
maximum = max(maximum, thread->_clock - thread->_uniqueID);
}
+2 -2
View File
@@ -16,8 +16,8 @@ struct Scheduler {
auto threads() const -> u32;
auto thread(u32 threadID) const -> maybe<Thread&>;
auto uniqueID() const -> u32;
auto minimum() const -> uintmax;
auto maximum() const -> uintmax;
auto minimum() const -> u64;
auto maximum() const -> u64;
auto append(Thread& thread) -> bool;
auto remove(Thread& thread) -> void;
+5 -5
View File
@@ -24,9 +24,9 @@ inline Thread::~Thread() {
inline auto Thread::active() const -> bool { return co_active() == _handle; }
inline auto Thread::handle() const -> cothread_t { return _handle; }
inline auto Thread::frequency() const -> uintmax { return _frequency; }
inline auto Thread::scalar() const -> uintmax { return _scalar; }
inline auto Thread::clock() const -> uintmax { return _clock; }
inline auto Thread::frequency() const -> u64 { return _frequency; }
inline auto Thread::scalar() const -> u64 { return _scalar; }
inline auto Thread::clock() const -> u64 { return _clock; }
inline auto Thread::setHandle(cothread_t handle) -> void {
_handle = handle;
@@ -37,11 +37,11 @@ inline auto Thread::setFrequency(double frequency) -> void {
_scalar = Second / _frequency;
}
inline auto Thread::setScalar(uintmax scalar) -> void {
inline auto Thread::setScalar(u64 scalar) -> void {
_scalar = scalar;
}
inline auto Thread::setClock(uintmax clock) -> void {
inline auto Thread::setClock(u64 clock) -> void {
_clock = clock;
}
+10 -10
View File
@@ -1,8 +1,8 @@
struct Scheduler;
struct Thread {
enum : uintmax { Second = (uintmax)-1 >> 1 };
enum : uintmax { Size = 16_KiB * sizeof(void*) };
enum : u64 { Second = (u64)-1 >> 1 };
enum : u64 { Size = 16_KiB * sizeof(void*) };
struct EntryPoint {
cothread_t handle = nullptr;
@@ -20,14 +20,14 @@ struct Thread {
explicit operator bool() const { return _handle; }
auto active() const -> bool;
auto handle() const -> cothread_t;
auto frequency() const -> uintmax;
auto scalar() const -> uintmax;
auto clock() const -> uintmax;
auto frequency() const -> u64;
auto scalar() const -> u64;
auto clock() const -> u64;
auto setHandle(cothread_t handle) -> void;
auto setFrequency(double frequency) -> void;
auto setScalar(uintmax scalar) -> void;
auto setClock(uintmax clock) -> void;
auto setScalar(u64 scalar) -> void;
auto setClock(u64 clock) -> void;
auto create(double frequency, function<void ()> entryPoint) -> void;
auto restart(function<void ()> entryPoint) -> void;
@@ -42,9 +42,9 @@ struct Thread {
protected:
cothread_t _handle = nullptr;
u32 _uniqueID = 0;
uintmax _frequency = 0;
uintmax _scalar = 0;
uintmax _clock = 0;
u64 _frequency = 0;
u64 _scalar = 0;
u64 _clock = 0;
friend class Scheduler;
};
@@ -1,6 +1,10 @@
auto M68000::instruction() -> void {
r.ird = r.ir;
return instructionTable[r.ird]();
if(!r.stop) {
r.ird = r.ir;
return instructionTable[r.ird]();
} else {
wait(1);
}
}
M68000::M68000() {
@@ -49,6 +49,7 @@ auto M68000::supervisor() -> bool {
}
auto M68000::exception(u32 exception, u32 vector, u32 priority) -> void {
r.stop = false;
idle(10); //todo: not accurate
auto pc = r.pc;
+16 -16
View File
@@ -10,6 +10,21 @@ auto SH2::Recompiler::block(u32 address) -> Block* {
return pool(address)->blocks[address >> 1 & 0x7f] = block;
}
alwaysinline auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
#define op(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 0;
#define br(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 1;
#include "decoder.hpp"
#undef op
#undef br
return 0;
}
auto SH2::Recompiler::emit(u32 address) -> Block* {
if(unlikely(allocator.available() < 1_MiB)) {
print("SH2 allocator flush\n");
@@ -32,7 +47,7 @@ auto SH2::Recompiler::emit(u32 address) -> Block* {
address += 2;
if(hasBranched || (address & 0xfe) == 0) break; //block boundary
hasBranched = branched;
test(rax, rax);
test(al, al);
jz(imm8(1));
ret();
}
@@ -41,18 +56,3 @@ auto SH2::Recompiler::emit(u32 address) -> Block* {
allocator.reserve(size());
return block;
}
auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
#define op(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 0;
#define br(id, name, ...) \
case id: \
call(&SH2::name, &self, ##__VA_ARGS__); \
return 1;
#include "decoder.hpp"
#undef op
#undef br
return 0;
}
+8 -2
View File
@@ -31,8 +31,14 @@ auto SH2::instruction() -> void {
if constexpr(Accuracy::Recompiler) {
exceptionHandler();
auto block = recompiler.block(PC - 4);
block->execute();
// Recompiled blocks may be very small, negating the impact
// minimum cycle counts ensure that the recompiler is a net positive
do {
auto block = recompiler.block(PC - 4);
block->execute(*this);
} while (CCR <= recompiler.min_cycles);
step(CCR);
CCR = 0;
ID = 0;
+244 -233
View File
@@ -44,12 +44,25 @@ auto SH2::Recompiler::emit(u32 address) -> Block* {
push(rbp);
push(r13);
if constexpr(ABI::Windows) {
push(rsi);
push(rdi);
sub(rsp, imm8(0x40));
}
mov(rbx, imm64(&self.R[0]));
mov(rbp, imm64(&self));
mov(rbx, ra0);
mov(rbp, ra1);
auto entry = declareLabel();
jmp8(entry);
auto epilogue = defineLabel();
if constexpr(ABI::Windows) {
add(rsp, imm8(0x40));
}
pop(r13);
pop(rbp);
pop(rbx);
ret();
defineLabel(entry);
bool hasBranched = 0;
while(true) {
@@ -61,27 +74,10 @@ auto SH2::Recompiler::emit(u32 address) -> Block* {
address += 2;
if(hasBranched || (address & 0xfe) == 0) break; //block boundary
hasBranched = branched;
test(rax, rax);
jz(imm8(ABI::Windows ? 11 : 5));
if constexpr(ABI::Windows) {
add(rsp, imm8(0x40));
pop(rdi);
pop(rsi);
}
pop(r13);
pop(rbp);
pop(rbx);
ret();
test(al, al);
jnz(epilogue);
}
if constexpr(ABI::Windows) {
add(rsp, imm8(0x40));
pop(rdi);
pop(rsi);
}
pop(r13);
pop(rbp);
pop(rbx);
ret();
jmp(epilogue);
allocator.reserve(size());
return block;
@@ -108,27 +104,27 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B Rm,@(R0,Rn)
case 0x04: {
mov(esi, Rn);
add(esi, R0);
mov(edx, Rm);
mov(ra1d, Rn);
add(ra1d, R0);
mov(ra2d, Rm);
call(writeByte);
return 0;
}
//MOV.W Rm,@(R0,Rn)
case 0x05: {
mov(esi, Rn);
add(esi, R0);
mov(edx, Rm);
mov(ra1d, Rn);
add(ra1d, R0);
mov(ra2d, Rm);
call(writeWord);
return 0;
}
//MOV.L Rm,@(R0,Rn)
case 0x06: {
mov(esi, Rn);
add(esi, R0);
mov(edx, Rm);
mov(ra1d, Rn);
add(ra1d, R0);
mov(ra2d, Rm);
call(writeLong);
return 0;
}
@@ -144,8 +140,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B @(R0,Rm),Rn
case 0x0c: {
mov(esi, Rm);
add(esi, R0);
mov(ra1d, Rm);
add(ra1d, R0);
call(readByte);
movsx(eax, al);
mov(Rn, eax);
@@ -154,8 +150,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @(R0,Rm),Rn
case 0x0d: {
mov(esi, Rm);
add(esi, R0);
mov(ra1d, Rm);
add(ra1d, R0);
call(readWord);
movsx(eax, ax);
mov(Rn, eax);
@@ -164,8 +160,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.L @(R0,Rm),Rn
case 0x0e: {
mov(esi, Rm);
add(esi, R0);
mov(ra1d, Rm);
add(ra1d, R0);
call(readLong);
mov(Rn, eax);
return 0;
@@ -173,13 +169,14 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MAC.L @Rm+,@Rn+
case 0x0f: {
mov(esi, Rn);
auto skip = declareLabel();
mov(ra1d, Rn);
addd(Rn, imm8(4));
call(readLong);
movsxd(rax, eax);
push(rax);
push(rax);
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(4));
call(readLong);
movsxd(rax, eax);
@@ -190,72 +187,73 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
add(rdx, MAC);
mov(al, S);
test(al, al);
jz(imm8(8));
jz8(skip);
sal(rdx, imm8(16));
sar(rdx, imm8(16));
defineLabel(skip);
mov(MAC, rdx);
return 0;
}
//MOV.L Rm,@(disp,Rn)
case 0x10 ... 0x1f: {
mov(esi, Rn);
add(esi, imm8(d4*4));
mov(edx, Rm);
mov(ra1d, Rn);
add(ra1d, imm8(d4*4));
mov(ra2d, Rm);
call(writeLong);
return 0;
}
//MOV.B Rm,@Rn
case 0x20: {
mov(esi, Rn);
mov(edx, Rm);
mov(ra1d, Rn);
mov(ra2d, Rm);
call(writeByte);
return 0;
}
//MOV.W Rm,@Rn
case 0x21: {
mov(esi, Rn);
mov(edx, Rm);
mov(ra1d, Rn);
mov(ra2d, Rm);
call(writeWord);
return 0;
}
//MOV.L Rm,@Rn
case 0x22: {
mov(esi, Rn);
mov(edx, Rm);
mov(ra1d, Rn);
mov(ra2d, Rm);
call(writeLong);
return 0;
}
//MOV.B Rm,@-Rn
case 0x24: {
mov(esi, Rn);
dec(esi);
mov(Rn, esi);
mov(edx, Rm);
mov(ra1d, Rn);
dec(ra1d);
mov(Rn, ra1d);
mov(ra2d, Rm);
call(writeByte);
return 0;
}
//MOV.W Rm,@-Rn
case 0x25: {
mov(esi, Rn);
sub(esi, imm8(2));
mov(Rn, esi);
mov(edx, Rm);
mov(ra1d, Rn);
sub(ra1d, imm8(2));
mov(Rn, ra1d);
mov(ra2d, Rm);
call(writeWord);
return 0;
}
//MOV.L Rm,@-Rn
case 0x26: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, Rm);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, Rm);
call(writeLong);
return 0;
}
@@ -374,6 +372,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//DIV1 Rm,Rn
case 0x34: {
auto skip = declareLabel();
auto skip2 = declareLabel();
mov(al, Q);
mov(cl, al);
mov(eax, Rn);
@@ -385,10 +385,12 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
or(dl, al);
mov(al, M);
cmp(al, cl);
jnz(imm8(5));
jnz8(skip);
sub(edx, Rm);
jmp(imm8(3));
jmp8(skip2);
defineLabel(skip);
add(edx, Rm);
defineLabel(skip2);
mov(Rn, edx);
setc(dl);
mov(al, Q);
@@ -503,13 +505,14 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MAC.W @Rm+,@Rn+
case 0x4f: {
mov(esi, Rn);
auto skip = declareLabel();
mov(ra1d, Rn);
addd(Rn, imm8(2));
call(readWord);
movsx(eax, ax);
push(rax);
push(rax);
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(2));
call(readWord);
movsx(eax, ax);
@@ -521,16 +524,17 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
add(rdx, MAC);
mov(al, S);
test(al, al);
jz(imm8(3));
jz8(skip);
movsxd(rdx, edx);
defineLabel(skip);
mov(MAC, rdx);
return 0;
}
//MOV.L @(disp,Rm),Rn
case 0x50 ... 0x5f: {
mov(esi, Rm);
add(esi, imm8(d4*4));
mov(ra1d, Rm);
add(ra1d, imm8(d4*4));
call(readLong);
mov(Rn, eax);
return 0;
@@ -538,7 +542,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B @Rm,Rn
case 0x60: {
mov(esi, Rm);
mov(ra1d, Rm);
call(readByte);
movsx(eax, al);
mov(Rn, eax);
@@ -547,7 +551,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @Rm,Rn
case 0x61: {
mov(esi, Rm);
mov(ra1d, Rm);
call(readWord);
movsx(eax, ax);
mov(Rn, eax);
@@ -556,7 +560,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.L @Rm,Rn
case 0x62: {
mov(esi, Rm);
mov(ra1d, Rm);
call(readLong);
mov(Rn, eax);
return 0;
@@ -571,7 +575,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B @Rm+,Rn
case 0x64: {
mov(esi, Rm);
mov(ra1d, Rm);
if(n != m) addd(Rm, imm8(1));
call(readByte);
movsx(eax, al);
@@ -581,7 +585,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @Rm+,Rn
case 0x65: {
mov(esi, Rm);
mov(ra1d, Rm);
if(n != m) addd(Rm, imm8(2));
call(readWord);
movsx(eax, ax);
@@ -591,7 +595,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.L @Rm+,Rn
case 0x66: {
mov(esi, Rm);
mov(ra1d, Rm);
if(n != m) addd(Rm, imm8(4));
call(readLong);
mov(Rn, eax);
@@ -691,8 +695,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @(disp,PC),Rn
case 0x90 ... 0x9f: {
mov(esi, PC);
add(esi, imm32(d8*2));
mov(ra1d, PC);
add(ra1d, imm32(d8*2));
call(readWord);
movsx(eax, ax);
mov(Rn, eax);
@@ -701,28 +705,28 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//BRA disp
case 0xa0 ... 0xaf: {
mov(esi, PC);
add(esi, imm32(4 + (i12)d12 * 2));
mov(PPC, esi);
mov(eax, PC);
add(eax, imm32(4 + (i12)d12 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
//BSR disp
case 0xb0 ... 0xbf: {
mov(esi, PC);
mov(PR, esi);
add(esi, imm32(4 + (i12)d12 * 2));
mov(PPC, esi);
mov(eax, PC);
mov(PR, eax);
add(eax, imm32(4 + (i12)d12 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
//MOV.L @(disp,PC),Rn
case 0xd0 ... 0xdf: {
mov(esi, PC);
and(esi, imm8(~3));
add(esi, imm32(d8*4));
mov(ra1d, PC);
and(ra1d, imm8(~3));
add(ra1d, imm32(d8*4));
call(readLong);
mov(Rn, eax);
return 0;
@@ -756,26 +760,26 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B R0,@(disp,Rn)
case 0x80: {
mov(esi, Rm);
add(esi, imm8(d4));
mov(edx, R0);
mov(ra1d, Rm);
add(ra1d, imm8(d4));
mov(ra2d, R0);
call(writeByte);
return 0;
}
//MOV.W R0,@(disp,Rn)
case 0x81: {
mov(esi, Rm);
add(esi, imm8(d4*2));
mov(edx, R0);
mov(ra1d, Rm);
add(ra1d, imm8(d4*2));
mov(ra2d, R0);
call(writeWord);
return 0;
}
//MOV.B @(disp,Rn),R0
case 0x84: {
mov(esi, Rm);
add(esi, imm8(d4));
mov(ra1d, Rm);
add(ra1d, imm8(d4));
call(readByte);
movsx(eax, al);
mov(R0, eax);
@@ -784,8 +788,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @(disp,Rn),R0
case 0x85: {
mov(esi, Rm);
add(esi, imm8(d4*2));
mov(ra1d, Rm);
add(ra1d, imm8(d4*2));
call(readWord);
movsx(eax, ax);
mov(R0, eax);
@@ -802,75 +806,83 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//BT disp
case 0x89: {
auto skip = declareLabel();
mov(al, T);
test(al, al);
jz(imm8(16));
mov(esi, PC);
add(esi, imm32(4 + (s8)d8 * 2));
mov(PPC, esi);
jz8(skip);
mov(eax, PC);
add(eax, imm32(4 + (s8)d8 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Take));
defineLabel(skip);
return 1;
}
//BF disp
case 0x8b: {
auto skip = declareLabel();
mov(al, T);
test(al, al);
jnz(imm8(16));
mov(esi, PC);
add(esi, imm32(4 + (s8)d8 * 2));
mov(PPC, esi);
jnz8(skip);
mov(eax, PC);
add(eax, imm32(4 + (s8)d8 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Take));
defineLabel(skip);
return 1;
}
//BT/S disp
case 0x8d: {
auto skip = declareLabel();
mov(al, T);
test(al, al);
jz(imm8(16));
mov(esi, PC);
add(esi, imm32(4 + (s8)d8 * 2));
mov(PPC, esi);
jz8(skip);
mov(eax, PC);
add(eax, imm32(4 + (s8)d8 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
defineLabel(skip);
return 1;
}
//BF/S disp
case 0x8f: {
auto skip = declareLabel();
mov(al, T);
test(al, al);
jnz(imm8(16));
mov(esi, PC);
add(esi, imm32(4 + (s8)d8 * 2));
mov(PPC, esi);
jnz8(skip);
mov(eax, PC);
add(eax, imm32(4 + (s8)d8 * 2));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
defineLabel(skip);
return 1;
}
//MOV.B R0,@(disp,GBR)
case 0xc0: {
mov(esi, GBR);
add(esi, imm32(d8));
mov(edx, R0);
mov(ra1d, GBR);
add(ra1d, imm32(d8));
mov(ra2d, R0);
call(writeByte);
return 0;
}
//MOV.W R0,@(disp,GBR)
case 0xc1: {
mov(esi, GBR);
add(esi, imm32(d8*2));
mov(edx, R0);
mov(ra1d, GBR);
add(ra1d, imm32(d8*2));
mov(ra2d, R0);
call(writeWord);
return 0;
}
//MOV.L R0,@(disp,GBR)
case 0xc2: {
mov(esi, GBR);
add(esi, imm32(d8*4));
mov(edx, R0);
mov(ra1d, GBR);
add(ra1d, imm32(d8*4));
mov(ra2d, R0);
call(writeLong);
return 0;
}
@@ -893,16 +905,18 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
mov(al, M);
shl(eax, imm8(9));
or(edx, eax);
mov(esi, R15);
mov(ra2d, edx);
mov(ra1d, R15);
addd(R15, imm8(4));
call(writeLong);
mov(edx, PC);
add(edx, imm8(2));
mov(esi, R15);
mov(ra2d, edx);
mov(ra1d, R15);
addd(R15, imm8(4));
call(writeLong);
mov(esi, VBR);
add(esi, imm32(i * 4));
mov(ra1d, VBR);
add(ra1d, imm32(i * 4));
call(readLong);
add(eax, imm8(4));
mov(PPC, eax);
@@ -912,8 +926,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.B @(disp,GBR),R0
case 0xc4: {
mov(esi, GBR);
add(esi, imm32(d8));
mov(ra1d, GBR);
add(ra1d, imm32(d8));
call(readByte);
movsx(eax, al);
mov(R0, eax);
@@ -922,8 +936,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.W @(disp,GBR),R0
case 0xc5: {
mov(esi, GBR);
add(esi, imm32(d8*2));
mov(ra1d, GBR);
add(ra1d, imm32(d8*2));
call(readWord);
movsx(eax, ax);
mov(R0, eax);
@@ -932,8 +946,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOV.L @(disp,GBR),R0
case 0xc6: {
mov(esi, GBR);
add(esi, imm32(d8*4));
mov(ra1d, GBR);
add(ra1d, imm32(d8*4));
call(readLong);
mov(R0, rax);
return 0;
@@ -941,16 +955,18 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//MOVA @(disp,PC),R0
case 0xc7: {
auto skip = declareLabel();
mov(eax, PC);
and(al, imm8(~3));
add(eax, imm32(d8*4));
mov(R0, eax);
mov(eax, PPM);
test(eax, eax);
jz(imm8(7));
jz8(skip);
mov(eax, R0);
sub(eax, imm8(2));
mov(R0, eax);
defineLabel(skip);
return 0;
}
@@ -988,8 +1004,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//TST.B #imm,@(R0,GBR)
case 0xcc: {
mov(esi, GBR);
add(esi, R0);
mov(ra1d, GBR);
add(ra1d, R0);
call(readByte);
and(al, imm8(i));
setz(T);
@@ -998,39 +1014,39 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//AND.B #imm,@(R0,GBR)
case 0xcd: {
mov(esi, GBR);
add(esi, R0);
mov(ra1d, GBR);
add(ra1d, R0);
call(readByte);
and(al, imm8(i));
mov(edx, eax);
mov(esi, GBR);
add(esi, R0);
mov(ra2d, eax);
mov(ra1d, GBR);
add(ra1d, R0);
call(writeByte);
return 0;
}
//XOR.B #imm,@(R0,GBR)
case 0xce: {
mov(esi, GBR);
add(esi, R0);
mov(ra1d, GBR);
add(ra1d, R0);
call(readByte);
xor(al, imm8(i));
mov(edx, eax);
mov(esi, GBR);
add(esi, R0);
mov(ra2d, eax);
mov(ra1d, GBR);
add(ra1d, R0);
call(writeByte);
return 0;
}
//OR.B #imm,@(R0,GBR)
case 0xcf: {
mov(esi, GBR);
add(esi, R0);
mov(ra1d, GBR);
add(ra1d, R0);
call(readByte);
or(al, imm8(i));
mov(edx, eax);
mov(esi, GBR);
add(esi, R0);
mov(ra2d, eax);
mov(ra1d, GBR);
add(ra1d, R0);
call(writeByte);
return 0;
}
@@ -1052,6 +1068,8 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//STC SR,Rn
case 0x002: {
auto skip = declareLabel();
auto skip2 = declareLabel();
xor(edx, edx);
xor(eax, eax);
mov(al, T);
@@ -1064,23 +1082,25 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
or(dl, al);
mov(al, Q);
test(al, al);
jz(imm8(6));
jz8(skip);
or(edx, imm32(0x100));
defineLabel(skip);
mov(al, M);
test(al, al);
jz(imm8(6));
jz8(skip2);
or(edx, imm32(0x200));
defineLabel(skip2);
mov(Rn, edx);
return 0;
}
//BSRF Rm
case 0x003: {
mov(esi, PC);
mov(PR, esi);
add(esi, Rm);
add(esi, imm8(4));
mov(PPC, esi);
mov(eax, PC);
mov(PR, eax);
add(eax, Rm);
add(eax, imm8(4));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
@@ -1115,10 +1135,10 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//BRAF Rm
case 0x023: {
mov(esi, PC);
add(esi, Rm);
add(esi, imm8(4));
mov(PPC, esi);
mov(eax, PC);
add(eax, Rm);
add(eax, imm8(4));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
@@ -1162,16 +1182,18 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//STS.L MACH,@-Rn
case 0x402: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, MACH);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, MACH);
call(writeLong);
return 0;
}
//STC.L SR,@-Rn
case 0x403: {
auto skip = declareLabel();
auto skip2 = declareLabel();
xor(edx, edx);
xor(eax, eax);
mov(al, T);
@@ -1184,15 +1206,18 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
or(dl, al);
mov(al, Q);
test(al, al);
jz(imm8(6));
jz8(skip);
or(edx, imm32(0x100));
defineLabel(skip);
mov(al, M);
test(al, al);
jz(imm8(6));
jz8(skip2);
or(edx, imm32(0x200));
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
defineLabel(skip2);
mov(ra2d, edx);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
call(writeLong);
return 0;
}
@@ -1221,7 +1246,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDS.L @Rm+,MACH
case 0x406: {
mov(esi, Rn);
mov(ra1d, Rn);
addd(Rn, imm8(4));
call(readLong);
mov(MACH, rax);
@@ -1230,7 +1255,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDC.L @Rm+,SR
case 0x407: {
mov(esi, Rn);
mov(ra1d, Rn);
addd(Rn, imm8(4));
call(readLong);
mov(edx, eax);
@@ -1280,11 +1305,11 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//JSR @Rm
case 0x40b: {
mov(esi, PC);
mov(PR, esi);
mov(esi, Rm);
add(esi, imm8(4));
mov(PPC, esi);
mov(eax, PC);
mov(PR, eax);
mov(eax, Rm);
add(eax, imm8(4));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
@@ -1334,20 +1359,20 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//STS.L MACL,@-Rn
case 0x412: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, MACL);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, MACL);
call(writeLong);
return 0;
}
//STC.L GBR,@-Rn
case 0x413: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, GBR);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, GBR);
call(writeLong);
return 0;
}
@@ -1362,7 +1387,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDS.L @Rm+,MACL
case 0x416: {
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(4));
call(readLong);
mov(MACL, eax);
@@ -1371,7 +1396,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDS.L @Rm+,GBR
case 0x417: {
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(4));
call(readLong);
mov(GBR, eax);
@@ -1403,9 +1428,9 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//TAS @Rn
case 0x41b: {
mov(esi, Rn);
and(esi, imm32(0x1fff'ffff));
or(esi, imm32(0x2000'0000));
mov(ra1d, Rn);
and(ra1d, imm32(0x1fff'ffff));
or(ra1d, imm32(0x2000'0000));
call(readByte);
mov(cl, al);
test(al, al);
@@ -1413,10 +1438,10 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
mov(T, al);
mov(al, cl);
or(al, imm8(0x80));
mov(edx, eax);
mov(esi, Rn);
and(esi, imm32(0x1fff'ffff));
or(esi, imm32(0x2000'0000));
mov(ra2d, eax);
mov(ra1d, Rn);
and(ra1d, imm32(0x1fff'ffff));
or(ra1d, imm32(0x2000'0000));
call(writeByte);
return 0;
}
@@ -1452,20 +1477,20 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//STS.L PR,@-Rn
case 0x422: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, PR);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, PR);
call(writeLong);
return 0;
}
//STC.L VBR,@-Rn
case 0x423: {
mov(esi, Rn);
sub(esi, imm8(4));
mov(Rn, esi);
mov(edx, VBR);
mov(ra1d, Rn);
sub(ra1d, imm8(4));
mov(Rn, ra1d);
mov(ra2d, VBR);
call(writeLong);
return 0;
}
@@ -1504,7 +1529,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDS.L @Rm+,PR
case 0x426: {
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(4));
call(readLong);
mov(PR, eax);
@@ -1513,7 +1538,7 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//LDC.L @Rm+,VBR
case 0x427: {
mov(esi, Rm);
mov(ra1d, Rm);
addd(Rm, imm8(4));
call(readLong);
mov(VBR, eax);
@@ -1545,9 +1570,9 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//JMP @Rm
case 0x42b: {
mov(esi, Rm);
add(esi, imm8(4));
mov(PPC, esi);
mov(eax, Rm);
add(eax, imm8(4));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
@@ -1581,9 +1606,9 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//RTS
case 0x000b: {
mov(esi, PR);
add(esi, imm8(4));
mov(PPC, esi);
mov(eax, PR);
add(eax, imm8(4));
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
return 1;
}
@@ -1606,12 +1631,16 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//SLEEP
case 0x001b: {
auto skip = declareLabel();
auto skip2 = declareLabel();
mov(eax, ET);
test(al, al);
jnz(imm8(6));
jnz8(skip);
subd(PC, imm8(2));
jmp(imm8(4));
jmp8(skip2);
defineLabel(skip);
movb(ET, imm8(0));
defineLabel(skip2);
return 1;
}
@@ -1624,12 +1653,12 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
//RTE
case 0x002b: {
mov(esi, R15);
mov(ra1d, R15);
addd(R15, imm8(4));
call(readLong);
mov(PPC, eax);
movb(PPM, imm8(Branch::Slot));
mov(esi, R15);
mov(ra1d, R15);
addd(R15, imm8(4));
call(readLong);
mov(edx, eax);
@@ -1710,21 +1739,3 @@ auto SH2::Recompiler::emitInstruction(u16 opcode) -> bool {
#undef writeWord
#undef writeLong
#undef illegal
template<typename V, typename... P>
auto SH2::Recompiler::call(V (SH2::*function)(P...)) -> void {
static_assert(sizeof...(P) <= 5);
mov(rax, imm64(function));
if constexpr(ABI::SystemV) {
mov(rdi, rbp);
}
if constexpr(ABI::Windows) {
if constexpr(sizeof...(P) >= 5) mov(dis8(rsp, 0x28), r9);
if constexpr(sizeof...(P) >= 4) mov(dis8(rsp, 0x20), r8);
if constexpr(sizeof...(P) >= 3) mov(r9, rcx);
if constexpr(sizeof...(P) >= 2) mov(r8, rdx);
if constexpr(sizeof...(P) >= 1) mov(rdx, rsi);
mov(rcx, rbp);
}
call(rax);
}
+4 -3
View File
@@ -9,8 +9,8 @@ namespace ares {
#include "exceptions.cpp"
#include "instruction.cpp"
#include "instructions.cpp"
//#include "cached.cpp"
#include "recompiler.cpp"
#include "cached.cpp"
//#include "recompiler.cpp"
#include "serialization.cpp"
#include "disassembler.cpp"
@@ -47,7 +47,8 @@ auto SH2::power(bool reset) -> void {
cache.power();
if constexpr(Accuracy::Recompiler) {
recompiler.allocator.resize(512_MiB, bump_allocator::executable | bump_allocator::zero_fill);
auto buffer = ares::Memory::FixedAllocator::get().acquire(512_MiB);
recompiler.allocator.resize(512_MiB, bump_allocator::executable | bump_allocator::zero_fill, buffer);
recompiler.reset();
}
}
+14 -4
View File
@@ -250,8 +250,8 @@ struct SH2 {
Recompiler(SH2& self) : self(self) {}
struct Block {
auto execute() -> void {
((void (*)())code)();
auto execute(SH2& self) -> void {
((void (*)(u32*, SH2*))code)(&self.R[0], &self);
}
u8* code;
@@ -266,7 +266,7 @@ struct SH2 {
}
auto invalidate(u32 address) -> void {
pools[address >> 8 & 0xffffff] = nullptr;
pool(address)->blocks[address >> 1 & 0x7f] = nullptr;
}
auto pool(u32 address) -> Pool*;
@@ -274,10 +274,20 @@ struct SH2 {
auto emit(u32 address) -> Block*;
auto emitInstruction(u16 opcode) -> bool;
template<typename R, typename... P> auto call(R (SH2::*function)(P...)) -> void;
template<typename V, typename... P>
alwaysinline auto call(V (SH2::*function)(P...)) -> void {
static_assert(sizeof...(P) <= 5);
if constexpr(ABI::Windows) {
if constexpr(sizeof...(P) >= 5) mov(dis8(rsp, 0x28), ra5);
if constexpr(sizeof...(P) >= 4) mov(dis8(rsp, 0x20), ra4);
}
mov(ra0, rbp);
call(imm64{function}, rax);
}
bump_allocator allocator;
Pool* pools[1 << 24];
int min_cycles = 0;
} recompiler{*this};
#include "sh7604/sh7604.hpp"
@@ -96,17 +96,16 @@ auto SM83::instructionCPL() -> void {
auto SM83::instructionDAA() -> void {
n16 a = A;
if(!NF) {
if(HF || (n4)a > 0x09) a += 0x06;
if(CF || (n8)a > 0x9f) a += 0x60;
} else {
if(HF) {
a -= 0x06;
if(!CF) a &= 0xff;
if(HF || (n4)A > 0x09) a += 0x06;
if(CF || (n8)A > 0x99) {
a += 0x60;
CF = 1;
}
} else {
if(HF) a -= 0x06;
if(CF) a -= 0x60;
}
A = a;
CF |= a.bit(8);
HF = 0;
ZF = A == 0;
}
@@ -135,6 +134,7 @@ auto SM83::instructionEI() -> void {
auto SM83::instructionHALT() -> void {
r.halt = 1;
haltBugTrigger();
while(r.halt) halt();
}
+6 -2
View File
@@ -1,10 +1,14 @@
auto SM83::operand() -> n8 {
if(r.haltBug) {
r.haltBug = 0;
return read(PC);
}
return read(PC++);
}
auto SM83::operands() -> n16 {
n16 data = read(PC++) << 0;
return data | read(PC++) << 8;
n16 data = operand() << 0;
return data | operand() << 8;
}
auto SM83::load(n16 address) -> n16 {
+4
View File
@@ -15,6 +15,7 @@ struct SM83 {
virtual auto idle() -> void = 0;
virtual auto read(n16 address) -> n8 = 0;
virtual auto write(n16 address, n8 data) -> void = 0;
virtual auto haltBugTrigger() -> void = 0;
//sm83.cpp
auto power() -> void;
@@ -175,6 +176,9 @@ struct SM83 {
n1 halt;
n1 stop;
n1 ime;
// set if halt bug occurs
n1 haltBug;
} r;
//disassembler.cpp
@@ -1,19 +1,19 @@
template<> auto TLCS900H::map(ControlRegister<n8> register) const -> maybe<n8&> {
switch(register.id) {
#define r(id, name) case id: return r.name;
r(0x00, dmas[0].b0) r(0x01, dmas[0].b1) r(0x02, dmas[0].b2) r(0x03, dmas[0].b3)
r(0x04, dmas[1].b0) r(0x05, dmas[1].b1) r(0x06, dmas[1].b2) r(0x07, dmas[1].b3)
r(0x08, dmas[2].b0) r(0x09, dmas[2].b1) r(0x0a, dmas[2].b2) r(0x0b, dmas[2].b3)
r(0x0c, dmas[3].b0) r(0x0d, dmas[3].b1) r(0x0e, dmas[3].b2) r(0x0f, dmas[3].b3)
r(0x10, dmad[0].b0) r(0x11, dmad[0].b1) r(0x12, dmad[0].b2) r(0x13, dmad[0].b3)
r(0x14, dmad[1].b0) r(0x15, dmad[1].b1) r(0x16, dmad[1].b2) r(0x17, dmad[1].b3)
r(0x18, dmad[2].b0) r(0x19, dmad[2].b1) r(0x1a, dmad[2].b2) r(0x1b, dmad[2].b3)
r(0x1c, dmad[3].b0) r(0x1d, dmad[3].b1) r(0x1e, dmad[3].b2) r(0x1f, dmad[3].b3)
r(0x20, dmam[0].b0) r(0x21, dmam[0].b1) r(0x22, dmam[0].b2) r(0x23, dmam[0].b3)
r(0x24, dmam[1].b0) r(0x25, dmam[1].b1) r(0x26, dmam[1].b2) r(0x27, dmam[1].b3)
r(0x28, dmam[2].b0) r(0x29, dmam[2].b1) r(0x2a, dmam[2].b2) r(0x2b, dmam[2].b3)
r(0x2c, dmam[3].b0) r(0x2d, dmam[3].b1) r(0x2e, dmam[3].b3) r(0x2f, dmam[3].b3)
r(0x3c, intnest.b0) r(0x3d, intnest.b1)
r(0x00, dmas[0].b.b0) r(0x01, dmas[0].b.b1) r(0x02, dmas[0].b.b2) r(0x03, dmas[0].b.b3)
r(0x04, dmas[1].b.b0) r(0x05, dmas[1].b.b1) r(0x06, dmas[1].b.b2) r(0x07, dmas[1].b.b3)
r(0x08, dmas[2].b.b0) r(0x09, dmas[2].b.b1) r(0x0a, dmas[2].b.b2) r(0x0b, dmas[2].b.b3)
r(0x0c, dmas[3].b.b0) r(0x0d, dmas[3].b.b1) r(0x0e, dmas[3].b.b2) r(0x0f, dmas[3].b.b3)
r(0x10, dmad[0].b.b0) r(0x11, dmad[0].b.b1) r(0x12, dmad[0].b.b2) r(0x13, dmad[0].b.b3)
r(0x14, dmad[1].b.b0) r(0x15, dmad[1].b.b1) r(0x16, dmad[1].b.b2) r(0x17, dmad[1].b.b3)
r(0x18, dmad[2].b.b0) r(0x19, dmad[2].b.b1) r(0x1a, dmad[2].b.b2) r(0x1b, dmad[2].b.b3)
r(0x1c, dmad[3].b.b0) r(0x1d, dmad[3].b.b1) r(0x1e, dmad[3].b.b2) r(0x1f, dmad[3].b.b3)
r(0x20, dmam[0].b.b0) r(0x21, dmam[0].b.b1) r(0x22, dmam[0].b.b2) r(0x23, dmam[0].b.b3)
r(0x24, dmam[1].b.b0) r(0x25, dmam[1].b.b1) r(0x26, dmam[1].b.b2) r(0x27, dmam[1].b.b3)
r(0x28, dmam[2].b.b0) r(0x29, dmam[2].b.b1) r(0x2a, dmam[2].b.b2) r(0x2b, dmam[2].b.b3)
r(0x2c, dmam[3].b.b0) r(0x2d, dmam[3].b.b1) r(0x2e, dmam[3].b.b3) r(0x2f, dmam[3].b.b3)
r(0x3c, intnest.b.b0) r(0x3d, intnest.b.b1)
#undef r
}
return nothing;
@@ -22,19 +22,19 @@ template<> auto TLCS900H::map(ControlRegister<n8> register) const -> maybe<n8&>
template<> auto TLCS900H::map(ControlRegister<n16> register) const -> maybe<n16&> {
switch(register.id & ~1) {
#define r(id, name) case id: return r.name;
r(0x00, dmas[0].w0) r(0x02, dmas[0].w1)
r(0x04, dmas[1].w0) r(0x06, dmas[1].w1)
r(0x08, dmas[2].w0) r(0x0a, dmas[2].w1)
r(0x0c, dmas[3].w0) r(0x0e, dmas[3].w1)
r(0x10, dmad[0].w0) r(0x12, dmad[0].w1)
r(0x14, dmad[1].w0) r(0x16, dmad[1].w1)
r(0x18, dmad[2].w0) r(0x1a, dmad[2].w1)
r(0x1c, dmad[3].w0) r(0x1e, dmad[3].w1)
r(0x20, dmam[0].w0) r(0x22, dmam[0].w1)
r(0x24, dmam[1].w0) r(0x26, dmam[1].w1)
r(0x28, dmam[2].w0) r(0x2a, dmam[2].w1)
r(0x2c, dmam[3].w0) r(0x2e, dmam[3].w1)
r(0x3c, intnest.w0)
r(0x00, dmas[0].w.w0) r(0x02, dmas[0].w.w1)
r(0x04, dmas[1].w.w0) r(0x06, dmas[1].w.w1)
r(0x08, dmas[2].w.w0) r(0x0a, dmas[2].w.w1)
r(0x0c, dmas[3].w.w0) r(0x0e, dmas[3].w.w1)
r(0x10, dmad[0].w.w0) r(0x12, dmad[0].w.w1)
r(0x14, dmad[1].w.w0) r(0x16, dmad[1].w.w1)
r(0x18, dmad[2].w.w0) r(0x1a, dmad[2].w.w1)
r(0x1c, dmad[3].w.w0) r(0x1e, dmad[3].w.w1)
r(0x20, dmam[0].w.w0) r(0x22, dmam[0].w.w1)
r(0x24, dmam[1].w.w0) r(0x26, dmam[1].w.w1)
r(0x28, dmam[2].w.w0) r(0x2a, dmam[2].w.w1)
r(0x2c, dmam[3].w.w0) r(0x2e, dmam[3].w.w1)
r(0x3c, intnest.w.w0)
#undef r
}
return nothing;
@@ -43,19 +43,19 @@ template<> auto TLCS900H::map(ControlRegister<n16> register) const -> maybe<n16&
template<> auto TLCS900H::map(ControlRegister<n32> register) const -> maybe<n32&> {
switch(register.id & ~1) {
#define r(id, name) case id: return r.name;
r(0x00, dmas[0].l0)
r(0x04, dmas[1].l0)
r(0x08, dmas[2].l0)
r(0x0c, dmas[3].l0)
r(0x10, dmad[0].l0)
r(0x14, dmad[1].l0)
r(0x18, dmad[2].l0)
r(0x1c, dmad[3].l0)
r(0x20, dmam[0].l0)
r(0x24, dmam[1].l0)
r(0x28, dmam[2].l0)
r(0x2c, dmam[3].l0)
r(0x3c, intnest.l0)
r(0x00, dmas[0].l.l0)
r(0x04, dmas[1].l.l0)
r(0x08, dmas[2].l.l0)
r(0x0c, dmas[3].l.l0)
r(0x10, dmad[0].l.l0)
r(0x14, dmad[1].l.l0)
r(0x18, dmad[2].l.l0)
r(0x1c, dmad[3].l.l0)
r(0x20, dmam[0].l.l0)
r(0x24, dmam[1].l.l0)
r(0x28, dmam[2].l.l0)
r(0x2c, dmam[3].l.l0)
r(0x3c, intnest.l.l0)
#undef r
}
return nothing;
@@ -638,14 +638,14 @@ noinline auto TLCS900H::disassembleInstruction() -> string {
noinline auto TLCS900H::disassembleContext() -> string {
string output;
output.append("XWA:", hex(r.xwa[RFP].l0, 8L), " ");
output.append("XBC:", hex(r.xbc[RFP].l0, 8L), " ");
output.append("XDE:", hex(r.xde[RFP].l0, 8L), " ");
output.append("XHL:", hex(r.xhl[RFP].l0, 8L), " ");
output.append("XIX:", hex(r.xix.l0, 8L), " ");
output.append("XIY:", hex(r.xiy.l0, 8L), " ");
output.append("XIZ:", hex(r.xiz.l0, 8L), " ");
output.append("XSP:", hex(r.xsp.l0, 8L), " ");
output.append("XWA:", hex(r.xwa[RFP].l.l0, 8L), " ");
output.append("XBC:", hex(r.xbc[RFP].l.l0, 8L), " ");
output.append("XDE:", hex(r.xde[RFP].l.l0, 8L), " ");
output.append("XHL:", hex(r.xhl[RFP].l.l0, 8L), " ");
output.append("XIX:", hex(r.xix.l.l0, 8L), " ");
output.append("XIY:", hex(r.xiy.l.l0, 8L), " ");
output.append("XIZ:", hex(r.xiz.l.l0, 8L), " ");
output.append("XSP:", hex(r.xsp.l.l0, 8L), " ");
output.append("IFF:", IFF, " ");
output.append("RFP:", RFP, " ");
output.append(SF ? "S" : "s");
+4 -4
View File
@@ -1,8 +1,8 @@
auto TLCS900H::dma(n2 channel) -> bool {
auto& source = r.dmas[channel].l0;
auto& target = r.dmad[channel].l0;
auto& length = r.dmam[channel].w0; //0 = 65536
auto& config = r.dmam[channel].w1;
auto& source = r.dmas[channel].l.l0;
auto& target = r.dmad[channel].l.l0;
auto& length = r.dmam[channel].w.w0; //0 = 65536
auto& config = r.dmam[channel].w.w1;
n32 mode = config.bit(2,4);
n32 size;
File diff suppressed because it is too large. Load diff
@@ -26,7 +26,7 @@ auto TLCS900H::instructionBit(Source source, Offset offset) -> void {
NF = 0;
VF = Undefined;
HF = 1;
ZF = !load(source).bit(load(offset) & Source::bits - 1);
ZF = !load(source).bit(load(offset));
SF = Undefined;
}
+1 -1
View File
@@ -9,7 +9,7 @@ template<typename T> auto TLCS900H::fetchImmediate() -> Immediate<T> { return Im
//
#define XSP r.xsp.l0
#define XSP r.xsp.l.l0
template<typename T> auto TLCS900H::pop(T data) -> void {
auto value = typename T::type();
@@ -1,4 +1,4 @@
#define PC r.pc.l0
#define PC r.pc.l.l0
//called on branches, returns, and interrupts
auto TLCS900H::invalidate() -> void {
+51 -53
View File
@@ -4,34 +4,34 @@
template<> auto TLCS900H::map(Register<n8> register) const -> maybe<n8&> {
switch(register.id) {
#define r(id, name) case id: return r.name;
r(0x00, xwa[0].b0) r(0x01, xwa[0].b1) r(0x02, xwa[0].b2) r(0x03, xwa[0].b3)
r(0x04, xbc[0].b0) r(0x05, xbc[0].b1) r(0x06, xbc[0].b2) r(0x07, xbc[0].b3)
r(0x08, xde[0].b0) r(0x09, xde[0].b1) r(0x0a, xde[0].b2) r(0x0b, xde[0].b3)
r(0x0c, xhl[0].b0) r(0x0d, xhl[0].b1) r(0x0e, xhl[0].b2) r(0x0f, xhl[0].b3)
r(0x10, xwa[1].b0) r(0x11, xwa[1].b1) r(0x12, xwa[1].b2) r(0x13, xwa[1].b3)
r(0x14, xbc[1].b0) r(0x15, xbc[1].b1) r(0x16, xbc[1].b2) r(0x17, xbc[1].b3)
r(0x18, xde[1].b0) r(0x19, xde[1].b1) r(0x1a, xde[1].b2) r(0x1b, xde[1].b3)
r(0x1c, xhl[1].b0) r(0x1d, xhl[1].b1) r(0x1e, xhl[1].b2) r(0x1f, xhl[1].b3)
r(0x20, xwa[2].b0) r(0x21, xwa[2].b1) r(0x22, xwa[2].b2) r(0x23, xwa[2].b3)
r(0x24, xbc[2].b0) r(0x25, xbc[2].b1) r(0x26, xbc[2].b2) r(0x27, xbc[2].b3)
r(0x28, xde[2].b0) r(0x29, xde[2].b1) r(0x2a, xde[2].b2) r(0x2b, xde[2].b3)
r(0x2c, xhl[2].b0) r(0x2d, xhl[2].b1) r(0x2e, xhl[2].b2) r(0x2f, xhl[2].b3)
r(0x30, xwa[3].b0) r(0x31, xwa[3].b1) r(0x32, xwa[3].b2) r(0x33, xwa[3].b3)
r(0x34, xbc[3].b0) r(0x35, xbc[3].b1) r(0x36, xbc[3].b2) r(0x37, xbc[3].b3)
r(0x38, xde[3].b0) r(0x39, xde[3].b1) r(0x3a, xde[3].b2) r(0x3b, xde[3].b3)
r(0x3c, xhl[3].b0) r(0x3d, xhl[3].b1) r(0x3e, xhl[3].b2) r(0x3f, xhl[3].b3)
r(0xd0, xwa[p].b0) r(0xd1, xwa[p].b1) r(0xd2, xwa[p].b2) r(0xd3, xwa[p].b3)
r(0xd4, xbc[p].b0) r(0xd5, xbc[p].b1) r(0xd6, xbc[p].b2) r(0xd7, xbc[p].b3)
r(0xd8, xde[p].b0) r(0xd9, xde[p].b1) r(0xda, xde[p].b2) r(0xdb, xde[p].b3)
r(0xdc, xhl[p].b0) r(0xdd, xhl[p].b1) r(0xde, xhl[p].b2) r(0xdf, xhl[p].b3)
r(0xe0, xwa[a].b0) r(0xe1, xwa[a].b1) r(0xe2, xwa[a].b2) r(0xe3, xwa[a].b3)
r(0xe4, xbc[a].b0) r(0xe5, xbc[a].b1) r(0xe6, xbc[a].b2) r(0xe7, xbc[a].b3)
r(0xe8, xde[a].b0) r(0xe9, xde[a].b1) r(0xea, xde[a].b2) r(0xeb, xde[a].b3)
r(0xec, xhl[a].b0) r(0xed, xhl[a].b1) r(0xee, xhl[a].b2) r(0xef, xhl[a].b3)
r(0xf0, xix .b0) r(0xf1, xix .b1) r(0xf2, xix .b2) r(0xf3, xix .b3)
r(0xf4, xiy .b0) r(0xf5, xiy .b1) r(0xf6, xiy .b2) r(0xf7, xiy .b3)
r(0xf8, xiz .b0) r(0xf9, xiz .b1) r(0xfa, xiz .b2) r(0xfb, xiz .b3)
r(0xfc, xsp .b0) r(0xfd, xsp .b1) r(0xfe, xsp .b2) r(0xff, xsp .b3)
r(0x00, xwa[0].b.b0) r(0x01, xwa[0].b.b1) r(0x02, xwa[0].b.b2) r(0x03, xwa[0].b.b3)
r(0x04, xbc[0].b.b0) r(0x05, xbc[0].b.b1) r(0x06, xbc[0].b.b2) r(0x07, xbc[0].b.b3)
r(0x08, xde[0].b.b0) r(0x09, xde[0].b.b1) r(0x0a, xde[0].b.b2) r(0x0b, xde[0].b.b3)
r(0x0c, xhl[0].b.b0) r(0x0d, xhl[0].b.b1) r(0x0e, xhl[0].b.b2) r(0x0f, xhl[0].b.b3)
r(0x10, xwa[1].b.b0) r(0x11, xwa[1].b.b1) r(0x12, xwa[1].b.b2) r(0x13, xwa[1].b.b3)
r(0x14, xbc[1].b.b0) r(0x15, xbc[1].b.b1) r(0x16, xbc[1].b.b2) r(0x17, xbc[1].b.b3)
r(0x18, xde[1].b.b0) r(0x19, xde[1].b.b1) r(0x1a, xde[1].b.b2) r(0x1b, xde[1].b.b3)
r(0x1c, xhl[1].b.b0) r(0x1d, xhl[1].b.b1) r(0x1e, xhl[1].b.b2) r(0x1f, xhl[1].b.b3)
r(0x20, xwa[2].b.b0) r(0x21, xwa[2].b.b1) r(0x22, xwa[2].b.b2) r(0x23, xwa[2].b.b3)
r(0x24, xbc[2].b.b0) r(0x25, xbc[2].b.b1) r(0x26, xbc[2].b.b2) r(0x27, xbc[2].b.b3)
r(0x28, xde[2].b.b0) r(0x29, xde[2].b.b1) r(0x2a, xde[2].b.b2) r(0x2b, xde[2].b.b3)
r(0x2c, xhl[2].b.b0) r(0x2d, xhl[2].b.b1) r(0x2e, xhl[2].b.b2) r(0x2f, xhl[2].b.b3)
r(0x30, xwa[3].b.b0) r(0x31, xwa[3].b.b1) r(0x32, xwa[3].b.b2) r(0x33, xwa[3].b.b3)
r(0x34, xbc[3].b.b0) r(0x35, xbc[3].b.b1) r(0x36, xbc[3].b.b2) r(0x37, xbc[3].b.b3)
r(0x38, xde[3].b.b0) r(0x39, xde[3].b.b1) r(0x3a, xde[3].b.b2) r(0x3b, xde[3].b.b3)
r(0x3c, xhl[3].b.b0) r(0x3d, xhl[3].b.b1) r(0x3e, xhl[3].b.b2) r(0x3f, xhl[3].b.b3)
r(0xd0, xwa[p].b.b0) r(0xd1, xwa[p].b.b1) r(0xd2, xwa[p].b.b2) r(0xd3, xwa[p].b.b3)
r(0xd4, xbc[p].b.b0) r(0xd5, xbc[p].b.b1) r(0xd6, xbc[p].b.b2) r(0xd7, xbc[p].b.b3)
r(0xd8, xde[p].b.b0) r(0xd9, xde[p].b.b1) r(0xda, xde[p].b.b2) r(0xdb, xde[p].b.b3)
r(0xdc, xhl[p].b.b0) r(0xdd, xhl[p].b.b1) r(0xde, xhl[p].b.b2) r(0xdf, xhl[p].b.b3)
r(0xe0, xwa[a].b.b0) r(0xe1, xwa[a].b.b1) r(0xe2, xwa[a].b.b2) r(0xe3, xwa[a].b.b3)
r(0xe4, xbc[a].b.b0) r(0xe5, xbc[a].b.b1) r(0xe6, xbc[a].b.b2) r(0xe7, xbc[a].b.b3)
r(0xe8, xde[a].b.b0) r(0xe9, xde[a].b.b1) r(0xea, xde[a].b.b2) r(0xeb, xde[a].b.b3)
r(0xec, xhl[a].b.b0) r(0xed, xhl[a].b.b1) r(0xee, xhl[a].b.b2) r(0xef, xhl[a].b.b3)
r(0xf0, xix .b.b0) r(0xf1, xix .b.b1) r(0xf2, xix .b.b2) r(0xf3, xix .b.b3)
r(0xf4, xiy .b.b0) r(0xf5, xiy .b.b1) r(0xf6, xiy .b.b2) r(0xf7, xiy .b.b3)
r(0xf8, xiz .b.b0) r(0xf9, xiz .b.b1) r(0xfa, xiz .b.b2) r(0xfb, xiz .b.b3)
r(0xfc, xsp .b.b0) r(0xfd, xsp .b.b1) r(0xfe, xsp .b.b2) r(0xff, xsp .b.b3)
#undef r
}
return nothing;
@@ -40,20 +40,20 @@ template<> auto TLCS900H::map(Register<n8> register) const -> maybe<n8&> {
template<> auto TLCS900H::map(Register<n16> register) const -> maybe<n16&> {
switch(register.id & ~1) {
#define r(id, name) case id: return r.name;
r(0x00, xwa[0].w0) r(0x02, xwa[0].w1) r(0x04, xbc[0].w0) r(0x06, xbc[0].w1)
r(0x08, xde[0].w0) r(0x0a, xde[0].w1) r(0x0c, xhl[0].w0) r(0x0e, xhl[0].w1)
r(0x10, xwa[1].w0) r(0x12, xwa[1].w1) r(0x14, xbc[1].w0) r(0x16, xbc[1].w1)
r(0x18, xde[1].w0) r(0x1a, xde[1].w1) r(0x1c, xhl[1].w0) r(0x1e, xhl[1].w1)
r(0x20, xwa[2].w0) r(0x22, xwa[2].w1) r(0x24, xbc[2].w0) r(0x26, xbc[2].w1)
r(0x28, xde[2].w0) r(0x2a, xde[2].w1) r(0x2c, xhl[2].w0) r(0x2e, xhl[2].w1)
r(0x30, xwa[3].w0) r(0x32, xwa[3].w1) r(0x34, xbc[3].w0) r(0x36, xbc[3].w1)
r(0x38, xde[3].w0) r(0x3a, xde[3].w1) r(0x3c, xhl[3].w0) r(0x3e, xhl[3].w1)
r(0xd0, xwa[p].w0) r(0xd2, xwa[p].w1) r(0xd4, xbc[p].w0) r(0xd6, xbc[p].w1)
r(0xd8, xde[p].w0) r(0xda, xde[p].w1) r(0xdc, xhl[p].w0) r(0xde, xhl[p].w1)
r(0xe0, xwa[a].w0) r(0xe2, xwa[a].w1) r(0xe4, xbc[a].w0) r(0xe6, xbc[a].w1)
r(0xe8, xde[a].w0) r(0xea, xde[a].w1) r(0xec, xhl[a].w0) r(0xee, xhl[a].w1)
r(0xf0, xix .w0) r(0xf2, xix .w1) r(0xf4, xiy .w0) r(0xf6, xiy .w1)
r(0xf8, xiz .w0) r(0xfa, xiz .w1) r(0xfc, xsp .w0) r(0xfe, xsp .w1)
r(0x00, xwa[0].w.w0) r(0x02, xwa[0].w.w1) r(0x04, xbc[0].w.w0) r(0x06, xbc[0].w.w1)
r(0x08, xde[0].w.w0) r(0x0a, xde[0].w.w1) r(0x0c, xhl[0].w.w0) r(0x0e, xhl[0].w.w1)
r(0x10, xwa[1].w.w0) r(0x12, xwa[1].w.w1) r(0x14, xbc[1].w.w0) r(0x16, xbc[1].w.w1)
r(0x18, xde[1].w.w0) r(0x1a, xde[1].w.w1) r(0x1c, xhl[1].w.w0) r(0x1e, xhl[1].w.w1)
r(0x20, xwa[2].w.w0) r(0x22, xwa[2].w.w1) r(0x24, xbc[2].w.w0) r(0x26, xbc[2].w.w1)
r(0x28, xde[2].w.w0) r(0x2a, xde[2].w.w1) r(0x2c, xhl[2].w.w0) r(0x2e, xhl[2].w.w1)
r(0x30, xwa[3].w.w0) r(0x32, xwa[3].w.w1) r(0x34, xbc[3].w.w0) r(0x36, xbc[3].w.w1)
r(0x38, xde[3].w.w0) r(0x3a, xde[3].w.w1) r(0x3c, xhl[3].w.w0) r(0x3e, xhl[3].w.w1)
r(0xd0, xwa[p].w.w0) r(0xd2, xwa[p].w.w1) r(0xd4, xbc[p].w.w0) r(0xd6, xbc[p].w.w1)
r(0xd8, xde[p].w.w0) r(0xda, xde[p].w.w1) r(0xdc, xhl[p].w.w0) r(0xde, xhl[p].w.w1)
r(0xe0, xwa[a].w.w0) r(0xe2, xwa[a].w.w1) r(0xe4, xbc[a].w.w0) r(0xe6, xbc[a].w.w1)
r(0xe8, xde[a].w.w0) r(0xea, xde[a].w.w1) r(0xec, xhl[a].w.w0) r(0xee, xhl[a].w.w1)
r(0xf0, xix .w.w0) r(0xf2, xix .w.w1) r(0xf4, xiy .w.w0) r(0xf6, xiy .w.w1)
r(0xf8, xiz .w.w0) r(0xfa, xiz .w.w1) r(0xfc, xsp .w.w0) r(0xfe, xsp .w.w1)
#undef r
}
return nothing;
@@ -62,13 +62,13 @@ template<> auto TLCS900H::map(Register<n16> register) const -> maybe<n16&> {
template<> auto TLCS900H::map(Register<n32> register) const -> maybe<n32&> {
switch(register.id & ~3) {
#define r(id, name) case id: return r.name;
r(0x00, xwa[0].l0) r(0x04, xbc[0].l0) r(0x08, xde[0].l0) r(0x0c, xhl[0].l0)
r(0x10, xwa[1].l0) r(0x14, xbc[1].l0) r(0x18, xde[1].l0) r(0x1c, xhl[1].l0)
r(0x20, xwa[2].l0) r(0x24, xbc[2].l0) r(0x28, xde[2].l0) r(0x2c, xhl[2].l0)
r(0x30, xwa[3].l0) r(0x34, xbc[3].l0) r(0x38, xde[3].l0) r(0x3c, xhl[3].l0)
r(0xd0, xwa[p].l0) r(0xd4, xbc[p].l0) r(0xd8, xde[p].l0) r(0xdc, xhl[p].l0)
r(0xe0, xwa[a].l0) r(0xe4, xbc[a].l0) r(0xe8, xde[a].l0) r(0xec, xhl[a].l0)
r(0xf0, xix .l0) r(0xf4, xiy .l0) r(0xf8, xiz .l0) r(0xfc, xsp .l0)
r(0x00, xwa[0].l.l0) r(0x04, xbc[0].l.l0) r(0x08, xde[0].l.l0) r(0x0c, xhl[0].l.l0)
r(0x10, xwa[1].l.l0) r(0x14, xbc[1].l.l0) r(0x18, xde[1].l.l0) r(0x1c, xhl[1].l.l0)
r(0x20, xwa[2].l.l0) r(0x24, xbc[2].l.l0) r(0x28, xde[2].l.l0) r(0x2c, xhl[2].l.l0)
r(0x30, xwa[3].l.l0) r(0x34, xbc[3].l.l0) r(0x38, xde[3].l.l0) r(0x3c, xhl[3].l.l0)
r(0xd0, xwa[p].l.l0) r(0xd4, xbc[p].l.l0) r(0xd8, xde[p].l.l0) r(0xdc, xhl[p].l.l0)
r(0xe0, xwa[a].l.l0) r(0xe4, xbc[a].l.l0) r(0xe8, xde[a].l.l0) r(0xec, xhl[a].l.l0)
r(0xf0, xix .l.l0) r(0xf4, xiy .l.l0) r(0xf8, xiz .l.l0) r(0xfc, xsp .l.l0)
#undef r
}
return nothing;
@@ -87,11 +87,9 @@ template<> auto TLCS900H::store<n32>(Register<n32> register, n32 data) -> void {
auto TLCS900H::expand(Register<n8 > register) const -> Register<n16> { return {register.id & ~1}; }
auto TLCS900H::expand(Register<n16> register) const -> Register<n32> { return {register.id & ~3}; }
auto TLCS900H::expand(Register<n32> register) const -> Register<n32> { return {register.id & ~3}; } //unused
auto TLCS900H::shrink(Register<n32> register) const -> Register<n16> { return {register.id}; }
auto TLCS900H::shrink(Register<n16> register) const -> Register<n8 > { return {register.id}; }
auto TLCS900H::shrink(Register<n8 > register) const -> Register<n8 > { return {register.id}; } //unused
auto TLCS900H::load(FlagRegister f) const -> n8 {
//TLCS-90: d3 = X (expansion carry flag); TLCS-900/H: always 0
@@ -123,10 +121,10 @@ auto TLCS900H::store(StatusRegister, n16 data) -> void {
}
auto TLCS900H::load(ProgramCounter) const -> n32 {
return r.pc.l0;
return r.pc.l.l0;
}
auto TLCS900H::store(ProgramCounter, n32 data) -> void {
r.pc.l0 = data;
r.pc.l.l0 = data;
invalidate();
}
@@ -1,22 +1,22 @@
auto TLCS900H::serialize(serializer& s) -> void {
for(u32 n : range(4)) {
s(r.xwa[n].l0);
s(r.xbc[n].l0);
s(r.xde[n].l0);
s(r.xhl[n].l0);
s(r.xwa[n].l.l0);
s(r.xbc[n].l.l0);
s(r.xde[n].l.l0);
s(r.xhl[n].l.l0);
}
s(r.xix.l0);
s(r.xiy.l0);
s(r.xiz.l0);
s(r.xsp.l0);
s(r.pc.l0);
s(r.xix.l.l0);
s(r.xiy.l.l0);
s(r.xiz.l.l0);
s(r.xsp.l.l0);
s(r.pc.l.l0);
for(u32 n : range(4)) {
s(r.dmas[n].l0);
s(r.dmad[n].l0);
s(r.dmam[n].l0);
s(r.dmas[n].l.l0);
s(r.dmad[n].l.l0);
s(r.dmam[n].l.l0);
}
s(r.intnest.l0);
s(r.intnest.l.l0);
s(CF);
s(NF);
@@ -45,10 +45,10 @@ struct TLCS900H {
template<typename T> auto store(Register<T>, n32) -> void;
auto expand(Register<n8 >) const -> Register<n16>;
auto expand(Register<n16>) const -> Register<n32>;
auto expand(Register<n32>) const -> Register<n32>; //unused
auto expand(Register<n32>) const -> Register<n32> = delete; //unused
auto shrink(Register<n32>) const -> Register<n16>;
auto shrink(Register<n16>) const -> Register<n8 >;
auto shrink(Register<n8 >) const -> Register<n8 >; //unused
auto shrink(Register<n8 >) const -> Register<n8 > = delete; //unused
auto load(FlagRegister) const -> n8;
auto store(FlagRegister, n8) -> void;
auto load(StatusRegister) const -> n16;
@@ -183,10 +183,10 @@ struct TLCS900H {
auto serialize(serializer&) -> void;
union DataRegister {
DataRegister() { l0 = 0; }
struct { n32 order_lsb1(l0); };
struct { n16 order_lsb2(w0, w1); };
struct { n8 order_lsb4(b0, b1, b2, b3); };
DataRegister() { l.l0 = 0; }
struct { n32 order_lsb1(l0); } l;
struct { n16 order_lsb2(w0, w1); } w;
struct { n8 order_lsb4(b0, b1, b2, b3); } b;
};
struct Registers {
+1 -6
View File
@@ -1,12 +1,7 @@
auto Z80::instruction() -> void {
EI = 0;
P = 0;
if(EI) {
EI = 0;
IFF1 = 1;
IFF2 = 1;
}
if(HALT) {
return wait(1);
}
@@ -217,7 +217,9 @@ auto Z80::instructionDJNZ_e() -> void { Q = 0;
}
auto Z80::instructionEI() -> void { Q = 0;
EI = 1; //raise IFF1, IFF2 after the next instruction
IFF1 = 1;
IFF2 = 1;
EI = 1; //ignore maskable interrupts until after the next instruction
}
auto Z80::instructionEX_irr_rr(n16& x, n16& y) -> void { Q = 0;
+2 -2
View File
@@ -35,8 +35,8 @@ auto Z80::power(MOSFET mosfet) -> void {
}
auto Z80::irq(bool maskable, n16 pc, n8 extbus) -> bool {
if(EI) return false; //do not execute interrupts immediately after EI instruction
if(maskable && !IFF1) return false;
//do not execute maskable interrupts if disabled or immediately after EI instruction
if(maskable && (!IFF1 || EI)) return false;
R.bit(0,6)++;
push(PC);
+18 -1
View File
@@ -71,7 +71,24 @@ auto TMS9918::Background::graphics2(n8 hoffset, n8 voffset) -> void {
}
auto TMS9918::Background::multicolor(n8 hoffset, n8 voffset) -> void {
debug(unimplemented, "[TMS9918::Background::multicolor]");
n14 nameAddress;
nameAddress.bit( 0, 4) = hoffset.bit(3,7);
nameAddress.bit( 5, 9) = voffset.bit(3,7);
nameAddress.bit(10,13) = io.nameTableAddress;
n8 pattern = self.vram.read(nameAddress);
n14 patternAddress;
patternAddress.bit( 0, 2) = voffset.bit(2,4);
patternAddress.bit( 3,10) = pattern;
patternAddress.bit(11,13) = io.patternTableAddress;
n8 color = self.vram.read(patternAddress);
if(hoffset.bit(2)) {
output.color = color.bit(0,3);
} else {
output.color = color.bit(4,7);
}
}
auto TMS9918::Background::power() -> void {
+2 -2
View File
@@ -11,7 +11,7 @@ auto TMS9918::status() -> n8 {
sprite.io.collision = 0;
sprite.io.overflow = 0;
irqFrame.pending = 0;
irq(0);
poll();
return data;
}
@@ -56,7 +56,7 @@ auto TMS9918::register(n3 register, n8 data) -> void {
irqFrame.enable = data.bit(5);
dac.io.displayEnable = data.bit(6);
io.vramMode = data.bit(7);
if(!irqFrame.enable) irqFrame.pending = 0;
poll();
break;
case 2:
+4 -4
View File
@@ -6,10 +6,11 @@ auto TMS9918::Sprite::setup(n8 voffset) -> void {
n14 attributeAddress;
attributeAddress.bit(7,13) = io.attributeTableAddress;
for(u32 index : range(32)) {
n8 y = self.vram.read(attributeAddress++);
i9 y = self.vram.read(attributeAddress++);
if(y == 0xd0) break;
if(y >= 0xe0) y -= 0x100;
n8 x = self.vram.read(attributeAddress++);
i9 x = self.vram.read(attributeAddress++);
n8 pattern = self.vram.read(attributeAddress++);
n8 extra = self.vram.read(attributeAddress++);
@@ -34,8 +35,7 @@ auto TMS9918::Sprite::run(n8 hoffset, n8 voffset) -> void {
output = {};
n4 color;
n4 hlimit = (8 << io.zoom) - 1;
n5 vlimit = (8 << io.zoom << io.size) - 1;
n5 hlimit = (8 << io.zoom << io.size) - 1, vlimit = hlimit;
for(auto& o : objects) {
if(o.y == 0xd0) continue;
+6 -2
View File
@@ -36,14 +36,18 @@ auto TMS9918::main() -> void {
io.vcounter++;
if(io.vcounter == 262) io.vcounter = 0;
if(io.vcounter == 0) irqFrame.pending = 0;
if(io.vcounter == 192) irqFrame.pending = 1, irq(irqFrame.enable), frame();
if(io.vcounter == 192) irqFrame.pending = 1, poll(), frame();
}
auto TMS9918::poll() -> void {
irq(irqFrame.pending && irqFrame.enable);
}
auto TMS9918::power() -> void {
background.power();
sprite.power();
dac.power();
irqFrame = {};
io = {};
}
+4 -3
View File
@@ -21,6 +21,7 @@ struct TMS9918 {
auto unload() -> void;
auto main() -> void;
auto poll() -> void;
auto power() -> void;
//io.cpp
@@ -73,8 +74,8 @@ protected:
auto serialize(serializer&) -> void;
struct Object {
n8 x;
n8 y = 0xd0;
i9 x;
i9 y = 0xd0;
n8 pattern;
n4 color;
} objects[4];
@@ -124,7 +125,7 @@ protected:
} irqFrame;
struct IO {
n8 vcounter;
n9 vcounter;
n8 hcounter;
n1 controlLatch;
+8 -8
View File
@@ -11,10 +11,11 @@ auto V9938::Sprite::setup(n8 voffset) -> void {
n14 address = io.nameTableAddress & 0x03f80;
for(u32 index : range(32)) {
n8 y = self.vram.read(address++);
i9 y = self.vram.read(address++);
if(y == 0xd0) break;
if(y >= 0xe0) y -= 0x100;
n8 x = self.vram.read(address++);
i9 x = self.vram.read(address++);
n8 pattern = self.vram.read(address++);
n8 attributes = self.vram.read(address++);
@@ -48,10 +49,11 @@ auto V9938::Sprite::setup(n8 voffset) -> void {
n17 address = io.nameTableAddress & 0x1fe00;
for(u32 index : range(32)) {
n8 y = self.vram.read(address++);
i9 y = self.vram.read(address++);
if(y == 0xd8) break;
if(y >= 0xe0) y -= 0x100;
n8 x = self.vram.read(address++);
i9 x = self.vram.read(address++);
n8 pattern = self.vram.read(address++);
n8 reserved = self.vram.read(address++);
@@ -101,8 +103,7 @@ auto V9938::Sprite::run(n8 x, n8 y) -> void {
auto V9938::Sprite::sprite1(n8 hoffset, n8 voffset) -> void {
n4 color;
n4 hlimit = (8 << io.zoom) - 1;
n5 vlimit = (8 << io.zoom << io.size) - 1;
n5 hlimit = (8 << io.zoom << io.size) - 1, vlimit = hlimit;
for(auto& o : objects) {
if(o.y == 0xd0) break;
@@ -126,8 +127,7 @@ auto V9938::Sprite::sprite1(n8 hoffset, n8 voffset) -> void {
auto V9938::Sprite::sprite2(n8 hoffset, n8 voffset) -> void {
n4 color;
n4 hlimit = (8 << io.zoom) - 1;
n5 vlimit = (8 << io.zoom << io.size) - 1;
n5 hlimit = (8 << io.zoom << io.size) - 1, vlimit = hlimit;
for(auto& o : objects) {
if(o.y == 0xd8) break;
+2 -2
View File
@@ -125,8 +125,8 @@ protected:
auto serialize(serializer&) -> void;
struct Object {
n8 x;
n8 y = 0xd0;
i9 x;
i9 y = 0xd0;
n8 pattern;
n4 color;
n1 collision;
+5
View File
@@ -38,4 +38,9 @@ auto Cartridge::save() -> void {
auto Cartridge::power() -> void {
}
auto Cartridge::read(n16 address) -> n8 {
if(address >= rom.size()) return 0xff;
return rom.read(address);
}
}
+3 -1
View File
@@ -13,10 +13,12 @@ struct Cartridge {
auto save() -> void;
auto power() -> void;
auto read(n16 address) -> n8;
//serialization.cpp
auto serialize(serializer&) -> void;
//private:
private:
struct Information {
string title;
string region;
+1 -1
View File
@@ -53,7 +53,7 @@ auto Gamepad::read() -> n8 {
xHold = 1, swap(leftLatch, rightLatch);
}
n8 data = 0xff;
n8 data = 0x7f;
if(select == 0) {
if(one->value ()) data.bit(0,3) = 0b1101;
else if(two->value ()) data.bit(0,3) = 0b0111;
+4 -2
View File
@@ -24,8 +24,8 @@ auto CPU::unload() -> void {
}
auto CPU::main() -> void {
if(state.nmiLine) {
state.nmiLine = 0; //edge-sensitive
if(state.nmiPending) {
state.nmiPending = 0; //edge-sensitive
debugger.interrupt("NMI");
irq(0, 0x0066, 0xff);
}
@@ -46,6 +46,7 @@ auto CPU::step(uint clocks) -> void {
}
auto CPU::setNMI(bool value) -> void {
if(!state.nmiLine && value) state.nmiPending = 1;
state.nmiLine = value;
}
@@ -61,6 +62,7 @@ auto CPU::power() -> void {
PC = 0x0000; //reset vector address
state = {};
io = {};
ram.fill(0);
}
}
+1
View File
@@ -46,6 +46,7 @@ struct CPU : Z80, Z80::Bus, Thread {
private:
struct State {
bool nmiPending = 0;
bool nmiLine = 0;
bool irqLine = 0;
} state;
+1 -1
View File
@@ -4,7 +4,7 @@ auto CPU::read(n16 address) -> n8 {
if(address >= 0x2000 && address <= 0x7fff && io.replaceRAM ) return expansion.read(address);
if(address >= 0x0000 && address <= 0x1fff) return system.bios[address & 0x1fff];
if(address >= 0x6000 && address <= 0x7fff) return ram.read(address - 0x6000);
if(address >= 0x8000 && address <= 0xffff) return cartridge.rom.read(address - 0x8000);
if(address >= 0x8000 && address <= 0xffff) return cartridge.read(address - 0x8000);
return data;
}
+1
View File
@@ -3,6 +3,7 @@ auto CPU::serialize(serializer& s) -> void {
Thread::serialize(s);
s(ram);
s(expansion);
s(state.nmiPending);
s(state.nmiLine);
s(state.irqLine);
s(io.replaceBIOS);
+2 -1
View File
@@ -7,6 +7,8 @@ VDP vdp;
#include "serialization.cpp"
auto VDP::load(Node::Object parent) -> void {
vram.allocate(16_KiB, 0x00);
node = parent->append<Node::Object>("VDP");
screen = node->append<Node::Video::Screen>("Screen", 256, 192);
@@ -45,7 +47,6 @@ auto VDP::power() -> void {
TMS9918::power();
Thread::create(system.colorburst() * 2, [&] { main(); });
screen->power();
vram.allocate(0x4000);
}
}
+2
View File
@@ -2,6 +2,7 @@ namespace Board {
#include "bandai-fcg.cpp"
#include "jaleco-jf.cpp"
#include "jaleco-jf11-jf14.cpp"
#include "konami-vrc1.cpp"
#include "konami-vrc2.cpp"
#include "konami-vrc3.cpp"
@@ -49,6 +50,7 @@ auto Interface::create(string board) -> Interface* {
if(!p) p = HVC_UxROM::create(board);
if(!p) p = IremTAMS1::create(board);
if(!p) p = JalecoJF::create(board);
if(!p) p = Jaleco_JF11_JF14::create(board);
if(!p) p = KonamiVRC1::create(board);
if(!p) p = KonamiVRC2::create(board);
if(!p) p = KonamiVRC3::create(board);
@@ -0,0 +1,56 @@
struct Jaleco_JF11_JF14 : Interface {
static auto create(string id) -> Interface* {
if(id == "JALECO-JF11-JF14") return new Jaleco_JF11_JF14;
return nullptr;
}
Memory::Readable<n8> programROM;
Memory::Readable<n8> characterROM;
auto load() -> void override {
Interface::load(programROM, "program.rom");
Interface::load(characterROM, "character.rom");
mirror = pak->attribute("mirror") == "vertical";
}
auto readPRG(n32 address, n8 data) -> n8 override {
if(address < 0x8000) return data;
return programROM.read(programBank << 15 | (n15)address);
}
auto writePRG(n32 address, n8 data) -> void override {
if(address < 0x6000 || address > 0x7fff) return;
characterBank = data.bit(0,1);
programBank = data.bit(4,5);
}
auto readCHR(n32 address, n8 data) -> n8 override {
if(address & 0x2000) {
address = address >> !mirror & 0x0400 | (n10)address;
return ppu.readCIRAM(address);
}
address = characterBank << 13 | (n13)address;
if(characterROM) return characterROM.read(address);
return data;
}
auto writeCHR(n32 address, n8 data) -> void override {
if(address & 0x2000) {
address = address >> !mirror & 0x0400 | (n10)address;
return ppu.writeCIRAM(address, data);
}
}
auto power() -> void override {
}
auto serialize(serializer& s) -> void override {
s(mirror);
s(programBank);
s(characterBank);
}
n1 mirror; //0 = horizontal, 1 = vertical
n2 programBank;
n2 characterBank;
};
+1 -1
View File
@@ -21,7 +21,7 @@ auto CPU::write(n16 address, n8 data) -> void {
}
auto CPU::lastCycle() -> void {
io.interruptPending = ((io.irqLine | io.apuLine) & ~P.i) | io.nmiPending;
io.interruptPending = ((io.irqLine | io.apuLine) & !P.i) | io.nmiPending;
}
auto CPU::nmi(n16& vector) -> void {
+2 -1
View File
@@ -56,6 +56,7 @@ struct CPU : SM83, Thread {
auto stop() -> void override;
auto halt() -> void override;
auto idle() -> void override;
auto haltBugTrigger() -> void override;
auto read(n16 address) -> n8 override;
auto write(n16 address, n8 data) -> void override;
auto readDMA(n16 address, n8 data) -> n8;
@@ -73,7 +74,7 @@ struct CPU : SM83, Thread {
auto timer1024hz() -> void;
auto hblank() -> void;
auto hblankTrigger() -> void;
struct Status {
n22 clock;
n8 interruptLatch;
+3 -4
View File
@@ -49,8 +49,7 @@ auto CPU::readIO(u32 cycle, n16 address, n8 data) -> n8 {
}
if(address == 0xff01 && cycle == 2) { //SB
//unemulated
return 0x00;
return status.serialData;
}
if(address == 0xff02 && cycle == 2) { //SC
@@ -97,8 +96,8 @@ auto CPU::readIO(u32 cycle, n16 address, n8 data) -> n8 {
if(Model::GameBoyColor())
if(address == 0xff55 && cycle == 2) { //HDMA5
data.bit(0,6) = status.dmaLength;
data.bit(7) = status.hdmaActive;
data.bit(0,6) = status.dmaLength;
data.bit(7) = !status.hdmaActive;
return data;
}
+9
View File
@@ -7,11 +7,20 @@ auto CPU::stop() -> void {
auto CPU::halt() -> void {
idle();
if(status.interruptLatch) r.halt = 0;
if(Model::SuperGameBoy()) {
scheduler.exit(Event::Step);
}
}
auto CPU::haltBugTrigger() -> void {
// halt bug is triggered when IME is off, and IE & IF != 0
// does not properly emulate two halts in a rom
if(!r.ime && status.interruptLatch != 0) {
r.haltBug = 1;
}
}
auto CPU::idle() -> void {
if(r.ei) r.ei = 0, r.ime = 1;
step();
+2
View File
@@ -54,6 +54,8 @@ auto CPU::timer16384hz() -> void {
auto CPU::timer8192hz() -> void {
if(status.serialTransfer && status.serialClock) {
status.serialData <<= 1;
status.serialData |= 1;
if(--status.serialBits == 0) {
status.serialTransfer = 0;
raise(Interrupt::Serial);
+1 -1
View File
@@ -109,13 +109,13 @@ auto PPU::runBackgroundCGB() -> void {
auto PPU::runWindowCGB() -> void {
if(status.ly < status.wy) return;
if(px + 7 < status.wx) return;
if(px + 7 == status.wx) latch.wy++;
n8 scrollY = latch.wy - 1;
n8 scrollX = px + 7 - latch.wx;
n3 tileX = scrollX & 7;
if(scrollX >= 160u) return; //also matches underflow (scrollX < 0)
if(tileX == 0 || px == 0) readTileCGB(status.windowTilemapSelect, scrollX, scrollY, window.tiledata, window.attributes);
n2 index;
+5 -7
View File
@@ -51,11 +51,7 @@ auto PPU::scanlineDMG() -> void {
}
//sort by X-coordinate
for(u32 lo = 0; lo < sprites; lo++) {
for(u32 hi = lo + 1; hi < sprites; hi++) {
if(sprite[hi].x < sprite[lo].x) swap(sprite[lo], sprite[hi]);
}
}
sort(sprite, sprites, [](auto l, auto r) { return l.x < r.x; });
}
auto PPU::runDMG() -> void {
@@ -79,7 +75,8 @@ auto PPU::runDMG() -> void {
if(Model::GameBoy()) {
auto output = screen->pixels().data() + status.ly * 160 + px++;
*output = color;
//LCD is still blank during the first frame
if(!latch.displayEnable) *output = color;
}
if(Model::SuperGameBoy()) {
superGameBoy->ppuWrite(color);
@@ -103,13 +100,14 @@ auto PPU::runBackgroundDMG() -> void {
auto PPU::runWindowDMG() -> void {
if(status.ly < status.wy) return;
if(px + 7 < status.wx) return;
if(px + 7 == status.wx) latch.wy++;
if(!status.bgEnable) return;
n8 scrollY = latch.wy - 1;
n8 scrollX = px + 7 - latch.wx;
n3 tileX = scrollX & 7;
if(scrollX >= 160u) return; //also matches underflow (scrollX < 0)
if(tileX == 0 || px == 0) readTileDMG(status.windowTilemapSelect, scrollX, scrollY, window.tiledata);
n2 index;
+1 -6
View File
@@ -48,7 +48,7 @@ auto PPU::readIO(u32 cycle, n16 address, n8 data) -> n8 {
}
if(address == 0xff44 && cycle == 2) { //LY
return status.ly;
return getLY();
}
if(address == 0xff45 && cycle == 2) { //LYC
@@ -190,11 +190,6 @@ auto PPU::writeIO(u32 cycle, n16 address, n8 data) -> void {
return;
}
if(address == 0xff44 && cycle == 2) { //LY
status.ly = 0;
return;
}
if(address == 0xff45 && cycle == 2) { //LYC
status.lyc = data;
return;
+7 -10
View File
@@ -97,8 +97,7 @@ auto PPU::main() -> void {
latch.wy = 0;
}
if(latch.displayEnable) {
latch.displayEnable = 0;
if(latch.displayEnable && status.ly == 0) {
mode(0);
step(72);
@@ -136,6 +135,8 @@ auto PPU::main() -> void {
cpu.raise(CPU::Interrupt::VerticalBlank);
if(screen) screen->frame();
scheduler.exit(Event::Frame);
latch.displayEnable = 0;
}
if(status.ly == 154) {
@@ -156,22 +157,18 @@ auto PPU::mode(n2 mode) -> void {
}
auto PPU::stat() -> void {
if(!status.displayEnable) return;
bool irq = status.irq;
status.irq = status.interruptHblank && status.mode == 0;
status.irq |= status.interruptVblank && status.mode == 1;
status.irq |= status.interruptOAM && status.mode == 2;
status.irq |= status.interruptLYC && coincidence();
status.irq |= status.interruptOAM && triggerOAM();
status.irq |= status.interruptLYC && compareLYC();
if(!irq && status.irq) cpu.raise(CPU::Interrupt::Stat);
}
auto PPU::coincidence() -> bool {
u32 ly = status.ly;
if(ly == 153 && status.lx >= 92) ly = 0; //LYC=0 triggers early during LY=153
return ly == status.lyc;
}
auto PPU::step(u32 clocks) -> void {
while(clocks--) {
history.mode = history.mode << 2 | status.mode;
+2 -1
View File
@@ -32,7 +32,6 @@ struct PPU : Thread {
auto main() -> void;
auto mode(n2 mode) -> void;
auto stat() -> void;
auto coincidence() -> bool;
auto step(u32 clocks) -> void;
auto hflip(n16 tiledata) const -> n16;
@@ -43,6 +42,8 @@ struct PPU : Thread {
auto canAccessVRAM() const -> bool;
auto canAccessOAM() const -> bool;
auto compareLYC() const -> bool;
auto getLY() const -> n8;
auto triggerOAM() const -> bool;
//io.cpp
auto vramAddress(n13 address) const -> n16;
+37
View File
@@ -38,3 +38,40 @@ auto PPU::compareLYC() const -> bool {
return lyc == ly;
}
auto PPU::getLY() const -> n8 {
auto ly = status.ly;
if(Model::GameBoy() || Model::SuperGameBoy()) {
auto lx = status.lx >> 2;
if(ly == 153 && lx >= 1) return 0;
}
if(Model::GameBoyColor() && cpu.lowSpeed()) {
auto lx = status.lx >> 2;
if(ly != 153 && lx >= 113) {
static const n3 pattern[8] = {0, 0, 2, 0, 4, 4, 6, 0};
if(ly.bit(0,3) != 0xf) {
ly.bit(0,2) = pattern[ly.bit(0,2)];
} else {
ly.bit(0,3) = 0;
ly.bit(4,6) = pattern[ly.bit(4,6)];
}
return ly;
}
if(ly == 153 && lx >= 1) return 0;
}
if(Model::GameBoyColor() && cpu.highSpeed()) {
auto lx = status.lx >> 1;
if(ly == 153 && lx >= 6) return 0;
}
return ly;
}
auto PPU::triggerOAM() const -> bool {
if(status.mode != 2) return 0;
auto lx = status.lx >> (cpu.status.speedDouble ? 1 : 2);
return lx == (status.ly == 0 ? 1 : 0);
}
+6 -2
View File
@@ -135,8 +135,12 @@ auto System::power(bool reset) -> void {
if(fastBoot->latch()) {
if(name == "boot.dmg-1.rom") {
bootROM.program(0x64, 0x18);
bootROM.program(0x65, 0x7a);
//skip the first 0x60 loop iterations (~4 seconds) and disable scrolling
bootROM.program(0x55, 0x26); //ld h,$60 ; loop upcount = 0x60
bootROM.program(0x56, 0x60);
bootROM.program(0x57, 0x16); //ld d,$04 ; loop downcount = 0x04
bootROM.program(0x58, 0x04);
bootROM.program(0x88, 0x00); //nop ; disable scroll
}
//todo: add fast boot patches for other boot ROMs
}
+100
View File
@@ -1,20 +1,98 @@
struct Banked : Interface {
using Interface::Interface;
Memory::Readable<n16> rom;
Memory::Writable<n16> wram;
Memory::Writable<n8 > uram;
Memory::Writable<n8 > lram;
M24C m24c;
auto load() -> void override {
Interface::load(rom, "program.rom");
if(auto fp = pak->read("save.ram")) {
Interface::load(wram, uram, lram, "save.ram");
}
if(auto fp = pak->read("save.eeprom")) {
Interface::load(m24c, "save.eeprom");
rsda = fp->attribute("rsda").natural();
wsda = fp->attribute("wsda").natural();
wscl = fp->attribute("wscl").natural();
}
}
auto save() -> void override {
if(auto fp = pak->write("save.ram")) {
Interface::save(wram, uram, lram, "save.ram");
}
if(auto fp = pak->write("save.eeprom")) {
Interface::save(m24c, "save.eeprom");
}
}
auto read(n1 upper, n1 lower, n22 address, n16 data) -> n16 override {
if(address >= 0x200000) {
if(wram && ramEnable) {
return wram[address >> 1];
}
if(uram && ramEnable) {
return uram[address >> 1] * 0x0101;
}
if(lram && ramEnable) {
return lram[address >> 1] * 0x0101;
}
if(m24c && eepromEnable) {
if(upper && rsda >> 3 == 1) data.bit(rsda) = m24c.read();
if(lower && rsda >> 3 == 0) data.bit(rsda) = m24c.read();
return data;
}
}
n25 offset = romBank[address >> 19] << 19 | (n19)address;
if ((offset >> 1) > rom.size() - 1) {
return 0xffff;
}
return data = rom[offset >> 1];
}
auto write(n1 upper, n1 lower, n22 address, n16 data) -> void override {
//emulating ramWritable will break commercial software:
//it does not appear that many (any?) games actually connect $a130f1.d1 to /WE;
//hence RAM ends up always being writable, and many games fail to set d1=1
if(address >= 0x200000) {
if(wram && ramEnable) {
if(upper) wram[address >> 1].byte(1) = data.byte(1);
if(lower) wram[address >> 1].byte(0) = data.byte(0);
return;
}
if(uram && ramEnable) {
if(upper) uram[address >> 1] = data;
return;
}
if(lram && ramEnable) {
if(lower) lram[address >> 1] = data;
return;
}
if(m24c) {
if(rom.size() * 2 > 0x200000 && upper && lower) {
eepromEnable = !data.bit(0);
return;
}
if(eepromEnable) {
if(upper && wscl >> 3 == 1) m24c.clock = data.bit(wscl);
if(upper && wsda >> 3 == 1) m24c.data = data.bit(wsda);
if(lower && wscl >> 3 == 0) m24c.clock = data.bit(wscl);
if(lower && wsda >> 3 == 0) m24c.data = data.bit(wsda);
return m24c.write();
}
}
}
}
auto readIO(n1 upper, n1 lower, n24 address, n16 data) -> n16 override {
@@ -27,6 +105,12 @@ struct Banked : Interface {
debug(unusual, "[Cartridge::Banked::writeIO] lower=0");
return;
}
if(address == 0xa130f0) {
ramEnable = data.bit(0);
ramWritable = data.bit(1);
}
if(address == 0xa130f2) romBank[1] = data.bit(0,5);
if(address == 0xa130f4) romBank[2] = data.bit(0,5);
if(address == 0xa130f6) romBank[3] = data.bit(0,5);
@@ -42,7 +126,23 @@ struct Banked : Interface {
auto serialize(serializer& s) -> void override {
s(romBank);
s(wram);
s(uram);
s(lram);
s(m24c);
s(ramEnable);
s(ramWritable);
s(eepromEnable);
s(rsda);
s(wsda);
s(wscl);
}
n6 romBank[8];
n1 ramEnable;
n1 ramWritable;
n1 eepromEnable;
n4 rsda;
n4 wsda;
n4 wscl;
};
-1
View File
@@ -3,7 +3,6 @@ namespace Board {
#include "linear.cpp"
#include "banked.cpp"
#include "svp.cpp"
#include "lock-on.cpp"
#include "j-cart.cpp"
#include "game-genie.cpp"
#include "mega-32x.cpp"
+4
View File
@@ -49,6 +49,10 @@ struct Linear : Interface {
}
}
if ((address >> 1) > rom.size() - 1) {
return 0xffff;
}
return rom[address >> 1];
}
-49
View File
@@ -1,49 +0,0 @@
struct LockOn : Interface {
using Interface::Interface;
Memory::Readable<n16> rom;
Memory::Readable<n16> patch;
CartridgeSlot slot{"Cartridge Slot"};
auto load() -> void override {
Interface::load(rom, "program.rom");
Interface::load(patch, "patch.rom");
slot.load(cartridge->node);
}
auto save() -> void override {
}
auto read(n1 upper, n1 lower, n22 address, n16 data) -> n16 override {
if(address < 0x200000) return data = rom[address >> 1];
if(address >= 0x300000 && patchEnable) return data = patch[address >> 1];
if(slot.connected()) return data = slot.cartridge.read(upper, lower, address, data);
return data;
}
auto write(n1 upper, n1 lower, n22 address, n16 data) -> void override {
if(slot.connected()) slot.cartridge.write(upper, lower, address, data);
}
auto readIO(n1 upper, n1 lower, n24 address, n16 data) -> n16 override {
if(slot.connected()) slot.cartridge.readIO(upper, lower, address, data);
return data;
}
auto writeIO(n1 upper, n1 lower, n24 address, n16 data) -> void override {
if(slot.connected()) slot.cartridge.writeIO(upper, lower, address, data);
if(!lower) return; //todo: unconfirmed
if(address == 0xa130f0) patchEnable = data.bit(0);
}
auto power(bool reset) -> void override {
if(slot.connected()) slot.cartridge.power(reset);
patchEnable = 1;
}
auto serialize(serializer& s) -> void override {
if(slot.connected()) s(slot.cartridge);
s(patchEnable);
}
n1 patchEnable;
};
-2
View File
@@ -23,8 +23,6 @@ auto Cartridge::connect() -> void {
board = new Board::Mega32X{*this};
} else if(pak->read("svp.rom")) {
board = new Board::SVP(*this);
} else if(pak->read("patch.rom")) {
board = new Board::LockOn(*this);
} else if(pak->attribute("label") == "Game Genie") {
board = new Board::GameGenie(*this);
} else if(pak->read("program.rom") && pak->read("program.rom")->size() > 0x400000) {
+5 -1
View File
@@ -64,6 +64,7 @@ auto CPU::step(u32 clocks) -> void {
while(refresh.ram >= 133) refresh.ram -= 133;
refresh.external += clocks;
Thread::step(clocks);
cyclesUntilSync -= clocks;
}
inline auto CPU::idle(u32 clocks) -> void {
@@ -72,7 +73,10 @@ inline auto CPU::idle(u32 clocks) -> void {
auto CPU::wait(u32 clocks) -> void {
step(clocks);
Thread::synchronize();
if (cyclesUntilSync <= 0) {
Thread::synchronize();
cyclesUntilSync += minCyclesBetweenSyncs;
}
}
auto CPU::raise(Interrupt interrupt) -> void {
+3
View File
@@ -69,6 +69,9 @@ struct CPU : M68000, Thread {
struct State {
n32 interruptPending;
} state;
int cyclesUntilSync = 0;
int minCyclesBetweenSyncs = 0;
};
extern CPU cpu;
+4 -2
View File
@@ -20,12 +20,12 @@ auto M32X::readExternal(n1 upper, n1 lower, n24 address, n16 data) -> n16 {
}
if(address >= 0x880000 && address <= 0x8fffff) {
return rom[address >> 1 & 0x3ffff];
if(!dreq.vram) return rom[address >> 1 & 0x3ffff];
}
if(address >= 0x900000 && address <= 0x9fffff) {
address = io.romBank * 0x100000 | address & 0x0fffff;
return rom[address >> 1];
if(!dreq.vram) return rom[address >> 1];
}
return data;
@@ -47,6 +47,7 @@ auto M32X::writeExternal(n1 upper, n1 lower, n24 address, n16 data) -> void {
}
if(address >= 0x840000 && address <= 0x85ffff) {
if (vdp.framebufferAccess) return;
if(!data && (!upper || !lower)) return; //8-bit 0x00 writes do not go through
shm.debugger.tracer.instruction->invalidate(0x0400'0000 | address & 0x1fffe);
shs.debugger.tracer.instruction->invalidate(0x0400'0000 | address & 0x1fffe);
@@ -56,6 +57,7 @@ auto M32X::writeExternal(n1 upper, n1 lower, n24 address, n16 data) -> void {
}
if(address >= 0x860000 && address <= 0x87ffff) {
if (vdp.framebufferAccess) return;
shm.debugger.tracer.instruction->invalidate(0x0402'0000 | address & 0x1fffe);
shs.debugger.tracer.instruction->invalidate(0x0402'0000 | address & 0x1fffe);
if(upper && data.byte(1)) vdp.bbram[address >> 1 & 0xffff].byte(1) = data.byte(1);
+8
View File
@@ -9,6 +9,12 @@ auto M32X::readInternal(n1 upper, n1 lower, n32 address, n16 data) -> n16 {
}
if(address >= 0x0200'0000 && address <= 0x023f'ffff) {
while(dreq.vram) {
// SH2 ROM accesses stall while RV is set
if(shm.active()) shm.step(1);
if(shs.active()) shs.step(1);
}
return rom[address >> 1];
}
@@ -29,6 +35,7 @@ auto M32X::writeInternal(n1 upper, n1 lower, n32 address, n16 data) -> void {
}
if(address >= 0x0400'0000 && address <= 0x0401'ffff) {
if (!vdp.framebufferAccess) return;
if(!data && (!upper || !lower)) return; //8-bit 0x00 writes do not go through
if(upper) vdp.bbram[address >> 1 & 0xffff].byte(1) = data.byte(1);
if(lower) vdp.bbram[address >> 1 & 0xffff].byte(0) = data.byte(0);
@@ -36,6 +43,7 @@ auto M32X::writeInternal(n1 upper, n1 lower, n32 address, n16 data) -> void {
}
if(address >= 0x0402'0000 && address <= 0x0403'ffff) {
if (!vdp.framebufferAccess) return;
if(upper && data.byte(1)) vdp.bbram[address >> 1 & 0xffff].byte(1) = data.byte(1);
if(lower && data.byte(0)) vdp.bbram[address >> 1 & 0xffff].byte(0) = data.byte(0);
return;
+7
View File
@@ -273,6 +273,7 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//bitmap mode
if(address == 0xa15180) {
if (vdp.framebufferAccess) return;
if(lower) {
vdp.mode = data.bit(0,1);
vdp.lines = data.bit(6);
@@ -282,6 +283,7 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//packed pixel control
if(address == 0xa15182) {
if (vdp.framebufferAccess) return;
if(lower) {
vdp.dotshift = data.bit(0);
}
@@ -289,6 +291,7 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//autofill length
if(address == 0xa15184) {
if (vdp.framebufferAccess) return;
if(lower) {
vdp.autofillLength = data.byte(0);
}
@@ -296,12 +299,14 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//autofill address
if(address == 0xa15186) {
if (vdp.framebufferAccess) return;
if(upper) vdp.autofillAddress.byte(1) = data.byte(1);
if(lower) vdp.autofillAddress.byte(0) = data.byte(0);
}
//autofill data
if(address == 0xa15188) {
if (vdp.framebufferAccess) return;
if(upper) vdp.autofillData.byte(1) = data.byte(1);
if(lower) vdp.autofillData.byte(0) = data.byte(0);
vdp.fill();
@@ -309,6 +314,7 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//frame buffer control
if(address == 0xa1518a) {
if (vdp.framebufferAccess) return;
if(lower) {
vdp.selectFramebuffer(data.bit(0));
}
@@ -316,6 +322,7 @@ auto M32X::writeExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> void {
//palette
if(address >= 0xa15200 && address <= 0xa153ff) {
if (vdp.framebufferAccess) return;
if(upper) vdp.cram[address >> 1 & 0xff].byte(1) = data.byte(1);
if(lower) vdp.cram[address >> 1 & 0xff].byte(0) = data.byte(0);
}
+8 -1
View File
@@ -111,7 +111,7 @@ auto M32X::readInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> n16 {
}
//packed pixel control
if(address == 0x4102) {
if(address == 0x4102) {
data.bit(0) = vdp.dotshift;
}
@@ -257,6 +257,7 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//bitmap mode
if(address == 0x4100) {
if (!vdp.framebufferAccess) return;
if(lower) {
vdp.mode = data.bit(0,1);
vdp.lines = data.bit(6);
@@ -266,6 +267,7 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//packed pixel control
if(address == 0x4102) {
if (!vdp.framebufferAccess) return;
if(lower) {
vdp.dotshift = data.bit(0);
}
@@ -273,6 +275,7 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//autofill length
if(address == 0x4104) {
if (!vdp.framebufferAccess) return;
if(lower) {
vdp.autofillLength = data.byte(0);
}
@@ -280,12 +283,14 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//autofill address
if(address == 0x4106) {
if (!vdp.framebufferAccess) return;
if(upper) vdp.autofillAddress.byte(1) = data.byte(1);
if(lower) vdp.autofillAddress.byte(0) = data.byte(0);
}
//autofill data
if(address == 0x4108) {
if (!vdp.framebufferAccess) return;
if(upper) vdp.autofillData.byte(1) = data.byte(1);
if(lower) vdp.autofillData.byte(0) = data.byte(0);
vdp.fill();
@@ -293,6 +298,7 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//frame buffer control
if(address == 0x410a) {
if (!vdp.framebufferAccess) return;
if(lower) {
vdp.selectFramebuffer(data.bit(0));
}
@@ -300,6 +306,7 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void {
//palette
if(address >= 0x4200 && address <= 0x43ff) {
if (!vdp.framebufferAccess) return;
if(upper) vdp.cram[address >> 1 & 0xff].byte(1) = data.byte(1);
if(lower) vdp.cram[address >> 1 & 0xff].byte(0) = data.byte(0);
}
Loaded 100 of 694 files, more files were not shown because too many files have changed in this diff. Show more