1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 
4 #include "machine/6821pia.h"
5 #include "machine/6840ptm.h"
6 #include "machine/nvram.h"
7 #include "machine/timer.h"
8 
9 #include "cpu/m6809/m6809.h"
10 #include "sound/ay8910.h"
11 #include "sound/okim6376.h"
12 #include "sound/ym2413.h"
13 #include "sound/upd7759.h"
14 #include "machine/steppers.h"
15 #include "machine/roc10937.h"
16 #include "machine/meters.h"
17 
18 #include "machine/bacta_datalogger.h"
19 
20 #include "emupal.h"
21 
22 
23 #define MPU4_MASTER_CLOCK           XTAL(6'880'000)
24 #define VIDEO_MASTER_CLOCK          XTAL(10'000'000)
25 
26 #ifdef MAME_DEBUG
27 #define MPU4VIDVERBOSE 1
28 #else
29 #define MPU4VIDVERBOSE 0
30 #endif
31 
32 #define LOGSTUFF(x) do { if (MPU4VIDVERBOSE) logerror x; } while (0)
33 
34 
35 
36 #ifdef MAME_DEBUG
37 #define MPU4VERBOSE 1
38 #else
39 #define MPU4VERBOSE 0
40 #endif
41 
42 #define LOG(x)  do { if (MPU4VERBOSE) logerror x; } while (0)
43 #define LOG_CHR(x)  do { if (MPU4VERBOSE) logerror x; } while (0)
44 #define LOG_CHR_FULL(x) do { if (MPU4VERBOSE) logerror x; } while (0)
45 #define LOG_IC3(x)  do { if (MPU4VERBOSE) logerror x; } while (0)
46 #define LOG_IC8(x)  do { if (MPU4VERBOSE) logerror x; } while (0)
47 #define LOG_SS(x)   do { if (MPU4VERBOSE) logerror x; } while (0)
48 
49 
50 
51 
52 
53 static const uint8_t reel_mux_table[8]= {0,4,2,6,1,5,3,7};//include 7, although I don't think it's used, this is basically a wire swap
54 static const uint8_t reel_mux_table7[8]= {3,1,5,6,4,2,0,7};
55 
56 static const uint8_t bwb_chr_table_common[10]= {0x00,0x04,0x04,0x0c,0x0c,0x1c,0x14,0x2c,0x5c,0x2c};
57 
58 //reel info
59 #define STANDARD_REEL  0    // As originally designed 3/4 reels
60 #define FIVE_REEL_5TO8 1    // Interfaces to meter port, allows some mechanical metering, but there is significant 'bounce' in the extra reel
61 #define FIVE_REEL_8TO5 2    // Mounted backwards for space reasons, but different board
62 #define FIVE_REEL_3TO6 3    // Connected to the centre of the meter connector, taking up meters 3 to 6
63 #define SIX_REEL_1TO8  4    // Two reels on the meter drives
64 #define SIX_REEL_5TO8  5    // Like FIVE_REEL_5TO8, but with an extra reel elsewhere
65 #define SEVEN_REEL     6    // Mainly club machines, significant reworking of reel hardware
66 #define FLUTTERBOX     7    // A fan feature using a reel mux-like setup, but not actually a reel
67 
68 //Lamp extension
69 #define NO_EXTENDER         0 // As originally designed
70 #define SMALL_CARD          1
71 #define LARGE_CARD_A        2 //96 Lamps
72 #define LARGE_CARD_B        3 //96 Lamps, 16 LEDs - as used by BwB
73 #define LARGE_CARD_C        4 //Identical to B, no built in LED support
74 
75 //LED cards
76 #define CARD_A          1
77 #define CARD_B          2
78 #define CARD_C          3
79 #define SIMPLE_CARD     4
80 
81 
82 //Hopper info
83 #define TUBES               0
84 #define HOPPER_DUART_A      1
85 #define HOPPER_DUART_B      2
86 #define HOPPER_DUART_C      3
87 #define HOPPER_NONDUART_A   4
88 #define HOPPER_NONDUART_B   5
89 
90 /* Lookup table for CHR data */
91 
92 struct mpu4_chr_table
93 {
94 	uint8_t call;
95 	uint8_t response;
96 };
97 
98 struct bwb_chr_table//dynamically populated table for BwB protection
99 {
100 	uint8_t response;
101 };
102 
103 
104 class mpu4_state : public driver_device
105 {
106 public:
mpu4_state(const machine_config & mconfig,device_type type,const char * tag)107 	mpu4_state(const machine_config &mconfig, device_type type, const char *tag)
108 		: driver_device(mconfig, type, tag)
109 		, m_maincpu(*this, "maincpu")
110 		, m_vfd(*this, "vfd")
111 		, m_6840ptm(*this, "ptm_ic2")
112 		, m_ptm_ic3ss(*this, "ptm_ic3ss")
113 		, m_pia3(*this, "pia_ic3")
114 		, m_pia4(*this, "pia_ic4")
115 		, m_pia5(*this, "pia_ic5")
116 		, m_pia6(*this, "pia_ic6")
117 		, m_pia7(*this, "pia_ic7")
118 		, m_pia8(*this, "pia_ic8")
119 		, m_pia_ic4ss(*this, "pia_ic4ss")
120 		, m_port_mux(*this, {"ORANGE1", "ORANGE2", "BLACK1", "BLACK2", "ORANGE1", "ORANGE2", "DIL1", "DIL2"})
121 		, m_aux1_port(*this, "AUX1")
122 		, m_aux2_port(*this, "AUX2")
123 		, m_bank1(*this, "bank1")
124 		, m_msm6376(*this, "msm6376")
125 		, m_reel(*this, "reel%u", 0U)
126 		, m_palette(*this, "palette")
127 		, m_meters(*this, "meters")
128 		, m_ym2413(*this, "ym2413")
129 		, m_ay8913(*this, "ay8913")
130 		, m_dataport(*this, "dataport")
131 		, m_lamps(*this, "lamp%u", 0U)
132 		, m_mpu4leds(*this, "mpu4led%u", 0U)
133 		, m_digits(*this, "digit%u", 0U)
134 		, m_triacs(*this, "triac%u", 0U)
135 	 { }
136 
137 	void init_m4default_alt();
138 	void init_crystali();
139 	void init_m4tst2();
140 	void init_crystal();
141 	void init_m_frkstn();
142 	void init_m4default_big();
143 	void init_m4default();
144 	void init_m4default_banks();
145 	void init_m4default_reels();
146 	void init_m4_low_volt_alt();
147 	void init_m4_aux1_invert();
148 	void init_m4_aux2_invert();
149 	void init_m4_door_invert();
150 	void init_m4_five_reel_std();
151 	void init_m4_five_reel_rev();
152 	void init_m4_five_reel_alt();
153 	void init_m4_six_reel_std();
154 	void init_m4_six_reel_alt();
155 	void init_m4_seven_reel();
156 	void init_m4_small_extender();
157 	void init_m4_large_extender_a();
158 	void init_m4_large_extender_b();
159 	void init_m4_large_extender_c();
160 	void init_m4_hopper_tubes();
161 	void init_m4_hopper_duart_a();
162 	void init_m4_hopper_duart_b();
163 	void init_m4_hopper_duart_c();
164 	void init_m4_hopper_nonduart_a();
165 	void init_m4_hopper_nonduart_b();
166 	void init_m4_led_a();
167 	void init_m4_led_b();
168 	void init_m4_led_c();
169 	void init_m4_led_simple();
170 	void init_m4_andycp10c();
171 	void init_m_blsbys();
172 	void init_m_oldtmr();
173 	void init_m4tst();
174 	void init_m_ccelbr();
175 	void init_m4gambal();
176 	void init_m4debug();
177 	void init_m4_showstring();
178 	void init_m4_showstring_mod4yam();
179 	void init_m4_debug_mod4yam();
180 	void init_m4_showstring_mod2();
181 	void init_m4_showstring_big();
182 	void init_connect4();
183 	void init_m4altreels();//legacy, will be removed once things are sorted out
184 	void init_m_grtecp();//legacy, will be removed once things are sorted out RE: CHR
185 	void init_m4tenten();
186 	void init_m4actbnk();
187 	void init_m4actclb();
188 	void init_m4actpak();
189 	void init_m4addr();
190 	void init_m4aao();
191 	void init_m4alladv();
192 	void init_m4alpha();
193 	void init_m4andycp();
194 	void init_m4andybt();
195 	void init_m4andyfh();
196 	void init_m4andyge();
197 	void init_m4apachg();
198 
199 	void bwboki(machine_config &config);
200 	void mod2(machine_config &config);
201 	void mod2_alt(machine_config &config);
202 	void mod4oki(machine_config &config);
203 	void mod4oki_5r(machine_config &config);
204 	void mod4oki_alt(machine_config &config);
205 	void mod4yam(machine_config &config);
206 	void mpu4_common(machine_config &config);
207 	void mpu4_common2(machine_config &config);
208 	void mpu4crys(machine_config &config);
209 	void mpu4_std_3reel(machine_config &config);
210 	void mpu4_type2_3reel(machine_config &config);
211 	void mpu4_type3_3reel(machine_config &config);
212 	void mpu4_type4_3reel(machine_config &config);
213 	void mpu4_bwb_3reel(machine_config &config);
214 	void mpu4_std_4reel(machine_config &config);
215 	void mpu4_type2_4reel(machine_config &config);
216 	void mpu4_type3_4reel(machine_config &config);
217 	void mpu4_type4_4reel(machine_config &config);
218 	void mpu4_bwb_4reel(machine_config &config);
219 	void mpu4_std_5reel(machine_config &config);
220 	void mpu4_type2_5reel(machine_config &config);
221 	void mpu4_type3_5reel(machine_config &config);
222 	void mpu4_type4_5reel(machine_config &config);
223 	void mpu4_bwb_5reel(machine_config &config);
224 	void mpu4_std_6reel(machine_config &config);
225 	void mpu4_type2_6reel(machine_config &config);
226 	void mpu4_type3_6reel(machine_config &config);
227 	void mpu4_type4_6reel(machine_config &config);
228 	void mpu4_bwb_6reel(machine_config &config);
229 	void mpu4_std_7reel(machine_config &config);
230 	void mpu4_type2_7reel(machine_config &config);
231 	void mpu4_type3_7reel(machine_config &config);
232 	void mpu4_type4_7reel(machine_config &config);
233 	void mpu4_bwb_7reel(machine_config &config);
234 	void mpu4base(machine_config &config);
235 
236 protected:
237 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
238 
239 	void mpu4_6809_map(address_map &map);
240 	void mpu4_memmap(address_map &map);
241 	void lamp_extend_small(int data);
242 	void lamp_extend_large(int data,int column,int active);
243 	void led_write_extender(int latch, int data, int column);
244 	void update_meters();
245 	void ic23_update();
246 	void ic24_output(int data);
247 	void ic24_setup();
248 	void update_ay(device_t *device);
249 	void mpu4_install_mod4yam_space(address_space &space);
250 	void mpu4_install_mod4oki_space(address_space &space);
251 	void mpu4_install_mod4bwb_space(address_space &space);
252 	void mpu4_config_common();
253 	DECLARE_MACHINE_START(mod2);
254 	DECLARE_MACHINE_RESET(mpu4);
255 	DECLARE_MACHINE_START(mpu4yam);
256 	DECLARE_MACHINE_START(mpu4oki);
257 	DECLARE_MACHINE_START(mpu4oki_alt);
258 	DECLARE_MACHINE_START(mod4oki_5r);
259 	DECLARE_MACHINE_START(mod2_alt);
260 	DECLARE_MACHINE_START(mpu4bwb);
261 	DECLARE_MACHINE_START(mpu4cry);
262 	TIMER_DEVICE_CALLBACK_MEMBER(gen_50hz);
DECLARE_WRITE_LINE_MEMBER(reel_optic_cb)263 	template <unsigned N> DECLARE_WRITE_LINE_MEMBER(reel_optic_cb) { if (state) m_optic_pattern |= (1 << N); else m_optic_pattern &= ~(1 << N); }
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)264 		uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
265 	{
266 		return 0;
267 	}
268 
269 	void bankswitch_w(uint8_t data);
270 	uint8_t bankswitch_r();
271 	void bankset_w(uint8_t data);
272 	void characteriser_w(offs_t offset, uint8_t data);
273 	uint8_t characteriser_r(address_space &space, offs_t offset);
274 	void bwb_characteriser_w(offs_t offset, uint8_t data);
275 	uint8_t bwb_characteriser_r(offs_t offset);
276 	void mpu4_ym2413_w(offs_t offset, uint8_t data);
277 	uint8_t mpu4_ym2413_r(offs_t offset);
278 	uint8_t crystal_sound_r();
279 	void crystal_sound_w(uint8_t data);
280 	void ic3ss_w(offs_t offset, uint8_t data);
281 	DECLARE_WRITE_LINE_MEMBER(cpu0_irq);
282 	DECLARE_WRITE_LINE_MEMBER(ic2_o1_callback);
283 	DECLARE_WRITE_LINE_MEMBER(ic2_o2_callback);
284 	DECLARE_WRITE_LINE_MEMBER(ic2_o3_callback);
285 	void pia_ic3_porta_w(uint8_t data);
286 	void pia_ic3_portb_w(uint8_t data);
287 	DECLARE_WRITE_LINE_MEMBER(pia_ic3_ca2_w);
288 	DECLARE_WRITE_LINE_MEMBER(pia_ic3_cb2_w);
289 	void pia_ic4_porta_w(uint8_t data);
290 	void pia_ic4_portb_w(uint8_t data);
291 	uint8_t pia_ic4_portb_r();
292 	DECLARE_WRITE_LINE_MEMBER(pia_ic4_ca2_w);
293 	DECLARE_WRITE_LINE_MEMBER(pia_ic4_cb2_w);
294 	uint8_t pia_ic5_porta_r();
295 	void pia_ic5_porta_w(uint8_t data);
296 	void pia_ic5_portb_w(uint8_t data);
297 	uint8_t pia_ic5_portb_r();
298 	DECLARE_WRITE_LINE_MEMBER(pia_ic5_ca2_w);
299 	DECLARE_WRITE_LINE_MEMBER(pia_ic5_cb2_w);
300 	void pia_ic6_portb_w(uint8_t data);
301 	void pia_ic6_porta_w(uint8_t data);
302 	DECLARE_WRITE_LINE_MEMBER(pia_ic6_ca2_w);
303 	DECLARE_WRITE_LINE_MEMBER(pia_ic6_cb2_w);
304 	void pia_ic7_porta_w(uint8_t data);
305 	void pia_ic7_portb_w(uint8_t data);
306 	uint8_t pia_ic7_portb_r();
307 	DECLARE_WRITE_LINE_MEMBER(pia_ic7_ca2_w);
308 	DECLARE_WRITE_LINE_MEMBER(pia_ic7_cb2_w);
309 	uint8_t pia_ic8_porta_r();
310 	void pia_ic8_portb_w(uint8_t data);
311 	DECLARE_WRITE_LINE_MEMBER(pia_ic8_ca2_w);
312 	DECLARE_WRITE_LINE_MEMBER(pia_ic8_cb2_w);
313 	void pia_gb_porta_w(uint8_t data);
314 	void pia_gb_portb_w(uint8_t data);
315 	uint8_t pia_gb_portb_r();
316 	DECLARE_WRITE_LINE_MEMBER(pia_gb_ca2_w);
317 	DECLARE_WRITE_LINE_MEMBER(pia_gb_cb2_w);
318 
319 	DECLARE_WRITE_LINE_MEMBER(dataport_rxd);
320 
321 	required_device<cpu_device> m_maincpu;
322 	optional_device<rocvfd_device> m_vfd;
323 	optional_device<ptm6840_device> m_6840ptm;
324 	optional_device<ptm6840_device> m_ptm_ic3ss;
325 	optional_device<pia6821_device> m_pia3;
326 	optional_device<pia6821_device> m_pia4;
327 	optional_device<pia6821_device> m_pia5;
328 	optional_device<pia6821_device> m_pia6;
329 	optional_device<pia6821_device> m_pia7;
330 	optional_device<pia6821_device> m_pia8;
331 	optional_device<pia6821_device> m_pia_ic4ss;
332 	required_ioport_array<8> m_port_mux;
333 	required_ioport m_aux1_port;
334 	required_ioport m_aux2_port;
335 	optional_memory_bank m_bank1;
336 	optional_device<okim6376_device> m_msm6376;
337 	optional_device_array<stepper_device, 8> m_reel;
338 	optional_device<palette_device> m_palette;
339 	required_device<meters_device> m_meters;
340 	optional_device<ym2413_device> m_ym2413;
341 	optional_device<ay8913_device> m_ay8913;
342 	optional_device<bacta_datalogger_device> m_dataport;
343 
344 	// not all systems have this many lamps/LEDs/digits but the driver is too much of a mess to split up now
345 
346 	// 0-63 are on PIA IC3 port A (always present)
347 	// 64-127 are on PIA IC3 port B (always present)
348 	// 128-132 136-140 144-148 152-156 160-164 168-172 176-180 184-188 are on small lamp extender
349 	// 128-255 are on large lamp externders
350 	output_finder<256> m_lamps;
351 
352 	// 0-63 are on PIA IC4 port A (always present)
353 	// 0-143 are on card B (possibly incorrectly mapped?)
354 	// 64-127 are on card C
355 	// 0-127 are on large card B
356 	output_finder<144> m_mpu4leds;
357 
358 	// 0-7 are on PIA IC4 port A with no LED extender
359 	// 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136 are on card B (possible incorrectly mapped?)
360 	// 8-15 are on card C
361 	// 8-9 are mapped to lamp lines for Connect 4
362 	// 0-15 are on large card B
363 	output_finder<144> m_digits;
364 
365 	output_finder<8> m_triacs;
366 
367 	enum
368 	{
369 		TIMER_IC24
370 	};
371 
372 	int m_mod_number;
373 	int m_mmtr_data;
374 	int m_ay8913_address;
375 	int m_serial_data;
376 	int m_signal_50hz;
377 	int m_ic4_input_b;
378 	int m_aux1_input;
379 	int m_aux2_input;
380 	int m_IC23G1;
381 	int m_IC23G2A;
382 	int m_IC23G2B;
383 	int m_IC23GC;
384 	int m_IC23GB;
385 	int m_IC23GA;
386 	int m_prot_col;
387 	int m_lamp_col;
388 	int m_init_col;
389 	int m_reel_flag;
390 	int m_ic23_active;
391 	int m_led_lamp;
392 	int m_link7a_connected;
393 	int m_low_volt_detect_disable;
394 	int m_aux1_invert;
395 	int m_aux2_invert;
396 	int m_door_invert;
397 	emu_timer *m_ic24_timer;
398 	int m_expansion_latch;
399 	int m_global_volume;
400 	int m_input_strobe;
401 	uint8_t m_lamp_strobe;
402 	uint8_t m_lamp_strobe2;
403 	uint8_t m_lamp_strobe_ext;
404 	uint8_t m_lamp_strobe_ext_persistence;
405 	uint8_t m_led_strobe;
406 	uint8_t m_ay_data;
407 	int m_optic_pattern;
408 
409 	int m_active_reel;
410 	int m_remote_meter;
411 	int m_reel_mux;
412 	int m_lamp_extender;
413 	int m_last_b7;
414 	int m_last_latch;
415 	int m_lamp_sense;
416 	int m_card_live;
417 	int m_led_extender;
418 	int m_bwb_bank;
419 	int m_chr_state;
420 	int m_chr_counter;
421 	int m_chr_value;
422 	int m_bwb_return;
423 	int m_pageval;
424 	int m_pageset;
425 	int m_hopper;
426 	int m_reels;
427 	int m_chrdata;
428 	int m_t1;
429 	int m_t3l;
430 	int m_t3h;
431 	uint8_t m_numbanks;
432 	mpu4_chr_table* m_current_chr_table;
433 	const bwb_chr_table* m_bwb_chr_table1;
434 };
435 
436 INPUT_PORTS_EXTERN( mpu4 );
437