Mercurial > repos > blastem
comparison segacd.c @ 2281:b9fed07f19e4
Implement BRAM cart support
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 08 Jan 2023 23:30:28 -0800 |
parents | 9ead0fe69d9b |
children | a6a68c33cce7 |
comparison
equal
deleted
inserted
replaced
2280:9ead0fe69d9b | 2281:b9fed07f19e4 |
---|---|
438 static void *pcm_write16(uint32_t address, void *vcontext, uint16_t value) | 438 static void *pcm_write16(uint32_t address, void *vcontext, uint16_t value) |
439 { | 439 { |
440 return pcm_write8(address+1, vcontext, value); | 440 return pcm_write8(address+1, vcontext, value); |
441 } | 441 } |
442 | 442 |
443 static uint16_t cart_area_read16(uint32_t address, void *vcontext) | |
444 { | |
445 m68k_context *m68k = vcontext; | |
446 genesis_context *gen = m68k->system; | |
447 segacd_context *cd = gen->expansion; | |
448 uint16_t open_bus = read_word(m68k->last_prefetch_address, (void **)m68k->mem_pointers, &m68k->options->gen, m68k); | |
449 if (cd->bram_cart_id > 7) { | |
450 // No cart, just return open bus | |
451 return open_bus; | |
452 } | |
453 address &= 0x3FFFFF; | |
454 if (address < 0x200000) { | |
455 if (address < 0x100000) { | |
456 return (open_bus & 0xFF00) | cd->bram_cart_id; | |
457 } | |
458 return open_bus; | |
459 } else { | |
460 address &= 0x1FFFFF; | |
461 uint32_t end = 0x2000 << (1 + cd->bram_cart_id); | |
462 if (address >= end) { | |
463 return open_bus; | |
464 } | |
465 return (open_bus & 0xFF00) | cd->bram_cart[address >> 1]; | |
466 } | |
467 } | |
468 | |
469 static uint8_t cart_area_read8(uint32_t address, void *vcontext) | |
470 { | |
471 m68k_context *m68k = vcontext; | |
472 genesis_context *gen = m68k->system; | |
473 segacd_context *cd = gen->expansion; | |
474 if (!(address & 1) || cd->bram_cart_id > 7) { | |
475 //open bus | |
476 return read_byte(m68k->last_prefetch_address | (address & 1), (void **)m68k->mem_pointers, &m68k->options->gen, m68k); | |
477 } | |
478 address &= 0x3FFFFF; | |
479 if (address < 0x200000) { | |
480 if (address < 0x100000) { | |
481 return cd->bram_cart_id; | |
482 } | |
483 return read_byte(m68k->last_prefetch_address | 1, (void **)m68k->mem_pointers, &m68k->options->gen, m68k); | |
484 } else { | |
485 address &= 0x1FFFFF; | |
486 uint32_t end = 0x2000 << (1 + cd->bram_cart_id); | |
487 if (address >= end) { | |
488 return read_byte(m68k->last_prefetch_address | 1, (void **)m68k->mem_pointers, &m68k->options->gen, m68k); | |
489 } | |
490 return cd->bram_cart[address >> 1]; | |
491 } | |
492 } | |
493 | |
494 static void *cart_area_write8(uint32_t address, void *vcontext, uint8_t value) | |
495 { | |
496 m68k_context *m68k = vcontext; | |
497 genesis_context *gen = m68k->system; | |
498 segacd_context *cd = gen->expansion; | |
499 if (!(address & 1) || cd->bram_cart_id > 7 || address < 0x600000) { | |
500 return vcontext; | |
501 } | |
502 address &= 0x1FFFFF; | |
503 uint32_t end = 0x2000 << (1 + cd->bram_cart_id); | |
504 if (address < end && cd->bram_cart_write_enabled) { | |
505 cd->bram_cart[address >> 1] = value; | |
506 } | |
507 if (address == 0x1FFFFF || (cd->bram_cart_id < 7 && address > 0x100000)) { | |
508 cd->bram_cart_write_enabled = value & 1; | |
509 } | |
510 return vcontext; | |
511 } | |
512 | |
513 static void *cart_area_write16(uint32_t address, void *vcontext, uint16_t value) | |
514 { | |
515 return cart_area_write8(address | 1, vcontext, value); | |
516 } | |
443 | 517 |
444 static void timers_run(segacd_context *cd, uint32_t cycle) | 518 static void timers_run(segacd_context *cd, uint32_t cycle) |
445 { | 519 { |
446 if (cycle <= cd->stopwatch_cycle) { | 520 if (cycle <= cd->stopwatch_cycle) { |
447 return; | 521 return; |
1458 cd->rom_mut[0x72/2] = 0xFFFF; | 1532 cd->rom_mut[0x72/2] = 0xFFFF; |
1459 | 1533 |
1460 cd->prog_ram = calloc(512*1024, 1); | 1534 cd->prog_ram = calloc(512*1024, 1); |
1461 cd->word_ram = calloc(256*1024, 1); | 1535 cd->word_ram = calloc(256*1024, 1); |
1462 cd->bram = calloc(8*1024, 1); | 1536 cd->bram = calloc(8*1024, 1); |
1463 | 1537 char *bram_size_id = tern_find_path_default(config, "system\0bram_cart_size_id\0", (tern_val){.ptrval = "4"}, TVAL_PTR).ptrval; |
1538 cd->bram_cart_id = 0xFF; | |
1539 cd->bram_cart = NULL; | |
1540 if (strcmp(bram_size_id, "none")) { | |
1541 char *end; | |
1542 long id = strtol(bram_size_id, &end, 10); | |
1543 if (end != bram_size_id && id < 8) { | |
1544 cd->bram_cart_id = id; | |
1545 cd->bram_cart = calloc(0x2000 << id, 1); | |
1546 } | |
1547 } | |
1464 | 1548 |
1465 sub_cpu_map[0].buffer = sub_cpu_map[1].buffer = cd->prog_ram; | 1549 sub_cpu_map[0].buffer = sub_cpu_map[1].buffer = cd->prog_ram; |
1466 sub_cpu_map[4].buffer = cd->bram; | 1550 sub_cpu_map[4].buffer = cd->bram; |
1467 m68k_options *mopts = malloc(sizeof(m68k_options)); | 1551 m68k_options *mopts = malloc(sizeof(m68k_options)); |
1468 init_m68k_opts(mopts, sub_cpu_map, sizeof(sub_cpu_map) / sizeof(*sub_cpu_map), 4, sync_components); | 1552 init_m68k_opts(mopts, sub_cpu_map, sizeof(sub_cpu_map) / sizeof(*sub_cpu_map), 4, sync_components); |
1536 save_int8(buf, cd->graphics_dst_y); | 1620 save_int8(buf, cd->graphics_dst_y); |
1537 save_int8(buf, cd->main_has_word2m); | 1621 save_int8(buf, cd->main_has_word2m); |
1538 save_int8(buf, cd->main_swap_request); | 1622 save_int8(buf, cd->main_swap_request); |
1539 save_int8(buf, cd->bank_toggle); | 1623 save_int8(buf, cd->bank_toggle); |
1540 save_int8(buf, cd->sub_paused_wordram); | 1624 save_int8(buf, cd->sub_paused_wordram); |
1625 save_int8(buf, cd->bram_cart_write_enabled); | |
1541 end_section(buf); | 1626 end_section(buf); |
1542 | 1627 |
1543 start_section(buf, SECTION_CDD_MCU); | 1628 start_section(buf, SECTION_CDD_MCU); |
1544 cdd_mcu_serialize(&cd->cdd, buf); | 1629 cdd_mcu_serialize(&cd->cdd, buf); |
1545 end_section(buf); | 1630 end_section(buf); |
1592 cd->graphics_dst_y = load_int8(buf); | 1677 cd->graphics_dst_y = load_int8(buf); |
1593 cd->main_has_word2m = load_int8(buf); | 1678 cd->main_has_word2m = load_int8(buf); |
1594 cd->main_swap_request = load_int8(buf); | 1679 cd->main_swap_request = load_int8(buf); |
1595 cd->bank_toggle = load_int8(buf); | 1680 cd->bank_toggle = load_int8(buf); |
1596 cd->sub_paused_wordram = load_int8(buf); | 1681 cd->sub_paused_wordram = load_int8(buf); |
1682 cd->bram_cart_write_enabled = load_int8(buf); | |
1597 | 1683 |
1598 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { | 1684 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { |
1599 //1M mode | 1685 //1M mode |
1600 cd->genesis->m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; | 1686 cd->genesis->m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; |
1601 cd->genesis->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; | 1687 cd->genesis->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; |
1643 //TODO: additional ROM/prog RAM aliases | 1729 //TODO: additional ROM/prog RAM aliases |
1644 {0x200000, 0x220000, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 1, | 1730 {0x200000, 0x220000, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 1, |
1645 .read_16 = unmapped_word_read16, .write_16 = unmapped_word_write16, .read_8 = unmapped_word_read8, .write_8 = unmapped_word_write8}, | 1731 .read_16 = unmapped_word_read16, .write_16 = unmapped_word_write16, .read_8 = unmapped_word_read8, .write_8 = unmapped_word_write8}, |
1646 {0x220000, 0x240000, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 2, | 1732 {0x220000, 0x240000, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 2, |
1647 .read_16 = cell_image_read16, .write_16 = cell_image_write16, .read_8 = cell_image_read8, .write_8 = cell_image_write8}, | 1733 .read_16 = cell_image_read16, .write_16 = cell_image_write16, .read_8 = cell_image_read8, .write_8 = cell_image_write8}, |
1648 {0xA12000, 0xA13000, 0xFFFFFF, .read_16 = main_gate_read16, .write_16 = main_gate_write16, .read_8 = main_gate_read8, .write_8 = main_gate_write8} | 1734 {0xA12000, 0xA13000, 0xFFFFFF, .read_16 = main_gate_read16, .write_16 = main_gate_write16, .read_8 = main_gate_read8, .write_8 = main_gate_write8}, |
1735 {0x400000, 0x800000, 0xFFFFFF, .read_16 = cart_area_read16, .write_16 = cart_area_write16, .read_8 = cart_area_read8, .write_8 = cart_area_write8} | |
1649 }; | 1736 }; |
1650 for (int i = 0; i < sizeof(main_cpu_map) / sizeof(*main_cpu_map); i++) | 1737 *num_chunks = sizeof(main_cpu_map) / sizeof(*main_cpu_map); |
1738 if (cart_boot) { | |
1739 *num_chunks--; | |
1740 } | |
1741 for (int i = 0; i < *num_chunks; i++) | |
1651 { | 1742 { |
1652 if (main_cpu_map[i].start < 0x800000) { | 1743 if (main_cpu_map[i].start < 0x400000) { |
1653 if (cart_boot) { | 1744 if (cart_boot) { |
1654 main_cpu_map[i].start |= 0x400000; | 1745 main_cpu_map[i].start |= 0x400000; |
1655 main_cpu_map[i].end |= 0x400000; | 1746 main_cpu_map[i].end |= 0x400000; |
1656 } else { | 1747 } else { |
1657 main_cpu_map[i].start &= 0x3FFFFF; | 1748 main_cpu_map[i].start &= 0x3FFFFF; |
1658 main_cpu_map[i].end &= 0x3FFFFF; | 1749 main_cpu_map[i].end &= 0x3FFFFF; |
1659 } | 1750 } |
1660 } | 1751 } |
1661 } | 1752 } |
1662 //TODO: support BRAM cart | |
1663 main_cpu_map[0].buffer = cd->rom_mut; | 1753 main_cpu_map[0].buffer = cd->rom_mut; |
1664 main_cpu_map[2].buffer = cd->rom; | 1754 main_cpu_map[2].buffer = cd->rom; |
1665 main_cpu_map[1].buffer = cd->prog_ram; | 1755 main_cpu_map[1].buffer = cd->prog_ram; |
1666 main_cpu_map[3].buffer = cd->word_ram; | 1756 main_cpu_map[3].buffer = cd->word_ram; |
1667 main_cpu_map[4].buffer = cd->word_ram + 0x10000; | 1757 main_cpu_map[4].buffer = cd->word_ram + 0x10000; |
1668 *num_chunks = sizeof(main_cpu_map) / sizeof(*main_cpu_map); | |
1669 return main_cpu_map; | 1758 return main_cpu_map; |
1670 } | 1759 } |
1671 | 1760 |
1672 void segacd_set_speed_percent(segacd_context *cd, uint32_t percent) | 1761 void segacd_set_speed_percent(segacd_context *cd, uint32_t percent) |
1673 { | 1762 { |