comparison genesis.c @ 2053:3414a4423de1 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 15 Jan 2022 13:15:21 -0800
parents 5dacaef602a7 3748a2a8a4b7
children 8ee7ecbf3f21
comparison
equal deleted inserted replaced
1692:5dacaef602a7 2053:3414a4423de1
17 #include "debug.h" 17 #include "debug.h"
18 #include "gdb_remote.h" 18 #include "gdb_remote.h"
19 #include "saves.h" 19 #include "saves.h"
20 #include "bindings.h" 20 #include "bindings.h"
21 #include "jcart.h" 21 #include "jcart.h"
22 #include "config.h"
23 #include "event_log.h"
22 #define MCLKS_NTSC 53693175 24 #define MCLKS_NTSC 53693175
23 #define MCLKS_PAL 53203395 25 #define MCLKS_PAL 53203395
24 26
25 uint32_t MCLKS_PER_68K; 27 uint32_t MCLKS_PER_68K;
26 #define MCLKS_PER_YM 7 28 #define MCLKS_PER_YM 7
32 34
33 //TODO: Figure out the exact value for this 35 //TODO: Figure out the exact value for this
34 #define LINES_NTSC 262 36 #define LINES_NTSC 262
35 #define LINES_PAL 313 37 #define LINES_PAL 313
36 38
37 #define MAX_SOUND_CYCLES 100000 39 #ifdef IS_LIB
38 40 #define MAX_SOUND_CYCLES (MCLKS_PER_YM*NUM_OPERATORS*6*4)
39 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) 41 #else
40 { 42 #define MAX_SOUND_CYCLES 100000
41 start_section(buf, SECTION_68000); 43 #endif
42 m68k_serialize(gen->m68k, m68k_pc, buf); 44
43 end_section(buf); 45 #ifdef NEW_CORE
44 46 #define Z80_CYCLE cycles
45 start_section(buf, SECTION_Z80); 47 #define Z80_OPTS opts
46 z80_serialize(gen->z80, buf); 48 #define z80_handle_code_write(...)
47 end_section(buf); 49 #else
48 50 #define Z80_CYCLE current_cycle
51 #define Z80_OPTS options
52 #endif
53
54 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc, uint8_t all)
55 {
56 if (all) {
57 start_section(buf, SECTION_68000);
58 m68k_serialize(gen->m68k, m68k_pc, buf);
59 end_section(buf);
60
61 start_section(buf, SECTION_Z80);
62 z80_serialize(gen->z80, buf);
63 end_section(buf);
64 }
65
49 start_section(buf, SECTION_VDP); 66 start_section(buf, SECTION_VDP);
50 vdp_serialize(gen->vdp, buf); 67 vdp_serialize(gen->vdp, buf);
51 end_section(buf); 68 end_section(buf);
52 69
53 start_section(buf, SECTION_YM2612); 70 start_section(buf, SECTION_YM2612);
54 ym_serialize(gen->ym, buf); 71 ym_serialize(gen->ym, buf);
55 end_section(buf); 72 end_section(buf);
56 73
57 start_section(buf, SECTION_PSG); 74 start_section(buf, SECTION_PSG);
58 psg_serialize(gen->psg, buf); 75 psg_serialize(gen->psg, buf);
59 end_section(buf); 76 end_section(buf);
60 77
61 start_section(buf, SECTION_GEN_BUS_ARBITER); 78 if (all) {
62 save_int8(buf, gen->z80->reset); 79 start_section(buf, SECTION_GEN_BUS_ARBITER);
63 save_int8(buf, gen->z80->busreq); 80 save_int8(buf, gen->z80->reset);
64 save_int16(buf, gen->z80->bank_reg); 81 save_int8(buf, gen->z80->busreq);
65 end_section(buf); 82 save_int16(buf, gen->z80_bank_reg);
66 83 end_section(buf);
67 start_section(buf, SECTION_SEGA_IO_1); 84
68 io_serialize(gen->io.ports, buf); 85 start_section(buf, SECTION_SEGA_IO_1);
69 end_section(buf); 86 io_serialize(gen->io.ports, buf);
70 87 end_section(buf);
71 start_section(buf, SECTION_SEGA_IO_2); 88
72 io_serialize(gen->io.ports + 1, buf); 89 start_section(buf, SECTION_SEGA_IO_2);
73 end_section(buf); 90 io_serialize(gen->io.ports + 1, buf);
74 91 end_section(buf);
75 start_section(buf, SECTION_SEGA_IO_EXT); 92
76 io_serialize(gen->io.ports + 2, buf); 93 start_section(buf, SECTION_SEGA_IO_EXT);
77 end_section(buf); 94 io_serialize(gen->io.ports + 2, buf);
78 95 end_section(buf);
79 start_section(buf, SECTION_MAIN_RAM); 96
80 save_int8(buf, RAM_WORDS * 2 / 1024); 97 start_section(buf, SECTION_MAIN_RAM);
81 save_buffer16(buf, gen->work_ram, RAM_WORDS); 98 save_int8(buf, RAM_WORDS * 2 / 1024);
82 end_section(buf); 99 save_buffer16(buf, gen->work_ram, RAM_WORDS);
83 100 end_section(buf);
84 start_section(buf, SECTION_SOUND_RAM); 101
85 save_int8(buf, Z80_RAM_BYTES / 1024); 102 start_section(buf, SECTION_SOUND_RAM);
86 save_buffer8(buf, gen->zram, Z80_RAM_BYTES); 103 save_int8(buf, Z80_RAM_BYTES / 1024);
87 end_section(buf); 104 save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
88 105 end_section(buf);
89 cart_serialize(&gen->header, buf); 106
107 if (gen->version_reg & 0xF) {
108 //only save TMSS info if it's present
109 //that will allow a state saved on a model lacking TMSS
110 //to be loaded on a model that has it
111 start_section(buf, SECTION_TMSS);
112 save_int8(buf, gen->tmss);
113 save_buffer16(buf, gen->tmss_lock, 2);
114 end_section(buf);
115 }
116
117 cart_serialize(&gen->header, buf);
118 }
119 }
120
121 static uint8_t *serialize(system_header *sys, size_t *size_out)
122 {
123 genesis_context *gen = (genesis_context *)sys;
124 uint32_t address;
125 if (gen->m68k->resume_pc) {
126 gen->m68k->target_cycle = gen->m68k->current_cycle;
127 gen->header.save_state = SERIALIZE_SLOT+1;
128 resume_68k(gen->m68k);
129 if (size_out) {
130 *size_out = gen->serialize_size;
131 }
132 return gen->serialize_tmp;
133 } else {
134 serialize_buffer state;
135 init_serialize(&state);
136 uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k) << 16;
137 address |= read_word(6, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k);
138 genesis_serialize(gen, &state, address, 1);
139 if (size_out) {
140 *size_out = state.size;
141 }
142 return state.data;
143 }
90 } 144 }
91 145
92 static void ram_deserialize(deserialize_buffer *buf, void *vgen) 146 static void ram_deserialize(deserialize_buffer *buf, void *vgen)
93 { 147 {
94 genesis_context *gen = vgen; 148 genesis_context *gen = vgen;
111 z80_invalidate_code_range(gen->z80, 0, 0x4000); 165 z80_invalidate_code_range(gen->z80, 0, 0x4000);
112 } 166 }
113 167
114 static void update_z80_bank_pointer(genesis_context *gen) 168 static void update_z80_bank_pointer(genesis_context *gen)
115 { 169 {
116 if (gen->z80->bank_reg < 0x140) { 170 if (gen->z80_bank_reg < 0x140) {
117 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80->bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen); 171 gen->z80->mem_pointers[1] = get_native_pointer(gen->z80_bank_reg << 15, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen);
118 } else { 172 } else {
119 gen->z80->mem_pointers[1] = NULL; 173 gen->z80->mem_pointers[1] = NULL;
120 } 174 }
175 z80_invalidate_code_range(gen->z80, 0x8000, 0xFFFF);
121 } 176 }
122 177
123 static void bus_arbiter_deserialize(deserialize_buffer *buf, void *vgen) 178 static void bus_arbiter_deserialize(deserialize_buffer *buf, void *vgen)
124 { 179 {
125 genesis_context *gen = vgen; 180 genesis_context *gen = vgen;
126 gen->z80->reset = load_int8(buf); 181 gen->z80->reset = load_int8(buf);
127 gen->z80->busreq = load_int8(buf); 182 gen->z80->busreq = load_int8(buf);
128 gen->z80->bank_reg = load_int16(buf) & 0x1FF; 183 gen->z80_bank_reg = load_int16(buf) & 0x1FF;
184 }
185
186 static void tmss_deserialize(deserialize_buffer *buf, void *vgen)
187 {
188 genesis_context *gen = vgen;
189 gen->tmss = load_int8(buf);
190 load_buffer16(buf, gen->tmss_lock, 2);
129 } 191 }
130 192
131 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context); 193 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
194 static void check_tmss_lock(genesis_context *gen);
195 static void toggle_tmss_rom(genesis_context *gen);
132 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 196 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
133 { 197 {
134 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 198 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
135 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 199 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
136 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 200 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
141 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2); 205 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2);
142 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT); 206 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT);
143 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM); 207 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM);
144 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM); 208 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM);
145 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER); 209 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER);
210 register_section_handler(buf, (section_handler){.fun = tmss_deserialize, .data = gen}, SECTION_TMSS);
211 uint8_t tmss_old = gen->tmss;
212 gen->tmss = 0xFF;
146 while (buf->cur_pos < buf->size) 213 while (buf->cur_pos < buf->size)
147 { 214 {
148 load_section(buf); 215 load_section(buf);
149 } 216 }
217 if (gen->version_reg & 0xF) {
218 if (gen->tmss == 0xFF) {
219 //state lacked a TMSS section, assume that the game ROM is mapped in
220 //and that the VDP is unlocked
221 gen->tmss_lock[0] = 0x5345;
222 gen->tmss_lock[1] = 0x4741;
223 gen->tmss = 1;
224 }
225 if (gen->tmss != tmss_old) {
226 toggle_tmss_rom(gen);
227 }
228 check_tmss_lock(gen);
229 }
150 update_z80_bank_pointer(gen); 230 update_z80_bank_pointer(gen);
151 adjust_int_cycle(gen->m68k, gen->vdp); 231 adjust_int_cycle(gen->m68k, gen->vdp);
232 free(buf->handlers);
233 buf->handlers = NULL;
234 }
235
236 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
237 static void deserialize(system_header *sys, uint8_t *data, size_t size)
238 {
239 genesis_context *gen = (genesis_context *)sys;
240 deserialize_buffer buffer;
241 init_deserialize(&buffer, data, size);
242 genesis_deserialize(&buffer, gen);
243 //HACK: Fix this once PC/IR is represented in a better way in 68K core
244 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, gen->m68k->last_prefetch_address);
152 } 245 }
153 246
154 uint16_t read_dma_value(uint32_t address) 247 uint16_t read_dma_value(uint32_t address)
155 { 248 {
156 genesis_context *genesis = (genesis_context *)current_system; 249 genesis_context *genesis = (genesis_context *)current_system;
157 //TODO: Figure out what happens when you try to DMA from weird adresses like IO or banked Z80 area 250 //TODO: Figure out what happens when you try to DMA from weird adresses like IO or banked Z80 area
158 if ((address >= 0xA00000 && address < 0xB00000) || (address >= 0xC00000 && address <= 0xE00000)) { 251 if ((address >= 0xA00000 && address < 0xB00000) || (address >= 0xC00000 && address <= 0xE00000)) {
159 return 0; 252 return 0;
160 } 253 }
161 254
162 //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do multiply by 2 255 //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do multiply by 2
163 return read_word(address * 2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen, genesis->m68k); 256 return read_word(address * 2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen, genesis->m68k);
164 } 257 }
165 258
166 static uint16_t get_open_bus_value(system_header *system) 259 static uint16_t get_open_bus_value(system_header *system)
175 genesis_context *gen = context->system; 268 genesis_context *gen = context->system;
176 if (context->sync_cycle - context->current_cycle > gen->max_cycles) { 269 if (context->sync_cycle - context->current_cycle > gen->max_cycles) {
177 context->sync_cycle = context->current_cycle + gen->max_cycles; 270 context->sync_cycle = context->current_cycle + gen->max_cycles;
178 } 271 }
179 context->int_cycle = CYCLE_NEVER; 272 context->int_cycle = CYCLE_NEVER;
180 if ((context->status & 0x7) < 6) { 273 uint8_t mask = context->status & 0x7;
274 if (mask < 6) {
181 uint32_t next_vint = vdp_next_vint(v_context); 275 uint32_t next_vint = vdp_next_vint(v_context);
182 if (next_vint != CYCLE_NEVER) { 276 if (next_vint != CYCLE_NEVER) {
183 context->int_cycle = next_vint; 277 context->int_cycle = next_vint;
184 context->int_num = 6; 278 context->int_num = 6;
185 } 279 }
186 if ((context->status & 0x7) < 4) { 280 if (mask < 4) {
187 uint32_t next_hint = vdp_next_hint(v_context); 281 uint32_t next_hint = vdp_next_hint(v_context);
188 if (next_hint != CYCLE_NEVER) { 282 if (next_hint != CYCLE_NEVER) {
189 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint; 283 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint;
190 if (next_hint < context->int_cycle) { 284 if (next_hint < context->int_cycle) {
191 context->int_cycle = next_hint; 285 context->int_cycle = next_hint;
192 context->int_num = 4; 286 context->int_num = 4;
193 287
194 } 288 }
195 } 289 }
290 if (mask < 2 && (v_context->regs[REG_MODE_3] & BIT_EINT_EN)) {
291 uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle);
292 uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle);
293 uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle);
294 uint32_t next_eint = next_eint_port0 < next_eint_port1
295 ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2)
296 : (next_eint_port1 < next_eint_port2 ? next_eint_port1 : next_eint_port2);
297 if (next_eint != CYCLE_NEVER) {
298 next_eint = next_eint < context->current_cycle ? context->current_cycle : next_eint;
299 if (next_eint < context->int_cycle) {
300 context->int_cycle = next_eint;
301 context->int_num = 2;
302 }
303 }
304 }
196 } 305 }
197 } 306 }
198 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 307 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
199 context->int_pending = INT_PENDING_NONE; 308 context->int_pending = INT_PENDING_NONE;
200 } 309 }
201 /*if (context->int_cycle != old_int_cycle) { 310 /*if (context->int_cycle != old_int_cycle) {
202 printf("int cycle changed to: %d, level: %d @ %d(%d), frame: %d, vcounter: %d, hslot: %d, mask: %d, hint_counter: %d\n", context->int_cycle, context->int_num, v_context->cycles, context->current_cycle, v_context->frame, v_context->vcounter, v_context->hslot, context->status & 0x7, v_context->hint_counter); 311 printf("int cycle changed to: %d, level: %d @ %d(%d), frame: %d, vcounter: %d, hslot: %d, mask: %d, hint_counter: %d\n", context->int_cycle, context->int_num, v_context->cycles, context->current_cycle, v_context->frame, v_context->vcounter, v_context->hslot, context->status & 0x7, v_context->hint_counter);
203 old_int_cycle = context->int_cycle; 312 old_int_cycle = context->int_cycle;
204 }*/ 313 }*/
205 314
206 if (context->status & M68K_STATUS_TRACE || context->trace_pending) { 315 if (context->status & M68K_STATUS_TRACE || context->trace_pending) {
207 context->target_cycle = context->current_cycle; 316 context->target_cycle = context->current_cycle;
208 return; 317 return;
209 } 318 }
210 319
211 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle; 320 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle;
212 if (context->should_return) { 321 if (context->should_return || gen->header.enter_debugger) {
213 context->target_cycle = context->current_cycle; 322 context->target_cycle = context->current_cycle;
214 } else if (context->target_cycle < context->current_cycle) { 323 } else if (context->target_cycle < context->current_cycle) {
215 //Changes to SR can result in an interrupt cycle that's in the past 324 //Changes to SR can result in an interrupt cycle that's in the past
216 //This can cause issues with the implementation of STOP though 325 //This can cause issues with the implementation of STOP though
217 context->target_cycle = context->current_cycle; 326 context->target_cycle = context->current_cycle;
225 } else if ((context->target_cycle - context->current_cycle) > gen->int_latency_prev2) { 334 } else if ((context->target_cycle - context->current_cycle) > gen->int_latency_prev2) {
226 context->target_cycle = context->sync_cycle = context->int_cycle - gen->int_latency_prev2; 335 context->target_cycle = context->sync_cycle = context->int_cycle - gen->int_latency_prev2;
227 } else { 336 } else {
228 context->target_cycle = context->sync_cycle = context->current_cycle; 337 context->target_cycle = context->sync_cycle = context->current_cycle;
229 } 338 }
230 339
231 } 340 }
232 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n", 341 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n",
233 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7), 342 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7),
234 v_context->regs[REG_MODE_2] & 0x20, v_context->regs[REG_MODE_1] & 0x10, v_context->hint_counter, v_context->regs[REG_HINT], v_context->cycles / MCLKS_LINE);*/ 343 v_context->regs[REG_MODE_2] & 0x20, v_context->regs[REG_MODE_1] & 0x10, v_context->hint_counter, v_context->regs[REG_HINT], v_context->cycles / MCLKS_LINE);*/
235 } 344 }
244 #endif 353 #endif
245 354
246 static void z80_next_int_pulse(z80_context * z_context) 355 static void z80_next_int_pulse(z80_context * z_context)
247 { 356 {
248 genesis_context * gen = z_context->system; 357 genesis_context * gen = z_context->system;
358 #ifdef NEW_CORE
359 z_context->int_cycle = vdp_next_vint_z80(gen->vdp);
360 z_context->int_end_cycle = z_context->int_cycle + Z80_INT_PULSE_MCLKS;
361 z_context->int_value = 0xFF;
362 z80_sync_cycle(z_context, z_context->sync_cycle);
363 #else
249 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp); 364 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
250 z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS; 365 z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS;
251 z_context->im2_vector = 0xFF; 366 z_context->im2_vector = 0xFF;
367 #endif
252 } 368 }
253 369
254 static void sync_z80(z80_context * z_context, uint32_t mclks) 370 static void sync_z80(z80_context * z_context, uint32_t mclks)
255 { 371 {
256 #ifndef NO_Z80 372 #ifndef NO_Z80
257 if (z80_enabled) { 373 if (z80_enabled) {
374 #ifdef NEW_CORE
375 if (z_context->int_cycle == 0xFFFFFFFFU) {
376 z80_next_int_pulse(z_context);
377 }
378 #endif
258 z80_run(z_context, mclks); 379 z80_run(z_context, mclks);
259 } else 380 } else
260 #endif 381 #endif
261 { 382 {
262 z_context->current_cycle = mclks; 383 z_context->Z80_CYCLE = mclks;
263 } 384 }
264 } 385 }
265 386
266 static void sync_sound(genesis_context * gen, uint32_t target) 387 static void sync_sound(genesis_context * gen, uint32_t target)
267 { 388 {
276 psg_run(gen->psg, target); 397 psg_run(gen->psg, target);
277 ym_run(gen->ym, target); 398 ym_run(gen->ym, target);
278 399
279 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 400 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
280 } 401 }
281
282 //TODO: move this inside the system context
283 static uint32_t last_frame_num;
284 402
285 //My refresh emulation isn't currently good enough and causes more problems than it solves 403 //My refresh emulation isn't currently good enough and causes more problems than it solves
286 #define REFRESH_EMULATION 404 #define REFRESH_EMULATION
287 #ifdef REFRESH_EMULATION 405 #ifdef REFRESH_EMULATION
288 #define REFRESH_INTERVAL 128 406 #define REFRESH_INTERVAL 128
311 429
312 uint32_t mclks = context->current_cycle; 430 uint32_t mclks = context->current_cycle;
313 sync_z80(z_context, mclks); 431 sync_z80(z_context, mclks);
314 sync_sound(gen, mclks); 432 sync_sound(gen, mclks);
315 vdp_run_context(v_context, mclks); 433 vdp_run_context(v_context, mclks);
434 io_run(gen->io.ports, mclks);
435 io_run(gen->io.ports + 1, mclks);
436 io_run(gen->io.ports + 2, mclks);
316 if (mclks >= gen->reset_cycle) { 437 if (mclks >= gen->reset_cycle) {
317 gen->reset_requested = 1; 438 gen->reset_requested = 1;
318 context->should_return = 1; 439 context->should_return = 1;
319 gen->reset_cycle = CYCLE_NEVER; 440 gen->reset_cycle = CYCLE_NEVER;
320 } 441 }
321 if (v_context->frame != last_frame_num) { 442 if (v_context->frame != gen->last_frame) {
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); 443 //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", gen->last_frame, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
323 last_frame_num = v_context->frame; 444 gen->last_frame = v_context->frame;
445 event_flush(mclks);
446 gen->last_flush_cycle = mclks;
324 447
325 if(exit_after){ 448 if(exit_after){
326 --exit_after; 449 --exit_after;
327 if (!exit_after) { 450 if (!exit_after) {
328 exit(0); 451 exit(0);
337 if (gen->mapper_type == MAPPER_JCART) { 460 if (gen->mapper_type == MAPPER_JCART) {
338 jcart_adjust_cycles(gen, deduction); 461 jcart_adjust_cycles(gen, deduction);
339 } 462 }
340 context->current_cycle -= deduction; 463 context->current_cycle -= deduction;
341 z80_adjust_cycles(z_context, deduction); 464 z80_adjust_cycles(z_context, deduction);
342 gen->ym->current_cycle -= deduction; 465 ym_adjust_cycles(gen->ym, deduction);
466 if (gen->ym->vgm) {
467 vgm_adjust_cycles(gen->ym->vgm, deduction);
468 }
343 gen->psg->cycles -= deduction; 469 gen->psg->cycles -= deduction;
344 if (gen->ym->write_cycle != CYCLE_NEVER) {
345 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0;
346 }
347 if (gen->reset_cycle != CYCLE_NEVER) { 470 if (gen->reset_cycle != CYCLE_NEVER) {
348 gen->reset_cycle -= deduction; 471 gen->reset_cycle -= deduction;
349 } 472 }
350 } 473 event_cycle_adjust(mclks, deduction);
474 gen->last_flush_cycle -= deduction;
475 }
476 } else if (mclks - gen->last_flush_cycle > gen->soft_flush_cycles) {
477 event_soft_flush(mclks);
478 gen->last_flush_cycle = mclks;
351 } 479 }
352 gen->frame_end = vdp_cycles_to_frame_end(v_context); 480 gen->frame_end = vdp_cycles_to_frame_end(v_context);
353 context->sync_cycle = gen->frame_end; 481 context->sync_cycle = gen->frame_end;
354 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot); 482 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
355 if (context->int_ack) { 483 if (context->int_ack) {
365 context->target_cycle = gen->reset_cycle; 493 context->target_cycle = gen->reset_cycle;
366 } 494 }
367 if (address) { 495 if (address) {
368 if (gen->header.enter_debugger) { 496 if (gen->header.enter_debugger) {
369 gen->header.enter_debugger = 0; 497 gen->header.enter_debugger = 0;
370 debugger(context, address); 498 if (gen->header.debugger_type == DEBUGGER_NATIVE) {
371 } 499 debugger(context, address);
500 } else {
501 gdb_debug_enter(context, address);
502 }
503 }
504 #ifdef NEW_CORE
505 if (gen->header.save_state) {
506 #else
372 if (gen->header.save_state && (z_context->pc || !z_context->native_pc || z_context->reset || !z_context->busreq)) { 507 if (gen->header.save_state && (z_context->pc || !z_context->native_pc || z_context->reset || !z_context->busreq)) {
508 #endif
373 uint8_t slot = gen->header.save_state - 1; 509 uint8_t slot = gen->header.save_state - 1;
374 gen->header.save_state = 0; 510 gen->header.save_state = 0;
511 #ifndef NEW_CORE
375 if (z_context->native_pc && !z_context->reset) { 512 if (z_context->native_pc && !z_context->reset) {
376 //advance Z80 core to the start of an instruction 513 //advance Z80 core to the start of an instruction
377 while (!z_context->pc) 514 while (!z_context->pc)
378 { 515 {
379 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 516 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
380 } 517 }
381 } 518 }
382 char *save_path = get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst"); 519 #endif
383 if (use_native_states) { 520 char *save_path = slot >= SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
521 if (use_native_states || slot >= SERIALIZE_SLOT) {
384 serialize_buffer state; 522 serialize_buffer state;
385 init_serialize(&state); 523 init_serialize(&state);
386 genesis_serialize(gen, &state, address); 524 genesis_serialize(gen, &state, address, slot != EVENTLOG_SLOT);
387 save_to_file(&state, save_path); 525 if (slot == SERIALIZE_SLOT) {
388 free(state.data); 526 gen->serialize_tmp = state.data;
527 gen->serialize_size = state.size;
528 context->sync_cycle = context->current_cycle;
529 context->should_return = 1;
530 } else if (slot == EVENTLOG_SLOT) {
531 event_state(context->current_cycle, &state);
532 } else {
533 save_to_file(&state, save_path);
534 free(state.data);
535 }
389 } else { 536 } else {
390 save_gst(gen, save_path, address); 537 save_gst(gen, save_path, address);
391 } 538 }
392 printf("Saved state to %s\n", save_path); 539 if (slot != SERIALIZE_SLOT) {
540 debug_message("Saved state to %s\n", save_path);
541 }
393 free(save_path); 542 free(save_path);
394 } else if(gen->header.save_state) { 543 } else if(gen->header.save_state) {
395 context->sync_cycle = context->current_cycle + 1; 544 context->sync_cycle = context->current_cycle + 1;
396 } 545 }
397 } 546 }
403 552
404 static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value) 553 static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value)
405 { 554 {
406 if (vdp_port & 0x2700E0) { 555 if (vdp_port & 0x2700E0) {
407 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port); 556 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port);
557 }
558 genesis_context * gen = context->system;
559 if (!gen->vdp_unlocked) {
560 fatal_error("machine freeze due to VDP write to %X without TMSS unlock\n", 0xC00000 | vdp_port);
408 } 561 }
409 vdp_port &= 0x1F; 562 vdp_port &= 0x1F;
410 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); 563 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle);
411 #ifdef REFRESH_EMULATION 564 #ifdef REFRESH_EMULATION
412 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 565 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
414 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 567 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
415 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 568 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
416 last_sync_cycle = context->current_cycle; 569 last_sync_cycle = context->current_cycle;
417 #endif 570 #endif
418 sync_components(context, 0); 571 sync_components(context, 0);
419 genesis_context * gen = context->system;
420 vdp_context *v_context = gen->vdp; 572 vdp_context *v_context = gen->vdp;
421 uint32_t before_cycle = v_context->cycles; 573 uint32_t before_cycle = v_context->cycles;
422 if (vdp_port < 0x10) { 574 if (vdp_port < 0x10) {
423 int blocked; 575 int blocked;
424 if (vdp_port < 4) { 576 if (vdp_port < 4) {
457 gen->bus_busy = 1; 609 gen->bus_busy = 1;
458 sync_components(context, 0); 610 sync_components(context, 0);
459 gen->bus_busy = 0; 611 gen->bus_busy = 0;
460 } 612 }
461 } 613 }
462 614
463 if (blocked < 0) { 615 if (blocked < 0) {
464 blocked = vdp_control_port_write(v_context, value); 616 blocked = vdp_control_port_write(v_context, value);
465 } else { 617 } else {
466 blocked = 0; 618 blocked = 0;
467 } 619 }
491 psg_write(gen->psg, value); 643 psg_write(gen->psg, value);
492 } else { 644 } else {
493 vdp_test_port_write(gen->vdp, value); 645 vdp_test_port_write(gen->vdp, value);
494 } 646 }
495 #ifdef REFRESH_EMULATION 647 #ifdef REFRESH_EMULATION
496 last_sync_cycle -= 4; 648 last_sync_cycle -= 4 * MCLKS_PER_68K;
497 //refresh may have happened while we were waiting on the VDP, 649 //refresh may have happened while we were waiting on the VDP,
498 //so advance refresh_counter but don't add any delays 650 //so advance refresh_counter but don't add any delays
499 if (vdp_port >= 4 && vdp_port < 8 && v_context->cycles != before_cycle) { 651 if (vdp_port >= 4 && vdp_port < 8 && v_context->cycles != before_cycle) {
500 refresh_counter = 0; 652 refresh_counter = 0;
501 } else { 653 } else {
521 fatal_error("machine freeze due to write to Z80 address %X\n", 0x7F00 | vdp_port); 673 fatal_error("machine freeze due to write to Z80 address %X\n", 0x7F00 | vdp_port);
522 } 674 }
523 if (vdp_port < 0x10) { 675 if (vdp_port < 0x10) {
524 //These probably won't currently interact well with the 68K accessing the VDP 676 //These probably won't currently interact well with the 68K accessing the VDP
525 if (vdp_port < 4) { 677 if (vdp_port < 4) {
526 vdp_run_context(gen->vdp, context->current_cycle); 678 vdp_run_context(gen->vdp, context->Z80_CYCLE);
527 vdp_data_port_write(gen->vdp, value << 8 | value); 679 vdp_data_port_write(gen->vdp, value << 8 | value);
528 } else if (vdp_port < 8) { 680 } else if (vdp_port < 8) {
529 vdp_run_context_full(gen->vdp, context->current_cycle); 681 vdp_run_context_full(gen->vdp, context->Z80_CYCLE);
530 vdp_control_port_write(gen->vdp, value << 8 | value); 682 vdp_control_port_write(gen->vdp, value << 8 | value);
531 } else { 683 } else {
532 fatal_error("Illegal write to HV Counter port %X\n", vdp_port); 684 fatal_error("Illegal write to HV Counter port %X\n", vdp_port);
533 } 685 }
534 } else if (vdp_port < 0x18) { 686 } else if (vdp_port < 0x18) {
535 sync_sound(gen, context->current_cycle); 687 sync_sound(gen, context->Z80_CYCLE);
536 psg_write(gen->psg, value); 688 psg_write(gen->psg, value);
537 } else { 689 } else {
538 vdp_test_port_write(gen->vdp, value); 690 vdp_test_port_write(gen->vdp, value);
539 } 691 }
540 return context; 692 return context;
542 694
543 static uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context) 695 static uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context)
544 { 696 {
545 if (vdp_port & 0x2700E0) { 697 if (vdp_port & 0x2700E0) {
546 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port); 698 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port);
699 }
700 genesis_context *gen = context->system;
701 if (!gen->vdp_unlocked) {
702 fatal_error("machine freeze due to VDP read from %X without TMSS unlock\n", 0xC00000 | vdp_port);
547 } 703 }
548 vdp_port &= 0x1F; 704 vdp_port &= 0x1F;
549 uint16_t value; 705 uint16_t value;
550 #ifdef REFRESH_EMULATION 706 #ifdef REFRESH_EMULATION
551 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 707 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
553 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 709 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
554 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 710 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
555 last_sync_cycle = context->current_cycle; 711 last_sync_cycle = context->current_cycle;
556 #endif 712 #endif
557 sync_components(context, 0); 713 sync_components(context, 0);
558 genesis_context *gen = context->system;
559 vdp_context * v_context = gen->vdp; 714 vdp_context * v_context = gen->vdp;
560 uint32_t before_cycle = v_context->cycles; 715 uint32_t before_cycle = v_context->cycles;
561 if (vdp_port < 0x10) { 716 if (vdp_port < 0x10) {
562 if (vdp_port < 4) { 717 if (vdp_port < 4) {
563 value = vdp_data_port_read(v_context); 718 value = vdp_data_port_read(v_context);
568 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); 723 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles);
569 } 724 }
570 } else if (vdp_port < 0x18){ 725 } else if (vdp_port < 0x18){
571 fatal_error("Illegal read from PSG port %X\n", vdp_port); 726 fatal_error("Illegal read from PSG port %X\n", vdp_port);
572 } else { 727 } else {
573 value = vdp_test_port_read(v_context); 728 value = get_open_bus_value(&gen->header);
574 } 729 }
575 if (v_context->cycles != before_cycle) { 730 if (v_context->cycles != before_cycle) {
576 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle); 731 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle);
577 context->current_cycle = v_context->cycles; 732 context->current_cycle = v_context->cycles;
578 //Lock the Z80 out of the bus until the VDP access is complete 733 //Lock the Z80 out of the bus until the VDP access is complete
580 gen->bus_busy = 1; 735 gen->bus_busy = 1;
581 sync_z80(gen->z80, v_context->cycles); 736 sync_z80(gen->z80, v_context->cycles);
582 gen->bus_busy = 0; 737 gen->bus_busy = 0;
583 } 738 }
584 #ifdef REFRESH_EMULATION 739 #ifdef REFRESH_EMULATION
585 last_sync_cycle -= 4; 740 last_sync_cycle -= 4 * MCLKS_PER_68K;
586 //refresh may have happened while we were waiting on the VDP, 741 //refresh may have happened while we were waiting on the VDP,
587 //so advance refresh_counter but don't add any delays 742 //so advance refresh_counter but don't add any delays
588 refresh_counter += (context->current_cycle - last_sync_cycle); 743 refresh_counter += (context->current_cycle - last_sync_cycle);
589 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 744 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
590 last_sync_cycle = context->current_cycle; 745 last_sync_cycle = context->current_cycle;
609 fatal_error("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port); 764 fatal_error("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port);
610 } 765 }
611 genesis_context * gen = context->system; 766 genesis_context * gen = context->system;
612 //VDP access goes over the 68K bus like a bank area access 767 //VDP access goes over the 68K bus like a bank area access
613 //typical delay from bus arbitration 768 //typical delay from bus arbitration
614 context->current_cycle += 3 * MCLKS_PER_Z80; 769 context->Z80_CYCLE += 3 * MCLKS_PER_Z80;
615 //TODO: add cycle for an access right after a previous one 770 //TODO: add cycle for an access right after a previous one
616 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high 771 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high
617 // Needs a new logic analyzer capture to get the actual delay on the 68K side 772 // Needs a new logic analyzer capture to get the actual delay on the 68K side
618 gen->m68k->current_cycle += 8 * MCLKS_PER_68K; 773 gen->m68k->current_cycle += 8 * MCLKS_PER_68K;
619 774
620 775
621 vdp_port &= 0x1F; 776 vdp_port &= 0x1F;
622 uint16_t ret; 777 uint16_t ret;
623 if (vdp_port < 0x10) { 778 if (vdp_port < 0x10) {
624 //These probably won't currently interact well with the 68K accessing the VDP 779 //These probably won't currently interact well with the 68K accessing the VDP
625 vdp_run_context(gen->vdp, context->current_cycle); 780 vdp_run_context(gen->vdp, context->Z80_CYCLE);
626 if (vdp_port < 4) { 781 if (vdp_port < 4) {
627 ret = vdp_data_port_read(gen->vdp); 782 ret = vdp_data_port_read(gen->vdp);
628 } else if (vdp_port < 8) { 783 } else if (vdp_port < 8) {
629 ret = vdp_control_port_read(gen->vdp); 784 ret = vdp_control_port_read(gen->vdp);
630 } else { 785 } else {
641 static uint32_t zram_counter = 0; 796 static uint32_t zram_counter = 0;
642 797
643 static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 798 static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
644 { 799 {
645 genesis_context * gen = context->system; 800 genesis_context * gen = context->system;
801 #ifdef REFRESH_EMULATION
802 //do refresh check here so we can avoid adding a penalty for a refresh that happens during an IO area access
803 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
804 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
805 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
806 last_sync_cycle = context->current_cycle - 4*MCLKS_PER_68K;
807 #endif
646 if (location < 0x10000) { 808 if (location < 0x10000) {
647 //Access to Z80 memory incurs a one 68K cycle wait state 809 //Access to Z80 memory incurs a one 68K cycle wait state
648 context->current_cycle += MCLKS_PER_68K; 810 context->current_cycle += MCLKS_PER_68K;
649 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) { 811 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
650 location &= 0x7FFF; 812 location &= 0x7FFF;
661 ym_address_write_part2(gen->ym, value); 823 ym_address_write_part2(gen->ym, value);
662 } else { 824 } else {
663 ym_address_write_part1(gen->ym, value); 825 ym_address_write_part1(gen->ym, value);
664 } 826 }
665 } else if (location == 0x6000) { 827 } else if (location == 0x6000) {
666 gen->z80->bank_reg = (gen->z80->bank_reg >> 1 | value << 8) & 0x1FF; 828 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF;
667 if (gen->z80->bank_reg < 0x80) { 829 if (gen->z80_bank_reg < 0x80) {
668 gen->z80->mem_pointers[1] = (gen->z80->bank_reg << 15) + ((char *)gen->z80->mem_pointers[2]); 830 gen->z80->mem_pointers[1] = (gen->z80_bank_reg << 15) + ((char *)gen->z80->mem_pointers[2]);
669 } else { 831 } else {
670 gen->z80->mem_pointers[1] = NULL; 832 gen->z80->mem_pointers[1] = NULL;
671 } 833 }
672 } else { 834 } else {
673 fatal_error("68K write to unhandled Z80 address %X\n", location); 835 fatal_error("68K write to unhandled Z80 address %X\n", location);
674 } 836 }
675 } 837 }
676 } else { 838 } else {
677 location &= 0x1FFF; 839 if (location < 0x10100) {
678 if (location < 0x100) { 840 switch(location >> 1 & 0xFF)
679 switch(location/2)
680 { 841 {
681 case 0x1: 842 case 0x1:
682 io_data_write(gen->io.ports, value, context->current_cycle); 843 io_data_write(gen->io.ports, value, context->current_cycle);
683 break; 844 break;
684 case 0x2: 845 case 0x2:
695 break; 856 break;
696 case 0x6: 857 case 0x6:
697 io_control_write(gen->io.ports+2, value, context->current_cycle); 858 io_control_write(gen->io.ports+2, value, context->current_cycle);
698 break; 859 break;
699 case 0x7: 860 case 0x7:
700 gen->io.ports[0].serial_out = value; 861 io_tx_write(gen->io.ports, value, context->current_cycle);
701 break; 862 break;
702 case 0x8: 863 case 0x8:
703 case 0xB: 864 case 0xB:
704 case 0xE: 865 case 0xE:
705 //serial input port is not writeable 866 //serial input port is not writeable
706 break; 867 break;
707 case 0x9: 868 case 0x9:
869 io_sctrl_write(gen->io.ports, value, context->current_cycle);
708 gen->io.ports[0].serial_ctrl = value; 870 gen->io.ports[0].serial_ctrl = value;
709 break; 871 break;
710 case 0xA: 872 case 0xA:
711 gen->io.ports[1].serial_out = value; 873 io_tx_write(gen->io.ports + 1, value, context->current_cycle);
712 break; 874 break;
713 case 0xC: 875 case 0xC:
714 gen->io.ports[1].serial_ctrl = value; 876 io_sctrl_write(gen->io.ports + 1, value, context->current_cycle);
715 break; 877 break;
716 case 0xD: 878 case 0xD:
717 gen->io.ports[2].serial_out = value; 879 io_tx_write(gen->io.ports + 2, value, context->current_cycle);
718 break; 880 break;
719 case 0xF: 881 case 0xF:
720 gen->io.ports[2].serial_ctrl = value; 882 io_sctrl_write(gen->io.ports + 2, value, context->current_cycle);
721 break; 883 break;
722 } 884 }
723 } else { 885 } else {
724 if (location == 0x1100) { 886 uint32_t masked = location & 0xFFF00;
887 if (masked == 0x11100) {
725 if (value & 1) { 888 if (value & 1) {
726 dputs("bus requesting Z80"); 889 dputs("bus requesting Z80");
727 if (z80_enabled) { 890 if (z80_enabled) {
728 z80_assert_busreq(gen->z80, context->current_cycle); 891 z80_assert_busreq(gen->z80, context->current_cycle);
729 } else { 892 } else {
744 z80_clear_busreq(gen->z80, context->current_cycle); 907 z80_clear_busreq(gen->z80, context->current_cycle);
745 } else { 908 } else {
746 gen->z80->busack = 0; 909 gen->z80->busack = 0;
747 } 910 }
748 } 911 }
749 } else if (location == 0x1200) { 912 } else if (masked == 0x11200) {
750 sync_z80(gen->z80, context->current_cycle); 913 sync_z80(gen->z80, context->current_cycle);
751 if (value & 1) { 914 if (value & 1) {
752 if (z80_enabled) { 915 if (z80_enabled) {
753 z80_clear_reset(gen->z80, context->current_cycle); 916 z80_clear_reset(gen->z80, context->current_cycle);
754 } else { 917 } else {
760 } else { 923 } else {
761 gen->z80->reset = 1; 924 gen->z80->reset = 1;
762 } 925 }
763 ym_reset(gen->ym); 926 ym_reset(gen->ym);
764 } 927 }
765 } 928 } else if (masked != 0x11300 && masked != 0x11000) {
766 } 929 fatal_error("Machine freeze due to unmapped write to address %X\n", location | 0xA00000);
767 } 930 }
931 }
932 }
933 #ifdef REFRESH_EMULATION
934 //no refresh delays during IO access
935 refresh_counter += context->current_cycle - last_sync_cycle;
936 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
937 #endif
768 return context; 938 return context;
769 } 939 }
770 940
771 static m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value) 941 static m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value)
772 { 942 {
786 956
787 static uint8_t io_read(uint32_t location, m68k_context * context) 957 static uint8_t io_read(uint32_t location, m68k_context * context)
788 { 958 {
789 uint8_t value; 959 uint8_t value;
790 genesis_context *gen = context->system; 960 genesis_context *gen = context->system;
961 #ifdef REFRESH_EMULATION
962 //do refresh check here so we can avoid adding a penalty for a refresh that happens during an IO area access
963 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
964 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
965 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
966 last_sync_cycle = context->current_cycle - 4*MCLKS_PER_68K;
967 #endif
791 if (location < 0x10000) { 968 if (location < 0x10000) {
792 //Access to Z80 memory incurs a one 68K cycle wait state 969 //Access to Z80 memory incurs a one 68K cycle wait state
793 context->current_cycle += MCLKS_PER_68K; 970 context->current_cycle += MCLKS_PER_68K;
794 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) { 971 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
795 location &= 0x7FFF; 972 location &= 0x7FFF;
796 if (location < 0x4000) { 973 if (location < 0x4000) {
797 value = gen->zram[location & 0x1FFF]; 974 value = gen->zram[location & 0x1FFF];
798 } else if (location < 0x6000) { 975 } else if (location < 0x6000) {
799 sync_sound(gen, context->current_cycle); 976 sync_sound(gen, context->current_cycle);
800 value = ym_read_status(gen->ym); 977 value = ym_read_status(gen->ym, context->current_cycle, location);
978 } else if (location < 0x7F00) {
979 value = 0xFF;
801 } else { 980 } else {
981 fatal_error("Machine freeze due to read of Z80 VDP memory window by 68K: %X\n", location | 0xA00000);
802 value = 0xFF; 982 value = 0xFF;
803 } 983 }
804 } else { 984 } else {
805 value = 0xFF; 985 uint16_t word = get_open_bus_value(&gen->header);
806 } 986 value = location & 1 ? word : word >> 8;
807 } else { 987 }
808 location &= 0x1FFF; 988 } else {
809 if (location < 0x100) { 989 if (location < 0x10100) {
810 switch(location/2) 990 switch(location >> 1 & 0xFF)
811 { 991 {
812 case 0x0: 992 case 0x0:
813 //version bits should be 0 for now since we're not emulating TMSS 993 //version bits should be 0 for now since we're not emulating TMSS
814 value = gen->version_reg; 994 value = gen->version_reg;
815 break; 995 break;
833 break; 1013 break;
834 case 0x7: 1014 case 0x7:
835 value = gen->io.ports[0].serial_out; 1015 value = gen->io.ports[0].serial_out;
836 break; 1016 break;
837 case 0x8: 1017 case 0x8:
838 value = gen->io.ports[0].serial_in; 1018 value = io_rx_read(gen->io.ports, context->current_cycle);
839 break; 1019 break;
840 case 0x9: 1020 case 0x9:
841 value = gen->io.ports[0].serial_ctrl; 1021 value = io_sctrl_read(gen->io.ports, context->current_cycle);
842 break; 1022 break;
843 case 0xA: 1023 case 0xA:
844 value = gen->io.ports[1].serial_out; 1024 value = gen->io.ports[1].serial_out;
845 break; 1025 break;
846 case 0xB: 1026 case 0xB:
847 value = gen->io.ports[1].serial_in; 1027 value = io_rx_read(gen->io.ports + 1, context->current_cycle);
848 break; 1028 break;
849 case 0xC: 1029 case 0xC:
850 value = gen->io.ports[1].serial_ctrl; 1030 value = io_sctrl_read(gen->io.ports, context->current_cycle);
851 break; 1031 break;
852 case 0xD: 1032 case 0xD:
853 value = gen->io.ports[2].serial_out; 1033 value = gen->io.ports[2].serial_out;
854 break; 1034 break;
855 case 0xE: 1035 case 0xE:
856 value = gen->io.ports[2].serial_in; 1036 value = io_rx_read(gen->io.ports + 1, context->current_cycle);
857 break; 1037 break;
858 case 0xF: 1038 case 0xF:
859 value = gen->io.ports[2].serial_ctrl; 1039 value = io_sctrl_read(gen->io.ports, context->current_cycle);
860 break; 1040 break;
861 default: 1041 default:
862 value = 0xFF; 1042 value = get_open_bus_value(&gen->header) >> 8;
863 } 1043 }
864 } else { 1044 } else {
865 if (location == 0x1100) { 1045 uint32_t masked = location & 0xFFF00;
1046 if (masked == 0x11100) {
866 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack; 1047 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack;
867 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE; 1048 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE;
868 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset); 1049 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset);
869 } else if (location == 0x1200) { 1050 } else if (masked == 0x11200) {
870 value = !gen->z80->reset; 1051 value = !gen->z80->reset;
1052 } else if (masked == 0x11300 || masked == 0x11000) {
1053 //A11300 is apparently completely unused
1054 //A11000 is the memory control register which I am assuming is write only
1055 value = get_open_bus_value(&gen->header) >> 8;
871 } else { 1056 } else {
1057 location |= 0xA00000;
1058 fatal_error("Machine freeze due to read of unmapped IO location %X\n", location);
872 value = 0xFF; 1059 value = 0xFF;
873 printf("Byte read of unknown IO location: %X\n", location); 1060 }
874 } 1061 }
875 } 1062 }
876 } 1063 #ifdef REFRESH_EMULATION
1064 //no refresh delays during IO access
1065 refresh_counter += context->current_cycle - last_sync_cycle;
1066 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
1067 #endif
877 return value; 1068 return value;
878 } 1069 }
879 1070
880 static uint16_t io_read_w(uint32_t location, m68k_context * context) 1071 static uint16_t io_read_w(uint32_t location, m68k_context * context)
881 { 1072 {
892 1083
893 static void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value) 1084 static void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value)
894 { 1085 {
895 z80_context * context = vcontext; 1086 z80_context * context = vcontext;
896 genesis_context * gen = context->system; 1087 genesis_context * gen = context->system;
897 sync_sound(gen, context->current_cycle); 1088 sync_sound(gen, context->Z80_CYCLE);
898 if (location & 1) { 1089 if (location & 1) {
899 ym_data_write(gen->ym, value); 1090 ym_data_write(gen->ym, value);
900 } else if (location & 2) { 1091 } else if (location & 2) {
901 ym_address_write_part2(gen->ym, value); 1092 ym_address_write_part2(gen->ym, value);
902 } else { 1093 } else {
907 1098
908 static uint8_t z80_read_ym(uint32_t location, void * vcontext) 1099 static uint8_t z80_read_ym(uint32_t location, void * vcontext)
909 { 1100 {
910 z80_context * context = vcontext; 1101 z80_context * context = vcontext;
911 genesis_context * gen = context->system; 1102 genesis_context * gen = context->system;
912 sync_sound(gen, context->current_cycle); 1103 sync_sound(gen, context->Z80_CYCLE);
913 return ym_read_status(gen->ym); 1104 return ym_read_status(gen->ym, context->Z80_CYCLE, location);
914 } 1105 }
915 1106
916 static uint8_t z80_read_bank(uint32_t location, void * vcontext) 1107 static uint8_t z80_read_bank(uint32_t location, void * vcontext)
917 { 1108 {
918 z80_context * context = vcontext; 1109 z80_context * context = vcontext;
919 genesis_context *gen = context->system; 1110 genesis_context *gen = context->system;
920 if (gen->bus_busy) { 1111 if (gen->bus_busy) {
921 context->current_cycle = context->sync_cycle; 1112 context->Z80_CYCLE = gen->m68k->current_cycle;
922 } 1113 }
923 //typical delay from bus arbitration 1114 //typical delay from bus arbitration
924 context->current_cycle += 3 * MCLKS_PER_Z80; 1115 context->Z80_CYCLE += 3 * MCLKS_PER_Z80;
925 //TODO: add cycle for an access right after a previous one 1116 //TODO: add cycle for an access right after a previous one
926 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high 1117 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high
927 // Needs a new logic analyzer capture to get the actual delay on the 68K side 1118 // Needs a new logic analyzer capture to get the actual delay on the 68K side
928 gen->m68k->current_cycle += 8 * MCLKS_PER_68K; 1119 gen->m68k->current_cycle += 8 * MCLKS_PER_68K;
929 1120
930 location &= 0x7FFF; 1121 location &= 0x7FFF;
931 if (context->mem_pointers[1]) { 1122 if (context->mem_pointers[1]) {
932 return context->mem_pointers[1][location ^ 1]; 1123 return context->mem_pointers[1][location ^ 1];
933 } 1124 }
934 uint32_t address = context->bank_reg << 15 | location; 1125 uint32_t address = gen->z80_bank_reg << 15 | location;
935 if (address >= 0xC00000 && address < 0xE00000) { 1126 if (address >= 0xC00000 && address < 0xE00000) {
936 return z80_vdp_port_read(location & 0xFF, context); 1127 return z80_vdp_port_read(location & 0xFF, context);
937 } else { 1128 } else if (address >= 0xA10000 && address <= 0xA10001) {
938 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, context->bank_reg << 15); 1129 //Apparently version reg can be read through Z80 banked area
1130 //TODO: Check rest of IO region addresses
1131 return gen->version_reg;
1132 } else {
1133 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, gen->z80_bank_reg << 15);
939 } 1134 }
940 return 0; 1135 return 0;
941 } 1136 }
942 1137
943 static void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value) 1138 static void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value)
944 { 1139 {
945 z80_context * context = vcontext; 1140 z80_context * context = vcontext;
946 genesis_context *gen = context->system; 1141 genesis_context *gen = context->system;
947 if (gen->bus_busy) { 1142 if (gen->bus_busy) {
948 context->current_cycle = context->sync_cycle; 1143 context->Z80_CYCLE = gen->m68k->current_cycle;
949 } 1144 }
950 //typical delay from bus arbitration 1145 //typical delay from bus arbitration
951 context->current_cycle += 3 * MCLKS_PER_Z80; 1146 context->Z80_CYCLE += 3 * MCLKS_PER_Z80;
952 //TODO: add cycle for an access right after a previous one 1147 //TODO: add cycle for an access right after a previous one
953 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high 1148 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high
954 // Needs a new logic analyzer capture to get the actual delay on the 68K side 1149 // Needs a new logic analyzer capture to get the actual delay on the 68K side
955 gen->m68k->current_cycle += 8 * MCLKS_PER_68K; 1150 gen->m68k->current_cycle += 8 * MCLKS_PER_68K;
956 1151
957 location &= 0x7FFF; 1152 location &= 0x7FFF;
958 uint32_t address = context->bank_reg << 15 | location; 1153 uint32_t address = gen->z80_bank_reg << 15 | location;
959 if (address >= 0xE00000) { 1154 if (address >= 0xE00000) {
960 address &= 0xFFFF; 1155 address &= 0xFFFF;
961 ((uint8_t *)gen->work_ram)[address ^ 1] = value; 1156 ((uint8_t *)gen->work_ram)[address ^ 1] = value;
962 } else if (address >= 0xC00000) { 1157 } else if (address >= 0xC00000) {
963 z80_vdp_port_write(location & 0xFF, context, value); 1158 z80_vdp_port_write(location & 0xFF, context, value);
968 } 1163 }
969 1164
970 static void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value) 1165 static void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value)
971 { 1166 {
972 z80_context * context = vcontext; 1167 z80_context * context = vcontext;
973 1168 genesis_context *gen = context->system;
974 context->bank_reg = (context->bank_reg >> 1 | value << 8) & 0x1FF; 1169
1170 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF;
975 update_z80_bank_pointer(context->system); 1171 update_z80_bank_pointer(context->system);
976 1172
977 return context; 1173 return context;
1174 }
1175
1176 static uint16_t unused_read(uint32_t location, void *vcontext)
1177 {
1178 m68k_context *context = vcontext;
1179 genesis_context *gen = context->system;
1180 if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1181 //Only called if the cart/exp doesn't have a more specific handler for this region
1182 return get_open_bus_value(&gen->header);
1183 } else if (location == 0xA14000 || location == 0xA14002) {
1184 if (gen->version_reg & 0xF) {
1185 return gen->tmss_lock[location >> 1 & 1];
1186 } else {
1187 fatal_error("Machine freeze due to read from TMSS lock when TMSS is not present %X\n", location);
1188 return 0xFFFF;
1189 }
1190 } else if (location == 0xA14100) {
1191 if (gen->version_reg & 0xF) {
1192 return get_open_bus_value(&gen->header);
1193 } else {
1194 fatal_error("Machine freeze due to read from TMSS control when TMSS is not present %X\n", location);
1195 return 0xFFFF;
1196 }
1197 } else {
1198 fatal_error("Machine freeze due to unmapped read from %X\n", location);
1199 return 0xFFFF;
1200 }
1201 }
1202
1203 static uint8_t unused_read_b(uint32_t location, void *vcontext)
1204 {
1205 uint16_t v = unused_read(location & 0xFFFFFE, vcontext);
1206 if (location & 1) {
1207 return v;
1208 } else {
1209 return v >> 8;
1210 }
1211 }
1212
1213 static void check_tmss_lock(genesis_context *gen)
1214 {
1215 gen->vdp_unlocked = gen->tmss_lock[0] == 0x5345 && gen->tmss_lock[1] == 0x4741;
1216 }
1217
1218 static void toggle_tmss_rom(genesis_context *gen)
1219 {
1220 m68k_context *context = gen->m68k;
1221 for (int i = 0; i < NUM_MEM_AREAS; i++)
1222 {
1223 uint16_t *tmp = context->mem_pointers[i];
1224 context->mem_pointers[i] = gen->tmss_pointers[i];
1225 gen->tmss_pointers[i] = tmp;
1226 }
1227 m68k_invalidate_code_range(context, 0, 0x400000);
1228 }
1229
1230 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
1231 {
1232 m68k_context *context = vcontext;
1233 genesis_context *gen = context->system;
1234 uint8_t has_tmss = gen->version_reg & 0xF;
1235 if (has_tmss && (location == 0xA14000 || location == 0xA14002)) {
1236 gen->tmss_lock[location >> 1 & 1] = value;
1237 check_tmss_lock(gen);
1238 } else if (has_tmss && location == 0xA14100) {
1239 value &= 1;
1240 if (gen->tmss != value) {
1241 gen->tmss = value;
1242 toggle_tmss_rom(gen);
1243 }
1244 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1245 //these writes are ignored when no relevant hardware is present
1246 } else {
1247 fatal_error("Machine freeze due to unmapped write to %X\n", location);
1248 }
1249 return vcontext;
1250 }
1251
1252 static void *unused_write_b(uint32_t location, void *vcontext, uint8_t value)
1253 {
1254 m68k_context *context = vcontext;
1255 genesis_context *gen = context->system;
1256 uint8_t has_tmss = gen->version_reg & 0xF;
1257 if (has_tmss && location >= 0xA14000 && location <= 0xA14003) {
1258 uint32_t offset = location >> 1 & 1;
1259 if (location & 1) {
1260 gen->tmss_lock[offset] &= 0xFF00;
1261 gen->tmss_lock[offset] |= value;
1262 } else {
1263 gen->tmss_lock[offset] &= 0xFF;
1264 gen->tmss_lock[offset] |= value << 8;
1265 }
1266 check_tmss_lock(gen);
1267 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
1268 if (location & 1) {
1269 value &= 1;
1270 if (gen->tmss != value) {
1271 gen->tmss = value;
1272 toggle_tmss_rom(gen);
1273 }
1274 }
1275 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1276 //these writes are ignored when no relevant hardware is present
1277 } else {
1278 fatal_error("Machine freeze due to unmapped byte write to %X\n", location);
1279 }
1280 return vcontext;
978 } 1281 }
979 1282
980 static void set_speed_percent(system_header * system, uint32_t percent) 1283 static void set_speed_percent(system_header * system, uint32_t percent)
981 { 1284 {
982 genesis_context *context = (genesis_context *)system; 1285 genesis_context *context = (genesis_context *)system;
1004 } else if (region & REGION_J) { 1307 } else if (region & REGION_J) {
1005 gen->version_reg = NO_DISK | JAP; 1308 gen->version_reg = NO_DISK | JAP;
1006 } else { 1309 } else {
1007 gen->version_reg = NO_DISK | USA; 1310 gen->version_reg = NO_DISK | USA;
1008 } 1311 }
1009 1312
1010 if (region & HZ50) { 1313 if (region & HZ50) {
1011 gen->normal_clock = MCLKS_PAL; 1314 gen->normal_clock = MCLKS_PAL;
1315 gen->soft_flush_cycles = MCLKS_LINE * 262 / 3 + 2;
1012 } else { 1316 } else {
1013 gen->normal_clock = MCLKS_NTSC; 1317 gen->normal_clock = MCLKS_NTSC;
1318 gen->soft_flush_cycles = MCLKS_LINE * 313 / 3 + 2;
1014 } 1319 }
1015 gen->master_clock = gen->normal_clock; 1320 gen->master_clock = gen->normal_clock;
1016 } 1321 }
1017 1322
1018 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
1019 static uint8_t load_state(system_header *system, uint8_t slot) 1323 static uint8_t load_state(system_header *system, uint8_t slot)
1020 { 1324 {
1021 genesis_context *gen = (genesis_context *)system; 1325 genesis_context *gen = (genesis_context *)system;
1022 char *statepath = get_slot_name(system, slot, "state"); 1326 char *statepath = get_slot_name(system, slot, "state");
1023 deserialize_buffer state; 1327 deserialize_buffer state;
1069 load_state(&gen->header, gen->header.delayed_load_slot - 1); 1373 load_state(&gen->header, gen->header.delayed_load_slot - 1);
1070 gen->header.delayed_load_slot = 0; 1374 gen->header.delayed_load_slot = 0;
1071 resume_68k(gen->m68k); 1375 resume_68k(gen->m68k);
1072 } 1376 }
1073 } 1377 }
1074 bindings_release_capture(); 1378 if (gen->header.force_release || render_should_release_on_exit()) {
1075 vdp_release_framebuffer(gen->vdp); 1379 bindings_release_capture();
1076 render_pause_source(gen->ym->audio); 1380 vdp_release_framebuffer(gen->vdp);
1077 render_pause_source(gen->psg->audio); 1381 render_pause_source(gen->ym->audio);
1382 render_pause_source(gen->psg->audio);
1383 }
1078 } 1384 }
1079 1385
1080 static void start_genesis(system_header *system, char *statefile) 1386 static void start_genesis(system_header *system, char *statefile)
1081 { 1387 {
1082 genesis_context *gen = (genesis_context *)system; 1388 genesis_context *gen = (genesis_context *)system;
1116 } 1422 }
1117 1423
1118 static void resume_genesis(system_header *system) 1424 static void resume_genesis(system_header *system)
1119 { 1425 {
1120 genesis_context *gen = (genesis_context *)system; 1426 genesis_context *gen = (genesis_context *)system;
1121 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1427 if (gen->header.force_release || render_should_release_on_exit()) {
1122 bindings_reacquire_capture(); 1428 gen->header.force_release = 0;
1123 vdp_reacquire_framebuffer(gen->vdp); 1429 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1124 render_resume_source(gen->ym->audio); 1430 bindings_reacquire_capture();
1125 render_resume_source(gen->psg->audio); 1431 vdp_reacquire_framebuffer(gen->vdp);
1432 render_resume_source(gen->ym->audio);
1433 render_resume_source(gen->psg->audio);
1434 }
1126 resume_68k(gen->m68k); 1435 resume_68k(gen->m68k);
1127 handle_reset_requests(gen); 1436 handle_reset_requests(gen);
1128 } 1437 }
1129 1438
1130 static void inc_debug_mode(system_header *system) 1439 static void inc_debug_mode(system_header *system)
1134 } 1443 }
1135 1444
1136 static void request_exit(system_header *system) 1445 static void request_exit(system_header *system)
1137 { 1446 {
1138 genesis_context *gen = (genesis_context *)system; 1447 genesis_context *gen = (genesis_context *)system;
1448 gen->m68k->target_cycle = gen->m68k->current_cycle;
1139 gen->m68k->should_return = 1; 1449 gen->m68k->should_return = 1;
1140 } 1450 }
1141 1451
1142 static void persist_save(system_header *system) 1452 static void persist_save(system_header *system)
1143 { 1453 {
1148 FILE * f = fopen(save_filename, "wb"); 1458 FILE * f = fopen(save_filename, "wb");
1149 if (!f) { 1459 if (!f) {
1150 fprintf(stderr, "Failed to open %s file %s for writing\n", save_type_name(gen->save_type), save_filename); 1460 fprintf(stderr, "Failed to open %s file %s for writing\n", save_type_name(gen->save_type), save_filename);
1151 return; 1461 return;
1152 } 1462 }
1463 if (gen->save_type == RAM_FLAG_BOTH) {
1464 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1465 }
1153 fwrite(gen->save_storage, 1, gen->save_size, f); 1466 fwrite(gen->save_storage, 1, gen->save_size, f);
1467 if (gen->save_type == RAM_FLAG_BOTH) {
1468 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1469 }
1154 fclose(f); 1470 fclose(f);
1155 printf("Saved %s to %s\n", save_type_name(gen->save_type), save_filename); 1471 printf("Saved %s to %s\n", save_type_name(gen->save_type), save_filename);
1156 } 1472 }
1157 1473
1158 static void load_save(system_header *system) 1474 static void load_save(system_header *system)
1161 FILE * f = fopen(save_filename, "rb"); 1477 FILE * f = fopen(save_filename, "rb");
1162 if (f) { 1478 if (f) {
1163 uint32_t read = fread(gen->save_storage, 1, gen->save_size, f); 1479 uint32_t read = fread(gen->save_storage, 1, gen->save_size, f);
1164 fclose(f); 1480 fclose(f);
1165 if (read > 0) { 1481 if (read > 0) {
1482 if (gen->save_type == RAM_FLAG_BOTH) {
1483 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1484 }
1166 printf("Loaded %s from %s\n", save_type_name(gen->save_type), save_filename); 1485 printf("Loaded %s from %s\n", save_type_name(gen->save_type), save_filename);
1167 } 1486 }
1168 } 1487 }
1169 } 1488 }
1170 1489
1187 memmap_chunk *map = (memmap_chunk *)gen->m68k->options->gen.memmap; 1506 memmap_chunk *map = (memmap_chunk *)gen->m68k->options->gen.memmap;
1188 m68k_options_free(gen->m68k->options); 1507 m68k_options_free(gen->m68k->options);
1189 free(gen->cart); 1508 free(gen->cart);
1190 free(gen->m68k); 1509 free(gen->m68k);
1191 free(gen->work_ram); 1510 free(gen->work_ram);
1192 z80_options_free(gen->z80->options); 1511 z80_options_free(gen->z80->Z80_OPTS);
1193 free(gen->z80); 1512 free(gen->z80);
1194 free(gen->zram); 1513 free(gen->zram);
1195 ym_free(gen->ym); 1514 ym_free(gen->ym);
1196 psg_free(gen->psg); 1515 psg_free(gen->psg);
1197 free(gen->header.save_dir); 1516 free(gen->header.save_dir);
1198 free_rom_info(&gen->header.info); 1517 free_rom_info(&gen->header.info);
1199 free(gen->lock_on); 1518 free(gen->lock_on);
1519 if (gen->save_type != SAVE_NONE && gen->mapper_type != MAPPER_SEGA_MED_V2) {
1520 free(gen->save_storage);
1521 }
1200 free(gen); 1522 free(gen);
1201 } 1523 }
1202 1524
1203 static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t button) 1525 static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t button)
1204 { 1526 {
1252 { 1574 {
1253 genesis_context *gen = (genesis_context *)system; 1575 genesis_context *gen = (genesis_context *)system;
1254 io_keyboard_up(&gen->io, scancode); 1576 io_keyboard_up(&gen->io, scancode);
1255 } 1577 }
1256 1578
1579 static void set_audio_config(genesis_context *gen)
1580 {
1581 char *config_gain;
1582 config_gain = tern_find_path(config, "audio\0psg_gain\0", TVAL_PTR).ptrval;
1583 render_audio_source_gaindb(gen->psg->audio, config_gain ? atof(config_gain) : 0.0f);
1584 config_gain = tern_find_path(config, "audio\0fm_gain\0", TVAL_PTR).ptrval;
1585 render_audio_source_gaindb(gen->ym->audio, config_gain ? atof(config_gain) : 0.0f);
1586
1587 char *config_dac = tern_find_path_default(config, "audio\0fm_dac\0", (tern_val){.ptrval="zero_offset"}, TVAL_PTR).ptrval;
1588 ym_enable_zero_offset(gen->ym, !strcmp(config_dac, "zero_offset"));
1589 }
1590
1257 static void config_updated(system_header *system) 1591 static void config_updated(system_header *system)
1258 { 1592 {
1259 genesis_context *gen = (genesis_context *)system; 1593 genesis_context *gen = (genesis_context *)system;
1260 setup_io_devices(config, &system->info, &gen->io); 1594 setup_io_devices(config, &system->info, &gen->io);
1595 set_audio_config(gen);
1596 }
1597
1598 static void start_vgm_log(system_header *system, char *filename)
1599 {
1600 genesis_context *gen = (genesis_context *)system;
1601 vgm_writer *vgm = vgm_write_open(filename, gen->version_reg & HZ50 ? 50 : 60, gen->master_clock, gen->m68k->current_cycle);
1602 if (vgm) {
1603 printf("Started logging VGM to %s\n", filename);
1604 sync_sound(gen, vgm->last_cycle);
1605 ym_vgm_log(gen->ym, gen->master_clock, vgm);
1606 psg_vgm_log(gen->psg, gen->master_clock, vgm);
1607 gen->header.vgm_logging = 1;
1608 } else {
1609 printf("Failed to start logging to %s\n", filename);
1610 }
1611 }
1612
1613 static void stop_vgm_log(system_header *system)
1614 {
1615 puts("Stopped VGM log");
1616 genesis_context *gen = (genesis_context *)system;
1617 vgm_close(gen->ym->vgm);
1618 gen->ym->vgm = gen->psg->vgm = NULL;
1619 gen->header.vgm_logging = 0;
1620 }
1621
1622 static void *tmss_rom_write_16(uint32_t address, void *context, uint16_t value)
1623 {
1624 m68k_context *m68k = context;
1625 genesis_context *gen = m68k->system;
1626 if (gen->tmss) {
1627 return gen->tmss_write_16(address, context, value);
1628 }
1629
1630 return context;
1631 }
1632
1633 static void *tmss_rom_write_8(uint32_t address, void *context, uint8_t value)
1634 {
1635 m68k_context *m68k = context;
1636 genesis_context *gen = m68k->system;
1637 if (gen->tmss) {
1638 return gen->tmss_write_8(address, context, value);
1639 }
1640
1641 return context;
1642 }
1643
1644 static uint16_t tmss_rom_read_16(uint32_t address, void *context)
1645 {
1646 m68k_context *m68k = context;
1647 genesis_context *gen = m68k->system;
1648 if (gen->tmss) {
1649 return gen->tmss_read_16(address, context);
1650 }
1651 return ((uint16_t *)gen->tmss_buffer)[address >> 1];
1652 }
1653
1654 static uint8_t tmss_rom_read_8(uint32_t address, void *context)
1655 {
1656 m68k_context *m68k = context;
1657 genesis_context *gen = m68k->system;
1658 if (gen->tmss) {
1659 return gen->tmss_read_8(address, context);
1660 }
1661 #ifdef BLASTEM_BIG_ENDIAN
1662 return gen->tmss_buffer[address];
1663 #else
1664 return gen->tmss_buffer[address ^ 1];
1665 #endif
1666 }
1667
1668 static void *tmss_word_write_16(uint32_t address, void *context, uint16_t value)
1669 {
1670 m68k_context *m68k = context;
1671 genesis_context *gen = m68k->system;
1672 if (gen->tmss) {
1673 address += gen->tmss_write_offset;
1674 uint16_t *dest = get_native_pointer(address, (void **)m68k->mem_pointers, &m68k->options->gen);
1675 *dest = value;
1676 m68k_handle_code_write(address, m68k);
1677 }
1678
1679 return context;
1680 }
1681
1682 static void *tmss_word_write_8(uint32_t address, void *context, uint8_t value)
1683 {
1684 m68k_context *m68k = context;
1685 genesis_context *gen = m68k->system;
1686 if (gen->tmss) {
1687 address += gen->tmss_write_offset;
1688 uint8_t *dest = get_native_pointer(address & ~1, (void **)m68k->mem_pointers, &m68k->options->gen);
1689 #ifdef BLASTEM_BIG_ENDIAN
1690 dest[address & 1] = value;
1691 #else
1692 dest[address & 1 ^ 1] = value;
1693 #endif
1694 m68k_handle_code_write(address & ~1, m68k);
1695 }
1696
1697 return context;
1698 }
1699
1700 static void *tmss_odd_write_16(uint32_t address, void *context, uint16_t value)
1701 {
1702 m68k_context *m68k = context;
1703 genesis_context *gen = m68k->system;
1704 if (gen->tmss) {
1705 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1706 address >>= 1;
1707 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1708 base[address] = value;
1709 }
1710 return context;
1711 }
1712
1713 static void *tmss_odd_write_8(uint32_t address, void *context, uint8_t value)
1714 {
1715 m68k_context *m68k = context;
1716 genesis_context *gen = m68k->system;
1717 if (gen->tmss && (address & 1)) {
1718 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1719 address >>= 1;
1720 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1721 base[address] = value;
1722 }
1723 return context;
1724 }
1725
1726 static void *tmss_even_write_16(uint32_t address, void *context, uint16_t value)
1727 {
1728 m68k_context *m68k = context;
1729 genesis_context *gen = m68k->system;
1730 if (gen->tmss) {
1731 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1732 address >>= 1;
1733 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1734 base[address] = value >> 8;
1735 }
1736 return context;
1737 }
1738
1739 static void *tmss_even_write_8(uint32_t address, void *context, uint8_t value)
1740 {
1741 m68k_context *m68k = context;
1742 genesis_context *gen = m68k->system;
1743 if (gen->tmss && !(address & 1)) {
1744 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1745 address >>= 1;
1746 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1747 base[address] = value;
1748 }
1749 return context;
1261 } 1750 }
1262 1751
1263 static genesis_context *shared_init(uint32_t system_opts, rom_info *rom, uint8_t force_region) 1752 static genesis_context *shared_init(uint32_t system_opts, rom_info *rom, uint8_t force_region)
1264 { 1753 {
1265 static memmap_chunk z80_map[] = { 1754 static memmap_chunk z80_map[] = {
1267 { 0x8000, 0x10000, 0x7FFF, 0, 0, 0, NULL, NULL, NULL, z80_read_bank, z80_write_bank}, 1756 { 0x8000, 0x10000, 0x7FFF, 0, 0, 0, NULL, NULL, NULL, z80_read_bank, z80_write_bank},
1268 { 0x4000, 0x6000, 0x0003, 0, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym}, 1757 { 0x4000, 0x6000, 0x0003, 0, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym},
1269 { 0x6000, 0x6100, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg}, 1758 { 0x6000, 0x6100, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg},
1270 { 0x7F00, 0x8000, 0x00FF, 0, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write} 1759 { 0x7F00, 0x8000, 0x00FF, 0, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write}
1271 }; 1760 };
1272 1761
1273 char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval; 1762 char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval;
1274 if (!m68k_divider) { 1763 if (!m68k_divider) {
1275 m68k_divider = "7"; 1764 m68k_divider = "7";
1276 } 1765 }
1277 MCLKS_PER_68K = atoi(m68k_divider); 1766 MCLKS_PER_68K = atoi(m68k_divider);
1278 if (!MCLKS_PER_68K) { 1767 if (!MCLKS_PER_68K) {
1279 MCLKS_PER_68K = 7; 1768 MCLKS_PER_68K = 7;
1280 } 1769 }
1281 1770
1282 genesis_context *gen = calloc(1, sizeof(genesis_context)); 1771 genesis_context *gen = calloc(1, sizeof(genesis_context));
1283 gen->header.set_speed_percent = set_speed_percent; 1772 gen->header.set_speed_percent = set_speed_percent;
1284 gen->header.start_context = start_genesis; 1773 gen->header.start_context = start_genesis;
1285 gen->header.resume_context = resume_genesis; 1774 gen->header.resume_context = resume_genesis;
1286 gen->header.load_save = load_save; 1775 gen->header.load_save = load_save;
1298 gen->header.mouse_motion_absolute = mouse_motion_absolute; 1787 gen->header.mouse_motion_absolute = mouse_motion_absolute;
1299 gen->header.mouse_motion_relative = mouse_motion_relative; 1788 gen->header.mouse_motion_relative = mouse_motion_relative;
1300 gen->header.keyboard_down = keyboard_down; 1789 gen->header.keyboard_down = keyboard_down;
1301 gen->header.keyboard_up = keyboard_up; 1790 gen->header.keyboard_up = keyboard_up;
1302 gen->header.config_updated = config_updated; 1791 gen->header.config_updated = config_updated;
1792 gen->header.serialize = serialize;
1793 gen->header.deserialize = deserialize;
1794 gen->header.start_vgm_log = start_vgm_log;
1795 gen->header.stop_vgm_log = stop_vgm_log;
1303 gen->header.type = SYSTEM_GENESIS; 1796 gen->header.type = SYSTEM_GENESIS;
1304 gen->header.info = *rom; 1797 gen->header.info = *rom;
1305 set_region(gen, rom, force_region); 1798 set_region(gen, rom, force_region);
1306 1799 tern_node *model = get_model(config, SYSTEM_GENESIS);
1307 gen->vdp = init_vdp_context(gen->version_reg & 0x40); 1800 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
1801 if (tmss) {
1802 gen->version_reg |= 1;
1803 } else {
1804 gen->vdp_unlocked = 1;
1805 }
1806
1807 uint8_t max_vsram = !strcmp(tern_find_ptr_default(model, "vsram", "40"), "64");
1808 gen->vdp = init_vdp_context(gen->version_reg & 0x40, max_vsram);
1308 gen->vdp->system = &gen->header; 1809 gen->vdp->system = &gen->header;
1309 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp); 1810 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp);
1310 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval; 1811 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval;
1311 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL; 1812 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL;
1312 gen->int_latency_prev1 = MCLKS_PER_68K * 32; 1813 gen->int_latency_prev1 = MCLKS_PER_68K * 32;
1313 gen->int_latency_prev2 = MCLKS_PER_68K * 16; 1814 gen->int_latency_prev2 = MCLKS_PER_68K * 16;
1314 1815
1315 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1816 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1316 1817 event_system_start(SYSTEM_GENESIS, (gen->version_reg & HZ50) ? VID_PAL : VID_NTSC, rom->name);
1818
1317 gen->ym = malloc(sizeof(ym2612_context)); 1819 gen->ym = malloc(sizeof(ym2612_context));
1820 char *fm = tern_find_ptr_default(model, "fm", "discrete 2612");
1821 if (!strcmp(fm + strlen(fm) -4, "3834")) {
1822 system_opts |= YM_OPT_3834;
1823 }
1318 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts); 1824 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts);
1319 1825
1320 gen->psg = malloc(sizeof(psg_context)); 1826 gen->psg = malloc(sizeof(psg_context));
1321 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG); 1827 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG);
1828
1829 set_audio_config(gen);
1322 1830
1323 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); 1831 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES);
1324 #ifndef NO_Z80 1832 #ifndef NO_Z80
1325 z80_options *z_opts = malloc(sizeof(z80_options)); 1833 z80_options *z_opts = malloc(sizeof(z80_options));
1326 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF); 1834 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF);
1327 gen->z80 = init_z80_context(z_opts); 1835 gen->z80 = init_z80_context(z_opts);
1836 #ifndef NEW_CORE
1328 gen->z80->next_int_pulse = z80_next_int_pulse; 1837 gen->z80->next_int_pulse = z80_next_int_pulse;
1838 #endif
1329 z80_assert_reset(gen->z80, 0); 1839 z80_assert_reset(gen->z80, 0);
1330 #else 1840 #else
1331 gen->z80 = calloc(1, sizeof(z80_context)); 1841 gen->z80 = calloc(1, sizeof(z80_context));
1332 #endif 1842 #endif
1333 1843
1334 gen->z80->system = gen; 1844 gen->z80->system = gen;
1335 gen->z80->mem_pointers[0] = gen->zram; 1845 gen->z80->mem_pointers[0] = gen->zram;
1336 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = NULL; 1846 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = NULL;
1337 1847
1338 gen->work_ram = calloc(2, RAM_WORDS); 1848 gen->work_ram = calloc(2, RAM_WORDS);
1339 if (!strcmp("random", tern_find_path_default(config, "system\0ram_init\0", (tern_val){.ptrval = "zero"}, TVAL_PTR).ptrval)) 1849 if (!strcmp("random", tern_find_path_default(config, "system\0ram_init\0", (tern_val){.ptrval = "zero"}, TVAL_PTR).ptrval))
1340 { 1850 {
1341 srand(time(NULL)); 1851 srand(time(NULL));
1342 for (int i = 0; i < RAM_WORDS; i++) 1852 for (int i = 0; i < RAM_WORDS; i++)
1357 } 1867 }
1358 for (int i = 0; i < CRAM_SIZE; i++) 1868 for (int i = 0; i < CRAM_SIZE; i++)
1359 { 1869 {
1360 write_cram_internal(gen->vdp, i, rand()); 1870 write_cram_internal(gen->vdp, i, rand());
1361 } 1871 }
1362 for (int i = 0; i < VSRAM_SIZE; i++) 1872 for (int i = 0; i < gen->vdp->vsram_size; i++)
1363 { 1873 {
1364 gen->vdp->vsram[i] = rand(); 1874 gen->vdp->vsram[i] = rand();
1365 } 1875 }
1366 } 1876 }
1367 1877
1368 return gen; 1878 return gen;
1369 } 1879 }
1370 1880
1371 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 1881 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
1372 { 1882 {
1373 genesis_context *gen = shared_init(system_opts, rom, force_region); 1883 genesis_context *gen = shared_init(system_opts, rom, force_region);
1374 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = (uint8_t *)main_rom; 1884 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = (uint8_t *)main_rom;
1375 1885
1376 gen->cart = main_rom; 1886 gen->cart = main_rom;
1377 gen->lock_on = lock_on; 1887 gen->lock_on = lock_on;
1378 1888
1379 setup_io_devices(config, rom, &gen->io); 1889 setup_io_devices(config, rom, &gen->io);
1380 gen->header.has_keyboard = io_has_keyboard(&gen->io); 1890 gen->header.has_keyboard = io_has_keyboard(&gen->io);
1381 gen->mapper_type = rom->mapper_type; 1891 gen->mapper_type = rom->mapper_type;
1382 gen->save_type = rom->save_type; 1892 gen->save_type = rom->save_type;
1383 if (gen->save_type != SAVE_NONE) { 1893 if (gen->save_type != SAVE_NONE) {
1393 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus); 1903 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus);
1394 } 1904 }
1395 } else { 1905 } else {
1396 gen->save_storage = NULL; 1906 gen->save_storage = NULL;
1397 } 1907 }
1398 1908
1909 gen->mapper_start_index = rom->mapper_start_index;
1910
1911 tern_node *model = get_model(config, SYSTEM_GENESIS);
1912 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
1913
1399 //This must happen before we generate memory access functions in init_m68k_opts 1914 //This must happen before we generate memory access functions in init_m68k_opts
1915 uint8_t next_ptr_index = 0;
1916 uint32_t tmss_min_alloc = 16 * 1024;
1400 for (int i = 0; i < rom->map_chunks; i++) 1917 for (int i = 0; i < rom->map_chunks; i++)
1401 { 1918 {
1402 if (rom->map[i].start == 0xE00000) { 1919 if (rom->map[i].start == 0xE00000) {
1403 rom->map[i].buffer = gen->work_ram; 1920 rom->map[i].buffer = gen->work_ram;
1404 break; 1921 if (!tmss) {
1405 } 1922 break;
1923 }
1924 }
1925 if (rom->map[i].flags & MMAP_PTR_IDX && rom->map[i].ptr_index >= next_ptr_index) {
1926 next_ptr_index = rom->map[i].ptr_index + 1;
1927 }
1928 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) {
1929 uint32_t highest_offset = (rom->map[i].end & rom->map[i].mask) + 1;
1930 if (highest_offset > tmss_min_alloc) {
1931 tmss_min_alloc = highest_offset;
1932 }
1933 }
1934 }
1935 if (tmss) {
1936 char *tmss_path = tern_find_path_default(config, "system\0tmss_path\0", (tern_val){.ptrval = "tmss.md"}, TVAL_PTR).ptrval;
1937 uint8_t *buffer = malloc(tmss_min_alloc);
1938 uint32_t tmss_size;
1939 if (is_absolute_path(tmss_path)) {
1940 FILE *f = fopen(tmss_path, "rb");
1941 if (!f) {
1942 fatal_error("Configured to use a model with TMSS, but failed to load the TMSS ROM from %s\n", tmss_path);
1943 }
1944 tmss_size = fread(buffer, 1, tmss_min_alloc, f);
1945 fclose(f);
1946 } else {
1947 char *tmp = read_bundled_file(tmss_path, &tmss_size);
1948 if (!tmp) {
1949 fatal_error("Configured to use a model with TMSS, but failed to load the TMSS ROM from %s\n", tmss_path);
1950 }
1951 memcpy(buffer, tmp, tmss_size);
1952 free(tmp);
1953 }
1954 for (uint32_t padded = nearest_pow2(tmss_size); tmss_size < padded; tmss_size++)
1955 {
1956 buffer[tmss_size] = 0xFF;
1957 }
1958 #ifndef BLASTEM_BIG_ENDIAN
1959 byteswap_rom(tmss_size, (uint16_t *)buffer);
1960 #endif
1961 //mirror TMSS ROM until we fill up to tmss_min_alloc
1962 for (uint32_t dst = tmss_size; dst < tmss_min_alloc; dst += tmss_size)
1963 {
1964 memcpy(buffer + dst, buffer, dst + tmss_size > tmss_min_alloc ? tmss_min_alloc - dst : tmss_size);
1965 }
1966 //modify mappings for ROM space to point to the TMSS ROM and fixup flags to allow switching back and forth
1967 //WARNING: This code makes some pretty big assumptions about the kinds of map chunks it will encounter
1968 for (int i = 0; i < rom->map_chunks; i++)
1969 {
1970 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) {
1971 if (rom->map[i].flags == MMAP_READ) {
1972 //Normal ROM
1973 rom->map[i].flags |= MMAP_PTR_IDX | MMAP_CODE;
1974 rom->map[i].ptr_index = next_ptr_index++;
1975 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) {
1976 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
1977 }
1978 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
1979 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
1980 } else if (rom->map[i].flags & MMAP_PTR_IDX) {
1981 //Sega mapper page or multi-game mapper
1982 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
1983 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
1984 if (rom->map[i].write_16) {
1985 if (!gen->tmss_write_16) {
1986 gen->tmss_write_16 = rom->map[i].write_16;
1987 gen->tmss_write_8 = rom->map[i].write_8;
1988 rom->map[i].write_16 = tmss_rom_write_16;
1989 rom->map[i].write_8 = tmss_rom_write_8;
1990 } else if (gen->tmss_write_16 == rom->map[i].write_16) {
1991 rom->map[i].write_16 = tmss_rom_write_16;
1992 rom->map[i].write_8 = tmss_rom_write_8;
1993 } else {
1994 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", rom->map[i].start);
1995 }
1996 }
1997 } else if ((rom->map[i].flags & (MMAP_READ | MMAP_WRITE)) == (MMAP_READ | MMAP_WRITE)) {
1998 //RAM or SRAM
1999 rom->map[i].flags |= MMAP_PTR_IDX;
2000 rom->map[i].ptr_index = next_ptr_index++;
2001 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
2002 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
2003 if (!gen->tmss_write_offset || gen->tmss_write_offset == rom->map[i].start) {
2004 gen->tmss_write_offset = rom->map[i].start;
2005 rom->map[i].flags &= ~MMAP_WRITE;
2006 if (rom->map[i].flags & MMAP_ONLY_ODD) {
2007 rom->map[i].write_16 = tmss_odd_write_16;
2008 rom->map[i].write_8 = tmss_odd_write_8;
2009 } else if (rom->map[i].flags & MMAP_ONLY_EVEN) {
2010 rom->map[i].write_16 = tmss_even_write_16;
2011 rom->map[i].write_8 = tmss_even_write_8;
2012 } else {
2013 rom->map[i].write_16 = tmss_word_write_16;
2014 rom->map[i].write_8 = tmss_word_write_8;
2015 }
2016 } else {
2017 warning("Could not remap writes for chunk starting at %X for TMSS because write_offset is %X\n", rom->map[i].start, gen->tmss_write_offset);
2018 }
2019 } else if (rom->map[i].flags & MMAP_READ_CODE) {
2020 //NOR flash
2021 rom->map[i].flags |= MMAP_PTR_IDX;
2022 rom->map[i].ptr_index = next_ptr_index++;
2023 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) {
2024 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
2025 }
2026 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
2027 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
2028 if (!gen->tmss_write_16) {
2029 gen->tmss_write_16 = rom->map[i].write_16;
2030 gen->tmss_write_8 = rom->map[i].write_8;
2031 gen->tmss_read_16 = rom->map[i].read_16;
2032 gen->tmss_read_8 = rom->map[i].read_8;
2033 rom->map[i].write_16 = tmss_rom_write_16;
2034 rom->map[i].write_8 = tmss_rom_write_8;
2035 rom->map[i].read_16 = tmss_rom_read_16;
2036 rom->map[i].read_8 = tmss_rom_read_8;
2037 } else if (gen->tmss_write_16 == rom->map[i].write_16) {
2038 rom->map[i].write_16 = tmss_rom_write_16;
2039 rom->map[i].write_8 = tmss_rom_write_8;
2040 rom->map[i].read_16 = tmss_rom_read_16;
2041 rom->map[i].read_8 = tmss_rom_read_8;
2042 } else {
2043 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", rom->map[i].start);
2044 }
2045 } else {
2046 warning("Didn't remap chunk starting at %X for TMSS because it has flags %X\n", rom->map[i].start, rom->map[i].flags);
2047 }
2048 }
2049 }
2050 gen->tmss_buffer = buffer;
1406 } 2051 }
1407 2052
1408 m68k_options *opts = malloc(sizeof(m68k_options)); 2053 m68k_options *opts = malloc(sizeof(m68k_options));
1409 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K); 2054 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K);
1410 //TODO: make this configurable 2055 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) {
1411 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY; 2056 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
2057 }
1412 gen->m68k = init_68k_context(opts, NULL); 2058 gen->m68k = init_68k_context(opts, NULL);
1413 gen->m68k->system = gen; 2059 gen->m68k->system = gen;
1414 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL; 2060 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL;
1415 2061
1416 //This must happen after the 68K context has been allocated 2062 //This must happen after the 68K context has been allocated
1417 for (int i = 0; i < rom->map_chunks; i++) 2063 for (int i = 0; i < rom->map_chunks; i++)
1418 { 2064 {
1419 if (rom->map[i].flags & MMAP_PTR_IDX) { 2065 if (rom->map[i].flags & MMAP_PTR_IDX) {
1420 gen->m68k->mem_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2066 gen->m68k->mem_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
1421 } 2067 }
1422 } 2068 }
1423 2069
1424 if (gen->mapper_type == MAPPER_SEGA) { 2070 if (gen->mapper_type == MAPPER_SEGA) {
1425 //initialize bank registers 2071 //initialize bank registers
1426 for (int i = 1; i < sizeof(gen->bank_regs); i++) 2072 for (int i = 1; i < sizeof(gen->bank_regs); i++)
1427 { 2073 {
1428 gen->bank_regs[i] = i; 2074 gen->bank_regs[i] = i;
1429 } 2075 }
1430 } 2076 }
2077 gen->reset_cycle = CYCLE_NEVER;
1431 2078
1432 return gen; 2079 return gen;
1433 } 2080 }
1434 2081
1435 static memmap_chunk base_map[] = { 2082 static memmap_chunk base_map[] = {
1436 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL, 2083 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL,
1437 NULL, NULL, NULL, NULL}, 2084 NULL, NULL, NULL, NULL},
1438 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL, 2085 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
1439 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, 2086 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1440 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, 2087 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1441 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL, 2088 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
1442 (read_16_fun)io_read_w, (write_16_fun)io_write_w, 2089 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
1443 (read_8_fun)io_read, (write_8_fun)io_write} 2090 (read_8_fun)io_read, (write_8_fun)io_write},
1444 }; 2091 {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL,
1445 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map); 2092 (read_16_fun)unused_read, (write_16_fun)unused_write,
2093 (read_8_fun)unused_read_b, (write_8_fun)unused_write_b}
2094 };
2095 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map);
1446 2096
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) 2097 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)
1448 { 2098 {
1449 tern_node *rom_db = get_rom_db(); 2099 tern_node *rom_db = get_rom_db();
1450 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks); 2100 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
1469 2119
1470 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region) 2120 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region)
1471 { 2121 {
1472 tern_node *rom_db = get_rom_db(); 2122 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); 2123 rom_info info = configure_rom(rom_db, media->buffer, media->size, NULL, 0, base_map, base_chunks);
1474 2124
1475 segacd_context *cd = alloc_configure_segacd(media, system_opts, force_region, &info); 2125 segacd_context *cd = alloc_configure_segacd(media, system_opts, force_region, &info);
1476 genesis_context *gen = shared_init(system_opts, &info, force_region); 2126 genesis_context *gen = shared_init(system_opts, &info, force_region);
1477 gen->cart = gen->lock_on = NULL; 2127 gen->cart = gen->lock_on = NULL;
1478 gen->save_storage = NULL; 2128 gen->save_storage = NULL;
1479 gen->save_type = SAVE_NONE; 2129 gen->save_type = SAVE_NONE;
1480 gen->version_reg &= ~NO_DISK; 2130 gen->version_reg &= ~NO_DISK;
1481 2131
1482 gen->expansion = cd; 2132 gen->expansion = cd;
1483 setup_io_devices(config, &info, &gen->io); 2133 setup_io_devices(config, &info, &gen->io);
1484 2134
1485 uint32_t cd_chunks; 2135 uint32_t cd_chunks;
1486 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, &cd_chunks); 2136 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, &cd_chunks);
1487 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks)); 2137 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks));
1488 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks); 2138 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks);
1489 memcpy(map + cd_chunks, base_map, sizeof(memmap_chunk) * base_chunks); 2139 memcpy(map + cd_chunks, base_map, sizeof(memmap_chunk) * base_chunks);
1490 map[cd_chunks].buffer = gen->work_ram; 2140 map[cd_chunks].buffer = gen->work_ram;
1491 uint32_t num_chunks = cd_chunks + base_chunks; 2141 uint32_t num_chunks = cd_chunks + base_chunks;
1492 2142
1493 m68k_options *opts = malloc(sizeof(m68k_options)); 2143 m68k_options *opts = malloc(sizeof(m68k_options));
1494 init_m68k_opts(opts, map, num_chunks, MCLKS_PER_68K); 2144 init_m68k_opts(opts, map, num_chunks, MCLKS_PER_68K);
1495 //TODO: make this configurable 2145 //TODO: make this configurable
1496 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY; 2146 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
1497 gen->m68k = init_68k_context(opts, NULL); 2147 gen->m68k = init_68k_context(opts, NULL);
1498 gen->m68k->system = gen; 2148 gen->m68k->system = gen;
1499 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL; 2149 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL;
1500 2150
1501 //This must happen after the 68K context has been allocated 2151 //This must happen after the 68K context has been allocated
1502 for (int i = 0; i < num_chunks; i++) 2152 for (int i = 0; i < num_chunks; i++)
1503 { 2153 {
1504 if (map[i].flags & MMAP_PTR_IDX) { 2154 if (map[i].flags & MMAP_PTR_IDX) {
1505 gen->m68k->mem_pointers[map[i].ptr_index] = map[i].buffer; 2155 gen->m68k->mem_pointers[map[i].ptr_index] = map[i].buffer;