196 Commits

Author SHA1 Message Date
meepingsnesroms
df927c1e45 Attempt to upgrade Musashi 2019-11-11 11:03:08 -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
288 changed files with 57689 additions and 41847 deletions

15
.circleci/config.yml Normal file
View File

@@ -0,0 +1,15 @@
# Use the latest 2.1 version of CircleCI pipeline processing engine, see https://circleci.com/docs/2.0/configuration-reference/
version: 2.1
# Use a package of configuration called an orb, see https://circleci.com/docs/2.0/orb-intro/
orbs:
# Declare a dependency on the welcome-orb
welcome: circleci/welcome-orb@0.3.1
# Orchestrate or schedule a set of jobs, see https://circleci.com/docs/2.0/workflows/
workflows:
# Name the workflow "Welcome"
Welcome:
# Run the welcome/run job in its own container
jobs:
- welcome/run

10
.gitignore vendored
View File

@@ -3,7 +3,7 @@
*.dll
*.so
*.dylib
*.pro.user
*.pro.user*
*_emscripten.bc
/libretroBuildSystem/obj
/libretroBuildSystem/libs
@@ -11,16 +11,10 @@
/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/palm/muExpansionDriver/devStuff/*
/tools/palm/muExpansionDriver/*.bin
/tools/palm/muExpansionDriver/*.grc
/tools/palm/muExpansionDriver/*.prc
/tools/palm/muExpansionDriver/muExpDriver
/tools/palm/muExpansionDriver/blobs/*.S68
/tools/palm/muExpansionDriver/blobs/*.L68
/tools/desktop/build-BufferGraphViewer-*
/tools/desktop/build-MakePalmBitmap-*
/tools/desktop/export16BitImageProperly/convert

View File

@@ -1,453 +0,0 @@
Cant draw screen, LCD on:false, PLL on:true, power save on:false, forced blank on:false(printed 4 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
Cant draw screen, LCD on:false, PLL on:true, power save on:false, forced blank on:false(printed 2 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CMD_PRINT: muExpDriver:OS booting! (printed 1 times)
CMD_PRINT: muExpDriver:RAM size:255232 bytes (printed 1 times)
CMD_PRINT: muExpDriver:RAM free:224284, RAM biggest block:224074 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage size:16514802 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage free:15796336 bytes, Storage biggest block:15769916 bytes (printed 1 times)
CMD_PRINT: muExpDriver:New trap table created at:0x0003A39C (printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
CMD_PRINT: muExpDriver:Attempting to load GUI. (printed 1 times)
CMD_PRINT: muExpDriver:Attempting reboot! (printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
Sandbox: Command 1 started(printed 1 times)
m68k jumped 0xEFF7B2D6 bytes to invalid address, from 0x10084D0A to 0xFFFFFFE0(printed 1 times)
m68k jumped 0x00000000 bytes to invalid address, from 0xFFFFFFE4 to 0xFFFFFFE4(printed 1 times)
m68k jumped 0x0000000E bytes to invalid address, from 0xFFFFFFEE to 0xFFFFFFE0(printed 1 times)
m68k jumped 0x00000000 bytes to invalid address, from 0xFFFFFFE4 to 0xFFFFFFE4(printed 1 times)
m68k jumped 0x0000000E bytes to invalid address, from 0xFFFFFFEE to 0xFFFFFFE0(printed 1 times)
m68k jumped 0x00000000 bytes to invalid address, from 0xFFFFFFE4 to 0xFFFFFFE4(printed 1 times)
Sandbox: Command 1 finished(printed 1 times)
CMD_PRINT: muExpDriver:No config file, setting default config. (printed 1 times)
CMD_PRINT: muExpDriver:Attempting to load GUI. (printed 1 times)
CMD_PRINT: muExpDriver:Attempting reboot! (printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CMD_PRINT: muExpDriver:OS booting! (printed 1 times)
CMD_PRINT: muExpDriver:RAM size:255232 bytes (printed 1 times)
CMD_PRINT: muExpDriver:RAM free:224284, RAM biggest block:224074 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage size:16514802 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage free:15796364 bytes, Storage biggest block:15769940 bytes (printed 1 times)
CMD_PRINT: muExpDriver:New trap table created at:0x0003A39C (printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
CMD_PRINT: muExpDriver:Called ARM function:0x000D4CA2 (printed 1 times)
Bus error timeout at:0xAA22CD58, PC:0x000EC522(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CMD_PRINT: muExpDriver:OS booting! (printed 1 times)
CMD_PRINT: muExpDriver:RAM size:255232 bytes (printed 1 times)
CMD_PRINT: muExpDriver:RAM free:224284, RAM biggest block:224074 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage size:16514802 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage free:15796364 bytes, Storage biggest block:15769940 bytes (printed 1 times)
CMD_PRINT: muExpDriver:New trap table created at:0x0003A39C (printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
CMD_PRINT: muExpDriver:Called ARM function:0x000D4CA2 (printed 1 times)
Bus error timeout at:0xAA22CD58, PC:0x000EC522(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CMD_PRINT: muExpDriver:OS booting! (printed 1 times)
CMD_PRINT: muExpDriver:RAM size:255232 bytes (printed 1 times)
CMD_PRINT: muExpDriver:RAM free:224284, RAM biggest block:224074 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage size:16514802 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage free:15796364 bytes, Storage biggest block:15769940 bytes (printed 1 times)
CMD_PRINT: muExpDriver:New trap table created at:0x0003A39C (printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
CMD_PRINT: muExpDriver:Called ARM function:0x000D4CA2 (printed 1 times)
Bus error timeout at:0xAA22CD58, PC:0x000EC522(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0xFB(printed 1 times)
USB command 0xFB, write not handeled(printed 1 times)
USB unknown command, value:0x00(printed 1 times)
USB command 0x00, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x02(printed 1 times)
USB command 0x02, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0x04(printed 1 times)
USB command 0x04, read not handeled(printed 1 times)
USB unknown command, value:0xF2(printed 1 times)
USB unknown command, value:0xF3(printed 1 times)
USB command 0xF3, write not handeled(printed 2 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, write not handeled(printed 1 times)
USB unknown command, value:0x40(printed 1 times)
USB command 0x40, read not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, write not handeled(printed 1 times)
USB unknown command, value:0x41(printed 1 times)
USB command 0x41, read not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, write not handeled(printed 1 times)
USB unknown command, value:0x42(printed 1 times)
USB command 0x42, read not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, write not handeled(printed 1 times)
USB unknown command, value:0x43(printed 1 times)
USB command 0x43, read not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, write not handeled(printed 1 times)
USB unknown command, value:0x44(printed 1 times)
USB command 0x44, read not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, write not handeled(printed 1 times)
USB unknown command, value:0x45(printed 1 times)
USB command 0x45, read not handeled(printed 1 times)
CMD_PRINT: muExpDriver:OS booting! (printed 1 times)
CMD_PRINT: muExpDriver:RAM size:255232 bytes (printed 1 times)
CMD_PRINT: muExpDriver:RAM free:224284, RAM biggest block:224074 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage size:16514802 bytes (printed 1 times)
CMD_PRINT: muExpDriver:Storage free:15810968 bytes, Storage biggest block:15785686 bytes (printed 1 times)
CMD_PRINT: muExpDriver:New trap table created at:0x0003A39C (printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEA94.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEABA.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AEAD2.(printed 1 times)
CPU wrote 16 bits of 0x00000800 to register 0x906, PC:0x100AEAE6.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AEAEE.(printed 1 times)
CPU wrote 16 bits of 0x000000C0 to register 0x908, PC:0x100AEB1E.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE118.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE12A.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE12A.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE14C.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE150.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU wrote 16 bits of 0x00000000 to register 0x908, PC:0x100AE2E8.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2F4.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE286.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE296.(printed 1 times)
CPU read 16 bits from register 0x900, PC:0x100AE2D2.(printed 1 times)
CPU read 16 bits from register 0x908, PC:0x100AE2D6.(printed 1 times)
CPU wrote 16 bits of 0x00000020 to register 0x908, PC:0x100AE2D6.(printed 1 times)
SD command blocked by idle state: isAcmd:0, cmd:5, arg:0x00000000, CRC:0x00(printed 1 times)
CMD_PRINT: muExpDriver:Called ARM function:0x000D1484 (printed 1 times)
50 ARM opcodes have been ran(printed 16 times)
36 ARM opcodes have been ran(printed 1 times)
CMD_PRINT: muExpDriver:ARM calling 68k function:0x00000013, stackBlob:0x0003A330, stackBlobSize:0x00000004, wantA0:1 (printed 1 times)
50 ARM opcodes have been ran(printed 1 times)
20 ARM opcodes have been ran(printed 1 times)
CMD_PRINT: muExpDriver:ARM calling 68k function:0x00000013, stackBlob:0x0003A328, stackBlobSize:0x00000004, wantA0:1 (printed 1 times)
m68k jumped 0x1AAF6E8C bytes to invalid address, from 0x000EA178 to 0x1ABE1004(printed 1 times)
Bus error timeout at:0x1ABE1004, PC:0x1ABE1004(printed 1 times)

View File

@@ -1 +0,0 @@
ARM executes mostly normal up until 68k functions are called when 32 bit aligned but acts weird when 16 bit aligned, there may be part of the CPU core I haven't patched yet.

1
bugs/currentBug.txt Normal file
View File

@@ -0,0 +1 @@
T3 locks up endlessly checking TSC2101 interrupts

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

@@ -1,4 +1,4 @@
Cinco De Mayo(May 5th), 17:00 GMT, hopefully with some good ARM stuff
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:

View File

@@ -1,5 +1,6 @@
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)

View File

@@ -1,3 +0,0 @@
Fixed:
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)

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,9 +1,5 @@
CPU:
sysTrapPceNativeCall, ARM Emulator
VFP(floating point) coprocessor for ARM
Test what bits of IMR are writable
sandbox isnt notified about switches to Thumb mode
function name finders for ARMv5 and Thumb are unimplemented
hardware registers don't have there names printed in sandbox
CPU I/O:
@@ -21,13 +17,13 @@ RxOverflow on SPI1, don't know if back or front of FIFO is overwritten on overfl
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)
PWM2 is not implemented
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
UART1 USTCNT1
PLLFSR has a hack that makes busy wait loops finish faster by toggling the CLK32 bit on read, for power button issue
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)
ARM CPU state isn't saved
trying to beam anything will lock up the OS
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:
unknown if DRAM bit expanded address space is used for CSC when its not an extension of CSD
@@ -43,21 +39,44 @@ electrical noise on lines(conversions probably should have +-20 added to 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:
Support for Silkyboard 2 silkscreen:https://archive.org/details/tucows_228076_SILKYBOARD_II
Qt port dosent support Windows touchscreen input
memory dumping dosent work for OS 5 yet
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
Fixed:
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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

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)
@@ -159,6 +161,17 @@ 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
# Theos iOS
else ifeq ($(platform), theos_ios)
DEPLOYMENT_IOSVERSION = 5.0
@@ -442,7 +455,7 @@ else ifeq ($(platform), xbox1_msvc2003)
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 +476,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 +501,7 @@ endif
COMMON_DEFINES += $(CODE_DEFINES) $(WARNINGS_DEFINES) $(fpic)
CFLAGS += $(DEFINES) $(COMMON_DEFINES)
CXXFLAGS += $(DEFINES) $(COMMON_DEFINES)
ifneq (,$(findstring msvc,$(platform)))
OBJOUT = -Fo
@@ -507,7 +521,7 @@ 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)
@@ -526,8 +540,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,6 +2,9 @@ EMU_PATH := $(CORE_DIR)/../src
LIBRETRO_COMM_DIR := $(CORE_DIR)/libretro-common
COREDEFINES :=
# my first make function!!!
CHECK_ALL = $(strip $(foreach v,$(2),$(if $(findstring $(v),$(1)),$(v),)))
INCFLAGS := -I$(LIBRETRO_COMM_DIR)/include
ifeq ($(DEBUG), 1)
@@ -10,24 +13,96 @@ else
COREDEFINES += -DEMU_NO_SAFETY
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
# 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)
@@ -35,8 +110,8 @@ COREDEFINES += $(EMU_DEFINES)
SOURCES_C := $(CORE_DIR)/libretro.c \
$(CORE_DIR)/cursors.c \
$(EMU_SOURCES_C)
SOURCES_ASM :=
SOURCES_CXX := $(EMU_SOURCES_CXX)
SOURCES_ASM := $(EMU_SOURCES_ASM)
ifneq ($(STATIC_LINKING), 1)
SOURCES_C += $(LIBRETRO_COMM_DIR)/compat/compat_strl.c \

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)

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)

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

@@ -0,0 +1,101 @@
##############
# Works on hosts Linux
# apt-get install mingw-w64
##########################
# Checks the host platform
HOST_PLATFORM = linux
ifeq ($(shell uname -a),)
HOST_PLATFORM = windows
else ifneq ($(findstring MINGW,$(shell uname -a)),)
HOST_PLATFORM = windows
else ifneq ($(findstring Darwin,$(shell uname -a)),)
HOST_PLATFORM = darwin
else ifneq ($(findstring win,$(shell uname -a)),)
HOST_PLATFORM = windows
endif
####################################
# Variable setup for Makefile.common
CORE_DIR ?= ..
BUILD_DIR ?= .
INCLUDES =
include $(BUILD_DIR)/Makefile.common
#################
# Toolchain setup
CC = cl.exe
CXX = cl.exe
PATH := $(shell IFS=$$'\n'; cygpath "$(VS90COMNTOOLS)../../VC/bin"):$(PATH)
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS90COMNTOOLS)../IDE")
INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS90COMNTOOLS)../../VC/include")
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS90COMNTOOLS)../../VC/lib")
WindowsSdkDir := $(INETSDK)
export INCLUDE := $(INCLUDE);$(WindowsSdkDir)/Include
export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib
############
# Extensions
OBJEXT = .obj
SOEXT = .dll
################
# Platform setup
STATIC_LINKING = 0
platform = win
PLATDEFS =
PLATCFLAGS = -DWINVER=0x0400 -D_WIN32_WINNT=0x0400 -DWIN32 -DCORRECT_VRAM_READS -D_WINDOWS -D_USRDLL -D_CRT_SECURE_NO_WARNINGS -DMSVC2010_EXPORTS -DFRONTEND_SUPPORTS_RGB565 -DGIT_VERSION=\"$(GIT_VERSION)\"
PLATCXXFLAGS = $(PLATCFLAGS)
#PLATLDFLAGS = -shared -lm
#PLATLDXFLAGS = -shared -lm
################
# libretro setup
RETRODEFS = -D__LIBRETRO__ -wd4710 -wd4711 -wd4127 -wd4204 -wd4242 -wd4244 -wd4820 -wd4214 -wd4100 -wd4738 -wd4706 -wd4668 -wd4245 -wd4255 -wd4389 -wd4305 -wd4113
RETROCFLAGS =
RETROCXXFLAGS =
RETROLDFLAGS =
RETROLDXFLAGS =
#################
# Final variables
DEFINES = $(PLATDEFS) $(COREDEFINES) $(RETRODEFS)
CFLAGS = $(PLATCFLAGS) $(RETROCFLAGS) $(DEFINES) $(INCLUDES)
CXXFLAGS = $(PLATCXXFLAGS) $(RETROCXXFLAGS) $(DEFINES) $(INCLUDES)
LDFLAGS = $(PLATLDFLAGS) $(RETROLDFLAGS)
LDXFLAGS = $(PLATLDXFLAGS) $(RETROLDXFLAGS)
########
# Tuning
ifeq ($(DEBUG),1)
CFLAGS += -Od -Zi -D_DEBUG
CXXFLAGS += -Od -Zi -D_DEBUG
LDFLAGS += -DEBUG -DLL
else
CFLAGS += -O2 -DNDEBUG
CXXFLAGS += -O2 -DNDEBUG
LDFLAGS += -DLL
endif
ifneq ($(LOG_PERFORMANCE),)
CFLAGS += -DLOG_PERFORMANCE
CXXFLAGS += -DLOG_PERFORMANCE
endif
###############
# Include rules
include $(BUILD_DIR)/Makefile.rules

View File

@@ -44,8 +44,8 @@ platform = win
PLATDEFS =
PLATCFLAGS = -fstrict-aliasing
PLATCXXFLAGS = -fstrict-aliasing
PLATLDFLAGS = -shared -lm
PLATLDXFLAGS = -shared -lm
PLATLDFLAGS = -shared -lm -static-libgcc -static-libstdc++
PLATLDXFLAGS = -shared -lm -static-libgcc -static-libstdc++
################
# libretro setup
@@ -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

@@ -44,8 +44,8 @@ platform = win
PLATDEFS =
PLATCFLAGS = -fpic -fstrict-aliasing
PLATCXXFLAGS = -fpic -fstrict-aliasing
PLATLDFLAGS = -shared -lm
PLATLDXFLAGS = -shared -lm
PLATLDFLAGS = -shared -lm -static-libgcc -static-libstdc++
PLATLDXFLAGS = -shared -lm -static-libgcc -static-libstdc++
################
# libretro setup
@@ -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

@@ -4,6 +4,23 @@ CORE_DIR := $(LOCAL_PATH)/..
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
platform = android_jni
# Palm OS 5 support
EMU_SUPPORT_PALM_OS5 := 1
EMU_OS := linux
ifeq ($(TARGET_ARCH_ABI), x86)
EMU_ARCH := x86_32
else ifeq ($(TARGET_ARCH_ABI), x86_64)
EMU_ARCH := x86_64
else ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
EMU_ARCH := armv7
else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
EMU_ARCH := armv8
else
EMU_ARCH := unknown
endif
include $(CORE_DIR)/build/Makefile.common
COREFLAGS := -ffast-math -funroll-loops -D__LIBRETRO__ -DINLINE=inline -DFRONTEND_SUPPORTS_RGB565 $(INCFLAGS) $(COREDEFINES)
@@ -14,7 +31,9 @@ endif
include $(CLEAR_VARS)
LOCAL_MODULE := retro
LOCAL_SRC_FILES := $(SOURCES_C) $(SOURCES_ASM)
LOCAL_SRC_FILES := $(SOURCES_C) $(SOURCES_CXX) $(SOURCES_ASM)
# LOCAL_CFLAGS := $(COREFLAGS) -fopenmp -DEMU_MULTITHREADED -DEMU_MANAGE_HOST_CPU_PIPELINE
# LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/build/link.T -fopenmp
LOCAL_CFLAGS := $(COREFLAGS)
LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/build/link.T

View File

@@ -1,2 +1,5 @@
APP_ABI := all
# only compile the CPUs that Android actually used at some point
APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64
APP_PLATFORM := android-18
APP_STL := c++_static
APP_CPPFLAGS += -std=c++11

View File

@@ -11,15 +11,18 @@
#include <compat/strl.h>
#include <retro_miscellaneous.h>
#include <streams/file_stream.h>
#include <string/stdstring.h>
#include "../src/emulator.h"
#include "../src/portability.h"
#include "../src/silkscreen.h"
#include "../src/fileLauncher/launcher.h"
#include "cursors.h"
#define JOYSTICK_DEADZONE 4000
#define JOYSTICK_MULTIPLIER 0.0001
#define SCREEN_HIRES (!(palmFramebufferWidth == 160 && palmFramebufferHeight == 220))
#define SCREEN_HIRES (!(palmFramebufferWidth == 160))
static retro_log_printf_t log_cb = NULL;
@@ -30,12 +33,35 @@ static retro_environment_t environ_cb = NULL;
static retro_input_poll_t input_poll_cb = NULL;
static retro_input_state_t input_state_cb = NULL;
static uint32_t emuFeatures;
static double cpuSpeed;
static bool syncRtc;
static bool allowInvalidBehavior;
#if defined(EMU_SUPPORT_PALM_OS5)
static bool useOs5;
#endif
static bool firstRetroRunCall;
static bool dontRenderGraffiti;
static bool useJoystickAsMouse;
static float touchCursorX;
static float touchCursorY;
static char contentPath[PATH_MAX_LENGTH];
static uint16_t mouseCursorOldArea[32 * 32];
static bool runningImgFile;
static uint16_t screenYEnd;
static void frontendGetCurrentTime(uint8_t* writeBack){
time_t rawTime;
struct tm* timeInfo;
time(&rawTime);
timeInfo = localtime(&rawTime);
writeBack[0] = timeInfo->tm_hour;
writeBack[1] = timeInfo->tm_min;
writeBack[2] = timeInfo->tm_sec;
}
static void renderMouseCursor(int16_t screenX, int16_t screenY){
if(SCREEN_HIRES){
int8_t x;
@@ -44,11 +70,15 @@ static void renderMouseCursor(int16_t screenX, int16_t screenY){
//align cursor to side of image
screenX -= 6;
for(y = 0; y < 32; y++)
for(x = 6; x < 26; x++)
if(screenX + x >= 0 && screenY + y >= 0 && screenX + x < palmFramebufferWidth && screenY + y < palmFramebufferHeight)
for(y = 0; y < 32; y++){
for(x = 6; x < 26; x++){
if(screenX + x >= 0 && screenY + y >= 0 && screenX + x < palmFramebufferWidth && screenY + y < palmFramebufferHeight){
mouseCursorOldArea[y * 32 + x] = palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x];
if(cursor32x32[y * 32 + x] != 0xFFFF)
palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x] = cursor32x32[y * 32 + x];
}
}
}
}
else{
int8_t x;
@@ -57,11 +87,42 @@ static void renderMouseCursor(int16_t screenX, int16_t screenY){
//align cursor to side of image
screenX -= 3;
for(y = 0; y < 16; y++){
for(x = 3; x < 13; x++){
if(screenX + x >= 0 && screenY + y >= 0 && screenX + x < palmFramebufferWidth && screenY + y < palmFramebufferHeight){
mouseCursorOldArea[y * 16 + x] = palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x];
if(cursor16x16[y * 16 + x] != 0xFFFF)
palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x] = cursor16x16[y * 16 + x];
}
}
}
}
}
static void unrenderMouseCursor(int16_t screenX, int16_t screenY){
if(SCREEN_HIRES){
int8_t x;
int8_t y;
//align cursors missing rectangle to side of image
screenX -= 6;
for(y = 0; y < 32; y++)
for(x = 6; x < 26; x++)
if(screenX + x >= 0 && screenY + y >= 0 && screenX + x < palmFramebufferWidth && screenY + y < palmFramebufferHeight)
palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x] = mouseCursorOldArea[y * 32 + x];
}
else{
int8_t x;
int8_t y;
//align cursors missing rectangle to side of image
screenX -= 3;
for(y = 0; y < 16; y++)
for(x = 3; x < 13; x++)
if(screenX + x >= 0 && screenY + y >= 0 && screenX + x < palmFramebufferWidth && screenY + y < palmFramebufferHeight)
if(cursor16x16[y * 16 + x] != 0xFFFF)
palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x] = cursor16x16[y * 16 + x];
palmFramebuffer[(screenY + y) * palmFramebufferWidth + screenX + x] = mouseCursorOldArea[y * 16 + x];
}
}
@@ -79,66 +140,32 @@ static void check_variables(bool booting){
struct retro_variable var = {0};
if(booting){
emuFeatures = FEATURE_ACCURATE;
var.key = "palm_emu_feature_ram_huge";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_RAM_HUGE;
var.key = "palm_emu_feature_fast_cpu";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_FAST_CPU;
var.key = "palm_emu_feature_hybrid_cpu";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_HYBRID_CPU;
var.key = "palm_emu_feature_custom_fb";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_CUSTOM_FB;
var.key = "palm_emu_cpu_speed";
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
cpuSpeed = atoi(var.value);
var.key = "palm_emu_feature_synced_rtc";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_SYNCED_RTC;
var.key = "palm_emu_feature_hle_apis";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_HLE_APIS;
var.key = "palm_emu_feature_emu_honest";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_EMU_HONEST;
var.key = "palm_emu_feature_ext_keys";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_EXT_KEYS;
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
syncRtc = !strcmp(var.value, "enabled");
var.key = "palm_emu_feature_durable";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_DURABLE;
var.key = "palm_emu_feature_snd_strms";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
if (!strcmp(var.value, "enabled"))
emuFeatures |= FEATURE_SND_STRMS;
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
allowInvalidBehavior = !strcmp(var.value, "enabled");
}
var.key = "palm_emu_use_joystick_as_mouse";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value){
if (!strcmp(var.value, "enabled"))
useJoystickAsMouse = true;
else
useJoystickAsMouse = false;
}
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
useJoystickAsMouse = !strcmp(var.value, "enabled");
var.key = "palm_emu_disable_graffiti";
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
dontRenderGraffiti = !strcmp(var.value, "enabled");
#if defined(EMU_SUPPORT_PALM_OS5)
var.key = "palm_emu_use_os5";
if(environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
useOs5 = !strcmp(var.value, "enabled");
#endif
}
void retro_init(void){
@@ -167,9 +194,9 @@ void retro_get_system_info(struct retro_system_info *info){
#ifndef GIT_VERSION
#define GIT_VERSION ""
#endif
info->library_version = "v1.0.0" GIT_VERSION;
info->need_fullpath = false;
info->valid_extensions = "rom";
info->library_version = "v1.1.0" GIT_VERSION;
info->need_fullpath = true;
info->valid_extensions = "prc|pqa|img";
}
void retro_get_system_av_info(struct retro_system_av_info *info){
@@ -178,8 +205,13 @@ void retro_get_system_av_info(struct retro_system_av_info *info){
info->geometry.base_width = 160;
info->geometry.base_height = 220;
info->geometry.max_width = 480;
#if defined(EMU_SUPPORT_PALM_OS5)
info->geometry.max_width = 320;
info->geometry.max_height = 480;
#else
info->geometry.max_width = 160;
info->geometry.max_height = 220;
#endif
info->geometry.aspect_ratio = 160.0 / 220.0;
}
@@ -188,37 +220,39 @@ void retro_set_environment(retro_environment_t cb){
struct retro_vfs_interface_info vfs_getter = { 1, NULL };
struct retro_led_interface led_getter;
struct retro_variable vars[] = {
{ "palm_emu_feature_ram_huge", "128mb RAM; disabled|enabled" },
{ "palm_emu_feature_fast_cpu", "Custom CPU Speeds; disabled|enabled" },
{ "palm_emu_feature_hybrid_cpu", "ARM Instruction Set; disabled|enabled" },
{ "palm_emu_feature_custom_fb", "Custom Resolution; disabled|enabled" },
{ "palm_emu_cpu_speed", "CPU Speed; 1.0|1.5|2.0|2.5|3.0|0.5" },
{ "palm_emu_feature_synced_rtc", "Force Match System Clock; disabled|enabled" },
{ "palm_emu_feature_hle_apis", "HLE API Implementations; disabled|enabled" },
{ "palm_emu_feature_emu_honest", "Is Emulator(for test programs); disabled|enabled" },
{ "palm_emu_feature_ext_keys", "Left, Right, Center Keys; disabled|enabled" },
{ "palm_emu_feature_durable", "Ignore Invalid Behavior; disabled|enabled" },
{ "palm_emu_feature_snd_strms", "Palm OS 5 PWM Streams; disabled|enabled" },
{ "palm_emu_use_joystick_as_mouse", "Use Left Joystick As Mouse; disabled|enabled" },
{ "palm_emu_disable_graffiti", "Disable Graffiti Area; disabled|enabled" },
#if defined(EMU_SUPPORT_PALM_OS5)
{ "palm_emu_use_os5", "Boot Apps In OS 5(DEV ONLY); disabled|enabled" },
#endif
{ 0 }
};
struct retro_input_descriptor input_desc[] = {
{ 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Touchscreen Mouse X" },
{ 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Touchscreen Mouse Y" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Touchscreen Mouse Click" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Dpad Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Touchscreen Mouse Click" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Dpad Up" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Dpad Down" },
#if defined(EMU_SUPPORT_PALM_OS5)
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Dpad Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Dpad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Dpad Middle" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Dpad Center" },
#endif
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Power" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Calender" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Address Book" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Todo" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Notes" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Date Book" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Address Book" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "To Do List" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Note Pad" },
{ 0 }
};
bool no_rom = true;
environ_cb = cb;
environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_rom);
if(environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging) && logging.log)
log_cb = logging.log;
@@ -264,6 +298,40 @@ void retro_reset(void){
void retro_run(void){
input_poll_cb();
//some RetroArch functions can only be called from this function so call those if needed
if(unlikely(firstRetroRunCall)){
struct retro_game_geometry geometry;
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5){
if(dontRenderGraffiti){
geometry.base_width = 320;
geometry.base_height = 320;
geometry.max_width = 320;
geometry.max_height = 480;
}
else{
geometry.base_width = 320;
geometry.base_height = 480;
}
}
else{
#endif
if(dontRenderGraffiti){
geometry.base_width = 160;
geometry.base_height = 160;
}
else{
geometry.base_width = 160;
geometry.base_height = 220;
}
#if defined(EMU_SUPPORT_PALM_OS5)
}
#endif
geometry.aspect_ratio = (float)geometry.base_width / (float)geometry.base_height;
environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &geometry);
firstRetroRunCall = false;
}
//touchscreen
if(useJoystickAsMouse){
int16_t x = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
@@ -287,27 +355,31 @@ void retro_run(void){
palmInput.touchscreenX = touchCursorX / (palmFramebufferWidth - 1);
palmInput.touchscreenY = touchCursorY / (palmFramebufferHeight - 1);
palmInput.touchscreenTouched = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2);
palmInput.touchscreenTouched = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R);
}
else{
//use RetroArch internal pointer
palmInput.touchscreenX = ((float)input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) / 0x7FFF + 1.0) / 2.0;
palmInput.touchscreenY = ((float)input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) / 0x7FFF + 1.0) / 2.0;
palmInput.touchscreenY = ((float)input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) / 0x7FFF + 1.0) / 2.0 * ((float)screenYEnd / palmFramebufferHeight);
palmInput.touchscreenTouched = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
}
//dpad
palmInput.buttonUp = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
palmInput.buttonRight = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
palmInput.buttonDown = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
palmInput.buttonLeft = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
palmInput.buttonCenter = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5){
palmInput.buttonLeft = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
palmInput.buttonRight = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
palmInput.buttonCenter = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT);
}
#endif
//app buttons
palmInput.buttonCalendar = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
palmInput.buttonAddress = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
palmInput.buttonTodo = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y);
palmInput.buttonNotes = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X);
palmInput.buttonCalendar = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y);
palmInput.buttonAddress = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X);
palmInput.buttonTodo = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
palmInput.buttonNotes = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
//special buttons
palmInput.buttonPower = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START);
@@ -319,70 +391,119 @@ void retro_run(void){
if(useJoystickAsMouse)
renderMouseCursor(touchCursorX, touchCursorY);
video_cb(palmFramebuffer, palmFramebufferWidth, palmFramebufferHeight, palmFramebufferWidth * sizeof(uint16_t));
video_cb(palmFramebuffer, palmFramebufferWidth, screenYEnd, palmFramebufferWidth * sizeof(uint16_t));
audio_cb(palmAudio, AUDIO_SAMPLES_PER_FRAME);
if(led_cb)
led_cb(0, palmMisc.powerButtonLed);
if(led_cb){
led_cb(0, palmMisc.greenLed);
#if defined(EMU_SUPPORT_PALM_OS5)
led_cb(1, palmMisc.redLed);
#endif
}
//repair damage done to the framebuffer by the mouse cursor
if(useJoystickAsMouse)
unrenderMouseCursor(touchCursorX, touchCursorY);
}
bool retro_load_game(const struct retro_game_info *info){
buffer_t rom;
buffer_t bootloader;
uint8_t* romData;
uint32_t romSize;
uint8_t* bootloaderData;
uint32_t bootloaderSize;
char romPath[PATH_MAX_LENGTH];
char bootloaderPath[PATH_MAX_LENGTH];
char saveRamPath[PATH_MAX_LENGTH];
char sdImgPath[PATH_MAX_LENGTH];
struct RFILE* romFile;
struct RFILE* bootloaderFile;
struct RFILE* saveRamFile;
struct RFILE* sdImgFile;
const char* systemDir;
const char* saveDir;
time_t rawTime;
struct tm* timeInfo;
bool hasSram = false;
uint32_t error;
if(info == NULL)
return false;
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &systemDir);
environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &saveDir);
rom.data = info->data;
rom.size = info->size;
//bootloader
strlcpy(bootloaderPath, systemDir, PATH_MAX_LENGTH);
strlcat(bootloaderPath, "/bootloader-en-m515.rom", PATH_MAX_LENGTH);
bootloaderFile = filestream_open(bootloaderPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(bootloaderFile){
bootloader.size = filestream_get_size(bootloaderFile);
bootloader.data = malloc(bootloader.size);
if(bootloader.data)
filestream_read(bootloaderFile, bootloader.data, bootloader.size);
else
bootloader.size = 0;
filestream_close(bootloaderFile);
}
else{
bootloader.data = NULL;
bootloader.size = 0;
}
//updates the emulator configuration
check_variables(true);
error = emulatorInit(rom, bootloader, emuFeatures);
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &systemDir);
if(info && !string_is_empty(info->path)){
//boot application
strlcpy(contentPath, info->path, PATH_MAX_LENGTH);
runningImgFile = string_is_equal_case_insensitive(contentPath + strlen(contentPath) - 4, ".img");
}
else{
//boot standard device image, "os5" or "os4" gets appended below
strlcpy(contentPath, systemDir, PATH_MAX_LENGTH);
strlcat(contentPath, "/default", PATH_MAX_LENGTH);
runningImgFile = false;
}
//ROM
strlcpy(romPath, systemDir, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(romPath, "/palmos52-en-t3.rom", PATH_MAX_LENGTH);
else
#endif
strlcat(romPath, "/palmos41-en-m515.rom", PATH_MAX_LENGTH);
romFile = filestream_open(romPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(romFile){
romSize = filestream_get_size(romFile);
romData = malloc(romSize);
if(romData)
filestream_read(romFile, romData, romSize);
else
romSize = 0;
filestream_close(romFile);
}
else{
//cant load without ROM
return false;
}
//bootloader, will simple be ignored for Tungsten T3
strlcpy(bootloaderPath, systemDir, PATH_MAX_LENGTH);
strlcat(bootloaderPath, "/bootloader-en-m515.rom", PATH_MAX_LENGTH);
bootloaderFile = filestream_open(bootloaderPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(bootloaderFile){
bootloaderSize = filestream_get_size(bootloaderFile);
bootloaderData = malloc(bootloaderSize);
if(bootloaderData)
filestream_read(bootloaderFile, bootloaderData, bootloaderSize);
else
bootloaderSize = 0;
filestream_close(bootloaderFile);
}
else{
bootloaderData = NULL;
bootloaderSize = 0;
}
error = emulatorInit(romData, romSize, bootloaderData, bootloaderSize, syncRtc, allowInvalidBehavior);
free(romData);
if(bootloaderData)
free(bootloaderData);
if(error != EMU_ERROR_NONE)
return false;
if(bootloader.data)
free(bootloader.data);
//save RAM
strlcpy(saveRamPath, saveDir, PATH_MAX_LENGTH);
strlcat(saveRamPath, "/userdata-en-m515.ram", PATH_MAX_LENGTH);
strlcpy(saveRamPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(saveRamPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(saveRamPath, ".os4", PATH_MAX_LENGTH);
strlcat(saveRamPath, ".ram", PATH_MAX_LENGTH);
saveRamFile = filestream_open(saveRamPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(saveRamFile){
hasSram = true;
if(filestream_get_size(saveRamFile) == emulatorGetRamSize()){
filestream_read(saveRamFile, palmRam, emulatorGetRamSize());
swap16BufferIfLittle(palmRam, emulatorGetRamSize() / sizeof(uint16_t));
@@ -390,25 +511,28 @@ bool retro_load_game(const struct retro_game_info *info){
filestream_close(saveRamFile);
}
//SD card
strlcpy(sdImgPath, saveDir, PATH_MAX_LENGTH);
strlcat(sdImgPath, "/sd-en-m515.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
buffer_t sdCard;
uint32_t sdImgSize = filestream_get_size(sdImgFile);
//use the NULL, size method because it takes less RAM
sdCard.data = NULL;
sdCard.size = sdImgSize;
error = emulatorInsertSdCard(sdCard, false);
if(error == EMU_ERROR_NONE){
sdCard = emulatorGetSdCardBuffer();
filestream_read(sdImgFile, sdCard.data, sdImgSize);
if(!runningImgFile){
//SD card
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
uint32_t sdImgSize = filestream_get_size(sdImgFile);
//use the NULL, size, NULL method because it takes less RAM
error = emulatorInsertSdCard(NULL, sdImgSize, NULL);
if(error == EMU_ERROR_NONE)
filestream_read(sdImgFile, palmSdCard.flashChipData, sdImgSize);
filestream_close(sdImgFile);
}
filestream_close(sdImgFile);
}
//set RTC
@@ -416,26 +540,115 @@ bool retro_load_game(const struct retro_game_info *info){
timeInfo = localtime(&rawTime);
emulatorSetRtc(timeInfo->tm_yday, timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
//see if RetroArch wants something launched
if(info && !string_is_empty(info->path)){
struct RFILE* contentFile;
uint8_t* contentData;
uint32_t contentSize;
contentFile = filestream_open(contentPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(contentFile){
contentSize = filestream_get_size(contentFile);
contentData = malloc(contentSize);
if(contentData)
filestream_read(contentFile, contentData, contentSize);
else
return false;
filestream_close(contentFile);
}
else{
//no content at path, fail time
return false;
}
launcherBootInstantly(hasSram);
if(runningImgFile){
char infoPath[PATH_MAX_LENGTH];
struct RFILE* infoFile;
uint8_t* infoData = NULL;
uint32_t infoSize;
sd_card_info_t sdInfo;
memset(&sdInfo, 0x00, sizeof(sdInfo));
strlcpy(infoPath, contentPath, PATH_MAX_LENGTH);
infoPath[strlen(infoPath) - 4] = '\0';//chop off ".img"
strlcat(infoPath, ".info", PATH_MAX_LENGTH);
infoFile = filestream_open(infoPath, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(infoFile){
infoSize = filestream_get_size(infoFile);
infoData = malloc(infoSize);
if(infoData)
filestream_read(infoFile, infoData, infoSize);
filestream_close(infoFile);
}
if(infoData)
launcherGetSdCardInfoFromInfoFile(infoData, infoSize, &sdInfo);
error = emulatorInsertSdCard(contentData, contentSize, infoData ? &sdInfo : NULL);
if(infoData)
free(infoData);
}
else{
if(!hasSram)
error = launcherInstallFile(contentData, contentSize);
if(error == EMU_ERROR_NONE)
error = launcherExecute(launcherGetAppId(contentData, contentSize));
}
free(contentData);
if(error != EMU_ERROR_NONE)
return false;
}
//set the time callback
palmGetRtcFromHost = frontendGetCurrentTime;
//set mouse position
touchCursorX = palmFramebufferWidth / 2;
touchCursorY = palmFramebufferHeight / 2;
//make touches land on the correct spot and screen render the correct size when the graffiti area is off
if(dontRenderGraffiti){
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
screenYEnd = 320;
else
#endif
screenYEnd = 160;
}
else{
screenYEnd = palmFramebufferHeight;
}
//used to resize things properly
firstRetroRunCall = true;
//set default CPU speed
emulatorSetCpuSpeed(cpuSpeed);
return true;
}
void retro_unload_game(void){
const char* saveDir;
char saveRamPath[PATH_MAX_LENGTH];
char sdImgPath[PATH_MAX_LENGTH];
struct RFILE* saveRamFile;
struct RFILE* sdImgFile;
buffer_t sdCard = emulatorGetSdCardBuffer();
environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &saveDir);
//save RAM
strlcpy(saveRamPath, saveDir, PATH_MAX_LENGTH);
strlcat(saveRamPath, "/userdata-en-m515.ram", PATH_MAX_LENGTH);
strlcpy(saveRamPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(saveRamPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(saveRamPath, ".os4", PATH_MAX_LENGTH);
strlcat(saveRamPath, ".ram", PATH_MAX_LENGTH);
saveRamFile = filestream_open(saveRamPath, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(saveRamFile){
swap16BufferIfLittle(palmRam, emulatorGetRamSize() / sizeof(uint16_t));//this will no longer be used, so its ok to destroy it when swapping
@@ -443,18 +656,26 @@ void retro_unload_game(void){
filestream_close(saveRamFile);
}
//SD card
if(sdCard.data){
strlcpy(sdImgPath, saveDir, PATH_MAX_LENGTH);
strlcat(sdImgPath, "/sd-en-m515.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
filestream_write(sdImgFile, sdCard.data, sdCard.size);
filestream_close(sdImgFile);
if(!runningImgFile){
//SD card
if(palmSdCard.flashChipData){
strlcpy(sdImgPath, contentPath, PATH_MAX_LENGTH);
#if defined(EMU_SUPPORT_PALM_OS5)
if(useOs5)
strlcat(sdImgPath, ".os5", PATH_MAX_LENGTH);
else
#endif
strlcat(sdImgPath, ".os4", PATH_MAX_LENGTH);
strlcat(sdImgPath, ".sd.img", PATH_MAX_LENGTH);
sdImgFile = filestream_open(sdImgPath, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(sdImgFile){
filestream_write(sdImgFile, palmSdCard.flashChipData, palmSdCard.flashChipSize);
filestream_close(sdImgFile);
}
}
}
emulatorExit();
emulatorDeinit();
}
unsigned retro_get_region(void){
@@ -473,21 +694,11 @@ size_t retro_serialize_size(void){
}
bool retro_serialize(void *data, size_t size){
buffer_t saveBuffer;
saveBuffer.data = (uint8_t*)data;
saveBuffer.size = size;
return emulatorSaveState(saveBuffer);
return emulatorSaveState(data, size);
}
bool retro_unserialize(const void *data, size_t size){
buffer_t saveBuffer;
saveBuffer.data = (uint8_t*)data;
saveBuffer.size = size;
return emulatorLoadState(saveBuffer);
return emulatorLoadState(data, size);
}
void* retro_get_memory_data(unsigned id){

View File

@@ -1,15 +1,21 @@
display_name = "Palm OS (Mu)"
authors = "guicrith / meepingsnesroms"
supported_extensions = "rom"
supported_extensions = "prc|pqa|img"
corename = "Mu"
manufacturer = "Palm"
categories = "Emulator"
systemname = "Palm OS"
license = "Non-commercial"
permissions = ""
display_version = "v1.0.0"
supports_no_game = "false"
firmware_count = 1
firmware0_desc = "bootloader-en-m515.rom (MC68VZ328 UART Bootloader)"
firmware0_path = "bootloader-en-m515.rom"
display_version = "v1.1.0"
supports_no_game = "true"
firmware_count = 3
firmware0_desc = "palmos41-en-m515.rom (Palm OS 4.1)"
firmware0_path = "palmos41-en-m515.rom"
firmware0_opt = "true"
firmware1_desc = "palmos52-en-t3.rom (Palm OS 5.2.1)"
firmware1_path = "palmos52-en-t3.rom"
firmware1_opt = "true"
firmware2_desc = "bootloader-en-m515.rom (MC68VZ328 UART Bootloader)"
firmware2_path = "bootloader-en-m515.rom"
firmware2_opt = "true"

View File

@@ -11,14 +11,14 @@ overlay0_desc2 = "up,0.504283,0.802938,radial,0.06852,0.04479"
overlay0_desc2_overlay = "X1_wswan.png"
overlay0_desc3 = "down,0.504283,0.964221,radial,0.06852,0.04479"
overlay0_desc3_overlay = "X3_wswan.png"
overlay0_desc4 = "a,0.0821626,0.960563,radial,0.07407,0.04167"
overlay0_desc4_overlay = "A.png"
overlay0_desc5 = "b,0.234211,0.960563,radial,0.07407,0.04167"
overlay0_desc5_overlay = "B.png"
overlay0_desc6 = "x,0.918421,0.960563,radial,0.07407,0.04167"
overlay0_desc6_overlay = "X.png"
overlay0_desc7 = "y,0.770469,0.960563,radial,0.07407,0.04167"
overlay0_desc7_overlay = "Y.png"
overlay0_desc4 = "y,0.0821626,0.960563,radial,0.07407,0.04167"
overlay0_desc4_overlay = "Y.png"
overlay0_desc5 = "x,0.234211,0.960563,radial,0.07407,0.04167"
overlay0_desc5_overlay = "X.png"
overlay0_desc6 = "a,0.918421,0.960563,radial,0.07407,0.04167"
overlay0_desc6_overlay = "A.png"
overlay0_desc7 = "b,0.770469,0.960563,radial,0.07407,0.04167"
overlay0_desc7_overlay = "B.png"
overlay0_desc8 = "start,0.860359,0.810741,rect,0.07037,0.03958"
overlay0_desc8_overlay = "start.png"
overlay0_desc9 = "menu_toggle,0.0552632,0.801573,radial,0.046296,0.02604"

View File

@@ -22,40 +22,46 @@ DEFINES += QT_DEPRECATED_WARNINGS
# You can also select to disable deprecated APIs only up to a certain version of Qt.
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += support_palm_os5
windows{
RC_ICONS = windows/Mu.ico
*msvc*{
QMAKE_CFLAGS += -openmp
QMAKE_CXXFLAGS += -openmp
DEFINES += "_Pragma=__pragma"
DEFINES += "_Pragma=__pragma" EMU_MULTITHREADED
}
*-g++{
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
QMAKE_LFLAGS += -fopenmp
DEFINES += EMU_MULTITHREADED EMU_MANAGE_HOST_CPU_PIPELINE
}
DEFINES += EMU_MULTITHREADED
CONFIG += cpu_x86_32 # this should be auto detected in the future
}
macx{
QMAKE_CFLAGS += -std=c89 -D__STDBOOL_H -Dinline= -Dbool=char -Dtrue=1 -Dfalse=0 # tests C89 mode
# QMAKE_CFLAGS += -std=c89 -D__STDBOOL_H -Dinline= -Dbool=char -Dtrue=1 -Dfalse=0 # tests C89 mode
ICON = macos/Mu.icns
QMAKE_INFO_PLIST = macos/Info.plist
DEFINES += EMU_MULTITHREADED
DEFINES += EMU_MULTITHREADED EMU_MANAGE_HOST_CPU_PIPELINE
CONFIG += cpu_x86_64 # Mac OS is only x86_64
}
linux-g++{
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
QMAKE_LFLAGS += -fopenmp
DEFINES += EMU_MULTITHREADED
DEFINES += EMU_MULTITHREADED EMU_MANAGE_HOST_CPU_PIPELINE
CONFIG += cpu_x86_64 # this should be auto detected in the future
}
android{
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
QMAKE_LFLAGS += -fopenmp
DEFINES += EMU_MULTITHREADED
DEFINES += EMU_MULTITHREADED EMU_MANAGE_HOST_CPU_PIPELINE
CONFIG += cpu_armv7 # this should be auto detected in the future
}
@@ -63,9 +69,10 @@ CONFIG(debug, debug|release){
# debug build, be accurate, fail hard, and add logging
DEFINES += EMU_DEBUG EMU_CUSTOM_DEBUG_LOG_HANDLER EMU_SANDBOX
# DEFINES += EMU_SANDBOX_LOG_MEMORY_ACCESSES # checks all reads and writes to memory and logs certain events
DEFINES += EMU_SANDBOX_OPCODE_LEVEL_DEBUG # for breakpoints
DEFINES += EMU_SANDBOX_LOG_JUMPS # log large jumps
DEFINES += EMU_SANDBOX_LOG_APIS # for printing sysTrap* calls, EMU_SANDBOX_OPCODE_LEVEL_DEBUG must be on too
# DEFINES += EMU_SANDBOX_OPCODE_LEVEL_DEBUG # for breakpoints
# DEFINES += EMU_SANDBOX_LOG_JUMPS # log large jumps
# DEFINES += EMU_SANDBOX_LOG_APIS # for printing sysTrap* calls, EMU_SANDBOX_OPCODE_LEVEL_DEBUG must be on too
CONFIG += no_dynarec # easier to debug with
macx|linux-g++{
# also check for any buffer overflows and memory leaks
# -fsanitize=undefined,leak
@@ -78,83 +85,193 @@ CONFIG(debug, debug|release){
DEFINES += EMU_NO_SAFETY
}
support_palm_os5{
DEFINES += EMU_SUPPORT_PALM_OS5 # the Qt build will not be supporting anything too slow to run OS 5
DEFINES += SUPPORT_LINUX # forces the dynarec to use accurate mode and disable Nspire OS hacks
!no_dynarec{
# Windows is only supported in 32 bit mode right now(this is a limitation of the dynarec)
# iOS needs IS_IOS_BUILD set, but the Qt port does not support iOS currently
cpu_x86_32{
SOURCES += \
../../src/armv5te/translate_x86.c \
../../src/armv5te/asmcode_x86.S
}
else{
# x86 has this implemented in asmcode_x86.S
SOURCES += \
../../src/armv5te/asmcode.c
}
cpu_x86_64{
SOURCES += \
../../src/armv5te/translate_x86_64.c \
../../src/armv5te/asmcode_x86_64.S
}
cpu_armv7{
SOURCES += \
../../src/armv5te/translate_arm.cpp \
../../src/armv5te/asmcode_arm.S
}
cpu_armv8{
SOURCES += \
../../src/armv5te/translate_aarch64.cpp \
../../src/armv5te/asmcode_aarch64.S
}
}
else{
# use platform independant C with no dynarec
SOURCES += \
../../src/armv5te/asmcode.c
DEFINES += NO_TRANSLATION
}
windows{
SOURCES += \
../../src/armv5te/os/os-win32.c
}
macx|linux-g++|android{
SOURCES += \
../../src/armv5te/os/os-linux.c
}
SOURCES += \
../../src/pxa260/pxa260_DMA.c \
../../src/pxa260/pxa260_DSP.c \
../../src/pxa260/pxa260_GPIO.c \
../../src/pxa260/pxa260_IC.c \
../../src/pxa260/pxa260_LCD.c \
../../src/pxa260/pxa260_PwrClk.c \
../../src/pxa260/pxa260_RTC.c \
../../src/pxa260/pxa260_TIMR.c \
../../src/pxa260/pxa260_UART.c \
../../src/pxa260/pxa260I2c.c \
../../src/pxa260/pxa260Memctrl.c \
../../src/pxa260/pxa260Timing.c \
../../src/pxa260/pxa260Ssp.c \
../../src/pxa260/pxa260Udc.c \
../../src/pxa260/pxa260.c \
../../src/armv5te/arm_interpreter.cpp \
../../src/armv5te/cpu.cpp \
../../src/armv5te/coproc.cpp \
../../src/armv5te/emuVarPool.c \
../../src/armv5te/thumb_interpreter.cpp \
../../src/armv5te/mem.c \
../../src/armv5te/mmu.c \
../../src/tps65010.c \
../../src/tsc2101.c \
../../src/w86l488.c
HEADERS += \
../../src/pxa260/pxa260_CPU.h \
../../src/pxa260/pxa260_DMA.h \
../../src/pxa260/pxa260_DSP.h \
../../src/pxa260/pxa260_GPIO.h \
../../src/pxa260/pxa260_IC.h \
../../src/pxa260/pxa260_LCD.h \
../../src/pxa260/pxa260_PwrClk.h \
../../src/pxa260/pxa260_RTC.h \
../../src/pxa260/pxa260_TIMR.h \
../../src/pxa260/pxa260_UART.h \
../../src/pxa260/pxa260I2c.h \
../../src/pxa260/pxa260Memctrl.h \
../../src/pxa260/pxa260Timing.h \
../../src/pxa260/pxa260Ssp.h \
../../src/pxa260/pxa260Udc.h \
../../src/pxa260/pxa260_types.h \
../../src/pxa260/pxa260_math64.h \
../../src/pxa260/pxa260Accessors.c.h \
../../src/pxa260/pxa260.h \
../../src/armv5te/os/os.h \
../../src/armv5te/asmcode.h \
../../src/armv5te/bitfield.h \
../../src/armv5te/cpu.h \
../../src/armv5te/emu.h \
../../src/armv5te/mem.h \
../../src/armv5te/translate.h \
../../src/armv5te/cpudefs.h \
../../src/armv5te/debug.h \
../../src/armv5te/mmu.h \
../../src/armv5te/armsnippets.h \
../../src/armv5te/literalpool.h \
../../src/tungstenT3Bus.h \
../../src/tps65010.h \
../../src/tsc2101.h \
../../src/w86l488.h
}
CONFIG += c++11
INCLUDEPATH += $$PWD/qt-common/include
SOURCES += \
../../src/ads7846.c \
../../src/armv5te/disasm.c \
../../src/audio/blip_buf.c \
../../src/dbvz.c \
../../src/debug/sandbox.c \
../../src/emulator.c \
../../src/fileLauncher/launcher.c \
../../src/flx68000.c \
../../src/m515Bus.c \
../../src/m68k/m68kcpu.c \
../../src/m68k/m68kdasm.c \
../../src/m68k/m68kops.c \
../../src/pdiUsbD12.c \
../../src/sdCard.c \
../../src/sed1376.c \
../../src/silkscreen.c \
debugviewer.cpp \
emuwrapper.cpp \
main.cpp \
mainwindow.cpp \
statemanager.cpp \
touchscreen.cpp \
../../src/audio/blip_buf.c \
../../src/debug/sandbox.c \
../../src/ads7846.c \
../../src/emulator.c \
../../src/flx68000.c \
../../src/hardwareRegisters.c \
../../src/memoryAccess.c \
../../src/pdiUsbD12.c \
../../src/sdCard.c \
../../src/sed1376.c \
../../src/silkscreen.c \
../../src/m68k/m68kcpu.c \
../../src/m68k/m68kdasm.c \
../../src/m68k/m68kopac.c \
../../src/m68k/m68kopdm.c \
../../src/m68k/m68kopnz.c \
../../src/m68k/m68kops.c \
../../src/armv5/CPU.c \
../../src/armv5/icache.c \
../../src/armv5.c \
../../src/expansionHardware.c \
settingsmanager.cpp
HEADERS += \
debugviewer.h \
emuwrapper.h \
mainwindow.h \
statemanager.h \
touchscreen.h \
../../src/ads7846.h \
../../src/armv5te/disasm.h \
../../src/audio/blip_buf.h \
../../src/dbvz.h \
../../src/dbvzRegisterAccessors.c.h \
../../src/dbvzRegisterNames.c.h \
../../src/dbvzTiming.c.h \
../../src/debug/sandbox.h \
../../src/debug/sandboxTrapNumToName.c.h \
../../src/debug/trapNames.h \
../../src/emulator.h \
../../src/fileLauncher/launcher.h \
../../src/flx68000.h \
../../src/m515Bus.h \
../../src/m68k/m68k.h \
../../src/m68k/m68kconf.h \
../../src/m68k/m68kcpu.h \
../../src/m68k/m68kexternal.h \
../../src/m68k/m68kops.h \
../../src/specs/dragonballVzRegisterSpec.h \
../../src/ads7846.h \
../../src/emulator.h \
../../src/flx68000.h \
../../src/hardwareRegisters.h \
../../src/hardwareRegistersAccessors.c.h \
../../src/hardwareRegistersTiming.c.h \
../../src/memoryAccess.h \
../../src/pdiUsbD12.h \
../../src/pdiUsbD12CommandNames.c.h \
../../src/portability.h \
../../src/sdCard.h \
../../src/sdCardAccessors.c.h \
../../src/sdCardCommandNames.c.h \
../../src/sdCardCrcTables.c.h \
../../src/sed1376.h \
../../src/sed1376Accessors.c.h \
../../src/sed1376RegisterNames.c.h \
../../src/silkscreen.h \
../../src/specs/sed1376RegisterSpec.h \
../../src/specs/pdiUsbD12CommandSpec.h \
../../src/specs/emuFeatureRegisterSpec.h \
../../src/specs/sdCardCommandSpec.h \
../../src/armv5/CPU.h \
../../src/armv5/math64.h \
../../src/armv5/types.h \
../../src/armv5/icache.h \
../../src/armv5.h \
../../src/expansionHardware.h \
../../src/sdCardAccessors.c.h \
../../src/sdCardCrcTables.c.h \
debugviewer.h \
emuwrapper.h \
mainwindow.h \
statemanager.h \
touchscreen.h \
settingsmanager.h
FORMS += \
mainwindow.ui \
debugviewer.ui \
@@ -165,6 +282,7 @@ CONFIG += mobility
MOBILITY =
DISTFILES += \
../../src/fileLauncher/readme.md \
android/AndroidManifest.xml \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradlew \
@@ -175,18 +293,22 @@ DISTFILES += \
android/res/drawable-hdpi/icon.png \
android/res/drawable-ldpi/icon.png \
android/res/drawable-mdpi/icon.png \
images/boot.svg \
images/addressBook.svg \
images/calendar.svg \
images/center.svg \
images/center.svg \
images/debugger.svg \
images/down.svg \
images/install.svg \
images/left.svg \
images/left.svg \
images/notes.svg \
images/pause.svg \
images/play.svg \
images/power.svg \
images/right.svg \
images/right.svg \
images/screenshot.svg \
images/settingsManager.svg \
images/stateManager.svg \

View File

@@ -1,12 +1,13 @@
#include "debugviewer.h"
#include "ui_debugviewer.h"
#include <QVector>
#include <QString>
#include <QFile>
#include <QDir>
#include <vector>
#include <stdint.h>
#include <stdio.h>
#include "mainwindow.h"
#include "emuwrapper.h"
@@ -44,24 +45,6 @@ int64_t DebugViewer::numberFromString(QString str, bool negativeAllowed){
return value;
}
QString DebugViewer::stringFromNumber(int64_t number, bool hex, uint32_t forcedZeros){
QString numString;
if(hex){
numString += QString::number(number, 16).toUpper();
while(numString.length() < (int)forcedZeros)numString.push_front("0");
numString.push_front("0x");
}
else{
numString += QString::number(qAbs(number), 10);
while(numString.length() < (int)forcedZeros)numString.push_front("0");
if(number < 0)
numString.push_front("-");
}
return numString;
}
void DebugViewer::debugRadioButtonHandler(){
switch(bitsPerEntry){
case 8:
@@ -94,12 +77,12 @@ void DebugViewer::on_debugGetHexValues_clicked(){
if(address != INT64_MIN && length != INT64_MIN && length != 0 && address + bits / 8 * length - 1 <= 0xFFFFFFFF){
for(int64_t count = 0; count < length; count++){
uint64_t data = emu.getEmulatorMemory(address, bits);
uint64_t data = emu.debugGetEmulatorMemory(address, bits);
QString value;
value += stringFromNumber(address, true, 8);
value += QString::asprintf("0x%08X", (uint32_t)address);
value += ":";
if(data != UINT64_MAX)
value += stringFromNumber(data, true, bits / 8 * 2);
value += QString::asprintf("0x%0*X", bits / 8 * 2, (uint32_t)data);
else
value += "Unsafe Access";
ui->debugValueList->addItem(value);
@@ -126,7 +109,7 @@ void DebugViewer::on_debug32Bit_clicked(){
debugRadioButtonHandler();
}
void DebugViewer::on_debugDump_clicked(){
void DebugViewer::on_debugDumpToFile_clicked(){
QString fileBuffer;
QFile fileOut(((MainWindow*)parentWidget())->settings->value("resourceDirectory", "").toString() + "/debugDumps/" + ui->debugFilePath->text());
@@ -142,23 +125,23 @@ void DebugViewer::on_debugDump_clicked(){
}
}
void DebugViewer::on_debugDumpToTerminal_clicked(){
for(int index = 0; index < ui->debugValueList->count(); index++)
printf("%s\n", ui->debugValueList->item(index)->text().toStdString().c_str());
fflush(stdout);
}
void DebugViewer::on_debugShowRegisters_clicked(){
std::vector<uint32_t> registers = ((MainWindow*)parentWidget())->emu.getCpuRegisters();
EmuWrapper& emu = ((MainWindow*)parentWidget())->emu;
ui->debugValueList->clear();
for(uint8_t dRegs = 0; dRegs < 8; dRegs++)
ui->debugValueList->addItem("D" + stringFromNumber(dRegs, false, 0) + ":" + stringFromNumber(registers[dRegs], true, 8));
for(uint8_t aRegs = 0; aRegs < 8; aRegs++)
ui->debugValueList->addItem("A" + stringFromNumber(aRegs, false, 0) + ":" + stringFromNumber(registers[8 + aRegs], true, 8));
ui->debugValueList->addItem("SP:" + stringFromNumber(registers[15], true, 8));
ui->debugValueList->addItem("PC:" + stringFromNumber(registers[16], true, 8));
ui->debugValueList->addItem("SR:" + stringFromNumber(registers[17], true, 4));
ui->debugValueList->addItems(emu.debugGetCpuRegisterString().split('\n'));
}
void DebugViewer::on_debugShowDebugLogs_clicked(){
EmuWrapper& emu = ((MainWindow*)parentWidget())->emu;
std::vector<QString>& debugStrings = emu.getDebugStrings();
std::vector<uint64_t>& duplicateCallCount = emu.getDuplicateCallCount();
QVector<QString>& debugStrings = emu.debugGetLogEntrys();
QVector<uint64_t>& duplicateCallCount = emu.debugGetDuplicateLogEntryCount();
int64_t length = numberFromString(ui->debugLength->text(), true/*negative allowed*/);
ui->debugValueList->clear();
@@ -181,6 +164,6 @@ void DebugViewer::on_debugShowDebugLogs_clicked(){
void DebugViewer::on_debugEraseDebugLogs_clicked(){
EmuWrapper& emu = ((MainWindow*)parentWidget())->emu;
emu.getDebugStrings().clear();
emu.getDuplicateCallCount().clear();
emu.debugGetLogEntrys().clear();
emu.debugGetDuplicateLogEntryCount().clear();
}

View File

@@ -18,7 +18,6 @@ public:
private:
int64_t numberFromString(QString str, bool negativeAllowed);
QString stringFromNumber(int64_t number, bool hex, uint32_t forcedZeros = 0);
private slots:
void debugRadioButtonHandler();
@@ -29,7 +28,8 @@ private slots:
void on_debug16Bit_clicked();
void on_debug32Bit_clicked();
void on_debugDump_clicked();
void on_debugDumpToFile_clicked();
void on_debugDumpToTerminal_clicked();
void on_debugShowRegisters_clicked();
void on_debugShowDebugLogs_clicked();
void on_debugEraseDebugLogs_clicked();

View File

@@ -45,6 +45,16 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="1">
<widget class="QRadioButton" name="debug8Bit">
<property name="text">
<string>8bit</string>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="11">
<widget class="QListWidget" name="debugValueList"/>
</item>
<item row="2" column="2">
<widget class="QRadioButton" name="debug16Bit">
<property name="text">
@@ -52,6 +62,34 @@
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLineEdit" name="debugFilePath">
<property name="placeholderText">
<string>File Path</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="debugAddress">
<property name="placeholderText">
<string>Address</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QLineEdit" name="debugLength">
<property name="placeholderText">
<string>Length</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QRadioButton" name="debug32Bit">
<property name="text">
<string>32bit</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QPushButton" name="debugGetHexValues">
<property name="text">
@@ -62,26 +100,6 @@
</property>
</widget>
</item>
<item row="0" column="0" rowspan="10">
<widget class="QListWidget" name="debugValueList"/>
</item>
<item row="2" column="3">
<widget class="QRadioButton" name="debug32Bit">
<property name="text">
<string>32bit</string>
</property>
</widget>
</item>
<item row="9" column="1" colspan="3">
<widget class="QPushButton" name="debugDump">
<property name="text">
<string>Dump To File</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QPushButton" name="debugShowRegisters">
<property name="text">
@@ -89,37 +107,6 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QLineEdit" name="debugLength">
<property name="placeholderText">
<string>Length</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="debug8Bit">
<property name="text">
<string>8bit</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="3">
<widget class="QPushButton" name="debugEraseDebugLogs">
<property name="text">
<string>Erase Debug Logs</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLineEdit" name="debugFilePath">
<property name="placeholderText">
<string>File Path</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="3">
<widget class="QPushButton" name="debugShowDebugLogs">
<property name="text">
@@ -130,10 +117,33 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="debugAddress">
<property name="placeholderText">
<string>Address</string>
<item row="9" column="1" colspan="3">
<widget class="QPushButton" name="debugDumpToFile">
<property name="text">
<string>Dump To File</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="8" column="1" colspan="3">
<widget class="QPushButton" name="debugEraseDebugLogs">
<property name="text">
<string>Erase Debug Logs</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="10" column="1" colspan="3">
<widget class="QPushButton" name="debugDumpToTerminal">
<property name="text">
<string>Dump To Terminal</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>

View File

@@ -1,7 +1,8 @@
#include <QString>
#include <QPixmap>
#include <QImage>
#include <QVector>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QByteArray>
#include <QDateTime>
#include <QDate>
@@ -10,25 +11,33 @@
#include <new>
#include <chrono>
#include <thread>
#include <vector>
#include <string>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include "emuwrapper.h"
#include "../../src/emulator.h"
#include "../../src/fileLauncher/launcher.h"
extern "C"{
#include "../../src/flx68000.h"
#include "../../src/m68k/m68k.h"
#include "../../src/pxa260/pxa260.h"
#include "../../src/armv5te/disasm.h"
#include "../../src/debug/sandbox.h"
}
#define MAX_LOG_ENTRY_LENGTH 200
static bool alreadyExists = false;//there can only be one of this class since it wrappers C code
static std::vector<QString> debugStrings;
static std::vector<uint64_t> duplicateCallCount;
uint32_t frontendDebugStringSize;
char* frontendDebugString;
static QVector<QString> debugStrings;
static QVector<uint64_t> duplicateCallCount;
uint32_t frontendDebugStringSize;
char* frontendDebugString;
void frontendHandleDebugPrint(){
@@ -50,6 +59,18 @@ void frontendHandleDebugPrint(){
}
}
static void frontendGetCurrentTime(uint8_t* writeBack){
time_t rawTime;
struct tm* timeInfo;
time(&rawTime);
timeInfo = localtime(&rawTime);
writeBack[0] = timeInfo->tm_hour;
writeBack[1] = timeInfo->tm_min;
writeBack[2] = timeInfo->tm_sec;
}
EmuWrapper::EmuWrapper(){
if(alreadyExists == true)
@@ -62,8 +83,8 @@ EmuWrapper::EmuWrapper(){
emuPaused = false;
emuNewFrameReady = false;
frontendDebugString = new char[200];
frontendDebugStringSize = 200;
frontendDebugString = new char[MAX_LOG_ENTRY_LENGTH];
frontendDebugStringSize = MAX_LOG_ENTRY_LENGTH;
}
EmuWrapper::~EmuWrapper(){
@@ -74,6 +95,9 @@ EmuWrapper::~EmuWrapper(){
frontendDebugStringSize = 0;
debugStrings.clear();
duplicateCallCount.clear();
//allow creating a new emu class after the old one is closed
alreadyExists = false;
}
void EmuWrapper::emuThreadRun(){
@@ -90,100 +114,93 @@ void EmuWrapper::emuThreadRun(){
emuPaused = true;
}
std::this_thread::sleep_for(std::chrono::milliseconds(3));
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
uint32_t EmuWrapper::init(const QString& romPath, const QString& bootloaderPath, const QString& ramPath, const QString& sdCardPath, uint32_t features){
void EmuWrapper::writeOutSaves(){
if(emuRamFilePath != ""){
QFile ramFile(emuRamFilePath);
uint32_t emuRamSize = emulatorGetRamSize();
uint8_t* emuRamData = new uint8_t[emuRamSize];
emulatorSaveRam(emuRamData, emuRamSize);
//save out RAM before exit
if(ramFile.open(QFile::WriteOnly | QFile::Truncate)){
ramFile.write((const char*)emuRamData, emuRamSize);
ramFile.close();
}
delete[] emuRamData;
}
if(emuSdCardFilePath != ""){
uint32_t emuSdCardSize = emulatorGetSdCardSize();
uint8_t* emuSdCardData = new uint8_t[emuSdCardSize];
if(emulatorGetSdCardData(emuSdCardData, emuSdCardSize) == EMU_ERROR_NONE){
QFile sdCardFile(emuSdCardFilePath);
//save out SD card before exit
if(sdCardFile.open(QFile::WriteOnly | QFile::Truncate)){
sdCardFile.write((const char*)emuSdCardData, emuSdCardSize);
sdCardFile.close();
}
}
}
}
uint32_t EmuWrapper::init(const QString& assetPath, uint8_t osVersion, bool syncRtc, bool allowInvalidBehavior, bool fastBoot){
if(!emuRunning && !emuInited){
//start emu
uint32_t error;
QFile romFile(romPath);
QFile bootloaderFile(bootloaderPath);
QByteArray romData;
QByteArray bootloaderData;
buffer_t romBuff;
buffer_t bootloaderBuff;
QString osVersionId = osVersion == 4 ? "41" : osVersion == 5 ? "52" : QString::number((int)osVersion) + "0";
QString model = osVersion > 4 ? "en-t3" : "en-m515";
QFile romFile(assetPath + "/palmos" + osVersionId + "-" + model + ".rom");
QFile bootloaderFile(assetPath + "/bootloader-" + model + ".rom");
QFile ramFile(assetPath + "/userdata-" + model + ".ram");
QFile sdCardFile(assetPath + "/sd-" + model + ".img");
bool hasBootloader = true;
if(romFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
romData = romFile.readAll();
romFile.close();
//used to mark saves with there OS version and prevent corruption
emuOsName = "os" + QString::number((int)osVersion);
romBuff.data = (uint8_t*)romData.data();
romBuff.size = romData.size();
}
else{
if(!romFile.open(QFile::ReadOnly | QFile::ExistingOnly))
return EMU_ERROR_INVALID_PARAMETER;
}
if(bootloaderPath != ""){
if(bootloaderFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
bootloaderData = bootloaderFile.readAll();
bootloaderFile.close();
if(!bootloaderFile.open(QFile::ReadOnly | QFile::ExistingOnly))
hasBootloader = false;
bootloaderBuff.data = (uint8_t*)bootloaderData.data();
bootloaderBuff.size = bootloaderData.size();
}
else{
return EMU_ERROR_INVALID_PARAMETER;
}
}
else{
bootloaderBuff.data = NULL;
bootloaderBuff.size = 0;
}
error = emulatorInit(romBuff, bootloaderBuff, features);
error = emulatorInit((uint8_t*)romFile.readAll().data(), romFile.size(), hasBootloader ? (uint8_t*)bootloaderFile.readAll().data() : NULL, hasBootloader ? bootloaderFile.size() : 0, syncRtc, allowInvalidBehavior);
if(error == EMU_ERROR_NONE){
QTime now = QTime::currentTime();
palmGetRtcFromHost = frontendGetCurrentTime;
emulatorSetRtc(QDate::currentDate().day(), now.hour(), now.minute(), now.second());
if(ramPath != ""){
QFile ramFile(ramPath);
if(ramFile.exists()){
if(ramFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QByteArray ramData;
buffer_t emuRam;
ramData = ramFile.readAll();
ramFile.close();
emuRam.data = (uint8_t*)ramData.data();
emuRam.size = ramData.size();
//only copy in data if its the correct size, the file will be overwritten on exit with the devices RAM either way
//(changing RAM size requires a factory reset for now and always will when going from 128mb back to 16mb)
if(emuRam.size == emulatorGetRamSize())
emulatorLoadRam(emuRam);
}
}
if(ramFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
emulatorLoadRam((uint8_t*)ramFile.readAll().data(), ramFile.size());
ramFile.close();
}
if(sdCardPath != ""){
QFile sdCardFile(sdCardPath);
if(sdCardFile.exists()){
if(sdCardFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QByteArray sdCardData;
buffer_t newSdCard;
sdCardData = sdCardFile.readAll();
sdCardFile.close();
newSdCard.data = (uint8_t*)sdCardData.data();
newSdCard.size = sdCardData.size();
emulatorInsertSdCard(newSdCard, false);
}
}
if(sdCardFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
emulatorInsertSdCard((uint8_t*)sdCardFile.readAll().data(), sdCardFile.size(), NULL);
sdCardFile.close();
}
emuInput = palmInput;
emuRamFilePath = ramPath;
emuSdCardFilePath = sdCardPath;
emuRamFilePath = assetPath + "/userdata-" + model + ".ram";
emuSdCardFilePath = assetPath + "/sd-" + model + ".img";
emuSaveStatePath = assetPath + "/states-" + model + ".states";
//make the place to store the saves
QDir(emuSaveStatePath).mkdir(".");
//skip the boot screen
if(fastBoot)
launcherBootInstantly(ramFile.exists());
//start the thread
emuThreadJoin = false;
emuInited = true;
emuRunning = true;
@@ -194,6 +211,9 @@ uint32_t EmuWrapper::init(const QString& romPath, const QString& bootloaderPath,
else{
return error;
}
romFile.close();
bootloaderFile.close();
}
return EMU_ERROR_NONE;
@@ -205,36 +225,8 @@ void EmuWrapper::exit(){
if(emuThread.joinable())
emuThread.join();
if(emuInited){
if(emuRamFilePath != ""){
QFile ramFile(emuRamFilePath);
buffer_t emuRam;
emuRam.size = emulatorGetRamSize();
emuRam.data = new uint8_t[emuRam.size];
emulatorSaveRam(emuRam);
//save out RAM before exit
if(ramFile.open(QFile::WriteOnly | QFile::Truncate)){
ramFile.write((const char*)emuRam.data, emuRam.size);
ramFile.close();
}
delete[] emuRam.data;
}
if(emuSdCardFilePath != ""){
buffer_t emuSdCard = emulatorGetSdCardBuffer();
if(emuSdCard.data){
QFile sdCardFile(emuSdCardFilePath);
//save out SD card before exit
if(sdCardFile.open(QFile::WriteOnly | QFile::Truncate)){
sdCardFile.write((const char*)emuSdCard.data, emuSdCard.size);
sdCardFile.close();
}
}
}
emulatorExit();
writeOutSaves();
emulatorDeinit();
}
}
@@ -271,23 +263,146 @@ void EmuWrapper::reset(bool hard){
}
}
uint32_t EmuWrapper::saveState(const QString& path){
void EmuWrapper::setCpuSpeed(double speed){
if(emuInited){
bool wasPaused = isPaused();
if(!wasPaused)
pause();
emulatorSetCpuSpeed(speed);
if(!wasPaused)
resume();
}
}
uint32_t EmuWrapper::bootFromFile(const QString& mainPath){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_NONE;
QFileInfo pathInfo(mainPath);
QFile appFile(mainPath);
QFile ramFile(mainPath + "." + emuOsName + ".ram");
QFile sdCardFile(mainPath + "." + emuOsName + ".sd.img");
QString suffix = QFileInfo(mainPath).suffix().toLower();
bool hasSaveRam;
bool hasSaveSdCard;
if(!wasPaused)
pause();
//save the current data for the last program launched, or the standard device image if none where launched
writeOutSaves();
//its OK if these fail, the buffer will just be NULL, 0 if they do
hasSaveRam = ramFile.open(QFile::ReadOnly | QFile::ExistingOnly);
hasSaveSdCard = suffix != "img" ? sdCardFile.open(QFile::ReadOnly | QFile::ExistingOnly) : false;
//fully clear the emu
emulatorEjectSdCard();
emulatorHardReset();
if(hasSaveRam)
emulatorLoadRam((uint8_t*)ramFile.readAll().data(), ramFile.size());
if(hasSaveSdCard)
emulatorInsertSdCard((uint8_t*)sdCardFile.readAll().data(), sdCardFile.size(), NULL);
//its OK if these fail
if(hasSaveRam)
ramFile.close();
if(hasSaveSdCard)
sdCardFile.close();
launcherBootInstantly(hasSaveRam);
if(appFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
QByteArray fileBuffer = appFile.readAll();
appFile.close();
if(suffix == "img"){
QFile infoFile(mainPath.mid(0, mainPath.length() - 3) + "info");//swap "img" for "info"
sd_card_info_t sdInfo;
memset(&sdInfo, 0x00, sizeof(sdInfo));
if(infoFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
launcherGetSdCardInfoFromInfoFile((uint8_t*)infoFile.readAll().data(), infoFile.size(), &sdInfo);
infoFile.close();
}
error = emulatorInsertSdCard((uint8_t*)fileBuffer.data(), fileBuffer.size(), &sdInfo);
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
else{
if(!hasSaveRam){
error = launcherInstallFile((uint8_t*)fileBuffer.data(), fileBuffer.size());
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
error = launcherExecute(launcherGetAppId((uint8_t*)fileBuffer.data(), fileBuffer.size()));
if(error != EMU_ERROR_NONE)
goto errorOccurred;
}
}
//everything worked, set output save files
emuRamFilePath = mainPath + "." + emuOsName + ".ram";
emuSdCardFilePath = suffix != "img" ? mainPath + "." + emuOsName + ".sd.img" : "";//dont duplicate booted SD card images
emuSaveStatePath = mainPath + "." + emuOsName + ".states";
//make the place to store the saves
QDir(emuSaveStatePath).mkdir(".");
//need this goto because the emulator must be released before returning
errorOccurred:
if(error != EMU_ERROR_NONE){
//try and recover from error
emulatorEjectSdCard();
emulatorHardReset();
}
if(!wasPaused)
resume();
return error;
}
uint32_t EmuWrapper::installApplication(const QString& path){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_INVALID_PARAMETER;
QFile stateFile(path);
QFile appFile(path);
if(!wasPaused)
pause();
if(appFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
error = launcherInstallFile((uint8_t*)appFile.readAll().data(), appFile.size());
appFile.close();
}
if(!wasPaused)
resume();
return error;
}
uint32_t EmuWrapper::saveState(const QString& name){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_INVALID_PARAMETER;
QFile stateFile(emuSaveStatePath + "/" + name + ".state");
if(!wasPaused)
pause();
//save here
if(stateFile.open(QFile::WriteOnly)){
buffer_t stateData;
uint32_t stateSize = emulatorGetStateSize();
uint8_t* stateData = new uint8_t[stateSize];
stateData.size = emulatorGetStateSize();
stateData.data = new uint8_t[stateData.size];
emulatorSaveState(stateData);//no need to check for errors since the buffer is always the right size
stateFile.write((const char*)stateData.data, stateData.size);
emulatorSaveState(stateData, stateSize);//no need to check for errors since the buffer is always the right size
stateFile.write((const char*)stateData, stateSize);
stateFile.close();
error = EMU_ERROR_NONE;
@@ -299,25 +414,19 @@ uint32_t EmuWrapper::saveState(const QString& path){
return error;
}
uint32_t EmuWrapper::loadState(const QString& path){
uint32_t EmuWrapper::loadState(const QString& name){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_INVALID_PARAMETER;
QFile stateFile(path);
QFile stateFile(emuSaveStatePath + "/" + name + ".state");
if(!wasPaused)
pause();
if(stateFile.open(QFile::ReadOnly)){
QByteArray stateDataBuffer;
buffer_t stateData;
stateDataBuffer = stateFile.readAll();
stateFile.close();
stateData.data = (uint8_t*)stateDataBuffer.data();
stateData.size = stateDataBuffer.size();
if(emulatorLoadState(stateData))
if(stateFile.open(QFile::ReadOnly | QFile::ExistingOnly)){
if(emulatorLoadState((uint8_t*)stateFile.readAll().data(), stateFile.size()))
error = EMU_ERROR_NONE;
stateFile.close();
}
if(!wasPaused)
@@ -370,6 +479,10 @@ void EmuWrapper::setKeyValue(uint8_t key, bool pressed){
emuInput.buttonNotes = pressed;
break;
case BUTTON_VOICE_MEMO:
emuInput.buttonVoiceMemo = pressed;
break;
case BUTTON_POWER:
emuInput.buttonPower = pressed;
break;
@@ -379,47 +492,56 @@ void EmuWrapper::setKeyValue(uint8_t key, bool pressed){
}
}
uint32_t EmuWrapper::installApplication(const QString& path){
bool wasPaused = isPaused();
uint32_t error = EMU_ERROR_INVALID_PARAMETER;
QFile appFile(path);
if(!wasPaused)
pause();
if(appFile.open(QFile::ReadOnly)){
QByteArray appDataBuffer;
buffer_t appData;
appDataBuffer = appFile.readAll();
appFile.close();
appData.data = (uint8_t*)appDataBuffer.data();
appData.size = appDataBuffer.size();
error = sandboxCommand(SANDBOX_CMD_DEBUG_INSTALL_APP, &appData);
}
if(!wasPaused)
resume();
return error;
}
std::vector<QString>& EmuWrapper::getDebugStrings(){
QVector<QString>& EmuWrapper::debugGetLogEntrys(){
return debugStrings;
}
std::vector<uint64_t>& EmuWrapper::getDuplicateCallCount(){
QVector<uint64_t>& EmuWrapper::debugGetDuplicateLogEntryCount(){
return duplicateCallCount;
}
std::vector<uint32_t> EmuWrapper::getCpuRegisters(){
std::vector<uint32_t> registers;
QString EmuWrapper::debugGetCpuRegisterString(){
QString regString = "";
for(uint8_t reg = 0; reg < 18; reg++)
registers.push_back(flx68000GetRegister(reg));
return registers;
if(palmEmulatingTungstenT3){
for(uint8_t regs = 0; regs < 16; regs++)
regString += QString::asprintf("R%d:0x%08X\n", regs, pxa260GetRegister(regs));
regString += QString::asprintf("SP:0x%08X\n", pxa260GetRegister(13));
regString += QString::asprintf("LR:0x%08X\n", pxa260GetRegister(14));
regString += QString::asprintf("PC:0x%08X\n", pxa260GetPc());
regString += QString::asprintf("CPSR:0x%08X\n", pxa260GetCpsr());
regString += QString::asprintf("SPSR:0x%08X", pxa260GetSpsr());
}
else{
for(uint8_t dRegs = 0; dRegs < 8; dRegs++)
regString += QString::asprintf("D%d:0x%08X\n", dRegs, flx68000GetRegister(dRegs));
for(uint8_t aRegs = 0; aRegs < 8; aRegs++)
regString += QString::asprintf("A%d:0x%08X\n", aRegs, flx68000GetRegister(8 + aRegs));
regString += QString::asprintf("SP:0x%08X\n", flx68000GetRegister(15));
regString += QString::asprintf("PC:0x%08X\n", flx68000GetPc());
regString += QString::asprintf("SR:0x%04X", flx68000GetStatusRegister());
}
return regString;
}
uint64_t EmuWrapper::getEmulatorMemory(uint32_t address, uint8_t size){
uint64_t EmuWrapper::debugGetEmulatorMemory(uint32_t address, uint8_t size){
if(palmEmulatingTungstenT3)
return pxa260ReadArbitraryMemory(address, size);
return flx68000ReadArbitraryMemory(address, size);
}
QString EmuWrapper::debugGetEmulatorDisassemble(uint32_t address, uint32_t opcodes){
QString output = "";
if(palmEmulatingTungstenT3){
}
else{
for(uint32_t index = 0; index < opcodes; index++){
}
}
return output;
}

View File

@@ -1,12 +1,12 @@
#pragma once
#include <QPixmap>
#include <QImage>
#include <QVector>
#include <QString>
#include <QByteArray>
#include <thread>
#include <atomic>
#include <vector>
#include <stdint.h>
#include "../../src/emulator.h"
@@ -22,11 +22,14 @@ private:
std::atomic<bool> emuRunning;
std::atomic<bool> emuPaused;
std::atomic<bool> emuNewFrameReady;
QString emuOsName;
QString emuRamFilePath;
QString emuSdCardFilePath;
QString emuSaveStatePath;
input_t emuInput;
void emuThreadRun();
void writeOutSaves();
public:
enum{
@@ -39,6 +42,7 @@ public:
BUTTON_ADDRESS,
BUTTON_TODO,
BUTTON_NOTES,
BUTTON_VOICE_MEMO,
BUTTON_POWER,
BUTTON_TOTAL_COUNT
};
@@ -46,34 +50,36 @@ public:
EmuWrapper();
~EmuWrapper();
uint32_t init(const QString& romPath, const QString& bootloaderPath = "", const QString& ramPath = "", const QString& sdCardPath = "", uint32_t features = FEATURE_ACCURATE);
uint32_t init(const QString& assetPath, uint8_t osVersion, bool syncRtc = false, bool allowInvalidBehavior = false, bool fastBoot = false);
void exit();
void pause();
void resume();
void reset(bool hard);
uint32_t saveState(const QString& path);
uint32_t loadState(const QString& path);
void setCpuSpeed(double speed);
uint32_t bootFromFile(const QString& mainPath);
uint32_t installApplication(const QString& path);
const QString& getStatePath() const{return emuSaveStatePath;}//needed for looking up state pictures in the GUI
uint32_t saveState(const QString& name);
uint32_t loadState(const QString& name);
bool isInited() const{return emuInited;}
bool isRunning() const{return emuRunning;}
bool isPaused() const{return emuPaused;}
void setPenValue(float x, float y, bool touched);
void setKeyValue(uint8_t key, bool pressed);
uint32_t installApplication(const QString& path);
std::vector<QString>& getDebugStrings();
std::vector<uint64_t>& getDuplicateCallCount();
std::vector<uint32_t> getCpuRegisters();
uint16_t screenWidth() const{return palmFramebufferWidth;}
uint16_t screenHeight() const{return palmFramebufferHeight;}
bool newFrameReady() const{return emuNewFrameReady;}
void frameHandled(){emuNewFrameReady = false;}
//calling these while newFrameReady() == false is undefined behavior, the other thread may be writing to them
const QPixmap getFramebuffer(){return QPixmap::fromImage(QImage((uchar*)palmFramebuffer, palmFramebufferWidth, palmFramebufferHeight, palmFramebufferWidth * sizeof(uint16_t), QImage::Format_RGB16));}
const QImage getFramebufferImage(){return QImage((uchar*)palmFramebuffer, palmFramebufferWidth, palmFramebufferHeight, palmFramebufferWidth * sizeof(uint16_t), QImage::Format_RGB16);}
const int16_t* getAudioSamples() const{return palmAudio;}
bool getPowerButtonLed() const{return palmMisc.powerButtonLed;}
bool getPowerButtonLed() const{return palmMisc.greenLed;}
uint64_t getEmulatorMemory(uint32_t address, uint8_t size);
QVector<QString>& debugGetLogEntrys();
QVector<uint64_t>& debugGetDuplicateLogEntryCount();
QString debugGetCpuRegisterString();
uint64_t debugGetEmulatorMemory(uint32_t address, uint8_t size);
QString debugGetEmulatorDisassemble(uint32_t address, uint32_t opcodes);
};

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="24.837" cy="36.421" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.645"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="21.929" cy="-3.218" gradientTransform="matrix(3.658819 0 0 2.080782 -62.4164 12.76204)" gradientUnits="userSpaceOnUse" r="13"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="22.5" cy="28.116" gradientTransform="matrix(2.365562 0 0 2.202845 -30.72517 -34.23996)" gradientUnits="userSpaceOnUse" r="14.538"><stop offset="0" stop-color="#ef2929"/><stop offset="1" stop-color="#c00"/></radialGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="21.702" x2="21.816" y1="8.912" y2="35.546"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".784"/></linearGradient><g fill-rule="evenodd"><path d="m36.5 22a14 13 0 1 1 -28 0 14 13 0 1 1 28 0z" style="opacity:.15;stroke-width:3.136616;stroke-linecap:square;stroke-linejoin:round;stroke:url(#d);fill:url(#c)" transform="matrix(.920697 0 0 .99358 3.679484 1.641236)"/><path d="m40.481863 36.421127a15.644737 8.3968935 0 1 1 -31.2894745 0 15.644737 8.3968935 0 1 1 31.2894745 0z" fill="url(#a)" opacity=".04" transform="matrix(1.150533 0 0 .565685 -4.5765 16.55285)"/><path d="m36.5 22a14 13 0 1 1 -28 0 14 13 0 1 1 28 0z" fill="url(#c)" stroke="#c00" stroke-linecap="square" stroke-linejoin="round" stroke-width="1.076" transform="matrix(.894862 0 0 .9657 3.855776 2.660348)"/></g><path d="m38 24a14 14 0 1 1 -28 0 14 14 0 1 1 28 0z" fill="none" stroke="#f77d7d" stroke-linecap="square" stroke-linejoin="round" stroke-width="1.217" transform="matrix(.821429 0 0 .821429 4.285117 4.191455)"/><path d="m23.84315 11.90574c-6.279532.079595-11.404423 4.992059-11.8125 11.1875 6.117823 2.51678 13.87042-1.451223 23.142005-3.381886-.68841-2.748569-4.55472-7.805614-11.173255-7.805614-.051707 0-.104697-.000653-.15625 0z" fill="url(#b)" fill-rule="evenodd" opacity=".6"/></svg>
<svg height="32.880508" width="35.999573" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="22.5" cy="28.115999" gradientTransform="matrix(2.365562 0 0 2.202845 -30.72517 -34.23996)" gradientUnits="userSpaceOnUse" r="14.538"><stop offset="0" stop-color="#ef2929"/><stop offset="1" stop-color="#c00"/></radialGradient><radialGradient id="b" cx="24.837" cy="36.421001" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.645"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="21.929001" cy="-3.218" gradientTransform="matrix(3.658819 0 0 2.080782 -68.416046 3.736818)" gradientUnits="userSpaceOnUse" r="13"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="21.702" x2="21.816" y1="8.912" y2="35.546001"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".784"/></linearGradient><g fill-rule="evenodd" transform="translate(-5.999646 -9.025222)"><path d="m36.5 22a14 13 0 1 1 -28 0 14 13 0 1 1 28 0z" style="opacity:.15;stroke-width:3.136616;stroke-linecap:square;stroke-linejoin:round;fill:url(#a);stroke:url(#d)" transform="matrix(.920697 0 0 .99358 3.679484 1.641236)"/><path d="m40.481863 36.421127a15.644737 8.3968937 0 1 1 -31.2894745 0 15.644737 8.3968937 0 1 1 31.2894745 0z" fill="url(#b)" opacity=".04" transform="matrix(1.150533 0 0 .565685 -4.5765 16.55285)"/><path d="m36.5 22a14 13 0 1 1 -28 0 14 13 0 1 1 28 0z" fill="url(#a)" stroke="#c00" stroke-linecap="square" stroke-linejoin="round" stroke-width="1.076" transform="matrix(.894862 0 0 .9657 3.855776 2.660348)"/></g><path d="m29.499773 14.880529a11.500006 11.500006 0 1 1 -23.0000123 0 11.500006 11.500006 0 1 1 23.0000123 0z" fill="none" stroke="#f77d7d" stroke-linecap="square" stroke-linejoin="round" stroke-width=".999679"/><path d="m17.843504 2.8805179c-6.279532.07959-11.4044233 4.992059-11.8125003 11.1875001 6.1178233 2.51678 13.8704203-1.451223 23.1420053-3.381886-.68841-2.7485691-4.55472-7.8056141-11.173255-7.8056141-.05171 0-.104697-.000653-.15625 0z" fill="url(#c)" fill-rule="evenodd" opacity=".6"/></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="35.292667" cy="20.494493" gradientTransform="matrix(0 -.843022 1.020168 0 .606436 42.58614)" gradientUnits="userSpaceOnUse" r="16.956199"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><radialGradient id="c" cx="15.987216" cy="1.535031" gradientTransform="matrix(0 -2.046729 -1.55761 0 44.11559 66.93275)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><path d="m40.481863 36.421127a15.644737 8.3968935 0 1 1 -31.2894745 0 15.644737 8.3968935 0 1 1 31.2894745 0z" fill="url(#a)" fill-rule="evenodd" opacity=".204545" transform="matrix(1.214466 0 0 .595458 -6.163846 16.31275)"/><g transform="matrix(-1 0 0 -1 47.02856 43.99921)"><path d="m14.519136 38.5 18.005029-.003906v-12.991626l7.995366-.007812-17.144722-19.9974425-16.8462505 19.9980705 7.9958815.00379-.005304 12.998926z" style="fill-rule:evenodd;stroke:#3a7304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill:url(#b)"/><path d="m39.429889 24.993467-7.406391.011719.002681 12.992837-15.378556-.009153c.769922-18.34099 10.722649-10.993073 15.381659-21.646879z" fill="url(#c)" fill-rule="evenodd" opacity=".508021"/><path d="m15.520704 37.496094 16.001405.003906v-12.99295l6.816811-.015625-14.954276-17.4525854-14.7065267 17.4569424 6.8399007.005247z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></g></svg>
<svg height="38.00079" width="38.000004" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="24.837126" cy="36.421127" gradientTransform="matrix(1.214466 0 0 .319596 -11.163843 21.360739)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="35.292667" cy="20.494493" gradientTransform="matrix(0 -.843022 1.020168 0 .606436 42.58614)" gradientUnits="userSpaceOnUse" r="16.9562"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><radialGradient id="c" cx="15.987216" cy="1.535031" gradientTransform="matrix(0 -2.046729 -1.55761 0 44.11559 66.93275)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><path d="m38.000003 33.000791a19.000001 4.9999976 0 1 1 -38.000003 0 19.000001 4.9999976 0 1 1 38.000003 0z" fill="url(#a)" fill-rule="evenodd" opacity=".204545" stroke-width=".85039"/><g transform="matrix(-1 0 0 -1 42.028562 39)"><path d="m14.519136 38.5 18.005029-.0039v-12.991632l7.995366-.0078-17.144722-19.9974545-16.8462505 19.9980705 7.9958815.0038z" style="fill-rule:evenodd;stroke:#3a7304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill:url(#b)"/><path d="m39.429889 24.993467-7.406391.01172.0027 12.992837-15.378556-.0092c.769903-18.340944 10.72263-10.993027 15.38164-21.646833z" fill="url(#c)" fill-rule="evenodd" opacity=".508021"/><path d="m15.520704 37.496094 16.001405.003906v-12.99295l6.816811-.015625-14.954276-17.4525854-14.7065267 17.4569424 6.8399007.0052z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="25.075571" cy="5.78598" gradientTransform="matrix(-2.046729 0 0 1.55761 67.59375 3.275309)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="22.291636" cy="32.797512" gradientTransform="matrix(-.843022 0 0 1.020168 43.57646 1.205215)" gradientUnits="userSpaceOnUse" r="16.956199"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><g fill-rule="evenodd"><path d="m40.481863 36.421127a15.644737 8.3968935 0 1 1 -31.2894745 0 15.644737 8.3968935 0 1 1 31.2894745 0z" fill="url(#b)" opacity=".299465" transform="matrix(-1.271186 0 0 1.271186 56.19514 -15.27857)"/><path d="m39.490316 15.496821v16.99442h-12.952563v8.482538l-19.959836-17.000191 19.953646-17.2439979v8.7725349z" fill="url(#c)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m25.988368 7.9779766v8.0564744h12.94217v8.884463c-16.75-6.25-16.133537 5.294712-31.383538-.955288z" fill="url(#a)" opacity=".508021"/></g><path d="m38.475551 16.541365v14.92194h-12.985367v7.301416l-17.321765-14.795691 17.337726-14.9054001v7.4826321z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>
<svg height="35.463821" width="39.774742" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="25.075571" cy="5.78598" gradientTransform="matrix(-2.046729 0 0 1.55761 67.59375 3.275309)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="22.291636" cy="32.797512" gradientTransform="matrix(-.843022 0 0 1.020168 43.57646 1.205215)" gradientUnits="userSpaceOnUse" r="16.9562"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><g fill-rule="evenodd" transform="translate(-4.735163 -6.229649)"><path d="m40.481863 36.421127a15.644737 8.3968937 0 1 1 -31.2894745 0 15.644737 8.3968937 0 1 1 31.2894745 0z" fill="url(#b)" opacity=".299465" transform="matrix(-1.271186 0 0 1.271186 56.19514 -15.27857)"/><path d="m39.490316 15.496821v16.99442h-12.952563v8.482538l-19.959836-17.000191 19.953646-17.2439979v8.7725349z" fill="url(#c)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m25.988368 7.9779766v8.0564744h12.94217v8.884463c-16.75-6.25-16.133537 5.294712-31.383538-.955288z" fill="url(#a)" opacity=".508021"/></g><path d="m33.740388 10.311716v14.92194h-12.985367v7.301416l-17.3217645-14.795691 17.3377255-14.9054005v7.4826325z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="15.089121" x2="13.9996" y1="15.197734" y2="52.416314"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientTransform="matrix(1 0 0 1.004384 -145.0004 -71.4625)" gradientUnits="userSpaceOnUse" x1="169" x2="169" y1="110.33805" y2="93.204849"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="c" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000356 -1.07205 1.992104 -.00000125 -175.6121 212.6949)" gradientUnits="userSpaceOnUse" r="11"><stop offset="0" stop-color="#f7f7f7"/><stop offset="1" stop-color="#ccd0c7"/></radialGradient><linearGradient id="d" gradientTransform="matrix(1.103262 0 0 1.054917 -163.1228 -76.31138)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" y1="84.263489" y2="105.49083"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".484536"/></linearGradient><path d="m26.086565 12.829103v22.153256h8.826093v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#d)"/><path d="m26.4996 13.40575v21h8v-21z" fill="url(#c)" fill-rule="evenodd"/><path d="m26.4996 13.407946v21.092064h8v-21.092064z" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round"/><path d="m27.4996 14.40575v19h6v-19z" fill="none" stroke="url(#a)" stroke-linecap="square"/><path d="m28.019106 14.942758v8.385631l4.993942-.618719v-7.8553z" display="block" fill="#f7f7f7" opacity=".5"/><g transform="translate(-12.97229)"><path d="m26.086565 12.829103v22.153256h8.826093v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#d)"/><path d="m26.4996 13.40575v21h8v-21z" fill="url(#c)" fill-rule="evenodd"/><path d="m26.4996 13.407946v21.092064h8v-21.092064z" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round"/><path d="m27.4996 14.40575v19h6v-19z" fill="none" stroke="url(#a)" stroke-linecap="square"/><path d="m28.019106 14.942758v10.06501l4.993942-.618719v-9.534679z" display="block" fill="#f7f7f7" opacity=".5"/></g></svg>
<svg height="24.153255" width="23.798384" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(1.103262 0 0 1.054917 -175.23707 -88.140483)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" xlink:href="#l" y1="84.263489" y2="105.49083"/><radialGradient id="b" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000356 -1.07205 1.992104 -.00000125 -187.72637 200.8658)" gradientUnits="userSpaceOnUse" r="11" xlink:href="#k"/><linearGradient id="c" gradientTransform="matrix(1 0 0 1.004384 -157.11467 -83.291603)" gradientUnits="userSpaceOnUse" x1="169" x2="169" xlink:href="#j" y1="110.33805" y2="93.204849"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="2.974846" x2="1.885325" xlink:href="#i" y1="3.368631" y2="40.58721"/><linearGradient id="e" gradientTransform="matrix(1.103262 0 0 1.054917 -163.1228 -76.31138)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" xlink:href="#l" y1="84.263489" y2="105.49083"/><radialGradient id="f" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000356 -1.07205 1.992104 -.00000125 -175.6121 212.6949)" gradientUnits="userSpaceOnUse" r="11" xlink:href="#k"/><linearGradient id="g" gradientTransform="matrix(1 0 0 1.004384 -145.0004 -71.4625)" gradientUnits="userSpaceOnUse" x1="169" x2="169" xlink:href="#j" y1="110.33805" y2="93.204849"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="15.089121" x2="13.9996" xlink:href="#i" y1="15.197734" y2="52.416313"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="15.089121" x2="13.9996" y1="15.197734" y2="52.416313"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="j" gradientTransform="matrix(1 0 0 1.004384 -145.0004 -71.4625)" gradientUnits="userSpaceOnUse" x1="169" x2="169" y1="110.33805" y2="93.204849"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="k" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000356 -1.07205 1.992104 -.00000125 -175.6121 212.6949)" gradientUnits="userSpaceOnUse" r="11"><stop offset="0" stop-color="#f7f7f7"/><stop offset="1" stop-color="#ccd0c7"/></radialGradient><linearGradient id="l" gradientTransform="matrix(1.103262 0 0 1.054917 -163.1228 -76.31138)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" y1="84.263489" y2="105.49083"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".484536"/></linearGradient><path d="m13.97229 1v22.153256h8.826093v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#a)"/><path d="m14.385325 1.576647v21h8v-21z" fill="url(#b)" fill-rule="evenodd"/><path d="m14.385325 1.578843v21.092064h8v-21.092064z" fill="none" stroke="url(#c)" stroke-linecap="square" stroke-linejoin="round"/><path d="m15.385325 2.576647v19h6v-19z" fill="none" stroke="url(#d)" stroke-linecap="square"/><path d="m15.904831 3.113655v8.385631l4.993942-.618719v-7.8553z" display="block" fill="#f7f7f7" opacity=".5"/><g transform="translate(-25.086565 -11.829103)"><path d="m26.086565 12.829103v22.153256h8.826093v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#e)"/><path d="m26.4996 13.40575v21h8v-21z" fill="url(#f)" fill-rule="evenodd"/><path d="m26.4996 13.407946v21.092064h8v-21.092064z" fill="none" stroke="url(#g)" stroke-linecap="square" stroke-linejoin="round"/><path d="m27.4996 14.40575v19h6v-19z" fill="none" stroke="url(#h)" stroke-linecap="square"/><path d="m28.019106 14.942758v10.06501l4.993942-.618719v-9.534679z" display="block" fill="#f7f7f7" opacity=".5"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="26.288536" x2="25.826522" y1="53.02227" y2="23.90575"><stop offset="0" stop-color="#adb0a8"/><stop offset="1" stop-color="#464744"/></linearGradient><radialGradient id="b" cx="107.5884" cy="83.990814" gradientTransform="matrix(.05324342 -.836238 2.019473 .128568 -151.9195 108.0768)" gradientUnits="userSpaceOnUse" r="12.551644"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d3d7cf"/></radialGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="26.010638" x2="26.053493" y1="31.42276" y2="16.961972"><stop offset="0" stop-color="#fff"/><stop offset="1"/></linearGradient><path d="m12 39.5v-30.5l26.06998 14.817079z" style="fill:none;stroke-width:1.999998;stroke-linecap:square;stroke-linejoin:round;opacity:.15;stroke:url(#c)"/><path d="m12.49946 37.81149v-27.811485l24.103287 13.905743z" fill="url(#b)" fill-rule="evenodd"/><path d="m12.49946 37.81149v-27.811485l24.103287 13.905743z" fill="none" stroke="url(#a)" stroke-linecap="square" stroke-linejoin="round"/><g fill="#fff"><path d="m12.99946 10.87449v26.0625l22.59375-13.03125zm1 1.75 19.5625 11.28125-19.5625 11.28125z" fill-rule="evenodd"/><path d="m13.9375 12.5625v11.6875c4.269198-.044785 9.164156-.345564 17.0625-1.875z" display="block" opacity=".5"/></g></svg>
<svg height="32.499847" width="28.06988" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="15.288535" x2="14.826522" y1="45.022197" y2="15.905677"><stop offset="0" stop-color="#adb0a8"/><stop offset="1" stop-color="#464744"/></linearGradient><radialGradient id="b" cx="107.5884" cy="83.990814" gradientTransform="matrix(.05324342 -.836238 2.019473 .128568 -162.9195 100.07673)" gradientUnits="userSpaceOnUse" r="12.551644"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d3d7cf"/></radialGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="15.010636" x2="15.053492" y1="23.422687" y2="8.961898"><stop offset="0" stop-color="#fff"/><stop offset="1"/></linearGradient><path d="m.99999899 31.499927v-30.49999985l26.06998001 14.81707885z" style="opacity:.15;fill:none;stroke-width:1.999998;stroke-linecap:square;stroke-linejoin:round;stroke:url(#c)"/><path d="m1.499459 29.811417v-27.8114848l24.103287 13.9057428z" fill="url(#b)" fill-rule="evenodd"/><path d="m1.499459 29.811417v-27.8114848l24.103287 13.9057428z" fill="none" stroke="url(#a)" stroke-linecap="square" stroke-linejoin="round"/><g fill="#fff" transform="translate(-11.000001 -8.000073)"><path d="m12.99946 10.87449v26.0625l22.59375-13.03125zm1 1.75 19.5625 11.28125-19.5625 11.28125z" fill-rule="evenodd"/><path d="m13.9375 12.5625v11.6875c4.269198-.044785 9.164156-.345564 17.0625-1.875z" display="block" opacity=".5"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.714" cy="486.648" gradientTransform="matrix(-2.774389 0 0 1.969706 112.7623 -872.8854)" gradientUnits="userSpaceOnUse" r="117.143" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.714" cy="486.648" gradientTransform="matrix(2.774389 0 0 1.969706 -1891.633 -872.8854)" gradientUnits="userSpaceOnUse" r="117.143" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(2.774389 0 0 1.969706 -1892.179 -872.8854)" gradientUnits="userSpaceOnUse" x1="302.857" x2="302.857" y1="366.648" y2="609.505"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d1d1d1"/></linearGradient><linearGradient id="f"><stop offset="0" stop-color="#fbfbfb"/><stop offset="1" stop-color="#dcdcdc"/></linearGradient><radialGradient id="g" cx="24.446" cy="35.878" gradientTransform="matrix(1.995058 0 0 1.855412 -24.37145 -30.2043)" gradientUnits="userSpaceOnUse" r="20.531" xlink:href="#f"/><linearGradient id="h" gradientTransform="matrix(1.045319 0 0 .957884 -1.154429 1.415543)" gradientUnits="userSpaceOnUse" x1="20.092" x2="31.799" xlink:href="#e" y1="8.947" y2="38.947"/><linearGradient id="i" gradientTransform="matrix(.984324 0 0 .957884 .336637 1.415543)" gradientUnits="userSpaceOnUse" x1="24.446" x2="24.446" xlink:href="#f" y1=".498" y2="39.447"/><linearGradient id="j" gradientTransform="matrix(.476329 0 0 .627721 12.7549 9.156933)" gradientUnits="userSpaceOnUse" x1="31.597" x2="24.446" xlink:href="#e" y1="33.448" y2="21.067"/><radialGradient id="k" cx="24.399" cy="29.1" gradientTransform="matrix(2.407878 0 0 1.86105 -34.35094 -20.55775)" gradientUnits="userSpaceOnUse" r="6.027"><stop offset="0" stop-color="#525252"/><stop offset="1"/></radialGradient><linearGradient id="l" gradientTransform="matrix(1.059222 0 0 .808101 -1.234132 4.001391)" gradientUnits="userSpaceOnUse" x1="22.586" x2="22.586" y1="34.15" y2="11.043"><stop offset="0" stop-color="#fff"/><stop offset=".46" stop-color="#e3e3e3"/><stop offset=".62" stop-color="#dadada" stop-opacity=".671"/><stop offset="1" stop-color="#d1d1d1" stop-opacity=".343"/></linearGradient><linearGradient id="m" gradientUnits="userSpaceOnUse" x1="25.279" x2="28.284" xlink:href="#b" y1="28.555" y2="38.454"/><radialGradient id="n" cx="24.484" cy="29.61" gradientTransform="matrix(2.777122 -.08126449 .06891211 2.223012 -45.28558 -33.24798)" gradientUnits="userSpaceOnUse" r="4.477"><stop offset="0" stop-color="#fff"/><stop offset=".216" stop-color="#fff"/><stop offset=".5" stop-color="#838383"/><stop offset="1" stop-color="#838383" stop-opacity="0"/></radialGradient><path d="m-1559.2523-150.69685h1339.6335v478.35718h-1339.6335z" fill="url(#d)" opacity=".402" transform="matrix(.02312904 0 0 .01818338 45.14375 40.29231)"/><path d="m-219.61876-150.68038v478.33079c142.874166.90045 345.40022-107.16966 345.40014-239.196175 0-132.026537-159.436816-239.134595-345.40014-239.134615z" fill="url(#c)" opacity=".402" transform="matrix(.02312904 0 0 .01818338 45.14375 40.29231)"/><path d="m-1559.2523-150.68038v478.33079c-142.8742.90045-345.4002-107.16966-345.4002-239.196175 0-132.026537 159.4368-239.134595 345.4002-239.134615z" fill="url(#a)" opacity=".402" transform="matrix(.02312904 0 0 .01818338 45.14375 40.29231)"/><rect fill="url(#g)" fill-rule="evenodd" height="39.915" rx="5.455" stroke="#9b9b9b" stroke-linejoin="bevel" stroke-miterlimit="10" width="40.062" x="4.368" y="3.617"/><rect fill="none" height="37.782" rx="4.243" stroke="#fff" stroke-linejoin="bevel" stroke-miterlimit="10" width="37.697" x="5.551" y="4.651"/><g fill-rule="evenodd"><rect fill="url(#i)" height="32.706" rx="2.298" stroke="url(#h)" stroke-linejoin="bevel" stroke-miterlimit="10" width="24.258" x="12.27" y="7.522"/><rect fill="url(#k)" height="20.903" rx="1.591" stroke="url(#j)" stroke-linejoin="bevel" stroke-miterlimit="10" width="12.115" x="18.519" y="13.866"/><path d="m19.975767 34.034641 2.65165 2.651651 11.136932-.176776s-2.828427-9.369166-2.828427-9.369166-.707107-9.369166-.707107-9.369166l-.707107 15.909904z" fill="url(#m)" opacity=".316"/><g stroke-linejoin="bevel" stroke-miterlimit="10"><rect fill="#8a8a8a" height="4.315" rx="1.061" stroke="#595959" width="8.971" x="20.02" y="29.218"/><rect fill="url(#l)" height="15.812" rx=".884" stroke="url(#n)" width="8.912" x="20.05" y="15.231"/></g></g></svg>
<svg height="43.133282" width="46.961987" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.71399" cy="486.64801" gradientTransform="matrix(-.06416895 0 0 .03581591 46.660868 21.303303)" gradientUnits="userSpaceOnUse" r="117.143" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.71399" cy="486.64801" gradientTransform="matrix(.06416895 0 0 .03581591 .301129 21.303303)" gradientUnits="userSpaceOnUse" r="117.143" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(.06416895 0 0 .03581591 .2885 21.303303)" gradientUnits="userSpaceOnUse" x1="302.85699" x2="302.85699" y1="366.64801" y2="609.505"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d1d1d1"/></linearGradient><linearGradient id="f"><stop offset="0" stop-color="#fbfbfb"/><stop offset="1" stop-color="#dcdcdc"/></linearGradient><radialGradient id="g" cx="24.445999" cy="35.877998" gradientTransform="matrix(1.995058 0 0 1.855412 -25.462416 -33.3213)" gradientUnits="userSpaceOnUse" r="20.531" xlink:href="#f"/><linearGradient id="h" gradientTransform="matrix(1.045319 0 0 .957884 -1.154429 1.415543)" gradientUnits="userSpaceOnUse" x1="20.091999" x2="31.799" xlink:href="#e" y1="8.947" y2="38.946999"/><linearGradient id="i" gradientTransform="matrix(.984324 0 0 .957884 .336637 1.415543)" gradientUnits="userSpaceOnUse" x1="24.445999" x2="24.445999" xlink:href="#f" y1=".498" y2="39.446999"/><linearGradient id="j" gradientTransform="matrix(.476329 0 0 .627721 12.7549 9.156933)" gradientUnits="userSpaceOnUse" x1="31.597" x2="24.445999" xlink:href="#e" y1="33.448002" y2="21.066999"/><radialGradient id="k" cx="24.399" cy="29.1" gradientTransform="matrix(2.407878 0 0 1.86105 -34.35094 -20.55775)" gradientUnits="userSpaceOnUse" r="6.027"><stop offset="0" stop-color="#525252"/><stop offset="1"/></radialGradient><linearGradient id="l" gradientTransform="matrix(1.059222 0 0 .808101 -1.234132 4.001391)" gradientUnits="userSpaceOnUse" x1="22.586" x2="22.586" y1="34.150002" y2="11.043"><stop offset="0" stop-color="#fff"/><stop offset=".46" stop-color="#e3e3e3"/><stop offset=".62" stop-color="#dadada" stop-opacity=".671"/><stop offset="1" stop-color="#d1d1d1" stop-opacity=".343"/></linearGradient><linearGradient id="m" gradientUnits="userSpaceOnUse" x1="25.278999" x2="28.284" xlink:href="#b" y1="28.555" y2="38.453999"/><radialGradient id="n" cx="24.483999" cy="29.610001" gradientTransform="matrix(2.777122 -.08126449 .06891211 2.223012 -45.28558 -33.24798)" gradientUnits="userSpaceOnUse" r="4.477"><stop offset="0" stop-color="#fff"/><stop offset=".216" stop-color="#fff"/><stop offset=".5" stop-color="#838383"/><stop offset="1" stop-color="#838383" stop-opacity="0"/></radialGradient><g stroke-width=".020508"><path d="m7.988775 34.435132h30.984437v8.69815h-30.984437z" fill="url(#d)" opacity=".402"/><path d="m38.973213 34.435431v8.697671c3.304542.01637 7.988775-1.948707 7.988773-4.349395 0-2.400689-3.68762-4.348275-7.988773-4.348276z" fill="url(#c)" opacity=".402"/><path d="m7.988775 34.435431v8.697671c-3.304543.016373-7.988775-1.948707-7.988775-4.349395 0-2.400689 3.6876201-4.348275 7.988775-4.348276z" fill="url(#a)" opacity=".402"/></g><rect fill="url(#g)" fill-rule="evenodd" height="39.915001" rx="5.455" stroke="#9b9b9b" stroke-linejoin="bevel" stroke-miterlimit="10" width="40.062" x="3.277034" y=".5"/><rect fill="none" height="37.782001" rx="4.243" stroke="#fff" stroke-linejoin="bevel" stroke-miterlimit="10" width="37.696999" x="4.460034" y="1.534"/><g fill-rule="evenodd" transform="translate(-1.090966 -3.117)"><rect fill="url(#i)" height="32.706001" rx="2.298" stroke="url(#h)" stroke-linejoin="bevel" stroke-miterlimit="10" width="24.257999" x="12.27" y="7.522"/><rect fill="url(#k)" height="20.903" rx="1.591" stroke="url(#j)" stroke-linejoin="bevel" stroke-miterlimit="10" width="12.115" x="18.518999" y="13.866"/><path d="m19.975767 34.034641 2.65165 2.651651 11.136932-.176776s-2.828427-9.369166-2.828427-9.369166-.707107-9.369166-.707107-9.369166l-.707107 15.909904z" fill="url(#m)" opacity=".316"/><g stroke-linejoin="bevel" stroke-miterlimit="10"><rect fill="#8a8a8a" height="4.315" rx="1.061" stroke="#595959" width="8.971" x="20.02" y="29.218"/><rect fill="url(#l)" height="15.812" rx=".884" stroke="url(#n)" width="8.912" x="20.049999" y="15.231"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="19.701141" cy="2.896938" gradientTransform="matrix(2.046729 0 0 1.55761 -19.51799 3.452086)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="22.291636" cy="32.797512" gradientTransform="matrix(.843022 0 0 1.020168 4.499298 1.381992)" gradientUnits="userSpaceOnUse" r="16.9562"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><g fill-rule="evenodd"><path d="m40.481863 36.421127a15.644737 8.3968935 0 1 1 -31.2894745 0 15.644737 8.3968935 0 1 1 31.2894745 0z" fill="url(#b)" opacity=".299465" transform="matrix(1.271186 0 0 1.271186 -8.119376 -15.10179)"/><path d="m8.5541875 15.517348v16.99442h12.9838125v8.545038l19.959835-16.906441-20.078645-17.0252482v8.3975352z" fill="url(#c)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m21.962385 8.2485033v7.8064747h-12.8171699v9.040713c17.7499999 2 16.6335369-7.455288 31.3835369-.955288z" fill="url(#a)" opacity=".508021"/></g><path d="m9.537702 16.561892v14.98444h12.985367v7.395166l17.478014-14.795691-17.493975-14.7804004v7.2013824z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>
<svg height="35.245075" width="39.774742" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="19.701141" cy="2.896938" gradientTransform="matrix(2.046729 0 0 1.55761 -19.51799 3.452086)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="22.291636" cy="32.797512" gradientTransform="matrix(.843022 0 0 1.020168 4.499298 1.381992)" gradientUnits="userSpaceOnUse" r="16.9562"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><g fill-rule="evenodd" transform="translate(-3.56586 -6.625175)"><path d="m40.481863 36.421127a15.644737 8.3968937 0 1 1 -31.2894745 0 15.644737 8.3968937 0 1 1 31.2894745 0z" fill="url(#b)" opacity=".299465" transform="matrix(1.271186 0 0 1.271186 -8.119376 -15.10179)"/><path d="m8.5541875 15.517348v16.99442h12.9838125v8.545038l19.959835-16.906441-20.078645-17.0252482v8.3975352z" fill="url(#c)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m21.962385 8.2485033v7.8064747h-12.8171699v9.040713c17.7499999 2 16.6335369-7.455288 31.3835369-.955288z" fill="url(#a)" opacity=".508021"/></g><path d="m5.9718424 9.9367173v14.9844397h12.9853666v7.395166l17.478014-14.795691-17.493975-14.7804001v7.2013824z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="25.456" cy="39.161" gradientTransform="matrix(1 0 0 .315315 0 26.81305)" gradientUnits="userSpaceOnUse" r="19.622"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="12.934" x2="37.862" y1="8.048" y2="42.077"><stop offset="0" stop-color="#c9c9c9"/><stop offset=".25" stop-color="#f8f8f8"/><stop offset=".5" stop-color="#e2e2e2"/><stop offset=".75" stop-color="#b0b0b0"/><stop offset="1" stop-color="#c9c9c9"/></linearGradient><path d="m45.078058 39.161163a19.622213 6.1871843 0 1 1 -39.2444265 0 19.622213 6.1871843 0 1 1 39.2444265 0z" fill="url(#a)" opacity=".409" transform="translate(-.883885 2.474874)"/><path d="m23.25.46875c-.465439.03184628-.917834.10393469-1.375.15625h-.03125l-1.09375 5.96875c-1.782725.4059899-3.459909 1.0949915-4.96875 2.03125l-4.90625-3.53125c-1.3262882 1.0296906-2.5331984 2.2305953-3.59375 3.53125l3.40625 4.96875c-1.0342329 1.580515-1.8119683 3.385224-2.25 5.28125-.000075.008963-.0000609.029688 0 .03125l-5.9375.9375c-.1085533.886633-.15625 1.802939-.15625 2.71875.0000001.7493.0206894 1.488589.09375 2.21875l5.9375 1.0625c.422279 2.061892 1.2244587 3.987512 2.34375 5.6875l-3.53125 4.84375c1.0113261 1.255518 2.1788917 2.398616 3.4375 3.40625l5-3.4375c1.747433 1.114717 3.698083 1.896374 5.8125 2.28125l.9375 5.90625c.666183.060639 1.349349.0625 2.03125.0625.962685-.000001 1.882237-.036483 2.8125-.15625l1.125-6.03125c2.007561-.499601 3.893469-1.36629 5.53125-2.53125l4.8125 3.5c1.248028-1.061797 2.389277-2.282256 3.375-3.59375l-3.5-5.0625c.947853-1.63699 1.604629-3.443141 1.9375-5.375l5.90625-.9375c.051794-.616346.0625-1.214087.0625-1.84375 0-1.094214-.127182-2.167084-.28125-3.21875l-6-1.09375c-.470194-1.736224-1.241676-3.356102-2.21875-4.8125l3.53125-4.84375c-1.094573-1.3386071-2.343178-2.5751812-3.71875-3.625l-5.09375 3.5c-1.463996-.8658374-3.039463-1.5301821-4.75-1.90625l-.9375-5.9375c-.853299-.10037539-1.713621-.15625-2.59375-.15625-.237872.00000001-.482684-.0074846-.71875 0-.115083.00364881-.228966-.0066949-.34375 0-.031088.0018132-.062721-.00212309-.09375 0zm.8125 15.1875c.114166-.005793.228152 0 .34375 0 3.699127 0 6.71875 3.019624 6.71875 6.71875.000001 3.699126-3.019624 6.6875-6.71875 6.6875-3.699125.000001-6.6875-2.988374-6.6875-6.6875.000001-3.583527 2.8046-6.539158 6.34375-6.71875z" fill="url(#b)" stroke="gray"/><g fill="none" stroke="#fff"><path d="m36.239223 23.781593a12.727922 12.727922 0 1 1 -25.455844 0 12.727922 12.727922 0 1 1 25.455844 0z" opacity=".648" stroke-width="1.649" transform="matrix(.606518 0 0 .606518 10.15021 7.936835)"/><path d="m22.557788 1.6501132-.878189 5.7790101c-1.670998.3805456-4.744725 1.5444111-6.159004 2.4219929l-4.672033-3.4871869c-1.2431682.965158-1.3284229 1.0306101-2.3225076 2.2497511l3.3780526 5.0099536c-.969415 1.481461-2.1338039 4.121495-2.5518734 6.008088 0 0-5.9194088.997841-5.9194088.997841-.1017499.831066-.0528497 2.609798.0156321 3.294198l5.6542436 1.018588c.395814 1.932669 1.8770305 5.043588 2.9261735 6.637034l-3.5755759 4.724044c.9479445 1.176832 1.1376642 1.284521 2.3173929 2.229005l4.781168-3.50282c1.637918 1.044855 4.889033 2.315886 6.870935 2.676641l.784687 5.706254c.624432.056839 2.349481.216281 3.221443.10402l.878188-5.940154c1.881743-.468289 5.13316-1.80296 6.668298-2.89491l4.776055 3.450808c1.169811-.995251 1.180292-1.145216 2.104238-2.374516l-3.539198-5.030701c.888449-1.534398 2.037228-4.535223 2.349237-6.346009l5.794642-.961463c.048547-.577719.05091-2.188789-.093502-3.174545l-5.903777-1.018588c-.440727-1.627411-1.953211-4.559982-2.869049-5.925104l3.752352-4.7240431c-1.025972-1.2547143-1.407444-1.4268709-2.696806-2.4108954l-4.942313 3.5391967c-1.372246-.8115728-4.108614-2.0487474-5.711948-2.4012464l-.873075-5.6542436c-.799821-.0940847-3.107395-.0523057-3.564478 0z" opacity=".347"/></g></svg>
<svg height="47.857918" width="45.125" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="25.455999" cy="39.160999" gradientTransform="matrix(1 0 0 .315315 -2.727635 29.322619)" gradientUnits="userSpaceOnUse" r="19.622"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="11.09025" x2="36.01825" y1="8.082695" y2="42.111695"><stop offset="0" stop-color="#c9c9c9"/><stop offset=".25" stop-color="#f8f8f8"/><stop offset=".5" stop-color="#e2e2e2"/><stop offset=".75" stop-color="#b0b0b0"/><stop offset="1" stop-color="#c9c9c9"/></linearGradient><path d="m42.350423 41.670732a19.622213 6.1871845 0 1 1 -39.2444265 0 19.622213 6.1871845 0 1 1 39.2444265 0z" fill="url(#a)" opacity=".409"/><path d="m21.40625.50344454c-.465439.0318463-.917834.10393469-1.375.15625h-.03125l-1.09375 5.96874996c-1.782725.4059899-3.459909 1.0949915-4.96875 2.03125l-4.90625-3.53125c-1.3262882 1.0296906-2.5331984 2.2305953-3.59375 3.53125l3.40625 4.9687505c-1.0342329 1.580515-1.8119683 3.385224-2.25 5.28125-.000075.009-.0000609.02969 0 .03125l-5.9375.9375c-.1085533.886633-.15625 1.802939-.15625 2.71875.0000001.7493.020689 1.488589.09375 2.21875l5.9375 1.0625c.422279 2.061892 1.2244587 3.987512 2.34375 5.6875l-3.53125 4.84375c1.0113261 1.255518 2.1788917 2.398616 3.4375 3.40625l5-3.4375c1.747433 1.114717 3.698083 1.896374 5.8125 2.28125l.9375 5.90625c.666183.06064 1.349349.0625 2.03125.0625.962685-.000001 1.882237-.03648 2.8125-.15625l1.125-6.03125c2.007561-.499601 3.893469-1.36629 5.53125-2.53125l4.8125 3.5c1.248028-1.061797 2.389277-2.282256 3.375-3.59375l-3.5-5.0625c.947853-1.63699 1.604629-3.443141 1.9375-5.375l5.90625-.9375c.05179-.616346.0625-1.214087.0625-1.84375 0-1.094214-.127182-2.167084-.28125-3.21875l-6-1.09375c-.470194-1.736224-1.241676-3.356102-2.21875-4.8125l3.53125-4.8437505c-1.094573-1.3386071-2.343178-2.5751812-3.71875-3.625l-5.09375 3.5c-1.463996-.8658374-3.039463-1.5301821-4.75-1.90625l-.9375-5.93749996c-.853299-.10037539-1.713621-.15625-2.59375-.15625-.237872.00000001-.482684-.007485-.71875 0-.115083.003649-.228966-.006695-.34375 0-.03109.001813-.06272-.002123-.09375 0zm.8125 15.18750046c.114166-.0058.228152 0 .34375 0 3.699127 0 6.71875 3.019624 6.71875 6.71875.000001 3.699126-3.019624 6.6875-6.71875 6.6875-3.699125.000001-6.6875-2.988374-6.6875-6.6875.000001-3.583527 2.8046-6.539158 6.34375-6.71875z" fill="url(#b)" stroke="#808080"/><g fill="none" stroke="#fff" transform="translate(-1.84375 .034695)"><path d="m36.239223 23.781593a12.727922 12.727922 0 1 1 -25.455844 0 12.727922 12.727922 0 1 1 25.455844 0z" opacity=".648" stroke-width="1.649" transform="matrix(.606518 0 0 .606518 10.15021 7.936835)"/><path d="m22.557788 1.6501132-.878189 5.7790101c-1.670998.3805456-4.744725 1.5444111-6.159004 2.4219929l-4.672033-3.4871869c-1.2431682.965158-1.3284229 1.0306101-2.3225076 2.2497511l3.3780526 5.0099536c-.969415 1.481461-2.1338039 4.121495-2.5518734 6.008088 0 0-5.9194088.997841-5.9194088.997841-.1017499.831066-.05285 2.609798.015632 3.294198l5.6542436 1.018588c.395814 1.932669 1.8770306 5.043588 2.9261736 6.637034l-3.575576 4.724044c.9479445 1.176832 1.1376642 1.284521 2.317393 2.229005l4.781168-3.50282c1.637918 1.044855 4.889033 2.315886 6.870935 2.676641l.784687 5.706254c.624432.05684 2.349481.216281 3.221443.10402l.878188-5.940154c1.881743-.468289 5.13316-1.80296 6.668298-2.89491l4.776055 3.450808c1.169811-.995251 1.180292-1.145216 2.104238-2.374516l-3.539198-5.030701c.888449-1.534398 2.037228-4.535223 2.349237-6.346009l5.794642-.961463c.04855-.577719.05091-2.188789-.0935-3.174545l-5.903779-1.018588c-.440727-1.627411-1.953211-4.559982-2.869049-5.925104l3.752352-4.7240431c-1.025972-1.2547143-1.407444-1.4268709-2.696806-2.4108954l-4.942313 3.5391967c-1.372246-.8115728-4.108614-2.0487474-5.711948-2.4012464l-.873075-5.6542436c-.799821-.094085-3.107395-.052306-3.564478 0z" opacity=".347"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.71429" cy="486.64789" gradientTransform="matrix(-2.774389 0 0 1.969706 112.7623 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.71429" cy="486.64789" gradientTransform="matrix(2.774389 0 0 1.969706 -1891.633 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(2.774389 0 0 1.969706 -1892.179 -872.8854)" gradientUnits="userSpaceOnUse" x1="302.85715" x2="302.85715" y1="366.64789" y2="609.50507"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e" gradientTransform="matrix(.976612 0 0 1.139789 .564215 -3.271158)" gradientUnits="userSpaceOnUse" x1="40.884724" x2="16.879831" y1="71.869133" y2="-.389314"><stop offset="0" stop-color="#1e2d69"/><stop offset="1" stop-color="#78a7e0"/></linearGradient><linearGradient id="f" gradientTransform="matrix(.985432 0 0 1.148179 .64107 -2.933883)" gradientUnits="userSpaceOnUse" x1="13.783585" x2="33.074715" y1="-.996729" y2="55.701546"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="g" gradientTransform="matrix(1.067698 0 0 1.121532 -1.368937 -5.57446)" gradientUnits="userSpaceOnUse" x1="20.125" x2="28.5625" y1="21.84375" y2="42.46875"><stop offset="0" stop-color="#858585"/><stop offset=".5" stop-color="#cbcbcb"/><stop offset="1" stop-color="#6b6b6b"/></linearGradient><g transform="matrix(.02415802 0 0 .02086758 45.237 41.6536)"><path d="m-1559.2523-150.69685h1339.6335v478.35718h-1339.6335z" fill="url(#d)" opacity=".402062"/><path d="m-219.61876-150.68038v478.33079c142.874166.90045 345.40022-107.16966 345.40014-239.196175 0-132.026537-159.436816-239.134595-345.40014-239.134615z" fill="url(#c)" opacity=".402062"/><path d="m-1559.2523-150.68038v478.33079c-142.8742.90045-345.4002-107.16966-345.4002-239.196175 0-132.026537 159.4368-239.134595 345.4002-239.134615z" fill="url(#a)" opacity=".402062"/></g><path d="m4.5577604 3.5675797h38.8903026c.589294 0 1.063708.4744141 1.063708 1.0637086v37.7652107c0 .589294-.474414 1.063708-1.063708 1.063708h-36.8903026s-3.0637085-3.063708-3.0637085-3.063708v-35.7652107c0-.5892945.474414-1.0637086 1.0637085-1.0637086z" fill="url(#e)" stroke="#25375f" stroke-linecap="round" stroke-linejoin="round"/><path d="m9 4h30v23h-30z" fill="#fff"/><rect fill="#d31c00" height="4" rx=".126208" width="30" x="9" y="4"/><rect height="2" opacity=".738636" rx=".126208" width="2" x="6" y="6"/><g stroke="#000"><path d="m11 12.5h26" opacity=".130682"/><path d="m11 17.5h26" opacity=".130682"/><path d="m11 22.5h26" opacity=".130682"/></g><path d="m4.6189226 4.5276647h38.7684814c.069919 0 .126208.0562886.126208.1262077v37.6482386c0 .069919-.056289.126208-.126208.126208h-36.4591222s-2.4355669-2.391373-2.4355669-2.391373v-35.3830736c0-.0699191.0562886-.1262077.1262077-.1262077z" fill="none" opacity=".596591" stroke="url(#f)" stroke-linecap="round"/><g stroke="#525252"><path d="m14.113967 28.562183h19.749824c.887971 0 1.602836.75091 1.602836 1.683653v13.201551h-22.955496v-13.201551c0-.932743.714865-1.683653 1.602836-1.683653z" fill="url(#g)" stroke-width=".999999"/><rect fill="#4967a2" height="10.06597" rx=".751207" ry=".751208" width="5.029753" x="16.464279" y="30.4566"/></g></svg>
<svg height="45.4235" width="49.051262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.71429" cy="486.64789" gradientTransform="matrix(-2.774389 0 0 1.969706 112.7623 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.71429" cy="486.64789" gradientTransform="matrix(2.774389 0 0 1.969706 -1891.633 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(2.774389 0 0 1.969706 -1892.179 -872.8854)" gradientUnits="userSpaceOnUse" x1="302.85715" x2="302.85715" y1="366.64789" y2="609.50507"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e" gradientTransform="matrix(.976612 0 0 1.139789 1.339848 -6.338738)" gradientUnits="userSpaceOnUse" x1="40.884724" x2="16.879831" y1="71.869133" y2="-.389314"><stop offset="0" stop-color="#1e2d69"/><stop offset="1" stop-color="#78a7e0"/></linearGradient><linearGradient id="f" gradientTransform="matrix(.985432 0 0 1.148179 1.416703 -6.001463)" gradientUnits="userSpaceOnUse" x1="13.783585" x2="33.074715" y1="-.996729" y2="55.701546"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="g" gradientTransform="matrix(1.067698 0 0 1.121532 -1.368937 -5.57446)" gradientUnits="userSpaceOnUse" x1="20.125" x2="28.5625" y1="21.84375" y2="42.46875"><stop offset="0" stop-color="#858585"/><stop offset=".5" stop-color="#cbcbcb"/><stop offset="1" stop-color="#6b6b6b"/></linearGradient><g transform="matrix(.02415802 0 0 .02086758 46.012633 38.58602)"><path d="m-1559.2523-150.69685h1339.6335v478.35718h-1339.6335z" fill="url(#d)" opacity=".402062"/><path d="m-219.61876-150.68038v478.33079c142.874166.90045 345.40022-107.16966 345.40014-239.196175 0-132.026537-159.436816-239.134595-345.40014-239.134615z" fill="url(#c)" opacity=".402062"/><path d="m-1559.2523-150.68038v478.33079c-142.8742.90045-345.4002-107.16966-345.4002-239.196175 0-132.026537 159.4368-239.134595 345.4002-239.134615z" fill="url(#a)" opacity=".402062"/></g><path d="m5.3333936.5h38.8903024c.589294 0 1.063708.4744141 1.063708 1.0637086v37.7652104c0 .589294-.474414 1.063708-1.063708 1.063708h-36.8903024s-3.0637085-3.063708-3.0637085-3.063708v-35.7652104c0-.5892945.474414-1.0637086 1.0637085-1.0637086z" fill="url(#e)" stroke="#25375f" stroke-linecap="round" stroke-linejoin="round"/><path d="m9.7756332.9324203h29.9999998v22.9999997h-29.9999998z" fill="#fff"/><rect fill="#d31c00" height="4" rx=".126208" width="30" x="9.775633" y=".93242"/><rect height="2" opacity=".738636" rx=".126208" width="2" x="6.775633" y="2.93242"/><g stroke="#000" transform="translate(.775633 -3.06758)"><path d="m11 12.5h26" opacity=".130682"/><path d="m11 17.5h26" opacity=".130682"/><path d="m11 22.5h26" opacity=".130682"/></g><path d="m5.3945558 1.460085h38.7684812c.06992 0 .126208.056289.126208.1262077v37.6482383c0 .06992-.05629.126208-.126208.126208h-36.459122s-2.4355669-2.391373-2.4355669-2.391373v-35.3830733c0-.069919.056289-.1262077.1262077-.1262077z" fill="none" opacity=".596591" stroke="url(#f)" stroke-linecap="round"/><g stroke="#525252" transform="translate(.775633 -3.06758)"><path d="m14.113967 28.562183h19.749824c.887971 0 1.602836.75091 1.602836 1.683653v13.201551h-22.955496v-13.201551c0-.932743.714865-1.683653 1.602836-1.683653z" fill="url(#g)" stroke-width=".999999"/><rect fill="#4967a2" height="10.06597" rx=".751207" ry=".751208" width="5.029753" x="16.464279" y="30.4566"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(3.000198 0 0 1 -67.006 -.09426)" gradientUnits="userSpaceOnUse" x1="15.089521" x2="14" y1="15.291994" y2="52.510574"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientTransform="matrix(2.498884 0 0 1.004384 -414.0618 -71.4625)" gradientUnits="userSpaceOnUse" x1="169" x2="169" y1="110.33805" y2="93.204849"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="c" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000891 -1.07205 4.98026 -.00000125 -490.7792 212.6949)" gradientUnits="userSpaceOnUse" r="11"><stop offset="0" stop-color="#f7f7f7"/><stop offset="1" stop-color="#ccd0c7"/></radialGradient><linearGradient id="d" gradientTransform="matrix(2.624525 0 0 1.054917 -436.1019 -76.31138)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" y1="84.263489" y2="105.49083"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".484536"/></linearGradient><path d="m14.00382 12.829103v22.153256h20.996184v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#d)"/><path d="m14.5 13.40575v21h20v-21z" fill="url(#c)" fill-rule="evenodd"/><path d="m14.496737 13.407946v21.092064h19.991071v-21.092064z" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round"/><path d="m15.499412 14.40575v19h18.001183v-19z" fill="none" stroke="url(#a)" stroke-linecap="square"/><path d="m16 14.942758v10.557242l17-2.79033v-7.8553z" display="block" fill="#f7f7f7" opacity=".5"/></svg>
<svg height="24.153255" width="22.996183" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(3.000198 0 0 1 -80.00982 -11.923363)" gradientUnits="userSpaceOnUse" x1="15.089521" x2="14" y1="15.291994" y2="52.510574"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientTransform="matrix(2.498884 0 0 1.004384 -427.06562 -83.291603)" gradientUnits="userSpaceOnUse" x1="169" x2="169" y1="110.33805" y2="93.204849"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="c" cx="169.77171" cy="100.20107" gradientTransform="matrix(.00000891 -1.07205 4.98026 -.00000125 -503.78302 200.8658)" gradientUnits="userSpaceOnUse" r="11"><stop offset="0" stop-color="#f7f7f7"/><stop offset="1" stop-color="#ccd0c7"/></radialGradient><linearGradient id="d" gradientTransform="matrix(2.624525 0 0 1.054917 -449.10572 -88.140483)" gradientUnits="userSpaceOnUse" x1="174.83363" x2="174.74524" y1="84.263489" y2="105.49083"><stop offset="0"/><stop offset="1" stop-color="#fff" stop-opacity=".484536"/></linearGradient><path d="m1 1v22.153256h20.996184v-22.153256z" style="opacity:.15;fill:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke:url(#d)"/><path d="m1.49618 1.576647v21h20v-21z" fill="url(#c)" fill-rule="evenodd"/><path d="m1.492917 1.578843v21.092064h19.991071v-21.092064z" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round"/><path d="m2.495592 2.576647v19h18.001183v-19z" fill="none" stroke="url(#a)" stroke-linecap="square"/><path d="m2.99618 3.113655v10.557242l17-2.79033v-7.8553z" display="block" fill="#f7f7f7" opacity=".5"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.71429" cy="486.64789" gradientTransform="matrix(-2.774389 0 0 1.969706 112.7623 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.71429" cy="486.64789" gradientTransform="matrix(2.774389 0 0 1.969706 -1891.633 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(2.774389 0 0 1.969706 -1892.179 -872.8854)" gradientUnits="userSpaceOnUse" x1="302.85715" x2="302.85715" y1="366.64789" y2="609.50507"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e" gradientTransform="matrix(1.342704 0 0 1.235378 -8.219611 -6.577189)" gradientUnits="userSpaceOnUse" x1="20.794008" x2="35.596001" y1="18.378813" y2="39.60046"><stop offset="0" stop-color="#f8f8f7"/><stop offset=".59928656" stop-color="#e8e8e8"/><stop offset="1" stop-color="#e2e2de"/></linearGradient><g transform="matrix(.02330573 0 0 .01227058 44.47891 44.41691)"><path d="m-1559.2523-150.69685h1339.6335v478.35718h-1339.6335z" fill="url(#d)" opacity=".402062"/><path d="m-219.61876-150.68038v478.33079c142.874166.90045 345.40022-107.16966 345.40014-239.196175 0-132.026537-159.436816-239.134595-345.40014-239.134615z" fill="url(#c)" opacity=".402062"/><path d="m-1559.2523-150.68038v478.33079c-142.8742.90045-345.4002-107.16966-345.4002-239.196175 0-132.026537 159.4368-239.134595 345.4002-239.134615z" fill="url(#a)" opacity=".402062"/></g><g fill-rule="evenodd"><rect fill="url(#e)" height="45.003101" rx=".566508" stroke="#888a85" width="38.996792" x="4.501602" y="1.496899"/><g fill="#999"><path d="m9 10h27v2h-27z"/><path d="m9 16h25v2h-25z"/><path d="m9 22h22.971531v2h-22.971531z"/><path d="m9 28h27v2h-27z"/><path d="m9 34h17v2h-17z"/></g></g><path d="m5.499713 2.499718h37.025566v43.022316h-37.025566z" fill="none" stroke="#fff"/></svg>
<svg height="47.440594" width="47.320744" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="605.71429" cy="486.64789" gradientTransform="matrix(-2.774389 0 0 1.969706 112.7623 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient id="c" cx="605.71429" cy="486.64789" gradientTransform="matrix(2.774389 0 0 1.969706 -1891.633 -872.8854)" gradientUnits="userSpaceOnUse" r="117.14286" xlink:href="#b"/><linearGradient id="d" gradientTransform="matrix(2.774389 0 0 1.969706 -1892.179 -872.8854)" gradientUnits="userSpaceOnUse" x1="302.85715" x2="302.85715" y1="366.64789" y2="609.50507"><stop offset="0" stop-opacity="0"/><stop offset=".5"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e" gradientTransform="matrix(1.342704 0 0 1.235378 -8.219611 -6.577189)" gradientUnits="userSpaceOnUse" x1="20.794008" x2="35.596001" y1="18.378813" y2="39.60046"><stop offset="0" stop-color="#f8f8f7"/><stop offset=".59928656" stop-color="#e8e8e8"/><stop offset="1" stop-color="#e2e2de"/></linearGradient><g transform="matrix(.02330573 0 0 .01227058 44.389317 43.420011)"><path d="m-1559.2523-150.69685h1339.6335v478.35718h-1339.6335z" fill="url(#d)" opacity=".402062"/><path d="m-219.61876-150.68038v478.33079c142.874166.90045 345.40022-107.16966 345.40014-239.196175 0-132.026537-159.436816-239.134595-345.40014-239.134615z" fill="url(#c)" opacity=".402062"/><path d="m-1559.2523-150.68038v478.33079c-142.8742.90045-345.4002-107.16966-345.4002-239.196175 0-132.026537 159.4368-239.134595 345.4002-239.134615z" fill="url(#a)" opacity=".402062"/></g><g fill-rule="evenodd" transform="translate(-.089593 -.996899)"><rect fill="url(#e)" height="45.003101" rx=".566508" stroke="#888a85" width="38.996792" x="4.501602" y="1.496899"/><g fill="#999"><path d="m9 10h27v2h-27z"/><path d="m9 16h25v2h-25z"/><path d="m9 22h22.971531v2h-22.971531z"/><path d="m9 28h27v2h-27z"/><path d="m9 34h17v2h-17z"/></g></g><path d="m5.4101199 1.502819h37.0255661v43.022316h-37.0255661z" fill="none" stroke="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1 +1 @@
<svg height="48" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="24.53788" cy=".400108" gradientTransform="matrix(0 -2.046729 1.55761 0 2.767009 66.93275)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="11.319205" cy="22.454971" gradientTransform="matrix(0 -.843022 1.020168 0 .606436 42.58614)" gradientUnits="userSpaceOnUse" r="16.956199"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><radialGradient id="c" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><g fill-rule="evenodd"><path d="m40.481863 36.421127a15.644737 8.3968935 0 1 1 -31.2894745 0 15.644737 8.3968935 0 1 1 31.2894745 0z" fill="url(#c)" opacity=".299465" transform="matrix(1.214466 0 0 .595458 -6.163846 16.31275)"/><path d="m14.491792 38.5h17.977685v-12.952563h8.030523l-17.125191-20.0482235-16.8462505 19.9902575 7.9685375.066291z" fill="url(#b)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m7.5855237 25.03253h7.4102973l.066601 6.561809c5.655612-11.000461 15.993095-8.844411 16.594346-15.627665 0 0-8.28983-9.5447048-8.28983-9.5447048z" fill="url(#a)" opacity=".508021"/></g><path d="m15.602735 37.5h15.899843v-12.99295h6.808998l-14.95037-17.4369604-14.7065262 17.4803804 6.8203692-.022097z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>
<svg height="38.000759" width="38.000004" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="24.53788" cy=".400108" gradientTransform="matrix(0 -2.046729 1.55761 0 2.767009 66.93275)" gradientUnits="userSpaceOnUse" r="17.171415"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><radialGradient id="b" cx="11.319205" cy="22.454971" gradientTransform="matrix(0 -.843022 1.020168 0 .606436 42.58614)" gradientUnits="userSpaceOnUse" r="16.9562"><stop offset="0" stop-color="#73d216"/><stop offset="1" stop-color="#4e9a06"/></radialGradient><radialGradient id="c" cx="24.837126" cy="36.421127" gradientTransform="matrix(1 0 0 .536723 0 16.87306)" gradientUnits="userSpaceOnUse" r="15.644737"><stop offset="0"/><stop offset="1" stop-opacity="0"/></radialGradient><g fill-rule="evenodd" transform="translate(-4.999997 -4.999241)"><path d="m40.481863 36.421127a15.644737 8.3968937 0 1 1 -31.2894745 0 15.644737 8.3968937 0 1 1 31.2894745 0z" fill="url(#c)" opacity=".299465" transform="matrix(1.214466 0 0 .595458 -6.163846 16.31275)"/><path d="m14.491792 38.5h17.977685v-12.952563h8.030523l-17.125191-20.0482235-16.8462505 19.9902575 7.9685375.06629z" fill="url(#b)" stroke="#3a7304" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path d="m7.5855237 25.03253h7.4102973l.0666 6.561809c5.655612-11.000461 15.993095-8.844411 16.594346-15.627665 0 0-8.28983-9.5447048-8.28983-9.5447048z" fill="url(#a)" opacity=".508021"/></g><path d="m10.602738 32.500759h15.899843v-12.99295h6.808998l-14.95037-17.4369602-14.7065265 17.4803802 6.8203695-.0221z" fill="none" opacity=".481283" stroke="#fff" stroke-miterlimit="10"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -14,7 +14,6 @@
#include <QKeyEvent>
#include <QGraphicsScene>
#include <QCoreApplication>
#include <QPixmap>
#include <QAudioOutput>
#include <QAudioFormat>
@@ -29,8 +28,6 @@ MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
QAudioFormat format;
QString resourceDirPath;
bool hideOnscreenKeys;
//audio output
format.setSampleRate(AUDIO_SAMPLE_RATE);
@@ -53,23 +50,34 @@ MainWindow::MainWindow(QWidget* parent) :
audioDevice = new QAudioOutput(format, this);
audioOut = audioDevice->start();
//resource directory
resourceDirPath = settings->value("resourceDirectory", "").toString();
//get default path if path not set
if(resourceDirPath == ""){
//set variables to there default if its the first boot
if(settings->value("firstBootCompleted", "").toString() == ""){
//resource dir
#if defined(Q_OS_ANDROID)
resourceDirPath = "/sdcard/Mu";
settings->setValue("resourceDirectory", "/sdcard/Mu");
#elif defined(Q_OS_IOS)
resourceDirPath = "/var/mobile/Media/Mu";
settings->setValue("resourceDirectory", "/var/mobile/Media/Mu");
#else
resourceDirPath = QDir::homePath() + "/Mu";
settings->setValue("resourceDirectory", QDir::homePath() + "/Mu");
#endif
settings->setValue("resourceDirectory", resourceDirPath);
}
createHomeDirectoryTree(settings->value("resourceDirectory", "").toString());
//create directory tree, in case someone deleted it since the emu was last run or it was never created
createHomeDirectoryTree(resourceDirPath);
//onscreen keys
#if defined(Q_OS_ANDROID) && defined(Q_OS_IOS)
settings->setValue("hideOnscreenKeys", false);
#else
//not a mobile device disable the on screen buttons
settings->setValue("hideOnscreenKeys", true);
#endif
//skip boot screen, most users dont want to wait 5 seconds on boot
settings->setValue("fastBoot", true);
settings->setValue("palmOsVersion", 4);
//dont run this function again unless the config is deleted
settings->setValue("firstBootCompleted", true);
}
//keyboard
for(uint8_t index = 0; index < EmuWrapper::BUTTON_TOTAL_COUNT; index++)
@@ -78,17 +86,6 @@ MainWindow::MainWindow(QWidget* parent) :
//GUI
ui->setupUi(this);
//check if onscreen keys should be hidden
if(settings->value("hideOnscreenKeys", "").toString() == ""){
#if defined(Q_OS_ANDROID) && defined(Q_OS_IOS)
settings->setValue("hideOnscreenKeys", false);
#else
//not a mobile device disable the on screen buttons
settings->setValue("hideOnscreenKeys", true);
#endif
}
hideOnscreenKeys = settings->value("hideOnscreenKeys", false).toBool();
//this makes the display window and button icons resize properly
ui->centralWidget->installEventFilter(this);
ui->centralWidget->setObjectName("centralWidget");
@@ -103,6 +100,7 @@ MainWindow::MainWindow(QWidget* parent) :
ui->addressBook->installEventFilter(this);
ui->todo->installEventFilter(this);
ui->notes->installEventFilter(this);
ui->voiceMemo->installEventFilter(this);
ui->power->installEventFilter(this);
@@ -113,20 +111,9 @@ MainWindow::MainWindow(QWidget* parent) :
ui->settings->installEventFilter(this);
ui->install->installEventFilter(this);
ui->debugger->installEventFilter(this);
ui->bootApp->installEventFilter(this);
//hide onscreen keys if needed
ui->up->setHidden(hideOnscreenKeys);
ui->down->setHidden(hideOnscreenKeys);
ui->left->setHidden(hideOnscreenKeys);
ui->right->setHidden(hideOnscreenKeys);
ui->center->setHidden(hideOnscreenKeys);
ui->calendar->setHidden(hideOnscreenKeys);
ui->addressBook->setHidden(hideOnscreenKeys);
ui->todo->setHidden(hideOnscreenKeys);
ui->notes->setHidden(hideOnscreenKeys);
ui->power->setHidden(hideOnscreenKeys);
redraw();
#if !defined(EMU_DEBUG) || defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
//doesnt support debug tools
@@ -167,33 +154,10 @@ void MainWindow::createHomeDirectoryTree(const QString& path){
//creates directorys if not present, does nothing if they exist already
homeDir.mkpath(".");
homeDir.mkpath("./saveStates");
homeDir.mkpath("./screenshots");
homeDir.mkpath("./debugDumps");
}
uint32_t MainWindow::getEmuFeatureList(){
uint32_t features = FEATURE_ACCURATE;
features |= settings->value("feature128mbRam", false).toBool() ? FEATURE_RAM_HUGE : 0;
features |= settings->value("featureFastCpu", false).toBool() ? FEATURE_FAST_CPU : 0;
features |= settings->value("featureHybridCpu", false).toBool() ? FEATURE_HYBRID_CPU : 0;
features |= settings->value("featureCustomFb", false).toBool() ? FEATURE_CUSTOM_FB : 0;
features |= settings->value("featureSyncedRtc", false).toBool() ? FEATURE_SYNCED_RTC : 0;
features |= settings->value("featureHleApis", false).toBool() ? FEATURE_HLE_APIS : 0;
features |= settings->value("featureEmuHonest", false).toBool() ? FEATURE_EMU_HONEST : 0;
features |= settings->value("featureExtraKeys", false).toBool() ? FEATURE_EXT_KEYS : 0;
features |= settings->value("featureDurable", false).toBool() ? FEATURE_DURABLE : 0;
features |= settings->value("featureSoundStreams", false).toBool() ? FEATURE_SND_STRMS : 0;
//lazy debug overrides
//features = FEATURE_EXT_KEYS | FEATURE_EMU_HONEST | FEATURE_FAST_CPU | FEATURE_HYBRID_CPU | FEATURE_CUSTOM_FB | FEATURE_DEBUG | FEATURE_SND_STRMS;
//features = FEATURE_FAST_CPU | FEATURE_HYBRID_CPU | FEATURE_CUSTOM_FB | FEATURE_DEBUG;
//features = FEATURE_FAST_CPU | FEATURE_HYBRID_CPU | FEATURE_DEBUG;
return features;
}
void MainWindow::popupErrorDialog(const QString& error){
QMessageBox::critical(this, "Mu", error, QMessageBox::Ok);
}
@@ -217,6 +181,7 @@ void MainWindow::redraw(){
ui->addressBook->setHidden(hideOnscreenKeys);
ui->todo->setHidden(hideOnscreenKeys);
ui->notes->setHidden(hideOnscreenKeys);
ui->voiceMemo->setHidden(hideOnscreenKeys);
ui->power->setHidden(hideOnscreenKeys);
@@ -240,16 +205,14 @@ bool MainWindow::eventFilter(QObject* object, QEvent* event){
ui->displayContainer->setFixedHeight(ui->centralWidget->height() * (hideOnscreenKeys ? 0.80 : 0.60));
smallestRatio = qMin(ui->displayContainer->size().width() * 0.98 / 3.0 , ui->displayContainer->size().height() * 0.98 / 4.0);
//the 0.98 above allows the display to shrink, without it the displayContainer couldent shrink because of the fixed size of the display
//the 0.98 above allows the display to shrink, without it the displayContainer couldnt shrink because of the fixed size of the display
//set new size
ui->display->setFixedSize(smallestRatio * 3.0, smallestRatio * 4.0);
//scale framebuffer to new size and refresh
if(emu.isInited()){
ui->display->setPixmap(emu.getFramebuffer().scaled(QSize(ui->display->size().width(), ui->display->size().height()), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->display->update();
}
if(emu.isInited())
ui->display->repaint();
}
}
@@ -259,8 +222,8 @@ bool MainWindow::eventFilter(QObject* object, QEvent* event){
//display
void MainWindow::updateDisplay(){
if(emu.newFrameReady()){
//video, this is doing bilinear filitering in software, this is why the Qt port is broken on Android, move this to a new thread if possible
ui->display->setPixmap(emu.getFramebuffer().scaled(ui->display->size().width(), ui->display->size().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
//video
ui->display->repaint();
//audio
audioOut->write((const char*)emu.getAudioSamples(), AUDIO_SAMPLES_PER_FRAME * 2/*channels*/ * sizeof(int16_t));
@@ -270,10 +233,6 @@ void MainWindow::updateDisplay(){
//allow next frame to start
emu.frameHandled();
//update GUI
ui->display->repaint();
ui->powerButtonLed->repaint();
}
}
@@ -310,6 +269,14 @@ void MainWindow::on_todo_released(){
emu.setKeyValue(EmuWrapper::BUTTON_TODO, false);
}
void MainWindow::on_voiceMemo_pressed(){
emu.setKeyValue(EmuWrapper::BUTTON_VOICE_MEMO, false);
}
void MainWindow::on_voiceMemo_released(){
emu.setKeyValue(EmuWrapper::BUTTON_VOICE_MEMO, false);
}
void MainWindow::on_notes_pressed(){
emu.setKeyValue(EmuWrapper::BUTTON_NOTES, true);
}
@@ -350,35 +317,48 @@ void MainWindow::on_right_released(){
emu.setKeyValue(EmuWrapper::BUTTON_RIGHT, false);
}
void MainWindow::on_center_pressed(){
emu.setKeyValue(EmuWrapper::BUTTON_CENTER, true);
}
void MainWindow::on_center_released(){
emu.setKeyValue(EmuWrapper::BUTTON_CENTER, false);
}
//emu control
void MainWindow::on_ctrlBtn_clicked(){
if(!emu.isInited()){
uint32_t enabledFeatures = getEmuFeatureList();
QString sysDir = settings->value("resourceDirectory", "").toString();
uint32_t error = emu.init(sysDir + "/palmos41-en-m515.rom", QFile(sysDir + "/bootloader-en-m515.rom").exists() ? sysDir + "/bootloader-en-m515.rom" : "", sysDir + "/userdata-en-m515.ram", sysDir + "/sd-en-m515.img", enabledFeatures);
uint32_t error = emu.init(sysDir, settings->value("palmOsVersion", false).toInt(), settings->value("featureSyncedRtc", false).toBool(), settings->value("featureDurable", false).toBool(), settings->value("fastBoot", false).toBool());
if(error == EMU_ERROR_NONE){
emu.setCpuSpeed(settings->value("cpuSpeed", 1.00).toDouble());
ui->up->setEnabled(true);
ui->down->setEnabled(true);
if(settings->value("palmOsVersion", false).toInt() > 4){
ui->left->setEnabled(true);
ui->right->setEnabled(true);
ui->center->setEnabled(true);
}
ui->calendar->setEnabled(true);
ui->addressBook->setEnabled(true);
ui->todo->setEnabled(true);
ui->notes->setEnabled(true);
ui->power->setEnabled(true);
if(settings->value("palmOsVersion", false).toInt() > 4)
ui->voiceMemo->setEnabled(true);
if(enabledFeatures & FEATURE_EXT_KEYS){
ui->left->setEnabled(true);
ui->right->setEnabled(true);
ui->center->setEnabled(true);
}
ui->power->setEnabled(true);
ui->screenshot->setEnabled(true);
ui->install->setEnabled(true);
ui->stateManager->setEnabled(true);
ui->debugger->setEnabled(true);
ui->reset->setEnabled(true);
ui->bootApp->setEnabled(true);
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/pause.svg"));
}
@@ -394,20 +374,29 @@ void MainWindow::on_ctrlBtn_clicked(){
emu.resume();
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/pause.svg"));
}
ui->ctrlBtn->repaint();
}
void MainWindow::on_install_clicked(){
if(emu.isInited()){
QString app = QFileDialog::getOpenFileName(this, "Select Application", QDir::root().path(), "Palm OS App (*.prc *.pdb *.pqa)");
QString app;
bool loadedNewApp = false;
bool wasPaused = emu.isPaused();
if(!wasPaused)
emu.pause();
app = QFileDialog::getOpenFileName(this, "Select File", QDir::root().path(), "Palm OS File (*.prc *.pdb *.pqa)");
if(app != ""){
uint32_t error = emu.installApplication(app);
if(error != EMU_ERROR_NONE)
if(error == EMU_ERROR_NONE)
loadedNewApp = true;
else
popupErrorDialog("Could not install app, Error:" + QString::number(error));
}
if(!wasPaused || loadedNewApp)
emu.resume();
}
}
@@ -415,7 +404,6 @@ void MainWindow::on_debugger_clicked(){
if(emu.isInited()){
emu.pause();
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/play.svg"));
ui->ctrlBtn->repaint();
emuDebugger->exec();
}
}
@@ -425,7 +413,7 @@ void MainWindow::on_screenshot_clicked(){
qlonglong screenshotNumber = settings->value("screenshotNum", 0).toLongLong();
QString screenshotPath = settings->value("resourceDirectory", "").toString() + "/screenshots/screenshot" + QString::number(screenshotNumber, 10) + ".png";
emu.getFramebuffer().save(screenshotPath, "PNG", 100);
emu.getFramebufferImage().save(screenshotPath, "PNG", 100);
screenshotNumber++;
settings->setValue("screenshotNum", screenshotNumber);
}
@@ -468,3 +456,27 @@ void MainWindow::on_settings_clicked(){
if(wasInited && !wasPaused)
emu.resume();
}
void MainWindow::on_bootApp_clicked(){
if(emu.isInited()){
QString app;
bool loadedNewApp = false;
bool wasPaused = emu.isPaused();
if(!wasPaused)
emu.pause();
app = QFileDialog::getOpenFileName(this, "Select File", QDir::root().path(), "Palm OS File (*.prc *.pqa *.img)");
if(app != ""){
uint32_t error = emu.bootFromFile(app);
if(error == EMU_ERROR_NONE)
loadedNewApp = true;
else
popupErrorDialog("Could not boot app, Error:" + QString::number(error));
}
if(!wasPaused || loadedNewApp)
emu.resume();
}
}

View File

@@ -38,7 +38,6 @@ public:
void createHomeDirectoryTree(const QString& path);
private:
uint32_t getEmuFeatureList();
void popupErrorDialog(const QString& error);
void popupInformationDialog(const QString& info);
void redraw();
@@ -60,6 +59,8 @@ private slots:
void on_todo_released();
void on_notes_pressed();
void on_notes_released();
void on_voiceMemo_pressed();
void on_voiceMemo_released();
void on_up_pressed();
void on_up_released();
void on_down_pressed();
@@ -68,6 +69,8 @@ private slots:
void on_left_released();
void on_right_pressed();
void on_right_released();
void on_center_pressed();
void on_center_released();
//frontend buttons
void on_ctrlBtn_clicked();
@@ -77,6 +80,7 @@ private slots:
void on_stateManager_clicked();
void on_reset_clicked();
void on_settings_clicked();
void on_bootApp_clicked();
private:
SettingsManager* settingsManager;

View File

@@ -2,16 +2,13 @@
<qresource prefix="/buttons">
<file>images/addressBook.svg</file>
<file>images/calendar.svg</file>
<file>images/center.svg</file>
<file>images/debugger.svg</file>
<file>images/down.svg</file>
<file>images/install.svg</file>
<file>images/left.svg</file>
<file>images/notes.svg</file>
<file>images/pause.svg</file>
<file>images/play.svg</file>
<file>images/power.svg</file>
<file>images/right.svg</file>
<file>images/screenshot.svg</file>
<file>images/stateManager.svg</file>
<file>images/stop.svg</file>
@@ -19,5 +16,10 @@
<file>images/up.svg</file>
<file>images/reset.svg</file>
<file>images/settingsManager.svg</file>
<file>images/center.svg</file>
<file>images/left.svg</file>
<file>images/right.svg</file>
<file>images/boot.svg</file>
<file>images/voiceMemo.svg</file>
</qresource>
</RCC>

View File

@@ -43,7 +43,7 @@
<number>0</number>
</property>
<item>
<widget class="TouchScreen" name="display">
<widget class="TouchScreen" name="display" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -56,12 +56,6 @@
<height>220</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
</layout>
@@ -94,8 +88,8 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="7" column="1">
<widget class="QPushButton" name="addressBook">
<item row="6" column="0">
<widget class="QPushButton" name="calendar">
<property name="enabled">
<bool>false</bool>
</property>
@@ -105,43 +99,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="screenshot">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/screenshot.svg</normaloff>:/buttons/images/screenshot.svg</iconset>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QPushButton" name="right">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/right.svg</normaloff>:/buttons/images/right.svg</iconset>
<normaloff>:/buttons/images/calendar.svg</normaloff>:/buttons/images/calendar.svg</iconset>
</property>
</widget>
</item>
@@ -153,6 +116,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Run/Pause</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
@@ -162,7 +131,310 @@
</property>
</widget>
</item>
<item row="7" column="5">
<item row="0" column="2">
<widget class="QPushButton" name="reset">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Reset</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/reset.svg</normaloff>:/buttons/images/reset.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="stateManager">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Save/Load State</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/stateManager.svg</normaloff>:/buttons/images/stateManager.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="settings">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Settings</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/settingsManager.svg</normaloff>:/buttons/images/settingsManager.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="power">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/power.svg</normaloff>:/buttons/images/power.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="bootApp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Boot App</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/boot.svg</normaloff>:/buttons/images/boot.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="install">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Install App</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/install.svg</normaloff>:/buttons/images/install.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="screenshot">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Snapshot</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/screenshot.svg</normaloff>:/buttons/images/screenshot.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="powerButtonLed">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>This is an LED not a button.😜</string>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="addressBook">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="left">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/left.svg</normaloff>:/buttons/images/left.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="up">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="center">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/center.svg</normaloff>:/buttons/images/center.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QPushButton" name="down">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QPushButton" name="right">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/right.svg</normaloff>:/buttons/images/right.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QPushButton" name="todo">
<property name="enabled">
<bool>false</bool>
@@ -185,26 +457,16 @@
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/todo.svg</normaloff>:/buttons/images/todo.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="powerButtonLed">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string>LED</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="7">
<item row="6" column="6">
<widget class="QPushButton" name="notes">
<property name="enabled">
<bool>false</bool>
@@ -215,180 +477,16 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/notes.svg</normaloff>:/buttons/images/notes.svg</iconset>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="left">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/left.svg</normaloff>:/buttons/images/left.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="stateManager">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/stateManager.svg</normaloff>:/buttons/images/stateManager.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="up">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QPushButton" name="center">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/center.svg</normaloff>:/buttons/images/center.svg</iconset>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QPushButton" name="down">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="calendar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/calendar.svg</normaloff>:/buttons/images/calendar.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="power">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/power.svg</normaloff>:/buttons/images/power.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="reset">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/reset.svg</normaloff>:/buttons/images/reset.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="settings">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/settingsManager.svg</normaloff>:/buttons/images/settingsManager.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="install">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/install.svg</normaloff>:/buttons/images/install.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="4">
<item row="1" column="5">
<widget class="QPushButton" name="debugger">
<property name="enabled">
<bool>false</bool>
@@ -399,12 +497,35 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Debugger</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/debugger.svg</normaloff>:/buttons/images/debugger.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="voiceMemo">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/voiceMemo.svg</normaloff>:/buttons/images/voiceMemo.svg</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -415,8 +536,9 @@
<customwidgets>
<customwidget>
<class>TouchScreen</class>
<extends>QLabel</extends>
<extends>QWidget</extends>
<header>touchscreen.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>

View File

@@ -9,6 +9,7 @@
#include <QKeyEvent>
#include "mainwindow.h"
#include "emuwrapper.h"
SettingsManager::SettingsManager(QWidget* parent) :
@@ -23,16 +24,11 @@ SettingsManager::SettingsManager(QWidget* parent) :
ui->homeDirectory->setText(settings->value("resourceDirectory", "").toString());
ui->showOnscreenKeys->setChecked(!settings->value("hideOnscreenKeys", false).toBool());
ui->feature128mbRam->setChecked(settings->value("feature128mbRam", false).toBool());
ui->featureFastCpu->setChecked(settings->value("featureFastCpu", false).toBool());
ui->featureHybridCpu->setChecked(settings->value("featureHybridCpu", false).toBool());
ui->featureCustomFb->setChecked(settings->value("featureCustomFb", false).toBool());
ui->fastBoot->setChecked(settings->value("fastBoot", false).toBool());
ui->palmOsVersion->setValue(settings->value("palmOsVersion", false).toInt());
ui->featureSyncedRtc->setChecked(settings->value("featureSyncedRtc", false).toBool());
ui->featureHleApis->setChecked(settings->value("featureHleApis", false).toBool());
ui->featureEmuHonest->setChecked(settings->value("featureEmuHonest", false).toBool());
ui->featureExtraKeys->setChecked(settings->value("featureExtraKeys", false).toBool());
ui->featureDurable->setChecked(settings->value("featureDurable", false).toBool());
ui->featureSoundStreams->setChecked(settings->value("featureSoundStreams", false).toBool());
setKeySelectorState(-1);
updateButtonKeys();
@@ -73,6 +69,7 @@ void SettingsManager::updateButtonKeys(){
ui->selectAddressBookKey->setText(QKeySequence(settings->value("palmButton" + QString::number(EmuWrapper::BUTTON_ADDRESS) + "Key", '\0').toInt()).toString());
ui->selectTodoKey->setText(QKeySequence(settings->value("palmButton" + QString::number(EmuWrapper::BUTTON_TODO) + "Key", '\0').toInt()).toString());
ui->selectNotesKey->setText(QKeySequence(settings->value("palmButton" + QString::number(EmuWrapper::BUTTON_NOTES) + "Key", '\0').toInt()).toString());
ui->selectVoiceMemoKey->setText(QKeySequence(settings->value("palmButton" + QString::number(EmuWrapper::BUTTON_VOICE_MEMO) + "Key", '\0').toInt()).toString());
ui->selectPowerKey->setText(QKeySequence(settings->value("palmButton" + QString::number(EmuWrapper::BUTTON_POWER) + "Key", '\0').toInt()).toString());
}
@@ -127,6 +124,10 @@ void SettingsManager::on_selectNotesKey_clicked(){
setKeySelectorState(EmuWrapper::BUTTON_NOTES);
}
void SettingsManager::on_selectVoiceMemoKey_clicked(){
setKeySelectorState(EmuWrapper::BUTTON_VOICE_MEMO);
}
void SettingsManager::on_selectPowerKey_clicked(){
setKeySelectorState(EmuWrapper::BUTTON_POWER);
}
@@ -140,42 +141,26 @@ void SettingsManager::on_clearKeyBind_clicked(){
}
}
void SettingsManager::on_feature128mbRam_toggled(bool checked){
settings->setValue("feature128mbRam", checked);
}
void SettingsManager::on_featureFastCpu_toggled(bool checked){
settings->setValue("featureFastCpu", checked);
}
void SettingsManager::on_featureHybridCpu_toggled(bool checked){
settings->setValue("featureHybridCpu", checked);
}
void SettingsManager::on_featureCustomFb_toggled(bool checked){
settings->setValue("featureCustomFb", checked);
}
void SettingsManager::on_featureSyncedRtc_toggled(bool checked){
settings->setValue("featureSyncedRtc", checked);
}
void SettingsManager::on_featureHleApis_toggled(bool checked){
settings->setValue("featureHleApis", checked);
}
void SettingsManager::on_featureEmuHonest_toggled(bool checked){
settings->setValue("featureEmuHonest", checked);
}
void SettingsManager::on_featureExtraKeys_toggled(bool checked){
settings->setValue("featureExtraKeys", checked);
}
void SettingsManager::on_featureSoundStreams_toggled(bool checked){
settings->setValue("featureSoundStreams", checked);
}
void SettingsManager::on_featureDurable_toggled(bool checked){
settings->setValue("featureDurable", checked);
}
void SettingsManager::on_fastBoot_toggled(bool checked){
settings->setValue("fastBoot", checked);
}
void SettingsManager::on_cpuSpeed_valueChanged(double arg1){
EmuWrapper& emu = ((MainWindow*)parentWidget())->emu;
settings->setValue("cpuSpeed", arg1);
if(emu.isInited())
emu.setCpuSpeed(arg1);
}
void SettingsManager::on_palmOsVersion_valueChanged(int arg1){
settings->setValue("palmOsVersion", arg1);
}

View File

@@ -40,20 +40,17 @@ private slots:
void on_selectAddressBookKey_clicked();
void on_selectTodoKey_clicked();
void on_selectNotesKey_clicked();
void on_selectVoiceMemoKey_clicked();
void on_selectPowerKey_clicked();
void on_clearKeyBind_clicked();
void on_feature128mbRam_toggled(bool checked);
void on_featureFastCpu_toggled(bool checked);
void on_featureHybridCpu_toggled(bool checked);
void on_featureCustomFb_toggled(bool checked);
void on_featureSyncedRtc_toggled(bool checked);
void on_featureHleApis_toggled(bool checked);
void on_featureEmuHonest_toggled(bool checked);
void on_featureExtraKeys_toggled(bool checked);
void on_featureSoundStreams_toggled(bool checked);
void on_featureDurable_toggled(bool checked);
void on_fastBoot_toggled(bool checked);
void on_cpuSpeed_valueChanged(double arg1);
void on_palmOsVersion_valueChanged(int arg1);
private:
Ui::SettingsManager* ui;
QSettings* settings;

View File

@@ -30,13 +30,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>417</height>
<width>613</width>
<height>444</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLineEdit" name="homeDirectory">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
@@ -44,13 +47,22 @@
</item>
<item>
<widget class="QPushButton" name="pickHomeDirectory">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Pick Home Directory</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showOnscreenKeys">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Show Onscreen Keys</string>
</property>
@@ -58,8 +70,11 @@
</item>
<item>
<widget class="QLabel" name="label">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set Keyboard Keys:</string>
<string>Set Palm Button Map:</string>
</property>
</widget>
</item>
@@ -72,42 +87,26 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QPushButton" name="selectAddressBookKey">
<item row="2" column="4">
<widget class="QPushButton" name="selectNotesKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
<normaloff>:/buttons/images/notes.svg</normaloff>:/buttons/images/notes.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="selectUpKey">
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="selectDownKey">
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
@@ -119,6 +118,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -126,6 +128,26 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/calendar.svg</normaloff>:/buttons/images/calendar.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="selectDownKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/down.svg</normaloff>:/buttons/images/down.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="3">
@@ -136,6 +158,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -143,22 +168,8 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/todo.svg</normaloff>:/buttons/images/todo.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="selectNotesKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/notes.svg</normaloff>:/buttons/images/notes.svg</iconset>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
@@ -170,6 +181,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -177,10 +191,73 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/power.svg</normaloff>:/buttons/images/power.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="selectUpKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/up.svg</normaloff>:/buttons/images/up.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="selectAddressBookKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/addressBook.svg</normaloff>:/buttons/images/addressBook.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="selectCenterKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/center.svg</normaloff>:/buttons/images/center.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="selectLeftKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -188,10 +265,16 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/left.svg</normaloff>:/buttons/images/left.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="selectRightKey">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
@@ -199,16 +282,28 @@
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/right.svg</normaloff>:/buttons/images/right.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="selectCenterKey">
<item row="0" column="1">
<widget class="QPushButton" name="selectVoiceMemoKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>MAXSIZE</string>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/center.svg</normaloff>:/buttons/images/center.svg</iconset>
<normaloff>:/buttons/images/voiceMemo.svg</normaloff>:/buttons/images/voiceMemo.svg</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
@@ -224,13 +319,72 @@
</item>
<item>
<widget class="QPushButton" name="clearKeyBind">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Clear Key Bind</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="palmOsVersionLabel">
<property name="text">
<string>Palm OS Version:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="palmOsVersion">
<property name="minimum">
<number>4</number>
</property>
<property name="maximum">
<number>6</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>CPU Speed:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="cpuSpeed">
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fastBoot">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Fast Boot(Fastforwards Through The Boot Screen)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set Emulator Features(Restart Required):</string>
</property>
@@ -239,73 +393,20 @@
<item>
<widget class="QWidget" name="gridWidget_2" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QCheckBox" name="featureSyncedRtc">
<item row="2" column="1">
<widget class="QCheckBox" name="featureDurable">
<property name="text">
<string>Sync Real Time Clock</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="featureHybridCpu">
<property name="text">
<string>ARM Instruction Set(OS 5)</string>
<string>Ignore Invalid Behavior</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="featureEmuHonest">
<property name="text">
<string>Tell Programs Their Emulated</string>
<widget class="QCheckBox" name="featureSyncedRtc">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="feature128mbRam">
<property name="text">
<string>128MB RAM</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="featureFastCpu">
<property name="text">
<string>Overclocking</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="featureSoundStreams">
<property name="text">
<string>PWM Audio Streams(OS 5)</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="featureHleApis">
<property name="text">
<string>HLE APIs(Speed Hack)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="featureExtraKeys">
<property name="text">
<string>Extra Dpad Keys(OS 5)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="featureCustomFb">
<property name="text">
<string>Resizeable Display(HiRes Mode)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="featureDurable">
<property name="text">
<string>Ignore Invalid Behavior</string>
<string>Sync Real Time Clock</string>
</property>
</widget>
</item>

View File

@@ -8,6 +8,8 @@
#include <QFile>
#include <QDir>
#include <QListWidgetItem>
#include <QRegExp>
#include <QRegExpValidator>
#include "mainwindow.h"
@@ -15,23 +17,30 @@
StateManager::StateManager(QWidget* parent) :
QDialog(parent),
ui(new Ui::StateManager){
settings = ((MainWindow*)parent)->settings;
emu = &((MainWindow*)parent)->emu;
//init GUI
ui->setupUi(this);
//this allows resizing the screenshot of the savestate
this->installEventFilter(this);
ui->statePreview->installEventFilter(this);
ui->statePreview->setObjectName("statePreview");
updateStateList();
noBadPaths = new QRegExpValidator(QRegExp("[a-z0-9_()-\\s]*"));
ui->newStateName->setValidator(noBadPaths);
}
StateManager::~StateManager(){
delete noBadPaths;
delete ui;
}
bool StateManager::eventFilter(QObject* object, QEvent* event){
if(object->objectName() == "StateManager" && event->type() == QEvent::WindowActivate){
updateStateList();
ui->states->setCurrentRow(0);
}
if(object->objectName() == "statePreview" && event->type() == QEvent::Resize)
updateStatePreview();
@@ -39,8 +48,7 @@ bool StateManager::eventFilter(QObject* object, QEvent* event){
}
void StateManager::updateStateList(){
QString saveDirPath = settings->value("resourceDirectory", "").toString() + "/saveStates";
QDir saveDir(saveDirPath);
QDir saveDir(emu->getStatePath());
QStringList saveStateNames;
QStringList filter;
@@ -60,7 +68,7 @@ void StateManager::updateStateList(){
void StateManager::updateStatePreview(){
if(ui->states->currentItem()){
QString statePath = settings->value("resourceDirectory", "").toString() + "/saveStates/" + ui->states->currentItem()->text();
QString statePath = emu->getStatePath() + "/" + ui->states->currentItem()->text();
ui->statePreview->setPixmap(QPixmap(statePath + ".png").scaled(ui->statePreview->width() * 0.98, ui->statePreview->height() * 0.98, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
@@ -68,8 +76,6 @@ void StateManager::updateStatePreview(){
//remove outdated image
ui->statePreview->clear();
}
ui->statePreview->update();
}
int StateManager::getStateIndexRowByName(const QString& name){
@@ -83,10 +89,10 @@ int StateManager::getStateIndexRowByName(const QString& name){
void StateManager::on_saveState_clicked(){
if(ui->newStateName->text() != ""){
MainWindow* parent = (MainWindow*)parentWidget();
QString statePath = settings->value("resourceDirectory", "").toString() + "/saveStates/" + ui->newStateName->text();
QString statePath = emu->getStatePath() + "/" + ui->newStateName->text();
parent->emu.saveState(statePath + ".state");
parent->emu.getFramebuffer().save(statePath + ".png");
parent->emu.saveState(ui->newStateName->text());
parent->emu.getFramebufferImage().save(statePath + ".png");
updateStateList();
ui->states->setCurrentRow(getStateIndexRowByName(ui->newStateName->text()));//this also updates the preview image
@@ -96,15 +102,15 @@ void StateManager::on_saveState_clicked(){
void StateManager::on_loadState_clicked(){
if(ui->states->currentItem()){
MainWindow* parent = (MainWindow*)parentWidget();
QString statePath = settings->value("resourceDirectory", "").toString() + "/saveStates/" + ui->states->currentItem()->text();
QString statePath = emu->getStatePath() + "/" + ui->states->currentItem()->text();
parent->emu.loadState(statePath + ".state");
parent->emu.loadState(ui->states->currentItem()->text());
}
}
void StateManager::on_deleteState_clicked(){
if(ui->states->currentItem()){
QString statePath = settings->value("resourceDirectory", "").toString() + "/saveStates/" + ui->states->currentItem()->text();
QString statePath = emu->getStatePath() + "/" + ui->states->currentItem()->text();
QFile(statePath + ".state").remove();
QFile(statePath + ".png").remove();
@@ -116,6 +122,4 @@ void StateManager::on_deleteState_clicked(){
void StateManager::on_states_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous){
updateStatePreview();
ui->states->repaint();
ui->statePreview->repaint();
}

View File

@@ -4,7 +4,10 @@
#include <QObject>
#include <QEvent>
#include <QListWidgetItem>
#include <QSettings>
#include <QString>
#include <QRegExpValidator>
#include "emuwrapper.h"
namespace Ui{
class StateManager;
@@ -32,5 +35,6 @@ private slots:
private:
Ui::StateManager* ui;
QSettings* settings;
EmuWrapper* emu;
QRegExpValidator* noBadPaths;
};

View File

@@ -1,6 +1,7 @@
#include "touchscreen.h"
#include <QLabel>
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
#include <stdint.h>
@@ -10,7 +11,7 @@
TouchScreen::TouchScreen(QWidget* parent)
: QLabel(parent){
: QWidget(parent){
}
@@ -22,6 +23,17 @@ float TouchScreen::rangeSwap(float newRange, float oldRange, float value){
return value / oldRange * newRange;
}
void TouchScreen::paintEvent(QPaintEvent* ev){
EmuWrapper& emu = ((MainWindow*)(parentWidget()->parentWidget()->parentWidget()))->emu;
if(emu.isInited()){
QPainter painter(this);
QImage image = emu.getFramebufferImage().scaled(painter.window().size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
painter.drawImage((painter.window().width() - image.width()) / 2, (painter.window().height() - image.height()) / 2, image);
}
}
void TouchScreen::mousePressEvent(QMouseEvent* ev){
if(ev->x() >= 0 && ev->x() < this->width() && ev->y() >= 0 && ev->y() < this->height()){
EmuWrapper& emu = ((MainWindow*)(parentWidget()->parentWidget()->parentWidget()))->emu;

View File

@@ -1,9 +1,10 @@
#pragma once
#include <QLabel>
#include <QWidget>
#include <QPaintEvent>
#include <QMouseEvent>
class TouchScreen : public QLabel{
class TouchScreen : public QWidget{
Q_OBJECT
private:
@@ -14,6 +15,7 @@ public:
~TouchScreen();
protected:
void paintEvent(QPaintEvent* ev);
void mousePressEvent(QMouseEvent* ev);
void mouseMoveEvent(QMouseEvent* ev);
void mouseReleaseEvent(QMouseEvent* ev);

View File

@@ -1,4 +1,4 @@
# Palm m515/OS 4.1 emulator(Mu)
# Palm OS emulator(Mu)
This is a complete restart of my Palm OS emulator, with the last one the code got too messy and the goal too ambitious(to emulate every palm API in software and for compatibility with all Palm OS versions and devices).
@@ -17,41 +17,17 @@ It is the best Palm brand OS 4 device that has no special hardware builtin(cellp
The Palm keyboard attachment will likely be emulated later on so the PC keyboard can be used on text fields.
## OS improvements
## What about OS 5?
If there is something the OS does not support(like an OS 5 API) I may add it manually, this will be in the form of a custom firmware as a ROM image or a .bps patch, not a patch to the emulator with only 1 exception "PceNativeCall" which would require an ARM interpreter, it would also be an option to not apply this patch leaving you with an accurately emulated stock Palm m515.
These patches will not be worked on until the emulator is actually running.
## But you shouldnt waste your time on OS 4, OS 5 can do more.
I have made a video of OS 5 doing that "more", it is extremely incompatible with OS 4 games which most games are, very few games used the ARM CPU and those that did are available on other platforms, some used the 320x320 display mode.
On Clie PEG-SL10:
ArgonV: Normal
Galax: Normal
Zap!20XX: Normal
Invaders: Normal
Platypus: No ARM CPU, Cant Run
On Palm T|X:
ArgonV: Runs At Warpspeed
Galax: Audio Cuts Out
Zap!20XX: Audio Cuts Out
Invaders: Reboots System
Platypus: Normal, Used To Prove Speaker Isnt Defective
Bonus: Has Adware(Addit)
[Palm T|X vs OS 4 Games](https://youtu.be/ithVLI_M6i0)
The lack of ARM CPU will be fixed in my emulator see "OS improvements".
I am planning on adding Tungsten T3 support as soon as possible.
## Credits
uARM (ARMv5 Core)
Musashi v3.4 (last version that builds outside of MAME)(68k Core)
blip_buf 1.1.0 (Audio Resampler)
http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/App-palm-icon.html (Desktop Icon)
http://tango.freedesktop.org/Tango_Icon_Library (Palm Action Buttons, All UI buttons)
[Firebird Emu](https://github.com/nspire-emus/firebird) (ARMv5TE Core)
[uARM](https://dmitry.gr/?r=05.Projects&proj=07.%20Linux%20on%208bit) (PXA260 CPU Peripherals)
[Musashi v3.4](https://github.com/kstenerud/Musashi) (last version that builds outside of MAME)(68k Core)
[blip_buf 1.1.0](https://github.com/TASVideos/BizHawk/tree/master/blip_buf) (Audio Resampler)
https://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/App-palm-icon.html (Desktop Icon)
https://tango.freedesktop.org/Tango_Icon_Library (Palm Action Buttons, All UI buttons)
https://www.iconfinder.com/icons/2317746/chip_computer_cpu_device_frequency_microchip_processor_icon (hwTestSuite Icon)
https://www.flaticon.com/free-icon/cow_235371#term=cow&page=1&position=13 (muExpDriver Icon)
https://findicons.com/icon/164302/cursor (Libretro Port Joystick Cursor)
@@ -89,6 +65,7 @@ Install prc-tools from the below link(self compiled or prepackaged VM)
#### Files
palmos41-en-m515.rom(all euro languages, from Palm dev program): 412557a221933a8be12622de7a21320a (MD5)
palmos41-en-m515.rom(English only, verified authentic from device): 83cb1d1c76e568b916dc2e7c0bf669f6 (MD5)
palmos52-en-t3.rom: de46ec84d9aabf655eabdf9b00a3845d (MD5)
bootloader-en-m515.rom(v1): 9da101cd2317830649a31f8fa46debec (MD5)
bootloader-en-m515.rom(v2): e64c755205bc3e79d1bc5b70128f688d (MD5)
@@ -97,14 +74,16 @@ I understand not everyone speaks English so I list both ROMs, I do all my testin
#### For Qt
1. Run once to create the directory tree
2. Copy "palmos41-en-m515.rom" to "~/Mu"
3. Copy "bootloader-en-m515.rom" to "~/Mu"
2. Copy "palmos41-en-m515.rom" and "palmos52-en-t3.rom" to "~/Mu"
3. (Optional)Copy "bootloader-en-m515.rom" to "~/Mu"
4. Run emu and press start button
#### For RetroArch
1. Download "Palm OS(Mu)" from "Online Updater->Core Updater"
2. Go back, select "Load Core", select "Palm OS(Mu)"
3. Run "palmos41-en-m515.rom"
3. Copy "palmos41-en-m515.rom" and "palmos52-en-t3.rom" to the RetroArch system directory
4. (Optional)Copy "bootloader-en-m515.rom" to the RetroArch system directory
5. Run a .prc or .img file
## Tools
[Prc-tools, Palm OS SDKs, pilrc, pilot-link](https://github.com/meepingsnesroms/prc-tools-remix)

View File

@@ -5,40 +5,55 @@ The end???
v3.2.0 to v4.0.0(*** ** 2020 - *** ** 2020)
Core:
Add Dragonball OG/EZ/VZ CPU builtin LCD controller support, some Palm OS 1<->3 games write directly to these registers to display their video and they won't work(with the exception of LSSA since the OS monitors that one)
add Dragonball OG/EZ/VZ CPU builtin LCD controller support too muExpDriver, some Palm OS 1<->3 games write directly to these registers to display their video and they won't work(with the exception of LSSA since the OS monitors that one)
------------------------------------------
v2.5.0 to v3.2.0(*** ** 2019 - *** ** 2020)
v1.1.0 to v3.2.0(*** ** 2020 - *** ** 2020)
RetroArch GUI:
//TODO: allow adding more content after boot
//TODO: get EMU_MANAGE_HOST_CPU_PIPELINE working on other platforms then the main 4
//TODO: get OpenMP working with RetroArch(already works but breaks the no external libs rule)
//TODO: switch to high contrast and top left corner aligned mouse cursors
//FIXED: when compiling with "make platform=windows_x86_64" the dll wont load(theres a really good chance its because "libgomp-1.dll"(the OpenMP handler library) is missing from the RetroArch folder)(fixed by disableing OpenMP :( )
Qt GUI:
//TODO: get circleci builds for QT port on Win/Mac/Linux
//TODO: allow reiniting the emu without closing the program
//FAIL: render with OpenGL widget(should be a major speed boost)(switched to the method from firebird instead and it changed nothing)
Core:
*allow direct 320x320 bitmap rendered over the 160x160 framebuffer expanded 2x in both directions, black pixels will be transparent showing what's on the 160x160 framebuffer
Emu Hwr Driver:
*set fake display framebuffer for 320x320 mode
------------------------------------------
v2.0.0 to v2.5.0(*** ** 2019 - *** ** 2019)
Core:
*add single 16 bit PCM sound stream, mixed with PWM1
Emu Hwr Driver:
*OS 5.1.* sound stream API support(possibly can use PRC file dumped from an OS 5.1.1 device as long as I still add the extra sound stream for it to write to)
------------------------------------------
v1.0.0 to v2.0.0(*** ** 2019 - *** ** 2019)
Core:
*ARM opcode support, most apps that use ARM code work, as long as no OS 5.1.* APIs are used(partialy done, alignment broken)
Emu Hwr Driver:
*ARM CPU is exported to OS 4 with custom PceNativeCall(already done)
*can set fake version number to prevent tripping compatibility checks(already done)
//TODO: thumb mode supposedly dosent work with ARM dynarec, test this and fix mode switches if it does
add Palm Tungsten T3 support
------------------------------------------
v1.0.0 to v1.1.0(Feb 25 2019 - Easter 2019)
RetroArch GUI:
*allow mouse cursor to be rendered with multiple CPUs(removed for now)
*now launches content like cartridge based systems
*make default button layout match default controller layout better
*allow disabling the silkscreen area
*booting without game works again
*add multithreading and pipeline speedups(disabled for now because of compiling issues)
Qt GUI:
//TODO: allow using host serial ports in Palm OS
//TODO: saving states isn't working on Mac OS, it won't create the directory, don't know why(its not the . in the path either already tested), QDir returns false so it is failing?
*fixed state manager not loading until a state is saved
*boot button uses install button icon now, changed install button to icon a "+"
*put back left/right/center keys
*added install and boot buttons to both modes, content loaded with the boot button has separate save paths just like cartridge systems
*added instant boot option, no longer have to wait for the 5 second boot up if you dont want to(instant boot is always on for loading games)
*can now set the feature bits
*can now set the resource directory
*keyboard mapping support
Core:
*implement UART1/2 to fix crashing when beaming or hotsyncing
*PLLFSR timing hack is gone, CLK32 bit now just toggles properly mid CLK32
*SD card access routines are now 6<->7X faster
*add a launcher to load prc/pdb/pqa files
*add frameskip for really low power devices and when video is not needed
*added host CPU pipeline control for another speed up
*implement FEATURE_SYNCED_RTC to make the Palm clock always match the host system clock

View File

@@ -3,12 +3,12 @@
#include "emulator.h"
#include "portability.h"
#include "hardwareRegisters.h"
#include "dbvz.h"
bool ads7846PenIrqEnabled;
static const uint16_t ads7846DockResistorValues[PORT_END] = {0xFFF/*none*/, 0x1EB/*USB cradle*/, 0x000/*serial cradle, unknown*/, 0x000/*USB peripheral, unknown*/, 0x000/*serial peripheral, unknown*/};
static const uint16_t ads7846DockResistorValues[EMU_PORT_END] = {0xFFF/*none*/, 0x1EB/*USB cradle*/, 0x000/*serial cradle, unknown*/, 0x000/*USB peripheral, unknown*/, 0x000/*serial peripheral, unknown*/};
static uint8_t ads7846BitsToNextControl;
static uint8_t ads7846ControlByte;
@@ -33,7 +33,7 @@ void ads7846Reset(void){
ads7846OutputValue = 0x0000;
ads7846ChipSelect = true;
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
m515RefreshTouchState();
#endif
}
@@ -84,7 +84,7 @@ void ads7846SetChipSelect(bool value){
ads7846PenIrqEnabled = true;
ads7846OutputValue = 0x0000;
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
m515RefreshTouchState();
#endif
}
ads7846ChipSelect = value;
@@ -116,7 +116,7 @@ bool ads7846ExchangeBit(bool bitIn){
//control byte and busy cycle finished, get output value
bool bitMode = !!(ads7846ControlByte & 0x08);
bool differentialMode = !(ads7846ControlByte & 0x04);
uint8_t channel = (ads7846ControlByte & 0x70) >> 4;
uint8_t channel = ads7846ControlByte >> 4 & 0x07;
uint8_t powerSave = ads7846ControlByte & 0x03;
//debugLog("Accessed ADS7846 Ch:%d, %d bits, %s Mode, Power Save:%d, PC:0x%08X.\n", channel, bitMode ? 8 : 12, differentialMode ? "Diff" : "Normal", ads7846ControlByte & 0x03, flx68000GetPc());
@@ -202,15 +202,15 @@ bool ads7846ExchangeBit(bool bitIn){
break;
case 2:
//battery, unknown hasent gotten low enough to test yet
//battery
//ads7846OutputValue = 0x600;//5%
//ads7846OutputValue = 0x61C;//30%
//ads7846OutputValue = 0x63C;//40%
//ads7846OutputValue = 0x65C;//60%
//ads7846OutputValue = 0x67C;//80%
//ads7846OutputValue = 0x68C;//100%
ads7846OutputValue = 0x69C;//100%
//ads7846OutputValue = ads7846RangeMap(0, 100, palmMisc.batteryLevel, 0x000, 0x7F8);
//ads7846OutputValue = 0x69C;//100%
ads7846OutputValue = ads7846RangeMap(0, 100, palmMisc.batteryLevel, 0x5FD, 0x68C);
break;
case 3:
@@ -273,7 +273,7 @@ bool ads7846ExchangeBit(bool bitIn){
ads7846PenIrqEnabled = !(powerSave & 0x01);
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
m515RefreshTouchState();
#endif
}

View File

@@ -1,297 +0,0 @@
#include <stdint.h>
#include <stdbool.h>
#include "emulator.h"
#include "hardwareRegisters.h"
#include "memoryAccess.h"
#include "portability.h"
#include "armv5/CPU.h"
#include "m68k/m68k.h"
#include "debug/sandbox.h"
#define ARMV5_CYCLES_PER_OPCODE 2
bool armv5ServiceRequest;
static ArmCpu armv5Cpu;
static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean privileged, UInt8* fsr){
//just gonna have ARM and 68k share the same bus for now, ARM may want fonts/bitmaps from ROM
//Fake ARM 32 bit alignment convention
//0x0XXXXXXX<->0x1XXXXXXX Normal memory access
//0x20000000<->0x3XXXXXXX Mirrored range, realAddress = address - 0x20000000 + 0x00000002
//this will still fail if ARM allocates a 16 bit aligned buffer and passes it to the m68k,
//but it allows 16 bit aligned data to be executed from the 68k stack and works as a
//temporary measure until I get MemChunkNew patched correctly
//while executing wont support non 32 bit alignment regular accesses can for now
/*
#if !defined(EMU_NO_SAFETY)
//size is not a power of two or address isnt aligned to size
if(size & (size - 1) || vaddr & (size - 1)){
debugLog("ARM attempted unaligned access: address:0x%08X, size:%d\n", vaddr, size);
return false;
}
#endif
*/
if(vaddr & 0x20000000)
vaddr ^= 0x20000002;
if(write){
switch(size){
case 1:
m68k_write_memory_8(vaddr, *(uint8_t*)buf);
return true;
case 2:
m68k_write_memory_16(vaddr, SWAP_16(*(uint16_t*)buf));
return true;
case 4:
m68k_write_memory_32(vaddr, SWAP_32(*(uint32_t*)buf));
return true;
default:
debugLog("Invalid ARMv5 write: address:0x%08X, size:%d\n", vaddr, size * 8);
return false;
}
}
else{
switch(size){
case 1:
*(uint8_t*)buf = m68k_read_memory_8(vaddr);
return true;
case 2:
*(uint16_t*)buf = SWAP_16(m68k_read_memory_16(vaddr));
return true;
case 4:
*(uint32_t*)buf = SWAP_32(m68k_read_memory_32(vaddr));
return true;
default:
debugLog("Invalid ARMv5 read: address:0x%08X, size:%d\n", vaddr, size * 8);
return false;
}
}
}
static Boolean armv5Hypercall(ArmCpu* cpu){
armv5ServiceRequest = true;
return true;
}
static void armv5EmulErr(ArmCpu* cpu, const char* errStr){
debugLog("%s\n", errStr);
}
static void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus){
//TODO
}
void armv5Reset(void){
cpuInit(&armv5Cpu, 0x00000000/*PC, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr);
armv5ServiceRequest = false;
}
uint32_t armv5StateSize(void){
uint32_t size = 0;
//armv5Cpu
size += sizeof(uint32_t) * 16;//armv5Cpu.regs
size += sizeof(uint32_t) * 2;//armv5Cpu.CPSR / armv5Cpu.SPSR
size += sizeof(uint32_t) * 3 * 6;//armv5Cpu.bank_(usr/svc/abt/und/irq/fiq)
size += sizeof(uint32_t) * 5;//armv5Cpu.extra_regs
size += sizeof(uint16_t) * 3;//armv5Cpu.waiting(Irqs/Fiqs) / armv5Cpu.CPAR
size += sizeof(uint32_t);//armv5Cpu.vectorBase
//variables
size += sizeof(uint8_t);//armv5ServiceRequest
return size;
}
void armv5SaveState(uint8_t* data){
uint32_t offset = 0;
uint8_t index;
//armv5Cpu
for(index = 0; index < 16; index++){
writeStateValue32(data + offset, armv5Cpu.regs[index]);
offset += sizeof(uint32_t);
}
writeStateValue32(data + offset, armv5Cpu.CPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_usr.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_usr.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_usr.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_svc.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_svc.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_svc.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_abt.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_abt.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_abt.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_und.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_und.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_und.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_irq.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_irq.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_irq.SPSR);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_fiq.R13);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_fiq.R14);
offset += sizeof(uint32_t);
writeStateValue32(data + offset, armv5Cpu.bank_fiq.SPSR);
offset += sizeof(uint32_t);
for(index = 0; index < 5; index++){
writeStateValue32(data + offset, armv5Cpu.extra_regs[index]);
offset += sizeof(uint32_t);
}
writeStateValue16(data + offset, armv5Cpu.waitingIrqs);
offset += sizeof(uint16_t);
writeStateValue16(data + offset, armv5Cpu.waitingFiqs);
offset += sizeof(uint16_t);
writeStateValue16(data + offset, armv5Cpu.CPAR);
offset += sizeof(uint16_t);
writeStateValue32(data + offset, armv5Cpu.vectorBase);
offset += sizeof(uint32_t);
//variables
writeStateValue8(data + offset, armv5ServiceRequest);
offset += sizeof(uint8_t);
}
void armv5LoadState(uint8_t* data){
uint32_t offset = 0;
uint8_t index;
//armv5Cpu
for(index = 0; index < 16; index++){
armv5Cpu.regs[index] = readStateValue32(data + offset);
offset += sizeof(uint32_t);
}
armv5Cpu.CPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_usr.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_usr.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_usr.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_svc.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_svc.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_svc.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_abt.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_abt.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_abt.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_und.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_und.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_und.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_irq.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_irq.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_irq.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_fiq.R13 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_fiq.R14 = readStateValue32(data + offset);
offset += sizeof(uint32_t);
armv5Cpu.bank_fiq.SPSR = readStateValue32(data + offset);
offset += sizeof(uint32_t);
for(index = 0; index < 5; index++){
armv5Cpu.extra_regs[index] = readStateValue32(data + offset);
offset += sizeof(uint32_t);
}
armv5Cpu.waitingIrqs = readStateValue16(data + offset);
offset += sizeof(uint16_t);
armv5Cpu.waitingFiqs = readStateValue16(data + offset);
offset += sizeof(uint16_t);
armv5Cpu.CPAR = readStateValue16(data + offset);
offset += sizeof(uint16_t);
armv5Cpu.vectorBase = readStateValue32(data + offset);
offset += sizeof(uint32_t);
//variables
armv5ServiceRequest = readStateValue8(data + offset);
offset += sizeof(uint8_t);
}
uint32_t armv5GetRegister(uint8_t reg){
return cpuGetRegExternal(&armv5Cpu, reg);
}
void armv5SetRegister(uint8_t reg, uint32_t value){
cpuSetReg(&armv5Cpu, reg, value);
}
int32_t armv5Execute(int32_t cycles){
#if defined(EMU_DEBUG)
uint32_t ranOpcodes = 0;
#endif
armv5ServiceRequest = false;
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX)
sandboxSetCpuArch(SANDBOX_CPU_ARCH_ARMV5);
#endif
//execution aborts on hypercall to request things from the m68k
while(cycles > 0 && !armv5ServiceRequest){
cpuCycleNoIrqs(&armv5Cpu);
cycles -= ARMV5_CYCLES_PER_OPCODE;
#if defined(EMU_DEBUG)
ranOpcodes++;
#endif
}
#if defined(EMU_DEBUG)
debugLog("%d ARM opcodes have been ran\n", ranOpcodes);
#endif
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX)
sandboxSetCpuArch(SANDBOX_CPU_ARCH_M68K);
#endif
return cycles;
}
uint32_t armv5GetPc(void){
return cpuGetRegExternal(&armv5Cpu, 15/*pc*/);
}

View File

@@ -1,20 +0,0 @@
#ifndef ARMV5_H
#define ARMV5_H
#include <stdint.h>
#include <stdbool.h>
extern bool armv5ServiceRequest;
void armv5Reset(void);
uint32_t armv5StateSize(void);
void armv5SaveState(uint8_t* data);
void armv5LoadState(uint8_t* data);
uint32_t armv5GetRegister(uint8_t reg);
void armv5SetRegister(uint8_t reg, uint32_t value);
int32_t armv5Execute(int32_t cycles);//returns cycles left
uint32_t armv5GetPc(void);//only for debugging
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,173 +0,0 @@
#ifndef UARM_CPU_H
#define UARM_CPU_H
//#define ARM_V6 //define to allow v6 instructions
//#define THUMB_2 //define to allow Thumb2
#include "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; //not using icache for now
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 cpuCycleNoIrqs(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);
#endif

View File

@@ -1,140 +0,0 @@
#include "types.h"
#include "CPU.h"
#include "icache.h"
//#define ICACHE_DEBUGGING
#ifdef ICACHE_DEBUGGING
#define _icache_fetch_func icacheFetch_
#define _icache_test_func icacheFetch
#else
#define _icache_fetch_func icacheFetch
#define _icache_test_func icacheFetch_test
#endif
void icacheInval(icache* ic){
UInt8 i, j;
for(i = 0; i < ICACHE_BUCKET_NUM; i++){
for(j = 0; j < ICACHE_BUCKET_SZ; j++) ic->lines[i][j].info = 0;
ic->ptr[i] = 0;
}
}
void icacheInit(icache* ic, ArmCpu* cpu, ArmCpuMemF memF){
ic->cpu = cpu;
ic->memF = memF;
icacheInval(ic);
}
static UInt8 icachePrvHash(UInt32 addr){
addr >>= ICACHE_L;
addr &= (1UL << ICACHE_S) - 1UL;
return addr;
}
void icacheInvalAddr(icache* ic, UInt32 va){
UInt32 off = va % ICACHE_LINE_SZ;
Int8 i, j, bucket;
icacheLine* lines;
va -= off;
bucket = icachePrvHash(va);
lines = ic->lines[bucket];
for(i = 0, j = ic->ptr[bucket]; (UInt8)i < ICACHE_BUCKET_SZ; i++){
if(--j == -1) j = ICACHE_BUCKET_SZ - 1;
if((lines[j].info & (ICACHE_ADDR_MASK | ICACHE_USED_MASK)) == (va | ICACHE_USED_MASK)){ //found it!
lines[j].info = 0;
}
}
}
/*
we cannot have data overlap cachelines since data is self aligned (word on 4-byte boundary, halfwords on2, etc. this is enforced elsewhere
*/
Boolean _icache_fetch_func(icache* ic, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsrP, void* buf){
UInt32 off = va % ICACHE_LINE_SZ;
Int8 i, j, bucket;
icacheLine* lines;
icacheLine* line;
va -= off;
bucket = icachePrvHash(va);
lines = ic->lines[bucket];
for(i = 0, j = ic->ptr[bucket]; (UInt8)i < ICACHE_BUCKET_SZ; i++){
if(--j == -1) j = ICACHE_BUCKET_SZ - 1;
if((lines[j].info & (ICACHE_ADDR_MASK | ICACHE_USED_MASK)) == (va | ICACHE_USED_MASK)){ //found it!
if(sz == 4){
*(UInt32*)buf = *(UInt32*)(lines[j].data + off);
}
else if(sz == 2){
*(UInt16*)buf = *(UInt16*)(lines[j].data + off);
}
else __mem_copy(buf, lines[j].data + off, sz);
return priviledged || !(lines[j].info & ICACHE_PRIV_MASK);
}
}
//if we're here, we found nothing - time to populate the cache
j = ic->ptr[bucket]++;
if(ic->ptr[bucket] == ICACHE_BUCKET_SZ) ic->ptr[bucket] = 0;
line = lines + j;
line->info = va | (priviledged ? ICACHE_PRIV_MASK : 0);
if(!ic->memF(ic->cpu, line->data, va, ICACHE_LINE_SZ, false, priviledged, fsrP)){
return false;
}
line->info |= ICACHE_USED_MASK;
if(sz == 4){
*(UInt32*)buf = *(UInt32*)(line->data + off);
}
else if(sz == 2){
*(UInt16*)buf = *(UInt16*)(line->data + off);
}
else __mem_copy(buf, line->data + off, sz);
return true;
}
#include "stdio.h"
Boolean _icache_test_func(icache* ic, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsrP, void* buf){
UInt8 fsrO = -1, fsrT = -1;
UInt8 dataO[4] = {0}, dataT[4] = {0};
Boolean retO, retT;
UInt8 i;
retO = _icache_fetch_func(ic, va, sz, priviledged, &fsrO, dataO);
retT = ic->memF(ic->cpu, dataT, va, sz, false, priviledged, &fsrT);
if((retT != retO) || (fsrT != fsrO) || (dataT[0] != dataO[0]) || (dataT[1] != dataO[1]) || (dataT[2] != dataO[2]) || (dataT[3] != dataO[3])){
fprintf(stderr, "icache fail!");
}
for(i = 0; i < sz; i++) ((UInt8*)buf)[i] = dataT[i];
if(retT) *fsrP = fsrT;
return retT;
}

View File

@@ -1,45 +0,0 @@
#ifndef UARM_ICACHE_H
#define UARM_ICACHE_H
#include "types.h"
#include "CPU.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,539 @@
#include <assert.h>
#include "asmcode.h"
#include "cpu.h"
#include "cpudefs.h"
#include "debug.h"
#include "mmu.h"
// Detect overflow after an addition or subtraction
#define ADD_OVERFLOW(left, right, sum) ((int32_t)(((left) ^ (sum)) & ((right) ^ (sum))) < 0)
#define SUB_OVERFLOW(left, right, sum) ((int32_t)(((left) ^ (right)) & ((left) ^ (sum))) < 0)
static uint32_t add(uint32_t left, uint32_t right, int carry, int setcc) {
uint32_t sum = left + right + carry;
if (!setcc)
return sum;
if (sum < left) carry = 1;
if (sum > left) carry = 0;
arm.cpsr_c = carry;
arm.cpsr_v = ADD_OVERFLOW(left, right, sum);
return sum;
}
// "uint8_t shift_val" is correct here. If it is a shift by register, only the bottom 8 bits are looked at.
static uint32_t shift(uint32_t value, uint8_t shift_type, uint8_t shift_val, bool setcc, bool has_rs)
{
if(shift_val == 0)
{
if(unlikely(!has_rs))
{
switch(shift_type)
{
case SH_ROR:
{
// RRX
bool carry = arm.cpsr_c;
if(setcc) arm.cpsr_c = value & 1;
return value >> 1 | uint32_t(carry) << 31;
}
case SH_ASR:
case SH_LSR: // #32 is encoded as LSR #0
return shift(value, shift_type, 32, setcc, false);
}
}
return value;
}
else if(likely(shift_val < 32))
{
switch(shift_type)
{
case SH_LSL:
if(setcc) arm.cpsr_c = (value >> (32 - shift_val)) & 1;
return value << shift_val;
case SH_LSR:
if(setcc) arm.cpsr_c = (value >> (shift_val - 1)) & 1;
return value >> shift_val;
case SH_ASR:
if(setcc) arm.cpsr_c = (value >> (shift_val - 1)) & 1;
if(value & (1u << 31)) //TODO: Verify!
return ~((~value) >> shift_val);
else
return value >> shift_val;
case SH_ROR:
if(setcc) arm.cpsr_c = (value >> (shift_val - 1)) & 1;
return value >> shift_val | (value << (32 - shift_val));
}
}
else if(shift_val == 32 || shift_type == SH_ASR || shift_type == SH_ROR)
{
switch(shift_type)
{
case SH_LSL: if(setcc) arm.cpsr_c = value & 1; return 0;
case SH_LSR: if(setcc) arm.cpsr_c = !!(value & (1u << 31)); return 0;
case SH_ASR: if(setcc) arm.cpsr_c = !!(value & (1u << 31));
if(value & (1u << 31))
return 0xFFFFFFFF;
else
return 0x00000000;
case SH_ROR: return shift(value, SH_ROR, shift_val & 0b11111, setcc, false);
}
}
else // shift_val > 32
{
if(setcc)
arm.cpsr_c = 0;
return 0;
}
return 0;
}
static uint32_t addr_mode_2(Instruction i)
{
if(!i.mem_proc.not_imm)
return i.mem_proc.immed;
return shift(reg_pc(i.mem_proc.rm), i.mem_proc.shift, i.mem_proc.shift_imm, false, false);
}
static uint32_t rotated_imm(Instruction i, bool setcc)
{
uint32_t imm = i.data_proc.immed_8;
uint8_t count = i.data_proc.rotate_imm << 1;
if(count == 0)
return imm;
imm = (imm >> count) | (imm << (32 - count));
if(setcc)
arm.cpsr_c = !!(imm & (1u << 31));
return imm;
}
static uint32_t addr_mode_1(Instruction i, bool setcc)
{
if(i.data_proc.imm)
return rotated_imm(i, setcc);
if(i.data_proc.reg_shift)
return shift(reg_pc(i.data_proc.rm), i.data_proc.shift, reg(i.data_proc.rs), setcc, true);
else
return shift(reg_pc(i.data_proc.rm), i.data_proc.shift, i.data_proc.shift_imm, setcc, false);
}
static inline void set_nz_flags(uint32_t value) {
arm.cpsr_n = value >> 31;
arm.cpsr_z = value == 0;
}
static inline void set_nz_flags_64(uint64_t value) {
arm.cpsr_n = value >> 63;
arm.cpsr_z = value == 0;
}
void do_arm_instruction(Instruction i)
{
bool exec = true;
// Shortcut for unconditional instructions
if(likely(i.cond == CC_AL))
goto always;
switch(i.cond)
{
case CC_EQ: case CC_NE: exec = arm.cpsr_z; break;
case CC_CS: case CC_CC: exec = arm.cpsr_c; break;
case CC_MI: case CC_PL: exec = arm.cpsr_n; break;
case CC_VS: case CC_VC: exec = arm.cpsr_v; break;
case CC_HI: case CC_LS: exec = !arm.cpsr_z && arm.cpsr_c; break;
case CC_GE: case CC_LT: exec = arm.cpsr_n == arm.cpsr_v; break;
case CC_GT: case CC_LE: exec = !arm.cpsr_z && arm.cpsr_n == arm.cpsr_v; break;
case CC_NV:
if((i.raw & 0xFD70F000) == 0xF550F000)
return;
else if((i.raw & 0xFE000000) == 0xFA000000)
{
// BLX
arm.reg[14] = arm.reg[15];
arm.reg[15] += 4 + ((int32_t) (i.raw << 8) >> 6) + (i.raw >> 23 & 2);
arm.cpsr_low28 |= 0x20; // Enter Thumb mode
return;
}
else
undefined_instruction();
return;
}
exec ^= i.cond & 1;
if(!exec)
return;
always:
uint32_t insn = i.raw;
if((insn & 0xE000090) == 0x0000090)
{
// MUL, SWP, etc.
// LDRH, STRSH, etc.
int type = insn >> 5 & 3;
if (type == 0) {
if ((insn & 0xFC000F0) == 0x0000090) {
/* MUL, MLA: 32x32 to 32 multiplications */
uint32_t res = reg(insn & 15)
* reg(insn >> 8 & 15);
if (insn & 0x0200000)
res += reg(insn >> 12 & 15);
set_reg(insn >> 16 & 15, res);
if (insn & 0x0100000) set_nz_flags(res);
} else if ((insn & 0xF8000F0) == 0x0800090) {
/* UMULL, UMLAL, SMULL, SMLAL: 32x32 to 64 multiplications */
uint32_t left = reg(insn & 15);
uint32_t right = reg(insn >> 8 & 15);
uint32_t reg_lo = insn >> 12 & 15;
uint32_t reg_hi = insn >> 16 & 15;
if (reg_lo == reg_hi)
error("RdLo and RdHi cannot be same for 64-bit multiply");
uint64_t res;
if (insn & 0x0400000) res = (int64_t)(int32_t)left * (int32_t)right;
else res = (uint64_t)left * right;
if (insn & 0x0200000) {
/* Accumulate */
res += (uint64_t)reg(reg_hi) << 32 | reg(reg_lo);
}
set_reg(reg_lo, res);
set_reg(reg_hi, res >> 32);
if (insn & 0x0100000) set_nz_flags_64(res);
} else if ((insn & 0xFB00FF0) == 0x1000090) {
/* SWP, SWPB */
uint32_t addr = reg(insn >> 16 & 15);
uint32_t ld, st = reg(insn & 15);
if (insn & 0x0400000) {
ld = read_byte(addr); write_byte(addr, st);
} else {
ld = read_word(addr); write_word(addr, st);
}
set_reg(insn >> 12 & 15, ld);
} else {
undefined_instruction();
}
} else {
/* Load/store halfword, signed byte/halfword, or doubleword */
int base_reg = insn >> 16 & 15;
int data_reg = insn >> 12 & 15;
int offset = (insn & (1 << 22))
? (insn & 0x0F) | (insn >> 4 & 0xF0)
: reg(insn & 15);
bool writeback = false;
uint32_t addr = reg_pc(base_reg);
if (!(insn & (1 << 23))) // Subtracted offset
offset = -offset;
if (insn & (1 << 24)) { // Offset or pre-indexed addressing
addr += offset;
offset = 0;
writeback = insn & (1 << 21);
} else {
if(insn & (1 << 21))
mmu_check_priv(addr, !((insn & (1 << 20)) || type == 2));
writeback = true;
}
if (insn & (1 << 20)) {
uint32_t data;
if (base_reg == data_reg && writeback)
error("Load instruction modifies base register twice");
if (type == 1) data = read_half(addr); /* LDRH */
else if (type == 2) data = (int8_t) read_byte(addr); /* LDRSB */
else data = (int16_t)read_half(addr); /* LDRSH */
set_reg(data_reg, data);
} else if (type == 1) { /* STRH */
write_half(addr, reg(data_reg));
} else {
if (data_reg & 1) error("LDRD/STRD with odd-numbered data register");
if (type == 2) { /* LDRD */
if ((base_reg & ~1) == data_reg && writeback)
error("Load instruction modifies base register twice");
uint32_t low = read_word(addr);
uint32_t high = read_word(addr + 4);
set_reg(data_reg, low);
set_reg(data_reg + 1, high);
} else { /* STRD */
write_word(addr, reg(data_reg));
write_word(addr + 4, reg(data_reg + 1));
}
}
if (writeback)
set_reg(base_reg, addr + offset);
}
}
else if((insn & 0xD900000) == 0x1000000)
{
// BLX, MRS, MSR, SMUL, etc.
if ((insn & 0xFFFFFD0) == 0x12FFF10) {
/* B(L)X: Branch(, link,) and exchange T bit */
uint32_t target = reg_pc(insn & 15);
if (insn & 0x20)
arm.reg[14] = arm.reg[15];
set_reg_bx(15, target);
} else if ((insn & 0xFBF0FFF) == 0x10F0000) {
/* MRS: Move reg <- status */
set_reg(insn >> 12 & 15, (insn & 0x0400000) ? get_spsr() : get_cpsr());
} else if ((insn & 0xFB0FFF0) == 0x120F000 ||
(insn & 0xFB0F000) == 0x320F000) {
/* MSR: Move status <- reg/imm */
uint32_t val, mask = 0;
if (insn & 0x2000000)
val = rotated_imm(i, false);
else
val = reg(insn & 15);
if (insn & 0x0080000) mask |= 0xFF000000;
if (insn & 0x0040000) mask |= 0x00FF0000;
if (insn & 0x0020000) mask |= 0x0000FF00;
if (insn & 0x0010000) mask |= 0x000000FF;
if (insn & 0x0400000)
set_spsr(val, mask);
else
set_cpsr(val, mask);
} else if ((insn & 0xF900090) == 0x1000080) {
int32_t left = reg(insn & 15);
int16_t right = reg((insn >> 8) & 15) >> ((insn & 0x40) ? 16 : 0);
int32_t product;
int type = insn >> 21 & 3;
if (type == 1) {
/* SMULW<y>, SMLAW<y>: Signed 32x16 to 48 multiply, uses only top 32 bits */
product = (int64_t)left * right >> 16;
if (!(insn & 0x20))
goto accumulate;
} else {
/* SMUL<x><y>, SMLA<x><y>, SMLAL<x><y>: Signed 16x16 to 32 multiply */
product = (int16_t)(left >> ((insn & 0x20) ? 16 : 0)) * right;
}
if (type == 2) {
/* SMLAL<x><y>: 64-bit accumulate */
uint32_t reg_lo = insn >> 12 & 15;
uint32_t reg_hi = insn >> 16 & 15;
int64_t sum;
if (reg_lo == reg_hi)
error("RdLo and RdHi cannot be same for 64-bit accumulate");
sum = product + ((uint64_t)reg(reg_hi) << 32 | reg(reg_lo));
set_reg(reg_lo, sum);
set_reg(reg_hi, sum >> 32);
} else if (type == 0) accumulate: {
/* SMLA<x><y>, SMLAW<y>: 32-bit accumulate */
int32_t acc = reg(insn >> 12 & 15);
int32_t sum = product + acc;
/* Set Q flag on overflow */
arm.cpsr_low28 |= ADD_OVERFLOW(product, acc, sum) << 27;
set_reg(insn >> 16 & 15, sum);
} else {
/* SMUL<x><y>, SMULW<y>: No accumulate */
set_reg(insn >> 16 & 15, product);
}
} else if ((insn & 0xF900FF0) == 0x1000050) {
/* QADD, QSUB, QDADD, QDSUB: Saturated arithmetic */
int32_t left = reg(insn & 15);
int32_t right = reg(insn >> 16 & 15);
int32_t res, overflow;
if (insn & 0x400000) {
/* Doubled right operand */
res = right << 1;
if (ADD_OVERFLOW(right, right, res)) {
/* Overflow, set Q flag and saturate */
arm.cpsr_low28 |= 1 << 27;
res = (res < 0) ? 0x7FFFFFFF : 0x80000000;
}
right = res;
}
if (!(insn & 0x200000)) {
res = left + right;
overflow = ADD_OVERFLOW(left, right, res);
} else {
res = left - right;
overflow = SUB_OVERFLOW(left, right, res);
}
if (overflow) {
/* Set Q flag and saturate */
arm.cpsr_low28 |= 1 << 27;
res = (res < 0) ? 0x7FFFFFFF : 0x80000000;
}
set_reg(insn >> 12 & 15, res);
} else if ((insn & 0xFFF0FF0) == 0x16F0F10) {
/* CLZ: Count leading zeros */
int32_t value = reg(insn & 15);
uint32_t zeros;
for (zeros = 0; zeros < 32 && value >= 0; zeros++)
value <<= 1;
set_reg(insn >> 12 & 15, zeros);
} else if ((insn & 0xFFF000F0) == 0xE1200070) {
gui_debug_printf("Software breakpoint at %08x (%04x)\n",
arm.reg[15], (insn >> 4 & 0xFFF0) | (insn & 0xF));
debugger(DBG_EXEC_BREAKPOINT, 0);
} else
undefined_instruction();
}
else if(likely((insn & 0xC000000) == 0x0000000))
{
// Data processing
bool carry = arm.cpsr_c,
setcc = i.data_proc.s;
uint32_t left = reg_pc(i.data_proc.rn),
right = addr_mode_1(i, setcc),
res = 0;
switch(i.data_proc.op)
{
case OP_AND: res = left & right; break;
case OP_EOR: res = left ^ right; break;
case OP_SUB: res = add( left, ~right, 1, setcc); break;
case OP_RSB: res = add(~left, right, 1, setcc); break;
case OP_ADD: res = add( left, right, 0, setcc); break;
case OP_ADC: res = add( left, right, carry, setcc); break;
case OP_SBC: res = add( left, ~right, carry, setcc); break;
case OP_RSC: res = add(~left, right, carry, setcc); break;
case OP_TST: res = left & right; break;
case OP_TEQ: res = left ^ right; break;
case OP_CMP: res = add( left, ~right, 1, setcc); break;
case OP_CMN: res = add( left, right, 0, setcc); break;
case OP_ORR: res = left | right; break;
case OP_MOV: res = right; break;
case OP_BIC: res = left & ~right; break;
case OP_MVN: res = ~right; break;
}
if(i.data_proc.op < OP_TST || i.data_proc.op > OP_CMN)
set_reg_pc(i.data_proc.rd, res);
if(setcc)
{
// Used for returning from exceptions, for instance
if(i.data_proc.rd == 15)
set_cpsr_full(get_spsr());
else
{
arm.cpsr_n = res >> 31;
arm.cpsr_z = res == 0;
}
}
}
else if((insn & 0xFF000F0) == 0x7F000F0)
undefined_instruction();
else if((insn & 0xC000000) == 0x4000000)
{
// LDR, STRB, etc.
uint32_t base = reg_pc(i.mem_proc.rn),
offset = addr_mode_2(i);
if(!i.mem_proc.u)
offset = -offset;
// Pre-indexed or offset
if(i.mem_proc.p)
base += offset; // Writeback for pre-indexed handled after access
else if(i.mem_proc.w) // Usermode Access
mmu_check_priv(base, !i.mem_proc.l);
// Byte access
if(i.mem_proc.b)
{
if(i.mem_proc.l) set_reg_bx(i.mem_proc.rd, read_byte(base));
else write_byte(base, reg_pc_mem(i.mem_proc.rd));
}
else
{
if(i.mem_proc.l) set_reg_bx(i.mem_proc.rd, read_word(base));
else write_word(base, reg_pc_mem(i.mem_proc.rd));
}
// Post-indexed addressing
if(!i.mem_proc.p)
base += offset;
// Writeback
if(!i.mem_proc.p || i.mem_proc.w)
set_reg(i.mem_proc.rn, base);
}
else if((insn & 0xE000000) == 0x8000000)
{
// LDM, STM, etc.
int base_reg = insn >> 16 & 15;
uint32_t addr = reg(base_reg);
uint32_t new_base = addr;
int count = __builtin_popcount(i.mem_multi.reglist);
if (i.mem_multi.u) { // Increasing
if (i.mem_multi.w) // Writeback
new_base += count * 4;
if (i.mem_multi.p) // Preincrement
addr += 4;
} else { // Decreasing
addr -= count * 4;
if (i.mem_multi.w) // Writeback
new_base = addr;
if (!i.mem_multi.p) // Postdecrement
addr += 4;
}
for (unsigned reg = 0, reglist = i.mem_multi.reglist; reglist && reg < 15; reglist >>= 1, reg++) {
if ((reglist & 1) == 0)
continue;
uint32_t *reg_ptr = &arm.reg[reg];
if (i.mem_multi.s && !i.mem_multi.w && !(i.mem_multi.reglist & (1<<15))) {
// User-mode registers
int mode = arm.cpsr_low28 & 0x1F;
if (reg >= 13) {
if (mode != MODE_USR && mode != MODE_SYS) reg_ptr = &arm.r13_usr[reg - 13];
} else if (reg >= 8) {
if (mode == MODE_FIQ) reg_ptr = &arm.r8_usr[reg - 8];
}
}
if (i.mem_multi.l) { // Load
if (reg_ptr == &arm.reg[base_reg]) {
if (i.mem_multi.w) // Writeback
error("Load instruction modifies base register twice");
reg_ptr = &new_base;
}
*reg_ptr = read_word(addr);
} else { // Store
write_word(addr, *reg_ptr);
}
addr += 4;
}
if (i.mem_multi.reglist & (1 << 15)) {
if (i.mem_multi.l) // Load
set_reg_bx(15, read_word(addr));
else // Store
write_word(addr, reg_pc_mem(15));
}
arm.reg[base_reg] = new_base;
if (i.mem_multi.l && i.mem_multi.s && i.mem_multi.reglist & (1<<15))
set_cpsr_full(get_spsr());
}
else if((insn & 0xE000000) == 0xA000000)
{
// B and BL
if(i.branch.l)
arm.reg[14] = arm.reg[15];
arm.reg[15] += (int32_t) (i.branch.immed << 8) >> 6;
arm.reg[15] += 4;
}
else if((insn & 0xF000F10) == 0xE000F10)
do_cp15_instruction(i);
else if((insn & 0xF000F10) == 0xE000E10)
do_cp14_instruction(i);
else if((insn & 0xF000000) == 0xF000000)
cpu_exception(EX_SWI);
else
undefined_instruction();
}

11
src/armv5te/armsnippets.h Normal file
View File

@@ -0,0 +1,11 @@
/* Declarations for armsnippets */
#ifndef _H_ARMSNIPPETS
#define _H_ARMSNIPPETS
//#include <stdbool.h>
#define armloader_cb()
//bool armloader_load_snippet(enum SNIPPETS snippet, struct armloader_load_params params[], unsigned params_num, void (*callback)(struct arm_state *));
#endif

167
src/armv5te/asmcode.c Normal file
View File

@@ -0,0 +1,167 @@
#include "asmcode.h"
#include "debug.h"
#include "mmu.h"
#include "mem.h"
//TODO: Read breakpoints, alignment checks
#if defined(NO_TRANSLATION)
void flush_translations() {}
#endif
uint32_t FASTCALL read_word(uint32_t addr)
{
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1));
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, false, data_abort);
return read_word(addr);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_read_word(entry);
}
}
entry += addr;
return *(uint32_t*)entry;
}
uint32_t FASTCALL read_byte(uint32_t addr)
{
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1));
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, false, data_abort);
return read_byte(addr);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_read_byte(entry);
}
}
entry += addr;
return *(uint8_t*)entry;
}
uint32_t FASTCALL read_half(uint32_t addr)
{
addr &= ~1;
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1));
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, false, data_abort);
return read_half(addr);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_read_half(entry);
}
}
entry += addr;
return *(uint16_t*)entry;
}
void FASTCALL write_byte(uint32_t addr, uint32_t value)
{
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1) + 1);
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, true, data_abort);
return write_byte(addr, value);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_write_byte(entry, value);
}
}
entry += addr;
if(RAM_FLAGS(entry & ~3) & DO_WRITE_ACTION)
write_action((void*) entry);
*(uint8_t*)entry = value;
}
void FASTCALL write_half(uint32_t addr, uint32_t value)
{
addr &= ~1;
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1) + 1);
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, true, data_abort);
return write_half(addr, value);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_write_half(entry, value);
}
}
entry += addr;
if(RAM_FLAGS(entry & ~3) & DO_WRITE_ACTION)
write_action((void*) entry);
*(uint16_t*)entry = value;
}
void FASTCALL write_word(uint32_t addr, uint32_t value)
{
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1) + 1);
//If the sum doesn't contain the address directly
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID) //Invalid entry
{
addr_cache_miss(addr, true, data_abort);
return write_word(addr, value);
}
else //Physical address
{
entry &= ~AC_FLAGS;
entry += addr;
return mmio_write_word(entry, value);
}
}
entry += addr;
if(RAM_FLAGS(entry & ~3) & DO_WRITE_ACTION)
write_action((void*) entry);
*(uint32_t*)entry = value;
}

50
src/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,400 @@
.macro loadsym reg, name
#ifdef __clang__
adrp \reg, \name\()@PAGE
add \reg, \reg, \name\()@PAGEOFF
#else
adrp \reg, \name
add \reg, \reg, #:lo12:\name
#endif
.endm
.data
.align 3
.global arm
.global cycle_count_delta
.global cpu_events
.global addr_cache
translation_sp: .global translation_sp
.xword 0
.text
.align 2
.global data_abort
translation_enter: .global translation_enter
stp x19, x30, [sp, #-16]!
stp x21, x22, [sp, #-16]!
stp x23, x24, [sp, #-16]!
stp x25, x26, [sp, #-16]!
// Store s into translation_sp
mov x1, sp
loadsym x2, translation_sp
str x1, [x2]
loadsym x19, arm
loadsym x26, addr_cache
ldr x26, [x26]
bl load_virt
b translation_next_enter
// Enter translation, check for thumb
translation_next_bx: .global translation_next_bx
tbnz w0, #0, to_thumb // if(pc & 1) goto to_thumb;
// Enter translation; sets arm.reg[15] = w0
translation_next: .global translation_next
mrs x17, nzcv
str w0, [x19, #15*4]
mov w1, w0
lsr x0, x0, #10
lsl x0, x0, #4
ldr x0, [x26, x0] // x0 = addr_cache[(x0 >> 10) << 1]
tbnz x0, #0, save_return // if(x0 & 1) goto save_return;
// Load RAM_FLAGS
add x0, x0, x1 // x0 = pointer to memory at x0
// Enter translation at x0 (has to be ptr to arm.reg[15]'s memory)
translation_next_enter:
loadsym x23, cpu_events
ldr w23, [x23]
cbnz w23, save_return // if(cpu_events) goto save_return;
mov x21, #80*1024*1024
ldr w21, [x0, x21] // w21 = RAM_FLAGS(x0)
tbz w21, #5, save_return // if((RAM_FLAGS(x0) & RF_CODE_TRANSLATED) == 0) goto save_return;
lsr w21, w21, #9 // w21 = w21 >> RFS_TRANSLATION_INDEX
loadsym x23, translation_table
add x23, x23, x21, lsl #5 // x23 = &translation_table[RAM_FLAGS(x0) >> RFS_TRANSLATION_INDEX]
ldr x24, [x23, #1*8] // x24 = x3->jump_table
ldp x25, x21, [x23, #2*8] // x25 = x23->start_ptr; x21 = x23->end_ptr
sub x21, x21, x0 // x21 = end_ptr - insn_ptr
lsr x21, x21, #2 // x21: number of instructions until the end
sub x25, x0, x25 // x25 = insn_ptr - start_ptr
//lsr x25, x25, #2 // x25 = count of instructions
//lsl x25, x25, #3
lsl x25, x25, #1
ldr x0, [x24, x25] // x0 = jump_table[(insn_ptr - start_ptr) / 4]
// add number of instructions to cycle_count_delta
loadsym x24, cycle_count_delta
ldr w25, [x24]
add w25, w25, w21
str w25, [x24]
cmp w25, #0
bpl save_return // if(cycle_count_delta > 0) goto save_return;
msr nzcv, x17
br x0
translation_jmp_ptr: .global translation_jmp_ptr
mrs x17, nzcv
b translation_next_enter
translation_jmp: .global translation_jmp
mrs x17, nzcv
// add number of instructions to cycle_count_delta
loadsym x24, cycle_count_delta
ldr w25, [x24]
adds w25, w25, #4 // We don't know how much will be executed, so use a possible number
bpl save_return
str w25, [x24]
msr nzcv, x17
br x0
to_thumb:
mrs x17, nzcv
sub w0, w0, #1
str w0, [x19, #15*4] // arm.reg[15] = w0 - 1
ldr w1, [x19, #16*4]
orr w1, w1, #0x20
str w1, [x19, #16*4] // arm.cpsr_low28 |= 0x20
save_return:
loadsym x0, translation_sp
mov x1, #0
str x1, [x0]
bl save_virt
ldp x25, x26, [sp], #16
ldp x23, x24, [sp], #16
ldp x21, x22, [sp], #16
ldp x19, x30, [sp], #16
ret
// Saves the virtual CPU state
save_virt:
stp w2, w3, [x19, #0*4]
stp w4, w5, [x19, #2*4]
stp w6, w7, [x19, #4*4]
stp w8, w9, [x19, #6*4]
stp w10, w11, [x19, #8*4]
stp w12, w13, [x19, #10*4]
stp w14, w15, [x19, #12*4]
str w16, [x19, #14*4]
// Save nzcv (in x17) to struct arm_state again
ubfx x2, x17, #31, #1
ubfx x3, x17, #30, #1
ubfx x4, x17, #29, #1
ubfx x5, x17, #28, #1
strb w2, [x19, #17*4+0]
strb w3, [x19, #17*4+1]
strb w4, [x19, #17*4+2]
strb w5, [x19, #17*4+3]
ret
// Loads the virtual CPU state
// x19 has to be a pointer to the arm_state
load_virt:
// Assemble virtual cpsr_nzcv in x17
ldrb w17, [x19, #17*4+0] // x17 = bit 31
ldrb w3, [x19, #17*4+1] // w3 = bit 30
ldrb w4, [x19, #17*4+2] // w4 = bit 29
ldrb w5, [x19, #17*4+3] // w5 = bit 28
lsl w17, w17, #31
bfi w17, w3, #30, #1
bfi w17, w4, #29, #1
bfi w17, w5, #28, #1
ldp w2, w3, [x19, #0*4]
ldp w4, w5, [x19, #2*4]
ldp w6, w7, [x19, #4*4]
ldp w8, w9, [x19, #6*4]
ldp w10, w11, [x19, #8*4]
ldp w12, w13, [x19, #10*4]
ldp w14, w15, [x19, #12*4]
ldr w16, [x19, #14*4]
ret
read_word_asm: .global read_word_asm
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21] // x22 = *x21
tbnz x22, #0, 1f
ldr w0, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_read_word
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #0
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again
read_half_asm: .global read_half_asm
bic w22, w22, #1
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21] // x22 = *x21
tbnz x22, #0, 1f
ldrh w0, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_read_half
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #0
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again
read_byte_asm: .global read_byte_asm
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21] // x22 = *x21
tbnz x22, #0, 1f
ldrb w0, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_read_byte
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #0
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again
write_word_asm: .global write_word_asm
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21, #8] // x22 = *(x21+1)
tbnz x22, #0, 1f
str w1, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_write_word
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #1
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again
write_half_asm: .global write_half_asm
bic w22, w22, #1
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21, #8] // x22 = *(x21+1)
tbnz x22, #0, 1f
strh w1, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_write_half
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #1
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again
write_byte_asm: .global write_byte_asm
lsr w22, w0, #10
add x21, x26, x22, lsl #4 // x21 = &addr_cache[(x0 >> 10) << 1]
0: ldr x22, [x21, #8] // x22 = *(x21+1)
tbnz x22, #0, 1f
strb w1, [x22, x0]
ret
// Not cached
1: tbnz x22, #1, 2f
// MMIO
bic x22, x22, #3
stp x30, x23, [sp, #-16]!
add x0, x0, x22
mrs x17, nzcv
bl save_virt
bl mmio_write_byte
bl load_virt
ldp x30, x23, [sp], #16
msr nzcv, x17
ret
// Invalid
2: stp x30, x23, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mrs x17, nzcv
bl save_virt
mov x1, #1
loadsym x2, data_abort
bl addr_cache_miss
bl load_virt
ldp x0, x1, [sp], #16
ldp x30, x23, [sp], #16
msr nzcv, x17
b 0b // Try again

334
src/armv5te/asmcode_arm.S Normal file
View File

@@ -0,0 +1,334 @@
.data
translation_sp: .global translation_sp
.word 0
.global arm
.global get_cpsr_flags
.global set_cpsr_flags
.global cycle_count_delta
.global cpu_events
.global read_instruction
.text
#ifdef __clang__
#define streqh strheq
#define streqb strbeq
#define ldreqh ldrheq
#define ldreqb ldrbeq
#endif
#define RF_CODE_TRANSLATED 32
#define RFS_TRANSLATION_INDEX 9
#define AC_INVALID 0b10
#define AC_NOT_PTR 0b01
#define AC_FLAGS (AC_INVALID|AC_NOT_PTR)
#if defined(__clang__)
/* On iOS, .text relocations are permitted and due to
a bug it's unable to handle our way of
avoiding them anyway... */
.macro sym name, no=1
.endm
.macro loadsym reg, name, no=1
ldr \reg, =\name
.endm
#else
/* What you can see here is a really bad way of avoiding
relocations in the .text section.
For each use of an external symbol, you need to insert
a sym (name), (number) here, which generates a word containing the
distance to the symbol relative to pc.
To use it, use loadsym (reg), (name), (number).
The whole process is a way of working around
https://sourceware.org/bugzilla/show_bug.cgi?id=18009
*/
.macro sym name, no=1
addr_\name\()_\no\(): .word \name - _tmp_\name\()_\no - 8
.endm
.macro loadsym reg, name, no=1
ldr \reg, addr_\name\()_\no
_tmp_\name\()_\no: add \reg, \reg, pc
.endm
sym translation_sp
sym arm
sym cpu_events
sym translation_table
sym cycle_count_delta, 2
sym translation_sp, 2
//sym cpu_events, 2
sym cycle_count_delta, 3
sym addr_cache
sym data_abort
sym addr_cache, 2
sym data_abort, 2
sym addr_cache, 3
sym data_abort, 3
sym addr_cache, 4
sym data_abort, 4
sym addr_cache, 5
sym data_abort, 5
sym addr_cache, 6
sym data_abort, 6
#endif
// r0: pointer to the instruction
translation_enter: .global translation_enter
push {r4-r11, lr}
mov r4, r0
loadsym r0, translation_sp
str sp, [r0]
bl get_cpsr
mov r11, r0 // r11 = cpsr
mov r0, r4
add r1, r0, #80*1024*1024 // r1 = &(RAM_FLAGS(r0))
ldr r1, [r1]
loadsym r10, arm // r10 is a pointer to the global arm_state
b translation_next_enter
// r0: pc
translation_next_bx: .global translation_next_bx
tst r0, #1
bne to_thumb
// r0: pc
translation_next: .global translation_next
str r0, [r10, #15*4] // save to arm.reg[15]
bl read_instruction // r0 = pointer to ARM code
cmp r0, #0
beq save_return
translation_jmp_ptr: .global translation_jmp_ptr
add r1, r0, #80*1024*1024 // r1 = &(RAM_FLAGS(r0))
ldr r1, [r1]
tst r1, #RF_CODE_TRANSLATED
beq save_return // not translated
// r0: pointer to instruction
// r1: RAM_FLAGS(r0)
translation_next_enter:
loadsym r2, cpu_events
ldr r2, [r2]
cmp r2, #0
bne save_return
mov r1, r1, lsr #RFS_TRANSLATION_INDEX // r1 is translation index
mov r1, r1, lsl #4
loadsym r2, translation_table
add r1, r2, r1 // r1 points to struct translation now
ldr r2, [r1, #1*4] // load translation.jump_table
ldr r3, [r1, #2*4] // load translation.start_ptr
ldr r4, [r1, #3*4] // load translation.end_ptr
sub r4, r4, r0 // r4 = end_ptr - pc_ptr
mov r4, r4, lsr #2 // r4 = number of instructions to the end
loadsym r6, cycle_count_delta, 2
ldr r5, [r6]
add r5, r5, r4 // add r4 to cycle_count_delta
str r5, [r6]
cmp r5, #0
bpl save_return
sub r0, r0, r3 // r0 = pc_ptr - start_ptr
msr cpsr_f, r11
ldr pc, [r2, r0] // jump to jump_table[r0]
to_thumb:
sub r0, r0, #1
str r0, [r10, #15*4] // arm.reg[PC] = r0
ldr r1, [r10, #16*4]
orr r1, r1, #0x20 // Set thumb bit
str r1, [r10, #16*4]
b save_return
// Invoked from within translated code to jump to other, already translated code
// Target address of translated code is in r0 - only r10 and r11 have to be preserved
// This is used to check for events and leave the translation to process them.
// arm.reg[15] must be set already!
translation_jmp: .global translation_jmp
/* loadsym r1, cpu_events, 2
ldr r2, [r1]
cmp r2, #0
bne save_return*/
loadsym r1, cycle_count_delta, 3
ldr r2, [r1]
add r2, #4 // We don't know how much will be executed, so use a possible number
str r2, [r1]
cmp r2, #0
bpl save_return
msr cpsr_f, r11
bx r0 // Jump to the target
// Save flags and leave, arm.reg[15] must be set already!
save_return:
loadsym r1, translation_sp, 2
mov r0, #0
str r0, [r1]
str r11, [r10, #18*4] // save to arm.cpsr_flags
mov r0, r11 // apply arm.cpsr_flags to arm.cpsr_*
pop {r4-r11, lr}
b set_cpsr_flags
// Below is basically a handcoded assembly version of asmcode.c
//TODO: Invoke write_action for translation invalidation!
write_word_asm: .global write_word_asm
// r0 is address, r1 is value
loadsym r2, addr_cache
ldr r2, [r2]
mov r3, r0, lsr #9
orr r3, r3, #1
ldr r3, [r2, r3, lsl #2] // r3 contains ac_entry
tst r3, #AC_FLAGS
streq r1, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne write_word_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_write_word
write_word_invalid:
push {r0, r1, r2, lr} //r2 for stack alignment
mov r1, #1
loadsym r2, data_abort
bl addr_cache_miss
pop {r0, r1, r2, lr}
b write_word_asm
write_half_asm: .global write_half_asm
// r0 is address, r1 is value
loadsym r2, addr_cache, 2
bic r0, r0, #1
ldr r2, [r2]
mov r3, r0, lsr #9
orr r3, r3, #1
ldr r3, [r2, r3, lsl #2] // r3 contains ac_entry
tst r3, #AC_FLAGS
streqh r1, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne write_half_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_write_half
write_half_invalid:
push {r0, r1, r2, lr} //r2 for stack alignment
mov r1, #1
loadsym r2, data_abort, 2
bl addr_cache_miss
pop {r0, r1, r2, lr}
b write_half_asm
write_byte_asm: .global write_byte_asm
// r0 is address, r1 is value
loadsym r2, addr_cache, 3
ldr r2, [r2]
mov r3, r0, lsr #9
orr r3, r3, #1
ldr r3, [r2, r3, lsl #2] // r3 contains ac_entry
tst r3, #AC_FLAGS
streqb r1, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne write_byte_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_write_byte
write_byte_invalid:
push {r0, r1, r2, lr} //r2 for stack alignment
mov r1, #1
loadsym r2, data_abort, 3
bl addr_cache_miss
pop {r0, r1, r2, lr}
b write_byte_asm
read_word_asm: .global read_word_asm
// r0 is address
loadsym r2, addr_cache, 4
ldr r2, [r2]
mov r3, r0, lsr #10
ldr r3, [r2, r3, lsl #3] // r3 contains ac_entry
tst r3, #AC_FLAGS
ldreq r0, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne read_word_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_read_word
read_word_invalid:
push {r0, lr}
mov r1, #0
loadsym r2, data_abort, 4
bl addr_cache_miss
pop {r0, lr}
b read_word_asm
read_half_asm: .global read_half_asm
// r0 is address
loadsym r2, addr_cache, 5
bic r0, r0, #1
ldr r2, [r2]
mov r3, r0, lsr #10
ldr r3, [r2, r3, lsl #3] // r3 contains ac_entry
tst r3, #AC_FLAGS
ldreqh r0, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne read_half_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_read_half
read_half_invalid:
push {r0, lr}
mov r1, #0
loadsym r2, data_abort, 5
bl addr_cache_miss
pop {r0, lr}
b read_half_asm
read_byte_asm: .global read_byte_asm
// r0 is address
loadsym r2, addr_cache, 6
ldr r2, [r2]
mov r3, r0, lsr #10
ldr r3, [r2, r3, lsl #3] // r3 contains ac_entry
tst r3, #AC_FLAGS
ldreqb r0, [r3, r0]
bxeq lr
str r11, [r10, #18*4] // save to arm.cpsr_flags
tst r3, #AC_INVALID
bne read_byte_invalid
bic r3, #AC_FLAGS
add r0, r3, r0
b mmio_read_byte
read_byte_invalid:
push {r0, lr}
mov r1, #0
loadsym r2, data_abort, 6
bl addr_cache_miss
pop {r0, lr}
b read_byte_asm

496
src/armv5te/asmcode_x86.S Normal file
View File

@@ -0,0 +1,496 @@
// arm_state structure offsets
#define ARM_PC 60
#define ARM_CPSR 64
#define ARM_FLAG_C 70
#define ARM_CONTROL 72
// translation structure offsets
#define TRANS_JUMP_TABLE 4
#define TRANS_END_PTR 12
#define RAM_FLAGS (80*1024*1024) // = 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_TRANSLATED 32
#define RF_CODE_NO_TRANSLATE 64
#define RF_READ_ONLY 128
#define RF_ARMLOADER_CB 256
#define RFS_TRANSLATION_INDEX 9
#define WRITE_SPECIAL_FLAGS 2+32+64
// List of locations of addresses which need to be relocated to addr_cache
// (necessary since it's now allocated at runtime)
.data
.globl ac_reloc_start
ac_reloc_start:
.macro AC_RELOC; 0: .data; .long 0b - 4; .text; .endm
.text
.globl translation_enter
translation_enter:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
pushl %edi
movl %esp, in_translation_esp
movl $arm, %ebx
movl ARM_PC(%ebx), %eax
jmp translation_next
.globl translation_next_bx
translation_next_bx:
testb $1, %al
jne switch_to_thumb
.globl translation_next
translation_next:
movl %eax, ARM_PC(%ebx)
cmpl $0, cycle_count_delta
jns return
cmpl $0, cpu_events
jnz return
// eax = VM_MEM_PTR(eax)
movl %eax, %ecx
shrl $10, %ecx
addl 0(, %ecx, 8), %eax
AC_RELOC
testl $0x80000003, %eax
jnz return
addr_ok:
movl RAM_FLAGS(%eax), %edx
testb $RF_CODE_TRANSLATED, %dl
jz return // Not translated
movl %eax, in_translation_pc_ptr
shrl $RFS_TRANSLATION_INDEX, %edx
shll $4, %edx
addl $translation_table, %edx
// Add one cycle for each instruction from this point to the end
movl TRANS_END_PTR(%edx), %ecx
subl %eax, %ecx
shrl $2, %ecx
addl %ecx, cycle_count_delta
movl TRANS_JUMP_TABLE(%edx), %edx
jmp *(%edx, %eax)
return:
andl $0, in_translation_esp
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
switch_to_thumb:
decl %eax
movl %eax, ARM_PC(%ebx)
orb $0x20, ARM_CPSR(%ebx)
jmp return
// These shift procedures are called only from translated code,
// so they may assume that %ebx == _arm
.align 4
.globl arm_shift_proc
arm_shift_proc:
.long lsl
.long lsr
.long asr
.long 0
.long lsl_carry
.long lsr_carry
.long asr_carry
.long ror_carry
.text
lsl:
cmpb $32, %cl
jae ls_32
shll %cl, %eax
ret
lsr:
cmpb $32, %cl
jae ls_32
shrl %cl, %eax
ret
ls_32:
xorl %eax, %eax
ret
asr:
cmpb $32, %cl
jae asr_32
sarl %cl, %eax
ret
asr_32:
sarl $31, %eax
ret
lsl_carry:
cmpb $32, %cl
jae lsl_carry_32
testb %cl, %cl
je lsl_carry_zero
shll %cl, %eax
setc ARM_FLAG_C(%ebx)
lsl_carry_zero:
ret
lsl_carry_32:
jne ls_carry_33
shrl $1, %eax
setc ARM_FLAG_C(%ebx)
xorl %eax, %eax
ret
lsr_carry:
cmpb $32, %cl
jae lsr_carry_32
testb %cl, %cl
je lsr_carry_zero
shrl %cl, %eax
setc ARM_FLAG_C(%ebx)
lsr_carry_zero:
ret
lsr_carry_32:
jne ls_carry_33
shll $1, %eax
setc ARM_FLAG_C(%ebx)
xorl %eax, %eax
ret
ls_carry_33:
xorl %eax, %eax
movb %al, ARM_FLAG_C(%ebx)
ret
asr_carry:
cmpb $32, %cl
jae asr_carry_32
testb %cl, %cl
je asr_carry_zero
sarl %cl, %eax
setc ARM_FLAG_C(%ebx)
asr_carry_zero:
ret
asr_carry_32:
sarl $31, %eax
sets ARM_FLAG_C(%ebx)
ret
ror_carry:
testb $31, %cl
jz ror_carry_mult_32
rorl %cl, %eax
setc ARM_FLAG_C(%ebx)
ror_carry_zero:
ret
ror_carry_mult_32:
testb %cl, %cl
je ror_carry_zero
testl %eax, %eax
sets ARM_FLAG_C(%ebx)
ret
// uint32_t FASTCALL read_byte(uint32_t addr);
.globl read_byte
.align 16
read_byte:
movl %ecx, %eax
shrl $10, %eax
addl 0(, %eax, 8), %ecx
AC_RELOC
js rb_slow
movl %ecx, %edx
andl $-4, %edx
testb $RF_READ_BREAKPOINT, RAM_FLAGS(%edx)
jnz rb_special
rb_fast:
movzbl (%ecx), %eax
ret
rb_special:
call read_special
jmp rb_fast
rb_slow:
movl 0(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
shll $10, %eax
jc rb_miss
addl %eax, %ecx
jmp mmio_read_byte
rb_miss:
call read_miss
jmp read_byte
// uint32_t FASTCALL read_half(uint32_t addr);
.globl read_half
.align 16
read_half:
movl %ecx, %eax
shrl $10, %eax
addl 0(, %eax, 8), %ecx
AC_RELOC
testl $0x80000001, %ecx
jnz rh_slow
movl %ecx, %edx
andl $-4, %edx
testb $RF_READ_BREAKPOINT, RAM_FLAGS(%edx)
jnz rh_special
rh_fast:
movzwl (%ecx), %eax
ret
rh_special:
call read_special
jmp rh_fast
rh_slow:
movl 0(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
testl $1, %ecx
jnz rh_unaligned
shll $10, %eax
jc rh_miss
addl %eax, %ecx
jmp mmio_read_half
rh_miss:
call read_miss
jmp read_half
rh_unaligned:
call align_fault
decl %ecx
jmp read_half
// uint32_t FASTCALL read_word(uint32_t addr);
.globl read_word
.align 16
read_word:
movl %ecx, %eax
shrl $10, %eax
addl 0(, %eax, 8), %ecx
AC_RELOC
testl $0x80000003, %ecx
jnz rw_slow
testb $RF_READ_BREAKPOINT, RAM_FLAGS(%ecx)
jnz rw_special
rw_fast:
movl (%ecx), %eax
ret
rw_special:
call read_special
jmp rw_fast
rw_slow:
movl 0(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
testl $3, %ecx
jnz rw_unaligned
shll $10, %eax
jc rw_miss
addl %eax, %ecx
jmp mmio_read_word
rw_miss:
call read_miss
jmp read_word
rw_unaligned:
call align_fault
andl $-4, %ecx
jmp read_word
// uint32_t FASTCALL read_word_ldr(uint32_t addr);
.globl read_word_ldr
.align 16
read_word_ldr:
movl %ecx, %eax
shrl $10, %eax
addl 0(, %eax, 8), %ecx
AC_RELOC
testl $0x80000003, %ecx
jnz rwl_slow
testb $RF_READ_BREAKPOINT, RAM_FLAGS(%ecx)
jnz rw_special
movl (%ecx), %eax
ret
rwl_slow:
movl 0(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
testl $3, %ecx
jnz rwl_unaligned
shll $10, %eax
jc rw_miss
addl %eax, %ecx
jmp mmio_read_word
rwl_unaligned:
pushl %ecx
call rw_unaligned
popl %ecx
shll $3, %ecx // Unaligned ldr rotates the word so that
rorl %cl, %eax // addressed byte ends up in low position
ret
read_special:
pushl %ecx
pushl %ecx
call read_action
popl %ecx
popl %ecx
ret
read_miss:
pushl %ecx
pushl $data_abort
pushl $0
pushl %ecx
call addr_cache_miss
addl $12, %esp
popl %ecx
ret
// void FASTCALL write_byte(uint32_t addr, uint8_t value);
.globl write_byte
.align 16
write_byte:
movl %ecx, %eax
shrl $10, %eax
addl 4(, %eax, 8), %ecx
AC_RELOC
js wb_slow
movl %ecx, %eax
andl $-4, %eax
testb $WRITE_SPECIAL_FLAGS, RAM_FLAGS(%eax)
jnz wb_special
wb_fast:
movb %dl, (%ecx)
ret
wb_special:
call write_special
jmp wb_fast
wb_slow:
movl 4(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
shll $10, %eax
jc wb_miss
addl %eax, %ecx
jmp mmio_write_byte
wb_miss:
call write_miss
jmp write_byte
// void FASTCALL write_half(uint32_t addr, uint16_t value);
.globl write_half
.align 16
write_half:
movl %ecx, %eax
shrl $10, %eax
addl 4(, %eax, 8), %ecx
AC_RELOC
testl $0x80000001, %ecx
jnz wh_slow
movl %ecx, %eax
andl $-4, %eax
testb $WRITE_SPECIAL_FLAGS, RAM_FLAGS(%eax)
jnz wh_special
wh_fast:
movw %dx, (%ecx)
ret
wh_special:
call write_special
jmp wh_fast
wh_slow:
movl 4(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
testl $1, %ecx
jnz wh_unaligned
shll $10, %eax
jc wh_miss
addl %eax, %ecx
jmp mmio_write_half
wh_miss:
call write_miss
jmp write_half
wh_unaligned:
call align_fault
decl %ecx
jmp write_half
// void FASTCALL write_word(uint32_t addr, uint32_t value);
.globl write_word
.align 16
write_word:
movl %ecx, %eax
shrl $10, %eax
addl 4(, %eax, 8), %ecx
AC_RELOC
testl $0x80000003, %ecx
jnz ww_slow
testb $WRITE_SPECIAL_FLAGS, RAM_FLAGS(%ecx)
jnz ww_special
ww_fast:
movl %edx, (%ecx)
ret
ww_special:
call write_special
jmp ww_fast
ww_slow:
movl 4(, %eax, 8), %eax
AC_RELOC
subl %eax, %ecx
testl $3, %ecx
jnz ww_unaligned
shll $10, %eax
jc ww_miss
addl %eax, %ecx
jmp mmio_write_word
ww_miss:
call write_miss
jmp write_word
ww_unaligned:
call align_fault
andl $-4, %ecx
jmp write_word
write_special:
pushl %edx
pushl %ecx
pushl %ecx
call write_action
popl %ecx
popl %ecx
popl %edx
ret
write_miss:
pushl %edx
pushl %ecx
pushl $data_abort
pushl $1
pushl %ecx
call addr_cache_miss
addl $12, %esp
popl %ecx
popl %edx
ret
align_fault:
testb $2, arm+ARM_CONTROL
jz 1f
pushl $1
pushl %ecx
call data_abort
1: ret
.data
.globl ac_reloc_end
ac_reloc_end:

View File

@@ -0,0 +1,335 @@
// arm_state structure offsets
#define ARM_PC 60
#define ARM_CPSR 64
#define ARM_FLAG_C 70
#define ARM_CONTROL 72
// translation structure offsets
#define TRANS_JUMP_TABLE 0x08
#define TRANS_START_PTR 0x10
#define TRANS_END_PTR 0x18
// RAM_FLAGS used to have "// = MEM_MAXSIZE" at the end but the clang assembler copys the "//" into the macro, commenting out the arguments of the opcodes that use it
#define RAM_FLAGS (80*1024*1024)
#define RF_READ_BREAKPOINT 1
#define RF_WRITE_BREAKPOINT 2
#define RF_EXEC_BREAKPOINT 4
#define RF_EXEC_DEBUG_NEXT 8
#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)
translation_enter: .global translation_enter
push %rbp
mov %rsp, %rbp
push %rbx
push %rsi
push %rdi
mov %rsp, in_translation_rsp(%rip)
lea arm(%rip), %rbx
mov ARM_PC(%rbx), %eax
jmp translation_next
translation_next_bx: .global translation_next_bx
testb $1, %al
jne switch_to_thumb
translation_next: .global translation_next
mov %eax, ARM_PC(%rbx)
lea cycle_count_delta(%rip), %r8
cmpl $0, (%r8)
jns return
lea cpu_events(%rip), %r8
cmpl $0, (%r8)
jnz return
mov ARM_PC(%rbx), %edi
push %rdi // For 16 byte stack alignment (call pushes 8 itself)
call read_instruction
pop %rdi
cmp $0, %rax
jz return
addr_ok:
movl RAM_FLAGS(%rax), %edx
testb $RF_CODE_TRANSLATED, %dl
jz return // Not translated
lea in_translation_pc_ptr(%rip), %r8
mov %rax, (%r8)
shr $RFS_TRANSLATION_INDEX, %rdx
shl $5, %rdx
lea translation_table(%rip), %r8
add %r8, %rdx
// Add one cycle for each instruction from this point to the end
mov TRANS_END_PTR(%rdx), %rcx
sub %rax, %rcx
shr $2, %rcx
lea cycle_count_delta(%rip), %r8
add %ecx, (%r8)
mov %rax, %rcx
sub TRANS_START_PTR(%rdx), %rcx
mov TRANS_JUMP_TABLE(%rdx), %rdx
jmp *(%rdx, %rcx, 2)
//That is the same as
//shr $2, %rcx
//jmp *(%rdx, %rcx, 8)
return:
lea in_translation_rsp(%rip), %r8
movq $0, (%r8)
pop %rdi
pop %rsi
pop %rbx
pop %rbp
ret
switch_to_thumb:
dec %eax
mov %eax, ARM_PC(%rbx)
orb $0x20, ARM_CPSR(%rbx)
jmp return
.data
// These shift procedures are called only from translated code,
// so they may assume that %rbx == _arm
.align 4
arm_shift_proc: .global arm_shift_proc
.quad lsl
.quad lsr
.quad asr
.quad 0
.quad lsl_carry
.quad lsr_carry
.quad asr_carry
.quad ror_carry
.text
lsl:
cmpb $32, %cl
jae ls_32
shl %cl, %eax
ret
lsr:
cmpb $32, %cl
jae ls_32
shr %cl, %eax
ret
ls_32:
xor %eax, %eax
ret
asr:
cmpb $32, %cl
jae asr_32
sar %cl, %eax
ret
asr_32:
sar $31, %eax
ret
lsl_carry:
cmpb $32, %cl
jae lsl_carry_32
testb %cl, %cl
je lsl_carry_zero
shl %cl, %eax
setc ARM_FLAG_C(%rbx)
lsl_carry_zero:
ret
lsl_carry_32:
jne ls_carry_33
shr $1, %eax
setc ARM_FLAG_C(%rbx)
xor %eax, %eax
ret
lsr_carry:
cmpb $32, %cl
jae lsr_carry_32
testb %cl, %cl
je lsr_carry_zero
shr %cl, %eax
setc ARM_FLAG_C(%rbx)
lsr_carry_zero:
ret
lsr_carry_32:
jne ls_carry_33
shl $1, %eax
setc ARM_FLAG_C(%rbx)
xor %eax, %eax
ret
ls_carry_33:
xor %eax, %eax
movb %al, ARM_FLAG_C(%rbx)
ret
asr_carry:
cmpb $32, %cl
jae asr_carry_32
testb %cl, %cl
je asr_carry_zero
sar %cl, %eax
setc ARM_FLAG_C(%rbx)
asr_carry_zero:
ret
asr_carry_32:
sar $31, %eax
sets ARM_FLAG_C(%rbx)
ret
ror_carry:
testb $31, %cl
jz ror_carry_mult_32
ror %cl, %eax
setc ARM_FLAG_C(%rbx)
ror_carry_zero:
ret
ror_carry_mult_32:
testb %cl, %cl
je ror_carry_zero
test %eax, %eax
sets ARM_FLAG_C(%rbx)
ret
read_word_asm: .global read_word_asm
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz rwa_miss
movl (%rax, %rdi), %eax
ret
rwa_miss:
push %rdx
push %rcx
call read_word
pop %rcx
pop %rdx
ret
write_word_asm: .global write_word_asm
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
add $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz wwa_miss
movl %esi, (%rax, %rdi)
testq $DO_WRITE_ACTION, RAM_FLAGS(%rax, %rdi)
jnz write_action_asm
ret
wwa_miss:
push %rdx
push %rcx
call write_word
pop %rcx
pop %rdx
ret
read_half_asm: .global read_half_asm
and $-2, %rdi
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz rha_miss
movzwl (%rax, %rdi), %eax
ret
rha_miss:
push %rdx
push %rcx
call read_half
pop %rcx
pop %rdx
ret
write_half_asm: .global write_half_asm
and $-2, %rdi
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
add $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz wha_miss
movw %si, (%rax, %rdi)
testq $DO_WRITE_ACTION, RAM_FLAGS(%rax, %rdi)
jnz write_action_asm
ret
wha_miss:
push %rdx
push %rcx
call write_half
pop %rcx
pop %rdx
ret
read_byte_asm: .global read_byte_asm
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz rba_miss
movzb (%rax, %rdi), %rax
ret
rba_miss:
push %rdx
push %rcx
call read_byte
pop %rcx
pop %rdx
ret
write_byte_asm: .global write_byte_asm
mov %rdi, %rax
shr $10, %rax
shl $1, %rax
add $1, %rax
mov addr_cache(%rip), %r8
mov (%r8, %rax, 8), %rax
test $3, %rax
jnz wba_miss
xchg %rsi, %rdx // Can't use %rsi directly
movb %dl, (%rax, %rdi)
xchg %rsi, %rdx
testq $DO_WRITE_ACTION, RAM_FLAGS(%rax, %rdi)
jnz write_action_asm
ret
wba_miss:
push %rdx
push %rcx
call write_byte
pop %rcx
pop %rdx
ret
write_action_asm:
add %rax, %rdi
push %rdx
push %rcx
call write_action
pop %rcx
pop %rdx
ret

81
src/armv5te/bitfield.h Normal file
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

170
src/armv5te/coproc.cpp Normal file
View File

@@ -0,0 +1,170 @@
#include "cpu.h"
#include "cpudefs.h"
#include "mmu.h"
extern "C" {
#include "../pxa260/pxa260.h"
#include "../pxa260/pxa260_PwrClk.h"
}
void do_cp15_mrc(uint32_t insn)
{
uint32_t value;
switch (insn & 0xEF00EF) {
case 0x000000: /* MRC p15, 0, <Rd>, c0, c0, 0: ID Code Register */
//value = 0x41069264; /* ARM926EJ-S revision 4 */
//value = 0x69052100;//Intel PXA260 "01101001000001010010000100000000"
value = 0x69052D05;//Intel PXA261 "01101001000001010010110100000101"
break;
case 0x000010: /* MRC p15, 0, <Rd>, c0, c0, 1: Cache Type Register */
value = 0x1D112152; /* ICache: 16KB 4-way 8 word, DCache: 8KB 4-way 8 word */
break;
case 0x000020: /* MRC p15, 0, <Rd>, c0, c0, 2: TCM Status Register */
value = 0;
break;
case 0x010000: /* MRC p15, 0, <Rd>, c1, c0, 0: Control Register */
value = arm.control;
break;
case 0x020000: /* MRC p15, 0, <Rd>, c2, c0, 0: Translation Table Base Register */
value = arm.translation_table_base;
break;
case 0x030000: /* MRC p15, 0, <Rd>, c3, c0, 0: Domain Access Control Register */
value = arm.domain_access_control;
break;
case 0x050000: /* MRC p15, 0, <Rd>, c5, c0, 0: Data Fault Status Register */
value = arm.data_fault_status;
break;
case 0x050020: /* MRC p15, 0, <Rd>, c5, c0, 1: Instruction Fault Status Register */
value = arm.instruction_fault_status;
break;
case 0x060000: /* MRC p15, 0, <Rd>, c6, c0, 0: Fault Address Register */
value = arm.fault_address;
break;
case 0x07006A: /* MRC p15, 0, <Rd>, c7, c10, 3: Test and clean DCache */
value = 1 << 30;
break;
case 0x07006E: /* MRC p15, 0, <Rd>, c7, c14, 3: Test, clean, and invalidate DCache */
value = 1 << 30;
break;
case 0x0D0000: /* MRC p15, 0, <Rd>, c13, c0, 0: Read FCSE PID */
value = 0;
break;
case 0x0F0000: /* MRC p15, 0, <Rd>, c15, c0, 0: Debug Override Register */
// Unimplemented
value = 0;
break;
case 0x0F0001: /* MRC p15, 0, <Rd>, c15, c1, 0: Unknown */
//TODO: Unknown(implmentation defined cp15 register)
value = 0;
break;
default:
warn("Unknown coprocessor instruction MRC %08X", insn);
value = 0;
break;
}
if ((insn >> 12 & 15) == 15) {
arm.cpsr_n = value >> 31 & 1;
arm.cpsr_z = value >> 30 & 1;
arm.cpsr_c = value >> 29 & 1;
arm.cpsr_v = value >> 28 & 1;
} else
arm.reg[insn >> 12 & 15] = value;
}
void do_cp15_mcr(uint32_t insn)
{
uint32_t value = reg(insn >> 12 & 15);
switch (insn & 0xEF00EF) {
case 0x010000: { /* MCR p15, 0, <Rd>, c1, c0, 0: Control Register */
uint32_t change = value ^ arm.control;
//TODO: actually implement this register fully
/*
if ((value & 0xFFFF8CF0) != 0x00050070)
error("Bad or unimplemented control register value: %x (unsupported: %x)\n", value, (value & 0xFFFF8CF8) ^ 0x00050078);
*/
arm.control = value;
if (change & 1){
// MMU is being turned on or off
addr_cache_flush();
emuprintf("Turned MMU %s\n", value & 1 ? "on" : "off");
}
break;
}
case 0x020000: /* MCR p15, 0, <Rd>, c2, c0, 0: Translation Table Base Register */
arm.translation_table_base = value & ~0x3FFF;
addr_cache_flush();
break;
case 0x030000: /* MCR p15, 0, <Rd>, c3, c0, 0: Domain Access Control Register */
arm.domain_access_control = value;
addr_cache_flush();
break;
case 0x050000: /* MCR p15, 0, <Rd>, c5, c0, 0: Data Fault Status Register */
arm.data_fault_status = value;
break;
case 0x050020: /* MCR p15, 0, <Rd>, c5, c0, 1: Instruction Fault Status Register */
arm.instruction_fault_status = value;
break;
case 0x060000: /* MCR p15, 0, <Rd>, c6, c0, 0: Fault Address Register */
arm.fault_address = value;
break;
case 0x070080: /* MCR p15, 0, <Rd>, c7, c0, 4: Wait for interrupt */
cycle_count_delta = 0;
if (arm.interrupts == 0) {
arm.reg[15] -= 4;
cpu_events |= EVENT_WAITING;
}
break;
case 0x080005: /* MCR p15, 0, <Rd>, c8, c5, 0: Invalidate instruction TLB */
case 0x080007: /* MCR p15, 0, <Rd>, c8, c7, 0: Invalidate TLB */
case 0x080025: /* MCR p15, 0, <Rd>, c8, c5, 1: Invalidate instruction TLB entry */
case 0x080027: /* MCR p15, 0, <Rd>, c8, c7, 1: Invalidate TLB (used by polydumper) */
case 0x070005: /* MCR p15, 0, <Rd>, c7, c5, 0: Invalidate ICache */
case 0x070025: /* MCR p15, 0, <Rd>, c7, c5, 1: Invalidate ICache line */
case 0x070007: /* MCR p15, 0, <Rd>, c7, c7, 0: Invalidate ICache and DCache */
addr_cache_flush();
break;
case 0x080006: /* MCR p15, 0, <Rd>, c8, c6, 0: Invalidate data TLB */
case 0x080026: /* MCR p15, 0, <Rd>, c8, c6, 1: Invalidate data TLB entry */
case 0x070026: /* MCR p15, 0, <Rd>, c7, c6, 1: Invalidate single DCache entry */
case 0x07002A: /* MCR p15, 0, <Rd>, c7, c10, 1: Clean DCache line */
case 0x07002E: /* MCR p15, 0, <Rd>, c7, c14, 1: Clean and invalidate single DCache entry */
case 0x07008A: /* MCR p15, 0, <Rd>, c7, c10, 4: Drain write buffer */
case 0x0F0000: /* MCR p15, 0, <Rd>, c15, c0, 0: Debug Override Register */
#ifdef SUPPORT_LINUX
// Normally ignored, but somehow needed for linux to boot correctly
addr_cache_flush();
#endif
break;
case 0x0F0001: /* MCR p15, 0, <Rd>, c15, c1, 0: Unknown */
//TODO: Unknown(implmentation defined cp15 register)
break;
default:
warn("Unknown coprocessor instruction MCR %08X", insn);
break;
}
}
void do_cp15_instruction(Instruction i)
{
uint32_t insn = i.raw;
if(insn & 0x00100000)
return do_cp15_mrc(insn);
else
return do_cp15_mcr(insn);
}
void do_cp14_instruction(Instruction i)
{
uint32_t instr = i.raw;
bool specialInstr = i.cond == 0xF;
bool success;
success = pxa260pwrClkPrvCoprocRegXferFunc(&pxa260PwrClk, specialInstr, (instr & 0x00100000) != 0, (instr >> 21) & 0x07, (instr >> 12) & 0x0F, (instr >> 16) & 0x0F, instr & 0x0F, (instr >> 5) & 0x07);
//fail if instr dosent actully exist
if(!success)
undefined_instruction();
}

428
src/armv5te/cpu.cpp Normal file
View File

@@ -0,0 +1,428 @@
#include <algorithm>
//#include <mutex>
#include <assert.h>
#include <setjmp.h>
// Uncomment the following line to measure the time until the OS is loaded
// #define BENCHMARK
#ifdef BENCHMARK
#include <time.h>
#endif
#include "armsnippets.h"
#include "asmcode.h"
#include "cpu.h"
#include "cpudefs.h"
#include "debug.h"
#include "emu.h"
#include "mem.h"
#include "mmu.h"
#include "translate.h"
// Global CPU state
struct arm_state arm;
void cpu_arm_loop()
{
while (!exiting && cycle_count_delta < 0 && current_instr_size == 4)
{
arm.reg[15] &= ~0x3; // Align PC
Instruction *p = static_cast<Instruction*>(read_instruction(arm.reg[15]));
#ifdef BENCHMARK
static clock_t start = 0;
if(arm.reg[15] == 0)
{
start = clock();
turbo_mode = true;
}
else if(arm.reg[15] == 0x10000000 || arm.reg[15] == 0x11800000)
{
clock_t diff = clock() - start;
printf("%ld ms\n", diff / 1000);
}
#endif
uint32_t *flags_ptr = &RAM_FLAGS(p);
// Check for pending events
if(cpu_events)
{
// Events other than DEBUG_STEP are handled outside
if(cpu_events & ~EVENT_DEBUG_STEP)
break;
goto enter_debugger;
}
// TODO: Other flags
if(*flags_ptr & (RF_EXEC_BREAKPOINT | RF_EXEC_DEBUG_NEXT | RF_ARMLOADER_CB))
{
if(*flags_ptr & RF_ARMLOADER_CB)
{
*flags_ptr &= ~RF_ARMLOADER_CB;
armloader_cb();
}
else
{
if(*flags_ptr & RF_EXEC_BREAKPOINT)
gui_debug_printf("Breakpoint at 0x%08x\n", arm.reg[15]);
enter_debugger:
uint32_t pc = arm.reg[15];
debugger(DBG_EXEC_BREAKPOINT, 0);
if(arm.reg[15] != pc)
continue; // Debugger changed PC
}
}
#ifndef NO_TRANSLATION
else if(do_translate && !(*flags_ptr & DONT_TRANSLATE) && (*flags_ptr & RF_CODE_EXECUTED))
translate(arm.reg[15], &p->raw);
// If the instruction is translated, use the translation
if((~cpu_events & EVENT_DEBUG_STEP) && *flags_ptr & RF_CODE_TRANSLATED)
{
#if TRANSLATION_ENTER_HAS_PTR
translation_enter(p);
#else
translation_enter();
#endif
continue;
}
*flags_ptr |= RF_CODE_EXECUTED;
#endif
/*
//TODO: remove this, causes slowdown
if(arm.reg[15] == 0x200AC088)
emuprintf("HAL state set:%d\n", arm.reg[0]);
*/
arm.reg[15] += 4; // Increment now to account for the pipeline
++cycle_count_delta;
do_arm_instruction(*p);
}
}
// Makes arm.reg[15] point to the current instruction
void fix_pc_for_fault()
{
#ifndef NO_TRANSLATION
translate_fix_pc();
#endif
arm.reg[15] -= current_instr_size;
}
void prefetch_abort(uint32_t mva, uint8_t status)
{
warn("Prefetch abort: address=%08x status=%02x\n", mva, status);
arm.reg[15] += 4;
// Fault address register not changed
arm.instruction_fault_status = status;
cpu_exception(EX_PREFETCH_ABORT);
if (mva == arm.reg[15])
error("Abort occurred with exception vectors unmapped");
longjmp(restart_after_exception, 1);
}
void data_abort(uint32_t mva, uint8_t status)
{
fix_pc_for_fault();
warn("Data abort: address=%08x status=%02x instruction at %08x\n", mva, status, arm.reg[15]);
arm.reg[15] += 8;
arm.fault_address = mva;
arm.data_fault_status = status;
cpu_exception(EX_DATA_ABORT);
longjmp(restart_after_exception, 1);
}
void undefined_instruction()
{
fix_pc_for_fault();
if(current_instr_size == 4)
warn("Undefined instruction 0x%08X at 0x%08X\n", read_word(arm.reg[15]), arm.reg[15]);
else
warn("Undefined instruction 0x%04X at 0x%08X\n", read_half(arm.reg[15]), arm.reg[15]);
arm.reg[15] += current_instr_size;
cpu_exception(EX_UNDEFINED);
longjmp(restart_after_exception, 1);
}
void *try_ptr(uint32_t addr)
{
//There are two different addr_cache formats...
#ifdef AC_FLAGS
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1));
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID)
return addr_cache_miss(addr, false, nullptr);
else // MMIO stuff
return nullptr;
}
entry += addr;
return (void*)entry;
#else
void *ptr = &addr_cache[(addr >> 10) << 1][addr];
if(unlikely((uintptr_t)ptr & AC_NOT_PTR))
ptr = addr_cache_miss(addr, false, nullptr);
return ptr;
#endif
}
void * FASTCALL read_instruction(uint32_t addr)
{
//There are two different addr_cache formats...
#ifdef AC_FLAGS
uintptr_t entry = *(uintptr_t*)(addr_cache + ((addr >> 10) << 1));
if(unlikely(entry & AC_FLAGS))
{
if(entry & AC_INVALID)
return addr_cache_miss(addr, false, prefetch_abort);
else // Executing MMIO stuff
error("PC in MMIO range: 0x%x\n", addr);
}
entry += addr;
return (void*)entry;
#else
void *ptr = &addr_cache[(addr >> 10) << 1][addr];
if(unlikely((uintptr_t)ptr & AC_NOT_PTR))
{
ptr = addr_cache_miss(addr, false, prefetch_abort);
if (!ptr)
error("Bad PC: %08x\n", addr);
}
return ptr;
#endif
}
// Update cpu_events
void cpu_int_check()
{
//events arnt threaded like this in Mu, plus this breaks the RetroArch build, some undefined reference thing
//static std::mutex mut;
//std::lock_guard<std::mutex> lg(mut);
if (arm.interrupts & ~arm.cpsr_low28 & 0x80)
cpu_events |= EVENT_IRQ;
else
cpu_events &= ~EVENT_IRQ;
if (arm.interrupts & ~arm.cpsr_low28 & 0x40)
cpu_events |= EVENT_FIQ;
else
cpu_events &= ~EVENT_FIQ;
}
static const constexpr uint8_t exc_flags[] = {
MODE_SVC | 0xC0, /* Reset */
MODE_UND | 0x80, /* Undefined instruction */
MODE_SVC | 0x80, /* Software interrupt */
MODE_ABT | 0x80, /* Prefetch abort */
MODE_ABT | 0x80, /* Data abort */
0, /* Reserved */
MODE_IRQ | 0x80, /* IRQ */
MODE_FIQ | 0xC0, /* FIQ */
};
void cpu_exception(int type)
{
/* Switch mode, disable interrupts */
uint32_t old_cpsr = get_cpsr();
set_cpsr_full((old_cpsr & ~0x3F) | exc_flags[type]);
*ptr_spsr() = old_cpsr;
/* Branch-and-link to exception handler */
arm.reg[14] = arm.reg[15];
arm.reg[15] = type << 2;
if (arm.control & 0x2000) /* High vectors */
arm.reg[15] += 0xFFFF0000;
}
uint32_t get_cpsr_flags()
{
return arm.cpsr_n << 31
| arm.cpsr_z << 30
| arm.cpsr_c << 29
| arm.cpsr_v << 28;
}
void set_cpsr_flags(uint32_t flags)
{
arm.cpsr_n = (flags >> 31) & 1;
arm.cpsr_z = (flags >> 30) & 1;
arm.cpsr_c = (flags >> 29) & 1;
arm.cpsr_v = (flags >> 28) & 1;
}
// Get full CPSR register
uint32_t get_cpsr()
{
return arm.cpsr_n << 31
| arm.cpsr_z << 30
| arm.cpsr_c << 29
| arm.cpsr_v << 28
| arm.cpsr_low28;
}
void set_cpsr_full(uint32_t cpsr)
{
uint8_t old_mode = arm.cpsr_low28 & 0x1F,
new_mode = cpsr & 0x1F;
if(old_mode == new_mode)
goto same_mode;
// Only FIQ mode has more than 2 regs banked
if(old_mode == MODE_FIQ)
std::copy(arm.reg + 8, arm.reg + 13, arm.r8_fiq);
else
std::copy(arm.reg + 8, arm.reg + 13, arm.r8_usr);
switch(old_mode)
{
case MODE_USR: case MODE_SYS:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_usr);
break;
case MODE_FIQ:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_fiq);
break;
case MODE_IRQ:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_irq);
break;
case MODE_SVC:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_svc);
break;
case MODE_ABT:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_abt);
break;
case MODE_UND:
std::copy(arm.reg + 13, arm.reg + 15, arm.r13_und);
break;
default: assert(false);
}
if(new_mode == MODE_FIQ)
std::copy(arm.r8_fiq, arm.r8_fiq + 5, arm.reg + 8);
else
std::copy(arm.r8_usr, arm.r8_usr + 5, arm.reg + 8);
switch(new_mode)
{
case MODE_USR: case MODE_SYS:
std::copy(arm.r13_usr, arm.r13_usr + 2, arm.reg + 13);
break;
case MODE_FIQ:
std::copy(arm.r13_fiq, arm.r13_fiq + 2, arm.reg + 13);
break;
case MODE_IRQ:
std::copy(arm.r13_irq, arm.r13_irq + 2, arm.reg + 13);
break;
case MODE_SVC:
std::copy(arm.r13_svc, arm.r13_svc + 2, arm.reg + 13);
break;
case MODE_ABT:
std::copy(arm.r13_abt, arm.r13_abt + 2, arm.reg + 13);
break;
case MODE_UND:
std::copy(arm.r13_und, arm.r13_und + 2, arm.reg + 13);
break;
default: error("Invalid mode 0x%x\n", new_mode);
}
// Access permissions are different
if((old_mode == MODE_USR) ^ (new_mode == MODE_USR))
addr_cache_flush();
same_mode:
if(cpsr & 0x01000000)
error("Jazelle not implemented!");
arm.cpsr_n = (cpsr >> 31) & 1;
arm.cpsr_z = (cpsr >> 30) & 1;
arm.cpsr_c = (cpsr >> 29) & 1;
arm.cpsr_v = (cpsr >> 28) & 1;
arm.cpsr_low28 = cpsr & 0x090000FF; // Mask off reserved bits
cpu_int_check();
}
void FASTCALL set_cpsr(uint32_t cpsr, uint32_t mask) {
if (!(arm.cpsr_low28 & 0x0F)) {
/* User mode. Don't change privileged or execution state bits */
mask &= ~0x010000FF;
}
cpsr = (cpsr & mask) | (get_cpsr() & ~mask);
if (cpsr & 0x20)
error("Cannot set T bit with MSR instruction");
set_cpsr_full(cpsr);
}
uint32_t *ptr_spsr()
{
switch (arm.cpsr_low28 & 0x1F)
{
case MODE_FIQ: return &arm.spsr_fiq;
case MODE_IRQ: return &arm.spsr_irq;
case MODE_SVC: return &arm.spsr_svc;
case MODE_ABT: return &arm.spsr_abt;
case MODE_UND: return &arm.spsr_und;
}
error("Attempted to access SPSR from user or system mode");
}
uint32_t get_spsr() {
return *ptr_spsr();
}
void FASTCALL set_spsr(uint32_t spsr, uint32_t mask) {
*ptr_spsr() ^= (*ptr_spsr() ^ spsr) & mask;
}
uint32_t reg(uint8_t i)
{
if(unlikely(i == 15))
error("PC invalid in this context!\n");
return arm.reg[i];
}
uint32_t reg_pc(uint8_t i)
{
if(unlikely(i == 15))
return arm.reg[15] + 4;
return arm.reg[i];
}
uint32_t reg_pc_mem(uint8_t i)
{
if(unlikely(i == 15))
return arm.reg[15] + 8;
return arm.reg[i];
}
void set_reg(uint8_t i, uint32_t value)
{
if(unlikely(i == 15))
error("PC invalid in this context!\n");
arm.reg[i] = value;
}
void set_reg_pc(uint8_t i, uint32_t value)
{
arm.reg[i] = value;
}
void set_reg_bx(uint8_t i, uint32_t value)
{
arm.reg[i] = value;
if(i == 15 && (value & 1))
{
arm.cpsr_low28 |= 0x20; // Enter Thumb mode
arm.reg[15] -= 1;
}
}

110
src/armv5te/cpu.h Normal file
View File

@@ -0,0 +1,110 @@
/* Declarations for cpu.c */
#ifndef CPU_H
#define CPU_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#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!
}
#ifndef __EMSCRIPTEN__
__attribute__((packed))
#endif
arm_state;
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
src/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

58
src/armv5te/debug.h Normal file
View File

@@ -0,0 +1,58 @@
/* 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 std::string ln_target_folder;
extern "C" {
#endif
extern FILE *debugger_input;
/*
extern bool gdb_connected;
extern bool in_debugger;
extern int rdbg_port;
*/
#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 virt_mem_ptr(x, y) NULL
#define backtrace(x)
#define process_debug_cmd(x) 0
#define debugger(x, y)
#define rdebug_recv()
#define rdebug_bind(x) false
#define rdebug_quit()
#ifdef __cplusplus
}
#endif
#endif

551
src/armv5te/disasm.c Normal file
View File

@@ -0,0 +1,551 @@
#include <stdio.h>
#include "debug.h"
#include "disasm.h"
#include "emu.h"
static char *strcpy2(char *dest, const char *src) {
while ((*dest = *src)) { dest++; src++; }
return dest;
}
const char reg_name[16][4] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"
};
static const char condcode[16][3] = {
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "", "2"
};
enum suffix {
none_,
XY, // halfword signed mul
Y, // halfword signed mul
S, // Bit 20 S: alu, MUL etc
B, // Bit 22 B: LDR/STR, SWP
BT, // Bit 21 T: LDR/STR with postindex (bit 24=0)
M, // Bit 23-24 DA/IA/DB/IB
H, // H/SB/SH
D, // double-word insn
L, // Bit 22 L: LDC/STC
};
enum operand {
none,
REG0, // Bits 0-3 specify register
REG8, // Bits 8-11 specify register
REG12, // Bits 12-15 specify register
REG16, // Bits 16-19 specify register
PSR,
SHFOP, // Bits 0-11 specify shifted reg or immediate
IMMED, // Bits 0-11 specify rotated immediate
MEM,
MEMH,
MEM16,
MULTI,
BRCH, // Bits 0-23 specify branch target
BRCHT, // Bits 0-24 specify branch target for THUMB code
COPR, // Bits 8-11 specify coprocessor number
CDP, MRC, MRRC, MEMC,
BKPT, SWI,
};
static const struct arm_insn {
uint32_t mask;
uint32_t value;
char name[7];
uint8_t suffix;
uint8_t op1, op2, op3, op4;
} table[] = {
{0xFD70F000,0xF550F000, "pld", 0, MEM, none, none, none },
{0xFE000000,0xFA000000, "blx", 0, BRCHT, none, none, none },
/* Coprocessor instructions may have any condition field */
{ 0xFF00000, 0xC400000, "mcrr", 0, COPR, MRRC, none, none },
{ 0xFF00000, 0xC500000, "mrrc", 0, COPR, MRRC, none, none },
{ 0xE100000, 0xC000000, "stc", L, COPR, MEMC, none, none },
{ 0xE100000, 0xC100000, "ldc", L, COPR, MEMC, none, none },
{ 0xF000010, 0xE000000, "cdp", 0, COPR, CDP, none, none },
{ 0xF100010, 0xE000010, "mcr", 0, COPR, MRC, none, none },
{ 0xF100010, 0xE100010, "mrc", 0, COPR, MRC, none, none },
/* No other instructions are valid with condition field 1111 */
{0xF0000000,0xF0000000, "???", 0, none, none, none, none },
{ 0xFE0F0F0, 0x0000090, "mul", S, REG16, REG0, REG8, none },
{ 0xFE000F0, 0x0200090, "mla", S, REG16, REG0, REG8, REG12 },
{ 0xFE000F0, 0x0800090, "umull", S, REG12, REG16, REG0, REG8 },
{ 0xFE000F0, 0x0A00090, "umlal", S, REG12, REG16, REG0, REG8 },
{ 0xFE000F0, 0x0C00090, "smull", S, REG12, REG16, REG0, REG8 },
{ 0xFE000F0, 0x0E00090, "smlal", S, REG12, REG16, REG0, REG8 },
{ 0xFB00FF0, 0x1000090, "swp", B, REG12, REG0, MEM16, none },
{ 0xE0000F0, 0x0000090, "???", 0, none, none, none, none },
{ 0xE1000F0, 0x00000B0, "str", H, REG12, MEMH, none, none },
{ 0xE1010F0, 0x00000D0, "ldr", D, REG12, MEMH, none, none },
{ 0xE1010F0, 0x00000F0, "str", D, REG12, MEMH, none, none },
{ 0xE1000F0, 0x01000B0, "ldr", H, REG12, MEMH, none, none },
{ 0xE1000F0, 0x01000D0, "ldr", H, REG12, MEMH, none, none },
{ 0xE1000F0, 0x01000F0, "ldr", H, REG12, MEMH, none, none },
{ 0xFBF0FFF, 0x10F0000, "mrs", 0, REG12, PSR, none, none },
{ 0xFB0FFF0, 0x120F000, "msr", 0, PSR, REG0, none, none },
{ 0xFF00FF0, 0x1000050, "qadd", 0, REG12, REG0, REG16, none },
{ 0xFF00FF0, 0x1200050, "qsub", 0, REG12, REG0, REG16, none },
{ 0xFF00FF0, 0x1400050, "qdadd", 0, REG12, REG0, REG16, none },
{ 0xFF00FF0, 0x1600050, "qdsub", 0, REG12, REG0, REG16, none },
{0xFFF000F0,0xE1200070, "bkpt", 0, BKPT, none, none, none },
{ 0xFB0F000, 0x320F000, "msr", 0, PSR, IMMED, none, none },
{ 0xFF00090, 0x1000080, "smla", XY,REG16, REG0, REG8, REG12 },
{ 0xFF000B0, 0x1200080, "smlaw", Y, REG16, REG0, REG8, REG12 },
{ 0xFF0F0B0, 0x12000A0, "smulw", Y, REG16, REG0, REG8, none },
{ 0xFF00090, 0x1400080, "smlal", XY,REG12, REG16, REG0, REG8 },
{ 0xFF0F090, 0x1600080, "smul", XY,REG16, REG0, REG8, none },
{ 0xFFFFFF0, 0x12FFF10, "bx", 0, REG0, none, none, none },
{ 0xFFFFFF0, 0x12FFF20, "bxj", 0, REG0, none, none, none },
{ 0xFFFFFF0, 0x12FFF30, "blx", 0, REG0, none, none, none },
{ 0xFFF0FF0, 0x16F0F10, "clz", 0, REG12, REG0, none, none },
{ 0xDE00000, 0x0000000, "and", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0200000, "eor", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0400000, "sub", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0600000, "rsb", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0800000, "add", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0A00000, "adc", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0C00000, "sbc", S, REG12, REG16, SHFOP, none },
{ 0xDE00000, 0x0E00000, "rsc", S, REG12, REG16, SHFOP, none },
{ 0xDF0F000, 0x1100000, "tst", 0, REG16, SHFOP, none, none },
{ 0xDF0F000, 0x1300000, "teq", 0, REG16, SHFOP, none, none },
{ 0xDF0F000, 0x1500000, "cmp", 0, REG16, SHFOP, none, none },
{ 0xDF0F000, 0x1700000, "cmn", 0, REG16, SHFOP, none, none },
{ 0xDE00000, 0x1800000, "orr", S, REG12, REG16, SHFOP, none },
{ 0xDEF0000, 0x1A00000, "mov", S, REG12, SHFOP, none, none },
{ 0xDE00000, 0x1C00000, "bic", S, REG12, REG16, SHFOP, none },
{ 0xDEF0000, 0x1E00000, "mvn", S, REG12, SHFOP, none, none },
/* 4000000-9FFFFFF: word-sized memory accesses */
{ 0xD100000, 0x4000000, "str", BT,REG12, MEM, none, none },
{ 0xD100000, 0x4100000, "ldr", BT,REG12, MEM, none, none },
{ 0xD100000, 0x5000000, "str", B, REG12, MEM, none, none },
{ 0xD100000, 0x5100000, "ldr", B, REG12, MEM, none, none },
{ 0xE100000, 0x8000000, "stm", M, MULTI, none, none, none },
{ 0xE100000, 0x8100000, "ldm", M, MULTI, none, none, none },
/* A000000-BFFFFFF: branches */
{ 0xF000000, 0xA000000, "b", 0, BRCH, none, none, none },
{ 0xF000000, 0xB000000, "bl", 0, BRCH, none, none, none },
/* F000000-FFFFFFF: software interrupt */
{ 0xF000000, 0xF000000, "swi", 0, SWI, none, none, none },
/* Catch-all */
{ 0x0000000, 0x0000000, "???", 0, none, none, none, none },
};
static char *do_shift(char *out, uint32_t insn) {
static const char shifts[4][4] = { "lsl", "lsr", "asr", "ror" };
int shift = insn >> 7 & 31;
int stype = insn >> 5 & 3;
out = strcpy2(out, reg_name[insn & 15]);
if (insn & 0x10) {
// shift by register (for data processing only, not load/store)
if (shift & 1) {
*out++ = '?';
return out;
}
out += sprintf(out, " %s %s", shifts[stype], reg_name[shift >> 1]);
} else {
// shift by immediate
int shift = insn >> 7 & 31;
int stype = insn >> 5 & 3;
if (shift == 0) {
if (stype == 0) {
// lsl #0 is a no-op
return out;
} else if (stype == 3) {
// ror #0
return strcpy2(out, " rrx");
} else {
// lsr #0 and asr #0 act like shift of 32
shift = 32;
}
}
out += sprintf(out, " %s #%d", shifts[stype], shift);
}
return out;
}
static char *do_reglist(char *out, int regs) {
int i;
*out++ = '{';
for (i = 0; i < 16; i++) {
if (regs >> i & 1) {
out = strcpy2(out, reg_name[i]);
if (regs >> i & 2) {
*out++ = '-';
while (regs >> ++i & 1);
out = strcpy2(out, reg_name[i-1]);
}
*out++ = ',';
}
}
out[-1] = '}';
*out = '\0';
return out;
}
uint32_t disasm_arm_insn(uint32_t pc) {
uint32_t *pc_ptr = virt_mem_ptr(pc, 4);
if(!pc_ptr)
return 0;
return disasm_arm_insn2(pc, pc_ptr);
}
uint32_t disasm_arm_insn2(uint32_t pc, uint32_t *pc_ptr) {
char buf[80];
uint32_t insn = *pc_ptr;
char *out = buf + sprintf(buf, "%08x: %08x\t", pc, insn);
int i;
const struct arm_insn *t = table;
while ((insn & t->mask) != t->value)
t++;
out = strcpy2(out, t->name);
switch (t->suffix) {
case XY:
*out++ = (insn & (1 << 5)) ? 't' : 'b';
/* fallthrough */
case Y:
*out++ = (insn & (1 << 6)) ? 't' : 'b';
}
if (!(t->mask & 0xF0000000))
out = strcpy2(out, condcode[insn >> 28]);
switch (t->suffix) {
case S:
if (insn & (1 << 20)) *out++ = 's';
break;
case B:
if (insn & (1 << 22)) *out++ = 'b';
break;
case BT:
if (insn & (1 << 22)) *out++ = 'b';
if (insn & (1 << 21)) *out++ = 't';
break;
case M:
*out++ = (insn & (1 << 23)) ? 'i' : 'd';
*out++ = (insn & (1 << 24)) ? 'b' : 'a';
break;
case H:
if (insn & (1 << 6)) *out++ = 's';
*out++ = (insn & (1 << 5)) ? 'h' : 'b';
break;
case D:
*out++ = 'd';
break;
case L:
if (insn & (1 << 22)) *out++ = 'l';
break;
}
for (i = 0; i < 4 && (&t->op1)[i] != none; i++) {
*out++ = i ? ',' : '\t';
switch ((&t->op1)[i]) {
case REG0: out = strcpy2(out, reg_name[insn & 15]); break;
case REG8: out = strcpy2(out, reg_name[insn >> 8 & 15]); break;
case REG12: out = strcpy2(out, reg_name[insn >> 12 & 15]); break;
case REG16: out = strcpy2(out, reg_name[insn >> 16 & 15]); break;
case SHFOP:
if (!(insn & (1 << 25))) {
out = do_shift(out, insn);
break;
}
/* fallthrough */
case IMMED: {
uint32_t imm = insn & 255, shift = insn >> 7 & 30;
out += sprintf(out, "%08x", imm >> shift | imm << (32 - shift));
break;
}
case PSR:
*out++ = (insn & (1 << 22)) ? 's' : 'c';
*out++ = 'p'; *out++ = 's'; *out++ = 'r';
if (~insn >> 16 & 15) {
*out++ = '_';
if (insn & (1 << 19)) *out++ = 'f';
if (insn & (1 << 18)) *out++ = 's';
if (insn & (1 << 17)) *out++ = 'x';
if (insn & (1 << 16)) *out++ = 'c';
}
break;
case MEM:
*out++ = '[';
out = strcpy2(out, reg_name[insn >> 16 & 15]);
if ((insn & 0x32F0000) == 0x10F0000) {
// immediate, offset mode, PC relative
int addr = insn & 0xFFF;
if (!(insn & (1 << 23))) addr = -addr;
addr += pc + 8;
out -= 2;
out += sprintf(out, "%08x]", addr);
uint32_t *ptr = virt_mem_ptr(addr, 4);
if (ptr)
out += sprintf(out, " = %08x", *ptr);
} else {
if (!(insn & (1 << 24))) // post-index
*out++ = ']';
*out++ = ' ';
*out++ = (insn & (1 << 23)) ? '+' : '-';
*out++ = ' ';
if (insn & (1 << 25)) {
// register offset
if (insn & 0x10) {
// register shifted by register not allowed
*out++ = '?';
} else {
out = do_shift(out, insn);
}
} else {
// immediate offset
if ((insn & 0xFFF) || !(insn & (1 << 23)))
out += sprintf(out, "%03x", insn & 0xFFF);
else
// don't display an added offset of 0
out -= 3;
}
if (insn & (1 << 24)) { // pre-index
*out++ = ']';
if (insn & (1 << 21)) // writeback
*out++ = '!';
}
}
break;
case MEMH:
*out++ = '[';
out = strcpy2(out, reg_name[insn >> 16 & 15]);
if (!(insn & (1 << 24))) // post-index
*out++ = ']';
*out++ = ' ';
*out++ = (insn & (1 << 23)) ? '+' : '-';
*out++ = ' ';
if (insn & (1 << 22)) {
// immediate offset
uint32_t imm = (insn & 0x0F) | (insn >> 4 & 0xF0);
if (imm || !(insn & (1 << 23)))
out += sprintf(out, "%03x", imm);
else
// don't display an added offset of 0
out -= 3;
} else {
// register offset
out = strcpy2(out, reg_name[insn & 15]);
}
if (insn & (1 << 24)) { // pre-index
*out++ = ']';
if (insn & (1 << 21)) // writeback
*out++ = '!';
} else { // post-index
// writeback assumed, setting W bit is invalid.
if (insn & (1 << 21))
*out++ = '?';
}
break;
case MEM16:
out += sprintf(out, "[%s]", reg_name[insn >> 16 & 15]);
break;
case MULTI:
out = strcpy2(out, reg_name[insn >> 16 & 15]);
if (insn & (1 << 21)) // Writeback
*out++ = '!';
*out++ = ',';
out = do_reglist(out, insn & 0xFFFF);
if (insn & (1 << 22)) // Load PSR or force user mode
*out++ = '^';
break;
case BRCH:
out += sprintf(out, "%08x", pc + 8 + ((int)insn << 8 >> 6));
break;
case BRCHT:
out += sprintf(out, "%08x", pc + 8 + ((int)insn << 8 >> 6 | (insn >> 23 & 2)));
break;
case COPR:
out += sprintf(out, "p%d", insn >> 8 & 15);
break;
case CDP:
out += sprintf(out, "%d,c%d,c%d,c%d,%d", insn >> 20 & 15,
insn >> 12 & 15, insn >> 16 & 15, insn & 15, insn >> 5 & 7);
break;
case MRC:
out += sprintf(out, "%d,%s,c%d,c%d,%d", insn >> 21 & 7,
reg_name[insn >> 12 & 15], insn >> 16 & 15, insn & 15, insn >> 5 & 7);
break;
case MRRC:
out += sprintf(out, "%d,%s,%s,c%d", insn >> 4 & 15,
reg_name[insn >> 12 & 15], reg_name[insn >> 16 & 15], insn & 15);
break;
case MEMC:
out += sprintf(out, "c%d,[%s", insn >> 12 & 15,
reg_name[insn >> 16 & 15]);
if (!(insn & (1 << 24))) { // Post-indexed or unindexed
*out++ = ']';
if (!(insn & (1 << 21))) {
// Unindexed addressing
if (!(insn & (1 << 23)))
*out++ = '?';
out += sprintf(out, ",{%02x}", insn & 0xFF);
break;
}
}
if (!(insn & (1 << 23)) || insn & 0xFF)
out += sprintf(out, " %c %03x",
(insn & (1 << 23)) ? '+' : '-',
(insn & 0xFF) << 2);
if (insn & (1 << 24)) { // Pre-indexed or offset
*out++ = ']';
if (insn & (1 << 21)) // Writeback (pre-indexed)
*out++ = '!';
}
break;
case BKPT:
out += sprintf(out, "%04x", (insn >> 4 & 0xFFF0) | (insn & 0x0F));
break;
case SWI:
out += sprintf(out, "%06x", insn & 0xFFFFFF);
break;
}
}
*out = '\0';
gui_debug_printf(buf);
gui_debug_printf("\n");
return 4;
}
uint32_t disasm_thumb_insn(uint32_t pc) {
char buf[80];
uint16_t *pc_ptr = virt_mem_ptr(pc, 2);
if (!pc_ptr)
return 0;
uint16_t insn = *pc_ptr;
char *out = buf + sprintf(buf, "%08x: %04x \t", pc, insn);
if (insn < 0x1800) {
static const char name[][4] = { "lsl", "lsr", "asr" };
sprintf(out, "%s\tr%d,r%d,%02x", name[insn >> 11],
insn & 7, insn >> 3 & 7, insn >> 6 & 31);
} else if (insn < 0x2000) {
sprintf(out, "%s\tr%d,r%d,%s%d",
(insn & 0x0200) ? "sub" : "add",
insn & 7, insn >> 3 & 7,
(insn & 0x400) ? "" : "r", insn >> 6 & 7);
} else if (insn < 0x4000) {
static const char name[][4] = { "mov", "cmp", "add", "sub" };
sprintf(out, "%s\tr%d,%02x", name[insn >> 11 & 3],
insn >> 8 & 7, insn & 0xFF);
} else if (insn < 0x4400) {
static const char name[][4] = {
"and", "eor", "lsl", "lsr", "asr", "adc", "sbc", "ror",
"tst", "neg", "cmp", "cmn", "orr", "mul", "bic", "mvn"
};
sprintf(out, "%s\tr%d,r%d", name[insn >> 6 & 15], insn & 7, insn >> 3 & 7);
} else if (insn < 0x4700) {
static const char name[][4] = { "add", "cmp", "mov" };
int rd = (insn & 7) | (insn >> 4 & 8);
int rn = insn >> 3 & 15;
if (!((rd | rn) & 8))
goto invalid;
sprintf(out, "%s\t%s,%s", name[insn >> 8 & 3], reg_name[rd], reg_name[rn]);
} else if (insn < 0x4800) {
if (insn & 7)
goto invalid;
sprintf(out, "%s\t%s", (insn & 0x80) ? "blx" : "bx", reg_name[insn >> 3 & 15]);
} else if (insn < 0x5000) {
int addr = ((pc + 4) & -4) + ((insn & 0xFF) << 2);
out += sprintf(out, "ldr\tr%d,[%08x]", insn >> 8 & 7, addr);
uint32_t *ptr = virt_mem_ptr(addr, 4);
if (ptr)
sprintf(out, " = %08x", *ptr);
} else if (insn < 0x6000) {
static const char name[][6] = {
"str", "strh", "strb", "ldrsb",
"ldr", "ldrh", "ldrb", "ldrsh"
};
sprintf(out, "%s\tr%d,[r%d + r%d]", name[insn >> 9 & 7],
insn & 7, insn >> 3 & 7, insn >> 6 & 7);
} else if (insn < 0x9000) {
static const char name[][5] = { "str", "ldr", "strb", "ldrb", "strh", "ldrh" };
int type = (insn - 0x6000) >> 11;
sprintf(out, "%s\tr%d,[r%d + %03x]", name[type],
insn & 7, insn >> 3 & 7,
(insn >> 6 & 31) << (0x12 >> (type & 6) & 3));
} else if (insn < 0xA000) {
sprintf(out, "%s\tr%d,[sp + %03x]",
(insn & 0x800) ? "ldr" : "str",
insn >> 8 & 7, (insn & 0xFF) << 2);
} else if (insn < 0xB000) {
sprintf(out, "add\tr%d,%s,%03x",
insn >> 8 & 7,
(insn & 0x800) ? "sp" : "pc", (insn & 0xFF) << 2);
} else if (insn < 0xB100) {
sprintf(out, "%s\tsp,%03x",
(insn & 0x80) ? "sub" : "add", (insn & 0x7F) << 2);
} else if (insn < 0xB400) {
goto invalid;
} else if (insn < 0xB600) {
out = strcpy2(out, "push\t");
do_reglist(out, (insn & 0xFF) | (insn & 0x100) << (14 - 8));
} else if (insn < 0xBC00) {
goto invalid;
} else if (insn < 0xBE00) {
out = strcpy2(out, "pop\t");
do_reglist(out, (insn & 0xFF) | (insn & 0x100) << (15 - 8));
} else if (insn < 0xBF00) {
sprintf(out, "bkpt\t%02x", insn & 0xFF);
} else if (insn < 0xC000) {
goto invalid;
} else if (insn < 0xD000) {
out += sprintf(out, "%smia\tr%d!,", (insn & 0x800) ? "ld" : "st", insn >> 8 & 7);
do_reglist(out, insn & 0xFF);
} else if (insn < 0xDE00) {
sprintf(out, "b%s\t%08x", condcode[insn >> 8 & 15], pc + 4 + ((int8_t)insn << 1));
} else if (insn < 0xDF00) {
invalid:
sprintf(out, "???");
} else if (insn < 0xE000) {
sprintf(out, "swi\t%02x", insn & 0xFF);
} else if (insn < 0xE800) {
sprintf(out, "b\t%08x", pc + 4 + ((int32_t)insn << 21 >> 20));
} else if (insn < 0xF000) {
sprintf(out, "(blx\tlr + %03x)", (insn & 0x7FF) << 1);
} else if (insn < 0xF800) {
int32_t target = (int32_t)insn << 21 >> 9;
/* Check next instruction to see if this is part of a BL or BLX pair */
pc_ptr = virt_mem_ptr(pc + 2, 2);
if (pc_ptr && ((insn = *pc_ptr) & 0xE800) == 0xE800) {
/* It is; show both instructions combined as one */
target += pc + 4 + ((insn & 0x7FF) << 1);
if (!(insn & 0x1000)) target &= ~3;
sprintf(out - 5, "%04x\t%s\t%08x", insn,
(insn & 0x1000) ? "bl" : "blx", target);
gui_debug_printf("%s\n", buf);
return 4;
}
sprintf(out, "(add\tlr,pc,%08x)", target);
} else {
sprintf(out, "(bl\tlr + %03x)", (insn & 0x7FF) << 1);
}
gui_debug_printf("%s\n", buf);
return 2;
}

18
src/armv5te/disasm.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _H_DISASM
#define _H_DISASM
#ifdef __cplusplus
extern "C" {
#endif
extern const char reg_name[16][4];
uint32_t disasm_arm_insn(uint32_t pc);
uint32_t disasm_arm_insn2(uint32_t pc, uint32_t *pc_ptr);
uint32_t disasm_thumb_insn(uint32_t pc);
#ifdef __cplusplus
}
#endif
#endif

56
src/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

20
src/armv5te/emuVarPool.c Normal file
View File

@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <setjmp.h>
#include "cpu.h"
#include "mem.h"
#include "emu.h"
/* cycle_count_delta is a (usually negative) number telling what the time is relative
* to the next scheduled event. See sched.c */
int cycle_count_delta;
bool exiting;
bool do_translate;
jmp_buf restart_after_exception;
uint32_t cpu_events;

Some files were not shown because too many files have changed in this diff Show More