mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2026-11-07 17:23:57 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
700ae61114 | ||
|
|
1c2216f1ac | ||
|
|
b2aacd0b19 | ||
|
|
d1a51d54bb | ||
|
|
d71c46c8f9 | ||
|
|
9109ea8de7 | ||
|
|
faf59aa52d | ||
|
|
7da24be26a | ||
|
|
4e273908a1 | ||
|
|
6d2c3a811c | ||
|
|
d44655c995 | ||
|
|
feb8c10c67 | ||
|
|
f1b9189375 | ||
|
|
68f681c199 | ||
|
|
972b451da1 | ||
|
|
490abb0942 | ||
|
|
d6a8e6a52c | ||
|
|
41fe3ece28 | ||
|
|
c8cd54dff1 | ||
|
|
028c060501 | ||
|
|
c52f7281a1 | ||
|
|
74d752eaf6 | ||
|
|
b57f775f9c | ||
|
|
c6e90ddcdf | ||
|
|
44e666f45b | ||
|
|
729872dd14 | ||
|
|
76a43f1464 | ||
|
|
8e0d886dea | ||
|
|
c779f8fbfa | ||
|
|
63dd0e17a3 | ||
|
|
39851534ea | ||
|
|
1b1c8b4f02 | ||
|
|
4e572a3cfa | ||
|
|
90ba6ac523 | ||
|
|
a4800add4a | ||
|
|
efee3d7535 | ||
|
|
eb48683f51 | ||
|
|
ba04d6df0d | ||
|
|
aea144ee00 | ||
|
|
cd8c26b076 | ||
|
|
922788f480 | ||
|
|
77a74a0c6b | ||
|
|
738da88175 | ||
|
|
263e94f93d | ||
|
|
9689bb8089 | ||
|
|
2be71ddc55 | ||
|
|
b759d14817 | ||
|
|
47df059481 | ||
|
|
b18beba724 | ||
|
|
1f4af3e541 | ||
|
|
4ae502f926 | ||
|
|
60efa1cf23 | ||
|
|
95350550af | ||
|
|
1ce0a5f337 | ||
|
|
518314a3f6 | ||
|
|
363df53e02 | ||
|
|
a80dc42515 | ||
|
|
79c0576d2c | ||
|
|
fcc7244dcf | ||
|
|
06c866ce2a | ||
|
|
05f0750b16 | ||
|
|
4eed6c5d2a | ||
|
|
879383ee1f | ||
|
|
a9204c52ef | ||
|
|
da026a5bb2 | ||
|
|
5b802d8b35 | ||
|
|
cf394a6574 | ||
|
|
fd803c5982 | ||
|
|
76ead2d796 | ||
|
|
e808994e57 | ||
|
|
6938b44422 | ||
|
|
3bb89b0e48 | ||
|
|
768052042d | ||
|
|
171ba5b64b | ||
|
|
c9dee938eb | ||
|
|
d56e07d807 | ||
|
|
09788668cd | ||
|
|
3656daec8f | ||
|
|
026fc306b2 | ||
|
|
efe3706545 | ||
|
|
bbcbb17c55 | ||
|
|
75081d5a26 | ||
|
|
fb3587bcf5 | ||
|
|
d652dde406 | ||
|
|
4c99c5a1ee | ||
|
|
7fbb4f0ff3 | ||
|
|
f50648a812 | ||
|
|
4dff4f5379 | ||
|
|
0beb3990e7 | ||
|
|
0b6b32108d | ||
|
|
365c5c1575 | ||
|
|
df18e30ff7 | ||
|
|
2f5bd293ea | ||
|
|
8abfedf413 | ||
|
|
17cbfb1520 | ||
|
|
2b5a7b60b1 | ||
|
|
42e51ad1ac | ||
|
|
afaf2194e2 | ||
|
|
3a9883ec0b | ||
|
|
29cfdd74a6 | ||
|
|
a839eabecf | ||
|
|
8e4fe16433 | ||
|
|
fca291202c | ||
|
|
5367783d35 | ||
|
|
4143119b7a | ||
|
|
8a5ce253c3 | ||
|
|
a39e8e14a4 | ||
|
|
66157802ca | ||
|
|
983de15a5b | ||
|
|
f8bd7b7eba | ||
|
|
df07ca5806 | ||
|
|
6e091948cb | ||
|
|
29f29c9c98 | ||
|
|
60398479ee | ||
|
|
9a18ef0125 | ||
|
|
11f869fd2c | ||
|
|
ee95143b5b | ||
|
|
964fd0cd64 | ||
|
|
9de523037d | ||
|
|
3da72f4979 | ||
|
|
1f9f61a0a2 | ||
|
|
9a073a9e7f | ||
|
|
33c43dc71c | ||
|
|
24431808bd | ||
|
|
b7ade41dd6 | ||
|
|
e647f9de33 | ||
|
|
0328317b61 | ||
|
|
8d6cfcc0f0 | ||
|
|
dcf7a46a89 | ||
|
|
91c76760c8 | ||
|
|
6cb0016dd9 | ||
|
|
279661b167 | ||
|
|
02e37425bc | ||
|
|
a1a4038044 | ||
|
|
9deea5d967 | ||
|
|
ea8f9c22d5 | ||
|
|
17ea1f8d0c | ||
|
|
f497ecf30b | ||
|
|
313c13f8cc | ||
|
|
ede0415209 | ||
|
|
de330f6f1f | ||
|
|
c53d18ba35 | ||
|
|
fcbe97809f | ||
|
|
5065e945f6 | ||
|
|
c4e3116ec1 | ||
|
|
3fbb1984d0 | ||
|
|
a1b0aec93e | ||
|
|
ed4d48593c | ||
|
|
a08825d185 | ||
|
|
baa8f286dd | ||
|
|
5f5347677a | ||
|
|
b542a68255 | ||
|
|
f223d0d043 | ||
|
|
4a98250c9b | ||
|
|
ce221d9041 | ||
|
|
772a847375 | ||
|
|
134416de46 | ||
|
|
969e5dc992 | ||
|
|
dc6eeec8af | ||
|
|
42e0dc0401 | ||
|
|
38f985a219 | ||
|
|
9fad49b7ef | ||
|
|
5105b47344 | ||
|
|
a4c2eb0eec | ||
|
|
ca80196640 | ||
|
|
ef6a479298 | ||
|
|
f74ab3cfa2 | ||
|
|
d263585173 | ||
|
|
55f73099fe | ||
|
|
4e475b570b | ||
|
|
8eda341b34 | ||
|
|
033e25b1ba | ||
|
|
4eefbe1a47 | ||
|
|
d589a345b4 | ||
|
|
2395e17d00 | ||
|
|
8ed47ed257 | ||
|
|
7f569d7cfa | ||
|
|
ec7ad2ef13 | ||
|
|
e853e2cc73 | ||
|
|
c121ca2440 | ||
|
|
2b89497415 | ||
|
|
a4ecfe381e | ||
|
|
6e43cb0af4 | ||
|
|
e3ffd31f2a | ||
|
|
fe8bd6b954 | ||
|
|
e6e5bf42b8 | ||
|
|
3d1e4f6571 | ||
|
|
9443880510 | ||
|
|
7a72d4a8f6 | ||
|
|
2932266ea5 | ||
|
|
7133e7555e | ||
|
|
c1bf743ec5 | ||
|
|
92319962eb | ||
|
|
f5fead7e83 | ||
|
|
9439901bc7 | ||
|
|
1e753a1eff | ||
|
|
60852799e7 | ||
|
|
4bad334837 | ||
|
|
95e5d7cc31 | ||
|
|
93020ea9b6 | ||
|
|
01c3656049 | ||
|
|
aeacff8bd1 | ||
|
|
dafaf76d83 | ||
|
|
1174053297 | ||
|
|
34eb76a601 | ||
|
|
401745b1c7 | ||
|
|
1ffc11be4c | ||
|
|
f69dff1199 | ||
|
|
8d23c43291 | ||
|
|
65e486adbd | ||
|
|
72ae8083fc | ||
|
|
0ce9aba25f | ||
|
|
d7b53f386b | ||
|
|
4f0c6639f7 | ||
|
|
a91d930b26 | ||
|
|
122afaab5a | ||
|
|
bf2bc81c4d | ||
|
|
888fed1076 | ||
|
|
f0e827d056 | ||
|
|
310048e018 | ||
|
|
9ff11a71f9 | ||
|
|
bf55b6512c | ||
|
|
88d4c2dd0b | ||
|
|
308a7d4af7 | ||
|
|
9c94d48f51 | ||
|
|
f4b8d2acf5 |
No files matched your search
+6
-1
@@ -1 +1,6 @@
|
||||
ananke/libananke.so
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
*.o
|
||||
/target-libretro/libs
|
||||
/target-libretro/obj
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
|
||||
|
||||
##############################################################################
|
||||
################################# BOILERPLATE ################################
|
||||
##############################################################################
|
||||
|
||||
# Core definitions
|
||||
.core-defs:
|
||||
variables:
|
||||
JNI_PATH: target-libretro
|
||||
CORENAME: bsnes2014_performance
|
||||
PROFILE: performance
|
||||
|
||||
.core-defs-balanced:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORENAME: bsnes2014_balanced
|
||||
PROFILE: balanced
|
||||
|
||||
.core-defs-accuracy:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORENAME: bsnes2014_accuracy
|
||||
PROFILE: accuracy
|
||||
|
||||
# Inclusion templates, required for the build to work
|
||||
include:
|
||||
################################## DESKTOPS ################################
|
||||
# Windows 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-x64-mingw.yml'
|
||||
|
||||
# Windows 32-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-i686-mingw.yml'
|
||||
|
||||
# Linux 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-x64.yml'
|
||||
|
||||
# Linux 32-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-i686.yml'
|
||||
|
||||
# MacOS 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/osx-x64.yml'
|
||||
|
||||
# MacOS ARM 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/osx-arm64.yml'
|
||||
|
||||
################################## CELLULAR ################################
|
||||
# Android
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/android-jni.yml'
|
||||
|
||||
# iOS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios-arm64.yml'
|
||||
|
||||
# iOS (armv7)
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios9.yml'
|
||||
|
||||
################################## CONSOLES ################################
|
||||
|
||||
# tvOS (AppleTV)
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/tvos-arm64.yml'
|
||||
|
||||
#################################### MISC ##################################
|
||||
|
||||
# Stages for building
|
||||
stages:
|
||||
- build-prepare
|
||||
- build-shared
|
||||
- build-static
|
||||
|
||||
###########################
|
||||
## bsnes2014_performance ##
|
||||
###########################
|
||||
|
||||
# Desktop
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64:
|
||||
extends:
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs
|
||||
|
||||
# Linux 32-bit
|
||||
libretro-build-linux-i686:
|
||||
extends:
|
||||
- .libretro-linux-i686-make-default
|
||||
- .core-defs
|
||||
|
||||
# Windows 64-bit
|
||||
libretro-build-windows-x64:
|
||||
extends:
|
||||
- .libretro-windows-x64-mingw-make-default
|
||||
- .core-defs
|
||||
|
||||
# Windows 32-bit
|
||||
libretro-build-windows-i686:
|
||||
extends:
|
||||
- .libretro-windows-i686-mingw-make-default
|
||||
- .core-defs
|
||||
|
||||
# Android
|
||||
android-armeabi-v7a:
|
||||
extends:
|
||||
- .libretro-android-jni-armeabi-v7a
|
||||
- .core-defs
|
||||
|
||||
android-arm64-v8a:
|
||||
extends:
|
||||
- .libretro-android-jni-arm64-v8a
|
||||
- .core-defs
|
||||
|
||||
android-x86_64:
|
||||
extends:
|
||||
- .libretro-android-jni-x86_64
|
||||
- .core-defs
|
||||
|
||||
android-x86:
|
||||
extends:
|
||||
- .libretro-android-jni-x86
|
||||
- .core-defs
|
||||
|
||||
########################
|
||||
## bsnes2014_balanced ##
|
||||
########################
|
||||
|
||||
# Desktop
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64-balanced:
|
||||
extends:
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs-balanced
|
||||
|
||||
# Linux 32-bit
|
||||
libretro-build-linux-i686-balanced:
|
||||
extends:
|
||||
- .libretro-linux-i686-make-default
|
||||
- .core-defs-balanced
|
||||
|
||||
# Windows 64-bit
|
||||
libretro-build-windows-x64-balanced:
|
||||
extends:
|
||||
- .libretro-windows-x64-mingw-make-default
|
||||
- .core-defs-balanced
|
||||
|
||||
# Windows 32-bit
|
||||
libretro-build-windows-i686-balanced:
|
||||
extends:
|
||||
- .libretro-windows-i686-mingw-make-default
|
||||
- .core-defs-balanced
|
||||
|
||||
# Android
|
||||
android-armeabi-v7a-balanced:
|
||||
extends:
|
||||
- .libretro-android-jni-armeabi-v7a
|
||||
- .core-defs-balanced
|
||||
|
||||
android-arm64-v8a-balanced:
|
||||
extends:
|
||||
- .libretro-android-jni-arm64-v8a
|
||||
- .core-defs-balanced
|
||||
|
||||
android-x86_64-balanced:
|
||||
extends:
|
||||
- .libretro-android-jni-x86_64
|
||||
- .core-defs-balanced
|
||||
|
||||
android-x86-balanced:
|
||||
extends:
|
||||
- .libretro-android-jni-x86
|
||||
- .core-defs-balanced
|
||||
|
||||
########################
|
||||
## bsnes2014_accuracy ##
|
||||
########################
|
||||
|
||||
# Desktop
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64-accuracy:
|
||||
extends:
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs-accuracy
|
||||
|
||||
# Linux 32-bit
|
||||
libretro-build-linux-i686-accuracy:
|
||||
extends:
|
||||
- .libretro-linux-i686-make-default
|
||||
- .core-defs-accuracy
|
||||
|
||||
# Windows 64-bit
|
||||
libretro-build-windows-x64-accuracy:
|
||||
extends:
|
||||
- .libretro-windows-x64-mingw-make-default
|
||||
- .core-defs-accuracy
|
||||
|
||||
# Windows 32-bit
|
||||
libretro-build-windows-i686-accuracy:
|
||||
extends:
|
||||
- .libretro-windows-i686-mingw-make-default
|
||||
- .core-defs-accuracy
|
||||
|
||||
# Android
|
||||
android-armeabi-v7a-accuracy:
|
||||
extends:
|
||||
- .libretro-android-jni-armeabi-v7a
|
||||
- .core-defs-accuracy
|
||||
|
||||
android-arm64-v8a-accuracy:
|
||||
extends:
|
||||
- .libretro-android-jni-arm64-v8a
|
||||
- .core-defs-accuracy
|
||||
|
||||
android-x86_64-accuracy:
|
||||
extends:
|
||||
- .libretro-android-jni-x86_64
|
||||
- .core-defs-accuracy
|
||||
|
||||
android-x86-accuracy:
|
||||
extends:
|
||||
- .libretro-android-jni-x86
|
||||
- .core-defs-accuracy
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
language: generic
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
env:
|
||||
global:
|
||||
- CORE=bsnes
|
||||
- COMPILER_NAME=gcc CXX=g++-7 CC=gcc-7 CXX11=g++-7
|
||||
matrix:
|
||||
- PLATFORM=linux_x64 NAME=bsnes_accuracy
|
||||
- PLATFORM=linux_x64 NAME=bsnes_balanced
|
||||
- PLATFORM=linux_x64 NAME=bsnes_performance
|
||||
before_script:
|
||||
- pwd
|
||||
- mkdir -p ~/bin
|
||||
- ln -s /usr/bin/gcc-7 ~/bin/gcc
|
||||
- ln -s /usr/bin/g++-7 ~/bin/g++
|
||||
- ln -s /usr/bin/cpp-7 ~/bin/cpp
|
||||
- export PATH=~/bin:$PATH
|
||||
- ls -l ~/bin
|
||||
- echo $PATH
|
||||
- g++-7 --version
|
||||
- g++ --version
|
||||
script:
|
||||
- cd ~/
|
||||
- git clone --depth=50 https://github.com/libretro/libretro-super
|
||||
- cd libretro-super/travis
|
||||
- ./build.sh
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. {http://fsf.org/}
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
Badnik Copyright (C) 2013 Adrien Plazas
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
{http://www.gnu.org/licenses/}.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
{http://www.gnu.org/philosophy/why-not-lgpl.html}.
|
||||
@@ -1,109 +1,549 @@
|
||||
include nall/Makefile
|
||||
DEBUG = 0
|
||||
FRONTEND_SUPPORTS_RGB565 = 1
|
||||
PROFILE ?= performance
|
||||
|
||||
fc := fc
|
||||
sfc := sfc
|
||||
gb := gb
|
||||
gba := gba
|
||||
CORE_DIR := .
|
||||
CFLAGS :=
|
||||
CXXFLAGS :=
|
||||
|
||||
profile := accuracy
|
||||
target := ethos
|
||||
SPACE :=
|
||||
SPACE := $(SPACE) $(SPACE)
|
||||
BACKSLASH :=
|
||||
BACKSLASH := \$(BACKSLASH)
|
||||
filter_out1 = $(filter-out $(firstword $1),$1)
|
||||
filter_out2 = $(call filter_out1,$(call filter_out1,$1))
|
||||
|
||||
# options += debugger
|
||||
# arch := x86
|
||||
# console := true
|
||||
ifeq ($(platform),)
|
||||
platform = unix
|
||||
ifeq ($(shell uname -s),)
|
||||
platform = win
|
||||
else ifneq ($(findstring MINGW,$(shell uname -s)),)
|
||||
platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -s)),)
|
||||
platform = osx
|
||||
else ifneq ($(findstring win,$(shell uname -s)),)
|
||||
platform = win
|
||||
endif
|
||||
endif
|
||||
|
||||
# compiler
|
||||
flags += -I. -O3 -fomit-frame-pointer
|
||||
link +=
|
||||
objects := libco
|
||||
# system platform
|
||||
system_platform = unix
|
||||
ifeq ($(shell uname -s),)
|
||||
EXE_EXT = .exe
|
||||
system_platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -s)),)
|
||||
system_platform = osx
|
||||
arch = intel
|
||||
ifeq ($(shell uname -p),powerpc)
|
||||
arch = ppc
|
||||
endif
|
||||
ifeq ($(shell uname -p),arm)
|
||||
arch = arm
|
||||
endif
|
||||
else ifneq ($(findstring MINGW,$(shell uname -s)),)
|
||||
system_platform = win
|
||||
endif
|
||||
|
||||
# profile-guided optimization mode
|
||||
# pgo := instrument
|
||||
# pgo := optimize
|
||||
|
||||
ifeq ($(pgo),instrument)
|
||||
flags += -fprofile-generate
|
||||
link += -lgcov
|
||||
else ifeq ($(pgo),optimize)
|
||||
flags += -fprofile-use
|
||||
ifeq ($(PGO),instrument)
|
||||
CFLAGS += -fprofile-generate
|
||||
CXXFLAGS += -fprofile-generate
|
||||
LDFLAGS += -lgcov
|
||||
else ifeq ($(PGO),optimize)
|
||||
CFLAGS += -fprofile-use
|
||||
CXXFLAGS += -fprofile-use
|
||||
endif
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),windows)
|
||||
ifeq ($(arch),x86)
|
||||
flags += -m32
|
||||
link += -m32
|
||||
endif
|
||||
ifeq ($(console),true)
|
||||
link += -mconsole
|
||||
else
|
||||
link += -mwindows
|
||||
endif
|
||||
link += -s -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 -lws2_32
|
||||
link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
else ifeq ($(platform),macosx)
|
||||
flags += -march=native
|
||||
else ifeq ($(platform),linux)
|
||||
flags += -march=native
|
||||
link += -s -Wl,-export-dynamic -lX11 -lXext -ldl
|
||||
else ifeq ($(platform),bsd)
|
||||
flags += -march=native
|
||||
link += -s -Wl,-export-dynamic -lX11 -lXext
|
||||
CORE_DEFINE :=
|
||||
|
||||
TARGET_NAME := bsnes2014
|
||||
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
|
||||
ifneq ($(GIT_VERSION)," unknown")
|
||||
CXXFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||
endif
|
||||
|
||||
ifeq ($(PROFILE), performance)
|
||||
TARGET_NAME = bsnes2014_performance
|
||||
else ifeq ($(PROFILE), balanced)
|
||||
TARGET_NAME = bsnes2014_balanced
|
||||
else ifeq ($(PROFILE), accuracy)
|
||||
TARGET_NAME = bsnes2014_accuracy
|
||||
endif
|
||||
|
||||
ifeq ($(platform), unix)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T
|
||||
ifneq ($(shell uname -p | grep -E '((i.|x)86|amd64)'),)
|
||||
IS_X86 = 1
|
||||
endif
|
||||
ifneq ($(findstring Haiku,$(shell uname -s)),)
|
||||
CXXFLAGS += -fpermissive
|
||||
endif
|
||||
LDFLAGS += -ldl
|
||||
else ifeq ($(platform), osx)
|
||||
TARGET := $(TARGET_NAME)_libretro.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
MINVERSION :=
|
||||
ifeq ($(arch),ppc)
|
||||
ENDIANNESS_DEFINES := -DMSB_FIRST
|
||||
OLD_GCC := 1
|
||||
endif
|
||||
OSXVER = `sw_vers -productVersion | cut -d. -f 2`
|
||||
OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"`
|
||||
fpic += -mmacosx-version-min=10.1
|
||||
FLAGS += -DHAVE_POSIX_MEMALIGN
|
||||
ifeq ($(OSX_LT_MAVERICKS),YES)
|
||||
MINVERSION = -mmacosx-version-min=10.1
|
||||
endif
|
||||
FLAGS += $(MINVERSION)
|
||||
|
||||
ifeq ($(CROSS_COMPILE),1)
|
||||
TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT)
|
||||
CFLAGS += $(TARGET_RULE)
|
||||
CPPFLAGS += $(TARGET_RULE)
|
||||
CXXFLAGS += $(TARGET_RULE)
|
||||
LDFLAGS += $(TARGET_RULE)
|
||||
endif
|
||||
|
||||
CFLAGS += $(ARCHFLAGS)
|
||||
CXXFLAGS += $(ARCHFLAGS)
|
||||
LDFLAGS += $(ARCHFLAGS)
|
||||
|
||||
# iOS
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
|
||||
TARGET := $(TARGET_NAME)_libretro_ios.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
MINVERSION :=
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
|
||||
endif
|
||||
|
||||
ifeq ($(platform),ios-arm64)
|
||||
CC = cc -arch arm64 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
|
||||
else
|
||||
$(error unsupported platform.)
|
||||
CC = cc -arch armv7 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch armv7 -isysroot $(IOSSDK)
|
||||
endif
|
||||
IPHONEMINVER :=
|
||||
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
|
||||
MINVERSION = -miphoneos-version-min=8.0
|
||||
else
|
||||
MINVERSION = -miphoneos-version-min=5.0
|
||||
endif
|
||||
LDFLAGS += $(MINVERSION)
|
||||
FLAGS += $(MINVERSION)
|
||||
FLAGS += -DHAVE_POSIX_MEMALIGN
|
||||
|
||||
# tvOS
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
|
||||
endif
|
||||
|
||||
ui := target-$(target)
|
||||
CC = cc -arch arm64 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
|
||||
FLAGS += -DHAVE_POSIX_MEMALIGN
|
||||
|
||||
# implicit rules
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(compiler) $(cflags) $(flags) $1 -c $< -o $@, \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(compiler) $(cppflags) $(flags) $1 -c $< -o $@ \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
else ifeq ($(platform), qnx)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).so
|
||||
fpic := -fPIC
|
||||
SHARED := -lcpp -lm -shared -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T
|
||||
CC = qcc -Vgcc_ntoarmv7le
|
||||
CXX = QCC -Vgcc_ntoarmv7le_cpp
|
||||
AR = QCC -Vgcc_ntoarmv7le
|
||||
FLAGS += -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
|
||||
else ifeq ($(platform), ps3)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
|
||||
AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
|
||||
ENDIANNESS_DEFINES := -DMSB_FIRST
|
||||
OLD_GCC := 1
|
||||
FLAGS += -DARCH_POWERPC_ALTIVEC
|
||||
STATIC_LINKING = 1
|
||||
else ifeq ($(platform), sncps3)
|
||||
TARGET := $(TARGET_NAME)_libretro_ps3.a
|
||||
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
|
||||
ENDIANNESS_DEFINES := -DMSB_FIRST
|
||||
CXXFLAGS += -Xc+=exceptions
|
||||
OLD_GCC := 1
|
||||
NO_GCC := 1
|
||||
FLAGS += -DARCH_POWERPC_ALTIVEC
|
||||
STATIC_LINKING = 1
|
||||
else ifeq ($(platform), psl1ght)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT)
|
||||
CXX = $(PS3DEV)/ppu/bin/ppu-g++$(EXE_EXT)
|
||||
AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT)
|
||||
ENDIANNESS_DEFINES := -DMSB_FIRST
|
||||
STATIC_LINKING = 1
|
||||
|
||||
%.o: $<; $(call compile)
|
||||
# PSP
|
||||
else ifeq ($(platform), psp1)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = psp-gcc$(EXE_EXT)
|
||||
CXX = psp-g++$(EXE_EXT)
|
||||
AR = psp-ar$(EXE_EXT)
|
||||
FLAGS += -DPSP -G0
|
||||
STATIC_LINKING = 1
|
||||
EXTRA_INCLUDES := -I$(shell psp-config --pspsdk-path)/include
|
||||
|
||||
all: build;
|
||||
# Vita
|
||||
else ifeq ($(platform), vita)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = arm-vita-eabi-gcc$(EXE_EXT)
|
||||
CXX = arm-vita-eabi-g++$(EXE_EXT)
|
||||
AR = arm-vita-eabi-ar$(EXE_EXT)
|
||||
FLAGS += -DVITA
|
||||
STATIC_LINKING = 1
|
||||
|
||||
obj/libco.o: libco/libco.c libco/*
|
||||
# Xbox 360
|
||||
else ifeq ($(platform), xenon)
|
||||
TARGET := $(TARGET_NAME)_libretro_xenon360.a
|
||||
CC = xenon-gcc$(EXE_EXT)
|
||||
CXX = xenon-g++$(EXE_EXT)
|
||||
AR = xenon-ar$(EXE_EXT)
|
||||
ENDIANNESS_DEFINES += -D__LIBXENON__ -m32 -D__ppc__ -DMSB_FIRST
|
||||
LIBS :=
|
||||
STATIC_LINKING = 1
|
||||
|
||||
include $(ui)/Makefile
|
||||
flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o)
|
||||
# Nintendo Switch (libnx)
|
||||
else ifeq ($(platform), libnx)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL
|
||||
CFLAGS += $(DEFINES) -fPIE -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec -Wl,--allow-multiple-definition -specs=$(LIBNX)/switch.specs
|
||||
CFLAGS += $(INCDIRS)
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX
|
||||
CXXFLAGS += $(ASFLAGS) $(CFLAGS) -fexceptions -fno-rtti -std=gnu++11
|
||||
CFLAGS += -std=gnu11
|
||||
STATIC_LINKING = 1
|
||||
|
||||
# Nintendo Gamecube
|
||||
else ifeq ($(platform), ngc)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
|
||||
ENDIANNESS_DEFINES += -DGEKKO -DHW_DOL -mrvl -mcpu=750 -meabi -mhard-float -DMSB_FIRST
|
||||
FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
|
||||
|
||||
EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include
|
||||
STATIC_LINKING = 1
|
||||
|
||||
# wii
|
||||
else ifeq ($(platform), wii)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
|
||||
ENDIANNESS_DEFINES += -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float -DMSB_FIRST
|
||||
FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
|
||||
|
||||
EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include
|
||||
STATIC_LINKING = 1
|
||||
|
||||
# wiiu
|
||||
else ifeq ($(platform), wiiu)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
|
||||
ENDIANNESS_DEFINES += -DGEKKO -DWIIU -DHW_RVL -mwup -mcpu=750 -meabi -mhard-float -DMSB_FIRST
|
||||
FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
|
||||
|
||||
EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include
|
||||
STATIC_LINKING = 1
|
||||
|
||||
else ifneq (,$(findstring armv,$(platform)))
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T
|
||||
CC = gcc
|
||||
IS_X86 = 0
|
||||
ifneq (,$(findstring cortexa8,$(platform)))
|
||||
FLAGS += -marm -mcpu=cortex-a8
|
||||
ASFLAGS += -mcpu=cortex-a8
|
||||
else ifneq (,$(findstring cortexa9,$(platform)))
|
||||
FLAGS += -marm -mcpu=cortex-a9
|
||||
ASFLAGS += -mcpu=cortex-a9
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring neon,$(platform)))
|
||||
FLAGS += -mfpu=neon
|
||||
ASFLAGS += -mfpu=neon
|
||||
HAVE_NEON = 1
|
||||
endif
|
||||
ifneq (,$(findstring softfloat,$(platform)))
|
||||
FLAGS += -mfloat-abi=softfp
|
||||
else ifneq (,$(findstring hardfloat,$(platform)))
|
||||
FLAGS += -mfloat-abi=hard
|
||||
endif
|
||||
FLAGS += -DARM
|
||||
|
||||
# Windows MSVC 2017 all architectures
|
||||
else ifneq (,$(findstring windows_msvc2017,$(platform)))
|
||||
|
||||
NO_GCC := 1
|
||||
CFLAGS += -DNOMINMAX
|
||||
CXXFLAGS += -DNOMINMAX
|
||||
WINDOWS_VERSION = 1
|
||||
|
||||
PlatformSuffix = $(subst windows_msvc2017_,,$(platform))
|
||||
ifneq (,$(findstring desktop,$(PlatformSuffix)))
|
||||
WinPartition = desktop
|
||||
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -FS
|
||||
LDFLAGS += -MANIFEST -LTCG:incremental -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1
|
||||
LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
|
||||
else ifneq (,$(findstring uwp,$(PlatformSuffix)))
|
||||
WinPartition = uwp
|
||||
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WINDLL -D_UNICODE -DUNICODE -D__WRL_NO_DEFAULT_LIB__ -EHsc -FS
|
||||
LDFLAGS += -APPCONTAINER -NXCOMPAT -DYNAMICBASE -MANIFEST:NO -LTCG -OPT:REF -SUBSYSTEM:CONSOLE -MANIFESTUAC:NO -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 -DEBUG:FULL -WINMD:NO
|
||||
LIBS += WindowsApp.lib
|
||||
endif
|
||||
|
||||
CFLAGS += $(MSVC2017CompileFlags)
|
||||
CXXFLAGS += $(MSVC2017CompileFlags)
|
||||
|
||||
TargetArchMoniker = $(subst $(WinPartition)_,,$(PlatformSuffix))
|
||||
|
||||
CC = cl.exe
|
||||
CXX = cl.exe
|
||||
LD = link.exe
|
||||
|
||||
reg_query = $(call filter_out2,$(subst $2,,$(shell reg query "$2" -v "$1" 2>nul)))
|
||||
fix_path = $(subst $(SPACE),\ ,$(subst \,/,$1))
|
||||
|
||||
ProgramFiles86w := $(shell cmd //c "echo %PROGRAMFILES(x86)%")
|
||||
ProgramFiles86 := $(shell cygpath "$(ProgramFiles86w)")
|
||||
|
||||
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0)
|
||||
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0)
|
||||
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0)
|
||||
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0)
|
||||
WindowsSdkDir := $(WindowsSdkDir)
|
||||
|
||||
WindowsSDKVersion ?= $(firstword $(foreach folder,$(subst $(subst \,/,$(WindowsSdkDir)Include/),,$(wildcard $(call fix_path,$(WindowsSdkDir)Include\*))),$(if $(wildcard $(call fix_path,$(WindowsSdkDir)Include/$(folder)/um/Windows.h)),$(folder),)))$(BACKSLASH)
|
||||
WindowsSDKVersion := $(WindowsSDKVersion)
|
||||
|
||||
VsInstallBuildTools = $(ProgramFiles86)/Microsoft Visual Studio/2017/BuildTools
|
||||
VsInstallEnterprise = $(ProgramFiles86)/Microsoft Visual Studio/2017/Enterprise
|
||||
VsInstallProfessional = $(ProgramFiles86)/Microsoft Visual Studio/2017/Professional
|
||||
VsInstallCommunity = $(ProgramFiles86)/Microsoft Visual Studio/2017/Community
|
||||
|
||||
VsInstallRoot ?= $(shell if [ -d "$(VsInstallBuildTools)" ]; then echo "$(VsInstallBuildTools)"; fi)
|
||||
ifeq ($(VsInstallRoot), )
|
||||
VsInstallRoot = $(shell if [ -d "$(VsInstallEnterprise)" ]; then echo "$(VsInstallEnterprise)"; fi)
|
||||
endif
|
||||
ifeq ($(VsInstallRoot), )
|
||||
VsInstallRoot = $(shell if [ -d "$(VsInstallProfessional)" ]; then echo "$(VsInstallProfessional)"; fi)
|
||||
endif
|
||||
ifeq ($(VsInstallRoot), )
|
||||
VsInstallRoot = $(shell if [ -d "$(VsInstallCommunity)" ]; then echo "$(VsInstallCommunity)"; fi)
|
||||
endif
|
||||
VsInstallRoot := $(VsInstallRoot)
|
||||
|
||||
VcCompilerToolsVer := $(shell cat "$(VsInstallRoot)/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt" | grep -o '[0-9\.]*')
|
||||
VcCompilerToolsDir := $(VsInstallRoot)/VC/Tools/MSVC/$(VcCompilerToolsVer)
|
||||
|
||||
WindowsSDKSharedIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\shared")
|
||||
WindowsSDKUCRTIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\ucrt")
|
||||
WindowsSDKUMIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\um")
|
||||
WindowsSDKUCRTLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\ucrt\$(TargetArchMoniker)")
|
||||
WindowsSDKUMLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\um\$(TargetArchMoniker)")
|
||||
|
||||
# For some reason the HostX86 compiler doesn't like compiling for x64
|
||||
# ("no such file" opening a shared library), and vice-versa.
|
||||
# Work around it for now by using the strictly x86 compiler for x86, and x64 for x64.
|
||||
# NOTE: What about ARM?
|
||||
ifneq (,$(findstring x64,$(TargetArchMoniker)))
|
||||
VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX64
|
||||
else
|
||||
VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX86
|
||||
endif
|
||||
|
||||
PATH := $(shell IFS=$$'\n'; cygpath "$(VCCompilerToolsBinDir)/$(TargetArchMoniker)"):$(PATH)
|
||||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include")
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker)")
|
||||
ifneq (,$(findstring uwp,$(PlatformSuffix)))
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(LIB)/store")
|
||||
endif
|
||||
|
||||
export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir)
|
||||
export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir)
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
LDFLAGS += -DLL
|
||||
|
||||
# Emscripten
|
||||
else ifeq ($(platform), emscripten)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).bc
|
||||
STATIC_LINKING = 1
|
||||
|
||||
# Windows MSVC 2005 x86
|
||||
else ifeq ($(platform), windows_msvc2005_x86)
|
||||
CC = cl.exe
|
||||
CXX = cl.exe
|
||||
|
||||
PATH := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin"):$(PATH)
|
||||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/include")
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/lib")
|
||||
BIN := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin")
|
||||
|
||||
WindowsSdkDir := $(INETSDK)
|
||||
|
||||
export INCLUDE := $(INCLUDE);$(INETSDK)/Include;libretro-common/include/compat/msvc
|
||||
export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
LDFLAGS += -DLL
|
||||
CFLAGS += -D_CRT_SECURE_NO_DEPRECATE
|
||||
LIBS =
|
||||
WINDOWS_VERSION=1
|
||||
|
||||
# Windows MSVC 2003 x86
|
||||
else ifeq ($(platform), windows_msvc2003_x86)
|
||||
CC = cl.exe
|
||||
CXX = cl.exe
|
||||
|
||||
PATH := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin"):$(PATH)
|
||||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/include")
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/lib")
|
||||
BIN := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin")
|
||||
|
||||
WindowsSdkDir := $(INETSDK)
|
||||
|
||||
export INCLUDE := $(INCLUDE);$(INETSDK)/Include;libretro-common/include/compat/msvc
|
||||
export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
LDFLAGS += -DLL
|
||||
CFLAGS += -D_CRT_SECURE_NO_DEPRECATE
|
||||
WINDOWS_VERSION=1
|
||||
|
||||
# Windows
|
||||
else
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
IS_X86 = 1
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T
|
||||
LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm -lws2_32
|
||||
WINDOWS_VERSION = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PROFILE), performance)
|
||||
FLAGS += -DPROFILE_PERFORMANCE
|
||||
else ifeq ($(PROFILE), balanced)
|
||||
FLAGS += -DPROFILE_BALANCED
|
||||
else ifeq ($(PROFILE), accuracy)
|
||||
FLAGS += -DPROFILE_ACCURACY
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
WARNINGS :=
|
||||
else
|
||||
WARNINGS := -Wall \
|
||||
-Wno-sign-compare \
|
||||
-Wno-unused-variable \
|
||||
-Wno-unused-function \
|
||||
-Wno-uninitialized \
|
||||
$(NEW_GCC_WARNING_FLAGS) \
|
||||
-Wno-strict-aliasing
|
||||
endif
|
||||
|
||||
EXTRA_GCC_FLAGS := -funroll-loops
|
||||
|
||||
ifeq ($(NO_GCC),1)
|
||||
EXTRA_GCC_FLAGS :=
|
||||
WARNINGS :=
|
||||
else
|
||||
EXTRA_GCC_FLAGS :=
|
||||
endif
|
||||
|
||||
OBJECTS := $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
ifeq ($(DEBUG),0)
|
||||
FLAGS += -O3 $(EXTRA_GCC_FLAGS)
|
||||
else
|
||||
FLAGS += -O0 -g
|
||||
endif
|
||||
|
||||
LDFLAGS += $(fpic) $(SHARED)
|
||||
FLAGS += $(fpic) $(NEW_GCC_FLAGS) $(INCFLAGS)
|
||||
|
||||
FLAGS += $(ENDIANNESS_DEFINES) $(WARNINGS) $(CORE_DEFINE) -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -DSFC_LAGFIX $(EXTRA_INCLUDES) $(SOUND_DEFINE)
|
||||
|
||||
CXXFLAGS += $(FLAGS) -std=c++11
|
||||
CFLAGS += $(FLAGS)
|
||||
|
||||
OBJOUT = -o
|
||||
LINKOUT = -o
|
||||
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
OBJOUT = -Fo
|
||||
LINKOUT = -out:
|
||||
ifeq ($(STATIC_LINKING),1)
|
||||
LD ?= lib.exe
|
||||
STATIC_LINKING=0
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -MTd
|
||||
CXXFLAGS += -MTd
|
||||
else
|
||||
CFLAGS += -MT
|
||||
CXXFLAGS += -MT
|
||||
endif
|
||||
else
|
||||
LD = link.exe
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -MDd
|
||||
CXXFLAGS += -MDd
|
||||
else
|
||||
CFLAGS += -MD
|
||||
CXXFLAGS += -MD
|
||||
endif
|
||||
endif
|
||||
else
|
||||
LD = $(CXX)
|
||||
endif
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
ifeq ($(platform), emscripten)
|
||||
$(CXX) $(CXXFLAGS) $(OBJOUT)$@ $^
|
||||
else ifeq ($(STATIC_LINKING), 1)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
else
|
||||
$(LD) $(LINKOUT)$@ $^ $(LDFLAGS) $(LIBS)
|
||||
endif
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) -c $(OBJOUT)$@ $< $(CXXFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(OBJOUT)$@ $< $(CFLAGS)
|
||||
|
||||
# targets
|
||||
clean:
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,obj/*.a)
|
||||
-@$(call delete,obj/*.so)
|
||||
-@$(call delete,obj/*.dylib)
|
||||
-@$(call delete,obj/*.dll)
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.manifest)
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
archive:
|
||||
if [ -f higan.tar.xz ]; then rm higan.tar.xz; fi
|
||||
tar -cJf higan.tar.xz `ls`
|
||||
|
||||
sync:
|
||||
ifeq ($(shell id -un),byuu)
|
||||
if [ -d ./libco ]; then rm -r ./libco; fi
|
||||
if [ -d ./nall ]; then rm -r ./nall; fi
|
||||
if [ -d ./ruby ]; then rm -r ./ruby; fi
|
||||
if [ -d ./phoenix ]; then rm -r ./phoenix; fi
|
||||
cp -r ../libco ./libco
|
||||
cp -r ../nall ./nall
|
||||
cp -r ../ruby ./ruby
|
||||
cp -r ../phoenix ./phoenix
|
||||
rm -r libco/doc
|
||||
rm -r libco/.test
|
||||
rm -r nall/.test
|
||||
rm -r ruby/.test
|
||||
rm -r phoenix/.test
|
||||
endif
|
||||
|
||||
help:;
|
||||
.PHONY: clean
|
||||
@@ -0,0 +1,78 @@
|
||||
SOURCES_CXX :=
|
||||
SOURCES_C :=
|
||||
|
||||
GB_DIR := $(CORE_DIR)/gb
|
||||
SNES_DIR := $(CORE_DIR)/sfc
|
||||
|
||||
INCFLAGS := \
|
||||
-I$(CORE_DIR) \
|
||||
-I$(SNES_DIR)
|
||||
|
||||
SOURCES_C += $(CORE_DIR)/libco/libco.c
|
||||
|
||||
SOURCES_CXX += \
|
||||
$(CORE_DIR)/processor/arm/arm.cpp \
|
||||
$(CORE_DIR)/processor/gsu/gsu.cpp \
|
||||
$(CORE_DIR)/processor/hg51b/hg51b.cpp \
|
||||
$(CORE_DIR)/processor/lr35902/lr35902.cpp \
|
||||
$(CORE_DIR)/processor/r65816/r65816.cpp \
|
||||
$(CORE_DIR)/processor/spc700/spc700.cpp \
|
||||
$(CORE_DIR)/processor/upd96050/upd96050.cpp \
|
||||
$(GB_DIR)/interface/interface.cpp \
|
||||
$(GB_DIR)/system/system.cpp \
|
||||
$(GB_DIR)/scheduler/scheduler.cpp \
|
||||
$(GB_DIR)/memory/memory.cpp \
|
||||
$(GB_DIR)/cartridge/cartridge.cpp \
|
||||
$(GB_DIR)/cpu/cpu.cpp \
|
||||
$(GB_DIR)/ppu/ppu.cpp \
|
||||
$(GB_DIR)/apu/apu.cpp \
|
||||
$(GB_DIR)/cheat/cheat.cpp \
|
||||
$(GB_DIR)/video/video.cpp \
|
||||
$(SNES_DIR)/interface/interface.cpp \
|
||||
$(SNES_DIR)/base/satellaview/satellaview.cpp \
|
||||
$(SNES_DIR)/system/system.cpp \
|
||||
$(SNES_DIR)/controller/controller.cpp \
|
||||
$(SNES_DIR)/cartridge/cartridge.cpp \
|
||||
$(SNES_DIR)/cheat/cheat.cpp \
|
||||
$(SNES_DIR)/memory/memory.cpp \
|
||||
$(SNES_DIR)/chip/armdsp/armdsp.cpp \
|
||||
$(SNES_DIR)/chip/bsx/bsx.cpp \
|
||||
$(SNES_DIR)/chip/epsonrtc/epsonrtc.cpp \
|
||||
$(SNES_DIR)/chip/event/event.cpp \
|
||||
$(SNES_DIR)/chip/hitachidsp/hitachidsp.cpp \
|
||||
$(SNES_DIR)/chip/hsu1/hsu1.cpp \
|
||||
$(SNES_DIR)/chip/icd2/icd2.cpp \
|
||||
$(SNES_DIR)/chip/msu1/msu1.cpp \
|
||||
$(SNES_DIR)/chip/necdsp/necdsp.cpp \
|
||||
$(SNES_DIR)/chip/nss/nss.cpp \
|
||||
$(SNES_DIR)/chip/obc1/obc1.cpp \
|
||||
$(SNES_DIR)/chip/sa1/sa1.cpp \
|
||||
$(SNES_DIR)/chip/sdd1/sdd1.cpp \
|
||||
$(SNES_DIR)/chip/sharprtc/sharprtc.cpp \
|
||||
$(SNES_DIR)/chip/spc7110/spc7110.cpp \
|
||||
$(SNES_DIR)/chip/superfx/superfx.cpp \
|
||||
$(SNES_DIR)/slot/satellaview/satellaview.cpp \
|
||||
$(SNES_DIR)/slot/sufamiturbo/sufamiturbo.cpp \
|
||||
$(CORE_DIR)/target-libretro/libretro.cpp
|
||||
|
||||
ifeq ($(PROFILE), performance)
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/cpu/cpu.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/smp/smp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/dsp/dsp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/ppu-performance/ppu.cpp
|
||||
else ifeq ($(PROFILE), balanced)
|
||||
SOURCES_CXX += $(SNES_DIR)/cpu/cpu.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/smp/smp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/dsp/dsp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/alt/ppu-balanced/ppu.cpp
|
||||
else ifeq ($(PROFILE), accuracy)
|
||||
SOURCES_CXX += $(SNES_DIR)/cpu/cpu.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/smp/smp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/dsp/dsp.cpp
|
||||
SOURCES_CXX += $(SNES_DIR)/ppu/ppu.cpp
|
||||
endif
|
||||
|
||||
ifneq ($(STATIC_LINKING), 1)
|
||||
SOURCES_CXX +=
|
||||
SOURCES_C +=
|
||||
endif
|
||||
+3
-3
@@ -20,9 +20,9 @@ resource: force
|
||||
sourcery resource/resource.bml resource/resource.cpp resource/resource.hpp
|
||||
|
||||
clean:
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,*.dll)
|
||||
-@$(call delete,*.so)
|
||||
-$(call delete,obj/*.o)
|
||||
-$(call delete,*.dll)
|
||||
-$(call delete,*.so)
|
||||
|
||||
install: uninstall
|
||||
ifeq ($(platform),windows)
|
||||
|
||||
@@ -143,7 +143,7 @@ typedef uint29_t uint29;
|
||||
typedef uint30_t uint30;
|
||||
typedef uint31_t uint31;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint_t<33> uint33;
|
||||
typedef nall::uint_t<33> uint33;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef varuint_t<unsigned> varuint;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <gb/gb.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace GameBoy {
|
||||
|
||||
@@ -25,4 +26,22 @@ optional<unsigned> Cheat::find(unsigned addr, unsigned comp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Cheat::decode(const char *part, unsigned &addr, unsigned &comp, unsigned &data) {
|
||||
/* Code Types
|
||||
* RAW:
|
||||
* AAAA:DD
|
||||
* Game Genie: http://gamehacking.org/library/114
|
||||
* GameShark: 0BDDAAAA - Byteswapped Address, bank+1
|
||||
* Codebreaker: 0BAAAA-DD
|
||||
* Xploder: Unknown
|
||||
*/
|
||||
std::cerr << "[bsnes]: Decoding cheats not implemented." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Cheat::synchronize() {
|
||||
std::cerr << "[bsnes]: Synchronizing cheats not implemented." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,9 @@ struct Cheat {
|
||||
void append(unsigned addr, unsigned data);
|
||||
void append(unsigned addr, unsigned comp, unsigned data);
|
||||
optional<unsigned> find(unsigned addr, unsigned comp);
|
||||
|
||||
bool decode(const char *part, unsigned &addr, unsigned &comp, unsigned &data);
|
||||
void synchronize();
|
||||
};
|
||||
|
||||
extern Cheat cheat;
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
libco.aarch64 (2017-06-26)
|
||||
author: webgeek1234
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local uint64_t co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle;
|
||||
|
||||
asm (
|
||||
".globl co_switch_aarch64\n"
|
||||
".globl _co_switch_aarch64\n"
|
||||
"co_switch_aarch64:\n"
|
||||
"_co_switch_aarch64:\n"
|
||||
" stp x8, x9, [x1]\n"
|
||||
" stp x10, x11, [x1, #16]\n"
|
||||
" stp x12, x13, [x1, #32]\n"
|
||||
" stp x14, x15, [x1, #48]\n"
|
||||
" str x19, [x1, #72]\n"
|
||||
" stp x20, x21, [x1, #80]\n"
|
||||
" stp x22, x23, [x1, #96]\n"
|
||||
" stp x24, x25, [x1, #112]\n"
|
||||
" stp x26, x27, [x1, #128]\n"
|
||||
" stp x28, x29, [x1, #144]\n"
|
||||
" mov x16, sp\n"
|
||||
" stp x16, x30, [x1, #160]\n"
|
||||
|
||||
" ldp x8, x9, [x0]\n"
|
||||
" ldp x10, x11, [x0, #16]\n"
|
||||
" ldp x12, x13, [x0, #32]\n"
|
||||
" ldp x14, x15, [x0, #48]\n"
|
||||
" ldr x19, [x0, #72]\n"
|
||||
" ldp x20, x21, [x0, #80]\n"
|
||||
" ldp x22, x23, [x0, #96]\n"
|
||||
" ldp x24, x25, [x0, #112]\n"
|
||||
" ldp x26, x27, [x0, #128]\n"
|
||||
" ldp x28, x29, [x0, #144]\n"
|
||||
" ldp x16, x17, [x0, #160]\n"
|
||||
" mov sp, x16\n"
|
||||
" br x17\n"
|
||||
);
|
||||
|
||||
/* ASM */
|
||||
void co_switch_aarch64(cothread_t handle, cothread_t current);
|
||||
|
||||
static void crash(void)
|
||||
{
|
||||
/* Called only if cothread_t entrypoint returns. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
size = (size + 1023) & ~1023;
|
||||
cothread_t handle = 0;
|
||||
#if HAVE_POSIX_MEMALIGN >= 1
|
||||
if (posix_memalign(&handle, 1024, size + 512) < 0)
|
||||
return 0;
|
||||
#else
|
||||
handle = memalign(1024, size + 512);
|
||||
#endif
|
||||
|
||||
if (!handle)
|
||||
return handle;
|
||||
|
||||
uint64_t *ptr = (uint64_t*)handle;
|
||||
/* Non-volatiles. */
|
||||
ptr[0] = 0; /* x8 */
|
||||
ptr[1] = 0; /* x9 */
|
||||
ptr[2] = 0; /* x10 */
|
||||
ptr[3] = 0; /* x11 */
|
||||
ptr[4] = 0; /* x12 */
|
||||
ptr[5] = 0; /* x13 */
|
||||
ptr[6] = 0; /* x14 */
|
||||
ptr[7] = 0; /* x15 */
|
||||
ptr[8] = 0; /* padding */
|
||||
ptr[9] = 0; /* x19 */
|
||||
ptr[10] = 0; /* x20 */
|
||||
ptr[11] = 0; /* x21 */
|
||||
ptr[12] = 0; /* x22 */
|
||||
ptr[13] = 0; /* x23 */
|
||||
ptr[14] = 0; /* x24 */
|
||||
ptr[15] = 0; /* x25 */
|
||||
ptr[16] = 0; /* x26 */
|
||||
ptr[17] = 0; /* x27 */
|
||||
ptr[18] = 0; /* x28 */
|
||||
ptr[20] = (uintptr_t)ptr + size + 512 - 16; /* x30, stack pointer */
|
||||
ptr[19] = ptr[20]; /* x29, frame pointer */
|
||||
ptr[21] = (uintptr_t)entrypoint; /* PC (link register x31 gets saved here). */
|
||||
return handle;
|
||||
}
|
||||
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_active_handle)
|
||||
co_active_handle = co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
cothread_t co_previous_handle = co_active();
|
||||
co_switch_aarch64(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+157
-64
@@ -9,92 +9,185 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__GNUC__) && !defined(_WIN32) && !defined(__cplusplus)
|
||||
#define CO_USE_INLINE_ASM
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local long long co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle = 0;
|
||||
#ifndef CO_USE_INLINE_ASM
|
||||
static void (*co_swap)(cothread_t, cothread_t) = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
//ABI: Win64
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x22, 0x48, 0x8B, 0x21, 0x58, 0x48, 0x89, 0x6A, 0x08, 0x48, 0x89, 0x72, 0x10, 0x48,
|
||||
0x89, 0x7A, 0x18, 0x48, 0x89, 0x5A, 0x20, 0x4C, 0x89, 0x62, 0x28, 0x4C, 0x89, 0x6A, 0x30, 0x4C,
|
||||
0x89, 0x72, 0x38, 0x4C, 0x89, 0x7A, 0x40, 0x48, 0x81, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
|
||||
0xE2, 0xF0, 0x0F, 0x29, 0x32, 0x0F, 0x29, 0x7A, 0x10, 0x44, 0x0F, 0x29, 0x42, 0x20, 0x44, 0x0F,
|
||||
0x29, 0x4A, 0x30, 0x44, 0x0F, 0x29, 0x52, 0x40, 0x44, 0x0F, 0x29, 0x5A, 0x50, 0x44, 0x0F, 0x29,
|
||||
0x62, 0x60, 0x44, 0x0F, 0x29, 0x6A, 0x70, 0x44, 0x0F, 0x29, 0xB2, 0x80, 0x00, 0x00, 0x00, 0x44,
|
||||
0x0F, 0x29, 0xBA, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x69, 0x08, 0x48, 0x8B, 0x71, 0x10, 0x48,
|
||||
0x8B, 0x79, 0x18, 0x48, 0x8B, 0x59, 0x20, 0x4C, 0x8B, 0x61, 0x28, 0x4C, 0x8B, 0x69, 0x30, 0x4C,
|
||||
0x8B, 0x71, 0x38, 0x4C, 0x8B, 0x79, 0x40, 0x48, 0x81, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
|
||||
0xE1, 0xF0, 0x0F, 0x29, 0x31, 0x0F, 0x29, 0x79, 0x10, 0x44, 0x0F, 0x29, 0x41, 0x20, 0x44, 0x0F,
|
||||
0x29, 0x49, 0x30, 0x44, 0x0F, 0x29, 0x51, 0x40, 0x44, 0x0F, 0x29, 0x59, 0x50, 0x44, 0x0F, 0x29,
|
||||
0x61, 0x60, 0x44, 0x0F, 0x29, 0x69, 0x70, 0x44, 0x0F, 0x29, 0xB1, 0x80, 0x00, 0x00, 0x00, 0x44,
|
||||
0x0F, 0x29, 0xB9, 0x90, 0x00, 0x00, 0x00, 0xFF, 0xE0,
|
||||
};
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void co_init() {
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
#else
|
||||
//ABI: SystemV
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x26, 0x48, 0x8B, 0x27, 0x58, 0x48, 0x89, 0x6E, 0x08, 0x48, 0x89, 0x5E, 0x10, 0x4C,
|
||||
0x89, 0x66, 0x18, 0x4C, 0x89, 0x6E, 0x20, 0x4C, 0x89, 0x76, 0x28, 0x4C, 0x89, 0x7E, 0x30, 0x48,
|
||||
0x8B, 0x6F, 0x08, 0x48, 0x8B, 0x5F, 0x10, 0x4C, 0x8B, 0x67, 0x18, 0x4C, 0x8B, 0x6F, 0x20, 0x4C,
|
||||
0x8B, 0x77, 0x28, 0x4C, 0x8B, 0x7F, 0x30, 0xFF, 0xE0,
|
||||
};
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void co_init() {
|
||||
unsigned long long addr = (unsigned long long)co_swap_function;
|
||||
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long long size = (addr - base) + sizeof co_swap_function;
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
void co_swap(cothread_t, cothread_t);
|
||||
#endif
|
||||
|
||||
static void crash() {
|
||||
#ifdef _WIN32
|
||||
//ABI: Win64
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x22, /* mov [rdx],rsp */
|
||||
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
|
||||
0x58, /* pop rax */
|
||||
0x48, 0x89, 0x6a, 0x08, /* mov [rdx+0x8],rbp */
|
||||
0x48, 0x89, 0x72, 0x10, /* mov [rdx+0x10],rsi */
|
||||
0x48, 0x89, 0x7a, 0x18, /* mov [rdx+0x18],rdi */
|
||||
0x48, 0x89, 0x5a, 0x20, /* mov [rdx+0x20],rbx */
|
||||
0x4c, 0x89, 0x62, 0x28, /* mov [rdx+0x28],r12 */
|
||||
0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+0x30],r13 */
|
||||
0x4c, 0x89, 0x72, 0x38, /* mov [rdx+0x38],r14 */
|
||||
0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+0x40],r15 */
|
||||
0x48, 0x81, 0xc2, 0x80, 0x00, 0x00, 0x00, /* add rdx,0x80 */
|
||||
0x48, 0x83, 0xe2, 0xf0, /* and rdx,-0x10 */
|
||||
0x0f, 0x29, 0x32, /* movaps [rdx],xmm6 */
|
||||
0x0f, 0x29, 0x7a, 0x10, /* movaps [rdx+0x10],xmm7 */
|
||||
0x44, 0x0f, 0x29, 0x42, 0x20, /* movaps [rdx+0x20],xmm8 */
|
||||
0x44, 0x0f, 0x29, 0x4a, 0x30, /* movaps [rdx+0x30],xmm9 */
|
||||
0x44, 0x0f, 0x29, 0x52, 0x40, /* movaps [rdx+0x40],xmm10 */
|
||||
0x44, 0x0f, 0x29, 0x5a, 0x50, /* movaps [rdx+0x50],xmm11 */
|
||||
0x44, 0x0f, 0x29, 0x62, 0x60, /* movaps [rdx+0x60],xmm12 */
|
||||
0x44, 0x0f, 0x29, 0x6a, 0x70, /* movaps [rdx+0x70],xmm13 */
|
||||
0x44, 0x0f, 0x29, 0xb2, 0x80, 0x00, 0x00, 0x00, /* movaps [rdx+0x80],xmm14 */
|
||||
0x44, 0x0f, 0x29, 0xba, 0x90, 0x00, 0x00, 0x00, /* movaps [rdx+0x90],xmm15 */
|
||||
0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+0x8] */
|
||||
0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+0x10] */
|
||||
0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+0x18] */
|
||||
0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+0x20] */
|
||||
0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+0x28] */
|
||||
0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+0x30] */
|
||||
0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+0x38] */
|
||||
0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+0x40] */
|
||||
0x48, 0x81, 0xc1, 0x80, 0x00, 0x00, 0x00, /* add rcx,0x80 */
|
||||
0x48, 0x83, 0xe1, 0xf0, /* and rcx,-0x10 */
|
||||
0x0f, 0x29, 0x31, /* movaps [rcx],xmm6 */
|
||||
0x0f, 0x29, 0x79, 0x10, /* movaps [rcx+0x10],xmm7 */
|
||||
0x44, 0x0f, 0x29, 0x41, 0x20, /* movaps [rcx+0x20],xmm8 */
|
||||
0x44, 0x0f, 0x29, 0x49, 0x30, /* movaps [rcx+0x30],xmm9 */
|
||||
0x44, 0x0f, 0x29, 0x51, 0x40, /* movaps [rcx+0x40],xmm10 */
|
||||
0x44, 0x0f, 0x29, 0x59, 0x50, /* movaps [rcx+0x50],xmm11 */
|
||||
0x44, 0x0f, 0x29, 0x61, 0x60, /* movaps [rcx+0x60],xmm12 */
|
||||
0x44, 0x0f, 0x29, 0x69, 0x70, /* movaps [rcx+0x70],xmm13 */
|
||||
0x44, 0x0f, 0x29, 0xb1, 0x80, 0x00, 0x00, 0x00, /* movaps [rcx+0x80],xmm14 */
|
||||
0x44, 0x0f, 0x29, 0xb9, 0x90, 0x00, 0x00, 0x00, /* movaps [rcx+0x90],xmm15 */
|
||||
0xff, 0xe0, /* jmp rax */
|
||||
};
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void co_init(void)
|
||||
{
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function,
|
||||
sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
#else
|
||||
//ABI: SystemV
|
||||
#ifndef CO_USE_INLINE_ASM
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x26, /* mov [rsi],rsp */
|
||||
0x48, 0x8b, 0x27, /* mov rsp,[rdi] */
|
||||
0x58, /* pop rax */
|
||||
0x48, 0x89, 0x6e, 0x08, /* mov [rsi+0x08],rbp */
|
||||
0x48, 0x89, 0x5e, 0x10, /* mov [rsi+0x10],rbx */
|
||||
0x4c, 0x89, 0x66, 0x18, /* mov [rsi+0x18],r12 */
|
||||
0x4c, 0x89, 0x6e, 0x20, /* mov [rsi+0x20],r13 */
|
||||
0x4c, 0x89, 0x76, 0x28, /* mov [rsi+0x28],r14 */
|
||||
0x4c, 0x89, 0x7e, 0x30, /* mov [rsi+0x30],r15 */
|
||||
0x48, 0x8b, 0x6f, 0x08, /* mov rbp,[rdi+0x08] */
|
||||
0x48, 0x8b, 0x5f, 0x10, /* mov rbx,[rdi+0x10] */
|
||||
0x4c, 0x8b, 0x67, 0x18, /* mov r12,[rdi+0x18] */
|
||||
0x4c, 0x8b, 0x6f, 0x20, /* mov r13,[rdi+0x20] */
|
||||
0x4c, 0x8b, 0x77, 0x28, /* mov r14,[rdi+0x28] */
|
||||
0x4c, 0x8b, 0x7f, 0x30, /* mov r15,[rdi+0x30] */
|
||||
0xff, 0xe0, /* jmp rax */
|
||||
};
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void co_init(void)
|
||||
{
|
||||
unsigned long long addr = (unsigned long long)co_swap_function;
|
||||
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long long size = (addr - base) + sizeof(co_swap_function);
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
#else
|
||||
__asm__(
|
||||
".intel_syntax noprefix\n"
|
||||
".globl co_swap \n"
|
||||
"co_swap: \n"
|
||||
".globl _co_swap \n" /* OSX ABI is different from Linux. */
|
||||
"_co_swap: \n"
|
||||
"mov [rsi],rsp \n"
|
||||
"mov [rsi+0x08],rbp \n"
|
||||
"mov [rsi+0x10],rbx \n"
|
||||
"mov [rsi+0x18],r12 \n"
|
||||
"mov [rsi+0x20],r13 \n"
|
||||
"mov [rsi+0x28],r14 \n"
|
||||
"mov [rsi+0x30],r15 \n"
|
||||
"mov rsp,[rdi] \n"
|
||||
"mov rbp,[rdi+0x08] \n"
|
||||
"mov rbx,[rdi+0x10] \n"
|
||||
"mov r12,[rdi+0x18] \n"
|
||||
"mov r13,[rdi+0x20] \n"
|
||||
"mov r14,[rdi+0x28] \n"
|
||||
"mov r15,[rdi+0x30] \n"
|
||||
"ret \n"
|
||||
".att_syntax \n"
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void crash(void)
|
||||
{
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
|
||||
cothread_t handle;
|
||||
if(!co_swap) {
|
||||
co_init();
|
||||
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
size += 512; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
cothread_t handle;
|
||||
|
||||
if(handle = (cothread_t)malloc(size)) {
|
||||
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
#ifndef CO_USE_INLINE_ASM
|
||||
if(!co_swap)
|
||||
{
|
||||
co_init();
|
||||
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
#endif
|
||||
|
||||
return handle;
|
||||
if (!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
size += 512; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
if((handle = (cothread_t)malloc(size)))
|
||||
{
|
||||
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle) {
|
||||
free(handle);
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle) {
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
libco.armeabi (2013-04-05)
|
||||
author: Themaister
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local uint32_t co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle;
|
||||
|
||||
asm (
|
||||
".arm\n"
|
||||
".align 4\n"
|
||||
".globl co_switch_arm\n"
|
||||
".globl _co_switch_arm\n"
|
||||
"co_switch_arm:\n"
|
||||
"_co_switch_arm:\n"
|
||||
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n"
|
||||
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n"
|
||||
);
|
||||
|
||||
/* ASM */
|
||||
void co_switch_arm(cothread_t handle, cothread_t current);
|
||||
|
||||
static void crash(void)
|
||||
{
|
||||
/* Called only if cothread_t entrypoint returns. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
size = (size + 1023) & ~1023;
|
||||
cothread_t handle = 0;
|
||||
#if defined(__APPLE__) || HAVE_POSIX_MEMALIGN >= 1
|
||||
if (posix_memalign(&handle, 1024, size + 256) < 0)
|
||||
return 0;
|
||||
#else
|
||||
handle = memalign(1024, size + 256);
|
||||
#endif
|
||||
|
||||
if (!handle)
|
||||
return handle;
|
||||
|
||||
uint32_t *ptr = (uint32_t*)handle;
|
||||
/* Non-volatiles. */
|
||||
ptr[0] = 0; /* r4 */
|
||||
ptr[1] = 0; /* r5 */
|
||||
ptr[2] = 0; /* r6 */
|
||||
ptr[3] = 0; /* r7 */
|
||||
ptr[4] = 0; /* r8 */
|
||||
ptr[5] = 0; /* r9 */
|
||||
ptr[6] = 0; /* r10 */
|
||||
ptr[7] = 0; /* r11 */
|
||||
/* Align stack to 64-bit */
|
||||
ptr[8] = (uintptr_t)ptr + size + 256 - 8; /* r13, stack pointer */
|
||||
ptr[9] = (uintptr_t)entrypoint; /* r15, PC (link register r14 gets saved here). */
|
||||
return handle;
|
||||
}
|
||||
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_active_handle)
|
||||
co_active_handle = co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
cothread_t co_previous_handle = co_active();
|
||||
co_switch_arm(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+26
-19
@@ -17,33 +17,40 @@ extern "C" {
|
||||
|
||||
static thread_local cothread_t co_active_ = 0;
|
||||
|
||||
static void __stdcall co_thunk(void *coentry) {
|
||||
((void (*)(void))coentry)();
|
||||
static void __stdcall co_thunk(void *coentry)
|
||||
{
|
||||
((void (*)(void))coentry)();
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_active_) {
|
||||
ConvertThreadToFiber(0);
|
||||
co_active_ = GetCurrentFiber();
|
||||
}
|
||||
return co_active_;
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if(!co_active_)
|
||||
{
|
||||
ConvertThreadToFiber(0);
|
||||
co_active_ = GetCurrentFiber();
|
||||
}
|
||||
return co_active_;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
|
||||
if(!co_active_) {
|
||||
ConvertThreadToFiber(0);
|
||||
co_active_ = GetCurrentFiber();
|
||||
}
|
||||
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
||||
{
|
||||
if(!co_active_)
|
||||
{
|
||||
ConvertThreadToFiber(0);
|
||||
co_active_ = GetCurrentFiber();
|
||||
}
|
||||
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
||||
}
|
||||
|
||||
void co_delete(cothread_t cothread) {
|
||||
DeleteFiber(cothread);
|
||||
void co_delete(cothread_t cothread)
|
||||
{
|
||||
DeleteFiber(cothread);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t cothread) {
|
||||
co_active_ = cothread;
|
||||
SwitchToFiber(cothread);
|
||||
void co_switch(cothread_t cothread)
|
||||
{
|
||||
co_active_ = cothread;
|
||||
SwitchToFiber(cothread);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+6
-6
@@ -4,18 +4,18 @@
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
#if defined(__GNUC__) && defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86))
|
||||
#include "x86.c"
|
||||
#elif defined(__GNUC__) && defined(__amd64__)
|
||||
#elif defined(__GNUC__) && defined(__amd64__) || (defined(_MSC_VER) && defined(_M_AMD64))
|
||||
#include "amd64.c"
|
||||
#elif defined(__GNUC__) && defined(_ARCH_PPC)
|
||||
#include "ppc.c"
|
||||
#elif defined(__GNUC__) && defined(__aarch64__)
|
||||
#include "aarch64.c"
|
||||
#elif defined(__GNUC__) && (defined(__ARM_EABI__) || defined(__arm__))
|
||||
#include "armeabi.c"
|
||||
#elif defined(__GNUC__)
|
||||
#include "sjlj.c"
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
#include "x86.c"
|
||||
#elif defined(_MSC_VER) && defined(_M_AMD64)
|
||||
#include "amd64.c"
|
||||
#elif defined(_MSC_VER)
|
||||
#include "fiber.c"
|
||||
#else
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ extern "C" {
|
||||
|
||||
typedef void* cothread_t;
|
||||
|
||||
cothread_t co_active();
|
||||
cothread_t co_active(void);
|
||||
cothread_t co_create(unsigned int, void (*)(void));
|
||||
void co_delete(cothread_t);
|
||||
void co_switch(cothread_t);
|
||||
|
||||
+31
-31
@@ -363,45 +363,45 @@ cothread_t co_create( unsigned int size, void (*entry_)( void ) )
|
||||
|
||||
void co_delete( cothread_t t )
|
||||
{
|
||||
free( t );
|
||||
free(t);
|
||||
}
|
||||
|
||||
static void co_init_( void )
|
||||
{
|
||||
#if LIBCO_MPROTECT
|
||||
/* TODO: pre- and post-pad PPC code so that this doesn't make other
|
||||
data executable and writable */
|
||||
long page_size = sysconf( _SC_PAGESIZE );
|
||||
if ( page_size > 0 )
|
||||
{
|
||||
uintptr_t align = page_size;
|
||||
uintptr_t begin = (uintptr_t) libco_ppc_code;
|
||||
uintptr_t end = begin + sizeof libco_ppc_code;
|
||||
|
||||
/* Align beginning and end */
|
||||
end += align - 1;
|
||||
end -= end % align;
|
||||
begin -= begin % align;
|
||||
|
||||
mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC );
|
||||
}
|
||||
#endif
|
||||
|
||||
co_active_handle = co_create_( state_size, (uintptr_t) &co_switch );
|
||||
#if LIBCO_MPROTECT
|
||||
/* TODO: pre- and post-pad PPC code so that this doesn't make other
|
||||
data executable and writable */
|
||||
long page_size = sysconf( _SC_PAGESIZE );
|
||||
if ( page_size > 0 )
|
||||
{
|
||||
uintptr_t align = page_size;
|
||||
uintptr_t begin = (uintptr_t) libco_ppc_code;
|
||||
uintptr_t end = begin + sizeof libco_ppc_code;
|
||||
|
||||
/* Align beginning and end */
|
||||
end += align - 1;
|
||||
end -= end % align;
|
||||
begin -= begin % align;
|
||||
|
||||
mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC );
|
||||
}
|
||||
#endif
|
||||
|
||||
co_active_handle = co_create_( state_size, (uintptr_t) &co_switch );
|
||||
}
|
||||
|
||||
cothread_t co_active()
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if ( !co_active_handle )
|
||||
co_init_();
|
||||
|
||||
return co_active_handle;
|
||||
if (!co_active_handle)
|
||||
co_init_();
|
||||
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
void co_switch( cothread_t t )
|
||||
void co_switch(cothread_t t)
|
||||
{
|
||||
cothread_t old = co_active_handle;
|
||||
co_active_handle = t;
|
||||
|
||||
CO_SWAP_ASM( t, old );
|
||||
cothread_t old = co_active_handle;
|
||||
co_active_handle = t;
|
||||
|
||||
CO_SWAP_ASM( t, old );
|
||||
}
|
||||
+65
-52
@@ -21,80 +21,93 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
sigjmp_buf context;
|
||||
void (*coentry)(void);
|
||||
void *stack;
|
||||
typedef struct
|
||||
{
|
||||
sigjmp_buf context;
|
||||
void (*coentry)(void);
|
||||
void *stack;
|
||||
} cothread_struct;
|
||||
|
||||
static thread_local cothread_struct co_primary;
|
||||
static thread_local cothread_struct *creating, *co_running = 0;
|
||||
|
||||
static void springboard(int ignored) {
|
||||
if(sigsetjmp(creating->context, 0)) {
|
||||
co_running->coentry();
|
||||
}
|
||||
static void springboard(int ignored)
|
||||
{
|
||||
if(sigsetjmp(creating->context, 0))
|
||||
co_running->coentry();
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_running) co_running = &co_primary;
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_running)
|
||||
co_running = &co_primary;
|
||||
return (cothread_t)co_running;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*coentry)(void)) {
|
||||
if(!co_running) co_running = &co_primary;
|
||||
cothread_t co_create(unsigned int size, void (*coentry)(void))
|
||||
{
|
||||
if(!co_running)
|
||||
co_running = &co_primary;
|
||||
|
||||
cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct));
|
||||
if(thread) {
|
||||
struct sigaction handler;
|
||||
struct sigaction old_handler;
|
||||
cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct));
|
||||
|
||||
stack_t stack;
|
||||
stack_t old_stack;
|
||||
if(thread)
|
||||
{
|
||||
struct sigaction handler;
|
||||
struct sigaction old_handler;
|
||||
|
||||
thread->coentry = thread->stack = 0;
|
||||
stack_t stack;
|
||||
stack_t old_stack;
|
||||
|
||||
stack.ss_flags = 0;
|
||||
stack.ss_size = size;
|
||||
thread->stack = stack.ss_sp = malloc(size);
|
||||
if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) {
|
||||
handler.sa_handler = springboard;
|
||||
handler.sa_flags = SA_ONSTACK;
|
||||
sigemptyset(&handler.sa_mask);
|
||||
creating = thread;
|
||||
thread->coentry = thread->stack = 0;
|
||||
|
||||
if(!sigaction(SIGUSR1, &handler, &old_handler)) {
|
||||
if(!raise(SIGUSR1)) {
|
||||
thread->coentry = coentry;
|
||||
}
|
||||
sigaltstack(&old_stack, 0);
|
||||
sigaction(SIGUSR1, &old_handler, 0);
|
||||
stack.ss_flags = 0;
|
||||
stack.ss_size = size;
|
||||
thread->stack = stack.ss_sp = malloc(size);
|
||||
|
||||
if(stack.ss_sp && !sigaltstack(&stack, &old_stack))
|
||||
{
|
||||
handler.sa_handler = springboard;
|
||||
handler.sa_flags = SA_ONSTACK;
|
||||
sigemptyset(&handler.sa_mask);
|
||||
creating = thread;
|
||||
|
||||
if(!sigaction(SIGUSR1, &handler, &old_handler))
|
||||
{
|
||||
if(!raise(SIGUSR1))
|
||||
thread->coentry = coentry;
|
||||
sigaltstack(&old_stack, 0);
|
||||
sigaction(SIGUSR1, &old_handler, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(thread->coentry != coentry) {
|
||||
co_delete(thread);
|
||||
thread = 0;
|
||||
}
|
||||
}
|
||||
if(thread->coentry != coentry)
|
||||
{
|
||||
co_delete(thread);
|
||||
thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (cothread_t)thread;
|
||||
return (cothread_t)thread;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t cothread) {
|
||||
if(cothread) {
|
||||
if(((cothread_struct*)cothread)->stack) {
|
||||
free(((cothread_struct*)cothread)->stack);
|
||||
}
|
||||
free(cothread);
|
||||
}
|
||||
void co_delete(cothread_t cothread)
|
||||
{
|
||||
if(cothread)
|
||||
{
|
||||
if(((cothread_struct*)cothread)->stack)
|
||||
free(((cothread_struct*)cothread)->stack);
|
||||
free(cothread);
|
||||
}
|
||||
}
|
||||
|
||||
void co_switch(cothread_t cothread) {
|
||||
if(!sigsetjmp(co_running->context, 0)) {
|
||||
co_running = (cothread_struct*)cothread;
|
||||
siglongjmp(co_running->context, 1);
|
||||
}
|
||||
void co_switch(cothread_t cothread)
|
||||
{
|
||||
if(!sigsetjmp(co_running->context, 0))
|
||||
{
|
||||
co_running = (cothread_struct*)cothread;
|
||||
siglongjmp(co_running->context, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+40
-26
@@ -28,38 +28,52 @@ extern "C" {
|
||||
static thread_local ucontext_t co_primary;
|
||||
static thread_local ucontext_t *co_running = 0;
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_running) co_running = &co_primary;
|
||||
return (cothread_t)co_running;
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_running)
|
||||
co_running = &co_primary;
|
||||
return (cothread_t)co_running;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
|
||||
if(!co_running) co_running = &co_primary;
|
||||
ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t));
|
||||
if(thread) {
|
||||
if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) {
|
||||
thread->uc_link = co_running;
|
||||
thread->uc_stack.ss_size = heapsize;
|
||||
makecontext(thread, coentry, 0);
|
||||
} else {
|
||||
co_delete((cothread_t)thread);
|
||||
thread = 0;
|
||||
}
|
||||
}
|
||||
return (cothread_t)thread;
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
||||
{
|
||||
if (!co_running)
|
||||
co_running = &co_primary;
|
||||
ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t));
|
||||
|
||||
if(thread)
|
||||
{
|
||||
if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize)))
|
||||
{
|
||||
thread->uc_link = co_running;
|
||||
thread->uc_stack.ss_size = heapsize;
|
||||
makecontext(thread, coentry, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
co_delete((cothread_t)thread);
|
||||
thread = 0;
|
||||
}
|
||||
}
|
||||
return (cothread_t)thread;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t cothread) {
|
||||
if(cothread) {
|
||||
if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); }
|
||||
free(cothread);
|
||||
}
|
||||
void co_delete(cothread_t cothread)
|
||||
{
|
||||
if (!cothread)
|
||||
return;
|
||||
|
||||
if(((ucontext_t*)cothread)->uc_stack.ss_sp)
|
||||
free(((ucontext_t*)cothread)->uc_stack.ss_sp);
|
||||
free(cothread);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t cothread) {
|
||||
ucontext_t *old_thread = co_running;
|
||||
co_running = (ucontext_t*)cothread;
|
||||
swapcontext(old_thread, co_running);
|
||||
void co_switch(cothread_t cothread)
|
||||
{
|
||||
ucontext_t *old_thread = co_running;
|
||||
|
||||
co_running = (ucontext_t*)cothread;
|
||||
swapcontext(old_thread, co_running);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+53
-39
@@ -32,60 +32,74 @@ static unsigned char co_swap_function[] = {
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <windows.h>
|
||||
|
||||
void co_init() {
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
void co_init(void)
|
||||
{
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function,
|
||||
sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void co_init() {
|
||||
unsigned long addr = (unsigned long)co_swap_function;
|
||||
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long size = (addr - base) + sizeof co_swap_function;
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
void co_init(void)
|
||||
{
|
||||
unsigned long addr = (unsigned long)co_swap_function;
|
||||
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long size = (addr - base) + sizeof co_swap_function;
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crash() {
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
static void crash(void)
|
||||
{
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if(!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
|
||||
cothread_t handle;
|
||||
if(!co_swap) {
|
||||
co_init();
|
||||
co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
size += 256; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
cothread_t handle;
|
||||
if(!co_swap)
|
||||
{
|
||||
co_init();
|
||||
co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
|
||||
if(handle = (cothread_t)malloc(size)) {
|
||||
long *p = (long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long)entrypoint; /* start of function */
|
||||
*(long*)handle = (long)p; /* stack pointer */
|
||||
}
|
||||
if(!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
|
||||
return handle;
|
||||
size += 256; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
if((handle = (cothread_t)malloc(size)))
|
||||
{
|
||||
long *p = (long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long)entrypoint; /* start of function */
|
||||
*(long*)handle = (long)p; /* stack pointer */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle) {
|
||||
free(handle);
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle) {
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+13
-34
@@ -6,6 +6,7 @@
|
||||
[a-z] = a b c d e f g h i j k l m n o p q r s t u v w x y z
|
||||
[0-9] = 0 1 2 3 4 5 6 7 8 9
|
||||
[markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ?
|
||||
# Some editors need this for proper syntax highlighting: '
|
||||
[all] = $([A-Z]) $([a-z]) $([0-9]) $([markup])
|
||||
[space] :=
|
||||
[space] +=
|
||||
@@ -15,54 +16,32 @@ ifeq ($(platform),)
|
||||
uname := $(shell uname -s)
|
||||
ifeq ($(uname),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
else ifneq ($(findstring Windows,$(uname)),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
else ifneq ($(findstring CYGWIN,$(uname)),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
else ifneq ($(findstring Darwin,$(uname)),)
|
||||
platform := macosx
|
||||
delete = rm -f $1
|
||||
else ifneq ($(findstring BSD,$(uname)),)
|
||||
platform := bsd
|
||||
delete = rm -f $1
|
||||
platform := osx
|
||||
else
|
||||
platform := linux
|
||||
delete = rm -f $1
|
||||
platform := unix
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
delete = del /F /Q $(subst /,\,$1)
|
||||
else
|
||||
delete = rm -f $1
|
||||
endif
|
||||
|
||||
# compiler detection
|
||||
ifeq ($(compiler),)
|
||||
ifeq ($(platform),windows)
|
||||
compiler := g++
|
||||
flags :=
|
||||
link :=
|
||||
else ifeq ($(platform),macosx)
|
||||
compiler := clang++
|
||||
flags := -w -stdlib=libc++
|
||||
link := -lc++ -lobjc
|
||||
else ifeq ($(platform),bsd)
|
||||
compiler := clang++
|
||||
flags := -w -I/usr/local/include
|
||||
compiler := $(CXX)
|
||||
else ifeq ($(platform),osx)
|
||||
compiler := clang++ -stdlib=libc++
|
||||
else
|
||||
compiler := g++
|
||||
flags :=
|
||||
link :=
|
||||
compiler := $(CXX)
|
||||
endif
|
||||
|
||||
cflags := -x c -std=c99
|
||||
objcflags := -x objective-c -std=c99
|
||||
cppflags := -x c++ -std=c++11
|
||||
objcppflags := -x objective-c++ -std=c++11
|
||||
endif
|
||||
|
||||
# cross-compilation support
|
||||
ifeq ($(arch),x86)
|
||||
flags := -m32 $(flags)
|
||||
link := -m32 $(link)
|
||||
endif
|
||||
|
||||
ifeq ($(prefix),)
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@ namespace nall {
|
||||
|
||||
constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
|
||||
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | (*s - '0')) :
|
||||
*s == '\'' ? binary_(s + 1, sum) :
|
||||
sum
|
||||
);
|
||||
@@ -15,7 +15,7 @@ constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
|
||||
|
||||
constexpr inline uintmax_t octal_(const char* s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
|
||||
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | (*s - '0')) :
|
||||
*s == '\'' ? octal_(s + 1, sum) :
|
||||
sum
|
||||
);
|
||||
@@ -31,9 +31,9 @@ constexpr inline uintmax_t decimal_(const char* s, uintmax_t sum = 0) {
|
||||
|
||||
constexpr inline uintmax_t hex_(const char* s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) :
|
||||
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) :
|
||||
*s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | *s - '0') :
|
||||
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | (*s - 'A' + 10)) :
|
||||
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | (*s - 'a' + 10)) :
|
||||
*s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | (*s - '0')) :
|
||||
*s == '\'' ? hex_(s + 1, sum) :
|
||||
sum
|
||||
);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#ifndef NALL_BIT_HPP
|
||||
#define NALL_BIT_HPP
|
||||
|
||||
// workaround for an infinite loop compiler bug in gcc7
|
||||
// https://github.com/libretro/bsnes-mercury/issues/47
|
||||
#if defined(PROFILE_ACCURACY)
|
||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#endif
|
||||
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -10,11 +16,24 @@ template<unsigned bits> inline uintmax_t uclamp(const uintmax_t x) {
|
||||
return y + ((x - y) & -(x < y)); //min(x, y);
|
||||
}
|
||||
|
||||
#if defined(PROFILE_ACCURACY)
|
||||
#if GCC_VERSION > 70000 && GCC_VERSION < 80101
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("no-strict-aliasing")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<unsigned bits> inline uintmax_t uclip(const uintmax_t x) {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return (x & m);
|
||||
}
|
||||
|
||||
#if defined(PROFILE_ACCURACY)
|
||||
#if GCC_VERSION > 70000 && GCC_VERSION < 80101
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<unsigned bits> inline intmax_t sclamp(const intmax_t x) {
|
||||
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
|
||||
return (x > m) ? m : (x < -b) ? -b : x;
|
||||
|
||||
+2
-2
@@ -187,7 +187,7 @@ private:
|
||||
struct dirent* ep;
|
||||
dp = opendir(pathname);
|
||||
if(dp) {
|
||||
while(ep = readdir(dp)) {
|
||||
while((ep = readdir(dp))) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
bool is_directory = ep->d_type & DT_DIR;
|
||||
@@ -212,7 +212,7 @@ private:
|
||||
struct dirent* ep;
|
||||
dp = opendir(pathname);
|
||||
if(dp) {
|
||||
while(ep = readdir(dp)) {
|
||||
while((ep = readdir(dp))) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
if((ep->d_type & DT_DIR) == 0) {
|
||||
|
||||
@@ -60,9 +60,15 @@ inline void library::close() {
|
||||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
static void junk_function() {}
|
||||
inline bool library::open(const string& name, const string& path) {
|
||||
if(handle) close();
|
||||
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endsWith("/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) {
|
||||
Dl_info info;
|
||||
dladdr((void*)&junk_function, &info);
|
||||
handle = (uintptr_t)dlopen(string(parentdir(info.dli_fname), "lib", name, ".dylib"), RTLD_LAZY);
|
||||
}
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ struct Resampler {
|
||||
virtual void clear() = 0;
|
||||
virtual void sample() = 0;
|
||||
Resampler(DSP& dsp) : dsp(dsp) {}
|
||||
virtual ~Resampler() {}
|
||||
};
|
||||
|
||||
struct DSP {
|
||||
|
||||
@@ -11,8 +11,11 @@ typedef float resample_samp_t;
|
||||
#if defined(__SSE__)
|
||||
#define SINCRESAMPLE_USE_SSE 1
|
||||
#ifndef __x86_64__
|
||||
#undef RESAMPLE_SSEREGPARM
|
||||
#define RESAMPLE_SSEREGPARM __attribute__((sseregparm))
|
||||
// clang may not have this extension (Apple's certainly doesn't)
|
||||
#ifndef __clang__
|
||||
#undef RESAMPLE_SSEREGPARM
|
||||
#define RESAMPLE_SSEREGPARM __attribute__((sseregparm))
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
// TODO: altivec here
|
||||
|
||||
+22
-5
@@ -9,6 +9,10 @@
|
||||
#include <nall/windows/utf8.hpp>
|
||||
#include <nall/stream/memory.hpp>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
namespace nall {
|
||||
|
||||
inline FILE* fopen_utf8(const string& filename, const string& mode) {
|
||||
@@ -191,10 +195,14 @@ struct file : varint {
|
||||
uintmax_t req_offset = file_offset;
|
||||
switch(index_) {
|
||||
case index::absolute: req_offset = offset; break;
|
||||
case index::relative: req_offset += offset; break;
|
||||
case index::relative:
|
||||
if (offset < 0 && -offset > req_offset)
|
||||
req_offset = 0; //cannot seek before start of file
|
||||
else
|
||||
req_offset += offset;
|
||||
break;
|
||||
}
|
||||
|
||||
if(req_offset < 0) req_offset = 0; //cannot seek before start of file
|
||||
if(req_offset > file_size) {
|
||||
if(file_mode == mode::read) { //cannot seek past end of file
|
||||
req_offset = file_size;
|
||||
@@ -232,7 +240,10 @@ struct file : varint {
|
||||
}
|
||||
|
||||
static bool exists(const string& filename) {
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__APPLE__) && TARGET_OS_IPHONE
|
||||
struct stat data;
|
||||
if(stat(filename, &data) != 0) return false;
|
||||
#elif !defined(_WIN32)
|
||||
struct stat data;
|
||||
if(stat(filename, &data) != 0) return false;
|
||||
#else
|
||||
@@ -244,7 +255,10 @@ struct file : varint {
|
||||
}
|
||||
|
||||
static uintmax_t size(const string& filename) {
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__APPLE__) && TARGET_OS_IPHONE
|
||||
struct stat data;
|
||||
if(stat(filename, &data) != 0) return false;
|
||||
#elif !defined(_WIN32)
|
||||
struct stat data;
|
||||
stat(filename, &data);
|
||||
#else
|
||||
@@ -255,7 +269,10 @@ struct file : varint {
|
||||
}
|
||||
|
||||
static time_t timestamp(const string& filename, file::time mode = file::time::create) {
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__APPLE__) && TARGET_OS_IPHONE
|
||||
struct stat data;
|
||||
if(stat(filename, &data) != 0) return false;
|
||||
#elif !defined(_WIN32)
|
||||
struct stat data;
|
||||
stat(filename, &data);
|
||||
#else
|
||||
|
||||
+9
-14
@@ -1,12 +1,10 @@
|
||||
#ifndef NALL_INTRINSICS_HPP
|
||||
#define NALL_INTRINSICS_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct Intrinsics {
|
||||
enum class Compiler : unsigned { Clang, GCC, VisualCPP, Unknown };
|
||||
enum class Platform : unsigned { Windows, MacOSX, X, Unknown }; //X = Linux, BSD, etc
|
||||
enum class Architecture : unsigned { x86, amd64, Unknown };
|
||||
enum class Architecture : unsigned { x86, amd64, ARM, aarch64, Unknown };
|
||||
enum class Endian : unsigned { LSB, MSB, Unknown };
|
||||
|
||||
static inline Compiler compiler();
|
||||
@@ -17,17 +15,13 @@ struct Intrinsics {
|
||||
|
||||
/* Compiler detection */
|
||||
|
||||
#if defined(__clang__)
|
||||
#define COMPILER_CLANG
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Clang; }
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(__GNUC__)
|
||||
#define COMPILER_GCC
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::GCC; }
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_VISUALCPP
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualCPP; }
|
||||
#else
|
||||
#warning "unable to detect compiler"
|
||||
#define COMPILER_UNKNOWN
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Unknown; }
|
||||
#endif
|
||||
@@ -44,7 +38,6 @@ struct Intrinsics {
|
||||
#define PLATFORM_X
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::X; }
|
||||
#else
|
||||
#warning "unable to detect platform"
|
||||
#define PLATFORM_UNKNOWN
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Unknown; }
|
||||
#endif
|
||||
@@ -57,26 +50,28 @@ struct Intrinsics {
|
||||
#elif defined(__amd64__) || defined(_M_AMD64)
|
||||
#define ARCH_AMD64
|
||||
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::amd64; }
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_AARCH64
|
||||
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::aarch64; }
|
||||
#elif defined(__arm__) || defined(__ARM_EABI__)
|
||||
#define ARCH_ARM
|
||||
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::ARM; }
|
||||
#else
|
||||
#warning "unable to detect architecture"
|
||||
#define ARCH_UNKNOWN
|
||||
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::Unknown; }
|
||||
#endif
|
||||
|
||||
/* Endian detection */
|
||||
|
||||
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
|
||||
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64) || defined(__ARM_EABI__) || defined(__arm__) || defined(__aarch64__)
|
||||
#define ENDIAN_LSB
|
||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::LSB; }
|
||||
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__powerpc__) || defined(_M_PPC)
|
||||
#define ENDIAN_MSB
|
||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; }
|
||||
#else
|
||||
#warning "unable to detect endian"
|
||||
#define ENDIAN_UNKNOWN
|
||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
-1
@@ -41,7 +41,11 @@ namespace Math {
|
||||
#undef interface
|
||||
#define dllexport __declspec(dllexport)
|
||||
#else
|
||||
#include <endian.h>
|
||||
#ifdef __linux__
|
||||
#include <endian.h>
|
||||
#else
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#define dllexport
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ struct serializer {
|
||||
|
||||
serializer() = default;
|
||||
serializer(const serializer& s) { operator=(s); }
|
||||
serializer(serializer&& s) { operator=(std::move(s)); }
|
||||
serializer(serializer&& s) { _data = nullptr; operator=(std::move(s)); }
|
||||
|
||||
serializer(unsigned capacity) {
|
||||
_mode = Save;
|
||||
|
||||
@@ -30,6 +30,7 @@ char* qstrlower(char* s) {
|
||||
if(quoted == false && *s >= 'A' && *s <= 'Z') *s += 0x20;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
char* qstrupper(char* s) {
|
||||
@@ -40,6 +41,7 @@ char* qstrupper(char* s) {
|
||||
if(quoted == false && *s >= 'a' && *s <= 'z') *s -= 0x20;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
char* strtr(char* dest, const char* before, const char* after) {
|
||||
|
||||
@@ -31,10 +31,9 @@ inline string evaluateExpression(Node* node) {
|
||||
}
|
||||
return result.rtrim<1>(", ").append(")");
|
||||
}
|
||||
default: throw "invalid operator";
|
||||
}
|
||||
#undef p
|
||||
|
||||
throw "invalid operator";
|
||||
}
|
||||
|
||||
inline int64_t evaluateInteger(Node* node) {
|
||||
@@ -87,10 +86,9 @@ inline int64_t evaluateInteger(Node* node) {
|
||||
case Node::Type::AssignBitwiseAnd: return p(0) & p(1);
|
||||
case Node::Type::AssignBitwiseOr: return p(0) | p(1);
|
||||
case Node::Type::AssignBitwiseXor: return p(0) ^ p(1);
|
||||
default: throw "invalid operator";
|
||||
}
|
||||
#undef p
|
||||
|
||||
throw "invalid operator";
|
||||
}
|
||||
|
||||
inline optional<int64_t> integer(const string& expression) {
|
||||
@@ -132,10 +130,10 @@ inline long double evaluateReal(Node* node) {
|
||||
case Node::Type::AssignDivide: return p(0) / p(1);
|
||||
case Node::Type::AssignAdd: return p(0) + p(1);
|
||||
case Node::Type::AssignSubtract: return p(0) - p(1);
|
||||
default: throw "invalid operator";
|
||||
}
|
||||
#undef p
|
||||
|
||||
throw "invalid operator";
|
||||
}
|
||||
|
||||
inline optional<long double> real(const string& expression) {
|
||||
|
||||
@@ -59,6 +59,7 @@ struct Node {
|
||||
case Comparator::LE: side = rule.split<1>("<="); break;
|
||||
case Comparator::GT: side = rule.split<1> (">"); break;
|
||||
case Comparator::GE: side = rule.split<1>(">="); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
string data = text();
|
||||
@@ -75,8 +76,10 @@ struct Node {
|
||||
case Comparator::LE: if(numeral(data) <= numeral(side(1))) continue; break;
|
||||
case Comparator::GT: if(numeral(data) > numeral(side(1))) continue; break;
|
||||
case Comparator::GE: if(numeral(data) >= numeral(side(1))) continue; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
higan
|
||||
*.a
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
@@ -17,6 +17,9 @@ bool ARM::condition(uint4 condition) {
|
||||
case 14: return true; //AL (always)
|
||||
case 15: return false; //NV (never)
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 ARM::bit(uint32 result) {
|
||||
@@ -59,7 +62,7 @@ uint32 ARM::lsl(uint32 source, uint8 shift) {
|
||||
carryout() = cpsr().c;
|
||||
if(shift == 0) return source;
|
||||
|
||||
carryout() = shift > 32 ? 0 : source & (1 << 32 - shift);
|
||||
carryout() = shift > 32 ? 0 : source & (1 << (32 - shift));
|
||||
source = shift > 31 ? 0 : source << shift;
|
||||
return source;
|
||||
}
|
||||
@@ -68,7 +71,7 @@ uint32 ARM::lsr(uint32 source, uint8 shift) {
|
||||
carryout() = cpsr().c;
|
||||
if(shift == 0) return source;
|
||||
|
||||
carryout() = shift > 32 ? 0 : source & (1 << shift - 1);
|
||||
carryout() = shift > 32 ? 0 : source & (1 << (shift - 1));
|
||||
source = shift > 31 ? 0 : source >> shift;
|
||||
return source;
|
||||
}
|
||||
@@ -77,7 +80,7 @@ uint32 ARM::asr(uint32 source, uint8 shift) {
|
||||
carryout() = cpsr().c;
|
||||
if(shift == 0) return source;
|
||||
|
||||
carryout() = shift > 32 ? source & (1 << 31) : source & (1 << shift - 1);
|
||||
carryout() = shift > 32 ? source & (1 << 31) : source & (1 << (shift - 1));
|
||||
source = shift > 31 ? (int32)source >> 31 : (int32)source >> shift;
|
||||
return source;
|
||||
}
|
||||
@@ -86,8 +89,8 @@ uint32 ARM::ror(uint32 source, uint8 shift) {
|
||||
carryout() = cpsr().c;
|
||||
if(shift == 0) return source;
|
||||
|
||||
if(shift &= 31)
|
||||
source = source << 32 - shift | source >> shift;
|
||||
if((shift &= 31))
|
||||
source = source << (32 - shift) | source >> shift;
|
||||
carryout() = source & (1 << 31);
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ void ARM::arm_op_data_register_shift() {
|
||||
if(mode == 0 ) rm = lsl(rm, rs < 33 ? rs : 33);
|
||||
if(mode == 1 ) rm = lsr(rm, rs < 33 ? rs : 33);
|
||||
if(mode == 2 ) rm = asr(rm, rs < 32 ? rs : 32);
|
||||
if(mode == 3 && rs) rm = ror(rm, rs & 31 == 0 ? 32 : rs & 31);
|
||||
if(mode == 3 && rs) rm = ror(rm, (rs & 31) == 0 ? 32 : rs & 31);
|
||||
|
||||
arm_opcode(rm);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ L rd.h = op_readlong(vectorN + 1);
|
||||
}
|
||||
|
||||
void R65816::op_stp() {
|
||||
while(regs.wai = true) {
|
||||
while((regs.wai = true)) {
|
||||
L op_io();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@ struct flag_t {
|
||||
+ (d << 3) + (i << 2) + (z << 1) + (c << 0);
|
||||
}
|
||||
|
||||
inline unsigned operator=(uint8 data) {
|
||||
inline unsigned assign(uint8 data) {
|
||||
n = data & 0x80; v = data & 0x40; m = data & 0x20; x = data & 0x10;
|
||||
d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01;
|
||||
return data;
|
||||
}
|
||||
|
||||
inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); }
|
||||
inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); }
|
||||
inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
|
||||
inline unsigned operator =(unsigned data) { return assign(data); }
|
||||
inline unsigned operator|=(unsigned data) { return assign(operator unsigned() | data); }
|
||||
inline unsigned operator^=(unsigned data) { return assign(operator unsigned() ^ data); }
|
||||
inline unsigned operator&=(unsigned data) { return assign(operator unsigned() & data); }
|
||||
|
||||
flag_t() : n(0), v(0), m(0), x(0), d(0), i(0), z(0), c(0) {}
|
||||
};
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
#include <X11/Xatom.h>
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
#define decimal CocoaDecimal
|
||||
#pragma push_macro("noinline")
|
||||
#undef noinline
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#pragma pop_macro("noinline")
|
||||
#undef decimal
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
@@ -35,18 +35,21 @@ struct pInputCarbon {
|
||||
group.input[inputID].value = value;
|
||||
}
|
||||
|
||||
void poll(vector<HID::Device*>& devices) {
|
||||
vector<HID::Device*> poll() {
|
||||
vector<HID::Device*> devices;
|
||||
KeyMap keymap;
|
||||
GetKeys(keymap);
|
||||
uint8_t* buffer = (uint8_t*)keymap;
|
||||
|
||||
unsigned inputID = 0;
|
||||
for(auto& key : keys) {
|
||||
bool value = buffer[key.id >> 3] & (1 << (key.id & 7)));
|
||||
bool value = buffer[key.id >> 3] & (1 << (key.id & 7));
|
||||
assign(kb.hid, HID::Keyboard::GroupID::Button, inputID++, value);
|
||||
}
|
||||
|
||||
devices.append(&kb.hid);
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
bool rumble(uint64_t id, bool enable) {
|
||||
|
||||
+11
-6
@@ -16,6 +16,7 @@ namespace ruby {
|
||||
|
||||
struct pVideoCGL : OpenGL {
|
||||
RubyVideoCGL* view;
|
||||
bool initialized;
|
||||
|
||||
struct {
|
||||
NSView* handle;
|
||||
@@ -144,21 +145,25 @@ struct pVideoCGL : OpenGL {
|
||||
}
|
||||
|
||||
clear();
|
||||
return true;
|
||||
return initialized = true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
OpenGL::term();
|
||||
if (initialized) {
|
||||
OpenGL::term();
|
||||
|
||||
@autoreleasepool {
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
view = nil;
|
||||
@autoreleasepool {
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
view = nil;
|
||||
}
|
||||
}
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
pVideoCGL() {
|
||||
view = nil;
|
||||
initialized = false;
|
||||
|
||||
settings.handle = nil;
|
||||
settings.synchronize = false;
|
||||
|
||||
+36
-33
@@ -9,22 +9,21 @@ sfc_objects += sfc-epsonrtc sfc-sharprtc
|
||||
sfc_objects += sfc-spc7110 sfc-sdd1 sfc-obc1
|
||||
sfc_objects += sfc-hsu1 sfc-msu1
|
||||
sfc_objects += sfc-satellaviewcart sfc-sufamiturbo
|
||||
objects += $(sfc_objects)
|
||||
|
||||
ifeq ($(profile),accuracy)
|
||||
flags += -DPROFILE_ACCURACY
|
||||
profflags := -DPROFILE_ACCURACY
|
||||
sfccpu := $(sfc)/cpu
|
||||
sfcsmp := $(sfc)/smp
|
||||
sfcdsp := $(sfc)/dsp
|
||||
sfcppu := $(sfc)/ppu
|
||||
else ifeq ($(profile),balanced)
|
||||
flags += -DPROFILE_BALANCED
|
||||
profflags := -DPROFILE_BALANCED
|
||||
sfccpu := $(sfc)/cpu
|
||||
sfcsmp := $(sfc)/smp
|
||||
sfcdsp := $(sfc)/alt/dsp
|
||||
sfcppu := $(sfc)/alt/ppu-balanced
|
||||
else ifeq ($(profile),performance)
|
||||
flags += -DPROFILE_PERFORMANCE
|
||||
profflags := -DPROFILE_PERFORMANCE
|
||||
sfccpu := $(sfc)/alt/cpu
|
||||
sfcsmp := $(sfc)/alt/smp
|
||||
sfcdsp := $(sfc)/alt/dsp
|
||||
@@ -33,40 +32,44 @@ else
|
||||
$(error unknown profile.)
|
||||
endif
|
||||
|
||||
obj/sfc-interface.o: $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface)
|
||||
obj/sfc-system.o: $(sfc)/system/system.cpp $(call rwildcard,$(sfc)/system/)
|
||||
obj/sfc-controller.o: $(sfc)/controller/controller.cpp $(call rwildcard,$(sfc)/controller/)
|
||||
obj/sfc-cartridge.o: $(sfc)/cartridge/cartridge.cpp $(sfc)/cartridge/*
|
||||
obj/sfc-cheat.o: $(sfc)/cheat/cheat.cpp $(sfc)/cheat/*
|
||||
obj/sfc-memory.o: $(sfc)/memory/memory.cpp $(call rwildcard,$(sfc)/memory/)
|
||||
obj/sfc-cpu.o: $(sfccpu)/cpu.cpp $(call rwildcard,$(sfccpu)/)
|
||||
obj/sfc-smp.o: $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/)
|
||||
obj/sfc-dsp.o: $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/)
|
||||
obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
|
||||
ifeq ($(sfc_lagfix),1)
|
||||
flags += -DSFC_LAGFIX
|
||||
endif
|
||||
|
||||
obj/sfc-satellaviewbase.o: $(sfc)/base/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/base/satellaview/)
|
||||
obj/sfc-interface-$(profile).o: $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface)
|
||||
obj/sfc-system-$(profile).o: $(sfc)/system/system.cpp $(call rwildcard,$(sfc)/system/)
|
||||
obj/sfc-controller-$(profile).o: $(sfc)/controller/controller.cpp $(call rwildcard,$(sfc)/controller/)
|
||||
obj/sfc-cartridge-$(profile).o: $(sfc)/cartridge/cartridge.cpp $(sfc)/cartridge/*
|
||||
obj/sfc-cheat-$(profile).o: $(sfc)/cheat/cheat.cpp $(sfc)/cheat/*
|
||||
obj/sfc-memory-$(profile).o: $(sfc)/memory/memory.cpp $(call rwildcard,$(sfc)/memory/)
|
||||
obj/sfc-cpu-$(profile).o: $(sfccpu)/cpu.cpp $(call rwildcard,$(sfccpu)/)
|
||||
obj/sfc-smp-$(profile).o: $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/)
|
||||
obj/sfc-dsp-$(profile).o: $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/)
|
||||
obj/sfc-ppu-$(profile).o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
|
||||
|
||||
obj/sfc-icd2.o: $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/)
|
||||
obj/sfc-bsx.o: $(sfc)/chip/bsx/bsx.cpp $(call rwildcard,$(sfc)/chip/bsx/)
|
||||
obj/sfc-nss.o: $(sfc)/chip/nss/nss.cpp $(call rwildcard,$(sfc)/chip/nss/)
|
||||
obj/sfc-event.o: $(sfc)/chip/event/event.cpp $(call rwildcard,$(sfc)/chip/event/)
|
||||
obj/sfc-satellaviewbase-$(profile).o: $(sfc)/base/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/base/satellaview/)
|
||||
|
||||
obj/sfc-sa1.o: $(sfc)/chip/sa1/sa1.cpp $(call rwildcard,$(sfc)/chip/sa1/)
|
||||
obj/sfc-superfx.o: $(sfc)/chip/superfx/superfx.cpp $(call rwildcard,$(sfc)/chip/superfx/)
|
||||
obj/sfc-icd2-$(profile).o: $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/)
|
||||
obj/sfc-bsx-$(profile).o: $(sfc)/chip/bsx/bsx.cpp $(call rwildcard,$(sfc)/chip/bsx/)
|
||||
obj/sfc-nss-$(profile).o: $(sfc)/chip/nss/nss.cpp $(call rwildcard,$(sfc)/chip/nss/)
|
||||
obj/sfc-event-$(profile).o: $(sfc)/chip/event/event.cpp $(call rwildcard,$(sfc)/chip/event/)
|
||||
|
||||
obj/sfc-armdsp.o: $(sfc)/chip/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/chip/armdsp/)
|
||||
obj/sfc-hitachidsp.o: $(sfc)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/chip/hitachidsp/)
|
||||
obj/sfc-necdsp.o: $(sfc)/chip/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/chip/necdsp/)
|
||||
obj/sfc-sa1-$(profile).o: $(sfc)/chip/sa1/sa1.cpp $(call rwildcard,$(sfc)/chip/sa1/)
|
||||
obj/sfc-superfx-$(profile).o: $(sfc)/chip/superfx/superfx.cpp $(call rwildcard,$(sfc)/chip/superfx/)
|
||||
|
||||
obj/sfc-epsonrtc.o: $(sfc)/chip/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/chip/epsonrtc/)
|
||||
obj/sfc-sharprtc.o: $(sfc)/chip/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/chip/sharprtc/)
|
||||
obj/sfc-armdsp-$(profile).o: $(sfc)/chip/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/chip/armdsp/)
|
||||
obj/sfc-hitachidsp-$(profile).o: $(sfc)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/chip/hitachidsp/)
|
||||
obj/sfc-necdsp-$(profile).o: $(sfc)/chip/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/chip/necdsp/)
|
||||
|
||||
obj/sfc-spc7110.o: $(sfc)/chip/spc7110/spc7110.cpp $(sfc)/chip/spc7110/*
|
||||
obj/sfc-sdd1.o: $(sfc)/chip/sdd1/sdd1.cpp $(sfc)/chip/sdd1/*
|
||||
obj/sfc-obc1.o: $(sfc)/chip/obc1/obc1.cpp $(sfc)/chip/obc1/*
|
||||
obj/sfc-epsonrtc-$(profile).o: $(sfc)/chip/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/chip/epsonrtc/)
|
||||
obj/sfc-sharprtc-$(profile).o: $(sfc)/chip/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/chip/sharprtc/)
|
||||
|
||||
obj/sfc-hsu1.o: $(sfc)/chip/hsu1/hsu1.cpp $(sfc)/chip/hsu1/*
|
||||
obj/sfc-msu1.o: $(sfc)/chip/msu1/msu1.cpp $(sfc)/chip/msu1/*
|
||||
obj/sfc-spc7110-$(profile).o: $(sfc)/chip/spc7110/spc7110.cpp $(sfc)/chip/spc7110/*
|
||||
obj/sfc-sdd1-$(profile).o: $(sfc)/chip/sdd1/sdd1.cpp $(sfc)/chip/sdd1/*
|
||||
obj/sfc-obc1-$(profile).o: $(sfc)/chip/obc1/obc1.cpp $(sfc)/chip/obc1/*
|
||||
|
||||
obj/sfc-satellaviewcart.o: $(sfc)/slot/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/slot/satellaview/)
|
||||
obj/sfc-sufamiturbo.o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/)
|
||||
obj/sfc-hsu1-$(profile).o: $(sfc)/chip/hsu1/hsu1.cpp $(sfc)/chip/hsu1/*
|
||||
obj/sfc-msu1-$(profile).o: $(sfc)/chip/msu1/msu1.cpp $(sfc)/chip/msu1/*
|
||||
|
||||
obj/sfc-satellaviewcart-$(profile).o: $(sfc)/slot/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/slot/satellaview/)
|
||||
obj/sfc-sufamiturbo-$(profile).o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/)
|
||||
@@ -139,6 +139,8 @@ void CPU::reset() {
|
||||
status.nmi_transition = false;
|
||||
status.nmi_pending = false;
|
||||
|
||||
status.frame_event_performed = false;
|
||||
|
||||
status.irq_valid = false;
|
||||
status.irq_line = false;
|
||||
status.irq_transition = false;
|
||||
|
||||
@@ -107,6 +107,8 @@ private:
|
||||
bool nmi_transition;
|
||||
bool nmi_pending;
|
||||
|
||||
bool frame_event_performed;
|
||||
|
||||
bool irq_valid;
|
||||
bool irq_line;
|
||||
bool irq_transition;
|
||||
|
||||
@@ -41,6 +41,8 @@ void CPU::serialize(serializer& s) {
|
||||
s.integer(status.nmi_transition);
|
||||
s.integer(status.nmi_pending);
|
||||
|
||||
s.integer(status.frame_event_performed);
|
||||
|
||||
s.integer(status.irq_valid);
|
||||
s.integer(status.irq_line);
|
||||
s.integer(status.irq_transition);
|
||||
|
||||
@@ -17,6 +17,12 @@ void CPU::last_cycle() {
|
||||
regs.wai = false;
|
||||
status.nmi_transition = false;
|
||||
status.nmi_pending = true;
|
||||
#ifdef SFC_LAGFIX
|
||||
if (!status.frame_event_performed) {
|
||||
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
status.frame_event_performed = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(status.irq_transition || regs.irq) {
|
||||
@@ -62,7 +68,7 @@ void CPU::scanline() {
|
||||
synchronize_smp();
|
||||
synchronize_ppu();
|
||||
synchronize_coprocessors();
|
||||
system.scanline();
|
||||
system.scanline(status.frame_event_performed);
|
||||
|
||||
if(vcounter() == 0) hdma_init();
|
||||
|
||||
@@ -79,6 +85,7 @@ void CPU::scanline() {
|
||||
if(status.nmi_enabled) status.nmi_transition = true;
|
||||
} else if(nmi_valid && !status.nmi_valid) {
|
||||
status.nmi_line = false;
|
||||
status.frame_event_performed = false;
|
||||
}
|
||||
|
||||
if(status.auto_joypad_poll_enabled && vcounter() == (ppu.overscan() == false ? 227 : 242)) {
|
||||
|
||||
@@ -34,7 +34,11 @@ void PPU::build_window_table(uint8 bg, bool screen) {
|
||||
}
|
||||
|
||||
if(regs.window1_enabled[bg] == true && regs.window2_enabled[bg] == false) {
|
||||
if(regs.window1_invert[bg] == true) set ^= clr ^= set ^= clr;
|
||||
if(regs.window1_invert[bg] == true) {
|
||||
bool tmp = set;
|
||||
set = clr;
|
||||
clr = tmp;
|
||||
}
|
||||
for(unsigned x = 0; x < 256; x++) {
|
||||
table[x] = (x >= window1_left && x <= window1_right) ? set : clr;
|
||||
}
|
||||
@@ -42,7 +46,11 @@ void PPU::build_window_table(uint8 bg, bool screen) {
|
||||
}
|
||||
|
||||
if(regs.window1_enabled[bg] == false && regs.window2_enabled[bg] == true) {
|
||||
if(regs.window2_invert[bg] == true) set ^= clr ^= set ^= clr;
|
||||
if(regs.window2_invert[bg] == true) {
|
||||
bool tmp = set;
|
||||
set = clr;
|
||||
clr = tmp;
|
||||
}
|
||||
for(unsigned x = 0; x < 256; x++) {
|
||||
table[x] = (x >= window2_left && x <= window2_right) ? set : clr;
|
||||
}
|
||||
|
||||
+3
@@ -109,6 +109,9 @@ uint8* PPU::Cache::tile(unsigned bpp, unsigned tile) {
|
||||
case 1: return tile_4bpp(tile);
|
||||
case 2: return tile_8bpp(tile);
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
PPU::Cache::Cache(PPU& self) : self(self) {
|
||||
|
||||
@@ -41,10 +41,10 @@ void PPU::LayerWindow::render(bool screen) {
|
||||
bool one_mask = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ^ one_invert;
|
||||
bool two_mask = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ^ two_invert;
|
||||
switch(mask) {
|
||||
case 0: output[x] = one_mask | two_mask == 1; break;
|
||||
case 1: output[x] = one_mask & two_mask == 1; break;
|
||||
case 2: output[x] = one_mask ^ two_mask == 1; break;
|
||||
case 3: output[x] = one_mask ^ two_mask == 0; break;
|
||||
case 0: output[x] = (one_mask | two_mask); break;
|
||||
case 1: output[x] = (one_mask & two_mask); break;
|
||||
case 2: output[x] = (one_mask ^ two_mask); break;
|
||||
case 3: output[x] = !(one_mask ^ two_mask); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,10 +87,10 @@ void PPU::ColorWindow::render(bool screen) {
|
||||
bool one_mask = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ^ one_invert;
|
||||
bool two_mask = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ^ two_invert;
|
||||
switch(mask) {
|
||||
case 0: output[x] = one_mask | two_mask == 1 ? set : clr; break;
|
||||
case 1: output[x] = one_mask & two_mask == 1 ? set : clr; break;
|
||||
case 2: output[x] = one_mask ^ two_mask == 1 ? set : clr; break;
|
||||
case 3: output[x] = one_mask ^ two_mask == 0 ? set : clr; break;
|
||||
case 0: output[x] = (one_mask | two_mask) ? set : clr; break;
|
||||
case 1: output[x] = (one_mask & two_mask) ? set : clr; break;
|
||||
case 2: output[x] = (one_mask ^ two_mask) ? set : clr; break;
|
||||
case 3: output[x] = !(one_mask ^ two_mask) ? set : clr; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ void SMP::op_write(uint16 addr, uint8 data) {
|
||||
|
||||
void SMP::op_step() {
|
||||
#define op_readpc() op_read(regs.pc++)
|
||||
#define op_readdp(addr) op_read((regs.p.p << 8) + addr)
|
||||
#define op_writedp(addr, data) op_write((regs.p.p << 8) + addr, data)
|
||||
#define op_readdp(addr) op_read((regs.p.p << 8) + (addr & 0xff))
|
||||
#define op_writedp(addr, data) op_write((regs.p.p << 8) + (addr & 0xff), data)
|
||||
#define op_readaddr(addr) op_read(addr)
|
||||
#define op_writeaddr(addr, data) op_write(addr, data)
|
||||
#define op_readstack() op_read(0x0100 | ++regs.sp)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <sfc/sfc.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#define CHEAT_CPP
|
||||
namespace SuperFamicom {
|
||||
|
||||
@@ -39,7 +39,7 @@ void ArmDSP::enter() {
|
||||
}
|
||||
|
||||
void ArmDSP::step(unsigned clocks) {
|
||||
if(bridge.timer && --bridge.timer == 0);
|
||||
if(bridge.timer) --bridge.timer;
|
||||
Coprocessor::step(clocks);
|
||||
synchronize_cpu();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ uint32 ArmDSP::bus_read(uint32 addr, uint32 size) {
|
||||
case Byte:
|
||||
return memory[addr];
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
};
|
||||
|
||||
switch(addr & 0xe0000000) {
|
||||
|
||||
@@ -31,6 +31,9 @@ void BSXCartridge::reset() {
|
||||
uint8 BSXCartridge::memory_access(bool write, Memory& memory, unsigned addr, uint8 data) {
|
||||
if(write == 0) return memory_read(memory, addr);
|
||||
memory_write(memory, addr, data);
|
||||
|
||||
// byuu returned nothing here (causing C++ to return 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 BSXCartridge::memory_read(Memory& memory, unsigned addr) {
|
||||
|
||||
@@ -165,6 +165,9 @@ uint8 EpsonRTC::read(unsigned addr) {
|
||||
if(addr == 2) {
|
||||
return ready << 7;
|
||||
}
|
||||
|
||||
// TODO: byuu returned nothing if addr == 3
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EpsonRTC::write(unsigned addr, uint8 data) {
|
||||
|
||||
@@ -38,7 +38,7 @@ uint8 HitachiDSP::dsp_read(unsigned addr) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
//Data RAM
|
||||
if((addr >= 0x0000 && addr <= 0x0bff) || (addr >= 0x1000 && addr <= 0x1bff)) {
|
||||
if(addr <= 0x0bff || (addr >= 0x1000 && addr <= 0x1bff)) {
|
||||
return dataRAM[addr & 0x0fff];
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
//Data RAM
|
||||
if((addr >= 0x0000 && addr <= 0x0bff) || (addr >= 0x1000 && addr <= 0x1bff)) {
|
||||
if(addr <= 0x0bff || (addr >= 0x1000 && addr <= 0x1bff)) {
|
||||
dataRAM[addr & 0x0fff] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,9 @@ uint8 MSU1::mmio_read(unsigned addr) {
|
||||
case 0x2006: return 'U';
|
||||
case 0x2007: return '1';
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MSU1::mmio_write(unsigned addr, uint8 data) {
|
||||
|
||||
@@ -32,16 +32,13 @@ void SA1::dma_normal() {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(mmio.dd) {
|
||||
case DMA::DestBWRAM:
|
||||
if (mmio.dd == DMA::DestBWRAM) {
|
||||
if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) {
|
||||
bus_write(dda, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case DMA::DestIRAM:
|
||||
} else {
|
||||
// mmio.dd == DMA::DestIRAM
|
||||
iram.write(dda & 0x07ff, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ uint8 SA1::vbr_read(unsigned addr) {
|
||||
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
|
||||
return iram.read(addr & 2047);
|
||||
}
|
||||
|
||||
// TODO: invalid address, what does real hardware do here?
|
||||
return 0;
|
||||
}
|
||||
|
||||
//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks)
|
||||
@@ -252,6 +255,9 @@ uint8 SA1::bitmap_read(unsigned addr) {
|
||||
case 3: return (bwram.read(addr) >> 6) & 3;
|
||||
}
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SA1::bitmap_write(unsigned addr, uint8 data) {
|
||||
|
||||
@@ -253,6 +253,9 @@ uint8 SDD1::Decomp::OL::decompress() {
|
||||
}
|
||||
return r1;
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
//core
|
||||
|
||||
@@ -50,6 +50,8 @@ uint8 SDD1::read(unsigned addr) {
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x4800: return sdd1_enable;
|
||||
case 0x4801: return xfer_enable;
|
||||
case 0x4804: return mmc[0] >> 20;
|
||||
case 0x4805: return mmc[1] >> 20;
|
||||
case 0x4806: return mmc[2] >> 20;
|
||||
|
||||
@@ -24,6 +24,9 @@ uint8 SuperFX::bus_read(unsigned addr) {
|
||||
}
|
||||
return ram.read(addr & ram_mask);
|
||||
}
|
||||
|
||||
// TODO: invalid address, what does real hardware do?
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SuperFX::bus_write(unsigned addr, uint8 data) {
|
||||
|
||||
@@ -33,17 +33,17 @@ void Controller::synchronize_cpu() {
|
||||
}
|
||||
|
||||
bool Controller::iobit() {
|
||||
switch(port) {
|
||||
case Controller::Port1: return cpu.pio() & 0x40;
|
||||
case Controller::Port2: return cpu.pio() & 0x80;
|
||||
}
|
||||
if (port == Controller::Port1)
|
||||
return cpu.pio() & 0x40;
|
||||
else
|
||||
return cpu.pio() & 0x80;
|
||||
}
|
||||
|
||||
void Controller::iobit(bool data) {
|
||||
switch(port) {
|
||||
case Controller::Port1: bus.write(0x4201, (cpu.pio() & ~0x40) | (data << 6)); break;
|
||||
case Controller::Port2: bus.write(0x4201, (cpu.pio() & ~0x80) | (data << 7)); break;
|
||||
}
|
||||
if (port == Controller::Port1)
|
||||
bus.write(0x4201, (cpu.pio() & ~0x40) | (data << 6));
|
||||
else
|
||||
bus.write(0x4201, (cpu.pio() & ~0x80) | (data << 7));
|
||||
}
|
||||
|
||||
Controller::Controller(bool port) : port(port) {
|
||||
|
||||
@@ -91,6 +91,9 @@ uint2 Justifier::data() {
|
||||
case 30: return 0;
|
||||
case 31: return 0;
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Justifier::latch(bool data) {
|
||||
|
||||
@@ -92,6 +92,9 @@ uint2 SuperScope::data() {
|
||||
case 6: return offscreen;
|
||||
case 7: return 0; //noise (1 = yes)
|
||||
}
|
||||
|
||||
// NOT REACHED
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SuperScope::latch(bool data) {
|
||||
|
||||
@@ -57,6 +57,8 @@ privileged:
|
||||
bool nmi_pending;
|
||||
bool nmi_hold;
|
||||
|
||||
bool frame_event_performed;
|
||||
|
||||
bool irq_valid;
|
||||
bool irq_line;
|
||||
bool irq_transition;
|
||||
|
||||
@@ -31,6 +31,8 @@ void CPU::serialize(serializer& s) {
|
||||
s.integer(status.nmi_pending);
|
||||
s.integer(status.nmi_hold);
|
||||
|
||||
s.integer(status.frame_event_performed);
|
||||
|
||||
s.integer(status.irq_valid);
|
||||
s.integer(status.irq_line);
|
||||
s.integer(status.irq_transition);
|
||||
|
||||
+17
-1
@@ -9,7 +9,16 @@ void CPU::poll_interrupts() {
|
||||
//NMI hold
|
||||
if(status.nmi_hold) {
|
||||
status.nmi_hold = false;
|
||||
if(status.nmi_enabled) status.nmi_transition = true;
|
||||
if(status.nmi_enabled)
|
||||
{
|
||||
status.nmi_transition = true;
|
||||
#ifdef SFC_LAGFIX
|
||||
if (!status.frame_event_performed) {
|
||||
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
status.frame_event_performed = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//NMI test
|
||||
@@ -21,6 +30,7 @@ void CPU::poll_interrupts() {
|
||||
} else if(status.nmi_valid && !nmi_valid) {
|
||||
//1->0 edge sensitive transition
|
||||
status.nmi_line = false;
|
||||
status.frame_event_performed = false;
|
||||
}
|
||||
status.nmi_valid = nmi_valid;
|
||||
|
||||
@@ -57,6 +67,12 @@ void CPU::nmitimen_update(uint8 data) {
|
||||
//0->1 edge sensitive transition
|
||||
if(!nmi_enabled && status.nmi_enabled && status.nmi_line) {
|
||||
status.nmi_transition = true;
|
||||
#ifdef SFC_LAGFIX
|
||||
if (!status.frame_event_performed) {
|
||||
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
status.frame_event_performed = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//?->1 level sensitive transition
|
||||
|
||||
@@ -44,7 +44,7 @@ void CPU::scanline() {
|
||||
synchronize_smp();
|
||||
synchronize_ppu();
|
||||
synchronize_coprocessors();
|
||||
system.scanline();
|
||||
system.scanline(status.frame_event_performed);
|
||||
|
||||
if(vcounter() == 0) {
|
||||
//HDMA init triggers once every frame
|
||||
@@ -180,6 +180,8 @@ void CPU::timing_reset() {
|
||||
status.nmi_pending = false;
|
||||
status.nmi_hold = false;
|
||||
|
||||
status.frame_event_performed = false;
|
||||
|
||||
status.irq_valid = false;
|
||||
status.irq_line = false;
|
||||
status.irq_transition = false;
|
||||
|
||||
@@ -272,6 +272,15 @@ void DSP::power() {
|
||||
voice[i].t_envx_out = 0;
|
||||
voice[i].hidden_env = 0;
|
||||
}
|
||||
|
||||
//note: memory is pseudo-random at startup; but internal state is less so
|
||||
//exact differences are unknown. need to separate memory from internal state
|
||||
for(unsigned r = 0; r < 0x80; r++) {
|
||||
state.regs[r] = 0x00;
|
||||
}
|
||||
REG(endx) = random(0x00);
|
||||
|
||||
REG(flg) = 0xe0;
|
||||
}
|
||||
|
||||
void DSP::reset() {
|
||||
|
||||
@@ -56,7 +56,8 @@ uint16 PPU::Screen::get_pixel_sub(bool hires) {
|
||||
priority = self.sprite.output.sub.priority;
|
||||
math.sub.color = get_color(self.sprite.output.sub.palette);
|
||||
}
|
||||
if(math.transparent = (priority == 0)) math.sub.color = get_color(0);
|
||||
math.transparent = (priority == 0);
|
||||
if(math.transparent) math.sub.color = get_color(0);
|
||||
|
||||
if(!hires) return 0;
|
||||
if(!math.sub.color_enable) return math.main.color_enable ? math.sub.color : 0;
|
||||
|
||||
@@ -20,10 +20,10 @@ void Input::connect(bool port, Input::Device id) {
|
||||
case Device::USART: controller = new USART(port); break;
|
||||
}
|
||||
|
||||
switch(port) {
|
||||
case Controller::Port1: configuration.controller_port1 = id; break;
|
||||
case Controller::Port2: configuration.controller_port2 = id; break;
|
||||
}
|
||||
if (port == Controller::Port1)
|
||||
configuration.controller_port1 = id;
|
||||
else
|
||||
configuration.controller_port2 = id;
|
||||
}
|
||||
|
||||
Input::Input() {
|
||||
|
||||
+11
-2
@@ -94,6 +94,9 @@ void System::term() {
|
||||
}
|
||||
|
||||
void System::load() {
|
||||
#ifdef __LIBRETRO__
|
||||
interface->loadRequest(ID::IPLROM, "");
|
||||
#else
|
||||
string manifest = string::read({interface->path(ID::System), "manifest.bml"});
|
||||
auto document = Markup::Document(manifest);
|
||||
|
||||
@@ -101,6 +104,7 @@ void System::load() {
|
||||
if(!file::exists({interface->path(ID::System), document["system/smp/rom/name"].data})) {
|
||||
interface->notify("Error: required Super Famicom firmware ipl.rom not found.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
region = configuration.region;
|
||||
expansion = configuration.expansion_port;
|
||||
@@ -236,9 +240,14 @@ void System::reset() {
|
||||
input.connect(1, configuration.controller_port2);
|
||||
}
|
||||
|
||||
void System::scanline() {
|
||||
void System::scanline(bool& frame_event_performed) {
|
||||
video.scanline();
|
||||
if(cpu.vcounter() == 241) scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
if(cpu.vcounter() == 241) {
|
||||
if(!frame_event_performed) {
|
||||
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
frame_event_performed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void System::frame() {
|
||||
|
||||
@@ -15,7 +15,7 @@ struct System : property<System> {
|
||||
void reset();
|
||||
|
||||
void frame();
|
||||
void scanline();
|
||||
void scanline(bool& frame_event_performed);
|
||||
|
||||
//return *active* system information (settings are cached upon power-on)
|
||||
readonly<Region> region;
|
||||
|
||||
@@ -33,8 +33,9 @@ void Video::generate_palette(Emulator::Interface::PaletteMode mode) {
|
||||
b = image::normalize(b, 5, 8);
|
||||
}
|
||||
|
||||
double L = (1.0 + l) / 16.0;
|
||||
if(l == 0) L *= 0.5;
|
||||
//luma=0 is not 100% black; but it's much darker than normal linear scaling
|
||||
//exact effect seems to be analog; requires > 24-bit color depth to represent accurately
|
||||
double L = (1.0 + l) / 16.0 * (l ? 1.0 : 0.25);
|
||||
unsigned R = L * image::normalize(r, 8, 16);
|
||||
unsigned G = L * image::normalize(g, 8, 16);
|
||||
unsigned B = L * image::normalize(b, 8, 16);
|
||||
@@ -121,6 +122,8 @@ void Video::update() {
|
||||
draw_cursor(0x02e0, device.player2.x, device.player2.y);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t* data = (uint32_t*)ppu.output;
|
||||
|
||||
@@ -43,6 +43,9 @@ link += $(rubylink)
|
||||
# rules
|
||||
objects := $(ui_objects) $(objects)
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
# sfc objects have your sfc profile setting in the filename
|
||||
sfc_objects := $(patsubst %,obj/%-$(profile).o,$(sfc_objects))
|
||||
objects += $(sfc_objects)
|
||||
|
||||
obj/ui-ethos.o: $(ui)/ethos.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-configuration.o: $(ui)/configuration/configuration.cpp $(call rwildcard,$(ui)/)
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
processors := arm hg51b upd96050 gsu r65816 spc700 lr35902
|
||||
include processor/Makefile
|
||||
|
||||
include sfc/Makefile
|
||||
include gb/Makefile
|
||||
output := libretro
|
||||
|
||||
core_installdir := $(prefix)/lib
|
||||
|
||||
ifeq ($(platform),linux)
|
||||
flags += -fPIC
|
||||
else ifeq ($(platform),osx)
|
||||
flags += -fPIC
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
|
||||
endif
|
||||
ifeq ($(platform),ios-arm64)
|
||||
flags += -arch arm64 -fPIC -isysroot $(IOSSDK) -marm -DHAVE_POSIX_MEMALIGN=1 -w -DIOS
|
||||
else
|
||||
flags += -arch armv7 -fPIC -isysroot $(IOSSDK) -marm -DHAVE_POSIX_MEMALIGN=1 -w -DIOS
|
||||
endif
|
||||
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
|
||||
flags += -miphoneos-version-min=8.0
|
||||
else
|
||||
flags += -miphoneos-version-min=5.0
|
||||
endif
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
|
||||
endif
|
||||
flags += -arch arm64 -fPIC -isysroot $(IOSSDK) -marm -DHAVE_POSIX_MEMALIGN=1 -w -DIOS
|
||||
endif
|
||||
|
||||
flags += -D__LIBRETRO__
|
||||
|
||||
GIT_VERSION ?= " $(shell git rev-parse --short HEAD || echo unknown)"
|
||||
ifneq ($(GIT_VERSION)," unknown")
|
||||
flags += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||
endif
|
||||
|
||||
#rules
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
sfc_objects += libretro
|
||||
sfc_objects := $(patsubst %,obj/%-$(profile).o,$(sfc_objects))
|
||||
objects += $(sfc_objects)
|
||||
|
||||
obj/libretro-$(profile).o: $(ui)/libretro.cpp $(ui)/*
|
||||
|
||||
#targets
|
||||
build: $(objects)
|
||||
ifeq ($(platform),linux)
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro.so -shared $(objects) -ldl -Wl,--no-undefined -Wl,--version-script=$(ui)/link.T
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
ifeq ($(platform),ios-arm64)
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro_ios.dylib -dynamiclib $(objects) -isysroot $(IOSSDK) -arch arm64
|
||||
else
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro_ios.dylib -dynamiclib $(objects) -isysroot $(IOSSDK) -arch armv7
|
||||
endif
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro_tvos.dylib -dynamiclib $(objects) -isysroot $(IOSSDK) -arch arm64
|
||||
else ifeq ($(platform),macosx)
|
||||
ifdef ($(NOUNIVERSAL))
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro.dylib -dynamiclib $(objects)
|
||||
else
|
||||
$(compiler) $(ARCHFLAGS) -o out/bsnes2014_$(profile)_libretro.dylib -dynamiclib $(objects)
|
||||
endif
|
||||
else ifeq ($(platform),windows)
|
||||
$(compiler) -o out/bsnes2014_$(profile)_libretro.dll -shared $(objects) -Wl,--no-undefined -Wl,--version-script=$(ui)/link.T -static-libgcc -static-libstdc++ -lws2_32
|
||||
else
|
||||
$(error invalid platform: $(platform). valid platforms are: windows linux macosx ios bsd)
|
||||
endif
|
||||
|
||||
install:
|
||||
ifeq ($(platform),linux)
|
||||
install -D -m 755 out/bsnes2014_$(profile)_libretro.so $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro.so
|
||||
else ifeq ($(platform),macosx)
|
||||
cp out/bsnes2014_$(profile)_libretro.dylib $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro.dylib
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
cp out/bsnes2014_$(profile)_libretro_ios.dylib $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro_ios.dylib
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
ifeq ($(platform),linux)
|
||||
rm $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro.so
|
||||
else ifeq ($(platform),macosx)
|
||||
rm $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro.dylib
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
rm $(DESTDIR)$(core_installdir)/bsnes2014_$(profile)_libretro_ios.dylib
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
CORE_DIR := $(LOCAL_PATH)/../..
|
||||
|
||||
ifeq ($(PROFILE),)
|
||||
PROFILE := performance
|
||||
endif
|
||||
|
||||
COREFLAGS := -fomit-frame-pointer -ffast-math -D__LIBRETRO__
|
||||
|
||||
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
|
||||
ifneq ($(GIT_VERSION)," unknown")
|
||||
COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||
endif
|
||||
|
||||
ifeq ($(PROFILE),performance)
|
||||
COREFLAGS += -DPROFILE_PERFORMANCE
|
||||
else ifeq ($(PROFILE),balanced)
|
||||
COREFLAGS += -DPROFILE_BALANCED
|
||||
else ifeq ($(PROFILE),accuracy) # If you're batshit insane
|
||||
COREFLAGS += -DPROFILE_ACCURACY
|
||||
endif
|
||||
|
||||
include $(CORE_DIR)/Makefile.common
|
||||
|
||||
COREFLAGS += $(INCFLAGS)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := retro
|
||||
LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C)
|
||||
LOCAL_CPPFLAGS := -std=c++11 $(COREFLAGS)
|
||||
LOCAL_CFLAGS := $(COREFLAGS)
|
||||
LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/target-libretro/link.T
|
||||
LOCAL_CPP_FEATURES := exceptions rtti
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -0,0 +1,2 @@
|
||||
APP_ABI := all
|
||||
APP_STL := c++_static
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,4 @@
|
||||
{
|
||||
global: retro_*;
|
||||
local: *;
|
||||
};
|
||||
Reference in new issue
Block a user