Author Topic: What I've been working on (iq_132's work in progress)  (Read 329382 times)

Offline gamez fan

  • Expert
  • *****
  • Posts: 495
  • Karma: +13/-1
  • Arcade Addict
Re: What I've been working on (iq_132's work in progress)
« Reply #1335 on: October 31, 2017, 06:08:22 pm »
Last working deco32 game ^^

Fantastico!!

Offline Gab75

  • Sr. Member
  • ****
  • Posts: 481
  • Karma: +19/-0
  • All games deserve to be emulated, more or less! :P
Re: What I've been working on (iq_132's work in progress)
« Reply #1336 on: October 31, 2017, 06:11:04 pm »
Kiiiiiiick ass!!:D

I fully agree! ;)

Offline Combone

  • Newbies
  • *
  • Posts: 27
  • Karma: +1/-0
Re: What I've been working on (iq_132's work in progress)
« Reply #1337 on: November 05, 2017, 10:19:21 pm »
Amazing job  :cool:    iq_132
« Last Edit: November 05, 2017, 11:08:37 pm by iq_132 »

Offline Bad Dude

  • Newbies
  • *
  • Posts: 10
  • Karma: +0/-0
Re: What I've been working on (iq_132's work in progress)
« Reply #1338 on: November 12, 2017, 06:28:54 am »
Great to see new ports for FBA, like Night Slashers and Fighter's History! I'm a super fan of both games!  :biggrin:

Offline iq_132

  • Administrator
  • *****
  • Posts: 3879
  • Karma: +365/-0
  • No one expects the Spanish Inquisition!
    • NeoSource
Re: What I've been working on (iq_132's work in progress)
« Reply #1339 on: November 17, 2017, 04:33:06 pm »
Sometimes it's good to have a second set of eyes on things.

Today I was looking at namco NA1.

This snippet specifically jumped out at me.
Code: [Select]
TILE_GET_INFO_MEMBER(namcona1_state::roz_get_info)
{
/* each logical tile is constructed from 4*4 normal tiles */
int use_4bpp_gfx = m_vreg[0xbc/2]&16; /* ? */
int c = tile_index%0x40;
int r = tile_index/0x40;
int data = m_videoram[0x8000/2+(r/4)*0x40+c/4]&0xfbf; /* mask out bit 0x40 - patch for Emeraldia Japan */
int tile = (data+(c%4)+(r%4)*0x40)&0xfff;
int gfx = use_4bpp_gfx ? 1 : 0;
int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;

if( data & 0x8000 )
{
SET_TILE_INFO_MEMBER(gfx,tile,color,TILE_FORCE_LAYER0 );
}
else
{
SET_TILE_INFO_MEMBER(gfx,tile,color,0 );
tileinfo.mask_data = &m_shaperam[tile*8];
}
}

Breaking it down further:

This line, in particular, is the offender:
Quote
   int data = m_videoram[0x8000/2+(r/4)*0x40+c/4]&0xfbf; /* mask out bit 0x40 - patch for Emeraldia Japan */

What that means is that data above 0xfff in "data" is 0. That means the following bits never actually do anything!

Quote
   int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;

   if( data & 0x8000 )
   {
      SET_TILE_INFO_MEMBER(gfx,tile,color,TILE_FORCE_LAYER0 );
   }
   else
   {
      SET_TILE_INFO_MEMBER(gfx,tile,color,0 );
      tileinfo.mask_data = &m_shaperam[tile*8];
   }

I'm curious if this is causing bugs or just dead code.
« Last Edit: November 17, 2017, 05:02:48 pm by iq_132 »


Offline Gab75

  • Sr. Member
  • ****
  • Posts: 481
  • Karma: +19/-0
  • All games deserve to be emulated, more or less! :P
Re: What I've been working on (iq_132's work in progress)
« Reply #1340 on: January 11, 2018, 01:01:04 pm »
New games/drivers: Konami Double Dribble & SNK-6502/Rock-Ola drivers by iq_132 with the help of dink! :)

SNK/Rock-Ola games list:
Fantasy
Nibbler
Pioneer Balloon
Sasuke Vs. Commander
Satan Of Saturn / Zarzon
Vanguard

Offline iq_132

  • Administrator
  • *****
  • Posts: 3879
  • Karma: +365/-0
  • No one expects the Spanish Inquisition!
    • NeoSource
Re: What I've been working on (iq_132's work in progress)
« Reply #1341 on: January 12, 2018, 08:38:23 am »
So it's been pretty quiet lately, I figured I'd give you all a quick update.

My first project was working on route16. The game has been in MAME a long time (the non-bootlegs, since 2003!) and has always had the ROM hacked to bypass the protection.

I spent a lot of time disassembling the code for the game and figuring out exactly what it needed to make it work.

This is more or less all it takes to get the game working properly.
Code: [Select]
READ8_MEMBER(route16_state::route16_prot_read)
{
m_protection_data++;
return (1 << ((m_protection_data >> 1) & 7));
}


These are the ugly patches that are now gone :)

Code: [Select]
DRIVER_INIT_MEMBER(route16_state,route16)
{
uint8_t *ROM = memregion("cpu1")->base();
/* TO DO : Replace these patches with simulation of the protection device */

/* patch the protection */
ROM[0x0105] = 0x00; /* jp nz,$4109 (nirvana) - NOP's in route16c */
ROM[0x0106] = 0x00;
ROM[0x0107] = 0x00;

ROM[0x072a] = 0x00; /* jp nz,$4238 (nirvana) */
ROM[0x072b] = 0x00;
ROM[0x072c] = 0x00;

DRIVER_INIT_CALL(route16c);
}

DRIVER_INIT_MEMBER(route16_state,route16c)
{
uint8_t *ROM = memregion("cpu1")->base();
/* Is this actually a bootleg? some of the protection has
   been removed */

/* patch the protection */
ROM[0x00e9] = 0x3a;

ROM[0x0754] = 0xc3;
ROM[0x0755] = 0x63;
ROM[0x0756] = 0x07;
}


DRIVER_INIT_MEMBER(route16_state,route16a)
{
uint8_t *ROM = memregion("cpu1")->base();
/* TO DO : Replace these patches with simulation of the protection device */

/* patch the protection */
ROM[0x00e9] = 0x3a;

ROM[0x0105] = 0x00; /* jp nz,$4109 (nirvana) - NOP's in route16c */
ROM[0x0106] = 0x00;
ROM[0x0107] = 0x00;

ROM[0x0731] = 0x00; /* jp nz,$4238 (nirvana) */
ROM[0x0732] = 0x00;
ROM[0x0733] = 0x00;

ROM[0x0747] = 0xc3;
ROM[0x0748] = 0x56;
ROM[0x0749] = 0x07;
}


Next I looked at Metafox. This game has a special memory region that it tests and throws an error if it doesn't pass.

I was able to greatly simplify what it was actually doing (writing to RAM, reading back certain values at different addresses than they are written) to get the game to play nice.

Here's the nice, new protection sim.
Code: [Select]
READ16_MEMBER(seta_state::metafox_protection_r)
 {
// very simplified protection simulation
// 21c000-21c3ff, 21d000-21d3ff, and 21e000-21e3ff are tested as 8 bit reads/writes
// the first address in each range is special and returns data written elsewhere in that range
// 21fde0-21fdff appears to be control bytes?

switch (offset)
{
case 0x0001/2:
return 0x3d;
 
case 0x1001/2:
return 0x76;

case 0x2001/2:
return 0x10;
}

return offset * 0x1f;
}

DRIVER_INIT_MEMBER(seta_state,metafox)
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0x21c000, 0x21ffff,read16_delegate(FUNC(seta_state::metafox_protection_r),this));
}

Here are the patches that were needed before.
Code: [Select]
DRIVER_INIT_MEMBER(seta_state,metafox)
{
uint16_t *RAM = (uint16_t *) memregion("maincpu")->base();

/* This game uses the 21c000-21ffff area for protection? */
RAM[0x8ab1c/2] = 0x4e71;    // patch protection test: "cp error"
RAM[0x8ab1e/2] = 0x4e71;
RAM[0x8ab20/2] = 0x4e71;
}


Next, I took a look at Maketrax. This game and its clones (Crush Roller) have had a really nasty way of making them work.
They use 1. ROM patches to bypass some of the protection checks, 2. the opcodes were being copied to a seperate area of memory and being used like the game had an encrypted ROM so that it passes rom checks. 3. hardcoded checks to bypass more. This isn't good on multiple levels for properly emulating this game.

here's the new code to emulate the protection

Code: [Select]

WRITE8_MEMBER(pacman_state::maketrax_protection_w)
{
if (data == 0) // disable protection / reset?
{
m_maketrax_counter = 0;
m_maketrax_offset = 0;
m_maketrax_disable_protection = 1;
return;
}

if (data == 1)
{
m_maketrax_disable_protection = 0;

m_maketrax_counter++;
if (m_maketrax_counter == 0x3c)
{
m_maketrax_counter = 0;
m_maketrax_offset++;

if (m_maketrax_offset == 0x1e)
m_maketrax_offset = 0;
}
}
}

READ8_MEMBER(pacman_state::maketrax_special_port2_r)
{
const uint8_t protdata[0x1e] = { // table at $ebd (odd entries)
0x00, 0xc0, 0x00, 0x40, 0xc0, 0x40, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x40, 0xc0, 0x40,
0x00, 0xc0, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x40, 0xc0, 0x40, 0x00, 0xc0, 0x00, 0x40
};
 
if (m_maketrax_disable_protection == 0)
return protdata[m_maketrax_offset];

uint8_t data = ioport("DSW1")->read() & 0x3f;
 
switch (offset)
{
case 0x01:
case 0x04:
data |= 0x40; break;
case 0x05:
data |= 0xc0; break;
default:
data &= 0x3f; break;
}

return data;
}

READ8_MEMBER(pacman_state::maketrax_special_port3_r)
{
const uint8_t protdata[0x1e] = { // table at $ebd (even entries)
0x1f, 0x3f, 0x2f, 0x2f, 0x0f, 0x0f, 0x0f, 0x3f, 0x0f, 0x0f, 0x1c, 0x3c, 0x2c, 0x2c, 0x0c, 0x0c,
0x0c, 0x3c, 0x0c, 0x0c, 0x11, 0x31, 0x21, 0x21, 0x01, 0x01, 0x01, 0x31, 0x01, 0x01
};
 
if (m_maketrax_disable_protection == 0)
return protdata[m_maketrax_offset];

switch (offset)
{
case 0x00:
return 0x1f;
case 0x09:
return 0x30;
case 0x0c:
return 0x00;
default:
return 0x20;
}

Here's the old code.

Code: [Select]
READ8_MEMBER(pacman_state::maketrax_special_port2_r)
{
int data = ioport("DSW1")->read();
int pc = m_maincpu->pcbase();

if ((pc == 0x1973) || (pc == 0x2389)) return data | 0x40;

switch (offset)
{
case 0x01:
case 0x04:
data |= 0x40; break;
case 0x05:
data |= 0xc0; break;
default:
data &= 0x3f; break;
}

return data;
}

READ8_MEMBER(pacman_state::maketrax_special_port3_r)
{
int pc = m_maincpu->pcbase();

if (pc == 0x040e) return 0x20;

if ((pc == 0x115e) || (pc == 0x3ae2)) return 0x00;

switch (offset)
{
case 0x00:
return 0x1f;
case 0x09:
return 0x30;
case 0x0c:
return 0x00;
default:
return 0x20;
}
}

void pacman_state::maketrax_rom_decode()
{
uint8_t *rom = memregion("maincpu")->base();

/* patch protection using a copy of the opcodes so ROM checksum */
/* tests will not fail */

memcpy(m_patched_opcodes,rom,0x4000);

m_patched_opcodes[0x0415] = 0xc9;
m_patched_opcodes[0x1978] = 0x18;
m_patched_opcodes[0x238e] = 0xc9;
m_patched_opcodes[0x3ae5] = 0xe6;
m_patched_opcodes[0x3ae7] = 0x00;
m_patched_opcodes[0x3ae8] = 0xc9;
m_patched_opcodes[0x3aed] = 0x86;
m_patched_opcodes[0x3aee] = 0xc0;
m_patched_opcodes[0x3aef] = 0xb0;
}

DRIVER_INIT_MEMBER(pacman_state,maketrax)
{
/* set up protection handlers */
m_maincpu->space(AS_PROGRAM).install_read_handler(0x5080, 0x50bf, read8_delegate(FUNC(pacman_state::maketrax_special_port2_r),this));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x50c0, 0x50ff, read8_delegate(FUNC(pacman_state::maketrax_special_port3_r),this));

maketrax_rom_decode();
}


Robert pointed out that after this change crushbl2 and mbrush (clones of maketrax) were not working.
These bootlegs had most of the protection changed! I looked at every read the games do from the area where the protection chip usually sits and figured out what it was expecting back.

Robert took some liberties with the code to make it a little clearer

Code: [Select]
READ8_MEMBER(pacman_state::mbrush_prot_r)
{
uint8_t data = ioport("DSW1")->read() & 0x3f;

switch (offset)
{
case 0x00:
case 0x04:
case 0x07:
case 0x0e:
case 0x0f:
return 0xc0 | data;
case 0x40:
case 0x41:
case 0x47:
case 0x49:
case 0x4d:
case 0x5d:
return 0x00;
case 0x42:
case 0x43:
case 0x46:
case 0x4c:
case 0x50:
return 0x02;
case 0x7f:
return 0x10;
}

return data;
}



Offline gamez fan

  • Expert
  • *****
  • Posts: 495
  • Karma: +13/-1
  • Arcade Addict
Re: What I've been working on (iq_132's work in progress)
« Reply #1342 on: January 12, 2018, 06:36:43 pm »
New games/drivers: Konami Double Dribble & SNK-6502/Rock-Ola drivers by iq_132 with the help of dink! :)

SNK/Rock-Ola games list:
Fantasy
Nibbler
Pioneer Balloon
Sasuke Vs. Commander
Satan Of Saturn / Zarzon
Vanguard

Nice work fellas!!

Offline Robert

  • MAME Devs
  • *****
  • Posts: 383
  • Karma: +27/-0
    • The MESSUI Place
Re: What I've been working on (iq_132's work in progress)
« Reply #1343 on: January 13, 2018, 08:01:26 am »
In HBMAME, there's just one hack of maketrax called mtturbo and it also uses the same protection. I eliminated the protection tables and told it to read the rom directly.

iq_132 has done a good job of getting rid of the blatant hacks which mostly have been in MAME forever. :)
« Last Edit: January 16, 2018, 02:36:50 am by Robert »

Offline iq_132

  • Administrator
  • *****
  • Posts: 3879
  • Karma: +365/-0
  • No one expects the Spanish Inquisition!
    • NeoSource
Re: What I've been working on (iq_132's work in progress)
« Reply #1344 on: January 13, 2018, 10:15:31 am »
In HBMAME, there's just one hack of maketrax called mtturbo and it also uses the same protection. I eliminated the protection tables and told it to read the rom directly.

iq_132 has done a good job of getting rid of the blatant hacks which mostly have been there forever. :)


Thanks again for submitting all of that stuff, cleaning up the dead hack stuff, testing, and making sure my stuff is up to MAME standards :)


Offline gamez fan

  • Expert
  • *****
  • Posts: 495
  • Karma: +13/-1
  • Arcade Addict
Re: What I've been working on (iq_132's work in progress)
« Reply #1345 on: January 15, 2018, 08:32:32 pm »
Ok me and dink have been busy adding in the speedhacks for all the games in the d_deco32.cpp driver, i had the easy bit reuse
the existing ARM CPU speedup code from d_backfire.cpp or d_simpl156.cpp and then add in the speedhacks from older MAME
dink did the real graft by pinning down the address values and adding new ones for every version of Fighters History and the
USA version of Night Slashers.

This will be of great benefit to those who use FBA on some lesser platforms like the Android, Rpi or even my ole Xbox :)


Enjoy!!

Offline barbudreadmon

  • Expert
  • *****
  • Posts: 217
  • Karma: +6/-0
  • lr-fbalpha developer
Re: What I've been working on (iq_132's work in progress)
« Reply #1346 on: January 16, 2018, 04:04:22 am »
Nice work :).

Offline furiadeoso

  • Newbies
  • *
  • Posts: 31
  • Karma: +0/-0
    • EMUpartidas online
Re: What I've been working on (iq_132's work in progress)
« Reply #1347 on: January 16, 2018, 06:40:15 am »
Ok me and dink have been busy adding in the speedhacks for all the games in the d_deco32.cpp driver, i had the easy bit reuse
the existing ARM CPU speedup code from d_backfire.cpp or d_simpl156.cpp and then add in the speedhacks from older MAME
dink did the real graft by pinning down the address values and adding new ones for every version of Fighters History and the
USA version of Night Slashers.

This will be of great benefit to those who use FBA on some lesser platforms like the Android, Rpi or even my ole Xbox :)


Enjoy!!

Nice! I'm looking forward to netplay with Night Slashers!