1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 #ifndef MAME_INCLUDES_XAVIX_H
4 #define MAME_INCLUDES_XAVIX_H
5 
6 #include "cpu/m6502/xavix.h"
7 #include "cpu/m6502/xavix2000.h"
8 #include "machine/timer.h"
9 #include "emupal.h"
10 #include "screen.h"
11 #include "speaker.h"
12 #include "machine/bankdev.h"
13 #include "machine/i2cmem.h"
14 #include "bus/generic/slot.h"
15 #include "bus/generic/carts.h"
16 #include "bus/ekara/slot.h"
17 #include "machine/nvram.h"
18 
19 #include "machine/xavix_mtrk_wheel.h"
20 #include "machine/xavix_madfb_ball.h"
21 #include "machine/xavix2002_io.h"
22 #include "machine/xavix_io.h"
23 #include "machine/xavix_adc.h"
24 #include "machine/xavix_anport.h"
25 #include "machine/xavix_math.h"
26 
27 // NTSC clock for regular XaviX?
28 #define MAIN_CLOCK XTAL(21'477'272)
29 // some games (eg Radica Opus) run off a 3.579545MHz XTAL ( same as the above /6 ) so presumably there is a divider / multiplier circuit on some PCBs?
30 // TODO: what's the PAL clock?
31 
32 
33 class xavix_sound_device : public device_t, public device_sound_interface
34 {
35 public:
36 	xavix_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
37 
read_regs_callback()38 	auto read_regs_callback() { return m_readregs_cb.bind(); }
read_samples_callback()39 	auto read_samples_callback() { return m_readsamples_cb.bind(); }
40 
41 	void enable_voice(int voice, bool update_only);
42 	void disable_voice(int voice);
43 	bool is_voice_enabled(int voice);
44 
45 protected:
46 	// device-level overrides
47 	virtual void device_start() override;
48 	virtual void device_reset() override;
49 
50 	// sound stream update overrides
51 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
52 
53 private:
54 	sound_stream *m_stream;
55 
56 	struct xavix_voice {
57 		bool enabled[2];
58 		uint32_t position[2];
59 		uint32_t startposition[2];
60 		uint8_t bank; // no samples appear to cross a bank boundary, so likely wraps
61 		int type;
62 		int rate;
63 		int vol;
64 	};
65 
66 	devcb_read8 m_readregs_cb;
67 
68 	devcb_read8 m_readsamples_cb;
69 
70 	xavix_voice m_voice[16];
71 };
72 
DECLARE_DEVICE_TYPE(XAVIX_SOUND,xavix_sound_device)73 DECLARE_DEVICE_TYPE(XAVIX_SOUND, xavix_sound_device)
74 
75 
76 class xavix_state : public driver_device
77 {
78 public:
79 	xavix_state(const machine_config &mconfig, device_type type, const char *tag)
80 		: driver_device(mconfig, type, tag),
81 		m_in0(*this, "IN0"),
82 		m_in1(*this, "IN1"),
83 		m_an_in(*this, "AN%u", 0U),
84 		m_mouse0x(*this, "MOUSE0X"),
85 		m_mouse0y(*this, "MOUSE0Y"),
86 		m_mouse1x(*this, "MOUSE1X"),
87 		m_mouse1y(*this, "MOUSE1Y"),
88 		m_maincpu(*this, "maincpu"),
89 		m_nvram(*this, "nvram"),
90 		m_screen(*this, "screen"),
91 		m_lowbus(*this, "lowbus"),
92 		m_sprite_xhigh_ignore_hack(true),
93 		m_mainram(*this, "mainram"),
94 		m_fragment_sprite(*this, "fragment_sprite"),
95 		m_rom_dma_src(*this,"rom_dma_src"),
96 		m_rom_dma_dst(*this,"rom_dma_dst"),
97 		m_rom_dma_len(*this,"rom_dma_len"),
98 		m_palram_sh(*this, "palram_sh"),
99 		m_palram_l(*this, "palram_l"),
100 		m_bmp_palram_sh(*this, "bmp_palram_sh"),
101 		m_bmp_palram_l(*this, "bmp_palram_l"),
102 		m_bmp_base(*this, "bmp_base"),
103 		m_colmix_sh(*this, "colmix_sh"),
104 		m_colmix_l(*this, "colmix_l"),
105 		m_colmix_ctrl(*this, "colmix_ctrl"),
106 		m_posirq_x(*this, "posirq_x"),
107 		m_posirq_y(*this, "posirq_y"),
108 		m_segment_regs(*this, "segment_regs"),
109 		m_palette(*this, "palette"),
110 		m_region(*this, "REGION"),
111 		m_gfxdecode(*this, "gfxdecode"),
112 		m_sound(*this, "xavix_sound"),
113 		m_adc(*this, "adc"),
114 		m_anport(*this, "anport"),
115 		m_math(*this, "math"),
116 		m_xavix2002io(*this, "xavix2002io")
117 	{ }
118 
119 	void xavix(machine_config &config);
120 	void xavix_nv(machine_config &config);
121 
122 	void xavixp(machine_config &config);
123 	void xavixp_nv(machine_config &config);
124 
125 	void xavix2000(machine_config &config);
126 	void xavix2000_nv(machine_config &config);
127 
128 	void xavix2002(machine_config &config);
129 
130 	void init_xavix();
131 
132 	DECLARE_WRITE_LINE_MEMBER(ioevent_trg01);
133 	DECLARE_WRITE_LINE_MEMBER(ioevent_trg02);
134 	DECLARE_WRITE_LINE_MEMBER(ioevent_trg04);
135 	DECLARE_WRITE_LINE_MEMBER(ioevent_trg08);
136 
137 	int m_rgnlen;
138 	uint8_t* m_rgn;
139 
140 	/* this is just a quick memory system bypass for video reads etc. because going through the
141 	   memory system is slow and also pollutes logs significantly with unmapped reads if the games
142 	   enable the video before actually setting up the source registers!
143 
144 	   this will need modifying if any games have RAM instead of ROM (which I think is possible
145 	   with SuperXaviX at least)
146 	*/
147 	inline uint8_t read_full_data_sp_lowbus_bypass(uint16_t adr)
148 	{
149 		adr &= 0x7fff;
150 
151 		if (adr < 0x4000)
152 		{
153 			adr &= 0x3fff;
154 			return m_mainram[adr];
155 		}
156 		else if (adr < 0x5000)
157 		{
158 			adr &= 0xfff;
159 			return txarray_r(adr);
160 		}
161 		else if ((adr >= 0x6000) && (adr < 0x6800))
162 		{
163 			adr &= 0x7ff;
164 			return m_fragment_sprite[adr];
165 		}
166 		else if ((adr >= 0x6800) && (adr < 0x6900))
167 		{
168 			adr &= 0xff;
169 			return m_palram_sh[adr];
170 		}
171 		else if ((adr >= 0x6900) && (adr < 0x6a00))
172 		{
173 			adr &= 0xff;
174 			return m_palram_l[adr];
175 		}
176 		else if ((adr >= 0x6a00) && (adr < 0x6a20))
177 		{
178 			adr &= 0x1f;
179 			return m_segment_regs[adr];
180 		}
181 		// superxavix bitmap palette?
182 
183 		return 0x00;
184 	}
185 
186 protected:
187 
188 	virtual uint8_t read_io0(uint8_t direction);
189 	virtual uint8_t read_io1(uint8_t direction);
190 	virtual void write_io0(uint8_t data, uint8_t direction);
191 	virtual void write_io1(uint8_t data, uint8_t direction);
192 	required_ioport m_in0;
193 	required_ioport m_in1;
194 	required_ioport_array<8> m_an_in;
195 	optional_ioport m_mouse0x;
196 	optional_ioport m_mouse0y;
197 	optional_ioport m_mouse1x;
198 	optional_ioport m_mouse1y;
199 	required_device<xavix_device> m_maincpu;
200 	optional_device<nvram_device> m_nvram;
201 	required_device<screen_device> m_screen;
202 	required_device<address_map_bank_device> m_lowbus;
203 	address_space* m_cpuspace;
204 
205 private:
206 
207 	// screen updates
208 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
209 
210 	void xavix_map(address_map &map);
211 
212 	void xavix_lowbus_map(address_map &map);
213 	void xavix_extbus_map(address_map &map);
214 	void superxavix_lowbus_map(address_map &map);
215 
216 	INTERRUPT_GEN_MEMBER(interrupt);
217 	TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
218 
219 	// driver_device overrides
220 	virtual void machine_start() override;
221 	virtual void machine_reset() override;
222 
223 	virtual void video_start() override;
224 
225 	void debug_mem_w(offs_t offset, uint8_t data)
226 	{
227 		m_mainram[offset] = data;
228 	};
229 
230 	virtual uint8_t opcodes_000000_r(offs_t offset)
231 	{
232 		if (offset & 0x8000)
233 		{
234 			return m_rgn[(offset) & (m_rgnlen - 1)];
235 		}
236 		else
237 		{
238 			return m_lowbus->read8(offset & 0x7fff);
239 		}
240 	}
241 
242 	virtual uint8_t opcodes_800000_r(offs_t offset)
243 	{
244 		// rad_fb, rad_madf confirm that for >0x800000 the CPU only sees ROM when executing opcodes
245 		return m_rgn[(offset) & (m_rgnlen - 1)];
246 	}
247 
248 	virtual uint8_t extbus_r(offs_t offset) { return m_rgn[(offset) & (m_rgnlen - 1)]; }
249 	virtual void extbus_w(offs_t offset, uint8_t data)
250 	{
251 		logerror("%s: write to external bus %06x %02x\n", machine().describe_context(), offset, data);
252 	}
253 
254 
255 	uint8_t sample_read(offs_t offset)
256 	{
257 		return read_full_data_sp_bypass(offset);
258 	};
259 
260 	virtual inline uint8_t read_full_data_sp_bypass(uint32_t adr)
261 	{
262 		uint8_t databank = adr >> 16;
263 
264 		if (databank >= 0x80)
265 		{
266 			return m_rgn[adr & (m_rgnlen - 1)];
267 		}
268 		else
269 		{
270 			if ((adr&0xffff) >= 0x8000)
271 			{
272 				return m_rgn[adr & (m_rgnlen - 1)];
273 			}
274 			else
275 			{
276 				return read_full_data_sp_lowbus_bypass(adr);
277 			}
278 		}
279 	}
280 
281 
282 	uint8_t ioevent_enable_r();
283 	void ioevent_enable_w(uint8_t data);
284 	uint8_t ioevent_irqstate_r();
285 	void ioevent_irqack_w(uint8_t data);
286 	uint8_t m_ioevent_enable;
287 	uint8_t m_ioevent_active;
288 	void process_ioevent(uint8_t bits);
289 
290 	void slotreg_7810_w(uint8_t data);
291 
292 	void rom_dmatrg_w(uint8_t data);
293 
294 	void rom_dmasrc_w(offs_t offset, uint8_t data);
295 
296 	void rom_dmadst_w(offs_t offset, uint8_t data);
297 	void rom_dmalen_w(offs_t offset, uint8_t data);
298 	uint8_t rom_dmastat_r();
299 
300 	void spritefragment_dma_params_1_w(offs_t offset, uint8_t data);
301 	void spritefragment_dma_params_2_w(offs_t offset, uint8_t data);
302 	void spritefragment_dma_trg_w(uint8_t data);
303 	uint8_t spritefragment_dma_status_r();
304 
305 	uint8_t io0_data_r();
306 	uint8_t io1_data_r();
307 	void io0_data_w(uint8_t data);
308 	void io1_data_w(uint8_t data);
309 
310 	uint8_t io0_direction_r();
311 	uint8_t io1_direction_r();
312 	void io0_direction_w(uint8_t data);
313 	void io1_direction_w(uint8_t data);
314 
315 	uint8_t m_io0_data;
316 	uint8_t m_io1_data;
317 	uint8_t m_io0_direction;
318 	uint8_t m_io1_direction;
319 
320 	uint8_t nmi_vector_lo_r();
321 	uint8_t nmi_vector_hi_r();
322 	uint8_t irq_vector_lo_r();
323 	uint8_t irq_vector_hi_r();
324 
325 	void vector_enable_w(uint8_t data);
326 	void nmi_vector_lo_w(uint8_t data);
327 	void nmi_vector_hi_w(uint8_t data);
328 	void irq_vector_lo_w(uint8_t data);
329 	void irq_vector_hi_w(uint8_t data);
330 
331 	uint8_t irq_source_r();
332 	void irq_source_w(uint8_t data);
333 
334 	uint8_t arena_start_r();
335 	void arena_start_w(uint8_t data);
336 	uint8_t arena_end_r();
337 	void arena_end_w(uint8_t data);
338 	uint8_t arena_control_r();
339 	void arena_control_w(uint8_t data);
340 
341 	uint8_t colmix_6ff0_r();
342 	void colmix_6ff0_w(uint8_t data);
343 
344 	void colmix_6ff1_w(uint8_t data);
345 	void colmix_6ff2_w(uint8_t data);
346 
347 	uint8_t dispctrl_6ff8_r();
348 	void dispctrl_6ff8_w(uint8_t data);
349 
350 	uint8_t sound_startstop_r(offs_t offset);
351 	void sound_startstop_w(offs_t offset, uint8_t data);
352 	uint8_t sound_updateenv_r(offs_t offset);
353 	void sound_updateenv_w(offs_t offset, uint8_t data);
354 
355 	uint8_t sound_sta16_r(offs_t offset);
356 	uint8_t sound_75f5_r();
357 	uint8_t sound_volume_r();
358 	void sound_volume_w(uint8_t data);
359 
360 	void sound_regbase_w(uint8_t data);
361 
362 	uint8_t sound_75f8_r();
363 	void sound_75f8_w(uint8_t data);
364 
365 	uint8_t sound_75f9_r();
366 	void sound_75f9_w(uint8_t data);
367 
368 	uint8_t sound_timer0_r();
369 	void sound_timer0_w(uint8_t data);
370 	uint8_t sound_timer1_r();
371 	void sound_timer1_w(uint8_t data);
372 	uint8_t sound_timer2_r();
373 	void sound_timer2_w(uint8_t data);
374 	uint8_t sound_timer3_r();
375 	void sound_timer3_w(uint8_t data);
376 
377 	uint8_t sound_irqstatus_r();
378 	void sound_irqstatus_w(uint8_t data);
379 	void sound_75ff_w(uint8_t data);
380 	uint8_t m_sound_irqstatus;
381 	uint8_t m_soundreg16_0[2];
382 	uint8_t m_soundreg16_1[2];
383 	uint8_t m_sound_regbase;
384 
385 	TIMER_CALLBACK_MEMBER(sound_timer_done);
386 	emu_timer *m_sound_timer[4];
387 
388 
389 	uint8_t timer_status_r();
390 	void timer_control_w(uint8_t data);
391 	uint8_t timer_baseval_r();
392 	void timer_baseval_w(uint8_t data);
393 	uint8_t timer_freq_r();
394 	void timer_freq_w(uint8_t data);
395 	uint8_t timer_curval_r();
396 	uint8_t m_timer_control;
397 	uint8_t m_timer_freq;
398 	TIMER_CALLBACK_MEMBER(freq_timer_done);
399 	emu_timer *m_freq_timer;
400 
401 	void palram_sh_w(offs_t offset, uint8_t data);
402 	void palram_l_w(offs_t offset, uint8_t data);
403 	void colmix_sh_w(offs_t offset, uint8_t data);
404 	void colmix_l_w(offs_t offset, uint8_t data);
405 	void bmp_palram_sh_w(offs_t offset, uint8_t data);
406 	void bmp_palram_l_w(offs_t offset, uint8_t data);
407 	void spriteram_w(offs_t offset, uint8_t data);
408 	bool m_sprite_xhigh_ignore_hack;
409 
410 	void tmap1_regs_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
411 	void tmap2_regs_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
412 	uint8_t tmap1_regs_r(offs_t offset);
413 	uint8_t tmap2_regs_r(offs_t offset);
414 
415 	void spriteregs_w(uint8_t data);
416 
417 	uint8_t pal_ntsc_r();
418 
419 	uint8_t xavix_memoryemu_txarray_r(offs_t offset);
420 	void xavix_memoryemu_txarray_w(offs_t offset, uint8_t data);
421 	uint8_t m_txarray[3];
422 
423 	inline uint8_t txarray_r(uint16_t offset)
424 	{
425 		if (offset < 0x100)
426 		{
427 			offset &= 0xff;
428 			return ((offset >> 4) | (offset << 4));
429 		}
430 		else if (offset < 0x200)
431 		{
432 			offset &= 0xff;
433 			return ((offset >> 4) | (~offset << 4));
434 		}
435 		else if (offset < 0x300)
436 		{
437 			offset &= 0xff;
438 			return ((~offset >> 4) | (offset << 4));
439 		}
440 		else if (offset < 0x400)
441 		{
442 			offset &= 0xff;
443 			return ((~offset >> 4) | (~offset << 4));
444 		}
445 		else if (offset < 0x800)
446 		{
447 			return m_txarray[0];
448 		}
449 		else if (offset < 0xc00)
450 		{
451 			return m_txarray[1];
452 		}
453 		else if (offset < 0x1000)
454 		{
455 			return m_txarray[2];
456 		}
457 
458 		return 0xff;
459 	}
460 
461 
462 	uint8_t adc0_r() { return m_an_in[0]->read(); };
463 	uint8_t adc1_r() { return m_an_in[1]->read(); };
464 	uint8_t adc2_r() { return m_an_in[2]->read(); };
465 	uint8_t adc3_r() { return m_an_in[3]->read(); };
466 	uint8_t adc4_r() { return m_an_in[4]->read(); };
467 	uint8_t adc5_r() { return m_an_in[5]->read(); };
468 	uint8_t adc6_r() { return m_an_in[6]->read(); };
469 	uint8_t adc7_r() { return m_an_in[7]->read(); };
470 
471 	uint8_t anport0_r() { logerror("%s: unhandled anport0_r\n", machine().describe_context()); return 0xff; };
472 	uint8_t anport1_r() { logerror("%s: unhandled anport1_r\n", machine().describe_context()); return 0xff; };
473 	uint8_t anport2_r() { logerror("%s: unhandled anport2_r\n", machine().describe_context()); return 0xff; };
474 	uint8_t anport3_r() { logerror("%s: unhandled anport3_r\n", machine().describe_context()); return 0xff; };
475 
476 	void update_irqs();
477 	uint8_t m_irqsource;
478 
479 	uint8_t m_vectorenable;
480 	uint8_t m_nmi_vector_lo_data;
481 	uint8_t m_nmi_vector_hi_data;
482 	uint8_t m_irq_vector_lo_data;
483 	uint8_t m_irq_vector_hi_data;
484 
485 	uint8_t m_spritefragment_dmaparam1[2];
486 	uint8_t m_spritefragment_dmaparam2[2];
487 
488 	uint8_t m_tmap1_regs[8];
489 	uint8_t m_tmap2_regs[8];
490 
491 	int m_arena_start;
492 	int m_arena_end;
493 	uint8_t m_arena_control;
494 
495 	uint8_t m_6ff0;
496 	uint8_t m_video_ctrl;
497 
498 	uint8_t m_mastervol;
499 	uint8_t m_unk_snd75f8;
500 	uint8_t m_unk_snd75f9;
501 	uint8_t m_unk_snd75ff;
502 	uint8_t m_sndtimer[4];
503 
504 	uint8_t m_timer_baseval;
505 
506 	int16_t get_vectors(int which, int half);
507 
508 	// raster IRQ
509 	TIMER_CALLBACK_MEMBER(interrupt_gen);
510 	emu_timer *m_interrupt_timer;
511 	void dispctrl_posirq_x_w(uint8_t data);
512 	void dispctrl_posirq_y_w(uint8_t data);
513 
514 	required_shared_ptr<uint8_t> m_mainram;
515 	required_shared_ptr<uint8_t> m_fragment_sprite;
516 	required_shared_ptr<uint8_t> m_rom_dma_src;
517 	required_shared_ptr<uint8_t> m_rom_dma_dst;
518 	required_shared_ptr<uint8_t> m_rom_dma_len;
519 
520 	required_shared_ptr<uint8_t> m_palram_sh;
521 	required_shared_ptr<uint8_t> m_palram_l;
522 
523 	optional_shared_ptr<uint8_t> m_bmp_palram_sh;
524 	optional_shared_ptr<uint8_t> m_bmp_palram_l;
525 	optional_shared_ptr<uint8_t> m_bmp_base;
526 
527 	required_shared_ptr<uint8_t> m_colmix_sh;
528 	required_shared_ptr<uint8_t> m_colmix_l;
529 	required_shared_ptr<uint8_t> m_colmix_ctrl;
530 
531 	required_shared_ptr<uint8_t> m_posirq_x;
532 	required_shared_ptr<uint8_t> m_posirq_y;
533 
534 	required_shared_ptr<uint8_t> m_segment_regs;
535 
536 	required_device<palette_device> m_palette;
537 
538 	required_ioport m_region;
539 
540 	required_device<gfxdecode_device> m_gfxdecode;
541 
542 	void update_pen(int pen, uint8_t shval, uint8_t lval);
543 	void draw_tile_line(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int tile, int bpp, int xpos, int ypos, int drawheight, int drawwidth, int flipx, int flipy, int pal, int zval, int line);
544 	void draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int which);
545 	void draw_tilemap_line(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int which, int line);
546 	void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
547 	void draw_sprites_line(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int line);
548 	void decode_inline_header(int &flipx, int &flipy, int &test, int& pal, int debug_packets);
549 
550 	bitmap_ind16 m_zbuffer;
551 
552 	uint8_t m_spritereg;
553 
554 	// variables used by rendering
555 	int m_tmp_dataaddress;
556 	int m_tmp_databit;
557 	uint8_t m_bit;
558 
559 	void set_data_address(int address, int bit);
560 	uint8_t get_next_bit();
561 	uint8_t get_next_byte();
562 
563 	int get_current_address_byte();
564 
565 	required_device<xavix_sound_device> m_sound;
566 
567 
568 	uint8_t sound_regram_read_cb(offs_t offset);
569 
570 protected:
571 	required_device<xavix_adc_device> m_adc;
572 	required_device<xavix_anport_device> m_anport;
573 	required_device<xavix_math_device> m_math;
574 	optional_device<xavix2002_io_device> m_xavix2002io;
575 
576 	uint8_t m_extbusctrl[3];
577 
578 	virtual uint8_t extintrf_790x_r(offs_t offset);
579 	virtual void extintrf_790x_w(offs_t offset, uint8_t data);
580 
581 	// additional SuperXaviX / XaviX2002 stuff
582 	uint8_t m_sx_extended_extbus[3];
583 
584 	void extended_extbus_reg0_w(uint8_t data);
585 	void extended_extbus_reg1_w(uint8_t data);
586 	void extended_extbus_reg2_w(uint8_t data);
587 };
588 
589 class xavix_guru_state : public xavix_state
590 {
591 public:
xavix_guru_state(const machine_config & mconfig,device_type type,const char * tag)592 	xavix_guru_state(const machine_config &mconfig, device_type type, const char *tag)
593 		: xavix_state(mconfig, type, tag)
594 	{ }
595 
596 	void xavix_guru(machine_config &config);
597 
598 protected:
599 
600 private:
guru_anport2_r()601 	uint8_t guru_anport2_r() { uint8_t ret = m_mouse1x->read()-0x10; return ret; }
602 };
603 
604 
605 class xavix_i2c_state : public xavix_state
606 {
607 public:
xavix_i2c_state(const machine_config & mconfig,device_type type,const char * tag)608 	xavix_i2c_state(const machine_config &mconfig, device_type type, const char *tag)
609 		: xavix_state(mconfig, type, tag),
610 		m_i2cmem(*this, "i2cmem"),
611 		hackaddress1(-1),
612 		hackaddress2(-1)
613 	{ }
614 
615 	void xavix_i2c_24lc04(machine_config &config);
616 	void xavix_i2c_24c02(machine_config &config);
617 	void xavix_i2c_24c08(machine_config &config);
618 
619 	void xavix2000_i2c_24c04(machine_config &config);
620 	void xavix2000_i2c_24c02(machine_config &config);
621 
622 	void xavix2002_i2c_24c04(machine_config &config);
623 	void xavix2002_i2c_mrangbat(machine_config& config);
624 
init_epo_efdx()625 	void init_epo_efdx()
626 	{
627 		init_xavix();
628 		hackaddress1 = 0x958a;
629 		hackaddress2 = 0x8524;
630 	}
631 
632 protected:
633 	virtual void write_io1(uint8_t data, uint8_t direction) override;
634 
635 	required_device<i2cmem_device> m_i2cmem;
636 
637 private:
638 	int hackaddress1;
639 	int hackaddress2;
640 };
641 
642 class xavix_i2c_ltv_tam_state : public xavix_i2c_state
643 {
644 public:
xavix_i2c_ltv_tam_state(const machine_config & mconfig,device_type type,const char * tag)645 	xavix_i2c_ltv_tam_state(const machine_config &mconfig, device_type type, const char *tag)
646 		: xavix_i2c_state(mconfig, type, tag)
647 	{ }
648 
649 	void xavix_i2c_24lc04_tam(machine_config &config);
650 
651 private:
652 	virtual void write_io1(uint8_t data, uint8_t direction) override;
653 
654 private:
tam_anport0_r()655 	uint8_t tam_anport0_r() { return m_mouse0x->read()^0x7f; }
tam_anport1_r()656 	uint8_t tam_anport1_r() { return m_mouse0y->read()^0x7f; }
tam_anport2_r()657 	uint8_t tam_anport2_r() { return m_mouse1x->read()^0x7f; }
tam_anport3_r()658 	uint8_t tam_anport3_r() { return m_mouse1y->read()^0x7f; }
659 };
660 
661 
662 
663 class xavix_i2c_lotr_state : public xavix_i2c_state
664 {
665 public:
xavix_i2c_lotr_state(const machine_config & mconfig,device_type type,const char * tag)666 	xavix_i2c_lotr_state(const machine_config &mconfig, device_type type, const char *tag)
667 		: xavix_i2c_state(mconfig, type, tag)
668 	{ }
669 
670 	DECLARE_READ_LINE_MEMBER(camera_r);
671 
672 protected:
673 	//virtual void write_io1(uint8_t data, uint8_t direction) override;
674 };
675 
676 
677 
678 
679 class xavix_mtrk_state : public xavix_state
680 {
681 public:
xavix_mtrk_state(const machine_config & mconfig,device_type type,const char * tag)682 	xavix_mtrk_state(const machine_config &mconfig, device_type type, const char *tag)
683 		: xavix_state(mconfig, type, tag),
684 		m_wheel(*this, "wheel")
685 	{ }
686 
687 	void xavix_mtrk(machine_config &config);
688 	void xavix_mtrkp(machine_config &config);
689 
690 	DECLARE_READ_LINE_MEMBER( mtrk_wheel_r );
691 
692 protected:
693 	required_device<xavix_mtrk_wheel_device> m_wheel;
694 };
695 
696 class xavix_madfb_state : public xavix_state
697 {
698 public:
xavix_madfb_state(const machine_config & mconfig,device_type type,const char * tag)699 	xavix_madfb_state(const machine_config &mconfig, device_type type, const char *tag)
700 		: xavix_state(mconfig, type, tag),
701 		m_ball(*this, "ball")
702 	{ }
703 
704 	void xavix_madfb(machine_config &config);
705 
706 protected:
707 	required_device<xavix_madfb_ball_device> m_ball;
708 };
709 
710 
711 class xavix_cart_state : public xavix_state
712 {
713 public:
xavix_cart_state(const machine_config & mconfig,device_type type,const char * tag)714 	xavix_cart_state(const machine_config &mconfig, device_type type, const char *tag) :
715 		xavix_state(mconfig, type, tag),
716 		m_cartslot(*this, "cartslot")
717 	{
718 		m_cartlimit = 0x400000;
719 	}
720 
721 	void xavix_cart(machine_config &config);
722 	void xavix_cart_ekara(machine_config &config);
723 	void xavix_cart_popira(machine_config &config);
724 	void xavix_cart_ddrfammt(machine_config &config);
725 	void xavix_cart_evio(machine_config &config);
726 
727 protected:
728 
729 	// for Cart cases this memory bypass becomes more complex
730 
opcodes_000000_r(offs_t offset)731 	virtual uint8_t opcodes_000000_r(offs_t offset) override
732 	{
733 		if (offset & 0x8000)
734 		{
735 			if ((offset & 0x7fffff) >= m_cartlimit)
736 			{
737 				return m_rgn[(offset) & (m_rgnlen - 1)];
738 			}
739 			else
740 			{
741 				if (m_cartslot->has_cart())
742 				{
743 					return m_cartslot->read_cart(offset);
744 				}
745 				else
746 				{
747 					return m_rgn[(offset) & (m_rgnlen - 1)];
748 				}
749 			}
750 		}
751 		else
752 		{
753 			return m_lowbus->read8(offset & 0x7fff);
754 		}
755 	}
756 
opcodes_800000_r(offs_t offset)757 	virtual uint8_t opcodes_800000_r(offs_t offset) override
758 	{
759 		if ((offset & 0x7fffff) >= m_cartlimit)
760 		{
761 			return m_rgn[(offset) & (m_rgnlen - 1)];
762 		}
763 		else
764 		{
765 			if (m_cartslot->has_cart())
766 			{
767 				return m_cartslot->read_cart(offset);
768 			}
769 			else
770 			{
771 				return m_rgn[(offset) & (m_rgnlen - 1)];
772 			}
773 		}
774 	}
775 
776 	// TODO, use callbacks?
extintrf_790x_r(offs_t offset)777 	virtual uint8_t extintrf_790x_r(offs_t offset) override
778 	{
779 		return xavix_state::extintrf_790x_r(offset);
780 	}
781 
extintrf_790x_w(offs_t offset,uint8_t data)782 	virtual void extintrf_790x_w(offs_t offset, uint8_t data) override
783 	{
784 		xavix_state::extintrf_790x_w(offset,data);
785 
786 		if (offset < 3)
787 		{
788 			if (m_cartslot->has_cart())
789 				m_cartslot->write_bus_control(offset,data);
790 		}
791 	};
792 
extbus_r(offs_t offset)793 	virtual uint8_t extbus_r(offs_t offset) override
794 	{
795 		if (m_cartslot->has_cart() && m_cartslot->is_read_access_not_rom())
796 		{
797 			logerror("%s: read from external bus %06x (SEEPROM READ?)\n", machine().describe_context(), offset);
798 			return m_cartslot->read_extra(offset);
799 		}
800 		else
801 		{
802 			if ((offset & 0x7fffff) >= m_cartlimit)
803 			{
804 				return m_rgn[(offset) & (m_rgnlen - 1)];
805 			}
806 			else
807 			{
808 				if (m_cartslot->has_cart())
809 				{
810 					return m_cartslot->read_cart(offset);
811 				}
812 				else
813 				{
814 					return m_rgn[(offset) & (m_rgnlen - 1)];
815 				}
816 			}
817 		}
818 	}
extbus_w(offs_t offset,uint8_t data)819 	virtual void extbus_w(offs_t offset, uint8_t data) override
820 	{
821 		if (m_cartslot->has_cart() && m_cartslot->is_write_access_not_rom())
822 		{
823 			logerror("%s: write to external bus %06x %02x (SEEPROM WRITE?)\n", machine().describe_context(), offset, data);
824 			return m_cartslot->write_extra(offset, data);
825 		}
826 		else
827 		{
828 			if (m_cartslot->has_cart())
829 			{
830 				return m_cartslot->write_cart(offset, data);
831 			}
832 			else
833 			{
834 				logerror("%s: write to external bus %06x %02x\n", machine().describe_context(), offset, data);
835 			}
836 		}
837 	}
838 
read_full_data_sp_bypass(uint32_t offset)839 	virtual inline uint8_t read_full_data_sp_bypass(uint32_t offset) override
840 	{
841 		uint8_t databank = offset >> 16;
842 
843 		if (databank >= 0x80)
844 		{
845 			if ((offset & 0x7fffff) >= m_cartlimit)
846 			{
847 				return m_rgn[(offset) & (m_rgnlen - 1)];
848 			}
849 			else
850 			{
851 				if (m_cartslot->has_cart())
852 				{
853 					return m_cartslot->read_cart(offset);
854 				}
855 				else
856 				{
857 					return m_rgn[(offset) & (m_rgnlen - 1)];
858 				}
859 			}
860 		}
861 		else
862 		{
863 			if ((offset & 0xffff) >= 0x8000)
864 			{
865 				if ((offset & 0x7fffff) >= m_cartlimit)
866 				{
867 					return m_rgn[(offset) & (m_rgnlen - 1)];
868 				}
869 				else
870 				{
871 					if (m_cartslot->has_cart())
872 					{
873 						return m_cartslot->read_cart(offset);
874 					}
875 					else
876 					{
877 						return m_rgn[(offset) & (m_rgnlen - 1)];
878 					}
879 				}
880 			}
881 			else
882 			{
883 				return read_full_data_sp_lowbus_bypass(offset);
884 			}
885 		}
886 	}
887 
888 	int m_cartlimit;
889 	required_device<ekara_cart_slot_device> m_cartslot;
890 };
891 
892 
893 class xavix_cart_gcslottv_state : public xavix_cart_state
894 {
895 public:
xavix_cart_gcslottv_state(const machine_config & mconfig,device_type type,const char * tag)896 	xavix_cart_gcslottv_state(const machine_config &mconfig, device_type type, const char *tag) :
897 		xavix_cart_state(mconfig, type, tag)
898 	{
899 		m_cartlimit = 0x800000;
900 	}
901 
902 	void xavix_cart_gcslottv(machine_config &config);
903 
904 protected:
905 };
906 
907 class xavix_i2c_cart_state : public xavix_cart_state
908 {
909 public:
xavix_i2c_cart_state(const machine_config & mconfig,device_type type,const char * tag)910 	xavix_i2c_cart_state(const machine_config &mconfig, device_type type, const char *tag)
911 		: xavix_cart_state(mconfig,type,tag),
912 		m_i2cmem(*this, "i2cmem")
913 	{ }
914 
915 	void xavix_i2c_taiko(machine_config &config);
916 	void xavix_i2c_jpopira(machine_config &config);
917 
918 protected:
919 	virtual void write_io1(uint8_t data, uint8_t direction) override;
920 
921 	required_device<i2cmem_device> m_i2cmem;
922 };
923 
924 class xavix_popira2_cart_state : public xavix_cart_state
925 {
926 public:
xavix_popira2_cart_state(const machine_config & mconfig,device_type type,const char * tag)927 	xavix_popira2_cart_state(const machine_config &mconfig, device_type type, const char *tag)
928 		: xavix_cart_state(mconfig,type,tag),
929 		m_p2(*this, "P2")
930 	{ }
931 
932 	void xavix_cart_popira2(machine_config &config);
933 
934 	DECLARE_READ_LINE_MEMBER(i2c_r);
935 
936 protected:
937 	virtual void write_io1(uint8_t data, uint8_t direction) override;
938 
939 private:
940 	uint8_t popira2_adc0_r();
941 	uint8_t popira2_adc1_r();
942 
943 	required_ioport m_p2;
944 };
945 
946 
947 class xavix_ekara_state : public xavix_cart_state
948 {
949 public:
xavix_ekara_state(const machine_config & mconfig,device_type type,const char * tag)950 	xavix_ekara_state(const machine_config &mconfig, device_type type, const char *tag)
951 		: xavix_cart_state(mconfig, type, tag),
952 		m_extra0(*this, "EXTRA0"),
953 		m_extra1(*this, "EXTRA1"),
954 		m_extraioselect(0),
955 		m_extraiowrite(0)
956 	{ }
957 
958 	DECLARE_READ_LINE_MEMBER(ekara_multi0_r);
959 	DECLARE_READ_LINE_MEMBER(ekara_multi1_r);
960 
961 //  void xavix_ekara(machine_config &config);
962 
963 protected:
964 
965 	required_ioport m_extra0;
966 	required_ioport m_extra1;
967 
968 	virtual void write_io0(uint8_t data, uint8_t direction) override;
969 	virtual void write_io1(uint8_t data, uint8_t direction) override;
970 
971 	uint8_t m_extraioselect;
972 	uint8_t m_extraiowrite;
973 };
974 
975 
976 #endif // MAME_INCLUDES_XAVIX_H
977