1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     Seibu Sound System v1.02, games using this include:
6 
7     Cross Shooter    1987   * "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (YM2151 substituted for YM3812)
8     Cabal            1988   * "Michel/Seibu    sound 11/04/88" (YM2151 substituted for YM3812, unknown ADPCM)
9     Dead Angle       1988   * "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (2xYM2203 substituted for YM3812, unknown ADPCM)
10     Dynamite Duke    1989   * "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
11     Toki             1989   * "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
12     Raiden           1990   * "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
13     Blood Brothers   1990     "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
14     D-Con            1992     "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
15 
16     Related sound programs (not implemented yet):
17 
18     Zero Team                 "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC."
19     Legionnaire               "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (YM2151 substituted for YM3812)
20     Raiden 2                  "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (YM2151 substituted for YM3812, plus extra MSM6205)
21     Raiden DX                 "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (YM2151 substituted for YM3812, plus extra MSM6205)
22     Cup Soccer                "START UP PROGRAM V1.02 (C)1986 SEIBU KAIHATSU INC." (YM2151 substituted for YM3812, plus extra MSM6205)
23     SD Gundam Psycho Salamander "Copyright by King Bee Sol 1991"
24     * = encrypted
25 
26 ***************************************************************************/
27 #ifndef MAME_AUDIO_SEIBU_H
28 #define MAME_AUDIO_SEIBU_H
29 
30 #pragma once
31 
32 #include "cpu/z80/z80.h"
33 #include "sound/okiadpcm.h"
34 #include "dirom.h"
35 
36 class seibu_sound_common {
37 public:
38 	virtual ~seibu_sound_common() = default;
39 
40 protected:
41 	void seibu_sound_map(address_map &map);
42 };
43 
44 class seibu_sound_device : public device_t
45 {
46 public:
47 	seibu_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
~seibu_sound_device()48 	~seibu_sound_device() { }
49 
50 	//  configuration
set_rom_tag(T && tag)51 	template <typename T> void set_rom_tag(T &&tag) { m_sound_rom.set_tag(std::forward<T>(tag)); }
set_rombank_tag(T && tag)52 	template <typename T> void set_rombank_tag(T &&tag) { m_rom_bank.set_tag(std::forward<T>(tag)); }
int_callback()53 	auto int_callback()  { return m_int_cb.bind(); }
ym_read_callback()54 	auto ym_read_callback()  { return m_ym_read_cb.bind(); }
ym_write_callback()55 	auto ym_write_callback() { return m_ym_write_cb.bind(); }
56 
57 	u8 main_r(offs_t offset);
58 	void main_w(offs_t offset, u8 data);
59 	void main_mustb_w(offs_t, u16 data, u16 mem_mask);
60 	void irq_clear_w(u8);
61 	void rst10_ack_w(u8);
62 	void rst18_ack_w(u8);
63 	u8 ym_r(offs_t offset);
64 	void ym_w(offs_t offset, u8 data);
65 	void bank_w(u8 data);
66 	void coin_w(u8 data);
67 	WRITE_LINE_MEMBER( fm_irqhandler );
68 	u8 soundlatch_r(offs_t offset);
69 	u8 main_data_pending_r();
70 	void main_data_w(offs_t offset, u8 data);
71 	void pending_w(u8);
72 
73 	IRQ_CALLBACK_MEMBER(im0_vector_cb);
74 
75 protected:
76 	// device-level overrides
77 	virtual void device_start() override;
78 	virtual void device_reset() override;
79 
80 private:
81 	void update_irq_lines(int param);
82 	TIMER_CALLBACK_MEMBER(update_irq_synced);
83 
84 	// device callbacks
85 	devcb_write_line m_int_cb;
86 	devcb_read8 m_ym_read_cb;
87 	devcb_write8 m_ym_write_cb;
88 
89 	// internal state
90 	optional_region_ptr<uint8_t> m_sound_rom;
91 	optional_memory_bank m_rom_bank;
92 	uint8_t m_main2sub[2];
93 	uint8_t m_sub2main[2];
94 	int m_main2sub_pending;
95 	int m_sub2main_pending;
96 	uint8_t m_rst10_irq;
97 	uint8_t m_rst18_irq;
98 
99 	enum
100 	{
101 		VECTOR_INIT,
102 		RST10_ASSERT,
103 		RST10_CLEAR,
104 		RST18_ASSERT,
105 		RST18_CLEAR
106 	};
107 };
108 
DECLARE_DEVICE_TYPE(SEIBU_SOUND,seibu_sound_device)109 DECLARE_DEVICE_TYPE(SEIBU_SOUND, seibu_sound_device)
110 
111 
112 // SEI80BU (Z80 program decryption)
113 
114 class sei80bu_device : public device_t, public device_rom_interface<16>
115 {
116 public:
117 	sei80bu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
118 
119 	u8 data_r(offs_t offset);
120 	u8 opcode_r(offs_t offset);
121 
122 protected:
123 	// device-level overrides
124 	virtual void device_start() override { }
125 	virtual void rom_bank_updated() override { }
126 };
127 
DECLARE_DEVICE_TYPE(SEI80BU,sei80bu_device)128 DECLARE_DEVICE_TYPE(SEI80BU, sei80bu_device)
129 
130 // Seibu ADPCM device
131 
132 class seibu_adpcm_device : public device_t,
133 									public device_sound_interface
134 {
135 public:
136 	seibu_adpcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
137 	~seibu_adpcm_device() { }
138 
139 	void decrypt();
140 	void adr_w(offs_t offset, u8 data);
141 	void ctl_w(u8 data);
142 
143 protected:
144 	// device-level overrides
145 	virtual void device_start() override;
146 
147 	// sound stream update overrides
148 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
149 
150 private:
151 	// internal state
152 	oki_adpcm_state m_adpcm;
153 	sound_stream *m_stream;
154 	uint32_t m_current;
155 	uint32_t m_end;
156 	uint8_t m_nibble;
157 	uint8_t m_playing;
158 	required_region_ptr<uint8_t> m_base;
159 };
160 
161 DECLARE_DEVICE_TYPE(SEIBU_ADPCM, seibu_adpcm_device)
162 
163 /**************************************************************************/
164 
165 #define SEIBU_COIN_INPUTS                                           \
166 	PORT_START("COIN")                                              \
167 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(4)     \
168 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_IMPULSE(4)     \
169 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )                    \
170 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )                    \
171 	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )                    \
172 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )                    \
173 	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )                    \
174 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
175 
176 #define SEIBU_COIN_INPUTS_INVERT                                    \
177 	PORT_START("COIN")                                              \
178 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(4)      \
179 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(4)      \
180 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )                     \
181 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )                     \
182 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )                     \
183 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )                     \
184 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )                     \
185 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
186 
187 /**************************************************************************/
188 
189 #endif // MAME_AUDIO_SEIBU_H
190