vicdual: add 97269-P-B and 97271-P daughterboards for nsub (#2192)

This commit is contained in:
Ariane Fugmann 2017-03-31 00:52:42 +02:00 committed by Vas Crabb
parent 0c1b6430d0
commit c8554aabcb
8 changed files with 535 additions and 55 deletions

View File

@ -3280,7 +3280,11 @@ files {
MAME_DIR .. "src/mame/includes/vicdual.h",
MAME_DIR .. "src/mame/audio/vicdual.cpp",
MAME_DIR .. "src/mame/audio/vicdual.h",
MAME_DIR .. "src/mame/audio/vicdual-97271p.cpp",
MAME_DIR .. "src/mame/audio/vicdual-97271p.h",
MAME_DIR .. "src/mame/video/vicdual.cpp",
MAME_DIR .. "src/mame/video/vicdual-97269pb.cpp",
MAME_DIR .. "src/mame/video/vicdual-97269pb.h",
MAME_DIR .. "src/mame/audio/carnival.cpp",
MAME_DIR .. "src/mame/audio/carnival.h",
MAME_DIR .. "src/mame/audio/depthch.cpp",

View File

@ -0,0 +1,207 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
/*
N-Sub Oscillator 97271-P
-----------------------------
for the time being this is a simple sample player based on the work by MASH.
*/
#include "emu.h"
#include "speaker.h"
#include "audio/vicdual-97271p.h"
#define S97271P_TAG "s97271p"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type S97271P = device_creator<s97271p_device>;
/* bit definitions - sound effect drive outputs */
#define S97271P_WARNING 0x01
#define S97271P_SONAR 0x02
#define S97271P_LAUNCH 0x04
#define S97271P_EXPL_L 0x08
#define S97271P_EXPL_S 0x10
#define S97271P_BONUS 0x20
#define S97271P_CODE 0x40
#define S97271P_BOAT 0x80
/* sample file names */
static const char *const nsub_sample_names[] =
{
"*nsub",
"SND_EXPL_L0",
"SND_EXPL_L1",
"SND_SONAR",
"SND_LAUNCH0",
"SND_LAUNCH1",
"SND_WARNING0",
"SND_WARNING1",
"SND_EXPL_S0",
"SND_EXPL_S1",
"SND_BONUS0",
"SND_BONUS1",
"SND_CODE",
"SND_BOAT",
nullptr
};
/* sample ids - must match sample file name table above */
enum
{
SND_EXPL_L0 = 0,
SND_EXPL_L1,
SND_SONAR,
SND_LAUNCH0,
SND_LAUNCH1,
SND_WARNING0,
SND_WARNING1,
SND_EXPL_S0,
SND_EXPL_S1,
SND_BONUS0,
SND_BONUS1,
SND_CODE,
SND_BOAT
};
//**************************************************************************
// MACHINE FRAGMENTS
//**************************************************************************
static MACHINE_CONFIG_FRAGMENT( nsub_audio )
MCFG_SPEAKER_STANDARD_MONO("mono")
/* samples */
MCFG_SOUND_ADD("samples", SAMPLES, 0)
MCFG_SAMPLES_CHANNELS(13)
MCFG_SAMPLES_NAMES(nsub_sample_names)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
MACHINE_CONFIG_END
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// s97271p_device - constructor
//-------------------------------------------------
s97271p_device::s97271p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, S97271P, "N-Sub Oscillator 97271-P", tag, owner, clock, "s97271p", __FILE__),
m_samples(*this, "samples")
{
}
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor s97271p_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( nsub_audio );
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void s97271p_device::device_start()
{
save_item(NAME(m_state));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void s97271p_device::device_reset()
{
m_state = 0xff;
}
void s97271p_device::port_w(uint8_t data)
{
uint8_t bitsChanged = m_state ^ data;
uint8_t bitsGoneHigh = bitsChanged & data;
uint8_t bitsGoneLow = bitsChanged & ~data;
m_state = data;
if (bitsGoneLow & S97271P_WARNING)
{
m_samples->start(SND_WARNING0, SND_WARNING0, 1);
m_samples->stop(SND_WARNING1);
} else if (bitsGoneHigh & S97271P_WARNING)
{
m_samples->start(SND_WARNING1, SND_WARNING1, 0);
m_samples->stop(SND_WARNING0);
}
if (bitsGoneLow & S97271P_SONAR)
{
m_samples->start(SND_SONAR, SND_SONAR, 1);
} else if (bitsGoneHigh & S97271P_SONAR)
{
m_samples->stop(SND_SONAR);
}
if (bitsGoneLow & S97271P_LAUNCH)
{
m_samples->start(SND_LAUNCH0, SND_LAUNCH0, 1);
m_samples->stop(SND_LAUNCH1);
} else if (bitsGoneHigh & S97271P_LAUNCH)
{
m_samples->start(SND_LAUNCH1, SND_LAUNCH1, 0);
m_samples->stop(SND_LAUNCH0);
}
if (bitsGoneLow & S97271P_WARNING)
{
m_samples->start(SND_WARNING0, SND_WARNING0, 1);
m_samples->stop(SND_WARNING1);
} else if (bitsGoneHigh & S97271P_WARNING)
{
m_samples->start(SND_WARNING1, SND_WARNING1, 0);
m_samples->stop(SND_WARNING0);
}
if (bitsGoneLow & S97271P_EXPL_S)
{
m_samples->start(SND_EXPL_S0, SND_EXPL_S0, 1);
m_samples->stop(SND_EXPL_S1);
} else if (bitsGoneHigh & S97271P_EXPL_S)
{
m_samples->start(SND_EXPL_S1, SND_EXPL_S1, 0);
m_samples->stop(SND_EXPL_S0);
}
if (bitsGoneLow & S97271P_BONUS)
{
m_samples->start(SND_BONUS0, SND_BONUS0, 1);
m_samples->stop(SND_BONUS1);
} else if (bitsGoneHigh & S97271P_BONUS)
{
m_samples->start(SND_BONUS1, SND_BONUS1, 0);
m_samples->stop(SND_BONUS0);
}
if (bitsGoneLow & S97271P_CODE)
{
m_samples->start(SND_CODE, SND_CODE, 1);
} else if (bitsGoneHigh & S97271P_CODE)
{
m_samples->stop(SND_CODE);
}
if (bitsGoneLow & S97271P_BOAT)
{
m_samples->start(SND_BOAT, SND_BOAT, 1);
} else if (bitsGoneHigh & S97271P_BOAT)
{
m_samples->stop(SND_BOAT);
}
}

View File

@ -0,0 +1,43 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
#pragma once
#ifndef MAME_AUDIO_VICDUAL_97271P_H
#define MAME_AUDIO_VICDUAL_97271P_H
#include "sound/samples.h"
#define MCFG_S97271P_ADD(_tag ) \
MCFG_DEVICE_ADD(_tag, S97271P, 0)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class s97271p_device : public device_t
{
public:
// construction/destruction
s97271p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// optional information overrides
virtual machine_config_constructor device_mconfig_additions() const override;
// daughterboard logic
void port_w(uint8_t data);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
required_device<samples_device> m_samples;
uint8_t m_state;
};
// device type definition
extern const device_type S97271P;
#endif /* MAME_AUDIO_VICDUAL_97271P_H */

View File

@ -58,6 +58,8 @@
#include "audio/invinco.h"
#include "audio/pulsar.h"
#include "audio/vicdual.h"
#include "audio/vicdual-97271p.h"
#include "video/vicdual-97269pb.h"
#include "cpu/i8085/i8085.h"
#include "cpu/z80/z80.h"
@ -2232,7 +2234,7 @@ MACHINE_CONFIG_END
*
*************************************/
READ8_MEMBER(vicdual_state::nsub_io_r)
READ8_MEMBER(nsub_state::nsub_io_r)
{
uint8_t ret = 0;
@ -2243,19 +2245,22 @@ READ8_MEMBER(vicdual_state::nsub_io_r)
}
WRITE8_MEMBER(vicdual_state::nsub_io_w)
WRITE8_MEMBER(nsub_state::nsub_io_w)
{
if (offset & 0x01) assert_coin_status();
if (offset & 0x02) { /* nsub_audio_w(0, data) */ }
if (offset & 0x02)
{
m_s97271p->port_w(data);
}
if (offset & 0x04)
{
palette_bank_w(space, 0, data);
m_gradient = data & 4;
m_s97269pb->palette_bank_w(data);
}
}
static ADDRESS_MAP_START( nsub_map, AS_PROGRAM, 8, vicdual_state )
static ADDRESS_MAP_START( nsub_map, AS_PROGRAM, 8, nsub_state )
AM_RANGE(0x0000, 0x3fff) AM_MIRROR(0x4000) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_NOP /* unused */
AM_RANGE(0xc000, 0xc3ff) AM_MIRROR(0x3000) AM_RAM_WRITE(videoram_w) AM_SHARE("videoram")
@ -2264,7 +2269,7 @@ static ADDRESS_MAP_START( nsub_map, AS_PROGRAM, 8, vicdual_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( nsub_io_map, AS_IO, 8, vicdual_state )
static ADDRESS_MAP_START( nsub_io_map, AS_IO, 8, nsub_state )
ADDRESS_MAP_GLOBAL_MASK(0x0f)
/* no decoder, just logic gates, so in theory the
@ -2275,7 +2280,7 @@ ADDRESS_MAP_END
// coinage is handled by extra hardware on a daughterboard, put before the coin-in pin on the main logic board
// IC board "COIN CALCULATOR" (97201-P): two 74191 counters, a 555 timer, coin meters, and lots of other TTL
TIMER_DEVICE_CALLBACK_MEMBER(vicdual_state::nsub_coin_pulse)
TIMER_DEVICE_CALLBACK_MEMBER(nsub_state::nsub_coin_pulse)
{
if (m_nsub_play_counter > 0)
{
@ -2284,7 +2289,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(vicdual_state::nsub_coin_pulse)
}
}
INPUT_CHANGED_MEMBER(vicdual_state::nsub_coin_in)
INPUT_CHANGED_MEMBER(nsub_state::nsub_coin_in)
{
if (newval)
{
@ -2339,14 +2344,14 @@ static INPUT_PORTS_START( nsub )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, get_composite_blank_comp, nullptr)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, nsub_state, get_composite_blank_comp, nullptr)
PORT_BIT( 0x7e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, read_coin_status, nullptr)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, nsub_state, read_coin_status, nullptr)
PORT_START("COIN")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vicdual_state,nsub_coin_in, (void*)0)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vicdual_state,nsub_coin_in, (void*)1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vicdual_state,nsub_coin_in, (void*)2)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, nsub_state, nsub_coin_in, (void*)0)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, nsub_state, nsub_coin_in, (void*)1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, nsub_state, nsub_coin_in, (void*)2)
PORT_START("COINAGE") // "OPTION SW." on daughterboard
PORT_DIPNAME( 0x07, 0x01, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW:1,2,3")
@ -2372,7 +2377,7 @@ static INPUT_PORTS_START( nsub )
INPUT_PORTS_END
MACHINE_START_MEMBER(vicdual_state,nsub)
MACHINE_START_MEMBER(nsub_state, nsub)
{
m_nsub_play_counter = 0;
save_item(NAME(m_nsub_coin_counter));
@ -2385,28 +2390,33 @@ MACHINE_START_MEMBER(vicdual_state,nsub)
m_nsub_coinage_timer->adjust(attotime::zero, 0, attotime::from_msec(150));
}
MACHINE_RESET_MEMBER(vicdual_state,nsub)
MACHINE_RESET_MEMBER(nsub_state, nsub)
{
m_nsub_coin_counter = m_coinage->read() & 7;
machine_reset();
}
static MACHINE_CONFIG_DERIVED( nsub, vicdual_root )
static MACHINE_CONFIG_START( nsub, nsub_state )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_ADD("maincpu", Z80, VICDUAL_MAIN_CPU_CLOCK)
MCFG_CPU_PROGRAM_MAP(nsub_map)
MCFG_CPU_IO_MAP(nsub_io_map)
MCFG_TIMER_DRIVER_ADD("nsub_coin", vicdual_state, nsub_coin_pulse)
MCFG_MACHINE_START_OVERRIDE(vicdual_state,nsub)
MCFG_MACHINE_RESET_OVERRIDE(vicdual_state,nsub)
MCFG_TIMER_DRIVER_ADD("coinstate", nsub_state, clear_coin_status)
MCFG_TIMER_DRIVER_ADD("nsub_coin", nsub_state, nsub_coin_pulse)
/* video hardware */
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(vicdual_state, screen_update_color)
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(VICDUAL_PIXEL_CLOCK, VICDUAL_HTOTAL, VICDUAL_HBEND, VICDUAL_HBSTART, VICDUAL_VTOTAL, VICDUAL_VBEND, VICDUAL_VBSTART)
MCFG_SCREEN_UPDATE_DRIVER(nsub_state, screen_update_color)
MCFG_S97269PB_ADD("s97269pb")
MCFG_MACHINE_START_OVERRIDE(nsub_state, nsub)
MCFG_MACHINE_RESET_OVERRIDE(nsub_state, nsub)
/* audio hardware */
MCFG_S97271P_ADD("s97271p")
MACHINE_CONFIG_END
@ -2664,11 +2674,8 @@ Epr-274.u42
Epr-275.u41
Pr-69.u11
Also PR33.u82 and PR34.u83 were not dumped from this pcb, couldn't be read because aluminium cooler on it.
They're probably the same as on other games.
This game use a separate "daughter" board for input ??? ref: 97269-P-B
with a prom on it : PR-02 type MMI 6336-1j which is soldered.
This game use a separate "daughter" board for gradient and starfield ref: 97269-P-B
with 3 proms on it : PR-02 type MMI 6336-1j, PR-56 type MB7054 and PR-57 type MB7054
*/
@ -3646,7 +3653,7 @@ GAME( 1979, headon2, 0, headon2, headon2, driver_device, 0, ROT0,
GAME( 1979, headon2s, headon2, headon2bw, car2, driver_device, 0, ROT0, "bootleg (Sidam)", "Head On 2 (Sidam bootleg)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // won't coin up?
GAME( 1979, car2, headon2, headon2bw, car2, driver_device, 0, ROT0, "bootleg (RZ Bologna)", "Car 2 (bootleg of Head On 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // title still says 'HeadOn 2'
GAME( 1979, invho2, 0, invho2, invho2, driver_device, 0, ROT270, "Sega", "Invinco / Head On 2", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, nsub, 0, nsub, nsub, driver_device, 0, ROT270, "Sega", "N-Sub (upright)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // this is the upright set. cocktail set still needs to be dumped
GAME( 1980, nsub, 0, nsub, nsub, driver_device, 0, ROT270, "Sega", "N-Sub (upright)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // this is the upright set. cocktail set still needs to be dumped
GAME( 1980, samurai, 0, samurai, samurai, driver_device, 0, ROT270, "Sega", "Samurai", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, invinco, 0, invinco, invinco, driver_device, 0, ROT270, "Sega", "Invinco", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, invds, 0, invds, invds, driver_device, 0, ROT270, "Sega", "Invinco / Deep Scan", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )

View File

@ -11,6 +11,8 @@
#include "sound/discrete.h"
#include "sound/samples.h"
#include "screen.h"
#include "audio/vicdual-97271p.h"
#include "video/vicdual-97269pb.h"
class vicdual_state : public driver_device
{
@ -58,10 +60,7 @@ public:
uint8_t m_coin_status;
uint8_t m_palette_bank;
uint8_t m_gradient;
uint8_t m_samurai_protection_data;
int m_nsub_coin_counter;
int m_nsub_play_counter;
int m_port1State;
int m_port2State;
int m_psgData;
@ -102,8 +101,6 @@ public:
DECLARE_WRITE8_MEMBER(alphaho_io_w);
DECLARE_WRITE8_MEMBER(samurai_protection_w);
DECLARE_WRITE8_MEMBER(samurai_io_w);
DECLARE_READ8_MEMBER(nsub_io_r);
DECLARE_WRITE8_MEMBER(nsub_io_w);
DECLARE_READ8_MEMBER(invinco_io_r);
DECLARE_WRITE8_MEMBER(invinco_io_w);
@ -139,14 +136,10 @@ public:
DECLARE_CUSTOM_INPUT_MEMBER(fake_lives_r);
DECLARE_CUSTOM_INPUT_MEMBER(samurai_protection_r);
DECLARE_INPUT_CHANGED_MEMBER(coin_changed);
DECLARE_INPUT_CHANGED_MEMBER(nsub_coin_in);
TIMER_DEVICE_CALLBACK_MEMBER(clear_coin_status);
TIMER_DEVICE_CALLBACK_MEMBER(nsub_coin_pulse);
DECLARE_MACHINE_START(samurai);
DECLARE_MACHINE_START(nsub);
DECLARE_MACHINE_RESET(nsub);
DECLARE_MACHINE_START(frogs_audio);
virtual void machine_start() override;
@ -156,4 +149,33 @@ public:
uint32_t screen_update_color(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
int get_vcounter();
int is_cabinet_color();
virtual pen_t choose_pen(uint8_t x, uint8_t y, pen_t back_pen);
};
class nsub_state : public vicdual_state
{
public:
nsub_state(const machine_config &mconfig, device_type type, const char *tag)
: vicdual_state(mconfig, type, tag),
m_s97269pb(*this,"s97269pb"),
m_s97271p(*this,"s97271p")
{ }
required_device<s97269pb_device> m_s97269pb;
required_device<s97271p_device> m_s97271p;
int m_nsub_coin_counter;
int m_nsub_play_counter;
DECLARE_READ8_MEMBER(nsub_io_r);
DECLARE_WRITE8_MEMBER(nsub_io_w);
DECLARE_INPUT_CHANGED_MEMBER(nsub_coin_in);
TIMER_DEVICE_CALLBACK_MEMBER(nsub_coin_pulse);
DECLARE_MACHINE_START(nsub);
DECLARE_MACHINE_RESET(nsub);
virtual pen_t choose_pen(uint8_t x, uint8_t y, pen_t back_pen);
};

View File

@ -0,0 +1,157 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
/*
N-Sub Daughterboard 97269-P-B
-----------------------------
Reference Image: http://images.arianchen.de/2017-01/030320171775.jpg
Wiring Notes: http://files.arianchen.de/nsub/97269-P-B.txt
|---------------------------------------------------|
| PR-02 74393 PR-57 74175 74367 7417 (A) |
| |
| PR-56 7410 74393 7400 74367 (B) |
| |
| 74161 74161 74157 74175 74365 (C) |
| |
| (1) (2) (3) (4) (5) (6) |
| SEGA 97269-P-B |
| [---CON-F---] [-----------CON-X-----------] |
|---------------------------------------------------|
Notes:
PR-02.A1 - MMI 6336-1J 256*8 PROM (DIP24, labelled 'PR-02')
PR-56.B2 - Fujitsu MB7054 1024*4 (DIP18, labelled 'PR-56')
PR-57.A3 - Fujitsu MB7054 1024*4 (DIP18, labelled 'PR-57')
CON-F - A 3.6 Pin Connector for monitor (different pinout!)
01 - NC
02 - NC
03 - GND
04 - KEY
05 - NC
06 - NC
07 - CSYNC
08 - GREEN
09 - BLUE
10 - RED
CON-X - A 15 Pin Connector which is wired to various places on the mainboard
01 - VCC
02 - GND
03 - CSYNC (U53.1)
04 - PALBANK-B2 (U18.7)
05 - EXTBLANK (U84.8)
06 - VIDEO (U54.13)
07 - PALBANK-B3 (U18.2)
08 - VSYNC (U53.12)
09 - VBLANK (U17.5)
10 - BLUE (U8.7)
11 - GREEN (U8.9)
12 - RED (U8.4)
13 - HSYNC- (U13.9)
14 - HRESET (U13.6)
15 - SRCK (U54.7)
*/
#include "emu.h"
#include "video/vicdual-97269pb.h"
#define S97269PB_TAG "s97269pb"
/*************************************
* 97269PB PROMS
*************************************/
ROM_START( s97269pb )
ROM_REGION( 0x1000, S97269PB_TAG, ROMREGION_ERASEFF )
ROM_LOAD( "pr-02.a1", 0x0000, 0x0100, CRC(8e633b5c) SHA1(7ee40abe0e8a56aae2cc5f1102fa8c334a19e075) )
ROM_LOAD( "pr-56.b2", 0x0800, 0x0400, CRC(f79c8e91) SHA1(eafff661e2aa1a6ef64f51faa9b1dac7af843557) )
ROM_LOAD( "pr-57.a3", 0x0c00, 0x0400, CRC(00d52430) SHA1(5f4de97cfe6fe39da75761e0f434de28d30f3e3b) )
ROM_END
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type S97269PB = device_creator<s97269pb_device>;
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
const tiny_rom_entry *s97269pb_device::device_rom_region() const
{
return ROM_NAME( s97269pb );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// s97269pb_device - constructor
//-------------------------------------------------
s97269pb_device::s97269pb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, S97269PB, "N-Sub Daughterboard 97269-P-B", tag, owner, clock, "s97269pb", __FILE__),
m_prom_ptr(*this, "s97269pb")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void s97269pb_device::device_start()
{
save_item(NAME(m_palette_bank));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void s97269pb_device::device_reset()
{
m_palette_bank = 0;
}
void s97269pb_device::palette_bank_w(uint8_t data)
{
m_palette_bank = data & 0x0c;
}
pen_t s97269pb_device::choose_pen(uint8_t x, uint8_t y, pen_t back_pen)
{
if (m_palette_bank & 0x04)
{
// TODO - starfield
// gradient is offset by about 10 pixels
// bit 2 enables the gradient and starfield/gradient
// bit 3 seems to be used for cocktail mode
uint8_t offset = ((x + 5) & 0xff) / 2;
if (m_palette_bank & 0x08)
offset |= 0x80;
uint8_t gradient_flags = m_prom_ptr[offset];
switch (gradient_flags >> 4)
{
case 0x1:
// blue-to-cyan
return rgb_t(0, 0x80 + (gradient_flags & 0x0f) * 0x08, 0xff);
break;
case 0x4:
// black-to-blue
return rgb_t(0, 0, (gradient_flags & 0x0f) * 0x11);;
break;
case 0xf:
default:
return back_pen;
break;
}
}
return back_pen;
}

View File

@ -0,0 +1,42 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
#pragma once
#ifndef MAME_VIDEO_VICDUAL_97269PB_H
#define MAME_VIDEO_VICDUAL_97269PB_H
#define MCFG_S97269PB_ADD(_tag ) \
MCFG_DEVICE_ADD(_tag, S97269PB, 0)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class s97269pb_device : public device_t
{
public:
// construction/destruction
s97269pb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// daughterboard logic
void palette_bank_w(uint8_t data);
pen_t choose_pen(uint8_t x, uint8_t y, pen_t back_pen);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual const tiny_rom_entry *device_rom_region() const override;
private:
required_region_ptr<uint8_t> m_prom_ptr;
// bit 2 enables gradient and starfield
// bit 3 seems to be used to flip for cocktail
uint8_t m_palette_bank;
};
// device type definition
extern const device_type S97269PB;
#endif /* MAME_VIDEO_VICDUAL_97269PB_H */

View File

@ -112,22 +112,8 @@ uint32_t vicdual_state::screen_update_color(screen_device &screen, bitmap_rgb32
fore_pen = pens_from_color_prom[(color_prom[offs] >> 5) & 0x07];
}
if (m_gradient == 0x04)
{
// used by nsub and starrkr (maybe others)
// bit 4 on palette_bank_w seems to enable/disable the starfield/gradient
// how exactly those work is unclear right now
if (x >= 24 && x < 105)
{
// nsub - black to blue gradient
back_pen = rgb_t(0x00, 0x00, (x - 24) * 3);
}
if (x >= 105 && x < 233)
{
// nsub - blue to cyan gradient
back_pen = rgb_t(0x00, 0x80 + (x - 105), 0xff);
}
}
// this does nothing by default, but is used to enable overrides
back_pen = choose_pen(x, y, back_pen);
/* plot the current pixel */
pen = (video_data & 0x80) ? fore_pen : back_pen;
@ -164,3 +150,15 @@ uint32_t vicdual_state::screen_update_bw_or_color(screen_device &screen, bitmap_
return 0;
}
pen_t vicdual_state::choose_pen(uint8_t x, uint8_t y, pen_t back_pen)
{
return back_pen;
}
pen_t nsub_state::choose_pen(uint8_t x, uint8_t y, pen_t back_pen)
{
return m_s97269pb->choose_pen(x, y, back_pen);
}