summaryrefslogtreecommitdiffstats
path: root/src/mame/audio/t5182.cpp
blob: 93726634dcbedfa3562e348d451b6537d4fbd79c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
// license:BSD-3-Clause
// copyright-holders:Jonathan Gevaryahu
/***************************************************************************

Toshiba T5182 die map, by Jonathan Gevaryahu AKA Lord Nightmare,
with assistance from Kevin Horton.
T5182 supplied by Tomasz 'Dox' Slanina which came from a Dark Mist PCB bought by Guru

Die Diagram:
|------------------------|
\ ROM  RAM  Z80    A     |
/ B    C    D   E  F  G  |
|------------------------|

The ROM is a 23128 wired as a 2364 by tying a13 to /ce
The RAM is a 2016
The Z80 is an NMOS Z80
Subdie A is a 7408 quad AND gate
Subdie B is a 74245 bidirectional bus transciever
Subdie C is a 74245 bidirectional bus transciever
Subdie D is a 74245 bidirectional bus transciever
Subdie E is a 74138 1 to 8 decoder/demultiplexer with active low outputs
Subdie F is a 74138 1 to 8 decoder/demultiplexer with active low outputs
Subdie G is a 7408 quad AND gate
Thanks to Kevin Horton for working out most of the logic gate types
from the diagram.


An updated version of Dox's t5182 pinout (originally from mustache.c) follows:

                       ______________________
                     _|*                     |_
               GND  |_|1                   50|_| Vcc
                     _|                      |_
                A8  |_|2                   49|_| A7
                     _|                      |_
                A9  |_|3                   48|_| A6
                     _|                      |_
               A10  |_|4                   47|_| A5
                     _|                      |_
               A11  |_|5                   46|_| A4
                     _|       TOSHIBA        |_
               A12  |_|6       T5182       45|_| A3
                     _|                      |_
               A13  |_|7                   44|_| A2
                     _|     JAPAN  8612      |_
               A14  |_|8                   43|_| A1
                     _|                      |_
               A15  |_|9                   42|_| A0
                     _|                      |_
                D4  |_|10                  41|_| D3
                     _|                      |_
                D5  |_|11                  40|_| D2
                     _|                      |_
                D6  |_|12                  39|_| D1
                     _|                      |_
                D7  |_|13                  38|_| D0
                     _|                      |_
         I/O /EN 2  |_|14                  37|_|  I/O /EN 1
                     _|                      |_
         I/O /EN 3  |_|15                  36|_|  I/O /EN 0
                     _|                      |_
         I/O /EN 4  |_|16                  35|_|  /EN 0x8000-0xFFFF
                     _|                      |_
         I/O /EN 5  |_|17                  34|_|  /EN 0x4000-0x7FFF
                     _|                      |_
  Z80 phi clock in  |_|18                  33|_|  N/C
                     _|                      |_
          Z80 /INT  |_|19                  32|_|  Z80 /RESET
                     _|                      |_
          Z80 /NMI  |_|20                  31|_|  Z80 /BUSRQ Test pin
                     _|                      |_
  Internal ROM /EN  |_|21                  30|_|  74245 'A'+'B' DIR Test pin
                     _|                      |_
 /EN 0x0000-0x1fff  |_|22                  29|_|  Z80 /BUSAK Test pin
                     _|                      |_
Z80 /MREQ Test pin  |_|23                  28|_|  Z80 /WR
                     _|                      |_
Z80 /IORQ Test pin  |_|24                  27|_|  Z80 /RD
                     _|                      |_
               GND  |_|25                  26|_|  Vcc
                      |______________________|

Based on sketch made by Tormod

Note: all pins marked as 'Test pin' are disabled internally and cannot be used
      without removing the chip cover and soldering together test pads.
Note: pins 21 and 22 are both shorted together on the pcb, and go active (low)
      while the internal rom is being read. The internal rom can be disabled by
      pulling /IORQ or /MREQ low, but both of those test pins are disabled, and
      also one would have to use the DIR test pin at the same time to feed the
      z80 a new internal rom. This is PROBABLY how Toshiba intended the t5182
      to be prototyped: a special t5182 with the internal jumpers all connected
      (except for the one between pins 21 and 22) would be given to a company
      who wanted to prototype the internal rom, allowing an external rom to be
      used instead of the internal one by using the test pins.

      However, the fact that pins 21 and 22 were NOT internally connected
      together by Toshiba on the *production* seibu t5182 means a huge
      security hole is opened:

      It is trivial, through external connections, without EVER opening the
      chip, to connect pin 22 to a trojan rom /CE and hence have a user trojan
      program run at 0x0000-0x1fff. Then, connect pin 21 to pin 34 to map the
      internal rom at 0x4000-0x7fff so it can be serially bit-banged out, or,
      even more easily, copied to an nvram chip attached to pin 35. Only 11
      bytes of code in the trojan rom are needed to do this.

      There is no internal protection in the chip at all which prevents the
      internal rom from being connected to an enable other than pin 22, which
      would have prevented this theoretical attack from working


Z80 Memory Map:
0x0000-0x1FFF - external space 0 (connected to internal rom /enable outside the
                chip)
0x2000-0x3fff - Internal RAM, repeated/mirrored 4 times
0x4000-0x7fff - external space 1 (used for communication shared memory?)
0x8000-0xFFFF - external space 2 (used for sound rom)

I/O map:
FEDCBA9876543210
xxxxxxxxx000xxxx i/o /EN 0 goes low
xxxxxxxxx001xxxx i/o /EN 1 goes low
xxxxxxxxx010xxxx i/o /EN 2 goes low
xxxxxxxxx011xxxx i/o /EN 3 goes low
xxxxxxxxx100xxxx i/o /EN 4 goes low
xxxxxxxxx101xxxx i/o /EN 5 goes low
xxxxxxxxx110xxxx i/o /EN 6\__ these two are unbonded pins, so are useless.
xxxxxxxxx111xxxx i/o /EN 7/

IMPORTANT: the data lines for the external rom on darkmist are scrambled on the
SEI8608B board as such:
CPU:     ROM:
D0       D0
D1       D6
D2       D5
D3       D4
D4       D3
D5       D2
D6       D1
D7       D7
Only the data lines are scrambled, the address lines are not.
These lines are NOT scrambled to the ym2151 or anything else, just the external
rom.

***************************************************************************/

#include "emu.h"
#include "t5182.h"

#define T5182_CLOCK     XTAL(14'318'181)/4

DEFINE_DEVICE_TYPE(T5182, t5182_device, "t5182", "T5182 MCU")

t5182_device::t5182_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, T5182, tag, owner, clock),
	m_ourcpu(*this, "t5182_z80"),
	m_sharedram(*this, "sharedram"),
	m_irqstate(0),
	m_semaphore_main(0),
	m_semaphore_snd(0)
{
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void t5182_device::device_start()
{
	m_setirq_cb = timer_alloc(SETIRQ_CB);

	save_item(NAME(m_irqstate));
	save_item(NAME(m_semaphore_main));
	save_item(NAME(m_semaphore_snd));
}

READ8_MEMBER(t5182_device::sharedram_r)
{
	return m_sharedram[offset];
}

WRITE8_MEMBER(t5182_device::sharedram_w)
{
	m_sharedram[offset] = data;
}

TIMER_CALLBACK_MEMBER( t5182_device::setirq_callback )
{
	switch(param)
	{
		case YM2151_ASSERT:
			m_irqstate |= 1|4;
			break;

		case YM2151_CLEAR:
			m_irqstate &= ~1;
			break;

		case YM2151_ACK:
			m_irqstate &= ~4;
			break;

		case CPU_ASSERT:
			m_irqstate |= 2;  // also used by t5182_sharedram_semaphore_main_r
			break;

		case CPU_CLEAR:
			m_irqstate &= ~2;
			break;
	}

	if (m_ourcpu == nullptr)
		return;

	if (m_irqstate == 0)  /* no IRQs pending */
		m_ourcpu->set_input_line(0,CLEAR_LINE);
	else    /* IRQ pending */
		m_ourcpu->set_input_line(0,ASSERT_LINE);
}

void t5182_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
		case SETIRQ_CB:
			setirq_callback(ptr, param);
			break;
		default:
			assert_always(false, "Unknown id in t5182_device::device_timer");
	}
}

WRITE8_MEMBER( t5182_device::sound_irq_w )
{
	synchronize(SETIRQ_CB, CPU_ASSERT);
}

WRITE8_MEMBER( t5182_device::ym2151_irq_ack_w )
{
	synchronize(SETIRQ_CB, YM2151_ACK);
}

WRITE8_MEMBER( t5182_device::cpu_irq_ack_w )
{
	synchronize(SETIRQ_CB, CPU_CLEAR);
}

WRITE_LINE_MEMBER(t5182_device::ym2151_irq_handler)
{
	if (state)
		synchronize(SETIRQ_CB, YM2151_ASSERT);
	else
		synchronize(SETIRQ_CB, YM2151_CLEAR);
}

READ8_MEMBER(t5182_device::sharedram_semaphore_snd_r)
{
	return m_semaphore_snd;
}

WRITE8_MEMBER(t5182_device::sharedram_semaphore_main_acquire_w)
{
	m_semaphore_main = 1;
}

WRITE8_MEMBER(t5182_device::sharedram_semaphore_main_release_w)
{
	m_semaphore_main = 0;
}

WRITE8_MEMBER(t5182_device::sharedram_semaphore_snd_acquire_w)
{
	m_semaphore_snd = 1;
}

WRITE8_MEMBER(t5182_device::sharedram_semaphore_snd_release_w)
{
	m_semaphore_snd = 0;
}

READ8_MEMBER(t5182_device::sharedram_semaphore_main_r)
{
	return m_semaphore_main | (m_irqstate & 2);
}

// ROM definition for the Toshiba T5182 Custom CPU internal program ROM
ROM_START( t5182 )
	ROM_REGION( 0x2000, "cpu", 0 )
	ROM_LOAD( "t5182.rom",   0x0000, 0x2000, CRC(d354c8fc) SHA1(a1c9e1ac293f107f69cc5788cf6abc3db1646e33) )
ROM_END

//-------------------------------------------------
//  rom_region - return a pointer to the device's
//  internal ROM region
//-------------------------------------------------
const tiny_rom_entry *t5182_device::device_rom_region() const
{
	return ROM_NAME( t5182 );
}

INPUT_PORTS_START(t5182)
	PORT_START("T5182_COIN")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(2)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_IMPULSE(2)
INPUT_PORTS_END

//-------------------------------------------------
//  input_ports - return a pointer to the implicit
//  input ports description for this device
//-------------------------------------------------

ioport_constructor t5182_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(t5182);
}


	// 4000-407F    RAM shared with main CPU
	// 4000 output queue length
	// 4001-4020 output queue
	// answers:
	//  80XX finished playing sound XX
	//  A0XX short contact on coin slot XX (coin error)
	//  A1XX inserted coin in slot XX
	// 4021 input queue length
	// 4022-4041 input queue
	// commands:
	//  80XX play sound XX
	//  81XX stop sound XX
	//  82XX stop all voices associated with timer A/B/both where XX = 01/02/03
	//  84XX play sound XX if it isn't already playing
	//  90XX reset
	//  A0XX
	// rest unused
void t5182_device::t5182_map(address_map &map)
{
	map(0x0000, 0x1fff).rom().region("cpu", 0); // internal ROM
	map(0x2000, 0x27ff).ram().mirror(0x1800); // internal RAM
	map(0x4000, 0x40ff).ram().mirror(0x3F00).share("sharedram"); // 2016 with four 74ls245s, one each for main and t5182 address and data. pins 23, 22, 20, 19, 18 are all tied low so only 256 bytes are usable
	map(0x8000, 0xffff).rom().region(":t5182_z80", 0); // external ROM
}


	// 00  W YM2151 address
	// 01 RW YM2151 data
	// 10  W semaphore for shared RAM: set as in use
	// 11  W semaphore for shared RAM: set as not in use
	// 12  W clear IRQ from YM2151
	// 13  W clear IRQ from main CPU
	// 20 R  flags bit 0 = main CPU is accessing shared RAM????  bit 1 = main CPU generated IRQ
	// 30 R  coin inputs (bits 0 and 1, active high)
	// 40  W external ROM banking? (the only 0 bit enables a ROM)
	// 50  W test mode status flags (bit 0 = ROM test fail, bit 1 = RAM test fail, bit 2 = YM2151 IRQ not received)
void t5182_device::t5182_io(address_map &map)
{
	map.global_mask(0xff);
	map(0x00, 0x01).rw(":ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
	map(0x10, 0x10).w(FUNC(t5182_device::sharedram_semaphore_snd_acquire_w));
	map(0x11, 0x11).w(FUNC(t5182_device::sharedram_semaphore_snd_release_w));
	map(0x12, 0x12).w(FUNC(t5182_device::ym2151_irq_ack_w));
	map(0x13, 0x13).w(FUNC(t5182_device::cpu_irq_ack_w));
	map(0x20, 0x20).r(FUNC(t5182_device::sharedram_semaphore_main_r));
	map(0x30, 0x30).portr("T5182_COIN");
}


//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------

MACHINE_CONFIG_START(t5182_device::device_add_mconfig)
	MCFG_DEVICE_ADD("t5182_z80", Z80, T5182_CLOCK)
	MCFG_DEVICE_PROGRAM_MAP(t5182_map)
	MCFG_DEVICE_IO_MAP(t5182_io)

MACHINE_CONFIG_END