int state_load(unsigned char *buffer) { /* buffer size */ int bufferptr = 0; /* first allocate state buffer */ unsigned char *state = (unsigned char *)malloc(STATE_SIZE); if (!state) return 0; /* uncompress savestate */ unsigned long inbytes, outbytes; memcpy(&inbytes, buffer, 4); outbytes = STATE_SIZE; uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes); /* signature check (GENPLUS-GX x.x.x) */ char version[17]; load_param(version,16); version[16] = 0; if (strncmp(version,STATE_VERSION,11)) { free(state); return -1; } /* version check (1.5.0 and above) */ if ((version[11] < 0x31) || ((version[11] == 0x31) && (version[13] < 0x35))) { free(state); return -1; } /* reset system */ system_reset(); // GENESIS if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { load_param(work_ram, sizeof(work_ram)); load_param(zram, sizeof(zram)); load_param(&zstate, sizeof(zstate)); load_param(&zbank, sizeof(zbank)); if (zstate == 3) { m68k_memory_map[0xa0].read8 = z80_read_byte; m68k_memory_map[0xa0].read16 = z80_read_word; m68k_memory_map[0xa0].write8 = z80_write_byte; m68k_memory_map[0xa0].write16 = z80_write_word; } else { m68k_memory_map[0xa0].read8 = m68k_read_bus_8; m68k_memory_map[0xa0].read16 = m68k_read_bus_16; m68k_memory_map[0xa0].write8 = m68k_unused_8_w; m68k_memory_map[0xa0].write16 = m68k_unused_16_w; } } else { load_param(work_ram, 0x2000); } /* extended state */ load_param(&mcycles_68k, sizeof(mcycles_68k)); load_param(&mcycles_z80, sizeof(mcycles_z80)); // IO if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { load_param(io_reg, sizeof(io_reg)); io_reg[0] = region_code | 0x20 | (config.tmss & 1); } else { load_param(&io_reg[0x0F], 1); } // VDP bufferptr += vdp_context_load(&state[bufferptr], version); // SOUND bufferptr += sound_context_load(&state[bufferptr], version); // 68000 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { uint16 tmp16; uint32 tmp32; load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32); load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32); } // Z80 load_param(&Z80, sizeof(Z80_Regs)); Z80.irq_callback = z80_irq_callback; // Cartridge HW if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { bufferptr += md_cart_context_load(&state[bufferptr]); } else { bufferptr += sms_cart_context_load(&state[bufferptr]); } free(state); return 1; }
int state_load_old(unsigned char *state) { int i, bufferptr = 0x10; /* reset system */ system_reset(); // GENESIS if (system_hw == SYSTEM_PBC || system_hw == SYSTEM_GAMEGEAR) { load_param(work_ram, 0x2000); } else { load_param(work_ram, sizeof(work_ram)); load_param(zram, sizeof(zram)); load_param(&zstate, sizeof(zstate)); load_param(&zbank, sizeof(zbank)); if (zstate == 3) { m68k_memory_map[0xa0].read8 = z80_read_byte; m68k_memory_map[0xa0].read16 = z80_read_word; m68k_memory_map[0xa0].write8 = z80_write_byte; m68k_memory_map[0xa0].write16 = z80_write_word; } else { m68k_memory_map[0xa0].read8 = m68k_read_bus_8; m68k_memory_map[0xa0].read16 = m68k_read_bus_16; m68k_memory_map[0xa0].write8 = m68k_unused_8_w; m68k_memory_map[0xa0].write16 = m68k_unused_16_w; } } // IO if (system_hw == SYSTEM_PBC || system_hw == SYSTEM_GAMEGEAR) { load_param(&io_reg[0xf], 1); bufferptr+=0x10-1; } else { load_param(io_reg, sizeof(io_reg)); io_reg[0] = region_code | 0x20 | (config.tmss & 1); } /* VDP */ bufferptr += vdp_context_load_old(&state[bufferptr]); /* SOUND */ bufferptr += sound_context_load(&state[bufferptr]); /* 68000 */ if (system_hw != SYSTEM_PBC && system_hw != SYSTEM_GAMEGEAR) { uint16 tmp16; uint32 tmp32; load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32); load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32); load_param(&tmp32, 4); m68k_set_reg(M68K_REG_ISP,tmp32); load_param(&mcycles_68k, sizeof(mcycles_68k)); load_param(&tmp32, 4); m68k_irq_state = tmp32 >> 8; bufferptr += 4; // skip m68k.stopped }