1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 /***************************************************************************
4 
5 IREM "M72" sound hardware
6 
7 All games have a YM2151 for music, and most of them also samples. Samples
8 are not handled consistently by all the games, some use a high frequency NMI
9 handler to push them through a DAC, others use external hardware.
10 In the following table, the NMI column indicates with a No the games whose
11 NMI handler only consists of RETN. R-Type is an exception, it doesn't have
12 a valid NMI handler at all.
13 
14 Game                                    Year  ID string     NMI
15 --------------------------------------  ----  ------------  ---
16 R-Type                                  1987  - (earlier version, no samples)
17 Battle Chopper / Mr. Heli               1987  Rev 2.20      Yes
18 Vigilante                               1988  Rev 2.20      Yes
19 Ninja Spirit                            1988  Rev 2.20      Yes
20 Image Fight                             1988  Rev 2.20      Yes
21 Legend of Hero Tonma                    1989  Rev 2.20      Yes
22 X Multiply                              1989  Rev 2.20      Yes
23 Dragon Breed                            1989  Rev 2.20      Yes
24 Kickle Cubicle                          1988  Rev 2.21      Yes
25 Shisensho                               1989  Rev 2.21      Yes
26 R-Type II                               1989  Rev 2.21      Yes
27 Major Title                             1990  Rev 2.21      Yes
28 Air Duel                                1990  Rev 3.14 M72   No
29 Daiku no Gensan                         1990  Rev 3.14 M81  Yes
30 Daiku no Gensan (M72)                   1990  Rev 3.15 M72   No
31 Hammerin' Harry                         1990  Rev 3.15 M81  Yes
32 Ken-Go                                  1991  Rev 3.15 M81  Yes
33 Pound for Pound                         1990  Rev 3.15 M83   No
34 Cosmic Cop                              1991  Rev 3.15 M81  Yes
35 Gallop - Armed Police Unit              1991  Rev 3.15 M72   No
36 Hasamu                                  1991  Rev 3.15 M81  Yes
37 Bomber Man                              1991  Rev 3.15 M81  Yes
38 Bomber Man World (Japan)                1992  Rev 3.31 M81  Yes
39 Bomber Man World (World) / Atomic Punk  1992  Rev 3.31 M99   No
40 Quiz F-1 1,2finish                      1992  Rev 3.33 M81  Yes
41 Risky Challenge                         1993  Rev 3.34 M81  Yes
42 Shisensho II                            1993  Rev 3.34 M81  Yes
43 
44 ***************************************************************************/
45 
46 #include "emu.h"
47 #include "m72.h"
48 
49 
50 DEFINE_DEVICE_TYPE(IREM_M72_AUDIO, m72_audio_device, "m72_audio", "Irem M72 Audio")
51 
m72_audio_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)52 m72_audio_device::m72_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
53 	: device_t(mconfig, IREM_M72_AUDIO, tag, owner, clock)
54 	, device_rom_interface(mconfig, *this)
55 	, m_sample_addr(0)
56 	, m_dac(*this, finder_base::DUMMY_TAG)
57 {
58 }
59 
60 //-------------------------------------------------
61 //  device_start - device-specific startup
62 //-------------------------------------------------
63 
device_start()64 void m72_audio_device::device_start()
65 {
66 	save_item(NAME(m_sample_addr));
67 }
68 
69 //-------------------------------------------------
70 //  rom_bank_updated - the rom bank has changed
71 //-------------------------------------------------
72 
rom_bank_updated()73 void m72_audio_device::rom_bank_updated()
74 {
75 }
76 
set_sample_start(int start)77 void m72_audio_device::set_sample_start(int start)
78 {
79 	m_sample_addr = start;
80 }
81 
vigilant_sample_addr_w(offs_t offset,u8 data)82 void m72_audio_device::vigilant_sample_addr_w(offs_t offset, u8 data)
83 {
84 	if (offset == 1)
85 		m_sample_addr = (m_sample_addr & 0x00ff) | ((data << 8) & 0xff00);
86 	else
87 		m_sample_addr = (m_sample_addr & 0xff00) | ((data << 0) & 0x00ff);
88 }
89 
shisen_sample_addr_w(offs_t offset,u8 data)90 void m72_audio_device::shisen_sample_addr_w(offs_t offset, u8 data)
91 {
92 	m_sample_addr >>= 2;
93 
94 	if (offset == 1)
95 		m_sample_addr = (m_sample_addr & 0x00ff) | ((data << 8) & 0xff00);
96 	else
97 		m_sample_addr = (m_sample_addr & 0xff00) | ((data << 0) & 0x00ff);
98 
99 	m_sample_addr <<= 2;
100 }
101 
rtype2_sample_addr_w(offs_t offset,u8 data)102 void m72_audio_device::rtype2_sample_addr_w(offs_t offset, u8 data)
103 {
104 	m_sample_addr >>= 5;
105 
106 	if (offset == 1)
107 		m_sample_addr = (m_sample_addr & 0x00ff) | ((data << 8) & 0xff00);
108 	else
109 		m_sample_addr = (m_sample_addr & 0xff00) | ((data << 0) & 0x00ff);
110 
111 	m_sample_addr <<= 5;
112 }
113 
poundfor_sample_addr_w(offs_t offset,u8 data)114 void m72_audio_device::poundfor_sample_addr_w(offs_t offset, u8 data)
115 {
116 	/* poundfor writes both sample start and sample END - a first for Irem...
117 	   we don't handle the end written here, 00 marks the sample end as usual. */
118 	if (offset > 1) return;
119 
120 	m_sample_addr >>= 4;
121 
122 	if (offset == 1)
123 		m_sample_addr = (m_sample_addr & 0x00ff) | ((data << 8) & 0xff00);
124 	else
125 		m_sample_addr = (m_sample_addr & 0xff00) | ((data << 0) & 0x00ff);
126 
127 	m_sample_addr <<= 4;
128 }
129 
sample_r()130 u8 m72_audio_device::sample_r()
131 {
132 	return read_byte(m_sample_addr);
133 }
134 
sample_w(u8 data)135 void m72_audio_device::sample_w(u8 data)
136 {
137 	m_dac->write(data);
138 	m_sample_addr++;
139 }
140