comparison genesis.c @ 1648:b7ecd0d6a77b mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Tue, 25 Dec 2018 11:12:26 -0800
parents 2455662378ed 6909c5d0bbb5
children 956c1cce05e2
comparison
equal deleted inserted replaced
1509:36732f5c2281 1648:b7ecd0d6a77b
13 #include "render.h" 13 #include "render.h"
14 #include "gst.h" 14 #include "gst.h"
15 #include "util.h" 15 #include "util.h"
16 #include "debug.h" 16 #include "debug.h"
17 #include "gdb_remote.h" 17 #include "gdb_remote.h"
18 #include "saves.h"
19 #include "bindings.h"
20 #include "jcart.h"
18 #define MCLKS_NTSC 53693175 21 #define MCLKS_NTSC 53693175
19 #define MCLKS_PAL 53203395 22 #define MCLKS_PAL 53203395
20 23
21 uint32_t MCLKS_PER_68K; 24 uint32_t MCLKS_PER_68K;
22 #define MCLKS_PER_YM 7 25 #define MCLKS_PER_YM 7
26 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE 29 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE
27 #define DEFAULT_LOWPASS_CUTOFF 3390 30 #define DEFAULT_LOWPASS_CUTOFF 3390
28 31
29 //TODO: Figure out the exact value for this 32 //TODO: Figure out the exact value for this
30 #define LINES_NTSC 262 33 #define LINES_NTSC 262
31 #define LINES_PAL 312 34 #define LINES_PAL 313
32 35
33 #define MAX_SOUND_CYCLES 100000 36 #define MAX_SOUND_CYCLES 100000
34 37
35 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) 38 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc)
36 { 39 {
107 z80_invalidate_code_range(gen->z80, 0, 0x4000); 110 z80_invalidate_code_range(gen->z80, 0, 0x4000);
108 } 111 }
109 112
110 static void update_z80_bank_pointer(genesis_context *gen) 113 static void update_z80_bank_pointer(genesis_context *gen)
111 { 114 {
112 if (gen->z80->bank_reg < 0x100) { 115 if (gen->z80->bank_reg < 0x140) {
113 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80->bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen); 116 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80->bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen);
114 } else { 117 } else {
115 gen->z80->mem_pointers[1] = NULL; 118 gen->z80->mem_pointers[1] = NULL;
116 } 119 }
117 } 120 }
122 gen->z80->reset = load_int8(buf); 125 gen->z80->reset = load_int8(buf);
123 gen->z80->busreq = load_int8(buf); 126 gen->z80->busreq = load_int8(buf);
124 gen->z80->bank_reg = load_int16(buf) & 0x1FF; 127 gen->z80->bank_reg = load_int16(buf) & 0x1FF;
125 } 128 }
126 129
130 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
127 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 131 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
128 { 132 {
129 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 133 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
130 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 134 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
131 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 135 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
141 while (buf->cur_pos < buf->size) 145 while (buf->cur_pos < buf->size)
142 { 146 {
143 load_section(buf); 147 load_section(buf);
144 } 148 }
145 update_z80_bank_pointer(gen); 149 update_z80_bank_pointer(gen);
150 adjust_int_cycle(gen->m68k, gen->vdp);
146 } 151 }
147 152
148 uint16_t read_dma_value(uint32_t address) 153 uint16_t read_dma_value(uint32_t address)
149 { 154 {
150 genesis_context *genesis = (genesis_context *)current_system; 155 genesis_context *genesis = (genesis_context *)current_system;
306 311
307 uint32_t mclks = context->current_cycle; 312 uint32_t mclks = context->current_cycle;
308 sync_z80(z_context, mclks); 313 sync_z80(z_context, mclks);
309 sync_sound(gen, mclks); 314 sync_sound(gen, mclks);
310 vdp_run_context(v_context, mclks); 315 vdp_run_context(v_context, mclks);
316 if (mclks >= gen->reset_cycle) {
317 gen->reset_requested = 1;
318 context->should_return = 1;
319 gen->reset_cycle = CYCLE_NEVER;
320 }
311 if (v_context->frame != last_frame_num) { 321 if (v_context->frame != last_frame_num) {
312 //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot); 322 //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
313 last_frame_num = v_context->frame; 323 last_frame_num = v_context->frame;
314 324
315 if(exit_after){ 325 if(exit_after){
322 uint32_t deduction = mclks - ADJUST_BUFFER; 332 uint32_t deduction = mclks - ADJUST_BUFFER;
323 vdp_adjust_cycles(v_context, deduction); 333 vdp_adjust_cycles(v_context, deduction);
324 io_adjust_cycles(gen->io.ports, context->current_cycle, deduction); 334 io_adjust_cycles(gen->io.ports, context->current_cycle, deduction);
325 io_adjust_cycles(gen->io.ports+1, context->current_cycle, deduction); 335 io_adjust_cycles(gen->io.ports+1, context->current_cycle, deduction);
326 io_adjust_cycles(gen->io.ports+2, context->current_cycle, deduction); 336 io_adjust_cycles(gen->io.ports+2, context->current_cycle, deduction);
337 if (gen->mapper_type == MAPPER_JCART) {
338 jcart_adjust_cycles(gen, deduction);
339 }
327 context->current_cycle -= deduction; 340 context->current_cycle -= deduction;
328 z80_adjust_cycles(z_context, deduction); 341 z80_adjust_cycles(z_context, deduction);
329 gen->ym->current_cycle -= deduction; 342 gen->ym->current_cycle -= deduction;
330 gen->psg->cycles -= deduction; 343 gen->psg->cycles -= deduction;
331 if (gen->ym->write_cycle != CYCLE_NEVER) { 344 if (gen->ym->write_cycle != CYCLE_NEVER) {
332 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0; 345 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0;
346 }
347 if (gen->reset_cycle != CYCLE_NEVER) {
348 gen->reset_cycle -= deduction;
333 } 349 }
334 } 350 }
335 } 351 }
336 gen->frame_end = vdp_cycles_to_frame_end(v_context); 352 gen->frame_end = vdp_cycles_to_frame_end(v_context);
337 context->sync_cycle = gen->frame_end; 353 context->sync_cycle = gen->frame_end;
343 } 359 }
344 if (!address && (gen->header.enter_debugger || gen->header.save_state)) { 360 if (!address && (gen->header.enter_debugger || gen->header.save_state)) {
345 context->sync_cycle = context->current_cycle + 1; 361 context->sync_cycle = context->current_cycle + 1;
346 } 362 }
347 adjust_int_cycle(context, v_context); 363 adjust_int_cycle(context, v_context);
364 if (gen->reset_cycle < context->target_cycle) {
365 context->target_cycle = gen->reset_cycle;
366 }
348 #ifdef USE_NATIVE 367 #ifdef USE_NATIVE
349 if (address) { 368 if (address) {
350 if (gen->header.enter_debugger) { 369 if (gen->header.enter_debugger) {
351 gen->header.enter_debugger = 0; 370 gen->header.enter_debugger = 0;
352 debugger(context, address); 371 debugger(context, address);
359 while (!z_context->pc) 378 while (!z_context->pc)
360 { 379 {
361 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 380 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
362 } 381 }
363 } 382 }
364 char *save_path; 383 char *save_path = get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
365 if (slot == QUICK_SAVE_SLOT) {
366 save_path = save_state_path;
367 } else {
368 char slotname[] = "slot_0.state";
369 slotname[5] = '0' + slot;
370 if (!use_native_states) {
371 strcpy(slotname + 7, "gst");
372 }
373 char const *parts[] = {gen->header.save_dir, PATH_SEP, slotname};
374 save_path = alloc_concat_m(3, parts);
375 }
376 if (use_native_states) { 384 if (use_native_states) {
377 serialize_buffer state; 385 serialize_buffer state;
378 init_serialize(&state); 386 init_serialize(&state);
379 genesis_serialize(gen, &state, address); 387 genesis_serialize(gen, &state, address);
380 save_to_file(&state, save_path); 388 save_to_file(&state, save_path);
381 free(state.data); 389 free(state.data);
382 } else { 390 } else {
383 save_gst(gen, save_path, address); 391 save_gst(gen, save_path, address);
384 } 392 }
385 printf("Saved state to %s\n", save_path); 393 printf("Saved state to %s\n", save_path);
386 if (slot != QUICK_SAVE_SLOT) { 394 free(save_path);
387 free(save_path);
388 }
389 } else if(gen->header.save_state) { 395 } else if(gen->header.save_state) {
390 context->sync_cycle = context->current_cycle + 1; 396 context->sync_cycle = context->current_cycle + 1;
391 } 397 }
392 } 398 }
393 #endif 399 #endif
1027 gen->normal_clock = MCLKS_NTSC; 1033 gen->normal_clock = MCLKS_NTSC;
1028 } 1034 }
1029 gen->master_clock = gen->normal_clock; 1035 gen->master_clock = gen->normal_clock;
1030 } 1036 }
1031 1037
1032 static void handle_reset_requests(genesis_context *gen)
1033 {
1034 while (gen->reset_requested)
1035 {
1036 gen->reset_requested = 0;
1037 z80_assert_reset(gen->z80, gen->m68k->current_cycle);
1038 z80_clear_busreq(gen->z80, gen->m68k->current_cycle);
1039 ym_reset(gen->ym);
1040 //Is there any sort of VDP reset?
1041 m68k_reset(gen->m68k);
1042 }
1043 vdp_release_framebuffer(gen->vdp);
1044 }
1045
1046 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up 1038 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
1047 static uint8_t load_state(system_header *system, uint8_t slot) 1039 static uint8_t load_state(system_header *system, uint8_t slot)
1048 { 1040 {
1049 genesis_context *gen = (genesis_context *)system; 1041 genesis_context *gen = (genesis_context *)system;
1050 char numslotname[] = "slot_0.state"; 1042 char *statepath = get_slot_name(system, slot, "state");
1051 char *slotname;
1052 if (slot == QUICK_SAVE_SLOT) {
1053 slotname = "quicksave.state";
1054 } else {
1055 numslotname[5] = '0' + slot;
1056 slotname = numslotname;
1057 }
1058 char const *parts[] = {gen->header.save_dir, PATH_SEP, slotname};
1059 char *statepath = alloc_concat_m(3, parts);
1060 deserialize_buffer state; 1043 deserialize_buffer state;
1061 uint32_t pc = 0; 1044 uint32_t pc = 0;
1062 uint8_t ret = 0; 1045 uint8_t ret = 0;
1046 if (!gen->m68k->resume_pc) {
1047 system->delayed_load_slot = slot + 1;
1048 gen->m68k->should_return = 1;
1049 ret = get_modification_time(statepath) != 0;
1050 if (!ret) {
1051 strcpy(statepath + strlen(statepath)-strlen("state"), "gst");
1052 ret = get_modification_time(statepath) != 0;
1053 }
1054 goto done;
1055 }
1063 if (load_from_file(&state, statepath)) { 1056 if (load_from_file(&state, statepath)) {
1064 genesis_deserialize(&state, gen); 1057 genesis_deserialize(&state, gen);
1065 free(state.data); 1058 free(state.data);
1066 //HACK 1059 //HACK
1067 pc = gen->m68k->last_prefetch_address; 1060 pc = gen->m68k->last_prefetch_address;
1076 #ifdef USE_NATIVE 1069 #ifdef USE_NATIVE
1077 if (ret) { 1070 if (ret) {
1078 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc); 1071 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc);
1079 } 1072 }
1080 #endif 1073 #endif
1074 done:
1081 free(statepath); 1075 free(statepath);
1082 return ret; 1076 return ret;
1083 } 1077 }
1084 1078
1079 static void handle_reset_requests(genesis_context *gen)
1080 {
1081 while (gen->reset_requested || gen->header.delayed_load_slot)
1082 {
1083 if (gen->reset_requested) {
1084 gen->reset_requested = 0;
1085 gen->m68k->should_return = 0;
1086 z80_assert_reset(gen->z80, gen->m68k->current_cycle);
1087 z80_clear_busreq(gen->z80, gen->m68k->current_cycle);
1088 ym_reset(gen->ym);
1089 //Is there any sort of VDP reset?
1090 m68k_reset(gen->m68k);
1091 }
1092 if (gen->header.delayed_load_slot) {
1093 load_state(&gen->header, gen->header.delayed_load_slot - 1);
1094 gen->header.delayed_load_slot = 0;
1095 resume_68k(gen->m68k);
1096 }
1097 }
1098 bindings_release_capture();
1099 vdp_release_framebuffer(gen->vdp);
1100 render_pause_source(gen->ym->audio);
1101 render_pause_source(gen->psg->audio);
1102 }
1103
1085 static void start_genesis(system_header *system, char *statefile) 1104 static void start_genesis(system_header *system, char *statefile)
1086 { 1105 {
1087 genesis_context *gen = (genesis_context *)system; 1106 genesis_context *gen = (genesis_context *)system;
1088 set_keybindings(&gen->io);
1089 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1090 if (statefile) { 1107 if (statefile) {
1091 //first try loading as a native format savestate 1108 //first try loading as a native format savestate
1092 deserialize_buffer state; 1109 deserialize_buffer state;
1093 uint32_t pc; 1110 uint32_t pc;
1094 if (load_from_file(&state, statefile)) { 1111 if (load_from_file(&state, statefile)) {
1128 } 1145 }
1129 1146
1130 static void resume_genesis(system_header *system) 1147 static void resume_genesis(system_header *system)
1131 { 1148 {
1132 genesis_context *gen = (genesis_context *)system; 1149 genesis_context *gen = (genesis_context *)system;
1133 map_all_bindings(&gen->io);
1134 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1150 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1151 bindings_reacquire_capture();
1135 vdp_reacquire_framebuffer(gen->vdp); 1152 vdp_reacquire_framebuffer(gen->vdp);
1153 render_resume_source(gen->ym->audio);
1154 render_resume_source(gen->psg->audio);
1136 resume_68k(gen->m68k); 1155 resume_68k(gen->m68k);
1137 handle_reset_requests(gen); 1156 handle_reset_requests(gen);
1138 } 1157 }
1139 1158
1140 static void inc_debug_mode(system_header *system) 1159 static void inc_debug_mode(system_header *system)
1141 { 1160 {
1142 genesis_context *gen = (genesis_context *)system; 1161 genesis_context *gen = (genesis_context *)system;
1143 gen->vdp->debug++; 1162 vdp_inc_debug_mode(gen->vdp);
1144 if (gen->vdp->debug == 7) {
1145 gen->vdp->debug = 0;
1146 }
1147 }
1148
1149 static void inc_debug_pal(system_header *system)
1150 {
1151 genesis_context *gen = (genesis_context *)system;
1152 gen->vdp->debug_pal++;
1153 if (gen->vdp->debug_pal == 4) {
1154 gen->vdp->debug_pal = 0;
1155 }
1156 } 1163 }
1157 1164
1158 static void request_exit(system_header *system) 1165 static void request_exit(system_header *system)
1159 { 1166 {
1160 genesis_context *gen = (genesis_context *)system; 1167 genesis_context *gen = (genesis_context *)system;
1191 } 1198 }
1192 1199
1193 static void soft_reset(system_header *system) 1200 static void soft_reset(system_header *system)
1194 { 1201 {
1195 genesis_context *gen = (genesis_context *)system; 1202 genesis_context *gen = (genesis_context *)system;
1196 gen->m68k->should_return = 1; 1203 if (gen->reset_cycle == CYCLE_NEVER) {
1197 gen->reset_requested = 1; 1204 double random = (double)rand()/(double)RAND_MAX;
1205 gen->reset_cycle = gen->m68k->current_cycle + random * MCLKS_LINE * (gen->version_reg & HZ50 ? LINES_PAL : LINES_NTSC);
1206 if (gen->reset_cycle < gen->m68k->target_cycle) {
1207 gen->m68k->target_cycle = gen->reset_cycle;
1208 }
1209 }
1198 } 1210 }
1199 1211
1200 static void free_genesis(system_header *system) 1212 static void free_genesis(system_header *system)
1201 { 1213 {
1202 genesis_context *gen = (genesis_context *)system; 1214 genesis_context *gen = (genesis_context *)system;
1203 vdp_free(gen->vdp); 1215 vdp_free(gen->vdp);
1216 memmap_chunk *map = (memmap_chunk *)gen->m68k->options->gen.memmap;
1204 m68k_options_free(gen->m68k->options); 1217 m68k_options_free(gen->m68k->options);
1205 free(gen->cart); 1218 free(gen->cart);
1206 free(gen->m68k); 1219 free(gen->m68k);
1207 free(gen->work_ram); 1220 free(gen->work_ram);
1208 z80_options_free(gen->z80->options); 1221 z80_options_free(gen->z80->options);
1209 free(gen->z80); 1222 free(gen->z80);
1210 free(gen->zram); 1223 free(gen->zram);
1211 ym_free(gen->ym); 1224 ym_free(gen->ym);
1212 psg_free(gen->psg); 1225 psg_free(gen->psg);
1213 free(gen->save_storage);
1214 free(gen->header.save_dir); 1226 free(gen->header.save_dir);
1227 free_rom_info(&gen->header.info);
1215 free(gen->lock_on); 1228 free(gen->lock_on);
1216 free(gen); 1229 free(gen);
1230 }
1231
1232 static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t button)
1233 {
1234 genesis_context *gen = (genesis_context *)system;
1235 io_gamepad_down(&gen->io, gamepad_num, button);
1236 if (gen->mapper_type == MAPPER_JCART) {
1237 jcart_gamepad_down(gen, gamepad_num, button);
1238 }
1239 }
1240
1241 static void gamepad_up(system_header *system, uint8_t gamepad_num, uint8_t button)
1242 {
1243 genesis_context *gen = (genesis_context *)system;
1244 io_gamepad_up(&gen->io, gamepad_num, button);
1245 if (gen->mapper_type == MAPPER_JCART) {
1246 jcart_gamepad_up(gen, gamepad_num, button);
1247 }
1248 }
1249
1250 static void mouse_down(system_header *system, uint8_t mouse_num, uint8_t button)
1251 {
1252 genesis_context *gen = (genesis_context *)system;
1253 io_mouse_down(&gen->io, mouse_num, button);
1254 }
1255
1256 static void mouse_up(system_header *system, uint8_t mouse_num, uint8_t button)
1257 {
1258 genesis_context *gen = (genesis_context *)system;
1259 io_mouse_up(&gen->io, mouse_num, button);
1260 }
1261
1262 static void mouse_motion_absolute(system_header *system, uint8_t mouse_num, uint16_t x, uint16_t y)
1263 {
1264 genesis_context *gen = (genesis_context *)system;
1265 io_mouse_motion_absolute(&gen->io, mouse_num, x, y);
1266 }
1267
1268 static void mouse_motion_relative(system_header *system, uint8_t mouse_num, int32_t x, int32_t y)
1269 {
1270 genesis_context *gen = (genesis_context *)system;
1271 io_mouse_motion_relative(&gen->io, mouse_num, x, y);
1272 }
1273
1274 static void keyboard_down(system_header *system, uint8_t scancode)
1275 {
1276 genesis_context *gen = (genesis_context *)system;
1277 io_keyboard_down(&gen->io, scancode);
1278 }
1279
1280 static void keyboard_up(system_header *system, uint8_t scancode)
1281 {
1282 genesis_context *gen = (genesis_context *)system;
1283 io_keyboard_up(&gen->io, scancode);
1284 }
1285
1286 static void config_updated(system_header *system)
1287 {
1288 genesis_context *gen = (genesis_context *)system;
1289 setup_io_devices(config, &system->info, &gen->io);
1217 } 1290 }
1218 1291
1219 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 1292 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
1220 { 1293 {
1221 static memmap_chunk z80_map[] = { 1294 static memmap_chunk z80_map[] = {
1235 gen->header.soft_reset = soft_reset; 1308 gen->header.soft_reset = soft_reset;
1236 gen->header.free_context = free_genesis; 1309 gen->header.free_context = free_genesis;
1237 gen->header.get_open_bus_value = get_open_bus_value; 1310 gen->header.get_open_bus_value = get_open_bus_value;
1238 gen->header.request_exit = request_exit; 1311 gen->header.request_exit = request_exit;
1239 gen->header.inc_debug_mode = inc_debug_mode; 1312 gen->header.inc_debug_mode = inc_debug_mode;
1240 gen->header.inc_debug_pal = inc_debug_pal; 1313 gen->header.gamepad_down = gamepad_down;
1314 gen->header.gamepad_up = gamepad_up;
1315 gen->header.mouse_down = mouse_down;
1316 gen->header.mouse_up = mouse_up;
1317 gen->header.mouse_motion_absolute = mouse_motion_absolute;
1318 gen->header.mouse_motion_relative = mouse_motion_relative;
1319 gen->header.keyboard_down = keyboard_down;
1320 gen->header.keyboard_up = keyboard_up;
1321 gen->header.config_updated = config_updated;
1241 gen->header.type = SYSTEM_GENESIS; 1322 gen->header.type = SYSTEM_GENESIS;
1323 gen->header.info = *rom;
1242 set_region(gen, rom, force_region); 1324 set_region(gen, rom, force_region);
1243 1325
1244 gen->vdp = malloc(sizeof(vdp_context)); 1326 gen->vdp = init_vdp_context(gen->version_reg & 0x40);
1245 init_vdp_context(gen->vdp, gen->version_reg & 0x40);
1246 gen->vdp->system = &gen->header; 1327 gen->vdp->system = &gen->header;
1247 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp); 1328 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp);
1248 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval; 1329 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval;
1249 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL; 1330 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL;
1250 gen->int_latency_prev1 = MCLKS_PER_68K * 32; 1331 gen->int_latency_prev1 = MCLKS_PER_68K * 32;
1251 gen->int_latency_prev2 = MCLKS_PER_68K * 16; 1332 gen->int_latency_prev2 = MCLKS_PER_68K * 16;
1252 1333
1253 char * lowpass_cutoff_str = tern_find_path(config, "audio\0lowpass_cutoff\0", TVAL_PTR).ptrval; 1334 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1254 uint32_t lowpass_cutoff = lowpass_cutoff_str ? atoi(lowpass_cutoff_str) : DEFAULT_LOWPASS_CUTOFF;
1255 1335
1256 gen->ym = malloc(sizeof(ym2612_context)); 1336 gen->ym = malloc(sizeof(ym2612_context));
1257 ym_init(gen->ym, render_sample_rate(), gen->master_clock, MCLKS_PER_YM, render_audio_buffer(), system_opts, lowpass_cutoff); 1337 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts);
1258 1338
1259 gen->psg = malloc(sizeof(psg_context)); 1339 gen->psg = malloc(sizeof(psg_context));
1260 psg_init(gen->psg, render_sample_rate(), gen->master_clock, MCLKS_PER_PSG, render_audio_buffer(), lowpass_cutoff); 1340 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG);
1261 1341
1262 gen->zram = calloc(1, Z80_RAM_BYTES);
1263 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); 1342 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES);
1264 #ifndef NO_Z80 1343 #ifndef NO_Z80
1265 z80_options *z_opts = malloc(sizeof(z80_options)); 1344 z80_options *z_opts = malloc(sizeof(z80_options));
1266 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF); 1345 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF);
1267 gen->z80 = init_z80_context(z_opts); 1346 gen->z80 = init_z80_context(z_opts);
1305 { 1384 {
1306 gen->vdp->vsram[i] = rand(); 1385 gen->vdp->vsram[i] = rand();
1307 } 1386 }
1308 } 1387 }
1309 setup_io_devices(config, rom, &gen->io); 1388 setup_io_devices(config, rom, &gen->io);
1389 gen->header.has_keyboard = io_has_keyboard(&gen->io);
1310 1390
1311 gen->mapper_type = rom->mapper_type; 1391 gen->mapper_type = rom->mapper_type;
1312 gen->save_type = rom->save_type; 1392 gen->save_type = rom->save_type;
1313 if (gen->save_type != SAVE_NONE) { 1393 if (gen->save_type != SAVE_NONE) {
1314 gen->save_ram_mask = rom->save_mask; 1394 gen->save_ram_mask = rom->save_mask;
1317 gen->eeprom_map = rom->eeprom_map; 1397 gen->eeprom_map = rom->eeprom_map;
1318 gen->num_eeprom = rom->num_eeprom; 1398 gen->num_eeprom = rom->num_eeprom;
1319 if (gen->save_type == SAVE_I2C) { 1399 if (gen->save_type == SAVE_I2C) {
1320 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size); 1400 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size);
1321 } else if (gen->save_type == SAVE_NOR) { 1401 } else if (gen->save_type == SAVE_NOR) {
1322 nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus); 1402 memcpy(&gen->nor, rom->nor, sizeof(gen->nor));
1403 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus);
1323 } 1404 }
1324 } else { 1405 } else {
1325 gen->save_storage = NULL; 1406 gen->save_storage = NULL;
1326 } 1407 }
1327 1408
1359 } 1440 }
1360 1441
1361 return gen; 1442 return gen;
1362 } 1443 }
1363 1444
1364 genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region, rom_info *info_out) 1445 genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region)
1365 { 1446 {
1366 static memmap_chunk base_map[] = { 1447 static memmap_chunk base_map[] = {
1367 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL, 1448 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL,
1368 NULL, NULL, NULL, NULL}, 1449 NULL, NULL, NULL, NULL},
1369 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL, 1450 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
1375 }; 1456 };
1376 static tern_node *rom_db; 1457 static tern_node *rom_db;
1377 if (!rom_db) { 1458 if (!rom_db) {
1378 rom_db = load_rom_db(); 1459 rom_db = load_rom_db();
1379 } 1460 }
1380 *info_out = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, sizeof(base_map)/sizeof(base_map[0])); 1461 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
1381 rom = info_out->rom; 1462 rom = info.rom;
1382 rom_size = info_out->rom_size; 1463 rom_size = info.rom_size;
1383 #ifndef BLASTEM_BIG_ENDIAN 1464 #ifndef BLASTEM_BIG_ENDIAN
1384 byteswap_rom(rom_size, rom); 1465 byteswap_rom(rom_size, rom);
1385 if (lock_on) { 1466 if (lock_on) {
1386 byteswap_rom(lock_on_size, lock_on); 1467 byteswap_rom(lock_on_size, lock_on);
1387 } 1468 }
1392 } 1473 }
1393 MCLKS_PER_68K = atoi(m68k_divider); 1474 MCLKS_PER_68K = atoi(m68k_divider);
1394 if (!MCLKS_PER_68K) { 1475 if (!MCLKS_PER_68K) {
1395 MCLKS_PER_68K = 7; 1476 MCLKS_PER_68K = 7;
1396 } 1477 }
1397 return alloc_init_genesis(info_out, rom, lock_on, ym_opts, force_region); 1478 return alloc_init_genesis(&info, rom, lock_on, ym_opts, force_region);
1398 } 1479 }