Skip to content

Commit 17d7b7c

Browse files
authored
snk/ngp.cpp: Improved real-time clock behavior - fixes MT05279. (#12855)
1 parent b4587b3 commit 17d7b7c

File tree

1 file changed

+100
-66
lines changed

1 file changed

+100
-66
lines changed

src/mame/snk/ngp.cpp

+100-66
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
55
SNK NeoGeo Pocket driver
66
7+
After setting the initial console settings power cycle the unit at least once,
8+
otherwise the settings will not be saved properly.
9+
10+
711
The NeoGeo Pocket (Color) contains one big chip which contains the following
812
components:
913
- Toshiba TLCS-900/H cpu core with 64KB ROM
@@ -98,6 +102,7 @@ the Neogeo Pocket.
98102

99103

100104
#include "emu.h"
105+
#include "k1ge.h"
101106

102107
#include "bus/generic/slot.h"
103108
#include "bus/generic/carts.h"
@@ -106,7 +111,7 @@ the Neogeo Pocket.
106111
#include "sound/t6w28.h"
107112
#include "sound/dac.h"
108113

109-
#include "k1ge.h"
114+
#include "dirtc.h"
110115
#include "screen.h"
111116
#include "softlist_dev.h"
112117
#include "speaker.h"
@@ -128,13 +133,15 @@ enum flash_state
128133
};
129134

130135

131-
class ngp_state : public driver_device, public device_nvram_interface
136+
class ngp_state : public driver_device, public device_nvram_interface, device_rtc_interface
132137
{
133138
public:
134139
ngp_state(const machine_config &mconfig, device_type type, const char *tag) :
135140
driver_device(mconfig, type, tag),
136141
device_nvram_interface(mconfig, *this),
142+
device_rtc_interface(mconfig, *this),
137143
m_maincpu(*this, "maincpu"),
144+
m_screen(*this, "screen"),
138145
m_z80(*this, "soundcpu"),
139146
m_t6w28(*this, "t6w28"),
140147
m_ldac(*this, "ldac"),
@@ -155,6 +162,7 @@ class ngp_state : public driver_device, public device_nvram_interface
155162
protected:
156163
virtual void machine_start() override ATTR_COLD;
157164
virtual void machine_reset() override ATTR_COLD;
165+
virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override ATTR_COLD;
158166

159167
private:
160168

@@ -173,6 +181,7 @@ class ngp_state : public driver_device, public device_nvram_interface
173181
} m_flash_chip[2];
174182

175183
required_device<tmp95c061_device> m_maincpu;
184+
required_device<screen_device> m_screen;
176185
required_device<cpu_device> m_z80;
177186
required_device<t6w28_device> m_t6w28;
178187
required_device<dac_byte_interface> m_ldac;
@@ -219,34 +228,7 @@ class ngp_state : public driver_device, public device_nvram_interface
219228

220229
TIMER_CALLBACK_MEMBER(ngp_state::ngp_seconds_callback)
221230
{
222-
m_io_reg[0x16] += 1;
223-
if ((m_io_reg[0x16] & 0x0f) == 0x0a)
224-
{
225-
m_io_reg[0x16] += 0x06;
226-
}
227-
228-
if (m_io_reg[0x16] >= 0x60)
229-
{
230-
m_io_reg[0x16] = 0;
231-
m_io_reg[0x15] += 1;
232-
if ((m_io_reg[0x15] & 0x0f) == 0x0a) {
233-
m_io_reg[0x15] += 0x06;
234-
}
235-
236-
if (m_io_reg[0x15] >= 0x60)
237-
{
238-
m_io_reg[0x15] = 0;
239-
m_io_reg[0x14] += 1;
240-
if ((m_io_reg[0x14] & 0x0f) == 0x0a) {
241-
m_io_reg[0x14] += 0x06;
242-
}
243-
244-
if (m_io_reg[0x14] == 0x24)
245-
{
246-
m_io_reg[0x14] = 0;
247-
}
248-
}
249-
}
231+
advance_seconds();
250232
}
251233

252234

@@ -256,12 +238,23 @@ uint8_t ngp_state::ngp_io_r(offs_t offset)
256238

257239
switch (offset)
258240
{
259-
case 0x30: /* Read controls */
260-
data = m_io_controls->read();
261-
break;
241+
case 0x11: // year
242+
return convert_to_bcd(get_clock_register(RTC_YEAR) % 100);
243+
case 0x12: // month
244+
return convert_to_bcd(get_clock_register(RTC_MONTH));
245+
case 0x13: // day
246+
return convert_to_bcd(get_clock_register(RTC_DAY));
247+
case 0x14: // hour
248+
return convert_to_bcd(get_clock_register(RTC_HOUR));
249+
case 0x15: // minute
250+
return convert_to_bcd(get_clock_register(RTC_MINUTE));
251+
case 0x16: // second
252+
return convert_to_bcd(get_clock_register(RTC_SECOND));
253+
case 0x30: // Read controls
254+
return m_io_controls->read();
262255
case 0x31:
263256
data = m_io_power->read() & 0x01;
264-
/* Sub-battery OK */
257+
// Sub-battery OK
265258
data |= 0x02;
266259
break;
267260
}
@@ -273,52 +266,67 @@ void ngp_state::ngp_io_w(offs_t offset, uint8_t data)
273266
{
274267
switch (offset)
275268
{
276-
case 0x20: /* t6w28 "right" */
277-
case 0x21: /* t6w28 "left" */
269+
case 0x11: // year
270+
set_clock_register(RTC_YEAR, bcd_to_integer(data));
271+
break;
272+
case 0x12: // month
273+
set_clock_register(RTC_MONTH, bcd_to_integer(data));
274+
break;
275+
case 0x13: // day
276+
set_clock_register(RTC_DAY, bcd_to_integer(data));
277+
break;
278+
case 0x14: // hour
279+
set_clock_register(RTC_HOUR, bcd_to_integer(data));
280+
break;
281+
case 0x15: // minute
282+
set_clock_register(RTC_MINUTE, bcd_to_integer(data));
283+
break;
284+
case 0x16: // second
285+
set_clock_register(RTC_SECOND, bcd_to_integer(data));
286+
break;
287+
case 0x20: // t6w28 "right"
288+
case 0x21: // t6w28 "left"
278289
if (m_io_reg[0x38] == 0x55 && m_io_reg[0x39] == 0xAA)
279-
{
280290
m_t6w28->write(0, data);
281-
}
282291
break;
283292

284-
case 0x22: /* DAC right */
293+
case 0x22: // DAC right
285294
m_rdac->write(data);
286295
break;
287-
case 0x23: /* DAC left */
296+
case 0x23: // DAC left
288297
m_ldac->write(data);
289298
break;
290299

291-
/* Internal eeprom related? */
292-
case 0x36:
300+
case 0x36: // 50 written when system powers down, 05 written when system starts up
293301
case 0x37:
294302
break;
295-
case 0x38: /* Sound enable/disable. */
303+
case 0x38: // Sound enable/disable.
296304
switch (data)
297305
{
298-
case 0x55: /* Enabled sound */
306+
case 0x55: // Enabled sound
299307
m_t6w28->set_enable(true);
300308
break;
301-
case 0xAA: /* Disable sound */
309+
case 0xAA: // Disable sound
302310
m_t6w28->set_enable(false);
303311
break;
304312
}
305313
break;
306314

307-
case 0x39: /* Z80 enable/disable. */
315+
case 0x39: // Z80 enable/disable.
308316
switch (data)
309317
{
310-
case 0x55: /* Enable Z80 */
318+
case 0x55: // Enable Z80
311319
m_z80->resume(SUSPEND_REASON_HALT);
312320
m_z80->reset();
313321
m_z80->set_input_line(0, CLEAR_LINE);
314322
break;
315-
case 0xAA: /* Disable Z80 */
323+
case 0xAA: // Disable Z80
316324
m_z80->suspend(SUSPEND_REASON_HALT, 1);
317325
break;
318326
}
319327
break;
320328

321-
case 0x3a: /* Trigger Z80 NMI */
329+
case 0x3a: // Trigger Z80 NMI
322330
m_z80->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
323331
break;
324332
}
@@ -605,10 +613,8 @@ void ngp_state::z80_io(address_map &map)
605613

606614
INPUT_CHANGED_MEMBER(ngp_state::power_callback)
607615
{
608-
if (m_io_reg[0x33] & 0x04)
609-
{
610-
m_maincpu->set_input_line(TLCS900_NMI, (m_io_power->read() & 0x01) ? CLEAR_LINE : ASSERT_LINE);
611-
}
616+
if (BIT(m_io_reg[0x33], 2))
617+
m_maincpu->set_input_line(TLCS900_NMI, (BIT(m_io_power->read(), 0) ? CLEAR_LINE : ASSERT_LINE));
612618
}
613619

614620

@@ -643,7 +649,8 @@ void ngp_state::ngp_hblank_pin_w(int state)
643649
void ngp_state::ngp_tlcs900_porta(offs_t offset, uint8_t data)
644650
{
645651
int to3 = BIT(data,3);
646-
if (to3 && ! m_old_to3)
652+
653+
if (to3 && !m_old_to3)
647654
m_z80->set_input_line(0, ASSERT_LINE);
648655

649656
m_old_to3 = to3;
@@ -805,9 +812,20 @@ void ngp_state::nvram_default()
805812

806813
bool ngp_state::nvram_read(util::read_stream &file)
807814
{
808-
auto const [err, actual] = read(file, m_mainram, 0x3000);
809-
if (!err && (actual == 0x3000))
815+
u8 data[0x3000 + 0x20];
816+
817+
auto const [err, actual] = read(file, data, 0x3000 + 0x20);
818+
if (!err && (actual == 0x3000 + 0x20))
810819
{
820+
for (int i = 0; i < 0x3000; i++)
821+
m_mainram[i] = data[i];
822+
for (int i = 0; i < 0x20; i++)
823+
m_io_reg[i] = data[0x3000 + i];
824+
825+
system_time curtime;
826+
machine().current_datetime(curtime);
827+
set_current_time(curtime);
828+
811829
m_nvram_loaded = true;
812830
return true;
813831
}
@@ -817,11 +835,29 @@ bool ngp_state::nvram_read(util::read_stream &file)
817835

818836
bool ngp_state::nvram_write(util::write_stream &file)
819837
{
820-
auto const [err, actual] = write(file, m_mainram, 0x3000);
838+
u8 data[0x3000 + 0x20];
839+
840+
for (int i = 0; i < 0x3000; i++)
841+
data[i] = m_mainram[i];
842+
for (int i = 0; i < 0x20; i++)
843+
data[0x3000 + i] = m_io_reg[i];
844+
845+
auto const [err, actual] = write(file, data, 0x3000 + 0x20);
821846
return !err;
822847
}
823848

824849

850+
void ngp_state::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
851+
{
852+
m_io_reg[0x16] = convert_to_bcd(second);
853+
m_io_reg[0x15] = convert_to_bcd(minute);
854+
m_io_reg[0x14] = convert_to_bcd(hour);
855+
m_io_reg[0x13] = convert_to_bcd(day);
856+
m_io_reg[0x12] = convert_to_bcd(month);
857+
m_io_reg[0x11] = convert_to_bcd(year % 100);
858+
}
859+
860+
825861
void ngp_state::ngp_common(machine_config &config)
826862
{
827863
TMP95C061(config, m_maincpu, 6.144_MHz_XTAL);
@@ -834,9 +870,9 @@ void ngp_state::ngp_common(machine_config &config)
834870
soundcpu.set_addrmap(AS_PROGRAM, &ngp_state::z80_mem);
835871
soundcpu.set_addrmap(AS_IO, &ngp_state::z80_io);
836872

837-
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
838-
screen.set_raw(6.144_MHz_XTAL, 515, 0, 160 /*480*/, 199, 0, 152);
839-
screen.set_screen_update(FUNC(ngp_state::screen_update_ngp));
873+
SCREEN(config, m_screen, SCREEN_TYPE_LCD);
874+
m_screen->set_raw(6.144_MHz_XTAL, 515, 0, 160 /*480*/, 199, 0, 152);
875+
m_screen->set_screen_update(FUNC(ngp_state::screen_update_ngp));
840876

841877
/* sound hardware */
842878
SPEAKER(config, "lspeaker").front_left();
@@ -855,17 +891,16 @@ void ngp_state::ngp(machine_config &config)
855891
{
856892
ngp_common(config);
857893

858-
K1GE(config, m_k1ge, 6.144_MHz_XTAL, "screen");
894+
K1GE(config, m_k1ge, 6.144_MHz_XTAL, m_screen);
859895
m_k1ge->vblank_callback().set(FUNC(ngp_state::ngp_vblank_pin_w));
860896
m_k1ge->hblank_callback().set(FUNC(ngp_state::ngp_hblank_pin_w));
861897

862-
subdevice<screen_device>("screen")->set_palette("k1ge:palette");
898+
m_screen->set_palette("k1ge:palette");
863899

864900
generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "ngp_cart", "bin,ngp,npc,ngc"));
865901
cartslot.set_device_load(FUNC(ngp_state::load_ngp_cart));
866902
cartslot.set_device_unload(FUNC(ngp_state::unload_ngp_cart));
867903

868-
/* software lists */
869904
SOFTWARE_LIST(config, "cart_list").set_original("ngp");
870905
SOFTWARE_LIST(config, "ngpc_list").set_compatible("ngpc");
871906
}
@@ -874,17 +909,16 @@ void ngp_state::ngp(machine_config &config)
874909
void ngp_state::ngpc(machine_config &config)
875910
{
876911
ngp_common(config);
877-
K2GE(config, m_k1ge, 6.144_MHz_XTAL, "screen");
912+
K2GE(config, m_k1ge, 6.144_MHz_XTAL, m_screen);
878913
m_k1ge->vblank_callback().set(FUNC(ngp_state::ngp_vblank_pin_w));
879914
m_k1ge->hblank_callback().set(FUNC(ngp_state::ngp_hblank_pin_w));
880915

881-
subdevice<screen_device>("screen")->set_palette("k1ge:palette");
916+
m_screen->set_palette("k1ge:palette");
882917

883918
generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "ngp_cart", "bin,ngp,npc,ngc"));
884919
cartslot.set_device_load(FUNC(ngp_state::load_ngp_cart));
885920
cartslot.set_device_unload(FUNC(ngp_state::unload_ngp_cart));
886921

887-
/* software lists */
888922
SOFTWARE_LIST(config, "cart_list").set_original("ngpc");
889923
SOFTWARE_LIST(config, "ngp_list").set_compatible("ngp");
890924
}

0 commit comments

Comments
 (0)