make flowerw3 (igs_m027_033vid.cpp) show the attract demo (#13474)

Co-authored-by: David Haywood <hazemamewip@hotmail.com>
This commit is contained in:
mamehaze 2025-03-14 07:38:22 +00:00 committed by GitHub
parent e75c7079cf
commit dfcb1350c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 117 additions and 14 deletions

View File

@ -459,6 +459,12 @@ void palette_device::write16_ext(offs_t offset, u16 data, u16 mem_mask)
update_for_write(offset * 2, 2);
}
void palette_device::write32_ext(offs_t offset, u32 data, u32 mem_mask)
{
m_paletteram_ext.write32(offset, data, mem_mask);
update_for_write(offset * 4, 4);
}
u8 palette_device::read8_ext(offs_t offset)
{
return m_paletteram_ext.read8(offset);
@ -469,6 +475,10 @@ u16 palette_device::read16_ext(offs_t offset)
return m_paletteram_ext.read16(offset);
}
u32 palette_device::read32_ext(offs_t offset)
{
return m_paletteram_ext.read32(offset);
}
//-------------------------------------------------
// write_indirect - write a byte to the base

View File

@ -367,7 +367,9 @@ public:
void write16(offs_t offset, u16 data, u16 mem_mask = u16(~0));
void write16_ext(offs_t offset, u16 data, u16 mem_mask = u16(~0));
u32 read32(offs_t offset);
u32 read32_ext(offs_t offset);
void write32(offs_t offset, u32 data, u32 mem_mask = u32(~0));
void write32_ext(offs_t offset, u32 data, u32 mem_mask = u32(~0));
// helper to update palette when data changed
void update() { if (!m_init.isnull()) m_init(*this); }

View File

@ -13,6 +13,10 @@ Main components for the IGS PCB-0405-02-FZ are:
- K668 ADPCM chip (M6295 clone)
- 3 banks of 8 DIP switches
TODO:
- IGS 033 appears to encapsulate the behavior of the video/interface chip found in igspoker.cpp
so could be turned into a device, possibly shared
*/
#include "emu.h"
@ -29,6 +33,7 @@ Main components for the IGS PCB-0405-02-FZ are:
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#include "endianness.h"
@ -46,15 +51,16 @@ public:
m_nvram(*this, "nvram"),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
m_palette(*this, "palette")
//m_video(*this, "igs033")
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode"),
m_bg_videoram(*this, "bg_videoram"),
m_bg_attr_videoram(*this, "bg_attr_videoram")
{ }
void m027_033vid(machine_config &config) ATTR_COLD;
void init_flowerw3() ATTR_COLD;
protected:
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
@ -67,9 +73,23 @@ private:
required_device<igs027a_cpu_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
//required_device<igs033_video_device> m_video;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint32_t> m_bg_videoram;
required_shared_ptr<uint32_t> m_bg_attr_videoram;
u32 m_xor_table[0x100];
tilemap_t *m_bg_tilemap = nullptr;
TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
void bg_videoram_w(offs_t offset, uint32_t data, uint32_t mem_mask);
void bg_attr_videoram_w(offs_t offset, uint32_t data, uint32_t mem_mask);
u32 gpio_r() { return 0xffffffff; };
u32 unknown_4000_r() { return 0xffffffff; };
u32 unknown_5030_r() { return 0xffffffff; };
u32 external_rom_r(offs_t offset);
void xor_table_w(offs_t offset, u8 data);
@ -94,10 +114,12 @@ void igs_m027_033vid_state::machine_reset()
void igs_m027_033vid_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(igs_m027_033vid_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
}
u32 igs_m027_033vid_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
@ -105,6 +127,41 @@ void igs_m027_033vid_state::screen_vblank(int state)
{
}
TILE_GET_INFO_MEMBER(igs_m027_033vid_state::get_bg_tile_info)
{
int tileno = m_bg_videoram[tile_index/4];
tileno = tileno >> (8 * (tile_index & 3)) & 0xff;
int attr = m_bg_attr_videoram[tile_index/4];
attr = attr >> (8 * (tile_index & 3)) & 0xff;
tileno |= ((attr & 0x1f) << 8);
int col = (attr & 0xe0) >> 5;
col <<= 1; // gfx are 4bpp, every other set of colours is unused
tileno |= 0x2000; // bank not hooked up (where is it, when is it used, not in attract, probably D-UP game)
tileinfo.set(0, tileno, col, 0);
}
// TODO: convert to 8-bit handlers and 8-bit RAM?
void igs_m027_033vid_state::bg_videoram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
COMBINE_DATA(&m_bg_videoram[offset]);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 0);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 1);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 2);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 3);
}
void igs_m027_033vid_state::bg_attr_videoram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
COMBINE_DATA(&m_bg_attr_videoram[offset]);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 0);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 1);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 2);
m_bg_tilemap->mark_tile_dirty((offset * 4) + 3);
}
/***************************************************************************
@ -118,11 +175,15 @@ void igs_m027_033vid_state::m027_map(address_map &map) // TODO: everything to be
map(0x1800'0000, 0x1800'7fff).ram().share(m_nvram);
map(0x2800'0000, 0x2800'0fff).ram();
map(0x3800'2000, 0x3800'20ff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
map(0x3800'3000, 0x3800'30ff).ram().w(m_palette, FUNC(palette_device::write32_ext)).share("palette_ext");
map(0x3800'0000, 0x3800'7fff).noprw(); // TODO: IGS033
map(0x38a0'0000, 0x38a0'11ff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
map(0x3800'4000, 0x3800'4003).r(FUNC(igs_m027_033vid_state::unknown_4000_r));
map(0x3800'5030, 0x3800'5033).r(FUNC(igs_m027_033vid_state::unknown_5030_r));
map(0x3800'7000, 0x3800'77ff).ram().w(FUNC(igs_m027_033vid_state::bg_videoram_w)).share(m_bg_videoram);
map(0x3800'7800, 0x3800'7fff).ram().w(FUNC(igs_m027_033vid_state::bg_attr_videoram_w)).share(m_bg_attr_videoram);
map(0x5000'0000, 0x5000'03ff).umask32(0x0000'00ff).w(FUNC(igs_m027_033vid_state::xor_table_w)); // uploads XOR table to external ROM here
}
@ -168,6 +229,32 @@ INPUT_PORTS_START( flowerw3 )
PORT_DIPUNKNOWN_DIPLOC(0x80, 0x80, "SW3:8")
INPUT_PORTS_END
static const gfx_layout tiles8x8x4_layout =
{
8, 8,
RGN_FRAC(1,1),
4,
{ 24,16,8,0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
32*8
};
static GFXDECODE_START( igs033 )
GFXDECODE_ENTRY( "igs033", 0, tiles8x8x4_layout, 0, 16 )
GFXDECODE_END
TIMER_DEVICE_CALLBACK_MEMBER(igs_m027_033vid_state::interrupt)
{
// TODO: which of these are needed, are they always enabled, when do they fire?
int scanline = param;
if (scanline == 240)
m_maincpu->pulse_input_line(arm7_cpu_device::ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time());
if (scanline == 0)
m_maincpu->pulse_input_line(arm7_cpu_device::ARM7_FIRQ_LINE, m_maincpu->minimum_quantum_time());
}
/***************************************************************************
@ -175,7 +262,6 @@ INPUT_PORTS_END
***************************************************************************/
u32 igs_m027_033vid_state::external_rom_r(offs_t offset)
{
return m_external_rom[offset] ^ m_xor_table[offset & 0x00ff];
@ -186,11 +272,11 @@ void igs_m027_033vid_state::xor_table_w(offs_t offset, u8 data)
m_xor_table[offset] = (u32(data) << 24) | (u32(data) << 8);
}
void igs_m027_033vid_state::m027_033vid(machine_config &config)
{
IGS027A(config, m_maincpu, 24_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_033vid_state::m027_map);
m_maincpu->in_port().set(FUNC(igs_m027_033vid_state::gpio_r));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
@ -198,14 +284,17 @@ void igs_m027_033vid_state::m027_033vid(machine_config &config)
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(1000));
m_screen->set_size(512, 256);
m_screen->set_visarea(0, 448-1, 0, 224-1);
m_screen->set_visarea(0, 512-1, 0, 256-1);
m_screen->set_screen_update(FUNC(igs_m027_033vid_state::screen_update));
m_screen->set_palette(m_palette);
m_screen->screen_vblank().set(FUNC(igs_m027_033vid_state::screen_vblank));
PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x1200/2);
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x100);
m_palette->set_membits(8);
// IGS033_VIDEO(config, m_video, 0);
GFXDECODE(config, m_gfxdecode, "palette", igs033);
TIMER(config, "scantimer").configure_scanline(FUNC(igs_m027_033vid_state::interrupt), "screen", 0, 1);
// sound hardware
SPEAKER(config, "mono").front_center();
@ -232,7 +321,8 @@ ROM_START( flowerw3 )
ROM_LOAD( "v118.u12", 0x00000, 0x80000, CRC(c2729fbe) SHA1(2153675a1161bd6aea6367c55fcf801c7fb0dd3a) )
ROM_REGION( 0x80000, "igs033", 0 )
ROM_LOAD( "7e.u20", 0x000000, 0x080000, CRC(a7b65af6) SHA1(bef13d38eb793b2860c2922f0cfb4b011fd9991b) )
// could be a slight encryption, but looks more like a bad read
ROM_LOAD( "7e.u20", 0x000000, 0x080000, BAD_DUMP CRC(a7b65af6) SHA1(bef13d38eb793b2860c2922f0cfb4b011fd9991b) )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "sp.3", 0x00000, 0x80000, CRC(06b70fe9) SHA1(5df34f870d32893b5c3095fb9653954209712cdb) )
@ -253,4 +343,5 @@ void igs_m027_033vid_state::init_flowerw3()
***************************************************************************/
GAME( 200?, flowerw3, 0, m027_033vid, flowerw3, igs_m027_033vid_state, init_flowerw3, ROT0, "IGS", "Flower World 3 (V118CN)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // title to be adjusted once it works
// internal ROM date is 2002, external software revision could be later
GAME( 2002, flowerw3, 0, m027_033vid, flowerw3, igs_m027_033vid_state, init_flowerw3, ROT0, "IGS", "Flower World 3 (V118CN)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // title to be adjusted once it works