comparison genesis.c @ 1692:5dacaef602a7 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 05 Jan 2019 00:58:08 -0800
parents a763523dadf4 6909c5d0bbb5
children 3414a4423de1
comparison
equal deleted inserted replaced
1504:95b3a1a8b26c 1692:5dacaef602a7
14 #include "render.h" 14 #include "render.h"
15 #include "gst.h" 15 #include "gst.h"
16 #include "util.h" 16 #include "util.h"
17 #include "debug.h" 17 #include "debug.h"
18 #include "gdb_remote.h" 18 #include "gdb_remote.h"
19 #include "saves.h"
20 #include "bindings.h"
21 #include "jcart.h"
19 #define MCLKS_NTSC 53693175 22 #define MCLKS_NTSC 53693175
20 #define MCLKS_PAL 53203395 23 #define MCLKS_PAL 53203395
21 24
22 uint32_t MCLKS_PER_68K; 25 uint32_t MCLKS_PER_68K;
23 #define MCLKS_PER_YM 7 26 #define MCLKS_PER_YM 7
27 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE 30 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE
28 #define DEFAULT_LOWPASS_CUTOFF 3390 31 #define DEFAULT_LOWPASS_CUTOFF 3390
29 32
30 //TODO: Figure out the exact value for this 33 //TODO: Figure out the exact value for this
31 #define LINES_NTSC 262 34 #define LINES_NTSC 262
32 #define LINES_PAL 312 35 #define LINES_PAL 313
33 36
34 #define MAX_SOUND_CYCLES 100000 37 #define MAX_SOUND_CYCLES 100000
35 38
36 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) 39 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc)
37 { 40 {
108 z80_invalidate_code_range(gen->z80, 0, 0x4000); 111 z80_invalidate_code_range(gen->z80, 0, 0x4000);
109 } 112 }
110 113
111 static void update_z80_bank_pointer(genesis_context *gen) 114 static void update_z80_bank_pointer(genesis_context *gen)
112 { 115 {
113 if (gen->z80->bank_reg < 0x100) { 116 if (gen->z80->bank_reg < 0x140) {
114 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80->bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen); 117 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80->bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen);
115 } else { 118 } else {
116 gen->z80->mem_pointers[1] = NULL; 119 gen->z80->mem_pointers[1] = NULL;
117 } 120 }
118 } 121 }
123 gen->z80->reset = load_int8(buf); 126 gen->z80->reset = load_int8(buf);
124 gen->z80->busreq = load_int8(buf); 127 gen->z80->busreq = load_int8(buf);
125 gen->z80->bank_reg = load_int16(buf) & 0x1FF; 128 gen->z80->bank_reg = load_int16(buf) & 0x1FF;
126 } 129 }
127 130
131 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
128 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 132 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
129 { 133 {
130 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 134 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
131 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 135 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
132 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 136 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
142 while (buf->cur_pos < buf->size) 146 while (buf->cur_pos < buf->size)
143 { 147 {
144 load_section(buf); 148 load_section(buf);
145 } 149 }
146 update_z80_bank_pointer(gen); 150 update_z80_bank_pointer(gen);
151 adjust_int_cycle(gen->m68k, gen->vdp);
147 } 152 }
148 153
149 uint16_t read_dma_value(uint32_t address) 154 uint16_t read_dma_value(uint32_t address)
150 { 155 {
151 genesis_context *genesis = (genesis_context *)current_system; 156 genesis_context *genesis = (genesis_context *)current_system;
241 static void z80_next_int_pulse(z80_context * z_context) 246 static void z80_next_int_pulse(z80_context * z_context)
242 { 247 {
243 genesis_context * gen = z_context->system; 248 genesis_context * gen = z_context->system;
244 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp); 249 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
245 z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS; 250 z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS;
251 z_context->im2_vector = 0xFF;
246 } 252 }
247 253
248 static void sync_z80(z80_context * z_context, uint32_t mclks) 254 static void sync_z80(z80_context * z_context, uint32_t mclks)
249 { 255 {
250 #ifndef NO_Z80 256 #ifndef NO_Z80
305 311
306 uint32_t mclks = context->current_cycle; 312 uint32_t mclks = context->current_cycle;
307 sync_z80(z_context, mclks); 313 sync_z80(z_context, mclks);
308 sync_sound(gen, mclks); 314 sync_sound(gen, mclks);
309 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 }
310 if (v_context->frame != last_frame_num) { 321 if (v_context->frame != last_frame_num) {
311 //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);
312 last_frame_num = v_context->frame; 323 last_frame_num = v_context->frame;
313 324
314 if(exit_after){ 325 if(exit_after){
321 uint32_t deduction = mclks - ADJUST_BUFFER; 332 uint32_t deduction = mclks - ADJUST_BUFFER;
322 vdp_adjust_cycles(v_context, deduction); 333 vdp_adjust_cycles(v_context, deduction);
323 io_adjust_cycles(gen->io.ports, context->current_cycle, deduction); 334 io_adjust_cycles(gen->io.ports, context->current_cycle, deduction);
324 io_adjust_cycles(gen->io.ports+1, context->current_cycle, deduction); 335 io_adjust_cycles(gen->io.ports+1, context->current_cycle, deduction);
325 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 }
326 context->current_cycle -= deduction; 340 context->current_cycle -= deduction;
327 z80_adjust_cycles(z_context, deduction); 341 z80_adjust_cycles(z_context, deduction);
328 gen->ym->current_cycle -= deduction; 342 gen->ym->current_cycle -= deduction;
329 gen->psg->cycles -= deduction; 343 gen->psg->cycles -= deduction;
330 if (gen->ym->write_cycle != CYCLE_NEVER) { 344 if (gen->ym->write_cycle != CYCLE_NEVER) {
331 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;
332 } 349 }
333 } 350 }
334 } 351 }
335 gen->frame_end = vdp_cycles_to_frame_end(v_context); 352 gen->frame_end = vdp_cycles_to_frame_end(v_context);
336 context->sync_cycle = gen->frame_end; 353 context->sync_cycle = gen->frame_end;
342 } 359 }
343 if (!address && (gen->header.enter_debugger || gen->header.save_state)) { 360 if (!address && (gen->header.enter_debugger || gen->header.save_state)) {
344 context->sync_cycle = context->current_cycle + 1; 361 context->sync_cycle = context->current_cycle + 1;
345 } 362 }
346 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 }
347 if (address) { 367 if (address) {
348 if (gen->header.enter_debugger) { 368 if (gen->header.enter_debugger) {
349 gen->header.enter_debugger = 0; 369 gen->header.enter_debugger = 0;
350 debugger(context, address); 370 debugger(context, address);
351 } 371 }
357 while (!z_context->pc) 377 while (!z_context->pc)
358 { 378 {
359 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 379 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
360 } 380 }
361 } 381 }
362 char *save_path; 382 char *save_path = get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
363 if (slot == QUICK_SAVE_SLOT) {
364 save_path = save_state_path;
365 } else {
366 char slotname[] = "slot_0.state";
367 slotname[5] = '0' + slot;
368 if (!use_native_states) {
369 strcpy(slotname + 7, "gst");
370 }
371 char const *parts[] = {gen->header.save_dir, PATH_SEP, slotname};
372 save_path = alloc_concat_m(3, parts);
373 }
374 if (use_native_states) { 383 if (use_native_states) {
375 serialize_buffer state; 384 serialize_buffer state;
376 init_serialize(&state); 385 init_serialize(&state);
377 genesis_serialize(gen, &state, address); 386 genesis_serialize(gen, &state, address);
378 save_to_file(&state, save_path); 387 save_to_file(&state, save_path);
379 free(state.data); 388 free(state.data);
380 } else { 389 } else {
381 save_gst(gen, save_path, address); 390 save_gst(gen, save_path, address);
382 } 391 }
383 printf("Saved state to %s\n", save_path); 392 printf("Saved state to %s\n", save_path);
384 if (slot != QUICK_SAVE_SLOT) { 393 free(save_path);
385 free(save_path);
386 }
387 } else if(gen->header.save_state) { 394 } else if(gen->header.save_state) {
388 context->sync_cycle = context->current_cycle + 1; 395 context->sync_cycle = context->current_cycle + 1;
389 } 396 }
390 } 397 }
391 #ifdef REFRESH_EMULATION 398 #ifdef REFRESH_EMULATION
1006 gen->normal_clock = MCLKS_NTSC; 1013 gen->normal_clock = MCLKS_NTSC;
1007 } 1014 }
1008 gen->master_clock = gen->normal_clock; 1015 gen->master_clock = gen->normal_clock;
1009 } 1016 }
1010 1017
1011 static void handle_reset_requests(genesis_context *gen)
1012 {
1013 while (gen->reset_requested)
1014 {
1015 gen->reset_requested = 0;
1016 z80_assert_reset(gen->z80, gen->m68k->current_cycle);
1017 z80_clear_busreq(gen->z80, gen->m68k->current_cycle);
1018 ym_reset(gen->ym);
1019 //Is there any sort of VDP reset?
1020 m68k_reset(gen->m68k);
1021 }
1022 vdp_release_framebuffer(gen->vdp);
1023 }
1024
1025 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up 1018 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
1026 static uint8_t load_state(system_header *system, uint8_t slot) 1019 static uint8_t load_state(system_header *system, uint8_t slot)
1027 { 1020 {
1028 genesis_context *gen = (genesis_context *)system; 1021 genesis_context *gen = (genesis_context *)system;
1029 char numslotname[] = "slot_0.state"; 1022 char *statepath = get_slot_name(system, slot, "state");
1030 char *slotname;
1031 if (slot == QUICK_SAVE_SLOT) {
1032 slotname = "quicksave.state";
1033 } else {
1034 numslotname[5] = '0' + slot;
1035 slotname = numslotname;
1036 }
1037 char const *parts[] = {gen->header.save_dir, PATH_SEP, slotname};
1038 char *statepath = alloc_concat_m(3, parts);
1039 deserialize_buffer state; 1023 deserialize_buffer state;
1040 uint32_t pc = 0; 1024 uint32_t pc = 0;
1041 uint8_t ret; 1025 uint8_t ret;
1026 if (!gen->m68k->resume_pc) {
1027 system->delayed_load_slot = slot + 1;
1028 gen->m68k->should_return = 1;
1029 ret = get_modification_time(statepath) != 0;
1030 if (!ret) {
1031 strcpy(statepath + strlen(statepath)-strlen("state"), "gst");
1032 ret = get_modification_time(statepath) != 0;
1033 }
1034 goto done;
1035 }
1042 if (load_from_file(&state, statepath)) { 1036 if (load_from_file(&state, statepath)) {
1043 genesis_deserialize(&state, gen); 1037 genesis_deserialize(&state, gen);
1044 free(state.data); 1038 free(state.data);
1045 //HACK 1039 //HACK
1046 pc = gen->m68k->last_prefetch_address; 1040 pc = gen->m68k->last_prefetch_address;
1051 ret = pc != 0; 1045 ret = pc != 0;
1052 } 1046 }
1053 if (ret) { 1047 if (ret) {
1054 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc); 1048 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc);
1055 } 1049 }
1050 done:
1056 free(statepath); 1051 free(statepath);
1057 return ret; 1052 return ret;
1058 } 1053 }
1059 1054
1055 static void handle_reset_requests(genesis_context *gen)
1056 {
1057 while (gen->reset_requested || gen->header.delayed_load_slot)
1058 {
1059 if (gen->reset_requested) {
1060 gen->reset_requested = 0;
1061 gen->m68k->should_return = 0;
1062 z80_assert_reset(gen->z80, gen->m68k->current_cycle);
1063 z80_clear_busreq(gen->z80, gen->m68k->current_cycle);
1064 ym_reset(gen->ym);
1065 //Is there any sort of VDP reset?
1066 m68k_reset(gen->m68k);
1067 }
1068 if (gen->header.delayed_load_slot) {
1069 load_state(&gen->header, gen->header.delayed_load_slot - 1);
1070 gen->header.delayed_load_slot = 0;
1071 resume_68k(gen->m68k);
1072 }
1073 }
1074 bindings_release_capture();
1075 vdp_release_framebuffer(gen->vdp);
1076 render_pause_source(gen->ym->audio);
1077 render_pause_source(gen->psg->audio);
1078 }
1079
1060 static void start_genesis(system_header *system, char *statefile) 1080 static void start_genesis(system_header *system, char *statefile)
1061 { 1081 {
1062 genesis_context *gen = (genesis_context *)system; 1082 genesis_context *gen = (genesis_context *)system;
1063 set_keybindings(&gen->io);
1064 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1065 if (statefile) { 1083 if (statefile) {
1066 //first try loading as a native format savestate 1084 //first try loading as a native format savestate
1067 deserialize_buffer state; 1085 deserialize_buffer state;
1068 uint32_t pc; 1086 uint32_t pc;
1069 if (load_from_file(&state, statefile)) { 1087 if (load_from_file(&state, statefile)) {
1098 } 1116 }
1099 1117
1100 static void resume_genesis(system_header *system) 1118 static void resume_genesis(system_header *system)
1101 { 1119 {
1102 genesis_context *gen = (genesis_context *)system; 1120 genesis_context *gen = (genesis_context *)system;
1103 map_all_bindings(&gen->io);
1104 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1121 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1122 bindings_reacquire_capture();
1105 vdp_reacquire_framebuffer(gen->vdp); 1123 vdp_reacquire_framebuffer(gen->vdp);
1124 render_resume_source(gen->ym->audio);
1125 render_resume_source(gen->psg->audio);
1106 resume_68k(gen->m68k); 1126 resume_68k(gen->m68k);
1107 handle_reset_requests(gen); 1127 handle_reset_requests(gen);
1108 } 1128 }
1109 1129
1110 static void inc_debug_mode(system_header *system) 1130 static void inc_debug_mode(system_header *system)
1111 { 1131 {
1112 genesis_context *gen = (genesis_context *)system; 1132 genesis_context *gen = (genesis_context *)system;
1113 gen->vdp->debug++; 1133 vdp_inc_debug_mode(gen->vdp);
1114 if (gen->vdp->debug == 7) {
1115 gen->vdp->debug = 0;
1116 }
1117 }
1118
1119 static void inc_debug_pal(system_header *system)
1120 {
1121 genesis_context *gen = (genesis_context *)system;
1122 gen->vdp->debug_pal++;
1123 if (gen->vdp->debug_pal == 4) {
1124 gen->vdp->debug_pal = 0;
1125 }
1126 } 1134 }
1127 1135
1128 static void request_exit(system_header *system) 1136 static void request_exit(system_header *system)
1129 { 1137 {
1130 genesis_context *gen = (genesis_context *)system; 1138 genesis_context *gen = (genesis_context *)system;
1161 } 1169 }
1162 1170
1163 static void soft_reset(system_header *system) 1171 static void soft_reset(system_header *system)
1164 { 1172 {
1165 genesis_context *gen = (genesis_context *)system; 1173 genesis_context *gen = (genesis_context *)system;
1166 gen->m68k->should_return = 1; 1174 if (gen->reset_cycle == CYCLE_NEVER) {
1167 gen->reset_requested = 1; 1175 double random = (double)rand()/(double)RAND_MAX;
1176 gen->reset_cycle = gen->m68k->current_cycle + random * MCLKS_LINE * (gen->version_reg & HZ50 ? LINES_PAL : LINES_NTSC);
1177 if (gen->reset_cycle < gen->m68k->target_cycle) {
1178 gen->m68k->target_cycle = gen->reset_cycle;
1179 }
1180 }
1168 } 1181 }
1169 1182
1170 static void free_genesis(system_header *system) 1183 static void free_genesis(system_header *system)
1171 { 1184 {
1172 genesis_context *gen = (genesis_context *)system; 1185 genesis_context *gen = (genesis_context *)system;
1173 vdp_free(gen->vdp); 1186 vdp_free(gen->vdp);
1187 memmap_chunk *map = (memmap_chunk *)gen->m68k->options->gen.memmap;
1174 m68k_options_free(gen->m68k->options); 1188 m68k_options_free(gen->m68k->options);
1175 free(gen->cart); 1189 free(gen->cart);
1176 free(gen->m68k); 1190 free(gen->m68k);
1177 free(gen->work_ram); 1191 free(gen->work_ram);
1178 z80_options_free(gen->z80->options); 1192 z80_options_free(gen->z80->options);
1179 free(gen->z80); 1193 free(gen->z80);
1180 free(gen->zram); 1194 free(gen->zram);
1181 ym_free(gen->ym); 1195 ym_free(gen->ym);
1182 psg_free(gen->psg); 1196 psg_free(gen->psg);
1183 free(gen->save_storage);
1184 free(gen->header.save_dir); 1197 free(gen->header.save_dir);
1198 free_rom_info(&gen->header.info);
1185 free(gen->lock_on); 1199 free(gen->lock_on);
1186 free(gen); 1200 free(gen);
1201 }
1202
1203 static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t button)
1204 {
1205 genesis_context *gen = (genesis_context *)system;
1206 io_gamepad_down(&gen->io, gamepad_num, button);
1207 if (gen->mapper_type == MAPPER_JCART) {
1208 jcart_gamepad_down(gen, gamepad_num, button);
1209 }
1210 }
1211
1212 static void gamepad_up(system_header *system, uint8_t gamepad_num, uint8_t button)
1213 {
1214 genesis_context *gen = (genesis_context *)system;
1215 io_gamepad_up(&gen->io, gamepad_num, button);
1216 if (gen->mapper_type == MAPPER_JCART) {
1217 jcart_gamepad_up(gen, gamepad_num, button);
1218 }
1219 }
1220
1221 static void mouse_down(system_header *system, uint8_t mouse_num, uint8_t button)
1222 {
1223 genesis_context *gen = (genesis_context *)system;
1224 io_mouse_down(&gen->io, mouse_num, button);
1225 }
1226
1227 static void mouse_up(system_header *system, uint8_t mouse_num, uint8_t button)
1228 {
1229 genesis_context *gen = (genesis_context *)system;
1230 io_mouse_up(&gen->io, mouse_num, button);
1231 }
1232
1233 static void mouse_motion_absolute(system_header *system, uint8_t mouse_num, uint16_t x, uint16_t y)
1234 {
1235 genesis_context *gen = (genesis_context *)system;
1236 io_mouse_motion_absolute(&gen->io, mouse_num, x, y);
1237 }
1238
1239 static void mouse_motion_relative(system_header *system, uint8_t mouse_num, int32_t x, int32_t y)
1240 {
1241 genesis_context *gen = (genesis_context *)system;
1242 io_mouse_motion_relative(&gen->io, mouse_num, x, y);
1243 }
1244
1245 static void keyboard_down(system_header *system, uint8_t scancode)
1246 {
1247 genesis_context *gen = (genesis_context *)system;
1248 io_keyboard_down(&gen->io, scancode);
1249 }
1250
1251 static void keyboard_up(system_header *system, uint8_t scancode)
1252 {
1253 genesis_context *gen = (genesis_context *)system;
1254 io_keyboard_up(&gen->io, scancode);
1255 }
1256
1257 static void config_updated(system_header *system)
1258 {
1259 genesis_context *gen = (genesis_context *)system;
1260 setup_io_devices(config, &system->info, &gen->io);
1187 } 1261 }
1188 1262
1189 static genesis_context *shared_init(uint32_t system_opts, rom_info *rom, uint8_t force_region) 1263 static genesis_context *shared_init(uint32_t system_opts, rom_info *rom, uint8_t force_region)
1190 { 1264 {
1191 static memmap_chunk z80_map[] = { 1265 static memmap_chunk z80_map[] = {
1215 gen->header.soft_reset = soft_reset; 1289 gen->header.soft_reset = soft_reset;
1216 gen->header.free_context = free_genesis; 1290 gen->header.free_context = free_genesis;
1217 gen->header.get_open_bus_value = get_open_bus_value; 1291 gen->header.get_open_bus_value = get_open_bus_value;
1218 gen->header.request_exit = request_exit; 1292 gen->header.request_exit = request_exit;
1219 gen->header.inc_debug_mode = inc_debug_mode; 1293 gen->header.inc_debug_mode = inc_debug_mode;
1220 gen->header.inc_debug_pal = inc_debug_pal; 1294 gen->header.gamepad_down = gamepad_down;
1295 gen->header.gamepad_up = gamepad_up;
1296 gen->header.mouse_down = mouse_down;
1297 gen->header.mouse_up = mouse_up;
1298 gen->header.mouse_motion_absolute = mouse_motion_absolute;
1299 gen->header.mouse_motion_relative = mouse_motion_relative;
1300 gen->header.keyboard_down = keyboard_down;
1301 gen->header.keyboard_up = keyboard_up;
1302 gen->header.config_updated = config_updated;
1221 gen->header.type = SYSTEM_GENESIS; 1303 gen->header.type = SYSTEM_GENESIS;
1222 1304 gen->header.info = *rom;
1223 set_region(gen, rom, force_region); 1305 set_region(gen, rom, force_region);
1224 1306
1225 gen->vdp = malloc(sizeof(vdp_context)); 1307 gen->vdp = init_vdp_context(gen->version_reg & 0x40);
1226 init_vdp_context(gen->vdp, gen->version_reg & 0x40);
1227 gen->vdp->system = &gen->header; 1308 gen->vdp->system = &gen->header;
1228 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp); 1309 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp);
1229 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval; 1310 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval;
1230 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL; 1311 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL;
1231 gen->int_latency_prev1 = MCLKS_PER_68K * 32; 1312 gen->int_latency_prev1 = MCLKS_PER_68K * 32;
1232 gen->int_latency_prev2 = MCLKS_PER_68K * 16; 1313 gen->int_latency_prev2 = MCLKS_PER_68K * 16;
1233 1314
1234 char * lowpass_cutoff_str = tern_find_path(config, "audio\0lowpass_cutoff\0", TVAL_PTR).ptrval; 1315 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1235 uint32_t lowpass_cutoff = lowpass_cutoff_str ? atoi(lowpass_cutoff_str) : DEFAULT_LOWPASS_CUTOFF;
1236 1316
1237 gen->ym = malloc(sizeof(ym2612_context)); 1317 gen->ym = malloc(sizeof(ym2612_context));
1238 ym_init(gen->ym, render_sample_rate(), gen->master_clock, MCLKS_PER_YM, render_audio_buffer(), system_opts, lowpass_cutoff); 1318 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts);
1239 1319
1240 gen->psg = malloc(sizeof(psg_context)); 1320 gen->psg = malloc(sizeof(psg_context));
1241 psg_init(gen->psg, render_sample_rate(), gen->master_clock, MCLKS_PER_PSG, render_audio_buffer(), lowpass_cutoff); 1321 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG);
1242 1322
1243 gen->zram = calloc(1, Z80_RAM_BYTES);
1244 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); 1323 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES);
1245 #ifndef NO_Z80 1324 #ifndef NO_Z80
1246 z80_options *z_opts = malloc(sizeof(z80_options)); 1325 z80_options *z_opts = malloc(sizeof(z80_options));
1247 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF); 1326 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF);
1248 gen->z80 = init_z80_context(z_opts); 1327 gen->z80 = init_z80_context(z_opts);
1296 1375
1297 gen->cart = main_rom; 1376 gen->cart = main_rom;
1298 gen->lock_on = lock_on; 1377 gen->lock_on = lock_on;
1299 1378
1300 setup_io_devices(config, rom, &gen->io); 1379 setup_io_devices(config, rom, &gen->io);
1380 gen->header.has_keyboard = io_has_keyboard(&gen->io);
1301 gen->mapper_type = rom->mapper_type; 1381 gen->mapper_type = rom->mapper_type;
1302 gen->save_type = rom->save_type; 1382 gen->save_type = rom->save_type;
1303 if (gen->save_type != SAVE_NONE) { 1383 if (gen->save_type != SAVE_NONE) {
1304 gen->save_ram_mask = rom->save_mask; 1384 gen->save_ram_mask = rom->save_mask;
1305 gen->save_size = rom->save_size; 1385 gen->save_size = rom->save_size;
1307 gen->eeprom_map = rom->eeprom_map; 1387 gen->eeprom_map = rom->eeprom_map;
1308 gen->num_eeprom = rom->num_eeprom; 1388 gen->num_eeprom = rom->num_eeprom;
1309 if (gen->save_type == SAVE_I2C) { 1389 if (gen->save_type == SAVE_I2C) {
1310 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size); 1390 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size);
1311 } else if (gen->save_type == SAVE_NOR) { 1391 } else if (gen->save_type == SAVE_NOR) {
1312 nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus); 1392 memcpy(&gen->nor, rom->nor, sizeof(gen->nor));
1393 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus);
1313 } 1394 }
1314 } else { 1395 } else {
1315 gen->save_storage = NULL; 1396 gen->save_storage = NULL;
1316 } 1397 }
1317 1398
1361 (read_16_fun)io_read_w, (write_16_fun)io_write_w, 1442 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
1362 (read_8_fun)io_read, (write_8_fun)io_write} 1443 (read_8_fun)io_read, (write_8_fun)io_write}
1363 }; 1444 };
1364 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map); 1445 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map);
1365 1446
1366 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) 1447 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)
1367 { 1448 {
1368 tern_node *rom_db = get_rom_db(); 1449 tern_node *rom_db = get_rom_db();
1369 *info_out = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks); 1450 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
1370 rom = info_out->rom; 1451 rom = info.rom;
1371 rom_size = info_out->rom_size; 1452 rom_size = info.rom_size;
1372 #ifndef BLASTEM_BIG_ENDIAN 1453 #ifndef BLASTEM_BIG_ENDIAN
1373 byteswap_rom(rom_size, rom); 1454 byteswap_rom(rom_size, rom);
1374 if (lock_on) { 1455 if (lock_on) {
1375 byteswap_rom(lock_on_size, lock_on); 1456 byteswap_rom(lock_on_size, lock_on);
1376 } 1457 }
1377 #endif 1458 #endif
1378 return alloc_init_genesis(info_out, rom, lock_on, ym_opts, force_region); 1459 char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval;
1379 } 1460 if (!m68k_divider) {
1380 1461 m68k_divider = "7";
1381 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region, rom_info *info_out) 1462 }
1382 { 1463 MCLKS_PER_68K = atoi(m68k_divider);
1383 segacd_context *cd = alloc_configure_segacd(media, system_opts, force_region, info_out); 1464 if (!MCLKS_PER_68K) {
1384 genesis_context *gen = shared_init(system_opts, info_out, force_region); 1465 MCLKS_PER_68K = 7;
1466 }
1467 return alloc_init_genesis(&info, rom, lock_on, ym_opts, force_region);
1468 }
1469
1470 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region)
1471 {
1472 tern_node *rom_db = get_rom_db();
1473 rom_info info = configure_rom(rom_db, media->buffer, media->size, NULL, 0, base_map, base_chunks);
1474
1475 segacd_context *cd = alloc_configure_segacd(media, system_opts, force_region, &info);
1476 genesis_context *gen = shared_init(system_opts, &info, force_region);
1385 gen->cart = gen->lock_on = NULL; 1477 gen->cart = gen->lock_on = NULL;
1386 gen->save_storage = NULL; 1478 gen->save_storage = NULL;
1387 gen->save_type = SAVE_NONE; 1479 gen->save_type = SAVE_NONE;
1388 gen->version_reg &= ~NO_DISK; 1480 gen->version_reg &= ~NO_DISK;
1389 1481
1390 gen->expansion = cd; 1482 gen->expansion = cd;
1391 setup_io_devices(config, info_out, &gen->io); 1483 setup_io_devices(config, &info, &gen->io);
1392 1484
1393 uint32_t cd_chunks; 1485 uint32_t cd_chunks;
1394 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, &cd_chunks); 1486 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, &cd_chunks);
1395 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks)); 1487 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks));
1396 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks); 1488 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks);