summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mame/jaleco/aeroboto.cpp413
-rw-r--r--src/mame/jaleco/aeroboto.h89
-rw-r--r--src/mame/jaleco/aeroboto_v.cpp212
-rw-r--r--src/mame/jaleco/exerion.cpp523
-rw-r--r--src/mame/jaleco/exerion.h103
-rw-r--r--src/mame/jaleco/exerion_v.cpp403
-rw-r--r--src/mame/jaleco/fcombat.cpp461
-rw-r--r--src/mame/jaleco/fcombat.h102
-rw-r--r--src/mame/jaleco/fcombat_v.cpp201
-rw-r--r--src/mame/jaleco/ginganin.cpp482
-rw-r--r--src/mame/jaleco/ginganin.h81
-rw-r--r--src/mame/jaleco/ginganin_v.cpp280
-rw-r--r--src/mame/jaleco/homerun.cpp302
-rw-r--r--src/mame/jaleco/homerun.h79
-rw-r--r--src/mame/jaleco/homerun_v.cpp157
-rw-r--r--src/mame/jaleco/momoko.cpp523
-rw-r--r--src/mame/jaleco/momoko.h89
-rw-r--r--src/mame/jaleco/momoko_v.cpp289
-rw-r--r--src/mame/jaleco/skyfox.cpp394
-rw-r--r--src/mame/jaleco/skyfox.h63
-rw-r--r--src/mame/jaleco/skyfox_v.cpp240
-rw-r--r--src/mame/omori/battlex.cpp297
-rw-r--r--src/mame/omori/battlex.h62
-rw-r--r--src/mame/omori/battlex_v.cpp122
-rw-r--r--src/mame/omori/popper.cpp8
25 files changed, 2950 insertions, 3025 deletions
diff --git a/src/mame/jaleco/aeroboto.cpp b/src/mame/jaleco/aeroboto.cpp
index 7c80398df2d..068dd16ebfa 100644
--- a/src/mame/jaleco/aeroboto.cpp
+++ b/src/mame/jaleco/aeroboto.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Carlos A. Lozano, Uki
+// copyright-holders: Carlos A. Lozano, Uki
+
/****************************************************************************
Formation Z / Aeroboto
@@ -14,7 +15,7 @@ TODO:
- The color of stars:
at 1st title screen = neutral tints of blue and aqua (1 color only)
at 2nd title screen and attract mode (purple surface) = light & dark aqua
- This color will not be affected by scroll. Leftmost 8pixels are light, next
+ This color will not be affected by scroll. Leftmost 8 pixels are light, next
16 pixels are dark, the next 16 pixels are light, and so on.
- Verify CPU clocks again. Main CPU is a HD68B09P, and next to it is a 8 MHz XTAL.
@@ -26,23 +27,321 @@ Revisions:
****************************************************************************/
#include "emu.h"
-#include "aeroboto.h"
#include "cpu/m6809/m6809.h"
#include "machine/gen_latch.h"
#include "sound/ay8910.h"
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_3004 (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_3004)
+
+#include "logmacro.h"
+
+#define LOG3004(...) LOGMASKED(LOG_3004, __VA_ARGS__)
+
+
+namespace {
+
+class aeroboto_state : public driver_device
+{
+public:
+ aeroboto_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_mainram(*this, "mainram"),
+ m_videoram(*this, "videoram"),
+ m_hscroll(*this, "hscroll"),
+ m_tilecolor(*this, "tilecolor"),
+ m_spriteram(*this, "spriteram"),
+ m_vscroll(*this, "vscroll"),
+ m_starx(*this, "starx"),
+ m_stary(*this, "stary"),
+ m_bgcolor(*this, "bgcolor"),
+ m_stars_rom(*this, "starfield_data"),
+ m_maincpu(*this, "maincpu"),
+ m_audiocpu(*this, "audiocpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_p(*this, "P%u", 1U)
+ { }
+
+ void formatz(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ // memory pointers
+ required_shared_ptr<uint8_t> m_mainram;
+ required_shared_ptr<uint8_t> m_videoram;
+ required_shared_ptr<uint8_t> m_hscroll;
+ required_shared_ptr<uint8_t> m_tilecolor;
+ required_shared_ptr<uint8_t> m_spriteram;
+ required_shared_ptr<uint8_t> m_vscroll;
+ required_shared_ptr<uint8_t> m_starx;
+ required_shared_ptr<uint8_t> m_stary;
+ required_shared_ptr<uint8_t> m_bgcolor;
+
+ // stars layout
+ required_region_ptr<uint8_t> m_stars_rom;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_audiocpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ // I/O
+ required_ioport_array<2> m_p;
+
+ // video-related
+ tilemap_t *m_bg_tilemap = nullptr;
+ uint8_t m_charbank = 0U;
+ uint8_t m_starsoff = 0U;
+ uint8_t m_sx = 0U;
+ uint8_t m_sy = 0U;
+ uint8_t m_ox = 0U;
+ uint8_t m_oy = 0U;
+
+ // misc
+ uint32_t m_count = 0U;
+ uint8_t m_disable_irq = 0U;
+
+ uint8_t _201_r();
+ uint8_t irq_ack_r();
+ uint8_t _2973_r();
+ void _1a2_w(uint8_t data);
+ uint8_t in0_r();
+ void _3000_w(uint8_t data);
+ void videoram_w(offs_t offset, uint8_t data);
+ void tilecolor_w(offs_t offset, uint8_t data);
+ TILE_GET_INFO_MEMBER(get_tile_info);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(vblank_irq);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
+// how the starfield ROM is interpreted: 0 = 256 x 256 x 1 linear bitmap, 1 = 8 x 8 x 1 x 1024 tilemap
+static constexpr uint8_t STARS_LAYOUT = 1;
+
+// scroll speed of the stars: 1 = normal, 2 = half, 3 = one-third...etc. (positive integers only)
+static constexpr uint8_t SCROLL_SPEED = 1;
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+TILE_GET_INFO_MEMBER(aeroboto_state::get_tile_info)
+{
+ uint8_t const code = m_videoram[tile_index];
+ tileinfo.set(0,
+ code + (m_charbank << 8),
+ m_tilecolor[code],
+ (m_tilecolor[code] >= 0x33) ? 0 : TILE_FORCE_LAYER0);
+}
+// transparency should only affect tiles with color 0x33 or higher
+
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+
+void aeroboto_state::video_start()
+{
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aeroboto_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 64);
+ m_bg_tilemap->set_transparent_pen(0);
+ m_bg_tilemap->set_scroll_rows(64);
+
+ save_item(NAME(m_charbank));
+ save_item(NAME(m_starsoff));
+ save_item(NAME(m_sx));
+ save_item(NAME(m_sy));
+ save_item(NAME(m_ox));
+ save_item(NAME(m_oy));
+
+ if (STARS_LAYOUT)
+ {
+ int len = m_stars_rom.bytes();
+ std::vector<uint8_t> temp(len);
+ memcpy(&temp[0], &m_stars_rom[0], len);
+
+ for (int i = 0; i < len; i++)
+ m_stars_rom[(i & ~0xff) + (i << 5 & 0xe0) + (i >> 3 & 0x1f)] = temp[i];
+ }
+}
+
+
+
+/***************************************************************************
+
+ Memory handlers
+
+***************************************************************************/
+
+uint8_t aeroboto_state::in0_r()
+{
+ return flip_screen() ? m_p[1]->read() : m_p[0]->read();
+}
+
+void aeroboto_state::_3000_w(uint8_t data)
+{
+ // bit 0 selects both flip screen and player1 / player2 controls
+ flip_screen_set(data & 0x01);
+
+ // bit 1 = char bank select
+ if (m_charbank != ((data & 0x02) >> 1))
+ {
+ m_bg_tilemap->mark_all_dirty();
+ m_charbank = (data & 0x02) >> 1;
+ }
+
+ // bit 2 = disable star field?
+ m_starsoff = data & 0x04;
+}
+
+void aeroboto_state::videoram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[offset] = data;
+ m_bg_tilemap->mark_tile_dirty(offset);
+}
+
+void aeroboto_state::tilecolor_w(offs_t offset, uint8_t data)
+{
+ if (m_tilecolor[offset] != data)
+ {
+ m_tilecolor[offset] = data;
+ m_bg_tilemap->mark_all_dirty();
+ }
+}
+
+
+
+/***************************************************************************
+
+ Display refresh
+
+***************************************************************************/
+
+void aeroboto_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
+ {
+ int x = m_spriteram[offs + 3];
+ int y = 240 - m_spriteram[offs];
+
+ if (flip_screen())
+ {
+ x = 248 - x;
+ y = 240 - y;
+ }
+
+ m_gfxdecode->gfx(1)->transpen(bitmap, cliprect,
+ m_spriteram[offs + 1],
+ m_spriteram[offs + 2] & 0x07,
+ flip_screen(), flip_screen(),
+ ((x + 8) & 0xff) - 8, y, 0);
+ }
+}
+
+
+uint32_t aeroboto_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ rectangle const splitrect1(0, 255, 0, 39);
+ rectangle const splitrect2(0, 255, 40, 255);
+
+ int star_color = *m_bgcolor << 2;
+ int sky_color = *m_bgcolor << 2;
+
+ // the star field is supposed to be seen through tile pen 0 when active
+ if (!m_starsoff)
+ {
+ if (star_color < 0xd0)
+ {
+ star_color = 0xd0;
+ sky_color = 0;
+ }
+
+ star_color += 2;
+
+ bitmap.fill(sky_color, cliprect);
+
+ // actual scroll speed is unknown but it can be adjusted by changing the SCROLL_SPEED constant
+ m_sx += char(*m_starx - m_ox);
+ m_ox = *m_starx;
+ int const x = m_sx / SCROLL_SPEED;
+
+ if (*m_vscroll != 0xff)
+ m_sy += char(*m_stary - m_oy);
+ m_oy = *m_stary;
+ int const y = m_sy / SCROLL_SPEED;
+
+ for (int i = 0; i < 256; i++)
+ {
+ int src_offsx = (x + i) & 0xff;
+ int const src_colmask = 1 << (src_offsx & 7);
+ src_offsx >>= 3;
+ uint8_t const *const src_colptr = &m_stars_rom[src_offsx];
+ int const pen = star_color + ((i + 8) >> 4 & 1);
+
+ for (int j = 0; j < 256; j++)
+ {
+ uint8_t const *const src_rowptr = src_colptr + (((y + j) & 0xff) << 5 );
+ if (!((unsigned)*src_rowptr & src_colmask))
+ bitmap.pix(j, i) = pen;
+ }
+ }
+ }
+ else
+ {
+ m_sx = m_ox = *m_starx;
+ m_sy = m_oy = *m_stary;
+ bitmap.fill(sky_color, cliprect);
+ }
+
+ for (int y = 0; y < 64; y++)
+ m_bg_tilemap->set_scrollx(y, m_hscroll[y]);
+
+ // the playfield is part of a splitscreen and should not overlap with status display
+ m_bg_tilemap->set_scrolly(0, *m_vscroll);
+ m_bg_tilemap->draw(screen, bitmap, splitrect2, 0, 0);
+ draw_sprites(bitmap, cliprect);
-uint8_t aeroboto_state::aeroboto_201_r()
+ // the status display behaves more closely to a 40-line splitscreen than an overlay
+ m_bg_tilemap->set_scrolly(0, 0);
+ m_bg_tilemap->draw(screen, bitmap, splitrect1, 0, 0);
+ return 0;
+}
+
+
+// machine
+
+uint8_t aeroboto_state::_201_r()
{
- /* if you keep a button pressed during boot, the game will expect this */
- /* serie of values to be returned from 3004, and display "PASS 201" if it is */
+ /* if you keep a button pressed during boot, the game will expect this
+ series of values to be returned from 3004, and display "PASS 201" if it is */
static const uint8_t res[4] = { 0xff, 0x9f, 0x1b, 0x03 };
- logerror("PC %04x: read 3004\n", m_maincpu->pc());
+ LOG3004("PC %04x: read 3004\n", m_maincpu->pc());
return res[(m_count++) & 3];
}
@@ -60,19 +359,19 @@ WRITE_LINE_MEMBER(aeroboto_state::vblank_irq)
}
}
-uint8_t aeroboto_state::aeroboto_irq_ack_r()
+uint8_t aeroboto_state::irq_ack_r()
{
m_maincpu->set_input_line(0, CLEAR_LINE);
return 0xff;
}
-uint8_t aeroboto_state::aeroboto_2973_r()
+uint8_t aeroboto_state::_2973_r()
{
m_mainram[0x02be] = 0;
return 0xff;
}
-void aeroboto_state::aeroboto_1a2_w(uint8_t data)
+void aeroboto_state::_1a2_w(uint8_t data)
{
m_mainram[0x01a2] = data;
if (data)
@@ -81,26 +380,26 @@ void aeroboto_state::aeroboto_1a2_w(uint8_t data)
void aeroboto_state::main_map(address_map &map)
{
- map(0x0000, 0x07ff).ram().share("mainram"); // main RAM
- map(0x01a2, 0x01a2).w(FUNC(aeroboto_state::aeroboto_1a2_w)); // affects IRQ line (more protection?)
+ map(0x0000, 0x07ff).ram().share(m_mainram);
+ map(0x01a2, 0x01a2).w(FUNC(aeroboto_state::_1a2_w)); // affects IRQ line (more protection?)
map(0x0800, 0x08ff).ram(); // tile color buffer; copied to 0x2000
map(0x0900, 0x09ff).writeonly().share("colors2"); // a backup of default tile colors
- map(0x1000, 0x17ff).ram().w(FUNC(aeroboto_state::aeroboto_videoram_w)).share("videoram"); // tile RAM
- map(0x1800, 0x183f).ram().share("hscroll"); // horizontal scroll regs
+ map(0x1000, 0x17ff).ram().w(FUNC(aeroboto_state::videoram_w)).share(m_videoram);
+ map(0x1800, 0x183f).ram().share(m_hscroll);
map(0x1840, 0x27ff).nopw(); // cleared during custom LSI test
- map(0x2000, 0x20ff).ram().w(FUNC(aeroboto_state::aeroboto_tilecolor_w)).share("tilecolor"); // tile color RAM
- map(0x2800, 0x28ff).ram().share("spriteram"); // sprite RAM
+ map(0x2000, 0x20ff).ram().w(FUNC(aeroboto_state::tilecolor_w)).share(m_tilecolor);
+ map(0x2800, 0x28ff).ram().share(m_spriteram);
map(0x2900, 0x2fff).nopw(); // cleared along with sprite RAM
- map(0x2973, 0x2973).r(FUNC(aeroboto_state::aeroboto_2973_r)); // protection read
- map(0x3000, 0x3000).rw(FUNC(aeroboto_state::aeroboto_in0_r), FUNC(aeroboto_state::aeroboto_3000_w));
+ map(0x2973, 0x2973).r(FUNC(aeroboto_state::_2973_r)); // protection read
+ map(0x3000, 0x3000).rw(FUNC(aeroboto_state::in0_r), FUNC(aeroboto_state::_3000_w));
map(0x3001, 0x3001).portr("DSW1").w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x3002, 0x3002).portr("DSW2").w("soundlatch2", FUNC(generic_latch_8_device::write));
- map(0x3003, 0x3003).writeonly().share("vscroll");
- map(0x3004, 0x3004).r(FUNC(aeroboto_state::aeroboto_201_r)).writeonly().share("starx");
- map(0x3005, 0x3005).writeonly().share("stary"); // usable but probably wrong
- map(0x3006, 0x3006).writeonly().share("bgcolor");
- map(0x3800, 0x3800).r(FUNC(aeroboto_state::aeroboto_irq_ack_r)); // watchdog or IRQ ack
- map(0x4000, 0xffff).rom(); // main ROM
+ map(0x3003, 0x3003).writeonly().share(m_vscroll);
+ map(0x3004, 0x3004).r(FUNC(aeroboto_state::_201_r)).writeonly().share(m_starx);
+ map(0x3005, 0x3005).writeonly().share(m_stary); // usable but probably wrong
+ map(0x3006, 0x3006).writeonly().share(m_bgcolor);
+ map(0x3800, 0x3800).r(FUNC(aeroboto_state::irq_ack_r)); // watchdog or IRQ ack
+ map(0x4000, 0xffff).rom();
}
void aeroboto_state::sound_map(address_map &map)
@@ -147,7 +446,7 @@ static INPUT_PORTS_START( formatz )
PORT_DIPSETTING( 0x08, "40000" )
PORT_DIPSETTING( 0x04, "70000" )
PORT_DIPSETTING( 0x00, "100000" )
- PORT_DIPUNUSED_DIPLOC( 0x10, 0x00, "SW1:5" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x10, 0x00, "SW1:5" ) // Listed as "Unused"
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:6")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x20, DEF_STR( On ) )
@@ -174,9 +473,9 @@ static INPUT_PORTS_START( formatz )
PORT_DIPSETTING( 0x08, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x10, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x18, DEF_STR( Hard ) )
- PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW2:6" ) /* Listed as "Unused" */
- PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW2:7" ) /* Listed as "Unused" */
- PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW2:8" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW2:6" ) // Listed as "Unused"
+ PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW2:7" ) // Listed as "Unused"
+ PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW2:8" ) // Listed as "Unused"
INPUT_PORTS_END
@@ -217,16 +516,13 @@ static const gfx_layout spritelayout =
};
static GFXDECODE_START( gfx_aeroboto )
- GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 ) /* chars */
-// GFXDECODE_ENTRY( "gfx2", 0, starlayout, 0, 128 ) /* sky */
- GFXDECODE_ENTRY( "gfx3", 0, spritelayout, 0, 8 )
+ GFXDECODE_ENTRY( "tiles", 0, charlayout, 0, 64 )
+// GFXDECODE_ENTRY( "starfield_data", 0, starlayout, 0, 128 )
+ GFXDECODE_ENTRY( "sprites", 0, spritelayout, 0, 8 )
GFXDECODE_END
void aeroboto_state::machine_start()
{
- m_stars_rom = memregion("gfx2")->base();
- m_stars_length = memregion("gfx2")->bytes();
-
save_item(NAME(m_disable_irq));
save_item(NAME(m_count));
}
@@ -246,20 +542,20 @@ void aeroboto_state::machine_reset()
void aeroboto_state::formatz(machine_config &config)
{
- /* basic machine hardware */
- MC6809(config, m_maincpu, XTAL(10'000'000)/2); /* verified on pcb */
+ // basic machine hardware
+ MC6809(config, m_maincpu, XTAL(10'000'000) / 2); // verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &aeroboto_state::main_map);
- MC6809(config, m_audiocpu, XTAL(10'000'000)/4); /* verified on pcb */
+ MC6809(config, m_audiocpu, XTAL(10'000'000) / 4); // verified on PCB
m_audiocpu->set_addrmap(AS_PROGRAM, &aeroboto_state::sound_map);
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(32*8, 32*8);
screen.set_visarea(0*8, 31*8-1, 2*8, 30*8-1);
- screen.set_screen_update(FUNC(aeroboto_state::screen_update_aeroboto));
+ screen.set_screen_update(FUNC(aeroboto_state::screen_update));
screen.set_palette(m_palette);
screen.screen_vblank().set(FUNC(aeroboto_state::vblank_irq));
@@ -267,18 +563,18 @@ void aeroboto_state::formatz(machine_config &config)
PALETTE(config, m_palette, palette_device::RGB_444_PROMS, "proms", 256);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch");
GENERIC_LATCH_8(config, "soundlatch2");
- ay8910_device &ay1(AY8910(config, "ay1", XTAL(10'000'000)/8)); /* verified on pcb */
+ ay8910_device &ay1(AY8910(config, "ay1", XTAL(10'000'000) / 8)); // verified on PCB
ay1.port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay1.port_b_read_callback().set("soundlatch2", FUNC(generic_latch_8_device::read));
ay1.add_route(ALL_OUTPUTS, "mono", 0.25);
- AY8910(config, "ay2", XTAL(10'000'000)/16).add_route(ALL_OUTPUTS, "mono", 0.25); /* verified on pcb */
+ AY8910(config, "ay2", XTAL(10'000'000) / 16).add_route(ALL_OUTPUTS, "mono", 0.25); // verified on PCB
}
@@ -298,16 +594,16 @@ ROM_START( formatz )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "format_z.9", 0xf000, 0x1000, CRC(6b9215ad) SHA1(3ab416d070bf6b9a8be3e19d4dbc3a399d9ab5cb) )
- ROM_REGION( 0x2000, "gfx1", 0 )
- ROM_LOAD( "format_z.5", 0x0000, 0x2000, CRC(ba50be57) SHA1(aa37b644e8c1944b4c0ba81164d5a52be8ab491f) ) /* characters */
+ ROM_REGION( 0x2000, "tiles", 0 )
+ ROM_LOAD( "format_z.5", 0x0000, 0x2000, CRC(ba50be57) SHA1(aa37b644e8c1944b4c0ba81164d5a52be8ab491f) )
- ROM_REGION( 0x2000, "gfx2", 0 ) // starfield data
- ROM_LOAD( "format_z.4", 0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) ) /* characters */
+ ROM_REGION( 0x2000, "starfield_data", 0 ) // starfield data
+ ROM_LOAD( "format_z.4", 0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) )
- ROM_REGION( 0x3000, "gfx3", 0 )
- ROM_LOAD( "format_z.1", 0x0000, 0x1000, CRC(5739afd2) SHA1(3a645bc8a5ac69f1dc878a589c580f2bf033d3cb) ) /* sprites */
- ROM_LOAD( "format_z.2", 0x1000, 0x1000, CRC(3a821391) SHA1(476507ba5e5d64ca3729244590beadb9b3a6a018) ) /* sprites */
- ROM_LOAD( "format_z.3", 0x2000, 0x1000, CRC(7d1aec79) SHA1(bb19d6c91a14df26706226cfe22853bb8383c63d) ) /* sprites */
+ ROM_REGION( 0x3000, "sprites", 0 )
+ ROM_LOAD( "format_z.1", 0x0000, 0x1000, CRC(5739afd2) SHA1(3a645bc8a5ac69f1dc878a589c580f2bf033d3cb) )
+ ROM_LOAD( "format_z.2", 0x1000, 0x1000, CRC(3a821391) SHA1(476507ba5e5d64ca3729244590beadb9b3a6a018) )
+ ROM_LOAD( "format_z.3", 0x2000, 0x1000, CRC(7d1aec79) SHA1(bb19d6c91a14df26706226cfe22853bb8383c63d) )
ROM_REGION( 0x0300, "proms", 0 )
ROM_LOAD( "10c", 0x0000, 0x0100, CRC(b756dd6d) SHA1(ea79f87f84ded2f0a66458af24cbc792e5ff77e3) )
@@ -324,16 +620,16 @@ ROM_START( aeroboto )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "format_z.9", 0xf000, 0x1000, CRC(6b9215ad) SHA1(3ab416d070bf6b9a8be3e19d4dbc3a399d9ab5cb) )
- ROM_REGION( 0x2000, "gfx1", 0 )
- ROM_LOAD( "aeroboto.5", 0x0000, 0x2000, CRC(32fc00f9) SHA1(fd912fe2ab0101057c15c846f0cc4259cd94b035) ) /* characters */
+ ROM_REGION( 0x2000, "tiles", 0 )
+ ROM_LOAD( "aeroboto.5", 0x0000, 0x2000, CRC(32fc00f9) SHA1(fd912fe2ab0101057c15c846f0cc4259cd94b035) )
- ROM_REGION( 0x2000, "gfx2", 0 ) // starfield data
- ROM_LOAD( "format_z.4", 0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) ) /* characters */
+ ROM_REGION( 0x2000, "starfield_data", 0 ) // starfield data
+ ROM_LOAD( "format_z.4", 0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) )
- ROM_REGION( 0x3000, "gfx3", 0 )
- ROM_LOAD( "aeroboto.1", 0x0000, 0x1000, CRC(7820eeaf) SHA1(dedd15295bb02f417d0f51a29df686b66b94dee1) ) /* sprites */
- ROM_LOAD( "aeroboto.2", 0x1000, 0x1000, CRC(c7f81a3c) SHA1(21476a4146d5c57e2b15125c304fc61d82edf4af) ) /* sprites */
- ROM_LOAD( "aeroboto.3", 0x2000, 0x1000, CRC(5203ad04) SHA1(d16eb370de9033793a502e23c82a3119cd633aa9) ) /* sprites */
+ ROM_REGION( 0x3000, "sprites", 0 )
+ ROM_LOAD( "aeroboto.1", 0x0000, 0x1000, CRC(7820eeaf) SHA1(dedd15295bb02f417d0f51a29df686b66b94dee1) )
+ ROM_LOAD( "aeroboto.2", 0x1000, 0x1000, CRC(c7f81a3c) SHA1(21476a4146d5c57e2b15125c304fc61d82edf4af) )
+ ROM_LOAD( "aeroboto.3", 0x2000, 0x1000, CRC(5203ad04) SHA1(d16eb370de9033793a502e23c82a3119cd633aa9) )
ROM_REGION( 0x0300, "proms", 0 )
ROM_LOAD( "10c", 0x0000, 0x0100, CRC(b756dd6d) SHA1(ea79f87f84ded2f0a66458af24cbc792e5ff77e3) )
@@ -341,6 +637,7 @@ ROM_START( aeroboto )
ROM_LOAD( "10a", 0x0200, 0x0100, CRC(e8733c8f) SHA1(105b44c9108ee173a417f8c79ec8381f824dd675) )
ROM_END
+} // anonymous namespace
GAME( 1984, formatz, 0, formatz, formatz, aeroboto_state, empty_init, ROT0, "Jaleco", "Formation Z", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/jaleco/aeroboto.h b/src/mame/jaleco/aeroboto.h
deleted file mode 100644
index 30610b7c0ed..00000000000
--- a/src/mame/jaleco/aeroboto.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Carlos A. Lozano, Uki
-/***************************************************************************
-
- Aeroboto
-
-***************************************************************************/
-#ifndef MAME_INCLUDES_AEROBOTO_H
-#define MAME_INCLUDES_AEROBOTO_H
-
-#pragma once
-
-#include "emupal.h"
-#include "tilemap.h"
-
-class aeroboto_state : public driver_device
-{
-public:
- aeroboto_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_mainram(*this, "mainram"),
- m_videoram(*this, "videoram"),
- m_hscroll(*this, "hscroll"),
- m_tilecolor(*this, "tilecolor"),
- m_spriteram(*this, "spriteram"),
- m_vscroll(*this, "vscroll"),
- m_starx(*this, "starx"),
- m_stary(*this, "stary"),
- m_bgcolor(*this, "bgcolor"),
- m_maincpu(*this, "maincpu"),
- m_audiocpu(*this, "audiocpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette")
- { }
-
- void formatz(machine_config &config);
-
-private:
- /* memory pointers */
- required_shared_ptr<uint8_t> m_mainram;
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_hscroll;
- required_shared_ptr<uint8_t> m_tilecolor;
- required_shared_ptr<uint8_t> m_spriteram;
- required_shared_ptr<uint8_t> m_vscroll;
- required_shared_ptr<uint8_t> m_starx;
- required_shared_ptr<uint8_t> m_stary;
- required_shared_ptr<uint8_t> m_bgcolor;
-
- /* stars layout */
- uint8_t * m_stars_rom = 0U;
- int m_stars_length = 0;
-
- /* video-related */
- tilemap_t *m_bg_tilemap = nullptr;
- int m_charbank = 0;
- int m_starsoff = 0;
- int m_sx = 0;
- int m_sy = 0;
- uint8_t m_ox = 0U;
- uint8_t m_oy = 0U;
-
- /* misc */
- int m_count = 0;
- int m_disable_irq = 0;
- uint8_t aeroboto_201_r();
- uint8_t aeroboto_irq_ack_r();
- uint8_t aeroboto_2973_r();
- void aeroboto_1a2_w(uint8_t data);
- uint8_t aeroboto_in0_r();
- void aeroboto_3000_w(uint8_t data);
- void aeroboto_videoram_w(offs_t offset, uint8_t data);
- void aeroboto_tilecolor_w(offs_t offset, uint8_t data);
- TILE_GET_INFO_MEMBER(get_tile_info);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
- uint32_t screen_update_aeroboto(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(vblank_irq);
- void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
- required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_audiocpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- void main_map(address_map &map);
- void sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_AEROBOTO_H
diff --git a/src/mame/jaleco/aeroboto_v.cpp b/src/mame/jaleco/aeroboto_v.cpp
deleted file mode 100644
index 42e3a5070a3..00000000000
--- a/src/mame/jaleco/aeroboto_v.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Carlos A. Lozano, Uki
-/***************************************************************************
-
- video/aeroboto.c
-
-***************************************************************************/
-
-
-#include "emu.h"
-#include "aeroboto.h"
-
-
-// how the starfield ROM is interpreted: 0=256x256x1 linear bitmap, 1=8x8x1x1024 tilemap
-#define STARS_LAYOUT 1
-
-// scroll speed of the stars: 1=normal, 2=half, 3=one-third...etc.(possitive integers only)
-#define SCROLL_SPEED 1
-
-/***************************************************************************
-
- Callbacks for the TileMap code
-
-***************************************************************************/
-
-TILE_GET_INFO_MEMBER(aeroboto_state::get_tile_info)
-{
- uint8_t code = m_videoram[tile_index];
- tileinfo.set(0,
- code + (m_charbank << 8),
- m_tilecolor[code],
- (m_tilecolor[code] >= 0x33) ? 0 : TILE_FORCE_LAYER0);
-}
-// transparency should only affect tiles with color 0x33 or higher
-
-
-/***************************************************************************
-
- Start the video hardware emulation.
-
-***************************************************************************/
-
-void aeroboto_state::video_start()
-{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aeroboto_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 64);
- m_bg_tilemap->set_transparent_pen(0);
- m_bg_tilemap->set_scroll_rows(64);
-
- save_item(NAME(m_charbank));
- save_item(NAME(m_starsoff));
- save_item(NAME(m_sx));
- save_item(NAME(m_sy));
- save_item(NAME(m_ox));
- save_item(NAME(m_oy));
-
- #if STARS_LAYOUT
- {
- int i;
-
- std::vector<uint8_t> temp(m_stars_length);
- memcpy(&temp[0], m_stars_rom, m_stars_length);
-
- for (i = 0; i < m_stars_length; i++)
- m_stars_rom[(i & ~0xff) + (i << 5 & 0xe0) + (i >> 3 & 0x1f)] = temp[i];
- }
- #endif
-}
-
-
-
-/***************************************************************************
-
- Memory handlers
-
-***************************************************************************/
-
-uint8_t aeroboto_state::aeroboto_in0_r()
-{
- return ioport(flip_screen() ? "P2" : "P1")->read();
-}
-
-void aeroboto_state::aeroboto_3000_w(uint8_t data)
-{
- /* bit 0 selects both flip screen and player1/player2 controls */
- flip_screen_set(data & 0x01);
-
- /* bit 1 = char bank select */
- if (m_charbank != ((data & 0x02) >> 1))
- {
- m_bg_tilemap->mark_all_dirty();
- m_charbank = (data & 0x02) >> 1;
- }
-
- /* bit 2 = disable star field? */
- m_starsoff = data & 0x4;
-}
-
-void aeroboto_state::aeroboto_videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_bg_tilemap->mark_tile_dirty(offset);
-}
-
-void aeroboto_state::aeroboto_tilecolor_w(offs_t offset, uint8_t data)
-{
- if (m_tilecolor[offset] != data)
- {
- m_tilecolor[offset] = data;
- m_bg_tilemap->mark_all_dirty();
- }
-}
-
-
-
-/***************************************************************************
-
- Display refresh
-
-***************************************************************************/
-
-void aeroboto_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
- {
- int x = m_spriteram[offs + 3];
- int y = 240 - m_spriteram[offs];
-
- if (flip_screen())
- {
- x = 248 - x;
- y = 240 - y;
- }
-
- m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
- m_spriteram[offs + 1],
- m_spriteram[offs + 2] & 0x07,
- flip_screen(), flip_screen(),
- ((x + 8) & 0xff) - 8, y, 0);
- }
-}
-
-
-uint32_t aeroboto_state::screen_update_aeroboto(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- rectangle const splitrect1(0, 255, 0, 39);
- rectangle const splitrect2(0, 255, 40, 255);
- int sky_color, star_color;
-
- sky_color = star_color = *m_bgcolor << 2;
-
- // the star field is supposed to be seen through tile pen 0 when active
- if (!m_starsoff)
- {
- if (star_color < 0xd0)
- {
- star_color = 0xd0;
- sky_color = 0;
- }
-
- star_color += 2;
-
- bitmap.fill(sky_color, cliprect);
-
- // actual scroll speed is unknown but it can be adjusted by changing the SCROLL_SPEED constant
- m_sx += char(*m_starx - m_ox);
- m_ox = *m_starx;
- int const x = m_sx / SCROLL_SPEED;
-
- if (*m_vscroll != 0xff)
- m_sy += char(*m_stary - m_oy);
- m_oy = *m_stary;
- int const y = m_sy / SCROLL_SPEED;
-
- uint8_t const *const src_base = m_stars_rom;
-
- for (int i = 0; i < 256; i++)
- {
- int src_offsx = (x + i) & 0xff;
- int const src_colmask = 1 << (src_offsx & 7);
- src_offsx >>= 3;
- uint8_t const *const src_colptr = src_base + src_offsx;
- int const pen = star_color + ((i + 8) >> 4 & 1);
-
- for (int j = 0; j < 256; j++)
- {
- uint8_t const *const src_rowptr = src_colptr + (((y + j) & 0xff) << 5 );
- if (!((unsigned)*src_rowptr & src_colmask))
- bitmap.pix(j, i) = pen;
- }
- }
- }
- else
- {
- m_sx = m_ox = *m_starx;
- m_sy = m_oy = *m_stary;
- bitmap.fill(sky_color, cliprect);
- }
-
- for (int y = 0; y < 64; y++)
- m_bg_tilemap->set_scrollx(y, m_hscroll[y]);
-
- // the playfield is part of a splitscreen and should not overlap with status display
- m_bg_tilemap->set_scrolly(0, *m_vscroll);
- m_bg_tilemap->draw(screen, bitmap, splitrect2, 0, 0);
-
- draw_sprites(bitmap, cliprect);
-
- // the status display behaves more closely to a 40-line splitscreen than an overlay
- m_bg_tilemap->set_scrolly(0, 0);
- m_bg_tilemap->draw(screen, bitmap, splitrect1, 0, 0);
- return 0;
-}
diff --git a/src/mame/jaleco/exerion.cpp b/src/mame/jaleco/exerion.cpp
index 430cf7c00af..b2cf80f0065 100644
--- a/src/mame/jaleco/exerion.cpp
+++ b/src/mame/jaleco/exerion.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders: Aaron Giles
+
/***************************************************************************
Jaleco Exerion hardware
@@ -44,15 +45,15 @@ Stephh's notes (based on the games Z80 code and some tests) :
to 0x4dff (code at 0x07d8) if 1st score in the high-score table is >= 80000.
If checksum doesn't match the hardcoded value (0x63), you get 255 credits !
Notice that the displayed number of credits won't be correct as the game
- isn't suppose to allow more than 9 credits.
- - In a 2 players game, when player changes, if player it was player 2 turn,
+ isn't supposed to allow more than 9 credits.
+ - In a 2 players game, when player changes, if it was player 2 turn,
values from 0x6030 to 0x6032 (see above) are compared with hard-coded values
(code at 0x04c8). If they don't match respectively 0xfe, 0xb3 and 0x4c,
and if 9th score in the high-score table is not 0, the game resets !
- Before entering player's initials, a checksum is computed from 0x5f00 to 0x5fff
(code at 0x5bd0) if player has reached level 6 (2nd kind of enemies after bonus
stage). If checksum doesn't match the hardcoded value (0x9a), the game resets !
- - There is sort of protection routine at 0x4120 which has an effect when
+ - There is a sort of protection routine at 0x4120 which has an effect when
player loses a life on reaching first bonus stage or after. If values read
from 0x6008 to 0x600b don't match values from ROM area 0x33c0-0x33ff,
the game resets. See 'protection_r' read handler.
@@ -120,14 +121,509 @@ Stephh's notes (based on the games Z80 code and some tests) :
***************************************************************************/
#include "emu.h"
-#include "exerion.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "sound/ay8910.h"
+#include "video/resnet.h"
+
+#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
+// configurable logging
+#define LOG_AYPORTB (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_AYPORTB)
+
+#include "logmacro.h"
+
+#define LOGAYPORTB(...) LOGMASKED(LOG_AYPORTB, __VA_ARGS__)
+
+
+namespace {
+
+class exerion_state : public driver_device
+{
+public:
+ exerion_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_main_ram(*this, "main_ram"),
+ m_videoram(*this, "videoram"),
+ m_spriteram(*this, "spriteram"),
+ m_maincpu_region(*this, "maincpu"),
+ m_background_mixer(*this, "bg_char_mixer_prom"),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_inputs(*this, "P%u", 1U)
+ { }
+
+ void exerion(machine_config &config);
+ void irion(machine_config &config);
+
+ void init_exerion();
+ void init_exerionb();
+ void init_irion();
+
+ DECLARE_CUSTOM_INPUT_MEMBER(controls_r);
+ DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ // memory pointers
+ required_shared_ptr<uint8_t> m_main_ram;
+ required_shared_ptr<uint8_t> m_videoram;
+ required_shared_ptr<uint8_t> m_spriteram;
+ required_region_ptr<uint8_t> m_maincpu_region;
+ required_region_ptr<uint8_t> m_background_mixer;
+
+ // video-related
+ uint8_t m_cocktail_flip = 0U;
+ uint8_t m_char_palette = 0U;
+ uint8_t m_sprite_palette = 0U;
+ uint8_t m_char_bank = 0U;
+ std::unique_ptr<uint16_t[]> m_background_gfx[4]{};
+ uint8_t m_background_latches[13]{};
+
+ // protection?
+ uint8_t m_porta = 0U;
+ uint8_t m_portb = 0U;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+
+ required_ioport_array<2> m_inputs;
+
+ uint8_t protection_r(offs_t offset);
+ void videoreg_w(uint8_t data);
+ void video_latch_w(offs_t offset, uint8_t data);
+ uint8_t video_timing_r();
+ uint8_t porta_r();
+ void portb_w(uint8_t data);
+ void palette(palette_device &palette) const;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void main_map(address_map &map);
+ void sub_map(address_map &map);
+};
+
+
+// video
+
+static constexpr XTAL MASTER_CLOCK = XTAL(19'968'000); // verified on PCB
+static constexpr XTAL CPU_CLOCK = MASTER_CLOCK / 6;
+static constexpr XTAL AY8910_CLOCK = CPU_CLOCK / 2;
+static constexpr XTAL PIXEL_CLOCK = MASTER_CLOCK / 3;
+static constexpr int HCOUNT_START = 0x58;
+static constexpr int HTOTAL = 512 - HCOUNT_START;
+static constexpr int HBEND = 12 * 8; // ??
+static constexpr int HBSTART = 52 * 8; // ??
+static constexpr int VTOTAL = 256;
+static constexpr int VBEND = 16;
+static constexpr int VBSTART = 240;
+
+static constexpr int BACKGROUND_X_START = 32;
+
+static constexpr int VISIBLE_X_MIN = 12 * 8;
+static constexpr int VISIBLE_X_MAX = 52 * 8;
+static constexpr int VISIBLE_Y_MIN = 2 * 8;
+static constexpr int VISIBLE_Y_MAX = 30 * 8;
+
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ The palette PROM is connected to the RGB output this way:
+
+ bit 7 -- 220 ohm resistor -- BLUE
+ -- 470 ohm resistor -- BLUE
+ -- 220 ohm resistor -- GREEN
+ -- 470 ohm resistor -- GREEN
+ -- 1 kohm resistor -- GREEN
+ -- 220 ohm resistor -- RED
+ -- 470 ohm resistor -- RED
+ bit 0 -- 1 kohm resistor -- RED
+
+***************************************************************************/
+
+void exerion_state::palette(palette_device &palette) const
+{
+ const uint8_t *color_prom = memregion("proms")->base();
+ static constexpr int resistances_rg[3] = { 1000, 470, 220 };
+ static constexpr int resistances_b [2] = { 470, 220 };
+
+ // compute the color output resistor weights
+ double rweights[3], gweights[3], bweights[2];
+ compute_resistor_weights(0, 255, -1.0,
+ 3, &resistances_rg[0], rweights, 0, 0,
+ 3, &resistances_rg[0], gweights, 0, 0,
+ 2, &resistances_b[0], bweights, 0, 0);
+
+ // create a lookup table for the palette
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1, bit2;
+
+ // red component
+ bit0 = BIT(color_prom[i], 0);
+ bit1 = BIT(color_prom[i], 1);
+ bit2 = BIT(color_prom[i], 2);
+ int const r = combine_weights(rweights, bit0, bit1, bit2);
+
+ // green component
+ bit0 = BIT(color_prom[i], 3);
+ bit1 = BIT(color_prom[i], 4);
+ bit2 = BIT(color_prom[i], 5);
+ int const g = combine_weights(gweights, bit0, bit1, bit2);
+
+ // blue component
+ bit0 = BIT(color_prom[i], 6);
+ bit1 = BIT(color_prom[i], 7);
+ int const b = combine_weights(bweights, bit0, bit1);
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ // color_prom now points to the beginning of the lookup table
+ color_prom += 0x20;
+
+ // fg chars and sprites
+ for (int i = 0; i < 0x200; i++)
+ {
+ uint8_t const ctabentry = 0x10 | (color_prom[(i & 0x1c0) | ((i & 3) << 4) | ((i >> 2) & 0x0f)] & 0x0f);
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ // bg chars (this is not the full story... there are four layers mixed using another PROM)
+ for (int i = 0x200; i < 0x300; i++)
+ {
+ uint8_t const ctabentry = color_prom[i] & 0x0f;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+}
+
+
+
+/*************************************
+ *
+ * Video system startup
+ *
+ *************************************/
+
+void exerion_state::video_start()
+{
+ // allocate memory for the decoded background graphics
+ m_background_gfx[0] = std::make_unique<uint16_t[]>(256 * 256);
+ m_background_gfx[1] = std::make_unique<uint16_t[]>(256 * 256);
+ m_background_gfx[2] = std::make_unique<uint16_t[]>(256 * 256);
+ m_background_gfx[3] = std::make_unique<uint16_t[]>(256 * 256);
+
+ save_pointer(NAME(m_background_gfx[0]), 256 * 256);
+ save_pointer(NAME(m_background_gfx[1]), 256 * 256);
+ save_pointer(NAME(m_background_gfx[2]), 256 * 256);
+ save_pointer(NAME(m_background_gfx[3]), 256 * 256);
+
+ m_cocktail_flip = 0;
+
+ /*---------------------------------
+ * Decode the background graphics
+ *
+ * We decode the 4 background layers separately, but shuffle the bits so that
+ * we can OR all four layers together. Each layer has 2 bits per pixel. Each
+ * layer is decoded into the following bit patterns:
+ *
+ * 000a 0000 00AA
+ * 00b0 0000 BB00
+ * 0c00 00CC 0000
+ * d000 DD00 0000
+ *
+ * Where AA,BB,CC,DD are the 2bpp data for the pixel,and a,b,c,d are the OR
+ * of these two bits together.
+ */
+ uint8_t *gfx = memregion("bgdata")->base();
+ for (int i = 0; i < 4; i++)
+ {
+ uint8_t *src = gfx + i * 0x2000;
+ uint16_t *dst = m_background_gfx[i].get();
+
+ for (int y = 0; y < 0x100; y++)
+ {
+ int x;
+
+ for (x = 0; x < 0x80; x += 4)
+ {
+ uint8_t data = *src++;
+ uint16_t val;
+
+ val = ((data >> 3) & 2) | ((data >> 0) & 1);
+ if (val) val |= 0x100 >> i;
+ *dst++ = val << (2 * i);
+
+ val = ((data >> 4) & 2) | ((data >> 1) & 1);
+ if (val) val |= 0x100 >> i;
+ *dst++ = val << (2 * i);
+
+ val = ((data >> 5) & 2) | ((data >> 2) & 1);
+ if (val) val |= 0x100 >> i;
+ *dst++ = val << (2 * i);
+
+ val = ((data >> 6) & 2) | ((data >> 3) & 1);
+ if (val) val |= 0x100 >> i;
+ *dst++ = val << (2 * i);
+ }
+
+ for (; x < 0x100; x++)
+ *dst++ = 0;
+ }
+ }
+}
+
+
+
+/*************************************
+ *
+ * Video register I/O
+ *
+ *************************************/
+
+void exerion_state::videoreg_w(uint8_t data)
+{
+ // bit 0 = flip screen and joystick input multiplexer
+ m_cocktail_flip = data & 1;
+
+ // bits 1-2 char lookup table bank
+ m_char_palette = (data & 0x06) >> 1;
+
+ // bits 3 char bank
+ m_char_bank = (data & 0x08) >> 3;
+
+ // bits 4-5 unused
+
+ // bits 6-7 sprite lookup table bank
+ m_sprite_palette = (data & 0xc0) >> 6;
+}
+
+
+void exerion_state::video_latch_w(offs_t offset, uint8_t data)
+{
+ int const scanline = m_screen->vpos();
+ if (scanline > 0)
+ m_screen->update_partial(scanline - 1);
+ m_background_latches[offset] = data;
+}
+
+
+uint8_t exerion_state::video_timing_r()
+{
+ // bit 0 is the SNMI signal, which is the negated value of H6, if H7=1 & H8=1 & VBLANK=0, otherwise 1
+ // bit 1 is VBLANK
+
+ uint16_t const hcounter = m_screen->hpos() + HCOUNT_START;
+ uint8_t snmi = 1;
+
+ if (((hcounter & 0x180) == 0x180) && !m_screen->vblank())
+ snmi = !((hcounter >> 6) & 0x01);
+
+ return (m_screen->vblank() << 1) | snmi;
+}
+
+
+/*************************************
+ *
+ * Background rendering
+ *
+ *************************************/
+
+void exerion_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // loop over all visible scanlines
+ for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ uint16_t const *src0 = &m_background_gfx[0][m_background_latches[1] * 256];
+ uint16_t const *src1 = &m_background_gfx[1][m_background_latches[3] * 256];
+ uint16_t const *src2 = &m_background_gfx[2][m_background_latches[5] * 256];
+ uint16_t const *src3 = &m_background_gfx[3][m_background_latches[7] * 256];
+ int xoffs0 = m_background_latches[0];
+ int xoffs1 = m_background_latches[2];
+ int xoffs2 = m_background_latches[4];
+ int xoffs3 = m_background_latches[6];
+ int start0 = m_background_latches[8] & 0x0f;
+ int start1 = m_background_latches[9] & 0x0f;
+ int start2 = m_background_latches[10] & 0x0f;
+ int start3 = m_background_latches[11] & 0x0f;
+ int stop0 = m_background_latches[8] >> 4;
+ int stop1 = m_background_latches[9] >> 4;
+ int stop2 = m_background_latches[10] >> 4;
+ int stop3 = m_background_latches[11] >> 4;
+ uint8_t *const mixer = &m_background_mixer[(m_background_latches[12] << 4) & 0xf0];
+ uint16_t scanline[VISIBLE_X_MAX];
+ pen_t const pen_base = 0x200 + ((m_background_latches[12] >> 4) << 4);
+
+ // the cocktail flip flag controls whether we count up or down in X
+ if (!m_cocktail_flip)
+ {
+ // skip processing anything that's not visible
+ for (int x = BACKGROUND_X_START; x < cliprect.min_x; x++)
+ {
+ if (!(++xoffs0 & 0x1f)) start0++, stop0++;
+ if (!(++xoffs1 & 0x1f)) start1++, stop1++;
+ if (!(++xoffs2 & 0x1f)) start2++, stop2++;
+ if (!(++xoffs3 & 0x1f)) start3++, stop3++;
+ }
+
+ // draw the rest of the scanline fully
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ uint16_t combined = 0;
+
+ // the output enable is controlled by the carries on the start/stop counters
+ // they are only active when the start has carried but the stop hasn't
+ if ((start0 ^ stop0) & 0x10) combined |= src0[xoffs0 & 0xff];
+ if ((start1 ^ stop1) & 0x10) combined |= src1[xoffs1 & 0xff];
+ if ((start2 ^ stop2) & 0x10) combined |= src2[xoffs2 & 0xff];
+ if ((start3 ^ stop3) & 0x10) combined |= src3[xoffs3 & 0xff];
+
+ // bits 8-11 of the combined value contains the lookup for the mixer PROM
+ uint8_t const lookupval = mixer[combined >> 8] & 3;
+
+ // the color index comes from the looked up value combined with the pixel data
+ scanline[x] = pen_base | (lookupval << 2) | ((combined >> (2 * lookupval)) & 3);
+
+ // the start/stop counters are clocked when the low 5 bits of the X counter overflow
+ if (!(++xoffs0 & 0x1f)) start0++, stop0++;
+ if (!(++xoffs1 & 0x1f)) start1++, stop1++;
+ if (!(++xoffs2 & 0x1f)) start2++, stop2++;
+ if (!(++xoffs3 & 0x1f)) start3++, stop3++;
+ }
+ }
+ else
+ {
+ // skip processing anything that's not visible
+ for (int x = BACKGROUND_X_START; x < cliprect.min_x; x++)
+ {
+ if (!(xoffs0-- & 0x1f)) start0++, stop0++;
+ if (!(xoffs1-- & 0x1f)) start1++, stop1++;
+ if (!(xoffs2-- & 0x1f)) start2++, stop2++;
+ if (!(xoffs3-- & 0x1f)) start3++, stop3++;
+ }
+
+ // draw the rest of the scanline fully
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ uint16_t combined = 0;
+
+ // the output enable is controlled by the carries on the start/stop counters
+ // they are only active when the start has carried but the stop hasn't
+ if ((start0 ^ stop0) & 0x10) combined |= src0[xoffs0 & 0xff];
+ if ((start1 ^ stop1) & 0x10) combined |= src1[xoffs1 & 0xff];
+ if ((start2 ^ stop2) & 0x10) combined |= src2[xoffs2 & 0xff];
+ if ((start3 ^ stop3) & 0x10) combined |= src3[xoffs3 & 0xff];
+
+ // bits 8-11 of the combined value contains the lookup for the mixer PROM
+ uint8_t const lookupval = mixer[combined >> 8] & 3;
+
+ // the color index comes from the looked up value combined with the pixel data
+ scanline[x] = pen_base | (lookupval << 2) | ((combined >> (2 * lookupval)) & 3);
+
+ // the start/stop counters are clocked when the low 5 bits of the X counter overflow
+ if (!(xoffs0-- & 0x1f)) start0++, stop0++;
+ if (!(xoffs1-- & 0x1f)) start1++, stop1++;
+ if (!(xoffs2-- & 0x1f)) start2++, stop2++;
+ if (!(xoffs3-- & 0x1f)) start3++, stop3++;
+ }
+ }
+
+ // draw the scanline
+ draw_scanline16(bitmap, cliprect.min_x, y, cliprect.width(), &scanline[cliprect.min_x], nullptr);
+ }
+}
+
+
+/*************************************
+ *
+ * Core refresh routine
+ *
+ *************************************/
+
+uint32_t exerion_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // draw background
+ draw_background(bitmap, cliprect);
+
+ // draw sprites
+ for (int i = 0; i < m_spriteram.bytes(); i += 4)
+ {
+ int const flags = m_spriteram[i + 0];
+ int y = m_spriteram[i + 1] ^ 255;
+ int code = m_spriteram[i + 2];
+ int x = m_spriteram[i + 3] * 2 + 72;
+
+ int xflip = flags & 0x80;
+ int yflip = flags & 0x40;
+ int const doubled = flags & 0x10;
+ int const wide = flags & 0x08;
+ int code2 = code;
+
+ int const color = ((flags >> 1) & 0x03) | ((code >> 5) & 0x04) | (code & 0x08) | (m_sprite_palette * 16);
+ gfx_element *gfx = doubled ? m_gfxdecode->gfx(2) : m_gfxdecode->gfx(1);
+
+ if (m_cocktail_flip)
+ {
+ x = 64 * 8 - gfx->width() - x;
+ y = 32 * 8 - gfx->height() - y;
+ if (wide) y -= gfx->height();
+ xflip = !xflip;
+ yflip = !yflip;
+ }
+
+ if (wide)
+ {
+ if (yflip)
+ code |= 0x10, code2 &= ~0x10;
+ else
+ code &= ~0x10, code2 |= 0x10;
+
+ gfx->transmask(bitmap, cliprect, code2, color, xflip, yflip, x, y + gfx->height(),
+ m_palette->transpen_mask(*gfx, color, 0x10));
+ }
+
+ gfx->transmask(bitmap, cliprect, code, color, xflip, yflip, x, y,
+ m_palette->transpen_mask(*gfx, color, 0x10));
+
+ if (doubled) i += 4;
+ }
+
+ // draw the visible text layer
+ for (int sy = cliprect.min_y / 8; sy <= cliprect.max_y / 8; sy++)
+ for (int sx = VISIBLE_X_MIN / 8; sx < VISIBLE_X_MAX / 8; sx++)
+ {
+ int const x = m_cocktail_flip ? (63 * 8 - 8 * sx) : 8 * sx;
+ int const y = m_cocktail_flip ? (31 * 8 - 8 * sy) : 8 * sy;
+
+ int const offs = sx + sy * 64;
+ m_gfxdecode->gfx(0)->transpen(bitmap, cliprect,
+ m_videoram[offs] + 256 * m_char_bank,
+ ((m_videoram[offs] & 0xf0) >> 4) + m_char_palette * 16,
+ m_cocktail_flip, m_cocktail_flip, x, y, 0);
+ }
+
+ return 0;
+}
+
+
+// machine
+
/*************************************
*
* Interrupts & inputs
@@ -170,7 +666,7 @@ void exerion_state::portb_w(uint8_t data)
m_porta = m_maincpu_region[0x5f76];
m_portb = data;
- logerror("Port B = %02X\n", data);
+ LOGAYPORTB("Port B = %02X\n", data);
}
@@ -371,30 +867,30 @@ void exerion_state::machine_reset()
void exerion_state::exerion(machine_config &config)
{
- Z80(config, m_maincpu, EXERION_CPU_CLOCK);
+ Z80(config, m_maincpu, CPU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &exerion_state::main_map);
- z80_device &sub(Z80(config, "sub", EXERION_CPU_CLOCK));
+ z80_device &sub(Z80(config, "sub", CPU_CLOCK));
sub.set_addrmap(AS_PROGRAM, &exerion_state::sub_map);
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_raw(EXERION_PIXEL_CLOCK, EXERION_HTOTAL, EXERION_HBEND, EXERION_HBSTART, EXERION_VTOTAL, EXERION_VBEND, EXERION_VBSTART);
+ m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);
m_screen->set_screen_update(FUNC(exerion_state::screen_update));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_exerion);
- PALETTE(config, m_palette, FUNC(exerion_state::palette), 256*3, 32);
+ PALETTE(config, m_palette, FUNC(exerion_state::palette), 256 * 3, 32);
// audio hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch");
- AY8910(config, "ay1", EXERION_AY8910_CLOCK).add_route(ALL_OUTPUTS, "mono", 0.30);
+ AY8910(config, "ay1", AY8910_CLOCK).add_route(ALL_OUTPUTS, "mono", 0.30);
- ay8910_device &ay2(AY8910(config, "ay2", EXERION_AY8910_CLOCK));
+ ay8910_device &ay2(AY8910(config, "ay2", AY8910_CLOCK));
ay2.port_a_read_callback().set(FUNC(exerion_state::porta_r));
ay2.port_b_write_callback().set(FUNC(exerion_state::portb_w));
ay2.add_route(ALL_OUTPUTS, "mono", 0.30);
@@ -673,7 +1169,7 @@ void exerion_state::init_exerionb()
void exerion_state::init_irion()
{
- // convert the gfx and cpu roms like in ExerionB
+ // convert the gfx and cpu ROMS like in ExerionB
init_exerionb();
// a further unscramble of gfx2
@@ -689,6 +1185,7 @@ void exerion_state::init_irion()
}
}
+} // anonymous namespace
/*************************************
diff --git a/src/mame/jaleco/exerion.h b/src/mame/jaleco/exerion.h
deleted file mode 100644
index cc4c4b41ab0..00000000000
--- a/src/mame/jaleco/exerion.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/*************************************************************************
-
- Jaleco Exerion
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_EXERION_H
-#define MAME_INCLUDES_EXERION_H
-
-#pragma once
-
-#include "emupal.h"
-#include "screen.h"
-
-
-#define EXERION_MASTER_CLOCK (XTAL(19'968'000)) /* verified on pcb */
-#define EXERION_CPU_CLOCK (EXERION_MASTER_CLOCK / 6)
-#define EXERION_AY8910_CLOCK (EXERION_CPU_CLOCK / 2)
-#define EXERION_PIXEL_CLOCK (EXERION_MASTER_CLOCK / 3)
-#define EXERION_HCOUNT_START (0x58)
-#define EXERION_HTOTAL (512-EXERION_HCOUNT_START)
-#define EXERION_HBEND (12*8) /* ?? */
-#define EXERION_HBSTART (52*8) /* ?? */
-#define EXERION_VTOTAL (256)
-#define EXERION_VBEND (16)
-#define EXERION_VBSTART (240)
-
-
-class exerion_state : public driver_device
-{
-public:
- exerion_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_main_ram(*this, "main_ram"),
- m_videoram(*this, "videoram"),
- m_spriteram(*this, "spriteram"),
- m_maincpu_region(*this, "maincpu"),
- m_background_mixer(*this, "bg_char_mixer_prom"),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_screen(*this, "screen"),
- m_palette(*this, "palette"),
- m_inputs(*this, "P%u", 1U)
- { }
-
- void exerion(machine_config &config);
- void irion(machine_config &config);
-
- void init_exerion();
- void init_exerionb();
- void init_irion();
-
- DECLARE_CUSTOM_INPUT_MEMBER(controls_r);
- DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- // memory pointers
- required_shared_ptr<uint8_t> m_main_ram;
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_spriteram;
- required_region_ptr<uint8_t> m_maincpu_region;
- required_region_ptr<uint8_t> m_background_mixer;
-
- // video-related
- uint8_t m_cocktail_flip = 0U;
- uint8_t m_char_palette = 0U;
- uint8_t m_sprite_palette = 0U;
- uint8_t m_char_bank = 0U;
- std::unique_ptr<uint16_t[]> m_background_gfx[4]{};
- uint8_t m_background_latches[13]{};
-
- // protection?
- uint8_t m_porta = 0U;
- uint8_t m_portb = 0U;
-
- // devices
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
-
- required_ioport_array<2> m_inputs;
-
- uint8_t protection_r(offs_t offset);
- void videoreg_w(uint8_t data);
- void video_latch_w(offs_t offset, uint8_t data);
- uint8_t video_timing_r();
- uint8_t porta_r();
- void portb_w(uint8_t data);
- void palette(palette_device &palette) const;
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_background( bitmap_ind16 &bitmap, const rectangle &cliprect);
- void main_map(address_map &map);
- void sub_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_EXERION_H
diff --git a/src/mame/jaleco/exerion_v.cpp b/src/mame/jaleco/exerion_v.cpp
deleted file mode 100644
index 78e85b78e9d..00000000000
--- a/src/mame/jaleco/exerion_v.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- Jaleco Exerion
-
-***************************************************************************/
-
-#include "emu.h"
-#include "video/resnet.h"
-#include "exerion.h"
-
-
-#define BACKGROUND_X_START 32
-
-#define VISIBLE_X_MIN (12*8)
-#define VISIBLE_X_MAX (52*8)
-#define VISIBLE_Y_MIN (2*8)
-#define VISIBLE_Y_MAX (30*8)
-
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- The palette PROM is connected to the RGB output this way:
-
- bit 7 -- 220 ohm resistor -- BLUE
- -- 470 ohm resistor -- BLUE
- -- 220 ohm resistor -- GREEN
- -- 470 ohm resistor -- GREEN
- -- 1 kohm resistor -- GREEN
- -- 220 ohm resistor -- RED
- -- 470 ohm resistor -- RED
- bit 0 -- 1 kohm resistor -- RED
-
-***************************************************************************/
-
-void exerion_state::palette(palette_device &palette) const
-{
- const uint8_t *color_prom = memregion("proms")->base();
- static constexpr int resistances_rg[3] = { 1000, 470, 220 };
- static constexpr int resistances_b [2] = { 470, 220 };
-
- // compute the color output resistor weights
- double rweights[3], gweights[3], bweights[2];
- compute_resistor_weights(0, 255, -1.0,
- 3, &resistances_rg[0], rweights, 0, 0,
- 3, &resistances_rg[0], gweights, 0, 0,
- 2, &resistances_b[0], bweights, 0, 0);
-
- // create a lookup table for the palette
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1, bit2;
-
- // red component
- bit0 = BIT(color_prom[i], 0);
- bit1 = BIT(color_prom[i], 1);
- bit2 = BIT(color_prom[i], 2);
- int const r = combine_weights(rweights, bit0, bit1, bit2);
-
- // green component
- bit0 = BIT(color_prom[i], 3);
- bit1 = BIT(color_prom[i], 4);
- bit2 = BIT(color_prom[i], 5);
- int const g = combine_weights(gweights, bit0, bit1, bit2);
-
- // blue component
- bit0 = BIT(color_prom[i], 6);
- bit1 = BIT(color_prom[i], 7);
- int const b = combine_weights(bweights, bit0, bit1);
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- // color_prom now points to the beginning of the lookup table
- color_prom += 0x20;
-
- // fg chars and sprites
- for (int i = 0; i < 0x200; i++)
- {
- uint8_t const ctabentry = 0x10 | (color_prom[(i & 0x1c0) | ((i & 3) << 4) | ((i >> 2) & 0x0f)] & 0x0f);
- palette.set_pen_indirect(i, ctabentry);
- }
-
- // bg chars (this is not the full story... there are four layers mixed using another PROM
- for (int i = 0x200; i < 0x300; i++)
- {
- uint8_t const ctabentry = color_prom[i] & 0x0f;
- palette.set_pen_indirect(i, ctabentry);
- }
-}
-
-
-
-/*************************************
- *
- * Video system startup
- *
- *************************************/
-
-void exerion_state::video_start()
-{
- // allocate memory for the decoded background graphics
- m_background_gfx[0] = std::make_unique<uint16_t[]>(256 * 256);
- m_background_gfx[1] = std::make_unique<uint16_t[]>(256 * 256);
- m_background_gfx[2] = std::make_unique<uint16_t[]>(256 * 256);
- m_background_gfx[3] = std::make_unique<uint16_t[]>(256 * 256);
-
- save_pointer(NAME(m_background_gfx[0]), 256 * 256);
- save_pointer(NAME(m_background_gfx[1]), 256 * 256);
- save_pointer(NAME(m_background_gfx[2]), 256 * 256);
- save_pointer(NAME(m_background_gfx[3]), 256 * 256);
-
- m_cocktail_flip = 0;
-
- /*---------------------------------
- * Decode the background graphics
- *
- * We decode the 4 background layers separately, but shuffle the bits so that
- * we can OR all four layers together. Each layer has 2 bits per pixel. Each
- * layer is decoded into the following bit patterns:
- *
- * 000a 0000 00AA
- * 00b0 0000 BB00
- * 0c00 00CC 0000
- * d000 DD00 0000
- *
- * Where AA,BB,CC,DD are the 2bpp data for the pixel,and a,b,c,d are the OR
- * of these two bits together.
- */
- uint8_t *gfx = memregion("bgdata")->base();
- for (int i = 0; i < 4; i++)
- {
- uint8_t *src = gfx + i * 0x2000;
- uint16_t *dst = m_background_gfx[i].get();
-
- for (int y = 0; y < 0x100; y++)
- {
- int x;
-
- for (x = 0; x < 0x80; x += 4)
- {
- uint8_t data = *src++;
- uint16_t val;
-
- val = ((data >> 3) & 2) | ((data >> 0) & 1);
- if (val) val |= 0x100 >> i;
- *dst++ = val << (2 * i);
-
- val = ((data >> 4) & 2) | ((data >> 1) & 1);
- if (val) val |= 0x100 >> i;
- *dst++ = val << (2 * i);
-
- val = ((data >> 5) & 2) | ((data >> 2) & 1);
- if (val) val |= 0x100 >> i;
- *dst++ = val << (2 * i);
-
- val = ((data >> 6) & 2) | ((data >> 3) & 1);
- if (val) val |= 0x100 >> i;
- *dst++ = val << (2 * i);
- }
-
- for (; x < 0x100; x++)
- *dst++ = 0;
- }
- }
-}
-
-
-
-/*************************************
- *
- * Video register I/O
- *
- *************************************/
-
-void exerion_state::videoreg_w(uint8_t data)
-{
- // bit 0 = flip screen and joystick input multiplexer
- m_cocktail_flip = data & 1;
-
- // bits 1-2 char lookup table bank
- m_char_palette = (data & 0x06) >> 1;
-
- // bits 3 char bank
- m_char_bank = (data & 0x08) >> 3;
-
- // bits 4-5 unused
-
- // bits 6-7 sprite lookup table bank
- m_sprite_palette = (data & 0xc0) >> 6;
-}
-
-
-void exerion_state::video_latch_w(offs_t offset, uint8_t data)
-{
- int scanline = m_screen->vpos();
- if (scanline > 0)
- m_screen->update_partial(scanline - 1);
- m_background_latches[offset] = data;
-}
-
-
-uint8_t exerion_state::video_timing_r()
-{
- // bit 0 is the SNMI signal, which is the negated value of H6, if H7=1 & H8=1 & VBLANK=0, otherwise 1
- // bit 1 is VBLANK
-
- uint16_t hcounter = m_screen->hpos() + EXERION_HCOUNT_START;
- uint8_t snmi = 1;
-
- if (((hcounter & 0x180) == 0x180) && !m_screen->vblank())
- snmi = !((hcounter >> 6) & 0x01);
-
- return (m_screen->vblank() << 1) | snmi;
-}
-
-
-/*************************************
- *
- * Background rendering
- *
- *************************************/
-
-void exerion_state::draw_background( bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // loop over all visible scanlines
- for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
- {
- uint16_t *src0 = &m_background_gfx[0][m_background_latches[1] * 256];
- uint16_t *src1 = &m_background_gfx[1][m_background_latches[3] * 256];
- uint16_t *src2 = &m_background_gfx[2][m_background_latches[5] * 256];
- uint16_t *src3 = &m_background_gfx[3][m_background_latches[7] * 256];
- int xoffs0 = m_background_latches[0];
- int xoffs1 = m_background_latches[2];
- int xoffs2 = m_background_latches[4];
- int xoffs3 = m_background_latches[6];
- int start0 = m_background_latches[8] & 0x0f;
- int start1 = m_background_latches[9] & 0x0f;
- int start2 = m_background_latches[10] & 0x0f;
- int start3 = m_background_latches[11] & 0x0f;
- int stop0 = m_background_latches[8] >> 4;
- int stop1 = m_background_latches[9] >> 4;
- int stop2 = m_background_latches[10] >> 4;
- int stop3 = m_background_latches[11] >> 4;
- uint8_t *mixer = &m_background_mixer[(m_background_latches[12] << 4) & 0xf0];
- uint16_t scanline[VISIBLE_X_MAX];
- pen_t pen_base = 0x200 + ((m_background_latches[12] >> 4) << 4);
-
- // the cocktail flip flag controls whether we count up or down in X
- if (!m_cocktail_flip)
- {
- // skip processing anything that's not visible
- for (int x = BACKGROUND_X_START; x < cliprect.min_x; x++)
- {
- if (!(++xoffs0 & 0x1f)) start0++, stop0++;
- if (!(++xoffs1 & 0x1f)) start1++, stop1++;
- if (!(++xoffs2 & 0x1f)) start2++, stop2++;
- if (!(++xoffs3 & 0x1f)) start3++, stop3++;
- }
-
- // draw the rest of the scanline fully
- for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
- {
- uint16_t combined = 0;
- uint8_t lookupval;
-
- // the output enable is controlled by the carries on the start/stop counters
- // they are only active when the start has carried but the stop hasn't
- if ((start0 ^ stop0) & 0x10) combined |= src0[xoffs0 & 0xff];
- if ((start1 ^ stop1) & 0x10) combined |= src1[xoffs1 & 0xff];
- if ((start2 ^ stop2) & 0x10) combined |= src2[xoffs2 & 0xff];
- if ((start3 ^ stop3) & 0x10) combined |= src3[xoffs3 & 0xff];
-
- // bits 8-11 of the combined value contains the lookup for the mixer PROM
- lookupval = mixer[combined >> 8] & 3;
-
- // the color index comes from the looked up value combined with the pixel data
- scanline[x] = pen_base | (lookupval << 2) | ((combined >> (2 * lookupval)) & 3);
-
- // the start/stop counters are clocked when the low 5 bits of the X counter overflow
- if (!(++xoffs0 & 0x1f)) start0++, stop0++;
- if (!(++xoffs1 & 0x1f)) start1++, stop1++;
- if (!(++xoffs2 & 0x1f)) start2++, stop2++;
- if (!(++xoffs3 & 0x1f)) start3++, stop3++;
- }
- }
- else
- {
- // skip processing anything that's not visible
- for (int x = BACKGROUND_X_START; x < cliprect.min_x; x++)
- {
- if (!(xoffs0-- & 0x1f)) start0++, stop0++;
- if (!(xoffs1-- & 0x1f)) start1++, stop1++;
- if (!(xoffs2-- & 0x1f)) start2++, stop2++;
- if (!(xoffs3-- & 0x1f)) start3++, stop3++;
- }
-
- // draw the rest of the scanline fully
- for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
- {
- uint16_t combined = 0;
- uint8_t lookupval;
-
- // the output enable is controlled by the carries on the start/stop counters
- // they are only active when the start has carried but the stop hasn't
- if ((start0 ^ stop0) & 0x10) combined |= src0[xoffs0 & 0xff];
- if ((start1 ^ stop1) & 0x10) combined |= src1[xoffs1 & 0xff];
- if ((start2 ^ stop2) & 0x10) combined |= src2[xoffs2 & 0xff];
- if ((start3 ^ stop3) & 0x10) combined |= src3[xoffs3 & 0xff];
-
- // bits 8-11 of the combined value contains the lookup for the mixer PROM
- lookupval = mixer[combined >> 8] & 3;
-
- // the color index comes from the looked up value combined with the pixel data
- scanline[x] = pen_base | (lookupval << 2) | ((combined >> (2 * lookupval)) & 3);
-
- // the start/stop counters are clocked when the low 5 bits of the X counter overflow
- if (!(xoffs0-- & 0x1f)) start0++, stop0++;
- if (!(xoffs1-- & 0x1f)) start1++, stop1++;
- if (!(xoffs2-- & 0x1f)) start2++, stop2++;
- if (!(xoffs3-- & 0x1f)) start3++, stop3++;
- }
- }
-
- // draw the scanline
- draw_scanline16(bitmap, cliprect.min_x, y, cliprect.width(), &scanline[cliprect.min_x], nullptr);
- }
-}
-
-
-/*************************************
- *
- * Core refresh routine
- *
- *************************************/
-
-uint32_t exerion_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // draw background
- draw_background(bitmap, cliprect);
-
- // draw sprites
- for (int i = 0; i < m_spriteram.bytes(); i += 4)
- {
- int flags = m_spriteram[i + 0];
- int y = m_spriteram[i + 1] ^ 255;
- int code = m_spriteram[i + 2];
- int x = m_spriteram[i + 3] * 2 + 72;
-
- int xflip = flags & 0x80;
- int yflip = flags & 0x40;
- int doubled = flags & 0x10;
- int wide = flags & 0x08;
- int code2 = code;
-
- int color = ((flags >> 1) & 0x03) | ((code >> 5) & 0x04) | (code & 0x08) | (m_sprite_palette * 16);
- gfx_element *gfx = doubled ? m_gfxdecode->gfx(2) : m_gfxdecode->gfx(1);
-
- if (m_cocktail_flip)
- {
- x = 64*8 - gfx->width() - x;
- y = 32*8 - gfx->height() - y;
- if (wide) y -= gfx->height();
- xflip = !xflip;
- yflip = !yflip;
- }
-
- if (wide)
- {
- if (yflip)
- code |= 0x10, code2 &= ~0x10;
- else
- code &= ~0x10, code2 |= 0x10;
-
- gfx->transmask(bitmap,cliprect, code2, color, xflip, yflip, x, y + gfx->height(),
- m_palette->transpen_mask(*gfx, color, 0x10));
- }
-
- gfx->transmask(bitmap,cliprect, code, color, xflip, yflip, x, y,
- m_palette->transpen_mask(*gfx, color, 0x10));
-
- if (doubled) i += 4;
- }
-
- // draw the visible text layer
- for (int sy = cliprect.min_y/8; sy <= cliprect.max_y/8; sy++)
- for (int sx = VISIBLE_X_MIN/8; sx < VISIBLE_X_MAX/8; sx++)
- {
- int x = m_cocktail_flip ? (63*8 - 8*sx) : 8*sx;
- int y = m_cocktail_flip ? (31*8 - 8*sy) : 8*sy;
-
- int offs = sx + sy * 64;
- m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
- m_videoram[offs] + 256 * m_char_bank,
- ((m_videoram[offs] & 0xf0) >> 4) + m_char_palette * 16,
- m_cocktail_flip, m_cocktail_flip, x, y, 0);
- }
-
- return 0;
-}
diff --git a/src/mame/jaleco/fcombat.cpp b/src/mame/jaleco/fcombat.cpp
index 214beff41a4..ae2b1f8c9af 100644
--- a/src/mame/jaleco/fcombat.cpp
+++ b/src/mame/jaleco/fcombat.cpp
@@ -1,11 +1,11 @@
// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
+// copyright-holders: Tomasz Slanina
/* Field Combat (c)1985 Jaleco
TS 2004.10.22.
- fixed sprite issues
- - added backgrounds and terrain info (external roms)
+ - added backgrounds and terrain info (external ROMs)
(press buttons 1+2 at the same time, to release 'army' ;)
@@ -32,26 +32,326 @@ inputs + notes by stephh
*/
#include "emu.h"
-#include "fcombat.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "sound/ay8910.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_PALETTEBANK (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_PALETTEBANK)
+
+#include "logmacro.h"
+
+#define LOGPALETTEBANK(...) LOGMASKED(LOG_PALETTEBANK, __VA_ARGS__)
+
+
+namespace {
+
+class fcombat_state : public driver_device
+{
+public:
+ fcombat_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_videoram(*this, "videoram"),
+ m_spriteram(*this, "spriteram"),
+ m_bgdata_rom(*this, "bgdata"),
+ m_terrain_rom(*this, "terrain_info"),
+ m_io_in(*this, "IN%u", 0U),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette")
+ { }
+
+ void fcombat(machine_config &config);
+
+ void init_fcombat();
+
+ DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ /* memory pointers */
+ required_shared_ptr<u8> m_videoram;
+ required_shared_ptr<u8> m_spriteram;
+ required_region_ptr<u8> m_bgdata_rom;
+ required_region_ptr<u8> m_terrain_rom;
+
+ required_ioport_array<2> m_io_in;
+
+ // video-related
+ tilemap_t *m_bgmap = nullptr;
+ u8 m_cocktail_flip = 0U;
+ u8 m_char_palette = 0U;
+ u8 m_sprite_palette = 0U;
+ u8 m_char_bank = 0U;
+
+ // misc
+ u8 m_fcombat_sh = 0;
+ u16 m_fcombat_sv = 0;
+ u8 m_tx = 0;
+ u8 m_ty = 0;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ u8 protection_r();
+ u8 port01_r();
+ void e900_w(u8 data);
+ void ea00_w(u8 data);
+ void eb00_w(u8 data);
+ void ec00_w(u8 data);
+ void ed00_w(u8 data);
+ u8 e300_r();
+ void ee00_w(u8 data);
+ void videoreg_w(u8 data);
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+ void fcombat_palette(palette_device &palette) const;
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void audio_map(address_map &map);
+ void main_map(address_map &map);
+};
+
+
+// video
+
+// this is copied from Exerion, but it should be correct
+static constexpr XTAL MASTER_CLOCK = 20_MHz_XTAL;
+static constexpr XTAL CPU_CLOCK = MASTER_CLOCK / 6;
+static constexpr XTAL AY8910_CLOCK = CPU_CLOCK / 2;
+static constexpr XTAL PIXEL_CLOCK = MASTER_CLOCK / 3;
+static constexpr int HCOUNT_START = 0x58;
+static constexpr int HTOTAL = 512 - HCOUNT_START;
+static constexpr int HBEND = 12 * 8; // ??
+static constexpr int HBSTART = 52 * 8; //
+static constexpr int VTOTAL = 256;
+static constexpr int VBEND = 16;
+static constexpr int VBSTART = 240;
+
+static constexpr int BACKGROUND_X_START = 32;
+static constexpr int BACKGROUND_X_START_FLIP = 72;
+
+static constexpr int VISIBLE_X_MIN = 12 * 8;
+static constexpr int VISIBLE_X_MAX = 52 * 8;
+static constexpr int VISIBLE_Y_MIN = 2 * 8;
+static constexpr int VISIBLE_Y_MAX = 30 * 8;
+
+
+TILE_GET_INFO_MEMBER(fcombat_state::get_bg_tile_info)
+{
+ //int palno = (tile_index - (tile_index / 32 * 16) * 32 * 16) / 32;
+
+ const int tileno = m_bgdata_rom[tile_index];
+ const int palno = 0x18; //m_terrain_rom[tile_index] >> 3;
+ tileinfo.set(2, tileno, palno, 0);
+}
+
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ The palette PROM is connected to the RGB output this way:
+
+ bit 7 -- 220 ohm resistor -- BLUE
+ -- 470 ohm resistor -- BLUE
+ -- 220 ohm resistor -- GREEN
+ -- 470 ohm resistor -- GREEN
+ -- 1 kohm resistor -- GREEN
+ -- 220 ohm resistor -- RED
+ -- 470 ohm resistor -- RED
+ bit 0 -- 1 kohm resistor -- RED
+
+***************************************************************************/
+
+void fcombat_state::fcombat_palette(palette_device &palette) const
+{
+ const u8 *color_prom = memregion("proms")->base();
+
+ // create a lookup table for the palette
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1, bit2;
+
+ // red component
+ bit0 = BIT(color_prom[i], 0);
+ bit1 = BIT(color_prom[i], 1);
+ bit2 = BIT(color_prom[i], 2);
+ const u8 r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ // green component
+ bit0 = BIT(color_prom[i], 3);
+ bit1 = BIT(color_prom[i], 4);
+ bit2 = BIT(color_prom[i], 5);
+ const u8 g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ // blue component
+ bit0 = 0;
+ bit1 = BIT(color_prom[i], 6);
+ bit2 = BIT(color_prom[i], 7);
+ const u8 b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ // color_prom now points to the beginning of the lookup table
+ color_prom += 0x20;
+
+ // fg chars/sprites
+ for (int i = 0; i < 0x200; i++)
+ {
+ const u8 ctabentry = (color_prom[(i & 0x1c0) | ((i & 3) << 4) | ((i >> 2) & 0x0f)] & 0x0f) | 0x10;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ // bg chars (this is not the full story... there are four layers mixed using another PROM)
+ for (int i = 0x200; i < 0x300; i++)
+ {
+ const u8 ctabentry = color_prom[i] & 0x0f;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+}
+
+
+/*************************************
+ *
+ * Video system startup
+ *
+ *************************************/
+void fcombat_state::video_start()
+{
+ m_bgmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(fcombat_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32 * 8 * 2, 32);
+}
+
+
+/*************************************
+ *
+ * Video register I/O
+ *
+ *************************************/
+
+void fcombat_state::videoreg_w(u8 data)
+{
+ // bit 0 = flip screen and joystick input multiplexer
+ m_cocktail_flip = data & 1;
+
+ // bits 1-2 char lookup table bank
+ m_char_palette = (data & 0x06) >> 1;
+
+ // bits 3 char bank
+ m_char_bank = (data & 0x08) >> 3;
+
+ // bits 4-5 unused
+
+ // bits 6-7 sprite lookup table bank
+ m_sprite_palette = 0; //(data & 0xc0) >> 6;
+ LOGPALETTEBANK("sprite palette bank: %02x", data);
+}
+
+
+u32 fcombat_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // draw background
+ m_bgmap->set_scrolly(0, m_fcombat_sh);
+ m_bgmap->set_scrollx(0, m_fcombat_sv - 24);
+
+ m_bgmap->mark_all_dirty();
+ m_bgmap->draw(screen, bitmap, cliprect, 0, 0);
+ //draw_background(bitmap, cliprect);
+
+ // draw sprites
+ for (int i = 0; i < m_spriteram.bytes(); i += 4)
+ {
+ const int flags = m_spriteram[i + 0];
+ int y = m_spriteram[i + 1] ^ 255;
+ int code = m_spriteram[i + 2] + ((flags & 0x20) << 3);
+ int x = m_spriteram[i + 3] * 2 + 72;
+
+ int xflip = flags & 0x80;
+ int yflip = flags & 0x40;
+ const bool doubled = false;// flags & 0x10;
+ const bool wide = flags & 0x08;
+ int code2 = code;
+
+ const int color = ((flags >> 1) & 0x03) | ((code >> 5) & 0x04) | (code & 0x08) | (m_sprite_palette * 16);
+ gfx_element *gfx = m_gfxdecode->gfx(1);
+
+ if (m_cocktail_flip)
+ {
+ x = 64 * 8 - gfx->width() - x;
+ y = 32 * 8 - gfx->height() - y;
+ if (wide) y -= gfx->height();
+ xflip = !xflip;
+ yflip = !yflip;
+ }
+
+ if (wide)
+ {
+ if (yflip)
+ code |= 0x10, code2 &= ~0x10;
+ else
+ code &= ~0x10, code2 |= 0x10;
+
+ gfx->transpen(bitmap, cliprect, code2, color, xflip, yflip, x, y + gfx->height(), 0);
+ }
+
+ if (flags & 0x10)
+ {
+ gfx->transpen(bitmap, cliprect, code2 + 16, color, xflip, yflip, x, y + gfx->height(), 0);
+ gfx->transpen(bitmap, cliprect, code2 + 16 * 2, color, xflip, yflip, x, y + 2 * gfx->height(), 0);
+ gfx->transpen(bitmap, cliprect, code2 + 16 * 3, color, xflip, yflip, x, y + 3 * gfx->height(), 0);
+
+ }
+
+ gfx->transpen(bitmap, cliprect, code, color, xflip, yflip, x, y, 0);
+
+ if (doubled) i += 4;
+ }
+
+ // draw the visible text layer
+ for (int sy = VISIBLE_Y_MIN / 8; sy < VISIBLE_Y_MAX / 8; sy++)
+ for (int sx = VISIBLE_X_MIN / 8; sx < VISIBLE_X_MAX / 8; sx++)
+ {
+ const int x = m_cocktail_flip ? (63 * 8 - 8 * sx) : 8 * sx;
+ const int y = m_cocktail_flip ? (31 * 8 - 8 * sy) : 8 * sy;
+
+ const int offs = sx + sy * 64;
+ m_gfxdecode->gfx(0)->transpen(bitmap, cliprect,
+ m_videoram[offs] + 256 * m_char_bank,
+ ((m_videoram[offs] & 0xf0) >> 4) + m_char_palette * 16,
+ m_cocktail_flip, m_cocktail_flip, x, y, 0);
+ }
+ return 0;
+}
+
+
+// machine
INPUT_CHANGED_MEMBER(fcombat_state::coin_inserted)
{
- /* coin insertion causes an NMI */
+ // coin insertion causes an NMI
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE);
}
-/* is it protection? */
+// is it protection?
u8 fcombat_state::protection_r()
{
- /* Must match ONE of these values after a "and $3E" intruction :
+ /* Must match ONE of these values after a "and $3E" instruction :
76F0: 1E 04 2E 26 34 32 3A 16 3E 36
@@ -61,11 +361,11 @@ u8 fcombat_state::protection_r()
}
-/* same as exerion again */
+// same as exerion again
u8 fcombat_state::port01_r()
{
- /* the cocktail flip bit muxes between ports 0 and 1 */
+ // the cocktail flip bit muxes between ports 0 and 1
return m_io_in[m_cocktail_flip ? 1 : 0]->read();
}
@@ -88,7 +388,7 @@ void fcombat_state::eb00_w(u8 data)
}
-// terrain info (ec00=x, ed00=y, return val in e300
+// terrain info (ec00=x, ed00=y, return val in e300)
void fcombat_state::ec00_w(u8 data)
{
@@ -105,7 +405,7 @@ u8 fcombat_state::e300_r()
const int wx = (m_tx + m_fcombat_sh) / 16;
const int wy = (m_ty * 2 + m_fcombat_sv) / 16;
- return m_user2_region[wx * 32 * 16 + wy];
+ return m_terrain_rom[wx * 32 * 16 + wy];
}
void fcombat_state::ee00_w(u8 data)
@@ -116,14 +416,14 @@ void fcombat_state::main_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0xc000, 0xc7ff).ram();
- map(0xd000, 0xd7ff).ram().share("videoram");
- map(0xd800, 0xd8ff).ram().share("spriteram");
+ map(0xd000, 0xd7ff).ram().share(m_videoram);
+ map(0xd800, 0xd8ff).ram().share(m_spriteram);
map(0xe000, 0xe000).r(FUNC(fcombat_state::port01_r));
map(0xe100, 0xe100).portr("DSW0");
map(0xe200, 0xe200).portr("DSW1");
map(0xe300, 0xe300).r(FUNC(fcombat_state::e300_r));
map(0xe400, 0xe400).r(FUNC(fcombat_state::protection_r)); // protection?
- map(0xe800, 0xe800).w(FUNC(fcombat_state::videoreg_w)); // at least bit 0 for flip screen and joystick input multiplexor
+ map(0xe800, 0xe800).w(FUNC(fcombat_state::videoreg_w)); // at least bit 0 for flip screen and joystick input multiplexer
map(0xe900, 0xe900).w(FUNC(fcombat_state::e900_w));
map(0xea00, 0xea00).w(FUNC(fcombat_state::ea00_w));
map(0xeb00, 0xeb00).w(FUNC(fcombat_state::eb00_w));
@@ -155,7 +455,7 @@ void fcombat_state::audio_map(address_map &map)
*************************************/
static INPUT_PORTS_START( fcombat )
- PORT_START("IN0") /* player 1 inputs (muxed on 0xe000) */
+ PORT_START("IN0") // player 1 inputs (muxed on 0xe000)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
@@ -165,7 +465,7 @@ static INPUT_PORTS_START( fcombat )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
- PORT_START("IN1") /* player 2 inputs (muxed on 0xe000) */
+ PORT_START("IN1") // player 2 inputs (muxed on 0xe000)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
@@ -175,7 +475,7 @@ static INPUT_PORTS_START( fcombat )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
- PORT_START("DSW0") /* dip switches (0xe100) */
+ PORT_START("DSW0") // dip switches (0xe100)
PORT_DIPNAME( 0x07, 0x02, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0x01, "2" )
@@ -198,7 +498,7 @@ static INPUT_PORTS_START( fcombat )
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x80, DEF_STR( Cocktail ) )
- PORT_START("DSW1") /* dip switches/VBLANK (0xe200) */
+ PORT_START("DSW1") // dip switches/VBLANK (0xe200)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) // related to vblank
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
@@ -211,7 +511,7 @@ static INPUT_PORTS_START( fcombat )
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("COIN")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, fcombat_state,coin_inserted, 0)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, fcombat_state, coin_inserted, 0)
INPUT_PORTS_END
@@ -247,9 +547,9 @@ static const gfx_layout spritelayout =
static GFXDECODE_START( gfx_fcombat )
- GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 )
- GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 256, 64 )
- GFXDECODE_ENTRY( "gfx3", 0, spritelayout, 512, 64 )
+ GFXDECODE_ENTRY( "fgtiles", 0, charlayout, 0, 64 )
+ GFXDECODE_ENTRY( "sprites", 0, spritelayout, 256, 64 )
+ GFXDECODE_ENTRY( "bgtiles", 0, spritelayout, 512, 64 )
GFXDECODE_END
@@ -286,32 +586,32 @@ void fcombat_state::machine_reset()
void fcombat_state::fcombat(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, 10000000/3);
+ // basic machine hardware
+ Z80(config, m_maincpu, CPU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &fcombat_state::main_map);
- z80_device &audiocpu(Z80(config, "audiocpu", 10000000/3));
+ z80_device &audiocpu(Z80(config, "audiocpu", CPU_CLOCK));
audiocpu.set_addrmap(AS_PROGRAM, &fcombat_state::audio_map);
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_raw(FCOMBAT_PIXEL_CLOCK, FCOMBAT_HTOTAL, FCOMBAT_HBEND, FCOMBAT_HBSTART, FCOMBAT_VTOTAL, FCOMBAT_VBEND, FCOMBAT_VBSTART);
+ screen.set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);
screen.set_screen_update(FUNC(fcombat_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_fcombat);
- PALETTE(config, m_palette, FUNC(fcombat_state::fcombat_palette), 256*3, 32);
+ PALETTE(config, m_palette, FUNC(fcombat_state::fcombat_palette), 256 * 3, 32);
- /* audio hardware */
+ // audio hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch");
- YM2149(config, "ay1", 1500000).add_route(ALL_OUTPUTS, "mono", 0.12);
+ YM2149(config, "ay1", 1'500'000).add_route(ALL_OUTPUTS, "mono", 0.12); // TODO: should this and the following be CPU_CLOCK / 2?
- YM2149(config, "ay2", 1500000).add_route(ALL_OUTPUTS, "mono", 0.12);
+ YM2149(config, "ay2", 1'500'000).add_route(ALL_OUTPUTS, "mono", 0.12);
- YM2149(config, "ay3", 1500000).add_route(ALL_OUTPUTS, "mono", 0.12);
+ YM2149(config, "ay3", 1'500'000).add_route(ALL_OUTPUTS, "mono", 0.12);
}
/*************************************
@@ -322,65 +622,65 @@ void fcombat_state::fcombat(machine_config &config)
void fcombat_state::init_fcombat()
{
- /* allocate some temporary space */
+ // allocate some temporary space
std::vector<u8> temp(0x10000);
- /* make a temporary copy of the character data */
+ // make a temporary copy of the character data
u8 *src = &temp[0];
- u8 *dst = memregion("gfx1")->base();
- u32 length = memregion("gfx1")->bytes();
+ u8 *dst = memregion("fgtiles")->base();
+ u32 length = memregion("fgtiles")->bytes();
memcpy(src, dst, length);
- /* decode the characters */
- /* the bits in the ROM are ordered: n8-n7 n6 n5 n4-v2 v1 v0 n3-n2 n1 n0 h2 */
- /* we want them ordered like this: n8-n7 n6 n5 n4-n3 n2 n1 n0-v2 v1 v0 h2 */
+ /* decode the characters
+ the bits in the ROM are ordered: n8-n7 n6 n5 n4-v2 v1 v0 n3-n2 n1 n0 h2
+ we want them ordered like this: n8-n7 n6 n5 n4-n3 n2 n1 n0-v2 v1 v0 h2 */
for (u32 oldaddr = 0; oldaddr < length; oldaddr++)
{
- u32 newaddr = ((oldaddr ) & 0x1f00) | /* keep n8-n4 */
- ((oldaddr << 3) & 0x00f0) | /* move n3-n0 */
- ((oldaddr >> 4) & 0x000e) | /* move v2-v0 */
- ((oldaddr ) & 0x0001); /* keep h2 */
+ u32 newaddr = ((oldaddr ) & 0x1f00) | // keep n8-n4
+ ((oldaddr << 3) & 0x00f0) | // move n3-n0
+ ((oldaddr >> 4) & 0x000e) | // move v2-v0
+ ((oldaddr ) & 0x0001); // keep h2
dst[newaddr] = src[oldaddr];
}
- /* make a temporary copy of the sprite data */
+ // make a temporary copy of the sprite data
src = &temp[0];
- dst = memregion("gfx2")->base();
- length = memregion("gfx2")->bytes();
+ dst = memregion("sprites")->base();
+ length = memregion("sprites")->bytes();
memcpy(src, dst, length);
- /* decode the sprites */
- /* the bits in the ROMs are ordered: n9 n8 n3 n7-n6 n5 n4 v3-v2 v1 v0 n2-n1 n0 h3 h2 */
- /* we want them ordered like this: n9 n8 n7 n6-n5 n4 n3 n2-n1 n0 v3 v2-v1 v0 h3 h2 */
+ /* decode the sprites
+ the bits in the ROMs are ordered: n9 n8 n3 n7-n6 n5 n4 v3-v2 v1 v0 n2-n1 n0 h3 h2
+ we want them ordered like this: n9 n8 n7 n6-n5 n4 n3 n2-n1 n0 v3 v2-v1 v0 h3 h2 */
for (u32 oldaddr = 0; oldaddr < length; oldaddr++)
{
- u32 newaddr = ((oldaddr << 1) & 0x3c00) | /* move n7-n4 */
- ((oldaddr >> 4) & 0x0200) | /* move n3 */
- ((oldaddr << 4) & 0x01c0) | /* move n2-n0 */
- ((oldaddr >> 3) & 0x003c) | /* move v3-v0 */
- ((oldaddr ) & 0xc003); /* keep n9-n8 h3-h2 */
+ u32 newaddr = ((oldaddr << 1) & 0x3c00) | // move n7-n4
+ ((oldaddr >> 4) & 0x0200) | // move n3
+ ((oldaddr << 4) & 0x01c0) | // move n2-n0
+ ((oldaddr >> 3) & 0x003c) | // move v3-v0
+ ((oldaddr ) & 0xc003); // keep n9-n8 h3-h2
dst[newaddr] = src[oldaddr];
}
- /* make a temporary copy of the character data */
+ // make a temporary copy of the character data
src = &temp[0];
- dst = memregion("gfx3")->base();
- length = memregion("gfx3")->bytes();
+ dst = memregion("bgtiles")->base();
+ length = memregion("bgtiles")->bytes();
memcpy(src, dst, length);
- /* decode the characters */
- /* the bits in the ROM are ordered: n8-n7 n6 n5 n4-v2 v1 v0 n3-n2 n1 n0 h2 */
- /* we want them ordered like this: n8-n7 n6 n5 n4-n3 n2 n1 n0-v2 v1 v0 h2 */
+ /* decode the characters
+ the bits in the ROM are ordered: n8-n7 n6 n5 n4-v2 v1 v0 n3-n2 n1 n0 h2
+ we want them ordered like this: n8-n7 n6 n5 n4-n3 n2 n1 n0-v2 v1 v0 h2 */
for (u32 oldaddr = 0; oldaddr < length; oldaddr++)
{
- u32 newaddr = ((oldaddr << 1) & 0x3c00) | /* move n7-n4 */
- ((oldaddr >> 4) & 0x0200) | /* move n3 */
- ((oldaddr << 4) & 0x01c0) | /* move n2-n0 */
- ((oldaddr >> 3) & 0x003c) | /* move v3-v0 */
- ((oldaddr ) & 0xc003); /* keep n9-n8 h3-h2 */
+ u32 newaddr = ((oldaddr << 1) & 0x3c00) | // move n7-n4
+ ((oldaddr >> 4) & 0x0200) | // move n3
+ ((oldaddr << 4) & 0x01c0) | // move n2-n0
+ ((oldaddr >> 3) & 0x003c) | // move v3-v0
+ ((oldaddr ) & 0xc003); // keep n9-n8 h3-h2
dst[newaddr] = src[oldaddr];
}
@@ -397,8 +697,8 @@ void fcombat_state::init_fcombat()
src = &temp[0];
- dst = memregion("user2")->base();
- length = memregion("user2")->bytes();
+ dst = memregion("terrain_info")->base();
+ length = memregion("terrain_info")->bytes();
memcpy(src, dst, length);
for (u32 oldaddr = 0; oldaddr < 32; oldaddr++)
@@ -413,31 +713,34 @@ ROM_START( fcombat )
ROM_LOAD( "fcombat2.t9", 0x0000, 0x4000, CRC(30cb0c14) SHA1(8b5b6a4efaca2f138709184725e9e0e0b9cfc4c7) )
ROM_LOAD( "fcombat3.10t", 0x4000, 0x4000, CRC(e8511da0) SHA1(bab5c9244c970b97c025381c37ad372aa3b5cddf) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "fcombat1.t5", 0x0000, 0x4000, CRC(a0cc1216) SHA1(3a8963ffde2ff4a3f428369133f94bb37717cae5) )
- ROM_REGION( 0x02000, "gfx1", 0 )
- ROM_LOAD( "fcombat7.l11", 0x00000, 0x2000, CRC(401061b5) SHA1(09dd23e86a56db8021e14432aced0eaf013fefe2) ) /* fg chars */
+ ROM_REGION( 0x02000, "fgtiles", 0 )
+ ROM_LOAD( "fcombat7.l11", 0x00000, 0x2000, CRC(401061b5) SHA1(09dd23e86a56db8021e14432aced0eaf013fefe2) )
- ROM_REGION( 0x0c000, "gfx2", 0 )
- ROM_LOAD( "fcombat8.d10", 0x00000, 0x4000, CRC(e810941e) SHA1(19ae85af0bf245caf3afe10d65e618cfb47d33c2) ) /* sprites */
+ ROM_REGION( 0x0c000, "sprites", 0 )
+ ROM_LOAD( "fcombat8.d10", 0x00000, 0x4000, CRC(e810941e) SHA1(19ae85af0bf245caf3afe10d65e618cfb47d33c2) )
ROM_LOAD( "fcombat9.d11", 0x04000, 0x4000, CRC(f95988e6) SHA1(25876652decca7ec1e9b37a16536c15ca2d1cb12) )
ROM_LOAD( "fcomba10.d12", 0x08000, 0x4000, CRC(908f154c) SHA1(b3761ee60d4a5ea36376759875105d23c57b4bf2) )
- ROM_REGION( 0x04000, "gfx3", 0 )
+ ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "fcombat6.f3", 0x00000, 0x4000, CRC(97282729) SHA1(72db0593551c2d15631341bf621b96013b46ce72) )
ROM_REGION( 0x04000, "bgdata", 0 )
- ROM_LOAD( "fcombat5.l3", 0x00000, 0x4000, CRC(96194ca7) SHA1(087d6ac8f93f087cb5e378dbe9a8cfcffa2cdddc) ) /* bg data */
+ ROM_LOAD( "fcombat5.l3", 0x00000, 0x4000, CRC(96194ca7) SHA1(087d6ac8f93f087cb5e378dbe9a8cfcffa2cdddc) )
- ROM_REGION( 0x04000, "user2", 0 )
- ROM_LOAD( "fcombat4.p3", 0x00000, 0x4000, CRC(efe098ab) SHA1(fe64a5e9170835d242368109b1b221b0f8090e7e) ) /* terrain info */
+ ROM_REGION( 0x04000, "terrain_info", 0 )
+ ROM_LOAD( "fcombat4.p3", 0x00000, 0x4000, CRC(efe098ab) SHA1(fe64a5e9170835d242368109b1b221b0f8090e7e) )
ROM_REGION( 0x0420, "proms", 0 )
- ROM_LOAD( "fcprom_a.c2", 0x0000, 0x0020, CRC(7ac480f0) SHA1(f491fe4da19d8c037e3733a5836de35cc438907e) ) /* palette */
- ROM_LOAD( "fcprom_d.k12", 0x0020, 0x0100, CRC(9a348250) SHA1(faf8db4c42adee07795d06bea20704f8c51090ff) ) /* fg char lookup table */
- ROM_LOAD( "fcprom_b.c4", 0x0120, 0x0100, CRC(ac9049f6) SHA1(57aa5b5df3e181bad76149745a422c3dd1edad49) ) /* sprite lookup table */
- ROM_LOAD( "fcprom_c.a9", 0x0220, 0x0100, CRC(768ac120) SHA1(ceede1d6cbeae08da96ef52bdca2718a839d88ab) ) /* bg char mixer */
+ ROM_LOAD( "fcprom_a.c2", 0x0000, 0x0020, CRC(7ac480f0) SHA1(f491fe4da19d8c037e3733a5836de35cc438907e) ) // palette
+ ROM_LOAD( "fcprom_d.k12", 0x0020, 0x0100, CRC(9a348250) SHA1(faf8db4c42adee07795d06bea20704f8c51090ff) ) // fg char lookup table
+ ROM_LOAD( "fcprom_b.c4", 0x0120, 0x0100, CRC(ac9049f6) SHA1(57aa5b5df3e181bad76149745a422c3dd1edad49) ) // sprite lookup table
+ ROM_LOAD( "fcprom_c.a9", 0x0220, 0x0100, CRC(768ac120) SHA1(ceede1d6cbeae08da96ef52bdca2718a839d88ab) ) // bg char mixer
ROM_END
+} // anonymous namespace
+
+
GAME( 1985, fcombat, 0, fcombat, fcombat, fcombat_state, init_fcombat, ROT90, "Jaleco", "Field Combat", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/jaleco/fcombat.h b/src/mame/jaleco/fcombat.h
deleted file mode 100644
index 7189e3159dc..00000000000
--- a/src/mame/jaleco/fcombat.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-#ifndef MAME_INCLUDES_FCOMBAT_H
-#define MAME_INCLUDES_FCOMBAT_H
-
-#pragma once
-
-#include "emupal.h"
-#include "tilemap.h"
-
-
-// this is copied from Exerion, but it should be correct
-#define FCOMBAT_MASTER_CLOCK (20000000)
-#define FCOMBAT_CPU_CLOCK (FCOMBAT_MASTER_CLOCK / 6)
-#define FCOMBAT_AY8910_CLOCK (FCOMBAT_CPU_CLOCK / 2)
-#define FCOMBAT_PIXEL_CLOCK (FCOMBAT_MASTER_CLOCK / 3)
-#define FCOMBAT_HCOUNT_START (0x58)
-#define FCOMBAT_HTOTAL (512-FCOMBAT_HCOUNT_START)
-#define FCOMBAT_HBEND (12*8) // ??
-#define FCOMBAT_HBSTART (52*8) //
-#define FCOMBAT_VTOTAL (256)
-#define FCOMBAT_VBEND (16)
-#define FCOMBAT_VBSTART (240)
-
-#define BACKGROUND_X_START 32
-#define BACKGROUND_X_START_FLIP 72
-
-#define VISIBLE_X_MIN (12*8)
-#define VISIBLE_X_MAX (52*8)
-#define VISIBLE_Y_MIN (2*8)
-#define VISIBLE_Y_MAX (30*8)
-
-
-class fcombat_state : public driver_device
-{
-public:
- fcombat_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_videoram(*this, "videoram"),
- m_spriteram(*this, "spriteram"),
- m_bgdata_rom(*this, "bgdata"),
- m_user2_region(*this, "user2"),
- m_io_in(*this, "IN%u", 0U),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette")
- { }
-
- void fcombat(machine_config &config);
-
- void init_fcombat();
-
- DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
-
-private:
- /* memory pointers */
- required_shared_ptr<u8> m_videoram;
- required_shared_ptr<u8> m_spriteram;
- required_region_ptr<u8> m_bgdata_rom;
- required_region_ptr<u8> m_user2_region;
-
- required_ioport_array<2> m_io_in;
-
- /* video-related */
- tilemap_t *m_bgmap = nullptr;
- u8 m_cocktail_flip = 0U;
- u8 m_char_palette = 0U;
- u8 m_sprite_palette = 0U;
- u8 m_char_bank = 0U;
-
- /* misc */
- int m_fcombat_sh = 0;
- int m_fcombat_sv = 0;
- int m_tx = 0;
- int m_ty = 0;
-
- /* devices */
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
-
- u8 protection_r();
- u8 port01_r();
- void e900_w(u8 data);
- void ea00_w(u8 data);
- void eb00_w(u8 data);
- void ec00_w(u8 data);
- void ed00_w(u8 data);
- u8 e300_r();
- void ee00_w(u8 data);
- void videoreg_w(u8 data);
- TILE_GET_INFO_MEMBER(get_bg_tile_info);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
- void fcombat_palette(palette_device &palette) const;
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void audio_map(address_map &map);
- void main_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_FCOMBAT_H
diff --git a/src/mame/jaleco/fcombat_v.cpp b/src/mame/jaleco/fcombat_v.cpp
deleted file mode 100644
index 5491f184732..00000000000
--- a/src/mame/jaleco/fcombat_v.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-/***************************************************************************
-
- Jaleco fcombat
-
-***************************************************************************/
-
-#include "emu.h"
-#include "fcombat.h"
-
-
-TILE_GET_INFO_MEMBER(fcombat_state::get_bg_tile_info)
-{
- int tileno, palno; //32*16 x 32
-
- //palno = (tile_index - (tile_index / 32 * 16) * 32 * 16) / 32;
-
- tileno = m_bgdata_rom[tile_index];
- palno = 0x18; //m_user2_region[tile_index] >> 3;
- tileinfo.set(2, tileno, palno, 0);
-}
-
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- The palette PROM is connected to the RGB output this way:
-
- bit 7 -- 220 ohm resistor -- BLUE
- -- 470 ohm resistor -- BLUE
- -- 220 ohm resistor -- GREEN
- -- 470 ohm resistor -- GREEN
- -- 1 kohm resistor -- GREEN
- -- 220 ohm resistor -- RED
- -- 470 ohm resistor -- RED
- bit 0 -- 1 kohm resistor -- RED
-
-***************************************************************************/
-
-void fcombat_state::fcombat_palette(palette_device &palette) const
-{
- const u8 *color_prom = memregion("proms")->base();
-
- // create a lookup table for the palette
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1, bit2;
-
- // red component
- bit0 = BIT(color_prom[i], 0);
- bit1 = BIT(color_prom[i], 1);
- bit2 = BIT(color_prom[i], 2);
- const u8 r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- // green component
- bit0 = BIT(color_prom[i], 3);
- bit1 = BIT(color_prom[i], 4);
- bit2 = BIT(color_prom[i], 5);
- const u8 g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- // blue component
- bit0 = 0;
- bit1 = BIT(color_prom[i], 6);
- bit2 = BIT(color_prom[i], 7);
- const u8 b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- // color_prom now points to the beginning of the lookup table
- color_prom += 0x20;
-
- // fg chars/sprites
- for (int i = 0; i < 0x200; i++)
- {
- const u8 ctabentry = (color_prom[(i & 0x1c0) | ((i & 3) << 4) | ((i >> 2) & 0x0f)] & 0x0f) | 0x10;
- palette.set_pen_indirect(i, ctabentry);
- }
-
- // bg chars (this is not the full story... there are four layers mixed using another PROM
- for (int i = 0x200; i < 0x300; i++)
- {
- const u8 ctabentry = color_prom[i] & 0x0f;
- palette.set_pen_indirect(i, ctabentry);
- }
-}
-
-
-/*************************************
- *
- * Video system startup
- *
- *************************************/
-
-void fcombat_state::video_start()
-{
- m_bgmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(fcombat_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32 * 8 * 2, 32);
-}
-
-
-/*************************************
- *
- * Video register I/O
- *
- *************************************/
-
-void fcombat_state::videoreg_w(u8 data)
-{
- /* bit 0 = flip screen and joystick input multiplexor */
- m_cocktail_flip = data & 1;
-
- /* bits 1-2 char lookup table bank */
- m_char_palette = (data & 0x06) >> 1;
-
- /* bits 3 char bank */
- m_char_bank = (data & 0x08) >> 3;
-
- /* bits 4-5 unused */
-
- /* bits 6-7 sprite lookup table bank */
- m_sprite_palette = 0;//(data & 0xc0) >> 6;
- //popmessage("%08x",data);
-}
-
-
-u32 fcombat_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- /* draw background */
- m_bgmap->set_scrolly(0, m_fcombat_sh);
- m_bgmap->set_scrollx(0, m_fcombat_sv - 24);
-
- m_bgmap->mark_all_dirty();
- m_bgmap->draw(screen, bitmap, cliprect, 0, 0);
- //draw_background(bitmap, cliprect);
-
- /* draw sprites */
- for (int i = 0; i < m_spriteram.bytes(); i += 4)
- {
- int flags = m_spriteram[i + 0];
- int y = m_spriteram[i + 1] ^ 255;
- int code = m_spriteram[i + 2] + ((flags & 0x20) << 3);
- int x = m_spriteram[i + 3] * 2 + 72;
-
- int xflip = flags & 0x80;
- int yflip = flags & 0x40;
- bool doubled = false;// flags & 0x10;
- const bool wide = flags & 0x08;
- int code2 = code;
-
- int color = ((flags >> 1) & 0x03) | ((code >> 5) & 0x04) | (code & 0x08) | (m_sprite_palette * 16);
- gfx_element *gfx = m_gfxdecode->gfx(1);
-
- if (m_cocktail_flip)
- {
- x = 64 * 8 - gfx->width() - x;
- y = 32 * 8 - gfx->height() - y;
- if (wide) y -= gfx->height();
- xflip = !xflip;
- yflip = !yflip;
- }
-
- if (wide)
- {
- if (yflip)
- code |= 0x10, code2 &= ~0x10;
- else
- code &= ~0x10, code2 |= 0x10;
-
- gfx->transpen(bitmap,cliprect, code2, color, xflip, yflip, x, y + gfx->height(), 0);
- }
-
- if (flags & 0x10)
- {
- gfx->transpen(bitmap,cliprect, code2 + 16, color, xflip, yflip, x, y + gfx->height(), 0);
- gfx->transpen(bitmap,cliprect, code2 + 16 * 2, color, xflip, yflip, x, y + 2 * gfx->height(), 0);
- gfx->transpen(bitmap,cliprect, code2 + 16 * 3, color, xflip, yflip, x, y + 3 * gfx->height(), 0);
-
- }
-
- gfx->transpen(bitmap,cliprect, code, color, xflip, yflip, x, y, 0);
-
- if (doubled) i += 4;
- }
-
- /* draw the visible text layer */
- for (int sy = VISIBLE_Y_MIN/8; sy < VISIBLE_Y_MAX/8; sy++)
- for (int sx = VISIBLE_X_MIN/8; sx < VISIBLE_X_MAX/8; sx++)
- {
- int x = m_cocktail_flip ? (63 * 8 - 8 * sx) : 8 * sx;
- int y = m_cocktail_flip ? (31 * 8 - 8 * sy) : 8 * sy;
-
- const int offs = sx + sy * 64;
- m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
- m_videoram[offs] + 256 * m_char_bank,
- ((m_videoram[offs] & 0xf0) >> 4) + m_char_palette * 16,
- m_cocktail_flip, m_cocktail_flip, x, y, 0);
- }
- return 0;
-}
diff --git a/src/mame/jaleco/ginganin.cpp b/src/mame/jaleco/ginganin.cpp
index f8521aaffac..fefacb2847d 100644
--- a/src/mame/jaleco/ginganin.cpp
+++ b/src/mame/jaleco/ginganin.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Luca Elia
+// copyright-holders: Luca Elia
+
/***************************************************************************
Ginga NinkyouDen
@@ -13,7 +14,7 @@ OSC. : 6.000MHz 3.579545MHz
* CTC uses MB-8873E (MC-6840)
- Interesting routines (main cpu)
+ Interesting routines (main CPU)
-------------------------------
Interrupts: 1-7] d17a: clears 20018 etc.
@@ -22,7 +23,7 @@ f4b2 print string: a1->(char)*,0x25(%) d7.w=color a0->screen (30000)
f5d6 print 7 digit BCD number: d0.l to (a1)+ color $3000
- Interesting locations (main cpu)
+ Interesting locations (main CPU)
--------------------------------
20014 # of players (1-2)
@@ -57,28 +58,371 @@ f5d6 print 7 digit BCD number: d0.l to (a1)+ color $3000
***************************************************************************/
#include "emu.h"
-#include "ginganin.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6809/m6809.h"
#include "machine/6840ptm.h"
+#include "machine/gen_latch.h"
#include "sound/ay8910.h"
#include "sound/ymopl.h"
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_VREGS (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_VREGS)
+
+#include "logmacro.h"
+
+#define LOGVREGS(...) LOGMASKED(LOG_VREGS, __VA_ARGS__)
+
+
+namespace {
+
+class ginganin_state : public driver_device
+{
+public:
+ ginganin_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_txtram(*this, "txtram"),
+ m_spriteram(*this, "spriteram"),
+ m_vregs(*this, "vregs"),
+ m_fgram(*this, "fgram"),
+ m_bgrom(*this, "bgrom"),
+ m_maincpu(*this, "maincpu"),
+ m_audiocpu(*this, "audiocpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_soundlatch(*this, "soundlatch")
+ { }
+
+ void ginganin(machine_config &config);
+
+ void init_ginganin();
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ // memory pointers
+ required_shared_ptr<u16> m_txtram;
+ required_shared_ptr<u16> m_spriteram;
+ required_shared_ptr<u16> m_vregs;
+ required_shared_ptr<u16> m_fgram;
+
+ required_region_ptr<u8> m_bgrom;
+
+ // video-related
+ tilemap_t *m_bg_tilemap = nullptr;
+ tilemap_t *m_fg_tilemap = nullptr;
+ tilemap_t *m_tx_tilemap = nullptr;
+ u16 m_layers_ctrl = 0;
+ u8 m_flipscreen = 0;
+#ifdef MAME_DEBUG
+ int m_posx = 0;
+ int m_posy = 0;
+#endif
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_audiocpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_device<generic_latch_8_device> m_soundlatch;
+
+ void fgram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
+ void txtram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
+ void vregs_w(offs_t offset, u16 data, u16 mem_mask = ~0);
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+ TILE_GET_INFO_MEMBER(get_fg_tile_info);
+ TILE_GET_INFO_MEMBER(get_txt_tile_info);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
+/**************************************************************************
+
+Note: if MAME_DEBUG is defined, pressing Z with:
+
+ Q shows background
+ W shows foreground
+ E shows frontmost (text) layer
+ A shows sprites
+
+ Keys can be used together!
+
+
+[Screen]
+ Visible Size: 256H x 240V
+ Dynamic Colors: 256 x 4
+ Color Space: 16R x 16G x 16B
+
+[Scrolling layers]
+ Format (all layers): Offset: 0x400 0x000
+ Bit: fedc---- -------- Color
+ ----ba98 76543210 Code
+
+ [Background]
+ Size: 8192 x 512 (static: stored in ROM)
+ Scrolling: X,Y (registers: $60006.w, $60004.w)
+ Tiles Size: 16 x 16
+ Tiles Number: $400
+ Colors: $300-$3ff
+
+ [Foreground]
+ Size: 4096 x 512
+ Scrolling: X,Y (registers: $60002.w, $60000.w)
+ Tiles Size: 16 x 16
+ Tiles Number: $400
+ Colors: $200-$2ff
+
+ [Frontmost]
+ Size: 256 x 256
+ Scrolling: -
+ Tiles Size: 8 x 8
+ Tiles Number: $200
+ Colors: $000-$0ff
+
+
+[Sprites]
+ On Screen: 256
+ In ROM: $a00
+ Colors: $100-$1ff
+ Format: See Below
+
+
+**************************************************************************/
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+
+// Background - Resides in ROM
+
+static constexpr u8 BG_GFX = 0;
+static constexpr u16 BG_NX = (16 * 32);
+static constexpr u8 BG_NY = (16 * 2);
+
+TILE_GET_INFO_MEMBER(ginganin_state::get_bg_tile_info)
+{
+ const u32 code = m_bgrom[2 * tile_index + 0] * 256 + m_bgrom[2 * tile_index + 1];
+ tileinfo.set(BG_GFX,
+ code,
+ code >> 12,
+ 0);
+}
+
+
+// Foreground - Resides in RAM
+
+static constexpr u8 FG_GFX = 1;
+static constexpr u16 FG_NX = (16 * 16);
+static constexpr u8 FG_NY = (16 * 2);
+
+TILE_GET_INFO_MEMBER(ginganin_state::get_fg_tile_info)
+{
+ const u16 code = m_fgram[tile_index];
+ tileinfo.set(FG_GFX,
+ code,
+ code >> 12,
+ 0);
+}
+
+void ginganin_state::fgram_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_fgram[offset]);
+ m_fg_tilemap->mark_tile_dirty(offset);
+}
+
+
+// Frontmost (text) Layer - Resides in RAM
+
+static constexpr u8 TXT_GFX = 2;
+static constexpr u8 TXT_NX = 32;
+static constexpr u8 TXT_NY = 32;
+
+TILE_GET_INFO_MEMBER(ginganin_state::get_txt_tile_info)
+{
+ const u16 code = m_txtram[tile_index];
+ tileinfo.set(TXT_GFX,
+ code,
+ code >> 12,
+ 0);
+}
+
+void ginganin_state::txtram_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_txtram[offset]);
+ m_tx_tilemap->mark_tile_dirty(offset);
+}
-#define MAIN_CLOCK XTAL(6'000'000)
-#define SOUND_CLOCK XTAL(3'579'545)
+void ginganin_state::video_start()
+{
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, BG_NX, BG_NY);
+ m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, FG_NX, FG_NY);
+ m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_txt_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, TXT_NX, TXT_NY);
+
+ m_fg_tilemap->set_transparent_pen(15);
+ m_tx_tilemap->set_transparent_pen(15);
+}
+
+
+void ginganin_state::vregs_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_vregs[offset]);
+ data = m_vregs[offset];
+
+ switch (offset)
+ {
+ case 0:
+ m_fg_tilemap->set_scrolly(0, data);
+ break;
+ case 1:
+ m_fg_tilemap->set_scrollx(0, data);
+ break;
+ case 2:
+ m_bg_tilemap->set_scrolly(0, data);
+ break;
+ case 3:
+ m_bg_tilemap->set_scrollx(0, data);
+ break;
+ case 4:
+ m_layers_ctrl = data;
+ break;
+/* case 5:
+ * break;
+ */
+ case 6:
+ m_flipscreen = !(data & 1);
+ machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
+ break;
+ case 7:
+ m_soundlatch->write(data);
+ m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
+ break;
+ default:
+ LOGVREGS("CPU #0 PC %06X : Warning, videoreg %04X <- %04X\n", m_maincpu->pc(), offset, data);
+ }
+}
+
+
+
+/* --------------------------[ Sprites Format ]----------------------------
+Offset: Values: Format:
-/*
-**
-** Main cpu data
-**
-*/
+0000.w y position fedc ba9- ---- ---- unused
+ ---- ---8 ---- ---- subtract 256
+ ---- ---- 7654 3210 position
+0002.w x position See above
+
+0004.w code f--- ---- ---- ---- y flip
+ -e-- ---- ---- ---- x flip
+ --dc ---- ---- ---- unused?
+ ---- ba98 7654 3210 code
+
+0006.w colour fedc ---- ---- ---- colour code
+ ---- ba98 7654 3210 unused?
+
+------------------------------------------------------------------------ */
+
+void ginganin_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = 0; offs < (m_spriteram.bytes() >> 1); offs += 4)
+ {
+ int y = m_spriteram[offs + 0];
+ int x = m_spriteram[offs + 1];
+ const u32 code = m_spriteram[offs + 2];
+ const u16 attr = m_spriteram[offs + 3];
+ int flipx = code & 0x4000;
+ int flipy = code & 0x8000;
+
+ x = (x & 0xff) - (x & 0x100);
+ y = (y & 0xff) - (y & 0x100);
+
+ if (m_flipscreen)
+ {
+ x = 240 - x;
+ y = 240 - y;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ m_gfxdecode->gfx(3)->transpen(bitmap, cliprect,
+ code & 0x3fff,
+ attr >> 12,
+ flipx, flipy,
+ x, y, 15);
+
+ }
+}
+
+
+u32 ginganin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int layers_ctrl1 = m_layers_ctrl;
+
+#ifdef MAME_DEBUG
+if (machine().input().code_pressed(KEYCODE_Z))
+{
+ int msk = 0;
+
+ if (machine().input().code_pressed(KEYCODE_Q)) { msk |= 0xfff1;}
+ if (machine().input().code_pressed(KEYCODE_W)) { msk |= 0xfff2;}
+ if (machine().input().code_pressed(KEYCODE_E)) { msk |= 0xfff4;}
+ if (machine().input().code_pressed(KEYCODE_A)) { msk |= 0xfff8;}
+ if (msk != 0) layers_ctrl1 &= msk;
+
+#define SETSCROLL \
+ m_bg_tilemap->set_scrollx(0, m_posx); \
+ m_bg_tilemap->set_scrolly(0, m_posy); \
+ m_fg_tilemap->set_scrollx(0, m_posx); \
+ m_fg_tilemap->set_scrolly(0, m_posy); \
+ popmessage("B>%04X:%04X F>%04X:%04X",m_posx%(BG_NX*16),m_posy%(BG_NY*16),m_posx%(FG_NX*16),m_posy%(FG_NY*16));
+
+ if (machine().input().code_pressed(KEYCODE_L)) { m_posx +=8; SETSCROLL }
+ if (machine().input().code_pressed(KEYCODE_J)) { m_posx -=8; SETSCROLL }
+ if (machine().input().code_pressed(KEYCODE_K)) { m_posy +=8; SETSCROLL }
+ if (machine().input().code_pressed(KEYCODE_I)) { m_posy -=8; SETSCROLL }
+ if (machine().input().code_pressed(KEYCODE_H)) { m_posx = m_posy = 0; SETSCROLL }
+
+}
+#endif
+
+ if (layers_ctrl1 & 1)
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ else
+ bitmap.fill(0, cliprect);
+
+ if (layers_ctrl1 & 2)
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ if (layers_ctrl1 & 8)
+ draw_sprites(bitmap, cliprect);
+ if (layers_ctrl1 & 4)
+ m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+
+ return 0;
+}
+
+
+// machine
void ginganin_state::main_map(address_map &map)
{
@@ -86,22 +430,16 @@ void ginganin_state::main_map(address_map &map)
// looks a debugging left-over for GFX patching (causes state garbage if hooked as RAM write mirror)
map(0x000000, 0x01ffff).rom().nopw();
map(0x020000, 0x023fff).ram();
- map(0x030000, 0x0307ff).ram().w(FUNC(ginganin_state::txtram_w)).share("txtram");
- map(0x040000, 0x0407ff).ram().share("spriteram");
+ map(0x030000, 0x0307ff).ram().w(FUNC(ginganin_state::txtram_w)).share(m_txtram);
+ map(0x040000, 0x0407ff).ram().share(m_spriteram);
map(0x050000, 0x0507ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
- map(0x060000, 0x06000f).ram().w(FUNC(ginganin_state::vregs_w)).share("vregs");
- map(0x068000, 0x06bfff).ram().w(FUNC(ginganin_state::fgram_w)).share("fgram");
+ map(0x060000, 0x06000f).ram().w(FUNC(ginganin_state::vregs_w)).share(m_vregs);
+ map(0x068000, 0x06bfff).ram().w(FUNC(ginganin_state::fgram_w)).share(m_fgram);
map(0x070000, 0x070001).portr("P1_P2");
map(0x070002, 0x070003).portr("DSW");
}
-/*
-**
-** Sound cpu data
-**
-*/
-
void ginganin_state::sound_map(address_map &map)
{
map(0x0000, 0x07ff).ram();
@@ -113,10 +451,8 @@ void ginganin_state::sound_map(address_map &map)
}
-/* Input Ports */
-
static INPUT_PORTS_START( ginganin )
- PORT_START("P1_P2") /* 70000.w */
+ PORT_START("P1_P2") // 70000.w
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
@@ -134,7 +470,7 @@ static INPUT_PORTS_START( ginganin )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
- PORT_START("DSW") /* 70002.w */
+ PORT_START("DSW") // 70002.w
PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x0000, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x0004, DEF_STR( 4C_1C ) )
@@ -171,10 +507,10 @@ static INPUT_PORTS_START( ginganin )
PORT_DIPNAME( 0x0800, 0x0000, DEF_STR( Cabinet ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x0800, DEF_STR( Cocktail ) )
- PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) /* probably unused */
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) // probably unused
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) /* it does something */
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) // it does something
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Flip_Screen ) )
@@ -187,18 +523,11 @@ INPUT_PORTS_END
-/*
-**
-** Gfx data
-**
-*/
-
-
static GFXDECODE_START( gfx_ginganin )
- GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*3, 16 ) /* [0] bg */
- GFXDECODE_ENTRY( "gfx2", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*2, 16 ) /* [1] fg */
- GFXDECODE_ENTRY( "gfx3", 0, gfx_8x8x4_packed_msb, 256*0, 16 ) /* [2] txt */
- GFXDECODE_ENTRY( "gfx4", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*1, 16 ) /* [3] sprites */
+ GFXDECODE_ENTRY( "bgtiles", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*3, 16 )
+ GFXDECODE_ENTRY( "fgtiles", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*2, 16 )
+ GFXDECODE_ENTRY( "txttiles", 0, gfx_8x8x4_packed_msb, 256*0, 16 )
+ GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_col_2x2_group_packed_msb, 256*1, 16 )
GFXDECODE_END
@@ -214,27 +543,24 @@ void ginganin_state::machine_reset()
m_flipscreen = 0;
}
-WRITE_LINE_MEMBER(ginganin_state::ptm_irq)
-{
- m_audiocpu->set_input_line(0, state ? ASSERT_LINE : CLEAR_LINE);
-}
-
-
void ginganin_state::ginganin(machine_config &config)
{
- /* basic machine hardware */
+ static constexpr XTAL MAIN_CLOCK = XTAL(6'000'000);
+ static constexpr XTAL SOUND_CLOCK = XTAL(3'579'545);
+
+ // basic machine hardware
M68000(config, m_maincpu, MAIN_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &ginganin_state::main_map);
- m_maincpu->set_vblank_int("screen", FUNC(ginganin_state::irq1_line_hold)); /* ? (vectors 1-7 contain the same address) */
+ m_maincpu->set_vblank_int("screen", FUNC(ginganin_state::irq1_line_hold)); // ? (vectors 1-7 contain the same address)
MC6809(config, m_audiocpu, SOUND_CLOCK); // MBL68B09?
m_audiocpu->set_addrmap(AS_PROGRAM, &ginganin_state::sound_map);
- ptm6840_device &ptm(PTM6840(config, "6840ptm", SOUND_CLOCK/2));
+ ptm6840_device &ptm(PTM6840(config, "6840ptm", SOUND_CLOCK / 2));
ptm.set_external_clocks(0, 0, 0);
- ptm.o1_callback().set(FUNC(ginganin_state::ptm_irq));
+ ptm.o1_callback().set_inputline(m_audiocpu, 0);
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
@@ -246,14 +572,14 @@ void ginganin_state::ginganin(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ginganin);
PALETTE(config, m_palette).set_format(palette_device::RGBx_444, 1024);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, m_soundlatch);
YM2149(config, "psg", SOUND_CLOCK / 2).add_route(ALL_OUTPUTS, "mono", 0.10);
- Y8950(config, "ymsnd", SOUND_CLOCK).add_route(ALL_OUTPUTS, "mono", 1.0); /* The Y8950 is basically a YM3526 with ADPCM built in */
+ Y8950(config, "ymsnd", SOUND_CLOCK).add_route(ALL_OUTPUTS, "mono", 1.0); // The Y8950 is basically a YM3526 with ADPCM built in
}
@@ -265,70 +591,70 @@ void ginganin_state::ginganin(machine_config &config)
***************************************************************************/
ROM_START( ginganin )
- ROM_REGION( 0x20000, "maincpu", 0 ) /* main cpu */
+ ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD16_BYTE( "gn_02.bin", 0x00000, 0x10000, CRC(4a4e012f) SHA1(7c94a5b6b71e037af355f3aa4623be1f585db8dc) )
ROM_LOAD16_BYTE( "gn_01.bin", 0x00001, 0x10000, CRC(30256fcb) SHA1(dc15e0da88ae5cabe0150f7290508c3d58c06c11) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "gn_05.bin", 0x00000, 0x10000, CRC(e76e10e7) SHA1(b16f10a1a01b7b04221c9bf1b0d157e936bc5fb5) )
- ROM_REGION( 0x20000, "gfx1", 0 )
- ROM_LOAD( "gn_15.bin", 0x000000, 0x10000, CRC(1b8ac9fb) SHA1(1e5ee2a565fa262f1e48c1088d84c6f42d84b4e3) ) /* bg */
+ ROM_REGION( 0x20000, "bgtiles", 0 )
+ ROM_LOAD( "gn_15.bin", 0x000000, 0x10000, CRC(1b8ac9fb) SHA1(1e5ee2a565fa262f1e48c1088d84c6f42d84b4e3) )
ROM_LOAD( "gn_14.bin", 0x010000, 0x10000, CRC(e73fe668) SHA1(fa39fddd7448d3fc6b539506e33b951db205afa1) )
- ROM_REGION( 0x20000, "gfx2", 0 )
- ROM_LOAD( "gn_12.bin", 0x000000, 0x10000, CRC(c134a1e9) SHA1(8bace0f0169e61f1b7254393fa9cad6dca09c335) ) /* fg */
+ ROM_REGION( 0x20000, "fgtiles", 0 )
+ ROM_LOAD( "gn_12.bin", 0x000000, 0x10000, CRC(c134a1e9) SHA1(8bace0f0169e61f1b7254393fa9cad6dca09c335) )
ROM_LOAD( "gn_13.bin", 0x010000, 0x10000, CRC(1d3bec21) SHA1(305823c78cad9288f918178e1c24cb0459ba2a6e) )
- ROM_REGION( 0x04000, "gfx3", 0 )
- ROM_LOAD( "gn_10.bin", 0x000000, 0x04000, CRC(ae371b2d) SHA1(d5e03b085586ed2bf40713f432bcf12e07318226) ) /* txt */
+ ROM_REGION( 0x04000, "txttiles", 0 )
+ ROM_LOAD( "gn_10.bin", 0x000000, 0x04000, CRC(ae371b2d) SHA1(d5e03b085586ed2bf40713f432bcf12e07318226) )
- ROM_REGION( 0x50000, "gfx4", 0 )
- ROM_LOAD( "gn_06.bin", 0x000000, 0x10000, CRC(bdc65835) SHA1(53222fc3ec15e641289abb754657b0d59b88b66b) ) /* sprites */
+ ROM_REGION( 0x50000, "sprites", 0 )
+ ROM_LOAD( "gn_06.bin", 0x000000, 0x10000, CRC(bdc65835) SHA1(53222fc3ec15e641289abb754657b0d59b88b66b) )
ROM_CONTINUE( 0x040000, 0x10000 )
ROM_LOAD( "gn_07.bin", 0x010000, 0x10000, CRC(c2b8eafe) SHA1(a042a200efd4e7361e9ab516085c9fc8067e28b4) )
ROM_LOAD( "gn_08.bin", 0x020000, 0x10000, CRC(f7c73c18) SHA1(102700e2217bcd1532af56ee6a00ad608c8217db) )
ROM_LOAD( "gn_09.bin", 0x030000, 0x10000, CRC(a5e07c3b) SHA1(cdda02cd847330575612cb33d1bb38a5d50a3e6d) )
- ROM_REGION( 0x08000, "bgrom", 0 ) /* background tilemaps */
+ ROM_REGION( 0x08000, "bgrom", 0 )
ROM_LOAD( "gn_11.bin", 0x00000, 0x08000, CRC(f0d0e605) SHA1(0c541e8e036573be1d99ecb71fdb4568ca8cc269) )
- ROM_REGION( 0x20000, "ymsnd", 0 ) /* samples */
+ ROM_REGION( 0x20000, "ymsnd", 0 )
ROM_LOAD( "gn_04.bin", 0x00000, 0x10000, CRC(0ed9133b) SHA1(77f628e8ec28016efac2d906146865ca4ec54bd5) )
ROM_LOAD( "gn_03.bin", 0x10000, 0x10000, CRC(f1ba222c) SHA1(780c0bd0045bac1e1bb3209576383db90504fbf3) )
ROM_END
ROM_START( ginganina )
- ROM_REGION( 0x20000, "maincpu", 0 ) /* main cpu */
+ ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD16_BYTE( "2.bin", 0x00000, 0x10000, CRC(6da1d8a3) SHA1(ea81f2934fa7901563e886f3d600edd08ec0ea24) )
ROM_LOAD16_BYTE( "1.bin", 0x00001, 0x10000, CRC(0bd32d59) SHA1(5ab2c0e4a1d9cafbd3448d981103508debd7ed96) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "gn_05.bin", 0x00000, 0x10000, CRC(e76e10e7) SHA1(b16f10a1a01b7b04221c9bf1b0d157e936bc5fb5) )
- ROM_REGION( 0x20000, "gfx1", 0 )
- ROM_LOAD( "gn_15.bin", 0x000000, 0x10000, CRC(1b8ac9fb) SHA1(1e5ee2a565fa262f1e48c1088d84c6f42d84b4e3) ) /* bg */
+ ROM_REGION( 0x20000, "bgtiles", 0 )
+ ROM_LOAD( "gn_15.bin", 0x000000, 0x10000, CRC(1b8ac9fb) SHA1(1e5ee2a565fa262f1e48c1088d84c6f42d84b4e3) )
ROM_LOAD( "gn_14.bin", 0x010000, 0x10000, CRC(e73fe668) SHA1(fa39fddd7448d3fc6b539506e33b951db205afa1) )
- ROM_REGION( 0x20000, "gfx2", 0 )
- ROM_LOAD( "gn_12.bin", 0x000000, 0x10000, CRC(c134a1e9) SHA1(8bace0f0169e61f1b7254393fa9cad6dca09c335) ) /* fg */
+ ROM_REGION( 0x20000, "fgtiles", 0 )
+ ROM_LOAD( "gn_12.bin", 0x000000, 0x10000, CRC(c134a1e9) SHA1(8bace0f0169e61f1b7254393fa9cad6dca09c335) )
ROM_LOAD( "gn_13.bin", 0x010000, 0x10000, CRC(1d3bec21) SHA1(305823c78cad9288f918178e1c24cb0459ba2a6e) )
- ROM_REGION( 0x04000, "gfx3", 0 )
- ROM_LOAD( "10.bin", 0x000000, 0x04000, CRC(48a20745) SHA1(69855b0402feca4ba9632142e569c652ca05b9fa) ) /* txt */
+ ROM_REGION( 0x04000, "txttiles", 0 )
+ ROM_LOAD( "10.bin", 0x000000, 0x04000, CRC(48a20745) SHA1(69855b0402feca4ba9632142e569c652ca05b9fa) )
- ROM_REGION( 0x50000, "gfx4", 0 )
- ROM_LOAD( "gn_06.bin", 0x000000, 0x10000, CRC(bdc65835) SHA1(53222fc3ec15e641289abb754657b0d59b88b66b) ) /* sprites */
+ ROM_REGION( 0x50000, "sprites", 0 )
+ ROM_LOAD( "gn_06.bin", 0x000000, 0x10000, CRC(bdc65835) SHA1(53222fc3ec15e641289abb754657b0d59b88b66b) )
ROM_CONTINUE( 0x040000, 0x10000 )
ROM_LOAD( "gn_07.bin", 0x010000, 0x10000, CRC(c2b8eafe) SHA1(a042a200efd4e7361e9ab516085c9fc8067e28b4) )
ROM_LOAD( "gn_08.bin", 0x020000, 0x10000, CRC(f7c73c18) SHA1(102700e2217bcd1532af56ee6a00ad608c8217db) )
ROM_LOAD( "gn_09.bin", 0x030000, 0x10000, CRC(a5e07c3b) SHA1(cdda02cd847330575612cb33d1bb38a5d50a3e6d) )
- ROM_REGION( 0x08000, "bgrom", 0 ) /* background tilemaps */
+ ROM_REGION( 0x08000, "bgrom", 0 )
ROM_LOAD( "gn_11.bin", 0x00000, 0x08000, CRC(f0d0e605) SHA1(0c541e8e036573be1d99ecb71fdb4568ca8cc269) )
- ROM_REGION( 0x20000, "ymsnd", 0 ) /* samples */
+ ROM_REGION( 0x20000, "ymsnd", 0 )
ROM_LOAD( "gn_04.bin", 0x00000, 0x10000, CRC(0ed9133b) SHA1(77f628e8ec28016efac2d906146865ca4ec54bd5) )
ROM_LOAD( "gn_03.bin", 0x10000, 0x10000, CRC(f1ba222c) SHA1(780c0bd0045bac1e1bb3209576383db90504fbf3) )
ROM_END
@@ -337,13 +663,15 @@ ROM_END
void ginganin_state::init_ginganin()
{
// pending full removal of this patch ...
- /* main cpu patches */
+ /* main CPU patches */
// u16 *rom = (u16 *)memregion("maincpu")->base();
- /* avoid writes to rom getting to the log */
+ /* avoid writes to ROM getting to the log */
// rom[0x408 / 2] = 0x6000;
// rom[0x40a / 2] = 0x001c;
}
+} // anonymous namespace
+
GAME( 1987, ginganin, 0, ginganin, ginganin, ginganin_state, init_ginganin, ROT0, "Jaleco", "Ginga NinkyouDen (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, ginganina, ginganin, ginganin, ginganin, ginganin_state, init_ginganin, ROT0, "Jaleco", "Ginga NinkyouDen (set 2)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/jaleco/ginganin.h b/src/mame/jaleco/ginganin.h
deleted file mode 100644
index 7e29df2468d..00000000000
--- a/src/mame/jaleco/ginganin.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Luca Elia
-/*************************************************************************
-
- Ginga NinkyouDen
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_GINGANIN_H
-#define MAME_INCLUDES_GINGANIN_H
-
-#pragma once
-
-#include "machine/gen_latch.h"
-#include "emupal.h"
-#include "tilemap.h"
-
-class ginganin_state : public driver_device
-{
-public:
- ginganin_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_txtram(*this, "txtram"),
- m_spriteram(*this, "spriteram"),
- m_vregs(*this, "vregs"),
- m_fgram(*this, "fgram"),
- m_bgrom(*this, "bgrom"),
- m_maincpu(*this, "maincpu"),
- m_audiocpu(*this, "audiocpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_soundlatch(*this, "soundlatch")
- { }
-
- void ginganin(machine_config &config);
-
- void init_ginganin();
-
-private:
- /* memory pointers */
- required_shared_ptr<u16> m_txtram;
- required_shared_ptr<u16> m_spriteram;
- required_shared_ptr<u16> m_vregs;
- required_shared_ptr<u16> m_fgram;
-
- required_region_ptr<u8> m_bgrom;
-
- /* video-related */
- tilemap_t *m_bg_tilemap = nullptr;
- tilemap_t *m_fg_tilemap = nullptr;
- tilemap_t *m_tx_tilemap = nullptr;
- int m_layers_ctrl = 0;
- int m_flipscreen = 0;
-#ifdef MAME_DEBUG
- int m_posx = 0;
- int m_posy = 0;
-#endif
-
- /* devices */
- required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_audiocpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- required_device<generic_latch_8_device> m_soundlatch;
-
- void fgram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
- void txtram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
- void vregs_w(offs_t offset, u16 data, u16 mem_mask = ~0);
- DECLARE_WRITE_LINE_MEMBER(ptm_irq);
- TILE_GET_INFO_MEMBER(get_bg_tile_info);
- TILE_GET_INFO_MEMBER(get_fg_tile_info);
- TILE_GET_INFO_MEMBER(get_txt_tile_info);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
- void main_map(address_map &map);
- void sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_GINGANIN_H
diff --git a/src/mame/jaleco/ginganin_v.cpp b/src/mame/jaleco/ginganin_v.cpp
deleted file mode 100644
index bf1b095feb3..00000000000
--- a/src/mame/jaleco/ginganin_v.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Luca Elia
-/**************************************************************************
-
- Ginga NinkyouDen
- (C) 1987 Jaleco
-
- driver by Luca Elia (l.elia@tin.it)
-
-
-Note: if MAME_DEBUG is defined, pressing Z with:
-
- Q shows background
- W shows foreground
- E shows frontmost (text) layer
- A shows sprites
-
- Keys can be used togheter!
-
-
-[Screen]
- Visible Size: 256H x 240V
- Dynamic Colors: 256 x 4
- Color Space: 16R x 16G x 16B
-
-[Scrolling layers]
- Format (all layers): Offset: 0x400 0x000
- Bit: fedc---- -------- Color
- ----ba98 76543210 Code
-
- [Background]
- Size: 8192 x 512 (static: stored in ROM)
- Scrolling: X,Y (registers: $60006.w, $60004.w)
- Tiles Size: 16 x 16
- Tiles Number: $400
- Colors: $300-$3ff
-
- [Foreground]
- Size: 4096 x 512
- Scrolling: X,Y (registers: $60002.w, $60000.w)
- Tiles Size: 16 x 16
- Tiles Number: $400
- Colors: $200-$2ff
-
- [Frontmost]
- Size: 256 x 256
- Scrolling: -
- Tiles Size: 8 x 8
- Tiles Number: $200
- Colors: $000-$0ff
-
-
-[Sprites]
- On Screen: 256
- In ROM: $a00
- Colors: $100-$1ff
- Format: See Below
-
-
-**************************************************************************/
-
-#include "emu.h"
-#include "ginganin.h"
-
-
-/***************************************************************************
-
- Callbacks for the TileMap code
-
-***************************************************************************/
-
-
-/* Background - Resides in ROM */
-
-#define BG_GFX (0)
-#define BG_NX (16*32)
-#define BG_NY (16*2)
-
-TILE_GET_INFO_MEMBER(ginganin_state::get_bg_tile_info)
-{
- const u32 code = m_bgrom[2 * tile_index + 0] * 256 + m_bgrom[2 * tile_index + 1];
- tileinfo.set(BG_GFX,
- code,
- code >> 12,
- 0);
-}
-
-
-/* Foreground - Resides in RAM */
-
-#define FG_GFX (1)
-#define FG_NX (16*16)
-#define FG_NY (16*2)
-
-TILE_GET_INFO_MEMBER(ginganin_state::get_fg_tile_info)
-{
- const u16 code = m_fgram[tile_index];
- tileinfo.set(FG_GFX,
- code,
- code >> 12,
- 0);
-}
-
-void ginganin_state::fgram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_fgram[offset]);
- m_fg_tilemap->mark_tile_dirty(offset);
-}
-
-
-/* Frontmost (text) Layer - Resides in RAM */
-
-#define TXT_GFX (2)
-#define TXT_NX (32)
-#define TXT_NY (32)
-
-TILE_GET_INFO_MEMBER(ginganin_state::get_txt_tile_info)
-{
- const u16 code = m_txtram[tile_index];
- tileinfo.set(TXT_GFX,
- code,
- code >> 12,
- 0);
-}
-
-void ginganin_state::txtram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_txtram[offset]);
- m_tx_tilemap->mark_tile_dirty(offset);
-}
-
-
-void ginganin_state::video_start()
-{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, BG_NX, BG_NY);
- m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, FG_NX, FG_NY);
- m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_txt_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, TXT_NX, TXT_NY);
-
- m_fg_tilemap->set_transparent_pen(15);
- m_tx_tilemap->set_transparent_pen(15);
-}
-
-
-void ginganin_state::vregs_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_vregs[offset]);
- data = m_vregs[offset];
-
- switch (offset)
- {
- case 0:
- m_fg_tilemap->set_scrolly(0, data);
- break;
- case 1:
- m_fg_tilemap->set_scrollx(0, data);
- break;
- case 2:
- m_bg_tilemap->set_scrolly(0, data);
- break;
- case 3:
- m_bg_tilemap->set_scrollx(0, data);
- break;
- case 4:
- m_layers_ctrl = data;
- break;
-/* case 5:
- * break;
- */
- case 6:
- m_flipscreen = !(data & 1);
- machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
- break;
- case 7:
- m_soundlatch->write(data);
- m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
- break;
- default:
- logerror("CPU #0 PC %06X : Warning, videoreg %04X <- %04X\n", m_maincpu->pc(), offset, data);
- }
-}
-
-
-
-/* --------------------------[ Sprites Format ]----------------------------
-
-Offset: Values: Format:
-
-0000.w y position fedc ba9- ---- ---- unused
- ---- ---8 ---- ---- subtract 256
- ---- ---- 7654 3210 position
-
-0002.w x position See above
-
-0004.w code f--- ---- ---- ---- y flip
- -e-- ---- ---- ---- x flip
- --dc ---- ---- ---- unused?
- ---- ba98 7654 3210 code
-
-0006.w colour fedc ---- ---- ---- colour code
- ---- ba98 7654 3210 unused?
-
------------------------------------------------------------------------- */
-
-void ginganin_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
-{
- for (int offs = 0; offs < (m_spriteram.bytes() >> 1); offs += 4)
- {
- int y = m_spriteram[offs + 0];
- int x = m_spriteram[offs + 1];
- const u32 code = m_spriteram[offs + 2];
- const u16 attr = m_spriteram[offs + 3];
- int flipx = code & 0x4000;
- int flipy = code & 0x8000;
-
- x = (x & 0xff) - (x & 0x100);
- y = (y & 0xff) - (y & 0x100);
-
- if (m_flipscreen)
- {
- x = 240 - x;
- y = 240 - y;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
- code & 0x3fff,
- attr >> 12,
- flipx, flipy,
- x,y,15);
-
- }
-}
-
-
-u32 ginganin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- int layers_ctrl1 = m_layers_ctrl;
-
-#ifdef MAME_DEBUG
-if (machine().input().code_pressed(KEYCODE_Z))
-{
- int msk = 0;
-
- if (machine().input().code_pressed(KEYCODE_Q)) { msk |= 0xfff1;}
- if (machine().input().code_pressed(KEYCODE_W)) { msk |= 0xfff2;}
- if (machine().input().code_pressed(KEYCODE_E)) { msk |= 0xfff4;}
- if (machine().input().code_pressed(KEYCODE_A)) { msk |= 0xfff8;}
- if (msk != 0) layers_ctrl1 &= msk;
-
-#define SETSCROLL \
- m_bg_tilemap->set_scrollx(0, m_posx); \
- m_bg_tilemap->set_scrolly(0, m_posy); \
- m_fg_tilemap->set_scrollx(0, m_posx); \
- m_fg_tilemap->set_scrolly(0, m_posy); \
- popmessage("B>%04X:%04X F>%04X:%04X",m_posx%(BG_NX*16),m_posy%(BG_NY*16),m_posx%(FG_NX*16),m_posy%(FG_NY*16));
-
- if (machine().input().code_pressed(KEYCODE_L)) { m_posx +=8; SETSCROLL }
- if (machine().input().code_pressed(KEYCODE_J)) { m_posx -=8; SETSCROLL }
- if (machine().input().code_pressed(KEYCODE_K)) { m_posy +=8; SETSCROLL }
- if (machine().input().code_pressed(KEYCODE_I)) { m_posy -=8; SETSCROLL }
- if (machine().input().code_pressed(KEYCODE_H)) { m_posx = m_posy = 0; SETSCROLL }
-
-}
-#endif
-
- if (layers_ctrl1 & 1)
- m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- else
- bitmap.fill(0, cliprect);
-
- if (layers_ctrl1 & 2)
- m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- if (layers_ctrl1 & 8)
- draw_sprites(bitmap, cliprect);
- if (layers_ctrl1 & 4)
- m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
-
- return 0;
-}
diff --git a/src/mame/jaleco/homerun.cpp b/src/mame/jaleco/homerun.cpp
index 35e33c55ef6..538c3ff691b 100644
--- a/src/mame/jaleco/homerun.cpp
+++ b/src/mame/jaleco/homerun.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
+// copyright-holders: Tomasz Slanina
+
/*
Moero!! Pro Yakyuu Homerun Kyousou - (c) 1988 Jaleco
Dynamic Shoot Kyousou - (c) 1988 Jaleco
@@ -16,7 +17,7 @@
homerun, dynashot and ganjaja use an extra soundchip for playing voice/samples
Todo :
- - Dump homerun and dynashot sample rom
+ - Dump homerun and dynashot sample ROM
- Improve controls/DIP switches
- Fix sprite glitches in ganjaja Hop Step & Jump
- Fix sample playing in ganjaja Saisho wa Goo. The words 'rock', 'paper', scissors' are not played?
@@ -109,15 +110,238 @@ This version of Homerun is not dumped.
*/
#include "emu.h"
-#include "homerun.h"
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "sound/samples.h"
+#include "sound/upd7759.h"
#include "sound/ymopn.h"
+
+#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+namespace {
+
+class homerun_state : public driver_device
+{
+public:
+ homerun_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_videoram(*this, "videoram"),
+ m_spriteram(*this, "spriteram"),
+ m_d7756(*this, "d7756"),
+ m_samples(*this, "samples"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_mainbank(*this, "mainbank")
+ { }
+
+ void ganjaja(machine_config &config);
+ void dynashot(machine_config &config);
+ void homerun(machine_config &config);
+
+ DECLARE_READ_LINE_MEMBER(sprite0_r);
+ DECLARE_READ_LINE_MEMBER(homerun_d7756_busy_r);
+ DECLARE_CUSTOM_INPUT_MEMBER(ganjaja_hopper_status_r);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_shared_ptr<u8> m_videoram;
+ required_shared_ptr<u8> m_spriteram;
+ required_device<upd7756_device> m_d7756;
+ optional_device<samples_device> m_samples;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+
+ required_memory_bank m_mainbank;
+
+ u8 m_control = 0;
+ u8 m_sample = 0;
+
+ tilemap_t *m_tilemap = nullptr;
+ u8 m_gfx_ctrl = 0;
+ u16 m_scrollx = 0;
+ u16 m_scrolly = 0;
+
+ void control_w(u8 data);
+ void d7756_sample_w(u8 data);
+ void videoram_w(offs_t offset, u8 data);
+ void scrollhi_w(u8 data);
+ void scrolly_w(u8 data);
+ void scrollx_w(u8 data);
+
+ static rgb_t homerun_RGB332(u32 raw);
+ TILE_GET_INFO_MEMBER(get_tile_info);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void banking_w(u8 data);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void io_map(address_map &map);
+ void mem_map(address_map &map);
+};
+
+
+// video
+
+/**************************************************************************/
+
+READ_LINE_MEMBER(homerun_state::sprite0_r)
+{
+ // sprite-0 vs background collision status, similar to NES
+ return (m_screen->vpos() > (m_spriteram[0] - 16 + 1)) ? 1 : 0;
+}
+
+void homerun_state::scrollhi_w(u8 data)
+{
+ // d0: scroll y high bit
+ // d1: scroll x high bit
+ // other bits: ?
+ m_scrolly = (m_scrolly & 0xff) | (data << 8 & 0x100);
+ m_scrollx = (m_scrollx & 0xff) | (data << 7 & 0x100);
+}
+
+void homerun_state::scrolly_w(u8 data)
+{
+ m_scrolly = (m_scrolly & 0xff00) | data;
+}
+
+void homerun_state::scrollx_w(u8 data)
+{
+ m_scrollx = (m_scrollx & 0xff00) | data;
+}
+
+void homerun_state::banking_w(u8 data)
+{
+ u8 const old = m_gfx_ctrl;
+ if (old ^ data)
+ {
+ if ((old ^ data) & 3)
+ {
+ // games do mid-screen gfx bank switching
+ int vpos = m_screen->vpos();
+ m_screen->update_partial(vpos);
+ }
+
+ // d0-d1: gfx bank
+ // d2-d4: ?
+ // d5-d7: prg bank
+ m_gfx_ctrl = data;
+ if ((old ^ m_gfx_ctrl) & 1)
+ m_tilemap->mark_all_dirty();
+
+ if ((old ^ m_gfx_ctrl) >> 5 & 7)
+ m_mainbank->set_entry(m_gfx_ctrl >> 5 & 7);
+
+ }
+}
+
+void homerun_state::videoram_w(offs_t offset, u8 data)
+{
+ m_videoram[offset] = data;
+ m_tilemap->mark_tile_dirty(offset & 0xfff);
+}
+
+rgb_t homerun_state::homerun_RGB332(u32 raw)
+{
+ /* from PCB photo:
+ bit 7: 470 ohm resistor \
+ bit 6: 220 ohm resistor - --> 470 ohm resistor --> blue
+ bit 5: 470 ohm resistor \
+ bit 4: 220 ohm resistor - --> 470 ohm resistor --> green
+ bit 3: 1 kohm resistor /
+ bit 2: 470 ohm resistor \
+ bit 1: 220 ohm resistor - --> 470 ohm resistor --> red
+ bit 0: 1 kohm resistor /
+ */
+
+ // let's implement it the old fashioned way until it's found out how exactly the resnet is hooked up
+ u8 bit0, bit1, bit2;
+
+ bit0 = (raw >> 0) & 0x01;
+ bit1 = (raw >> 1) & 0x01;
+ bit2 = (raw >> 2) & 0x01;
+ int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ bit0 = (raw >> 3) & 0x01;
+ bit1 = (raw >> 4) & 0x01;
+ bit2 = (raw >> 5) & 0x01;
+ int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ bit0 = 0;
+ bit1 = (raw >> 6) & 0x01;
+ bit2 = (raw >> 7) & 0x01;
+ int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ return rgb_t(r, g, b);
+}
+
+/**************************************************************************/
+
+TILE_GET_INFO_MEMBER(homerun_state::get_tile_info)
+{
+ u32 const tileno = (m_videoram[tile_index]) | ((m_videoram[tile_index | 0x1000] & 0x38) << 5) | ((m_gfx_ctrl & 1) << 11);
+ u16 const palno = (m_videoram[tile_index | 0x1000] & 0x07);
+
+ tileinfo.set(0, tileno, palno, 0);
+}
+void homerun_state::video_start()
+{
+ m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(homerun_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
+
+ save_item(NAME(m_gfx_ctrl));
+ save_item(NAME(m_scrolly));
+ save_item(NAME(m_scrollx));
+}
+
+
+void homerun_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
+ {
+ if (m_spriteram[offs + 0] == 0)
+ continue;
+
+ int const sy = m_spriteram[offs + 0] - 16 + 1;
+ int const sx = m_spriteram[offs + 3];
+ u32 const code = (m_spriteram[offs + 1]) | ((m_spriteram[offs + 2] & 0x8) << 5) | ((m_gfx_ctrl & 3) << 9);
+ u32 const color = (m_spriteram[offs + 2] & 0x07) | 8;
+ bool const flipx = (m_spriteram[offs + 2] & 0x40) >> 6;
+ bool const flipy = (m_spriteram[offs + 2] & 0x80) >> 7;
+
+ if (sy >= 0)
+ {
+ m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx, sy, 0);
+
+ // wraparound x
+ m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx - 256 , sy, 0);
+ }
+ }
+}
+
+u32 homerun_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_tilemap->set_scrolly(0, m_scrolly);
+ m_tilemap->set_scrollx(0, m_scrollx);
+
+ m_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+
+ return 0;
+}
+
+
+// machine
+
/***************************************************************************
I/O / Memory
@@ -137,7 +361,7 @@ void homerun_state::control_w(u8 data)
}
if (m_samples != nullptr)
{
- // play MAME sample if a dump of the internal rom does not exist
+ // play MAME sample if a dump of the internal ROM does not exist
if (data & 0x20 & ~m_control)
m_samples->stop(0);
@@ -164,9 +388,9 @@ void homerun_state::d7756_sample_w(u8 data)
void homerun_state::mem_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
- map(0x4000, 0x7fff).bankr("mainbank");
- map(0x8000, 0x9fff).ram().w(FUNC(homerun_state::videoram_w)).share("videoram");
- map(0xa000, 0xa0ff).ram().share("spriteram");
+ map(0x4000, 0x7fff).bankr(m_mainbank);
+ map(0x8000, 0x9fff).ram().w(FUNC(homerun_state::videoram_w)).share(m_videoram);
+ map(0xa000, 0xa0ff).ram().share(m_spriteram);
map(0xb000, 0xb03f).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
map(0xc000, 0xdfff).ram();
}
@@ -189,11 +413,6 @@ READ_LINE_MEMBER(homerun_state::homerun_d7756_busy_r)
return m_samples->playing(0) ? 0 : 1;
}
-READ_LINE_MEMBER(homerun_state::ganjaja_d7756_busy_r)
-{
- return m_d7756->busy_r();
-}
-
CUSTOM_INPUT_MEMBER(homerun_state::ganjaja_hopper_status_r)
{
// gives hopper error if not 0
@@ -251,7 +470,7 @@ static INPUT_PORTS_START( homerun )
PORT_DIPSETTING( 0x80, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_2C ) )
-// The manuals shows the following DIPs but they don't appear to do anything
+// The manual shows the following DIPs but they don't appear to do anything
// so this could be for a different version which is not dumped.
//..PORT_DIPNAME( 0x70, 0x70, "Difficulty" ) PORT_DIPLOCATION("DIPSW:5,6,7")
//..PORT_DIPSETTING( 0x70, "1" )
@@ -313,7 +532,7 @@ static INPUT_PORTS_START( ganjaja )
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // ?
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(homerun_state, sprite0_r)
- PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(homerun_state, ganjaja_d7756_busy_r)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("d7756", upd7756_device, busy_r)
PORT_BIT( 0x36, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("IN1")
@@ -357,7 +576,7 @@ INPUT_PORTS_END
***************************************************************************/
// homerun samples, taken from the Famicom version of Moero!! Pro Yakyuu
-// note that this is the complete rom contents; not all samples are used in this game
+// note that this is the complete ROM contents; not all samples are used in this game
static const char *const homerun_sample_names[] =
{
"*homerun",
@@ -405,8 +624,8 @@ static const gfx_layout spritelayout =
};
static GFXDECODE_START( gfx_homerun )
- GFXDECODE_ENTRY( "gfx1", 0, gfxlayout, 0, 16 )
- GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 0, 16 )
+ GFXDECODE_ENTRY( "tiles", 0, gfxlayout, 0, 16 )
+ GFXDECODE_ENTRY( "sprites", 0, spritelayout, 0, 16 )
GFXDECODE_END
@@ -435,8 +654,8 @@ void homerun_state::machine_reset()
void homerun_state::dynashot(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, XTAL(20'000'000)/4);
+ // basic machine hardware
+ Z80(config, m_maincpu, XTAL(20'000'000) / 4);
m_maincpu->set_addrmap(AS_PROGRAM, &homerun_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &homerun_state::io_map);
m_maincpu->set_vblank_int("screen", FUNC(homerun_state::irq0_line_hold));
@@ -446,32 +665,31 @@ void homerun_state::dynashot(machine_config &config)
ppi.out_pb_callback().set(FUNC(homerun_state::scrolly_w));
ppi.out_pc_callback().set(FUNC(homerun_state::scrollx_w));
- /* video hardware */
+ // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_raw(XTAL(20'000'000)/4,328,0,256,253,0,240);
+ m_screen->set_raw(XTAL(20'000'000) / 4, 328, 0, 256, 253, 0, 240);
m_screen->set_screen_update(FUNC(homerun_state::screen_update));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_homerun);
- PALETTE(config, m_palette).set_format(1, &homerun_state::homerun_RGB332, 16*4);
+ PALETTE(config, m_palette).set_format(1, &homerun_state::homerun_RGB332, 16 * 4);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
- ym2203_device &ymsnd(YM2203(config, "ymsnd", XTAL(20'000'000)/8));
+ ym2203_device &ymsnd(YM2203(config, "ymsnd", XTAL(20'000'000) / 8));
ymsnd.port_a_read_callback().set_ioport("DSW");
ymsnd.port_b_write_callback().set(FUNC(homerun_state::banking_w));
ymsnd.add_route(ALL_OUTPUTS, "mono", 0.50);
+
+ UPD7756(config, m_d7756);
+ m_d7756->add_route(ALL_OUTPUTS, "mono", 0.75);
}
void homerun_state::homerun(machine_config &config)
{
dynashot(config);
- /* sound hardware */
- UPD7756(config, m_d7756);
- m_d7756->add_route(ALL_OUTPUTS, "mono", 0.75);
-
SAMPLES(config, m_samples);
m_samples->set_channels(1);
m_samples->set_samples_names(homerun_sample_names);
@@ -482,12 +700,8 @@ void homerun_state::ganjaja(machine_config &config)
{
dynashot(config);
- /* basic machine hardware */
- m_maincpu->set_periodic_int(FUNC(homerun_state::irq0_line_hold), attotime::from_hz(4*60)); // ?
-
- /* sound hardware */
- UPD7756(config, m_d7756);
- m_d7756->add_route(ALL_OUTPUTS, "mono", 0.75);
+ // basic machine hardware
+ m_maincpu->set_periodic_int(FUNC(homerun_state::irq0_line_hold), attotime::from_hz(4 * 60)); // ?
}
@@ -498,10 +712,10 @@ ROM_START( homerun )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "homerun.ic43", 0x00000, 0x20000, CRC(e759e476) SHA1(ad4f356ff26209033320a3e6353e4d4d9beb59c1) )
- ROM_REGION( 0x10000, "gfx1", 0 )
+ ROM_REGION( 0x10000, "tiles", 0 )
ROM_LOAD( "homerun.ic60", 0x00000, 0x10000, CRC(69a720d1) SHA1(0f0a4877578f358e9e829ece8c31e23f01adcf83) )
- ROM_REGION( 0x20000, "gfx2", 0 )
+ ROM_REGION( 0x20000, "sprites", 0 )
ROM_LOAD( "homerun.ic120", 0x00000, 0x20000, CRC(52f0709b) SHA1(19e675bcccadb774f60ec5929fc1fb5cf0d3f617) )
ROM_REGION( 0x08000, "d7756", ROMREGION_ERASE00 )
@@ -512,10 +726,10 @@ ROM_START( nhomerun )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "1.ic43", 0x00000, 0x20000, CRC(aed96d6d) SHA1(5cb3932f4cfa3f6c0134ac20a1747c562db31a65) )
- ROM_REGION( 0x10000, "gfx1", 0 )
+ ROM_REGION( 0x10000, "tiles", 0 )
ROM_LOAD( "3.ic60", 0x00000, 0x10000, CRC(69a720d1) SHA1(0f0a4877578f358e9e829ece8c31e23f01adcf83) )
- ROM_REGION( 0x20000, "gfx2", 0 )
+ ROM_REGION( 0x20000, "sprites", 0 )
ROM_LOAD( "2.ic120", 0x00000, 0x20000, CRC(57e9b757) SHA1(8190d690721005407a5b06d13d64e70301d1e925) )
ROM_REGION( 0x08000, "d7756", ROMREGION_ERASE00 )
@@ -526,10 +740,10 @@ ROM_START( dynashot )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "1.ic43", 0x00000, 0x20000, CRC(bf3c9586) SHA1(439effbda305f5fa265e5897c81dc1447e5d867d) )
- ROM_REGION( 0x10000, "gfx1", 0 )
+ ROM_REGION( 0x10000, "tiles", 0 )
ROM_LOAD( "3.ic60", 0x00000, 0x10000, CRC(77d6a608) SHA1(a31ff343a5d4d6f20301c030ecc2e252149bcf9d) )
- ROM_REGION( 0x20000, "gfx2", 0 )
+ ROM_REGION( 0x20000, "sprites", 0 )
ROM_LOAD( "2.ic120", 0x00000, 0x20000, CRC(bedf7b98) SHA1(cb6c5fcaf8df5f5c7636c3c8f79b9dda78e30c2e) )
ROM_REGION( 0x08000, "d7756", ROMREGION_ERASE00 )
@@ -541,16 +755,18 @@ ROM_START( ganjaja )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "1.ic43", 0x00000, 0x20000, CRC(dad57543) SHA1(dbd8b5cee33756ee5e3c41bf84c0f7141d3466dc) )
- ROM_REGION( 0x10000, "gfx1", 0 )
+ ROM_REGION( 0x10000, "tiles", 0 )
ROM_LOAD( "ic60", 0x00000, 0x10000, CRC(855f6b28) SHA1(386411e88cf9bed54fe2073f0828d579cb1d04ee) )
- ROM_REGION( 0x20000, "gfx2", 0 )
+ ROM_REGION( 0x20000, "sprites", 0 )
ROM_LOAD( "2.ic120", 0x00000, 0x20000, CRC(e65d4d57) SHA1(2ec9e5bdaa94b808573313b6eca657d798004b53) )
ROM_REGION( 0x08000, "d7756", 0 )
- ROM_LOAD( "d77p56cr.ic98", 0x00000, 0x08000, CRC(06a234ac) SHA1(b4ceff3f9f78551cf4a085642e162e33b266f067) ) /* D77P56CR OTP rom (One-Time Programmable, note the extra P) */
+ ROM_LOAD( "d77p56cr.ic98", 0x00000, 0x08000, CRC(06a234ac) SHA1(b4ceff3f9f78551cf4a085642e162e33b266f067) ) // D77P56CR OTP rom (One-Time Programmable, note the extra P)
ROM_END
+} // anonymous namespace
+
// YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS
GAME( 1988, nhomerun, 0, homerun, homerun, homerun_state, empty_init, ROT0, "Jaleco", "NEW Moero!! Pro Yakyuu Homerun Kyousou", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // same as below but harder?
diff --git a/src/mame/jaleco/homerun.h b/src/mame/jaleco/homerun.h
deleted file mode 100644
index 59ac37893d1..00000000000
--- a/src/mame/jaleco/homerun.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-/*************************************************************************
-
- Jaleco Moero Pro Yakyuu Homerun hardware
-
-*************************************************************************/
-
-#include "sound/upd7759.h"
-#include "sound/samples.h"
-#include "emupal.h"
-#include "screen.h"
-#include "tilemap.h"
-
-class homerun_state : public driver_device
-{
-public:
- homerun_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_videoram(*this, "videoram"),
- m_spriteram(*this, "spriteram"),
- m_d7756(*this, "d7756"),
- m_samples(*this, "samples"),
- m_gfxdecode(*this, "gfxdecode"),
- m_screen(*this, "screen"),
- m_palette(*this, "palette"),
- m_mainbank(*this, "mainbank")
- { }
-
- void ganjaja(machine_config &config);
- void dynashot(machine_config &config);
- void homerun(machine_config &config);
-
- DECLARE_READ_LINE_MEMBER(sprite0_r);
- DECLARE_READ_LINE_MEMBER(homerun_d7756_busy_r);
- DECLARE_READ_LINE_MEMBER(ganjaja_d7756_busy_r);
- DECLARE_CUSTOM_INPUT_MEMBER(ganjaja_hopper_status_r);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- required_device<cpu_device> m_maincpu;
- required_shared_ptr<u8> m_videoram;
- required_shared_ptr<u8> m_spriteram;
- optional_device<upd7756_device> m_d7756;
- optional_device<samples_device> m_samples;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
-
- required_memory_bank m_mainbank;
-
- u8 m_control = 0;
- u8 m_sample = 0;
-
- tilemap_t *m_tilemap = nullptr;
- int m_gfx_ctrl = 0;
- int m_scrollx = 0;
- int m_scrolly = 0;
-
- void control_w(u8 data);
- void d7756_sample_w(u8 data);
- void videoram_w(offs_t offset, u8 data);
- void scrollhi_w(u8 data);
- void scrolly_w(u8 data);
- void scrollx_w(u8 data);
-
- static rgb_t homerun_RGB332(u32 raw);
- TILE_GET_INFO_MEMBER(get_tile_info);
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void banking_w(u8 data);
- void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
- void io_map(address_map &map);
- void mem_map(address_map &map);
-};
diff --git a/src/mame/jaleco/homerun_v.cpp b/src/mame/jaleco/homerun_v.cpp
deleted file mode 100644
index bea65f63d29..00000000000
--- a/src/mame/jaleco/homerun_v.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-/*************************************************************************
-
- Jaleco Moero Pro Yakyuu Homerun hardware
-
-*************************************************************************/
-
-#include "emu.h"
-#include "homerun.h"
-
-
-/**************************************************************************/
-
-READ_LINE_MEMBER(homerun_state::sprite0_r)
-{
- // sprite-0 vs background collision status, similar to NES
- return (m_screen->vpos() > (m_spriteram[0] - 16 + 1)) ? 1 : 0;
-}
-
-void homerun_state::scrollhi_w(u8 data)
-{
- // d0: scroll y high bit
- // d1: scroll x high bit
- // other bits: ?
- m_scrolly = (m_scrolly & 0xff) | (data << 8 & 0x100);
- m_scrollx = (m_scrollx & 0xff) | (data << 7 & 0x100);
-}
-
-void homerun_state::scrolly_w(u8 data)
-{
- m_scrolly = (m_scrolly & 0xff00) | data;
-}
-
-void homerun_state::scrollx_w(u8 data)
-{
- m_scrollx = (m_scrollx & 0xff00) | data;
-}
-
-void homerun_state::banking_w(u8 data)
-{
- u8 const old = m_gfx_ctrl;
- if (old ^ data)
- {
- if ((old ^ data) & 3)
- {
- // games do mid-screen gfx bank switching
- int vpos = m_screen->vpos();
- m_screen->update_partial(vpos);
- }
-
- // d0-d1: gfx bank
- // d2-d4: ?
- // d5-d7: prg bank
- m_gfx_ctrl = data;
- if ((old ^ m_gfx_ctrl) & 1)
- m_tilemap->mark_all_dirty();
-
- if ((old ^ m_gfx_ctrl) >> 5 & 7)
- m_mainbank->set_entry(m_gfx_ctrl >> 5 & 7);
-
- }
-}
-
-void homerun_state::videoram_w(offs_t offset, u8 data)
-{
- m_videoram[offset] = data;
- m_tilemap->mark_tile_dirty(offset & 0xfff);
-}
-
-rgb_t homerun_state::homerun_RGB332(u32 raw)
-{
- /* from PCB photo:
- bit 7: 470 ohm resistor \
- bit 6: 220 ohm resistor - --> 470 ohm resistor --> blue
- bit 5: 470 ohm resistor \
- bit 4: 220 ohm resistor - --> 470 ohm resistor --> green
- bit 3: 1 kohm resistor /
- bit 2: 470 ohm resistor \
- bit 1: 220 ohm resistor - --> 470 ohm resistor --> red
- bit 0: 1 kohm resistor /
- */
-
- // let's implement it the old fashioned way until it's found out how exactly the resnet is hooked up
- u8 bit0, bit1, bit2;
-
- bit0 = (raw >> 0) & 0x01;
- bit1 = (raw >> 1) & 0x01;
- bit2 = (raw >> 2) & 0x01;
- int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
- bit0 = (raw >> 3) & 0x01;
- bit1 = (raw >> 4) & 0x01;
- bit2 = (raw >> 5) & 0x01;
- int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
- bit0 = 0;
- bit1 = (raw >> 6) & 0x01;
- bit2 = (raw >> 7) & 0x01;
- int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- return rgb_t(r, g, b);
-}
-
-/**************************************************************************/
-
-TILE_GET_INFO_MEMBER(homerun_state::get_tile_info)
-{
- u32 const tileno = (m_videoram[tile_index]) | ((m_videoram[tile_index | 0x1000] & 0x38) << 5) | ((m_gfx_ctrl & 1) << 11);
- u16 const palno = (m_videoram[tile_index | 0x1000] & 0x07);
-
- tileinfo.set(0, tileno, palno, 0);
-}
-
-
-void homerun_state::video_start()
-{
- m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(homerun_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
-
- save_item(NAME(m_gfx_ctrl));
- save_item(NAME(m_scrolly));
- save_item(NAME(m_scrollx));
-}
-
-
-void homerun_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- for (int offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
- {
- if (m_spriteram[offs + 0] == 0)
- continue;
-
- int const sy = m_spriteram[offs + 0] - 16 + 1;
- int const sx = m_spriteram[offs + 3];
- u32 const code = (m_spriteram[offs + 1]) | ((m_spriteram[offs + 2] & 0x8) << 5) | ((m_gfx_ctrl & 3) << 9);
- u32 const color = (m_spriteram[offs + 2] & 0x07) | 8;
- bool const flipx = (m_spriteram[offs + 2] & 0x40) >> 6;
- bool const flipy = (m_spriteram[offs + 2] & 0x80) >> 7;
-
- if (sy >= 0)
- {
- m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx, sy, 0);
-
- // wraparound x
- m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx - 256 , sy, 0);
- }
- }
-}
-
-u32 homerun_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_tilemap->set_scrolly(0, m_scrolly);
- m_tilemap->set_scrollx(0, m_scrollx);
-
- m_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- draw_sprites(bitmap, cliprect);
-
- return 0;
-}
diff --git a/src/mame/jaleco/momoko.cpp b/src/mame/jaleco/momoko.cpp
index dc7901cc926..70af846da76 100644
--- a/src/mame/jaleco/momoko.cpp
+++ b/src/mame/jaleco/momoko.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Uki
+// copyright-holders: Uki
+
/*****************************************************************************
Momoko 120% (c) 1986 Jaleco
@@ -12,18 +13,18 @@
Notes
-Real machine has some bugs.(escalator bug, sprite garbage)
-It is not emulation bug.
+The real machine has some bugs(escalator bug, sprite garbage).
+They are not emulation bugs.
Flipped screen looks wrong, but it is correct.
Note that the game-breaking escalator bug only happens on an 8-way joystick,
-it's safe to assume that this game dedicated cpanel was 4-way.
+it's safe to assume that this game dedicated control panel was 4-way.
Stephh's notes (based on the game Z80 code and some tests) :
- Accoding to the "initialisation" routine (code at 0x2a23),
- the "Bonus Life" Dip Switches shall be coded that way :
+ the "Bonus Life" Dip Switches shall be coded this way :
PORT_DIPNAME( 0x03, 0x03, "1st Bonus Life" )
PORT_DIPSETTING( 0x01, "20k" )
@@ -46,16 +47,385 @@ Stephh's notes (based on the game Z80 code and some tests) :
*****************************************************************************/
#include "emu.h"
-#include "momoko.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "machine/watchdog.h"
#include "sound/ymopn.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+namespace {
+
+class momoko_state : public driver_device
+{
+public:
+ momoko_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_spriteram(*this, "spriteram"),
+ m_videoram(*this, "videoram"),
+ m_bg_scrolly(*this, "bg_scrolly"),
+ m_bg_scrollx(*this, "bg_scrollx"),
+ m_bg_gfx(*this, "bg_gfx"),
+ m_bg_map(*this, "bg_map"),
+ m_bg_col_map(*this, "bg_col_map"),
+ m_fg_map(*this, "fg_map"),
+ m_proms(*this, "proms"),
+ m_bgbank(*this, "bgbank"),
+ m_io_fake(*this, "FAKE"),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette")
+ { }
+
+ void momoko(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ // memory pointers
+ required_shared_ptr<u8> m_spriteram;
+ required_shared_ptr<u8> m_videoram;
+ required_shared_ptr<u8> m_bg_scrolly;
+ required_shared_ptr<u8> m_bg_scrollx;
+ required_region_ptr<u8> m_bg_gfx;
+ required_region_ptr<u8> m_bg_map;
+ required_region_ptr<u8> m_bg_col_map;
+ required_region_ptr<u8> m_fg_map;
+ required_region_ptr<u8> m_proms;
+ required_memory_bank m_bgbank;
+ required_ioport m_io_fake;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ // video-related
+ u8 m_fg_scrollx = 0;
+ u8 m_fg_scrolly = 0;
+ u8 m_fg_select = 0;
+ u8 m_text_scrolly = 0;
+ u8 m_text_mode = 0;
+ u8 m_bg_select = 0;
+ u8 m_bg_priority = 0;
+ u8 m_bg_mask = 0;
+ u8 m_fg_mask = 0;
+ u8 m_flipscreen = 0;
+
+ void bg_read_bank_w(u8 data);
+ void fg_scrollx_w(u8 data);
+ void fg_scrolly_w(u8 data);
+ void fg_select_w(u8 data);
+ void text_scrolly_w(u8 data);
+ void text_mode_w(u8 data);
+ void bg_scrollx_w(offs_t offset, u8 data);
+ void bg_scrolly_w(offs_t offset, u8 data);
+ void bg_select_w(u8 data);
+ void bg_priority_w(u8 data);
+ void flipscreen_w(u8 data);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_bg_pri(bitmap_ind16 &bitmap, int chr, int col, int flipx, int flipy, int x, int y, int pri);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int start, int end, int flip);
+ void draw_text_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip);
+ void draw_fg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip);
+ void draw_bg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip, bool high);
+
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
+/*******************************************************************************
+
+ Video consists of
+ - Sprites
+ - 2x ROM based tilemaps (bg and fg) with priority over some sprites
+ - 1x RAM based tilemap (text layer) (no wrapping?)
+
+ TODO:
+ - update to use tilemap system?
+ - check if any of this is common Jaleco/NMK etc. hardware and use shared
+ devices if possible
+
+*******************************************************************************/
+
+void momoko_state::fg_scrollx_w(u8 data)
+{
+ m_fg_scrollx = data;
+}
+
+void momoko_state::fg_scrolly_w(u8 data)
+{
+ m_fg_scrolly = data;
+}
+
+void momoko_state::fg_select_w(u8 data)
+{
+ m_fg_select = data & 0x0f;
+ m_fg_mask = data & 0x10;
+}
+
+void momoko_state::text_scrolly_w(u8 data)
+{
+ m_text_scrolly = data;
+}
+
+void momoko_state::text_mode_w(u8 data)
+{
+ m_text_mode = data;
+}
+
+void momoko_state::bg_scrollx_w(offs_t offset, u8 data)
+{
+ m_bg_scrollx[offset] = data;
+}
+
+void momoko_state::bg_scrolly_w(offs_t offset, u8 data)
+{
+ m_bg_scrolly[offset] = data;
+}
+
+void momoko_state::bg_select_w(u8 data)
+{
+ m_bg_select = data & 0x0f;
+ m_bg_mask = data & 0x10;
+}
+
+void momoko_state::bg_priority_w(u8 data)
+{
+ m_bg_priority = data & 0x01;
+}
+
+void momoko_state::flipscreen_w(u8 data)
+{
+ m_flipscreen = data & 0x01;
+}
+
+/****************************************************************************/
+
+void momoko_state::draw_bg_pri(bitmap_ind16 &bitmap, int chr, int col, int flipx, int flipy, int x, int y, int pri)
+{
+ for (int sy = 0; sy < 8; sy++)
+ {
+ const u32 gfxadr = chr * 16 + sy * 2;
+ for (int xx = 0; xx < 2; xx++)
+ {
+ u8 d0 = m_bg_gfx[gfxadr + xx * 4096];
+ u8 d1 = m_bg_gfx[gfxadr + xx * 4096 + 1];
+
+ for (int sx = 0; sx < 4; sx++)
+ {
+ const u8 dot = (d0 & 0x08) | ((d0 & 0x80) >> 5) | ((d1 & 0x08) >> 2) | ((d1 & 0x80) >> 7);
+ const int px = (flipx == 0) ? (sx + xx * 4 + x) : (7 - sx - xx * 4 + x);
+ const int py = (flipy == 0) ? (sy + y) : (7 - sy + y);
+
+ if (dot >= pri)
+ bitmap.pix(py, px) = col * 16 + dot + 256;
+
+ d0 <<= 1;
+ d1 <<= 1;
+ }
+ }
+ }
+}
+
+
+void momoko_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int start, int end, int flip)
+{
+ for (int offs = start; offs < end; offs += 4)
+ {
+ int px, py;
+ u32 chr = m_spriteram[offs + 1] | ((m_spriteram[offs + 2] & 0x60) << 3);
+ chr = ((chr & 0x380) << 1) | (chr & 0x7f);
+ const int col = m_spriteram[offs + 2] & 0x07;
+ const int fx = ((m_spriteram[offs + 2] & 0x10) >> 4) ^ flip;
+ const int fy = ((m_spriteram[offs + 2] & 0x08) >> 3) ^ flip; // ???
+ const int x = m_spriteram[offs + 3];
+ const int y = m_spriteram[offs + 0];
+
+ if (flip == 0)
+ {
+ px = x;
+ py = 239 - y;
+ }
+ else
+ {
+ px = 248 - x;
+ py = y + 1;
+ }
+ m_gfxdecode->gfx(3)->transpen(bitmap, cliprect,
+ chr,
+ col,
+ !fx, fy,
+ px, py, 0);
+ }
+}
+
+void momoko_state::draw_text_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip)
+{
+ for (int y = 16; y < 240; y++)
+ {
+ for (int x = 0; x < 32; x++)
+ {
+ int px, py, col;
+ int sy = y;
+ if (m_text_mode == 0)
+ col = m_proms[(sy >> 3) + 0x100] & 0x0f;
+ else
+ {
+ if (m_proms[y] < 0x08)
+ sy += m_text_scrolly;
+ col = (m_proms[y] & 0x07) + 0x10;
+ }
+ const int dy = sy & 7;
+ if (flip == 0)
+ {
+ px = x * 8;
+ py = y;
+ }
+ else
+ {
+ px = 248 - x * 8;
+ py = 255 - y;
+ }
+ const int ramoffset = (sy >> 3) * 32 + x;
+
+ if (ramoffset < 0x400) // high score table, no wrapping?
+ m_gfxdecode->gfx(0)->transpen(bitmap, cliprect,
+ m_videoram[ramoffset] * 8 + dy,
+ col,
+ flip, 0,
+ px, py, 0);
+ }
+ }
+}
+
+void momoko_state::draw_fg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip)
+{
+ const int dx = (7 - m_fg_scrollx) & 7;
+ const int dy = (7 - m_fg_scrolly) & 7;
+ const int rx = m_fg_scrollx >> 3;
+ const int ry = m_fg_scrolly >> 3;
+
+ for (int y = 0; y < 29; y++)
+ {
+ for (int x = 0; x < 32; x++)
+ {
+ int px, py;
+ const int radr = ((ry + y + 34) & 0x3f) * 0x20 + ((rx + x) & 0x1f) + (m_fg_select & 3) * 0x800;
+ const u32 chr = m_fg_map[radr];
+ if (flip == 0)
+ {
+ px = 8 * x + dx - 6;
+ py = 8 * y + dy + 9;
+ }
+ else
+ {
+ px = 248 - (8 * x + dx - 8);
+ py = 248 - (8 * y + dy + 9);
+ }
+ m_gfxdecode->gfx(2)->transpen(bitmap, cliprect,
+ chr,
+ 0, // color
+ flip, flip, // flip
+ px, py, 0);
+ }
+ }
+}
+
+void momoko_state::draw_bg_romtilemap(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int flip, bool high)
+{
+ const int dx = (7 - m_bg_scrollx[0]) & 7;
+ const int dy = (7 - m_bg_scrolly[0]) & 7;
+ const int rx = (m_bg_scrollx[0] + m_bg_scrollx[1] * 256) >> 3;
+ const int ry = (m_bg_scrolly[0] + m_bg_scrolly[1] * 256) >> 3;
+
+ for (int y = 0; y < 29; y++)
+ {
+ for (int x = 0; x < 32; x++)
+ {
+ int px, py;
+ const int radr = ((ry + y + 2) & 0x3ff) * 128 + ((rx + x) & 0x7f);
+ u32 chr = m_bg_map[radr];
+ int col = m_bg_col_map[chr + m_bg_select * 512 + m_bg_priority * 256];
+ chr = chr + m_bg_select * 512;
+
+ if (flip == 0)
+ {
+ px = 8 * x + dx - 6;
+ py = 8 * y + dy + 9;
+ }
+ else
+ {
+ px = 248 - (8 * x + dx - 8);
+ py = 248 - (8 * y + dy + 9);
+ }
+
+ if (!high)
+ {
+ m_gfxdecode->gfx(1)->opaque(bitmap, cliprect,
+ chr,
+ col,
+ flip, flip,
+ px, py);
+ }
+ else
+ {
+ const u8 pri = (col & 0x10) >> 1;
+ if (pri != 0)
+ {
+ col = col & 0x0f;
+ draw_bg_pri(bitmap, chr, col, flip, flip, px, py, pri);
+ }
+ }
+ }
+ }
+}
+
+/****************************************************************************/
+
+u32 momoko_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ const int flip = m_flipscreen ^ (m_io_fake->read() & 0x01);
+
+ // draw BG layer - all tiles
+
+ if (m_bg_mask == 0)
+ draw_bg_romtilemap(screen, bitmap, cliprect, flip, false);
+ else
+ bitmap.fill(256, cliprect);
+
+ // draw sprites (momoko)
+ draw_sprites(screen, bitmap, cliprect, 0, 9 * 4, flip);
+
+ // draw BG layer - high priority tiles
+ if (m_bg_mask == 0)
+ draw_bg_romtilemap(screen, bitmap, cliprect, flip, true);
+
+ // draw sprites (others)
+ draw_sprites(screen, bitmap, cliprect, 9 * 4, m_spriteram.bytes(), flip);
+
+ // draw text layer
+ draw_text_tilemap(screen, bitmap, cliprect, flip);
+
+ // draw FG layer
+ if (m_fg_mask == 0)
+ draw_fg_romtilemap(screen, bitmap, cliprect, flip);
+
+ return 0;
+}
+
+
+// machine
+
void momoko_state::bg_read_bank_w(u8 data)
{
m_bgbank->set_entry(data & 0x1f);
@@ -63,12 +433,12 @@ void momoko_state::bg_read_bank_w(u8 data)
/****************************************************************************/
-void momoko_state::momoko_map(address_map &map)
+void momoko_state::main_map(address_map &map)
{
map(0x0000, 0xbfff).rom();
map(0xc000, 0xcfff).ram();
- map(0xd064, 0xd0ff).ram().share("spriteram");
- map(0xd400, 0xd400).portr("IN0").nopw(); /* interrupt ack? */
+ map(0xd064, 0xd0ff).ram().share(m_spriteram);
+ map(0xd400, 0xd400).portr("IN0").nopw(); // interrupt ack?
map(0xd402, 0xd402).portr("IN1").w(FUNC(momoko_state::flipscreen_w));
map(0xd404, 0xd404).w("watchdog", FUNC(watchdog_timer_device::reset_w));
map(0xd406, 0xd406).portr("DSW0").w("soundlatch", FUNC(generic_latch_8_device::write));
@@ -77,24 +447,24 @@ void momoko_state::momoko_map(address_map &map)
map(0xdc00, 0xdc00).w(FUNC(momoko_state::fg_scrolly_w));
map(0xdc01, 0xdc01).w(FUNC(momoko_state::fg_scrollx_w));
map(0xdc02, 0xdc02).w(FUNC(momoko_state::fg_select_w));
- map(0xe000, 0xe3ff).ram().share("videoram");
+ map(0xe000, 0xe3ff).ram().share(m_videoram);
map(0xe800, 0xe800).w(FUNC(momoko_state::text_scrolly_w));
map(0xe801, 0xe801).w(FUNC(momoko_state::text_mode_w));
- map(0xf000, 0xffff).bankr("bgbank");
- map(0xf000, 0xf001).w(FUNC(momoko_state::bg_scrolly_w)).share("bg_scrolly");
- map(0xf002, 0xf003).w(FUNC(momoko_state::bg_scrollx_w)).share("bg_scrollx");
+ map(0xf000, 0xffff).bankr(m_bgbank);
+ map(0xf000, 0xf001).w(FUNC(momoko_state::bg_scrolly_w)).share(m_bg_scrolly);
+ map(0xf002, 0xf003).w(FUNC(momoko_state::bg_scrollx_w)).share(m_bg_scrollx);
map(0xf004, 0xf004).w(FUNC(momoko_state::bg_read_bank_w));
map(0xf006, 0xf006).w(FUNC(momoko_state::bg_select_w));
map(0xf007, 0xf007).w(FUNC(momoko_state::bg_priority_w));
}
-void momoko_state::momoko_sound_map(address_map &map)
+void momoko_state::sound_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram();
- map(0x9000, 0x9000).nopw(); /* unknown */
+ map(0x9000, 0x9000).nopw(); // unknown
map(0xa000, 0xa001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write));
- map(0xb000, 0xb000).nopw(); /* unknown */
+ map(0xb000, 0xb000).nopw(); // unknown
map(0xc000, 0xc001).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write));
}
@@ -145,13 +515,13 @@ static INPUT_PORTS_START( momoko )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_START("DSW1")
- PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) /* see notes */
+ PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) // see notes
PORT_DIPSETTING( 0x01, "20k" )
PORT_DIPSETTING( 0x03, "30k" )
PORT_DIPSETTING( 0x02, "50k" )
PORT_DIPSETTING( 0x00, "100k" )
- PORT_DIPUNUSED( 0x04, IP_ACTIVE_LOW ) /* see notes */
- PORT_DIPUNUSED( 0x08, IP_ACTIVE_LOW ) /* see notes */
+ PORT_DIPUNUSED( 0x04, IP_ACTIVE_LOW ) // see notes
+ PORT_DIPUNUSED( 0x08, IP_ACTIVE_LOW ) // see notes
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Cabinet ) )
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x10, DEF_STR( Cocktail ) )
@@ -171,9 +541,9 @@ INPUT_PORTS_END
static const gfx_layout charlayout =
{
- 8,8, /* 8*8 characters */
- 256, /* 256 characters */
- 2, /* 2 bits per pixel */
+ 8,8, // 8*8 characters
+ 256, // 256 characters
+ 2, // 2 bits per pixel
{4, 0},
{0, 1, 2, 3, 256*8*8+0, 256*8*8+1, 256*8*8+2, 256*8*8+3},
{8*0, 8*1, 8*2, 8*3, 8*4, 8*5, 8*6, 8*7},
@@ -182,9 +552,9 @@ static const gfx_layout charlayout =
static const gfx_layout spritelayout =
{
- 8,16, /* 8*16 characters */
- 2048-128, /* 1024 sprites ( ccc 0ccccccc ) */
- 4, /* 4 bits per pixel */
+ 8,16, // 8*16 characters
+ 2048-128, // 1024 sprites ( ccc 0ccccccc )
+ 4, // 4 bits per pixel
{12,8,4,0},
{0, 1, 2, 3, 4096*8+0, 4096*8+1, 4096*8+2, 4096*8+3},
{0, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,
@@ -194,9 +564,9 @@ static const gfx_layout spritelayout =
static const gfx_layout tilelayout =
{
- 8,8, /* 8*8 characters */
- 8192-256, /* 4096 tiles ( cccc0 cccccccc ) */
- 4, /* 4 bits per pixel */
+ 8,8, // 8*8 characters
+ 8192-256, // 4096 tiles ( cccc0 cccccccc )
+ 4, // 4 bits per pixel
{4,0,12,8},
{0, 1, 2, 3, 4096*8+0, 4096*8+1, 4096*8+2, 4096*8+3},
{0, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16},
@@ -205,9 +575,9 @@ static const gfx_layout tilelayout =
static const gfx_layout charlayout1 =
{
- 8,1, /* 8*1 characters */
- 256*8, /* 2048 characters */
- 2, /* 2 bits per pixel */
+ 8,1, // 8*1 characters
+ 256*8, // 2048 characters
+ 2, // 2 bits per pixel
{4, 0},
{0, 1, 2, 3, 256*8*8+0, 256*8*8+1, 256*8*8+2, 256*8*8+3},
{8*0},
@@ -215,10 +585,10 @@ static const gfx_layout charlayout1 =
};
static GFXDECODE_START( gfx_momoko )
- GFXDECODE_ENTRY( "text", 0x0000, charlayout1, 0, 24 ) /* TEXT */
- GFXDECODE_ENTRY( "bg_gfx", 0x0000, tilelayout, 256, 16 ) /* BG */
- GFXDECODE_ENTRY( "fg_gfx", 0x0000, charlayout, 0, 1 ) /* FG */
- GFXDECODE_ENTRY( "spr_gfx", 0x0000, spritelayout, 128, 8 ) /* sprite */
+ GFXDECODE_ENTRY( "text", 0x0000, charlayout1, 0, 24 )
+ GFXDECODE_ENTRY( "bg_gfx", 0x0000, tilelayout, 256, 16 )
+ GFXDECODE_ENTRY( "fg_gfx", 0x0000, charlayout, 0, 1 )
+ GFXDECODE_ENTRY( "spr_gfx", 0x0000, spritelayout, 128, 8 )
GFXDECODE_END
/****************************************************************************/
@@ -255,20 +625,20 @@ void momoko_state::machine_reset()
void momoko_state::momoko(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, XTAL(10'000'000)/2); /* 5.0MHz */
- m_maincpu->set_addrmap(AS_PROGRAM, &momoko_state::momoko_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, XTAL(10'000'000) / 2); // 5.0MHz
+ m_maincpu->set_addrmap(AS_PROGRAM, &momoko_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(momoko_state::irq0_line_hold));
- z80_device &audiocpu(Z80(config, "audiocpu", XTAL(10'000'000)/4)); /* 2.5MHz */
- audiocpu.set_addrmap(AS_PROGRAM, &momoko_state::momoko_sound_map);
+ z80_device &audiocpu(Z80(config, "audiocpu", XTAL(10'000'000) / 4)); // 2.5MHz
+ audiocpu.set_addrmap(AS_PROGRAM, &momoko_state::sound_map);
WATCHDOG_TIMER(config, "watchdog");
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_size(32*8, 32*8);
screen.set_visarea(1*8, 31*8-1, 2*8, 29*8-1);
screen.set_screen_update(FUNC(momoko_state::screen_update));
@@ -278,18 +648,18 @@ void momoko_state::momoko(machine_config &config)
PALETTE(config, m_palette).set_format(palette_device::xRGB_444, 512);
m_palette->set_endianness(ENDIANNESS_BIG);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch");
- ym2203_device &ym1(YM2203(config, "ym1", XTAL(10'000'000)/8));
+ ym2203_device &ym1(YM2203(config, "ym1", XTAL(10'000'000) / 8));
ym1.add_route(0, "mono", 0.15);
ym1.add_route(1, "mono", 0.15);
ym1.add_route(2, "mono", 0.15);
ym1.add_route(3, "mono", 0.40);
- ym2203_device &ym2(YM2203(config, "ym2", XTAL(10'000'000)/8));
+ ym2203_device &ym2(YM2203(config, "ym2", XTAL(10'000'000) / 8));
ym2.port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ym2.add_route(0, "mono", 0.15);
ym2.add_route(1, "mono", 0.15);
@@ -300,128 +670,131 @@ void momoko_state::momoko(machine_config &config)
/****************************************************************************/
ROM_START( momoko )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* main CPU */
+ ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "momoko03.m6", 0x0000, 0x8000, CRC(386e26ed) SHA1(ad746ed1b87bafc5b4df9a28aade58cf894f4e7b) ) // age progression text in Japanese
ROM_LOAD( "momoko02.m5", 0x8000, 0x4000, CRC(4255e351) SHA1(27a0e8d8aea223d2128139582e3b66106f3608ef) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound CPU */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "momoko01.u4", 0x0000, 0x8000, CRC(e8a6673c) SHA1(f8984b063929305c9058801202405e6d45254b5b) )
- ROM_REGION( 0x2000, "text", 0 ) /* text */
+ ROM_REGION( 0x2000, "text", 0 )
ROM_LOAD( "momoko13.u4", 0x0000, 0x2000, CRC(2745cf5a) SHA1(3db7c6319cac63df1620ef25508c5c45eaa4b141) ) // On the FP-8631 PCB
- ROM_REGION( 0x2000, "fg_gfx", 0 ) /* FG */
+ ROM_REGION( 0x2000, "fg_gfx", 0 )
ROM_LOAD( "momoko14.p2", 0x0000, 0x2000, CRC(cfccca05) SHA1(4ecff488a37ac76ecb9ecf8980bea30dcc9c9951) )
- ROM_REGION( 0x10000, "spr_gfx", 0 ) /* sprite */
+ ROM_REGION( 0x10000, "spr_gfx", 0 )
ROM_LOAD16_BYTE( "momoko16.e5", 0x0000, 0x8000, CRC(fc6876fc) SHA1(b2d06bc01ef9f4db9bf8902d67f31ccbb0fea61a) ) // On the FP-8631 PCB
ROM_LOAD16_BYTE( "momoko17.e6", 0x0001, 0x8000, CRC(45dc0247) SHA1(1b2bd4197ab7d237966e037c249b5bd623646c0b) ) // On the FP-8631 PCB
- ROM_REGION( 0x20000, "bg_gfx", 0 ) /* BG */
+ ROM_REGION( 0x20000, "bg_gfx", 0 )
ROM_LOAD16_BYTE( "momoko09.e8", 0x00000, 0x8000, CRC(9f5847c7) SHA1(6bc9a00622d8a23446294a8d5d467375c5719125) )
ROM_LOAD16_BYTE( "momoko11.c8", 0x00001, 0x8000, CRC(9c9fbd43) SHA1(7adfd7ea3dd6745c14e719883f1a86e0a3b3c0ff) )
ROM_LOAD16_BYTE( "momoko10.d8", 0x10000, 0x8000, CRC(ae17e74b) SHA1(f52657ea6b6ac518b70fd7b811d9699da27f67d9) )
ROM_LOAD16_BYTE( "momoko12.a8", 0x10001, 0x8000, CRC(1e29c9c4) SHA1(d78f102cefc9852b529dd317a76c7003ec2ad3d5) )
- ROM_REGION( 0x20000, "bg_map", 0 ) /* BG map */
+ ROM_REGION( 0x20000, "bg_map", 0 )
ROM_LOAD( "momoko04.r8", 0x0000, 0x8000, CRC(3ab3c2c3) SHA1(d4a0d7f83bf64769e90a2c264c6114ac308cb8b5) )
ROM_LOAD( "momoko05.p8", 0x8000, 0x8000, CRC(757cdd2b) SHA1(3471b42dc6458a18894dbd0638f4fe43c86dd70d) )
ROM_LOAD( "momoko06.n8", 0x10000, 0x8000, CRC(20cacf8b) SHA1(e2b39abfc960e1c472e2bcf0cf06825c39941c03) )
ROM_LOAD( "momoko07.l8", 0x18000, 0x8000, CRC(b94b38db) SHA1(9c9e45bbeca7b6b8b0051b144fb31fceaf5d6906) )
- ROM_REGION( 0x2000, "bg_col_map", 0 ) /* BG color/priority table */
+ ROM_REGION( 0x2000, "bg_col_map", 0 )
ROM_LOAD( "momoko08.h8", 0x0000, 0x2000, CRC(69b41702) SHA1(21b33b243dd6eaec8d41d9fd4d9e7faf2bd7f4d2) )
- ROM_REGION( 0x4000, "fg_map", 0 ) /* FG map */
+ ROM_REGION( 0x4000, "fg_map", 0 )
ROM_LOAD( "momoko15.k2", 0x0000, 0x4000, CRC(8028f806) SHA1(c7450d48803082f64af67fe752b6f49b71b6ff48) ) // On the FP-8631 PCB
- ROM_REGION( 0x0120, "proms", 0 ) /* TEXT color */
+ ROM_REGION( 0x0120, "proms", 0 ) // text color
ROM_LOAD( "momoko-c.bin", 0x0000, 0x0100, CRC(f35ccae0) SHA1(60b99dd3c96637dacba7e96a143b1a2d6ffd28b9) )
ROM_LOAD( "momoko-b.bin", 0x0100, 0x0020, CRC(427b0e5c) SHA1(aa2797b899571527cc96013fd3420b841954ee67) )
ROM_END
ROM_START( momokoe )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* main CPU */
+ ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "3.m6", 0x0000, 0x8000, CRC(84053a7d) SHA1(6e8fb22bb48954f4fed2530991ebe5b872c9c089) ) // age progression text in English
ROM_LOAD( "2.m5", 0x8000, 0x4000, CRC(98ad397b) SHA1(b7ae218d0d397b1e258ec6d1f836cb998f984092) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound CPU */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "momoko01.u4", 0x0000, 0x8000, CRC(e8a6673c) SHA1(f8984b063929305c9058801202405e6d45254b5b) )
- ROM_REGION( 0x2000, "text", 0 ) /* text */
+ ROM_REGION( 0x2000, "text", 0 )
ROM_LOAD( "momoko13.u4", 0x0000, 0x2000, CRC(2745cf5a) SHA1(3db7c6319cac63df1620ef25508c5c45eaa4b141) ) // On the FP-8631 PCB
- ROM_REGION( 0x2000, "fg_gfx", 0 ) /* FG */
+ ROM_REGION( 0x2000, "fg_gfx", 0 )
ROM_LOAD( "momoko14.p2", 0x0000, 0x2000, CRC(cfccca05) SHA1(4ecff488a37ac76ecb9ecf8980bea30dcc9c9951) )
- ROM_REGION( 0x10000, "spr_gfx", 0 ) /* sprite */
+ ROM_REGION( 0x10000, "spr_gfx", 0 )
ROM_LOAD16_BYTE( "momoko16.e5", 0x0000, 0x8000, CRC(fc6876fc) SHA1(b2d06bc01ef9f4db9bf8902d67f31ccbb0fea61a) ) // On the FP-8631 PCB
ROM_LOAD16_BYTE( "momoko17.e6", 0x0001, 0x8000, CRC(45dc0247) SHA1(1b2bd4197ab7d237966e037c249b5bd623646c0b) ) // On the FP-8631 PCB
- ROM_REGION( 0x20000, "bg_gfx", 0 ) /* BG */
+ ROM_REGION( 0x20000, "bg_gfx", 0 )
ROM_LOAD16_BYTE( "momoko09.e8", 0x00000, 0x8000, CRC(9f5847c7) SHA1(6bc9a00622d8a23446294a8d5d467375c5719125) )
ROM_LOAD16_BYTE( "momoko11.c8", 0x00001, 0x8000, CRC(9c9fbd43) SHA1(7adfd7ea3dd6745c14e719883f1a86e0a3b3c0ff) )
ROM_LOAD16_BYTE( "momoko10.d8", 0x10000, 0x8000, CRC(ae17e74b) SHA1(f52657ea6b6ac518b70fd7b811d9699da27f67d9) )
ROM_LOAD16_BYTE( "momoko12.a8", 0x10001, 0x8000, CRC(1e29c9c4) SHA1(d78f102cefc9852b529dd317a76c7003ec2ad3d5) )
- ROM_REGION( 0x20000, "bg_map", 0 ) /* BG map */
+ ROM_REGION( 0x20000, "bg_map", 0 )
ROM_LOAD( "momoko04.r8", 0x0000, 0x8000, CRC(3ab3c2c3) SHA1(d4a0d7f83bf64769e90a2c264c6114ac308cb8b5) )
ROM_LOAD( "momoko05.p8", 0x8000, 0x8000, CRC(757cdd2b) SHA1(3471b42dc6458a18894dbd0638f4fe43c86dd70d) )
ROM_LOAD( "momoko06.n8", 0x10000, 0x8000, CRC(20cacf8b) SHA1(e2b39abfc960e1c472e2bcf0cf06825c39941c03) )
ROM_LOAD( "momoko07.l8", 0x18000, 0x8000, CRC(b94b38db) SHA1(9c9e45bbeca7b6b8b0051b144fb31fceaf5d6906) )
- ROM_REGION( 0x2000, "bg_col_map", 0 ) /* BG color/priority table */
+ ROM_REGION( 0x2000, "bg_col_map", 0 )
ROM_LOAD( "momoko08.h8", 0x0000, 0x2000, CRC(69b41702) SHA1(21b33b243dd6eaec8d41d9fd4d9e7faf2bd7f4d2) )
- ROM_REGION( 0x4000, "fg_map", 0 ) /* FG map */
+ ROM_REGION( 0x4000, "fg_map", 0 )
ROM_LOAD( "momoko15.k2", 0x0000, 0x4000, CRC(8028f806) SHA1(c7450d48803082f64af67fe752b6f49b71b6ff48) ) // On the FP-8631 PCB
- ROM_REGION( 0x0120, "proms", 0 ) /* TEXT color */
+ ROM_REGION( 0x0120, "proms", 0 ) // text color
ROM_LOAD( "momoko-c.bin", 0x0000, 0x0100, CRC(f35ccae0) SHA1(60b99dd3c96637dacba7e96a143b1a2d6ffd28b9) )
ROM_LOAD( "momoko-b.bin", 0x0100, 0x0020, CRC(427b0e5c) SHA1(aa2797b899571527cc96013fd3420b841954ee67) )
ROM_END
ROM_START( momokob ) // bootleg board, almost exact copy of an original one
- ROM_REGION( 0x10000, "maincpu", 0 ) /* main CPU */
+ ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "3.bin", 0x0000, 0x8000, CRC(a18d7e78) SHA1(5d2dd498be3e22b5e8fc5ffe17e1ef463c1e9a02) ) // age progression text in Engrish, title screen in English
ROM_LOAD( "2.bin", 0x8000, 0x4000, CRC(2dcf50ed) SHA1(6d02cb86fce031859bc0a5a26ecf7a8c8b89dea3) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound CPU */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "momoko01.u4", 0x0000, 0x8000, CRC(e8a6673c) SHA1(f8984b063929305c9058801202405e6d45254b5b) )
- ROM_REGION( 0x2000, "text", 0 ) /* text */
+ ROM_REGION( 0x2000, "text", 0 )
ROM_LOAD( "momoko13.u4", 0x0000, 0x2000, CRC(2745cf5a) SHA1(3db7c6319cac63df1620ef25508c5c45eaa4b141) )
- ROM_REGION( 0x2000, "fg_gfx", 0 ) /* FG */
+ ROM_REGION( 0x2000, "fg_gfx", 0 )
ROM_LOAD( "momoko14.p2", 0x0000, 0x2000, CRC(cfccca05) SHA1(4ecff488a37ac76ecb9ecf8980bea30dcc9c9951) )
- ROM_REGION( 0x10000, "spr_gfx", 0 ) /* sprite */
+ ROM_REGION( 0x10000, "spr_gfx", 0 )
ROM_LOAD16_BYTE( "16.bin", 0x0000, 0x8000, CRC(49de49a1) SHA1(b4954286cba50332d4366a8160e9fbfd574c60ed) )
ROM_LOAD16_BYTE( "17.bin", 0x0001, 0x8000, CRC(f06a3d1a) SHA1(f377ffad958fdc9cff2baee70ce4ba9080b5fe0d) )
- ROM_REGION( 0x20000, "bg_gfx", 0 ) /* BG */
+ ROM_REGION( 0x20000, "bg_gfx", 0 )
ROM_LOAD16_BYTE( "momoko09.e8", 0x00000, 0x8000, CRC(9f5847c7) SHA1(6bc9a00622d8a23446294a8d5d467375c5719125) )
ROM_LOAD16_BYTE( "momoko11.c8", 0x00001, 0x8000, CRC(9c9fbd43) SHA1(7adfd7ea3dd6745c14e719883f1a86e0a3b3c0ff) )
ROM_LOAD16_BYTE( "10.bin", 0x10000, 0x8000, CRC(68b9156d) SHA1(e157434d7ee33837ba35e720d221bf1eb21b7020) )
ROM_LOAD16_BYTE( "12.bin", 0x10001, 0x8000, CRC(c32f5e19) SHA1(488da565e20bf002ff3dffca1efedbdf29e6e559) )
- ROM_REGION( 0x20000, "bg_map", 0 ) /* BG map */
+ ROM_REGION( 0x20000, "bg_map", 0 )
ROM_LOAD( "4.bin", 0x0000, 0x8000, CRC(1f0226d5) SHA1(6411e85c51e23dfe6c643692987dc7eeef37538f) )
ROM_LOAD( "momoko05.p8", 0x8000, 0x8000, CRC(757cdd2b) SHA1(3471b42dc6458a18894dbd0638f4fe43c86dd70d) )
ROM_LOAD( "momoko06.n8", 0x10000, 0x8000, CRC(20cacf8b) SHA1(e2b39abfc960e1c472e2bcf0cf06825c39941c03) )
ROM_LOAD( "momoko07.l8", 0x18000, 0x8000, CRC(b94b38db) SHA1(9c9e45bbeca7b6b8b0051b144fb31fceaf5d6906) )
- ROM_REGION( 0x2000, "bg_col_map", 0 ) /* BG color/priority table */
+ ROM_REGION( 0x2000, "bg_col_map", 0 )
ROM_LOAD( "momoko08.h8", 0x0000, 0x2000, CRC(69b41702) SHA1(21b33b243dd6eaec8d41d9fd4d9e7faf2bd7f4d2) )
- ROM_REGION( 0x4000, "fg_map", 0 ) /* FG map */
+ ROM_REGION( 0x4000, "fg_map", 0 )
ROM_LOAD( "momoko15.k2", 0x0000, 0x4000, CRC(8028f806) SHA1(c7450d48803082f64af67fe752b6f49b71b6ff48) )
- ROM_REGION( 0x0120, "proms", 0 ) /* TEXT color */
+ ROM_REGION( 0x0120, "proms", 0 ) // text color
ROM_LOAD( "momoko-c.bin", 0x0000, 0x0100, CRC(f35ccae0) SHA1(60b99dd3c96637dacba7e96a143b1a2d6ffd28b9) )
ROM_LOAD( "momoko-b.bin", 0x0100, 0x0020, CRC(427b0e5c) SHA1(aa2797b899571527cc96013fd3420b841954ee67) )
ROM_END
+} // anonymous namespace
+
+
GAME( 1986, momoko, 0, momoko, momoko, momoko_state, empty_init, ROT0, "Jaleco", "Momoko 120% (Japanese text)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, momokoe, momoko, momoko, momoko, momoko_state, empty_init, ROT0, "Jaleco", "Momoko 120% (English text)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, momokob, momoko, momoko, momoko, momoko_state, empty_init, ROT0, "bootleg", "Momoko 120% (bootleg)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/jaleco/momoko.h b/src/mame/jaleco/momoko.h
deleted file mode 100644
index 787f98a2776..00000000000
--- a/src/mame/jaleco/momoko.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Uki
-/*************************************************************************
-
- Momoko 120%
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_MOMOKO_H
-#define MAME_INCLUDES_MOMOKO_H
-
-#pragma once
-
-#include "emupal.h"
-
-class momoko_state : public driver_device
-{
-public:
- momoko_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_spriteram(*this, "spriteram"),
- m_videoram(*this, "videoram"),
- m_bg_scrolly(*this, "bg_scrolly"),
- m_bg_scrollx(*this, "bg_scrollx"),
- m_bg_gfx(*this, "bg_gfx"),
- m_bg_map(*this, "bg_map"),
- m_bg_col_map(*this, "bg_col_map"),
- m_fg_map(*this, "fg_map"),
- m_proms(*this, "proms"),
- m_bgbank(*this, "bgbank"),
- m_io_fake(*this, "FAKE"),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette")
- { }
-
- void momoko(machine_config &config);
-
-private:
- /* memory pointers */
- required_shared_ptr<u8> m_spriteram;
- required_shared_ptr<u8> m_videoram;
- required_shared_ptr<u8> m_bg_scrolly;
- required_shared_ptr<u8> m_bg_scrollx;
- required_region_ptr<u8> m_bg_gfx;
- required_region_ptr<u8> m_bg_map;
- required_region_ptr<u8> m_bg_col_map;
- required_region_ptr<u8> m_fg_map;
- required_region_ptr<u8> m_proms;
- required_memory_bank m_bgbank;
- required_ioport m_io_fake;
-
- /* video-related */
- u8 m_fg_scrollx = 0;
- u8 m_fg_scrolly = 0;
- u8 m_fg_select = 0;
- u8 m_text_scrolly = 0;
- u8 m_text_mode = 0;
- u8 m_bg_select = 0;
- u8 m_bg_priority = 0;
- u8 m_bg_mask = 0;
- u8 m_fg_mask = 0;
- u8 m_flipscreen = 0;
- void bg_read_bank_w(u8 data);
- void fg_scrollx_w(u8 data);
- void fg_scrolly_w(u8 data);
- void fg_select_w(u8 data);
- void text_scrolly_w(u8 data);
- void text_mode_w(u8 data);
- void bg_scrollx_w(offs_t offset, u8 data);
- void bg_scrolly_w(offs_t offset, u8 data);
- void bg_select_w(u8 data);
- void bg_priority_w(u8 data);
- void flipscreen_w(u8 data);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_bg_pri(bitmap_ind16 &bitmap, int chr, int col, int flipx, int flipy, int x, int y, int pri);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int start, int end, int flip);
- void draw_text_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip);
- void draw_fg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip);
- void draw_bg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip, bool high);
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- void momoko_map(address_map &map);
- void momoko_sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_MOMOKO_H
diff --git a/src/mame/jaleco/momoko_v.cpp b/src/mame/jaleco/momoko_v.cpp
deleted file mode 100644
index 1d319fc26fb..00000000000
--- a/src/mame/jaleco/momoko_v.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Uki
-/*******************************************************************************
-
- Momoko 120% (c) 1986 Jaleco
-
- Video hardware driver by Uki 02/Mar/2001
-
- Video consists of
- - Sprites
- - 2x ROM based tilemaps (bg and fg) with priority over some sprites
- - 1x RAM based tilemap (text layer) (no wrapping?)
-
- TODO:
- - update to use tilemap system?
- - check if any of this is common Jaleco/NMK etc. hardware and use shared
- devices if possible
-
-*******************************************************************************/
-
-#include "emu.h"
-#include "momoko.h"
-
-
-void momoko_state::fg_scrollx_w(u8 data)
-{
- m_fg_scrollx = data;
-}
-
-void momoko_state::fg_scrolly_w(u8 data)
-{
- m_fg_scrolly = data;
-}
-
-void momoko_state::fg_select_w(u8 data)
-{
- m_fg_select = data & 0x0f;
- m_fg_mask = data & 0x10;
-}
-
-void momoko_state::text_scrolly_w(u8 data)
-{
- m_text_scrolly = data;
-}
-
-void momoko_state::text_mode_w(u8 data)
-{
- m_text_mode = data;
-}
-
-void momoko_state::bg_scrollx_w(offs_t offset, u8 data)
-{
- m_bg_scrollx[offset] = data;
-}
-
-void momoko_state::bg_scrolly_w(offs_t offset, u8 data)
-{
- m_bg_scrolly[offset] = data;
-}
-
-void momoko_state::bg_select_w(u8 data)
-{
- m_bg_select = data & 0x0f;
- m_bg_mask = data & 0x10;
-}
-
-void momoko_state::bg_priority_w(u8 data)
-{
- m_bg_priority = data & 0x01;
-}
-
-void momoko_state::flipscreen_w(u8 data)
-{
- m_flipscreen = data & 0x01;
-}
-
-/****************************************************************************/
-
-void momoko_state::draw_bg_pri(bitmap_ind16 &bitmap, int chr, int col, int flipx, int flipy, int x, int y, int pri)
-{
- for (int sy = 0; sy < 8; sy++)
- {
- const u32 gfxadr = chr * 16 + sy * 2;
- for (int xx = 0; xx < 2; xx++)
- {
- u8 d0 = m_bg_gfx[gfxadr + xx * 4096];
- u8 d1 = m_bg_gfx[gfxadr + xx * 4096 + 1];
-
- for (int sx = 0; sx < 4; sx++)
- {
- const u8 dot = (d0 & 0x08) | ((d0 & 0x80) >> 5) | ((d1 & 0x08) >> 2) | ((d1 & 0x80) >> 7);
- const int px = (flipx == 0) ? (sx + xx * 4 + x) : (7 - sx - xx * 4 + x);
- const int py = (flipy == 0) ? (sy + y) : (7 - sy + y);
-
- if (dot >= pri)
- bitmap.pix(py, px) = col * 16 + dot + 256;
-
- d0 <<= 1;
- d1 <<= 1;
- }
- }
- }
-}
-
-
-void momoko_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int start, int end, int flip)
-{
- for (int offs = start; offs < end; offs += 4)
- {
- int px, py;
- u32 chr = m_spriteram[offs + 1] | ((m_spriteram[offs + 2] & 0x60) << 3);
- chr = ((chr & 0x380) << 1) | (chr & 0x7f);
- int col = m_spriteram[offs + 2] & 0x07;
- const int fx = ((m_spriteram[offs + 2] & 0x10) >> 4) ^ flip;
- const int fy = ((m_spriteram[offs + 2] & 0x08) >> 3) ^ flip; /* ??? */
- int x = m_spriteram[offs + 3];
- int y = m_spriteram[offs + 0];
-
- if (flip == 0)
- {
- px = x;
- py = 239 - y;
- }
- else
- {
- px = 248 - x;
- py = y + 1;
- }
- m_gfxdecode->gfx(3)->transpen(bitmap, cliprect,
- chr,
- col,
- !fx, fy,
- px, py, 0);
- }
-}
-
-void momoko_state::draw_text_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip)
-{
- for (int y = 16; y < 240; y++)
- {
- for (int x = 0; x < 32; x++)
- {
- int px, py, col;
- int sy = y;
- if (m_text_mode == 0)
- col = m_proms[(sy >> 3) + 0x100] & 0x0f;
- else
- {
- if (m_proms[y] < 0x08)
- sy += m_text_scrolly;
- col = (m_proms[y] & 0x07) + 0x10;
- }
- int dy = sy & 7;
- if (flip == 0)
- {
- px = x * 8;
- py = y;
- }
- else
- {
- px = 248 - x * 8;
- py = 255 - y;
- }
- int ramoffset = (sy >> 3) * 32 + x;
-
- if (ramoffset < 0x400) // high score table, no wrapping?
- m_gfxdecode->gfx(0)->transpen(bitmap, cliprect,
- m_videoram[ramoffset] * 8 + dy,
- col,
- flip, 0,
- px, py, 0);
- }
- }
-}
-
-void momoko_state::draw_fg_romtilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int flip)
-{
- int dx = (7 - m_fg_scrollx) & 7;
- int dy = (7 - m_fg_scrolly) & 7;
- int rx = m_fg_scrollx >> 3;
- int ry = m_fg_scrolly >> 3;
-
- for (int y = 0; y < 29; y++)
- {
- for (int x = 0; x < 32; x++)
- {
- int px, py;
- const int radr = ((ry + y + 34) & 0x3f) * 0x20 + ((rx + x) & 0x1f) + (m_fg_select & 3) * 0x800;
- const u32 chr = m_fg_map[radr];
- if (flip == 0)
- {
- px = 8 * x + dx - 6;
- py = 8 * y + dy + 9;
- }
- else
- {
- px = 248 - (8 * x + dx - 8);
- py = 248 - (8 * y + dy + 9);
- }
- m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
- chr,
- 0, /* color */
- flip,flip, /* flip */
- px,py,0);
- }
- }
-}
-
-void momoko_state::draw_bg_romtilemap(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int flip, bool high)
-{
- int dx = (7 - m_bg_scrollx[0]) & 7;
- int dy = (7 - m_bg_scrolly[0]) & 7;
- int rx = (m_bg_scrollx[0] + m_bg_scrollx[1] * 256) >> 3;
- int ry = (m_bg_scrolly[0] + m_bg_scrolly[1] * 256) >> 3;
-
- for (int y = 0; y < 29; y++)
- {
- for (int x = 0; x < 32; x++)
- {
- int px, py;
- const int radr = ((ry + y + 2) & 0x3ff) * 128 + ((rx + x) & 0x7f);
- u32 chr = m_bg_map[radr];
- int col = m_bg_col_map[chr + m_bg_select * 512 + m_bg_priority * 256];
- chr = chr + m_bg_select * 512;
-
- if (flip == 0)
- {
- px = 8 * x + dx - 6;
- py = 8 * y + dy + 9;
- }
- else
- {
- px = 248 - (8 * x + dx - 8);
- py = 248 - (8 * y + dy + 9);
- }
-
- if (!high)
- {
- m_gfxdecode->gfx(1)->opaque(bitmap,cliprect,
- chr,
- col,
- flip,flip,
- px,py);
- }
- else
- {
- const u8 pri = (col & 0x10) >> 1;
- if (pri != 0)
- {
- col = col & 0x0f;
- draw_bg_pri(bitmap, chr, col, flip, flip, px, py, pri);
- }
- }
- }
- }
-}
-
-/****************************************************************************/
-
-u32 momoko_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- const int flip = m_flipscreen ^ (m_io_fake->read() & 0x01);
-
- /* draw BG layer - all tiles */
-
- if (m_bg_mask == 0)
- draw_bg_romtilemap(screen, bitmap, cliprect, flip, false);
- else
- bitmap.fill(256, cliprect);
-
- /* draw sprites (momoko) */
- draw_sprites(screen, bitmap, cliprect, 0, 9 * 4, flip);
-
- /* draw BG layer - high priority tiles */
- if (m_bg_mask == 0)
- draw_bg_romtilemap(screen, bitmap, cliprect, flip, true);
-
- /* draw sprites (others) */
- draw_sprites(screen, bitmap, cliprect, 9*4, m_spriteram.bytes(), flip);
-
- /* draw text layer */
- draw_text_tilemap(screen, bitmap, cliprect, flip);
-
- /* draw FG layer */
- if (m_fg_mask == 0)
- draw_fg_romtilemap(screen, bitmap, cliprect, flip);
-
- return 0;
-}
diff --git a/src/mame/jaleco/skyfox.cpp b/src/mame/jaleco/skyfox.cpp
index eb453f8848a..b5bce3b0977 100644
--- a/src/mame/jaleco/skyfox.cpp
+++ b/src/mame/jaleco/skyfox.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Luca Elia
+// copyright-holders: Luca Elia
+
/***************************************************************************
-= Sky Fox / Exerizer =-
@@ -24,46 +25,325 @@ Verified Dip locations and recommended settings with manual
***************************************************************************/
#include "emu.h"
-#include "skyfox.h"
#include "cpu/z80/z80.h"
+#include "machine/gen_latch.h"
#include "sound/ymopn.h"
+#include "video/resnet.h"
+
+#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
+namespace {
+
+class skyfox_state : public driver_device
+{
+public:
+ skyfox_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_audiocpu(*this, "audiocpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_spriteram(*this, "spriteram"),
+ m_bgram(*this, "bgram"),
+ m_bgrom(*this, "tiles")
+ { }
+
+ void skyfox(machine_config &config);
+
+ void init_skyfox();
+
+ DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ // devices/memory pointers
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_audiocpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ required_shared_ptr<uint8_t> m_spriteram;
+ required_shared_ptr<uint8_t> m_bgram;
+ required_region_ptr<uint8_t> m_bgrom;
+
+ uint8_t m_bg_ctrl = 0;
+
+ void bg_ctrl_w(uint8_t data);
+ void palette(palette_device &palette) const;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
/***************************************************************************
- Main CPU
+
+ [ 1 Background ]
+
+ The stars in the background are not tile based (I think!) and
+ their rendering is entirely guesswork for now..
+
+ I draw a star for each horizontal line using 2 bytes in the
+ background ROM:
+
+ - the first byte seems a color / shape info
+ - the second byte seems a position info
+
+ The ROM holds 4 chunks of $2000 bytes. Most of the data does not
+ change between chunks, while the remaining part (which is rendered
+ to what seems a "milky way") pulsates in color and/or shape
+ to simulate the shimmering of stars (?!) if we draw one chunk only
+ and cycle through the four. Indeed, there's a register cycling
+ through 4 values.
+
+ Since the result kind of matches a screenshot we have, I feel the
+ drawn result is not that far from reality. On the other hand we
+ have a random arrangement of stars, so it's hard to tell for sure..
+
+ [ 256 Sprites ]
+
+ Sprites are 8 planes deep and can be 8x8, 16x16 or 32x32 pixels
+ in size. They are stored as 32x32x8 tiles in the ROMs.
+
+
+***************************************************************************/
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ There are three 256x4 palette PROMs (one per gun).
+ The palette PROMs are connected to the RGB output this way:
+
+ bit 3 -- 110 ohm resistor -- RED/GREEN/BLUE
+ -- 220 ohm resistor -- RED/GREEN/BLUE
+ -- 680 ohm resistor -- RED/GREEN/BLUE
+ bit 0 -- 1.2kohm resistor -- RED/GREEN/BLUE
+
+***************************************************************************/
+
+static constexpr res_net_decode_info decode_info =
+{
+ 1,
+ 0, 255, // start/end
+ // R, G, B,
+ { 0, 0x100, 0x200, }, // offsets
+ { 0, 0, 0, }, // shifts
+ { 0xf, 0xf, 0xf, } // masks
+};
+
+static constexpr res_net_info net_info =
+{
+ RES_NET_VCC_5V | RES_NET_VBIAS_5V | RES_NET_VIN_TTL_OUT,
+ {
+ { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } },
+ { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } },
+ { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } }
+ }
+};
+
+void skyfox_state::palette(palette_device &palette) const
+{
+ uint8_t const *const color_prom = memregion("proms")->base();
+ std::vector<rgb_t> rgb;
+
+ compute_res_net_all(rgb, color_prom, decode_info, net_info);
+ palette.set_pen_colors(0, rgb);
+}
+
+
+/***************************************************************************
+
+ Sprites Drawing
+
+Offset: Value:
+
+03 Code: selects one of the 32x32 tiles in the ROMs.
+ (Tiles $80-ff are bankswitched to cover $180 tiles)
+
+02 Code + Attr
+
+ 7654 ---- Code (low 4 bits)
+ 8x8 sprites use bits 7654 (since there are 16 8x8 tiles in the 32x32 one)
+ 16x16 sprites use bits --54 (since there are 4 16x16 tiles in the 32x32 one)
+ 32x32 sprites use no bits (since the 32x32 tile is already selected)
+
+ 7--- 3--- Size
+ 1--- 1--- : 32x32 sprites
+ 0--- 1--- : 16x16 sprites
+ 8x8 sprites otherwise
+
+ ---- -2-- Flip Y
+ ---- --1- Flip X
+ ---- ---0 X Low Bit
+
+00 Y
+
+01 X (High 8 Bits)
***************************************************************************/
-void skyfox_state::output_w(offs_t offset, uint8_t data)
+void skyfox_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- // TODO: untangle
- switch (offset)
+ gfx_element *gfx = m_gfxdecode->gfx(0);
+ int const width = m_screen->width();
+ int const height = m_screen->height();
+
+ // The 32x32 tiles in the 80-ff range are bankswitched
+ int const shift = (m_bg_ctrl & 0x80) ? (4 - 1) : 4;
+
+ for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
{
- case 0:
- m_bg_ctrl = data;
- break;
+ int code = m_spriteram[offs + 3] << 8 | m_spriteram[offs + 2];
+ int flipx = code & 0x2;
+ int flipy = code & 0x4;
+ int y = m_spriteram[offs + 0];
+ int x = m_spriteram[offs + 1] << 1 | (code & 1);
+
+ int const high_code = ((code >> 4) & 0x7f0) + ((code & 0x8000) >> shift);
+
+ int low_code, n;
+
+ switch (code & 0x88)
+ {
+ case 0x88: n = 4; low_code = 0; break;
+ case 0x08: n = 2; low_code = (code & 0x20) >> 2 | (code & 0x10) >> 3; break;
+ default: n = 1; low_code = (code >> 4) & 0xf; break;
+ }
+
+ if (m_bg_ctrl & 1) // flipscreen
+ {
+ x = width - x - n * 8;
+ y = height - y - n * 8;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ int xstart, ystart, xend, yend, xinc, yinc;
+
+ if (flipx) { xstart = n - 1; xend = -1; xinc = -1; }
+ else { xstart = 0; xend = n; xinc = +1; }
+
+ if (flipy) { ystart = n - 1; yend = -1; yinc = -1; }
+ else { ystart = 0; yend = n; yinc = +1; }
+
+
+ code = low_code + high_code;
+
+ for (int dy = ystart; dy != yend; dy += yinc)
+ {
+ for (int dx = xstart; dx != xend; dx += xinc, code++)
+ {
+ gfx->transpen(bitmap, cliprect, code, 0, flipx, flipy, dx * 8 + x, dy * 8 + y, 0xff);
+
+ // wraparound y - BTANB: large sprites exiting the screen sometimes reappear on the other edge
+ gfx->transpen(bitmap, cliprect, code, 0, flipx, flipy, dx * 8 + x, dy * 8 + y - 256, 0xff);
+ }
+
+ if (n == 2)
+ code += 2;
+ }
+ }
+}
+
+
+
+/***************************************************************************
+
+ Background Rendering
+
+***************************************************************************/
+
+void skyfox_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // Blinking stops until the first star moves after turning on the power
+ bool const blinking = (m_bg_ctrl & 0x8);
+ /* Star pattern change. This will change when all star clusters go out of screen or when the player restarts.
+ When it changes, it will change color of the star clusters. */
+ int const pattern = (m_bg_ctrl & 0x6) >> 1;
- case 1:
- m_soundlatch->write(data);
- break;
+ for (int i = 0; i < 0x1000; i++)
+ {
+ // contains the position of stars from 0xd4e0 in RAM
+ int const ramoffset = 0xe0 + (i & 0xf) * 2;
+ int const pos = m_bgram[ramoffset + 1] * 2 + ((m_bgram[ramoffset] & 0x80) ? 1 : 0);
+
+ // ROM offset of star pattern
+ int const offs = (i * 2) % 0x2000 + pattern * 0x2000;
+
+ /* Adjusted with 1 pixel accuracy compared to PCB.
+ Confirmed that pixel and color pattern match in the "1UP START" screen. */
+ int const pen = m_bgrom[offs];
+ int const x = m_bgrom[offs + 1] * 2 + pos + 0x5b;
+ int const y = (i >> 4) + 1;
+
+ /* When flipscreen is enabled, scroll direction is flipped by only in-game subroutine.
+ This PCB does not seem to support background flip. */
+
+ /* This looks perfect at first glance.
+ but when strict compared on "1UP START" screen,
+ it seems the blinking pattern in each star may be different. */
+ if (((m_bg_ctrl >> 4) & 3) != (pen & 3) || !blinking)
+ bitmap.pix(y % 256, x % 512) = pen;
}
}
-void skyfox_state::skyfox_map(address_map &map)
+
+/***************************************************************************
+
+ Screen Drawing
+
+***************************************************************************/
+
+uint32_t skyfox_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(0xff, cliprect); // the bg is black
+ draw_background(bitmap, cliprect);
+ draw_sprites(bitmap, cliprect);
+ return 0;
+}
+
+
+// machine
+
+/***************************************************************************
+
+ Main CPU
+
+***************************************************************************/
+
+void skyfox_state::bg_ctrl_w(uint8_t data)
+{
+ m_bg_ctrl = data;
+}
+
+void skyfox_state::main_map(address_map &map)
{
map(0x0000, 0xbfff).rom();
map(0xc000, 0xcfff).ram();
- map(0xd000, 0xd3ff).ram().share("spriteram");
- map(0xd400, 0xd4ff).ram().share("bgram"); // For background stars
+ map(0xd000, 0xd3ff).ram().share(m_spriteram);
+ map(0xd400, 0xd4ff).ram().share(m_bgram); // For background stars
// TODO: verify if A11 is unconnected
map(0xd500, 0xdfff).ram();
map(0xe000, 0xe000).portr("INPUTS");
map(0xe001, 0xe001).portr("DSW0");
map(0xe002, 0xe002).portr("DSW1");
- map(0xe008, 0xe009).w(FUNC(skyfox_state::output_w));
+ map(0xe008, 0xe008).w(FUNC(skyfox_state::bg_ctrl_w));
+ map(0xe009, 0xe009).w("soundlatch", FUNC(generic_latch_8_device::write));
// map(0xe00a, 0xe00e) // POST only?
map(0xe00f, 0xe00f).nopw(); // DMA trigger
map(0xf001, 0xf001).portr("DSW2");
@@ -76,7 +356,7 @@ void skyfox_state::skyfox_map(address_map &map)
***************************************************************************/
-void skyfox_state::skyfox_sound_map(address_map &map)
+void skyfox_state::sound_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram();
@@ -84,7 +364,7 @@ void skyfox_state::skyfox_sound_map(address_map &map)
map(0xa000, 0xa001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write));
// map(0xb000, 0xb001).nopw(); // ??
map(0xc000, 0xc001).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write));
- map(0xb000, 0xb000).r(m_soundlatch, FUNC(generic_latch_8_device::read));
+ map(0xb000, 0xb000).r("soundlatch", FUNC(generic_latch_8_device::read));
}
@@ -146,7 +426,7 @@ static INPUT_PORTS_START( skyfox )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
- /* According to manual, there is also "SW2:4" which has to be always OFF */
+ // According to manual, there is also "SW2:4" which has to be always OFF
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -169,8 +449,8 @@ static INPUT_PORTS_START( skyfox )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("COINS") // Fake input port, coins are directly connected on NMI line
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, skyfox_state,coin_inserted, 0)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, skyfox_state,coin_inserted, 0)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, skyfox_state, coin_inserted, 0)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, skyfox_state, coin_inserted, 0)
INPUT_PORTS_END
@@ -187,7 +467,7 @@ INPUT_PORTS_END
support 8x8, 16x16 and 32x32 sprites. */
static GFXDECODE_START( gfx_skyfox )
- GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x8_raw, 0, 1 ) // [0] Sprites
+ GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x8_raw, 0, 1 )
GFXDECODE_END
@@ -209,35 +489,35 @@ void skyfox_state::machine_reset()
void skyfox_state::skyfox(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, XTAL(8'000'000)/2); /* Verified at 4MHz */
- m_maincpu->set_addrmap(AS_PROGRAM, &skyfox_state::skyfox_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, XTAL(8'000'000) / 2); // Verified at 4MHz
+ m_maincpu->set_addrmap(AS_PROGRAM, &skyfox_state::main_map);
// IM0, never enables ei opcode
- Z80(config, m_audiocpu, XTAL(14'318'181)/8); /* Verified at 1.789772MHz */
- m_audiocpu->set_addrmap(AS_PROGRAM, &skyfox_state::skyfox_sound_map);
+ Z80(config, m_audiocpu, XTAL(14'318'181) / 8); // Verified at 1.789772MHz
+ m_audiocpu->set_addrmap(AS_PROGRAM, &skyfox_state::sound_map);
- /* video hardware */
+ // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
// TODO: legacy screen configuration with no vblank irq
m_screen->set_refresh_hz(62.65);
- m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
+ m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
m_screen->set_size(512, 256);
m_screen->set_visarea(0+0x60, 320-1+0x60, 0+16, 256-1-16); // from $30*2 to $CC*2+8
- m_screen->set_screen_update(FUNC(skyfox_state::screen_update_skyfox));
+ m_screen->set_screen_update(FUNC(skyfox_state::screen_update));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_skyfox);
- PALETTE(config, m_palette, FUNC(skyfox_state::skyfox_palette), 256); // 256 static colors
+ PALETTE(config, m_palette, FUNC(skyfox_state::palette), 256); // 256 static colors
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
- GENERIC_LATCH_8(config, m_soundlatch);
+ GENERIC_LATCH_8(config, "soundlatch");
- YM2203(config, "ym1", XTAL(14'318'181)/8).add_route(ALL_OUTPUTS, "mono", 0.80); /* Verified at 1.789772MHz */
+ YM2203(config, "ym1", XTAL(14'318'181) / 8).add_route(ALL_OUTPUTS, "mono", 0.80); // Verified at 1.789772MHz
- YM2203(config, "ym2", XTAL(14'318'181)/8).add_route(ALL_OUTPUTS, "mono", 0.80); /* Verified at 1.789772MHz */
+ YM2203(config, "ym2", XTAL(14'318'181) / 8).add_route(ALL_OUTPUTS, "mono", 0.80); // Verified at 1.789772MHz
}
@@ -308,14 +588,14 @@ Video Board: Jaleco made in japan ER-8737
ROM_START( skyfox )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* Main Z80 Code */
+ ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code
ROM_LOAD( "skyfox1.bin", 0x00000, 0x8000, CRC(b4d4bb6f) SHA1(ed1cf6d91ca7170cb7d1c80b586c11164430fd49) )
ROM_LOAD( "skyfox2.bin", 0x08000, 0x8000, CRC(e15e0263) SHA1(005934327834aed46b17161aef82117ee508e9c4) ) // identical halves
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* Sound Z80 Code */
+ ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code
ROM_LOAD( "skyfox9.bin", 0x00000, 0x8000, CRC(0b283bf5) SHA1(5b14d0beea689ee7e9174017e5a127435df4fbe3) )
- ROM_REGION( 0x60000, "gfx1", 0 ) /* Sprites */
+ ROM_REGION( 0x60000, "sprites", 0 )
ROM_LOAD( "skyfox3.bin", 0x00000, 0x10000, CRC(3a17a929) SHA1(973fb36af416161e04a83d7869819d9b13df18cd) )
ROM_LOAD( "skyfox4.bin", 0x10000, 0x10000, CRC(358053bb) SHA1(589e3270eda0d44e73fbc7ac06e782f332920b39) )
ROM_LOAD( "skyfox5.bin", 0x20000, 0x10000, CRC(c1215a6e) SHA1(5ca30be8a68ac6a00907cc9e47ede0acec980f46) )
@@ -323,24 +603,24 @@ ROM_START( skyfox )
ROM_LOAD( "skyfox7.bin", 0x40000, 0x10000, CRC(fa2ab5b4) SHA1(c0878b25dae28f7d49e14376ff885d1d4e3d5dfe) )
ROM_LOAD( "skyfox8.bin", 0x50000, 0x10000, CRC(0e3edc49) SHA1(3d1c59ecaabe1c9517203b7e814db41d5cff0cd4) )
- ROM_REGION( 0x08000, "gfx2", 0 ) /* Background */
+ ROM_REGION( 0x08000, "tiles", 0 )
ROM_LOAD( "skyfox10.bin", 0x0000, 0x8000, CRC(19f58f9c) SHA1(6887216243b47152129448cbb4c7d52309feed03) )
- ROM_REGION( 0x300, "proms", 0 ) /* Color Proms */
+ ROM_REGION( 0x300, "proms", 0 ) // colors
ROM_LOAD( "sfoxrprm.bin", 0x000, 0x100, CRC(79913c7f) SHA1(e64e6a3eb55f37984cb2597c8ffba6bc3bad49c7) ) // R
ROM_LOAD( "sfoxgprm.bin", 0x100, 0x100, CRC(fb73d434) SHA1(4a9bd61fbdce9441753c5921f95ead5c4655957e) ) // G
ROM_LOAD( "sfoxbprm.bin", 0x200, 0x100, CRC(60d2ab41) SHA1(e58a54f2aaee5c07136d5437e513d61fb18fbd9f) ) // B
ROM_END
ROM_START( exerizer )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* Main Z80 Code */
+ ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code
ROM_LOAD( "1.2v", 0x00000, 0x8000, CRC(5df72a5d) SHA1(ca35ac06f3702fd650a584da2f442fbc61c00fce) )
ROM_LOAD( "2.3v", 0x08000, 0x8000, CRC(e15e0263) SHA1(005934327834aed46b17161aef82117ee508e9c4) ) // 1-b
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* Sound Z80 Code */
+ ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code
ROM_LOAD( "9.5n", 0x00000, 0x8000, CRC(0b283bf5) SHA1(5b14d0beea689ee7e9174017e5a127435df4fbe3) ) // 1-i
- ROM_REGION( 0x60000, "gfx1", 0 ) /* Sprites */
+ ROM_REGION( 0x60000, "sprites", 0 )
ROM_LOAD( "3-1.7w", 0x00000, 0x10000, CRC(3a17a929) SHA1(973fb36af416161e04a83d7869819d9b13df18cd) )
ROM_LOAD( "4.7u", 0x10000, 0x10000, CRC(358053bb) SHA1(589e3270eda0d44e73fbc7ac06e782f332920b39) ) // 1-d
ROM_LOAD( "5-1.7t", 0x20000, 0x10000, CRC(c1215a6e) SHA1(5ca30be8a68ac6a00907cc9e47ede0acec980f46) )
@@ -348,24 +628,24 @@ ROM_START( exerizer )
ROM_LOAD( "7.7p", 0x40000, 0x10000, CRC(c9bbfe5c) SHA1(ce3f7d32baa8bb0bfc110877b5b5f4648ee959ac) )
ROM_LOAD( "8.7n", 0x50000, 0x10000, CRC(0e3edc49) SHA1(3d1c59ecaabe1c9517203b7e814db41d5cff0cd4) ) // 1-h
- ROM_REGION( 0x08000, "gfx2", 0 ) /* Background */
+ ROM_REGION( 0x08000, "tiles", 0 )
ROM_LOAD( "10.5e", 0x0000, 0x8000, CRC(19f58f9c) SHA1(6887216243b47152129448cbb4c7d52309feed03) ) // 1-j
- ROM_REGION( 0x300, "proms", 0 ) /* Color Proms */
+ ROM_REGION( 0x300, "proms", 0 ) // colors
ROM_LOAD( "r.1c", 0x000, 0x100, CRC(79913c7f) SHA1(e64e6a3eb55f37984cb2597c8ffba6bc3bad49c7) ) // 2-bpr
ROM_LOAD( "g.1b", 0x100, 0x100, CRC(fb73d434) SHA1(4a9bd61fbdce9441753c5921f95ead5c4655957e) ) // 3-bpr
ROM_LOAD( "b.1d", 0x200, 0x100, CRC(60d2ab41) SHA1(e58a54f2aaee5c07136d5437e513d61fb18fbd9f) ) // 1-bpr
ROM_END
ROM_START( exerizerb )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* Main Z80 Code */
+ ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code
ROM_LOAD( "1-a", 0x00000, 0x8000, CRC(5df72a5d) SHA1(ca35ac06f3702fd650a584da2f442fbc61c00fce) )
ROM_LOAD( "skyfox2.bin", 0x08000, 0x8000, CRC(e15e0263) SHA1(005934327834aed46b17161aef82117ee508e9c4) ) // 1-b
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* Sound Z80 Code */
+ ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code
ROM_LOAD( "skyfox9.bin", 0x00000, 0x8000, CRC(0b283bf5) SHA1(5b14d0beea689ee7e9174017e5a127435df4fbe3) ) // 1-i
- ROM_REGION( 0x60000, "gfx1", 0 ) /* Sprites */
+ ROM_REGION( 0x60000, "sprites", 0 )
ROM_LOAD( "1-c", 0x00000, 0x10000, CRC(450e9381) SHA1(f99b2ca73f1e4ba91b8066bb6d28d33b66a3ee81) )
ROM_LOAD( "skyfox4.bin", 0x10000, 0x10000, CRC(358053bb) SHA1(589e3270eda0d44e73fbc7ac06e782f332920b39) ) // 1-d
ROM_LOAD( "1-e", 0x20000, 0x10000, CRC(50a38c60) SHA1(a4b8d530914d6c85b15940a7821b4365068de668) )
@@ -373,21 +653,21 @@ ROM_START( exerizerb )
ROM_LOAD( "1-g", 0x40000, 0x10000, CRC(c9bbfe5c) SHA1(ce3f7d32baa8bb0bfc110877b5b5f4648ee959ac) )
ROM_LOAD( "skyfox8.bin", 0x50000, 0x10000, CRC(0e3edc49) SHA1(3d1c59ecaabe1c9517203b7e814db41d5cff0cd4) ) // 1-h
- ROM_REGION( 0x08000, "gfx2", 0 ) /* Background */
+ ROM_REGION( 0x08000, "tiles", 0 )
ROM_LOAD( "skyfox10.bin", 0x0000, 0x8000, CRC(19f58f9c) SHA1(6887216243b47152129448cbb4c7d52309feed03) ) // 1-j
- ROM_REGION( 0x300, "proms", 0 ) /* Color Proms */
+ ROM_REGION( 0x300, "proms", 0 ) // colors
ROM_LOAD( "sfoxrprm.bin", 0x000, 0x100, CRC(79913c7f) SHA1(e64e6a3eb55f37984cb2597c8ffba6bc3bad49c7) ) // 2-bpr
ROM_LOAD( "sfoxgprm.bin", 0x100, 0x100, CRC(fb73d434) SHA1(4a9bd61fbdce9441753c5921f95ead5c4655957e) ) // 3-bpr
ROM_LOAD( "sfoxbprm.bin", 0x200, 0x100, CRC(60d2ab41) SHA1(e58a54f2aaee5c07136d5437e513d61fb18fbd9f) ) // 1-bpr
ROM_END
-/* Untangle the graphics: cut each 32x32x8 tile in 16 8x8x8 tiles */
+// Untangle the graphics: cut each 32x32x8 tile in 16 8x8x8 tiles
void skyfox_state::init_skyfox()
{
- uint8_t *rom = memregion("gfx1")->base();
- uint8_t *end = rom + memregion("gfx1")->bytes();
+ uint8_t *rom = memregion("sprites")->base();
+ uint8_t *end = rom + memregion("sprites")->bytes();
uint8_t buf[32 * 32];
while (rom < end)
@@ -400,7 +680,9 @@ void skyfox_state::init_skyfox()
}
}
+} // anonymous namespace
+
-GAME( 1987, skyfox, 0, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "Jaleco (Nichibutsu USA license)", "Sky Fox", MACHINE_SUPPORTS_SAVE )
-GAME( 1987, exerizer, skyfox, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "Jaleco", "Exerizer (Japan)", MACHINE_SUPPORTS_SAVE )
-GAME( 1987, exerizerb, skyfox, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "bootleg", "Exerizer (bootleg)", MACHINE_SUPPORTS_SAVE )
+GAME( 1987, skyfox, 0, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "Jaleco (Nichibutsu USA license)", "Sky Fox", MACHINE_SUPPORTS_SAVE )
+GAME( 1987, exerizer, skyfox, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "Jaleco", "Exerizer (Japan)", MACHINE_SUPPORTS_SAVE )
+GAME( 1987, exerizerb, skyfox, skyfox, skyfox, skyfox_state, init_skyfox, ROT90, "bootleg", "Exerizer (bootleg)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/jaleco/skyfox.h b/src/mame/jaleco/skyfox.h
deleted file mode 100644
index 234a31eb31f..00000000000
--- a/src/mame/jaleco/skyfox.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Luca Elia
-/*************************************************************************
-
- Skyfox
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_SKYFOX_H
-#define MAME_INCLUDES_SKYFOX_H
-
-#pragma once
-
-#include "machine/gen_latch.h"
-#include "emupal.h"
-#include "screen.h"
-
-class skyfox_state : public driver_device
-{
-public:
- skyfox_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_audiocpu(*this, "audiocpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_screen(*this, "screen"),
- m_palette(*this, "palette"),
- m_soundlatch(*this, "soundlatch"),
- m_spriteram(*this, "spriteram"),
- m_bgram(*this, "bgram")
- { }
-
- void skyfox(machine_config &config);
-
- void init_skyfox();
-
- DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
-
-private:
- /* devices/memory pointers */
- required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_audiocpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
- required_device<generic_latch_8_device> m_soundlatch;
- required_shared_ptr<uint8_t> m_spriteram;
- required_shared_ptr<uint8_t> m_bgram;
-
- int m_bg_ctrl = 0;
-
- void output_w(offs_t offset, uint8_t data);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- void skyfox_palette(palette_device &palette) const;
- uint32_t screen_update_skyfox(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
- void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void skyfox_map(address_map &map);
- void skyfox_sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_SKYFOX_H
diff --git a/src/mame/jaleco/skyfox_v.cpp b/src/mame/jaleco/skyfox_v.cpp
deleted file mode 100644
index 22c10647343..00000000000
--- a/src/mame/jaleco/skyfox_v.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Luca Elia
-/***************************************************************************
-
- -= Sky Fox / Exerizer =-
-
- driver by Luca Elia (l.elia@tin.it)
-
-
- [ 1 Background ]
-
- The stars in the background are not tile based (I think!) and
- their rendering is entirely guesswork for now..
-
- I draw a star for each horizontal line using 2 bytes in the
- background rom:
-
- - the first byte seems a color / shape info
- - the second byte seems a position info
-
- The rom holds 4 chunks of $2000 bytes. Most of the data does not
- change between chunks, while the remaining part (which is rendered
- to what seems a "milky way") pulsates in color and/or shape
- to simulate the shimmering of stars (?!) if we draw one chunk only
- and cycle through the four. Indeed, there's a register cycling
- through 4 values.
-
- Since the result kind of matches a screenshot we have, I feel the
- drawn result is not that far from reality. On the other hand we
- have a random arrangement of stars, so it's hard to tell for sure..
-
- [ 256 Sprites ]
-
- Sprites are 8 planes deep and can be 8x8, 16x16 or 32x32 pixels
- in size. They are stored as 32x32x8 tiles in the ROMs.
-
-
-***************************************************************************/
-
-#include "emu.h"
-#include "video/resnet.h"
-#include "skyfox.h"
-
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- There are three 256x4 palette PROMs (one per gun).
- The palette PROMs are connected to the RGB output this way:
-
- bit 3 -- 110 ohm resistor -- RED/GREEN/BLUE
- -- 220 ohm resistor -- RED/GREEN/BLUE
- -- 680 ohm resistor -- RED/GREEN/BLUE
- bit 0 -- 1.2kohm resistor -- RED/GREEN/BLUE
-
-***************************************************************************/
-
-static constexpr res_net_decode_info skyfox_decode_info =
-{
- 1,
- 0, 255, // start/end
- // R, G, B,
- { 0, 0x100, 0x200, }, // offsets
- { 0, 0, 0, }, // shifts
- { 0xf, 0xf, 0xf, } // masks
-};
-
-static constexpr res_net_info skyfox_net_info =
-{
- RES_NET_VCC_5V | RES_NET_VBIAS_5V | RES_NET_VIN_TTL_OUT,
- {
- { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } },
- { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } },
- { RES_NET_AMP_NONE, 0, 0, 4, { 1200, 680, 220, 110 } }
- }
-};
-
-void skyfox_state::skyfox_palette(palette_device &palette) const
-{
- uint8_t const *const color_prom = memregion("proms")->base();
- std::vector<rgb_t> rgb;
-
- compute_res_net_all(rgb, color_prom, skyfox_decode_info, skyfox_net_info);
- palette.set_pen_colors(0, rgb);
-}
-
-
-/***************************************************************************
-
- Sprites Drawing
-
-Offset: Value:
-
-03 Code: selects one of the 32x32 tiles in the ROMs.
- (Tiles $80-ff are bankswitched to cover $180 tiles)
-
-02 Code + Attr
-
- 7654 ---- Code (low 4 bits)
- 8x8 sprites use bits 7654 (since there are 16 8x8 tiles in the 32x32 one)
- 16x16 sprites use bits --54 (since there are 4 16x16 tiles in the 32x32 one)
- 32x32 sprites use no bits (since the 32x32 tile is already selected)
-
- 7--- 3--- Size
- 1--- 1--- : 32x32 sprites
- 0--- 1--- : 16x16 sprites
- 8x8 sprites otherwise
-
- ---- -2-- Flip Y
- ---- --1- Flip X
- ---- ---0 X Low Bit
-
-00 Y
-
-01 X (High 8 Bits)
-
-***************************************************************************/
-
-void skyfox_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- gfx_element *gfx = m_gfxdecode->gfx(0);
- int width = m_screen->width();
- int height = m_screen->height();
-
- /* The 32x32 tiles in the 80-ff range are bankswitched */
- int shift = (m_bg_ctrl & 0x80) ? (4 - 1) : 4;
-
- for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
- {
- int xstart, ystart, xend, yend;
- int xinc, yinc, dx, dy;
- int low_code, high_code, n;
-
- int code = m_spriteram[offs + 3] << 8 | m_spriteram[offs + 2];
- int flipx = code & 0x2;
- int flipy = code & 0x4;
- int y = m_spriteram[offs + 0];
- int x = m_spriteram[offs + 1] << 1 | (code & 1);
-
- high_code = ((code >> 4) & 0x7f0) + ((code & 0x8000) >> shift);
-
- switch (code & 0x88)
- {
- case 0x88: n = 4; low_code = 0; break;
- case 0x08: n = 2; low_code = (code & 0x20) >> 2 | (code & 0x10) >> 3; break;
- default: n = 1; low_code = (code >> 4) & 0xf; break;
- }
-
- if (m_bg_ctrl & 1) // flipscreen
- {
- x = width - x - n * 8;
- y = height - y - n * 8;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- if (flipx) { xstart = n - 1; xend = -1; xinc = -1; }
- else { xstart = 0; xend = n; xinc = +1; }
-
- if (flipy) { ystart = n - 1; yend = -1; yinc = -1; }
- else { ystart = 0; yend = n; yinc = +1; }
-
-
- code = low_code + high_code;
-
- for (dy = ystart; dy != yend; dy += yinc)
- {
- for (dx = xstart; dx != xend; dx += xinc, code++)
- {
- gfx->transpen(bitmap, cliprect, code, 0, flipx, flipy, dx*8 + x, dy*8 + y, 0xff);
-
- // wraparound y - BTANB: large sprites exiting the screen sometimes reappear on the other edge
- gfx->transpen(bitmap, cliprect, code, 0, flipx, flipy, dx*8 + x, dy*8 + y - 256, 0xff);
- }
-
- if (n == 2)
- code += 2;
- }
- }
-}
-
-
-
-/***************************************************************************
-
- Background Rendering
-
-***************************************************************************/
-
-void skyfox_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- uint8_t *rom = memregion("gfx2")->base();
-
- /* Blinking stops until the first star moves after turning on the power */
- bool blinking = (m_bg_ctrl & 0x8);
- /* Star pattern change. This will change at when all star clusters to out of screen or when player restart.
- When it changes, will change color of star clusters. */
- int pattern = (m_bg_ctrl & 0x6) >> 1;
-
- for (int i = 0; i < 0x1000; i++)
- {
- /* contains the position of stars from 0xd4e0 in RAM */
- int ramoffset = 0xe0 + (i & 0xf) * 2;
- int pos = m_bgram[ramoffset + 1] * 2 + ((m_bgram[ramoffset] & 0x80) ? 1 : 0);
-
- /* ROM offset of star pattern */
- int offs = (i * 2) % 0x2000 + pattern * 0x2000;
-
- /* Adjusted with 1 pixel accuracy compared to PCB.
- Confirmed that pixel and color pattern match in the "1UP START" screen. */
- int pen = rom[offs];
- int x = rom[offs + 1] * 2 + pos + 0x5b;
- int y = (i >> 4) + 1;
-
- /* When flipscreen is enabled, scroll direction is flipped by only in-game subroutine.
- This PCB seems does not support background flip. */
-
- /* This looks perfect at first glance.
- but when strict compared on "1UP START" screen,
- it seems the blinking pattern in each star may be different. */
- if (((m_bg_ctrl >> 4) & 3) != (pen & 3) || !blinking)
- bitmap.pix(y % 256, x % 512) = pen;
- }
-}
-
-
-/***************************************************************************
-
- Screen Drawing
-
-***************************************************************************/
-
-uint32_t skyfox_state::screen_update_skyfox(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- bitmap.fill(0xff, cliprect); // the bg is black
- draw_background(bitmap, cliprect);
- draw_sprites(bitmap, cliprect);
- return 0;
-}
diff --git a/src/mame/omori/battlex.cpp b/src/mame/omori/battlex.cpp
index a2f77aae534..d096fb7e779 100644
--- a/src/mame/omori/battlex.cpp
+++ b/src/mame/omori/battlex.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:David Haywood
+// copyright-holders: David Haywood
+
/***************************************************************************
Omori Battle Cross
@@ -12,7 +13,7 @@
Its effect is the following :
* you need to insert at least one credit and start a game
* when the game is over, you can start another games WITHOUT
- inserting another coins
+ inserting another coin
Note that the number of credits is decremented though.
Credits are BCD coded on 3 bytes (0x000000-0x999999) at addresses
0xa039 (LSB), 0xa03a and 0xa03b (MSB), but only the LSB is displayed.
@@ -25,7 +26,7 @@
Each 8x8 BG tile is defined by:
- 1 bit 8x8 mask (one tile - 8 consecutive bytes - user2 region)
- - 4+4 bits of color ( one tile - 8 consecutive bytes - user1 region)
+ - 4+4 bits of color (one tile - 8 consecutive bytes - user1 region)
- bit 3 of color = brightness ?
Single mask byte defines one row of tile pixels (FG or BG)
@@ -57,13 +58,13 @@
- missing starfield
- - game speed, its seems to be controlled by the IRQ's, how fast should it
- be? firing seems frustratingly inconsistant (better with PORT_IMPULSE)
+ - game speed, it seems to be controlled by the IRQ's, how fast should it
+ be? firing seems frustratingly inconsistent (better with PORT_IMPULSE)
- - BG tilemap palette bits (in most cases paltte 0 is used,
- only highlights ( battlex logo, hiscore table) uses different palettes(?).
+ - BG tilemap palette bits (in most cases palette 0 is used,
+ only highlights (battlex logo, hiscore table) use different palettes(?).
Current implementation gives different highlight colors than on real
- hardware (i.e. battlex logo should have yellow highights)
+ hardware (i.e. battlex logo should have yellow highlights)
****************************************************************************
@@ -82,21 +83,215 @@
#include "emu.h"
-#include "battlex.h"
#include "cpu/z80/z80.h"
#include "sound/ay8910.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+namespace {
+
+class battlex_state : public driver_device
+{
+public:
+ battlex_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_videoram(*this, "videoram"),
+ m_spriteram(*this, "spriteram")
+ { }
+
+ void init_battlex();
+
+ void battlex(machine_config &config);
+
+ DECLARE_CUSTOM_INPUT_MEMBER(in0_b4_r);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ // memory pointers
+ required_shared_ptr<uint8_t> m_videoram;
+ required_shared_ptr<uint8_t> m_spriteram;
+
+ tilemap_t *m_bg_tilemap = nullptr;
+
+ void io_map(address_map &map);
+
+private:
+ // video-related
+ uint8_t m_scroll_lsb = 0U;
+ uint8_t m_scroll_msb = 0U;
+ uint8_t m_starfield_enabled = 0U;
+
+ uint8_t m_in0_b4 = 0U;
+
+ void palette_w(offs_t offset, uint8_t data);
+ void scroll_x_lsb_w(uint8_t data);
+ void scroll_x_msb_w(uint8_t data);
+ void scroll_starfield_w(uint8_t data);
+ void videoram_w(offs_t offset, uint8_t data);
+ void flipscreen_w(uint8_t data);
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(interrupt);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void main_map(address_map &map);
+};
+
+class dodgeman_state : public battlex_state
+{
+public:
+ using battlex_state::battlex_state;
+
+ void dodgeman(machine_config &config);
+
+protected:
+ virtual void video_start() override;
+
+private:
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+
+ void io_map(address_map &map);
+};
+
+// video
+
+void battlex_state::palette_w(offs_t offset, uint8_t data)
+{
+ int const palette_num = offset / 8;
+ int const color_num = offset & 7;
+
+ m_palette->set_pen_color(offset, pal1bit(data >> 0), pal1bit(data >> 2), pal1bit(data >> 1));
+ // set darker colors
+ m_palette->set_pen_color(64 + palette_num * 16 + color_num, pal1bit(data >> 0), pal1bit(data >> 2), pal1bit(data >> 1));
+ m_palette->set_pen_color(64 + palette_num * 16 + color_num + 8, pal2bit((data >> 0) & 1), pal2bit((data >> 2) & 1), pal2bit((data >> 1) & 1));
+}
+
+void battlex_state::scroll_x_lsb_w(uint8_t data)
+{
+ m_scroll_lsb = data;
+}
+
+void battlex_state::scroll_x_msb_w(uint8_t data)
+{
+ m_scroll_msb = data;
+}
+
+void battlex_state::scroll_starfield_w(uint8_t data)
+{
+}
+
+void battlex_state::videoram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[offset] = data;
+ m_bg_tilemap->mark_tile_dirty(offset / 2);
+}
+
+void battlex_state::flipscreen_w(uint8_t data)
+{
+ m_starfield_enabled = data & 0x10;
+
+ if (flip_screen() != (data >> 7))
+ {
+ flip_screen_set(data & 0x80);
+ machine().tilemap().mark_all_dirty();
+ }
+}
+
+
+TILE_GET_INFO_MEMBER(battlex_state::get_bg_tile_info)
+{
+ int const tile = m_videoram[tile_index * 2] | (((m_videoram[tile_index * 2 + 1] & 0x01)) << 8);
+ int const color = (m_videoram[tile_index * 2 + 1] & 0x0e) >> 1; // high bits unused
+
+ tileinfo.set(0, tile, color, 0);
+}
+
+TILE_GET_INFO_MEMBER(dodgeman_state::get_bg_tile_info)
+{
+ int const tile = m_videoram[tile_index * 2] | (((m_videoram[tile_index * 2 + 1] & 0x03)) << 8);
+ int const color = (m_videoram[tile_index * 2 + 1] & 0x0c) >> 2; // high bits unused
+ tileinfo.set(0, tile, color, 0);
+}
-INTERRUPT_GEN_MEMBER(battlex_state::battlex_interrupt)
+void battlex_state::video_start()
+{
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(battlex_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
+}
+
+void dodgeman_state::video_start()
+{
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dodgeman_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
+}
+
+void battlex_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ gfx_element *gfx = m_gfxdecode->gfx(1);
+ uint8_t const *source = m_spriteram;
+ uint8_t const *finish = m_spriteram + 0x200;
+
+ while (source < finish)
+ {
+ int sx = (source[0] & 0x7f) * 2 - (source[0] & 0x80) * 2;
+ int sy = source[3];
+ int const tile = source[2] ; // dodgeman has 0x100 sprites
+ int const color = source[1] & 0x07; // bits 3, 4, 5 also used during explosions
+ int flipy = source[1] & 0x80;
+ int flipx = source[1] & 0x40;
+
+ if (flip_screen())
+ {
+ sx = 240 - sx;
+ sy = 240 - sy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ gfx->transpen(bitmap, cliprect, tile, color, flipx, flipy, sx, sy, 0);
+ source += 4;
+ }
+
+}
+
+uint32_t battlex_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (!flip_screen())
+ m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 8));
+ else
+ m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 3));
+
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+
+ return 0;
+}
+
+
+// machine
+
+INTERRUPT_GEN_MEMBER(battlex_state::interrupt)
{
m_in0_b4 = 1;
device.execute().set_input_line(0, ASSERT_LINE);
}
-CUSTOM_INPUT_MEMBER(battlex_state::battlex_in0_b4_r)
+CUSTOM_INPUT_MEMBER(battlex_state::in0_b4_r)
{
uint32_t ret = m_in0_b4;
if (m_in0_b4)
@@ -115,13 +310,13 @@ CUSTOM_INPUT_MEMBER(battlex_state::battlex_in0_b4_r)
*
*************************************/
-void battlex_state::battlex_map(address_map &map)
+void battlex_state::main_map(address_map &map)
{
map(0x0000, 0x5fff).rom();
- map(0x8000, 0x8fff).ram().w(FUNC(battlex_state::battlex_videoram_w)).share("videoram");
- map(0x9000, 0x91ff).ram().share("spriteram");
+ map(0x8000, 0x8fff).ram().w(FUNC(battlex_state::videoram_w)).share(m_videoram);
+ map(0x9000, 0x91ff).ram().share(m_spriteram);
map(0xa000, 0xa3ff).ram();
- map(0xe000, 0xe03f).ram().w(FUNC(battlex_state::battlex_palette_w));
+ map(0xe000, 0xe03f).ram().w(FUNC(battlex_state::palette_w));
}
@@ -132,18 +327,18 @@ void battlex_state::io_map(address_map &map)
map(0x01, 0x01).portr("SYSTEM");
map(0x02, 0x02).portr("INPUTS");
map(0x03, 0x03).portr("DSW2");
- map(0x10, 0x10).w(FUNC(battlex_state::battlex_flipscreen_w));
+ map(0x10, 0x10).w(FUNC(battlex_state::flipscreen_w));
- /* verify all of these */
+ // verify all of these
map(0x22, 0x23).w("ay1", FUNC(ay8910_device::data_address_w));
- map(0x30, 0x30).w(FUNC(battlex_state::battlex_scroll_starfield_w));
- map(0x32, 0x32).w(FUNC(battlex_state::battlex_scroll_x_lsb_w));
- map(0x33, 0x33).w(FUNC(battlex_state::battlex_scroll_x_msb_w));
+ map(0x30, 0x30).w(FUNC(battlex_state::scroll_starfield_w));
+ map(0x32, 0x32).w(FUNC(battlex_state::scroll_x_lsb_w));
+ map(0x33, 0x33).w(FUNC(battlex_state::scroll_x_msb_w));
}
-void battlex_state::dodgeman_io_map(address_map &map)
+void dodgeman_state::io_map(address_map &map)
{
- io_map(map);
+ battlex_state::io_map(map);
map(0x26, 0x27).w("ay2", FUNC(ay8910_device::data_address_w));
}
@@ -154,7 +349,7 @@ void battlex_state::dodgeman_io_map(address_map &map)
*************************************/
static INPUT_PORTS_START( battlex )
- PORT_START("DSW1") /* IN0 */
+ PORT_START("DSW1") // IN0
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x02, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
@@ -166,7 +361,7 @@ static INPUT_PORTS_START( battlex )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Demo_Sounds ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x08, DEF_STR( On ) )
- PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(battlex_state, battlex_in0_b4_r)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(battlex_state, in0_b4_r)
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Cabinet ) )
PORT_DIPSETTING( 0x20, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
@@ -175,7 +370,7 @@ static INPUT_PORTS_START( battlex )
PORT_DIPSETTING( 0x40, DEF_STR( On ) )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_START("SYSTEM") /* IN1 */
+ PORT_START("SYSTEM") // IN1
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
// TODO: PORT_IMPULSE?
@@ -186,7 +381,7 @@ static INPUT_PORTS_START( battlex )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
- PORT_START("INPUTS") /* IN2 */
+ PORT_START("INPUTS") // IN2
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY
@@ -196,7 +391,7 @@ static INPUT_PORTS_START( battlex )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
- PORT_START("DSW2") /* IN3 */
+ PORT_START("DSW2") // IN3
PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coin_B ) )
PORT_DIPSETTING( 0x07, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x05, DEF_STR( 2C_1C ) )
@@ -252,8 +447,8 @@ static const gfx_layout battlex_spritelayout =
};
static GFXDECODE_START( gfx_battlex )
- GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 64, 8 )
- GFXDECODE_ENTRY( "gfx2", 0, battlex_spritelayout, 0, 8 )
+ GFXDECODE_ENTRY( "tiles", 0, gfx_8x8x4_packed_msb, 64, 8 )
+ GFXDECODE_ENTRY( "sprites", 0, battlex_spritelayout, 0, 8 )
GFXDECODE_END
@@ -265,7 +460,7 @@ GFXDECODE_END
void battlex_state::machine_start()
{
- /* register for save states */
+ // register for save states
save_item(NAME(m_scroll_lsb));
save_item(NAME(m_scroll_msb));
save_item(NAME(m_starfield_enabled));
@@ -282,39 +477,38 @@ void battlex_state::machine_reset()
void battlex_state::battlex(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, XTAL(10'000'000)/4 ); // ?
- m_maincpu->set_addrmap(AS_PROGRAM, &battlex_state::battlex_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, XTAL(10'000'000) / 4 ); // divider not verified
+ m_maincpu->set_addrmap(AS_PROGRAM, &battlex_state::main_map);
m_maincpu->set_addrmap(AS_IO, &battlex_state::io_map);
- m_maincpu->set_periodic_int(FUNC(battlex_state::battlex_interrupt), attotime::from_hz(400)); /* controls game speed? */
+ m_maincpu->set_periodic_int(FUNC(battlex_state::interrupt), attotime::from_hz(400)); // controls game speed?
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(32*8, 32*8);
screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
- screen.set_screen_update(FUNC(battlex_state::screen_update_battlex));
+ screen.set_screen_update(FUNC(battlex_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_battlex);
PALETTE(config, m_palette).set_entries(64 + 128);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
- AY8910(config, "ay1", XTAL(10'000'000)/8).add_route(ALL_OUTPUTS, "mono", 0.40); // ?
+ AY8910(config, "ay1", XTAL(10'000'000) / 8).add_route(ALL_OUTPUTS, "mono", 0.40); // divider not verified
}
-void battlex_state::dodgeman(machine_config &config)
+void dodgeman_state::dodgeman(machine_config &config)
{
battlex(config);
- m_maincpu->set_addrmap(AS_IO, &battlex_state::dodgeman_io_map);
+ m_maincpu->set_addrmap(AS_IO, &dodgeman_state::io_map);
- MCFG_VIDEO_START_OVERRIDE(battlex_state, dodgeman)
- AY8910(config, "ay2", XTAL(10'000'000)/8).add_route(ALL_OUTPUTS, "mono", 0.40); // ?
+ AY8910(config, "ay2", XTAL(10'000'000) / 8).add_route(ALL_OUTPUTS, "mono", 0.40); // divider not verified
}
@@ -333,9 +527,9 @@ ROM_START( battlex )
ROM_LOAD( "p-rom5.2", 0x4000, 0x1000, CRC(ceb63d38) SHA1(92cab905d009c59115f52172ba7d01c8ff8991d7) )
ROM_LOAD( "p-rom6.1", 0x5000, 0x1000, CRC(6923f601) SHA1(e6c33cbd8d8679299d7b2c568d56f96ed3073971) )
- ROM_REGION( 0x4000, "gfx1", ROMREGION_ERASE00 ) // filled in later
+ ROM_REGION( 0x4000, "tiles", ROMREGION_ERASE00 ) // filled in later
- ROM_REGION( 0x3000, "gfx2", 0 )
+ ROM_REGION( 0x3000, "sprites", 0 )
ROM_LOAD( "1a_f.6f", 0x0000, 0x1000, CRC(2b69287a) SHA1(30c0edaec44118b95ec390bd41c1bd49a2802451) )
ROM_LOAD( "1a_h.6h", 0x1000, 0x1000, CRC(9f4c3bdd) SHA1(e921ecafefe54c033d05d9cd289808e971ac7940) )
ROM_LOAD( "1a_j.6j", 0x2000, 0x1000, CRC(c1345b05) SHA1(17194c8ec961990222bd295ff1d036a64f497b0e) )
@@ -356,9 +550,9 @@ ROM_START( dodgeman )
ROM_LOAD( "dg4.2f", 0x4000, 0x001000, CRC(14169361) SHA1(86d3cd1fa0aa4f21029daea2eba99bdaa34372e8) )
ROM_LOAD( "dg5.1f", 0x5000, 0x001000, CRC(8f83ae2f) SHA1(daad41b61ba3d55531021d444bbe4acfc275cfc9) )
- ROM_REGION( 0x8000, "gfx1", ROMREGION_ERASE00 ) // filled in later
+ ROM_REGION( 0x8000, "tiles", ROMREGION_ERASE00 ) // filled in later
- ROM_REGION( 0x6000, "gfx2", ROMREGION_ERASE00 )
+ ROM_REGION( 0x6000, "sprites", ROMREGION_ERASE00 )
ROM_LOAD( "f.6f", 0x0000, 0x002000, CRC(dfaaf4c8) SHA1(1e09f1d72e7e5e6782d73ae60bca7982fc04df0e) )
ROM_LOAD( "h.6h", 0x2000, 0x002000, CRC(e2525ffe) SHA1(a17b608b4089014be381b26f16597b83d4a66ebd) )
ROM_LOAD( "j.6j", 0x4000, 0x002000, CRC(2731ee46) SHA1(15b9350e19f31b1cea99deb9935543777644e6a8) )
@@ -381,8 +575,8 @@ void battlex_state::init_battlex()
{
uint8_t *colormask = memregion("user1")->base();
uint8_t *gfxdata = memregion("user2")->base();
- uint8_t *dest = memregion("gfx1")->base();
- int tile_size = memregion("gfx1")->bytes() / 32;
+ uint8_t *dest = memregion("tiles")->base();
+ int tile_size = memregion("tiles")->bytes() / 32;
int offset = 0;
for (int tile = 0; tile < tile_size; tile++)
@@ -409,11 +603,14 @@ void battlex_state::init_battlex()
}
}
+} // anonymous namespace
+
+
/*************************************
*
* Game driver
*
*************************************/
-GAME( 1982, battlex, 0, battlex, battlex, battlex_state, init_battlex, ROT180, "Omori Electric Co., Ltd.", "Battle Cross", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
-GAME( 1983, dodgeman, 0, dodgeman, dodgeman, battlex_state, init_battlex, ROT180, "Omori Electric Co., Ltd.", "Dodge Man", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
+GAME( 1982, battlex, 0, battlex, battlex, battlex_state, init_battlex, ROT180, "Omori Electric Co., Ltd.", "Battle Cross", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
+GAME( 1983, dodgeman, 0, dodgeman, dodgeman, dodgeman_state, init_battlex, ROT180, "Omori Electric Co., Ltd.", "Dodge Man", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
diff --git a/src/mame/omori/battlex.h b/src/mame/omori/battlex.h
deleted file mode 100644
index 3f5aca57b59..00000000000
--- a/src/mame/omori/battlex.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-/***************************************************************************
-
- Battle Cross
-
-***************************************************************************/
-
-#include "emupal.h"
-#include "tilemap.h"
-
-class battlex_state : public driver_device
-{
-public:
- battlex_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_videoram(*this, "videoram"),
- m_spriteram(*this, "spriteram"),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette") { }
-
- void init_battlex();
- void dodgeman(machine_config &config);
- void battlex(machine_config &config);
- DECLARE_CUSTOM_INPUT_MEMBER(battlex_in0_b4_r);
-
-private:
- uint8_t m_in0_b4 = 0U;
-
- /* memory pointers */
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_spriteram;
-
- /* video-related */
- tilemap_t *m_bg_tilemap = nullptr;
- uint8_t m_scroll_lsb = 0U;
- uint8_t m_scroll_msb = 0U;
- uint8_t m_starfield_enabled = 0U;
- void battlex_palette_w(offs_t offset, uint8_t data);
- void battlex_scroll_x_lsb_w(uint8_t data);
- void battlex_scroll_x_msb_w(uint8_t data);
- void battlex_scroll_starfield_w(uint8_t data);
- void battlex_videoram_w(offs_t offset, uint8_t data);
- void battlex_flipscreen_w(uint8_t data);
- TILE_GET_INFO_MEMBER(get_bg_tile_info);
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
- uint32_t screen_update_battlex(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(battlex_interrupt);
- void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
-
- DECLARE_VIDEO_START(dodgeman);
- TILE_GET_INFO_MEMBER(get_dodgeman_bg_tile_info);
- void battlex_map(address_map &map);
- void dodgeman_io_map(address_map &map);
- void io_map(address_map &map);
-};
diff --git a/src/mame/omori/battlex_v.cpp b/src/mame/omori/battlex_v.cpp
deleted file mode 100644
index 899376181dd..00000000000
--- a/src/mame/omori/battlex_v.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-/***************************************************************************
-
- Video emulation for Omori Battle Cross
-
-***************************************************************************/
-
-#include "emu.h"
-#include "battlex.h"
-
-
-void battlex_state::battlex_palette_w(offs_t offset, uint8_t data)
-{
- int palette_num = offset / 8;
- int color_num = offset & 7;
-
- m_palette->set_pen_color(offset, pal1bit(data >> 0), pal1bit(data >> 2), pal1bit(data >> 1));
- /* set darker colors */
- m_palette->set_pen_color(64+palette_num*16+color_num, pal1bit(data >> 0), pal1bit(data >> 2), pal1bit(data >> 1));
- m_palette->set_pen_color(64+palette_num*16+color_num+8, pal2bit((data >> 0)&1), pal2bit((data >> 2)&1), pal2bit( (data >> 1) &1));
-}
-
-void battlex_state::battlex_scroll_x_lsb_w(uint8_t data)
-{
- m_scroll_lsb = data;
-}
-
-void battlex_state::battlex_scroll_x_msb_w(uint8_t data)
-{
- m_scroll_msb = data;
-}
-
-void battlex_state::battlex_scroll_starfield_w(uint8_t data)
-{
-}
-
-void battlex_state::battlex_videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_bg_tilemap->mark_tile_dirty(offset / 2);
-}
-
-void battlex_state::battlex_flipscreen_w(uint8_t data)
-{
- m_starfield_enabled = data & 0x10;
-
- if (flip_screen() != (data >> 7))
- {
- flip_screen_set(data & 0x80);
- machine().tilemap().mark_all_dirty();
- }
-}
-
-
-TILE_GET_INFO_MEMBER(battlex_state::get_bg_tile_info)
-{
- int tile = m_videoram[tile_index * 2] | (((m_videoram[tile_index * 2 + 1] & 0x01)) << 8);
- int color = (m_videoram[tile_index * 2 + 1] & 0x0e) >> 1; // high bits unused
-
- tileinfo.set(0, tile, color, 0);
-}
-
-TILE_GET_INFO_MEMBER(battlex_state::get_dodgeman_bg_tile_info)
-{
- int tile = m_videoram[tile_index * 2] | (((m_videoram[tile_index * 2 + 1] & 0x03)) << 8);
- int color = (m_videoram[tile_index * 2 + 1] & 0x0c) >> 2; // high bits unused
-
- tileinfo.set(0, tile, color, 0);
-}
-
-void battlex_state::video_start()
-{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(battlex_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
-}
-
-void battlex_state::video_start_dodgeman()
-{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(battlex_state::get_dodgeman_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
-}
-
-void battlex_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- gfx_element *gfx = m_gfxdecode->gfx(1);
- uint8_t *source = m_spriteram;
- uint8_t *finish = m_spriteram + 0x200;
-
- while (source < finish)
- {
- int sx = (source[0] & 0x7f) * 2 - (source[0] & 0x80) * 2;
- int sy = source[3];
- int tile = source[2] ; /* dodgeman has 0x100 sprites */
- int color = source[1] & 0x07; /* bits 3,4,5 also used during explosions */
- int flipy = source[1] & 0x80;
- int flipx = source[1] & 0x40;
-
- if (flip_screen())
- {
- sx = 240 - sx;
- sy = 240 - sy;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- gfx->transpen(bitmap,cliprect, tile, color, flipx, flipy, sx, sy, 0);
- source += 4;
- }
-
-}
-
-uint32_t battlex_state::screen_update_battlex(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- if (!flip_screen())
- m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 8));
- else
- m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 3));
-
- m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- draw_sprites(bitmap, cliprect);
-
- return 0;
-}
diff --git a/src/mame/omori/popper.cpp b/src/mame/omori/popper.cpp
index e9e696fa2c2..63a6cd1f1fd 100644
--- a/src/mame/omori/popper.cpp
+++ b/src/mame/omori/popper.cpp
@@ -48,6 +48,8 @@
#include "tilemap.h"
+namespace {
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -590,10 +592,12 @@ ROM_START( popper )
ROM_LOAD("p.m4", 0x20, 0x20, CRC(384de5c1) SHA1(892c89a01c11671c5708113b4e4c27b84be37ea6))
ROM_END
+} // anonymous namespace
+
//**************************************************************************
// SYSTEM DRIVERS
//**************************************************************************
-// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROTATION COMPANY FULLNAME FLAGS
-GAME( 1983, popper, 0, popper, popper, popper_state, empty_init, ROT90, "Omori", "Popper", MACHINE_SUPPORTS_SAVE )
+// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROTATION COMPANY FULLNAME FLAGS
+GAME( 1983, popper, 0, popper, popper, popper_state, empty_init, ROT90, "Omori Electric Co., Ltd.", "Popper", MACHINE_SUPPORTS_SAVE )