From 1952a6f9391c5a86ea97fc555186dd9e75d99020 Mon Sep 17 00:00:00 2001 From: "Benjamin C. Wiley Sittler" Date: Sat, 25 Feb 2023 14:40:45 -0500 Subject: [PATCH] - MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 159989c1dbc422f3bbd64f8769e0229df354d1e9 Author: Benjamin C. Wiley Sittler Date: Sun May 14 17:41:13 2023 -0700 Add mapper `#48` MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF for "GG 48 in 1 [Doraemon 2] (Unl)" I've been calling it "GG 48 in 1 [Doraemon 2] (Unl)" but the actual name is not entirely clear The only apparent actual name is: 48 in 1 [label background] G.G. 48 IN 1 [menu title] I have this as a loose Game Gear cartridge only. The label has only a truncated game list in English and Traditional Chinese (items 24 and 48 are mostly cut off at the bottom) and item 1. is "DORAEMON 3". The first item in the menu system is "DORAEMON 2". Partial transcription of English label text: ``` 1.DORAEMON 3 2.TAILS ADVELTUR 3.ROCKMAN 2 4.SLAM DUNK 2 5.YAIBA 2 6.ZONKI 2 7.BUBBLE BOBBLE 8.PHANTASY STAR 9.SPACE HARRIER 10.HELLAY WARS 11 .TAN PIN 12.BATTLE SHIP 13.PAC MAN 14.WOODY POP 15.PENGO 16.COLUMNS 17.DORAEMN 18.TALIS 3 19.ROCKMAN 20.SLAM DUNK 21 .YAIBA 22.ZONKI 23.BUBBLE POP 24.PHANTASY [inferred] 25.SPACE MAN 26.HELLAY 27.DOUGE BALL 28.ATTACK SHIP 29.PRO PACMAN 30.ALLEY WAY 31 .PENGO LAND 32.TETRIS 33.DIG DUG 34.SONIC 35.MEGAMAN 36.SLAM BALL 37.PRO YAIBA 38.ZONKI BOY 39.BOBBLE DROGAN 40.STR DRAGM 41 HAPPIER 42.SPACE WARSAN 43.SOCCER 44.STAR SHIP 45.SUPER PACMAN 46.GHOST LAND 47.ICE PENGO 48.KALX [inferred] ``` Incomplete transcription of Traditional Chinese label text: (errors are mine) ``` 1. 小叮噹 3 2. 音速小子外得 2 3. 洛克人 2 4. 灌籃高手 2 5. 劍勇傳說 2 6. 鬼神童子 2 7. 泡泡龍 8. 夢幻之星 2 9. 火龍 10. 哈雷大戰 11. 彈平 12. 潛水大戰 13. 小精靈 14. 打磚王 15. 企鵝 16. 魔王寶石 17. 小叮噹 18. 音速小子3 19. 洛克人世界 20. 灌籃高手 21. 劍勇傳說 22. 鬼話童子 23. 泡泡鬼 24. ???? [unreadable] 25. 銀??士 26. 哈雷慧星 27. 炎之門球 28. 海戰 29. ??? 30. 彈?合 31. 夢大陸 32. 夢幻寶石 33. 小叮噹歷險 34. 音速小子 35. 米茄超人 36. 暴力籃球 37. ???? 38. ????? 39. 幻想空間 40. ???? 41. ??戰記 42. ???? 43. 熱血?避? 44. 星艦巡航 45. ???? 46. 樂樂? 47. 冰上企鵝 48. [unreadable] ``` NOTE: Some of the Traditional Chinese character choices, for instance 小叮噹 (i.e. "little Ding-Dong") for Doraemon and 劍勇傳說 (i.e. "sword legend") for YAIBA, suggest a Taiwanese origin. This is a 4MB ROM containing a menu system and 16 distinct Game Gear games, including six 512KB games, one 256KB game, four 128KB games, two 64KB games, and three 32KB games. Game list: Doraemon Waku Waku Pocket Paradise, Tails Adventures, Mega Man, Slam Dunk - Shouri-e no Starting 5 (From TV animation), Kenyuu Densetsu Yaiba, Kishin Douji Zenki, Bubble Bobble, Phantasy Star Adventure, Space Harrier, Halley Wars, Honoo no Toukyuuji Dodge Danpei, Battleship - The classic naval combat game, Pac-Man, Woody Pop, Pengo, Columns In addition to the reachable games this multicart has an apparently functional version of SG-1000 Exerion in the same 32KB page as the menu, but it is not reachable from the menu and would require SMS-GG mode. There are also remnants of an earlier "G.G. 20 IN 1" menu system which had as its first item "YUU YUU 2". Dumping script: ``` // G.G. 48 in 1 [Doraemon 2] multicart // Dump in half-megabyte sections, disconnecting and reconnecting in between local half_megabyte = (use_gg48in1 - 1); local bias = half_megabyte * 512 * 1024; local ram_addr = 0xC000; // used to assert writes for longer for (local i = bias; (i - bias) < max_dump_size; i += 512 * 1024) { local gg48in1_base = i / 0x4000; cpu_write(d, ram_addr, 0x10); cpu_write(d, 0xFFF8, 0x10); cpu_write(d, ram_addr, 0x10); cpu_write(d, ram_addr, 0x1F); cpu_write(d, 0xFFF9, 0x1F); cpu_write(d, ram_addr, 0x1F); cpu_write(d, ram_addr, gg48in1_base & 0x1F); cpu_write(d, 0xFFF9, gg48in1_base & 0x1F); cpu_write(d, ram_addr, gg48in1_base & 0x1F); cpu_write(d, ram_addr, 0x18 | (gg48in1_base >> 5)); cpu_write(d, 0xFFF9, 0x18 | (gg48in1_base >> 5)); cpu_write(d, ram_addr, 0x18 | (gg48in1_base >> 5)); cpu_write(d, ram_addr, 0x00); cpu_write(d, 0xFFF8, 0x00); cpu_write(d, ram_addr, 0x00); cpu_write(d, ram_addr, 0x01); cpu_write(d, 0xFFFE, 0x01); cpu_write(d, ram_addr, 0x01); for (local j = 0; j < (512 * 1024); j += 0x4000) { local sega_page = j / (16 * 1024); cpu_write(d, ram_addr, sega_page); cpu_write(d, 0xFFFF, sega_page); cpu_write(d, ram_addr, sega_page); cpu_write(d, ram_addr, 0xFF); cpu_read(d, 0x8000, 0x4000); } } ``` The menu writes 0xFFFE=0x01 on startup. The "→" cursor is movable, and is shown below in its initial position on each screen of the menu. Menu screen 1: ``` G.G. 48 IN 1 PUSH ↑.↓.START →01.DORAEMON 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1F, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg 02.TAILS ADVENTUR [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1E, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-60-Tails Adventures (JP,US,EU)-512k.gg 03.ROCKMAN 4 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1D, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-50-Mega Man (US)-512k.gg 04.SLAM DUNK 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1C, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg 05.YAIBA 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1B, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg 06.ZONKI 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1A, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-20-Kishin Douji Zenki (JP)-512k.gg 07.BUBBLE BOBBLE [0xFFF8=0x10, 0xFFF9=0x0F, 0xFFF9=0x10, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-18-Bubble Bobble (US)-256k.gg 08.PHANTASY STAR [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x08, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-14-Phantasy Star Adventure (JP)-128k.gg 09.SPACE HARRIER [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x00, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-10-Space Harrier (JP,US,EU)-128k.gg 10.HELLAY WARS [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x18, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-0c-Halley Wars (JP)-128k.gg 11.TAN PIN [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x10, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 12.BATTLE SHIP [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x0C, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-06-Battleship - The classic naval combat game (US)-64k.gg ``` Menu screen 2: ``` G.G. 48 IN 1 PUSH ↑.↓.START →13.PAC MAN [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x08, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-04-pac-man-64k.gg 14.WOODY POP [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x02, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-01-woody-pop-32k.gg 15.PENGO [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x04, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-02-pengo-32k.gg 16.COLUMNS [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x06, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-03-Columns [v0] (JP)-32k.gg 17.DORAEMON [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1F, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg 18.TALIS 3 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1E, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-60-Tails Adventures (JP,US,EU)-512k.gg 19.ROCKMAN [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1D, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-50-Mega Man (US)-512k.gg 20.SLAM DUNK [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1C, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg 21.YAIBA [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1B, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg 22.ZONKI [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1A, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-20-Kishin Douji Zenki (JP)-512k.gg 23.BUBBLE POP [0xFFF8=0x10, 0xFFF9=0x0F, 0xFFF9=0x10, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-18-Bubble Bobble (US)-256k.gg 24.PHANTASY [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x08, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-14-Phantasy Star Adventure (JP)-128k.gg ``` Menu screen 3: ``` G.G. 48 IN 1 PUSH ↑.↓.START →25.SPACE MAN [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x00, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-10-Space Harrier (JP,US,EU)-128k.gg 26.HELLAY [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x18, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-0c-Halley Wars (JP)-128k.gg 27.DOUGE BALL [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x10, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 28.ATTACK SHIP [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x0C, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-06-Battleship - The classic naval combat game (US)-64k.gg 29.PRO PACMAN [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x08, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-04-pac-man-64k.gg 30.ALLEY WAY [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x02, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-01-woody-pop-32k.gg 31.PENGOLAND [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x04, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-02-pengo-32k.gg 32.TETRIS [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x06, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-03-Columns [v0] (JP)-32k.gg 33.DIG DUG 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0X1F, 0xFFF8=0x00, 0xFFFE=0x01] 34.SONIC 4 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1E, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-60-Tails Adventures (JP,US,EU)-512k.gg 35.MEGAMAN 2 [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1D, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-50-Mega Man (US)-512k.gg 36.SLAM BALL [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1C, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg ``` Menu screen 4: ``` G.G. 48 IN 1 PUSH ↑.↓.START →37.PRO YAIBA [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1B, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg 38.ZONKI BOY [0xFFF8=0x10, 0xFFF9=0x1F, 0xFFF9=0x00, 0xFFF9=0x1A, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-20-Kishin Douji Zenki (JP)-512k.gg 49.BOBBLE DROGAN [0xFFF8=0x10, 0xFFF9=0x0F, 0xFFF9=0x10, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-18-Bubble Bobble (US)-256k.gg 40.STR DRAGM [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x08, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-14-Phantasy Star Adventure (JP)-128k.gg 41.HARRIER [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x00, 0xFFF9=0x19, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-10-Space Harrier (JP,US,EU)-128k.gg 42.SPACE WARSAN [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x18, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-0c-Halley Wars (JP)-128k.gg 43.SOCCER [0xFFF8=0x10, 0xFFF9=0x07, 0xFFF9=0x10, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 44.STAR SHIP [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x0C, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-06-Battleship - The classic naval combat game (US)-64k.gg 45.SUPER PACMAN [0xFFF8=0x10, 0xFFF9=0x03, 0xFFF9=0x08, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-04-pac-man-64k.gg 46.GHOST LAND [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x02, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-01-woody-pop-32k.gg 47.ICE PENGO [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x04, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-02-pengo-32k.gg 48.KALX [0xFFF8=0x10, 0xFFF9=0x01, 0xFFF9=0x06, 0xFFF9=0x18, 0xFFF8=0x00, 0xFFFE=0x01]; it's part-03-Columns [v0] (JP)-32k.gg ``` Initially the Sega mapper registers can access the first 512KB of the ROM. Activating a menu entry writes the following mapper sequence: 1. 0xFFF8=0x10; this seems to unlock the multicart mapper 2. 0xFFF9=MASK; this sets the paging mask for subsequent writes to the Sega mapper registers 3. 0xFFF9=LOWER; this write sets the lower 5 bits of the 16KB starting page 4. 0xFFF9=0x18 | UPPER; the low three bits of this write sets the upper 5 bits of the 16KB starting page 5. 0xFFF8=0x00; this seems to re-lock the multicart mapper 6. 0xFFFE=0x01; this seems to be normal Sega paging ROM fingerprint info: 4.0M GG 48 in 1 [Doraemon 2] (Unl).gg Checking for export header with matching CRC... NO sha256:6ec136a591cc27bbb016861906e3be37732383a487c94ea2f2c11dfd6a6405f2 GG 48 in 1 [Doraemon 2] (Unl).gg sha1:57a4c584446724dd63067789a59c2d4eafcef8da GG 48 in 1 [Doraemon 2] (Unl).gg md5:51aa953901b3113714954f511a72025b GG 48 in 1 [Doraemon 2] (Unl).gg mekacrc:F07FEFF54F0A7CD8 GG 48 in 1 [Doraemon 2] (Unl).gg crc32:3394aaea GG 48 in 1 [Doraemon 2] (Unl).gg 32K GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg Checking for export header with matching CRC... NO sha256:de4ecac13d0a02d123e791c11954a6358c912d5ce51ee51b36d2e9cfb8381026 GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg sha1:b1d2d4f7a14fdb4d7be643f5726528c7a10ddf39 GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg md5:4bb5680ee1dd4f5bb4c48c0ff8ce6c5e GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg mekacrc:44D021095DE38DF5 GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg crc32:ac03b313 GG 48 in 1 [Doraemon 2] (Unl)/part-00-menu-and-exerion-32k.gg 32K GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg Checking for export header with matching CRC... NO sha256:cf22231c68b26a1e42d482b474d25023e72c1345f173f675fa0cae2364e5f9d6 GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg sha1:3ed18e1ad8ef7ef629549c730c883d95885a343e GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg md5:31a9fd292903d731a6f74364ab4e11fa GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg mekacrc:83304DDFE016002B GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg crc32:c2e287d1 GG 48 in 1 [Doraemon 2] (Unl)/part-01-woody-pop-32k.gg 32K GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg Checking for export header with matching CRC... NO sha256:f908b5a151141ca7d871a67d2566aec6bd84eede2def2e1086aaa5a678e72dfd GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg sha1:a11c382a036ff295a2034cb405d12b91087ac258 GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg md5:35896d40c71a9b7669db87f1a891b400 GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg mekacrc:66437B3670F4DC66 GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg crc32:44b8267f GG 48 in 1 [Doraemon 2] (Unl)/part-02-pengo-32k.gg 32K GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg Checking for export header with matching CRC... NO sha256:d57014795c01ad9f051ee7b470a9993f7b0e3a2772f128bb79afa66bcfc1879e GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg sha1:8b39ba23132af102b8dc313c5c1c211f4a4f27e1 GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg md5:680682aaa9b7eae0642e4b9c4ef80f59 GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg mekacrc:10E74B085532032C GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg crc32:f3ca6676 GG 48 in 1 [Doraemon 2] (Unl)/part-03-Columns [v0] (JP)-32k.gg 64K GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg Checking for export header with matching CRC... NO sha256:062ae6710d6ed59ab1d684027b870b70d6fad3f904148c21bfc99ab6d2f50733 GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg sha1:2a994d5d8c54ffd72218f4dedaebe74f06bfa157 GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg md5:f5212e5249cf7c1ceb076cfcd7e67fe7 GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg mekacrc:3E0814A4FB499C22 GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg crc32:4d9840b6 GG 48 in 1 [Doraemon 2] (Unl)/part-04-pac-man-64k.gg 64K GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg Checking for export header with matching CRC... NO sha256:ebb25e0a26fea259b05811a684df47e4832758f14f5436bee0f801b6a086cf79 GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg sha1:eae1ebec2c1be522924f669a2dc884f9f4a68cf3 GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg md5:ba836ae19e88f6354d746a86582beff8 GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg mekacrc:82E53FF69611EBD2 GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg crc32:fddd8cd9 GG 48 in 1 [Doraemon 2] (Unl)/part-06-Battleship - The classic naval combat game (US)-64k.gg 128K GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg Checking for export header with matching CRC... NO sha256:ac7b81ec5cdc7dd6ed1cfd8f1690fdd9461493827535f3744ddc1c95e834ba30 GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg sha1:66032cc214d728b2f1c59ad2934277e378b36865 GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg md5:a299b81a9a5455bfff538f669a5e7a0d GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg mekacrc:357F4A30EE2C9A1E GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg crc32:dfa805a0 GG 48 in 1 [Doraemon 2] (Unl)/part-08-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 128K GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg Checking for export header with matching CRC... NO sha256:af245727b846b3d13f9f6c4ba6977537408925074a17c44456448779f0953607 GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg sha1:1c9932f592bb12e61acf597985e0bd5041e45da5 GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg md5:9b26a17f41f2f0dc508d0815945e2634 GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg mekacrc:1F25824E7BFAA5D2 GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg crc32:def5a5d0 GG 48 in 1 [Doraemon 2] (Unl)/part-0c-Halley Wars (JP)-128k.gg 128K GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg Checking for export header with matching CRC... NO sha256:0e62d1ffbf6b8397c88da14a7934f214b8146b801e4fc5e6fa94895eb44465be GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg sha1:d00b8ff195d4423f2a344490eb34156017f4ee64 GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg md5:cd3809b8d6d32144c45de8e102623aa0 GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg mekacrc:308DC2BE252AC7AD GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg crc32:600c15b3 GG 48 in 1 [Doraemon 2] (Unl)/part-10-Space Harrier (JP,US,EU)-128k.gg 128K GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg Checking for export header with matching CRC... NO sha256:59b93c908fa2d40ce624fa727029ec313f3d550eca30fa583cf7859432da5b2a GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg sha1:fdd940556f7d3af14979dbf057809d5a22e46d8e GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg md5:8fad420b7dc93cd7ed10bfc54ec04f07 GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg mekacrc:CEE87887BE4C5BE6 GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg crc32:1a51579d GG 48 in 1 [Doraemon 2] (Unl)/part-14-Phantasy Star Adventure (JP)-128k.gg 256K GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg Checking for export header with matching CRC... NO sha256:faebc43b4219c14f34cbbd585f567e4b0e506fb43f2632117c2657e31741c77f GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg sha1:c2c99d798bd0d4960021743a55e74644ad9020c6 GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg md5:4f08cab3e252c2e3979ef33e9e59f294 GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg mekacrc:D558C670ED32D2AC GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg crc32:fba338c5 GG 48 in 1 [Doraemon 2] (Unl)/part-18-Bubble Bobble (US)-256k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg Checking for export header with matching CRC... NO sha256:abf85ee0730a3d54f1f5446c834a694b69c614d9eb59b7f132e5a4c62aa31f80 GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg sha1:0fb3530633070551f3d5a04839fc42babc092fbd GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg md5:ac6ed281ac8e9d71af186602951cfd7a GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg mekacrc:73CDFBB9A17B628E GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg crc32:7d622bdd GG 48 in 1 [Doraemon 2] (Unl)/part-20-Kishin Douji Zenki (JP)-512k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg Checking for export header with matching CRC... NO sha256:dd1fc9c31e2270a296c3ea07067c832a232af1d6544284031d35d6b005bdcf40 GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg sha1:21b08c5c4b086e169d5f780cafc22c041e19807b GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg md5:d8cb893b1cf1ae9555ad9b7eaad469e0 GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg mekacrc:896982D01506AFF2 GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg crc32:d9ce3f4c GG 48 in 1 [Doraemon 2] (Unl)/part-30-Kenyuu Densetsu Yaiba (JP)-512k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg Checking for export header with matching CRC... NO sha256:aa466c1de24009a0c843d588d88a6e6df7d3260bee8b9eb156355aef369cd592 GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg sha1:bee62a373655d0ef931d8b9a4ed88fb0f4d1a8bc GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg md5:087039a3c04f4a3ae2f09bc258be00d1 GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg mekacrc:B0541293B90BC5CE GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg crc32:751dad4c GG 48 in 1 [Doraemon 2] (Unl)/part-40-Slam Dunk - Shouri-e no Starting 5 (From TV animation) (JP)-512k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg Checking for export header with matching CRC... NO sha256:b313e90469133da5d0d39f683cc098993c3b137458804dd0aafb173eb39cd98a GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg sha1:085517c4ac940b937d0e0a900e4735a2247ca4dd GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg md5:8583950be61ffbaf0f63dde8dded2ab3 GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg mekacrc:F0B8660AB1883B74 GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg crc32:1ace93af GG 48 in 1 [Doraemon 2] (Unl)/part-50-Mega Man (US)-512k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg Checking for export header with matching CRC... NO sha256:92a9985333df0ee46e9a44b97bda37c565de831bbcbc9b740cd43637b0f5072a GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg sha1:da3df145b8e9f2a2e680d2c92939084d4530ed90 GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg md5:a8bdb1beed088ff83c725c5af6b85e1f GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg mekacrc:134A286D9BE1D8BA GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg crc32:5bb6e5d6 GG 48 in 1 [Doraemon 2] (Unl)/part-60-Tails Adventures (JP,US,EU)-512k.gg 512K GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg Checking for export header with matching CRC... NO sha256:62e53420623ca2bb2aceb798b872bcf0e344b7ce3dc66bd0fec01afcb620a4ce GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg sha1:495816dbd49560cf02e841b53bd996456078c36b GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg md5:5dae999e98312e4cb5962041ddea351f GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg mekacrc:1D6B7F6FC8CE6D87 GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg crc32:733292a6 GG 48 in 1 [Doraemon 2] (Unl)/part-70-Doraemon Waku Waku Pocket Paradise (JP)-512k.gg Squashed commit of the following: commit b2f66ed6865b6b6fff50c2a20d425af65c2dfe26 Author: Benjamin C. Wiley Sittler Date: Sun May 14 18:44:42 2023 -0700 Add mapper `#49` MAPPER_GG_18_in_1_00xx for "18 in 1 - Super Games Collection [Columns] (Unl)" I've been calling this "18 in 1 - Super Games Collection [Columns] (Unl)" but the actual name is unclear The label is titled "Super Games Collection" The menu is titled "18 IN 1" The first entry in the first menu screen is "COLUMNS" This is a 512KB Game Gear multicart containing a mix of 32KB Game Gear games and 32KB SMS games and a menu system with 18 entries and 15 distinct games; they are GG: Columns, Pengo, Woody Pop, SMS: Great Baseball, Astro Flash, Seishun Scandal, Spy vs. Spy, Pit Pot, Teddy Boy, Ghost House, Satellite-7, Hang-On, Great Soccer, Super Tennis, Machine Gun Joe The label has a game list with both Traditional Chinese and English names for each menu item. Spelling is notably awful for the English part. The menu system spelling is quite a bit better though English-only Label text: (transcription or translation errors mine) 𝒮𝓊𝓅ℯ𝓇 𝒢𝒶𝓂ℯ𝓈 𝒞ℴ𝓁𝓁ℯ𝒸𝓉𝒾ℴ𝓃 ⒈ 寶石方塊COLUMS (i.e. "gem cube") ⒉ 企鵝推冰PENGO (i.e. "penguin pushing ice") ⒊ 玩具撞磚WOODY POP (i.e. "toy brick") ⒋ 棒球BASE BALL (i.e. "baseball") ⒌ 空中戰機AS TRO FLASE (i.e. "aerial fighter") ⒍ 青春英雄MY HERO (i.e. "youth fighter") ⒎ 諜對諜SPY V.S. SPY (i.e. "spy vs. spy") ⒏ 陷阱遊戲PIT POT (i.e. "trap game") ⒐ 泰迪男孩( 頗皮童)TEDDY BOY (i.e. "teddy boy (puppy boy)") ⒑ 鬼屋GHOST HOUSE (i.e. "haunted house") ⒒ 雷鳥STAELLILE (i.e. "thunder bird") ⒓ 越野機車HANG NO (i.e. "off-road bike") ⒔ 足球SOCCER (i.e. "football"/"soccer") ⒕ 網球TENNIS (i.e. "tennis") ⒖ 機槍大戰MACHING GUN (i.e. "machine gun battle") ⒗ 20雙撞磚王ARKANOID (perhaps "20 double brick king"?) ⒘ 超級企鵝EASY PENGO (i.e. "super penguin") ⒙ 恐怖鬼屋GHOST HOUSE (i.e. "terrifying haunted house") NOTE: The menu uses a movable harpoon cursor "⇀" to mark the current selection. Its initial position is shown in each screen below. Contents of the first menu screen: ``` 18 IN 1 PUSH ↑.↓.1.2.START 01.COLUMNS [0x0002=0x00]; it's part-02-columns-32k.gg 02.PENGO [0x0001=0x05]; it's part-01-pengo-32k.gg 03.WOODY POP [0x0003=0x03]; it's part-03-woody-pop-32k.gg 04.BASE BALL [0x001E=0x00]; it's part-0e-Great Baseball [JP] (JP)-32k.sms ⇀05.ASTRO FLASH [0x0014=0x05]; it's part-04-astro-flash-32k.sms 06.MY HERO [0x0015=0x00]; it's part-05-Seishun Scandal (JP)-32k.sms 07.SPY VS SPY [0x0016=0x00]; it's part-06-Spy vs Spy (JP,KR)-32k.sms 08.PIT POT [0x001F=0x00]; it's part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms 09.TEDDY BOY [0x0018=0x00]; it's part-08-Teddy Boy Blues (JP)-32k.sms 10.GHOST HOUSE [0x0019=0x02]; it's part-09-ghost-house-32k.sms ``` Contents of the second menu screen: ``` 18 IN 1 PUSH ↑.↓.1.2.START 11.STAELLITE 7 [0x001A=0x00]; it's part-0a-Satellite 7 (JP)-32k.sms 12.HANG ON [0x001B=0x00]; it's part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms 13.SOCCER [0x001C=0x00]; it's part-0c-Great Soccer (JP)-32k.sms ⇀14.TENNIS [0x001D=0x00]; it's part-0d-Super Tennis (US,EU,DE)-32k.sms 15.MACHINE GUN [0x0017=0x00]; it's part-07-Comical Machine Gun Joe (JP)-32k.sms 16.ARKANOID [0x0003=0x14]; it's part-03-woody-pop-32k.gg 17.EASY PENGO [0x0001=0x14]; it's part-01-pengo-32k.gg 18.GHOST [0x0019=0x14]; it's part-09-ghost-house-32k.sms ``` The mapper seems to work by writing a byte to one of the low 32 addresses (0x0001...0x001F), with the 0x0010 bit specifying SMS-GG mode and the low 4 bits selecting the game. Games that have multiple trainings write different byte values for each training, and Astro Flash writes 0x05. Some games have been modified to interact with RAM-based trainer code and/or to obscure original authorship. The entire multicart is readable in one go using a very simple dumping script: ``` // 18 in 1 - Super Games Collection [Columns] for (local page = 0; (page * 0x8000) < rom_size; page += 1) { cpu_write(d, page & 0x0F, page >> 4); cpu_read (d, 0, 0x8000); } ``` The mapper appears to be build using just a few NAND gates and some D flip-flops. ROM fingerprint info: 512K 18 in 1 - Super Games Collection [Columns] (Unl).gg Checking for export header with matching CRC... NO sha256:b46635b8c87199f8e3f05008ea39eaac00009737947822e946c29cc9cc032f7e 18 in 1 - Super Games Collection [Columns] (Unl).gg sha1:2af084c8d60c31c66134aa940d0dd7362b89fbd2 18 in 1 - Super Games Collection [Columns] (Unl).gg md5:c9f96b821074d186c15dfbad04b0dedd 18 in 1 - Super Games Collection [Columns] (Unl).gg mekacrc:6AAE6866CB4814F3 18 in 1 - Super Games Collection [Columns] (Unl).gg crc32:81818f55 18 in 1 - Super Games Collection [Columns] (Unl).gg 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg Checking for export header with matching CRC... NO sha256:e64cc5c5308d94bc292878a49ac0d47d67b704a006ccd27b9db3c662c89af88b 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg sha1:5e7059001651a09e9350be9461dfb98cc415dc1b 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg md5:b8fd7243db3507a79f55207795536309 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg mekacrc:458A4C66FE7CAA5B 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg crc32:2e46d85d 18 in 1 - Super Games Collection [Columns] (Unl)/part-00-menu-and-pengo-remnants-32k.gg 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg Checking for export header with matching CRC... NO sha256:fb19e89fafeba20a1fd976465f28d7f0623e321239be9b96b4cd72ddd7d954b4 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg sha1:b48bd6bec0cdde7b1f6cb10364e027a0e3a03a55 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg md5:630e6ca44a8933c508691baaa5d2769c 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg mekacrc:7C42713471EBDD64 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg crc32:cc13c408 18 in 1 - Super Games Collection [Columns] (Unl)/part-01-pengo-32k.gg 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg Checking for export header with matching CRC... NO sha256:dccfe80f1ca1f10ad68c5b930c12623394cdd8f712fdaf9706c374ab938aa38a 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg sha1:52493c55c2b3815d960886a70a416df685823307 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg md5:f8c12df1869aa3e4c363b9d7dc308790 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg mekacrc:29E34504572F0322 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg crc32:5a1e2db6 18 in 1 - Super Games Collection [Columns] (Unl)/part-02-columns-32k.gg 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg Checking for export header with matching CRC... NO sha256:bf73da437483edfc250ca6174258edf73118eca624fba2a1b910d9e275935db7 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg sha1:00752ac2ad89e4006cc2a1a3f18336d786d66b0e 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg md5:3dfa83da24646abcc0794f8053412a30 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg mekacrc:932C48DEDF130029 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg crc32:b16eab57 18 in 1 - Super Games Collection [Columns] (Unl)/part-03-woody-pop-32k.gg 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms Checking for export header with matching CRC... NO sha256:bf22972cc6e88a0eb3a6f2e483fa769ba4a5573edfe421dbfa75a6697053bef7 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms sha1:94a0c358ef4e4c13ae2dc03558a0d5f46a28efd9 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms md5:9d9aac5b483d3e750ba120959aaaac20 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms mekacrc:2D22172DD72A88E4 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms crc32:ea5692a8 18 in 1 - Super Games Collection [Columns] (Unl)/part-04-astro-flash-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms Checking for export header with matching CRC... NO sha256:5c86b5f3531518e20bb875a05e26430aa3fbd3d162164da807826eb4bc4b262c 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms sha1:6942f38e608cc7d70cf9cc8c13ee8c22e4b81679 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms md5:fb2ad2524646bd069e3ec1b51fd7eb39 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms mekacrc:A2297AFAC9472988 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms crc32:f0ba2bc6 18 in 1 - Super Games Collection [Columns] (Unl)/part-05-Seishun Scandal (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms Checking for export header with matching CRC... NO sha256:e3df51893d16e512cadf3723a58f143dc679127fbe4444662be63fafb4b2a777 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms sha1:c5e004b34d6569e6e1d99bff6be940f308e2c39f 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms md5:2a6ee78e2617886fe540dcb8a1500e90 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms mekacrc:440AA3B0518BF192 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms crc32:d41b9a08 18 in 1 - Super Games Collection [Columns] (Unl)/part-06-Spy vs Spy (JP,KR)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms Checking for export header with matching CRC... NO sha256:ea9c74555e551974a681296c41972c1f6ddd7289fed5502f64e35b8527b6dde4 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms sha1:33c21d164fd3cdf7aa9e7e0fe1a3ae5a491bd9f5 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms md5:2d59b3d27f022b04a597e767e6660ca9 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms mekacrc:59868AC9BD4815B4 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms crc32:9d549e08 18 in 1 - Super Games Collection [Columns] (Unl)/part-07-Comical Machine Gun Joe (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms Checking for export header with matching CRC... NO sha256:42de9fc6028da76b4991ba81b3a666c9ae303e269d8f55c715f6518dcadb8773 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms sha1:fb61c04f30c83733fdbf503b16e17aa8086932df 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms md5:de5d6c9e1349844b74f53caaf2af680b 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms mekacrc:BBE8D843FF8FF6BE 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms crc32:316727dd 18 in 1 - Super Games Collection [Columns] (Unl)/part-08-Teddy Boy Blues (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms Checking for export header with matching CRC... NO sha256:5c31df49065f505b5390019b5bb75f1e3fb7ac5f1799cb69d1081ddc1ce082ea 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms sha1:654468a74a1c633ceecfb83e07a88ddf1b53a57b 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms md5:bc9281e171d910e9ac3dadc65eb3c8ce 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms mekacrc:777E31E6ED69940A 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms crc32:8f0284e3 18 in 1 - Super Games Collection [Columns] (Unl)/part-09-ghost-house-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms Checking for export header with matching CRC... NO sha256:3e659f15fbcc6511dfeb2112762074a8441479bb33887d196eb343e124d14fe5 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms sha1:88fc5596773ea31eda8ae5a8baf6f0ce5c3f7e5e 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms md5:eac6a843975c50e39eb32f764da2a5ac 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms mekacrc:ABFBCE1810529280 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms crc32:16249e19 18 in 1 - Super Games Collection [Columns] (Unl)/part-0a-Satellite 7 (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms Checking for export header with matching CRC... YES sha256:0d35d0e232d64e714fa5d07e45acaf01ea9fb5a8f88fe9ac8018719ac2818d6f 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms sha1:e601257f6477b85eb0b25a5b6d46ebc070d8a05a 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms md5:2864be0d35269c5030a7f297f70e3ac3 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms mekacrc:F0A23277115075EF 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms crc32:071b045e 18 in 1 - Super Games Collection [Columns] (Unl)/part-0b-Hang On (EU,AU,BR,DE,IT)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms Checking for export header with matching CRC... NO sha256:b2a524164e1a0a264dc4ac7cb29742293b3384b9369e0ce0cf2ab5ca2b50a1cd 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms sha1:110536303b7bccc193bef4437ba5a9eb6fd4ac8e 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms md5:0ed883302e87ca46c1c1a55660e17900 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms mekacrc:68A3CEF02BC61B2B 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms crc32:2d7fd7ef 18 in 1 - Super Games Collection [Columns] (Unl)/part-0c-Great Soccer (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms Checking for export header with matching CRC... YES sha256:5fb097b508a482c29f12c2203a0a98a0dd7ce9873e7ef12fb7e0aeea250a99e2 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms sha1:67787f3f29a5b5e74b5f6a636428da4517a0f992 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms md5:2db9404fe79593fd2379921ca822103a 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms mekacrc:F799F9C458560EF7 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms crc32:914514e3 18 in 1 - Super Games Collection [Columns] (Unl)/part-0d-Super Tennis (US,EU,DE)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms Checking for export header with matching CRC... NO sha256:84a62928d7a231657db0a5d77efa77eebda9f5cbefb5d5a68af64af2ecdb88fd 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms sha1:e6eaaec61bec32dee5161ae59a7a0902f0d05dc9 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms md5:94ca79d4eb2709ad98b850d33728a045 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms mekacrc:9F82F97234F38CC1 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms crc32:89e98a7c 18 in 1 - Super Games Collection [Columns] (Unl)/part-0e-Great Baseball [JP] (JP)-32k.sms 32K 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms Checking for export header with matching CRC... NO sha256:be7c284c39c1e18e53f7a97d3950caf93550783cdddcdf9324f9b209353682b9 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms sha1:b1afa682b2f70bfc4ab2020d7c3047aabbaf9a24 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms md5:209ee37dcabc263aa462c781d3123fce 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms mekacrc:B637976CB4B28D1D 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms crc32:e6795c53 18 in 1 - Super Games Collection [Columns] (Unl)/part-0f-Fushigi no Oshiro Pit Pot (JP,KR)-32k.sms Squashed commit of the following: commit 28526d60b9b8939f80d6768089254bee1825cfbc Author: Benjamin C. Wiley Sittler Date: Sun May 14 15:08:55 2023 -0700 Add mapper `#47` MAPPER_SMS_Power_256KB_FFFF_FFFE for power-cycling multicarts of 256KB SMS games (Super 2 in 1 - Sonic & Alien Storm [SMS-GG], Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG], Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG]) As Meka does not yet expose keyboard shortcuts for power-cycling, nor mapper hooks for responding to it, the mapper is currently implemented in terms of reset instead of power-cycle. As the Game Gear did not have a reset button, this does not end up actually breaking any functionality Scroll down for descriptions of each multicart --- I've been calling this menu-less SMS-GG multicart "Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)" but the actual name is not known The cartridge label lists the contents in English and Traditional Chinese: SONIC 超音鼠 (i.e. "sonic mouse") ALIEN STORM 異形風暴 (i.e. "alien storm") Other label contents: PORTABLE VIDEO GAME SYSTEM ゲームギア (i.e. Game Gear, in Japanese) GAME GEAR COLOR VIDEO GAME I have a second cartridge with identical contents. The label on that one does not include chinese, and lists the games as: Super 2 in 1 - Sonic - Alienstorm Despite the cartridge being Game Gear-shaped, it operates exclusively in SMS-GG mode and the games are both unmodified copies of standard SMS releases This is a 512KB ROM containing two 256KB SMS games: Sonic The Hedgehog and Alien Storm There does not seem to be any sort of menu, and switching games is accomplished by power-cycling the console Each game uses the Sega mapper registers for paging. This paging does not cross game boundaries, it wraps at 256KB instead ROM fingerprint info: 512K Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms Checking for export header with matching CRC... YES sha256:7382900a9f84653eae7f621aea31da0b17db74357857fdce4ebfafdef6f831e8 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms sha1:9deeb3ef00feeeaebd33d289ed266201aa62bdf3 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms md5:19ee7015deaef4cd7b2df4edad3e1aef Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms mekacrc:414DF3905F54E953 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms crc32:c5c66fa8 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl).sms 256K Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms Checking for export header with matching CRC... YES sha256:6ad738965ece231427ee046b9905cfee470d5c01220afdd934da4673e4a2458b Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms sha1:6b9677e4a9abb37765d6db4658f4324251807e07 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms md5:dc13a61eafe75c13c15b5ece419ac57b Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms mekacrc:2F2C8E1A0AE456B9 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms crc32:b519e833 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-00-Sonic The Hedgehog (EU,US,BR)-256k.sms 256K Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms Checking for export header with matching CRC... YES sha256:6ce161836437106b3cef1e0e71e4045b97f4f2aeb851e9106a99751aba0abcc8 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms sha1:aece64ecbfbe08b199b29df9bc75743773ea3d34 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms md5:c60380642a89805f569124a875248d71 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms mekacrc:122165765570939A Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms crc32:7f30f793 Super 2 in 1 - Sonic & Alien Storm [SMS-GG] (Unl)/part-10-Alien Storm (EU,BR)-256k.sms --- I've been calling it "Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)" I have this as a loose cartridge only. There appears to be no collection title. The cartridge label has pictures for each of the four included games Also on the label: GEAR GAME This is a 1MB Game Gear-shaped multicart with no menu. Rotating through the included games is accomplished by power-cycling. Each of the four included games is an unmodified 256KB SMS release and runs in SMS-GG mode; the games are: SMS: Moonwalker, Double Dragon, Sagaia, Spider-Man The individual games use the Sega mapper, but that does not map across game boundaries ROM fingerprint info: 1.0M Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms Checking for export header with matching CRC... YES sha256:9f113a6cc339941b0bdc9d12910ea32f02e7d34c8ed1a7931e45075340d54cad Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms sha1:d5ff9f75ecc39b23d4ed7f7ce3ba847b5026b1d4 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms md5:79732827c33b2d8babe8edbdb2ecac93 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms mekacrc:F0B71C1C94F56830 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms crc32:f4de22f1 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl).sms 256K Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms Checking for export header with matching CRC... YES sha256:1b9c2fffeb533a086e078188e9747112b4320f7c9c5d5f1e98bd1ac7157ed3b6 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms sha1:939416cebb381458d28ff628afb3d1f80293afa9 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms md5:aa3bc8467e80a6aaab02051818ecb035 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms mekacrc:FA387D6C37963DDB Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms crc32:56cc906b Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-00-Moonwalker (Michael Jackson's) (US,EU,BR,KR)-256k.sms 256K Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms Checking for export header with matching CRC... YES sha256:26290f94a597ad015da5b74e8d3649aa50b033c280c81fbfa460f947376b776a Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms sha1:cad5532af94ed75c0ada8820a83fa04d22f7bef5 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms md5:fe9aa8044951b10f876b15f4456161a9 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms mekacrc:3488F258EC375C7B Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms crc32:a55d89f3 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-01-Double Dragon (JP,US,EU,BR,KR)-256k.sms 256K Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms Checking for export header with matching CRC... YES sha256:6038714821cbd5cecc862527496463d9404e79ec814781655741863f66cadf99 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms sha1:2a3e859139f8ca83494bb800dc848fe4d02db82a Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms md5:d8a4c95203bbe294760085189f9544fa Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms mekacrc:D28E2F698C014338 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms crc32:66388128 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-02-Sagaia (EU,BR)-256k.sms 256K Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms Checking for export header with matching CRC... YES sha256:cbc3ccef0f16d33153239f2f6ce7bc96059b23383da06cd99f93b40316b8bfbe Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms sha1:02ebee891d88bacdadd37a3e75e05763b7ad3c9b Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms md5:fa10ee70e43385e88e5d1a008716668b Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms mekacrc:F0697EEFE5278CA2 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms crc32:908ff25c Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] (Unl)/part-03-Spider-Man - vs. The Kingpin (EU,US,BR,AU)-256k.sms --- I've been calling this "Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)" but its actual name is unclear The label says: 双截龍 (shuang jie long, i.e. "twin dragons"/"dragon twins", the Chinese title characters for Double Dragon) SUPER 2 IN 1 魔界村 (Makai Mura, i.e. "Demon World Village", the Japanese title for Ghouls'n Ghosts) This is a menu-less power-cycling 512KB SMS-GG multicart containing two 256KB SMS games: Ghouls'n Ghosts, Double Dragon The boot-up game from a discharged state seems to be Ghouls'n Ghosts. Each power-cycle rotates to the other game The PCB appears to use a capacitor to preserve mapper state across the power-cycles used to rotate through the games Both games are unmodified compared to their official releases 512K Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms Checking for export header with matching CRC... YES sha256:5f88de3df4e627ae70c3787e4803458cc0f089ba301ae054bbd1355808101f73 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms sha1:279eb9deba7d59f05d81062e62952ddbccf1dda7 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms md5:0d8135a36ff768de78643a7dd25cbb5d Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms mekacrc:0FE54D8F9C2ED591 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms crc32:4f72c1fc Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl).sms 256K Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms Checking for export header with matching CRC... YES sha256:d5730a00b6f54aa7a68d815db358f82aa4e8b45dd3bc8712b4f1de18658b8ffe Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms sha1:b193e624795b2beb741249981d621cb650c658db Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms md5:85707b3a74483910699ccc4ba20c64ff Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms mekacrc:DB5D5B37B0F77916 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms crc32:7a92eba6 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-00-Ghouls'n Ghosts (US,EU,BR,KR)-256k.sms 256K Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms Checking for export header with matching CRC... YES sha256:26290f94a597ad015da5b74e8d3649aa50b033c280c81fbfa460f947376b776a Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms sha1:cad5532af94ed75c0ada8820a83fa04d22f7bef5 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms md5:fe9aa8044951b10f876b15f4456161a9 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms mekacrc:3488F258EC375C7B Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms crc32:a55d89f3 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] (Unl)/part-10-Double Dragon (JP,US,EU,BR,KR)-256k.sms Add support for "GG Super 56 in 1 (B) [Mega Man]" --- I've been calling this "GG Super 56 in 1 (B) [Mega Man] (Unl)" but the correct name is not entirely clear The label has some title candidate text: GG (in a jagged balloon) Super 56 in 1 (B) The menu screens also have a collection title: G.G. 56 IN 1 The cartridge label has a game list with Traditional Chinese and English names for each of the 56 entries Mine came used as a loose cartridge This is a 2MB Game Gear multicart with a menu and 17 distinct games (16 accessible) including both native Game Gear games and SMS games running in SMS-GG mode. The accessible games are: GG: Columns, Pengo, Woody Pop, Honoo no Toukyuuji Dodge Danpei (JP), Doraemon Nora no Suke no Yabou (JP), Tails' Skypatrol (JP), Fatal Fury Special (US), Mega Man (US); SMS: Hang On, Great Soccer, Spy vs Spy, Seishun Scandal, Machine Gun Joe, Astro Flash, Satellite-7, Ghost House This cartridge also contains a copy of SG-1000 Exerion combined with the menu, but this appears not to be reachable and may not be fully playable though it can at least be started by forcing a jump to address 0x0004 Dumping steps are the same as for "Super GG 68 in 1 [Sonic Adventure] (Unl)" and the mapper is basically the same too Here's the dumping script I used to extract the contents. It turns out the cartridge can remain connected between dumps. After the fragment shown, I used a regular Sega dumping steps (regular read for the first 32KB, then paging using 0xFFFF and the 0x8000...0xBFFF range after that.) ``` // /* first megabyte, first 256K */ 0x000C00; // /* first megabyte, second 256K */ 0x080C00; // /* first megabyte, third 256K */ 0x100C00; // /* first megabyte, fourth 256K */ 0x180C00; // /* second megabyte, first 512K */ 0x001204; // /* second megabyte, second 512K */ 0x101204; local base_page_unlock = 0x200C00; // adjust for different games cpu_write(d, 0xFFF9, 0x00); cpu_write(d, 0xFFF8, 0x00); cpu_write(d, 0xFFFA, 0x01); cpu_write(d, 0xFFF8, (base_page_unlock & 0xFF0000) >> 16); cpu_write(d, 0xFFF9, (base_page_unlock & 0xFF00) >> 8); cpu_write(d, 0xFFFA, base_page_unlock & 0xFF); cpu_write(d, 0xFFFE, 0x01); ``` On startup the menu writes: [0xFFFE=0x01] Menu contents: (the arrow "→" is a movable cursor and shown in its initial position) Screen 1: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →01.MAGA MAN [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-30-Mega Man (US)-512k.gg 02.FATAL FURY 2 [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x00, 0xFFFE=0x01]; it's [GG] part-20-Fatal Fury Special (US)-512k.gg 03.DORAEMON [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg 04.SONIC TAIL [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x18, 0xFFFE=0x01]; it's [GG] part-18-Tails' Skypatrol (JP)-256k.gg 05.DAN PEN [0xFFFA=0x00, 0xFFF9=0x08, 0xFFF8=0x04, 0xFFFE=0x01]; it's [GG] part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 06.COLUMNS [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x01, 0xFFFE=0x01]; it's [GG] part-01-columns-32k.gg 07.GHOST HOUSE [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0f, 0xFFFE=0x01]; it's [SMS-GG] part-0f-ghost-house-32k.sms 08.SATELLITE-7 [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0e, 0xFFFE=0x01]; it's [SMS-GG] part-0e-satellite-7-32k.sms 09.ASTRO FLASH [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0d, 0xFFFE=0x01]; it's [SMS-GG] part-0d-astro-flash-32k.sms 10.MACHINE GUN [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0c, 0xFFFE=0x01]; it's [SMS-GG] part-0c-machine-gun-joe-32k.sms ``` Screen 2: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →11.ACTION BOY [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0b, 0xFFFE=0x01]; it's [SMS-GG] part-0b-seishun-scandal-32k.sms 12.SPY VS SPY [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0a, 0xFFFE=0x01]; it's [SMS-GG] part-0a-spy-vs-spy-32k.sms 13.GREAT SOCCER [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x09, 0xFFFE=0x01]; it's [SMS-GG] part-09-great-soccer-32k.sms 14.HANG ON [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x08, 0xFFFE=0x01]; it's [SMS-GG] part-08-hang-on-32k.sms 15.WOODY POP [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x03, 0xFFFE=0x01]; it's [GG] part-03-woody-pop-32k.gg 16.PENGUIN LAND [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x02, 0xFFFE=0x01]; it's [GG] part-02-pengo-32k.gg 17.ARO DIN DON [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg 18.SUPER DAN PEI [0xFFFA=0x00, 0xFFF9=0x08, 0xFFF8=0x04, 0xFFFE=0x01]; it's [GG] part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 19.ROCK MAN [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-30-Mega Man (US)-512k.gg 20.WORLD HEROS [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x00, 0xFFFE=0x01]; it's [GG] part-20-Fatal Fury Special (US)-512k.gg ``` Screen 3: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →21.SONIC BROTHER [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x18, 0xFFFE=0x01]; it's [GG] part-18-Tails' Skypatrol (JP)-256k.gg 22.ALLEY WAY [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x03, 0xFFFE=0x01]; it's [GG] part-03-woody-pop-32k.gg 23.PENGO [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x02, 0xFFFE=0x01]; it's [GG] part-02-pengo-32k.gg 24.COLORS TETRIS [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x01, 0xFFFE=0x01]; it's [GG] part-01-columns-32k.gg 25.GHOST LAND [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0f, 0xFFFE=0x01]; it's [SMS-GG] part-0f-ghost-house-32k.sms 26.STAR GATE [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0e, 0xFFFE=0x01]; it's [SMS-GG] part-0e-satellite-7-32k.sms 27.VOLLEY FIRE [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0d, 0xFFFE=0x01]; it's [SMS-GG] part-0d-astro-flash-32k.sms 28.SHOOT GUN [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0c, 0xFFFE=0x01]; it's [SMS-GG] part-0c-machine-gun-joe-32k.sms 29.SCHOOL BOY [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0b, 0xFFFE=0x01]; it's [SMS-GG] part-0b-seishun-scandal-32k.sms 30.TECHNO COP [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0a, 0xFFFE=0x01]; it's [SMS-GG] part-0a-spy-vs-spy-32k.sms ``` Screen 4: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →31.FIFA SOCCER [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x09, 0xFFFE=0x01]; it's [SMS-GG] part-09-great-soccer-32k.sms 32.MOTOBIKE [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x08, 0xFFFE=0x01]; it's [SMS-GG] part-08-hang-on-32k.sms 33.ATTACK [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-30-Mega Man (US)-512k.gg 34.THUNDER [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg 35.DANGEROUS [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x18, 0xFFFE=0x01]; it's [GG] part-18-Tails' Skypatrol (JP)-256k.gg 36.POP POP HERO [0xFFFA=0x00, 0xFFF9=0x08, 0xFFF8=0x04, 0xFFFE=0x01]; it's [GG] part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 37.YOUNG GUY [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0b, 0xFFFE=0x01]; it's [SMS-GG] part-0b-seishun-scandal-32k.sms 38.FURY 95 [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x00, 0xFFFE=0x01]; it's [GG] part-20-Fatal Fury Special (US)-512k.gg 39.LIONET [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x08, 0xFFFE=0x01]; it's [SMS-GG] part-08-hang-on-32k.sms 40.WOODY WAY [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x03, 0xFFFE=0x01]; it's [GG] part-03-woody-pop-32k.gg ``` Screen 5: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →41.PENGUIN EGG [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x02, 0xFFFE=0x01]; it's [GG] part-02-pengo-32k.gg 42.COLORS BLOCK [0xFFFA=0x00, 0xFFF9=0x00, 0xFFF8=0x01, 0xFFFE=0x01]; it's [GG] part-01-columns-32k.gg 43.GHOST BUSTER [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0f, 0xFFFE=0x01]; it's [SMS-GG] part-0f-ghost-house-32k.sms 44.TOP GUN [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0e, 0xFFFE=0x01]; it's [SMS-GG] part-0e-satellite-7-32k.sms 45.AIR WAR [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0d, 0xFFFE=0x01]; it's [SMS-GG] part-0d-astro-flash-32k.sms 46.HUNTER [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0c, 0xFFFE=0x01]; it's [SMS-GG] part-0c-machine-gun-joe-32k.sms 47.MY HERO [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0b, 0xFFFE=0x01]; it's [SMS-GG] part-0b-seishun-scandal-32k.sms 48.SPY MAN [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0a, 0xFFFE=0x01]; it's [SMS-GG] part-0a-spy-vs-spy-32k.sms 49.PRO SOCCER [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x09, 0xFFFE=0x01]; it's [SMS-GG] part-09-great-soccer-32k.sms 40.MOTOCROSS [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x08, 0xFFFE=0x01]; it's [SMS-GG] part-08-hang-on-32k.sms ``` Screen 6: ``` G.G. 56 IN 1 PUSH ↑.↓.1.START →51.PRO CRAZY BOY [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-30-Mega Man (US)-512k.gg 52.BOY BLUES [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x10, 0xFFFE=0x01]; it's [GG] part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg 53.P.P GAMES [0xFFFA=0x00, 0xFFF9=0x0c, 0xFFF8=0x18, 0xFFFE=0x01]; it's [GG] part-18-Tails' Skypatrol (JP)-256k.gg 54.KLAX [0xFFFA=0x00, 0xFFF9=0x08, 0xFFF8=0x04, 0xFFFE=0x01]; it's [GG] part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 55.F 16 BOY [0xFFFA=0x01, 0xFFF9=0x00, 0xFFF8=0x0d, 0xFFFE=0x01]; it's [SMS-GG] part-0d-astro-flash-32k.sms 56.STREE FIGHTER [0xFFFA=0x00, 0xFFF9=0x13, 0xFFF8=0x00, 0xFFFE=0x01]; it's [GG] part-20-Fatal Fury Special (US)-512k.gg ``` ROM fingerprint information: 2.0M GG Super 56 in 1 (B) [Mega Man] (Unl).gg Checking for export header with matching CRC... NO sha256:80ab455b6204ba7b1968bbb4b085fe3a23ed567c02a7d94bb223ee30000266a5 GG Super 56 in 1 (B) [Mega Man] (Unl).gg sha1:a31755d835e42ad4695e453dece0d9b3f98c92cf GG Super 56 in 1 (B) [Mega Man] (Unl).gg md5:2bb00478b5df60492c49e77075d432fa GG Super 56 in 1 (B) [Mega Man] (Unl).gg mekacrc:92CBD58C8243F885 GG Super 56 in 1 (B) [Mega Man] (Unl).gg crc32:271f40a3 GG Super 56 in 1 (B) [Mega Man] (Unl).gg 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg Checking for export header with matching CRC... NO sha256:e2c42cacc925c5625deaa3b1b8c4ba3af02388aec5a31de3b1ff6cb3549fc29f GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg sha1:af611e1557c4f10ce4f76ff155ae8f6f216a4443 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg md5:e26a304dfef7ea019c79dedc0b2782ad GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg mekacrc:A96A175A0CC102AD GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg crc32:4a97d476 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-00-menu-and-exerion-32k.gg 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg Checking for export header with matching CRC... NO sha256:73f6012c1a92bcc96497668cdecfb3b592162c6b39a8c7efb8b9dc3931380561 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg sha1:26d407e8389a5564b836f0a68585a935ca019802 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg md5:bfcf0e46ec8df8a51776bd2315b859fc GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg mekacrc:1DE54704572F032A GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg crc32:7316423e GG Super 56 in 1 (B) [Mega Man] (Unl)/part-01-columns-32k.gg 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg Checking for export header with matching CRC... NO sha256:1c221bcb0b7ef67e644a695b78cb4dd851b800202ee13fd8d03fb099e533c46a GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg sha1:126654feb2975e3a52431d29cefcafbd37bb2ef5 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg md5:69bf00297cad6ee0bb6046c8084e5e37 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg mekacrc:6C3C703170EBD587 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg crc32:6bd56e95 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-02-pengo-32k.gg 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg Checking for export header with matching CRC... NO sha256:0c23fccffa3160b6754fa54ecbf08d3828f5e60a64dbe4203109715644ad94ce GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg sha1:58516c23f1e1b87daebda1b971fab278a6e7ce59 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg md5:3885c64be1dc990918adebcbe9675855 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg mekacrc:9D2A47DDDF12FD27 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg crc32:0c6e4769 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-03-woody-pop-32k.gg 128K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg Checking for export header with matching CRC... NO sha256:ac7b81ec5cdc7dd6ed1cfd8f1690fdd9461493827535f3744ddc1c95e834ba30 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg sha1:66032cc214d728b2f1c59ad2934277e378b36865 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg md5:a299b81a9a5455bfff538f669a5e7a0d GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg mekacrc:357F4A30EE2C9A1E GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg crc32:dfa805a0 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-04-Honoo no Toukyuuji Dodge Danpei (JP)-128k.gg 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms Checking for export header with matching CRC... NO sha256:5a2ecca3d78ae9aa8a6ac2c1775122cfdce3744898032ce5763c0017350e58ce GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms sha1:5726c7f7948612ca42daed96ded45745393bd80a GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms md5:5c25b6b38963fc513958a26e64c591d4 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms mekacrc:02A62976104874ED GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms crc32:40cedfd9 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-08-hang-on-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms Checking for export header with matching CRC... NO sha256:b48ce6a09946941fdf62e8ebf611fc1706344e26ea230bb206ba98cf04e9fbd2 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms sha1:41d55da9ed00124c570d9964494b791e09d93af8 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms md5:cecccff2d09d3cc705d848b28037e267 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms mekacrc:7CB0BCEF29C11827 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms crc32:be711818 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-09-great-soccer-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms Checking for export header with matching CRC... NO sha256:bcba12678775542b59694fc8fe3945530490cdd92a2bfafb07f74b189fa03ede GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms sha1:fd7d1bee1ca42c6d962780f21d5ad138b792db59 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms md5:324741e68234ae80ff3df8bc3f411557 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms mekacrc:98EC9FA8477AEC88 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms crc32:f13a28c0 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0a-spy-vs-spy-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms Checking for export header with matching CRC... NO sha256:3a1df738527b578e248b6650c9a1498abaf9bef6da813a172dfae0a63be4e746 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms sha1:2c39fdf814e223e2dc14646941a276879ae14c64 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms md5:c021bce5a58cfbf513af253a25bc29bd GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms mekacrc:D41A76F3C3411E87 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms crc32:637dbbef GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0b-seishun-scandal-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms Checking for export header with matching CRC... NO sha256:3981649682a895772012a769e8296e24e660ac4fc4102ecfbb747d53d18cee3e GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms sha1:03a8a50b3b9e97ea5e10d7e094d287b51ca477af GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms md5:02906381c66601fb49b10bed123455d4 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms mekacrc:5C858AC9BD4714B4 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms crc32:9a94c7cc GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0c-machine-gun-joe-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms Checking for export header with matching CRC... NO sha256:514484c1d4156fc77e4cefcd39cffd71f3e126c708420100ebb07e4972dc3486 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms sha1:b4e2483fbfe9e4c23a6fb14e755e5aa8c6ecece0 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms md5:4c13f02b69c266ffea80fd7aba160bb2 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms mekacrc:13171118D3218C2D GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms crc32:b1267d52 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0d-astro-flash-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms Checking for export header with matching CRC... NO sha256:3adcd01767ee06949a930b88b76f9e2d8c89031c41e289af9d2e4290455ee5c1 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms sha1:be0ace7ed8f1f1ab6fa51dfaa3ba2dd167ab3863 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms md5:7cb52be125ef66daa5e7a6e971a2a97f GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms mekacrc:C30BB9170D4D8E7A GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms crc32:eb9a0359 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0e-satellite-7-32k.sms 32K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms Checking for export header with matching CRC... NO sha256:c690ae4bff9711c0244e9a2ab18a579a429b29191dcc993f0ed5a496b472cfd3 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms sha1:9917f8f06ed4c99b71d58d8a03fbea13330c84a1 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms md5:343210de693491444b452df7b665921d GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms mekacrc:A5771FE4EC52960D GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms crc32:317451a3 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-0f-ghost-house-32k.sms 256K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg Checking for export header with matching CRC... NO sha256:09a0ff25362323583df586c6e6825a54499a24883802190854b9ff856e3fd7ce GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg sha1:6976b170879767889994b1e763a52726aa62ed98 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg md5:e768a7c45f8ea390d6091032fdf6dcbe GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg mekacrc:4200580F20BADF9E GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg crc32:9a8b2c16 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-10-Doraemon Nora No Suke No Yabou (JP)-256k.gg 256K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg Checking for export header with matching CRC... NO sha256:334406059c26a3704e881680fe102f819472cd331ceb13a79ce9f6b9adc08e0b GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg sha1:9cb440611e9e3a7957438698fede0978d568a807 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg md5:ffb364bbaf72881cf7571e7ec388490d GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg mekacrc:9AB480AD16FFC7A9 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg crc32:88618afa GG Super 56 in 1 (B) [Mega Man] (Unl)/part-18-Tails' Skypatrol (JP)-256k.gg 512K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg Checking for export header with matching CRC... NO sha256:e7b53995690c55dbb1fbe95349a0dce5fe3ed6106d5610d1cd394f93dda43fea GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg sha1:7ce20ca34b7bc91ba7e73f830b40830ad6bafbc8 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg md5:4292c099f98cc0c6d03025f0729f64df GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg mekacrc:01B1CB4E2F1E4C9C GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg crc32:449787e2 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-20-Fatal Fury Special (US)-512k.gg 512K GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg Checking for export header with matching CRC... NO sha256:b313e90469133da5d0d39f683cc098993c3b137458804dd0aafb173eb39cd98a GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg sha1:085517c4ac940b937d0e0a900e4735a2247ca4dd GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg md5:8583950be61ffbaf0f63dde8dded2ab3 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg mekacrc:F0B8660AB1883B74 GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg crc32:1ace93af GG Super 56 in 1 (B) [Mega Man] (Unl)/part-30-Mega Man (US)-512k.gg Add a homebrew mapper --- meka/compat.txt | 54 +- meka/meka.nam | 52 +- meka/srcs/machine.cpp | 508 ++++++++++++++++++ meka/srcs/machine.h | 1 + meka/srcs/mappers.cpp | 1171 +++++++++++++++++++++++++++++++++++++++++ meka/srcs/mappers.h | 48 +- meka/srcs/saves.cpp | 345 +++++++++++- meka/srcs/video.cpp | 6 +- 8 files changed, 2172 insertions(+), 13 deletions(-) diff --git a/meka/compat.txt b/meka/compat.txt index ab16dc0f..64a7ec3f 100644 --- a/meka/compat.txt +++ b/meka/compat.txt @@ -16,6 +16,8 @@ SMS-GG: This version is a GG cartridge using the SMS compatibility mode SMS-MD: This version is an MD cartridge using the SMS compatibility mode ----------------------------------------------------------------------------- + 11 Hap Gam-Boy (KR) - *Ok + 12 in 1 [Hang On] [SMS-GG] (Unl) - *Ok 128 Hap (KR) - *Ok 2 Hap in 1 (Moai-ui bomul, David-2) (KR) - *Ok 20 em 1 (BR) - Ok @@ -286,6 +288,14 @@ Hi-Com 3-in-1 The Best Game Collection D (KR) - Ok Hi-Com 3-in-1 The Best Game Collection E (KR) - Ok Hi-Com 3-in-1 The Best Game Collection F (KR) - Ok + Hi-Com 3-in-1 The Best Game Collection G (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection A (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection B (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection C (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection D (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection E (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection F (KR) - *Ok + Hi-Com 4-in-1 The Best Game Collection G (KR) - *Ok Hi-Com 8-in-1 The Best Game Collection A (KR) - Ok Hi-Com 8-in-1 The Best Game Collection B (KR) - Ok Hi-Com 8-in-1 The Best Game Collection C (KR) - Ok @@ -549,6 +559,9 @@ Summer Games [Proto 0] - Ok (No audio) Summer Games [Proto 1] FM Ok Suho Jeonsa (KR) - Ok + Super 12 in 1 [Teddy Boy] [SMS-MD] (Unl) - *Ok + Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG] - *Ok + Super 2 in 1 - Sonic & Alien Storm [SMS-GG] - *Ok Super Basketball [Demo] - Ok Super Bioman I (KR) - Ok Super Boy I (KR) - Ok @@ -558,7 +571,9 @@ Super Bubble Bobble (KR) - Ok Super Columns (KR) - Ok Super Futebol II [Game Box Série Esportes] (BR)- Ok - Super Game 45 (KR) - Ok + Super Game 30 [Road Fighter] [Super Game 45] (KR)- *Ok + Super Game 45 [Road Fighter] (KR) - *Ok + Super Game 45 [Teddy Boy] (KR) - Ok Super Game 52 Hap (KR) - Ok Super Game 150 (KR) - *Ok Super Game 180 (KR) - *Ok @@ -622,6 +637,7 @@ Ultima IV FM Ok Ultima IV [Proto] FM Ok Ultimate Soccer - Ok + Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] - *Ok Vigilante FM Ok Virtua Fighter Animation - Ok Walter Payton Football - Ok @@ -665,6 +681,11 @@ Zaxxon 3-D / Zaxxon 3D FM,(3D) Ok Zaxxon 3-D / Zaxxon 3D [Proto] (3D) Ok Zemina 4-in-1 (Q-Bert, Sports 3, Gulkave..)(KR)- *Ok + Zemina Best 25 [Best 88] (KR) - *Ok + Zemina Best 39 [Best 88] (KR) - *Ok + Zemina Best 39 [Best 88] [MISSING 64K] (KR) - *Ok + Zemina Best 88 (KR) - *Ok + Zemina Best 88 [MISSING-64K] (KR) - *Ok Zillion [v0] / Akai Koudan Zillion - Ok Zillion [v1] - Ok Zillion [v2] - Ok @@ -672,7 +693,7 @@ Zillion II: The Tri Formation [Proto] FM Ok Zool - Ok ----------------------------------------------------------------------------- - 651 games tested - 647 are "Ok" + 672 games tested - 668 are "Ok" ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -980,6 +1001,7 @@ ----------------------------------------------------------------------------- SEGA GAME GEAR (GG) COMPATIBILITY LIST ----------------------------------------------------------------------------- + 18 in 1 - Super Games Collection [Columns] *Ok 5 in One Fun Pak Ok Aa Harimanada (JP) Ok Addams Family, The Ok @@ -1136,14 +1158,17 @@ Garou Densetsu Special (JP) Ok Ganbare Gorby! (JP) Ok Garfield: Caught in the Act Ok + Gear 6 in 1 [Alien Syndrome] *Ok Gear Stadium (JP) Ok Gear Stadium Heiseiban (JP) Ok Gear Works Ok George Foreman's KO Boxing Ok + GG 48 in 1 [Doraemon 2] *Ok GG Aleste (JP) Ok GG Portrait - Pai Chen (JP) Ok GG Portrait - Yuuki Akira (JP) Ok GG Shinobi, The (JP) Ok + GG Super 56 in 1 (B) [Mega Man] *Ok Global Gladiators Ok G-LOC - Air Battle Ok G-LOC - Air Battle [v0] (JP) Ok @@ -1405,9 +1430,31 @@ Street Hero [Proto 1] [SMS-GG] Ok Strider Returns Ok Striker Ok + Super 5 in 1 Game Gear [Mortal Kombat] [Super 12 in 1] *Ok + Super 7 in 1 Game Gear [Bare Knuckle 2] [Super 12 in 1] *Ok + Super 12 in 1 Game Gear [Bare Knuckle 2] *Ok + Super 12 in 1 Game Gear [Mortal Kombat] *Ok + Super 21 in 1 [Pacmania] [Super 53 in 1] *Ok + Super 32 in 1 [Alien 3] [Super 53 in 1] *Ok + Super 53 in 1 [Alien 3] *Ok + Super 53 in 1 [Pacmania] *Ok + Super 68 in 1 [Simpson] *Ok Super Battletank Ok Super Columns Ok Super Columns (JP) Ok + Super Game Gear 9 in 1 [Sonic II] *Ok + Super Game Gear 73 in 1 [Sonic 2] *Ok + Super Game Gear 73 in 1 [Street Fighter 2] *Ok + Super Gear 20 in 1 [Ninja Gaiden] *Ok + Super Gear 23 in 1 [Ninja Gaiden] *Ok + Super GG 15 [Cliffhanger] [Gold & Yellow Label] *Ok + Super GG 15 [Last Action] [Super GG 30 Gold & Green Label] *Ok + Super GG 15 in 1 [Sonic 5] *Ok + Super GG 18 in 1 [Nettou Samurai] *Ok + Super GG 21 in 1 [Sonic Drift] [Gold & Yellow Label] *Ok + Super GG 30 [Last Action] [Gold & Green Label] *Ok + Super GG 30 in 1 [Sonic 2] [Gold & Yellow Label] *Ok + Super GG 68 in 1 [Sonic Adventure] *Ok Super Golf (JP) Ok Super Kick Off [SMS-GG] Ok Superman - The Man of Steel Ok @@ -1454,6 +1501,7 @@ Tom and Jerry: The Movie (JP) Ok Torarete Tamaruka!? (JP) Ok True Lies Ok + Turbo 9 in 1 [Street Fighter 2] *Ok Ultimate Soccer Ok Urban Strike Ok Vampire - Master of Darkness (US) Ok @@ -1498,7 +1546,7 @@ Zoop (US) Ok Zoop [Proto] (US) Ok ----------------------------------------------------------------------------- - 517 games tested - 506 are "Ok" - Compatibility rate: 97.63% + 544 games tested - 533 are "Ok" - Compatibility rate: 97.98% ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- diff --git a/meka/meka.nam b/meka/meka.nam index 77c032bf..b8ac31aa 100644 --- a/meka/meka.nam +++ b/meka/meka.nam @@ -88,8 +88,10 @@ ; DATA - SEGA MASTER SYSTEM (SMS) ;----------------------------------------------------------------------------- +SMS ea61eb12 4CB8CC9931B0A313 12 in 1 [Hang On] [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=46 SMS ba5ec0e3 0707EB856DC38BC7 128 Hap (KR)/COUNTRY=KR/EMU_MAPPER=19 SMS 1b3e032e 8479DA42A3D4F67A 2 Hap in 1 (Moai-ui bomul, David-2)/COUNTRY=KR/EMU_MAPPER=27 +SMS 4342db9d CE8A9AB977B6FE2A 11 Hap Gam-Boy (KR)/COUNTRY=KR/EMU_MAPPER=39 SMS f0f35c22 02079D9D9AF6B27B 20 em 1/COUNTRY=BR SMS 56dcb2d4 9FA930C396F93600 3D Gunner [Proto]/EMU_MAPPER=0/EMU_INPUTS=LIGHTPHASER/EMU_3D/EMU_LP_FUNC=2/COMMENT=Prototype version of the unreleased game. SMS a67f2a5c 4EB5F14E8488C9E9 4 PAK All Action/COUNTRY=AU/EMU_MAPPER=14 @@ -365,6 +367,14 @@ SMS 81a36a4f 76FBAF87132C908A Hi-Com 3-in-1 The Best Game Collection C/COUNTRY SMS 8d2d695d 54C959A96963AD68 Hi-Com 3-in-1 The Best Game Collection D/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Teddy Boy Blues, Great Soccer, Comical Machine Gun Joe. SMS 82c09b57 B547AFCC3800361B Hi-Com 3-in-1 The Best Game Collection E/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Ghost House, Teddy Boy Blues, Seishun Scandal. SMS 4088eeb4 BF636F2E924ECC95 Hi-Com 3-in-1 The Best Game Collection F/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Satellite-7, Great Baseball, Seishun Scandal. +SMS 752d198c 71F075819FADB0AD Hi-Com 3-in-1 The Best Game Collection G/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Ghost House, Super Tennis, Astro Flash. +SMS 761e35ae DCA4DCB4EA4FB403 Hi-Com 4-in-1 The Best Game Collection A/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Hyper Sports 2, Champion Boxing, Safari Race, Astro Flash. +SMS 002e1a49 89578202B1EDF509 Hi-Com 4-in-1 The Best Game Collection B/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Monkey Academy, Star Force, Bank Panic, Teddy Boy. +SMS 6a63eea6 C84D03172970BE7A Hi-Com 4-in-1 The Best Game Collection C/COUNTRY=KR/EMU_MAPPER=16/COMMENT=King's Valley, Ghost House, Sega-Galaga, Monaco GP. +SMS f27e8f80 4C0ACA087125370B Hi-Com 4-in-1 The Best Game Collection D/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Magical Tree, Ninja Princess, Satellite-7, Hang-On. +SMS 52587fb9 EC870F68788ADB39 Hi-Com 4-in-1 The Best Game Collection E/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Athletic Land, Super Tank, Bomb Jack, Hyper Sports. +SMS 6f62f5a4 8A76E791EDE24E6B Hi-Com 4-in-1 The Best Game Collection F/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Circus Charlie, Exerion, Great Baseball, Yie Ar Kung-Fu. +SMS deb45078 84A7B17C9D1F628A Hi-Com 4-in-1 The Best Game Collection G/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Galaxian, Loderunner, Super Tennis, Seishyun Scandal SMS fba94148 65FB5EB69B3CA90C Hi-Com 8-in-1 The Best Game Collection A/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Hyper Sports 2, Champion Boxing, Safari Race, Astro Flash, Monkey Academy, Star Force, Bank Panic, Teddy Boy. SMS 8333c86e 1457CD1F9A95F585 Hi-Com 8-in-1 The Best Game Collection B/COUNTRY=KR/EMU_MAPPER=16/COMMENT=King's Valley, Ghost House, Sega-Galaga, Monaco GP, Magical Tree, Ninja Princess, Satellite-7, Hang-On. SMS 00e9809f 76FDF6F9656C29A4 Hi-Com 8-in-1 The Best Game Collection C/COUNTRY=KR/EMU_MAPPER=16/COMMENT=Athletic Land, Super Tank, Bomb Jack, Hyper Sports, Circus Charlie, Exerion, Great Baseball, Yie Ar Kung-Fu. @@ -641,6 +651,9 @@ SMS 8da5c93f AF2D01D4A78C8B91 Summer Games/NAME_BR=Jogos Olímpicos/COUNTRY=EU SMS 4f530cb2 D1B42E8EF4C358B0 Summer Games [Proto 0]/FLAGS=PROTO/COMMENT=Early prototype version of the game. No audio. SMS 80eb1fff 420EEF0B240F3152 Summer Games [Proto 1]/FLAGS=PROTO/COMMENT=Prototype version of the game. SMS 01686d67 88E8E8D0608B22CB Suho Jeonsa/COUNTRY=KR/PRODUCT_NO=DS-G402 +SMS 6037e93b 4CB8CC9931B0A313 Super 12 in 1 [Teddy Boy] [SMS-MD]/EMU_MAPPER=46 +SMS 4f72c1fc 0FE54D8F9C2ED591 Super 2 in 1 - Double Dragon, Ghouls'n Ghosts [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 +SMS c5c66fa8 414DF3905F54E953 Super 2 in 1 - Sonic & Alien Storm [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 SMS 0dbf3b4a 01EF5A009C6701B2 Super Basketball [Demo]/FLAGS=PROTO/COUNTRY=US/COMMENT=Rolling non-interactive demo to advertise unreleased game. Was shown at the CES exposition floor in USA (around 1989?). SMS a66d26cf 5E7FE6D39D642445 Super Bioman I/COUNTRY=KR SMS bf5a994a 8DF09E55615029B6 Super Boy I/COUNTRY=KR @@ -655,7 +668,9 @@ SMS 4e202aa2 3EE0DA7C01A6786D Super Game 180/COUNTRY=KR/EMU_MAPPER=20 SMS ba5d2776 1EBAD8829E4FF6EB Super Game 200/COUNTRY=KR/EMU_MAPPER=20 SMS d9ef7d69 7A8AA34E6083F137 Super Game 270/COUNTRY=KR/EMU_MAPPER=22 SMS d3056492 1537C90CFD960E3E Super Game 270 Hap ~ Jaemissneun-270/COUNTRY=KR/EMU_MAPPER=18 -SMS edb13847 3EEA007A568DAECD Super Game 45/COUNTRY=KR/EMU_MAPPER=21 +SMS 710bbdb4 2ED70C7D9A4A6A24 Super Game 30 [Road Fighter] [Super Game 45]/COUNTRY=KR/EMU_MAPPER=45 +SMS 4d3db8be 2ED70C7D9A4A6A24 Super Game 45 [Road Fighter]/COUNTRY=KR/EMU_MAPPER=44 +SMS edb13847 3EEA007A568DAECD Super Game 45 [Teddy Boy]/COUNTRY=KR/EMU_MAPPER=21 SMS a841c0b7 82F73F4413D9CF49 Super Game 52 Hap/COUNTRY=KR/EMU_MAPPER=20 SMS ab07ecd4 BA49364933A43F68 Super Game World 260 Hap/COUNTRY=KR/EMU_MAPPER=18 SMS 0cde0938 2DFBC7EBB5C63576 Super Game World 30 Hap/COUNTRY=KR/EMU_MAPPER=18/COMMENT=Variation of "Super World 30 Hap" @@ -717,6 +732,7 @@ SMS e1714a88 830DC65B43CD65DA TV Colosso (As Aventuras da)/COUNTRY=BR/PRODUCT_ SMS b52d60c8 3EEC41D938FA3456 Ultima IV/COUNTRY=EU,BR/PRODUCT_NO=9501 SMS de9f8517 A9FD5B95131658E9 Ultima IV [Proto]/FLAGS=PROTO/COMMENT=Prototype version of the game. SMS 15668ca4 7638A4C78062F114 Ultimate Soccer/COUNTRY=EU,BR/PRODUCT_NO=7119,024440 +SMS f4de22f1 F0B71C1C94F56830 Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG]/FLAGS=SMSGG_MODE/EMU_MAPPER=47 SMS dfb0b161 826B0C3B91EAF65B Vigilante/COUNTRY=US,EU,BR/PRODUCT_NO=7023 SMS 57f1545b 63CE90266CDA3B98 Virtua Fighter Animation/COUNTRY=BR/PRODUCT_NO=030020/COMMENT=This is a port from the Game Gear version. SMS 3d55759b 2893A79D37A62301 Walter Payton Football/COUNTRY=US/PRODUCT_NO=7020/COMMENT=US version of "American Pro Football". @@ -761,6 +777,11 @@ SMS e8b82066 06806D7C60FB9C9A Y's: The Vanished Omens [Demo]/COUNTRY=US/FLAGS= SMS a3ef13cb 73E4CCD0CC1A69BE Zaxxon 3-D/NAME_JP=Zaxxon 3D/COUNTRY=JP,US,EU,BR/EMU_3D/PRODUCT_NO=G-1336,8002/COMMENT=The 3-D effect can be removed by pressing Pause on title screen. It works only on non-Japanese systems. SMS bba74147 2D689EA985B828BF Zaxxon 3-D [Proto]/NAME_JP=Zaxxon 3D/FLAGS=PROTO/EMU_3D/COMMENT=Unfinished prototype version of the game. SMS 7cd51467 488D49FF0599CE77 Zemina 4-in-1 (Q-Bert, Sports 3, Gulkave, Pooyan)/COUNTRY=KR/EMU_MAPPER=23 +SMS e6c9c046 F4E9FC49C3C374E4 Zemina Best 25 [Best 88]/COUNTRY=KR/EMU_MAPPER=40/COMMENT=This is the second 512KB of Zemina Best 88 +SMS d8169fe2 BF9411BD7824093A Zemina Best 39 [Best 88]/COUNTRY=KR/EMU_MAPPER=40/COMMENT=This is the first 512KB of Zemina Best 88 +SMS 397069ff BC8B94BFE2F8D6B6 Zemina Best 39 [Best 88] [MISSING 64K]/COUNTRY=KR/EMU_MAPPER=40/COMMENT=This is the first 512KB of Zemina Best 88 [MISSING 64K]. 64KB of the ROM with 4 MSX games is missing and replaced with duplicates of other games +SMS 3c339d9e B37D0D063BE77D1E Zemina Best 88/COUNTRY=KR/EMU_MAPPER=40 +SMS e30720b8 B0749008A5BB4A9A Zemina Best 88 [MISSING 64K]/COUNTRY=KR/EMU_MAPPER=40/COMMENT=64KB of the ROM with 4 MSX games is missing and replaced with duplicates of other games SMS 60c19645 39A919D7DA6933B8 Zillion [v0]/NAME_JP=Akai Koudan Zillion/COUNTRY=JP,EU/PRODUCT_NO=G-1325,5075 SMS 5718762c 88E69FBAA2DA4974 Zillion [v1]/COUNTRY=US/PRODUCT_NO=5075 ; [EDITOR NOTE] Country listing for all 3 versions are based on what we found so far. It's probable that v1 and v2 were released in both US and EU. SMS 7ba54510 8AE29FB6A2DC4B76 Zillion [v2]/COUNTRY=EU/PRODUCT_NO=5075 @@ -881,6 +902,7 @@ SMS 317f14da 642D4E5E1BB23ABC Ninja Gaiden/FLAGS=TRANS/TRANS=DE/VERSION=1.00/A ; DATA - SEGA GAME GEAR (GG) ;----------------------------------------------------------------------------- +GG 81818f55 6AAE6866CB4814F3 18 in 1 - Super Games Collection [Columns]/EMU_MAPPER=49 GG f85a8ce8 5DB92D172BF43C4B 5 in One Fun Pak/COUNTRY=US/PRODUCT_NO=T-125028 GG 1d17d2a0 A5D21350B842022A Aa Harimanada/COUNTRY=JP/PRODUCT_NO=G-3327 GG 1d01f999 EE39E44E85E0C77B Addams Family, The/COUNTRY=US,EU,JP/PRODUCT_NO=T-81188,T-81188-50,T-81087 @@ -1031,15 +1053,18 @@ GG 0593ba24 905D6D377D1F9D36 Galaga '91/COUNTRY=JP/PRODUCT_NO=T-14057/COMMENT GG 95ecece2 432C080C09AD5275 Galaga 2/COUNTRY=EU/PRODUCT_NO=2322/COMMENT=Export version of "Galaga '91". GG cd53f3af 5434506F49A77C4D Garfield: Caught in the Act/COUNTRY=US,EU/PRODUCT_NO=2560,2560-50 GG 9afb6f33 CE07E49360532BD6 Garou Densetsu Special/COUNTRY=JP/PRODUCT_NO=T-103017/COMMENT=Japanese version of "Fatal Fury Special". +GG 983ffa6c 380E4248BE33AC93 Gear 6 in 1 [Alien Syndrome]/EMU_MAPPER=42 GG 0e300223 27BA4F0E3A5DBF6C Gear Stadium/COUNTRY=JP/PRODUCT_NO=T-14037/COMMENT=Japanese version of "Batter Up". GG a0530664 08ADE585B8DA024D Gear Stadium Heiseiban/COUNTRY=JP/PRODUCT_NO=T-14077 GG e9a2efb4 F9F734AF23CDB28B Gear Works/COUNTRY=US/PRODUCT_NO=T-93058 GG 58b44585 C92745E46E995090 George Foreman's KO Boxing/COUNTRY=US,EU/PRODUCT_NO=T-81038,T-81038-50 +GG 3394aaea F07FEFF54F0A7CD8 GG 48 in 1 [Doraemon 2]/EMU_MAPPER=48 GG 1b80a75b 682713F64A0AAD67 GG Aleste/COUNTRY=JP/PRODUCT_NO=T-66017 GG 695cc120 FCC991E880B52D60 GG Portrait - Pai Chen/COUNTRY=JP/PRODUCT_NO=G-3387 GG 51159f8f 5D96967FEE1C49A5 GG Portrait - Yuuki Akira/COUNTRY=JP/PRODUCT_NO=G-3386 GG 83926bd1 7EC1D6C6D2A7119B GG Shinobi, The/COUNTRY=JP/PRODUCT_NO=G-3302 GG d2b6021e F0E8A87399B7C4F9 Global Gladiators/COUNTRY=US,EU/PRODUCT_NO=T-70058,T-70058-50 +GG 271f40a3 92CBD58C8243F885 GG Super 56 in 1 (B) [Mega Man]/EMU_MAPPER=32 GG 18de59ed 093B5C63C1FA1E24 G-LOC - Air Battle/NAME_BR=G-LOC/COUNTRY=US,EU,BR/PRODUCT_NO=2301,012120 GG 2333f615 9B4CDA9945218AB6 G-LOC - Air Battle [v0]/COUNTRY=JP/PRODUCT_NO=G-3204 GG 33237f50 6949D8B6CE13CD12 G-LOC - Air Battle [v1]/COUNTRY=JP/PRODUCT_NO=G-3204 @@ -1288,10 +1313,32 @@ GG 0b618409 85CFE82DBD812633 Streets of Rage II/NAME_US=Streets of Rage 2/NAM GG 6c395a69 BC45532F90B98FA5 Streets of Rage II [Proto]/NAME_US=Streets of Rage 2/NAME_JP=Bare Knuckle II/FLAGS=PROTO/COMMENT=Prototype version of the game. GG 1ebfa5ca 24A227CBB87248D6 Strider Returns (Journey from Darkness)/COUNTRY=US,EU/PRODUCT_NO=T-79048,79048,79048-50 GG b421c057 96BD12C62621B8D6 Striker/COUNTRY=EU/PRODUCT_NO=2551-50 +GG 0e098f92 F4782D31A464BB73 Super 5 in 1 Game Gear [Mortal Kombat] [Super 12 in 1]/EMU_MAPPER=28 +GG 55d04386 97D2BF32485053BB Super 7 in 1 Game Gear [Bare Knuckle 2] [Super 12 in 1]/EMU_MAPPER=28 +GG f56d3219 8B4AEC63ECB40E2E Super 12 in 1 Game Gear [Bare Knuckle 2]/EMU_MAPPER=28 +GG 2ff576fa 8B4AEC63ECB40E2E Super 12 in 1 Game Gear [Mortal Kombat]/EMU_MAPPER=28 +GG 05539043 7AAAB32E98A513AB Super 21 in 1 [Pacmania] [Super 53 in 1]/EMU_MAPPER=41 +GG 3b87194e 040AB4999C343E97 Super 32 in 1 [Alien 3] [Super 53 in 1]/EMU_MAPPER=41 +GG 55b18291 7EB467C734D95142 Super 53 in 1 [Alien 3]/EMU_MAPPER=41 +GG 83c15a37 F85E1AF5CC7E64ED Super 53 in 1 [Pacmania]/EMU_MAPPER=41 +GG 179f3519 CDAB487A05130DA1 Super 68 in 1 [Simpson]/EMU_MAPPER=41 GG 73d6745a 18CC99C9849C9901 Super Battletank/COUNTRY=US/PRODUCT_NO=1239 GG 8ba43af3 DAA4C785B7042952 Super Columns/COUNTRY=US,EU/PRODUCT_NO=2449,2449-50 GG 2a100717 E7260408CEC8EE63 Super Columns/COUNTRY=JP/PRODUCT_NO=G-3226 +GG 7cc51c51 6727345FC46B6C44 Super Game Gear 9 in 1 [Sonic II]/EMU_MAPPER=43 +GG 5585010f ADC7A676E4A80ADA Super Game Gear 73 in 1 [Sonic 2]/EMU_MAPPER=33 +GG ec7240f1 ADC7A676E4A80ADA Super Game Gear 73 in 1 [Street Fighter 2]/EMU_MAPPER=34 +GG 696b1789 376AE3342E2149B0 Super Gear 20 in 1 [Ninja Gaiden]/EMU_MAPPER=31 +GG 67a43451 306E7F66E4B6F9EA Super Gear 23 in 1 [Ninja Gaiden]/EMU_MAPPER=36 +GG c818109d 8CDA5761ECE8A46A Super GG 15 [Cliffhanger] [Gold & Yellow Label]/EMU_MAPPER=29 +GG 079e81c7 A4D60FD57EA08DF7 Super GG 15 [Last Action] [Super GG 30 Gold & Green Label]/EMU_MAPPER=35 +GG ddd38967 F9DF6ACEEED956D3 Super GG 15 in 1 [Sonic 5]/EMU_MAPPER=38/COMMENT=Multicart has a bug. Launches Bank Panic in native GG mode. Change the byte at linear ROM address 0xE324 from 0x8F to 0x4F to fix it. +GG b0a898d4 61346F715403E054 Super GG 21 in 1 [Sonic Drift] [Gold & Yellow Label]/EMU_MAPPER=33 +GG 5346f695 30B066366A883161 Super GG 30 [Last Action] [Gold & Green Label]/EMU_MAPPER=35 +GG a60037d5 58B43BDEE1635740 Super GG 30 in 1 [Sonic 2] [Gold & Yellow Label]/EMU_MAPPER=33 +GG 99ee7296 8F378BEF3668D84A Super GG 68 in 1 [Sonic Adventure]/EMU_MAPPER=32 GG 528cbbce FAE75543A7740E5E Super Golf/COUNTRY=JP/PRODUCT_NO=T-26017,T-26027 +GG 30747b3e 0F6C5B53A79F0F82 Super GG 18 in 1 [Nettou Samurai]/EMU_MAPPER=37 GG 73df5a15 43574420E8CF212A Superman - The Man of Steel/COUNTRY=EU/PRODUCT_NO=T-70068,70068-00 GG aa3f2172 0A5C6040EBCF152B Superman - The Man of Steel [Proto]/FLAGS=PROTO/COMMENT=Prototype version of the game. GG b731bb80 A220C02C0082E6EA Super Momotarou Dentetsu III/COUNTRY=JP/PRODUCT_NO=T-143017 @@ -1332,6 +1379,7 @@ GG a1453efa D9F631F59C7933C3 Tom and Jerry: The Movie/COUNTRY=JP,BR/PRODUCT_N GG 5cd33ff2 DC1F080D96A53D78 Tom and Jerry: The Movie/COUNTRY=US,EU/PRODUCT_NO=2434 GG 5bcf9b97 F9471D41510253BC Torarete Tamaruka!?/COUNTRY=JP/PRODUCT_NO=G-3348 GG 5173b02a B31BDB3827A8440C True Lies/COUNTRY=US,EU,JP/PRODUCT_NO=T-81318,T-81318-50,T-81167 +GG 763b5d62 BD832687D3D0244C Turbo 9 in 1 [Street Fighter 2]/EMU_MAPPER=30 GG 820965a3 78192012DB30BF73 Ultimate Soccer/COUNTRY=JP,EU,BR/PRODUCT_NO=G-3333,075300 GG 185e9fc1 07D77087D26DD517 Urban Strike/COUNTRY=US/PRODUCT_NO=T-100048 GG 7ec64025 84C269594C15F3A4 Vampire - Master of Darkness/COUNTRY=US/PRODUCT_NO=2437/COMMENT=US version of "In the Wake of Vampire" (Japan) and "Master of Darkness" (Europe). @@ -1401,11 +1449,13 @@ GG 231e5b78 E4B611A11356D972 VR Troopers/FLAGS=BAD/COUNTRY=US,EU/COMMENT=2 ba ; Hacks GG 90d40776 8A8E033FAF71E0A6 Lion King, The (Disney's) [Hack]/COUNTRY=US/FLAGS=HACK/COMMENT=Hack of the game. Include a cheat trainer. GG 040512ce 8B8D0340AF70E0A6 Lion King, The (Disney's) [Hack]/COUNTRY=EU/FLAGS=HACK/COMMENT=Hack of the game. Include a cheat trainer. +GG 445e468a F9DF6BCEEDD956D3 Super GG 15 in 1 [Sonic 5] (Unl) [HACK+MODEFIX]/EMU_MAPPER=38/FLAGS=HACK/COMMENT=Hack of the multicart. Launches Bank Panic in SMS-GG mode. ; Homebrews GG 820ceb2c 30002377B9BF704E Chaos/FLAGS=HOMEBREW/AUTHORS=Charles Doty (Raster) & Pickster GG dbdb3a2e 707D62A152450079 Frog/FLAGS=HOMEBREW/VERSION=2/AUTHORS=Charles Doty GG f366b29d 8A4C513A5DD6DD8F Windows for the GG/FLAGS=HOMEBREW/VERSION=4/AUTHORS=Victor Klemp +GG 95f353a4 C8CDF06A6E698BAF 2404e9ea7e6e520b93a7c24ba49556af01900fd0/FLAGS=HOMEBREW/EMU_MAPPER=127/AUTHORS=58a40bad2aa4061961c945795d6bb66abf8b1b8f/VERSION=2021-12-31 ;----------------------------------------------------------------------------- ; DATA - SEGA GAME 1000 (SG-1000) diff --git a/meka/srcs/machine.cpp b/meka/srcs/machine.cpp index f23e934f..a94eb3f3 100644 --- a/meka/srcs/machine.cpp +++ b/meka/srcs/machine.cpp @@ -22,6 +22,7 @@ #include "tvtype.h" #include "sound/fmunit.h" #include "sound/psg.h" +#include "app_game.h" //----------------------------------------------------------------------------- // Data @@ -196,6 +197,75 @@ void Machine_Set_Handler_MemRW(void) case MAPPER_SMS_Korean_MSX_32KB_2000: WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_32KB_2000; break; + case MAPPER_GG_Super_GG_15_BFFF_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_GG_15_BFFF_FFFF; + break; + case MAPPER_GG_Super_12_in_1_FFFE: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_12_in_1_FFFE; + break; + case MAPPER_GG_Turbo_9_in_1_8000_4000: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Turbo_9_in_1_8000_4000; + break; + case MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Gear_20_in_1_FFFF_FFFE_button; + break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF; + break; + case MAPPER_GG_Super_73_in_1_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_73_in_1_FFFE_FFFF; + break; + case MAPPER_GG_Super_73_in_1_8000_4000: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_73_in_1_8000_4000; + break; + case MAPPER_GG_Super_GG_30_1FFx_FFFx: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_GG_30_1FFx_FFFx; + break; + case MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_Gear_23_in_1_FFFE_FFFF; + break; + case MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_GG_18_in_1_FFF8_FFFE; + break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1; + break; + case MAPPER_SMS_Korean_SMS_32KB_2000: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_SMS_32KB_2000; + break; + case MAPPER_SMS_Korean_MSX_SMS_8000: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_SMS_8000; + break; + case MAPPER_GG_Super_68_in_1_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_68_in_1_FFFE_FFFF; + break; + case MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Gear_6_in_1_FFFE_FFF7_FFFF; + break; + case MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Super_9_in_1_FFFE_FFF7_FFFF; + break; + case MAPPER_SMS_Korean_MSX_16KB_BFFE: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_16KB_BFFE; + break; + case MAPPER_SMS_Korean_MSX_16KB_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Korean_MSX_16KB_FFFF; + break; + case MAPPER_SMS_Meta_Power_FFFF_HiCom: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Meta_Power_FFFF_HiCom; + break; + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + WrZ80 = WrZ80_NoHook = Write_Mapper_SMS_Power_256KB_FFFF_FFFE; + break; + case MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_48_in_1_FFF8_FFF9_FFFE_FFFF; + break; + case MAPPER_GG_18_in_1_00xx: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_18_in_1_00xx; + break; + case MAPPER_GG_Homebrew_FFF2: + WrZ80 = WrZ80_NoHook = Write_Mapper_GG_Homebrew_FFF2; + break; } } @@ -485,6 +555,432 @@ void Machine_Set_Mapping (void) g_machine.mapper_regs[0] = 0; break; + case MAPPER_GG_Super_GG_15_BFFF_FFFF: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 4; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_12_in_1_FFFE: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + break; + + case MAPPER_GG_Turbo_9_in_1_8000_4000: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[0] = 0x80; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button: + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + if (SRAM[0x7FFF] != 0xAA) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = 0x00; + } else { + // FIXME: don't know yet how the mapper decides which games are which sizes + if (SRAM[0x7FFE] <= 0x1F) { + SRAM[0x7FFE] += 0x08; + } else { + SRAM[0x7FFE] += 0x02; + } + SRAM[0x7FFE] = ((SRAM[0x7FFE] * 2) & tsms.Pages_Mask_8k) / 2; + } + g_machine.mapper_regs[0] = SRAM[0x7FFE]; + Map_8k_ROM(0, ((g_machine.mapper_regs[0]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((g_machine.mapper_regs[0]) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((g_machine.mapper_regs[0] + 1) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((g_machine.mapper_regs[0] + 1) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((g_machine.mapper_regs[0]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((g_machine.mapper_regs[0]) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + // FIXME: don't know yet how the mapper decides which games need SMS-GG mode + if ((g_machine.mapper_regs[0] <= 0x1F) | ((g_machine.mapper_regs[0] >= 0x38) && (g_machine.mapper_regs[0] <= 0x3D))) { + drv_set(DRV_GG); + } else { + drv_set(DRV_SMS); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 6; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_73_in_1_FFFE_FFFF: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_73_in_1_8000_4000: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[1] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_GG_30_1FFx_FFFx: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 6; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF: + Map_8k_ROM(0, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x80 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 5; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_SMS_Korean_SMS_32KB_2000: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 1; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + break; + + case MAPPER_SMS_Korean_MSX_SMS_8000: + Map_8k_ROM(0, 0x3c & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x3c & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 2 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 1; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + break; + + case MAPPER_GG_Super_68_in_1_FFFE_FFFF: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 4; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[2] = 1; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + break; + + case MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_SMS_Korean_MSX_16KB_BFFE: + case MAPPER_SMS_Korean_MSX_16KB_FFFF: + Map_8k_ROM(0, (0x20 * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((0x20 * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 1; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + break; + + case MAPPER_SMS_Meta_Power_FFFF_HiCom: + if (true) { + // FIXME: Right now this uses reset rather than power-cycle to + // trigger the outer multicart cycling. This is because Meka + // does not yet have hooks for mappers to respond reliably to + // power-cycling, nor does it have key bindings to allow easy + // use of power-cycling multicarts + g_machine.mapper_regs_count = 2; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + if (SRAM[0x7FFF] != 0xAA) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = 0x00; + } else { + SRAM[0x7FFE] += 0x04; + SRAM[0x7FFE] = ((SRAM[0x7FFE] * 4) & tsms.Pages_Mask_8k) / 4; + } + g_machine.mapper_regs[0] = SRAM[0x7FFE]; + unsigned int base_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 4; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + } + break; + + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + if (true) { + // FIXME: Right now this uses reset rather than power-cycle to + // trigger the outer multicart cycling. This is because Meka + // does not yet have hooks for mappers to respond reliably to + // power-cycling, nor does it have key bindings to allow easy + // use of power-cycling multicarts + g_machine.mapper_regs_count = 3; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[1] = 1; + if (SRAM[0x7FFF] != 0xAA) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = 0x00; + } else { + SRAM[0x7FFE] += 0x10; + SRAM[0x7FFE] = ((SRAM[0x7FFE] * 2) & tsms.Pages_Mask_8k) / 2; + } + g_machine.mapper_regs[0] = SRAM[0x7FFE]; + unsigned int base_page_8k = g_machine.mapper_regs[0] * 2; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + } + break; + + case MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF: + g_machine.mapper_regs_count = 4; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[0] = 0x1F; + g_machine.mapper_regs[3] = 1; + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + break; + + case MAPPER_GG_18_in_1_00xx: + Map_8k_ROM(0, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 1 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 2 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 3 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 1 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 1; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + drv_set(DRV_GG); + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + break; + + case MAPPER_GG_Homebrew_FFF2: + Map_8k_ROM(0, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x01 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x02 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x03 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x00 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x01 & tsms.Pages_Mask_8k); + Map_8k_RAM(6, 0); + Map_8k_RAM(7, 0); + g_machine.mapper_regs_count = 1; + for (int i = 0; i != MAPPER_REGS_MAX; i++) + g_machine.mapper_regs[i] = 0; + g_machine.mapper_regs[0] = 2; + break; + case MAPPER_SC3000_Survivors_Multicart: g_machine.mapper_regs_count = 1; for (int i = 0; i != MAPPER_REGS_MAX; i++) @@ -582,6 +1078,18 @@ void Machine_Set_TV_Lines(void) g_machine.TV_lines = g_machine.TV->screen_lines; } +// RESET EMULATED CPU --------------------------------------------------------- +void Machine_Reset_Z80(void) +{ +#ifdef MARAT_Z80 + ResetZ80 (&sms.R); +#elif MAME_Z80 + z80_reset (NULL); +#elif RAZE_Z80 + z80_reset(); +#endif +} + // RESET EMULATED MACHINE ----------------------------------------------------- void Machine_Reset(void) { diff --git a/meka/srcs/machine.h b/meka/srcs/machine.h index c5d45054..b0357983 100644 --- a/meka/srcs/machine.h +++ b/meka/srcs/machine.h @@ -17,6 +17,7 @@ void Machine_Pause (void); void Machine_Debug_Start (void); void Machine_Debug_Stop (void); void Machine_Reset (void); +void Machine_Reset_Z80 (void); void Machine_Set_Mapper (void); void Machine_Set_Mapping (void); diff --git a/meka/srcs/mappers.cpp b/meka/srcs/mappers.cpp index 00bf3386..d2e0c9dc 100644 --- a/meka/srcs/mappers.cpp +++ b/meka/srcs/mappers.cpp @@ -14,6 +14,9 @@ #include "shared.h" #include "mappers.h" #include "eeprom.h" +#include "vdp.h" +#include "video.h" +#include "app_game.h" //----------------------------------------------------------------------------- // Data @@ -952,6 +955,1174 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000) Write_Error (Addr, Value); } +// Mapper #28 +// +// Super 5 in 1 Game Gear [Mortal Kombat] [Super 12 in 1] +// Super 7 in 1 Game Gear [Bare Knuckle 2] [Super 12 in 1] +// Super 12 in 1 Game Gear [Mortal Kombat] (Unl) +// Super 12 in 1 Game Gear [Bare Knuckle 2] (Unl) +WRITE_FUNC (Write_Mapper_GG_Super_12_in_1_FFFE) +{ + if ((Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + int in_menu_mode = (g_machine.mapper_regs[0] & 0x08) == 0x00; + if (Addr == 0xFFFE) { + if (in_menu_mode && ((Value & 0xF0) == 0x40)) { + g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0x1E) | (Value & 0x0E) << 4 | (Value & 0x01); + } else if (in_menu_mode && ((Value & 0xE0) == 0x00)) { + g_machine.mapper_regs[0] = (g_machine.mapper_regs[0] & 0xF0) | ((Value & 0x10) >> 4); + } else { + g_machine.mapper_regs[2] = Value & 0x1F; + } + } + if (Addr == 0xFFFF) { + if (in_menu_mode && ((Value & 0xF0) == 0x40)) { + g_machine.mapper_regs[0] |= 0x08; + in_menu_mode = 0; + } else if ((!in_menu_mode) && ((Value & 0xE0) == 0xE0)) { + // Meka extension: this is used to reliably reset the + // mapper to menu mode when loading save states + g_machine.mapper_regs[0] &= ~0x08; + in_menu_mode = 1; + } + g_machine.mapper_regs[1] = Value & 0x1F; + } + const int effective_mapbase = (g_machine.mapper_regs[0] & 0xF0) | ((g_machine.mapper_regs[0] & 0x01) << 4); + const int fixed_or_reg1 = in_menu_mode ? 1 : (g_machine.mapper_regs[2] & 0x1F); + const int fixed_or_reg0 = in_menu_mode ? 0 : (g_machine.mapper_regs[1] & 0x1F); + Map_8k_ROM(0, (effective_mapbase << 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((effective_mapbase << 1) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((effective_mapbase | fixed_or_reg1) << 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((effective_mapbase | fixed_or_reg1) << 1) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((effective_mapbase | fixed_or_reg0) << 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((effective_mapbase | fixed_or_reg0) << 1) | 1) & tsms.Pages_Mask_8k); + //return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #29 +// Super GG 15 [Cliffhanger] [Gold & Yellow Label] +WRITE_FUNC(Write_Mapper_GG_Super_GG_15_BFFF_FFFF) +{ + // TODO: implement the various restrictions found in the hardware, + // e.g. requiring mode bit 0x04 to access the second 512KB of the + // ROM. + if ((Addr == 0xBFFF) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xBFFF) { + unsigned int high_page_offset = 0; + if (g_machine.mapper_regs[0] == 0x0c) { + unsigned int mask = (g_machine.mapper_regs[1] & 0xF0) ? 0xF0 : 0xFE; + g_machine.mapper_regs[3] = g_machine.mapper_regs[1] & mask; + if (mask == 0xF0) { + high_page_offset = g_machine.mapper_regs[1] & 0x0F; + } + } + g_machine.mapper_regs[0] = Value; + g_machine.mapper_regs[1] = high_page_offset; + g_machine.mapper_regs[2] = 1; + if (Value & 0x10) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } + else if (Addr == 0xFFFF) + { + g_machine.mapper_regs[1] = Value; + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + } + Map_8k_ROM(0, (g_machine.mapper_regs[3] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (g_machine.mapper_regs[3] * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (g_machine.mapper_regs[3] * 2 + g_machine.mapper_regs[2] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (g_machine.mapper_regs[3] * 2 + g_machine.mapper_regs[2] * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (g_machine.mapper_regs[3] * 2 + g_machine.mapper_regs[1] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (g_machine.mapper_regs[3] * 2 + g_machine.mapper_regs[1] * 2 + 1) & tsms.Pages_Mask_8k); + if (Addr == 0xBFFF) { + // no RAM shadowing for writes to this address + return; + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #30 +// Turbo 9 in 1 [Street Fighter 2] +WRITE_FUNC(Write_Mapper_GG_Turbo_9_in_1_8000_4000) +{ + if (Addr == 0x8000 || Addr == 0x4000) // Configurable segment ----------------------------------------------- + { + if (Addr == 0x8000) { + g_machine.mapper_regs[1] = Value; + } + if (Addr == 0x4000) { + g_machine.mapper_regs[2] = Value; + } + if ((g_machine.mapper_regs[2] == 0x11) && (g_machine.mapper_regs[0] == 0x80)) { + // use of 0x80 to signal the initial state is a Meka + // extension but does not conflict with the menu code's + // use of the mapper + g_machine.mapper_regs[0] = g_machine.mapper_regs[1]; + g_machine.mapper_regs[1] = 0; + g_machine.mapper_regs[2] = 1; + } else if ((g_machine.mapper_regs[2] == 0x11) && (g_machine.mapper_regs[1] == 0x80)) { + // use of 0x80 to return to the initial state is a Meka + // extension but does not conflict with the menu code's + // use of the mapper, nor does it conflict with the one + // game that uses the mapper + g_machine.mapper_regs[0] = 0x80; + g_machine.mapper_regs[1] = 0; + g_machine.mapper_regs[2] = 1; + } + Map_8k_ROM(0, (g_machine.mapper_regs[0] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (g_machine.mapper_regs[0] * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2 + 1) & tsms.Pages_Mask_8k); + // It is unclear how the cartridge decides whether to switch + // from native GG mode (which is the power-on default) to + // SMS-GG mode, but it appears to happen at the moment 0x11 is + // written to 0x4000 *unless* 0x0a was the most recent value + // previously written to 0x4000. + if ((g_machine.mapper_regs[0] != 0x80) && (g_machine.mapper_regs[0] != 0x0a)) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #31 +// Super Gear 20 in 1 [Ninja Gaiden] +WRITE_FUNC(Write_Mapper_GG_Gear_20_in_1_FFFF_FFFE_button) +{ + // FIXME: don't know yet how the mapper decides which games need SMS-GG mode + if ((g_machine.mapper_regs[0] <= 0x1F) | ((g_machine.mapper_regs[0] >= 0x38) && (g_machine.mapper_regs[0] <= 0x3D))) { + drv_set(DRV_GG); + } else { + drv_set(DRV_SMS); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + if (Addr == 0xFFFF) // Configurable segment ----------------------------------------------- + { + g_machine.mapper_regs[1] = Value; + Map_8k_ROM(4, ((g_machine.mapper_regs[0] + Value) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((g_machine.mapper_regs[0] + Value) * 2 + 1) & tsms.Pages_Mask_8k); + //return; + } + if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + Map_8k_ROM(2, ((g_machine.mapper_regs[0] + Value) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((g_machine.mapper_regs[0] + Value) * 2 + 1) & tsms.Pages_Mask_8k); + //return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #32 +// Super GG 68 in 1 [Sonic Adventure] +// GG Super 56 in 1 (B) [Mega Man] +WRITE_FUNC(Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF) +{ + if ((Addr == 0xFFF8) || (Addr == 0xFFF9) || (Addr == 0xFFFA) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF8) { + g_machine.mapper_regs[5] = Value; + } else if (Addr == 0xFFF9) { + g_machine.mapper_regs[4] = Value; + } else if (Addr == 0xFFFA) { + g_machine.mapper_regs[3] = Value; + g_machine.mapper_regs[0] = 0x40; + } else if (Addr == 0xFFFE) { + g_machine.mapper_regs[2] = Value; + if ((Value == 0x01) && (g_machine.mapper_regs[0] == 0x40)) { + bool second_megabyte_active = (g_machine.mapper_regs[4] & 0x12) || (g_machine.mapper_regs[3] & 0x04); + bool sega_mapper_active = (g_machine.mapper_regs[4] & 0x1E) || (g_machine.mapper_regs[3] & 0x04); + g_machine.mapper_regs[0] = (g_machine.mapper_regs[5] & 0x1F) | (second_megabyte_active ? 0x20 : 0x00) | (sega_mapper_active ? 0x80 : 0x00); + } + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[1] = Value; + } + if (1) { + bool sega_mapper_active = g_machine.mapper_regs[0] & 0x80; + bool second_megabyte_active = g_machine.mapper_regs[0] & 0x20; + unsigned int sega_mapper_mask = sega_mapper_active ? (second_megabyte_active ? 0x1F : 0x0F) : 0x01; + unsigned int page_0000_8k = (g_machine.mapper_regs[0] & 0x3F) * 4; + unsigned int page_4000_8k = page_0000_8k + ((g_machine.mapper_regs[2] & sega_mapper_mask) * 2); + unsigned int page_8000_8k = page_0000_8k + ((g_machine.mapper_regs[1] & sega_mapper_mask) * 2); + Map_8k_ROM(0, page_0000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (page_0000_8k | 0x01) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, page_4000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (page_4000_8k | 0x01) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, page_8000_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (page_8000_8k | 0x01) & tsms.Pages_Mask_8k); + } + bool sms_gg_mode_active = (g_machine.mapper_regs[4] & 0x80) || (g_machine.mapper_regs[3] & 0x01); + if (sms_gg_mode_active) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + //return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #33 +// Super Game Gear 73 in 1 [Sonic 2] +WRITE_FUNC(Write_Mapper_GG_Super_73_in_1_FFFE_FFFF) +{ + if ((Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFFE) { + g_machine.mapper_regs[2] = Value; + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[1] = Value; + } + if (! (g_machine.mapper_regs[0] & 0x40)) { + // "menu" mapping mode + if (g_machine.mapper_regs[2] & 0x40) { + // high-part mapper write + g_machine.mapper_regs[0] = (g_machine.mapper_regs[2] & 0x08) ? 0x80 : 0x00; // SMS-GG mode flag + // upper two bits of MAPBASE + g_machine.mapper_regs[0] &= ~0x30; + g_machine.mapper_regs[0] |= (g_machine.mapper_regs[2] & 0x06) << 3; + } else { + // low-part mapper write (lower four bits of MAPBASE) + g_machine.mapper_regs[0] &= ~0x0F; + g_machine.mapper_regs[0] |= (g_machine.mapper_regs[2] & 0x1E) >> 1; + } + if (g_machine.mapper_regs[1] & 0x40) { + // switch to "game" mapping mode + g_machine.mapper_regs[0] |= 0x40; + g_machine.mapper_regs[1] = 0; + g_machine.mapper_regs[2] = 1; + } + } + unsigned int mapbase_16k = 0; + unsigned int page_4000_offset_16k = 1; + unsigned int page_8000_offset_16k = 0; + bool game_mapping_mode = g_machine.mapper_regs[0] & 0x40; + if (game_mapping_mode) { + mapbase_16k = (g_machine.mapper_regs[0] & 0x3F) * 2; + page_4000_offset_16k = g_machine.mapper_regs[2]; + page_8000_offset_16k = g_machine.mapper_regs[1]; + } + Map_8k_ROM(0, (mapbase_16k * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (mapbase_16k * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((mapbase_16k + page_4000_offset_16k) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((mapbase_16k + page_4000_offset_16k) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((mapbase_16k + page_8000_offset_16k) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((mapbase_16k + page_8000_offset_16k) * 2 + 1) & tsms.Pages_Mask_8k); + bool sms_gg_mode_active = g_machine.mapper_regs[0] & 0x80; + if (sms_gg_mode_active) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + //return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #34 +// Super Game Gear 73 in 1 [Street Fighter 2] +WRITE_FUNC(Write_Mapper_GG_Super_73_in_1_8000_4000) +{ + if ((Addr == 0x8000) || (Addr == 0x4000)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0x8000) { + g_machine.mapper_regs[2] = Value; + } else if (Addr == 0x4000) { + g_machine.mapper_regs[1] = Value; + } + if (! (g_machine.mapper_regs[0] & 0x40)) { + // "menu" mapping mode + if (g_machine.mapper_regs[2] & 0x40) { + // high-part mapper write + g_machine.mapper_regs[0] = (g_machine.mapper_regs[2] & 0x08) ? 0x80 : 0x00; // SMS-GG mode flag + // upper two bits of MAPBASE + g_machine.mapper_regs[0] &= ~0x30; + g_machine.mapper_regs[0] |= (g_machine.mapper_regs[2] & 0x06) << 3; + } else { + // low-part mapper write (lower four bits of MAPBASE) + g_machine.mapper_regs[0] &= ~0x0F; + g_machine.mapper_regs[0] |= (g_machine.mapper_regs[2] & 0x1E) >> 1; + } + if (g_machine.mapper_regs[1] & 0x40) { + // switch to "game" mapping mode + g_machine.mapper_regs[0] |= 0x40; + g_machine.mapper_regs[2] = 0; + g_machine.mapper_regs[1] = 1; + } + } + unsigned int mapbase_16k = 0; + unsigned int page_4000_offset_16k = 1; + unsigned int page_8000_offset_16k = 0; + bool game_mapping_mode = g_machine.mapper_regs[0] & 0x40; + if (game_mapping_mode) { + mapbase_16k = (g_machine.mapper_regs[0] & 0x3F) * 2; + page_4000_offset_16k = g_machine.mapper_regs[1]; + page_8000_offset_16k = g_machine.mapper_regs[2]; + } + Map_8k_ROM(0, (mapbase_16k * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (mapbase_16k * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((mapbase_16k + page_4000_offset_16k) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((mapbase_16k + page_4000_offset_16k) * 2 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((mapbase_16k + page_8000_offset_16k) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((mapbase_16k + page_8000_offset_16k) * 2 + 1) & tsms.Pages_Mask_8k); + bool sms_gg_mode_active = g_machine.mapper_regs[0] & 0x80; + if (sms_gg_mode_active) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #35 +// Super GG 15 [Last Action] [Super GG 30 Gold & Green Label] +// Super GG 30 [Last Action] [Gold & Green Label] +WRITE_FUNC(Write_Mapper_GG_Super_GG_30_1FFx_FFFx) +{ + if ((Addr == 0x1FFE) || (Addr == 0xFFFE) || (Addr == 0xFFFF) || (Addr == 0x1FFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0x1FFF) { + // TODO: Value & 0x01 may be "Sega mode" mapper locking + // Value & 0x40 indicates chip select/output enable for 2nd half of each megabyte of ROM + // Value & 0x10 indicates SMS-GG mode as opposed to native GG mode + g_machine.mapper_regs[0] = Value; + if (Value & 0x10) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } + else if (Addr == 0x1FFE) + { + // Value & 0x10 indicates chip select/output enable for 2nd megabyte of ROM + g_machine.mapper_regs[1] = Value; + // Value & 0x04 indicates "Sega mode" as opposed to "menu mode" + } + else if (Addr == 0xFFFF) + { + g_machine.mapper_regs[2] = Value; + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[3] = Value; + } + if (g_machine.mapper_regs[1] & 0x04) { + // "menu mode" + g_machine.mapper_regs[4] = g_machine.mapper_regs[2] & 0xF0; + if (! (g_machine.mapper_regs[4] & 0x30)) { + g_machine.mapper_regs[4] = g_machine.mapper_regs[2] & 0xFE; + } + g_machine.mapper_regs[5] = g_machine.mapper_regs[3] & 0xF0; + if (! (g_machine.mapper_regs[5] & 0x30)) { + g_machine.mapper_regs[5] = g_machine.mapper_regs[3] & 0xFE; + } + } + unsigned int rom_chip_select_and_enable = ((g_machine.mapper_regs[1] & 0x10) ? 0x40 : 0x00) | ((g_machine.mapper_regs[0] & 0x40) ? 0x20 : 0x00); + Map_8k_ROM(0, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[5] * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[5] * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[5] * 2) | (g_machine.mapper_regs[3] * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[5] * 2) | (g_machine.mapper_regs[3] * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[4] * 2) | (g_machine.mapper_regs[2] * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((rom_chip_select_and_enable * 2) | (g_machine.mapper_regs[4] * 2) | (g_machine.mapper_regs[2] * 2) | 1) & tsms.Pages_Mask_8k); + if (Addr <= 0xBFFF) { + // no RAM shadowing for writes to this address + return; + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + + +// Mapper #36 +// Super Gear 23 in 1 [Ninja Gaiden] +WRITE_FUNC(Write_Mapper_GG_Super_Gear_23_in_1_FFFE_FFFF) +{ + if ((Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFFF) + { + g_machine.mapper_regs[1] = Value; + if (! (g_machine.mapper_regs[0] & 0x80)) { + // "menu mode" + if (Value & 0x08) { + // switch to "Sega mode" + g_machine.mapper_regs[0] |= 0x80; + g_machine.mapper_regs[2] = 1; + } + } + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + if (! (g_machine.mapper_regs[0] & 0x80)) { + // "menu mode" + if (Value & 0x08) { + g_machine.mapper_regs[0] &= 0xCF; + g_machine.mapper_regs[0] |= (Value & 0x03) << 4; + if (g_machine.mapper_regs[0] & 0x20) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } else if (Value & 0x04) { + g_machine.mapper_regs[0] &= 0xF3; + g_machine.mapper_regs[0] |= (Value & 0x03) << 2; + } else { + g_machine.mapper_regs[0] &= 0xFC; + g_machine.mapper_regs[0] |= Value & 0x03; + } + } + } + if (! (g_machine.mapper_regs[0] & 0x80)) { + // "menu mode" + Map_8k_ROM(0, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(2, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(3, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(4, 0x80 & tsms.Pages_Mask_8k); + Map_8k_ROM(5, 0x80 & tsms.Pages_Mask_8k); + } else { + // "Sega mode" + Map_8k_ROM(0, ((g_machine.mapper_regs[0] & 0x1F) * 4) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (((g_machine.mapper_regs[0] & 0x1F) * 4) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (((g_machine.mapper_regs[0] & 0x1F) * 4) | ((g_machine.mapper_regs[2] & 0x07) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((g_machine.mapper_regs[0] & 0x1F) * 4) | ((g_machine.mapper_regs[2] & 0x07) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (((g_machine.mapper_regs[0] & 0x1F) * 4) | ((g_machine.mapper_regs[1] & 0x07) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((g_machine.mapper_regs[0] & 0x1F) * 4) | ((g_machine.mapper_regs[1] & 0x07) * 2) | 1) & tsms.Pages_Mask_8k); + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #37 +// Super GG 18 in 1 [Nettou Samurai] +WRITE_FUNC (Write_Mapper_GG_Super_GG_18_in_1_FFF8_FFFE) +{ + if ((Addr == 0xFFF8) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF8) { + if (g_machine.mapper_regs[0] == 0x00) { + g_machine.mapper_regs[0] = Value; + if (Value & 0x18) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[1] = Value; + } else if (Addr == 0xFFFE) { + g_machine.mapper_regs[2] = Value; + } + Map_8k_ROM(0, (g_machine.mapper_regs[0] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((g_machine.mapper_regs[0] * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((g_machine.mapper_regs[0] | g_machine.mapper_regs[2]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((g_machine.mapper_regs[0] | g_machine.mapper_regs[2]) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((g_machine.mapper_regs[0] | g_machine.mapper_regs[1]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((g_machine.mapper_regs[0] | g_machine.mapper_regs[1]) * 2) | 1) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #38 +// Super GG 15 in 1 [Sonic 5] +WRITE_FUNC(Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1) +{ + if ((Addr == 0xFFF8) || (Addr == 0xFFF9) || (Addr == 0xFFFA) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF8) { + g_machine.mapper_regs[2] = Value; + Map_8k_ROM(0, (g_machine.mapper_regs[2] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((g_machine.mapper_regs[2] * 2) | 0x01) & tsms.Pages_Mask_8k); + } else if (Addr == 0xFFF9) { + g_machine.mapper_regs[3] = Value; + } else if (Addr == 0xFFFA) { + g_machine.mapper_regs[4] = Value; + if (Value & 0x40) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } else if (Addr == 0xFFFE) { + g_machine.mapper_regs[1] = (Value & ~g_machine.mapper_regs[3]) | (g_machine.mapper_regs[2] & g_machine.mapper_regs[3]); + Map_8k_ROM(2, (g_machine.mapper_regs[1] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((g_machine.mapper_regs[1] * 2) | 0x01) & tsms.Pages_Mask_8k); + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[0] = (Value & ~g_machine.mapper_regs[3]) | (g_machine.mapper_regs[2] & g_machine.mapper_regs[3]); + Map_8k_ROM(4, (g_machine.mapper_regs[0] * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((g_machine.mapper_regs[0] * 2) | 0x01) & tsms.Pages_Mask_8k); + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #39 +// 11 Hap Gam-Boy +WRITE_FUNC (Write_Mapper_SMS_Korean_SMS_32KB_2000) +{ + if (Addr == 0x2000) // Configurable segment ----------------------------------------------- + { + g_machine.mapper_regs[0] = Value; + Map_8k_ROM(0, (Value * 4) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (Value * 4 + 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (Value * 4 + 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (Value * 4 + 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (Value * 4) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (Value * 4 + 1) & tsms.Pages_Mask_8k); + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #40 +// Zemina Best 88 [MISSING-64K] (KR) +// Zemina Best 39 [Best 88] [MISSING 64K] (KR) +WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_SMS_8000) +{ + if (Addr == 0x8000) // Configurable segment ----------------------------------------------- + { + // Special case to support Zemina Best 25 [Best 88] (KR) + if (g_machine.mapper_regs[0] == 0xFF) { + Value ^= 0x22; + } + g_machine.mapper_regs[0] = Value; + if (Value & 0x80) { + Map_8k_ROM(0, (Value ^ 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (Value ^ 2) & tsms.Pages_Mask_8k); + } else { + Map_8k_ROM(0, 0x3c & tsms.Pages_Mask_8k); + Map_8k_ROM(1, 0x3c & tsms.Pages_Mask_8k); + } + Map_8k_ROM(2, (Value ^ 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (Value ^ 0) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (Value ^ 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (Value ^ 2) & tsms.Pages_Mask_8k); + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #41 +// Super 68 in 1 [Simpson] +WRITE_FUNC(Write_Mapper_GG_Super_68_in_1_FFFE_FFFF) +{ + if ((Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFFF) + { + g_machine.mapper_regs[1] = Value; + if (! (g_machine.mapper_regs[3] & 0x80)) { + // "menu mode" + if (Value & 0x08) { + g_machine.mapper_regs[1] = 0; + g_machine.mapper_regs[2] = 1; + // switch to "Sega mode" + g_machine.mapper_regs[3] |= 0x80; + bool sms_gg_mode = false; + if (g_machine.mapper_regs[3] & 0x08) { + // SMS-GG mode according to heuristic + int game_id_low = g_machine.mapper_regs[0] & 0x3F; + sms_gg_mode = (game_id_low < 0x14) || (game_id_low == 0x18) || (game_id_low == 0x28); + } else if (g_machine.mapper_regs[3] & 0x04) { + // SMS-GG mode according to game_id & 0x40 + sms_gg_mode = !! (g_machine.mapper_regs[0] & 0x40); + } else { + // SMS-GG mode according to game_id & 0x20 + // (game ID limited to six bits in this mode) + sms_gg_mode = !! (g_machine.mapper_regs[0] & 0x20); + } + if (sms_gg_mode) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + } + } + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + if (! (g_machine.mapper_regs[3] & 0x80)) { + // "menu mode" + if ((Value & 0x0C) == 0x0C) { + g_machine.mapper_regs[0] &= 0x3F; + g_machine.mapper_regs[0] |= (Value & 0x03) << 6; + + if (! (g_machine.mapper_regs[3] & 0x08)) { + // choose mechanism for SMS-GG mode signalling in non-heuristic mode: + // store "use game_id & 0x40" bit 0x04 in register 3 + g_machine.mapper_regs[3] = 0x04 | (g_machine.mapper_regs[3] & 0xF3); + } + } else if (Value & 0x08) { + g_machine.mapper_regs[0] &= 0xCF; + g_machine.mapper_regs[0] |= (Value & 0x03) << 4; + } else if (Value & 0x04) { + g_machine.mapper_regs[0] &= 0xF3; + g_machine.mapper_regs[0] |= (Value & 0x03) << 2; + } else { + g_machine.mapper_regs[0] &= 0xFC; + g_machine.mapper_regs[0] |= Value & 0x03; + // choose mechanism for SMS-GG mode signalling: + // store "use heuristic" as bit 0x08 in register 3 (and clear bit 0x04) + g_machine.mapper_regs[3] = (g_machine.mapper_regs[0] & 0x08) | (g_machine.mapper_regs[3] & 0xF3); + } + } + } + + unsigned int game_id = g_machine.mapper_regs[0]; + // when ROM is three megabytes it acts like 4MB layout A B C C + // NOTE: tsms.Pages_Count_8k is actually a maximum value -- not a count! + unsigned int game_id_mask = ((game_id & 0x40) && ((tsms.Pages_Count_8k + 1) / 4 == 0x60)) ? 0x5F : 0xFF; + unsigned int base_page_8k = (game_id & game_id_mask) * 4; + + // NOTE: 68-in-1 hardware masks pages with 0x07 for game_id + // less than 0x20 but 53-in-1 doesn't, and a wider mask + // doesn't break anything for 68-in-1 + unsigned int paging_mask = 0x0F; + + if (! (g_machine.mapper_regs[3] & 0x80)) { + // "menu mode" + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + } else { + // "Sega mode" + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | ((g_machine.mapper_regs[2] & paging_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | ((g_machine.mapper_regs[2] & paging_mask) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (base_page_8k | ((g_machine.mapper_regs[1] & paging_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | ((g_machine.mapper_regs[1] & paging_mask) * 2) | 1) & tsms.Pages_Mask_8k); + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #42 +// Gear 6 in 1 [Alien Syndrome] +WRITE_FUNC(Write_Mapper_GG_Gear_6_in_1_FFFE_FFF7_FFFF) +{ + if ((Addr == 0xFFF7) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF7) + { + if (! (g_machine.mapper_regs[0] & 0x80)) { + // switch from "menu" mapper mode to "Sega" mapper mode + g_machine.mapper_regs[0] = 0x80 | ((Value & 0x01) << 4) | (g_machine.mapper_regs[2] & 0x0F); + g_machine.mapper_regs[2] = 1; + } + } + else if (Addr == 0xFFFF) + { + g_machine.mapper_regs[1] = Value; + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + } + int mask = (g_machine.mapper_regs[0] & 0x80) ? 0x07 : 0x01; + Map_8k_ROM(0, ((g_machine.mapper_regs[0] & 0x1F) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (((g_machine.mapper_regs[0] & 0x1F) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (((g_machine.mapper_regs[0] & 0x1F) * 2) | ((g_machine.mapper_regs[2] & mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((g_machine.mapper_regs[0] & 0x1F) * 2) | ((g_machine.mapper_regs[2] & mask) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (((g_machine.mapper_regs[0] & 0x1F) * 2) | ((g_machine.mapper_regs[1] & mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((g_machine.mapper_regs[0] & 0x1F) * 2) | ((g_machine.mapper_regs[1] & mask) * 2) | 1) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #43 +// Super Game Gear 9 in 1 [Sonic II] +WRITE_FUNC(Write_Mapper_GG_Super_9_in_1_FFFE_FFF7_FFFF) +{ + if (((Addr == 0x0A7E) && (Value & 0x20)) || (Addr == 0xFFF7) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF7) + { + if (! (g_machine.mapper_regs[2])) { + g_machine.mapper_regs[0] |= Value; + } + } + else if (Addr == 0xFFFF) + { + g_machine.mapper_regs[1] = Value; + } + else if (Addr == 0xFFFE) + { + g_machine.mapper_regs[2] = Value; + } + bool force_reset = false; + if ((Addr == 0x0A7E) && (Value & 0x20)) { + // This seems to force a reset and apply the mapping + g_machine.mapper_regs[1] = 0; + g_machine.mapper_regs[2] = 1; + force_reset = true; + } + if (force_reset || (Addr == 0xFFFE) || (Addr == 0xFFFF)) { + int mapbase = g_machine.mapper_regs[0] & 0xFE; + Map_8k_ROM(0, (mapbase * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((mapbase * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, ((mapbase * 2) | ((g_machine.mapper_regs[2] & 0x1F) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((mapbase * 2) | ((g_machine.mapper_regs[2] & 0x1F) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, ((mapbase * 2) | ((g_machine.mapper_regs[1] & 0x1F) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((mapbase * 2) | ((g_machine.mapper_regs[1] & 0x1F) * 2) | 1) & tsms.Pages_Mask_8k); + } + if (g_machine.mapper_regs[0] & 0x01) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + if (force_reset) { + Machine_Reset_Z80(); + return; + } + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #44 +// Super Game 45 [Road Fighter] (KR) +WRITE_FUNC(Write_Mapper_SMS_Korean_MSX_16KB_BFFE) +{ + if (Addr == 0xBFFE) // Configurable segment ----------------------------------------------- + { + g_machine.mapper_regs[0] = Value; + unsigned int page_mask = ((Value & 0x3f) == 0x21) ? 0x3f : 0x1f; + Map_8k_ROM(2, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + if (Value & 0x20) { + // "Namco" mapping: A B B A + Map_8k_ROM(4, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + } else { + // normal mapping: A B A B + Map_8k_ROM(4, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + } + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #45 +// Super Game 30 [Road Fighter] [Super Game 45] (KR) +WRITE_FUNC(Write_Mapper_SMS_Korean_MSX_16KB_FFFF) +{ + if (Addr == 0xFFFF) // Configurable segment ----------------------------------------------- + { + g_machine.mapper_regs[0] = Value; + unsigned int page_mask = ((Value & 0x3f) == 0x21) ? 0x3f : 0x1f; + Map_8k_ROM(2, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + if (Value & 0x20) { + // "Namco" mapping: A B B A + Map_8k_ROM(4, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + } else { + // normal mapping: A B A B + Map_8k_ROM(4, (((Value & page_mask) * 2)) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (((Value & page_mask) * 2) | 1) & tsms.Pages_Mask_8k); + } + //return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #46 +// 12 in 1 [Hang On] [SMS-GG] +// Super 12 in 1 [Teddy Boy] [SMS-MD] +// +// It is no coincidence that this is very similar to +// Write_Mapper_SMS_Korean_FFFF_HiCom as this mapper is an extension +// of that one allowing power-cycle switching between multiple 128KB +// Hi-Com collections +WRITE_FUNC(Write_Mapper_SMS_Meta_Power_FFFF_HiCom) +{ + if (Addr == 0xFFFF) // Frame 2 ----------------------------------------------- + { + g_machine.mapper_regs[1] = Value & 3; + unsigned int base_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 4; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #47 +// Super 2 in 1 - Sonic & Alien Storm [SMS-GG] +// Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG] +WRITE_FUNC(Write_Mapper_SMS_Power_256KB_FFFF_FFFE) +{ + if (Addr == 0xFFFF) // Upper reconfigurable segment ----------------------------------------------- + { + g_machine.mapper_regs[1] = Value & 0x0f; + unsigned int upper_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 2; + Map_8k_ROM(4, upper_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (upper_page_8k | 1) & tsms.Pages_Mask_8k); + } + else if (Addr == 0xFFFE) // Lower reconfigurable segment ----------------------------------------------- + { + g_machine.mapper_regs[2] = Value & 0x0f; + unsigned int lower_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[2]) * 2; + Map_8k_ROM(2, lower_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (lower_page_8k | 1) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #48 +// GG 48 in 1 [Doraemon 2] +WRITE_FUNC (Write_Mapper_GG_48_in_1_FFF8_FFF9_FFFE_FFFF) +{ + // Mapper register allocations: + // - Mode and mask: g_machine.mapper_regs[0] + // Bits 0xE0: configuration mode + // - 0x00: not in configuration mode + // - 0x80: expecting paging mask [step 1] + // - 0x40: expecting lower 5 bits of base page [step 2] + // - 0x20: expecting upper 3 bits of base page [step 3] + // - 0xE0: not expecting further configuration bytes + // Bits 0x1F: 16KB paging mask + // - Base page: g_machine.mapper_regs[1] + // Bits 0xFF: 16KB base page + // - Upper Sega paging register: g_machine.mapper_regs[2] + // Bits 0x1F: 16KB page offset for region 0x8000..0xBFFF + // - Lower Sega paging register: g_machine.mapper_regs[3] + // Bits 0x1F: 16KB page offset for region 0x4000..0x7FFF + if ((Addr == 0xFFF8) || (Addr == 0xFFF9) || (Addr == 0xFFFE) || (Addr == 0xFFFF)) // Configurable segment ----------------------------------------------- + { + if (Addr == 0xFFF8) { + // lock mapper + g_machine.mapper_regs[0] &= 0x1F; + if (Value & 0x10) { + // unlock mapper, expect paging mask next + g_machine.mapper_regs[0] |= 0x80; + } + } else if (Addr == 0xFFF9) { + if ((g_machine.mapper_regs[0] & 0xE0) == 0x80) { + // expecting paging mask + g_machine.mapper_regs[0] &= 0xE0; + g_machine.mapper_regs[0] |= Value & 0x1F; + // expect lower 5 bits of base page next + g_machine.mapper_regs[0] &= 0x1F; + g_machine.mapper_regs[0] |= 0x40; + } else if ((g_machine.mapper_regs[0] & 0xE0) == 0x40) { + // expecting lower 5 bits of base page + g_machine.mapper_regs[1] &= 0xE0; + g_machine.mapper_regs[1] |= Value & 0x1F; + // expect upper 3 bits of base page next + g_machine.mapper_regs[0] &= 0x1F; + g_machine.mapper_regs[0] |= 0x20; + } else if (((g_machine.mapper_regs[0] & 0xE0) == 0x20) && ((Value & 0x18) == 0x18)) { + // expecting upper 3 bits of base page + g_machine.mapper_regs[1] &= 0x1F; + g_machine.mapper_regs[1] |= (Value & 0x07) << 5; + // subsequent writes to 0xFFF9 ignored + g_machine.mapper_regs[0] &= 0x1F; + g_machine.mapper_regs[0] |= 0xE0; + } + } else if (Addr == 0xFFFF) { + g_machine.mapper_regs[2] = Value; + } else if (Addr == 0xFFFE) { + g_machine.mapper_regs[3] = Value; + } + unsigned int paging_mask = g_machine.mapper_regs[0] & 0x1F; + unsigned int base_page_16k = g_machine.mapper_regs[1]; + unsigned int upper_page_16k = base_page_16k + (g_machine.mapper_regs[2] & paging_mask); + unsigned int lower_page_16k = base_page_16k + (g_machine.mapper_regs[3] & paging_mask); + Map_8k_ROM(0, (base_page_16k * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((base_page_16k * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (lower_page_16k * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, ((lower_page_16k * 2) | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, (upper_page_16k * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(5, ((upper_page_16k * 2) | 1) & tsms.Pages_Mask_8k); + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + +// Mapper #49 +// 18 in 1 - Super Games Collection [Columns] +WRITE_FUNC (Write_Mapper_GG_18_in_1_00xx) +{ + // FIXME: It is likely the actual hardware does not completely + // decode the address bits, but the effective mapper address + // decoding mask is not yet known + if ((Addr | 0x001F) == 0x001F) // Configurable segment ----------------------------------------------- + { + g_machine.mapper_regs[0] = Addr & 0x1F; + if (Addr & 0x10) { + drv_set(DRV_SMS); + } else { + drv_set(DRV_GG); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + unsigned int base_page_8k = (Addr & 0x0F) * 4; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + Map_8k_ROM(2, (base_page_8k | 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(3, (base_page_8k | 3) & tsms.Pages_Mask_8k); + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + return; + } + + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages[6][Addr] = Value; return; + case 7: Mem_Pages[7][Addr] = Value; return; + } + + Write_Error(Addr, Value); +} + +// Mapper #127 +// 2404e9ea7e6e520b93a7c24ba49556af01900fd0 +WRITE_FUNC (Write_Mapper_GG_Homebrew_FFF2) +{ + if (Addr == 0xFFF2) { + // 0xFFF2: Map 16KB page at 0x8000-0xBFFF + RAM [0x1FFF] = g_machine.mapper_regs[2] = Value & tsms.Pages_Mask_16k; + Map_16k_ROM (4, g_machine.mapper_regs[2] * 2); + } + + // RAM ----------------------------------------------------------------------- + switch (Addr >> 13) + { + // RAM [0xC000] = [0xE000] ------------------------------------------------ + case 6: Mem_Pages [6] [Addr] = Value; return; + case 7: Mem_Pages [7] [Addr] = Value; return; + } + + Write_Error (Addr, Value); +} + // Based on MSX ASCII 8KB mapper? http://bifi.msxnet.org/msxnet/tech/megaroms.html#ascii8 // - This mapper requires 4 registers to save bank switching state. // However, all other mappers so far used only 3 registers, stored as 3 bytes. diff --git a/meka/srcs/mappers.h b/meka/srcs/mappers.h index 3711266f..b7553688 100644 --- a/meka/srcs/mappers.h +++ b/meka/srcs/mappers.h @@ -43,13 +43,36 @@ #define MAPPER_SMS_Korean_MSX_8KB_0300 (18) // Registers at 0x0000,0x0100,0x0200,0x0300 (Super Multi Game Super 75 in 1, Super Game World 75 etc.) #define MAPPER_SMS_Korean_2000_xor_1F (19) // Register at 0x2000 (128 Hap, Game Mo-eumjip 188 Hap etc.) #define MAPPER_SMS_Korean_BFFC (20) // Register at 0xBFFC -#define MAPPER_SMS_Korean_FFFE (21) // Register at 0xFFFE (Super Game 45) +#define MAPPER_SMS_Korean_FFFE (21) // Register at 0xFFFE (Super Game 45 [Teddy Boy]) #define MAPPER_SMS_Korean_FFF3_FFFC (22) // Registers at 0xFFF3 and 0xFFFC (Super Game 150, Super Game 270) #define MAPPER_SMS_Korean_0000_xor_FF (23) // Register at 0x0000 with MSX-oriented paging #define MAPPER_SMS_Korean_MD_FFF0 (24) // Registers at 0xFFF0 and 0xFFFF (Mega Mode Super Game 30 [SMS-MD]) #define MAPPER_SMS_Korean_MD_FFF5 (25) // Registers at 0xFFF5 and 0xFFFF (Jaemiissneun Game Mo-eumjip 42/65 Hap [SMS-MD], Pigu Wang Hap ~ Jaemiiss-neun Game Mo-eumjip [SMS-MD]) #define MAPPER_SMS_Korean_MD_FFFA (26) // Registers at 0xFFFA and 0xFFFF (Game Jiphap 30 Hap [SMS-MD]) #define MAPPER_SMS_Korean_MSX_32KB_2000 (27) // Register at 0x2000 (2 Hap in 1 (Moai-ui bomul, David-2)) +#define MAPPER_GG_Super_12_in_1_FFFE (28) // Registers at 0xFFFE 0xFFFF (Super 5/7/12 in 1 Game Gear [Mortal Kombat]/[Bare Knuckle 2]) +#define MAPPER_GG_Super_GG_15_BFFF_FFFF (29) // Registers at 0xBFFF, 0xFFFF, and 0xFFFE (Super GG 15 [Cliffhanger] [Gold & Yellow Label]) +#define MAPPER_GG_Turbo_9_in_1_8000_4000 (30) // Registers at 0x8000 and 0x4000 (Turbo 9 in 1) +#define MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button (31) // Registers at 0xFFFF and 0xFFFE, reset or pushbutton cycles games (Super Gear 20 in 1 [Ninja Gaiden]) +#define MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF (32) // Registers at 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFE, and 0xFFFF (Super GG 68 in 1 [Sonic Adventure], GG Super 56 in 1 (B) [Mega Man]) +#define MAPPER_GG_Super_73_in_1_FFFE_FFFF (33) // Registers at 0xFFFE and 0xFFFF (Super Game Gear 73 in 1 [Sonic 2]) +#define MAPPER_GG_Super_73_in_1_8000_4000 (34) // Registers at 0x8000 and 0x4000 (Super Game Gear 73 in 1 [Street Fighter 2]) +#define MAPPER_GG_Super_GG_30_1FFx_FFFx (35) // Registers at 0x1FFE, 0xFFFE, 0xFFFF, and 0x1FFF (Super GG 30 [Last Action] [Gold & Green Label], Super GG 15 [Last Action] [Super GG 30 Gold & Green Label]) +#define MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF (36) // Registers at 0xFFFE and 0xFFFF (Super Gear 23 in 1 [Ninja Gaiden]) +#define MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE (37) // Registers at 0xFFF8, 0xFFFE, and 0xFFFF (Super GG 18 in 1 [Nettou Samurai]) +#define MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1 (38) // Registers at 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFE, and 0xFFFF (Super GG 15 in 1 [Sonic 5]) +#define MAPPER_SMS_Korean_SMS_32KB_2000 (39) // Register at 0x2000 (11 Hap Gam-Boy) +#define MAPPER_SMS_Korean_MSX_SMS_8000 (40) // Register at 0x8000 with 8KB granularity and both MSX and SMS game support (Zemina Best 88 [MISSING 64K]) +#define MAPPER_GG_Super_68_in_1_FFFE_FFFF (41) // Registers at 0xFFFE and 0xFFFF (Super 68 in 1 [Simpson]) +#define MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF (42) // Registers at 0xFFFE, 0xFFF7, and 0xFFFF (Gear 6 in 1 [Alien Syndrome]) +#define MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF (43) // Registers at 0xFFFE, 0xFFF7, and 0xFFFF (Super Game Gear 9 in 1 [Sonic II]) +#define MAPPER_SMS_Korean_MSX_16KB_BFFE (44) // Register at 0xBFFE (Super Game 45 [Road Fighter]) +#define MAPPER_SMS_Korean_MSX_16KB_FFFF (45) // Register at 0xFFFF (Super Game 30 [Road Fighter] [Super Game 45]) +#define MAPPER_SMS_Meta_Power_FFFF_HiCom (46) // Power-cycling meta-multicart, inner collections use MAPPER_SMS_Korean_FFFF_HiCom (12 in 1 [Hang On] [SMS-GG], Super 12 in 1 [Teddy Boy] [SMS-MD]) +#define MAPPER_SMS_Power_256KB_FFFF_FFFE (47) // Power-cycling multicart of 256KB SMS games (Super 2 in 1 - Sonic & Alien Storm [SMS-GG], Untitled 4-in-1 (Moonwalker, Double Dragon, Sagaia & Spider-Man) [SMS-GG]) +#define MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF (48) // Registers at 0xFFF8, 0xFFF9, 0xFFFE, 0xFFFF (GG 48 in 1 [Doraemon 2]) +#define MAPPER_GG_18_in_1_00xx (49) // Registers at 0x0000..0x001F (18 in 1 - Super Games Collection [Columns]) +#define MAPPER_GG_Homebrew_FFF2 (127) // Register at 0xFFF2 (2404e9ea7e6e520b93a7c24ba49556af01900fd0) #define READ_FUNC(_NAME) u8 _NAME(register u16 Addr) #define WRITE_FUNC(_NAME) void _NAME(register u16 Addr, register u8 Value) @@ -96,6 +119,29 @@ WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFF0); WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFF5); WRITE_FUNC (Write_Mapper_SMS_Korean_MD_FFFA); WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_32KB_2000); +WRITE_FUNC (Write_Mapper_GG_Super_12_in_1_FFFE); +WRITE_FUNC (Write_Mapper_GG_Super_GG_15_BFFF_FFFF); +WRITE_FUNC (Write_Mapper_GG_Turbo_9_in_1_8000_4000); +WRITE_FUNC (Write_Mapper_GG_Gear_20_in_1_FFFF_FFFE_button); +WRITE_FUNC (Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF); +WRITE_FUNC (Write_Mapper_GG_Super_73_in_1_FFFE_FFFF); +WRITE_FUNC (Write_Mapper_GG_Super_73_in_1_8000_4000); +WRITE_FUNC (Write_Mapper_GG_Super_GG_30_1FFx_FFFx); +WRITE_FUNC (Write_Mapper_GG_Super_Gear_23_in_1_FFFE_FFFF); +WRITE_FUNC (Write_Mapper_GG_Super_GG_18_in_1_FFF8_FFFE); +WRITE_FUNC (Write_Mapper_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1); +WRITE_FUNC (Write_Mapper_SMS_Korean_SMS_32KB_2000); +WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_SMS_8000); +WRITE_FUNC (Write_Mapper_GG_Super_68_in_1_FFFE_FFFF); +WRITE_FUNC (Write_Mapper_GG_Gear_6_in_1_FFFE_FFF7_FFFF); +WRITE_FUNC (Write_Mapper_GG_Super_9_in_1_FFFE_FFF7_FFFF); +WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_16KB_BFFE); +WRITE_FUNC (Write_Mapper_SMS_Korean_MSX_16KB_FFFF); +WRITE_FUNC (Write_Mapper_SMS_Meta_Power_FFFF_HiCom); +WRITE_FUNC (Write_Mapper_SMS_Power_256KB_FFFF_FFFE); +WRITE_FUNC (Write_Mapper_GG_48_in_1_FFF8_FFF9_FFFE_FFFF); +WRITE_FUNC (Write_Mapper_GG_18_in_1_00xx); +WRITE_FUNC (Write_Mapper_GG_Homebrew_FFF2); //----------------------------------------------------------------------------- void Out_SC3000_SurvivorsMulticarts_DataWrite(u8 v); diff --git a/meka/srcs/saves.cpp b/meka/srcs/saves.cpp index 09bb14b8..281768d7 100644 --- a/meka/srcs/saves.cpp +++ b/meka/srcs/saves.cpp @@ -16,6 +16,8 @@ #include "vmachine.h" #include "sound/fmunit.h" #include "sound/psg.h" +#include "video.h" +#include "app_game.h" //----------------------------------------------------------------------------- // Functions @@ -26,6 +28,7 @@ void Load_Game_Fixup(void) { int i; u8 b; + bool sms_gg_mode_in_mapper = false; // CPU #ifdef MARAT_Z80 @@ -144,13 +147,305 @@ void Load_Game_Fixup(void) case MAPPER_SMS_Korean_MSX_32KB_2000: WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]); break; + case MAPPER_SMS_Korean_MSX_16KB_BFFE: + WrZ80_NoHook(0xBFFE, g_machine.mapper_regs[0]); + break; + case MAPPER_SMS_Korean_MSX_16KB_FFFF: + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[0]); + break; + case MAPPER_GG_Super_12_in_1_FFFE: + if (1) { + const int in_menu_mode = (g_machine.mapper_regs[0] & 0x08) == 0x00; + const int mapbase = g_machine.mapper_regs[0] & 0xF1; + const int reg1 = g_machine.mapper_regs[2] & 0x1F; + const int reg0 = g_machine.mapper_regs[1] & 0x1F; + WrZ80_NoHook(0xFFFE, 0xE0); // Meka extension: mapper reset to menu mode + WrZ80_NoHook(0xFFFE, 0x40 | ((mapbase & 0xE0) >> 4) | (mapbase & 0x01)); + WrZ80_NoHook(0xFFFE, mapbase & 0x10); + if (in_menu_mode) { + // Meka extension: reliable mapper register restoration in menu mode + WrZ80_NoHook(0xFFFE, 0x80 | reg1); + WrZ80_NoHook(0xFFFF, reg0); + } else { + WrZ80_NoHook(0xFFFF, 0x40); + WrZ80_NoHook(0xFFFE, reg1); + WrZ80_NoHook(0xFFFF, reg0); + } + } + break; + case MAPPER_GG_Super_GG_15_BFFF_FFFF: + if (1) { + unsigned int mapper_mode = g_machine.mapper_regs[0]; + unsigned int slot_8000_page_offset_16k = g_machine.mapper_regs[1]; + unsigned int slot_4000_page_offset_16k = g_machine.mapper_regs[2]; + unsigned int game_number = g_machine.mapper_regs[3]; + WrZ80_NoHook(0xBFFF, 0x0C); + WrZ80_NoHook(0xFFFF, game_number); + WrZ80_NoHook(0xBFFF, mapper_mode); + WrZ80_NoHook(0xFFFF, slot_8000_page_offset_16k); + WrZ80_NoHook(0xFFFE, slot_4000_page_offset_16k); + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Turbo_9_in_1_8000_4000: + if (1) { + unsigned int base_page_16k = g_machine.mapper_regs[0]; + unsigned int page_8000_offset_16k = g_machine.mapper_regs[1]; + unsigned int page_4000_offset_16k = g_machine.mapper_regs[2]; + // use of 0x80 to return to the initial state is a Meka + // extension but does not conflict with the menu code's + // use of the mapper, nor does it conflict with the one + // game that uses the mapper + WrZ80_NoHook(0x8000, 0x80); + WrZ80_NoHook(0x4000, 0x11); + WrZ80_NoHook(0x8000, base_page_16k); + WrZ80_NoHook(0x4000, 0x11); + WrZ80_NoHook(0x4000, page_4000_offset_16k); + WrZ80_NoHook(0x8000, page_8000_offset_16k); + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button: + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = g_machine.mapper_regs[0]; + // FIXME: don't know yet how the mapper decides which games need SMS-GG mode + if ((g_machine.mapper_regs[0] <= 0x1F) | ((g_machine.mapper_regs[0] >= 0x38) && (g_machine.mapper_regs[0] <= 0x3E))) { + drv_set(DRV_GG); + } else { + drv_set(DRV_SMS); + } + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + Map_8k_ROM(0, ((g_machine.mapper_regs[0]) * 2) & tsms.Pages_Mask_8k); + Map_8k_ROM(1, ((g_machine.mapper_regs[0]) * 2 + 1) & tsms.Pages_Mask_8k); + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + if (1) { + bool sega_mapper_active = g_machine.mapper_regs[0] & 0x80; + bool mapper_latch_open = g_machine.mapper_regs[0] & 0x40; + bool second_megabyte_active = g_machine.mapper_regs[0] & 0x20; + unsigned int base_page_32k = g_machine.mapper_regs[0] & 0x1F; + unsigned int reg_FFF8 = g_machine.mapper_regs[5]; + unsigned int reg_FFF9 = g_machine.mapper_regs[4]; + unsigned int reg_FFFA = g_machine.mapper_regs[3]; + unsigned int reg_FFFE = g_machine.mapper_regs[2]; + unsigned int reg_FFFF = g_machine.mapper_regs[1]; + WrZ80_NoHook(0xFFF9, 0x00); + WrZ80_NoHook(0xFFF8, 0x00); + WrZ80_NoHook(0xFFFA, 0x01); + WrZ80_NoHook(0xFFF8, base_page_32k); + WrZ80_NoHook(0xFFF9, (reg_FFF9 & 0x80) | ((sega_mapper_active && second_megabyte_active) ? 0x12 : 0x00) | ((sega_mapper_active && !second_megabyte_active) ? 0x0C : 0x00)); + WrZ80_NoHook(0xFFFA, (reg_FFFA & 0x01) | ((sega_mapper_active && second_megabyte_active) ? 0x04 : 0x00)); + WrZ80_NoHook(0xFFFE, 0x01); + if (g_machine.mapper_regs[1] != reg_FFFF) { + WrZ80_NoHook(0xFFFF, reg_FFFF); + } + if (g_machine.mapper_regs[2] != reg_FFFE) { + WrZ80_NoHook(0xFFFE, reg_FFFE); + } + if (mapper_latch_open) { + WrZ80_NoHook(0xFFF9, 0x00); + WrZ80_NoHook(0xFFF8, 0x00); + WrZ80_NoHook(0xFFFA, 0x01); + } + if (g_machine.mapper_regs[4] != reg_FFF9) { + WrZ80_NoHook(0xFFF9, reg_FFF9); + } + if (g_machine.mapper_regs[5] != reg_FFF8) { + WrZ80_NoHook(0xFFF8, reg_FFF8); + } + if (g_machine.mapper_regs[3] != reg_FFFA) { + WrZ80_NoHook(0xFFFA, reg_FFFA); + } + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Super_73_in_1_FFFE_FFFF: + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_GG_Super_73_in_1_8000_4000: + WrZ80_NoHook(0x4000, g_machine.mapper_regs[1]); + WrZ80_NoHook(0x8000, g_machine.mapper_regs[2]); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_GG_Super_GG_30_1FFx_FFFx: + if (1) { + unsigned int mapper_mode_upper_1FFF = g_machine.mapper_regs[0]; + unsigned int mapper_mode_lower_1FFE = g_machine.mapper_regs[1]; + unsigned int slot_8000_page_offset_16k_FFFF = g_machine.mapper_regs[2]; + unsigned int slot_4000_page_offset_16k_FFFE = g_machine.mapper_regs[3]; + unsigned int slot_8000_base_16k_FFFF = g_machine.mapper_regs[4]; + unsigned int slot_0000_4000_base_16k_FFFE = g_machine.mapper_regs[5]; + WrZ80_NoHook(0x1FFE, 0x00); + WrZ80_NoHook(0x1FFF, 0x00); + WrZ80_NoHook(0x1FFE, 0x04); + WrZ80_NoHook(0xFFFF, slot_8000_base_16k_FFFF); + WrZ80_NoHook(0xFFFE, slot_0000_4000_base_16k_FFFE); + WrZ80_NoHook(0x1FFE, 0x00); + WrZ80_NoHook(0x1FFF, 0x00); + WrZ80_NoHook(0xFFFF, slot_8000_page_offset_16k_FFFF); + WrZ80_NoHook(0xFFFE, slot_4000_page_offset_16k_FFFE); + WrZ80_NoHook(0x1FFE, mapper_mode_lower_1FFE); + WrZ80_NoHook(0x1FFF, mapper_mode_upper_1FFF); + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF: + if (1) { + unsigned int mapper_mode = g_machine.mapper_regs[0]; + unsigned int slot_8000_page_offset_16k_FFFF = g_machine.mapper_regs[1]; + unsigned int slot_4000_page_offset_16k_FFFE = g_machine.mapper_regs[2]; + g_machine.mapper_regs[0] = 0x00; + g_machine.mapper_regs[1] = 0x00; + g_machine.mapper_regs[2] = 0x00; + WrZ80_NoHook(0xFFFE, mapper_mode & 0x03); + WrZ80_NoHook(0xFFFE, 0x04 | ((mapper_mode & 0x0C) >> 2)); + WrZ80_NoHook(0xFFFE, 0x08 | ((mapper_mode & 0x30) >> 4)); + if (mapper_mode & 0x80) { + // "Sega mode" + WrZ80_NoHook(0xFFFF, 0x08); + WrZ80_NoHook(0xFFFF, slot_8000_page_offset_16k_FFFF); + WrZ80_NoHook(0xFFFE, slot_4000_page_offset_16k_FFFE); + } + g_machine.mapper_regs[0] = mapper_mode; + g_machine.mapper_regs[1] = slot_8000_page_offset_16k_FFFF; + g_machine.mapper_regs[2] = slot_4000_page_offset_16k_FFFE; + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE: + if (1) { + int mapper_mode = g_machine.mapper_regs[0]; + g_machine.mapper_regs[0] = 0; + WrZ80_NoHook(0xFFF8, mapper_mode); + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1: + WrZ80_NoHook(0xFFF8, g_machine.mapper_regs[2]); + WrZ80_NoHook(0xFFF9, g_machine.mapper_regs[3]); + WrZ80_NoHook(0xFFFA, g_machine.mapper_regs[4]); + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[0]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[1]); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_SMS_Korean_SMS_32KB_2000: + WrZ80_NoHook(0x2000, g_machine.mapper_regs[0]); + break; + case MAPPER_SMS_Korean_MSX_SMS_8000: + if (1) { + int mapper_page = g_machine.mapper_regs[0]; + WrZ80_NoHook(0x8000, 0x00); // reset the mapper to avoid the 0xFF special case + WrZ80_NoHook(0x8000, mapper_page); + } + break; + case MAPPER_GG_Super_68_in_1_FFFE_FFFF: + if (1) { + unsigned int game_id = g_machine.mapper_regs[0]; + unsigned int slot_8000_page_offset_16k_FFFF = g_machine.mapper_regs[1]; + unsigned int slot_4000_page_offset_16k_FFFE = g_machine.mapper_regs[2]; + unsigned int mapper_mode = g_machine.mapper_regs[3]; + // mapper is initially in GG mode + drv_set(DRV_GG); + g_machine.mapper_regs[0] = 0x00; + g_machine.mapper_regs[1] = 0x00; + g_machine.mapper_regs[2] = 0x00; + g_machine.mapper_regs[3] = 0x00; + if (mapper_mode & 0x08) { + // "heuristic mode" for SMS-GG determination + WrZ80_NoHook(0xFFFE, 0x06); + } + // low two bits of game ID (also locks in "heuristic mode" bit) + WrZ80_NoHook(0xFFFE, game_id & 0x03); + // lower middle two bits of game ID + WrZ80_NoHook(0xFFFE, 0x04 | ((game_id & 0x0C) >> 2)); + // upper middle two bits of game ID + WrZ80_NoHook(0xFFFE, 0x08 | ((game_id & 0x30) >> 4)); + if ((mapper_mode & 0x0C) || (game_id & 0xC0)) { + // high two bits of game ID + // + // ... and also ... + // + // "use game_id & 0x40" for SMS-GG determination + // when not in heuristic mode + WrZ80_NoHook(0xFFFE, 0x0C | ((game_id & 0xC0) >> 6)); + } + if (mapper_mode & 0x80) { + // "Sega mode" + WrZ80_NoHook(0xFFFF, 0x08); + WrZ80_NoHook(0xFFFF, slot_8000_page_offset_16k_FFFF); + WrZ80_NoHook(0xFFFE, slot_4000_page_offset_16k_FFFE); + } + g_machine.mapper_regs[0] = game_id; + g_machine.mapper_regs[1] = slot_8000_page_offset_16k_FFFF; + g_machine.mapper_regs[2] = slot_4000_page_offset_16k_FFFE; + g_machine.mapper_regs[3] = mapper_mode; + gamebox_resize_all(); + VDP_UpdateLineLimits(); + Video_GameMode_UpdateBounds(); + sms_gg_mode_in_mapper = true; + } + break; + case MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF: + // rewriting these will automatically read and apply the hidden register's state + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + break; + case MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF: + // rewriting these will automatically read and apply the hidden register's state + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_SMS_Meta_Power_FFFF_HiCom: + if (true) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = g_machine.mapper_regs[0]; + unsigned int base_page_8k = (g_machine.mapper_regs[0] + g_machine.mapper_regs[1]) * 4; + Map_8k_ROM(4, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(5, (base_page_8k | 1) & tsms.Pages_Mask_8k); + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + } + break; + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + if (true) { + SRAM[0x7FFF] = 0xAA; + SRAM[0x7FFE] = g_machine.mapper_regs[0]; + unsigned int base_page_8k = g_machine.mapper_regs[0] * 2; + Map_8k_ROM(0, base_page_8k & tsms.Pages_Mask_8k); + Map_8k_ROM(1, (base_page_8k | 1) & tsms.Pages_Mask_8k); + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[1]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[2]); + } + break; + case MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF: + // Re-writing these registers will have the side-effect of + // re-applying all the rest of the memory mapper state too + WrZ80_NoHook(0xFFFF, g_machine.mapper_regs[2]); + WrZ80_NoHook(0xFFFE, g_machine.mapper_regs[3]); + break; + case MAPPER_GG_18_in_1_00xx: + WrZ80_NoHook(0x0000 | g_machine.mapper_regs[0], 0x00); + sms_gg_mode_in_mapper = true; + break; + case MAPPER_GG_Homebrew_FFF2: + WrZ80_NoHook(0xFFF2, g_machine.mapper_regs[0]); + break; } } // VDP/Graphic related - tsms.VDP_Video_Change |= VDP_VIDEO_CHANGE_ALL; - VDP_UpdateLineLimits(); - // FALSE!!! // tsms.VDP_Line = 224; + if (!sms_gg_mode_in_mapper) { + tsms.VDP_Video_Change |= VDP_VIDEO_CHANGE_ALL; + VDP_UpdateLineLimits(); + // FALSE!!! // tsms.VDP_Line = 224; + } // Rewrite all VDP registers (we can do that since it has zero side-effect) for (i = 0; i < 16; i ++) @@ -339,6 +634,28 @@ int Save_Game_MSV(FILE *f) case MAPPER_SMS_Korean_MD_FFF5: case MAPPER_SMS_Korean_MD_FFFA: case MAPPER_SMS_Korean_MSX_32KB_2000: + case MAPPER_GG_Super_12_in_1_FFFE: + case MAPPER_GG_Super_GG_15_BFFF_FFFF: + case MAPPER_GG_Turbo_9_in_1_8000_4000: + case MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button: + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + case MAPPER_GG_Super_73_in_1_FFFE_FFFF: + case MAPPER_GG_Super_73_in_1_8000_4000: + case MAPPER_GG_Super_GG_30_1FFx_FFFx: + case MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF: + case MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE: + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1: + case MAPPER_SMS_Korean_SMS_32KB_2000: + case MAPPER_SMS_Korean_MSX_SMS_8000: + case MAPPER_GG_Super_68_in_1_FFFE_FFFF: + case MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF: + case MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF: + case MAPPER_SMS_Korean_MSX_16KB_BFFE: + case MAPPER_SMS_Korean_MSX_16KB_FFFF: + case MAPPER_SMS_Meta_Power_FFFF_HiCom: + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + case MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF: + case MAPPER_GG_18_in_1_00xx: default: fwrite (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change break; @@ -518,6 +835,28 @@ int Load_Game_MSV(FILE *f) case MAPPER_SMS_Korean_MD_FFF5: case MAPPER_SMS_Korean_MD_FFFA: case MAPPER_SMS_Korean_MSX_32KB_2000: + case MAPPER_GG_Super_12_in_1_FFFE: + case MAPPER_GG_Super_GG_15_BFFF_FFFF: + case MAPPER_GG_Turbo_9_in_1_8000_4000: + case MAPPER_GG_Gear_20_in_1_FFFF_FFFE_button: + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF: + case MAPPER_GG_Super_73_in_1_FFFE_FFFF: + case MAPPER_GG_Super_73_in_1_8000_4000: + case MAPPER_GG_Super_GG_30_1FFx_FFFx: + case MAPPER_GG_Super_Gear_23_in_1_FFFE_FFFF: + case MAPPER_GG_Super_GG_18_in_1_FFF8_FFFE: + case MAPPER_GG_FFF8_FFF9_FFFA_FFFE_FFFF_15_1: + case MAPPER_SMS_Korean_SMS_32KB_2000: + case MAPPER_SMS_Korean_MSX_SMS_8000: + case MAPPER_GG_Super_68_in_1_FFFE_FFFF: + case MAPPER_GG_Gear_6_in_1_FFFE_FFF7_FFFF: + case MAPPER_GG_Super_9_in_1_FFFE_FFF7_FFFF: + case MAPPER_SMS_Korean_MSX_16KB_BFFE: + case MAPPER_SMS_Korean_MSX_16KB_FFFF: + case MAPPER_SMS_Meta_Power_FFFF_HiCom: + case MAPPER_SMS_Power_256KB_FFFF_FFFE: + case MAPPER_GG_48_in_1_FFF8_FFF9_FFFE_FFFF: + case MAPPER_GG_18_in_1_00xx: default: fread (RAM, 0x2000, 1, f); // Do not use g_driver->ram because of g_driver video mode change break; diff --git a/meka/srcs/video.cpp b/meka/srcs/video.cpp index fa03ee85..eb9c6872 100644 --- a/meka/srcs/video.cpp +++ b/meka/srcs/video.cpp @@ -143,11 +143,7 @@ static int Video_ChangeVideoMode(t_video_driver* driver, int w, int h, bool full // Create new display int display_flags = driver->flags; if (fullscreen) -#if ARCH_MACOSX - display_flags |= ALLEGRO_FULLSCREEN_WINDOW; // FIXME: Expose/use FULLSCREEN_WINDOW everywhere? -#else - display_flags |= ALLEGRO_FULLSCREEN; -#endif + display_flags |= ALLEGRO_FULLSCREEN_WINDOW; else display_flags |= ALLEGRO_WINDOWED; al_set_new_display_flags(display_flags);