// license:BSD-3-Clause // copyright-holders:Xing Xing /* IGS ARM7 (IGS027A) based Mahjong / Gambling platform(s) Driver by Xing Xing These games use the IGS027A processor. This is an ARM7 with Internal ROM. (Also used on later PGM games) In some cases the first part of the Internal ROM is excute only, and cannot be read out with a trojan. It hasn't been confirmed if these games make use of that feature. To emulate these games the Internal ROM will need dumping There are at least 20 other games on this and similar platforms. Many of these also seem to have a 80C51 based MCU, also covered by a holographic sticker, this appears to be unprotected but has only been read for a few sets, it probably either acts as a secondary protection device or as a main CPU instructing the ARM. */ #include "emu.h" #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" #include "machine/nvram.h" #include "machine/pgmcrypt.h" #include "video/igs017_igs031.h" class igs_m027_state : public driver_device { public: igs_m027_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_igs_mainram(*this, "igs_mainram"), m_maincpu(*this, "maincpu"), m_igs017_igs031(*this, "igs017_igs031") { } optional_shared_ptr m_igs_mainram; required_device m_maincpu; required_device m_igs017_igs031; DECLARE_DRIVER_INIT(sdwx); DECLARE_DRIVER_INIT(chessc2); DECLARE_DRIVER_INIT(lhzb4); DECLARE_DRIVER_INIT(mgfx); DECLARE_DRIVER_INIT(lhzb3); DECLARE_DRIVER_INIT(gonefsh2); DECLARE_DRIVER_INIT(sddz); DECLARE_DRIVER_INIT(hauntedh); DECLARE_DRIVER_INIT(zhongguo); DECLARE_DRIVER_INIT(klxyj); DECLARE_DRIVER_INIT(slqz3); DECLARE_DRIVER_INIT(fruitpar); DECLARE_DRIVER_INIT(amazonia); DECLARE_DRIVER_INIT(amazoni2); virtual void video_start() override; UINT32 screen_update_igs_majhong(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(igs_majhong_interrupt); void sdwx_gfx_decrypt(); void pgm_create_dummy_internal_arm_region(); }; /*************************************************************************** Video 0x38001000, 0x380017ff CG_CONTROL,8 byte per object, 0x100 in total 0x38001800, 0x380019ff PALETTE RAM,2 byte per color, 0x100 in total 0x38004000, 0x38005FFF TX Video RAM????????1E00??????512x240?????? 0x38006000, 0x38007FFF BG Video RAM????????1E00??????512x240?????? ***************************************************************************/ /* CGLayer */ #if 0 WRITE32_MEMBER(igs_m027_state::igs_cg_videoram_w) { COMBINE_DATA(&m_igs_cg_videoram[offset]); //if(data!=0) logerror("PC(%08X) CG @%x = %x!\n",space.device().safe_pc(),offset ,m_igs_cg_videoram[offset]); /* ROM:08020520 DCW 0x3E ddd1 y ROM:08020522 DCW 0x29 ddd2 x ROM:08020524 DCD 0x190BB6 ddd3 n ROM:08020528 DCW 0xC ddd4 Y ROM:0802052A DCW 0xA6 ddd5 X (ddd5+?)??10bit ddd2??9bit (ddd4+?)??11bit ddd1??8bit ddd3??10bit 8060a4a6 2642ed8f A6A46080 8FED4226 XXXX-XXXX XXxx-xxxx xxxY-YYYY YYYY-YYyy yyyy-yynn nnnn-nnnn */ } #endif void igs_m027_state::video_start() { m_igs017_igs031->video_start(); } UINT32 igs_m027_state::screen_update_igs_majhong(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { m_igs017_igs031->screen_update_igs017(screen, bitmap, cliprect); return 0; } /*************************************************************************** Memory Maps ***************************************************************************/ static ADDRESS_MAP_START( igs_majhong_map, AS_PROGRAM, 32, igs_m027_state ) AM_RANGE(0x00000000, 0x00003fff) AM_ROM /* Internal ROM */ AM_RANGE(0x08000000, 0x0807ffff) AM_ROM AM_REGION("user1", 0)/* Game ROM */ AM_RANGE(0x10000000, 0x100003ff) AM_RAM AM_SHARE("igs_mainram")// main ram for asic? AM_RANGE(0x18000000, 0x18007fff) AM_RAM AM_RANGE(0x38000000, 0x38007FFF) AM_DEVREADWRITE8("igs017_igs031", igs017_igs031_device, read,write, 0xffffffff) // guess based on below #if 0 AM_RANGE(0x38001000, 0x380017ff) AM_RAM_WRITE(igs_cg_videoram_w) AM_SHARE("igs_cg_videoram") //0x200 * 1 CG PALETTE? AM_RANGE(0x38001800, 0x38001fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") //0x200 * 1 AM_RANGE(0x38004000, 0x38005FFF) AM_RAM_WRITE(igs_tx_videoram_w) AM_SHARE("igs_tx_videoram") /* Text Layer */ AM_RANGE(0x38006000, 0x38007FFF) AM_RAM_WRITE(igs_bg_videoram_w) AM_SHARE("igs_bg_videoram") /* CG Layer */ AM_RANGE(0x38002010, 0x38002017) AM_RAM //?????????????? #endif AM_RANGE(0x38009000, 0x38009003) AM_RAM //?????????????? oki 6295 AM_RANGE(0x70000200, 0x70000203) AM_RAM //?????????????? AM_RANGE(0x50000000, 0x500003ff) AM_WRITENOP // uploads xor table to external rom here AM_RANGE(0xf0000000, 0xF000000f) AM_WRITENOP // magic registers ADDRESS_MAP_END /*************************************************************************** Common functions ***************************************************************************/ /*************************************************************************** Code Decryption ***************************************************************************/ #if 0 static const UINT8 sdwx_tab[] = { 0x49,0x47,0x53,0x30,0x30,0x35,0x35,0x52,0x44,0x34,0x30,0x32,0x30,0x36,0x32,0x31, 0x8A,0xBB,0x20,0x67,0x97,0xA5,0x20,0x45,0x6B,0xC0,0xE8,0x0C,0x80,0xFB,0x49,0xAA, 0x1E,0xAC,0x29,0xF2,0xB9,0x9F,0x01,0x4A,0x8D,0x5F,0x95,0x96,0x78,0xC3,0xF6,0x65, 0x17,0xBD,0xB6,0x5B,0x25,0x5F,0x6B,0xDE,0x10,0x2E,0x67,0x05,0xDC,0xAC,0xB6,0xBD, 0x3D,0x20,0x58,0x3D,0xF0,0xA8,0xC0,0xAD,0x5B,0x82,0x8D,0x12,0x65,0x97,0x87,0x7D, 0x97,0x49,0xDD,0x74,0x74,0x7E,0x9D,0xA1,0x15,0xED,0x75,0xB9,0x09,0xA8,0xA8,0xB0, 0x6B,0xEA,0x54,0x1B,0x45,0x23,0xE2,0xE5,0x25,0x42,0xCE,0x36,0xFE,0x42,0x99,0xA0, 0x41,0xF8,0x0B,0x8C,0x3C,0x1B,0xAE,0xE4,0xB2,0x94,0x87,0x02,0xBC,0x08,0x17,0xD9, 0xE0,0xA4,0x93,0x63,0x6F,0x28,0x5F,0x4A,0x24,0x36,0xD1,0xDA,0xFA,0xDD,0x23,0x26, 0x4E,0x61,0xB9,0x7A,0x36,0x4D,0x95,0x01,0x20,0xBC,0x18,0xB7,0xAF,0xE4,0xFB,0x92, 0xD2,0xE3,0x8E,0xEC,0x26,0xCE,0x2F,0x34,0x8F,0xF7,0x0D,0xD6,0x11,0x7F,0x1F,0x68, 0xF4,0x1D,0x5F,0x16,0x19,0x2D,0x4C,0x4F,0x96,0xFC,0x9F,0xB0,0x99,0x53,0x4C,0x32, 0x7B,0x41,0xBC,0x90,0x23,0x2E,0x4A,0xFC,0x9E,0x1D,0xFC,0x02,0xFC,0x41,0x83,0xBC, 0x6D,0xC4,0x75,0x37,0x9D,0xD3,0xC9,0x26,0x4D,0xED,0x93,0xC6,0x32,0x6D,0x02,0x11, 0x12,0x56,0x97,0x26,0x1D,0x5F,0xA7,0xF8,0x89,0x3F,0x14,0x36,0x72,0x3B,0x48,0x7B, 0xF1,0xED,0x72,0xB7,0x7A,0x56,0x05,0xDE,0x7B,0x27,0x6D,0xCF,0x33,0x4C,0x14,0x86, }; #endif void igs_m027_state::sdwx_gfx_decrypt() { int i; unsigned rom_size = 0x80000; UINT8 *src = (UINT8 *) (memregion("tilemaps")->base()); dynamic_buffer result_data(rom_size); for (i=0; ibase(); // fill with RX 14 int i; for (i=0;i<0x4000/2;i+=2) { temp16[i] = 0xff1e; temp16[i+1] = 0xe12f; } // jump straight to external area temp16[(0x0000)/2] = 0xd088; temp16[(0x0002)/2] = 0xe59f; temp16[(0x0004)/2] = 0x0680; temp16[(0x0006)/2] = 0xe3a0; temp16[(0x0008)/2] = 0xff10; temp16[(0x000a)/2] = 0xe12f; temp16[(0x0090)/2] = 0x0400; temp16[(0x0092)/2] = 0x1000; } /* DRIVER_INIT_MEMBER(igs_m027_state,igs_m027) { pgm_create_dummy_internal_arm_region(machine()); } */ DRIVER_INIT_MEMBER(igs_m027_state,sdwx) { sdwx_decrypt(machine()); sdwx_gfx_decrypt(); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,klxyj) { klxyj_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,chessc2) { chessc2_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,hauntedh) { hauntedh_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,lhzb4) { lhzb4_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,mgfx) { mgfx_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,lhzb3) { lhzb3_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,sddz) { sddz_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,gonefsh2) { gonefsh2_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,zhongguo) { zhongguo_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,slqz3) { slqz3_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,fruitpar) { fruitpar_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,amazonia) { amazonia_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(igs_m027_state,amazoni2) { amazoni2_decrypt(machine()); //sdwx_gfx_decrypt(machine()); pgm_create_dummy_internal_arm_region(); } /*************************************************************************** Game Drivers ***************************************************************************/ GAME( 1999, slqz3, 0, igs_majhong, sdwx, igs_m027_state, slqz3, ROT0, "IGS", "Mahjong Shuang Long Qiang Zhu 3 (China, VS107C)", MACHINE_IS_SKELETON ) GAME( 1999, amazonia, 0, amazonia,amazonia, igs_m027_state, amazonia, ROT0, "IGS", "Amazonia King (V104BR)", MACHINE_IS_SKELETON ) GAME( 200?, fruitpar, 0, igs_majhong, sdwx, igs_m027_state, fruitpar, ROT0, "IGS", "Fruit Paradise (V214)", MACHINE_IS_SKELETON ) GAME( 2002, sdwx, 0, igs_majhong, sdwx, igs_m027_state, sdwx, ROT0, "IGS", "Sheng Dan Wu Xian", MACHINE_IS_SKELETON ) // aka Christmas 5 Line? (or Amazonia King II, shares roms at least?) GAME( 2002, amazoni2, 0, igs_majhong, sdwx, igs_m027_state, amazoni2, ROT0, "IGS", "Amazonia King II (V202BR)", MACHINE_IS_SKELETON ) GAME( 200?, sddz, 0, igs_majhong, sdwx, igs_m027_state, sddz, ROT0, "IGS", "Super Dou Di Zhu", MACHINE_IS_SKELETON ) GAME( 2000, zhongguo, 0, igs_majhong, sdwx, igs_m027_state, zhongguo, ROT0, "IGS", "Zhong Guo Chu Da D", MACHINE_IS_SKELETON ) GAME( 200?, lhzb3, 0, igs_majhong, sdwx, igs_m027_state, lhzb3, ROT0, "IGS", "Long Hu Zheng Ba 3", MACHINE_IS_SKELETON ) GAME( 200?, lhzb4, 0, igs_majhong, sdwx, igs_m027_state, lhzb4, ROT0, "IGS", "Long Hu Zheng Ba 4", MACHINE_IS_SKELETON ) GAME( 200?, klxyj, 0, igs_majhong, sdwx, igs_m027_state, klxyj, ROT0, "IGS", "Kuai Le Xi You Ji", MACHINE_IS_SKELETON ) GAME( 2000, mgfx, 0, igs_majhong, sdwx, igs_m027_state, mgfx, ROT0, "IGS", "Man Guan Fu Xing", MACHINE_IS_SKELETON ) GAME( 200?, gonefsh2, 0, igs_majhong, sdwx, igs_m027_state, gonefsh2, ROT0, "IGS", "Gone Fishing 2", MACHINE_IS_SKELETON ) GAME( 200?, chessc2, 0, igs_majhong, sdwx, igs_m027_state, chessc2, ROT0, "IGS", "Chess Challenge 2", MACHINE_IS_SKELETON ) GAME( 200?, haunthig, 0, igs_majhong, sdwx, igs_m027_state, hauntedh, ROT0, "IGS", "Haunted House (IGS)", MACHINE_IS_SKELETON )