1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /*************************************************************************
4 
5     Driver for Midway Zeus games
6 
7 **************************************************************************/
8 
9 #define MIDZEUS_VIDEO_CLOCK     XTAL(66'666'700)
10 
11 #include "machine/timekpr.h"
12 #include "emupal.h"
13 #include "screen.h"
14 #include "machine/midwayic.h"
15 #include "video/poly.h"
16 
17 /*************************************
18  *
19  *  Type definitions
20  *
21  *************************************/
22 
23 struct mz_poly_extra_data
24 {
25 	const void *    palbase;
26 	const void *    texbase;
27 	uint16_t          solidcolor;
28 	uint16_t          voffset;
29 	int16_t           zoffset;
30 	uint16_t          transcolor;
31 	uint16_t          texwidth;
32 	uint16_t          color;
33 	uint32_t          alpha;
34 	uint32_t          ctrl_word;
35 	bool            blend_enable;
36 	bool            depth_test_enable;
37 	bool            depth_write_enable;
38 	uint32_t          blend;
39 	uint8_t           (*get_texel)(const void *, int, int, int);
40 };
41 
42 
43 class midzeus_state;
44 
45 class midzeus_renderer : public poly_manager<float, mz_poly_extra_data, 4, 10000>
46 {
47 public:
48 	midzeus_renderer(midzeus_state &state);
49 
50 	void render_poly(int32_t scanline, const extent_t& extent, const mz_poly_extra_data& object, int threadid);
51 	void render_poly_solid_fixedz(int32_t scanline, const extent_t& extent, const mz_poly_extra_data& object, int threadid);
52 
53 	void zeus_draw_quad(int long_fmt, const uint32_t *databuffer, uint32_t texdata, bool logit);
54 	void zeus_draw_debug_quad(const rectangle& rect, const vertex_t* vert);
55 
56 private:
57 	midzeus_state& m_state;
58 };
59 
60 typedef midzeus_renderer::vertex_t poly_vertex;
61 
62 
63 class midzeus_state : public driver_device
64 {
65 	friend class midzeus_renderer;
66 
67 public:
midzeus_state(const machine_config & mconfig,device_type type,const char * tag)68 	midzeus_state(const machine_config &mconfig, device_type type, const char *tag)
69 		: driver_device(mconfig, type, tag),
70 		m_nvram(*this, "nvram"),
71 		m_ram_base(*this, "ram_base"),
72 		m_tms32031_control(*this, "tms32031_ctl"),
73 		m_zeusbase(*this, "zeusbase"),
74 		m_m48t35(*this, "m48t35"),
75 		m_maincpu(*this, "maincpu"),
76 		m_screen(*this, "screen"),
77 		m_palette(*this, "palette"),
78 		m_ioasic(*this, "ioasic"),
79 		m_io_analog(*this, "ANALOG%u", 0U),
80 		m_io_gun_x(*this, "GUNX%u", 1U),
81 		m_io_gun_y(*this, "GUNY%u", 1U),
82 		m_io_trackx(*this, "TRACKX1"),
83 		m_io_tracky(*this, "TRACKY1"),
84 		m_io_49way_x(*this, "49WAYX"),
85 		m_io_49way_y(*this, "49WAYY"),
86 		m_io_keypad(*this, "KEYPAD"),
87 		m_digits(*this, "digit%u", 0U)
88 	{ }
89 
90 	//static constexpr XTAL CPU_CLOCK = XTAL(60'000'000);
91 	static constexpr int BEAM_DY = 3;
92 	static constexpr int BEAM_DX = 3;
93 	static constexpr int BEAM_XOFFS = 40; // table in the code indicates an offset of 20 with a beam height of 7
94 
95 	required_shared_ptr<uint32_t> m_nvram;
96 	required_shared_ptr<uint32_t> m_ram_base;
97 	required_shared_ptr<uint32_t> m_tms32031_control;
98 	optional_shared_ptr<uint32_t> m_zeusbase;
99 
100 	void cmos_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
101 	uint32_t cmos_r(offs_t offset);
102 	void cmos_protect_w(uint32_t data);
103 	uint32_t zpram_r(offs_t offset);
104 	void zpram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
105 	uint32_t disk_asic_jr_r(offs_t offset);
106 	void disk_asic_jr_w(offs_t offset, uint32_t data);
107 	uint32_t tms32031_control_r(offs_t offset);
108 	void tms32031_control_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
109 	void keypad_select_w(offs_t offset, uint32_t data);
110 	uint32_t analog_r(offs_t offset);
111 	void analog_w(uint32_t data);
112 	void invasn_gun_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
113 	uint32_t invasn_gun_r();
114 	uint32_t zeus_r(offs_t offset);
115 	void zeus_w(offs_t offset, uint32_t data);
116 	DECLARE_CUSTOM_INPUT_MEMBER(custom_49way_r);
117 	DECLARE_CUSTOM_INPUT_MEMBER(keypad_r);
118 	uint32_t grid_keypad_r(offs_t offset);
119 	uint32_t trackball_r(offs_t offset);
120 	void init_invasn();
121 	void init_mk4();
122 
123 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
124 	INTERRUPT_GEN_MEMBER(display_irq);
125 	TIMER_CALLBACK_MEMBER(display_irq_off);
126 	TIMER_CALLBACK_MEMBER(invasn_gun_callback);
127 	void midzeus(machine_config &config);
128 	void invasn(machine_config &config);
129 	void mk4(machine_config &config);
130 	void zeus_map(address_map &map);
131 
132 protected:
133 	virtual void machine_start() override;
134 	virtual void machine_reset() override;
135 	virtual void video_start() override;
136 
137 	optional_device<timekeeper_device> m_m48t35;
138 	required_device<cpu_device> m_maincpu;
139 	required_device<screen_device> m_screen;
140 	optional_device<palette_device> m_palette;
141 	required_device<midway_ioasic_device> m_ioasic;
142 	optional_ioport_array<4> m_io_analog;
143 	optional_ioport_array<2> m_io_gun_x;
144 	optional_ioport_array<2> m_io_gun_y;
145 	optional_ioport m_io_trackx;
146 	optional_ioport m_io_tracky;
147 	optional_ioport m_io_49way_x;
148 	optional_ioport m_io_49way_y;
149 	optional_ioport m_io_keypad;
150 	output_finder<7> m_digits;
151 
152 	emu_timer *     m_display_irq_off_timer;
153 	uint8_t         m_crusnexo_leds_select;
154 	uint32_t        m_disk_asic_jr[0x10];
155 
156 	uint8_t         m_cmos_protected;
157 
158 	emu_timer *     m_timer[2];
159 
160 private:
161 	uint32_t        m_gun_control;
162 	uint8_t         m_gun_irq_state;
163 	emu_timer *     m_gun_timer[2];
164 	int32_t         m_gun_x[2], m_gun_y[2];
165 	uint8_t         m_keypad_select;
166 
167 	void exit_handler();
168 	void zeus_pointer_w(uint32_t which, uint32_t data, bool logit);
169 	void zeus_register16_w(offs_t offset, uint16_t data, bool logit);
170 	void zeus_register32_w(offs_t offset, uint32_t data, bool logit);
171 	void zeus_register_update(offs_t offset);
172 	int zeus_fifo_process(const uint32_t *data, int numwords);
173 	void zeus_draw_model(uint32_t texdata, bool logit);
174 
175 	void log_fifo_command(const uint32_t *data, int numwords, const char *suffix);
176 	void log_waveram(uint32_t length_and_base);
177 	void update_gun_irq();
178 
179 	void *waveram0_ptr_from_block_addr(uint32_t addr);
180 	void *waveram0_ptr_from_expanded_addr(uint32_t addr);
181 	void *waveram1_ptr_from_expanded_addr(uint32_t addr);
182 	void *waveram0_ptr_from_texture_addr(uint32_t addr, int width);
183 	void waveram_plot_depth(int y, int x, uint16_t color, uint16_t depth);
184 	void waveram_plot(int y, int x, uint16_t color);
185 	void waveram_plot_check_depth(int y, int x, uint16_t color, uint16_t depth);
186 	void waveram_plot_check_depth_nowrite(int y, int x, uint16_t color, uint16_t depth);
187 
188 	std::unique_ptr<midzeus_renderer> m_poly;
189 	uint8_t     m_log_fifo;
190 
191 	uint32_t    m_zeus_fifo[20];
192 	uint8_t     m_zeus_fifo_words;
193 	int16_t     m_zeus_matrix[3][3];
194 	int32_t     m_zeus_point[3];
195 	int16_t     m_zeus_light[3];
196 	void *      m_zeus_renderbase;
197 	uint32_t    m_zeus_palbase;
198 	uint32_t    m_zeus_unkbase;
199 	int         m_zeus_enable_logging;
200 	uint32_t    m_zeus_objdata;
201 	rectangle   m_zeus_cliprect;
202 
203 	std::unique_ptr<uint32_t[]> m_waveram[2];
204 	int         m_yoffs;
205 	int         m_texel_width;
206 	int         m_is_mk4b;
207 };
208