summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author wilbertpol <wilbertpol@users.noreply.github.com>2022-04-25 04:13:21 +0100
committer GitHub <noreply@github.com>2022-04-24 23:13:21 -0400
commit2dda885973695335c72f7413f9e1b72738405e03 (patch)
treeb7a540a53970411d63aa74924e3888afb4a33274
parent174c246037911759fbbdff64c1da909802efcf83 (diff)
upd7759.cpp: Add support for mode switching. (#9614)
-rw-r--r--src/devices/sound/upd7759.cpp203
-rw-r--r--src/devices/sound/upd7759.h89
2 files changed, 158 insertions, 134 deletions
diff --git a/src/devices/sound/upd7759.cpp b/src/devices/sound/upd7759.cpp
index cbd6bca0f83..1e9a98b8a3d 100644
--- a/src/devices/sound/upd7759.cpp
+++ b/src/devices/sound/upd7759.cpp
@@ -126,9 +126,14 @@
#include "upd7759.h"
-#define DEBUG_STATES (0)
+#define MASK_LOG_STATE (1U << 1)
+#define MASK_LOG_DRQ (1U << 2)
+//#define VERBOSE (MASK_LOG_STATE|MASK_LOG_DRQ)
+#include "logmacro.h"
+#define LOG_STATE(...) LOGMASKED(MASK_LOG_STATE, __VA_ARGS__)
+#define LOG_DRQ(...) LOGMASKED(MASK_LOG_DRQ, __VA_ARGS__)
/************************************************************
@@ -136,7 +141,7 @@
*************************************************************/
-/* step value fractional bits */
+// step value fractional bits
#define FRAC_BITS 20
#define FRAC_ONE (1 << FRAC_BITS)
#define FRAC_MASK (FRAC_ONE - 1)
@@ -168,6 +173,7 @@ upd775x_device::upd775x_device(const machine_config &mconfig, device_type type,
, m_offset(0)
, m_repeat_offset(0)
, m_start_delay(0)
+ , m_mode(MODE_STAND_ALONE)
, m_adpcm_state(0)
, m_adpcm_data(0)
, m_sample(0)
@@ -209,13 +215,10 @@ upd7756_device::upd7756_device(const machine_config &mconfig, device_type type,
void upd775x_device::device_start()
{
- // allocate a stream channel
m_channel = stream_alloc(0, 1, clock()/4);
- // compute the stepping rate based on the chip's clock speed
m_step = 4 * FRAC_ONE;
- // compute the clock period
m_clock_period = clock() ? attotime::from_hz(clock()) : attotime::zero;
save_item(NAME(m_pos));
@@ -243,6 +246,8 @@ void upd775x_device::device_start()
save_item(NAME(m_adpcm_state));
save_item(NAME(m_adpcm_data));
save_item(NAME(m_sample));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_md));
}
void upd775x_device::device_clock_changed()
@@ -261,14 +266,12 @@ void upd7759_device::device_start()
{
upd775x_device::device_start();
- // chip configuration
m_sample_offset_shift = 1;
m_timer = timer_alloc(TID_SLAVE_UPDATE);
m_drqcallback.resolve_safe();
- // toggle the reset line to finish the reset
device_reset();
}
@@ -277,7 +280,6 @@ void upd7756_device::device_start()
{
upd775x_device::device_start();
- // toggle the reset line to finish the reset
device_reset();
}
@@ -288,7 +290,7 @@ void upd7756_device::device_start()
void upd775x_device::device_reset()
{
m_pos = 0;
- //m_fifo_in = 0; // this seems keeping state when /RESET line asserted (test case: konmedal.cpp games)
+ //m_fifo_in = 0; // this seems to keep state when /RESET line asserted (test case: konmedal.cpp games)
m_state = STATE_IDLE;
m_clocks_left = 0;
m_nibbles_left = 0;
@@ -305,13 +307,13 @@ void upd775x_device::device_reset()
m_adpcm_state = 0;
m_adpcm_data = 0;
m_sample = 0;
+ m_mode = MODE_STAND_ALONE;
}
void upd7759_device::device_reset()
{
upd775x_device::device_reset();
- // turn off any timer
m_timer->adjust(attotime::never);
if (m_drq)
@@ -365,11 +367,9 @@ static const int upd775x_state_table[16] = { -1, -1, 0, 0, 1, 2, 2, 3, -1, -1, 0
void upd775x_device::update_adpcm(int data)
{
- /* update the sample and the state */
m_sample += upd775x_step[m_adpcm_state][data];
m_adpcm_state += upd775x_state_table[data];
- /* clamp the state to 0..15 */
if (m_adpcm_state < 0)
m_adpcm_state = 0;
else if (m_adpcm_state > 15)
@@ -388,12 +388,14 @@ void upd775x_device::advance_state()
{
switch (m_state)
{
- /* Idle state: we stick around here while there's nothing to do */
+ // Idle state: we stick around here while there's nothing to do
case STATE_IDLE:
+ // If we have dropped back to idle state we always switch back to stand alone mode
+ m_mode = MODE_STAND_ALONE;
m_clocks_left = 4;
break;
- /* drop DRQ state: update to the intended state */
+ // drop DRQ state: update to the intended state
case STATE_DROP_DRQ:
m_drq = 0;
@@ -401,10 +403,10 @@ void upd775x_device::advance_state()
m_state = m_post_drq_state;
break;
- /* Start state: we begin here as soon as a sample is triggered */
+ // Start state: we begin here as soon as a sample is triggered
case STATE_START:
- m_req_sample = m_md ? m_fifo_in : 0x10;
- if (DEBUG_STATES) logerror("req_sample = %02X\n", m_req_sample);
+ m_req_sample = (m_mode == MODE_STAND_ALONE) ? m_fifo_in : 0x10;
+ LOG_STATE("req_sample = %02X\n", m_req_sample);
/* 35+ cycles after we get here, the /DRQ goes low
* (first byte (number of samples in ROM) should be sent in response)
@@ -413,17 +415,16 @@ void upd775x_device::advance_state()
* Depending on the state the chip was in just before the /MD was set to 0 (reset, standby
* or just-finished-playing-previous-sample) this number can range from 35 up to ~24000).
* It also varies slightly from test to test, but not much - a few cycles at most.) */
- m_clocks_left = 70 + m_start_delay; /* 35 - breaks cotton */
+ m_clocks_left = 70 + m_start_delay;
m_state = STATE_FIRST_REQ;
break;
/* First request state: issue a request for the first byte */
/* The expected response will be the index of the last sample */
case STATE_FIRST_REQ:
- if (DEBUG_STATES) logerror("first data request\n");
+ LOG_STATE("first data request\n");
m_drq = 1;
- /* 44 cycles later, we will latch this value and request another byte */
m_clocks_left = 44;
m_state = STATE_LAST_SAMPLE;
break;
@@ -431,22 +432,20 @@ void upd775x_device::advance_state()
/* Last sample state: latch the last sample value and issue a request for the second byte */
/* The second byte read will be just a dummy */
case STATE_LAST_SAMPLE:
- m_last_sample = m_md ? read_byte(0) : m_fifo_in;
- if (DEBUG_STATES) logerror("last_sample = %02X, requesting dummy 1\n", m_last_sample);
+ m_last_sample = (m_mode == MODE_STAND_ALONE) ? read_byte(0) : m_fifo_in;
+ LOG_STATE("last_sample = %02X, requesting dummy 1\n", m_last_sample);
m_drq = 1;
- /* 28 cycles later, we will latch this value and request another byte */
- m_clocks_left = 28; /* 28 - breaks cotton */
+ m_clocks_left = 28;
m_state = (m_req_sample > m_last_sample) ? STATE_IDLE : STATE_DUMMY1;
break;
/* First dummy state: ignore any data here and issue a request for the third byte */
/* The expected response will be the MSB of the sample address */
case STATE_DUMMY1:
- if (DEBUG_STATES) logerror("dummy1, requesting offset_hi\n");
+ LOG_STATE("dummy1, requesting offset_hi\n");
m_drq = 1;
- /* 32 cycles later, we will latch this value and request another byte */
m_clocks_left = 32;
m_state = STATE_ADDR_MSB;
break;
@@ -454,11 +453,10 @@ void upd775x_device::advance_state()
/* Address MSB state: latch the MSB of the sample address and issue a request for the fourth byte */
/* The expected response will be the LSB of the sample address */
case STATE_ADDR_MSB:
- m_offset = (m_md ? read_byte(m_req_sample * 2 + 5) : m_fifo_in) << (8 + m_sample_offset_shift);
- if (DEBUG_STATES) logerror("offset_hi = %02X, requesting offset_lo\n", m_offset >> (8 + m_sample_offset_shift));
+ m_offset = ((m_mode == MODE_STAND_ALONE) ? read_byte(m_req_sample * 2 + 5) : m_fifo_in) << (8 + m_sample_offset_shift);
+ LOG_STATE("offset_hi = %02X, requesting offset_lo\n", m_offset >> (8 + m_sample_offset_shift));
m_drq = 1;
- /* 44 cycles later, we will latch this value and request another byte */
m_clocks_left = 44;
m_state = STATE_ADDR_LSB;
break;
@@ -466,11 +464,10 @@ void upd775x_device::advance_state()
/* Address LSB state: latch the LSB of the sample address and issue a request for the fifth byte */
/* The expected response will be just a dummy */
case STATE_ADDR_LSB:
- m_offset |= (m_md ? read_byte(m_req_sample * 2 + 6) : m_fifo_in) << m_sample_offset_shift;
- if (DEBUG_STATES) logerror("offset_lo = %02X, requesting dummy 2\n", (m_offset >> m_sample_offset_shift) & 0xff);
+ m_offset |= ((m_mode == MODE_STAND_ALONE) ? read_byte(m_req_sample * 2 + 6) : m_fifo_in) << m_sample_offset_shift;
+ LOG_STATE("offset_lo = %02X, requesting dummy 2\n", (m_offset >> m_sample_offset_shift) & 0xff);
m_drq = 1;
- /* 36 cycles later, we will latch this value and request another byte */
m_clocks_left = 36;
m_state = STATE_DUMMY2;
break;
@@ -480,59 +477,55 @@ void upd775x_device::advance_state()
case STATE_DUMMY2:
m_offset++;
m_first_valid_header = 0;
- if (DEBUG_STATES) logerror("dummy2, requesting block header\n");
+ LOG_STATE("dummy2, requesting block header\n");
m_drq = 1;
- /* 36?? cycles later, we will latch this value and request another byte */
m_clocks_left = 36;
m_state = STATE_BLOCK_HEADER;
break;
- /* Block header state: latch the header and issue a request for the first byte afterwards */
+ // Block header state: latch the header and issue a request for the first byte afterwards
case STATE_BLOCK_HEADER:
- /* if we're in a repeat loop, reset the offset to the repeat point and decrement the count */
if (m_repeat_count)
{
m_repeat_count--;
m_offset = m_repeat_offset;
}
- m_block_header = m_md ? read_byte(m_offset++) : m_fifo_in;
- if (DEBUG_STATES) logerror("header (@%05X) = %02X, requesting next byte\n", m_offset, m_block_header);
+ m_block_header = (m_mode == MODE_STAND_ALONE) ? read_byte(m_offset++) : m_fifo_in;
+ LOG_STATE("header (@%05X) = %02X, requesting next byte\n", m_offset, m_block_header);
m_drq = 1;
- /* our next step depends on the top two bits */
switch (m_block_header & 0xc0)
{
- case 0x00: /* silence */
+ case 0x00: // silence
m_clocks_left = 1024 * ((m_block_header & 0x3f) + 1);
m_state = (m_block_header == 0 && m_first_valid_header) ? STATE_IDLE : STATE_BLOCK_HEADER;
m_sample = 0;
m_adpcm_state = 0;
break;
- case 0x40: /* 256 nibbles */
+ case 0x40: // 256 nibbles
m_sample_rate = (m_block_header & 0x3f) + 1;
m_nibbles_left = 256;
- m_clocks_left = 36; /* just a guess */
+ m_clocks_left = 36; // just a guess
m_state = STATE_NIBBLE_MSN;
break;
- case 0x80: /* n nibbles */
+ case 0x80: // n nibbles
m_sample_rate = (m_block_header & 0x3f) + 1;
- m_clocks_left = 36; /* just a guess */
+ m_clocks_left = 36; // just a guess
m_state = STATE_NIBBLE_COUNT;
break;
- case 0xc0: /* repeat loop */
+ case 0xc0: // repeat loop
m_repeat_count = (m_block_header & 7) + 1;
m_repeat_offset = m_offset;
- m_clocks_left = 36; /* just a guess */
+ m_clocks_left = 36; // just a guess
m_state = STATE_BLOCK_HEADER;
break;
}
- /* set a flag when we get the first non-zero header */
if (m_block_header != 0)
m_first_valid_header = 1;
break;
@@ -540,23 +533,21 @@ void upd775x_device::advance_state()
/* Nibble count state: latch the number of nibbles to play and request another byte */
/* The expected response will be the first data byte */
case STATE_NIBBLE_COUNT:
- m_nibbles_left = (m_md ? read_byte(m_offset++) : m_fifo_in) + 1;
- if (DEBUG_STATES) logerror("nibble_count = %u, requesting next byte\n", (unsigned)m_nibbles_left);
+ m_nibbles_left = ((m_mode == MODE_STAND_ALONE) ? read_byte(m_offset++) : m_fifo_in) + 1;
+ LOG_STATE("nibble_count = %u, requesting next byte\n", (unsigned)m_nibbles_left);
m_drq = 1;
- /* 36?? cycles later, we will latch this value and request another byte */
- m_clocks_left = 36; /* just a guess */
+ m_clocks_left = 36; // just a guess
m_state = STATE_NIBBLE_MSN;
break;
/* MSN state: latch the data for this pair of samples and request another byte */
/* The expected response will be the next sample data or another header */
case STATE_NIBBLE_MSN:
- m_adpcm_data = m_md ? read_byte(m_offset++) : m_fifo_in;
+ m_adpcm_data = (m_mode == MODE_STAND_ALONE) ? read_byte(m_offset++) : m_fifo_in;
update_adpcm(m_adpcm_data >> 4);
m_drq = 1;
- /* we stay in this state until the time for this sample is complete */
m_clocks_left = m_sample_rate * 4;
if (--m_nibbles_left == 0)
m_state = STATE_BLOCK_HEADER;
@@ -564,11 +555,10 @@ void upd775x_device::advance_state()
m_state = STATE_NIBBLE_LSN;
break;
- /* LSN state: process the lower nibble */
+ // LSN state: process the lower nibble
case STATE_NIBBLE_LSN:
update_adpcm(m_adpcm_data & 15);
- /* we stay in this state until the time for this sample is complete */
m_clocks_left = m_sample_rate * 4;
if (--m_nibbles_left == 0)
m_state = STATE_BLOCK_HEADER;
@@ -577,7 +567,6 @@ void upd775x_device::advance_state()
break;
}
- /* if there's a DRQ, fudge the state */
if (m_drq)
{
m_post_drq_state = m_state;
@@ -596,6 +585,7 @@ void upd775x_device::advance_state()
void upd7759_device::device_timer(emu_timer &timer, device_timer_id id, int param)
{
uint8_t olddrq = m_drq;
+ int old_state = m_state;
switch (id)
{
@@ -611,21 +601,23 @@ void upd7759_device::device_timer(emu_timer &timer, device_timer_id id, int para
internal_start_w(param);
break;
+ case TID_MD_WRITE:
+ internal_md_w(param);
+ break;
+
case TID_SLAVE_UPDATE:
- /* update the stream */
m_channel->update();
- /* advance the state */
advance_state();
- /* if the DRQ changed, update it */
- if (DEBUG_STATES)
- logerror("upd7759_slave_update: DRQ %d->%d\n", olddrq, m_drq);
+ LOG_STATE("upd7759_slave_update: DRQ %d->%d\n", olddrq, m_drq);
if (olddrq != m_drq)
+ {
+ LOG_DRQ("DRQ changed %d->%d\n", olddrq, m_drq);
m_drqcallback(m_drq);
+ }
- /* set a timer to go off when that is done */
- if (m_state != STATE_IDLE)
+ if (m_state != STATE_IDLE || old_state != STATE_IDLE)
m_timer->adjust(m_clock_period * m_clocks_left);
break;
@@ -647,18 +639,31 @@ WRITE_LINE_MEMBER( upd775x_device::reset_w )
void upd775x_device::internal_reset_w(int state)
{
- /* update the reset value */
uint8_t oldreset = m_reset;
m_reset = (state != 0);
- /* update the stream first */
m_channel->update();
- /* on the falling edge, reset everything */
if (oldreset && !m_reset)
device_reset();
}
+void upd7759_device::internal_reset_w(int state)
+{
+ uint8_t oldreset = m_reset;
+ upd775x_device::internal_reset_w(state);
+
+ if (!oldreset && m_reset)
+ {
+ if (!m_md)
+ {
+ m_mode = MODE_SLAVE;
+ m_state = STATE_START;
+ m_timer->adjust(attotime::zero);
+ }
+ }
+}
+
WRITE_LINE_MEMBER( upd775x_device::start_w )
{
synchronize(TID_START_WRITE, state);
@@ -666,23 +671,18 @@ WRITE_LINE_MEMBER( upd775x_device::start_w )
void upd7759_device::internal_start_w(int state)
{
- /* update the start value */
uint8_t oldstart = m_start;
m_start = (state != 0);
- if (DEBUG_STATES)
- logerror("upd7759_start_w: %d->%d\n", oldstart, m_start);
+ LOG_STATE("upd7759_start_w: %d->%d\n", oldstart, m_start);
- /* update the stream first */
m_channel->update();
- /* on the rising edge, if we're idle, start going, but not if we're held in reset */
- if (m_state == STATE_IDLE && !oldstart && m_start && m_reset)
+ if (m_state == STATE_IDLE && oldstart && !m_start && m_reset)
{
m_state = STATE_START;
- /* for slave mode, start the timer going */
- if (!m_md)
+ if (m_mode == MODE_SLAVE)
m_timer->adjust(attotime::zero);
}
}
@@ -690,37 +690,61 @@ void upd7759_device::internal_start_w(int state)
void upd7756_device::internal_start_w(int state)
{
- /* update the start value */
uint8_t oldstart = m_start;
m_start = (state != 0);
- if (DEBUG_STATES)
- logerror("upd7759_start_w: %d->%d\n", oldstart, m_start);
+ LOG_STATE("upd7759_start_w: %d->%d\n", oldstart, m_start);
+
+ m_channel->update();
+
+ if (m_state == STATE_IDLE && oldstart && !m_start && m_reset)
+ {
+ m_state = STATE_START;
+ }
+}
+
+
+WRITE_LINE_MEMBER(upd7759_device::md_w)
+{
+ // When called from machine configs/during start up set the mode pin directly.
+ if (m_timer == nullptr)
+ {
+ m_md = state;
+ return;
+ }
+ synchronize(TID_MD_WRITE, state);
+}
+
+
+void upd7759_device::internal_md_w(int state)
+{
+ uint8_t old_md = m_md;
+ m_md = (state != 0);
+
+ LOG_STATE("upd7759_md_w: %d->%d\n", old_md, m_md);
- /* update the stream first */
m_channel->update();
- /* on the rising edge, if we're idle, start going, but not if we're held in reset */
- if (m_state == STATE_IDLE && !oldstart && m_start && m_reset)
+ if (m_state == STATE_IDLE && old_md && !m_md && m_reset)
{
+ m_mode = MODE_SLAVE;
m_state = STATE_START;
+ m_timer->adjust(attotime::zero);
}
}
void upd775x_device::port_w(u8 data)
{
- /* update the FIFO value */
synchronize(TID_PORT_WRITE, data);
}
READ_LINE_MEMBER( upd775x_device::busy_r )
{
- /* update the stream first */
m_channel->update();
- /* return /BUSY */
+ // return /BUSY
return (m_state == STATE_IDLE);
}
@@ -737,48 +761,39 @@ void upd775x_device::sound_stream_update(sound_stream &stream, std::vector<read_
uint32_t step = m_step;
uint32_t pos = m_pos;
- /* loop until done */
u32 index = 0;
if (m_state != STATE_IDLE)
for ( ; index < outputs[0].samples(); index++)
{
- /* store the current sample */
outputs[0].put(index, sample);
- /* advance by the number of clocks/output sample */
pos += step;
- /* handle clocks, but only in standalone mode */
- while (m_md && pos >= FRAC_ONE)
+ while ((m_mode == MODE_STAND_ALONE) && pos >= FRAC_ONE)
{
int clocks_this_time = pos >> FRAC_BITS;
if (clocks_this_time > clocks_left)
clocks_this_time = clocks_left;
- /* clock once */
pos -= clocks_this_time * FRAC_ONE;
clocks_left -= clocks_this_time;
- /* if we're out of clocks, time to handle the next state */
if (clocks_left == 0)
{
- /* advance one state; if we hit idle, bail */
advance_state();
if (m_state == STATE_IDLE)
break;
- /* reimport the variables that we cached */
clocks_left = m_clocks_left;
sample = stream_buffer::sample_t(m_sample) * sample_scale;
}
}
}
- /* if we got out early, just zap the rest of the buffer */
+ // if we got out early, just zap the rest of the buffer
for (; index < outputs[0].samples(); index++)
outputs[0].put(index, 0);
- /* flush the state back */
m_clocks_left = clocks_left;
m_pos = pos;
}
diff --git a/src/devices/sound/upd7759.h b/src/devices/sound/upd7759.h
index 5508e8d92bb..23f24ad1ae5 100644
--- a/src/devices/sound/upd7759.h
+++ b/src/devices/sound/upd7759.h
@@ -11,8 +11,6 @@
/* There are two modes for the uPD7759, selected through the !MD pin.
This is the mode select input. High is stand alone, low is slave.
- We're making the assumption that nobody switches modes through
- software.
*/
class upd775x_device : public device_t,
@@ -37,7 +35,8 @@ protected:
TID_PORT_WRITE,
TID_START_WRITE,
TID_RESET_WRITE,
- TID_SLAVE_UPDATE
+ TID_SLAVE_UPDATE,
+ TID_MD_WRITE
};
// chip states
@@ -57,6 +56,12 @@ protected:
STATE_NIBBLE_MSN,
STATE_NIBBLE_LSN
};
+ // chip modes
+ enum
+ {
+ MODE_STAND_ALONE,
+ MODE_SLAVE
+ };
upd775x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -74,45 +79,46 @@ protected:
virtual void advance_state();
// internal state
- sound_stream *m_channel; /* stream channel for playback */
-
- /* chip configuration */
- uint8_t m_sample_offset_shift; /* header sample address shift (access data > 0xffff) */
-
- /* internal clock to output sample rate mapping */
- uint32_t m_pos; /* current output sample position */
- uint32_t m_step; /* step value per output sample */
- attotime m_clock_period; /* clock period */
-
- /* I/O lines */
- uint8_t m_fifo_in; /* last data written to the sound chip */
- uint8_t m_reset; /* current state of the RESET line */
- uint8_t m_start; /* current state of the START line */
- uint8_t m_drq; /* current state of the DRQ line */
-
- /* internal state machine */
- int8_t m_state; /* current overall chip state */
- int32_t m_clocks_left; /* number of clocks left in this state */
- uint16_t m_nibbles_left; /* number of ADPCM nibbles left to process */
- uint8_t m_repeat_count; /* number of repeats remaining in current repeat block */
- int8_t m_post_drq_state; /* state we will be in after the DRQ line is dropped */
- int32_t m_post_drq_clocks; /* clocks that will be left after the DRQ line is dropped */
- uint8_t m_req_sample; /* requested sample number */
- uint8_t m_last_sample; /* last sample number available */
- uint8_t m_block_header; /* header byte */
- uint8_t m_sample_rate; /* number of UPD clocks per ADPCM nibble */
- uint8_t m_first_valid_header; /* did we get our first valid header yet? */
- uint32_t m_offset; /* current ROM offset */
- uint32_t m_repeat_offset; /* current ROM repeat offset */
+ sound_stream *m_channel; // stream channel for playback
+
+ // chip configuration
+ uint8_t m_sample_offset_shift; // header sample address shift (access data > 0xffff)
+
+ // internal clock to output sample rate mapping
+ uint32_t m_pos; // current output sample position
+ uint32_t m_step; // step value per output sample
+ attotime m_clock_period; // clock period
+
+ // I/O lines
+ uint8_t m_fifo_in; // last data written to the sound chip
+ uint8_t m_reset; // current state of the RESET line
+ uint8_t m_start; // current state of the START line
+ uint8_t m_drq; // current state of the DRQ line
+
+ // internal state machine
+ int8_t m_state; // current overall chip state
+ int32_t m_clocks_left; // number of clocks left in this state
+ uint16_t m_nibbles_left; // number of ADPCM nibbles left to process
+ uint8_t m_repeat_count; // number of repeats remaining in current repeat block
+ int8_t m_post_drq_state; // state we will be in after the DRQ line is dropped
+ int32_t m_post_drq_clocks; // clocks that will be left after the DRQ line is dropped
+ uint8_t m_req_sample; // requested sample number
+ uint8_t m_last_sample; // last sample number available
+ uint8_t m_block_header; // header byte
+ uint8_t m_sample_rate; // number of UPD clocks per ADPCM nibble
+ uint8_t m_first_valid_header; // did we get our first valid header yet?
+ uint32_t m_offset; // current ROM offset
+ uint32_t m_repeat_offset; // current ROM repeat offset
uint32_t m_start_delay;
+ int m_mode; // current mode of the sound chip
- /* ADPCM processing */
- int8_t m_adpcm_state; /* ADPCM state index */
- uint8_t m_adpcm_data; /* current byte of ADPCM data */
- int16_t m_sample; /* current sample value */
+ // ADPCM processing
+ int8_t m_adpcm_state; // ADPCM state index
+ uint8_t m_adpcm_data; // current byte of ADPCM data
+ int16_t m_sample; // current sample value
- /* ROM access */
- int m_md; /* High is stand alone, low is slave. */
+ // ROM access
+ int m_md; // High is stand alone, low is slave.
};
class upd7759_device : public upd775x_device
@@ -122,10 +128,11 @@ public:
upd7759_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = STANDARD_CLOCK);
- DECLARE_WRITE_LINE_MEMBER( md_w ) { m_md = state; }
+ DECLARE_WRITE_LINE_MEMBER( md_w );
protected:
virtual void internal_start_w(int state) override;
+ virtual void internal_reset_w(int state) override;
upd7759_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -133,6 +140,8 @@ protected:
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
+ void internal_md_w(int state);
+
devcb_write_line m_drqcallback;
emu_timer *m_timer;
};