446 Commits

Author SHA1 Message Date
Stephanie Gawroriski
45154c0c73 Bump version to 1.3.2. 2024-06-16 19:47:29 -04:00
Stephanie Gawroriski
5e5e21e302 Move up definition. 2024-06-14 19:13:52 -04:00
Stephanie Gawroriski
8223b6fd76 No longer crash the Qt interface if it could not initialize audio. 2024-06-14 18:56:56 -04:00
Stephanie Gawroriski
dee65d0d1a Fill initial RAM with garbage so PalmOS is much more likely to find it invalid; Add RetroArch run command if it exists in PATH. 2024-06-14 18:49:21 -04:00
LibretroAdmin
865acf3a28 Update Makefile.libretro 2023-11-01 19:20:58 -07:00
Stephanie Gawroriski
15bb26daa5 Merge pull request #29 from warmenhoven/dev/warmenhoven/tvos
Add tvos build
2023-05-27 18:38:29 -04:00
Eric Warmenhoven
dc854cef9e Add tvos build 2023-05-27 17:43:15 -04:00
Stephanie Gawroriski
91a46734dd Merge pull request #28 from libretro/wip-macosarmfix
Attempt fix of macOS ARM build (Fixes #27).
2023-01-23 08:55:17 -05:00
Stephanie Gawroriski
d0651a450d Attempt fix of macOS ARM build. 2023-01-22 17:01:37 -05:00
Stephanie Gawroriski
4a3fee96e7 README updates. 2022-10-02 17:58:21 -04:00
Stephanie Gawroriski
4d084a03d7 RetroArch CMake corrections; Implement loading from ZIP files which contain PRCs and PDBs. 2022-10-02 17:34:57 -04:00
Stephanie Gawroriski
aadb0a29ff Include miniz library; Make all CMake builds PIC. 2022-10-02 16:25:53 -04:00
Stephanie Gawroriski
90a9a94257 Update valid extensions to everything in the core info; Disallow libRetro from looking into ZIP files, we will be handling it ourself so that we can load all PRCs and PDBs. 2022-10-02 00:14:01 -04:00
Stephanie Gawroriski
679626b58f Add build for Mac OS ARM. 2022-10-01 23:41:38 -04:00
Stephanie Gawroriski
1361da0401 Merge pull request #19 from phcoder/patch-1
Fix dingux compilation name
2022-03-17 17:53:24 -04:00
Vladimir Serbinenko
c13324e9c7 Fix dingux compilation name 2022-03-16 06:53:55 +01:00
Stephanie Gawroriski
9d23f9bb67 Merge pull request #18 from crystalct/master
PS3/PSL1GHT build fix
2022-02-26 13:42:47 -05:00
CrystalCT
f16e54e879 PS3/PSL1GHT build fix 2022-02-21 13:47:56 +01:00
Stephanie Gawroriski
2954a42bba Merge pull request #17 from TyroneSlothrop/master
Add iOS ARM64 build
2022-01-25 18:16:49 -05:00
Tyrone Slothrop
b066eb856d Add iOS ARM64 build 2022-01-22 00:25:51 +00:00
Stephanie Gawroriski
be844bf74d Add pdb to the extensions list. 2021-11-27 10:53:45 -05:00
Stephanie Gawroriski
7ead066572 Update RetroArch core info. 2021-07-16 08:27:07 -04:00
Stephanie Gawroriski
304c0855c1 Add license file; Add Windows icon resource. 2021-07-16 08:03:14 -04:00
Stephanie Gawroriski
932f224580 Add threads to build (needed for mingw-64 POSIX and Linux); Dedication within CMake. 2021-07-15 23:50:01 -04:00
Stephanie Gawroriski
6fd0600446 Add instructions. 2021-07-15 23:40:07 -04:00
Stephanie Gawroriski
ebd397f5ba Merge branch 'master' of github.com:libretro/Mu 2021-07-15 23:27:50 -04:00
Stephanie Gawroriski
f631649bf7 Bring in the Qt interface into CMake; Fixes for Visual Studio build. 2021-07-15 23:27:00 -04:00
Autechre
5795ade531 Update .gitlab-ci.yml 2021-03-17 15:30:24 +01:00
twinaphex
ff746b8196 Fix MSVC builds - embed MSVCRT runtime 2021-02-14 22:09:34 +01:00
twinaphex
e053b170d2 Add MSVC 2005 / 2010 cores 2021-02-13 01:47:51 +01:00
Autechre
df5a0c63bc Merge pull request #9 from fjtrujy/PS2NewToolchain
[PS2] Update bins for new toolchain
2021-01-15 00:51:48 +01:00
Francisco Javier Trujillo Mata
d93c8c0efc Update bins for new toolchain 2021-01-15 00:16:07 +01:00
Autechre
62a7f6f2b3 Update .gitlab-ci.yml 2021-01-10 23:34:35 +01:00
Autechre
e4209e1044 Update .gitlab-ci.yml 2021-01-09 16:52:52 +01:00
Autechre
e140a25c5b Merge pull request #8 from webgeek1234/master
Fix multiple definitions of pxa260Framebuffer
2021-01-03 01:16:28 +01:00
Autechre
3d408f3b37 Update .gitlab-ci.yml 2021-01-03 01:16:19 +01:00
Autechre
5a7750163f Update .gitlab-ci.yml 2021-01-03 01:15:56 +01:00
Aaron Kling
c9af673bf4 Fix multiple definitions of pxa260Framebuffer 2021-01-02 15:48:58 -06:00
Autechre
cb2dcc1740 Update Makefile.libretro 2020-12-29 07:07:42 +01:00
Autechre
bda022c63a Update Makefile.libretro 2020-12-29 02:37:58 +01:00
Autechre
5022d08ffb Update .gitlab-ci.yml 2020-12-29 01:41:16 +01:00
Stephanie Gawroriski
95ebb37e5f Merge branch 'master' of github.com:libretro/Mu 2020-12-28 19:13:43 -05:00
Stephanie Gawroriski
ec3ba7e2cd Add Wii U. 2020-12-28 19:10:00 -05:00
Autechre
41e0edcaa3 Update .gitlab-ci.yml 2020-12-28 23:47:19 +01:00
Stephanie Gawroriski
223255e2e1 Add Dingux, Nintendo 3DS, Nintendo GameCube, and Nintendo Wii. 2020-12-04 19:18:49 -05:00
Stephanie Gawroriski
1705a0ddd6 Merge pull request #7 from webgeek1234/master
libretro: Update gitlab ci extends ordering
2020-12-02 07:41:14 -05:00
Aaron Kling
6ffa4d1d66 libretro: Update gitlab ci extends ordering 2020-12-01 19:25:53 -06:00
Stephanie Gawroriski
9057820fbc Make sure our include flags are included when compiling C++ code. 2020-11-06 21:21:35 -05:00
Stephanie Gawroriski
254212a229 Define UINTMAX_MAX for PS2. 2020-11-06 21:13:26 -05:00
Stephanie Gawroriski
87c8cfce6b Correct includes in translators. 2020-11-06 21:03:28 -05:00
Stephanie Gawroriski
96e70d964f Include standard headers (for PS2). 2020-11-06 20:59:36 -05:00
Stephanie Gawroriski
855504f180 Correct Linux OS build. 2020-11-06 20:57:13 -05:00
Stephanie Gawroriski
6870d8b7ab Correct includes. 2020-11-06 20:55:05 -05:00
Stephanie Gawroriski
be386ff05d For CMake disable dynamic recompilation for now. 2020-11-06 20:43:59 -05:00
Stephanie Gawroriski
5a86c5ccf9 Add CMake and re-organize project, keeping includes separated from sources. 2020-11-06 20:29:40 -05:00
Stephanie Gawroriski
3e4829f443 Include missing include. 2020-11-06 18:56:59 -05:00
Stephanie Gawroriski
f6c7944c64 Import PS2 build from SquirrelJME. 2020-11-06 18:54:13 -05:00
Stephanie Gawroriski
d9437c28cb Correct CI/CD config. 2020-11-06 18:48:03 -05:00
Stephanie Gawroriski
1a6d22086d Add GitLab CI/CD for RetroArch building. 2020-11-06 18:43:51 -05:00
Stephanie Gawroriski
46b29248dc Add dedication to Emily, I hope that you are resting in peace. 2020-11-06 18:38:54 -05:00
Stephanie Gawroriski
e7da587071 Remove CircleCI config as it is not used; Add CLion project. 2020-11-06 18:31:08 -05:00
meepingsnesroms
4ac406874c Merge pull request #97 from meepingsnesroms/tungstenT3Support
Remove Android armv5/6
2019-11-29 14:32:57 -08:00
meepingsnesroms
c2ffd5a04a Remove Android armv5/6 2019-11-29 14:32:11 -08:00
meepingsnesroms
d29d1978ee Merge pull request #96 from meepingsnesroms/tungstenT3Support
Tungsten t3 support
2019-11-29 13:24:04 -08:00
meepingsnesroms
f66e5613b3 Fix lockups in 68K Palm OS 2019-11-27 14:39:55 -08:00
meepingsnesroms
865b1d5f86 More bug info 2019-11-26 18:31:22 -08:00
meepingsnesroms
815f061683 Some fixes 2019-11-26 15:15:19 -08:00
meepingsnesroms
97f8f85021 Make release mode work in QT 2019-11-26 14:06:10 -08:00
meepingsnesroms
e9385a62ab Update currentBug.txt 2019-11-26 13:06:47 -08:00
meepingsnesroms
b18cc463b6 Update Makefile.common 2019-11-26 12:47:26 -08:00
meepingsnesroms
2ece2d56d4 m500 support working in RetroArch 2019-11-26 12:45:35 -08:00
meepingsnesroms
4738d36119 Finish m500 support 2019-11-26 11:43:00 -08:00
meepingsnesroms
4b836d98db Update dbvz.c 2019-11-26 10:31:16 -08:00
meepingsnesroms
c8c4539e6f Clean up gradiant code, make backlight code overflow safe 2019-11-25 23:10:46 -08:00
meepingsnesroms
aed3be3b80 Add backlight for m500, clean up m515 backlight
Also backup gradiant code.
2019-11-25 23:00:28 -08:00
meepingsnesroms
c6df0303c8 Fix memory size for m500 2019-11-25 21:14:09 -08:00
meepingsnesroms
126b2cf20f Clean up and increase safety with multiple device and ROM versions 2019-11-25 20:44:48 -08:00
meepingsnesroms
0c8e6fdebc m500 booting again 2019-11-25 19:05:33 -08:00
meepingsnesroms
daf0aede3d Remove sandbox, it was all unused 68k stuff anyway 2019-11-25 18:41:41 -08:00
meepingsnesroms
f768615984 Palm m500 support Part 1, not booting again 2019-11-25 18:25:00 -08:00
meepingsnesroms
c427a607ec Add basic CPU LCD controller support 2019-11-24 14:58:56 -08:00
meepingsnesroms
aff2d76148 Flush changes 2019-11-21 09:35:48 -08:00
meepingsnesroms
9d41480371 Cleanups and plarity fix for TPS65010 INT pin 2019-11-20 12:09:34 -08:00
meepingsnesroms
de8c733340 Add uARM as reference CPU core 2019-11-20 10:02:38 -08:00
meepingsnesroms
8d386d8027 Add another IDA script 2019-11-16 13:02:12 -08:00
meepingsnesroms
3b009d7131 Clean up logs after so many entrys, log all DAL function calls 2019-11-15 10:54:42 -08:00
meepingsnesroms
c303c7426b Switch ARMv5 to virtual addresses, they where already used(and the only option) for 68k 2019-11-14 13:27:20 -08:00
meepingsnesroms
0372fdbaff Can now copy from log output 2019-11-11 16:21:46 -08:00
meepingsnesroms
863cd964bd Decompiling now supported directly in the emu, cleanups 2019-11-11 15:36:44 -08:00
meepingsnesroms
a06d013f33 Create getOs4FunctionNames.py 2019-11-07 13:31:23 -08:00
meepingsnesroms
c08bdd573a Create dalAddrFromPc.py 2019-11-07 13:28:11 -08:00
meepingsnesroms
4712e77413 Cleanups, add missing button, log PC for more events 2019-11-07 12:20:18 -08:00
meepingsnesroms
57d19df30d Update TPS65010, fix T3 overclocking method 2019-09-25 11:29:09 -07:00
meepingsnesroms
dd09261b53 Fix cutting off the 6MB of ROM at the end and SIGSEGV on reset 2019-09-23 17:20:57 -07:00
meepingsnesroms
c72edbfa1b Remove old CPU core linkage 2019-09-23 10:33:59 -07:00
meepingsnesroms
20348abf85 Update logging 2019-09-22 22:45:57 -07:00
meepingsnesroms
6b1e293c44 Use opcode timing instead of frame timing for CPU timer events
Makes things much faster!
2019-09-22 22:32:52 -07:00
meepingsnesroms
d0292b312f Add key matrix handleing 2019-09-22 19:13:21 -07:00
meepingsnesroms
2b982cee22 Update tests.c 2019-09-22 15:40:39 -07:00
meepingsnesroms
2c072ded8a ARM calling is working 2019-09-22 14:25:09 -07:00
meepingsnesroms
309f91312f Fill out more of the TSC2101 test 2019-09-22 13:26:43 -07:00
meepingsnesroms
4450ac9402 Arm test code is now compiling and linking properly 2019-09-21 20:07:04 -07:00
meepingsnesroms
01bebf5418 Switch to new compiler, need to test 2019-09-21 19:35:05 -07:00
meepingsnesroms
4c7d34facf ARM tests are now compiling, not callable yet though 2019-09-20 13:42:11 -07:00
meepingsnesroms
16924bb811 Fix test compiling 2019-09-20 10:46:55 -07:00
meepingsnesroms
e9d6d21625 Add ARM side C code skeleton, definetly broke test compiling 2019-09-18 16:18:04 -07:00
meepingsnesroms
6b351c67fd Start working on T3 ADC test 2019-09-17 10:11:35 -07:00
meepingsnesroms
7be8825f96 More USB stuff 2019-09-16 19:41:01 -07:00
meepingsnesroms
02778eeb08 Update pxa260Udc.c 2019-09-12 14:12:18 -07:00
meepingsnesroms
f76abf87a1 Add more USB port registers 2019-09-12 13:54:01 -07:00
meepingsnesroms
0bb3287d6d Better event logging 2019-09-12 12:56:05 -07:00
meepingsnesroms
64950ac431 Block annyoing idle loop 2019-09-12 12:12:47 -07:00
meepingsnesroms
85e9a03796 Merge pull request #95 from meepingsnesroms/master
Merge over tvOS support
2019-09-12 10:42:00 -07:00
meepingsnesroms
14e0d66101 Merge pull request #94 from yoshisuga/tvos_platform
(tvOS) support building
2019-09-12 10:40:56 -07:00
Yoshi Sugawara
eea4c328d2 (tvOS) support building 2019-09-11 07:50:47 -10:00
meepingsnesroms
9143759c29 Small changes 2019-09-05 17:35:47 -07:00
meepingsnesroms
9289232dd0 Was stuck on a delay loop, now to implement the USB enough to boot 2019-09-02 09:57:55 -07:00
meepingsnesroms
a2dbb98d88 I2C seems fixed now 2019-09-01 12:45:49 -07:00
meepingsnesroms
fd572858e2 Lots of I2C bugs
Still need to fix more
2019-09-01 11:41:43 -07:00
meepingsnesroms
d5b6664c73 Get ARM accesses working 2019-08-30 19:02:46 -07:00
meepingsnesroms
ff46e40ded Start adding arm testing stuff, remove special emu functions 2019-08-30 16:17:09 -07:00
meepingsnesroms
f00cfd057b Fix swapped registers, TSC2101 status now tells Palm OS what values are new 2019-08-30 11:38:37 -07:00
meepingsnesroms
12ed98e68b Doesnt get as far anymore but is more accurate 2019-08-27 17:54:32 -07:00
meepingsnesroms
e277ae8a3b More TSC2101 work 2019-08-27 11:45:10 -07:00
meepingsnesroms
80850117e6 Add more of TSC2101 2019-08-26 18:01:29 -07:00
meepingsnesroms
09ae1544e4 Fix missing define 2019-08-26 15:03:05 -07:00
meepingsnesroms
c4e9edf702 Make interrupts clearable(and persistant when not acknoledged) 2019-08-26 14:06:59 -07:00
meepingsnesroms
dbf1341597 Remove backlight value from SED1376 and make it a percentage for T3 2019-08-24 21:42:23 -07:00
meepingsnesroms
5af248eaef Partially implement TSC2101 buffer 2019-08-24 12:56:18 -07:00
meepingsnesroms
afa5b13d14 Fix another bug in TSC2101 making commands never again start after the first 2019-08-23 14:06:52 -07:00
meepingsnesroms
68c9e28c08 Implement more of the TSC2101 2019-08-22 13:50:57 -07:00
meepingsnesroms
7962bee8bf Terminate TSC2101 command when its finished 2019-08-20 17:02:51 -07:00
meepingsnesroms
e6535b546c Add chip select and reset lines for TSC2101 2019-08-20 11:45:45 -07:00
meepingsnesroms
696874b42a Merge pull request #93 from meepingsnesroms/master
Add new changes from master
2019-08-17 21:59:58 -07:00
meepingsnesroms
ab608e1d78 Merge pull request #92 from webgeek1234/master
libretro: allow mingw cross compile
2019-08-17 21:58:45 -07:00
Aaron Kling
7ccef9020c libretro: allow mingw cross compile 2019-08-17 18:36:54 -05:00
meepingsnesroms
65e12a2b7b Some I2C fixes 2019-08-15 17:20:47 -07:00
meepingsnesroms
7ab964efcb Attach IC memory accessors 2019-08-15 16:22:23 -07:00
meepingsnesroms
4129e74af0 Fix RetroArch port again
Overclocking should be working now for both ports.
2019-08-15 15:53:06 -07:00
meepingsnesroms
8dcf19d2e1 Add namespaces to vars and make chip define headers subfiles of there chips 2019-08-15 15:21:45 -07:00
meepingsnesroms
aa196cb87f Remove custom driver stuff, no longer needed 2019-08-15 15:12:36 -07:00
meepingsnesroms
136cdca5d7 Add more tsc2101 stuff 2019-08-15 13:40:34 -07:00
meepingsnesroms
d4b9997d43 Add TSC2101 protocol handler 2019-08-13 17:39:57 -07:00
meepingsnesroms
8de283a87d SSP finished 2019-08-13 10:16:27 -07:00
meepingsnesroms
c860faa9e7 Add more of SSR, fix some bugs 2019-08-12 21:53:06 -07:00
meepingsnesroms
0d87bf2610 Add most of SSP SPI port 2019-08-10 21:35:23 -07:00
meepingsnesroms
99da94a143 More SSP regs 2019-08-09 12:43:16 -07:00
meepingsnesroms
ca89c58c1a Add SSP files 2019-08-08 21:59:49 -07:00
meepingsnesroms
771856944b Finish PXA255 references, update uARM to latest 2019-08-08 18:48:56 -07:00
meepingsnesroms
814d180642 I2C should be working now 2019-08-02 18:29:46 -07:00
meepingsnesroms
ad53041077 Fake cycle counting seems to be working 2019-08-01 13:47:57 -07:00
meepingsnesroms
6bfae8fcb2 Try to implement basic CPU timing, untested 2019-07-31 15:47:42 -07:00
meepingsnesroms
9eb415c4ac More I2C work 2019-07-30 16:56:32 -07:00
meepingsnesroms
632a57a38f Implement basic PMU comunication
I2C registers for PXA260 arnet finished yet though so cant actually send anything
2019-07-30 15:44:21 -07:00
meepingsnesroms
430ebc01a0 Add I2C accessors 2019-07-30 11:32:57 -07:00
meepingsnesroms
cc882d2141 Add some I2C stuff 2019-07-30 11:08:48 -07:00
meepingsnesroms
5ad9760c52 Get RetroArch build compiling again 2019-07-30 10:06:37 -07:00
meepingsnesroms
d67233cc8e Add skeleton files for some T3 chips 2019-07-30 09:58:44 -07:00
meepingsnesroms
07d8ee95f1 Update changelog 2019-07-29 13:57:04 -07:00
meepingsnesroms
a6f3ec5c1f Use HMARK 2019-07-29 13:37:08 -07:00
meepingsnesroms
631111ce25 Add UART 2 stuff
Neither UART 1 or 2 is working yet.
2019-07-29 11:32:18 -07:00
meepingsnesroms
4237ae0eb8 Add T3 SD chip disable patch
Should make debugging easier for now, dont need an SD slot for a while anyway.
2019-07-22 16:40:06 -07:00
meepingsnesroms
07b4aa53a8 Clean up sandbox to prepare for adding ARMv5 tools to it 2019-07-22 15:00:20 -07:00
meepingsnesroms
81bbcd20f0 Allow setting OS version number to something other than 4/5 2019-07-22 12:14:00 -07:00
meepingsnesroms
58d59a9964 Add callbacks for reconfiguring the serial ports 2019-07-20 09:53:15 -07:00
meepingsnesroms
e601bf1e15 Some LCD fixes from Dmitry Grinberg 2019-07-16 20:42:22 -07:00
meepingsnesroms
369b2ebaf4 Fix spacing in readme 2019-07-13 22:15:18 -07:00
meepingsnesroms
bc47eee5c0 Git apperently forgot this file a while ago 2019-07-12 22:15:53 -07:00
meepingsnesroms
943dfb3b09 More UART stuff 2019-07-09 10:38:39 -07:00
meepingsnesroms
a23df8f79a Fix number 2019-07-08 19:58:06 -07:00
meepingsnesroms
e0c1cb9d6b Save state fixes for UARTs 2019-07-08 19:55:59 -07:00
meepingsnesroms
7b6fcdb0e1 Set up basic external communication functions
Just got rid of the CPU FIFOs for UART, each emulated device will have an infintly large receive buffer which is written to directly by the other emulated devics transmit, the oldest 12 or 64 bytes of that buffer will belong to the CPU, when the CPU reads a byte it gets deleted and if theres more bytes the CPU will be able to access the next.
Turning off the FIFO will flush the whole buffer because the CPU would have been unable to read those bytes since it was off.

Now I just need to set up UART2 and a USB to serial adapter and I can try to sync my modern laptop with Palm Desktop on a Windows XP computer.
2019-07-08 19:48:44 -07:00
meepingsnesroms
e70d84fac4 More UART stuff 2019-06-20 20:44:50 -07:00
meepingsnesroms
d67b44130a Minor cleanups, verify states are working on Windows
They work on Windows, dont know why the are broken on Mac?
2019-06-20 17:46:34 -07:00
meepingsnesroms
1567cbce67 Clean up global namespace, add basic UART1 for m515
Going to try and get it to not crash when beaming.
2019-06-20 17:40:18 -07:00
meepingsnesroms
3059dfda06 Delay some stuff 2019-06-20 13:47:11 -07:00
meepingsnesroms
94f4c09d54 Rename to PXA260, PXA255 is almost identical and that naming is misleading 2019-06-12 18:41:38 -07:00
meepingsnesroms
452d5030a1 Update ARM debug functions, allow QT port to compile without OS 5 support 2019-06-12 10:23:45 -07:00
meepingsnesroms
1bb71d8aec Postpone some stuff to next release 2019-06-09 12:00:44 -07:00
meepingsnesroms
0337882c4f Remove QPixmap and switch to QImage for rendering
Need to test if this fixes Android.
2019-06-09 10:52:11 -07:00
meepingsnesroms
33f7cb8948 Merge pull request #91 from meepingsnesroms/tungstenT3Support
Disable OpenMP on libretro for now
2019-06-08 20:44:20 -07:00
meepingsnesroms
51e405fc84 Disable OpenMP on libretro for now
Causing way too many issues for the benefit
2019-06-08 20:43:44 -07:00
meepingsnesroms
d0ccc7115f Merge pull request #90 from meepingsnesroms/tungstenT3Support
Input updates
2019-06-07 13:23:31 -07:00
meepingsnesroms
61602de392 Update mouse click button 2019-06-07 12:34:15 -07:00
meepingsnesroms
29ca09302f Make control layout relative to SNES controller 2019-06-06 16:57:07 -07:00
meepingsnesroms
4c8649da4e Add small ARM patch, update roadmap 2019-06-04 20:44:11 -07:00
meepingsnesroms
9723c83381 Update Makefile.common 2019-06-04 15:18:07 -07:00
meepingsnesroms
37f4b859aa Cleanups, implement FEATURE_SYNCED_RTC, allow disabling graffiti
Also patched RetroArch makefile again, this will enable ARM on more platforms, possibly causing more build issues when merged.
2019-06-02 22:12:49 -07:00
meepingsnesroms
7ba0cb5dca Jused checked, m515 screen refreshes almost instantly
Remove the ghosting stuff, if caused flickering too.
2019-06-01 16:35:55 -07:00
meepingsnesroms
c95792b146 Update ghosting 2019-06-01 16:31:54 -07:00
meepingsnesroms
c111be3f64 Add ghosting support, not finished yet 2019-06-01 16:23:46 -07:00
meepingsnesroms
b145a329c0 Merge pull request #88 from meepingsnesroms/master
Merge over button names
2019-05-30 17:59:20 -07:00
meepingsnesroms
0ca5627ee3 Fix buffer overflow 2019-05-30 17:57:41 -07:00
meepingsnesroms
a1fd0799be Merge pull request #84 from paradadf/button-names
Change button names
2019-05-30 17:39:30 -07:00
paradadf
4fb3bed984 Update libretro.c
Use names from manual
2019-05-30 17:21:31 -04:00
meepingsnesroms
9ed1d0c21d Commit some broken code so I can test it on my other comupter with asan 2019-05-30 10:42:19 -07:00
meepingsnesroms
1405e2a681 Attach the timer 2019-05-29 16:36:34 -07:00
meepingsnesroms
55013870ca Attach PwrClk module 2019-05-29 15:52:37 -07:00
meepingsnesroms
912210695d ARM: Add cp14, dosent do much yet 2019-05-28 19:50:55 -07:00
meepingsnesroms
5c89783ea0 Cleanups, fix armv7 dynarec issue 2019-05-28 15:18:25 -07:00
meepingsnesroms
c68fac77cc Merge pull request #83 from meepingsnesroms/tungstenT3Support
Clean up overcomplicated launcher operation
2019-05-27 15:42:00 -07:00
meepingsnesroms
d0ca2655bb Update roadmap.txt 2019-05-27 15:41:04 -07:00
meepingsnesroms
5c1547467b Completley redo how launcher works
RetroArch still works.
Also tested .img file with a separate .info file in RetroArch and it worked.
2019-05-27 15:20:42 -07:00
meepingsnesroms
8e9ef22f42 Fix another state path issue
Also disabled keyboard focus so mapping keys like space and enter dont do anything weird.
2019-05-26 22:58:51 -07:00
meepingsnesroms
892359f226 Fix state manager not loading state list when opened 2019-05-26 22:14:06 -07:00
meepingsnesroms
d46e146ae7 Prevent invalid paths and get custom state dirs working 2019-05-26 20:08:45 -07:00
meepingsnesroms
fc6b32d065 Merge pull request #82 from meepingsnesroms/tungstenT3Support
Fix MSVC again
2019-05-26 16:24:30 -07:00
meepingsnesroms
66f32cdb94 Fix MSVC stuff again 2019-05-26 16:22:47 -07:00
meepingsnesroms
3601c471cf Update roadmap.txt 2019-05-26 16:06:14 -07:00
meepingsnesroms
9384fc37a8 Crop whitespace from svgs
All button images are the around the same size now instead of some being tiny.
2019-05-26 15:59:28 -07:00
meepingsnesroms
02fe7809ff Update roadmap.txt 2019-05-26 14:40:16 -07:00
meepingsnesroms
5f3ace9b6b Update launcher now actualy launches the program instead of the homescreen 2019-05-26 14:31:44 -07:00
meepingsnesroms
967c2f3ec1 Pause emu while selecting new content and select files again now that files can be installed after boot 2019-05-26 12:11:52 -07:00
meepingsnesroms
99dfc62823 Merge pull request #81 from meepingsnesroms/tungstenT3Support
Fix 4 bugs
2019-05-26 10:00:09 -07:00
meepingsnesroms
f0b9d524a6 Fix 4 bugs
Prevent the standard case from overwriting EMU_SUPPORT_PALM_OS5 := 1 from the jni makefile.
Remove unsupported __builtin_expect(x, y) from MSVC compilers.
Use <*.h> headers instead of <c*> headers for C headers in C++11 for RetroArchs weird Mac OS toolchain.
Remove unused <mutex> header for RetroArchs weird Mac OS toolchain.
2019-05-26 09:59:03 -07:00
meepingsnesroms
80026cb33e Merge pull request #80 from meepingsnesroms/tungstenT3Support
Compile fix for Mac OS
2019-05-25 22:24:57 -07:00
meepingsnesroms
5f1e8a53c1 Compile fix for Mac OS 2019-05-25 22:23:41 -07:00
meepingsnesroms
b068d6ed53 Merge pull request #79 from meepingsnesroms/tungstenT3Support
Fix the fix
2019-05-25 14:31:40 -07:00
meepingsnesroms
b222b23bd0 Fix the fix 2019-05-25 14:31:09 -07:00
meepingsnesroms
7e0399ad17 Merge pull request #78 from meepingsnesroms/tungstenT3Support
More RetroArch fixes
2019-05-25 14:23:14 -07:00
meepingsnesroms
f355c82d0b Disable multithreading for simple loops(no function calls, < 1000 runs)
Try to fix silkscreen issue in a clean and fast way.
2019-05-25 14:21:41 -07:00
meepingsnesroms
535c9254f6 Some more fixes
<cstdint> for Mac OS and disabeing OS5 for msvc because of custom asm syntax.
2019-05-25 10:14:30 -07:00
meepingsnesroms
4476697b4b Merge pull request #76 from meepingsnesroms/tungstenT3Support
Tons of bugfixes
2019-05-25 09:59:45 -07:00
meepingsnesroms
92d6a857a8 Tons of bugfixes 2019-05-25 09:58:00 -07:00
meepingsnesroms
6e8005cf56 Merge pull request #74 from meepingsnesroms/tungstenT3Support
Add launcher to RetroArch port
2019-05-24 18:37:59 -07:00
meepingsnesroms
eb4a241ef4 Android is now compiling 2019-05-24 18:28:46 -07:00
meepingsnesroms
ec66577b53 Update Makefile.common 2019-05-24 16:03:21 -07:00
meepingsnesroms
41a305f0bd Just use real setjmp 2019-05-24 15:45:16 -07:00
meepingsnesroms
e9f7a40c53 Fix some segfaults and missing symbols
It runs now but pushing to master is going to be a mess.
2019-05-24 15:16:21 -07:00
meepingsnesroms
b1914d9586 More RetroArch port fixes 2019-05-24 14:33:56 -07:00
meepingsnesroms
a63000884f Fix some oopsies 2019-05-24 13:53:07 -07:00
meepingsnesroms
5a38b67708 More work on RetroArch port 2019-05-24 13:36:41 -07:00
meepingsnesroms
97e00aaef2 Launcher now successfuly skips touch calibration
More work on keeping OS 4 and 5 separate too.
2019-05-23 17:23:31 -07:00
meepingsnesroms
82c767a7a0 Update libretro.c 2019-05-23 15:44:51 -07:00
meepingsnesroms
ab4788c921 Major speed and launcher cleanups 2019-05-23 15:25:15 -07:00
meepingsnesroms
c4eec6864b Launcher now makes filesystem images but the OS wont execpt them 2019-05-22 18:06:18 -07:00
meepingsnesroms
9b09d19e19 Switch to Tungsten T3, widescreen is more important than a keyboard 2019-05-22 14:51:00 -07:00
meepingsnesroms
3de2c67cae Tested more, this dosent slow down games, there just slow when doing a lot of stuff 2019-05-19 16:10:53 -07:00
meepingsnesroms
1d693ae10d Fix some buggy stuff 2019-05-19 15:55:38 -07:00
meepingsnesroms
1b3336c9af Clean up file accesses in frontend, remove timing hack, seems to be working 2019-05-19 13:45:56 -07:00
meepingsnesroms
4d88e893e0 Launcher work
Gonna try and make the launcher as simple as possible, no zip files, the frontend can handle that if it wants.

Going to make the Qt port launch directorys instead of files too since the file dialog only allows selecting files or directorys and some apps have resource files.
2019-05-18 20:01:28 -07:00
meepingsnesroms
2238274f51 Put back self modifying code check 2019-05-17 21:58:45 -07:00
meepingsnesroms
5b93a54b2b Win64 support is now working, Win32 also works with dynarec disabled now 2019-05-17 21:50:29 -07:00
meepingsnesroms
c89da48739 Fix crashing with ARMv5 core 2019-05-17 21:46:23 -07:00
meepingsnesroms
b6093dc8ca Work on launcher
Also tryed to get x86 windows working without dynarec enabled
2019-05-17 21:18:31 -07:00
meepingsnesroms
48ba518086 Work on launcher 2019-05-16 12:02:13 -07:00
meepingsnesroms
372d23e534 Update launcher.h 2019-05-14 10:34:22 -07:00
meepingsnesroms
125e85d73b Got Mac RetroArch build working with ARM emulator
Hopefully dident break ARM emulator on Windows.
2019-05-13 12:38:42 -07:00
meepingsnesroms
d70e2b02b9 Remove unneeded file access functions from ARM emulator 2019-05-13 11:53:43 -07:00
meepingsnesroms
a2058e2d73 Remove buffer_t stuff from RetroArch port, fix path names 2019-05-13 09:32:33 -07:00
meepingsnesroms
c7f8816541 Can now compile without the dynarec enabled, removed buffer_t 2019-05-12 23:09:36 -07:00
meepingsnesroms
6c53ade08b Start file launcher stuff 2019-05-12 20:50:54 -07:00
meepingsnesroms
d8abf3643d Update flx68000.c 2019-05-12 11:32:56 -07:00
meepingsnesroms
a80b783c71 More SD card optimizations 2019-05-12 11:10:38 -07:00
meepingsnesroms
06acab1345 Try to speed up SD card accesses, theoreticly should be a 10<->16x speed up 2019-05-11 13:34:07 -07:00
meepingsnesroms
8482c98010 Cleanups, add some Tungsten C timer stuff 2019-05-03 14:33:54 -07:00
meepingsnesroms
3c645bd0bd Move stuff, set proper ARM CPU ID 2019-05-01 13:25:52 -07:00
meepingsnesroms
368757023c Cleanups, add PCMCIA slot stuff to ARM 2019-05-01 13:06:06 -07:00
meepingsnesroms
4d803c6fc0 Clean up emulator*State* functions 2019-05-01 11:06:39 -07:00
meepingsnesroms
cb9093c5f4 Add all the OS5 stuff to the RetroArch makefiles 2019-04-25 11:19:37 -07:00
meepingsnesroms
fa5f85e77c Fix addr_cache stuff, now executing
Also tried to fix compiling with dynarec off, dont know it works yet though.
2019-04-24 19:19:44 -07:00
meepingsnesroms
1b5f4d215f Update Mu.pro 2019-04-24 17:15:28 -07:00
meepingsnesroms
55a2e97bc5 Clean ups
The dynarec is using the segmentation fault handler as a speed up, so debugging will be really hard.
2019-04-24 16:55:31 -07:00
meepingsnesroms
0a58122f4b Remove fixed SD card IDs, should help make Palm game carts work 2019-04-24 12:18:43 -07:00
meepingsnesroms
5a7191cd47 Fix ASM clang conflict
Add circle ci stuff, need to actually set it up though
2019-04-24 11:18:48 -07:00
meepingsnesroms
cee653b1a0 Remove block alignment requirement for SD card accesses
Also fix bug where a multiple block write could write to anywhere in host RAM
2019-04-24 11:10:10 -07:00
meepingsnesroms
0bf5f9f981 Fix 2 SEGFAULTs 2019-04-21 21:55:46 -07:00
meepingsnesroms
23f943ce8b Prepare for a test run 2019-04-21 21:39:16 -07:00
meepingsnesroms
9e98f29215 Attach IC part 2019-04-21 21:31:11 -07:00
meepingsnesroms
ee7fd8e676 Clean up and attach LCD stuff 2019-04-21 21:05:01 -07:00
meepingsnesroms
34e4b9ce7c Remove more calculator stuff from the dynarec
Increase MEM_SIZE define, start making module wrapper for the PXA255.
2019-04-21 19:05:48 -07:00
meepingsnesroms
4e7a08e6df Snowy plover 2019-04-21 14:49:35 -07:00
meepingsnesroms
ae6efb6b7b Now compiling with PXA255 code
Still only Windows x86_32.
2019-04-21 13:20:13 -07:00
meepingsnesroms
f1d1c3f051 Rename more Dragonball exclusive stuff
Dynarec is compiling on Windows x86_32, still not attached though.
2019-04-21 12:24:55 -07:00
meepingsnesroms
03101a5214 Almost seems to be compiling 2019-04-19 20:52:43 -07:00
meepingsnesroms
f4a6d6c1b0 Add dynarec stuff
This broke compiling for now.
2019-04-19 18:16:11 -07:00
meepingsnesroms
bb2698b498 Put more vars under the "dbvz" module 2019-04-19 11:21:11 -07:00
meepingsnesroms
48ff83d3af Merge pull request #72 from meepingsnesroms/removeOldArmCpu
Remove old arm cpu
2019-04-19 11:02:02 -07:00
meepingsnesroms
48d3983b72 Remove more old stuff 2019-04-19 10:59:32 -07:00
meepingsnesroms
f7f7b9d2d9 Remove ARM stuff from muExpDriver
Still keeping the driver around for potential speed hacks and overclock config.
2019-04-19 10:50:24 -07:00
meepingsnesroms
2244a1edd8 Cleanups prepare to add Tungsten C stuff 2019-04-19 10:38:35 -07:00
meepingsnesroms
f7c1dacba4 Start tunring m515 and dragonball stuff into modules
Prepareing for tungsten c support.
2019-04-19 09:35:14 -07:00
meepingsnesroms
47ba41fdc5 Clean up ARM references 2019-04-17 13:11:04 -07:00
meepingsnesroms
6df973a77c Remove ARM stuff from core 2019-04-17 13:03:38 -07:00
meepingsnesroms
180a8ba97f Add new feature bits to RetroArch port, update chunk info print format 2019-04-15 13:10:32 -07:00
meepingsnesroms
84c0c40f36 Set up FEATURE_DURABLE in GUI, fix settings icon not scaling 2019-04-15 13:00:50 -07:00
meepingsnesroms
8eae0b1ddd Update unimplementedHardware.txt 2019-04-15 12:00:54 -07:00
meepingsnesroms
efc3b9ca77 Fix consistncy of REG_PPC, it is now always the start address of the last opcode executed
Before there was an inconsistancy where it would be set to the current opcode when exiting the loop, that causes weird side effects and is completely unneeded since it will just be set the next time the loop starts anyway.
2019-04-14 22:36:20 -07:00
meepingsnesroms
4c27b1abb1 Print chunk misalignment details on fail 2019-04-14 21:05:52 -07:00
meepingsnesroms
e1a9162cc9 Locate another potential alignment check 2019-04-11 15:15:28 -07:00
meepingsnesroms
71af4b89a5 Update sandbox.c 2019-04-11 13:01:17 -07:00
meepingsnesroms
65db73b129 Patch another memory function to 32 bit alignment 2019-04-11 12:33:58 -07:00
meepingsnesroms
2270e8f112 List other functions that may need to be patched 2019-04-11 11:41:44 -07:00
meepingsnesroms
1b538a0bfe Some ASM updates 2019-04-11 11:38:08 -07:00
meepingsnesroms
8cd5dcb446 Locate another memory alignment check 2019-04-11 11:04:40 -07:00
meepingsnesroms
1ec53c904a Memory alignment tests are working
Shuffling memory is causing misalignment but allocation seems to always be 32 bit aligned now.
2019-04-11 10:51:11 -07:00
meepingsnesroms
f2233197e4 Add sandbox frame callback, make memory alignment test 2019-04-11 09:51:26 -07:00
meepingsnesroms
432233d8f1 It kinda works still 2019-04-09 11:07:03 -07:00
meepingsnesroms
07af2b45ec Fix MemChunkNew patches again 2019-04-09 00:28:19 -07:00
meepingsnesroms
d3540e3f77 Fix OS patch 2019-04-08 22:53:21 -07:00
meepingsnesroms
6c144a3e85 Add OS patch 2019-04-08 22:25:41 -07:00
meepingsnesroms
f166dd173b Add alignment info 2019-04-08 22:04:44 -07:00
meepingsnesroms
f11fdcdf18 ARM actually ran so I will just commit this
There is still severe issues with 32 bit alignment.
2019-04-08 21:28:15 -07:00
meepingsnesroms
1b407a4497 Make new patch for unaligned access since disabling it completely broke things 2019-04-08 18:53:50 -07:00
meepingsnesroms
81f0521165 Revert "Attempt to block 32 bit alignment requirement"
This reverts commit 79af40b61f.
2019-04-08 18:11:41 -07:00
meepingsnesroms
79af40b61f Attempt to block 32 bit alignment requirement
This didnt work so it will be reverted right after this commit.
2019-04-08 18:11:27 -07:00
meepingsnesroms
182a188cda More debug tools and tests, seems 32 bit alignment is still messing with ARM execution 2019-04-08 17:43:18 -07:00
meepingsnesroms
d34b0a0694 Fix invalid jump instruction 2019-04-08 15:01:43 -07:00
meepingsnesroms
a40b29dca4 Merge pull request #70 from meepingsnesroms/master
Copy fixes from master to armCpu
2019-04-07 11:50:43 -05:00
meepingsnesroms
e6262335d9 Incomplete, just syncing so I can install the repo on another computer 2019-04-07 09:34:05 -07:00
meepingsnesroms
c6174d335b Fix non PIC 68k assembly code, add support for MinGW 2019-04-07 09:30:20 -07:00
meepingsnesroms
c9138ec32a Put back old debug stuff that forwards MemPtrNew call
This debug version was not in a git commit, but the new one doesnt trigger.
2019-04-05 18:48:11 -07:00
meepingsnesroms
15d7d2dd54 Some ARM fixes 2019-04-05 11:33:38 -07:00
meepingsnesroms
424d07ce60 Add LED support, fix function not returning value 2019-04-05 07:25:04 -07:00
meepingsnesroms
857b4bbed3 Fixed buffer overflow of trap table 2019-04-04 21:49:30 -07:00
meepingsnesroms
90ed900001 Update libretro port, LED still dosent work 2019-04-04 18:41:29 -07:00
meepingsnesroms
20400675fa Expose memory watch API to MuExpDriver 2019-04-02 21:02:23 -07:00
meepingsnesroms
850064d498 Add basic ARMv5 support to sandbox, finish sandbox save and load state 2019-04-02 17:21:58 -07:00
meepingsnesroms
089090486c More cleanups
Almost have a decent debugger now
2019-04-02 14:24:32 -07:00
meepingsnesroms
dc200683e2 Move more logging stuff to sandbox
Register logging still isnt working though
2019-04-02 13:51:37 -07:00
meepingsnesroms
33002e9fb3 Cleanups, try and make sandbox C89 compliant 2019-04-02 12:35:20 -07:00
meepingsnesroms
992e1cda84 Begin adding ability to monitor app behavior with sandbox 2019-04-02 12:03:21 -07:00
meepingsnesroms
6ca82f22cc Add missing semicannoli 2019-03-31 12:39:57 -07:00
meepingsnesroms
bdb445fb72 Fixed debug stack reading 2019-03-31 12:24:28 -07:00
meepingsnesroms
806c95b20b Allow clearing key binds without assigning new ones 2019-03-30 11:40:12 -07:00
meepingsnesroms
6b488b8817 Add armv5Cpu struct to savestate, remove blobs again now that the 32 bit alignment requirement is gone
Also disabled more icache stuff since it had alignment restrictions and wasnt used anyway.
2019-03-29 17:19:03 -07:00
meepingsnesroms
e579e67b19 Clean up ARMv5 code 2019-03-29 13:22:02 -07:00
meepingsnesroms
d31862b435 Merge pull request #69 from meepingsnesroms/armCpu
Merge over important Qt updates
2019-03-27 11:45:18 -07:00
meepingsnesroms
ea8a4fd618 Update readme.md 2019-03-27 09:39:36 -07:00
meepingsnesroms
68d45bb396 Allow setting feature bits through GUI 2019-03-26 17:15:51 -07:00
meepingsnesroms
6b81ca4cc0 Keyboard support for Qt GUI
Theres now a settings panel too.
2019-03-26 11:51:02 -07:00
meepingsnesroms
9b39360288 Start adding a settings window and allow disableing onscreen buttons 2019-03-25 21:38:01 -07:00
meepingsnesroms
111220a17f Remove old print audio buffer code, disable opcode prefetch to keep compatibility 2019-03-25 14:30:14 -07:00
meepingsnesroms
f6bee9c9cf Separate the creator IDs of MuExpDriver and TstSuite
Apperently for applications the creator is a 4 char application name not actually the creator, otherwise the apps will be considered the same app.
2019-03-14 11:21:04 -07:00
meepingsnesroms
5f5ea20c66 Clean up MuExpDriver GUI
Decided not to let the user set the OS version, that will only cause more issues I will have to deal with down the line.
2019-03-13 12:32:11 -07:00
meepingsnesroms
60389c9a0e Add functions to operate on the trap dispatchers stack frame
Only really useful for 1 function, emuSysUnimplemented, will tell me what and where unimplemented API calls are coming from.

This takes advantage of the trap dispatcher being clueless as to the signature of the function its calling, if I just make the stack frame bigger then the real one it will capture some of the previous functions stack going backwards.

Havent verifyed the output of this yet though.
2019-03-12 15:31:41 -07:00
meepingsnesroms
df49ff3a4c Update MuExpDriver, doesnt do anything new though 2019-03-11 20:03:55 -07:00
meepingsnesroms
017797509e Now reads current CPU speed when opening the GUI 2019-03-08 12:23:41 -08:00
meepingsnesroms
96919e3458 More fixes 2019-03-08 11:55:12 -08:00
meepingsnesroms
968cafda58 Update MuExpDriver GUI, still needs work though 2019-03-08 10:51:05 -08:00
meepingsnesroms
1b1346fa7e Add safe mode flag, Chuzzle still doesnt work 2019-03-07 16:57:38 -08:00
meepingsnesroms
eb159b1e02 Increase accuracy of SD card resets 2019-03-07 12:44:34 -08:00
meepingsnesroms
a1ee77c9a5 Cleanups, disable ARMv5 icache
For some reason the new versions of MuExpDriver dont work with Chuzzle anymore.
2019-03-06 12:35:27 -08:00
meepingsnesroms
7f5c14baee Clean up ARM loader a bit
Gonna try to disable ARM alignment requirements next.
2019-03-06 11:41:21 -08:00
meepingsnesroms
89f50f88c5 Make sandboxOnMemoryAccess recursion safe, allow printing function name where error occurred 2019-03-03 20:31:55 -08:00
meepingsnesroms
419b18f170 Check LCD params on set not render, allow capturing memory accesses 2019-03-03 11:37:46 -08:00
meepingsnesroms
930e4f314c Fix reset button crashing when pressed before the emu is started 2019-03-03 10:49:14 -08:00
meepingsnesroms
89e193a091 Add reset button to Qt, optimize all the svgs 2019-03-02 11:14:08 -08:00
meepingsnesroms
fa98647959 Fix invalid writes to storage area
Also starting to render hires stuff, but crashes on BltChars
2019-03-01 21:04:01 -08:00
meepingsnesroms
11c392f8b6 Start implementing fake HwrDisplayAttributes 2019-03-01 14:06:58 -08:00
meepingsnesroms
dd8e8d2141 Add CSB1 memory mapping even though it has no chip, needed for accurate error handling
Cull some old fixed issues from the bug list.
2019-03-01 10:49:26 -08:00
meepingsnesroms
c5a094620a Add debug tags in Tungsten W driver install function 2019-02-28 13:05:43 -08:00
meepingsnesroms
53b5ea1e6b Ignore Tungsten W GPU driver, just want the new graphics API, not hardware drivers 2019-02-28 11:06:45 -08:00
meepingsnesroms
e3dbfaf369 Update muExpDriver 2019-02-28 10:19:19 -08:00
meepingsnesroms
d936c13205 320x320 stuff 2019-02-26 17:15:22 -08:00
meepingsnesroms
8d19f91487 Start working on hires mode 2019-02-26 14:13:16 -08:00
meepingsnesroms
f0d2b992da Remove duplicate reset code 2019-02-26 10:29:55 -08:00
meepingsnesroms
afa7462733 Merge pull request #68 from meepingsnesroms/armCpu
Fix 3 possible SD card corruption bugs
2019-02-26 10:19:59 -08:00
meepingsnesroms
e034878ee0 Fix 3 possible SD card corruption bugs
0 out SD card struct on load, should prevent a non zero pointer size from getting through and fixed the mask to include the 2, 4 and 8mb size bits, and put parentheses around the size mask to & before +.
2019-02-26 10:19:18 -08:00
meepingsnesroms
b637a6495f Merge pull request #67 from meepingsnesroms/armCpu
Fixes
2019-02-25 15:35:48 -08:00
meepingsnesroms
97cd9bc543 Can now get SD cards size properly on format, reduce offsets from 64 to 32 bit
If theres a > 4gb savestate, thats the problem, not the address bits in the offset.
2019-02-25 15:32:35 -08:00
meepingsnesroms
7660f2e64b Move CRC tables out of main file, start switch away from fixed CSD, having it breaks formating cards that arnt 1gb 2019-02-25 14:03:54 -08:00
meepingsnesroms
cd3acf4c98 Merge pull request #66 from meepingsnesroms/armCpu
Mu v1.0.0
2019-02-25 10:32:51 -08:00
meepingsnesroms
338aa7ed4e Enable SD access on RetroArch port 2019-02-25 10:27:58 -08:00
meepingsnesroms
d43d9c637f v1.0.0 prep 2019-02-25 09:18:01 -08:00
meepingsnesroms
a51a549ecd Remove USB hack 2019-02-25 08:45:11 -08:00
meepingsnesroms
7c0a2b0dde Write works add new SD card vars to save states 2019-02-25 06:46:48 -08:00
meepingsnesroms
1543c35f49 Writing now works with hack, dont know what causes the desync
Just need to remove this hack and the NOP patch applied to the serial/USB print routine and then I will be ready for another release
2019-02-24 23:15:18 -08:00
meepingsnesroms
0710c2cf26 May have an idea of what is wrong with SD writes
Also add a common sense limit of 2gb to the SD card insert routine.
2019-02-24 21:54:36 -08:00
meepingsnesroms
31fbd559f5 Still gives error on write but seems to actually write the data, at least the first block
Dont know what is wrong yet.
2019-02-24 16:57:03 -08:00
meepingsnesroms
57c24f55d6 SD card write is starting to work 2019-02-24 14:52:16 -08:00
meepingsnesroms
0290174a7e SD card now reads properly 2019-02-24 13:15:00 -08:00
meepingsnesroms
5cc6f229c1 Will attempt to format the card now, but will fail because writes arnt implemented 2019-02-24 11:40:23 -08:00
meepingsnesroms
ff04a096b9 Actually send the data instead of sending the token 512 times
SD card now displays properly at least, data transfer is still broken.
2019-02-24 11:25:28 -08:00
meepingsnesroms
fb9bd5243d Try to get SD card multiblock read working, its still not though 2019-02-23 14:56:07 -08:00
meepingsnesroms
915e7d3247 Almost have single block read working on SD card 2019-02-23 13:25:27 -08:00
meepingsnesroms
42852dc331 Add large FIFO for SD card responses, can now read the OCR, CSD and CID 2019-02-23 11:17:30 -08:00
meepingsnesroms
1662655786 Now initializes SD card, but gives up after reading OCR 2019-02-22 13:35:41 -08:00
meepingsnesroms
3f0e0baca0 Almost able to fully initialize SD card 2019-02-22 13:11:53 -08:00
meepingsnesroms
d802e93681 Add SD card response bits 2019-02-22 12:08:01 -08:00
meepingsnesroms
142b8152d8 More SD card stuff 2019-02-22 11:36:40 -08:00
meepingsnesroms
8dbc416bfd SD card init step 1 now works, needed to unset the XCH bit 2019-02-22 09:57:08 -08:00
meepingsnesroms
0cdf24711b More SD card stuff 2019-02-21 13:26:55 -08:00
meepingsnesroms
3cb346bbbb Remove old feature bits 2019-02-21 11:41:47 -08:00
meepingsnesroms
a57d45862e Use lowercase paths like pilrc 2019-02-21 11:03:31 -08:00
meepingsnesroms
c7dc657de5 Fix 2 bitmap converter bugs, all the icons work now 2019-02-21 10:22:52 -08:00
meepingsnesroms
a1dba7bb9f Move expansion hardware stuff 2019-02-20 12:43:31 -08:00
meepingsnesroms
d39eb886f1 Add remaining standard accessors for SED1376 2019-01-24 12:41:58 -08:00
meepingsnesroms
afb43ff3eb Change how ARM stack is set, add memalign functions
Need to patch the Palm OS malloc function to always allocate 32 bit aligned too.
2019-01-23 14:28:11 -08:00
meepingsnesroms
7c585bd242 Add simple accessors for SED1376 timing registers 2019-01-21 20:54:21 -08:00
meepingsnesroms
d305fe4dfc Update muExpDriver add a GUI(its still nonfunctional though) 2019-01-21 19:25:09 -08:00
meepingsnesroms
fac89d59bb Merge pull request #56 from meepingsnesroms/armCpu
Arm cpu
2019-01-20 22:29:42 +00:00
meepingsnesroms
f9229590f5 Add CPU speed to muExpDriver 2019-01-20 14:26:51 -08:00
meepingsnesroms
64ec6f6e91 Allow the emulator to set its own speed, prep for Chuzzle
This is far cleaner than a normal overclock, its always 100% on boot to allow normal init and custom speeds can be set per app, this was not doable with just FEATURE_FAST_CPU doubling the clock speed.
2019-01-20 10:08:00 -08:00
meepingsnesroms
133484b0dc Put memory saving back to normal
First OS 5 game is running, its not ARM though.
2019-01-19 09:41:06 -08:00
meepingsnesroms
7b39db4782 Update memory comments, add value to ARMv5 save state 2019-01-17 19:33:01 -08:00
meepingsnesroms
8a990b2839 Increase ADS7846 accuracy, implement PLLFSR 8 bit reads, enable logging on all unemulated regiser accesses 2019-01-17 13:45:11 -08:00
meepingsnesroms
4f96b53bb1 Make return/break syntax match for all memory accessors 2019-01-16 19:40:09 -08:00
meepingsnesroms
6ba1e42926 Match switch/return style, THE LAST COMMIT AND THIS HAVE BROKEN RAM ACCESS
Running experiments on larger RAM sizes, normal RAM access is broken right now.
2019-01-16 14:37:18 -08:00
meepingsnesroms
424a0cb5a5 Too much stuff to list 2019-01-16 14:21:38 -08:00
meepingsnesroms
8304eb33f9 More driver work 2019-01-11 15:54:34 -08:00
meepingsnesroms
0b645f8d7e Fix invalid SDK patch, try to add basic GUI 2019-01-10 10:16:19 -08:00
meepingsnesroms
f02bba3755 Start work on GUI 2019-01-10 09:05:45 -08:00
meepingsnesroms
1282d1b2b7 Put all the *.func blobs back, everything compiles
Presumably ARM should run now as is if there isnt any more unforseen circumstances.
2019-01-10 08:53:56 -08:00
meepingsnesroms
23b5fc6456 In emulation there is no right or wrong, only success or failure
The ARM blobs are back, they were checked with online dissasembler, no more low level ARM C compiling, its too much work.
2019-01-09 20:59:02 -08:00
meepingsnesroms
60b14cf79b This was a horrible experince, prc-tools is shit
There is no way to reliably write to a register in C, volatile is broken, optimizations cant be disabled, and the standalone code resource macros only work in C, so getting the correct register state for hypercall is impossible without making binary blobs at least for ARM, the 68k blob function seems OK to optimize since it isnt interrupted.
2019-01-09 19:47:14 -08:00
meepingsnesroms
def07b53d0 Ok, ARM blobs seem to be compiling 2019-01-09 11:47:17 -08:00
meepingsnesroms
e885942603 Remembered the register keyword, can just do the stack stuff in C with no vars on stack 2019-01-09 10:49:18 -08:00
meepingsnesroms
bf2163b21d This function seems to be done, now comes ARM asm 2019-01-09 09:29:28 -08:00
meepingsnesroms
02033457de Try to match Palm OS call format exactly
Not tested yet
2019-01-09 08:19:35 -08:00
meepingsnesroms
7e17a5a3e8 Add asm stuff 2019-01-08 21:34:33 -08:00
meepingsnesroms
5d4df87b7c Implement the ASM functions in psudocode
Have to manually compile it bit by bit then endian swap the ARM opcodes
2019-01-08 19:12:53 -08:00
meepingsnesroms
d16f495f1c Write C part of PceNativeCall handler 2019-01-08 16:16:54 -08:00
meepingsnesroms
7581114be6 Allow setting device IDs to match the screen and CPU type 2019-01-08 12:19:16 -08:00
meepingsnesroms
84d96c29d7 Early commit, unfinished
I am going to be pushing unfinished commits more now becuse my dev laptop is on the decline and I dont want to lose progress.
2019-01-08 11:19:11 -08:00
meepingsnesroms
fa7194f1f5 Commit finished, custom IO is working 2019-01-07 20:03:11 -08:00
meepingsnesroms
fad58ee6f3 Unfinished, computer is acting physically broken
May not work anymore after reboot so Ill just commit now.
2019-01-07 16:53:55 -08:00
meepingsnesroms
32f440a26d Correct code style a bit 2019-01-04 15:02:22 -08:00
meepingsnesroms
6d2466cf3b muExpansionDriver now compiles!!! 2019-01-04 13:29:36 -08:00
meepingsnesroms
e4625f1233 Try to get muExpansionDriver compiling, still not compiling though 2019-01-04 12:56:16 -08:00
meepingsnesroms
512dd785f6 Work on OS side driver, use (void) instead of () in Palm tools 2019-01-04 12:02:38 -08:00
meepingsnesroms
e1ef2fe5a1 ARM now seems to be fully attached, also hooked up more emu commands(Ill need them later anyway)
Just need to write the driver and get save states working for ARM.
2019-01-04 11:06:50 -08:00
meepingsnesroms
7238544735 Add more ARM stuff 2019-01-03 14:00:34 -08:00
meepingsnesroms
b3c2d4c09b Start emu side driver, ...
Label 64 bit constants to prevent them form being truncated, remove EMU_CMD_KEY, nothing is going to make arbitrary writes to the space I am using.
2019-01-02 17:13:01 -08:00
meepingsnesroms
2d1fcbdfb9 Attach more hardware registers 2019-01-01 14:01:00 -08:00
meepingsnesroms
bf65ad9b38 ARM stuff step 1
Dont know how many steps this will take, its very complicated :)
2019-01-01 12:13:59 -08:00
meepingsnesroms
b39797da21 Merge pull request #55 from meepingsnesroms/devel
Devel
2018-12-31 19:20:39 +00:00
meepingsnesroms
8b008aa575 Clean up flx68000PcLongJump remove more safety checks from release builds 2018-12-31 11:19:13 -08:00
meepingsnesroms
20f1e8b2ed Remove old function 2018-12-31 09:46:40 -08:00
meepingsnesroms
1ce59ac0f6 Merge pull request #54 from meepingsnesroms/devel
Update code for fast local memory access
2018-12-31 17:13:33 +00:00
meepingsnesroms
9761b9baca Update code for fast local memory access 2018-12-31 09:03:36 -08:00
meepingsnesroms
cdc74a654e Merge pull request #53 from meepingsnesroms/devel
Redo all the CPU stuff again
2018-12-30 01:49:09 +00:00
meepingsnesroms
4144f7c8b6 Prevent unaligned 32 bit accesses 2018-12-29 17:46:11 -08:00
meepingsnesroms
a9fbe45d52 Try to move cyclone speedups to musashi since cyclone is gone 2018-12-29 14:05:20 -08:00
meepingsnesroms
6829ed6f81 Finish removing cyclone 2018-12-29 12:05:48 -08:00
meepingsnesroms
f34256ba69 No more cyclone 2018-12-29 11:40:04 -08:00
meepingsnesroms
97397d49ee Merge pull request #52 from meepingsnesroms/devel
Disable cyclone again
2018-12-29 00:58:40 +00:00
meepingsnesroms
abb2e6526b Disable cyclone again
As of now its not stable and there isnt plans to reenable it unless someone else can figure out what is wrong since I dont know ARM ASM.
2018-12-28 16:57:58 -08:00
meepingsnesroms
adbd803dc9 Merge pull request #51 from meepingsnesroms/devel
Devel
2018-12-28 04:33:13 +00:00
meepingsnesroms
d96c0ec8c4 Fix typo 2018-12-27 20:19:03 -08:00
meepingsnesroms
6c37868055 Add extra bits to savestate
Need too move the SD card varibles into sdCard.c and add *prepareLoadState() and *finishedLoadState() for modules that need memory buffers like the SD card.
2018-12-27 19:59:43 -08:00
meepingsnesroms
b02fa8ba52 More SD card fixes 2018-12-27 17:50:02 -08:00
meepingsnesroms
94b0baaf7f Update .txt files, fix writes to IMR blocking vaild interrupts instead of invalid ones
Figure out SD card chip select.
Port D now seems to be fully datasheet compliant, interrupt quirks and all.
Add new bits to SD card.
2018-12-27 17:25:02 -08:00
meepingsnesroms
f8baa0eb85 See description below
Fix FIFO incaauracys.
Remove extra left shift on SPI1 data after the final bit is in.
Remove old image when last state is deleted.
Set active state to the newest one on save state and update image accordingly.
Set spi1RxOverflowed to false on boot.
Move variables to top of function in mainwindow constructor.
2018-12-27 14:56:01 -08:00
meepingsnesroms
538fd36c08 Allow any custom fb size part 2 2018-12-27 10:15:44 -08:00
meepingsnesroms
335997f19c Allow any custom fb size part 1 2018-12-27 09:24:22 -08:00
383 changed files with 85639 additions and 429031 deletions

27
.gitignore vendored
View File

@@ -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
View 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
View File

2
.idea/Mu.iml generated Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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:

View File

@@ -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
View 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)

View File

@@ -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

View File

@@ -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
View 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.

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -0,0 +1,4 @@
Whenever I register ShadowThief, this happens:
It happens on any version of Mu
PHEM/ST is fine

View File

@@ -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])

View File

@@ -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

View File

@@ -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);

View File

@@ -0,0 +1,6 @@
#ifndef H_ARMSNIPPETS
#define H_ARMSNIPPETS
#define armloader_cb()
#endif

50
include/armv5te/asmcode.h Normal file
View 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

View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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

View 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

View 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

View 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

View 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
View 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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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
View 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

View 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
View 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
View 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
View 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

View File

@@ -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 */

View File

@@ -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

File diff suppressed because it is too large Load Diff

View 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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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
View 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
View 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

View 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);
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -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
View 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*/;
}

View 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

View 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
};

View File

@@ -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

View 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;
}
}
}

View 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

View File

@@ -4,6 +4,5 @@
#include <stdint.h>
extern const uint16_t silkscreen160x60[];
extern const uint16_t silkscreen320x120[];
#endif

14
include/tps65010.h Normal file
View 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
View 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
View 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
View 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

View 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()

View File

@@ -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)$@ $<

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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