diff --git a/src/mame/snk/ngp.cpp b/src/mame/snk/ngp.cpp index d6960b7e5782d..f43ca76b272c3 100644 --- a/src/mame/snk/ngp.cpp +++ b/src/mame/snk/ngp.cpp @@ -4,6 +4,10 @@ SNK NeoGeo Pocket driver +After setting the initial console settings power cycle the unit at least once, +otherwise the settings will not be saved properly. + + The NeoGeo Pocket (Color) contains one big chip which contains the following components: - Toshiba TLCS-900/H cpu core with 64KB ROM @@ -98,6 +102,7 @@ the Neogeo Pocket. #include "emu.h" +#include "k1ge.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" @@ -106,7 +111,7 @@ the Neogeo Pocket. #include "sound/t6w28.h" #include "sound/dac.h" -#include "k1ge.h" +#include "dirtc.h" #include "screen.h" #include "softlist_dev.h" #include "speaker.h" @@ -128,13 +133,15 @@ enum flash_state }; -class ngp_state : public driver_device, public device_nvram_interface +class ngp_state : public driver_device, public device_nvram_interface, device_rtc_interface { public: ngp_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), device_nvram_interface(mconfig, *this), + device_rtc_interface(mconfig, *this), m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), m_z80(*this, "soundcpu"), m_t6w28(*this, "t6w28"), m_ldac(*this, "ldac"), @@ -155,6 +162,7 @@ class ngp_state : public driver_device, public device_nvram_interface protected: virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override ATTR_COLD; private: @@ -173,6 +181,7 @@ class ngp_state : public driver_device, public device_nvram_interface } m_flash_chip[2]; required_device m_maincpu; + required_device m_screen; required_device m_z80; required_device m_t6w28; required_device m_ldac; @@ -219,34 +228,7 @@ class ngp_state : public driver_device, public device_nvram_interface TIMER_CALLBACK_MEMBER(ngp_state::ngp_seconds_callback) { - m_io_reg[0x16] += 1; - if ((m_io_reg[0x16] & 0x0f) == 0x0a) - { - m_io_reg[0x16] += 0x06; - } - - if (m_io_reg[0x16] >= 0x60) - { - m_io_reg[0x16] = 0; - m_io_reg[0x15] += 1; - if ((m_io_reg[0x15] & 0x0f) == 0x0a) { - m_io_reg[0x15] += 0x06; - } - - if (m_io_reg[0x15] >= 0x60) - { - m_io_reg[0x15] = 0; - m_io_reg[0x14] += 1; - if ((m_io_reg[0x14] & 0x0f) == 0x0a) { - m_io_reg[0x14] += 0x06; - } - - if (m_io_reg[0x14] == 0x24) - { - m_io_reg[0x14] = 0; - } - } - } + advance_seconds(); } @@ -256,12 +238,23 @@ uint8_t ngp_state::ngp_io_r(offs_t offset) switch (offset) { - case 0x30: /* Read controls */ - data = m_io_controls->read(); - break; + case 0x11: // year + return convert_to_bcd(get_clock_register(RTC_YEAR) % 100); + case 0x12: // month + return convert_to_bcd(get_clock_register(RTC_MONTH)); + case 0x13: // day + return convert_to_bcd(get_clock_register(RTC_DAY)); + case 0x14: // hour + return convert_to_bcd(get_clock_register(RTC_HOUR)); + case 0x15: // minute + return convert_to_bcd(get_clock_register(RTC_MINUTE)); + case 0x16: // second + return convert_to_bcd(get_clock_register(RTC_SECOND)); + case 0x30: // Read controls + return m_io_controls->read(); case 0x31: data = m_io_power->read() & 0x01; - /* Sub-battery OK */ + // Sub-battery OK data |= 0x02; break; } @@ -273,52 +266,67 @@ void ngp_state::ngp_io_w(offs_t offset, uint8_t data) { switch (offset) { - case 0x20: /* t6w28 "right" */ - case 0x21: /* t6w28 "left" */ + case 0x11: // year + set_clock_register(RTC_YEAR, bcd_to_integer(data)); + break; + case 0x12: // month + set_clock_register(RTC_MONTH, bcd_to_integer(data)); + break; + case 0x13: // day + set_clock_register(RTC_DAY, bcd_to_integer(data)); + break; + case 0x14: // hour + set_clock_register(RTC_HOUR, bcd_to_integer(data)); + break; + case 0x15: // minute + set_clock_register(RTC_MINUTE, bcd_to_integer(data)); + break; + case 0x16: // second + set_clock_register(RTC_SECOND, bcd_to_integer(data)); + break; + case 0x20: // t6w28 "right" + case 0x21: // t6w28 "left" if (m_io_reg[0x38] == 0x55 && m_io_reg[0x39] == 0xAA) - { m_t6w28->write(0, data); - } break; - case 0x22: /* DAC right */ + case 0x22: // DAC right m_rdac->write(data); break; - case 0x23: /* DAC left */ + case 0x23: // DAC left m_ldac->write(data); break; - /* Internal eeprom related? */ - case 0x36: + case 0x36: // 50 written when system powers down, 05 written when system starts up case 0x37: break; - case 0x38: /* Sound enable/disable. */ + case 0x38: // Sound enable/disable. switch (data) { - case 0x55: /* Enabled sound */ + case 0x55: // Enabled sound m_t6w28->set_enable(true); break; - case 0xAA: /* Disable sound */ + case 0xAA: // Disable sound m_t6w28->set_enable(false); break; } break; - case 0x39: /* Z80 enable/disable. */ + case 0x39: // Z80 enable/disable. switch (data) { - case 0x55: /* Enable Z80 */ + case 0x55: // Enable Z80 m_z80->resume(SUSPEND_REASON_HALT); m_z80->reset(); m_z80->set_input_line(0, CLEAR_LINE); break; - case 0xAA: /* Disable Z80 */ + case 0xAA: // Disable Z80 m_z80->suspend(SUSPEND_REASON_HALT, 1); break; } break; - case 0x3a: /* Trigger Z80 NMI */ + case 0x3a: // Trigger Z80 NMI m_z80->pulse_input_line(INPUT_LINE_NMI, attotime::zero); break; } @@ -605,10 +613,8 @@ void ngp_state::z80_io(address_map &map) INPUT_CHANGED_MEMBER(ngp_state::power_callback) { - if (m_io_reg[0x33] & 0x04) - { - m_maincpu->set_input_line(TLCS900_NMI, (m_io_power->read() & 0x01) ? CLEAR_LINE : ASSERT_LINE); - } + if (BIT(m_io_reg[0x33], 2)) + m_maincpu->set_input_line(TLCS900_NMI, (BIT(m_io_power->read(), 0) ? CLEAR_LINE : ASSERT_LINE)); } @@ -643,7 +649,8 @@ void ngp_state::ngp_hblank_pin_w(int state) void ngp_state::ngp_tlcs900_porta(offs_t offset, uint8_t data) { int to3 = BIT(data,3); - if (to3 && ! m_old_to3) + + if (to3 && !m_old_to3) m_z80->set_input_line(0, ASSERT_LINE); m_old_to3 = to3; @@ -805,9 +812,20 @@ void ngp_state::nvram_default() bool ngp_state::nvram_read(util::read_stream &file) { - auto const [err, actual] = read(file, m_mainram, 0x3000); - if (!err && (actual == 0x3000)) + u8 data[0x3000 + 0x20]; + + auto const [err, actual] = read(file, data, 0x3000 + 0x20); + if (!err && (actual == 0x3000 + 0x20)) { + for (int i = 0; i < 0x3000; i++) + m_mainram[i] = data[i]; + for (int i = 0; i < 0x20; i++) + m_io_reg[i] = data[0x3000 + i]; + + system_time curtime; + machine().current_datetime(curtime); + set_current_time(curtime); + m_nvram_loaded = true; return true; } @@ -817,11 +835,29 @@ bool ngp_state::nvram_read(util::read_stream &file) bool ngp_state::nvram_write(util::write_stream &file) { - auto const [err, actual] = write(file, m_mainram, 0x3000); + u8 data[0x3000 + 0x20]; + + for (int i = 0; i < 0x3000; i++) + data[i] = m_mainram[i]; + for (int i = 0; i < 0x20; i++) + data[0x3000 + i] = m_io_reg[i]; + + auto const [err, actual] = write(file, data, 0x3000 + 0x20); return !err; } +void ngp_state::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_io_reg[0x16] = convert_to_bcd(second); + m_io_reg[0x15] = convert_to_bcd(minute); + m_io_reg[0x14] = convert_to_bcd(hour); + m_io_reg[0x13] = convert_to_bcd(day); + m_io_reg[0x12] = convert_to_bcd(month); + m_io_reg[0x11] = convert_to_bcd(year % 100); +} + + void ngp_state::ngp_common(machine_config &config) { TMP95C061(config, m_maincpu, 6.144_MHz_XTAL); @@ -834,9 +870,9 @@ void ngp_state::ngp_common(machine_config &config) soundcpu.set_addrmap(AS_PROGRAM, &ngp_state::z80_mem); soundcpu.set_addrmap(AS_IO, &ngp_state::z80_io); - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); - screen.set_raw(6.144_MHz_XTAL, 515, 0, 160 /*480*/, 199, 0, 152); - screen.set_screen_update(FUNC(ngp_state::screen_update_ngp)); + SCREEN(config, m_screen, SCREEN_TYPE_LCD); + m_screen->set_raw(6.144_MHz_XTAL, 515, 0, 160 /*480*/, 199, 0, 152); + m_screen->set_screen_update(FUNC(ngp_state::screen_update_ngp)); /* sound hardware */ SPEAKER(config, "lspeaker").front_left(); @@ -855,17 +891,16 @@ void ngp_state::ngp(machine_config &config) { ngp_common(config); - K1GE(config, m_k1ge, 6.144_MHz_XTAL, "screen"); + K1GE(config, m_k1ge, 6.144_MHz_XTAL, m_screen); m_k1ge->vblank_callback().set(FUNC(ngp_state::ngp_vblank_pin_w)); m_k1ge->hblank_callback().set(FUNC(ngp_state::ngp_hblank_pin_w)); - subdevice("screen")->set_palette("k1ge:palette"); + m_screen->set_palette("k1ge:palette"); generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "ngp_cart", "bin,ngp,npc,ngc")); cartslot.set_device_load(FUNC(ngp_state::load_ngp_cart)); cartslot.set_device_unload(FUNC(ngp_state::unload_ngp_cart)); - /* software lists */ SOFTWARE_LIST(config, "cart_list").set_original("ngp"); SOFTWARE_LIST(config, "ngpc_list").set_compatible("ngpc"); } @@ -874,17 +909,16 @@ void ngp_state::ngp(machine_config &config) void ngp_state::ngpc(machine_config &config) { ngp_common(config); - K2GE(config, m_k1ge, 6.144_MHz_XTAL, "screen"); + K2GE(config, m_k1ge, 6.144_MHz_XTAL, m_screen); m_k1ge->vblank_callback().set(FUNC(ngp_state::ngp_vblank_pin_w)); m_k1ge->hblank_callback().set(FUNC(ngp_state::ngp_hblank_pin_w)); - subdevice("screen")->set_palette("k1ge:palette"); + m_screen->set_palette("k1ge:palette"); generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "ngp_cart", "bin,ngp,npc,ngc")); cartslot.set_device_load(FUNC(ngp_state::load_ngp_cart)); cartslot.set_device_unload(FUNC(ngp_state::unload_ngp_cart)); - /* software lists */ SOFTWARE_LIST(config, "cart_list").set_original("ngpc"); SOFTWARE_LIST(config, "ngp_list").set_compatible("ngp"); }