summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2026-05-19 20:12:12 +0200
committer angelosa <lordkale4@gmail.com>2026-05-19 20:12:19 +0200
commit46dbf56bb9507a5c403189175451d370aad7ac6e (patch)
treef5e8ecff199d190021cd533e0d4fec96160f13b5 /src
parent3a9fb92d490d3484d50a240ad3d1daeff7b05e0e (diff)
skeleton/extrema_m27sv.cpp: hookup basic video, hookup palette bank
Diffstat (limited to 'src')
-rw-r--r--src/mame/skeleton/extrema_m27sv.cpp241
1 files changed, 182 insertions, 59 deletions
diff --git a/src/mame/skeleton/extrema_m27sv.cpp b/src/mame/skeleton/extrema_m27sv.cpp
index e3eb74170a5..0b8dbc14fba 100644
--- a/src/mame/skeleton/extrema_m27sv.cpp
+++ b/src/mame/skeleton/extrema_m27sv.cpp
@@ -9,8 +9,10 @@ TODO:
- hangs at startup;
\- $9002 becomes 0x11, loops until that becomes 0 then it throws an halt with irqs disabled.
- video (if above bypassed puts some GFX at $e000);
-- palette banks;
-- I/O;
+- confirm palette RGB layout;
+- Upper bank of VRAM clearly view selected thru a bit in $fe2a;
+- ds5000t (view selected too?)
+- I/O (looks non-functional even if they are clearly tested);
The main components (at least for M27-SV rev.1.0) are:
Z84C0010PEC Z80 CPU
@@ -50,8 +52,9 @@ public:
, m_maincpu(*this, "maincpu")
, m_program_rom(*this, "program_rom")
, m_bank(*this, "bank")
+ , m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
- , m_palette_ram(*this, "paletteram")
+ , m_vram(*this, "vram")
{ }
void extrema_m27sv(machine_config &config) ATTR_COLD;
@@ -65,17 +68,26 @@ private:
required_device<cpu_device> m_maincpu;
required_memory_region m_program_rom;
required_memory_bank m_bank;
+ required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
- required_shared_ptr<u8> m_palette_ram;
+ std::unique_ptr<u8[]> m_palette_ram;
+ required_shared_ptr<u8> m_vram;
+ u8 palette_r(offs_t offset);
+ void palette_w(offs_t offset, u8 data);
+ void vram_w(offs_t offset, u8 data);
+
+ TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ tilemap_t *m_tilemap;
+
void program_map(address_map &map) ATTR_COLD;
void io_map(address_map &map) ATTR_COLD;
void mmio_map(address_map &map) ATTR_COLD;
u8 m_unk_fe20 = 0;
- void palette_w(offs_t offset, u8 data);
+ u16 m_pal_bank = 0;
};
void extrema_m27sv_state::machine_start()
@@ -83,41 +95,77 @@ void extrema_m27sv_state::machine_start()
m_bank->configure_entries(0, 8, m_program_rom->base(), 0x8000);
save_item(NAME(m_unk_fe20));
+ save_item(NAME(m_pal_bank));
}
void extrema_m27sv_state::machine_reset()
{
m_unk_fe20 = 0;
+ m_pal_bank = 0;
m_bank->set_entry(0);
}
+TILE_GET_INFO_MEMBER(extrema_m27sv_state::get_tile_info)
+{
+ u8 attr = m_vram[(tile_index * 2 + 1) & 0xfff];
+ u16 code = m_vram[(tile_index * 2) & 0xfff] + ((attr & 0x0f) << 8);
+ u8 color = (attr >> 6) & 3;
+ u8 flags = 0;
+
+ if (BIT(attr, 4))
+ flags |= TILE_FLIPX;
+
+ if (BIT(attr, 5))
+ flags |= TILE_FLIPY;
+
+ tileinfo.set(0, code, color, flags);
+}
+
void extrema_m27sv_state::video_start()
{
+ m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(extrema_m27sv_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
+
+ m_palette_ram = make_unique_clear<u8[]>(0xc00 * 2);
+
+ save_pointer(NAME(m_palette_ram), 0xc00 * 2);
}
uint32_t extrema_m27sv_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ m_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
+void extrema_m27sv_state::vram_w(offs_t offset, u8 data)
+{
+ m_vram[offset] = data;
+ m_tilemap->mark_tile_dirty(offset >> 1);
+}
+
+u8 extrema_m27sv_state::palette_r(offs_t offset)
+{
+ return m_palette_ram[offset + m_pal_bank];
+}
+
void extrema_m27sv_state::palette_w(offs_t offset, u8 data)
{
- m_palette_ram[offset] = data;
+ m_palette_ram[offset + m_pal_bank] = data;
u16 pal_offset = offset & 0x3ff;
// TODO: determine bank order
- u8 r = m_palette_ram[pal_offset | 0x000];
- u8 g = m_palette_ram[pal_offset | 0x400];
- u8 b = m_palette_ram[pal_offset | 0x800];
- m_palette->set_pen_color(pal_offset, pal6bit(r), pal6bit(g), pal6bit(b));
+ u8 r = m_palette_ram[pal_offset + 0x000 + m_pal_bank];
+ u8 g = m_palette_ram[pal_offset + 0x400 + m_pal_bank];
+ u8 b = m_palette_ram[pal_offset + 0x800 + m_pal_bank];
+
+ m_palette->set_pen_color(pal_offset | (m_pal_bank & 0x400), pal6bit(r), pal6bit(g), pal6bit(b));
}
void extrema_m27sv_state::program_map(address_map &map)
{
map(0x0000, 0x7fff).bankr("bank");
map(0x8000, 0xdfff).ram();
- map(0xe000, 0xefff).ram(); // video
- map(0xf000, 0xfbff).ram().w(FUNC(extrema_m27sv_state::palette_w)).share("paletteram");
+ map(0xe000, 0xefff).ram().w(FUNC(extrema_m27sv_state::vram_w)).share("vram");
+ map(0xf000, 0xfbff).rw(FUNC(extrema_m27sv_state::palette_r), FUNC(extrema_m27sv_state::palette_w));
map(0xfe00, 0xfeff).m(*this, FUNC(extrema_m27sv_state::mmio_map));
}
@@ -142,7 +190,20 @@ void extrema_m27sv_state::mmio_map(address_map &map)
LOG("$fe20 %02x\n", data);
})
);
- map(0x2a, 0x2a).nopw(); // flips bit 2 a lot, watchdog?
+
+ // x--- ---- palette r/w bank
+ // -x-- ---- <unknown>
+ // --x- ---- <unknown>
+ // ---- -x-- flipped a lot
+ // ---- --x- <unknown>
+ // ---- ---x <unknown>
+ map(0x2a, 0x2a).lw8(
+ NAME([this] (offs_t offset, u8 data) {
+ m_pal_bank = BIT(data, 7) * 0xc00;
+ if (data & 0xfb)
+ LOG("$fe2a %02x\n", data);
+ })
+ );
// goes $40 up to $4d on second init cycle.
map(0x40, 0x4f).w("aysnd", FUNC(ay8910_device::data_w));
@@ -158,62 +219,126 @@ void extrema_m27sv_state::io_map(address_map &map)
static INPUT_PORTS_START( multgmxl )
PORT_START("IN0")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_DIPNAME( 0x01, 0x01, "IN0" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("IN1")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_DIPNAME( 0x01, 0x01, "IN1" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("IN2")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_DIPNAME( 0x01, 0x01, "IN2" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("IN3")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
-// no DSW on PCB
+ PORT_DIPNAME( 0x01, 0x01, "IN3" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ // no DSW on PCB
INPUT_PORTS_END
// TODO: incomplete
static const gfx_layout charlayout =
{
8, 8,
- RGN_FRAC(1, 2),
+ RGN_FRAC(1, 1),
8,
- { STEP4(0, 1), STEP4(RGN_FRAC(1, 2), 1) },
- { STEP8(0, 4) },
- { STEP8(0, 4*8) },
- 8*8*4
+ { STEP8(0, 1) },
+ { STEP8(0, 8) },
+ { STEP8(0, 8*8) },
+ 8*8*8
};
static GFXDECODE_START( gfx_extrema_m27sv )
- GFXDECODE_ENTRY( "gfx", 0, charlayout, 0, 4 )
+ GFXDECODE_ENTRY( "gfx", 0, charlayout, 0, 8 )
GFXDECODE_END
@@ -231,9 +356,9 @@ void extrema_m27sv_state::extrema_m27sv(machine_config &config)
screen.set_visarea(0, 64*8-1, 0, 32*8-1);
screen.set_screen_update(FUNC(extrema_m27sv_state::screen_update));
- GFXDECODE(config, "gfxdecode", "palette", gfx_extrema_m27sv);
+ GFXDECODE(config, m_gfxdecode, "palette", gfx_extrema_m27sv);
- PALETTE(config, "palette").set_entries(0x400);
+ PALETTE(config, "palette").set_entries(0x800);
SPEAKER(config, "mono").front_center();
@@ -251,10 +376,8 @@ ROM_START( multgmxl )
// 32K bytes internal NVRAM
ROM_REGION( 0x200000, "gfx", 0 )
- ROM_LOAD( "u10_multigamexl.u10", 0x000000, 0x080000, CRC(d745758e) SHA1(9aeb8fd8e46b2ee0663f436628c95e73057dfc51) )
- ROM_CONTINUE( 0x100000, 0x080000 )
- ROM_LOAD( "u11_multigamexl.u11", 0x080000, 0x080000, CRC(ca59894e) SHA1(a97afe937d29e4261cc46e41283e6977b20eafc5) )
- ROM_CONTINUE( 0x180000, 0x080000 )
+ ROM_LOAD16_BYTE( "u10_multigamexl.u10", 0x000001, 0x100000, CRC(d745758e) SHA1(9aeb8fd8e46b2ee0663f436628c95e73057dfc51) )
+ ROM_LOAD16_BYTE( "u11_multigamexl.u11", 0x000000, 0x100000, CRC(ca59894e) SHA1(a97afe937d29e4261cc46e41283e6977b20eafc5) )
ROM_END
} // anonymous namespace