diff options
Diffstat (limited to 'src/mame/drivers/astrcorp.cpp')
-rw-r--r-- | src/mame/drivers/astrcorp.cpp | 319 |
1 files changed, 137 insertions, 182 deletions
diff --git a/src/mame/drivers/astrcorp.cpp b/src/mame/drivers/astrcorp.cpp index 9ed45d4c9ba..3a106ec783a 100644 --- a/src/mame/drivers/astrcorp.cpp +++ b/src/mame/drivers/astrcorp.cpp @@ -78,6 +78,23 @@ protected: virtual void video_start() override; private: + struct decryption_info { + struct { + // Address bits used for bitswap/xor selection + u8 bits[3]; + struct { + // 8-8 Bitswap + u8 bits[8]; + // Xor + u8 xor_mask; + } entries[8]; + } rom[2]; + // Global address bitswap (src -> dest, bits 12-8 only) + u8 bits[5]; + }; + + static const decryption_info astoneag_table; + // devices required_device<cpu_device> m_maincpu; required_device<okim6295_device> m_oki; @@ -113,6 +130,8 @@ private: void showhand_map(address_map &map); void skilldrp_map(address_map &map); void speeddrp_map(address_map &map); + + void decrypt_rom(const decryption_info &table); }; /*************************************************************************** @@ -525,26 +544,26 @@ TODO: understand if later hardware uses different parameters (XTAL is almost sur #define ASTROCORP_VBEND 0 #define ASTROCORP_VBSTART 240 -MACHINE_CONFIG_START(astrocorp_state::showhand) - +void astrocorp_state::showhand(machine_config &config) +{ /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", M68000, XTAL(20'000'000) / 2) - MCFG_DEVICE_PROGRAM_MAP(showhand_map) - MCFG_DEVICE_VBLANK_INT_DRIVER("screen", astrocorp_state, irq4_line_hold) + M68000(config, m_maincpu, XTAL(20'000'000) / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &astrocorp_state::showhand_map); + m_maincpu->set_vblank_int("screen", FUNC(astrocorp_state::irq4_line_hold)); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); EEPROM_93C46_16BIT(config, "eeprom").default_data(showhand_default_eeprom, sizeof(showhand_default_eeprom)); /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) -// MCFG_SCREEN_REFRESH_RATE(58.846) // measured on pcb -// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) -// MCFG_SCREEN_SIZE(320, 240) -// MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) - MCFG_SCREEN_RAW_PARAMS(ASTROCORP_PIXEL_CLOCK,ASTROCORP_HTOTAL,ASTROCORP_HBEND,320,ASTROCORP_VTOTAL,ASTROCORP_VBEND,ASTROCORP_VBSTART) - MCFG_SCREEN_UPDATE_DRIVER(astrocorp_state, screen_update_astrocorp) - MCFG_SCREEN_PALETTE(m_palette) + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); +// m_screen->set_refresh_hz(58.846); // measured on pcb +// m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); +// m_screen->set_size(320, 240); +// m_screen->set_visarea_full(); + m_screen->set_raw(ASTROCORP_PIXEL_CLOCK,ASTROCORP_HTOTAL,ASTROCORP_HBEND,320,ASTROCORP_VTOTAL,ASTROCORP_VBEND,ASTROCORP_VBSTART); + m_screen->set_screen_update(FUNC(astrocorp_state::screen_update_astrocorp)); + m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_astrocorp); PALETTE(config, m_palette).set_format(palette_device::BGR_565, 0x100); @@ -552,16 +571,15 @@ MACHINE_CONFIG_START(astrocorp_state::showhand) /* sound hardware */ SPEAKER(config, "mono").front_center(); - MCFG_DEVICE_ADD("oki", OKIM6295, XTAL(20'000'000)/20, okim6295_device::PIN7_HIGH) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) -MACHINE_CONFIG_END + OKIM6295(config, m_oki, XTAL(20'000'000)/20, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 1.0); +} -MACHINE_CONFIG_START(astrocorp_state::showhanc) +void astrocorp_state::showhanc(machine_config &config) +{ showhand(config); - MCFG_DEVICE_MODIFY("maincpu") - MCFG_DEVICE_PROGRAM_MAP(showhanc_map) -MACHINE_CONFIG_END + m_maincpu->set_addrmap(AS_PROGRAM, &astrocorp_state::showhanc_map); +} TIMER_DEVICE_CALLBACK_MEMBER(astrocorp_state::skilldrp_scanline) @@ -575,28 +593,28 @@ TIMER_DEVICE_CALLBACK_MEMBER(astrocorp_state::skilldrp_scanline) m_maincpu->set_input_line(2, HOLD_LINE); } -MACHINE_CONFIG_START(astrocorp_state::skilldrp) - +void astrocorp_state::skilldrp(machine_config &config) +{ /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", M68000, XTAL(24'000'000) / 2) // JX-1689F1028N GRX586.V5 - MCFG_DEVICE_PROGRAM_MAP(skilldrp_map) - MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", astrocorp_state, skilldrp_scanline, "screen", 0, 1) + M68000(config, m_maincpu, XTAL(24'000'000) / 2); // JX-1689F1028N GRX586.V5 + m_maincpu->set_addrmap(AS_PROGRAM, &astrocorp_state::skilldrp_map); + TIMER(config, "scantimer").configure_scanline(FUNC(astrocorp_state::skilldrp_scanline), "screen", 0, 1); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); EEPROM_93C46_16BIT(config, "eeprom"); - MCFG_TICKET_DISPENSER_ADD("ticket", attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW ) - MCFG_TICKET_DISPENSER_ADD("hopper", attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW ) + TICKET_DISPENSER(config, m_ticket, attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW ); + TICKET_DISPENSER(config, m_hopper, attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW ); /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) -// MCFG_SCREEN_REFRESH_RATE(58.846) -// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) -// MCFG_SCREEN_SIZE(0x200, 0x100) -// MCFG_SCREEN_VISIBLE_AREA(0, 0x200-1, 0, 0xf0-1) - MCFG_SCREEN_RAW_PARAMS(ASTROCORP_PIXEL_CLOCK,ASTROCORP_HTOTAL,ASTROCORP_HBEND,512,ASTROCORP_VTOTAL,ASTROCORP_VBEND,ASTROCORP_VBSTART) - MCFG_SCREEN_UPDATE_DRIVER(astrocorp_state, screen_update_astrocorp) - MCFG_SCREEN_PALETTE(m_palette) + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); +// m_screen->set_refresh_hz(58.846); +// m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); +// m_screen->set_size(0x200, 0x100); +// m_screen->set_visarea(0, 0x200-1, 0, 0xf0-1); + m_screen->set_raw(ASTROCORP_PIXEL_CLOCK,ASTROCORP_HTOTAL,ASTROCORP_HBEND,512,ASTROCORP_VTOTAL,ASTROCORP_VBEND,ASTROCORP_VBSTART); + m_screen->set_screen_update(FUNC(astrocorp_state::screen_update_astrocorp)); + m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_astrocorp); PALETTE(config, m_palette).set_format(palette_device::BGR_565, 0x100); @@ -604,16 +622,15 @@ MACHINE_CONFIG_START(astrocorp_state::skilldrp) /* sound hardware */ SPEAKER(config, "mono").front_center(); - MCFG_DEVICE_ADD("oki", OKIM6295, XTAL(24'000'000)/24, okim6295_device::PIN7_HIGH) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) -MACHINE_CONFIG_END + OKIM6295(config, m_oki, XTAL(24'000'000)/24, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 1.0); +} -MACHINE_CONFIG_START(astrocorp_state::speeddrp) +void astrocorp_state::speeddrp(machine_config &config) +{ skilldrp(config); - MCFG_DEVICE_MODIFY("maincpu") - MCFG_DEVICE_PROGRAM_MAP(speeddrp_map) -MACHINE_CONFIG_END + m_maincpu->set_addrmap(AS_PROGRAM, &astrocorp_state::speeddrp_map); +} /*************************************************************************** @@ -1238,155 +1255,93 @@ void astrocorp_state::init_showhanc() #endif } -void astrocorp_state::init_astoneag() +void astrocorp_state::decrypt_rom(const decryption_info &table) { -#if 0 - uint16_t *rom = (uint16_t*)memregion("maincpu")->base(); - uint16_t x; - int i; - - for (i = 0x25100/2; i < 0x25200/2; i++) - { - x = 0x0000; - if ( (i & 0x0001) ) x |= 0x0200; - if ( (i & 0x0004) && !(i & 0x0001) ) x |= 0x0080; - if ( (i & 0x0040) || (i & 0x0001) ) x |= 0x0040; - if ( (i & 0x0010) && !(i & 0x0001) ) x |= 0x0020; - if ( !(i & 0x0020) || (i & 0x0001) ) x |= 0x0010; - if ( (i & 0x0002) || (i & 0x0001) ) x |= 0x0008; - if ( (i & 0x0008) && !(i & 0x0001) ) x |= 0x0004; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0002; - if ( (i & 0x0040) && !(i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; - } - -/* - for (i = 0x25300/2; i < 0x25400/2; i++) - { - x = 0x1300; - rom[i] ^= x; - } -*/ - - for (i = 0x25400/2; i < 0x25500/2; i++) - { - x = 0x4200; - if ( (i & 0x0001) ) x |= 0x0400; - if ( (i & 0x0020) && !(i & 0x0001) ) x |= 0x0080; - if ( !(i & 0x0010) || (i & 0x0001) ) x |= 0x0040; - if ( (i & 0x0040) && !(i & 0x0001) ) x |= 0x0020; - if ( !(i & 0x0004) || (i & 0x0001) ) x |= 0x0010; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0004; - if ( (i & 0x0008) && !(i & 0x0001) ) x |= 0x0002; - if ( (i & 0x0002) || (i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; - } - - for (i = 0x25500/2; i < 0x25600/2; i++) - { - x = 0x4200; - if ( (i & 0x0001) ) x |= 0x0400; - if ( (i & 0x0010) && !(i & 0x0001) ) x |= 0x0080; - if ( (i & 0x0040) && !(i & 0x0001) ) x |= 0x0040; - if ( !(i & 0x0002) && !(i & 0x0001) ) x |= 0x0020; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0010; - if ( (i & 0x0008) && !(i & 0x0001) ) x |= 0x0008; - if ( (i & 0x0020) && !(i & 0x0001) ) x |= 0x0004; - if ( (i & 0x0004) && !(i & 0x0001) ) x |= 0x0002; - if ( (i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; - } - -/* - for (i = 0x25700/2; i < 0x25800/2; i++) - { - x = 0x6800; - if ( !(i & 0x0001) ) x |= 0x8000; - - if ( !(i & 0x0040) || ((i & 0x0001) || !(i & 0x0001)) ) x |= 0x0100; - - rom[i] ^= x; - } -*/ - - for (i = 0x25800/2; i < 0x25900/2; i++) - { - x = 0x8300; - if ( (i & 0x0040) || (i & 0x0001) ) x |= 0x2000; - if ( (i & 0x0002) || (i & 0x0001) ) x |= 0x0080; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0040; - if ( (i & 0x0020) && !(i & 0x0001) ) x |= 0x0020; - if ( !(i & 0x0004) || (i & 0x0001) ) x |= 0x0010; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0008; - if ( (i & 0x0010) && !(i & 0x0001) ) x |= 0x0004; - if ( (i & 0x0008) && !(i & 0x0001) ) x |= 0x0002; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; + u32 size = memregion("maincpu")->bytes(); + u16 *rom = (u16 *)memregion("maincpu")->base(); + std::unique_ptr<u16[]> tmp = std::make_unique<u16[]>(size/2); + + // Pass 1: decrypt high and low byte independently. They go + // trough a bitswap and an xor, choosing between 8 possibilities + // through address bits. + + for(u32 i = 0; i != size; i += 2) { + u16 orig = rom[i >> 1]; + u16 result = 0; + for(u32 rb = 0; rb < 2; rb ++) { + u8 val = orig >> (rb ? 0 : 8); + u32 index = + (BIT(i, table.rom[rb].bits[0]) << 2) | + (BIT(i, table.rom[rb].bits[1]) << 1) | + BIT(i, table.rom[rb].bits[2]); + val = bitswap(val, + table.rom[rb].entries[index].bits[0], + table.rom[rb].entries[index].bits[1], + table.rom[rb].entries[index].bits[2], + table.rom[rb].entries[index].bits[3], + table.rom[rb].entries[index].bits[4], + table.rom[rb].entries[index].bits[5], + table.rom[rb].entries[index].bits[6], + table.rom[rb].entries[index].bits[7]); + val = val ^ table.rom[rb].entries[index].xor_mask; + + result |= val << (rb ? 0 : 8); + } + tmp[i >> 1] = result; } -// for (i = 0x25900/2; i < 0x25a00/2; i++) - - for (i = 0x25c00/2; i < 0x25d00/2; i++) - { - // changed from 25400 -// x = 0x4200; - x = 0x4000; -// if ( (i & 0x0001) ) x |= 0x0400; - if ( (i & 0x0020) && !(i & 0x0001) ) x |= 0x0080; - if ( !(i & 0x0010) || (i & 0x0001) ) x |= 0x0040; - if ( (i & 0x0040) && !(i & 0x0001) ) x |= 0x0020; - if ( !(i & 0x0004) || (i & 0x0001) ) x |= 0x0010; - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0004; - if ( (i & 0x0008) && !(i & 0x0001) ) x |= 0x0002; - if ( (i & 0x0002) || (i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; + // Pass 2: copy back the decrypted data following the address + // scrambling + for(u32 i = 0; i != size; i += 2) { + u32 dest = + (i & 0xffffe0ff) | + (BIT(i, table.bits[0]) << 12) | + (BIT(i, table.bits[1]) << 11) | + (BIT(i, table.bits[2]) << 10) | + (BIT(i, table.bits[3]) << 9) | + (BIT(i, table.bits[4]) << 8); + rom[dest >> 1] = tmp[i >> 1]; } -/* - for (i = 0x25d00/2; i < 0x25e00/2; i++) - { - x = 0x4000; - if ( !(i & 0x0040) ) x |= 0x0800; - - if ( !(i & 0x0040) && !(i & 0x0001) ) x |= 0x0100; // almost!! - - if ( ((i & 0x0040)&&((i & 0x0020)||(i & 0x0010))) || !(i & 0x0001) ) x |= 0x0200; // almost!! - if ( (!(i & 0x0040) || !(i & 0x0008)) && !(i & 0x0001) ) x |= 0x0008; - if ( (i & 0x0040) || !(i & 0x0020) || (i & 0x0001) ) x |= 0x0001; // almost!! - rom[i] ^= x; - } -*/ - -/* - for (i = 0x25e00/2; i < 0x25f00/2; i++) - { - x = 0xa600; - - if ( (i & 0x0040) && (i & 0x0001) ) x |= 0x4000; - if ( (i & 0x0040) && (i & 0x0001) ) x |= 0x0800; - if ( !(i & 0x0001) ) x |= 0x0100; - - if ( ( (i & 0x0040) && (i & 0x0008) && !(i & 0x0001)) || - ( !(i & 0x0040) && ((i & 0x0004) ^ (i & 0x0002)) && !(i & 0x0001) ) ) x |= 0x0002; // almost!! - - if ( !(i & 0x0040) || !(i & 0x0002) || (i & 0x0001) ) x |= 0x0001; - rom[i] ^= x; - } -*/ + // There's more stuff happening for addresses < 0x400... - for (i = 0x26f00/2; i < 0x27000/2; i++) - { - x = 0xb94c; - rom[i] ^= x; - } +} - for (i = 0x27000/2; i < 0x27100/2; i++) +const astrocorp_state::decryption_info astrocorp_state::astoneag_table = { { - x = 0x5f10; - rom[i] ^= x; - } + { + { 11, 10, 9 }, + { + { { 7, 5, 4, 6, 0, 3, 2, 1 }, 0x00 }, + { { 1, 4, 6, 0, 2, 5, 3, 7 }, 0xd0 }, + { { 1, 7, 4, 3, 6, 5, 0, 2 }, 0x88 }, + { { 6, 5, 2, 3, 7, 1, 0, 4 }, 0xd1 }, + { { 6, 1, 7, 2, 4, 0, 3, 5 }, 0x64 }, + { { 1, 7, 2, 6, 5, 4, 3, 0 }, 0x83 }, + { { 6, 7, 4, 2, 5, 0, 1, 3 }, 0x81 }, + { { 7, 5, 1, 0, 2, 4, 6, 3 }, 0xea }, + } + }, + { + { 12, 10, 8 }, + { + { { 6, 5, 4, 3, 2, 1, 0, 7 }, 0x90 }, + { { 2, 4, 0, 7, 5, 6, 3, 1 }, 0x32 }, + { { 7, 1, 0, 6, 5, 2, 3, 4 }, 0xa9 }, + { { 2, 0, 3, 5, 1, 4, 6, 7 }, 0xa2 }, + { { 3, 0, 6, 5, 2, 1, 4, 7 }, 0x02 }, + { { 0, 1, 6, 4, 5, 2, 7, 3 }, 0x30 }, + { { 3, 5, 2, 7, 6, 1, 4, 0 }, 0x0a }, + { { 0, 6, 4, 2, 7, 3, 1, 5 }, 0x81 }, + } + }, + }, + { 12, 9, 11, 8, 10 } +}; -#endif +void astrocorp_state::init_astoneag() +{ + decrypt_rom(astoneag_table); } GAME( 2000, showhand, 0, showhand, showhand, astrocorp_state, init_showhand, ROT0, "Astro Corp.", "Show Hand (Italy)", MACHINE_SUPPORTS_SAVE ) |