Mercurial > repos > blastem
comparison blastem.c @ 449:7696d824489d opengl
Started work on OpenGL support in new branch
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 23 Jul 2013 23:01:03 -0700 |
parents | 8b3ae850d1c4 |
children | c08a4efeee7f |
comparison
equal
deleted
inserted
replaced
428:006008a3f370 | 449:7696d824489d |
---|---|
48 int load_smd_rom(long filesize, FILE * f) | 48 int load_smd_rom(long filesize, FILE * f) |
49 { | 49 { |
50 uint8_t block[SMD_BLOCK_SIZE]; | 50 uint8_t block[SMD_BLOCK_SIZE]; |
51 filesize -= SMD_HEADER_SIZE; | 51 filesize -= SMD_HEADER_SIZE; |
52 fseek(f, SMD_HEADER_SIZE, SEEK_SET); | 52 fseek(f, SMD_HEADER_SIZE, SEEK_SET); |
53 | 53 |
54 uint16_t * dst = cart; | 54 uint16_t * dst = cart; |
55 while (filesize > 0) { | 55 while (filesize > 0) { |
56 fread(block, 1, SMD_BLOCK_SIZE, f); | 56 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++) { | 57 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; | 58 *(dst++) = *high << 8 | *low; |
135 if (next_hint != CYCLE_NEVER) { | 135 if (next_hint != CYCLE_NEVER) { |
136 next_hint /= MCLKS_PER_68K; | 136 next_hint /= MCLKS_PER_68K; |
137 if (next_hint < context->int_cycle) { | 137 if (next_hint < context->int_cycle) { |
138 context->int_cycle = next_hint; | 138 context->int_cycle = next_hint; |
139 context->int_num = 4; | 139 context->int_num = 4; |
140 | 140 |
141 } | 141 } |
142 } | 142 } |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle; | 146 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", | 147 /*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), | 148 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);*/ | 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);*/ |
150 } | 150 } |
151 | 151 |
152 int break_on_sync = 0; | 152 int break_on_sync = 0; |
153 | 153 |
195 void sync_sound(genesis_context * gen, uint32_t target) | 195 void sync_sound(genesis_context * gen, uint32_t target) |
196 { | 196 { |
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); | 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); |
198 psg_run(gen->psg, target); | 198 psg_run(gen->psg, target); |
199 ym_run(gen->ym, target); | 199 ym_run(gen->ym, target); |
200 | 200 |
201 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); | 201 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); |
202 } | 202 } |
203 | 203 |
204 uint32_t frame=0; | 204 uint32_t frame=0; |
205 m68k_context * sync_components(m68k_context * context, uint32_t address) | 205 m68k_context * sync_components(m68k_context * context, uint32_t address) |
217 if (gen->ym->write_cycle != CYCLE_NEVER) { | 217 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; | 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; |
219 } | 219 } |
220 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); | 220 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); |
221 vdp_run_context(v_context, mclks_per_frame); | 221 vdp_run_context(v_context, mclks_per_frame); |
222 | 222 |
223 if (!headless) { | 223 if (!headless) { |
224 break_on_sync |= wait_render_frame(v_context, frame_limit); | 224 break_on_sync |= wait_render_frame(v_context, frame_limit); |
225 } | 225 } |
226 frame++; | 226 frame++; |
227 mclks -= mclks_per_frame; | 227 mclks -= mclks_per_frame; |
494 busack = new_busack; | 494 busack = new_busack; |
495 busack_cycle = CYCLE_NEVER; | 495 busack_cycle = CYCLE_NEVER; |
496 } | 496 } |
497 if (value & 1) { | 497 if (value & 1) { |
498 dputs("bus requesting Z80"); | 498 dputs("bus requesting Z80"); |
499 | 499 |
500 if(!reset && !busreq) { | 500 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; | 501 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY; |
502 new_busack = Z80_REQ_ACK; | 502 new_busack = Z80_REQ_ACK; |
503 } | 503 } |
504 busreq = 1; | 504 busreq = 1; |
516 new_busack = Z80_REQ_BUSY; | 516 new_busack = Z80_REQ_BUSY; |
517 busreq = 0; | 517 busreq = 0; |
518 } | 518 } |
519 //busack_cycle = CYCLE_NEVER; | 519 //busack_cycle = CYCLE_NEVER; |
520 //busack = Z80_REQ_BUSY; | 520 //busack = Z80_REQ_BUSY; |
521 | 521 |
522 } | 522 } |
523 } else if (location == 0x1200) { | 523 } else if (location == 0x1200) { |
524 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); | 524 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); |
525 if (value & 1) { | 525 if (value & 1) { |
526 if (reset && busreq) { | 526 if (reset && busreq) { |
1431 case 'z': { | 1431 case 'z': { |
1432 genesis_context * gen = context->system; | 1432 genesis_context * gen = context->system; |
1433 //Z80 debug commands | 1433 //Z80 debug commands |
1434 switch(input_buf[1]) | 1434 switch(input_buf[1]) |
1435 { | 1435 { |
1436 case 'b': | 1436 case 'b': |
1437 param = find_param(input_buf); | 1437 param = find_param(input_buf); |
1438 if (!param) { | 1438 if (!param) { |
1439 fputs("zb command requires a parameter\n", stderr); | 1439 fputs("zb command requires a parameter\n", stderr); |
1440 break; | 1440 break; |
1441 } | 1441 } |
1550 context->flags[ZF_H] = f & 1; | 1550 context->flags[ZF_H] = f & 1; |
1551 f >>= 2; | 1551 f >>= 2; |
1552 context->flags[ZF_Z] = f & 1; | 1552 context->flags[ZF_Z] = f & 1; |
1553 f >>= 1; | 1553 f >>= 1; |
1554 context->flags[ZF_S] = f; | 1554 context->flags[ZF_S] = f; |
1555 | 1555 |
1556 context->regs[Z80_A] = *curpos; | 1556 context->regs[Z80_A] = *curpos; |
1557 curpos += 3; | 1557 curpos += 3; |
1558 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { | 1558 for (int reg = Z80_C; reg <= Z80_IYH; reg++) { |
1559 context->regs[reg++] = *(curpos++); | 1559 context->regs[reg++] = *(curpos++); |
1560 context->regs[reg] = *curpos; | 1560 context->regs[reg] = *curpos; |
1638 gen->ports[0].control = 0x40; | 1638 gen->ports[0].control = 0x40; |
1639 gen->ports[1].control = 0x40; | 1639 gen->ports[1].control = 0x40; |
1640 adjust_int_cycle(gen->m68k, gen->vdp); | 1640 adjust_int_cycle(gen->m68k, gen->vdp); |
1641 fclose(gstfile); | 1641 fclose(gstfile); |
1642 return pc; | 1642 return pc; |
1643 | 1643 |
1644 error_close: | 1644 error_close: |
1645 fclose(gstfile); | 1645 fclose(gstfile); |
1646 error: | 1646 error: |
1647 return 0; | 1647 return 0; |
1648 } | 1648 } |
1656 #define RAM_FLAG_MASK 0x1800 | 1656 #define RAM_FLAG_MASK 0x1800 |
1657 | 1657 |
1658 const memmap_chunk static_map[] = { | 1658 const memmap_chunk static_map[] = { |
1659 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, | 1659 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, |
1660 NULL, NULL, NULL, NULL}, | 1660 NULL, NULL, NULL, NULL}, |
1661 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, | 1661 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, |
1662 NULL, NULL, NULL, NULL}, | 1662 NULL, NULL, NULL, NULL}, |
1663 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, | 1663 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, |
1664 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, | 1664 (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}, | 1665 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, |
1666 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, | 1666 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, |
1709 if (ram_start >= rom_end) { | 1709 if (ram_start >= rom_end) { |
1710 memmap[0].end = rom_end; | 1710 memmap[0].end = rom_end; |
1711 memmap[0].mask = 0xFFFFFF; | 1711 memmap[0].mask = 0xFFFFFF; |
1712 memmap[0].flags = MMAP_READ; | 1712 memmap[0].flags = MMAP_READ; |
1713 memmap[0].buffer = cart; | 1713 memmap[0].buffer = cart; |
1714 | 1714 |
1715 ram_start &= 0xFFFFFE; | 1715 ram_start &= 0xFFFFFE; |
1716 ram_end |= 1; | 1716 ram_end |= 1; |
1717 memmap[1].start = ram_start; | 1717 memmap[1].start = ram_start; |
1718 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; | 1718 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; |
1719 ram_end += 1; | 1719 ram_end += 1; |
1726 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { | 1726 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { |
1727 memmap[1].flags |= MMAP_ONLY_EVEN; | 1727 memmap[1].flags |= MMAP_ONLY_EVEN; |
1728 size /= 2; | 1728 size /= 2; |
1729 } | 1729 } |
1730 memmap[1].buffer = gen->save_ram = malloc(size); | 1730 memmap[1].buffer = gen->save_ram = malloc(size); |
1731 | 1731 |
1732 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); | 1732 memcpy(memmap+2, static_map+1, sizeof(static_map)-sizeof(static_map[0])); |
1733 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; | 1733 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; |
1734 } else { | 1734 } else { |
1735 //Assume the standard Sega mapper for now | 1735 //Assume the standard Sega mapper for now |
1736 memmap[0].end = 0x200000; | 1736 memmap[0].end = 0x200000; |
1737 memmap[0].mask = 0xFFFFFF; | 1737 memmap[0].mask = 0xFFFFFF; |
1738 memmap[0].flags = MMAP_READ; | 1738 memmap[0].flags = MMAP_READ; |
1739 memmap[0].buffer = cart; | 1739 memmap[0].buffer = cart; |
1740 | 1740 |
1741 memmap[1].start = 0x200000; | 1741 memmap[1].start = 0x200000; |
1742 memmap[1].end = 0x400000; | 1742 memmap[1].end = 0x400000; |
1743 memmap[1].mask = 0x1FFFFF; | 1743 memmap[1].mask = 0x1FFFFF; |
1744 ram_start &= 0xFFFFFE; | 1744 ram_start &= 0xFFFFFE; |
1745 ram_end |= 1; | 1745 ram_end |= 1; |
1755 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); | 1755 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); |
1756 memmap[num_chunks].start = 0xA13000; | 1756 memmap[num_chunks].start = 0xA13000; |
1757 memmap[num_chunks].end = 0xA13100; | 1757 memmap[num_chunks].end = 0xA13100; |
1758 memmap[num_chunks].mask = 0xFF; | 1758 memmap[num_chunks].mask = 0xFF; |
1759 memmap[num_chunks].write_16 = (write_16_fun)write_bank_reg_w; | 1759 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; | 1760 memmap[num_chunks].write_8 = (write_8_fun)write_bank_reg_b; |
1761 num_chunks++; | 1761 num_chunks++; |
1762 ram_end++; | 1762 ram_end++; |
1763 size = ram_end-ram_start; | 1763 size = ram_end-ram_start; |
1764 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { | 1764 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { |
1765 size /= 2; | 1765 size /= 2; |
1784 atexit(save_sram); | 1784 atexit(save_sram); |
1785 } | 1785 } |
1786 init_x86_68k_opts(&opts, memmap, num_chunks); | 1786 init_x86_68k_opts(&opts, memmap, num_chunks); |
1787 opts.address_log = address_log; | 1787 opts.address_log = address_log; |
1788 init_68k_context(&context, opts.native_code_map, &opts); | 1788 init_68k_context(&context, opts.native_code_map, &opts); |
1789 | 1789 |
1790 context.video_context = gen->vdp; | 1790 context.video_context = gen->vdp; |
1791 context.system = gen; | 1791 context.system = gen; |
1792 //cartridge ROM | 1792 //cartridge ROM |
1793 context.mem_pointers[0] = cart; | 1793 context.mem_pointers[0] = cart; |
1794 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; | 1794 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; |
1956 if (version_reg & 0x40) { | 1956 if (version_reg & 0x40) { |
1957 mclks_per_frame = MCLKS_LINE * LINES_PAL; | 1957 mclks_per_frame = MCLKS_LINE * LINES_PAL; |
1958 fps = 50; | 1958 fps = 50; |
1959 } | 1959 } |
1960 if (!headless) { | 1960 if (!headless) { |
1961 render_init(width, height, title, fps); | 1961 render_init(width, height, title, fps, 0); |
1962 } | 1962 } |
1963 vdp_context v_context; | 1963 vdp_context v_context; |
1964 | 1964 |
1965 init_vdp_context(&v_context); | 1965 init_vdp_context(&v_context); |
1966 | 1966 |
1967 ym2612_context y_context; | 1967 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); | 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); |
1969 | 1969 |
1970 psg_context p_context; | 1970 psg_context p_context; |
1971 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer()); | 1971 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer()); |
1972 | 1972 |
1973 z80_context z_context; | 1973 z80_context z_context; |
1974 x86_z80_options z_opts; | 1974 x86_z80_options z_opts; |
1975 init_x86_z80_opts(&z_opts); | 1975 init_x86_z80_opts(&z_opts); |
1976 init_z80_context(&z_context, &z_opts); | 1976 init_z80_context(&z_context, &z_opts); |
1977 | 1977 |
1981 z_context.system = &gen; | 1981 z_context.system = &gen; |
1982 z_context.mem_pointers[0] = z80_ram; | 1982 z_context.mem_pointers[0] = z80_ram; |
1983 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; | 1983 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; |
1984 z_context.int_cycle = CYCLE_NEVER; | 1984 z_context.int_cycle = CYCLE_NEVER; |
1985 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; | 1985 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; |
1986 | 1986 |
1987 gen.z80 = &z_context; | 1987 gen.z80 = &z_context; |
1988 gen.vdp = &v_context; | 1988 gen.vdp = &v_context; |
1989 gen.ym = &y_context; | 1989 gen.ym = &y_context; |
1990 gen.psg = &p_context; | 1990 gen.psg = &p_context; |
1991 genesis = &gen; | 1991 genesis = &gen; |
1992 | 1992 |
1993 int fname_size = strlen(argv[1]); | 1993 int fname_size = strlen(argv[1]); |
1994 sram_filename = malloc(fname_size+6); | 1994 sram_filename = malloc(fname_size+6); |
1995 memcpy(sram_filename, argv[1], fname_size); | 1995 memcpy(sram_filename, argv[1], fname_size); |
1996 int i; | 1996 int i; |
1997 for (i = fname_size-1; fname_size >= 0; --i) { | 1997 for (i = fname_size-1; fname_size >= 0; --i) { |
2002 } | 2002 } |
2003 if (i < 0) { | 2003 if (i < 0) { |
2004 strcpy(sram_filename + fname_size, ".sram"); | 2004 strcpy(sram_filename + fname_size, ".sram"); |
2005 } | 2005 } |
2006 set_keybindings(); | 2006 set_keybindings(); |
2007 | 2007 |
2008 init_run_cpu(&gen, debug, address_log, statefile); | 2008 init_run_cpu(&gen, debug, address_log, statefile); |
2009 return 0; | 2009 return 0; |
2010 } | 2010 } |