1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria, Mike Coates, Frank Palazzolo, Aaron Giles
3 /***************************************************************************
4 
5     Bally Astrocade-based hardware
6 
7 ***************************************************************************/
8 #ifndef MAME_INCLUDES_ASTROCDE_H
9 #define MAME_INCLUDES_ASTROCDE_H
10 
11 #pragma once
12 
13 #include "cpu/z80/z80.h"
14 #include "machine/bankdev.h"
15 #include "machine/gen_latch.h"
16 #include "sound/astrocde.h"
17 #include "sound/samples.h"
18 #include "sound/votrax.h"
19 #include "emupal.h"
20 #include "screen.h"
21 
22 #define ASTROCADE_CLOCK     (XTAL(14'318'181)/2)
23 
24 #define AC_SOUND_PRESENT    (0x01)
25 #define AC_LIGHTPEN_INTS    (0x02)
26 #define AC_STARS            (0x04)
27 #define AC_MONITOR_BW       (0x08)
28 
29 
30 class astrocde_state : public driver_device
31 {
32 public:
33 	enum
34 	{
35 		TIMER_INTERRUPT_OFF,
36 		TIMER_SCANLINE
37 	};
38 
astrocde_state(const machine_config & mconfig,device_type type,const char * tag)39 	astrocde_state(const machine_config &mconfig, device_type type, const char *tag) :
40 		driver_device(mconfig, type, tag),
41 		m_maincpu(*this, "maincpu"),
42 		m_votrax(*this, "votrax"),
43 		m_astrocade_sound1(*this, "astrocade1"),
44 		m_videoram(*this, "videoram"),
45 		m_protected_ram(*this, "protected_ram"),
46 		m_nvram(*this, "nvram"),
47 		m_screen(*this, "screen"),
48 		m_palette(*this, "palette"),
49 		m_soundlatch(*this, "soundlatch"),
50 		m_bank4000(*this, "bank4000"),
51 		m_bank8000(*this, "bank8000"),
52 		m_handle(*this, "P%uHANDLE", 1U),
53 		m_interrupt_scanline(0xff)
54 	{ }
55 
56 	required_device<cpu_device> m_maincpu;
57 	optional_device<votrax_sc01_device> m_votrax;
58 	optional_device<astrocade_io_device> m_astrocade_sound1;
59 	optional_shared_ptr<uint8_t> m_videoram;
60 	optional_shared_ptr<uint8_t> m_protected_ram;
61 	optional_shared_ptr<uint8_t> m_nvram;
62 	required_device<screen_device> m_screen;
63 	required_device<palette_device> m_palette;
64 	optional_device<generic_latch_8_device> m_soundlatch;
65 	optional_device<address_map_bank_device> m_bank4000;
66 	optional_memory_bank m_bank8000;
67 	optional_ioport_array<4> m_handle;
68 
69 	uint8_t m_video_config;
70 	uint8_t m_sparkle[4];
71 	char m_totalword[256];
72 	char *m_totalword_ptr;
73 	char m_oldword[256];
74 	int m_plural;
75 	uint8_t m_ram_write_enable;
76 	uint8_t m_input_select;
77 	std::unique_ptr<uint8_t[]> m_sparklestar;
78 	uint8_t m_interrupt_enabl;
79 	uint8_t m_interrupt_vector;
80 	uint8_t m_interrupt_scanline;
81 	uint8_t m_vertical_feedback;
82 	uint8_t m_horizontal_feedback;
83 	emu_timer *m_scanline_timer;
84 	emu_timer *m_intoff_timer;
85 	uint8_t m_colors[8];
86 	uint8_t m_colorsplit;
87 	uint8_t m_bgdata;
88 	uint8_t m_vblank;
89 	uint8_t m_video_mode;
90 	uint8_t m_funcgen_expand_color[2];
91 	uint8_t m_funcgen_control;
92 	uint8_t m_funcgen_expand_count;
93 	uint8_t m_funcgen_rotate_count;
94 	uint8_t m_funcgen_rotate_data[4];
95 	uint8_t m_funcgen_shift_prev_data;
96 	uint8_t m_funcgen_intercept;
97 	uint16_t m_pattern_source;
98 	uint8_t m_pattern_mode;
99 	uint16_t m_pattern_dest;
100 	uint8_t m_pattern_skip;
101 	uint8_t m_pattern_width;
102 	uint8_t m_pattern_height;
103 	std::unique_ptr<uint16_t[]> m_profpac_videoram;
104 	uint16_t m_profpac_palette[16];
105 	uint8_t m_profpac_colormap[4];
106 	uint8_t m_profpac_intercept;
107 	uint8_t m_profpac_vispage;
108 	uint8_t m_profpac_readpage;
109 	uint8_t m_profpac_readshift;
110 	uint8_t m_profpac_writepage;
111 	uint8_t m_profpac_writemode;
112 	uint16_t m_profpac_writemask;
113 	uint8_t m_profpac_vw;
114 	void protected_ram_enable_w(uint8_t data);
115 	uint8_t protected_ram_r(offs_t offset);
116 	void protected_ram_w(offs_t offset, uint8_t data);
117 	uint8_t input_mux_r(offs_t offset);
118 	template<int Coin> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
119 	template<int Bit> DECLARE_WRITE_LINE_MEMBER(sparkle_w);
120 	DECLARE_WRITE_LINE_MEMBER(gorf_sound_switch_w);
121 	void profpac_banksw_w(uint8_t data);
122 	void demndrgn_banksw_w(uint8_t data);
123 	uint8_t video_register_r(offs_t offset);
124 	void video_register_w(offs_t offset, uint8_t data);
125 	void astrocade_funcgen_w(address_space &space, offs_t offset, uint8_t data);
126 	void expand_register_w(uint8_t data);
127 	void astrocade_pattern_board_w(offs_t offset, uint8_t data);
128 	void profpac_page_select_w(uint8_t data);
129 	uint8_t profpac_intercept_r();
130 	void profpac_screenram_ctrl_w(offs_t offset, uint8_t data);
131 	uint8_t profpac_videoram_r(offs_t offset);
132 	void profpac_videoram_w(offs_t offset, uint8_t data);
133 	DECLARE_INPUT_CHANGED_MEMBER(spacezap_monitor);
134 	DECLARE_WRITE_LINE_MEMBER(lightpen_trigger_w);
135 	void init_profpac();
136 	void init_spacezap();
137 	void init_robby();
138 	void init_wow();
139 	void init_tenpindx();
140 	void init_seawolf2();
141 	void init_demndrgn();
142 	void init_ebases();
143 	void init_gorf();
144 	void init_astrocde();
145 	virtual void video_start() override;
146 	void astrocade_palette(palette_device &palette) const;
147 	DECLARE_VIDEO_START(profpac);
148 	void profpac_palette(palette_device &palette) const;
149 	uint32_t screen_update_astrocde(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
150 	uint32_t screen_update_profpac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
151 	TIMER_CALLBACK_MEMBER(scanline_callback);
152 	inline int mame_vpos_to_astrocade_vpos(int scanline);
153 	void init_savestate();
154 	void astrocade_trigger_lightpen(uint8_t vfeedback, uint8_t hfeedback);
155 	inline void increment_source(uint8_t curwidth, uint8_t *u13ff);
156 	inline void increment_dest(uint8_t curwidth);
157 	void execute_blit();
158 	void init_sparklestar();
159 	virtual void machine_start() override;
160 
161 	void votrax_speech_w(uint8_t data);
162 	DECLARE_READ_LINE_MEMBER( votrax_speech_status_r );
163 
164 	void astrocade_base(machine_config &config);
165 	void astrocade_16color_base(machine_config &config);
166 	void astrocade_mono_sound(machine_config &config);
167 	void astrocade_stereo_sound(machine_config &config);
168 	void spacezap(machine_config &config);
169 	void gorf(machine_config &config);
170 	void profpac(machine_config &config);
171 	void robby(machine_config &config);
172 	void wow(machine_config &config);
173 	void bank4000_map(address_map &map);
174 	void demndrgn_map(address_map &map);
175 	void port_map(address_map &map);
176 	void port_map_16col_pattern(address_map &map);
177 	void port_map_16col_pattern_nosound(address_map &map);
178 	void port_map_mono_pattern(address_map &map);
179 	void port_map_stereo_pattern(address_map &map);
180 	void profpac_bank4000_map(address_map &map);
181 	void profpac_map(address_map &map);
182 	void robby_map(address_map &map);
183 	void seawolf2_map(address_map &map);
184 	void spacezap_map(address_map &map);
185 	void wow_map(address_map &map);
186 protected:
187 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
188 };
189 
190 class seawolf2_state : public astrocde_state
191 {
192 public:
seawolf2_state(const machine_config & mconfig,device_type type,const char * tag)193 	seawolf2_state(const machine_config &mconfig, device_type type, const char *tag) :
194 		astrocde_state(mconfig, type, tag),
195 		m_samples(*this, "samples")
196 	{ }
197 
198 	void seawolf2(machine_config &config);
199 private:
200 	void sound_1_w(uint8_t data);
201 	void sound_2_w(uint8_t data);
202 
203 	void port_map_discrete(address_map &map);
204 
205 	virtual void machine_start() override;
206 
207 	required_device<samples_device> m_samples;
208 	uint8_t m_port_1_last;
209 	uint8_t m_port_2_last;
210 };
211 
212 class ebases_state : public astrocde_state
213 {
214 public:
ebases_state(const machine_config & mconfig,device_type type,const char * tag)215 	ebases_state(const machine_config &mconfig, device_type type, const char *tag) :
216 		astrocde_state(mconfig, type, tag),
217 		m_trackball(*this, {"TRACKX2", "TRACKY2", "TRACKX1", "TRACKY1"})
218 	{ }
219 
220 	void ebases(machine_config &config);
221 	DECLARE_CUSTOM_INPUT_MEMBER(trackball_r);
222 private:
223 	void trackball_select_w(uint8_t data);
224 	void coin_w(uint8_t data);
225 
226 	void ebases_map(address_map &map);
227 	void port_map_ebases(address_map &map);
228 
229 	required_ioport_array<4> m_trackball;
230 };
231 
232 class demndrgn_state : public astrocde_state
233 {
234 public:
demndrgn_state(const machine_config & mconfig,device_type type,const char * tag)235 	demndrgn_state(const machine_config &mconfig, device_type type, const char *tag)
236 		: astrocde_state(mconfig, type, tag)
237 		, m_joystick(*this, {"MOVEX", "MOVEY"})
238 	{ }
239 
240 	void demndrgn(machine_config &config);
241 	DECLARE_CUSTOM_INPUT_MEMBER(joystick_r);
242 private:
243 	DECLARE_WRITE_LINE_MEMBER(input_select_w);
244 	void sound_w(uint8_t data);
245 
246 	void port_map_16col_pattern_demndrgn(address_map &map);
247 
248 	required_ioport_array<2> m_joystick;
249 };
250 
251 class tenpindx_state : public astrocde_state
252 {
253 public:
tenpindx_state(const machine_config & mconfig,device_type type,const char * tag)254 	tenpindx_state(const machine_config &mconfig, device_type type, const char *tag) :
255 		astrocde_state(mconfig, type, tag),
256 		m_subcpu(*this, "sub"),
257 		m_lamps(*this, "lamp%u", 0U)
258 	{ }
259 
260 	void tenpindx(machine_config &config);
261 private:
262 	void lamp_w(offs_t offset, uint8_t data);
263 	void counter_w(uint8_t data);
264 	void lights_w(uint8_t data);
265 
266 	virtual void machine_start() override;
267 
268 	void port_map_16col_pattern_tenpindx(address_map &map);
269 	void sub_io_map(address_map &map);
270 	void sub_map(address_map &map);
271 
272 	required_device<z80_device> m_subcpu;
273 	output_finder<19> m_lamps;
274 };
275 
276 #endif // MAME_INCLUDES_ASTROCDE_H
277