1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /*************************************************************************
4 
5     Sega vector hardware
6 
7 *************************************************************************/
8 
9 #include "audio/segaspeech.h"
10 #include "audio/segausb.h"
11 #include "audio/segag80.h"
12 #include "cpu/z80/z80.h"
13 #include "machine/segag80.h"
14 #include "sound/ay8910.h"
15 #include "sound/samples.h"
16 #include "video/vector.h"
17 
18 #include "screen.h"
19 
20 #define CPU_CLOCK           8000000     /* not used when video boards are connected */
21 #define VIDEO_CLOCK         15468480
22 
23 class segag80v_state : public driver_device
24 {
25 public:
segag80v_state(const machine_config & mconfig,device_type type,const char * tag)26 	segag80v_state(const machine_config &mconfig, device_type type, const char *tag) :
27 		driver_device(mconfig, type, tag),
28 		m_mainrom(*this, "maincpu"),
29 		m_mainram(*this, "mainram"),
30 		m_vectorram(*this, "vectorram"),
31 		m_maincpu(*this, "maincpu"),
32 		m_samples(*this, "samples"),
33 		m_speech(*this, "speech"),
34 		m_usb(*this, "usbsnd"),
35 		m_g80_audio(*this, "g80sound"),
36 		m_aysnd(*this, "aysnd"),
37 		m_vector(*this, "vector"),
38 		m_screen(*this, "screen"),
39 		m_d7d6(*this, "D7D6"),
40 		m_d5d4(*this, "D5D4"),
41 		m_d3d2(*this, "D3D2"),
42 		m_d1d0(*this, "D1D0"),
43 		m_fc(*this, "FC"),
44 		m_coins(*this, "COINS"),
45 		m_spinner(*this, "SPINNER"),
46 		m_mult_data{0,0},
47 		m_mult_result(0),
48 		m_spinner_select(0),
49 		m_spinner_sign(0),
50 		m_spinner_count(0),
51 		m_coin_ff_state(0),
52 		m_coin_last_state(0),
53 		m_edgint_ff_state(0),
54 		m_scrambled_write_pc(0),
55 		m_decrypt(nullptr),
56 		m_min_x(0),
57 		m_min_y(0),
58 		m_draw_end_time(attotime::zero)
59 	{ }
60 
61 	void g80v_base(machine_config &config);
62 	void tacscan(machine_config &config);
63 	void elim2(machine_config &config);
64 	void startrek(machine_config &config);
65 	void zektor(machine_config &config);
66 	void spacfury(machine_config &config);
67 
68 	void init_waitstates();
69 	void init_zektor();
70 	void init_startrek();
71 	void init_elim4();
72 	void init_elim2();
73 	void init_tacscan();
74 	void init_spacfury();
75 
76 	DECLARE_READ_LINE_MEMBER(elim4_joint_coin_r);
77 	DECLARE_READ_LINE_MEMBER(draw_r);
78 	DECLARE_WRITE_LINE_MEMBER(service_switch_w);
79 	DECLARE_WRITE_LINE_MEMBER(irq_ack_w);
80 
81 	template<int Index>
DECLARE_WRITE_LINE_MEMBER(coin_w)82 	DECLARE_WRITE_LINE_MEMBER( coin_w )
83 	{
84 		const u8 mask = 1 << Index;
85 
86 		if (state == 0 && (m_coin_last_state & mask) != 0)
87 			m_coin_ff_state |= mask;
88 		else
89 			m_coin_ff_state &= ~mask;
90 
91 		if (state)
92 			m_coin_last_state |= mask;
93 		else
94 			m_coin_last_state &= ~mask;
95 
96 		update_int();
97 	}
98 
99 private:
100 	required_memory_region m_mainrom;
101 	required_shared_ptr<u8> m_mainram;
102 	required_shared_ptr<u8> m_vectorram;
103 
104 	required_device<z80_device> m_maincpu;
105 	optional_device<samples_device> m_samples;
106 	optional_device<sega_speech_device> m_speech;
107 	optional_device<usb_sound_device> m_usb;
108 	optional_device<segag80_audio_device_base> m_g80_audio;
109 	optional_device<ay8912_device> m_aysnd;
110 	required_device<vector_device> m_vector;
111 	required_device<screen_device> m_screen;
112 
113 	required_ioport m_d7d6;
114 	required_ioport m_d5d4;
115 	required_ioport m_d3d2;
116 	required_ioport m_d1d0;
117 	required_ioport m_fc;
118 	optional_ioport m_coins;
119 	optional_ioport m_spinner;
120 
121 	u8 m_mult_data[2];
122 	u16 m_mult_result;
123 	u8 m_spinner_select;
124 	u8 m_spinner_sign;
125 	u8 m_spinner_count;
126 	u8 m_coin_ff_state;
127 	u8 m_coin_last_state;
128 	u8 m_edgint_ff_state;
129 	offs_t m_scrambled_write_pc;
130 	segag80_decrypt_func m_decrypt;
131 	int m_min_x;
132 	int m_min_y;
133 	attotime m_draw_end_time;
134 
135 	u8 opcode_r(offs_t offset);
136 	u8 mainrom_r(offs_t offset);
137 	void mainram_w(offs_t offset, u8 data);
138 	void vectorram_w(offs_t offset, u8 data);
139 	u8 mangled_ports_r(offs_t offset);
140 	void spinner_select_w(u8 data);
141 	u8 spinner_input_r();
142 	u8 elim4_input_r();
143 	void multiply_w(offs_t offset, u8 data);
144 	u8 multiply_r();
145 	void coin_count_w(u8 data);
146 	void unknown_w(u8 data);
147 	void update_int();
148 	void vblank_callback(screen_device &screen, bool state);
149 
150 	void usb_ram_w(offs_t offset, u8 data);
151 
152 	virtual void machine_start() override;
153 	virtual void video_start() override;
154 	uint32_t screen_update_segag80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
155 	inline bool adjust_xy(int rawx, int rawy, int &outx, int &outy);
156 	void sega_generate_vector_list();
157 	offs_t decrypt_offset(offs_t offset);
158 	inline u8 demangle(u8 d7d6, u8 d5d4, u8 d3d2, u8 d1d0);
159 
160 	void main_map(address_map &map);
161 	void opcodes_map(address_map &map);
162 	void main_portmap(address_map &map);
163 };
164