Previous 15994 Revisions Next

r4665 Monday 11th May, 2009 at 08:02:18 UTC by Curt Coder
[UPD1990A] Implemented time set mode and clock advance.
[src/mess/machine]upd1990a.c upd1990a.h

src/mess/machine/upd1990a.c
r4664r4665
1/*********************************************************************
1/**********************************************************************
22
3   upd1990a.c
3   NEC uPD1990AC Serial I/O Calendar & Clock emulation
44
5   NEC uPD1990AC CMOS Digital Integrated Circuit
6   Serial I/O Calendar & Clock
7   CMOS LSI
5   Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
87
98*********************************************************************/
109
r4664r4665
1211
1312   TODO:
1413
15   - set clock mode
1614   - test mode
17   - clock advance (currently it just reads the system time)
18   - divide frequencies from chip clock
1915
2016*/
2117
r4664r4665
9288   return ((val / 10) << 4) | (val % 10);
9389}
9490
91INLINE int bcd_to_integer(UINT8 val)
92{
93   return (((val & 0xf0) >> 4) * 10) + (val & 0x0f);
94}
95
9596/***************************************************************************
9697    IMPLEMENTATION
9798***************************************************************************/
r4664r4665
146147
147148         /* 1 Hz data out pulse */
148149         upd1990a->data_out = 1;
149         timer_adjust_periodic(upd1990a->data_out_timer, attotime_zero, 0, ATTOTIME_IN_HZ(1*2));
150         timer_adjust_periodic(upd1990a->data_out_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/32768)*2));
150151
151152         /* 64 Hz time pulse */
152         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(64*2));
153         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/512)*2));
153154         break;
154155
155156      case UPD1990A_MODE_SHIFT:
156157         if (LOG) logerror("UPD1990A Shift Mode\n");
158         
157159         /* enable time counter */
158160         timer_enable(upd1990a->clock_timer, 1);
159161
r4664r4665
165167         devcb_call_write_line(&upd1990a->out_data_func, upd1990a->data_out);
166168
167169         /* 32 Hz time pulse */
168         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(32*2));
170         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/1024)*2));
169171         break;
170172
171173      case UPD1990A_MODE_TIME_SET:
172174         {
173175         int i;
174176
175         if (LOG) logerror("UPD1990A Time Set Mode not supported!\n");
177         if (LOG) logerror("UPD1990A Time Set Mode\n");
176178         if (LOG) logerror("UPD1990A Shift Register %02x%02x%02x%02x%02x\n", upd1990a->shift_reg[4], upd1990a->shift_reg[3], upd1990a->shift_reg[2], upd1990a->shift_reg[1], upd1990a->shift_reg[0]);
177179
178180         /* disable time counter */
r4664r4665
192194         }
193195
194196         /* 32 Hz time pulse */
195         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(32*2));
197         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/1024)*2));
196198         }
197199         break;
198200
199201      case UPD1990A_MODE_TIME_READ:
200202         {
201         mame_system_time curtime, *systime = &curtime;
202203         int i;
203204         
204205         if (LOG) logerror("UPD1990A Time Read Mode\n");
r4664r4665
206207         /* enable time counter */
207208         timer_enable(upd1990a->clock_timer, 1);
208209
209         /* HACK: load time counter from system time */
210         mame_get_current_datetime(device->machine, &curtime);
211
212         upd1990a->time_counter[0] = convert_to_bcd(systime->local_time.second);
213         upd1990a->time_counter[1] = convert_to_bcd(systime->local_time.minute);
214         upd1990a->time_counter[2] = convert_to_bcd(systime->local_time.hour);
215         upd1990a->time_counter[3] = convert_to_bcd(systime->local_time.mday);
216         upd1990a->time_counter[4] = systime->local_time.weekday;
217         upd1990a->time_counter[4] |= (systime->local_time.month + 1) << 4;
218
219210         /* load time counter data into shift register */
220211         for (i = 0; i < 5; i++)
221212         {
r4664r4665
226217
227218         /* 512 Hz data out pulse */
228219         upd1990a->data_out = 1;
229         timer_adjust_periodic(upd1990a->data_out_timer, attotime_zero, 0, ATTOTIME_IN_HZ(512*2));
220         timer_adjust_periodic(upd1990a->data_out_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/64)*2));
230221
231222         /* 32 Hz time pulse */
232         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(32*2));
223         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/1024)*2));
233224         }
234225         break;
235226
r4664r4665
237228         if (LOG) logerror("UPD1990A TP = 64 Hz Set Mode\n");
238229         
239230         /* 64 Hz time pulse */
240         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(64*2));
231         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/512)*2));
241232         break;
242233
243234      case UPD1990A_MODE_TP_256HZ_SET:
244235         if (LOG) logerror("UPD1990A TP = 256 Hz Set Mode\n");
245236         
246237         /* 256 Hz time pulse */
247         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(256*2));
238         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/128)*2));
248239         break;
249240
250241      case UPD1990A_MODE_TP_2048HZ_SET:
251242         if (LOG) logerror("UPD1990A TP = 2048 Hz Set Mode\n");
252243
253244         /* 2048 Hz time pulse */
254         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ(2048*2));
245         timer_adjust_periodic(upd1990a->tp_timer, attotime_zero, 0, ATTOTIME_IN_HZ((device->clock/16)*2));
255246         break;
256247
257248      case UPD1990A_MODE_TEST:
258249         if (LOG) logerror("UPD1990A Test Mode not supported!\n");
250
251         if (upd1990a->oe)
252         {
253            /* time counter is advanced at 1024 Hz from "Second" counter input */
254         }
255         else
256         {
257            /* each counter is advanced at 1024 Hz in parallel, overflow carry does not affect next counter */
258         }
259
259260         break;
260261      }
261262   }
r4664r4665
294295         {
295296            upd1990a->data_out = BIT(upd1990a->shift_reg[0], 0);
296297
297            logerror("UPD1990A DATA OUT %u\n", upd1990a->data_out);
298            if (LOG) logerror("UPD1990A DATA OUT %u\n", upd1990a->data_out);
299
298300            devcb_call_write_line(&upd1990a->out_data_func, upd1990a->data_out);
299
300301         }
301
302302      }
303303   }
304304
r4664r4665
358358}
359359
360360/*-------------------------------------------------
361    advance_seconds - advance seconds counter
362-------------------------------------------------*/
363
364static void advance_seconds(upd1990a_t *upd1990a)
365{
366   int days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
367
368   int seconds = bcd_to_integer(upd1990a->time_counter[0]);
369   int minutes = bcd_to_integer(upd1990a->time_counter[1]);
370   int hours = bcd_to_integer(upd1990a->time_counter[2]);
371   int days = bcd_to_integer(upd1990a->time_counter[3]);
372   int day_of_week = upd1990a->time_counter[4] & 0x0f;
373   int month = (upd1990a->time_counter[4] & 0xf0) >> 4;
374
375   seconds++;
376
377   if (seconds > 59)
378   {
379      seconds = 0;
380      minutes++;
381   }
382
383   if (minutes > 59)
384   {
385      minutes = 0;
386      hours++;
387   }
388
389   if (hours > 23)
390   {
391      hours = 0;
392      days++;
393      day_of_week++;
394   }
395
396   if (day_of_week > 6)
397   {
398      day_of_week++;
399   }
400
401   if (days > days_per_month[month - 1])
402   {
403      days = 1;
404      month++;
405   }
406
407   if (month > 12)
408   {
409      month = 1;
410   }
411
412   upd1990a->time_counter[0] = convert_to_bcd(seconds);
413   upd1990a->time_counter[1] = convert_to_bcd(minutes);
414   upd1990a->time_counter[2] = convert_to_bcd(hours);
415   upd1990a->time_counter[3] = convert_to_bcd(days);
416   upd1990a->time_counter[4] = (month << 4) | day_of_week;
417}
418
419/*-------------------------------------------------
361420    TIMER_CALLBACK( clock_tick )
362421-------------------------------------------------*/
363422
364423static TIMER_CALLBACK( clock_tick )
365424{
366//   const device_config *device = ptr;
367//   upd1990a_t *upd1990a = get_safe_token(device);
425   const device_config *device = ptr;
426   upd1990a_t *upd1990a = get_safe_token(device);
368427
369   // TODO: advance clock
428   advance_seconds(upd1990a);
370429}
371430
372431/*-------------------------------------------------
r4664r4665
394453   const device_config *device = ptr;
395454   upd1990a_t *upd1990a = get_safe_token(device);
396455
397   logerror("UPD1990A DATA OUT TICK %u\n", upd1990a->data_out);
456   if (LOG) logerror("UPD1990A DATA OUT TICK %u\n", upd1990a->data_out);
398457
399458   devcb_call_write_line(&upd1990a->out_data_func, upd1990a->data_out);
400459
r4664r4665
416475
417476   /* create the timers */
418477   upd1990a->clock_timer = timer_alloc(device->machine, clock_tick, (void *)device);
419   timer_adjust_periodic(upd1990a->clock_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 32768));
478   timer_adjust_periodic(upd1990a->clock_timer, attotime_zero, 0, ATTOTIME_IN_HZ(1));
420479
421480   upd1990a->tp_timer = timer_alloc(device->machine, tp_tick, (void *)device);
422481
r4664r4665
435494    state_save_register_global(device->machine, upd1990a->tp);
436495}
437496
497static DEVICE_RESET( upd1990a )
498{
499   upd1990a_t *upd1990a = get_safe_token(device);
500
501   mame_system_time curtime, *systime = &curtime;
502
503   mame_get_current_datetime(device->machine, &curtime);
504
505   /* HACK: load time counter from system time */
506   upd1990a->time_counter[0] = convert_to_bcd(systime->local_time.second);
507   upd1990a->time_counter[1] = convert_to_bcd(systime->local_time.minute);
508   upd1990a->time_counter[2] = convert_to_bcd(systime->local_time.hour);
509   upd1990a->time_counter[3] = convert_to_bcd(systime->local_time.mday);
510   upd1990a->time_counter[4] = systime->local_time.weekday;
511   upd1990a->time_counter[4] |= (systime->local_time.month + 1) << 4;
512}
513
438514/*-------------------------------------------------
439515    DEVICE_GET_INFO( upd1990a )
440516-------------------------------------------------*/
r4664r4665
451527      /* --- the following bits of info are returned as pointers to data or functions --- */
452528      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(upd1990a);   break;
453529      case DEVINFO_FCT_STOP:                     /* Nothing */                        break;
454      case DEVINFO_FCT_RESET:                     /* Nothing */                        break;
530      case DEVINFO_FCT_RESET:                     info->reset = DEVICE_RESET_NAME(upd1990a);   break;
455531
456532      /* --- the following bits of info are returned as NULL-terminated strings --- */
457533      case DEVINFO_STR_NAME:                     strcpy(info->s, "NEC uPD1990AC");         break;
src/mess/machine/upd1990a.h
r4664r4665
1/***************************************************************************
1/**********************************************************************
22
3   NEC uPD1990AC CMOS Digital Integrated Circuit
4   Serial I/O Calendar & Clock
5   CMOS LSI
3   NEC uPD1990AC Serial I/O Calendar & Clock emulation
64
7***************************************************************************/
5   Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
87
8**********************************************************************
9                     _____   _____
10                C2    1 |*    \_/     | 14  Vdd
11               C1    2 |          | 13  XTAL
12               C0    3 |          | 12  _XTAL
13               STB    4 |  uPD1990AC    | 11  OUT ENBL
14               CS    5 |          | 10  TP
15            DATA IN    6 |          | 9   DATA OUT
16               GND   7 |_____________| 8   CLK
17
18**********************************************************************/
19
920#ifndef __UPD1990A_H__
1021#define __UPD1990A_H__
1122

Previous 15994 Revisions Next


© 1998-2018 The MESS Team