From 37a8c8f56fabd25f79bd821546aeb9205a813bd5 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Sat, 25 Aug 2012 04:15:46 +0000 Subject: [PATCH] Written up a bare-bones M50458 OSD video chip device, used by Nintendo Super System HW [Angelo Salese] --- src/emu/video/m50458.c | 117 +++++++++++++++++++++++++++++++++++++++-- src/emu/video/m50458.h | 15 +++++- src/mame/drivers/nss.c | 45 ++++++++-------- 3 files changed, 148 insertions(+), 29 deletions(-) diff --git a/src/emu/video/m50458.c b/src/emu/video/m50458.c index 16e497b89de..8f6de3c57a7 100644 --- a/src/emu/video/m50458.c +++ b/src/emu/video/m50458.c @@ -16,6 +16,69 @@ Mitsubishi M50458 OSD chip // device type definition const device_type M50458 = &device_creator; +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(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; +} diff --git a/src/emu/video/m50458.h b/src/emu/video/m50458.h index 1c46e207ee6..866594af30d 100644 --- a/src/emu/video/m50458.h +++ b/src/emu/video/m50458.h @@ -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; }; diff --git a/src/mame/drivers/nss.c b/src/mame/drivers/nss.c index 33864e00bca..a24f73e20b8 100644 --- a/src/mame/drivers/nss.c +++ b/src/mame/drivers/nss.c @@ -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 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)