// Fast raw chunk reader
static void DOReadChunk(StateMem *st, SFORMAT *sf)
{
   while(sf->size || sf->name)       // Size can sometimes be zero, so also check for the text name.  
      // These two should both be zero only at the end of a struct.
   {
      if(!sf->size || !sf->v)
      {
         sf++;
         continue;
      }

      if(sf->size == (uint32_t) ~0) // Link to another SFORMAT struct
      {
         DOReadChunk(st, (SFORMAT *)sf->v);
         sf++;
         continue;
      }

      int32_t bytesize = sf->size;

      // Loading raw data, bool types are stored as they appear in memory, not as single bytes in the full state format.
      // In the SFORMAT structure, the size member for bool entries is the number of bool elements, not the total in-memory size,
      // so we adjust it here.
      if(sf->flags & MDFNSTATE_BOOL)
         bytesize *= sizeof(bool);

      smem_read(st, (uint8_t *)sf->v, bytesize);
      sf++;
   }
}
示例#2
0
文件: slib.c 项目: AzagraMac/PS2_SDK
/**
 * slib_get_exp_lib - Retrieve an export library by name.
 */
int slib_get_exp_lib(const char *name, slib_exp_lib_t *library)
{
	u8 buf[0x300];	/* We can even handle CDVDMAN's bloat!  */
	slib_exp_lib_list_t *exp_lib_list = &_slib_cur_exp_lib_list;
	slib_exp_lib_t *exp_lib = (slib_exp_lib_t *)buf;
	void *cur_lib;
	int len = strlen(name), count = 0;

	if (!exp_lib_list->head && !(exp_lib_list = slib_exp_lib_list()))
		return 0;

	/* Read the tail export library to initiate the search.  */
	cur_lib = exp_lib_list->tail;

	while (cur_lib) {
		smem_read(cur_lib, exp_lib, sizeof buf);

		if (!__memcmp(exp_lib->name, name, len)) {
			while (exp_lib->exports[count] != 0)
				count++;

			if (library)
				memcpy(library, exp_lib, sizeof(slib_exp_lib_t) + count * 4);

			return count;
		}

		cur_lib = exp_lib->prev;
	}

	return 0;
}
示例#3
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only)
{
	SFORMAT *tmp;
	int temp;

	if(data_only)
	{
		DOReadChunk(st, sf);
	}
	else
	{
		temp = smem_tell(st);
		while(smem_tell(st) < temp + size)
		{
			uint32 tsize;
			char toa[32];

			if(smem_read(st, toa, 32) <= 0)
			{
				puts("Unexpected EOF?");
				return 0;
			}

			smem_read32le(st, &tsize);
			if((tmp=CheckS(sf,tsize,toa)))
			{
				int32 bytesize = tmp->s&(~(MDFNSTATE_RLSB32 | MDFNSTATE_RLSB16 | RLSB));

				smem_read(st, (uint8 *)tmp->v, bytesize);

				if(tmp->s & MDFNSTATE_RLSB32)
					Endian_A32_LE_to_NE(tmp->v, bytesize / sizeof(uint32));
				else if(tmp->s & MDFNSTATE_RLSB16)
					Endian_A16_LE_to_NE(tmp->v, bytesize / sizeof(uint16));
				else if(tmp->s&RLSB)
					Endian_V_LE_to_NE(tmp->v, bytesize);
			}
			else
				if(smem_seek(st,tsize,SEEK_CUR) < 0)
				{
					puts("Seek error");
					return(0);
				}
		} // while(...)
	}
	return 1;
}
int MDFNSS_StateAction(void* st_p, int load, SFORMAT* sf, const char* name)
{
   StateMem* st = (StateMem*)st_p;
   if (load)
   {
      char sname[32];

      int found = 0;
      uint32 tmp_size;
      uint32 total = 0;

      while (smem_read(st, (uint8*)sname, 32) == 32)
      {
         if (smem_read32le(st, &tmp_size) != 4)
            return (0);

         total += tmp_size + 32 + 4;

         // Yay, we found the section
         if (!strncmp(sname, name, 32))
         {
            if (!ReadStateChunk(st, sf, tmp_size))
            {
               printf("Error reading chunk: %s\n", name);
               return (0);
            }
            found = 1;
            break;
         }
         else
         {
            if (smem_seek(st, tmp_size, SEEK_CUR) < 0)
            {
               puts("Chunk seek failure");
               return (0);
            }
         }
      }
      if (smem_seek(st, -total, SEEK_CUR) < 0)
      {
         puts("Reverse seek error");
         return (0);
      }
      if (!found) // Not found.  We are sad!
      {
         printf("Section missing:  %.32s\n", name);
         return (0);
      }


   }
   else
   {
      if (!WriteStateChunk(st, name, sf))
         return (0);
   }

   return (1);
}
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
static int MDFNSS_StateAction_internal(void *st_p, int load, int data_only, SSDescriptor *section)
{
   StateMem *st = (StateMem*)st_p;

   if(load)
   {
      char sname[32];

      int found = 0;
      uint32_t tmp_size;
      uint32_t total = 0;

      while(smem_read(st, (uint8_t *)sname, 32) == 32)
      {
         if(smem_read32le(st, &tmp_size) != 4)
            return(0);

         total += tmp_size + 32 + 4;

         // Yay, we found the section
         if(!strncmp(sname, section->name, 32))
         {
            if(!ReadStateChunk(st, section->sf, tmp_size))
            {
               printf("Error reading chunk: %s\n", section->name);
               return(0);
            }
            found = 1;
            break;
         } 
         else
         {
            if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
            {
               puts("Chunk seek failure");
               return(0);
            }
         }
      }
      if(smem_seek(st, -total, SEEK_CUR) < 0)
      {
         puts("Reverse seek error");
         return(0);
      }
      if(!found && !section->optional) // Not found.  We are sad!
      {
         printf("Section missing:  %.32s\n", section->name);
         return(0);
      }
   }
   else
   {
      if(!WriteStateChunk(st, section->name, section->sf))
         return(0);
   }

   return(1);
}
示例#6
0
void list_loaded_modules(void)
{
	char search_name[60];
	smod_mod_info_t	mod_t;

	smod_get_next_mod(NULL,&mod_t);

	smem_read(mod_t.name, search_name, sizeof search_name);

	printf("Module %d is %s\n", mod_t.id, search_name);

	while(smod_get_next_mod(&mod_t,&mod_t))
	{
		smem_read(mod_t.name, search_name, sizeof search_name);
		printf("Module %d is %s\n", mod_t.id, search_name);
	}

}
int smem_read32le(StateMem *st, uint32_t *b)
{
   uint8_t s[4];

   if(smem_read(st, s, 4) < 4)
      return(0);

   *b = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);

   return(4);
}
示例#8
0
文件: slib.c 项目: AzagraMac/PS2_SDK
/**
 * slib_exp_lib_list - Find the head and tail of the export library list.
 *
 * Returns NULL if the list couldn't be found, and the address of the head and
 * tail pointers if it was located.
 *
 * This routine will need to be called everytime the IOP is reset.
 */
slib_exp_lib_list_t *slib_exp_lib_list()
{
	slib_exp_lib_t *core_exps;
	u32 *exp_func, *core_info;
	u8 *smem_loc;	/* Current location into our IOP mem buffer.  */
	slib_exp_lib_list_t *exp_lib_list = 0;
	u32 i, addr, core_end, gmt_ofs = 0x800;

	/* Read 16k of IOP RAM from the start of the global module table -
	   this is where we will search.  */
	smem_read((void *)gmt_ofs, smem_buf, SEARCH_SIZE);

	/* The first entry points to LOADCORE's module info.  We then use the
	   module info to determine the end of LOADCORE's .text segment (just
	   past the export library we're trying to find.  */
	core_info = (u32 *)(smem_buf + (*(u32 *)smem_buf - gmt_ofs));
	core_end = core_info[6] + core_info[7];  /* 6 and 7 are .text start and end.  */

	/* Back up so we position ourselves infront of where the export
	   library will be.  */
	smem_loc = smem_buf + core_end - gmt_ofs - 512;
	
	/* Search for LOADCORE's export library.  */
	for (i = 0; i < 512; i += 4) {
		/* SYSMEM's export library sits at 0x830, so it should appear in
		   LOADCORE's prev pointer.  */
		if (*(u32 *)(smem_loc + i) == 0x830) {
			if (!__memcmp(smem_loc + i + 12, "loadcore", 8))
				break;
		}
	}
	if (i >= 512)
		return 0;

	/* Get to the start of the export table, and find the address of the
	   routine that will get us the export library list info.  */
	core_exps = (slib_exp_lib_t *)(smem_loc + i);
	exp_func = (u32 *)(smem_buf + (u32)core_exps->exports[3] - gmt_ofs);

	/* Parse the two instructions that hold the address of the table.  */
	if ((exp_func[0] & 0xffff0000) != 0x3c020000)	/* lui v0, XXXX */
		return 0;
	if ((exp_func[1] & 0xffff0000) != 0x24420000)	/* addiu v0, v0, XXXX */
		return 0;

	addr = (exp_func[0] & 0xffff) << 16;
	addr |= exp_func[1] & 0xffff;
	addr -= gmt_ofs;
	_slib_cur_exp_lib_list.tail = (slib_exp_lib_t *)(*(u32 *)(smem_buf + addr));
	_slib_cur_exp_lib_list.head = (slib_exp_lib_t *)(*(u32 *)(smem_buf + addr + 4));
	exp_lib_list = &_slib_cur_exp_lib_list;

	return exp_lib_list;
}
int MDFNSS_LoadSM(void *st_p, int, int)
{
   uint8_t header[32];
   uint32_t stateversion;
   StateMem *st = (StateMem*)st_p;

   smem_read(st, header, 32);

   if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
      return(0);

   stateversion = MDFN_de32lsb(header + 16);

   return StateAction(st, stateversion, 0);
}
示例#10
0
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only)
{
	uint8 header[32];
	uint32 stateversion;

	if(data_only)
	{
		stateversion = MEDNAFEN_VERSION_NUMERIC;
	}
	else
	{
		smem_read(st, header, 32);
		// if(memcmp(header,"MEDNAFENSVESTATE",16))
		// return(0);

		stateversion = MDFN_de32lsb(header + 16);

		if(stateversion < 0x0600)
		{
			// printf("State too old: %08x\n", stateversion);
			// return(0);
		}
	}

	currFrameCounter = MDFN_de32lsb(header + 12);
	pcejin.lagFrameCounter = MDFN_de32lsb(header + 16);

	if(haspreview)
	{
		uint32 width = MDFN_de32lsb(header + 24);
		uint32 height = MDFN_de32lsb(header + 28);
		uint32 psize;

		//PREVIEWIMAGE
		psize = width * height * 4;
		smem_seek(st, psize, SEEK_CUR); // Skip preview
	}

	// State rewinding code path hack, FIXME
	if(data_only)
	{
		// if(!MDFN_RawInputStateAction(st, stateversion, data_only))
		return(0);
	}

	return(MDFNGameInfo->StateAction(st, stateversion, data_only));
}
示例#11
0
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only)
{
        uint8 header[32];
	uint32 stateversion;

	if(data_only)
	{
	 stateversion = MEDNAFEN_VERSION_NUMERIC;
	}
	else
	{
         smem_read(st, header, 32);

         if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
          return(0);

	 stateversion = MDFN_de32lsb(header + 16);
	}

	if(haspreview)
        {
         uint32 width = MDFN_de32lsb(header + 24);
         uint32 height = MDFN_de32lsb(header + 28);
	 uint32 psize;

	 psize = width * height * 3;
	 smem_seek(st, psize, SEEK_CUR);	// Skip preview
 	}

	// State rewinding code path hack, FIXME
	if(data_only)
	{
	 if(!MDFN_RawInputStateAction(st, stateversion, data_only))
	  return(0);
	}

	return(MDFNGameInfo->StateAction(st, stateversion, data_only));
}
示例#12
0
// Fast raw chunk reader
static void DOReadChunk(StateMem *st, SFORMAT *sf)
{
	while(sf->s || sf->desc)// Size can sometimes be zero, so also check for the text description.
		// These two should both be zero only at the end of a struct.
	{
		if(!sf->s || !sf->v)
		{
			sf++;
			continue;
		}

		if(sf->s == (uint32) ~0) // Link to another SFORMAT struct
		{
			DOReadChunk(st, (SFORMAT *)sf->v);
			sf++;
			continue;
		}

		int32 bytesize = sf->s&(~(MDFNSTATE_RLSB32 | MDFNSTATE_RLSB16 | RLSB));

		smem_read(st, (uint8 *)sf->v, bytesize);
		sf++;
	}
}
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size)
{
   int temp = st->loc;

   while (st->loc < (temp + size))
   {
      uint32_t recorded_size;	// In bytes
      uint8_t toa[1 + 256];	// Don't change to char unless cast toa[0] to unsigned to smem_read() and other places.

      if(smem_read(st, toa, 1) != 1)
      {
         puts("Unexpected EOF");
         return(0);
      }

      if(smem_read(st, toa + 1, toa[0]) != toa[0])
      {
         puts("Unexpected EOF?");
         return 0;
      }

      toa[1 + toa[0]] = 0;

      smem_read32le(st, &recorded_size);

      SFORMAT *tmp = FindSF((char*)toa + 1, sf);

      if(tmp)
      {
         uint32_t expected_size = tmp->size;	// In bytes

         if(recorded_size != expected_size)
         {
            printf("Variable in save state wrong size: %s.  Need: %d, got: %d\n", toa + 1, expected_size, recorded_size);
            if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
            {
               puts("Seek error");
               return(0);
            }
         }
         else
         {
            smem_read(st, (uint8_t *)tmp->v, expected_size);

            if(tmp->flags & MDFNSTATE_BOOL)
            {
               // Converting downwards is necessary for the case of sizeof(bool) > 1
               for(int32_t bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--)
               {
                  ((bool *)tmp->v)[bool_monster] = ((uint8_t *)tmp->v)[bool_monster];
               }
            }
#ifdef MSB_FIRST
            if(tmp->flags & MDFNSTATE_RLSB64)
               Endian_A64_LE_to_NE(tmp->v, expected_size / sizeof(uint64_t));
            else if(tmp->flags & MDFNSTATE_RLSB32)
               Endian_A32_LE_to_NE(tmp->v, expected_size / sizeof(uint32_t));
            else if(tmp->flags & MDFNSTATE_RLSB16)
               Endian_A16_LE_to_NE(tmp->v, expected_size / sizeof(uint16_t));
            else if(tmp->flags & RLSB)
               Endian_V_LE_to_NE(tmp->v, expected_size);
#endif
         }
      }
      else
      {
         printf("Unknown variable in save state: %s\n", toa + 1);
         if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
         {
            puts("Seek error");
            return(0);
         }
      }
   } // while(...)

   assert(st->loc == (temp + size));
   return 1;
}
示例#14
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size)
{
    int temp;

    {
        SFMap_t sfmap;
        SFMap_t sfmap_found;	// Used for identifying variables that are missing in the save state.

        MakeSFMap(sf, sfmap);

        temp = smem_tell(st);
        while(smem_tell(st) < (temp + size))
        {
            uint32 recorded_size;	// In bytes
            uint8 toa[1 + 256];	// Don't change to char unless cast toa[0] to unsigned to smem_read() and other places.

            if(smem_read(st, toa, 1) != 1)
            {
                puts("Unexpected EOF");
                return(0);
            }

            if(smem_read(st, toa + 1, toa[0]) != toa[0])
            {
                puts("Unexpected EOF?");
                return 0;
            }

            toa[1 + toa[0]] = 0;

            smem_read32le(st, &recorded_size);

            SFMap_t::iterator sfmit;

            sfmit = sfmap.find((char *)toa + 1);

            if(sfmit != sfmap.end())
            {
                SFORMAT *tmp = sfmit->second;
                uint32 expected_size = tmp->size;	// In bytes

                if(recorded_size != expected_size)
                {
                    printf("Variable in save state wrong size: %s.  Need: %d, got: %d\n", toa + 1, expected_size, recorded_size);
                    if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
                    {
                        puts("Seek error");
                        return(0);
                    }
                }
                else
                {
                    sfmap_found[tmp->name] = tmp;

                    smem_read(st, (uint8 *)tmp->v, expected_size);

                    if(tmp->flags & MDFNSTATE_BOOL)
                    {
                        // Converting downwards is necessary for the case of sizeof(bool) > 1
                        for(int32 bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--)
                        {
                            ((bool *)tmp->v)[bool_monster] = ((uint8 *)tmp->v)[bool_monster];
                        }
                    }
                    if(tmp->flags & MDFNSTATE_RLSB64)
                        Endian_A64_LE_to_NE(tmp->v, expected_size / sizeof(uint64));
                    else if(tmp->flags & MDFNSTATE_RLSB32)
                        Endian_A32_LE_to_NE(tmp->v, expected_size / sizeof(uint32));
                    else if(tmp->flags & MDFNSTATE_RLSB16)
                        Endian_A16_LE_to_NE(tmp->v, expected_size / sizeof(uint16));
                    else if(tmp->flags & RLSB)
                        Endian_V_LE_to_NE(tmp->v, expected_size);
                }
            }
            else
            {
                printf("Unknown variable in save state: %s\n", toa + 1);
                if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
                {
                    puts("Seek error");
                    return(0);
                }
            }
        } // while(...)

        for(SFMap_t::const_iterator it = sfmap.begin(); it != sfmap.end(); it++)
        {
            if(sfmap_found.find(it->second->name) == sfmap_found.end())
            {
                printf("Variable missing from save state: %s\n", it->second->name);
            }
        }

        assert(smem_tell(st) == (temp + size));
    }
    return 1;
}
示例#15
0
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
int MDFNSS_StateAction(void *st_p, int load, int data_only, std::vector <SSDescriptor> &sections)
{
    StateMem *st = (StateMem*)st_p;
    std::vector<SSDescriptor>::iterator section;

    if(load)
    {
        {
            char sname[32];

            for(section = sections.begin(); section != sections.end(); section++)
            {
                int found = 0;
                uint32 tmp_size;
                uint32 total = 0;

                while(smem_read(st, (uint8 *)sname, 32) == 32)
                {
                    if(smem_read32le(st, &tmp_size) != 4)
                        return(0);

                    total += tmp_size + 32 + 4;

                    // Yay, we found the section
                    if(!strncmp(sname, section->name, 32))
                    {
                        if(!ReadStateChunk(st, section->sf, tmp_size))
                        {
                            printf("Error reading chunk: %s\n", section->name);
                            return(0);
                        }
                        found = 1;
                        break;
                    }
                    else
                    {
                        if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
                        {
                            puts("Chunk seek failure");
                            return(0);
                        }
                    }
                }
                if(smem_seek(st, -total, SEEK_CUR) < 0)
                {
                    puts("Reverse seek error");
                    return(0);
                }
                if(!found && !section->optional) // Not found.  We are sad!
                {
                    printf("Section missing:  %.32s\n", section->name);
                    return(0);
                }
            }
        }
    }
    else
    {
        for(section = sections.begin(); section != sections.end(); section++)
        {
            if(!WriteStateChunk(st, section->name, section->sf))
                return(0);
        }
    }

    return(1);
}
示例#16
0
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDescriptor> &sections)
{
	std::vector<SSDescriptor>::iterator section;

	if(load)
	{
		char sname[4];

		for(section = sections.begin(); section != sections.end(); section++)
		{
			if(data_only)
			{
				ReadStateChunk(st, section->sf, ~0, 1);
			}
			else
			{
				int found = 0;
				uint32 tmp_size;
				uint32 total = 0;
				while(smem_read(st, (uint8 *)sname, 4) == 4)
				{
					if(!smem_read32le(st, &tmp_size)) return(0);
					total += tmp_size + 8;
					// Yay, we found the section
					if(!memcmp(sname, section->name, 4))
					{
						if(!ReadStateChunk(st, section->sf, tmp_size, 0))
						{
							printf("Error reading chunk: %.4s\n", section->name);
							return(0);
						}
						found = 1;
						break;
					}
					else
					{
						//puts("SEEK");
						if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
						{
							puts("Chunk seek failure");
							return(0);
						}
					}
				}
				if(smem_seek(st, -(int)total, SEEK_CUR) < 0)
				{
					puts("Reverse seek error");
					return(0);
				}
				if(!found && !section->optional) // Not found. We are sad!
				{
					printf("Chunk missing: %.4s\n", section->name);
					return(0);
				}
			}
		}
	}
	else
		for(section = sections.begin(); section != sections.end(); section++)
		{
			if(!WriteStateChunk(st, section->name, section->sf, data_only))
				return(0);
		}
		return(1);
}
示例#17
0
int sbv_patch_enable_lmb()
{
	u8 buf[256];
	slib_exp_lib_t *modload_lib = (slib_exp_lib_t *)buf;
	smod_mod_info_t *loadfile_info = (smod_mod_info_t *)buf;
	void *pStartModule, *pLoadModuleBuffer, *lf_text_start, *patch_addr;
	u32 lf_rpc_dispatch, lf_jump_table, result;
	int nexps, id, i;

	memset(&_slib_cur_exp_lib_list, 0, sizeof(slib_exp_lib_list_t));

	/* Locate the modload export library - it must have at least 16 exports.  */
	if ((nexps = slib_get_exp_lib("modload", modload_lib)) < 16)
		return -1;

	pStartModule = modload_lib->exports[8];
	pLoadModuleBuffer = modload_lib->exports[10];

	/* Now we need to find the loadfile module.  */
	memset(buf, 0, sizeof(smod_mod_info_t));
	if (!(id = smod_get_mod_by_name("LoadModuleByEE", loadfile_info)))
		return -1;

	/* Locate the loadfile RPC dispatch code, where the first 4 instructions look like:
	
	   27bdffe8	addiu	$sp, -24
	   2c820006	sltiu	$v0, $a0, 6
	   14400003	bnez	$v0, +12
	   afbf0010	sw	$ra, 0x10($sp)
	*/
	lf_text_start = (void *)(loadfile_info->text_start + 0x400);
	smem_read(lf_text_start, buf, sizeof buf);

	for (i = 0; i < sizeof buf; i += 4) {
		if ((*(u32 *)(buf + i) == 0x27bdffe8) &&
				(*(u32 *)(buf + i + 4) == 0x2c820006) &&
				(*(u32 *)(buf + i + 8) == 0x14400003) &&
				(*(u32 *)(buf + i + 12) == 0xafbf0010))
			break;
	}
	/* This is a special case: if the IOP was reset with an image that contains a
	   LOADFILE that supports LMB, we won't detect the dispatch routine.  If we
	   even got this far in the code then we can return success.  */
	if (i >= sizeof buf)
		return 0;

	/* We need to extract the address of the jump table, it's only 40 bytes in. */
	lf_rpc_dispatch = (u32)lf_text_start + i;
	smem_read((void *)lf_rpc_dispatch, buf, 40);

	lf_jump_table = (*(u16 *)(buf + 0x1c) << 16) + *(s16 *)(buf + 0x24);

	/* Now we can patch our subversive LoadModuleBuffer RPC call.  */
	SifInitIopHeap();
	if (!(patch_addr = SifAllocIopHeap(sizeof lmb_patch)))
		return -1;

	/* result is where the RPC return structure is stored.  */
	result = (u32)patch_addr + 96;
	lmb_patch[5] = JAL((u32)pLoadModuleBuffer);
	lmb_patch[7] = HI16(result);
	lmb_patch[9] = LO16(result);
	lmb_patch[15] = JAL((u32)pStartModule);

	SyncDCache(lmb_patch, (void *)(lmb_patch + 24));
	smem_write(patch_addr, lmb_patch, sizeof lmb_patch);

	/* Finally.  The last thing to do is to patch the loadfile RPC dispatch routine
	   so that it will jump to entry #6 in it's jump table, and to patch the jump
	   table itself.  */
	ee_kmode_enter();
	*(u32 *)(SUB_VIRT_MEM + lf_rpc_dispatch + 4) = 0x2c820007;
	*(u32 *)(SUB_VIRT_MEM + lf_jump_table + 0x18) = (u32)patch_addr;
	ee_kmode_exit();

	return 0;
}
示例#18
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only)
{
 int temp;

 if(data_only)
 {
  DOReadChunk(st, sf);
 }
 else
 {
  SFMap_t sfmap;
  SFMap_t sfmap_found;	// Used for identify variables that are missing in the save state.

  MakeSFMap(sf, sfmap);

  temp = smem_tell(st);
  while(smem_tell(st) < (temp + size))
  {
   uint32 tsize;
   char toa[1 + 256];

   if(smem_read(st, toa, 1) != 1)
   {
    puts("Unexpected EOF");
    return(0);
   }

   if(smem_read(st, toa + 1, toa[0]) != toa[0])
   {
    puts("Unexpected EOF?");
    return 0;
   }

   toa[1 + toa[0]] = 0;

   smem_read32le(st, &tsize);

   SFMap_t::iterator sfmit;

   sfmit = sfmap.find(toa + 1);

   if(sfmit != sfmap.end())
   {
    SFORMAT *tmp = sfmit->second;
    int32 bytesize = tmp->size;

    sfmap_found[tmp->name] = tmp;

    smem_read(st, (uint8 *)tmp->v, bytesize);

    if(tmp->flags & MDFNSTATE_BOOL)
    {
     // Converting downwards is necessary for the case of sizeof(bool) > 1
     for(int32 bool_monster = bytesize - 1; bool_monster >= 0; bool_monster--)
     {
      ((bool *)tmp->v)[bool_monster] = (bool)((uint8 *)tmp->v)[bool_monster];
     }
    }
    if(tmp->flags & MDFNSTATE_RLSB64)
     Endian_A64_LE_to_NE(tmp->v, bytesize / sizeof(uint64));
    else if(tmp->flags & MDFNSTATE_RLSB32)
     Endian_A32_LE_to_NE(tmp->v, bytesize / sizeof(uint32));
    else if(tmp->flags & MDFNSTATE_RLSB16)
     Endian_A16_LE_to_NE(tmp->v, bytesize / sizeof(uint16));
    else if(tmp->flags & RLSB)
     Endian_V_LE_to_NE(tmp->v, bytesize);
   }
   else
   {
    printf("Unknown variable in save state: %s\n", toa + 1);
    if(smem_seek(st, tsize, SEEK_CUR) < 0)
    {
     puts("Seek error");
     return(0);
    }
   }
  } // while(...)

  for(SFMap_t::const_iterator it = sfmap.begin(); it != sfmap.end(); it++)
  {
   if(sfmap_found.find(it->second->name) == sfmap_found.end())
   {
    printf("Variable missing from save state: %s\n", it->second->name);
   }
  }

  assert(smem_tell(st) == (temp + size));
 }
 return 1;
}