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 {