summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2021-11-18 03:33:30 +1100
committer Robbbert <Robbbert@users.noreply.github.com>2021-11-18 03:33:30 +1100
commit886d6289df1665aff881277a42f162b181530d67 (patch)
treea141fd0d69a92d06149aaaec6409b98df09b4249 /src
parentdff6c8c10392c1fdc3fcaed986cdfa07f5f5bf1e (diff)
nsm.cpp: WIP. Test menu works.
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/nsm.cpp454
-rw-r--r--src/mame/drivers/techno.cpp2
-rw-r--r--src/mame/layout/nsm.lay80
3 files changed, 417 insertions, 119 deletions
diff --git a/src/mame/drivers/nsm.cpp b/src/mame/drivers/nsm.cpp
index 50782e39887..b713a88d23b 100644
--- a/src/mame/drivers/nsm.cpp
+++ b/src/mame/drivers/nsm.cpp
@@ -2,18 +2,36 @@
// copyright-holders:Robbbert
/********************************************************************************
- PINBALL
- NSM (Lowen) : Hot Fire Birds
+PINBALL
+NSM (Lowen) : Hot Fire Birds
- Schematic and PinMAME used as references
+Schematic and PinMAME used as references
- Everything in this machine is controlled by a serial bus based on the
- processor's CRU pins (serial i/o).
+Everything in this machine is controlled by a serial bus based on the
+ processor's CRU pins (serial i/o).
+To program the machine, you need to plug in a numeric keypad, engage test
+ mode, make the adjustments, and remove the keypad. For full scale setting up,
+ it seems you need a pilot's licence, and to be able to understand German.
+
+Setting up the machine (the simple way):
+- Turn Diag6 dip on, choose Reset
+- You get the test menu. Press num-4, then num-1 then num-Enter. It will slowly
+ set itself up.
+- When the menu reappears, turn Diag6 dip off, and choose Reset.
+- The machine now seems to be working, and you can insert coins, but then it reboots.
+
+If the display says FLiPPEr you can go into the test menu and then exit.
+
+Status:
+- See above. Unable to start a game.
+- gamesnsm keeps rebooting itself at start
+- Pressing the coin input buttons restarts the machine.
ToDo:
-- Inputs (i have no idea how CRU inputs work)
+- There's a protection circuit for E600 which isn't quite right yet.
+- Inputs (they are there, but unable to test)
- Mechanical sounds
-- Further testing, etc
+- Solenoids fail in the test menu
*********************************************************************************/
@@ -27,100 +45,373 @@ ToDo:
#include "nsm.lh"
-class nsm_state : public driver_device
+class nsm_state : public genpin_class
{
public:
nsm_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
+ : genpin_class(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
+ , m_nvram(*this, "nvram")
+ , m_io_keyboard(*this, "X%u", 0U)
, m_digits(*this, "digit%u", 0U)
+ , m_io_outputs(*this, "out%u", 0U)
{ }
void nsm(machine_config &config);
private:
- uint8_t ff_r();
- void cru_w(offs_t offset, uint8_t data);
- void oe_w(uint8_t data);
- void nsm_io_map(address_map &map);
- void nsm_map(address_map &map);
+ u8 ff_r() { return 1; }
+ void e600_w(offs_t, u8);
+ u8 enwnv_r();
+ u8 loadin_r();
+ u8 loadout_r();
+ u8 clockin_r();
+ void clockout_w(u8);
+ u8 np_clock_r(offs_t);
+ void np_sel1_w(u8);
+ void np_sel2_w(u8);
+ void np_load_w(u8);
+ u8 diag3_r();
+ u8 diag4_r();
+ u8 diag6_r();
+ void ay1a_w(u8);
+ void ay2a_w(u8);
+ void io_map(address_map &map);
+ void mem_map(address_map &map);
- uint8_t m_cru_data[9];
- uint8_t m_cru_count;
+ u8 m_cru_out[9]{};
+ u8 m_cru_in[3]{};
+ u8 m_cru_in_bit = 0;
+ u8 m_cru_overflow = 0;
+ u8 m_row = 0;
+ u8 m_np_cru = 0;
+ u8 m_np_sel = 0;
+ bool m_e600_locked = false;
virtual void machine_reset() override;
- virtual void machine_start() override { m_digits.resolve(); }
+ virtual void machine_start() override;
required_device<tms9995_device> m_maincpu;
- output_finder<60> m_digits;
+ required_shared_ptr<u8> m_nvram;
+ required_ioport_array<13> m_io_keyboard;
+ output_finder<48> m_digits;
+ output_finder<80> m_io_outputs; // 16 solenoids + 64 lamps
};
-void nsm_state::nsm_map(address_map &map)
+void nsm_state::mem_map(address_map &map)
{
- map(0x0000, 0x7fff).rom();
- map(0xe000, 0xefff).ram();
+ map(0x0000, 0x7fff).rom(); // ic602/3/4/5, 2764
+ map(0xe000, 0xe7ff).ram().share("nvram"); // ic606, 6116
+ map(0xe800, 0xefff).ram(); // ic607, 2016
map(0xffec, 0xffed).w("ay1", FUNC(ay8910_device::address_data_w));
map(0xffee, 0xffef).w("ay2", FUNC(ay8910_device::address_data_w));
+ map(0xe600, 0xe601).w(FUNC(nsm_state::e600_w));
}
-void nsm_state::nsm_io_map(address_map &map)
+void nsm_state::io_map(address_map &map)
{
- // 00-71 selected by IC600 (74LS151)
- map(0x0000, 0x001f).r(FUNC(nsm_state::ff_r)); // 5v supply
- map(0x0100, 0x011f).nopr(); // antenna
- map(0x0200, 0x021f).nopr(); // reset circuit
- map(0x0300, 0x031f).r(FUNC(nsm_state::ff_r)); // service plug
- map(0x0400, 0x041f).r(FUNC(nsm_state::ff_r)); // service plug
- map(0x0500, 0x051f).r(FUNC(nsm_state::ff_r)); // test of internal battery
- map(0x0600, 0x061f).r(FUNC(nsm_state::ff_r)); // sum of analog outputs of ay2
- //map(0x0700, 0x071f).nopr(); // serial data in
- map(0x1ee0, 0x1efb).nopw();
- map(0xfe40, 0xffff).nopr();
- map(0xff60, 0xff7f).w(FUNC(nsm_state::cru_w));
- map(0xffa0, 0xffa3).w(FUNC(nsm_state::oe_w));
+ // 000-71f selected by IC600 (74LS151)
+ map(0x0000, 0x001f).mirror(0xf8e0).r(FUNC(nsm_state::ff_r)); // 5v supply (low = black screen)
+ map(0x0100, 0x011f).mirror(0xf8e0).nopr(); // antenna (high = black screen)
+ map(0x0200, 0x021f).mirror(0xf8e0).nopr(); // reset circuit, not used?
+ map(0x0300, 0x031f).mirror(0xf8e0).r(FUNC(nsm_state::diag3_r)); // service plug (if low, the test fail msg stays up longer)
+ map(0x0400, 0x041f).mirror(0xf8e0).r(FUNC(nsm_state::diag4_r)); // service plug, not used?
+ map(0x0500, 0x051f).mirror(0xf8e0).nopr(); // test of internal battery (high = BA error)
+ map(0x0600, 0x061f).mirror(0xf8e0).r(FUNC(nsm_state::diag6_r)); // low = test menu (sch says ST703 but it's ST702)
+ map(0x1ee0, 0x1efb).noprw();
+ map(0xfe40, 0xfe4f).r(FUNC(nsm_state::np_clock_r));
+ map(0xff00, 0xff1f).r(FUNC(nsm_state::loadin_r)).w(FUNC(nsm_state::np_load_w));
+ map(0xff20, 0xff3f).r(FUNC(nsm_state::loadout_r));
+ map(0xff40, 0xff5f).r(FUNC(nsm_state::clockin_r));
+ map(0xff60, 0xff7f).w(FUNC(nsm_state::clockout_w));
+ map(0xff80, 0xff9f).w(FUNC(nsm_state::np_sel1_w));
+ map(0xffa0, 0xffbf).w(FUNC(nsm_state::np_sel2_w));
+ map(0xffe0, 0xffff).r(FUNC(nsm_state::enwnv_r));
}
static INPUT_PORTS_START( nsm )
+ PORT_START("X0")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("INP09")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_NAME("INP10")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("INP11")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_NAME("INP12")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP13")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP14")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP15")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP16")
+
+ PORT_START("X1")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("INP17")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_NAME("INP18")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_G) PORT_NAME("INP19")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_H) PORT_NAME("INP20")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("INP21")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP22")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP23")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP24")
+
+ PORT_START("X2")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("INP25")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) PORT_NAME("INP26")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_L) PORT_NAME("INP27")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("INP28")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP29")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP30")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP31")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP32")
+
+ PORT_START("X3")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("INP33")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_O) PORT_NAME("INP34")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_P) PORT_NAME("INP35")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("INP36")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP37")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP38")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP39")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP40")
+
+ PORT_START("X4")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("INP41")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("INP42")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("INP43")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) PORT_NAME("INP44")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP45")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP46")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP47")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP48")
+
+ PORT_START("X5")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_V) PORT_NAME("INP49")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("INP50")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_NAME("INP51")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) PORT_NAME("INP52")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP53")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP54")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP55")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP56")
+
+ PORT_START("X6")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("INP57")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_STOP) PORT_NAME("INP58")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH) PORT_NAME("INP59")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_COLON) PORT_NAME("INP60")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP61")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP62")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP63")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP64")
+
+ PORT_START("X7")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_QUOTE) PORT_NAME("INP01")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_NAME("INP02")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_NAME("INP03")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_NAME("INP04")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP05")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP06")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP07")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_NAME("INP08")
+
+ PORT_START("X8")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Right Flipper")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // *OUT_OK
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) // I5
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // I4
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // I1
+
+ PORT_START("X9")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_NAME("Tilt")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START ) // INP73
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("Left Flipper")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("Outhole")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // 12v
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN3 )
+
+ // Programming pad, keys are guesswork, no schematic or pictures exist
+ PORT_START("X10")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME("PAD12") // nothing
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("PAD13") // nothing
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("PAD04")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("PAD09")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("PAD08") // and scroll list
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("PAD07")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("PAD10")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("PAD00")
+
+ PORT_START("X11")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("PAD14") // nothing
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("PAD11") // backspace
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("PAD15") // nothing
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("PAD03")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("PAD02")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("PAD01")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("PAD06")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("PAD05")
+
+ PORT_START("X12")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_NAME("Diag3")
+ PORT_DIPNAME( 0x02, 0x02, "Diag4") // Appears to do nothing
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPSETTING( 0x02, DEF_STR(Off))
+ PORT_DIPNAME( 0x04, 0x04, "Diag6") // Test mode
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPSETTING( 0x04, DEF_STR(Off))
INPUT_PORTS_END
-uint8_t nsm_state::ff_r() { return 1; }
+// **** SERVICE SWITCHES ****
+u8 nsm_state::diag3_r()
+{
+ return BIT(m_io_keyboard[12]->read(), 0);
+}
+
+u8 nsm_state::diag4_r()
+{
+ return BIT(m_io_keyboard[12]->read(), 1);
+}
-void nsm_state::oe_w(uint8_t data)
+u8 nsm_state::diag6_r()
{
- m_cru_count = 9;
+ return BIT(m_io_keyboard[12]->read(), 2);
}
-void nsm_state::cru_w(offs_t offset, uint8_t data)
+u8 nsm_state::enwnv_r()
{
- offset &= 7;
- if (!offset)
- {
- m_cru_count--;
- m_cru_data[m_cru_count] = 0;
- }
- m_cru_data[m_cru_count] |= (data << offset);
+ m_e600_locked = false;
+ return m_cru_in_bit;
+}
+
+// Todo: find out how this really works
+void nsm_state::e600_w(offs_t offset, u8 data)
+{
+ if (offset && BIT(data, 4))
+ m_e600_locked = true;
+ if (!m_e600_locked)
+ m_nvram[0x600+offset] = data;
+}
+
+// **** CRU OUTPUTS ****
+// send clocked data from 4094 chain to outputs
+u8 nsm_state::loadout_r()
+{
+ // 0 = strobe for keyboard, lamps, display
+ u8 i;
+ for (i = 0; i < 8; i++)
+ if (BIT(m_cru_out[0], i))
+ m_row = i;
- uint8_t i,j;
- int segments;
- if (!m_cru_count && (offset == 7))
+ for (i = 0; i < 8; i++)
{
- m_cru_count = 9;
- //for (i = 0; i < 9; i++) printf("%02X ",m_cru_data[i]);printf("\n");
- for (i = 0; i < 8; i++)
- {
- if (BIT(m_cru_data[0], i))
- {
- for (j = 0; j < 5; j++)
- {
- segments = m_cru_data[8-j]^0xff;
- m_digits[j * 10 + i] = bitswap<16>(segments, 8, 8, 8, 8, 8, 8, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7);
- }
- }
- }
+ // 1 = Lamps
+ m_io_outputs[16+m_row*8+i] = BIT(m_cru_out[1], i) ? 0 : 1;
+ // 2,3 = Solenoids
+ m_io_outputs[i] = BIT(m_cru_out[2], i);
+ m_io_outputs[8+i] = BIT(m_cru_out[3], i);
}
+
+ // 4 = player 1 display
+ // 5 = player 2 display
+ // 6 = player 3 display
+ // 7 = player 4 display
+ // 8 = status display
+ for (i = 0; i < 5; i++)
+ m_digits[i * 10 + m_row] = bitswap<10>(m_cru_out[i+4] ^ 0xff, 7, 7, 6, 6, 5, 4, 3, 2, 1, 0);
+ return m_cru_in_bit;
+}
+
+// send a cru bit to 4094 chain
+void nsm_state::clockout_w(u8 data)
+{
+ m_cru_overflow = BIT(m_cru_out[8], 7);
+ m_cru_out[8] = (m_cru_out[8] << 1) | BIT(m_cru_out[7], 7);
+ m_cru_out[7] = (m_cru_out[7] << 1) | BIT(m_cru_out[6], 7);
+ m_cru_out[6] = (m_cru_out[6] << 1) | BIT(m_cru_out[5], 7);
+ m_cru_out[5] = (m_cru_out[5] << 1) | BIT(m_cru_out[4], 7);
+ m_cru_out[4] = (m_cru_out[4] << 1) | BIT(m_cru_out[3], 7);
+ m_cru_out[3] = (m_cru_out[3] << 1) | BIT(m_cru_out[2], 7);
+ m_cru_out[2] = (m_cru_out[2] << 1) | BIT(m_cru_out[1], 7);
+ m_cru_out[1] = (m_cru_out[1] << 1) | BIT(m_cru_out[0], 7);
+ m_cru_out[0] = (m_cru_out[0] << 1) | data;
+ (void)clockin_r();
+}
+
+// **** CRU INPUTS ****
+// load up 4021 chain with keyboard inputs
+u8 nsm_state::loadin_r()
+{
+ // 0 = playboard inputs
+ m_cru_in[0] = m_io_keyboard[m_row]->read();
+ // 1 = hardware error detectors
+ m_cru_in[1] = m_io_keyboard[8]->read();
+ // 2 = door inputs
+ m_cru_in[2] = m_io_keyboard[9]->read();
+ return m_cru_in_bit;
+}
+
+// get a bit from 4021 chain
+u8 nsm_state::clockin_r()
+{
+ m_cru_in_bit = BIT(m_cru_in[2], 7);
+ m_cru_in[2] = (m_cru_in[2] << 1) | BIT(m_cru_in[1], 7);
+ m_cru_in[1] = (m_cru_in[1] << 1) | BIT(m_cru_in[0], 7);
+ m_cru_in[0] = (m_cru_in[0] << 1) | m_cru_overflow;
+ return m_cru_in_bit;
+}
+
+// **** PROGRAMMER KEYPAD ****
+// All guesswork, no schematic or pictures exist
+u8 nsm_state::np_clock_r(offs_t offset)
+{
+ return BIT(m_np_cru, offset);
+}
+
+void nsm_state::np_sel1_w(u8 data)
+{
+ m_np_sel = 0;
+}
+
+void nsm_state::np_sel2_w(u8 data)
+{
+ m_np_sel = 1;
+}
+
+void nsm_state::np_load_w(u8 data)
+{
+ m_np_cru = m_io_keyboard[10U+m_np_sel]->read();
+}
+
+// Apply tonal changes to the sound
+void nsm_state::ay1a_w(u8 data)
+{
+}
+
+void nsm_state::ay2a_w(u8 data)
+{
+}
+
+void nsm_state::machine_start()
+{
+ genpin_class::machine_start();
+
+ m_digits.resolve();
+ m_io_outputs.resolve();
+
+ save_item(NAME(m_cru_out));
+ save_item(NAME(m_cru_in));
+ save_item(NAME(m_cru_in_bit));
+ save_item(NAME(m_cru_overflow));
+ save_item(NAME(m_row));
+ save_item(NAME(m_np_cru));
+ save_item(NAME(m_np_sel));
}
void nsm_state::machine_reset()
{
+ genpin_class::machine_reset();
+ for (u8 i = 0; i < m_io_outputs.size(); i++)
+ m_io_outputs[i] = 0;
+
// Disable auto wait state generation by raising the READY line on reset
m_maincpu->ready_line(ASSERT_LINE);
m_maincpu->reset_line(ASSERT_LINE);
@@ -130,24 +421,31 @@ void nsm_state::nsm(machine_config &config)
{
// CPU TMS9995, standard variant; no line connection
TMS9995(config, m_maincpu, 11052000);
- m_maincpu->set_addrmap(AS_PROGRAM, &nsm_state::nsm_map);
- m_maincpu->set_addrmap(AS_IO, &nsm_state::nsm_io_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &nsm_state::mem_map);
+ m_maincpu->set_addrmap(AS_IO, &nsm_state::io_map);
+
+ NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
/* Video */
config.set_default_layout(layout_nsm);
/* Sound */
+ genpin_audio(config);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- AY8912(config, "ay1", 11052000/8).add_route(ALL_OUTPUTS, "lspeaker", 0.75);
- AY8912(config, "ay2", 11052000/8).add_route(ALL_OUTPUTS, "rspeaker", 0.75);
+ ay8912_device &ay1(AY8912(config, "ay1", 11052000/8));
+ ay1.add_route(ALL_OUTPUTS, "lspeaker", 0.75);
+ ay1.port_a_write_callback().set(FUNC(nsm_state::ay1a_w));
+ ay8912_device &ay2(AY8912(config, "ay2", 11052000/8));
+ ay2.add_route(ALL_OUTPUTS, "rspeaker", 0.75);
+ ay2.port_a_write_callback().set(FUNC(nsm_state::ay2a_w));
}
/*-------------------------------------------------------------------
/ Cosmic Flash (1985)
/-------------------------------------------------------------------*/
ROM_START(cosflnsm)
- ROM_REGION(0x10000, "maincpu", 0)
+ ROM_REGION(0x8000, "maincpu", ROMREGION_ERASEFF)
ROM_LOAD("ic602.bin", 0x0000, 0x2000, CRC(1ce79cd7) SHA1(d5caf6d4323cc43a9c4379b51630190bf5799202))
ROM_LOAD("ic603.bin", 0x2000, 0x2000, CRC(538de9f8) SHA1(c64942ffa600a2a7a37b986e1a346d351d0b65eb))
ROM_LOAD("ic604.bin", 0x4000, 0x2000, CRC(4b52e5d7) SHA1(1547bb7a06ff0bdf55c635b2f4e57b7d93a191ee))
@@ -157,10 +455,10 @@ ROM_END
/ Hot Fire Birds (1985)
/-------------------------------------------------------------------*/
ROM_START(firebird)
- ROM_REGION(0x10000, "maincpu", 0)
- ROM_LOAD("nsmf02.764", 0x0000, 0x2000, CRC(236b5780) SHA1(19ef6e1fc900e5d94f615a4316f0383ed5ee939c))
- ROM_LOAD("nsmf03.764", 0x2000, 0x2000, CRC(d88c6ef5) SHA1(00edeefaab7e1141741aa132e6f7e56a911573be))
- ROM_LOAD("nsmf04.764", 0x4000, 0x2000, CRC(38a8add4) SHA1(74f781edc31aad07411feacad53c5f6cc73d09f4))
+ ROM_REGION(0x8000, "maincpu", ROMREGION_ERASEFF)
+ ROM_LOAD("nsmf02.ic602", 0x0000, 0x2000, CRC(236b5780) SHA1(19ef6e1fc900e5d94f615a4316f0383ed5ee939c))
+ ROM_LOAD("nsmf03.ic603", 0x2000, 0x2000, CRC(d88c6ef5) SHA1(00edeefaab7e1141741aa132e6f7e56a911573be))
+ ROM_LOAD("nsmf04.ic604", 0x4000, 0x2000, CRC(38a8add4) SHA1(74f781edc31aad07411feacad53c5f6cc73d09f4))
ROM_END
/*-------------------------------------------------------------------
@@ -171,12 +469,12 @@ ROM_END
/ The Games (1985)
/-------------------------------------------------------------------*/
ROM_START(gamesnsm)
- ROM_REGION(0x10000, "maincpu", 0)
- ROM_LOAD("151595-602.bin", 0x0000, 0x2000, CRC(18f3e309) SHA1(f587d40ddf128f4e040e660c054e98cbebad99c7))
- ROM_LOAD("151596-603.bin", 0x2000, 0x2000, CRC(fdf1b48b) SHA1(fd63ef5e49aa4b84b10972e118bd54219d680d36))
- ROM_LOAD("151597-604.bin", 0x4000, 0x2000, CRC(5c8a3547) SHA1(843a56012227a61ff068bc1e14baf090d4a95fe1))
+ ROM_REGION(0x8000, "maincpu", ROMREGION_ERASEFF)
+ ROM_LOAD("151595.ic602", 0x0000, 0x2000, CRC(18f3e309) SHA1(f587d40ddf128f4e040e660c054e98cbebad99c7))
+ ROM_LOAD("151596.ic603", 0x2000, 0x2000, CRC(fdf1b48b) SHA1(fd63ef5e49aa4b84b10972e118bd54219d680d36))
+ ROM_LOAD("151597.ic604", 0x4000, 0x2000, CRC(5c8a3547) SHA1(843a56012227a61ff068bc1e14baf090d4a95fe1))
ROM_END
-GAME(1985, cosflnsm, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "Cosmic Flash (NSM)", MACHINE_NOT_WORKING | MACHINE_MECHANICAL)
-GAME(1985, firebird, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "Hot Fire Birds", MACHINE_NOT_WORKING | MACHINE_MECHANICAL)
-GAME(1985, gamesnsm, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "The Games (NSM)", MACHINE_NOT_WORKING | MACHINE_MECHANICAL)
+GAME(1985, cosflnsm, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "Cosmic Flash (NSM)", MACHINE_IS_SKELETON_MECHANICAL )
+GAME(1985, firebird, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "Hot Fire Birds", MACHINE_IS_SKELETON_MECHANICAL )
+GAME(1985, gamesnsm, 0, nsm, nsm, nsm_state, empty_init, ROT0, "NSM", "The Games (NSM)", MACHINE_IS_SKELETON_MECHANICAL )
diff --git a/src/mame/drivers/techno.cpp b/src/mame/drivers/techno.cpp
index fbceb65c334..61adaaf14cf 100644
--- a/src/mame/drivers/techno.cpp
+++ b/src/mame/drivers/techno.cpp
@@ -47,7 +47,7 @@ public:
, m_maincpu(*this, "maincpu")
, m_audiocpu(*this, "audiocpu")
, m_dac(*this, "dac")
- , m_io_keyboard(*this, "X%u", 0)
+ , m_io_keyboard(*this, "X%u", 0U)
, m_digits(*this, "digit%u", 0U)
, m_io_outputs(*this, "out%u", 0U)
{ }
diff --git a/src/mame/layout/nsm.lay b/src/mame/layout/nsm.lay
index 256318309c0..ff4a6a167dd 100644
--- a/src/mame/layout/nsm.lay
+++ b/src/mame/layout/nsm.lay
@@ -26,132 +26,132 @@ copyright-holders:Robbbert
<!-- Player 1 Score -->
- <element name="digit47" ref="digit">
+ <element name="digit0" ref="digit">
<bounds left="10" top="45" right="44" bottom="84" />
</element>
- <element name="digit46" ref="digit">
+ <element name="digit1" ref="digit">
<bounds left="54" top="45" right="88" bottom="84" />
</element>
- <element name="digit45" ref="digit">
+ <element name="digit2" ref="digit">
<bounds left="98" top="45" right="132" bottom="84" />
</element>
- <element name="digit44" ref="digit">
+ <element name="digit3" ref="digit">
<bounds left="142" top="45" right="176" bottom="84" />
</element>
- <element name="digit43" ref="digit">
+ <element name="digit4" ref="digit">
<bounds left="186" top="45" right="220" bottom="84" />
</element>
- <element name="digit42" ref="digit">
+ <element name="digit5" ref="digit">
<bounds left="230" top="45" right="264" bottom="84" />
</element>
- <element name="digit41" ref="digit">
+ <element name="digit6" ref="digit">
<bounds left="274" top="45" right="308" bottom="84" />
</element>
- <element name="digit40" ref="digit">
+ <element name="digit7" ref="digit">
<bounds left="318" top="45" right="352" bottom="84" />
</element>
<!-- Player 2 Score -->
- <element name="digit37" ref="digit">
+ <element name="digit10" ref="digit">
<bounds left="10" top="105" right="44" bottom="144" />
</element>
- <element name="digit36" ref="digit">
+ <element name="digit11" ref="digit">
<bounds left="54" top="105" right="88" bottom="144" />
</element>
- <element name="digit35" ref="digit">
+ <element name="digit12" ref="digit">
<bounds left="98" top="105" right="132" bottom="144" />
</element>
- <element name="digit34" ref="digit">
+ <element name="digit13" ref="digit">
<bounds left="142" top="105" right="176" bottom="144" />
</element>
- <element name="digit33" ref="digit">
+ <element name="digit14" ref="digit">
<bounds left="186" top="105" right="220" bottom="144" />
</element>
- <element name="digit32" ref="digit">
+ <element name="digit15" ref="digit">
<bounds left="230" top="105" right="264" bottom="144" />
</element>
- <element name="digit31" ref="digit">
+ <element name="digit16" ref="digit">
<bounds left="274" top="105" right="308" bottom="144" />
</element>
- <element name="digit30" ref="digit">
+ <element name="digit17" ref="digit">
<bounds left="318" top="105" right="352" bottom="144" />
</element>
<!-- Player 3 Score -->
- <element name="digit27" ref="digit">
+ <element name="digit20" ref="digit">
<bounds left="10" top="165" right="44" bottom="204" />
</element>
- <element name="digit26" ref="digit">
+ <element name="digit21" ref="digit">
<bounds left="54" top="165" right="88" bottom="204" />
</element>
- <element name="digit25" ref="digit">
+ <element name="digit22" ref="digit">
<bounds left="98" top="165" right="132" bottom="204" />
</element>
- <element name="digit24" ref="digit">
+ <element name="digit23" ref="digit">
<bounds left="142" top="165" right="176" bottom="204" />
</element>
- <element name="digit23" ref="digit">
+ <element name="digit24" ref="digit">
<bounds left="186" top="165" right="220" bottom="204" />
</element>
- <element name="digit22" ref="digit">
+ <element name="digit25" ref="digit">
<bounds left="230" top="165" right="264" bottom="204" />
</element>
- <element name="digit21" ref="digit">
+ <element name="digit26" ref="digit">
<bounds left="274" top="165" right="308" bottom="204" />
</element>
- <element name="digit20" ref="digit">
+ <element name="digit27" ref="digit">
<bounds left="318" top="165" right="352" bottom="204" />
</element>
<!-- Player 4 Score -->
- <element name="digit17" ref="digit">
+ <element name="digit30" ref="digit">
<bounds left="10" top="225" right="44" bottom="264" />
</element>
- <element name="digit16" ref="digit">
+ <element name="digit31" ref="digit">
<bounds left="54" top="225" right="88" bottom="264" />
</element>
- <element name="digit15" ref="digit">
+ <element name="digit32" ref="digit">
<bounds left="98" top="225" right="132" bottom="264" />
</element>
- <element name="digit14" ref="digit">
+ <element name="digit33" ref="digit">
<bounds left="142" top="225" right="176" bottom="264" />
</element>
- <element name="digit13" ref="digit">
+ <element name="digit34" ref="digit">
<bounds left="186" top="225" right="220" bottom="264" />
</element>
- <element name="digit12" ref="digit">
+ <element name="digit35" ref="digit">
<bounds left="230" top="225" right="264" bottom="264" />
</element>
- <element name="digit11" ref="digit">
+ <element name="digit36" ref="digit">
<bounds left="274" top="225" right="308" bottom="264" />
</element>
- <element name="digit10" ref="digit">
+ <element name="digit37" ref="digit">
<bounds left="318" top="225" right="352" bottom="264" />
</element>
<!-- Credits and Balls -->
- <element name="digit7" ref="digit">
+ <element name="digit40" ref="digit">
<bounds left="10" top="345" right="44" bottom="384" />
</element>
- <element name="digit6" ref="digit">
+ <element name="digit41" ref="digit">
<bounds left="54" top="345" right="88" bottom="384" />
</element>
- <element name="digit5" ref="digit">
+ <element name="digit42" ref="digit">
<bounds left="98" top="345" right="132" bottom="384" />
</element>
- <element name="digit4" ref="digit">
+ <element name="digit43" ref="digit">
<bounds left="142" top="345" right="176" bottom="384" />
</element>
- <element name="digit3" ref="digit">
+ <element name="digit44" ref="digit">
<bounds left="186" top="345" right="220" bottom="384" />
</element>
- <element name="digit2" ref="digit">
+ <element name="digit45" ref="digit">
<bounds left="230" top="345" right="264" bottom="384" />
</element>
- <element name="digit1" ref="digit">
+ <element name="digit46" ref="digit">
<bounds left="274" top="345" right="308" bottom="384" />
</element>
- <element name="digit0" ref="digit">
+ <element name="digit47" ref="digit">
<bounds left="318" top="345" right="352" bottom="384" />
</element>