1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont, Olivier Galibert, ElSemi, Angelo Salese
3 #ifndef MAME_INCLUDES_MODEL2_H
4 #define MAME_INCLUDES_MODEL2_H
5 
6 #pragma once
7 
8 #include "audio/dsbz80.h"
9 #include "audio/segam1audio.h"
10 #include "cpu/i960/i960.h"
11 #include "cpu/mb86233/mb86233.h"
12 #include "cpu/sharc/sharc.h"
13 #include "cpu/mb86235/mb86235.h"
14 #include "machine/315-5881_crypt.h"
15 #include "machine/315-5838_317-0229_comp.h"
16 #include "machine/bankdev.h"
17 #include "machine/eepromser.h"
18 #include "machine/gen_fifo.h"
19 #include "machine/i8251.h"
20 #include "machine/m2comm.h"
21 #include "machine/segabill.h"
22 #include "machine/timer.h"
23 #include "sound/scsp.h"
24 #include "video/segaic24.h"
25 #include "video/poly.h"
26 #include "emupal.h"
27 #include "screen.h"
28 
29 #include <algorithm>
30 
31 
32 class model2_renderer;
33 
34 class model2_state : public driver_device
35 {
36 public:
37 	struct plane;
38 	struct texture_parameter;
39 	struct triangle;
40 	struct quad_m2;
41 	struct raster_state;
42 	struct geo_state;
43 
model2_state(const machine_config & mconfig,device_type type,const char * tag)44 	model2_state(const machine_config &mconfig, device_type type, const char *tag) :
45 		driver_device(mconfig, type, tag),
46 		m_textureram0(*this, "textureram0"),
47 		m_textureram1(*this, "textureram1"),
48 		m_workram(*this, "workram"),
49 		m_bufferram(*this, "bufferram"),
50 		m_soundram(*this, "soundram"),
51 		m_maincpu(*this,"maincpu"),
52 		m_dsbz80(*this, DSBZ80_TAG),
53 		m_m1audio(*this, M1AUDIO_TAG),
54 		m_uart(*this, "uart"),
55 		m_m2comm(*this, "m2comm"),
56 		m_audiocpu(*this, "audiocpu"),
57 		m_copro_fifo_in(*this, "copro_fifo_in"),
58 		m_copro_fifo_out(*this, "copro_fifo_out"),
59 		m_drivecpu(*this, "drivecpu"),
60 		m_eeprom(*this, "eeprom"),
61 		m_tiles(*this, "tile"),
62 		m_screen(*this, "screen"),
63 		m_palette(*this, "palette"),
64 		m_scsp(*this, "scsp"),
65 		m_timers(*this, "timer%u", 0U),
66 		m_cryptdevice(*this, "315_5881"),
67 		m_0229crypt(*this, "317_0229"),
68 		m_copro_data(*this, "copro_data"),
69 		m_in0(*this, "IN0"),
70 		m_gears(*this, "GEARS"),
71 		m_lightgun_ports(*this, {"P1_Y", "P1_X", "P2_Y", "P2_X"})
72 	{ }
73 
74 	/* Public for access by the rendering functions */
75 	required_shared_ptr<u32> m_textureram0;
76 	required_shared_ptr<u32> m_textureram1;
77 	std::unique_ptr<u16[]> m_palram;
78 	std::unique_ptr<u16[]> m_colorxlat;
79 	std::unique_ptr<u16[]> m_lumaram;
80 	u8 m_gamma_table[256];
81 	std::unique_ptr<model2_renderer> m_poly;
82 
83 	/* Public for access by the ioports */
84 	DECLARE_CUSTOM_INPUT_MEMBER(daytona_gearbox_r);
85 
86 	/* Public for access by MCFG */
87 	TIMER_DEVICE_CALLBACK_MEMBER(model2_interrupt);
88 	u16 crypt_read_callback(u32 addr);
89 	DECLARE_MACHINE_START(model2);
90 
91 
92 	/* Public for access by GAME() */
93 	void init_overrev();
94 	void init_pltkids();
95 	void init_rchase2();
96 	void init_manxttdx();
97 	void init_doa();
98 	void init_zerogun();
99 	void init_sgt24h();
100 	void init_srallyc();
101 	void init_powsledm();
102 
103 protected:
104 	virtual void machine_start() override;
105 	virtual void machine_reset() override;
106 
107 	required_shared_ptr<u32> m_workram;
108 	required_shared_ptr<u32> m_bufferram;
109 	std::unique_ptr<u16[]> m_fbvramA;
110 	std::unique_ptr<u16[]> m_fbvramB;
111 	optional_shared_ptr<u16> m_soundram;
112 
113 	required_device<i960_cpu_device> m_maincpu;
114 	optional_device<dsbz80_device> m_dsbz80;    // Z80-based MPEG Digital Sound Board
115 	optional_device<segam1audio_device> m_m1audio;  // Model 1 standard sound board
116 	required_device<i8251_device> m_uart;
117 	optional_device<m2comm_device> m_m2comm;        // Model 2 communication board
118 	optional_device<cpu_device> m_audiocpu;
119 	required_device<generic_fifo_u32_device> m_copro_fifo_in;
120 	required_device<generic_fifo_u32_device> m_copro_fifo_out;
121 	optional_device<cpu_device> m_drivecpu;
122 	optional_device<eeprom_serial_93cxx_device> m_eeprom;
123 	required_device<segas24_tile_device> m_tiles;
124 	required_device<screen_device> m_screen;
125 	required_device<palette_device> m_palette;
126 	optional_device<scsp_device> m_scsp;
127 	required_device_array<timer_device, 4> m_timers;
128 	optional_device<sega_315_5881_crypt_device> m_cryptdevice;
129 	optional_device<sega_315_5838_comp_device> m_0229crypt;
130 	optional_memory_region m_copro_data;
131 
132 	required_ioport m_in0;
133 	optional_ioport m_gears;
134 	optional_ioport_array<4> m_lightgun_ports;
135 
136 	u32 m_timervals[4];
137 	u32 m_timerorig[4];
138 	int m_timerrun[4];
139 	int m_ctrlmode;
140 	u16 m_cmd_data;
141 	u8 m_driveio_comm_data;
142 	int m_iop_write_num;
143 	u32 m_iop_data;
144 	int m_geo_iop_write_num;
145 	u32 m_geo_iop_data;
146 
147 	u32 m_geo_read_start_address;
148 	u32 m_geo_write_start_address;
149 	std::unique_ptr<raster_state> m_raster;
150 	std::unique_ptr<geo_state> m_geo;
151 	bitmap_rgb32 m_sys24_bitmap;
152 //  u32 m_soundack;
153 	void model2_check_irq_state();
154 	void model2_check_irqack_state(u32 data);
155 	u8 m_gearsel;
156 	u8 m_lightgun_mux;
157 
158 	// Coprocessor communications
159 	u32 copro_prg_r();
160 	u32 copro_ctl1_r();
161 	void copro_ctl1_w(offs_t offset, u32 data, u32 mem_mask = ~0);
162 	u32 copro_status_r();
163 
164 	// Geometrizer communications
165 	void geo_ctl1_w(u32 data);
166 	u32 geo_prg_r(offs_t offset);
167 	void geo_prg_w(u32 data);
168 	u32 geo_r(offs_t offset);
169 	void geo_w(offs_t offset, u32 data);
170 
171 	// Everything else
172 	u32 timers_r(offs_t offset);
173 	void timers_w(offs_t offset, u32 data, u32 mem_mask = ~0);
174 	u16 palette_r(offs_t offset);
175 	void palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
176 	u16 colorxlat_r(offs_t offset);
177 	void colorxlat_w(offs_t offset, u16 data, u16 mem_mask = ~0);
178 	void eeprom_w(u8 data);
179 	u8 in0_r();
180 	u32 fifo_control_2a_r();
181 	u32 videoctl_r();
182 	void videoctl_w(offs_t offset, u32 data, u32 mem_mask = ~0);
183 	u8 rchase2_drive_board_r();
184 	void rchase2_drive_board_w(u8 data);
185 	void drive_board_w(u8 data);
186 	u8 lightgun_data_r(offs_t offset);
187 	u8 lightgun_mux_r();
188 	void lightgun_mux_w(u8 data);
189 	u8 lightgun_offscreen_r(offs_t offset);
190 	u32 irq_request_r();
191 	void irq_ack_w(u32 data);
192 	u32 irq_enable_r();
193 	void irq_enable_w(offs_t offset, u32 data, u32 mem_mask = ~0);
194 	u32 model2_serial_r(offs_t offset, u32 mem_mask = ~0);
195 	void model2_serial_w(offs_t offset, u32 data, u32 mem_mask = ~0);
196 	void horizontal_sync_w(u16 data);
197 	void vertical_sync_w(u16 data);
198 	u32 doa_prot_r(offs_t offset, u32 mem_mask = ~0);
199 	u32 doa_unk_r();
200 	void sega_0229_map(address_map &map);
201 	int m_prot_a;
202 
203 	void raster_init(memory_region *texture_rom);
204 	void geo_init(memory_region *polygon_rom);
205 	u32 render_mode_r();
206 	void render_mode_w(u32 data);
207 	u16 lumaram_r(offs_t offset);
208 	void lumaram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
209 	u16 fbvram_bankA_r(offs_t offset);
210 	void fbvram_bankA_w(offs_t offset, u16 data, u16 mem_mask = ~0);
211 	u16 fbvram_bankB_r(offs_t offset);
212 	void fbvram_bankB_w(offs_t offset, u16 data, u16 mem_mask = ~0);
213 	void model2_3d_zclip_w(u32 data);
214 	void model2snd_ctrl(u16 data);
215 	u8 tgpid_r(offs_t offset);
216 	u32 polygon_count_r();
217 
218 	u8 driveio_portg_r();
219 	u8 driveio_porth_r();
220 	void driveio_port_w(u8 data);
221 	void push_geo_data(u32 data);
222 	DECLARE_VIDEO_START(model2);
223 	void reset_model2_scsp();
224 	u32 screen_update_model2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
225 //  DECLARE_WRITE_LINE_MEMBER(screen_vblank_model2);
226 //  DECLARE_WRITE_LINE_MEMBER(sound_ready_w);
227 	TIMER_DEVICE_CALLBACK_MEMBER(model2_timer_cb);
228 	void scsp_irq(offs_t offset, u8 data);
229 
230 	void model2_3d_frame_start( void );
231 	void geo_parse( void );
232 	void model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &cliprect );
233 	void draw_framebuffer(bitmap_rgb32 &bitmap, const rectangle &cliprect );
234 
235 	void model2_timers(machine_config &config);
236 	void model2_screen(machine_config &config);
237 	void model2_scsp(machine_config &config);
238 
239 	void sj25_0207_01(machine_config &config);
240 
241 	void drive_io_map(address_map &map);
242 	void drive_map(address_map &map);
243 	void geo_sharc_map(address_map &map);
244 	void model2_base_mem(address_map &map);
245 	void model2_5881_mem(address_map &map);
246 	void model2_0229_mem(address_map &map);
247 	void model2_snd(address_map &map);
248 	void scsp_map(address_map &map);
249 
250 	void debug_init();
251 	void debug_commands( int ref, const std::vector<std::string> &params );
252 	void debug_geo_dasm_command(int ref, const std::vector<std::string> &params);
253 	void debug_tri_dump_command(int ref, const std::vector<std::string> &params);
254 	void debug_help_command(int ref, const std::vector<std::string> &params);
255 
256 	virtual void video_start() override;
257 
258 	u32 m_intreq;
259 	u32 m_intena;
260 	u32 m_coproctl;
261 	u32 m_coprocnt;
262 
263 	virtual void copro_halt() = 0;
264 	virtual void copro_boot() = 0;
265 
266 private:
267 	void tri_list_dump(FILE *dst);
268 
269 	u32 m_geoctl;
270 	u32 m_geocnt;
271 	u32 m_videocontrol;
272 
273 	bool m_render_unk;
274 	bool m_render_mode;
275 	bool m_render_test_mode;
276 	int16 m_crtc_xoffset, m_crtc_yoffset;
277 
278 	u32 *geo_process_command( geo_state *geo, u32 opcode, u32 *input, bool *end_code );
279 	// geo commands
280 	u32 *geo_nop( geo_state *geo, u32 opcode, u32 *input );
281 	u32 *geo_object_data( geo_state *geo, u32 opcode, u32 *input );
282 	u32 *geo_direct_data( geo_state *geo, u32 opcode, u32 *input );
283 	u32 *geo_window_data( geo_state *geo, u32 opcode, u32 *input );
284 	u32 *geo_texture_data( geo_state *geo, u32 opcode, u32 *input );
285 	u32 *geo_polygon_data( geo_state *geo, u32 opcode, u32 *input );
286 	u32 *geo_texture_parameters( geo_state *geo, u32 opcode, u32 *input );
287 	u32 *geo_mode( geo_state *geo, u32 opcode, u32 *input );
288 	u32 *geo_zsort_mode( geo_state *geo, u32 opcode, u32 *input );
289 	u32 *geo_focal_distance( geo_state *geo, u32 opcode, u32 *input );
290 	u32 *geo_light_source( geo_state *geo, u32 opcode, u32 *input );
291 	u32 *geo_matrix_write( geo_state *geo, u32 opcode, u32 *input );
292 	u32 *geo_translate_write( geo_state *geo, u32 opcode, u32 *input );
293 	u32 *geo_data_mem_push( geo_state *geo, u32 opcode, u32 *input );
294 	u32 *geo_test( geo_state *geo, u32 opcode, u32 *input );
295 	u32 *geo_end( geo_state *geo, u32 opcode, u32 *input );
296 	u32 *geo_dummy( geo_state *geo, u32 opcode, u32 *input );
297 	u32 *geo_log_data( geo_state *geo, u32 opcode, u32 *input );
298 	u32 *geo_lod( geo_state *geo, u32 opcode, u32 *input );
299 	u32 *geo_code_upload( geo_state *geo, u32 opcode, u32 *input );
300 	u32 *geo_code_jump( geo_state *geo, u32 opcode, u32 *input );
301 	// geo code drawing paths
302 	void geo_parse_np_ns( geo_state *geo, u32 *input, u32 count );
303 	void geo_parse_np_s( geo_state *geo, u32 *input, u32 count );
304 	void geo_parse_nn_ns( geo_state *geo, u32 *input, u32 count );
305 	void geo_parse_nn_s( geo_state *geo, u32 *input, u32 count );
306 
307 	// raster functions
308 	// main data input port
309 	void model2_3d_push( raster_state *raster, u32 input );
310 	// quad & triangle push paths
311 	void model2_3d_process_quad( raster_state *raster, u32 attr );
312 	void model2_3d_process_triangle( raster_state *raster, u32 attr );
313 
314 	// inliners
315 	inline void model2_3d_project( triangle *tri );
316 	inline u16 float_to_zval( float floatval );
317 	inline bool check_culling( raster_state *raster, u32 attr, float min_z, float max_z );
318 };
319 
320 /*****************************
321  *
322  * Model 2/2A TGP support
323  *
324  *****************************/
325 
326 class model2_tgp_state : public model2_state
327 {
328 public:
model2_tgp_state(const machine_config & mconfig,device_type type,const char * tag)329 	model2_tgp_state(const machine_config &mconfig, device_type type, const char *tag)
330 		: model2_state(mconfig, type, tag),
331 		  m_copro_tgp(*this, "copro_tgp"),
332 		  m_copro_tgp_program(*this, "copro_tgp_program"),
333 		  m_copro_tgp_tables(*this, "copro_tgp_tables"),
334 		  m_copro_tgp_bank(*this, "copro_tgp_bank")
335 	{}
336 
337 protected:
338 	virtual void machine_start() override;
339 	virtual void machine_reset() override;
340 
341 	required_device<mb86234_device> m_copro_tgp;
342 	required_shared_ptr<u32> m_copro_tgp_program;
343 	required_region_ptr<u32> m_copro_tgp_tables;
344 	required_device<address_map_bank_device> m_copro_tgp_bank;
345 
346 	u32 m_copro_tgp_bank_reg;
347 	u32 m_copro_sincos_base;
348 	u32 m_copro_inv_base;
349 	u32 m_copro_isqrt_base;
350 	u32 m_copro_atan_base[4];
351 
352 	void copro_function_port_w(offs_t offset, u32 data);
353 	u32 copro_fifo_r();
354 	void copro_fifo_w(u32 data);
355 	void tex0_w(offs_t offset, u32 data);
356 	void tex1_w(offs_t offset, u32 data);
357 
358 	void copro_tgp_bank_w(offs_t offset, u32 data, u32 mem_mask = ~0);
359 	u32 copro_tgp_memory_r(offs_t offset);
360 	void copro_tgp_memory_w(offs_t offset, u32 data, u32 mem_mask = ~0);
361 
362 	void copro_sincos_w(offs_t offset, u32 data, u32 mem_mask = ~0);
363 	u32 copro_sincos_r(offs_t offset);
364 	void copro_inv_w(offs_t offset, u32 data, u32 mem_mask = ~0);
365 	u32 copro_inv_r(offs_t offset);
366 	void copro_isqrt_w(offs_t offset, u32 data, u32 mem_mask = ~0);
367 	u32 copro_isqrt_r(offs_t offset);
368 	void copro_atan_w(offs_t offset, u32 data, u32 mem_mask = ~0);
369 	u32 copro_atan_r();
370 
371 	void model2_tgp_mem(address_map &map);
372 
373 	void copro_tgp_prog_map(address_map &map);
374 	void copro_tgp_data_map(address_map &map);
375 	void copro_tgp_bank_map(address_map &map);
376 	void copro_tgp_io_map(address_map &map);
377 	void copro_tgp_rf_map(address_map &map);
378 
379 	virtual void copro_halt() override;
380 	virtual void copro_boot() override;
381 };
382 
383 /*****************************
384  *
385  * Model 2 support
386  *
387  *****************************/
388 
389 class model2o_state : public model2_tgp_state
390 {
391 public:
model2o_state(const machine_config & mconfig,device_type type,const char * tag)392 	model2o_state(const machine_config &mconfig, device_type type, const char *tag)
393 		: model2_tgp_state(mconfig, type, tag)
394 	{}
395 
396 	void model2o(machine_config &config);
397 	void daytona(machine_config &config);
398 	void desert(machine_config &config);
399 	void vcop(machine_config &config);
400 
401 protected:
402 	u32 fifo_control_2o_r();
403 	void daytona_output_w(u8 data);
404 	void desert_output_w(u8 data);
405 	void vcop_output_w(u8 data);
406 
407 	void model2o_mem(address_map &map);
408 };
409 
410 /*****************************
411  *
412  * Daytona To The Maxx
413  *
414  *****************************/
415 
416 class model2o_maxx_state : public model2o_state
417 {
418 public:
model2o_maxx_state(const machine_config & mconfig,device_type type,const char * tag)419 	model2o_maxx_state(const machine_config &mconfig, device_type type, const char *tag)
420 		: model2o_state(mconfig, type, tag)
421 	{}
422 
423 	u32 maxx_r(offs_t offset, u32 mem_mask = ~0);
424 	void daytona_maxx(machine_config &config);
425 	void model2o_maxx_mem(address_map &map);
426 
427 private:
428 	int m_maxxstate;
429 };
430 
431 /*****************************
432  *
433  * Daytona GTX 2004 Edition
434  *
435  *****************************/
436 
437 class model2o_gtx_state : public model2o_state
438 {
439 public:
model2o_gtx_state(const machine_config & mconfig,device_type type,const char * tag)440 	model2o_gtx_state(const machine_config &mconfig, device_type type, const char *tag)
441 		: model2o_state(mconfig, type, tag)
442 	{}
443 
444 	u8 gtx_r(offs_t offset);
445 	void daytona_gtx(machine_config &config);
446 	void model2o_gtx_mem(address_map &map);
447 
448 private:
449 	int m_gtx_state;
450 };
451 
452 /*****************************
453  *
454  * Model 2A
455  *
456  *****************************/
457 
458 class model2a_state : public model2_tgp_state
459 {
460 public:
model2a_state(const machine_config & mconfig,device_type type,const char * tag)461 	model2a_state(const machine_config &mconfig, device_type type, const char *tag)
462 		: model2_tgp_state(mconfig, type, tag),
463 		  m_billboard(*this, "billboard")
464 	{}
465 
466 	void manxtt(machine_config &config);
467 	void manxttdx(machine_config &config);
468 	void model2a(machine_config &config);
469 	void model2a_0229(machine_config &config);
470 	void model2a_5881(machine_config &config);
471 	void srallyc(machine_config &config);
472 	void vcop2(machine_config &config);
473 	void skytargt(machine_config &config);
474 	void zeroguna(machine_config &config);
475 
476 protected:
477 	virtual void machine_reset() override;
478 
479 	void model2a_crx_mem(address_map &map);
480 	void model2a_5881_mem(address_map &map);
481 	void model2a_0229_mem(address_map &map);
482 
483 private:
484 	required_device<sega_billboard_device> m_billboard;
485 };
486 
487 /*****************************
488  *
489  * Model 2B
490  *
491  *****************************/
492 
493 class model2b_state : public model2_state
494 {
495 public:
model2b_state(const machine_config & mconfig,device_type type,const char * tag)496 	model2b_state(const machine_config &mconfig, device_type type, const char *tag)
497 		: model2_state(mconfig, type, tag),
498 		  m_copro_adsp(*this, "copro_adsp"),
499 		  m_billboard(*this, "billboard")
500 	{}
501 
502 	void model2b(machine_config &config);
503 	void model2b_0229(machine_config &config);
504 	void model2b_5881(machine_config &config);
505 	void indy500(machine_config &config);
506 	void overrev2b(machine_config &config);
507 	void powsled(machine_config &config);
508 	void rchase2(machine_config &config);
509 	void gunblade(machine_config &config);
510 	void dynabb(machine_config &config);
511 	void zerogun(machine_config &config);
512 
513 protected:
514 	virtual void machine_start() override;
515 	virtual void machine_reset() override;
516 
517 	required_device<adsp21062_device> m_copro_adsp;
518 
519 	void copro_function_port_w(offs_t offset, u32 data);
520 	u32 copro_fifo_r();
521 	void copro_fifo_w(u32 data);
522 	void copro_sharc_iop_w(offs_t offset, u32 data);
523 	u32 copro_sharc_buffer_r(offs_t offset);
524 	void copro_sharc_buffer_w(offs_t offset, u32 data);
525 
526 	void model2b_crx_mem(address_map &map);
527 	void model2b_5881_mem(address_map &map);
528 	void model2b_0229_mem(address_map &map);
529 	// TODO: split into own class
530 	void rchase2_iocpu_map(address_map &map);
531 	void rchase2_ioport_map(address_map &map);
532 
533 	void copro_sharc_map(address_map &map);
534 
535 	virtual void copro_halt() override;
536 	virtual void copro_boot() override;
537 
538 private:
539 	required_device<sega_billboard_device> m_billboard;
540 };
541 
542 /*****************************
543  *
544  * Model 2C
545  *
546  *****************************/
547 
548 class model2c_state : public model2_state
549 {
550 public:
model2c_state(const machine_config & mconfig,device_type type,const char * tag)551 	model2c_state(const machine_config &mconfig, device_type type, const char *tag)
552 		: model2_state(mconfig, type, tag),
553 		  m_copro_tgpx4(*this, "copro_tgpx4"),
554 		  m_copro_tgpx4_program(*this, "copro_tgpx4_program")
555 	{}
556 
557 	void model2c(machine_config &config);
558 	void model2c_5881(machine_config &config);
559 	void skisuprg(machine_config &config);
560 	void stcc(machine_config &config);
561 	void waverunr(machine_config &config);
562 	void bel(machine_config &config);
563 	void hotd(machine_config &config);
564 	void overrev2c(machine_config &config);
565 	void segawski(machine_config &config);
566 	void topskatr(machine_config &config);
567 
568 protected:
569 	virtual void machine_start() override;
570 	virtual void machine_reset() override;
571 
572 	required_device<mb86235_device> m_copro_tgpx4;
573 	required_shared_ptr<u64> m_copro_tgpx4_program;
574 
575 	void copro_function_port_w(offs_t offset, u32 data);
576 	u32 copro_fifo_r();
577 	void copro_fifo_w(u32 data);
578 
579 	TIMER_DEVICE_CALLBACK_MEMBER(model2c_interrupt);
580 
581 	void model2c_crx_mem(address_map &map);
582 	void model2c_5881_mem(address_map &map);
583 	void copro_tgpx4_map(address_map &map);
584 	void copro_tgpx4_data_map(address_map &map);
585 
586 	virtual void copro_halt() override;
587 	virtual void copro_boot() override;
588 };
589 
590 /*****************************
591  *
592  * Modern polygon renderer
593  *
594  *****************************/
595 
596 struct m2_poly_extra_data
597 {
598 	model2_state *  state;
599 	u32      lumabase;
600 	u32      colorbase;
601 	u32 *    texsheet;
602 	u32      texwidth;
603 	u32      texheight;
604 	u32      texx, texy;
605 	u8       texmirrorx;
606 	u8       texmirrory;
607 };
608 
609 
get_texel(u32 base_x,u32 base_y,int x,int y,u32 * sheet)610 static inline u16 get_texel( u32 base_x, u32 base_y, int x, int y, u32 *sheet )
611 {
612 	u32  baseoffs = ((base_y/2)*512)+(base_x/2);
613 	u32  texeloffs = ((y/2)*512)+(x/2);
614 	u32  offset = baseoffs + texeloffs;
615 	u32  texel = sheet[offset>>1];
616 
617 	if ( offset & 1 )
618 		texel >>= 16;
619 
620 	if ( (y & 1) == 0 )
621 		texel >>= 8;
622 
623 	if ( (x & 1) == 0 )
624 		texel >>= 4;
625 
626 	return (texel & 0x0f);
627 }
628 
629 // 0x10000 = size of the tri_sorted_list array
630 class model2_renderer : public poly_manager<float, m2_poly_extra_data, 4, 0x10000>
631 {
632 public:
633 	typedef void (model2_renderer::*scanline_render_func)(int32_t scanline, const extent_t& extent, const m2_poly_extra_data& object, int threadid);
634 
635 public:
636 	using triangle = model2_state::triangle;
637 
model2_renderer(model2_state & state)638 	model2_renderer(model2_state& state)
639 		: poly_manager<float, m2_poly_extra_data, 4, 0x10000>(state.machine())
640 		, m_state(state)
641 		, m_destmap(512, 512)
642 	{
643 		m_renderfuncs[0] = &model2_renderer::model2_3d_render_0;
644 		m_renderfuncs[1] = &model2_renderer::model2_3d_render_1;
645 		m_renderfuncs[2] = &model2_renderer::model2_3d_render_2;
646 		m_renderfuncs[3] = &model2_renderer::model2_3d_render_3;
647 		m_renderfuncs[4] = &model2_renderer::model2_3d_render_4;
648 		m_renderfuncs[5] = &model2_renderer::model2_3d_render_5;
649 		m_renderfuncs[6] = &model2_renderer::model2_3d_render_6;
650 		m_renderfuncs[7] = &model2_renderer::model2_3d_render_7;
651 		m_xoffs = 90;
652 		m_yoffs = -8;
653 	}
654 
destmap()655 	bitmap_rgb32& destmap() { return m_destmap; }
656 
657 	void model2_3d_render(triangle *tri, const rectangle &cliprect);
set_xoffset(int16 xoffs)658 	void set_xoffset(int16 xoffs) { m_xoffs = xoffs; }
set_yoffset(int16 yoffs)659 	void set_yoffset(int16 yoffs) { m_yoffs = yoffs; }
660 
661 	/* checker = 0, textured = 0, transparent = 0 */
662 	#define MODEL2_FUNC 0
663 	#define MODEL2_FUNC_NAME    model2_3d_render_0
664 	#include "video/model2rd.hxx"
665 	#undef MODEL2_FUNC
666 	#undef MODEL2_FUNC_NAME
667 
668 	/* checker = 0, textured = 0, translucent = 1 */
669 	#define MODEL2_FUNC 1
670 	#define MODEL2_FUNC_NAME    model2_3d_render_1
671 	#include "video/model2rd.hxx"
672 	#undef MODEL2_FUNC
673 	#undef MODEL2_FUNC_NAME
674 
675 	/* checker = 0, textured = 1, translucent = 0 */
676 	#define MODEL2_FUNC 2
677 	#define MODEL2_FUNC_NAME    model2_3d_render_2
678 	#include "video/model2rd.hxx"
679 	#undef MODEL2_FUNC
680 	#undef MODEL2_FUNC_NAME
681 
682 	/* checker = 0, textured = 1, translucent = 1 */
683 	#define MODEL2_FUNC 3
684 	#define MODEL2_FUNC_NAME    model2_3d_render_3
685 	#include "video/model2rd.hxx"
686 	#undef MODEL2_FUNC
687 	#undef MODEL2_FUNC_NAME
688 
689 	/* checker = 1, textured = 0, translucent = 0 */
690 	#define MODEL2_FUNC 4
691 	#define MODEL2_FUNC_NAME    model2_3d_render_4
692 	#include "video/model2rd.hxx"
693 	#undef MODEL2_FUNC
694 	#undef MODEL2_FUNC_NAME
695 
696 	/* checker = 1, textured = 0, translucent = 1 */
697 	#define MODEL2_FUNC 5
698 	#define MODEL2_FUNC_NAME    model2_3d_render_5
699 	#include "video/model2rd.hxx"
700 	#undef MODEL2_FUNC
701 	#undef MODEL2_FUNC_NAME
702 
703 	/* checker = 1, textured = 1, translucent = 0 */
704 	#define MODEL2_FUNC 6
705 	#define MODEL2_FUNC_NAME    model2_3d_render_6
706 	#include "video/model2rd.hxx"
707 	#undef MODEL2_FUNC
708 	#undef MODEL2_FUNC_NAME
709 
710 	/* checker = 1, textured = 1, translucent = 1 */
711 	#define MODEL2_FUNC 7
712 	#define MODEL2_FUNC_NAME    model2_3d_render_7
713 	#include "video/model2rd.hxx"
714 	#undef MODEL2_FUNC
715 	#undef MODEL2_FUNC_NAME
716 
717 	scanline_render_func m_renderfuncs[8];
718 
719 private:
720 	model2_state& m_state;
721 	bitmap_rgb32 m_destmap;
722 	int16_t m_xoffs,m_yoffs;
723 };
724 
725 typedef model2_renderer::vertex_t poly_vertex;
726 
727 
728 /*******************************************
729  *
730  *  Basic Data Types
731  *
732  *******************************************/
733 
734 struct model2_state::plane
735 {
planeplane736 	plane() : normal(0, 0)
737 	{
738 		std::fill(std::begin(normal.p), std::end(normal.p), 0);
739 	}
740 
741 	poly_vertex     normal;
742 	float           distance = 0;
743 };
744 
745 struct model2_state::texture_parameter
746 {
747 	float           diffuse = 0;
748 	float           ambient = 0;
749 	u32             specular_control = 0;
750 	float           specular_scale = 0;
751 };
752 
753 struct model2_state::triangle
754 {
triangletriangle755 	triangle() : v{ { 0, 0 }, { 0, 0 }, { 0, 0 } }
756 	{
757 		for (poly_vertex &vertex : v)
758 			std::fill(std::begin(vertex.p), std::end(vertex.p), 0);
759 	}
760 
761 	void *          next = nullptr;
762 	poly_vertex     v[3];
763 	u16             z = 0;
764 	u16             texheader[4] = { 0, 0, 0, 0 };
765 	u8              luma = 0;
766 	int16_t         viewport[4] = { 0, 0, 0, 0 };
767 	int16_t         center[2] = { 0, 0 };
768 };
769 
770 struct model2_state::quad_m2
771 {
quad_m2quad_m2772 	quad_m2() : v{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }
773 	{
774 		for (poly_vertex &vertex : v)
775 			std::fill(std::begin(vertex.p), std::end(vertex.p), 0);
776 	}
777 
778 	poly_vertex     v[4];
779 	u16             z = 0;
780 	u16             texheader[4] = { 0, 0, 0, 0 };
781 	u8              luma = 0;
782 };
783 
784 /*******************************************
785  *
786  *  Hardware 3D Rasterizer Internal State
787  *
788  *******************************************/
789 
790 #define MAX_TRIANGLES       32768
791 
792 struct model2_state::raster_state
793 {
raster_stateraster_state794 	raster_state()
795 	{
796 		std::fill(std::begin(command_buffer), std::end(command_buffer), 0);
797 		std::fill(std::begin(tri_sorted_list), std::end(tri_sorted_list), nullptr);
798 		std::fill(std::begin(texture_ram), std::end(texture_ram), 0);
799 		std::fill(std::begin(log_ram), std::end(log_ram), 0);
800 	}
801 
802 //  u32             mode = 0;                       // bit 0 = Test Mode, bit 2 = Switch 60Hz(1)/30Hz(0) operation
803 	u16 *           texture_rom = nullptr;          // Texture ROM pointer
804 	u32             texture_rom_mask = 0;           // Texture ROM mask
805 	int16_t         viewport[4] = { 0, 0, 0, 0 };   // View port (startx,starty,endx,endy)
806 	int16_t         center[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; // Centers (eye 0[x,y],1[x,y],2[x,y],3[x,y])
807 	u16             center_sel = 0;                 // Selected center
808 	u32             reverse = 0;                    // Left/Right Reverse
809 	float           z_adjust = 0;                   // ZSort Mode
810 	float           triangle_z = 0;                 // Current Triangle z value
811 	u8              master_z_clip = 0;              // Master Z-Clip value
812 	u32             cur_command = 0;                // Current command
813 	u32             command_buffer[32];             // Command buffer
814 	u32             command_index = 0;              // Command buffer index
815 	triangle        tri_list[MAX_TRIANGLES];        // Triangle list
816 	u32             tri_list_index = 0;             // Triangle list index
817 	triangle *      tri_sorted_list[0x10000];       // Sorted Triangle list
818 	u16             min_z = 0;                      // Minimum sortable Z value
819 	u16             max_z = 0;                      // Maximum sortable Z value
820 	u16             texture_ram[0x10000];           // Texture RAM pointer
821 	u8              log_ram[0x40000];               // Log RAM pointer
822 };
823 
824 /*******************************************
825  *
826  *  Geometry Engine Internal State
827  *
828  *******************************************/
829 
830 struct model2_state::geo_state
831 {
geo_stategeo_state832 	geo_state() : focus(0, 0), light(0, 0)
833 	{
834 		std::fill(std::begin(matrix), std::end(matrix), 0);
835 		std::fill(std::begin(focus.p), std::end(focus.p), 0);
836 		std::fill(std::begin(light.p), std::end(light.p), 0);
837 		std::fill(std::begin(coef_table), std::end(coef_table), 0);
838 		std::fill(std::begin(polygon_ram0), std::end(polygon_ram0), 0);
839 		std::fill(std::begin(polygon_ram1), std::end(polygon_ram1), 0);
840 	}
841 
842 	raster_state *      raster = nullptr;
843 	u32                 mode = 0;                   // bit 0 = Enable Specular, bit 1 = Calculate Normals
844 	u32 *               polygon_rom = nullptr;      // Polygon ROM pointer
845 	u32                 polygon_rom_mask = 0;       // Polygon ROM mask
846 	float               matrix[12];                 // Current Transformation Matrix
847 	poly_vertex         focus;                      // Focus (x,y)
848 	poly_vertex         light;                      // Light Vector
849 	float               lod = 0;                    // LOD
850 	float               coef_table[32];             // Distane Coefficient table
851 	texture_parameter   texture_parameters[32];     // Texture parameters
852 	u32                 polygon_ram0[0x8000];       // Fast Polygon RAM pointer
853 	u32                 polygon_ram1[0x8000];       // Slow Polygon RAM pointer
854 	model2_state *      state = nullptr;
855 };
856 
857 #endif // MAME_INCLUDES_MODEL2_H
858