summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/video/zeus2.h
blob: bfd2cb4cdc289e5812612c83492acfabc5c3f582 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11






                                                                           



                          
 



                                  


                                      
                                              


                             
                             



                                

                                








                                      
                                     


                                     
                                   
                                   
                                    



                                       
                                     
                                 
                                         

                                           
                                           
 
                                                         
                                                         





                                      

                                                                                                            
 
                                                                                           


                                                                                                       
                                                                                           


                                                                                                        
                                                                                 


                                                                                                         







                                                                                  
                                            
 
                                                                                                                           
 
                                                                                      

        
                              
  

                                                




                                      
                                                                                       

                                   
                                                                                    
 


                                                                
                                                                   

       
                                                                                                      
 
                                                                                                       




                                               

                                                                                                                                        


                                    

                                                                                             
 

                                    


                             

                                
                      
                                

                            
                              
                           
                          
 

                                                 
                                                
                                    
                                

                                  
                              
 

                                



                        

                                            



                                                                                 
 







                                                  

                                                                              
                                                                    
                                                                           

                                                                               



                                                                                        
 


                                              
                         
 

                                
 
                              
                             
 

                     



                                                



                                      
                               










                                     


                                              
                                                
         
                                 
                                                             
                 



                                                                 
                                                                               
         










                                                                                                          
                                                                                            
                                                  


                            
                                                     
                                                                      
           
                                                                                
           
 
                                                              
                                               
                                                                    
         
                                                                                                 





                                 
                                                                            

                                                          
                                                                   










                                                                            
                                                                            









                                                                                  
                                                                                   








                                                                            
 
                                                                   
         
                                                                                                                


                                                
                      
                                                                             
         
                                                              






                                                
                                                            


                                                                                                
 



                                                                                                                          







                                                                                                                                       
                      
                                                              





                                                                       
                      
                                                                                    






                                                                         
      

                      
                                                                                          


                                                 
                                                                                     









                                                                               
                                                                                                  


                                                 
                                                                                     







                                                                               
                         
                                                                                           




                                                                                                            
                                                                                           
         
                                                                                                      


                                                     

                                                                                           
         
                                                                                                            

                                                                               
 
                                                                                           



                                                                                                      






                                                                                                      














                                                                                                      
         
 


                         
                                        
 
                          
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************

    Midway Zeus2 Video

**************************************************************************/
#ifndef MAME_VIDEO_ZEUS2_H
#define MAME_VIDEO_ZEUS2_H

#pragma once

#include "video/poly.h"
#include "video/rgbutil.h"
#include "cpu/tms32031/tms32031.h"

/*************************************
*  Constants
*************************************/
#define ZEUS2_VIDEO_CLOCK     XTAL(66'666'700)

#define DUMP_WAVE_RAM       0
#define TRACK_REG_USAGE     0
#define PRINT_TEX_INFO      0

#define WAVERAM0_WIDTH      1024
#define WAVERAM0_HEIGHT     2048

#define WAVERAM1_WIDTH      512
#define WAVERAM1_HEIGHT     1024

/*************************************
*  Type definitions
*************************************/

struct zeus2_poly_extra_data
{
	const void *    palbase;
	const void *    texbase;
	uint16_t          solidcolor;
	uint16_t          transcolor;
	uint16_t          texwidth;
	uint16_t          color;
	uint32_t          srcAlpha;
	uint32_t          dstAlpha;
	uint32_t          ctrl_word;
	uint32_t          ucode_src;
	uint32_t          tex_src;
	bool            texture_alpha;
	bool            texture_rgb555;
	bool            blend_enable;
	int32_t         zbuf_min;
	bool            depth_min_enable;
	bool            depth_test_enable;
	bool            depth_write_enable;
	bool            depth_clear_enable;

	uint8_t(*get_texel)(const void *, int, int, int);
	uint8_t(*get_alpha)(const void *, int, int, int);
};

/*************************************
*  Macros
*************************************/

#define WAVERAM_BLOCK0(blocknum)                ((void *)((uint8_t *)waveram + 8 * (blocknum)))
#define WAVERAM_BLOCK0_EXT(blocknum)                ((void *)((uint8_t *)m_state->waveram + 8 * (blocknum)))

#define WAVERAM_PTR8(base, bytenum)             ((uint8_t *)(base) + BYTE4_XOR_LE(bytenum))
#define WAVERAM_READ8(base, bytenum)            (*WAVERAM_PTR8(base, bytenum))
#define WAVERAM_WRITE8(base, bytenum, data)     do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0)

#define WAVERAM_PTR16(base, wordnum)            ((uint16_t *)(base) + BYTE_XOR_LE(wordnum))
#define WAVERAM_READ16(base, wordnum)           (*WAVERAM_PTR16(base, wordnum))
#define WAVERAM_WRITE16(base, wordnum, data)    do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0)

#define WAVERAM_PTR32(base, dwordnum)           ((uint32_t *)(base) + (dwordnum))
#define WAVERAM_READ32(base, dwordnum)          (*WAVERAM_PTR32(base, dwordnum))
#define WAVERAM_WRITE32(base, dwordnum, data)   do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0)

/*************************************
*  Polygon renderer
*************************************/
class zeus2_device;

class zeus2_renderer : public poly_manager<float, zeus2_poly_extra_data, 4, 10000>
{
public:
	zeus2_renderer(zeus2_device *state);

	void render_poly_8bit(int32_t scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid);

	void zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdata, int logit);

private:
	zeus2_device* m_state;
};
typedef zeus2_renderer::vertex_t z2_poly_vertex;
typedef zeus2_renderer::extent_t z2_poly_extent;

/*************************************
*  Zeus2 Video Device
*************************************/
#define MCFG_ZEUS2_VBLANK_CB(_devcb) \
	devcb = &downcast<zeus2_device &>(*device).set_vblank_callback(DEVCB_##_devcb);

#define MCFG_ZEUS2_IRQ_CB(_devcb) \
	devcb = &downcast<zeus2_device &>(*device).set_irq_callback(DEVCB_##_devcb);

#define MCFG_ZEUS2_FLOAT_MODE(_mode) \
	downcast<zeus2_device *>(device)->set_float_mode(_mode);

class zeus2_device : public device_t, public device_video_interface
{
public:
	zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	DECLARE_READ32_MEMBER( zeus2_r );
	DECLARE_WRITE32_MEMBER( zeus2_w );
	TIMER_CALLBACK_MEMBER(display_irq_off);
	TIMER_CALLBACK_MEMBER(display_irq);

	template <class Object> devcb_base &set_vblank_callback(Object &&cb) { return m_vblank.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq.set_callback(std::forward<Object>(cb)); }
	devcb_write_line   m_vblank;
	devcb_write_line   m_irq;

	void set_float_mode(int mode) { m_atlantis = mode; }
	int m_atlantis; // Used to switch to using IEEE754 floating point format for atlantis

	uint32_t m_zeusbase[0x80];
	uint32_t m_renderRegs[0x50];

	zeus2_renderer* poly;

	rectangle zeus_cliprect;

	int m_palSize;
	float zeus_matrix[3][3];
	float zeus_trans[4];
	float zeus_light[3];
	uint32_t zeus_texbase;
	int zeus_quad_size;
	bool m_useZOffset;

	uint32_t *waveram;
	std::unique_ptr<uint32_t[]> m_frameColor;
	std::unique_ptr<int32_t[]> m_frameDepth;
	uint32_t m_pal_table[0x100];
	uint32_t m_ucode[0x200];
	uint32_t m_curUCodeSrc;
	uint32_t m_curPalTableSrc;
	uint32_t m_texmodeReg;

	emu_timer *int_timer;
	emu_timer *vblank_timer;
	int yoffs;
	int texel_width;
	float zbase;

	enum { THEGRID, CRUSNEXO, MWSKINS };
	int m_system;
#if PRINT_TEX_INFO
	void check_tex(uint32_t &texmode, float &zObj, float &zMat, float &zOff);
	std::string tex_info(void);
#endif

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_stop() override;

private:
	TIMER_CALLBACK_MEMBER(int_timer_callback);
	void zeus2_register32_w(offs_t offset, uint32_t data, int logit);
	void zeus2_register_update(offs_t offset, uint32_t oldval, int logit);
	bool zeus2_fifo_process(const uint32_t *data, int numwords);
	void zeus2_pointer_write(uint8_t which, uint32_t value, int logit);
	void load_pal_table(void *wavePtr, uint32_t ctrl, int type, int logit);
	void load_ucode(void *wavePtr, uint32_t ctrl, int logit);
	void zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit);
	void log_fifo_command(const uint32_t *data, int numwords, const char *suffix);
	void print_fifo_command(const uint32_t *data, int numwords, const char *suffix);
	void log_render_info(uint32_t texdata);

	/*************************************
	*  Member variables
	*************************************/
	uint8_t log_fifo;

	uint32_t zeus_fifo[20];
	uint8_t zeus_fifo_words;

	uint32_t m_fill_color;
	int32_t m_fill_depth;

	int m_yScale;

#if PRINT_TEX_INFO
	std::map<uint32_t, std::string> tex_map;
#endif

#if TRACK_REG_USAGE
	struct reg_info
	{
		struct reg_info *next;
		uint32_t value;
	};

	reg_info *regdata[0x80];
	int regdata_count[0x80];
	int regread_count[0x80];
	int regwrite_count[0x80];
	reg_info *subregdata[0x100];
	int subregdata_count[0x80];
	int subregwrite_count[0x100];
#endif
public:
	/*************************************
	*  Inlines for block addressing
	*************************************/
	inline float convert_float(uint32_t val)
	{
		if (m_atlantis) {
			return reinterpret_cast<float&>(val);
		}
		else
			return tms3203x_device::fp_to_float(val);
	}

	inline uint32_t frame_addr_from_xy(uint32_t x, uint32_t y, bool render)
	{
		uint32_t addr;
		if (render) {
			// Rendering is y location
			addr = m_renderRegs[0x4] << (9 + m_yScale);
		}
		else {
			// y.16:x.16 row/col
			// Ignore col for now
			addr = m_zeusbase[0x38] >> (16 - 9 - 2 * m_yScale);
		}
		//uint32_t addr = render ? frame_addr_from_phys_addr(m_renderRegs[0x4] << (15 + m_yScale))
		//  : frame_addr_from_phys_addr((m_zeusbase[0x38] >> 1) << (m_yScale << 1));
		addr += (y << (9 + m_yScale)) + x;
		return addr;
	}

	// Convert 0xRRRRCCCC to frame buffer address
	//inline uint32_t frame_addr_from_expanded_addr(uint32_t addr)
	//{
	//  return (((addr & 0x3ff0000) >> (16 - 9 + 1)) | (addr & 0x1ff)) << 1;
	//}

	// Convert Physical 0xRRRRCCCC to frame buffer address
	// Based on address reg 51 (no scaling)
	inline uint32_t frame_addr_from_phys_addr(uint32_t physAddr)
	{
		uint32_t addr = (((physAddr & 0x3ff0000) >> (16 - 9)) | (physAddr & 0x1ff)) << 1;
		return addr;
	}

	// Read from frame buffer
	inline void frame_read()
	{
		uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]);
		m_zeusbase[0x58] = m_frameColor[addr];
		m_zeusbase[0x59] = m_frameColor[addr + 1];
		m_zeusbase[0x5a] = *(uint32_t*)&m_frameDepth[addr];
		if (m_zeusbase[0x5e] & 0x40)
		{
			m_zeusbase[0x51]++;
			m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
			m_zeusbase[0x51] &= ~0xfe00;
		}
	}

	// Write to frame buffer
	inline void frame_write()
	{
		uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]);
		if (m_zeusbase[0x57] & 0x1)
			m_frameColor[addr] = m_zeusbase[0x58];
		if (m_zeusbase[0x5e] & 0x20) {
			if (m_zeusbase[0x57] & 0x4)
				m_frameColor[addr + 1] = m_zeusbase[0x5a];
		} else
		{
			if (m_zeusbase[0x57] & 0x4)
					m_frameColor[addr + 1] = m_zeusbase[0x59];
			if (m_zeusbase[0x57] & 0x10)
				*(uint32_t*)&m_frameDepth[addr] = m_zeusbase[0x5a];
		}

		if (m_zeusbase[0x5e] & 0x40)
		{
			m_zeusbase[0x51]++;
			m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
			m_zeusbase[0x51] &= ~0xfe00;
		}
	}

	inline void *waveram0_ptr_from_expanded_addr(uint32_t addr)
	{
		uint32_t blocknum = (addr % WAVERAM0_WIDTH) + ((addr >> 16) % WAVERAM0_HEIGHT) * WAVERAM0_WIDTH;
		return WAVERAM_BLOCK0(blocknum);
	}

#ifdef UNUSED_FUNCTION
	inline void *waveram0_ptr_from_texture_addr(uint32_t addr, int width)
	{
		uint32_t blocknum = ((addr & ~1) * width) / 8;
		return WAVERAM_BLOCK0(blocknum);
	}
#endif

	/*************************************
	*  Inlines for rendering
	*************************************/
	inline uint32_t conv_rgb555_to_rgb32(uint16_t color)
	{
		return ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x1f) << 3);
	}

	inline uint32_t conv_rgb565_to_rgb32(uint16_t color)
	{
		return ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x8000) >> 5) | ((color & 0x1f) << 3);
	}
	inline uint32_t conv_rgb332_to_rgb32(uint8_t color)
	{
		uint32_t result;
		result =  ((((color) >> 0) & 0xe0) | (((color) >> 3) & 0x1c) | (((color) >> 6) & 0x03)) << 16;
		result |= ((((color) << 3) & 0xe0) | (((color) >> 0) & 0x1c) | (((color) >> 3) & 0x03)) << 8;
		result |= ((((color) << 6) & 0xc0) | (((color) << 4) & 0x30) | (((color) << 2) & 0x0c) | (((color) << 0) & 0x03)) << 0;
		return result;
	}
#ifdef UNUSED_FUNCTION
	inline void WAVERAM_plot(int y, int x, uint32_t color)
	{
		if (zeus_cliprect.contains(x, y))
			WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
	}
#endif

#ifdef UNUSED_FUNCTION
	inline void waveram_plot_depth(int y, int x, uint32_t color, uint16_t depth)
	{
		if (zeus_cliprect.contains(x, y))
		{
			WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
			WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth);
		}
	}
#endif

#ifdef UNUSED_FUNCTION
	inline void waveram_plot_check_depth(int y, int x, uint32_t color, uint16_t depth)
	{
		if (zeus_cliprect.contains(x, y))
		{
			uint16_t *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
			if (depth <= *depthptr)
			{
				WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
				*depthptr = depth;
			}
		}
	}
#endif

#ifdef UNUSED_FUNCTION
	inline void waveram_plot_check_depth_nowrite(int y, int x, uint32_t color, uint16_t depth)
	{
		if (zeus_cliprect.contains(x, y))
		{
			uint16_t *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
			if (depth <= *depthptr)
				WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
		}
	}
#endif
	/*************************************
	*  Inlines for texel accesses
	*************************************/
	// 4x2 block size
	static inline uint8_t get_texel_4bit_4x2(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3);
		return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f;
	}

	static inline uint8_t get_texel_8bit_4x2(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3);
		return WAVERAM_READ8(base, byteoffs);
	}

	// 2x2 block size within 32 bits, 2 2x2 blocks stacked in y in 64 bits
	static inline uint8_t get_texel_4bit_2x2(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 4) * (width * 4) + ((x / 4) << 3) + ((y & 3) << 1) + ((x / 2) & 1);
		return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f;
	}

	static inline uint8_t get_texel_8bit_2x2(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 4) * (width * 4) + ((x / 2) << 3) + ((y & 3) << 1) + (x & 1);
		return WAVERAM_READ8(base, byteoffs);
	}
	// 2x2 block size of texel, alpha in 64 bits
	// 8 Bit texel, 8 bit alpha
	static inline uint8_t get_texel_8bit_2x2_alpha(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1);
		// Only grab RGB value for now
		byteoffs <<= 1;
		return WAVERAM_READ8(base, byteoffs + 0);
	}
	static inline uint8_t get_alpha_8bit_2x2_alpha(const void *base, int y, int x, int width)
	{
		uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1);
		// Only grab Alpha value for now
		byteoffs <<= 1;
		return WAVERAM_READ8(base, byteoffs + 1);
	}
	// 2x2 block size of r5g5r5 in 64 bits
	static inline uint32_t get_rgb555(const void *base, int y, int x, int width)
	{
		uint32_t wordoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1);
		uint16_t color = WAVERAM_READ16(base, wordoffs);
		return ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x1f) << 3);
	}

};

// device type definition
DECLARE_DEVICE_TYPE(ZEUS2, zeus2_device)

#endif // MAME_VIDEO_ZEUS2