From ef7add9d10b218a1dd75f2f0266c621f955a25eb Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Sat, 12 Jul 2025 15:34:23 +0200 Subject: cdtv: Subcode support --- src/devices/bus/amiga/cpuslot/a570.cpp | 10 +- src/devices/bus/c64/magic_voice.cpp | 4 +- src/devices/machine/6525tpi.cpp | 199 +++++++++++---------------------- src/devices/machine/6525tpi.h | 18 +-- src/devices/machine/cr511b.cpp | 192 +++++++++++++++++++++---------- src/devices/machine/cr511b.h | 15 +++ src/mame/amiga/amiga.cpp | 10 +- src/mame/commodore/cbm2.cpp | 22 ++-- 8 files changed, 245 insertions(+), 225 deletions(-) diff --git a/src/devices/bus/amiga/cpuslot/a570.cpp b/src/devices/bus/amiga/cpuslot/a570.cpp index abd42370380..ec3adffcb2a 100644 --- a/src/devices/bus/amiga/cpuslot/a570.cpp +++ b/src/devices/bus/amiga/cpuslot/a570.cpp @@ -122,12 +122,14 @@ void a570_device::device_add_mconfig(machine_config &config) CR511B(config, m_drive, 0); m_drive->add_route(0, "speaker", 1.0, 0); m_drive->add_route(1, "speaker", 1.0, 1); - m_drive->scor_cb().set(m_tpi, FUNC(tpi6525_device::i1_w)).invert(); - m_drive->stch_cb().set(m_tpi, FUNC(tpi6525_device::i2_w)).invert(); - m_drive->sten_cb().set(m_tpi, FUNC(tpi6525_device::i3_w)); + m_drive->sbcp_cb().set(m_tpi, FUNC(tpi6525_device::pc0_w)).invert(); + m_drive->scor_cb().set(m_tpi, FUNC(tpi6525_device::pc1_w)).invert(); + m_drive->stch_cb().set(m_tpi, FUNC(tpi6525_device::pc2_w)).invert(); + m_drive->sten_cb().set(m_tpi, FUNC(tpi6525_device::pc3_w)); m_drive->sten_cb().append(FUNC(a570_device::sten_w)); - m_drive->drq_cb().set(m_tpi, FUNC(tpi6525_device::i4_w)); + m_drive->drq_cb().set(m_tpi, FUNC(tpi6525_device::pc4_w)); m_drive->drq_cb().append(FUNC(a570_device::drq_w)); + m_drive->subcode_data_cb().set(m_tpi, FUNC(tpi6525_device::pa_w)); SPEAKER(config, "speaker", 2).front(); diff --git a/src/devices/bus/c64/magic_voice.cpp b/src/devices/bus/c64/magic_voice.cpp index b9e0949ed3d..b1c06f202ac 100644 --- a/src/devices/bus/c64/magic_voice.cpp +++ b/src/devices/bus/c64/magic_voice.cpp @@ -231,11 +231,11 @@ void c64_magic_voice_cartridge_device::device_add_mconfig(machine_config &config m_tpi->out_cb_cb().set(FUNC(c64_magic_voice_cartridge_device::tpi_cb_w)); CD40105(config, m_fifo, 0); - m_fifo->in_ready_cb().set(m_tpi, FUNC(tpi6525_device::i3_w)); + m_fifo->in_ready_cb().set(m_tpi, FUNC(tpi6525_device::pc3_w)); SPEAKER(config, "mono").front_center(); T6721A(config, m_vslsi, XTAL(640'000)); - m_vslsi->eos_handler().set(m_tpi, FUNC(tpi6525_device::i2_w)); + m_vslsi->eos_handler().set(m_tpi, FUNC(tpi6525_device::pc2_w)); m_vslsi->phi2_handler().set(FUNC(c64_magic_voice_cartridge_device::phi2_w)); m_vslsi->dtrd_handler().set(FUNC(c64_magic_voice_cartridge_device::dtrd_w)); m_vslsi->apd_handler().set(FUNC(c64_magic_voice_cartridge_device::apd_w)); diff --git a/src/devices/machine/6525tpi.cpp b/src/devices/machine/6525tpi.cpp index addebf837b1..ed399e0f27c 100644 --- a/src/devices/machine/6525tpi.cpp +++ b/src/devices/machine/6525tpi.cpp @@ -119,23 +119,17 @@ tpi6525_device::tpi6525_device(const machine_config &mconfig, const char *tag, d m_out_cb_cb(*this), m_port_a(0), m_ddr_a(0), - m_in_a(0), + m_in_a(0xff), m_port_b(0), m_ddr_b(0), - m_in_b(0), + m_in_b(0xff), m_port_c(0), m_ddr_c(0), - m_in_c(0), - m_ca_level(0), - m_cb_level(0), - m_interrupt_level(0), + m_in_c(0xff), m_cr(0), - m_air(0) + m_air(0), + m_irq_latch(0) { - for (auto & elem : m_irq_level) - { - elem = 0; - } } //------------------------------------------------- @@ -144,12 +138,7 @@ tpi6525_device::tpi6525_device(const machine_config &mconfig, const char *tag, d void tpi6525_device::device_start() { - /* setup some initial values */ - m_in_a = 0xff; - m_in_b = 0xff; - m_in_c = 0xff; - - /* register for state saving */ + // register for state saving save_item(NAME(m_port_a)); save_item(NAME(m_ddr_a)); save_item(NAME(m_in_a)); @@ -159,12 +148,9 @@ void tpi6525_device::device_start() save_item(NAME(m_port_c)); save_item(NAME(m_ddr_c)); save_item(NAME(m_in_c)); - save_item(NAME(m_ca_level)); - save_item(NAME(m_cb_level)); - save_item(NAME(m_interrupt_level)); save_item(NAME(m_cr)); save_item(NAME(m_air)); - save_item(NAME(m_irq_level)); + save_item(NAME(m_irq_latch)); } //------------------------------------------------- @@ -182,108 +168,74 @@ void tpi6525_device::device_reset() void tpi6525_device::set_interrupt() { - if (!m_interrupt_level && (m_air != 0)) + if ((BIT(m_irq_latch, 5) == 0) && (m_air != 0)) { - m_interrupt_level = 1; + m_irq_latch |= 1 << 5; DBG_LOG(machine(), 3, "tpi6525", ("%s set interrupt\n", tag())); - m_out_irq_cb(m_interrupt_level); + m_out_irq_cb(1); } } void tpi6525_device::clear_interrupt() { - if (m_interrupt_level && (m_air == 0)) + if ((BIT(m_irq_latch, 5) == 1) && (m_air == 0)) { - m_interrupt_level = 0; + m_irq_latch &= ~(1 << 5); DBG_LOG(machine(), 3, "tpi6525", ("%s clear interrupt\n", tag())); - m_out_irq_cb(m_interrupt_level); - } -} - - -void tpi6525_device::i0_w(int state) -{ - if (INTERRUPT_MODE && (state != m_irq_level[0])) - { - m_irq_level[0] = state; - - if ((state == 0) && !(m_air & 1) && (m_ddr_c & 1)) - { - m_air |= 1; - set_interrupt(); - } + m_out_irq_cb(0); } } -void tpi6525_device::i1_w(int state) +void tpi6525_device::portc_line_w(int line, int state) { - if (INTERRUPT_MODE && (state != m_irq_level[1])) - { - m_irq_level[1] = state; - - if ((state == 0) && !(m_air & 2) && (m_ddr_c & 2)) - { - m_air |= 2; - set_interrupt(); - } - } -} - + bool active = false; -void tpi6525_device::i2_w(int state) -{ - if (INTERRUPT_MODE && (state != m_irq_level[2])) + switch (line) { - m_irq_level[2] = state; - - if ((state == 0) && !(m_air & 4) && (m_ddr_c & 4)) - { - m_air |= 4; - set_interrupt(); - } + case 0: + case 1: + case 2: + active = (state == 0) && (BIT(m_in_c, line) == 1); + break; + + case 3: + if (INTERRUPT3_RISING_EDGE) + active = (state == 1) && (BIT(m_in_c, line) == 0); + else + active = (state == 0) && (BIT(m_in_c, line) == 1); + break; + + case 4: + if (INTERRUPT4_RISING_EDGE) + active = (state == 1) && (BIT(m_in_c, line) == 0); + else + active = (state == 0) && (BIT(m_in_c, line) == 1); + break; } -} + m_in_c &= ~(1 << line); + m_in_c |= state << line; -void tpi6525_device::i3_w(int state) -{ - if (INTERRUPT_MODE && (state != m_irq_level[3])) + if (INTERRUPT_MODE && active) { - m_irq_level[3] = state; + m_irq_latch |= 1 << line; - if (((INTERRUPT3_RISING_EDGE && (state == 1)) - || (!INTERRUPT3_RISING_EDGE && (state == 0))) - && !(m_air & 8) && (m_ddr_c & 8)) + // set interrupt if not yet active and not masked + if (BIT(m_air, line) == 0 && BIT(m_ddr_c, line) == 1) { - m_air |= 8; + m_air |= 1 << line; set_interrupt(); } } } -void tpi6525_device::i4_w(int state) -{ - if (INTERRUPT_MODE && (state != m_irq_level[4]) ) - { - m_irq_level[4] = state; - - if (((INTERRUPT4_RISING_EDGE && (state == 1)) - ||(!INTERRUPT4_RISING_EDGE&&(state == 0))) - && !(m_air & 0x10) && (m_ddr_c & 0x10)) - { - m_air |= 0x10; - set_interrupt(); - } - } -} - uint8_t tpi6525_device::pa_r() { uint8_t data = m_in_a; @@ -370,16 +322,7 @@ uint8_t tpi6525_device::read(offs_t offset) case 2: if (INTERRUPT_MODE) { - data = 0; - - if (m_irq_level[0]) data |= 0x01; - if (m_irq_level[1]) data |= 0x02; - if (m_irq_level[2]) data |= 0x04; - if (m_irq_level[3]) data |= 0x08; - if (m_irq_level[4]) data |= 0x10; - if (!m_interrupt_level) data |= 0x20; - if (m_ca_level) data |= 0x40; - if (m_cb_level) data |= 0x80; + data = m_irq_latch; } else { @@ -413,36 +356,22 @@ uint8_t tpi6525_device::read(offs_t offset) case 7: /* air */ if (PRIORIZED_INTERRUPTS) { - if (m_air & 0x10) - { - data = 0x10; - m_air &= ~0x10; - } - else if (m_air & 8) - { - data = 8; - m_air &= ~8; - } - else if (m_air & 4) - { - data = 4; - m_air &= ~4; - } - else if (m_air & 2) - { - data = 2; - m_air &= ~2; - } - else if (m_air & 1) + for (int i = 4; i >= 0; i--) { - data = 1; - m_air &= ~1; + if (BIT(m_air, i)) + { + data = 1 << i; + m_air &= ~(1 << i); + m_irq_latch &= ~(1 << i); + break; + } } } else { data = m_air; m_air = 0; + m_irq_latch &= 0xe0; } clear_interrupt(); @@ -481,12 +410,10 @@ void tpi6525_device::write(offs_t offset, uint8_t data) } else { - // clear latches - if (BIT(data, 0) == 0) m_irq_level[0] = 1; - if (BIT(data, 1) == 0) m_irq_level[1] = 1; - if (BIT(data, 2) == 0) m_irq_level[2] = 1; - if (BIT(data, 3) == 0) m_irq_level[3] = INTERRUPT3_RISING_EDGE ? 0 : 1; - if (BIT(data, 4) == 0) m_irq_level[4] = INTERRUPT4_RISING_EDGE ? 0 : 1; + for (int i = 0; i <= 4; i++) + if (BIT(data, i) == 0) + m_irq_latch &= ~(1 << i); + } break; @@ -514,18 +441,20 @@ void tpi6525_device::write(offs_t offset, uint8_t data) { if (CA_MANUAL_OUT) { - if (m_ca_level != CA_MANUAL_LEVEL) + if (BIT(m_irq_latch, 6) != CA_MANUAL_LEVEL) { - m_ca_level = CA_MANUAL_LEVEL; - m_out_ca_cb(m_ca_level); + m_irq_latch &= ~(1 << 6); + m_irq_latch |= CA_MANUAL_LEVEL << 6; + m_out_ca_cb(BIT(m_irq_latch, 6)); } } if (CB_MANUAL_OUT) { - if (m_cb_level != CB_MANUAL_LEVEL) + if (BIT(m_irq_latch, 7) != CB_MANUAL_LEVEL) { - m_cb_level = CB_MANUAL_LEVEL; - m_out_cb_cb(m_cb_level); + m_irq_latch &= ~(1 << 7); + m_irq_latch |= CB_MANUAL_LEVEL << 7; + m_out_ca_cb(BIT(m_irq_latch, 7)); } } } diff --git a/src/devices/machine/6525tpi.h b/src/devices/machine/6525tpi.h index c2487bde39b..3aa576b3eb6 100644 --- a/src/devices/machine/6525tpi.h +++ b/src/devices/machine/6525tpi.h @@ -56,12 +56,6 @@ public: uint8_t read(offs_t offset); void write(offs_t offset, uint8_t data); - void i0_w(int state); - void i1_w(int state); - void i2_w(int state); - void i3_w(int state); - void i4_w(int state); - uint8_t pa_r(); uint8_t pb_r(); uint8_t pc_r(); @@ -78,6 +72,12 @@ public: void pb6_w(int state) { port_line_w(m_in_b, 6, state); } void pb7_w(int state) { port_line_w(m_in_b, 7, state); } + void pc0_w(int state) { portc_line_w(0, state); } + void pc1_w(int state) { portc_line_w(1, state); } + void pc2_w(int state) { portc_line_w(2, state); } + void pc3_w(int state) { portc_line_w(3, state); } + void pc4_w(int state) { portc_line_w(4, state); } + protected: // device-level overrides virtual void device_start() override ATTR_COLD; @@ -103,16 +103,16 @@ private: uint8_t m_port_b, m_ddr_b, m_in_b; uint8_t m_port_c, m_ddr_c, m_in_c; - uint8_t m_ca_level, m_cb_level, m_interrupt_level; - uint8_t m_cr; uint8_t m_air; - uint8_t m_irq_level[5]; + uint8_t m_irq_latch; void set_interrupt(); void clear_interrupt(); + void portc_line_w(int line, int state); + // helper function to write a single line static void port_line_w(uint8_t &port, int line, int state); }; diff --git a/src/devices/machine/cr511b.cpp b/src/devices/machine/cr511b.cpp index 7f52ced1e20..8d0f6261430 100644 --- a/src/devices/machine/cr511b.cpp +++ b/src/devices/machine/cr511b.cpp @@ -22,11 +22,12 @@ #include "emu.h" #include "cr511b.h" -#define LOG_CMD (1 << 1) -#define LOG_PARAM (1 << 2) -#define LOG_DATA (1 << 3) -#define LOG_SUBQ (1 << 4) -#define LOG_SUBQ2 (1 << 5) // log subq data to popmessage +#define LOG_CMD (1 << 1) +#define LOG_PARAM (1 << 2) +#define LOG_DATA (1 << 3) +#define LOG_SUBQ (1 << 4) +#define LOG_SUBQ2 (1 << 5) // log subq data to popmessage +#define LOG_SUBCODE (1 << 6) #define VERBOSE (LOG_GENERAL | LOG_CMD | LOG_PARAM) @@ -52,6 +53,8 @@ cr511b_device::cr511b_device(const machine_config &mconfig, const char *tag, dev m_drq_cb(*this), m_dten_cb(*this), m_scor_cb(*this), + m_sbcp_cb(*this), + m_subcode_data_cb(*this), m_input_fifo_pos(0), m_output_fifo_pos(0), m_output_fifo_length(0), @@ -88,8 +91,10 @@ void cr511b_device::device_start() cdrom_image_device::device_start(); m_frame_timer = timer_alloc(FUNC(cr511b_device::frame_cb), this); + m_subcode_timer = timer_alloc(FUNC(cr511b_device::subcode_cb), this); m_stch_timer = timer_alloc(FUNC(cr511b_device::stch), this); m_sten_timer = timer_alloc(FUNC(cr511b_device::sten), this); + m_scor_timer = timer_alloc(FUNC(cr511b_device::scor), this); std::fill(std::begin(m_input_fifo), std::end(m_input_fifo), 0x00); std::fill(std::begin(m_output_fifo), std::end(m_output_fifo), 0x00); @@ -102,6 +107,9 @@ void cr511b_device::device_start() save_item(NAME(m_output_fifo_length)); save_item(NAME(m_status)); save_item(NAME(m_sector_size)); + save_item(NAME(m_subcode_count)); + save_item(NAME(m_subcode_buffer)); + save_item(NAME(m_subcode_valid)); save_item(NAME(m_transfer_lba)); save_item(NAME(m_transfer_sectors)); save_item(NAME(m_transfer_length)); @@ -210,16 +218,52 @@ TIMER_CALLBACK_MEMBER(cr511b_device::frame_cb) } else if (m_status & STATUS_PLAYING) { - // TODO: subcode handling - m_scor_cb(0); - m_scor_cb(1); + if (!m_cdda->audio_paused()) + { + uint32_t lba = m_cdda->get_audio_lba(); + + LOGMASKED(LOG_SUBCODE, "Fetching new subchannel data for sector %d\n", lba); + + uint32_t subsize = get_toc().tracks[get_track(lba)].subsize; + + m_subcode_count = 0; + m_subcode_valid = read_subcode(lba, m_subcode_buffer) && (subsize == 96); + + if (m_subcode_valid) + m_subcode_timer->adjust(attotime::zero, 0, attotime::from_hz(75 * 98)); + } + + m_scor_timer->adjust(attotime::from_usec(64), 1); // TODO: Timing + } +} + +TIMER_CALLBACK_MEMBER(cr511b_device::subcode_cb) +{ + if (!m_cdda->audio_paused()) + { + // we skip the first two (sync) bytes + if (m_subcode_count > 1 && m_subcode_count < 98) + { + uint8_t data = m_subcode_buffer[m_subcode_count - 2]; + + LOGMASKED(LOG_SUBCODE, "Subcode %d = %02x\n", m_subcode_count - 2, data); + + m_subcode_data_cb(bitswap<8>(data, 0, 1, 2, 3, 4, 5, 6, 7)); + + m_sbcp_cb(0); + m_sbcp_cb(1); + } + + m_subcode_count++; } } TIMER_CALLBACK_MEMBER(cr511b_device::stch) { - m_stch_cb(1); - m_stch_cb(0); + m_sten_cb(param); + + if (param == 0) + m_stch_timer->adjust(attotime::from_usec(64 / 64), 1); } void cr511b_device::status_change(uint8_t status) @@ -233,16 +277,19 @@ void cr511b_device::status_change(uint8_t status) else m_frame_timer->adjust(attotime::never); - m_stch_timer->adjust(attotime::from_usec(64 * 3)); // TODO + if (!(m_status & STATUS_PLAYING)) + m_subcode_timer->adjust(attotime::never); + + m_stch_timer->adjust(attotime::from_usec(64 * 3), 0); // TODO: Timing } } TIMER_CALLBACK_MEMBER(cr511b_device::sten) { - m_status_ready = true; + m_sten_cb(param); - m_sten_cb(0); - m_sten_cb(1); + if (param == 0) + m_sten_timer->adjust(attotime::from_usec(64 / 64), 1); } void cr511b_device::status_enable(uint8_t output_length) @@ -257,10 +304,19 @@ void cr511b_device::status_enable(uint8_t output_length) if (m_input_fifo[0] != 0x87 || (VERBOSE & LOG_SUBQ)) LOGMASKED(LOG_CMD, "-> Output: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", m_output_fifo[0], m_output_fifo[1], m_output_fifo[2], m_output_fifo[3], m_output_fifo[4], m_output_fifo[5], m_output_fifo[6], m_output_fifo[7], m_output_fifo[8], m_output_fifo[9], m_output_fifo[10], m_output_fifo[11]); - m_sten_timer->adjust(attotime::from_usec(64 * 4)); // TODO + m_status_ready = true; + m_sten_timer->adjust(attotime::from_usec(64 * 4), 0); // TODO: Timing } } +TIMER_CALLBACK_MEMBER(cr511b_device::scor) +{ + m_scor_cb(param); + + if (param == 1) + m_scor_timer->adjust(attotime::from_usec(64), 0); +} + void cr511b_device::audio_end_cb(int state) { if (!state) @@ -271,6 +327,47 @@ void cr511b_device::audio_end_cb(int state) status_change(m_status & ~STATUS_PLAYING); } +void cr511b_device::play_audio(uint32_t start, uint32_t end) +{ + if (start == 0 && end == 0) + { + LOGMASKED(LOG_CMD, "Stop audio\n"); + + uint8_t status = m_status; + + if (m_cdda->audio_active()) + status |= STATUS_SUCCESS; + + m_cdda->stop_audio(); + + status &= ~STATUS_PLAYING; + status &= ~STATUS_MOTOR; + + status_change(status); + } + else if (start < end) + { + LOGMASKED(LOG_CMD, "Playing audio %02d:%02d.%02d to %02d:%02d.%02d (LBA %d to %d)\n", + m_input_fifo[1], m_input_fifo[2], m_input_fifo[3], + m_input_fifo[4], m_input_fifo[5], m_input_fifo[6], start, end); + + m_cdda->start_audio(start, end - start); + + uint8_t status = m_status; + + status |= STATUS_PLAYING; + status |= STATUS_MOTOR; + + status_change(status); + } + else + { + LOGMASKED(LOG_CMD, "Invalid range %d to %d!\n", start, end); + + status_change(m_status | STATUS_ERROR); + } +} + uint8_t cr511b_device::read() { uint8_t data = 0xff; @@ -439,8 +536,15 @@ void cr511b_device::cmd_play_lba() LOGMASKED(LOG_CMD, "Command: Play LBA\n"); LOGPARAM; - // haven't found anything that uses it yet - fatalerror("Play LBA: Not implemented\n"); + uint32_t start = (m_input_fifo[1] << 16) | (m_input_fifo[2] << 8) | (m_input_fifo[3] << 0); + uint32_t end = (m_input_fifo[4] << 16) | (m_input_fifo[5] << 8) | (m_input_fifo[6] << 0); + + // play to the end of the disc? + if (end == 0x7fffff) + end = get_track_start(0xaa) - 1; + + play_audio(start, end); + status_enable(0); } void cr511b_device::cmd_play_msf() @@ -448,53 +552,17 @@ void cr511b_device::cmd_play_msf() LOGMASKED(LOG_CMD, "Command: Play MSF\n"); LOGPARAM; - uint32_t start = (m_input_fifo[1] << 16) | (m_input_fifo[2] << 8) | (m_input_fifo[3] << 0); - uint32_t end = (m_input_fifo[4] << 16) | (m_input_fifo[5] << 8) | (m_input_fifo[6] << 0); + uint32_t start_msf = (m_input_fifo[1] << 16) | (m_input_fifo[2] << 8) | (m_input_fifo[3] << 0); + uint32_t end_msf = (m_input_fifo[4] << 16) | (m_input_fifo[5] << 8) | (m_input_fifo[6] << 0); - int32_t start_lba = msf_to_lba(start); - int32_t end_lba = msf_to_lba(end); + int32_t start = start_msf ? msf_to_lba(start_msf) : 0; + int32_t end = end_msf ? msf_to_lba(end_msf) : 0; // play to the end of the disc? if (end == 0xffffff) - end_lba = get_track_start(0xaa) - 1; - - if (start == 0 && end == 0) - { - LOGMASKED(LOG_CMD, "Stop audio\n"); - - uint8_t status = m_status; - - if (m_cdda->audio_active()) - status |= STATUS_SUCCESS; - - m_cdda->stop_audio(); - - status &= ~STATUS_PLAYING; - status &= ~STATUS_MOTOR; - - status_change(status); - } - else if (start_lba < end_lba) - { - LOGMASKED(LOG_CMD, "Playing audio %02d:%02d.%02d to %02d:%02d.%02d (LBA %d to %d)\n", - m_input_fifo[1], m_input_fifo[2], m_input_fifo[3], - m_input_fifo[4], m_input_fifo[5], m_input_fifo[6], start_lba, end_lba); - - m_cdda->start_audio(start_lba, end_lba - start_lba); - - uint8_t status = m_status; - - status |= STATUS_PLAYING; - status |= STATUS_MOTOR; - - status_change(status); - } - else - { - LOGMASKED(LOG_CMD, "Invalid range %d to %d!\n", start_lba, end_lba); - status_change(m_status | STATUS_ERROR); - } + end = get_track_start(0xaa) - 1; + play_audio(start, end); status_enable(0); } @@ -508,6 +576,10 @@ void cr511b_device::cmd_play_track() uint8_t end_track = m_input_fifo[3]; uint8_t end_index = m_input_fifo[4]; // TODO + // cd+g/cd+midi mode sends an all 0x00 cmd after starting the motor? + if (start_track == 0 || end_track == 0) + return; + uint32_t start_lba = get_track_start(start_track - 1); uint32_t end_lba = get_track_start(end_track - 1) - 1; @@ -515,7 +587,7 @@ void cr511b_device::cmd_play_track() m_cdda->start_audio(start_lba, end_lba - start_lba); - status_change(m_status | STATUS_PLAYING | STATUS_MOTOR); + status_change(m_status | STATUS_PLAYING | STATUS_MOTOR); status_enable(0); } diff --git a/src/devices/machine/cr511b.h b/src/devices/machine/cr511b.h index e773c8b1f82..b5c7727872e 100644 --- a/src/devices/machine/cr511b.h +++ b/src/devices/machine/cr511b.h @@ -50,6 +50,8 @@ public: auto drq_cb() { return m_drq_cb.bind(); } auto dten_cb() { return m_dten_cb.bind(); } auto scor_cb() { return m_scor_cb.bind(); } + auto sbcp_cb() { return m_sbcp_cb.bind(); } + auto subcode_data_cb() { return m_subcode_data_cb.bind(); } uint8_t read(); void write(uint8_t data); @@ -72,6 +74,7 @@ private: int size_to_track_type(); TIMER_CALLBACK_MEMBER(frame_cb); + TIMER_CALLBACK_MEMBER(subcode_cb); TIMER_CALLBACK_MEMBER(stch); void status_change(uint8_t status); @@ -79,7 +82,10 @@ private: TIMER_CALLBACK_MEMBER(sten); void status_enable(uint8_t output_length); + TIMER_CALLBACK_MEMBER(scor); + void audio_end_cb(int state); + void play_audio(uint32_t start, uint32_t end); // commands void cmd_seek(); @@ -124,10 +130,15 @@ private: devcb_write_line m_drq_cb; devcb_write_line m_dten_cb; devcb_write_line m_scor_cb; + devcb_write_line m_sbcp_cb; + devcb_write8 m_subcode_data_cb; emu_timer *m_frame_timer; + emu_timer *m_subcode_timer; + emu_timer *m_stch_timer; emu_timer *m_sten_timer; + emu_timer *m_scor_timer; uint8_t m_input_fifo[16]; uint8_t m_input_fifo_pos; @@ -139,6 +150,10 @@ private: uint8_t m_status; uint16_t m_sector_size; + uint8_t m_subcode_count; + uint8_t m_subcode_buffer[96]; + bool m_subcode_valid; + uint32_t m_transfer_lba; uint16_t m_transfer_sectors; uint32_t m_transfer_length; diff --git a/src/mame/amiga/amiga.cpp b/src/mame/amiga/amiga.cpp index 350aabe92cb..12186dd82e3 100644 --- a/src/mame/amiga/amiga.cpp +++ b/src/mame/amiga/amiga.cpp @@ -1980,12 +1980,14 @@ void cdtv_state::cdtv(machine_config &config) CR511B(config, m_cdrom, 0); m_cdrom->add_route(0, "speaker", 1.0, 0); m_cdrom->add_route(1, "speaker", 1.0, 1); - m_cdrom->scor_cb().set(m_tpi, FUNC(tpi6525_device::i1_w)).invert(); - m_cdrom->stch_cb().set(m_tpi, FUNC(tpi6525_device::i2_w)).invert(); - m_cdrom->sten_cb().set(m_tpi, FUNC(tpi6525_device::i3_w)); + m_cdrom->sbcp_cb().set(m_tpi, FUNC(tpi6525_device::pc0_w)).invert(); + m_cdrom->scor_cb().set(m_tpi, FUNC(tpi6525_device::pc1_w)).invert(); + m_cdrom->stch_cb().set(m_tpi, FUNC(tpi6525_device::pc2_w)).invert(); + m_cdrom->sten_cb().set(m_tpi, FUNC(tpi6525_device::pc3_w)); m_cdrom->sten_cb().append(FUNC(cdtv_state::sten_w)); - m_cdrom->drq_cb().set(m_tpi, FUNC(tpi6525_device::i4_w)); + m_cdrom->drq_cb().set(m_tpi, FUNC(tpi6525_device::pc4_w)); m_cdrom->drq_cb().append(FUNC(cdtv_state::drq_w)); + m_cdrom->subcode_data_cb().set(m_tpi, FUNC(tpi6525_device::pa_w)); SOFTWARE_LIST(config, "cd_list").set_original("cdtv"); } diff --git a/src/mame/commodore/cbm2.cpp b/src/mame/commodore/cbm2.cpp index 2cb1b975e42..e2e0989b82e 100644 --- a/src/mame/commodore/cbm2.cpp +++ b/src/mame/commodore/cbm2.cpp @@ -1975,7 +1975,7 @@ void cbm2_state::ext_tpi_pc_w(uint8_t data) void cbm2_state::ext_cia_irq_w(int state) { - m_tpi1->i3_w(!state); + m_tpi1->pc3_w(!state); } uint8_t cbm2_state::ext_cia_pb_r() @@ -2055,7 +2055,7 @@ void cbm2_state::ext_cia_pb_w(uint8_t data) TIMER_CALLBACK_MEMBER(cbm2_state::tod_tick) { - m_tpi1->i0_w(m_todclk); + m_tpi1->pc0_w(m_todclk); if (m_ext_pic) m_ext_pic->ir2_w(m_todclk); @@ -2291,7 +2291,7 @@ void p500_state::p500_ntsc(machine_config &config) MOS6551(config, m_acia, VIC6567_CLOCK); m_acia->set_xtal(XTAL(1'843'200)); - m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::i4_w)); + m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::pc4_w)); m_acia->txd_handler().set(RS232_TAG, FUNC(rs232_port_device::write_txd)); m_acia->dtr_handler().set(RS232_TAG, FUNC(rs232_port_device::write_dtr)); m_acia->rts_handler().set(RS232_TAG, FUNC(rs232_port_device::write_rts)); @@ -2299,7 +2299,7 @@ void p500_state::p500_ntsc(machine_config &config) MOS6526A(config, m_cia, XTAL(14'318'181)/14); m_cia->set_tod_clock(60); - m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::i2_w)); + m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::pc2_w)); m_cia->cnt_wr_callback().set(m_user, FUNC(cbm2_user_port_device::cnt_w)); m_cia->sp_wr_callback().set(m_user, FUNC(cbm2_user_port_device::sp_w)); m_cia->pa_rd_callback().set(FUNC(cbm2_state::cia_pa_r)); @@ -2332,7 +2332,7 @@ void p500_state::p500_ntsc(machine_config &config) IEEE488(config, m_ieee, 0); ieee488_slot_device::add_cbm_defaults(config, "c8050"); - m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::i1_w)); + m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::pc1_w)); PET_DATASSETTE_PORT(config, m_cassette, cbm_datassette_devices, nullptr); m_cassette->read_handler().set(m_cia, FUNC(mos6526_device::flag_w)); @@ -2424,12 +2424,12 @@ void p500_state::p500_pal(machine_config &config) MOS6551(config, m_acia, 0); m_acia->set_xtal(XTAL(1'843'200)); - m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::i4_w)); + m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::pc4_w)); m_acia->txd_handler().set(RS232_TAG, FUNC(rs232_port_device::write_txd)); MOS6526A(config, m_cia, XTAL(17'734'472)/18); m_cia->set_tod_clock(50); - m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::i2_w)); + m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::pc2_w)); m_cia->cnt_wr_callback().set(m_user, FUNC(cbm2_user_port_device::cnt_w)); m_cia->sp_wr_callback().set(m_user, FUNC(cbm2_user_port_device::sp_w)); m_cia->pa_rd_callback().set(FUNC(cbm2_state::cia_pa_r)); @@ -2462,7 +2462,7 @@ void p500_state::p500_pal(machine_config &config) IEEE488(config, m_ieee, 0); ieee488_slot_device::add_cbm_defaults(config, "c8050"); - m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::i1_w)); + m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::pc1_w)); PET_DATASSETTE_PORT(config, m_cassette, cbm_datassette_devices, nullptr); m_cassette->read_handler().set(m_cia, FUNC(mos6526_device::flag_w)); @@ -2554,12 +2554,12 @@ void cbm2_state::cbm2lp_ntsc(machine_config &config) MOS6551(config, m_acia, 0); m_acia->set_xtal(XTAL(1'843'200)); - m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::i4_w)); + m_acia->irq_handler().set(m_tpi1, FUNC(tpi6525_device::pc4_w)); m_acia->txd_handler().set(RS232_TAG, FUNC(rs232_port_device::write_txd)); MOS6526A(config, m_cia, XTAL(18'000'000)/9); m_cia->set_tod_clock(60); - m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::i2_w)); + m_cia->irq_wr_callback().set(m_tpi1, FUNC(tpi6525_device::pc2_w)); m_cia->cnt_wr_callback().set(m_user, FUNC(cbm2_user_port_device::cnt_w)); m_cia->sp_wr_callback().set(m_user, FUNC(cbm2_user_port_device::sp_w)); m_cia->pa_rd_callback().set(FUNC(cbm2_state::cia_pa_r)); @@ -2592,7 +2592,7 @@ void cbm2_state::cbm2lp_ntsc(machine_config &config) IEEE488(config, m_ieee, 0); ieee488_slot_device::add_cbm_defaults(config, "c8050"); - m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::i1_w)); + m_ieee->srq_callback().set(m_tpi1, FUNC(tpi6525_device::pc1_w)); PET_DATASSETTE_PORT(config, m_cassette, cbm_datassette_devices, nullptr); m_cassette->read_handler().set(m_cia, FUNC(mos6526_device::flag_w)); -- cgit v1.2.3