comparison cdd_mcu.c @ 2080:bafb757e1cd2

Implement CD audio
author Michael Pavone <pavone@retrodev.com>
date Wed, 02 Feb 2022 01:10:07 -0800
parents 5a2b759f6b2d
children cfd53c94fffb
comparison
equal deleted inserted replaced
2079:5a2b759f6b2d 2080:bafb757e1cd2
37 void cdd_mcu_init(cdd_mcu *context, system_media *media) 37 void cdd_mcu_init(cdd_mcu *context, system_media *media)
38 { 38 {
39 context->next_int_cycle = CYCLE_NEVER; 39 context->next_int_cycle = CYCLE_NEVER;
40 context->last_subcode_cycle = CYCLE_NEVER; 40 context->last_subcode_cycle = CYCLE_NEVER;
41 context->last_nibble_cycle = CYCLE_NEVER; 41 context->last_nibble_cycle = CYCLE_NEVER;
42 context->last_byte_cycle = CYCLE_NEVER; 42 context->last_byte_cycle = 0;
43 context->requested_format = SF_NOTREADY; 43 context->requested_format = SF_NOTREADY;
44 context->media = media; 44 context->media = media;
45 context->current_status_nibble = -1; 45 context->current_status_nibble = -1;
46 context->current_cmd_nibble = -1; 46 context->current_cmd_nibble = -1;
47 context->current_sector_byte = -1; 47 context->current_sector_byte = -1;
50 enum { 50 enum {
51 GAO_CDD_CTRL, 51 GAO_CDD_CTRL,
52 GAO_CDD_STATUS, 52 GAO_CDD_STATUS,
53 GAO_CDD_CMD = GAO_CDD_STATUS+5 53 GAO_CDD_CMD = GAO_CDD_STATUS+5
54 }; 54 };
55 //GAO_CDD_CTRL
56 #define BIT_MUTE 0x100
57 #define BIT_HOCK 0x0004
58 #define BIT_DRS 0x0002
59 #define BIT_DTS 0x0001
55 60
56 static uint8_t checksum(uint8_t *vbuffer) 61 static uint8_t checksum(uint8_t *vbuffer)
57 { 62 {
58 uint8_t *buffer = vbuffer; 63 uint8_t *buffer = vbuffer;
59 uint8_t sum = 0; 64 uint8_t sum = 0;
103 context->status_buffer.b.time.sec_low = seconds % 10; 108 context->status_buffer.b.time.sec_low = seconds % 10;
104 context->status_buffer.b.time.frame_high = frames / 10; 109 context->status_buffer.b.time.frame_high = frames / 10;
105 context->status_buffer.b.time.frame_low = frames % 10; 110 context->status_buffer.b.time.frame_low = frames % 10;
106 } 111 }
107 112
108 static void update_status(cdd_mcu *context) 113 static void update_status(cdd_mcu *context, uint16_t *gate_array)
109 { 114 {
115 gate_array[GAO_CDD_CTRL] |= BIT_MUTE;
110 switch (context->status) 116 switch (context->status)
111 { 117 {
112 case DS_PLAY: 118 case DS_PLAY:
113 handle_seek(context); 119 handle_seek(context);
114 if (!context->seeking) { 120 if (!context->seeking) {
115 context->head_pba++; 121 context->head_pba++;
116 context->media->seek(context->media, context->head_pba - LEADIN_SECTORS); 122 uint8_t track = context->media->seek(context->media, context->head_pba - LEADIN_SECTORS);
123 if (context->media->tracks[track].type == TRACK_AUDIO) {
124 gate_array[GAO_CDD_CTRL] &= ~BIT_MUTE;
125 }
117 } 126 }
118 break; 127 break;
119 case DS_PAUSE: 128 case DS_PAUSE:
120 handle_seek(context); 129 handle_seek(context);
121 break; 130 break;
285 context->status_buffer.status = context->error_status; 294 context->status_buffer.status = context->error_status;
286 context->status_buffer.format = SF_NOTREADY; 295 context->status_buffer.format = SF_NOTREADY;
287 context->error_status = DS_STOP; 296 context->error_status = DS_STOP;
288 } 297 }
289 if (context->requested_format != SF_TOCN) { 298 if (context->requested_format != SF_TOCN) {
290 context->status_buffer.b.time.flags = 1; //TODO: populate these 299 context->status_buffer.b.time.flags = !!(gate_array[GAO_CDD_CTRL] & BIT_MUTE); //TODO: populate these
291 } 300 }
292 } else { 301 } else {
293 // Did not receive our first command so just send zeroes 302 // Did not receive our first command so just send zeroes
294 memset(&context->status_buffer, 0, sizeof(context->status_buffer) - 1); 303 memset(&context->status_buffer, 0, sizeof(context->status_buffer) - 1);
295 } 304 }
430 default: 439 default:
431 printf("CDD CMD: Unimplemented(%d)\n", context->cmd_buffer.cmd_type); 440 printf("CDD CMD: Unimplemented(%d)\n", context->cmd_buffer.cmd_type);
432 } 441 }
433 } 442 }
434 443
435 #define BIT_HOCK 0x4 444 void cdd_mcu_run(cdd_mcu *context, uint32_t cycle, uint16_t *gate_array, lc8951* cdc, cdd_fader* fader)
436 #define BIT_DRS 0x2
437 #define BIT_DTS 0x1
438
439 void cdd_mcu_run(cdd_mcu *context, uint32_t cycle, uint16_t *gate_array, lc8951* cdc)
440 { 445 {
441 uint32_t cd_cycle = mclks_to_cd_block(cycle); 446 uint32_t cd_cycle = mclks_to_cd_block(cycle);
447 uint32_t next_byte = context->last_byte_cycle + BYTE_CLOCKS;
442 if (!(gate_array[GAO_CDD_CTRL] & BIT_HOCK)) { 448 if (!(gate_array[GAO_CDD_CTRL] & BIT_HOCK)) {
443 //it's a little unclear if this gates the actual cd block clock or just handshaking 449 //it's a little unclear if this gates the actual cd block clock or just handshaking
444 //assum it's actually the clock for now 450 //assum it's actually the clock for now
445 context->cycle = cd_cycle; 451 for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER) {
452 if (context->cycle >= next_byte) {
453 cdd_fader_data(fader, 0);
454 next_byte = context->cycle + BYTE_CLOCKS;
455 context->last_byte_cycle = context->cycle;
456 }
457 }
458 gate_array[GAO_CDD_CTRL] |= BIT_MUTE;
446 return; 459 return;
447 } 460 }
448 uint32_t next_subcode = context->last_subcode_cycle + SECTOR_CLOCKS; 461 uint32_t next_subcode = context->last_subcode_cycle + SECTOR_CLOCKS;
449 uint32_t next_nibble = context->current_status_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER; 462 uint32_t next_nibble = context->current_status_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER;
450 uint32_t next_cmd_nibble = context->current_cmd_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER; 463 uint32_t next_cmd_nibble = context->current_cmd_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER;
451 uint32_t next_byte = context->current_sector_byte >= 0 ? context->last_byte_cycle + BYTE_CLOCKS : CYCLE_NEVER; 464
452 for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER) 465 for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER)
453 { 466 {
454 if (context->cycle >= next_subcode) { 467 if (context->cycle >= next_subcode) {
455 context->last_subcode_cycle = context->cycle; 468 context->last_subcode_cycle = context->cycle;
456 next_subcode = context->cycle + SECTOR_CLOCKS; 469 next_subcode = context->cycle + SECTOR_CLOCKS;
457 update_status(context); 470 update_status(context, gate_array);
458 next_nibble = context->cycle; 471 next_nibble = context->cycle;
459 context->current_status_nibble = 0; 472 context->current_status_nibble = 0;
460 gate_array[GAO_CDD_STATUS] |= BIT_DRS; 473 gate_array[GAO_CDD_STATUS] |= BIT_DRS;
461 if (context->status == DS_PLAY && !context->seeking) { 474 if (context->status == DS_PLAY && !context->seeking) {
462 next_byte = context->cycle;
463 context->current_sector_byte = 0; 475 context->current_sector_byte = 0;
464 } 476 }
465 } 477 }
466 if (context->cycle >= next_nibble) { 478 if (context->cycle >= next_nibble) {
467 if (context->current_status_nibble == sizeof(cdd_status)) { 479 if (context->current_status_nibble == sizeof(cdd_status)) {
506 context->last_nibble_cycle = context->cycle; 518 context->last_nibble_cycle = context->cycle;
507 next_cmd_nibble = context->cycle + NIBBLE_CLOCKS; 519 next_cmd_nibble = context->cycle + NIBBLE_CLOCKS;
508 } 520 }
509 } 521 }
510 if (context->cycle >= next_byte) { 522 if (context->cycle >= next_byte) {
511 uint8_t byte = context->media->read(context->media, context->current_sector_byte); 523 if (context->current_sector_byte >= 0) {
512 lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), context->current_sector_byte++, byte); 524 uint8_t byte = context->media->read(context->media, context->current_sector_byte);
525 lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), context->current_sector_byte++, byte);
526 cdd_fader_data(fader, gate_array[GAO_CDD_CTRL] & BIT_MUTE ? 0 : byte);
527 } else {
528 cdd_fader_data(fader, 0);
529 }
513 context->last_byte_cycle = context->cycle; 530 context->last_byte_cycle = context->cycle;
514 if (context->current_sector_byte == 2352) { 531 if (context->current_sector_byte == 2352) {
515 context->current_sector_byte = -1; 532 context->current_sector_byte = -1;
516 next_byte = CYCLE_NEVER; 533 }
517 } else { 534 next_byte = context->cycle + BYTE_CLOCKS;
518 next_byte = context->cycle + BYTE_CLOCKS;
519 }
520 } 535 }
521 } 536 }
522 } 537 }
523 538
524 void cdd_mcu_start_cmd_recv(cdd_mcu *context, uint16_t *gate_array) 539 void cdd_mcu_start_cmd_recv(cdd_mcu *context, uint16_t *gate_array)
542 void cdd_hock_disabled(cdd_mcu *context) 557 void cdd_hock_disabled(cdd_mcu *context)
543 { 558 {
544 context->last_subcode_cycle = CYCLE_NEVER; 559 context->last_subcode_cycle = CYCLE_NEVER;
545 context->next_int_cycle = CYCLE_NEVER; 560 context->next_int_cycle = CYCLE_NEVER;
546 context->last_nibble_cycle = CYCLE_NEVER; 561 context->last_nibble_cycle = CYCLE_NEVER;
547 context->last_byte_cycle = CYCLE_NEVER;
548 context->current_status_nibble = -1; 562 context->current_status_nibble = -1;
549 context->current_cmd_nibble = -1; 563 context->current_cmd_nibble = -1;
550 } 564 }
551 565
552 void cdd_mcu_adjust_cycle(cdd_mcu *context, uint32_t deduction) 566 void cdd_mcu_adjust_cycle(cdd_mcu *context, uint32_t deduction)