Mercurial > repos > blastem
comparison gst.c @ 2657:d1f689ed3956
Get GST savestates working with new CPU cores
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 03 Mar 2025 22:11:34 -0800 |
parents | d44fe974fb85 |
children |
comparison
equal
deleted
inserted
replaced
2656:ec02a08196d5 | 2657:d1f689ed3956 |
---|---|
81 } | 81 } |
82 for (int i = 0; i < 8; i++) { | 82 for (int i = 0; i < 8; i++) { |
83 context->aregs[i] = read_le_32(curpos); | 83 context->aregs[i] = read_le_32(curpos); |
84 curpos += sizeof(uint32_t); | 84 curpos += sizeof(uint32_t); |
85 } | 85 } |
86 context->trace_pending = 0; | |
86 uint32_t pc = read_le_32(buffer + GST_68K_PC_OFFSET); | 87 uint32_t pc = read_le_32(buffer + GST_68K_PC_OFFSET); |
87 uint16_t sr = read_le_16(buffer + GST_68K_SR_OFFSET); | 88 uint16_t sr = read_le_16(buffer + GST_68K_SR_OFFSET); |
88 context->status = sr >> 8; | 89 context->status = sr >> 8; |
89 #ifdef NEW_CORE | 90 #ifdef NEW_CORE |
90 //TODO: implement me | 91 context->pc = pc + 2; |
92 context->xflag = sr & 0x10; | |
93 context->nflag = sr & 0x08; | |
94 context->zflag = sr & 0x04; | |
95 context->vflag = sr & 0x02; | |
96 context->cflag = sr & 0x01; | |
97 if (context->status & (1 << 5)) { | |
98 context->other_sp = read_le_32(buffer + GST_68K_USP_OFFSET); | |
99 } else { | |
100 context->other_sp = read_le_32(buffer + GST_68K_SSP_OFFSET); | |
101 } | |
102 context->prefetch = read_word(pc, (void**)context->mem_pointers, &context->opts->gen, context); | |
103 context->stopped = 0; | |
104 context->int_priority = context->int_num = context->int_pending_num = 0; | |
105 context->int_pending = 255; | |
106 printf("m68k_load_gst pc: %X, prefetch: %X\n", context->pc, context->prefetch); | |
91 #else | 107 #else |
92 for (int flag = 4; flag >= 0; flag--) { | 108 for (int flag = 4; flag >= 0; flag--) { |
93 context->flags[flag] = sr & 1; | 109 context->flags[flag] = sr & 1; |
94 sr >>= 1; | 110 sr >>= 1; |
95 } | 111 } |
96 #endif | |
97 if (context->status & (1 << 5)) { | 112 if (context->status & (1 << 5)) { |
98 context->aregs[8] = read_le_32(buffer + GST_68K_USP_OFFSET); | 113 context->aregs[8] = read_le_32(buffer + GST_68K_USP_OFFSET); |
99 } else { | 114 } else { |
100 context->aregs[8] = read_le_32(buffer + GST_68K_SSP_OFFSET); | 115 context->aregs[8] = read_le_32(buffer + GST_68K_SSP_OFFSET); |
101 } | 116 } |
117 #endif | |
102 | 118 |
103 return pc; | 119 return pc; |
104 } | 120 } |
105 | 121 |
106 uint8_t m68k_save_gst(m68k_context * context, uint32_t pc, FILE * gstfile) | 122 uint8_t m68k_save_gst(m68k_context * context, uint32_t pc, FILE * gstfile) |
113 } | 129 } |
114 for (int i = 0; i < 8; i++) { | 130 for (int i = 0; i < 8; i++) { |
115 write_le_32(curpos, context->aregs[i]); | 131 write_le_32(curpos, context->aregs[i]); |
116 curpos += sizeof(uint32_t); | 132 curpos += sizeof(uint32_t); |
117 } | 133 } |
118 write_le_32(buffer + GST_68K_PC_OFFSET, pc); | 134 |
135 #ifdef NEW_CORE | |
136 uint16_t sr = context->status << 8; | |
137 pc = context->pc - 2; | |
138 if (context->xflag) { sr |= 0x10; } | |
139 if (context->nflag) { sr |= 0x08; } | |
140 if (context->zflag) { sr |= 0x04; } | |
141 if (context->vflag) { sr |= 0x02; } | |
142 if (context->cflag) { sr |= 0x1; } | |
143 if (context->status & (1 << 5)) { | |
144 write_le_32(buffer + GST_68K_USP_OFFSET, context->other_sp); | |
145 write_le_32(buffer + GST_68K_SSP_OFFSET, context->aregs[7]); | |
146 } else { | |
147 write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[7]); | |
148 write_le_32(buffer + GST_68K_SSP_OFFSET, context->other_sp); | |
149 } | |
150 #else | |
119 uint16_t sr = context->status << 3; | 151 uint16_t sr = context->status << 3; |
120 #ifdef NEW_CORE | |
121 //TODO: implement me | |
122 #else | |
123 for (int flag = 4; flag >= 0; flag--) { | 152 for (int flag = 4; flag >= 0; flag--) { |
124 sr <<= 1; | 153 sr <<= 1; |
125 sr |= context->flags[flag]; | 154 sr |= context->flags[flag]; |
126 } | 155 } |
127 #endif | |
128 write_le_16(buffer + GST_68K_SR_OFFSET, sr); | |
129 if (context->status & (1 << 5)) { | 156 if (context->status & (1 << 5)) { |
130 write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[8]); | 157 write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[8]); |
131 write_le_32(buffer + GST_68K_SSP_OFFSET, context->aregs[7]); | 158 write_le_32(buffer + GST_68K_SSP_OFFSET, context->aregs[7]); |
132 } else { | 159 } else { |
133 write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[7]); | 160 write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[7]); |
134 write_le_32(buffer + GST_68K_SSP_OFFSET, context->aregs[8]); | 161 write_le_32(buffer + GST_68K_SSP_OFFSET, context->aregs[8]); |
135 } | 162 } |
163 #endif | |
164 write_le_32(buffer + GST_68K_PC_OFFSET, pc); | |
165 write_le_16(buffer + GST_68K_SR_OFFSET, sr); | |
136 fseek(gstfile, GST_68K_REGS, SEEK_SET); | 166 fseek(gstfile, GST_68K_REGS, SEEK_SET); |
137 if (fwrite(buffer, 1, GST_68K_REG_SIZE, gstfile) != GST_68K_REG_SIZE) { | 167 if (fwrite(buffer, 1, GST_68K_REG_SIZE, gstfile) != GST_68K_REG_SIZE) { |
138 fputs("Failed to write 68K registers to savestate\n", stderr); | 168 fputs("Failed to write 68K registers to savestate\n", stderr); |
139 return 0; | 169 return 0; |
140 } | 170 } |
150 fputs("Failed to read Z80 registers from savestate\n", stderr); | 180 fputs("Failed to read Z80 registers from savestate\n", stderr); |
151 return 0; | 181 return 0; |
152 } | 182 } |
153 uint8_t * curpos = regdata; | 183 uint8_t * curpos = regdata; |
154 uint8_t f = *(curpos++); | 184 uint8_t f = *(curpos++); |
155 #ifndef NEW_CORE | 185 #ifdef NEW_CORE |
186 context->main[6] = context->last_flag_result = f; | |
187 context->chflags = ((f & 1) ? 0x80 : 0) | ((f & 0x10) ? 8 : 0); | |
188 context->nflag = f & 2; | |
189 context->pvflag = f & 4; | |
190 context->zflag = f & 0x40; | |
191 context->main[7] = *curpos; | |
192 curpos += 3; | |
193 for (int reg = 0; reg < 6; reg+=2) { | |
194 context->main[reg ^ 1] = *(curpos++); | |
195 context->main[reg] = *curpos; | |
196 curpos += 3; | |
197 } | |
198 context->ix = read_le_16(curpos); | |
199 curpos += 4; | |
200 context->iy = read_le_16(curpos); | |
201 curpos += 4; | |
202 #else | |
156 context->flags[ZF_C] = f & 1; | 203 context->flags[ZF_C] = f & 1; |
157 f >>= 1; | 204 f >>= 1; |
158 context->flags[ZF_N] = f & 1; | 205 context->flags[ZF_N] = f & 1; |
159 f >>= 1; | 206 f >>= 1; |
160 context->flags[ZF_PV] = f & 1; | 207 context->flags[ZF_PV] = f & 1; |
170 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { | 217 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { |
171 context->regs[reg++] = *(curpos++); | 218 context->regs[reg++] = *(curpos++); |
172 context->regs[reg] = *curpos; | 219 context->regs[reg] = *curpos; |
173 curpos += 3; | 220 curpos += 3; |
174 } | 221 } |
222 #endif | |
175 context->pc = read_le_16(curpos); | 223 context->pc = read_le_16(curpos); |
176 curpos += 4; | 224 curpos += 4; |
177 context->sp = read_le_16(curpos); | 225 context->sp = read_le_16(curpos); |
178 curpos += 4; | 226 curpos += 4; |
179 f = *(curpos++); | 227 f = *(curpos++); |
228 #ifdef NEW_CORE | |
229 context->alt[6] = f; | |
230 context->alt[7] = *curpos; | |
231 curpos += 3; | |
232 for (int reg = 0; reg < 6; reg+=2) { | |
233 context->alt[reg ^ 1] = *(curpos++); | |
234 context->alt[reg] = *curpos; | |
235 curpos += 3; | |
236 } | |
237 context->i = *curpos; | |
238 #else | |
180 context->alt_flags[ZF_C] = f & 1; | 239 context->alt_flags[ZF_C] = f & 1; |
181 f >>= 1; | 240 f >>= 1; |
182 context->alt_flags[ZF_N] = f & 1; | 241 context->alt_flags[ZF_N] = f & 1; |
183 f >>= 1; | 242 f >>= 1; |
184 context->alt_flags[ZF_PV] = f & 1; | 243 context->alt_flags[ZF_PV] = f & 1; |
194 context->alt_regs[reg++] = *(curpos++); | 253 context->alt_regs[reg++] = *(curpos++); |
195 context->alt_regs[reg] = *curpos; | 254 context->alt_regs[reg] = *curpos; |
196 curpos += 3; | 255 curpos += 3; |
197 } | 256 } |
198 context->regs[Z80_I] = *curpos; | 257 context->regs[Z80_I] = *curpos; |
258 #endif | |
199 curpos += 2; | 259 curpos += 2; |
200 context->iff1 = context->iff2 = *curpos; | 260 context->iff1 = context->iff2 = *curpos; |
201 curpos += 2; | 261 curpos += 2; |
202 context->reset = !*(curpos++); | 262 context->reset = !*(curpos++); |
203 context->busreq = *curpos; | 263 context->busreq = *curpos; |
206 if (bank < 0x400000) { | 266 if (bank < 0x400000) { |
207 context->mem_pointers[1] = context->mem_pointers[2] + bank; | 267 context->mem_pointers[1] = context->mem_pointers[2] + bank; |
208 } else { | 268 } else { |
209 context->mem_pointers[1] = NULL; | 269 context->mem_pointers[1] = NULL; |
210 } | 270 } |
211 context->bank_reg = bank >> 15; | 271 genesis_context *gen = context->system; |
212 #endif | 272 gen->z80_bank_reg = bank >> 15; |
213 uint8_t buffer[Z80_RAM_BYTES]; | 273 uint8_t buffer[Z80_RAM_BYTES]; |
214 fseek(gstfile, GST_Z80_RAM, SEEK_SET); | 274 fseek(gstfile, GST_Z80_RAM, SEEK_SET); |
215 if(fread(buffer, 1, sizeof(buffer), gstfile) != (8*1024)) { | 275 if(fread(buffer, 1, sizeof(buffer), gstfile) != (8*1024)) { |
216 fputs("Failed to read Z80 RAM from savestate\n", stderr); | 276 fputs("Failed to read Z80 RAM from savestate\n", stderr); |
217 return 0; | 277 return 0; |
308 uint8_t z80_save_gst(z80_context * context, FILE * gstfile) | 368 uint8_t z80_save_gst(z80_context * context, FILE * gstfile) |
309 { | 369 { |
310 uint8_t regdata[GST_Z80_REG_SIZE]; | 370 uint8_t regdata[GST_Z80_REG_SIZE]; |
311 uint8_t * curpos = regdata; | 371 uint8_t * curpos = regdata; |
312 memset(regdata, 0, sizeof(regdata)); | 372 memset(regdata, 0, sizeof(regdata)); |
313 #ifndef NEW_CORE | 373 #ifdef NEW_CORE |
374 uint8_t f = context->last_flag_result; | |
375 if (context->zflag) { f |= 0x40; } | |
376 if (context->chflags & 8) { f |= 0x10; } | |
377 if (context->pvflag) { f |= 0x04; } | |
378 if (context->nflag) { f |= 0x02; } | |
379 if (context->chflags & 0x80) { f |= 0x01; } | |
380 *(curpos++) = f; | |
381 *curpos = context->main[7]; | |
382 | |
383 curpos += 3; | |
384 for (int reg = 0; reg < 6; reg+=2) { | |
385 *(curpos++) = context->main[reg^1]; | |
386 *curpos = context->main[reg]; | |
387 curpos += 3; | |
388 } | |
389 write_le_16(curpos, context->ix); | |
390 curpos += 4; | |
391 write_le_16(curpos, context->iy); | |
392 curpos += 4; | |
393 #else | |
314 uint8_t f = context->flags[ZF_S]; | 394 uint8_t f = context->flags[ZF_S]; |
315 f <<= 1; | 395 f <<= 1; |
316 f |= context->flags[ZF_Z] ; | 396 f |= context->flags[ZF_Z] ; |
317 f <<= 2; | 397 f <<= 2; |
318 f |= context->flags[ZF_H]; | 398 f |= context->flags[ZF_H]; |
329 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { | 409 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { |
330 *(curpos++) = context->regs[reg++]; | 410 *(curpos++) = context->regs[reg++]; |
331 *curpos = context->regs[reg]; | 411 *curpos = context->regs[reg]; |
332 curpos += 3; | 412 curpos += 3; |
333 } | 413 } |
414 #endif | |
334 write_le_16(curpos, context->pc); | 415 write_le_16(curpos, context->pc); |
335 curpos += 4; | 416 curpos += 4; |
336 write_le_16(curpos, context->sp); | 417 write_le_16(curpos, context->sp); |
337 curpos += 4; | 418 curpos += 4; |
419 #ifdef NEW_CORE | |
420 *(curpos++) = context->alt[6]; | |
421 *curpos = context->alt[7]; | |
422 | |
423 curpos += 3; | |
424 for (int reg = 0; reg < 6; reg+=2) { | |
425 *(curpos++) = context->alt[reg^1]; | |
426 *curpos = context->alt[reg]; | |
427 curpos += 3; | |
428 } | |
429 *curpos = context->i; | |
430 #else | |
338 f = context->alt_flags[ZF_S]; | 431 f = context->alt_flags[ZF_S]; |
339 f <<= 1; | 432 f <<= 1; |
340 f |= context->alt_flags[ZF_Z] ; | 433 f |= context->alt_flags[ZF_Z] ; |
341 f <<= 2; | 434 f <<= 2; |
342 f |= context->alt_flags[ZF_H]; | 435 f |= context->alt_flags[ZF_H]; |
353 *(curpos++) = context->alt_regs[reg++]; | 446 *(curpos++) = context->alt_regs[reg++]; |
354 *curpos = context->alt_regs[reg]; | 447 *curpos = context->alt_regs[reg]; |
355 curpos += 3; | 448 curpos += 3; |
356 } | 449 } |
357 *curpos = context->regs[Z80_I]; | 450 *curpos = context->regs[Z80_I]; |
451 #endif | |
358 curpos += 2; | 452 curpos += 2; |
359 *curpos = context->iff1; | 453 *curpos = context->iff1; |
360 curpos += 2; | 454 curpos += 2; |
361 *(curpos++) = !context->reset; | 455 *(curpos++) = !context->reset; |
362 *curpos = context->busreq; | 456 *curpos = context->busreq; |
363 curpos += 3; | 457 curpos += 3; |
364 uint32_t bank = context->bank_reg << 15; | 458 genesis_context *gen = context->system; |
459 uint32_t bank = gen->z80_bank_reg << 15; | |
365 write_le_32(curpos, bank); | 460 write_le_32(curpos, bank); |
366 #endif | |
367 fseek(gstfile, GST_Z80_REGS, SEEK_SET); | 461 fseek(gstfile, GST_Z80_REGS, SEEK_SET); |
368 if (fwrite(regdata, 1, sizeof(regdata), gstfile) != sizeof(regdata)) { | 462 if (fwrite(regdata, 1, sizeof(regdata), gstfile) != sizeof(regdata)) { |
369 return 0; | 463 return 0; |
370 } | 464 } |
371 fseek(gstfile, GST_Z80_RAM, SEEK_SET); | 465 fseek(gstfile, GST_Z80_RAM, SEEK_SET); |
470 m68k_handle_code_write(0xFF0000 | (i << 1), gen->m68k); | 564 m68k_handle_code_write(0xFF0000 | (i << 1), gen->m68k); |
471 } | 565 } |
472 i++; | 566 i++; |
473 } | 567 } |
474 } | 568 } |
475 #ifdef NEW_CORE | 569 #ifndef NEW_CORE |
476 gen->m68k->pc = pc; | |
477 #else | |
478 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc); | 570 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc); |
479 #endif | 571 #endif |
480 fclose(gstfile); | 572 fclose(gstfile); |
481 return pc; | 573 return pc; |
482 | 574 |