Mercurial > repos > blastem
comparison blastem.c @ 488:32f053ad9b02 opengl
Basic OpenGL rendering is working
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 27 Oct 2013 01:29:50 -0700 |
parents | c08a4efeee7f |
children | 6fc71114d145 |
comparison
equal
deleted
inserted
replaced
487:c08a4efeee7f | 488:32f053ad9b02 |
---|---|
60 int load_smd_rom(long filesize, FILE * f) | 60 int load_smd_rom(long filesize, FILE * f) |
61 { | 61 { |
62 uint8_t block[SMD_BLOCK_SIZE]; | 62 uint8_t block[SMD_BLOCK_SIZE]; |
63 filesize -= SMD_HEADER_SIZE; | 63 filesize -= SMD_HEADER_SIZE; |
64 fseek(f, SMD_HEADER_SIZE, SEEK_SET); | 64 fseek(f, SMD_HEADER_SIZE, SEEK_SET); |
65 | 65 |
66 uint16_t * dst = cart; | 66 uint16_t * dst = cart; |
67 while (filesize > 0) { | 67 while (filesize > 0) { |
68 fread(block, 1, SMD_BLOCK_SIZE, f); | 68 fread(block, 1, SMD_BLOCK_SIZE, f); |
69 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++) { |
70 *(dst++) = *high << 8 | *low; | 70 *(dst++) = *high << 8 | *low; |
147 if (next_hint != CYCLE_NEVER) { | 147 if (next_hint != CYCLE_NEVER) { |
148 next_hint /= MCLKS_PER_68K; | 148 next_hint /= MCLKS_PER_68K; |
149 if (next_hint < context->int_cycle) { | 149 if (next_hint < context->int_cycle) { |
150 context->int_cycle = next_hint; | 150 context->int_cycle = next_hint; |
151 context->int_num = 4; | 151 context->int_num = 4; |
152 | 152 |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 } | 156 } |
157 | 157 |
158 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; |
159 /*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", |
160 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), |
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);*/ | 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);*/ |
162 } | 162 } |
163 | 163 |
164 int break_on_sync = 0; | 164 int break_on_sync = 0; |
165 int save_state = 0; | 165 int save_state = 0; |
215 //printf("Running YM-2612 to cycle %d\n", cur_target); | 215 //printf("Running YM-2612 to cycle %d\n", cur_target); |
216 ym_run(gen->ym, cur_target); | 216 ym_run(gen->ym, cur_target); |
217 } | 217 } |
218 psg_run(gen->psg, target); | 218 psg_run(gen->psg, target); |
219 ym_run(gen->ym, target); | 219 ym_run(gen->ym, target); |
220 | 220 |
221 //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); |
222 } | 222 } |
223 | 223 |
224 uint32_t frame=0; | 224 uint32_t frame=0; |
225 m68k_context * sync_components(m68k_context * context, uint32_t address) | 225 m68k_context * sync_components(m68k_context * context, uint32_t address) |
237 if (gen->ym->write_cycle != CYCLE_NEVER) { | 237 if (gen->ym->write_cycle != CYCLE_NEVER) { |
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; | 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; |
239 } | 239 } |
240 //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); |
241 vdp_run_context(v_context, mclks_per_frame); | 241 vdp_run_context(v_context, mclks_per_frame); |
242 | 242 |
243 if (!headless) { | 243 if (!headless) { |
244 break_on_sync |= wait_render_frame(v_context, frame_limit); | 244 break_on_sync |= wait_render_frame(v_context, frame_limit); |
245 } | 245 } |
246 frame++; | 246 frame++; |
247 mclks -= mclks_per_frame; | 247 mclks -= mclks_per_frame; |
530 busack = new_busack; | 530 busack = new_busack; |
531 busack_cycle = CYCLE_NEVER; | 531 busack_cycle = CYCLE_NEVER; |
532 } | 532 } |
533 if (value & 1) { | 533 if (value & 1) { |
534 dputs("bus requesting Z80"); | 534 dputs("bus requesting Z80"); |
535 | 535 |
536 if(!reset && !busreq) { | 536 if(!reset && !busreq) { |
537 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K + Z80_ACK_DELAY*MCLKS_PER_Z80); | 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; | 538 busack_cycle = (gen->z80->current_cycle * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY; |
539 new_busack = Z80_REQ_ACK; | 539 new_busack = Z80_REQ_ACK; |
540 } | 540 } |
554 new_busack = Z80_REQ_BUSY; | 554 new_busack = Z80_REQ_BUSY; |
555 busreq = 0; | 555 busreq = 0; |
556 } | 556 } |
557 //busack_cycle = CYCLE_NEVER; | 557 //busack_cycle = CYCLE_NEVER; |
558 //busack = Z80_REQ_BUSY; | 558 //busack = Z80_REQ_BUSY; |
559 | 559 |
560 } | 560 } |
561 } else if (location == 0x1200) { | 561 } else if (location == 0x1200) { |
562 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); | 562 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); |
563 if (value & 1) { | 563 if (value & 1) { |
564 if (reset && busreq) { | 564 if (reset && busreq) { |
1469 case 'z': { | 1469 case 'z': { |
1470 genesis_context * gen = context->system; | 1470 genesis_context * gen = context->system; |
1471 //Z80 debug commands | 1471 //Z80 debug commands |
1472 switch(input_buf[1]) | 1472 switch(input_buf[1]) |
1473 { | 1473 { |
1474 case 'b': | 1474 case 'b': |
1475 param = find_param(input_buf); | 1475 param = find_param(input_buf); |
1476 if (!param) { | 1476 if (!param) { |
1477 fputs("zb command requires a parameter\n", stderr); | 1477 fputs("zb command requires a parameter\n", stderr); |
1478 break; | 1478 break; |
1479 } | 1479 } |
1521 #define RAM_FLAG_MASK 0x1800 | 1521 #define RAM_FLAG_MASK 0x1800 |
1522 | 1522 |
1523 const memmap_chunk static_map[] = { | 1523 const memmap_chunk static_map[] = { |
1524 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, | 1524 {0, 0x400000, 0xFFFFFF, 0, MMAP_READ, cart, |
1525 NULL, NULL, NULL, NULL}, | 1525 NULL, NULL, NULL, NULL}, |
1526 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, | 1526 {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, |
1527 NULL, NULL, NULL, NULL}, | 1527 NULL, NULL, NULL, NULL}, |
1528 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, | 1528 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL, |
1529 (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, |
1530 (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}, |
1531 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, | 1531 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL, |
1574 if (ram_start >= rom_end) { | 1574 if (ram_start >= rom_end) { |
1575 memmap[0].end = rom_end; | 1575 memmap[0].end = rom_end; |
1576 memmap[0].mask = 0xFFFFFF; | 1576 memmap[0].mask = 0xFFFFFF; |
1577 memmap[0].flags = MMAP_READ; | 1577 memmap[0].flags = MMAP_READ; |
1578 memmap[0].buffer = cart; | 1578 memmap[0].buffer = cart; |
1579 | 1579 |
1580 ram_start &= 0xFFFFFE; | 1580 ram_start &= 0xFFFFFE; |
1581 ram_end |= 1; | 1581 ram_end |= 1; |
1582 memmap[1].start = ram_start; | 1582 memmap[1].start = ram_start; |
1583 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; | 1583 gen->save_ram_mask = memmap[1].mask = ram_end-ram_start; |
1584 ram_end += 1; | 1584 ram_end += 1; |
1591 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { | 1591 } else if((ram_flags & RAM_FLAG_MASK) == RAM_FLAG_EVEN) { |
1592 memmap[1].flags |= MMAP_ONLY_EVEN; | 1592 memmap[1].flags |= MMAP_ONLY_EVEN; |
1593 size /= 2; | 1593 size /= 2; |
1594 } | 1594 } |
1595 memmap[1].buffer = gen->save_ram = malloc(size); | 1595 memmap[1].buffer = gen->save_ram = malloc(size); |
1596 | 1596 |
1597 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])); |
1598 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; | 1598 num_chunks = sizeof(static_map)/sizeof(memmap_chunk)+1; |
1599 } else { | 1599 } else { |
1600 //Assume the standard Sega mapper for now | 1600 //Assume the standard Sega mapper for now |
1601 memmap[0].end = 0x200000; | 1601 memmap[0].end = 0x200000; |
1602 memmap[0].mask = 0xFFFFFF; | 1602 memmap[0].mask = 0xFFFFFF; |
1603 memmap[0].flags = MMAP_READ; | 1603 memmap[0].flags = MMAP_READ; |
1604 memmap[0].buffer = cart; | 1604 memmap[0].buffer = cart; |
1605 | 1605 |
1606 memmap[1].start = 0x200000; | 1606 memmap[1].start = 0x200000; |
1607 memmap[1].end = 0x400000; | 1607 memmap[1].end = 0x400000; |
1608 memmap[1].mask = 0x1FFFFF; | 1608 memmap[1].mask = 0x1FFFFF; |
1609 ram_start &= 0xFFFFFE; | 1609 ram_start &= 0xFFFFFE; |
1610 ram_end |= 1; | 1610 ram_end |= 1; |
1620 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); | 1620 memset(memmap+num_chunks, 0, sizeof(memmap[num_chunks])); |
1621 memmap[num_chunks].start = 0xA13000; | 1621 memmap[num_chunks].start = 0xA13000; |
1622 memmap[num_chunks].end = 0xA13100; | 1622 memmap[num_chunks].end = 0xA13100; |
1623 memmap[num_chunks].mask = 0xFF; | 1623 memmap[num_chunks].mask = 0xFF; |
1624 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; |
1625 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; |
1626 num_chunks++; | 1626 num_chunks++; |
1627 ram_end++; | 1627 ram_end++; |
1628 size = ram_end-ram_start; | 1628 size = ram_end-ram_start; |
1629 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { | 1629 if ((ram_flags & RAM_FLAG_MASK) != RAM_FLAG_BOTH) { |
1630 size /= 2; | 1630 size /= 2; |
1649 atexit(save_sram); | 1649 atexit(save_sram); |
1650 } | 1650 } |
1651 init_x86_68k_opts(&opts, memmap, num_chunks); | 1651 init_x86_68k_opts(&opts, memmap, num_chunks); |
1652 opts.address_log = address_log; | 1652 opts.address_log = address_log; |
1653 init_68k_context(&context, opts.native_code_map, &opts); | 1653 init_68k_context(&context, opts.native_code_map, &opts); |
1654 | 1654 |
1655 context.video_context = gen->vdp; | 1655 context.video_context = gen->vdp; |
1656 context.system = gen; | 1656 context.system = gen; |
1657 //cartridge ROM | 1657 //cartridge ROM |
1658 context.mem_pointers[0] = cart; | 1658 context.mem_pointers[0] = cart; |
1659 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; |
1771 int loaded = 0; | 1771 int loaded = 0; |
1772 uint8_t force_version = 0; | 1772 uint8_t force_version = 0; |
1773 char * romfname = NULL; | 1773 char * romfname = NULL; |
1774 FILE *address_log = NULL; | 1774 FILE *address_log = NULL; |
1775 char * statefile = NULL; | 1775 char * statefile = NULL; |
1776 uint8_t fullscreen = 0; | 1776 uint8_t fullscreen = 0, use_gl = 0; |
1777 for (int i = 1; i < argc; i++) { | 1777 for (int i = 1; i < argc; i++) { |
1778 if (argv[i][0] == '-') { | 1778 if (argv[i][0] == '-') { |
1779 switch(argv[i][1]) { | 1779 switch(argv[i][1]) { |
1780 case 'd': | 1780 case 'd': |
1781 debug = 1; | 1781 debug = 1; |
1782 break; | 1782 break; |
1783 case 'f': | 1783 case 'f': |
1784 fullscreen = 1; | 1784 fullscreen = 1; |
1785 break; | |
1786 case 'g': | |
1787 use_gl = 1; | |
1785 break; | 1788 break; |
1786 case 'l': | 1789 case 'l': |
1787 address_log = fopen("address.log", "w"); | 1790 address_log = fopen("address.log", "w"); |
1788 break; | 1791 break; |
1789 case 'v': | 1792 case 'v': |
1883 if (version_reg & 0x40) { | 1886 if (version_reg & 0x40) { |
1884 mclks_per_frame = MCLKS_LINE * LINES_PAL; | 1887 mclks_per_frame = MCLKS_LINE * LINES_PAL; |
1885 fps = 50; | 1888 fps = 50; |
1886 } | 1889 } |
1887 if (!headless) { | 1890 if (!headless) { |
1888 render_init(width, height, title, fps, fullscreen, 0); | 1891 render_init(width, height, title, fps, fullscreen, use_gl); |
1889 } | 1892 } |
1890 vdp_context v_context; | 1893 vdp_context v_context; |
1891 genesis_context gen; | 1894 genesis_context gen; |
1892 memset(&gen, 0, sizeof(gen)); | 1895 memset(&gen, 0, sizeof(gen)); |
1893 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; | 1896 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; |
1894 | 1897 |
1895 init_vdp_context(&v_context); | 1898 init_vdp_context(&v_context); |
1896 | 1899 |
1897 ym2612_context y_context; | 1900 ym2612_context y_context; |
1898 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); | 1901 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); |
1899 | 1902 |
1900 psg_context p_context; | 1903 psg_context p_context; |
1901 psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer()); | 1904 psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer()); |
1902 | 1905 |
1903 z80_context z_context; | 1906 z80_context z_context; |
1904 x86_z80_options z_opts; | 1907 x86_z80_options z_opts; |
1905 init_x86_z80_opts(&z_opts); | 1908 init_x86_z80_opts(&z_opts); |
1906 init_z80_context(&z_context, &z_opts); | 1909 init_z80_context(&z_context, &z_opts); |
1907 | 1910 |
1908 z_context.system = &gen; | 1911 z_context.system = &gen; |
1909 z_context.mem_pointers[0] = z80_ram; | 1912 z_context.mem_pointers[0] = z80_ram; |
1910 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; | 1913 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; |
1911 z_context.int_cycle = CYCLE_NEVER; | 1914 z_context.int_cycle = CYCLE_NEVER; |
1912 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; | 1915 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; |
1913 | 1916 |
1914 gen.z80 = &z_context; | 1917 gen.z80 = &z_context; |
1915 gen.vdp = &v_context; | 1918 gen.vdp = &v_context; |
1916 gen.ym = &y_context; | 1919 gen.ym = &y_context; |
1917 gen.psg = &p_context; | 1920 gen.psg = &p_context; |
1918 genesis = &gen; | 1921 genesis = &gen; |
1919 | 1922 |
1920 int fname_size = strlen(romfname); | 1923 int fname_size = strlen(romfname); |
1921 sram_filename = malloc(fname_size+6); | 1924 sram_filename = malloc(fname_size+6); |
1922 memcpy(sram_filename, romfname, fname_size); | 1925 memcpy(sram_filename, romfname, fname_size); |
1923 int i; | 1926 int i; |
1924 for (i = fname_size-1; fname_size >= 0; --i) { | 1927 for (i = fname_size-1; fname_size >= 0; --i) { |
1929 } | 1932 } |
1930 if (i < 0) { | 1933 if (i < 0) { |
1931 strcpy(sram_filename + fname_size, ".sram"); | 1934 strcpy(sram_filename + fname_size, ".sram"); |
1932 } | 1935 } |
1933 set_keybindings(); | 1936 set_keybindings(); |
1934 | 1937 |
1935 init_run_cpu(&gen, debug, address_log, statefile); | 1938 init_run_cpu(&gen, debug, address_log, statefile); |
1936 return 0; | 1939 return 0; |
1937 } | 1940 } |