Skip to content

Commit ec7eb50

Browse files
authored
casio/cps200.cpp: Added a skeleton Casio CPS-2000 driver; also improved µPD934 and MSM6200 emulation. (#13591)
* machine/msm6200.cpp: Scan matrix on a timer until a change is detected. * sound/upd934g.cpp: Fixed play sample command. * casio/cz1.cpp: Added MSM6200 clock input frequency. New systems marked not working --------------- Casio CPS-2000 [BCM, Devin Acker]
1 parent 8ac83f8 commit ec7eb50

File tree

8 files changed

+470
-35
lines changed

8 files changed

+470
-35
lines changed

Diff for: src/devices/machine/msm6200.cpp

+23-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ msm6200_device::msm6200_device(const machine_config &mconfig, const char *tag, d
2121
/**************************************************************************/
2222
void msm6200_device::device_start()
2323
{
24+
m_timer = timer_alloc(FUNC(msm6200_device::scan_timer), this);
25+
2426
m_cmd = 0xf;
2527

2628
save_item(NAME(m_cmd));
@@ -39,6 +41,18 @@ void msm6200_device::device_reset()
3941
std::fill(std::begin(m_last_state), std::end(m_last_state), 0);
4042
}
4143

44+
/**************************************************************************/
45+
TIMER_CALLBACK_MEMBER(msm6200_device::scan_timer)
46+
{
47+
(++m_row) %= m_keys.size();
48+
m_key_state = m_keys[m_row].read_safe(0);
49+
if (m_key_state != m_last_state[m_row])
50+
{
51+
m_irq_cb(1);
52+
m_timer->adjust(attotime::never);
53+
}
54+
}
55+
4256
/**************************************************************************/
4357
void msm6200_device::write(offs_t offset, u8 data)
4458
{
@@ -60,30 +74,32 @@ void msm6200_device::write(offs_t offset, u8 data)
6074
}
6175
}
6276
if (m_key_state == m_last_state[m_row])
77+
{
6378
m_irq_cb(0);
79+
m_timer->adjust(attotime::zero, 0, attotime::from_ticks(TIMER_RATE, clock()));
80+
}
6481
break;
6582

6683
case 1: // read velocity
6784
m_key_data = m_velocity.read_safe(0x3f);
6885
break;
6986

70-
case 2: // next row?
71-
(++m_row) %= m_keys.size();
87+
case 2:
7288
// TODO: what should this one actually be?
7389
// the cz1/ht6000 key MCU code outputs the result to port 1 for debugging
7490
m_key_data = m_row;
7591
break;
7692

77-
case 7: // capture current row?
78-
m_key_state = m_keys[m_row].read_safe(0);
79-
if (m_key_state != m_last_state[m_row])
80-
m_irq_cb(1);
93+
case 7: // ?
94+
// cz1/ht6000 writes this constantly, cps2000 much less frequently
8195
break;
8296

83-
case 8: // init all rows
97+
case 8: // init all rows, start scanning
8498
for (int i = 0; i < m_keys.size(); i++)
8599
m_last_state[i] = m_keys[i].read_safe(0);
100+
86101
m_irq_cb(0);
102+
m_timer->adjust(attotime::zero, 0, attotime::from_ticks(TIMER_RATE, clock()));
87103
break;
88104

89105
default:

Diff for: src/devices/machine/msm6200.h

+6
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ class msm6200_device : public device_t
2424
virtual void device_reset() override ATTR_COLD;
2525

2626
private:
27+
static constexpr unsigned TIMER_RATE = 256; // arbitrary
28+
29+
TIMER_CALLBACK_MEMBER(scan_timer);
30+
2731
optional_ioport_array<38> m_keys;
2832
optional_ioport m_velocity;
2933

3034
devcb_write_line m_irq_cb;
3135

36+
emu_timer *m_timer;
37+
3238
u8 m_cmd, m_row, m_key_data;
3339
u8 m_key_state;
3440
u8 m_last_state[38];

Diff for: src/devices/sound/upd934g.cpp

+25-20
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ void upd934g_device::device_start()
5353
m_stream = stream_alloc(0, 4, 20000);
5454

5555
// register for save states
56-
save_pointer(NAME(m_addr), 16);
56+
save_item(NAME(m_addr));
57+
save_item(NAME(m_valid));
5758

5859
save_item(STRUCT_MEMBER(m_channel, pos));
5960
save_item(STRUCT_MEMBER(m_channel, playing));
@@ -71,8 +72,15 @@ void upd934g_device::device_reset()
7172
{
7273
m_ready = false;
7374

75+
for (unsigned i = 0; i < 16; i++)
76+
m_addr[i] = m_valid[i] = 0;
77+
7478
for (unsigned i = 0; i < 4; i++)
79+
{
80+
m_channel[i].pos = 0;
7581
m_channel[i].playing = -1;
82+
m_channel[i].effect = 0;
83+
}
7684
}
7785

7886
//-------------------------------------------------
@@ -86,14 +94,15 @@ void upd934g_device::sound_stream_update(sound_stream &stream, std::vector<read_
8694
{
8795
if (m_ready && m_channel[ch].playing != -1)
8896
{
89-
uint16_t end = m_addr[m_channel[ch].playing + 1] - 1;
97+
uint16_t end = m_addr[(m_channel[ch].playing + 1) & 0xf] - 1;
9098

9199
for (unsigned i = 0; i < outputs[ch].samples(); i++)
92100
{
93101
int16_t raw = static_cast<int8_t>(read_byte(m_channel[ch].pos)) * 4;
94102

95103
// normal, muted, accented
96-
const double adjust[] = { 0, 0.7, 0.4, 1.0 };
104+
// TODO: cps2000 regularly sets effect bits to 0 instead of 2 - are these the same?
105+
const double adjust[] = { 0.4, 0.7, 0.4, 1.0 };
97106
raw *= adjust[m_channel[ch].effect];
98107

99108
outputs[ch].put_int(i, raw, 32768 / 64);
@@ -118,38 +127,34 @@ void upd934g_device::sound_stream_update(sound_stream &stream, std::vector<read_
118127

119128
void upd934g_device::write(offs_t offset, uint8_t data)
120129
{
121-
switch (offset)
130+
switch (offset & 3)
122131
{
123132
case 0:
124133
// format of data written here is:
125-
// 76------ command
134+
// 76------ effect
126135
// --5432-- sample number
127136
// ------10 output channel
128137
m_sample = (data >> 2) & 0x0f;
129138

130-
switch (data >> 6)
139+
// don't play a sample unless we're sure it's actually supposed to play:
140+
// - all models write this with effect=0 to select which sample to set the address of
141+
// - cps2000 writes this with effect=0 to play muted(?) samples
142+
// - cps2000 also writes this with effect=1 and sample=f on boot even though there are only 12 valid samples
143+
if (m_valid[m_sample])
131144
{
132-
case 0:
133-
LOG("CMD STORE ADDRESS sample %x\n", m_sample);
134-
break;
135-
case 1: // normal
136-
case 2: // muted
137-
case 3: // accented
138-
{
139-
const u8 ch = (data & 3) ^ 2; // effective order seems to be "2, 3, 0, 1"
140-
LOG("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, ch, data >> 6);
141-
m_channel[ch].pos = m_addr[m_sample];
142-
m_channel[ch].playing = m_sample;
143-
m_channel[ch].effect = data >> 6;
144-
}
145-
break;
145+
const u8 ch = (data & 3) ^ 2; // effective order seems to be "2, 3, 0, 1"
146+
LOG("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, ch, data >> 6);
147+
m_channel[ch].pos = m_addr[m_sample];
148+
m_channel[ch].playing = m_sample;
149+
m_channel[ch].effect = data >> 6;
146150
}
147151
break;
148152
case 1:
149153
m_addr[m_sample] = (m_addr[m_sample] & 0xff00) | (data << 0);
150154
break;
151155
case 2:
152156
m_addr[m_sample] = (m_addr[m_sample] & 0x00ff) | (data << 8);
157+
m_valid[m_sample] = 1;
153158
LOG(" sample %x address = %04x\n", m_sample, m_addr[m_sample]);
154159
break;
155160
case 3:

Diff for: src/devices/sound/upd934g.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class upd934g_device : public device_t, public device_sound_interface, public de
2727
// construction/destruction
2828
upd934g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
2929

30-
void write(offs_t offset, uint8_t data);
30+
void write(offs_t offset, u8 data);
3131

3232
protected:
3333
// device-level overrides
@@ -39,18 +39,19 @@ class upd934g_device : public device_t, public device_sound_interface, public de
3939
private:
4040
sound_stream *m_stream;
4141

42-
uint16_t m_addr[16];
42+
u16 m_addr[16];
43+
u8 m_valid[16];
4344

4445
struct
4546
{
46-
uint16_t pos;
47-
int playing;
48-
int effect;
47+
u16 pos;
48+
s8 playing;
49+
u8 effect;
4950
}
5051
m_channel[4];
5152

52-
int m_sample;
53-
bool m_ready;
53+
u8 m_sample;
54+
u8 m_ready;
5455
};
5556

5657
// device type definition

Diff for: src/emu/xtal.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const double XTAL::known_xtals[] = {
8383
2'250'000, // 2.25_MHz_XTAL Resonator - YM2154 on Yamaha PSR-60 & PSR-70
8484
2'376'000, // 2.376_MHz_XTAL CIT-101 keyboard
8585
2'457'600, // 2.4576_MHz_XTAL Atari ST MFP
86+
2'470'000, // 2.47_MHz_XTAL CSA2.47MG ceramic oscillator - Casio CZ-1
8687
2'500'000, // 2.5_MHz_XTAL Janken Man units
8788
2'600'000, // 2.6_MHz_XTAL Sharp PC-1500
8889
2'700'000, // 2.7_MHz_XTAL Resonator - YM2154 on Yamaha RX15
@@ -119,6 +120,7 @@ const double XTAL::known_xtals[] = {
119120
4'433'619, // 4.433619_MHz_XTAL PAL color subcarrier (technically 4.43361875mhz)
120121
4'608'000, // 4.608_MHz_XTAL Luxor ABC-77 keyboard (Keytronic custom part #48-300-107 is equivalent)
121122
4'915'200, // 4.9152_MHz_XTAL -
123+
4'946'800, // 4.9468_MHz_XTAL Casio CPS-2000
122124
4'946'864, // 4.946864_MHz_XTAL Casiotone 8000
123125
4'952'000, // 4.952_MHz_XTAL IGS M036 based mahjong games, for TT5665 sound chip
124126
5'000'000, // 5_MHz_XTAL Mutant Night

0 commit comments

Comments
 (0)