comparison blastem.c @ 447:e730fc040169

Fix performance regression from stop instruction work
author Mike Pavone <pavone@retrodev.com>
date Sat, 20 Jul 2013 23:40:28 -0700
parents 1e828ed04a7c
children 3758bcdae5de b7c3b2d22858
comparison
equal deleted inserted replaced
446:1e828ed04a7c 447:e730fc040169
50 int load_smd_rom(long filesize, FILE * f) 50 int load_smd_rom(long filesize, FILE * f)
51 { 51 {
52 uint8_t block[SMD_BLOCK_SIZE]; 52 uint8_t block[SMD_BLOCK_SIZE];
53 filesize -= SMD_HEADER_SIZE; 53 filesize -= SMD_HEADER_SIZE;
54 fseek(f, SMD_HEADER_SIZE, SEEK_SET); 54 fseek(f, SMD_HEADER_SIZE, SEEK_SET);
55 55
56 uint16_t * dst = cart; 56 uint16_t * dst = cart;
57 while (filesize > 0) { 57 while (filesize > 0) {
58 fread(block, 1, SMD_BLOCK_SIZE, f); 58 fread(block, 1, SMD_BLOCK_SIZE, f);
59 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) { 59 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) {
60 *(dst++) = *high << 8 | *low; 60 *(dst++) = *high << 8 | *low;
137 if (next_hint != CYCLE_NEVER) { 137 if (next_hint != CYCLE_NEVER) {
138 next_hint /= MCLKS_PER_68K; 138 next_hint /= MCLKS_PER_68K;
139 if (next_hint < context->int_cycle) { 139 if (next_hint < context->int_cycle) {
140 context->int_cycle = next_hint; 140 context->int_cycle = next_hint;
141 context->int_num = 4; 141 context->int_num = 4;
142 142
143 } 143 }
144 } 144 }
145 } 145 }
146 } 146 }
147 147
148 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle; 148 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle;
149 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n", 149 /*printf("Cyc: %d, Trgt: %d, Int Cyc: %d, Int: %d, Mask: %X, V: %d, H: %d, HICount: %d, HReg: %d, Line: %d\n",
150 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7), 150 context->current_cycle, context->target_cycle, context->int_cycle, context->int_num, (context->status & 0x7),
151 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);*/ 151 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);*/
152 } 152 }
153 153
154 int break_on_sync = 0; 154 int break_on_sync = 0;
155 155
197 void sync_sound(genesis_context * gen, uint32_t target) 197 void sync_sound(genesis_context * gen, uint32_t target)
198 { 198 {
199 //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); 199 //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);
200 psg_run(gen->psg, target); 200 psg_run(gen->psg, target);
201 ym_run(gen->ym, target); 201 ym_run(gen->ym, target);
202 202
203 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 203 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
204 } 204 }
205 205
206 uint32_t frame=0; 206 uint32_t frame=0;
207 m68k_context * sync_components(m68k_context * context, uint32_t address) 207 m68k_context * sync_components(m68k_context * context, uint32_t address)
219 if (gen->ym->write_cycle != CYCLE_NEVER) { 219 if (gen->ym->write_cycle != CYCLE_NEVER) {
220 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; 220 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;
221 } 221 }
222 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 222 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
223 vdp_run_context(v_context, mclks_per_frame); 223 vdp_run_context(v_context, mclks_per_frame);
224 224
225 if (!headless) { 225 if (!headless) {
226 break_on_sync |= wait_render_frame(v_context, frame_limit); 226 break_on_sync |= wait_render_frame(v_context, frame_limit);
227 } 227 }
228 frame++; 228 frame++;
229 mclks -= mclks_per_frame; 229 mclks -= mclks_per_frame;
256 if (context->int_ack) { 256 if (context->int_ack) {
257 vdp_int_ack(v_context, context->int_ack); 257 vdp_int_ack(v_context, context->int_ack);
258 context->int_ack = 0; 258 context->int_ack = 0;
259 } 259 }
260 adjust_int_cycle(context, v_context); 260 adjust_int_cycle(context, v_context);
261 if (context->current_cycle <= context->sync_cycle) {
262 context->sync_cycle = context->current_cycle + 4;
263 if (context->sync_cycle < context->int_cycle) {
264 context->target_cycle = context->sync_cycle;
265 }
266 }
267 if (break_on_sync && address) { 261 if (break_on_sync && address) {
268 break_on_sync = 0; 262 break_on_sync = 0;
269 debugger(context, address); 263 debugger(context, address);
270 } 264 }
271 return context; 265 return context;
502 busack = new_busack; 496 busack = new_busack;
503 busack_cycle = CYCLE_NEVER; 497 busack_cycle = CYCLE_NEVER;
504 } 498 }
505 if (value & 1) { 499 if (value & 1) {
506 dputs("bus requesting Z80"); 500 dputs("bus requesting Z80");
507 501
508 if(!reset && !busreq) { 502 if(!reset && !busreq) {
509 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY; 503 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
510 new_busack = Z80_REQ_ACK; 504 new_busack = Z80_REQ_ACK;
511 } 505 }
512 busreq = 1; 506 busreq = 1;
524 new_busack = Z80_REQ_BUSY; 518 new_busack = Z80_REQ_BUSY;
525 busreq = 0; 519 busreq = 0;
526 } 520 }
527 //busack_cycle = CYCLE_NEVER; 521 //busack_cycle = CYCLE_NEVER;
528 //busack = Z80_REQ_BUSY; 522 //busack = Z80_REQ_BUSY;
529 523
530 } 524 }
531 } else if (location == 0x1200) { 525 } else if (location == 0x1200) {
532 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 526 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
533 if (value & 1) { 527 if (value & 1) {
534 if (reset && busreq) { 528 if (reset && busreq) {
1439 case 'z': { 1433 case 'z': {
1440 genesis_context * gen = context->system; 1434 genesis_context * gen = context->system;
1441 //Z80 debug commands 1435 //Z80 debug commands
1442 switch(input_buf[1]) 1436 switch(input_buf[1])
1443 { 1437 {
1444 case 'b': 1438 case 'b':
1445 param = find_param(input_buf); 1439 param = find_param(input_buf);
1446 if (!param) { 1440 if (!param) {
1447 fputs("zb command requires a parameter\n", stderr); 1441 fputs("zb command requires a parameter\n", stderr);
1448 break; 1442 break;
1449 } 1443 }
1558 context->flags[ZF_H] = f & 1; 1552 context->flags[ZF_H] = f & 1;
1559 f >>= 2; 1553 f >>= 2;
1560 context->flags[ZF_Z] = f & 1; 1554 context->flags[ZF_Z] = f & 1;
1561 f >>= 1; 1555 f >>= 1;
1562 context->flags[ZF_S] = f; 1556 context->flags[ZF_S] = f;
1563 1557
1564 context->regs[Z80_A] = *curpos; 1558 context->regs[Z80_A] = *curpos;
1565 curpos += 3; 1559 curpos += 3;
1566 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { 1560 for (int reg = Z80_C; reg <= Z80_IYH; reg++) {
1567 context->regs[reg++] = *(curpos++); 1561 context->regs[reg++] = *(curpos++);
1568 context->regs[reg] = *curpos; 1562 context->regs[reg] = *curpos;
1646 gen->ports[0].control = 0x40; 1640 gen->ports[0].control = 0x40;
1647 gen->ports[1].control = 0x40; 1641 gen->ports[1].control = 0x40;
1648 adjust_int_cycle(gen->m68k, gen->vdp); 1642 adjust_int_cycle(gen->m68k, gen->vdp);
1649 fclose(gstfile); 1643 fclose(gstfile);
1650 return pc; 1644 return pc;
1651 1645
1652 error_close: 1646 error_close:
1653 fclose(gstfile); 1647 fclose(gstfile);
1654 error: 1648 error:
1655 return 0; 1649 return 0;
1656 } 1650 }
1664 #define RAM_FLAG_MASK 0x1800 1658 #define RAM_FLAG_MASK 0x1800
1665 1659
1666 const memmap_chunk static_map[] = { 1660 const memmap_chunk static_map[] = {
1667 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, 1661 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart,
1668 NULL, NULL, NULL, NULL}, 1662 NULL, NULL, NULL, NULL},
1669 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, 1663 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram,
1670 NULL, NULL, NULL, NULL}, 1664 NULL, NULL, NULL, NULL},
1671 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, 1665 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL,
1672 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, 1666 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1673 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, 1667 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1674 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, 1668 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL,
1717 if (ram_start >= rom_end) { 1711 if (ram_start >= rom_end) {
1718 memmap[0].end = rom_end; 1712 memmap[0].end = rom_end;
1719 memmap[0].mask = 0xFFFFFF; 1713 memmap[0].mask = 0xFFFFFF;
1720 memmap[0].flags = MMAP_READ; 1714 memmap[0].flags = MMAP_READ;
1721 memmap[0].buffer = cart; 1715 memmap[0].buffer = cart;
1722 1716
1723 ram_start &= 0xFFFFFE; 1717 ram_start &= 0xFFFFFE;
1724 ram_end |= 1; 1718 ram_end |= 1;
1725 memmap[1].start = ram_start; 1719 memmap[1].start = ram_start;
1726 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; 1720 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start;
1727 ram_end += 1; 1721 ram_end += 1;
1734 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { 1728 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) {
1735 memmap[1].flags |= MMAP_ONLY_EVEN; 1729 memmap[1].flags |= MMAP_ONLY_EVEN;
1736 size /= 2; 1730 size /= 2;
1737 } 1731 }
1738 memmap[1].buffer = gen->save_ram = malloc(size); 1732 memmap[1].buffer = gen->save_ram = malloc(size);
1739 1733
1740 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); 1734 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0]));
1741 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; 1735 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1;
1742 } else { 1736 } else {
1743 //Assume the standard Sega mapper for now 1737 //Assume the standard Sega mapper for now
1744 memmap[0].end = 0x200000; 1738 memmap[0].end = 0x200000;
1745 memmap[0].mask = 0xFFFFFF; 1739 memmap[0].mask = 0xFFFFFF;
1746 memmap[0].flags = MMAP_READ; 1740 memmap[0].flags = MMAP_READ;
1747 memmap[0].buffer = cart; 1741 memmap[0].buffer = cart;
1748 1742
1749 memmap[1].start = 0x200000; 1743 memmap[1].start = 0x200000;
1750 memmap[1].end = 0x400000; 1744 memmap[1].end = 0x400000;
1751 memmap[1].mask = 0x1FFFFF; 1745 memmap[1].mask = 0x1FFFFF;
1752 ram_start &= 0xFFFFFE; 1746 ram_start &= 0xFFFFFE;
1753 ram_end |= 1; 1747 ram_end |= 1;
1763 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); 1757 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks]));
1764 memmap[num_chunks].start = 0xA13000; 1758 memmap[num_chunks].start = 0xA13000;
1765 memmap[num_chunks].end = 0xA13100; 1759 memmap[num_chunks].end = 0xA13100;
1766 memmap[num_chunks].mask = 0xFF; 1760 memmap[num_chunks].mask = 0xFF;
1767 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w; 1761 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w;
1768 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b; 1762 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b;
1769 num_chunks++; 1763 num_chunks++;
1770 ram_end++; 1764 ram_end++;
1771 size = ram_end-ram_start; 1765 size = ram_end-ram_start;
1772 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { 1766 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) {
1773 size /= 2; 1767 size /= 2;
1792 atexit(save_sram); 1786 atexit(save_sram);
1793 } 1787 }
1794 init_x86_68k_opts(&opts, memmap, num_chunks); 1788 init_x86_68k_opts(&opts, memmap, num_chunks);
1795 opts.address_log = address_log; 1789 opts.address_log = address_log;
1796 init_68k_context(&context, opts.native_code_map, &opts); 1790 init_68k_context(&context, opts.native_code_map, &opts);
1797 1791
1798 context.video_context = gen->vdp; 1792 context.video_context = gen->vdp;
1799 context.system = gen; 1793 context.system = gen;
1800 //cartridge ROM 1794 //cartridge ROM
1801 context.mem_pointers[0] = cart; 1795 context.mem_pointers[0] = cart;
1802 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; 1796 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K;
1996 } 1990 }
1997 if (!headless) { 1991 if (!headless) {
1998 render_init(width, height, title, fps, fullscreen); 1992 render_init(width, height, title, fps, fullscreen);
1999 } 1993 }
2000 vdp_context v_context; 1994 vdp_context v_context;
2001 1995
2002 init_vdp_context(&v_context); 1996 init_vdp_context(&v_context);
2003 1997
2004 ym2612_context y_context; 1998 ym2612_context y_context;
2005 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); 1999 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);
2006 2000
2007 psg_context p_context; 2001 psg_context p_context;
2008 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer()); 2002 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer());
2009 2003
2010 z80_context z_context; 2004 z80_context z_context;
2011 x86_z80_options z_opts; 2005 x86_z80_options z_opts;
2012 init_x86_z80_opts(&z_opts); 2006 init_x86_z80_opts(&z_opts);
2013 init_z80_context(&z_context, &z_opts); 2007 init_z80_context(&z_context, &z_opts);
2014 2008
2018 z_context.system = &gen; 2012 z_context.system = &gen;
2019 z_context.mem_pointers[0] = z80_ram; 2013 z_context.mem_pointers[0] = z80_ram;
2020 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; 2014 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80;
2021 z_context.int_cycle = CYCLE_NEVER; 2015 z_context.int_cycle = CYCLE_NEVER;
2022 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 2016 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
2023 2017
2024 gen.z80 = &z_context; 2018 gen.z80 = &z_context;
2025 gen.vdp = &v_context; 2019 gen.vdp = &v_context;
2026 gen.ym = &y_context; 2020 gen.ym = &y_context;
2027 gen.psg = &p_context; 2021 gen.psg = &p_context;
2028 genesis = &gen; 2022 genesis = &gen;
2029 2023
2030 int fname_size = strlen(argv[1]); 2024 int fname_size = strlen(argv[1]);
2031 sram_filename = malloc(fname_size+6); 2025 sram_filename = malloc(fname_size+6);
2032 memcpy(sram_filename, argv[1], fname_size); 2026 memcpy(sram_filename, argv[1], fname_size);
2033 int i; 2027 int i;
2034 for (i = fname_size-1; fname_size >= 0; --i) { 2028 for (i = fname_size-1; fname_size >= 0; --i) {
2039 } 2033 }
2040 if (i < 0) { 2034 if (i < 0) {
2041 strcpy(sram_filename + fname_size, ".sram"); 2035 strcpy(sram_filename + fname_size, ".sram");
2042 } 2036 }
2043 set_keybindings(); 2037 set_keybindings();
2044 2038
2045 init_run_cpu(&gen, debug, address_log, statefile); 2039 init_run_cpu(&gen, debug, address_log, statefile);
2046 return 0; 2040 return 0;
2047 } 2041 }