Mercurial > repos > blastem
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 |