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 }