New games added or promoted from NOT_WORKING status

---------------------------------------------------
Turret Tower [Philip Bennett, smf]
This commit is contained in:
smf- 2013-10-26 11:09:59 +00:00
parent 6feb1c98da
commit 22abd3cdb8
7 changed files with 1057 additions and 96 deletions

3
.gitattributes vendored
View File

@ -3271,6 +3271,7 @@ src/mame/audio/trackfld.c svneol=native#text/plain
src/mame/audio/trackfld.h svneol=native#text/plain
src/mame/audio/triplhnt.c svneol=native#text/plain
src/mame/audio/turbo.c svneol=native#text/plain
src/mame/audio/turrett.c svneol=native#text/plain
src/mame/audio/tx1.c svneol=native#text/plain
src/mame/audio/vicdual.c svneol=native#text/plain
src/mame/audio/videopin.c svneol=native#text/plain
@ -5212,6 +5213,7 @@ src/mame/includes/tumbleb.h svneol=native#text/plain
src/mame/includes/tumblep.h svneol=native#text/plain
src/mame/includes/tunhunt.h svneol=native#text/plain
src/mame/includes/turbo.h svneol=native#text/plain
src/mame/includes/turrett.h svneol=native#text/plain
src/mame/includes/tutankhm.h svneol=native#text/plain
src/mame/includes/twin16.h svneol=native#text/plain
src/mame/includes/twincobr.h svneol=native#text/plain
@ -6582,6 +6584,7 @@ src/mame/video/tumbleb.c svneol=native#text/plain
src/mame/video/tumblep.c svneol=native#text/plain
src/mame/video/tunhunt.c svneol=native#text/plain
src/mame/video/turbo.c svneol=native#text/plain
src/mame/video/turrett.c svneol=native#text/plain
src/mame/video/tutankhm.c svneol=native#text/plain
src/mame/video/twin16.c svneol=native#text/plain
src/mame/video/twincobr.c svneol=native#text/plain

View File

@ -60,8 +60,9 @@ protected:
UINT8 m_num_sectors;
UINT8 m_num_heads;
virtual UINT32 lba_address();
private:
UINT32 lba_address();
void set_geometry(UINT8 sectors, UINT8 heads) { m_num_sectors = sectors; m_num_heads = heads; }
void finished_read();
void finished_write();

162
src/mame/audio/turrett.c Normal file
View File

@ -0,0 +1,162 @@
/***************************************************************************
Turret Tower sound hardware
****************************************************************************/
#include "emu.h"
#include "includes/turrett.h"
//-------------------------------------------------
// turrett_device - constructor
//-------------------------------------------------
turrett_device::turrett_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TURRETT, "Turret Tower Sound", tag, owner, clock, "ttsnd", __FILE__),
device_sound_interface(mconfig, *this),
device_memory_interface(mconfig, *this),
m_space_config("ttsound", ENDIANNESS_LITTLE, 16, 28, 0, NULL)
{
}
//-------------------------------------------------
// memory_space_config - configure address space
//-------------------------------------------------
const address_space_config *turrett_device::memory_space_config(address_spacenum spacenum) const
{
return (spacenum == 0) ? &m_space_config : NULL;
}
//-------------------------------------------------
// device_start - initialize the device
//-------------------------------------------------
void turrett_device::device_start()
{
// Find our direct access
m_direct = &space().direct();
// Create the sound stream
m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100, this);
// Create the volume table
for (int i = 0; i < 0x4f; ++i)
m_volume_table[i] = 65536 * powf(2.0, (-0.375/4) * i);
// Last entry is effectively mute
m_volume_table[0x4f] = 0;
// Register state for saving
for (int ch = 0; ch < SOUND_CHANNELS; ++ch)
{
save_item(NAME(m_channels[ch].m_address), ch);
save_item(NAME(m_channels[ch].m_volume), ch);
save_item(NAME(m_channels[ch].m_playing), ch);
}
}
//-------------------------------------------------
// device_reset - reset the device
//-------------------------------------------------
void turrett_device::device_reset()
{
for (int ch = 0; ch < SOUND_CHANNELS; ++ch)
m_channels[ch].m_playing = false;
}
//-------------------------------------------------
// sound_stream_update - update sound stream
//-------------------------------------------------
void turrett_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// Silence the buffers
memset(outputs[0], 0x00, sizeof(stream_sample_t) * samples);
memset(outputs[1], 0x00, sizeof(stream_sample_t) * samples);
for (int ch = 0; ch < SOUND_CHANNELS; ++ch)
{
stream_sample_t *l = outputs[0];
stream_sample_t *r = outputs[1];
if (m_channels[ch].m_playing)
{
UINT32 &addr = m_channels[ch].m_address;
INT32 lvol = (m_channels[ch].m_volume >> 16) & 0xff;
INT32 rvol = m_channels[ch].m_volume & 0xff;
lvol = m_volume_table[lvol];
rvol = m_volume_table[rvol];
// Channels 30 and 31 expect interleaved stereo samples
UINT32 incr = (ch >= 30) ? 2 : 1;
for (int s = 0; s < samples; ++s)
{
INT16 sample = m_direct->read_raw_word(addr << 1);
if ((UINT16)sample == 0x8000)
{
m_channels[ch].m_playing = false;
break;
}
addr += incr;
*l++ += (sample * lvol) >> 17;
*r++ += (sample * rvol) >> 17;
}
}
}
}
//-------------------------------------------------
// read - host CPU read access
//-------------------------------------------------
READ32_MEMBER( turrett_device::read )
{
m_stream->update();
int ch = offset & 0x3f;
return m_channels[ch].m_playing << 31;
}
//-------------------------------------------------
// write - host CPU write access
//-------------------------------------------------
WRITE32_MEMBER( turrett_device::write )
{
m_stream->update();
int ch = offset & 0x3f;
if (offset < 0x100/4)
{
if (data == 0)
{
m_channels[ch].m_playing = false;
}
else
{
m_channels[ch].m_address = data;
m_channels[ch].m_playing = true;
}
}
else
{
m_channels[ch].m_volume = data;
}
}

View File

@ -1,139 +1,390 @@
/*
/***************************************************************************
Turret Tower by Dell Electronics
Turret Tower by Dell Electronics
PCB Info
========
Silkscreened Copyright (c) 2001 Dell Electroinics Labs, Ltd
Samsung SV2001H Hard drive stickered (c)DELL V1.XX
TOCAB0181
TURRET TOWER
IDT 79R3041-25J
XG0110P
Xilinx Spartan XCS30XL x2
PQ208AKP0105
D1164035A
4c
Xilinx XC9572
PC84AEM0109
A1172748A
10C
IDT 71124 x8
S12Y
N0048M
COMPAQ MT16LSDT1664AG-10CY5 SDRAM stick x2
.u7 AM29F040B stickered U7 (c)DELL
.u8 AM29F040B stickered U8 (c)DELL
.u12 AM29F040B stickered U12 (c)DELL
.u13 AM29F040B stickered U13 (c)DELL
.u29 stickered TTML(1) (c) DELL Unmarked chip looks like 28 PIN DIP PLD
CHDMAN info
Version 0.128
Input offset 511
Cycliders 2438
Heads 255
Sectors 63
Bytes/Sector 512
Sectors/Hunk 8
Logical size 20,053,232,640
Windows showed a 5.94 gig partion empty and a 12.74 unallocated partition
*/
driver by Phil Bennett
****************************************************************************/
#include "emu.h"
#include "cpu/mips/r3000.h"
#include "machine/ataintf.h"
#include "includes/turrett.h"
class turrett_state : public driver_device
/*************************************
*
* Definitions
*
*************************************/
#define R3041_CLOCK XTAL_25MHz
/*************************************
*
* Machine initialization
*
*************************************/
void turrett_state::machine_start()
{
public:
turrett_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{ }
// Allocate memory for the two 256kx16 banks of video RAM
m_video_ram[0] = (UINT16*)auto_alloc_array(machine(), UINT16, VRAM_BANK_WORDS);
m_video_ram[1] = (UINT16*)auto_alloc_array(machine(), UINT16, VRAM_BANK_WORDS);
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
// Register our state for saving
save_pointer(NAME(m_video_ram[0]), VRAM_BANK_WORDS);
save_pointer(NAME(m_video_ram[1]), VRAM_BANK_WORDS);
save_item(NAME(m_inputs_active));
save_item(NAME(m_last_pixel));
save_item(NAME(m_video_ctrl));
save_item(NAME(m_video_fade));
save_item(NAME(m_x_pos));
save_item(NAME(m_x_start));
save_item(NAME(m_x_mod));
save_item(NAME(m_dx));
save_item(NAME(m_y_pos));
save_item(NAME(m_scale_cnt_y));
save_item(NAME(m_scale_cnt_x));
save_item(NAME(m_skip_x));
save_item(NAME(m_skip_y));
save_item(NAME(m_scale));
save_item(NAME(m_hotspot_x));
save_item(NAME(m_hotspot_y));
save_item(NAME(m_dma_idle));
save_item(NAME(m_dma_addr));
save_item(NAME(m_ipt_val));
save_item(NAME(m_frame));
save_item(NAME(m_adc));
protected:
// devices
required_device<cpu_device> m_maincpu;
// driver_device overrides
virtual void video_start();
};
#define R3041_CLOCK 25000000
void turrett_state::video_start()
{
m_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(turrett_state::dma_complete), this));
}
UINT32 turrett_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
void turrett_state::machine_reset()
{
return 0;
m_dma_idle = true;
m_frame = 0;
m_adc = 0;
m_inputs_active = 0;
}
/*************************************
*
* Memory maps
*
*************************************/
static ADDRESS_MAP_START( cpu_map, AS_PROGRAM, 32, turrett_state )
AM_RANGE(0x00000000, 0x0007ffff) AM_RAM
AM_RANGE(0x1fc00000, 0x1fdfffff) AM_ROM AM_REGION("maincpu", 0)
AM_RANGE(0x02000010, 0x02000013) AM_RAM
AM_RANGE(0x02000040, 0x02000043) AM_RAM
AM_RANGE(0x02000050, 0x02000053) AM_RAM
AM_RANGE(0x02000060, 0x02000063) AM_RAM
AM_RANGE(0x02000070, 0x02000073) AM_RAM
AM_RANGE(0x04000100, 0x04000103) AM_RAM
AM_RANGE(0x08000000, 0x08000003) AM_RAM
AM_RANGE(0x08000004, 0x08000007) AM_RAM
AM_RANGE(0x08000008, 0x0800000b) AM_RAM
AM_RANGE(0x0800000c, 0x0800000f) AM_RAM
AM_RANGE(0x02000070, 0x02000073) AM_RAM // TODO: What are these?
AM_RANGE(0x04000000, 0x0400000f) AM_WRITE(dma_w)
AM_RANGE(0x04000100, 0x04000103) AM_READWRITE(int_r, int_w)
AM_RANGE(0x04000200, 0x040003ff) AM_DEVREADWRITE("ttsound", turrett_device, read, write)
AM_RANGE(0x08000000, 0x0800000f) AM_READWRITE(video_r, video_w)
AM_RANGE(0x08000200, 0x080003ff) AM_DEVREADWRITE16("ata", ata_interface_device, read_cs0, write_cs0, 0xffffffff)
AM_RANGE(0x1fc00000, 0x1fdfffff) AM_ROM AM_REGION("maincpu", 0)
ADDRESS_MAP_END
static ADDRESS_MAP_START( turrett_sound_map, AS_0, 16, turrett_state )
AM_RANGE(0x0000000, 0x7ffffff) AM_RAM AM_SHARE("bank_a")
AM_RANGE(0x8000000, 0xfffffff) AM_RAM AM_SHARE("bank_b")
ADDRESS_MAP_END
/*************************************
*
* Port definitions
*
*************************************/
static INPUT_PORTS_START( turrett )
PORT_START("PORT 0X")
PORT_BIT( 0x3f, 0x00, IPT_AD_STICK_Y ) PORT_MINMAX(0x20,0x1f) PORT_SENSITIVITY(60) PORT_KEYDELTA(2)
PORT_START("PORT 4X")
PORT_BIT( 0x3f, 0x00, IPT_AD_STICK_X ) PORT_MINMAX(0x20,0x1f) PORT_SENSITIVITY(60) PORT_KEYDELTA(2)
PORT_START("PORT CX")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00000100)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00000200)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BILL1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00000400)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00000800)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00001000)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00002000)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00004000)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00008000)
PORT_START("PORT DX")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00010000)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00020000)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00040000)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00080000)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00100000)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00200000)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00400000)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, turrett_state, ipt_change, (void *)0x00800000)
PORT_START("PORT EX")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Floor mat")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Door Lock") PORT_TOGGLE
PORT_START("PORT FX")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Seat Belt") PORT_TOGGLE
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Home")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Emergency Stop") PORT_TOGGLE
INPUT_PORTS_END
/*************************************
*
* I/O handling
*
*************************************/
READ_LINE_MEMBER( turrett_state::sbrc2_r )
{
return machine().primary_screen->vblank();
}
READ_LINE_MEMBER( turrett_state::sbrc3_r )
{
return m_dma_idle;
}
READ32_MEMBER( turrett_state::int_r )
{
return update_inputs() << 24;
}
WRITE32_MEMBER( turrett_state::int_w )
{
// TODO
logerror("Output write: %08x\n", data);
}
UINT32 turrett_state::update_inputs(void)
{
UINT32 val = 0;
// TODO: Prioritise?
if (m_inputs_active)
{
if (m_inputs_active & 0x00000001)
{
val = 0x00 | (ioport("PORT 0X")->read() & 0x3f);
m_inputs_active &= ~1;
}
else if (m_inputs_active & 0x00000002)
{
val = 0x40 | (ioport("PORT 4X")->read() & 0x3f);
m_inputs_active &= ~2;
}
else if (m_inputs_active & 0x0000ff00)
{
UINT32 data = ioport("PORT CX")->read();
UINT32 bits = m_inputs_active >> 8;
val = 0xc0;
for (int i = 0; i < 8; ++i)
{
if (bits & (1 << i))
{
val |= i << 1;
val |= (data >> i) & 1;
m_inputs_active &= ~(1 << (i + 8));
break;
}
}
}
else if (m_inputs_active & 0x00ff0000)
{
UINT32 data = ioport("PORT DX")->read();
UINT32 bits = m_inputs_active >> 16;
val = 0xd0;
for (int i = 0; i < 8; ++i)
{
if (bits & (1 << i))
{
val |= i << 1;
val |= (data >> i) & 1;
m_inputs_active &= ~(1 << (i + 16));
break;
}
}
}
else if (m_inputs_active & 0x01000000)
{
val = 0xe0 | ioport("PORT EX")->read();
m_inputs_active &= ~0x01000000;
}
else if (m_inputs_active & 0x02000000)
{
val = 0xf0 | ioport("PORT FX")->read();
m_inputs_active &= ~0x02000000;
}
}
// Update IRQ state
m_maincpu->set_input_line(R3000_IRQ1, m_inputs_active ? ASSERT_LINE : CLEAR_LINE);
return val;
}
INPUT_CHANGED_MEMBER( turrett_state::ipt_change )
{
int p = (FPTR)param;
if (newval != oldval)
{
// TODO: Tidy this up
if (p & (0x02000000 | 0x00000200 | 0x00000400 | 0x00001000 | 0x00002000))
{
if (newval == 0)
{
m_inputs_active |= p;
m_maincpu->set_input_line(R3000_IRQ1, ASSERT_LINE);
}
}
else
{
m_inputs_active |= p;
m_maincpu->set_input_line(R3000_IRQ1, ASSERT_LINE);
}
}
}
/*************************************
*
* Interrupts
*
*************************************/
INTERRUPT_GEN_MEMBER( turrett_state::vblank )
{
if (m_frame)
m_inputs_active |= 0x01000000;
else
m_inputs_active |= 0x02000000;
m_frame ^= 1;
m_maincpu->set_input_line(R3000_IRQ1, ASSERT_LINE);
}
INTERRUPT_GEN_MEMBER( turrett_state::adc )
{
if (m_adc)
m_inputs_active |= 0x00000001;
else
m_inputs_active |= 0x00000002;
m_adc ^= 1;
m_maincpu->set_input_line(R3000_IRQ1, ASSERT_LINE);
}
/*************************************
*
* Hard drive
*
*************************************/
/// HACK: The game expects a different LBA mapping to the standard HDD.
/// The reason for this is unknown.
#include "machine/idehd.h"
extern const device_type TURRETT_HARDDISK;
class turrett_hdd : public ide_hdd_device
{
public:
turrett_hdd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ide_hdd_device(mconfig, TURRETT_HARDDISK, "Turrett Tower HDD", tag, owner, clock, "turrett_hdd", __FILE__)
{
}
virtual UINT32 lba_address()
{
if (m_device_head & IDE_DEVICE_HEAD_L)
return (((m_device_head & IDE_DEVICE_HEAD_HS) << 24) | (m_cylinder_high << 16) | (m_cylinder_low << 8) | m_sector_number) - 63;
return ata_mass_storage_device::lba_address();
}
};
const device_type TURRETT_HARDDISK = &device_creator<turrett_hdd>;
SLOT_INTERFACE_START(turrett_devices)
SLOT_INTERFACE("hdd", TURRETT_HARDDISK)
SLOT_INTERFACE_END
/*************************************
*
* Machine driver
*
*************************************/
static MACHINE_CONFIG_START( turrett, turrett_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", R3041, R3041_CLOCK)
MCFG_R3000_ENDIANNESS(ENDIANNESS_BIG)
MCFG_R3000_BRCOND2_INPUT(READLINE(turrett_state, sbrc2_r))
MCFG_R3000_BRCOND3_INPUT(READLINE(turrett_state, sbrc3_r))
MCFG_CPU_PROGRAM_MAP(cpu_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", turrett_state, vblank)
MCFG_CPU_PERIODIC_INT_DRIVER(turrett_state, adc, 60)
MCFG_ATA_INTERFACE_ADD("ata", turrett_devices, "hdd", NULL, true)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
// TODO: Likely not correct. Refresh rate empirically determined
// to ensure in-sync streaming sound
MCFG_SCREEN_RAW_PARAMS(4000000, 512, 0, 336, 259, 0, 244)
MCFG_SCREEN_UPDATE_DRIVER(turrett_state, screen_update)
MCFG_SCREEN_SIZE(64*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0, 64*8-1, 0*8, 32*8-1)
MCFG_PALETTE_LENGTH(32768)
MCFG_PALETTE_INIT_OVERRIDE(driver_device, RRRRR_GGGGG_BBBBB)
MCFG_PALETTE_LENGTH(0x2000)
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_DEVICE_ADD("ttsound", TURRETT, R3041_CLOCK) // ?
MCFG_DEVICE_ADDRESS_MAP(AS_0, turrett_sound_map)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END
/*************************************
*
* ROM definition
*
*************************************/
ROM_START( turrett )
ROM_REGION( 0x200000, "maincpu", 0 )
ROM_LOAD32_BYTE( "turret.u13", 0x000000, 0x080000, CRC(85287007) SHA1(990b954905c66340d3e88918b2f8cc7f1b9c7cf4) )
@ -141,9 +392,16 @@ ROM_START( turrett )
ROM_LOAD32_BYTE( "turret.u8", 0x000002, 0x080000, CRC(ddff4898) SHA1(a8f859a0dcab8ec83fbfe255d58b3e644933b923) )
ROM_LOAD32_BYTE( "turret.u7", 0x000003, 0x080000, CRC(fa8b5a5a) SHA1(658e9eeadc9c70185973470565d562c76f4fcdd7) )
DISK_REGION( "disks" )
DISK_REGION( "ata:0:hdd:image" )
DISK_IMAGE( "turrett", 0, SHA1(b0c98c5876870dd8b3e37a38fe35846c9e011df4) )
ROM_END
GAME( 2001, turrett, 0, turrett, turrett, driver_device, 0, ROT0, "Dell Electronics (Namco license)", "Turret Tower", GAME_IS_SKELETON )
/*************************************
*
* Game driver
*
*************************************/
GAME( 2001, turrett, 0, turrett, turrett, driver_device, 0, ROT0, "Dell Electronics (Namco license)", "Turret Tower", 0 )

128
src/mame/includes/turrett.h Normal file
View File

@ -0,0 +1,128 @@
/***************************************************************************
Turret Tower hardware
****************************************************************************/
#include "machine/ataintf.h"
class turrett_state : public driver_device
{
public:
turrett_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ata(*this, "ata"),
m_bank_a(*this, "bank_a"),
m_bank_b(*this, "bank_b") {}
// constants
static const UINT32 X_VISIBLE = 336;
static const UINT32 Y_VISIBLE = 244;
static const UINT32 DIMM_BANK_WORDS = 128 * 1024 * 1024 / 2;
static const UINT32 DIMM_BANK_MASK = DIMM_BANK_WORDS - 1;
static const UINT32 VRAM_BANK_WORDS = 256 * 1024;
// devices
required_device<cpu_device> m_maincpu;
required_device<ata_interface_device> m_ata;
required_shared_ptr<UINT16> m_bank_a;
required_shared_ptr<UINT16> m_bank_b;
// handlers
DECLARE_WRITE32_MEMBER(dma_w);
DECLARE_READ32_MEMBER(video_r);
DECLARE_WRITE32_MEMBER(video_w);
DECLARE_READ32_MEMBER(int_r);
DECLARE_WRITE32_MEMBER(int_w);
DECLARE_READ32_MEMBER(sound_r);
DECLARE_WRITE32_MEMBER(sound_w);
INPUT_CHANGED_MEMBER(ipt_change);
DECLARE_READ_LINE_MEMBER(sbrc2_r);
DECLARE_READ_LINE_MEMBER(sbrc3_r);
TIMER_CALLBACK_MEMBER(dma_complete);
INTERRUPT_GEN_MEMBER(vblank);
INTERRUPT_GEN_MEMBER(adc);
// functions
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 write_video_ram(UINT16 data);
void update_video_addr(void);
UINT32 update_inputs(void);
// members
emu_timer *m_dma_timer;
UINT32 m_inputs_active;
UINT16 *m_video_ram[2];
UINT16 m_last_pixel;
INT32 m_video_ctrl;
UINT16 m_video_fade;
INT16 m_x_pos;
INT16 m_x_start;
INT16 m_x_mod;
INT16 m_dx;
INT16 m_y_pos;
INT16 m_scale_cnt_y;
INT16 m_scale_cnt_x;
bool m_skip_x;
bool m_skip_y;
INT16 m_scale;
INT16 m_hotspot_x;
INT16 m_hotspot_y;
bool m_dma_idle;
UINT32 m_dma_addr[2];
UINT32 m_ipt_val;
UINT8 m_frame;
UINT8 m_adc;
protected:
// driver_device overrides
virtual void machine_reset();
virtual void machine_start();
};
class turrett_device : public device_t,
public device_sound_interface,
public device_memory_interface
{
static const UINT32 SOUND_CHANNELS = 32;
public:
// construction/destruction
turrett_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ32_MEMBER(read);
DECLARE_WRITE32_MEMBER(write);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_sound_interface overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
const address_space_config m_space_config;
private:
direct_read_data *m_direct;
sound_stream *m_stream;
struct
{
UINT32 m_address;
UINT32 m_volume;
bool m_playing;
} m_channels[SOUND_CHANNELS];
INT32 m_volume_table[0x50];
};
// device type definition
const device_type TURRETT = &device_creator<turrett_device>;

View File

@ -1351,7 +1351,7 @@ $(MAMEOBJ)/namco.a: \
$(DRIVERS)/tankbatt.o $(VIDEO)/tankbatt.o \
$(DRIVERS)/tceptor.o $(VIDEO)/tceptor.o \
$(DRIVERS)/toypop.o $(VIDEO)/toypop.o \
$(DRIVERS)/turrett.o \
$(DRIVERS)/turrett.o $(AUDIO)/turrett.o $(VIDEO)/turrett.o \
$(DRIVERS)/warpwarp.o $(AUDIO)/geebee.o $(AUDIO)/warpwarp.o $(VIDEO)/warpwarp.o \
$(MACHINE)/namcoio.o \
$(MACHINE)/namco06.o \

409
src/mame/video/turrett.c Normal file
View File

@ -0,0 +1,409 @@
/*************************************************************************
Turrett Tower video hardware
*************************************************************************/
#include "emu.h"
#include "machine/idectrl.h"
#include "includes/turrett.h"
inline UINT8 clamp_5bit(INT8 val)
{
if (val < 0)
return 0;
if (val > 31)
return 31;
return val;
}
UINT32 turrett_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int page = (m_video_ctrl & 1) ^ 1;
const UINT16 *vram = m_video_ram[page];
INT8 fade_b = m_video_fade & 0x1f;
INT8 fade_g = (m_video_fade >> 5) & 0x1f;
INT8 fade_r = (m_video_fade >> 10) & 0x1f;
if (m_video_fade & 0x8000)
{
fade_b = -fade_b;
fade_g = -fade_g;
fade_r = -fade_r;
}
for (int y = cliprect.min_y; y <= cliprect.max_y; ++y)
{
const UINT16 *src = &vram[y * X_VISIBLE + cliprect.min_x];
UINT16 *dest = &bitmap.pix16(y, cliprect.min_x);
if (m_video_fade != 0)
{
for (int x = cliprect.min_x; x <= cliprect.max_x; ++x)
{
UINT16 srcpix = *src++;
UINT8 src_b = srcpix & 0x1f;
UINT8 src_g = (srcpix >> 5) & 0x1f;
UINT8 src_r = (srcpix >> 10) & 0x1f;
UINT8 dst_b = clamp_5bit(src_b + fade_b);
UINT8 dst_g = clamp_5bit(src_g + fade_g);
UINT8 dst_r = clamp_5bit(src_r + fade_r);
*dest++ = (dst_r << 10) | (dst_g << 5) | dst_b;
}
}
else
{
for (int x = cliprect.min_x; x <= cliprect.max_x; ++x)
{
*dest++ = *src++ & 0x7fff;
}
}
}
return 0;
}
UINT32 turrett_state::write_video_ram(UINT16 data)
{
UINT32 clocks = 1;
if (!m_skip_x && !m_skip_y)
{
// Handle hot spot test
if (m_x_pos == m_hotspot_x
&& m_y_pos == (m_hotspot_y & 0xfff))
{
m_hotspot_y |= 0x8000;
}
if (m_x_pos >= 0 && m_x_pos < X_VISIBLE
&& m_y_pos >= 0 && m_y_pos < Y_VISIBLE)
{
int address = m_y_pos * X_VISIBLE + m_x_pos;
UINT16 *vramptr = &m_video_ram[m_video_ctrl & 1][address];
UINT16 srcpix = data;
UINT16 dstpix = data;
// Blending enabled?
if (data & 0x8000)
{
dstpix = *vramptr;
UINT8 src_b = srcpix & 0x1f;
UINT8 src_g = (srcpix >> 5) & 0x1f;
UINT8 src_r = (srcpix >> 10) & 0x1f;
UINT8 dst_b = dstpix & 0x1f;
UINT8 dst_g = (dstpix >> 5) & 0x1f;
UINT8 dst_r = (dstpix >> 10) & 0x1f;
// Additive
if (m_video_ctrl & 2)
{
dst_b = clamp_5bit(src_b + dst_b);
dst_g = clamp_5bit(src_g + dst_g);
dst_r = clamp_5bit(src_r + dst_r);
}
else
{
// R always seems to be 0 for blended pixels
if ((src_g & 1) && (src_b & 1))
{
dst_b = clamp_5bit(dst_b - src_b);
dst_g = clamp_5bit(dst_g - src_g);
dst_r = clamp_5bit(dst_r - src_r);
}
else
{
// 75% source, 25% destination?
dst_b = (src_b - (src_b >> 2)) + (dst_b >> 2);
dst_g = (src_g - (src_g >> 2)) + (dst_g >> 2);
dst_r = (src_r - (src_r >> 2)) + (dst_r >> 2);
}
}
clocks += 2;
*vramptr = (dst_r << 10) | (dst_g << 5) | dst_b;
}
else
{
clocks += 2;
*vramptr = srcpix;
}
}
}
update_video_addr();
return clocks;
}
void turrett_state::update_video_addr(void)
{
// Handle auto-increment
if (m_dx == m_x_mod)
{
m_dx = 0;
m_scale_cnt_y += m_scale;
if (m_scale_cnt_y & 0x800)
{
m_skip_y = false;
m_scale_cnt_y &= 0x7ff;
--m_y_pos;
m_x_pos = m_x_start;
}
else
{
m_skip_y = true;
}
}
else
{
++m_dx;
m_scale_cnt_x += m_scale;
if (m_scale_cnt_x & 0x800)
{
m_scale_cnt_x &= 0x7ff;
m_skip_x = false;
++m_x_pos;
}
else
{
m_skip_x = true;
}
}
}
READ32_MEMBER( turrett_state::video_r )
{
UINT32 ret = 0;
if (offset == 3 && mem_mask == 0x0000ffff)
{
// Collision detection flag
ret = m_hotspot_y & 0x8000;
}
else
{
fatalerror("Unhandled video read (%x %x)!", offset, mem_mask);
}
return ret;
}
WRITE32_MEMBER( turrett_state::video_w )
{
switch (offset)
{
case 0:
{
if (mem_mask == 0xffff0000)
{
data >>= 16;
// TODO: Merge with DMA code?
if ((data & 0xc400) == 0xc400)
{
// RLE word
int count = (data & 0x3ff) + 1;
// TODO: Cycle stalling
while (count--)
write_video_ram(m_last_pixel);
}
else
{
write_video_ram(data);
// Store current pixel
m_last_pixel = data;
}
}
else
{
m_video_ctrl = data & 3;
}
break;
}
case 1:
{
m_x_mod = data & 0xffff;
m_scale = 0x800 - (data >> 16);
break;
}
case 2:
{
m_y_pos = data & 0xffff;
m_x_pos = data >> 16;
// Seems the logical place to set these
m_x_start = m_x_pos;
m_skip_x = false;
m_skip_y = false;
m_dx = 0;
break;
}
case 3:
{
if (mem_mask == 0xffff0000)
{
m_video_fade = data >> 16;
}
else if (mem_mask == 0x0000ffff)
{
if (data & 0x4000)
m_hotspot_y = data;
else
m_hotspot_x = data;
}
else
{
fatalerror("Unhandled");
}
break;
}
default:
fatalerror("Unhandled video write: %x %x\n", offset, data);
}
}
TIMER_CALLBACK_MEMBER( turrett_state::dma_complete )
{
m_dma_idle = true;
}
WRITE32_MEMBER( turrett_state::dma_w )
{
int bank = ((offset & 2) >> 1) ^ 1;
if ((offset & 1) == 0)
{
m_dma_addr[bank] = data;
}
else
{
UINT32 clocks = 0;
UINT32 words = data & 0x0fffffff;
// IDE to DRAM
if (data & 0x10000000)
{
UINT32 addr = m_dma_addr[bank];
UINT16 *ram = bank ? m_bank_b : m_bank_a;
while (words--)
{
ram[addr & DIMM_BANK_MASK] = m_ata->read_cs0(space, 0, 0xffff);
++addr;
}
clocks = 500; // TODO: May be too high
m_dma_addr[bank] = addr;
}
// IDE to video RAM
else if (data & 0x40000000)
{
while (words--)
{
UINT16 data = m_ata->read_cs0(space, 0, 0xffff);
// TODO: Verify if this is correct
if ((data & 0xc400) == 0xc400)
{
fatalerror("IDE RLE detected");
// RLE word
int count = (data & 0x3ff) + 1;
while (count--)
write_video_ram(m_last_pixel);
}
else
{
write_video_ram(data);
// Store current pixel
m_last_pixel = data;
}
}
clocks = 500; // TODO
}
// RAM to video RAM
else if (data & 0x80000000)
{
UINT32 addr = m_dma_addr[bank];
UINT16 *ram = bank ? m_bank_b : m_bank_a;
//bool first = true; // Does it matter?
while (words--)
{
UINT16 val = ram[addr++];
//++clocks;
switch (val & 0xc400)
{
// Transparent run
case 0x8400:
{
int run = (((val & 0x3800) >> 1) | (val & 0x03ff)) + 1;
while (run--)
{
update_video_addr();
//++clocks;
}
break;
}
case 0xc400:
{
int run = (((val & 0x3800) >> 1) | (val & 0x03ff)) + 1;
while (run--)
clocks += write_video_ram(m_last_pixel);
break;
}
default:
{
m_last_pixel = val;
clocks += write_video_ram(val);
break;
}
}
//first = false;
}
// clocks =1;///= 2;
}
else
{
popmessage("Unhandled DMA case: %.8x, contact MAMEdev!\n", data);
}
// Set the DMA completion timer
m_dma_idle = false;
m_dma_timer->adjust(attotime::from_nsec(10) * clocks, 0);
}
}