Mercurial > repos > blastem
comparison blastem.c @ 767:ea525f600b1d
SRAM detection from ROM header is no working correctly again
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 06 Jul 2015 19:46:46 -0700 |
parents | 1b2f8280ba81 |
children | 4638b88bc72d |
comparison
equal
deleted
inserted
replaced
766:1b2f8280ba81 | 767:ea525f600b1d |
---|---|
778 psg_adjust_master_clock(context->psg, context->master_clock); | 778 psg_adjust_master_clock(context->psg, context->master_clock); |
779 } | 779 } |
780 | 780 |
781 #define MAX_MAP_CHUNKS (4+7+1) | 781 #define MAX_MAP_CHUNKS (4+7+1) |
782 | 782 |
783 const memmap_chunk static_map[] = { | 783 const memmap_chunk base_map[] = { |
784 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, | |
785 NULL, NULL, NULL, NULL}, | |
786 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, | 784 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, |
787 NULL, NULL, NULL, NULL}, | 785 NULL, NULL, NULL, NULL}, |
788 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, | 786 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, |
789 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, | 787 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, |
790 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, | 788 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, |
791 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, | 789 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, |
792 (read_16_fun)io_read_w, (write_16_fun)io_write_w, | 790 (read_16_fun)io_read_w, (write_16_fun)io_write_w, |
793 (read_8_fun)io_read, (write_8_fun)io_write} | 791 (read_8_fun)io_read, (write_8_fun)io_write} |
794 }; | 792 }; |
795 | 793 |
796 char * sram_filename; | 794 char * save_filename; |
797 genesis_context * genesis; | 795 genesis_context * genesis; |
798 void save_sram() | 796 void persist_save() |
799 { | 797 { |
800 FILE * f = fopen(sram_filename, "wb"); | 798 FILE * f = fopen(save_filename, "wb"); |
801 if (!f) { | 799 if (!f) { |
802 fprintf(stderr, "Failed to open SRAM file %s for writing\n", sram_filename); | 800 fprintf(stderr, "Failed to open %s file %s for writing\n", genesis->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); |
803 return; | 801 return; |
804 } | 802 } |
805 uint32_t size = genesis->save_ram_mask+1; | 803 fwrite(genesis->save_storage, 1, genesis->save_size, f); |
806 if (genesis->save_flags != RAM_FLAG_BOTH) { | |
807 size/= 2; | |
808 } | |
809 fwrite(genesis->save_ram, 1, size, f); | |
810 fclose(f); | 804 fclose(f); |
811 printf("Saved SRAM to %s\n", sram_filename); | 805 printf("Saved %s to %s\n", genesis->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); |
812 } | 806 } |
813 | 807 |
814 void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger) | 808 void init_run_cpu(genesis_context * gen, rom_info *rom, FILE * address_log, char * statefile, uint8_t * debugger) |
815 { | 809 { |
816 m68k_options opts; | 810 m68k_options opts; |
817 memmap_chunk memmap[MAX_MAP_CHUNKS]; | 811 |
818 uint32_t num_chunks; | 812 gen->save_type = rom->save_type; |
819 void * initial_mapped = NULL; | 813 if (gen->save_type != SAVE_NONE) { |
820 gen->save_ram = NULL; | 814 gen->save_ram_mask = rom->save_mask; |
821 //TODO: Handle carts larger than 4MB | 815 gen->save_size = rom->save_size; |
822 //TODO: Handle non-standard mappers | 816 gen->save_storage = rom->save_buffer; |
823 uint32_t size; | 817 memset(gen->save_storage, 0, rom->save_size); |
824 /* | 818 FILE * f = fopen(save_filename, "rb"); |
825 if ((cart[RAM_ID/2] & 0xFF) == 'A' && (cart[RAM_ID/2] >> 8) == 'R') { | |
826 //Cart has save RAM | |
827 uint32_t rom_end = ((cart[ROM_END/2] << 16) | cart[ROM_END/2+1]) + 1; | |
828 uint32_t ram_start = (cart[RAM_START/2] << 16) | cart[RAM_START/2+1]; | |
829 uint32_t ram_end = (cart[RAM_END/2] << 16) | cart[RAM_END/2+1]; | |
830 uint16_t ram_flags = cart[RAM_FLAGS/2]; | |
831 gen->save_flags = ram_flags & RAM_FLAG_MASK; | |
832 memset(memmap, 0, sizeof(memmap_chunk)*2); | |
833 if (ram_start >= rom_end) { | |
834 memmap[0].end = rom_end; | |
835 memmap[0].mask = 0xFFFFFF; | |
836 memmap[0].flags = MMAP_READ; | |
837 memmap[0].buffer = cart; | |
838 | |
839 ram_start &= 0xFFFFFE; | |
840 ram_end |= 1; | |
841 memmap[1].start = ram_start; | |
842 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; | |
843 ram_end += 1; | |
844 memmap[1].end = ram_end; | |
845 memmap[1].flags = MMAP_READ | MMAP_WRITE; | |
846 size = ram_end-ram_start; | |
847 if ((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_ODD) { | |
848 memmap[1].flags |= MMAP_ONLY_ODD; | |
849 size /= 2; | |
850 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { | |
851 memmap[1].flags |= MMAP_ONLY_EVEN; | |
852 size /= 2; | |
853 } | |
854 memmap[1].buffer = gen->save_ram = malloc(size); | |
855 | |
856 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); | |
857 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; | |
858 } else { | |
859 //Assume the standard Sega mapper for now | |
860 memmap[0].end = 0x200000; | |
861 memmap[0].mask = 0xFFFFFF; | |
862 memmap[0].flags = MMAP_READ; | |
863 memmap[0].buffer = cart; | |
864 | |
865 memmap[1].start = 0x200000; | |
866 memmap[1].end = 0x400000; | |
867 memmap[1].mask = 0x1FFFFF; | |
868 ram_start &= 0xFFFFFE; | |
869 ram_end |= 1; | |
870 gen->save_ram_mask = ram_end-ram_start; | |
871 memmap[1].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL; | |
872 memmap[1].ptr_index = 2; | |
873 memmap[1].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL | |
874 memmap[1].read_8 = (read_8_fun)read_sram_b; | |
875 memmap[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area | |
876 memmap[1].write_8 = (write_8_fun)write_sram_area_b; | |
877 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); | |
878 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; | |
879 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); | |
880 memmap[num_chunks].start = 0xA13000; | |
881 memmap[num_chunks].end = 0xA13100; | |
882 memmap[num_chunks].mask = 0xFF; | |
883 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w; | |
884 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b; | |
885 num_chunks++; | |
886 ram_end++; | |
887 size = ram_end-ram_start; | |
888 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { | |
889 size /= 2; | |
890 } | |
891 gen->save_ram = malloc(size); | |
892 memmap[1].buffer = initial_mapped = cart + 0x200000/2; | |
893 } | |
894 } else { | |
895 memcpy(memmap, static_map, sizeof(static_map)); | |
896 num_chunks = sizeof(static_map)/sizeof(memmap_chunk); | |
897 } | |
898 */ | |
899 if (gen->save_ram) { | |
900 memset(gen->save_ram, 0, size); | |
901 FILE * f = fopen(sram_filename, "rb"); | |
902 if (f) { | 819 if (f) { |
903 uint32_t read = fread(gen->save_ram, 1, size, f); | 820 uint32_t read = fread(gen->save_storage, 1, rom->save_size, f); |
904 fclose(f); | 821 fclose(f); |
905 if (read > 0) { | 822 if (read > 0) { |
906 printf("Loaded SRAM from %s\n", sram_filename); | 823 printf("Loaded %s from %s\n", rom->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); |
907 } | 824 } |
908 } | 825 } |
909 atexit(save_sram); | 826 atexit(persist_save); |
910 } | 827 } else { |
911 init_m68k_opts(&opts, memmap, num_chunks, MCLKS_PER_68K); | 828 gen->save_storage = NULL; |
829 } | |
830 | |
831 init_m68k_opts(&opts, rom->map, rom->map_chunks, MCLKS_PER_68K); | |
912 opts.address_log = address_log; | 832 opts.address_log = address_log; |
913 m68k_context *context = init_68k_context(&opts); | 833 m68k_context *context = init_68k_context(&opts); |
914 gen->m68k = context; | 834 gen->m68k = context; |
915 | 835 |
916 context->video_context = gen->vdp; | 836 context->video_context = gen->vdp; |
919 context->mem_pointers[0] = cart; | 839 context->mem_pointers[0] = cart; |
920 context->target_cycle = context->sync_cycle = gen->frame_end > gen->max_cycles ? gen->frame_end : gen->max_cycles; | 840 context->target_cycle = context->sync_cycle = gen->frame_end > gen->max_cycles ? gen->frame_end : gen->max_cycles; |
921 //work RAM | 841 //work RAM |
922 context->mem_pointers[1] = ram; | 842 context->mem_pointers[1] = ram; |
923 //save RAM/map | 843 //save RAM/map |
924 context->mem_pointers[2] = initial_mapped; | 844 context->mem_pointers[2] = rom->map[1].buffer; |
925 context->mem_pointers[3] = (uint16_t *)gen->save_ram; | 845 context->mem_pointers[3] = (uint16_t *)gen->save_storage; |
926 | 846 |
927 if (statefile) { | 847 if (statefile) { |
928 uint32_t pc = load_gst(gen, statefile); | 848 uint32_t pc = load_gst(gen, statefile); |
929 if (!pc) { | 849 if (!pc) { |
930 fprintf(stderr, "Failed to load save state %s\n", statefile); | 850 fprintf(stderr, "Failed to load save state %s\n", statefile); |
1082 default: | 1002 default: |
1083 fprintf(stderr, "Unrecognized switch %s\n", argv[i]); | 1003 fprintf(stderr, "Unrecognized switch %s\n", argv[i]); |
1084 return 1; | 1004 return 1; |
1085 } | 1005 } |
1086 } else if (!loaded) { | 1006 } else if (!loaded) { |
1087 if(rom_size = load_rom(argv[i])) { | 1007 if (!(rom_size = load_rom(argv[i]))) { |
1088 fprintf(stderr, "Failed to open %s for reading\n", argv[i]); | 1008 fprintf(stderr, "Failed to open %s for reading\n", argv[i]); |
1089 return 1; | 1009 return 1; |
1090 } | 1010 } |
1091 romfname = argv[i]; | 1011 romfname = argv[i]; |
1092 loaded = 1; | 1012 loaded = 1; |
1099 if (!loaded) { | 1019 if (!loaded) { |
1100 fputs("You must specify a ROM filename!\n", stderr); | 1020 fputs("You must specify a ROM filename!\n", stderr); |
1101 return 1; | 1021 return 1; |
1102 } | 1022 } |
1103 tern_node *rom_db = load_rom_db(); | 1023 tern_node *rom_db = load_rom_db(); |
1104 rom_info info = configure_rom(rom_db, cart, rom_size, static_map+1, sizeof(static_map)/sizeof(static_map[0]) - 1); | 1024 rom_info info = configure_rom(rom_db, cart, rom_size, base_map, sizeof(base_map)/sizeof(base_map[0])); |
1105 byteswap_rom(); | 1025 byteswap_rom(); |
1106 set_region(&info, force_version); | 1026 set_region(&info, force_version); |
1107 update_title(info.name); | 1027 update_title(info.name); |
1108 int def_width = 0; | 1028 int def_width = 0; |
1109 char *config_width = tern_find_path(config, "video\0width\0").ptrval; | 1029 char *config_width = tern_find_path(config, "video\0width\0").ptrval; |
1156 gen.psg = &p_context; | 1076 gen.psg = &p_context; |
1157 genesis = &gen; | 1077 genesis = &gen; |
1158 setup_io_devices(config, gen.ports); | 1078 setup_io_devices(config, gen.ports); |
1159 | 1079 |
1160 int fname_size = strlen(romfname); | 1080 int fname_size = strlen(romfname); |
1161 sram_filename = malloc(fname_size+6); | 1081 char * ext = info.save_type == SAVE_I2C ? "eeprom" : "sram"; |
1162 memcpy(sram_filename, romfname, fname_size); | 1082 save_filename = malloc(fname_size+strlen(ext) + 2); |
1083 memcpy(save_filename, romfname, fname_size); | |
1163 int i; | 1084 int i; |
1164 for (i = fname_size-1; fname_size >= 0; --i) { | 1085 for (i = fname_size-1; fname_size >= 0; --i) { |
1165 if (sram_filename[i] == '.') { | 1086 if (save_filename[i] == '.') { |
1166 strcpy(sram_filename + i + 1, "sram"); | 1087 strcpy(save_filename + i + 1, ext); |
1167 break; | 1088 break; |
1168 } | 1089 } |
1169 } | 1090 } |
1170 if (i < 0) { | 1091 if (i < 0) { |
1171 strcpy(sram_filename + fname_size, ".sram"); | 1092 save_filename[fname_size] = '.'; |
1093 strcpy(save_filename + fname_size + 1, ext); | |
1172 } | 1094 } |
1173 set_keybindings(gen.ports); | 1095 set_keybindings(gen.ports); |
1174 | 1096 |
1175 init_run_cpu(&gen, address_log, statefile, debuggerfun); | 1097 init_run_cpu(&gen, &info, address_log, statefile, debuggerfun); |
1176 return 0; | 1098 return 0; |
1177 } | 1099 } |