Skip to content

Commit 3b79698

Browse files
committed
mks3: first hle
1 parent d73c21c commit 3b79698

File tree

5 files changed

+327
-4
lines changed

5 files changed

+327
-4
lines changed

src/devices/cpu/h8/swx00.cpp

+15-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ swx00_device::swx00_device(const machine_config &mconfig, const char *tag, devic
4141
m_read_pad(*this, 0xff),
4242
m_write_pad(*this),
4343
m_write_cmah(*this),
44+
m_write_txd(*this),
4445
m_s_config("s", ENDIANNESS_BIG, 16, 24, -1),
4546
m_mode(mode),
4647
m_syscr(0)
@@ -53,6 +54,7 @@ swx00_device::swx00_device(const machine_config &mconfig, const char *tag, devic
5354
m_read_pad.bind().set(*this, FUNC(swx00_device::pad_default_r));
5455
m_write_pad.bind().set(*this, FUNC(swx00_device::pad_default_w));
5556
m_write_cmah.bind().set(*this, FUNC(swx00_device::cmah_default_w));
57+
m_write_txd.bind().set(*this, FUNC(swx00_device::txd_default_w));
5658
}
5759

5860
u16 swx00_device::s_r(offs_t offset)
@@ -71,7 +73,7 @@ void swx00_device::map(address_map &map)
7173
map(0xffe028, 0xffe029).w(FUNC(swx00_device::pdt_ddr_w));
7274
map(0xffe02a, 0xffe02b).rw(FUNC(swx00_device::pdt_r), FUNC(swx00_device::pdt_w));
7375
map(0xffe02d, 0xffe02d).w(FUNC(swx00_device::cmah_w));
74-
76+
map(0xffe02e, 0xffe02e).w(FUNC(swx00_device::txd_w));
7577
map(0xffe02f, 0xffe02f).lr8(NAME([]() -> uint8_t { return 0xff; }));
7678

7779
map(0xfff000, 0xfffbff).ram();
@@ -305,10 +307,11 @@ void swx00_device::device_add_mconfig(machine_config &config)
305307
h8_timer16_channel_device::INPUT_C,
306308
h8_timer16_channel_device::DIV_256,
307309
h8_timer16_channel_device::INPUT_D);
308-
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
310+
309311
H8_WATCHDOG(config, m_watchdog, *this, m_intc, 25, h8_watchdog_device::S);
310312
H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
311313
H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
314+
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
312315

313316
SWX00_SOUND(config, m_swx00);
314317
m_swx00->set_space(DEVICE_SELF, AS_S);
@@ -516,6 +519,11 @@ void swx00_device::cmah_default_w(u8 data)
516519
logerror("write of un-hooked port cmah %02x\n", data);
517520
}
518521

522+
void swx00_device::txd_default_w(u8 data)
523+
{
524+
logerror("write of un-hooked port txd %02x\n", data);
525+
}
526+
519527
void swx00_device::pdt_ddr_w(offs_t, u16 data, u16 mem_mask)
520528
{
521529
COMBINE_DATA(&m_pdt_ddr);
@@ -547,3 +555,8 @@ void swx00_device::cmah_w(u8 data)
547555
m_write_cmah(data);
548556
}
549557

558+
void swx00_device::txd_w(u8 data)
559+
{
560+
m_write_txd(data);
561+
}
562+

src/devices/cpu/h8/swx00.h

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class swx00_device : public h8s2000_device {
5858
auto read_pad() { return m_read_pad.bind(); }
5959
auto write_pad() { return m_write_pad.bind(); }
6060
auto write_cmah() { return m_write_cmah.bind(); }
61+
auto write_txd() { return m_write_txd.bind(); }
6162

6263
u8 syscr_r();
6364
void syscr_w(u8 data);
@@ -99,6 +100,7 @@ class swx00_device : public h8s2000_device {
99100
devcb_read8 m_read_pad;
100101
devcb_write8 m_write_pad;
101102
devcb_write8 m_write_cmah;
103+
devcb_write8 m_write_txd;
102104

103105
address_space_config m_s_config;
104106

@@ -129,12 +131,14 @@ class swx00_device : public h8s2000_device {
129131
u8 pad_r();
130132
void pad_w(u8 data);
131133
void cmah_w(u8 data);
134+
void txd_w(u8 data);
132135

133136
u16 pdt_default_r();
134137
void pdt_default_w(u16 data);
135138
u8 pad_default_r();
136139
void pad_default_w(u8 data);
137140
void cmah_default_w(u8 data);
141+
void txd_default_w(u8 data);
138142

139143
void map(address_map &map);
140144

src/mame/yamaha/mks3.cpp

+237
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
// license:BSD-3-Clause
2+
// copyright-holders:Olivier Galibert
3+
4+
// HLE emulation of the MKS3 keyboard scanning PCB used in the psr340
5+
// and psr540 among others.
6+
7+
// Uses a 63B05 with a not-yet-dumped internal rom
8+
9+
// Messages 0x81 and 0x82 are special, but not understood.
10+
11+
// What should happen so that the test mode works is not understood either.
12+
13+
#include "emu.h"
14+
#include "mks3.h"
15+
16+
DEFINE_DEVICE_TYPE(MKS3, mks3_device, "mks3", "Yamaha MKS3 piano keyboard scanner")
17+
18+
static INPUT_PORTS_START(piano)
19+
PORT_START("P0")
20+
PORT_BIT(0xffffffff, IP_ACTIVE_HIGH, IPT_UNUSED)
21+
22+
PORT_START("P1")
23+
PORT_BIT(0x0000000f, IP_ACTIVE_HIGH, IPT_UNUSED)
24+
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C2")
25+
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C2#")
26+
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D2")
27+
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D2#")
28+
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("E2")
29+
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F2")
30+
PORT_BIT(0x00000400, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F2#")
31+
PORT_BIT(0x00000800, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G2")
32+
PORT_BIT(0x00001000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G2#")
33+
PORT_BIT(0x00002000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A2")
34+
PORT_BIT(0x00004000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A2#")
35+
PORT_BIT(0x00008000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("B2")
36+
PORT_BIT(0x00010000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C3")
37+
PORT_BIT(0x00020000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C3#")
38+
PORT_BIT(0x00040000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D3")
39+
PORT_BIT(0x00080000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D3#")
40+
PORT_BIT(0x00100000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("E3")
41+
PORT_BIT(0x00200000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F3")
42+
PORT_BIT(0x00400000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F3#")
43+
PORT_BIT(0x00800000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G3")
44+
PORT_BIT(0x01000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G3#")
45+
PORT_BIT(0x02000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A3")
46+
PORT_BIT(0x04000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A3#")
47+
PORT_BIT(0x08000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("B3")
48+
PORT_BIT(0x10000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C4")
49+
PORT_BIT(0x20000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C4#")
50+
PORT_BIT(0x40000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D4")
51+
PORT_BIT(0x80000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D4#")
52+
53+
PORT_START("P2")
54+
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("E4")
55+
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F4")
56+
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F4#")
57+
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G4")
58+
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G4#")
59+
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A4")
60+
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A4#")
61+
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("B4")
62+
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C5")
63+
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C5#")
64+
PORT_BIT(0x00000400, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D5")
65+
PORT_BIT(0x00000800, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D5#")
66+
PORT_BIT(0x00001000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("E5")
67+
PORT_BIT(0x00002000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F5")
68+
PORT_BIT(0x00004000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F5#")
69+
PORT_BIT(0x00008000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G5")
70+
PORT_BIT(0x00010000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G5#")
71+
PORT_BIT(0x00020000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A5")
72+
PORT_BIT(0x00040000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A5#")
73+
PORT_BIT(0x00080000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("B5")
74+
PORT_BIT(0x00100000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C6")
75+
PORT_BIT(0x00200000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C6#")
76+
PORT_BIT(0x00400000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D6")
77+
PORT_BIT(0x00800000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("D6#")
78+
PORT_BIT(0x01000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("E6")
79+
PORT_BIT(0x02000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F6")
80+
PORT_BIT(0x04000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("F6#")
81+
PORT_BIT(0x08000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G6")
82+
PORT_BIT(0x10000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("G6#")
83+
PORT_BIT(0x20000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A6")
84+
PORT_BIT(0x40000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("A6#")
85+
PORT_BIT(0x80000000, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("B6")
86+
87+
PORT_START("P3")
88+
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_NAME("C7")
89+
PORT_BIT(0xfffffffe, IP_ACTIVE_HIGH, IPT_UNUSED)
90+
INPUT_PORTS_END
91+
92+
93+
mks3_device::mks3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
94+
device_t(mconfig, MKS3, tag, owner, clock),
95+
m_port(*this, "P%d", 0),
96+
m_write_da(*this),
97+
m_write_clk(*this)
98+
{
99+
}
100+
101+
ioport_constructor mks3_device::device_input_ports() const
102+
{
103+
return INPUT_PORTS_NAME(piano);
104+
}
105+
106+
void mks3_device::device_start()
107+
{
108+
save_item(NAME(m_ic));
109+
save_item(NAME(m_req));
110+
save_item(NAME(m_step));
111+
save_item(NAME(m_byte));
112+
save_item(NAME(m_bytes));
113+
save_item(NAME(m_byte_count));
114+
save_item(NAME(m_sent_state));
115+
save_item(NAME(m_current_state));
116+
117+
m_ic = 1;
118+
m_req = 1;
119+
120+
m_scan_timer = timer_alloc(FUNC(mks3_device::scan_tick), this);
121+
m_transmit_timer = timer_alloc(FUNC(mks3_device::transmit_tick), this);
122+
}
123+
124+
void mks3_device::device_reset()
125+
{
126+
m_write_da(1);
127+
m_write_clk(1);
128+
m_step = 0xff;
129+
m_byte = 0;
130+
m_byte_count = 0;
131+
std::fill(m_bytes.begin(), m_bytes.end(), 0);
132+
std::fill(m_sent_state.begin(), m_sent_state.end(), 0);
133+
134+
for(int i=0; i != 4; i++)
135+
m_current_state[i] = m_port[i]->read();
136+
137+
138+
m_scan_timer->adjust(attotime::from_hz(100), 0, attotime::from_hz(100));
139+
}
140+
141+
void mks3_device::ic_w(int state)
142+
{
143+
if(state == m_ic)
144+
return;
145+
146+
m_ic = state;
147+
if(!m_ic)
148+
reset();
149+
}
150+
151+
void mks3_device::req_w(int state)
152+
{
153+
if(state == m_req)
154+
return;
155+
156+
m_req = state;
157+
if(m_req == 0)
158+
transmit_next();
159+
}
160+
161+
TIMER_CALLBACK_MEMBER(mks3_device::transmit_tick)
162+
{
163+
if(m_step == 15) {
164+
transmit_next();
165+
return;
166+
}
167+
168+
if(m_step & 1) {
169+
m_write_clk(0);
170+
m_write_da(BIT(m_byte, 6 - (m_step >> 1)));
171+
} else
172+
m_write_clk(1);
173+
m_step++;
174+
175+
m_transmit_timer->adjust(attotime::from_hz(500000));
176+
}
177+
178+
void mks3_device::transmit_next()
179+
{
180+
if(m_byte_count == 0) {
181+
m_step = 0xff;
182+
send_next();
183+
return;
184+
}
185+
186+
m_byte = m_bytes[0];
187+
m_byte_count --;
188+
if(m_byte_count)
189+
memmove(m_bytes.data(), m_bytes.data() + 1, m_byte_count);
190+
191+
logerror("start %02x\n", m_byte);
192+
m_write_clk(0);
193+
m_write_da(BIT(m_byte, 7));
194+
m_step = 0;
195+
m_transmit_timer->adjust(attotime::from_hz(500000));
196+
}
197+
198+
u32 mks3_device::find_next()
199+
{
200+
for(int i=0; i != 4; i++)
201+
if(m_current_state[i] != m_sent_state[i])
202+
for(int j=0; j != 32; j++)
203+
if(BIT(m_current_state[i]^m_sent_state[i], j)) {
204+
m_sent_state[i] ^= 1 << j;
205+
return (i << 5) | j | (BIT(m_current_state[i], j) ? 0x100 : 0);
206+
}
207+
return 0xffffffff;
208+
}
209+
210+
void mks3_device::send_next()
211+
{
212+
u32 key = find_next();
213+
if(key == 0xffffffff)
214+
return;
215+
216+
// velocity is 10 bits, 0 = max, 3ff = min
217+
//
218+
// 80 | key number
219+
// 20 for keyoff, velocity >> 5 otherwise
220+
// 60 | (velocity & 1f)
221+
222+
m_bytes[0] = 0x80 | (key & 0x7f);
223+
m_bytes[1] = key & 0x100 ? 0 : 0x20;
224+
m_bytes[2] = 0x60;
225+
m_byte_count = 3;
226+
transmit_next();
227+
}
228+
229+
230+
TIMER_CALLBACK_MEMBER(mks3_device::scan_tick)
231+
{
232+
for(int i=0; i != 4; i++)
233+
m_current_state[i] = m_port[i]->read();
234+
235+
if(m_step == 0xff)
236+
send_next();
237+
}

src/mame/yamaha/mks3.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// license:BSD-3-Clause
2+
// copyright-holders:Olivier Galibert
3+
4+
// HLE emulation of the MKS3 keyboard scanning PCB used in the psr340
5+
// and psr540 among others.
6+
7+
// Uses a 63B05 with a not-yet-dumped internal rom
8+
9+
10+
#ifndef MAME_YAMAHA_MKS3_H
11+
#define MAME_YAMAHA_MKS3_H
12+
13+
#pragma once
14+
15+
DECLARE_DEVICE_TYPE(MKS3, mks3_device)
16+
17+
class mks3_device : public device_t
18+
{
19+
public:
20+
mks3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
21+
22+
void ic_w(int state);
23+
void req_w(int state);
24+
auto write_da() { return m_write_da.bind(); }
25+
auto write_clk() { return m_write_clk.bind(); }
26+
27+
protected:
28+
virtual void device_start() override;
29+
virtual void device_reset() override;
30+
virtual ioport_constructor device_input_ports() const override;
31+
32+
private:
33+
required_ioport_array<4> m_port;
34+
devcb_write_line m_write_da;
35+
devcb_write_line m_write_clk;
36+
emu_timer *m_scan_timer, *m_transmit_timer;
37+
38+
std::array<u8, 3> m_bytes;
39+
40+
std::array<u32, 4> m_sent_state;
41+
std::array<u32, 4> m_current_state;
42+
43+
int m_ic, m_req;
44+
u8 m_step, m_byte, m_byte_count;
45+
46+
u32 find_next();
47+
void send_next();
48+
void transmit_next();
49+
TIMER_CALLBACK_MEMBER(transmit_tick);
50+
TIMER_CALLBACK_MEMBER(scan_tick);
51+
};
52+
53+
#endif

0 commit comments

Comments
 (0)