summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/battlera.c
blob: 42f5649d6ac7af0266c8f919278f7507925cc063 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                                                
                
                     
                            
                              
 




                                                                                
                                                                      

                                                                        
 

                                                
 

                                                                                                  
 



                                                                                        
 


                                                                      







                                                                                
                                                            

                                

                                                                                                                                  





                                                                                
                                                                               
                                             



                                 
                                                                               
                                           


                                   
                                                                               

               
                                                                                           





                                             
                                                                                            





                                                                          
                                                                               

                                        
                                           










                                                                                
                                                                               



                                 
                                                                                           

                                

                                                                                                                








                                      
                                                                               

                                 
                                                        

                                          
                                                                                                              


                                          
                                                                                                              


                                          



                                                                                                                          
                                 
                                                                                                                               






                                                           

                                                                                           
                                                           

                                                                                     


                                                                   
                                                                                                              


                                                    
                                                                                                              


                                                    
                                                                                                              





                                          
                                                                                                 


                                           
                                                                                                                







                                                               
                                                        

                                                                          
                                                                                                               


                                          
                                                                                                               


                                                




                                                                                                                                       
                                 

                                                                                                   




                                                                



                                                                              





                                                                   
                                                                                                               


                                                    
                                                                                                               


                                                       
                                                                                                               





                                          
                                                                                                 


                                                     
                                                                                                                 



                                       
                                                                                                                                              



                                                                                
                                                                                                  
 
                                                                      


                                                                     
                                                                                                                  
         

                                                                           
 
                                                                                        

                             

                                                                                      



                       



                                                         
 
                                                               














                                                                                          
                                                                    


                                       
                                         

                                
                                                                            


                                                       
                                                            









                                                                          

                                                                                
                         
 
                                                                                

                                            
                                                   
                                                                         
         

                                                                            
         






                                                   
                                                                                                 

                                                                             


                                                                                       
                                             
                                                                         
                                            
                                                   
                                                                                        


                                                                                
                                                   
                                                                                           
                                             
                                                                         
                                            
                                                       
                 

         
                           

                                                                 
 
                                                                                     



                                                        
                                                                                  

                                            
                                                                                                

                                                      
                                                                                  
 






                                                                                
                                                                                
                                                                                         

                                                                           

                                                                                                   
                                                                                


                             

                                                  
                                                                      
                                        
                                                                              


                           

                                             

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

    Battle Rangers - Bryan McPhail, mish@tendril.co.uk

    This file only implements necessary features - not all PC-Engine video
    features are used in this game (no DMA for one).

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

#include "emu.h"
#include "deprecat.h"
#include "cpu/h6280/h6280.h"
#include "includes/battlera.h"


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

VIDEO_START( battlera )
{
	battlera_state *state = machine.driver_data<battlera_state>();
	state->m_HuC6270_vram=auto_alloc_array(machine, UINT8, 0x20000);
	state->m_vram_dirty=auto_alloc_array(machine, UINT8, 0x1000);

	memset(state->m_HuC6270_vram,0,0x20000);
	memset(state->m_vram_dirty,1,0x1000);

	state->m_tile_bitmap=auto_bitmap_alloc(machine,512,512,machine.primary_screen->format());
	state->m_front_bitmap=auto_bitmap_alloc(machine,512,512,machine.primary_screen->format());

	state->m_vram_ptr=0;
	state->m_inc_value=1;
	state->m_current_scanline=0;
	state->m_irq_enable=state->m_rcr_enable=state->m_sb_enable=state->m_bb_enable=0;

	gfx_element_set_source(machine.gfx[0], state->m_HuC6270_vram);
	gfx_element_set_source(machine.gfx[1], state->m_HuC6270_vram);
	gfx_element_set_source(machine.gfx[2], state->m_blank_tile);
}

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

WRITE8_HANDLER( battlera_palette_w )
{
	int pal_word;

	space->machine().generic.paletteram.u8[offset]=data;
	if (offset%2) offset-=1;

	pal_word=space->machine().generic.paletteram.u8[offset] | (space->machine().generic.paletteram.u8[offset+1]<<8);
	palette_set_color_rgb(space->machine(), offset/2, pal3bit(pal_word >> 3), pal3bit(pal_word >> 6), pal3bit(pal_word >> 0));
}

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

READ8_HANDLER( HuC6270_debug_r )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	return state->m_HuC6270_vram[offset];
}

WRITE8_HANDLER( HuC6270_debug_w )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	state->m_HuC6270_vram[offset]=data;
}
READ8_HANDLER( HuC6270_register_r )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	int rr;

	if ((state->m_current_scanline+56)==state->m_HuC6270_registers[6]) rr=1; else rr=0;

	return 0		/* CR flag */
		| (0 << 1)	/* OR flag */
		| (rr << 2)	/* RR flag */
		| (0 << 3)	/* DS flag */
		| (0 << 4)	/* DV flag */
		| (state->m_bldwolf_vblank << 5)	/* VD flag (1 when vblank else 0) */
		| (0 << 6)	/* BSY flag (1 when dma active, else 0) */
		| (0 << 7);	/* Always zero */
}

WRITE8_HANDLER( HuC6270_register_w )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	switch (offset) {
	case 0: /* Select data region */
		state->m_VDC_register=data;
		break;
	case 1: /* Unused */
		break;
	}
}

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

#ifdef UNUSED_FUNCTION
READ8_HANDLER( HuC6270_data_r )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	int result;

	switch (offset) {
		case 0: /* LSB */
			return state->m_HuC6270_vram[(state->m_HuC6270_registers[1]<<1)|1];

		case 1:/* MSB */
			result=state->m_HuC6270_vram[(state->m_HuC6270_registers[1]<<1)|0];
			state->m_HuC6270_registers[1]=(state->m_HuC6270_registers[1]+state->m_inc_value)&0xffff;
			return result;
	}

	return 0;
}
#endif

WRITE8_HANDLER( HuC6270_data_w )
{
	battlera_state *state = space->machine().driver_data<battlera_state>();
	switch (offset) {
		case 0: /* LSB */
			switch (state->m_VDC_register) {

			case 0: /* MAWR */
				state->m_HuC6270_registers[0]=(state->m_HuC6270_registers[0]&0xff00) | (data);
				return;

			case 1: /* MARR */
				state->m_HuC6270_registers[0]=(state->m_HuC6270_registers[1]&0xff00) | (data);
				return;

			case 2: /* VRAM */
				if (state->m_HuC6270_vram[(state->m_HuC6270_registers[0]<<1)|1]!=data) {
					state->m_HuC6270_vram[(state->m_HuC6270_registers[0]<<1)|1]=data;
					gfx_element_mark_dirty(space->machine().gfx[0], state->m_HuC6270_registers[0]>>4);
					gfx_element_mark_dirty(space->machine().gfx[1], state->m_HuC6270_registers[0]>>6);
				}
				if (state->m_HuC6270_registers[0]<0x1000) state->m_vram_dirty[state->m_HuC6270_registers[0]]=1;
				return;

			case 3: break; /* Unused */
			case 4: break; /* Unused */

			case 5: /* CR - Control register */
				/* Bits 0,1 unknown */
				state->m_rcr_enable=data&0x4; /* Raster interrupt enable */
				state->m_irq_enable=data&0x8; /* VBL interrupt enable */
				/* Bits 4,5 unknown (EX) */
				state->m_sb_enable=data&0x40; /* Sprites enable */
				state->m_bb_enable=data&0x80; /* Background enable */
				return;

			case 6: /* RCR - Raster counter register */
				state->m_HuC6270_registers[6]=(state->m_HuC6270_registers[6]&0xff00) | (data);
				return;

			case 7: /* BXR - X scroll */
				state->m_HuC6270_registers[7]=(state->m_HuC6270_registers[7]&0xff00) | (data);
				return;

			case 8: /* BYR - Y scroll */
				state->m_HuC6270_registers[8]=(state->m_HuC6270_registers[8]&0xff00) | (data);
				return;

			case 15: /* DMA */
			case 16:
			case 17:
			case 18:
				logerror("%04x: dma 2 %02x\n",cpu_get_pc(&space->device()),data);
				break;

			case 19: /* SATB */
				state->m_HuC6270_registers[19]=(state->m_HuC6270_registers[19]&0xff00) | (data);
				return;

			}
			break;

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

		case 1: /* MSB (Autoincrement on this write) */
			switch (state->m_VDC_register) {

			case 0: /* MAWR - Memory Address Write Register */
				state->m_HuC6270_registers[0]=(state->m_HuC6270_registers[0]&0xff) | (data<<8);
				return;

			case 1: /* MARR */
				state->m_HuC6270_registers[1]=(state->m_HuC6270_registers[1]&0xff) | (data<<8);
				return;

			case 2: /* VWR - VRAM */
				if (state->m_HuC6270_vram[(state->m_HuC6270_registers[0]<<1)|0]!=data) {
					state->m_HuC6270_vram[(state->m_HuC6270_registers[0]<<1)|0]=data;
					gfx_element_mark_dirty(space->machine().gfx[0], state->m_HuC6270_registers[0]>>4);
					gfx_element_mark_dirty(space->machine().gfx[1], state->m_HuC6270_registers[0]>>6);
					if (state->m_HuC6270_registers[0]<0x1000) state->m_vram_dirty[state->m_HuC6270_registers[0]]=1;
				}
				state->m_HuC6270_registers[0]+=state->m_inc_value;
				state->m_HuC6270_registers[0]=state->m_HuC6270_registers[0]&0xffff;
				return;

			case 5: /* CR */
				/* IW - Auto-increment values */
				switch ((data>>3)&3) {
					case 0: state->m_inc_value=1; break;
					case 1: state->m_inc_value=32;break;
					case 2: state->m_inc_value=64; break;
					case 3: state->m_inc_value=128; break;
				}

				/* DR, TE unknown */
				return;

			case 6: /* RCR - Raster counter register */
				state->m_HuC6270_registers[6]=(state->m_HuC6270_registers[6]&0xff) | (data<<8);
				return;

			case 7: /* BXR - X scroll */
				state->m_HuC6270_registers[7]=(state->m_HuC6270_registers[7]&0xff) | (data<<8);
						return;

			case 8: /* BYR - Y scroll */
				state->m_HuC6270_registers[8]=(state->m_HuC6270_registers[8]&0xff) | (data<<8);
				return;

			case 15: /* DMA */
			case 16:
			case 17:
			case 18:
				logerror("%04x: dma 2 %02x\n",cpu_get_pc(&space->device()),data);
				break;

			case 19: /* SATB - Sprites */
				state->m_HuC6270_registers[19]=(state->m_HuC6270_registers[19]&0xff) | (data<<8);
				return;
			}
			break;
	}
	logerror("%04x: unknown write to  VDC_register %02x (%02x) at %02x\n",cpu_get_pc(&space->device()),state->m_VDC_register,data,offset);
}

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

static void draw_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *clip,int pri)
{
	battlera_state *state = machine.driver_data<battlera_state>();
	int offs,my,mx,code,code2,fx,fy,cgy=0,cgx,colour,i,yinc;

	/* Draw sprites, starting at SATB, draw in _reverse_ order */
	for (offs=(state->m_HuC6270_registers[19]<<1)+0x200-8; offs>=(state->m_HuC6270_registers[19]<<1); offs-=8)
	{
		if ((state->m_HuC6270_vram[offs+7]&0x80) && !pri) continue;
		if (!(state->m_HuC6270_vram[offs+7]&0x80) && pri) continue;

		code=state->m_HuC6270_vram[offs+5] + (state->m_HuC6270_vram[offs+4]<<8);
		code=code>>1;

		my=state->m_HuC6270_vram[offs+1] + (state->m_HuC6270_vram[offs+0]<<8);
		mx=state->m_HuC6270_vram[offs+3] + (state->m_HuC6270_vram[offs+2]<<8);

		mx-=32;
		my-=57;

		fx=state->m_HuC6270_vram[offs+6]&0x8;
		fy=state->m_HuC6270_vram[offs+6]&0x80;
		cgx=state->m_HuC6270_vram[offs+6]&1;
		colour=state->m_HuC6270_vram[offs+7]&0xf;

		switch ((state->m_HuC6270_vram[offs+6]>>4)&3) {
		case 0: cgy=1; break;
		case 1: cgy=2; break;
		case 2: cgy=0; break; /* Illegal */
		case 3: cgy=4; break;
		}

		if (cgx && cgy==2) code=code&0x3fc; /* Title screen */

		if (fx && cgx) {code2=code; code++;} /* Swap tile order on X flips */
		else code2=code+1;

		yinc = 16;
		if (fy) { my += 16*(cgy-1); yinc = -16; } /* Swap tile order on Y flips */

		for (i=0; i<cgy; i++) {
			drawgfx_transpen(bitmap,clip,machine.gfx[1],
				code,
				colour,
				fx,fy,
				mx,my,0);

			if (cgx)
				drawgfx_transpen(bitmap,clip,machine.gfx[1],
						code2,
						colour,
						fx,fy,
						mx+16,my,0);
			my += yinc;
			/* if (cgx) */ /* Different from console? */
			code += 2;
			code2 += 2;
			/*else code += 1; */ /* Different from console? */
		}
	}

}

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

SCREEN_UPDATE( battlera )
{
	battlera_state *state = screen->machine().driver_data<battlera_state>();
	int offs,code,scrollx,scrolly,mx,my;

	/* if any tiles changed, redraw the VRAM */
	if (screen->machine().gfx[0]->dirtyseq != state->m_tile_dirtyseq)
	{
		state->m_tile_dirtyseq = screen->machine().gfx[0]->dirtyseq;
		memset(state->m_vram_dirty, 1, 0x1000);
	}

	mx=-1;
	my=0;
	for (offs = 0x0000;offs < 0x2000;offs += 2)
	{
		mx++;
		if (mx==64) {mx=0; my++;}
		code=state->m_HuC6270_vram[offs+1] + ((state->m_HuC6270_vram[offs] & 0x0f) << 8);

		/* If this tile was changed OR tilemap was changed, redraw */
		if (state->m_vram_dirty[offs/2]) {
			state->m_vram_dirty[offs/2]=0;
			drawgfx_opaque(state->m_tile_bitmap,0,screen->machine().gfx[0],
					code,
					state->m_HuC6270_vram[offs] >> 4,
					0,0,
					8*mx,8*my);
			drawgfx_opaque(state->m_front_bitmap,0,screen->machine().gfx[2],
					0,
					0,	/* fill the spot with pen 256 */
					0,0,
					8*mx,8*my);
			drawgfx_transmask(state->m_front_bitmap,0,screen->machine().gfx[0],
					code,
					state->m_HuC6270_vram[offs] >> 4,
					0,0,
					8*mx,8*my,0x1);
		}
	}

	/* Render bitmap */
	scrollx=-state->m_HuC6270_registers[7];
	scrolly=-state->m_HuC6270_registers[8]+cliprect->min_y-1;

	copyscrollbitmap(bitmap,state->m_tile_bitmap,1,&scrollx,1,&scrolly,cliprect);

	/* Todo:  Background enable (not used anyway) */

	/* Render low priority sprites, if enabled */
	if (state->m_sb_enable) draw_sprites(screen->machine(),bitmap,cliprect,0);

	/* Render background over sprites */
	copyscrollbitmap_trans(bitmap,state->m_front_bitmap,1,&scrollx,1,&scrolly,cliprect,256);

	/* Render high priority sprites, if enabled */
	if (state->m_sb_enable) draw_sprites(screen->machine(),bitmap,cliprect,1);

	return 0;
}

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

INTERRUPT_GEN( battlera_interrupt )
{
	battlera_state *state = device->machine().driver_data<battlera_state>();
	state->m_current_scanline=255-cpu_getiloops(device); /* 8 lines clipped at top */

	/* If raster interrupt occurs, refresh screen _up_ to this point */
	if (state->m_rcr_enable && (state->m_current_scanline+56)==state->m_HuC6270_registers[6]) {
		device->machine().primary_screen->update_partial(state->m_current_scanline);
		device_set_input_line(device, 0, HOLD_LINE); /* RCR interrupt */
	}

	/* Start of vblank */
	else if (state->m_current_scanline==240) {
		state->m_bldwolf_vblank=1;
		device->machine().primary_screen->update_partial(240);
		if (state->m_irq_enable)
			device_set_input_line(device, 0, HOLD_LINE); /* VBL */
	}

	/* End of vblank */
	if (state->m_current_scanline==254) {
		state->m_bldwolf_vblank=0;
	}
}