gemba 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/THIRD_PARTY_NOTICES +37 -2
  3. data/assets/placeholder_boxart.png +0 -0
  4. data/bin/gemba +2 -2
  5. data/ext/gemba/extconf.rb +24 -1
  6. data/ext/gemba/gemba_ext.c +436 -2
  7. data/ext/gemba/gemba_ext.h +2 -0
  8. data/gemba.gemspec +5 -3
  9. data/lib/gemba/achievements/achievement.rb +23 -0
  10. data/lib/gemba/achievements/backend.rb +186 -0
  11. data/lib/gemba/achievements/cache.rb +70 -0
  12. data/lib/gemba/achievements/credentials_presenter.rb +142 -0
  13. data/lib/gemba/achievements/fake_backend.rb +205 -0
  14. data/lib/gemba/achievements/null_backend.rb +11 -0
  15. data/lib/gemba/achievements/offline_backend.rb +168 -0
  16. data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
  17. data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
  18. data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
  19. data/lib/gemba/achievements.rb +19 -0
  20. data/lib/gemba/achievements_window.rb +556 -0
  21. data/lib/gemba/app_controller.rb +1015 -0
  22. data/lib/gemba/bios.rb +54 -0
  23. data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
  24. data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
  25. data/lib/gemba/boxart_fetcher.rb +79 -0
  26. data/lib/gemba/bus_emitter.rb +13 -0
  27. data/lib/gemba/child_window.rb +24 -1
  28. data/lib/gemba/cli/commands/config_cmd.rb +83 -0
  29. data/lib/gemba/cli/commands/decode.rb +154 -0
  30. data/lib/gemba/cli/commands/patch.rb +78 -0
  31. data/lib/gemba/cli/commands/play.rb +78 -0
  32. data/lib/gemba/cli/commands/record.rb +114 -0
  33. data/lib/gemba/cli/commands/replay.rb +161 -0
  34. data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
  35. data/lib/gemba/cli/commands/version.rb +22 -0
  36. data/lib/gemba/cli.rb +52 -364
  37. data/lib/gemba/config.rb +135 -1
  38. data/lib/gemba/data/gb_games.json +1 -0
  39. data/lib/gemba/data/gb_md5.json +1 -0
  40. data/lib/gemba/data/gba_games.json +1 -0
  41. data/lib/gemba/data/gba_md5.json +1 -0
  42. data/lib/gemba/data/gbc_games.json +1 -0
  43. data/lib/gemba/data/gbc_md5.json +1 -0
  44. data/lib/gemba/emulator_frame.rb +1060 -0
  45. data/lib/gemba/event_bus.rb +48 -0
  46. data/lib/gemba/frame_stack.rb +60 -0
  47. data/lib/gemba/game_index.rb +84 -0
  48. data/lib/gemba/game_picker_frame.rb +268 -0
  49. data/lib/gemba/gamepad_map.rb +103 -0
  50. data/lib/gemba/headless.rb +6 -5
  51. data/lib/gemba/headless_player.rb +33 -3
  52. data/lib/gemba/help_window.rb +61 -0
  53. data/lib/gemba/hotkey_map.rb +3 -1
  54. data/lib/gemba/input_recorder.rb +107 -0
  55. data/lib/gemba/input_replayer.rb +119 -0
  56. data/lib/gemba/keyboard_map.rb +90 -0
  57. data/lib/gemba/locales/en.yml +97 -5
  58. data/lib/gemba/locales/ja.yml +97 -5
  59. data/lib/gemba/main_window.rb +56 -0
  60. data/lib/gemba/modal_stack.rb +81 -0
  61. data/lib/gemba/patcher_window.rb +223 -0
  62. data/lib/gemba/platform/gb.rb +21 -0
  63. data/lib/gemba/platform/gba.rb +21 -0
  64. data/lib/gemba/platform/gbc.rb +23 -0
  65. data/lib/gemba/platform.rb +20 -0
  66. data/lib/gemba/platform_open.rb +19 -0
  67. data/lib/gemba/recorder.rb +4 -3
  68. data/lib/gemba/replay_player.rb +691 -0
  69. data/lib/gemba/rom_info.rb +57 -0
  70. data/lib/gemba/rom_info_window.rb +16 -3
  71. data/lib/gemba/rom_library.rb +106 -0
  72. data/lib/gemba/rom_overrides.rb +47 -0
  73. data/lib/gemba/rom_patcher/bps.rb +161 -0
  74. data/lib/gemba/rom_patcher/ips.rb +101 -0
  75. data/lib/gemba/rom_patcher/ups.rb +118 -0
  76. data/lib/gemba/rom_patcher.rb +109 -0
  77. data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
  78. data/lib/gemba/runtime.rb +59 -26
  79. data/lib/gemba/save_state_manager.rb +4 -7
  80. data/lib/gemba/save_state_picker.rb +17 -4
  81. data/lib/gemba/session_logger.rb +64 -0
  82. data/lib/gemba/settings/audio_tab.rb +77 -0
  83. data/lib/gemba/settings/gamepad_tab.rb +351 -0
  84. data/lib/gemba/settings/hotkeys_tab.rb +259 -0
  85. data/lib/gemba/settings/paths.rb +11 -0
  86. data/lib/gemba/settings/recording_tab.rb +83 -0
  87. data/lib/gemba/settings/save_states_tab.rb +91 -0
  88. data/lib/gemba/settings/system_tab.rb +362 -0
  89. data/lib/gemba/settings/video_tab.rb +318 -0
  90. data/lib/gemba/settings_window.rb +162 -1036
  91. data/lib/gemba/version.rb +1 -1
  92. data/lib/gemba/virtual_keyboard.rb +19 -0
  93. data/lib/gemba.rb +2 -12
  94. data/test/achievements_window/test_bulk_sync.rb +218 -0
  95. data/test/achievements_window/test_bus_events.rb +125 -0
  96. data/test/achievements_window/test_close_confirmation.rb +201 -0
  97. data/test/achievements_window/test_initial_state.rb +164 -0
  98. data/test/achievements_window/test_sorting.rb +227 -0
  99. data/test/achievements_window/test_tree_rendering.rb +133 -0
  100. data/test/fixtures/fake_bios.bin +0 -0
  101. data/test/fixtures/pong.gba +0 -0
  102. data/test/fixtures/test.gb +0 -0
  103. data/test/fixtures/test.gbc +0 -0
  104. data/test/fixtures/test_quicksave.ss +0 -0
  105. data/test/screenshots/no_focus.png +0 -0
  106. data/test/shared/teek_test_worker.rb +17 -1
  107. data/test/shared/tk_test_helper.rb +91 -4
  108. data/test/support/achievements_window_helpers.rb +18 -0
  109. data/test/support/fake_core.rb +25 -0
  110. data/test/support/fake_ra_runtime.rb +74 -0
  111. data/test/support/fake_requester.rb +68 -0
  112. data/test/support/player_helpers.rb +20 -5
  113. data/test/test_achievement.rb +32 -0
  114. data/test/{test_player.rb → test_app_controller.rb} +353 -85
  115. data/test/test_bios.rb +123 -0
  116. data/test/test_boxart_fetcher.rb +150 -0
  117. data/test/test_cli.rb +17 -265
  118. data/test/test_cli_config.rb +64 -0
  119. data/test/test_cli_decode.rb +97 -0
  120. data/test/test_cli_patch.rb +58 -0
  121. data/test/test_cli_play.rb +213 -0
  122. data/test/test_cli_ra.rb +175 -0
  123. data/test/test_cli_record.rb +69 -0
  124. data/test/test_cli_replay.rb +72 -0
  125. data/test/test_cli_sync_requester.rb +152 -0
  126. data/test/test_cli_version.rb +27 -0
  127. data/test/test_config.rb +2 -3
  128. data/test/test_config_ra.rb +69 -0
  129. data/test/test_core.rb +62 -1
  130. data/test/test_credentials_presenter.rb +192 -0
  131. data/test/test_event_bus.rb +100 -0
  132. data/test/test_fake_backend_achievements.rb +130 -0
  133. data/test/test_fake_backend_auth.rb +68 -0
  134. data/test/test_game_index.rb +77 -0
  135. data/test/test_game_picker_frame.rb +310 -0
  136. data/test/test_gamepad_map.rb +1 -3
  137. data/test/test_headless_player.rb +17 -3
  138. data/test/test_help_window.rb +82 -0
  139. data/test/test_hotkey_map.rb +22 -1
  140. data/test/test_input_recorder.rb +179 -0
  141. data/test/test_input_replay_determinism.rb +113 -0
  142. data/test/test_input_replayer.rb +162 -0
  143. data/test/test_keyboard_map.rb +1 -3
  144. data/test/test_libretro_backend.rb +41 -0
  145. data/test/test_locale.rb +1 -1
  146. data/test/test_logging.rb +123 -0
  147. data/test/test_null_backend.rb +42 -0
  148. data/test/test_offline_backend.rb +116 -0
  149. data/test/test_overlay_renderer.rb +1 -1
  150. data/test/test_platform.rb +149 -0
  151. data/test/test_ra_backend.rb +313 -0
  152. data/test/test_ra_backend_unlock_gate.rb +56 -0
  153. data/test/test_recorder.rb +0 -3
  154. data/test/test_replay_player.rb +316 -0
  155. data/test/test_rom_info.rb +149 -0
  156. data/test/test_rom_overrides.rb +86 -0
  157. data/test/test_rom_patcher.rb +382 -0
  158. data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
  159. data/test/test_save_state_manager.rb +2 -4
  160. data/test/test_settings_audio.rb +107 -0
  161. data/test/test_settings_hotkeys.rb +83 -66
  162. data/test/test_settings_recording.rb +49 -0
  163. data/test/test_settings_save_states.rb +97 -0
  164. data/test/test_settings_system.rb +133 -0
  165. data/test/test_settings_video.rb +450 -0
  166. data/test/test_settings_window.rb +76 -507
  167. data/test/test_tip_service.rb +6 -6
  168. data/test/test_toast_overlay.rb +1 -1
  169. data/test/test_virtual_events.rb +156 -0
  170. data/test/test_virtual_keyboard.rb +1 -1
  171. data/vendor/rcheevos/CHANGELOG.md +495 -0
  172. data/vendor/rcheevos/LICENSE +21 -0
  173. data/vendor/rcheevos/Package.swift +33 -0
  174. data/vendor/rcheevos/README.md +67 -0
  175. data/vendor/rcheevos/include/module.modulemap +70 -0
  176. data/vendor/rcheevos/include/rc_api_editor.h +296 -0
  177. data/vendor/rcheevos/include/rc_api_info.h +280 -0
  178. data/vendor/rcheevos/include/rc_api_request.h +77 -0
  179. data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
  180. data/vendor/rcheevos/include/rc_api_user.h +262 -0
  181. data/vendor/rcheevos/include/rc_client.h +877 -0
  182. data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
  183. data/vendor/rcheevos/include/rc_consoles.h +138 -0
  184. data/vendor/rcheevos/include/rc_error.h +59 -0
  185. data/vendor/rcheevos/include/rc_export.h +100 -0
  186. data/vendor/rcheevos/include/rc_hash.h +200 -0
  187. data/vendor/rcheevos/include/rc_runtime.h +148 -0
  188. data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
  189. data/vendor/rcheevos/include/rc_util.h +51 -0
  190. data/vendor/rcheevos/include/rcheevos.h +8 -0
  191. data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
  192. data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
  193. data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
  194. data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
  195. data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
  196. data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
  197. data/vendor/rcheevos/src/rc_client.c +6941 -0
  198. data/vendor/rcheevos/src/rc_client_external.c +281 -0
  199. data/vendor/rcheevos/src/rc_client_external.h +177 -0
  200. data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
  201. data/vendor/rcheevos/src/rc_client_internal.h +409 -0
  202. data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
  203. data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
  204. data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
  205. data/vendor/rcheevos/src/rc_compat.c +251 -0
  206. data/vendor/rcheevos/src/rc_compat.h +121 -0
  207. data/vendor/rcheevos/src/rc_libretro.c +915 -0
  208. data/vendor/rcheevos/src/rc_libretro.h +98 -0
  209. data/vendor/rcheevos/src/rc_util.c +199 -0
  210. data/vendor/rcheevos/src/rc_version.c +11 -0
  211. data/vendor/rcheevos/src/rc_version.h +32 -0
  212. data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
  213. data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
  214. data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
  215. data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
  216. data/vendor/rcheevos/src/rcheevos/format.c +330 -0
  217. data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
  218. data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
  219. data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
  220. data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
  221. data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
  222. data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
  223. data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
  224. data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
  225. data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
  226. data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
  227. data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
  228. data/vendor/rcheevos/src/rcheevos/value.c +935 -0
  229. data/vendor/rcheevos/src/rhash/aes.c +480 -0
  230. data/vendor/rcheevos/src/rhash/aes.h +49 -0
  231. data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
  232. data/vendor/rcheevos/src/rhash/hash.c +1402 -0
  233. data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
  234. data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
  235. data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
  236. data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
  237. data/vendor/rcheevos/src/rhash/md5.c +382 -0
  238. data/vendor/rcheevos/src/rhash/md5.h +91 -0
  239. data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
  240. data/vendor/rcheevos/test/libretro.h +205 -0
  241. data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
  242. data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
  243. data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
  244. data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
  245. data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
  246. data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
  247. data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
  248. data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
  249. data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
  250. data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
  251. data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
  252. data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
  253. data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
  254. data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
  255. data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
  256. data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
  257. data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
  258. data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
  259. data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
  260. data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
  261. data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
  262. data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
  263. data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
  264. data/vendor/rcheevos/test/rhash/data.c +657 -0
  265. data/vendor/rcheevos/test/rhash/data.h +32 -0
  266. data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
  267. data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
  268. data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
  269. data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
  270. data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
  271. data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
  272. data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
  273. data/vendor/rcheevos/test/test.c +113 -0
  274. data/vendor/rcheevos/test/test_framework.h +205 -0
  275. data/vendor/rcheevos/test/test_rc_client.c +10509 -0
  276. data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
  277. data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
  278. data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
  279. data/vendor/rcheevos/test/test_types.natvis +9 -0
  280. data/vendor/rcheevos/validator/validator.c +658 -0
  281. data/vendor/rcheevos/validator/validator.vcxproj +152 -0
  282. data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
  283. metadata +274 -11
  284. data/lib/gemba/input_mappings.rb +0 -214
  285. data/lib/gemba/player.rb +0 -1515
@@ -0,0 +1,1215 @@
1
+ #include "rc_consoles.h"
2
+
3
+ #include <ctype.h>
4
+
5
+ const char* rc_console_name(uint32_t console_id)
6
+ {
7
+ switch (console_id)
8
+ {
9
+ case RC_CONSOLE_3DO:
10
+ return "3DO";
11
+
12
+ case RC_CONSOLE_AMIGA:
13
+ return "Amiga";
14
+
15
+ case RC_CONSOLE_AMSTRAD_PC:
16
+ return "Amstrad CPC";
17
+
18
+ case RC_CONSOLE_APPLE_II:
19
+ return "Apple II";
20
+
21
+ case RC_CONSOLE_ARCADE:
22
+ return "Arcade";
23
+
24
+ case RC_CONSOLE_ARCADIA_2001:
25
+ return "Arcadia 2001";
26
+
27
+ case RC_CONSOLE_ARDUBOY:
28
+ return "Arduboy";
29
+
30
+ case RC_CONSOLE_ATARI_2600:
31
+ return "Atari 2600";
32
+
33
+ case RC_CONSOLE_ATARI_5200:
34
+ return "Atari 5200";
35
+
36
+ case RC_CONSOLE_ATARI_7800:
37
+ return "Atari 7800";
38
+
39
+ case RC_CONSOLE_ATARI_JAGUAR:
40
+ return "Atari Jaguar";
41
+
42
+ case RC_CONSOLE_ATARI_JAGUAR_CD:
43
+ return "Atari Jaguar CD";
44
+
45
+ case RC_CONSOLE_ATARI_LYNX:
46
+ return "Atari Lynx";
47
+
48
+ case RC_CONSOLE_ATARI_ST:
49
+ return "Atari ST";
50
+
51
+ case RC_CONSOLE_CASSETTEVISION:
52
+ return "CassetteVision";
53
+
54
+ case RC_CONSOLE_CDI:
55
+ return "CD-I";
56
+
57
+ case RC_CONSOLE_COLECOVISION:
58
+ return "ColecoVision";
59
+
60
+ case RC_CONSOLE_COMMODORE_64:
61
+ return "Commodore 64";
62
+
63
+ case RC_CONSOLE_DREAMCAST:
64
+ return "Dreamcast";
65
+
66
+ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER:
67
+ return "Elektor TV Games Computer";
68
+
69
+ case RC_CONSOLE_EVENTS:
70
+ return "Events";
71
+
72
+ case RC_CONSOLE_FAIRCHILD_CHANNEL_F:
73
+ return "Fairchild Channel F";
74
+
75
+ case RC_CONSOLE_FAMICOM_DISK_SYSTEM:
76
+ return "Famicom Disk System";
77
+
78
+ case RC_CONSOLE_FM_TOWNS:
79
+ return "FM Towns";
80
+
81
+ case RC_CONSOLE_GAME_AND_WATCH:
82
+ return "Game & Watch";
83
+
84
+ case RC_CONSOLE_GAMEBOY:
85
+ return "GameBoy";
86
+
87
+ case RC_CONSOLE_GAMEBOY_ADVANCE:
88
+ return "GameBoy Advance";
89
+
90
+ case RC_CONSOLE_GAMEBOY_COLOR:
91
+ return "GameBoy Color";
92
+
93
+ case RC_CONSOLE_GAMECUBE:
94
+ return "GameCube";
95
+
96
+ case RC_CONSOLE_GAME_GEAR:
97
+ return "Game Gear";
98
+
99
+ case RC_CONSOLE_HUBS:
100
+ return "Hubs";
101
+
102
+ case RC_CONSOLE_INTELLIVISION:
103
+ return "Intellivision";
104
+
105
+ case RC_CONSOLE_INTERTON_VC_4000:
106
+ return "Interton VC 4000";
107
+
108
+ case RC_CONSOLE_MAGNAVOX_ODYSSEY2:
109
+ return "Magnavox Odyssey 2";
110
+
111
+ case RC_CONSOLE_MASTER_SYSTEM:
112
+ return "Master System";
113
+
114
+ case RC_CONSOLE_MEGA_DRIVE:
115
+ return "Sega Genesis";
116
+
117
+ case RC_CONSOLE_MEGADUCK:
118
+ return "Mega Duck";
119
+
120
+ case RC_CONSOLE_MS_DOS:
121
+ return "MS-DOS";
122
+
123
+ case RC_CONSOLE_MSX:
124
+ return "MSX";
125
+
126
+ case RC_CONSOLE_NEO_GEO_CD:
127
+ return "Neo Geo CD";
128
+
129
+ case RC_CONSOLE_NEOGEO_POCKET:
130
+ return "Neo Geo Pocket";
131
+
132
+ case RC_CONSOLE_NINTENDO:
133
+ return "Nintendo Entertainment System";
134
+
135
+ case RC_CONSOLE_NINTENDO_64:
136
+ return "Nintendo 64";
137
+
138
+ case RC_CONSOLE_NINTENDO_DS:
139
+ return "Nintendo DS";
140
+
141
+ case RC_CONSOLE_NINTENDO_DSI:
142
+ return "Nintendo DSi";
143
+
144
+ case RC_CONSOLE_NINTENDO_3DS:
145
+ return "Nintendo 3DS";
146
+
147
+ case RC_CONSOLE_NOKIA_NGAGE:
148
+ return "Nokia N-Gage";
149
+
150
+ case RC_CONSOLE_ORIC:
151
+ return "Oric";
152
+
153
+ case RC_CONSOLE_PC6000:
154
+ return "PC-6000";
155
+
156
+ case RC_CONSOLE_PC8800:
157
+ return "PC-8000/8800";
158
+
159
+ case RC_CONSOLE_PC9800:
160
+ return "PC-9800";
161
+
162
+ case RC_CONSOLE_PCFX:
163
+ return "PC-FX";
164
+
165
+ case RC_CONSOLE_PC_ENGINE:
166
+ return "PC Engine";
167
+
168
+ case RC_CONSOLE_PC_ENGINE_CD:
169
+ return "PC Engine CD";
170
+
171
+ case RC_CONSOLE_PLAYSTATION:
172
+ return "PlayStation";
173
+
174
+ case RC_CONSOLE_PLAYSTATION_2:
175
+ return "PlayStation 2";
176
+
177
+ case RC_CONSOLE_PSP:
178
+ return "PlayStation Portable";
179
+
180
+ case RC_CONSOLE_POKEMON_MINI:
181
+ return "Pokemon Mini";
182
+
183
+ case RC_CONSOLE_SEGA_32X:
184
+ return "Sega 32X";
185
+
186
+ case RC_CONSOLE_SEGA_CD:
187
+ return "Sega CD";
188
+
189
+ case RC_CONSOLE_PICO:
190
+ return "Sega Pico";
191
+
192
+ case RC_CONSOLE_SATURN:
193
+ return "Sega Saturn";
194
+
195
+ case RC_CONSOLE_SG1000:
196
+ return "SG-1000";
197
+
198
+ case RC_CONSOLE_SHARPX1:
199
+ return "Sharp X1";
200
+
201
+ case RC_CONSOLE_STANDALONE:
202
+ return "Standalone";
203
+
204
+ case RC_CONSOLE_SUPER_NINTENDO:
205
+ return "Super Nintendo Entertainment System";
206
+
207
+ case RC_CONSOLE_SUPER_CASSETTEVISION:
208
+ return "Super CassetteVision";
209
+
210
+ case RC_CONSOLE_SUPERVISION:
211
+ return "Watara Supervision";
212
+
213
+ case RC_CONSOLE_THOMSONTO8:
214
+ return "Thomson TO8";
215
+
216
+ case RC_CONSOLE_TI83:
217
+ return "TI-83";
218
+
219
+ case RC_CONSOLE_TIC80:
220
+ return "TIC-80";
221
+
222
+ case RC_CONSOLE_UZEBOX:
223
+ return "Uzebox";
224
+
225
+ case RC_CONSOLE_VECTREX:
226
+ return "Vectrex";
227
+
228
+ case RC_CONSOLE_VIC20:
229
+ return "VIC-20";
230
+
231
+ case RC_CONSOLE_VIRTUAL_BOY:
232
+ return "Virtual Boy";
233
+
234
+ case RC_CONSOLE_WASM4:
235
+ return "WASM-4";
236
+
237
+ case RC_CONSOLE_WII:
238
+ return "Wii";
239
+
240
+ case RC_CONSOLE_WII_U:
241
+ return "Wii-U";
242
+
243
+ case RC_CONSOLE_WONDERSWAN:
244
+ return "WonderSwan";
245
+
246
+ case RC_CONSOLE_X68K:
247
+ return "X68K";
248
+
249
+ case RC_CONSOLE_XBOX:
250
+ return "XBOX";
251
+
252
+ case RC_CONSOLE_ZEEBO:
253
+ return "Zeebo";
254
+
255
+ case RC_CONSOLE_ZX81:
256
+ return "ZX-81";
257
+
258
+ case RC_CONSOLE_ZX_SPECTRUM:
259
+ return "ZX Spectrum";
260
+
261
+ default:
262
+ return "Unknown";
263
+ }
264
+ }
265
+
266
+ /* ===== 3DO ===== */
267
+ /* http://www.arcaderestoration.com/memorymap/48/3DO+Bios.aspx */
268
+ /* NOTE: the Opera core attempts to expose the NVRAM as RETRO_SAVE_RAM, but the 3DO documentation
269
+ * says that applications should only access NVRAM through API calls as it's shared across mulitple
270
+ * games. This suggests that even if the core does expose it, it may change depending on which other
271
+ * games the user has played - so ignore it.
272
+ */
273
+ static const rc_memory_region_t _rc_memory_regions_3do[] = {
274
+ { 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
275
+ };
276
+ static const rc_memory_regions_t rc_memory_regions_3do = { _rc_memory_regions_3do, 1 };
277
+
278
+ /* ===== Amiga ===== */
279
+ /* http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node00D3.html */
280
+ static const rc_memory_region_t _rc_memory_regions_amiga[] = {
281
+ { 0x000000U, 0x07FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" }, /* 512KB main RAM */
282
+ { 0x080000U, 0x0FFFFFU, 0x080000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }, /* 512KB extended RAM */
283
+ };
284
+ static const rc_memory_regions_t rc_memory_regions_amiga = { _rc_memory_regions_amiga, 2 };
285
+
286
+ /* ===== Amstrad CPC ===== */
287
+ /* http://www.cpcalive.com/docs/amstrad_cpc_6128_memory_map.html */
288
+ /* https://www.cpcwiki.eu/index.php/File:AWMG_page151.jpg */
289
+ /* The original CPC only had 64KB of memory, but the newer model has 128KB (expandable to 576KB) */
290
+ /* https://www.grimware.org/doku.php/documentations/devices/gatearraydo=export_xhtml#mmr */
291
+ static const rc_memory_region_t _rc_memory_regions_amstrad_pc[] = {
292
+ { 0x000000U, 0x00003FU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Firmware" },
293
+ { 0x000040U, 0x00B0FFU, 0x000040U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
294
+ { 0x00B100U, 0x00BFFFU, 0x00B100U, RC_MEMORY_TYPE_SYSTEM_RAM, "Stack and Firmware Data" },
295
+ { 0x00C000U, 0x00FFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen Memory" },
296
+ { 0x010000U, 0x08FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" },
297
+ };
298
+ static const rc_memory_regions_t rc_memory_regions_amstrad_pc = { _rc_memory_regions_amstrad_pc, 5 };
299
+
300
+ /* ===== Apple II ===== */
301
+ static const rc_memory_region_t _rc_memory_regions_appleii[] = {
302
+ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
303
+ { 0x010000U, 0x01FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Auxillary RAM" }
304
+ };
305
+ static const rc_memory_regions_t rc_memory_regions_appleii = { _rc_memory_regions_appleii, 2 };
306
+
307
+ /* ===== Arcadia 2001 ===== */
308
+ /* https://amigan.yatho.com/a-coding.txt */
309
+ /* RAM banks 1 and 2 only exist on some variant models - no game actually uses them */
310
+ static const rc_memory_region_t _rc_memory_regions_arcadia_2001[] = {
311
+ { 0x000000U, 0x0000FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 3 */
312
+ { 0x000100U, 0x0001FFU, 0x001900U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" },
313
+ { 0x000200U, 0x0002FFU, 0x001A00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 4 */
314
+ };
315
+ static const rc_memory_regions_t rc_memory_regions_arcadia_2001 = { _rc_memory_regions_arcadia_2001, 3 };
316
+
317
+ /* ===== Arduboy ===== */
318
+ /* https://scienceprog.com/avr-microcontroller-memory-map/ (Atmega32) */
319
+ static const rc_memory_region_t _rc_memory_regions_arduboy[] = {
320
+ { 0x000000U, 0x0000FFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Registers" },
321
+ /* https://www.dailydot.com/debug/arduboy-kickstarter/ 2.5KB of RAM */
322
+ /* https://github.com/buserror/simavr/blob/1d227277b3d0039f9faef9ea62880ca3051b14f8/simavr/cores/avr/iom32u4.h#L1444-L1445 */
323
+ { 0x000100U, 0x000AFFU, 0x00000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
324
+ /* 1KB of EEPROM https://github.com/libretro/arduous/blob/93e1a6289b42ef48de1fcfb96443981725955ad0/src/arduous/arduous.cpp#L453-L455
325
+ * https://github.com/buserror/simavr/blob/1d227277b3d0039f9faef9ea62880ca3051b14f8/simavr/cores/avr/iom32u4.h#L1450 */
326
+ /* EEPROM has it's own addressing scheme starting at $0000. I've chosen to virtualize the address
327
+ * at $80000000 to avoid a conflict */
328
+ { 0x000B00U, 0x000EFFU, 0x80000000U, RC_MEMORY_TYPE_SAVE_RAM, "EEPROM" }
329
+ };
330
+ static const rc_memory_regions_t rc_memory_regions_arduboy = { _rc_memory_regions_arduboy, 3 };
331
+
332
+ /* ===== Atari 2600 ===== */
333
+ static const rc_memory_region_t _rc_memory_regions_atari2600[] = {
334
+ { 0x000000U, 0x00007FU, 0x000080U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
335
+ };
336
+ static const rc_memory_regions_t rc_memory_regions_atari2600 = { _rc_memory_regions_atari2600, 1 };
337
+
338
+ /* ===== Atari 7800 ===== */
339
+ /* http://www.atarihq.com/danb/files/78map.txt */
340
+ /* http://pdf.textfiles.com/technical/7800_devkit.pdf */
341
+ static const rc_memory_region_t _rc_memory_regions_atari7800[] = {
342
+ { 0x000000U, 0x0017FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware Interface" },
343
+ { 0x001800U, 0x0027FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
344
+ { 0x002800U, 0x002FFFU, 0x002800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
345
+ { 0x003000U, 0x0037FFU, 0x003000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
346
+ { 0x003800U, 0x003FFFU, 0x003800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
347
+ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" },
348
+ { 0x008000U, 0x00FFFFU, 0x008000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM" }
349
+ };
350
+ static const rc_memory_regions_t rc_memory_regions_atari7800 = { _rc_memory_regions_atari7800, 7 };
351
+
352
+ /* ===== Atari Jaguar ===== */
353
+ /* https://www.mulle-kybernetik.com/jagdox/memorymap.html */
354
+ static const rc_memory_region_t _rc_memory_regions_atari_jaguar[] = {
355
+ { 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
356
+ };
357
+ static const rc_memory_regions_t rc_memory_regions_atari_jaguar = { _rc_memory_regions_atari_jaguar, 1 };
358
+
359
+ /* ===== Atari Lynx ===== */
360
+ /* http://www.retroisle.com/atari/lynx/Technical/Programming/lynxprgdumm.php */
361
+ static const rc_memory_region_t _rc_memory_regions_atari_lynx[] = {
362
+ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Zero Page" },
363
+ { 0x000100U, 0x0001FFU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "Stack" },
364
+ { 0x000200U, 0x00FBFFU, 0x000200U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
365
+ { 0x00FC00U, 0x00FCFFU, 0x00FC00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "SUZY hardware access" },
366
+ { 0x00FD00U, 0x00FDFFU, 0x00FD00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "MIKEY hardware access" },
367
+ { 0x00FE00U, 0x00FFF7U, 0x00FE00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Boot ROM" },
368
+ { 0x00FFF8U, 0x00FFFFU, 0x00FFF8U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware vectors" }
369
+ };
370
+ static const rc_memory_regions_t rc_memory_regions_atari_lynx = { _rc_memory_regions_atari_lynx, 7 };
371
+
372
+ /* ===== ColecoVision ===== */
373
+ static const rc_memory_region_t _rc_memory_regions_colecovision[] = {
374
+ /* "System RAM" refers to the main RAM at 0x6000-0x63FF. However, this RAM might not always be visible.
375
+ * If the Super Game Module (SGM) is active, then it might overlay its own RAM at 0x0000-0x1FFF and 0x2000-0x7FFF.
376
+ * These positions overlap the BIOS and System RAM, therefore we use virtual addresses for these memory spaces. */
377
+ { 0x000000U, 0x0003FFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
378
+ { 0x000400U, 0x0023FFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "SGM Low RAM" }, /* Normally situated at 0x0000-0x1FFF, which overlaps the BIOS */
379
+ { 0x002400U, 0x0083FFU, 0x012000U, RC_MEMORY_TYPE_SYSTEM_RAM, "SGM High RAM" } /* Normally situated at 0x2000-0x7FFF, which overlaps System RAM */
380
+ };
381
+ static const rc_memory_regions_t rc_memory_regions_colecovision = { _rc_memory_regions_colecovision, 3 };
382
+
383
+ /* ===== Commodore 64 ===== */
384
+ /* https://www.c64-wiki.com/wiki/Memory_Map */
385
+ /* https://sta.c64.org/cbm64mem.html */
386
+ /* NOTE: Several blocks of C64 memory can be bank-switched for ROM data (see https://www.c64-wiki.com/wiki/Bank_Switching).
387
+ * Achievement triggers rely on values changing, so we don't really need to look at the ROM data.
388
+ * The achievement logic assumes the RAM data is always present in the bankable blocks. As such,
389
+ * clients providing memory to achievements should always return the RAM values at the queried address. */
390
+ static const rc_memory_region_t _rc_memory_regions_c64[] = {
391
+ { 0x000000U, 0x0003FFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
392
+ { 0x000400U, 0x0007FFU, 0x000400U, RC_MEMORY_TYPE_VIDEO_RAM, "Screen RAM" },
393
+ { 0x000800U, 0x009FFFU, 0x000800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* BASIC area. $8000-$9FFF can bank to cartridge ROM */
394
+ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to BASIC ROM or cartridge ROM */
395
+ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
396
+ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to I/O Area or character ROM */
397
+ { 0x00E000U, 0x00FFFFU, 0x00E000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to kernel ROM */
398
+ };
399
+ static const rc_memory_regions_t rc_memory_regions_c64 = { _rc_memory_regions_c64, 7 };
400
+
401
+ /* ===== Dreamcast ===== */
402
+ /* http://archiv.sega-dc.de/munkeechuff/hardware/Memory.html */
403
+ static const rc_memory_region_t _rc_memory_regions_dreamcast[] = {
404
+ { 0x00000000U, 0x00FFFFFFU, 0x0C000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
405
+ };
406
+ static const rc_memory_regions_t rc_memory_regions_dreamcast = { _rc_memory_regions_dreamcast, 1 };
407
+
408
+ /* ===== Elektor TV Games Computer ===== */
409
+ /* https://amigan.yatho.com/e-coding.txt */
410
+ static const rc_memory_region_t _rc_memory_regions_elektor_tv_games[] = {
411
+ { 0x000000U, 0x0013FFU, 0x000800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
412
+ { 0x001400U, 0x0014FFU, 0x001C00U, RC_MEMORY_TYPE_UNUSED, "Unused" }, /* mirror of $1D00-$1DFF */
413
+ { 0x001500U, 0x0016FFU, 0x001D00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" }, /* two 256-byte I/O areas */
414
+ { 0x001700U, 0x0017FFU, 0x001F00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
415
+ };
416
+ static const rc_memory_regions_t rc_memory_regions_elektor_tv_games = { _rc_memory_regions_elektor_tv_games, 4 };
417
+
418
+ /* ===== Fairchild Channel F ===== */
419
+ static const rc_memory_region_t _rc_memory_regions_fairchild_channel_f[] = {
420
+ /* "System RAM" is actually just a bunch of registers internal to CPU so all carts have it.
421
+ * "Video RAM" is part of the console so it's always available but it is write-only by the ROMs.
422
+ * "Cartridge RAM" is the cart BUS. Most carts only have ROMs on this bus. Exception are
423
+ * German Schach and homebrew carts that have 2K of RAM there in addition to ROM.
424
+ * "F2102 RAM" is used by Maze for 1K of RAM.
425
+ * https://discord.com/channels/310192285306454017/645777658319208448/967001438087708714 */
426
+ { 0x00000000U, 0x0000003FU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
427
+ { 0x00000040U, 0x0000083FU, 0x00300000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" },
428
+ { 0x00000840U, 0x0001083FU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
429
+ { 0x00010840U, 0x00010C3FU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "F2102 RAM" }
430
+ };
431
+ static const rc_memory_regions_t rc_memory_regions_fairchild_channel_f = { _rc_memory_regions_fairchild_channel_f, 4 };
432
+
433
+ /* ===== Famicon Disk System ===== */
434
+ /* https://fms.komkon.org/EMUL8/NES.html */
435
+ static const rc_memory_region_t _rc_memory_regions_famicom_disk_system[] = {
436
+ { 0x0000U, 0x07FFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
437
+ { 0x0800U, 0x0FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
438
+ { 0x1000U, 0x17FFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
439
+ { 0x1800U, 0x1FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
440
+ { 0x2000U, 0x2007U, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "PPU Register" },
441
+ { 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */
442
+ { 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" },
443
+ { 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" },
444
+ { 0x4020U, 0x40FFU, 0x4020U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "FDS I/O registers"},
445
+ { 0x4100U, 0x5FFFU, 0x4100U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */
446
+ { 0x6000U, 0xDFFFU, 0x6000U, RC_MEMORY_TYPE_SYSTEM_RAM, "FDS RAM"},
447
+ { 0xE000U, 0xFFFFU, 0xE000U, RC_MEMORY_TYPE_READONLY, "FDS BIOS ROM"},
448
+ };
449
+ static const rc_memory_regions_t rc_memory_regions_famicom_disk_system = { _rc_memory_regions_famicom_disk_system, 12 };
450
+
451
+ /* ===== GameBoy / MegaDuck ===== */
452
+ static const rc_memory_region_t _rc_memory_regions_gameboy[] = {
453
+ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" },
454
+ { 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" },
455
+ { 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */
456
+ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */
457
+ { 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" },
458
+ { 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" },
459
+ { 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" },
460
+ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"},
461
+ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" },
462
+ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" },
463
+ { 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" },
464
+ { 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"},
465
+ { 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_UNUSED, ""},
466
+ { 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"},
467
+ { 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"},
468
+ { 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"},
469
+
470
+ /* GameBoy's cartridge RAM may have a total of up to 16 banks that can be paged through $A000-$BFFF.
471
+ * It is desirable to always have access to these extra banks. We do this by expecting the extra banks
472
+ * to be addressable at addresses not supported by the native system. 0x10000-0x16000 is reserved
473
+ * for the extra banks of system memory that are exclusive to the GameBoy Color. */
474
+ { 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_UNUSED, "Unused (GameBoy Color exclusive)" },
475
+ { 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" },
476
+ };
477
+ static const rc_memory_regions_t rc_memory_regions_megaduck = { _rc_memory_regions_gameboy, 16 };
478
+ static const rc_memory_regions_t rc_memory_regions_gameboy = { _rc_memory_regions_gameboy, 18 };
479
+
480
+ /* ===== GameBoy Color ===== */
481
+ static const rc_memory_region_t _rc_memory_regions_gameboy_color[] = {
482
+ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" },
483
+ { 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" },
484
+ { 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */
485
+ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */
486
+ { 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" },
487
+ { 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" },
488
+ { 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" },
489
+ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"},
490
+ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 0)" },
491
+ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 1)" },
492
+ { 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" },
493
+ { 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"},
494
+ { 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_UNUSED, ""},
495
+ { 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"},
496
+ { 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"},
497
+ { 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"},
498
+
499
+ /* GameBoy Color provides 6 extra banks of system memory that can be paged out through the $D000-$DFFF,
500
+ * and the cartridge RAM may have a total of up to 16 banks page through $A000-$BFFF.
501
+ * It is desirable to always have access to these extra banks. We do this by expecting the extra banks
502
+ * to be addressable at addresses not supported by the native system. */
503
+ { 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (banks 2-7)" },
504
+ { 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" },
505
+ };
506
+ static const rc_memory_regions_t rc_memory_regions_gameboy_color = { _rc_memory_regions_gameboy_color, 18 };
507
+
508
+ /* ===== GameBoy Advance ===== */
509
+ /* http://problemkaputt.de/gbatek-gba-memory-map.htm */
510
+ static const rc_memory_region_t _rc_memory_regions_gameboy_advance[] = {
511
+ { 0x000000U, 0x007FFFU, 0x03000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* 32KB Internal Work RAM */
512
+ { 0x008000U, 0x047FFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* 256KB External Work RAM */
513
+ { 0x048000U, 0x057FFFU, 0x0E000000U, RC_MEMORY_TYPE_SAVE_RAM, "Save RAM" } /* 64KB Game Pak SRAM */
514
+ };
515
+ static const rc_memory_regions_t rc_memory_regions_gameboy_advance = { _rc_memory_regions_gameboy_advance, 3 };
516
+
517
+ /* ===== GameCube ===== */
518
+ /* https://wiibrew.org/wiki/Memory_map */
519
+ static const rc_memory_region_t _rc_memory_regions_gamecube[] = {
520
+ { 0x00000000U, 0x017FFFFF, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
521
+ };
522
+ static const rc_memory_regions_t rc_memory_regions_gamecube = { _rc_memory_regions_gamecube, 1 };
523
+
524
+ /* ===== Game Gear ===== */
525
+ /* https://www.smspower.org/Development/MemoryMap */
526
+ /* https://www.smspower.org/Development/Mappers */
527
+ static const rc_memory_region_t _rc_memory_regions_game_gear[] = {
528
+ { 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
529
+ /* GG/SMS have various possible mappings for cartridge memory depending on the mapper used.
530
+ * However, these ultimately do not map all of their memory at once, typically requiring banking.
531
+ * Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block.
532
+ * Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM.
533
+ * libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however.
534
+ */
535
+ { 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
536
+ };
537
+ static const rc_memory_regions_t rc_memory_regions_game_gear = { _rc_memory_regions_game_gear, 2 };
538
+
539
+ /* ===== Intellivision ===== */
540
+ /* http://wiki.intellivision.us/index.php/Memory_Map */
541
+ /* NOTE: Intellivision memory addresses point at 16-bit values. FreeIntv exposes them as little-endian
542
+ * 32-bit values. As such, the addresses are off by a factor of 4 _and_ the data is only where we
543
+ * expect it on little-endian systems.
544
+ */
545
+ static const rc_memory_region_t _rc_memory_regions_intellivision[] = {
546
+ /* For backwards compatibility, register a 128-byte chunk of video RAM so the system memory
547
+ * will start at $0080. $0000-$007F previously tried to map to the STIC video registers as
548
+ * RETRO_MEMORY_VIDEO_RAM, and FreeIntv didn't expose any RETRO_MEMORY_VIDEO_RAM, so the first
549
+ * byte of RETRO_MEMORY_SYSTEM_RAM was registered at $0080. The data at $0080 is actually the
550
+ * STIC registers (4 bytes each), so we need to provide an arbitrary 128-byte padding that
551
+ * claims to be video RAM to ensure the system RAM ends up at the right address.
552
+ */
553
+ { 0x000000U, 0x00007FU, 0xFFFFFFU, RC_MEMORY_TYPE_VIDEO_RAM, "" },
554
+
555
+ /* RetroAchievements address = real address x4 + 0x80.
556
+ * These all have to map to RETRO_MEMORY_SYSTEM_RAM (even the video-related fields) as the
557
+ * entire block is exposed as a single entity by FreeIntv */
558
+
559
+ /* $0000-$007F: STIC registers, $0040-$007F are readonly */
560
+ { 0x000080U, 0x00027FU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "STIC Registers" },
561
+ /* $0080-$00FF: unused */
562
+ { 0x000280U, 0x00047FU, 0x000080U, RC_MEMORY_TYPE_UNUSED, "" },
563
+ /* $0100-$035F: system RAM, $0100-$01EF is scratch memory and only 8-bits per address */
564
+ { 0x000480U, 0x000DFFU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
565
+ /* $0360-$03FF: unused */
566
+ { 0x000E00U, 0x00107FU, 0x000360U, RC_MEMORY_TYPE_UNUSED, "" },
567
+ /* $0400-$0FFF: cartridge RAM */
568
+ { 0x001080U, 0x00407FU, 0x000400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
569
+ /* $1000-$1FFF: unused */
570
+ { 0x004080U, 0x00807FU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" },
571
+ /* $2000-$2FFF: cartridge RAM */
572
+ { 0x008080U, 0x00C07FU, 0x002000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
573
+ /* $3000-$3FFF: video RAM */
574
+ { 0x00C080U, 0x01007FU, 0x003000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Video RAM" },
575
+ /* $4000-$FFFF: cartridge RAM */
576
+ { 0x010080U, 0x04007FU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
577
+ };
578
+ static const rc_memory_regions_t rc_memory_regions_intellivision = { _rc_memory_regions_intellivision, 10 };
579
+
580
+ /* ===== Interton VC 4000 ===== */
581
+ /* https://amigan.yatho.com/i-coding.txt */
582
+ /* Cartridge RAM is not persisted, it's just expanded storage */
583
+ static const rc_memory_region_t _rc_memory_regions_interton_vc_4000[] = {
584
+ { 0x000000U, 0x0003FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
585
+ { 0x000400U, 0x0004FFU, 0x001E00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" },
586
+ { 0x000500U, 0x0005FFU, 0x001F00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
587
+ };
588
+ static const rc_memory_regions_t rc_memory_regions_interton_vc_4000 = { _rc_memory_regions_interton_vc_4000, 3 };
589
+
590
+ /* ===== Magnavox Odyssey 2 ===== */
591
+ /* https://sudonull.com/post/76885-Architecture-and-programming-Philips-Videopac-Magnavox-Odyssey-2 */
592
+ static const rc_memory_region_t _rc_memory_regions_magnavox_odyssey_2[] = {
593
+ /* Internal and external RAMs are reachable using unique instructions.
594
+ * The real addresses provided are virtual and for mapping purposes only. */
595
+ { 0x000000U, 0x00003FU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Internal RAM" },
596
+ { 0x000040U, 0x00013FU, 0x000040U, RC_MEMORY_TYPE_SYSTEM_RAM, "External RAM" }
597
+ };
598
+ static const rc_memory_regions_t rc_memory_regions_magnavox_odyssey_2 = { _rc_memory_regions_magnavox_odyssey_2, 2 };
599
+
600
+ /* ===== Master System ===== */
601
+ /* https://www.smspower.org/Development/MemoryMap */
602
+ /* https://www.smspower.org/Development/Mappers */
603
+ static const rc_memory_region_t _rc_memory_regions_master_system[] = {
604
+ { 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
605
+ /* GG/SMS have various possible mappings for cartridge memory depending on the mapper used.
606
+ * However, these ultimately do not map all of their memory at once, typically requiring banking.
607
+ * Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block.
608
+ * Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM.
609
+ * libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however.
610
+ */
611
+ { 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
612
+ };
613
+ static const rc_memory_regions_t rc_memory_regions_master_system = { _rc_memory_regions_master_system, 2 };
614
+
615
+ /* ===== MegaDrive (Genesis) ===== */
616
+ /* https://www.smspower.org/Development/MemoryMap */
617
+ static const rc_memory_region_t _rc_memory_regions_megadrive[] = {
618
+ { 0x000000U, 0x00FFFFU, 0xFF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
619
+ { 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
620
+ };
621
+ static const rc_memory_regions_t rc_memory_regions_megadrive = { _rc_memory_regions_megadrive, 2 };
622
+
623
+ /* ===== MegaDrive 32X (Genesis 32X) ===== */
624
+ /* http://devster.monkeeh.com/sega/32xguide1.txt */
625
+ static const rc_memory_region_t _rc_memory_regions_megadrive_32x[] = {
626
+ { 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* Main MegaDrive RAM */
627
+ { 0x010000U, 0x04FFFFU, 0x06000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "32X RAM"}, /* Additional 32X RAM */
628
+ { 0x050000U, 0x05FFFFU, 0x00000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
629
+ };
630
+ static const rc_memory_regions_t rc_memory_regions_megadrive_32x = { _rc_memory_regions_megadrive_32x, 3 };
631
+
632
+ /* ===== MSX ===== */
633
+ /* https://www.msx.org/wiki/The_Memory */
634
+ /* MSX only has 64KB of addressable RAM, of which 32KB is reserved for the system/BIOS.
635
+ * However, the system has up to 512KB of RAM, which is paged into the addressable RAM
636
+ * We expect the raw RAM to be exposed, rather than force the devs to worry about the
637
+ * paging system. The entire RAM is expected to appear starting at $10000, which is not
638
+ * addressable by the system itself.
639
+ */
640
+ static const rc_memory_region_t _rc_memory_regions_msx[] = {
641
+ { 0x000000U, 0x07FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
642
+ };
643
+ static const rc_memory_regions_t rc_memory_regions_msx = { _rc_memory_regions_msx, 1 };
644
+
645
+ /* ===== MS DOS ===== */
646
+ static const rc_memory_region_t _rc_memory_regions_ms_dos[] = {
647
+ /* DOS emulators split the 640 KB conventional memory into two regions.
648
+ * First the part of the conventional memory given to the running game at $000000.
649
+ * The part of the conventional memory containing DOS and BIOS controlled memory
650
+ * is at $100000. The length of these can vary depending on the hardware
651
+ * and DOS version (or emulated DOS shell).
652
+ * These first two regions will only ever total to 640 KB but the regions map
653
+ * to 1 MB bounds to make resulting memory addresses more readable.
654
+ * When emulating a game not under DOS (so called 'PC Booter' games), the entirety
655
+ * of the 640 KB conventional memory block will be at $000000.
656
+ */
657
+ { 0x00000000U, 0x0009FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Game Conventional Memory" },
658
+ { 0x000A0000U, 0x000FFFFFU, 0x000A0000U, RC_MEMORY_TYPE_UNUSED, "Padding to align OS Conventional Memory" },
659
+ { 0x00100000U, 0x0019FFFFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "OS Conventional Memory" },
660
+ { 0x001A0000U, 0x001FFFFFU, 0x001A0000U, RC_MEMORY_TYPE_UNUSED, "Padding to align Expanded Memory" },
661
+ /* Last is all the expanded memory which for now we map up to 64 MB which should be
662
+ * enough for the games we want to cover. An emulator might emulate more than that.
663
+ */
664
+ { 0x00200000U, 0x041FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Expanded Memory" }
665
+ };
666
+ static const rc_memory_regions_t rc_memory_regions_ms_dos = { _rc_memory_regions_ms_dos, 5 };
667
+
668
+ /* ===== Neo Geo Pocket ===== */
669
+ /* http://neopocott.emuunlim.com/docs/tech-11.txt */
670
+ static const rc_memory_region_t _rc_memory_regions_neo_geo_pocket[] = {
671
+ /* The docs suggest there's Work RAM exposed from $0000-$6FFF, Sound RAM from $7000-$7FFF, and Video
672
+ * RAM from $8000-$BFFF, but both MednafenNGP and FBNeo only expose system RAM from $4000-$7FFF */
673
+ { 0x000000U, 0x003FFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
674
+ };
675
+ static const rc_memory_regions_t rc_memory_regions_neo_geo_pocket = { _rc_memory_regions_neo_geo_pocket, 1 };
676
+
677
+ /* ===== Neo Geo CD ===== */
678
+ /* https://wiki.neogeodev.org/index.php?title=68k_memory_map */
679
+ /* NeoCD exposes $000000-$1FFFFF as System RAM, but it seems like only the WORKRAM section is used.
680
+ * This is consistent with http://www.hardmvs.fr/manuals/NeoGeoProgrammersGuide.pdf (page25), which says:
681
+ *
682
+ * Furthermore, the NEO-GEO provides addresses 100000H-10FFFFH as a work area, out of which the
683
+ * addresses 10F300H-10FFFFH are reserved exclusively for use by the system program. Therefore,
684
+ * every game is to use addresses 100000H-10F2FFH.
685
+ *
686
+ * Also note that PRG files (game ROM) can be loaded anywhere else in the $000000-$1FFFFF range.
687
+ * AoF3 illustrates this pretty clearly: https://wiki.neogeodev.org/index.php?title=IPL_file
688
+ *
689
+ * PROG_CD.PRG,0,0
690
+ * PROG_CDX.PRG,0,058000
691
+ * CNV_NM.PRG,0,0C0000
692
+ * FIX_DATA.PRG,0,0FD000
693
+ * OBJACTLK.PRG,0,130000
694
+ * SSEL_CNV.PRG,0,15A000
695
+ * SSEL_BAK.PRG,0,16F000
696
+ * HITMSG.PRG,0,170000
697
+ * SSEL_SPR.PRG,0,19D000
698
+ */
699
+ static const rc_memory_region_t _rc_memory_regions_neo_geo_cd[] = {
700
+ { 0x000000U, 0x00F2FFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
701
+ /* NOTE: some BIOS settings are exposed through the reserved RAM: https://wiki.neogeodev.org/index.php?title=68k_ASM_defines */
702
+ { 0x00F300U, 0x00FFFFU, 0x0010F300U, RC_MEMORY_TYPE_SYSTEM_RAM, "Reserved RAM" },
703
+ };
704
+ static const rc_memory_regions_t rc_memory_regions_neo_geo_cd = { _rc_memory_regions_neo_geo_cd, 2 };
705
+
706
+ /* ===== Nintendo Entertainment System ===== */
707
+ /* https://wiki.nesdev.com/w/index.php/CPU_memory_map */
708
+ static const rc_memory_region_t _rc_memory_regions_nes[] = {
709
+ { 0x0000U, 0x07FFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
710
+ { 0x0800U, 0x0FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
711
+ { 0x1000U, 0x17FFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
712
+ { 0x1800U, 0x1FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
713
+ { 0x2000U, 0x2007U, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "PPU Register" },
714
+ { 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */
715
+ { 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" },
716
+ { 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" },
717
+
718
+ /* NOTE: these are for the original NES/Famicom */
719
+ { 0x4020U, 0x5FFFU, 0x4020U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */
720
+ { 0x6000U, 0x7FFFU, 0x6000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"},
721
+ { 0x8000U, 0xFFFFU, 0x8000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM"},
722
+ };
723
+ static const rc_memory_regions_t rc_memory_regions_nes = { _rc_memory_regions_nes, 11 };
724
+
725
+ /* ===== Nintendo 64 ===== */
726
+ /* https://raw.githubusercontent.com/mikeryan/n64dev/master/docs/n64ops/n64ops%23h.txt */
727
+ /* https://n64brew.dev/wiki/Memory_map#Virtual_Memory_Map */
728
+ static const rc_memory_region_t _rc_memory_regions_n64[] = {
729
+ { 0x000000U, 0x1FFFFFU, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 1 */
730
+ { 0x200000U, 0x3FFFFFU, 0x80200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 2 */
731
+ { 0x400000U, 0x7FFFFFU, 0x80400000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } /* expansion pak */
732
+ };
733
+ static const rc_memory_regions_t rc_memory_regions_n64 = { _rc_memory_regions_n64, 3 };
734
+
735
+ /* ===== Nintendo DS ===== */
736
+ /* https://www.akkit.org/info/gbatek.htm#dsmemorymaps */
737
+ static const rc_memory_region_t _rc_memory_regions_nintendo_ds[] = {
738
+ { 0x0000000U, 0x03FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
739
+ /* To keep DS/DSi memory maps aligned, padding is set here for the DSi's extra RAM */
740
+ { 0x0400000U, 0x0FFFFFFU, 0x02400000U, RC_MEMORY_TYPE_UNUSED, "Unused (DSi exclusive)" },
741
+ /* The DS/DSi have "tightly coupled memory": very fast memory directly connected to the CPU.
742
+ * This memory has an instruction variant (ITCM) and a data variant (DTCM).
743
+ * For achievement purposes it is useful to be able to access the data variant.
744
+ * This memory does not have a fixed address on console, being able to be moved to any $0xxxx000 region.
745
+ * While normally this kind of memory is addressed outside of the possible native addressing space, this is simply not possible,
746
+ * as the DS/DSi's address space covers all possible uint32_t values.
747
+ * $0E000000 is used here as a "pseudo-end," as this is nearly the end of all the memory actually mapped to addresses
748
+ * This means that (with the exception of $FFFF0000 onwards, which has the ARM9 BIOS mapped) $0E000000 onwards has nothing mapped to it
749
+ */
750
+ { 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" }
751
+ };
752
+ static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 3 };
753
+
754
+ /* ===== Nintendo DSi ===== */
755
+ /* https://problemkaputt.de/gbatek.htm#dsiiomap */
756
+ static const rc_memory_region_t _rc_memory_regions_nintendo_dsi[] = {
757
+ { 0x0000000U, 0x0FFFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
758
+ { 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" }
759
+ };
760
+ static const rc_memory_regions_t rc_memory_regions_nintendo_dsi = { _rc_memory_regions_nintendo_dsi, 2 };
761
+
762
+ /* ===== Oric ===== */
763
+ static const rc_memory_region_t _rc_memory_regions_oric[] = {
764
+ /* actual size depends on machine type - up to 64KB */
765
+ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
766
+ };
767
+ static const rc_memory_regions_t rc_memory_regions_oric = { _rc_memory_regions_oric, 1 };
768
+
769
+ /* ===== PC-8800 ===== */
770
+ static const rc_memory_region_t _rc_memory_regions_pc8800[] = {
771
+ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
772
+ { 0x010000U, 0x010FFFU, 0x010000U, RC_MEMORY_TYPE_VIDEO_RAM, "Text VRAM" } /* technically VRAM, but often used as system RAM */
773
+ };
774
+ static const rc_memory_regions_t rc_memory_regions_pc8800 = { _rc_memory_regions_pc8800, 2 };
775
+
776
+ /* ===== PC Engine ===== */
777
+ /* http://www.archaicpixels.com/Memory_Map */
778
+ static const rc_memory_region_t _rc_memory_regions_pc_engine[] = {
779
+ { 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
780
+ };
781
+ static const rc_memory_regions_t rc_memory_regions_pc_engine = { _rc_memory_regions_pc_engine, 1 };
782
+
783
+ /* ===== PC Engine CD===== */
784
+ /* http://www.archaicpixels.com/Memory_Map */
785
+ static const rc_memory_region_t _rc_memory_regions_pc_engine_cd[] = {
786
+ { 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
787
+ { 0x002000U, 0x011FFFU, 0x100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD RAM" },
788
+ { 0x012000U, 0x041FFFU, 0x0D0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Super System Card RAM" },
789
+ { 0x042000U, 0x0427FFU, 0x1EE000U, RC_MEMORY_TYPE_SAVE_RAM, "CD Battery-backed RAM" }
790
+ };
791
+ static const rc_memory_regions_t rc_memory_regions_pc_engine_cd = { _rc_memory_regions_pc_engine_cd, 4 };
792
+
793
+ /* ===== PC-FX ===== */
794
+ /* http://daifukkat.su/pcfx/data/memmap.html */
795
+ static const rc_memory_region_t _rc_memory_regions_pcfx[] = {
796
+ { 0x000000U, 0x1FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
797
+ { 0x200000U, 0x207FFFU, 0xE0000000U, RC_MEMORY_TYPE_SAVE_RAM, "Internal Backup Memory" },
798
+ { 0x208000U, 0x20FFFFU, 0xE8000000U, RC_MEMORY_TYPE_SAVE_RAM, "External Backup Memory" },
799
+ };
800
+ static const rc_memory_regions_t rc_memory_regions_pcfx = { _rc_memory_regions_pcfx, 3 };
801
+
802
+ /* ===== PlayStation ===== */
803
+ /* http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt */
804
+ static const rc_memory_region_t _rc_memory_regions_playstation[] = {
805
+ { 0x000000U, 0x00FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
806
+ { 0x010000U, 0x1FFFFFU, 0x00010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
807
+ { 0x200000U, 0x2003FFU, 0x1F800000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Scratchpad RAM" }
808
+ };
809
+ static const rc_memory_regions_t rc_memory_regions_playstation = { _rc_memory_regions_playstation, 3 };
810
+
811
+ /* ===== PlayStation 2 ===== */
812
+ /* https://psi-rockin.github.io/ps2tek/ */
813
+ static const rc_memory_region_t _rc_memory_regions_playstation2[] = {
814
+ { 0x00000000U, 0x000FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
815
+ { 0x00100000U, 0x01FFFFFFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
816
+ { 0x02000000U, 0x02003FFFU, 0x70000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Scratchpad RAM" },
817
+ };
818
+ static const rc_memory_regions_t rc_memory_regions_playstation2 = { _rc_memory_regions_playstation2, 3 };
819
+
820
+ /* ===== PlayStation Portable ===== */
821
+ /* https://github.com/uofw/upspd/wiki/Memory-map */
822
+ static const rc_memory_region_t _rc_memory_regions_psp[] = {
823
+ { 0x00000000U, 0x007FFFFFU, 0x08000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
824
+ { 0x00800000U, 0x01FFFFFFU, 0x08800000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
825
+ };
826
+ static const rc_memory_regions_t rc_memory_regions_psp = { _rc_memory_regions_psp, 2 };
827
+
828
+ /* ===== Pokemon Mini ===== */
829
+ /* https://www.pokemon-mini.net/documentation/memory-map/ */
830
+ static const rc_memory_region_t _rc_memory_regions_pokemini[] = {
831
+ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "BIOS RAM" },
832
+ { 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
833
+ };
834
+ static const rc_memory_regions_t rc_memory_regions_pokemini = { _rc_memory_regions_pokemini, 2 };
835
+
836
+ /* ===== Sega CD ===== */
837
+ /* https://en.wikibooks.org/wiki/Genesis_Programming/68K_Memory_map/ */
838
+ static const rc_memory_region_t _rc_memory_regions_segacd[] = {
839
+ { 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "68000 RAM" },
840
+ { 0x010000U, 0x08FFFFU, 0x80020000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD PRG RAM" }, /* normally banked into $020000-$03FFFF */
841
+ { 0x090000U, 0x0AFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD WORD RAM" }
842
+ };
843
+ static const rc_memory_regions_t rc_memory_regions_segacd = { _rc_memory_regions_segacd, 3 };
844
+
845
+ /* ===== Sega Saturn ===== */
846
+ /* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */
847
+ static const rc_memory_region_t _rc_memory_regions_saturn[] = {
848
+ { 0x000000U, 0x0FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM Low" },
849
+ { 0x100000U, 0x1FFFFFU, 0x06000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM High" }
850
+ };
851
+ static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions_saturn, 2 };
852
+
853
+ /* ===== SG-1000 ===== */
854
+ /* https://www.smspower.org/Development/MemoryMap */
855
+ static const rc_memory_region_t _rc_memory_regions_sg1000[] = {
856
+ { 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
857
+ /* https://github.com/libretro/FBNeo/blob/697801c6262be6ca91615cf905444d3e039bc06f/src/burn/drv/sg1000/d_sg1000.cpp#L210-L237 */
858
+ /* Expansion mode B exposes 8KB at $C000. The first 2KB hides the System RAM, but since the address matches,
859
+ we'll leverage that definition and expand it another 6KB */
860
+ { 0x000400U, 0x001FFFU, 0xC400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" },
861
+ /* Expansion mode A exposes 8KB at $2000 */
862
+ { 0x002000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" },
863
+ /* Othello exposes 2KB at $8000, and The Castle exposes 8KB at $8000 */
864
+ { 0x004000U, 0x005FFFU, 0x8000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }
865
+ };
866
+ static const rc_memory_regions_t rc_memory_regions_sg1000 = { _rc_memory_regions_sg1000, 4 };
867
+
868
+ /* ===== Super Cassette Vision ===== */
869
+ /* https://github.com/mamedev/mame/blob/f32bb79e8541ba96d3a8144b220c48fb7536ba4b/src/mame/epoch/scv.cpp#L78-L86 */
870
+ /* SCV only has 128 bytes of system RAM, any additional memory is provided on the individual carts and is
871
+ * not backed up by battery. */
872
+ /* http://www.videogameconsolelibrary.com/pg80-super_cass_vis.htm#page=specs */
873
+ static const rc_memory_region_t _rc_memory_regions_scv[] = {
874
+ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_READONLY, "System ROM" }, /* BIOS */
875
+ { 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" },
876
+ { 0x002000U, 0x003FFFU, 0x002000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" }, /* only really goes to $33FF? */
877
+ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_UNUSED, "" },
878
+ { 0x008000U, 0x00FF7FU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
879
+ { 0x00FF80U, 0x00FFFFU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
880
+ };
881
+ static const rc_memory_regions_t rc_memory_regions_scv = { _rc_memory_regions_scv, 6 };
882
+
883
+ /* ===== Super Nintendo ===== */
884
+ /* https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map#LoROM */
885
+ static const rc_memory_region_t _rc_memory_regions_snes[] = {
886
+ { 0x000000U, 0x01FFFFU, 0x07E0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
887
+ /* Cartridge RAM here could be in a variety of places in SNES memory, depending on the ROM type.
888
+ * Due to this, we place Cartridge RAM outside of the possible native addressing space.
889
+ * Note that this also covers SA-1 BW-RAM (which is exposed as RETRO_MEMORY_SAVE_RAM for libretro).
890
+ */
891
+ { 0x020000U, 0x09FFFFU, 0x1000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" },
892
+ /* I-RAM on the SA-1 is normally at 0x003000. However, this address typically just has a mirror of System RAM for other ROM types.
893
+ * To avoid conflicts, don't use 0x003000, instead map it outside of the possible native addressing space.
894
+ */
895
+ { 0x0A0000U, 0x0A07FFU, 0x1080000U, RC_MEMORY_TYPE_SYSTEM_RAM, "I-RAM (SA-1)" }
896
+ };
897
+ static const rc_memory_regions_t rc_memory_regions_snes = { _rc_memory_regions_snes, 3 };
898
+
899
+ /* ===== Thomson TO8 ===== */
900
+ /* https://github.com/mamedev/mame/blob/master/src/mame/drivers/thomson.cpp#L1617 */
901
+ static const rc_memory_region_t _rc_memory_regions_thomson_to8[] = {
902
+ { 0x000000U, 0x07FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
903
+ };
904
+ static const rc_memory_regions_t rc_memory_regions_thomson_to8 = { _rc_memory_regions_thomson_to8, 1 };
905
+
906
+ /* ===== TI-83 ===== */
907
+ /* https://tutorials.eeems.ca/ASMin28Days/lesson/day03.html#mem */
908
+ static const rc_memory_region_t _rc_memory_regions_ti83[] = {
909
+ { 0x000000U, 0x007FFFU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
910
+ };
911
+ static const rc_memory_regions_t rc_memory_regions_ti83 = { _rc_memory_regions_ti83, 1 };
912
+
913
+ /* ===== TIC-80 ===== */
914
+ /* https://github.com/nesbox/TIC-80/wiki/RAM */
915
+ static const rc_memory_region_t _rc_memory_regions_tic80[] = {
916
+ { 0x000000U, 0x003FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Video RAM" }, /* have to classify this as system RAM because the core exposes it as part of the RETRO_MEMORY_SYSTEM_RAM */
917
+ { 0x004000U, 0x005FFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Tile RAM" },
918
+ { 0x006000U, 0x007FFFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite RAM" },
919
+ { 0x008000U, 0x00FF7FU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "MAP RAM" },
920
+ { 0x00FF80U, 0x00FF8BU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Input State" },
921
+ { 0x00FF8CU, 0x014003U, 0x00FF8CU, RC_MEMORY_TYPE_SYSTEM_RAM, "Sound RAM" },
922
+ { 0x014004U, 0x014403U, 0x014004U, RC_MEMORY_TYPE_SAVE_RAM, "Persistent Memory" }, /* this is also returned as part of RETRO_MEMORY_SYSTEM_RAM, but can be extrapolated correctly because the pointer starts at the first SYSTEM_RAM region */
923
+ { 0x014404U, 0x014603U, 0x014404U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite Flags" },
924
+ { 0x014604U, 0x014E03U, 0x014604U, RC_MEMORY_TYPE_SYSTEM_RAM, "System Font" },
925
+ { 0x014E04U, 0x017FFFU, 0x014E04U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM"}
926
+ };
927
+ static const rc_memory_regions_t rc_memory_regions_tic80 = { _rc_memory_regions_tic80, 10 };
928
+
929
+ /* ===== Uzebox ===== */
930
+ /* https://uzebox.org/index.php */
931
+ static const rc_memory_region_t _rc_memory_regions_uzebox[] = {
932
+ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
933
+ };
934
+ static const rc_memory_regions_t rc_memory_regions_uzebox = { _rc_memory_regions_uzebox, 1 };
935
+
936
+ /* ===== Vectrex ===== */
937
+ /* https://roadsidethoughts.com/vectrex/vectrex-memory-map.htm */
938
+ static const rc_memory_region_t _rc_memory_regions_vectrex[] = {
939
+ { 0x000000U, 0x0003FFU, 0x00C800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
940
+ };
941
+ static const rc_memory_regions_t rc_memory_regions_vectrex = { _rc_memory_regions_vectrex, 1 };
942
+
943
+ /* ===== Virtual Boy ===== */
944
+ static const rc_memory_region_t _rc_memory_regions_virtualboy[] = {
945
+ { 0x000000U, 0x00FFFFU, 0x05000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
946
+ { 0x010000U, 0x01FFFFU, 0x06000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
947
+ };
948
+ static const rc_memory_regions_t rc_memory_regions_virtualboy = { _rc_memory_regions_virtualboy, 2 };
949
+
950
+ /* ===== Watara Supervision ===== */
951
+ /* https://github.com/libretro/potator/blob/b5e5ba02914fcdf4a8128072dbc709da28e08832/common/memorymap.c#L231-L259 */
952
+ static const rc_memory_region_t _rc_memory_regions_watara_supervision[] = {
953
+ { 0x0000U, 0x001FFFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
954
+ { 0x2000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Registers" },
955
+ { 0x4000U, 0x005FFFU, 0x4000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" }
956
+ };
957
+ static const rc_memory_regions_t rc_memory_regions_watara_supervision = { _rc_memory_regions_watara_supervision, 3 };
958
+
959
+ /* ===== WASM-4 ===== */
960
+ /* fantasy console that runs specifically designed WebAssembly games */
961
+ /* https://github.com/aduros/wasm4/blob/main/site/docs/intro.md#hardware-specs */
962
+ static const rc_memory_region_t _rc_memory_regions_wasm4[] = {
963
+ { 0x000000U, 0x00FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
964
+ /* Persistent storage is not directly accessible from the game. It has to be loaded into System RAM first
965
+ { 0x010000U, 0x0103FFU, 0x80000000U, RC_MEMORY_TYPE_SAVE_RAM, "Disk Storage"}
966
+ */
967
+ };
968
+ static const rc_memory_regions_t rc_memory_regions_wasm4 = { _rc_memory_regions_wasm4, 1 };
969
+
970
+ /* ===== Wii ===== */
971
+ /* https://wiibrew.org/wiki/Memory_map */
972
+ static const rc_memory_region_t _rc_memory_regions_wii[] = {
973
+ { 0x00000000U, 0x017FFFFF, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
974
+ { 0x01800000U, 0x0FFFFFFF, 0x81800000U, RC_MEMORY_TYPE_UNUSED, "Unused" },
975
+ { 0x10000000U, 0x13FFFFFF, 0x90000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
976
+ };
977
+ static const rc_memory_regions_t rc_memory_regions_wii = { _rc_memory_regions_wii, 3 };
978
+
979
+ /* ===== WonderSwan ===== */
980
+ /* http://daifukkat.su/docs/wsman/#ovr_memmap */
981
+ static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
982
+ /* RAM ends at 0x3FFF for WonderSwan, WonderSwan color uses all 64KB */
983
+ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
984
+ /* Only 64KB of SRAM is accessible via the addressing scheme, but the cartridge
985
+ * may have up to 512KB of SRAM. http://daifukkat.su/docs/wsman/#cart_meta
986
+ * Since beetle_wswan exposes it as a contiguous block, assume its contiguous
987
+ * even though the documentation says $20000-$FFFFF is ROM data. If this causes
988
+ * a conflict in the future, we can revisit. A new region with a virtual address
989
+ * could be added to pick up the additional SRAM data. As long as it immediately
990
+ * follows the 64KB at $10000, all existing achievements should be unaffected.
991
+ */
992
+ { 0x010000U, 0x08FFFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
993
+ };
994
+ static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 };
995
+
996
+ /* ===== ZX Spectrum ===== */
997
+ /* https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs
998
+ * https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs
999
+ * https://worldofspectrum.org/faq/reference/128kreference.htm */
1000
+ static const rc_memory_region_t _rc_memory_regions_zx_spectrum[] = {
1001
+ /* ZX Spectrum is complicated as multiple models exist with varying amounts of memory.
1002
+ * In practice, this can be reduced to two categories: 16K/48K units, and 128K units.
1003
+ * 16K/48K units have RAM starting at $4000 onwards, 16K ending at $7FFF, 48K ending at $FFFF.
1004
+ * 128K units have banked memory, with $4000-$7FFF normally having RAM bank 5, and $8000-$BFFF normally having RAM bank 2.
1005
+ * $C000-$FFFF is normally reserved for banked RAM, having any of banks 0-7.
1006
+ * For the purposes of the RAM map, $C000-$FFFF is assumed to be bank 0, and $10000 onwards has the other banks in order (1, 3, 4, 6, 7)
1007
+ * Doing it this way always for 16K/48K games to have the same memory map on the 128K, and thus avoid issues due to the model selected.
1008
+ * Later 128K units also have a special banking mode that changes up banking completely, but for 16K/48K compatibility purposes this doesn't matter, and so is irrelevant.
1009
+ */
1010
+ { 0x00000U, 0x03FFFU, 0x04000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" }, /* RAM bank 5 on 128K units */
1011
+ { 0x04000U, 0x07FFFU, 0x08000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 2 on 128K units */
1012
+ { 0x08000U, 0x0BFFFU, 0x0C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 0-7 on 128K units, assumed to be bank 0 here */
1013
+ { 0x0C000U, 0x0FFFFU, 0x10000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 1 on 128K units */
1014
+ { 0x10000U, 0x13FFFU, 0x14000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 3 on 128K units */
1015
+ { 0x14000U, 0x17FFFU, 0x18000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 4 on 128K units */
1016
+ { 0x18000U, 0x1BFFFU, 0x1C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 6 on 128K units */
1017
+ { 0x1C000U, 0x1FFFFU, 0x20000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" } /* RAM bank 7 on 128K units */
1018
+ };
1019
+ static const rc_memory_regions_t rc_memory_regions_zx_spectrum = { _rc_memory_regions_zx_spectrum, 8 };
1020
+
1021
+ /* ===== default ===== */
1022
+ static const rc_memory_regions_t rc_memory_regions_none = { 0, 0 };
1023
+
1024
+ const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id)
1025
+ {
1026
+ switch (console_id)
1027
+ {
1028
+ case RC_CONSOLE_3DO:
1029
+ return &rc_memory_regions_3do;
1030
+
1031
+ case RC_CONSOLE_AMIGA:
1032
+ return &rc_memory_regions_amiga;
1033
+
1034
+ case RC_CONSOLE_AMSTRAD_PC:
1035
+ return &rc_memory_regions_amstrad_pc;
1036
+
1037
+ case RC_CONSOLE_APPLE_II:
1038
+ return &rc_memory_regions_appleii;
1039
+
1040
+ case RC_CONSOLE_ARCADIA_2001:
1041
+ return &rc_memory_regions_arcadia_2001;
1042
+
1043
+ case RC_CONSOLE_ARDUBOY:
1044
+ return &rc_memory_regions_arduboy;
1045
+
1046
+ case RC_CONSOLE_ATARI_2600:
1047
+ return &rc_memory_regions_atari2600;
1048
+
1049
+ case RC_CONSOLE_ATARI_7800:
1050
+ return &rc_memory_regions_atari7800;
1051
+
1052
+ case RC_CONSOLE_ATARI_JAGUAR:
1053
+ case RC_CONSOLE_ATARI_JAGUAR_CD:
1054
+ return &rc_memory_regions_atari_jaguar;
1055
+
1056
+ case RC_CONSOLE_ATARI_LYNX:
1057
+ return &rc_memory_regions_atari_lynx;
1058
+
1059
+ case RC_CONSOLE_COLECOVISION:
1060
+ return &rc_memory_regions_colecovision;
1061
+
1062
+ case RC_CONSOLE_COMMODORE_64:
1063
+ return &rc_memory_regions_c64;
1064
+
1065
+ case RC_CONSOLE_DREAMCAST:
1066
+ return &rc_memory_regions_dreamcast;
1067
+
1068
+ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER:
1069
+ return &rc_memory_regions_elektor_tv_games;
1070
+
1071
+ case RC_CONSOLE_FAIRCHILD_CHANNEL_F:
1072
+ return &rc_memory_regions_fairchild_channel_f;
1073
+
1074
+ case RC_CONSOLE_FAMICOM_DISK_SYSTEM:
1075
+ return &rc_memory_regions_famicom_disk_system;
1076
+
1077
+ case RC_CONSOLE_GAMEBOY:
1078
+ return &rc_memory_regions_gameboy;
1079
+
1080
+ case RC_CONSOLE_GAMEBOY_COLOR:
1081
+ return &rc_memory_regions_gameboy_color;
1082
+
1083
+ case RC_CONSOLE_GAMEBOY_ADVANCE:
1084
+ return &rc_memory_regions_gameboy_advance;
1085
+
1086
+ case RC_CONSOLE_GAMECUBE:
1087
+ return &rc_memory_regions_gamecube;
1088
+
1089
+ case RC_CONSOLE_GAME_GEAR:
1090
+ return &rc_memory_regions_game_gear;
1091
+
1092
+ case RC_CONSOLE_INTELLIVISION:
1093
+ return &rc_memory_regions_intellivision;
1094
+
1095
+ case RC_CONSOLE_INTERTON_VC_4000:
1096
+ return &rc_memory_regions_interton_vc_4000;
1097
+
1098
+ case RC_CONSOLE_MAGNAVOX_ODYSSEY2:
1099
+ return &rc_memory_regions_magnavox_odyssey_2;
1100
+
1101
+ case RC_CONSOLE_MASTER_SYSTEM:
1102
+ return &rc_memory_regions_master_system;
1103
+
1104
+ case RC_CONSOLE_MEGA_DRIVE:
1105
+ return &rc_memory_regions_megadrive;
1106
+
1107
+ case RC_CONSOLE_MEGADUCK:
1108
+ return &rc_memory_regions_megaduck;
1109
+
1110
+ case RC_CONSOLE_SEGA_32X:
1111
+ return &rc_memory_regions_megadrive_32x;
1112
+
1113
+ case RC_CONSOLE_MSX:
1114
+ return &rc_memory_regions_msx;
1115
+
1116
+ case RC_CONSOLE_MS_DOS:
1117
+ return &rc_memory_regions_ms_dos;
1118
+
1119
+ case RC_CONSOLE_NEOGEO_POCKET:
1120
+ return &rc_memory_regions_neo_geo_pocket;
1121
+
1122
+ case RC_CONSOLE_NEO_GEO_CD:
1123
+ return &rc_memory_regions_neo_geo_cd;
1124
+
1125
+ case RC_CONSOLE_NINTENDO:
1126
+ return &rc_memory_regions_nes;
1127
+
1128
+ case RC_CONSOLE_NINTENDO_64:
1129
+ return &rc_memory_regions_n64;
1130
+
1131
+ case RC_CONSOLE_NINTENDO_DS:
1132
+ return &rc_memory_regions_nintendo_ds;
1133
+
1134
+ case RC_CONSOLE_NINTENDO_DSI:
1135
+ return &rc_memory_regions_nintendo_dsi;
1136
+
1137
+ case RC_CONSOLE_ORIC:
1138
+ return &rc_memory_regions_oric;
1139
+
1140
+ case RC_CONSOLE_PC8800:
1141
+ return &rc_memory_regions_pc8800;
1142
+
1143
+ case RC_CONSOLE_PC_ENGINE:
1144
+ return &rc_memory_regions_pc_engine;
1145
+
1146
+ case RC_CONSOLE_PC_ENGINE_CD:
1147
+ return &rc_memory_regions_pc_engine_cd;
1148
+
1149
+ case RC_CONSOLE_PCFX:
1150
+ return &rc_memory_regions_pcfx;
1151
+
1152
+ case RC_CONSOLE_PLAYSTATION:
1153
+ return &rc_memory_regions_playstation;
1154
+
1155
+ case RC_CONSOLE_PLAYSTATION_2:
1156
+ return &rc_memory_regions_playstation2;
1157
+
1158
+ case RC_CONSOLE_PSP:
1159
+ return &rc_memory_regions_psp;
1160
+
1161
+ case RC_CONSOLE_POKEMON_MINI:
1162
+ return &rc_memory_regions_pokemini;
1163
+
1164
+ case RC_CONSOLE_SATURN:
1165
+ return &rc_memory_regions_saturn;
1166
+
1167
+ case RC_CONSOLE_SEGA_CD:
1168
+ return &rc_memory_regions_segacd;
1169
+
1170
+ case RC_CONSOLE_SG1000:
1171
+ return &rc_memory_regions_sg1000;
1172
+
1173
+ case RC_CONSOLE_SUPER_CASSETTEVISION:
1174
+ return &rc_memory_regions_scv;
1175
+
1176
+ case RC_CONSOLE_SUPER_NINTENDO:
1177
+ return &rc_memory_regions_snes;
1178
+
1179
+ case RC_CONSOLE_SUPERVISION:
1180
+ return &rc_memory_regions_watara_supervision;
1181
+
1182
+ case RC_CONSOLE_THOMSONTO8:
1183
+ return &rc_memory_regions_thomson_to8;
1184
+
1185
+ case RC_CONSOLE_TI83:
1186
+ return &rc_memory_regions_ti83;
1187
+
1188
+ case RC_CONSOLE_TIC80:
1189
+ return &rc_memory_regions_tic80;
1190
+
1191
+ case RC_CONSOLE_UZEBOX:
1192
+ return &rc_memory_regions_uzebox;
1193
+
1194
+ case RC_CONSOLE_VECTREX:
1195
+ return &rc_memory_regions_vectrex;
1196
+
1197
+ case RC_CONSOLE_VIRTUAL_BOY:
1198
+ return &rc_memory_regions_virtualboy;
1199
+
1200
+ case RC_CONSOLE_WASM4:
1201
+ return &rc_memory_regions_wasm4;
1202
+
1203
+ case RC_CONSOLE_WII:
1204
+ return &rc_memory_regions_wii;
1205
+
1206
+ case RC_CONSOLE_WONDERSWAN:
1207
+ return &rc_memory_regions_wonderswan;
1208
+
1209
+ case RC_CONSOLE_ZX_SPECTRUM:
1210
+ return &rc_memory_regions_zx_spectrum;
1211
+
1212
+ default:
1213
+ return &rc_memory_regions_none;
1214
+ }
1215
+ }