summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/jagblit.hxx
blob: 86c3bc9d8d7cf228954c34216e9bd96422ffa51c (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

                                











                                                                            
                          




                                                                             
                                                        


               
                                                       


               
                                                       


               
                                                       



                                                  
                                                                                                                                                          
                                          
                                                                                                                                                                              
                                                                                                                             
                                          

                                                  
                                                                                                                                                          
                                          
                                                                                                                                                                              
                                                                                                                             
                                          

                                                  
                                                                                                                                                          
                                          
                                                                                                                                                                              
                                                                                                                             
                                          
 
                                                                                                                                                      
                                                                 
                                                                                                                                               

                                                                                                
 
                                                                                                                                                      
                                                                  
                                                                                                                                                 

                                                                                                      
 
                                                                                                                                                      
                                                                  
                                                                                                             

                                                                                                       


                                                               




                                                                        


                                                           




                                                                    


                                                           




                                                                    
 



                                                       





                                                                                                                                                                       








                                                                          
                                                                                                                                                                                                                                                                                                                    
                                      
                                                                                                                                                                                                                                                                                                                    
                                      
                                                                                                                                                                                                                                                                                                                    










                                                                                                                                                           

            





                                                                                 

                   
                          

            





                                                                                 


                   
                                                                                 
 
























                                                                                                                                                            
 

                                                           

                         

                                   
 
                                                                           



















                                                                               
 







                                               

                                                                                                  























                                               

                                                                                   




                                                      

                                                             


                                 

                                                                 


                                 

                                                                

         














                                                                                       
 















                                                                     

                      
                                                             



                                                                 





                                                                                             




                                                                 





                                                                                             


                                                                     
         
 
                                              

                                                                                                








                                           




                                               




                                                         
                                                                              
                                                                 
                                                                                       
                                                                     
                                                                                                                    


                                    
                                                                                                          
                                                                
                                                                                                                    




                                                         
                                                                                
                                                                 
                                                                                         
                                            
                                                                                                                      


                                    
                                                                                                             
                                                                 
                                                                                                                      




                                                         


                                                                                                              















                                                                              
                                                                                                                       



                                                                    
                                                                                                                          








                                                                          
                                                                                                                       





















                                                                                                     



                                                                                 
                                                                                                     


















                                                                                                                 



                                                            




                                                                   
                                                                          
                         

































                                                                       



                                                          
 


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

    Atari Jaguar blitter

****************************************************************************

    How to use this module:

    #define FUNCNAME -- name of the function to be generated
    #define COMMAND  -- blitter command bits for blitter
    #define A1FIXED  -- fixed A1 flag bits for blitter
    #define A2FIXED  -- fixed A2 flag bits for blitter
    #include "jagblit.hxx"

****************************************************************************/


#ifndef FUNCNAME
#error jagblit.inc -- requires FUNCNAME to be predefined
#endif

#ifndef COMMAND
#error jagblit.inc -- requires COMMAND to be predefined
#endif

#ifndef A1FIXED
#error jagblit.inc -- requires A1FIXED to be predefined
#endif

#ifndef A2FIXED
#error jagblit.inc -- requires A2FIXED to be predefined
#endif

#ifndef PIXEL_SHIFT_1
#define PIXEL_SHIFT_1(a)      ((~a##_x >> 16) & 7)
#define PIXEL_OFFSET_1(a)     (((uint32_t)a##_y >> 16) * a##_width / 8 + (((uint32_t)a##_x >> 19) & ~7) * (1 + a##_pitch) + (((uint32_t)a##_x >> 19) & 7))
#define ZDATA_OFFSET_1(a)     0 /* huh? */
#define READ_RDATA_1(r,a,p)   ((p) ? (((((uint8_t *)&m_blitter_regs[r])[BYTE4_XOR_BE(((uint32_t)a##_x >> 19) & 7)]) >> PIXEL_SHIFT_1(a)) & 0x01) : (m_blitter_regs[r] & 0x01))
#define READ_PIXEL_1(a)       ((m_gpu->space(AS_PROGRAM).read_byte(a##_base + PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
#define READ_ZDATA_1(a)       0 /* huh? */

#define PIXEL_SHIFT_2(a)      ((~a##_x >> 15) & 6)
#define PIXEL_OFFSET_2(a)     (((uint32_t)a##_y >> 16) * a##_width / 4 + (((uint32_t)a##_x >> 18) & ~7) * (1 + a##_pitch) + (((uint32_t)a##_x >> 18) & 7))
#define ZDATA_OFFSET_2(a)     0 /* huh? */
#define READ_RDATA_2(r,a,p)   ((p) ? (((((uint8_t *)&m_blitter_regs[r])[BYTE4_XOR_BE(((uint32_t)a##_x >> 18) & 7)]) >> PIXEL_SHIFT_2(a)) & 0x03) : (m_blitter_regs[r] & 0x03))
#define READ_PIXEL_2(a)       ((m_gpu->space(AS_PROGRAM).read_byte(a##_base + PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
#define READ_ZDATA_2(a)       0 /* huh? */

#define PIXEL_SHIFT_4(a)      ((~a##_x >> 14) & 4)
#define PIXEL_OFFSET_4(a)     (((uint32_t)a##_y >> 16) * a##_width / 2 + (((uint32_t)a##_x >> 17) & ~7) * (1 + a##_pitch) + (((uint32_t)a##_x >> 17) & 7))
#define ZDATA_OFFSET_4(a)     0 /* huh? */
#define READ_RDATA_4(r,a,p)   ((p) ? (((((uint8_t *)&m_blitter_regs[r])[BYTE4_XOR_BE(((uint32_t)a##_x >> 17) & 7)]) >> PIXEL_SHIFT_4(a)) & 0x0f) : (m_blitter_regs[r] & 0x0f))
#define READ_PIXEL_4(a)       ((m_gpu->space(AS_PROGRAM).read_byte(a##_base + PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
#define READ_ZDATA_4(a)       0 /* huh? */

#define PIXEL_OFFSET_8(a)     (((uint32_t)a##_y >> 16) * a##_width + (((uint32_t)a##_x >> 16) & ~7) * (1 + a##_pitch) + (((uint32_t)a##_x >> 16) & 7))
#define ZDATA_OFFSET_8(a)     (PIXEL_OFFSET_8(a) + a##_zoffs * 8)
#define READ_RDATA_8(r,a,p)   ((p) ? (((uint8_t *)&m_blitter_regs[r])[BYTE4_XOR_BE(((uint32_t)a##_x >> 16) & 7)]) : (m_blitter_regs[r] & 0xff))
#define READ_PIXEL_8(a)       (m_gpu->space(AS_PROGRAM).read_byte(a##_base + PIXEL_OFFSET_8(a)))
#define READ_ZDATA_8(a)       (m_gpu->space(AS_PROGRAM).read_byte(a##_base + ZDATA_OFFSET_8(a)))

#define PIXEL_OFFSET_16(a)    (((uint32_t)a##_y >> 16) * a##_width + (((uint32_t)a##_x >> 16) & ~3) * (1 + a##_pitch) + (((uint32_t)a##_x >> 16) & 3))
#define ZDATA_OFFSET_16(a)    (PIXEL_OFFSET_16(a) + a##_zoffs * 4)
#define READ_RDATA_16(r,a,p)  ((p) ? (((uint16_t *)&m_blitter_regs[r])[BYTE_XOR_BE(((uint32_t)a##_x >> 16) & 3)]) : (m_blitter_regs[r] & 0xffff))
#define READ_PIXEL_16(a)      (m_gpu->space(AS_PROGRAM).read_word(a##_base + (PIXEL_OFFSET_16(a)<<1)))
#define READ_ZDATA_16(a)      (m_gpu->space(AS_PROGRAM).read_word(a##_base + (ZDATA_OFFSET_16(a)<<1)))

#define PIXEL_OFFSET_32(a)    (((uint32_t)a##_y >> 16) * a##_width + (((uint32_t)a##_x >> 16) & ~1) * (1 + a##_pitch) + (((uint32_t)a##_x >> 16) & 1))
#define ZDATA_OFFSET_32(a)    (PIXEL_OFFSET_32(a) + a##_zoffs * 2)
#define READ_RDATA_32(r,a,p)  ((p) ? (m_blitter_regs[r + (((uint32_t)a##_x >> 16) & 1)]) : m_blitter_regs[r])
#define READ_PIXEL_32(a)      (m_gpu->space(AS_PROGRAM).read_dword(a##_base + (PIXEL_OFFSET_32(a)<<2)))
#define READ_ZDATA_32(a)      (m_gpu->space(AS_PROGRAM).read_dword(a##_base + (ZDATA_OFFSET_32(a)<<2)))

#define READ_RDATA(r,a,f,p) \
	((((f) & 0x38) == (0 << 3)) ? (READ_RDATA_1(r,a,p)) : \
		(((f) & 0x38) == (1 << 3)) ? (READ_RDATA_2(r,a,p)) : \
		(((f) & 0x38) == (2 << 3)) ? (READ_RDATA_4(r,a,p)) : \
		(((f) & 0x38) == (3 << 3)) ? (READ_RDATA_8(r,a,p)) : \
		(((f) & 0x38) == (4 << 3)) ? (READ_RDATA_16(r,a,p)) : \
		(((f) & 0x38) == (5 << 3)) ? (READ_RDATA_32(r,a,p)) : 0)

#define READ_PIXEL(a,f) \
	((((f) & 0x38) == (0 << 3)) ? (READ_PIXEL_1(a)) : \
		(((f) & 0x38) == (1 << 3)) ? (READ_PIXEL_2(a)) : \
		(((f) & 0x38) == (2 << 3)) ? (READ_PIXEL_4(a)) : \
		(((f) & 0x38) == (3 << 3)) ? (READ_PIXEL_8(a)) : \
		(((f) & 0x38) == (4 << 3)) ? (READ_PIXEL_16(a)) : \
		(((f) & 0x38) == (5 << 3)) ? (READ_PIXEL_32(a)) : 0)

#define READ_ZDATA(a,f) \
	((((f) & 0x38) == (0 << 3)) ? (READ_ZDATA_1(a)) : \
		(((f) & 0x38) == (1 << 3)) ? (READ_ZDATA_2(a)) : \
		(((f) & 0x38) == (2 << 3)) ? (READ_ZDATA_4(a)) : \
		(((f) & 0x38) == (3 << 3)) ? (READ_ZDATA_8(a)) : \
		(((f) & 0x38) == (4 << 3)) ? (READ_ZDATA_16(a)) : \
		(((f) & 0x38) == (5 << 3)) ? (READ_ZDATA_32(a)) : 0)

#define PIXEL_SHIFT_WRITE_1      ((~adest_x >> 16) & 7)
#define PIXEL_SHIFT_WRITE_2      ((~adest_x >> 15) & 6)
#define PIXEL_SHIFT_WRITE_4      ((~adest_x >> 14) & 4)

#define PIXEL_OFFSET_WRITE_1     (((uint32_t)adest_y >> 16) * adest_width / 8 + (((uint32_t)adest_x >> 19) & ~7) * (1 + adest_pitch) + (((uint32_t)adest_x >> 19) & 7))
#define PIXEL_OFFSET_WRITE_2     (((uint32_t)adest_y >> 16) * adest_width / 4 + (((uint32_t)adest_x >> 18) & ~7) * (1 + adest_pitch) + (((uint32_t)adest_x >> 18) & 7))
#define PIXEL_OFFSET_WRITE_4     (((uint32_t)adest_y >> 16) * adest_width / 2 + (((uint32_t)adest_x >> 17) & ~7) * (1 + adest_pitch) + (((uint32_t)adest_x >> 17) & 7))
#define PIXEL_OFFSET_WRITE_8     (((uint32_t)adest_y >> 16) * adest_width + (((uint32_t)adest_x >> 16) & ~7) * (1 + adest_pitch) + (((uint32_t)adest_x >> 16) & 7))
#define PIXEL_OFFSET_WRITE_16    (((uint32_t)adest_y >> 16) * adest_width + (((uint32_t)adest_x >> 16) & ~3) * (1 + adest_pitch) + (((uint32_t)adest_x >> 16) & 3))
#define PIXEL_OFFSET_WRITE_32    (((uint32_t)adest_y >> 16) * adest_width + (((uint32_t)adest_x >> 16) & ~1) * (1 + adest_pitch) + (((uint32_t)adest_x >> 16) & 1))

#define ZDATA_OFFSET_WRITE_1     0 /* huh? */
#define ZDATA_OFFSET_WRITE_2     0 /* huh? */
#define ZDATA_OFFSET_WRITE_4     0 /* huh? */
#define ZDATA_OFFSET_WRITE_8     (PIXEL_OFFSET_WRITE_8 + adest_zoffs * 8)
#define ZDATA_OFFSET_WRITE_16    (PIXEL_OFFSET_WRITE_16 + adest_zoffs * 4)
#define ZDATA_OFFSET_WRITE_32    (PIXEL_OFFSET_WRITE_32 + adest_zoffs * 2)


#define WRITE_PIXEL_1(d)    do { int writeoffs = PIXEL_OFFSET_WRITE_1; int shift = PIXEL_SHIFT_WRITE_1; uint8_t pix = m_gpu->space(AS_PROGRAM).read_byte(adest_base + (writeoffs)); pix = (pix & ~(0x01 << shift)) | ((d) << shift); m_gpu->space(AS_PROGRAM).write_byte(adest_base + (writeoffs), pix); } while (0)
#define WRITE_ZDATA_1(d)    /* huh? */
#define WRITE_PIXEL_2(d)    do { int writeoffs = PIXEL_OFFSET_WRITE_2; int shift = PIXEL_SHIFT_WRITE_2; uint8_t pix = m_gpu->space(AS_PROGRAM).read_byte(adest_base + (writeoffs)); pix = (pix & ~(0x03 << shift)) | ((d) << shift); m_gpu->space(AS_PROGRAM).write_byte(adest_base + (writeoffs), pix); } while (0)
#define WRITE_ZDATA_2(d)    /* huh? */
#define WRITE_PIXEL_4(d)    do { int writeoffs = PIXEL_OFFSET_WRITE_4; int shift = PIXEL_SHIFT_WRITE_4; uint8_t pix = m_gpu->space(AS_PROGRAM).read_byte(adest_base + (writeoffs)); pix = (pix & ~(0x0f << shift)) | ((d) << shift); m_gpu->space(AS_PROGRAM).write_byte(adest_base + (writeoffs), pix); } while (0)
#define WRITE_ZDATA_4(d)    /* huh? */
#define WRITE_PIXEL_8(d)    do { int writeoffs = PIXEL_OFFSET_WRITE_8;  m_gpu->space(AS_PROGRAM).write_byte(adest_base + (writeoffs), (d)); } while (0)
#define WRITE_ZDATA_8(d)    do { int writeoffs = ZDATA_OFFSET_WRITE_8;  m_gpu->space(AS_PROGRAM).write_byte(adest_base + (writeoffs), (d)); } while (0)
#define WRITE_PIXEL_16(d)   do { int writeoffs = PIXEL_OFFSET_WRITE_16; m_gpu->space(AS_PROGRAM).write_word(adest_base + (writeoffs<<1), (d)); } while (0)
#define WRITE_ZDATA_16(d)   do { int writeoffs = ZDATA_OFFSET_WRITE_16; m_gpu->space(AS_PROGRAM).write_word(adest_base + (writeoffs<<1), (d)); } while (0)
#define WRITE_PIXEL_32(d)   do { int writeoffs = PIXEL_OFFSET_WRITE_32; m_gpu->space(AS_PROGRAM).write_dword(adest_base + (writeoffs<<2), (d)); } while (0)
#define WRITE_ZDATA_32(d)   do { int writeoffs = ZDATA_OFFSET_WRITE_32; m_gpu->space(AS_PROGRAM).write_dword(adest_base + (writeoffs<<2), (d)); } while (0)



#define WRITE_PIXEL(f,d) \
	do \
	{ \
				if (((f) & 0x38) == (0 << 3)) WRITE_PIXEL_1(d); \
		else if (((f) & 0x38) == (1 << 3)) WRITE_PIXEL_2(d); \
		else if (((f) & 0x38) == (2 << 3)) WRITE_PIXEL_4(d); \
		else if (((f) & 0x38) == (3 << 3)) WRITE_PIXEL_8(d); \
		else if (((f) & 0x38) == (4 << 3)) WRITE_PIXEL_16(d); \
		else if (((f) & 0x38) == (5 << 3)) WRITE_PIXEL_32(d); \
	} while (0)

#define WRITE_ZDATA(f,d) \
	do \
	{ \
				if (((f) & 0x38) == (0 << 3)) WRITE_ZDATA_1(d); \
		else if (((f) & 0x38) == (1 << 3)) WRITE_ZDATA_2(d); \
		else if (((f) & 0x38) == (2 << 3)) WRITE_ZDATA_4(d); \
		else if (((f) & 0x38) == (3 << 3)) WRITE_ZDATA_8(d); \
		else if (((f) & 0x38) == (4 << 3)) WRITE_ZDATA_16(d); \
		else if (((f) & 0x38) == (5 << 3)) WRITE_ZDATA_32(d); \
	} while (0)
#endif

void jaguar_state::FUNCNAME(uint32_t command, uint32_t a1flags, uint32_t a2flags)
{
	uint32_t a1_base = m_blitter_regs[A1_BASE] & ~0x7;
	int32_t a1_pitch = (A1FIXED & 3) ^ ((A1FIXED & 2) >> 1);
	int32_t a1_zoffs = (A1FIXED >> 6) & 7;
	int32_t a1_width = ((4 | ((a1flags >> 9) & 3)) << ((a1flags >> 11) & 15)) >> 2;
	int32_t a1_xadd = (A1FIXED >> 16) & 0x03;
	int32_t a1_yadd = (A1FIXED >> 18) & 0x01;
	int32_t a1_x = (m_blitter_regs[A1_PIXEL] << 16) | (m_blitter_regs[A1_FPIXEL] & 0xffff);
	int32_t a1_y = (m_blitter_regs[A1_PIXEL] & 0xffff0000) | (m_blitter_regs[A1_FPIXEL] >> 16);
	int32_t a1_xstep = 0;
	int32_t a1_ystep = 0;
	uint32_t a1_xmask = 0xffffffff;
	uint32_t a1_ymask = 0xffffffff;

	uint32_t a2_base = m_blitter_regs[A2_BASE] & ~0x7;
	int32_t a2_pitch = (A2FIXED & 3) ^ ((A2FIXED & 2) >> 1);
	int32_t a2_zoffs = (A2FIXED >> 6) & 7;
	int32_t a2_width = ((4 | ((a2flags >> 9) & 3)) << ((a2flags >> 11) & 15)) >> 2;
	int32_t a2_xadd = (A2FIXED >> 16) & 0x03;
	int32_t a2_yadd = (A1FIXED >> 18) & 0x01;     // From Jaguar HW errata: "If the A1 Y add control bit is set it will affect both address generators."
	int32_t a2_x = (m_blitter_regs[A2_PIXEL] << 16);
	int32_t a2_y = (m_blitter_regs[A2_PIXEL] & 0xffff0000);
	int32_t a2_xstep = 0;
	int32_t a2_ystep = 0;
	uint32_t a2_xmask = 0xffffffff;
	uint32_t a2_ymask = 0xffffffff;

	int inner_count = m_blitter_regs[B_COUNT] & 0xffff;
	int outer_count = m_blitter_regs[B_COUNT] >> 16;
	int inner, outer;

	uint8_t a1_phrase_mode = 0;
	uint8_t a2_phrase_mode = 0;

	uint32_t asrc_base =    (COMMAND & 0x00000800) ? a1_base : a2_base;
	uint32_t asrcflags =      (COMMAND & 0x00000800) ? A1FIXED : A2FIXED;
	int32_t asrc_x =          (COMMAND & 0x00000800) ? a1_x : a2_x;
	int32_t asrc_y =          (COMMAND & 0x00000800) ? a1_y : a2_y;
	int32_t asrc_width =      (COMMAND & 0x00000800) ? a1_width : a2_width;
	int32_t asrc_pitch =      (COMMAND & 0x00000800) ? a1_pitch : a2_pitch;
	int32_t asrc_zoffs =      (COMMAND & 0x00000800) ? a1_zoffs : a2_zoffs;
	uint8_t asrc_phrase_mode;
	int32_t asrc_xadd, asrc_xstep, asrc_yadd, asrc_ystep;
	uint32_t asrc_xmask, asrc_ymask;

	uint32_t adest_base =  (COMMAND & 0x00000800) ? a2_base : a1_base;
	uint32_t adestflags =     (COMMAND & 0x00000800) ? A2FIXED : A1FIXED;
	int32_t adest_x =         (COMMAND & 0x00000800) ? a2_x : a1_x;
	int32_t adest_y =         (COMMAND & 0x00000800) ? a2_y : a1_y;
	int32_t adest_width =     (COMMAND & 0x00000800) ? a2_width : a1_width;
	int32_t adest_pitch =     (COMMAND & 0x00000800) ? a2_pitch : a1_pitch;
	int32_t adest_zoffs =     (COMMAND & 0x00000800) ? a2_zoffs : a1_zoffs;
	uint8_t adest_phrase_mode;
	int32_t adest_xadd, adest_xstep, adest_yadd, adest_ystep;
	uint32_t adest_xmask, adest_ymask;

	/* determine actual xadd/yadd for A1 */
	a1_yadd <<= 16;
	if (A1FIXED & 0x00100000)
		a1_yadd = -a1_yadd;

	a1_phrase_mode = (a1_xadd == 0);
	if (a1_xadd == 3)
	{
		a1_xadd = (m_blitter_regs[A1_INC] << 16) | (m_blitter_regs[A1_FINC] & 0xffff);
		a1_yadd = (m_blitter_regs[A1_INC] & 0xffff0000) | (m_blitter_regs[A1_FINC] >> 16);
	}
	else if (a1_xadd == 2)
		a1_xadd = 0;
	else
		a1_xadd = 1 << 16;
	if (A1FIXED & 0x00080000)
		a1_xadd = -a1_xadd;

	/* determine actual xadd/yadd for A2 */
	a2_yadd <<= 16;
	if (A2FIXED & 0x00100000)
		a2_yadd = -a2_yadd;

	a2_phrase_mode = (a2_xadd == 0);
	if (a2_xadd == 2)
		a2_xadd = 0;
	else
		a2_xadd = 1 << 16;
	if (A2FIXED & 0x00080000)
		a2_xadd = -a2_xadd;

	/* set up the A2 mask */
	if (A2FIXED & 0x00008000)
	{
		a2_xmask = ((m_blitter_regs[A2_MASK] & 0x0000ffff) << 16) | 0xffff;
		a2_ymask = (m_blitter_regs[A2_MASK] & 0xffff0000) | 0xffff;
	}

	/* modify outer loop steps based on command */
	if (command & 0x00000100)
	{
		a1_xstep = m_blitter_regs[A1_FSTEP] & 0xffff;
		a1_ystep = m_blitter_regs[A1_FSTEP] >> 16;
	}
	if (command & 0x00000200)
	{
		a1_xstep += m_blitter_regs[A1_STEP] << 16;
		a1_ystep += m_blitter_regs[A1_STEP] & 0xffff0000;
	}
	if (command & 0x00000400)
	{
		a2_xstep = m_blitter_regs[A2_STEP] << 16;
		a2_ystep = m_blitter_regs[A2_STEP] & 0xffff0000;
	}

	asrc_phrase_mode    = (COMMAND & 0x00000800) ? a1_phrase_mode : a2_phrase_mode;
	asrc_xstep          = (COMMAND & 0x00000800) ? a1_xstep : a2_xstep;
	asrc_ystep          = (COMMAND & 0x00000800) ? a1_ystep : a2_ystep;
	asrc_xadd           = (COMMAND & 0x00000800) ? a1_xadd : a2_xadd;
	asrc_yadd           = (COMMAND & 0x00000800) ? a1_yadd : a2_yadd;
	asrc_xmask          = (COMMAND & 0x00000800) ? a1_xmask : a2_xmask;
	asrc_ymask          = (COMMAND & 0x00000800) ? a1_ymask : a2_ymask;

	adest_phrase_mode   = (COMMAND & 0x00000800) ? a2_phrase_mode : a1_phrase_mode;
	adest_xstep         = (COMMAND & 0x00000800) ? a2_xstep : a1_xstep;
	adest_ystep         = (COMMAND & 0x00000800) ? a2_ystep : a1_ystep;
	adest_xadd          = (COMMAND & 0x00000800) ? a2_xadd : a1_xadd;
	adest_yadd          = (COMMAND & 0x00000800) ? a2_yadd : a1_yadd;
	adest_xmask         = (COMMAND & 0x00000800) ? a2_xmask : a1_xmask;
	adest_ymask         = (COMMAND & 0x00000800) ? a2_ymask : a1_ymask;

	int gouraud_color[4];
	gouraud_color[0] = (m_blitter_regs[B_PATD_H] >> 16) & 0xff00;
	gouraud_color[1] = m_blitter_regs[B_PATD_H] & 0xff00;
	gouraud_color[2] = (m_blitter_regs[B_PATD_L] >> 16) & 0xff00;
	gouraud_color[3] = m_blitter_regs[B_PATD_L] & 0xff00;

	int gouraud_inten[4];
	gouraud_inten[3] = m_blitter_regs[B_I0] & 0xffffff;
	gouraud_inten[2] = m_blitter_regs[B_I1] & 0xffffff;
	gouraud_inten[1] = m_blitter_regs[B_I2] & 0xffffff;
	gouraud_inten[0] = m_blitter_regs[B_I3] & 0xffffff;

	int gouraud_iinc = m_blitter_regs[B_IINC] & 0xffffff;
	if (gouraud_iinc & 0x800000)
		gouraud_iinc |= 0xff000000;

	if (LOG_BLITS)
	{
	logerror("%s:Blit!\n", machine().describe_context());
	logerror("  a1_base  = %08X\n", a1_base);
	logerror("  a1_pitch = %d\n", a1_pitch);
	logerror("  a1_psize = %d\n", 1 << ((A1FIXED >> 3) & 7));
	logerror("  a1_width = %d\n", a1_width);
	logerror("  a1_xadd  = %f (phrase=%d)\n", (double)a1_xadd / 65536.0, a1_phrase_mode);
	logerror("  a1_yadd  = %f\n", (double)a1_yadd / 65536.0);
	logerror("  a1_xstep = %f\n", (double)a1_xstep / 65536.0);
	logerror("  a1_ystep = %f\n", (double)a1_ystep / 65536.0);
	logerror("  a1_x     = %f\n", (double)a1_x / 65536.0);
	logerror("  a1_y     = %f\n", (double)a1_y / 65536.0);

	logerror("  a2_base  = %08X\n", a2_base);
	logerror("  a2_pitch = %d\n", a2_pitch);
	logerror("  a2_psize = %d\n", 1 << ((A2FIXED >> 3) & 7));
	logerror("  a2_width = %d\n", a2_width);
	logerror("  a2_xadd  = %f (phrase=%d)\n", (double)a2_xadd / 65536.0, a2_phrase_mode);
	logerror("  a2_yadd  = %f\n", (double)a2_yadd / 65536.0);
	logerror("  a2_xstep = %f\n", (double)a2_xstep / 65536.0);
	logerror("  a2_ystep = %f\n", (double)a2_ystep / 65536.0);
	logerror("  a2_x     = %f\n", (double)a2_x / 65536.0);
	logerror("  a2_y     = %f\n", (double)a2_y / 65536.0);

	logerror("  count    = %d x %d\n", inner_count, outer_count);
	logerror("  command  = %08X\n", COMMAND);
	}

	/* check for unhandled command bits */
	if ((COMMAND & 0x24003000) && LOG_UNHANDLED_BLITS)
		logerror("Blitter unhandled: these command bits: %08X\n", COMMAND & 0x24003000);

	/* top of the outer loop */
	outer = outer_count;
	while (outer--)
	{
		/* top of the inner loop */
		inner = inner_count;
		while (inner--)
		{
			uint32_t srcdata;
			uint32_t srczdata = 0;
			uint32_t dstdata;
			uint32_t dstzdata = 0;
			uint32_t writedata = 0;
			int inhibit = 0;

				/* load src data and Z */
				if (COMMAND & 0x00000001)
				{
					srcdata = READ_PIXEL(asrc, asrcflags);
					if (COMMAND & 0x00000002)
						srczdata = READ_ZDATA(asrc, asrcflags);
					else if (COMMAND & 0x001c020)
						srczdata = READ_RDATA(B_SRCZ1_H, asrc, asrcflags, asrc_phrase_mode);
				}
				else
				{
					srcdata = READ_RDATA(B_SRCD_H, asrc, asrcflags, asrc_phrase_mode);
					if (COMMAND & 0x001c020)
						srczdata = READ_RDATA(B_SRCZ1_H, asrc, asrcflags, asrc_phrase_mode);
				}

				/* load dst data and Z */
				if (COMMAND & 0x00000008)
				{
					dstdata = READ_PIXEL(adest, adestflags);
					if (COMMAND & 0x00000010)
						dstzdata = READ_ZDATA(adest, adestflags);
					else
						dstzdata = READ_RDATA(B_DSTZ_H, adest, adestflags, adest_phrase_mode);
				}
				else
				{
					dstdata = READ_RDATA(B_DSTD_H, adest, adestflags, adest_phrase_mode);
					if (COMMAND & 0x00000010)
						dstzdata = READ_RDATA(B_DSTZ_H, adest, adestflags, adest_phrase_mode);
				}

				/* handle clipping */
				if (COMMAND & 0x00000040)
				{
					if (adest_x < 0 || adest_y < 0 ||
						(adest_x >> 16) >= (m_blitter_regs[A1_CLIP] & 0x7fff) ||
						(adest_y >> 16) >= ((m_blitter_regs[A1_CLIP] >> 16) & 0x7fff))
						inhibit = 1;
				}

				/* apply Z comparator */
				if (COMMAND & 0x00040000)
					if (srczdata < dstzdata) inhibit = 1;
				if (COMMAND & 0x00080000)
					if (srczdata == dstzdata) inhibit = 1;
				if (COMMAND & 0x00100000)
					if (srczdata > dstzdata) inhibit = 1;

				/* apply data comparator */
				if (COMMAND & 0x08000000)
				{
					if (!(COMMAND & 0x02000000))
					{
						if (srcdata == READ_RDATA(B_PATD_H, asrc, asrcflags, asrc_phrase_mode))
							inhibit = 1;
					}
					else
					{
						if (dstdata == READ_RDATA(B_PATD_H, adest, adestflags, adest_phrase_mode))
							inhibit = 1;
					}
				}

				/* compute the write data and store */
				if (!inhibit)
				{
					/* handle patterns/additive/LFU */
					if (COMMAND & 0x00010000)
						writedata = READ_RDATA(B_PATD_H, adest, adestflags, adest_phrase_mode);
					else if (COMMAND & 0x00020000)
					{
						writedata = (srcdata & 0xff) + (dstdata & 0xff);
						if (!(COMMAND & 0x00004000) && writedata > 0xff)
							writedata = 0xff;
						writedata |= (srcdata & 0xf00) + (dstdata & 0xf00);
						if (!(COMMAND & 0x00008000) && writedata > 0xfff)
							writedata = 0xfff;
						writedata |= (srcdata & 0xf000) + (dstdata & 0xf000);
					}
					else
					{
						if (COMMAND & 0x00200000)
							writedata |= ~srcdata & ~dstdata;
						if (COMMAND & 0x00400000)
							writedata |= ~srcdata & dstdata;
						if (COMMAND & 0x00800000)
							writedata |= srcdata & ~dstdata;
						if (COMMAND & 0x01000000)
							writedata |= srcdata & dstdata;
					}

					/* handle source shading */
					if (COMMAND & 0x40000000)
					{
						int intensity = srcdata & 0x00ff;
						intensity += (int8_t) (m_blitter_regs[B_IINC] >> 16);
						if (intensity < 0)
							intensity = 0;
						else if (intensity > 0xff)
							intensity = 0xff;
						writedata = (srcdata & 0xff00) | intensity;
					}

					/* handle gouraud shading */
					if (COMMAND & 0x1000)
					{
						int p = asrc_phrase_mode ? (asrc_x & 3) : 3;
						writedata = ((gouraud_inten[p] >> 16) & 0xff) | gouraud_color[p];

						int intensity = gouraud_inten[p];
						intensity += gouraud_iinc;
						if (intensity < 0) intensity = 0;
						if (intensity > 0xffffff) intensity = 0xffffff;
						gouraud_inten[p] = intensity;
					}
				}
				else
					writedata = dstdata;

			if ((command & 0x10000000) || !inhibit)
			{
				/* write to the destination */
				WRITE_PIXEL(adestflags, writedata);
				if (COMMAND & 0x00000020)
					WRITE_ZDATA(adestflags, srczdata);
			}

				/* update X/Y */
			asrc_x = (asrc_x + asrc_xadd) & asrc_xmask;
			asrc_y = (asrc_y + asrc_yadd) & asrc_ymask;
			adest_x = (adest_x + adest_xadd) & adest_xmask;
			adest_y = (adest_y + adest_yadd) & adest_ymask;
		}

		/* adjust for phrase mode */
		if (asrc_phrase_mode)
		{
			if (asrc_xadd > 0)
				asrc_x += 3 << 16;
			else
				asrc_x -= 3 << 16;
			asrc_x &= ~(3 << 16);
		}
		if (adest_phrase_mode)
		{
			if (adest_xadd > 0)
				adest_x += 3 << 16;
			else
				adest_x -= 3 << 16;
			adest_x &= ~(3 << 16);
		}

		/* update for outer loop */
		asrc_x += asrc_xstep;
		asrc_y += asrc_ystep;
		adest_x += adest_xstep;
		adest_y += adest_ystep;
	}

	/* write values back to registers */
	a1_x =  (COMMAND & 0x00000800) ? asrc_x : adest_x;
	a1_y =  (COMMAND & 0x00000800) ? asrc_y : adest_y;
	a2_x =  (COMMAND & 0x00000800) ? adest_x : asrc_x;
	a2_y =  (COMMAND & 0x00000800) ? adest_y : asrc_y;

	m_blitter_regs[A1_PIXEL] = (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff);
	m_blitter_regs[A1_FPIXEL] = (a1_y << 16) | (a1_x & 0xffff);
	m_blitter_regs[A2_PIXEL] = (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff);
}