Mercurial > repos > blastem
comparison romdb.c @ 774:41dc895e85ff
Fix map for NFL Quarterback Club 96. Fix default EEPROM value. Initial work for supporing Sega mapper in ROM DB
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 19 Jul 2015 20:51:09 -0700 |
parents | 1b82b282b829 |
children | 22728a57d7f3 |
comparison
equal
deleted
inserted
replaced
773:13d3744b170e | 774:41dc895e85ff |
---|---|
607 return; | 607 return; |
608 } | 608 } |
609 fprintf(stderr, "bit %s is connected to unrecognized write pin %s", key, pin); | 609 fprintf(stderr, "bit %s is connected to unrecognized write pin %s", key, pin); |
610 } | 610 } |
611 | 611 |
612 void process_sram_def(char *key, map_iter_state *state) | |
613 { | |
614 if (!state->info->save_size) { | |
615 char * size = tern_find_path(state->root, "SRAM\0size\0").ptrval; | |
616 if (!size) { | |
617 fprintf(stderr, "ROM DB map entry %d with address %s has device type SRAM, but the SRAM size is not defined\n", state->index, key); | |
618 exit(1); | |
619 } | |
620 state->info->save_size = atoi(size); | |
621 if (!state->info->save_size) { | |
622 fprintf(stderr, "SRAM size %s is invalid\n", size); | |
623 exit(1); | |
624 } | |
625 state->info->save_buffer = malloc(state->info->save_size); | |
626 memset(state->info->save_buffer, 0, state->info->save_size); | |
627 char *bus = tern_find_path(state->root, "SRAM\0bus\0").ptrval; | |
628 if (!strcmp(bus, "odd")) { | |
629 state->info->save_type = RAM_FLAG_ODD; | |
630 } else if(!strcmp(bus, "even")) { | |
631 state->info->save_type = RAM_FLAG_EVEN; | |
632 } else { | |
633 state->info->save_type = RAM_FLAG_BOTH; | |
634 } | |
635 } | |
636 } | |
637 | |
638 void process_eeprom_def(char * key, map_iter_state *state) | |
639 { | |
640 if (!state->info->save_size) { | |
641 char * size = tern_find_path(state->root, "EEPROM\0size\0").ptrval; | |
642 if (!size) { | |
643 fprintf(stderr, "ROM DB map entry %d with address %s has device type EEPROM, but the EEPROM size is not defined\n", state->index, key); | |
644 exit(1); | |
645 } | |
646 state->info->save_size = atoi(size); | |
647 if (!state->info->save_size) { | |
648 fprintf(stderr, "EEPROM size %s is invalid\n", size); | |
649 exit(1); | |
650 } | |
651 char *etype = tern_find_path(state->root, "EEPROM\0type\0").ptrval; | |
652 if (!etype) { | |
653 etype = "i2c"; | |
654 } | |
655 if (!strcmp(etype, "i2c")) { | |
656 state->info->save_type = SAVE_I2C; | |
657 } else { | |
658 fprintf(stderr, "EEPROM type %s is invalid\n", etype); | |
659 exit(1); | |
660 } | |
661 state->info->save_buffer = malloc(state->info->save_size); | |
662 memset(state->info->save_buffer, 0xFF, state->info->save_size); | |
663 state->info->eeprom_map = malloc(sizeof(eeprom_map) * state->num_els); | |
664 memset(state->info->eeprom_map, 0, sizeof(eeprom_map) * state->num_els); | |
665 } | |
666 } | |
667 | |
668 void add_eeprom_map(tern_node *node, uint32_t start, uint32_t end, map_iter_state *state) | |
669 { | |
670 eeprom_map *eep_map = state->info->eeprom_map + state->info->num_eeprom; | |
671 eep_map->start = start; | |
672 eep_map->end = end; | |
673 eep_map->sda_read_bit = 0xFF; | |
674 tern_node * bits_read = tern_find_ptr(node, "bits_read"); | |
675 if (bits_read) { | |
676 tern_foreach(bits_read, eeprom_read_fun, eep_map); | |
677 } | |
678 tern_node * bits_write = tern_find_ptr(node, "bits_write"); | |
679 if (bits_write) { | |
680 tern_foreach(bits_write, eeprom_write_fun, eep_map); | |
681 } | |
682 printf("EEPROM address %X: sda read: %X, sda write: %X, scl: %X\n", start, eep_map->sda_read_bit, eep_map->sda_write_mask, eep_map->scl_mask); | |
683 state->info->num_eeprom++; | |
684 } | |
685 | |
612 void map_iter_fun(char *key, tern_val val, void *data) | 686 void map_iter_fun(char *key, tern_val val, void *data) |
613 { | 687 { |
614 map_iter_state *state = data; | 688 map_iter_state *state = data; |
615 tern_node *node = tern_get_node(val); | 689 tern_node *node = tern_get_node(val); |
616 if (!node) { | 690 if (!node) { |
622 if (!end || end < start) { | 696 if (!end || end < start) { |
623 fprintf(stderr, "'last' value is missing or invalid for ROM DB map entry %d with address %s\n", state->index, key); | 697 fprintf(stderr, "'last' value is missing or invalid for ROM DB map entry %d with address %s\n", state->index, key); |
624 exit(1); | 698 exit(1); |
625 } | 699 } |
626 char * dtype = tern_find_ptr_default(node, "device", "ROM"); | 700 char * dtype = tern_find_ptr_default(node, "device", "ROM"); |
627 uint32_t offset = strtol(tern_find_ptr_default(node, "offset", "0"), NULL, 0); | 701 uint32_t offset = strtol(tern_find_ptr_default(node, "offset", "0"), NULL, 16); |
628 memmap_chunk *map = state->info->map + state->index; | 702 memmap_chunk *map = state->info->map + state->index; |
629 map->start = start; | 703 map->start = start; |
630 map->end = end; | 704 map->end = end + 1; |
631 if (!strcmp(dtype, "ROM")) { | 705 if (!strcmp(dtype, "ROM")) { |
632 map->buffer = state->rom + offset; | 706 map->buffer = state->rom + offset; |
633 map->flags = MMAP_READ; | 707 map->flags = MMAP_READ; |
634 map->mask = calc_mask(state->rom_size, start, end); | 708 map->mask = calc_mask(state->rom_size - offset, start, end); |
635 } else if (!strcmp(dtype, "EEPROM")) { | 709 } else if (!strcmp(dtype, "EEPROM")) { |
636 if (!state->info->save_size) { | 710 process_eeprom_def(key, state); |
637 char * size = tern_find_path(state->root, "EEPROM\0size\0").ptrval; | 711 add_eeprom_map(node, start, end, state); |
638 if (!size) { | 712 |
639 fprintf(stderr, "ROM DB map entry %d with address %s has device type EEPROM, but the EEPROM size is not defined\n", state->index, key); | |
640 exit(1); | |
641 } | |
642 state->info->save_size = atoi(size); | |
643 if (!state->info->save_size) { | |
644 fprintf(stderr, "EEPROM size %s is invalid\n", size); | |
645 exit(1); | |
646 } | |
647 char *etype = tern_find_path(state->root, "EEPROM\0type\0").ptrval; | |
648 if (!etype) { | |
649 etype = "i2c"; | |
650 } | |
651 if (!strcmp(etype, "i2c")) { | |
652 state->info->save_type = SAVE_I2C; | |
653 } else { | |
654 fprintf(stderr, "EEPROM type %s is invalid\n", etype); | |
655 exit(1); | |
656 } | |
657 state->info->save_buffer = malloc(state->info->save_size); | |
658 state->info->eeprom_map = malloc(sizeof(eeprom_map) * state->num_els); | |
659 memset(state->info->eeprom_map, 0, sizeof(eeprom_map) * state->num_els); | |
660 } | |
661 eeprom_map *eep_map = state->info->eeprom_map + state->info->num_eeprom; | |
662 eep_map->start = start; | |
663 eep_map->end = end; | |
664 eep_map->sda_read_bit = 0xFF; | |
665 tern_node * bits_read = tern_find_ptr(node, "bits_read"); | |
666 if (bits_read) { | |
667 tern_foreach(bits_read, eeprom_read_fun, eep_map); | |
668 } | |
669 tern_node * bits_write = tern_find_ptr(node, "bits_write"); | |
670 if (bits_write) { | |
671 tern_foreach(bits_write, eeprom_write_fun, eep_map); | |
672 } | |
673 printf("EEPROM address %X: sda read: %X, sda write: %X, scl: %X\n", start, eep_map->sda_read_bit, eep_map->sda_write_mask, eep_map->scl_mask); | |
674 state->info->num_eeprom++; | |
675 map->write_16 = write_eeprom_i2c_w; | 713 map->write_16 = write_eeprom_i2c_w; |
676 map->write_8 = write_eeprom_i2c_b; | 714 map->write_8 = write_eeprom_i2c_b; |
677 map->read_16 = read_eeprom_i2c_w; | 715 map->read_16 = read_eeprom_i2c_w; |
678 map->read_8 = read_eeprom_i2c_b; | 716 map->read_8 = read_eeprom_i2c_b; |
679 map->mask = 0xFFFFFF; | 717 map->mask = 0xFFFFFF; |
680 } else if (!strcmp(dtype, "SRAM")) { | 718 } else if (!strcmp(dtype, "SRAM")) { |
681 if (!state->info->save_size) { | 719 process_sram_def(key, state); |
682 char * size = tern_find_path(state->root, "SRAM\0size\0").ptrval; | |
683 if (!size) { | |
684 fprintf(stderr, "ROM DB map entry %d with address %s has device type SRAM, but the SRAM size is not defined\n", state->index, key); | |
685 exit(1); | |
686 } | |
687 state->info->save_size = atoi(size); | |
688 if (!state->info->save_size) { | |
689 fprintf(stderr, "SRAM size %s is invalid\n", size); | |
690 exit(1); | |
691 } | |
692 state->info->save_buffer = malloc(state->info->save_size); | |
693 char *bus = tern_find_path(state->root, "SRAM\0bus\0").ptrval; | |
694 if (!strcmp(bus, "odd")) { | |
695 state->info->save_type = RAM_FLAG_ODD; | |
696 } else if(!strcmp(bus, "even")) { | |
697 state->info->save_type = RAM_FLAG_EVEN; | |
698 } else { | |
699 state->info->save_type = RAM_FLAG_BOTH; | |
700 } | |
701 } | |
702 map->buffer = state->info->save_buffer + offset; | 720 map->buffer = state->info->save_buffer + offset; |
703 map->flags = MMAP_READ | MMAP_WRITE; | 721 map->flags = MMAP_READ | MMAP_WRITE; |
704 if (state->info->save_type == RAM_FLAG_ODD) { | 722 if (state->info->save_type == RAM_FLAG_ODD) { |
705 map->flags |= MMAP_ONLY_ODD; | 723 map->flags |= MMAP_ONLY_ODD; |
706 } else if(state->info->save_type == RAM_FLAG_EVEN) { | 724 } else if(state->info->save_type == RAM_FLAG_EVEN) { |
707 map->flags |= MMAP_ONLY_EVEN; | 725 map->flags |= MMAP_ONLY_EVEN; |
708 } | 726 } |
709 map->mask = calc_mask(state->info->save_size, start, end); | 727 map->mask = calc_mask(state->info->save_size, start, end); |
728 } else if (!strcmp(dtype, "Sega mapper")) { | |
729 map->buffer = state->rom + offset; | |
730 //TODO: Calculate this | |
731 map->ptr_index = 2; | |
732 map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL; | |
733 map->mask = calc_mask(state->rom_size - offset, start, end); | |
734 char *save_device = tern_find_path(node, "save\0device\0").ptrval; | |
735 if (save_device && !strcmp(save_device, "SRAM")) { | |
736 process_sram_def(key, state); | |
737 map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL | |
738 map->read_8 = (read_8_fun)read_sram_b; | |
739 map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area | |
740 map->write_8 = (write_8_fun)write_sram_area_b; | |
741 } else if (save_device && !strcmp(save_device, "EEPROM")) { | |
742 process_eeprom_def(key, state); | |
743 add_eeprom_map(node, start & map->mask, end & map->mask, state); | |
744 map->write_16 = write_eeprom_i2c_w; | |
745 map->write_8 = write_eeprom_i2c_b; | |
746 map->read_16 = read_eeprom_i2c_w; | |
747 map->read_8 = read_eeprom_i2c_b; | |
748 } | |
749 state->info->map_chunks++; | |
750 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks); | |
751 state->index++; | |
752 memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk)); | |
753 map = state->info->map + state->index; | |
754 map->start = 0xA13000; | |
755 map->end = 0xA13100; | |
756 map->mask = 0xFF; | |
757 map->write_16 = (write_16_fun)write_bank_reg_w; | |
758 map->write_8 = (write_8_fun)write_bank_reg_b; | |
710 } else { | 759 } else { |
711 fprintf(stderr, "Invalid device type for ROM DB map entry %d with address %s\n", state->index, key); | 760 fprintf(stderr, "Invalid device type for ROM DB map entry %d with address %s\n", state->index, key); |
712 exit(1); | 761 exit(1); |
713 } | 762 } |
714 state->index++; | 763 state->index++; |
755 info.regions = get_header_regions(rom); | 804 info.regions = get_header_regions(rom); |
756 } | 805 } |
757 | 806 |
758 tern_node *map = tern_find_ptr(entry, "map"); | 807 tern_node *map = tern_find_ptr(entry, "map"); |
759 if (map) { | 808 if (map) { |
809 info.save_type = SAVE_NONE; | |
760 info.map_chunks = tern_count(map); | 810 info.map_chunks = tern_count(map); |
761 if (info.map_chunks) { | 811 if (info.map_chunks) { |
762 info.map_chunks += base_chunks; | 812 info.map_chunks += base_chunks; |
763 info.save_buffer = NULL; | 813 info.save_buffer = NULL; |
764 info.save_size = 0; | 814 info.save_size = 0; |
765 info.map = malloc(sizeof(memmap_chunk) * info.map_chunks); | 815 info.map = malloc(sizeof(memmap_chunk) * info.map_chunks); |
766 info.eeprom_map = NULL; | 816 info.eeprom_map = NULL; |
767 info.num_eeprom = 0; | 817 info.num_eeprom = 0; |
768 memset(info.map, 0, sizeof(memmap_chunk) * (info.map_chunks - base_chunks)); | 818 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks); |
769 map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks}; | 819 map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks}; |
770 tern_foreach(map, map_iter_fun, &state); | 820 tern_foreach(map, map_iter_fun, &state); |
771 memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks); | 821 memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks); |
772 } else { | 822 } else { |
773 add_memmap_header(&info, rom, rom_size, base_map, base_chunks); | 823 add_memmap_header(&info, rom, rom_size, base_map, base_chunks); |