comparison blastem.c @ 766:1b2f8280ba81

WIP changes to support reading cart memory map from ROM DB
author Michael Pavone <pavone@retrodev.com>
date Sun, 05 Jul 2015 14:21:34 -0700
parents dc54387ee1cd
children ea525f600b1d
comparison
equal deleted inserted replaced
765:dc54387ee1cd 766:1b2f8280ba81
60 uint8_t block[SMD_BLOCK_SIZE]; 60 uint8_t block[SMD_BLOCK_SIZE];
61 filesize -= SMD_HEADER_SIZE; 61 filesize -= SMD_HEADER_SIZE;
62 fseek(f, SMD_HEADER_SIZE, SEEK_SET); 62 fseek(f, SMD_HEADER_SIZE, SEEK_SET);
63 63
64 uint16_t * dst = cart; 64 uint16_t * dst = cart;
65 int rom_size = filesize;
65 while (filesize > 0) { 66 while (filesize > 0) {
66 fread(block, 1, SMD_BLOCK_SIZE, f); 67 fread(block, 1, SMD_BLOCK_SIZE, f);
67 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) { 68 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) {
68 *(dst++) = *low << 8 | *high; 69 *(dst++) = *low << 8 | *high;
69 } 70 }
70 filesize -= SMD_BLOCK_SIZE; 71 filesize -= SMD_BLOCK_SIZE;
71 } 72 }
72 return 1; 73 return filesize;
73 } 74 }
74 75
75 void byteswap_rom() 76 void byteswap_rom()
76 { 77 {
77 for(unsigned short * cur = cart; cur - cart < CARTRIDGE_WORDS; ++cur) 78 for(unsigned short * cur = cart; cur - cart < CARTRIDGE_WORDS; ++cur)
110 return load_smd_rom(filesize, f); 111 return load_smd_rom(filesize, f);
111 } 112 }
112 } 113 }
113 fread(cart, 2, filesize/2, f); 114 fread(cart, 2, filesize/2, f);
114 fclose(f); 115 fclose(f);
115 return 1; 116 return filesize;
116 } 117 }
117 118
118 uint16_t read_dma_value(uint32_t address) 119 uint16_t read_dma_value(uint32_t address)
119 { 120 {
120 //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do div by 2 121 //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do div by 2
764 } 765 }
765 766
766 return context; 767 return context;
767 } 768 }
768 769
769 uint16_t read_sram_w(uint32_t address, m68k_context * context)
770 {
771 genesis_context * gen = context->system;
772 address &= gen->save_ram_mask;
773 switch(gen->save_flags)
774 {
775 case RAM_FLAG_BOTH:
776 return gen->save_ram[address] << 8 | gen->save_ram[address+1];
777 case RAM_FLAG_EVEN:
778 return gen->save_ram[address >> 1] << 8 | 0xFF;
779 case RAM_FLAG_ODD:
780 return gen->save_ram[address >> 1] | 0xFF00;
781 }
782 return 0xFFFF;//We should never get here
783 }
784
785 uint8_t read_sram_b(uint32_t address, m68k_context * context)
786 {
787 genesis_context * gen = context->system;
788 address &= gen->save_ram_mask;
789 switch(gen->save_flags)
790 {
791 case RAM_FLAG_BOTH:
792 return gen->save_ram[address];
793 case RAM_FLAG_EVEN:
794 if (address & 1) {
795 return 0xFF;
796 } else {
797 return gen->save_ram[address >> 1];
798 }
799 case RAM_FLAG_ODD:
800 if (address & 1) {
801 return gen->save_ram[address >> 1];
802 } else {
803 return 0xFF;
804 }
805 }
806 return 0xFF;//We should never get here
807 }
808
809 m68k_context * write_sram_area_w(uint32_t address, m68k_context * context, uint16_t value)
810 {
811 genesis_context * gen = context->system;
812 if ((gen->bank_regs[0] & 0x3) == 1) {
813 address &= gen->save_ram_mask;
814 switch(gen->save_flags)
815 {
816 case RAM_FLAG_BOTH:
817 gen->save_ram[address] = value >> 8;
818 gen->save_ram[address+1] = value;
819 break;
820 case RAM_FLAG_EVEN:
821 gen->save_ram[address >> 1] = value >> 8;
822 break;
823 case RAM_FLAG_ODD:
824 gen->save_ram[address >> 1] = value;
825 break;
826 }
827 }
828 return context;
829 }
830
831 m68k_context * write_sram_area_b(uint32_t address, m68k_context * context, uint8_t value)
832 {
833 genesis_context * gen = context->system;
834 if ((gen->bank_regs[0] & 0x3) == 1) {
835 address &= gen->save_ram_mask;
836 switch(gen->save_flags)
837 {
838 case RAM_FLAG_BOTH:
839 gen->save_ram[address] = value;
840 break;
841 case RAM_FLAG_EVEN:
842 if (!(address & 1)) {
843 gen->save_ram[address >> 1] = value;
844 }
845 break;
846 case RAM_FLAG_ODD:
847 if (address & 1) {
848 gen->save_ram[address >> 1] = value;
849 }
850 break;
851 }
852 }
853 return context;
854 }
855
856 m68k_context * write_bank_reg_w(uint32_t address, m68k_context * context, uint16_t value)
857 {
858 genesis_context * gen = context->system;
859 address &= 0xE;
860 address >>= 1;
861 gen->bank_regs[address] = value;
862 if (!address) {
863 if (value & 1) {
864 context->mem_pointers[2] = NULL;
865 } else {
866 context->mem_pointers[2] = cart + 0x200000/2;
867 }
868 }
869 return context;
870 }
871
872 m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_t value)
873 {
874 if (address & 1) {
875 genesis_context * gen = context->system;
876 address &= 0xE;
877 address >>= 1;
878 gen->bank_regs[address] = value;
879 if (!address) {
880 if (value & 1) {
881 context->mem_pointers[2] = NULL;
882 } else {
883 context->mem_pointers[2] = cart + 0x200000/2;
884 }
885 }
886 }
887 return context;
888 }
889
890 void set_speed_percent(genesis_context * context, uint32_t percent) 770 void set_speed_percent(genesis_context * context, uint32_t percent)
891 { 771 {
892 uint32_t old_clock = context->master_clock; 772 uint32_t old_clock = context->master_clock;
893 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100; 773 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100;
894 while (context->ym->current_cycle != context->psg->cycles) { 774 while (context->ym->current_cycle != context->psg->cycles) {
896 } 776 }
897 ym_adjust_master_clock(context->ym, context->master_clock); 777 ym_adjust_master_clock(context->ym, context->master_clock);
898 psg_adjust_master_clock(context->psg, context->master_clock); 778 psg_adjust_master_clock(context->psg, context->master_clock);
899 } 779 }
900 780
901 #define ROM_END 0x1A4
902 #define RAM_ID 0x1B0
903 #define RAM_FLAGS 0x1B2
904 #define RAM_START 0x1B4
905 #define RAM_END 0x1B8
906 #define MAX_MAP_CHUNKS (4+7+1) 781 #define MAX_MAP_CHUNKS (4+7+1)
907 #define RAM_FLAG_MASK 0x1800
908 782
909 const memmap_chunk static_map[] = { 783 const memmap_chunk static_map[] = {
910 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, 784 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart,
911 NULL, NULL, NULL, NULL}, 785 NULL, NULL, NULL, NULL},
912 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, 786 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram,
945 void * initial_mapped = NULL; 819 void * initial_mapped = NULL;
946 gen->save_ram = NULL; 820 gen->save_ram = NULL;
947 //TODO: Handle carts larger than 4MB 821 //TODO: Handle carts larger than 4MB
948 //TODO: Handle non-standard mappers 822 //TODO: Handle non-standard mappers
949 uint32_t size; 823 uint32_t size;
824 /*
950 if ((cart[RAM_ID/2] & 0xFF) == 'A' && (cart[RAM_ID/2] >> 8) == 'R') { 825 if ((cart[RAM_ID/2] & 0xFF) == 'A' && (cart[RAM_ID/2] >> 8) == 'R') {
951 //Cart has save RAM 826 //Cart has save RAM
952 uint32_t rom_end = ((cart[ROM_END/2] << 16) | cart[ROM_END/2+1]) + 1; 827 uint32_t rom_end = ((cart[ROM_END/2] << 16) | cart[ROM_END/2+1]) + 1;
953 uint32_t ram_start = (cart[RAM_START/2] << 16) | cart[RAM_START/2+1]; 828 uint32_t ram_start = (cart[RAM_START/2] << 16) | cart[RAM_START/2+1];
954 uint32_t ram_end = (cart[RAM_END/2] << 16) | cart[RAM_END/2+1]; 829 uint32_t ram_end = (cart[RAM_END/2] << 16) | cart[RAM_END/2+1];
1018 } 893 }
1019 } else { 894 } else {
1020 memcpy(memmap, static_map, sizeof(static_map)); 895 memcpy(memmap, static_map, sizeof(static_map));
1021 num_chunks = sizeof(static_map)/sizeof(memmap_chunk); 896 num_chunks = sizeof(static_map)/sizeof(memmap_chunk);
1022 } 897 }
898 */
1023 if (gen->save_ram) { 899 if (gen->save_ram) {
1024 memset(gen->save_ram, 0, size); 900 memset(gen->save_ram, 0, size);
1025 FILE * f = fopen(sram_filename, "rb"); 901 FILE * f = fopen(sram_filename, "rb");
1026 if (f) { 902 if (f) {
1027 uint32_t read = fread(gen->save_ram, 1, size, f); 903 uint32_t read = fread(gen->save_ram, 1, size, f);
1124 int loaded = 0; 1000 int loaded = 0;
1125 uint8_t force_version = 0; 1001 uint8_t force_version = 0;
1126 char * romfname = NULL; 1002 char * romfname = NULL;
1127 FILE *address_log = NULL; 1003 FILE *address_log = NULL;
1128 char * statefile = NULL; 1004 char * statefile = NULL;
1005 int rom_size;
1129 uint8_t * debuggerfun = NULL; 1006 uint8_t * debuggerfun = NULL;
1130 uint8_t fullscreen = 0, use_gl = 1; 1007 uint8_t fullscreen = 0, use_gl = 1;
1131 for (int i = 1; i < argc; i++) { 1008 for (int i = 1; i < argc; i++) {
1132 if (argv[i][0] == '-') { 1009 if (argv[i][0] == '-') {
1133 switch(argv[i][1]) { 1010 switch(argv[i][1]) {
1205 default: 1082 default:
1206 fprintf(stderr, "Unrecognized switch %s\n", argv[i]); 1083 fprintf(stderr, "Unrecognized switch %s\n", argv[i]);
1207 return 1; 1084 return 1;
1208 } 1085 }
1209 } else if (!loaded) { 1086 } else if (!loaded) {
1210 if(!load_rom(argv[i])) { 1087 if(rom_size = load_rom(argv[i])) {
1211 fprintf(stderr, "Failed to open %s for reading\n", argv[i]); 1088 fprintf(stderr, "Failed to open %s for reading\n", argv[i]);
1212 return 1; 1089 return 1;
1213 } 1090 }
1214 romfname = argv[i]; 1091 romfname = argv[i];
1215 loaded = 1; 1092 loaded = 1;
1222 if (!loaded) { 1099 if (!loaded) {
1223 fputs("You must specify a ROM filename!\n", stderr); 1100 fputs("You must specify a ROM filename!\n", stderr);
1224 return 1; 1101 return 1;
1225 } 1102 }
1226 tern_node *rom_db = load_rom_db(); 1103 tern_node *rom_db = load_rom_db();
1227 rom_info info = configure_rom(rom_db, cart); 1104 rom_info info = configure_rom(rom_db, cart, rom_size, static_map+1, sizeof(static_map)/sizeof(static_map[0]) - 1);
1228 byteswap_rom(); 1105 byteswap_rom();
1229 set_region(&info, force_version); 1106 set_region(&info, force_version);
1230 update_title(info.name); 1107 update_title(info.name);
1231 int def_width = 0; 1108 int def_width = 0;
1232 char *config_width = tern_find_ptr(config, "videowidth"); 1109 char *config_width = tern_find_path(config, "video\0width\0").ptrval;
1233 if (config_width) { 1110 if (config_width) {
1234 def_width = atoi(config_width); 1111 def_width = atoi(config_width);
1235 } 1112 }
1236 if (!def_width) { 1113 if (!def_width) {
1237 def_width = 640; 1114 def_width = 640;
1250 memset(&gen, 0, sizeof(gen)); 1127 memset(&gen, 0, sizeof(gen));
1251 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; 1128 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL;
1252 1129
1253 init_vdp_context(&v_context, version_reg & 0x40); 1130 init_vdp_context(&v_context, version_reg & 0x40);
1254 gen.frame_end = vdp_cycles_to_frame_end(&v_context); 1131 gen.frame_end = vdp_cycles_to_frame_end(&v_context);
1255 char * config_cycles = tern_find_ptr(config, "clocksmax_cycles"); 1132 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0").ptrval;
1256 gen.max_cycles = config_cycles ? atoi(config_cycles) : 10000000; 1133 gen.max_cycles = config_cycles ? atoi(config_cycles) : 10000000;
1257 1134
1258 ym2612_context y_context; 1135 ym2612_context y_context;
1259 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); 1136 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0);
1260 1137