Announcement

Collapse
No announcement yet.

Where does the PS1 GameShark engine live?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Where does the PS1 GameShark engine live?

    The engine is the assembly routine that parses the code list and preforms appropriate actions depending on code types. On the PS2, this is usually copied to a free area in kernel memory, then a hook code replaces an instruction that gets called many times a second with a jump to the code enigine before executing the original instruction it replaced.

    My wild guess as to how it works on the PS1 is that it copies the code engine to an unused area in kernel memory and replaces the address of either one of the exception vectors to point to the code engine (maybe the vblank handler?). It will then call the original exception vector or BIOS function after parsing the code list.

    Another possibility is that it modifies the COP0 debug-break vector (http://problemkaputt.de/psx-spx.htm#biosmemorymap) to point to the code engine. Here is a function found in the Beatmania 5th source code that detects if a "Pro Action Replay 3" is detected:
    Code:
    /* =========================================================================== */
    /* --------------------------------------------- */
    /* PAR3 が装着してあるかを調べる                 */
    /* return 0: PAR3 なし                           */
    /*        0以外: PAR3 あり                       */
    /*       多分全機種でOKだと思います              */
    /* --------------------------------------------- */
    int
    Check_PAR3_existance (void)
    {
      int i;
    //  unsigned int  *code1, *code2;
      unsigned char  *p, *base;
    
      base = (unsigned char *)0;
    
      p = base+0x40;
    
      for (i = 0; i < 3; i++, p += 4)
        {
          if ((*(p+3) == 0x3c) && (*(p+1) == 0x1f) && (*p == 0x00))
    	return *(p+1);
        }
    
      p = base + 0xf40;
      if ((*(p+3) == 0x3c) && (*(p+1) == 0x1f) && (*p == 0x00))
          return *(p+1);
    
      p = base + 0x998;
      if ((*(p+3) == 0x1f) && (*(p+2) == 0x00))
        return *(p+3);
    
      return (int)base;
    }
    According to the no$psx documentation, 0x00000040 is where the COP0 debug-vector is stored. It looks like it checks this to make sure it hasn't been modified.

    But that's just a guess and I haven't dug into it much to verify this. Most games don't require Master/Enable codes, so it must be patching a function that's universal to every game and console. Some games require Master Codes because the games have checks similar to these in place.
    Last edited by root670; 12-18-2014, 11:06:27 AM.

  • #2
    Did a little research and figured it out! This was found with CodeBreaker PS1, but it might be done similarly in GameShark. The engine code is installed to 0x00000A00 and the code list is at 0000F800. It modifies the B(nnh) function vector at 0x000000B0 to jump to 0x00000A00 instead of the original B(nnh) handler. The engine then jumps to the original B(nnh) handler if the requested function (the function ID is stored in the t1 register) is NOT 0x17 (ReturnFromException()). So this means that the code engine gets executed after every exception.

    I'll look into GameShark to see if it does the same thing, but this making a homebrew cheat device might be a cool project
    Last edited by root670; 12-18-2014, 10:18:30 PM.

    Comment

    Working...
    X