1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 Namco 52XX
6
7 This instance of the Fujitsu MB8843 MCU is programmed to act as a
8 sample player. It is used by just a few games, most notably Bosconian
9 and Pole Position.
10
11 A0-A15 = address to read from sample ROMs
12 D0-D7 = data from sample ROMs
13 CMD0-CMD3 = command from CPU (sample to play, 0 = none)
14 OUT0-OUT3 = sound output
15
16 +------+
17 EX|1 42|Vcc
18 X|2 41|K3 (CMD3)
19 /RESET|3 40|K2 (CMD2)
20 /IRQ|4 39|K1 (CMD1)
21 (n.c.) SO|5 38|K0 (CMD0)
22 [1] SI|6 37|R15 (A7)
23 (n.c.) /SC/TO|7 36|R14 (A6)
24 [2] /TC|8 35|R13 (A5)
25 (OUT0) P0|9 34|R12 (A4)
26 (OUT1) P1|10 33|R11 (A3)
27 (OUT2) P2|11 32|R10 (A2)
28 (OUT3) P3|12 31|R9 (A1)
29 (A8) O0|13 30|R8 (A0)
30 (A9) O1|14 29|R7 (D7)
31 (A10) O2|15 28|R6 (D6)
32 (A11) O3|16 27|R5 (D5)
33 (A12) O4|17 26|R4 (D4)
34 (A13) O5|18 25|R3 (D3)
35 (A14) O6|19 24|R2 (D2)
36 (A15) O7|20 23|R1 (D1)
37 GND|21 22|R0 (D0)
38 +------+
39
40 [1] in polepos, +5V; in bosco, GND
41 this value controls the ROM addressing mode:
42 if 0 (GND), A12-A15 are direct active-low chip enables
43 if 1 (Vcc), A12-A15 are address lines
44
45 [2] in polepos, GND; in bosco, output from a 555 timer
46 this value is an external timer, which is used for some samples
47
48 ***************************************************************************/
49
50 #include "emu.h"
51 #include "namco52.h"
52
WRITE_LINE_MEMBER(namco_52xx_device::reset)53 WRITE_LINE_MEMBER( namco_52xx_device::reset )
54 {
55 // The incoming signal is active low
56 m_cpu->set_input_line(INPUT_LINE_RESET, !state);
57 }
58
TIMER_CALLBACK_MEMBER(namco_52xx_device::latch_callback)59 TIMER_CALLBACK_MEMBER( namco_52xx_device::latch_callback )
60 {
61 m_latched_cmd = param;
62 }
63
K_r()64 uint8_t namco_52xx_device::K_r()
65 {
66 return m_latched_cmd & 0x0f;
67 }
68
READ_LINE_MEMBER(namco_52xx_device::SI_r)69 READ_LINE_MEMBER( namco_52xx_device::SI_r )
70 {
71 return m_si(0) ? 1 : 0;
72 }
73
R0_r()74 uint8_t namco_52xx_device::R0_r()
75 {
76 return m_romread(m_address) & 0x0f;
77 }
78
R1_r()79 uint8_t namco_52xx_device::R1_r()
80 {
81 return m_romread(m_address) >> 4;
82 }
83
84
P_w(uint8_t data)85 void namco_52xx_device::P_w(uint8_t data)
86 {
87 m_discrete->write(NAMCO_52XX_P_DATA(m_basenode), data & 0x0f);
88 }
89
R2_w(uint8_t data)90 void namco_52xx_device::R2_w(uint8_t data)
91 {
92 m_address = (m_address & 0xfff0) | ((data & 0xf) << 0);
93 }
94
R3_w(uint8_t data)95 void namco_52xx_device::R3_w(uint8_t data)
96 {
97 m_address = (m_address & 0xff0f) | ((data & 0xf) << 4);
98 }
99
O_w(uint8_t data)100 void namco_52xx_device::O_w(uint8_t data)
101 {
102 if (data & 0x10)
103 m_address = (m_address & 0x0fff) | ((data & 0xf) << 12);
104 else
105 m_address = (m_address & 0xf0ff) | ((data & 0xf) << 8);
106 }
107
108
write(uint8_t data)109 void namco_52xx_device::write(uint8_t data)
110 {
111 machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_52xx_device::latch_callback),this), data);
112
113 // TODO: should use chip_select line for this
114 m_cpu->pulse_input_line(0, m_irq_duration);
115 }
116
WRITE_LINE_MEMBER(namco_52xx_device::chip_select)117 WRITE_LINE_MEMBER( namco_52xx_device::chip_select )
118 {
119 // TODO: broken sound when using this
120 //m_cpu->set_input_line(0, state);
121 }
122
TIMER_CALLBACK_MEMBER(namco_52xx_device::external_clock_pulse)123 TIMER_CALLBACK_MEMBER( namco_52xx_device::external_clock_pulse )
124 {
125 m_cpu->clock_w(ASSERT_LINE);
126 m_cpu->clock_w(CLEAR_LINE);
127 }
128
129
130 /***************************************************************************
131 DEVICE INTERFACE
132 ***************************************************************************/
133
134 ROM_START( namco_52xx )
135 ROM_REGION( 0x400, "mcu", 0 )
136 ROM_LOAD( "52xx.bin", 0x0000, 0x0400, CRC(3257d11e) SHA1(4883b2fdbc99eb7b9906357fcc53915842c2c186) )
137 ROM_END
138
139
140 DEFINE_DEVICE_TYPE(NAMCO_52XX, namco_52xx_device, "namco52", "Namco 52xx")
141
namco_52xx_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)142 namco_52xx_device::namco_52xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
143 : device_t(mconfig, NAMCO_52XX, tag, owner, clock),
144 m_cpu(*this, "mcu"),
145 m_discrete(*this, finder_base::DUMMY_TAG),
146 m_irq_duration(attotime::from_usec(100)),
147 m_basenode(0),
148 m_extclock(0),
149 m_romread(*this),
150 m_si(*this),
151 m_latched_cmd(0),
152 m_address(0)
153 {
154 }
155
156 //-------------------------------------------------
157 // device_start - device-specific startup
158 //-------------------------------------------------
159
device_start()160 void namco_52xx_device::device_start()
161 {
162 /* resolve our read/write callbacks */
163 m_romread.resolve_safe(0);
164 m_si.resolve_safe(0);
165
166 /* start the external clock */
167 if (m_extclock != 0)
168 {
169 m_extclock_pulse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(namco_52xx_device::external_clock_pulse), this));
170 m_extclock_pulse_timer->adjust(attotime(0, m_extclock), 0, attotime(0, m_extclock));
171 }
172
173 save_item(NAME(m_latched_cmd));
174 save_item(NAME(m_address));
175 }
176
177 //-------------------------------------------------
178 // device_add_mconfig - add device configuration
179 //-------------------------------------------------
180
device_add_mconfig(machine_config & config)181 void namco_52xx_device::device_add_mconfig(machine_config &config)
182 {
183 MB8843(config, m_cpu, DERIVED_CLOCK(1,1)); /* parent clock, internally divided by 6 */
184 m_cpu->read_k().set(FUNC(namco_52xx_device::K_r));
185 m_cpu->write_o().set(FUNC(namco_52xx_device::O_w));
186 m_cpu->write_p().set(FUNC(namco_52xx_device::P_w));
187 m_cpu->read_si().set(FUNC(namco_52xx_device::SI_r));
188 m_cpu->read_r<0>().set(FUNC(namco_52xx_device::R0_r));
189 m_cpu->read_r<1>().set(FUNC(namco_52xx_device::R1_r));
190 m_cpu->write_r<2>().set(FUNC(namco_52xx_device::R2_w));
191 m_cpu->write_r<3>().set(FUNC(namco_52xx_device::R3_w));
192 }
193
194 //-------------------------------------------------
195 // device_rom_region - return a pointer to the
196 // the device's ROM definitions
197 //-------------------------------------------------
198
device_rom_region() const199 const tiny_rom_entry *namco_52xx_device::device_rom_region() const
200 {
201 return ROM_NAME(namco_52xx );
202 }
203