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