comparison genesis.c @ 2039:3b8e29ef1145

Add TMSS state to save states
author Michael Pavone <pavone@retrodev.com>
date Sun, 07 Mar 2021 23:13:19 -0800
parents b0b0c31338c3
children 638eb2d25696 3748a2a8a4b7
comparison
equal deleted inserted replaced
2038:5b51f03b2227 2039:3b8e29ef1145
101 start_section(buf, SECTION_SOUND_RAM); 101 start_section(buf, SECTION_SOUND_RAM);
102 save_int8(buf, Z80_RAM_BYTES / 1024); 102 save_int8(buf, Z80_RAM_BYTES / 1024);
103 save_buffer8(buf, gen->zram, Z80_RAM_BYTES); 103 save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
104 end_section(buf); 104 end_section(buf);
105 105
106 if (gen->version_reg & 0xF) {
107 //only save TMSS info if it's present
108 //that will allow a state saved on a model lacking TMSS
109 //to be loaded on a model that has it
110 start_section(buf, SECTION_TMSS);
111 save_int8(buf, gen->tmss);
112 save_buffer16(buf, gen->tmss_lock, 2);
113 end_section(buf);
114 }
115
106 cart_serialize(&gen->header, buf); 116 cart_serialize(&gen->header, buf);
107 } 117 }
108 } 118 }
109 119
110 static uint8_t *serialize(system_header *sys, size_t *size_out) 120 static uint8_t *serialize(system_header *sys, size_t *size_out)
170 gen->z80->reset = load_int8(buf); 180 gen->z80->reset = load_int8(buf);
171 gen->z80->busreq = load_int8(buf); 181 gen->z80->busreq = load_int8(buf);
172 gen->z80_bank_reg = load_int16(buf) & 0x1FF; 182 gen->z80_bank_reg = load_int16(buf) & 0x1FF;
173 } 183 }
174 184
185 static void tmss_deserialize(deserialize_buffer *buf, void *vgen)
186 {
187 genesis_context *gen = vgen;
188 gen->tmss = load_int8(buf);
189 load_buffer16(buf, gen->tmss_lock, 2);
190 }
191
175 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context); 192 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
193 static void check_tmss_lock(genesis_context *gen);
194 static void toggle_tmss_rom(genesis_context *gen);
176 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 195 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
177 { 196 {
178 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 197 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
179 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 198 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
180 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 199 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
185 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2); 204 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2);
186 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT); 205 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT);
187 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM); 206 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM);
188 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM); 207 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM);
189 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER); 208 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER);
209 register_section_handler(buf, (section_handler){.fun = tmss_deserialize, .data = gen}, SECTION_TMSS);
210 uint8_t tmss_old = gen->tmss;
211 gen->tmss = 0xFF;
190 while (buf->cur_pos < buf->size) 212 while (buf->cur_pos < buf->size)
191 { 213 {
192 load_section(buf); 214 load_section(buf);
215 }
216 if (gen->version_reg & 0xF) {
217 if (gen->tmss == 0xFF) {
218 //state lacked a TMSS section, assume that the game ROM is mapped in
219 //and that the VDP is unlocked
220 gen->tmss_lock[0] = 0x5345;
221 gen->tmss_lock[1] = 0x4741;
222 gen->tmss = 1;
223 }
224 if (gen->tmss != tmss_old) {
225 toggle_tmss_rom(gen);
226 }
227 check_tmss_lock(gen);
193 } 228 }
194 update_z80_bank_pointer(gen); 229 update_z80_bank_pointer(gen);
195 adjust_int_cycle(gen->m68k, gen->vdp); 230 adjust_int_cycle(gen->m68k, gen->vdp);
196 free(buf->handlers); 231 free(buf->handlers);
197 buf->handlers = NULL; 232 buf->handlers = NULL;
1174 } 1209 }
1175 } 1210 }
1176 1211
1177 static void check_tmss_lock(genesis_context *gen) 1212 static void check_tmss_lock(genesis_context *gen)
1178 { 1213 {
1179 gen->vdp_unlocked = gen->tmss_lock[0] == 'SE' && gen->tmss_lock[1] == 'GA'; 1214 gen->vdp_unlocked = gen->tmss_lock[0] == 0x5345 && gen->tmss_lock[1] == 0x4741;
1215 }
1216
1217 static void toggle_tmss_rom(genesis_context *gen)
1218 {
1219 m68k_context *context = gen->m68k;
1220 for (int i = 0; i < NUM_MEM_AREAS; i++)
1221 {
1222 uint16_t *tmp = context->mem_pointers[i];
1223 context->mem_pointers[i] = gen->tmss_pointers[i];
1224 gen->tmss_pointers[i] = tmp;
1225 }
1226 m68k_invalidate_code_range(context, 0, 0x400000);
1180 } 1227 }
1181 1228
1182 static void *unused_write(uint32_t location, void *vcontext, uint16_t value) 1229 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
1183 { 1230 {
1184 m68k_context *context = vcontext; 1231 m68k_context *context = vcontext;
1189 check_tmss_lock(gen); 1236 check_tmss_lock(gen);
1190 } else if (has_tmss && location == 0xA14100) { 1237 } else if (has_tmss && location == 0xA14100) {
1191 value &= 1; 1238 value &= 1;
1192 if (gen->tmss != value) { 1239 if (gen->tmss != value) {
1193 gen->tmss = value; 1240 gen->tmss = value;
1194 for (int i = 0; i < NUM_MEM_AREAS; i++) 1241 toggle_tmss_rom(gen);
1195 {
1196 uint16_t *tmp = context->mem_pointers[i];
1197 context->mem_pointers[i] = gen->tmss_pointers[i];
1198 gen->tmss_pointers[i] = tmp;
1199 }
1200 m68k_invalidate_code_range(context, 0, 0x400000);
1201 } 1242 }
1202 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) { 1243 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1203 //these writes are ignored when no relevant hardware is present 1244 //these writes are ignored when no relevant hardware is present
1204 } else { 1245 } else {
1205 fatal_error("Machine freeze due to unmapped write to %X\n", location); 1246 fatal_error("Machine freeze due to unmapped write to %X\n", location);
1225 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) { 1266 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
1226 if (location & 1) { 1267 if (location & 1) {
1227 value &= 1; 1268 value &= 1;
1228 if (gen->tmss != value) { 1269 if (gen->tmss != value) {
1229 gen->tmss = value; 1270 gen->tmss = value;
1230 for (int i = 0; i < NUM_MEM_AREAS; i++) 1271 toggle_tmss_rom(gen);
1231 {
1232 uint16_t *tmp = context->mem_pointers[i];
1233 context->mem_pointers[i] = gen->tmss_pointers[i];
1234 gen->tmss_pointers[i] = tmp;
1235 }
1236 m68k_invalidate_code_range(context, 0, 0x400000);
1237 } 1272 }
1238 } 1273 }
1239 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) { 1274 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1240 //these writes are ignored when no relevant hardware is present 1275 //these writes are ignored when no relevant hardware is present
1241 } else { 1276 } else {