diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 8120ac70..73444915 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.05"; + static const string Version = "106.06"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/systems/Super Famicom.sys/boards.bml b/higan/systems/Super Famicom.sys/boards.bml index f10f46c0..83ae8f0e 100644 --- a/higan/systems/Super Famicom.sys/boards.bml +++ b/higan/systems/Super Famicom.sys/boards.bml @@ -1,10 +1,10 @@ database - revision: 2018-02-10 + revision: 2018-02-15 //Boards (Production) database - revision: 2017-12-29 + revision: 2018-02-11 board: 1A0N-(01,02,10,20,30) rom @@ -379,7 +379,7 @@ board: BJ0N-(01,20) map address=00-3f,80-bf:8000-ffff map address=40-7d,c0-ff:0000-ffff -board: BJ1M-10 +board: BJ1M-(10,20) rom map address=00-3f,80-bf:8000-ffff map address=40-7d,c0-ff:0000-ffff @@ -414,9 +414,21 @@ board: YJ0N-01 //Boards (Generic) database - revision: 2018-02-10 + revision: 2018-02-15 -board: BS-HIROM-NVRAM +board: ARM-LOROM-RAM + rom + map address=00-7d,80-ff:8000-ffff mask=0x8000 + map address=40-6f,c0-ef:0000-7fff mask=0x8000 + ram + map address=70-7d,f0-ff:0000-ffff + armdsp frequency=21477272 + map address=00-3f,80-bf:3800-38ff + prom + drom + ram + +board: BS-HIROM-RAM rom map address=00-1f,80-9f:8000-ffff map address=40-5f,c0-df:0000-ffff @@ -426,7 +438,7 @@ board: BS-HIROM-NVRAM map address=20-3f,a0-bf:8000-ffff map address=60-7d,e0-ff:0000-ffff -board: BS-LOROM-NVRAM +board: BS-LOROM-RAM rom map address=00-1f:8000-ffff base=0x000000 mask=0x8000 map address=20-3f:8000-ffff base=0x100000 mask=0x8000 @@ -437,7 +449,7 @@ board: BS-LOROM-NVRAM bsmemory map address=c0-ef:0000-ffff -board: BS-NVRAM +board: BS-MCC-RAM ram map address=10-1f:5000-5fff mask=0xf000 mcc @@ -449,7 +461,7 @@ board: BS-NVRAM map address=00-3f,80-bf:6000-7fff mask=0xe000 bsmemory -board: BS-SA1-NVRAM +board: BS-SA1-RAM sa1 map address=00-3f,80-bf:2200-23ff rom @@ -463,17 +475,55 @@ board: BS-SA1-NVRAM bsmemory map -board: CX4-LOROM +board: HIROM + rom + map address=00-3f,80-bf:8000-ffff + map address=40-7d,c0-ff:0000-ffff + +board: HIROM-RAM + rom + map address=00-3f,80-bf:8000-ffff + map address=40-7d,c0-ff:0000-ffff + ram + map address=20-3f,a0-bf:6000-7fff mask=0xe000 + +board: HIROMEX-RAM + rom + map address=00-3f:8000-ffff base=0x400000 + map address=40-7d:0000-ffff base=0x400000 + map address=80-bf:8000-ffff mask=0xc00000 + map address=c0-ff:0000-ffff mask=0xc00000 + ram + map address=20-3f,a0-bf:6000-7fff mask=0xe000 + map address=70-7d:0000-7fff + +board: HITACHI-LOROM hitachidsp model=HG51B169 frequency=20000000 map address=00-3f,80-bf:6c00-6fff,7c00-7fff - map=ram address=70-77:0000-7fff mask=0x8000 + map address=70-77:0000-7fff rom map address=00-3f,80-bf:8000-ffff mask=0x8000 drom dram map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000 -board: DSP-HIROM +board: LOROM + rom + map address=00-7d,80-ff:8000-ffff mask=0x8000 + +board: LOROM-RAM + rom + map address=00-3f,80-bf:8000-ffff mask=0x8000 + ram + map address=70-7d,f0-ff:0000-ffff mask=0x8000 + +board: LOROMEX-RAM + rom + map address=00-7d,80-ff:8000-ffff mask=0x8000 + ram + map address=70-7d,f0-ff:0000-7fff mask=0x8000 + +board: NEC-HIROM rom map address=00-3f,80-bf:8000-ffff map address=40-7d,c0-ff:0000-ffff @@ -483,7 +533,7 @@ board: DSP-HIROM drom dram -board: DSP-HIROM-NVRAM +board: NEC-HIROM-RAM rom map address=00-3f,80-bf:8000-ffff map address=40-7d,c0-ff:0000-ffff @@ -495,7 +545,7 @@ board: DSP-HIROM-NVRAM drom dram -board: DSP-LOROM +board: NEC-LOROM rom map address=00-1f,80-9f:8000-ffff mask=0x8000 necdsp model=uPD7725 frequency=8000000 @@ -504,7 +554,7 @@ board: DSP-LOROM drom dram -board: DSP-LOROM-NVRAM +board: NEC-LOROM-RAM rom map address=00-1f,80-9f:8000-ffff mask=0x8000 ram @@ -515,45 +565,38 @@ board: DSP-LOROM-NVRAM drom dram -board: EXHIROM-NVRAM +board: NEC-LOROMEX-RAM rom - map address=00-3f:8000-ffff base=0x400000 - map address=40-7d:0000-ffff base=0x400000 - map address=80-bf:8000-ffff mask=0xc00000 - map address=c0-ff:0000-ffff mask=0xc00000 - ram - map address=20-3f,a0-bf:6000-7fff mask=0xe000 - map address=70-7d:0000-7fff - -board: EXLOROM-NVRAM - rom - map address=00-7d,80-ff:8000-ffff mask=0x8000 + map address=00-3f,80-bf:8000-ffff mask=0x8000 ram map address=70-7d,f0-ff:0000-7fff mask=0x8000 + necdsp model=uPD7725 frequency=8000000 + map address=60-6f,e0-ef:0000-7fff mask=0x3fff + prom + drom + dram -board: HIROM - rom - map address=00-3f,80-bf:8000-ffff - map address=40-7d,c0-ff:0000-ffff - -board: HIROM-NVRAM - rom - map address=00-3f,80-bf:8000-ffff - map address=40-7d,c0-ff:0000-ffff - ram - map address=20-3f,a0-bf:6000-7fff mask=0xe000 - -board: LOROM +board: NECEX-LOROM-BATTERY#11 rom map address=00-7d,80-ff:8000-ffff mask=0x8000 + necdsp model=uPD96050 frequency=11000000 + map address=60-67,e0-e7:0000-3fff + prom + drom + dram + map address=68-6f,e8-ef:0000-7fff mask=0x8000 -board: LOROM-NVRAM +board: NECEX-LOROM-BATTERY#15 rom - map address=00-6f,80-ef:8000-ffff mask=0x8000 - ram - map address=70-7d,f0-ff:0000-ffff mask=0x8000 + map address=00-7d,80-ff:8000-ffff mask=0x8000 + necdsp model=uPD96050 frequency=15000000 + map address=60-67,e0-e7:0000-3fff + prom + drom + dram + map address=68-6f,e8-ef:0000-7fff mask=0x8000 -board: OBC1-LOROM-NVRAM +board: OBC1-LOROM-RAM rom map address=00-3f,80-bf:8000-ffff mask=0x8000 obc1 @@ -561,7 +604,7 @@ board: OBC1-LOROM-NVRAM map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000 ram -board: RTC-EXHIROM-NVRAM +board: RTC-HIROMEX-RAM rom map address=00-3f:8000-ffff base=0x400000 map address=40-7d:0000-ffff base=0x400000 @@ -574,7 +617,7 @@ board: RTC-EXHIROM-NVRAM map address=00-3f,80-bf:2800-2801 ram -board: SA1-(RAM,NVRAM) +board: SA1-RAM sa1 map address=00-3f,80-bf:2200-23ff rom @@ -593,7 +636,7 @@ board: SDD1 map address=00-3f,80-bf:8000-ffff map address=c0-ff:0000-ffff -board: SDD1-NVRAM +board: SDD1-RAM sdd1 map address=00-3f,80-bf:4800-480f rom @@ -611,7 +654,7 @@ board: SGB-LOROM map address=00-3f,80-bf:6000-67ff,7000-7fff rom -board: SPC7110-NVRAM +board: SPC7110-RAM spc7110 map address=00-3f,80-bf:4800-483f map address=50,58:0000-ffff @@ -622,7 +665,7 @@ board: SPC7110-NVRAM ram map address=00-3f,80-bf:6000-7fff mask=0xe000 -board: SPC7110-RTC-NVRAM +board: SPC7110-RTC-RAM spc7110 map address=00-3f,80-bf:4800-483f map address=50,58:0000-ffff @@ -651,39 +694,7 @@ board: ST-LOROM ram map address=70-7d,f0-ff:0000-ffff -board: ST010-LOROM-BATTERY - rom - map address=00-7d,80-ff:8000-ffff mask=0x8000 - necdsp model=uPD96050 frequency=11000000 - map address=60-67,e0-e7:0000-3fff - prom - drom - dram - map address=68-6f,e8-ef:0000-7fff mask=0x8000 - -board: ST011-LOROM-BATTERY - rom - map address=00-7d,80-ff:8000-ffff mask=0x8000 - necdsp model=uPD96050 frequency=15000000 - map address=60-67,e0-e7:0000-3fff - prom - drom - dram - map address=68-6f,e8-ef:0000-7fff mask=0x8000 - -board: ST018-LOROM-NVRAM - rom - map address=00-7d,80-ff:8000-ffff mask=0x8000 - map address=40-6f,c0-ef:0000-7fff mask=0x8000 - ram - map address=70-7d,f0-ff:0000-ffff - armdsp frequency=21477272 - map address=00-3f,80-bf:3800-38ff - prom - drom - ram - -board: SUPERFX-(RAM,NVRAM) +board: SUPERFX-RAM superfx map address=00-3f,80-bf:3000-34ff rom diff --git a/icarus/Database/BS Memory.bml b/icarus/Database/BS Memory.bml new file mode 100644 index 00000000..7acfd945 --- /dev/null +++ b/icarus/Database/BS Memory.bml @@ -0,0 +1,44 @@ +database + revision: 2018-02-14 + +//BS Memory (JPN) + +database + revision: 2018-02-12 + +game + sha256: 80c34b50817d58820bc8c88d2d9fa462550b4a76372e19c6467cbfbc8cf5d9ef + region: BSMC-ZS5J-JPN + revision: BSMC-ZS5J-0 + board: BSMC-CR-01 + name: Same Game - Chara Cassette + label: 鮫亀 キャラカセット + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: 859c7f7b4771d920a5bdb11f1d247ab6b43fb026594d1062f6f72d32cd340a0a + region: BSMC-YS5J-JPN + revision: BSMC-YS5J-0 + board: BSMC-CR-01 + name: Same Game - Chara Data Shuu + label: 鮫亀 キャラデータ集 + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: c92a15fdd9b0133f9ea69105d0230a3acd1cdeef98567462eca86ea02a959e4e + region: BSMC-ZX3J-JPN + revision: BSMC-ZX3J-0 + board: BSMC-BR-01 + name: SD Gundam G Next - Unit & Map Collection + label: SDガンダム ジーネクスト ユニット&マップコレクション + memory + type: ROM + size: 0x80000 + name: program.rom + diff --git a/icarus/Database/Sufami Turbo.bml b/icarus/Database/Sufami Turbo.bml new file mode 100644 index 00000000..878bde13 --- /dev/null +++ b/icarus/Database/Sufami Turbo.bml @@ -0,0 +1,213 @@ +database + revision: 2018-02-14 + +//Sufami Turbo (JPN) + +database + revision: 2018-02-12 + +game + sha256: f73bda08743565e0bd101632ebbac2d363d703a3ab39d23f49d95217cab29269 + region: SFT-0112-JPN + revision: SAILOR MOON + board: PT-911 + name: Bishoujo Senshi Sailor Moon Sailor Stars - Fuwafuwa Panic 2 + label: 美少女戦士セーラームーン セーラースターズ ふわふわパニック2 + note: Unlinkable + memory + type: ROM + size: 0x100000 + name: program.rom + +game + sha256: afb3f2a83b5bfcb1b8829b6995f108cc4d64ca322d1ba4a50b83af6e1f2e89bd + region: SFT-0113-JPN + revision: SHINCYAN + board: PT-911 + name: Crayon Shin-chan - Nagagutsu Dobon!! + label: クレヨンしんちゃん 長ぐつドボン!! + note: Unlinkable + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: d93b3a570e7cf343f680ab0768a50b77e3577f9c555007e2de3decd6bc4765c8 + region: SFT-0106-JPN + revision: KITARO DONJYAR + board: PT-911 + name: Gegege no Kitarou - Youkai Donjara + label: ゲゲゲの鬼太郎 妖怪ドンジャラ + note: Unlinkable + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: 89aecd4e23d8219c8de3e71bb75db3dfe667d51c1eba4ea7239d2f772743d0cc + region: SFT-0109-JPN + revision: CAR RANGER + board: PT-911 + name: Gekisou Sentai Carranger - Zenkai! Racer Senshi + label: 激走戦隊カーレンジャ 全開!レーサー戦士 + note: Unlinkable + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: 602b20b788640f5743487108a10f3f77bca5ce2d24208b25b1ca498a96eb0d69 + region: SFT-0103-JPN + revision: POI POI NINJYA + board: PT-911 + name: Poi Poi Ninja World + label: ぽいぽい忍者ワールド + note: Linkable: SFT-0103-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x800 + name: save.ram + +game + sha256: 2a9d7c9a61318861028a73ca03e32a48cff162d76cba36fbaab8690b212efe9b + region: SFT-0107-JPN + revision: GUNDAM C + board: PT-912 + name: SD Gundam Generation - Axis Senki + label: SDガンダムジェネレーション アクシズ戦記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 60ac017c18f534e8cf24ca7f38e22ce92db95ea6c30b2d59d76f13c4f1c8a6e4 + region: SFT-0108-JPN + revision: GUNDAM D + board: PT-912 + name: SD Gundam Generation - Babylonia Kenkoku Senki + label: SDガンダムジェネレーション バビロニア建国戦記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: e639b5d5d722432b6809ccc6801dc584e1a3016379f34b335ed2dfa73b1ebf69 + region: SFT-0111-JPN + revision: GUNDAM F + board: PT-912 + name: SD Gundam Generation - Colony Kakutouki + label: SDガンダムジェネレーション コロニー格闘記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 8547a08ed11fe408eac282a90ac46654bd2e5f49bda3aec8e5edf166a0a4b9af + region: SFT-0105-JPN + revision: GUNDAM B + board: PT-912 + name: SD Gundam Generation - Gryps Senki + label: SDガンダムジェネレーション グリプス戦記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 3e82215bed08274874b30d461fc4a965c6bca932229da5d46d56e36f484d65eb + region: SFT-0104-JPN + revision: GUNDAM A + board: PT-912 + name: SD Gundam Generation - Ichinen Sensouki + label: SDガンダムジェネレーション 一年戦争記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 5951a58a91d8e397d0a237ccc2b1248e17c7312cb9cc11cbc350200a97b4e021 + region: SFT-0110-JPN + revision: GUNDAM E + board: PT-912 + name: SD Gundam Generation - Zanscare Senki + label: SDガンダムジェネレーション ザンスカール戦記 + note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 2fec5f2bc7dee010af10569a3d2bc18715a79a126940800c3eade5abbd625e3f + region: SFT-0102-JPN + revision: ULTRA SEVEN 1 + board: PT-911 + name: SD Ultra Battle - Seven Densetsu + label: SDウルトラバトル セブン伝説 + note: Linkable: SFT-0101-JPN, SFT-0102-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x800 + name: save.ram + +game + sha256: 2bb55214fb668ca603d7b944b14f105dfb10b987a8902d420fe4ae1cb69c1d4a + region: SFT-0101-JPN + revision: ULTRA MAN 1 + board: PT-911 + name: SD Ultra Battle - Ultraman Densetsu + label: SDウルトラバトル ウルトラマン伝説 + note: Linkable: SFT-0101-JPN, SFT-0102-JPN + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x800 + name: save.ram + diff --git a/icarus/Database/Super Famicom.bml b/icarus/Database/Super Famicom.bml index 1765e697..7b6c22c9 100644 --- a/icarus/Database/Super Famicom.bml +++ b/icarus/Database/Super Famicom.bml @@ -1,5 +1,5 @@ database - revision: 2018-02-01 + revision: 2018-02-14 //Super Comboy (KOR) @@ -58,6 +58,317 @@ game size: 0x100000 name: program.rom +//Super Famicom (HKG) + +database + revision: 2018-02-14 + +game + sha256: bd763c1a56365c244be92e6cffefd318780a2a19eda7d5baf1c6d5bd6c1b3e06 + region: SNSN-YI-HKG + revision: SNS-YI-1 + board: SHVC-1CB5B-20 + name: Super Mario World 2 - Yoshi's Island + label: Super Mario World 2: Yoshi's Island + memory + type: ROM + size: 0x200000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + +//Super Famicom (JPN) + +database + revision: 2018-02-14 + +game + sha256: 3ce321496edc5d77038de2034eb3fb354d7724afd0bc7fd0319f3eb5d57b984d + region: SHVC-ZBSJ-JPN + revision: SHVC-ZBSJ-1 + board: BSC-1A5B9P-01 + name: BS-X - Sore wa Namae o Nusumareta Machi no Monogatari + label: BS-X それは名前を盗まれた街の物語 + memory + type: ROM + size: 0x100000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + memory + type: PSRAM + size: 0x80000 + name: download.ram + +game + sha256: 38a855229eab468c3ede7573db73082c66b157adfc7af787ccac50559b747f5f + region: SHVC-ZDBJ-JPN + revision: SHVC-ZDBJ-0 + board: BSC-1A5M-02 + name: Derby Stallion '96 + label: ダービースタリオン96 + memory + type: ROM + size: 0x300000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + +game + sha256: 74aa3a26b66f34819fbbdcdb2475cf9161cc2590fb1ec89fb24940ef10e44332 + region: SHVC-F4 + revision: SHVC-F4-0 + board: SHVC-1A3B-11 + name: Final Fantasy IV + label: ファイナルファンタジーIV + memory + type: ROM + size: 0x100000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 4dfba33201de6b5dec952d0f327aeb44ed784c025a72c982356dd41b52efc219 + region: SHVC-ZBPJ-JPN + revision: SHVC-ZBPJ-0 + board: BSC-1L3B-01 + name: Itoi Shigesato no Bass Tsuri No. 1 + label: 糸井重里のバス釣りNo. 1 + memory + type: ROM + size: 0x400000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + memory + type: RAM + size: 0x800 + name: internal.ram + +game + sha256: 23b320be74b9fc20de512080be3051575ba36c3246d5c4ee224f31a2fa7808f5 + region: SHVC-ZTMJ-JPN + revision: SHVC-ZTMJ-0 + board: BSC-1J3M-01 + name: Joushou Mahjong Tenpai + label: 常勝麻雀天牌 + memory + type: ROM + size: 0x100000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: d712adecbde70a74c4a580fe90a45d0d19f2641d1b4e091d507bddeec9601de1 + region: SHVC-ZMCJ-JPN + revision: SHVC-ZMCJ-0 + board: BSC-1J5M-01 + name: Ongaku Tsukuuru Kanadeeru + label: 音楽ツクールかなでーる + memory + type: ROM + size: 0x100000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + +game + sha256: d1e0d1c930011d22423cb7cde8feac445a00705da8067a4e53a735b08389a19d + region: SHVC-ZR2J-JPN + revision: SHVC-ZR2J-0 + board: BSC-1A7M-01 + name: RPG Tsukuuru 2 + label: RPGツクール2 + memory + type: ROM + size: 0x200000 + name: program.rom + memory + type: NVRAM + size: 0x10000 + name: save.ram + +game + sha256: 3a709383208d8258dceb20a5e566903326515ba42931bf97fd389a415a13a72d + region: SHVC-ZS5J-JPN + revision: SHVC-ZS5J-0 + board: BSC-1J3M-01 + name: Same Game + label: 鮫亀 + memory + type: ROM + size: 0x100000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 208f5ecb7a82b33629e67f39e96b7aa7a992cb2fcc3d1e4eb959abb0a8b7dd95 + region: SHVC-ZX3J-JPN + revision: SHVC-ZX3J-0 + board: BSC-1L5B-01 + name: SD Gundam G Next + label: SDガンダム ジーネクスト + memory + type: ROM + size: 0x180000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + memory + type: RAM + size: 0x800 + name: internal.ram + +game + sha256: 7be858fc681df6728650f460d67fe6c80d816d5fbfc530c11153f652f8b1878e + region: SHVC-ZSNJ-JPN + revision: SHVC-ZSNJ-0 + board: BSC-1A7M-10 + name: Sound Novel Tsukuuru + label: サウンドノベルツクール + memory + type: ROM + size: 0x300000 + name: program.rom + memory + type: NVRAM + size: 0x10000 + name: save.ram + +game + sha256: edacb453da14f825f05d1134d6035f4bf034e55f7cfb97c70c4ee107eabc7342 + region: SHVC-A9PJ-JPN + revision: SHVC-A9PJ-0 + board: BANDAI-PT-923 + name: Sufami Turbo + label: スーファミターボ + memory + type: ROM + size: 0x40000 + name: program.rom + +game + sha256: 4d7fc331a811b8dc630b469262fd6f45e289243cef83101f32038158967d1b28 + region: SHVC-SGB + revision: SYS-SGB-2 + board: SGB-R-10 + name: Super Game Boy + label: スーパーゲームボーイ + memory + type: ROM + size: 0x40000 + name: program.rom + memory + type: ROM + size: 0x100 + name: sgb1.boot.rom + +game + sha256: e1db895a9da7ce992941c1238f711437a9110c2793083bb04e0b4d49b7915916 + region: SHVC-SGB2-JPN + revision: SYS-SGB2-10 + board: SHVC-SGB2-01 + name: Super Game Boy 2 + label: スーパーゲームボーイ2 + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: ROM + size: 0x100 + name: sgb2.boot.rom + +game + sha256: f56c083e54bc94efdc46c5224b3ceebc56c8ba7a0c38ee8620b0f73cd1317677 + region: SHVC-IQ + revision: SHVC-IQ-0 + board: SHVC-1A3B-13 + name: Super Mahjong Taikai + label: スーパー麻雀大会 + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 96c0cb3c670c36e068c36b38d1edae145f24f60159537da4988bf956eee58d59 + region: SHVC-IQ + revision: SHVC-IQ-1 + board: SHVC-1A3B-13 + name: Super Mahjong Taikai + label: スーパー麻雀大会 + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +game + sha256: 15d1187d17fa10c77152f691197d33674e64c33a1f8ceb37e8570588be507b89 + region: SHVC-IQ + revision: SHVC-IQ-3 + board: SHVC-1A3B-13 + name: Super Mahjong Taikai + label: スーパー麻雀大会 + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + +//Super Famicom (ROC) + +database + revision: 2018-02-11 + +game + sha256: 1cf13dac329f83a7fe5347dcc20f92c3a09b3eab1511dd461f9cec90e9258403 + region: SNSN-S3-ROC + revision: SCHN-S3-0 + board: SHVC-1J5M-20 + name: Sanguozhi III + label: 三国志III + memory + type: ROM + size: 0x180000 + name: program.rom + memory + type: NVRAM + size: 0x8000 + name: save.ram + //Super Nintendo (AUS) database @@ -103,6 +414,28 @@ game size: 0x100000 name: program.rom +//Super Nintendo (BRA) + +database + revision: 2018-02-11 + +game + sha256: 1edcceab07d1544dcbd0fd681148b0fbefeea58b7077136fa0c3011973bf34df + region: SNS-A8FB-BRA + revision: SNS-A8FB-0 + board: EA-1A3M-30 + name: FIFA - A Caminho da Copa '98 + label: FIFA: A Caminho da Copa '98 + note: Serial# is from ROM data; it is not present on cartridge or ROM chip + memory + type: ROM + size: 0x200000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + //Super Nintendo (CAN) database @@ -127,7 +460,7 @@ game //Super Nintendo (ESP) database - revision: 2018-01-29 + revision: 2018-02-11 game sha256: bd5e7a6bc08f64d39c54204b82c6c156f144c03e13c890128588c5faa560659c @@ -165,6 +498,30 @@ game size: 0x100000 name: program.rom +game + sha256: 4a4803056afb251b06a2e9fa68d8062b6999156535bb66ff9fb069de180f32c1 + region: SNSP-JN-ESP + revision: SPAL-JN-0 + board: SHVC-1A0N-10 + name: Jack Nicklaus Golf + label: Jack Nicklaus Golf + memory + type: ROM + size: 0x80000 + name: program.rom + +game + sha256: 929e15c8439b3beea249730e598e72cb192a3a70af0624ab7f91300f8f786a13 + region: SNSP-J8-ESP + revision: SESP-J8-0 + board: SHVC-2A0N-01 + name: Jurassic Park + label: Jurassic Park + memory + type: ROM + size: 0x200000 + name: program.rom + game sha256: d2233d6310522bbf183b6ca9bbe3e2afaf24de0cc4304bff6d0d547d678aed6f region: SNSP-SK-ESP @@ -244,7 +601,7 @@ game //Super Nintendo (EUR) database - revision: 2018-01-30 + revision: 2018-02-11 game sha256: ec3e81d628a293514e303b44e3b1ac03461ddd1da32764b10b7fab1e507602df @@ -925,10 +1282,6 @@ game type: ROM size: 0x180000 name: program.rom - memory - type: RAM - size: 0 - name: save.ram memory type: ROM size: 0xc00 @@ -949,10 +1302,6 @@ game type: ROM size: 0x200000 name: program.rom - memory - type: RAM - size: 0 - name: save.ram memory type: ROM size: 0xc00 @@ -1397,7 +1746,7 @@ game //Super Nintendo (FAH) database - revision: 2018-01-29 + revision: 2018-02-11 game sha256: 0aafd04a43ae29266e43920a7f9954d4a49f6fe43a5abffecc9c2fd5ad7d6cea @@ -1503,6 +1852,18 @@ game size: 0x100000 name: program.rom +game + sha256: 5a181f25055298579d24571b4f1cd21dd81583fb41a235fc4f226fa28d9df916 + region: SNSP-JN-FAH + revision: SFRA-JN-0 + board: SHVC-1A0N-20 + name: Jack Nicklaus Golf + label: Jack Nicklaus Golf + memory + type: ROM + size: 0x80000 + name: program.rom + game sha256: 9b52a2848b78aa7ecb7cac295bce7ae033089af6099e127c2c904f518c6d4b89 region: SNSP-LV-FAH @@ -1778,7 +2139,7 @@ game //Super Nintendo (FRA) database - revision: 2018-01-29 + revision: 2018-02-11 game sha256: 65df600780021f13ced52e7fbc507b7b2e6491b2c5c25fe78d0515dcbe669403 @@ -1948,6 +2309,22 @@ game size: 0x800 name: save.ram +game + sha256: 1432590492b63d7103caa715e10e3c3ebbc77b63b6472ee9dee0e5afda311551 + region: SNSP-MQ-FRA + revision: SFRA-MQ-0 + board: SHVC-1A3M-20 + name: Mystic Quest Legend + label: Mystic Quest Legend + memory + type: ROM + size: 0x80000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + game sha256: a4621118ef174d2c8a9ffe934e31ff3a00f66a3aaa13340983eec43625a773f6 region: SNSP-25-FRA @@ -2074,6 +2451,27 @@ game size: 0x800 name: save.ram +//Super Nintendo (HOL) + +database + revision: 2018-02-11 + +game + sha256: dc8b3144329a23459bfcce93c89e0e561d133709aca6bfc74f9e0755f1a04b91 + region: SNSP-ANIH-HOL + revision: SPAL-ANIH-0 + board: SHVC-1A3M-30 + name: Lufia + label: Lufia + memory + type: ROM + size: 0x300000 + name: program.rom + memory + type: NVRAM + size: 0x2000 + name: save.ram + //Super Nintendo (ITA) database @@ -2111,7 +2509,7 @@ game //Super Nintendo (NOE) database - revision: 2018-01-29 + revision: 2018-02-11 game sha256: b342d12d71729edebc1911725ea23d58c1a397b27253a5c8cd96cfb58af242a9 @@ -2166,8 +2564,8 @@ game region: SNSP-AP-NOE revision: SPAL-AP-0 board: SHVC-1A0N-20 - name: Alien vs Predator - label: Alien vs Predator + name: Alien vs. Predator + label: Alien vs. Predator memory type: ROM size: 0x100000 @@ -3409,7 +3807,7 @@ game //Super Nintendo (UKV) database - revision: 2018-01-29 + revision: 2018-02-11 game sha256: 38e050ac3ffec01031c6dd8ead20676aacec78ebf8d890a3a00d1badaaba3d3b @@ -3751,6 +4149,18 @@ game size: 0x2000 name: save.ram +game + sha256: 21f4b54ed90de7bb0f5f02d64d11f80ba9f2147197b7a3bd09fc7aa1858ba0f5 + region: SNSP-4P-UKV + revision: SPAL-4P-0 + board: SHVC-1A0N-20 + name: Side Pocket + label: Side Pocket + memory + type: ROM + size: 0x100000 + name: program.rom + game sha256: d02f8e6b75f9b9ede20a32b8ec93c06475f18160ced1eb069cd6a3cbbc3cba2e region: SNSP-7Q-UKV @@ -4018,7 +4428,7 @@ game //Super Nintendo (USA) database - revision: 2018-01-30 + revision: 2018-02-11 game sha256: 2ffe8828480f943056fb1ab5c3c84d48a0bf8cbe3ed7c9960b349b59adb07f3b @@ -5872,6 +6282,22 @@ game size: 0x800 name: save.ram +game + sha256: b79c2bb86f6fc76e1fc61c62fc16d51c664c381e58bc2933be643bbc4d8b610c + region: SNS-ADNE-USA + revision: SNS-ADNE-1 + board: SHVC-BJ1M-20 + name: Donkey Kong Country 2 - Diddy's Kong Quest + label: Donkey Kong Country 2: Diddy's Kong Quest + memory + type: ROM + size: 0x400000 + name: program.rom + memory + type: NVRAM + size: 0x800 + name: save.ram + game sha256: 2277a2d8dddb01fe5cb0ae9a0fa225d42b3a11adccaeafa18e3c339b3794a32b region: SNS-A3CE-USA @@ -8495,10 +8921,6 @@ game type: ROM size: 0x180000 name: program.rom - memory - type: NVRAM - size: 0 - name: save.ram memory type: ROM size: 0xc00 @@ -8519,10 +8941,6 @@ game type: ROM size: 0x200000 name: program.rom - memory - type: NVRAM - size: 0 - name: save.ram memory type: ROM size: 0xc00 diff --git a/icarus/Firmware/cx4.data.rom b/icarus/Firmware/cx4.data.rom new file mode 100644 index 00000000..31c8c44d Binary files /dev/null and b/icarus/Firmware/cx4.data.rom differ diff --git a/icarus/Firmware/sgb1.boot.rom b/icarus/Firmware/sgb1.boot.rom new file mode 100644 index 00000000..2bece748 Binary files /dev/null and b/icarus/Firmware/sgb1.boot.rom differ diff --git a/icarus/Firmware/sgb2.boot.rom b/icarus/Firmware/sgb2.boot.rom new file mode 100644 index 00000000..96d22b34 Binary files /dev/null and b/icarus/Firmware/sgb2.boot.rom differ diff --git a/icarus/GNUmakefile b/icarus/GNUmakefile index 937a5a9f..cf4b54a1 100644 --- a/icarus/GNUmakefile +++ b/icarus/GNUmakefile @@ -44,10 +44,12 @@ else ifneq ($(filter $(platform),linux bsd),) mkdir -p $(prefix)/share/applications/ mkdir -p $(prefix)/share/icons/ mkdir -p $(prefix)/share/$(name)/Database/ + mkdir -p $(prefix)/share/$(name)/Firmware/ cp out/$(name) $(prefix)/bin/$(name) cp data/$(name).desktop $(prefix)/share/applications/$(name).desktop cp data/$(name).png $(prefix)/share/icons/$(name).png cp -R Database/* $(prefix)/share/$(name)/Database/ + cp -R Firmware/* $(prefix)/share/$(name)/Firmware/ endif uninstall: diff --git a/icarus/core/bs-memory.cpp b/icarus/core/bs-memory.cpp index 54a96549..25a5b016 100644 --- a/icarus/core/bs-memory.cpp +++ b/icarus/core/bs-memory.cpp @@ -5,7 +5,7 @@ auto Icarus::bsMemoryManifest(string location) -> string { } auto Icarus::bsMemoryManifest(vector& buffer, string location) -> string { - string digest = Hash::SHA256(buffer).digest(); + auto digest = Hash::SHA256(buffer).digest(); if(settings["icarus/UseDatabase"].boolean()) { for(auto game : database.bsMemory.find("game")) { @@ -14,11 +14,11 @@ auto Icarus::bsMemoryManifest(vector& buffer, string location) -> strin } if(settings["icarus/UseHeuristics"].boolean()) { - Heuristics::BSMemory game{buffer.data(), buffer.size()}; - if(string manifest = game.manifest()) return manifest; + Heuristics::BSMemory game{buffer, location}; + if(auto manifest = game.manifest()) return manifest; } - return ""; + return {}; } auto Icarus::bsMemoryImport(vector& buffer, string location) -> string { diff --git a/icarus/core/core.hpp b/icarus/core/core.hpp index f59c25eb..f48de576 100644 --- a/icarus/core/core.hpp +++ b/icarus/core/core.hpp @@ -44,7 +44,6 @@ struct Icarus { //super-famicom.cpp auto superFamicomManifest(string location) -> string; auto superFamicomManifest(vector& buffer, string location) -> string; - auto superFamicomManifestScan(vector& roms, Markup::Node node) -> void; auto superFamicomImport(vector& buffer, string location) -> string; //master-system.cpp diff --git a/icarus/core/sufami-turbo.cpp b/icarus/core/sufami-turbo.cpp index 60bd41e7..5bd381ad 100644 --- a/icarus/core/sufami-turbo.cpp +++ b/icarus/core/sufami-turbo.cpp @@ -5,7 +5,7 @@ auto Icarus::sufamiTurboManifest(string location) -> string { } auto Icarus::sufamiTurboManifest(vector& buffer, string location) -> string { - string digest = Hash::SHA256(buffer).digest(); + auto digest = Hash::SHA256(buffer).digest(); if(settings["icarus/UseDatabase"].boolean()) { for(auto game : database.sufamiTurbo.find("game")) { @@ -14,11 +14,11 @@ auto Icarus::sufamiTurboManifest(vector& buffer, string location) -> st } if(settings["icarus/UseHeuristics"].boolean()) { - Heuristics::SufamiTurbo game{buffer.data(), buffer.size()}; - if(string manifest = game.manifest()) return manifest; + Heuristics::SufamiTurbo game{buffer, location}; + if(auto manifest = game.manifest()) return manifest; } - return ""; + return {}; } auto Icarus::sufamiTurboImport(vector& buffer, string location) -> string { diff --git a/icarus/core/super-famicom.cpp b/icarus/core/super-famicom.cpp index 50dceb21..1d15fb39 100644 --- a/icarus/core/super-famicom.cpp +++ b/icarus/core/super-famicom.cpp @@ -3,7 +3,6 @@ auto Icarus::superFamicomManifest(string location) -> string { auto files = directory::files(location, "*.rom"); concatenate(buffer, {location, "program.rom"}); concatenate(buffer, {location, "data.rom" }); - for(auto& file : files.match("slot-*.rom" )) concatenate(buffer, {location, file}); for(auto& file : files.match("*.boot.rom" )) concatenate(buffer, {location, file}); for(auto& file : files.match("*.program.rom")) concatenate(buffer, {location, file}); for(auto& file : files.match("*.data.rom" )) concatenate(buffer, {location, file}); @@ -11,7 +10,7 @@ auto Icarus::superFamicomManifest(string location) -> string { } auto Icarus::superFamicomManifest(vector& buffer, string location) -> string { - string digest = Hash::SHA256(buffer).digest(); + auto digest = Hash::SHA256(buffer).digest(); if(settings["icarus/UseDatabase"].boolean()) { for(auto game : database.superFamicom.find("game")) { @@ -20,17 +19,14 @@ auto Icarus::superFamicomManifest(vector& buffer, string location) -> s } if(settings["icarus/UseHeuristics"].boolean()) { - bool hasMSU1 = exists({location, "msu1.rom"}); - Heuristics::SuperFamicom game{buffer.data(), buffer.size(), hasMSU1}; - if(string manifest = game.manifest()) return manifest; + Heuristics::SuperFamicom game{buffer, location}; + if(auto manifest = game.manifest()) { + if(exists({location, "msu1.rom"})) manifest.append(" msu1\n"); + return manifest; + } } - return ""; -} - -auto Icarus::superFamicomManifestScan(vector& roms, Markup::Node node) -> void { - if(node["name"].text().endsWith(".rom")) roms.append(node); - for(auto leaf : node) superFamicomManifestScan(roms, leaf); + return {}; } auto Icarus::superFamicomImport(vector& buffer, string location) -> string { @@ -38,24 +34,28 @@ auto Icarus::superFamicomImport(vector& buffer, string location) -> str auto source = Location::path(location); string target{settings["Library/Location"].text(), "Super Famicom/", name, ".sfc/"}; - auto markup = superFamicomManifest(buffer, location); - if(!markup) return failure("failed to parse ROM image"); + auto manifest = superFamicomManifest(buffer, location); + if(!manifest) return failure("failed to parse ROM image"); if(!create(target)) return failure("library path unwritable"); if(exists({source, name, ".srm"}) && !exists({target, "save.ram"})) { copy({source, name, ".srm"}, {target, "save.ram"}); } - if(settings["icarus/CreateManifests"].boolean()) write({target, "manifest.bml"}, markup); - uint offset = (buffer.size() & 0x7fff) == 512 ? 512 : 0; //skip header if present - auto document = BML::unserialize(markup); - vector roms; - superFamicomManifestScan(roms, document["board"]); - for(auto rom : roms) { + if(settings["icarus/CreateManifests"].boolean()) write({target, "manifest.bml"}, manifest); + uint offset = 0; + auto document = BML::unserialize(manifest); + for(auto rom : document.find("game/memory")) { + if(rom["type"].text() != "ROM") continue; auto name = rom["name"].text(); auto size = rom["size"].natural(); if(size > buffer.size() - offset) { - missingFiles.append(name); + auto location = locate({"Firmware/", name}); + if(location && file::size(location) == size) { + write({target, name}, file::read(location)); + } else { + missingFiles.append(name); + } continue; } write({target, name}, buffer.data() + offset, size); diff --git a/icarus/heuristics/bs-memory.cpp b/icarus/heuristics/bs-memory.cpp index 86118f84..c06f4ca1 100644 --- a/icarus/heuristics/bs-memory.cpp +++ b/icarus/heuristics/bs-memory.cpp @@ -1,21 +1,21 @@ namespace Heuristics { struct BSMemory { - BSMemory(const uint8_t* data, uint size); + BSMemory(vector& data, string location); explicit operator bool() const; auto manifest() const -> string; private: - const uint8_t* data = nullptr; - uint size = 0; + vector& data; + string location; }; -BSMemory::BSMemory(const uint8_t* data, uint size) : data(data), size(size) { +BSMemory::BSMemory(vector& data, string location) : data(data), location(location) { } BSMemory::operator bool() const { - return size == 0x100000; + return data.size() >= 0x8000; } auto BSMemory::manifest() const -> string { @@ -23,10 +23,12 @@ auto BSMemory::manifest() const -> string { string output; output.append("game\n"); - output.append(" sha256: ", Hash::SHA256(data, size).digest(), "\n"); + output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); + output.append(" name: ", Location::prefix(location), "\n"); + output.append(" label: ", Location::prefix(location), "\n"); output.append(" memory\n"); output.append(" type: NAND\n"); - output.append(" size: 0x", hex(size), "\n"); + output.append(" size: 0x", hex(data.size()), "\n"); output.append(" name: program.rom\n"); return output; } diff --git a/icarus/heuristics/sufami-turbo.cpp b/icarus/heuristics/sufami-turbo.cpp index 6f11ec23..95852225 100644 --- a/icarus/heuristics/sufami-turbo.cpp +++ b/icarus/heuristics/sufami-turbo.cpp @@ -1,39 +1,37 @@ namespace Heuristics { struct SufamiTurbo { - SufamiTurbo(const uint8_t* data, uint size); + SufamiTurbo(vector& data, string location); explicit operator bool() const; auto manifest() const -> string; private: - const uint8_t* data = nullptr; - uint size = 0; + vector& data; + string location; }; -SufamiTurbo::SufamiTurbo(const uint8_t* data, uint size) : data(data), size(size) { +SufamiTurbo::SufamiTurbo(vector& data, string location) : data(data), location(location) { } SufamiTurbo::operator bool() const { - return size >= 0x20000; + return data.size() >= 0x20000; } auto SufamiTurbo::manifest() const -> string { if(!operator bool()) return ""; uint romSize = data[0x36] * 0x20000; //128KB - uint ramSize = data[0x37] * 0x800; //2KB - bool linkable = data[0x35]; //TODO: unconfirmed + uint ramSize = data[0x37] * 0x800; // 2KB string output; output.append("game\n"); - if(linkable) { - output.append(" linkable\n"); - } + output.append(" name: ", Location::prefix(location), "\n"); + output.append(" label: ", Location::prefix(location), "\n"); if(romSize) { output.append(" memory\n"); output.append(" type: ROM\n"); - output.append(" size: 0x", hex(romSize), "\n"); + output.append(" size: 0x", hex(data.size()), "\n"); output.append(" name: program.rom\n"); } if(ramSize) { diff --git a/icarus/heuristics/super-famicom.cpp b/icarus/heuristics/super-famicom.cpp index 6ed9b830..7214ab10 100644 --- a/icarus/heuristics/super-famicom.cpp +++ b/icarus/heuristics/super-famicom.cpp @@ -1,12 +1,10 @@ namespace Heuristics { struct SuperFamicom { - SuperFamicom(const uint8_t* data, uint size, bool hasMSU1 = false); + SuperFamicom(vector& data, string location); explicit operator bool() const; auto manifest() const -> string; - auto memory(string type, uint size, string name) const -> string; - auto sha256() const -> string; auto region() const -> string; auto revision() const -> string; auto board() const -> string; @@ -15,19 +13,31 @@ struct SuperFamicom { auto romSize() const -> uint; auto ramSize() const -> uint; auto expansionRamSize() const -> uint; + auto battery() const -> bool; private: + auto size() const -> uint { return data.size(); } + auto memory(string type, uint size, string name) const -> string; auto scoreHeader(uint address) -> uint; + auto firmwareARM() const -> string; + auto firmwareHITACHI() const -> string; + auto firmwareNEC() const -> string; + auto firmwareNECEX() const -> string; + auto firmwareSGB() const -> string; - const uint8_t* data = nullptr; - uint size = 0; + vector& data; + string location; uint headerAddress = 0; - bool hasMSU1 = false; }; -SuperFamicom::SuperFamicom(const uint8_t* data, uint size, bool hasMSU1) : data(data), size(size), hasMSU1(hasMSU1) { - if((size & 0x7fff) == 512) data += 512, size -= 512; //skip copier header (if present) - if(size < 0x8000) return; //ignore images too small to be valid +SuperFamicom::SuperFamicom(vector& data, string location) : data(data), location(location) { + if((size() & 0x7fff) == 512) { + //remove header if present + memory::move(&data[0], &data[512], size() - 512); + data.resize(size() - 512); + } + + if(size() < 0x8000) return; //ignore images too small to be valid uint scoreLo = scoreHeader( 0x7fb0); uint scoreHi = scoreHeader( 0xffb0); @@ -44,73 +54,70 @@ SuperFamicom::operator bool() const { } auto SuperFamicom::manifest() const -> string { - if(!operator bool()) return "error\n"; + if(!operator bool()) return {}; string output; output.append("game\n"); - output.append(" sha256: ", sha256(), "\n"); + output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" region: ", region(), "\n"); output.append(" revision: ", revision(), "\n"); output.append(" board: ", board(), "\n"); + output.append(" name: ", Location::prefix(location), "\n"); output.append(" label: ", label(), "\n"); auto board = this->board().split("-"); - if(board.left() == "CX4") { - output.append(memory("ROM", size - 0xc00, "program.rom")); - output.append(memory("ROM", 0xc00, "cx4.data.rom")); - } else if(board.left() == "DSP") { - output.append(memory("ROM", size - 0x2000, "program.rom")); - output.append(memory("ROM", 0x1800, "dsp.program.rom")); - output.append(memory("ROM", 0x800, "dsp.data.rom")); + if(board.left() == "ARM") { + output.append(memory("ROM", size() - 0x28000, "program.rom")); + output.append(memory("ROM", 0x20000, {firmwareARM(), ".program.rom"})); + output.append(memory("ROM", 0x8000, {firmwareARM(), ".data.rom"})); + } else if(board.left() == "HITACHI") { + output.append(memory("ROM", size() - 0xc00, "program.rom")); + output.append(memory("ROM", 0xc00, {firmwareHITACHI(), ".data.rom"})); + } else if(board.left() == "NEC") { + output.append(memory("ROM", size() - 0x2000, "program.rom")); + output.append(memory("ROM", 0x1800, {firmwareNEC(), ".program.rom"})); + output.append(memory("ROM", 0x800, {firmwareNEC(), ".data.rom"})); + } else if(board.left() == "NECEX") { + output.append(memory("ROM", size() - 0xd000, "program.rom")); + output.append(memory("ROM", 0xc000, {firmwareNECEX(), ".program.rom"})); + output.append(memory("ROM", 0x1000, {firmwareNECEX(), ".data.rom"})); } else if(board.left() == "SGB") { - output.append(memory("ROM", size - 0x100, "program.rom")); - output.append(memory("ROM", 0x100, "sgb.boot.rom")); + output.append(memory("ROM", size() - 0x100, "program.rom")); + output.append(memory("ROM", 0x100, {firmwareSGB(), ".boot.rom"})); } else if(board.left() == "SPC7110") { output.append(memory("ROM", 0x100000, "program.rom")); - output.append(memory("ROM", size - 0x100000, "data.rom")); - } else if(board.left() == "ST010" || board.left() == "ST011") { - output.append(memory("ROM", size - 0xd000, "program.rom")); - output.append(memory("ROM", 0xc000, "st.program.rom")); - output.append(memory("ROM", 0x1000, "st.data.rom")); - } else if(board.left() == "ST018") { - output.append(memory("ROM", size - 0x28000, "program.rom")); - output.append(memory("ROM", 0x20000, "seta.program.rom")); - output.append(memory("ROM", 0x8000, "seta.data.rom")); + output.append(memory("ROM", size() - 0x100000, "data.rom")); } else { - output.append(memory("ROM", size, "program.rom")); + output.append(memory("ROM", size(), "program.rom")); } if(auto size = ramSize()) { - auto type = board.right() == "NVRAM" ? "NVRAM" : "RAM"; + auto type = battery() ? "NVRAM" : "RAM"; output.append(memory(type, size, "save.ram")); } if(auto size = expansionRamSize()) { - auto type = board.right() == "NVRAM" ? "NVRAM" : "RAM"; + auto type = battery() ? "NVRAM" : "RAM"; output.append(memory(type, size, "expansion.ram")); } - if(board.left() == "BS" && board(1) == "NVRAM") { - output.append(memory("NVRAM", 0x80000, "download.ram")); - } else if(board.left() == "CX4") { - output.append(memory("RAM", 0xc00, "cx4.data.ram")); - } else if(board.left() == "DSP") { - output.append(memory("RAM", 0x200, "dsp.data.ram")); + if(board.left() == "ARM") { + output.append(memory("NVRAM", 0x4000, {firmwareARM(), ".data.ram"})); + } else if(board.left() == "BS" && board(1) == "MCC") { + output.append(memory("PSRAM", 0x80000, "download.ram")); + } else if(board.left() == "HITACHI") { + output.append(memory("RAM", 0xc00, {firmwareHITACHI(), ".data.ram"})); + } else if(board.left() == "NEC") { + output.append(memory("RAM", 0x200, {firmwareNEC(), ".data.ram"})); + } else if(board.left() == "NECEX") { + output.append(memory("NVRAM", 0x1000, {firmwareNEC(), ".data.ram"})); } else if(board.left() == "RTC") { - output.append(memory("NVRAM", 0x10, "rtc.ram")); + output.append(memory("NVRAM", 0x10, "sharp.rtc.ram")); } else if(board.left() == "SA1") { output.append(memory("RAM", 0x800, "internal.ram")); } else if(board.left() == "SPC7110" && board(1) == "RTC") { - output.append(memory("NVRAM", 0x10, "rtc.ram")); - } else if(board.left() == "ST010" || board.left() == "ST011") { - output.append(memory("NVRAM", 0x1000, "st.save.ram")); - } else if(board.left() == "ST018") { - output.append(memory("NVRAM", 0x4000, "seta.save.ram")); - } - - if(hasMSU1) { - output.append(" msu1\n"); + output.append(memory("NVRAM", 0x10, "epson.rtc.ram")); } return output; @@ -125,10 +132,6 @@ auto SuperFamicom::memory(string type, uint size, string name) const -> string { return output; } -auto SuperFamicom::sha256() const -> string { - return Hash::SHA256(data, size).digest(); -} - auto SuperFamicom::region() const -> string { string region; @@ -240,14 +243,14 @@ auto SuperFamicom::board() const -> string { if(mapMode == 0x21 || mapMode == 0x31) mode = "HIROM-"; if(mapMode == 0x22 || mapMode == 0x32) mode = "SDD1-"; if(mapMode == 0x23 || mapMode == 0x33) mode = "SA1-"; - if(mapMode == 0x25 || mapMode == 0x35) mode = "EXHIROM-"; + if(mapMode == 0x25 || mapMode == 0x35) mode = "HIROMEX-"; if(mapMode == 0x2a || mapMode == 0x3a) mode = "SPC7110-"; //many games will store an extra title character, overwriting the map mode if(!mode) { if(headerAddress == 0x7fb0) mode = "LOROM-"; if(headerAddress == 0xffb0) mode = "HIROM-"; - if(headerAddress == 0x40ffb0) mode = "EXHIROM-"; + if(headerAddress == 0x40ffb0) mode = "HIROMEX-"; } if(serial() == "A9PJ") { @@ -255,43 +258,143 @@ auto SuperFamicom::board() const -> string { board.append("ST-", mode); } else if(serial() == "ZSBJ") { //BS-X: Sore wa Namae o Nusumareta Machi no Monogatari (JPN) - board.append("BS-"); + board.append("BS-MCC-"); + } else if(serial() == "042J") { + //Super Game Boy 2 + board.append("SGB-", mode); } else if(serial().match("Z\?\?J")) { board.append("BS-", mode); } else if(cartridgeTypeLo >= 0x3) { - if(cartridgeTypeHi == 0x0) board.append("DSP-", mode); + if(cartridgeTypeHi == 0x0) board.append("NEC-", mode); if(cartridgeTypeHi == 0x1) board.append("SUPERFX-"); if(cartridgeTypeHi == 0x2) board.append("OBC1-", mode); if(cartridgeTypeHi == 0x3) board.append("SA1-"); if(cartridgeTypeHi == 0x4) board.append("SDD1-"); if(cartridgeTypeHi == 0x5) board.append("RTC-", mode); - if(cartridgeTypeHi == 0xe && cartridgeTypeLo == 0x3) board.append("SGB-"); + if(cartridgeTypeHi == 0xe && cartridgeTypeLo == 0x3) board.append("SGB-", mode); if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x00 && cartridgeTypeLo == 0x5) board.append("SPC7110-"); if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x00 && cartridgeTypeLo == 0x9) board.append("SPC7110-RTC-"); - if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x01) board.append(romSize() == 0x100000 ? "ST010-" : "ST011-"); - if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x02) board.append("ST018-", mode); - if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x10) board.append("CX4-", mode); + if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x01) board.append("NECEX-", mode); + if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x02) board.append("ARM-", mode); + if(cartridgeTypeHi == 0xf && cartridgeSubType == 0x10) board.append("HITACHI-", mode); } if(!board) board.append(mode); - //grow ROM region and restrict RAM region for large LOROM boards ("EXLOROM") - if(board.beginsWith("LOROM-") && romSize() > 0x380000 && ramSize()) board.prepend("EX"); + if(board.beginsWith("LOROM-") && romSize() > 0x200000 && ramSize()) board.replace("LOROM-", "LOROMEX-"); + if(board.beginsWith("NEC-LOROM-") && romSize() > 0x100000) board.replace("NEC-LOROM-", "NEC-LOROMEX-"); - if(cartridgeTypeLo == 0x1 || cartridgeTypeLo == 0x4) board.append("RAM-"); - if(cartridgeTypeLo == 0x2 || cartridgeTypeLo == 0x5) board.append("NVRAM-"); - if(cartridgeTypeLo == 0x6) board.append("BATTERY-"); + if(cartridgeTypeLo == 0x1 || cartridgeTypeLo == 0x4) board.append("RAM-"); //without battery + if(cartridgeTypeLo == 0x2 || cartridgeTypeLo == 0x5) board.append("RAM-"); //with battery + if(cartridgeTypeLo == 0x6) board.append("BATTERY-"); //without RAM - return board.trimRight("-", 1L); + board.trimRight("-", 1L); + + //NEC uPD96050 frequency + if(board.beginsWith("NECEX-") && firmwareNECEX() == "st010") board.append("#11"); //11MHz (22MHz / 2) + if(board.beginsWith("NECEX-") && firmwareNECEX() == "st011") board.append("#15"); //15MHz + + return board; } auto SuperFamicom::label() const -> string { string label; - auto append = [&](char c) -> void { - if(c >= 0x20 && c <= 0x7e) label.append(c); //ASCII - //todo: convert Shift-JIS half-width katakana to UTF-8 here + + for(uint n = 0; n < 0x15; n++) { + auto x = data[headerAddress + 0x10 + n]; + auto y = n == 0x14 ? 0 : data[headerAddress + 0x11 + n]; + + //null terminator (padding) + if(x == 0x00 || x == 0xff); + + //ASCII + else if(x >= 0x20 && x <= 0x7e) label.append((char)x); + + //Shift-JIS (half-width katakana) + else if(x == 0xa1) label.append("。"); + else if(x == 0xa2) label.append("「"); + else if(x == 0xa3) label.append("」"); + else if(x == 0xa4) label.append("、"); + else if(x == 0xa5) label.append("・"); + else if(x == 0xa6) label.append("ヲ"); + else if(x == 0xa7) label.append("ァ"); + else if(x == 0xa8) label.append("ィ"); + else if(x == 0xa9) label.append("ゥ"); + else if(x == 0xaa) label.append("ェ"); + else if(x == 0xab) label.append("ォ"); + else if(x == 0xac) label.append("ャ"); + else if(x == 0xad) label.append("ュ"); + else if(x == 0xae) label.append("ョ"); + else if(x == 0xaf) label.append("ッ"); + else if(x == 0xb0) label.append("ー"); + + else if(x == 0xb1) label.append( "ア"); + else if(x == 0xb2) label.append( "イ"); + else if(x == 0xb3) label.append(y == 0xde ? "ヴ" : "ウ"); + else if(x == 0xb4) label.append( "エ"); + else if(x == 0xb5) label.append( "オ"); + + else if(x == 0xb6) label.append(y == 0xde ? "ガ" : "カ"); + else if(x == 0xb7) label.append(y == 0xde ? "ギ" : "キ"); + else if(x == 0xb8) label.append(y == 0xde ? "グ" : "ク"); + else if(x == 0xb9) label.append(y == 0xde ? "ゲ" : "ケ"); + else if(x == 0xba) label.append(y == 0xde ? "ゴ" : "コ"); + + else if(x == 0xbb) label.append(y == 0xde ? "ザ" : "サ"); + else if(x == 0xbc) label.append(y == 0xde ? "ジ" : "シ"); + else if(x == 0xbd) label.append(y == 0xde ? "ズ" : "ス"); + else if(x == 0xbe) label.append(y == 0xde ? "ゼ" : "セ"); + else if(x == 0xbf) label.append(y == 0xde ? "ゾ" : "ソ"); + + else if(x == 0xc0) label.append(y == 0xde ? "ダ" : "タ"); + else if(x == 0xc1) label.append(y == 0xde ? "ヂ" : "チ"); + else if(x == 0xc2) label.append(y == 0xde ? "ヅ" : "ツ"); + else if(x == 0xc3) label.append(y == 0xde ? "デ" : "テ"); + else if(x == 0xc4) label.append(y == 0xde ? "ド" : "ト"); + + else if(x == 0xc5) label.append("ナ"); + else if(x == 0xc6) label.append("ニ"); + else if(x == 0xc7) label.append("ヌ"); + else if(x == 0xc8) label.append("ネ"); + else if(x == 0xc9) label.append("ノ"); + + else if(x == 0xca) label.append(y == 0xdf ? "パ" : y == 0xde ? "バ" : "ハ"); + else if(x == 0xcb) label.append(y == 0xdf ? "ピ" : y == 0xde ? "ビ" : "ヒ"); + else if(x == 0xcc) label.append(y == 0xdf ? "プ" : y == 0xde ? "ブ" : "フ"); + else if(x == 0xcd) label.append(y == 0xdf ? "ペ" : y == 0xde ? "ベ" : "ヘ"); + else if(x == 0xce) label.append(y == 0xdf ? "ポ" : y == 0xde ? "ボ" : "ホ"); + + else if(x == 0xcf) label.append("マ"); + else if(x == 0xd0) label.append("ミ"); + else if(x == 0xd1) label.append("ム"); + else if(x == 0xd2) label.append("メ"); + else if(x == 0xd3) label.append("モ"); + + else if(x == 0xd4) label.append("ヤ"); + else if(x == 0xd5) label.append("ユ"); + else if(x == 0xd6) label.append("ヨ"); + + else if(x == 0xd7) label.append("ラ"); + else if(x == 0xd8) label.append("リ"); + else if(x == 0xd9) label.append("ル"); + else if(x == 0xda) label.append("レ"); + else if(x == 0xdb) label.append("ロ"); + + else if(x == 0xdc) label.append("ワ"); + else if(x == 0xdd) label.append("ン"); + + else if(x == 0xde) label.append("\xef\xbe\x9e"); //dakuten + else if(x == 0xdf) label.append("\xef\xbe\x9f"); //handakuten + + //unknown else label.append("?"); - }; - for(uint n : range(0x15)) append(data[headerAddress + 0x10 + n]); + + //(han)dakuten skip + if(y == 0xde && x == 0xb3) n++; + if(y == 0xde && x >= 0xb6 && x <= 0xc4) n++; + if(y == 0xde && x >= 0xca && x <= 0xce) n++; + if(y == 0xdf && x >= 0xca && y <= 0xce) n++; + } + return label.strip(); } @@ -311,12 +414,12 @@ auto SuperFamicom::serial() const -> string { auto SuperFamicom::romSize() const -> uint { //subtract appended firmware size, if firmware is present - if((size & 0x7fff) == 0x100) return size - 0x100; - if((size & 0x7fff) == 0xc00) return size - 0xc00; - if((size & 0x7fff) == 0x2000) return size - 0x2000; - if((size & 0xffff) == 0xd000) return size - 0xd000; - if((size & 0x3ffff) == 0x28000) return size - 0x28000; - return size; + if((size() & 0x7fff) == 0x100) return size() - 0x100; + if((size() & 0x7fff) == 0xc00) return size() - 0xc00; + if((size() & 0x7fff) == 0x2000) return size() - 0x2000; + if((size() & 0xffff) == 0xd000) return size() - 0xd000; + if((size() & 0x3ffff) == 0x28000) return size() - 0x28000; + return size(); //auto romSize = data[headerAddress + 0x27] & 15; //return 1024 << romSize; @@ -335,9 +438,14 @@ auto SuperFamicom::expansionRamSize() const -> uint { return 0; } +auto SuperFamicom::battery() const -> bool { + auto cartridgeTypeLo = data[headerAddress + 0x26] & 15; + return cartridgeTypeLo == 0x2 || cartridgeTypeLo == 0x5 || cartridgeTypeLo == 0x6; +} + auto SuperFamicom::scoreHeader(uint address) -> uint { int score = 0; - if(size < address + 0x50) return score; + if(size() < address + 0x50) return score; uint8_t mapMode = data[address + 0x25] & ~0x10; //ignore FastROM bit uint16_t complement = data[address + 0x2c] << 0 | data[address + 0x2d] << 8; @@ -395,4 +503,34 @@ auto SuperFamicom::scoreHeader(uint address) -> uint { return max(0, score); } +auto SuperFamicom::firmwareARM() const -> string { + return "st018"; +} + +auto SuperFamicom::firmwareHITACHI() const -> string { + return "cx4"; +} + +auto SuperFamicom::firmwareNEC() const -> string { + if(label() == "PILOTWINGS") return "dsp1"; + if(label() == "DUNGEON MASTER") return "dsp2"; + if(label() == "SDガンダムGX") return "dsp3"; + if(label() == "PLANETS CHAMP TG3000") return "dsp4"; + if(label() == "TOP GEAR 3000") return "dsp4"; + return "dsp1b"; +} + +auto SuperFamicom::firmwareNECEX() const -> string { + if(label() == "EXHAUST HEAT2") return "st010"; + if(label() == "F1 ROC II") return "st010"; + if(label() == "2DAN MORITA SHOUGI") return "st011"; + return "st010"; +} + +auto SuperFamicom::firmwareSGB() const -> string { + if(label() == "Super GAMEBOY") return "sgb1"; + if(label() == "Super GAMEBOY2") return "sgb2"; + return "sgb1"; +} + } diff --git a/icarus/icarus.cpp b/icarus/icarus.cpp index c4208971..f8075763 100644 --- a/icarus/icarus.cpp +++ b/icarus/icarus.cpp @@ -8,9 +8,6 @@ auto locate(string name) -> string { string location = {Path::program(), name}; if(inode::exists(location)) return location; - location = {Path::config(), "icarus/", name}; - if(inode::exists(location)) return location; - directory::create({Path::local(), "icarus/"}); return {Path::local(), "icarus/", name}; }