mirror of
https://github.com/libretro/Mu.git
synced 2026-02-13 13:45:21 +00:00
Compare commits
446 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45154c0c73 | ||
|
|
5e5e21e302 | ||
|
|
8223b6fd76 | ||
|
|
dee65d0d1a | ||
|
|
865acf3a28 | ||
|
|
15bb26daa5 | ||
|
|
dc854cef9e | ||
|
|
91a46734dd | ||
|
|
d0651a450d | ||
|
|
4a3fee96e7 | ||
|
|
4d084a03d7 | ||
|
|
aadb0a29ff | ||
|
|
90a9a94257 | ||
|
|
679626b58f | ||
|
|
1361da0401 | ||
|
|
c13324e9c7 | ||
|
|
9d23f9bb67 | ||
|
|
f16e54e879 | ||
|
|
2954a42bba | ||
|
|
b066eb856d | ||
|
|
be844bf74d | ||
|
|
7ead066572 | ||
|
|
304c0855c1 | ||
|
|
932f224580 | ||
|
|
6fd0600446 | ||
|
|
ebd397f5ba | ||
|
|
f631649bf7 | ||
|
|
5795ade531 | ||
|
|
ff746b8196 | ||
|
|
e053b170d2 | ||
|
|
df5a0c63bc | ||
|
|
d93c8c0efc | ||
|
|
62a7f6f2b3 | ||
|
|
e4209e1044 | ||
|
|
e140a25c5b | ||
|
|
3d408f3b37 | ||
|
|
5a7750163f | ||
|
|
c9af673bf4 | ||
|
|
cb2dcc1740 | ||
|
|
bda022c63a | ||
|
|
5022d08ffb | ||
|
|
95ebb37e5f | ||
|
|
ec3ba7e2cd | ||
|
|
41e0edcaa3 | ||
|
|
223255e2e1 | ||
|
|
1705a0ddd6 | ||
|
|
6ffa4d1d66 | ||
|
|
9057820fbc | ||
|
|
254212a229 | ||
|
|
87c8cfce6b | ||
|
|
96e70d964f | ||
|
|
855504f180 | ||
|
|
6870d8b7ab | ||
|
|
be386ff05d | ||
|
|
5a86c5ccf9 | ||
|
|
3e4829f443 | ||
|
|
f6c7944c64 | ||
|
|
d9437c28cb | ||
|
|
1a6d22086d | ||
|
|
46b29248dc | ||
|
|
e7da587071 | ||
|
|
4ac406874c | ||
|
|
c2ffd5a04a | ||
|
|
d29d1978ee | ||
|
|
f66e5613b3 | ||
|
|
865b1d5f86 | ||
|
|
815f061683 | ||
|
|
97f8f85021 | ||
|
|
e9385a62ab | ||
|
|
b18cc463b6 | ||
|
|
2ece2d56d4 | ||
|
|
4738d36119 | ||
|
|
4b836d98db | ||
|
|
c8c4539e6f | ||
|
|
aed3be3b80 | ||
|
|
c6df0303c8 | ||
|
|
126b2cf20f | ||
|
|
0c8e6fdebc | ||
|
|
daf0aede3d | ||
|
|
f768615984 | ||
|
|
c427a607ec | ||
|
|
aff2d76148 | ||
|
|
9d41480371 | ||
|
|
de8c733340 | ||
|
|
8d386d8027 | ||
|
|
3b009d7131 | ||
|
|
c303c7426b | ||
|
|
0372fdbaff | ||
|
|
863cd964bd | ||
|
|
a06d013f33 | ||
|
|
c08bdd573a | ||
|
|
4712e77413 | ||
|
|
57d19df30d | ||
|
|
dd09261b53 | ||
|
|
c72edbfa1b | ||
|
|
20348abf85 | ||
|
|
6b1e293c44 | ||
|
|
d0292b312f | ||
|
|
2b982cee22 | ||
|
|
2c072ded8a | ||
|
|
309f91312f | ||
|
|
4450ac9402 | ||
|
|
01bebf5418 | ||
|
|
4c7d34facf | ||
|
|
16924bb811 | ||
|
|
e9d6d21625 | ||
|
|
6b351c67fd | ||
|
|
7be8825f96 | ||
|
|
02778eeb08 | ||
|
|
f76abf87a1 | ||
|
|
0bb3287d6d | ||
|
|
64950ac431 | ||
|
|
85e9a03796 | ||
|
|
14e0d66101 | ||
|
|
eea4c328d2 | ||
|
|
9143759c29 | ||
|
|
9289232dd0 | ||
|
|
a2dbb98d88 | ||
|
|
fd572858e2 | ||
|
|
d5b6664c73 | ||
|
|
ff46e40ded | ||
|
|
f00cfd057b | ||
|
|
12ed98e68b | ||
|
|
e277ae8a3b | ||
|
|
80850117e6 | ||
|
|
09ae1544e4 | ||
|
|
c4e9edf702 | ||
|
|
dbf1341597 | ||
|
|
5af248eaef | ||
|
|
afa5b13d14 | ||
|
|
68c9e28c08 | ||
|
|
7962bee8bf | ||
|
|
e6535b546c | ||
|
|
696874b42a | ||
|
|
ab608e1d78 | ||
|
|
7ccef9020c | ||
|
|
65e12a2b7b | ||
|
|
7ab964efcb | ||
|
|
4129e74af0 | ||
|
|
8dcf19d2e1 | ||
|
|
aa196cb87f | ||
|
|
136cdca5d7 | ||
|
|
d4b9997d43 | ||
|
|
8de283a87d | ||
|
|
c860faa9e7 | ||
|
|
0d87bf2610 | ||
|
|
99da94a143 | ||
|
|
ca89c58c1a | ||
|
|
771856944b | ||
|
|
814d180642 | ||
|
|
ad53041077 | ||
|
|
6bfae8fcb2 | ||
|
|
9eb415c4ac | ||
|
|
632a57a38f | ||
|
|
430ebc01a0 | ||
|
|
cc882d2141 | ||
|
|
5ad9760c52 | ||
|
|
d67233cc8e | ||
|
|
07d8ee95f1 | ||
|
|
a6f3ec5c1f | ||
|
|
631111ce25 | ||
|
|
4237ae0eb8 | ||
|
|
07b4aa53a8 | ||
|
|
81bbcd20f0 | ||
|
|
58d59a9964 | ||
|
|
e601bf1e15 | ||
|
|
369b2ebaf4 | ||
|
|
bc47eee5c0 | ||
|
|
943dfb3b09 | ||
|
|
a23df8f79a | ||
|
|
e0c1cb9d6b | ||
|
|
7b6fcdb0e1 | ||
|
|
e70d84fac4 | ||
|
|
d67b44130a | ||
|
|
1567cbce67 | ||
|
|
3059dfda06 | ||
|
|
94f4c09d54 | ||
|
|
452d5030a1 | ||
|
|
1bb71d8aec | ||
|
|
0337882c4f | ||
|
|
33f7cb8948 | ||
|
|
51e405fc84 | ||
|
|
d0ccc7115f | ||
|
|
61602de392 | ||
|
|
29ca09302f | ||
|
|
4c8649da4e | ||
|
|
9723c83381 | ||
|
|
37f4b859aa | ||
|
|
7ba0cb5dca | ||
|
|
c95792b146 | ||
|
|
c111be3f64 | ||
|
|
b145a329c0 | ||
|
|
0ca5627ee3 | ||
|
|
a1fd0799be | ||
|
|
4fb3bed984 | ||
|
|
9ed1d0c21d | ||
|
|
1405e2a681 | ||
|
|
55013870ca | ||
|
|
912210695d | ||
|
|
5c89783ea0 | ||
|
|
c68fac77cc | ||
|
|
d0ca2655bb | ||
|
|
5c1547467b | ||
|
|
8e9ef22f42 | ||
|
|
892359f226 | ||
|
|
d46e146ae7 | ||
|
|
fc6b32d065 | ||
|
|
66f32cdb94 | ||
|
|
3601c471cf | ||
|
|
9384fc37a8 | ||
|
|
02fe7809ff | ||
|
|
5f3ace9b6b | ||
|
|
967c2f3ec1 | ||
|
|
99dfc62823 | ||
|
|
f0b9d524a6 | ||
|
|
80026cb33e | ||
|
|
5f1e8a53c1 | ||
|
|
b068d6ed53 | ||
|
|
b222b23bd0 | ||
|
|
7e0399ad17 | ||
|
|
f355c82d0b | ||
|
|
535c9254f6 | ||
|
|
4476697b4b | ||
|
|
92d6a857a8 | ||
|
|
6e8005cf56 | ||
|
|
eb4a241ef4 | ||
|
|
ec66577b53 | ||
|
|
41a305f0bd | ||
|
|
e9f7a40c53 | ||
|
|
b1914d9586 | ||
|
|
a63000884f | ||
|
|
5a38b67708 | ||
|
|
97e00aaef2 | ||
|
|
82c767a7a0 | ||
|
|
ab4788c921 | ||
|
|
c4eec6864b | ||
|
|
9b09d19e19 | ||
|
|
3de2c67cae | ||
|
|
1d693ae10d | ||
|
|
1b3336c9af | ||
|
|
4d88e893e0 | ||
|
|
2238274f51 | ||
|
|
5b93a54b2b | ||
|
|
c89da48739 | ||
|
|
b6093dc8ca | ||
|
|
48ba518086 | ||
|
|
372d23e534 | ||
|
|
125e85d73b | ||
|
|
d70e2b02b9 | ||
|
|
a2058e2d73 | ||
|
|
c7f8816541 | ||
|
|
6c53ade08b | ||
|
|
d8abf3643d | ||
|
|
a80b783c71 | ||
|
|
06acab1345 | ||
|
|
8482c98010 | ||
|
|
3c645bd0bd | ||
|
|
368757023c | ||
|
|
4d803c6fc0 | ||
|
|
cb9093c5f4 | ||
|
|
fa5f85e77c | ||
|
|
1b5f4d215f | ||
|
|
55a2e97bc5 | ||
|
|
0a58122f4b | ||
|
|
5a7191cd47 | ||
|
|
cee653b1a0 | ||
|
|
0bf5f9f981 | ||
|
|
23f943ce8b | ||
|
|
9e98f29215 | ||
|
|
ee7fd8e676 | ||
|
|
34e4b9ce7c | ||
|
|
4e7a08e6df | ||
|
|
ae6efb6b7b | ||
|
|
f1d1c3f051 | ||
|
|
03101a5214 | ||
|
|
f4a6d6c1b0 | ||
|
|
bb2698b498 | ||
|
|
48ff83d3af | ||
|
|
48d3983b72 | ||
|
|
f7f7b9d2d9 | ||
|
|
2244a1edd8 | ||
|
|
f7c1dacba4 | ||
|
|
47ba41fdc5 | ||
|
|
6df973a77c | ||
|
|
180a8ba97f | ||
|
|
84c0c40f36 | ||
|
|
8eae0b1ddd | ||
|
|
efc3b9ca77 | ||
|
|
4c27b1abb1 | ||
|
|
e1a9162cc9 | ||
|
|
71af4b89a5 | ||
|
|
65db73b129 | ||
|
|
2270e8f112 | ||
|
|
1b538a0bfe | ||
|
|
8cd5dcb446 | ||
|
|
1ec53c904a | ||
|
|
f2233197e4 | ||
|
|
432233d8f1 | ||
|
|
07af2b45ec | ||
|
|
d3540e3f77 | ||
|
|
6c144a3e85 | ||
|
|
f166dd173b | ||
|
|
f11fdcdf18 | ||
|
|
1b407a4497 | ||
|
|
81f0521165 | ||
|
|
79af40b61f | ||
|
|
182a188cda | ||
|
|
d34b0a0694 | ||
|
|
a40b29dca4 | ||
|
|
e6262335d9 | ||
|
|
c6174d335b | ||
|
|
c9138ec32a | ||
|
|
15d7d2dd54 | ||
|
|
424d07ce60 | ||
|
|
857b4bbed3 | ||
|
|
90ed900001 | ||
|
|
20400675fa | ||
|
|
850064d498 | ||
|
|
089090486c | ||
|
|
dc200683e2 | ||
|
|
33002e9fb3 | ||
|
|
992e1cda84 | ||
|
|
6ca82f22cc | ||
|
|
bdb445fb72 | ||
|
|
806c95b20b | ||
|
|
6b488b8817 | ||
|
|
e579e67b19 | ||
|
|
d31862b435 | ||
|
|
ea8a4fd618 | ||
|
|
68d45bb396 | ||
|
|
6b81ca4cc0 | ||
|
|
9b39360288 | ||
|
|
111220a17f | ||
|
|
f6bee9c9cf | ||
|
|
5f5ea20c66 | ||
|
|
60389c9a0e | ||
|
|
df49ff3a4c | ||
|
|
017797509e | ||
|
|
96919e3458 | ||
|
|
968cafda58 | ||
|
|
1b1346fa7e | ||
|
|
eb159b1e02 | ||
|
|
a1ee77c9a5 | ||
|
|
7f5c14baee | ||
|
|
89f50f88c5 | ||
|
|
419b18f170 | ||
|
|
930e4f314c | ||
|
|
89e193a091 | ||
|
|
fa98647959 | ||
|
|
11c392f8b6 | ||
|
|
dd8e8d2141 | ||
|
|
c5a094620a | ||
|
|
53b5ea1e6b | ||
|
|
e3dbfaf369 | ||
|
|
d936c13205 | ||
|
|
8d19f91487 | ||
|
|
f0d2b992da | ||
|
|
afa7462733 | ||
|
|
e034878ee0 | ||
|
|
b637a6495f | ||
|
|
97cd9bc543 | ||
|
|
7660f2e64b | ||
|
|
cd3acf4c98 | ||
|
|
338aa7ed4e | ||
|
|
d43d9c637f | ||
|
|
a51a549ecd | ||
|
|
7c0a2b0dde | ||
|
|
1543c35f49 | ||
|
|
0710c2cf26 | ||
|
|
31fbd559f5 | ||
|
|
57c24f55d6 | ||
|
|
0290174a7e | ||
|
|
5cc6f229c1 | ||
|
|
ff04a096b9 | ||
|
|
fb9bd5243d | ||
|
|
915e7d3247 | ||
|
|
42852dc331 | ||
|
|
1662655786 | ||
|
|
3f0e0baca0 | ||
|
|
d802e93681 | ||
|
|
142b8152d8 | ||
|
|
8dbc416bfd | ||
|
|
0cdf24711b | ||
|
|
3cb346bbbb | ||
|
|
a57d45862e | ||
|
|
c7dc657de5 | ||
|
|
a1dba7bb9f | ||
|
|
d39eb886f1 | ||
|
|
afb43ff3eb | ||
|
|
7c585bd242 | ||
|
|
d305fe4dfc | ||
|
|
fac89d59bb | ||
|
|
f9229590f5 | ||
|
|
64ec6f6e91 | ||
|
|
133484b0dc | ||
|
|
7b39db4782 | ||
|
|
8a990b2839 | ||
|
|
4f96b53bb1 | ||
|
|
6ba1e42926 | ||
|
|
424a0cb5a5 | ||
|
|
8304eb33f9 | ||
|
|
0b645f8d7e | ||
|
|
f02bba3755 | ||
|
|
1282d1b2b7 | ||
|
|
23b5fc6456 | ||
|
|
60b14cf79b | ||
|
|
def07b53d0 | ||
|
|
e885942603 | ||
|
|
bf2163b21d | ||
|
|
02033457de | ||
|
|
7e17a5a3e8 | ||
|
|
5d4df87b7c | ||
|
|
d16f495f1c | ||
|
|
7581114be6 | ||
|
|
84d96c29d7 | ||
|
|
fa7194f1f5 | ||
|
|
fad58ee6f3 | ||
|
|
32f440a26d | ||
|
|
6d2466cf3b | ||
|
|
e4625f1233 | ||
|
|
512dd785f6 | ||
|
|
e1ef2fe5a1 | ||
|
|
7238544735 | ||
|
|
b3c2d4c09b | ||
|
|
2d1fcbdfb9 | ||
|
|
bf65ad9b38 | ||
|
|
b39797da21 | ||
|
|
8b008aa575 | ||
|
|
20f1e8b2ed | ||
|
|
1ce59ac0f6 | ||
|
|
9761b9baca | ||
|
|
cdc74a654e | ||
|
|
4144f7c8b6 | ||
|
|
a9fbe45d52 | ||
|
|
6829ed6f81 | ||
|
|
f34256ba69 | ||
|
|
97397d49ee | ||
|
|
abb2e6526b | ||
|
|
adbd803dc9 | ||
|
|
d96c0ec8c4 | ||
|
|
6c37868055 | ||
|
|
b02fa8ba52 | ||
|
|
94b0baaf7f | ||
|
|
f8baa0eb85 | ||
|
|
538fd36c08 | ||
|
|
335997f19c |
27
.gitignore
vendored
27
.gitignore
vendored
@@ -3,7 +3,7 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.pro.user
|
||||
*.pro.user*
|
||||
*_emscripten.bc
|
||||
/libretroBuildSystem/obj
|
||||
/libretroBuildSystem/libs
|
||||
@@ -11,9 +11,30 @@
|
||||
/tools/palm/hwTestSuite/*.bin
|
||||
/tools/palm/hwTestSuite/*.grc
|
||||
/tools/palm/hwTestSuite/*.prc
|
||||
/tools/palm/hwTestSuite/armCode
|
||||
/tools/palm/hwTestSuite/TstSuite
|
||||
/tools/palm/hwTestSuite/TstSuite-sections.s
|
||||
/tools/palm/hwTestSuite/TstSuite-sections.ld
|
||||
/tools/desktop/build-BufferGraphViewer-*
|
||||
/tools/desktop/build-MakePalmIcon-*
|
||||
/tools/desktop/export16BitImageProperly/convert
|
||||
/tools/desktop/build-MakePalmBitmap-*
|
||||
/tools/desktop/export16BitImageProperly/convert
|
||||
|
||||
# CLion
|
||||
.idea/workspace.xml
|
||||
.idea/discord.xml
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
cmake-build-debug-mingw/
|
||||
cmake-build-release-mingw/
|
||||
cmake-build-debug-visual-studio/
|
||||
cmake-build-release-visual-studio/
|
||||
cmake-build-debug-visual-studio-1/
|
||||
cmake-build-release-visual-studio-1/
|
||||
|
||||
# Test ROM
|
||||
userdata-palmos41-en-m515.ram
|
||||
userdata-en-m515.ram
|
||||
palmos41-en-m515.rom
|
||||
default-palmos41-en-m515.ram
|
||||
259
.gitlab-ci.yml
Normal file
259
.gitlab-ci.yml
Normal file
@@ -0,0 +1,259 @@
|
||||
##############################################################################
|
||||
################################# BOILERPLATE ################################
|
||||
##############################################################################
|
||||
|
||||
# Core definitions
|
||||
.core-defs:
|
||||
variables:
|
||||
CORENAME: mu
|
||||
JNI_PATH: libretroBuildSystem
|
||||
MAKEFILE_PATH: libretroBuildSystem
|
||||
MAKEFILE: Makefile.libretro
|
||||
|
||||
# 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'
|
||||
|
||||
# Windows msvc10 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-x64-msvc10-msys2.yml'
|
||||
|
||||
# Windows msvc10 32-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-i686-msvc10-msys2.yml'
|
||||
|
||||
# Windows msvc05 32-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-i686-msvc05-msys2.yml'
|
||||
|
||||
# Linux 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-x64.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 9
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios9.yml'
|
||||
|
||||
# iOS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios-arm64.yml'
|
||||
|
||||
# tvOS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/tvos-arm64.yml'
|
||||
|
||||
################################## CONSOLES ################################
|
||||
# Dingux (GCW Zero)
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/dingux-mips32.yml'
|
||||
|
||||
# Nintendo 3DS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ctr-static.yml'
|
||||
|
||||
# Nintendo GameCube
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ngc-static.yml'
|
||||
|
||||
# Nintendo Wii
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/wii-static.yml'
|
||||
|
||||
# Nintendo WiiU
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/wiiu-static.yml'
|
||||
|
||||
# Nintendo Switch
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/libnx-static.yml'
|
||||
|
||||
# PLayStation 2
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ps2-static.yml'
|
||||
|
||||
# PlayStation Vita
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/vita-static.yml'
|
||||
|
||||
#################################### MISC ##################################
|
||||
# Emscripten
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/emscripten-static.yml'
|
||||
|
||||
# Stages for building
|
||||
stages:
|
||||
- build-prepare
|
||||
- build-shared
|
||||
- build-static
|
||||
|
||||
##############################################################################
|
||||
#################################### STAGES ##################################
|
||||
##############################################################################
|
||||
|
||||
################################### DESKTOPS #################################
|
||||
# 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
|
||||
|
||||
# Windows msvc10 64-bit
|
||||
libretro-build-windows-msvc10-x64:
|
||||
extends:
|
||||
- .libretro-windows-x64-msvc10-msys2-make-default
|
||||
- .core-defs
|
||||
|
||||
# Windows msvc10 32-bit
|
||||
libretro-build-windows-msvc10-i686:
|
||||
extends:
|
||||
- .libretro-windows-i686-msvc10-msys2-make-default
|
||||
- .core-defs
|
||||
|
||||
# Windows msvc05 32-bit
|
||||
libretro-build-windows-msvc05-i686:
|
||||
extends:
|
||||
- .libretro-windows-i686-msvc05-msys2-make-default
|
||||
- .core-defs
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64:
|
||||
extends:
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs
|
||||
|
||||
# MacOS 64-bit
|
||||
libretro-build-osx-x64:
|
||||
extends:
|
||||
- .libretro-osx-x64-make-default
|
||||
- .core-defs
|
||||
|
||||
# MacOS ARM 64-bit
|
||||
libretro-build-osx-arm64:
|
||||
extends:
|
||||
- .libretro-osx-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
################################### CELLULAR #################################
|
||||
# Android ARMv7a
|
||||
android-armeabi-v7a:
|
||||
extends:
|
||||
- .libretro-android-jni-armeabi-v7a
|
||||
- .core-defs
|
||||
|
||||
# Android ARMv8a
|
||||
android-arm64-v8a:
|
||||
extends:
|
||||
- .libretro-android-jni-arm64-v8a
|
||||
- .core-defs
|
||||
|
||||
# Android 64-bit x86
|
||||
android-x86_64:
|
||||
extends:
|
||||
- .libretro-android-jni-x86_64
|
||||
- .core-defs
|
||||
|
||||
# Android 32-bit x86
|
||||
android-x86:
|
||||
extends:
|
||||
- .libretro-android-jni-x86
|
||||
- .core-defs
|
||||
|
||||
# iOS 9
|
||||
libretro-build-ios9:
|
||||
extends:
|
||||
- .libretro-ios9-make-default
|
||||
- .core-defs
|
||||
|
||||
# iOS
|
||||
libretro-build-ios-arm64:
|
||||
extends:
|
||||
- .libretro-ios-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
# tvOS
|
||||
libretro-build-tvos-arm64:
|
||||
extends:
|
||||
- .libretro-tvos-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
################################### CONSOLES #################################
|
||||
# Dingux (GCW Zero)
|
||||
libretro-build-dingux-mips32:
|
||||
extends:
|
||||
- .libretro-dingux-mips32-make-default
|
||||
- .core-defs
|
||||
|
||||
# Nintendo 3DS
|
||||
libretro-build-ctr:
|
||||
extends:
|
||||
- .libretro-ctr-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# Nintendo GameCube
|
||||
libretro-build-ngc:
|
||||
extends:
|
||||
- .libretro-ngc-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# Nintendo Wii
|
||||
libretro-build-wii:
|
||||
extends:
|
||||
- .libretro-wii-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# Nintendo Wii U
|
||||
libretro-build-wiiu:
|
||||
extends:
|
||||
- .libretro-wiiu-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# Nintendo Switch
|
||||
libretro-build-libnx-aarch64:
|
||||
extends:
|
||||
- .libretro-libnx-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# PlayStation 2
|
||||
libretro-build-ps2:
|
||||
extends:
|
||||
- .libretro-ps2-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
# PlayStation Vita
|
||||
libretro-build-vita:
|
||||
extends:
|
||||
- .libretro-vita-static-retroarch-master
|
||||
- .core-defs
|
||||
|
||||
#################################### MISC ##################################
|
||||
# Emscripten
|
||||
libretro-build-emscripten:
|
||||
extends:
|
||||
- .libretro-emscripten-static-retroarch-master
|
||||
- .core-defs
|
||||
0
.idea/.gitignore
generated
vendored
Normal file
0
.idea/.gitignore
generated
vendored
Normal file
2
.idea/Mu.iml
generated
Normal file
2
.idea/Mu.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
19
.idea/misc.xml
generated
Normal file
19
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
<component name="CidrRootsConfiguration">
|
||||
<sourceRoots>
|
||||
<file path="$PROJECT_DIR$/include" />
|
||||
<file path="$PROJECT_DIR$/src" />
|
||||
</sourceRoots>
|
||||
<excludeRoots>
|
||||
<file path="$PROJECT_DIR$/.github" />
|
||||
<file path="$PROJECT_DIR$/.idea" />
|
||||
<file path="$PROJECT_DIR$/bugs" />
|
||||
<file path="$PROJECT_DIR$/cmake-build-debug-visual-studio-1" />
|
||||
<file path="$PROJECT_DIR$/debugDumps" />
|
||||
<file path="$PROJECT_DIR$/images" />
|
||||
<file path="$PROJECT_DIR$/tools" />
|
||||
</excludeRoots>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Mu.iml" filepath="$PROJECT_DIR$/.idea/Mu.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required (VERSION 3.13)
|
||||
project(Mu
|
||||
VERSION 1.3.2
|
||||
DESCRIPTION "Classic Palm OS Emulator."
|
||||
HOMEPAGE_URL https://github.com/libretro/Mu
|
||||
LANGUAGES C CXX)
|
||||
|
||||
# Requires C99
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
# To Emily...
|
||||
message("******************************")
|
||||
message("The continuation of the Mu along with the RetroArch Core is dedicated to")
|
||||
message("Emily (1998-2020), your friendship was very important to me and I hope")
|
||||
message("that you are resting well.")
|
||||
message(" -- Your friend, Stephanie")
|
||||
message("******************************")
|
||||
|
||||
# Main project sources
|
||||
add_subdirectory(src)
|
||||
|
||||
# LibRetro Build
|
||||
add_subdirectory(libretroBuildSystem)
|
||||
|
||||
# QT Build
|
||||
add_subdirectory(qtBuildSystem)
|
||||
334
LICENSE
Normal file
334
LICENSE
Normal file
@@ -0,0 +1,334 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
Attribution-NonCommercial 3.0 Unported
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
|
||||
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
|
||||
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Adaptation" means a work based upon the Work, or upon the Work and
|
||||
other pre-existing works, such as a translation, adaptation,
|
||||
derivative work, arrangement of music or other alterations of a
|
||||
literary or artistic work, or phonogram or performance and includes
|
||||
cinematographic adaptations or any other form in which the Work may be
|
||||
recast, transformed, or adapted including in any form recognizably
|
||||
derived from the original, except that a work that constitutes a
|
||||
Collection will not be considered an Adaptation for the purpose of
|
||||
this License. For the avoidance of doubt, where the Work is a musical
|
||||
work, performance or phonogram, the synchronization of the Work in
|
||||
timed-relation with a moving image ("synching") will be considered an
|
||||
Adaptation for the purpose of this License.
|
||||
b. "Collection" means a collection of literary or artistic works, such as
|
||||
encyclopedias and anthologies, or performances, phonograms or
|
||||
broadcasts, or other works or subject matter other than works listed
|
||||
in Section 1(f) below, which, by reason of the selection and
|
||||
arrangement of their contents, constitute intellectual creations, in
|
||||
which the Work is included in its entirety in unmodified form along
|
||||
with one or more other contributions, each constituting separate and
|
||||
independent works in themselves, which together are assembled into a
|
||||
collective whole. A work that constitutes a Collection will not be
|
||||
considered an Adaptation (as defined above) for the purposes of this
|
||||
License.
|
||||
c. "Distribute" means to make available to the public the original and
|
||||
copies of the Work or Adaptation, as appropriate, through sale or
|
||||
other transfer of ownership.
|
||||
d. "Licensor" means the individual, individuals, entity or entities that
|
||||
offer(s) the Work under the terms of this License.
|
||||
e. "Original Author" means, in the case of a literary or artistic work,
|
||||
the individual, individuals, entity or entities who created the Work
|
||||
or if no individual or entity can be identified, the publisher; and in
|
||||
addition (i) in the case of a performance the actors, singers,
|
||||
musicians, dancers, and other persons who act, sing, deliver, declaim,
|
||||
play in, interpret or otherwise perform literary or artistic works or
|
||||
expressions of folklore; (ii) in the case of a phonogram the producer
|
||||
being the person or legal entity who first fixes the sounds of a
|
||||
performance or other sounds; and, (iii) in the case of broadcasts, the
|
||||
organization that transmits the broadcast.
|
||||
f. "Work" means the literary and/or artistic work offered under the terms
|
||||
of this License including without limitation any production in the
|
||||
literary, scientific and artistic domain, whatever may be the mode or
|
||||
form of its expression including digital form, such as a book,
|
||||
pamphlet and other writing; a lecture, address, sermon or other work
|
||||
of the same nature; a dramatic or dramatico-musical work; a
|
||||
choreographic work or entertainment in dumb show; a musical
|
||||
composition with or without words; a cinematographic work to which are
|
||||
assimilated works expressed by a process analogous to cinematography;
|
||||
a work of drawing, painting, architecture, sculpture, engraving or
|
||||
lithography; a photographic work to which are assimilated works
|
||||
expressed by a process analogous to photography; a work of applied
|
||||
art; an illustration, map, plan, sketch or three-dimensional work
|
||||
relative to geography, topography, architecture or science; a
|
||||
performance; a broadcast; a phonogram; a compilation of data to the
|
||||
extent it is protected as a copyrightable work; or a work performed by
|
||||
a variety or circus performer to the extent it is not otherwise
|
||||
considered a literary or artistic work.
|
||||
g. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this License with
|
||||
respect to the Work, or who has received express permission from the
|
||||
Licensor to exercise rights under this License despite a previous
|
||||
violation.
|
||||
h. "Publicly Perform" means to perform public recitations of the Work and
|
||||
to communicate to the public those public recitations, by any means or
|
||||
process, including by wire or wireless means or public digital
|
||||
performances; to make available to the public Works in such a way that
|
||||
members of the public may access these Works from a place and at a
|
||||
place individually chosen by them; to perform the Work to the public
|
||||
by any means or process and the communication to the public of the
|
||||
performances of the Work, including by public digital performance; to
|
||||
broadcast and rebroadcast the Work by any means including signs,
|
||||
sounds or images.
|
||||
i. "Reproduce" means to make copies of the Work by any means including
|
||||
without limitation by sound or visual recordings and the right of
|
||||
fixation and reproducing fixations of the Work, including storage of a
|
||||
protected performance or phonogram in digital form or other electronic
|
||||
medium.
|
||||
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
|
||||
limit, or restrict any uses free from copyright or rights arising from
|
||||
limitations or exceptions that are provided for in connection with the
|
||||
copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
perpetual (for the duration of the applicable copyright) license to
|
||||
exercise the rights in the Work as stated below:
|
||||
|
||||
a. to Reproduce the Work, to incorporate the Work into one or more
|
||||
Collections, and to Reproduce the Work as incorporated in the
|
||||
Collections;
|
||||
b. to create and Reproduce Adaptations provided that any such Adaptation,
|
||||
including any translation in any medium, takes reasonable steps to
|
||||
clearly label, demarcate or otherwise identify that changes were made
|
||||
to the original Work. For example, a translation could be marked "The
|
||||
original work was translated from English to Spanish," or a
|
||||
modification could indicate "The original work has been modified.";
|
||||
c. to Distribute and Publicly Perform the Work including as incorporated
|
||||
in Collections; and,
|
||||
d. to Distribute and Publicly Perform Adaptations.
|
||||
|
||||
The above rights may be exercised in all media and formats whether now
|
||||
known or hereafter devised. The above rights include the right to make
|
||||
such modifications as are technically necessary to exercise the rights in
|
||||
other media and formats. Subject to Section 8(f), all rights not expressly
|
||||
granted by Licensor are hereby reserved, including but not limited to the
|
||||
rights set forth in Section 4(d).
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made
|
||||
subject to and limited by the following restrictions:
|
||||
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms
|
||||
of this License. You must include a copy of, or the Uniform Resource
|
||||
Identifier (URI) for, this License with every copy of the Work You
|
||||
Distribute or Publicly Perform. You may not offer or impose any terms
|
||||
on the Work that restrict the terms of this License or the ability of
|
||||
the recipient of the Work to exercise the rights granted to that
|
||||
recipient under the terms of the License. You may not sublicense the
|
||||
Work. You must keep intact all notices that refer to this License and
|
||||
to the disclaimer of warranties with every copy of the Work You
|
||||
Distribute or Publicly Perform. When You Distribute or Publicly
|
||||
Perform the Work, You may not impose any effective technological
|
||||
measures on the Work that restrict the ability of a recipient of the
|
||||
Work from You to exercise the rights granted to that recipient under
|
||||
the terms of the License. This Section 4(a) applies to the Work as
|
||||
incorporated in a Collection, but this does not require the Collection
|
||||
apart from the Work itself to be made subject to the terms of this
|
||||
License. If You create a Collection, upon notice from any Licensor You
|
||||
must, to the extent practicable, remove from the Collection any credit
|
||||
as required by Section 4(c), as requested. If You create an
|
||||
Adaptation, upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Adaptation any credit as required by
|
||||
Section 4(c), as requested.
|
||||
b. You may not exercise any of the rights granted to You in Section 3
|
||||
above in any manner that is primarily intended for or directed toward
|
||||
commercial advantage or private monetary compensation. The exchange of
|
||||
the Work for other copyrighted works by means of digital file-sharing
|
||||
or otherwise shall not be considered to be intended for or directed
|
||||
toward commercial advantage or private monetary compensation, provided
|
||||
there is no payment of any monetary compensation in connection with
|
||||
the exchange of copyrighted works.
|
||||
c. If You Distribute, or Publicly Perform the Work or any Adaptations or
|
||||
Collections, You must, unless a request has been made pursuant to
|
||||
Section 4(a), keep intact all copyright notices for the Work and
|
||||
provide, reasonable to the medium or means You are utilizing: (i) the
|
||||
name of the Original Author (or pseudonym, if applicable) if supplied,
|
||||
and/or if the Original Author and/or Licensor designate another party
|
||||
or parties (e.g., a sponsor institute, publishing entity, journal) for
|
||||
attribution ("Attribution Parties") in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party
|
||||
or parties; (ii) the title of the Work if supplied; (iii) to the
|
||||
extent reasonably practicable, the URI, if any, that Licensor
|
||||
specifies to be associated with the Work, unless such URI does not
|
||||
refer to the copyright notice or licensing information for the Work;
|
||||
and, (iv) consistent with Section 3(b), in the case of an Adaptation,
|
||||
a credit identifying the use of the Work in the Adaptation (e.g.,
|
||||
"French translation of the Work by Original Author," or "Screenplay
|
||||
based on original Work by Original Author"). The credit required by
|
||||
this Section 4(c) may be implemented in any reasonable manner;
|
||||
provided, however, that in the case of a Adaptation or Collection, at
|
||||
a minimum such credit will appear, if a credit for all contributing
|
||||
authors of the Adaptation or Collection appears, then as part of these
|
||||
credits and in a manner at least as prominent as the credits for the
|
||||
other contributing authors. For the avoidance of doubt, You may only
|
||||
use the credit required by this Section for the purpose of attribution
|
||||
in the manner set out above and, by exercising Your rights under this
|
||||
License, You may not implicitly or explicitly assert or imply any
|
||||
connection with, sponsorship or endorsement by the Original Author,
|
||||
Licensor and/or Attribution Parties, as appropriate, of You or Your
|
||||
use of the Work, without the separate, express prior written
|
||||
permission of the Original Author, Licensor and/or Attribution
|
||||
Parties.
|
||||
d. For the avoidance of doubt:
|
||||
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme cannot be waived, the Licensor
|
||||
reserves the exclusive right to collect such royalties for any
|
||||
exercise by You of the rights granted under this License;
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme can be waived, the Licensor reserves
|
||||
the exclusive right to collect such royalties for any exercise by
|
||||
You of the rights granted under this License if Your exercise of
|
||||
such rights is for a purpose or use which is otherwise than
|
||||
noncommercial as permitted under Section 4(b) and otherwise waives
|
||||
the right to collect royalties through any statutory or compulsory
|
||||
licensing scheme; and,
|
||||
iii. Voluntary License Schemes. The Licensor reserves the right to
|
||||
collect royalties, whether individually or, in the event that the
|
||||
Licensor is a member of a collecting society that administers
|
||||
voluntary licensing schemes, via that society, from any exercise
|
||||
by You of the rights granted under this License that is for a
|
||||
purpose or use which is otherwise than noncommercial as permitted
|
||||
under Section 4(c).
|
||||
e. Except as otherwise agreed in writing by the Licensor or as may be
|
||||
otherwise permitted by applicable law, if You Reproduce, Distribute or
|
||||
Publicly Perform the Work either by itself or as part of any
|
||||
Adaptations or Collections, You must not distort, mutilate, modify or
|
||||
take other derogatory action in relation to the Work which would be
|
||||
prejudicial to the Original Author's honor or reputation. Licensor
|
||||
agrees that in those jurisdictions (e.g. Japan), in which any exercise
|
||||
of the right granted in Section 3(b) of this License (the right to
|
||||
make Adaptations) would be deemed to be a distortion, mutilation,
|
||||
modification or other derogatory action prejudicial to the Original
|
||||
Author's honor and reputation, the Licensor will waive or not assert,
|
||||
as appropriate, this Section, to the fullest extent permitted by the
|
||||
applicable national law, to enable You to reasonably exercise Your
|
||||
right under Section 3(b) of this License (right to make Adaptations)
|
||||
but not otherwise.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
|
||||
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
|
||||
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
|
||||
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
|
||||
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
||||
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
|
||||
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
||||
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
|
||||
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this License.
|
||||
Individuals or entities who have received Adaptations or Collections
|
||||
from You under this License, however, will not have their licenses
|
||||
terminated provided such individuals or entities remain in full
|
||||
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
|
||||
survive any termination of this License.
|
||||
b. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the
|
||||
Work under different license terms or to stop distributing the Work at
|
||||
any time; provided, however that any such election will not serve to
|
||||
withdraw this License (or any other license that has been, or is
|
||||
required to be, granted under the terms of this License), and this
|
||||
License will continue in full force and effect unless terminated as
|
||||
stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection,
|
||||
the Licensor offers to the recipient a license to the Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
|
||||
offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
c. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this License, and without further action
|
||||
by the parties to this agreement, such provision shall be reformed to
|
||||
the minimum extent necessary to make such provision valid and
|
||||
enforceable.
|
||||
d. No term or provision of this License shall be deemed waived and no
|
||||
breach consented to unless such waiver or consent shall be in writing
|
||||
and signed by the party to be charged with such waiver or consent.
|
||||
e. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings,
|
||||
agreements or representations with respect to the Work not specified
|
||||
here. Licensor shall not be bound by any additional provisions that
|
||||
may appear in any communication from You. This License may not be
|
||||
modified without the mutual written agreement of the Licensor and You.
|
||||
f. The rights granted under, and the subject matter referenced, in this
|
||||
License were drafted utilizing the terminology of the Berne Convention
|
||||
for the Protection of Literary and Artistic Works (as amended on
|
||||
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
|
||||
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
|
||||
and the Universal Copyright Convention (as revised on July 24, 1971).
|
||||
These rights and subject matter take effect in the relevant
|
||||
jurisdiction in which the License terms are sought to be enforced
|
||||
according to the corresponding provisions of the implementation of
|
||||
those treaty provisions in the applicable national law. If the
|
||||
standard suite of rights granted under applicable copyright law
|
||||
includes additional rights not granted under this License, such
|
||||
additional rights are deemed to be included in the License; this
|
||||
License is not intended to restrict the license of any rights under
|
||||
applicable law.
|
||||
|
||||
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, Creative Commons does not authorize
|
||||
the use by either party of the trademark "Creative Commons" or any
|
||||
related trademark or logo of Creative Commons without the prior
|
||||
written consent of Creative Commons. Any permitted use will be in
|
||||
compliance with Creative Commons' then-current trademark usage
|
||||
guidelines, as may be published on its website or otherwise made
|
||||
available upon request from time to time. For the avoidance of doubt,
|
||||
this trademark restriction does not form part of the License.
|
||||
|
||||
Creative Commons may be contacted at https://creativecommons.org/.
|
||||
7
bugs/accidentalFinds.txt
Normal file
7
bugs/accidentalFinds.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Bugs in other peoples code I found while writing Mu, haven't followed up on them yet:
|
||||
(RetroArch)RETRO_ENVIRONMENT_GET_MIDI_INTERFACE states its passed a pointer to a pointer but its just a pointer to a struct
|
||||
(RetroArch)"led_driver" setting is not exposed to GUI
|
||||
(RetroArch)retro_set_environment will sometimes be called multiple times and provide invalid values fetching environment variables on the subsequent calls, this will cause function pointers to be corrupted if they are not checked for validity first
|
||||
QT will clobber object files when there are 2 source files with the same name even if they are in different folders
|
||||
|
||||
Fixed:
|
||||
@@ -1,9 +1,10 @@
|
||||
Lakka(needs makefile)
|
||||
classics/new haxchi(should work)
|
||||
xbox(don't know)
|
||||
xbox360(don't know)
|
||||
Android armv5/6, the NDK dropped support for them and they broke when the buildbot was updated
|
||||
|
||||
Fixed:
|
||||
classics/new haxchi
|
||||
PSP
|
||||
msvc2010
|
||||
msvc2003
|
||||
|
||||
5
bugs/currentBug.txt
Normal file
5
bugs/currentBug.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
T3 locks up endlessly checking TSC2101 interrupts
|
||||
QT release build is broken
|
||||
|
||||
Fixed:
|
||||
68K Palm OS randomly locks up for 1-2 seconds(caused by interrupt handling code not turning the CPU back on for masked interrupts when it should because of faulty interrupt cacheing, Caused by commit: 1567cbce674741bc13be92b0847f59a5cc68335a)
|
||||
@@ -1,18 +0,0 @@
|
||||
0x9bdfeacc 0f 10 08 e2 and r1, r8, #15
|
||||
0x9bdfead0 <+0x0004> 01 11 d7 e7 ldrb r1, [r7, r1, lsl #2]
|
||||
0x9bdfead4 <+0x0008> 01 2c b0 e1 lsls r2, r1, #24
|
||||
0x9bdfead8 <+0x000c> 02 a1 02 e2 and r10, r2, #-2147483648 ; 0x80000000
|
||||
0x9bdfeadc <+0x0010> 01 a1 8a 03 orreq r10, r10, #1073741824 ; 0x40000000
|
||||
0x9bdfeae0 <+0x0014> 1e 2c 08 e2 and r2, r8, #7680 ; 0x1e00
|
||||
0x9bdfeae4 <+0x0018> a2 03 97 e7 ldr r0, [r7, r2, lsr #7]
|
||||
0x9bdfeae8 <+0x001c> 01 30 80 e2 add r3, r0, #1
|
||||
0x9bdfeaec <+0x0020> a2 33 87 e7 str r3, [r7, r2, lsr #7]
|
||||
0x9bdfeaf0 <+0x0024> 0f e0 a0 e1 mov lr, pc
|
||||
0x9bdfeaf4 <+0x0028> 74 f0 97 e5 ldr pc, [r7, #116] ; 0x74
|
||||
0x9bdfeaf8 <+0x002c> b2 80 d4 e0 ldrh r8, [r4], #2
|
||||
0x9bdfeafc <+0x0030> 08 50 55 e2 subs r5, r5, #8
|
||||
0x9bdfeb00 <+0x0034> 08 f1 96 c7 ldrgt pc, [r6, r8, lsl #2]
|
||||
0x9bdfeb04 <+0x0038> a3 fb ff ea b 0x9bdfd998 <CycloneEnd>
|
||||
|
||||
Crashed with SIGSEGV
|
||||
When compiled in release mode crashes with SIGILL
|
||||
@@ -1,87 +0,0 @@
|
||||
The datasheet states:
|
||||
When external interrupts INT[3:0], IRQ1, IRQ2, IRQ3, and IRQ6 are programmed as edge-triggered interrupts, they can be cleared by writing a 1 to the corresponding status bit in the interrupt status register in the interrupt controller. When programmed as level-triggered interrupts, these interrupts are cleared at the requesting sources.
|
||||
|
||||
But all attempts to use the INT* pins as edge triggered have failed and they continue as level triggered
|
||||
|
||||
PDIUSBD12 uses CSA1 and CPU A1 as USB A0
|
||||
|
||||
All of the interrupt signals in the table can be used as system wake-up interrupts, except for the edge interrupt on INT[3:0]. Edge interrupts on INT[3:0] can only interrupt the CPU when the system is awake. The INT[3:0] signals are all level 4 interrupts, but IRQx has its own level. Any combination of Port D signals and OR (negative logic) can be selected to generate keyboard (KB) interrupts to the CPU. The KBx signal is an active low, level-sensitive interrupt of the selected pins. Like the other ports, each pin can be configured as an input or output on a bit-by-bit basis. When they are configured as inputs, each pin can generate a CPU interrupt.
|
||||
|
||||
CS(A/B/C/D)1 seem to not be connected, only CS*0 is used
|
||||
|
||||
PFPUEN has both pull up and pull down on it, the 4 address lines are the pull downs
|
||||
|
||||
cmp.* seems like it can only set the Carry flag if the result or one of the parameters is negative
|
||||
|
||||
The first argument to a function is the last pushed on the stack(proof below, the 16 bit int is the last argument and its pushed first)
|
||||
|
||||
ROM:1003026C move.w d0,-(sp) ; Move Data from Source to Destination
|
||||
ROM:1003026E move.l a4,-(sp) ; Move Data from Source to Destination
|
||||
ROM:10030270 move.l d7,-(sp) ; Move Data from Source to Destination
|
||||
ROM:10030272 trap #$F ; Trap sysTrapStrNCopy
|
||||
ROM:10030272 dc.w $A2CE
|
||||
Char * StrNCopy(Char *dst, const Char *src, Int16 n)SYS_TRAP(sysTrapStrNCopy);
|
||||
|
||||
|
||||
HwrIRQ4Handler Interrupt Level 4 Priority(top of the list is checked first):
|
||||
UART 1 and 2(they have the same priority)
|
||||
RTC
|
||||
All Buttons
|
||||
|
||||
IVR = 0x18
|
||||
interrupt vector start = 0x60
|
||||
|
||||
vectors starting at level 0(no interrupt) to level 7
|
||||
0x00000060:0x00000000 (no interrupt, never called)
|
||||
0x00000064:0x101904BE
|
||||
0x00000068:0x101904EC
|
||||
0x0000006C:0x1019051A
|
||||
0x00000070:0x10190548 (level 4, hardware buttons)
|
||||
0x00000074:0x10190576 (level 5, seems to be touchscreen)
|
||||
0x00000078:0x101905A4
|
||||
0x0000007C:0x10015F34 (level 7, debugging IRQ, not used)
|
||||
|
||||
SPI Routine Location:
|
||||
PrvSetBB7846ChanRef or PrvReadnBB7846PwrDn
|
||||
0x10081518
|
||||
|
||||
SPI Start Chunk(sent once on boot):
|
||||
12 4 bit delay, 8 bit check battery command, 0x0AE0
|
||||
5 5 bit receive, continued from last command, 0x0014
|
||||
|
||||
Palm OS reads from the touchscreen SPI in 5 accesses:
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:16(printed 1 times)
|
||||
SPI2 transfer, before:0xE01B, after:0x00FF(printed 1 times)
|
||||
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:3(printed 1 times)
|
||||
SPI2 transfer, before:0x0004, after:0x0026(printed 1 times)
|
||||
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:5(printed 1 times)
|
||||
SPI2 transfer, before:0x001D, after:0x03BF(printed 1 times)
|
||||
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:12(printed 1 times)
|
||||
SPI2 transfer, before:0x0E1C, after:0xCE00(printed 1 times)
|
||||
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:16(printed 1 times)
|
||||
SPI2 transfer, before:0xE01C, after:0xFEFF(printed 1 times)
|
||||
|
||||
|
||||
resync event?{
|
||||
16 0xE01B
|
||||
3 only sends 0s, delay or receive, 0x0004
|
||||
5 only sends 0s, delay or receive, 0x001D
|
||||
}
|
||||
12 4 bit delay, 8 bit send command, 0x0E1C
|
||||
16 0xE01C
|
||||
|
||||
TouchScreen Read Order:
|
||||
|
||||
//check x
|
||||
Accessed ADS7846 Ch:5, Normal Mode, Power Save:0, PC:0x1008119E.(printed 1 times)
|
||||
//don't know why
|
||||
Accessed ADS7846 Ch:0, Normal Mode, Power Save:3, PC:0x10081208.(printed 1 times)
|
||||
//don't know why
|
||||
Accessed ADS7846 Ch:6, Normal Mode, Power Save:3, PC:0x10081208.(printed 1 times)
|
||||
//...repeat until released
|
||||
//check battery before returning
|
||||
Accessed ADS7846 Ch:2, Normal Mode, Power Save:3, PC:0x10081208.(printed 1 times)
|
||||
6
bugs/fixed/T3Crash.txt
Normal file
6
bugs/fixed/T3Crash.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
10:32:11: Debugging starts
|
||||
mincore\com\oleaut32\dispatch\ups.cpp(2125)\OLEAUT32.dll!00007FFE26F51D23: (caller: 00007FFE26F51E9A) ReturnHr(1) tid(1870) 8002801D Library not registered.
|
||||
QObject::~QObject: Timers cannot be stopped from another thread
|
||||
10:32:24: Debugging has finished
|
||||
|
||||
Just a crash from killing the program due to a buffer overflow.
|
||||
14
bugs/fixed/sdCardImplementation/possibleCauses.txt
Normal file
14
bugs/fixed/sdCardImplementation/possibleCauses.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
chip select may not be readable from CPU
|
||||
|
||||
Need to investigate:
|
||||
HwrSpiCsSet_100AC772
|
||||
|
||||
|
||||
CPU read 8 bits from register 0x704, PC:0x100A5976.(printed 65536 times)
|
||||
It may not be reading back at all, because it sure keeps trying.
|
||||
This is SPICONT1, the only purpose this many reads could accomplish is checking if an exchange is in progress.
|
||||
|
||||
it seems the write response is off by 1 bit, i don't know why
|
||||
|
||||
Fixed:
|
||||
XCH bit was not being cleared
|
||||
1614
bugs/fixed/sdCardImplementation/sdCardFullAccessLogGood.txt
Normal file
1614
bugs/fixed/sdCardImplementation/sdCardFullAccessLogGood.txt
Normal file
File diff suppressed because it is too large
Load Diff
2453
bugs/fixed/sdCardImplementation/sdCardWriteTransferLogGood.txt
Normal file
2453
bugs/fixed/sdCardImplementation/sdCardWriteTransferLogGood.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
Release at Christmas 17:00 GMT, 9:00 My time, 12:00 SquirrelJME devs time
|
||||
|
||||
I post to r/emulation, Stephanie(SquirrelJME dev) posts to Twitter and Mastodon
|
||||
|
||||
Cinco De Mayo(May 5th), 17:00 GMT, hopefully with some good ARM stuff(delayed again)
|
||||
Easter release, 17:00 GMT, hopefully with some good ARM stuff(delayed)
|
||||
|
||||
Done:
|
||||
Release at Christmas 17:00 GMT, 9:00 My time, 12:00 SquirrelJME devs time
|
||||
I post to r/emulation, Stephanie(SquirrelJME dev) posts to Twitter and Mastodon
|
||||
Sister projects with SquirrelJME: https://github.com/XerTheSquirrel/SquirrelJME
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
This is like unimplementedHardware.txt but only lists things that have functionality issues not accuracy issues.
|
||||
|
||||
UGUI file picker for RetroArch
|
||||
State manager goes bezerk and crashes when saving on android, also can't close the window or it won't open again(also only on Android)
|
||||
If there is no userdata-en-m515.ram on Android the emu won't create it(this is likely because theres no graceful exit being done on Android only goto home menu and kill process)
|
||||
app install hack needs to be removed when SD card works
|
||||
cyclone68k is broken on iOS
|
||||
|
||||
|
||||
Fixed:
|
||||
app install hack needs to be removed when SD card works(done, its only enabled in developer mode for fast testing)
|
||||
cyclone68k is broken on iOS(not gonna happen, iOS supposedly has its own ASM syntax)
|
||||
double pressing power button issue(better without PDKBEN but still not correct)
|
||||
Holding the buttons emulates pressing them like a turbo button(may be caused by the lack of sound emulation(wrong, sound works now))(may be because the minimum length of a button press is a whole frame(wrong, increasing the framerate doesn't change this behavior))(port d doesn't seem to be documented properly)
|
||||
16 bpp mode is broken
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Fixed:
|
||||
Endian compatibility is broken(the CPU state needs to be standardized)(fixed again with musashi and the other 68k core isn't used right now)
|
||||
RetroArch port crashes on exit(needed to check if environ_cb returned true, switched to libretro-common filestreams too)
|
||||
BIN
bugs/shadowTheifBug/Screenshot_20190426-220702.png
Normal file
BIN
bugs/shadowTheifBug/Screenshot_20190426-220702.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
4
bugs/shadowTheifBug/text.txt
Normal file
4
bugs/shadowTheifBug/text.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Whenever I register ShadowThief, this happens:
|
||||
|
||||
It happens on any version of Mu
|
||||
PHEM/ST is fine
|
||||
@@ -1,10 +1,6 @@
|
||||
CPU:
|
||||
sysTrapPceNativeCall, ARM Emulator
|
||||
Trace T1 bit, should be unused by the OS and applications anyway
|
||||
Test what bits of IMR are writable
|
||||
On hardware PDIRQEG seems not to actually work at all(CPUID:0x57000000)
|
||||
SCR privilege violation doesnt trigger the same as on hardware(likely has to do with not emulating the unused chip selects)
|
||||
TCN2 is unimplemented and seems to be used by the same routines that turn the CPU off for sleep mode
|
||||
hardware registers don't have there names printed in sandbox
|
||||
|
||||
CPU I/O:
|
||||
Peripheral Control Register, audio ppm mixing selection
|
||||
@@ -12,57 +8,109 @@ Setting the battery dead bit(PDDATA 0x80) if the emulated battery percent gets t
|
||||
DRAMC write enable
|
||||
Port M Infrared shutdown (PMDATA 0x20)
|
||||
some undocumented I/O might be on port e and port j
|
||||
SPI1, probably the SD card since SD cards use SPI for data transfer
|
||||
SPITEST SSTATUS is undocumented and therefore unemulated
|
||||
may need to trigger an interrupt if a IMR masked interrupt becomes unmasked and its bit is still set in IPR
|
||||
When SPICLK2, SPITXD or SPIRXD on port e is disabled ADS7846 functions should respond appropriately(not transmitting or receiving or blocking both for the clock)
|
||||
REFREQ clock frequency in RTCCTL should slow down the RTC when enabled
|
||||
Dont know if it possible to have the backlight on and the display off at the same time(theres no reason for it but it may be possible)
|
||||
SPI1 slave mode, should never be used
|
||||
port d data register INT* bits seem to have there data bits cleared when an edge triggered interrupt is cleared(according to MC68VZ328UM.pdf Page 10-15)
|
||||
RxOverflow on SPI1, don't know if back or front of FIFO is overwritten on overflow(currently losing oldest entry)
|
||||
ICR POL(1,2,3,6) may flip the pin value as well as the interrupt, POL5 does not flip the INT5 pin though, this was confirmed with a hardware test(it doesnt seem to but there is instability on the pin when the SD card is plugged in, this may have to do with card detect also being a data line on the SD pinout)
|
||||
edge triggered INT* don't clear on write to ISR when masked in IMR(at least that seems to be the reason)
|
||||
Cyclone will cause SIGSEGVs, don't know why yet
|
||||
PWM2 is not implemented
|
||||
don't know if flushing the PWM1 FIFO sets all the bytes to 0x00, or just sets the read pointer to the write pointer preserving the newest sample and making the size 0(readPtr = writePtr has significantly cleaner audio then 0ing it out though)
|
||||
while it is stated that the PLL is turned off "30 clocks" after the DISPLL bit is set, it doesnt state where the clocks come from, CLK32 or SYSCLK
|
||||
SPI1 SPISPC register
|
||||
UART1 USTCNT1
|
||||
PLLFSR has a hack that makes busy wait loops finish faster by toggling the CLK32 bit on read, for power button issue
|
||||
PDKBEN also has a hack for power on
|
||||
should also not transfer data to SD card when MOSI, MISO or SPICLK1 are disabled
|
||||
port d data register INT* bits seem to have there data bits cleared when an edge triggered interrupt is cleared(according to MC68VZ328UM.pdf Page 10-15)
|
||||
sound plays too long when the category's menu is selected on the home screen and the pen is pressed and held in the middle of the screen(only happens there, other views of the same type don't have this issue)(effected by CPU speed, turning it up reduces the duration of the excess squeal)(the home menu may be changing the clock speed when this menu is released since it refreshes a bunch of icons which is CPU intensive, if it is it would distort the audio since sysclks are only calculated at the begining of a frame the new value would not take effect until a new frame began, and since it works properly sometimes that is probably when the change occurs just at the end of the last frame and the sysclk duration refresh happens at the intended time due to the new frame starting)
|
||||
UART1 OLD DATA interrupt uses timing, may just have this be the same a DATA READY
|
||||
SPI1 rxOverflow is may not be emulated exactly as its supposed to be, the overflow data is written to the newest FIFO byte when it should probably be written to the oldest
|
||||
UART CTS pin is not emulated
|
||||
since actual UART hardware is not being used should be safe to ignore the parity bit and timing
|
||||
|
||||
Memory:
|
||||
SD card can't be read or written to by Palm OS
|
||||
unknown if DRAM bit expanded address space is used for CSC when its not an extension of CSD
|
||||
there is conflicting information on whether the DRAM bit effects CSC, needs a test made
|
||||
the unemulated chip selects(CSB1, CSC0/1) privilege violation interrupts will not be handled properly
|
||||
may need to emulated CSC0/1 chip selects
|
||||
|
||||
SED1376:
|
||||
swivelview register
|
||||
|
||||
ADS7846:
|
||||
verify chip select(no test has been done yet, but everything points to port g bit 2)
|
||||
need to trigger a false PENIRQ interrupt on reading certain channels
|
||||
electrical noise on lines(conversions probably should have +-20 added to values)(probably no need for this, it works so theres no need to use less precise values)
|
||||
in the edge case that SPICLK2 is disabled while using ADS7846 and a 1 was the last bit shifted out 0s will still be shifted in
|
||||
need to to verify behavior of differential mode bit
|
||||
|
||||
TSC2101:
|
||||
values of AUX1 and AUX2 are unknown an need to be tested, emulation has issues with the USB port shortly after and it would make sense that since the T3 has the same connector as the m515 AUX1 is the device type resistor in the bottom connector
|
||||
|
||||
SD Card:
|
||||
block specific write protect bits don't work
|
||||
IRQ2 may actually be attached to the SD Card data out pin, triggering an interrupt when a 0 is received to process the return data
|
||||
need to test if Port J Pin 3(SD card chip select) is attached to Port D Pin 5(SD Card Status(IRQ2))(pinouts.ru says chip select and card detect are the same line)
|
||||
This thing: case SEND_STATUS://HACK, need to add real write protection, this command is also how the host reads the value of the little switch on the side
|
||||
|
||||
Debug tools:
|
||||
ADS7846 channels can't be read in single reference mode in hwTestSuite
|
||||
Mu sandbox dosent have memory and opcode hooks setup when in ARMv5 mode
|
||||
|
||||
MakePalmBitmap:
|
||||
|
||||
Other:
|
||||
Qt port dosent support Windows touchscreen input
|
||||
T3 I2C currently has no ACK bits(should work without them its just inaccurate)(I2C works fine though)
|
||||
T3 emulation attempts to set GPIO1(reset button) as an output
|
||||
GPIO lines from misc chips to CPU are not implemented
|
||||
PXA260 idle mode is unimplemented
|
||||
0x0E071F16 MCR P15, #0, R1, C7, C2, #5 is unimplemented along with several other unknown CP15 opcodes
|
||||
|
||||
|
||||
Fixed:
|
||||
memory dumping dosent work for OS 5 yet
|
||||
Endian compatibility is broken(the CPU state needs to be standardized)
|
||||
RetroArch port crashes on exit(needed to check if environ_cb returned true, switched to libretro-common filestreams too)
|
||||
make the headers belong to the main file of the target chip being emulated for specs
|
||||
remove specs folder
|
||||
UART1 USTCNT1
|
||||
trying to beam anything will lock up the OS
|
||||
Qt dosent have a hybrid file/folder selector so apps will always have to be launched from folders for now
|
||||
File Installer isnt working yet
|
||||
Qt GUI dosent resize properly with 320x320 framebuffer
|
||||
PLLFSR has a hack that makes busy wait loops finish faster by toggling the CLK32 bit on read, for power button issue(removed, power button works as expected if you wait at least 2 seconds before pushing it again(makes sence that it cnat read the new press while its turning off the CPU))
|
||||
(CPU)VFP(floating point) coprocessor for ARM(dont think the ARM Palms even used VFP)
|
||||
(Other)need to get rid of buffer_t, its not used much anyway
|
||||
ARM dynarec SIGSEGVs on exit(pushing play in the debugger still lets it continue, dont think this is a bug)
|
||||
(Feature)need to add FEATURE_DURABLE which will ignore CPU errors, increasing stability at the cost of bugginess
|
||||
(RetroArch port)set the alarm LED using retro_set_led_state_t on RetroArch
|
||||
(CPU I/O)SPI1 SPISPC register(this is just a clock divider used to slow transfers to allow the voltages to settle, since the emu has no voltages all transfers are just instant)
|
||||
(CPU)TCN2 is unimplemented and seems to be used by the same routines that turn the CPU off for sleep mode(it is implemented now and it wasn't the cause of the sleep mode issue)
|
||||
(CPU)SCR privilege violation doesnt trigger the same as on hardware(likely has to do with not emulating the unused chip selects)(I added those chip selects)
|
||||
(CPU)Trace T1 bit, should be unused by the OS and applications anyway(this was fixed long ago, don't know why it was still listed?)
|
||||
(SD Card)data blocks won't work properly when CRC checks are enabled
|
||||
(SD Card)the CRC of CSD and CID are invalid
|
||||
unemulated chip select(CSB1) privilege violation interrupts are not handled properly
|
||||
SD card can't be inserted in RetroArch port
|
||||
USB chip seems to share an interrupt with the SD card(the SD card interrupt is unimplemented at boot and triggers a printf over USB instead, if USB is not properly emulated that will cause a lock up)(enough of the USB is now emulated to prevent this)
|
||||
(SD Card)need to an input option for the write protect switch on the side of the SD card(will be fixed at input time since you can't flip it when in the slot)
|
||||
(SD Card)memory block ordering is broken
|
||||
(SD Card)block length is fixed at 512 right now(this is actually proper behavior for newer SDSC cards)
|
||||
(SD Card)need to dump valid SCR
|
||||
(SD Card)SEND_SCR may not be sending in the proper format(the return data format was not specified in the spec I read)(data packet format is working)
|
||||
SPI1(the SD card interface)(SPI1 master mode seems fully implemented now)
|
||||
SD card can't be read or written to by Palm OS(SPI transactions are going both ways now, some flash chip read commands are implemented too)
|
||||
(ADS7846)need to trigger a false PENIRQ interrupt on reading certain channels(this is being done now)
|
||||
(MakePalmBitmap)the small icons are corrupt
|
||||
(MakePalmBitmap)the non 16 bpp large icons are corrupt
|
||||
need to test if Port J Pin 3(SD card chip select) is attached to Port D Pin 5(SD Card Status(IRQ2))(pinouts.ru says chip select and card detect are the same line)(IRQ2 doesnt change when SD card chip select is toggled regardless of wether the card is inserted)
|
||||
the "Fatal Error" dialog reset button doesnt work, may not be a bug, could just an be issue with certain errors needing a full reset(its error dependent, one bug proved the other bug wasn't actually a bug)
|
||||
don't know if flushing the PWM1 FIFO sets all the bytes to 0x00, or just sets the read pointer to the write pointer preserving the newest sample and making the size 0(readPtr = writePtr has significantly cleaner audio then 0ing it out though(they sound the same now, this just masked the actual issue))
|
||||
edge triggered INT* don't clear on write to ISR when masked in IMR(I needed to use (ints & ~IMR) not (ints & IMR) which only triggers disable interrupts while blocking active ones)
|
||||
PDKBEN also has a hack for power on(its been removed)
|
||||
On hardware PDIRQEG seems not to actually work at all(CPUID:0x57000000)(it does)
|
||||
may need to trigger an interrupt if a IMR masked interrupt becomes unmasked and its bit is still set in IPR(already doing that)
|
||||
power button must be pushed twice to turn the CPU back on(when debugging it works the first time, then must be pushed twice to turn off instead of on)(this also occurs in the RetroArch build)
|
||||
the power button double press issue may be because the button map I am using was taken from POSE source, the power button may be mapped to other locations on the button matrix than expected
|
||||
if a sound interrupt is triggered while the button interrupt is disabled the button interrupt will still trigger(in galax game)(seems to be an issue with FIFOAV always = true hack and how INT_PWM1 needed to be cleared on read or write)
|
||||
SED1376 16 bpp mode is broken and crushed to the top of the screen
|
||||
audio can max out the resampler buffer, the max 1 FIFO sample can play is around 2.16 minutes(CLK32 / period(257) / clockDivider(16) / prescaler(128) / repeat(8))(257 * 16 * 128 * 8 / 32768=128.5 seconds)(safety check added, >= 1 second duty cycle is useless and will just make annoying cracks anyway)
|
||||
Cyclone CPU emulator is not working
|
||||
PWM1 output value is not a direct range cast of 0<->255 to 0<->32767, its additive, see properPwmSineWave.png
|
||||
inductor dosent properly drain when PWM1 gets disabled
|
||||
PWM1 FIFOAV is always set true
|
||||
@@ -82,7 +130,6 @@ Edge triggered IRQ* interrupt pins may actually read the value of the interrupt
|
||||
ADS7846 channels are not implemented properly in the emulator(works now)
|
||||
ADS7846 Channels 3 and 4(they need to be scaled differently)(works now)
|
||||
CPU32 table lookup opcodes(there is no CPU32)
|
||||
USB chip seems to share an interrupt with the SD card(the SD card interrupt is unimplemented at boot and triggers a printf over USB instead, if USB is not properly emulated that will cause a lock up)
|
||||
IRQ2 seems to not even be hooked up in IDA(IRQ2 is setup after boot by the SD driver, the kernels IRQ2 driver only sends a debug message over USB or serial)
|
||||
framebuffer accesses can cause a buffer overflow(this was always the case, its not a new bug)(just increased the buffer to an address line maskable size)
|
||||
chipselect mirroring is wrong(CS*0 and CS*1 are considered continuous when mapped with more address space than memory, mirroring is currently [CS*0, CS*1, repeat alternating till the end of address space] it should be [CS*0, repeat CS*0 until half way through CS* address space, CS*1, repeat CS*1 until end of CS* address space])
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
------------------------------------------
|
||||
v(1/3*3) to v1.0.0(Christmas 2018 - Feb 25 2019)
|
||||
|
||||
Core:
|
||||
*SD card support
|
||||
*all non timing based hacks are gone, this was my requirement for a v1.0.0 release
|
||||
|
||||
------------------------------------------
|
||||
v0.9.5 to v(1/3*3)(equal to 1 until measured in a finite precision system)(Oct 18 2018 - Christmas 2018)
|
||||
|
||||
@@ -10,6 +17,7 @@ Qt GUI:
|
||||
*removed unneeded buffers on the GUI side and replaced them with a mutex
|
||||
|
||||
Core:
|
||||
*fix power button double press bug
|
||||
*sound works perfectly as far as I can tell(unless a program purposely sets the sample length > 1 second, which is useless for generating sound anyway)
|
||||
*add ARM optimized 68k CPU core(not fully working yet, SIGSEGVs when running)
|
||||
*allow safety checks to be disabled with EMU_NO_SAFETY, accuracy is maintained when its not defined
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
@@ -7,7 +7,7 @@
|
||||
extern bool ads7846PenIrqEnabled;
|
||||
|
||||
void ads7846Reset(void);
|
||||
uint64_t ads7846StateSize(void);
|
||||
uint32_t ads7846StateSize(void);
|
||||
void ads7846SaveState(uint8_t* data);
|
||||
void ads7846LoadState(uint8_t* data);
|
||||
|
||||
6
include/armv5te/armsnippets.h
Normal file
6
include/armv5te/armsnippets.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef H_ARMSNIPPETS
|
||||
#define H_ARMSNIPPETS
|
||||
|
||||
#define armloader_cb()
|
||||
|
||||
#endif
|
||||
50
include/armv5te/asmcode.h
Normal file
50
include/armv5te/asmcode.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Declarations for asmcode.S */
|
||||
|
||||
#ifndef H_ASMCODE
|
||||
#define H_ASMCODE
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
// Supply the pointer to the instruction directly to avoid read_instruction
|
||||
void translation_enter(void *ptr) __asm__("translation_enter");
|
||||
#define TRANSLATION_ENTER_HAS_PTR 1
|
||||
#else
|
||||
void translation_enter() __asm__("translation_enter");
|
||||
#define TRANSLATION_ENTER_HAS_PTR 0
|
||||
#endif
|
||||
|
||||
// Jump to the translated code starting at ptr.
|
||||
// Checks for cycle_count_delta and exits if necessary.
|
||||
void translation_jmp(void *ptr) __asm__("translation_jmp");
|
||||
// Checks whether code at ptr is now translated and if so, jumps to it
|
||||
void translation_jmp_ptr(void *ptr) __asm__("translation_jmp_ptr");
|
||||
|
||||
void * FASTCALL read_instruction(uint32_t addr) __asm__("read_instruction");
|
||||
uint32_t FASTCALL read_byte(uint32_t addr) __asm__("read_byte");
|
||||
uint32_t FASTCALL read_half(uint32_t addr) __asm__("read_half");
|
||||
uint32_t FASTCALL read_word(uint32_t addr) __asm__("read_word");
|
||||
void FASTCALL write_byte(uint32_t addr, uint32_t value) __asm__("write_byte");
|
||||
void FASTCALL write_half(uint32_t addr, uint32_t value) __asm__("write_half");
|
||||
void FASTCALL write_word(uint32_t addr, uint32_t value) __asm__("write_word");
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
|
||||
// For some JITs there's in internal version called by JIT'ed code that can't be called
|
||||
// from outside the JIT'ed code
|
||||
uint32_t FASTCALL read_byte_asm(uint32_t addr) __asm__("read_byte_asm");
|
||||
uint32_t FASTCALL read_half_asm(uint32_t addr) __asm__("read_half_asm");
|
||||
uint32_t FASTCALL read_word_asm(uint32_t addr) __asm__("read_word_asm");
|
||||
void FASTCALL write_byte_asm(uint32_t addr, uint32_t value) __asm__("write_byte_asm");
|
||||
void FASTCALL write_half_asm(uint32_t addr, uint32_t value) __asm__("write_half_asm");
|
||||
void FASTCALL write_word_asm(uint32_t addr, uint32_t value) __asm__("write_word_asm");
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
81
include/armv5te/bitfield.h
Normal file
81
include/armv5te/bitfield.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef BITFIELD_H
|
||||
#define BITFIELD_H
|
||||
|
||||
/* Portable and safe implementation of C bitfields
|
||||
Source: http://blog.codef00.com/2014/12/06/portable-bitfields-using-c11/ */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//Mac OS RetroArch port is lacking <type_traits>
|
||||
template<bool B, class T, class F>
|
||||
struct typeConditional { typedef T type; };
|
||||
|
||||
template<class T, class F>
|
||||
struct typeConditional<false, T, F> { typedef F type; };
|
||||
|
||||
template <size_t LastBit>
|
||||
struct MinimumTypeHelper {
|
||||
typedef
|
||||
typename typeConditional<LastBit == 0 , void,
|
||||
typename typeConditional<LastBit <= 8 , uint8_t,
|
||||
typename typeConditional<LastBit <= 16, uint16_t,
|
||||
typename typeConditional<LastBit <= 32, uint32_t,
|
||||
typename typeConditional<LastBit <= 64, uint64_t,
|
||||
void>::type>::type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <size_t Index, size_t Bits = 1>
|
||||
class BitField {
|
||||
private:
|
||||
enum {
|
||||
Mask = (1u << Bits) - 1u
|
||||
};
|
||||
|
||||
typedef typename MinimumTypeHelper<Index + Bits>::type T;
|
||||
public:
|
||||
template <class T2>
|
||||
BitField &operator=(T2 value) {
|
||||
value_ = (value_ & ~(Mask << Index)) | ((value & Mask) << Index);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
T2 as() { return (value_ >> Index) & Mask; }
|
||||
operator T() const { return (value_ >> Index) & Mask; }
|
||||
explicit operator bool() const { return value_ & (Mask << Index); }
|
||||
BitField &operator++() { return *this = *this + 1; }
|
||||
T operator++(int) { T r = *this; ++*this; return r; }
|
||||
BitField &operator--() { return *this = *this - 1; }
|
||||
T operator--(int) { T r = *this; ++*this; return r; }
|
||||
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
|
||||
template <size_t Index>
|
||||
class BitField<Index, 1> {
|
||||
private:
|
||||
enum {
|
||||
Bits = 1,
|
||||
Mask = 0x01
|
||||
};
|
||||
|
||||
typedef typename MinimumTypeHelper<Index + Bits>::type T;
|
||||
public:
|
||||
template <typename T2>
|
||||
T2 as() { return (value_ >> Index) & Mask; }
|
||||
BitField &operator=(bool value) {
|
||||
value_ = (value_ & ~(Mask << Index)) | (value << Index);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const { return value_ & (Mask << Index); }
|
||||
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
#endif // BITFIELD_H
|
||||
|
||||
122
include/armv5te/cpu.h
Normal file
122
include/armv5te/cpu.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Declarations for cpu.c */
|
||||
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fixings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(pack(push, 1))
|
||||
#endif
|
||||
|
||||
typedef struct arm_state { // Remember to update asmcode.S if this gets rearranged
|
||||
uint32_t reg[16]; // Registers for current mode.
|
||||
|
||||
uint32_t cpsr_low28; // CPSR bits 0-27
|
||||
uint8_t cpsr_n; // CPSR bit 31
|
||||
uint8_t cpsr_z; // CPSR bit 30
|
||||
uint8_t cpsr_c; // CPSR bit 29
|
||||
uint8_t cpsr_v; // CPSR bit 28
|
||||
|
||||
#if defined(__arm__)
|
||||
uint32_t cpsr_flags; // Only used in ARM translations
|
||||
#endif
|
||||
|
||||
/* CP15 registers */
|
||||
uint32_t control;
|
||||
uint32_t translation_table_base;
|
||||
uint32_t domain_access_control;
|
||||
uint8_t data_fault_status, instruction_fault_status, pad1, pad2; // pad1 and pad2 for better alignment
|
||||
uint32_t fault_address;
|
||||
|
||||
uint32_t r8_usr[5], r13_usr[2];
|
||||
uint32_t r8_fiq[5], r13_fiq[2], spsr_fiq;
|
||||
uint32_t r13_irq[2], spsr_irq;
|
||||
uint32_t r13_svc[2], spsr_svc;
|
||||
uint32_t r13_abt[2], spsr_abt;
|
||||
uint32_t r13_und[2], spsr_und;
|
||||
|
||||
uint8_t interrupts;
|
||||
uint32_t cpu_events_state; // Only used for suspend and resume!
|
||||
}
|
||||
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(_MSC_VER)
|
||||
__attribute__((packed))
|
||||
#endif
|
||||
arm_state;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(pack(pop))
|
||||
#endif
|
||||
|
||||
extern struct arm_state arm __asm__("arm");
|
||||
|
||||
#define MODE_USR 0x10
|
||||
#define MODE_FIQ 0x11
|
||||
#define MODE_IRQ 0x12
|
||||
#define MODE_SVC 0x13
|
||||
#define MODE_ABT 0x17
|
||||
#define MODE_UND 0x1B
|
||||
#define MODE_SYS 0x1F
|
||||
#define PRIVILEGED_MODE() (arm.cpsr_low28 & 3)
|
||||
#define USER_MODE() (!(arm.cpsr_low28 & 3))
|
||||
|
||||
#define EX_RESET 0
|
||||
#define EX_UNDEFINED 1
|
||||
#define EX_SWI 2
|
||||
#define EX_PREFETCH_ABORT 3
|
||||
#define EX_DATA_ABORT 4
|
||||
#define EX_IRQ 6
|
||||
#define EX_FIQ 7
|
||||
|
||||
#define current_instr_size ((arm.cpsr_low28 & 0x20) ? 2 /* thumb */ : 4)
|
||||
|
||||
// Needed for the assembler calling convention
|
||||
#ifdef __i386__
|
||||
#ifdef FASTCALL
|
||||
#undef FASTCALL
|
||||
#endif
|
||||
#define FASTCALL __attribute__((fastcall))
|
||||
#else
|
||||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
void cpu_int_check();
|
||||
uint32_t get_cpsr() __asm__("get_cpsr");
|
||||
void set_cpsr_full(uint32_t cpsr);
|
||||
void FASTCALL set_cpsr(uint32_t cpsr, uint32_t mask);
|
||||
uint32_t get_spsr();
|
||||
void FASTCALL set_spsr(uint32_t cpsr, uint32_t mask);
|
||||
uint32_t *ptr_spsr();
|
||||
uint32_t get_cpsr_flags();
|
||||
void set_cpsr_flags(uint32_t flags) __asm__("set_cpsr_flags");
|
||||
void cpu_exception(int type);
|
||||
void fix_pc_for_fault();
|
||||
void *try_ptr(uint32_t addr);
|
||||
void cpu_interpret_instruction(uint32_t insn);
|
||||
void cpu_arm_loop();
|
||||
void cpu_thumb_loop();
|
||||
typedef void fault_proc(uint32_t mva, uint8_t status);
|
||||
fault_proc prefetch_abort, data_abort __asm__("data_abort");
|
||||
void undefined_instruction();
|
||||
|
||||
uint32_t reg(uint8_t i);
|
||||
uint32_t reg_pc(uint8_t i);
|
||||
uint32_t reg_pc_mem(uint8_t i);
|
||||
void set_reg(uint8_t i, uint32_t value);
|
||||
void set_reg_pc(uint8_t i, uint32_t value);
|
||||
void set_reg_bx(uint8_t i, uint32_t value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
157
include/armv5te/cpudefs.h
Normal file
157
include/armv5te/cpudefs.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#ifndef CPUDEFS_H
|
||||
#define CPUDEFS_H
|
||||
|
||||
#include "bitfield.h"
|
||||
|
||||
// Structure of instructions, enums etc.
|
||||
|
||||
union Instruction {
|
||||
uint32_t raw;
|
||||
|
||||
BitField<28, 4> cond;
|
||||
BitField<0, 28> rest;
|
||||
|
||||
union {
|
||||
BitField<24> l;
|
||||
BitField<0, 24> immed;
|
||||
} branch;
|
||||
|
||||
union {
|
||||
BitField<0, 4> rm;
|
||||
BitField<5> l;
|
||||
} bx;
|
||||
|
||||
union {
|
||||
BitField<21, 4> op;
|
||||
BitField<20> s;
|
||||
BitField<16, 4> rn;
|
||||
BitField<12, 4> rd;
|
||||
BitField<25> imm;
|
||||
|
||||
// If imm
|
||||
BitField<0, 8> immed_8;
|
||||
BitField<8, 4> rotate_imm;
|
||||
// else
|
||||
BitField<4> reg_shift;
|
||||
BitField<0, 4> rm;
|
||||
BitField<5, 2> shift;
|
||||
// If reg_shift
|
||||
BitField<8, 4> rs;
|
||||
// else
|
||||
BitField<7, 5> shift_imm;
|
||||
} data_proc; // ADD, MOV, etc.
|
||||
|
||||
union {
|
||||
BitField<25> not_imm;
|
||||
BitField<24> p;
|
||||
BitField<23> u;
|
||||
BitField<22> b;
|
||||
BitField<21> w;
|
||||
BitField<20> l;
|
||||
BitField<16, 4> rn;
|
||||
BitField<12, 4> rd;
|
||||
|
||||
// If not_imm == 0
|
||||
BitField<0, 12> immed;
|
||||
// else
|
||||
BitField<0, 4> rm;
|
||||
BitField<5, 2> shift;
|
||||
BitField<7, 5> shift_imm;
|
||||
} mem_proc; // LDR, STRB, etc.
|
||||
|
||||
union {
|
||||
BitField<24> p;
|
||||
BitField<23> u;
|
||||
BitField<22> i;
|
||||
BitField<21> w;
|
||||
BitField<20> l;
|
||||
BitField<16, 4> rn;
|
||||
BitField<12, 4> rd;
|
||||
|
||||
BitField<6> s;
|
||||
BitField<5> h;
|
||||
|
||||
// If i
|
||||
BitField<8, 4> immed_h;
|
||||
BitField<0, 4> immed_l;
|
||||
// else
|
||||
BitField<0, 4> rm;
|
||||
} mem_proc2; // LDRH, STRSH, etc.
|
||||
|
||||
union {
|
||||
BitField<23> l;
|
||||
BitField<21> a;
|
||||
BitField<20> s;
|
||||
|
||||
BitField<8, 4> rs;
|
||||
BitField<0, 4> rm;
|
||||
|
||||
// If l
|
||||
BitField<16, 4> rdhi;
|
||||
BitField<12, 4> rdlo;
|
||||
// else
|
||||
BitField<16, 4> rd;
|
||||
BitField<12, 4> rn;
|
||||
} mult;
|
||||
|
||||
union {
|
||||
BitField<22> r;
|
||||
BitField<12, 4> rd;
|
||||
} mrs;
|
||||
|
||||
union {
|
||||
BitField<24> p;
|
||||
BitField<23> u;
|
||||
BitField<22> s;
|
||||
BitField<21> w;
|
||||
BitField<20> l;
|
||||
BitField<16, 4> rn;
|
||||
BitField<0, 16> reglist;
|
||||
} mem_multi;
|
||||
};
|
||||
|
||||
enum Condition {
|
||||
CC_EQ=0, CC_NE,
|
||||
CC_CS, CC_CC,
|
||||
CC_MI, CC_PL,
|
||||
CC_VS, CC_VC,
|
||||
CC_HI, CC_LS,
|
||||
CC_GE, CC_LT,
|
||||
CC_GT, CC_LE,
|
||||
CC_AL, CC_NV
|
||||
};
|
||||
|
||||
enum ShiftType {
|
||||
SH_LSL=0,
|
||||
SH_LSR,
|
||||
SH_ASR,
|
||||
SH_ROR // RRX if count == 0
|
||||
};
|
||||
|
||||
enum DataOp {
|
||||
OP_AND=0,
|
||||
OP_EOR,
|
||||
OP_SUB,
|
||||
OP_RSB,
|
||||
OP_ADD,
|
||||
OP_ADC,
|
||||
OP_SBC,
|
||||
OP_RSC,
|
||||
OP_TST,
|
||||
OP_TEQ,
|
||||
OP_CMP,
|
||||
OP_CMN,
|
||||
OP_ORR,
|
||||
OP_MOV,
|
||||
OP_BIC,
|
||||
OP_MVN
|
||||
};
|
||||
|
||||
// Defined in arm_interpreter.cpp
|
||||
void do_arm_instruction(Instruction i);
|
||||
// Defined in coproc.cpp
|
||||
void do_cp15_instruction(Instruction i);
|
||||
void do_cp14_instruction(Instruction i);
|
||||
|
||||
#endif // CPUDEFS_H
|
||||
|
||||
47
include/armv5te/debug.h
Normal file
47
include/armv5te/debug.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* Declarations for debug.c */
|
||||
#ifndef H_DEBUG
|
||||
#define H_DEBUG
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
extern FILE *debugger_input;
|
||||
#define gdb_connected false
|
||||
#define in_debugger false
|
||||
#define rdbg_port 0
|
||||
*/
|
||||
|
||||
enum DBG_REASON {
|
||||
DBG_USER,
|
||||
DBG_EXCEPTION,
|
||||
DBG_EXEC_BREAKPOINT,
|
||||
DBG_READ_BREAKPOINT,
|
||||
DBG_WRITE_BREAKPOINT,
|
||||
};
|
||||
|
||||
/*
|
||||
void *virt_mem_ptr(uint32_t addr, uint32_t size);
|
||||
void backtrace(uint32_t fp);
|
||||
int process_debug_cmd(char *cmdline);
|
||||
void debugger(enum DBG_REASON reason, uint32_t addr);
|
||||
void rdebug_recv(void);
|
||||
bool rdebug_bind(unsigned int port);
|
||||
void rdebug_quit();
|
||||
*/
|
||||
#define debugger(x, y)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
19
include/armv5te/disasm.h
Normal file
19
include/armv5te/disasm.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef H_DISASM
|
||||
#define H_DISASM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char disasmReturnBuf[80];
|
||||
|
||||
uint32_t disasm_arm_insn(uint32_t pc);
|
||||
uint32_t disasm_thumb_insn(uint32_t pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
include/armv5te/emu.h
Normal file
56
include/armv5te/emu.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef H_EMU
|
||||
#define H_EMU
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mem.h"
|
||||
|
||||
#include "../emulator.h"
|
||||
#include "../portability.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint16_t BSWAP16(uint16_t x) { return x << 8 | x >> 8; }
|
||||
#define BSWAP32(x) __builtin_bswap32(x)
|
||||
|
||||
extern int cycle_count_delta __asm__("cycle_count_delta");
|
||||
extern uint32_t cpu_events __asm__("cpu_events");
|
||||
#define EVENT_IRQ 1
|
||||
#define EVENT_FIQ 2
|
||||
#define EVENT_RESET 4
|
||||
#define EVENT_DEBUG_STEP 8
|
||||
#define EVENT_WAITING 16
|
||||
|
||||
// Settings
|
||||
extern bool exiting;
|
||||
extern bool do_translate;
|
||||
|
||||
enum { LOG_CPU, LOG_IO, LOG_FLASH, LOG_INTS, LOG_ICOUNT, LOG_USB, LOG_GDB, MAX_LOG };
|
||||
#define LOG_TYPE_TBL "CIFQ#UG"
|
||||
//void logprintf(int type, const char *str, ...);
|
||||
//void emuprintf(const char *format, ...);
|
||||
#define logprintf(type, ...) debugLog(__VA_ARGS__)
|
||||
#define emuprintf(...) debugLog(__VA_ARGS__)
|
||||
|
||||
//void warn(const char *fmt, ...);
|
||||
//__attribute__((noreturn)) void error(const char *fmt, ...);
|
||||
#define warn(...) debugLog(__VA_ARGS__)
|
||||
#define error(...) abort()
|
||||
|
||||
extern jmp_buf restart_after_exception;
|
||||
|
||||
// GUI callbacks
|
||||
#define gui_debug_printf(...) debugLog(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
37
include/armv5te/literalpool.h
Normal file
37
include/armv5te/literalpool.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef LITERALPOOL_H
|
||||
#define LITERALPOOL_H
|
||||
|
||||
/* Code shared by various translators, this file keeps the
|
||||
arch-independant parts. */
|
||||
|
||||
struct LiteralRef {
|
||||
void *inst;
|
||||
uintptr_t value;
|
||||
};
|
||||
|
||||
static constexpr size_t MAX_LITERALS = 1024;
|
||||
static LiteralRef literals[MAX_LITERALS];
|
||||
static size_t literals_count = 0;
|
||||
|
||||
void literalpool_add(uintptr_t value)
|
||||
{
|
||||
if(literals_count >= MAX_LITERALS)
|
||||
{
|
||||
literals_count = 0; // Otherwise it won't ever be empty again
|
||||
error("Literal pool full, please increase the size");
|
||||
return;
|
||||
}
|
||||
|
||||
literals[literals_count++] = LiteralRef { .inst = translate_current,
|
||||
.value = value };
|
||||
}
|
||||
|
||||
/* Function implemented by the architecture.
|
||||
It needs to iterate through all elements in literals until literals_count,
|
||||
emit the literal into a suitable location and fixup all instructions that
|
||||
reference it. If alignment is not an issue, certain values can be optimized,
|
||||
but in such cases the loading instruction and the literal pool need to agree.
|
||||
It then needs to reset literals_count to 0. */
|
||||
void literalpool_fill();
|
||||
|
||||
#endif //LITERALPOOL_H
|
||||
84
include/armv5te/mem.h
Normal file
84
include/armv5te/mem.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Declarations for memory.c */
|
||||
|
||||
#ifndef H_MEM
|
||||
#define H_MEM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MEM_MAXSIZE (80*1024*1024) // also defined as RAM_FLAGS in asmcode.S
|
||||
|
||||
extern uint8_t (*read_byte_map[64])(uint32_t addr);
|
||||
extern uint16_t (*read_half_map[64])(uint32_t addr);
|
||||
extern uint32_t (*read_word_map[64])(uint32_t addr);
|
||||
extern void (*write_byte_map[64])(uint32_t addr, uint8_t value);
|
||||
extern void (*write_half_map[64])(uint32_t addr, uint16_t value);
|
||||
extern void (*write_word_map[64])(uint32_t addr, uint32_t value);
|
||||
|
||||
// Must be allocated below 2GB (see comments for mmu.c)
|
||||
extern uint8_t *mem_and_flags;
|
||||
struct mem_area_desc {
|
||||
uint32_t base, size;
|
||||
uint8_t *ptr;
|
||||
};
|
||||
extern struct mem_area_desc mem_areas[2];
|
||||
void *phys_mem_ptr(uint32_t addr, uint32_t size);
|
||||
uint32_t phys_mem_addr(void *ptr);
|
||||
|
||||
/* Each word of memory has a flag word associated with it. For fast access,
|
||||
* flags are located at a constant offset from the memory data itself.
|
||||
*
|
||||
* These can't be per-byte because a translation index wouldn't fit then.
|
||||
* This does mean byte/halfword accesses have to mask off the low bits to
|
||||
* check flags, but the alternative would be another 32MB of memory overhead. */
|
||||
#define RAM_FLAGS(memptr) (*(uint32_t *)((uint8_t *)(memptr) + MEM_MAXSIZE))
|
||||
|
||||
#define RF_READ_BREAKPOINT 1
|
||||
#define RF_WRITE_BREAKPOINT 2
|
||||
#define RF_EXEC_BREAKPOINT 4
|
||||
#define RF_EXEC_DEBUG_NEXT 8
|
||||
#define RF_CODE_EXECUTED 16
|
||||
#define RF_CODE_TRANSLATED 32
|
||||
#define RF_CODE_NO_TRANSLATE 64
|
||||
#define RF_READ_ONLY 128
|
||||
#define RF_ARMLOADER_CB 256
|
||||
#define RFS_TRANSLATION_INDEX 9
|
||||
|
||||
#define DO_READ_ACTION (RF_READ_BREAKPOINT)
|
||||
#define DO_WRITE_ACTION (RF_WRITE_BREAKPOINT | RF_CODE_TRANSLATED | RF_CODE_NO_TRANSLATE | RF_CODE_EXECUTED)
|
||||
#define DONT_TRANSLATE (RF_EXEC_BREAKPOINT | RF_EXEC_DEBUG_NEXT | RF_CODE_TRANSLATED | RF_CODE_NO_TRANSLATE)
|
||||
|
||||
uint8_t bad_read_byte(uint32_t addr);
|
||||
uint16_t bad_read_half(uint32_t addr);
|
||||
uint32_t bad_read_word(uint32_t addr);
|
||||
void bad_write_byte(uint32_t addr, uint8_t value);
|
||||
void bad_write_half(uint32_t addr, uint16_t value);
|
||||
void bad_write_word(uint32_t addr, uint32_t value);
|
||||
|
||||
void write_action(void *ptr) __asm__("write_action");
|
||||
void read_action(void *ptr) __asm__("read_action");
|
||||
|
||||
uint8_t memory_read_byte(uint32_t addr);
|
||||
uint16_t memory_read_half(uint32_t addr);
|
||||
uint32_t memory_read_word(uint32_t addr);
|
||||
void memory_write_byte(uint32_t addr, uint8_t value);
|
||||
void memory_write_half(uint32_t addr, uint16_t value);
|
||||
void memory_write_word(uint32_t addr, uint32_t value);
|
||||
|
||||
uint32_t FASTCALL mmio_read_byte(uint32_t addr) __asm__("mmio_read_byte");
|
||||
uint32_t FASTCALL mmio_read_half(uint32_t addr) __asm__("mmio_read_half");
|
||||
uint32_t FASTCALL mmio_read_word(uint32_t addr) __asm__("mmio_read_word");
|
||||
void FASTCALL mmio_write_byte(uint32_t addr, uint32_t value) __asm__("mmio_write_byte");
|
||||
void FASTCALL mmio_write_half(uint32_t addr, uint32_t value) __asm__("mmio_write_half");
|
||||
void FASTCALL mmio_write_word(uint32_t addr, uint32_t value) __asm__("mmio_write_word");
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
78
include/armv5te/mmu.h
Normal file
78
include/armv5te/mmu.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef H_MMU
|
||||
#define H_MMU
|
||||
|
||||
#include "cpu.h"
|
||||
#include "emu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Translate a VA to a PA, using a page table lookup */
|
||||
uint32_t mmu_translate(uint32_t addr, bool writing, fault_proc *fault, uint8_t *s_status);
|
||||
|
||||
/* Used for t-type (usermode-like) access */
|
||||
void mmu_check_priv(uint32_t addr, bool writing);
|
||||
|
||||
/* addr_cache is used to cache the translation of VA to PA per page.
|
||||
* It has two entries per page (1k), one for reading and one for writing.
|
||||
* The format for 32-bit x86 with JIT is different to minimize the needed
|
||||
* registers in the x86 memory access functions and won't work for all
|
||||
* platforms:
|
||||
*
|
||||
* a) Pointer entry
|
||||
* The result of adding the virtual address (VA) to the entry has bit 31
|
||||
* clear, and that sum is a pointer to within mem_and_flags.
|
||||
* It would be cleaner to just use bit 0 or 1 to distinguish this case, but
|
||||
* this way we can simultaneously check both that this is a pointer entry,
|
||||
* and that the address is aligned, with a single bit test instruction.
|
||||
* b) Physical address entry
|
||||
* VA + entry has bit 31 set, and the entry (not the sum) has bit 22 clear.
|
||||
* Bits 0-21 contain the difference between virtual and physical address.
|
||||
* c) Invalid entry
|
||||
* VA + entry has bit 31 set, entry has bit 22 set. Entry is invalid and
|
||||
* addr_cache_miss must be called.
|
||||
*
|
||||
* In all other cases the format is simpler:
|
||||
* a) Pointer entry: Bit 0 clear, rest difference to pointer to start of physical page
|
||||
* b) Physical entry: Bit 0 set, Bit 1 clear, rest difference to physical address
|
||||
* c) Invalid entry: Bit 0 set, Bit 1 set
|
||||
*/
|
||||
|
||||
#define AC_NUM_ENTRIES (((1ull << 32) >> 10) * 2)
|
||||
typedef uint8_t *ac_entry;
|
||||
extern ac_entry *addr_cache __asm__("addr_cache");
|
||||
|
||||
#if defined(__i386__) && !defined(NO_TRANSLATION)
|
||||
#define AC_SET_ENTRY_PTR(entry, va, ptr) \
|
||||
entry = (ptr) - (va);
|
||||
#define AC_NOT_PTR 0x80000000
|
||||
#define AC_INVALID (1 << 22)
|
||||
#define AC_SET_ENTRY_PHYS(entry, va, pa) \
|
||||
entry = (ac_entry)(((pa) - (va)) >> 10); \
|
||||
entry += (~(uintptr_t)((va) + entry) & AC_NOT_PTR);
|
||||
#define AC_SET_ENTRY_INVALID(entry, va) \
|
||||
entry = (ac_entry)(AC_INVALID); \
|
||||
entry += (~(uintptr_t)((va) + entry) & AC_NOT_PTR);
|
||||
#else
|
||||
#define AC_SET_ENTRY_PTR(entry, va, ptr) \
|
||||
entry = (ptr) - (va);
|
||||
#define AC_NOT_PTR 0x1
|
||||
#define AC_INVALID 0x2
|
||||
#define AC_FLAGS 0x3
|
||||
#define AC_SET_ENTRY_PHYS(entry, va, pa) \
|
||||
entry = (ac_entry)(((pa) - (va)) | AC_NOT_PTR);
|
||||
#define AC_SET_ENTRY_INVALID(entry, va) \
|
||||
entry = (ac_entry)(AC_INVALID | AC_NOT_PTR);
|
||||
#endif
|
||||
|
||||
bool addr_cache_pagefault(void *addr);
|
||||
void *addr_cache_miss(uint32_t addr, bool writing, fault_proc *fault) __asm__("addr_cache_miss");
|
||||
void addr_cache_flush(void);
|
||||
void mmu_dump_tables(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
include/armv5te/os/os.h
Normal file
47
include/armv5te/os/os.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef OS_H
|
||||
#define OS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef IS_IOS_BUILD
|
||||
int iOS_is_debugger_attached();
|
||||
#endif
|
||||
|
||||
#if !defined(__x86_64__) && !defined(NO_TRANSLATION) && (defined(_WIN32) || defined(WIN32))
|
||||
#define OS_HAS_PAGEFAULT_HANDLER 1
|
||||
#else
|
||||
#define OS_HAS_PAGEFAULT_HANDLER 0
|
||||
#endif
|
||||
|
||||
void *os_reserve(size_t size);
|
||||
void *os_alloc_executable(size_t size);
|
||||
void os_free(void *ptr, size_t size);
|
||||
|
||||
#if OS_HAS_PAGEFAULT_HANDLER
|
||||
// The Win32 mechanism to handle pagefaults uses SEH, which requires a linked
|
||||
// list of handlers on the stack. The frame has to stay alive on the stack and
|
||||
// armed during all addr_cache accesses.
|
||||
|
||||
typedef struct { void *prev, *function; } os_exception_frame_t;
|
||||
void os_faulthandler_arm(os_exception_frame_t *frame);
|
||||
void os_faulthandler_unarm(os_exception_frame_t *frame);
|
||||
|
||||
void *os_commit(void *addr, size_t size);
|
||||
void *os_sparse_commit(void *page, size_t size);
|
||||
void os_sparse_decommit(void *page, size_t size);
|
||||
#endif
|
||||
|
||||
void addr_cache_init();
|
||||
void addr_cache_deinit();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
48
include/armv5te/translate.h
Normal file
48
include/armv5te/translate.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Declarations for translate.c */
|
||||
|
||||
#ifndef H_TRANSLATE
|
||||
#define H_TRANSLATE
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "fixings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(pack(push, 1))
|
||||
#endif
|
||||
|
||||
struct translation {
|
||||
uintptr_t unused;
|
||||
void** jump_table;
|
||||
uint32_t *start_ptr;
|
||||
uint32_t *end_ptr;
|
||||
}
|
||||
#if !defined(_MSC_VER)
|
||||
__attribute__((packed))
|
||||
#endif
|
||||
;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(pack(pop))
|
||||
#endif
|
||||
|
||||
extern struct translation translation_table[] __asm__("translation_table");
|
||||
#define INSN_BUFFER_SIZE 0x1000000
|
||||
|
||||
bool translate_init();
|
||||
void translate_deinit();
|
||||
void translate(uint32_t start_pc, uint32_t *insnp);
|
||||
void flush_translations();
|
||||
void invalidate_translation(int index);
|
||||
void translate_fix_pc();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
179
include/armv5te/uArm/CPU_2.h
Normal file
179
include/armv5te/uArm/CPU_2.h
Normal file
@@ -0,0 +1,179 @@
|
||||
#ifndef _CPU_H_
|
||||
#define _CPU_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#define ARM_V6 //define to allow v6 instructions
|
||||
//#define THUMB_2 //define to allow Thumb2
|
||||
|
||||
#include "../../pxa260/pxa260_types.h"
|
||||
|
||||
struct ArmCpu;
|
||||
|
||||
#define ARM_SR_N 0x80000000UL
|
||||
#define ARM_SR_Z 0x40000000UL
|
||||
#define ARM_SR_C 0x20000000UL
|
||||
#define ARM_SR_V 0x10000000UL
|
||||
#define ARM_SR_Q 0x08000000UL
|
||||
#ifdef ARM_V6 //V6KT2, but without T2 to be exact (we implement things like MLS, but not Thumb2 or ThumbEE)
|
||||
#define ARM_SR_J 0x01000000UL
|
||||
#define ARM_SR_E 0x00000200UL
|
||||
#define ARM_SR_A 0x00000100UL
|
||||
#define ARM_SR_GE_0 0x00010000UL
|
||||
#define ARM_SR_GE_1 0x00020000UL
|
||||
#define ARM_SR_GE_2 0x00040000UL
|
||||
#define ARM_SR_GE_3 0x00080000UL
|
||||
#define ARM_SR_GE_MASK 0x000F0000UL
|
||||
#define ARM_SR_GE_SHIFT 16
|
||||
#endif
|
||||
#define ARM_SR_I 0x00000080UL
|
||||
#define ARM_SR_F 0x00000040UL
|
||||
#define ARM_SR_T 0x00000020UL
|
||||
#define ARM_SR_M 0x0000001FUL
|
||||
|
||||
#define ARM_SR_MODE_USR 0x00000010UL
|
||||
#define ARM_SR_MODE_FIQ 0x00000011UL
|
||||
#define ARM_SR_MODE_IRQ 0x00000012UL
|
||||
#define ARM_SR_MODE_SVC 0x00000013UL
|
||||
#define ARM_SR_MODE_ABT 0x00000017UL
|
||||
#define ARM_SR_MODE_UND 0x0000001BUL
|
||||
#define ARM_SR_MODE_SYS 0x0000001FUL
|
||||
|
||||
#define ARV_VECTOR_OFFT_RST 0x00000000UL
|
||||
#define ARM_VECTOR_OFFT_UND 0x00000004UL
|
||||
#define ARM_VECTOR_OFFT_SWI 0x00000008UL
|
||||
#define ARM_VECTOR_OFFT_P_ABT 0x0000000CUL
|
||||
#define ARM_VECTOR_OFFT_D_ABT 0x00000010UL
|
||||
#define ARM_VECTOR_OFFT_UNUSED 0x00000014UL
|
||||
#define ARM_VECTOR_OFFT_IRQ 0x00000018UL
|
||||
#define ARM_VECTOR_OFFT_FIQ 0x0000001CUL
|
||||
|
||||
#define HYPERCALL_ARM 0xF7BBBBBBUL
|
||||
#define HYPERCALL_THUMB 0xBBBBUL
|
||||
|
||||
//the following are for cpuGetRegExternal() and are generally used for debugging purposes
|
||||
#define ARM_REG_NUM_CPSR 16
|
||||
#define ARM_REG_NUM_SPSR 17
|
||||
|
||||
struct ArmCpu;
|
||||
|
||||
typedef Boolean (*ArmCoprocRegXferF) (struct ArmCpu* cpu, void* userData, Boolean two/* MCR2/MRC2 ? */, Boolean MRC, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2);
|
||||
typedef Boolean (*ArmCoprocDatProcF) (struct ArmCpu* cpu, void* userData, Boolean two/* CDP2 ? */, UInt8 op1, UInt8 CRd, UInt8 CRn, UInt8 CRm, UInt8 op2);
|
||||
typedef Boolean (*ArmCoprocMemAccsF) (struct ArmCpu* cpu, void* userData, Boolean two /* LDC2/STC2 ? */, Boolean N, Boolean store, UInt8 CRd, UInt32 addr, UInt8* option /* NULL if none */);
|
||||
typedef Boolean (*ArmCoprocTwoRegF) (struct ArmCpu* cpu, void* userData, Boolean MRRC, UInt8 op, UInt8 Rd, UInt8 Rn, UInt8 CRm);
|
||||
|
||||
typedef Boolean (*ArmCpuMemF) (struct ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean priviledged, UInt8* fsr); //read/write
|
||||
typedef Boolean (*ArmCpuHypercall) (struct ArmCpu* cpu); //return true if handled
|
||||
typedef void (*ArmCpuEmulErr) (struct ArmCpu* cpu, const char* err_str);
|
||||
|
||||
typedef void (*ArmSetFaultAdrF) (struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus);
|
||||
|
||||
#include "icache.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
coprocessors:
|
||||
|
||||
0 - DSP (pxa only)
|
||||
0, 1 - WMMX (pxa only)
|
||||
11 - VFP (arm standard)
|
||||
15 - system control (arm standard)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
ArmCoprocRegXferF regXfer;
|
||||
ArmCoprocDatProcF dataProcessing;
|
||||
ArmCoprocMemAccsF memAccess;
|
||||
ArmCoprocTwoRegF twoRegF;
|
||||
void* userData;
|
||||
|
||||
}ArmCoprocessor;
|
||||
|
||||
typedef struct{
|
||||
|
||||
UInt32 R13, R14;
|
||||
UInt32 SPSR; //usr mode doesn't have an SPSR
|
||||
}ArmBankedRegs;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct ArmCpu{
|
||||
|
||||
UInt32 regs[16]; //current active regs as per current mode
|
||||
UInt32 CPSR, SPSR;
|
||||
|
||||
ArmBankedRegs bank_usr; //usr regs when in another mode
|
||||
ArmBankedRegs bank_svc; //svc regs when in another mode
|
||||
ArmBankedRegs bank_abt; //abt regs when in another mode
|
||||
ArmBankedRegs bank_und; //und regs when in another mode
|
||||
ArmBankedRegs bank_irq; //irq regs when in another mode
|
||||
ArmBankedRegs bank_fiq; //fiq regs when in another mode
|
||||
UInt32 extra_regs[5]; //fiq regs when not in fiq mode, usr regs when in fiq mode. R8-12
|
||||
|
||||
UInt16 waitingIrqs;
|
||||
UInt16 waitingFiqs;
|
||||
UInt16 CPAR;
|
||||
|
||||
ArmCoprocessor coproc[16]; //coprocessors
|
||||
|
||||
// various other cpu config options
|
||||
UInt32 vectorBase; //address of vector base
|
||||
|
||||
#ifdef ARM_V6
|
||||
|
||||
Boolean EEE; //endianness one exception entry
|
||||
Boolean impreciseAbtWaiting;
|
||||
#endif
|
||||
|
||||
ArmCpuMemF memF;
|
||||
ArmCpuEmulErr emulErrF;
|
||||
ArmCpuHypercall hypercallF;
|
||||
ArmSetFaultAdrF setFaultAdrF;
|
||||
|
||||
icache ic;
|
||||
|
||||
void* userData; //shared by all callbacks
|
||||
}ArmCpu;
|
||||
|
||||
|
||||
Err cpuInit(ArmCpu* cpu, UInt32 pc, ArmCpuMemF memF, ArmCpuEmulErr emulErrF, ArmCpuHypercall hypercallF, ArmSetFaultAdrF setFaultAdrF);
|
||||
Err cpuDeinit(ArmCpu* cp);
|
||||
void cpuCycle(ArmCpu* cpu);
|
||||
void cpuIrq(ArmCpu* cpu, Boolean fiq, Boolean raise); //unraise when acknowledged
|
||||
|
||||
#ifdef ARM_V6
|
||||
|
||||
void cpuSignalImpreciseAbt(ArmCpu* cpu, Boolean raise);
|
||||
|
||||
#endif
|
||||
|
||||
UInt32 cpuGetRegExternal(ArmCpu* cpu, UInt8 reg);
|
||||
void cpuSetReg(ArmCpu* cpu, UInt8 reg, UInt32 val);
|
||||
|
||||
void cpuCoprocessorRegister(ArmCpu* cpu, UInt8 cpNum, ArmCoprocessor* coproc);
|
||||
void cpuCoprocessorUnregister(ArmCpu* cpu, UInt8 cpNum);
|
||||
|
||||
void cpuSetVectorAddr(ArmCpu* cpu, UInt32 adr);
|
||||
|
||||
UInt16 cpuGetCPAR(ArmCpu* cpu);
|
||||
void cpuSetCPAR(ArmCpu* cpu, UInt16 cpar);
|
||||
|
||||
void cpuIcacheInval(ArmCpu* cpu);
|
||||
void cpuIcacheInvalAddr(ArmCpu* cpu, UInt32 addr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
include/armv5te/uArm/icache.h
Normal file
47
include/armv5te/uArm/icache.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef ICACHE_H
|
||||
#define ICACHE_H
|
||||
|
||||
|
||||
#include "../../pxa260/pxa260_types.h"
|
||||
#include "CPU_2.h"
|
||||
|
||||
|
||||
#define ICACHE_L 5UL //line size is 2^L bytes
|
||||
#define ICACHE_S 6UL //number of sets is 2^S
|
||||
#define ICACHE_A 3UL //set associativity
|
||||
|
||||
|
||||
#define ICACHE_LINE_SZ (1UL << ICACHE_L)
|
||||
#define ICACHE_BUCKET_NUM (1UL << ICACHE_S)
|
||||
#define ICACHE_BUCKET_SZ (ICACHE_A)
|
||||
|
||||
|
||||
#define ICACHE_ADDR_MASK ((UInt32)-ICACHE_LINE_SZ)
|
||||
#define ICACHE_USED_MASK 1UL
|
||||
#define ICACHE_PRIV_MASK 2UL
|
||||
|
||||
typedef struct{
|
||||
|
||||
UInt32 info; //addr, masks
|
||||
UInt8 data[ICACHE_LINE_SZ];
|
||||
|
||||
}icacheLine;
|
||||
|
||||
typedef struct{
|
||||
|
||||
struct ArmCpu* cpu;
|
||||
ArmCpuMemF memF;
|
||||
icacheLine lines[ICACHE_BUCKET_NUM][ICACHE_BUCKET_SZ];
|
||||
UInt8 ptr[ICACHE_BUCKET_NUM];
|
||||
|
||||
}icache;
|
||||
|
||||
|
||||
void icacheInit(icache* ic, struct ArmCpu* cpu, ArmCpuMemF memF);
|
||||
Boolean icacheFetch(icache* ic, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsr, void* buf);
|
||||
void icacheInval(icache* ic);
|
||||
void icacheInvalAddr(icache* ic, UInt32 addr);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
21
include/armv5te/uArm/uArmGlue.h
Normal file
21
include/armv5te/uArm/uArmGlue.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef UARM_GLUE_H
|
||||
#define UARM_GLUE_H
|
||||
|
||||
#include "CPU_2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Boolean uArmMemAccess(struct ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean priviledged, UInt8* fsr); //read/write
|
||||
Boolean uArmHypercall(struct ArmCpu* cpu);//return true if handled
|
||||
void uArmEmulErr (struct ArmCpu* cpu, const char* err_str);
|
||||
void uArmSetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus);
|
||||
|
||||
void uArmInitCpXX(ArmCpu* cpu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
108
include/dbvz.h
Normal file
108
include/dbvz.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef DBVZ_H
|
||||
#define DBVZ_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//interrupt names
|
||||
#define DBVZ_INT_EMIQ 0x00800000//level 7
|
||||
#define DBVZ_INT_RTI 0x00400000//level 4
|
||||
#define DBVZ_INT_SPI1 0x00200000//level 1<->6, configurable, datasheet is contraditory on this one
|
||||
#define DBVZ_INT_IRQ5 0x00100000//level 5
|
||||
#define DBVZ_INT_IRQ6 0x00080000//level 6
|
||||
#define DBVZ_INT_IRQ3 0x00040000//level 3
|
||||
#define DBVZ_INT_IRQ2 0x00020000//level 2
|
||||
#define DBVZ_INT_IRQ1 0x00010000//level 1
|
||||
#define DBVZ_INT_PWM2 0x00002000//level 1<->6, configurable
|
||||
#define DBVZ_INT_UART2 0x00001000//level 1<->6, configurable
|
||||
#define DBVZ_INT_INT3 0x00000800//level 4
|
||||
#define DBVZ_INT_INT2 0x00000400//level 4
|
||||
#define DBVZ_INT_INT1 0x00000200//level 4
|
||||
#define DBVZ_INT_INT0 0x00000100//level 4
|
||||
#define DBVZ_INT_PWM1 0x00000080//level 6
|
||||
#define DBVZ_INT_KB 0x00000040//level 4
|
||||
#define DBVZ_INT_TMR2 0x00000020//level 1<->6, configurable
|
||||
#define DBVZ_INT_RTC 0x00000010//level 4
|
||||
#define DBVZ_INT_WDT 0x00000008//level 4
|
||||
#define DBVZ_INT_UART1 0x00000004//level 4
|
||||
#define DBVZ_INT_TMR1 0x00000002//level 6
|
||||
#define DBVZ_INT_SPI2 0x00000001//level 4
|
||||
|
||||
//reasons a timer is triggered
|
||||
#define DBVZ_TIMER_REASON_SYSCLK 0x00
|
||||
#define DBVZ_TIMER_REASON_TIN 0x01
|
||||
#define DBVZ_TIMER_REASON_CLK32 0x02
|
||||
|
||||
//chip names
|
||||
enum{
|
||||
DBVZ_CHIP_BEGIN = 0,
|
||||
DBVZ_CHIP_A0_ROM = 0,
|
||||
DBVZ_CHIP_A1_USB,
|
||||
DBVZ_CHIP_B0_SED,
|
||||
DBVZ_CHIP_B1_NIL,
|
||||
//DBVZ_CHIP_CX_RAM, //CSC* is owned by CSD during normal operation
|
||||
DBVZ_CHIP_DX_RAM,
|
||||
DBVZ_CHIP_00_EMU,
|
||||
DBVZ_CHIP_REGISTERS,
|
||||
DBVZ_CHIP_NONE,
|
||||
DBVZ_CHIP_END
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool enable;
|
||||
uint32_t start;
|
||||
uint32_t lineSize;//the size of a single chip select line, multiply by 2 to get the range size for RAM
|
||||
uint32_t mask;//the address lines the chip responds to, so 0x10000 on an chip with 16 address lines will return the value at 0x0000
|
||||
|
||||
//attributes
|
||||
bool inBootMode;
|
||||
bool readOnly;
|
||||
bool readOnlyForProtectedMemory;
|
||||
bool supervisorOnlyProtectedMemory;
|
||||
uint32_t unprotectedSize;
|
||||
}dbvz_chip_t;
|
||||
|
||||
//variables
|
||||
extern dbvz_chip_t dbvzChipSelects[];
|
||||
extern uint8_t dbvzReg[];//needed for direct execution of the DBVZ regs without a RAM access function
|
||||
extern uint16_t* dbvzFramebuffer;
|
||||
extern uint16_t dbvzFramebufferWidth;
|
||||
extern uint16_t dbvzFramebufferHeight;
|
||||
|
||||
//CPU
|
||||
void dbvzLcdRender(void);
|
||||
bool dbvzIsPllOn(void);
|
||||
bool m515BacklightAmplifierState(void);
|
||||
bool dbvzAreRegistersXXFFMapped(void);
|
||||
bool sed1376ClockConnected(void);
|
||||
void ads7846OverridePenState(bool value);
|
||||
void m5XXRefreshTouchState(void);//just refreshes the touchscreen
|
||||
void m5XXRefreshInputState(void);//refreshes touchscreen, buttons and docked status
|
||||
//int32_t interruptAcknowledge(int32_t intLevel);//this is in m68kexternal.h
|
||||
|
||||
//memory errors
|
||||
void dbvzSetBusErrorTimeOut(uint32_t address, bool isWrite);
|
||||
void dbvzSetPrivilegeViolation(uint32_t address, bool isWrite);
|
||||
void dbvzSetWriteProtectViolation(uint32_t address);
|
||||
|
||||
//memory accessors
|
||||
uint8_t dbvzGetRegister8(uint32_t address);
|
||||
uint16_t dbvzGetRegister16(uint32_t address);
|
||||
uint32_t dbvzGetRegister32(uint32_t address);
|
||||
void dbvzSetRegister8(uint32_t address, uint8_t value);
|
||||
void dbvzSetRegister16(uint32_t address, uint16_t value);
|
||||
void dbvzSetRegister32(uint32_t address, uint32_t value);
|
||||
|
||||
//config
|
||||
void dbvzReset(void);
|
||||
void dbvzLoadBootloader(uint8_t* data, uint32_t size);
|
||||
void dbvzSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
|
||||
uint32_t dbvzStateSize(void);
|
||||
void dbvzSaveState(uint8_t* data);
|
||||
void dbvzLoadState(uint8_t* data);
|
||||
void dbvzLoadStateFinished(void);
|
||||
|
||||
void dbvzExecute(void);
|
||||
|
||||
#endif
|
||||
@@ -11,12 +11,12 @@ static uint8_t getPortKValue(void);
|
||||
static uint8_t getPortMValue(void);
|
||||
|
||||
//basic accessors
|
||||
static uint8_t registerArrayRead8(uint32_t address){return BUFFER_READ_8(palmReg, address, 0xFFF);}
|
||||
static uint16_t registerArrayRead16(uint32_t address){return BUFFER_READ_16(palmReg, address, 0xFFF);}
|
||||
static uint32_t registerArrayRead32(uint32_t address){return BUFFER_READ_32(palmReg, address, 0xFFF);}
|
||||
static void registerArrayWrite8(uint32_t address, uint8_t value){BUFFER_WRITE_8(palmReg, address, 0xFFF, value);}
|
||||
static void registerArrayWrite16(uint32_t address, uint16_t value){BUFFER_WRITE_16(palmReg, address, 0xFFF, value);}
|
||||
static void registerArrayWrite32(uint32_t address, uint32_t value){BUFFER_WRITE_32(palmReg, address, 0xFFF, value);}
|
||||
static uint8_t registerArrayRead8(uint32_t address){return M68K_BUFFER_READ_8(dbvzReg, address, 0xFFF);}
|
||||
static uint16_t registerArrayRead16(uint32_t address){return M68K_BUFFER_READ_16(dbvzReg, address, 0xFFF);}
|
||||
static uint32_t registerArrayRead32(uint32_t address){return M68K_BUFFER_READ_32(dbvzReg, address, 0xFFF);}
|
||||
static void registerArrayWrite8(uint32_t address, uint8_t value){M68K_BUFFER_WRITE_8(dbvzReg, address, 0xFFF, value);}
|
||||
static void registerArrayWrite16(uint32_t address, uint16_t value){M68K_BUFFER_WRITE_16(dbvzReg, address, 0xFFF, value);}
|
||||
static void registerArrayWrite32(uint32_t address, uint32_t value){M68K_BUFFER_WRITE_32(dbvzReg, address, 0xFFF, value);}
|
||||
|
||||
//interrupt setters, used for setting an interrupt with masking by IMR and logging in IPR
|
||||
static void setIprIsrBit(uint32_t interruptBit){
|
||||
@@ -40,21 +40,21 @@ static uint8_t spi1RxFifoEntrys(void){
|
||||
}
|
||||
|
||||
static uint16_t spi1RxFifoRead(void){
|
||||
uint16_t value = spi1RxFifo[spi1RxReadPosition];
|
||||
if(spi1RxFifoEntrys() > 0)
|
||||
spi1RxReadPosition = (spi1RxReadPosition + 1) % 9;
|
||||
spi1RxOverflowed = false;
|
||||
return value;
|
||||
return spi1RxFifo[spi1RxReadPosition];
|
||||
}
|
||||
|
||||
static void spi1RxFifoWrite(uint16_t value){
|
||||
if(spi1RxFifoEntrys() < 8){
|
||||
spi1RxWritePosition = (spi1RxWritePosition + 1) % 9;
|
||||
spi1RxFifo[spi1RxWritePosition] = value;
|
||||
}
|
||||
else{
|
||||
spi1RxOverflowed = true;
|
||||
debugLog("SPI1 RX FIFO overflowed\n");
|
||||
}
|
||||
spi1RxFifo[spi1RxWritePosition] = value;
|
||||
}
|
||||
|
||||
static void spi1RxFifoFlush(void){
|
||||
@@ -69,10 +69,9 @@ static uint8_t spi1TxFifoEntrys(void){
|
||||
}
|
||||
|
||||
static uint16_t spi1TxFifoRead(void){
|
||||
uint16_t value = spi1TxFifo[spi1TxReadPosition];
|
||||
//dont need a safety check here, the emulator will always check that data is present before trying to access it
|
||||
spi1TxReadPosition = (spi1TxReadPosition + 1) % 9;
|
||||
return value;
|
||||
return spi1TxFifo[spi1TxReadPosition];
|
||||
}
|
||||
|
||||
static void spi1TxFifoWrite(uint16_t value){
|
||||
@@ -86,6 +85,82 @@ static void spi1TxFifoFlush(void){
|
||||
spi1TxReadPosition = spi1TxWritePosition;
|
||||
}
|
||||
|
||||
//UART1 FIFO accessors
|
||||
static uint8_t uart1RxFifoEntrys(void){
|
||||
if(palmIrDataSize){
|
||||
uint32_t fifoEntrys = palmIrDataSize();
|
||||
|
||||
return FAST_MIN(fifoEntrys, 12);
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint16_t uart1RxFifoRead(void){
|
||||
if(palmIrDataReceive)
|
||||
return palmIrDataReceive();
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
//no uart1RxFifoWrite, RX FIFO is written to externally
|
||||
|
||||
static void uart1RxFifoFlush(void){
|
||||
if(palmIrDataFlush)
|
||||
palmIrDataFlush();
|
||||
}
|
||||
|
||||
static uint8_t uart1TxFifoEntrys(void){
|
||||
return 0;//all entrys are transmitted instantly so none are left inside the CPU
|
||||
}
|
||||
|
||||
//no uart1TxFifoRead, TX FIFO is read externally
|
||||
|
||||
static void uart1TxFifoWrite(uint16_t value){
|
||||
if(palmIrDataSend)
|
||||
palmIrDataSend(value);
|
||||
}
|
||||
|
||||
static void uart1TxFifoFlush(void){
|
||||
//do nothing, its always empty
|
||||
}
|
||||
|
||||
//UART2 FIFO accessors
|
||||
static uint8_t uart2RxFifoEntrys(void){
|
||||
if(palmSerialDataSize){
|
||||
uint32_t fifoEntrys = palmSerialDataSize();
|
||||
|
||||
return FAST_MIN(fifoEntrys, 64);
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint16_t uart2RxFifoRead(void){
|
||||
if(palmSerialDataReceive)
|
||||
return palmSerialDataReceive();
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
//no uart2RxFifoWrite, RX FIFO is written to externally
|
||||
|
||||
static void uart2RxFifoFlush(void){
|
||||
if(palmSerialDataFlush)
|
||||
palmSerialDataFlush();
|
||||
}
|
||||
|
||||
static uint8_t uart2TxFifoEntrys(void){
|
||||
return 0;//all entrys are transmitted instantly so none are left inside the CPU
|
||||
}
|
||||
|
||||
//no uart2TxFifoRead, TX FIFO is read externally
|
||||
|
||||
static void uart2TxFifoWrite(uint16_t value){
|
||||
if(palmSerialDataSend)
|
||||
palmSerialDataSend(value);
|
||||
}
|
||||
|
||||
static void uart2TxFifoFlush(void){
|
||||
//do nothing, its always empty
|
||||
}
|
||||
|
||||
//PWM1 FIFO accessors
|
||||
static uint8_t pwm1FifoEntrys(void){
|
||||
//check for wraparound
|
||||
@@ -95,7 +170,6 @@ static uint8_t pwm1FifoEntrys(void){
|
||||
}
|
||||
|
||||
int32_t pwm1FifoRunSample(int32_t now, int32_t clockOffset){
|
||||
uint8_t sample = pwm1Fifo[pwm1ReadPosition];
|
||||
uint16_t period = registerArrayRead8(PWMP1) + 2;
|
||||
uint16_t pwmc1 = registerArrayRead16(PWMC1);
|
||||
uint8_t prescaler = (pwmc1 >> 8 & 0x7F) + 1;
|
||||
@@ -103,12 +177,17 @@ int32_t pwm1FifoRunSample(int32_t now, int32_t clockOffset){
|
||||
uint8_t repeat = 1 << (pwmc1 >> 2 & 0x03);
|
||||
int32_t audioNow = now + clockOffset;
|
||||
int32_t audioSampleDuration = (pwmc1 & 0x8000)/*CLKSRC*/ ? audioGetFramePercentIncrementFromClk32s(period * prescaler * clockDivider) : audioGetFramePercentIncrementFromSysclks(period * prescaler * clockDivider);
|
||||
float dutyCycle = fMin((float)sample / period, 1.00);
|
||||
float dutyCycle;
|
||||
uint8_t index;
|
||||
|
||||
//try to get next sample, if none are available play old sample
|
||||
if(pwm1FifoEntrys() > 0)
|
||||
pwm1ReadPosition = (pwm1ReadPosition + 1) % 6;
|
||||
dutyCycle = FAST_MIN((float)pwm1Fifo[pwm1ReadPosition] / period, 1.00);
|
||||
|
||||
for(index = 0; index < repeat; index++){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(audioNow + audioSampleDuration >= AUDIO_CLOCK_RATE)
|
||||
if(audioNow + audioSampleDuration >= DBVZ_AUDIO_MAX_CLOCK_RATE)
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -117,15 +196,11 @@ int32_t pwm1FifoRunSample(int32_t now, int32_t clockOffset){
|
||||
audioNow += audioSampleDuration;
|
||||
}
|
||||
|
||||
//remove used entry
|
||||
if(pwm1FifoEntrys() > 0)
|
||||
pwm1ReadPosition = (pwm1ReadPosition + 1) % 6;
|
||||
|
||||
//check for interrupt
|
||||
if(pwm1FifoEntrys() < 2){
|
||||
//trigger interrupt if enabled
|
||||
if(pwmc1 & 0x0040)
|
||||
setIprIsrBit(INT_PWM1);
|
||||
setIprIsrBit(DBVZ_INT_PWM1);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
registerArrayWrite16(PWMC1, pwmc1 | 0x0080);//set IRQ bit
|
||||
@@ -143,22 +218,23 @@ static void pwm1FifoWrite(uint8_t value){
|
||||
|
||||
static void pwm1FifoFlush(void){
|
||||
pwm1ReadPosition = pwm1WritePosition;
|
||||
pwm1Fifo[pwm1WritePosition] = 0x00;
|
||||
}
|
||||
|
||||
//register setters
|
||||
static void setCsa(uint16_t value){
|
||||
chips[CHIP_A0_ROM].enable = value & 0x0001;
|
||||
chips[CHIP_A0_ROM].readOnly = !!(value & 0x8000);
|
||||
chips[CHIP_A0_ROM].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].enable = value & 0x0001;
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].readOnly = !!(value & 0x8000);
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//CSA is now just a normal chip select
|
||||
if(chips[CHIP_A0_ROM].enable && chips[CHIP_A0_ROM].inBootMode)
|
||||
chips[CHIP_A0_ROM].inBootMode = false;
|
||||
if(dbvzChipSelects[DBVZ_CHIP_A0_ROM].enable && dbvzChipSelects[DBVZ_CHIP_A0_ROM].inBootMode)
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].inBootMode = false;
|
||||
|
||||
chips[CHIP_A1_USB].enable = chips[CHIP_A0_ROM].enable;
|
||||
chips[CHIP_A1_USB].readOnly = chips[CHIP_A0_ROM].readOnly;
|
||||
chips[CHIP_A1_USB].start = chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize;
|
||||
chips[CHIP_A1_USB].lineSize = chips[CHIP_A0_ROM].lineSize;
|
||||
dbvzChipSelects[DBVZ_CHIP_A1_USB].enable = dbvzChipSelects[DBVZ_CHIP_A0_ROM].enable;
|
||||
dbvzChipSelects[DBVZ_CHIP_A1_USB].readOnly = dbvzChipSelects[DBVZ_CHIP_A0_ROM].readOnly;
|
||||
dbvzChipSelects[DBVZ_CHIP_A1_USB].start = dbvzChipSelects[DBVZ_CHIP_A0_ROM].start + dbvzChipSelects[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
dbvzChipSelects[DBVZ_CHIP_A1_USB].lineSize = dbvzChipSelects[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
|
||||
registerArrayWrite16(CSA, value & 0x81FF);
|
||||
}
|
||||
@@ -166,17 +242,25 @@ static void setCsa(uint16_t value){
|
||||
static void setCsb(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_B0_SED].enable = value & 0x0001;
|
||||
chips[CHIP_B0_SED].readOnly = !!(value & 0x8000);
|
||||
chips[CHIP_B0_SED].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].enable = value & 0x0001;
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].readOnly = !!(value & 0x8000);
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_B0_SED].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[CHIP_B0_SED].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0001)
|
||||
chips[CHIP_B0_SED].unprotectedSize = chips[CHIP_B0_SED].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].unprotectedSize = dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
else
|
||||
chips[CHIP_B0_SED].unprotectedSize = chips[CHIP_B0_SED].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].unprotectedSize = dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].enable = dbvzChipSelects[DBVZ_CHIP_B0_SED].enable;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].readOnly = dbvzChipSelects[DBVZ_CHIP_B0_SED].readOnly;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].start = dbvzChipSelects[DBVZ_CHIP_B0_SED].start + dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].lineSize = dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].supervisorOnlyProtectedMemory = dbvzChipSelects[DBVZ_CHIP_B0_SED].supervisorOnlyProtectedMemory;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].readOnlyForProtectedMemory = dbvzChipSelects[DBVZ_CHIP_B0_SED].readOnlyForProtectedMemory;
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].unprotectedSize = dbvzChipSelects[DBVZ_CHIP_B0_SED].unprotectedSize;
|
||||
|
||||
registerArrayWrite16(CSB, value & 0xF9FF);
|
||||
}
|
||||
@@ -184,20 +268,22 @@ static void setCsb(uint16_t value){
|
||||
static void setCsd(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_DX_RAM].enable = value & 0x0001;
|
||||
chips[CHIP_DX_RAM].readOnly = !!(value & 0x8000);
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].enable = value & 0x0001;
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].readOnly = !!(value & 0x8000);
|
||||
if(csControl1 & 0x0040 && value & 0x0200)
|
||||
chips[CHIP_DX_RAM].lineSize = 0x800000/*8mb*/ << (value >> 1 & 0x0001);
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].lineSize = 0x800000/*8mb*/ << (value >> 1 & 0x0001);
|
||||
else
|
||||
chips[CHIP_DX_RAM].lineSize = 0x8000/*32kb*/ << (value >> 1 & 0x0007);
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].lineSize = 0x8000/*32kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_DX_RAM].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[CHIP_DX_RAM].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0010)
|
||||
chips[CHIP_DX_RAM].unprotectedSize = chips[CHIP_DX_RAM].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].unprotectedSize = dbvzChipSelects[DBVZ_CHIP_DX_RAM].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
else
|
||||
chips[CHIP_DX_RAM].unprotectedSize = chips[CHIP_DX_RAM].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].unprotectedSize = dbvzChipSelects[DBVZ_CHIP_DX_RAM].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
|
||||
//debugLog("RAM unprotected size:0x%08X, bits:0x%02X\n", dbvzChipSelects[DBVZ_CHIP_DX_RAM].unprotectedSize, ((value >> 11 & 0x0003) | (csControl1 & 0x4000 && csControl1 & 0x0010) * 0x0004));
|
||||
|
||||
registerArrayWrite16(CSD, value);
|
||||
}
|
||||
@@ -207,11 +293,11 @@ static void setCsgba(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_A0_ROM].start = (csugba >> 12 & 0x0007) << 29 | value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].start = (csugba >> 12 & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_A0_ROM].start = value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_A0_ROM].start = value >> 1 << 14;
|
||||
|
||||
chips[CHIP_A1_USB].start = chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize;
|
||||
dbvzChipSelects[DBVZ_CHIP_A1_USB].start = dbvzChipSelects[DBVZ_CHIP_A0_ROM].start + dbvzChipSelects[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
|
||||
registerArrayWrite16(CSGBA, value & 0xFFFE);
|
||||
}
|
||||
@@ -221,9 +307,11 @@ static void setCsgbb(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_B0_SED].start = (csugba >> 8 & 0x0007) << 29 | value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].start = (csugba >> 8 & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_B0_SED].start = value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_B0_SED].start = value >> 1 << 14;
|
||||
|
||||
dbvzChipSelects[DBVZ_CHIP_B1_NIL].start = dbvzChipSelects[DBVZ_CHIP_B0_SED].start + dbvzChipSelects[DBVZ_CHIP_B0_SED].lineSize;
|
||||
|
||||
registerArrayWrite16(CSGBB, value & 0xFFFE);
|
||||
}
|
||||
@@ -233,9 +321,9 @@ static void setCsgbd(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_DX_RAM].start = (csugba & 0x0007) << 29 | value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].start = (csugba & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_DX_RAM].start = value >> 1 << 14;
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].start = value >> 1 << 14;
|
||||
|
||||
registerArrayWrite16(CSGBD, value & 0xFFFE);
|
||||
}
|
||||
@@ -246,19 +334,19 @@ static void updateCsdAddressLines(void){
|
||||
|
||||
if(registerArrayRead16(CSD) & 0x0200 && sdctrl & 0x8000 && dramc & 0x8000 && !(dramc & 0x0400)){
|
||||
//this register can remap address lines, that behavior is way too CPU intensive and complicated so only the "memory testing" and "correct" behavior is being emulated
|
||||
chips[CHIP_DX_RAM].mask = 0x003FFFFF;
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].mask = 0x003FFFFF;
|
||||
|
||||
//address line 23 is enabled
|
||||
if((sdctrl & 0x000C) == 0x0008)
|
||||
chips[CHIP_DX_RAM].mask |= 0x00800000;
|
||||
if(!palmEmulatingM500 && (sdctrl & 0x000C) == 0x0008)
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].mask |= 0x00800000;
|
||||
|
||||
//address line 22 is enabled
|
||||
if((sdctrl & 0x0030) == 0x0010)
|
||||
chips[CHIP_DX_RAM].mask |= 0x00400000;
|
||||
if(palmEmulatingM500 || (sdctrl & 0x0030) == 0x0010)
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].mask |= 0x00400000;
|
||||
}
|
||||
else{
|
||||
//RAM is not enabled properly
|
||||
chips[CHIP_DX_RAM].mask = 0x00000000;
|
||||
dbvzChipSelects[DBVZ_CHIP_DX_RAM].mask = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +356,7 @@ static void setPllfsr(uint16_t value){
|
||||
//change frequency if frequency protect bit isnt set
|
||||
if(!(oldPllfsr & 0x4000)){
|
||||
registerArrayWrite16(PLLFSR, (value & 0x4CFF) | (oldPllfsr & 0x8000));//preserve CLK32 bit
|
||||
palmSysclksPerClk32 = sysclksPerClk32();
|
||||
dbvzSysclksPerClk32 = sysclksPerClk32();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,14 +370,14 @@ static void setScr(uint8_t value){
|
||||
//clear violations on writing 1 to them
|
||||
newScr &= ~(value & 0xE0);
|
||||
|
||||
chips[CHIP_REGISTERS].supervisorOnlyProtectedMemory = value & 0x08;
|
||||
dbvzChipSelects[DBVZ_CHIP_REGISTERS].supervisorOnlyProtectedMemory = value & 0x08;
|
||||
|
||||
registerArrayWrite8(SCR, newScr);//must be written before calling setRegisterFFFFAccessMode
|
||||
if((newScr & 0x04) != (oldScr & 0x04)){
|
||||
if(newScr & 0x04)
|
||||
setRegisterXXFFAccessMode();
|
||||
dbvzSetRegisterXXFFAccessMode();
|
||||
else
|
||||
setRegisterFFFFAccessMode();
|
||||
dbvzSetRegisterFFFFAccessMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,15 +424,15 @@ static void setSpiIntCs(uint16_t value){
|
||||
newSpiIntCs |= (rxEntrys >= 4) << 4;//RH
|
||||
newSpiIntCs |= (rxEntrys > 0) << 3;//RR
|
||||
newSpiIntCs |= (txEntrys == 8) << 2;//TF
|
||||
newSpiIntCs |= (txEntrys >= 4) << 1;//TH
|
||||
newSpiIntCs |= (txEntrys >= 4) << 1;//TH, TODO: the datasheet contradicts itself on whether its more than or equal to 4 empty or full slots
|
||||
newSpiIntCs |= txEntrys == 0;//TE
|
||||
|
||||
//if interrupt state changed update interrupts too, top 8 bits are just the enable bits for the bottom 8
|
||||
if(!!(newSpiIntCs >> 8 & newSpiIntCs) != !!(oldSpiIntCs >> 8 & oldSpiIntCs)){
|
||||
if(newSpiIntCs >> 8 & newSpiIntCs)
|
||||
setIprIsrBit(INT_SPI1);
|
||||
setIprIsrBit(DBVZ_INT_SPI1);
|
||||
else
|
||||
clearIprIsrBit(INT_SPI1);
|
||||
clearIprIsrBit(DBVZ_INT_SPI1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
@@ -358,7 +446,7 @@ static void setSpiCont1(uint16_t value){
|
||||
//debugLog("SPICONT1 write, old value:0x%04X, value:0x%04X\n", oldSpiCont1, value);
|
||||
|
||||
//SPI1 disabled
|
||||
if(oldSpiCont1 & 0x0200 && !(value & 0x2000)){
|
||||
if(oldSpiCont1 & 0x0200 && !(value & 0x0200)){
|
||||
spi1RxFifoFlush();
|
||||
spi1TxFifoFlush();
|
||||
}
|
||||
@@ -371,19 +459,22 @@ static void setSpiCont1(uint16_t value){
|
||||
if(value & oldSpiCont1 & 0x0200 && value & 0x0100){
|
||||
while(spi1TxFifoEntrys() > 0){
|
||||
uint16_t currentTxFifoEntry = spi1TxFifoRead();
|
||||
uint16_t newRxFifoEntry = 0x0000;
|
||||
uint16_t newRxFifoEntry;// = 0x0000;
|
||||
uint8_t bitCount = (value & 0x000F) + 1;
|
||||
uint16_t startBit = 1 << (bitCount - 1);
|
||||
uint8_t bits;
|
||||
//uint16_t startBit = 1 << (bitCount - 1);
|
||||
//uint8_t bits;
|
||||
|
||||
//debugLog("SPI1 transfer, PC:0x%08X\n", flx68000GetPc());
|
||||
//debugLog("SPI1 transfer, bitCount:%d, PC:0x%08X\n", bitCount, flx68000GetPc());
|
||||
|
||||
//The most significant bit is output when the CPU loads the transmitted data, 13.2.3 SPI 1 Phase and Polarity Configurations MC68VZ328UM.pdf
|
||||
/*
|
||||
for(bits = 0; bits < bitCount; bits++){
|
||||
newRxFifoEntry |= sdCardExchangeBit(!!(currentTxFifoEntry & startBit));
|
||||
newRxFifoEntry <<= 1;
|
||||
newRxFifoEntry |= sdCardExchangeBit(!!(currentTxFifoEntry & startBit));
|
||||
currentTxFifoEntry <<= 1;
|
||||
}
|
||||
*/
|
||||
newRxFifoEntry = sdCardExchangeXBitsOptimized(currentTxFifoEntry, bitCount);
|
||||
|
||||
//add received data back to RX FIFO
|
||||
spi1RxFifoWrite(newRxFifoEntry);
|
||||
@@ -398,6 +489,11 @@ static void setSpiCont1(uint16_t value){
|
||||
//update SPIINTCS interrupt bits
|
||||
setSpiIntCs(registerArrayRead16(SPIINTCS));
|
||||
|
||||
//unset XCH, transfers are instant since timing is not emulated
|
||||
value &= 0xFEFF;
|
||||
|
||||
//debugLog("Transfer complete, SPIINTCS:0x%04X\n", registerArrayRead16(SPIINTCS));
|
||||
|
||||
registerArrayWrite16(SPICONT1, value);
|
||||
}
|
||||
|
||||
@@ -408,9 +504,9 @@ static void setSpiCont2(uint16_t value){
|
||||
|
||||
//force or clear an interrupt
|
||||
if((value & 0x00C0) == 0x00C0)
|
||||
setIprIsrBit(INT_SPI2);
|
||||
setIprIsrBit(DBVZ_INT_SPI2);
|
||||
else
|
||||
clearIprIsrBit(INT_SPI2);
|
||||
clearIprIsrBit(DBVZ_INT_SPI2);
|
||||
|
||||
//do a transfer if enabled(this register write and last) and exchange set
|
||||
if(value & oldSpiCont2 & 0x0200 && value & 0x0100){
|
||||
@@ -448,7 +544,7 @@ static void setSpiCont2(uint16_t value){
|
||||
|
||||
//IRQEN set, send an interrupt after transfer
|
||||
if(value & 0x0040)
|
||||
setIprIsrBit(INT_SPI2);
|
||||
setIprIsrBit(DBVZ_INT_SPI2);
|
||||
}
|
||||
|
||||
//check for any interrupts from the transfer
|
||||
@@ -457,6 +553,165 @@ static void setSpiCont2(uint16_t value){
|
||||
registerArrayWrite16(SPICONT2, value & 0xE3FF);
|
||||
}
|
||||
|
||||
static void updateUart1PortState(void){
|
||||
if(palmIrSetPortProperties){
|
||||
uint16_t ustcnt1 = registerArrayRead16(USTCNT1);
|
||||
uint16_t ubaud1 = registerArrayRead16(UBAUD1);
|
||||
uint8_t divider = 1 << (ubaud1 >> 8 & 0x07);
|
||||
uint8_t prescaler = 65 - (ubaud1 & 0x001F);
|
||||
bool baudSrc = !!(ubaud1 & 0x0800);
|
||||
serial_port_properties_t properties;
|
||||
|
||||
properties.enable = !!(ustcnt1 & 0x8000);
|
||||
properties.enableParity = !!(ustcnt1 & 0x0800);
|
||||
properties.oddParity = !!(ustcnt1 & 0x0400);
|
||||
properties.stopBits = !!(ustcnt1 & 0x0200) ? 2 : 1;
|
||||
properties.use8BitMode = !!(ustcnt1 & 0x0100);
|
||||
properties.baudRate = (baudSrc ? EMU_SERIAL_USE_EXTERNAL_CLOCK_SOURCE : sysclksPerClk32() * M5XX_CRYSTAL_FREQUENCY) / prescaler / divider;
|
||||
|
||||
palmIrSetPortProperties(&properties);
|
||||
}
|
||||
}
|
||||
|
||||
static void updateUart1Interrupt(void){
|
||||
//the UART1 interrupt has a rather complex set of trigger methods so they all have to be checked after one changes to prevent clearing a valid interrupt thats on the same line
|
||||
uint16_t ustcnt1 = registerArrayRead16(USTCNT1);
|
||||
bool interruptState = false;
|
||||
|
||||
//is enabled
|
||||
if(ustcnt1 & 0x8000){
|
||||
//RX is enabled
|
||||
if(ustcnt1 & 0x4000){
|
||||
uint16_t urx1 = registerArrayRead16(URX1);
|
||||
uint8_t entrys = uart1RxFifoEntrys();
|
||||
|
||||
//TODO: old data timer is unemualted
|
||||
//if(ustcnt1 & 0x0080 && entrys > 0)
|
||||
// interruptState = true;
|
||||
|
||||
if(ustcnt1 & 0x0020 && entrys == 12)
|
||||
interruptState = true;
|
||||
if(ustcnt1 & 0x0010 && entrys > 6)
|
||||
interruptState = true;
|
||||
if(ustcnt1 & 0x0008 && entrys > 0)
|
||||
interruptState = true;
|
||||
}
|
||||
|
||||
//TX is enabled
|
||||
if(ustcnt1 & 0x2000){
|
||||
uint16_t utx1 = registerArrayRead16(UTX1);
|
||||
uint8_t entrys = uart1TxFifoEntrys();
|
||||
|
||||
if(ustcnt1 & 0x0004 && entrys == 0)
|
||||
interruptState = true;
|
||||
if(ustcnt1 & 0x0002 && entrys < 4)
|
||||
interruptState = true;
|
||||
if(ustcnt1 & 0x0001 && entrys < 8)
|
||||
interruptState = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(interruptState)
|
||||
setIprIsrBit(DBVZ_INT_UART1);
|
||||
else
|
||||
clearIprIsrBit(DBVZ_INT_UART1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
static void setUstcnt1(uint16_t value){
|
||||
//flush RX FIFO if disabled
|
||||
if(!((value & 0xC000) == 0xC000))
|
||||
uart1RxFifoFlush();
|
||||
|
||||
//flush TX FIFO if disabled
|
||||
if(!((value & 0xA000) == 0xA000))
|
||||
uart1TxFifoFlush();
|
||||
|
||||
registerArrayWrite16(USTCNT1, value);
|
||||
updateUart1Interrupt();
|
||||
}
|
||||
|
||||
static void updateUart2PortState(void){
|
||||
if(palmSerialSetPortProperties){
|
||||
uint16_t ustcnt2 = registerArrayRead16(USTCNT2);
|
||||
uint16_t ubaud2 = registerArrayRead16(UBAUD2);
|
||||
uint8_t divider = 1 << (ubaud2 >> 8 & 0x07);
|
||||
uint8_t prescaler = 65 - (ubaud2 & 0x001F);
|
||||
bool baudSrc = !!(ubaud2 & 0x0800);
|
||||
serial_port_properties_t properties;
|
||||
|
||||
properties.enable = !!(ustcnt2 & 0x8000);
|
||||
properties.enableParity = !!(ustcnt2 & 0x0800);
|
||||
properties.oddParity = !!(ustcnt2 & 0x0400);
|
||||
properties.stopBits = !!(ustcnt2 & 0x0200) ? 2 : 1;
|
||||
properties.use8BitMode = !!(ustcnt2 & 0x0100);
|
||||
properties.baudRate = (baudSrc ? EMU_SERIAL_USE_EXTERNAL_CLOCK_SOURCE : sysclksPerClk32() * M5XX_CRYSTAL_FREQUENCY) / prescaler / divider;
|
||||
|
||||
palmSerialSetPortProperties(&properties);
|
||||
}
|
||||
}
|
||||
|
||||
static void updateUart2Interrupt(void){
|
||||
//the UART2 interrupt has a rather complex set of trigger methods so they all have to be checked after one changes to prevent clearing a valid interrupt thats on the same line
|
||||
uint16_t ustcnt2 = registerArrayRead16(USTCNT2);
|
||||
uint16_t hmark = registerArrayRead16(HMARK);
|
||||
uint8_t hmarkRx = (hmark & 0x0F) * 4;
|
||||
uint8_t hmarkTx = (hmark >> 8) * 4;
|
||||
bool interruptState = false;
|
||||
|
||||
//is enabled
|
||||
if(ustcnt2 & 0x8000){
|
||||
//RX is enabled
|
||||
if(ustcnt2 & 0x4000){
|
||||
uint16_t urx2 = registerArrayRead16(URX2);
|
||||
uint8_t entrys = uart2RxFifoEntrys();
|
||||
|
||||
//TODO: old data timer is unemualted
|
||||
//if(ustcnt2 & 0x0080 && entrys > 0)
|
||||
// interruptState = true;
|
||||
|
||||
if(ustcnt2 & 0x0020 && entrys == 64)
|
||||
interruptState = true;
|
||||
if(ustcnt2 & 0x0010 && entrys > hmarkRx && hmarkRx != 0x00)
|
||||
interruptState = true;
|
||||
if(ustcnt2 & 0x0008 && entrys > 0)
|
||||
interruptState = true;
|
||||
}
|
||||
|
||||
//TX is enabled
|
||||
if(ustcnt2 & 0x2000){
|
||||
uint16_t utx2 = registerArrayRead16(UTX2);
|
||||
uint8_t entrys = uart2TxFifoEntrys();
|
||||
|
||||
if(ustcnt2 & 0x0004 && entrys == 0)
|
||||
interruptState = true;
|
||||
if(ustcnt2 & 0x0002 && entrys < hmarkTx && hmarkTx != 0x00)
|
||||
interruptState = true;
|
||||
if(ustcnt2 & 0x0001 && entrys < 64)
|
||||
interruptState = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(interruptState)
|
||||
setIprIsrBit(DBVZ_INT_UART2);
|
||||
else
|
||||
clearIprIsrBit(DBVZ_INT_UART2);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
static void setUstcnt2(uint16_t value){
|
||||
//flush RX FIFO if disabled
|
||||
if(!((value & 0xC000) == 0xC000))
|
||||
uart2RxFifoFlush();
|
||||
|
||||
//flush TX FIFO if disabled
|
||||
if(!((value & 0xA000) == 0xA000))
|
||||
uart2TxFifoFlush();
|
||||
|
||||
registerArrayWrite16(USTCNT2, value);
|
||||
updateUart2Interrupt();
|
||||
}
|
||||
|
||||
static void setTstat1(uint16_t value){
|
||||
uint16_t oldTstat1 = registerArrayRead16(TSTAT1);
|
||||
uint16_t newTstat1 = (value & timerStatusReadAcknowledge[0]) | (oldTstat1 & ~timerStatusReadAcknowledge[0]);
|
||||
@@ -465,7 +720,7 @@ static void setTstat1(uint16_t value){
|
||||
|
||||
if(!(newTstat1 & 0x0001) && (oldTstat1 & 0x0001)){
|
||||
//debugLog("Timer 1 interrupt cleared.\n");
|
||||
clearIprIsrBit(INT_TMR1);
|
||||
clearIprIsrBit(DBVZ_INT_TMR1);
|
||||
checkInterrupts();
|
||||
}
|
||||
timerStatusReadAcknowledge[0] &= newTstat1;//clear acknowledged reads cleared bits
|
||||
@@ -480,7 +735,7 @@ static void setTstat2(uint16_t value){
|
||||
|
||||
if(!(newTstat2 & 0x0001) && (oldTstat2 & 0x0001)){
|
||||
//debugLog("Timer 2 interrupt cleared.\n");
|
||||
clearIprIsrBit(INT_TMR2);
|
||||
clearIprIsrBit(DBVZ_INT_TMR2);
|
||||
checkInterrupts();
|
||||
}
|
||||
timerStatusReadAcknowledge[1] &= newTstat2;//clear acknowledged reads for cleared bits
|
||||
@@ -501,14 +756,14 @@ static void setPwmc1(uint16_t value){
|
||||
|
||||
//clear interrupt by write(reading can also clear the interrupt)
|
||||
if(oldPwmc1 & 0x0080 && !(value & 0x0080)){
|
||||
clearIprIsrBit(INT_PWM1);
|
||||
clearIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
//interrupt enabled and interrupt set
|
||||
if((value & 0x00C0) == 0x00C0){
|
||||
//this register also allows forcing an interrupt by writing a 1 to its IRQ bit when IRQEN is enabled
|
||||
setIprIsrBit(INT_PWM1);
|
||||
setIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
@@ -532,19 +787,19 @@ static void setIsr(uint32_t value, bool useTopWord, bool useBottomWord){
|
||||
|
||||
//IRQ1 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0800))
|
||||
value &= ~INT_IRQ1;
|
||||
value &= ~DBVZ_INT_IRQ1;
|
||||
|
||||
//IRQ2 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0400))
|
||||
value &= ~INT_IRQ2;
|
||||
value &= ~DBVZ_INT_IRQ2;
|
||||
|
||||
//IRQ3 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0200))
|
||||
value &= ~INT_IRQ3;
|
||||
value &= ~DBVZ_INT_IRQ3;
|
||||
|
||||
//IRQ6 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0100))
|
||||
value &= ~INT_IRQ6;
|
||||
value &= ~DBVZ_INT_IRQ6;
|
||||
|
||||
registerArrayWrite16(IPR, registerArrayRead16(IPR) & ~(value >> 16));
|
||||
registerArrayWrite16(ISR, registerArrayRead16(ISR) & ~(value >> 16));
|
||||
@@ -566,7 +821,7 @@ static uint8_t getPortDInputPinValues(void){
|
||||
|
||||
//portDInputValues |= 0x80;//battery dead bit, dont know the proper level to set this
|
||||
|
||||
if(palmSdCard.flashChip.data)
|
||||
if(palmSdCard.flashChipData)
|
||||
portDInputValues |= 0x20;
|
||||
|
||||
//kbd row 0
|
||||
@@ -621,10 +876,10 @@ static uint8_t getPortFValue(void){
|
||||
uint8_t portFData = registerArrayRead8(PFDATA);
|
||||
uint8_t portFDir = registerArrayRead8(PFDIR);
|
||||
uint8_t portFSel = registerArrayRead8(PFSEL);
|
||||
bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch
|
||||
bool penIrqPin = ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true;//penIrqPin pulled low on touch
|
||||
|
||||
portFValue |= penIrqPin << 1;
|
||||
portFValue |= 0x85;//bit 7 & 2-0 have pull ups, bits 6-3 have pull downs, bit 2 is occupied by PENIRQ
|
||||
portFValue |= 0x85;//bit 7 & 2<->0 have pull ups, bits 6<->3 have pull downs, bit 2 is occupied by PENIRQ
|
||||
portFValue &= ~portFDir & (portFSel | 0x02);//IRQ5 is readable even when PFSEL bit 2 is false
|
||||
portFValue |= portFData & portFDir & portFSel;
|
||||
|
||||
@@ -656,7 +911,7 @@ static uint8_t getPortKValue(void){
|
||||
uint8_t portKDir = registerArrayRead8(PKDIR);
|
||||
uint8_t portKSel = registerArrayRead8(PKSEL);
|
||||
|
||||
portKValue |= !(palmMisc.dataPort == PORT_USB_CRADLE || palmMisc.dataPort == PORT_SERIAL_CRADLE) << 2;//true if charging
|
||||
portKValue |= !palmMisc.batteryCharging << 2;//false if chargeing
|
||||
portKValue |= 0xFB;//floating pins are high
|
||||
portKValue &= ~portKDir & portKSel;
|
||||
portKValue |= portKData & portKDir & portKSel;
|
||||
@@ -665,7 +920,7 @@ static uint8_t getPortKValue(void){
|
||||
}
|
||||
|
||||
static uint8_t getPortMValue(void){
|
||||
//bit 5 has a pull up not pull down, bits 4-0 have a pull down, bit 7-6 are not active at all
|
||||
//bit 5 has a pull up not pull down, bits 4<->0 have a pull down, bit 7<->6 are not active at all
|
||||
return ((registerArrayRead8(PMDATA) & registerArrayRead8(PMDIR)) | (~registerArrayRead8(PMDIR) & 0x20)) & registerArrayRead8(PMSEL);
|
||||
}
|
||||
|
||||
@@ -701,7 +956,7 @@ static uint16_t getPwmc1(void){
|
||||
|
||||
//clear INT_PWM1 if active
|
||||
if(returnValue & 0x0080){
|
||||
clearIprIsrBit(INT_PWM1);
|
||||
clearIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
registerArrayWrite16(PWMC1, returnValue & 0xFF5F);
|
||||
}
|
||||
@@ -714,7 +969,7 @@ static uint16_t getPwmc1(void){
|
||||
|
||||
//updaters
|
||||
static void updatePowerButtonLedStatus(void){
|
||||
palmMisc.powerButtonLed = !!(getPortBValue() & 0x40) != palmMisc.batteryCharging;
|
||||
palmMisc.greenLed = !!(getPortBValue() & 0x40) != palmMisc.batteryCharging;
|
||||
}
|
||||
|
||||
static void updateVibratorStatus(void){
|
||||
@@ -725,23 +980,15 @@ static void updateAds7846ChipSelectStatus(void){
|
||||
ads7846SetChipSelect(!!(getPortGValue() & 0x04));
|
||||
}
|
||||
|
||||
static void updateBacklightAmplifierStatus(void){
|
||||
palmMisc.backlightLevel = (palmMisc.backlightLevel > 0) ? (1 + backlightAmplifierState()) : 0;
|
||||
static void updateSdCardChipSelectStatus(void){
|
||||
sdCardSetChipSelect(!!(getPortJValue() & 0x08));
|
||||
}
|
||||
|
||||
static void updateTouchState(void){
|
||||
//check if interrupt enabled and is input
|
||||
if(!(registerArrayRead8(PFSEL) & registerArrayRead8(PFDIR) & 0x02)){
|
||||
uint16_t icr = registerArrayRead16(ICR);
|
||||
bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch
|
||||
|
||||
//switch polarity
|
||||
if(icr & 0x0080)
|
||||
penIrqPin = !penIrqPin;
|
||||
|
||||
if(!penIrqPin)
|
||||
setIprIsrBit(INT_IRQ5);
|
||||
if((ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true) == !!(registerArrayRead16(ICR) & 0x0080))
|
||||
setIprIsrBit(DBVZ_INT_IRQ5);
|
||||
else
|
||||
clearIprIsrBit(INT_IRQ5);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ5);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
#ifndef DRAGONBALL_VZ_REGISTER_SPEC_H
|
||||
#define DRAGONBALL_VZ_REGISTER_SPEC_H
|
||||
|
||||
/*Dragonball VZ Register Definitions*/
|
||||
#define HW_REG_ADDR(x) (0xFFFFF000 | (x))
|
||||
|
||||
/*SIM - System Integration Module*/
|
||||
#define SCR 0x000/*System Control Register*/
|
||||
@@ -154,12 +150,16 @@
|
||||
#define LCWCH 0xA1C/*Cursor Width & Height Register*/
|
||||
#define LBLKC 0xA1F/*Blink Control Register*/
|
||||
#define LPICF 0xA20/*Panel Interface Config Register*/
|
||||
#define LPOLCF 0xA21/*LCD Polarity Configuration Register*/
|
||||
#define LACDRC 0xA23/*LACD Rate Control Register*/
|
||||
#define LPXCD 0xA25/*Pixel Clock Divider Register*/
|
||||
#define LCKCON 0xA27/*Clocking Control Register*/
|
||||
#define LRRA 0xA28/*LCD Refresh Rate Adjustment Register*/
|
||||
/*Reserved 0xA2B Octet Terminal Count Register On Original Dragonball*/
|
||||
#define LPOSR 0xA2D/*LCD Panning Offset Register*/
|
||||
#define LFRCM 0xA31/*Frame Rate Control Modulation Register*/
|
||||
#define LGPMR 0xA33/*Gray Palette Mapping Register*/
|
||||
#define PWMR 0xA36/*PWM Contrast Control Register*/
|
||||
#define DMACR 0xA39/*DMA Control Register*/
|
||||
|
||||
/*RTC - Real Time Clock*/
|
||||
@@ -176,5 +176,3 @@
|
||||
#define DRAMMC 0xC00/*DRAM Memory Configuration Register*/
|
||||
#define DRAMC 0xC02/*DRAM Control Register*/
|
||||
#define SDCTRL 0xC04/*SDRAM Control Register*/
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
//both timer functions can call eachother define them here
|
||||
static void timer1(uint8_t reason, double sysclk);
|
||||
static void timer2(uint8_t reason, double sysclk);
|
||||
static void timer1(uint8_t reason, double sysclks);
|
||||
static void timer2(uint8_t reason, double sysclks);
|
||||
|
||||
static void timer1(uint8_t reason, double sysclks){
|
||||
uint16_t timer1Control = registerArrayRead16(TCTL1);
|
||||
@@ -16,25 +16,25 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
return;
|
||||
|
||||
case 0x0001://SYSCLK / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[0] += sysclks / timer1Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0002://SYSCLK / 16 / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[0] += sysclks / 16.0 / timer1Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0003://TIN/TOUT pin / timer prescaler, the other timer can be attached to TIN/TOUT
|
||||
if(reason != TIMER_REASON_TIN)
|
||||
if(reason != DBVZ_TIMER_REASON_TIN)
|
||||
return;
|
||||
timerCycleCounter[0] += 1.0 / timer1Prescaler;
|
||||
break;
|
||||
|
||||
default://CLK32 / timer prescaler
|
||||
if(reason != TIMER_REASON_CLK32)
|
||||
if(reason != DBVZ_TIMER_REASON_CLK32)
|
||||
return;
|
||||
timerCycleCounter[0] += 1.0 / timer1Prescaler;
|
||||
break;
|
||||
@@ -47,7 +47,7 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
|
||||
//interrupt enabled
|
||||
if(timer1Control & 0x0010)
|
||||
setIprIsrBit(INT_TMR1);
|
||||
setIprIsrBit(DBVZ_INT_TMR1);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
//set timer triggered bit
|
||||
@@ -56,7 +56,7 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
|
||||
//increment other timer if enabled
|
||||
if(pcrTinToutConfig == 0x03)
|
||||
timer2(TIMER_REASON_TIN, 0);
|
||||
timer2(DBVZ_TIMER_REASON_TIN, 0);
|
||||
|
||||
//not free running, reset to 0, to prevent loss of ticks after compare event just subtract timerXCompare
|
||||
if(!(timer1Control & 0x0100))
|
||||
@@ -83,25 +83,25 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
return;
|
||||
|
||||
case 0x0001://SYSCLK / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[1] += sysclks / timer2Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0002://SYSCLK / 16 / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[1] += sysclks / 16.0 / timer2Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0003://TIN/TOUT pin / timer prescaler, the other timer can be attached to TIN/TOUT
|
||||
if(reason != TIMER_REASON_TIN)
|
||||
if(reason != DBVZ_TIMER_REASON_TIN)
|
||||
return;
|
||||
timerCycleCounter[1] += 1.0 / timer2Prescaler;
|
||||
break;
|
||||
|
||||
default://CLK32 / timer prescaler
|
||||
if(reason != TIMER_REASON_CLK32)
|
||||
if(reason != DBVZ_TIMER_REASON_CLK32)
|
||||
return;
|
||||
timerCycleCounter[1] += 1.0 / timer2Prescaler;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
|
||||
//interrupt enabled
|
||||
if(timer2Control & 0x0010)
|
||||
setIprIsrBit(INT_TMR2);
|
||||
setIprIsrBit(DBVZ_INT_TMR2);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
//set timer triggered bit
|
||||
@@ -123,7 +123,7 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
|
||||
//increment other timer if enabled
|
||||
if(pcrTinToutConfig == 0x02)
|
||||
timer1(TIMER_REASON_TIN, 0);
|
||||
timer1(DBVZ_TIMER_REASON_TIN, 0);
|
||||
|
||||
//not free running, reset to 0, to prevent loss of ticks after compare event just subtract timerXCompare
|
||||
if(!(timer2Control & 0x0100))
|
||||
@@ -169,35 +169,35 @@ static void rtiInterruptClk32(void){
|
||||
//this function is part of endClk32();
|
||||
uint16_t triggeredRtiInterrupts = 0x0000;
|
||||
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 512) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 512) == 0){
|
||||
//RIS7 - 512HZ
|
||||
triggeredRtiInterrupts |= 0x8000;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 256) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 256) == 0){
|
||||
//RIS6 - 256HZ
|
||||
triggeredRtiInterrupts |= 0x4000;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 128) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 128) == 0){
|
||||
//RIS5 - 128HZ
|
||||
triggeredRtiInterrupts |= 0x2000;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 64) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 64) == 0){
|
||||
//RIS4 - 64HZ
|
||||
triggeredRtiInterrupts |= 0x1000;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 32) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 32) == 0){
|
||||
//RIS3 - 32HZ
|
||||
triggeredRtiInterrupts |= 0x0800;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 16) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 16) == 0){
|
||||
//RIS2 - 16HZ
|
||||
triggeredRtiInterrupts |= 0x0400;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 8) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 8) == 0){
|
||||
//RIS1 - 8HZ
|
||||
triggeredRtiInterrupts |= 0x0200;
|
||||
}
|
||||
if(clk32Counter % (CRYSTAL_FREQUENCY / 4) == 0){
|
||||
if(clk32Counter % (M5XX_CRYSTAL_FREQUENCY / 4) == 0){
|
||||
//RIS0 - 4HZ
|
||||
triggeredRtiInterrupts |= 0x0100;
|
||||
}
|
||||
@@ -205,7 +205,7 @@ static void rtiInterruptClk32(void){
|
||||
triggeredRtiInterrupts &= registerArrayRead16(RTCIENR);
|
||||
if(triggeredRtiInterrupts){
|
||||
registerArrayWrite16(RTCISR, registerArrayRead16(RTCISR) | triggeredRtiInterrupts);
|
||||
setIprIsrBit(INT_RTI);
|
||||
setIprIsrBit(DBVZ_INT_RTI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ static void watchdogSecondTickClk32(void){
|
||||
if(watchdogState & 0x0002){
|
||||
//interrupt
|
||||
watchdogState |= 0x0080;
|
||||
setIprIsrBit(INT_WDT);
|
||||
setIprIsrBit(DBVZ_INT_WDT);
|
||||
}
|
||||
else{
|
||||
//reset
|
||||
@@ -249,16 +249,36 @@ static void rtcAddSecondClk32(void){
|
||||
uint8_t minutes = oldRtcTime >> 16 & 0x0000003F;
|
||||
uint8_t seconds = oldRtcTime & 0x0000003F;
|
||||
|
||||
seconds++;
|
||||
rtcInterruptEvents |= 0x0010;
|
||||
if(seconds >= 60){
|
||||
if(palmSyncRtc && palmGetRtcFromHost){
|
||||
//get new RTC value from system
|
||||
uint16_t stopwatch = registerArrayRead16(STPWCH);
|
||||
uint8_t alarmHours = rtcAlrm >> 24;
|
||||
uint8_t alarmMinutes = rtcAlrm >> 16 & 0x0000003F;
|
||||
uint8_t alarmSeconds = rtcAlrm & 0x0000003F;
|
||||
uint8_t time[3];
|
||||
|
||||
palmGetRtcFromHost(time);
|
||||
|
||||
//day rollover happened
|
||||
if(hours > time[0]){
|
||||
days++;
|
||||
rtcInterruptEvents |= 0x0008;
|
||||
}
|
||||
|
||||
if(time[0] != hours)
|
||||
rtcInterruptEvents |= 0x0020;
|
||||
|
||||
if(time[1] != minutes)
|
||||
rtcInterruptEvents |= 0x0002;
|
||||
|
||||
if(time[2] != seconds)
|
||||
rtcInterruptEvents |= 0x0010;
|
||||
|
||||
if(stopwatch != 0x003F){
|
||||
if(stopwatch == 0x0000)
|
||||
stopwatch -= FAST_ABS(time[1] - minutes);
|
||||
|
||||
if(stopwatch <= 0x0000)
|
||||
stopwatch = 0x003F;
|
||||
else
|
||||
stopwatch--;
|
||||
registerArrayWrite16(STPWCH, stopwatch);
|
||||
}
|
||||
|
||||
@@ -266,32 +286,68 @@ static void rtcAddSecondClk32(void){
|
||||
if(stopwatch == 0x003F)
|
||||
rtcInterruptEvents |= 0x0001;
|
||||
|
||||
minutes++;
|
||||
seconds = 0;
|
||||
rtcInterruptEvents |= 0x0002;
|
||||
if(minutes >= 60){
|
||||
hours++;
|
||||
minutes = 0;
|
||||
rtcInterruptEvents |= 0x0020;
|
||||
if(hours >= 24){
|
||||
hours = 0;
|
||||
days++;
|
||||
rtcInterruptEvents |= 0x0008;
|
||||
newRtcTime = time[2];//seconds
|
||||
newRtcTime |= time[1] << 16;//minutes
|
||||
newRtcTime |= time[0] << 24;//hours
|
||||
|
||||
//check alarm range to see if it triggered in the time that has passed
|
||||
if(days == dayAlrm){
|
||||
if(hours < alarmHours || hours == alarmHours && minutes < alarmMinutes || hours == alarmHours && minutes == alarmMinutes && seconds < alarmSeconds){
|
||||
//old time is before alarm
|
||||
if(time[0] > alarmHours || time[0] == alarmHours && time[1] > alarmMinutes || time[0] == alarmHours && time[1] == alarmMinutes && time[0] >= alarmSeconds){
|
||||
//new time is after alarm
|
||||
rtcInterruptEvents |= 0x0040;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
//standard frame based time increment
|
||||
|
||||
newRtcTime = seconds;
|
||||
newRtcTime |= minutes << 16;
|
||||
newRtcTime |= hours << 24;
|
||||
seconds++;
|
||||
rtcInterruptEvents |= 0x0010;
|
||||
if(seconds >= 60){
|
||||
uint16_t stopwatch = registerArrayRead16(STPWCH);
|
||||
|
||||
if(newRtcTime == rtcAlrm && days == dayAlrm)
|
||||
rtcInterruptEvents |= 0x0040;
|
||||
if(stopwatch != 0x003F){
|
||||
if(stopwatch == 0x0000)
|
||||
stopwatch = 0x003F;
|
||||
else
|
||||
stopwatch--;
|
||||
registerArrayWrite16(STPWCH, stopwatch);
|
||||
}
|
||||
|
||||
//if stopwatch ran out above or was enabled with 0x003F in the register trigger interrupt
|
||||
if(stopwatch == 0x003F)
|
||||
rtcInterruptEvents |= 0x0001;
|
||||
|
||||
minutes++;
|
||||
seconds = 0;
|
||||
rtcInterruptEvents |= 0x0002;
|
||||
if(minutes >= 60){
|
||||
hours++;
|
||||
minutes = 0;
|
||||
rtcInterruptEvents |= 0x0020;
|
||||
if(hours >= 24){
|
||||
hours = 0;
|
||||
days++;
|
||||
rtcInterruptEvents |= 0x0008;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newRtcTime = seconds;
|
||||
newRtcTime |= minutes << 16;
|
||||
newRtcTime |= hours << 24;
|
||||
|
||||
if(newRtcTime == rtcAlrm && days == dayAlrm)
|
||||
rtcInterruptEvents |= 0x0040;
|
||||
}
|
||||
|
||||
rtcInterruptEvents &= registerArrayRead16(RTCIENR);
|
||||
if(rtcInterruptEvents){
|
||||
registerArrayWrite16(RTCISR, registerArrayRead16(RTCISR) | rtcInterruptEvents);
|
||||
setIprIsrBit(INT_RTC);
|
||||
setIprIsrBit(DBVZ_INT_RTC);
|
||||
}
|
||||
|
||||
registerArrayWrite32(RTCTIME, newRtcTime);
|
||||
@@ -301,16 +357,13 @@ static void rtcAddSecondClk32(void){
|
||||
watchdogSecondTickClk32();
|
||||
}
|
||||
|
||||
void beginClk32(void){
|
||||
palmClk32Sysclks = 0.0;
|
||||
static void dbvzBeginClk32(void){
|
||||
dbvzClk32Sysclks = 0.0;
|
||||
}
|
||||
|
||||
void endClk32(void){
|
||||
//currently using toggle on read hack
|
||||
//registerArrayWrite16(PLLFSR, registerArrayRead16(PLLFSR) ^ 0x8000);
|
||||
|
||||
static void dbvzEndClk32(void){
|
||||
//second position counter
|
||||
if(clk32Counter >= CRYSTAL_FREQUENCY - 1){
|
||||
if(clk32Counter >= M5XX_CRYSTAL_FREQUENCY - 1){
|
||||
clk32Counter = 0;
|
||||
rtcAddSecondClk32();
|
||||
}
|
||||
@@ -322,15 +375,15 @@ void endClk32(void){
|
||||
if(registerArrayRead16(RTCCTL) & 0x0080 || registerArrayRead16(WATCHDOG) & 0x01)
|
||||
rtiInterruptClk32();
|
||||
|
||||
timer1(TIMER_REASON_CLK32, 0);
|
||||
timer2(TIMER_REASON_CLK32, 0);
|
||||
timer1(DBVZ_TIMER_REASON_CLK32, 0);
|
||||
timer2(DBVZ_TIMER_REASON_CLK32, 0);
|
||||
samplePwm1(true/*forClk32*/, 0.0);
|
||||
|
||||
//PLLCR sleep wait
|
||||
if(pllSleepWait != -1){
|
||||
if(pllSleepWait == 0){
|
||||
//disable PLL and CPU
|
||||
palmSysclksPerClk32 = 0.0;
|
||||
dbvzSysclksPerClk32 = 0.0;
|
||||
debugLog("PLL disabled, CPU is off!\n");
|
||||
}
|
||||
pllSleepWait--;
|
||||
@@ -341,34 +394,38 @@ void endClk32(void){
|
||||
if(pllWakeWait == 0){
|
||||
//reenable PLL and CPU
|
||||
registerArrayWrite16(PLLCR, registerArrayRead16(PLLCR) & 0xFFF7);
|
||||
palmSysclksPerClk32 = sysclksPerClk32();
|
||||
dbvzSysclksPerClk32 = sysclksPerClk32();
|
||||
debugLog("PLL reenabled, CPU is on!\n");
|
||||
}
|
||||
pllWakeWait--;
|
||||
}
|
||||
|
||||
//UART1/2, these are polled to remain thread safe
|
||||
updateUart1Interrupt();
|
||||
updateUart2Interrupt();
|
||||
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
void addSysclks(double count){
|
||||
timer1(TIMER_REASON_SYSCLK, count);
|
||||
timer2(TIMER_REASON_SYSCLK, count);
|
||||
static void dbvzAddSysclks(double count){
|
||||
timer1(DBVZ_TIMER_REASON_SYSCLK, count);
|
||||
timer2(DBVZ_TIMER_REASON_SYSCLK, count);
|
||||
samplePwm1(false/*forClk32*/, count);
|
||||
|
||||
checkInterrupts();
|
||||
palmClk32Sysclks += count;
|
||||
dbvzClk32Sysclks += count;
|
||||
}
|
||||
|
||||
static int32_t audioGetFramePercentIncrementFromClk32s(int32_t count){
|
||||
return (double)count / ((double)CRYSTAL_FREQUENCY / EMU_FPS) * AUDIO_END_OF_FRAME;
|
||||
return (double)count / ((double)M5XX_CRYSTAL_FREQUENCY / EMU_FPS) * DBVZ_AUDIO_END_OF_FRAME;
|
||||
}
|
||||
|
||||
static int32_t audioGetFramePercentIncrementFromSysclks(double count){
|
||||
return count / (palmSysclksPerClk32 * ((double)CRYSTAL_FREQUENCY / EMU_FPS)) * AUDIO_END_OF_FRAME;
|
||||
return count / (dbvzSysclksPerClk32 * ((double)M5XX_CRYSTAL_FREQUENCY / EMU_FPS)) * DBVZ_AUDIO_END_OF_FRAME;
|
||||
}
|
||||
|
||||
static int32_t audioGetFramePercentage(void){
|
||||
//returns how much of the frame has executed
|
||||
//0% = 0, 100% = AUDIO_END_OF_FRAME
|
||||
return audioGetFramePercentIncrementFromClk32s(palmFrameClk32s) + (pllIsOn() ? audioGetFramePercentIncrementFromSysclks(palmClk32Sysclks) : 0);
|
||||
//0% = 0, 100% = DBVZ_AUDIO_END_OF_FRAME
|
||||
return audioGetFramePercentIncrementFromClk32s(dbvzFrameClk32s) + (dbvzIsPllOn() ? audioGetFramePercentIncrementFromSysclks(dbvzClk32Sysclks) : 0);
|
||||
}
|
||||
241
include/emulator.h
Normal file
241
include/emulator.h
Normal file
@@ -0,0 +1,241 @@
|
||||
#ifndef EMULATOR_H
|
||||
#define EMULATOR_H
|
||||
//this is the only header a frontend needs to include from the emulator
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "audio/blip_buf.h"
|
||||
#include "m5XXBus.h"//for size macros
|
||||
|
||||
//DEFINE INFO!!!
|
||||
//define EMU_SUPPORT_PALM_OS5 to compile in Tungsten T3 support(not reccomended for low power devices)
|
||||
//define EMU_MULTITHREADED to speed up long loops
|
||||
//define EMU_MANAGE_HOST_CPU_PIPELINE to optimize the CPU pipeline for the most common cases
|
||||
//define EMU_NO_SAFETY to remove all safety checks
|
||||
//define EMU_BIG_ENDIAN on big endian systems
|
||||
//define EMU_HAVE_FILE_LAUNCHER to enable launching files from the host system
|
||||
//to enable degguging define EMU_DEBUG, all options below do nothing unless EMU_DEBUG is defined
|
||||
//to enable memory access logging define EMU_SANDBOX_LOG_MEMORY_ACCESSES
|
||||
//to enable opcode level debugging define EMU_SANDBOX_OPCODE_LEVEL_DEBUG
|
||||
//to enable flow control logging define EMU_SANDBOX_LOG_JUMPS, EMU_SANDBOX_OPCODE_LEVEL_DEBUG must also be defined for this to work
|
||||
//to log all API calls define EMU_SANDBOX_LOG_APIS, EMU_SANDBOX_OPCODE_LEVEL_DEBUG must also be defined for this to work
|
||||
|
||||
//debug
|
||||
#if defined(EMU_DEBUG)
|
||||
#if defined(EMU_CUSTOM_DEBUG_LOG_HANDLER)
|
||||
extern uint32_t frontendDebugStringSize;
|
||||
extern char* frontendDebugString;
|
||||
void frontendHandleDebugPrint();
|
||||
#define debugLog(...) (snprintf(frontendDebugString, frontendDebugStringSize, __VA_ARGS__), frontendHandleDebugPrint())
|
||||
#else
|
||||
#define debugLog(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
#else
|
||||
//msvc2003 doesnt support variadic macros, so just use an empty variadic function instead, EMU_DEBUG is not supported at all on msvc2003
|
||||
static void debugLog(char* str, ...){};
|
||||
#endif
|
||||
|
||||
//config options
|
||||
#define EMU_FPS 60
|
||||
#define DBVZ_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy
|
||||
|
||||
#define AUDIO_SAMPLE_RATE 48000
|
||||
#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLE_RATE / EMU_FPS)
|
||||
|
||||
#define AUDIO_SPEAKER_RANGE 0x6000//prevent hitting the top or bottom of the speaker when switching direction rapidly
|
||||
#define SD_CARD_NCR_BYTES 1//how many 0xFF bytes come before the R1 response
|
||||
#define SAVE_STATE_VERSION 0x00000001
|
||||
|
||||
//shared constants
|
||||
#define SD_CARD_BLOCK_SIZE 512//all newer SDSC cards have this fixed at 512
|
||||
#define SD_CARD_BLOCK_DATA_PACKET_SIZE (1 + SD_CARD_BLOCK_SIZE + 2)
|
||||
#define SD_CARD_RESPONSE_FIFO_SIZE (SD_CARD_BLOCK_DATA_PACKET_SIZE * 3)
|
||||
|
||||
//system constants
|
||||
#define DBVZ_CPU_PERCENT_WAITING 0.30//account for wait states when reading memory, tested with SysInfo.prc
|
||||
#define DBVZ_AUDIO_MAX_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME
|
||||
#define DBVZ_AUDIO_END_OF_FRAME (DBVZ_AUDIO_MAX_CLOCK_RATE / EMU_FPS)
|
||||
#define M5XX_CRYSTAL_FREQUENCY 32768
|
||||
#define SAVE_STATE_FOR_M500 0x40000000
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
#define TUNGSTEN_T3_CPU_PERCENT_WAITING 0.30//TODO: dont know ARM CPU speeds yet
|
||||
#define TUNGSTEN_T3_CPU_CRYSTAL_FREQUENCY 3686400
|
||||
#define TUNGSTEN_T3_CPU_PLL_FREQUENCY 368640000//TODO: dont know ARM CPU speeds yet
|
||||
#define TUNGSTEN_T3_RTC_CRYSTAL_FREQUENCY 32768
|
||||
#define SAVE_STATE_FOR_TUNGSTEN_T3 0x80000000
|
||||
#endif
|
||||
|
||||
//emu errors
|
||||
enum{
|
||||
EMU_ERROR_NONE = 0,
|
||||
EMU_ERROR_UNKNOWN,
|
||||
EMU_ERROR_NOT_IMPLEMENTED,
|
||||
EMU_ERROR_CALLBACKS_NOT_SET,
|
||||
EMU_ERROR_OUT_OF_MEMORY,
|
||||
EMU_ERROR_INVALID_PARAMETER,
|
||||
EMU_ERROR_RESOURCE_LOCKED
|
||||
};
|
||||
|
||||
//port types
|
||||
enum{
|
||||
EMU_PORT_NONE = 0,
|
||||
EMU_PORT_USB_CRADLE,
|
||||
EMU_PORT_SERIAL_CRADLE,
|
||||
EMU_PORT_USB_PERIPHERAL,
|
||||
EMU_PORT_SERIAL_PERIPHERAL,
|
||||
EMU_PORT_END
|
||||
};
|
||||
|
||||
//serial codes, behaviors of a serial connection other then the raw bytes, the data bytes are stored as uint16_t's with the top 8 bits being the special codes
|
||||
#define EMU_SERIAL_USE_EXTERNAL_CLOCK_SOURCE 0//check baud rate against this when a serial port is reconfigured, if its equal use the clock from the other device
|
||||
#define EMU_SERIAL_PARITY_ERROR 0x100
|
||||
#define EMU_SERIAL_FRAME_ERROR 0x200
|
||||
#define EMU_SERIAL_BREAK (EMU_SERIAL_PARITY_ERROR | 0x00)
|
||||
|
||||
//emulated devices
|
||||
enum{
|
||||
EMU_DEVICE_PALM_M500 = 0,
|
||||
EMU_DEVICE_PALM_M515
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
,EMU_DEVICE_TUNGSTEN_T3
|
||||
#endif
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool enable;
|
||||
bool enableParity;
|
||||
bool oddParity;
|
||||
uint8_t stopBits;
|
||||
bool use8BitMode;
|
||||
uint32_t baudRate;
|
||||
}serial_port_properties_t;
|
||||
|
||||
typedef struct{
|
||||
bool buttonUp;
|
||||
bool buttonDown;
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
bool buttonLeft;
|
||||
bool buttonRight;
|
||||
bool buttonCenter;
|
||||
#endif
|
||||
|
||||
bool buttonCalendar;//hw button 1
|
||||
bool buttonAddress;//hw button 2
|
||||
bool buttonTodo;//hw button 3
|
||||
bool buttonNotes;//hw button 4
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
bool buttonVoiceMemo;
|
||||
#endif
|
||||
|
||||
bool buttonPower;
|
||||
|
||||
float touchscreenX;//0.0 = left, 1.0 = right
|
||||
float touchscreenY;//0.0 = top, 1.0 = bottom
|
||||
bool touchscreenTouched;
|
||||
}input_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t csd[16];
|
||||
uint8_t cid[16];
|
||||
uint8_t scr[8];
|
||||
uint32_t ocr;
|
||||
bool writeProtectSwitch;
|
||||
}sd_card_info_t;
|
||||
|
||||
typedef struct{
|
||||
uint64_t command;
|
||||
uint8_t commandBitsRemaining;
|
||||
uint8_t runningCommand;
|
||||
uint32_t runningCommandVars[3];
|
||||
uint8_t runningCommandPacket[SD_CARD_BLOCK_DATA_PACKET_SIZE];
|
||||
uint8_t responseFifo[SD_CARD_RESPONSE_FIFO_SIZE];
|
||||
uint16_t responseReadPosition;
|
||||
int8_t responseReadPositionBit;
|
||||
uint16_t responseWritePosition;
|
||||
bool commandIsAcmd;
|
||||
bool allowInvalidCrc;
|
||||
bool chipSelect;
|
||||
bool receivingCommand;
|
||||
bool inIdleState;
|
||||
sd_card_info_t sdInfo;
|
||||
uint8_t* flashChipData;
|
||||
uint32_t flashChipSize;
|
||||
}sd_card_t;
|
||||
|
||||
typedef struct{
|
||||
bool greenLed;
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
bool redLed;
|
||||
#endif
|
||||
bool lcdOn;
|
||||
uint8_t backlightLevel;
|
||||
bool vibratorOn;
|
||||
bool batteryCharging;
|
||||
uint8_t batteryLevel;
|
||||
uint8_t dataPort;
|
||||
}misc_hw_t;
|
||||
|
||||
//emulator data, some are GUI interface variables, some should be left alone
|
||||
#if defined(EMU_SUPPORT_PALM_OS5)
|
||||
extern bool palmEmulatingTungstenT3;//read allowed, but not advised
|
||||
#endif
|
||||
extern bool palmEmulatingM500;//dont touch
|
||||
extern uint8_t* palmRom;//dont touch
|
||||
extern uint8_t* palmRam;//access allowed to read save RAM without allocating a giant buffer, but endianness must be taken into account
|
||||
extern input_t palmInput;//write allowed
|
||||
extern sd_card_t palmSdCard;//access allowed to read flash chip data without allocating a giant buffer
|
||||
extern misc_hw_t palmMisc;//read/write allowed
|
||||
extern uint16_t* palmFramebuffer;//read allowed
|
||||
extern uint16_t palmFramebufferWidth;//read allowed
|
||||
extern uint16_t palmFramebufferHeight;//read allowed
|
||||
extern int16_t* palmAudio;//read allowed, 2 channel signed 16 bit audio
|
||||
extern blip_t* palmAudioResampler;//dont touch
|
||||
extern double palmCycleCounter;//dont touch
|
||||
extern double palmClockMultiplier;//dont touch
|
||||
extern bool palmSyncRtc;//dont touch
|
||||
extern bool palmAllowInvalidBehavior;//dont touch
|
||||
extern void (*palmIrSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native I/R connections
|
||||
extern uint32_t (*palmIrDataSize)(void);//returns the current number of bytes in the hosts IR receive FIFO
|
||||
extern uint16_t (*palmIrDataReceive)(void);//called by the emulator to read the hosts IR receive FIFO
|
||||
extern void (*palmIrDataSend)(uint16_t data);//called by the emulator to send IR data
|
||||
extern void (*palmIrDataFlush)(void);//called by the emulator to delete all data in the hosts IR receive FIFO
|
||||
extern void (*palmSerialSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native serial connections
|
||||
extern uint32_t (*palmSerialDataSize)(void);//returns the current number of bytes in the hosts serial receive FIFO
|
||||
extern uint16_t (*palmSerialDataReceive)(void);//called by the emulator to read the hosts serial receive FIFO
|
||||
extern void (*palmSerialDataSend)(uint16_t data);//called by the emulator to send serial data
|
||||
extern void (*palmSerialDataFlush)(void);//called by the emulator to delete all data in the hosts serial receive FIFO
|
||||
extern void (*palmGetRtcFromHost)(uint8_t* writeBack);//[0] = hours, [1] = minutes, [2] = seconds
|
||||
|
||||
//functions
|
||||
uint32_t emulatorInit(uint8_t emulatedDevice, uint8_t* palmRomData, uint32_t palmRomSize, uint8_t* palmBootloaderData, uint32_t palmBootloaderSize, bool syncRtc, bool allowInvalidBehavior);
|
||||
void emulatorDeinit(void);
|
||||
void emulatorHardReset(void);
|
||||
void emulatorSoftReset(void);
|
||||
void emulatorSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
|
||||
void emulatorSetCpuSpeed(double speed);
|
||||
uint32_t emulatorGetStateSize(void);
|
||||
bool emulatorSaveState(uint8_t* data, uint32_t size);//true = success
|
||||
bool emulatorLoadState(uint8_t* data, uint32_t size);//true = success
|
||||
uint32_t emulatorGetRamSize(void);
|
||||
bool emulatorSaveRam(uint8_t* data, uint32_t size);//true = success
|
||||
bool emulatorLoadRam(uint8_t* data, uint32_t size);//true = success
|
||||
uint32_t emulatorInsertSdCard(uint8_t* data, uint32_t size, sd_card_info_t* sdInfo);//use (NULL, desired size) to create a new empty SD card, pass NULL for sdInfo to use defaults
|
||||
uint32_t emulatorGetSdCardSize(void);
|
||||
uint32_t emulatorGetSdCardData(uint8_t* data, uint32_t size);
|
||||
void emulatorEjectSdCard(void);
|
||||
void emulatorRunFrame(void);
|
||||
void emulatorSkipFrame(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
26
include/fileLauncher/launcher.h
Normal file
26
include/fileLauncher/launcher.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef LAUNCHER_H
|
||||
#define LAUNCHER_H
|
||||
//this is the only header a frontend needs to include from the launcher
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../emulator.h"
|
||||
|
||||
void launcherBootInstantly(bool hasSram);//fastforwards through the boot sequence
|
||||
uint32_t launcherInstallFile(uint8_t* data, uint32_t size);//only call after the emu has booted, launcherBootInstantly() will ensure a full boot has completed otherwise this is up to the frontend to be safe
|
||||
bool launcherIsExecutable(uint8_t* data, uint32_t size);
|
||||
uint32_t launcherGetAppId(uint8_t* data, uint32_t size);
|
||||
uint32_t launcherExecute(uint32_t appId);//must first be installed with launcherInstallFile
|
||||
|
||||
void launcherGetSdCardInfoFromInfoFile(uint8_t* data, uint32_t size, sd_card_info_t* returnValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
18
include/fixings.h
Normal file
18
include/fixings.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by xer on 2021-07-15.
|
||||
//
|
||||
|
||||
#ifndef MU_FIXINGS_H
|
||||
#define MU_FIXINGS_H
|
||||
|
||||
/* Fixes for Visual Studio. */
|
||||
#if defined(_MSC_VER)
|
||||
/* Prevent any assembly references from being used. */
|
||||
#define __asm__(what)
|
||||
|
||||
/* GCC's __builtin_popcount */
|
||||
#include <intrin.h>
|
||||
#define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
#endif // MU_FIXINGS_H
|
||||
10
src/flx68000.h → include/flx68000.h
Executable file → Normal file
10
src/flx68000.h → include/flx68000.h
Executable file → Normal file
@@ -4,20 +4,20 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void flx68000Init(void);
|
||||
void flx68000Reset(void);
|
||||
uint64_t flx68000StateSize(void);
|
||||
uint32_t flx68000StateSize(void);
|
||||
void flx68000SaveState(uint8_t* data);
|
||||
void flx68000LoadState(uint8_t* data);
|
||||
void flx68000LoadStateFinished(void);
|
||||
|
||||
void flx68000Execute(void);//runs the CPU for 1 CLK32 pulse
|
||||
void flx68000Execute(int32_t cycles);
|
||||
void flx68000SetIrq(uint8_t irqLevel);
|
||||
void flx68000RefreshAddressing(void);
|
||||
bool flx68000IsSupervisor(void);
|
||||
void flx68000BusError(uint32_t address, bool isWrite);
|
||||
|
||||
uint32_t flx68000GetRegister(uint8_t reg);//only for debugging
|
||||
uint32_t flx68000GetRegister(uint8_t reg);//only for debugging, D0<->7 come first then A0<->7
|
||||
uint32_t flx68000GetPc(void);//only for debugging
|
||||
uint32_t flx68000GetStatusRegister(void);//only for debugging
|
||||
uint64_t flx68000ReadArbitraryMemory(uint32_t address, uint8_t size);//only for debugging
|
||||
|
||||
#endif
|
||||
70
include/m5XXBus.h
Normal file
70
include/m5XXBus.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef M5XX_BUS_H
|
||||
#define M5XX_BUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//address space
|
||||
//new bank size (0x4000)
|
||||
#define DBVZ_BANK_SCOOT 14
|
||||
#define DBVZ_NUM_BANKS(areaSize) (((areaSize) >> DBVZ_BANK_SCOOT) + ((areaSize) & ((1 << DBVZ_BANK_SCOOT) - 1) ? 1 : 0))
|
||||
#define DBVZ_START_BANK(address) ((address) >> DBVZ_BANK_SCOOT)
|
||||
#define DBVZ_END_BANK(address, size) (DBVZ_START_BANK(address) + DBVZ_NUM_BANKS(size) - 1)
|
||||
#define DBVZ_BANK_IN_RANGE(bank, address, size) ((bank) >= DBVZ_START_BANK(address) && (bank) <= DBVZ_END_BANK(address, size))
|
||||
#define DBVZ_BANK_ADDRESS(bank) ((bank) << DBVZ_BANK_SCOOT)
|
||||
#define DBVZ_TOTAL_MEMORY_BANKS (1 << (32 - DBVZ_BANK_SCOOT))//0x40000 banks for *_BANK_SCOOT = 14
|
||||
|
||||
//chip addresses and sizes
|
||||
//after boot RAM is at 0x00000000,
|
||||
//ROM is at 0x10000000
|
||||
//and the SED1376 is at 0x1FF80000(+ 0x20000 for framebuffer)
|
||||
#define DBVZ_EMUCS_START_ADDRESS 0xFFFC0000
|
||||
#define DBVZ_REG_START_ADDRESS 0xFFFFF000
|
||||
#define M5XX_ROM_SIZE (4 * 0x100000)//4mb ROM
|
||||
#define M500_RAM_SIZE (8 * 0x100000)//16mb RAM
|
||||
#define M515_RAM_SIZE (16 * 0x100000)//16mb RAM
|
||||
#define DBVZ_EMUCS_SIZE 0x20000
|
||||
#define DBVZ_REG_SIZE 0x1000//is actually 0xE00 without bootloader
|
||||
#define DBVZ_BOOTLOADER_SIZE 0x200
|
||||
#define SED1376_MR_BIT 0x20000
|
||||
|
||||
//buffers
|
||||
//the read/write stuff looks messy here but makes the memory access functions alot cleaner
|
||||
#if defined(EMU_BIG_ENDIAN)
|
||||
//memory layout is the same as the Palm m515, just cast to pointer and access, 32 bit accesses are split to prevent unaligned access issues
|
||||
#define M68K_BUFFER_READ_8(segment, accessAddress, mask) (*(uint8_t*)(segment + ((accessAddress) & (mask))))
|
||||
#define M68K_BUFFER_READ_16(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask))))
|
||||
#define M68K_BUFFER_READ_32(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask))) << 16 | *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))))
|
||||
#define M68K_BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define M68K_BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define M68K_BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define M68K_BUFFER_READ_8_BIG_ENDIAN M68K_BUFFER_READ_8
|
||||
#define M68K_BUFFER_READ_16_BIG_ENDIAN M68K_BUFFER_READ_16
|
||||
#define M68K_BUFFER_READ_32_BIG_ENDIAN M68K_BUFFER_READ_32
|
||||
#define M68K_BUFFER_WRITE_8_BIG_ENDIAN M68K_BUFFER_WRITE_8
|
||||
#define M68K_BUFFER_WRITE_16_BIG_ENDIAN M68K_BUFFER_WRITE_16
|
||||
#define M68K_BUFFER_WRITE_32_BIG_ENDIAN M68K_BUFFER_WRITE_32
|
||||
#else
|
||||
//memory layout is different from the Palm m515, optimize for opcode fetches(16 bit reads)
|
||||
#define M68K_BUFFER_READ_8(segment, accessAddress, mask) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)))
|
||||
#define M68K_BUFFER_READ_16(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask))))
|
||||
#define M68K_BUFFER_READ_32(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask))) << 16 | *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))))
|
||||
#define M68K_BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)) = (value))
|
||||
#define M68K_BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define M68K_BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define M68K_BUFFER_READ_8_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)])
|
||||
#define M68K_BUFFER_READ_16_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 8 | segment[(accessAddress) + 1 & (mask)])
|
||||
#define M68K_BUFFER_READ_32_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 24 | segment[(accessAddress) + 1 & (mask)] << 16 | segment[(accessAddress) + 2 & (mask)] << 8 | segment[(accessAddress) + 3 & (mask)])
|
||||
#define M68K_BUFFER_WRITE_8_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value))
|
||||
#define M68K_BUFFER_WRITE_16_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value) >> 8, segment[(accessAddress) + 1 & (mask)] = (value) & 0xFF)
|
||||
#define M68K_BUFFER_WRITE_32_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value) >> 24, segment[(accessAddress) + 1 & (mask)] = ((value) >> 16) & 0xFF, segment[(accessAddress) + 2 & (mask)] = ((value) >> 8) & 0xFF, segment[(accessAddress) + 3 & (mask)] = (value) & 0xFF)
|
||||
#endif
|
||||
|
||||
extern uint8_t dbvzBankType[];
|
||||
|
||||
void dbvzSetRegisterXXFFAccessMode(void);
|
||||
void dbvzSetRegisterFFFFAccessMode(void);
|
||||
void m515SetSed1376Attached(bool attached);
|
||||
void dbvzResetAddressSpace(void);
|
||||
|
||||
#endif
|
||||
@@ -27,8 +27,10 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef M68K__HEADER
|
||||
#define M68K__HEADER
|
||||
#ifndef M68K_HEADER
|
||||
#define M68K_HEADER
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
@@ -78,58 +80,59 @@
|
||||
/* CPU types for use in m68k_set_cpu_type() */
|
||||
enum
|
||||
{
|
||||
M68K_CPU_TYPE_INVALID,
|
||||
M68K_CPU_TYPE_68000,
|
||||
M68K_CPU_TYPE_68010,
|
||||
M68K_CPU_TYPE_68EC020,
|
||||
M68K_CPU_TYPE_68020,
|
||||
M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_INVALID,
|
||||
M68K_CPU_TYPE_68000,
|
||||
M68K_CPU_TYPE_68010,
|
||||
M68K_CPU_TYPE_68EC020,
|
||||
M68K_CPU_TYPE_68020,
|
||||
M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_68040, /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_DBVZ
|
||||
};
|
||||
|
||||
/* Registers used by m68k_get_reg() and m68k_set_reg() */
|
||||
typedef enum
|
||||
{
|
||||
/* Real registers */
|
||||
M68K_REG_D0, /* Data registers */
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
M68K_REG_A0, /* Address registers */
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
M68K_REG_PC, /* Program Counter */
|
||||
M68K_REG_SR, /* Status Register */
|
||||
M68K_REG_SP, /* The current Stack Pointer (located in A7) */
|
||||
M68K_REG_USP, /* User Stack Pointer */
|
||||
M68K_REG_ISP, /* Interrupt Stack Pointer */
|
||||
M68K_REG_MSP, /* Master Stack Pointer */
|
||||
M68K_REG_SFC, /* Source Function Code */
|
||||
M68K_REG_DFC, /* Destination Function Code */
|
||||
M68K_REG_VBR, /* Vector Base Register */
|
||||
M68K_REG_CACR, /* Cache Control Register */
|
||||
M68K_REG_CAAR, /* Cache Address Register */
|
||||
/* Real registers */
|
||||
M68K_REG_D0, /* Data registers */
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
M68K_REG_A0, /* Address registers */
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
M68K_REG_PC, /* Program Counter */
|
||||
M68K_REG_SR, /* Status Register */
|
||||
M68K_REG_SP, /* The current Stack Pointer (located in A7) */
|
||||
M68K_REG_USP, /* User Stack Pointer */
|
||||
M68K_REG_ISP, /* Interrupt Stack Pointer */
|
||||
M68K_REG_MSP, /* Master Stack Pointer */
|
||||
M68K_REG_SFC, /* Source Function Code */
|
||||
M68K_REG_DFC, /* Destination Function Code */
|
||||
M68K_REG_VBR, /* Vector Base Register */
|
||||
M68K_REG_CACR, /* Cache Control Register */
|
||||
M68K_REG_CAAR, /* Cache Address Register */
|
||||
|
||||
/* Assumed registers */
|
||||
/* These are cheat registers which emulate the 1-longword prefetch
|
||||
* present in the 68000 and 68010.
|
||||
*/
|
||||
M68K_REG_PREF_ADDR, /* Last prefetch address */
|
||||
M68K_REG_PREF_DATA, /* Last prefetch data */
|
||||
/* Assumed registers */
|
||||
/* These are cheat registers which emulate the 1-longword prefetch
|
||||
* present in the 68000 and 68010.
|
||||
*/
|
||||
M68K_REG_PREF_ADDR, /* Last prefetch address */
|
||||
M68K_REG_PREF_DATA, /* Last prefetch data */
|
||||
|
||||
/* Convenience registers */
|
||||
M68K_REG_PPC, /* Previous value in the program counter */
|
||||
M68K_REG_IR, /* Instruction register */
|
||||
M68K_REG_CPU_TYPE /* Type of CPU being run */
|
||||
/* Convenience registers */
|
||||
M68K_REG_PPC, /* Previous value in the program counter */
|
||||
M68K_REG_IR, /* Instruction register */
|
||||
M68K_REG_CPU_TYPE /* Type of CPU being run */
|
||||
} m68k_register_t;
|
||||
|
||||
/* ======================================================================== */
|
||||
@@ -157,28 +160,28 @@ typedef enum
|
||||
*/
|
||||
|
||||
/* Read from anywhere */
|
||||
unsigned int m68k_read_memory_8(unsigned int address);
|
||||
unsigned int m68k_read_memory_16(unsigned int address);
|
||||
unsigned int m68k_read_memory_32(unsigned int address);
|
||||
uint8_t m68k_read_memory_8(uint32_t address);
|
||||
uint16_t m68k_read_memory_16(uint32_t address);
|
||||
uint32_t m68k_read_memory_32(uint32_t address);
|
||||
|
||||
/* Read data immediately following the PC */
|
||||
unsigned int m68k_read_immediate_16(unsigned int address);
|
||||
unsigned int m68k_read_immediate_32(unsigned int address);
|
||||
uint16_t m68k_read_immediate_16(uint32_t address);
|
||||
uint32_t m68k_read_immediate_32(uint32_t address);
|
||||
|
||||
/* Read data relative to the PC */
|
||||
unsigned int m68k_read_pcrelative_8(unsigned int address);
|
||||
unsigned int m68k_read_pcrelative_16(unsigned int address);
|
||||
unsigned int m68k_read_pcrelative_32(unsigned int address);
|
||||
uint8_t m68k_read_pcrelative_8(uint32_t address);
|
||||
uint16_t m68k_read_pcrelative_16(uint32_t address);
|
||||
uint32_t m68k_read_pcrelative_32(uint32_t address);
|
||||
|
||||
/* Memory access for the disassembler */
|
||||
unsigned int m68k_read_disassembler_8 (unsigned int address);
|
||||
unsigned int m68k_read_disassembler_16 (unsigned int address);
|
||||
unsigned int m68k_read_disassembler_32 (unsigned int address);
|
||||
uint8_t m68k_read_disassembler_8(uint32_t address);
|
||||
uint16_t m68k_read_disassembler_16(uint32_t address);
|
||||
uint32_t m68k_read_disassembler_32(uint32_t address);
|
||||
|
||||
/* Write to anywhere */
|
||||
void m68k_write_memory_8(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_16(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_32(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_8(uint32_t address, uint8_t value);
|
||||
void m68k_write_memory_16(uint32_t address, uint16_t value);
|
||||
void m68k_write_memory_32(uint32_t address, uint32_t value);
|
||||
|
||||
/* Special call to simulate undocumented 68k behavior when move.l with a
|
||||
* predecrement destination mode is executed.
|
||||
@@ -187,7 +190,7 @@ void m68k_write_memory_32(unsigned int address, unsigned int value);
|
||||
*
|
||||
* Enable this functionality with M68K_SIMULATE_PD_WRITES in m68kconf.h.
|
||||
*/
|
||||
void m68k_write_memory_32_pd(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_32_pd(uint32_t address, uint32_t value);
|
||||
|
||||
|
||||
|
||||
@@ -213,7 +216,7 @@ void m68k_write_memory_32_pd(unsigned int address, unsigned int value);
|
||||
* services the interrupt.
|
||||
* Default behavior: return M68K_INT_ACK_AUTOVECTOR.
|
||||
*/
|
||||
void m68k_set_int_ack_callback(int (*callback)(int int_level));
|
||||
void m68k_set_int_ack_callback(int32_t (*callback)(int32_t int_level));
|
||||
|
||||
|
||||
/* Set the callback for a breakpoint acknowledge (68010+).
|
||||
@@ -222,7 +225,7 @@ void m68k_set_int_ack_callback(int (*callback)(int int_level));
|
||||
* BKPT instruction for 68020+, or 0 for 68010.
|
||||
* Default behavior: do nothing.
|
||||
*/
|
||||
void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data));
|
||||
void m68k_set_bkpt_ack_callback(void (*callback)(uint32_t data));
|
||||
|
||||
|
||||
/* Set the callback for the RESET instruction.
|
||||
@@ -239,7 +242,7 @@ void m68k_set_reset_instr_callback(void (*callback)(void));
|
||||
* by a large value (currently set for changes by longwords).
|
||||
* Default behavior: do nothing.
|
||||
*/
|
||||
void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc));
|
||||
void m68k_set_pc_changed_callback(void (*callback)(uint32_t new_pc));
|
||||
|
||||
|
||||
/* Set the callback for CPU function code changes.
|
||||
@@ -249,7 +252,7 @@ void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc));
|
||||
* access it is (supervisor/user, program/data and such).
|
||||
* Default behavior: do nothing.
|
||||
*/
|
||||
void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));
|
||||
void m68k_set_fc_callback(void (*callback)(uint32_t new_fc));
|
||||
|
||||
|
||||
/* Set a callback for the instruction cycle of the CPU.
|
||||
@@ -270,7 +273,7 @@ void m68k_set_instr_hook_callback(void (*callback)(void));
|
||||
* Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68010,
|
||||
* M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020.
|
||||
*/
|
||||
void m68k_set_cpu_type(unsigned int cpu_type);
|
||||
void m68k_set_cpu_type(uint32_t cpu_type);
|
||||
|
||||
/* Do whatever initialisations the core requires. Should be called
|
||||
* at least once at init time.
|
||||
@@ -286,23 +289,23 @@ void m68k_init(void);
|
||||
void m68k_pulse_reset(void);
|
||||
|
||||
/* execute num_cycles worth of instructions. returns number of cycles used */
|
||||
int m68k_execute(int num_cycles);
|
||||
int32_t m68k_execute(int32_t num_cycles);
|
||||
|
||||
/* These functions let you read/write/modify the number of cycles left to run
|
||||
* while m68k_execute() is running.
|
||||
* These are useful if the 68k accesses a memory-mapped port on another device
|
||||
* that requires immediate processing by another CPU.
|
||||
*/
|
||||
int m68k_cycles_run(void); /* Number of cycles run so far */
|
||||
int m68k_cycles_remaining(void); /* Number of cycles left */
|
||||
void m68k_modify_timeslice(int cycles); /* Modify cycles left */
|
||||
int32_t m68k_cycles_run(void); /* Number of cycles run so far */
|
||||
int32_t m68k_cycles_remaining(void); /* Number of cycles left */
|
||||
void m68k_modify_timeslice(int32_t cycles); /* Modify cycles left */
|
||||
void m68k_end_timeslice(void); /* End timeslice now */
|
||||
|
||||
/* Set the IPL0-IPL2 pins on the CPU (IRQ).
|
||||
* A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).
|
||||
* Setting IRQ to 0 will clear an interrupt request.
|
||||
*/
|
||||
void m68k_set_irq(unsigned int int_level);
|
||||
void m68k_set_irq(uint32_t int_level);
|
||||
|
||||
|
||||
/* Halt the CPU as if you pulsed the HALT pin. */
|
||||
@@ -312,10 +315,10 @@ void m68k_pulse_halt(void);
|
||||
/* Context switching to allow multiple CPUs */
|
||||
|
||||
/* Get the size of the cpu context in bytes */
|
||||
unsigned int m68k_context_size(void);
|
||||
uint32_t m68k_context_size(void);
|
||||
|
||||
/* Get a cpu context */
|
||||
unsigned int m68k_get_context(void* dst);
|
||||
uint32_t m68k_get_context(void* dst);
|
||||
|
||||
/* set the current cpu context */
|
||||
void m68k_set_context(void* dst);
|
||||
@@ -328,31 +331,22 @@ void m68k_state_register(const char *type);
|
||||
* retrieved using m68k_get_context() or the currently running context.
|
||||
* If context is NULL, the currently running CPU context will be used.
|
||||
*/
|
||||
unsigned int m68k_get_reg(void* context, m68k_register_t reg);
|
||||
uint32_t m68k_get_reg(void* context, m68k_register_t reg);
|
||||
|
||||
/* Poke values into the internals of the currently running CPU context */
|
||||
void m68k_set_reg(m68k_register_t reg, unsigned int value);
|
||||
void m68k_set_reg(m68k_register_t reg, uint32_t value);
|
||||
|
||||
/* Check if an instruction is valid for the specified CPU type */
|
||||
unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type);
|
||||
uint32_t m68k_is_valid_instruction(uint32_t instruction, uint32_t cpu_type);
|
||||
|
||||
/* Disassemble 1 instruction using the epecified CPU type at pc. Stores
|
||||
/* Disassemble 1 instruction using the specified CPU type at pc. Stores
|
||||
* disassembly in str_buff and returns the size of the instruction in bytes.
|
||||
*/
|
||||
unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== MAME STUFF ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#if M68K_COMPILE_FOR_MAME == OPT_ON
|
||||
#include "m68kmame.h"
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
uint32_t m68k_disassemble(char* str_buff, uint32_t pc, uint32_t cpu_type);
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#endif /* M68K__HEADER */
|
||||
#endif /* M68K_HEADER */
|
||||
@@ -29,9 +29,14 @@
|
||||
|
||||
|
||||
|
||||
#ifndef M68KCONF__HEADER
|
||||
#define M68KCONF__HEADER
|
||||
#ifndef M68KCONF_HEADER
|
||||
#define M68KCONF_HEADER
|
||||
|
||||
/* Function declarations.
|
||||
* Declare any callback functions used by musashi that arnt called through
|
||||
* pointers.
|
||||
*/
|
||||
#include "m68kexternal.h"
|
||||
|
||||
/* Configuration switches.
|
||||
* Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks.
|
||||
@@ -44,21 +49,6 @@
|
||||
#define OPT_SPECIFY_HANDLER 2
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== MAME STUFF ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* If you're compiling this for MAME, only change M68K_COMPILE_FOR_MAME
|
||||
* to OPT_ON and use m68kmame.h to configure the 68k core.
|
||||
*/
|
||||
#ifndef M68K_COMPILE_FOR_MAME
|
||||
#define M68K_COMPILE_FOR_MAME OPT_OFF
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
|
||||
|
||||
#if M68K_COMPILE_FOR_MAME == OPT_OFF
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= CONFIGURATION ============================ */
|
||||
/* ======================================================================== */
|
||||
@@ -73,22 +63,26 @@
|
||||
* and m68k_read_pcrelative_xx() for PC-relative addressing.
|
||||
* If off, all read requests from the CPU will be redirected to m68k_read_xx()
|
||||
*/
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
#define M68K_SEPARATE_READS OPT_OFF
|
||||
#else
|
||||
#define M68K_SEPARATE_READS OPT_ON
|
||||
#endif
|
||||
|
||||
/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a
|
||||
* predecrement destination EA mode instead of m68k_write_32().
|
||||
* To simulate real 68k behavior, m68k_write_32_pd() must first write the high
|
||||
* word to [address+2], and then write the low word to [address].
|
||||
*/
|
||||
#define M68K_SIMULATE_PD_WRITES OPT_OFF
|
||||
#define M68K_SIMULATE_PD_WRITES OPT_ON
|
||||
|
||||
/* If ON, CPU will call the interrupt acknowledge callback when it services an
|
||||
* interrupt.
|
||||
* If off, all interrupts will be autovectored and all interrupt requests will
|
||||
* auto-clear when the interrupt is serviced.
|
||||
*/
|
||||
#define M68K_EMULATE_INT_ACK OPT_ON
|
||||
#define M68K_INT_ACK_CALLBACK(A) your_int_ack_handler_function(A)
|
||||
#define M68K_EMULATE_INT_ACK OPT_SPECIFY_HANDLER
|
||||
#define M68K_INT_ACK_CALLBACK(A) interruptAcknowledge(A)
|
||||
|
||||
|
||||
/* If ON, CPU will call the breakpoint acknowledge callback when it encounters
|
||||
@@ -100,14 +94,18 @@
|
||||
|
||||
/* If ON, the CPU will monitor the trace flags and take trace exceptions
|
||||
*/
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
#define M68K_EMULATE_TRACE OPT_ON
|
||||
#else
|
||||
#define M68K_EMULATE_TRACE OPT_OFF
|
||||
#endif
|
||||
|
||||
|
||||
/* If ON, CPU will call the output reset callback when it encounters a reset
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_EMULATE_RESET OPT_ON
|
||||
#define M68K_RESET_CALLBACK() your_reset_handler_function()
|
||||
#define M68K_EMULATE_RESET OPT_SPECIFY_HANDLER
|
||||
#define M68K_RESET_CALLBACK() emulatorSoftReset()
|
||||
|
||||
|
||||
/* If ON, CPU will call the set fc callback on every memory access to
|
||||
@@ -124,18 +122,24 @@
|
||||
* large value. This allows host programs to be nicer when it comes to
|
||||
* fetching immediate data and instructions on a banked memory system.
|
||||
*/
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
#define M68K_MONITOR_PC OPT_OFF
|
||||
#define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A)
|
||||
#else
|
||||
#define M68K_MONITOR_PC OPT_SPECIFY_HANDLER
|
||||
#endif
|
||||
#define M68K_SET_PC_CALLBACK(A) flx68000PcLongJump(A)
|
||||
|
||||
|
||||
/* If ON, CPU will call the instruction hook callback before every
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_INSTRUCTION_HOOK OPT_OFF
|
||||
#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function()
|
||||
#define M68K_INSTRUCTION_CALLBACK() on_opcode_run()
|
||||
|
||||
|
||||
/* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */
|
||||
/* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000.
|
||||
* This needs to stay off to keep save state compatibility between debug and release mode.
|
||||
*/
|
||||
#define M68K_EMULATE_PREFETCH OPT_OFF
|
||||
|
||||
|
||||
@@ -170,22 +174,13 @@
|
||||
* operations.
|
||||
*/
|
||||
#define M68K_USE_64_BIT OPT_OFF
|
||||
|
||||
|
||||
/* Set to your compiler's static inline keyword to enable it, or
|
||||
* set it to blank to disable it.
|
||||
* If you define MUSASHI_INLINE in the makefile, it will override this value.
|
||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||
/* It seems MASK_OUT_ABOVE_32 is has to be called on every 32 bit operation when using this option,
|
||||
* possibly even making the speed worse than with just 32 bits.
|
||||
*/
|
||||
#ifndef MUSASHI_INLINE
|
||||
#define MUSASHI_INLINE static inline
|
||||
#endif /* MUSASHI_INLINE */
|
||||
|
||||
#endif /* M68K_COMPILE_FOR_MAME */
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#endif /* M68KCONF__HEADER */
|
||||
#endif /* M68KCONF_HEADER */
|
||||
1951
include/m68k/m68kcpu.h
Normal file
1951
include/m68k/m68kcpu.h
Normal file
File diff suppressed because it is too large
Load Diff
10
include/m68k/m68kexternal.h
Normal file
10
include/m68k/m68kexternal.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef M68KEXTERNAL_HEADER
|
||||
#define M68KEXTERNAL_HEADER
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t interruptAcknowledge(int32_t intLevel);
|
||||
void emulatorSoftReset(void);
|
||||
void flx68000PcLongJump(uint32_t newPc);
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#ifndef M68KOPS__HEADER
|
||||
#define M68KOPS__HEADER
|
||||
#ifndef M68KOPS_HEADER
|
||||
#define M68KOPS_HEADER
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================ OPCODE HANDLERS =========================== */
|
||||
@@ -1972,13 +1974,13 @@ void m68k_op_unpk_16_mm(void);
|
||||
void m68ki_build_opcode_table(void);
|
||||
|
||||
extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
|
||||
extern unsigned char m68ki_cycles[][0x10000];
|
||||
extern uint8_t m68ki_cycles[][0x10000];
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#endif /* M68KOPS__HEADER */
|
||||
#endif /* M68KOPS_HEADER */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
void pdiUsbD12Reset(void);
|
||||
uint64_t pdiUsbD12StateSize(void);
|
||||
uint32_t pdiUsbD12StateSize(void);
|
||||
void pdiUsbD12SaveState(uint8_t* data);
|
||||
void pdiUsbD12LoadState(uint8_t* data);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#ifndef PDI_USB_D12_COMMAND_SPEC_H
|
||||
#define PDI_USB_D12_COMMAND_SPEC_H
|
||||
/*PDIUSBD12 Commands*/
|
||||
|
||||
#define SELECT_ENDPOINT_CTRL_OUT 0x00
|
||||
@@ -13,10 +11,9 @@
|
||||
|
||||
#define SET_ENDPOINT_ENABLE 0xD8
|
||||
|
||||
#define READ_WRITE_BUFFER 0xF0
|
||||
#define CLEAR_BUFFER 0xF2
|
||||
#define SET_MODE 0xF3
|
||||
#define READ_INTERRUPT_REGISTER 0xF4
|
||||
|
||||
#define SET_DMA 0xFB
|
||||
|
||||
#endif
|
||||
183
include/portability.h
Normal file
183
include/portability.h
Normal file
@@ -0,0 +1,183 @@
|
||||
#ifndef PORTABILITY_H
|
||||
#define PORTABILITY_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
|
||||
//threads
|
||||
#if defined(EMU_MULTITHREADED)
|
||||
#define PRAGMA_STRINGIFY(x) _Pragma(#x)
|
||||
#define MULTITHREAD_LOOP(x) PRAGMA_STRINGIFY(omp parallel for private(x))
|
||||
#define MULTITHREAD_DOUBLE_LOOP(x, y) PRAGMA_STRINGIFY(omp parallel for collapse(2) private(x, y))
|
||||
#else
|
||||
#define MULTITHREAD_LOOP(x)
|
||||
#define MULTITHREAD_DOUBLE_LOOP(x, y)
|
||||
#endif
|
||||
|
||||
//pipeline
|
||||
#if defined(EMU_MANAGE_HOST_CPU_PIPELINE)
|
||||
#define unlikely(x) __builtin_expect(!!(x), false)
|
||||
#define likely(x) __builtin_expect(!!(x), true)
|
||||
#define likely_equal(x, y) __builtin_expect((x), (y))
|
||||
#else
|
||||
#define unlikely(x) x
|
||||
#define likely(x) x
|
||||
#define likely_equal(x, y) x
|
||||
#endif
|
||||
|
||||
// PS2 is lacking intmax_t and uintmax_t!
|
||||
#if !defined(UINTMAX_MAX)
|
||||
typedef intmax_t signed long long int;
|
||||
typedef uintmax_t unsigned long long int;
|
||||
|
||||
#define INTMAX_MAX LONG_LONG_MAX
|
||||
#define UINTMAX_MAX ULONG_LONG_MAX
|
||||
#endif
|
||||
|
||||
//endian
|
||||
#define SWAP_16(x) ((uint16_t)((((uint16_t)(x) & 0x00FF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8)))
|
||||
#define SWAP_32(x) ((uint32_t)((((uint32_t)(x) & 0x000000FF) << 24) | (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x00FF0000) >> 8) | (((uint32_t)(x) & 0xFF000000) >> 24)))
|
||||
#define SWAP_64(x) ((((uint64_t)(x) & UINT64_C(0x00000000000000FF)) << 56) | (((uint64_t)(x) & UINT64_C(0x000000000000FF00)) << 40) | (((uint64_t)(x) & UINT64_C(0x0000000000FF0000)) << 24) | (((uint64_t)(x) & UINT64_C(0x00000000FF000000)) << 8) | (((uint64_t)(x) & UINT64_C(0x000000FF00000000)) >> 8) | (((uint64_t)(x) & UINT64_C(0x0000FF0000000000)) >> 24) | (((uint64_t)(x) & UINT64_C(0x00FF000000000000)) >> 40) | (((uint64_t)(x) & UINT64_C(0xFF00000000000000)) >> 56))
|
||||
|
||||
static inline void swap16(uint8_t* buffer, uint32_t count){
|
||||
uint32_t index;
|
||||
|
||||
//count specifys the number of uint16_t's that need to be swapped, the uint8_t* is because of alignment restrictions that crash on some platforms
|
||||
count *= sizeof(uint16_t);
|
||||
MULTITHREAD_LOOP(index) for(index = 0; index < count; index += 2){
|
||||
uint8_t temp = buffer[index];
|
||||
buffer[index] = buffer[index + 1];
|
||||
buffer[index + 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void swap16BufferIfLittle(uint8_t* buffer, uint32_t count){
|
||||
#if !defined(EMU_BIG_ENDIAN)
|
||||
swap16(buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void swap16BufferIfBig(uint8_t* buffer, uint32_t count){
|
||||
#if defined(EMU_BIG_ENDIAN)
|
||||
swap16(buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
//custom operators
|
||||
#define SIZEOF_BITS(value) (sizeof(value) * 8)
|
||||
|
||||
static inline uintmax_t fillBottomWith0s(uintmax_t value, uint8_t count){
|
||||
return value & UINTMAX_MAX << count;
|
||||
}
|
||||
|
||||
static inline uintmax_t fillTopWith0s(uintmax_t value, uint8_t count){
|
||||
return value & UINTMAX_MAX >> count;
|
||||
}
|
||||
|
||||
static inline uintmax_t fillBottomWith1s(uintmax_t value, uint8_t count){
|
||||
return value | (UINTMAX_MAX >> SIZEOF_BITS(uintmax_t) - count);
|
||||
}
|
||||
|
||||
static inline uintmax_t fillTopWith1s(uintmax_t value, uint8_t count){
|
||||
return value | (UINTMAX_MAX << SIZEOF_BITS(uintmax_t) - count);
|
||||
}
|
||||
|
||||
static inline uintmax_t leftShiftUse1s(uintmax_t value, uint8_t count){
|
||||
return fillBottomWith1s(value << count, count);
|
||||
}
|
||||
|
||||
static inline uintmax_t rightShiftUse1s(uintmax_t value, uint8_t count){
|
||||
return fillTopWith1s(value >> count, count);
|
||||
}
|
||||
|
||||
//range capping
|
||||
#define FAST_MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define FAST_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define FAST_ABS(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
//float platform safety
|
||||
static inline uint64_t getUint64FromDouble(double data){
|
||||
//1.32.31 fixed point
|
||||
uint64_t fixedPointDouble = UINT64_C(0x0000000000000000);
|
||||
|
||||
if(data < 0.0){
|
||||
data = -data;
|
||||
fixedPointDouble |= UINT64_C(0x8000000000000000);
|
||||
}
|
||||
|
||||
fixedPointDouble |= (uint64_t)data << 31;
|
||||
data -= (uint64_t)data;
|
||||
data *= (double)0x7FFFFFFF;
|
||||
fixedPointDouble |= (uint64_t)data;
|
||||
|
||||
return fixedPointDouble;
|
||||
}
|
||||
|
||||
static inline double getDoubleFromUint64(uint64_t data){
|
||||
//1.32.31 fixed point
|
||||
double floatingPointDouble;
|
||||
|
||||
floatingPointDouble = (double)(data & 0x7FFFFFFF);
|
||||
floatingPointDouble /= (double)0x7FFFFFFF;
|
||||
floatingPointDouble += (double)(data >> 31 & 0xFFFFFFFF);
|
||||
if(data & UINT64_C(0x8000000000000000))
|
||||
floatingPointDouble = -floatingPointDouble;
|
||||
|
||||
return floatingPointDouble;
|
||||
}
|
||||
|
||||
//savestate platform safety
|
||||
static inline uint64_t readStateValue64(uint8_t* where){
|
||||
return (uint64_t)where[0] << 56 | (uint64_t)where[1] << 48 | (uint64_t)where[2] << 40 | (uint64_t)where[3] << 32 | (uint64_t)where[4] << 24 | (uint64_t)where[5] << 16 | (uint64_t)where[6] << 8 | (uint64_t)where[7];
|
||||
}
|
||||
|
||||
static inline void writeStateValue64(uint8_t* where, uint64_t value){
|
||||
where[0] = value >> 56;
|
||||
where[1] = value >> 48 & 0xFF;
|
||||
where[2] = value >> 40 & 0xFF;
|
||||
where[3] = value >> 32 & 0xFF;
|
||||
where[4] = value >> 24 & 0xFF;
|
||||
where[5] = value >> 16 & 0xFF;
|
||||
where[6] = value >> 8 & 0xFF;
|
||||
where[7] = value & 0xFF;
|
||||
}
|
||||
|
||||
static inline uint32_t readStateValue32(uint8_t* where){
|
||||
return (uint32_t)where[0] << 24 | (uint32_t)where[1] << 16 | (uint32_t)where[2] << 8 | (uint32_t)where[3];
|
||||
}
|
||||
|
||||
static inline void writeStateValue32(uint8_t* where, uint32_t value){
|
||||
where[0] = value >> 24;
|
||||
where[1] = value >> 16 & 0xFF;
|
||||
where[2] = value >> 8 & 0xFF;
|
||||
where[3] = value & 0xFF;
|
||||
}
|
||||
|
||||
static inline uint16_t readStateValue16(uint8_t* where){
|
||||
return (uint16_t)where[0] << 8 | (uint16_t)where[1];
|
||||
}
|
||||
|
||||
static inline void writeStateValue16(uint8_t* where, uint16_t value){
|
||||
where[0] = value >> 8;
|
||||
where[1] = value & 0xFF;
|
||||
}
|
||||
|
||||
static inline uint8_t readStateValue8(uint8_t* where){
|
||||
return where[0];
|
||||
}
|
||||
|
||||
static inline void writeStateValue8(uint8_t* where, uint8_t value){
|
||||
where[0] = value;
|
||||
}
|
||||
|
||||
static inline double readStateValueDouble(uint8_t* where){
|
||||
return getDoubleFromUint64(readStateValue64(where));
|
||||
}
|
||||
|
||||
static inline void writeStateValueDouble(uint8_t* where, double value){
|
||||
writeStateValue64(where, getUint64FromDouble(value));
|
||||
}
|
||||
|
||||
#endif
|
||||
44
include/pxa260/pxa260.h
Normal file
44
include/pxa260/pxa260.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef PXA260_H
|
||||
#define PXA260_H
|
||||
|
||||
//this is the main module for the PXA260, with all the files it may be kind of confusing
|
||||
//this is the only file from this directory that the emu should interface with
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pxa260_IC.h"
|
||||
#include "pxa260_PwrClk.h"
|
||||
#include "pxa260_GPIO.h"
|
||||
#include "pxa260_TIMR.h"
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
#include "../armv5te/uArm/CPU_2.h"
|
||||
#endif
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
extern ArmCpu pxa260CpuState;
|
||||
#endif
|
||||
|
||||
extern uint16_t* pxa260Framebuffer;
|
||||
extern Pxa260pwrClk pxa260PwrClk;
|
||||
extern Pxa260ic pxa260Ic;
|
||||
extern Pxa260gpio pxa260Gpio;
|
||||
extern Pxa260timr pxa260Timer;
|
||||
|
||||
bool pxa260Init(uint8_t** returnRom, uint8_t** returnRam);
|
||||
void pxa260Deinit(void);
|
||||
void pxa260Reset(void);
|
||||
void pxa260SetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
|
||||
uint32_t pxa260StateSize(void);
|
||||
void pxa260SaveState(uint8_t* data);
|
||||
void pxa260LoadState(uint8_t* data);
|
||||
|
||||
void pxa260Execute(bool wantVideo);//runs the CPU for 1 frame
|
||||
|
||||
uint32_t pxa260GetRegister(uint8_t reg);//only for debugging
|
||||
#define pxa260GetPc() pxa260GetRegister(15)//only for debugging
|
||||
uint32_t pxa260GetCpsr(void);//only for debugging
|
||||
uint32_t pxa260GetSpsr(void);//only for debugging
|
||||
uint64_t pxa260ReadArbitraryMemory(uint32_t address, uint8_t size);//only for debugging, uses physical address not MMU mapped
|
||||
|
||||
#endif
|
||||
185
include/pxa260/pxa260Accessors.c.h
Normal file
185
include/pxa260/pxa260Accessors.c.h
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "../w86l488.h"
|
||||
|
||||
static uint8_t pxa260_io_read_byte(uint32_t addr){
|
||||
debugLog("Invalid 8 bit PXA260 register read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint16_t pxa260_io_read_half(uint32_t addr){
|
||||
debugLog("Invalid 16 bit PXA260 register read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
static uint32_t pxa260_io_read_word(uint32_t addr){
|
||||
uint32_t out;
|
||||
|
||||
switch(addr >> 16){
|
||||
case PXA260_CLOCK_MANAGER_BASE >> 16:
|
||||
pxa260pwrClkPrvClockMgrMemAccessF(&pxa260PwrClk, addr, 4, false, &out);
|
||||
break;
|
||||
case PXA260_POWER_MANAGER_BASE >> 16:
|
||||
pxa260pwrClkPrvPowerMgrMemAccessF(&pxa260PwrClk, addr, 4, false, &out);
|
||||
break;
|
||||
case PXA260_TIMR_BASE >> 16:
|
||||
pxa260timrPrvMemAccessF(&pxa260Timer, addr, 4, false, &out);
|
||||
break;
|
||||
case PXA260_GPIO_BASE >> 16:
|
||||
pxa260gpioPrvMemAccessF(&pxa260Gpio, addr, 4, false, &out);
|
||||
break;
|
||||
case PXA260_I2C_BASE >> 16:
|
||||
out = pxa260I2cReadWord(addr);
|
||||
break;
|
||||
case PXA260_SSP_BASE >> 16:
|
||||
out = pxa260SspReadWord(addr);
|
||||
break;
|
||||
case PXA260_UDC_BASE >> 16:
|
||||
out = pxa260UdcReadWord(addr);
|
||||
break;
|
||||
case PXA260_IC_BASE >> 16:
|
||||
pxa260icPrvMemAccessF(&pxa260Ic, addr, 4, false, &out);
|
||||
break;
|
||||
|
||||
case PXA260_DMA_BASE >> 16:
|
||||
case PXA260_RTC_BASE >> 16:
|
||||
case PXA260_FFUART_BASE >> 16:
|
||||
case PXA260_BTUART_BASE >> 16:
|
||||
case PXA260_STUART_BASE >> 16:
|
||||
//need to implement these
|
||||
debugLog("Unimplemented 32 bit PXA260 register read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
out = 0x00000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("Invalid 32 bit PXA260 register read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
out = 0x00000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void pxa260_io_write_byte(uint32_t addr, uint8_t value){
|
||||
debugLog("Invalid 8 bit PXA260 register write:0x%08X, value:0x%02X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_io_write_half(uint32_t addr, uint16_t value){
|
||||
debugLog("Invalid 16 bit PXA260 register write:0x%08X, value:0x%04X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_io_write_word(uint32_t addr, uint32_t value){
|
||||
switch(addr >> 16){
|
||||
case PXA260_CLOCK_MANAGER_BASE >> 16:
|
||||
pxa260pwrClkPrvClockMgrMemAccessF(&pxa260PwrClk, addr, 4, true, &value);
|
||||
break;
|
||||
case PXA260_POWER_MANAGER_BASE >> 16:
|
||||
pxa260pwrClkPrvPowerMgrMemAccessF(&pxa260PwrClk, addr, 4, true, &value);
|
||||
break;
|
||||
case PXA260_TIMR_BASE >> 16:
|
||||
pxa260timrPrvMemAccessF(&pxa260Timer, addr, 4, true, &value);
|
||||
break;
|
||||
case PXA260_GPIO_BASE >> 16:
|
||||
pxa260gpioPrvMemAccessF(&pxa260Gpio, addr, 4, true, &value);
|
||||
break;
|
||||
case PXA260_I2C_BASE >> 16:
|
||||
pxa260I2cWriteWord(addr, value);
|
||||
break;
|
||||
case PXA260_SSP_BASE >> 16:
|
||||
pxa260SspWriteWord(addr, value);
|
||||
break;
|
||||
case PXA260_UDC_BASE >> 16:
|
||||
pxa260UdcWriteWord(addr, value);
|
||||
break;
|
||||
case PXA260_IC_BASE >> 16:
|
||||
pxa260icPrvMemAccessF(&pxa260Ic, addr, 4, true, &value);
|
||||
break;
|
||||
|
||||
case PXA260_DMA_BASE >> 16:
|
||||
case PXA260_RTC_BASE >> 16:
|
||||
case PXA260_FFUART_BASE >> 16:
|
||||
case PXA260_BTUART_BASE >> 16:
|
||||
case PXA260_STUART_BASE >> 16:
|
||||
//need to implement these
|
||||
debugLog("Unimplemented 32 bit PXA260 register write:0x%08X, value:0x%08X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("Invalid 32 bit PXA260 register write:0x%08X, value:0x%08X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t pxa260_lcd_read_word(uint32_t addr){
|
||||
uint32_t out;
|
||||
|
||||
pxa260lcdPrvMemAccessF(&pxa260Lcd, addr, 4, false, &out);
|
||||
debugLog("32 bit PXA260 LCD register read:0x%08X\n", addr);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void pxa260_lcd_write_word(uint32_t addr, uint32_t value){
|
||||
pxa260lcdPrvMemAccessF(&pxa260Lcd, addr, 4, true, &value);
|
||||
debugLog("32 bit PXA260 LCD register write:0x%08X, value:0x%08X\n", addr, value);
|
||||
}
|
||||
|
||||
static uint8_t pxa260_pcmcia0_read_byte(uint32_t addr){
|
||||
debugLog("PCMCIA0 8 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint16_t pxa260_pcmcia0_read_half(uint32_t addr){
|
||||
debugLog("PCMCIA0 16 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
static uint32_t pxa260_pcmcia0_read_word(uint32_t addr){
|
||||
debugLog("PCMCIA0 32 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia0_write_byte(uint32_t addr, uint8_t value){
|
||||
debugLog("PCMCIA0 8 bit write:0x%08X, value:0x%02X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia0_write_half(uint32_t addr, uint16_t value){
|
||||
debugLog("PCMCIA0 16 bit write:0x%08X, value:0x%04X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia0_write_word(uint32_t addr, uint32_t value){
|
||||
debugLog("PCMCIA0 32 bit write:0x%08X, value:0x%08X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static uint8_t pxa260_pcmcia1_read_byte(uint32_t addr){
|
||||
debugLog("PCMCIA1 8 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint16_t pxa260_pcmcia1_read_half(uint32_t addr){
|
||||
debugLog("PCMCIA1 16 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
static uint32_t pxa260_pcmcia1_read_word(uint32_t addr){
|
||||
debugLog("PCMCIA1 32 bit read:0x%08X, PC:0x%08X\n", addr, pxa260GetPc());
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia1_write_byte(uint32_t addr, uint8_t value){
|
||||
debugLog("PCMCIA1 8 bit write:0x%08X, value:0x%02X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia1_write_half(uint32_t addr, uint16_t value){
|
||||
debugLog("PCMCIA1 16 bit write:0x%08X, value:0x%04X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static void pxa260_pcmcia1_write_word(uint32_t addr, uint32_t value){
|
||||
debugLog("PCMCIA1 32 bit write:0x%08X, value:0x%08X, PC:0x%08X\n", addr, value, pxa260GetPc());
|
||||
}
|
||||
|
||||
static uint16_t pxa260_static_chip_select_2_read_half(uint32_t addr){
|
||||
return w86l488Read16(addr & 0x0E);
|
||||
}
|
||||
|
||||
static void pxa260_static_chip_select_2_write_half(uint32_t addr, uint16_t value){
|
||||
w86l488Write16(addr & 0x0E, value);
|
||||
}
|
||||
|
||||
39
include/pxa260/pxa260I2c.h
Normal file
39
include/pxa260/pxa260I2c.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef PXA260_I2C_H
|
||||
#define PXA260_I2C_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PXA260_I2C_BASE 0x40300000
|
||||
#define PXA260_I2C_SIZE 0x00010000
|
||||
|
||||
enum{
|
||||
I2C_0 = 0x00,
|
||||
I2C_1,
|
||||
I2C_START,
|
||||
I2C_STOP,
|
||||
I2C_FLOATING_BUS = 0x07
|
||||
};
|
||||
|
||||
enum{
|
||||
I2C_WAIT_FOR_ADDR = 0,
|
||||
I2C_NOT_SELECTED,
|
||||
I2C_RECEIVING,
|
||||
I2C_SENDING
|
||||
};
|
||||
|
||||
extern uint8_t pxa260I2cBus;
|
||||
extern uint8_t pxa260I2cBuffer;
|
||||
extern uint16_t pxa260I2cIcr;
|
||||
extern uint16_t pxa260I2cIsr;
|
||||
extern uint8_t pxa260I2cIsar;
|
||||
|
||||
void pxa260I2cReset(void);
|
||||
|
||||
uint32_t pxa260I2cReadWord(uint32_t address);
|
||||
void pxa260I2cWriteWord(uint32_t address, uint32_t value);
|
||||
|
||||
void pxa260I2cTransmitEmpty(void);
|
||||
void pxa260I2cReceiveFull(void);
|
||||
|
||||
#endif
|
||||
16
include/pxa260/pxa260Memctrl.h
Normal file
16
include/pxa260/pxa260Memctrl.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef PXA260_MEMCTRL_H
|
||||
#define PXA260_MEMCTRL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PXA260_MEMCTRL_BASE 0x48000000
|
||||
#define PXA260_MEMCTRL_SIZE 0x00010000
|
||||
|
||||
extern uint32_t pxa260MemctrlRegisters[];
|
||||
|
||||
void pxa260MemctrlReset(void);
|
||||
|
||||
uint32_t pxa260MemctrlReadWord(uint32_t address);
|
||||
void pxa260MemctrlWriteWord(uint32_t address, uint32_t value);
|
||||
|
||||
#endif
|
||||
28
include/pxa260/pxa260Ssp.h
Normal file
28
include/pxa260/pxa260Ssp.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef PXA260_SSP_H
|
||||
#define PXA260_SSP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PXA260_SSP_BASE 0x41000000
|
||||
#define PXA260_SSP_SIZE 0x00010000
|
||||
|
||||
extern uint32_t pxa260SspSscr0;
|
||||
extern uint32_t pxa260SspSscr1;
|
||||
extern uint16_t pxa260SspRxFifo[];
|
||||
extern uint16_t pxa260SspTxFifo[];
|
||||
extern uint8_t pxa260SspRxReadPosition;
|
||||
extern uint8_t pxa260SspRxWritePosition;
|
||||
extern bool pxa260SspRxOverflowed;
|
||||
extern uint8_t pxa260SspTxReadPosition;
|
||||
extern uint8_t pxa260SspTxWritePosition;
|
||||
extern bool pxa260SspTransfering;
|
||||
|
||||
void pxa260SspReset(void);
|
||||
|
||||
uint32_t pxa260SspReadWord(uint32_t address);
|
||||
void pxa260SspWriteWord(uint32_t address, uint32_t value);
|
||||
|
||||
void pxa260SspTransferComplete(void);
|
||||
|
||||
#endif
|
||||
28
include/pxa260/pxa260Timing.h
Normal file
28
include/pxa260/pxa260Timing.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef PXA260_TIMING_H
|
||||
#define PXA260_TIMING_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum{
|
||||
PXA260_TIMING_CALLBACK_TICK_CPU_TIMER = 0,
|
||||
PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY,
|
||||
PXA260_TIMING_CALLBACK_I2C_RECEIVE_FULL,
|
||||
PXA260_TIMING_CALLBACK_SSP_TRANSFER_COMPLETE,
|
||||
PXA260_TIMING_CALLBACK_UDC_DEVICE_RESUME_COMPLETE,
|
||||
PXA260_TIMING_CALLBACK_TSC2101_SCAN,
|
||||
PXA260_TIMING_TOTAL_CALLBACKS
|
||||
};
|
||||
|
||||
extern void (*pxa260TimingCallbacks[])(void);//saving a function pointer in a state is not portable and will crash even on the same system between program loads with ASLR
|
||||
extern int32_t pxa260TimingQueuedEvents[];
|
||||
|
||||
void pxa260TimingInit(void);
|
||||
void pxa260TimingReset(void);
|
||||
|
||||
void pxa260TimingTriggerEvent(uint8_t callbackId, int32_t wait);
|
||||
void pxa260TimingCancelEvent(uint8_t callbackId);
|
||||
void pxa260TimingRun(int32_t cycles);//this runs the CPU
|
||||
|
||||
void pxa260TimingTickCpuTimer(void);
|
||||
|
||||
#endif
|
||||
19
include/pxa260/pxa260Udc.h
Normal file
19
include/pxa260/pxa260Udc.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef PXA260_UDC_H
|
||||
#define PXA260_UDC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PXA260_UDC_BASE 0x40600000
|
||||
#define PXA260_UDC_SIZE 0x00010000
|
||||
|
||||
extern uint8_t pxa260UdcUdccr;
|
||||
extern uint8_t pxa260UdcUicr0;
|
||||
|
||||
void pxa260UdcReset(void);
|
||||
|
||||
uint32_t pxa260UdcReadWord(uint32_t address);
|
||||
void pxa260UdcWriteWord(uint32_t address, uint32_t value);
|
||||
|
||||
void pxa260UdcDeviceResumeComplete(void);
|
||||
|
||||
#endif
|
||||
19
include/pxa260/pxa260_CPU.h
Normal file
19
include/pxa260/pxa260_CPU.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef PXA260_CPU_H
|
||||
#define PXA260_CPU_H
|
||||
|
||||
#include "pxa260_types.h"
|
||||
|
||||
#if defined(EMU_NO_SAFETY)
|
||||
#include "../armv5te/emu.h"
|
||||
#include "../armv5te/cpu.h"
|
||||
|
||||
#define cpuGetRegExternal(x, regNum) reg_pc(regNum)
|
||||
#define cpuSetReg(x, regNum, value) set_reg(regNum, value)
|
||||
|
||||
#define cpuIrq(x, fiq, raise) (raise ? (cpu_events |= (fiq ? EVENT_FIQ : EVENT_IRQ)) : (cpu_events &= (fiq ? ~EVENT_FIQ : ~EVENT_IRQ)))
|
||||
#else
|
||||
#include "../armv5te/uArm/CPU_2.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
38
include/pxa260/pxa260_DMA.h
Normal file
38
include/pxa260/pxa260_DMA.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef PXA260_DMA_H
|
||||
#define PXA260_DMA_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
/*
|
||||
PXA260 OS DMA controller
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_DMA_BASE 0x40000000UL
|
||||
#define PXA260_DMA_SIZE 0x00001000UL
|
||||
|
||||
typedef struct{
|
||||
|
||||
UInt32 DAR; //descriptor address register
|
||||
UInt32 SAR; //source address register
|
||||
UInt32 TAR; //target address register
|
||||
UInt32 CR; //command register
|
||||
UInt32 CSR; //control and status register
|
||||
|
||||
}Pxa260dmaChannel;
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
|
||||
UInt16 DINT;
|
||||
Pxa260dmaChannel channels[16];
|
||||
UInt8 CMR[40]; //channel map registers [ we store lower 8 bits only :-) ]
|
||||
|
||||
}Pxa260dma;
|
||||
|
||||
void pxa260dmaInit(Pxa260dma* gpio, Pxa260ic* ic);
|
||||
|
||||
#endif
|
||||
|
||||
13
include/pxa260/pxa260_DSP.h
Normal file
13
include/pxa260/pxa260_DSP.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef PXA260_DSP_H
|
||||
#define PXA260_DSP_H
|
||||
|
||||
#include "pxa260_types.h"
|
||||
|
||||
typedef struct{
|
||||
UInt64 acc0;
|
||||
}Pxa260dsp;
|
||||
|
||||
Boolean pxa260dspAccess(void* userData, Boolean MRRC, UInt8 op, UInt8 RdLo, UInt8 RdHi, UInt8 acc);
|
||||
void pxa260dspInit(Pxa260dsp* dsp);
|
||||
|
||||
#endif
|
||||
48
include/pxa260/pxa260_GPIO.h
Normal file
48
include/pxa260/pxa260_GPIO.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef PXA260_GPIO_H
|
||||
#define PXA260_GPIO_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
/*
|
||||
PXA260 OS GPIO controller
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_GPIO_BASE 0x40E00000UL
|
||||
#define PXA260_GPIO_SIZE 0x00001000UL
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
|
||||
UInt32 latches[3]; //what pxa wants to be outputting
|
||||
UInt32 inputs[3]; //what pxa is receiving [only set by the pxa260gpioSetState() API]
|
||||
UInt32 levels[3]; //what pxa sees (it differs from above for IN pins)
|
||||
UInt32 dirs[3]; //1 = output
|
||||
UInt32 riseDet[3]; //1 = rise detect
|
||||
UInt32 fallDet[3]; //1 = fall detect
|
||||
UInt32 detStatus[3]; //1 = detect happened
|
||||
UInt32 AFRs[6]; //1, 2, 3 = alt funcs
|
||||
|
||||
}Pxa260gpio;
|
||||
|
||||
#define PXA260_GPIO_LOW 0 //these values make it look like all HiZ, AFR, and nonexistent pins have pullups to those who dumbly assume gpioGEt returns a boolean
|
||||
#define PXA260_GPIO_HIGH 1
|
||||
#define PXA260_GPIO_HiZ 2
|
||||
#define PXA260_GPIO_AFR1 3
|
||||
#define PXA260_GPIO_AFR2 4
|
||||
#define PXA260_GPIO_AFR3 5
|
||||
#define PXA260_GPIO_NOT_PRESENT 6
|
||||
|
||||
Boolean pxa260gpioPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
void pxa260gpioInit(Pxa260gpio* gpio, Pxa260ic* ic);
|
||||
|
||||
//for external use :)
|
||||
UInt8 pxa260gpioGetState(Pxa260gpio* gpio, UInt8 gpioNum);
|
||||
void pxa260gpioSetState(Pxa260gpio* gpio, UInt8 gpioNum, Boolean on); //we can only set value (and only of input pins), not direction
|
||||
void pxa260gpioUpdateKeyMatrix(Pxa260gpio* gpio);
|
||||
|
||||
#endif
|
||||
|
||||
61
include/pxa260/pxa260_IC.h
Normal file
61
include/pxa260/pxa260_IC.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef PXA260_IC_H
|
||||
#define PXA260_IC_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
PXA260 interrupt controller
|
||||
|
||||
PURRPOSE: raises IRQ, FIQ as needed
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_IC_BASE 0x40D00000UL
|
||||
#define PXA260_IC_SIZE 0x00010000UL
|
||||
|
||||
|
||||
#define PXA260_I_RTC_ALM 31
|
||||
#define PXA260_I_RTC_HZ 30
|
||||
#define PXA260_I_TIMR3 29
|
||||
#define PXA260_I_TIMR2 28
|
||||
#define PXA260_I_TIMR1 27
|
||||
#define PXA260_I_TIMR0 26
|
||||
#define PXA260_I_DMA 25
|
||||
#define PXA260_I_SSP 24
|
||||
#define PXA260_I_MMC 23
|
||||
#define PXA260_I_FFUART 22
|
||||
#define PXA260_I_BTUART 21
|
||||
#define PXA260_I_STUART 20
|
||||
#define PXA260_I_ICP 19
|
||||
#define PXA260_I_I2C 18
|
||||
#define PXA260_I_LCD 17
|
||||
#define PXA260_I_NET_SSP 16
|
||||
#define PXA260_I_AC97 14
|
||||
#define PXA260_I_I2S 13
|
||||
#define PXA260_I_PMU 12
|
||||
#define PXA260_I_USB 11
|
||||
#define PXA260_I_GPIO_all 10
|
||||
#define PXA260_I_GPIO_1 9
|
||||
#define PXA260_I_GPIO_0 8
|
||||
#define PXA260_I_HWUART 7
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
UInt32 ICMR; //Mask Register
|
||||
UInt32 ICLR; //Level Register
|
||||
UInt32 ICCR; //Control Register
|
||||
UInt32 ICPR; //Pending register
|
||||
|
||||
Boolean wasIrq, wasFiq;
|
||||
|
||||
}Pxa260ic;
|
||||
|
||||
Boolean pxa260icPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
void pxa260icInit(Pxa260ic* ic);
|
||||
void pxa260icInt(Pxa260ic* ic, UInt8 intNum, Boolean raise); //interrupt caused by emulated hardware/ interrupt handled by guest
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
54
include/pxa260/pxa260_LCD.h
Normal file
54
include/pxa260/pxa260_LCD.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef PXA260_LCD_H
|
||||
#define PXA260_LCD_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
extern uint16_t* pxa260Framebuffer;
|
||||
|
||||
/*
|
||||
PXA260 OS LCD controller
|
||||
|
||||
PURRPOSE: it's nice to have a framebuffer
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_LCD_BASE 0x44000000UL
|
||||
#define PXA260_LCD_SIZE 0x00001000UL
|
||||
|
||||
|
||||
|
||||
|
||||
#define LCD_STATE_IDLE 0
|
||||
#define LCD_STATE_DMA_0_START 1
|
||||
#define LCD_STATE_DMA_0_END 2
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
|
||||
//registers
|
||||
UInt32 lccr0, lccr1, lccr2, lccr3, fbr0, fbr1, liicr, trgbr, tcr;
|
||||
UInt32 fdadr0, fsadr0, fidr0, ldcmd0;
|
||||
UInt32 fdadr1, fsadr1, fidr1, ldcmd1;
|
||||
UInt16 lcsr; //yes, 16-bit :)
|
||||
|
||||
//for our use
|
||||
UInt16 intMask;
|
||||
|
||||
UInt8 state : 6;
|
||||
UInt8 intWasPending : 1;
|
||||
UInt8 enbChanged : 1;
|
||||
|
||||
UInt8 palette[512];
|
||||
|
||||
UInt32 frameNum;
|
||||
|
||||
}Pxa260lcd;
|
||||
|
||||
Boolean pxa260lcdPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
void pxa260lcdInit(Pxa260lcd* lcd, Pxa260ic* ic);
|
||||
void pxa260lcdFrame(Pxa260lcd* lcd);
|
||||
|
||||
#endif
|
||||
|
||||
24
include/pxa260/pxa260_PwrClk.h
Normal file
24
include/pxa260/pxa260_PwrClk.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef PXA260_PWR_CLK_H
|
||||
#define PXA260_PWR_CLK_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
|
||||
typedef struct{
|
||||
UInt32 CCCR, CKEN, OSCR; //clocks manager regs
|
||||
UInt32 pwrRegs[13]; //we care so little about these, we don't even name them
|
||||
Boolean turbo;
|
||||
}Pxa260pwrClk;
|
||||
|
||||
|
||||
#define PXA260_CLOCK_MANAGER_BASE 0x41300000UL
|
||||
#define PXA260_CLOCK_MANAGER_SIZE 0x00001000UL
|
||||
|
||||
#define PXA260_POWER_MANAGER_BASE 0x40F00000UL
|
||||
#define PXA260_POWER_MANAGER_SIZE 0x00001000UL
|
||||
|
||||
Boolean pxa260pwrClkPrvCoprocRegXferFunc(void* userData, Boolean two, Boolean read, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2);
|
||||
Boolean pxa260pwrClkPrvClockMgrMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
Boolean pxa260pwrClkPrvPowerMgrMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
void pxa260pwrClkInit(Pxa260pwrClk* pc);
|
||||
|
||||
#endif
|
||||
36
include/pxa260/pxa260_RTC.h
Normal file
36
include/pxa260/pxa260_RTC.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef PXA260_RTC_H
|
||||
#define PXA260_RTC_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
|
||||
/*
|
||||
PXA260 OS RTC controller
|
||||
|
||||
PURRPOSE: it's nice to know what time it is
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_RTC_BASE 0x40900000UL
|
||||
#define PXA260_RTC_SIZE 0x00001000UL
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
|
||||
UInt32 RCNR_offset; //RTC counter offset from our local time
|
||||
UInt32 RTAR; //RTC alarm
|
||||
UInt32 RTSR; //RTC status
|
||||
UInt32 RTTR; //RTC trim - we ignore this alltogether
|
||||
UInt32 lastSeenTime; //for HZ interrupt
|
||||
|
||||
}Pxa260rtc;
|
||||
|
||||
void pxa260rtcInit(Pxa260rtc* rtc, Pxa260ic* ic);
|
||||
void pxa260rtcUpdate(Pxa260rtc* rtc);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
37
include/pxa260/pxa260_TIMR.h
Normal file
37
include/pxa260/pxa260_TIMR.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef PXA260_TIMR_H
|
||||
#define PXA260_TIMR_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
|
||||
/*
|
||||
PXA260 OS timers controller
|
||||
|
||||
PURRPOSE: timers are useful for stuff :)
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_TIMR_BASE 0x40A00000UL
|
||||
#define PXA260_TIMR_SIZE 0x00010000UL
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
|
||||
UInt32 OSMR[4]; //Match Register 0-3
|
||||
UInt32 OIER; //Interrupt Enable
|
||||
UInt32 OWER; //Watchdog enable
|
||||
UInt32 OSCR; //Counter Register
|
||||
UInt32 OSSR; //Status Register
|
||||
|
||||
}Pxa260timr;
|
||||
|
||||
Boolean pxa260timrPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf);
|
||||
void pxa260timrInit(Pxa260timr* timr, Pxa260ic* ic);
|
||||
void pxa260timrTick(Pxa260timr* timr);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
87
include/pxa260/pxa260_UART.h
Normal file
87
include/pxa260/pxa260_UART.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef PXA260_UART_H
|
||||
#define PXA260_UART_H
|
||||
|
||||
#include "pxa260_CPU.h"
|
||||
#include "pxa260_IC.h"
|
||||
|
||||
|
||||
/*
|
||||
PXA260 UARTs
|
||||
|
||||
PXA260 has three. they are identical, but at diff base addresses. this implements one. instanciate more than one of this struct to make all 3 work if needed.
|
||||
PURRPOSE: this is how linux talks to us :)
|
||||
|
||||
|
||||
by default we read nothing and write nowhere (buffer drains fast into nothingness)
|
||||
this can be changed by addidng appropriate callbacks
|
||||
|
||||
*/
|
||||
|
||||
#define PXA260_FFUART_BASE 0x40100000UL
|
||||
#define PXA260_BTUART_BASE 0x40200000UL
|
||||
#define PXA260_STUART_BASE 0x40700000UL
|
||||
#define PXA260_UART_SIZE 0x00010000UL
|
||||
|
||||
#define UART_FIFO_DEPTH 64
|
||||
|
||||
|
||||
#define UART_CHAR_BREAK 0x800
|
||||
#define UART_CHAR_FRAME_ERR 0x400
|
||||
#define UART_CHAR_PAR_ERR 0x200
|
||||
#define UART_CHAR_NONE 0x100
|
||||
|
||||
typedef UInt16 (*Pxa260UartReadF)(void* userData);
|
||||
typedef void (*Pxa260UartWriteF)(UInt16 chr, void* userData);
|
||||
|
||||
#define UART_FIFO_EMPTY 0xFF
|
||||
|
||||
typedef struct{
|
||||
|
||||
UInt8 read;
|
||||
UInt8 write;
|
||||
UInt16 buf[UART_FIFO_DEPTH];
|
||||
|
||||
}UartFifo;
|
||||
|
||||
typedef struct{
|
||||
|
||||
Pxa260ic* ic;
|
||||
UInt32 baseAddr;
|
||||
|
||||
Pxa260UartReadF readF;
|
||||
Pxa260UartWriteF writeF;
|
||||
void* accessFuncsData;
|
||||
|
||||
UartFifo TX, RX;
|
||||
|
||||
UInt16 transmitShift; //char currently "sending"
|
||||
UInt16 transmitHolding; //holding register for no-fifo mode
|
||||
|
||||
UInt16 receiveHolding; //char just received
|
||||
|
||||
UInt8 irq:5;
|
||||
UInt8 cyclesSinceRecv:3;
|
||||
|
||||
UInt8 IER; //interrupt enable register
|
||||
UInt8 IIR; //interrupt information register
|
||||
UInt8 FCR; //fifo control register
|
||||
UInt8 LCR; //line control register
|
||||
UInt8 LSR; //line status register
|
||||
UInt8 MCR; //modem control register
|
||||
UInt8 MSR; //modem status register
|
||||
UInt8 SPR; //scratchpad register
|
||||
UInt8 DLL; //divisor latch low
|
||||
UInt8 DLH; //divior latch high;
|
||||
UInt8 ISR; //infrared selection register
|
||||
|
||||
|
||||
|
||||
}Pxa260uart;
|
||||
|
||||
void pxa260uartInit(Pxa260uart* uart, Pxa260ic* ic, UInt32 baseAddr, UInt8 irq);
|
||||
void pxa260uartProcess(Pxa260uart* uart); //write out data in TX fifo and read data into RX fifo
|
||||
|
||||
void pxa260uartSetFuncs(Pxa260uart* uart, Pxa260UartReadF readF, Pxa260UartWriteF writeF, void* userData);
|
||||
|
||||
#endif
|
||||
|
||||
25
include/pxa260/pxa260_math64.h
Normal file
25
include/pxa260/pxa260_math64.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef UARM_MATH_64_H
|
||||
#define UARM_MATH_64_H
|
||||
|
||||
#include "pxa260_types.h"
|
||||
|
||||
static inline UInt64 u64_from_halves(UInt32 hi, UInt32 lo) { return (((UInt64)hi) << 32ULL) | ((UInt64)lo); }
|
||||
static inline UInt64 u64_32_to_64(UInt32 v) { return (UInt64)v; }
|
||||
static inline UInt32 u64_64_to_32(UInt64 v) { return (UInt32)v; }
|
||||
static inline UInt32 u64_get_hi(UInt64 v) { return (UInt32)(v >> 32ULL); }
|
||||
static inline UInt64 u64_add(UInt64 a, UInt64 b) { return a + b; }
|
||||
static inline UInt64 u64_add32(UInt64 a, UInt32 b) { return a + (UInt64)b; }
|
||||
static inline UInt64 u64_umul3232(UInt32 a, UInt32 b) { return ((UInt64)a) * ((UInt64)b); } //sad but true: gcc has no u32xu32->64 multiply
|
||||
static inline UInt64 u64_smul3232(Int32 a, Int32 b) { return ((Int64)a) * ((Int64)b); } //sad but true: gcc has no s32xs32->64 multiply
|
||||
static inline UInt64 u64_shr(UInt64 a, unsigned bits) { return a >> (UInt64)bits; }
|
||||
static inline UInt64 u64_shl(UInt64 a, unsigned bits) { return a << (UInt64)bits; }
|
||||
static inline UInt64 u64_xtnd32(UInt64 a) { if(a & 0x80000000UL) a |= (((UInt64)-1) << 32ULL); return a; }
|
||||
static inline Boolean u64_isZero(UInt64 a) { return a == 0; }
|
||||
static inline UInt64 u64_inc(UInt64 a) { return a + 1ULL; }
|
||||
static inline UInt64 u64_and(UInt64 a, UInt64 b) { return a & b; }
|
||||
static inline UInt64 u64_zero(void) { return 0; }
|
||||
static inline UInt64 u64_sub(UInt64 a, UInt64 b) { return a - b; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
38
include/pxa260/pxa260_types.h
Normal file
38
include/pxa260/pxa260_types.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef UARM_TYPES_H
|
||||
#define UARM_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../emulator.h"
|
||||
|
||||
typedef uint64_t UInt64;
|
||||
typedef int64_t Int64;
|
||||
typedef uint32_t UInt32;
|
||||
typedef int32_t Int32;
|
||||
typedef uint16_t UInt16;
|
||||
typedef int16_t Int16;
|
||||
typedef uint8_t UInt8;
|
||||
typedef int8_t Int8;
|
||||
typedef uint8_t Err;
|
||||
typedef uint8_t Boolean;//must use uint8_t, some functions store extra info in the other bits
|
||||
|
||||
#define _INLINE_ inline
|
||||
#define _UNUSED_
|
||||
|
||||
#define TYPE_CHECK ((sizeof(UInt32) == 4) && (sizeof(UInt16) == 2) && (sizeof(UInt8) == 1))
|
||||
|
||||
#define errNone 0x00
|
||||
#define errInternal 0x01
|
||||
|
||||
/* runtime stuffs */
|
||||
#define err_str(str) debugLog(str)
|
||||
#define err_hex(num) debugLog("0x%X", num)
|
||||
#define err_dec(num) debugLog("%d", num)
|
||||
|
||||
#define __mem_zero(mem, len) memset(mem, 0x00, len)
|
||||
#define __mem_copy(dst, src, size) memcpy(dst, src, size)
|
||||
|
||||
#endif
|
||||
@@ -2,9 +2,12 @@
|
||||
#define SD_CARD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void sdCardReset(void);
|
||||
|
||||
void sdCardSetChipSelect(bool value);
|
||||
bool sdCardExchangeBit(bool bit);
|
||||
uint32_t sdCardExchangeXBitsOptimized(uint32_t bits, uint8_t size);
|
||||
|
||||
#endif
|
||||
161
include/sdCardAccessors.c.h
Normal file
161
include/sdCardAccessors.c.h
Normal file
@@ -0,0 +1,161 @@
|
||||
//FIFO accessors
|
||||
static uint16_t sdCardResponseFifoByteEntrys(void){
|
||||
//check for wraparound
|
||||
if(palmSdCard.responseWritePosition < palmSdCard.responseReadPosition)
|
||||
return palmSdCard.responseWritePosition + SD_CARD_RESPONSE_FIFO_SIZE - palmSdCard.responseReadPosition;
|
||||
return palmSdCard.responseWritePosition - palmSdCard.responseReadPosition;
|
||||
}
|
||||
|
||||
static bool sdCardResponseFifoReadBit(void){
|
||||
if(sdCardResponseFifoByteEntrys() > 0){
|
||||
bool bit = !!(palmSdCard.responseFifo[palmSdCard.responseReadPosition] & 1 << palmSdCard.responseReadPositionBit);
|
||||
palmSdCard.responseReadPositionBit--;
|
||||
if(palmSdCard.responseReadPositionBit < 0){
|
||||
palmSdCard.responseReadPositionBit = 7;
|
||||
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t sdCardResponseFifoReadByteOptimized(void){
|
||||
switch(sdCardResponseFifoByteEntrys()){
|
||||
case 0:
|
||||
//no bytes
|
||||
return 0xFF;
|
||||
|
||||
case 1:{
|
||||
//unsafe, use slow mode
|
||||
uint8_t byte = 0x00;
|
||||
uint8_t index;
|
||||
|
||||
for(index = 0; index < 8; index++){
|
||||
byte <<= 1;
|
||||
byte |= sdCardResponseFifoReadBit();
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
default:{
|
||||
uint8_t byte;
|
||||
|
||||
if(palmSdCard.responseReadPositionBit == 7){
|
||||
//just read the whole byte at once
|
||||
byte = palmSdCard.responseFifo[palmSdCard.responseReadPosition];
|
||||
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
return byte;
|
||||
}
|
||||
else{
|
||||
//have to merge 2 bytes
|
||||
byte = palmSdCard.responseFifo[palmSdCard.responseReadPosition] << 7 - palmSdCard.responseReadPositionBit;
|
||||
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
byte |= palmSdCard.responseFifo[palmSdCard.responseReadPosition] >> palmSdCard.responseReadPositionBit + 1;
|
||||
return byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sdCardResponseFifoWriteByte(uint8_t value){
|
||||
if(likely(sdCardResponseFifoByteEntrys() < SD_CARD_RESPONSE_FIFO_SIZE - 1)){
|
||||
palmSdCard.responseFifo[palmSdCard.responseWritePosition] = value;
|
||||
palmSdCard.responseWritePosition = (palmSdCard.responseWritePosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static void sdCardResponseFifoFlush(void){
|
||||
palmSdCard.responseReadPosition = palmSdCard.responseWritePosition;
|
||||
palmSdCard.responseReadPositionBit = 7;
|
||||
}
|
||||
|
||||
//basic responses
|
||||
static void sdCardDoResponseDelay(uint16_t bytes){
|
||||
uint16_t index;
|
||||
for(index = 0; index < bytes; index++)
|
||||
sdCardResponseFifoWriteByte(0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseBusy(uint16_t bytes){
|
||||
uint16_t index;
|
||||
for(index = 0; index < bytes; index++)
|
||||
sdCardResponseFifoWriteByte(0x00);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR1(uint8_t r1){
|
||||
sdCardDoResponseDelay(SD_CARD_NCR_BYTES);
|
||||
sdCardResponseFifoWriteByte(r1);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR2(uint8_t r1, uint8_t status){
|
||||
sdCardDoResponseR1(r1);
|
||||
sdCardResponseFifoWriteByte(status);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR3R7(uint8_t r1, uint32_t value){
|
||||
sdCardDoResponseR1(r1);
|
||||
sdCardResponseFifoWriteByte(value >> 24);
|
||||
sdCardResponseFifoWriteByte(value >> 16 & 0xFF);
|
||||
sdCardResponseFifoWriteByte(value >> 8 & 0xFF);
|
||||
sdCardResponseFifoWriteByte(value & 0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseDataPacket(uint8_t token, const uint8_t* data, uint16_t size){
|
||||
uint16_t crc16;
|
||||
uint16_t offset;
|
||||
|
||||
if(likely(palmSdCard.allowInvalidCrc))
|
||||
crc16 = 0x0000;
|
||||
else
|
||||
crc16 = sdCardCrc16(data, size);
|
||||
|
||||
sdCardResponseFifoWriteByte(token);
|
||||
for(offset = 0; offset < size; offset++)
|
||||
sdCardResponseFifoWriteByte(data[offset]);
|
||||
sdCardResponseFifoWriteByte(crc16 >> 8);
|
||||
sdCardResponseFifoWriteByte(crc16 & 0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseDataResponse(uint8_t response){
|
||||
sdCardResponseFifoWriteByte(response);
|
||||
sdCardDoResponseBusy(1);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseErrorToken(uint8_t token){
|
||||
sdCardResponseFifoWriteByte(token);
|
||||
}
|
||||
|
||||
//register getters
|
||||
static void sdCardGetCsd(uint8_t* csd){
|
||||
uint16_t deviceSize;
|
||||
|
||||
memcpy(csd, palmSdCard.sdInfo.csd, 16);
|
||||
|
||||
//set device size field(in multiples of 256k right now, the multiplier size also scales based on chip size), needed to get size
|
||||
deviceSize = palmSdCard.flashChipSize / SD_CARD_BLOCK_SIZE / 512;//to calculate the card capacity excluding security area ((device size + 1) * device size multiplier * max read data block length) bytes
|
||||
csd[6] = csd[6] & 0xFC | deviceSize >> 10 & 0x03;
|
||||
csd[7] = deviceSize >> 2 & 0xFF;
|
||||
csd[8] = csd[8] & 0x3F | deviceSize << 6 & 0xC0;
|
||||
|
||||
if(unlikely(!palmSdCard.allowInvalidCrc))
|
||||
csd[15] = sdCardCrc7(csd, 15);
|
||||
|
||||
//debugLog("CSD bytes: 0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", csd[0], csd[1], csd[2], csd[3], csd[4], csd[5], csd[6], csd[7], csd[8], csd[9], csd[10], csd[11], csd[12], csd[13], csd[14], csd[15]);
|
||||
}
|
||||
|
||||
static void sdCardGetCid(uint8_t* cid){
|
||||
memcpy(cid, palmSdCard.sdInfo.cid, 16);
|
||||
|
||||
if(unlikely(!palmSdCard.allowInvalidCrc))
|
||||
cid[15] = sdCardCrc7(cid, 15);
|
||||
}
|
||||
|
||||
static void sdCardGetScr(uint8_t* scr){
|
||||
//dont know it this needs a CRC7 or not?
|
||||
memcpy(scr, palmSdCard.sdInfo.scr, 8);
|
||||
}
|
||||
|
||||
static uint32_t sdCardGetOcr(void){
|
||||
return !palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | palmSdCard.sdInfo.ocr/*supported voltages, misc stuff*/;
|
||||
}
|
||||
63
include/sdCardCommandNames.c.h
Normal file
63
include/sdCardCommandNames.c.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*SD Card Commands*/
|
||||
/*Command Format:01IIIIIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCCCC1*/
|
||||
/*48 bits, I = index, A = argument, C = CRC*/
|
||||
/*see http://elm-chan.org/docs/mmc/mmc_e.html for more command information*/
|
||||
|
||||
#define GO_IDLE_STATE 0/*software reset*/
|
||||
#define SEND_OP_COND 1/*initiate initialization process*/
|
||||
#define SEND_IF_COND 8/*only for SDC V2, checks voltage range.*/
|
||||
#define SEND_CSD 9/*read CSD register*/
|
||||
#define SEND_CID 10/*read CID register*/
|
||||
#define STOP_TRANSMISSION 12/*stop to read data*/
|
||||
#define SEND_STATUS 13/*asks the card to send its status register*/
|
||||
#define SET_BLOCKLEN 16/*change R/W block size*/
|
||||
#define READ_SINGLE_BLOCK 17/*read a block*/
|
||||
#define READ_MULTIPLE_BLOCK 18/*read multiple blocks*/
|
||||
#define SET_BLOCK_COUNT 23/*only for MMC, defines number of blocks to transfer with next multi-block read/write command*/
|
||||
#define WRITE_SINGLE_BLOCK 24/*write a block*/
|
||||
#define WRITE_MULTIPLE_BLOCK 25/*write multiple blocks*/
|
||||
#define SEND_WRITE_PROT 30/*if the card has write protection features this command asks the card to send the status of the write protection bits*/
|
||||
#define APP_CMD 55/*next command is ACMD<n> command*/
|
||||
#define READ_OCR 58/*read OCR(Operation Condtion Register)*/
|
||||
#define CRC_ON_OFF 59/*turns the CRC option on or off, a 1 in the CRC option bit will turn the option on, a 0 will turn it off*/
|
||||
|
||||
/*Application Commands*/
|
||||
#define SET_WR_BLOCK_ERASE_COUNT 23/*only for SDC, defines number of blocks to pre-erase with next multi-block write command*/
|
||||
#define APP_SEND_OP_COND 41/*only for SDC, same as SEND_OP_COND*/
|
||||
#define SEND_SCR 51/*reads the SCR(SD Configuration Register)*/
|
||||
|
||||
/*R1 Response Bits*/
|
||||
#define R1_IN_IDLE_STATE 0x01
|
||||
#define R1_ERASE_RESET 0x02
|
||||
#define R1_ILLEGAL_COMMAND 0x04
|
||||
#define R1_COMMAND_CRC_ERROR 0x08
|
||||
#define R1_ERASE_SEQUENCE_ERROR 0x10
|
||||
#define R1_ADDRESS_ERROR 0x20
|
||||
#define R1_PARAMETER_ERROR 0x40
|
||||
|
||||
/*R2 Response Bits*/
|
||||
#define R2_CARD_IS_LOCKED 0x01
|
||||
#define R2_WRITE_PROTECT_ERASE_SKIP 0x02
|
||||
#define R2_ERROR 0x04
|
||||
#define R2_CC_ERROR 0x08
|
||||
#define R2_CARD_ECC_FAILED 0x10
|
||||
#define R2_WRITE_PROTECT_VIOLATION 0x20
|
||||
#define R2_ERASE_PARAM 0x40
|
||||
#define R2_OUT_OF_RANGE 0x80/*also called R2_CSD_OVERWRITE*/
|
||||
|
||||
/*Error Token Bits*/
|
||||
#define ET_ERROR 0x01
|
||||
#define ET_CC_ERROR 0x02
|
||||
#define ET_CARD_ECC_FAILED 0x04
|
||||
#define ET_OUT_OF_RANGE 0x08
|
||||
#define ET_CARD_IS_LOCKED 0x10
|
||||
|
||||
/*Data Transfer Tokens*/
|
||||
#define DATA_TOKEN_DEFAULT 0xFE
|
||||
#define DATA_TOKEN_CMD25 0xFC
|
||||
#define STOP_TRAN 0xFD
|
||||
|
||||
/*Data Response Bits*/
|
||||
#define DR_ACCEPTED 0x05
|
||||
#define DR_CRC_ERROR 0x0B
|
||||
#define DR_WRITE_ERROR 0x0D
|
||||
53
include/sdCardCrcTables.c.h
Normal file
53
include/sdCardCrcTables.c.h
Normal file
@@ -0,0 +1,53 @@
|
||||
static const uint8_t sdCardCrc7Table[256] = {
|
||||
0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77,
|
||||
0x19, 0x10, 0x0B, 0x02, 0x3D, 0x34, 0x2F, 0x26, 0x51, 0x58, 0x43, 0x4A, 0x75, 0x7C, 0x67, 0x6E,
|
||||
0x32, 0x3B, 0x20, 0x29, 0x16, 0x1F, 0x04, 0x0D, 0x7A, 0x73, 0x68, 0x61, 0x5E, 0x57, 0x4C, 0x45,
|
||||
0x2B, 0x22, 0x39, 0x30, 0x0F, 0x06, 0x1D, 0x14, 0x63, 0x6A, 0x71, 0x78, 0x47, 0x4E, 0x55, 0x5C,
|
||||
0x64, 0x6D, 0x76, 0x7F, 0x40, 0x49, 0x52, 0x5B, 0x2C, 0x25, 0x3E, 0x37, 0x08, 0x01, 0x1A, 0x13,
|
||||
0x7D, 0x74, 0x6F, 0x66, 0x59, 0x50, 0x4B, 0x42, 0x35, 0x3C, 0x27, 0x2E, 0x11, 0x18, 0x03, 0x0A,
|
||||
0x56, 0x5F, 0x44, 0x4D, 0x72, 0x7B, 0x60, 0x69, 0x1E, 0x17, 0x0C, 0x05, 0x3A, 0x33, 0x28, 0x21,
|
||||
0x4F, 0x46, 0x5D, 0x54, 0x6B, 0x62, 0x79, 0x70, 0x07, 0x0E, 0x15, 0x1C, 0x23, 0x2A, 0x31, 0x38,
|
||||
0x41, 0x48, 0x53, 0x5A, 0x65, 0x6C, 0x77, 0x7E, 0x09, 0x00, 0x1B, 0x12, 0x2D, 0x24, 0x3F, 0x36,
|
||||
0x58, 0x51, 0x4A, 0x43, 0x7C, 0x75, 0x6E, 0x67, 0x10, 0x19, 0x02, 0x0B, 0x34, 0x3D, 0x26, 0x2F,
|
||||
0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C, 0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04,
|
||||
0x6A, 0x63, 0x78, 0x71, 0x4E, 0x47, 0x5C, 0x55, 0x22, 0x2B, 0x30, 0x39, 0x06, 0x0F, 0x14, 0x1D,
|
||||
0x25, 0x2C, 0x37, 0x3E, 0x01, 0x08, 0x13, 0x1A, 0x6D, 0x64, 0x7F, 0x76, 0x49, 0x40, 0x5B, 0x52,
|
||||
0x3C, 0x35, 0x2E, 0x27, 0x18, 0x11, 0x0A, 0x03, 0x74, 0x7D, 0x66, 0x6F, 0x50, 0x59, 0x42, 0x4B,
|
||||
0x17, 0x1E, 0x05, 0x0C, 0x33, 0x3A, 0x21, 0x28, 0x5F, 0x56, 0x4D, 0x44, 0x7B, 0x72, 0x69, 0x60,
|
||||
0x0E, 0x07, 0x1C, 0x15, 0x2A, 0x23, 0x38, 0x31, 0x46, 0x4F, 0x54, 0x5D, 0x62, 0x6B, 0x70, 0x79
|
||||
};
|
||||
|
||||
static const uint16_t sdCardCrc16Table[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
@@ -4,10 +4,13 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern uint8_t sed1376Framebuffer[];
|
||||
extern uint16_t* sed1376Framebuffer;
|
||||
extern uint16_t sed1376FramebufferWidth;
|
||||
extern uint16_t sed1376FramebufferHeight;
|
||||
extern uint8_t sed1376Ram[];
|
||||
|
||||
void sed1376Reset(void);
|
||||
uint64_t sed1376StateSize(void);
|
||||
uint32_t sed1376StateSize(void);
|
||||
void sed1376SaveState(uint8_t* data);
|
||||
void sed1376LoadState(uint8_t* data);
|
||||
|
||||
@@ -16,5 +19,6 @@ uint8_t sed1376GetRegister(uint8_t address);
|
||||
void sed1376SetRegister(uint8_t address, uint8_t value);
|
||||
|
||||
void sed1376Render(void);
|
||||
void sed1376UpdateLcdStatus(void);
|
||||
|
||||
#endif
|
||||
123
include/sed1376Accessors.c.h
Normal file
123
include/sed1376Accessors.c.h
Normal file
@@ -0,0 +1,123 @@
|
||||
//data access
|
||||
static uint32_t handlePanelDataSwaps(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
//word swap
|
||||
if(sed1376Registers[SPECIAL_EFFECT] & 0x80)
|
||||
address ^= 0x00000002;
|
||||
#endif
|
||||
//byte swap, used in 16 bpp mode
|
||||
if(sed1376Registers[SPECIAL_EFFECT] & 0x40)
|
||||
address ^= 0x00000001;
|
||||
return address;
|
||||
}
|
||||
|
||||
//color conversion
|
||||
static uint16_t makeRgb16FromSed666(uint8_t r, uint8_t g, uint8_t b){
|
||||
uint16_t color = r >> 2 << 10 & 0xF800;
|
||||
color |= g >> 2 << 5 & 0x07E0;
|
||||
color |= b >> 2 >> 1 & 0x001F;
|
||||
return color;
|
||||
}
|
||||
static uint16_t makeRgb16FromGreenComponent(uint16_t g){
|
||||
uint16_t color = g;
|
||||
color |= g >> 6;
|
||||
color |= g << 5 & 0xF1;
|
||||
return color;
|
||||
}
|
||||
static uint16_t lutMonochromeValue(uint8_t lutIndex){
|
||||
return makeRgb16FromSed666(sed1376GLut[lutIndex], sed1376GLut[lutIndex], sed1376GLut[lutIndex]);
|
||||
}
|
||||
|
||||
//monochrome
|
||||
static uint16_t get1BppMonochrome(uint16_t x, uint16_t y){
|
||||
return lutMonochromeValue(sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 8)] >> (7 - x % 8) & 0x01);
|
||||
}
|
||||
static uint16_t get2BppMonochrome(uint16_t x, uint16_t y){
|
||||
return lutMonochromeValue(sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 4)] >> (6 - x % 4 * 2) & 0x03);
|
||||
}
|
||||
static uint16_t get4BppMonochrome(uint16_t x, uint16_t y){
|
||||
return lutMonochromeValue(sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 2)] >> (4 - x % 2 * 4) & 0x0F);
|
||||
}
|
||||
static uint16_t get8BppMonochrome(uint16_t x, uint16_t y){
|
||||
return lutMonochromeValue(sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x)]);
|
||||
}
|
||||
static uint16_t get16BppMonochrome(uint16_t x, uint16_t y){
|
||||
uint16_t pixelValue = sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + (y * sed1376LineSize + x) * 2)] << 8 | sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + (y * sed1376LineSize + x) * 2 + 1)];
|
||||
return makeRgb16FromGreenComponent(pixelValue);
|
||||
}
|
||||
|
||||
//color
|
||||
static uint16_t get1BppColor(uint16_t x, uint16_t y){
|
||||
return sed1376OutputLut[sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 8)] >> (7 - x % 8) & 0x01];
|
||||
}
|
||||
static uint16_t get2BppColor(uint16_t x, uint16_t y){
|
||||
return sed1376OutputLut[sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 4)] >> (6 - x % 4 * 2) & 0x03];
|
||||
}
|
||||
static uint16_t get4BppColor(uint16_t x, uint16_t y){
|
||||
return sed1376OutputLut[sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x / 2)] >> (4 - x % 2 * 4) & 0x0F];
|
||||
}
|
||||
static uint16_t get8BppColor(uint16_t x, uint16_t y){
|
||||
return sed1376OutputLut[sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + y * sed1376LineSize + x)]];
|
||||
}
|
||||
static uint16_t get16BppColor(uint16_t x, uint16_t y){
|
||||
//this format is little endian, to use big endian data sed1376Registers[SPECIAL_EFFECT] & 0x40 must be set
|
||||
return sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + (y * sed1376LineSize + x * 2) + 1)] << 8 | sed1376Ram[handlePanelDataSwaps(sed1376ScreenStartAddress + (y * sed1376LineSize + x * 2))];
|
||||
}
|
||||
|
||||
static void selectRenderer(bool color, uint8_t bpp){
|
||||
sed1376RenderPixel = NULL;
|
||||
if(color){
|
||||
switch(bpp){
|
||||
case 1:
|
||||
sed1376RenderPixel = get1BppColor;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sed1376RenderPixel = get2BppColor;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
sed1376RenderPixel = get4BppColor;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
sed1376RenderPixel = get8BppColor;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
sed1376RenderPixel = get16BppColor;
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SED1376 invalid color bpp:%d\n", bpp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
switch(bpp){
|
||||
case 1:
|
||||
sed1376RenderPixel = get1BppMonochrome;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sed1376RenderPixel = get2BppMonochrome;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
sed1376RenderPixel = get4BppMonochrome;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
sed1376RenderPixel = get8BppMonochrome;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
sed1376RenderPixel = get16BppMonochrome;
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SED1376 invalid grayscale bpp:%d\n", bpp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
include/sed1376RegisterNames.c.h
Normal file
83
include/sed1376RegisterNames.c.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*SED1376 Register Definitions*/
|
||||
|
||||
/*Read-Only Configuration Registers*/
|
||||
#define REV_CODE 0x00
|
||||
#define DISP_BUFF_SIZE 0x01
|
||||
#define CFG_READBACK 0x02
|
||||
|
||||
/*Clock Configuration Registers*/
|
||||
#define MEM_CLK 0x04
|
||||
#define PIXEL_CLK 0x05
|
||||
|
||||
/*Look Up Table Registers*/
|
||||
#define LUT_B_WRITE 0x08
|
||||
#define LUT_G_WRITE 0x09
|
||||
#define LUT_R_WRITE 0x0A
|
||||
#define LUT_WRITE_LOC 0x0B
|
||||
#define LUT_B_READ 0x0C
|
||||
#define LUT_G_READ 0x0D
|
||||
#define LUT_R_READ 0x0E
|
||||
#define LUT_READ_LOC 0x0F
|
||||
|
||||
/*Panel Configuration Registers*/
|
||||
#define PANEL_TYPE 0x10
|
||||
#define MOD_RATE 0x11
|
||||
#define HORIZ_TOTAL 0x12
|
||||
#define HORIZ_PERIOD 0x14
|
||||
#define HORIZ_START_0 0x16
|
||||
#define HORIZ_START_1 0x17
|
||||
#define VERT_TOTAL_0 0x18
|
||||
#define VERT_TOTAL_1 0x19
|
||||
#define VERT_PERIOD_0 0x1C
|
||||
#define VERT_PERIOD_1 0x1D
|
||||
#define VERT_START_0 0x1E
|
||||
#define VERT_START_1 0x1F
|
||||
#define FPLINE_WIDTH 0x20
|
||||
#define FPLINE_START_0 0x22
|
||||
#define FPLINE_START_1 0x23
|
||||
#define FPFRAME_WIDTH 0x24
|
||||
#define FPFRAME_START_0 0x26
|
||||
#define FPFRAME_START_1 0x27
|
||||
#define DTFD_GCP_INDEX 0x28
|
||||
#define DTFD_GCP_DATA 0x2C
|
||||
|
||||
/*Display Mode Registers*/
|
||||
#define DISP_MODE 0x70
|
||||
#define SPECIAL_EFFECT 0x71
|
||||
#define DISP_ADDR_0 0x74
|
||||
#define DISP_ADDR_1 0x75
|
||||
#define DISP_ADDR_2 0x76
|
||||
#define LINE_SIZE_0 0x78
|
||||
#define LINE_SIZE_1 0x79
|
||||
|
||||
/*Picture-in-Picture Plus (PIP+) Registers*/
|
||||
#define PIP_ADDR_0 0x7C
|
||||
#define PIP_ADDR_1 0x7D
|
||||
#define PIP_ADDR_2 0x7E
|
||||
#define PIP_LINE_SZ_0 0x80
|
||||
#define PIP_LINE_SZ_1 0x81
|
||||
#define PIP_X_START_0 0x84
|
||||
#define PIP_X_START_1 0x85
|
||||
#define PIP_Y_START_0 0x88
|
||||
#define PIP_Y_START_1 0x89
|
||||
#define PIP_X_END_0 0x8C
|
||||
#define PIP_X_END_1 0x8D
|
||||
#define PIP_Y_END_0 0x90
|
||||
#define PIP_Y_END_1 0x91
|
||||
|
||||
/*Miscellaneous Registers*/
|
||||
#define PWR_SAVE_CFG 0xA0
|
||||
#define SCRATCH_0 0xA4
|
||||
#define SCRATCH_1 0xA5
|
||||
|
||||
/*General Purpose IO Pins Registers*/
|
||||
#define GPIO_CONF_0 0xA8
|
||||
#define GPIO_CONF_1 0xA9
|
||||
#define GPIO_CONT_0 0xAC
|
||||
#define GPIO_CONT_1 0xAD
|
||||
|
||||
/*PWM Clock and CV Pulse Configuration Registers*/
|
||||
#define PWM_CONTROL 0xB0
|
||||
#define PWM_CONFIG 0xB1
|
||||
#define PWM_LENGTH 0xB2
|
||||
#define PWM_DUTY_CYCLE 0xB3
|
||||
@@ -4,6 +4,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint16_t silkscreen160x60[];
|
||||
extern const uint16_t silkscreen320x120[];
|
||||
|
||||
#endif
|
||||
14
include/tps65010.h
Normal file
14
include/tps65010.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef TPS65010_H
|
||||
#define TPS65010_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void tps65010Reset(void);
|
||||
uint32_t tps65010StateSize(void);
|
||||
void tps65010SaveState(uint8_t* data);
|
||||
void tps65010LoadState(uint8_t* data);
|
||||
|
||||
uint8_t tps65010I2cExchange(uint8_t i2cBus);
|
||||
void tps65010UpdateInterrupt(void);//called when buttons are refreshed or an SD card is inserted
|
||||
|
||||
#endif
|
||||
20
include/tsc2101.h
Normal file
20
include/tsc2101.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef TSC2101_H
|
||||
#define TSC2101_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void tsc2101Reset(bool isBoot);
|
||||
uint32_t tsc2101StateSize(void);
|
||||
void tsc2101SaveState(uint8_t* data);
|
||||
void tsc2101LoadState(uint8_t* data);
|
||||
|
||||
void tsc2101SetPwrDn(bool value);
|
||||
void tsc2101SetChipSelect(bool value);
|
||||
bool tsc2101ExchangeBit(bool bit);
|
||||
void tsc2101UpdateInterrupt(void);//called after touchscreen update to flush the values
|
||||
//TODO: this chip seems to do audio output, need to add a 16bit optimized transfer function
|
||||
|
||||
void tsc2101Scan(void);
|
||||
|
||||
#endif
|
||||
23
include/tungstenT3Bus.h
Normal file
23
include/tungstenT3Bus.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef TUNGSTEN_T3_BUS_H
|
||||
#define TUNGSTEN_T3_BUS_H
|
||||
|
||||
#define PXA260_BANK_SCOOT 26
|
||||
#define PXA260_NUM_BANKS(areaSize) (((areaSize) >> PXA260_BANK_SCOOT) + ((areaSize) & ((1 << PXA260_BANK_SCOOT) - 1) ? 1 : 0))
|
||||
#define PXA260_START_BANK(address) ((address) >> PXA260_BANK_SCOOT)
|
||||
#define PXA260_END_BANK(address, size) (PXA260_START_BANK(address) + PXA260_NUM_BANKS(size) - 1)
|
||||
#define PXA260_BANK_IN_RANGE(bank, address, size) ((bank) >= PXA260_START_BANK(address) && (bank) <= PXA260_END_BANK(address, size))
|
||||
#define PXA260_BANK_ADDRESS(bank) ((bank) << PXA260_BANK_SCOOT)
|
||||
#define PXA260_TOTAL_MEMORY_BANKS (1 << (32 - PXA260_BANK_SCOOT))//64 banks for *_BANK_SCOOT = 26
|
||||
|
||||
#define PXA260_ROM_START_ADDRESS 0x00000000
|
||||
#define PXA260_RAM_START_ADDRESS 0xA0000000
|
||||
#define TUNGSTEN_T3_W86L488_START_ADDRESS 0x08000000
|
||||
#define PXA260_PCMCIA0_START_ADDRESS 0x20000000
|
||||
#define PXA260_PCMCIA1_START_ADDRESS 0x30000000
|
||||
#define TUNGSTEN_T3_ROM_SIZE (16 * 0x100000)//16mb ROM
|
||||
#define TUNGSTEN_T3_RAM_SIZE (64 * 0x100000)//64mb RAM
|
||||
#define TUNGSTEN_T3_W86L488_SIZE 0x04000000
|
||||
#define PXA260_PCMCIA0_SIZE 0x10000000
|
||||
#define PXA260_PCMCIA1_SIZE 0x10000000
|
||||
|
||||
#endif
|
||||
14
include/w86l488.h
Normal file
14
include/w86l488.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef W86L488_H
|
||||
#define W86L488_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void w86l488Reset(void);
|
||||
uint32_t w86l488StateSize(void);
|
||||
void w86l488SaveState(uint8_t* data);
|
||||
void w86l488LoadState(uint8_t* data);
|
||||
|
||||
uint16_t w86l488Read16(uint8_t address);
|
||||
void w86l488Write16(uint8_t address, uint16_t value);
|
||||
|
||||
#endif
|
||||
50
libretroBuildSystem/CMakeLists.txt
Normal file
50
libretroBuildSystem/CMakeLists.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
add_library(mu_libretro SHARED
|
||||
libretro.c
|
||||
cursors.c
|
||||
miniz.c
|
||||
libretro-common/compat/compat_strl.c
|
||||
libretro-common/compat/compat_posix_string.c
|
||||
libretro-common/compat/fopen_utf8.c
|
||||
libretro-common/encodings/encoding_utf.c
|
||||
libretro-common/memmap/memmap.c
|
||||
libretro-common/streams/file_stream.c
|
||||
libretro-common/string/stdstring.c
|
||||
libretro-common/vfs/vfs_implementation.c)
|
||||
|
||||
# Remove the "lib" prefix always, RetroArch does not name in this way
|
||||
set_target_properties(mu_libretro PROPERTIES PREFIX "")
|
||||
|
||||
# Bring all the sub-modules as needed
|
||||
target_link_libraries(mu_libretro
|
||||
MuCore)
|
||||
|
||||
# Include the required includes
|
||||
target_include_directories(mu_libretro PUBLIC
|
||||
"${PROJECT_SOURCE_DIR}/include"
|
||||
"libretro-common/include")
|
||||
|
||||
# Custom launching the core, tries to find RetroArch on the system
|
||||
## Determine RetroArch directory
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
set(MU_LIBRETRO_EXTENSION ".exe")
|
||||
|
||||
if (EXISTS "$ENV{APPDATA}/RetroArch")
|
||||
set(MU_LIBRETRO_DIR "$ENV{APPDATA}/RetroArch")
|
||||
endif()
|
||||
else()
|
||||
find_program(RETROARCH_APP retroarch)
|
||||
if(RETROARCH_APP)
|
||||
get_filename_component(MU_LIBRETRO_DIR "${RETROARCH_APP}" DIRECTORY)
|
||||
endif()
|
||||
|
||||
set(MU_LIBRETRO_EXTENSION "")
|
||||
endif()
|
||||
|
||||
## Target to run RetroArch with the Mu Core
|
||||
if(DEFINED MU_LIBRETRO_DIR)
|
||||
add_custom_target(RetroArch
|
||||
DEPENDS mu_libretro
|
||||
COMMAND "${MU_LIBRETRO_DIR}/retroarch${MU_LIBRETRO_EXTENSION}" "-v" "-L" "$<TARGET_FILE:mu_libretro>"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
COMMENT "Starting RetroArch with Mu")
|
||||
endif()
|
||||
@@ -35,6 +35,8 @@ else ifeq ($(platform),windows_msvc2003_x86)
|
||||
include $(BUILD_DIR)/Makefile.windows_msvc2003_x86
|
||||
else ifeq ($(platform),windows_msvc2005_x86)
|
||||
include $(BUILD_DIR)/Makefile.windows_msvc2005_x86
|
||||
else ifeq ($(platform),windows_msvc2008_x86)
|
||||
include $(BUILD_DIR)/Makefile.windows_msvc2008_x86
|
||||
else ifeq ($(platform),windows_msvc2010_x86)
|
||||
include $(BUILD_DIR)/Makefile.windows_msvc2010_x86
|
||||
else ifeq ($(platform),windows_msvc2010_x64)
|
||||
@@ -125,13 +127,28 @@ ifeq ($(arch),ppc)
|
||||
CFLAGS += -D__ppc__ -DMSB_FIRST -DWORDS_BIGENDIAN=1
|
||||
endif
|
||||
OSXVER = $(shell sw_vers -productVersion | cut -d. -f 2)
|
||||
OSX_LT_MAVERICKS = $(shell (( $(OSXVER) <= 9)) && echo "YES")
|
||||
OSX_GT_MOJAVE = $(shell (( $(OSXVER) >= 14)) && echo "YES")
|
||||
ifneq ($(OSX_GT_MOJAVE),YES)
|
||||
#this breaks compiling on Mac OS Mojave
|
||||
fpic += -mmacosx-version-min=10.1
|
||||
endif
|
||||
|
||||
ifeq ($(OSX_LT_MAVERICKS),"YES")
|
||||
fpic += -mmacosx-version-min=10.5
|
||||
else
|
||||
ifneq ($(OSX_GT_MOJAVE),YES)
|
||||
#this breaks compiling on Mac OS Mojave
|
||||
fpic += -mmacosx-version-min=10.1
|
||||
endif
|
||||
endif
|
||||
|
||||
SHARED := -dynamiclib
|
||||
|
||||
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
|
||||
|
||||
# iOS
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
EXT ?= dylib
|
||||
@@ -159,6 +176,19 @@ CC += -miphoneos-version-min=5.0
|
||||
CFLAGS += -miphoneos-version-min=5.0
|
||||
endif
|
||||
|
||||
# tvOS
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
CFLAGS := -DIOS
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
|
||||
endif
|
||||
CC = clang -arch arm64 -isysroot $(IOSSDK)
|
||||
CXX = clang++ -arch arm64 -isysroot $(IOSSDK)
|
||||
|
||||
# Theos iOS
|
||||
else ifeq ($(platform), theos_ios)
|
||||
DEPLOYMENT_IOSVERSION = 5.0
|
||||
@@ -180,33 +210,15 @@ else ifeq ($(platform), qnx)
|
||||
AR = qcc -Vgcc_ntoarmv7le
|
||||
CFLAGS += -D__BLACKBERRY_QNX__
|
||||
|
||||
# PS3
|
||||
else ifeq ($(platform), ps3)
|
||||
EXT = a
|
||||
TARGET := $(TARGET_NAME)_libretro_ps3.$(EXT)
|
||||
CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
|
||||
CFLAGS += -D__ppc__ -DMSB_FIRST -DWORDS_BIGENDIAN=1
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
# PS3 (SNC)
|
||||
else ifeq ($(platform), sncps3)
|
||||
EXT = a
|
||||
TARGET := $(TARGET_NAME)_libretro_ps3.$(EXT)
|
||||
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
|
||||
CFLAGS += -D__ppc__ -DMSB_FIRST -DWORDS_BIGENDIAN=1
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
# Lightweight PS3 Homebrew SDK
|
||||
else ifeq ($(platform), psl1ght)
|
||||
EXT = a
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT)
|
||||
CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT)
|
||||
AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT)
|
||||
CFLAGS += -D__ppc__ -DMSB_FIRST -DWORDS_BIGENDIAN=1
|
||||
else ifneq (,$(filter $(platform), ps3 psl1ght))
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT)
|
||||
AR = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)ar$(EXE_EXT)
|
||||
ifeq ($(platform), psl1ght)
|
||||
CFLAGS += -D__PSL1GHT__
|
||||
endif
|
||||
CFLAGS += -D__ppc__ -DMSB_FIRST -DWORDS_BIGENDIAN=1 -D__PS3__
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
@@ -381,7 +393,9 @@ else ifneq (,$(findstring armv,$(platform)))
|
||||
# Emscripten
|
||||
else ifeq ($(platform), emscripten)
|
||||
TARGET := $(TARGET_NAME)_libretro_emscripten.bc
|
||||
AR=emar
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
# GCW0
|
||||
else ifeq ($(platform), gcw0)
|
||||
@@ -438,11 +452,21 @@ else ifeq ($(platform), xbox1_msvc2003)
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
# PlayStation 2
|
||||
else ifeq ($(platform), ps2)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
CC = mips64r5900el-ps2-elf-gcc$(EXE_EXT)
|
||||
CXX = mips64r5900el-ps2-elf-g++$(EXE_EXT)
|
||||
AR = mips64r5900el-ps2-elf-ar$(EXE_EXT)
|
||||
CFLAGS += -Wall -DPS2 -DABGR1555
|
||||
STATIC_LINKING = 1
|
||||
STATIC_LINKING_LINK = 1
|
||||
|
||||
# Windows
|
||||
else
|
||||
EXT ?= dll
|
||||
TARGET := $(TARGET_NAME)_libretro.$(EXT)
|
||||
CC = gcc
|
||||
CC ?= gcc
|
||||
SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=$(BUILD_DIR)/link.T
|
||||
CFLAGS += -D__WIN32__ -D__WIN32_LIBRETRO__
|
||||
endif
|
||||
@@ -463,9 +487,9 @@ endif
|
||||
|
||||
include $(BUILD_DIR)/Makefile.common
|
||||
|
||||
OBJECTS := $(SOURCES_C:.c=.o) $(SOURCES_ASM:.S=.o)
|
||||
OBJECTS := $(SOURCES_C:.c=.o) $(SOURCES_CXX:.cpp=.o) $(SOURCES_ASM:.S=.o)
|
||||
|
||||
DEFINES = $(COREDEFINES)
|
||||
DEFINES += $(COREDEFINES)
|
||||
|
||||
ifeq ($(STATIC_LINKING), 1)
|
||||
DEFINES += -DSTATIC_LINKING
|
||||
@@ -488,6 +512,7 @@ endif
|
||||
COMMON_DEFINES += $(CODE_DEFINES) $(WARNINGS_DEFINES) $(fpic)
|
||||
|
||||
CFLAGS += $(DEFINES) $(COMMON_DEFINES)
|
||||
CXXFLAGS += $(DEFINES) $(COMMON_DEFINES)
|
||||
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
OBJOUT = -Fo
|
||||
@@ -507,16 +532,14 @@ endif
|
||||
ifeq ($(platform), theos_ios)
|
||||
COMMON_FLAGS := -DIOS -DARM $(COMMON_DEFINES) $(INCFLAGS) -I$(THEOS_INCLUDE_PATH) -Wno-error
|
||||
$(LIBRARY_NAME)_CFLAGS += $(COMMON_FLAGS)
|
||||
${LIBRARY_NAME}_FILES = $(SOURCES_C) $(SOURCES_ASM)
|
||||
${LIBRARY_NAME}_FILES = $(SOURCES_C) $(SOURCES_CXX) $(SOURCES_ASM)
|
||||
include $(THEOS_MAKE_PATH)/library.mk
|
||||
else
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
@echo "** BUILDING $(TARGET) FOR PLATFORM $(platform) **"
|
||||
ifeq ($(platform), emscripten)
|
||||
$(CC) $(CFLAGS) $(OBJOUT)$@ $^
|
||||
else ifeq ($(STATIC_LINKING_LINK), 1)
|
||||
ifeq ($(STATIC_LINKING_LINK), 1)
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
$(LD) $(LINKOUT)$@ $(OBJECTS)
|
||||
else
|
||||
@@ -526,8 +549,6 @@ else
|
||||
$(CC) $(fpic) $(SHARED) $(INCFLAGS) $(LDFLAGS) $(OBJOUT)$@ $(OBJECTS) $(LIBM)
|
||||
endif
|
||||
|
||||
@echo "** BUILD SUCCESSFUL! GG NO RE **"
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(INCFLAGS) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
|
||||
@@ -2,49 +2,117 @@ EMU_PATH := $(CORE_DIR)/../src
|
||||
LIBRETRO_COMM_DIR := $(CORE_DIR)/libretro-common
|
||||
COREDEFINES :=
|
||||
|
||||
INCFLAGS := -I$(LIBRETRO_COMM_DIR)/include
|
||||
# my first make function!!!
|
||||
CHECK_ALL = $(strip $(foreach v,$(2),$(if $(findstring $(v),$(1)),$(v),)))
|
||||
|
||||
INCFLAGS := -I$(CORE_DIR)/../include -I$(LIBRETRO_COMM_DIR)/include
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
COREDEFINES += -DEMU_DEBUG -DEMU_SANDBOX
|
||||
COREDEFINES += -DEMU_DEBUG
|
||||
else
|
||||
COREDEFINES += -DEMU_NO_SAFETY
|
||||
EMU_NO_SAFETY := 1
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring msvc200,$(platform)))
|
||||
# "unix" or "win" is not specific enough, need to know the CPU arch too
|
||||
this_system := $(platform)
|
||||
ifneq (,$(filter unix win,$(this_system)))
|
||||
this_system := $(shell $(CC) -dumpmachine)
|
||||
endif
|
||||
|
||||
|
||||
ifneq (,$(findstring msvc200,$(this_system)))
|
||||
INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring msvc20,$(platform)))
|
||||
ifneq (,$(findstring msvc20,$(this_system)))
|
||||
# Mu is dependent on stdbool.h and the standard inline directive existing
|
||||
INCFLAGS += -I$(CORE_DIR)/fixIncludes/stdbool
|
||||
COREDEFINES += -Dinline=_inline -DINLINE=_inline
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ps3 sncps3 psl1ght ngc wii wiiu,$(platform)))
|
||||
ifneq (,$(call CHECK_ALL,$(this_system),windows mingw))
|
||||
# Windows
|
||||
ifeq (,$(findstring msvc,$(this_system)))
|
||||
EMU_SUPPORT_PALM_OS5 := 1
|
||||
EMU_OS := windows
|
||||
ifneq (,$(call CHECK_ALL,$(this_system),x86_64 x64))
|
||||
EMU_ARCH := x86_64
|
||||
else
|
||||
EMU_ARCH := x86_32
|
||||
endif
|
||||
else
|
||||
# MSVC uses its own(incompatible) ASM syntax
|
||||
EMU_SUPPORT_PALM_OS5 := 0
|
||||
endif
|
||||
else ifneq (,$(call CHECK_ALL,$(this_system),armv8 aarch64))
|
||||
# ARM Linux 64
|
||||
EMU_SUPPORT_PALM_OS5 := 1
|
||||
EMU_ARCH := armv8
|
||||
EMU_OS := linux
|
||||
else ifneq (,$(call CHECK_ALL,$(this_system),armv rpi2 rpi3))
|
||||
# ARM Linux(rpi3 is aarch64 but its almost always used in 32bit mode)
|
||||
EMU_SUPPORT_PALM_OS5 := 1
|
||||
EMU_ARCH := armv7
|
||||
EMU_OS := linux
|
||||
else ifneq (,$(findstring armhf,$(this_system)))
|
||||
# ARM Linux ARMv5
|
||||
# this needs to be before "linux" because it will trigger the linux case
|
||||
EMU_SUPPORT_PALM_OS5 := 0
|
||||
else ifneq (,$(call CHECK_ALL,$(this_system),osx linux))
|
||||
# x86_* Linux
|
||||
EMU_SUPPORT_PALM_OS5 := 1
|
||||
ifneq (,$(call CHECK_ALL,$(this_system),osx x86_64 x64))
|
||||
EMU_ARCH := x86_64
|
||||
else
|
||||
EMU_ARCH := x86_32
|
||||
endif
|
||||
EMU_OS := linux
|
||||
endif
|
||||
|
||||
# OS 5 isnt even booting yet, just turn the dynarec off to make it compile easier
|
||||
EMU_ARCH := unknown
|
||||
|
||||
ifneq (,$(filter ps3 sncps3 psl1ght ngc wii wiiu,$(this_system)))
|
||||
COREDEFINES += -DEMU_BIG_ENDIAN
|
||||
else ifeq ($(platform), osx)
|
||||
else ifeq ($(this_system), osx)
|
||||
ifeq ($(arch), ppc)
|
||||
COREDEFINES += -DEMU_BIG_ENDIAN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter qnx vita ctr rpi2 classic_armv7_a7,$(platform)))
|
||||
EMU_OPTIMIZE_FOR_ARM32 = 1
|
||||
else ifneq (,$(findstring armv7,$(platform)))
|
||||
EMU_OPTIMIZE_FOR_ARM32 = 1
|
||||
else ifneq (,$(findstring armv6,$(platform)))
|
||||
EMU_OPTIMIZE_FOR_ARM32 = 1
|
||||
else ifneq (,$(findstring armhf,$(platform)))
|
||||
EMU_OPTIMIZE_FOR_ARM32 = 1
|
||||
# use all CPUs and optimize for the most likely outcome, Android is handled separately
|
||||
# Apple broke OpenMP in there port of Clang so no Mac OS or iOS
|
||||
# ifneq (,$(call CHECK_ALL,$(this_system),windows mingw linux))
|
||||
# # none of libretros MSVC compilers work with these optimizations for multiple different reasons
|
||||
# # they dont have the library "VCOMP.lib"
|
||||
# # they are too old for the extension to exist
|
||||
# # MSVC never has or will support __builtin_expect
|
||||
# ifeq (,$(findstring msvc,$(this_system)))
|
||||
# COREDEFINES += -fopenmp -DEMU_MULTITHREADED -DEMU_MANAGE_HOST_CPU_PIPELINE
|
||||
# LDFLAGS += -fopenmp
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# use C++11
|
||||
ifeq ($(EMU_SUPPORT_PALM_OS5), 1)
|
||||
ifneq ($(this_system), android_jni)
|
||||
CXXFLAGS += -std=c++11
|
||||
endif
|
||||
endif
|
||||
|
||||
# RetroArch needs to be able to launch files directly
|
||||
EMU_HAVE_FILE_LAUNCHER := 1
|
||||
|
||||
include $(EMU_PATH)/makefile.all
|
||||
|
||||
COREDEFINES += $(EMU_DEFINES)
|
||||
|
||||
SOURCES_C := $(CORE_DIR)/libretro.c \
|
||||
$(CORE_DIR)/cursors.c \
|
||||
$(CORE_DIR)/miniz.c \
|
||||
$(EMU_SOURCES_C)
|
||||
SOURCES_CXX := $(EMU_SOURCES_CXX)
|
||||
SOURCES_ASM := $(EMU_SOURCES_ASM)
|
||||
|
||||
ifneq ($(STATIC_LINKING), 1)
|
||||
SOURCES_C += $(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
|
||||
@@ -57,4 +125,5 @@ ifneq ($(STATIC_LINKING), 1)
|
||||
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
|
||||
endif
|
||||
|
||||
SOURCES_ASM := $(EMU_SOURCES_ASM)
|
||||
# Make sure C++ shares our include flags!
|
||||
CXXFLAGS += $(INCFLAGS)
|
||||
|
||||
@@ -59,7 +59,7 @@ RETROLDXFLAGS =
|
||||
#################
|
||||
# Final variables
|
||||
|
||||
DEFINES = $(PLATDEFS) $(RETRODEFS)
|
||||
DEFINES = $(PLATDEFS) $(COREDEFINES) $(RETRODEFS)
|
||||
CFLAGS = $(PLATCFLAGS) $(RETROCFLAGS) $(DEFINES) $(INCLUDES)
|
||||
CXXFLAGS = $(PLATCXXFLAGS) $(RETROCXXFLAGS) $(DEFINES) $(INCLUDES)
|
||||
LDFLAGS = $(PLATLDFLAGS) $(RETROLDFLAGS)
|
||||
|
||||
@@ -59,7 +59,7 @@ RETROLDXFLAGS =
|
||||
#################
|
||||
# Final variables
|
||||
|
||||
DEFINES = $(PLATDEFS) $(RETRODEFS)
|
||||
DEFINES = $(PLATDEFS) $(COREDEFINES) $(RETRODEFS)
|
||||
CFLAGS = $(PLATCFLAGS) $(RETROCFLAGS) $(DEFINES) $(INCLUDES)
|
||||
CXXFLAGS = $(PLATCXXFLAGS) $(RETROCXXFLAGS) $(DEFINES) $(INCLUDES)
|
||||
LDFLAGS = $(PLATLDFLAGS) $(RETROLDFLAGS)
|
||||
|
||||
@@ -59,7 +59,7 @@ RETROLDXFLAGS =
|
||||
#################
|
||||
# Final variables
|
||||
|
||||
DEFINES = $(PLATDEFS) $(RETRODEFS)
|
||||
DEFINES = $(PLATDEFS) $(COREDEFINES) $(RETRODEFS)
|
||||
CFLAGS = $(PLATCFLAGS) $(RETROCFLAGS) $(DEFINES) $(INCLUDES)
|
||||
CXXFLAGS = $(PLATCXXFLAGS) $(RETROCXXFLAGS) $(DEFINES) $(INCLUDES)
|
||||
LDFLAGS = $(PLATLDFLAGS) $(RETROLDFLAGS)
|
||||
|
||||
@@ -59,7 +59,7 @@ RETROLDXFLAGS =
|
||||
#################
|
||||
# Final variables
|
||||
|
||||
DEFINES = $(PLATDEFS) $(RETRODEFS)
|
||||
DEFINES = $(PLATDEFS) $(COREDEFINES) $(RETRODEFS)
|
||||
CFLAGS = $(PLATCFLAGS) $(RETROCFLAGS) $(DEFINES) $(INCLUDES)
|
||||
CXXFLAGS = $(PLATCXXFLAGS) $(RETROCXXFLAGS) $(DEFINES) $(INCLUDES)
|
||||
LDFLAGS = $(PLATLDFLAGS) $(RETROLDFLAGS)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user