1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 Namco 54XX
6
7 This custom chip is a Fujitsu MB8844 MCU programmed to act as a noise
8 generator. It is used for explosions, the shoot sound in Bosconian,
9 and the tire screech sound in Pole Position.
10
11 CMD = command from main CPU
12 OUTn = sound outputs (3 channels)
13
14 The chip reads the command when the /IRQ is pulled down.
15
16 +------+
17 EX|1 28|Vcc
18 X|2 27|K3 (CMD7)
19 /RESET|3 26|K2 (CMD6)
20 (OUT0.0) O0|4 25|K1 (CMD5)
21 (OUT0.1) O1|5 24|K0 (CMD4)
22 (OUT0.2) O2|6 23|R10/IRQ
23 (OUT0.3) O3|7 22|R9/TC
24 (OUT1.0) O4|8 21|R8
25 (OUT1.1) O5|9 20|R7 (OUT2.3)
26 (OUT1.2) O6|10 19|R6 (OUT2.2)
27 (OUT1.3) O7|11 18|R5 (OUT2.1)
28 (CMD0) R0|12 17|R4 (OUT2.0)
29 (CMD1) R1|13 16|R3 (CMD3)
30 GND|14 15|R2 (CMD2)
31 +------+
32
33 [1] The RNG that drives the type A output is output on pin 21, and
34 the one that drives the type B output is output on pin 22, but those
35 pins are not connected on the board.
36
37
38 The command format is very simple:
39
40 0x: nop
41 1x: play sound type A
42 2x: play sound type B
43 3x: set parameters (type A) (followed by 4 bytes)
44 4x: set parameters (type B) (followed by 4 bytes)
45 5x: play sound type C
46 6x: set parameters (type C) (followed by 5 bytes)
47 7x: set volume for sound type C to x
48 8x-Fx: nop
49
50 ***************************************************************************/
51
52 #include "emu.h"
53 #include "namco54.h"
54
TIMER_CALLBACK_MEMBER(namco_54xx_device::latch_callback)55 TIMER_CALLBACK_MEMBER( namco_54xx_device::latch_callback )
56 {
57 m_latched_cmd = param;
58 }
59
WRITE_LINE_MEMBER(namco_54xx_device::reset)60 WRITE_LINE_MEMBER( namco_54xx_device::reset )
61 {
62 // The incoming signal is active low
63 m_cpu->set_input_line(INPUT_LINE_RESET, !state);
64 }
65
K_r()66 uint8_t namco_54xx_device::K_r()
67 {
68 return m_latched_cmd >> 4;
69 }
70
R0_r()71 uint8_t namco_54xx_device::R0_r()
72 {
73 return m_latched_cmd & 0x0f;
74 }
75
O_w(uint8_t data)76 void namco_54xx_device::O_w(uint8_t data)
77 {
78 uint8_t out = (data & 0x0f);
79 if (data & 0x10)
80 m_discrete->write(NAMCO_54XX_1_DATA(m_basenode), out);
81 else
82 m_discrete->write(NAMCO_54XX_0_DATA(m_basenode), out);
83 }
84
R1_w(uint8_t data)85 void namco_54xx_device::R1_w(uint8_t data)
86 {
87 uint8_t out = (data & 0x0f);
88
89 m_discrete->write(NAMCO_54XX_2_DATA(m_basenode), out);
90 }
91
92
write(uint8_t data)93 void namco_54xx_device::write(uint8_t data)
94 {
95 machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_54xx_device::latch_callback),this), data);
96
97 // TODO: should use chip_select line for this
98 m_cpu->pulse_input_line(0, m_irq_duration);
99 }
100
WRITE_LINE_MEMBER(namco_54xx_device::chip_select)101 WRITE_LINE_MEMBER( namco_54xx_device::chip_select )
102 {
103 // TODO: broken sound when using this
104 //m_cpu->set_input_line(0, state);
105 }
106
107
108 /***************************************************************************
109 DEVICE INTERFACE
110 ***************************************************************************/
111
112 ROM_START( namco_54xx )
113 ROM_REGION( 0x400, "mcu", 0 )
CRC(ee7357e0)114 ROM_LOAD( "54xx.bin", 0x0000, 0x0400, CRC(ee7357e0) SHA1(01bdf984a49e8d0cc8761b2cc162fd6434d5afbe) )
115 ROM_END
116
117 DEFINE_DEVICE_TYPE(NAMCO_54XX, namco_54xx_device, "namco54", "Namco 54xx")
118
119 namco_54xx_device::namco_54xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
120 : device_t(mconfig, NAMCO_54XX, tag, owner, clock),
121 m_cpu(*this, "mcu"),
122 m_discrete(*this, finder_base::DUMMY_TAG),
123 m_irq_duration(attotime::from_usec(100)),
124 m_basenode(0),
125 m_latched_cmd(0)
126 {
127 }
128
129 //-------------------------------------------------
130 // device_start - device-specific startup
131 //-------------------------------------------------
132
device_start()133 void namco_54xx_device::device_start()
134 {
135 save_item(NAME(m_latched_cmd));
136 }
137
138 //-------------------------------------------------
139 // device_add_mconfig - add device configuration
140 //-------------------------------------------------
141
device_add_mconfig(machine_config & config)142 void namco_54xx_device::device_add_mconfig(machine_config &config)
143 {
144 MB8844(config, m_cpu, DERIVED_CLOCK(1,1)); /* parent clock, internally divided by 6 */
145 m_cpu->read_k().set(FUNC(namco_54xx_device::K_r));
146 m_cpu->write_o().set(FUNC(namco_54xx_device::O_w));
147 m_cpu->read_r<0>().set(FUNC(namco_54xx_device::R0_r));
148 m_cpu->write_r<1>().set(FUNC(namco_54xx_device::R1_w));
149 }
150
151 //-------------------------------------------------
152 // device_rom_region - return a pointer to the
153 // the device's ROM definitions
154 //-------------------------------------------------
155
device_rom_region() const156 const tiny_rom_entry *namco_54xx_device::device_rom_region() const
157 {
158 return ROM_NAME(namco_54xx );
159 }
160