(MESS) gizmondo: converted the GF4500 to be a device. [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2013-06-03 12:40:04 +00:00
parent 24a894246c
commit 8d6ee4e61c
3 changed files with 156 additions and 90 deletions

View File

@ -45,7 +45,9 @@ class gizmondo_state : public driver_device
public:
gizmondo_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) ,
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_gf4500(*this, "gf4500")
{ }
UINT32 m_port[9];
device_t *m_s3c2440;
@ -55,8 +57,11 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(port_changed);
inline void ATTR_PRINTF(3,4) verboselog( int n_level, const char *s_fmt, ...);
required_device<cpu_device> m_maincpu;
required_device<gf4500_device> m_gf4500;
DECLARE_READ32_MEMBER(s3c2440_gpio_port_r);
DECLARE_WRITE32_MEMBER(s3c2440_gpio_port_w);
bitmap_rgb32 m_bitmap;
};
@ -95,11 +100,11 @@ READ32_MEMBER(gizmondo_state::s3c2440_gpio_port_r)
data = data & ~0x000000F2;
// keys
data |= 0x00F2;
if ((port_c & 0x01) == 0) data &= ~ioport( "PORTF-01")->read();
if ((port_c & 0x02) == 0) data &= ~ioport( "PORTF-02")->read();
if ((port_c & 0x04) == 0) data &= ~ioport( "PORTF-04")->read();
if ((port_c & 0x08) == 0) data &= ~ioport( "PORTF-08")->read();
if ((port_c & 0x10) == 0) data &= ~ioport( "PORTF-10")->read();
if ((port_c & 0x01) == 0) data &= ~ioport("PORTF-01")->read();
if ((port_c & 0x02) == 0) data &= ~ioport("PORTF-02")->read();
if ((port_c & 0x04) == 0) data &= ~ioport("PORTF-04")->read();
if ((port_c & 0x08) == 0) data &= ~ioport("PORTF-08")->read();
if ((port_c & 0x10) == 0) data &= ~ioport("PORTF-10")->read();
data &= ~ioport( "PORTF")->read();
}
break;
@ -159,11 +164,11 @@ void gizmondo_state::machine_reset()
static ADDRESS_MAP_START( gizmondo_map, AS_PROGRAM, 32, gizmondo_state )
AM_RANGE(0x00000000, 0x000007ff) AM_ROM
AM_RANGE(0x00000800, 0x00000fff) AM_DEVREADWRITE16( "diskonchip", diskonchip_g3_device, sec_1_r, sec_1_w, 0xffffffff)
AM_RANGE(0x00001000, 0x000017ff) AM_DEVREADWRITE16( "diskonchip", diskonchip_g3_device, sec_2_r, sec_2_w, 0xffffffff)
AM_RANGE(0x00001800, 0x00001fff) AM_DEVREADWRITE16( "diskonchip", diskonchip_g3_device, sec_3_r, sec_3_w, 0xffffffff)
AM_RANGE(0x00000800, 0x00000fff) AM_DEVREADWRITE16("diskonchip", diskonchip_g3_device, sec_1_r, sec_1_w, 0xffffffff)
AM_RANGE(0x00001000, 0x000017ff) AM_DEVREADWRITE16("diskonchip", diskonchip_g3_device, sec_2_r, sec_2_w, 0xffffffff)
AM_RANGE(0x00001800, 0x00001fff) AM_DEVREADWRITE16("diskonchip", diskonchip_g3_device, sec_3_r, sec_3_w, 0xffffffff)
AM_RANGE(0x30000000, 0x33ffffff) AM_RAM
AM_RANGE(0x34000000, 0x3413ffff) AM_READWRITE_LEGACY(gf4500_r, gf4500_w)
AM_RANGE(0x34000000, 0x3413ffff) AM_DEVREADWRITE("gf4500", gf4500_device, read, write)
ADDRESS_MAP_END
/*******************************************************************************
@ -193,6 +198,20 @@ static S3C2440_INTERFACE( gizmondo_s3c2440_intf )
{ 0 }
};
VIDEO_START( gizmondo )
{
gizmondo_state *state = machine.driver_data<gizmondo_state>();
machine.primary_screen->register_screen_bitmap(state->m_bitmap);
}
SCREEN_UPDATE_RGB32( gizmondo )
{
gizmondo_state *state = screen.machine().driver_data<gizmondo_state>();
state->m_gf4500->render_screen(state->m_bitmap);
copybitmap(bitmap, state->m_bitmap, 0, 0, 0, 0, cliprect);
return 0;
}
static MACHINE_CONFIG_START( gizmondo, gizmondo_state )
MCFG_CPU_ADD("maincpu", ARM9, 40000000)
MCFG_CPU_PROGRAM_MAP(gizmondo_map)
@ -204,12 +223,13 @@ static MACHINE_CONFIG_START( gizmondo, gizmondo_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(320, 240)
MCFG_SCREEN_VISIBLE_AREA(0, 320 - 1, 0, 240 - 1)
MCFG_SCREEN_UPDATE_STATIC(gf4500)
MCFG_SCREEN_UPDATE_STATIC(gizmondo)
MCFG_DEFAULT_LAYOUT(layout_lcd)
MCFG_VIDEO_START(gf4500)
MCFG_VIDEO_START(gizmondo)
MCFG_GF4500_ADD("gf4500")
MCFG_S3C2440_ADD("s3c2440", 12000000, gizmondo_s3c2440_intf)

View File

@ -7,6 +7,7 @@
*/
#include "emu.h"
#include "video/gf4500.h"
#define VERBOSE_LEVEL ( 0 )
@ -16,10 +17,10 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine &machine, int n_level,
{
va_list v;
char buf[32768];
va_start( v, s_fmt);
vsprintf( buf, s_fmt, v);
va_end( v);
logerror( "%s: %s", machine.describe_context( ), buf);
va_start(v, s_fmt);
vsprintf(buf, s_fmt, v);
va_end(v);
logerror("%s: %s", machine.describe_context(), buf);
}
}
@ -28,108 +29,128 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine &machine, int n_level,
#define GF4500_FRAMEBUF_OFFSET 0x20000
static struct {
UINT32 *data;
int screen_x;
int screen_y;
int screen_x_max;
int screen_y_max;
int screen_x_min;
int screen_y_min;
bitmap_rgb32 bitmap;
} gf4500;
static void gf4500_init( running_machine &machine)
const device_type GF4500 = &device_creator<gf4500_device>;
gf4500_device::gf4500_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, GF4500, "NVIDIA GoForce 4500", tag, owner, clock)
{
gf4500.data = auto_alloc_array( machine, UINT32, 0x140000 / 4);
memset(gf4500.data, 0, sizeof(UINT32) * 0x140000 / 4);
gf4500.screen_x = gf4500.screen_y = 0;
gf4500.screen_x_max = gf4500.screen_y_max = gf4500.screen_x_min = gf4500.screen_y_min = 0;
machine.primary_screen->register_screen_bitmap(gf4500.bitmap);
}
static void gf4500_vram_write16( UINT16 data)
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void gf4500_device::device_config_complete()
{
if ((gf4500.screen_x < gf4500.screen_x_max) && (gf4500.screen_y < gf4500.screen_y_max))
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void gf4500_device::device_start()
{
m_data = auto_alloc_array_clear(machine(), UINT32, 0x140000/4);
save_pointer(NAME(m_data), 0x140000/4);
save_item(NAME(m_screen_x));
save_item(NAME(m_screen_y));
save_item(NAME(m_screen_x_max));
save_item(NAME(m_screen_y_max));
save_item(NAME(m_screen_x_min));
save_item(NAME(m_screen_y_min));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void gf4500_device::device_reset()
{
m_screen_x = m_screen_y = 0;
m_screen_x_max = m_screen_y_max = m_screen_x_min = m_screen_y_min = 0;
}
void gf4500_device::vram_write16( UINT16 data )
{
if ((m_screen_x < m_screen_x_max) && (m_screen_y < m_screen_y_max))
{
UINT16 *vram = (UINT16 *)((UINT8 *)gf4500.data + GF4500_FRAMEBUF_OFFSET + (((gf4500.screen_y_min + gf4500.screen_y) * (320 + 1)) + (gf4500.screen_x_min + gf4500.screen_x)) * 2);
UINT16 *vram = (UINT16 *)((UINT8 *)m_data + GF4500_FRAMEBUF_OFFSET + (((m_screen_y_min + m_screen_y) * (320 + 1)) + (m_screen_x_min + m_screen_x)) * 2);
*vram = data;
gf4500.screen_x++;
m_screen_x++;
}
}
static rgb_t gf4500_get_color_16( UINT16 data)
static rgb_t gf4500_get_color_16( UINT16 data )
{
UINT8 r, g, b;
r = BITS( data, 15, 11) << 3;
g = BITS( data, 10, 5) << 2;
b = BITS( data, 4, 0) << 3;
return MAKE_RGB( r, g, b);
r = BITS(data, 15, 11) << 3;
g = BITS(data, 10, 5) << 2;
b = BITS(data, 4, 0) << 3;
return MAKE_RGB(r, g, b);
}
static void gf4500_render_screen( running_machine &machine, bitmap_rgb32 &bitmap)
void gf4500_device::render_screen( bitmap_rgb32 &bitmap )
{
UINT16 *vram = (UINT16 *)(gf4500.data + GF4500_FRAMEBUF_OFFSET / 4);
UINT16 *vram = (UINT16 *)(m_data + GF4500_FRAMEBUF_OFFSET / 4);
int x, y;
for (y = 0; y < 240; y++)
{
UINT32 *scanline = &bitmap.pix32(y);
for (x = 0; x < 320; x++)
{
*scanline++ = gf4500_get_color_16( *vram++);
*scanline++ = gf4500_get_color_16(*vram++);
}
vram += 1;
}
}
READ32_HANDLER( gf4500_r )
READ32_MEMBER( gf4500_device::read )
{
UINT32 data = gf4500.data[offset];
UINT32 data = m_data[offset];
switch (offset)
{
case 0x4C / 4 :
{
case 0x4c / 4:
data = 0x00145000;
}
break;
break;
}
if ((offset < (GF4500_FRAMEBUF_OFFSET / 4)) || (offset >= ((GF4500_FRAMEBUF_OFFSET + (321 * 240 * 2)) / 4)))
{
verboselog( space.machine(), 9, "(GFO) %08X -> %08X\n", 0x34000000 + (offset << 2), data);
verboselog(machine(), 9, "(GFO) %08X -> %08X\n", 0x34000000 + (offset << 2), data);
}
return data;
}
WRITE32_HANDLER( gf4500_w )
WRITE32_MEMBER( gf4500_device::write )
{
COMBINE_DATA(&gf4500.data[offset]);
COMBINE_DATA(&m_data[offset]);
if ((offset < (GF4500_FRAMEBUF_OFFSET / 4)) || (offset >= ((GF4500_FRAMEBUF_OFFSET + (321 * 240 * 2)) / 4)))
{
verboselog( space.machine(), 9, "(GFO) %08X <- %08X\n", 0x34000000 + (offset << 2), data);
verboselog(machine(), 9, "(GFO) %08X <- %08X\n", 0x34000000 + (offset << 2), data);
}
switch (offset)
{
case 0x300 / 4 :
{
gf4500.screen_x = gf4500.screen_y = 0;
}
break;
m_screen_x = m_screen_y = 0;
break;
case 0x304 / 4 :
{
gf4500.screen_x_max = (data >> 0) & 0xFFFF;
gf4500.screen_y_max = (data >> 16) & 0xFFFF;
if (gf4500.screen_x_max & 1) gf4500.screen_x_min++;
m_screen_x_max = (data >> 0) & 0xFFFF;
m_screen_y_max = (data >> 16) & 0xFFFF;
if (m_screen_x_max & 1) m_screen_x_min++;
//if (screen_y_max & 1) screen_y_min++;
}
break;
break;
case 0x308 / 4 :
{
gf4500.screen_x_min = (data >> 0) & 0xFFFF;
gf4500.screen_y_min = (data >> 16) & 0xFFFF;
if (gf4500.screen_x_min & 1) gf4500.screen_x_min--;
m_screen_x_min = (data >> 0) & 0xFFFF;
m_screen_y_min = (data >> 16) & 0xFFFF;
if (m_screen_x_min & 1) m_screen_x_min--;
//if (screen_y_min & 1) screen_y_min--;
}
break;
break;
}
if ((offset >= (0x200 / 4)) && (offset < (0x280 / 4)))
{
@ -149,24 +170,13 @@ WRITE32_HANDLER( gf4500_w )
// ...
// 'maincpu' (02996A24): (GFO) 3400027C <- AE9FAE9F
gf4500_vram_write16( (data >> 0) & 0xFFFF);
gf4500_vram_write16( (data >> 16) & 0xFFFF);
if (gf4500.screen_x >= gf4500.screen_x_max)
vram_write16((data >> 0) & 0xFFFF);
vram_write16((data >> 16) & 0xFFFF);
if (m_screen_x >= m_screen_x_max)
{
gf4500.screen_x = 0;
gf4500.screen_y++;
m_screen_x = 0;
m_screen_y++;
}
}
}
VIDEO_START( gf4500 )
{
gf4500_init( machine);
}
SCREEN_UPDATE_RGB32( gf4500 )
{
gf4500_render_screen( screen.machine(), gf4500.bitmap);
copybitmap(bitmap, gf4500.bitmap, 0, 0, 0, 0, cliprect);
return 0;
}

View File

@ -9,10 +9,46 @@
#ifndef __GF4500_H__
#define __GF4500_H__
DECLARE_READ32_HANDLER( gf4500_r );
DECLARE_WRITE32_HANDLER( gf4500_w );
VIDEO_START( gf4500 );
SCREEN_UPDATE_RGB32( gf4500 );
class gf4500_device : public device_t
{
public:
gf4500_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~gf4500_device() {}
DECLARE_READ32_MEMBER( read );
DECLARE_WRITE32_MEMBER( write );
void render_screen(bitmap_rgb32 &bitmap);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
void vram_write16(UINT16 data);
UINT32 *m_data;
int m_screen_x;
int m_screen_y;
int m_screen_x_max;
int m_screen_y_max;
int m_screen_x_min;
int m_screen_y_min;
};
#define MCFG_GF4500_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, GF4500, 0)
extern const device_type GF4500;
#endif /* __GF4500_H__ */