summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/craft.c
blob: 5bddd6cc8cfadd64791334600fc6ebd1d0fe8a2b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
               
                               


                           
                       



                          

                      
                           
 
                              
 
                                
 







                                                           

                                                      

                                                      




                                                                                     
                                                    

                                            
         

         

                            

                                     

                                   
 




                              
                                         
 
                                               
 

                                      
                                   
                                     
                                                                                                           
                                                                                     
                                          

  














                                                                        

                                 

 
                                 
 

                        





                                    
         
 
                 

 
                                  
 

                        
                                             
                                    
                              
 
                                             
                 








                                                                                      
                         

                                                                                           
                         

                                        
                 
 
                                             



                                                   
 
                                             





                                                                                  
         

 
                                
 

                                                                     
 
                                         
         



                                                                                                                 
         
            
         




                                                                                                            
                 
                                                                       
                 




                                                         
 
                                     






                                                                     
                                       

               
                                                                   
                                       

               
                                                               
                                                                             

               




                                                      

                                                          





                                                      
                                                                                                               
 




                                                    
                                                                    



                                                                        

                 
                 









                                                      
                                 
 
                                     
 

                                

 

                                   
                

  

                                                 












                                                                         
                                                                   
                                           
 



                                          









                                                                                                              
                                                                                                                               
// license:MAME
// copyright-holders:Ryan Holtz
/*\
* * Linus Akesson's "Craft"
* *
* * Driver by MooglyGuy
\*/

#include "emu.h"
#include "cpu/avr8/avr8.h"
#include "sound/dac.h"

#define VERBOSE_LEVEL   (0)

#define ENABLE_VERBOSE_LOG (0)

#define MASTER_CLOCK    20000000

#define VISIBLE_CYCLES      480
#define HSYNC_CYCLES        155
#define LINE_CYCLES         (VISIBLE_CYCLES + HSYNC_CYCLES)
#define VISIBLE_LINES       480
#define VSYNC_LINES         45
#define LINES_PER_FRAME     (VISIBLE_LINES + VSYNC_LINES)
#define CYCLES_PER_FRAME    (LINES_PER_FRAME * LINE_CYCLES)
#define PIXELS_PER_FRAME    (CYCLES_PER_FRAME)

/****************************************************\
* I/O devices                                        *
\****************************************************/

class craft_state : public driver_device
{
public:
	craft_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_dac(*this, "dac")
	{
	}

	void video_update();

	virtual void machine_start();

	UINT32 m_last_cycles;
	UINT64 m_frame_start_cycle;

	UINT8 m_port_b;
	UINT8 m_port_c;
	UINT8 m_port_d;

	UINT8 m_latched_color;
	UINT8 m_pixels[PIXELS_PER_FRAME];

	required_device<avr8_device> m_maincpu;

	DECLARE_READ8_MEMBER(port_r);
	DECLARE_WRITE8_MEMBER(port_w);
	DECLARE_DRIVER_INIT(craft);
	virtual void machine_reset();
	UINT32 screen_update_craft(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3,4);
	required_device<dac_device> m_dac;
};

inline void craft_state::verboselog(int n_level, const char *s_fmt, ...)
{
#if ENABLE_VERBOSE_LOG
	if( VERBOSE_LEVEL >= n_level )
	{
		va_list v;
		char buf[ 32768 ];
		va_start( v, s_fmt );
		vsprintf( buf, s_fmt, v );
		va_end( v );
		logerror( "%08x: %s", m_maincpu->safe_pc(), buf );
	}
#endif
}

void craft_state::machine_start()
{
}

READ8_MEMBER(craft_state::port_r)
{
	switch( offset )
	{
		case 0x00: // Port A
		case 0x01: // Port B
		case 0x02: // Port C
		case 0x03: // Port D
			// Unhandled
			return 0x00;
	}

	return 0;
}

WRITE8_MEMBER(craft_state::port_w)
{
	switch( offset )
	{
		case AVR8_IO_PORTA: // Port A
			// Unhandled
			break;

		case AVR8_IO_PORTB: // Port B
		{
			UINT8 old_port_b = m_port_b;
			UINT8 pins = data;
			UINT8 changed = pins ^ old_port_b;
			if(pins & changed & 0x02)
			{
				m_frame_start_cycle = m_maincpu->get_elapsed_cycles();
				video_update();
			}
			if(changed & 0x08)
			{
				video_update();
				m_latched_color = (pins & 0x08) ? (m_port_c & 0x3f) : 0x3f;
			}
			m_port_b = data;
			break;
		}

		case AVR8_IO_PORTC: // Port C
			video_update();
			m_port_c = data;
			m_latched_color = m_port_c;
			break;

		case AVR8_IO_PORTD: // Port D
		{
			m_port_d = data;
			UINT8 audio_sample = (data & 0x02) | ((data & 0xf4) >> 2);
			m_dac->write_unsigned8(audio_sample << 1);
			break;
		}
	}
}

void craft_state::video_update()
{
	UINT64 cycles = m_maincpu->get_elapsed_cycles();
	UINT32 frame_cycles = (UINT32)(cycles - m_frame_start_cycle);

	if (m_last_cycles < frame_cycles)
	{
		for (UINT32 pixidx = m_last_cycles; pixidx < frame_cycles && pixidx < PIXELS_PER_FRAME; pixidx++)
		{
			m_pixels[pixidx] = m_latched_color;
		}
	}
	else
	{
		UINT32 end_clear = sizeof(m_pixels) - m_last_cycles;
		UINT32 start_clear = frame_cycles;
		end_clear = (end_clear > PIXELS_PER_FRAME) ? (PIXELS_PER_FRAME - m_last_cycles) : end_clear;
		start_clear = (start_clear > PIXELS_PER_FRAME) ? PIXELS_PER_FRAME : start_clear;
		if (m_last_cycles < PIXELS_PER_FRAME)
		{
			memset(m_pixels + m_last_cycles, 0, end_clear);
		}
		if (start_clear < PIXELS_PER_FRAME)
		{
			memset(m_pixels, 0, start_clear);
		}
	}

	m_last_cycles = frame_cycles;
}

/****************************************************\
* Address maps                                       *
\****************************************************/

static ADDRESS_MAP_START( craft_prg_map, AS_PROGRAM, 8, craft_state )
	AM_RANGE(0x0000, 0x1fff) AM_ROM
ADDRESS_MAP_END

static ADDRESS_MAP_START( craft_data_map, AS_DATA, 8, craft_state )
	AM_RANGE(0x0100, 0x04ff) AM_RAM
ADDRESS_MAP_END

static ADDRESS_MAP_START( craft_io_map, AS_IO, 8, craft_state )
	AM_RANGE(AVR8_IO_PORTA, AVR8_IO_PORTD) AM_READWRITE( port_r, port_w )
ADDRESS_MAP_END

/****************************************************\
* Input ports                                        *
\****************************************************/

static INPUT_PORTS_START( craft )
	PORT_START("MAIN")
		PORT_BIT(0xff, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END

/****************************************************\
* Video hardware                                     *
\****************************************************/

UINT32 craft_state::screen_update_craft(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	for(int y = 0; y < LINES_PER_FRAME; y++)
	{
		UINT32 *line = &bitmap.pix32(y);
		for(int x = 0; x < LINE_CYCLES; x++)
		{
			UINT8 pixel = m_pixels[y * LINE_CYCLES + x];
			UINT8 r = 0x55 * ((pixel & 0x30) >> 4);
			UINT8 g = 0x55 * ((pixel & 0x0c) >> 2);
			UINT8 b = 0x55 * (pixel & 0x03);
			line[x] = 0xff000000 | (r << 16) | (g << 8) | b;
		}
	}
	return 0;
}

/****************************************************\
* Machine definition                                 *
\****************************************************/

DRIVER_INIT_MEMBER(craft_state,craft)
{
}

void craft_state::machine_reset()
{
	m_dac->write_unsigned8(0x00);

	m_frame_start_cycle = 0;
	m_last_cycles = 0;
}

const avr8_config atmega88_config =
{
	"eeprom"
};

static MACHINE_CONFIG_START( craft, craft_state )

	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu", ATMEGA88, MASTER_CLOCK)
	MCFG_CPU_AVR8_CONFIG(atmega88_config)
	MCFG_CPU_PROGRAM_MAP(craft_prg_map)
	MCFG_CPU_DATA_MAP(craft_data_map)
	MCFG_CPU_IO_MAP(craft_io_map)

	/* video hardware */
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_REFRESH_RATE(59.99)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1429)) /* accurate */
	MCFG_SCREEN_SIZE(635, 525)
	MCFG_SCREEN_VISIBLE_AREA(47, 526, 36, 515)
	MCFG_SCREEN_UPDATE_DRIVER(craft_state, screen_update_craft)
	MCFG_PALETTE_ADD("palette", 0x1000)

	/* sound hardware */
	MCFG_SPEAKER_STANDARD_MONO("avr8")
	MCFG_SOUND_ADD("dac", DAC, 0)
	MCFG_SOUND_ROUTE(0, "avr8", 1.00)
MACHINE_CONFIG_END

ROM_START( craft )
	ROM_REGION( 0x2000, "maincpu", 0 )  /* Main program store */
	ROM_LOAD( "craft.bin", 0x0000, 0x2000, CRC(2e6f9ad2) SHA1(75e495bf18395d74289ca7ee2649622fc4010457) )
	ROM_REGION( 0x200, "eeprom", 0 )  /* on-die eeprom */
	ROM_LOAD( "eeprom.raw", 0x0000, 0x0200, CRC(e18a2af9) SHA1(81fc6f2d391edfd3244870214fac37929af0ac0c) )
ROM_END

/*   YEAR  NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      COMPANY          FULLNAME */
CONS(2008, craft,    0,        0,        craft,    craft, craft_state,    craft,    "Linus Akesson", "Craft", GAME_NOT_WORKING)