- namcofl.cpp: consolidated driver in one file, minor cleanups

- pokechmp.cpp: switched to configured banking, enabled save state support, minor cleanups
This commit is contained in:
Ivan Vangelista 2022-07-26 06:38:07 +02:00
parent 17f6a2759e
commit c1026f3123
7 changed files with 419 additions and 461 deletions

View File

@ -41,90 +41,209 @@ ClawGrip, Jul 2006
*/
#include "emu.h"
#include "pokechmp.h"
#include "cpu/m6502/m6502.h"
#include "machine/gen_latch.h"
#include "sound/okim6295.h"
#include "sound/ymopn.h"
#include "sound/ymopl.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
void pokechmp_state::pokechmp_bank_w(uint8_t data)
namespace {
class pokechmp_state : public driver_device
{
uint8_t *ROM = memregion("maincpu")->base();
public:
pokechmp_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_palette(*this, "palette"),
m_videoram(*this, "videoram"),
m_spriteram(*this, "spriteram"),
m_mainbank(*this, "mainbank"),
m_okibank(*this, "okibank")
{ }
int bank;
void pokechmp(machine_config &config);
bank = (data & 0x1) ? 0x04000 : 0x00000;
bank |= (data & 0x2) ? 0x10000 : 0x00000;
protected:
virtual void machine_start() override;
virtual void video_start() override;
membank("bank1")->set_base(&ROM[bank]);
private:
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_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_spriteram;
required_memory_bank m_mainbank;
required_memory_bank m_okibank;
tilemap_t *m_bg_tilemap = nullptr;
void main_bank_w(uint8_t data);
void oki_bank_w(uint8_t data);
void videoram_w(offs_t offset, uint8_t data);
void flipscreen_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(sound_irq);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
uint32_t 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 oki_map(address_map &map);
void sound_map(address_map &map);
};
// video
void pokechmp_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset / 2);
}
void pokechmp_state::flipscreen_w(uint8_t data)
{
if (flip_screen() != (data & 0x80))
{
flip_screen_set(data & 0x80);
machine().tilemap().mark_all_dirty();
}
}
TILE_GET_INFO_MEMBER(pokechmp_state::get_bg_tile_info)
{
int code = m_videoram[tile_index * 2 + 1] + ((m_videoram[tile_index * 2] & 0x3f) << 8);
int color = m_videoram[tile_index * 2] >> 6;
tileinfo.set(0, code, color, 0);
}
void pokechmp_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pokechmp_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
}
void pokechmp_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
{
if (m_spriteram[offs] != 0xf8)
{
int sx = 240 - m_spriteram[offs + 2];
int sy = 240 - m_spriteram[offs];
int flipx = m_spriteram[offs + 1] & 0x04;
int flipy = m_spriteram[offs + 1] & 0x02;
if (flip_screen())
{
sx = 240 - sx;
sy = 240 - sy;
if (flipx) flipx = 0; else flipx = 1;
if (flipy) flipy = 0; else flipy = 1;
}
int tileno = m_spriteram[offs + 3];
if (m_spriteram[offs + 1] & 0x01) tileno += 0x100;
if (m_spriteram[offs + 1] & 0x08) tileno += 0x200;
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect,
tileno,
(m_spriteram[offs + 1] & 0xf0) >> 4,
flipx, flipy,
sx, sy, 0);
}
}
}
uint32_t pokechmp_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}
void pokechmp_state::pokechmp_sound_bank_w(uint8_t data)
// machine
void pokechmp_state::machine_start()
{
uint8_t *ROM = memregion("oki")->base();
membank("okibank")->set_base(&ROM[data*0x8000]);
m_mainbank->configure_entries(0, 2, memregion("maincpu")->base(), 0x4000);
m_mainbank->configure_entries(2, 2, memregion("maincpu")->base() + 0x10000, 0x4000);
m_okibank->configure_entries(0, 16, memregion("oki")->base(), 0x8000);
m_okibank->set_entry(0x08);
}
void pokechmp_state::pokechmp_sound_w(uint8_t data)
void pokechmp_state::main_bank_w(uint8_t data)
{
m_soundlatch->write(data);
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_mainbank->set_entry(data & 0x03);
}
void pokechmp_state::oki_bank_w(uint8_t data)
{
m_okibank->set_entry(data & 0x0f);
}
void pokechmp_state::pokechmp_map(address_map &map)
void pokechmp_state::main_map(address_map &map)
{
map(0x0000, 0x07ff).ram();
map(0x0800, 0x0fff).ram().w(FUNC(pokechmp_state::pokechmp_videoram_w)).share("videoram");
map(0x1000, 0x11ff).ram().share("spriteram");
map(0x0800, 0x0fff).ram().w(FUNC(pokechmp_state::videoram_w)).share(m_videoram);
map(0x1000, 0x11ff).ram().share(m_spriteram);
map(0x1800, 0x1800).portr("P1");
map(0x1801, 0x1801).w(FUNC(pokechmp_state::pokechmp_flipscreen_w));
/* 1800 - 0x181f are unused BAC-06 registers, see video/dec0.c */
map(0x1801, 0x1801).w(FUNC(pokechmp_state::flipscreen_w));
// 1800 - 0x181f are unused BAC-06 registers
map(0x1802, 0x181f).nopw();
map(0x1a00, 0x1a00).portr("P2").w(FUNC(pokechmp_state::pokechmp_sound_w));
map(0x1c00, 0x1c00).portr("DSW").w(FUNC(pokechmp_state::pokechmp_bank_w));
map(0x1a00, 0x1a00).portr("P2").w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x1c00, 0x1c00).portr("DSW").w(FUNC(pokechmp_state::main_bank_w));
/* Extra on Poke Champ (not on Pocket Gal) */
// Extra on Poke Champ (not on Pocket Gal)
map(0x2000, 0x23ff).ram().w(m_palette, FUNC(palette_device::write8_ext)).share("palette_ext");
map(0x2400, 0x27ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
map(0x4000, 0x7fff).bankr("bank1");
map(0x8000, 0xffff).bankr("fixed");
map(0x4000, 0x7fff).bankr(m_mainbank);
map(0x8000, 0xffff).rom().region("maincpu", 0x18000);
}
/***************************************************************************/
void pokechmp_state::pokechmp_sound_map(address_map &map)
void pokechmp_state::sound_map(address_map &map)
{
map(0x0000, 0x07ff).ram();
map(0x0800, 0x0801).w("ym1", FUNC(ym2203_device::write));
map(0x1000, 0x1001).w("ym2", FUNC(ym3812_device::write));
map(0x1800, 0x1800).nopw(); /* MSM5205 chip on Pocket Gal, not connected here? */
map(0x2000, 0x2000).w(FUNC(pokechmp_state::pokechmp_sound_bank_w)); /* sound rom bank seems to be replaced with OKI bank */
map(0x1800, 0x1800).nopw(); // MSM5205 chip on Pocket Gal, not connected here?
map(0x2000, 0x2000).w(FUNC(pokechmp_state::oki_bank_w)); // sound ROM bank seems to be replaced with OKI bank
map(0x2800, 0x2800).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // extra
map(0x3000, 0x3000).r(m_soundlatch, FUNC(generic_latch_8_device::read));
// map(0x3400, 0x3400).r(FUNC(pokechmp_state::pokechmp_adpcm_reset_r)); /* not on here */
map(0x4000, 0x7fff).bankr("bank3");
map(0x8000, 0xffff).rom();
map(0x3000, 0x3000).r("soundlatch", FUNC(generic_latch_8_device::read));
map(0x8000, 0xffff).rom().region("audiocpu", 0x8000);
}
void pokechmp_state::pokechmp_oki_map(address_map &map)
void pokechmp_state::oki_map(address_map &map)
{
map(0x00000, 0x37fff).rom();
map(0x38000, 0x3ffff).bankr("okibank");
map(0x38000, 0x3ffff).bankr(m_okibank);
}
@ -149,7 +268,7 @@ static INPUT_PORTS_START( pokechmp )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_START("DSW") /* Dip switch */
PORT_START("DSW")
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8,7")
PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) )
@ -164,46 +283,46 @@ static INPUT_PORTS_START( pokechmp )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3") /* Affects Time: Normal=120 & Hardest=100 */
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3") // Affects Time: Normal=120 & Hardest=100
PORT_DIPSETTING( 0x20, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:2") /* Listed as "Number of Balls" in the manual */
PORT_DIPSETTING( 0x00, "3" ) /* Manual shows 2 */
PORT_DIPSETTING( 0x40, "4" ) /* Manual shows 3 */
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1") /* Not shown or listed in the manual */
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:2") // Listed as "Number of Balls" in the manual
PORT_DIPSETTING( 0x00, "3" ) // Manual shows 2
PORT_DIPSETTING( 0x40, "4" ) // Manual shows 3
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1") // Not shown or listed in the manual
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
static const gfx_layout pokechmp_charlayout =
{
8,8, /* 8*8 characters */
8,8, // 8*8 characters
RGN_FRAC(1,8),
8,
/* bizzare order, but it seems to be correct? */
// bizarre order, but it seems to be correct?
{ RGN_FRAC(1,8), RGN_FRAC(3,8),RGN_FRAC(0,8),RGN_FRAC(5,8),RGN_FRAC(2,8),RGN_FRAC(7,8),RGN_FRAC(4,8),RGN_FRAC(6,8) },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every char takes 8 consecutive bytes */
8*8 // every char takes 8 consecutive bytes
};
static const gfx_layout pokechmp_spritelayout =
{
16,16, /* 16*16 sprites */
RGN_FRAC(1,4), /* 1024 sprites */
16,16, // 16*16 sprites
RGN_FRAC(1,4), // 1024 sprites
4,
{RGN_FRAC(0,4),RGN_FRAC(1,4),RGN_FRAC(2,4),RGN_FRAC(3,4)},
{ 128+7, 128+6, 128+5, 128+4, 128+3, 128+2, 128+1, 128+0, 7, 6, 5, 4, 3, 2, 1, 0 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
32*8 /* every char takes 8 consecutive bytes */
32*8 // every char takes 8 consecutive bytes
};
static GFXDECODE_START( gfx_pokechmp )
GFXDECODE_ENTRY( "bgs", 0x00000, pokechmp_charlayout, 0x100, 4 ) /* chars */
GFXDECODE_ENTRY( "sprites", 0x00000, pokechmp_spritelayout, 0, 32 ) /* sprites */
GFXDECODE_ENTRY( "bgs", 0x00000, pokechmp_charlayout, 0x100, 4 )
GFXDECODE_ENTRY( "sprites", 0x00000, pokechmp_spritelayout, 0, 32 )
GFXDECODE_END
/*
@ -228,20 +347,20 @@ WRITE_LINE_MEMBER(pokechmp_state::sound_irq)
void pokechmp_state::pokechmp(machine_config &config)
{
/* basic machine hardware */
M6502(config, m_maincpu, 4_MHz_XTAL/4);
m_maincpu->set_addrmap(AS_PROGRAM, &pokechmp_state::pokechmp_map);
// basic machine hardware
M6502(config, m_maincpu, 4_MHz_XTAL / 4);
m_maincpu->set_addrmap(AS_PROGRAM, &pokechmp_state::main_map);
M6502(config, m_audiocpu, 4_MHz_XTAL/4);
m_audiocpu->set_addrmap(AS_PROGRAM, &pokechmp_state::pokechmp_sound_map);
M6502(config, m_audiocpu, 4_MHz_XTAL / 4);
m_audiocpu->set_addrmap(AS_PROGRAM, &pokechmp_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, 32*8-1, 2*8, 30*8-1);
screen.set_screen_update(FUNC(pokechmp_state::screen_update_pokechmp));
screen.set_screen_update(FUNC(pokechmp_state::screen_update));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
screen.screen_vblank().append(FUNC(pokechmp_state::sound_irq));
@ -249,31 +368,19 @@ void pokechmp_state::pokechmp(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_pokechmp);
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x400);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, m_soundlatch);
GENERIC_LATCH_8(config, "soundlatch").data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI);
YM2203(config, "ym1", XTAL(4'000'000)/4).add_route(ALL_OUTPUTS, "mono", 0.60);
YM2203(config, "ym1", 4_MHz_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 0.60);
YM3812(config, "ym2", XTAL(24'000'000)/16).add_route(ALL_OUTPUTS, "mono", 1.0);
YM3812(config, "ym2", 24_MHz_XTAL / 16).add_route(ALL_OUTPUTS, "mono", 1.0);
okim6295_device &oki(OKIM6295(config, "oki", XTAL(24'000'000)/16, okim6295_device::PIN7_LOW));
oki.add_route(ALL_OUTPUTS, "mono", 0.50); /* sound fx */
okim6295_device &oki(OKIM6295(config, "oki", 24_MHz_XTAL / 16, okim6295_device::PIN7_LOW));
oki.add_route(ALL_OUTPUTS, "mono", 0.50);
oki.set_addrmap(0, &pokechmp_state::pokechmp_oki_map);
}
void pokechmp_state::init_pokechmp()
{
// default sound rom bank
membank("bank3")->configure_entries(0, 2, memregion("audiocpu")->base() + 0x10000, 0x4000);
// default fixed area for main CPU
membank("fixed")->set_base( memregion("maincpu")->base() + 0x18000 );
// default OKI sample bank
membank("okibank")->set_base( memregion("oki")->base() + 0x40000 );
oki.add_route(ALL_OUTPUTS, "mono", 0.50);
oki.set_addrmap(0, &pokechmp_state::oki_map);
}
@ -281,9 +388,8 @@ ROM_START( pokechmp )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "pokechamp_11_27010.bin", 0x00000, 0x20000, CRC(9afb6912) SHA1(e45da9524e3bb6f64a68200b70d0f83afe6e4379) )
ROM_REGION( 0x18000, "audiocpu", 0 ) /* 96k for code + 96k for decrypted opcodes */
ROM_LOAD( "pokechamp_09_27c512.bin", 0x10000, 0x8000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21) )
ROM_CONTINUE( 0x08000, 0x8000 )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "pokechamp_09_27c512.bin", 0x00000, 0x10000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21) ) // 0xxxxxxxxxxxxxxx = 0x00
ROM_REGION( 0x100000, "bgs", 0 )
ROM_LOAD( "pokechamp_05_27c020.bin", 0x00000, 0x40000, CRC(554cfa42) SHA1(862d0dd83697da7bd52dc640c34926c62691afea) )
@ -292,7 +398,7 @@ ROM_START( pokechmp )
ROM_LOAD( "pokechamp_08_27c020.bin", 0xc0000, 0x40000, CRC(e9db54d6) SHA1(ac3b7c06d0f61847bf9bc6147f2f88d712f2b4b3) )
ROM_REGION( 0x20000, "sprites", 0 )
/* the first half of all these roms is identical. For rom 3 both halves match. Correct decode is to ignore the first half */
// the first half of all these ROMs is identical. For ROM 3 both halves match. Correct decode is to ignore the first half
ROM_LOAD( "pokechamp_02_27c512.bin", 0x00000, 0x08000, CRC(1ff44545) SHA1(2eee44484accce7b0ba21babf6e8344b234a4e87) ) ROM_CONTINUE( 0x00000, 0x8000 )
ROM_LOAD( "pokechamp_01_27c512.bin", 0x08000, 0x08000, CRC(338fc412) SHA1(bb8ae99ee6a399a8c67bedb88d0837fd0a4a426c) ) ROM_CONTINUE( 0x08000, 0x8000 )
ROM_LOAD( "pokechamp_04_27c512.bin", 0x10000, 0x08000, CRC(ee6991af) SHA1(8eca3cdfd2eb74257253957a87b245b7f85bd038) ) ROM_CONTINUE( 0x10000, 0x8000 )
@ -303,13 +409,12 @@ ROM_START( pokechmp )
ROM_END
// only the 'maincpu' and 'bgs' regions were dumped for this set, others assumed to be the same
ROM_START( pokechmpa )
ROM_START( pokechmpa ) // PCB: DGRM NO 1342
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "1", 0x00000, 0x20000, CRC(7d051c36) SHA1(8c2329f863ad677f4398a7dab7476c9492ad4f24) )
ROM_REGION( 0x18000, "audiocpu", 0 ) /* 96k for code + 96k for decrypted opcodes */
ROM_LOAD("pokechamp_09_27c512.bin", 0x10000, 0x8000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21))
ROM_CONTINUE( 0x08000, 0x8000 )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD("pokechamp_09_27c512.bin", 0x00000, 0x10000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21)) // 0xxxxxxxxxxxxxxx = 0x00
ROM_REGION( 0x100000, "bgs", 0 )
ROM_LOAD( "6", 0x00000, 0x40000, CRC(1aec1de2) SHA1(f42db2445dcf1fb0957bf8a4414c3266ae47fae1) )
@ -318,7 +423,7 @@ ROM_START( pokechmpa )
ROM_LOAD( "3", 0xc0000, 0x40000, CRC(a22946b8) SHA1(d77fb5bfe00349753a9e6ea9de82c1eefca090f7) )
ROM_REGION( 0x20000, "sprites", 0 )
/* the first half of all these roms is identical. For rom 3 both halves match. Correct decode is to ignore the first half */
// the first half of all these ROMs is identical. For ROM 3 both halves match. Correct decode is to ignore the first half
ROM_LOAD( "pokechamp_02_27c512.bin", 0x00000, 0x08000, CRC(1ff44545) SHA1(2eee44484accce7b0ba21babf6e8344b234a4e87) ) ROM_CONTINUE( 0x00000, 0x8000 )
ROM_LOAD( "pokechamp_01_27c512.bin", 0x08000, 0x08000, CRC(338fc412) SHA1(bb8ae99ee6a399a8c67bedb88d0837fd0a4a426c) ) ROM_CONTINUE( 0x08000, 0x8000 )
ROM_LOAD( "pokechamp_04_27c512.bin", 0x10000, 0x08000, CRC(ee6991af) SHA1(8eca3cdfd2eb74257253957a87b245b7f85bd038) ) ROM_CONTINUE( 0x10000, 0x8000 )
@ -333,9 +438,8 @@ ROM_START(billlist)
ROM_REGION(0x20000, "maincpu", 0)
ROM_LOAD("billiard_list.1", 0x00000, 0x20000, CRC(4ef416f7) SHA1(e995410e2c79a3fbd2ac76a80dc6c412eb454e52) )
ROM_REGION(0x18000, "audiocpu", 0) /* 96k for code + 96k for decrypted opcodes */
ROM_LOAD("pokechamp_09_27c512.bin", 0x10000, 0x8000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21))
ROM_CONTINUE(0x08000, 0x8000)
ROM_REGION(0x10000, "audiocpu", 0)
ROM_LOAD("pokechamp_09_27c512.bin", 0x00000, 0x10000, CRC(c78f6483) SHA1(a0d063effd8d1850f674edccb6e7a285b2311d21)) // 0xxxxxxxxxxxxxxx = 0x00
ROM_REGION(0x100000, "bgs", 0)
ROM_LOAD("billiard_list.6", 0x00000, 0x40000, CRC(e674f7c0) SHA1(8a610a92ae141f3004497dc3ce102d07a178683f) )
@ -344,7 +448,7 @@ ROM_START(billlist)
ROM_LOAD("billiard_list.3", 0xc0000, 0x40000, CRC(1ac4fa42) SHA1(2da5c6aa7e6b34ad1a2f052a41a2e607e2f904c2) )
ROM_REGION(0x20000, "sprites", 0)
/* the first half of all these roms is identical. For rom 3 both halves match. Correct decode is to ignore the first half */
// the first half of all these ROMs is identical. For ROM 3 both halves match. Correct decode is to ignore the first half
ROM_LOAD("pokechamp_02_27c512.bin", 0x00000, 0x08000, CRC(1ff44545) SHA1(2eee44484accce7b0ba21babf6e8344b234a4e87)) ROM_CONTINUE(0x00000, 0x8000)
ROM_LOAD("pokechamp_01_27c512.bin", 0x08000, 0x08000, CRC(338fc412) SHA1(bb8ae99ee6a399a8c67bedb88d0837fd0a4a426c)) ROM_CONTINUE(0x08000, 0x8000)
ROM_LOAD("pokechamp_04_27c512.bin", 0x10000, 0x08000, CRC(ee6991af) SHA1(8eca3cdfd2eb74257253957a87b245b7f85bd038)) ROM_CONTINUE(0x10000, 0x8000)
@ -354,6 +458,9 @@ ROM_START(billlist)
ROM_LOAD("billiard_list.x", 0x00000, 0x80000, CRC(b54806ed) SHA1(c6e1485c263ebd9102ff1e8c09b4c4ca5f63c3da) )
ROM_END
GAME( 1995, pokechmp, 0, pokechmp, pokechmp, pokechmp_state, init_pokechmp, ROT0, "D.G.R.M.", "Poke Champ (set 1)", 0 )
GAME( 1995, pokechmpa,pokechmp, pokechmp, pokechmp, pokechmp_state, init_pokechmp, ROT0, "D.G.R.M.", "Poke Champ (set 2)", 0 )
GAME( 1995, billlist, pokechmp, pokechmp, pokechmp, pokechmp_state, init_pokechmp, ROT0, "D.G.R.M.", "Billard List", 0)
} // anonymous namespace
GAME( 1995, pokechmp, 0, pokechmp, pokechmp, pokechmp_state, empty_init, ROT0, "D.G.R.M.", "Poke Champ (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, pokechmpa, pokechmp, pokechmp, pokechmp, pokechmp_state, empty_init, ROT0, "D.G.R.M.", "Poke Champ (set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, billlist, pokechmp, pokechmp, pokechmp, pokechmp_state, empty_init, ROT0, "D.G.R.M.", "Billard List", MACHINE_SUPPORTS_SAVE )

View File

@ -1,54 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_INCLUDES_POKECHMP_H
#define MAME_INCLUDES_POKECHMP_H
#pragma once
#include "machine/gen_latch.h"
#include "emupal.h"
#include "tilemap.h"
class pokechmp_state : public driver_device
{
public:
pokechmp_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_audiocpu(*this, "audiocpu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_soundlatch(*this, "soundlatch")
{ }
void pokechmp(machine_config &config);
void init_pokechmp();
private:
required_shared_ptr<uint8_t> m_videoram;
tilemap_t *m_bg_tilemap = nullptr;
required_shared_ptr<uint8_t> m_spriteram;
void pokechmp_bank_w(uint8_t data);
void pokechmp_sound_bank_w(uint8_t data);
void pokechmp_sound_w(uint8_t data);
void pokechmp_videoram_w(offs_t offset, uint8_t data);
void pokechmp_flipscreen_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(sound_irq);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
virtual void video_start() override;
uint32_t screen_update_pokechmp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
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;
required_device<generic_latch_8_device> m_soundlatch;
void pokechmp_map(address_map &map);
void pokechmp_oki_map(address_map &map);
void pokechmp_sound_map(address_map &map);
};
#endif // MAME_INCLUDES_POKECHMP_H

View File

@ -1,81 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/* Poke Champ */
#include "emu.h"
#include "pokechmp.h"
void pokechmp_state::pokechmp_videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset / 2);
}
void pokechmp_state::pokechmp_flipscreen_w(uint8_t data)
{
if (flip_screen() != (data & 0x80))
{
flip_screen_set(data & 0x80);
machine().tilemap().mark_all_dirty();
}
}
TILE_GET_INFO_MEMBER(pokechmp_state::get_bg_tile_info)
{
uint8_t *videoram = m_videoram;
int code = videoram[tile_index*2+1] + ((videoram[tile_index*2] & 0x3f) << 8);
int color = videoram[tile_index*2] >> 6;
tileinfo.set(0, code, color, 0);
}
void pokechmp_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(
*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pokechmp_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS,
8, 8, 32, 32);
}
void pokechmp_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t *spriteram = m_spriteram;
int offs;
for (offs = 0;offs < m_spriteram.bytes();offs += 4)
{
if (spriteram[offs] != 0xf8)
{
int sx,sy,flipx,flipy;
sx = 240 - spriteram[offs+2];
sy = 240 - spriteram[offs];
flipx = spriteram[offs+1] & 0x04;
flipy = spriteram[offs+1] & 0x02;
if (flip_screen()) {
sx=240-sx;
sy=240-sy;
if (flipx) flipx=0; else flipx=1;
if (flipy) flipy=0; else flipy=1;
}
int tileno = spriteram[offs+3];
if (spriteram[offs+1] & 0x01) tileno += 0x100;
if (spriteram[offs+1] & 0x08) tileno += 0x200;
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
tileno,
(spriteram[offs+1] & 0xf0) >> 4,
flipx,flipy,
sx,sy,0);
}
}
}
uint32_t pokechmp_state::screen_update_pokechmp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}

View File

@ -6,6 +6,16 @@ Mogura Desse, Konami 1991
Hardware info by Guru
---------------------
This is a small test board. The game is basically a whack-a-mole type
game and has basic sound but the game is purely a bonus. The board is
primarily for testing the controls and setting up the screen and may
have been provided in non-dedicated empty Konami cabinets from the era
as there is (or was?) a Japanese law stating that arcade cabinets
could not be sold without a game included. If this is true then there
were likely many of these boards manufactured, but due to the simple
game may have been thrown away by arcade operators so how many survive
today is unknown.
PCB Layout
----------

View File

@ -161,16 +161,176 @@ OSC3: 48.384MHz
*/
#include "emu.h"
#include "namcofl.h"
#include "namco_c123tmap.h"
#include "namco_c116.h"
#include "namco_c169roz.h"
#include "namco_c355spr.h"
#include "namcomcu.h"
#include "cpu/i960/i960.h"
#include "sound/c352.h"
#include "machine/nvram.h"
#include "machine/timer.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "finalapr.lh"
#include <algorithm>
namespace {
class namcofl_state : public driver_device
{
public:
namcofl_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_c116(*this, "c116"),
m_screen(*this, "screen"),
m_c123tmap(*this, "c123tmap"),
m_c169roz(*this, "c169roz"),
m_c355spr(*this, "c355spr"),
m_mcu(*this, "mcu"),
m_workram(*this, "workram"),
m_shareram(*this, "shareram"),
m_mainbank(*this, "mainbank"),
m_in0(*this, "IN0"),
m_in1(*this, "IN1"),
m_in2(*this, "IN2"),
m_misc(*this, "MISC"),
m_accel(*this, "ACCEL"),
m_brake(*this, "BRAKE"),
m_wheel(*this, "WHEEL")
{ }
void namcofl(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device<i960_cpu_device> m_maincpu;
required_device<namco_c116_device> m_c116;
required_device<screen_device> m_screen;
required_device<namco_c123tmap_device> m_c123tmap;
required_device<namco_c169roz_device> m_c169roz;
required_device<namco_c355spr_device> m_c355spr;
required_device<m37710_cpu_device> m_mcu;
required_shared_ptr<uint32_t> m_workram;
required_shared_ptr<uint32_t> m_shareram;
memory_view m_mainbank;
required_ioport m_in0;
required_ioport m_in1;
required_ioport m_in2;
required_ioport m_misc;
required_ioport m_accel;
optional_ioport m_brake;
required_ioport m_wheel;
emu_timer *m_raster_interrupt_timer = nullptr;
emu_timer *m_vblank_interrupt_timer = nullptr;
emu_timer *m_network_interrupt_timer = nullptr;
uint8_t m_mcu_port6 = 0;
uint32_t m_sprbank = 0;
uint32_t unk1_r();
uint8_t network_r(offs_t offset);
uint32_t sysreg_r();
void sysreg_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void c116_w(offs_t offset, uint8_t data);
uint16_t mcu_shared_r(offs_t offset);
void mcu_shared_w(offs_t offset, uint16_t data, uint16_t mem_mask);
uint8_t port6_r();
void port6_w(uint8_t data);
uint8_t port7_r();
uint8_t dac6_r();
void spritebank_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(network_interrupt_callback);
TIMER_CALLBACK_MEMBER(vblank_interrupt_callback);
TIMER_CALLBACK_MEMBER(raster_interrupt_callback);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_irq0_cb);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_irq2_cb);
int objcode2tile(int code);
void tilemap_cb(uint16_t code, int *tile, int *mask);
void roz_cb(uint16_t code, int *tile, int *mask, int which);
void namcoc75_am(address_map &map);
void main_map(address_map &map);
};
// video
void namcofl_state::tilemap_cb(uint16_t code, int *tile, int *mask)
{
*tile = code;
*mask = code;
}
void namcofl_state::roz_cb(uint16_t code, int *tile, int *mask, int which)
{
*tile = code;
*mask = code;
}
uint32_t namcofl_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// compute window for custom screen blanking
rectangle clip;
//004c 016b 0021 0101 004a 0060 (finalapr*)
//004b 016b 0021 0101 0144 0047 (speedrcr)
clip.min_x = m_c116->get_reg(0) - 0x4b;
clip.max_x = m_c116->get_reg(1) - 0x4b - 1;
clip.min_y = m_c116->get_reg(2) - 0x21;
clip.max_y = m_c116->get_reg(3) - 0x21 - 1;
// intersect with master clip rectangle
clip &= cliprect;
bitmap.fill(m_c116->black_pen(), cliprect );
for (int pri = 0; pri < 16; pri++)
{
m_c169roz->draw(screen, bitmap, clip, pri);
if ((pri & 1) == 0)
{
m_c123tmap->draw(screen, bitmap, clip, pri >> 1);
}
m_c355spr->draw(screen, bitmap, clip, pri);
}
return 0;
}
// NOTE : The two low bits toggle banks (code + 0x4000) for two
// groups of sprites. I am unsure how to differentiate those groups
// at this time however.
void namcofl_state::spritebank_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
COMBINE_DATA(&m_sprbank);
}
int namcofl_state::objcode2tile(int code)
{
if (BIT(code, 13))
return (m_sprbank << 13) | (code & 0x1fff);
return code;
}
// machine
uint32_t namcofl_state::unk1_r()
{
return 0xffffffff;
@ -211,27 +371,27 @@ void namcofl_state::c116_w(offs_t offset, uint8_t data)
}
}
void namcofl_state::namcofl_mem(address_map &map)
void namcofl_state::main_map(address_map &map)
{
map(0x00000000, 0x1fffffff).view(m_mainbank);
m_mainbank[0](0x00000000, 0x000fffff).flags(i960_cpu_device::BURST).ram().share("workram");
m_mainbank[0](0x00000000, 0x000fffff).flags(i960_cpu_device::BURST).ram().share(m_workram);
m_mainbank[0](0x10000000, 0x100fffff).flags(i960_cpu_device::BURST).rom().region("maincpu", 0);
m_mainbank[1](0x00000000, 0x000fffff).flags(i960_cpu_device::BURST).rom().region("maincpu", 0);
m_mainbank[1](0x10000000, 0x100fffff).flags(i960_cpu_device::BURST).ram().share("workram");
m_mainbank[1](0x10000000, 0x100fffff).flags(i960_cpu_device::BURST).ram().share(m_workram);
map(0x20000000, 0x201fffff).flags(i960_cpu_device::BURST).rom().region("data", 0);
map(0x30000000, 0x30001fff).flags(i960_cpu_device::BURST).ram().share("nvram"); /* nvram */
map(0x30000000, 0x30001fff).flags(i960_cpu_device::BURST).ram().share("nvram");
map(0x30100000, 0x30100003).flags(i960_cpu_device::BURST).w(FUNC(namcofl_state::spritebank_w));
map(0x30284000, 0x3028bfff).flags(i960_cpu_device::BURST).ram().share("shareram");
map(0x30300000, 0x30303fff).flags(i960_cpu_device::BURST).ram(); /* COMRAM */
map(0x30380000, 0x303800ff).flags(i960_cpu_device::BURST).r(FUNC(namcofl_state::network_r)).umask32(0x00ff00ff); /* network registers */
map(0x30284000, 0x3028bfff).flags(i960_cpu_device::BURST).ram().share(m_shareram);
map(0x30300000, 0x30303fff).flags(i960_cpu_device::BURST).ram(); // COMRAM
map(0x30380000, 0x303800ff).flags(i960_cpu_device::BURST).r(FUNC(namcofl_state::network_r)).umask32(0x00ff00ff); // network registers
map(0x30400000, 0x30407fff).flags(i960_cpu_device::BURST).r(m_c116, FUNC(namco_c116_device::read)).w(FUNC(namcofl_state::c116_w));
map(0x30800000, 0x3080ffff).flags(i960_cpu_device::BURST).rw(m_c123tmap, FUNC(namco_c123tmap_device::videoram16_r), FUNC(namco_c123tmap_device::videoram16_w));
map(0x30a00000, 0x30a0003f).flags(i960_cpu_device::BURST).rw(m_c123tmap, FUNC(namco_c123tmap_device::control16_r), FUNC(namco_c123tmap_device::control16_w));
map(0x30c00000, 0x30c1ffff).flags(i960_cpu_device::BURST).rw(m_c169roz, FUNC(namco_c169roz_device::videoram_r), FUNC(namco_c169roz_device::videoram_w));
map(0x30d00000, 0x30d0001f).flags(i960_cpu_device::BURST).rw(m_c169roz, FUNC(namco_c169roz_device::control_r), FUNC(namco_c169roz_device::control_w));
map(0x30e00000, 0x30e1ffff).flags(i960_cpu_device::BURST).rw(m_c355spr, FUNC(namco_c355spr_device::spriteram_r), FUNC(namco_c355spr_device::spriteram_w)).share("objram");
map(0x30f00000, 0x30f0000f).flags(i960_cpu_device::BURST).ram(); /* NebulaM2 code says this is int enable at 0000, int request at 0004, but doesn't do much about it */
map(0x30f00000, 0x30f0000f).flags(i960_cpu_device::BURST).ram(); // NebulaM2 code says this is int enable at 0000, int request at 0004, but doesn't do much about it
map(0x40000000, 0x4000005f).flags(i960_cpu_device::BURST).rw(FUNC(namcofl_state::sysreg_r), FUNC(namcofl_state::sysreg_w));
map(0xfffffffc, 0xffffffff).flags(i960_cpu_device::BURST).r(FUNC(namcofl_state::unk1_r));
}
@ -263,7 +423,7 @@ void namcofl_state::mcu_shared_w(offs_t offset, uint16_t data, uint16_t mem_mask
uint16_t namcofl_state::mcu_shared_r(offs_t offset)
{
if(offset & 1)
if (offset & 1)
return m_shareram[offset >> 1] >> 16;
else
return m_shareram[offset >> 1];
@ -302,27 +462,11 @@ uint8_t namcofl_state::port7_r()
return 0xff;
}
uint8_t namcofl_state::dac7_r()
{
return m_accel.read_safe(0xff);
}
uint8_t namcofl_state::dac6_r()
{
return m_brake.read_safe(0xff);
}
uint8_t namcofl_state::dac5_r()
{
return m_wheel.read_safe(0xff);
}
uint8_t namcofl_state::dac4_r(){ return 0xff; }
uint8_t namcofl_state::dac3_r(){ return 0xff; }
uint8_t namcofl_state::dac2_r(){ return 0xff; }
uint8_t namcofl_state::dac1_r(){ return 0xff; }
uint8_t namcofl_state::dac0_r(){ return 0xff; }
void namcofl_state::namcoc75_am(address_map &map)
{
map(0x002000, 0x002fff).rw("c352", FUNC(c352_device::read), FUNC(c352_device::write));
@ -387,8 +531,7 @@ static INPUT_PORTS_START( speedrcr )
PORT_START("ACCEL")
PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(20)
PORT_START("BRAKE")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // no brake
// no brake
PORT_START("WHEEL")
PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(100) PORT_KEYDELTA(4)
@ -498,6 +641,9 @@ void namcofl_state::machine_start()
m_vblank_interrupt_timer = timer_alloc(FUNC(namcofl_state::vblank_interrupt_callback), this);
m_mainbank.select(1);
save_item(NAME(m_mcu_port6));
save_item(NAME(m_sprbank));
}
@ -513,30 +659,30 @@ void namcofl_state::machine_reset()
void namcofl_state::namcofl(machine_config &config)
{
I960(config, m_maincpu, 80_MHz_XTAL/4); // i80960KA-20 == 20 MHz part
m_maincpu->set_addrmap(AS_PROGRAM, &namcofl_state::namcofl_mem);
I960(config, m_maincpu, 80_MHz_XTAL / 4); // i80960KA-20 == 20 MHz part
m_maincpu->set_addrmap(AS_PROGRAM, &namcofl_state::main_map);
NAMCO_C75(config, m_mcu, 48.384_MHz_XTAL/3);
NAMCO_C75(config, m_mcu, 48.384_MHz_XTAL / 3);
m_mcu->set_addrmap(AS_PROGRAM, &namcofl_state::namcoc75_am);
m_mcu->p6_in_cb().set(FUNC(namcofl_state::port6_r));
m_mcu->p6_out_cb().set(FUNC(namcofl_state::port6_w));
m_mcu->p7_in_cb().set(FUNC(namcofl_state::port7_r));
m_mcu->an7_cb().set(FUNC(namcofl_state::dac7_r));
m_mcu->an7_cb().set_ioport("ACCEL");
m_mcu->an6_cb().set(FUNC(namcofl_state::dac6_r));
m_mcu->an5_cb().set(FUNC(namcofl_state::dac5_r));
m_mcu->an4_cb().set(FUNC(namcofl_state::dac4_r));
m_mcu->an3_cb().set(FUNC(namcofl_state::dac3_r));
m_mcu->an2_cb().set(FUNC(namcofl_state::dac2_r));
m_mcu->an1_cb().set(FUNC(namcofl_state::dac1_r));
m_mcu->an0_cb().set(FUNC(namcofl_state::dac0_r));
/* TODO: irq generation for these */
m_mcu->an5_cb().set_ioport("WHEEL");
m_mcu->an4_cb().set_constant(0xff);
m_mcu->an3_cb().set_constant(0xff);
m_mcu->an2_cb().set_constant(0xff);
m_mcu->an1_cb().set_constant(0xff);
m_mcu->an0_cb().set_constant(0xff);
// TODO: IRQ generation for these
TIMER(config, "mcu_irq0").configure_periodic(FUNC(namcofl_state::mcu_irq0_cb), attotime::from_hz(60));
TIMER(config, "mcu_irq2").configure_periodic(FUNC(namcofl_state::mcu_irq2_cb), attotime::from_hz(60));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(48.384_MHz_XTAL/8, 384, 0, 288, 264, 0, 224); // same as namconb1.cpp?
m_screen->set_raw(48.384_MHz_XTAL / 8, 384, 0, 288, 264, 0, 224); // same as namconb1.cpp?
m_screen->set_screen_update(FUNC(namcofl_state::screen_update));
m_screen->screen_vblank().set(m_c355spr, FUNC(namco_c355spr_device::vblank));
m_screen->set_palette(m_c116);
@ -544,22 +690,22 @@ void namcofl_state::namcofl(machine_config &config)
NAMCO_C169ROZ(config, m_c169roz, 0);
m_c169roz->set_palette(m_c116);
m_c169roz->set_is_namcofl(true);
m_c169roz->set_ram_words(0x20000/2);
m_c169roz->set_tile_callback(namco_c169roz_device::c169_tilemap_delegate(&namcofl_state::RozCB, this));
m_c169roz->set_ram_words(0x20000 / 2);
m_c169roz->set_tile_callback(namco_c169roz_device::c169_tilemap_delegate(&namcofl_state::roz_cb, this));
m_c169roz->set_color_base(0x1800);
NAMCO_C355SPR(config, m_c355spr, 0);
m_c355spr->set_screen(m_screen);
m_c355spr->set_palette(m_c116);
m_c355spr->set_scroll_offsets(0, 0);
m_c355spr->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate(&namcofl_state::FLobjcode2tile, this));
m_c355spr->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate(&namcofl_state::objcode2tile, this));
m_c355spr->set_palxor(0x0);
m_c355spr->set_color_base(0);
m_c355spr->set_buffer(1);
NAMCO_C123TMAP(config, m_c123tmap, 0);
m_c123tmap->set_palette(m_c116);
m_c123tmap->set_tile_callback(namco_c123tmap_device::c123_tilemap_delegate(&namcofl_state::TilemapCB, this));
m_c123tmap->set_tile_callback(namco_c123tmap_device::c123_tilemap_delegate(&namcofl_state::tilemap_cb, this));
m_c123tmap->set_color_base(0x1000);
NAMCO_C116(config, m_c116, 0);
@ -567,7 +713,7 @@ void namcofl_state::namcofl(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
c352_device &c352(C352(config, "c352", 48.384_MHz_XTAL/2, 288));
c352_device &c352(C352(config, "c352", 48.384_MHz_XTAL / 2, 288));
c352.add_route(0, "lspeaker", 1.00);
c352.add_route(1, "rspeaker", 1.00);
//c352.add_route(2, "lspeaker", 1.00); // Second DAC not present.
@ -579,13 +725,13 @@ ROM_START( speedrcr )
ROM_LOAD32_WORD("se2_mp_ea4.19a", 0x000000, 0x080000, CRC(95ab3fd7) SHA1(273a536f8512f3c55260ac1b78533bc35b8390ed) )
ROM_LOAD32_WORD("se2_mp_oa4.18a", 0x000002, 0x080000, CRC(5b5ef1eb) SHA1(3e9e4abb1a32269baef772079de825dfe1ea230c) )
ROM_REGION32_LE( 0x200000, "data", 0 ) // Data
ROM_REGION32_LE( 0x200000, "data", 0 )
ROM_LOAD32_BYTE("se1_dat0.13a", 0x000000, 0x080000, CRC(cc5d6ff5) SHA1(6fad40a1fac75bc64d3b7a7562cf7ce2a3abd36a) )
ROM_LOAD32_BYTE("se1_dat1.14a", 0x000001, 0x080000, CRC(ddc8b306) SHA1(f169d521b800c108deffdef9fc6b0058621ee909) )
ROM_LOAD32_BYTE("se1_dat2.15a", 0x000002, 0x080000, CRC(2a29abbb) SHA1(945419ed61e9a656a340214a63a01818396fbe98) )
ROM_LOAD32_BYTE("se1_dat3.16a", 0x000003, 0x080000, CRC(49849aff) SHA1(b7c7eea1d56304e40e996ee998c971313ff03614) )
ROM_REGION16_LE( 0x80000, "c75data", 0 ) // C75 data
ROM_REGION16_LE( 0x80000, "c75data", 0 )
ROM_LOAD("se1_spr.21l", 0x000000, 0x80000, CRC(850a27ac) SHA1(7d5db840ec67659a1f2e69a62cdb03ce6ee0b47b) )
ROM_REGION( 0x200000, "c169roz", 0 ) // "RCHAR" (roz characters)
@ -613,12 +759,12 @@ ROM_START( speedrcr )
ROM_REGION( 0x1000000, "c352", 0 ) // Samples
ROM_LOAD("se1_voi.23s", 0x000000, 0x400000, CRC(0cfa2d8a) SHA1(e029b39432cf35071eec8da27df8beeccd458eba) )
ROM_REGION( 0x000005, "pals", 0) /* PAL's */
ROM_LOAD( "sysfl-1.bin", 0x000000, 0x000001, NO_DUMP ) /* PAL16L8BCN at 2S */
ROM_LOAD( "sysfl-2.bin", 0x000000, 0x000001, NO_DUMP ) /* PAL16L8BCN at 3L */
ROM_LOAD( "sysfl-3.bin", 0x000000, 0x000001, NO_DUMP ) /* PALCE16V8H-15PC/4 at 12S */
ROM_LOAD( "sysfl-4.bin", 0x000000, 0x000001, NO_DUMP ) /* PAL20L8BCNS at 20N */
ROM_LOAD( "sysfl-5.bin", 0x000000, 0x000001, NO_DUMP ) /* PALCE16V8H-15PC/4 at 19D */
ROM_REGION( 0x000005, "pals", 0)
ROM_LOAD( "sysfl-1.bin", 0x000000, 0x000001, NO_DUMP ) // PAL16L8BCN at 2S
ROM_LOAD( "sysfl-2.bin", 0x000000, 0x000001, NO_DUMP ) // PAL16L8BCN at 3L
ROM_LOAD( "sysfl-3.bin", 0x000000, 0x000001, NO_DUMP ) // PALCE16V8H-15PC/4 at 12S
ROM_LOAD( "sysfl-4.bin", 0x000000, 0x000001, NO_DUMP ) // PAL20L8BCNS at 20N
ROM_LOAD( "sysfl-5.bin", 0x000000, 0x000001, NO_DUMP ) // PALCE16V8H-15PC/4 at 19D
ROM_REGION( 0x2000, "nvram", 0 ) // default settings, including calibration
ROM_LOAD("speedrcr.nv", 0x000000, 0x2000, CRC(58b41c70) SHA1(c30ea7f4951ce208781deafef8d99bdb4902e5b8) )
@ -630,9 +776,9 @@ ROM_START( finalapr )
ROM_LOAD32_WORD("flr2_mp_eb.19a", 0x000000, 0x080000, CRC(8bfe615f) SHA1(7b867eb261268a83177f1f873689f77d1b6c47ca) )
ROM_LOAD32_WORD("flr2_mp_ob.18a", 0x000002, 0x080000, CRC(91c14e4f) SHA1(934a86daaef0e3e2c2b3066f4677ccb3aaab6eaf) )
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF ) // Data
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF )
ROM_REGION16_LE( 0x80000, "c75data", 0 ) // C75 data
ROM_REGION16_LE( 0x80000, "c75data", 0 )
ROM_LOAD("flr1_spr.21l", 0x000000, 0x20000, CRC(69bb0f5e) SHA1(6831d618de42a165e508ad37db594d3aa290c530) )
ROM_REGION( 0x200000, "c169roz", 0 ) // "RCHAR" (roz characters)
@ -669,9 +815,9 @@ ROM_START( finalapr1 )
ROM_LOAD32_WORD("flr2_mp_e.19a", 0x000000, 0x080000, CRC(cc8961ae) SHA1(08ce4d27a723101370d1c536b26256ce0d8a1b6c) )
ROM_LOAD32_WORD("flr2_mp_o.18a", 0x000002, 0x080000, CRC(8118f465) SHA1(c4b79878a82fd36b5707e92aa893f69c2b942d57) )
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF ) // Data
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF )
ROM_REGION16_LE( 0x80000, "c75data", 0 ) // C75 data
ROM_REGION16_LE( 0x80000, "c75data", 0 )
ROM_LOAD("flr1_spr.21l", 0x000000, 0x20000, CRC(69bb0f5e) SHA1(6831d618de42a165e508ad37db594d3aa290c530) )
ROM_REGION( 0x200000, "c169roz", 0 ) // "RCHAR" (roz characters)
@ -708,9 +854,9 @@ ROM_START( finalaprj )
ROM_LOAD32_WORD("flr1_mp_ec.19a", 0x000000, 0x080000, CRC(52735494) SHA1(db9873cb39bcfdd3dbe2e5079249fecac2c46df9) )
ROM_LOAD32_WORD("flr1_mp_oc.18a", 0x000002, 0x080000, CRC(b11fe577) SHA1(70b51a1e66a3bb92f027aad7ba0f358c0e139b3c) )
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF ) // Data
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF )
ROM_REGION16_LE( 0x80000, "c75data", 0 ) // C75 data
ROM_REGION16_LE( 0x80000, "c75data", 0 )
ROM_LOAD("flr1_spr.21l", 0x000000, 0x20000, CRC(69bb0f5e) SHA1(6831d618de42a165e508ad37db594d3aa290c530) )
ROM_REGION( 0x200000, "c169roz", 0 ) // "RCHAR" (roz characters)
@ -747,9 +893,9 @@ ROM_START( finalaprj1 )
ROM_LOAD32_WORD("flr1_mp_eb.19a", 0x000000, 0x080000, CRC(1a77bcc0) SHA1(4090917afcd0346ea78e6e307879a980cf196204) )
ROM_LOAD32_WORD("flr1_mp_ob.18a", 0x000002, 0x080000, CRC(5f64eb2b) SHA1(0011ceeedefcf16c333c7ab28f334dd228eac4cf) )
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF ) // Data
ROM_REGION32_LE( 0x200000, "data", ROMREGION_ERASEFF )
ROM_REGION16_LE( 0x80000, "c75data", 0 ) // C75 data
ROM_REGION16_LE( 0x80000, "c75data", 0 )
ROM_LOAD("flr1_spr.21l", 0x000000, 0x20000, CRC(69bb0f5e) SHA1(6831d618de42a165e508ad37db594d3aa290c530) )
ROM_REGION( 0x200000, "c169roz", 0 ) // "RCHAR" (roz characters)
@ -781,16 +927,13 @@ ROM_START( finalaprj1 )
ROM_LOAD("finalapr.nv", 0x000000, 0x2000, CRC(d51d65fe) SHA1(8a0a523cb6ba2880951e41ca04db23584f0a108c) )
ROM_END
void namcofl_state::driver_init()
{
save_item(NAME(m_mcu_port6));
save_item(NAME(m_sprbank));
}
} // anonymous namespace
GAME( 1995, speedrcr, 0, namcofl, speedrcr, namcofl_state, driver_init, ROT0, "Namco", "Speed Racer", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
GAME( 1995, speedrcr, 0, namcofl, speedrcr, namcofl_state, empty_init, ROT0, "Namco", "Speed Racer", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
// Final Lap R was released 02/94, a 1993 copyright date is displayed on the title screen
GAMEL( 1994, finalapr, 0, namcofl, finalapr, namcofl_state, driver_init, ROT0, "Namco", "Final Lap R (Rev. B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalapr1, finalapr, namcofl, finalapr, namcofl_state, driver_init, ROT0, "Namco", "Final Lap R", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalaprj, finalapr, namcofl, finalapr, namcofl_state, driver_init, ROT0, "Namco", "Final Lap R (Japan Rev. C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalaprj1, finalapr, namcofl, finalapr, namcofl_state, driver_init, ROT0, "Namco", "Final Lap R (Japan Rev. B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalapr, 0, namcofl, finalapr, namcofl_state, empty_init, ROT0, "Namco", "Final Lap R (Rev. B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalapr1, finalapr, namcofl, finalapr, namcofl_state, empty_init, ROT0, "Namco", "Final Lap R", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalaprj, finalapr, namcofl, finalapr, namcofl_state, empty_init, ROT0, "Namco", "Final Lap R (Japan Rev. C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )
GAMEL( 1994, finalaprj1, finalapr, namcofl, finalapr, namcofl_state, empty_init, ROT0, "Namco", "Final Lap R (Japan Rev. B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_finalapr )

View File

@ -1,102 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont, ElSemi
#include "cpu/i960/i960.h"
#include "namcomcu.h"
#include "machine/timer.h"
#include "namco_c123tmap.h"
#include "namco_c116.h"
#include "namco_c169roz.h"
#include "namco_c355spr.h"
#include "emupal.h"
#include "screen.h"
class namcofl_state : public driver_device
{
public:
namcofl_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_c116(*this, "c116"),
m_screen(*this, "screen"),
m_c123tmap(*this, "c123tmap"),
m_c169roz(*this, "c169roz"),
m_c355spr(*this, "c355spr"),
m_mcu(*this, "mcu"),
m_workram(*this, "workram"),
m_shareram(*this, "shareram"),
m_mainbank(*this, "mainbank"),
m_in0(*this, "IN0"),
m_in1(*this, "IN1"),
m_in2(*this, "IN2"),
m_misc(*this, "MISC"),
m_accel(*this, "ACCEL"),
m_brake(*this, "BRAKE"),
m_wheel(*this, "WHEEL")
{ }
void namcofl(machine_config &config);
void driver_init() override;
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device<i960_cpu_device> m_maincpu;
required_device<namco_c116_device> m_c116;
required_device<screen_device> m_screen;
required_device<namco_c123tmap_device> m_c123tmap;
required_device<namco_c169roz_device> m_c169roz;
required_device<namco_c355spr_device> m_c355spr;
required_device<m37710_cpu_device> m_mcu;
required_shared_ptr<uint32_t> m_workram;
required_shared_ptr<uint32_t> m_shareram;
memory_view m_mainbank;
required_ioport m_in0;
required_ioport m_in1;
required_ioport m_in2;
required_ioport m_misc;
optional_ioport m_accel;
optional_ioport m_brake;
optional_ioport m_wheel;
emu_timer *m_raster_interrupt_timer = nullptr;
emu_timer *m_vblank_interrupt_timer = nullptr;
emu_timer *m_network_interrupt_timer = nullptr;
uint8_t m_mcu_port6 = 0;
uint32_t m_sprbank = 0;
uint32_t unk1_r();
uint8_t network_r(offs_t offset);
uint32_t sysreg_r();
void sysreg_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void c116_w(offs_t offset, uint8_t data);
uint16_t mcu_shared_r(offs_t offset);
void mcu_shared_w(offs_t offset, uint16_t data, uint16_t mem_mask);
uint8_t port6_r();
void port6_w(uint8_t data);
uint8_t port7_r();
uint8_t dac7_r();
uint8_t dac6_r();
uint8_t dac5_r();
uint8_t dac4_r();
uint8_t dac3_r();
uint8_t dac2_r();
uint8_t dac1_r();
uint8_t dac0_r();
void spritebank_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(network_interrupt_callback);
TIMER_CALLBACK_MEMBER(vblank_interrupt_callback);
TIMER_CALLBACK_MEMBER(raster_interrupt_callback);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_irq0_cb);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_irq2_cb);
int FLobjcode2tile(int code);
void TilemapCB(uint16_t code, int *tile, int *mask);
void RozCB(uint16_t code, int *tile, int *mask, int which);
void namcoc75_am(address_map &map);
void namcofl_mem(address_map &map);
};

View File

@ -1,65 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont, ElSemi
/* video/namcofl.cpp */
#include "emu.h"
#include "namcofl.h"
void namcofl_state::TilemapCB(uint16_t code, int *tile, int *mask)
{
*tile = code;
*mask = code;
}
void namcofl_state::RozCB(uint16_t code, int *tile, int *mask, int which)
{
*tile = code;
*mask = code;
}
uint32_t namcofl_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* compute window for custom screen blanking */
rectangle clip;
//004c 016b 0021 0101 004a 0060 (finalapr*)
//004b 016b 0021 0101 0144 0047 (speedrcr)
clip.min_x = m_c116->get_reg(0) - 0x4b;
clip.max_x = m_c116->get_reg(1) - 0x4b - 1;
clip.min_y = m_c116->get_reg(2) - 0x21;
clip.max_y = m_c116->get_reg(3) - 0x21 - 1;
/* intersect with master clip rectangle */
clip &= cliprect;
bitmap.fill(m_c116->black_pen(), cliprect );
for( int pri=0; pri<16; pri++ )
{
m_c169roz->draw(screen, bitmap, clip, pri);
if ((pri & 1) == 0)
{
m_c123tmap->draw(screen, bitmap, clip, pri >> 1);
}
m_c355spr->draw(screen, bitmap, clip, pri );
}
return 0;
}
// NOTE : The two low bits toggle banks (code + 0x4000) for two
// groups of sprites. I am unsure how to differentiate those groups
// at this time however.
void namcofl_state::spritebank_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
COMBINE_DATA(&m_sprbank);
}
int namcofl_state::FLobjcode2tile(int code)
{
if (BIT(code, 13))
return (m_sprbank << 13) | (code & 0x1fff);
return code;
}