comparison sms.c @ 1648:b7ecd0d6a77b mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Tue, 25 Dec 2018 11:12:26 -0800
parents 2455662378ed 6909c5d0bbb5
children 956c1cce05e2
comparison
equal deleted inserted replaced
1509:36732f5c2281 1648:b7ecd0d6a77b
4 #include "sms.h" 4 #include "sms.h"
5 #include "blastem.h" 5 #include "blastem.h"
6 #include "render.h" 6 #include "render.h"
7 #include "util.h" 7 #include "util.h"
8 #include "debug.h" 8 #include "debug.h"
9 #include "saves.h"
10 #include "bindings.h"
9 11
10 static void *memory_io_write(uint32_t location, void *vcontext, uint8_t value) 12 static void *memory_io_write(uint32_t location, void *vcontext, uint8_t value)
11 { 13 {
12 z80_context *z80 = vcontext; 14 z80_context *z80 = vcontext;
13 sms_context *sms = z80->system; 15 sms_context *sms = z80->system;
290 } 292 }
291 } 293 }
292 294
293 static void save_state(sms_context *sms, uint8_t slot) 295 static void save_state(sms_context *sms, uint8_t slot)
294 { 296 {
295 char *save_path; 297 char *save_path = get_slot_name(&sms->header, slot, "state");
296 if (slot == QUICK_SAVE_SLOT) {
297 save_path = save_state_path;
298 } else {
299 char slotname[] = "slot_0.state";
300 slotname[5] = '0' + slot;
301 char const *parts[] = {sms->header.save_dir, PATH_SEP, slotname};
302 save_path = alloc_concat_m(3, parts);
303 }
304 serialize_buffer state; 298 serialize_buffer state;
305 init_serialize(&state); 299 init_serialize(&state);
306 sms_serialize(sms, &state); 300 sms_serialize(sms, &state);
307 save_to_file(&state, save_path); 301 save_to_file(&state, save_path);
308 printf("Saved state to %s\n", save_path); 302 printf("Saved state to %s\n", save_path);
303 free(save_path);
309 free(state.data); 304 free(state.data);
310 } 305 }
311 306
312 static uint8_t load_state_path(sms_context *sms, char *path) 307 static uint8_t load_state_path(sms_context *sms, char *path)
313 { 308 {
322 } 317 }
323 318
324 static uint8_t load_state(system_header *system, uint8_t slot) 319 static uint8_t load_state(system_header *system, uint8_t slot)
325 { 320 {
326 sms_context *sms = (sms_context *)system; 321 sms_context *sms = (sms_context *)system;
327 char numslotname[] = "slot_0.state"; 322 char *statepath = get_slot_name(system, slot, "state");
328 char *slotname; 323 uint8_t ret;
329 if (slot == QUICK_SAVE_SLOT) { 324 #ifdef USE_NATIVE
330 slotname = "quicksave.state"; 325 if (!sms->z80->native_pc) {
331 } else { 326 ret = get_modification_time(statepath) != 0;
332 numslotname[5] = '0' + slot; 327 if (ret) {
333 slotname = numslotname; 328 system->delayed_load_slot = slot + 1;
334 } 329 }
335 char const *parts[] = {sms->header.save_dir, PATH_SEP, slotname}; 330 goto done;
336 char *statepath = alloc_concat_m(3, parts); 331
337 uint8_t ret = load_state_path(sms, statepath); 332 }
333 #endif
334 ret = load_state_path(sms, statepath);
335 done:
338 free(statepath); 336 free(statepath);
339 return ret; 337 return ret;
340 } 338 }
341 339
342 static void run_sms(system_header *system) 340 static void run_sms(system_header *system)
343 { 341 {
344 render_disable_ym();
345 sms_context *sms = (sms_context *)system; 342 sms_context *sms = (sms_context *)system;
346 uint32_t target_cycle = sms->z80->current_cycle + 3420*16; 343 uint32_t target_cycle = sms->z80->current_cycle + 3420*16;
347 //TODO: PAL support 344 //TODO: PAL support
348 render_set_video_standard(VID_NTSC); 345 render_set_video_standard(VID_NTSC);
349 while (!sms->should_return) 346 while (!sms->should_return)
350 { 347 {
351 #ifdef USE_NATIVE 348 #ifdef USE_NATIVE
349 if (system->delayed_load_slot) {
350 load_state(system, system->delayed_load_slot - 1);
351 system->delayed_load_slot = 0;
352
353 }
352 if (system->enter_debugger && sms->z80->pc) { 354 if (system->enter_debugger && sms->z80->pc) {
353 system->enter_debugger = 0; 355 system->enter_debugger = 0;
354 zdebugger(sms->z80, sms->z80->pc); 356 zdebugger(sms->z80, sms->z80->pc);
355 } 357 }
356 #endif 358 #endif
388 vdp_adjust_cycles(sms->vdp, adjust); 390 vdp_adjust_cycles(sms->vdp, adjust);
389 sms->psg->cycles -= adjust; 391 sms->psg->cycles -= adjust;
390 target_cycle -= adjust; 392 target_cycle -= adjust;
391 } 393 }
392 } 394 }
395 bindings_release_capture();
393 vdp_release_framebuffer(sms->vdp); 396 vdp_release_framebuffer(sms->vdp);
397 render_pause_source(sms->psg->audio);
394 sms->should_return = 0; 398 sms->should_return = 0;
395 render_enable_ym();
396 } 399 }
397 400
398 static void resume_sms(system_header *system) 401 static void resume_sms(system_header *system)
399 { 402 {
400 sms_context *sms = (sms_context *)system; 403 sms_context *sms = (sms_context *)system;
404 bindings_reacquire_capture();
401 vdp_reacquire_framebuffer(sms->vdp); 405 vdp_reacquire_framebuffer(sms->vdp);
406 render_resume_source(sms->psg->audio);
402 run_sms(system); 407 run_sms(system);
403 } 408 }
404 409
405 static void start_sms(system_header *system, char *statefile) 410 static void start_sms(system_header *system, char *statefile)
406 { 411 {
407 sms_context *sms = (sms_context *)system; 412 sms_context *sms = (sms_context *)system;
408 set_keybindings(&sms->io);
409 413
410 z80_assert_reset(sms->z80, 0); 414 z80_assert_reset(sms->z80, 0);
411 z80_clear_reset(sms->z80, 128*15); 415 z80_clear_reset(sms->z80, 128*15);
412 416
413 if (statefile) { 417 if (statefile) {
455 } 459 }
456 460
457 static void inc_debug_mode(system_header *system) 461 static void inc_debug_mode(system_header *system)
458 { 462 {
459 sms_context *sms = (sms_context *)system; 463 sms_context *sms = (sms_context *)system;
460 sms->vdp->debug++; 464 vdp_inc_debug_mode(sms->vdp);
461 if (sms->vdp->debug == 7) {
462 sms->vdp->debug = 0;
463 }
464 }
465
466 static void inc_debug_pal(system_header *system)
467 {
468 sms_context *sms = (sms_context *)system;
469 sms->vdp->debug_pal++;
470 if (sms->vdp->debug_pal == 4) {
471 sms->vdp->debug_pal = 0;
472 }
473 } 465 }
474 466
475 static void load_save(system_header *system) 467 static void load_save(system_header *system)
476 { 468 {
477 //TODO: Implement me 469 //TODO: Implement me
480 static void persist_save(system_header *system) 472 static void persist_save(system_header *system)
481 { 473 {
482 //TODO: Implement me 474 //TODO: Implement me
483 } 475 }
484 476
485 sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out) 477 static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t button)
486 { 478 {
487 memset(info_out, 0, sizeof(*info_out)); 479 sms_context *sms = (sms_context *)system;
480 if (gamepad_num == GAMEPAD_MAIN_UNIT) {
481 if (button == MAIN_UNIT_PAUSE) {
482 vdp_pbc_pause(sms->vdp);
483 }
484 } else {
485 io_gamepad_down(&sms->io, gamepad_num, button);
486 }
487 }
488
489 static void gamepad_up(system_header *system, uint8_t gamepad_num, uint8_t button)
490 {
491 sms_context *sms = (sms_context *)system;
492 io_gamepad_up(&sms->io, gamepad_num, button);
493 }
494
495 static void mouse_down(system_header *system, uint8_t mouse_num, uint8_t button)
496 {
497 sms_context *sms = (sms_context *)system;
498 io_mouse_down(&sms->io, mouse_num, button);
499 }
500
501 static void mouse_up(system_header *system, uint8_t mouse_num, uint8_t button)
502 {
503 sms_context *sms = (sms_context *)system;
504 io_mouse_up(&sms->io, mouse_num, button);
505 }
506
507 static void mouse_motion_absolute(system_header *system, uint8_t mouse_num, uint16_t x, uint16_t y)
508 {
509 sms_context *sms = (sms_context *)system;
510 io_mouse_motion_absolute(&sms->io, mouse_num, x, y);
511 }
512
513 static void mouse_motion_relative(system_header *system, uint8_t mouse_num, int32_t x, int32_t y)
514 {
515 sms_context *sms = (sms_context *)system;
516 io_mouse_motion_relative(&sms->io, mouse_num, x, y);
517 }
518
519 static void keyboard_down(system_header *system, uint8_t scancode)
520 {
521 sms_context *sms = (sms_context *)system;
522 io_keyboard_down(&sms->io, scancode);
523 }
524
525 static void keyboard_up(system_header *system, uint8_t scancode)
526 {
527 sms_context *sms = (sms_context *)system;
528 io_keyboard_up(&sms->io, scancode);
529 }
530
531 static void config_updated(system_header *system)
532 {
533 sms_context *sms = (sms_context *)system;
534 setup_io_devices(config, &system->info, &sms->io);
535 }
536
537
538 sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region)
539 {
488 sms_context *sms = calloc(1, sizeof(sms_context)); 540 sms_context *sms = calloc(1, sizeof(sms_context));
489 uint32_t rom_size = nearest_pow2(media->size); 541 uint32_t rom_size = nearest_pow2(media->size);
490 memmap_chunk memory_map[6]; 542 memmap_chunk memory_map[6];
491 if (media->size > 0xC000) { 543 if (media->size > 0xC000) {
492 info_out->map_chunks = 6; 544 sms->header.info.map_chunks = 6;
493 uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4; 545 uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4;
494 memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, media->buffer, NULL, NULL, NULL, NULL}; 546 memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, media->buffer, NULL, NULL, NULL, NULL};
495 memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; 547 memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
496 memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; 548 memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
497 memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, cart_ram_write}; 549 memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, cart_ram_write};
498 memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL}; 550 memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
499 memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0x0003, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write}; 551 memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0x0003, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write};
500 } else { 552 } else {
501 info_out->map_chunks = 2; 553 sms->header.info.map_chunks = 2;
502 memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, media->buffer, NULL, NULL, NULL, NULL}; 554 memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, media->buffer, NULL, NULL, NULL, NULL};
503 memory_map[1] = (memmap_chunk){0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL}; 555 memory_map[1] = (memmap_chunk){0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
504 }; 556 };
505 info_out->map = malloc(sizeof(memmap_chunk) * info_out->map_chunks); 557 sms->header.info.map = malloc(sizeof(memmap_chunk) * sms->header.info.map_chunks);
506 memcpy(info_out->map, memory_map, sizeof(memmap_chunk) * info_out->map_chunks); 558 memcpy(sms->header.info.map, memory_map, sizeof(memmap_chunk) * sms->header.info.map_chunks);
507 z80_options *zopts = malloc(sizeof(z80_options)); 559 z80_options *zopts = malloc(sizeof(z80_options));
508 init_z80_opts(zopts, info_out->map, info_out->map_chunks, io_map, 4, 15, 0xFF); 560 init_z80_opts(zopts, sms->header.info.map, sms->header.info.map_chunks, io_map, 4, 15, 0xFF);
509 sms->z80 = init_z80_context(zopts); 561 sms->z80 = init_z80_context(zopts);
510 sms->z80->system = sms; 562 sms->z80->system = sms;
511 sms->z80->options->gen.debug_cmd_handler = debug_commands; 563 sms->z80->options->gen.debug_cmd_handler = debug_commands;
512 564
513 sms->rom = media->buffer; 565 sms->rom = media->buffer;
514 sms->rom_size = rom_size; 566 sms->rom_size = rom_size;
515 if (info_out->map_chunks > 2) { 567 if (sms->header.info.map_chunks > 2) {
516 sms->z80->mem_pointers[0] = sms->rom; 568 sms->z80->mem_pointers[0] = sms->rom;
517 sms->z80->mem_pointers[1] = sms->rom + 0x4000; 569 sms->z80->mem_pointers[1] = sms->rom + 0x4000;
518 sms->z80->mem_pointers[2] = sms->rom + 0x8000; 570 sms->z80->mem_pointers[2] = sms->rom + 0x8000;
519 sms->bank_regs[1] = 0; 571 sms->bank_regs[1] = 0;
520 sms->bank_regs[2] = 0x4000 >> 14; 572 sms->bank_regs[2] = 0x4000 >> 14;
521 sms->bank_regs[3] = 0x8000 >> 14; 573 sms->bank_regs[3] = 0x8000 >> 14;
522 } 574 }
523 575
524 char * lowpass_cutoff_str = tern_find_path(config, "audio\0lowpass_cutoff\0", TVAL_PTR).ptrval;
525 uint32_t lowpass_cutoff = lowpass_cutoff_str ? atoi(lowpass_cutoff_str) : 3390;
526
527 //TODO: Detect region and pick master clock based off of that 576 //TODO: Detect region and pick master clock based off of that
528 sms->normal_clock = sms->master_clock = 53693175; 577 sms->normal_clock = sms->master_clock = 53693175;
529 578
530 sms->psg = malloc(sizeof(psg_context)); 579 sms->psg = malloc(sizeof(psg_context));
531 psg_init(sms->psg, render_sample_rate(), sms->master_clock, 15*16, render_audio_buffer(), lowpass_cutoff); 580 psg_init(sms->psg, sms->master_clock, 15*16);
532 581
533 sms->vdp = malloc(sizeof(vdp_context)); 582 sms->vdp = init_vdp_context(0);
534 init_vdp_context(sms->vdp, 0);
535 sms->vdp->system = &sms->header; 583 sms->vdp->system = &sms->header;
536 584
537 info_out->save_type = SAVE_NONE; 585 sms->header.info.save_type = SAVE_NONE;
538 info_out->name = strdup(media->name); 586 sms->header.info.name = strdup(media->name);
539 587
540 setup_io_devices(config, info_out, &sms->io); 588 setup_io_devices(config, &sms->header.info, &sms->io);
589 sms->header.has_keyboard = io_has_keyboard(&sms->io);
541 590
542 sms->header.set_speed_percent = set_speed_percent; 591 sms->header.set_speed_percent = set_speed_percent;
543 sms->header.start_context = start_sms; 592 sms->header.start_context = start_sms;
544 sms->header.resume_context = resume_sms; 593 sms->header.resume_context = resume_sms;
545 sms->header.load_save = load_save; 594 sms->header.load_save = load_save;
548 sms->header.free_context = free_sms; 597 sms->header.free_context = free_sms;
549 sms->header.get_open_bus_value = get_open_bus_value; 598 sms->header.get_open_bus_value = get_open_bus_value;
550 sms->header.request_exit = request_exit; 599 sms->header.request_exit = request_exit;
551 sms->header.soft_reset = soft_reset; 600 sms->header.soft_reset = soft_reset;
552 sms->header.inc_debug_mode = inc_debug_mode; 601 sms->header.inc_debug_mode = inc_debug_mode;
553 sms->header.inc_debug_pal = inc_debug_pal; 602 sms->header.gamepad_down = gamepad_down;
603 sms->header.gamepad_up = gamepad_up;
604 sms->header.mouse_down = mouse_down;
605 sms->header.mouse_up = mouse_up;
606 sms->header.mouse_motion_absolute = mouse_motion_absolute;
607 sms->header.mouse_motion_relative = mouse_motion_relative;
608 sms->header.keyboard_down = keyboard_down;
609 sms->header.keyboard_up = keyboard_up;
610 sms->header.config_updated = config_updated;
554 sms->header.type = SYSTEM_SMS; 611 sms->header.type = SYSTEM_SMS;
555 612
556 return sms; 613 return sms;
557 } 614 }