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