Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 18 additions & 115 deletions src/mame/philips/cdicdic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,6 @@
#define VERBOSE (0)
#include "logmacro.h"


namespace {

[[maybe_unused]] constexpr int16_t clip_int16(int32_t sample)
{
return int16_t(std::clamp<int32_t>(sample, -32768, 32767));
}

} // anonymous namespace


// device type definition
DEFINE_DEVICE_TYPE(CDI_CDIC, cdicdic_device, "cdicdic", "CD-i CDIC")

Expand Down Expand Up @@ -267,119 +256,33 @@ const uint8_t cdicdic_device::s_sector_scramble[2448] =
// MEMBER FUNCTIONS
//**************************************************************************

void cdicdic_device::decode_xa_unit(const uint8_t param, int16_t sample, int16_t &sample0, int16_t &sample1, int16_t &out_buffer)
{
int16_t const *const filter = s_xa_filter_coef[(param >> 4) & 3];
uint8_t const range = (param & 0xf);
sample = (sample >> range) + ((filter[0] * sample0 + filter[1] * sample1 + 128) >> 8);

//int16_t const sample16 = clip_int16(sample);
sample1 = std::exchange(sample0, sample);
out_buffer = sample0;
static inline int16_t clip_int16(int32_t sample) {
if (sample < -32768)
return -32768;
if (sample > 32767)
return 32767;
return static_cast<int16_t>(sample);
}

void cdicdic_device::decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
{
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags = xa[4 + (s << 1)];

for (int32_t i = 0; i < 28; i++)
{
//int16_t sample = ((*data) & 0xf) << 12;
int16_t d = (xa[16 + (i << 2) + s] & 0xf) << 12;
decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
}

flags = xa[5 + (s << 1)];

for (int32_t i = 0; i < 28; i++)
{
//int16_t sample = (*data >> 4) << 12;
int16_t d = (xa[16 + (i << 2) + s] >> 4) << 12;
decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
}
}

xa += 128;
}
inline void rotate_samples(int16_t val, int16_t& a, int16_t& b, int16_t& output) {
b = a;
a = val;
output = a;
}

void cdicdic_device::decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
void cdicdic_device::decode_xa_unit(const uint8_t param, int16_t sample, int16_t& sample0, int16_t& sample1, int16_t& out_buffer)
{
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags = xa[4 + s];
for (int32_t i = 0; i < 28; i++)
{
int16_t d = (xa[16 + (i << 2) + s] << 8);
decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
}
}

xa += 128;
}
}
const int16_t* filter = s_xa_filter_coef[(param >> 4) & 3]; // High bits are reserved.
uint8_t range = (param & 0xf);
if (range > 12) range = 12; // Should be at most 8. Some decoders set 13..15 to 9.

void cdicdic_device::decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
{
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags0 = xa[4 + (s << 1)];
uint8_t flags1 = xa[5 + (s << 1)];
int32_t sample32 = (int32_t)sample; // Work in 32-bit, clamp to avoid peaking audio.
sample32 = (sample32 >> range) + (((int32_t)filter[0] * sample0 + (int32_t)filter[1] * sample1 + 128) >> 8);

for (int32_t i = 0; i < 28; i++)
{
int16_t d = xa[16 + (i << 2) + s];
int16_t d0 = (d & 0xf) << 12;
decode_xa_unit(flags0, d0, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;

int16_t d1 = (d >> 4) << 12;
decode_xa_unit(flags1, d1, cdic_xa_last[2], cdic_xa_last[3], dp[0]);
dp++;
}
}

xa += 128;
}
sample = clip_int16(sample32);
rotate_samples(sample, sample0, sample1, out_buffer);
}

void cdicdic_device::decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
{
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s += 2)
{
uint8_t flags0 = xa[4 + s];
uint8_t flags1 = xa[5 + s];

for (int32_t i = 0; i < 28; i++)
{
int16_t d0 = (xa[16 + (i << 2) + s + 0] << 8);

decode_xa_unit(flags0, d0, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;

int16_t d1 = (xa[16 + (i << 2) + s + 1] << 8);
decode_xa_unit(flags1, d1, cdic_xa_last[2], cdic_xa_last[3], dp[0]);
dp++;
}
}
xa += 128;
}
}


void cdicdic_device::decode_8bit_xa_unit(int channel, uint8_t param, const uint8_t *data, int16_t *out_buffer)
{
int16_t *const old_samples = &m_xa_last[channel << 1];
Expand Down
4 changes: 0 additions & 4 deletions src/mame/philips/cdicdic.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,6 @@ class cdicdic_device : public device_t
uint32_t lba_from_time();

static uint8_t get_sector_count_for_coding(uint8_t coding);
void decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
void decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
void decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
void decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);

static const int16_t s_xa_filter_coef[4][2];
static const int32_t s_samples_per_sector;
Expand Down
81 changes: 34 additions & 47 deletions src/mame/philips/cdislavehle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,59 +141,46 @@ void cdislave_hle_device::set_mouse_position()
m_device_mouse_y = ((m_in_buf[1] & 0x0f) << 6) | (m_in_buf[0] & 0x3f);
}

void cdislave_hle_device::slave_w_mouse(offs_t offset, uint16_t data)
{
m_in_buf[m_in_index] = data & 0x00ff;
bool set_mouse = m_in_buf[0] >= 0xc0;
if (set_mouse)
{
if (m_in_index == 0)
{
LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Update Mouse Position (0x%02x)\n", offset, data & 0x00ff);
m_in_count = 3;
}
else
{
if (m_in_index == m_in_count - 1)
{
// Update Mouse Position
set_mouse_position();
memset(m_in_buf, 0, 17);
m_in_index = 0;
m_in_count = 0;
return;
}
}
}
else
{
LOGMASKED(LOG_COMMANDS | LOG_UNKNOWNS, "slave_w: Channel %d: Unknown register: %02x\n", offset, data & 0x00ff);
if (m_in_index == 0){
return;
}
}
m_in_index++;
}
void cdislave_hle_device::slave_w(offs_t offset, uint16_t data)
{
LOGMASKED(LOG_WRITES, "slave_w: Channel %d: %d = %02x\n", offset, m_in_index, data & 0x00ff);
switch (offset)
{
case 0:
if (m_in_index)
{
m_in_buf[m_in_index] = data & 0x00ff;
m_in_index++;
if (m_in_index == m_in_count)
{
switch (m_in_buf[0])
{
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: // Update Mouse Position
set_mouse_position();
memset(m_in_buf, 0, 17);
m_in_index = 0;
m_in_count = 0;
break;
}
}
}
else
{
m_in_buf[m_in_index] = data & 0x00ff;
m_in_index++;
switch (data & 0x00ff)
{
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Update Mouse Position (0x%02x)\n", offset, data & 0x00ff);
m_in_count = 3;
break;
default:
LOGMASKED(LOG_COMMANDS | LOG_UNKNOWNS, "slave_w: Channel %d: Unknown register: %02x\n", offset, data & 0x00ff);
m_in_index = 0;
break;
}
}
slave_w_mouse(offset, data);
break;
case 1:
if (m_in_index)
Expand Down
1 change: 1 addition & 0 deletions src/mame/philips/cdislavehle.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class cdislave_hle_device : public device_t

uint16_t slave_r(offs_t offset);
void slave_w(offs_t offset, uint16_t data);
void slave_w_mouse(offs_t offset, uint16_t data);

protected:
// device_t implementation
Expand Down
Loading