gaelco/blmbycar.cpp, gaelco/glass.cpp, gaelco/targeth.cpp, gaelco/wrally.cpp, gaelco/xorworld.cpp, gametron/gatron.cpp, gametron/sbugger.cpp: consolidated drivers in single files, minor cleanups

This commit is contained in:
Ivan Vangelista 2022-09-03 09:22:55 +02:00
parent 6f6aca1b7f
commit 86d08c090d
25 changed files with 1877 additions and 1970 deletions

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
// copyright-holders: Luca Elia
/***************************************************************************
-= Blomby Car =-
@ -28,14 +29,238 @@ Check game speed, it depends on a bit we toggle..
***************************************************************************/
#include "emu.h"
#include "blmbycar.h"
#include "gaelco_wrally_sprites.h"
#include "cpu/m68000/m68000.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class base_state : public driver_device
{
public:
base_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_okibank(*this, "okibank"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_sprites(*this, "sprites"),
m_vram(*this, "vram_%u", 0U),
m_scroll(*this, "scroll_%u", 0U),
m_spriteram(*this, "spriteram")
{
}
void base(machine_config &config);
protected:
virtual void video_start() override;
required_device<cpu_device> m_maincpu;
required_memory_bank m_okibank;
void common_map(address_map &map);
private:
// devices
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<gaelco_wrally_sprites_device> m_sprites;
// memory pointers
required_shared_ptr_array<uint16_t, 2> m_vram;
required_shared_ptr_array<uint16_t, 2> m_scroll;
required_shared_ptr<uint16_t> m_spriteram;
// video-related
tilemap_t *m_tilemap[2]{};
void okibank_w(uint8_t data);
template<int Layer> void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
void oki_map(address_map &map);
};
class blmbycar_state : public base_state
{
public:
blmbycar_state(const machine_config &mconfig, device_type type, const char *tag) :
base_state(mconfig, type, tag),
m_pot_wheel_io(*this, "POT_WHEEL"),
m_opt_wheel_io(*this, "OPT_WHEEL")
{
}
void blmbycar(machine_config &config);
void init_blmbycar();
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_ioport m_pot_wheel_io;
required_ioport m_opt_wheel_io;
// input-related
uint8_t m_pot_wheel = 0;
uint8_t m_old_val = 0;
void pot_wheel_reset_w(uint8_t data);
void pot_wheel_shift_w(uint8_t data);
uint16_t pot_wheel_r();
uint16_t opt_wheel_r();
void prg_map(address_map &map);
};
class watrball_state : public base_state
{
public:
watrball_state(const machine_config &mconfig, device_type type, const char *tag) :
base_state(mconfig, type, tag)
{
}
void watrball(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
uint8_t m_retvalue = 0;
uint16_t unk_r();
void prg_map(address_map &map);
};
// video
/***************************************************************************
Note: if MAME_DEBUG is defined, pressing Z with:
Q shows the background
W shows the foreground
A shows the sprites
Keys can be used together!
[ 2 Scrolling Layers ]
The Tilemaps are 64 x 32 tiles in size (1024 x 512).
Tiles are 16 x 16 x 4, with 32 color codes and 2 priority
levels (wrt sprites). Each tile needs 4 bytes.
[ 1024? Sprites ]
They use the same graphics the tilemaps use (16 x 16 x 4 tiles)
with 16 color codes and 2 levels of priority
***************************************************************************/
/***************************************************************************
Tilemaps
Offset: Bits: Value:
0.w Code
2.w fedc ba98 ---- ----
---- ---- 7--- ---- Flip Y
---- ---- -6-- ---- Flip X
---- ---- --5- ---- Priority (0 = Low)
---- ---- ---4 3210 Color
***************************************************************************/
static constexpr uint8_t DIM_NX = 0x40;
static constexpr uint8_t DIM_NY = 0x20;
template<int Layer>
TILE_GET_INFO_MEMBER(base_state::get_tile_info)
{
uint16_t const code = m_vram[Layer][tile_index * 2 + 0];
uint16_t const attr = m_vram[Layer][tile_index * 2 + 1];
tileinfo.set(0,
code,
attr & 0x1f,
TILE_FLIPYX((attr >> 6) & 3));
tileinfo.category = (attr >> 5) & 1;
}
/***************************************************************************
Video Init
***************************************************************************/
void base_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(base_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(base_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap[1]->set_transparent_pen(0);
}
/***************************************************************************
Screen Drawing
***************************************************************************/
uint32_t base_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_sprites->draw_sprites(cliprect, m_spriteram, flip_screen());
m_tilemap[0]->set_scrolly(0, m_scroll[0][0]);
m_tilemap[0]->set_scrollx(0, m_scroll[0][1]);
m_tilemap[1]->set_scrolly(0, m_scroll[1][0] + 1);
m_tilemap[1]->set_scrollx(0, m_scroll[1][1] + 5);
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect);
m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
m_sprites->mix_sprites(bitmap, cliprect, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, 1, 1);
m_tilemap[1]->draw(screen, bitmap, cliprect, 1, 1);
m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}
// machine
/***************************************************************************
@ -44,9 +269,9 @@ Check game speed, it depends on a bit we toggle..
***************************************************************************/
/* The top 64k of samples are banked (16 banks total) */
// The top 64k of samples are banked (16 banks total)
void blmbycar_state::okibank_w(uint8_t data)
void base_state::okibank_w(uint8_t data)
{
m_okibank->set_entry(data & 0x0f);
}
@ -59,29 +284,29 @@ void blmbycar_state::okibank_w(uint8_t data)
***************************************************************************/
/* Preliminary potentiometric wheel support */
// Preliminary potentiometric wheel support
void blmbycar_state::blmbycar_pot_wheel_reset_w(uint8_t data)
void blmbycar_state::pot_wheel_reset_w(uint8_t data)
{
m_pot_wheel = m_pot_wheel_io->read() & 0xff;
}
void blmbycar_state::blmbycar_pot_wheel_shift_w(uint8_t data)
void blmbycar_state::pot_wheel_shift_w(uint8_t data)
{
if ( ((m_old_val & 0xff) == 0xff) && ((data & 0xff) == 0) )
if ( ((m_old_val) == 0xff) && ((data) == 0) )
m_pot_wheel <<= 1;
m_old_val = data;
}
uint16_t blmbycar_state::blmbycar_pot_wheel_r()
uint16_t blmbycar_state::pot_wheel_r()
{
return ((m_pot_wheel & 0x80) ? 0x04 : 0) | (machine().rand() & 0x08);
}
/* Preliminary optical wheel support */
// Preliminary optical wheel support
uint16_t blmbycar_state::blmbycar_opt_wheel_r()
uint16_t blmbycar_state::opt_wheel_r()
{
return ((m_opt_wheel_io->read() & 0xff) << 8) | 0xff;
}
@ -96,7 +321,7 @@ uint16_t blmbycar_state::blmbycar_opt_wheel_r()
***************************************************************************/
template<int Layer>
void blmbycar_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
void base_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_vram[Layer][offset]);
m_tilemap[Layer]->mark_tile_dirty(offset / 2);
@ -111,58 +336,58 @@ void blmbycar_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
***************************************************************************/
void blmbycar_state::common_map(address_map &map)
void base_state::common_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x103fff).writeonly().share("unk_100000"); // ???
map(0x104000, 0x105fff).ram().w(FUNC(blmbycar_state::vram_w<1>)).share("vram_1"); // Layer 1
map(0x106000, 0x107fff).ram().w(FUNC(blmbycar_state::vram_w<0>)).share("vram_0"); // Layer 0
map(0x104000, 0x105fff).ram().w(FUNC(base_state::vram_w<1>)).share(m_vram[1]); // Layer 1
map(0x106000, 0x107fff).ram().w(FUNC(base_state::vram_w<0>)).share(m_vram[0]); // Layer 0
map(0x108000, 0x10bfff).writeonly().share("unk_108000"); // ???
map(0x10c000, 0x10c003).writeonly().share("scroll_1"); // Scroll 1
map(0x10c004, 0x10c007).writeonly().share("scroll_0"); // Scroll 0
map(0x200000, 0x203fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette").mirror(0x4000); // Palette
map(0x10c000, 0x10c003).writeonly().share(m_scroll[1]);
map(0x10c004, 0x10c007).writeonly().share(m_scroll[0]);
map(0x200000, 0x203fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette").mirror(0x4000);
map(0x440000, 0x441fff).ram();
map(0x444000, 0x445fff).writeonly().share("spriteram");// Sprites (size?)
map(0x444000, 0x445fff).writeonly().share(m_spriteram); // (size?)
map(0x700000, 0x700001).portr("DSW");
map(0x700002, 0x700003).portr("P1_P2");
map(0x70000d, 0x70000d).w(FUNC(blmbycar_state::okibank_w)); // Sound
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // Sound
map(0x70000d, 0x70000d).w(FUNC(base_state::okibank_w));
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
map(0xfec000, 0xfeffff).ram();
}
void blmbycar_state::blmbycar_map(address_map &map)
void blmbycar_state::prg_map(address_map &map)
{
common_map(map);
map(0x700004, 0x700005).r(FUNC(blmbycar_state::blmbycar_opt_wheel_r)); // Wheel (optical)
map(0x700004, 0x700005).r(FUNC(blmbycar_state::opt_wheel_r));
map(0x700006, 0x700007).portr("UNK");
map(0x700008, 0x700009).r(FUNC(blmbycar_state::blmbycar_pot_wheel_r)); // Wheel (potentiometer)
map(0x700008, 0x700009).r(FUNC(blmbycar_state::pot_wheel_r));
map(0x70000a, 0x70000b).nopw(); // ? Wheel
map(0x70006a, 0x70006b).nopr(); // Wheel (potentiometer)
map(0x70006b, 0x70006b).w(FUNC(blmbycar_state::blmbycar_pot_wheel_reset_w)); // Wheel (potentiometer)
map(0x70007a, 0x70007b).nopr(); //
map(0x70007b, 0x70007b).w(FUNC(blmbycar_state::blmbycar_pot_wheel_shift_w)); //
map(0x70006a, 0x70006b).nopr(); // Wheel (potentiometer)
map(0x70006b, 0x70006b).w(FUNC(blmbycar_state::pot_wheel_reset_w));
map(0x70007a, 0x70007b).nopr();
map(0x70007b, 0x70007b).w(FUNC(blmbycar_state::pot_wheel_shift_w));
}
uint16_t blmbycar_state::waterball_unk_r()
uint16_t watrball_state::unk_r()
{
m_retvalue ^= 0x0008; // must toggle.. but not vblank?
return m_retvalue;
}
void blmbycar_state::watrball_map(address_map &map)
void watrball_state::prg_map(address_map &map)
{
common_map(map);
map(0x700006, 0x700007).nopr(); // read
map(0x700008, 0x700009).r(FUNC(blmbycar_state::waterball_unk_r)); // 0x0008 must toggle
map(0x700008, 0x700009).r(FUNC(watrball_state::unk_r)); // 0x0008 must toggle
map(0x70000a, 0x70000b).nopw(); // ?? busy
}
void blmbycar_state::blmbycar_oki_map(address_map &map)
void base_state::oki_map(address_map &map)
{
map(0x00000, 0x2ffff).rom();
map(0x30000, 0x3ffff).bankr("okibank");
map(0x30000, 0x3ffff).bankr(m_okibank);
}
/***************************************************************************
@ -175,7 +400,7 @@ void blmbycar_state::blmbycar_oki_map(address_map &map)
static INPUT_PORTS_START( blmbycar )
PORT_START("DSW") /* $700000.w */
PORT_START("DSW") // $700000.w
PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:8,7")
PORT_DIPSETTING( 0x0002, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x0003, DEF_STR( Normal ) )
@ -243,13 +468,13 @@ static INPUT_PORTS_START( blmbycar )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
PORT_START("OPT_WHEEL") /* $700004.w */
PORT_START("OPT_WHEEL") // $700004.w
PORT_BIT ( 0x00ff, 0x0000, IPT_DIAL ) PORT_SENSITIVITY(30) PORT_KEYDELTA(1) PORT_REVERSE PORT_CONDITION("DSW", 0x18, EQUALS, 0x08) PORT_NAME("P1 Opt Wheel")
PORT_START("POT_WHEEL")
PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(1) PORT_REVERSE PORT_CONDITION("DSW", 0x18, EQUALS, 0x10) PORT_NAME("P1 Pot Wheel")
PORT_START("UNK") /* $700006.w */
PORT_START("UNK") // $700006.w
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
@ -257,11 +482,11 @@ INPUT_PORTS_END
static INPUT_PORTS_START( watrball )
PORT_START("DSW")
PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:8,7") /* Affects timer */
PORT_DIPSETTING( 0x0002, DEF_STR( Easy ) ) /* 180 Seconds */
PORT_DIPSETTING( 0x0003, DEF_STR( Normal ) ) /* 150 Seconds */
PORT_DIPSETTING( 0x0001, DEF_STR( Hard ) ) /* 120 Seconds */
PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) ) /* 100 Seconds */
PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:8,7") // Affects timer
PORT_DIPSETTING( 0x0002, DEF_STR( Easy ) ) // 180 Seconds
PORT_DIPSETTING( 0x0003, DEF_STR( Normal ) ) // 150 Seconds
PORT_DIPSETTING( 0x0001, DEF_STR( Hard ) ) // 120 Seconds
PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) ) // 100 Seconds
PORT_DIPUNUSED_DIPLOC( 0x0004, 0x0004, "SW1:6" )
PORT_DIPUNUSED_DIPLOC( 0x0008, 0x0008, "SW1:5" )
PORT_DIPUNUSED_DIPLOC( 0x0010, 0x0010, "SW1:4" )
@ -322,7 +547,7 @@ INPUT_PORTS_END
***************************************************************************/
/* 16x16x4 tiles (made of four 8x8 tiles) */
// 16x16x4 tiles (made of four 8x8 tiles)/
static const gfx_layout layout_16x16x4 =
{
16,16,
@ -334,7 +559,7 @@ static const gfx_layout layout_16x16x4 =
16*16
};
/* Layers both use the first $20 color codes. Sprites the next $10 */
// Layers both use the first $20 color codes. Sprites the next $10
static GFXDECODE_START( gfx_blmbycar )
GFXDECODE_ENTRY( "sprites", 0, layout_16x16x4, 0x0, 64*8 ) // [0] Layers + Sprites
GFXDECODE_END
@ -349,7 +574,7 @@ GFXDECODE_END
***************************************************************************/
MACHINE_START_MEMBER(blmbycar_state,blmbycar)
void blmbycar_state::machine_start()
{
save_item(NAME(m_pot_wheel));
save_item(NAME(m_old_val));
@ -357,29 +582,23 @@ MACHINE_START_MEMBER(blmbycar_state,blmbycar)
m_okibank->configure_entries(0, 16, memregion("oki")->base(), 0x10000);
}
MACHINE_RESET_MEMBER(blmbycar_state,blmbycar)
void blmbycar_state::machine_reset()
{
m_pot_wheel = 0;
m_old_val = 0;
}
void blmbycar_state::blmbycar(machine_config &config)
void base_state::base(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(24'000'000)/2); /* 12MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &blmbycar_state::blmbycar_map);
// basic machine hardware
M68000(config, m_maincpu, XTAL(24'000'000) / 2); // 12MHz
m_maincpu->set_vblank_int("screen", FUNC(blmbycar_state::irq1_line_hold));
MCFG_MACHINE_START_OVERRIDE(blmbycar_state,blmbycar)
MCFG_MACHINE_RESET_OVERRIDE(blmbycar_state,blmbycar)
/* 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(0x180, 0x100);
screen.set_visarea_full();
screen.set_screen_update(FUNC(blmbycar_state::screen_update));
screen.set_palette(m_palette);
@ -391,40 +610,48 @@ void blmbycar_state::blmbycar(machine_config &config)
m_sprites->set_gfxdecode_tag("gfxdecode");
m_sprites->set_screen_tag("screen");
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); // clock frequency & pin 7 not verified
oki.set_addrmap(0, &blmbycar_state::blmbycar_oki_map);
oki.set_addrmap(0, &blmbycar_state::oki_map);
oki.add_route(ALL_OUTPUTS, "mono", 1.0);
}
void blmbycar_state::blmbycar(machine_config &config)
{
base(config);
MACHINE_START_MEMBER(blmbycar_state,watrball)
// basic machine hardware
m_maincpu->set_addrmap(AS_PROGRAM, &blmbycar_state::prg_map);
screen_device &screen(*subdevice<screen_device>("screen"));
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_visarea_full();
}
void watrball_state::machine_start()
{
save_item(NAME(m_retvalue));
m_okibank->configure_entries(0, 16, memregion("oki")->base(), 0x10000);
}
MACHINE_RESET_MEMBER(blmbycar_state,watrball)
void watrball_state::machine_reset()
{
m_retvalue = 0;
}
void blmbycar_state::watrball(machine_config &config)
void watrball_state::watrball(machine_config &config)
{
blmbycar(config);
base(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &blmbycar_state::watrball_map);
// basic machine hardware
m_maincpu->set_addrmap(AS_PROGRAM, &watrball_state::prg_map);
MCFG_MACHINE_START_OVERRIDE(blmbycar_state,watrball)
MCFG_MACHINE_RESET_OVERRIDE(blmbycar_state,watrball)
/* video hardware */
// video hardware
screen_device &screen(*subdevice<screen_device>("screen"));
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_visarea(0, 0x180-1, 16, 0x100-1);
}
@ -451,41 +678,41 @@ GFX : TI TPC1020AFN-084
***************************************************************************/
ROM_START( blmbycar )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "bcrom4.bin", 0x000000, 0x080000, CRC(06d490ba) SHA1(6d113561b474bf613c6b91c9525a52025ae65ab7) )
ROM_LOAD16_BYTE( "bcrom6.bin", 0x000001, 0x080000, CRC(33aca664) SHA1(04fff492654d3edac62e9d35808e5946bcc78cbb) )
ROM_REGION( 0x200000, "sprites", 0 ) /* Sprites */
ROM_REGION( 0x200000, "sprites", 0 )
ROM_LOAD( "bc_rom7", 0x000000, 0x080000, CRC(e55ca79b) SHA1(4453a6ae0518832f437ab701c28cb2f32920f8ba) )
ROM_LOAD( "bc_rom8", 0x080000, 0x080000, CRC(cdf38c96) SHA1(3273c29b6a01a7296d06fc653120f8c615195d2c) )
ROM_LOAD( "bc_rom9", 0x100000, 0x080000, CRC(0337ab3d) SHA1(18c72cd640c7b599390dffaeb670f5832202bf06) )
ROM_LOAD( "bc_rom10", 0x180000, 0x080000, CRC(5458917e) SHA1(c8dd5a391cc20a573e27a140b185893a8c04859e) )
ROM_REGION( 0x100000, "oki", 0 ) /* 8 bit adpcm (banked) */
ROM_REGION( 0x100000, "oki", 0 ) // 8 bit ADPCM (banked)
ROM_LOAD( "bc_rom1", 0x000000, 0x080000, CRC(ac6f8ba1) SHA1(69d2d47cdd331bde5a8973d29659b3f8520452e7) )
ROM_LOAD( "bc_rom2", 0x080000, 0x080000, CRC(a4bc31bf) SHA1(f3d60141a91449a73f6cec9f4bc5d95ca7911e19) )
ROM_END
ROM_START( blmbycaru )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "bc_rom4", 0x000000, 0x080000, CRC(76f054a2) SHA1(198efd152b13033e5249119ca48b9e0f6351b0b9) )
ROM_LOAD16_BYTE( "bc_rom6", 0x000001, 0x080000, CRC(2570b4c5) SHA1(706465950023a6ef7c85ceb9c76246d7556b3859) )
ROM_REGION( 0x200000, "sprites", 0 ) /* Sprites */
ROM_REGION( 0x200000, "sprites", 0 )
ROM_LOAD( "bc_rom7", 0x000000, 0x080000, CRC(e55ca79b) SHA1(4453a6ae0518832f437ab701c28cb2f32920f8ba) )
ROM_LOAD( "bc_rom8", 0x080000, 0x080000, CRC(cdf38c96) SHA1(3273c29b6a01a7296d06fc653120f8c615195d2c) )
ROM_LOAD( "bc_rom9", 0x100000, 0x080000, CRC(0337ab3d) SHA1(18c72cd640c7b599390dffaeb670f5832202bf06) )
ROM_LOAD( "bc_rom10", 0x180000, 0x080000, CRC(5458917e) SHA1(c8dd5a391cc20a573e27a140b185893a8c04859e) )
ROM_REGION( 0x100000, "oki", 0 ) /* 8 bit adpcm (banked) */
ROM_REGION( 0x100000, "oki", 0 ) // 8 bit ADPCM (banked)
ROM_LOAD( "bc_rom1", 0x000000, 0x080000, CRC(ac6f8ba1) SHA1(69d2d47cdd331bde5a8973d29659b3f8520452e7) )
ROM_LOAD( "bc_rom2", 0x080000, 0x080000, CRC(a4bc31bf) SHA1(f3d60141a91449a73f6cec9f4bc5d95ca7911e19) )
ROM_END
/*
Waterball by ABM (sticker on the pcb 12-3-96)
The pcb has some empty sockets, maybe it was used for other games since it has no markings.
Waterball by ABM (sticker on the PCB 12-3-96)
The PCB has some empty sockets, maybe it was used for other games since it has no markings.
The game has fonts identical to World Rally and obviously Blomby Car ;)
@ -499,25 +726,25 @@ The game has fonts identical to World Rally and obviously Blomby Car ;)
*/
ROM_START( watrball )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "rom4.bin", 0x000000, 0x020000, CRC(bfbfa720) SHA1(d6d14c0ba545eb7adee7190da2d3db1c6dd00d75) )
ROM_LOAD16_BYTE( "rom6.bin", 0x000001, 0x020000, CRC(acff9b01) SHA1(b85671bcc4f03fdf05eb1c9b5d4143e33ec1d7db) )
ROM_REGION( 0x200000, "sprites", 0 ) /* Sprites */
ROM_REGION( 0x200000, "sprites", 0 )
ROM_LOAD( "rom7.bin", 0x000000, 0x080000, CRC(e7e5c311) SHA1(5af1a666bf23c5505d120d81fb942f5c49341861) )
ROM_LOAD( "rom8.bin", 0x080000, 0x080000, CRC(fd27ce6e) SHA1(a472a8cc25818427d2870518649780146e51835b) )
ROM_LOAD( "rom9.bin", 0x100000, 0x080000, CRC(122cc0ad) SHA1(27cdb19fa082089e47c5cdb44742cfd93aa23a00) )
ROM_LOAD( "rom10.bin", 0x180000, 0x080000, CRC(22a2a706) SHA1(c7350a94a857e0007d7fc0076b44a3d62693cb6c) )
ROM_REGION( 0x100000, "oki", 0 ) /* 8 bit adpcm (banked) */
ROM_REGION( 0x100000, "oki", 0 ) // 8 bit ADPCM (banked)
ROM_LOAD( "rom1.bin", 0x000000, 0x080000, CRC(7f88dee7) SHA1(d493b961fa4631185a33faee7f61786430707209))
// ROM_LOAD( "rom2.bin", 0x080000, 0x080000, /* not populated for this game */ )
// ROM_LOAD( "rom2.bin", 0x080000, 0x080000, // not populated for this game
ROM_END
void blmbycar_state::init_blmbycar()
{
uint16_t *RAM = (uint16_t *) memregion("maincpu")->base();
uint16_t *RAM = (uint16_t *) memregion("maincpu")->base();
size_t size = memregion("maincpu")->bytes() / 2;
for (int i = 0; i < size; i++)
{
@ -527,6 +754,9 @@ void blmbycar_state::init_blmbycar()
}
}
} // anonymous namespace
/***************************************************************************
@ -535,6 +765,6 @@ void blmbycar_state::init_blmbycar()
***************************************************************************/
GAME( 1994, blmbycar, 0, blmbycar, blmbycar, blmbycar_state, init_blmbycar, ROT0, "ABM & Gecas", "Blomby Car (Version 1P0)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, blmbycar, 0, blmbycar, blmbycar, blmbycar_state, init_blmbycar, ROT0, "ABM & Gecas", "Blomby Car (Version 1P0)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, blmbycaru, blmbycar, blmbycar, blmbycar, blmbycar_state, empty_init, ROT0, "ABM & Gecas", "Blomby Car (Version 1P0, not encrypted)", MACHINE_SUPPORTS_SAVE )
GAME( 1996, watrball, 0, watrball, watrball, blmbycar_state, empty_init, ROT0, "ABM", "Water Balls", MACHINE_SUPPORTS_SAVE )
GAME( 1996, watrball, 0, watrball, watrball, watrball_state, empty_init, ROT0, "ABM", "Water Balls", MACHINE_SUPPORTS_SAVE )

View File

@ -1,87 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
/***************************************************************************
Blomby Car
***************************************************************************/
#include "gaelco_wrally_sprites.h"
#include "emupal.h"
#include "tilemap.h"
class blmbycar_state : public driver_device
{
public:
blmbycar_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_sprites(*this, "sprites"),
m_vram(*this, "vram_%u", 0U),
m_scroll(*this, "scroll_%u", 0U),
m_spriteram(*this, "spriteram"),
m_okibank(*this, "okibank"),
m_pot_wheel_io(*this, "POT_WHEEL"),
m_opt_wheel_io(*this, "OPT_WHEEL")
{
}
void watrball(machine_config &config);
void blmbycar(machine_config &config);
void init_blmbycar();
private:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<gaelco_wrally_sprites_device> m_sprites;
/* memory pointers */
required_shared_ptr_array<uint16_t, 2> m_vram;
required_shared_ptr_array<uint16_t, 2> m_scroll;
required_shared_ptr<uint16_t> m_spriteram;
required_memory_bank m_okibank;
optional_ioport m_pot_wheel_io;
optional_ioport m_opt_wheel_io;
/* video-related */
tilemap_t *m_tilemap[2]{};
/* input-related */
uint8_t m_pot_wheel = 0; // blmbycar
uint8_t m_old_val = 0; // blmbycar
int m_retvalue = 0; // waterball
// common
void okibank_w(uint8_t data);
template<int Layer> void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
// blmbycar
void blmbycar_pot_wheel_reset_w(uint8_t data);
void blmbycar_pot_wheel_shift_w(uint8_t data);
uint16_t blmbycar_pot_wheel_r();
uint16_t blmbycar_opt_wheel_r();
// waterball
uint16_t waterball_unk_r();
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
virtual void video_start() override;
DECLARE_MACHINE_START(blmbycar);
DECLARE_MACHINE_RESET(blmbycar);
DECLARE_MACHINE_START(watrball);
DECLARE_MACHINE_RESET(watrball);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
void blmbycar_map(address_map &map);
void blmbycar_oki_map(address_map &map);
void common_map(address_map &map);
void watrball_map(address_map &map);
};

View File

@ -1,118 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
/***************************************************************************
-= Blomby Car =-
driver by Luca Elia (l.elia@tin.it)
Note: if MAME_DEBUG is defined, pressing Z with:
Q shows the background
W shows the foreground
A shows the sprites
Keys can be used together!
[ 2 Scrolling Layers ]
The Tilemaps are 64 x 32 tiles in size (1024 x 512).
Tiles are 16 x 16 x 4, with 32 color codes and 2 priority
leves (wrt sprites). Each tile needs 4 bytes.
[ 1024? Sprites ]
They use the same graphics the tilemaps use (16 x 16 x 4 tiles)
with 16 color codes and 2 levels of priority
***************************************************************************/
#include "emu.h"
#include "blmbycar.h"
#include "screen.h"
/***************************************************************************
Tilemaps
Offset: Bits: Value:
0.w Code
2.w fedc ba98 ---- ----
---- ---- 7--- ---- Flip Y
---- ---- -6-- ---- Flip X
---- ---- --5- ---- Priority (0 = Low)
---- ---- ---4 3210 Color
***************************************************************************/
#define DIM_NX (0x40)
#define DIM_NY (0x20)
template<int Layer>
TILE_GET_INFO_MEMBER(blmbycar_state::get_tile_info)
{
uint16_t code = m_vram[Layer][tile_index * 2 + 0];
uint16_t attr = m_vram[Layer][tile_index * 2 + 1];
tileinfo.set(0,
code,
attr & 0x1f,
TILE_FLIPYX((attr >> 6) & 3));
tileinfo.category = (attr >> 5) & 1;
}
/***************************************************************************
Video Init
***************************************************************************/
void blmbycar_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(blmbycar_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(blmbycar_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap[1]->set_transparent_pen(0);
}
/***************************************************************************
Screen Drawing
***************************************************************************/
uint32_t blmbycar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_sprites->draw_sprites(cliprect,m_spriteram,flip_screen());
m_tilemap[0]->set_scrolly(0, m_scroll[0][0]);
m_tilemap[0]->set_scrollx(0, m_scroll[0][1]);
m_tilemap[1]->set_scrolly(0, m_scroll[1][0] + 1);
m_tilemap[1]->set_scrollx(0, m_scroll[1][1] + 5);
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect);
m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
m_sprites->mix_sprites(bitmap, cliprect, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, 1, 1);
m_tilemap[1]->draw(screen, bitmap, cliprect, 1, 1);
m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, David Haywood
// copyright-holders: Manuel Abadia, David Haywood
/***************************************************************************
Glass (c) 1993 Gaelco (Developed by OMK. Produced by Gaelco)
@ -12,26 +13,289 @@ Todo:
***************************************************************************/
#include "emu.h"
#include "glass.h"
#include "gaelco_ds5002fp.h"
#include "cpu/m68000/m68000.h"
#include "cpu/mcs51/mcs51.h"
#include "machine/74259.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class glass_state : public driver_device
{
public:
glass_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_outlatch(*this, "outlatch"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_bmap(*this, "bmap"),
m_okibank(*this, "okibank"),
m_pant{ nullptr, nullptr },
m_blitter_command(0)
{ }
void glass(machine_config &config);
void glass_ds5002fp(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
// devices
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<ls259_device> m_outlatch;
// memory pointers
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_region_ptr<uint8_t> m_bmap;
required_memory_bank m_okibank;
// video-related
tilemap_t *m_pant[2]{};
std::unique_ptr<bitmap_ind16> m_screen_bitmap;
// misc
uint8_t m_current_bit = 0;
uint8_t m_cause_interrupt = 0;
uint8_t m_blitter_command = 0;
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
void clr_int_w(uint16_t data);
void oki_bankswitch_w(uint8_t data);
void coin_w(offs_t offset, uint16_t data);
void blitter_w(uint16_t data);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_lockout_w);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
template<int Layer> TILE_GET_INFO_MEMBER(get_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);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
};
// video
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (32*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | xxxxxxxx xxxxxxxx | code
1 | -------- ---xxxxx | color (uses colors 0x200-0x3ff)
1 | -------- --x----- | not used?
1 | -------- -x------ | flip x
1 | -------- x------- | flip y
1 | xxxxxxxx -------- | not used
*/
template<int Layer>
TILE_GET_INFO_MEMBER(glass_state::get_tile_info)
{
int const data = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1)];
int const data2 = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1) + 1];
int const code = ((data & 0x03) << 14) | ((data & 0x0fffc) >> 2);
tileinfo.set(0, code, 0x20 + (data2 & 0x1f), TILE_FLIPYX((data2 & 0xc0) >> 6));
}
/***************************************************************************
Blitter
***************************************************************************/
/*
The blitter is accessed writing 5 consecutive bits. The stream is: P0 P1 B2 B1 B0
if P0 is set, the hardware selects the first half of ROM H9 (girls)
if P1 is set, the hardware selects the second half of ROM H9 (boys)
B2B1B0 selects the picture (there are 8 pictures in each half of the ROM)
*/
void glass_state::blitter_w(uint16_t data)
{
m_blitter_command = ((m_blitter_command << 1) | (data & 0x01)) & 0x1f;
m_current_bit++;
if (m_current_bit == 5)
{
m_current_bit = 0;
// fill the screen bitmap with the current picture
{
uint8_t const *gfx = m_bmap + (m_blitter_command & 0x07) * 0x10000 + (m_blitter_command & 0x08) * 0x10000 + 0x140;
if ((m_blitter_command & 0x18) != 0)
{
for (int j = 0; j < 200; j++)
{
for (int i = 0; i < 320; i++)
{
int const color = *gfx;
gfx++;
m_screen_bitmap->pix(j, i) = color & 0xff;
}
}
}
else
m_screen_bitmap->fill(0);
}
}
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void glass_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_pant[offset >> 11]->mark_tile_dirty(((offset << 1) & 0x0fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void glass_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(glass_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(glass_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_screen_bitmap = std::make_unique<bitmap_ind16>(320, 200);
save_item(NAME(*m_screen_bitmap));
m_pant[0]->set_transparent_pen(0);
m_pant[1]->set_transparent_pen(0);
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | --xxxxxx -------- | not used?
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used?
2 | -------x xxxxxxxx | x position
2 | ---xxxx- -------- | sprite color (uses colors 0x100-0x1ff)
2 | xx------ -------- | not used?
3 | xxxxxxxx xxxxxxxx | sprite code
*/
void glass_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = m_gfxdecode->gfx(0);
for (int i = 3; i < (0x1000 - 6) / 2; i += 4)
{
int const sx = m_spriteram[i + 2] & 0x01ff;
int const sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int number = m_spriteram[i + 3];
int const color = (m_spriteram[i + 2] & 0x1e00) >> 9;
int const attr = (m_spriteram[i] & 0xfe00) >> 9;
int const xflip = attr & 0x20;
int const yflip = attr & 0x40;
number = ((number & 0x03) << 14) | ((number & 0x0fffc) >> 2);
gfx->transpen(bitmap, cliprect, number,
0x10 + (color & 0x0f), xflip, yflip,
sx - 0x0f, sy, 0);
}
}
/***************************************************************************
Display Refresh
****************************************************************************/
uint32_t glass_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// set scroll registers
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1] + 0x04);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
// draw layers + sprites
bitmap.fill(m_palette->black_pen(), cliprect);
copybitmap(bitmap, *m_screen_bitmap, 0, 0, 0x18, 0x24, cliprect);
m_pant[1]->draw(screen, bitmap, cliprect, 0, 0);
m_pant[0]->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}
// machine
void glass_state::shareram_w(offs_t offset, uint8_t data)
{
// why isn't there address map functionality for this?
reinterpret_cast<u8 *>(m_shareram.target())[BYTE_XOR_BE(offset)] = data;
reinterpret_cast<uint8_t *>(m_shareram.target())[BYTE_XOR_BE(offset)] = data;
}
uint8_t glass_state::shareram_r(offs_t offset)
{
// why isn't there address map functionality for this?
return reinterpret_cast<u8 const *>(m_shareram.target())[BYTE_XOR_BE(offset)];
return reinterpret_cast<uint8_t const *>(m_shareram.target())[BYTE_XOR_BE(offset)];
}
@ -52,9 +316,9 @@ INTERRUPT_GEN_MEMBER(glass_state::interrupt)
static const gfx_layout glass_tilelayout16 =
{
16,16, /* 16x16 tiles */
RGN_FRAC(1,2), /* number of tiles */
4, /* 4 bpp */
16,16, // 16x16 tiles
RGN_FRAC(1,2), // number of tiles
4, // 4 bpp
{ RGN_FRAC(1,2)+8, RGN_FRAC(1,2), 8, 0 },
{ STEP8(0,1), STEP8(8*2*16,1), },
{ STEP16(0,8*2) },
@ -76,24 +340,16 @@ void glass_state::coin_w(offs_t offset, uint16_t data)
m_outlatch->write_bit(offset >> 3, BIT(data, 0));
}
WRITE_LINE_MEMBER(glass_state::coin1_lockout_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(glass_state::coin_lockout_w)
{
machine().bookkeeping().coin_lockout_w(0, !state);
machine().bookkeeping().coin_lockout_w(Which, !state);
}
WRITE_LINE_MEMBER(glass_state::coin2_lockout_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(glass_state::coin_counter_w)
{
machine().bookkeeping().coin_lockout_w(1, !state);
}
WRITE_LINE_MEMBER(glass_state::coin1_counter_w)
{
machine().bookkeeping().coin_counter_w(0, state);
}
WRITE_LINE_MEMBER(glass_state::coin2_counter_w)
{
machine().bookkeeping().coin_counter_w(1, state);
machine().bookkeeping().coin_counter_w(Which, state);
}
@ -103,31 +359,31 @@ void glass_state::mcu_hostmem_map(address_map &map)
}
void glass_state::glass_map(address_map &map)
void glass_state::main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x101fff).ram().w(FUNC(glass_state::vram_w)).share("videoram"); // Video RAM
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x101fff).ram().w(FUNC(glass_state::vram_w)).share(m_videoram);
map(0x102000, 0x102fff).ram(); // Extra Video RAM
map(0x108000, 0x108007).writeonly().share("vregs"); // Video Registers
map(0x108008, 0x108009).w(FUNC(glass_state::clr_int_w)); // CLR INT Video
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
map(0x108000, 0x108007).writeonly().share(m_vregs);
map(0x108008, 0x108009).w(FUNC(glass_state::clr_int_w));
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x440000, 0x440fff).ram().share(m_spriteram);
map(0x700000, 0x700001).portr("DSW2");
map(0x700002, 0x700003).portr("DSW1");
map(0x700004, 0x700005).portr("P1");
map(0x700006, 0x700007).portr("P2");
map(0x700008, 0x700009).w(FUNC(glass_state::blitter_w)); // serial blitter
map(0x70000a, 0x70000b).select(0x000070).w(FUNC(glass_state::coin_w)); // Coin Counters/Lockout
map(0x70000d, 0x70000d).w(FUNC(glass_state::oki_bankswitch_w)); // OKI6295 bankswitch
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // OKI6295 status register
map(0xfec000, 0xfeffff).ram().share("shareram"); // Work RAM (partially shared with DS5002FP)
map(0x700008, 0x700009).w(FUNC(glass_state::blitter_w));
map(0x70000a, 0x70000b).select(0x000070).w(FUNC(glass_state::coin_w));
map(0x70000d, 0x70000d).w(FUNC(glass_state::oki_bankswitch_w));
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
map(0xfec000, 0xfeffff).ram().share(m_shareram); // Work RAM (partially shared with DS5002FP)
}
void glass_state::oki_map(address_map &map)
{
map(0x00000, 0x2ffff).rom();
map(0x30000, 0x3ffff).bankr("okibank");
map(0x30000, 0x3ffff).bankr(m_okibank);
}
@ -175,7 +431,7 @@ static INPUT_PORTS_START( glass )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x20, DEF_STR( On ) )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:2" ) /* Listed as "Unused" */
PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:2" ) // Listed as "Unused"
PORT_SERVICE_DIPLOC( 0x80, IP_ACTIVE_LOW, "SW2:1" )
PORT_START("P1")
@ -222,22 +478,22 @@ void glass_state::machine_reset()
void glass_state::glass(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(24'000'000)/2); /* 12 MHz verified on PCB */
m_maincpu->set_addrmap(AS_PROGRAM, &glass_state::glass_map);
// basic machine hardware
M68000(config, m_maincpu, XTAL(24'000'000) / 2); // 12 MHz verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &glass_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(glass_state::interrupt));
LS259(config, m_outlatch);
m_outlatch->q_out_cb<0>().set(FUNC(glass_state::coin1_lockout_w));
m_outlatch->q_out_cb<1>().set(FUNC(glass_state::coin2_lockout_w));
m_outlatch->q_out_cb<2>().set(FUNC(glass_state::coin1_counter_w));
m_outlatch->q_out_cb<3>().set(FUNC(glass_state::coin2_counter_w));
m_outlatch->q_out_cb<0>().set(FUNC(glass_state::coin_lockout_w<0>));
m_outlatch->q_out_cb<1>().set(FUNC(glass_state::coin_lockout_w<1>));
m_outlatch->q_out_cb<2>().set(FUNC(glass_state::coin_counter_w<0>));
m_outlatch->q_out_cb<3>().set(FUNC(glass_state::coin_counter_w<1>));
m_outlatch->q_out_cb<4>().set_nop(); // Sound Muting (if bit 0 == 1, sound output stream = 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(2500) /* not accurate */);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_size(32*16, 32*16);
screen.set_visarea(0, 368-1, 16, 256-1);
screen.set_screen_update(FUNC(glass_state::screen_update));
@ -246,10 +502,10 @@ void glass_state::glass(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_glass);
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); /* 1MHz Resonator & pin 7 high verified on PCB */
okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); // 1MHz Resonator & pin 7 high verified on PCB
oki.set_addrmap(0, &glass_state::oki_map);
oki.add_route(ALL_OUTPUTS, "mono", 1.0);
}
@ -257,117 +513,119 @@ void glass_state::glass(machine_config &config)
void glass_state::glass_ds5002fp(machine_config &config)
{
glass(config);
gaelco_ds5002fp_device &ds5002fp(GAELCO_DS5002FP(config, "gaelco_ds5002fp", XTAL(24'000'000) / 2)); /* verified on pcb */
gaelco_ds5002fp_device &ds5002fp(GAELCO_DS5002FP(config, "gaelco_ds5002fp", XTAL(24'000'000) / 2)); // verified on PCB
ds5002fp.set_addrmap(0, &glass_state::mcu_hostmem_map);
config.set_perfect_quantum("gaelco_ds5002fp:mcu");
}
ROM_START( glass ) /* Version 1.1 */
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_START( glass ) // Version 1.1
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "1.c23", 0x000000, 0x040000, CRC(aeebd4ed) SHA1(04759dc146dff0fc74b78d70e79dfaebe68328f9) )
ROM_LOAD16_BYTE( "2.c22", 0x000001, 0x040000, CRC(165e2e01) SHA1(180a2e2b5151f2321d85ac23eff7fbc9f52023a5) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "glass_ds5002fp_sram.bin", 0x00000, 0x8000, CRC(47c9df4c) SHA1(e0ac4f3d3086a4e8164d42aaae125037c222118a) )
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
/* these are the default states stored in NVRAM */
// these are the default states stored in NVRAM
DS5002FP_SET_MON( 0x29 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x400000, "gfx", 0 ) /* Graphics */
ROM_REGION( 0x400000, "gfx", 0 )
ROM_LOAD( "h13.bin", 0x000000, 0x200000, CRC(13ab7f31) SHA1(468424f74d6cccd1b445a9f20e2d24bc46d61ed6) )
ROM_LOAD( "h11.bin", 0x200000, 0x200000, CRC(c6ac41c8) SHA1(22408ef1e35c66d0fba0c72972c46fad891d1193) )
ROM_REGION( 0x100000, "bmap", 0 ) /* 16 bitmaps (320x200, indexed colors) */
ROM_REGION( 0x100000, "bmap", 0 ) // 16 bitmaps (320x200, indexed colors)
ROM_LOAD( "h9.bin", 0x000000, 0x100000, CRC(b9492557) SHA1(3f5c0d696d65e1cd492763dfa749c813dd56a9bf) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "c1.bin", 0x000000, 0x100000, CRC(d9f075a2) SHA1(31a7a677861f39d512e9d1f51925c689e481159a) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_END
ROM_START( glass10 ) /* Version 1.0 */
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_START( glass10 ) // Version 1.0
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c23.bin", 0x000000, 0x040000, CRC(688cdf33) SHA1(b59dcc3fc15f72037692b745927b110e97d8282e) )
ROM_LOAD16_BYTE( "c22.bin", 0x000001, 0x040000, CRC(ab17c992) SHA1(1509b5b4bbfb4e022e0ab6fbbc0ffc070adfa531) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "glass_ds5002fp_sram.bin", 0x00000, 0x8000, CRC(47c9df4c) SHA1(e0ac4f3d3086a4e8164d42aaae125037c222118a) )
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
/* these are the default states stored in NVRAM */
// these are the default states stored in NVRAM
DS5002FP_SET_MON( 0x29 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x400000, "gfx", 0 ) /* Graphics */
ROM_REGION( 0x400000, "gfx", 0 )
ROM_LOAD( "h13.bin", 0x000000, 0x200000, CRC(13ab7f31) SHA1(468424f74d6cccd1b445a9f20e2d24bc46d61ed6) )
ROM_LOAD( "h11.bin", 0x200000, 0x200000, CRC(c6ac41c8) SHA1(22408ef1e35c66d0fba0c72972c46fad891d1193) )
ROM_REGION( 0x100000, "bmap", 0 ) /* 16 bitmaps (320x200, indexed colors) */
ROM_REGION( 0x100000, "bmap", 0 ) // 16 bitmaps (320x200, indexed colors)
ROM_LOAD( "h9.bin", 0x000000, 0x100000, CRC(b9492557) SHA1(3f5c0d696d65e1cd492763dfa749c813dd56a9bf) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "c1.bin", 0x000000, 0x100000, CRC(d9f075a2) SHA1(31a7a677861f39d512e9d1f51925c689e481159a) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_END
ROM_START( glass10a ) /* Title screen shows "GLASS" and under that "Break Edition" on a real PCB */
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_START( glass10a ) // Title screen shows "GLASS" and under that "Break Edition" on a real PCB
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "spl-c23.bin", 0x000000, 0x040000, CRC(c1393bea) SHA1(a5f877ba38305a7b49fa3c96b9344cbf71e8c9ef) )
ROM_LOAD16_BYTE( "spl-c22.bin", 0x000001, 0x040000, CRC(0d6fa33e) SHA1(37e9258ef7e108d034c80abc8e5e5ab6dacf0a61) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "glass_ds5002fp_sram.bin", 0x00000, 0x8000, CRC(47c9df4c) SHA1(e0ac4f3d3086a4e8164d42aaae125037c222118a) )
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
/* these are the default states stored in NVRAM */
// these are the default states stored in NVRAM
DS5002FP_SET_MON( 0x29 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x400000, "gfx", 0 ) /* Graphics */
ROM_REGION( 0x400000, "gfx", 0 )
ROM_LOAD( "h13.bin", 0x000000, 0x200000, CRC(13ab7f31) SHA1(468424f74d6cccd1b445a9f20e2d24bc46d61ed6) )
ROM_LOAD( "h11.bin", 0x200000, 0x200000, CRC(c6ac41c8) SHA1(22408ef1e35c66d0fba0c72972c46fad891d1193) )
ROM_REGION( 0x100000, "bmap", 0 ) /* 16 bitmaps (320x200, indexed colors) */
ROM_REGION( 0x100000, "bmap", 0 ) // 16 bitmaps (320x200, indexed colors)
ROM_LOAD( "h9.bin", 0x000000, 0x100000, CRC(b9492557) SHA1(3f5c0d696d65e1cd492763dfa749c813dd56a9bf) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "c1.bin", 0x000000, 0x100000, CRC(d9f075a2) SHA1(31a7a677861f39d512e9d1f51925c689e481159a) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_END
ROM_START( glasskr )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "glassk.c23", 0x000000, 0x080000, CRC(6ee19376) SHA1(8a8fdeebe094bd3e29c35cf59584e3cab708732d) )
ROM_LOAD16_BYTE( "glassk.c22", 0x000001, 0x080000, CRC(bd546568) SHA1(bcd5e7591f4e68c9470999b8a0ef1ee4392c907c) )
ROM_REGION( 0x400000, "gfx", 0 ) /* Graphics */
ROM_REGION( 0x400000, "gfx", 0 )
ROM_LOAD( "h13.bin", 0x000000, 0x200000, CRC(13ab7f31) SHA1(468424f74d6cccd1b445a9f20e2d24bc46d61ed6) )
ROM_LOAD( "h11.bin", 0x200000, 0x200000, CRC(c6ac41c8) SHA1(22408ef1e35c66d0fba0c72972c46fad891d1193) )
ROM_REGION( 0x100000, "bmap", 0 ) /* 16 bitmaps (320x200, indexed colors) */
ROM_REGION( 0x100000, "bmap", 0 ) // 16 bitmaps (320x200, indexed colors)
ROM_LOAD( "glassk.h9", 0x000000, 0x100000, CRC(d499be4c) SHA1(204f754813be687e8dc00bfe7b5dbc4857ac8738) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "c1.bin", 0x000000, 0x100000, CRC(d9f075a2) SHA1(31a7a677861f39d512e9d1f51925c689e481159a) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_END
} // anonymous namespace
/*
ALL versions of Glass contain the 'Break Edition' string (it just seems to be part of the title?)
The 2 version 1.0 releases are very similar code, it was thought that one was a break edition and the other wasn't, but this is not the case.
Version 1.1 releases also show Version 1994 on the title screen. These versions do not have skulls in the playfield (at least not on early stages)
The protected version 1.1 also doesn't show any kind of attract gameplay, looks like it was patched out? (should be verified on an untouched original 1.1 using it's original SRAM tho)
The protected version 1.1 also doesn't show any kind of attract gameplay, looks like it was patched out? (should be verified on an untouched original 1.1 using its original SRAM tho)
The unprotected version appears to be a Korean set, is censored, and has different girl pictures.
*/
GAME( 1994, glass, 0, glass_ds5002fp, glass, glass_state, empty_init, ROT0, "OMK / Gaelco", "Glass (Ver 1.1, Break Edition, Checksum 49D5E66B, Version 1994)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, glasskr, glass, glass, glass, glass_state, empty_init, ROT0, "OMK / Gaelco (Promat license)", "Glass (Ver 1.1, Break Edition, Checksum D419AB69, Version 1994) (censored, unprotected)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS ) // promat stickers on program roms
GAME( 1993, glass10, glass, glass_ds5002fp, glass, glass_state, empty_init, ROT0, "OMK / Gaelco", "Glass (Ver 1.0, Break Edition, Checksum C5513F3C)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1993, glass10a, glass, glass_ds5002fp, glass, glass_state, empty_init, ROT0, "OMK / Gaelco", "Glass (Ver 1.0, Break Edition, Checksum D3864FDB)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, glasskr, glass, glass, glass, glass_state, empty_init, ROT0, "OMK / Gaelco (Promat license)", "Glass (Ver 1.1, Break Edition, Checksum D419AB69, Version 1994) (censored, unprotected)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS ) // promat stickers on program ROMs
GAME( 1993, glass10, glass, glass_ds5002fp, glass, glass_state, empty_init, ROT0, "OMK / Gaelco", "Glass (Ver 1.0, Break Edition, Checksum C5513F3C)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1993, glass10a, glass, glass_ds5002fp, glass, glass_state, empty_init, ROT0, "OMK / Gaelco", "Glass (Ver 1.0, Break Edition, Checksum D3864FDB)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )

View File

@ -1,84 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
/*************************************************************************
Glass
*************************************************************************/
#include "machine/74259.h"
#include "emupal.h"
#include "tilemap.h"
class glass_state : public driver_device
{
public:
glass_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_outlatch(*this, "outlatch"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_bmap(*this, "bmap"),
m_okibank(*this, "okibank"),
m_pant{ nullptr, nullptr },
m_blitter_command(0)
{ }
void glass(machine_config &config);
void glass_ds5002fp(machine_config &config);
private:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<ls259_device> m_outlatch;
/* memory pointers */
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_region_ptr<uint8_t> m_bmap;
required_memory_bank m_okibank;
/* video-related */
tilemap_t *m_pant[2]{};
std::unique_ptr<bitmap_ind16> m_screen_bitmap;
/* misc */
int m_current_bit = 0;
int m_cause_interrupt = 0;
int m_blitter_command = 0;
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
void clr_int_w(uint16_t data);
void oki_bankswitch_w(uint8_t data);
void coin_w(offs_t offset, uint16_t data);
void blitter_w(uint16_t data);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
DECLARE_WRITE_LINE_MEMBER(coin1_lockout_w);
DECLARE_WRITE_LINE_MEMBER(coin2_lockout_w);
DECLARE_WRITE_LINE_MEMBER(coin1_counter_w);
DECLARE_WRITE_LINE_MEMBER(coin2_counter_w);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
template<int Layer> TILE_GET_INFO_MEMBER(get_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 glass_map(address_map &map);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
};

View File

@ -1,192 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
/***************************************************************************
Glass Video Hardware
Functions to emulate the video hardware of the machine
***************************************************************************/
#include "emu.h"
#include "glass.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (32*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | xxxxxxxx xxxxxxxx | code
1 | -------- ---xxxxx | color (uses colors 0x200-0x3ff)
1 | -------- --x----- | not used?
1 | -------- -x------ | flip x
1 | -------- x------- | flip y
1 | xxxxxxxx -------- | not used
*/
template<int Layer>
TILE_GET_INFO_MEMBER(glass_state::get_tile_info)
{
int data = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1)];
int data2 = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1) + 1];
int code = ((data & 0x03) << 14) | ((data & 0x0fffc) >> 2);
tileinfo.set(0, code, 0x20 + (data2 & 0x1f), TILE_FLIPYX((data2 & 0xc0) >> 6));
}
/***************************************************************************
Blitter
***************************************************************************/
/*
The blitter is accessed writing 5 consecutive bits. The stream is: P0 P1 B2 B1 B0
if P0 is set, the hardware selects the first half of ROM H9 (girls)
if P1 is set, the hardware selects the second half of ROM H9 (boys)
B2B1B0 selects the picture (there are 8 pictures in each half of the ROM)
*/
void glass_state::blitter_w(uint16_t data)
{
m_blitter_command = ((m_blitter_command << 1) | (data & 0x01)) & 0x1f;
m_current_bit++;
if (m_current_bit == 5)
{
m_current_bit = 0;
/* fill the screen bitmap with the current picture */
{
uint8_t const *gfx = m_bmap + (m_blitter_command & 0x07) * 0x10000 + (m_blitter_command & 0x08) * 0x10000 + 0x140;
if ((m_blitter_command & 0x18) != 0)
{
for (int j = 0; j < 200; j++)
{
for (int i = 0; i < 320; i++)
{
int const color = *gfx;
gfx++;
m_screen_bitmap->pix(j, i) = color & 0xff;
}
}
}
else
m_screen_bitmap->fill(0);
}
}
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void glass_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_pant[offset >> 11]->mark_tile_dirty(((offset << 1) & 0x0fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void glass_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(glass_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(glass_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_screen_bitmap = std::make_unique<bitmap_ind16>(320, 200);
save_item(NAME(*m_screen_bitmap));
m_pant[0]->set_transparent_pen(0);
m_pant[1]->set_transparent_pen(0);
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | --xxxxxx -------- | not used?
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used?
2 | -------x xxxxxxxx | x position
2 | ---xxxx- -------- | sprite color (uses colors 0x100-0x1ff)
2 | xx------ -------- | not used?
3 | xxxxxxxx xxxxxxxx | sprite code
*/
void glass_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
{
int i;
gfx_element *gfx = m_gfxdecode->gfx(0);
for (i = 3; i < (0x1000 - 6) / 2; i += 4)
{
int sx = m_spriteram[i + 2] & 0x01ff;
int sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int number = m_spriteram[i + 3];
int color = (m_spriteram[i + 2] & 0x1e00) >> 9;
int attr = (m_spriteram[i] & 0xfe00) >> 9;
int xflip = attr & 0x20;
int yflip = attr & 0x40;
number = ((number & 0x03) << 14) | ((number & 0x0fffc) >> 2);
gfx->transpen(bitmap,cliprect,number,
0x10 + (color & 0x0f),xflip,yflip,
sx-0x0f,sy,0);
}
}
/***************************************************************************
Display Refresh
****************************************************************************/
uint32_t glass_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* set scroll registers */
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1] + 0x04);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
/* draw layers + sprites */
bitmap.fill(m_palette->black_pen(), cliprect);
copybitmap(bitmap, *m_screen_bitmap, 0, 0, 0x18, 0x24, cliprect);
m_pant[1]->draw(screen, bitmap, cliprect, 0, 0);
m_pant[0]->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, David Haywood
// copyright-holders: Manuel Abadia, David Haywood
/***************************************************************************
Target Hits (c) 1994 Gaelco (Designed & Developed by Zigurat. Produced by Gaelco)
@ -58,47 +59,246 @@ DS5002FP Box contains:
3.6v Battery
JP1 - 5 pin port to program SRAM
* NOTE: PCB can use four 27C040 eproms at I7, I9, I11 & I13 or two 8Meg MASK
roms at H8 & H12. Same set up as used on the World Rally PCBs
* NOTE: PCB can use four 27C040 EPROMs at I7, I9, I11 & I13 or two 8Meg MASK
ROMs at H8 & H12. Same set up as used on the World Rally PCBs
***************************************************************************/
#include "emu.h"
#include "targeth.h"
#include "gaelco_ds5002fp.h"
#include "cpu/mcs51/mcs51.h"
#include "cpu/m68000/m68000.h"
#include "machine/74259.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class targeth_state : public driver_device
{
public:
targeth_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_screen(*this, "screen"),
m_palette(*this, "palette"),
m_outlatch(*this, "outlatch"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_okibank(*this, "okibank")
{ }
void targeth(machine_config &config);
protected:
virtual void video_start() override;
virtual void machine_start() override;
private:
void oki_bankswitch_w(uint8_t data);
void output_latch_w(offs_t offset, uint16_t data);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
void vram_w(offs_t offset, uint16_t data);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
TIMER_CALLBACK_MEMBER(gun1_irq);
TIMER_CALLBACK_MEMBER(gun2_irq);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
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_device<ls259_device> m_outlatch;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_memory_bank m_okibank;
emu_timer *m_gun_irq_timer[2]{};
tilemap_t *m_pant[2]{};
};
// video
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (64*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | --xxxxxx xxxxxxxx | code
0 | xx------ -------- | not used?
1 | -------- ---xxxxx | color (uses 1st half of the palette)
1 | -------- --x----- | flip y
1 | -------- -x------ | flip x
1 | xxxxxxxx x------- | not used?
*/
template<int Layer>
TILE_GET_INFO_MEMBER(targeth_state::get_tile_info)
{
int const data = m_videoram[(Layer * 0x2000 / 2) + (tile_index << 1)];
int const data2 = m_videoram[(Layer * 0x2000 / 2) + (tile_index << 1) + 1];
int const code = data & 0x3fff;
tileinfo.set(0, code, data2 & 0x1f, TILE_FLIPXY((data2 >> 5) & 0x03));
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void targeth_state::vram_w(offs_t offset, uint16_t data)
{
m_videoram[offset] = data;
m_pant[(offset & 0x1fff) >> 12]->mark_tile_dirty(((offset << 1) & 0x1fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void targeth_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(targeth_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(targeth_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_pant[0]->set_transparent_pen(0);
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | --xxxxxx -------- | not used?
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used?
2 | ------xx xxxxxxxx | x position
2 | -xxxxx-- -------- | sprite color (uses 2nd half of the palette)
3 | --xxxxxx xxxxxxxx | sprite code
3 | xx------ -------- | not used?
*/
void targeth_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = m_gfxdecode->gfx(0);
for (int i = 3; i < (0x1000 - 6)/2; i += 4){
int const sx = m_spriteram[i+2] & 0x03ff;
int const sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int const number = m_spriteram[i+3] & 0x3fff;
int const color = (m_spriteram[i+2] & 0x7c00) >> 10;
int const attr = (m_spriteram[i] & 0xfe00) >> 9;
int const xflip = attr & 0x20;
int const yflip = attr & 0x40;
gfx->transpen(bitmap, cliprect, number,
0x20 + color, xflip, yflip,
sx - 0x0f, sy, 0);
}
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t targeth_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// set scroll registers
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1] + 0x04);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
m_pant[1]->draw(screen, bitmap, cliprect, 0, 0);
m_pant[0]->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap,cliprect);
return 0;
}
// machine
static const gfx_layout tilelayout =
{
16,16, /* 16x16 tiles */
RGN_FRAC(1,4), /* number of tiles */
4, /* bitplanes */
{ RGN_FRAC(3,4), RGN_FRAC(2,4), RGN_FRAC(1,4), RGN_FRAC(0,4) }, /* plane offsets */
16,16, // 16x16 tiles
RGN_FRAC(1,4), // number of tiles
4, // bitplanes
{ RGN_FRAC(3,4), RGN_FRAC(2,4), RGN_FRAC(1,4), RGN_FRAC(0,4) }, // plane offsets
{ STEP8(0,1), STEP8(16*8,1) },
{ STEP16(0,8) },
32*8
};
static GFXDECODE_START( gfx_targeth )
GFXDECODE_ENTRY( "gfx1", 0x000000, tilelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx", 0x000000, tilelayout, 0, 64 )
GFXDECODE_END
TIMER_CALLBACK_MEMBER(targeth_state::gun1_irq)
{
/* IRQ 4: Read 1P Gun */
// IRQ 4: Read 1P Gun
m_maincpu->set_input_line(4, HOLD_LINE);
m_gun_irq_timer[0]->adjust( m_screen->time_until_pos(128, 0 ) );
}
TIMER_CALLBACK_MEMBER(targeth_state::gun2_irq)
{
/* IRQ 6: Read 2P Gun */
// IRQ 6: Read 2P Gun
m_maincpu->set_input_line(6, HOLD_LINE);
m_gun_irq_timer[1]->adjust( m_screen->time_until_pos(160, 0 ) );
}
@ -113,26 +313,22 @@ void targeth_state::output_latch_w(offs_t offset, uint16_t data)
m_outlatch->write_bit(offset >> 3, BIT(data, 0));
}
WRITE_LINE_MEMBER(targeth_state::coin1_counter_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(targeth_state::coin_counter_w)
{
machine().bookkeeping().coin_counter_w(0, state);
}
WRITE_LINE_MEMBER(targeth_state::coin2_counter_w)
{
machine().bookkeeping().coin_counter_w(1, state);
machine().bookkeeping().coin_counter_w(Which, state);
}
void targeth_state::shareram_w(offs_t offset, uint8_t data)
{
// why isn't there address map functionality for this?
util::big_endian_cast<u8>(m_shareram.target())[offset] = data;
util::big_endian_cast<uint8_t>(m_shareram.target())[offset] = data;
}
uint8_t targeth_state::shareram_r(offs_t offset)
{
// why isn't there address map functionality for this?
return util::big_endian_cast<u8 const>(m_shareram.target())[offset];
return util::big_endian_cast<uint8_t const>(m_shareram.target())[offset];
}
@ -144,32 +340,32 @@ void targeth_state::mcu_hostmem_map(address_map &map)
void targeth_state::main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x103fff).ram().w(FUNC(targeth_state::vram_w)).share("videoram"); /* Video RAM */
map(0x100000, 0x103fff).ram().w(FUNC(targeth_state::vram_w)).share(m_videoram);
map(0x108000, 0x108001).portr("GUNX1");
map(0x108002, 0x108003).portr("GUNY1");
map(0x108004, 0x108005).portr("GUNX2");
map(0x108006, 0x108007).portr("GUNY2");
map(0x108000, 0x108007).writeonly().share("vregs"); /* Video Registers */
map(0x108000, 0x108007).writeonly().share(m_vregs);
map(0x10800c, 0x10800d).nopw(); /* CLR Video INT */
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); /* Palette */
map(0x440000, 0x440fff).ram().share("spriteram"); /* Sprite RAM */
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x440000, 0x440fff).ram().share(m_spriteram);
map(0x700000, 0x700001).portr("DSW2");
map(0x700002, 0x700003).portr("DSW1");
map(0x700006, 0x700007).portr("SYSTEM"); /* Coins, Start & Fire buttons */
map(0x700008, 0x700009).portr("SERVICE"); /* Service & Guns Reload? */
map(0x700006, 0x700007).portr("SYSTEM"); // Coins, Start & Fire buttons
map(0x700008, 0x700009).portr("SERVICE"); // Service & Guns Reload?
map(0x70000a, 0x70000b).select(0x000070).w(FUNC(targeth_state::output_latch_w));
map(0x70000d, 0x70000d).w(FUNC(targeth_state::oki_bankswitch_w)); /* OKI6295 bankswitch */
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); /* OKI6295 status register */
map(0x700010, 0x700011).nopw(); /* ??? Guns reload related? */
map(0xfe0000, 0xfe7fff).ram(); /* Work RAM */
map(0xfe8000, 0xfeffff).ram().share("shareram"); /* Work RAM (shared with D5002FP) */
map(0x70000d, 0x70000d).w(FUNC(targeth_state::oki_bankswitch_w));
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
map(0x700010, 0x700011).nopw(); // ??? Guns reload related?
map(0xfe0000, 0xfe7fff).ram(); // Work RAM
map(0xfe8000, 0xfeffff).ram().share(m_shareram); // Work RAM (shared with D5002FP)
}
void targeth_state::oki_map(address_map &map)
{
map(0x00000, 0x2ffff).rom();
map(0x30000, 0x3ffff).bankr("okibank");
map(0x30000, 0x3ffff).bankr(m_okibank);
}
void targeth_state::machine_start()
@ -243,7 +439,7 @@ static INPUT_PORTS_START( targeth )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x20, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, "Gun alarm" ) /* Service mode gets default from here when uninitialized */
PORT_DIPNAME( 0x40, 0x40, "Gun alarm" ) // Service mode gets default from here when uninitialized
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_SERVICE( 0x80, IP_ACTIVE_LOW )
@ -261,17 +457,17 @@ static INPUT_PORTS_START( targeth )
PORT_START("SERVICE")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* this MUST be low or the game doesn't boot */
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) /* Reload 1P? */
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) /* Reload 2P? */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) // this MUST be low or the game doesn't boot
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) // Reload 1P?
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) // Reload 2P?
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
void targeth_state::targeth(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(24'000'000)/2); /* 12 MHz */
// basic machine hardware
M68000(config, m_maincpu, XTAL(24'000'000) / 2); // 12 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &targeth_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(targeth_state::irq2_line_hold));
@ -280,13 +476,13 @@ void targeth_state::targeth(machine_config &config)
config.set_perfect_quantum("gaelco_ds5002fp:mcu");
LS259(config, m_outlatch);
m_outlatch->q_out_cb<2>().set(FUNC(targeth_state::coin1_counter_w));
m_outlatch->q_out_cb<3>().set(FUNC(targeth_state::coin2_counter_w));
m_outlatch->q_out_cb<2>().set(FUNC(targeth_state::coin_counter_w<0>));
m_outlatch->q_out_cb<3>().set(FUNC(targeth_state::coin_counter_w<1>));
/* video hardware */
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
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(64*16, 16*16);
m_screen->set_visarea(3*8, 23*16-8-1, 16, 16*16-8-1);
m_screen->set_screen_update(FUNC(targeth_state::screen_update));
@ -295,7 +491,7 @@ void targeth_state::targeth(machine_config &config)
GFXDECODE(config, "gfxdecode", m_palette, gfx_targeth);
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); // 1MHz resonator - pin 7 not verified
@ -304,11 +500,11 @@ void targeth_state::targeth(machine_config &config)
}
ROM_START( targeth )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "th2_b_c_23.c23", 0x000000, 0x040000, CRC(840887d6) SHA1(9a36b346608d531a62a2e0704ea44f12e07f9d91) ) // The "B" was hand written
ROM_LOAD16_BYTE( "th2_b_c_22.c22", 0x000001, 0x040000, CRC(d2435eb8) SHA1(ce75a115dad8019c8e66a1c3b3e15f54781f65ae) ) // The "B" was hand written
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "targeth_ds5002fp.bin", 0x00000, 0x8000, CRC(abcdfee4) SHA1(c5955d5dbbcecbe1c2ae77d59671ae40eb814d30) )
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
@ -317,15 +513,15 @@ ROM_START( targeth )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 ) /* Graphics */
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD( "targeth.i13", 0x000000, 0x080000, CRC(b892be24) SHA1(9cccaaacf20e77c7358f0ceac60b8a1012f1216c) )
ROM_LOAD( "targeth.i11", 0x080000, 0x080000, CRC(6797faf9) SHA1(112cffe72f91cb46c262e19a47b0cab3237dd60f) )
ROM_LOAD( "targeth.i9", 0x100000, 0x080000, CRC(0e922c1c) SHA1(6920e345c82e76f7e0af6101f39eb65ac1f112b9) )
ROM_LOAD( "targeth.i7", 0x180000, 0x080000, CRC(d8b41000) SHA1(cbe91eb91bdc7a60b2333c6bea37d08a57902669) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "targeth.c1", 0x000000, 0x080000, CRC(d6c9dfbc) SHA1(3ec70dea94fc89df933074012a52de6034571e87) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_LOAD( "targeth.c3", 0x080000, 0x080000, CRC(d4c771df) SHA1(7cc0a86ef6aa3d26ab8f19d198f62112bf012870) )
ROM_END
@ -343,24 +539,24 @@ ROM_START( targetha )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 ) /* Graphics */
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD( "targeth.i13", 0x000000, 0x080000, CRC(b892be24) SHA1(9cccaaacf20e77c7358f0ceac60b8a1012f1216c) )
ROM_LOAD( "targeth.i11", 0x080000, 0x080000, CRC(6797faf9) SHA1(112cffe72f91cb46c262e19a47b0cab3237dd60f) )
ROM_LOAD( "targeth.i9", 0x100000, 0x080000, CRC(0e922c1c) SHA1(6920e345c82e76f7e0af6101f39eb65ac1f112b9) )
ROM_LOAD( "targeth.i7", 0x180000, 0x080000, CRC(d8b41000) SHA1(cbe91eb91bdc7a60b2333c6bea37d08a57902669) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "targeth.c1", 0x000000, 0x080000, CRC(d6c9dfbc) SHA1(3ec70dea94fc89df933074012a52de6034571e87) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_LOAD( "targeth.c3", 0x080000, 0x080000, CRC(d4c771df) SHA1(7cc0a86ef6aa3d26ab8f19d198f62112bf012870) )
ROM_END
ROM_START( targeth10 )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c23.bin", 0x000000, 0x040000, CRC(e38a54e2) SHA1(239bfa6f1c0fc8aa0ad7de9be237bef55b384007) )
ROM_LOAD16_BYTE( "c22.bin", 0x000001, 0x040000, CRC(24fe3efb) SHA1(8f48f08a6db28966c9263be119883c9179e349ed) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "targeth_ds5002fp.bin", 0x00000, 0x8000, CRC(abcdfee4) SHA1(c5955d5dbbcecbe1c2ae77d59671ae40eb814d30) )
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
@ -369,18 +565,21 @@ ROM_START( targeth10 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 ) /* Graphics */
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD( "targeth.i13", 0x000000, 0x080000, CRC(b892be24) SHA1(9cccaaacf20e77c7358f0ceac60b8a1012f1216c) )
ROM_LOAD( "targeth.i11", 0x080000, 0x080000, CRC(6797faf9) SHA1(112cffe72f91cb46c262e19a47b0cab3237dd60f) )
ROM_LOAD( "targeth.i9", 0x100000, 0x080000, CRC(0e922c1c) SHA1(6920e345c82e76f7e0af6101f39eb65ac1f112b9) )
ROM_LOAD( "targeth.i7", 0x180000, 0x080000, CRC(d8b41000) SHA1(cbe91eb91bdc7a60b2333c6bea37d08a57902669) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "targeth.c1", 0x000000, 0x080000, CRC(d6c9dfbc) SHA1(3ec70dea94fc89df933074012a52de6034571e87) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched from all the ROMs
ROM_LOAD( "targeth.c3", 0x080000, 0x080000, CRC(d4c771df) SHA1(7cc0a86ef6aa3d26ab8f19d198f62112bf012870) )
ROM_END
GAME( 1994, targeth, 0, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.1, Checksum 5152)", 0 )
GAME( 1994, targetha, targeth, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.1, Checksum 86E1)", 0 )
GAME( 1994, targeth10, targeth, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.0, Checksum FBCB)", 0 )
} // anonymous namespace
GAME( 1994, targeth, 0, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.1, Checksum 5152)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, targetha, targeth, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.1, Checksum 86E1)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, targeth10, targeth, targeth, targeth, targeth_state, empty_init, ROT0, "Gaelco", "Target Hits (ver 1.0, Checksum FBCB)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,76 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
#ifndef MAME_INCLUDES_TARGETH_H
#define MAME_INCLUDES_TARGETH_H
#pragma once
#include "machine/74259.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
class targeth_state : public driver_device
{
public:
targeth_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_screen(*this, "screen"),
m_palette(*this, "palette"),
m_outlatch(*this, "outlatch"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_okibank(*this, "okibank")
{ }
void targeth(machine_config &config);
private:
void oki_bankswitch_w(uint8_t data);
void output_latch_w(offs_t offset, uint16_t data);
DECLARE_WRITE_LINE_MEMBER(coin1_counter_w);
DECLARE_WRITE_LINE_MEMBER(coin2_counter_w);
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
void vram_w(offs_t offset, uint16_t data);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
TIMER_CALLBACK_MEMBER(gun1_irq);
TIMER_CALLBACK_MEMBER(gun2_irq);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
virtual void video_start() override;
virtual void machine_start() override;
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
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_device<ls259_device> m_outlatch;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_memory_bank m_okibank;
emu_timer *m_gun_irq_timer[2]{};
tilemap_t *m_pant[2]{};
};
#endif // MAME_INCLUDES_TARGETH_H

View File

@ -1,137 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
/***************************************************************************
Target Hits Video Hardware
Functions to emulate the video hardware of the machine
***************************************************************************/
#include "emu.h"
#include "targeth.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (64*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | --xxxxxx xxxxxxxx | code
0 | xx------ -------- | not used?
1 | -------- ---xxxxx | color (uses 1st half of the palette)
1 | -------- --x----- | flip y
1 | -------- -x------ | flip x
1 | xxxxxxxx x------- | not used?
*/
template<int Layer>
TILE_GET_INFO_MEMBER(targeth_state::get_tile_info)
{
int data = m_videoram[(Layer * 0x2000/2) + (tile_index << 1)];
int data2 = m_videoram[(Layer * 0x2000/2) + (tile_index << 1) + 1];
int code = data & 0x3fff;
tileinfo.set(0, code, data2 & 0x1f, TILE_FLIPXY((data2 >> 5) & 0x03));
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void targeth_state::vram_w(offs_t offset, uint16_t data)
{
m_videoram[offset] = data;
m_pant[(offset & 0x1fff) >> 12]->mark_tile_dirty(((offset << 1) & 0x1fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void targeth_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(targeth_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(targeth_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_pant[0]->set_transparent_pen(0);
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | --xxxxxx -------- | not used?
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used?
2 | ------xx xxxxxxxx | x position
2 | -xxxxx-- -------- | sprite color (uses 2nd half of the palette)
3 | --xxxxxx xxxxxxxx | sprite code
3 | xx------ -------- | not used?
*/
void targeth_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = m_gfxdecode->gfx(0);
for (int i = 3; i < (0x1000 - 6)/2; i += 4){
int sx = m_spriteram[i+2] & 0x03ff;
int sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int number = m_spriteram[i+3] & 0x3fff;
int color = (m_spriteram[i+2] & 0x7c00) >> 10;
int attr = (m_spriteram[i] & 0xfe00) >> 9;
int xflip = attr & 0x20;
int yflip = attr & 0x40;
gfx->transpen(bitmap,cliprect,number,
0x20 + color,xflip,yflip,
sx - 0x0f,sy,0);
}
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t targeth_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* set scroll registers */
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1] + 0x04);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
m_pant[1]->draw(screen, bitmap, cliprect, 0,0);
m_pant[0]->draw(screen, bitmap, cliprect, 0,0);
draw_sprites(bitmap,cliprect);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Peter Ferrie, David Haywood
// copyright-holders: Manuel Abadia, Peter Ferrie, David Haywood
/***************************************************************************
Thunder Hoop II: Strikes Back (c) 1994 Gaelco
@ -55,7 +56,6 @@ Measurements from actual PCB:
***************************************************************************/
#include "emu.h"
#include "thoop2.h"
#include "gaelco_ds5002fp.h"
@ -65,10 +65,278 @@ Measurements from actual PCB:
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class thoop2_state : public driver_device
{
public:
thoop2_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_pant{ nullptr, nullptr },
m_maincpu(*this, "maincpu"),
m_outlatch(*this, "outlatch"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_okibank(*this, "okibank"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram")
{ }
void thoop2(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
void oki_bankswitch_w(uint8_t data);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_lockout_w);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
void thoop2_map(address_map &map);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
tilemap_t *m_pant[2]{};
required_device<cpu_device> m_maincpu;
required_device<ls259_device> m_outlatch;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_memory_bank m_okibank;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
};
// video
/***************************************************************************
Gaelco Type 1 Video Hardware Rev B
The video hardware is nearly identical to the previous
revision but it can handle more tiles and more sprites
***************************************************************************/
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (32*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- ------xx | code (high bits)
0 | xxxxxxxx xxxxxx-- | code (low bits)
1 | -------- --xxxxxx | color
1 | -------- xx------ | priority
1 | --xxxxxx -------- | not used
1 | -x------ -------- | flip x
1 | x------- -------- | flip y
*/
template<int Layer>
TILE_GET_INFO_MEMBER(thoop2_state::get_tile_info)
{
int const data = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1)];
int const data2 = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1) + 1];
int const code = ((data & 0xfffc) >> 2) | ((data & 0x0003) << 14);
tileinfo.category = (data2 >> 6) & 0x03;
tileinfo.set(1, code, data2 & 0x3f, TILE_FLIPYX((data2 >> 14) & 0x03));
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void thoop2_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_pant[offset >> 11]->mark_tile_dirty(((offset << 1) & 0x0fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void thoop2_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(thoop2_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(thoop2_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_pant[0]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
m_pant[1]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | -----xxx -------- | not used
0 | ----x--- -------- | sprite size
0 | --xx---- -------- | sprite priority
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used
2 | -------x xxxxxxxx | x position
2 | -xxxxxx- -------- | sprite color
3 | -------- ------xx | sprite code (high bits)
3 | xxxxxxxx xxxxxx-- | sprite code (low bits)
*/
void thoop2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = m_gfxdecode->gfx(0);
static const int x_offset[2] = {0x0, 0x2};
static const int y_offset[2] = {0x0, 0x1};
for (int i = 0x800 - 4 - 1; i >= 3; i -= 4)
{
int const sx = m_spriteram[i + 2] & 0x01ff;
int const sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int number = m_spriteram[i + 3];
int const color = (m_spriteram[i + 2] & 0x7e00) >> 9;
int const attr = (m_spriteram[i] & 0xfe00) >> 9;
int priority = (m_spriteram[i] & 0x3000) >> 12;
int const xflip = attr & 0x20;
int const yflip = attr & 0x40;
int spr_size, pri_mask;
// palettes 0x38-0x3f are used for high priority sprites
if (color >= 0x38)
priority = 4;
switch (priority)
{
case 0: pri_mask = 0xff00; break;
case 1: pri_mask = 0xff00 | 0xf0f0; break;
case 2: pri_mask = 0xff00 | 0xf0f0 | 0xcccc; break;
case 3: pri_mask = 0xff00 | 0xf0f0 | 0xcccc | 0xaaaa; break;
default:
case 4: pri_mask = 0; break;
}
number |= ((number & 0x03) << 16);
if (attr & 0x04)
{
spr_size = 1;
}
else
{
spr_size = 2;
number &= (~3);
}
for (int y = 0; y < spr_size; y++)
{
for (int x = 0; x < spr_size; x++)
{
int const ex = xflip ? (spr_size-1-x) : x;
int const ey = yflip ? (spr_size-1-y) : y;
gfx->prio_transpen(bitmap, cliprect, number + x_offset[ex] + y_offset[ey],
color, xflip, yflip,
sx - 0x0f + x * 8, sy + y * 8,
screen.priority(), pri_mask, 0);
}
}
}
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t thoop2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// set scroll registers
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1] + 4);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
draw_sprites(screen, bitmap, cliprect);
return 0;
}
// machine
void thoop2_state::machine_start()
{
m_okibank->configure_entries(0, 16, memregion("oki")->base(), 0x10000);
@ -79,36 +347,28 @@ void thoop2_state::oki_bankswitch_w(uint8_t data)
m_okibank->set_entry(data & 0x0f);
}
WRITE_LINE_MEMBER(thoop2_state::coin1_lockout_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(thoop2_state::coin_lockout_w)
{
machine().bookkeeping().coin_lockout_w(0, !state);
machine().bookkeeping().coin_lockout_w(Which, !state);
}
WRITE_LINE_MEMBER(thoop2_state::coin2_lockout_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(thoop2_state::coin_counter_w)
{
machine().bookkeeping().coin_lockout_w(1, !state);
}
WRITE_LINE_MEMBER(thoop2_state::coin1_counter_w)
{
machine().bookkeeping().coin_counter_w(0, state);
}
WRITE_LINE_MEMBER(thoop2_state::coin2_counter_w)
{
machine().bookkeeping().coin_counter_w(1, state);
machine().bookkeeping().coin_counter_w(Which, state);
}
void thoop2_state::shareram_w(offs_t offset, uint8_t data)
{
// why isn't there address map functionality for this?
util::big_endian_cast<u8>(m_shareram.target())[offset] = data;
util::big_endian_cast<uint8_t>(m_shareram.target())[offset] = data;
}
uint8_t thoop2_state::shareram_r(offs_t offset)
{
// why isn't there address map functionality for this?
return util::big_endian_cast<u8 const>(m_shareram.target())[offset];
return util::big_endian_cast<uint8_t const>(m_shareram.target())[offset];
}
@ -120,29 +380,29 @@ void thoop2_state::mcu_hostmem_map(address_map &map)
void thoop2_state::thoop2_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); /* ROM */
map(0x100000, 0x101fff).ram().w(FUNC(thoop2_state::vram_w)).share("videoram"); /* Video RAM */
map(0x108000, 0x108007).writeonly().share("vregs"); /* Video Registers */
map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); /* INT 6 ACK/Watchdog timer */
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");/* Palette */
map(0x440000, 0x440fff).ram().share("spriteram"); /* Sprite RAM */
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x101fff).ram().w(FUNC(thoop2_state::vram_w)).share(m_videoram);
map(0x108000, 0x108007).writeonly().share(m_vregs);
map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); // INT 6 ACK / Watchdog timer
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x440000, 0x440fff).ram().share(m_spriteram);
map(0x700000, 0x700001).portr("DSW2");
map(0x700002, 0x700003).portr("DSW1");
map(0x700004, 0x700005).portr("P1");
map(0x700006, 0x700007).portr("P2");
map(0x700008, 0x700009).portr("SYSTEM");
map(0x70000b, 0x70000b).select(0x000070).lw8(NAME([this] (offs_t offset, u8 data) { m_outlatch->write_d0(offset >> 4, data); }));
map(0x70000d, 0x70000d).w(FUNC(thoop2_state::oki_bankswitch_w)); /* OKI6295 bankswitch */
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); /* OKI6295 data register */
map(0xfe0000, 0xfe7fff).ram(); /* Work RAM */
map(0xfe8000, 0xfeffff).ram().share("shareram"); /* Work RAM (shared with D5002FP) */
map(0x70000d, 0x70000d).w(FUNC(thoop2_state::oki_bankswitch_w));
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
map(0xfe0000, 0xfe7fff).ram(); // Work RAM
map(0xfe8000, 0xfeffff).ram().share(m_shareram); // Work RAM (shared with D5002FP)
}
void thoop2_state::oki_map(address_map &map)
{
map(0x00000, 0x2ffff).rom();
map(0x30000, 0x3ffff).bankr("okibank");
map(0x30000, 0x3ffff).bankr(m_okibank);
}
@ -217,7 +477,7 @@ static INPUT_PORTS_START( thoop2 )
PORT_START("SYSTEM")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* test button */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) // test button
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
@ -229,9 +489,9 @@ INPUT_PORTS_END
static const gfx_layout thoop2_tilelayout =
{
8,8, /* 8x8 tiles */
RGN_FRAC(1,2), /* number of tiles */
4, /* 4 bpp */
8,8, // 8x8 tiles
RGN_FRAC(1,2), // number of tiles
4, // 4 bpp
{ 8, 0, RGN_FRAC(1,2)+8, RGN_FRAC(1,2)+0 },
{ STEP8(0,1) },
{ STEP8(0,8*2) },
@ -240,9 +500,9 @@ static const gfx_layout thoop2_tilelayout =
static const gfx_layout thoop2_tilelayout_16 =
{
16,16, /* 16x16 tiles */
RGN_FRAC(1,2), /* number of tiles */
4, /* 4 bpp */
16,16, // 16x16 tiles
RGN_FRAC(1,2), // number of tiles
4, // 4 bpp
{ 8, 0, RGN_FRAC(1,2)+8, RGN_FRAC(1,2)+0 },
{ STEP8(0,1), STEP8(8*2*16,1) },
{ STEP16(0,8*2) },
@ -251,14 +511,14 @@ static const gfx_layout thoop2_tilelayout_16 =
static GFXDECODE_START( gfx_thoop2 )
GFXDECODE_ENTRY( "gfx1", 0x000000, thoop2_tilelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx1", 0x000000, thoop2_tilelayout_16, 0, 64 )
GFXDECODE_ENTRY( "gfx", 0x000000, thoop2_tilelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx", 0x000000, thoop2_tilelayout_16, 0, 64 )
GFXDECODE_END
void thoop2_state::thoop2(machine_config &config)
{
/* basic machine hardware */
// basic machine hardware
M68000(config, m_maincpu, XTAL(24'000'000) / 2); // 12MHz verified
m_maincpu->set_addrmap(AS_PROGRAM, &thoop2_state::thoop2_map);
m_maincpu->set_vblank_int("screen", FUNC(thoop2_state::irq6_line_hold));
@ -268,19 +528,19 @@ void thoop2_state::thoop2(machine_config &config)
config.set_perfect_quantum("gaelco_ds5002fp:mcu");
LS259(config, m_outlatch);
m_outlatch->q_out_cb<0>().set(FUNC(thoop2_state::coin1_lockout_w));
m_outlatch->q_out_cb<1>().set(FUNC(thoop2_state::coin2_lockout_w));
m_outlatch->q_out_cb<2>().set(FUNC(thoop2_state::coin1_counter_w));
m_outlatch->q_out_cb<3>().set(FUNC(thoop2_state::coin2_counter_w));
m_outlatch->q_out_cb<0>().set(FUNC(thoop2_state::coin_lockout_w<0>));
m_outlatch->q_out_cb<1>().set(FUNC(thoop2_state::coin_lockout_w<1>));
m_outlatch->q_out_cb<2>().set(FUNC(thoop2_state::coin_counter_w<0>));
m_outlatch->q_out_cb<3>().set(FUNC(thoop2_state::coin_counter_w<1>));
m_outlatch->q_out_cb<4>().set_nop(); // unknown. Sound related?
m_outlatch->q_out_cb<5>().set_nop(); // unknown
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(59.24);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_size(32*16, 32*16);
screen.set_visarea(0, 320-1, 16, 256-1);
screen.set_screen_update(FUNC(thoop2_state::screen_update));
@ -289,7 +549,7 @@ void thoop2_state::thoop2(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_thoop2);
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
okim6295_device &oki(OKIM6295(config, "oki", XTAL(1'000'000), okim6295_device::PIN7_HIGH)); // 1MHz resonator - pin 7 not connected
@ -299,29 +559,29 @@ void thoop2_state::thoop2(machine_config &config)
ROM_START( thoop2 ) /* REF.940411 PCB */
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_START( thoop2 ) // REF.940411 PCB
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "th2c23.c23", 0x000000, 0x080000, CRC(3e465753) SHA1(1ea1173b9fe5d652e7b5fafb822e2535cecbc198) )
ROM_LOAD16_BYTE( "th2c22.c22", 0x000001, 0x080000, CRC(837205b7) SHA1(f78b90c2be0b4dddaba26f074ea00eff863cfdb2) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) /* dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) // dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
/* these are the default states stored in NVRAM */
// these are the default states stored in NVRAM
DS5002FP_SET_MON( 0x79 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x800000, "gfx1", 0 )
ROM_REGION( 0x800000, "gfx", 0 )
ROM_LOAD( "th2-h8.h8", 0x000000, 0x400000, CRC(60328a11) SHA1(fcdb374d2fc7ef5351a4181c471d192199dc2081) )
ROM_LOAD( "th2-h12.h12", 0x400000, 0x400000, CRC(b25c2d3e) SHA1(d70f3e4e2432d80c2ac87cd81208ada303bac04a) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "th2-c1.c1", 0x000000, 0x100000, CRC(8fac8c30) SHA1(8e49bb596144761eae95f3e1266e57fb386664f2) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched
ROM_REGION(0x0a00, "plds", 0) // PALs
ROM_REGION(0x0a00, "plds", 0)
ROM_LOAD("pal16r8-1.b16", 0x0000, 0x0104, CRC(27b1ca8b) SHA1(038d1352baff18f619ac4149e5825ef9664c983b) )
ROM_LOAD("pal20l8-2.b23", 0x0200, 0x0144, CRC(87e5e6ab) SHA1(f42b952128bd26fe565b06403c7b1c95061e5034) )
ROM_LOAD("pal16r4-3.e2", 0x0400, 0x0104, CRC(0488f37b) SHA1(e2e4e3ca57713da7b0fcae57b34b0bfc5c9d3635) )
@ -329,29 +589,29 @@ ROM_START( thoop2 ) /* REF.940411 PCB */
ROM_LOAD("palce16v8-5.h21", 0x0800, 0x0117, CRC(b651bc3b) SHA1(89f8bc2d3ae710189912373464c2f35b6780357d) )
ROM_END
ROM_START( thoop2a ) /* REF.940411 PCB */
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_START( thoop2a ) // REF.940411 PCB
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "3.c23", 0x000000, 0x080000, CRC(6cd4a8dc) SHA1(7d0cdce64b390c3f9769b07d57cf1eee1e6a7bf5) )
ROM_LOAD16_BYTE( "2.c22", 0x000001, 0x080000, CRC(59ba9b43) SHA1(6c6690a2e389fc9f1e166c87748da1175e3b58f8) )
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) /* DS5002FP code */
ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) /* dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct */
ROM_REGION( 0x8000, "gaelco_ds5002fp:sram", 0 ) // DS5002FP code
ROM_LOAD( "thoop2_ds5002fp.bin", 0x00000, 0x8000, CRC(6881384d) SHA1(c1eff5558716293e1325b766e2205783286c12f9) ) // dumped from 3 boards, reconstructed with 2/3 wins rule, all bytes verified by hand as correct
ROM_REGION( 0x100, "gaelco_ds5002fp:mcu:internal", ROMREGION_ERASE00 )
/* these are the default states stored in NVRAM */
// these are the default states stored in NVRAM
DS5002FP_SET_MON( 0x79 )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x800000, "gfx1", 0 )
ROM_REGION( 0x800000, "gfx", 0 )
ROM_LOAD( "th2-h8.h8", 0x000000, 0x400000, CRC(60328a11) SHA1(fcdb374d2fc7ef5351a4181c471d192199dc2081) )
ROM_LOAD( "th2-h12.h12", 0x400000, 0x400000, CRC(b25c2d3e) SHA1(d70f3e4e2432d80c2ac87cd81208ada303bac04a) )
ROM_REGION( 0x100000, "oki", 0 ) /* ADPCM samples - sound chip is OKIM6295 */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "th2-c1.c1", 0x000000, 0x100000, CRC(8fac8c30) SHA1(8e49bb596144761eae95f3e1266e57fb386664f2) )
/* 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched */
// 0x00000-0x2ffff is fixed, 0x30000-0x3ffff is bank switched
ROM_REGION(0x0a00, "plds", 0) // PALs
ROM_REGION(0x0a00, "plds", 0)
ROM_LOAD("pal16r8-1.b16", 0x0000, 0x0104, CRC(27b1ca8b) SHA1(038d1352baff18f619ac4149e5825ef9664c983b) )
ROM_LOAD("pal20l8-2.b23", 0x0200, 0x0144, CRC(87e5e6ab) SHA1(f42b952128bd26fe565b06403c7b1c95061e5034) )
ROM_LOAD("pal16r4-3.e2", 0x0400, 0x0104, CRC(0488f37b) SHA1(e2e4e3ca57713da7b0fcae57b34b0bfc5c9d3635) )
@ -359,5 +619,8 @@ ROM_START( thoop2a ) /* REF.940411 PCB */
ROM_LOAD("palce16v8-5.h21", 0x0800, 0x0117, CRC(b651bc3b) SHA1(89f8bc2d3ae710189912373464c2f35b6780357d) )
ROM_END
} // anonymous namespace
GAME( 1994, thoop2, 0, thoop2, thoop2, thoop2_state, empty_init, ROT0, "Gaelco", "TH Strikes Back (Non North America, Version 1.0, Checksum 020E0867)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1994, thoop2a, thoop2, thoop2, thoop2, thoop2_state, empty_init, ROT0, "Gaelco", "TH Strikes Back (Non North America, Version 1.0, Checksum 020EB356)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )

View File

@ -1,69 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Peter Ferrie
#ifndef MAME_INCLUDES_THOOP2_H
#define MAME_INCLUDES_THOOP2_H
#pragma once
#include "machine/74259.h"
#include "emupal.h"
#include "tilemap.h"
class thoop2_state : public driver_device
{
public:
thoop2_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_pant{ nullptr, nullptr },
m_maincpu(*this, "maincpu"),
m_outlatch(*this, "outlatch"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_okibank(*this, "okibank"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram")
{ }
void thoop2(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
void oki_bankswitch_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(coin1_lockout_w);
DECLARE_WRITE_LINE_MEMBER(coin2_lockout_w);
DECLARE_WRITE_LINE_MEMBER(coin1_counter_w);
DECLARE_WRITE_LINE_MEMBER(coin2_counter_w);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void shareram_w(offs_t offset, uint8_t data);
uint8_t shareram_r(offs_t offset);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
void thoop2_map(address_map &map);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
tilemap_t *m_pant[2]{};
required_device<cpu_device> m_maincpu;
required_device<ls259_device> m_outlatch;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_memory_bank m_okibank;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
};
#endif // MAME_INCLUDES_THOOP2_H

View File

@ -1,211 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Peter Ferrie
/***************************************************************************
Gaelco Type 1 Video Hardware Rev B
The video hardware it's nearly identical to the previous
revision but it can handle more tiles and more sprites
Functions to emulate the video hardware of the machine
***************************************************************************/
#include "emu.h"
#include "thoop2.h"
#include "screen.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (32*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- ------xx | code (high bits)
0 | xxxxxxxx xxxxxx-- | code (low bits)
1 | -------- --xxxxxx | color
1 | -------- xx------ | priority
1 | --xxxxxx -------- | not used
1 | -x------ -------- | flip x
1 | x------- -------- | flip y
*/
template<int Layer>
TILE_GET_INFO_MEMBER(thoop2_state::get_tile_info)
{
int data = m_videoram[(Layer * 0x1000/2) + (tile_index << 1)];
int data2 = m_videoram[(Layer * 0x1000/2) + (tile_index << 1) + 1];
int code = ((data & 0xfffc) >> 2) | ((data & 0x0003) << 14);
tileinfo.category = (data2 >> 6) & 0x03;
tileinfo.set(1, code, data2 & 0x3f, TILE_FLIPYX((data2 >> 14) & 0x03));
}
/***************************************************************************
Memory Handlers
***************************************************************************/
void thoop2_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_pant[offset >> 11]->mark_tile_dirty(((offset << 1) & 0x0fff) >> 2);
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void thoop2_state::video_start()
{
m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(thoop2_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(thoop2_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_pant[0]->set_transmask(0,0xff01,0x00ff); /* pens 1-7 opaque, pens 0, 8-15 transparent */
m_pant[1]->set_transmask(0,0xff01,0x00ff); /* pens 1-7 opaque, pens 0, 8-15 transparent */
}
/***************************************************************************
Sprites
***************************************************************************/
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | y position
0 | -----xxx -------- | not used
0 | ----x--- -------- | sprite size
0 | --xx---- -------- | sprite priority
0 | -x------ -------- | flipx
0 | x------- -------- | flipy
1 | xxxxxxxx xxxxxxxx | not used
2 | -------x xxxxxxxx | x position
2 | -xxxxxx- -------- | sprite color
3 | -------- ------xx | sprite code (high bits)
3 | xxxxxxxx xxxxxx-- | sprite code (low bits)
*/
void thoop2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i, x, y, ex, ey;
gfx_element *gfx = m_gfxdecode->gfx(0);
static const int x_offset[2] = {0x0,0x2};
static const int y_offset[2] = {0x0,0x1};
for (i = 0x800 - 4 - 1; i >= 3; i -= 4)
{
int sx = m_spriteram[i+2] & 0x01ff;
int sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
int number = m_spriteram[i+3];
int color = (m_spriteram[i+2] & 0x7e00) >> 9;
int attr = (m_spriteram[i] & 0xfe00) >> 9;
int priority = (m_spriteram[i] & 0x3000) >> 12;
int xflip = attr & 0x20;
int yflip = attr & 0x40;
int spr_size, pri_mask;
/* palettes 0x38-0x3f are used for high priority sprites */
if (color >= 0x38)
priority = 4;
switch (priority)
{
case 0: pri_mask = 0xff00; break;
case 1: pri_mask = 0xff00 | 0xf0f0; break;
case 2: pri_mask = 0xff00 | 0xf0f0 | 0xcccc; break;
case 3: pri_mask = 0xff00 | 0xf0f0 | 0xcccc | 0xaaaa; break;
default:
case 4: pri_mask = 0; break;
}
number |= ((number & 0x03) << 16);
if (attr & 0x04)
{
spr_size = 1;
}
else
{
spr_size = 2;
number &= (~3);
}
for (y = 0; y < spr_size; y++)
{
for (x = 0; x < spr_size; x++)
{
ex = xflip ? (spr_size-1-x) : x;
ey = yflip ? (spr_size-1-y) : y;
gfx->prio_transpen(bitmap,cliprect,number + x_offset[ex] + y_offset[ey],
color,xflip,yflip,
sx-0x0f+x*8,sy+y*8,
screen.priority(),pri_mask,0);
}
}
}
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t thoop2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* set scroll registers */
m_pant[0]->set_scrolly(0, m_vregs[0]);
m_pant[0]->set_scrollx(0, m_vregs[1]+4);
m_pant[1]->set_scrolly(0, m_vregs[2]);
m_pant[1]->set_scrollx(0, m_vregs[3]);
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
draw_sprites(screen, bitmap, cliprect);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna
// copyright-holders: Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna
/***************************************************************************
World Rally (c) 1993 Gaelco (Designed & Developed by Zigurat. Produced by Gaelco)
@ -118,26 +119,195 @@ produces a high clock frequency, slow movements a low freq.
PCB: REF.930217
The PCB has a layout that can either use the 4 rom set of I7, I9, I11 & I13 or larger
roms at H8 & H12 for graphics as well as the ability to use different size sound sample
roms at C1 & C3
The PCB has a layout that can either use the 4 ROM set of I7, I9, I11 & I13 or larger
ROMs at H8 & H12 for graphics as well as the ability to use different size sound sample
ROMs at C1 & C3
***************************************************************************/
#include "emu.h"
#include "wrally.h"
#include "gaelco_ds5002fp.h"
#include "gaelco_wrally_sprites.h"
#include "gaelcrpt.h"
#include "cpu/m68000/m68000.h"
#include "cpu/mcs51/mcs51.h"
#include "machine/74259.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class wrally_state : public driver_device
{
public:
wrally_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_outlatch(*this, "outlatch"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_sprites(*this, "sprites"),
m_okibank(*this, "okibank"),
m_vramcrypt(*this, "vramcrypt"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_analog(*this, "ANALOG%u", 0U),
m_tilemap{ nullptr, nullptr }
{
}
void wrally(machine_config &config);
template <int N> DECLARE_READ_LINE_MEMBER(analog_bit_r);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
uint8_t shareram_r(offs_t offset);
void shareram_w(offs_t offset, uint8_t data);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
void okim6295_bankswitch_w(uint8_t data);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_lockout_w);
DECLARE_WRITE_LINE_MEMBER(adc_clk);
DECLARE_WRITE_LINE_MEMBER(adc_en);
template <int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
void main_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<ls259_device> m_outlatch;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<gaelco_wrally_sprites_device> m_sprites;
required_memory_bank m_okibank;
required_device<gaelco_vram_encryption_device> m_vramcrypt;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_ioport_array<2> m_analog;
tilemap_t *m_tilemap[2]{};
uint8_t m_analog_ports[2]{};
};
// video
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (64*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | --xxxxxx xxxxxxxx | code
0 | xx------ -------- | not used?
1 | -------- ---xxxxx | color
1 | -------- --x----- | priority
1 | -------- -x------ | flip y
1 | -------- x------- | flip x
1 | ---xxxxx -------- | data used to handle collisions, speed, etc
1 | xxx----- -------- | not used?
*/
template <int Layer>
TILE_GET_INFO_MEMBER(wrally_state::get_tile_info)
{
int const data = m_videoram[(Layer * 0x2000 / 2) + (tile_index << 1)];
int const data2 = m_videoram[(Layer * 0x2000 / 2) + (tile_index << 1) + 1];
int const code = data & 0x3fff;
tileinfo.category = (data2 >> 5) & 0x01;
tileinfo.set(0, code, data2 & 0x1f, TILE_FLIPYX((data2 >> 6) & 0x03));
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void wrally_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wrally_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wrally_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_tilemap[0]->set_transmask(0, 0xff01, 0x00ff); // this layer is split in two (pens 1..7, pens 8-15)
m_tilemap[1]->set_transparent_pen(0);
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t wrally_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_sprites->draw_sprites(cliprect, m_spriteram, flip_screen());
// set scroll registers
if (!flip_screen()) {
m_tilemap[0]->set_scrolly(0, m_vregs[0]);
m_tilemap[0]->set_scrollx(0, m_vregs[1] + 4);
m_tilemap[1]->set_scrolly(0, m_vregs[2]);
m_tilemap[1]->set_scrollx(0, m_vregs[3]);
} else {
m_tilemap[0]->set_scrolly(0, 248 - m_vregs[0]);
m_tilemap[0]->set_scrollx(0, 1024 - m_vregs[1] - 4);
m_tilemap[1]->set_scrolly(0, 248 - m_vregs[2]);
m_tilemap[1]->set_scrollx(0, 1024 - m_vregs[3]);
}
// draw tilemaps + sprites
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER0,0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER1,0);
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1), 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER0,0);
m_sprites->mix_sprites(bitmap, cliprect, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER1,0);
m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}
// machine
void wrally_state::machine_start()
{
@ -155,13 +325,13 @@ void wrally_state::machine_start()
void wrally_state::shareram_w(offs_t offset, uint8_t data)
{
// why isn't there address map functionality for this?
util::big_endian_cast<u8>(m_shareram.target())[offset] = data;
util::big_endian_cast<uint8_t>(m_shareram.target())[offset] = data;
}
uint8_t wrally_state::shareram_r(offs_t offset)
{
// why isn't there address map functionality for this?
return util::big_endian_cast<u8 const>(m_shareram.target())[offset];
return util::big_endian_cast<uint8_t const>(m_shareram.target())[offset];
}
void wrally_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
@ -182,24 +352,16 @@ void wrally_state::okim6295_bankswitch_w(uint8_t data)
m_okibank->set_entry(data & 0x0f);
}
WRITE_LINE_MEMBER(wrally_state::coin1_counter_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(wrally_state::coin_counter_w)
{
machine().bookkeeping().coin_counter_w(0, state);
machine().bookkeeping().coin_counter_w(Which, state);
}
WRITE_LINE_MEMBER(wrally_state::coin2_counter_w)
template <uint8_t Which>
WRITE_LINE_MEMBER(wrally_state::coin_lockout_w)
{
machine().bookkeeping().coin_counter_w(1, state);
}
WRITE_LINE_MEMBER(wrally_state::coin1_lockout_w)
{
machine().bookkeeping().coin_lockout_w(0, !state);
}
WRITE_LINE_MEMBER(wrally_state::coin2_lockout_w)
{
machine().bookkeeping().coin_lockout_w(1, !state);
machine().bookkeeping().coin_lockout_w(Which, !state);
}
// the following methods have been pilfered from gaelco2.cpp (wrally2). They seem to work fine for wrally, too
@ -236,32 +398,32 @@ void wrally_state::mcu_hostmem_map(address_map &map)
}
void wrally_state::wrally_map(address_map &map)
void wrally_state::main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x103fff).ram().w(FUNC(wrally_state::vram_w)).share("videoram"); // Encrypted Video RAM
map(0x108000, 0x108007).ram().share("vregs"); // Video Registers
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x103fff).ram().w(FUNC(wrally_state::vram_w)).share(m_videoram); // Encrypted
map(0x108000, 0x108007).ram().share(m_vregs);
map(0x10800c, 0x10800d).nopw(); // CLR INT Video
map(0x200000, 0x203fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
map(0x200000, 0x203fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
map(0x440000, 0x440fff).ram().share(m_spriteram);
map(0x700000, 0x700001).portr("DSW");
map(0x700002, 0x700003).portr("P1_P2");
map(0x700004, 0x700005).portr("WHEEL");
map(0x700008, 0x700009).portr("SYSTEM");
map(0x70000b, 0x70000b).select(0x000070).lw8(NAME([this] (offs_t offset, u8 data) { m_outlatch->write_d0(offset >> 4, data); }));
map(0x70000d, 0x70000d).w(FUNC(wrally_state::okim6295_bankswitch_w)); // OKI6295 bankswitch
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // OKI6295 status/data register
map(0x70000d, 0x70000d).w(FUNC(wrally_state::okim6295_bankswitch_w));
map(0x70000f, 0x70000f).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
map(0x70006a, 0x70006b).nopr();
map(0x70007a, 0x70007b).nopr();
map(0xfec000, 0xfeffff).ram().share("shareram"); // Work RAM (shared with DS5002FP)
map(0xfec000, 0xfeffff).ram().share(m_shareram); // Work RAM (shared with DS5002FP)
}
void wrally_state::oki_map(address_map &map)
{
map(0x00000, 0x2ffff).rom();
map(0x30000, 0x3ffff).bankr("okibank");
map(0x30000, 0x3ffff).bankr(m_okibank);
}
@ -360,15 +522,15 @@ static const gfx_layout wrally_tilelayout16 =
};
static GFXDECODE_START( gfx_wrally )
GFXDECODE_ENTRY( "gfx1", 0x000000, wrally_tilelayout16, 0, 64*8 )
GFXDECODE_ENTRY( "gfx", 0x000000, wrally_tilelayout16, 0, 64*8 )
GFXDECODE_END
void wrally_state::wrally(machine_config &config)
{
// Basic machine hardware
M68000(config, m_maincpu, XTAL(24'000'000)/2); // Verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &wrally_state::wrally_map);
M68000(config, m_maincpu, XTAL(24'000'000) / 2); // Verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &wrally_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(wrally_state::irq6_line_hold));
gaelco_ds5002fp_device &ds5002(GAELCO_DS5002FP(config, "gaelco_ds5002fp", XTAL(24'000'000) / 2)); // verified on PCB
@ -395,12 +557,12 @@ void wrally_state::wrally(machine_config &config)
m_sprites->set_screen_tag("screen");
LS259(config, m_outlatch);
m_outlatch->q_out_cb<0>().set(FUNC(wrally_state::coin1_lockout_w));
m_outlatch->q_out_cb<1>().set(FUNC(wrally_state::coin2_lockout_w));
m_outlatch->q_out_cb<2>().set(FUNC(wrally_state::coin1_counter_w));
m_outlatch->q_out_cb<3>().set(FUNC(wrally_state::coin2_counter_w));
m_outlatch->q_out_cb<0>().set(FUNC(wrally_state::coin_lockout_w<0>));
m_outlatch->q_out_cb<1>().set(FUNC(wrally_state::coin_lockout_w<1>));
m_outlatch->q_out_cb<2>().set(FUNC(wrally_state::coin_counter_w<0>));
m_outlatch->q_out_cb<3>().set(FUNC(wrally_state::coin_counter_w<1>));
m_outlatch->q_out_cb<4>().set_nop(); // Sound muting
m_outlatch->q_out_cb<5>().set(FUNC(wrally_state::flipscreen_w)); // Flip screen
m_outlatch->q_out_cb<5>().set(FUNC(wrally_state::flipscreen_w));
m_outlatch->q_out_cb<6>().set(FUNC(wrally_state::adc_en)); // ENA/D, for pot wheel
m_outlatch->q_out_cb<7>().set(FUNC(wrally_state::adc_clk)); // CKA/D, "
@ -427,7 +589,7 @@ ROM_START( wrally )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 )
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) )
ROM_LOAD16_BYTE( "worldr20.i11", 0x000001, 0x080000, CRC(58b2809a) SHA1(8741ec544c54e2a2f5d17ac2f8400ee2ce382e83) )
ROM_LOAD16_BYTE( "worldr19.i09", 0x100000, 0x080000, CRC(018b35bb) SHA1(ca789e23d18cc7d7e48b6858e6b61e03bf88b475) )
@ -460,7 +622,7 @@ ROM_START( wrallya )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 )
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) )
ROM_LOAD16_BYTE( "worldr20.i11", 0x000001, 0x080000, CRC(58b2809a) SHA1(8741ec544c54e2a2f5d17ac2f8400ee2ce382e83) )
ROM_LOAD16_BYTE( "worldr19.i09", 0x100000, 0x080000, CRC(018b35bb) SHA1(ca789e23d18cc7d7e48b6858e6b61e03bf88b475) )
@ -493,7 +655,7 @@ ROM_START( wrallyb )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 )
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD( "rally h-12.h12", 0x000000, 0x100000, CRC(3353dc00) SHA1(db3b1686751dcaa231d66c08b5be81fcfe299ad9) ) // Same data, different layout
ROM_LOAD( "rally h-8.h8", 0x100000, 0x100000, CRC(58dcd024) SHA1(384ff296d3c7c8e0c4469231d1940de3cea89fc2) )
@ -522,7 +684,7 @@ ROM_START( wrallyc )
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 )
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD16_BYTE( "rally i13.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) )
ROM_LOAD16_BYTE( "rally i11.i11", 0x000001, 0x080000, CRC(58b2809a) SHA1(8741ec544c54e2a2f5d17ac2f8400ee2ce382e83) )
ROM_LOAD16_BYTE( "rally i9.i9", 0x100000, 0x080000, CRC(018b35bb) SHA1(ca789e23d18cc7d7e48b6858e6b61e03bf88b475) )
@ -555,7 +717,7 @@ ROM_START( wrallyat ) // Board Marked 930217, Atari License
DS5002FP_SET_RPCTL( 0x00 )
DS5002FP_SET_CRCR( 0x80 )
ROM_REGION( 0x200000, "gfx1", 0 )
ROM_REGION( 0x200000, "gfx", 0 )
ROM_LOAD( "rally h-12.h12", 0x000000, 0x100000, CRC(3353dc00) SHA1(db3b1686751dcaa231d66c08b5be81fcfe299ad9) ) // Same data, different layout
ROM_LOAD( "rally h-8.h8", 0x100000, 0x100000, CRC(58dcd024) SHA1(384ff296d3c7c8e0c4469231d1940de3cea89fc2) )
@ -570,6 +732,8 @@ ROM_START( wrallyat ) // Board Marked 930217, Atari License
ROM_LOAD( "pal16r8-b15.bin", 0x0000, 0x0104, CRC(b50337a6) SHA1(1f922753cb9982cad9a3c9246894ecd38273236e) )
ROM_END
} // anonymous namespace
GAME( 1993, wrally, 0, wrally, wrally, wrally_state, empty_init, ROT0, "Gaelco", "World Rally (Version 1.0, Checksum 0E56)", MACHINE_SUPPORTS_SAVE ) // Dallas DS5002FP power failure shows as: "Tension baja"
GAME( 1993, wrallya, wrally, wrally, wrally, wrally_state, empty_init, ROT0, "Gaelco", "World Rally (Version 1.0, Checksum 3873)", MACHINE_SUPPORTS_SAVE ) // Dallas DS5002FP power failure shows as: "Power Failure"

View File

@ -1,84 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna
#ifndef MAME_INCLUDES_WRALLY_H
#define MAME_INCLUDES_WRALLY_H
#pragma once
#include "machine/74259.h"
#include "gaelcrpt.h"
#include "gaelco_wrally_sprites.h"
#include "emupal.h"
#include "tilemap.h"
class wrally_state : public driver_device
{
public:
wrally_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_outlatch(*this, "outlatch"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_sprites(*this, "sprites"),
m_okibank(*this, "okibank"),
m_vramcrypt(*this, "vramcrypt"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
m_analog(*this, "ANALOG%u", 0U),
m_tilemap{ nullptr, nullptr }
{
}
void wrally(machine_config &config);
template <int N> DECLARE_READ_LINE_MEMBER(analog_bit_r);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
uint8_t shareram_r(offs_t offset);
void shareram_w(offs_t offset, uint8_t data);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
void okim6295_bankswitch_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(coin1_counter_w);
DECLARE_WRITE_LINE_MEMBER(coin2_counter_w);
DECLARE_WRITE_LINE_MEMBER(coin1_lockout_w);
DECLARE_WRITE_LINE_MEMBER(coin2_lockout_w);
DECLARE_WRITE_LINE_MEMBER(adc_clk);
DECLARE_WRITE_LINE_MEMBER(adc_en);
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mcu_hostmem_map(address_map &map);
void oki_map(address_map &map);
void wrally_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<ls259_device> m_outlatch;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<gaelco_wrally_sprites_device> m_sprites;
required_memory_bank m_okibank;
required_device<gaelco_vram_encryption_device> m_vramcrypt;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_vregs;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
required_ioport_array<2> m_analog;
tilemap_t *m_tilemap[2]{};
uint8_t m_analog_ports[2]{};
};
#endif // MAME_INCLUDES_WRALLY_H

View File

@ -1,104 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna
/***************************************************************************
World Rally Video Hardware
Functions to emulate the video hardware of the machine
***************************************************************************/
#include "emu.h"
#include "wrally.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/*
Tile format
-----------
Screen 0 & 1: (64*32, 16x16 tiles)
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | --xxxxxx xxxxxxxx | code
0 | xx------ -------- | not used?
1 | -------- ---xxxxx | color
1 | -------- --x----- | priority
1 | -------- -x------ | flip y
1 | -------- x------- | flip x
1 | ---xxxxx -------- | data used to handle collisions, speed, etc
1 | xxx----- -------- | not used?
*/
template<int Layer>
TILE_GET_INFO_MEMBER(wrally_state::get_tile_info)
{
int data = m_videoram[(Layer * 0x2000/2) + (tile_index << 1)];
int data2 = m_videoram[(Layer * 0x2000/2) + (tile_index << 1) + 1];
int code = data & 0x3fff;
tileinfo.category = (data2 >> 5) & 0x01;
tileinfo.set(0, code, data2 & 0x1f, TILE_FLIPYX((data2 >> 6) & 0x03));
}
/***************************************************************************
Start/Stop the video hardware emulation.
***************************************************************************/
void wrally_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wrally_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wrally_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 64,32);
m_tilemap[0]->set_transmask(0,0xff01,0x00ff); /* this layer is split in two (pens 1..7, pens 8-15) */
m_tilemap[1]->set_transparent_pen(0);
}
/***************************************************************************
Display Refresh
***************************************************************************/
uint32_t wrally_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_sprites->draw_sprites(cliprect,m_spriteram,flip_screen());
/* set scroll registers */
if (!flip_screen()) {
m_tilemap[0]->set_scrolly(0, m_vregs[0]);
m_tilemap[0]->set_scrollx(0, m_vregs[1]+4);
m_tilemap[1]->set_scrolly(0, m_vregs[2]);
m_tilemap[1]->set_scrollx(0, m_vregs[3]);
} else {
m_tilemap[0]->set_scrolly(0, 248 - m_vregs[0]);
m_tilemap[0]->set_scrollx(0, 1024 - m_vregs[1] - 4);
m_tilemap[1]->set_scrolly(0, 248 - m_vregs[2]);
m_tilemap[1]->set_scrollx(0, 1024 - m_vregs[3]);
}
/* draw tilemaps + sprites */
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER0,0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER1,0);
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1),0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER0,0);
m_sprites->mix_sprites(bitmap, cliprect, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER1,0);
m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}

View File

@ -27,41 +27,197 @@ Interrupts:
EEPROM chip: 93C46
TODO: protection is patched out
***************************************************************************/
#include "emu.h"
#include "xorworld.h"
#include "cpu/m68000/m68000.h"
#include "machine/74259.h"
#include "machine/eepromser.h"
#include "sound/saa1099.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
/****************************************************************
Init machine
****************************************************************/
namespace {
class xorworld_state : public driver_device
{
public:
xorworld_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_eeprom(*this, "eeprom"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_videoram(*this, "videoram"),
m_spriteram(*this, "spriteram")
{ }
void xorworld(machine_config &config);
void init_xorworld();
protected:
virtual void video_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_spriteram;
tilemap_t *m_bg_tilemap = nullptr;
template <uint8_t Which> void irq_ack_w(uint16_t data);
void irq6_ack_w(uint16_t data);
void videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
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 prg_map(address_map &map);
};
// video
/***************************************************************************
Convert the color PROMs into a more useable format.
Xor World has three 256x4 palette PROMs (one per gun).
The palette PROMs are connected to the RGB output this way:
bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE
-- 460 ohm resistor -- RED/GREEN/BLUE
-- 1 kohm resistor -- RED/GREEN/BLUE
bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE
***************************************************************************/
void xorworld_state::palette(palette_device &palette) const
{
const uint8_t *color_prom = memregion("proms")->base();
for (int i = 0; i < palette.entries(); i++)
{
int bit0, bit1, bit2, bit3;
// red component
bit0 = BIT(color_prom[0], 0);
bit1 = BIT(color_prom[0], 1);
bit2 = BIT(color_prom[0], 2);
bit3 = BIT(color_prom[0], 3);
int const r = 0x0e * bit0 + 0x1e * bit1 + 0x44 * bit2 + 0x8f * bit3;
// green component
bit0 = BIT(color_prom[palette.entries()], 0);
bit1 = BIT(color_prom[palette.entries()], 1);
bit2 = BIT(color_prom[palette.entries()], 2);
bit3 = BIT(color_prom[palette.entries()], 3);
int const g = 0x0e * bit0 + 0x1e * bit1 + 0x44 * bit2 + 0x8f * bit3;
// blue component
bit0 = BIT(color_prom[2 * palette.entries()], 0);
bit1 = BIT(color_prom[2 * palette.entries()], 1);
bit2 = BIT(color_prom[2 * palette.entries()], 2);
bit3 = BIT(color_prom[2 * palette.entries()], 3);
int const b = 0x0e * bit0 + 0x1e * bit1 + 0x44 * bit2 + 0x8f * bit3;
palette.set_pen_color(i, rgb_t(r, g, b));
color_prom++;
}
}
void xorworld_state::videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset);
}
/*
Tile format
-----------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | ----xxxx xxxxxxxx | code
0 | xxxx---- -------- | color
*/
TILE_GET_INFO_MEMBER(xorworld_state::get_bg_tile_info)
{
int const data = m_videoram[tile_index];
int const code = data & 0x0fff;
tileinfo.set(0, code, data >> 12, 0);
}
void xorworld_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(
*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(xorworld_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS,
8, 8, 32, 32);
}
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | x position
0 | xxxxxxxx -------- | y position
1 | -------- ------xx | flipxy? (not used)
1 | ----xxxx xxxxxx-- | sprite number
1 | xxxx---- -------- | sprite color
*/
void xorworld_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (int i = 0; i < 0x40; i += 2)
{
int const sx = m_spriteram[i] & 0x00ff;
int const sy = 240 - (((m_spriteram[i] & 0xff00) >> 8) & 0xff);
int const code = (m_spriteram[i+1] & 0x0ffc) >> 2;
int const color = (m_spriteram[i+1] & 0xf000) >> 12;
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code, color, 0, 0, sx, sy, 0);
}
}
uint32_t xorworld_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;
}
// machine
/****************************************************************
EEPROM read/write/control
****************************************************************/
void xorworld_state::irq2_ack_w(uint16_t data)
template <uint8_t Which>
void xorworld_state::irq_ack_w(uint16_t data)
{
m_maincpu->set_input_line(2, CLEAR_LINE);
m_maincpu->set_input_line(Which, CLEAR_LINE);
}
void xorworld_state::irq6_ack_w(uint16_t data)
{
m_maincpu->set_input_line(6, CLEAR_LINE);
}
void xorworld_state::xorworld_map(address_map &map)
void xorworld_state::prg_map(address_map &map)
{
map(0x000000, 0x01ffff).rom();
map(0x200000, 0x200001).portr("P1");
@ -69,10 +225,10 @@ void xorworld_state::xorworld_map(address_map &map)
map(0x600000, 0x600001).portr("DSW");
map(0x800000, 0x800003).w("saa", FUNC(saa1099_device::write)).umask16(0x00ff);
map(0xa00000, 0xa0000f).w("mainlatch", FUNC(ls259_device::write_d0)).umask16(0x00ff);
map(0xffc000, 0xffc7ff).ram().w(FUNC(xorworld_state::videoram_w)).share("videoram");
map(0xffc800, 0xffc87f).ram().share("spriteram");
map(0xffc880, 0xffc881).w(FUNC(xorworld_state::irq2_ack_w)).nopr();
map(0xffc882, 0xffc883).w(FUNC(xorworld_state::irq6_ack_w)).nopr();
map(0xffc000, 0xffc7ff).ram().w(FUNC(xorworld_state::videoram_w)).share(m_videoram);
map(0xffc800, 0xffc87f).ram().share(m_spriteram);
map(0xffc880, 0xffc881).w(FUNC(xorworld_state::irq_ack_w<2>)).nopr();
map(0xffc882, 0xffc883).w(FUNC(xorworld_state::irq_ack_w<6>)).nopr();
map(0xffc884, 0xffffff).ram();
}
@ -91,7 +247,7 @@ static INPUT_PORTS_START( xorworld )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Demo_Sounds ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) /* used for accessing the NVRAM */
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) // used for accessing the NVRAM
PORT_DIPNAME( 0x60, 0x40, DEF_STR( Difficulty ) )
PORT_DIPSETTING( 0x40, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x60, DEF_STR( Normal ) )
@ -123,10 +279,10 @@ INPUT_PORTS_END
static const gfx_layout tilelayout =
{
8,8, /* 8x8 tiles */
0x10000/16, /* 4096 tiles */
4, /* 4 bpp */
{ 1*0x10000*8, 1*0x10000*8+4, 0, 4 }, /* plane offsets */
8,8, // 8x8 tiles
0x10000/16, // 4096 tiles
4, // 4 bpp
{ 1*0x10000*8, 1*0x10000*8+4, 0, 4 }, // plane offsets
{ 0*8, 0*8+1, 0*8+2, 0*8+3, 1*8+0, 1*8+1, 1*8+2, 1*8+3 },
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
16*8
@ -134,10 +290,10 @@ static const gfx_layout tilelayout =
static const gfx_layout spritelayout =
{
16,16, /* 16x16 sprites */
0x10000/64, /* 1024 sprites */
4, /* 4 bpp */
{ 1*0x10000*8, 1*0x10000*8+4, 0, 4 }, /* plane offsets */
16,16, // 16x16 sprites
0x10000/64, // 1024 sprites
4, // 4 bpp
{ 1*0x10000*8, 1*0x10000*8+4, 0, 4 }, // plane offsets
{ 0*8, 0*8+1, 0*8+2, 0*8+3, 1*8+0, 1*8+1, 1*8+2, 1*8+3,
32*8+0, 32*8+1, 32*8+2, 32*8+3, 33*8+0, 33*8+1, 33*8+2, 33*8+3},
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,
@ -147,21 +303,21 @@ static const gfx_layout spritelayout =
static GFXDECODE_START( gfx_xorworld )
GFXDECODE_ENTRY( "gfx1", 0x000000, tilelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx1", 0x000000, spritelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx", 0x000000, tilelayout, 0, 64 )
GFXDECODE_ENTRY( "gfx", 0x000000, spritelayout, 0, 64 )
GFXDECODE_END
void xorworld_state::xorworld(machine_config &config)
{
// basic machine hardware
M68000(config, m_maincpu, 10000000); // 10 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &xorworld_state::xorworld_map);
M68000(config, m_maincpu, 10'000'000); // 10 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &xorworld_state::prg_map);
//m_maincpu->set_vblank_int("screen", FUNC(xorworld_state::irq6_line_assert)); // irq 4 or 6
//m_maincpu->set_periodic_int(FUNC(xorworld_state::irq2_line_assert), attotime::from_hz(3*60)); //timed irq, unknown timing
//m_maincpu->set_periodic_int(FUNC(xorworld_state::irq2_line_assert), attotime::from_hz(3 * 60)); //timed irq, unknown timing
// Simple fix - but this sounds good!! -Valley Bell
m_maincpu->set_vblank_int("screen", FUNC(xorworld_state::irq2_line_assert)); // irq 4 or 6
m_maincpu->set_periodic_int(FUNC(xorworld_state::irq6_line_assert), attotime::from_hz(3*60)); //timed irq, unknown timing
m_maincpu->set_periodic_int(FUNC(xorworld_state::irq6_line_assert), attotime::from_hz(3 * 60)); //timed irq, unknown timing
config.set_maximum_quantum(attotime::from_hz(60));
@ -175,34 +331,34 @@ void xorworld_state::xorworld(machine_config &config)
// 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(0*8, 32*8-1, 2*8, 30*8-1);
screen.set_screen_update(FUNC(xorworld_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_xorworld);
PALETTE(config, m_palette, FUNC(xorworld_state::xorworld_palette), 256);
PALETTE(config, m_palette, FUNC(xorworld_state::palette), 256);
// sound hardware
SPEAKER(config, "mono").front_center();
SAA1099(config, "saa", 8000000 /* guess */).add_route(ALL_OUTPUTS, "mono", 1.0);
SAA1099(config, "saa", 8'000'000).add_route(ALL_OUTPUTS, "mono", 1.0); // guessed clock
}
ROM_START( xorworld )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code */
ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c13.bin", 0x000000, 0x010000, CRC(615a864d) SHA1(db07eef19d26a4daa0bcc17ac24d237483f93bf6) )
ROM_LOAD16_BYTE( "b13.bin", 0x000001, 0x010000, CRC(632e8ee5) SHA1(ec53e632c762f72ad1fe3fab85111bdcc1e818ae) )
ROM_REGION( 0x020000, "gfx1", 0 )
ROM_REGION( 0x020000, "gfx", 0 )
ROM_LOAD( "d9.bin", 0x000000, 0x010000, CRC(da8d4d65) SHA1(41bcc15f26066bd820b44c0f258e70d0102953c9) )
ROM_LOAD( "d10.bin", 0x010000, 0x010000, CRC(3b1d6f24) SHA1(bedf60a4cbf20492b8a846b6a7b578f8fe8dbde9) )
ROM_REGION( 0x0300, "proms", 0 )
ROM_LOAD( "b4.bin", 0x0000, 0x0100, CRC(75e468af) SHA1(b5fd1a086c27ca2e837cbbf1b7e57dfdd369b0d0) ) /* Red palette ROM (4 bits) */
ROM_LOAD( "b7.bin", 0x0100, 0x0100, CRC(7e1cd146) SHA1(fd26a28f90c50ffcb0fe7718820c81eb9fe79e66) ) /* Green palette ROM (4 bits) */
ROM_LOAD( "b5.bin", 0x0200, 0x0100, CRC(c1b9d9f9) SHA1(c4b02bf60db449fb308a5eb3e41c43299ad8e3e3) ) /* Blue palette ROM (4 bits) */
ROM_LOAD( "b4.bin", 0x0000, 0x0100, CRC(75e468af) SHA1(b5fd1a086c27ca2e837cbbf1b7e57dfdd369b0d0) ) // Red palette ROM (4 bits)
ROM_LOAD( "b7.bin", 0x0100, 0x0100, CRC(7e1cd146) SHA1(fd26a28f90c50ffcb0fe7718820c81eb9fe79e66) ) // Green palette ROM (4 bits)
ROM_LOAD( "b5.bin", 0x0200, 0x0100, CRC(c1b9d9f9) SHA1(c4b02bf60db449fb308a5eb3e41c43299ad8e3e3) ) // Blue palette ROM (4 bits)
ROM_END
@ -215,17 +371,19 @@ void xorworld_state::init_xorworld()
uint16_t *rom = (uint16_t *)(memregion("maincpu")->base() + 0x1390);
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe196); /* clr.b $ffe196 */
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe197); /* clr.b $ffe197 */
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe0bc); /* clr.b $ffe0bc */
PATCH(0x41f9); PATCH(0x00ff); PATCH(0xcfce); /* lea $ffcfce,A0 */
PATCH(0x3e3c); PATCH(0x000f); /* move #$f,D7 */
PATCH(0x4218); /* clr.b (A0)+ */
PATCH(0x51cf); PATCH(0xfffc); /* dbra D7,$13ac */
PATCH(0x4e75); /* rts */
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe196); // clr.b $ffe196
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe197); // clr.b $ffe197
PATCH(0x4239); PATCH(0x00ff); PATCH(0xe0bc); // clr.b $ffe0bc
PATCH(0x41f9); PATCH(0x00ff); PATCH(0xcfce); // lea $ffcfce,A0
PATCH(0x3e3c); PATCH(0x000f); // move #$f,D7
PATCH(0x4218); // clr.b (A0)+
PATCH(0x51cf); PATCH(0xfffc); // dbra D7,$13ac
PATCH(0x4e75); // rts
PATCH(0x31ff); /* adjust checksum */
PATCH(0x31ff); // adjust checksum
}
} // anonymous namespace
GAME( 1990, xorworld, 0, xorworld, xorworld, xorworld_state, init_xorworld, ROT0, "Gaelco", "Xor World (prototype)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,55 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
#ifndef MAME_INCLUDES_XORWORLD_H
#define MAME_INCLUDES_XORWORLD_H
#pragma once
#include "machine/eepromser.h"
#include "emupal.h"
#include "tilemap.h"
class xorworld_state : public driver_device
{
public:
xorworld_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_eeprom(*this, "eeprom"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_videoram(*this, "videoram"),
m_spriteram(*this, "spriteram")
{ }
void xorworld(machine_config &config);
void init_xorworld();
private:
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_spriteram;
tilemap_t *m_bg_tilemap = nullptr;
void irq2_ack_w(uint16_t data);
void irq6_ack_w(uint16_t data);
void videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
virtual void video_start() override;
void xorworld_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 xorworld_map(address_map &map);
};
#endif // MAME_INCLUDES_XORWORLD_H

View File

@ -1,115 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Manuel Abadia
#include "emu.h"
#include "xorworld.h"
/***************************************************************************
Convert the color PROMs into a more useable format.
Xor World has three 256x4 palette PROMs (one per gun).
The palette PROMs are connected to the RGB output this way:
bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE
-- 460 ohm resistor -- RED/GREEN/BLUE
-- 1 kohm resistor -- RED/GREEN/BLUE
bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE
***************************************************************************/
void xorworld_state::xorworld_palette(palette_device &palette) const
{
const uint8_t *color_prom = memregion("proms")->base();
for (int i = 0; i < palette.entries(); i++)
{
int bit0, bit1, bit2, bit3;
// red component
bit0 = BIT(color_prom[0], 0);
bit1 = BIT(color_prom[0], 1);
bit2 = BIT(color_prom[0], 2);
bit3 = BIT(color_prom[0], 3);
int const r = 0x0e*bit0 + 0x1e*bit1 + 0x44*bit2 + 0x8f*bit3;
// green component
bit0 = BIT(color_prom[palette.entries()], 0);
bit1 = BIT(color_prom[palette.entries()], 1);
bit2 = BIT(color_prom[palette.entries()], 2);
bit3 = BIT(color_prom[palette.entries()], 3);
int const g = 0x0e*bit0 + 0x1e*bit1 + 0x44*bit2 + 0x8f*bit3;
// blue component
bit0 = BIT(color_prom[2 * palette.entries()], 0);
bit1 = BIT(color_prom[2 * palette.entries()], 1);
bit2 = BIT(color_prom[2 * palette.entries()], 2);
bit3 = BIT(color_prom[2 * palette.entries()], 3);
int const b = 0x0e*bit0 + 0x1e * bit1 + 0x44*bit2 + 0x8f*bit3;
palette.set_pen_color(i, rgb_t(r, g, b));
color_prom++;
}
}
void xorworld_state::videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset);
}
/*
Tile format
-----------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | ----xxxx xxxxxxxx | code
0 | xxxx---- -------- | color
*/
TILE_GET_INFO_MEMBER(xorworld_state::get_bg_tile_info)
{
int data = m_videoram[tile_index];
int code = data & 0x0fff;
tileinfo.set(0, code, data >> 12, 0);
}
void xorworld_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(
*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(xorworld_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS,
8, 8, 32, 32);
}
/*
Sprite Format
-------------
Word | Bit(s) | Description
-----+-FEDCBA98-76543210-+--------------------------
0 | -------- xxxxxxxx | x position
0 | xxxxxxxx -------- | y position
1 | -------- ------xx | flipxy? (not used)
1 | ----xxxx xxxxxx-- | sprite number
1 | xxxx---- -------- | sprite color
*/
void xorworld_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect )
{
for (int i = 0; i < 0x40; i += 2)
{
int sx = m_spriteram[i] & 0x00ff;
int sy = 240 - (((m_spriteram[i] & 0xff00) >> 8) & 0xff);
int code = (m_spriteram[i+1] & 0x0ffc) >> 2;
int color = (m_spriteram[i+1] & 0xf000) >> 12;
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, code, color, 0, 0, sx, sy, 0);
}
}
uint32_t xorworld_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;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Roberto Fresca
// copyright-holders: Roberto Fresca
/****************************************************************************************
GAME-A-TRON gambling hardware.
@ -66,7 +67,7 @@
Identified the unknown writes as a init sequence for 1x PSG sound device.
Is a SN76489/496 family device, and can't be identified accurately due to
almost all devices are plastic covered.
almost all devices being plastic covered.
* PCB 3: BINGO.
@ -129,8 +130,8 @@
All games:
The first time the machine is turned on, will show the legend "DATA ERROR".
You must to RESET (F3) the machine to initialize the NVRAM properly.
The first time the machine is turned on, it will show the legend "DATA ERROR".
You must RESET (F3) the machine to initialize the NVRAM properly.
NOTE: These games are intended to be for amusement only.
There is not such a payout system, so... Don't ask about it!
@ -322,24 +323,95 @@
#include "emu.h"
#include "gatron.h"
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "machine/nvram.h"
#include "sound/sn76496.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#include "bingo.lh"
#include "poker41.lh"
#include "pulltabs.lh"
#define MASTER_CLOCK XTAL(16'000'000)
#define CPU_CLOCK MASTER_CLOCK / 24 // 666.66 kHz, guess...
namespace {
class gatron_state : public driver_device
{
public:
gatron_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_lamps(*this, "lamp%u", 0U) { }
void gat(machine_config &config);
protected:
virtual void video_start() override;
private:
required_shared_ptr<uint8_t> m_videoram;
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
output_finder<9> m_lamps;
tilemap_t *m_bg_tilemap = nullptr;
void output_port_0_w(uint8_t data);
void output_port_1_w(uint8_t data);
void videoram_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void prg_map(address_map &map);
void port_map(address_map &map);
};
// video
void gatron_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
TILE_GET_INFO_MEMBER(gatron_state::get_bg_tile_info)
{
/* - bits -
7654 3210
xxxx xxxx tiles code.
only one color code
*/
int const code = m_videoram[tile_index];
tileinfo.set(0, code, 0, 0);
}
void gatron_state::video_start()
{
m_lamps.resolve();
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gatron_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 16, 48, 16);
}
uint32_t gatron_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
// machine
/****************************
* Read/Write Handlers *
@ -445,16 +517,16 @@ void gatron_state::output_port_1_w(uint8_t data)
* Memory Map Information *
*************************/
void gatron_state::gat_map(address_map &map)
void gatron_state::prg_map(address_map &map)
{
map(0x0000, 0x5fff).rom();
map(0x6000, 0x63ff).ram().w(FUNC(gatron_state::videoram_w)).share("videoram");
map(0x8000, 0x87ff).ram().share("nvram"); /* battery backed RAM */
map(0xa000, 0xa000).w("snsnd", FUNC(sn76489_device::write)); /* PSG */
map(0xe000, 0xe000).w(FUNC(gatron_state::output_port_0_w)); /* lamps */
map(0x6000, 0x63ff).ram().w(FUNC(gatron_state::videoram_w)).share(m_videoram);
map(0x8000, 0x87ff).ram().share("nvram"); // battery backed RAM
map(0xa000, 0xa000).w("snsnd", FUNC(sn76489_device::write)); // PSG
map(0xe000, 0xe000).w(FUNC(gatron_state::output_port_0_w)); // lamps
}
void gatron_state::gat_portmap(address_map &map)
void gatron_state::port_map(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x03).rw("ppi8255", FUNC(i8255_device::read), FUNC(i8255_device::write));
@ -539,14 +611,13 @@ INPUT_PORTS_END
static const gfx_layout charlayout =
{
8, 16,
RGN_FRAC(1,3), /* 256 tiles */
RGN_FRAC(1,3), // 256 tiles
3,
{ 0, RGN_FRAC(1,3), RGN_FRAC(2,3) }, /* bitplanes are separated */
{ 0, RGN_FRAC(1,3), RGN_FRAC(2,3) }, // bitplanes are separated
{ 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, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
16*8 /* every char takes 16 consecutive bytes */
16*8 // every char takes 16 consecutive bytes
};
@ -555,7 +626,7 @@ static const gfx_layout charlayout =
******************************/
static GFXDECODE_START( gfx_gat )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 16 )
GFXDECODE_ENTRY( "chars", 0, charlayout, 0, 16 )
GFXDECODE_END
@ -565,10 +636,13 @@ GFXDECODE_END
void gatron_state::gat(machine_config &config)
{
/* basic machine hardware */
static constexpr XTAL MASTER_CLOCK = XTAL(16'000'000);
static constexpr XTAL CPU_CLOCK = MASTER_CLOCK / 24; // 666.66 kHz, guess...
// basic machine hardware
Z80(config, m_maincpu, CPU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &gatron_state::gat_map);
m_maincpu->set_addrmap(AS_IO, &gatron_state::gat_portmap);
m_maincpu->set_addrmap(AS_PROGRAM, &gatron_state::prg_map);
m_maincpu->set_addrmap(AS_IO, &gatron_state::port_map);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
@ -577,7 +651,7 @@ void gatron_state::gat(machine_config &config)
ppi.in_pb_callback().set_ioport("IN1");
ppi.out_pc_callback().set(FUNC(gatron_state::output_port_1_w));
/* 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));
@ -590,9 +664,9 @@ void gatron_state::gat(machine_config &config)
GFXDECODE(config, m_gfxdecode, "palette", gfx_gat);
PALETTE(config, "palette").set_entries(8);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
SN76489(config, "snsnd", MASTER_CLOCK/8).add_route(ALL_OUTPUTS, "mono", 2.00); // Present in Bingo PCB. Clock need to be verified.
SN76489(config, "snsnd", MASTER_CLOCK / 8).add_route(ALL_OUTPUTS, "mono", 2.00); // Present in Bingo PCB. Clock needs to be verified.
}
@ -605,7 +679,7 @@ ROM_START( poker41 )
ROM_LOAD( "poker.u00", 0x0000, 0x2000, CRC(8361fccd) SHA1(4faae6bb3104c1f4a0939d613966085d7e34c1df))
ROM_LOAD( "poker-4-1.u08", 0x2000, 0x1000, CRC(61e71f31) SHA1(b8d162a47752cff7412b3920ec9dd7a469e81e62) )
ROM_REGION( 0x3000, "gfx1", 0 )
ROM_REGION( 0x3000, "chars", 0 )
ROM_LOAD( "black.u33", 0x0000, 0x1000, CRC(3f8a2d59) SHA1(d61dce33aa8637105905830e2f37c1052c441194) )
ROM_LOAD( "poker-g.u32", 0x1000, 0x1000, CRC(3e7772b2) SHA1(c7499ff148e5a9cbf0958820c41ea09a843ab355) )
ROM_LOAD( "poker-r.u31", 0x2000, 0x1000, CRC(18d090ec) SHA1(3504f18b3984d16545dbe61a03fbf6b8e2027150) )
@ -615,7 +689,7 @@ ROM_START( pulltabs )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "pull-tabs-1-90.u00", 0x0000, 0x2000, CRC(7cfd490d) SHA1(8eb360f8f4806a4281dae12236d30aa86d00993d) )
ROM_REGION( 0x3000, "gfx1", 0 )
ROM_REGION( 0x3000, "chars", 0 )
ROM_LOAD( "pt-3b-v.u33", 0x0000, 0x1000, CRC(3505cec1) SHA1(98ab0383c4be382aea81ab93433f2f29a075f65d) )
ROM_LOAD( "pt-2g-v.u32", 0x1000, 0x1000, CRC(4a3f4f36) SHA1(3dc29f78b7df1a433d0b39bfeaa227615e70ceed) )
ROM_LOAD( "pt-1r-v.u31", 0x2000, 0x1000, CRC(6d1b80f4) SHA1(f2da4b4ae1eb05f9ea02e7495ee8110698cc5d1b) )
@ -625,18 +699,20 @@ ROM_START( bingo )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "revb.u2", 0x0000, 0x2000, CRC(0322e2b5) SHA1(e191ad00de56e448a41350e32fb6a4828050a2d4) )
ROM_REGION( 0x3000, "gfx1", 0 )
ROM_REGION( 0x3000, "chars", 0 )
ROM_LOAD( "revb.u23", 0x0000, 0x1000, CRC(8d15fc35) SHA1(e66abaead70e6c024efbf177f1a4616449f2d231) )
ROM_LOAD( "revb.u22", 0x1000, 0x1000, CRC(60254c3b) SHA1(4b9e57a8ac9e6e2c6349d6847bbf3f46232721ad) )
ROM_LOAD( "revb.u21", 0x2000, 0x1000, CRC(b8cc348b) SHA1(34a4690f6464db17ee363bba8709d0ad63aa7cf1) )
ROM_END
} // anonymous namespace
/*************************
* Game Drivers *
*************************/
/* YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS LAYOUT */
GAMEL( 1983, poker41, 0, gat, poker41, gatron_state, empty_init, ROT0, "Game-A-Tron", "Four In One Poker", MACHINE_SUPPORTS_SAVE, layout_poker41 )
GAMEL( 1983, pulltabs, 0, gat, pulltabs, gatron_state, empty_init, ROT0, "Game-A-Tron", "Pull Tabs", MACHINE_SUPPORTS_SAVE, layout_pulltabs )
GAMEL( 1983, bingo, 0, gat, bingo, gatron_state, empty_init, ROT0, "Game-A-Tron", "Bingo", MACHINE_SUPPORTS_SAVE, layout_bingo )
// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS LAYOUT
GAMEL( 1983, poker41, 0, gat, poker41, gatron_state, empty_init, ROT0, "Game-A-Tron", "Four In One Poker", MACHINE_SUPPORTS_SAVE, layout_poker41 )
GAMEL( 1983, pulltabs, 0, gat, pulltabs, gatron_state, empty_init, ROT0, "Game-A-Tron", "Pull Tabs", MACHINE_SUPPORTS_SAVE, layout_pulltabs )
GAMEL( 1983, bingo, 0, gat, bingo, gatron_state, empty_init, ROT0, "Game-A-Tron", "Bingo", MACHINE_SUPPORTS_SAVE, layout_bingo )

View File

@ -1,37 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Roberto Fresca
#include "tilemap.h"
class gatron_state : public driver_device
{
public:
gatron_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_lamps(*this, "lamp%u", 0U) { }
void gat(machine_config &config);
protected:
virtual void video_start() override;
private:
required_shared_ptr<uint8_t> m_videoram;
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
output_finder<9> m_lamps;
tilemap_t *m_bg_tilemap = nullptr;
void output_port_0_w(uint8_t data);
void videoram_w(offs_t offset, uint8_t data);
void output_port_1_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);
void gat_map(address_map &map);
void gat_portmap(address_map &map);
};

View File

@ -1,57 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Roberto Fresca
/******************************************************************************
GAME-A-TRON gambling hardware
-----------------------------
*** Video Hardware ***
Written by Roberto Fresca.
Games running on this hardware:
* Poker 4-1, 1983, Game-A-Tron.
* Pull Tabs, 1983, Game-A-Tron.
*******************************************************************************/
#include "emu.h"
#include "gatron.h"
void gatron_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
TILE_GET_INFO_MEMBER(gatron_state::get_bg_tile_info)
{
/* - bits -
7654 3210
xxxx xxxx tiles code.
only one color code
*/
int code = m_videoram[tile_index];
tileinfo.set(0, code, 0, 0);
}
void gatron_state::video_start()
{
m_lamps.resolve();
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gatron_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 16, 48, 16);
}
uint32_t gatron_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
// copyright-holders: David Haywood
/*
Space Bugger
@ -7,8 +8,8 @@ Game-A-Tron, 1981
TS 20060821:
- there's really huge difference between both sets (code and data). weird
- wrong colors, it looks like there's direct color mapping - bits from attribute ram connected to r/g/b outputs without
use of color prom or color table
- wrong colors, it looks like there's direct color mapping - bits from attribute RAM connected to r/g/b outputs without
use of color PROM or color table
- interrupt is generated by 8156 - very old combination chip containing 256*8 RAM (used as stack area),
a timer and 8+8+6 ports. After game start all 8156 ports are set as inputs, timer is working in mode 3 - automatic reload.
TC register is set to 0x7f. Timer input frequency is unknown. Output should be close to 1440 Hz.
@ -100,27 +101,118 @@ Sound PCB
*/
#include "emu.h"
#include "sbugger.h"
#include "cpu/i8085/i8085.h"
#include "machine/i8155.h"
#include "sound/sn76496.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
/* memory maps */
namespace {
void sbugger_state::sbugger_map(address_map &map)
class sbugger_state : public driver_device
{
public:
sbugger_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_videoram_attr(*this, "videoram_attr"),
m_videoram(*this, "videoram")
{ }
void sbugger(machine_config &config);
protected:
virtual void video_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint8_t> m_videoram_attr;
required_shared_ptr<uint8_t> m_videoram;
tilemap_t *m_tilemap = nullptr;
void videoram_w(offs_t offset, uint8_t data);
void videoram_attr_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
void palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void io_map(address_map &map);
void prg_map(address_map &map);
};
// video
TILE_GET_INFO_MEMBER(sbugger_state::get_tile_info)
{
int const tileno = m_videoram[tile_index];
int const color = m_videoram_attr[tile_index];
tileinfo.set(0,tileno,color,0);
}
void sbugger_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_tilemap->mark_tile_dirty(offset);
}
void sbugger_state::videoram_attr_w(offs_t offset, uint8_t data)
{
m_videoram_attr[offset] = data;
m_tilemap->mark_tile_dirty(offset);
}
void sbugger_state::video_start()
{
m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sbugger_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 16, 64, 16);
}
uint32_t sbugger_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
// not right but so we can see things OK
void sbugger_state::palette(palette_device &palette) const
{
// just some random colours for now
for (int i = 0; i < 256; i++)
{
int const r = i ? (machine().rand() | 0x80) : 0;
int const g = i ? (machine().rand() | 0x80) : 0;
int const b = i ? (machine().rand() | 0x80) : 0;
palette.set_pen_color(i * 2 + 1, rgb_t(r, g, b));
palette.set_pen_color(i * 2, rgb_t(0, 0, 0));
}
}
// machine
void sbugger_state::prg_map(address_map &map)
{
map(0x0000, 0x37ff).rom();
map(0xc800, 0xcbff).ram().w(FUNC(sbugger_state::videoram_attr_w)).share("videoram_attr");
map(0xcc00, 0xcfff).ram().w(FUNC(sbugger_state::videoram_w)).share("videoram");
map(0xe000, 0xe0ff).rw("i8156", FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); /* sp is set to e0ff */
map(0xc800, 0xcbff).ram().w(FUNC(sbugger_state::videoram_attr_w)).share(m_videoram_attr);
map(0xcc00, 0xcfff).ram().w(FUNC(sbugger_state::videoram_w)).share(m_videoram);
map(0xe000, 0xe0ff).rw("i8156", FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); // sp is set to e0ff
map(0xf400, 0xffff).ram();
}
void sbugger_state::sbugger_io_map(address_map &map)
void sbugger_state::io_map(address_map &map)
{
map(0xe0, 0xe7).rw("i8156", FUNC(i8155_device::io_r), FUNC(i8155_device::io_w));
map(0xe8, 0xe8).w("sn76489.1", FUNC(sn76489_device::write));
@ -128,8 +220,6 @@ void sbugger_state::sbugger_io_map(address_map &map)
}
/* gfx decode */
static const gfx_layout char16layout =
{
8,16,
@ -144,12 +234,10 @@ static const gfx_layout char16layout =
};
static GFXDECODE_START( gfx_sbugger )
GFXDECODE_ENTRY( "gfx1", 0, char16layout, 0, 256 )
GFXDECODE_ENTRY( "chars", 0, char16layout, 0, 256 )
GFXDECODE_END
/* input ports */
static INPUT_PORTS_START( sbugger )
PORT_START("INPUTS")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_2WAY
@ -211,16 +299,13 @@ static INPUT_PORTS_START( sbugger )
INPUT_PORTS_END
/* machine driver */
void sbugger_state::sbugger(machine_config &config)
{
I8085A(config, m_maincpu, 6000000); /* 3.00 MHz??? */
m_maincpu->set_addrmap(AS_PROGRAM, &sbugger_state::sbugger_map);
m_maincpu->set_addrmap(AS_IO, &sbugger_state::sbugger_io_map);
I8085A(config, m_maincpu, 6'000'000); // 3.00 MHz???
m_maincpu->set_addrmap(AS_PROGRAM, &sbugger_state::prg_map);
m_maincpu->set_addrmap(AS_IO, &sbugger_state::io_map);
i8156_device &i8156(I8156(config, "i8156", 200000)); /* freq is an approximation */
i8156_device &i8156(I8156(config, "i8156", 200'000)); // freq is an approximation
i8156.in_pa_callback().set_ioport("INPUTS");
i8156.in_pb_callback().set_ioport("DSW1");
i8156.in_pc_callback().set_ioport("DSW2");
@ -236,36 +321,33 @@ void sbugger_state::sbugger(machine_config &config)
screen.set_screen_update(FUNC(sbugger_state::screen_update));
screen.set_palette("palette");
PALETTE(config, "palette", FUNC(sbugger_state::sbugger_palette), 512);
PALETTE(config, "palette", FUNC(sbugger_state::palette), 512);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
SN76489(config, "sn76489.1", 3000000).add_route(ALL_OUTPUTS, "mono", 1.0);
SN76489(config, "sn76489.1", 3'000'000).add_route(ALL_OUTPUTS, "mono", 1.0);
SN76489(config, "sn76489.2", 3000000).add_route(ALL_OUTPUTS, "mono", 1.0);
SN76489(config, "sn76489.2", 3'000'000).add_route(ALL_OUTPUTS, "mono", 1.0);
}
/* rom loading */
ROM_START( sbugger )
ROM_REGION( 0x10000, "maincpu", 0 ) /* 8085 Code */
ROM_REGION( 0x10000, "maincpu", 0 ) // 8085 code
ROM_LOAD( "spbugger.u35", 0x0000, 0x0800, CRC(7c2000a1) SHA1(01a60745ea8e9a70de37d1a785fad1d17eafc812) ) // seems to map at 0
ROM_LOAD( "spbugger.u22", 0x0800, 0x0800, BAD_DUMP CRC(66e00c53) SHA1(49ca567a98978308306cdb8455c61c022668693b) ) // FIXED BITS (xxxx1111) it jumps here .... bad rom?
ROM_LOAD( "spbugger.u22", 0x0800, 0x0800, BAD_DUMP CRC(66e00c53) SHA1(49ca567a98978308306cdb8455c61c022668693b) ) // FIXED BITS (xxxx1111) it jumps here .... bad ROM?
ROM_LOAD( "spbugger.u34", 0x1000, 0x0800, CRC(db357dde) SHA1(363392b971f48e9d99f4167aa17f0c885b0865ee) ) // seems to map at 1000
ROM_LOAD( "spbugger.u21", 0x1800, 0x0800, CRC(618a5b2a) SHA1(aa7a40b1944f09c396f675d7dd3a8c3c35bf01f1) ) // seems to map at 1800
ROM_LOAD( "spbugger.u20", 0x2000, 0x0800, CRC(8957563c) SHA1(b33a75fcf375d2a1a766105f87dd8e4d42db3d76) ) // seems to map at 2000
ROM_LOAD( "spbugger.u33", 0x2800, 0x0800, CRC(f6cb1399) SHA1(53cb67e29a238c5ac20c6be9423d850e004212c1) ) // seems to map at 2800
ROM_LOAD( "spbugger.u32", 0x3000, 0x0800, CRC(f49af2b3) SHA1(1519ee4786b78546767827d3a9508e7ddb646765) ) // seems to map at 3000
ROM_REGION( 0x1000, "gfx1", 0 ) /* GFX */
ROM_REGION( 0x1000, "chars", 0 )
ROM_LOAD( "spbugger.gfx", 0x0000, 0x1000, CRC(d3f345b5) SHA1(a5082ffc3043352e9b731af95770bdd62fb928bf) )
ROM_END
ROM_START( sbuggera )
ROM_REGION( 0x10000, "maincpu", 0 ) /* 8085 Code */
ROM_REGION( 0x10000, "maincpu", 0 ) // 8085 code
ROM_LOAD( "bug_g10.u35", 0x0000, 0x0800, CRC(60a3044d) SHA1(5b2be551a84e4a7a35637208a19b3477629f20d9) )
ROM_LOAD( "bug_c10.u22", 0x0800, 0x0800, CRC(34a829f7) SHA1(135ec2739879c2e47f3c6d4a5196c865b5940a84) )
ROM_LOAD( "bug_f10.u34", 0x1000, 0x0800, CRC(e2f7a51c) SHA1(ee221f6697021d14838fd6c4aff41678ce62e4ba) )
@ -274,9 +356,12 @@ ROM_START( sbuggera )
ROM_LOAD( "bug_e10.u33", 0x2800, 0x0800, CRC(fefd9c5e) SHA1(1b0bbf462231c32014d45ec21b105a669665d90d) )
ROM_LOAD( "bug_d10.u32", 0x3000, 0x0800, BAD_DUMP CRC(c807742f) SHA1(cb5c44ffd6dd184c6a0722003ff6674caf865bee) ) // missing in this set
ROM_REGION( 0x4000, "gfx1", 0 ) /* GFX */
ROM_REGION( 0x4000, "chars", 0 )
ROM_LOAD( "spbugger.gfx", 0x0000, 0x1000, CRC(d3f345b5) SHA1(a5082ffc3043352e9b731af95770bdd62fb928bf) )
ROM_END
} // anonymous namespace
GAME( 1981, sbugger, 0, sbugger, sbugger, sbugger_state, empty_init, ROT270, "Game-A-Tron", "Space Bugger (set 1)", MACHINE_NOT_WORKING | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
GAME( 1981, sbuggera, sbugger, sbugger, sbugger, sbugger_state, empty_init, ROT270, "Game-A-Tron", "Space Bugger (set 2)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )

View File

@ -1,46 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_INCLUDES_SBUGGER_H
#define MAME_INCLUDES_SBUGGER_H
#pragma once
#include "emupal.h"
#include "tilemap.h"
class sbugger_state : public driver_device
{
public:
sbugger_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_videoram_attr(*this, "videoram_attr"),
m_videoram(*this, "videoram")
{ }
void sbugger(machine_config &config);
private:
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint8_t> m_videoram_attr;
required_shared_ptr<uint8_t> m_videoram;
tilemap_t *m_tilemap = nullptr;
void videoram_w(offs_t offset, uint8_t data);
void videoram_attr_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
virtual void video_start() override;
void sbugger_palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void sbugger_io_map(address_map &map);
void sbugger_map(address_map &map);
};
#endif // MAME_INCLUDES_SBUGGER_H

View File

@ -1,54 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/* Space Bugger - Video Hardware */
#include "emu.h"
#include "sbugger.h"
TILE_GET_INFO_MEMBER(sbugger_state::get_tile_info)
{
int tileno, color;
tileno = m_videoram[tile_index];
color = m_videoram_attr[tile_index];
tileinfo.set(0,tileno,color,0);
}
void sbugger_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_tilemap->mark_tile_dirty(offset);
}
void sbugger_state::videoram_attr_w(offs_t offset, uint8_t data)
{
m_videoram_attr[offset] = data;
m_tilemap->mark_tile_dirty(offset);
}
void sbugger_state::video_start()
{
m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sbugger_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 16, 64, 16);
}
uint32_t sbugger_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_tilemap->draw(screen, bitmap, cliprect, 0,0);
return 0;
}
// not right but so we can see things OK
void sbugger_state::sbugger_palette(palette_device &palette) const
{
// just some random colours for now
for (int i = 0; i < 256; i++)
{
int const r = i ? (machine().rand() | 0x80) : 0;
int const g = i ? (machine().rand() | 0x80) : 0;
int const b = i ? (machine().rand() | 0x80) : 0;
palette.set_pen_color(i*2+1, rgb_t(r, g, b));
palette.set_pen_color(i*2, rgb_t(0, 0, 0));
}
}

View File

@ -157,4 +157,4 @@ ROM_END
} // anonymous namespace
GAME( 1987, smb3bl, 0, smb3bl, smb3bl, nes_arcade_bl_state, empty_init, ROT0, "Sang Ho Soft", "Super Mario Bros. 3 (NES bootleg)", 0 ) // 1987.10.01 in Z80 ROM
GAME( 1987, smb3bl, 0, smb3bl, smb3bl, nes_arcade_bl_state, empty_init, ROT0, "Sang Ho Soft", "Super Mario Bros. 3 (NES bootleg)", MACHINE_IS_SKELETON ) // 1987.10.01 in Z80 ROM