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