1 // license:GPL-2.0+
2 // copyright-holders: Felipe Sanches
3 /***************************************************************************
4
5 SONY PVE-500 Editing Control Unit
6 "A/B roll edit controller for professional video editing applications"
7
8 Driver by Felipe Correa da Silva Sanches <juca@members.fsf.org>
9 Technical info at https://www.garoa.net.br/wiki/PVE-500
10
11 Notes:
12 One can induce the self-diagnose by booting the device holding LEARN and P2-RESET buttons togheter
13 With the default keyboard map, this can be done by holding keys L and S while pressing F3.
14 (Don't forget to unlock the keyboard by using the UI TOGGLE key)
15
16 This self-diagnose routine displays the value C817, which is the checksum value of the subcpu ROM
17 and afterwards it displays the following message:
18
19 SELFdIAG Error___ _F3 F3_CtC3c
20
21 which means it detected an error in the CTC circuitry (it means we're emulating it wrong!)
22 F3 is the coordinate of the subcpu EPROM chip in the PCB.
23
24 According to the service manual, this error code means: "ICF3 CTC CH-3 counter operation failure (No interruption)"
25
26 Known issues:
27 There's still an annoying blinking in the 7-seg display.
28
29 Changelog:
30
31 2014 SEP 01 [Felipe Sanches]:
32 * hooked-up MB8421 device (dual-port SRAM)
33
34 2014 JUN 24 [Felipe Sanches]:
35 * figured out the multiplexing signals for the 7-seg display
36
37 2014 JUN 23 [Felipe Sanches]:
38 * hooked-up the RS422 ports
39
40 2014 JAN 14 [Felipe Sanches]:
41 * Initial driver skeleton
42 */
43
44 #define LOG_7SEG_DISPLAY_SIGNALS 0
45 #define DEBUGGING_INDUCE_SELFDIAGNOSE 0
46
47 #include "emu.h"
48 #include "bus/rs232/rs232.h" /* actually meant to be RS422 ports */
49 #include "cpu/mb88xx/mb88xx.h"
50 #include "cpu/z80/tmpz84c015.h"
51 #include "machine/clock.h"
52 #include "machine/cxd1095.h"
53 #include "machine/eepromser.h"
54 #include "machine/mb8421.h"
55 #include "machine/z80sio.h"
56 #include "sound/beep.h"
57 #include "speaker.h"
58
59 #include "pve500.lh"
60
61 #define IO_EXPANDER_PORTA 0
62 #define IO_EXPANDER_PORTB 1
63 #define IO_EXPANDER_PORTC 2
64 #define IO_EXPANDER_PORTD 3
65 #define IO_EXPANDER_PORTE 4
66
67 class pve500_state : public driver_device
68 {
69 public:
pve500_state(const machine_config & mconfig,device_type type,const char * tag)70 pve500_state(const machine_config &mconfig, device_type type, const char *tag)
71 : driver_device(mconfig, type, tag)
72 , m_maincpu(*this, "maincpu")
73 , m_subcpu(*this, "subcpu")
74 , m_cxdio(*this, "cxdio")
75 , m_eeprom(*this, "eeprom")
76 , m_buzzer(*this, "buzzer")
77 , m_digits(*this, "digit%u", 0U)
78 { }
79
80 void pve500(machine_config &config);
81
82 void init_pve500();
83
84 private:
85 DECLARE_WRITE_LINE_MEMBER(mb8421_intl);
86 DECLARE_WRITE_LINE_MEMBER(mb8421_intr);
87 DECLARE_WRITE_LINE_MEMBER(GPI_w);
88 DECLARE_WRITE_LINE_MEMBER(cxdio_reset_w);
89 DECLARE_WRITE_LINE_MEMBER(external_monitor_w);
90
91 uint8_t io_ky_r();
92 void io_sc_w(uint8_t data);
93 void io_le_w(uint8_t data);
94 void io_ld_w(uint8_t data);
95 void io_sel_w(uint8_t data);
96 void eeprom_w(uint8_t data);
97 uint8_t eeprom_r();
98 void maincpu_io(address_map &map);
99 void maincpu_prg(address_map &map);
100 void subcpu_io(address_map &map);
101 void subcpu_prg(address_map &map);
102
103 virtual void machine_start() override;
104 virtual void machine_reset() override;
105 required_device<tmpz84c015_device> m_maincpu;
106 required_device<tmpz84c015_device> m_subcpu;
107 required_device<cxd1095_device> m_cxdio;
108 required_device<eeprom_serial_er5911_device> m_eeprom;
109 required_device<beep_device> m_buzzer;
110 output_finder<27> m_digits;
111
112 uint8_t io_SEL, io_LD, io_LE, io_SC, io_KY;
113 int LD_data[4];
114 };
115
WRITE_LINE_MEMBER(pve500_state::GPI_w)116 WRITE_LINE_MEMBER(pve500_state::GPI_w)
117 {
118 /* TODO: Implement-me */
119 }
120
WRITE_LINE_MEMBER(pve500_state::cxdio_reset_w)121 WRITE_LINE_MEMBER(pve500_state::cxdio_reset_w)
122 {
123 if (!state)
124 m_cxdio->reset();
125 }
126
WRITE_LINE_MEMBER(pve500_state::external_monitor_w)127 WRITE_LINE_MEMBER(pve500_state::external_monitor_w)
128 {
129 /* TODO: Implement-me */
130 }
131
132 static const z80_daisy_config maincpu_daisy_chain[] =
133 {
134 { "external_ctc" },
135 { "external_sio" },
136 { nullptr }
137 };
138
139
maincpu_io(address_map & map)140 void pve500_state::maincpu_io(address_map &map)
141 {
142 map(0x00, 0x03).mirror(0xff00).rw("external_sio", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w));
143 map(0x08, 0x0B).mirror(0xff00).rw("external_ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
144 }
145
maincpu_prg(address_map & map)146 void pve500_state::maincpu_prg(address_map &map)
147 {
148 map(0x0000, 0xbfff).rom(); // ICB7: 48kbytes EPROM
149 map(0xc000, 0xdfff).ram(); // ICD6: 8kbytes of RAM
150 map(0xe000, 0xe7ff).mirror(0x1800).rw("mb8421", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w));
151 }
152
subcpu_io(address_map & map)153 void pve500_state::subcpu_io(address_map &map)
154 {
155 }
156
subcpu_prg(address_map & map)157 void pve500_state::subcpu_prg(address_map &map)
158 {
159 map(0x0000, 0x7fff).rom(); // ICG5: 32kbytes EPROM
160 map(0x8000, 0x8007).mirror(0x3ff8).rw(m_cxdio, FUNC(cxd1095_device::read), FUNC(cxd1095_device::write));
161 map(0xc000, 0xc7ff).mirror(0x3800).rw("mb8421", FUNC(mb8421_device::right_r), FUNC(mb8421_device::right_w));
162 }
163
init_pve500()164 void pve500_state::init_pve500()
165 {
166 }
167
168 static INPUT_PORTS_START( pve500 )
169 PORT_START("SCAN0")
PORT_CODE(KEYCODE_5)170 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRANS") PORT_CODE(KEYCODE_5)
171 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A/B") PORT_CODE(KEYCODE_4)
172 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("FROM TO") PORT_CODE(KEYCODE_3)
173 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P2") PORT_CODE(KEYCODE_2)
174 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P1") PORT_CODE(KEYCODE_1)
175 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED)
176 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
177 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTRY") PORT_CODE(KEYCODE_SPACE)
178
179 PORT_START("SCAN1")
180 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALL STOP") PORT_CODE(KEYCODE_M)
181 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LAST EDIT") PORT_CODE(KEYCODE_I)
182 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("AUDIO SPLIT") PORT_CODE(KEYCODE_T)
183 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A2") PORT_CODE(KEYCODE_9)
184 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ASMBL") PORT_CODE(KEYCODE_6)
185 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_7)
186 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A1") PORT_CODE(KEYCODE_8)
187 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTRY") PORT_CODE(KEYCODE_SPACE)
188
189 PORT_START("SCAN2")
190 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RVW/JUMP") PORT_CODE(KEYCODE_N)
191 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("AUTO EDIT") PORT_CODE(KEYCODE_B)
192 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PREVIEW") PORT_CODE(KEYCODE_V)
193 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-FF") PORT_CODE(KEYCODE_R)
194 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-REW") PORT_CODE(KEYCODE_E)
195 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-STILL") PORT_CODE(KEYCODE_W)
196 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-PLAY") PORT_CODE(KEYCODE_Q)
197 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTRY") PORT_CODE(KEYCODE_SPACE)
198
199 PORT_START("SCAN3")
200 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-OUT") PORT_CODE(KEYCODE_K)
201 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-IN") PORT_CODE(KEYCODE_J)
202 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("GO TO") PORT_CODE(KEYCODE_H)
203 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-OUT") PORT_CODE(KEYCODE_G)
204 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P-IN") PORT_CODE(KEYCODE_F)
205 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRIM+") PORT_CODE(KEYCODE_U)
206 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRIM-") PORT_CODE(KEYCODE_Y)
207 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTRY") PORT_CODE(KEYCODE_SPACE)
208
209 PORT_START("SCAN4")
210 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-FF") PORT_CODE(KEYCODE_OPENBRACE)
211 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-REW") PORT_CODE(KEYCODE_QUOTE)
212 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-STILL") PORT_CODE(KEYCODE_P)
213 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-PLAY") PORT_CODE(KEYCODE_O)
214 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EDIT") PORT_CODE(KEYCODE_EQUALS)
215 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("REC") PORT_CODE(KEYCODE_MINUS)
216 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
217 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTRY") PORT_CODE(KEYCODE_SPACE)
218
219 PORT_START("SCAN5")
220 PORT_DIPNAME( 0x03, 0x02, "R-EDIT REF" )
221 PORT_DIPSETTING( 0x02, "TC" )
222 PORT_DIPSETTING( 0x00, "RTC" )
223 PORT_DIPSETTING( 0x01, "CTL" )
224
225 PORT_DIPNAME( 0x0C, 0x08, "P2-EDIT REF" )
226 PORT_DIPSETTING( 0x08, "TC" )
227 PORT_DIPSETTING( 0x00, "RTC" )
228 PORT_DIPSETTING( 0x04, "CTL" )
229
230 PORT_DIPNAME( 0x30, 0x20, "P1-EDIT REF" )
231 PORT_DIPSETTING( 0x20, "TC" )
232 PORT_DIPSETTING( 0x00, "RTC" )
233 PORT_DIPSETTING( 0x10, "CTL" )
234
235 PORT_START("SCAN6")
236 PORT_DIPNAME( 0x03, 0x02, "SYNCHRO" )
237 PORT_DIPSETTING( 0x02, "ON/CF" )
238 PORT_DIPSETTING( 0x00, "ON" )
239 PORT_DIPSETTING( 0x01, "OFF" )
240
241 PORT_DIPNAME( 0x0C, 0x08, "PREROLL" )
242 PORT_DIPSETTING( 0x08, "7" )
243 PORT_DIPSETTING( 0x00, "5" )
244 PORT_DIPSETTING( 0x04, "3" )
245
246 PORT_START("SCAN7")
247 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TOTAL") PORT_CODE(KEYCODE_CLOSEBRACE)
248 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEARN") PORT_CODE(KEYCODE_L)
249 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRANS-1F") PORT_CODE(KEYCODE_Z)
250 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRANS-10F") PORT_CODE(KEYCODE_X)
251 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TRANS-100F") PORT_CODE(KEYCODE_C)
252 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-RESET") PORT_CODE(KEYCODE_A)
253 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P2-RESET") PORT_CODE(KEYCODE_S)
254 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P1-RESET") PORT_CODE(KEYCODE_D)
255 INPUT_PORTS_END
256
257 void pve500_state::machine_start()
258 {
259 io_LD = 0;
260 io_SC = 0;
261 io_LE = 0;
262 io_SEL = 0;
263 io_KY = 0;
264 m_digits.resolve();
265 }
266
machine_reset()267 void pve500_state::machine_reset()
268 {
269 /* Setup beep */
270 m_buzzer->set_state(0);
271 }
272
WRITE_LINE_MEMBER(pve500_state::mb8421_intl)273 WRITE_LINE_MEMBER(pve500_state::mb8421_intl)
274 {
275 // shared ram interrupt request from subcpu side
276 m_maincpu->trg1(state);
277 }
278
WRITE_LINE_MEMBER(pve500_state::mb8421_intr)279 WRITE_LINE_MEMBER(pve500_state::mb8421_intr)
280 {
281 // shared ram interrupt request from maincpu side
282 m_subcpu->trg1(state);
283 }
284
eeprom_r()285 uint8_t pve500_state::eeprom_r()
286 {
287 return (m_eeprom->ready_read() << 1) | m_eeprom->do_read();
288 }
289
eeprom_w(uint8_t data)290 void pve500_state::eeprom_w(uint8_t data)
291 {
292 m_eeprom->di_write( (data & (1 << 2)) ? ASSERT_LINE : CLEAR_LINE);
293 m_eeprom->clk_write( (data & (1 << 3)) ? ASSERT_LINE : CLEAR_LINE);
294 m_eeprom->cs_write( (data & (1 << 4)) ? ASSERT_LINE : CLEAR_LINE);
295 }
296
io_ky_r()297 uint8_t pve500_state::io_ky_r()
298 {
299 io_KY = 0x00;
300 if (!BIT(io_SC, 0)) io_KY |= ioport("SCAN0")->read();
301 if (!BIT(io_SC, 1)) io_KY |= ioport("SCAN1")->read();
302 if (!BIT(io_SC, 2)) io_KY |= ioport("SCAN2")->read();
303 if (!BIT(io_SC, 3)) io_KY |= ioport("SCAN3")->read();
304 if (!BIT(io_SC, 4)) io_KY |= ioport("SCAN4")->read();
305 if (!BIT(io_SC, 5)) io_KY |= ioport("SCAN5")->read();
306 if (!BIT(io_SC, 6)) io_KY |= ioport("SCAN6")->read();
307 if (!BIT(io_SC, 7)) io_KY |= ioport("SCAN7")->read();
308 #if DEBUGGING_INDUCE_SELFDIAGNOSE
309 io_KY = 0x42; //according to procedure described in the service manual
310 #endif
311 return io_KY;
312 }
313
io_sc_w(uint8_t data)314 void pve500_state::io_sc_w(uint8_t data)
315 {
316 const int swap[4] = {2,1,0,3};
317
318 #if LOG_7SEG_DISPLAY_SIGNALS
319 printf("CXD1095 PORTA (io_SC=%02X)\n", data);
320 #endif
321 io_SC = data;
322
323 for (int j=0; j<8; j++){
324 if (!BIT(io_SC,j)){
325 int digits = (j < 3) ? 4 : 3;
326 for (int i = 0; i < digits; i++)
327 {
328 assert(8*swap[i] + j < 27);
329 m_digits[8*swap[i] + j] = LD_data[i];
330 }
331 }
332 }
333 }
334
io_le_w(uint8_t data)335 void pve500_state::io_le_w(uint8_t data)
336 {
337 #if LOG_7SEG_DISPLAY_SIGNALS
338 printf("CXD1095 PORTB (io_LE=%02X)\n", data);
339 #endif
340 io_LE = data;
341 }
342
io_ld_w(uint8_t data)343 void pve500_state::io_ld_w(uint8_t data)
344 {
345 #if LOG_7SEG_DISPLAY_SIGNALS
346 printf("CXD1095 PORTD (io_LD=%02X)\n", data);
347 #endif
348 io_LD = data;
349 }
350
io_sel_w(uint8_t data)351 void pve500_state::io_sel_w(uint8_t data)
352 {
353 #if LOG_7SEG_DISPLAY_SIGNALS
354 printf("CXD1095 PORTE (io_SEL=%02X)\n", data);
355 #endif
356 io_SEL = data;
357 for (int i=0; i<4; i++){
358 if (BIT(io_SEL, i)){
359 LD_data[i] = 0x7F & bitswap<8>(io_LD ^ 0xFF, 7, 0, 1, 2, 3, 4, 5, 6);
360 }
361 }
362 }
363
pve500(machine_config & config)364 void pve500_state::pve500(machine_config &config)
365 {
366 /* Main CPU */
367 TMPZ84C015(config, m_maincpu, 12_MHz_XTAL / 2); // TMPZ84C015BF-6
368 m_maincpu->set_addrmap(AS_PROGRAM, &pve500_state::maincpu_prg);
369 m_maincpu->set_addrmap(AS_IO, &pve500_state::maincpu_io);
370 m_maincpu->set_daisy_config(maincpu_daisy_chain);
371 m_maincpu->out_dtra_callback().set(FUNC(pve500_state::GPI_w));
372 m_maincpu->out_dtrb_callback().set(m_buzzer, FUNC(beep_device::set_state)).invert();
373 m_maincpu->out_txda_callback().set("recorder", FUNC(rs232_port_device::write_txd));
374 m_maincpu->out_txdb_callback().set("player1", FUNC(rs232_port_device::write_txd));
375
376 z80ctc_device& ctc(Z80CTC(config, "external_ctc", 12_MHz_XTAL / 2));
377 ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
378
379 z80sio_device& sio(Z80SIO(config, "external_sio", 12_MHz_XTAL / 2)); // TMPZ84C40AP-8
380 sio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
381 sio.out_txda_callback().set("player2", FUNC(rs232_port_device::write_txd));
382 sio.out_txdb_callback().set("edl_inout", FUNC(rs232_port_device::write_txd));
383
384 /* Secondary CPU */
385 TMPZ84C015(config, m_subcpu, 12_MHz_XTAL / 2); /* TMPZ84C015BF-6 */
386 m_subcpu->set_addrmap(AS_PROGRAM, &pve500_state::subcpu_prg);
387 m_subcpu->set_addrmap(AS_IO, &pve500_state::subcpu_io);
388 m_subcpu->out_dtra_callback().set(FUNC(pve500_state::cxdio_reset_w));
389 m_subcpu->out_dtrb_callback().set(FUNC(pve500_state::external_monitor_w));
390 m_subcpu->out_txda_callback().set("switcher", FUNC(rs232_port_device::write_txd));
391 m_subcpu->out_txdb_callback().set("serial_mixer", FUNC(rs232_port_device::write_txd));
392
393 // PIO callbacks
394 m_subcpu->in_pa_callback().set(FUNC(pve500_state::eeprom_r));
395 m_subcpu->out_pa_callback().set(FUNC(pve500_state::eeprom_w));
396
397 // ICG3: I/O Expander
398 CXD1095(config, m_cxdio);
399 m_cxdio->out_porta_cb().set(FUNC(pve500_state::io_sc_w));
400 m_cxdio->out_portb_cb().set(FUNC(pve500_state::io_le_w));
401 m_cxdio->in_portc_cb().set(FUNC(pve500_state::io_ky_r));
402 m_cxdio->out_portd_cb().set(FUNC(pve500_state::io_ld_w));
403 m_cxdio->out_porte_cb().set(FUNC(pve500_state::io_sel_w));
404
405 /* Search Dial MCUs */
406 MB88201(config, "dial_mcu_left", 4_MHz_XTAL).set_disable(); /* PLAYER DIAL MCU */
407 MB88201(config, "dial_mcu_right", 4_MHz_XTAL).set_disable(); /* RECORDER DIAL MCU */
408
409 /* Serial EEPROM (128 bytes, 8-bit data organization) */
410 /* The EEPROM stores the setup data */
411 EEPROM_MSM16911_8BIT(config, "eeprom");
412
413 /* FIX-ME: These are actually RS422 ports (except EDL IN/OUT which is indeed an RS232 port)*/
414 rs232_port_device &recorder(RS232_PORT(config, "recorder", default_rs232_devices, nullptr));
415 recorder.rxd_handler().set(m_maincpu, FUNC(tmpz84c015_device::rxa_w));
416
417 rs232_port_device &player1(RS232_PORT(config, "player1", default_rs232_devices, nullptr));
418 player1.rxd_handler().set(m_maincpu, FUNC(tmpz84c015_device::rxb_w));
419
420 rs232_port_device &player2(RS232_PORT(config, "player2", default_rs232_devices, nullptr));
421 player2.rxd_handler().set("external_sio", FUNC(z80sio_device::rxa_w));
422
423 rs232_port_device &edl_inout(RS232_PORT(config, "edl_inout", default_rs232_devices, nullptr));
424 edl_inout.rxd_handler().set("external_sio", FUNC(z80sio_device::rxb_w));
425
426 rs232_port_device &switcher(RS232_PORT(config, "switcher", default_rs232_devices, nullptr));
427 switcher.rxd_handler().set(m_subcpu, FUNC(tmpz84c015_device::rxa_w));
428
429 rs232_port_device &serial_mixer(RS232_PORT(config, "serial_mixer", default_rs232_devices, nullptr));
430 serial_mixer.rxd_handler().set(m_subcpu, FUNC(tmpz84c015_device::rxb_w));
431
432 clock_device &clk1(CLOCK(config, "clk1", 12_MHz_XTAL / 20));
433 clk1.signal_handler().set(m_maincpu, FUNC(tmpz84c015_device::rxca_w));
434 clk1.signal_handler().append(m_maincpu, FUNC(tmpz84c015_device::txca_w));
435 clk1.signal_handler().append(m_maincpu, FUNC(tmpz84c015_device::rxcb_w));
436 clk1.signal_handler().append(m_maincpu, FUNC(tmpz84c015_device::txcb_w));
437 clk1.signal_handler().append(m_subcpu, FUNC(tmpz84c015_device::rxca_w));
438 clk1.signal_handler().append(m_subcpu, FUNC(tmpz84c015_device::txca_w));
439 clk1.signal_handler().append(m_subcpu, FUNC(tmpz84c015_device::rxcb_w));
440 clk1.signal_handler().append(m_subcpu, FUNC(tmpz84c015_device::txcb_w));
441
442 /* ICF5: 2kbytes of RAM shared between the two CPUs (dual-port RAM)*/
443 mb8421_device &mb8421(MB8421(config, "mb8421"));
444 mb8421.intl_callback().set(FUNC(pve500_state::mb8421_intl));
445 mb8421.intr_callback().set(FUNC(pve500_state::mb8421_intr));
446
447 /* video hardware */
448 config.set_default_layout(layout_pve500);
449
450 /* audio hardware */
451 SPEAKER(config, "mono").front_center();
452 BEEP(config, "buzzer", 12_MHz_XTAL / 3200).add_route(ALL_OUTPUTS, "mono", 0.05); // 3.75 kHz CLK2 coming out of IC D4 (frequency divider circuitry)
453 }
454
455 ROM_START( pve500 )
456 ROM_REGION( 0x10000, "maincpu", 0 )
457 ROM_LOAD("pve500.icb7", 0x00000, 0x10000, CRC(1036709c) SHA1(207d6fcad5c2f081a138184060ce7bd02736965b) ) //48kbyte main-cpu program + 16kbyte of unreachable memory
458
459 ROM_REGION( 0x8000, "subcpu", 0 )
460 ROM_LOAD("pve500.icg5", 0x00000, 0x8000, CRC(28cca60a) SHA1(308d70062653769250327ede7a4e1a8a76fc9ab9) ) //32kbyte sub-cpu program
461
462 ROM_REGION( 0x200, "dial_mcu_left", 0 ) /* PLAYER DIAL MCU */
463 ROM_LOAD( "pve500.icd3", 0x0000, 0x0200, NO_DUMP )
464
465 ROM_REGION( 0x200, "dial_mcu_right", 0 ) /* RECORDER DIAL MCU */
466 ROM_LOAD( "pve500.icc3", 0x0000, 0x0200, NO_DUMP )
467
468 ROM_REGION( 0x80, "eeprom", 0 ) /* The EEPROM stores the setup data */
469 ROM_LOAD( "pve500.ice3", 0x0000, 0x080, NO_DUMP )
470 ROM_END
471
472 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
473 COMP( 1995, pve500, 0, 0, pve500, pve500, pve500_state, init_pve500, "SONY", "PVE-500", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS)
474