comparison blastem.c @ 487:c08a4efeee7f opengl

Update opengl branch from default. Fix build breakage unrelated to merge
author Mike Pavone <pavone@retrodev.com>
date Sat, 26 Oct 2013 22:38:47 -0700
parents 7696d824489d 3e1573fa22cf
children 32f053ad9b02
comparison
equal deleted inserted replaced
449:7696d824489d 487:c08a4efeee7f
1 /*
2 Copyright 2013 Michael Pavone
3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */
1 #include "68kinst.h" 6 #include "68kinst.h"
2 #include "m68k_to_x86.h" 7 #include "m68k_to_x86.h"
3 #include "z80_to_x86.h" 8 #include "z80_to_x86.h"
4 #include "mem.h" 9 #include "mem.h"
5 #include "vdp.h" 10 #include "vdp.h"
6 #include "render.h" 11 #include "render.h"
7 #include "blastem.h" 12 #include "blastem.h"
13 #include "gst.h"
8 #include <stdio.h> 14 #include <stdio.h>
9 #include <stdlib.h> 15 #include <stdlib.h>
10 #include <string.h> 16 #include <string.h>
17
18 #define BLASTEM_VERSION "0.1.0"
11 19
12 #define CARTRIDGE_WORDS 0x200000 20 #define CARTRIDGE_WORDS 0x200000
13 #define RAM_WORDS 32 * 1024 21 #define RAM_WORDS 32 * 1024
14 #define Z80_RAM_BYTES 8 * 1024 22 #define Z80_RAM_BYTES 8 * 1024
15 23
23 31
24 //TODO: Figure out the exact value for this 32 //TODO: Figure out the exact value for this
25 #define LINES_NTSC 262 33 #define LINES_NTSC 262
26 #define LINES_PAL 312 34 #define LINES_PAL 312
27 35
36 #define MAX_SOUND_CYCLES 100000
37
28 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC; 38 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC;
29 39
30 uint16_t cart[CARTRIDGE_WORDS]; 40 uint16_t cart[CARTRIDGE_WORDS];
31 uint16_t ram[RAM_WORDS]; 41 uint16_t ram[RAM_WORDS];
32 uint8_t z80_ram[Z80_RAM_BYTES]; 42 uint8_t z80_ram[Z80_RAM_BYTES];
33 43
34 int headless = 0; 44 int headless = 0;
35 int z80_enabled = 1; 45 int z80_enabled = 1;
36 int frame_limit = 0; 46 int frame_limit = 0;
47
48 tern_node * config;
37 49
38 #ifndef MIN 50 #ifndef MIN
39 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 51 #define MIN(a,b) ((a) < (b) ? (a) : (b))
40 #endif 52 #endif
41 53
48 int load_smd_rom(long filesize, FILE * f) 60 int load_smd_rom(long filesize, FILE * f)
49 { 61 {
50 uint8_t block[SMD_BLOCK_SIZE]; 62 uint8_t block[SMD_BLOCK_SIZE];
51 filesize -= SMD_HEADER_SIZE; 63 filesize -= SMD_HEADER_SIZE;
52 fseek(f, SMD_HEADER_SIZE, SEEK_SET); 64 fseek(f, SMD_HEADER_SIZE, SEEK_SET);
53 65
54 uint16_t * dst = cart; 66 uint16_t * dst = cart;
55 while (filesize > 0) { 67 while (filesize > 0) {
56 fread(block, 1, SMD_BLOCK_SIZE, f); 68 fread(block, 1, SMD_BLOCK_SIZE, f);
57 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) { 69 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) {
58 *(dst++) = *high << 8 | *low; 70 *(dst++) = *high << 8 | *low;
135 if (next_hint != CYCLE_NEVER) { 147 if (next_hint != CYCLE_NEVER) {
136 next_hint /= MCLKS_PER_68K; 148 next_hint /= MCLKS_PER_68K;
137 if (next_hint < context->int_cycle) { 149 if (next_hint < context->int_cycle) {
138 context->int_cycle = next_hint; 150 context->int_cycle = next_hint;
139 context->int_num = 4; 151 context->int_num = 4;
140 152
141 } 153 }
142 } 154 }
143 } 155 }
144 } 156 }
145 157
146 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle; 158 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle;
147 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n", 159 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n",
148 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7), 160 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7),
149 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);*/ 161 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);*/
150 } 162 }
151 163
152 int break_on_sync = 0; 164 int break_on_sync = 0;
165 int save_state = 0;
153 166
154 uint8_t reset = 1; 167 uint8_t reset = 1;
155 uint8_t need_reset = 0; 168 uint8_t need_reset = 0;
156 uint8_t busreq = 0; 169 uint8_t busreq = 0;
157 uint8_t busack = 0; 170 uint8_t busack = 0;
193 } 206 }
194 207
195 void sync_sound(genesis_context * gen, uint32_t target) 208 void sync_sound(genesis_context * gen, uint32_t target)
196 { 209 {
197 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2); 210 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2);
211 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES) {
212 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES;
213 //printf("Running PSG to cycle %d\n", cur_target);
214 psg_run(gen->psg, cur_target);
215 //printf("Running YM-2612 to cycle %d\n", cur_target);
216 ym_run(gen->ym, cur_target);
217 }
198 psg_run(gen->psg, target); 218 psg_run(gen->psg, target);
199 ym_run(gen->ym, target); 219 ym_run(gen->ym, target);
200 220
201 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 221 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
202 } 222 }
203 223
204 uint32_t frame=0; 224 uint32_t frame=0;
205 m68k_context * sync_components(m68k_context * context, uint32_t address) 225 m68k_context * sync_components(m68k_context * context, uint32_t address)
217 if (gen->ym->write_cycle != CYCLE_NEVER) { 237 if (gen->ym->write_cycle != CYCLE_NEVER) {
218 gen->ym->write_cycle = gen->ym->write_cycle >= mclks_per_frame/MCLKS_PER_68K ? gen->ym->write_cycle - mclks_per_frame/MCLKS_PER_68K : 0; 238 gen->ym->write_cycle = gen->ym->write_cycle >= mclks_per_frame/MCLKS_PER_68K ? gen->ym->write_cycle - mclks_per_frame/MCLKS_PER_68K : 0;
219 } 239 }
220 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 240 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
221 vdp_run_context(v_context, mclks_per_frame); 241 vdp_run_context(v_context, mclks_per_frame);
222 242
223 if (!headless) { 243 if (!headless) {
224 break_on_sync |= wait_render_frame(v_context, frame_limit); 244 break_on_sync |= wait_render_frame(v_context, frame_limit);
225 } 245 }
226 frame++; 246 frame++;
227 mclks -= mclks_per_frame; 247 mclks -= mclks_per_frame;
254 if (context->int_ack) { 274 if (context->int_ack) {
255 vdp_int_ack(v_context, context->int_ack); 275 vdp_int_ack(v_context, context->int_ack);
256 context->int_ack = 0; 276 context->int_ack = 0;
257 } 277 }
258 adjust_int_cycle(context, v_context); 278 adjust_int_cycle(context, v_context);
259 if (break_on_sync && address) { 279 if (address) {
280 if (break_on_sync) {
260 break_on_sync = 0; 281 break_on_sync = 0;
261 debugger(context, address); 282 debugger(context, address);
283 }
284 if (save_state) {
285 save_state = 0;
286 while (!z_context->pc)
287 {
288 sync_z80(z_context, z_context->current_cycle * MCLKS_PER_Z80 + MCLKS_PER_Z80);
289 }
290 save_gst(gen, "savestate.gst", address);
291 }
262 } 292 }
263 return context; 293 return context;
264 } 294 }
265 295
266 m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value) 296 m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value)
280 while (vdp_data_port_write(v_context, value) < 0) { 310 while (vdp_data_port_write(v_context, value) < 0) {
281 while(v_context->flags & FLAG_DMA_RUN) { 311 while(v_context->flags & FLAG_DMA_RUN) {
282 vdp_run_dma_done(v_context, mclks_per_frame); 312 vdp_run_dma_done(v_context, mclks_per_frame);
283 if (v_context->cycles >= mclks_per_frame) { 313 if (v_context->cycles >= mclks_per_frame) {
284 if (!headless) { 314 if (!headless) {
315 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, v_context->cycles);
285 wait_render_frame(v_context, frame_limit); 316 wait_render_frame(v_context, frame_limit);
286 } 317 }
287 vdp_adjust_cycles(v_context, mclks_per_frame); 318 vdp_adjust_cycles(v_context, mclks_per_frame);
288 genesis_context * gen = context->system; 319 genesis_context * gen = context->system;
289 io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); 320 io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
297 busack = new_busack; 328 busack = new_busack;
298 } 329 }
299 } 330 }
300 } 331 }
301 } 332 }
302 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 333 //context->current_cycle = v_context->cycles / MCLKS_PER_68K;
303 } 334 }
304 } else if(vdp_port < 8) { 335 } else if(vdp_port < 8) {
305 blocked = vdp_control_port_write(v_context, value); 336 blocked = vdp_control_port_write(v_context, value);
306 if (blocked) { 337 if (blocked) {
307 while (blocked) { 338 while (blocked) {
330 blocked = vdp_control_port_write(v_context, value); 361 blocked = vdp_control_port_write(v_context, value);
331 } else { 362 } else {
332 blocked = 0; 363 blocked = 0;
333 } 364 }
334 } 365 }
335 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
336 } else { 366 } else {
337 adjust_int_cycle(context, v_context); 367 adjust_int_cycle(context, v_context);
338 } 368 }
339 } else { 369 } else {
340 printf("Illegal write to HV Counter port %X\n", vdp_port); 370 printf("Illegal write to HV Counter port %X\n", vdp_port);
341 exit(1); 371 exit(1);
342 } 372 }
343 if (v_context->cycles != before_cycle) { 373 if (v_context->cycles != before_cycle) {
374 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for write\n", v_context->cycles / MCLKS_PER_68K - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle);
344 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 375 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
345 } 376 }
346 } else if (vdp_port < 0x18) { 377 } else if (vdp_port < 0x18) {
347 genesis_context * gen = context->system; 378 genesis_context * gen = context->system;
348 sync_sound(gen, context->current_cycle * MCLKS_PER_68K); 379 sync_sound(gen, context->current_cycle * MCLKS_PER_68K);
378 } 409 }
379 } else if (vdp_port < 0x18) { 410 } else if (vdp_port < 0x18) {
380 sync_sound(gen, context->current_cycle * MCLKS_PER_Z80); 411 sync_sound(gen, context->current_cycle * MCLKS_PER_Z80);
381 psg_write(gen->psg, value); 412 psg_write(gen->psg, value);
382 } else { 413 } else {
383 //TODO: Implement undocumented test register(s) 414 vdp_test_port_write(gen->vdp, value);
384 } 415 }
385 return context; 416 return context;
386 } 417 }
387 418
388 uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context) 419 uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context)
393 } 424 }
394 vdp_port &= 0x1F; 425 vdp_port &= 0x1F;
395 uint16_t value; 426 uint16_t value;
396 sync_components(context, 0); 427 sync_components(context, 0);
397 vdp_context * v_context = context->video_context; 428 vdp_context * v_context = context->video_context;
429 uint32_t before_cycle = v_context->cycles;
398 if (vdp_port < 0x10) { 430 if (vdp_port < 0x10) {
399 if (vdp_port < 4) { 431 if (vdp_port < 4) {
400 value = vdp_data_port_read(v_context); 432 value = vdp_data_port_read(v_context);
401 } else if(vdp_port < 8) { 433 } else if(vdp_port < 8) {
402 value = vdp_control_port_read(v_context); 434 value = vdp_control_port_read(v_context);
403 } else { 435 } else {
404 value = vdp_hv_counter_read(v_context); 436 value = vdp_hv_counter_read(v_context);
405 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); 437 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles);
406 } 438 }
407 context->current_cycle = v_context->cycles/MCLKS_PER_68K; 439 } else if (vdp_port < 0x18){
440 printf("Illegal read from PSG port %X\n", vdp_port);
441 exit(1);
408 } else { 442 } else {
409 printf("Illegal read from PSG or test register port %X\n", vdp_port); 443 value = vdp_test_port_read(v_context);
410 exit(1); 444 }
445 if (v_context->cycles != before_cycle) {
446 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles / MCLKS_PER_68K - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle);
447 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
411 } 448 }
412 return value; 449 return value;
413 } 450 }
414 451
415 uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context) 452 uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context)
487 gen->ports[2].control = value; 524 gen->ports[2].control = value;
488 break; 525 break;
489 } 526 }
490 } else { 527 } else {
491 if (location == 0x1100) { 528 if (location == 0x1100) {
492 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
493 if (busack_cycle <= context->current_cycle) { 529 if (busack_cycle <= context->current_cycle) {
494 busack = new_busack; 530 busack = new_busack;
495 busack_cycle = CYCLE_NEVER; 531 busack_cycle = CYCLE_NEVER;
496 } 532 }
497 if (value & 1) { 533 if (value & 1) {
498 dputs("bus requesting Z80"); 534 dputs("bus requesting Z80");
499 535
500 if(!reset && !busreq) { 536 if(!reset && !busreq) {
501 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY; 537 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K + Z80_ACK_DELAY*MCLKS_PER_Z80);
538 busack_cycle = (gen->z80->current_cycle * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
502 new_busack = Z80_REQ_ACK; 539 new_busack = Z80_REQ_ACK;
503 } 540 }
504 busreq = 1; 541 busreq = 1;
505 } else { 542 } else {
543 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
506 if (busreq) { 544 if (busreq) {
507 dputs("releasing z80 bus"); 545 dputs("releasing z80 bus");
508 #ifdef DO_DEBUG_PRINT 546 #ifdef DO_DEBUG_PRINT
509 char fname[20]; 547 char fname[20];
510 sprintf(fname, "zram-%d", zram_counter++); 548 sprintf(fname, "zram-%d", zram_counter++);
516 new_busack = Z80_REQ_BUSY; 554 new_busack = Z80_REQ_BUSY;
517 busreq = 0; 555 busreq = 0;
518 } 556 }
519 //busack_cycle = CYCLE_NEVER; 557 //busack_cycle = CYCLE_NEVER;
520 //busack = Z80_REQ_BUSY; 558 //busack = Z80_REQ_BUSY;
521 559
522 } 560 }
523 } else if (location == 0x1200) { 561 } else if (location == 0x1200) {
524 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 562 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
525 if (value & 1) { 563 if (value & 1) {
526 if (reset && busreq) { 564 if (reset && busreq) {
1431 case 'z': { 1469 case 'z': {
1432 genesis_context * gen = context->system; 1470 genesis_context * gen = context->system;
1433 //Z80 debug commands 1471 //Z80 debug commands
1434 switch(input_buf[1]) 1472 switch(input_buf[1])
1435 { 1473 {
1436 case 'b': 1474 case 'b':
1437 param = find_param(input_buf); 1475 param = find_param(input_buf);
1438 if (!param) { 1476 if (!param) {
1439 fputs("zb command requires a parameter\n", stderr); 1477 fputs("zb command requires a parameter\n", stderr);
1440 break; 1478 break;
1441 } 1479 }
1461 } 1499 }
1462 } 1500 }
1463 return context; 1501 return context;
1464 } 1502 }
1465 1503
1466 #define GST_68K_REGS 0x80 1504 void set_speed_percent(genesis_context * context, uint32_t percent)
1467 #define GST_68K_REG_SIZE (0xDA-GST_68K_REGS) 1505 {
1468 #define GST_68K_PC_OFFSET (0xC8-GST_68K_REGS) 1506 uint32_t old_clock = context->master_clock;
1469 #define GST_68K_SR_OFFSET (0xD0-GST_68K_REGS) 1507 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100;
1470 #define GST_68K_USP_OFFSET (0xD2-GST_68K_REGS) 1508 while (context->ym->current_cycle != context->psg->cycles) {
1471 #define GST_68K_SSP_OFFSET (0xD6-GST_68K_REGS) 1509 sync_sound(context, context->psg->cycles + MCLKS_PER_PSG);
1472 #define GST_68K_RAM 0x2478 1510 }
1473 #define GST_Z80_REGS 0x404 1511 ym_adjust_master_clock(context->ym, context->master_clock);
1474 #define GST_Z80_REG_SIZE (0x440-GST_Z80_REGS) 1512 psg_adjust_master_clock(context->psg, context->master_clock);
1475 #define GST_Z80_RAM 0x474
1476
1477 uint32_t read_le_32(uint8_t * data)
1478 {
1479 return data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0];
1480 }
1481
1482 uint16_t read_le_16(uint8_t * data)
1483 {
1484 return data[1] << 8 | data[0];
1485 }
1486
1487 uint16_t read_be_16(uint8_t * data)
1488 {
1489 return data[0] << 8 | data[1];
1490 }
1491
1492 uint32_t m68k_load_gst(m68k_context * context, FILE * gstfile)
1493 {
1494 uint8_t buffer[4096];
1495 fseek(gstfile, GST_68K_REGS, SEEK_SET);
1496 if (fread(buffer, 1, GST_68K_REG_SIZE, gstfile) != GST_68K_REG_SIZE) {
1497 fputs("Failed to read 68K registers from savestate\n", stderr);
1498 return 0;
1499 }
1500 uint8_t * curpos = buffer;
1501 for (int i = 0; i < 8; i++) {
1502 context->dregs[i] = read_le_32(curpos);
1503 curpos += sizeof(uint32_t);
1504 }
1505 for (int i = 0; i < 8; i++) {
1506 context->aregs[i] = read_le_32(curpos);
1507 curpos += sizeof(uint32_t);
1508 }
1509 uint32_t pc = read_le_32(buffer + GST_68K_PC_OFFSET);
1510 uint16_t sr = read_le_16(buffer + GST_68K_SR_OFFSET);
1511 context->status = sr >> 8;
1512 for (int flag = 4; flag >= 0; flag--) {
1513 context->flags[flag] = sr & 1;
1514 sr >>= 1;
1515 }
1516 if (context->status & (1 << 5)) {
1517 context->aregs[8] = read_le_32(buffer + GST_68K_USP_OFFSET);
1518 } else {
1519 context->aregs[8] = read_le_32(buffer + GST_68K_SSP_OFFSET);
1520 }
1521 fseek(gstfile, GST_68K_RAM, SEEK_SET);
1522 for (int i = 0; i < (32*1024);) {
1523 if (fread(buffer, 1, sizeof(buffer), gstfile) != sizeof(buffer)) {
1524 fputs("Failed to read 68K RAM from savestate\n", stderr);
1525 return 0;
1526 }
1527 for(curpos = buffer; curpos < (buffer + sizeof(buffer)); curpos += sizeof(uint16_t)) {
1528 context->mem_pointers[1][i++] = read_be_16(curpos);
1529 }
1530 }
1531 return pc;
1532 }
1533
1534 uint8_t z80_load_gst(z80_context * context, FILE * gstfile)
1535 {
1536 uint8_t regdata[GST_Z80_REG_SIZE];
1537 fseek(gstfile, GST_Z80_REGS, SEEK_SET);
1538 if (fread(regdata, 1, sizeof(regdata), gstfile) != sizeof(regdata)) {
1539 fputs("Failed to read Z80 registers from savestate\n", stderr);
1540 return 0;
1541 }
1542 uint8_t * curpos = regdata;
1543 uint8_t f = *(curpos++);
1544 context->flags[ZF_C] = f & 1;
1545 f >>= 1;
1546 context->flags[ZF_N] = f & 1;
1547 f >>= 1;
1548 context->flags[ZF_PV] = f & 1;
1549 f >>= 2;
1550 context->flags[ZF_H] = f & 1;
1551 f >>= 2;
1552 context->flags[ZF_Z] = f & 1;
1553 f >>= 1;
1554 context->flags[ZF_S] = f;
1555
1556 context->regs[Z80_A] = *curpos;
1557 curpos += 3;
1558 for (int reg = Z80_C; reg <= Z80_IYH; reg++) {
1559 context->regs[reg++] = *(curpos++);
1560 context->regs[reg] = *curpos;
1561 curpos += 3;
1562 }
1563 uint16_t pc = read_le_16(curpos);
1564 curpos += 4;
1565 context->sp = read_le_16(curpos);
1566 curpos += 4;
1567 f = *(curpos++);
1568 context->alt_flags[ZF_C] = f & 1;
1569 f >>= 1;
1570 context->alt_flags[ZF_N] = f & 1;
1571 f >>= 1;
1572 context->alt_flags[ZF_PV] = f & 1;
1573 f >>= 2;
1574 context->alt_flags[ZF_H] = f & 1;
1575 f >>= 2;
1576 context->alt_flags[ZF_Z] = f & 1;
1577 f >>= 1;
1578 context->alt_flags[ZF_S] = f;
1579 context->alt_regs[Z80_A] = *curpos;
1580 curpos += 3;
1581 for (int reg = Z80_C; reg <= Z80_H; reg++) {
1582 context->alt_regs[reg++] = *(curpos++);
1583 context->alt_regs[reg] = *curpos;
1584 curpos += 3;
1585 }
1586 context->regs[Z80_I] = *curpos;
1587 curpos += 2;
1588 context->iff1 = context->iff2 = *curpos;
1589 curpos += 2;
1590 reset = !*(curpos++);
1591 busreq = *curpos;
1592 curpos += 3;
1593 uint32_t bank = read_le_32(curpos);
1594 if (bank < 0x400000) {
1595 context->mem_pointers[1] = context->mem_pointers[2] + bank;
1596 } else {
1597 context->mem_pointers[1] = NULL;
1598 }
1599 context->bank_reg = bank >> 15;
1600 fseek(gstfile, GST_Z80_RAM, SEEK_SET);
1601 if(fread(context->mem_pointers[0], 1, 8*1024, gstfile) != (8*1024)) {
1602 fputs("Failed to read Z80 RAM from savestate\n", stderr);
1603 return 0;
1604 }
1605 context->native_pc = z80_get_native_address_trans(context, pc);
1606 return 1;
1607 }
1608
1609 uint32_t load_gst(genesis_context * gen, char * fname)
1610 {
1611 FILE * gstfile = fopen(fname, "rb");
1612 if (!gstfile) {
1613 fprintf(stderr, "Could not open file %s for reading\n", fname);
1614 goto error;
1615 }
1616 char ident[5];
1617 if (fread(ident, 1, sizeof(ident), gstfile) != sizeof(ident)) {
1618 fprintf(stderr, "Could not read ident code from %s\n", fname);
1619 goto error_close;
1620 }
1621 if (memcmp(ident, "GST\xE0\x40", 3) != 0) {
1622 fprintf(stderr, "%s doesn't appear to be a GST savestate. The ident code is %c%c%c\\x%X\\x%X instead of GST\\xE0\\x40.\n", fname, ident[0], ident[1], ident[2], ident[3], ident[4]);
1623 goto error_close;
1624 }
1625 uint32_t pc = m68k_load_gst(gen->m68k, gstfile);
1626 if (!pc) {
1627 goto error_close;
1628 }
1629 if (!vdp_load_gst(gen->vdp, gstfile)) {
1630 goto error_close;
1631 }
1632 if (!ym_load_gst(gen->ym, gstfile)) {
1633 goto error_close;
1634 }
1635 if (!z80_load_gst(gen->z80, gstfile)) {
1636 goto error_close;
1637 }
1638 gen->ports[0].control = 0x40;
1639 gen->ports[1].control = 0x40;
1640 adjust_int_cycle(gen->m68k, gen->vdp);
1641 fclose(gstfile);
1642 return pc;
1643
1644 error_close:
1645 fclose(gstfile);
1646 error:
1647 return 0;
1648 } 1513 }
1649 1514
1650 #define ROM_END 0x1A4 1515 #define ROM_END 0x1A4
1651 #define RAM_ID 0x1B0 1516 #define RAM_ID 0x1B0
1652 #define RAM_FLAGS 0x1B2 1517 #define RAM_FLAGS 0x1B2
1656 #define RAM_FLAG_MASK 0x1800 1521 #define RAM_FLAG_MASK 0x1800
1657 1522
1658 const memmap_chunk static_map[] = { 1523 const memmap_chunk static_map[] = {
1659 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, 1524 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart,
1660 NULL, NULL, NULL, NULL}, 1525 NULL, NULL, NULL, NULL},
1661 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, 1526 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram,
1662 NULL, NULL, NULL, NULL}, 1527 NULL, NULL, NULL, NULL},
1663 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, 1528 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL,
1664 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, 1529 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1665 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, 1530 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1666 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, 1531 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL,
1709 if (ram_start >= rom_end) { 1574 if (ram_start >= rom_end) {
1710 memmap[0].end = rom_end; 1575 memmap[0].end = rom_end;
1711 memmap[0].mask = 0xFFFFFF; 1576 memmap[0].mask = 0xFFFFFF;
1712 memmap[0].flags = MMAP_READ; 1577 memmap[0].flags = MMAP_READ;
1713 memmap[0].buffer = cart; 1578 memmap[0].buffer = cart;
1714 1579
1715 ram_start &= 0xFFFFFE; 1580 ram_start &= 0xFFFFFE;
1716 ram_end |= 1; 1581 ram_end |= 1;
1717 memmap[1].start = ram_start; 1582 memmap[1].start = ram_start;
1718 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; 1583 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start;
1719 ram_end += 1; 1584 ram_end += 1;
1726 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { 1591 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) {
1727 memmap[1].flags |= MMAP_ONLY_EVEN; 1592 memmap[1].flags |= MMAP_ONLY_EVEN;
1728 size /= 2; 1593 size /= 2;
1729 } 1594 }
1730 memmap[1].buffer = gen->save_ram = malloc(size); 1595 memmap[1].buffer = gen->save_ram = malloc(size);
1731 1596
1732 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); 1597 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0]));
1733 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; 1598 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1;
1734 } else { 1599 } else {
1735 //Assume the standard Sega mapper for now 1600 //Assume the standard Sega mapper for now
1736 memmap[0].end = 0x200000; 1601 memmap[0].end = 0x200000;
1737 memmap[0].mask = 0xFFFFFF; 1602 memmap[0].mask = 0xFFFFFF;
1738 memmap[0].flags = MMAP_READ; 1603 memmap[0].flags = MMAP_READ;
1739 memmap[0].buffer = cart; 1604 memmap[0].buffer = cart;
1740 1605
1741 memmap[1].start = 0x200000; 1606 memmap[1].start = 0x200000;
1742 memmap[1].end = 0x400000; 1607 memmap[1].end = 0x400000;
1743 memmap[1].mask = 0x1FFFFF; 1608 memmap[1].mask = 0x1FFFFF;
1744 ram_start &= 0xFFFFFE; 1609 ram_start &= 0xFFFFFE;
1745 ram_end |= 1; 1610 ram_end |= 1;
1755 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); 1620 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks]));
1756 memmap[num_chunks].start = 0xA13000; 1621 memmap[num_chunks].start = 0xA13000;
1757 memmap[num_chunks].end = 0xA13100; 1622 memmap[num_chunks].end = 0xA13100;
1758 memmap[num_chunks].mask = 0xFF; 1623 memmap[num_chunks].mask = 0xFF;
1759 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w; 1624 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w;
1760 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b; 1625 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b;
1761 num_chunks++; 1626 num_chunks++;
1762 ram_end++; 1627 ram_end++;
1763 size = ram_end-ram_start; 1628 size = ram_end-ram_start;
1764 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { 1629 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) {
1765 size /= 2; 1630 size /= 2;
1784 atexit(save_sram); 1649 atexit(save_sram);
1785 } 1650 }
1786 init_x86_68k_opts(&opts, memmap, num_chunks); 1651 init_x86_68k_opts(&opts, memmap, num_chunks);
1787 opts.address_log = address_log; 1652 opts.address_log = address_log;
1788 init_68k_context(&context, opts.native_code_map, &opts); 1653 init_68k_context(&context, opts.native_code_map, &opts);
1789 1654
1790 context.video_context = gen->vdp; 1655 context.video_context = gen->vdp;
1791 context.system = gen; 1656 context.system = gen;
1792 //cartridge ROM 1657 //cartridge ROM
1793 context.mem_pointers[0] = cart; 1658 context.mem_pointers[0] = cart;
1794 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; 1659 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K;
1801 address = cart[2] << 16 | cart[3]; 1666 address = cart[2] << 16 | cart[3];
1802 translate_m68k_stream(address, &context); 1667 translate_m68k_stream(address, &context);
1803 if (statefile) { 1668 if (statefile) {
1804 uint32_t pc = load_gst(gen, statefile); 1669 uint32_t pc = load_gst(gen, statefile);
1805 if (!pc) { 1670 if (!pc) {
1671 fprintf(stderr, "Failed to load save state %s\n", statefile);
1806 exit(1); 1672 exit(1);
1807 } 1673 }
1674 printf("Loaded %s\n", statefile);
1808 if (debug) { 1675 if (debug) {
1809 insert_breakpoint(&context, pc, (uint8_t *)debugger); 1676 insert_breakpoint(&context, pc, (uint8_t *)debugger);
1810 } 1677 }
1678 adjust_int_cycle(gen->m68k, gen->vdp);
1679 gen->z80->native_pc = z80_get_native_address_trans(gen->z80, gen->z80->pc);
1811 start_68k_context(&context, pc); 1680 start_68k_context(&context, pc);
1812 } else { 1681 } else {
1813 if (debug) { 1682 if (debug) {
1814 insert_breakpoint(&context, address, (uint8_t *)debugger); 1683 insert_breakpoint(&context, address, (uint8_t *)debugger);
1815 } 1684 }
1863 version_reg = NO_DISK | USA; 1732 version_reg = NO_DISK | USA;
1864 } else if (detect_specific_region('J')) { 1733 } else if (detect_specific_region('J')) {
1865 version_reg = NO_DISK | JAP; 1734 version_reg = NO_DISK | JAP;
1866 } else if (detect_specific_region('E') || detect_specific_region('A')) { 1735 } else if (detect_specific_region('E') || detect_specific_region('A')) {
1867 version_reg = NO_DISK | EUR; 1736 version_reg = NO_DISK | EUR;
1737 } else {
1738 char * def_region = tern_find_ptr(config, "default_region");
1739 if (def_region) {
1740 switch(*def_region)
1741 {
1742 case 'j':
1743 case 'J':
1744 version_reg = NO_DISK | JAP;
1745 break;
1746 case 'u':
1747 case 'U':
1748 version_reg = NO_DISK | USA;
1749 break;
1750 case 'e':
1751 case 'E':
1752 version_reg = NO_DISK | EUR;
1753 break;
1754 }
1755 }
1868 } 1756 }
1869 } 1757 }
1870 1758
1871 int main(int argc, char ** argv) 1759 int main(int argc, char ** argv)
1872 { 1760 {
1873 if (argc < 2) { 1761 if (argc < 2) {
1874 fputs("Usage: blastem FILENAME\n", stderr); 1762 fputs("Usage: blastem [OPTIONS] ROMFILE [WIDTH] [HEIGHT]\n", stderr);
1875 return 1; 1763 return 1;
1876 } 1764 }
1877 if(!load_rom(argv[1])) { 1765 config = load_config(argv[0]);
1878 fprintf(stderr, "Failed to open %s for reading\n", argv[1]);
1879 return 1;
1880 }
1881 detect_region(); 1766 detect_region();
1882 int width = -1; 1767 int width = -1;
1883 int height = -1; 1768 int height = -1;
1884 int debug = 0; 1769 int debug = 0;
1885 int ym_log = 0; 1770 int ym_log = 0;
1771 int loaded = 0;
1772 uint8_t force_version = 0;
1773 char * romfname = NULL;
1886 FILE *address_log = NULL; 1774 FILE *address_log = NULL;
1887 char * statefile = NULL; 1775 char * statefile = NULL;
1888 for (int i = 2; i < argc; i++) { 1776 uint8_t fullscreen = 0;
1777 for (int i = 1; i < argc; i++) {
1889 if (argv[i][0] == '-') { 1778 if (argv[i][0] == '-') {
1890 switch(argv[i][1]) { 1779 switch(argv[i][1]) {
1891 case 'd': 1780 case 'd':
1892 debug = 1; 1781 debug = 1;
1893 break; 1782 break;
1894 case 'f': 1783 case 'f':
1895 frame_limit = 1; 1784 fullscreen = 1;
1896 break; 1785 break;
1897 case 'l': 1786 case 'l':
1898 address_log = fopen("address.log", "w"); 1787 address_log = fopen("address.log", "w");
1899 break; 1788 break;
1900 case 'v': 1789 case 'v':
1901 headless = 1; 1790 printf("blastem %s\n", BLASTEM_VERSION);
1791 return 0;
1902 break; 1792 break;
1903 case 'n': 1793 case 'n':
1904 z80_enabled = 0; 1794 z80_enabled = 0;
1905 break; 1795 break;
1906 case 'r': 1796 case 'r':
1911 } 1801 }
1912 switch (argv[i][0]) 1802 switch (argv[i][0])
1913 { 1803 {
1914 case 'j': 1804 case 'j':
1915 case 'J': 1805 case 'J':
1916 version_reg = NO_DISK | JAP; 1806 force_version = NO_DISK | JAP;
1917 break; 1807 break;
1918 case 'u': 1808 case 'u':
1919 case 'U': 1809 case 'U':
1920 version_reg = NO_DISK | USA; 1810 force_version = NO_DISK | USA;
1921 break; 1811 break;
1922 case 'e': 1812 case 'e':
1923 case 'E': 1813 case 'E':
1924 version_reg = NO_DISK | EUR; 1814 force_version = NO_DISK | EUR;
1925 break; 1815 break;
1926 default: 1816 default:
1927 fprintf(stderr, "'%c' is not a valid region character for the -r option\n", argv[i][0]); 1817 fprintf(stderr, "'%c' is not a valid region character for the -r option\n", argv[i][0]);
1928 return 1; 1818 return 1;
1929 } 1819 }
1937 statefile = argv[i]; 1827 statefile = argv[i];
1938 break; 1828 break;
1939 case 'y': 1829 case 'y':
1940 ym_log = 1; 1830 ym_log = 1;
1941 break; 1831 break;
1832 case 'h':
1833 puts(
1834 "Usage: blastem [OPTIONS] ROMFILE [WIDTH] [HEIGHT]\n"
1835 "Options:\n"
1836 " -h Print this help text\n"
1837 " -r (J|U|E) Force region to Japan, US or Europe respectively\n"
1838 " -f Start in fullscreen mode\n"
1839 " -s FILE Load a GST format savestate from FILE\n"
1840 " -d Enter debugger on startup\n"
1841 " -n Disable Z80\n"
1842 " -v Display version number and exit\n"
1843 " -l Log 68K code addresses (useful for assemblers)\n"
1844 " -y Log individual YM-2612 channels to WAVE files\n"
1845 );
1846 return 0;
1942 default: 1847 default:
1943 fprintf(stderr, "Unrecognized switch %s\n", argv[i]); 1848 fprintf(stderr, "Unrecognized switch %s\n", argv[i]);
1944 return 1; 1849 return 1;
1945 } 1850 }
1851 } else if (!loaded) {
1852 if(!load_rom(argv[i])) {
1853 fprintf(stderr, "Failed to open %s for reading\n", argv[i]);
1854 return 1;
1855 }
1856 romfname = argv[i];
1857 loaded = 1;
1946 } else if (width < 0) { 1858 } else if (width < 0) {
1947 width = atoi(argv[i]); 1859 width = atoi(argv[i]);
1948 } else if (height < 0) { 1860 } else if (height < 0) {
1949 height = atoi(argv[i]); 1861 height = atoi(argv[i]);
1950 } 1862 }
1951 } 1863 }
1864 if (!loaded) {
1865 fputs("You must specify a ROM filename!\n", stderr);
1866 return 1;
1867 }
1868 if (force_version) {
1869 version_reg = force_version;
1870 }
1952 update_title(); 1871 update_title();
1953 width = width < 320 ? 640 : width; 1872 int def_width = 0;
1873 char *config_width = tern_find_ptr(config, "videowidth");
1874 if (config_width) {
1875 def_width = atoi(config_width);
1876 }
1877 if (!def_width) {
1878 def_width = 640;
1879 }
1880 width = width < 320 ? def_width : width;
1954 height = height < 240 ? (width/320) * 240 : height; 1881 height = height < 240 ? (width/320) * 240 : height;
1955 uint32_t fps = 60; 1882 uint32_t fps = 60;
1956 if (version_reg & 0x40) { 1883 if (version_reg & 0x40) {
1957 mclks_per_frame = MCLKS_LINE * LINES_PAL; 1884 mclks_per_frame = MCLKS_LINE * LINES_PAL;
1958 fps = 50; 1885 fps = 50;
1959 } 1886 }
1960 if (!headless) { 1887 if (!headless) {
1961 render_init(width, height, title, fps, 0); 1888 render_init(width, height, title, fps, fullscreen, 0);
1962 } 1889 }
1963 vdp_context v_context; 1890 vdp_context v_context;
1964 1891 genesis_context gen;
1892 memset(&gen, 0, sizeof(gen));
1893 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL;
1894
1965 init_vdp_context(&v_context); 1895 init_vdp_context(&v_context);
1966 1896
1967 ym2612_context y_context; 1897 ym2612_context y_context;
1968 ym_init(&y_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); 1898 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0);
1969 1899
1970 psg_context p_context; 1900 psg_context p_context;
1971 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer()); 1901 psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer());
1972 1902
1973 z80_context z_context; 1903 z80_context z_context;
1974 x86_z80_options z_opts; 1904 x86_z80_options z_opts;
1975 init_x86_z80_opts(&z_opts); 1905 init_x86_z80_opts(&z_opts);
1976 init_z80_context(&z_context, &z_opts); 1906 init_z80_context(&z_context, &z_opts);
1977
1978 genesis_context gen;
1979 memset(&gen, 0, sizeof(gen));
1980 1907
1981 z_context.system = &gen; 1908 z_context.system = &gen;
1982 z_context.mem_pointers[0] = z80_ram; 1909 z_context.mem_pointers[0] = z80_ram;
1983 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; 1910 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80;
1984 z_context.int_cycle = CYCLE_NEVER; 1911 z_context.int_cycle = CYCLE_NEVER;
1985 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 1912 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
1986 1913
1987 gen.z80 = &z_context; 1914 gen.z80 = &z_context;
1988 gen.vdp = &v_context; 1915 gen.vdp = &v_context;
1989 gen.ym = &y_context; 1916 gen.ym = &y_context;
1990 gen.psg = &p_context; 1917 gen.psg = &p_context;
1991 genesis = &gen; 1918 genesis = &gen;
1992 1919
1993 int fname_size = strlen(argv[1]); 1920 int fname_size = strlen(romfname);
1994 sram_filename = malloc(fname_size+6); 1921 sram_filename = malloc(fname_size+6);
1995 memcpy(sram_filename, argv[1], fname_size); 1922 memcpy(sram_filename, romfname, fname_size);
1996 int i; 1923 int i;
1997 for (i = fname_size-1; fname_size >= 0; --i) { 1924 for (i = fname_size-1; fname_size >= 0; --i) {
1998 if (sram_filename[i] == '.') { 1925 if (sram_filename[i] == '.') {
1999 strcpy(sram_filename + i + 1, "sram"); 1926 strcpy(sram_filename + i + 1, "sram");
2000 break; 1927 break;
2002 } 1929 }
2003 if (i < 0) { 1930 if (i < 0) {
2004 strcpy(sram_filename + fname_size, ".sram"); 1931 strcpy(sram_filename + fname_size, ".sram");
2005 } 1932 }
2006 set_keybindings(); 1933 set_keybindings();
2007 1934
2008 init_run_cpu(&gen, debug, address_log, statefile); 1935 init_run_cpu(&gen, debug, address_log, statefile);
2009 return 0; 1936 return 0;
2010 } 1937 }