mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
atari/klax.cpp, atari/liberatr.cpp, atari/metalmx.cpp, atari/nitedrvr.cpp: consolidated drivers in single files
This commit is contained in:
parent
2913bbaaf8
commit
2b9da4a413
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Klax hardware
|
||||
@ -20,16 +21,208 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "klax.h"
|
||||
|
||||
#include "atarimo.h"
|
||||
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/eeprompar.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/msm5205.h"
|
||||
#include "sound/okim6295.h"
|
||||
#include "emupal.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class klax_state : public driver_device
|
||||
{
|
||||
public:
|
||||
klax_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_playfield_tilemap(*this, "playfield")
|
||||
, m_mob(*this, "mob")
|
||||
, m_p1(*this, "P1")
|
||||
{ }
|
||||
|
||||
void klax(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
|
||||
required_ioport m_p1;
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
|
||||
void klax_base(machine_config &config);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline_update);
|
||||
|
||||
void interrupt_ack_w(u16 data = 0);
|
||||
|
||||
void latch_w(u16 data);
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void klax_map(address_map &map);
|
||||
};
|
||||
|
||||
class klax_bootleg_state : public klax_state
|
||||
{
|
||||
public:
|
||||
klax_bootleg_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: klax_state(mconfig, type, tag)
|
||||
, m_audiocpu(*this, "audiocpu")
|
||||
, m_msm(*this, "msm%u", 1)
|
||||
, m_rombank(*this, "rombank")
|
||||
, m_audio_ram(*this, "audioram")
|
||||
{ }
|
||||
|
||||
void klax5bl(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
void m5205_int1(int state);
|
||||
|
||||
void bootleg_sound_map(address_map &map);
|
||||
void klax5bl_map(address_map &map);
|
||||
|
||||
u16 audio_ram_r(offs_t offset);
|
||||
void audio_ram_w(offs_t offset, u16 data);
|
||||
void audio_sample_w(offs_t offset, u8 data);
|
||||
void audio_ctrl_w(u8 data);
|
||||
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device_array<msm5205_device, 2> m_msm;
|
||||
required_memory_bank m_rombank;
|
||||
required_shared_ptr<u8> m_audio_ram;
|
||||
u8 m_audio_sample[2]{};
|
||||
bool m_audio_nibble = false;
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(klax_state::get_playfield_tile_info)
|
||||
{
|
||||
const u16 data1 = m_playfield_tilemap->basemem_read(tile_index);
|
||||
const u16 data2 = m_playfield_tilemap->extmem_read(tile_index) >> 8;
|
||||
const u32 code = data1 & 0x1fff;
|
||||
const u32 color = data2 & 0x0f;
|
||||
tileinfo.set(0, code, color, (data1 >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config klax_state::s_mob_config =
|
||||
{
|
||||
1, // index to which gfx system
|
||||
1, // number of motion object banks
|
||||
1, // are the entries linked?
|
||||
0, // are the entries split?
|
||||
0, // render in reverse order?
|
||||
0, // render in swapped X/Y order?
|
||||
0, // does the neighbor bit affect the next object?
|
||||
8, // pixels per SLIP entry (0 for no-slip)
|
||||
0, // pixel offset for SLIPs
|
||||
0, // maximum number of links to visit/scanline (0=all)
|
||||
|
||||
0x000, // base palette entry
|
||||
0x100, // maximum number of colors
|
||||
0, // transparent pen index
|
||||
|
||||
{{ 0x00ff,0,0,0 }}, // mask for the link
|
||||
{{ 0,0x0fff,0,0 }}, // mask for the code index
|
||||
{{ 0,0,0x000f,0 }}, // mask for the color
|
||||
{{ 0,0,0xff80,0 }}, // mask for the X position
|
||||
{{ 0,0,0,0xff80 }}, // mask for the Y position
|
||||
{{ 0,0,0,0x0070 }}, // mask for the width, in tiles
|
||||
{{ 0,0,0,0x0007 }}, // mask for the height, in tiles
|
||||
{{ 0,0,0,0x0008 }}, // mask for the horizontal flip
|
||||
{{ 0 }}, // mask for the vertical flip
|
||||
{{ 0 }}, // mask for the priority
|
||||
{{ 0 }}, // mask for the neighbor
|
||||
{{ 0 }}, // mask for absolute coordinates
|
||||
|
||||
{{ 0 }}, // mask for the special value
|
||||
0 // resulting value to indicate "special"
|
||||
};
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Latch write handler
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void klax_state::latch_w(u16 data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
u32 klax_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
// draw the playfield
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
u16 const *const mo = &mobitmap.pix(y);
|
||||
u16 *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* verified from schematics:
|
||||
|
||||
PFPRI if (PFS7-4 == 0 || LBPIX3-0 == 0)
|
||||
*/
|
||||
if ((pf[x] & 0xf0) != 0xf0)
|
||||
pf[x] = mo[x];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -39,9 +232,9 @@
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(klax_state::scanline_update)
|
||||
{
|
||||
int scanline = param;
|
||||
const int scanline = param;
|
||||
|
||||
/* generate 32V signals */
|
||||
// generate 32V signals
|
||||
if ((scanline & 32) == 0 && !m_screen->vblank() && !(m_p1->read() & 0x800))
|
||||
m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE);
|
||||
}
|
||||
@ -78,10 +271,6 @@ void klax_bootleg_state::m5205_int1(int state)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void klax_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
void klax_bootleg_state::machine_start()
|
||||
{
|
||||
m_rombank->configure_entries(0, 4, memregion("audiocpu")->base(), 0x8000);
|
||||
@ -172,8 +361,8 @@ INPUT_PORTS_END
|
||||
*************************************/
|
||||
|
||||
static GFXDECODE_START( gfx_klax )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 256, 16 ) /* playfield */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, gfx_8x8x4_packed_msb, 0, 16 ) /* sprites */
|
||||
GFXDECODE_ENTRY( "tiles", 0, gfx_8x8x4_packed_msb, 256, 16 )
|
||||
GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_packed_msb, 0, 16 )
|
||||
GFXDECODE_END
|
||||
|
||||
static const gfx_layout bootleg_layout =
|
||||
@ -188,8 +377,8 @@ static const gfx_layout bootleg_layout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_klax5bl )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, bootleg_layout, 256, 16 ) /* playfield */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, gfx_8x8x4_packed_msb, 0, 16 ) /* sprites */
|
||||
GFXDECODE_ENTRY( "tiles", 0, bootleg_layout, 256, 16 )
|
||||
GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_packed_msb, 0, 16 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
@ -201,13 +390,13 @@ GFXDECODE_END
|
||||
|
||||
void klax_state::klax_base(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M68000(config, m_maincpu, 14.318181_MHz_XTAL/2);
|
||||
// basic machine hardware
|
||||
M68000(config, m_maincpu, 14.318181_MHz_XTAL / 2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &klax_state::klax_map);
|
||||
|
||||
EEPROM_2816(config, "eeprom").lock_after_write(true);
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
GFXDECODE(config, m_gfxdecode, "palette", gfx_klax);
|
||||
PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 512).set_membits(8);
|
||||
|
||||
@ -219,9 +408,9 @@ void klax_state::klax_base(machine_config &config)
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
|
||||
/* note: these parameters are from published specs, not derived */
|
||||
/* the board uses an SOS-2 chip to generate video signals */
|
||||
m_screen->set_raw(14.318181_MHz_XTAL/2, 456, 0, 336, 262, 0, 240);
|
||||
/* note: these parameters are from published specs, not derived
|
||||
the board uses an SOS-2 chip to generate video signals */
|
||||
m_screen->set_raw(14.318181_MHz_XTAL / 2, 456, 0, 336, 262, 0, 240);
|
||||
m_screen->set_screen_update(FUNC(klax_state::screen_update));
|
||||
m_screen->set_palette("palette");
|
||||
m_screen->screen_vblank().set_inputline(m_maincpu, M68K_IRQ_4, ASSERT_LINE);
|
||||
@ -250,7 +439,7 @@ void klax_bootleg_state::bootleg_sound_map(address_map &map)
|
||||
map(0x3800, 0x3800).nopw(); // ?
|
||||
map(0x4f00, 0x4f7f).ram().share(m_audio_ram);
|
||||
map(0x4f80, 0x4fff).ram();
|
||||
map(0x8000, 0xffff).bankr("rombank");
|
||||
map(0x8000, 0xffff).bankr(m_rombank);
|
||||
}
|
||||
|
||||
void klax_bootleg_state::klax5bl(machine_config &config)
|
||||
@ -259,40 +448,40 @@ void klax_bootleg_state::klax5bl(machine_config &config)
|
||||
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &klax_bootleg_state::klax5bl_map);
|
||||
|
||||
Z80(config, m_audiocpu, 14.318181_MHz_XTAL / 2); /* ? */
|
||||
Z80(config, m_audiocpu, 14.318181_MHz_XTAL / 2); // ?
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &klax_bootleg_state::bootleg_sound_map);
|
||||
|
||||
m_mob->set_origin(8, 7); // sprites are offset in bootlegs
|
||||
m_gfxdecode->set_info(gfx_klax5bl);
|
||||
|
||||
MSM5205(config, m_msm[0], 384000); // clock speed / prescaler not verified
|
||||
MSM5205(config, m_msm[0], 384'000); // clock speed / prescaler not verified
|
||||
m_msm[0]->vck_callback().set(FUNC(klax_bootleg_state::m5205_int1));
|
||||
m_msm[0]->set_prescaler_selector(msm5205_device::S64_4B); /* ? */
|
||||
m_msm[0]->set_prescaler_selector(msm5205_device::S64_4B); // ?
|
||||
m_msm[0]->add_route(ALL_OUTPUTS, "mono", 1.00);
|
||||
|
||||
MSM5205(config, m_msm[1], 384000);
|
||||
MSM5205(config, m_msm[1], 384'000);
|
||||
m_msm[1]->set_prescaler_selector(msm5205_device::S64_4B);
|
||||
m_msm[1]->add_route(ALL_OUTPUTS, "mono", 1.00);
|
||||
}
|
||||
|
||||
uint16_t klax_bootleg_state::audio_ram_r(offs_t offset)
|
||||
u16 klax_bootleg_state::audio_ram_r(offs_t offset)
|
||||
{
|
||||
return (m_audio_ram[offset << 1] << 8) | m_audio_ram[(offset << 1) | 1];
|
||||
}
|
||||
|
||||
void klax_bootleg_state::audio_ram_w(offs_t offset, uint16_t data)
|
||||
void klax_bootleg_state::audio_ram_w(offs_t offset, u16 data)
|
||||
{
|
||||
m_audio_ram[offset << 1] = data >> 8;
|
||||
m_audio_ram[(offset << 1) | 1] = data & 0xff;
|
||||
}
|
||||
|
||||
void klax_bootleg_state::audio_sample_w(offs_t offset, uint8_t data)
|
||||
void klax_bootleg_state::audio_sample_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (offset & 2) m_audio_sample[0] = data;
|
||||
if (offset & 1) m_audio_sample[1] = data;
|
||||
}
|
||||
|
||||
void klax_bootleg_state::audio_ctrl_w(uint8_t data)
|
||||
void klax_bootleg_state::audio_ctrl_w(u8 data)
|
||||
{
|
||||
m_rombank->set_entry(data & 3);
|
||||
|
||||
@ -311,27 +500,27 @@ void klax_bootleg_state::audio_ctrl_w(uint8_t data)
|
||||
*************************************/
|
||||
|
||||
ROM_START( klax )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136075-6006.3n", 0x00000, 0x10000, CRC(e8991709) SHA1(90d69b0712e68e842a8b946539f1f43ef165e8de) )
|
||||
ROM_LOAD16_BYTE( "136075-6005.1n", 0x00001, 0x10000, CRC(72b8c510) SHA1(f79d3a2de4deaabbcec632e8be9a1d5f6c0c3740) )
|
||||
ROM_LOAD16_BYTE( "136075-6008.3k", 0x20000, 0x10000, CRC(c7c91a9d) SHA1(9f79ca689ec635f8113a74162e81f253c88992f5) )
|
||||
ROM_LOAD16_BYTE( "136075-6007.1k", 0x20001, 0x10000, CRC(d2021a88) SHA1(0f8a0dcc3bb5ca433601b1abfc796c98791facf6) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -341,27 +530,27 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( klax5 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "13607-5006.3n", 0x00000, 0x10000, CRC(05c98fc0) SHA1(84880d3d65c46c96c739063b3f61b1663989c56e) )
|
||||
ROM_LOAD16_BYTE( "13607-5005.1n", 0x00001, 0x10000, CRC(d461e1ee) SHA1(73e8615a742555f74c1086c0b745afc7e94a478f) )
|
||||
ROM_LOAD16_BYTE( "13607-5008.3k", 0x20000, 0x10000, CRC(f1b8e588) SHA1(080511f90aecb7526ab2107c196e73cb881a2bb5) )
|
||||
ROM_LOAD16_BYTE( "13607-5007.1k", 0x20001, 0x10000, CRC(adbe33a8) SHA1(c6c4f9ea5224169dbf4dda1062954563ebab18d4) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -370,7 +559,7 @@ ROM_START( klax5 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( klax5bl ) // derived from 'klax5' set
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "6.bin", 0x00000, 0x10000, CRC(3cfd2748) SHA1(165c446bab9df6517746451d056330386cb5212c) )
|
||||
ROM_LOAD16_BYTE( "2.bin", 0x00001, 0x10000, CRC(910e5bf9) SHA1(2b5af427e7cbad8d4ed2a202900f227295e1dea9) )
|
||||
ROM_LOAD16_BYTE( "5.bin", 0x20000, 0x10000, CRC(4fcacf88) SHA1(4ad87b03ac4cdf763586f8bf5d54bee950b6779c) )
|
||||
@ -380,19 +569,19 @@ ROM_START( klax5bl ) // derived from 'klax5' set
|
||||
ROM_LOAD( "3.bin", 0x00000, 0x10000, CRC(b0441f1c) SHA1(edced52b86641ce6db934ba05435f1221a12809a) )
|
||||
ROM_LOAD( "4.bin", 0x10000, 0x10000, CRC(a245e005) SHA1(8843edfa9deec405f491647d40007d0a38c25262) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD32_BYTE( "11.bin", 0x00000, 0x10000, CRC(ef7712fd) SHA1(9308b37a8b024837b32d10e358a5205fdc582214) )
|
||||
ROM_LOAD32_BYTE( "12.bin", 0x00001, 0x10000, CRC(1e0c1262) SHA1(960d61b9751276e4d0dbfd3f07cadc1329079abc) )
|
||||
ROM_LOAD32_BYTE( "9.bin", 0x00002, 0x10000, CRC(ebe4bd96) SHA1(31f941e39aeaed6a64b35827df4d234cd641b47d) )
|
||||
ROM_LOAD32_BYTE( "10.bin", 0x00003, 0x10000, CRC(e7ad1cbd) SHA1(4b37cbe5d3168e532b00e8e34e7b8cf6d69e3487) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "7.bin", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "8.bin", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( klax5bl2 ) // derived from 'klax5' set, closer than klax5bl
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "3.ic31", 0x00000, 0x10000, CRC(e43699f3) SHA1(2a78959ad065e1c0f69cc2ba4146a50102ccfd7e) )
|
||||
ROM_LOAD16_BYTE( "1.ic13", 0x00001, 0x10000, CRC(dc67f13a) SHA1(6021f48b53f9000983bcd786b8366ba8638174de) )
|
||||
ROM_LOAD16_BYTE( "4.ic30", 0x20000, 0x10000, CRC(f1b8e588) SHA1(080511f90aecb7526ab2107c196e73cb881a2bb5) )
|
||||
@ -402,13 +591,13 @@ ROM_START( klax5bl2 ) // derived from 'klax5' set, closer than klax5bl
|
||||
ROM_LOAD( "6.ic22", 0x00000, 0x10000, CRC(edd4c42c) SHA1(22f992615afa24a7a671ed2f5cf08f25965d5b3a) ) // likely a bad dump of "3.bin" from klax5bl
|
||||
ROM_LOAD( "5.ic23", 0x10000, 0x10000, CRC(a245e005) SHA1(8843edfa9deec405f491647d40007d0a38c25262) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD32_BYTE( "12.ic134", 0x00000, 0x10000, CRC(ef7712fd) SHA1(9308b37a8b024837b32d10e358a5205fdc582214) )
|
||||
ROM_LOAD32_BYTE( "11.ic135", 0x00001, 0x10000, CRC(c2d8ce0c) SHA1(6b2f3c3f5f238dc00501646230dc8787dd862ed4) )
|
||||
ROM_LOAD32_BYTE( "8.ic116", 0x00002, 0x10000, CRC(ebe4bd96) SHA1(31f941e39aeaed6a64b35827df4d234cd641b47d) )
|
||||
ROM_LOAD32_BYTE( "7.ic117", 0x00003, 0x10000, CRC(3b79c0d3) SHA1(f6910f2526e1d92eae260b5eb73b1672db891f4b) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "10.ic101", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "9.ic102", 0x00001, 0x10000, CRC(29708e34) SHA1(6bea1527ad941fbb1abfad59ef3d78900dcd7f27) )
|
||||
|
||||
@ -420,7 +609,7 @@ ROM_START( klax5bl2 ) // derived from 'klax5' set, closer than klax5bl
|
||||
ROM_END
|
||||
|
||||
ROM_START( klax5bl3 ) // almost identical to klax5bl2, only the first audiocpu ROM differs
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "3.ic31", 0x00000, 0x10000, CRC(e43699f3) SHA1(2a78959ad065e1c0f69cc2ba4146a50102ccfd7e) )
|
||||
ROM_LOAD16_BYTE( "1.ic13", 0x00001, 0x10000, CRC(dc67f13a) SHA1(6021f48b53f9000983bcd786b8366ba8638174de) )
|
||||
ROM_LOAD16_BYTE( "4.ic30", 0x20000, 0x10000, CRC(f1b8e588) SHA1(080511f90aecb7526ab2107c196e73cb881a2bb5) )
|
||||
@ -430,13 +619,13 @@ ROM_START( klax5bl3 ) // almost identical to klax5bl2, only the first audiocpu R
|
||||
ROM_LOAD( "6.ic22", 0x00000, 0x10000, CRC(d2c40941) SHA1(34d35d9333c315e116198aebc7db00fce6ccceb0) )
|
||||
ROM_LOAD( "5.ic23", 0x10000, 0x10000, CRC(a245e005) SHA1(8843edfa9deec405f491647d40007d0a38c25262) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD32_BYTE( "12.ic134", 0x00000, 0x10000, CRC(ef7712fd) SHA1(9308b37a8b024837b32d10e358a5205fdc582214) )
|
||||
ROM_LOAD32_BYTE( "11.ic135", 0x00001, 0x10000, CRC(c2d8ce0c) SHA1(6b2f3c3f5f238dc00501646230dc8787dd862ed4) )
|
||||
ROM_LOAD32_BYTE( "8.ic116", 0x00002, 0x10000, CRC(ebe4bd96) SHA1(31f941e39aeaed6a64b35827df4d234cd641b47d) )
|
||||
ROM_LOAD32_BYTE( "7.ic117", 0x00003, 0x10000, CRC(3b79c0d3) SHA1(f6910f2526e1d92eae260b5eb73b1672db891f4b) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "10.ic101", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "9.ic102", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
@ -451,27 +640,27 @@ ROM_START( klax5bl3 ) // almost identical to klax5bl2, only the first audiocpu R
|
||||
ROM_END
|
||||
|
||||
ROM_START( klax4 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136075-5006.3n", 0x00000, 0x10000, CRC(65eb9a31) SHA1(3f47d58fe9eb154ab14ac282919f92679b5c7922) )
|
||||
ROM_LOAD16_BYTE( "136075-5005.1n", 0x00001, 0x10000, CRC(7be27349) SHA1(79eef2b7f4a0fb6991d81f6543d5ae00de9f2452) )
|
||||
ROM_LOAD16_BYTE( "136075-4008.3k", 0x20000, 0x10000, CRC(f3c79106) SHA1(c315159020d5bc6f919c3fb975fb8b228584f88c) )
|
||||
ROM_LOAD16_BYTE( "136075-4007.1k", 0x20001, 0x10000, CRC(a23cde5d) SHA1(51afadc900524d73ff7906b003fdf801f5d1f1fd) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -480,27 +669,27 @@ ROM_START( klax4 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( klaxj4 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136075-4406.3n", 0x00000, 0x10000, CRC(fc4045ec) SHA1(58441ffeb58c1dc9ef18f3c6381eec52923ffe03) )
|
||||
ROM_LOAD16_BYTE( "136075-4405.1n", 0x00001, 0x10000, CRC(f017461a) SHA1(a0acd66a48c2a964c3e8f2bdacd94908bfc84843) )
|
||||
ROM_LOAD16_BYTE( "136075-4408.3k", 0x20000, 0x10000, CRC(23231159) SHA1(a0ac57d358078f7fbec95964a2608213f79e4b6f) )
|
||||
ROM_LOAD16_BYTE( "136075-4407.1k", 0x20001, 0x10000, CRC(8d8158b2) SHA1(299570f16a6019c34f210bffe39ff8489f3f11f1) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -509,27 +698,27 @@ ROM_START( klaxj4 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( klaxj3 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136075-3406.3n", 0x00000, 0x10000, CRC(ab2aa50b) SHA1(0ebffc8b4724eb8c4423e0b1f62b0fff7cc30aab) )
|
||||
ROM_LOAD16_BYTE( "136075-3405.1n", 0x00001, 0x10000, CRC(9dc9a590) SHA1(4c77b1ad9c083325f33520f2b6aa598dde247ad8) )
|
||||
ROM_LOAD16_BYTE( "136075-2408.3k", 0x20000, 0x10000, CRC(89d515ce) SHA1(4991b859a53f34776671f660dbdb18a746259549) )
|
||||
ROM_LOAD16_BYTE( "136075-2407.1k", 0x20001, 0x10000, CRC(48ce4edb) SHA1(014f879298408295a338c19c2d518524b41491cb) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -539,27 +728,27 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( klaxd2 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136075-2206.3n", 0x00000, 0x10000, CRC(9d1a713b) SHA1(6e60a43934bd8959c5c07dd12e087c63ea791bb9) )
|
||||
ROM_LOAD16_BYTE( "136075-1205.1n", 0x00001, 0x10000, CRC(45065a5a) SHA1(77339ca04e54a04489ce9d6e11816475e57d1311) )
|
||||
ROM_LOAD16_BYTE( "136075-1208.3k", 0x20000, 0x10000, CRC(b4019b32) SHA1(83fba82a9100af14cddd812be9f3dbd58d8511d2) )
|
||||
ROM_LOAD16_BYTE( "136075-1207.1k", 0x20001, 0x10000, CRC(14550a75) SHA1(35599a339e6978682a09db4fb78c76bb3d3b6bc7) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2010.17x", 0x00000, 0x10000, CRC(15290a0d) SHA1(e1338f3fb298aae19735548f4b597d1c33944960) )
|
||||
ROM_LOAD16_BYTE( "136075-2009.17u", 0x00001, 0x10000, CRC(6368dbaf) SHA1(fa8b5cf6777108c0b1e38a3650ee4cdb2ec76810) )
|
||||
ROM_LOAD16_BYTE( "136075-2012.12x", 0x20000, 0x10000, CRC(c0d9eb0f) SHA1(aa68b9ad435eeaa8b43693e237cc7f9a53d94dfc) )
|
||||
ROM_LOAD16_BYTE( "136075-2011.12u", 0x20001, 0x10000, CRC(e83cca91) SHA1(45f1155d51ab3e2cc08aad1ec4e557d132085cc6) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx2", 0 )
|
||||
ROM_REGION( 0x20000, "sprites", 0 )
|
||||
ROM_LOAD16_BYTE( "136075-2014.17y", 0x00000, 0x10000, CRC(5c551e92) SHA1(cbff8fc4f4d370b6db2b4953ecbedd249916b891) )
|
||||
ROM_LOAD16_BYTE( "136075-2013.17w", 0x00001, 0x10000, CRC(36764bbc) SHA1(5762996a327b5f7f93f42dad7eccb6297b3e4c0b) )
|
||||
|
||||
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
|
||||
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
|
||||
ROM_LOAD( "136075-1015.14b", 0x00000, 0x10000, CRC(4d24c768) SHA1(da102105a4d8c552e3594b8ffb1903ecbaa69415) )
|
||||
ROM_LOAD( "136075-1016.12b", 0x10000, 0x10000, CRC(12e9b4b7) SHA1(2447f116cd865e46e61022143a2668beca99d5d1) )
|
||||
|
||||
ROM_REGION( 0x00573, "pals", 0 ) /* Lattice GAL16V8A-25LP GAL's */
|
||||
ROM_REGION( 0x00573, "pals", 0 ) // Lattice GAL16V8A-25LP GALs
|
||||
ROM_LOAD( "136075-1000.11c.bin", 0x0000, 0x0117, CRC(fb86e94a) SHA1(b16f037c49766ab734e47c8e1b16b5178809b8a3) )
|
||||
ROM_LOAD( "136075-1001.18l.bin", 0x0000, 0x0117, CRC(cd21acfe) SHA1(14bd9e2f1b50a1da550933e3fdc16e3f09b65e92) )
|
||||
ROM_LOAD( "136075-1002.8w.bin", 0x0000, 0x0117, CRC(4a7b6c44) SHA1(9579e098af3e5cd19bd14c361d3b1c5cb9047171) )
|
||||
@ -567,6 +756,8 @@ ROM_START( klaxd2 )
|
||||
ROM_LOAD( "136075-1004.6w.bin", 0x0000, 0x0117, CRC(6cd3270d) SHA1(84854b5beee539a80fc94f6e4637aa1c2543a1cb) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
|
@ -1,95 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/*************************************************************************
|
||||
|
||||
Atari Klax hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_KLAX_H
|
||||
#define MAME_ATARI_KLAX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/timer.h"
|
||||
#include "sound/msm5205.h"
|
||||
#include "atarimo.h"
|
||||
#include "screen.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class klax_state : public driver_device
|
||||
{
|
||||
public:
|
||||
klax_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_playfield_tilemap(*this, "playfield")
|
||||
, m_mob(*this, "mob")
|
||||
, m_p1(*this, "P1")
|
||||
{ }
|
||||
|
||||
void klax_base(machine_config &config);
|
||||
void klax(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_reset() override;
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline_update);
|
||||
|
||||
void interrupt_ack_w(u16 data = 0);
|
||||
|
||||
void latch_w(u16 data);
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void klax_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
|
||||
required_ioport m_p1;
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
};
|
||||
|
||||
class klax_bootleg_state : public klax_state
|
||||
{
|
||||
public:
|
||||
klax_bootleg_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: klax_state(mconfig, type, tag)
|
||||
, m_audiocpu(*this, "audiocpu")
|
||||
, m_msm(*this, "msm%u", 1)
|
||||
, m_rombank(*this, "rombank")
|
||||
, m_audio_ram(*this, "audioram")
|
||||
{ }
|
||||
|
||||
void klax5bl(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
void m5205_int1(int state);
|
||||
|
||||
void bootleg_sound_map(address_map &map);
|
||||
void klax5bl_map(address_map &map);
|
||||
|
||||
uint16_t audio_ram_r(offs_t offset);
|
||||
void audio_ram_w(offs_t offset, uint16_t data);
|
||||
void audio_sample_w(offs_t offset, uint8_t data);
|
||||
void audio_ctrl_w(uint8_t data);
|
||||
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device_array<msm5205_device, 2> m_msm;
|
||||
required_memory_bank m_rombank;
|
||||
required_shared_ptr<uint8_t> m_audio_ram;
|
||||
uint8_t m_audio_sample[2]{};
|
||||
bool m_audio_nibble = false;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_KLAX_H
|
@ -1,115 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/***************************************************************************
|
||||
|
||||
Atari Klax hardware
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "atarimo.h"
|
||||
#include "klax.h"
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(klax_state::get_playfield_tile_info)
|
||||
{
|
||||
const u16 data1 = m_playfield_tilemap->basemem_read(tile_index);
|
||||
const u16 data2 = m_playfield_tilemap->extmem_read(tile_index) >> 8;
|
||||
const u32 code = data1 & 0x1fff;
|
||||
const u32 color = data2 & 0x0f;
|
||||
tileinfo.set(0, code, color, (data1 >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config klax_state::s_mob_config =
|
||||
{
|
||||
1, /* index to which gfx system */
|
||||
1, /* number of motion object banks */
|
||||
1, /* are the entries linked? */
|
||||
0, /* are the entries split? */
|
||||
0, /* render in reverse order? */
|
||||
0, /* render in swapped X/Y order? */
|
||||
0, /* does the neighbor bit affect the next object? */
|
||||
8, /* pixels per SLIP entry (0 for no-slip) */
|
||||
0, /* pixel offset for SLIPs */
|
||||
0, /* maximum number of links to visit/scanline (0=all) */
|
||||
|
||||
0x000, /* base palette entry */
|
||||
0x100, /* maximum number of colors */
|
||||
0, /* transparent pen index */
|
||||
|
||||
{{ 0x00ff,0,0,0 }}, /* mask for the link */
|
||||
{{ 0,0x0fff,0,0 }}, /* mask for the code index */
|
||||
{{ 0,0,0x000f,0 }}, /* mask for the color */
|
||||
{{ 0,0,0xff80,0 }}, /* mask for the X position */
|
||||
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
|
||||
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
|
||||
{{ 0,0,0,0x0007 }}, /* mask for the height, in tiles */
|
||||
{{ 0,0,0,0x0008 }}, /* mask for the horizontal flip */
|
||||
{{ 0 }}, /* mask for the vertical flip */
|
||||
{{ 0 }}, /* mask for the priority */
|
||||
{{ 0 }}, /* mask for the neighbor */
|
||||
{{ 0 }}, /* mask for absolute coordinates */
|
||||
|
||||
{{ 0 }}, /* mask for the special value */
|
||||
0 /* resulting value to indicate "special" */
|
||||
};
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Latch write handler
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void klax_state::latch_w(u16 data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
u32 klax_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
/* draw the playfield */
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
u16 const *const mo = &mobitmap.pix(y);
|
||||
u16 *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* verified from schematics:
|
||||
|
||||
PFPRI if (PFS7-4 == 0 || LBPIX3-0 == 0)
|
||||
*/
|
||||
if ((pf[x] & 0xf0) != 0xf0)
|
||||
pf[x] = mo[x];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Liberator hardware
|
||||
@ -137,12 +138,411 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "liberatr.h"
|
||||
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/74259.h"
|
||||
#include "machine/er2055.h"
|
||||
#include "machine/rescap.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/pokey.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define MASTER_CLOCK 20000000 /* 20Mhz Main Clock Xtal */
|
||||
|
||||
namespace {
|
||||
|
||||
class liberatr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
liberatr_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_earom(*this, "earom")
|
||||
, m_outlatch(*this, "outlatch")
|
||||
, m_screen(*this, "screen")
|
||||
, m_base_ram(*this, "base_ram")
|
||||
, m_planet_frame(*this, "planet_frame")
|
||||
, m_xcoord(*this, "xcoord")
|
||||
, m_ycoord(*this, "ycoord")
|
||||
, m_bitmapram(*this, "bitmapram")
|
||||
, m_colorram(*this, "colorram")
|
||||
, m_videoram(*this, "videoram", 0x10000, ENDIANNESS_LITTLE)
|
||||
, m_fake(*this, "FAKE")
|
||||
, m_in0(*this, "IN0")
|
||||
, m_earom_data(0)
|
||||
, m_earom_control(0)
|
||||
{ }
|
||||
|
||||
void liberat2(machine_config &config);
|
||||
void liberatr(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
// vector and early raster EAROM interface
|
||||
required_device<er2055_device> m_earom;
|
||||
required_device<ls259_device> m_outlatch;
|
||||
required_device<screen_device> m_screen;
|
||||
|
||||
required_shared_ptr<uint8_t> m_base_ram;
|
||||
required_shared_ptr<uint8_t> m_planet_frame;
|
||||
required_shared_ptr<uint8_t> m_xcoord;
|
||||
required_shared_ptr<uint8_t> m_ycoord;
|
||||
required_shared_ptr<uint8_t> m_bitmapram;
|
||||
required_shared_ptr<uint8_t> m_colorram;
|
||||
|
||||
memory_share_creator<uint8_t> m_videoram;
|
||||
|
||||
required_ioport m_fake;
|
||||
required_ioport m_in0;
|
||||
|
||||
uint8_t m_earom_data = 0U;
|
||||
uint8_t m_earom_control = 0U;
|
||||
|
||||
uint8_t m_trackball_offset = 0U;
|
||||
uint8_t m_ctrld = 0U;
|
||||
|
||||
bool m_planet_select = false;
|
||||
|
||||
// The following structure describes the (up to 32) line segments
|
||||
// that make up one horizontal line (latitude) for one display frame of the planet.
|
||||
// Note: this and the following structure are only used to collect the
|
||||
// data before it is packed for actual use.
|
||||
struct planet_frame_line
|
||||
{
|
||||
uint8_t segment_count; // the number of segments on this line
|
||||
uint8_t max_x; // the maximum value of x_array for this line
|
||||
uint8_t color_array[32]; // the color values
|
||||
uint8_t x_array[32]; // and maximum x values for each segment
|
||||
};
|
||||
|
||||
// The following structure describes the lines (latitudes)
|
||||
// that make up one complete display frame of the planet.
|
||||
// Note: this and the previous structure are only used to collect the
|
||||
// data before it is packed for actual use.
|
||||
struct planet_frame
|
||||
{
|
||||
planet_frame_line lines[0x80];
|
||||
};
|
||||
|
||||
// The following structure collects the 256 frames of the
|
||||
// planet (one per value of longitude).
|
||||
// The data is packed segment_count,segment_start,color,length,color,length,... then
|
||||
// segment_count,segment_start,color,length,color,length... for the next line, etc
|
||||
// for the 128 lines.
|
||||
struct planet
|
||||
{
|
||||
std::unique_ptr<uint8_t []> frames[256];
|
||||
};
|
||||
|
||||
// The following array collects the 2 different planet
|
||||
// descriptions, which are selected by planetbit
|
||||
planet m_planets[2]{};
|
||||
|
||||
static constexpr uint8_t NUM_PENS = 0x18;
|
||||
|
||||
void output_latch_w(offs_t offset, uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(coin_counter_left_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(coin_counter_right_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(trackball_reset_w);
|
||||
uint8_t port0_r();
|
||||
|
||||
void bitmap_w(offs_t offset, uint8_t data);
|
||||
uint8_t bitmap_xy_r();
|
||||
void bitmap_xy_w(uint8_t data);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
// early raster EAROM interface
|
||||
uint8_t earom_r();
|
||||
void earom_w(offs_t offset, uint8_t data);
|
||||
void earom_control_w(uint8_t data);
|
||||
|
||||
void liberat2_map(address_map &map);
|
||||
void liberatr_map(address_map &map);
|
||||
|
||||
void init_planet(planet &liberatr_planet, uint8_t *planet_rom);
|
||||
void get_pens(pen_t *pens);
|
||||
void draw_planet(bitmap_rgb32 &bitmap, pen_t *pens);
|
||||
void draw_bitmap(bitmap_rgb32 &bitmap, pen_t *pens);
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Liberator's screen is 256 pixels by 256 pixels. The
|
||||
round planet in the middle of the screen is 128 pixels
|
||||
tall by 96 equivalent (192 at double pixel rate). The
|
||||
emulator needs to account for the aspect ratio of 4/3
|
||||
from the arcade video system in order to make the planet
|
||||
appear round.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void liberatr_state::bitmap_xy_w(uint8_t data)
|
||||
{
|
||||
m_videoram[(*m_ycoord << 8) | *m_xcoord] = data & 0xe0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t liberatr_state::bitmap_xy_r()
|
||||
{
|
||||
return m_videoram[(*m_ycoord << 8) | *m_xcoord];
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::bitmap_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_bitmapram[offset] = data;
|
||||
|
||||
offset += 3;
|
||||
uint8_t const x = (offset & 0x3f) << 2;
|
||||
uint8_t const y = offset >> 6;
|
||||
|
||||
data = data & 0xe0;
|
||||
|
||||
m_videoram[(y << 8) | x | 0] = data;
|
||||
m_videoram[(y << 8) | x | 1] = data;
|
||||
m_videoram[(y << 8) | x | 2] = data;
|
||||
m_videoram[(y << 8) | x | 3] = data;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************
|
||||
init_planet()
|
||||
|
||||
The data for the planet is stored in ROM using a run-length type of encoding. This
|
||||
function does the conversion to the above structures and then a smaller
|
||||
structure which is quicker to use in real time.
|
||||
|
||||
It's a multi-step process, reflecting the history of the code. Not quite as efficient
|
||||
as it might be, but this is not realtime stuff, so who cares...
|
||||
********************************************************************************************/
|
||||
|
||||
void liberatr_state::init_planet(planet &liberatr_planet, uint8_t *planet_rom)
|
||||
{
|
||||
const uint8_t *const latitude_scale = memregion("latitude_scaler")->base();
|
||||
const uint8_t *const longitude_scale = memregion("longitude_scaler")->base();
|
||||
|
||||
// for each starting longitude
|
||||
for (uint16_t longitude = 0; longitude < 0x100; longitude++)
|
||||
{
|
||||
planet_frame frame;
|
||||
uint16_t total_segment_count = 0;
|
||||
|
||||
// for each latitude
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
uint8_t x_array[32], color_array[32], visible_array[32];
|
||||
|
||||
// point to the structure which will hold the data for this line
|
||||
planet_frame_line *line = &frame.lines[latitude];
|
||||
|
||||
uint8_t latitude_scale_factor = latitude_scale[latitude];
|
||||
|
||||
// for this latitude, load the 32 segments into the arrays
|
||||
for (uint8_t segment = 0; segment < 0x20; segment++)
|
||||
{
|
||||
// read the planet picture ROM and get the latitude and longitude scaled from the scaling PROMS
|
||||
uint16_t address = (latitude << 5) + segment;
|
||||
uint16_t const planet_data = (planet_rom[address] << 8) | planet_rom[address + 0x1000];
|
||||
|
||||
uint8_t const color = (planet_data >> 8) & 0x0f;
|
||||
uint16_t const length = ((planet_data << 1) & 0x1fe) + ((planet_data >> 15) & 0x01);
|
||||
|
||||
|
||||
// scale the longitude limit (adding the starting longitude)
|
||||
address = longitude + (length >> 1) + (length & 1); // shift with rounding
|
||||
visible_array[segment] = BIT(address, 8);
|
||||
uint8_t longitude_scale_factor;
|
||||
if (address & 0x80)
|
||||
{
|
||||
longitude_scale_factor = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
address = ((address & 0x7f) << 1) + (((length & 1) || visible_array[segment]) ? 0 : 1);
|
||||
longitude_scale_factor = longitude_scale[address];
|
||||
}
|
||||
|
||||
x_array[segment] = (((uint16_t)latitude_scale_factor * (uint16_t)longitude_scale_factor) + 0x80) >> 8; // round it
|
||||
color_array[segment] = color;
|
||||
}
|
||||
|
||||
// determine which segment is the western horizon and leave 'start_segment' indexing it.
|
||||
uint8_t start_segment;
|
||||
for (start_segment = 0; start_segment < 0x1f; start_segment++) // if not found, 'start_segment' = 0x1f
|
||||
if (visible_array[start_segment]) break;
|
||||
|
||||
// transfer from the temporary arrays to the structure
|
||||
line->max_x = (latitude_scale_factor * 0xc0) >> 8;
|
||||
if (line->max_x & 1)
|
||||
line->max_x += 1; // make it even
|
||||
|
||||
/*
|
||||
as part of the quest to reduce memory usage (and to a lesser degree
|
||||
execution time), stitch together segments that have the same color
|
||||
*/
|
||||
uint8_t segment = start_segment;
|
||||
uint8_t segment_count = 0;
|
||||
uint8_t i = 0;
|
||||
uint8_t x = 0;
|
||||
|
||||
do
|
||||
{
|
||||
uint8_t color = color_array[segment];
|
||||
while (color == color_array[segment])
|
||||
{
|
||||
x = x_array[segment];
|
||||
segment = (segment + 1) & 0x1f;
|
||||
if (segment == start_segment)
|
||||
break;
|
||||
}
|
||||
|
||||
line->color_array[i] = color;
|
||||
line->x_array[i] = (x > line->max_x) ? line->max_x : x;
|
||||
i++;
|
||||
segment_count++;
|
||||
} while ((i < 32) && (x <= line->max_x));
|
||||
|
||||
total_segment_count += segment_count;
|
||||
line->segment_count = segment_count;
|
||||
}
|
||||
|
||||
/* now that the all the lines have been processed, and we know how
|
||||
many segments it will take to store the description, allocate the
|
||||
space for it and copy the data to it.
|
||||
*/
|
||||
liberatr_planet.frames[longitude] = std::make_unique<uint8_t []>(2 * (128 + total_segment_count));
|
||||
uint8_t *buffer = liberatr_planet.frames[longitude].get();
|
||||
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
planet_frame_line *line = &frame.lines[latitude];
|
||||
uint8_t const segment_count = line->segment_count;
|
||||
*buffer++ = segment_count;
|
||||
|
||||
/* calculate the bitmap's x coordinate for the western horizon
|
||||
center of bitmap - (the number of planet pixels) / 4 */
|
||||
*buffer++ = (m_screen->width() / 2) - ((line->max_x + 2) / 4);
|
||||
|
||||
for (uint8_t i = 0, last_x = 0; i < segment_count; i++)
|
||||
{
|
||||
uint8_t const current_x = (line->x_array[i] + 1) / 2;
|
||||
|
||||
*buffer++ = line->color_array[i];
|
||||
*buffer++ = current_x - last_x;
|
||||
|
||||
last_x = current_x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Start the video hardware emulation.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void liberatr_state::video_start()
|
||||
{
|
||||
// for each planet in the planet ROMs
|
||||
init_planet(m_planets[0], &memregion("planet")->base()[0x2000]);
|
||||
init_planet(m_planets[1], &memregion("planet")->base()[0x0000]);
|
||||
|
||||
save_item(NAME(m_planet_select));
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::get_pens(pen_t *pens)
|
||||
{
|
||||
for (offs_t i = 0; i < NUM_PENS; i++)
|
||||
{
|
||||
/* handle the hardware flip of the bit order from 765 to 576 that
|
||||
hardware does between VRAM and color RAM */
|
||||
static const offs_t penmap[] = { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
|
||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
|
||||
0x10, 0x12, 0x14, 0x16, 0x11, 0x13, 0x15, 0x17 };
|
||||
|
||||
uint8_t const data = m_colorram[i];
|
||||
|
||||
// scale it from 0x00-0xff
|
||||
uint8_t r = ((~data >> 3) & 0x07) * 0x24 + 3; if (r == 3) r = 0;
|
||||
uint8_t g = ((~data >> 0) & 0x07) * 0x24 + 3; if (g == 3) g = 0;
|
||||
uint8_t b = ((~data >> 5) & 0x06) * 0x24 + 3; if (b == 3) b = 0;
|
||||
|
||||
pens[penmap[i]] = rgb_t(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::draw_planet(bitmap_rgb32 &bitmap, pen_t *pens)
|
||||
{
|
||||
uint8_t const *buffer = m_planets[m_planet_select].frames[*m_planet_frame].get();
|
||||
|
||||
// for each latitude
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
// grab the color value for the base (if any) at this latitude
|
||||
uint8_t const base_color = m_base_ram[latitude >> 3] ^ 0x0f;
|
||||
|
||||
uint8_t const segment_count = *buffer++;
|
||||
uint8_t x = *buffer++;
|
||||
uint8_t const y = 64 + latitude;
|
||||
|
||||
// run through the segments, drawing its color until its x_array value comes up.
|
||||
for (uint8_t segment = 0; segment < segment_count; segment++)
|
||||
{
|
||||
uint8_t color = *buffer++;
|
||||
uint8_t const segment_length = *buffer++;
|
||||
|
||||
if ((color & 0x0c) == 0x0c)
|
||||
color = base_color;
|
||||
|
||||
for (uint8_t i = 0; i < segment_length; i++, x++)
|
||||
bitmap.pix(y, x) = pens[color];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::draw_bitmap(bitmap_rgb32 &bitmap, pen_t *pens)
|
||||
{
|
||||
for (offs_t offs = 0; offs < 0x10000; offs++)
|
||||
{
|
||||
uint8_t const data = m_videoram[offs];
|
||||
|
||||
uint8_t const y = offs >> 8;
|
||||
uint8_t const x = offs & 0xff;
|
||||
|
||||
if (data)
|
||||
bitmap.pix(y, x) = pens[(data >> 5) | 0x10];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t liberatr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
pen_t pens[NUM_PENS];
|
||||
get_pens(pens);
|
||||
|
||||
bitmap.fill(rgb_t::black(), cliprect);
|
||||
draw_planet(bitmap, pens);
|
||||
draw_bitmap(bitmap, pens);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
void liberatr_state::machine_start()
|
||||
{
|
||||
@ -151,7 +551,6 @@ void liberatr_state::machine_start()
|
||||
|
||||
save_item(NAME(m_trackball_offset));
|
||||
save_item(NAME(m_ctrld));
|
||||
save_item(NAME(m_videoram));
|
||||
}
|
||||
|
||||
|
||||
@ -197,12 +596,12 @@ WRITE_LINE_MEMBER(liberatr_state::coin_counter_right_w)
|
||||
|
||||
WRITE_LINE_MEMBER(liberatr_state::trackball_reset_w)
|
||||
{
|
||||
/* on the rising edge of /ctrld, the /ld signal on the LS191 is released and the value of the switches */
|
||||
/* input becomes the starting point for the trackball counters */
|
||||
/* on the rising edge of /ctrld, the /ld signal on the LS191 is released and the value of the switches
|
||||
input becomes the starting point for the trackball counters */
|
||||
if (!m_ctrld && state)
|
||||
{
|
||||
uint8_t trackball = ioport("FAKE")->read();
|
||||
uint8_t switches = ioport("IN0")->read();
|
||||
uint8_t const trackball = m_fake->read();
|
||||
uint8_t const switches = m_in0->read();
|
||||
m_trackball_offset = ((trackball & 0xf0) - (switches & 0xf0)) | ((trackball - switches) & 0x0f);
|
||||
}
|
||||
m_ctrld = state;
|
||||
@ -211,16 +610,16 @@ WRITE_LINE_MEMBER(liberatr_state::trackball_reset_w)
|
||||
|
||||
uint8_t liberatr_state::port0_r()
|
||||
{
|
||||
/* if ctrld is high, the /ld signal on the LS191 is NOT set, meaning that the trackball is counting */
|
||||
// if ctrld is high, the /ld signal on the LS191 is NOT set, meaning that the trackball is counting
|
||||
if (m_ctrld)
|
||||
{
|
||||
uint8_t trackball = ioport("FAKE")->read();
|
||||
uint8_t const trackball = m_fake->read();
|
||||
return ((trackball & 0xf0) - (m_trackball_offset & 0xf0)) | ((trackball - m_trackball_offset) & 0x0f);
|
||||
}
|
||||
|
||||
/* otherwise, the LS191 is simply passing through the raw switch inputs */
|
||||
// otherwise, the LS191 is simply passing through the raw switch inputs
|
||||
else
|
||||
return ioport("IN0")->read();
|
||||
return m_in0->read();
|
||||
}
|
||||
|
||||
|
||||
@ -276,18 +675,18 @@ void liberatr_state::earom_control_w(uint8_t data)
|
||||
|
||||
void liberatr_state::liberatr_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0000).ram().share("xcoord");
|
||||
map(0x0001, 0x0001).ram().share("ycoord");
|
||||
map(0x0000, 0x0000).ram().share(m_xcoord);
|
||||
map(0x0001, 0x0001).ram().share(m_ycoord);
|
||||
map(0x0002, 0x0002).rw(FUNC(liberatr_state::bitmap_xy_r), FUNC(liberatr_state::bitmap_xy_w));
|
||||
map(0x0003, 0x3fff).ram().w(FUNC(liberatr_state::bitmap_w)).share("bitmapram");
|
||||
map(0x0003, 0x3fff).ram().w(FUNC(liberatr_state::bitmap_w)).share(m_bitmapram);
|
||||
map(0x4000, 0x403f).r(FUNC(liberatr_state::earom_r));
|
||||
map(0x5000, 0x5000).r(FUNC(liberatr_state::port0_r));
|
||||
map(0x5001, 0x5001).portr("IN1");
|
||||
map(0x6000, 0x600f).nopr().writeonly().share("base_ram");
|
||||
map(0x6200, 0x621f).nopr().writeonly().share("colorram");
|
||||
map(0x6000, 0x600f).nopr().writeonly().share(m_base_ram);
|
||||
map(0x6200, 0x621f).nopr().writeonly().share(m_colorram);
|
||||
map(0x6400, 0x6400).nopw();
|
||||
map(0x6600, 0x6600).w(FUNC(liberatr_state::earom_control_w));
|
||||
map(0x6800, 0x6800).writeonly().share("planet_frame");
|
||||
map(0x6800, 0x6800).writeonly().share(m_planet_frame);
|
||||
map(0x6a00, 0x6a00).w("watchdog", FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x6c00, 0x6c07).w(FUNC(liberatr_state::output_latch_w));
|
||||
map(0x6e00, 0x6e3f).nopr().w(FUNC(liberatr_state::earom_w));
|
||||
@ -307,19 +706,19 @@ void liberatr_state::liberatr_map(address_map &map)
|
||||
|
||||
void liberatr_state::liberat2_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0000).ram().share("xcoord");
|
||||
map(0x0001, 0x0001).ram().share("ycoord");
|
||||
map(0x0000, 0x0000).ram().share(m_xcoord);
|
||||
map(0x0001, 0x0001).ram().share(m_ycoord);
|
||||
map(0x0002, 0x0002).rw(FUNC(liberatr_state::bitmap_xy_r), FUNC(liberatr_state::bitmap_xy_w));
|
||||
map(0x0003, 0x3fff).ram().w(FUNC(liberatr_state::bitmap_w)).share("bitmapram");
|
||||
map(0x0003, 0x3fff).ram().w(FUNC(liberatr_state::bitmap_w)).share(m_bitmapram);
|
||||
map(0x4000, 0x4000).r(FUNC(liberatr_state::port0_r));
|
||||
map(0x4001, 0x4001).portr("IN1");
|
||||
map(0x4002, 0x400f).nopr();
|
||||
map(0x4000, 0x400f).writeonly().share("base_ram");
|
||||
map(0x4200, 0x421f).nopr().writeonly().share("colorram");
|
||||
map(0x4000, 0x400f).writeonly().share(m_base_ram);
|
||||
map(0x4200, 0x421f).nopr().writeonly().share(m_colorram);
|
||||
map(0x4400, 0x4400).nopw();
|
||||
map(0x4600, 0x4600).w(FUNC(liberatr_state::earom_control_w));
|
||||
map(0x4800, 0x483f).r(FUNC(liberatr_state::earom_r));
|
||||
map(0x4800, 0x4800).writeonly().share("planet_frame");
|
||||
map(0x4800, 0x4800).writeonly().share(m_planet_frame);
|
||||
map(0x4a00, 0x4a00).w("watchdog", FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x4c00, 0x4c07).w(FUNC(liberatr_state::output_latch_w));
|
||||
map(0x4e00, 0x4e3f).nopr().w(FUNC(liberatr_state::earom_w));
|
||||
@ -339,7 +738,7 @@ void liberatr_state::liberat2_map(address_map &map)
|
||||
*************************************/
|
||||
|
||||
static INPUT_PORTS_START( liberatr )
|
||||
PORT_START("IN0") /* IN0 - $5000 */
|
||||
PORT_START("IN0") // IN0 - $5000
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN3 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
@ -351,7 +750,7 @@ static INPUT_PORTS_START( liberatr )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
|
||||
PORT_SERVICE( 0x80, IP_ACTIVE_LOW )
|
||||
|
||||
PORT_START("IN1") /* IN1 - $5001 */
|
||||
PORT_START("IN1") // IN1 - $5001
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
@ -361,7 +760,7 @@ static INPUT_PORTS_START( liberatr )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH,IPT_CUSTOM ) PORT_VBLANK("screen")
|
||||
|
||||
PORT_START("DSW1") /* IN2 - Game Option switches DSW @ D4 on PCB */
|
||||
PORT_START("DSW1") // IN2 - Game Option switches DSW @ D4 on PCB
|
||||
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
|
||||
PORT_DIPSETTING( 0x00, "4" )
|
||||
PORT_DIPSETTING( 0x01, "5" )
|
||||
@ -384,7 +783,7 @@ static INPUT_PORTS_START( liberatr )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START("DSW2") /* IN3 - Pricing Option switches DSW @ A4 on PCB */
|
||||
PORT_START("DSW2") // IN3 - Pricing Option switches DSW @ A4 on PCB
|
||||
PORT_DIPNAME( 0x03, 0x02, DEF_STR( Coinage ) )
|
||||
PORT_DIPSETTING( 0x03, DEF_STR( 2C_1C ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( 1C_1C ) )
|
||||
@ -398,7 +797,7 @@ static INPUT_PORTS_START( liberatr )
|
||||
PORT_DIPNAME( 0x10, 0x00, "Left Coin" )
|
||||
PORT_DIPSETTING ( 0x00, "*1" )
|
||||
PORT_DIPSETTING ( 0x10, "*2" )
|
||||
/* TODO: verify the following settings */
|
||||
// TODO: verify the following settings
|
||||
PORT_DIPNAME( 0xe0, 0x00, "Bonus Coins" )
|
||||
PORT_DIPSETTING ( 0x00, DEF_STR( None ) )
|
||||
PORT_DIPSETTING ( 0x80, "1 each 5" )
|
||||
@ -409,7 +808,7 @@ static INPUT_PORTS_START( liberatr )
|
||||
PORT_DIPSETTING ( 0xc0, "Freeze Mode" )
|
||||
PORT_DIPSETTING ( 0xe0, "Freeze Mode" )
|
||||
|
||||
PORT_START("FAKE") /* IN4 - FAKE - overlaps IN0 in the HW */
|
||||
PORT_START("FAKE") // IN4 - FAKE - overlaps IN0 in the HW
|
||||
PORT_BIT( 0x0f, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10)
|
||||
PORT_BIT( 0xf0, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10)
|
||||
INPUT_PORTS_END
|
||||
@ -423,8 +822,10 @@ INPUT_PORTS_END
|
||||
|
||||
void liberatr_state::liberatr(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
m6502_device &maincpu(M6502(config, "maincpu", MASTER_CLOCK/16)); /* 1.25Mhz divided from 20Mhz master clock */
|
||||
constexpr XTAL MASTER_CLOCK = 20_MHz_XTAL;
|
||||
|
||||
// basic machine hardware
|
||||
m6502_device &maincpu(M6502(config, "maincpu", MASTER_CLOCK / 16)); // 1.25Mhz divided from 20Mhz master clock
|
||||
maincpu.set_addrmap(AS_PROGRAM, &liberatr_state::liberatr_map);
|
||||
maincpu.set_periodic_int(FUNC(liberatr_state::irq0_line_hold), attotime::from_hz(4*60));
|
||||
|
||||
@ -442,23 +843,23 @@ void liberatr_state::liberatr(machine_config &config)
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
/* 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_screen_update(FUNC(liberatr_state::screen_update));
|
||||
m_screen->set_size(256,256);
|
||||
m_screen->set_size(256, 256);
|
||||
m_screen->set_visarea(8, 247, 13, 244);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
pokey_device &pokey1(POKEY(config, "pokey1", MASTER_CLOCK/16)); /* 1.25Mhz from Phi2 signal from 6502 */
|
||||
pokey_device &pokey1(POKEY(config, "pokey1", MASTER_CLOCK / 16)); // 1.25Mhz from Phi2 signal from 6502
|
||||
pokey1.allpot_r().set_ioport("DSW2");
|
||||
pokey1.set_output_opamp_low_pass(RES_K(4.7), CAP_U(0.01), 5.0);
|
||||
pokey1.add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
pokey_device &pokey2(POKEY(config, "pokey2", MASTER_CLOCK/16)); /* 1.25Mhz from Phi2 signal from 6502 */
|
||||
pokey_device &pokey2(POKEY(config, "pokey2", MASTER_CLOCK / 16)); // 1.25Mhz from Phi2 signal from 6502
|
||||
pokey2.set_output_opamp_low_pass(RES_K(4.7), CAP_U(0.01), 5.0);
|
||||
pokey2.allpot_r().set_ioport("DSW1");
|
||||
pokey2.add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
@ -468,7 +869,7 @@ void liberatr_state::liberat2(machine_config &config)
|
||||
{
|
||||
liberatr(config);
|
||||
|
||||
/* basic machine hardware */
|
||||
// basic machine hardware
|
||||
subdevice<m6502_device>("maincpu")->set_addrmap(AS_PROGRAM, &liberatr_state::liberat2_map);
|
||||
}
|
||||
|
||||
@ -481,7 +882,7 @@ void liberatr_state::liberat2(machine_config &config)
|
||||
*************************************/
|
||||
|
||||
ROM_START( liberatr )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* 64k for code and data */
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD( "136012.206", 0x8000, 0x1000, CRC(1a0cb4a0) SHA1(595828a07af729a84aab4e0b51e873046b56b419) )
|
||||
ROM_LOAD( "136012.205", 0x9000, 0x1000, CRC(2f071920) SHA1(8764f3e78451c4968bffb7c7f72d1ed862f4b185) )
|
||||
ROM_LOAD( "136012.204", 0xa000, 0x1000, CRC(bcc91827) SHA1(3bfbe1f1db58437ccd204a857e58695f56819649) )
|
||||
@ -489,57 +890,58 @@ ROM_START( liberatr )
|
||||
ROM_LOAD( "136012.202", 0xc000, 0x1000, CRC(569ba7ea) SHA1(4812b255886204192ab999d1370550d48438ea81) )
|
||||
ROM_LOAD( "136012.201", 0xd000, 0x1000, CRC(d12cd6d0) SHA1(94474429cbcdbb406eb045152fb158e2a23cd26d) )
|
||||
ROM_LOAD( "136012.200", 0xe000, 0x1000, CRC(1e98d21a) SHA1(92c7cc033c78ae0ce8127d49debe62263404feb1) )
|
||||
ROM_RELOAD( 0xf000, 0x1000 ) /* for interrupt/reset vectors */
|
||||
ROM_RELOAD( 0xf000, 0x1000 ) // for interrupt/reset vectors
|
||||
|
||||
ROM_REGION( 0x4000, "gfx1", 0 ) /* planet image, used at runtime */
|
||||
ROM_REGION( 0x4000, "planet", 0 ) // used at runtime
|
||||
ROM_LOAD( "136012.110", 0x0000, 0x1000, CRC(6eb11221) SHA1(355b71812a18cbb2ee4dc20b3622fca1c96e4570) )
|
||||
ROM_LOAD( "136012.107", 0x1000, 0x1000, CRC(8a616a63) SHA1(76794cc4e11048bb6f2628bd8b84c9a7e2e82551) )
|
||||
ROM_LOAD( "136012.108", 0x2000, 0x1000, CRC(3f8e4cf6) SHA1(a9d0feb0892f343687e00b96f05adb423ee4d659) )
|
||||
ROM_LOAD( "136012.109", 0x3000, 0x1000, CRC(dda0c0ef) SHA1(6e547c07c1abd17383a4389b0b4ced442ed65ce7) )
|
||||
|
||||
ROM_REGION( 0x100, "user1", 0 ) /* latitude scaler */
|
||||
ROM_REGION( 0x100, "latitude_scaler", 0 ) /* latitude scaler */
|
||||
ROM_LOAD_NIB_LOW ( "136012.123", 0x0000, 0x0100, CRC(b8c806e0) SHA1(19b1b9796e1e9a42899a92ec53288d17d5d15fb3) )
|
||||
ROM_LOAD_NIB_HIGH( "136012.124", 0x0000, 0x0100, CRC(e51ec78f) SHA1(224237370c418361a00d62a77d39fa494e7d8831) )
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 ) /* longitude scaler */
|
||||
ROM_REGION( 0x100, "longitude_scaler", 0 ) /* longitude scaler */
|
||||
ROM_LOAD_NIB_LOW ( "136012.125", 0x0000, 0x0100, CRC(52ac8dd9) SHA1(125d54b562d079b974f2562e71ab7c7a0b97e709) )
|
||||
ROM_LOAD_NIB_HIGH( "136012.126", 0x0000, 0x0100, CRC(2e670aa6) SHA1(a6bcc49d0948d2dfe497c5e3ad4a834fa78f779a) )
|
||||
|
||||
ROM_REGION( 0x200, "proms", 0 )
|
||||
ROM_LOAD( "136012.021", 0x0000, 0x0100, CRC(ffdcd7bc) SHA1(2ce733203d628e299ec4fb93db8be1598b49142c) ) /* write protect PROM */
|
||||
ROM_LOAD( "136012.022", 0x0100, 0x0100, CRC(3353edce) SHA1(915308b11096fc1d02acf9b4af806a2a935dd748) ) /* sync PROM */
|
||||
ROM_LOAD( "136012.021", 0x0000, 0x0100, CRC(ffdcd7bc) SHA1(2ce733203d628e299ec4fb93db8be1598b49142c) ) // write protect PROM
|
||||
ROM_LOAD( "136012.022", 0x0100, 0x0100, CRC(3353edce) SHA1(915308b11096fc1d02acf9b4af806a2a935dd748) ) // sync PROM
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( liberatr2 )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* 64k for code and data */
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD( "l6.bin", 0x6000, 0x1000, CRC(78093d06) SHA1(0f6ca01e27b32aae384a6ab67a6f14eedd3f1d9c) )
|
||||
ROM_LOAD( "l5.bin", 0x7000, 0x1000, CRC(988db636) SHA1(8fdd07b397d4bef108aafb10c06c2fd53fc1f99a) )
|
||||
ROM_LOAD( "l4.bin", 0x8000, 0x1000, CRC(ec114540) SHA1(eb35510b59f5e9624c3d94fb16dacb4968349030) )
|
||||
ROM_LOAD( "l3.bin", 0x9000, 0x1000, CRC(184c751f) SHA1(e020d2943be89f244c1aeeb34a28b7aa7dbc1454) )
|
||||
ROM_LOAD( "l2.bin", 0xa000, 0x1000, CRC(c3f61f88) SHA1(a56ce094fe7374d3ac341d5eb9e06df083e16b1f) )
|
||||
ROM_LOAD( "l1.bin", 0xb000, 0x1000, CRC(ef6e9f9e) SHA1(b1f7cc9e0a2ea08ec89428ad31161ac81e7faaaf) )
|
||||
ROM_RELOAD( 0xf000, 0x1000 ) /* for interrupt/reset vectors */
|
||||
ROM_RELOAD( 0xf000, 0x1000 ) // for interrupt/reset vectors
|
||||
|
||||
ROM_REGION( 0x4000, "gfx1", 0 ) /* planet image, used at runtime */
|
||||
ROM_REGION( 0x4000, "planet", 0 ) // used at runtime
|
||||
ROM_LOAD( "136012.110", 0x0000, 0x1000, CRC(6eb11221) SHA1(355b71812a18cbb2ee4dc20b3622fca1c96e4570) )
|
||||
ROM_LOAD( "136012.107", 0x1000, 0x1000, CRC(8a616a63) SHA1(76794cc4e11048bb6f2628bd8b84c9a7e2e82551) )
|
||||
ROM_LOAD( "136012.108", 0x2000, 0x1000, CRC(3f8e4cf6) SHA1(a9d0feb0892f343687e00b96f05adb423ee4d659) )
|
||||
ROM_LOAD( "136012.109", 0x3000, 0x1000, CRC(dda0c0ef) SHA1(6e547c07c1abd17383a4389b0b4ced442ed65ce7) )
|
||||
|
||||
ROM_REGION( 0x100, "user1", 0 ) /* latitude scaler */
|
||||
ROM_REGION( 0x100, "latitude_scaler", 0 )
|
||||
ROM_LOAD_NIB_LOW ( "136012.123", 0x0000, 0x0100, CRC(b8c806e0) SHA1(19b1b9796e1e9a42899a92ec53288d17d5d15fb3) )
|
||||
ROM_LOAD_NIB_HIGH( "136012.124", 0x0000, 0x0100, CRC(e51ec78f) SHA1(224237370c418361a00d62a77d39fa494e7d8831) )
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 ) /* longitude scaler */
|
||||
ROM_REGION( 0x100, "longitude_scaler", 0 )
|
||||
ROM_LOAD_NIB_LOW ( "136012.125", 0x0000, 0x0100, CRC(52ac8dd9) SHA1(125d54b562d079b974f2562e71ab7c7a0b97e709) )
|
||||
ROM_LOAD_NIB_HIGH( "136012.126", 0x0000, 0x0100, CRC(2e670aa6) SHA1(a6bcc49d0948d2dfe497c5e3ad4a834fa78f779a) )
|
||||
|
||||
ROM_REGION( 0x200, "proms", 0 )
|
||||
ROM_LOAD( "136012.021", 0x0000, 0x0100, CRC(ffdcd7bc) SHA1(2ce733203d628e299ec4fb93db8be1598b49142c) ) /* write protect PROM */
|
||||
ROM_LOAD( "136012.022", 0x0100, 0x0100, CRC(3353edce) SHA1(915308b11096fc1d02acf9b4af806a2a935dd748) ) /* sync PROM */
|
||||
ROM_LOAD( "136012.021", 0x0000, 0x0100, CRC(ffdcd7bc) SHA1(2ce733203d628e299ec4fb93db8be1598b49142c) ) // write protect PROM
|
||||
ROM_LOAD( "136012.022", 0x0100, 0x0100, CRC(3353edce) SHA1(915308b11096fc1d02acf9b4af806a2a935dd748) ) // sync PROM
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -548,5 +950,5 @@ ROM_END
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1982, liberatr, 0, liberatr, liberatr, liberatr_state, empty_init, ROT0, "Atari", "Liberator (set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, liberatr2,liberatr, liberat2, liberatr, liberatr_state, empty_init, ROT0, "Atari", "Liberator (set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, liberatr, 0, liberatr, liberatr, liberatr_state, empty_init, ROT0, "Atari", "Liberator (set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, liberatr2, liberatr, liberat2, liberatr, liberatr_state, empty_init, ROT0, "Atari", "Liberator (set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,129 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
/*************************************************************************
|
||||
|
||||
Atari Liberator hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_LIBERATR_H
|
||||
#define MAME_ATARI_LIBERATR_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/74259.h"
|
||||
#include "machine/er2055.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/pokey.h"
|
||||
#include "screen.h"
|
||||
|
||||
class liberatr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
liberatr_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_earom(*this, "earom")
|
||||
, m_earom_data(0)
|
||||
, m_earom_control(0)
|
||||
, m_outlatch(*this, "outlatch")
|
||||
, m_screen(*this, "screen")
|
||||
, m_base_ram(*this, "base_ram")
|
||||
, m_planet_frame(*this, "planet_frame")
|
||||
, m_xcoord(*this, "xcoord")
|
||||
, m_ycoord(*this, "ycoord")
|
||||
, m_bitmapram(*this, "bitmapram")
|
||||
, m_colorram(*this, "colorram")
|
||||
{ }
|
||||
|
||||
void liberat2(machine_config &config);
|
||||
void liberatr(machine_config &config);
|
||||
|
||||
private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
void output_latch_w(offs_t offset, uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(coin_counter_left_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(coin_counter_right_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(trackball_reset_w);
|
||||
uint8_t port0_r();
|
||||
|
||||
void bitmap_w(offs_t offset, uint8_t data);
|
||||
uint8_t bitmap_xy_r();
|
||||
void bitmap_xy_w(uint8_t data);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
// early raster EAROM interface
|
||||
uint8_t earom_r();
|
||||
void earom_w(offs_t offset, uint8_t data);
|
||||
void earom_control_w(uint8_t data);
|
||||
|
||||
void liberat2_map(address_map &map);
|
||||
void liberatr_map(address_map &map);
|
||||
|
||||
// The following structure describes the (up to 32) line segments
|
||||
// that make up one horizontal line (latitude) for one display frame of the planet.
|
||||
// Note: this and the following structure is only used to collect the
|
||||
// data before it is packed for actual use.
|
||||
struct planet_frame_line
|
||||
{
|
||||
uint8_t segment_count; // the number of segments on this line
|
||||
uint8_t max_x; // the maximum value of x_array for this line
|
||||
uint8_t color_array[32]; // the color values
|
||||
uint8_t x_array[32]; // and maximum x values for each segment
|
||||
};
|
||||
|
||||
// The following structure describes the lines (latitudes)
|
||||
// that make up one complete display frame of the planet.
|
||||
// Note: this and the previous structure is only used to collect the
|
||||
// data before it is packed for actual use.
|
||||
struct planet_frame
|
||||
{
|
||||
planet_frame_line lines[0x80];
|
||||
};
|
||||
|
||||
// The following structure collects the 256 frames of the
|
||||
// planet (one per value of longitude).
|
||||
// The data is packed segment_count,segment_start,color,length,color,length,... then
|
||||
// segment_count,segment_start,color,length,color,length... for the next line, etc
|
||||
// for the 128 lines.
|
||||
struct planet
|
||||
{
|
||||
std::unique_ptr<uint8_t []> frames[256];
|
||||
};
|
||||
|
||||
void init_planet(planet &liberatr_planet, uint8_t *planet_rom);
|
||||
void get_pens(pen_t *pens);
|
||||
void draw_planet(bitmap_rgb32 &bitmap, pen_t *pens);
|
||||
void draw_bitmap(bitmap_rgb32 &bitmap, pen_t *pens);
|
||||
|
||||
// vector and early raster EAROM interface
|
||||
required_device<er2055_device> m_earom;
|
||||
uint8_t m_earom_data;
|
||||
uint8_t m_earom_control;
|
||||
|
||||
required_device<ls259_device> m_outlatch;
|
||||
|
||||
required_device<screen_device> m_screen;
|
||||
required_shared_ptr<uint8_t> m_base_ram;
|
||||
required_shared_ptr<uint8_t> m_planet_frame;
|
||||
required_shared_ptr<uint8_t> m_xcoord;
|
||||
required_shared_ptr<uint8_t> m_ycoord;
|
||||
required_shared_ptr<uint8_t> m_bitmapram;
|
||||
required_shared_ptr<uint8_t> m_colorram;
|
||||
|
||||
uint8_t m_trackball_offset = 0U;
|
||||
uint8_t m_ctrld = 0U;
|
||||
uint8_t m_videoram[0x10000]{};
|
||||
|
||||
bool m_planet_select = false;
|
||||
|
||||
// The following array collects the 2 different planet
|
||||
// descriptions, which are selected by planetbit
|
||||
planet m_planets[2]{};
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_LIBERATR_H
|
@ -1,289 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
/***************************************************************************
|
||||
|
||||
video/liberatr.c
|
||||
|
||||
Functions to emulate the video hardware of the machine.
|
||||
|
||||
Liberator's screen is 256 pixels by 256 pixels. The
|
||||
round planet in the middle of the screen is 128 pixels
|
||||
tall by 96 equivalent (192 at double pixel rate). The
|
||||
emulator needs to account for the aspect ratio of 4/3
|
||||
from the arcade video system in order to make the planet
|
||||
appear round.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "liberatr.h"
|
||||
|
||||
|
||||
#define NUM_PENS (0x18)
|
||||
|
||||
|
||||
|
||||
|
||||
void liberatr_state::bitmap_xy_w(uint8_t data)
|
||||
{
|
||||
m_videoram[(*m_ycoord << 8) | *m_xcoord] = data & 0xe0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t liberatr_state::bitmap_xy_r()
|
||||
{
|
||||
return m_videoram[(*m_ycoord << 8) | *m_xcoord];
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::bitmap_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
uint8_t x, y;
|
||||
|
||||
m_bitmapram[offset] = data;
|
||||
|
||||
offset += 3;
|
||||
x = (offset & 0x3f) << 2;
|
||||
y = offset >> 6;
|
||||
|
||||
data = data & 0xe0;
|
||||
|
||||
m_videoram[(y << 8) | x | 0] = data;
|
||||
m_videoram[(y << 8) | x | 1] = data;
|
||||
m_videoram[(y << 8) | x | 2] = data;
|
||||
m_videoram[(y << 8) | x | 3] = data;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************
|
||||
liberatr_init_planet()
|
||||
|
||||
The data for the planet is stored in ROM using a run-length type of encoding. This
|
||||
function does the conversion to the above structures and then a smaller
|
||||
structure which is quicker to use in real time.
|
||||
|
||||
Its a multi-step process, reflecting the history of the code. Not quite as efficient
|
||||
as it might be, but this is not realtime stuff, so who cares...
|
||||
********************************************************************************************/
|
||||
|
||||
void liberatr_state::init_planet(planet &liberatr_planet, uint8_t *planet_rom)
|
||||
{
|
||||
const uint8_t *const latitude_scale = memregion("user1")->base();
|
||||
const uint8_t *const longitude_scale = memregion("user2")->base();
|
||||
|
||||
// for each starting longitude
|
||||
for (uint16_t longitude = 0; longitude < 0x100; longitude++)
|
||||
{
|
||||
planet_frame frame;
|
||||
uint16_t total_segment_count = 0;
|
||||
|
||||
// for each latitude
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
uint8_t x_array[32], color_array[32], visible_array[32];
|
||||
|
||||
// point to the structure which will hold the data for this line
|
||||
planet_frame_line *line = &frame.lines[latitude];
|
||||
|
||||
uint8_t latitude_scale_factor = latitude_scale[latitude];
|
||||
|
||||
// for this latitude, load the 32 segments into the arrays
|
||||
for (uint8_t segment = 0; segment < 0x20; segment++)
|
||||
{
|
||||
uint16_t address;
|
||||
|
||||
// read the planet picture ROM and get the latitude and longitude scaled from the scaling PROMS
|
||||
address = (latitude << 5) + segment;
|
||||
uint16_t planet_data = (planet_rom[address] << 8) | planet_rom[address + 0x1000];
|
||||
|
||||
uint8_t color = (planet_data >> 8) & 0x0f;
|
||||
uint16_t length = ((planet_data << 1) & 0x1fe) + ((planet_data >> 15) & 0x01);
|
||||
|
||||
|
||||
// scale the longitude limit (adding the starting longitude)
|
||||
address = longitude + (length >> 1) + (length & 1); // shift with rounding
|
||||
visible_array[segment] = BIT(address, 8);
|
||||
uint8_t longitude_scale_factor;
|
||||
if (address & 0x80)
|
||||
{
|
||||
longitude_scale_factor = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
address = ((address & 0x7f) << 1) + (((length & 1) || visible_array[segment]) ? 0 : 1);
|
||||
longitude_scale_factor = longitude_scale[address];
|
||||
}
|
||||
|
||||
x_array[segment] = (((uint16_t)latitude_scale_factor * (uint16_t)longitude_scale_factor) + 0x80) >> 8; /* round it */
|
||||
color_array[segment] = color;
|
||||
}
|
||||
|
||||
// determine which segment is the western horizon and leave 'start_segment' indexing it.
|
||||
uint8_t start_segment;
|
||||
for (start_segment = 0; start_segment < 0x1f; start_segment++) // if not found, 'start_segment' = 0x1f
|
||||
if (visible_array[start_segment]) break;
|
||||
|
||||
// transfer from the temporary arrays to the structure
|
||||
line->max_x = (latitude_scale_factor * 0xc0) >> 8;
|
||||
if (line->max_x & 1)
|
||||
line->max_x += 1; // make it even
|
||||
|
||||
/*
|
||||
as part of the quest to reduce memory usage (and to a lesser degree
|
||||
execution time), stitch together segments that have the same color
|
||||
*/
|
||||
uint8_t segment = start_segment;
|
||||
uint8_t segment_count = 0;
|
||||
uint8_t i = 0;
|
||||
uint8_t x = 0;
|
||||
|
||||
do
|
||||
{
|
||||
uint8_t color = color_array[segment];
|
||||
while (color == color_array[segment])
|
||||
{
|
||||
x = x_array[segment];
|
||||
segment = (segment+1) & 0x1f;
|
||||
if (segment == start_segment)
|
||||
break;
|
||||
}
|
||||
|
||||
line->color_array[i] = color;
|
||||
line->x_array[i] = (x > line->max_x) ? line->max_x : x;
|
||||
i++;
|
||||
segment_count++;
|
||||
} while ((i < 32) && (x <= line->max_x));
|
||||
|
||||
total_segment_count += segment_count;
|
||||
line->segment_count = segment_count;
|
||||
}
|
||||
|
||||
/* now that the all the lines have been processed, and we know how
|
||||
many segments it will take to store the description, allocate the
|
||||
space for it and copy the data to it.
|
||||
*/
|
||||
liberatr_planet.frames[longitude] = std::make_unique<uint8_t []>(2 * (128 + total_segment_count));
|
||||
uint8_t *buffer = liberatr_planet.frames[longitude].get();
|
||||
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
planet_frame_line *line = &frame.lines[latitude];
|
||||
uint8_t segment_count = line->segment_count;
|
||||
*buffer++ = segment_count;
|
||||
|
||||
/* calculate the bitmap's x coordinate for the western horizon
|
||||
center of bitmap - (the number of planet pixels) / 4 */
|
||||
*buffer++ = (m_screen->width() / 2) - ((line->max_x + 2) / 4);
|
||||
|
||||
for (uint8_t i = 0, last_x = 0; i < segment_count; i++)
|
||||
{
|
||||
uint8_t current_x = (line->x_array[i] + 1) / 2;
|
||||
|
||||
*buffer++ = line->color_array[i];
|
||||
*buffer++ = current_x - last_x;
|
||||
|
||||
last_x = current_x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Start the video hardware emulation.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void liberatr_state::video_start()
|
||||
{
|
||||
// for each planet in the planet ROMs
|
||||
init_planet(m_planets[0], &memregion("gfx1")->base()[0x2000]);
|
||||
init_planet(m_planets[1], &memregion("gfx1")->base()[0x0000]);
|
||||
|
||||
save_item(NAME(m_planet_select));
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::get_pens(pen_t *pens)
|
||||
{
|
||||
offs_t i;
|
||||
|
||||
for (i = 0; i < NUM_PENS; i++)
|
||||
{
|
||||
uint8_t r,g,b;
|
||||
|
||||
/* handle the hardware flip of the bit order from 765 to 576 that
|
||||
hardware does between vram and color ram */
|
||||
static const offs_t penmap[] = { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
|
||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
|
||||
0x10, 0x12, 0x14, 0x16, 0x11, 0x13, 0x15, 0x17 };
|
||||
|
||||
uint8_t data = m_colorram[i];
|
||||
|
||||
/* scale it from 0x00-0xff */
|
||||
r = ((~data >> 3) & 0x07) * 0x24 + 3; if (r == 3) r = 0;
|
||||
g = ((~data >> 0) & 0x07) * 0x24 + 3; if (g == 3) g = 0;
|
||||
b = ((~data >> 5) & 0x06) * 0x24 + 3; if (b == 3) b = 0;
|
||||
|
||||
pens[penmap[i]] = rgb_t(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::draw_planet(bitmap_rgb32 &bitmap, pen_t *pens)
|
||||
{
|
||||
uint8_t const *buffer = m_planets[m_planet_select].frames[*m_planet_frame].get();
|
||||
|
||||
/* for each latitude */
|
||||
for (uint8_t latitude = 0; latitude < 0x80; latitude++)
|
||||
{
|
||||
/* grab the color value for the base (if any) at this latitude */
|
||||
uint8_t const base_color = m_base_ram[latitude >> 3] ^ 0x0f;
|
||||
|
||||
uint8_t const segment_count = *buffer++;
|
||||
uint8_t x = *buffer++;
|
||||
uint8_t const y = 64 + latitude;
|
||||
|
||||
/* run through the segments, drawing its color until its x_array value comes up. */
|
||||
for (uint8_t segment = 0; segment < segment_count; segment++)
|
||||
{
|
||||
uint8_t color = *buffer++;
|
||||
uint8_t segment_length = *buffer++;
|
||||
|
||||
if ((color & 0x0c) == 0x0c)
|
||||
color = base_color;
|
||||
|
||||
for (uint8_t i = 0; i < segment_length; i++, x++)
|
||||
bitmap.pix(y, x) = pens[color];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void liberatr_state::draw_bitmap(bitmap_rgb32 &bitmap, pen_t *pens)
|
||||
{
|
||||
for (offs_t offs = 0; offs < 0x10000; offs++)
|
||||
{
|
||||
uint8_t const data = m_videoram[offs];
|
||||
|
||||
uint8_t const y = offs >> 8;
|
||||
uint8_t const x = offs & 0xff;
|
||||
|
||||
if (data)
|
||||
bitmap.pix(y, x) = pens[(data >> 5) | 0x10];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t liberatr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
pen_t pens[NUM_PENS];
|
||||
get_pens(pens);
|
||||
|
||||
bitmap.fill(rgb_t::black(), cliprect);
|
||||
draw_planet(bitmap, pens);
|
||||
draw_bitmap(bitmap, pens);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Philip Bennett
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Metal Maniax
|
||||
@ -256,12 +257,81 @@ Logic:
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "metalmx.h"
|
||||
|
||||
#include "cage.h"
|
||||
|
||||
#include "cpu/adsp2100/adsp2100.h"
|
||||
#include "cpu/m68000/m68020.h"
|
||||
#include "cpu/tms34010/tms34010.h"
|
||||
#include "cpu/dsp32/dsp32.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class metalmx_state : public driver_device
|
||||
{
|
||||
public:
|
||||
metalmx_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gsp(*this, "gsp"),
|
||||
m_adsp(*this, "adsp"),
|
||||
m_dsp32c(*this, "dsp32c_%u", 1U),
|
||||
m_cage(*this, "cage"),
|
||||
m_adsp_internal_program_ram(*this, "adsp_intprog"),
|
||||
m_gsp_dram(*this, "gsp_dram"),
|
||||
m_gsp_vram(*this, "gsp_vram")
|
||||
{ }
|
||||
|
||||
void init_metalmx();
|
||||
void metalmx(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_device<m68ec020_device> m_maincpu;
|
||||
required_device<tms34020_device> m_gsp;
|
||||
required_device<adsp2105_device> m_adsp;
|
||||
required_device_array<dsp32c_device, 2> m_dsp32c;
|
||||
required_device<atari_cage_device> m_cage;
|
||||
|
||||
required_shared_ptr<uint32_t> m_adsp_internal_program_ram;
|
||||
required_shared_ptr<uint32_t> m_gsp_dram;
|
||||
required_shared_ptr<uint32_t> m_gsp_vram;
|
||||
|
||||
uint32_t unk_r();
|
||||
uint32_t watchdog_r();
|
||||
void shifter_w(uint32_t data);
|
||||
void motor_w(uint32_t data);
|
||||
void reset_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t sound_data_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void sound_data_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
template<int Chip> void dsp32c_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
template<int Chip> uint32_t dsp32c_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void host_gsp_w(offs_t offset, uint32_t data);
|
||||
uint32_t host_gsp_r(offs_t offset);
|
||||
uint32_t host_dram_r(offs_t offset);
|
||||
void host_dram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t host_vram_r(offs_t offset);
|
||||
void host_vram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
void timer_w(offs_t offset, uint32_t data);
|
||||
void cage_irq_callback(uint8_t data);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void adsp_data_map(address_map &map);
|
||||
void adsp_program_map(address_map &map);
|
||||
void dsp32c_1_map(address_map &map);
|
||||
void dsp32c_2_map(address_map &map);
|
||||
void gsp_map(address_map &map);
|
||||
void main_map(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Forward definitions
|
||||
@ -281,9 +351,9 @@ void metalmx_state::video_start()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t metalmx_state::screen_update_metalmx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
uint32_t metalmx_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* TODO: TMS34020 should take care of this */
|
||||
// TODO: TMS34020 should take care of this
|
||||
|
||||
// uint32_t *src_base = &gsp_vram[(vreg_base[0x40/4] & 0x40) ? 0x20000 : 0];
|
||||
uint32_t const *const src_base = &m_gsp_vram[0];
|
||||
@ -389,14 +459,12 @@ void metalmx_state::dsp32c_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
template<int Chip>
|
||||
uint32_t metalmx_state::dsp32c_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
offset <<= 1;
|
||||
|
||||
if (ACCESSING_BITS_0_15)
|
||||
offset += 1;
|
||||
|
||||
data = m_dsp32c[Chip]->pio_r(offset);
|
||||
uint32_t data = m_dsp32c[Chip]->pio_r(offset);
|
||||
|
||||
if (ACCESSING_BITS_16_31)
|
||||
data <<= 16;
|
||||
@ -481,22 +549,22 @@ void metalmx_state::main_map(address_map &map)
|
||||
map(0x600000, 0x6fffff).rw(FUNC(metalmx_state::host_dram_r), FUNC(metalmx_state::host_dram_w));
|
||||
map(0x700000, 0x7fffff).rw(FUNC(metalmx_state::host_vram_r), FUNC(metalmx_state::host_vram_w));
|
||||
map(0x800000, 0x80001f).rw(FUNC(metalmx_state::dsp32c_r<1>), FUNC(metalmx_state::dsp32c_w<1>));
|
||||
map(0x800020, 0x85ffff).noprw(); /* Unknown */
|
||||
map(0x800020, 0x85ffff).noprw(); // Unknown
|
||||
map(0x880000, 0x88001f).rw(FUNC(metalmx_state::dsp32c_r<0>), FUNC(metalmx_state::dsp32c_w<0>));
|
||||
map(0x980000, 0x9800ff).w(FUNC(metalmx_state::reset_w));
|
||||
map(0xb40000, 0xb40003).rw(FUNC(metalmx_state::sound_data_r), FUNC(metalmx_state::sound_data_w));
|
||||
map(0xf00000, 0xf00003).ram(); /* Network message port */
|
||||
map(0xf00000, 0xf00003).ram(); // Network message port
|
||||
map(0xf02000, 0xf02003).rw(FUNC(metalmx_state::watchdog_r), FUNC(metalmx_state::shifter_w));
|
||||
map(0xf03000, 0xf03003).portr("P1").w(FUNC(metalmx_state::motor_w));
|
||||
map(0xf04000, 0xf04003).portr("P2");
|
||||
map(0xf05000, 0xf05fff).nopw(); /* Lamps */ // f06000 = ADC // f01xxx = ADC
|
||||
map(0xf19000, 0xf19003).nopw(); /* Network */
|
||||
map(0xf05000, 0xf05fff).nopw(); // Lamps // f06000 = ADC // f01xxx = ADC
|
||||
map(0xf19000, 0xf19003).nopw(); // Network
|
||||
map(0xf1a000, 0xf1a003).nopw();
|
||||
map(0xf1b000, 0xf1b003).nopw();
|
||||
map(0xf1e000, 0xf1e003).ram(); /* Network status flags : 1000 = LIRQ 4000 = SFLAG 8000 = 68FLAG */
|
||||
map(0xf1e000, 0xf1e003).ram(); // Network status flags : 1000 = LIRQ 4000 = SFLAG 8000 = 68FLAG
|
||||
map(0xf20000, 0xf2ffff).w(FUNC(metalmx_state::timer_w));
|
||||
map(0xfc0000, 0xfc1fff).ram(); /* Zero power RAM */
|
||||
map(0xfd0000, 0xffffff).ram(); /* Scratch RAM */
|
||||
map(0xfc0000, 0xfc1fff).ram(); // Zero power RAM
|
||||
map(0xfd0000, 0xffffff).ram(); // Scratch RAM
|
||||
}
|
||||
|
||||
|
||||
@ -508,7 +576,7 @@ void metalmx_state::main_map(address_map &map)
|
||||
|
||||
void metalmx_state::adsp_program_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x03ff).ram().share("adsp_intprog");
|
||||
map(0x0000, 0x03ff).ram().share(m_adsp_internal_program_ram);
|
||||
}
|
||||
|
||||
void metalmx_state::adsp_data_map(address_map &map)
|
||||
@ -527,10 +595,10 @@ void metalmx_state::adsp_data_map(address_map &map)
|
||||
|
||||
void metalmx_state::gsp_map(address_map &map)
|
||||
{
|
||||
map(0x88800000, 0x8880001f).ram(); /* ? */
|
||||
map(0x88c00000, 0x88c0001f).ram(); /* ? */
|
||||
map(0xff000000, 0xff7fffff).ram().share("gsp_dram");
|
||||
map(0xff800000, 0xffffffff).ram().share("gsp_vram");
|
||||
map(0x88800000, 0x8880001f).ram(); // ?
|
||||
map(0x88c00000, 0x88c0001f).ram(); // ?
|
||||
map(0xff000000, 0xff7fffff).ram().share(m_gsp_dram);
|
||||
map(0xff800000, 0xffffffff).ram().share(m_gsp_vram);
|
||||
}
|
||||
|
||||
|
||||
@ -545,11 +613,11 @@ void metalmx_state::dsp32c_1_map(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x03ffff).ram();
|
||||
map(0x600000, 0x67ffff).ram();
|
||||
map(0x700000, 0x700003).nopw(); /* LEDs? */
|
||||
map(0x700000, 0x700003).nopw(); // LEDs?
|
||||
map(0xa00000, 0xa00003).r(FUNC(metalmx_state::unk_r));
|
||||
map(0xb00000, 0xb00003).r(FUNC(metalmx_state::unk_r));
|
||||
map(0xc00000, 0xc00003).ram(); /* FIFO? */
|
||||
map(0xf00000, 0xffffff).ram(); /* 3D registers */
|
||||
map(0xc00000, 0xc00003).ram(); // FIFO?
|
||||
map(0xf00000, 0xffffff).ram(); // 3D registers
|
||||
}
|
||||
|
||||
/*************************************
|
||||
@ -563,11 +631,11 @@ void metalmx_state::dsp32c_2_map(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x03ffff).ram();
|
||||
map(0x600000, 0x67ffff).ram();
|
||||
map(0x700000, 0x700003).nopw(); /* LEDs? */
|
||||
map(0x700000, 0x700003).nopw(); // LEDs?
|
||||
map(0xa00000, 0xa00003).r(FUNC(metalmx_state::unk_r));
|
||||
map(0xb00000, 0xb00003).r(FUNC(metalmx_state::unk_r));
|
||||
map(0xc00000, 0xc00003).ram(); /* FIFO? */
|
||||
map(0xf00000, 0xffffff).ram(); /* 3D registers */
|
||||
map(0xc00000, 0xc00003).ram(); // FIFO?
|
||||
map(0xf00000, 0xffffff).ram(); // 3D registers
|
||||
}
|
||||
|
||||
|
||||
@ -596,7 +664,7 @@ static INPUT_PORTS_START( metalmx )
|
||||
PORT_BIT( 0x00004000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
/* COINS */
|
||||
// COINS
|
||||
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_COIN3 )
|
||||
@ -606,7 +674,7 @@ static INPUT_PORTS_START( metalmx )
|
||||
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
/* AUX */
|
||||
// AUX
|
||||
PORT_BIT( 0x01000000, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x02000000, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x04000000, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
@ -667,17 +735,17 @@ void metalmx_state::metalmx(machine_config &config)
|
||||
m_adsp->set_addrmap(AS_PROGRAM, &metalmx_state::adsp_program_map);
|
||||
m_adsp->set_addrmap(AS_DATA, &metalmx_state::adsp_data_map);
|
||||
|
||||
TMS34020(config, m_gsp, 40000000); /* Unverified */
|
||||
TMS34020(config, m_gsp, 40'000'000); // Unverified
|
||||
m_gsp->set_addrmap(AS_PROGRAM, &metalmx_state::gsp_map);
|
||||
m_gsp->set_halt_on_reset(true);
|
||||
m_gsp->set_pixel_clock(4000000);
|
||||
m_gsp->set_pixel_clock(4'000'000);
|
||||
m_gsp->set_pixels_per_clock(2);
|
||||
m_gsp->output_int().set_inputline("maincpu", 4);
|
||||
|
||||
DSP32C(config, m_dsp32c[0], 40000000); /* Unverified */
|
||||
DSP32C(config, m_dsp32c[0], 40'000'000); // Unverified
|
||||
m_dsp32c[0]->set_addrmap(AS_PROGRAM, &metalmx_state::dsp32c_1_map);
|
||||
|
||||
DSP32C(config, m_dsp32c[1], 40000000); /* Unverified */
|
||||
DSP32C(config, m_dsp32c[1], 40'000'000); // Unverified
|
||||
m_dsp32c[1]->set_addrmap(AS_PROGRAM, &metalmx_state::dsp32c_2_map);
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -685,7 +753,7 @@ void metalmx_state::metalmx(machine_config &config)
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(512, 384);
|
||||
screen.set_visarea(0, 511, 0, 383);
|
||||
screen.set_screen_update(FUNC(metalmx_state::screen_update_metalmx));
|
||||
screen.set_screen_update(FUNC(metalmx_state::screen_update));
|
||||
screen.set_palette("palette");
|
||||
|
||||
PALETTE(config, "palette", palette_device::RGB_565);
|
||||
@ -831,6 +899,8 @@ ROM_START( metalmx )
|
||||
ROM_LOAD( "103-1116.bin", 0x000, 0x117, CRC(37edc36c) SHA1(be53131c52e84cb3fe055af5ca4e2f6aa5442ff0) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
|
@ -1,72 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Philip Bennett
|
||||
#ifndef MAME_ATARI_METALMX_H
|
||||
#define MAME_ATARI_METALMX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cage.h"
|
||||
|
||||
#include "cpu/adsp2100/adsp2100.h"
|
||||
#include "cpu/m68000/m68020.h"
|
||||
#include "cpu/tms34010/tms34010.h"
|
||||
#include "cpu/dsp32/dsp32.h"
|
||||
|
||||
class metalmx_state : public driver_device
|
||||
{
|
||||
public:
|
||||
metalmx_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gsp(*this, "gsp"),
|
||||
m_adsp(*this, "adsp"),
|
||||
m_dsp32c(*this, "dsp32c_%u", 1U),
|
||||
m_cage(*this, "cage"),
|
||||
m_adsp_internal_program_ram(*this, "adsp_intprog"),
|
||||
m_gsp_dram(*this, "gsp_dram"),
|
||||
m_gsp_vram(*this, "gsp_vram")
|
||||
{ }
|
||||
|
||||
void init_metalmx();
|
||||
void metalmx(machine_config &config);
|
||||
|
||||
private:
|
||||
uint32_t unk_r();
|
||||
uint32_t watchdog_r();
|
||||
void shifter_w(uint32_t data);
|
||||
void motor_w(uint32_t data);
|
||||
void reset_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t sound_data_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void sound_data_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
template<int Chip> void dsp32c_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
template<int Chip> uint32_t dsp32c_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void host_gsp_w(offs_t offset, uint32_t data);
|
||||
uint32_t host_gsp_r(offs_t offset);
|
||||
uint32_t host_dram_r(offs_t offset);
|
||||
void host_dram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t host_vram_r(offs_t offset);
|
||||
void host_vram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
void timer_w(offs_t offset, uint32_t data);
|
||||
void cage_irq_callback(uint8_t data);
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_metalmx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void adsp_data_map(address_map &map);
|
||||
void adsp_program_map(address_map &map);
|
||||
void dsp32c_1_map(address_map &map);
|
||||
void dsp32c_2_map(address_map &map);
|
||||
void gsp_map(address_map &map);
|
||||
void main_map(address_map &map);
|
||||
|
||||
required_device<m68ec020_device> m_maincpu;
|
||||
required_device<tms34020_device> m_gsp;
|
||||
required_device<adsp2105_device> m_adsp;
|
||||
required_device_array<dsp32c_device, 2> m_dsp32c;
|
||||
required_device<atari_cage_device> m_cage;
|
||||
|
||||
required_shared_ptr<uint32_t> m_adsp_internal_program_ram;
|
||||
required_shared_ptr<uint32_t> m_gsp_dram;
|
||||
required_shared_ptr<uint32_t> m_gsp_vram;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_METALMX_H
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mike Balfour
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Night Driver hardware
|
||||
@ -37,15 +38,441 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "nitedrvr.h"
|
||||
|
||||
#include "nitedrvr_a.h"
|
||||
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/rescap.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/discrete.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class nitedrvr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
nitedrvr_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_discrete(*this, "discrete"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette"),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_hvc(*this, "hvc"),
|
||||
m_steer(*this, "STEER"),
|
||||
m_gears(*this, "GEARS"),
|
||||
m_in0(*this, "IN0"),
|
||||
m_dsw(*this, "DSW%u", 0U),
|
||||
m_led(*this, "led"),
|
||||
m_track_sel(*this, "track%u", 1U),
|
||||
m_gear_sel(*this, "gear%u", 1U)
|
||||
{ }
|
||||
|
||||
void nitedrvr(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
// devices
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<discrete_device> m_discrete;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
// memory pointers
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
required_shared_ptr<uint8_t> m_hvc;
|
||||
|
||||
// input
|
||||
uint8_t m_gear = 0;
|
||||
uint8_t m_track = 0;
|
||||
int32_t m_steering_buf = 0;
|
||||
int32_t m_steering_val = 0;
|
||||
uint8_t m_crash_en = 0;
|
||||
uint8_t m_crash_data = 0;
|
||||
uint8_t m_crash_data_en = 0; // IC D8
|
||||
uint8_t m_ac_line = 0;
|
||||
int32_t m_last_steering_val = 0;
|
||||
required_ioport m_steer, m_gears, m_in0;
|
||||
required_ioport_array<3> m_dsw;
|
||||
|
||||
// output
|
||||
output_finder<> m_led;
|
||||
output_finder<3> m_track_sel;
|
||||
output_finder<4> m_gear_sel;
|
||||
|
||||
uint8_t steering_reset_r();
|
||||
void steering_reset_w(uint8_t data);
|
||||
uint8_t in0_r(offs_t offset);
|
||||
uint8_t in1_r(offs_t offset);
|
||||
void out0_w(uint8_t data);
|
||||
void out1_w(uint8_t data);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(crash_toggle_callback);
|
||||
void draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect, int bx, int by, int ex, int ey);
|
||||
void draw_roadway(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
int steering();
|
||||
void main_map(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
void nitedrvr_state::draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect, int bx, int by, int ex, int ey)
|
||||
{
|
||||
for (int y = by; y < ey; y++)
|
||||
{
|
||||
for (int x = bx; x < ex; x++)
|
||||
if (cliprect.contains(x, y))
|
||||
bitmap.pix(y, x) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::draw_roadway(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int roadway = 0; roadway < 16; roadway++)
|
||||
{
|
||||
int const bx = m_hvc[roadway];
|
||||
int const by = m_hvc[roadway + 16];
|
||||
int const ex = bx + ((m_hvc[roadway + 32] & 0xf0) >> 4);
|
||||
int const ey = by + (16 - (m_hvc[roadway + 32] & 0x0f));
|
||||
|
||||
draw_box(bitmap, cliprect, bx, by, ex, ey);
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// draw tiles manually, note that tile rows are ignored on V&8, V&64, V&128
|
||||
for (int offs = 0; offs < 0x80; offs++)
|
||||
{
|
||||
int const code = m_videoram[offs];
|
||||
int const sx = (offs & 0x1f) * 8;
|
||||
int const sy = (offs >> 5) * 2 * 8;
|
||||
|
||||
m_gfxdecode->gfx(0)->opaque(bitmap, cliprect, code, 0, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nitedrvr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
draw_tiles(bitmap, cliprect);
|
||||
draw_roadway(bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
/***************************************************************************
|
||||
Steering
|
||||
|
||||
When D7 is high, the steering wheel has moved.
|
||||
If D6 is low, it moved left. If D6 is high, it moved right.
|
||||
Be sure to keep returning a direction until steering_reset is called,
|
||||
because D6 and D7 are apparently checked at different times, and a
|
||||
change in-between can affect the direction you move.
|
||||
***************************************************************************/
|
||||
|
||||
int nitedrvr_state::steering()
|
||||
{
|
||||
int const this_val = m_steer->read();
|
||||
int delta = this_val - m_last_steering_val;
|
||||
|
||||
m_last_steering_val = this_val;
|
||||
|
||||
if (delta > 128)
|
||||
delta -= 256;
|
||||
else if (delta < -128)
|
||||
delta += 256;
|
||||
|
||||
// Divide by four to make our steering less sensitive
|
||||
m_steering_buf += (delta / 4);
|
||||
|
||||
if (m_steering_buf > 0)
|
||||
{
|
||||
m_steering_buf--;
|
||||
m_steering_val = 0xc0;
|
||||
}
|
||||
else if (m_steering_buf < 0)
|
||||
{
|
||||
m_steering_buf++;
|
||||
m_steering_val = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_steering_val = 0x00;
|
||||
}
|
||||
|
||||
return m_steering_val;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
steering_reset
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::steering_reset_r()
|
||||
{
|
||||
m_steering_val = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nitedrvr_state::steering_reset_w(uint8_t data)
|
||||
{
|
||||
m_steering_val = 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
in0_r
|
||||
|
||||
Night Driver looks for the following:
|
||||
A: $00
|
||||
D4 - OPT1
|
||||
D5 - OPT2
|
||||
D6 - OPT3
|
||||
D7 - OPT4
|
||||
A: $01
|
||||
D4 - TRACK SET
|
||||
D5 - BONUS TIME ALLOWED
|
||||
D6 - VBLANK
|
||||
D7 - !TEST
|
||||
A: $02
|
||||
D4 - !GEAR 1
|
||||
D5 - !GEAR 2
|
||||
D6 - !GEAR 3
|
||||
D7 - SPARE
|
||||
A: $03
|
||||
D4 - SPARE
|
||||
D5 - DIFFICULT BONUS
|
||||
D6 - STEER A
|
||||
D7 - STEER B
|
||||
|
||||
Fill in the steering and gear bits in a special way.
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::in0_r(offs_t offset)
|
||||
{
|
||||
int const gear = m_gears->read();
|
||||
|
||||
if (gear & 0x10) m_gear = 1;
|
||||
else if (gear & 0x20) m_gear = 2;
|
||||
else if (gear & 0x40) m_gear = 3;
|
||||
else if (gear & 0x80) m_gear = 4;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
m_gear_sel[i] = ((m_gear == (i + 1)) ? 1 : 0);
|
||||
|
||||
switch (offset & 0x03)
|
||||
{
|
||||
case 0x00: // No remapping necessary
|
||||
return m_dsw[0]->read();
|
||||
case 0x01: // No remapping necessary
|
||||
return m_dsw[1]->read();
|
||||
case 0x02: // Remap our gear shift
|
||||
if (m_gear == 1)
|
||||
return 0xe0;
|
||||
else if (m_gear == 2)
|
||||
return 0xd0;
|
||||
else if (m_gear == 3)
|
||||
return 0xb0;
|
||||
else
|
||||
return 0x70;
|
||||
case 0x03: // Remap our steering
|
||||
return (m_dsw[2]->read() | steering());
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
in1_r
|
||||
|
||||
Night Driver looks for the following:
|
||||
A: $00
|
||||
D6 - SPARE
|
||||
D7 - COIN 1
|
||||
A: $01
|
||||
D6 - SPARE
|
||||
D7 - COIN 2
|
||||
A: $02
|
||||
D6 - SPARE
|
||||
D7 - !START
|
||||
A: $03
|
||||
D6 - SPARE
|
||||
D7 - !ACC
|
||||
A: $04
|
||||
D6 - SPARE
|
||||
D7 - EXPERT
|
||||
A: $05
|
||||
D6 - SPARE
|
||||
D7 - NOVICE
|
||||
A: $06
|
||||
D6 - SPARE
|
||||
D7 - Special Alternating Signal
|
||||
A: $07
|
||||
D6 - SPARE
|
||||
D7 - Ground
|
||||
|
||||
Fill in the track difficulty switch and special signal in a special way.
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::in1_r(offs_t offset)
|
||||
{
|
||||
int const port = m_in0->read();
|
||||
|
||||
m_ac_line = (m_ac_line + 1) % 3;
|
||||
|
||||
if (port & 0x10) m_track = 0;
|
||||
else if (port & 0x20) m_track = 1;
|
||||
else if (port & 0x40) m_track = 2;
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
m_track_sel[i] = (m_track == i ? 1 : 0);
|
||||
|
||||
switch (offset & 0x07)
|
||||
{
|
||||
case 0x00:
|
||||
return ((port & 0x01) << 7);
|
||||
case 0x01:
|
||||
return ((port & 0x02) << 6);
|
||||
case 0x02:
|
||||
return ((port & 0x04) << 5);
|
||||
case 0x03:
|
||||
return ((port & 0x08) << 4);
|
||||
case 0x04:
|
||||
if (m_track == 1) return 0x80; else return 0x00;
|
||||
case 0x05:
|
||||
if (m_track == 0) return 0x80; else return 0x00;
|
||||
case 0x06:
|
||||
// TODO: fix alternating signal?
|
||||
if (m_ac_line == 0) return 0x80; else return 0x00;
|
||||
case 0x07:
|
||||
return 0x00;
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
out0_w
|
||||
|
||||
Sound bits:
|
||||
|
||||
D0 = !SPEED1
|
||||
D1 = !SPEED2
|
||||
D2 = !SPEED3
|
||||
D3 = !SPEED4
|
||||
D4 = SKID1
|
||||
D5 = SKID2
|
||||
***************************************************************************/
|
||||
|
||||
void nitedrvr_state::out0_w(uint8_t data)
|
||||
{
|
||||
m_discrete->write(NITEDRVR_MOTOR_DATA, data & 0x0f); // Motor freq data
|
||||
m_discrete->write(NITEDRVR_SKID1_EN, data & 0x10); // Skid1 enable
|
||||
m_discrete->write(NITEDRVR_SKID2_EN, data & 0x20); // Skid2 enable
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
out1_w
|
||||
|
||||
D0 = !CRASH - also drives a video invert signal
|
||||
D1 = ATTRACT
|
||||
D2 = Spare (Not used)
|
||||
D3 = Not used?
|
||||
D4 = LED START
|
||||
D5 = Spare (Not used)
|
||||
***************************************************************************/
|
||||
|
||||
void nitedrvr_state::out1_w(uint8_t data)
|
||||
{
|
||||
m_led = BIT(data, 4);
|
||||
|
||||
m_crash_en = data & 0x01;
|
||||
|
||||
m_discrete->write(NITEDRVR_CRASH_EN, m_crash_en); // Crash enable
|
||||
m_discrete->write(NITEDRVR_ATTRACT_EN, data & 0x02); // Attract enable (sound disable)
|
||||
|
||||
if (!m_crash_en)
|
||||
{
|
||||
// Crash reset, set counter high and enable output
|
||||
m_crash_data_en = 1;
|
||||
m_crash_data = 0x0f;
|
||||
// Invert video
|
||||
m_palette->set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); // BLACK
|
||||
m_palette->set_pen_color(0, rgb_t(0xff, 0xff, 0xff)); // WHITE
|
||||
}
|
||||
m_discrete->write(NITEDRVR_BANG_DATA, m_crash_data_en ? m_crash_data : 0); // Crash Volume
|
||||
}
|
||||
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(nitedrvr_state::crash_toggle_callback)
|
||||
{
|
||||
if (m_crash_en && m_crash_data_en)
|
||||
{
|
||||
m_crash_data--;
|
||||
m_discrete->write(NITEDRVR_BANG_DATA, m_crash_data); // Crash Volume
|
||||
if (!m_crash_data)
|
||||
m_crash_data_en = 0; // Done counting?
|
||||
|
||||
if (m_crash_data & 0x01)
|
||||
{
|
||||
// Invert video
|
||||
m_palette->set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); // BLACK
|
||||
m_palette->set_pen_color(0, rgb_t(0xff, 0xff, 0xff)); // WHITE
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal video
|
||||
m_palette->set_pen_color(0, rgb_t(0x00,0x00,0x00)); // BLACK
|
||||
m_palette->set_pen_color(1, rgb_t(0xff,0xff,0xff)); // WHITE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::machine_start()
|
||||
{
|
||||
m_led.resolve();
|
||||
m_track_sel.resolve();
|
||||
m_gear_sel.resolve();
|
||||
|
||||
save_item(NAME(m_gear));
|
||||
save_item(NAME(m_track));
|
||||
save_item(NAME(m_steering_buf));
|
||||
save_item(NAME(m_steering_val));
|
||||
save_item(NAME(m_crash_en));
|
||||
save_item(NAME(m_crash_data));
|
||||
save_item(NAME(m_crash_data_en));
|
||||
save_item(NAME(m_ac_line));
|
||||
save_item(NAME(m_last_steering_val));
|
||||
}
|
||||
|
||||
void nitedrvr_state::machine_reset()
|
||||
{
|
||||
m_gear = 1;
|
||||
m_track = 0;
|
||||
m_steering_buf = 0;
|
||||
m_steering_val = 0;
|
||||
m_crash_en = 0;
|
||||
m_crash_data = 0x0f;
|
||||
m_crash_data_en = 0;
|
||||
m_ac_line = 0;
|
||||
m_last_steering_val = 0;
|
||||
}
|
||||
|
||||
|
||||
// Memory Map
|
||||
|
||||
void nitedrvr_state::main_map(address_map &map)
|
||||
@ -119,23 +546,10 @@ static INPUT_PORTS_START( nitedrvr )
|
||||
PORT_ADJUSTER( 60, "Motor RPM" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
// Graphics Layouts
|
||||
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8, 8,
|
||||
64,
|
||||
1,
|
||||
{ 0 },
|
||||
{ 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
|
||||
};
|
||||
|
||||
// Graphics Decode Information
|
||||
|
||||
static GFXDECODE_START( gfx_nitedrvr )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 1 )
|
||||
GFXDECODE_ENTRY( "gfx", 0, gfx_8x8x1, 0, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
// Machine Driver
|
||||
@ -190,13 +604,16 @@ ROM_START( nitedrvr )
|
||||
ROM_LOAD( "006570-01.f2", 0x9800, 0x0800, CRC(bf5d77b1) SHA1(6f603f8b0973bd89e0e721b66944aac8e9f904d9) ) // mask ROM 2
|
||||
ROM_RELOAD( 0xf800, 0x0800 ) // vectors
|
||||
|
||||
ROM_REGION( 0x200, "gfx1", 0 )
|
||||
ROM_REGION( 0x200, "gfx", 0 )
|
||||
ROM_LOAD( "006568-01.p2", 0x0000, 0x0200, CRC(f80d8889) SHA1(ca573543dcce1221459d5693c476cef14bfac4f4) ) // PROM, Alpha-Numeric
|
||||
|
||||
ROM_REGION( 0x100, "proms", 0 )
|
||||
ROM_REGION( 0x100, "sync_prom", 0 )
|
||||
ROM_LOAD( "006559-01.h7", 0x0000, 0x0100, CRC(5a8d0e42) SHA1(772220c4c24f18769696ddba26db2bc2e5b0909d) ) // PROM, Sync
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
// Game Drivers
|
||||
|
||||
GAME( 1976, nitedrvr, 0, nitedrvr, nitedrvr, nitedrvr_state, empty_init, ROT0, "Atari", "Night Driver", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,99 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mike Balfour
|
||||
/*************************************************************************
|
||||
|
||||
Atari Night Driver hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_NITEDRVR_H
|
||||
#define MAME_ATARI_NITEDRVR_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/timer.h"
|
||||
#include "sound/discrete.h"
|
||||
#include "emupal.h"
|
||||
|
||||
// Discrete Sound Input Nodes
|
||||
#define NITEDRVR_BANG_DATA NODE_01
|
||||
#define NITEDRVR_SKID1_EN NODE_02
|
||||
#define NITEDRVR_SKID2_EN NODE_03
|
||||
#define NITEDRVR_MOTOR_DATA NODE_04
|
||||
#define NITEDRVR_CRASH_EN NODE_05
|
||||
#define NITEDRVR_ATTRACT_EN NODE_06
|
||||
|
||||
|
||||
class nitedrvr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
nitedrvr_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_discrete(*this, "discrete"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette"),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_hvc(*this, "hvc"),
|
||||
m_steer(*this, "STEER"),
|
||||
m_gears(*this, "GEARS"),
|
||||
m_in0(*this, "IN0"),
|
||||
m_dsw(*this, "DSW%u", 0U),
|
||||
m_led(*this, "led"),
|
||||
m_track_sel(*this, "track%u", 1U),
|
||||
m_gear_sel(*this, "gear%u", 1U)
|
||||
{ }
|
||||
|
||||
void nitedrvr(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
uint8_t steering_reset_r();
|
||||
void steering_reset_w(uint8_t data);
|
||||
uint8_t in0_r(offs_t offset);
|
||||
uint8_t in1_r(offs_t offset);
|
||||
void out0_w(uint8_t data);
|
||||
void out1_w(uint8_t data);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(crash_toggle_callback);
|
||||
void draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect, int bx, int by, int ex, int ey);
|
||||
void draw_roadway(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
int steering();
|
||||
void main_map(address_map &map);
|
||||
|
||||
// devices
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<discrete_device> m_discrete;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
// memory pointers
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
required_shared_ptr<uint8_t> m_hvc;
|
||||
|
||||
// input
|
||||
uint8_t m_gear = 0;
|
||||
uint8_t m_track = 0;
|
||||
int32_t m_steering_buf = 0;
|
||||
int32_t m_steering_val = 0;
|
||||
uint8_t m_crash_en = 0;
|
||||
uint8_t m_crash_data = 0;
|
||||
uint8_t m_crash_data_en = 0; // IC D8
|
||||
uint8_t m_ac_line = 0;
|
||||
int32_t m_last_steering_val = 0;
|
||||
required_ioport m_steer, m_gears, m_in0;
|
||||
required_ioport_array<3> m_dsw;
|
||||
|
||||
// output
|
||||
output_finder<> m_led;
|
||||
output_finder<3> m_track_sel;
|
||||
output_finder<4> m_gear_sel;
|
||||
};
|
||||
|
||||
//----------- defined in audio/nitedrvr.cpp -----------
|
||||
DISCRETE_SOUND_EXTERN( nitedrvr_discrete );
|
||||
|
||||
#endif // MAME_ATARI_NITEDRVR_H
|
@ -1,13 +1,14 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Derrick Renaud
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
audio\nitedrvr.cpp
|
||||
|
||||
*************************************************************************/
|
||||
#include "emu.h"
|
||||
#include "nitedrvr.h"
|
||||
#include "sound/discrete.h"
|
||||
|
||||
#include "nitedrvr_a.h"
|
||||
|
||||
|
||||
// Discrete Sound Emulation
|
||||
|
27
src/mame/atari/nitedrvr_a.h
Normal file
27
src/mame/atari/nitedrvr_a.h
Normal file
@ -0,0 +1,27 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Derrick Renaud
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Night Driver Audio
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef MAME_ATARI_NITEDRVR_A_H
|
||||
#define MAME_ATARI_NITEDRVR_A_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sound/discrete.h"
|
||||
|
||||
// discrete sound input nodes
|
||||
|
||||
#define NITEDRVR_BANG_DATA NODE_01
|
||||
#define NITEDRVR_SKID1_EN NODE_02
|
||||
#define NITEDRVR_SKID2_EN NODE_03
|
||||
#define NITEDRVR_MOTOR_DATA NODE_04
|
||||
#define NITEDRVR_CRASH_EN NODE_05
|
||||
#define NITEDRVR_ATTRACT_EN NODE_06
|
||||
|
||||
DISCRETE_SOUND_EXTERN( nitedrvr_discrete );
|
||||
|
||||
#endif // MAME_ATARI_NITEDRVR_A_H
|
@ -1,308 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mike Balfour
|
||||
/***************************************************************************
|
||||
|
||||
Atari Night Driver hardware
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "nitedrvr.h"
|
||||
#include "sound/discrete.h"
|
||||
|
||||
/***************************************************************************
|
||||
Steering
|
||||
|
||||
When D7 is high, the steering wheel has moved.
|
||||
If D6 is low, it moved left. If D6 is high, it moved right.
|
||||
Be sure to keep returning a direction until steering_reset is called,
|
||||
because D6 and D7 are apparently checked at different times, and a
|
||||
change in-between can affect the direction you move.
|
||||
***************************************************************************/
|
||||
|
||||
int nitedrvr_state::steering()
|
||||
{
|
||||
int this_val = m_steer->read();
|
||||
int delta = this_val - m_last_steering_val;
|
||||
|
||||
m_last_steering_val = this_val;
|
||||
|
||||
if (delta > 128)
|
||||
delta -= 256;
|
||||
else if (delta < -128)
|
||||
delta += 256;
|
||||
|
||||
// Divide by four to make our steering less sensitive
|
||||
m_steering_buf += (delta / 4);
|
||||
|
||||
if (m_steering_buf > 0)
|
||||
{
|
||||
m_steering_buf--;
|
||||
m_steering_val = 0xc0;
|
||||
}
|
||||
else if (m_steering_buf < 0)
|
||||
{
|
||||
m_steering_buf++;
|
||||
m_steering_val = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_steering_val = 0x00;
|
||||
}
|
||||
|
||||
return m_steering_val;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
steering_reset
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::steering_reset_r()
|
||||
{
|
||||
m_steering_val = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nitedrvr_state::steering_reset_w(uint8_t data)
|
||||
{
|
||||
m_steering_val = 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
in0_r
|
||||
|
||||
Night Driver looks for the following:
|
||||
A: $00
|
||||
D4 - OPT1
|
||||
D5 - OPT2
|
||||
D6 - OPT3
|
||||
D7 - OPT4
|
||||
A: $01
|
||||
D4 - TRACK SET
|
||||
D5 - BONUS TIME ALLOWED
|
||||
D6 - VBLANK
|
||||
D7 - !TEST
|
||||
A: $02
|
||||
D4 - !GEAR 1
|
||||
D5 - !GEAR 2
|
||||
D6 - !GEAR 3
|
||||
D7 - SPARE
|
||||
A: $03
|
||||
D4 - SPARE
|
||||
D5 - DIFFICULT BONUS
|
||||
D6 - STEER A
|
||||
D7 - STEER B
|
||||
|
||||
Fill in the steering and gear bits in a special way.
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::in0_r(offs_t offset)
|
||||
{
|
||||
int gear = m_gears->read();
|
||||
|
||||
if (gear & 0x10) m_gear = 1;
|
||||
else if (gear & 0x20) m_gear = 2;
|
||||
else if (gear & 0x40) m_gear = 3;
|
||||
else if (gear & 0x80) m_gear = 4;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
m_gear_sel[i] = ((m_gear == (i + 1)) ? 1 : 0);
|
||||
|
||||
switch (offset & 0x03)
|
||||
{
|
||||
case 0x00: // No remapping necessary
|
||||
return m_dsw[0]->read();
|
||||
case 0x01: // No remapping necessary
|
||||
return m_dsw[1]->read();
|
||||
case 0x02: // Remap our gear shift
|
||||
if (m_gear == 1)
|
||||
return 0xe0;
|
||||
else if (m_gear == 2)
|
||||
return 0xd0;
|
||||
else if (m_gear == 3)
|
||||
return 0xb0;
|
||||
else
|
||||
return 0x70;
|
||||
case 0x03: // Remap our steering
|
||||
return (m_dsw[2]->read() | steering());
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
in1_r
|
||||
|
||||
Night Driver looks for the following:
|
||||
A: $00
|
||||
D6 - SPARE
|
||||
D7 - COIN 1
|
||||
A: $01
|
||||
D6 - SPARE
|
||||
D7 - COIN 2
|
||||
A: $02
|
||||
D6 - SPARE
|
||||
D7 - !START
|
||||
A: $03
|
||||
D6 - SPARE
|
||||
D7 - !ACC
|
||||
A: $04
|
||||
D6 - SPARE
|
||||
D7 - EXPERT
|
||||
A: $05
|
||||
D6 - SPARE
|
||||
D7 - NOVICE
|
||||
A: $06
|
||||
D6 - SPARE
|
||||
D7 - Special Alternating Signal
|
||||
A: $07
|
||||
D6 - SPARE
|
||||
D7 - Ground
|
||||
|
||||
Fill in the track difficulty switch and special signal in a special way.
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t nitedrvr_state::in1_r(offs_t offset)
|
||||
{
|
||||
int port = m_in0->read();
|
||||
|
||||
m_ac_line = (m_ac_line + 1) % 3;
|
||||
|
||||
if (port & 0x10) m_track = 0;
|
||||
else if (port & 0x20) m_track = 1;
|
||||
else if (port & 0x40) m_track = 2;
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
m_track_sel[i] = (m_track == i ? 1 : 0);
|
||||
|
||||
switch (offset & 0x07)
|
||||
{
|
||||
case 0x00:
|
||||
return ((port & 0x01) << 7);
|
||||
case 0x01:
|
||||
return ((port & 0x02) << 6);
|
||||
case 0x02:
|
||||
return ((port & 0x04) << 5);
|
||||
case 0x03:
|
||||
return ((port & 0x08) << 4);
|
||||
case 0x04:
|
||||
if (m_track == 1) return 0x80; else return 0x00;
|
||||
case 0x05:
|
||||
if (m_track == 0) return 0x80; else return 0x00;
|
||||
case 0x06:
|
||||
// TODO: fix alternating signal?
|
||||
if (m_ac_line==0) return 0x80; else return 0x00;
|
||||
case 0x07:
|
||||
return 0x00;
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
out0_w
|
||||
|
||||
Sound bits:
|
||||
|
||||
D0 = !SPEED1
|
||||
D1 = !SPEED2
|
||||
D2 = !SPEED3
|
||||
D3 = !SPEED4
|
||||
D4 = SKID1
|
||||
D5 = SKID2
|
||||
***************************************************************************/
|
||||
|
||||
void nitedrvr_state::out0_w(uint8_t data)
|
||||
{
|
||||
m_discrete->write(NITEDRVR_MOTOR_DATA, data & 0x0f); // Motor freq data
|
||||
m_discrete->write(NITEDRVR_SKID1_EN, data & 0x10); // Skid1 enable
|
||||
m_discrete->write(NITEDRVR_SKID2_EN, data & 0x20); // Skid2 enable
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
out1_w
|
||||
|
||||
D0 = !CRASH - also drives a video invert signal
|
||||
D1 = ATTRACT
|
||||
D2 = Spare (Not used)
|
||||
D3 = Not used?
|
||||
D4 = LED START
|
||||
D5 = Spare (Not used)
|
||||
***************************************************************************/
|
||||
|
||||
void nitedrvr_state::out1_w(uint8_t data)
|
||||
{
|
||||
m_led = BIT(data, 4);
|
||||
|
||||
m_crash_en = data & 0x01;
|
||||
|
||||
m_discrete->write(NITEDRVR_CRASH_EN, m_crash_en); // Crash enable
|
||||
m_discrete->write(NITEDRVR_ATTRACT_EN, data & 0x02); // Attract enable (sound disable)
|
||||
|
||||
if (!m_crash_en)
|
||||
{
|
||||
// Crash reset, set counter high and enable output
|
||||
m_crash_data_en = 1;
|
||||
m_crash_data = 0x0f;
|
||||
// Invert video
|
||||
m_palette->set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); // BLACK
|
||||
m_palette->set_pen_color(0, rgb_t(0xff, 0xff, 0xff)); // WHITE
|
||||
}
|
||||
m_discrete->write(NITEDRVR_BANG_DATA, m_crash_data_en ? m_crash_data : 0); // Crash Volume
|
||||
}
|
||||
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(nitedrvr_state::crash_toggle_callback)
|
||||
{
|
||||
if (m_crash_en && m_crash_data_en)
|
||||
{
|
||||
m_crash_data--;
|
||||
m_discrete->write(NITEDRVR_BANG_DATA, m_crash_data); // Crash Volume
|
||||
if (!m_crash_data)
|
||||
m_crash_data_en = 0; // Done counting?
|
||||
|
||||
if (m_crash_data & 0x01)
|
||||
{
|
||||
// Invert video
|
||||
m_palette->set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); // BLACK
|
||||
m_palette->set_pen_color(0, rgb_t(0xff, 0xff, 0xff)); // WHITE
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal video
|
||||
m_palette->set_pen_color(0, rgb_t(0x00,0x00,0x00)); // BLACK
|
||||
m_palette->set_pen_color(1, rgb_t(0xff,0xff,0xff)); // WHITE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::machine_start()
|
||||
{
|
||||
m_led.resolve();
|
||||
m_track_sel.resolve();
|
||||
m_gear_sel.resolve();
|
||||
|
||||
save_item(NAME(m_gear));
|
||||
save_item(NAME(m_track));
|
||||
save_item(NAME(m_steering_buf));
|
||||
save_item(NAME(m_steering_val));
|
||||
save_item(NAME(m_crash_en));
|
||||
save_item(NAME(m_crash_data));
|
||||
save_item(NAME(m_crash_data_en));
|
||||
save_item(NAME(m_ac_line));
|
||||
save_item(NAME(m_last_steering_val));
|
||||
}
|
||||
|
||||
void nitedrvr_state::machine_reset()
|
||||
{
|
||||
m_gear = 1;
|
||||
m_track = 0;
|
||||
m_steering_buf = 0;
|
||||
m_steering_val = 0;
|
||||
m_crash_en = 0;
|
||||
m_crash_data = 0x0f;
|
||||
m_crash_data_en = 0;
|
||||
m_ac_line = 0;
|
||||
m_last_steering_val = 0;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mike Balfour
|
||||
/***************************************************************************
|
||||
|
||||
Atari Night Driver hardware
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "nitedrvr.h"
|
||||
|
||||
|
||||
void nitedrvr_state::draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect, int bx, int by, int ex, int ey)
|
||||
{
|
||||
for (int y = by; y < ey; y++)
|
||||
{
|
||||
for (int x = bx; x < ex; x++)
|
||||
if (cliprect.contains(x, y))
|
||||
bitmap.pix(y, x) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::draw_roadway(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int roadway = 0; roadway < 16; roadway++)
|
||||
{
|
||||
int bx = m_hvc[roadway];
|
||||
int by = m_hvc[roadway + 16];
|
||||
int ex = bx + ((m_hvc[roadway + 32] & 0xf0) >> 4);
|
||||
int ey = by + (16 - (m_hvc[roadway + 32] & 0x0f));
|
||||
|
||||
draw_box(bitmap, cliprect, bx, by, ex, ey);
|
||||
}
|
||||
}
|
||||
|
||||
void nitedrvr_state::draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// draw tiles manually, note that tile rows are ignored on V&8, V&64, V&128
|
||||
for (int offs = 0; offs < 0x80; offs++)
|
||||
{
|
||||
int code = m_videoram[offs];
|
||||
int sx = (offs & 0x1f) * 8;
|
||||
int sy = (offs >> 5) * 2 * 8;
|
||||
|
||||
m_gfxdecode->gfx(0)->opaque(bitmap, cliprect, code, 0, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nitedrvr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
draw_tiles(bitmap, cliprect);
|
||||
draw_roadway(bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user