-fireone: Committed netlist for couriersud to have a look at.

This commit is contained in:
Ryan Holtz 2020-08-04 23:39:01 +02:00
parent 830c6299a8
commit e404f347c6
17 changed files with 1054 additions and 188 deletions

View File

@ -129,6 +129,7 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/solver/vector_base.h",
MAME_DIR .. "src/lib/netlist/devices/net_lib.cpp",
MAME_DIR .. "src/lib/netlist/devices/net_lib.h",
MAME_DIR .. "src/lib/netlist/devices/net_devinc.h",
MAME_DIR .. "src/lib/netlist/devices/nld_9316_base.hxx",
MAME_DIR .. "src/lib/netlist/devices/nld_2102A.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_2102A.h",

View File

@ -1917,6 +1917,8 @@ files {
createMAMEProjects(_target, _subtarget, "exidy")
files {
MAME_DIR .. "src/mame/audio/nl_carpolo.h",
MAME_DIR .. "src/mame/audio/nl_carpolo.cpp",
MAME_DIR .. "src/mame/drivers/carpolo.cpp",
MAME_DIR .. "src/mame/includes/carpolo.h",
MAME_DIR .. "src/mame/machine/carpolo.cpp",
@ -1946,6 +1948,8 @@ files {
MAME_DIR .. "src/mame/video/antic.h",
MAME_DIR .. "src/mame/video/gtia.cpp",
MAME_DIR .. "src/mame/video/gtia.h",
MAME_DIR .. "src/mame/audio/nl_fireone.h",
MAME_DIR .. "src/mame/audio/nl_fireone.cpp",
MAME_DIR .. "src/mame/drivers/starfire.cpp",
MAME_DIR .. "src/mame/includes/starfire.h",
MAME_DIR .. "src/mame/video/starfire.cpp",

View File

@ -105,6 +105,7 @@ NETLIST_EXTERNAL(ROMS_lib)
#include "nld_log.h"
#include "netlist/macro/nlm_cd4xxx.h"
#include "netlist/macro/nlm_mc3340.h"
#include "netlist/macro/nlm_opamp.h"
#include "netlist/macro/nlm_other.h"
#include "netlist/macro/nlm_roms.h"

View File

@ -600,6 +600,13 @@
#define CD4006(...) \
NET_REGISTER_DEVEXT(CD4006, __VA_ARGS__)
// ---------------------------------------------------------------------
// Source: src/lib/netlist/devices/nld_4013.cpp
// ---------------------------------------------------------------------
// usage : CD4013(name)
#define CD4013(...) \
NET_REGISTER_DEVEXT(CD4013, __VA_ARGS__)
// ---------------------------------------------------------------------
// Source: src/lib/netlist/devices/nld_4017.cpp
// ---------------------------------------------------------------------
@ -1338,6 +1345,10 @@
#define MB3614_DIP(...) \
NET_REGISTER_DEVEXT(MB3614_DIP, __VA_ARGS__)
// usage : MC3340_DIP(name)
#define MC3340_DIP(...) \
NET_REGISTER_DEVEXT(MC3340_DIP, __VA_ARGS__)
// usage : TL081_DIP(name)
#define TL081_DIP(...) \
NET_REGISTER_DEVEXT(TL081_DIP, __VA_ARGS__)
@ -1370,6 +1381,10 @@
#define UA741_DIP14(...) \
NET_REGISTER_DEVEXT(UA741_DIP14, __VA_ARGS__)
// usage : MC1558_DIP(name)
#define MC1558_DIP(...) \
NET_REGISTER_DEVEXT(MC1558_DIP, __VA_ARGS__)
// usage : LM747_DIP(name)
#define LM747_DIP(...) \
NET_REGISTER_DEVEXT(LM747_DIP, __VA_ARGS__)

View File

@ -14,7 +14,6 @@ static NETLIST_START(diode_models)
NET_MODEL("1N916 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL("1N4001 D(Is=14.11n N=1.984 Rs=33.89m Ikf=94.81 Xti=3 Eg=1.11 Cjo=25.89p M=.44 Vj=.3245 Fc=.5 Bv=75 Ibv=10u Tt=5.7u Iave=1 Vpk=50 mfg=GI type=silicon)")
NET_MODEL("1N4148 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
// FIXME: Unsure of the peak voltage of the 1N4154!
NET_MODEL("1N4154 D(Is=0.1n Rs=4 N=1.67 Cjo=2p M=.333 tt=3n Iave=150m Vpk=35 Bv=60 Ibv=0.1p mfg=Vishay type=silicon)")
NET_MODEL("1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75)")

View File

@ -0,0 +1,34 @@
// license:GPL-2.0+
// copyright-holders:Ryan Holtz
#ifndef NLM_MC3340_H_
#define NLM_MC3340_H_
///
/// \file nlm_mc3340.h
///
#include "netlist/nl_setup.h"
#ifndef __PLIB_PREPROCESSOR__
/* ----------------------------------------------------------------------------
* Netlist Macros
* ---------------------------------------------------------------------------*/
#if !NL_AUTO_DEVICES
#define MC3340_DIP(name) \
NET_REGISTER_DEV(MC3340_DIP, name)
#endif // NL_AUTO_DEVICES
/* ----------------------------------------------------------------------------
* External declarations
* ---------------------------------------------------------------------------*/
// moved to net_lib.h
#endif // __PLIB_PREPROCESSOR__
#endif

View File

@ -137,6 +137,176 @@ static NETLIST_START(MB3614_DIP)
NETLIST_END()
static NETLIST_START(MC3340_DIP)
// A netlist description of the Motorola MC3340 Electronic Attenuator
// IC, a voltage-controlled amplifier/attenuator. It amplifies or
// attenuates an input signal according to the voltage of a second,
// control signal, with a maximum gain of about 12-13 dB (about a
// factor of 4 in voltage), and higher control voltages giving greater
// attenuation, which scales logarithmically.
// The netlist here is based on the circuit schematic given in
// Motorola's own data books, especially the most recent ones
// published in the 1990s (e.g. _Motorola Analog/Interface ICs Device
// Data, Vol. II_ (1996), p. 9-67), which are the only schematics that
// include resistor values. However, the 1990s schematics are missing
// one crossover connection which is present in older schematics
// published in the 1970s (e.g. _Motorola Linear Integrated Circuits_
// (1979), p. 5-130). This missing connection is clearly an error
// which has been fixed in this netlist; without it, the circuit won't
// amplify properly, generating only a very weak output signal.
// The 1990s schematics also omit a couple of diodes which are present
// in the 1970s schematics. Both of these diodes have been included
// here. One raises the minimum control voltage at which signal
// attenuation starts, so it makes the netlist's profile of
// attenuation vs. control voltage better match Motorola's charts for
// the device. The other affects the level of the input "midpoint",
// and including it makes the engine sound closer to that on real
// 280-ZZZAP machines.
// The Motorola schematics do not label components, so I've created my
// own labeling scheme based on numbering components on the schematics
// from top to bottom, left to right, with resistors also getting
// their value (expressed European-style to avoid decimal points) as
// part of the name. The netlist is also listed following the
// schematics in roughly top-to-bottom, left-to-right order.
// A very simple model is used for the transistors here, based on the
// generic NPN default but with a larger scale current. Again, this
// was chosen to better match the netlist's attenuation vs. control
// voltage profile to that given in Motorola's charts for the device.
// The MC3340 has the same circuit internally as an older Motorola
// device, the MFC6040, which was replaced by the MC3340 in the
// mid-1970s. The two chips differ only in packaging. Older arcade
// games which use the MFC6040 may also benefit from this netlist
// implementation.
RES(R1_5K1, RES_K(5.1))
DIODE(D1, "D(IS=1e-15 N=1)")
RES(R2_4K7, RES_K(4.7))
QBJT_EB(Q1, "NPN(IS=1E-13 BF=100)")
RES(R3_750, RES_R(750))
RES(R4_10K, RES_K(10))
QBJT_EB(Q2, "NPN(IS=1E-13 BF=100)")
RES(R5_750, RES_R(750))
RES(R6_3K9, RES_K(3.9))
RES(R7_5K1, RES_K(5.1))
RES(R8_20K, RES_K(20))
DIODE(D2, "D(IS=1e-15 N=1)")
RES(R9_510, RES_R(510))
QBJT_EB(Q3, "NPN(IS=1E-13 BF=100)")
QBJT_EB(Q4, "NPN(IS=1E-13 BF=100)")
QBJT_EB(Q5, "NPN(IS=1E-13 BF=100)")
RES(R10_1K3, RES_K(1.3))
QBJT_EB(Q6, "NPN(IS=1E-13 BF=100)")
RES(R11_5K1, RES_K(5.1))
QBJT_EB(Q7, "NPN(IS=1E-13 BF=100)")
QBJT_EB(Q8, "NPN(IS=1E-13 BF=100)")
RES(R12_1K5, RES_K(1.5))
RES(R13_6K2, RES_K(6.2))
QBJT_EB(Q9, "NPN(IS=1E-13 BF=100)")
RES(R14_5K1, RES_K(5.1))
QBJT_EB(Q10, "NPN(IS=1E-13 BF=100)")
RES(R15_5K1, RES_K(5.1))
RES(R16_200, RES_R(200))
RES(R17_5K1, RES_K(5.1))
DIODE(D3, "D(IS=1e-15 N=1)")
RES(R18_510, RES_R(510))
ALIAS(VCC, R1_5K1.1)
NET_C(R1_5K1.1, Q1.C, Q2.C, R7_5K1.1, Q3.C, Q4.C, Q7.C,
R13_6K2.1, Q10.C, R17_5K1.1)
// Location of first diode present on 1970s schematics but omitted on
// 1990s ones. Including it raises the control voltage threshold for
// attenuation significantly.
NET_C(R1_5K1.2, D1.A, Q1.B)
NET_C(D1.K, R2_4K7.1)
NET_C(R2_4K7.2, GND)
NET_C(Q1.E, R3_750.1, R5_750.1)
NET_C(R3_750.2, R4_10K.1, Q2.B)
NET_C(R4_10K.2, GND)
NET_C(R5_750.2, R6_3K9.1, Q3.B)
ALIAS(CONTROL, R6_3K9.2)
ALIAS(INPUT, Q5.B)
NET_C(INPUT, R8_20K.1)
// Location of second diode present on 1970s schematics but omitted on
// 1990s ones. Including it is critical to making the tone of the
// output engine sound match that of real 280-ZZZAP machines.
NET_C(R7_5K1.2, R8_20K.2, D2.A)
NET_C(D2.K, R9_510.1)
NET_C(R9_510.2, GND)
NET_C(Q4.E, Q6.E, Q5.C)
NET_C(Q5.E, R10_1K3.1)
NET_C(R10_1K3.2, GND)
NET_C(Q6.B, Q7.B, Q2.E, R11_5K1.1)
NET_C(R11_5K1.2, GND)
NET_C(Q7.E, Q9.E, Q8.C)
NET_C(Q8.E, R12_1K5.1)
NET_C(R12_1K5.2, GND)
NET_C(Q4.B, Q9.B, Q3.E, R14_5K1.1)
NET_C(R14_5K1.2, GND)
// This is where the cross-connection is erroneously omitted from
// 1990s schematics.
NET_C(Q6.C, R13_6K2.2, Q9.C, Q10.B)
// Connection for external frequency compensation capacitor; unused
// here.
ALIAS(ROLLOFF, Q10.B)
NET_C(Q10.E, R16_200.1, R15_5K1.1)
NET_C(R15_5K1.2, GND)
ALIAS(OUTPUT, R16_200.2)
NET_C(R17_5K1.2, D3.A, Q8.B)
NET_C(D3.K, R18_510.1)
ALIAS(GND, R18_510.2);
ALIAS(1, INPUT)
ALIAS(2, CONTROL)
ALIAS(3, GND)
ALIAS(6, ROLLOFF)
ALIAS(7, OUTPUT)
ALIAS(8, VCC)
NETLIST_END()
static NETLIST_START(TL081_DIP)
OPAMP(A, "TL084")
@ -204,6 +374,14 @@ static NETLIST_START(UA741_DIP14)
NETLIST_END()
static NETLIST_START(MC1558_DIP)
OPAMP(A, "UA741")
OPAMP(B, "UA741")
INCLUDE(opamp_layout_2_8_4)
NETLIST_END()
static NETLIST_START(LM747_DIP)
OPAMP(A, "LM747")
OPAMP(B, "LM747")
@ -405,6 +583,7 @@ NETLIST_START(OPAMP_lib)
NET_MODEL("UA741 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=75 DAB=0.0017)")
NET_MODEL("LM747 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=50 DAB=0.0017)")
NET_MODEL("LM747A OPAMP(TYPE=3 VLH=2.0 VLL=2.0 FPF=5 UGF=1000k SLEW=0.7M RI=6000k RO=50 DAB=0.0015)")
// FIXME: LM748 values are calculated based on a documented schematic of the part and may be wrong.
// TI and Motorola Datasheets differ - below are Motorola values, SLEW is average of LH and HL
NET_MODEL("LM3900 OPAMP(TYPE=3 VLH=1.0 VLL=0.03 FPF=2k UGF=4M SLEW=10M RI=10M RO=2k DAB=0.0015)")
@ -413,6 +592,7 @@ NETLIST_START(OPAMP_lib)
NET_MODEL("LM3900_PNP1 PNP(IS=1E-14 BF=40 TF=1E-7 CJC=1E-12 CJE=1E-12 VAF=150 RB=100 RE=5)")
#endif
LOCAL_LIB_ENTRY(MB3614_DIP)
LOCAL_LIB_ENTRY(MC3340_DIP)
LOCAL_LIB_ENTRY(TL081_DIP)
LOCAL_LIB_ENTRY(TL084_DIP)
LOCAL_LIB_ENTRY(LM324_DIP)
@ -421,6 +601,7 @@ NETLIST_START(OPAMP_lib)
LOCAL_LIB_ENTRY(UA741_DIP8)
LOCAL_LIB_ENTRY(UA741_DIP10)
LOCAL_LIB_ENTRY(UA741_DIP14)
LOCAL_LIB_ENTRY(MC1558_DIP)
LOCAL_LIB_ENTRY(LM747_DIP)
LOCAL_LIB_ENTRY(LM747A_DIP)
LOCAL_LIB_ENTRY(LM3900)

View File

@ -48,6 +48,9 @@
#define UA741_DIP14(name) \
NET_REGISTER_DEV(UA741_DIP14, name)
#define MC1558_DIP(name) \
NET_REGISTER_DEV(MC1558_DIP, name)
#define LM747_DIP(name) \
NET_REGISTER_DEV(LM747_DIP, name)

View File

@ -0,0 +1,158 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//
// Netlist for Car Polo audio
//
// Derived from the schematics in the Car Polo manual.
//
// Known problems/issues:
//
// * Uses HLE noise due to abusing a 2N3904 in breakdown as a noise source.
// * Very slow
//
#include "netlist/devices/net_lib.h"
#include "nl_carpolo.h"
#define HLE_NOISE (1)
//
// Player Crash netlist
//
static NETLIST_START(PLAYER_CRASH)
ALIAS(V15, R200.1)
ALIAS(VCC, 4C.VCC)
ALIAS(GND, R210.2)
ALIAS(CRASH_IN, 4C.A)
ALIAS(AUDIO_OUT, R217.1)
ALIAS(NOISE_IN, CR10.K)
TTL_7407_GATE(4C)
NET_C(4C.GND, GND)
RES(R200, RES_K(1.2))
RES(R202, RES_K(150))
RES(R203, RES_K(550))
RES(R204, RES_K(100))
RES(R205, RES_K(270))
RES(R210, RES_K(33))
RES(R212, RES_K(1))
RES(R213, RES_K(10))
RES(R216, RES_K(47))
RES(R217, RES_K(5))
CAP(C89, CAP_U(0.1))
CAP(C90, CAP_U(0.01))
CAP(C91, CAP_U(0.01))
CAP(C92, CAP_U(6.8))
CAP(C93, CAP_U(2.2))
DIODE(CR10, "1N4454")
DIODE(CR11, "1N4454")
DIODE(CR14, "1N4454")
QBJT_EB(Q6, "2N3904")
NET_C(R200.1, R212.1, R216.1)
NET_C(R200.2, 4C.Y, CR11.A)
NET_C(CR11.K, C93.1, R204.1, R205.1)
NET_C(C93.2, R205.2, Q6.E, R217.1, R210.2, C92.2)
NET_C(R204.2, R203.1, R202.1, CR10.A)
NET_C(R202.2, C89.1)
NET_C(C89.2, C90.1, R203.2, Q6.B)
NET_C(C90.2, R210.1, C91.1)
NET_C(C91.2, Q6.C, CR14.K, R213.1)
NET_C(R213.2, R212.2, C92.1)
NET_C(R217.2, CR14.A, R216.2)
NETLIST_END()
//
// Main netlist
//
NETLIST_START(carpolo)
NET_MODEL("1N4454 D(Is=168.1e-21 Rs=.1 N=1 Cjo=2p M=.333 tt=5.771n Iave=400m Vpk=35 Bv=75 Ibv=100u mfg=OnSemi type=silicon)")
NET_MODEL("2N3904 NPN(IS=1E-14 VAF=100 Bf=300 IKF=0.4 XTB=1.5 BR=4 CJC=4E-12 CJE=8E-12 RB=20 RC=0.1 RE=0.1 TR=250E-9 TF=350E-12 ITF=1 VTF=2 XTF=3 Vceo=40 Icrating=200m mfg=Philips)")
NET_MODEL("LM748 OPAMP(TYPE=3 VLH=2.0 VLL=2.0 FPF=5 UGF=800k SLEW=0.7M RI=800k RO=60 DAB=0.001)")
SOLVER(Solver, 48000)
ANALOG_INPUT(V15, 15)
ANALOG_INPUT(V7_5, 7.5)
ANALOG_INPUT(V5, 5)
ALIAS(VCC, V5)
TTL_INPUT(PL1_CRASH, 1) // active high
TTL_INPUT(PL2_CRASH, 0) // active high
TTL_INPUT(PL3_CRASH, 0) // active high
TTL_INPUT(PL4_CRASH, 0) // active high
LOCAL_SOURCE(PLAYER_CRASH)
NET_C(GND, PL1_CRASH.GND, PL2_CRASH.GND, PL3_CRASH.GND, PL4_CRASH.GND)
NET_C(VCC, PL1_CRASH.VCC, PL2_CRASH.VCC, PL3_CRASH.VCC, PL4_CRASH.VCC)
// HLE Noise Gen
CLOCK(NOISE_CLOCK, 10000)
NET_C(NOISE_CLOCK.GND, GND)
NET_C(NOISE_CLOCK.VCC, VCC)
SYS_NOISE_MT_N(NOISE, 0.1)
NET_C(NOISE.I, NOISE_CLOCK.Q)
// White Noise
#if HLE_NOISE
NET_C(NOISE.1, V7_5)
ALIAS(WHITE_NOISE, NOISE.2)
#else
RES(R240, RES_K(1.2))
RES(R241, RES_M(1))
RES(R242, 100)
RES(R243, RES_M(1))
RES(R244, RES_K(47))
RES(R245, RES_K(10))
RES(R246, RES_K(1))
RES(R247, RES_K(10))
RES(R248, RES_M(1))
CAP(C99, CAP_U(2.2))
//CAP(C100, CAP_P(100))
CAP(C101, CAP_U(6.8))
CAP(C102, CAP_U(2.2))
CAP(C103, CAP_U(6.8))
//QBJT_EB(Q8, "2N3904") // Used as a reverse-biased noise source.
QBJT_EB(Q9, "2N3904")
OPAMP(1A, "LM748")
NET_C(1A.GND, GND)
NET_C(1A.VCC, C101.1, R241.1, R240.1)
DIODE(CR22, "1N4454")
NET_C(NOISE.1, R241.2, 1A.PLUS)
NET_C(NOISE.2, C99.1, GND)
// White Noise
NET_C(V15, R240.2, R246.1)
NET_C(C99.2, R242.1)
NET_C(R242.2, R243.1, CR22.K, 1A.MINUS)
NET_C(CR22.A, R244.1)
NET_C(R243.2, R244.2, 1A.OUT, R245.1)
NET_C(C101.2, GND)
NET_C(R245.2, C102.1)
NET_C(C102.2, R248.1, Q9.B)
NET_C(Q9.E, GND)
NET_C(Q9.C, R248.2, R247.1)
NET_C(R247.2, R246.2, C103.1)
NET_C(C103.2, GND)
ALIAS(WHITE_NOISE, Q9.C)
#endif
SUBMODEL(PLAYER_CRASH, PLAYER_1_CRASH)
NET_C(PLAYER_1_CRASH.NOISE_IN, WHITE_NOISE)
NET_C(PLAYER_1_CRASH.CRASH_IN, PL1_CRASH.Q)
NET_C(PLAYER_1_CRASH.V15, V15)
NET_C(PLAYER_1_CRASH.VCC, VCC)
NET_C(PLAYER_1_CRASH.GND, GND)
NETLIST_END()

View File

@ -0,0 +1,10 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#ifndef MAME_AUDIO_NL_CARPOLO_H
#define MAME_AUDIO_NL_CARPOLO_H
#pragma once
NETLIST_EXTERNAL(carpolo)
#endif // MAME_AUDIO_NL_CARPOLO_H

View File

@ -0,0 +1,334 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//
// Netlist for Fire One
//
// Derived from the schematics in the manual.
//
// Known problems/issues:
//
// * None.
//
#include "netlist/devices/net_lib.h"
#include "nl_fireone.h"
//
// 556 is just two 555s in one package
//
#define NE556_DIP(name) SUBMODEL(_NE556_DIP, name)
#define LM556_DIP NE556_DIP
static NETLIST_START(_NE556_DIP)
NE555(A)
NE555(B)
NET_C(A.GND, B.GND)
NET_C(A.VCC, B.VCC)
DIPPINS( /* +--------------+ */
A.DISCH, /* 1DISCH |1 ++ 14| VCC */ A.VCC,
A.THRESH, /* 1THRES |2 13| 2DISCH */ B.DISCH,
A.CONT, /* 1CONT |3 12| 2THRES */ B.THRESH,
A.RESET, /* 1RESET |4 NE556 11| 2CONT */ B.CONT,
A.OUT, /* 1OUT |5 10| 2RESET */ B.RESET,
A.TRIG, /* 1TRIG |6 9| 2OUT */ B.OUT,
A.GND, /* GND |7 8| 2TRIG */ B.TRIG
/* +--------------+ */
)
NETLIST_END()
//
// Main netlist
//
NETLIST_START(fireone)
NET_MODEL("2N3704 NPN(IS=26.03f VAF=90.7 Bf=736.1K IKF=.1983 XTB=1.5 BR=1.024 CJC=11.01p CJE=24.07p RB=10 RC=.5 RE=.5 TR=233.8n TF=1.03n ITF=0 VTF=0 XTF=0 mfg=Motorola)")
SOLVER(Solver, 48000)
ANALOG_INPUT(V12, 12)
ANALOG_INPUT(VM12, -12)
ANALOG_INPUT(V5, 5)
ALIAS(VCC, V5)
TTL_INPUT(LTORP, 0) // active high
TTL_INPUT(LSHPHT, 0) // active high
TTL_INPUT(LBOOM, 0) // active high
TTL_INPUT(SOUND_OFF, 0) // active high
TTL_INPUT(RTORP, 0) // active high
TTL_INPUT(RSHPHT, 0) // active high
TTL_INPUT(RBOOM, 0) // active high
TTL_INPUT(SUBENG, 0) // active high
TTL_INPUT(ALERT, 0) // active high
//TTL_INPUT(SONAR_ENABLE, 0) // active high
TTL_INPUT(SONAR_SYNC, 0) // active low
NET_C(V12, LTORP.VCC, LSHPHT.VCC, LBOOM.VCC, SOUND_OFF.VCC, RTORP.VCC, RSHPHT.VCC, RBOOM.VCC, SUBENG.VCC, ALERT.VCC, SONAR_SYNC.VCC)
NET_C(GND, LTORP.GND, LSHPHT.GND, LBOOM.GND, SOUND_OFF.GND, RTORP.GND, RSHPHT.GND, RBOOM.GND, SUBENG.GND, ALERT.GND, SONAR_SYNC.GND)
LOCAL_SOURCE(_NE556_DIP)
TTL_7406_GATE(IC27_A)
TTL_7406_GATE(IC27_C)
TTL_7406_GATE(IC27_D)
NET_C(VCC, IC27_A.VCC, IC27_C.VCC, IC27_D.VCC)
NET_C(GND, IC27_A.GND, IC27_C.GND, IC27_D.GND)
//TTL_7406_GATE(IC27_E)
//CD4070_GATE(IC41_A)
//CD4070_GATE(IC41_B)
CD4070_GATE(IC41_C)
CD4070_GATE(IC41_D)
NET_C(V12, /*IC41_A.VDD, IC41_B.VDD,*/ IC41_C.VDD, IC41_D.VDD)
NET_C(GND, /*IC41_A.VSS, IC41_B.VSS,*/ IC41_C.VSS, IC41_D.VSS)
CD4006_DIP(IC40)
NET_C(V12, IC40.14)
NET_C(GND, IC40.7)
CD4017_DIP(IC25)
NET_C(V12, IC25.16)
NET_C(GND, IC25.8)
CD4013(IC3)
NET_C(V12, IC3.VDD)
NET_C(GND, IC3.VSS)
MC1558_DIP(IC6)
NET_C(IC6.8, V12)
NET_C(IC6.4, VM12)
MC1558_DIP(IC16)
NET_C(IC16.8, V12)
NET_C(IC16.4, VM12)
MC1558_DIP(IC17)
NET_C(IC17.8, V12)
NET_C(IC17.4, VM12)
NE555(IC29)
NE556_DIP(IC31)
NET_C(IC31.14, V5)
NET_C(IC31.7, GND)
MC3340_DIP(IC28)
NET_C(IC28.8, V12)
NET_C(IC28.3, GND)
MC3340_DIP(IC30)
NET_C(IC30.8, V12)
NET_C(IC30.3, GND)
RES(R19, RES_K(150))
RES(R27, RES_K(270))
RES(R35, RES_K(1))
RES(R36, RES_K(15))
RES(R37, RES_K(15))
RES(R38, RES_K(820))
RES(R39, RES_M(1))
RES(R56, RES_K(10))
RES(R62, RES_M(1))
RES(R66, RES_K(27))
RES(R68, RES_K(100))
RES(R69, RES_M(1))
RES(R70, RES_K(10))
RES(R71, RES_K(16))
RES(R72, RES_K(68))
RES(R73, RES_K(47))
RES(R75, RES_K(120))
RES(R79, RES_K(130))
RES(R80, RES_K(130))
RES(R82, RES_K(160))
RES(R83, RES_M(1))
RES(R84, RES_K(100))
RES(R85, RES_K(270))
RES(R86, RES_K(16))
RES(R87, RES_K(100))
//RES(R101, RES_K(10))
RES(R102, RES_K(3))
RES(R103, RES_K(3))
RES(R104, RES_M(1))
RES(R105, RES_K(100))
RES(R106, RES_K(100))
RES(R107, RES_K(47))
RES(R108, RES_K(20))
RES(R110, RES_K(1))
RES(R117, RES_K(20))
RES(R120, RES_K(5.6))
RES(R122, RES_K(2.7))
RES(R123, RES_K(100))
RES(R124, RES_K(3))
RES(R125, RES_K(3))
RES(R126, RES_K(6.8))
RES(R127, RES_K(8.2))
RES(R137, RES_K(5.6))
RES(R138, RES_K(47))
RES(R139, 100)
RES(R141, RES_K(3))
//RES(R142, RES_K(56))
//RES(R143, RES_K(56))
RES(R140, RES_K(10))
//RES(R, RES_K())
CAP(C23, CAP_U(0.33))
CAP(C26, CAP_U(0.022))
CAP(C27, CAP_U(0.022))
CAP(C45, CAP_U(0.1))
CAP(C51, CAP_U(0.1))
CAP(C52, CAP_U(0.1))
CAP(C55, CAP_U(0.1))
CAP(C70, CAP_U(1.0))
CAP(C72, CAP_U(2.2))
CAP(C73, CAP_U(1.0))
CAP(C74, CAP_U(1.0))
CAP(C75, CAP_U(0.1))
CAP(C80, CAP_U(1.0))
CAP(C81, CAP_U(0.1))
CAP(C84, CAP_U(0.1))
CAP(C85, CAP_U(2.2))
CAP(C100, CAP_U(0.22))
//CAP(C102, CAP_U(0.001))
CAP(C114, CAP_U(0.1))
//CAP(C, CAP_U())
DIODE(D2, "1N914")
DIODE(D3, "1N914")
DIODE(D7, "1N914")
DIODE(D8, "1N914")
DIODE(D14, "1N914")
QBJT_EB(Q2, "2N3704")
// Noise Generator
CLOCK(HLE_SONAR_CLOCK, 998)
NET_C(HLE_SONAR_CLOCK.GND, GND)
NET_C(HLE_SONAR_CLOCK.VCC, V12)
SWITCH2(SONAR_ENABLE)
NET_C(SONAR_ENABLE.1, HLE_SONAR_CLOCK.Q)
NET_C(SONAR_ENABLE.2, GND)
NET_C(SONAR_ENABLE.Q, IC40.3)
NET_C(IC40.1, IC40.12, IC41_C.A)
NET_C(IC40.4, IC41_C.Q)
NET_C(IC40.5, IC41_D.Q)
NET_C(IC40.6, IC40.10, R141.1, C45.1)
ALIAS(NOISE_A, IC40.10)
NET_C(R141.2, R140.1)
NET_C(R140.2, V12)
ALIAS(NOISE, R140.1)
NET_C(IC40.8, IC41_C.B)
NET_C(IC40.13, IC41_D.A)
// Sonar
NET_C(IC27_A.A, SONAR_SYNC.Q)
NET_C(IC27_A.Y, R70.1, IC25.15, IC41_D.B)
NET_C(R70.2, V12, IC29.RESET)
NET_C(IC29.GND, GND)
NET_C(IC29.VCC, V12)
NET_C(IC29.DISCH, R110.1, R107.1)
NET_C(R110.2, V12)
NET_C(IC29.THRESH, IC29.TRIG, R107.2, C72.1)
NET_C(C72.2, GND)
NET_C(IC29.OUT, D3.K, IC3.CLOCK)
NET_C(IC3.QQ, IC3.DATA)
NET_C(IC3.SET, IC3.RESET, GND)
NET_C(IC3.Q, D2.K, IC25.14)
NET_C(IC25.13, GND)
NET_C(IC25.2, R36.1)
NET_C(IC25.4, R72.1)
NET_C(IC25.10, R73.1)
NET_C(IC25.11, R75.1)
NET_C(R36.2, R72.2, R73.2, R75.2, D3.A, D2.A, R19.2, Q2.C)
NET_C(NOISE_A, R138.1)
NET_C(R138.2, C100.1, R137.1)
NET_C(C100.2, GND)
NET_C(R137.2, R139.1, C27.1, C26.1, R19.1)
NET_C(R139.2, GND)
NET_C(IC6.3, GND)
NET_C(IC6.2, R38.1, C27.2)
NET_C(IC6.1, R37.1, R38.2, R85.1, R27.1, C26.2)
NET_C(R37.2, D7.A, D8.K, IC6.5)
NET_C(D7.K, GND)
NET_C(D8.A, GND)
NET_C(IC6.6, R35.1, R39.1)
NET_C(R35.2, C23.1)
NET_C(C23.2, GND)
NET_C(IC6.7, R56.1, R39.2)
NET_C(R56.2, D14.K, Q2.B)
NET_C(D14.A, GND)
NET_C(Q2.E, GND)
ALIAS(MIX_L, R27.2)
ALIAS(MIX_R, R85.2)
// Low Filter
NET_C(C45.2, R68.1)
NET_C(IC16.6, R68.2, R66.1)
NET_C(IC16.5, GND)
NET_C(IC16.7, R66.2, R71.1)
NET_C(R71.2, R86.1, C51.1)
NET_C(R86.2, C55.1, IC17.5)
NET_C(C55.2, GND)
NET_C(C51.2, IC17.7, R82.1)
NET_C(IC17.6, R82.2, R123.1)
NET_C(R123.2, GND)
ALIAS(RUMBLE, IC17.7)
// Submarine Engine
NET_C(IC31.4, V5)
NET_C(IC31.1, R120.1, R122.1)
NET_C(R120.2, V5)
NET_C(IC31.2, IC31.6, IC31.11, R122.2, C85.1)
NET_C(C85.2, GND)
NET_C(IC31.5, GND)
NET_C(IC31.13, R126.1, R127.1)
NET_C(R126.2, V5)
NET_C(IC31.8, IC31.12, R127.2, C84.1)
NET_C(C84.2, GND)
NET_C(IC31.10, SUBENG.Q)
NET_C(IC31.9, R124.1)
NET_C(R124.2, R125.1, C114.1)
NET_C(C114.2, GND)
NET_C(R125.2, R79.1, R80.1, C52.1)
NET_C(C52.2, GND)
NET_C(R79.2, MIX_L)
NET_C(R80.2, MIX_R)
// Ship Explosion (L)
NET_C(RUMBLE, R87.1)
NET_C(R87.2, R84.1, C80.1)
NET_C(R84.2, GND)
NET_C(IC30.1, C80.2)
NET_C(IC30.7, R117.1)
NET_C(IC30.6, C81.1)
NET_C(C81.2, GND)
NET_C(LBOOM.Q, IC27_C.A)
NET_C(IC27_C.Y, R103.1)
NET_C(R103.2, R104.1, C70.1)
NET_C(C70.2, GND)
NET_C(R104.2, IC17.3, R83.1)
NET_C(R83.2, V5)
NET_C(IC17.1, IC17.2, IC30.2)
NET_C(R117.2, MIX_L)
// Ship Explosion (R)
NET_C(RUMBLE, R105.1)
NET_C(R105.2, R106.1, C74.1)
NET_C(R106.2, GND)
NET_C(IC28.1, C74.2)
NET_C(IC28.7, R108.1)
NET_C(IC28.6, C75.1)
NET_C(C75.2, GND)
NET_C(RBOOM.Q, IC27_D.A)
NET_C(IC27_D.Y, R102.1)
NET_C(R102.2, R69.1, C73.1)
NET_C(C73.2, GND)
NET_C(R69.2, IC16.3, R62.1)
NET_C(R62.2, V5)
NET_C(IC16.1, IC16.2, IC28.2)
NET_C(R108.2, MIX_R)
NETLIST_END()

View File

@ -0,0 +1,10 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#ifndef MAME_AUDIO_NL_FIREONE_H
#define MAME_AUDIO_NL_FIREONE_H
#pragma once
NETLIST_EXTERNAL(fireone)
#endif // MAME_AUDIO_NL_FIREONE_H

View File

@ -290,6 +290,18 @@ void carpolo_state::carpolo(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_carpolo);
PALETTE(config, m_palette, FUNC(carpolo_state::carpolo_palette), 12*2+2*16+4*2);
/* sound hardware */
NETLIST_SOUND(config, "sound_nl", 48000)
.set_source(NETLIST_NAME(carpolo))
.add_route(ALL_OUTPUTS, "mono", 1.0);
NETLIST_LOGIC_INPUT(config, "sound_nl:player_crash1", "PL1_CRASH.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:player_crash2", "PL2_CRASH.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:player_crash3", "PL3_CRASH.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:player_crash4", "PL4_CRASH.IN", 0);
NETLIST_STREAM_OUTPUT(config, "sound_nl:cout0", 0, "").set_mult_offset(10000.0, 0.0);
}

View File

@ -60,35 +60,36 @@ starfira has one less rom in total than starfire but everything passes as
*
*************************************/
void starfire_state::starfire_scratch_w(offs_t offset, uint8_t data)
void starfire_base_state::scratch_w(offs_t offset, uint8_t data)
{
/* A12 and A3 select video control registers */
/* A12 and A3 select video control registers, only the low 4 addresses have an effect */
if ((offset & 0x1008) == 0x1000)
{
switch (offset & 7)
{
case 0: m_starfire_vidctrl = data; break;
case 1: m_starfire_vidctrl1 = data; break;
case 2: m_io2_write(data); break;
case 0: m_vidctrl = data; break;
case 1: m_vidctrl1 = data; break;
case 2: sound_w(0, data); break;
case 3: sound_w(1, data); break;
default: break;
}
}
/* convert to a videoram offset */
offset = (offset & 0x31f) | ((offset & 0xe0) << 5);
m_starfire_videoram[offset] = data;
m_videoram[offset] = data;
}
uint8_t starfire_state::starfire_scratch_r(offs_t offset)
uint8_t starfire_base_state::scratch_r(offs_t offset)
{
/* A11 selects input ports */
if (offset & 0x800)
return m_input_read(offset);
return input_r(offset);
/* convert to a videoram offset */
offset = (offset & 0x31f) | ((offset & 0xe0) << 5);
return m_starfire_videoram[offset];
return m_videoram[offset];
}
@ -99,65 +100,75 @@ uint8_t starfire_state::starfire_scratch_r(offs_t offset)
*
*************************************/
void starfire_state::starfire_sound_w(uint8_t data)
void starfire_state::sound_w(offs_t offset, uint8_t data)
{
// starfire sound samples (preliminary)
uint8_t rise = data & ~m_prev_sound;
m_prev_sound = data;
// d0: rumble
if (rise & 1) m_samples->start(0, 0, true);
if (~data & 1) m_samples->stop(0);
if (BIT(rise, 0)) m_samples->start(0, 0, true);
if (BIT(~data, 0)) m_samples->stop(0);
// d1: explosion
// d2: tie weapon
// d3: laser
if (rise & 2) m_samples->start(1, 1);
if (rise & 4) m_samples->start(2, 2);
if (rise & 8) m_samples->start(3, 3);
if (BIT(rise, 1)) m_samples->start(1, 1);
if (BIT(rise, 2)) m_samples->start(2, 2);
if (BIT(rise, 3)) m_samples->start(3, 3);
// these are from the same generator (called "computer" in schematics)
// d4: track
// d5: lock
// d6: scanner
// d7: overheat
if (rise & 0x80) m_samples->start(4, 7);
else if (rise & 0x40) m_samples->start(4, 6);
else if (rise & 0x20) m_samples->start(4, 5);
else if (rise & 0x10) m_samples->start(4, 4);
if (BIT(rise, 7)) m_samples->start(4, 7);
else if (BIT(rise, 6)) m_samples->start(4, 6);
else if (BIT(rise, 5)) m_samples->start(4, 5);
else if (BIT(rise, 4)) m_samples->start(4, 4);
}
void starfire_state::fireone_sound_w(uint8_t data)
void fireone_state::sound_w(offs_t offset, uint8_t data)
{
// TODO: sound
m_fireone_select = (data & 0x8) ? 0 : 1;
if (offset == 0)
{
m_sound_left_boom->write(BIT(data, 2));
m_player_select = BIT(~data, 3);
}
else
{
m_sound_right_boom->write(BIT(data, 2));
m_sound_submarine_engine->write(BIT(data, 4));
m_sound_sonar_sync->write(BIT(data, 6));
m_sound_sonar_enable->write(BIT(data, 7));
}
}
uint8_t starfire_state::starfire_input_r(offs_t offset)
uint8_t starfire_state::input_r(offs_t offset)
{
switch (offset & 15)
{
case 0: return ioport("DSW")->read();
case 0: return m_dsw->read();
case 1:
{
// d3 and d4 come from the audio circuit, how does it work exactly?
// tie_on sounds ok, but laser_on sounds buggy
uint8_t tie_on = m_samples->playing(2) ? 0x00 : 0x08;
uint8_t laser_on = m_samples->playing(3) ? 0x00 : 0x10;
uint8_t input = ioport("SYSTEM")->read() & 0xe7;
const uint8_t tie_on = m_samples->playing(2) ? 0x00 : 0x08;
const uint8_t laser_on = m_samples->playing(3) ? 0x00 : 0x10;
const uint8_t input = m_system->read() & 0xe7;
return input | tie_on | laser_on | 0x10; // disable laser_on for now
}
case 5: return ioport("STICKZ")->read();
case 6: return ioport("STICKX")->read();
case 7: return ioport("STICKY")->read();
case 5: return m_stick2->read();
case 6: return m_stickx->read();
case 7: return m_sticky->read();
default: return 0xff;
}
}
uint8_t starfire_state::fireone_input_r(offs_t offset)
uint8_t fireone_state::input_r(offs_t offset)
{
static const uint8_t fireone_paddle_map[64] =
static const uint8_t s_paddle_map[64] =
{
0x00,0x01,0x03,0x02,0x06,0x07,0x05,0x04,
0x0c,0x0d,0x0f,0x0e,0x0a,0x0b,0x09,0x08,
@ -171,12 +182,14 @@ uint8_t starfire_state::fireone_input_r(offs_t offset)
switch (offset & 15)
{
case 0: return ioport("DSW")->read();
case 1: return ioport("SYSTEM")->read();
case 0:
return m_dsw->read();
case 1:
return m_system->read();
case 2:
{
uint8_t input = m_fireone_select ? ioport("P1")->read() : ioport("P2")->read();
return (input & 0xc0) | fireone_paddle_map[input & 0x3f];
const uint8_t input = m_controls[m_player_select]->read();
return (input & 0xc0) | s_paddle_map[input & 0x3f];
}
default: return 0xff;
}
@ -190,12 +203,12 @@ uint8_t starfire_state::fireone_input_r(offs_t offset)
*
*************************************/
void starfire_state::main_map(address_map &map)
void starfire_base_state::main_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x9fff).rw(FUNC(starfire_state::starfire_scratch_r), FUNC(starfire_state::starfire_scratch_w));
map(0xa000, 0xbfff).rw(FUNC(starfire_state::starfire_colorram_r), FUNC(starfire_state::starfire_colorram_w)).share("colorram");
map(0xc000, 0xffff).rw(FUNC(starfire_state::starfire_videoram_r), FUNC(starfire_state::starfire_videoram_w)).share("videoram");
map(0x8000, 0x9fff).rw(FUNC(starfire_base_state::scratch_r), FUNC(starfire_base_state::scratch_w));
map(0xa000, 0xbfff).rw(FUNC(starfire_base_state::colorram_r), FUNC(starfire_base_state::colorram_w)).share("colorram");
map(0xc000, 0xffff).rw(FUNC(starfire_base_state::videoram_r), FUNC(starfire_base_state::videoram_w)).share("videoram");
}
@ -233,8 +246,8 @@ static INPUT_PORTS_START( starfire )
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_CUSTOM ) // (audio) TIE ON, see starfire_input_r
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_CUSTOM ) // (audio) LASER ON, see starfire_input_r
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_CUSTOM ) // (audio) TIE ON, see input_r
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_CUSTOM ) // (audio) LASER ON, see input_r
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_TILT ) // SLAM/STATIC
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
@ -306,6 +319,28 @@ INPUT_PORTS_END
*
*************************************/
void starfire_state::machine_start()
{
/* register for state saving */
save_item(NAME(m_prev_sound));
}
void starfire_state::machine_reset()
{
m_prev_sound = 0;
}
void fireone_state::machine_start()
{
/* register for state saving */
save_item(NAME(m_player_select));
}
void fireone_state::machine_reset()
{
m_player_select = 0;
}
static const char *const starfire_sample_names[] =
{
"*starfire",
@ -323,26 +358,61 @@ static const char *const starfire_sample_names[] =
INTERRUPT_GEN_MEMBER(starfire_state::vblank_int)
{
// starfire has a jumper for disabling NMI, used to do a complete RAM test
if (m_nmi.read_safe(0x01))
if (m_nmi->read())
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
void starfire_state::fireone(machine_config &config)
INTERRUPT_GEN_MEMBER(fireone_state::vblank_int)
{
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
void starfire_base_state::base_config(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, STARFIRE_CPU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &starfire_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(starfire_state::vblank_int));
m_maincpu->set_addrmap(AS_PROGRAM, &starfire_base_state::main_map);
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(STARFIRE_PIXEL_CLOCK, STARFIRE_HTOTAL, STARFIRE_HBEND, STARFIRE_HBSTART, STARFIRE_VTOTAL, STARFIRE_VBEND, STARFIRE_VBSTART);
m_screen->set_screen_update(FUNC(starfire_state::screen_update_starfire));
m_screen->set_screen_update(FUNC(starfire_base_state::screen_update));
}
void fireone_state::fireone(machine_config &config)
{
base_config(config);
m_maincpu->set_vblank_int("screen", FUNC(fireone_state::vblank_int));
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
NETLIST_SOUND(config, "sound_nl", 48000)
.set_source(NETLIST_NAME(fireone))
.add_route(0, "lspeaker", 1.0)
.add_route(0, "rspeaker", 1.0);
NETLIST_LOGIC_INPUT(config, "sound_nl:ltorp", "LTORP.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:lshpht", "LSHPHT.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:lboom", "LBOOM.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:sound_off", "SOUND_OFF.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:rtorp", "RTORP.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:rshpht", "RSHPHT.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:rboom", "RBOOM.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:subeng", "SUBENG.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:alert", "ALERT.IN", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:sonar_enable", "SONAR_ENABLE.POS", 0);
NETLIST_LOGIC_INPUT(config, "sound_nl:sonar_sync", "SONAR_SYNC.IN", 0);
NETLIST_STREAM_OUTPUT(config, "sound_nl:cout0", 0, "MIX_L").set_mult_offset(10000.0, 0.0);
NETLIST_STREAM_OUTPUT(config, "sound_nl:cout1", 1, "MIX_R").set_mult_offset(10000.0, 0.0);
}
void starfire_state::starfire(machine_config &config)
{
fireone(config);
base_config(config);
m_maincpu->set_vblank_int("screen", FUNC(starfire_state::vblank_int));
/* sound hardware */
SPEAKER(config, "mono").front_center();
@ -440,41 +510,13 @@ ROM_START( starfir2 )
ROM_LOAD( "prom-2.8a", 0x0020, 0x0020, CRC(9b713924) SHA1(943ad55d232f7bb99886a9a273dd14a1e1533491) ) /* BPROM type is N82S123 */
ROM_END
/*************************************
*
* Driver init
*
*************************************/
void starfire_state::init_starfire()
{
m_input_read = read8sm_delegate(*this, FUNC(starfire_state::starfire_input_r));
m_io2_write = write8smo_delegate(*this, FUNC(starfire_state::starfire_sound_w));
/* register for state saving */
save_item(NAME(m_prev_sound));
}
void starfire_state::init_fireone()
{
m_input_read = read8sm_delegate(*this, FUNC(starfire_state::fireone_input_r));
m_io2_write = write8smo_delegate(*this, FUNC(starfire_state::fireone_sound_w));
/* register for state saving */
save_item(NAME(m_fireone_select));
}
/*************************************
*
* Game drivers
*
*************************************/
GAME( 1979, starfire, 0, starfire, starfire, starfire_state, init_starfire, ROT0, "Exidy", "Star Fire (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, starfirea,starfire, starfire, starfire, starfire_state, init_starfire, ROT0, "Exidy", "Star Fire (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, fireone, 0, fireone, fireone, starfire_state, init_fireone, ROT0, "Exidy", "Fire One", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, starfir2, 0, starfire, starfire, starfire_state, init_starfire, ROT0, "Exidy", "Star Fire 2", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, starfire, 0, starfire, starfire, starfire_state, empty_init, ROT0, "Exidy", "Star Fire (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, starfirea,starfire, starfire, starfire, starfire_state, empty_init, ROT0, "Exidy", "Star Fire (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1979, fireone, 0, fireone, fireone, fireone_state, empty_init, ROT0, "Exidy", "Fire One", MACHINE_SUPPORTS_SAVE )
GAME( 1979, starfir2, 0, starfire, starfire, starfire_state, empty_init, ROT0, "Exidy", "Star Fire 2", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )

View File

@ -17,6 +17,9 @@
#include "machine/7474.h"
#include "machine/74148.h"
#include "machine/74153.h"
#include "machine/netlist.h"
#include "netlist/nl_setup.h"
#include "audio/nl_carpolo.h"
#include "emupal.h"
class carpolo_state : public driver_device
@ -47,6 +50,7 @@ public:
, m_dial(*this, "DIAL%u", 0U)
, m_in(*this, "IN%u", 0U)
, m_pedals(*this, "PEDALS")
, m_player_crash(*this, "sound_nl:player_crash%u", 1U)
{ }
void init_carpolo();
@ -151,6 +155,8 @@ private:
int x2, int y2, int code2, int flipy2,
int *col_x, int *col_y);
void main_map(address_map &map);
required_device_array<netlist_mame_logic_input_device, 4> m_player_crash;
};
#endif // MAME_INCLUDES_CARPOLO_H

View File

@ -10,6 +10,9 @@
#pragma once
#include "machine/netlist.h"
#include "netlist/nl_setup.h"
#include "audio/nl_fireone.h"
#include "sound/samples.h"
#include "screen.h"
@ -26,67 +29,120 @@
#define STARFIRE_NUM_PENS (0x40)
class starfire_state : public driver_device
class starfire_base_state : public driver_device
{
public:
starfire_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_starfire_colorram(*this, "colorram"),
m_starfire_videoram(*this, "videoram"),
m_samples(*this, "samples"),
m_nmi(*this, "NMI"),
m_input_read(*this),
m_io2_write(*this),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen")
starfire_base_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_colorram(*this, "colorram")
, m_videoram(*this, "videoram")
, m_dsw(*this, "DSW")
, m_system(*this, "SYSTEM")
{ }
void fireone(machine_config &config);
void starfire(machine_config &config);
protected:
virtual void video_start() override;
void init_starfire();
void init_fireone();
private:
required_shared_ptr<uint8_t> m_starfire_colorram;
required_shared_ptr<uint8_t> m_starfire_videoram;
optional_device<samples_device> m_samples;
optional_ioport m_nmi;
uint8_t m_prev_sound;
uint8_t m_fireone_select;
uint8_t m_starfire_vidctrl;
uint8_t m_starfire_vidctrl1;
uint8_t m_starfire_color;
uint16_t m_starfire_colors[STARFIRE_NUM_PENS];
read8sm_delegate m_input_read;
write8smo_delegate m_io2_write;
emu_timer* m_scanline_timer;
bitmap_rgb32 m_starfire_screen;
void base_config(machine_config &config);
void main_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
required_shared_ptr<uint8_t> m_colorram;
required_shared_ptr<uint8_t> m_videoram;
required_ioport m_dsw;
required_ioport m_system;
void starfire_scratch_w(offs_t offset, uint8_t data);
uint8_t starfire_scratch_r(offs_t offset);
uint8_t starfire_input_r(offs_t offset);
uint8_t fireone_input_r(offs_t offset);
void starfire_sound_w(uint8_t data);
void fireone_sound_w(uint8_t data);
void starfire_colorram_w(offs_t offset, uint8_t data);
uint8_t starfire_colorram_r(offs_t offset);
void starfire_videoram_w(offs_t offset, uint8_t data);
uint8_t starfire_videoram_r(offs_t offset);
virtual void video_start() override;
uint32_t screen_update_starfire(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(starfire_scanline_callback);
INTERRUPT_GEN_MEMBER(vblank_int);
uint8_t m_vidctrl;
uint8_t m_vidctrl1;
uint8_t m_color;
uint16_t m_colors[STARFIRE_NUM_PENS];
emu_timer* m_scanline_timer;
bitmap_rgb32 m_screen_bitmap;
virtual uint8_t input_r(offs_t offset) = 0;
virtual void sound_w(offs_t offset, uint8_t data) = 0;
void scratch_w(offs_t offset, uint8_t data);
uint8_t scratch_r(offs_t offset);
void colorram_w(offs_t offset, uint8_t data);
uint8_t colorram_r(offs_t offset);
void videoram_w(offs_t offset, uint8_t data);
uint8_t videoram_r(offs_t offset);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(scanline_callback);
void get_pens(pen_t *pens);
void scanline_callback(uint32_t data);
};
void main_map(address_map &map);
class starfire_state : public starfire_base_state
{
public:
starfire_state(const machine_config &mconfig, device_type type, const char *tag)
: starfire_base_state(mconfig, type, tag)
, m_samples(*this, "samples")
, m_nmi(*this, "NMI")
, m_stick2(*this, "STICK2")
, m_stickx(*this, "STICKX")
, m_sticky(*this, "STICKY")
{ }
void starfire(machine_config &config);
private:
virtual void machine_start() override;
virtual void machine_reset() override;
required_device<samples_device> m_samples;
required_ioport m_nmi;
required_ioport m_stick2;
required_ioport m_stickx;
required_ioport m_sticky;
virtual uint8_t input_r(offs_t offset) override;
virtual void sound_w(offs_t offset, uint8_t data) override;
INTERRUPT_GEN_MEMBER(vblank_int);
uint8_t m_prev_sound;
};
class fireone_state : public starfire_base_state
{
public:
fireone_state(const machine_config &mconfig, device_type type, const char *tag)
: starfire_base_state(mconfig, type, tag)
, m_controls(*this, "P%u", 1U)
, m_sound_left_boom(*this, "sound_nl:lboom")
, m_sound_right_boom(*this, "sound_nl:rboom")
, m_sound_submarine_engine(*this, "sound_nl:subeng")
, m_sound_sonar_enable(*this, "sound_nl:sonar_enable")
, m_sound_sonar_sync(*this, "sound_nl:sonar_sync")
{ }
void fireone(machine_config &config);
private:
virtual void machine_start() override;
virtual void machine_reset() override;
required_ioport_array<2> m_controls;
virtual uint8_t input_r(offs_t offset) override;
virtual void sound_w(offs_t offset, uint8_t data) override;
uint8_t m_player_select;
INTERRUPT_GEN_MEMBER(vblank_int);
required_device<netlist_mame_logic_input_device> m_sound_left_boom;
required_device<netlist_mame_logic_input_device> m_sound_right_boom;
required_device<netlist_mame_logic_input_device> m_sound_submarine_engine;
required_device<netlist_mame_logic_input_device> m_sound_sonar_enable;
required_device<netlist_mame_logic_input_device> m_sound_sonar_sync;
};
#endif // MAME_INCLUDES_STARFIRE_H

View File

@ -17,17 +17,17 @@
*
*************************************/
void starfire_state::video_start()
void starfire_base_state::video_start()
{
m_screen->register_screen_bitmap(m_starfire_screen);
m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(starfire_state::starfire_scanline_callback),this));
m_screen->register_screen_bitmap(m_screen_bitmap);
m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(starfire_base_state::scanline_callback),this));
m_scanline_timer->adjust(m_screen->time_until_pos(STARFIRE_VBEND), STARFIRE_VBEND);
/* register for state saving */
save_item(NAME(m_starfire_vidctrl));
save_item(NAME(m_starfire_vidctrl1));
save_item(NAME(m_starfire_color));
save_item(NAME(m_starfire_colors));
save_item(NAME(m_vidctrl));
save_item(NAME(m_vidctrl1));
save_item(NAME(m_color));
save_item(NAME(m_colors));
}
@ -37,7 +37,7 @@ void starfire_state::video_start()
*
*************************************/
void starfire_state::starfire_colorram_w(offs_t offset, uint8_t data)
void starfire_base_state::colorram_w(offs_t offset, uint8_t data)
{
/* handle writes to the pseudo-color RAM */
if ((offset & 0xe0) == 0)
@ -45,19 +45,19 @@ void starfire_state::starfire_colorram_w(offs_t offset, uint8_t data)
int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4);
/* set RAM regardless */
int cl = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
int cl = (m_vidctrl1 & 0x80) ? m_color : (data & 0x1f);
int cr = (data >> 5) | ((offset & 0x100) >> 5);
cr |= (m_starfire_vidctrl1 & 0x80) ? (m_starfire_color & 0x10) : (data & 0x10);
cr |= (m_vidctrl1 & 0x80) ? (m_color & 0x10) : (data & 0x10);
m_starfire_colorram[offset & ~0x100] = cl;
m_starfire_colorram[offset | 0x100] = cr;
m_colorram[offset & ~0x100] = cl;
m_colorram[offset | 0x100] = cr;
m_starfire_color = cl;
m_color = cl;
/* don't modify the palette unless the TRANS bit is set */
if (m_starfire_vidctrl1 & 0x40)
if (m_vidctrl1 & 0x40)
{
m_starfire_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
m_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
}
}
@ -65,30 +65,30 @@ void starfire_state::starfire_colorram_w(offs_t offset, uint8_t data)
else
{
/* set RAM based on CDRM */
m_starfire_colorram[offset] = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
m_starfire_color = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
m_colorram[offset] = (m_vidctrl1 & 0x80) ? m_color : (data & 0x1f);
m_color = (m_vidctrl1 & 0x80) ? m_color : (data & 0x1f);
}
}
uint8_t starfire_state::starfire_colorram_r(offs_t offset)
uint8_t starfire_base_state::colorram_r(offs_t offset)
{
/* handle writes to the pseudo-color RAM, which also happen on reads */
if ((offset & 0xe0) == 0)
{
int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4);
int cl = m_starfire_colorram[offset & ~0x100];
int cr = m_starfire_colorram[offset | 0x100];
int cl = m_colorram[offset & ~0x100];
int cr = m_colorram[offset | 0x100];
/* don't modify the palette unless the TRANS bit is set */
if (m_starfire_vidctrl1 & 0x40)
if (m_vidctrl1 & 0x40)
{
m_starfire_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
m_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
}
return cl | ((cr & 0x7) << 5);
}
return m_starfire_colorram[offset];
return m_colorram[offset];
}
/*************************************
@ -97,26 +97,26 @@ uint8_t starfire_state::starfire_colorram_r(offs_t offset)
*
*************************************/
void starfire_state::starfire_videoram_w(offs_t offset, uint8_t data)
void starfire_base_state::videoram_w(offs_t offset, uint8_t data)
{
int sh, lr, dm, ds, mask, d0, dalu;
int offset1 = offset & 0x1fff;
int offset2 = (offset + 0x100) & 0x1fff;
/* PROT */
if (!(offset & 0xe0) && !(m_starfire_vidctrl1 & 0x20))
if (!(offset & 0xe0) && !(m_vidctrl1 & 0x20))
return;
/* selector 6A */
if (offset & 0x2000)
{
sh = (m_starfire_vidctrl >> 1) & 0x07;
lr = m_starfire_vidctrl & 0x01;
sh = (m_vidctrl >> 1) & 0x07;
lr = m_vidctrl & 0x01;
}
else
{
sh = (m_starfire_vidctrl >> 5) & 0x07;
lr = (m_starfire_vidctrl >> 4) & 0x01;
sh = (m_vidctrl >> 5) & 0x07;
lr = (m_vidctrl >> 4) & 0x01;
}
/* mirror bits 5B/5C/5D/5E */
@ -132,18 +132,18 @@ void starfire_state::starfire_videoram_w(offs_t offset, uint8_t data)
/* ROLL */
if ((offset & 0x1f00) == 0x1f00)
{
if (m_starfire_vidctrl1 & 0x10)
if (m_vidctrl1 & 0x10)
mask &= 0x00ff;
else
mask &= 0xff00;
}
/* ALU 8B/8D */
d0 = (m_starfire_videoram[offset1] << 8) | m_starfire_videoram[offset2];
d0 = (m_videoram[offset1] << 8) | m_videoram[offset2];
dalu = d0 & ~mask;
d0 &= mask;
ds &= mask;
switch (~m_starfire_vidctrl1 & 15)
switch (~m_vidctrl1 & 15)
{
case 0: dalu |= ds ^ mask; break;
case 1: dalu |= (ds | d0) ^ mask; break;
@ -164,20 +164,20 @@ void starfire_state::starfire_videoram_w(offs_t offset, uint8_t data)
}
/* final output */
m_starfire_videoram[offset1] = dalu >> 8;
m_starfire_videoram[offset2] = dalu;
m_videoram[offset1] = dalu >> 8;
m_videoram[offset2] = dalu;
/* color output */
if (!(offset & 0x2000) && !(m_starfire_vidctrl1 & 0x80))
if (!(offset & 0x2000) && !(m_vidctrl1 & 0x80))
{
if (mask & 0xff00)
m_starfire_colorram[offset1] = m_starfire_color;
m_colorram[offset1] = m_color;
if (mask & 0x00ff)
m_starfire_colorram[offset2] = m_starfire_color;
m_colorram[offset2] = m_color;
}
}
uint8_t starfire_state::starfire_videoram_r(offs_t offset)
uint8_t starfire_base_state::videoram_r(offs_t offset)
{
int sh, mask, d0;
int offset1 = offset & 0x1fff;
@ -185,9 +185,9 @@ uint8_t starfire_state::starfire_videoram_r(offs_t offset)
/* selector 6A */
if (offset & 0x2000)
sh = (m_starfire_vidctrl >> 1) & 0x07;
sh = (m_vidctrl >> 1) & 0x07;
else
sh = (m_starfire_vidctrl >> 5) & 0x07;
sh = (m_vidctrl >> 5) & 0x07;
/* shifters 6D/6E */
mask = 0xff00 >> sh;
@ -195,14 +195,14 @@ uint8_t starfire_state::starfire_videoram_r(offs_t offset)
/* ROLL */
if ((offset & 0x1f00) == 0x1f00)
{
if (m_starfire_vidctrl1 & 0x10)
if (m_vidctrl1 & 0x10)
mask &= 0x00ff;
else
mask &= 0xff00;
}
/* munge the results */
d0 = (m_starfire_videoram[offset1] & (mask >> 8)) | (m_starfire_videoram[offset2] & mask);
d0 = (m_videoram[offset1] & (mask >> 8)) | (m_videoram[offset2] & mask);
d0 = (d0 << sh) | (d0 >> (8 - sh));
return d0 & 0xff;
}
@ -215,41 +215,41 @@ uint8_t starfire_state::starfire_videoram_r(offs_t offset)
*
*************************************/
void starfire_state::get_pens(pen_t *pens)
void starfire_base_state::get_pens(pen_t *pens)
{
offs_t offs;
for (offs = 0; offs < STARFIRE_NUM_PENS; offs++)
{
uint16_t color = m_starfire_colors[offs];
uint16_t color = m_colors[offs];
pens[offs] = rgb_t(pal3bit(color >> 6), pal3bit(color >> 3), pal3bit(color >> 0));
}
}
TIMER_CALLBACK_MEMBER(starfire_state::starfire_scanline_callback)
TIMER_CALLBACK_MEMBER(starfire_base_state::scanline_callback)
{
pen_t pens[STARFIRE_NUM_PENS];
int y = param;
get_pens(pens);
uint8_t *pix = &m_starfire_videoram[y];
uint8_t *col = &m_starfire_colorram[y];
uint8_t *pix = &m_videoram[y];
uint8_t *col = &m_colorram[y];
for (int x = 0; x < 256; x += 8)
{
int data = pix[0];
int color = col[0];
m_starfire_screen.pix32(y, x + 0) = pens[color | ((data >> 2) & 0x20)];
m_starfire_screen.pix32(y, x + 1) = pens[color | ((data >> 1) & 0x20)];
m_starfire_screen.pix32(y, x + 2) = pens[color | ((data >> 0) & 0x20)];
m_starfire_screen.pix32(y, x + 3) = pens[color | ((data << 1) & 0x20)];
m_starfire_screen.pix32(y, x + 4) = pens[color | ((data << 2) & 0x20)];
m_starfire_screen.pix32(y, x + 5) = pens[color | ((data << 3) & 0x20)];
m_starfire_screen.pix32(y, x + 6) = pens[color | ((data << 4) & 0x20)];
m_starfire_screen.pix32(y, x + 7) = pens[color | ((data << 5) & 0x20)];
m_screen_bitmap.pix32(y, x + 0) = pens[color | ((data >> 2) & 0x20)];
m_screen_bitmap.pix32(y, x + 1) = pens[color | ((data >> 1) & 0x20)];
m_screen_bitmap.pix32(y, x + 2) = pens[color | ((data >> 0) & 0x20)];
m_screen_bitmap.pix32(y, x + 3) = pens[color | ((data << 1) & 0x20)];
m_screen_bitmap.pix32(y, x + 4) = pens[color | ((data << 2) & 0x20)];
m_screen_bitmap.pix32(y, x + 5) = pens[color | ((data << 3) & 0x20)];
m_screen_bitmap.pix32(y, x + 6) = pens[color | ((data << 4) & 0x20)];
m_screen_bitmap.pix32(y, x + 7) = pens[color | ((data << 5) & 0x20)];
pix += 256;
col += 256;
@ -260,9 +260,9 @@ TIMER_CALLBACK_MEMBER(starfire_state::starfire_scanline_callback)
m_scanline_timer->adjust(m_screen->time_until_pos(y), y);
}
uint32_t starfire_state::screen_update_starfire(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t starfire_base_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
copybitmap(bitmap, m_starfire_screen, 0, 0, 0, 0, cliprect);
copybitmap(bitmap, m_screen_bitmap, 0, 0, 0, 0, cliprect);
return 0;
}