Namco System 21 and other related refactors (#4013)

* namco checkpoint (including cam900 submission)

* move code into device (nw)

* start splitting DSP support code into devices (nw)

* fix crash (nw)

* prepare for further splitting (nw)

* move code for C67 based DSP PCB into it's own device (nw)

* survive F3 resets without crashing or breaking the 3D (nw)

* less magic numbers (nw)

* optional -> required
don't use fake bootstrap on older type, suspend CPU instead

* restore CPU yield hack for solvalou (nw)

* (nw)

* give galaxian3 some DSPs (nw)

* address hap's concern with a different workaround since MAME is awkward (nw)

* split namco21 driver into 3 drivers as the different configurations really are entirely different boardsets with similar components, not a real 'system'
emulated entire PCB set for driveyes ( http://www.tvspels-nostalgi.com/Bilder/PCB/Namco/driverseye_cage_inside.jpg ) although how the PCBs communicate is not yet known (C139 maybe, which might also be an MCU)

* remove empty file (nw)

* actually thinking about it, this is cleaner (nw)

* mark cybsledj as World instead, there's nothing about this set other than the CY1 code to indicate that it's a Japanese set, and I don't think the Namco codes represent region, just release order.

* newline (nw)

* newline (nw)
This commit is contained in:
David Haywood 2018-09-21 20:01:12 +01:00 committed by ajrhacker
parent 14a94c1c90
commit ccded2bf8b
21 changed files with 4319 additions and 3009 deletions

View File

@ -2784,8 +2784,16 @@ files {
MAME_DIR .. "src/mame/video/namcos2_roz.cpp",
MAME_DIR .. "src/mame/video/namcos2_roz.h",
MAME_DIR .. "src/mame/drivers/namcos21.cpp",
MAME_DIR .. "src/mame/includes/namcos21.h",
MAME_DIR .. "src/mame/video/namcos21.cpp",
MAME_DIR .. "src/mame/drivers/namcos21_de.cpp",
MAME_DIR .. "src/mame/drivers/namcos21_c67.cpp",
MAME_DIR .. "src/mame/video/namcos21_3d.cpp",
MAME_DIR .. "src/mame/video/namcos21_3d.h",
MAME_DIR .. "src/mame/machine/namcos21_dsp.cpp",
MAME_DIR .. "src/mame/machine/namcos21_dsp.h",
MAME_DIR .. "src/mame/machine/namcos21_dsp_c67.cpp",
MAME_DIR .. "src/mame/machine/namcos21_dsp_c67.h",
MAME_DIR .. "src/mame/machine/namco_c67.cpp",
MAME_DIR .. "src/mame/machine/namco_c67.h",
MAME_DIR .. "src/mame/drivers/namcos22.cpp",
MAME_DIR .. "src/mame/includes/namcos22.h",
MAME_DIR .. "src/mame/video/namcos22.cpp",

View File

@ -184,6 +184,14 @@ Table 3-2. TMS32025/26 Memory Blocks
#define IND m_AR[ARP] /* address used in indirect memory access operations */
/*
Processor can be operated in one of two modes based on Pin 1 (MP/MC)
MP/MC = 1 (Microprocessor Mode)
MP/MC = 0 (Microcomputer Mode)
in 'Microcomputer' mode the 4K Word internal ROM is used (TMS320C25)
use set_mp_mc in the device configuration to set the pin for internal ROM mode
*/
DEFINE_DEVICE_TYPE(TMS32025, tms32025_device, "tms32025", "Texas Instruments TMS32025")
DEFINE_DEVICE_TYPE(TMS32026, tms32026_device, "tms32026", "Texas Instruments TMS32026")
@ -214,18 +222,29 @@ void tms32025_device::tms32026_data(address_map &map)
map(0x0600, 0x07ff).ram().share("b3");
}
tms32025_device::tms32025_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: tms32025_device(mconfig, TMS32025, tag, owner, clock, address_map_constructor(FUNC(tms32025_device::tms32025_data), this))
#if 0
// Instead of using the map here we install the ROM depending on the MP/MC pin set in the config
void tms32025_device::tms32025_program(address_map &map)
{
m_fixed_STR1 = 0x0180;
map(0x0000, 0x0fff).rom().region("internal", 0); // 4K Words Internal ROM / EPROM
}
#endif
ROM_START( tms32025 )
ROM_REGION16_BE( 0x2000, "internal", ROMREGION_ERASE00 )
// use blank data if internal ROM is not programmed
ROM_END
const tiny_rom_entry *tms32025_device::device_rom_region() const
{
return ROM_NAME(tms32025);
}
tms32025_device::tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map)
tms32025_device::tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor prgmap, address_map_constructor datamap)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_BIG, 16, 16, -1)
, m_data_config("data", ENDIANNESS_BIG, 16, 16, -1, map)
, m_program_config("program", ENDIANNESS_BIG, 16, 16, -1, prgmap)
, m_data_config("data", ENDIANNESS_BIG, 16, 16, -1, datamap)
, m_io_config("io", ENDIANNESS_BIG, 16, 16, -1)
, m_b0(*this, "b0")
, m_b1(*this, "b1")
@ -237,12 +256,24 @@ tms32025_device::tms32025_device(const machine_config &mconfig, device_type type
, m_xf_out(*this)
, m_dr_in(*this)
, m_dx_out(*this)
, m_mp_mc(true)
{
}
tms32025_device::tms32025_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: tms32025_device(mconfig, TMS32025, tag, owner, clock, address_map_constructor(), address_map_constructor(FUNC(tms32025_device::tms32025_data), this))
{
m_fixed_STR1 = 0x0180;
}
tms32025_device::tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: tms32025_device(mconfig, type, tag, owner, clock, address_map_constructor(), address_map_constructor(FUNC(tms32025_device::tms32025_data), this))
{
m_fixed_STR1 = 0x0180;
}
tms32026_device::tms32026_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: tms32025_device(mconfig, TMS32026, tag, owner, clock, address_map_constructor(FUNC(tms32026_device::tms32026_data), this))
: tms32025_device(mconfig, TMS32026, tag, owner, clock, address_map_constructor(), address_map_constructor(FUNC(tms32026_device::tms32026_data), this))
{
m_fixed_STR1 = 0x0100;
}
@ -1625,6 +1656,11 @@ void tms32025_device::device_start()
m_data = &space(AS_DATA);
m_io = &space(AS_IO);
if (!m_mp_mc) // if pin 1 is 0 then we're using internal ROM
{
m_program->install_rom(0x0000, 0x0fff, memregion("internal")->base());
}
m_bio_in.resolve_safe(0xffff);
m_hold_in.resolve_safe(0xffff);
m_hold_ack_out.resolve_safe();

View File

@ -63,6 +63,7 @@ class tms32025_device : public cpu_device
public:
// construction/destruction
tms32025_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
auto bio_in_cb() { return m_bio_in.bind(); }
@ -72,6 +73,8 @@ public:
auto dr_in_cb() { return m_dr_in.bind(); }
auto dx_out_cb() { return m_dx_out.bind(); }
void set_mp_mc(bool state) { m_mp_mc = state; }
DECLARE_READ16_MEMBER( drr_r);
DECLARE_WRITE16_MEMBER(drr_w);
DECLARE_READ16_MEMBER( dxr_r);
@ -85,10 +88,11 @@ public:
DECLARE_READ16_MEMBER( greg_r);
DECLARE_WRITE16_MEMBER(greg_w);
//void tms32025_program(address_map &map);
void tms32025_data(address_map &map);
void tms32026_data(address_map &map);
protected:
tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map);
tms32025_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor prgmap, address_map_constructor datamap);
// device-level overrides
virtual void device_start() override;
@ -110,6 +114,8 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
virtual const tiny_rom_entry *device_rom_region() const override;
void common_reset();
address_space_config m_program_config;
@ -354,6 +360,8 @@ protected:
void zals();
inline int process_IRQs();
inline void process_timer(int clocks);
bool m_mp_mc;
};
@ -370,7 +378,6 @@ protected:
virtual void conf() override;
};
DECLARE_DEVICE_TYPE(TMS32025, tms32025_device)
DECLARE_DEVICE_TYPE(TMS32026, tms32026_device)

View File

@ -117,13 +117,22 @@ WRITE8_MEMBER(palette_device::write8_ext)
update_for_write(offset, 1);
}
WRITE16_MEMBER(palette_device::write16_ext)
{
m_paletteram_ext.write16(offset, data, mem_mask);
update_for_write(offset * 2, 2);
}
READ8_MEMBER(palette_device::read8_ext)
{
return m_paletteram_ext.read8(offset);
}
READ16_MEMBER(palette_device::read16_ext)
{
return m_paletteram_ext.read16(offset);
}
//-------------------------------------------------
// write_indirect - write a byte to the base

View File

@ -399,11 +399,13 @@ public:
// generic read/write handlers
DECLARE_READ8_MEMBER(read8);
DECLARE_READ8_MEMBER(read8_ext);
DECLARE_WRITE8_MEMBER(write8);
DECLARE_WRITE8_MEMBER(write8_ext);
DECLARE_WRITE8_MEMBER(write_indirect);
DECLARE_WRITE8_MEMBER(write_indirect_ext);
DECLARE_READ16_MEMBER(read16);
DECLARE_READ16_MEMBER(read16_ext);
DECLARE_WRITE16_MEMBER(write16);
DECLARE_WRITE16_MEMBER(write16_ext);
DECLARE_READ32_MEMBER(read32);

View File

@ -45,8 +45,8 @@
| | | |
| | | |------- Slave 68020
| | | |-------- 1x master DSP, 4x slave DSPs, Polygon, 2D Sprite ------> V-MIX board -----> SCREEN
| | | |-------- ........ more video boards ......... |
| | | |-------- ........ more video boards ......... LD Player
| | | |-------- ........ more video boards ......... (max 2 per slave?) |
| | | LD Player
| | |
| | |------- ........ more slave 68020s .........
| |
@ -135,6 +135,9 @@ better notes (complete chip lists) for each board still needed
#include "rendlay.h"
#include "speaker.h"
#include "video/namco_c355spr.h"
#include "machine/namcos21_dsp_c67.h"
#include "video/namcos21_3d.h"
#define NAMCOS21_NUM_COLORS 0x8000
@ -143,39 +146,45 @@ class gal3_state : public driver_device
public:
gal3_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_c355spr(*this, "c355spr"),
m_palette(*this, "palette"),
m_c355spr(*this, "c355spr_%u", 1U),
m_palette(*this, "palette_%u", 1U),
m_rso_shared_ram(*this, "rso_shared_ram"),
m_generic_paletteram_16(*this, "paletteram"),
m_c140_16a(*this, "c140_16a"),
m_c140_16g(*this, "c140_16g")
m_c140_16g(*this, "c140_16g"),
m_namcos21_3d(*this, "namcos21_3d_%u", 1U),
m_namcos21_dsp_c67(*this, "namcos21dsp_c67_%u", 1U)
{ }
void gal3(machine_config &config);
private:
required_device<namco_c355spr_device> m_c355spr;
required_device<palette_device> m_palette;
uint16_t m_namcos21_video_enable;
required_device_array<namco_c355spr_device, 2> m_c355spr;
required_device_array<palette_device, 2> m_palette;
uint16_t m_video_enable[2];
required_shared_ptr<uint16_t> m_rso_shared_ram;
optional_shared_ptr<uint16_t> m_generic_paletteram_16;
required_device<c140_device> m_c140_16a;
required_device<c140_device> m_c140_16g;
required_device_array<namcos21_3d_device, 2> m_namcos21_3d;
required_device_array<namcos21_dsp_c67_device, 2> m_namcos21_dsp_c67;
uint32_t m_led_mst;
uint32_t m_led_slv;
DECLARE_READ32_MEMBER(led_mst_r);
DECLARE_WRITE32_MEMBER(led_mst_w);
DECLARE_READ32_MEMBER(led_slv_r);
DECLARE_WRITE32_MEMBER(led_slv_w);
DECLARE_READ32_MEMBER(paletteram32_r);
DECLARE_WRITE32_MEMBER(paletteram32_w);
DECLARE_READ32_MEMBER(namcos21_video_enable_r);
DECLARE_WRITE32_MEMBER(namcos21_video_enable_w);
DECLARE_READ32_MEMBER(rso_r);
DECLARE_WRITE32_MEMBER(rso_w);
DECLARE_VIDEO_START(gal3);
uint32_t screen_update_gal3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void update_palette( );
template<int Screen> DECLARE_READ16_MEMBER(video_enable_r);
template<int Screen> DECLARE_WRITE16_MEMBER(video_enable_w);
DECLARE_READ16_MEMBER(rso_r);
DECLARE_WRITE16_MEMBER(rso_w);
virtual void machine_start() override;
virtual void video_start() override;
// using ind16 for now because namco_c355spr_device::zdrawgfxzoom does not support rgb32, will probably need to be improved for LD use
uint32_t screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void cpu_mst_map(address_map &map);
void cpu_slv_map(address_map &map);
void psn_b1_cpu_map(address_map &map);
@ -184,57 +193,37 @@ private:
};
VIDEO_START_MEMBER(gal3_state,gal3)
void gal3_state::machine_start()
{
m_generic_paletteram_16.allocate(0x10000);
save_item(NAME(m_led_mst));
save_item(NAME(m_led_slv));
}
/* FIXME: this code has simply been copypasted from namcos21.c
(which has subsequently been rewritten to use generic MAME
palette handling) with a 32-bit CPU it's rather unlikely
that the palette RAM is actually laid out this way */
void gal3_state::update_palette( )
void gal3_state::video_start()
{
int i;
int16_t data1,data2;
int r,g,b;
save_item(NAME(m_video_enable));
}
for( i=0; i<NAMCOS21_NUM_COLORS; i++ )
{
data1 = m_generic_paletteram_16[0x00000/2+i];
data2 = m_generic_paletteram_16[0x10000/2+i];
r = data1>>8;
g = data1&0xff;
b = data2&0xff;
m_palette->set_pen_color( i, rgb_t(r,g,b) );
}
} /* update_palette */
uint32_t gal3_state::screen_update_gal3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t gal3_state::screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i;
char mst[18], slv[18];
static int pivot = 15;
int pri;
update_palette();
if( machine().input().code_pressed_once(KEYCODE_H)&&(pivot<15) ) pivot+=1;
if( machine().input().code_pressed_once(KEYCODE_J)&&(pivot>0) ) pivot-=1;
for( pri=0; pri<pivot; pri++ )
{
m_c355spr->draw(screen, bitmap, cliprect, pri);
m_c355spr[0]->draw(screen, bitmap, cliprect, pri);
}
/* CopyVisiblePolyFrameBuffer( bitmap, cliprect,0,0x7fbf );
for( pri=pivot; pri<15; pri++ )
{
m_c355spr->draw(screen, bitmap, cliprect, pri);
m_c355spr[0]->draw(screen, bitmap, cliprect, pri);
}*/
// CPU Diag LEDs
@ -265,6 +254,29 @@ uint32_t gal3_state::screen_update_gal3(screen_device &screen, bitmap_rgb32 &bit
return 0;
}
uint32_t gal3_state::screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
static int pivot = 15;
int pri;
if( machine().input().code_pressed_once(KEYCODE_H)&&(pivot<15) ) pivot+=1;
if( machine().input().code_pressed_once(KEYCODE_J)&&(pivot>0) ) pivot-=1;
for( pri=0; pri<pivot; pri++ )
{
m_c355spr[1]->draw(screen, bitmap, cliprect, pri);
}
/* CopyVisiblePolyFrameBuffer( bitmap, cliprect,0,0x7fbf );
for( pri=pivot; pri<15; pri++ )
{
m_c355spr[1]->draw(screen, bitmap, cliprect, pri);
}*/
return 0;
}
/***************************************************************************************/
@ -288,55 +300,30 @@ WRITE32_MEMBER(gal3_state::led_slv_w)
COMBINE_DATA(&m_led_slv);
}
/* palette memory handlers */
READ32_MEMBER(gal3_state::paletteram32_r)
template<int Screen>
READ16_MEMBER(gal3_state::video_enable_r)
{
offset *= 2;
return (m_generic_paletteram_16[offset]<<16)|m_generic_paletteram_16[offset+1];
return m_video_enable[Screen];
}
WRITE32_MEMBER(gal3_state::paletteram32_w)
template<int Screen>
WRITE16_MEMBER(gal3_state::video_enable_w)
{
uint32_t v;
offset *= 2;
v = (m_generic_paletteram_16[offset]<<16)|m_generic_paletteram_16[offset+1];
COMBINE_DATA( &v );
m_generic_paletteram_16[offset+0] = v>>16;
m_generic_paletteram_16[offset+1] = v&0xffff;
COMBINE_DATA(&m_video_enable[Screen]); // 0xff53, instead of 0x40 in namcos21
}
READ32_MEMBER(gal3_state::namcos21_video_enable_r)
{
return m_namcos21_video_enable<<16;
}
WRITE32_MEMBER(gal3_state::namcos21_video_enable_w)
{
uint32_t v;
v = m_namcos21_video_enable<<16;
COMBINE_DATA( &v ); // 0xff53, instead of 0x40 in namcos21
m_namcos21_video_enable = v>>16;
}
READ32_MEMBER(gal3_state::rso_r)
READ16_MEMBER(gal3_state::rso_r)
{
/*store $5555 @$0046, and readback @$0000
read @$0144 and store at A6_21e & A4_5c
Check @$009a==1 to start DEMO
HACK*/
offset *= 2;
return (m_rso_shared_ram[offset]<<16)|m_rso_shared_ram[offset+1];
return m_rso_shared_ram[offset];
}
WRITE32_MEMBER(gal3_state::rso_w)
WRITE16_MEMBER(gal3_state::rso_w)
{
uint32_t v;
offset *= 2;
v = (m_rso_shared_ram[offset]<<16)|m_rso_shared_ram[offset+1];
COMBINE_DATA( &v );
m_rso_shared_ram[offset+0] = v>>16;
m_rso_shared_ram[offset+1] = v&0xffff;
COMBINE_DATA(&m_rso_shared_ram[offset]);
}
@ -371,21 +358,31 @@ void gal3_state::cpu_slv_map(address_map &map)
map(0x60010000, 0x60017fff).ram().share("share1");
map(0x80000000, 0x8007ffff).ram(); //512K Local RAM
map(0xf1200000, 0xf120ffff).ram(); //DSP RAM
/// AM_RANGE(0xf1400000, 0xf1400003) AM_WRITE(pointram_control_w)
/// AM_RANGE(0xf1440000, 0xf1440003) AM_READWRITE(pointram_data_r,pointram_data_w)
/// AM_RANGE(0x440002, 0x47ffff) AM_WRITENOP /* (frame buffer?) */
/// AM_RANGE(0xf1480000, 0xf14807ff) AM_READWRITE(namcos21_depthcue_r,namcos21_depthcue_w)
map(0xf1700000, 0xf170ffff).rw(m_c355spr, FUNC(namco_c355spr_device::spriteram_r), FUNC(namco_c355spr_device::spriteram_w)).share("objram");
map(0xf1720000, 0xf1720007).rw(m_c355spr, FUNC(namco_c355spr_device::position_r), FUNC(namco_c355spr_device::position_w));
map(0xf1740000, 0xf175ffff).rw(FUNC(gal3_state::paletteram32_r), FUNC(gal3_state::paletteram32_w));
map(0xf1760000, 0xf1760003).rw(FUNC(gal3_state::namcos21_video_enable_r), FUNC(gal3_state::namcos21_video_enable_w));
// Video chain 1
map(0xf1200000, 0xf120ffff).rw(m_namcos21_dsp_c67[0], FUNC(namcos21_dsp_c67_device::dspram16_r), FUNC(namcos21_dsp_c67_device::dspram16_hack_w));
map(0xf1400000, 0xf1400003).w(m_namcos21_dsp_c67[0], FUNC(namcos21_dsp_c67_device::pointram_control_w));
map(0xf1440000, 0xf1440003).rw(m_namcos21_dsp_c67[0], FUNC(namcos21_dsp_c67_device::pointram_data_r), FUNC(namcos21_dsp_c67_device::pointram_data_w));
map(0xf1440004, 0xf147ffff).nopw();
map(0xf1480000, 0xf14807ff).rw(m_namcos21_dsp_c67[0], FUNC(namcos21_dsp_c67_device::namcos21_depthcue_r), FUNC(namcos21_dsp_c67_device::namcos21_depthcue_w));
map(0xf1700000, 0xf170ffff).rw(m_c355spr[0], FUNC(namco_c355spr_device::spriteram_r), FUNC(namco_c355spr_device::spriteram_w)).share("objram_1");
map(0xf1720000, 0xf1720007).rw(m_c355spr[0], FUNC(namco_c355spr_device::position_r), FUNC(namco_c355spr_device::position_w));
map(0xf1740000, 0xf174ffff).rw(m_palette[0], FUNC(palette_device::read16), FUNC(palette_device::write16)).share("palette_1");
map(0xf1750000, 0xf175ffff).rw(m_palette[0], FUNC(palette_device::read16_ext), FUNC(palette_device::write16_ext)).share("palette_1_ext");
map(0xf1760000, 0xf1760001).rw(FUNC(gal3_state::video_enable_r<0>), FUNC(gal3_state::video_enable_w<0>));
map(0xf2200000, 0xf220ffff).ram();
map(0xf2700000, 0xf270ffff).ram(); //AM_READWRITE16(spriteram_r,spriteram_w,0xffffffff) AM_SHARE("objram")
map(0xf2720000, 0xf2720007).ram(); //AM_READWRITE16(position_r,position_w,0xffffffff)
map(0xf2740000, 0xf275ffff).ram(); //AM_READWRITE(paletteram16_r,paletteram16_w) AM_SHARE("paletteram")
map(0xf2760000, 0xf2760003).ram(); //AM_READWRITE(namcos21_video_enable_r,namcos21_video_enable_w)
// Video chain 2
map(0xf2200000, 0xf220ffff).rw(m_namcos21_dsp_c67[1], FUNC(namcos21_dsp_c67_device::dspram16_r), FUNC(namcos21_dsp_c67_device::dspram16_hack_w));
map(0xf2400000, 0xf2400003).w(m_namcos21_dsp_c67[1], FUNC(namcos21_dsp_c67_device::pointram_control_w));
map(0xf2440000, 0xf2440003).rw(m_namcos21_dsp_c67[1], FUNC(namcos21_dsp_c67_device::pointram_data_r), FUNC(namcos21_dsp_c67_device::pointram_data_w));
map(0xf2440004, 0xf247ffff).nopw();
map(0xf2480000, 0xf24807ff).rw(m_namcos21_dsp_c67[1], FUNC(namcos21_dsp_c67_device::namcos21_depthcue_r), FUNC(namcos21_dsp_c67_device::namcos21_depthcue_w));
map(0xf2700000, 0xf270ffff).rw(m_c355spr[1], FUNC(namco_c355spr_device::spriteram_r), FUNC(namco_c355spr_device::spriteram_w)).share("objram_2");
map(0xf2720000, 0xf2720007).rw(m_c355spr[1], FUNC(namco_c355spr_device::position_r), FUNC(namco_c355spr_device::position_w));
map(0xf2740000, 0xf274ffff).rw(m_palette[1], FUNC(palette_device::read16), FUNC(palette_device::write16)).share("palette_2");
map(0xf2750000, 0xf275ffff).rw(m_palette[1], FUNC(palette_device::read16_ext), FUNC(palette_device::write16_ext)).share("palette_2_ext");
map(0xf2760000, 0xf2760001).rw(FUNC(gal3_state::video_enable_r<1>), FUNC(gal3_state::video_enable_w<1>));
}
void gal3_state::rs_cpu_map(address_map &map)
@ -603,10 +600,14 @@ static const gfx_layout tile_layout =
8*64 /* sprite offset */
};
static GFXDECODE_START( gfx_namcos21 )
static GFXDECODE_START( gfx_gal3_l )
GFXDECODE_ENTRY( "obj_board1", 0x000000, tile_layout, 0x000, 0x20 )
GFXDECODE_END
static GFXDECODE_START( gfx_gal3_r )
GFXDECODE_ENTRY( "obj_board2", 0x000000, tile_layout, 0x000, 0x20 )
GFXDECODE_END
MACHINE_CONFIG_START(gal3_state::gal3)
MCFG_DEVICE_ADD("maincpu", M68020, 49152000/2)
MCFG_DEVICE_PROGRAM_MAP(cpu_mst_map)
@ -636,32 +637,68 @@ MACHINE_CONFIG_START(gal3_state::gal3)
NVRAM(config, "nvmem", nvram_device::DEFAULT_ALL_0);
// video chain 1
MCFG_SCREEN_ADD("lscreen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(64*8, 64*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 512-1, 0*8, 512-1)
MCFG_SCREEN_UPDATE_DRIVER(gal3_state, screen_update_gal3)
MCFG_SCREEN_UPDATE_DRIVER(gal3_state, screen_update_left)
MCFG_SCREEN_PALETTE("palette_1")
MCFG_DEVICE_ADD("gfxdecode_1", GFXDECODE, "palette_1", gfx_gal3_l)
MCFG_PALETTE_ADD("palette_1", NAMCOS21_NUM_COLORS)
MCFG_PALETTE_MEMBITS(16)
MCFG_PALETTE_FORMAT(XBRG)
NAMCO_C355SPR(config, m_c355spr[0], 0);
m_c355spr[0]->set_palette_tag("palette_1");
m_c355spr[0]->set_gfxdecode_tag("gfxdecode_1");
m_c355spr[0]->set_is_namcofl(false);
m_c355spr[0]->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate());
m_c355spr[0]->set_palxor(0xf); // reverse mapping
m_c355spr[0]->set_gfxregion(0);
NAMCOS21_3D(config, m_namcos21_3d[0], 0);
m_namcos21_3d[0]->set_zz_shift_mult(11, 0x200);
m_namcos21_3d[0]->set_depth_reverse(false);
m_namcos21_3d[0]->set_framebuffer_size(496,480);
NAMCOS21_DSP_C67(config, m_namcos21_dsp_c67[0], 0);
m_namcos21_dsp_c67[0]->set_renderer_tag("namcos21_3d_1");
// video chain 2
MCFG_SCREEN_ADD("rscreen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(64*8, 64*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 512-1, 0*8, 512-1)
MCFG_SCREEN_UPDATE_DRIVER(gal3_state, screen_update_gal3)
MCFG_SCREEN_UPDATE_DRIVER(gal3_state, screen_update_right)
MCFG_SCREEN_PALETTE("palette_2")
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_namcos21)
MCFG_PALETTE_ADD("palette", NAMCOS21_NUM_COLORS)
MCFG_DEVICE_ADD("gfxdecode_2", GFXDECODE, "palette_2", gfx_gal3_r)
MCFG_PALETTE_ADD("palette_2", NAMCOS21_NUM_COLORS)
MCFG_PALETTE_MEMBITS(16)
MCFG_PALETTE_FORMAT(XBRG)
NAMCO_C355SPR(config, m_c355spr, 0);
m_c355spr->set_palette_tag("palette");
m_c355spr->set_gfxdecode_tag("gfxdecode");
m_c355spr->set_is_namcofl(false);
m_c355spr->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate());
m_c355spr->set_palxor(0xf); // reverse mapping
m_c355spr->set_gfxregion(0);
NAMCO_C355SPR(config, m_c355spr[1], 0);
m_c355spr[1]->set_palette_tag("palette_2");
m_c355spr[1]->set_gfxdecode_tag("gfxdecode_2");
m_c355spr[1]->set_is_namcofl(false);
m_c355spr[1]->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate());
m_c355spr[1]->set_palxor(0xf); // reverse mapping
m_c355spr[1]->set_gfxregion(0);
NAMCOS21_3D(config, m_namcos21_3d[1], 0);
m_namcos21_3d[1]->set_zz_shift_mult(11, 0x200);
m_namcos21_3d[1]->set_depth_reverse(false);
m_namcos21_3d[1]->set_framebuffer_size(496,480);
NAMCOS21_DSP_C67(config, m_namcos21_dsp_c67[1], 0);
m_namcos21_dsp_c67[1]->set_renderer_tag("namcos21_3d_2");
MCFG_VIDEO_START_OVERRIDE(gal3_state,gal3)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@ -816,17 +853,15 @@ ROM_START( gal3 )
ROM_LOAD32_BYTE( "glc-slv-prg3.18b", 0x00000, 0x20000, CRC(deae86d2) SHA1(1898955423b8da585b6319406566aad02db20d64) )
/********* DSP board x2 *********/
ROM_REGION32_BE( 0x400000, "dsp_board1", ROMREGION_ERASE ) /* 24bit signed point data */
ROM_REGION32_BE( 0x400000, "namcos21dsp_c67_1:point24", ROMREGION_ERASE ) /* 24bit signed point data */
ROM_LOAD32_BYTE( "glc1-dsp-ptoh.2f", 0x000001, 0x80000, CRC(b4213c83) SHA1(9d036b73149656fdc13eed38946a70f532bff3f1) ) /* most significant */
ROM_LOAD32_BYTE( "glc1-dsp-ptou.2k", 0x000002, 0x80000, CRC(14877cef) SHA1(5ebdccd6db837ceb9473bd219eb211431944cbf0) )
ROM_LOAD32_BYTE( "glc1-dsp-ptol.2n", 0x000003, 0x80000, CRC(b318534a) SHA1(6fcf2ead6dd0d5a6f22438520588ba4e33ca39a8) ) /* least significant */
/* and 5x C67 (TMS320C25) */
ROM_REGION32_BE( 0x400000, "dsp_board2", ROMREGION_ERASE ) /* 24bit signed point data */
ROM_REGION32_BE( 0x400000, "namcos21dsp_c67_2:point24", ROMREGION_ERASE ) /* 24bit signed point data */
ROM_LOAD32_BYTE( "glc1-dsp-ptoh.2f", 0x000001, 0x80000, CRC(b4213c83) SHA1(9d036b73149656fdc13eed38946a70f532bff3f1) ) /* most significant */
ROM_LOAD32_BYTE( "glc1-dsp-ptou.2k", 0x000002, 0x80000, CRC(14877cef) SHA1(5ebdccd6db837ceb9473bd219eb211431944cbf0) )
ROM_LOAD32_BYTE( "glc1-dsp-ptol.2n", 0x000003, 0x80000, CRC(b318534a) SHA1(6fcf2ead6dd0d5a6f22438520588ba4e33ca39a8) ) /* least significant */
/* and 5x C67 (TMS320C25) */
/********* OBJ board x2 *********/
ROM_REGION( 0x200000, "obj_board1", 0 )

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,861 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino, Naibo, David Haywood
/**
see http://www.tvspels-nostalgi.com/driverseye.htm for details about setup
2008/06/11, by Naibo(translated to English by Mameplus team):
Driver's Eyes works,
-the communication work between CPU and 3D DSP should be limited to the master M68000,
if the address mapping is done in the shared memory, master CPU would be disturbed by the slave one.
-The left, center and right screens have separate programs and boards, each would work independently.
About projection angles of left and right screen, the angle is correct on "DRIVER'S EYES" title screen, however in the tracks of demo mode it doesn't seem correct.
(probably wants angle sent by main board?)
-On demo screen, should fog effects be turned off?
NOTES:
Driver's Eyes
not yet working
TODO:
Driver's Eyes
add communications for Left and Right screen (linked C139 or something else?)
*/
#include "emu.h"
#include "machine/namcoio_gearbox.h"
#include "screen.h"
#include "emupal.h"
#include "speaker.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6805/m6805.h"
#include "cpu/m6809/m6809.h"
#include "cpu/tms32025/tms32025.h"
#include "machine/nvram.h"
#include "machine/timer.h"
#include "machine/namco_c139.h"
#include "machine/namco_c148.h"
#include "machine/namco68.h"
#include "machine/namcos21_dsp.h"
#include "video/namco_c355spr.h"
#include "video/namcos21_3d.h"
#include "sound/ym2151.h"
#include "sound/c140.h"
// TODO: basic parameters to get 60.606060 Hz, x2 is for interlace
#define MCFG_SCREEN_RAW_PARAMS_NAMCO480I \
MCFG_SCREEN_RAW_PARAMS(12288000*2, 768, 0, 496, 264*2,0,480)
#define ENABLE_LOGGING 0
#define NAMCOS21_NUM_COLORS 0x8000
DECLARE_DEVICE_TYPE(NAMCO_DE_PCB, namco_de_pcbstack_device)
class namco_de_pcbstack_device : public device_t
{
public:
// construction/destruction
namco_de_pcbstack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void configure_c148_standard(machine_config &config);
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
private:
INTERRUPT_GEN_MEMBER( irq0_line_hold );
INTERRUPT_GEN_MEMBER( irq1_line_hold );
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_slave;
required_device<namcoc68_device> m_c68;
required_device<namco_c139_device> m_sci;
required_device<namco_c148_device> m_master_intc;
required_device<namco_c148_device> m_slave_intc;
required_device<c140_device> m_c140;
required_device<namco_c355spr_device> m_c355spr;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
required_memory_bank m_audiobank;
required_shared_ptr<uint8_t> m_mpDualPortRAM;
required_device<namcos21_3d_device> m_namcos21_3d;
required_device<namcos21_dsp_device> m_namcos21_dsp;
uint16_t m_video_enable;
DECLARE_READ16_MEMBER(namcos21_video_enable_r);
DECLARE_WRITE16_MEMBER(namcos21_video_enable_w);
DECLARE_READ16_MEMBER(namcos2_68k_dualportram_word_r);
DECLARE_WRITE16_MEMBER(namcos2_68k_dualportram_word_w);
DECLARE_READ8_MEMBER(namcos2_dualportram_byte_r);
DECLARE_WRITE8_MEMBER(namcos2_dualportram_byte_w);
DECLARE_WRITE8_MEMBER( namcos2_68k_eeprom_w );
DECLARE_READ8_MEMBER( namcos2_68k_eeprom_r );
DECLARE_WRITE8_MEMBER( namcos2_sound_bankselect_w );
DECLARE_WRITE8_MEMBER(sound_reset_w);
DECLARE_WRITE8_MEMBER(system_reset_w);
void reset_all_subcpus(int state);
std::unique_ptr<uint8_t[]> m_eeprom;
TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
uint32_t screen_update_driveyes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void configure_c68_namcos21(machine_config &config);
void driveyes_common_map(address_map &map);
void driveyes_master_map(address_map &map);
void driveyes_slave_map(address_map &map);
void sound_map(address_map &map);
};
DEFINE_DEVICE_TYPE(NAMCO_DE_PCB, namco_de_pcbstack_device, "namco_de_pcb", "Namco Driver's Eyes PCB stack")
namco_de_pcbstack_device::namco_de_pcbstack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCO_DE_PCB, tag, owner, clock),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_slave(*this, "slave"),
m_c68(*this, "c68mcu"),
m_sci(*this, "sci"),
m_master_intc(*this, "master_intc"),
m_slave_intc(*this, "slave_intc"),
m_c140(*this, "c140"),
m_c355spr(*this, "c355spr"),
m_palette(*this, "palette"),
m_screen(*this, "screen"),
m_audiobank(*this, "audiobank"),
m_mpDualPortRAM(*this, "mpdualportram"),
m_namcos21_3d(*this, "namcos21_3d"),
m_namcos21_dsp(*this, "namcos21dsp")
{}
INTERRUPT_GEN_MEMBER( namco_de_pcbstack_device::irq0_line_hold ) { device.execute().set_input_line(0, HOLD_LINE); }
INTERRUPT_GEN_MEMBER( namco_de_pcbstack_device::irq1_line_hold ) { device.execute().set_input_line(1, HOLD_LINE); }
static const gfx_layout tile_layout =
{
16,16,
RGN_FRAC(1,4), /* number of tiles */
8, /* bits per pixel */
{ /* plane offsets */
0,1,2,3,4,5,6,7
},
{ /* x offsets */
0*8,RGN_FRAC(1,4)+0*8,RGN_FRAC(2,4)+0*8,RGN_FRAC(3,4)+0*8,
1*8,RGN_FRAC(1,4)+1*8,RGN_FRAC(2,4)+1*8,RGN_FRAC(3,4)+1*8,
2*8,RGN_FRAC(1,4)+2*8,RGN_FRAC(2,4)+2*8,RGN_FRAC(3,4)+2*8,
3*8,RGN_FRAC(1,4)+3*8,RGN_FRAC(2,4)+3*8,RGN_FRAC(3,4)+3*8
},
{ /* y offsets */
0*32,1*32,2*32,3*32,
4*32,5*32,6*32,7*32,
8*32,9*32,10*32,11*32,
12*32,13*32,14*32,15*32
},
8*64 /* sprite offset */
};
static GFXDECODE_START( gfx_namcos21 )
GFXDECODE_ENTRY( "gfx1", 0x000000, tile_layout, 0x1000, 0x10 )
GFXDECODE_END
MACHINE_CONFIG_START(namco_de_pcbstack_device::device_add_mconfig)
MCFG_DEVICE_ADD("maincpu", M68000,12288000) /* Master */
MCFG_DEVICE_PROGRAM_MAP(driveyes_master_map)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namco_de_pcbstack_device, screen_scanline, "screen", 0, 1)
MCFG_DEVICE_ADD("slave", M68000,12288000) /* Slave */
MCFG_DEVICE_PROGRAM_MAP(driveyes_slave_map)
MCFG_DEVICE_ADD("audiocpu", MC6809E, 3072000) /* Sound */
MCFG_DEVICE_PROGRAM_MAP(sound_map)
MCFG_DEVICE_PERIODIC_INT_DRIVER(namco_de_pcbstack_device, irq0_line_hold, 2*60)
MCFG_DEVICE_PERIODIC_INT_DRIVER(namco_de_pcbstack_device, irq1_line_hold, 120)
configure_c68_namcos21(config);
NAMCOS21_DSP(config, m_namcos21_dsp, 0);
m_namcos21_dsp->set_renderer_tag("namcos21_3d");
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame */
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
configure_c148_standard(config);
NAMCO_C139(config, m_sci, 0);
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS_NAMCO480I
MCFG_SCREEN_UPDATE_DRIVER(namco_de_pcbstack_device, screen_update_driveyes)
MCFG_SCREEN_PALETTE("palette")
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_namcos21)
MCFG_PALETTE_ADD("palette", NAMCOS21_NUM_COLORS)
MCFG_PALETTE_FORMAT(XBRG)
NAMCOS21_3D(config, m_namcos21_3d, 0);
m_namcos21_3d->set_fixed_palbase(0x3f00);
m_namcos21_3d->set_zz_shift_mult(10, 0x100);
m_namcos21_3d->set_depth_reverse(false);
m_namcos21_3d->set_framebuffer_size(496,480);
NAMCO_C355SPR(config, m_c355spr, 0);
m_c355spr->set_palette_tag("palette");
m_c355spr->set_gfxdecode_tag("gfxdecode");
m_c355spr->set_is_namcofl(false);
m_c355spr->set_tile_callback(namco_c355spr_device::c355_obj_code2tile_delegate());
m_c355spr->set_palxor(0xf); // reverse mapping
m_c355spr->set_gfxregion(0);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
C140(config, m_c140, 8000000/374);
m_c140->set_bank_type(c140_device::C140_TYPE::SYSTEM21);
m_c140->add_route(0, "lspeaker", 0.50);
m_c140->add_route(1, "rspeaker", 0.50);
MCFG_DEVICE_ADD("ymsnd", YM2151, 3579580)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.30)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.30)
MACHINE_CONFIG_END
uint32_t namco_de_pcbstack_device::screen_update_driveyes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
//uint8_t *videoram = m_gpu_videoram.get();
int pivot = 3;
int pri;
bitmap.fill(0xff, cliprect );
m_c355spr->draw(screen, bitmap, cliprect, 2 );
m_c355spr->draw(screen, bitmap, cliprect, 14 ); //driver's eyes
m_namcos21_3d->copy_visible_poly_framebuffer(bitmap, cliprect, 0x7fc0, 0x7ffe);
m_c355spr->draw(screen, bitmap, cliprect, 0 );
m_c355spr->draw(screen, bitmap, cliprect, 1 );
m_namcos21_3d->copy_visible_poly_framebuffer(bitmap, cliprect, 0, 0x7fbf);
for (pri = pivot; pri < 8; pri++)
{
m_c355spr->draw(screen, bitmap, cliprect, pri);
}
m_c355spr->draw(screen, bitmap, cliprect, 15 ); //driver's eyes
return 0;
}
READ16_MEMBER(namco_de_pcbstack_device::namcos21_video_enable_r)
{
return m_video_enable;
}
WRITE16_MEMBER(namco_de_pcbstack_device::namcos21_video_enable_w)
{
COMBINE_DATA( &m_video_enable ); /* 0x40 = enable */
if( m_video_enable!=0 && m_video_enable!=0x40 )
{
logerror( "unexpected namcos21_video_enable_w=0x%x\n", m_video_enable );
}
}
/***********************************************************/
/* dual port ram memory handlers */
READ16_MEMBER(namco_de_pcbstack_device::namcos2_68k_dualportram_word_r)
{
return m_mpDualPortRAM[offset];
}
WRITE16_MEMBER(namco_de_pcbstack_device::namcos2_68k_dualportram_word_w)
{
if( ACCESSING_BITS_0_7 )
{
m_mpDualPortRAM[offset] = data&0xff;
}
}
READ8_MEMBER(namco_de_pcbstack_device::namcos2_dualportram_byte_r)
{
return m_mpDualPortRAM[offset];
}
WRITE8_MEMBER(namco_de_pcbstack_device::namcos2_dualportram_byte_w)
{
m_mpDualPortRAM[offset] = data;
}
/*************************************************************/
/* SOUND 6809 CPU Memory declarations */
/*************************************************************/
void namco_de_pcbstack_device::sound_map(address_map &map)
{
map(0x0000, 0x3fff).bankr("audiobank"); /* banked */
map(0x3000, 0x3003).nopw(); /* ? */
map(0x4000, 0x4001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
map(0x5000, 0x6fff).rw(m_c140, FUNC(c140_device::c140_r), FUNC(c140_device::c140_w));
map(0x7000, 0x77ff).rw(FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_r), FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_w)).share("mpdualportram");
map(0x7800, 0x7fff).rw(FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_r), FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_w)); /* mirror */
map(0x8000, 0x9fff).ram();
map(0xa000, 0xbfff).nopw(); /* amplifier enable on 1st write */
map(0xc000, 0xffff).nopw(); /* avoid debug log noise; games write frequently to 0xe000 */
map(0xc000, 0xc001).w(FUNC(namco_de_pcbstack_device::namcos2_sound_bankselect_w));
map(0xd001, 0xd001).nopw(); /* watchdog */
map(0xd000, 0xffff).rom().region("audiocpu", 0x01000);
}
/*************************************************************/
/* I/O HD63705 MCU Memory declarations */
/*************************************************************/
void namco_de_pcbstack_device::configure_c68_namcos21(machine_config &config)
{
NAMCOC68(config, m_c68, 8000000);
m_c68->in_pb_callback().set_ioport("MCUB");
m_c68->in_pc_callback().set_ioport("MCUC");
m_c68->in_ph_callback().set_ioport("MCUH");
m_c68->in_pdsw_callback().set_ioport("DSW");
m_c68->di0_in_cb().set_ioport("MCUDI0");
m_c68->di1_in_cb().set_ioport("MCUDI1");
m_c68->di2_in_cb().set_ioport("MCUDI2");
m_c68->di3_in_cb().set_ioport("MCUDI3");
m_c68->an0_in_cb().set_ioport("AN0");
m_c68->an1_in_cb().set_ioport("AN1");
m_c68->an2_in_cb().set_ioport("AN2");
m_c68->an3_in_cb().set_ioport("AN3");
m_c68->an4_in_cb().set_ioport("AN4");
m_c68->an5_in_cb().set_ioport("AN5");
m_c68->an6_in_cb().set_ioport("AN6");
m_c68->an7_in_cb().set_ioport("AN7");
m_c68->dp_in_callback().set(FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_r));
m_c68->dp_out_callback().set(FUNC(namco_de_pcbstack_device::namcos2_dualportram_byte_w));
}
/*************************************************************/
/* Driver's Eyes Memory declarations overrides */
/*************************************************************/
void namco_de_pcbstack_device::driveyes_common_map(address_map &map)
{
map(0x700000, 0x71ffff).rw(m_c355spr, FUNC(namco_c355spr_device::spriteram_r), FUNC(namco_c355spr_device::spriteram_w));
map(0x720000, 0x720007).rw(m_c355spr, FUNC(namco_c355spr_device::position_r), FUNC(namco_c355spr_device::position_w));
map(0x740000, 0x74ffff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x750000, 0x75ffff).ram().w(m_palette, FUNC(palette_device::write16_ext)).share("palette_ext");
map(0x760000, 0x760001).rw(FUNC(namco_de_pcbstack_device::namcos21_video_enable_r), FUNC(namco_de_pcbstack_device::namcos21_video_enable_w));
map(0x800000, 0x8fffff).rom().region("data", 0);
map(0x900000, 0x90ffff).ram().share("sharedram");
map(0xa00000, 0xa00fff).rw(FUNC(namco_de_pcbstack_device::namcos2_68k_dualportram_word_r), FUNC(namco_de_pcbstack_device::namcos2_68k_dualportram_word_w));
map(0xb00000, 0xb03fff).rw(m_sci, FUNC(namco_c139_device::ram_r), FUNC(namco_c139_device::ram_w));
map(0xb80000, 0xb8000f).m(m_sci, FUNC(namco_c139_device::regs_map));
}
void namco_de_pcbstack_device::driveyes_master_map(address_map &map)
{
driveyes_common_map(map);
map(0x000000, 0x03ffff).rom();
map(0x100000, 0x10ffff).ram(); /* private work RAM */
map(0x180000, 0x183fff).rw(FUNC(namco_de_pcbstack_device::namcos2_68k_eeprom_r), FUNC(namco_de_pcbstack_device::namcos2_68k_eeprom_w)).umask16(0x00ff);
map(0x1c0000, 0x1fffff).m(m_master_intc, FUNC(namco_c148_device::map));
// DSP related
map(0x250000, 0x25ffff).ram().share("namcos21dsp:winrun_polydata");
map(0x280000, 0x281fff).w(m_namcos21_dsp, FUNC(namcos21_dsp_device::winrun_dspbios_w));
map(0x380000, 0x38000f).rw(m_namcos21_dsp, FUNC(namcos21_dsp_device::winrun_dspcomram_control_r), FUNC(namcos21_dsp_device::winrun_dspcomram_control_w));
map(0x3c0000, 0x3c1fff).rw(m_namcos21_dsp, FUNC(namcos21_dsp_device::winrun_68k_dspcomram_r), FUNC(namcos21_dsp_device::winrun_68k_dspcomram_w));
map(0x400000, 0x400001).w(m_namcos21_dsp, FUNC(namcos21_dsp_device::pointram_control_w));
map(0x440000, 0x440001).rw(m_namcos21_dsp, FUNC(namcos21_dsp_device::pointram_data_r), FUNC(namcos21_dsp_device::pointram_data_w));
}
void namco_de_pcbstack_device::driveyes_slave_map(address_map &map)
{
driveyes_common_map(map);
map(0x000000, 0x03ffff).rom();
map(0x100000, 0x10ffff).ram(); /* private work RAM */
map(0x1c0000, 0x1fffff).m(m_slave_intc, FUNC(namco_c148_device::map));
}
WRITE8_MEMBER( namco_de_pcbstack_device::namcos2_sound_bankselect_w )
{
m_audiobank->set_entry(data>>4);
}
WRITE8_MEMBER(namco_de_pcbstack_device::sound_reset_w)
{
if (data & 0x01)
{
/* Resume execution */
m_audiocpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
m_maincpu->yield();
}
else
{
/* Suspend execution */
m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
}
WRITE8_MEMBER(namco_de_pcbstack_device::system_reset_w)
{
reset_all_subcpus(data & 1 ? CLEAR_LINE : ASSERT_LINE);
if (data & 0x01)
m_maincpu->yield();
}
void namco_de_pcbstack_device::reset_all_subcpus(int state)
{
m_slave->set_input_line(INPUT_LINE_RESET, state);
m_c68->ext_reset(state);
}
WRITE8_MEMBER(namco_de_pcbstack_device::namcos2_68k_eeprom_w)
{
m_eeprom[offset] = data;
}
READ8_MEMBER(namco_de_pcbstack_device::namcos2_68k_eeprom_r)
{
return m_eeprom[offset];
}
TIMER_DEVICE_CALLBACK_MEMBER(namco_de_pcbstack_device::screen_scanline)
{
int scanline = param;
// int cur_posirq = get_posirq_scanline()*2;
if(scanline == 240*2)
{
m_master_intc->vblank_irq_trigger();
m_slave_intc->vblank_irq_trigger();
m_c68->ext_interrupt(ASSERT_LINE);
}
}
void namco_de_pcbstack_device::configure_c148_standard(machine_config &config)
{
NAMCO_C148(config, m_master_intc, 0, m_maincpu, true);
m_master_intc->link_c148_device(m_slave_intc);
m_master_intc->out_ext1_callback().set(FUNC(namco_de_pcbstack_device::sound_reset_w));
m_master_intc->out_ext2_callback().set(FUNC(namco_de_pcbstack_device::system_reset_w));
NAMCO_C148(config, m_slave_intc, 0, m_slave, false);
m_slave_intc->link_c148_device(m_master_intc);
}
void namco_de_pcbstack_device::device_start()
{
m_eeprom = std::make_unique<uint8_t[]>(0x2000);
subdevice<nvram_device>("nvram")->set_base(m_eeprom.get(), 0x2000);
if (m_audiobank)
{
uint32_t max = memregion("audiocpu")->bytes() / 0x4000;
for (int i = 0; i < 0x10; i++)
m_audiobank->configure_entry(i, memregion("audiocpu")->base() + (i % max) * 0x4000);
m_audiobank->set_entry(0);
}
}
void namco_de_pcbstack_device::device_reset()
{
address_space &audio_space = m_audiocpu->space(AS_PROGRAM);
/* Initialise the bank select in the sound CPU */
namcos2_sound_bankselect_w(audio_space, 0, 0); /* Page in bank 0 */
m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE );
/* Place CPU2 & CPU3 into the reset condition */
reset_all_subcpus(ASSERT_LINE);
}
class namcos21_de_state : public driver_device
{
public:
namcos21_de_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_pcb(*this, "pcb_%u", 0U),
m_io_gearbox(*this, "gearbox")
{ }
void driveyes(machine_config &config);
private:
required_device_array<namco_de_pcbstack_device, 3> m_pcb;
required_device<namcoio_gearbox_device> m_io_gearbox;
};
// driveyes only
MACHINE_CONFIG_START(namcos21_de_state::driveyes)
MCFG_DEVICE_ADD("pcb_0", NAMCO_DE_PCB,0)
MCFG_DEVICE_ADD("pcb_1", NAMCO_DE_PCB,0)
MCFG_DEVICE_ADD("pcb_2", NAMCO_DE_PCB,0)
MCFG_DEVICE_ADD("gearbox", NAMCOIO_GEARBOX, 0)
MACHINE_CONFIG_END
// stacks with the DSWs set to left or right screen will show 'receive error' because they want comms from the main screen
static INPUT_PORTS_START( driveyes )
PORT_START("pcb_1:MCUC")
PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Service Button") PORT_CODE(KEYCODE_0) PORT_TOGGLE // alt test mode switch
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_START("pcb_1:MCUB")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("gearbox", namcoio_gearbox_device, clutch_r )
PORT_BIT( 0x37, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* ? */
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* ? */
PORT_START("pcb_1:MCUH")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Red Button")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Green Button")
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:DSW")
PORT_SERVICE( 0x01, IP_ACTIVE_LOW )
PORT_DIPNAME( 0x02, 0x02, "DSW2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x0c, 0x0c, "Screen (DON'T CHANGE)")
PORT_DIPSETTING( 0x0c, "Center (correct)" )
PORT_DIPSETTING( 0x08, "Left (invalid)" )
PORT_DIPSETTING( 0x04, "Right (invalid)" )
PORT_DIPSETTING( 0x00, "Right (invalid) (duplicate)" )
PORT_DIPNAME( 0x10, 0x10, "DSW5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, "PCM ROM")
PORT_DIPSETTING( 0x20, "2M" )
PORT_DIPSETTING( 0x00, "4M" )
PORT_DIPNAME( 0x40, 0x40, "DSW7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Screen Stop")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("pcb_1:AN0")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:AN1")
PORT_BIT( 0xff, 0x80, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(15) PORT_KEYDELTA(10) PORT_NAME("Gas Pedal")
PORT_START("pcb_1:AN2")
PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(15) PORT_KEYDELTA(10) PORT_NAME("Steering Wheel")
PORT_START("pcb_1:AN3")
PORT_BIT( 0xff, 0x80, IPT_PEDAL2 ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(15) PORT_KEYDELTA(10) PORT_NAME("Brake Pedal")
PORT_START("pcb_1:AN4")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:AN5")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:AN6")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:AN7")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:MCUDI0")
PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER("gearbox", namcoio_gearbox_device, in_r, nullptr )
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:MCUDI1") /* 63B05Z0 - $3001 */
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:MCUDI2") /* 63B05Z0 - $3002 */
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_1:MCUDI3") /* 63B05Z0 - $3003 */
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
// the side view screens do still read inputs, but it's more likely that the main screen should be transfering them
// somehow rather than the controls being directly split
PORT_START("pcb_0:DSW")
PORT_SERVICE( 0x01, IP_ACTIVE_LOW )
PORT_DIPNAME( 0x02, 0x02, "DSW2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x0c, 0x08, "Screen (DON'T CHANGE)")
PORT_DIPSETTING( 0x0c, "Center (invalid)" )
PORT_DIPSETTING( 0x08, "Left (correct)" )
PORT_DIPSETTING( 0x04, "Right (invalid)" )
PORT_DIPSETTING( 0x00, "Right (invalid) (duplicate)" )
PORT_DIPNAME( 0x10, 0x10, "DSW5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, "PCM ROM")
PORT_DIPSETTING( 0x20, "2M" )
PORT_DIPSETTING( 0x00, "4M" )
PORT_DIPNAME( 0x40, 0x40, "DSW7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Screen Stop")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("pcb_0:MCUC")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUB")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUH")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN0")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN1")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN2")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN3")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN4")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN5")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN6")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:AN7")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUDI0")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUDI1")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUDI2")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_0:MCUDI3")
PORT_START("pcb_2:DSW")
PORT_SERVICE( 0x01, IP_ACTIVE_LOW )
PORT_DIPNAME( 0x02, 0x02, "DSW2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x0c, 0x04, "Screen (DON'T CHANGE)")
PORT_DIPSETTING( 0x0c, "Center (invalid)" )
PORT_DIPSETTING( 0x08, "Left (invalid)" )
PORT_DIPSETTING( 0x04, "Right (correct)" )
PORT_DIPSETTING( 0x00, "Right (invalid) (duplicate)" )
PORT_DIPNAME( 0x10, 0x10, "DSW5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, "PCM ROM")
PORT_DIPSETTING( 0x20, "2M" )
PORT_DIPSETTING( 0x00, "4M" )
PORT_DIPNAME( 0x40, 0x40, "DSW7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Screen Stop")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("pcb_2:MCUC")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUB")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUH")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN0")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN1")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN2")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN3")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN4")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN5")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN6")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:AN7")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUDI0")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUDI1")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUDI2")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("pcb_2:MCUDI3")
INPUT_PORTS_END
/*
Note, only the main screen PCB stack has voice roms populated
the sound program also differs on the side screen sets
pcb_0 = left
pcb_1 = center
pcb_2 = right
*/
ROM_START( driveyes )
// pcb_1 - center
ROM_REGION( 0x40000, "pcb_1:maincpu", 0 ) /* C68C - 68k code */
ROM_LOAD16_BYTE( "de2-mp-ub.3j", 0x000000, 0x20000, CRC(f9c86fb5) SHA1(b48d16e8f26e7a2cfecb30285b517c42e5585ac7) )
ROM_LOAD16_BYTE( "de2-mp-lb.1j", 0x000001, 0x20000, CRC(11d8587a) SHA1(ecb1e8fe2ba56b6f6a71a5552d5663b597165786) )
ROM_REGION( 0x40000, "pcb_1:slave", 0 ) /* C68 - 68k code */
ROM_LOAD16_BYTE( "de1-sp-ub.6c", 0x000000, 0x20000, CRC(231b144f) SHA1(42518614cb083455dc5fec71e699403907ca784b) )
ROM_LOAD16_BYTE( "de1-sp-lb.4c", 0x000001, 0x20000, CRC(50cb9f59) SHA1(aec7fa080854f0297d9e90e3aaeb0f332fd579bd) )
ROM_REGION( 0x20000, "pcb_1:audiocpu", 0 ) /* Sound */
ROM_LOAD( "de1-snd0.8j", 0x000000, 0x020000, CRC(5474f203) SHA1(e0ae2f6978deb0c934d9311a334a6e36bb402aee) ) /* correct for center view */
ROM_REGION( 0x200000, "pcb_1:c140", 0 ) /* sound samples - populated for center view only */
ROM_LOAD("de1-voi0.12b", 0x040000, 0x40000, CRC(fc44adbd) SHA1(4268bb1f025e47a94212351d1c1cfd0e5029221f) )
ROM_LOAD("de1-voi1.12c", 0x0c0000, 0x40000, CRC(a71dc55a) SHA1(5e746184db9144ab4e3a97b20195b92b0f56c8cc) )
ROM_LOAD("de1-voi2.12d", 0x140000, 0x40000, CRC(4d32879a) SHA1(eae65f4b98cee9efe4e5dad7298c3717cfb1e6bf) )
ROM_LOAD("de1-voi3.12e", 0x1c0000, 0x40000, CRC(e4832d18) SHA1(0460c79d3942aab89a765b0bd8bbddaf19a6d682) )
ROM_REGION( 0x8000, "pcb_1:c68mcu:external", ROMREGION_ERASE00 ) /* C68 (M37450) I/O MCU program */
/* external ROM not populated, unclear how it would map */
ROM_REGION( 0x200000, "pcb_1:gfx1", 0 ) /* sprites */
ROM_LOAD( "de1-obj0.5s", 0x000000, 0x40000, CRC(7438bd53) SHA1(7619c4b56d5c466e845eb45e6157dcaf2a03ad94) )
ROM_LOAD( "de1-obj4.4s", 0x040000, 0x40000, CRC(335f0ea4) SHA1(9ec065d99ad0874b262b372334179a7e7612558e) )
ROM_LOAD( "de1-obj1.5x", 0x080000, 0x40000, CRC(45f2334e) SHA1(95f277a4e43d6662ae44d6b69a57f65c72978319) )
ROM_LOAD( "de1-obj5.4x", 0x0c0000, 0x40000, CRC(9e22999c) SHA1(02624186c359b5e2c96cd3f0e2cb1598ea36dff7) )
ROM_LOAD( "de1-obj2.3s", 0x100000, 0x40000, CRC(8f1a542c) SHA1(2cb59713607d8929815a9b28bf2a384b6a6c9db8) )
ROM_LOAD( "de1-obj6.2s", 0x140000, 0x40000, CRC(346df4d5) SHA1(edbadb9db93b7f5a3b064c7f6acb77001cdacce2) )
ROM_LOAD( "de1-obj3.3x", 0x180000, 0x40000, CRC(fc94544c) SHA1(6297445c64784ee253716f6438d98e5fcd4e7520) )
ROM_LOAD( "de1-obj7.2x", 0x1c0000, 0x40000, CRC(9ce325d7) SHA1(de4d788bec14842507ed405244974b4fd4f07515) )
ROM_REGION16_BE( 0x100000, "pcb_1:data", 0 ) /* 68k */
ROM_LOAD16_BYTE( "de1-data-u.3a", 0x00000, 0x80000, CRC(fe65d2ab) SHA1(dbe962dda7efa60357fa3a684a265aaad49df5b5) )
ROM_LOAD16_BYTE( "de1-data-l.1a", 0x00001, 0x80000, CRC(9bb37aca) SHA1(7f5dffc95cadcf12f53ff7944920afc25ed3cf68) )
ROM_REGION16_BE( 0xc0000, "pcb_1:namcos21dsp:point16", 0 ) /* 3d objects */
ROM_LOAD16_BYTE( "de1-pt0-ub.8j", 0x00000, 0x20000, CRC(3b6b746d) SHA1(40c992ef4cf5187b30aba42c5fe7ce0f8f02bee0) )
ROM_LOAD16_BYTE( "de1-pt0-lb.8d", 0x00001, 0x20000, CRC(9c5c477e) SHA1(c8ae8a663227d636d35bd5f432d23f05d6695942) )
ROM_LOAD16_BYTE( "de1-pt1-u.8l", 0x40000, 0x20000, CRC(23bc72a1) SHA1(083e2955ae2f88d1ad461517b47054d64375b46e) )
ROM_LOAD16_BYTE( "de1-pt1-l.8e", 0x40001, 0x20000, CRC(a05ee081) SHA1(1be4c61ad716abb809856e04d4bb450943706a55) )
ROM_LOAD16_BYTE( "de1-pt2-u.5n", 0x80000, 0x20000, CRC(10e83d81) SHA1(446fedc3b1e258a39fb9467e5327c9f9a9f1ac3f) )
ROM_LOAD16_BYTE( "de1-pt2-l.7n", 0x80001, 0x20000, CRC(3339a976) SHA1(c9eb9c04f7b3f2a85e5ab64ffb2fe4fcfb6c494b) )
ROM_REGION( 0x2000, "pcb_1:nvram", 0 ) /* default settings, including calibration */
ROM_LOAD( "nvram", 0x0000, 0x2000, CRC(fa6623e9) SHA1(8c313f136724eb6c829261b223a2ac1fc08d00c2) )
// pcb_0 - left
ROM_REGION( 0x40000, "pcb_0:maincpu", 0 ) /* C68C - 68k code */
ROM_LOAD16_BYTE( "de2-mp-ub.3j", 0x000000, 0x20000, CRC(f9c86fb5) SHA1(b48d16e8f26e7a2cfecb30285b517c42e5585ac7) )
ROM_LOAD16_BYTE( "de2-mp-lb.1j", 0x000001, 0x20000, CRC(11d8587a) SHA1(ecb1e8fe2ba56b6f6a71a5552d5663b597165786) )
ROM_REGION( 0x40000, "pcb_0:slave", 0 ) /* C68 - 68k code */
ROM_LOAD16_BYTE( "de1-sp-ub.6c", 0x000000, 0x20000, CRC(231b144f) SHA1(42518614cb083455dc5fec71e699403907ca784b) )
ROM_LOAD16_BYTE( "de1-sp-lb.4c", 0x000001, 0x20000, CRC(50cb9f59) SHA1(aec7fa080854f0297d9e90e3aaeb0f332fd579bd) )
ROM_REGION( 0x20000, "pcb_0:audiocpu", 0 ) /* Sound */
ROM_LOAD( "de1-snd0r.8j", 0x000000, 0x020000, CRC(7bbeda42) SHA1(fe840cc9069758928492bbeec79acded18daafd9) ) // correct for left & right views
ROM_REGION( 0x200000, "pcb_0:c140", ROMREGION_ERASE00 ) /* sound samples */
/* unpopulated for left / right views */
ROM_REGION( 0x8000, "pcb_0:c68mcu:external", ROMREGION_ERASE00 ) /* C68 (M37450) I/O MCU program */
/* external ROM not populated, unclear how it would map */
ROM_REGION( 0x200000, "pcb_0:gfx1", 0 ) /* sprites */
ROM_LOAD( "de1-obj0.5s", 0x000000, 0x40000, CRC(7438bd53) SHA1(7619c4b56d5c466e845eb45e6157dcaf2a03ad94) )
ROM_LOAD( "de1-obj4.4s", 0x040000, 0x40000, CRC(335f0ea4) SHA1(9ec065d99ad0874b262b372334179a7e7612558e) )
ROM_LOAD( "de1-obj1.5x", 0x080000, 0x40000, CRC(45f2334e) SHA1(95f277a4e43d6662ae44d6b69a57f65c72978319) )
ROM_LOAD( "de1-obj5.4x", 0x0c0000, 0x40000, CRC(9e22999c) SHA1(02624186c359b5e2c96cd3f0e2cb1598ea36dff7) )
ROM_LOAD( "de1-obj2.3s", 0x100000, 0x40000, CRC(8f1a542c) SHA1(2cb59713607d8929815a9b28bf2a384b6a6c9db8) )
ROM_LOAD( "de1-obj6.2s", 0x140000, 0x40000, CRC(346df4d5) SHA1(edbadb9db93b7f5a3b064c7f6acb77001cdacce2) )
ROM_LOAD( "de1-obj3.3x", 0x180000, 0x40000, CRC(fc94544c) SHA1(6297445c64784ee253716f6438d98e5fcd4e7520) )
ROM_LOAD( "de1-obj7.2x", 0x1c0000, 0x40000, CRC(9ce325d7) SHA1(de4d788bec14842507ed405244974b4fd4f07515) )
ROM_REGION16_BE( 0x100000, "pcb_0:data", 0 ) /* 68k */
ROM_LOAD16_BYTE( "de1-data-u.3a", 0x00000, 0x80000, CRC(fe65d2ab) SHA1(dbe962dda7efa60357fa3a684a265aaad49df5b5) )
ROM_LOAD16_BYTE( "de1-data-l.1a", 0x00001, 0x80000, CRC(9bb37aca) SHA1(7f5dffc95cadcf12f53ff7944920afc25ed3cf68) )
ROM_REGION16_BE( 0xc0000, "pcb_0:namcos21dsp:point16", 0 ) /* 3d objects */
ROM_LOAD16_BYTE( "de1-pt0-ub.8j", 0x00000, 0x20000, CRC(3b6b746d) SHA1(40c992ef4cf5187b30aba42c5fe7ce0f8f02bee0) )
ROM_LOAD16_BYTE( "de1-pt0-lb.8d", 0x00001, 0x20000, CRC(9c5c477e) SHA1(c8ae8a663227d636d35bd5f432d23f05d6695942) )
ROM_LOAD16_BYTE( "de1-pt1-u.8l", 0x40000, 0x20000, CRC(23bc72a1) SHA1(083e2955ae2f88d1ad461517b47054d64375b46e) )
ROM_LOAD16_BYTE( "de1-pt1-l.8e", 0x40001, 0x20000, CRC(a05ee081) SHA1(1be4c61ad716abb809856e04d4bb450943706a55) )
ROM_LOAD16_BYTE( "de1-pt2-u.5n", 0x80000, 0x20000, CRC(10e83d81) SHA1(446fedc3b1e258a39fb9467e5327c9f9a9f1ac3f) )
ROM_LOAD16_BYTE( "de1-pt2-l.7n", 0x80001, 0x20000, CRC(3339a976) SHA1(c9eb9c04f7b3f2a85e5ab64ffb2fe4fcfb6c494b) )
ROM_REGION( 0x2000, "pcb_0:nvram", 0 ) /* default settings, including calibration */
ROM_LOAD( "nvram", 0x0000, 0x2000, CRC(fa6623e9) SHA1(8c313f136724eb6c829261b223a2ac1fc08d00c2) )
// pcb_2 - right
ROM_REGION( 0x40000, "pcb_2:maincpu", 0 ) /* C68C - 68k code */
ROM_LOAD16_BYTE( "de2-mp-ub.3j", 0x000000, 0x20000, CRC(f9c86fb5) SHA1(b48d16e8f26e7a2cfecb30285b517c42e5585ac7) )
ROM_LOAD16_BYTE( "de2-mp-lb.1j", 0x000001, 0x20000, CRC(11d8587a) SHA1(ecb1e8fe2ba56b6f6a71a5552d5663b597165786) )
ROM_REGION( 0x40000, "pcb_2:slave", 0 ) /* C68 - 68k code */
ROM_LOAD16_BYTE( "de1-sp-ub.6c", 0x000000, 0x20000, CRC(231b144f) SHA1(42518614cb083455dc5fec71e699403907ca784b) )
ROM_LOAD16_BYTE( "de1-sp-lb.4c", 0x000001, 0x20000, CRC(50cb9f59) SHA1(aec7fa080854f0297d9e90e3aaeb0f332fd579bd) )
ROM_REGION( 0x20000, "pcb_2:audiocpu", 0 ) /* Sound */
ROM_LOAD( "de1-snd0r.8j", 0x000000, 0x020000, CRC(7bbeda42) SHA1(fe840cc9069758928492bbeec79acded18daafd9) ) // correct for left & right views
ROM_REGION( 0x200000, "pcb_2:c140", ROMREGION_ERASE00 ) /* sound samples */
/* unpopulated for left / right views */
ROM_REGION( 0x8000, "pcb_2:c68mcu:external", ROMREGION_ERASE00 ) /* C68 (M37450) I/O MCU program */
/* external ROM not populated, unclear how it would map */
ROM_REGION( 0x200000, "pcb_2:gfx1", 0 ) /* sprites */
ROM_LOAD( "de1-obj0.5s", 0x000000, 0x40000, CRC(7438bd53) SHA1(7619c4b56d5c466e845eb45e6157dcaf2a03ad94) )
ROM_LOAD( "de1-obj4.4s", 0x040000, 0x40000, CRC(335f0ea4) SHA1(9ec065d99ad0874b262b372334179a7e7612558e) )
ROM_LOAD( "de1-obj1.5x", 0x080000, 0x40000, CRC(45f2334e) SHA1(95f277a4e43d6662ae44d6b69a57f65c72978319) )
ROM_LOAD( "de1-obj5.4x", 0x0c0000, 0x40000, CRC(9e22999c) SHA1(02624186c359b5e2c96cd3f0e2cb1598ea36dff7) )
ROM_LOAD( "de1-obj2.3s", 0x100000, 0x40000, CRC(8f1a542c) SHA1(2cb59713607d8929815a9b28bf2a384b6a6c9db8) )
ROM_LOAD( "de1-obj6.2s", 0x140000, 0x40000, CRC(346df4d5) SHA1(edbadb9db93b7f5a3b064c7f6acb77001cdacce2) )
ROM_LOAD( "de1-obj3.3x", 0x180000, 0x40000, CRC(fc94544c) SHA1(6297445c64784ee253716f6438d98e5fcd4e7520) )
ROM_LOAD( "de1-obj7.2x", 0x1c0000, 0x40000, CRC(9ce325d7) SHA1(de4d788bec14842507ed405244974b4fd4f07515) )
ROM_REGION16_BE( 0x100000, "pcb_2:data", 0 ) /* 68k */
ROM_LOAD16_BYTE( "de1-data-u.3a", 0x00000, 0x80000, CRC(fe65d2ab) SHA1(dbe962dda7efa60357fa3a684a265aaad49df5b5) )
ROM_LOAD16_BYTE( "de1-data-l.1a", 0x00001, 0x80000, CRC(9bb37aca) SHA1(7f5dffc95cadcf12f53ff7944920afc25ed3cf68) )
ROM_REGION16_BE( 0xc0000, "pcb_2:namcos21dsp:point16", 0 ) /* 3d objects */
ROM_LOAD16_BYTE( "de1-pt0-ub.8j", 0x00000, 0x20000, CRC(3b6b746d) SHA1(40c992ef4cf5187b30aba42c5fe7ce0f8f02bee0) )
ROM_LOAD16_BYTE( "de1-pt0-lb.8d", 0x00001, 0x20000, CRC(9c5c477e) SHA1(c8ae8a663227d636d35bd5f432d23f05d6695942) )
ROM_LOAD16_BYTE( "de1-pt1-u.8l", 0x40000, 0x20000, CRC(23bc72a1) SHA1(083e2955ae2f88d1ad461517b47054d64375b46e) )
ROM_LOAD16_BYTE( "de1-pt1-l.8e", 0x40001, 0x20000, CRC(a05ee081) SHA1(1be4c61ad716abb809856e04d4bb450943706a55) )
ROM_LOAD16_BYTE( "de1-pt2-u.5n", 0x80000, 0x20000, CRC(10e83d81) SHA1(446fedc3b1e258a39fb9467e5327c9f9a9f1ac3f) )
ROM_LOAD16_BYTE( "de1-pt2-l.7n", 0x80001, 0x20000, CRC(3339a976) SHA1(c9eb9c04f7b3f2a85e5ab64ffb2fe4fcfb6c494b) )
ROM_REGION( 0x2000, "pcb_2:nvram", 0 ) /* default settings, including calibration */
ROM_LOAD( "nvram", 0x0000, 0x2000, CRC(fa6623e9) SHA1(8c313f136724eb6c829261b223a2ac1fc08d00c2) )
ROM_END
/* YEAR NAME PARENT MACHINE INPUT CLASS INIT MONITOR COMPANY FULLNAME FLAGS */
// 3 PCB stacks in a single cage (3x 4 PCBs) linked for 3 screen panorama, boards look similar to original Namco System 21 (not 21B) including TMS320C25 DSP, but use C68 I/O MCU and sprite chip instead of "68000 'GPU'" ?
GAME( 1992, driveyes, 0, driveyes, driveyes, namcos21_de_state, empty_init, ROT0, "Namco", "Driver's Eyes (Japan) (1992/01/10, Main Ver 2.1, Sub Ver 1.1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN)

View File

@ -1,305 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino
/**
* @file namcos21.h
*/
#ifndef MAME_INCLUDES_NAMCOS21_H
#define MAME_INCLUDES_NAMCOS21_H
#pragma once
#include "machine/namcoio_gearbox.h"
#include "machine/timer.h"
#include "machine/namco_c139.h"
#include "machine/namco_c148.h"
#include "machine/timer.h"
#include "sound/c140.h"
#include "video/c45.h"
#include "machine/namco65.h"
#include "machine/namco68.h"
#include "video/namco_c355spr.h"
#include "video/namcos2_sprite.h"
#include "video/namcos2_roz.h"
#define NAMCOS21_POLY_FRAME_WIDTH 496
#define NAMCOS21_POLY_FRAME_HEIGHT 480
#define WINRUN_MAX_POLY_PARAM (1+256*3)
#define NAMCOS21_NUM_COLORS 0x8000
#define DSP_BUF_MAX (4096*12)
struct dsp_state
{
unsigned masterSourceAddr;
uint16_t slaveInputBuffer[DSP_BUF_MAX];
unsigned slaveBytesAvailable;
unsigned slaveBytesAdvertised;
unsigned slaveInputStart;
uint16_t slaveOutputBuffer[DSP_BUF_MAX];
unsigned slaveOutputSize;
uint16_t masterDirectDrawBuffer[256];
unsigned masterDirectDrawSize;
int masterFinished;
int slaveActive;
};
struct n21_vertex
{
double x,y;
double z;
};
struct edge
{
double x;
double z;
};
class namcos21_state : public driver_device
{
public:
enum
{ /* Namco System21 */
NAMCOS21_AIRCOMBAT = 0x4000,
NAMCOS21_STARBLADE,
NAMCOS21_CYBERSLED,
NAMCOS21_SOLVALOU,
NAMCOS21_WINRUN91,
NAMCOS21_DRIVERS_EYES,
};
namcos21_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_master_dsp_code(*this,"master_dsp_code"),
m_gametype(0),
m_dspmaster(*this, "dspmaster"),
m_dspslave(*this, "dspslave"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_slave(*this, "slave"),
m_c65(*this, "c65mcu"),
m_c68(*this, "c68mcu"),
m_sci(*this, "sci"),
m_master_intc(*this, "master_intc"),
m_slave_intc(*this, "slave_intc"),
m_c140(*this, "c140"),
m_c355spr(*this, "c355spr"),
m_palette(*this, "palette"),
m_screen(*this, "screen"),
m_audiobank(*this, "audiobank"),
m_winrun_dspbios(*this,"winrun_dspbios"),
m_winrun_polydata(*this,"winrun_polydata"),
m_dspram16(*this,"dspram16"),
m_mpDualPortRAM(*this,"mpdualportram"),
m_ptrom24(*this,"point24"),
m_ptrom16(*this,"point16"),
m_dsp(*this, "dsp"),
m_io_gearbox(*this, "gearbox"),
m_gpu_intc(*this, "gpu_intc")
{ }
void configure_c148_standard(machine_config &config);
void driveyes(machine_config &config);
void winrun(machine_config &config);
void namcos21(machine_config &config);
void init_driveyes();
void init_winrun();
void init_starblad();
void init_solvalou();
void init_cybsled();
void init_aircomb();
optional_shared_ptr<uint16_t> m_master_dsp_code;
int m_mbNeedsKickstart;
void clear_poly_framebuffer();
std::unique_ptr<dsp_state> m_mpDspState;
int m_gametype;
optional_device<cpu_device> m_dspmaster;
optional_device<cpu_device> m_dspslave;
private:
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_slave;
optional_device<namcoc65_device> m_c65;
optional_device<namcoc68_device> m_c68;
optional_device<namco_c139_device> m_sci;
optional_device<namco_c148_device> m_master_intc;
optional_device<namco_c148_device> m_slave_intc;
optional_device<c140_device> m_c140;
optional_device<namco_c355spr_device> m_c355spr;
required_device<palette_device> m_palette;
optional_device<screen_device> m_screen;
optional_memory_bank m_audiobank;
optional_shared_ptr<uint16_t> m_winrun_dspbios;
optional_shared_ptr<uint16_t> m_winrun_polydata;
optional_shared_ptr<uint16_t> m_dspram16;
required_shared_ptr<uint8_t> m_mpDualPortRAM;
optional_region_ptr<int32_t> m_ptrom24;
optional_region_ptr<uint16_t> m_ptrom16;
optional_device<cpu_device> m_dsp;
optional_device<namcoio_gearbox_device> m_io_gearbox;
optional_device<namco_c148_device> m_gpu_intc;
std::unique_ptr<uint8_t[]> m_videoram;
std::unique_ptr<uint8_t[]> m_maskram;
std::unique_ptr<uint16_t[]> m_winrun_dspcomram;
uint16_t m_winrun_poly_buf[WINRUN_MAX_POLY_PARAM];
int m_winrun_poly_index;
uint32_t m_winrun_pointrom_addr;
int m_winrun_dsp_alive;
uint16_t m_winrun_dspcomram_control[8];
uint16_t m_video_enable;
std::unique_ptr<uint8_t[]> m_pointram;
int m_pointram_idx;
uint16_t m_pointram_control;
uint32_t m_pointrom_idx;
uint8_t m_mPointRomMSB;
int m_mbPointRomDataAvailable;
int m_irq_enable;
uint8_t m_depthcue[2][0x400];
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferPens;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferZ;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferPens2;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferZ2;
uint16_t m_winrun_color;
uint16_t m_winrun_gpu_register[0x10/2];
DECLARE_READ16_MEMBER(namcos21_video_enable_r);
DECLARE_WRITE16_MEMBER(namcos21_video_enable_w);
DECLARE_WRITE16_MEMBER(dspcuskey_w);
DECLARE_READ16_MEMBER(dspcuskey_r);
DECLARE_READ16_MEMBER(dspram16_r);
template<bool maincpu> DECLARE_WRITE16_MEMBER(dspram16_w);
DECLARE_READ16_MEMBER(dsp_port0_r);
DECLARE_WRITE16_MEMBER(dsp_port0_w);
DECLARE_READ16_MEMBER(dsp_port1_r);
DECLARE_WRITE16_MEMBER(dsp_port1_w);
DECLARE_READ16_MEMBER(dsp_port2_r);
DECLARE_WRITE16_MEMBER(dsp_port2_w);
DECLARE_READ16_MEMBER(dsp_port3_idc_rcv_enable_r);
DECLARE_WRITE16_MEMBER(dsp_port3_w);
DECLARE_WRITE16_MEMBER(dsp_port4_w);
DECLARE_READ16_MEMBER(dsp_port8_r);
DECLARE_WRITE16_MEMBER(dsp_port8_w);
DECLARE_READ16_MEMBER(dsp_port9_r);
DECLARE_READ16_MEMBER(dsp_porta_r);
DECLARE_WRITE16_MEMBER(dsp_porta_w);
DECLARE_READ16_MEMBER(dsp_portb_r);
DECLARE_WRITE16_MEMBER(dsp_portb_w);
DECLARE_WRITE16_MEMBER(dsp_portc_w);
DECLARE_READ16_MEMBER(dsp_portf_r);
DECLARE_WRITE16_MEMBER(dsp_xf_w);
DECLARE_READ16_MEMBER(slave_port0_r);
DECLARE_WRITE16_MEMBER(slave_port0_w);
DECLARE_READ16_MEMBER(slave_port2_r);
DECLARE_READ16_MEMBER(slave_port3_r);
DECLARE_WRITE16_MEMBER(slave_port3_w);
DECLARE_WRITE16_MEMBER(slave_XF_output_w);
DECLARE_READ16_MEMBER(slave_portf_r);
DECLARE_WRITE16_MEMBER(pointram_control_w);
DECLARE_READ16_MEMBER(pointram_data_r);
DECLARE_WRITE16_MEMBER(pointram_data_w);
DECLARE_READ16_MEMBER(namcos21_depthcue_r);
DECLARE_WRITE16_MEMBER(namcos21_depthcue_w);
DECLARE_READ16_MEMBER(namcos2_68k_dualportram_word_r);
DECLARE_WRITE16_MEMBER(namcos2_68k_dualportram_word_w);
DECLARE_READ8_MEMBER(namcos2_dualportram_byte_r);
DECLARE_WRITE8_MEMBER(namcos2_dualportram_byte_w);
DECLARE_READ16_MEMBER(winrun_dspcomram_r);
DECLARE_WRITE16_MEMBER(winrun_dspcomram_w);
DECLARE_READ16_MEMBER(winrun_cuskey_r);
DECLARE_WRITE16_MEMBER(winrun_cuskey_w);
DECLARE_READ16_MEMBER(winrun_poly_reset_r);
DECLARE_WRITE16_MEMBER(winrun_dsp_render_w);
DECLARE_WRITE16_MEMBER(winrun_dsp_pointrom_addr_w);
DECLARE_READ16_MEMBER(winrun_dsp_pointrom_data_r);
DECLARE_WRITE16_MEMBER(winrun_dsp_complete_w);
DECLARE_READ16_MEMBER(winrun_table_r);
DECLARE_WRITE16_MEMBER(winrun_dspbios_w);
DECLARE_READ16_MEMBER(winrun_68k_dspcomram_r);
DECLARE_WRITE16_MEMBER(winrun_68k_dspcomram_w);
DECLARE_READ16_MEMBER(winrun_dspcomram_control_r);
DECLARE_WRITE16_MEMBER(winrun_dspcomram_control_w);
DECLARE_READ16_MEMBER(winrun_gpu_color_r);
DECLARE_WRITE16_MEMBER(winrun_gpu_color_w);
DECLARE_READ16_MEMBER(winrun_gpu_register_r);
DECLARE_WRITE16_MEMBER(winrun_gpu_register_w);
DECLARE_WRITE16_MEMBER(winrun_gpu_videoram_w);
DECLARE_READ16_MEMBER(winrun_gpu_videoram_r);
DECLARE_WRITE8_MEMBER( namcos2_68k_eeprom_w );
DECLARE_READ8_MEMBER( namcos2_68k_eeprom_r );
DECLARE_WRITE8_MEMBER( namcos2_sound_bankselect_w );
DECLARE_WRITE8_MEMBER(sound_reset_w);
DECLARE_WRITE8_MEMBER(system_reset_w);
void reset_all_subcpus(int state);
// game type helpers
bool is_system21();
std::unique_ptr<uint8_t[]> m_eeprom;
TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
uint8_t m_gearbox_state;
DECLARE_CUSTOM_INPUT_MEMBER(driveyes_gearbox_r);
DECLARE_MACHINE_START(namcos21);
DECLARE_MACHINE_RESET(namcos21);
DECLARE_VIDEO_START(namcos21);
uint32_t screen_update_namcos21(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_winrun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_driveyes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void allocate_poly_framebuffer();
void copy_visible_poly_framebuffer(bitmap_ind16 &bitmap, const rectangle &clip, int zlo, int zhi);
void winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &cliprect);
void renderscanline_flat(const edge *e1, const edge *e2, int sy, unsigned color, int depthcueenable);
void rendertri(const n21_vertex *v0, const n21_vertex *v1, const n21_vertex *v2, unsigned color, int depthcueenable);
void draw_quad(int sx[4], int sy[4], int zcode[4], int color);
int32_t read_pointrom_data(unsigned offset);
void transmit_word_to_slave(uint16_t data);
void transfer_dsp_data();
uint16_t read_word_from_slave_input();
uint16_t get_input_bytes_advertised_for_slave();
int init_dsp();
void render_slave_output(uint16_t data);
void winrun_flush_poly();
void init(int game_type);
void configure_c65_namcos21(machine_config &config);
void configure_c68_namcos21(machine_config &config);
void common_map(address_map &map);
void driveyes_common_map(address_map &map);
void driveyes_master_map(address_map &map);
void driveyes_slave_map(address_map &map);
void master_dsp_data(address_map &map);
void master_dsp_io(address_map &map);
void master_dsp_program(address_map &map);
void master_map(address_map &map);
void mcu_map(address_map &map);
void slave_dsp_data(address_map &map);
void slave_dsp_io(address_map &map);
void slave_dsp_program(address_map &map);
void slave_map(address_map &map);
void sound_map(address_map &map);
void winrun_dsp_data(address_map &map);
void winrun_dsp_io(address_map &map);
void winrun_dsp_program(address_map &map);
void winrun_gpu_map(address_map &map);
void winrun_master_map(address_map &map);
void winrun_slave_map(address_map &map);
};
#endif // MAME_INCLUDES_NAMCOS21_H

View File

@ -8,6 +8,7 @@
TODO:
- Make this to actually work!
- Is RAM shared with a specific CPU other than master/slave?
- is this another MCU with internal ROM?
***************************************************************************/

View File

@ -0,0 +1,32 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/******************************************************************************
This is simply a TMS320C25 with internal ROM and Namco code '67'
used by Namco System 21 for both the master and slave DSPs (configuration
is decided based on a port read)
******************************************************************************/
#include "emu.h"
#include "namco_c67.h"
DEFINE_DEVICE_TYPE(NAMCO_C67, namco_c67_device, "namcoc67", "Namco C67 (TMS320C25)")
namco_c67_device::namco_c67_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
tms32025_device(mconfig, NAMCO_C67, tag, owner, clock)
{
set_mp_mc(false);
}
ROM_START( c67 )
ROM_REGION16_BE( 0x2000, "internal", 0 )
ROM_LOAD( "c67.bin", 0, 0x2000, CRC(6bd8988e) SHA1(c9ec18d5f88d53976b94444eedc64d5568155958) )
ROM_END
const tiny_rom_entry *namco_c67_device::device_rom_region() const
{
return ROM_NAME(c67);
}

View File

@ -0,0 +1,25 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_MACHINE_NAMCO_C67_H
#define MAME_MACHINE_NAMCO_C67_H
#pragma once
#include "cpu/tms32025/tms32025.h"
// base class
class namco_c67_device : public tms32025_device
{
public:
namco_c67_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual const tiny_rom_entry *device_rom_region() const override;
};
DECLARE_DEVICE_TYPE(NAMCO_C67, namco_c67_device)
#endif // MAME_MACHINE_NAMCO_C67_H

View File

@ -0,0 +1,275 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino, David Haywood
/*
Common code for the original Namco System 21 DSP board, with a single DSP
used by Winning Run, Driver's Eyes
TODO: handle protection properly and with callbacks
some of the list processing should probably be in the 3d device, split it out
*/
#include "emu.h"
#include "namcos21_dsp.h"
DEFINE_DEVICE_TYPE(NAMCOS21_DSP, namcos21_dsp_device, "namcos21_dsp_device", "Namco System 21 DSP Setup (1x TMS320C25 type)")
namcos21_dsp_device::namcos21_dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCOS21_DSP, tag, owner, clock),
m_dsp(*this, "dsp"),
m_winrun_dspbios(*this,"winrun_dspbios"),
m_winrun_polydata(*this,"winrun_polydata"),
m_ptrom16(*this,"point16"),
m_renderer(*this, finder_base::DUMMY_TAG)
{
}
void namcos21_dsp_device::device_start()
{
m_winrun_dspcomram = std::make_unique<uint16_t[]>(0x1000*2);
m_suspend_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(namcos21_dsp_device::suspend_callback),this));
m_pointram = std::make_unique<uint8_t[]>(PTRAM_SIZE);
m_pointram_idx = 0;
}
TIMER_CALLBACK_MEMBER(namcos21_dsp_device::suspend_callback)
{
m_dsp->suspend(SUSPEND_REASON_HALT, true);
}
void namcos21_dsp_device::device_reset()
{
m_poly_frame_width = m_renderer->get_width();
m_poly_frame_height = m_renderer->get_height();
// can't suspend directly from here, needs to be on a timer?
m_suspend_timer->adjust(attotime::zero);
}
READ16_MEMBER(namcos21_dsp_device::winrun_dspcomram_r)
{
int bank = 1-(m_winrun_dspcomram_control[0x4/2]&1);
uint16_t *mem = &m_winrun_dspcomram[0x1000*bank];
return mem[offset];
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dspcomram_w)
{
int bank = 1-(m_winrun_dspcomram_control[0x4/2]&1);
uint16_t *mem = &m_winrun_dspcomram[0x1000*bank];
COMBINE_DATA( &mem[offset] );
}
READ16_MEMBER(namcos21_dsp_device::winrun_cuskey_r)
{
int pc = m_dsp->pc();
switch( pc )
{
case 0x0064: /* winrun91 */
return 0xFEBB;
case 0x006c: /* winrun91 */
return 0xFFFF;
case 0x0073: /* winrun91 */
return 0x0144;
case 0x0075: /* winrun */
return 0x24;
default:
break;
}
return 0;
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_cuskey_w)
{
}
void namcos21_dsp_device::winrun_flush_poly()
{
if( m_winrun_poly_index>0 )
{
const uint16_t *pSource = m_winrun_poly_buf;
uint16_t color;
int sx[4], sy[4], zcode[4];
int j;
color = *pSource++;
if( color&0x8000 )
{ /* direct-draw */
for( j=0; j<4; j++ )
{
sx[j] = m_poly_frame_width/2 + (int16_t)*pSource++;
sy[j] = m_poly_frame_height/2 + (int16_t)*pSource++;
zcode[j] = *pSource++;
}
m_renderer->draw_quad(sx, sy, zcode, color&0x7fff);
}
else
{
int quad_idx = color*6;
for(;;)
{
uint8_t code = m_pointram[quad_idx++];
color = m_pointram[quad_idx++];
for( j=0; j<4; j++ )
{
uint8_t vi = m_pointram[quad_idx++];
sx[j] = m_poly_frame_width/2 + (int16_t)pSource[vi*3+0];
sy[j] = m_poly_frame_height/2 + (int16_t)pSource[vi*3+1];
zcode[j] = pSource[vi*3+2];
}
m_renderer->draw_quad(sx, sy, zcode, color&0x7fff);
if( code&0x80 )
{ /* end-of-quadlist marker */
break;
}
}
}
m_winrun_poly_index = 0;
}
} /* winrun_flushpoly */
READ16_MEMBER(namcos21_dsp_device::winrun_poly_reset_r)
{
winrun_flush_poly();
return 0;
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dsp_render_w)
{
if( m_winrun_poly_index<WINRUN_MAX_POLY_PARAM )
{
m_winrun_poly_buf[m_winrun_poly_index++] = data;
}
else
{
logerror( "WINRUN_POLY_OVERFLOW\n" );
}
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dsp_pointrom_addr_w)
{
if( offset==0 )
{ /* port 8 */
m_winrun_pointrom_addr = data;
}
else
{ /* port 9 */
m_winrun_pointrom_addr |= (data<<16);
}
}
READ16_MEMBER(namcos21_dsp_device::winrun_dsp_pointrom_data_r)
{
return m_ptrom16[m_winrun_pointrom_addr++];
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dsp_complete_w)
{
if( data )
{
winrun_flush_poly();
m_dsp->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
m_renderer->swap_and_clear_poly_framebuffer();
}
}
READ16_MEMBER(namcos21_dsp_device::winrun_table_r)
{
return m_winrun_polydata[offset];
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dspbios_w)
{
COMBINE_DATA( &m_winrun_dspbios[offset] );
if( offset==0xfff ) // is this the real trigger?
{
m_winrun_dsp_alive = 1;
m_dsp->resume(SUSPEND_REASON_HALT);
}
}
//380000 : read : dsp status? 1 = busy
//380000 : write(0x01) - done before dsp comram init
//380004 : dspcomram bank, as seen by 68k
//380008 : read : state?
READ16_MEMBER(namcos21_dsp_device::winrun_68k_dspcomram_r)
{
int bank = m_winrun_dspcomram_control[0x4/2]&1;
uint16_t *mem = &m_winrun_dspcomram[0x1000*bank];
return mem[offset];
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_68k_dspcomram_w)
{
int bank = m_winrun_dspcomram_control[0x4/2]&1;
uint16_t *mem = &m_winrun_dspcomram[0x1000*bank];
COMBINE_DATA( &mem[offset] );
}
READ16_MEMBER(namcos21_dsp_device::winrun_dspcomram_control_r)
{
return m_winrun_dspcomram_control[offset];
}
WRITE16_MEMBER(namcos21_dsp_device::winrun_dspcomram_control_w)
{
COMBINE_DATA( &m_winrun_dspcomram_control[offset] );
}
void namcos21_dsp_device::winrun_dsp_program(address_map &map)
{
// MCU is used in external program mode, program is uploaded to shared RAM by the 68k
map(0x0000, 0x0fff).ram().share("winrun_dspbios");
}
void namcos21_dsp_device::winrun_dsp_data(address_map &map)
{
map(0x2000, 0x200f).rw(FUNC(namcos21_dsp_device::winrun_cuskey_r), FUNC(namcos21_dsp_device::winrun_cuskey_w));
map(0x4000, 0x4fff).rw(FUNC(namcos21_dsp_device::winrun_dspcomram_r), FUNC(namcos21_dsp_device::winrun_dspcomram_w));
map(0x8000, 0xffff).r(FUNC(namcos21_dsp_device::winrun_table_r));
}
void namcos21_dsp_device::winrun_dsp_io(address_map &map)
{
map(0x08, 0x09).rw(FUNC(namcos21_dsp_device::winrun_dsp_pointrom_data_r), FUNC(namcos21_dsp_device::winrun_dsp_pointrom_addr_w));
map(0x0a, 0x0a).w(FUNC(namcos21_dsp_device::winrun_dsp_render_w));
map(0x0b, 0x0b).nopw();
map(0x0c, 0x0c).w(FUNC(namcos21_dsp_device::winrun_dsp_complete_w));
}
void namcos21_dsp_device::device_add_mconfig(machine_config &config)
{
tms32025_device& dsp(TMS32025(config, m_dsp, 24000000*2)); /* 48 MHz? overclocked */
dsp.set_addrmap(AS_PROGRAM, &namcos21_dsp_device::winrun_dsp_program);
dsp.set_addrmap(AS_DATA, &namcos21_dsp_device::winrun_dsp_data);
dsp.set_addrmap(AS_IO, &namcos21_dsp_device::winrun_dsp_io);
dsp.bio_in_cb().set(FUNC(namcos21_dsp_device::winrun_poly_reset_r));
dsp.hold_in_cb().set_constant(0);
dsp.hold_ack_out_cb().set_nop();
dsp.xf_out_cb().set_nop();
}
WRITE16_MEMBER(namcos21_dsp_device::pointram_control_w)
{
COMBINE_DATA( &m_pointram_control );
m_pointram_idx = 0; /* HACK */
}
READ16_MEMBER(namcos21_dsp_device::pointram_data_r)
{
return m_pointram[m_pointram_idx];
}
WRITE16_MEMBER(namcos21_dsp_device::pointram_data_w)
{
if( ACCESSING_BITS_0_7 )
{
m_pointram[m_pointram_idx++] = data;
m_pointram_idx &= (PTRAM_SIZE-1);
}
}

View File

@ -0,0 +1,85 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_VIDEO_NAMCOS21_DSP_H
#define MAME_VIDEO_NAMCOS21_DSP_H
#pragma once
#include "cpu/tms32025/tms32025.h"
#include "video/namcos21_3d.h"
#define WINRUN_MAX_POLY_PARAM (1+256*3)
#define PTRAM_SIZE 0x20000
class namcos21_dsp_device : public device_t
{
public:
namcos21_dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// config
template <typename T> void set_renderer_tag(T &&tag) { m_renderer.set_tag(std::forward<T>(tag)); }
DECLARE_WRITE16_MEMBER(winrun_dspbios_w);
DECLARE_READ16_MEMBER(winrun_68k_dspcomram_r);
DECLARE_WRITE16_MEMBER(winrun_68k_dspcomram_w);
DECLARE_READ16_MEMBER(winrun_dspcomram_control_r);
DECLARE_WRITE16_MEMBER(winrun_dspcomram_control_w);
DECLARE_WRITE16_MEMBER(pointram_control_w);
DECLARE_READ16_MEMBER(pointram_data_r);
DECLARE_WRITE16_MEMBER(pointram_data_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
void winrun_dsp_data(address_map &map);
void winrun_dsp_io(address_map &map);
void winrun_dsp_program(address_map &map);
private:
required_device<cpu_device> m_dsp;
required_shared_ptr<uint16_t> m_winrun_dspbios;
required_shared_ptr<uint16_t> m_winrun_polydata;
required_region_ptr<uint16_t> m_ptrom16;
required_device<namcos21_3d_device> m_renderer;
std::unique_ptr<uint8_t[]> m_pointram;
int m_pointram_idx;
uint16_t m_pointram_control;
uint16_t m_winrun_dspcomram_control[8];
std::unique_ptr<uint16_t[]> m_winrun_dspcomram;
uint16_t m_winrun_poly_buf[WINRUN_MAX_POLY_PARAM];
int m_winrun_poly_index;
uint32_t m_winrun_pointrom_addr;
int m_winrun_dsp_alive;
void winrun_flush_poly();
int m_poly_frame_width;
int m_poly_frame_height;
DECLARE_READ16_MEMBER(winrun_cuskey_r);
DECLARE_WRITE16_MEMBER(winrun_cuskey_w);
DECLARE_READ16_MEMBER(winrun_dspcomram_r);
DECLARE_WRITE16_MEMBER(winrun_dspcomram_w);
DECLARE_READ16_MEMBER(winrun_table_r);
DECLARE_WRITE16_MEMBER(winrun_dsp_complete_w);
DECLARE_WRITE16_MEMBER(winrun_dsp_render_w);
DECLARE_READ16_MEMBER(winrun_poly_reset_r);
DECLARE_WRITE16_MEMBER(winrun_dsp_pointrom_addr_w);
DECLARE_READ16_MEMBER(winrun_dsp_pointrom_data_r);
TIMER_CALLBACK_MEMBER(suspend_callback);
emu_timer *m_suspend_timer;
};
DECLARE_DEVICE_TYPE(NAMCOS21_DSP, namcos21_dsp_device)
#endif // MAME_VIDEO_NAMCOS21_DSP_H

View File

@ -0,0 +1,769 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino, David Haywood
/*
Common code for the later Namco System 21 DSP board 5 TMS320C25 DSPs with custom Namco programming (marked C67) in a 1x Master, 4x Slave configuration
used by Star Blade, Cybersled
TODO: handle protection properly and with callbacks
handle splitting of workload across slaves
remove hacks!
some of the list processing should probably be in the 3d device, split it out
*/
#include "emu.h"
#include "namcos21_dsp_c67.h"
DEFINE_DEVICE_TYPE(NAMCOS21_DSP_C67, namcos21_dsp_c67_device, "namcos21_dsp_c67_device", "Namco System 21 DSP Setup (5x C67 type)")
namcos21_dsp_c67_device::namcos21_dsp_c67_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCOS21_DSP_C67, tag, owner, clock),
m_renderer(*this, finder_base::DUMMY_TAG),
m_c67master(*this, "dspmaster"),
m_c67slave(*this, "dspslave%u", 0U),
m_ptrom24(*this,"point24"),
m_master_dsp_ram(*this,"master_dsp_ram"),
m_gametype(0),
m_yield_hack_cb(*this),
m_irq_enable(false)
{
}
void namcos21_dsp_c67_device::device_start()
{
m_dspram16.resize(0x10000/2); // 0x8000 16-bit words
std::fill(std::begin(m_dspram16), std::end(m_dspram16), 0x0000);
m_yield_hack_cb.resolve_safe();
m_pointram = std::make_unique<uint8_t[]>(PTRAM_SIZE);
m_mpDspState = make_unique_clear<dsp_state>();
save_item(NAME(m_dspram16));
}
void namcos21_dsp_c67_device::device_reset()
{
m_poly_frame_width = m_renderer->get_width();
m_poly_frame_height = m_renderer->get_height();
/* DSP startup hacks */
m_mbNeedsKickstart = 20;
if (m_gametype == NAMCOS21_CYBERSLED)
{
m_mbNeedsKickstart = 200;
}
/* Wipe the framebuffers */
m_renderer->swap_and_clear_poly_framebuffer();
m_renderer->swap_and_clear_poly_framebuffer();
//reset_dsps(ASSERT_LINE);
m_mpDspState->masterSourceAddr = 0;
m_mpDspState->slaveBytesAvailable = 0;
m_mpDspState->slaveBytesAdvertised = 0;
m_mpDspState->slaveInputStart = 0;
m_mpDspState->slaveOutputSize = 0;
m_mpDspState->masterDirectDrawSize = 0;
m_mpDspState->masterFinished = 0;
m_mpDspState->slaveActive = 0;
m_pointram_idx = 0;
m_pointram_control = 0;
m_pointrom_idx = 0;
m_mPointRomMSB = 0;
m_mbPointRomDataAvailable = 0;
m_irq_enable = 0;
// clear these?
//m_depthcue[2][0x400];
//m_pointram
//m_mpDspState->slaveInputBuffer[DSP_BUF_MAX];
//m_mpDspState->slaveOutputBuffer[DSP_BUF_MAX];
//m_mpDspState->masterDirectDrawBuffer[256];
}
void namcos21_dsp_c67_device::reset_dsps(int state)
{
if (m_c67master)
m_c67master->set_input_line(INPUT_LINE_RESET, state);
if (m_c67slave[0])
m_c67slave[0]->set_input_line(INPUT_LINE_RESET, state);
}
void namcos21_dsp_c67_device::reset_kickstart()
{
//printf( "dspkick=0x%x\n", data );
namcos21_kickstart_hacks(1);
}
void namcos21_dsp_c67_device::device_add_mconfig(machine_config &config)
{
namco_c67_device& dspmaster(NAMCO_C67(config, m_c67master, 24000000)); /* 24 MHz? overclocked */
dspmaster.set_addrmap(AS_PROGRAM, &namcos21_dsp_c67_device::master_dsp_program);
dspmaster.set_addrmap(AS_DATA, &namcos21_dsp_c67_device::master_dsp_data);
dspmaster.set_addrmap(AS_IO, &namcos21_dsp_c67_device::master_dsp_io);
dspmaster.hold_in_cb().set_constant(0);
dspmaster.hold_ack_out_cb().set_nop();
dspmaster.xf_out_cb().set(FUNC(namcos21_dsp_c67_device::dsp_xf_w));
for (int i = 0; i < 4; i++)
{
namco_c67_device& dspslave(NAMCO_C67(config, m_c67slave[i], 24000000)); /* 24 MHz? overclocked */
dspslave.set_addrmap(AS_PROGRAM, &namcos21_dsp_c67_device::slave_dsp_program);
dspslave.set_addrmap(AS_DATA, &namcos21_dsp_c67_device::slave_dsp_data);
dspslave.set_addrmap(AS_IO, &namcos21_dsp_c67_device::slave_dsp_io);
dspslave.hold_in_cb().set_constant(0);
dspslave.hold_ack_out_cb().set_nop();
dspslave.xf_out_cb().set(FUNC(namcos21_dsp_c67_device::slave_XF_output_w));
// the emulation currently only uses one slave DSP clocked at 4x the normal rate instead of the master splitting the workload across the 4 slaves
if (i!=0)
dspslave.set_disable();
else
dspslave.set_clock(24000000*4);
}
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dspcuskey_w)
{ /* TODO: proper cuskey emulation */
}
READ16_MEMBER(namcos21_dsp_c67_device::dspcuskey_r)
{
uint16_t result = 0;
if( m_gametype == NAMCOS21_SOLVALOU )
{
switch( m_c67master->pc() )
{
case 0x805e: result = 0x0000; break;
case 0x805f: result = 0xfeba; break;
case 0x8067: result = 0xffff; break;
case 0x806e: result = 0x0145; break;
default:
logerror( "unk cuskey_r; pc=0x%x\n", m_c67master->pc() );
break;
}
}
else if( m_gametype == NAMCOS21_CYBERSLED )
{
switch( m_c67master->pc() )
{
case 0x8061: result = 0xfe95; break;
case 0x8069: result = 0xffff; break;
case 0x8070: result = 0x016A; break;
default:
break;
}
}
else if( m_gametype == NAMCOS21_AIRCOMBAT )
{
switch( m_c67master->pc() )
{
case 0x8062: result = 0xfeb9; break;
case 0x806a: result = 0xffff; break;
case 0x8071: result = 0x0146; break;
default:
break;
}
}
return result;
}
void namcos21_dsp_c67_device::transmit_word_to_slave(uint16_t data)
{
unsigned offs = m_mpDspState->slaveInputStart+m_mpDspState->slaveBytesAvailable++;
m_mpDspState->slaveInputBuffer[offs%DSP_BUF_MAX] = data;
if (ENABLE_LOGGING) logerror( "+%04x(#%04x)\n", data, m_mpDspState->slaveBytesAvailable );
m_mpDspState->slaveActive = 1;
if( m_mpDspState->slaveBytesAvailable >= DSP_BUF_MAX )
{
fatalerror( "IDC overflow\n" );
}
}
void namcos21_dsp_c67_device::transfer_dsp_data()
{
uint16_t addr = m_mpDspState->masterSourceAddr;
int mode = addr&0x8000;
addr&=0x7fff;
if( addr )
{
for(;;)
{
int i;
uint16_t old = addr;
uint16_t code = m_dspram16[addr++];
if( code == 0xffff )
{
if( mode )
{
addr = m_dspram16[addr];
m_mpDspState->masterSourceAddr = addr;
if (ENABLE_LOGGING) logerror( "LOOP:0x%04x\n", addr );
addr&=0x7fff;
if( old==addr )
{
return;
}
}
else
{
m_mpDspState->masterSourceAddr = 0;
return;
}
}
else if( mode==0 )
{ /* direct data transfer */
if (ENABLE_LOGGING) logerror( "DATA TFR(0x%x)\n", code );
transmit_word_to_slave(code);
for( i=0; i<code; i++ )
{
uint16_t data = m_dspram16[addr++];
transmit_word_to_slave(data);
}
}
else if( code==0x18 || code==0x1a )
{
if (ENABLE_LOGGING) logerror( "HEADER TFR(0x%x)\n", code );
transmit_word_to_slave(code+1);
for( i=0; i<code; i++ )
{
uint16_t data = m_dspram16[addr++];
transmit_word_to_slave(data);
}
}
else
{
int32_t masterAddr = read_pointrom_data(code);
if (ENABLE_LOGGING) logerror( "OBJ TFR(0x%x)\n", code );
{
uint16_t len = m_dspram16[addr++];
for(;;)
{
int subAddr = read_pointrom_data(masterAddr++);
if( subAddr==0xffffff )
{
break;
}
else
{
int primWords = (uint16_t)read_pointrom_data(subAddr++);
// TODO: this function causes an IDC overflow in Solvalou, something else failed prior to that?
// In Header TFR when bad parameters happens there's a suspicious 0x000f 0x0003 as first two words,
// maybe it's supposed to have a different length there ...
// cfr: object code 0x17 in service mode
if( primWords>2 )
{
transmit_word_to_slave(0); /* pad1 */
transmit_word_to_slave(len+1);
for( i=0; i<len; i++ )
{ /* transform */
transmit_word_to_slave(m_dspram16[addr+i]);
}
transmit_word_to_slave(0); /* pad2 */
transmit_word_to_slave(primWords+1);
for( i=0; i<primWords; i++ )
{
transmit_word_to_slave((uint16_t)read_pointrom_data(subAddr+i));
}
}
else
{
if (ENABLE_LOGGING) logerror( "TFR NOP?\n" );
}
}
} /* for(;;) */
addr+=len;
}
}
} /* for(;;) */
}
}
void namcos21_dsp_c67_device::namcos21_kickstart_hacks(int internal)
{
/* patch dsp watchdog */
switch (m_gametype)
{
case namcos21_dsp_c67_device::NAMCOS21_AIRCOMBAT:
m_master_dsp_ram[0x008e] = 0x808f;
break;
case namcos21_dsp_c67_device::NAMCOS21_SOLVALOU:
m_master_dsp_ram[0x008b] = 0x808c;
break;
default:
break;
}
if (internal)
{
if (m_mbNeedsKickstart == 0) return;
m_mbNeedsKickstart--;
if (m_mbNeedsKickstart) return;
}
m_renderer->swap_and_clear_poly_framebuffer();
m_mpDspState->masterSourceAddr = 0;
m_mpDspState->slaveOutputSize = 0;
m_mpDspState->masterFinished = 0;
m_mpDspState->slaveActive = 0;
m_c67master->set_input_line(0, HOLD_LINE);
m_c67slave[0]->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
}
uint16_t namcos21_dsp_c67_device::read_word_from_slave_input()
{
uint16_t data = 0;
if( m_mpDspState->slaveBytesAvailable>0 )
{
data = m_mpDspState->slaveInputBuffer[m_mpDspState->slaveInputStart++];
m_mpDspState->slaveInputStart %= DSP_BUF_MAX;
m_mpDspState->slaveBytesAvailable--;
if( m_mpDspState->slaveBytesAdvertised>0 )
{
m_mpDspState->slaveBytesAdvertised--;
}
if (ENABLE_LOGGING) logerror( "%s:-%04x(0x%04x)\n", machine().describe_context(), data, m_mpDspState->slaveBytesAvailable );
}
return data;
}
uint16_t namcos21_dsp_c67_device::get_input_bytes_advertised_for_slave()
{
if( m_mpDspState->slaveBytesAdvertised < m_mpDspState->slaveBytesAvailable )
{
m_mpDspState->slaveBytesAdvertised++;
}
else if( m_mpDspState->slaveActive && m_mpDspState->masterFinished && m_mpDspState->masterSourceAddr )
{
namcos21_kickstart_hacks(0);
}
return m_mpDspState->slaveBytesAdvertised;
}
READ16_MEMBER(namcos21_dsp_c67_device::dspram16_r)
{
return m_dspram16[offset];
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dspram16_hack_w)
{
COMBINE_DATA(&m_dspram16[offset]);
if (m_mpDspState->masterSourceAddr && offset == 1 + (m_mpDspState->masterSourceAddr & 0x7fff))
{
if (ENABLE_LOGGING) logerror("IDC-CONTINUE\n");
transfer_dsp_data();
}
else if (m_gametype == NAMCOS21_SOLVALOU && offset == 0x103)
{
// HACK: synchronization for solvalou - is this really needed?
m_yield_hack_cb(1);
}
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dspram16_w)
{
COMBINE_DATA(&m_dspram16[offset]);
if (m_mpDspState->masterSourceAddr && offset == 1 + (m_mpDspState->masterSourceAddr & 0x7fff))
{
if (ENABLE_LOGGING) logerror("IDC-CONTINUE\n");
transfer_dsp_data();
}
}
/***********************************************************/
int32_t namcos21_dsp_c67_device::read_pointrom_data(unsigned offset)
{
return m_ptrom24[offset];
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port0_r)
{
int32_t data = read_pointrom_data(m_pointrom_idx++);
m_mPointRomMSB = (uint8_t)(data>>16);
m_mbPointRomDataAvailable = 1;
return (uint16_t)data;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port0_w)
{ /* unused? */
if (ENABLE_LOGGING) logerror( "PTRAM_LO(0x%04x)\n", data );
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port1_r)
{
if( m_mbPointRomDataAvailable )
{
m_mbPointRomDataAvailable = 0;
return m_mPointRomMSB;
}
return 0x8000; /* IDC ack? */
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port1_w)
{ /* unused? */
if (ENABLE_LOGGING) logerror( "PTRAM_HI(0x%04x)\n", data );
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port2_r)
{ /* IDC TRANSMIT ENABLE? */
return 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port2_w)
{
if (ENABLE_LOGGING) logerror( "IDC ADDR INIT(0x%04x)\n", data );
m_mpDspState->masterSourceAddr = data;
transfer_dsp_data();
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port3_idc_rcv_enable_r)
{ /* IDC RECEIVE ENABLE? */
return 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port3_w)
{
m_pointrom_idx<<=16;
m_pointrom_idx|=data;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port4_w)
{ /* receives $0B<<4 prior to IDC setup */
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port8_r)
{ /* SMU status */
return 1;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port8_w)
{
if (ENABLE_LOGGING) logerror( "port8_w(%d)\n", data );
if( data )
{
m_mpDspState->masterFinished = 1;
}
m_irq_enable = data;
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_port9_r)
{ /* render-device-busy; used for direct-draw */
return 0;
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_porta_r)
{ /* config */
return 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_porta_w)
{
/* boot: 1 */
/* IRQ0 end: 0 */
/* INT2 begin: 1 */
/* direct-draw begin: 0 */
/* INT1 begin: 1 */
// if (ENABLE_LOGGING) logerror( "dsp_porta_w(0x%04x)\n", data );
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_portb_r)
{ /* config */
return 1;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_portb_w)
{
if( data==0 )
{ /* only 0->1 transition triggers */
return;
}
if( m_mpDspState->masterDirectDrawSize == 13 )
{
int i;
int sx[4], sy[4], zcode[4];
int color = m_mpDspState->masterDirectDrawBuffer[0];
for( i=0; i<4; i++ )
{
sx[i] = m_poly_frame_width/2 + (int16_t)m_mpDspState->masterDirectDrawBuffer[i*3+1];
sy[i] = m_poly_frame_height/2 + (int16_t)m_mpDspState->masterDirectDrawBuffer[i*3+2];
zcode[i] = m_mpDspState->masterDirectDrawBuffer[i*3+3];
}
if( color&0x8000 )
{
m_renderer->draw_quad(sx, sy, zcode, color);
}
else
{
logerror( "indirection used w/ direct draw?\n" );
}
}
else if( m_mpDspState->masterDirectDrawSize )
{
logerror( "unexpected masterDirectDrawSize=%d!\n",m_mpDspState->masterDirectDrawSize );
}
m_mpDspState->masterDirectDrawSize = 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_portc_w)
{
if( m_mpDspState->masterDirectDrawSize < DSP_BUF_MAX )
{
m_mpDspState->masterDirectDrawBuffer[m_mpDspState->masterDirectDrawSize++] = data;
}
else
{
logerror( "portc overflow\n" );
}
}
READ16_MEMBER(namcos21_dsp_c67_device::dsp_portf_r)
{ /* informs BIOS that this is Master DSP */
return 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_xf_w)
{
if (ENABLE_LOGGING) logerror("xf(%d)\n",data);
}
void namcos21_dsp_c67_device::master_dsp_program(address_map &map)
{
map(0x8000, 0xbfff).ram().share("master_dsp_ram");
}
void namcos21_dsp_c67_device::master_dsp_data(address_map &map)
{
map(0x2000, 0x200f).rw(FUNC(namcos21_dsp_c67_device::dspcuskey_r), FUNC(namcos21_dsp_c67_device::dspcuskey_w));
map(0x8000, 0xffff).rw(FUNC(namcos21_dsp_c67_device::dspram16_r), FUNC(namcos21_dsp_c67_device::dspram16_w)); /* 0x8000 words */
}
void namcos21_dsp_c67_device::master_dsp_io(address_map &map)
{
map(0x00, 0x00).rw(FUNC(namcos21_dsp_c67_device::dsp_port0_r), FUNC(namcos21_dsp_c67_device::dsp_port0_w));
map(0x01, 0x01).rw(FUNC(namcos21_dsp_c67_device::dsp_port1_r), FUNC(namcos21_dsp_c67_device::dsp_port1_w));
map(0x02, 0x02).rw(FUNC(namcos21_dsp_c67_device::dsp_port2_r), FUNC(namcos21_dsp_c67_device::dsp_port2_w));
map(0x03, 0x03).rw(FUNC(namcos21_dsp_c67_device::dsp_port3_idc_rcv_enable_r), FUNC(namcos21_dsp_c67_device::dsp_port3_w));
map(0x04, 0x04).w(FUNC(namcos21_dsp_c67_device::dsp_port4_w));
map(0x08, 0x08).rw(FUNC(namcos21_dsp_c67_device::dsp_port8_r), FUNC(namcos21_dsp_c67_device::dsp_port8_w));
map(0x09, 0x09).r(FUNC(namcos21_dsp_c67_device::dsp_port9_r));
map(0x0a, 0x0a).rw(FUNC(namcos21_dsp_c67_device::dsp_porta_r), FUNC(namcos21_dsp_c67_device::dsp_porta_w));
map(0x0b, 0x0b).rw(FUNC(namcos21_dsp_c67_device::dsp_portb_r), FUNC(namcos21_dsp_c67_device::dsp_portb_w));
map(0x0c, 0x0c).w(FUNC(namcos21_dsp_c67_device::dsp_portc_w));
map(0x0f, 0x0f).r(FUNC(namcos21_dsp_c67_device::dsp_portf_r));
}
/************************************************************************************/
void namcos21_dsp_c67_device::render_slave_output(uint16_t data)
{
if( m_mpDspState->slaveOutputSize >= 4096 )
{
fatalerror( "SLAVE OVERFLOW (0x%x)\n",m_mpDspState->slaveOutputBuffer[0] );
}
/* append word to slave output buffer */
m_mpDspState->slaveOutputBuffer[m_mpDspState->slaveOutputSize++] = data;
{
uint16_t *pSource = m_mpDspState->slaveOutputBuffer;
uint16_t count = *pSource++;
if( count && m_mpDspState->slaveOutputSize > count )
{
uint16_t color = *pSource++;
int sx[4], sy[4],zcode[4];
int j;
if( color&0x8000 )
{
if( count!=13 ) logerror( "?!direct-draw(%d)\n", count );
for( j=0; j<4; j++ )
{
sx[j] = m_poly_frame_width/2 + (int16_t)pSource[3*j+0];
sy[j] = m_poly_frame_height/2 + (int16_t)pSource[3*j+1];
zcode[j] = pSource[3*j+2];
}
m_renderer->draw_quad(sx, sy, zcode, color&0x7fff);
}
else
{
int quad_idx = color*6;
for(;;)
{
uint8_t code = m_pointram[quad_idx++];
color = m_pointram[quad_idx++]|(code<<8);
for( j=0; j<4; j++ )
{
uint8_t vi = m_pointram[quad_idx++];
sx[j] = m_poly_frame_width/2 + (int16_t)pSource[vi*3+0];
sy[j] = m_poly_frame_height/2 + (int16_t)pSource[vi*3+1];
zcode[j] = pSource[vi*3+2];
}
m_renderer->draw_quad(sx, sy, zcode, color&0x7fff);
if( code&0x80 )
{ /* end-of-quadlist marker */
break;
}
}
}
m_mpDspState->slaveOutputSize = 0;
}
else if( count==0 )
{
fatalerror( "RenderSlaveOutput\n" );
}
}
}
READ16_MEMBER(namcos21_dsp_c67_device::slave_port0_r)
{
return read_word_from_slave_input();
}
WRITE16_MEMBER(namcos21_dsp_c67_device::slave_port0_w)
{
render_slave_output(data);
}
READ16_MEMBER(namcos21_dsp_c67_device::slave_port2_r)
{
return get_input_bytes_advertised_for_slave();
}
READ16_MEMBER(namcos21_dsp_c67_device::slave_port3_r)
{ /* render-device queue size */
/* up to 0x1fe bytes?
* slave blocks until free &space exists
*/
return 0;
}
WRITE16_MEMBER(namcos21_dsp_c67_device::slave_port3_w)
{ /* 0=busy, 1=ready? */
}
WRITE16_MEMBER(namcos21_dsp_c67_device::slave_XF_output_w)
{
if (ENABLE_LOGGING) logerror( "%s :slaveXF(%d)\n", machine().describe_context(), data );
}
READ16_MEMBER(namcos21_dsp_c67_device::slave_portf_r)
{ /* informs BIOS that this is Slave DSP */
return 1;
}
void namcos21_dsp_c67_device::slave_dsp_program(address_map &map)
{
map(0x8000, 0x8fff).ram();
}
void namcos21_dsp_c67_device::slave_dsp_data(address_map &map)
{
/* no external data memory */
}
void namcos21_dsp_c67_device::slave_dsp_io(address_map &map)
{
map(0x00, 0x00).rw(FUNC(namcos21_dsp_c67_device::slave_port0_r), FUNC(namcos21_dsp_c67_device::slave_port0_w));
map(0x02, 0x02).r(FUNC(namcos21_dsp_c67_device::slave_port2_r));
map(0x03, 0x03).rw(FUNC(namcos21_dsp_c67_device::slave_port3_r), FUNC(namcos21_dsp_c67_device::slave_port3_w));
map(0x0f, 0x0f).r(FUNC(namcos21_dsp_c67_device::slave_portf_r));
}
/************************************************************************************/
/**
* 801f->800f : prepare for master access to point ram
* 801f : done
*
* #bits data line
* 8 1a0 4
* 7 0f8 4
* 7 0ff 4
* 1 001 4
* 7 00a 2
* a 0fe 8
*
* line #bits data
* 0003 000A 000004FE
* 0001 0007 0000000A
* 0002 001A 03FFF1A0
*/
WRITE16_MEMBER(namcos21_dsp_c67_device::pointram_control_w)
{
// uint16_t prev = m_pointram_control;
COMBINE_DATA( &m_pointram_control );
/* m_pointram_control&0x20 : bank for depthcue data */
#if 0
logerror( "%s dsp_control_w:[%x]:=%04x ",
machine().describe_context(),
offset,
m_pointram_control );
uint16_t delta = (prev^m_pointram_control)&m_pointram_control;
if( delta&0x10 )
{
logerror( " [reset]" );
}
if( delta&2 )
{
logerror( " send(A)%x", m_pointram_control&1 );
}
if( delta&4 )
{
logerror( " send(B)%x", m_pointram_control&1 );
}
if( delta&8 )
{
logerror( " send(C)%x", m_pointram_control&1 );
}
logerror( "\n" );
#endif
m_pointram_idx = 0; /* HACK */
}
READ16_MEMBER(namcos21_dsp_c67_device::pointram_data_r)
{
return m_pointram[m_pointram_idx];
}
WRITE16_MEMBER(namcos21_dsp_c67_device::pointram_data_w)
{
if( ACCESSING_BITS_0_7 )
{
// if( (m_pointram_idx%6)==0 ) logerror("\n" );
// logerror( " %02x", data );
m_pointram[m_pointram_idx++] = data;
m_pointram_idx &= (PTRAM_SIZE-1);
}
}
READ16_MEMBER(namcos21_dsp_c67_device::namcos21_depthcue_r)
{
int bank = (m_pointram_control&0x20)?1:0;
return m_depthcue[bank][offset];
}
WRITE16_MEMBER(namcos21_dsp_c67_device::namcos21_depthcue_w)
{
if( ACCESSING_BITS_0_7 )
{
int bank = (m_pointram_control&0x20)?1:0;
m_depthcue[bank][offset] = data;
// if( (offset&0xf)==0 ) logerror( "\n depthcue: " );
// logerror( " %02x", data );
}
}

View File

@ -0,0 +1,147 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_VIDEO_NAMCOS21_DSP_C67_H
#define MAME_VIDEO_NAMCOS21_DSP_C67_H
#pragma once
#include "machine/namco_c67.h"
#include "video/namcos21_3d.h"
#define PTRAM_SIZE 0x20000
#define ENABLE_LOGGING 0
class namcos21_dsp_c67_device : public device_t
{
public:
enum
{ /* Namco System21 */
NAMCOS21_AIRCOMBAT = 0x4000,
NAMCOS21_STARBLADE,
NAMCOS21_CYBERSLED,
NAMCOS21_SOLVALOU,
};
namcos21_dsp_c67_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// config
template <typename T> void set_renderer_tag(T &&tag) { m_renderer.set_tag(std::forward<T>(tag)); }
template <class Object> devcb_base &set_yield_hack_callback(Object &&cb) { return m_yield_hack_cb.set_callback(std::forward<Object>(cb)); }
auto yield_hack_callback() { return m_yield_hack_cb.bind(); }
void set_gametype(int gametype) { m_gametype = gametype; }
DECLARE_READ16_MEMBER(dspram16_r);
DECLARE_WRITE16_MEMBER(dspram16_hack_w);
DECLARE_WRITE16_MEMBER(dspram16_w);
DECLARE_WRITE16_MEMBER(pointram_control_w);
DECLARE_READ16_MEMBER(pointram_data_r);
DECLARE_WRITE16_MEMBER(pointram_data_w);
DECLARE_READ16_MEMBER(namcos21_depthcue_r);
DECLARE_WRITE16_MEMBER(namcos21_depthcue_w);
void reset_dsps(int state);
void reset_kickstart();
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
#define DSP_BUF_MAX (4096*12)
struct dsp_state
{
unsigned masterSourceAddr;
uint16_t slaveInputBuffer[DSP_BUF_MAX];
unsigned slaveBytesAvailable;
unsigned slaveBytesAdvertised;
unsigned slaveInputStart;
uint16_t slaveOutputBuffer[DSP_BUF_MAX];
unsigned slaveOutputSize;
uint16_t masterDirectDrawBuffer[256];
unsigned masterDirectDrawSize;
int masterFinished;
int slaveActive;
};
required_device<namcos21_3d_device> m_renderer;
required_device<cpu_device> m_c67master;
required_device_array<cpu_device,4> m_c67slave;
required_region_ptr<int32_t> m_ptrom24;
std::vector<uint16_t> m_dspram16;
required_shared_ptr<uint16_t> m_master_dsp_ram;
int m_gametype; // hacks
devcb_write_line m_yield_hack_cb;
std::unique_ptr<dsp_state> m_mpDspState;
std::unique_ptr<uint8_t[]> m_pointram;
int m_pointram_idx;
uint16_t m_pointram_control;
uint32_t m_pointrom_idx;
uint8_t m_mPointRomMSB;
int m_mbPointRomDataAvailable;
uint8_t m_depthcue[2][0x400];
int m_irq_enable;
int m_mbNeedsKickstart;
int m_poly_frame_width;
int m_poly_frame_height;
int32_t read_pointrom_data(unsigned offset);
void transmit_word_to_slave(uint16_t data);
void transfer_dsp_data();
uint16_t read_word_from_slave_input();
uint16_t get_input_bytes_advertised_for_slave();
void render_slave_output(uint16_t data);
void namcos21_kickstart_hacks(int internal);
DECLARE_WRITE16_MEMBER(dspcuskey_w);
DECLARE_READ16_MEMBER(dspcuskey_r);
DECLARE_READ16_MEMBER(dsp_port0_r);
DECLARE_WRITE16_MEMBER(dsp_port0_w);
DECLARE_READ16_MEMBER(dsp_port1_r);
DECLARE_WRITE16_MEMBER(dsp_port1_w);
DECLARE_READ16_MEMBER(dsp_port2_r);
DECLARE_WRITE16_MEMBER(dsp_port2_w);
DECLARE_READ16_MEMBER(dsp_port3_idc_rcv_enable_r);
DECLARE_WRITE16_MEMBER(dsp_port3_w);
DECLARE_WRITE16_MEMBER(dsp_port4_w);
DECLARE_READ16_MEMBER(dsp_port8_r);
DECLARE_WRITE16_MEMBER(dsp_port8_w);
DECLARE_READ16_MEMBER(dsp_port9_r);
DECLARE_READ16_MEMBER(dsp_porta_r);
DECLARE_WRITE16_MEMBER(dsp_porta_w);
DECLARE_READ16_MEMBER(dsp_portb_r);
DECLARE_WRITE16_MEMBER(dsp_portb_w);
DECLARE_WRITE16_MEMBER(dsp_portc_w);
DECLARE_READ16_MEMBER(dsp_portf_r);
DECLARE_WRITE16_MEMBER(dsp_xf_w);
DECLARE_READ16_MEMBER(slave_port0_r);
DECLARE_WRITE16_MEMBER(slave_port0_w);
DECLARE_READ16_MEMBER(slave_port2_r);
DECLARE_READ16_MEMBER(slave_port3_r);
DECLARE_WRITE16_MEMBER(slave_port3_w);
DECLARE_WRITE16_MEMBER(slave_XF_output_w);
DECLARE_READ16_MEMBER(slave_portf_r);
void master_dsp_data(address_map &map);
void master_dsp_io(address_map &map);
void master_dsp_program(address_map &map);
void slave_dsp_data(address_map &map);
void slave_dsp_io(address_map &map);
void slave_dsp_program(address_map &map);
};
DECLARE_DEVICE_TYPE(NAMCOS21_DSP_C67, namcos21_dsp_c67_device)
#endif // MAME_VIDEO_NAMCOS21_DSP_C67_H

View File

@ -29191,7 +29191,7 @@ valkyrie // (c) 1989 (Japan)
aircomb // (c) 1992 (US)
aircombj // (c) 1992 (Japan)
cybsled // (c) 1993 (World)
cybsledj // (c) 1993 (Japan)
cybsleda // (c) 1993 (World)
driveyes // (c) 1992?
solvalou // (c) 1991 (Japan)
starblad // (c) 1991 (World)

View File

@ -1,471 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino
/***************************************************************************
Namco System 21 Video Hardware
- sprite hardware is identical to Namco System NB1
- there are no tilemaps
- 3d graphics are managed by DSP processors
*/
/* Palette:
0x0000..0x1fff sprite palettes (0x10 sets of 0x100 colors)
0x2000..0x3fff polygon palette bank0 (0x10 sets of 0x200 colors)
(in starblade, some palette animation effects are performed here)
0x4000..0x5fff polygon palette bank1 (0x10 sets of 0x200 colors)
0x6000..0x7fff polygon palette bank2 (0x10 sets of 0x200 colors)
The polygon-dedicated color sets within a bank typically increase in
intensity from very dark to full intensity.
Probably the selected palette is determined by most significant bits of z-code.
This is not yet hooked up.
*/
#include "emu.h"
#include "includes/namcos21.h"
#define FRAMEBUFFER_SIZE_IN_BYTES (sizeof(uint16_t)*NAMCOS21_POLY_FRAME_WIDTH*NAMCOS21_POLY_FRAME_HEIGHT)
READ16_MEMBER(namcos21_state::winrun_gpu_color_r)
{
return m_winrun_color;
}
WRITE16_MEMBER(namcos21_state::winrun_gpu_color_w)
{
COMBINE_DATA( &m_winrun_color );
}
READ16_MEMBER(namcos21_state::winrun_gpu_register_r)
{
return m_winrun_gpu_register[offset];
}
WRITE16_MEMBER(namcos21_state::winrun_gpu_register_w)
{
COMBINE_DATA( &m_winrun_gpu_register[offset] );
m_screen->update_partial(m_screen->vpos());
}
WRITE16_MEMBER(namcos21_state::winrun_gpu_videoram_w)
{
int color = data>>8;
int mask = data&0xff;
int i;
for( i=0; i<8; i++ )
{
if( mask&(0x01<<i) )
{
m_videoram[(offset+i)&0x7ffff] = color;
m_maskram[(offset+i)&0x7ffff] = mask;
}
}
}
READ16_MEMBER(namcos21_state::winrun_gpu_videoram_r)
{
return (m_videoram[offset]<<8) | m_maskram[offset];
}
void namcos21_state::allocate_poly_framebuffer()
{
m_mpPolyFrameBufferZ = std::make_unique<uint16_t[]>(FRAMEBUFFER_SIZE_IN_BYTES/2 );
m_mpPolyFrameBufferPens = std::make_unique<uint16_t[]>(FRAMEBUFFER_SIZE_IN_BYTES/2 );
m_mpPolyFrameBufferZ2 = std::make_unique<uint16_t[]>(FRAMEBUFFER_SIZE_IN_BYTES/2 );
m_mpPolyFrameBufferPens2 = std::make_unique<uint16_t[]>(FRAMEBUFFER_SIZE_IN_BYTES/2 );
clear_poly_framebuffer();
clear_poly_framebuffer();
}
void namcos21_state::clear_poly_framebuffer()
{
/* swap work and visible framebuffers */
m_mpPolyFrameBufferZ.swap(m_mpPolyFrameBufferZ2);
m_mpPolyFrameBufferPens.swap(m_mpPolyFrameBufferPens2);
/* wipe work zbuffer */
for( int i = 0; i < NAMCOS21_POLY_FRAME_WIDTH*NAMCOS21_POLY_FRAME_HEIGHT; i++ )
{
m_mpPolyFrameBufferZ[i] = 0x7fff;
}
}
void namcos21_state::copy_visible_poly_framebuffer(bitmap_ind16 &bitmap, const rectangle &clip, int zlo, int zhi)
{
/* blit the visible framebuffer */
int sy;
for( sy=clip.top(); sy<=clip.bottom(); sy++ )
{
uint16_t *dest = &bitmap.pix16(sy);
const uint16_t *pPen = m_mpPolyFrameBufferPens2.get()+NAMCOS21_POLY_FRAME_WIDTH*sy;
const uint16_t *pZ = m_mpPolyFrameBufferZ2.get()+NAMCOS21_POLY_FRAME_WIDTH*sy;
int sx;
for( sx=clip.left(); sx<=clip.right(); sx++ )
{
int z = pZ[sx];
//if( pZ[sx]!=0x7fff )
if( z>=zlo && z<=zhi )
{
dest[sx] = pPen[sx];
}
}
}
}
/*********************************************************************************************/
#define SWAP(T,A,B) { const T *temp = A; A = B; B = temp; }
void namcos21_state::renderscanline_flat(const edge *e1, const edge *e2, int sy, unsigned color, int depthcueenable)
{
if( e1->x > e2->x )
{
SWAP(edge,e1,e2);
}
{
uint16_t *pDest = m_mpPolyFrameBufferPens.get() + sy*NAMCOS21_POLY_FRAME_WIDTH;
uint16_t *pZBuf = m_mpPolyFrameBufferZ.get() + sy*NAMCOS21_POLY_FRAME_WIDTH;
int x0 = (int)e1->x;
int x1 = (int)e2->x;
int w = x1-x0;
if( w )
{
double z = e1->z;
double dz = (e2->z - e1->z)/w;
int x, crop;
crop = - x0;
if( crop>0 )
{
z += crop*dz;
x0 = 0;
}
if( x1>NAMCOS21_POLY_FRAME_WIDTH-1 )
{
x1 = NAMCOS21_POLY_FRAME_WIDTH-1;
}
for( x=x0; x<x1; x++ )
{
uint16_t zz = (uint16_t)z;
if( zz<pZBuf[x] )
{
int pen = color;
if( depthcueenable && zz>0 )
{
int depth = 0;
if( m_gametype == NAMCOS21_WINRUN91 )
{
depth = (zz>>10)*0x100;
pen += depth;
}
else if( m_gametype == NAMCOS21_DRIVERS_EYES )
{
depth = (zz>>10)*0x100;
pen -= depth;
}
else
{
depth = (zz>>11)*0x200;
pen -= depth;
}
}
pDest[x] = pen;
pZBuf[x] = zz;
}
z += dz;
}
}
}
}
void namcos21_state::rendertri(const n21_vertex *v0, const n21_vertex *v1, const n21_vertex *v2, unsigned color, int depthcueenable)
{
int dy,ystart,yend,crop;
/* first, sort so that v0->y <= v1->y <= v2->y */
for(;;)
{
if( v0->y > v1->y )
{
SWAP(n21_vertex,v0,v1);
}
else if( v1->y > v2->y )
{
SWAP(n21_vertex,v1,v2);
}
else
{
break;
}
}
ystart = v0->y;
yend = v2->y;
dy = yend-ystart;
if( dy )
{
int y;
edge e1; /* short edge (top and bottom) */
edge e2; /* long (common) edge */
double dx2dy = (v2->x - v0->x)/dy;
double dz2dy = (v2->z - v0->z)/dy;
double dx1dy;
double dz1dy;
e2.x = v0->x;
e2.z = v0->z;
crop = -ystart;
if( crop>0 )
{
e2.x += dx2dy*crop;
e2.z += dz2dy*crop;
}
ystart = v0->y;
yend = v1->y;
dy = yend-ystart;
if( dy )
{
e1.x = v0->x;
e1.z = v0->z;
dx1dy = (v1->x - v0->x)/dy;
dz1dy = (v1->z - v0->z)/dy;
crop = -ystart;
if( crop>0 )
{
e1.x += dx1dy*crop;
e1.z += dz1dy*crop;
ystart = 0;
}
if( yend>NAMCOS21_POLY_FRAME_HEIGHT-1 ) yend = NAMCOS21_POLY_FRAME_HEIGHT-1;
for( y=ystart; y<yend; y++ )
{
renderscanline_flat(&e1, &e2, y, color, depthcueenable);
e2.x += dx2dy;
e2.z += dz2dy;
e1.x += dx1dy;
e1.z += dz1dy;
}
}
ystart = v1->y;
yend = v2->y;
dy = yend-ystart;
if( dy )
{
e1.x = v1->x;
e1.z = v1->z;
dx1dy = (v2->x - v1->x)/dy;
dz1dy = (v2->z - v1->z)/dy;
crop = -ystart;
if( crop>0 )
{
e1.x += dx1dy*crop;
e1.z += dz1dy*crop;
ystart = 0;
}
if( yend>NAMCOS21_POLY_FRAME_HEIGHT-1 )
{
yend = NAMCOS21_POLY_FRAME_HEIGHT-1;
}
for( y=ystart; y<yend; y++ )
{
renderscanline_flat(&e1, &e2, y, color, depthcueenable);
e2.x += dx2dy;
e2.z += dz2dy;
e1.x += dx1dy;
e1.z += dz1dy;
}
}
}
}
void namcos21_state::draw_quad(int sx[4], int sy[4], int zcode[4], int color)
{
n21_vertex a,b,c,d;
int depthcueenable = 1;
/*
0x0000..0x1fff sprite palettes (0x20 sets of 0x100 colors)
0x2000..0x3fff polygon palette bank0 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
0x4000..0x5fff polygon palette bank1 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
0x6000..0x7fff polygon palette bank2 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
*/
if( m_gametype == NAMCOS21_WINRUN91 )
{
color = 0x4000|(color&0xff);
}
else if ( m_gametype == NAMCOS21_DRIVERS_EYES )
{
color = 0x3f00|(color&0xff);
}
else
{ /* map color code to hardware pen */
int code = color>>8;
if( code&0x80 )
{
color = color&0xff;
// color = 0x3e00|color;
color = 0x2100|color;
depthcueenable = 0;
}
else
{
color&=0xff;
color = 0x3e00|color;
if( (code&0x02)==0 )
{
color|=0x100;
}
}
}
a.x = sx[0];
a.y = sy[0];
a.z = zcode[0];
b.x = sx[1];
b.y = sy[1];
b.z = zcode[1];
c.x = sx[2];
c.y = sy[2];
c.z = zcode[2];
d.x = sx[3];
d.y = sy[3];
d.z = zcode[3];
rendertri(&a, &b, &c, color, depthcueenable);
rendertri(&c, &d, &a, color, depthcueenable);
}
VIDEO_START_MEMBER(namcos21_state,namcos21)
{
if( m_gametype == NAMCOS21_WINRUN91 )
{
m_videoram = std::make_unique<uint8_t[]>(0x80000);
m_maskram = std::make_unique<uint8_t[]>(0x80000);
}
allocate_poly_framebuffer();
}
uint32_t namcos21_state::screen_update_namcos21(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
//uint8_t *videoram = m_videoram.get();
int pivot = 3;
int pri;
bitmap.fill(0xff, cliprect );
m_c355spr->draw(screen, bitmap, cliprect, 2 );
//draw(screen, bitmap, cliprect, 14 ); //driver's eyes
copy_visible_poly_framebuffer(bitmap, cliprect, 0x7fc0, 0x7ffe);
m_c355spr->draw(screen, bitmap, cliprect, 0 );
m_c355spr->draw(screen, bitmap, cliprect, 1 );
copy_visible_poly_framebuffer(bitmap, cliprect, 0, 0x7fbf);
/* draw high priority 2d sprites */
for( pri=pivot; pri<8; pri++ )
{
m_c355spr->draw(screen, bitmap, cliprect, pri );
}
// draw(screen, bitmap, cliprect, 15 ); //driver's eyes
return 0;
}
uint32_t namcos21_state::screen_update_driveyes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
//uint8_t *videoram = m_videoram.get();
int pivot = 3;
int pri;
bitmap.fill(0xff, cliprect );
m_c355spr->draw(screen, bitmap, cliprect, 2 );
m_c355spr->draw(screen, bitmap, cliprect, 14 ); //driver's eyes
copy_visible_poly_framebuffer(bitmap, cliprect, 0x7fc0, 0x7ffe);
m_c355spr->draw(screen, bitmap, cliprect, 0 );
m_c355spr->draw(screen, bitmap, cliprect, 1 );
copy_visible_poly_framebuffer(bitmap, cliprect, 0, 0x7fbf);
for (pri = pivot; pri < 8; pri++)
{
m_c355spr->draw(screen, bitmap, cliprect, pri);
}
m_c355spr->draw(screen, bitmap, cliprect, 15 ); //driver's eyes
return 0;
}
void namcos21_state::winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t *videoram = m_videoram.get();
//printf("%d %d (%d %d) - %04x %04x %04x|%04x %04x\n",cliprect.top(),cliprect.bottom(),m_screen->vpos(),m_gpu_intc->get_posirq_line(),m_winrun_gpu_register[0],m_winrun_gpu_register[2/2],m_winrun_gpu_register[4/2],m_winrun_gpu_register[0xa/2],m_winrun_gpu_register[0xc/2]);
int yscroll = -cliprect.top()+(int16_t)m_winrun_gpu_register[0x2/2];
int xscroll = 0;//m_winrun_gpu_register[0xc/2] >> 7;
int base = 0x1000+0x100*(m_winrun_color&0xf);
int sx,sy;
for( sy=cliprect.top(); sy<=cliprect.bottom(); sy++ )
{
const uint8_t *pSource = &videoram[((yscroll+sy)&0x3ff)*0x200];
uint16_t *pDest = &bitmap.pix16(sy);
for( sx=cliprect.left(); sx<=cliprect.right(); sx++ )
{
int pen = pSource[(sx+xscroll) & 0x1ff];
switch( pen )
{
case 0xff:
break;
// TODO: additive blending? winrun car select uses register [0xc] for a xscroll value
case 0x00:
pDest[sx] = (pDest[sx]&0x1fff)+0x4000;
break;
case 0x01:
pDest[sx] = (pDest[sx]&0x1fff)+0x6000;
break;
default:
pDest[sx] = base|pen;
break;
}
}
}
}
uint32_t namcos21_state::screen_update_winrun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0xff, cliprect );
copy_visible_poly_framebuffer(bitmap, cliprect, 0x7fc0, 0x7ffe);
copy_visible_poly_framebuffer(bitmap, cliprect, 0, 0x7fbf);
winrun_bitmap_draw(bitmap,cliprect);
//popmessage("%04x %04x %04x|%04x %04x",m_winrun_gpu_register[0],m_winrun_gpu_register[2/2],m_winrun_gpu_register[4/2],m_winrun_gpu_register[0xa/2],m_winrun_gpu_register[0xc/2]);
return 0;
}

View File

@ -0,0 +1,311 @@
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino, David Haywood
#include "emu.h"
#include "namcos21_3d.h"
DEFINE_DEVICE_TYPE(NAMCOS21_3D, namcos21_3d_device, "namcos21_3d", "Namco System 21 3D Rasterizer")
namcos21_3d_device::namcos21_3d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCOS21_3D, tag, owner, clock),
m_fixed_palbase(-1),
m_zz_shift(10),
m_zzmult(0x100),
m_depth_reverse(false),
m_poly_frame_width(0),
m_poly_frame_height(0),
m_framebuffer_size_in_bytes(0)
{
}
void namcos21_3d_device::device_start()
{
allocate_poly_framebuffer();
}
void namcos21_3d_device::device_reset()
{
}
void namcos21_3d_device::allocate_poly_framebuffer()
{
if (m_framebuffer_size_in_bytes == 0)
fatalerror("m_framebuffer_size_in_bytes == 0\n");
m_mpPolyFrameBufferZ = std::make_unique<uint16_t[]>(m_framebuffer_size_in_bytes / 2);
m_mpPolyFrameBufferPens = std::make_unique<uint16_t[]>(m_framebuffer_size_in_bytes / 2);
m_mpPolyFrameBufferZ2 = std::make_unique<uint16_t[]>(m_framebuffer_size_in_bytes / 2);
m_mpPolyFrameBufferPens2 = std::make_unique<uint16_t[]>(m_framebuffer_size_in_bytes / 2);
swap_and_clear_poly_framebuffer();
swap_and_clear_poly_framebuffer();
}
void namcos21_3d_device::swap_and_clear_poly_framebuffer()
{
/* swap work and visible framebuffers */
m_mpPolyFrameBufferZ.swap(m_mpPolyFrameBufferZ2);
m_mpPolyFrameBufferPens.swap(m_mpPolyFrameBufferPens2);
/* wipe work zbuffer */
for (int i = 0; i < m_poly_frame_width*m_poly_frame_height; i++)
{
m_mpPolyFrameBufferZ[i] = 0x7fff;
}
}
void namcos21_3d_device::copy_visible_poly_framebuffer(bitmap_ind16 &bitmap, const rectangle &clip, int zlo, int zhi)
{
/* blit the visible framebuffer */
int sy;
for (sy = clip.top(); sy <= clip.bottom(); sy++)
{
uint16_t *dest = &bitmap.pix16(sy);
const uint16_t *pPen = m_mpPolyFrameBufferPens2.get() + m_poly_frame_width * sy;
const uint16_t *pZ = m_mpPolyFrameBufferZ2.get() + m_poly_frame_width * sy;
int sx;
for (sx = clip.left(); sx <= clip.right(); sx++)
{
int z = pZ[sx];
//if( pZ[sx]!=0x7fff )
if (z >= zlo && z <= zhi)
{
dest[sx] = pPen[sx];
}
}
}
}
/*********************************************************************************************/
#define SWAP(T,A,B) { const T *temp = A; A = B; B = temp; }
void namcos21_3d_device::renderscanline_flat(const edge *e1, const edge *e2, int sy, unsigned color, int depthcueenable)
{
if (e1->x > e2->x)
{
SWAP(edge, e1, e2);
}
{
uint16_t *pDest = m_mpPolyFrameBufferPens.get() + sy * m_poly_frame_width;
uint16_t *pZBuf = m_mpPolyFrameBufferZ.get() + sy * m_poly_frame_width;
int x0 = (int)e1->x;
int x1 = (int)e2->x;
int w = x1 - x0;
if (w)
{
double z = e1->z;
double dz = (e2->z - e1->z) / w;
int x, crop;
crop = -x0;
if (crop > 0)
{
z += crop * dz;
x0 = 0;
}
if (x1 > m_poly_frame_width - 1)
{
x1 = m_poly_frame_width - 1;
}
for (x = x0; x < x1; x++)
{
uint16_t zz = (uint16_t)z;
if (zz < pZBuf[x])
{
int pen = color;
if (depthcueenable && zz > 0)
{
int depth = 0;
if (m_depth_reverse)
{
depth = (zz >> m_zz_shift)*m_zzmult;
pen += depth;
}
else
{
depth = (zz >> m_zz_shift)*m_zzmult;
pen -= depth;
}
}
pDest[x] = pen;
pZBuf[x] = zz;
}
z += dz;
}
}
}
}
void namcos21_3d_device::rendertri(const n21_vertex *v0, const n21_vertex *v1, const n21_vertex *v2, unsigned color, int depthcueenable)
{
int dy, ystart, yend, crop;
/* first, sort so that v0->y <= v1->y <= v2->y */
for (;;)
{
if (v0->y > v1->y)
{
SWAP(n21_vertex, v0, v1);
}
else if (v1->y > v2->y)
{
SWAP(n21_vertex, v1, v2);
}
else
{
break;
}
}
ystart = v0->y;
yend = v2->y;
dy = yend - ystart;
if (dy)
{
int y;
edge e1; /* short edge (top and bottom) */
edge e2; /* long (common) edge */
double dx2dy = (v2->x - v0->x) / dy;
double dz2dy = (v2->z - v0->z) / dy;
double dx1dy;
double dz1dy;
e2.x = v0->x;
e2.z = v0->z;
crop = -ystart;
if (crop > 0)
{
e2.x += dx2dy * crop;
e2.z += dz2dy * crop;
}
ystart = v0->y;
yend = v1->y;
dy = yend - ystart;
if (dy)
{
e1.x = v0->x;
e1.z = v0->z;
dx1dy = (v1->x - v0->x) / dy;
dz1dy = (v1->z - v0->z) / dy;
crop = -ystart;
if (crop > 0)
{
e1.x += dx1dy * crop;
e1.z += dz1dy * crop;
ystart = 0;
}
if (yend > m_poly_frame_height - 1) yend = m_poly_frame_height - 1;
for (y = ystart; y < yend; y++)
{
renderscanline_flat(&e1, &e2, y, color, depthcueenable);
e2.x += dx2dy;
e2.z += dz2dy;
e1.x += dx1dy;
e1.z += dz1dy;
}
}
ystart = v1->y;
yend = v2->y;
dy = yend - ystart;
if (dy)
{
e1.x = v1->x;
e1.z = v1->z;
dx1dy = (v2->x - v1->x) / dy;
dz1dy = (v2->z - v1->z) / dy;
crop = -ystart;
if (crop > 0)
{
e1.x += dx1dy * crop;
e1.z += dz1dy * crop;
ystart = 0;
}
if (yend > m_poly_frame_height - 1)
{
yend = m_poly_frame_height - 1;
}
for (y = ystart; y < yend; y++)
{
renderscanline_flat(&e1, &e2, y, color, depthcueenable);
e2.x += dx2dy;
e2.z += dz2dy;
e1.x += dx1dy;
e1.z += dz1dy;
}
}
}
}
void namcos21_3d_device::draw_quad(int sx[4], int sy[4], int zcode[4], int color)
{
n21_vertex a, b, c, d;
int depthcueenable = 1;
/*
0x0000..0x1fff sprite palettes (0x20 sets of 0x100 colors)
0x2000..0x3fff polygon palette bank0 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
0x4000..0x5fff polygon palette bank1 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
0x6000..0x7fff polygon palette bank2 (0x10 sets of 0x200 colors or 0x20 sets of 0x100 colors)
*/
if (m_fixed_palbase != -1)
{
// Winning Run & Driver's Eyes use this logic
color = m_fixed_palbase | (color & 0xff);
}
else
{ /* map color code to hardware pen */
int code = color >> 8;
if (code & 0x80)
{
color = color & 0xff;
// color = 0x3e00|color;
color = 0x2100 | color;
depthcueenable = 0;
}
else
{
color &= 0xff;
color = 0x3e00 | color;
if ((code & 0x02) == 0)
{
color |= 0x100;
}
}
}
a.x = sx[0];
a.y = sy[0];
a.z = zcode[0];
b.x = sx[1];
b.y = sy[1];
b.z = zcode[1];
c.x = sx[2];
c.y = sy[2];
c.z = zcode[2];
d.x = sx[3];
d.y = sy[3];
d.z = zcode[3];
rendertri(&a, &b, &c, color, depthcueenable);
rendertri(&c, &d, &a, color, depthcueenable);
}

View File

@ -0,0 +1,71 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_VIDEO_NAMCOS21_3D_H
#define MAME_VIDEO_NAMCOS21_3D_H
#pragma once
class namcos21_3d_device : public device_t
{
public:
namcos21_3d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// config
void set_fixed_palbase(int base) { m_fixed_palbase = base; }
void set_zz_shift_mult(int shift, int mult) { m_zz_shift = shift; m_zzmult = mult; }
void set_depth_reverse(bool reverse) { m_depth_reverse = reverse; }
void set_framebuffer_size(int width, int height)
{
m_poly_frame_width = width;
m_poly_frame_height = height;
m_framebuffer_size_in_bytes = (sizeof(uint16_t)*m_poly_frame_width*m_poly_frame_height);
}
int get_width() { return m_poly_frame_width; }
int get_height() { return m_poly_frame_height; }
void copy_visible_poly_framebuffer(bitmap_ind16 &bitmap, const rectangle &clip, int zlo, int zhi);
void swap_and_clear_poly_framebuffer();
void draw_quad(int sx[4], int sy[4], int zcode[4], int color);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
struct n21_vertex
{
double x,y;
double z;
};
struct edge
{
double x;
double z;
};
void renderscanline_flat(const edge *e1, const edge *e2, int sy, unsigned color, int depthcueenable);
void rendertri(const n21_vertex *v0, const n21_vertex *v1, const n21_vertex *v2, unsigned color, int depthcueenable);
void allocate_poly_framebuffer();
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferPens;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferZ;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferPens2;
std::unique_ptr<uint16_t[]> m_mpPolyFrameBufferZ2;
int m_fixed_palbase;
int m_zz_shift, m_zzmult;
bool m_depth_reverse;
int m_poly_frame_width;
int m_poly_frame_height;
int m_framebuffer_size_in_bytes;
};
DECLARE_DEVICE_TYPE(NAMCOS21_3D, namcos21_3d_device)
#endif // MAME_VIDEO_NAMCOS21_3D_H