summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2026-05-19 15:37:45 +0200
committer angelosa <lordkale4@gmail.com>2026-05-19 15:38:55 +0200
commit464f95b511ca680c7dbbdd9fd3dddd8085821f91 (patch)
tree5f36f6dc532389eeb1764dc39c00246f5a74df88 /src
parentd5eefe0406857da5df4557d8b68984b0ee67106a (diff)
skeleton/extrema_m27sv.cpp: hookup program bank, AY sound, palette, make MMIO shared
Diffstat (limited to 'src')
-rw-r--r--src/mame/skeleton/extrema_m27sv.cpp134
1 files changed, 115 insertions, 19 deletions
diff --git a/src/mame/skeleton/extrema_m27sv.cpp b/src/mame/skeleton/extrema_m27sv.cpp
index 38b3be158d0..e3eb74170a5 100644
--- a/src/mame/skeleton/extrema_m27sv.cpp
+++ b/src/mame/skeleton/extrema_m27sv.cpp
@@ -2,8 +2,16 @@
// copyright-holders:
/*
+
Video slots by Extrema running on the Extrema M27-SV PCB
+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;
+
The main components (at least for M27-SV rev.1.0) are:
Z84C0010PEC Z80 CPU
DALLAS DS5000T
@@ -15,7 +23,6 @@ Winbond WF19054
ADV7120 RAMDAC
2x CY7C199 RAM (1 near Z80, 1 near GFX ROMs)
-TODO: everything.
*/
@@ -23,62 +30,129 @@ TODO: everything.
#include "cpu/z80/z80.h"
#include "sound/ay8910.h"
-#include "video/ramdac.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
+#define VERBOSE (LOG_GENERAL)
+#include "logmacro.h"
+
namespace {
class extrema_m27sv_state : public driver_device
{
public:
- extrema_m27sv_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu")
+ extrema_m27sv_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_program_rom(*this, "program_rom")
+ , m_bank(*this, "bank")
+ , m_palette(*this, "palette")
+ , m_palette_ram(*this, "paletteram")
{ }
void extrema_m27sv(machine_config &config) ATTR_COLD;
protected:
+ virtual void machine_start() override ATTR_COLD;
+ virtual void machine_reset() override ATTR_COLD;
virtual void video_start() override ATTR_COLD;
private:
required_device<cpu_device> m_maincpu;
+ required_memory_region m_program_rom;
+ required_memory_bank m_bank;
+ required_device<palette_device> m_palette;
+ required_shared_ptr<u8> m_palette_ram;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
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);
+};
-uint32_t extrema_m27sv_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+void extrema_m27sv_state::machine_start()
{
+ m_bank->configure_entries(0, 8, m_program_rom->base(), 0x8000);
- return 0;
+ save_item(NAME(m_unk_fe20));
+}
+
+void extrema_m27sv_state::machine_reset()
+{
+ m_unk_fe20 = 0;
+ m_bank->set_entry(0);
}
void extrema_m27sv_state::video_start()
{
}
+uint32_t extrema_m27sv_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ return 0;
+}
+
+void extrema_m27sv_state::palette_w(offs_t offset, u8 data)
+{
+ m_palette_ram[offset] = 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));
+}
void extrema_m27sv_state::program_map(address_map &map)
{
- map(0x0000, 0x7fff).rom();
+ map(0x0000, 0x7fff).bankr("bank");
map(0x8000, 0xdfff).ram();
- map(0xe000, 0xefff).ram();
- map(0xfe00, 0xffff).ram();
+ map(0xe000, 0xefff).ram(); // video
+ map(0xf000, 0xfbff).ram().w(FUNC(extrema_m27sv_state::palette_w)).share("paletteram");
+ map(0xfe00, 0xfeff).m(*this, FUNC(extrema_m27sv_state::mmio_map));
+}
+
+// area $fe00-$feff looks shared between memory and I/O maps
+// this is a tracer bullet, in case we really need A8-A15 for I/O.
+void extrema_m27sv_state::mmio_map(address_map &map)
+{
+ map(0x08, 0x08).portr("IN0");
+ map(0x09, 0x09).portr("IN1");
+ map(0x0a, 0x0a).portr("IN2");
+ map(0x0b, 0x0b).portr("IN3");
+
+// map(0x10, 0x10) read then discarded with a pop af
+
+ // x--- ---- test switch?
+ // -xxx ---- program bank
+ map(0x20, 0x20).lrw8(
+ NAME([this] (offs_t offset) { return m_unk_fe20; }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_unk_fe20 = data & 0xff;
+ m_bank->set_entry((data & 0x70) >> 4);
+ LOG("$fe20 %02x\n", data);
+ })
+ );
+ map(0x2a, 0x2a).nopw(); // flips bit 2 a lot, watchdog?
+
+ // goes $40 up to $4d on second init cycle.
+ map(0x40, 0x4f).w("aysnd", FUNC(ay8910_device::data_w));
+ map(0x60, 0x60).w("aysnd", FUNC(ay8910_device::address_w));
}
void extrema_m27sv_state::io_map(address_map &map)
{
//map.unmap_value_high();
- map.global_mask(0xff);
+ map(0xfe00, 0xfeff).m(*this, FUNC(extrema_m27sv_state::mmio_map));
}
@@ -113,12 +187,33 @@ static INPUT_PORTS_START( multgmxl )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ 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
INPUT_PORTS_END
+// TODO: incomplete
+static const gfx_layout charlayout =
+{
+ 8, 8,
+ RGN_FRAC(1, 2),
+ 8,
+ { STEP4(0, 1), STEP4(RGN_FRAC(1, 2), 1) },
+ { STEP8(0, 4) },
+ { STEP8(0, 4*8) },
+ 8*8*4
+};
-// TODO
static GFXDECODE_START( gfx_extrema_m27sv )
+ GFXDECODE_ENTRY( "gfx", 0, charlayout, 0, 4 )
GFXDECODE_END
@@ -138,18 +233,17 @@ void extrema_m27sv_state::extrema_m27sv(machine_config &config)
GFXDECODE(config, "gfxdecode", "palette", gfx_extrema_m27sv);
- PALETTE(config, "palette").set_entries(0x100); // TODO
-
- RAMDAC(config, "ramdac", 0, "palette");
+ PALETTE(config, "palette").set_entries(0x400);
SPEAKER(config, "mono").front_center();
+ // Winbond WF19054
AY8910(config, "aysnd", 36_MHz_XTAL / 8); // divider not verified. Or maybe uses one of the 11.0592 XTALs?
}
ROM_START( multgmxl )
- ROM_REGION( 0x40000, "maincpu", 0 )
+ ROM_REGION( 0x40000, "program_rom", 0 )
ROM_LOAD( "u8_multigamexl.u8", 0x00000, 0x40000, CRC(735a8b87) SHA1(974a3a6c4de41131021b74d280b409d668c87de9) )
ROM_REGION( 0x8000, "ds5000t", ROMREGION_ERASE00 )
@@ -157,8 +251,10 @@ ROM_START( multgmxl )
// 32K bytes internal NVRAM
ROM_REGION( 0x200000, "gfx", 0 )
- ROM_LOAD( "u10_multigamexl.u10", 0x000000, 0x100000, CRC(d745758e) SHA1(9aeb8fd8e46b2ee0663f436628c95e73057dfc51) )
- ROM_LOAD( "u11_multigamexl.u11", 0x100000, 0x100000, CRC(ca59894e) SHA1(a97afe937d29e4261cc46e41283e6977b20eafc5) )
+ 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_END
} // anonymous namespace