Written up a bare-bones M50458 OSD video chip device, used by Nintendo Super System HW [Angelo Salese]

This commit is contained in:
Angelo Salese 2012-08-25 04:15:46 +00:00
parent 6fb8919afa
commit 37a8c8f56f
3 changed files with 148 additions and 29 deletions

View File

@ -16,6 +16,69 @@ Mitsubishi M50458 OSD chip
// device type definition
const device_type M50458 = &device_creator<m50458_device>;
static ADDRESS_MAP_START( m50458_vram, AS_0, 16, m50458_device )
AM_RANGE(0x0000, 0x023f) AM_RAM // vram
AM_RANGE(0x024e, 0x024f) AM_WRITE(vreg_127_w)
ADDRESS_MAP_END
// internal GFX ROM (TODO: GFXs in here should be 12x18, not 16x18)
ROM_START( m50458 )
ROM_REGION( 0x1200, "m50458", 0 )
ROM_LOAD("m50458_char.bin", 0x0000, 0x1200, BAD_DUMP CRC(011cc342) SHA1(d5b9f32d6e251b4b25945267d7c68c099bd83e96) )
ROM_END
WRITE16_MEMBER( m50458_device::vreg_127_w)
{
if(data & 0x20) // RAMERS, display RAM is erased
{
int i;
for(i=0;i<0x120;i++)
write_word(i,0);
}
}
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
const rom_entry *m50458_device::device_rom_region() const
{
return ROM_NAME( m50458 );
}
//-------------------------------------------------
// memory_space_config - return a description of
// any address spaces owned by this device
//-------------------------------------------------
const address_space_config *m50458_device::memory_space_config(address_spacenum spacenum) const
{
return (spacenum == AS_0) ? &m_space_config : NULL;
}
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
//-------------------------------------------------
// readbyte - read a byte at the given address
//-------------------------------------------------
inline UINT16 m50458_device::read_word(offs_t address)
{
return space()->read_word(address << 1);
}
//-------------------------------------------------
// writebyte - write a byte at the given address
//-------------------------------------------------
inline void m50458_device::write_word(offs_t address, UINT16 data)
{
space()->write_word(address << 1, data);
}
//**************************************************************************
// LIVE DEVICE
@ -26,7 +89,9 @@ const device_type M50458 = &device_creator<m50458_device>;
//-------------------------------------------------
m50458_device::m50458_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, M50458, "m50458", tag, owner, clock)
: device_t(mconfig, M50458, "m50458", tag, owner, clock),
device_memory_interface(mconfig, *this),
m_space_config("videoram", ENDIANNESS_LITTLE, 16, 16, 0, NULL, *ADDRESS_MAP_NAME(m50458_vram))
{
}
@ -76,7 +141,7 @@ WRITE_LINE_MEMBER( m50458_device::set_cs_line )
if(m_reset_line != CLEAR_LINE)
{
printf("Reset asserted\n");
//printf("Reset asserted\n");
m_cmd_stream_pos = 0;
m_current_cmd = 0;
m_osd_state = OSD_SET_ADDRESS;
@ -108,8 +173,8 @@ WRITE_LINE_MEMBER( m50458_device::set_clock_line )
m_osd_state = OSD_SET_DATA;
break;
case OSD_SET_DATA:
printf("%04x %04x\n",m_osd_addr,m_current_cmd);
//printf("%04x %04x\n",m_osd_addr,m_current_cmd);
write_word(m_osd_addr,m_current_cmd);
m_osd_addr++;
/* Presumably wraps at 0x127? */
if(m_osd_addr > 0x127) { m_osd_addr = 0; }
@ -122,3 +187,47 @@ WRITE_LINE_MEMBER( m50458_device::set_clock_line )
}
}
}
//-------------------------------------------------
// update_screen -
//-------------------------------------------------
UINT32 m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int x,y;
UINT8 *pcg = memregion("m50458")->base();
for(y=0;y<12;y++)
{
for(x=0;x<24;x++)
{
int xi,yi;
UINT16 tile;
tile = read_word(x+y*24);
for(yi=0;yi<18;yi++)
{
for(xi=4;xi<16;xi++) /* TODO: remove 4 / 16 / -4 offset once that the ROM is fixed */
{
UINT8 pix;
UINT8 r,g,b;
UINT16 offset = ((tile & 0x7f)*36+yi*2);
if(xi>=8)
pix = (pcg[offset+1] >> (7-(xi & 0x7))) & 1;
else
pix = (pcg[offset+0] >> (7-(xi & 0x7))) & 1;
r = (tile & 0x100 && pix) ? 0xff : 0x00;
g = (tile & 0x200 && pix) ? 0xff : 0x00;
b = (tile & 0x400 && pix) ? 0xff : 0x00;
bitmap.pix32(y*18+yi,x*12+(xi-4)) = r << 16 | g << 8 | b;
}
}
}
}
return 0;
}

View File

@ -32,7 +32,8 @@ typedef enum
// ======================> m50458_device
class m50458_device : public device_t
class m50458_device : public device_t,
public device_memory_interface
{
public:
// construction/destruction
@ -42,21 +43,31 @@ public:
WRITE_LINE_MEMBER( write_bit );
WRITE_LINE_MEMBER( set_cs_line );
WRITE_LINE_MEMBER( set_clock_line );
DECLARE_WRITE16_MEMBER(vreg_127_w);
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
virtual const rom_entry *device_rom_region() const;
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
int m_latch;
int m_reset_line;
int m_clock_line;
int m_current_cmd;
UINT16 m_current_cmd;
int m_cmd_stream_pos;
UINT16 m_osd_addr;
m50458_state_t m_osd_state;
private:
inline UINT16 read_word(offs_t address);
inline void write_word(offs_t address, UINT16 data);
const address_space_config m_space_config;
};

View File

@ -298,18 +298,22 @@ Contra III CONTRA_III_1 TC574000 CONTRA_III_0 TC574000 GAME1_NSSU
#include "machine/eeprom.h"
#include "video/m50458.h"
#include "includes/snes.h"
#include "rendlay.h"
class nss_state : public snes_state
{
public:
nss_state(const machine_config &mconfig, device_type type, const char *tag)
: snes_state(mconfig, type, tag)
: snes_state(mconfig, type, tag),
m_m50458(*this,"m50458")
{ }
required_device<m50458_device> m_m50458;
UINT8 m_wram_wp_flag;
UINT8 *m_wram;
UINT8 m_nmi_enable;
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ8_MEMBER(spc_ram_100_r);
DECLARE_WRITE8_MEMBER(spc_ram_100_w);
@ -321,6 +325,13 @@ public:
DECLARE_WRITE8_MEMBER(eeprom_w);
};
UINT32 nss_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
m_m50458->screen_update(screen,bitmap,cliprect);
return 0;
}
static ADDRESS_MAP_START( snes_map, AS_PROGRAM, 8, nss_state )
AM_RANGE(0x000000, 0x2fffff) AM_READWRITE_LEGACY(snes_r_bank1, snes_w_bank1) /* I/O and ROM (repeats for each bank) */
@ -715,22 +726,6 @@ static INPUT_PORTS_START( snes )
#endif
INPUT_PORTS_END
static const gfx_layout nss_char_layout_16x18 =
{
16,18,
RGN_FRAC(1,1),
1,
{ 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7,8,9,10,11,12,13,14,15 },
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16, 16*16,17*16 },
16*18
};
/* decoded for debugging purpose, this will be nuked in the end... */
static GFXDECODE_START( nss )
GFXDECODE_ENTRY( "chargen", 0x00000, nss_char_layout_16x18, 0, 1 )
GFXDECODE_END
static MACHINE_CONFIG_START( snes, nss_state )
@ -776,12 +771,20 @@ static MACHINE_CONFIG_DERIVED( nss, snes )
MCFG_CPU_IO_MAP(bios_io_map)
MCFG_CPU_VBLANK_INT("screen", nss_vblank_irq)
/* TODO: the screen should actually superimpose, but for the time being let's just separate outputs for now */
MCFG_DEFAULT_LAYOUT(layout_dualhsxs)
MCFG_SCREEN_ADD("osd", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(24*12+22, 12*18+22)
MCFG_SCREEN_VISIBLE_AREA(0*8, 24*12-1, 0*8, 12*18-1)
MCFG_SCREEN_UPDATE_DRIVER(nss_state,screen_update)
MCFG_EEPROM_ADD("eeprom", nss_eeprom_intf)
MCFG_M50458_ADD("m50458",4000000) /* TODO: clock */
MCFG_GFXDECODE( nss )
MCFG_PALETTE_LENGTH(2)
MCFG_MACHINE_START( nss )
MACHINE_CONFIG_END
@ -799,10 +802,6 @@ MACHINE_CONFIG_END
ROM_REGION(0x20000, "bios", 0) /* Bios CPU (what is it?) */ \
ROM_LOAD("nss-c.dat" , 0x00000, 0x8000, CRC(a8e202b3) SHA1(b7afcfe4f5cf15df53452dc04be81929ced1efb2) ) /* bios */ \
ROM_LOAD("nss-ic14.02", 0x10000, 0x8000, CRC(e06cb58f) SHA1(62f507e91a2797919a78d627af53f029c7d81477) ) /* bios */ \
ROM_REGION( 0x1200, "chargen", ROMREGION_ERASEFF ) \
ROM_LOAD("m50458_char.bin", 0x0000, 0x1200, BAD_DUMP CRC(011cc342) SHA1(d5b9f32d6e251b4b25945267d7c68c099bd83e96) ) \
ROM_REGION( 0x1000, "m50458_gfx", ROMREGION_ERASEFF ) \
ROM_LOAD("m50458_char_mod.bin", 0x0000, 0x1000, BAD_DUMP CRC(8c4326ef) SHA1(21a63c5245ff7f3f70cb45e217b3045b19d0d799) ) \
ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) \
ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)