comparison blastem.c @ 354:15dd6418fe67

Initial PSG support. Mostly works, noise channel is borked though.
author Mike Pavone <pavone@retrodev.com>
date Thu, 23 May 2013 23:42:42 -0700
parents 2f264d2a60c2
children 79e4b466e7d0
comparison
equal deleted inserted replaced
353:a60e527cd21f 354:15dd6418fe67
12 #define CARTRIDGE_WORDS 0x200000 12 #define CARTRIDGE_WORDS 0x200000
13 #define RAM_WORDS 32 * 1024 13 #define RAM_WORDS 32 * 1024
14 #define Z80_RAM_BYTES 8 * 1024 14 #define Z80_RAM_BYTES 8 * 1024
15 #define MCLKS_PER_68K 7 15 #define MCLKS_PER_68K 7
16 #define MCLKS_PER_Z80 15 16 #define MCLKS_PER_Z80 15
17 #define MCLKS_PER_PSG (MCLKS_PER_Z80*16)
17 //TODO: Figure out the exact value for this 18 //TODO: Figure out the exact value for this
18 #define CYCLE_NEVER 0xFFFFFFFF 19 #define CYCLE_NEVER 0xFFFFFFFF
19 #define LINES_NTSC 262 20 #define LINES_NTSC 262
20 #define LINES_PAL 312 21 #define LINES_PAL 312
21 22
198 if (mclks >= mclks_per_frame) { 199 if (mclks >= mclks_per_frame) {
199 ym_run(gen->ym, context->current_cycle); 200 ym_run(gen->ym, context->current_cycle);
200 gen->ym->current_cycle -= mclks_per_frame/MCLKS_PER_68K; 201 gen->ym->current_cycle -= mclks_per_frame/MCLKS_PER_68K;
201 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 202 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
202 vdp_run_context(v_context, mclks_per_frame); 203 vdp_run_context(v_context, mclks_per_frame);
204 psg_run(gen->psg, mclks/MCLKS_PER_PSG);
205 gen->psg->cycles -= mclks_per_frame/MCLKS_PER_PSG;
203 if (!headless) { 206 if (!headless) {
204 break_on_sync |= wait_render_frame(v_context, frame_limit); 207 break_on_sync |= wait_render_frame(v_context, frame_limit);
205 } 208 }
206 frame++; 209 frame++;
207 mclks -= mclks_per_frame; 210 mclks -= mclks_per_frame;
226 vdp_run_context(v_context, mclks); 229 vdp_run_context(v_context, mclks);
227 } 230 }
228 } else { 231 } else {
229 //printf("running VDP for %d cycles\n", mclks - v_context->cycles); 232 //printf("running VDP for %d cycles\n", mclks - v_context->cycles);
230 vdp_run_context(v_context, mclks); 233 vdp_run_context(v_context, mclks);
234 psg_run(gen->psg, mclks/MCLKS_PER_PSG);
231 } 235 }
232 if (context->int_ack) { 236 if (context->int_ack) {
233 vdp_int_ack(v_context, context->int_ack); 237 vdp_int_ack(v_context, context->int_ack);
234 context->int_ack = 0; 238 context->int_ack = 0;
235 } 239 }
316 } 320 }
317 if (v_context->cycles != before_cycle) { 321 if (v_context->cycles != before_cycle) {
318 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 322 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
319 } 323 }
320 } else if (vdp_port < 0x18) { 324 } else if (vdp_port < 0x18) {
321 //TODO: Implement PSG 325 genesis_context * gen = context->system;
326 psg_run(gen->psg, (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_PSG);
327 psg_write(gen->psg, value);
322 } else { 328 } else {
323 //TODO: Implement undocumented test register(s) 329 //TODO: Implement undocumented test register(s)
324 } 330 }
325 return context; 331 return context;
326 } 332 }
327 333
328 m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8_t value) 334 m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8_t value)
329 { 335 {
330 return vdp_port_write(vdp_port, context, value | value << 8); 336 return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : value);
331 } 337 }
332 338
333 uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context) 339 uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context)
334 { 340 {
335 if (vdp_port & 0x2700E0) { 341 if (vdp_port & 0x2700E0) {
1383 } else if (detect_specific_region('E') || detect_specific_region('A')) { 1389 } else if (detect_specific_region('E') || detect_specific_region('A')) {
1384 version_reg = NO_DISK | EUR; 1390 version_reg = NO_DISK | EUR;
1385 } 1391 }
1386 } 1392 }
1387 1393
1394 #define PSG_CLKS_NTSC (3579545/16)
1395 #define PSG_CLKS_PAL (3546893/16)
1396
1388 int main(int argc, char ** argv) 1397 int main(int argc, char ** argv)
1389 { 1398 {
1390 if (argc < 2) { 1399 if (argc < 2) {
1391 fputs("Usage: blastem FILENAME\n", stderr); 1400 fputs("Usage: blastem FILENAME\n", stderr);
1392 return 1; 1401 return 1;
1454 } 1463 }
1455 } 1464 }
1456 update_title(); 1465 update_title();
1457 width = width < 320 ? 320 : width; 1466 width = width < 320 ? 320 : width;
1458 height = height < 240 ? (width/320) * 240 : height; 1467 height = height < 240 ? (width/320) * 240 : height;
1459 if (!headless) { 1468 uint32_t fps = 60;
1460 render_init(width, height, title);
1461 }
1462 if (version_reg & 0x40) { 1469 if (version_reg & 0x40) {
1463 mclks_per_frame = MCLKS_LINE * LINES_PAL; 1470 mclks_per_frame = MCLKS_LINE * LINES_PAL;
1464 render_fps(50); 1471 fps = 50;
1472 }
1473 if (!headless) {
1474 render_init(width, height, title, fps);
1465 } 1475 }
1466 vdp_context v_context; 1476 vdp_context v_context;
1467 1477
1468 init_vdp_context(&v_context); 1478 init_vdp_context(&v_context);
1469 1479
1470 ym2612_context y_context; 1480 ym2612_context y_context;
1471 ym_init(&y_context); 1481 ym_init(&y_context);
1482
1483 psg_context p_context;
1484 psg_init(&p_context, render_sample_rate(), fps == 60 ? PSG_CLKS_NTSC : PSG_CLKS_PAL, render_audio_buffer());
1472 1485
1473 z80_context z_context; 1486 z80_context z_context;
1474 x86_z80_options z_opts; 1487 x86_z80_options z_opts;
1475 init_x86_z80_opts(&z_opts); 1488 init_x86_z80_opts(&z_opts);
1476 init_z80_context(&z_context, &z_opts); 1489 init_z80_context(&z_context, &z_opts);
1484 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 1497 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
1485 1498
1486 gen.z80 = &z_context; 1499 gen.z80 = &z_context;
1487 gen.vdp = &v_context; 1500 gen.vdp = &v_context;
1488 gen.ym = &y_context; 1501 gen.ym = &y_context;
1502 gen.psg = &p_context;
1489 genesis = &gen; 1503 genesis = &gen;
1490 1504
1491 int fname_size = strlen(argv[1]); 1505 int fname_size = strlen(argv[1]);
1492 sram_filename = malloc(fname_size+6); 1506 sram_filename = malloc(fname_size+6);
1493 memcpy(sram_filename, argv[1], fname_size); 1507 memcpy(sram_filename, argv[1], fname_size);