Previous 15994 Revisions Next

r11202 Saturday 16th April, 2011 at 15:30:11 UTC by Curt Coder
Refactored the RP5C01 into a C++ device and moved to emu folder. (no whatsnew)
[src/emu]emu.mak
[src/emu/machine]rp5c01.c* rp5c01.h*
[src/mess]mess.mak
[src/mess/drivers]kyocera.c
[src/mess/includes]kyocera.h
[src/mess/machine]rp5c01a.c rp5c01a.h

src/emu/emu.mak
r11201r11202
204204   $(EMUMACHINE)/pit8253.o      \
205205   $(EMUMACHINE)/ram.o         \
206206   $(EMUMACHINE)/roc10937.o   \
207   $(EMUMACHINE)/rp5c01.o      \
207208   $(EMUMACHINE)/rp5h01.o      \
208209   $(EMUMACHINE)/rtc65271.o   \
209210   $(EMUMACHINE)/s3c2400.o      \
src/emu/machine/rp5c01.c
r0r11202
1/**********************************************************************
2
3    Ricoh RP5C01(A) Real Time Clock With Internal RAM emulation
4
5    Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
7
8*********************************************************************/
9
10/*
11
12    TODO:
13
14    - 12 hour clock
15   - test register
16    - timer reset
17
18*/
19
20#include "rp5c01.h"
21
22
23
24//**************************************************************************
25//  MACROS / CONSTANTS
26//**************************************************************************
27
28#define LOG 0
29
30
31#define RAM_SIZE 13
32
33
34// registers
35enum
36{
37   REGISTER_1_SECOND = 0,
38   REGISTER_10_SECOND,
39   REGISTER_1_MINUTE,
40   REGISTER_10_MINUTE,
41   REGISTER_1_HOUR,
42   REGISTER_10_HOUR,
43   REGISTER_DAY_OF_THE_WEEK,
44   REGISTER_1_DAY,
45   REGISTER_10_DAY,
46   REGISTER_1_MONTH,
47   REGISTER_10_MONTH, REGISTER_12_24_SELECT = REGISTER_10_MONTH,
48   REGISTER_1_YEAR, REGISTER_LEAP_YEAR = REGISTER_1_YEAR,
49   REGISTER_10_YEAR,
50   REGISTER_MODE,
51   REGISTER_TEST,
52   REGISTER_RESET
53};
54
55
56// register write mask
57static const int REGISTER_WRITE_MASK[2][16] =
58{
59   { 0xf, 0x7, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0xf, 0x1, 0xf, 0xf, 0xf, 0xf, 0xf },
60   { 0x0, 0x0, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0x0, 0x1, 0x3, 0x0, 0xf, 0xf, 0xf }
61};
62
63
64// days per month
65static const int DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
66
67
68// modes
69enum
70{
71   MODE00 = 0,
72   MODE01,
73   BLOCK10,
74   BLOCK11
75};
76
77
78// mode register
79#define MODE_TIMER_EN      0x08
80#define MODE_ALARM_EN      0x04
81#define MODE_MASK         0x03
82
83
84// test register
85#define TEST_3            0x08
86#define TEST_2            0x04
87#define TEST_1            0x02
88#define TEST_0            0x01
89
90
91// reset register
92#define RESET_ALARM         0x08
93#define RESET_TIMER         0x04
94#define RESET_16_HZ         0x02
95#define RESET_1_HZ         0x01
96
97
98
99//**************************************************************************
100//  GLOBAL VARIABLES
101//**************************************************************************
102
103// devices
104const device_type RP5C01 = rp5c01_device_config::static_alloc_device_config;
105
106
107
108//**************************************************************************
109//  DEVICE CONFIGURATION
110//**************************************************************************
111
112//-------------------------------------------------
113//  rp5c01_device_config - constructor
114//-------------------------------------------------
115
116rp5c01_device_config::rp5c01_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
117   : device_config(mconfig, static_alloc_device_config, "RP5C01", tag, owner, clock),
118     device_config_nvram_interface(mconfig, *this)
119{
120}
121
122
123//-------------------------------------------------
124//  static_alloc_device_config - allocate a new
125//  configuration object
126//-------------------------------------------------
127
128device_config *rp5c01_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
129{
130   return global_alloc(rp5c01_device_config(mconfig, tag, owner, clock));
131}
132
133
134//-------------------------------------------------
135//  alloc_device - allocate a new device object
136//-------------------------------------------------
137
138device_t *rp5c01_device_config::alloc_device(running_machine &machine) const
139{
140   return auto_alloc(machine, rp5c01_device(machine, *this));
141}
142
143
144//-------------------------------------------------
145//  device_config_complete - perform any
146//  operations now that the configuration is
147//  complete
148//-------------------------------------------------
149
150void rp5c01_device_config::device_config_complete()
151{
152   // inherit a copy of the static data
153   const rp5c01_interface *intf = reinterpret_cast<const rp5c01_interface *>(static_config());
154   if (intf != NULL)
155      *static_cast<rp5c01_interface *>(this) = *intf;
156
157   // or initialize to defaults if none provided
158   else
159   {
160      memset(&m_out_alarm_func, 0, sizeof(m_out_alarm_func));
161   }
162}
163
164
165
166//**************************************************************************
167//  INLINE HELPERS
168//**************************************************************************
169
170//-------------------------------------------------
171//  read_counter -
172//-------------------------------------------------
173
174inline int rp5c01_device::read_counter(int counter)
175{
176   return (m_reg[MODE00][counter + 1] * 10) + m_reg[MODE00][counter];
177}
178
179
180//-------------------------------------------------
181//  write_counter -
182//-------------------------------------------------
183
184inline void rp5c01_device::write_counter(int counter, int value)
185{
186   m_reg[MODE00][counter] = value % 10;
187   m_reg[MODE00][counter + 1] = value / 10;
188}
189
190
191//-------------------------------------------------
192//  advance_seconds -
193//-------------------------------------------------
194
195inline void rp5c01_device::advance_seconds()
196{
197   int seconds = read_counter(REGISTER_1_SECOND);
198
199   seconds++;
200
201   if (seconds > 59)
202   {
203      seconds = 0;
204
205      advance_minutes();
206   }
207
208   write_counter(REGISTER_1_SECOND, seconds);
209   
210   if (!(m_mode & RESET_1_HZ))
211   {
212      // pulse 1Hz alarm signal
213      trigger_alarm();
214   }
215}
216
217
218//-------------------------------------------------
219//  advance_minutes -
220//-------------------------------------------------
221
222inline void rp5c01_device::advance_minutes()
223{
224   int minutes = read_counter(REGISTER_1_MINUTE);
225   int hours = read_counter(REGISTER_1_HOUR);
226   int days = read_counter(REGISTER_1_DAY);
227   int month = read_counter(REGISTER_1_MONTH);
228   int year = read_counter(REGISTER_1_YEAR);
229   int day_of_week = m_reg[MODE00][REGISTER_DAY_OF_THE_WEEK];
230
231   minutes++;
232
233   if (minutes > 59)
234   {
235      minutes = 0;
236      hours++;
237   }
238
239   if (hours > 23)
240   {
241      hours = 0;
242      days++;
243      day_of_week++;
244   }
245
246   if (day_of_week > 6)
247   {
248      day_of_week++;
249   }
250
251   if (days > DAYS_PER_MONTH[month - 1])
252   {
253      days = 1;
254      month++;
255   }
256
257   if (month > 12)
258   {
259      month = 1;
260      year++;
261      m_reg[MODE01][REGISTER_LEAP_YEAR]++;
262      m_reg[MODE01][REGISTER_LEAP_YEAR] &= 0x03;
263   }
264
265   if (year > 99)
266   {
267      year = 0;
268   }
269
270   write_counter(REGISTER_1_MINUTE, minutes);
271   write_counter(REGISTER_1_HOUR, hours);
272   write_counter(REGISTER_1_DAY, days);
273   write_counter(REGISTER_1_MONTH, month);
274   write_counter(REGISTER_1_YEAR, year);
275   m_reg[MODE00][REGISTER_DAY_OF_THE_WEEK] = day_of_week;
276
277   check_alarm();
278}
279
280
281//-------------------------------------------------
282//  check_alarm -
283//-------------------------------------------------
284
285inline void rp5c01_device::check_alarm()
286{
287   if (m_mode & MODE_ALARM_EN)
288   {
289      for (int i = REGISTER_1_MINUTE; i < REGISTER_1_MONTH; i++)
290      {
291         if (m_reg[MODE01][i] != m_reg[MODE00][i]) return;
292      }
293
294      trigger_alarm();
295   }
296}
297
298
299//-------------------------------------------------
300//  trigger_alarm -
301//-------------------------------------------------
302
303inline void rp5c01_device::trigger_alarm()
304{
305   devcb_call_write_line(&m_out_alarm_func, 0);
306   devcb_call_write_line(&m_out_alarm_func, 1);
307}
308
309
310
311//**************************************************************************
312//  LIVE DEVICE
313//**************************************************************************
314
315//-------------------------------------------------
316//  rp5c01_device - constructor
317//-------------------------------------------------
318
319rp5c01_device::rp5c01_device(running_machine &_machine, const rp5c01_device_config &config)
320    : device_t(_machine, config),
321     device_nvram_interface(_machine, config, *this),
322      m_config(config)
323{
324}
325
326
327//-------------------------------------------------
328//  device_start - device-specific startup
329//-------------------------------------------------
330
331void rp5c01_device::device_start()
332{
333   // resolve callbacks
334   devcb_resolve_write_line(&m_out_alarm_func, &m_config.m_out_alarm_func, this);
335
336   // allocate timers
337   m_clock_timer = timer_alloc(TIMER_CLOCK);
338   m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
339   
340   m_alarm_timer = timer_alloc(TIMER_ALARM);
341   m_alarm_timer->adjust(attotime::from_hz(clock() / 2048), 0, attotime::from_hz(clock() / 2048));
342
343   // state saving
344   save_item(NAME(m_reg[MODE00]));
345   save_item(NAME(m_reg[MODE01]));
346   save_item(NAME(m_mode));
347   save_item(NAME(m_reset));
348}
349
350
351//-------------------------------------------------
352//  device_timer - handler timer events
353//-------------------------------------------------
354
355void rp5c01_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
356{
357   switch (id)
358   {
359   case TIMER_CLOCK:
360      advance_seconds();
361      break;
362
363   case TIMER_ALARM:
364      if (!(m_reset & RESET_16_HZ))
365      {
366         trigger_alarm();
367      }
368      break;
369   }
370}
371
372
373//-------------------------------------------------
374//  nvram_default - called to initialize NVRAM to
375//  its default state
376//-------------------------------------------------
377
378void rp5c01_device::nvram_default()
379{
380}
381
382
383//-------------------------------------------------
384//  nvram_read - called to read NVRAM from the
385//  .nv file
386//-------------------------------------------------
387
388void rp5c01_device::nvram_read(emu_file &file)
389{
390   file.read(m_ram, RAM_SIZE);
391}
392
393
394//-------------------------------------------------
395//  nvram_write - called to write NVRAM to the
396//  .nv file
397//-------------------------------------------------
398
399void rp5c01_device::nvram_write(emu_file &file)
400{
401   file.write(m_ram, RAM_SIZE);
402}
403
404
405//-------------------------------------------------
406//  adj_w -
407//-------------------------------------------------
408
409WRITE_LINE_MEMBER( rp5c01_device::adj_w )
410{
411   if (state)
412   {
413      int seconds = read_counter(REGISTER_1_SECOND);
414
415      if (seconds < 30)
416      {
417         write_counter(REGISTER_1_SECOND, 0);
418      }
419      else
420      {
421         write_counter(REGISTER_1_SECOND, 0);
422         advance_minutes();
423      }
424   }
425}
426
427
428//-------------------------------------------------
429//  read -
430//-------------------------------------------------
431
432READ8_MEMBER( rp5c01_device::read )
433{
434   UINT8 data = 0;
435
436   switch (offset & 0x0f)
437   {
438   case REGISTER_MODE:
439      data = m_mode;
440      break;
441
442   case REGISTER_TEST:
443   case REGISTER_RESET:
444      // write only
445      break;
446
447   default:
448      data = m_reg[m_mode & MODE_MASK][offset];
449      break;
450   }
451
452   return data;
453}
454
455
456//-------------------------------------------------
457//  write -
458//-------------------------------------------------
459
460WRITE8_MEMBER( rp5c01_device::write )
461{
462   int mode = m_mode & MODE_MASK;
463
464   switch (offset & 0x0f)
465   {
466   case REGISTER_MODE:
467      m_mode = data;
468
469      m_clock_timer->enable(data & MODE_TIMER_EN);
470
471      if (LOG)
472      {
473         logerror("RP5C01 '%s' Mode %u\n", tag(), data & MODE_MASK);
474         logerror("RP5C01 '%s' Timer %s\n", tag(), (data & MODE_TIMER_EN) ? "enabled" : "disabled");
475         logerror("RP5C01 '%s' Alarm %s\n", tag(), (data & MODE_ALARM_EN) ? "enabled" : "disabled");
476      }
477      break;
478
479   case REGISTER_TEST:
480      if (LOG) logerror("RP5C01 '%s' Test %u not supported!\n", tag(), data);
481      break;
482
483   case REGISTER_RESET:
484      m_reset = data;
485
486      if (data & RESET_ALARM)
487      {
488         int i;
489
490         // reset alarm registers
491         for (i = REGISTER_1_MINUTE; i < REGISTER_1_MONTH; i++)
492         {
493            m_reg[MODE01][i] = 0;
494         }
495      }
496
497      if (LOG)
498      {
499         if (data & RESET_ALARM) logerror("RP5C01 '%s' Alarm Reset\n", tag());
500         if (data & RESET_TIMER) logerror("RP5C01 '%s' Timer Reset not supported!\n", tag());
501         logerror("RP5C01 '%s' 16Hz Signal %s\n", tag(), (data & RESET_16_HZ) ? "disabled" : "enabled");
502         logerror("RP5C01 '%s' 1Hz Signal %s\n", tag(), (data & RESET_1_HZ) ? "disabled" : "enabled");
503      }
504      break;
505
506   default:
507      switch (mode)
508      {
509      case MODE00:
510      case MODE01:
511         m_reg[mode][offset & 0x0f] = data & REGISTER_WRITE_MASK[mode][offset & 0x0f];
512         break;
513
514      case BLOCK10:
515         m_ram[offset & 0x0f] = (m_ram[offset & 0x0f] & 0xf0) | (data & 0x0f);
516         break;
517
518      case BLOCK11:
519         m_ram[offset & 0x0f] = (data << 4) | (m_ram[offset & 0x0f] & 0x0f);
520         break;
521      }
522
523      if (LOG) logerror("RP5C01 '%s' Register %u Write %02x\n", tag(), offset & 0x0f, data);
524      break;
525   }
526}
src/emu/machine/rp5c01.h
r0r11202
1/**********************************************************************
2
3    Ricoh RP5C01(A) Real Time Clock With Internal RAM emulation
4
5    Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
7
8**********************************************************************
9                            _____   _____
10                   _CS   1 |*    \_/     | 18  Vcc
11                    CS   2 |             | 17  OSCOUT
12                   ADJ   3 |             | 16  OSCIN
13                    A0   4 |   RP5C01    | 15  _ALARM
14                    A1   5 |   RP5C01   | 14  D3
15                    A2   6 |   RF5C01A   | 13  D2
16                    A3   7 |             | 12  D1
17                   _RD   8 |             | 11  D0
18                   GND   9 |_____________| 10  _WR
19
20**********************************************************************/
21
22#pragma once
23
24#ifndef __RP5C01__
25#define __RP5C01__
26
27#include "emu.h"
28
29
30
31//**************************************************************************
32//  INTERFACE CONFIGURATION MACROS
33//**************************************************************************
34
35#define MCFG_RP5C01_ADD(_tag, _clock, _config) \
36   MCFG_DEVICE_ADD((_tag), RP5C01, _clock)   \
37   MCFG_DEVICE_CONFIG(_config)
38
39
40#define RP5C01_INTERFACE(name) \
41   const rp5c01_interface (name) =
42
43
44
45//**************************************************************************
46//  TYPE DEFINITIONS
47//**************************************************************************
48
49// ======================> rp5c01_interface
50
51struct rp5c01_interface
52{
53   devcb_write_line      m_out_alarm_func;
54};
55
56
57
58// ======================> rp5c01_device_config
59
60class rp5c01_device_config :   public device_config,
61                        public device_config_nvram_interface,
62                               public rp5c01_interface
63{
64    friend class rp5c01_device;
65
66    // construction/destruction
67    rp5c01_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
68
69public:
70    // allocators
71    static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
72    virtual device_t *alloc_device(running_machine &machine) const;
73
74protected:
75   // device_config overrides
76   virtual void device_config_complete();
77};
78
79
80
81// ======================> rp5c01_device
82
83class rp5c01_device :   public device_t,
84                  public device_nvram_interface
85{
86    friend class rp5c01_device_config;
87
88    // construction/destruction
89    rp5c01_device(running_machine &_machine, const rp5c01_device_config &_config);
90
91public:
92   DECLARE_READ8_MEMBER( read );
93   DECLARE_WRITE8_MEMBER( write );
94   DECLARE_WRITE_LINE_MEMBER( adj_w );
95
96protected:
97    // device-level overrides
98    virtual void device_start();
99   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
100
101   // device_nvram_interface overrides
102   virtual void nvram_default();
103   virtual void nvram_read(emu_file &file);
104   virtual void nvram_write(emu_file &file);
105
106private:
107   inline int read_counter(int counter);
108   inline void write_counter(int counter, int value);
109   inline void advance_seconds();
110   inline void advance_minutes();
111   inline void trigger_alarm();
112   inline void check_alarm();
113
114   static const device_timer_id TIMER_CLOCK = 0;
115   static const device_timer_id TIMER_ALARM = 1;
116
117   devcb_resolved_write_line   m_out_alarm_func;
118
119   UINT8 m_reg[2][13];         // clock registers
120   UINT8 m_ram[13];         // RAM
121
122   UINT8 m_mode;            // mode register
123   UINT8 m_reset;            // reset register
124
125   // timers
126   emu_timer *m_clock_timer;
127   emu_timer *m_alarm_timer;
128
129   const rp5c01_device_config &m_config;
130};
131
132
133// device type definition
134extern const device_type RP5C01;
135
136
137
138#endif
src/mess/machine/rp5c01a.c
r11201r11202
1/**********************************************************************
2
3    Ricoh RP5C01A Real Time Clock With Internal RAM emulation
4
5    Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
7
8*********************************************************************/
9
10/*
11
12    TODO:
13
14    - divide frequencies from device clock
15    - mask out unused bits in register writes
16    - clock adjust
17    - 12 hour clock
18    - leap year counter
19    - timer reset
20
21*/
22
23#include "emu.h"
24#include "rp5c01a.h"
25
26/***************************************************************************
27    PARAMETERS
28***************************************************************************/
29
30#define LOG 0
31
32enum
33{
34   RP5C01A_REGISTER_1_SECOND = 0,
35   RP5C01A_REGISTER_10_SECOND,
36   RP5C01A_REGISTER_1_MINUTE,
37   RP5C01A_REGISTER_10_MINUTE,
38   RP5C01A_REGISTER_1_HOUR,
39   RP5C01A_REGISTER_10_HOUR,
40   RP5C01A_REGISTER_DAY_OF_THE_WEEK,
41   RP5C01A_REGISTER_1_DAY,
42   RP5C01A_REGISTER_10_DAY,
43   RP5C01A_REGISTER_1_MONTH,
44   RP5C01A_REGISTER_10_MONTH, RP5C01A_REGISTER_12_24_SELECT = RP5C01A_REGISTER_10_MONTH,
45   RP5C01A_REGISTER_1_YEAR, RP5C01A_REGISTER_LEAP_YEAR = RP5C01A_REGISTER_1_YEAR,
46   RP5C01A_REGISTER_10_YEAR,
47   RP5C01A_REGISTER_MODE,
48   RP5C01A_REGISTER_TEST,
49   RP5C01A_REGISTER_RESET
50};
51
52#define RP5C01A_MODE_TIMER_EN      0x08
53#define RP5C01A_MODE_ALARM_EN      0x04
54#define RP5C01A_MODE_MASK         0x03
55#define RP5C01A_MODE_RAM_BLOCK11   0x03
56#define RP5C01A_MODE_RAM_BLOCK10   0x02
57#define RP5C01A_MODE_ALARM         0x01
58#define RP5C01A_MODE_TIME         0x00
59
60#define RP5C01A_TEST_4            0x08
61#define RP5C01A_TEST_3            0x04
62#define RP5C01A_TEST_2            0x02
63#define RP5C01A_TEST_1            0x01
64
65#define RP5C01A_RESET_ALARM         0x08
66#define RP5C01A_RESET_TIMER         0x04
67#define RP5C01A_RESET_16_HZ         0x02
68#define RP5C01A_RESET_1_HZ         0x01
69
70/***************************************************************************
71    TYPE DEFINITIONS
72***************************************************************************/
73
74typedef struct _rp5c01a_t rp5c01a_t;
75struct _rp5c01a_t
76{
77   devcb_resolved_write_line   out_alarm_func;
78
79   UINT8 reg[4][13];         /* clock registers */
80
81   UINT8 mode;               /* mode register */
82
83   /* timers */
84   emu_timer *clock_timer;
85   emu_timer *alarm_timer;
86};
87
88/***************************************************************************
89    INLINE FUNCTIONS
90***************************************************************************/
91
92INLINE rp5c01a_t *get_safe_token(device_t *device)
93{
94   assert(device != NULL);
95   assert(device->type() == RP5C01A);
96   return (rp5c01a_t *)downcast<legacy_device_base *>(device)->token();
97}
98
99INLINE const rp5c01a_interface *get_interface(device_t *device)
100{
101   assert(device != NULL);
102   assert((device->type() == RP5C01A));
103   return (const rp5c01a_interface *) device->baseconfig().static_config();
104}
105
106/***************************************************************************
107    IMPLEMENTATION
108***************************************************************************/
109
110/*-------------------------------------------------
111    rp5c01a_adj_w - clock adjust write
112-------------------------------------------------*/
113
114WRITE_LINE_DEVICE_HANDLER( rp5c01a_adj_w )
115{
116//  rp5c01a_t *rp5c01a = get_safe_token(device);
117
118}
119
120/*-------------------------------------------------
121    rp5c01a_r - register read
122-------------------------------------------------*/
123
124READ8_DEVICE_HANDLER( rp5c01a_r )
125{
126   rp5c01a_t *rp5c01a = get_safe_token(device);
127
128   UINT8 data = 0;
129
130   switch (offset & 0x0f)
131   {
132   case RP5C01A_REGISTER_MODE:
133      data = rp5c01a->mode;
134      break;
135
136   case RP5C01A_REGISTER_TEST:
137   case RP5C01A_REGISTER_RESET:
138      /* write only */
139      break;
140
141   default:
142      data = rp5c01a->reg[rp5c01a->mode & RP5C01A_MODE_MASK][offset];
143      break;
144   }
145
146   return data;
147}
148
149/*-------------------------------------------------
150    rp5c01a_w - register write
151-------------------------------------------------*/
152
153WRITE8_DEVICE_HANDLER( rp5c01a_w )
154{
155   rp5c01a_t *rp5c01a = get_safe_token(device);
156
157   int mode = rp5c01a->mode & RP5C01A_MODE_MASK;
158
159   switch (offset & 0x0f)
160   {
161   case RP5C01A_REGISTER_MODE:
162      rp5c01a->mode = data;
163
164      rp5c01a->clock_timer->enable(data & RP5C01A_MODE_TIMER_EN);
165
166      if (LOG)
167      {
168         logerror("RP5C01A '%s' Mode %u\n", device->tag(), data & RP5C01A_MODE_MASK);
169         logerror("RP5C01A '%s' Timer %s\n", device->tag(), (data & RP5C01A_MODE_TIMER_EN ) ? "enabled" : "disabled");
170         logerror("RP5C01A '%s' Alarm %s\n", device->tag(), (data & RP5C01A_MODE_ALARM_EN ) ? "enabled" : "disabled");
171      }
172      break;
173
174   case RP5C01A_REGISTER_TEST:
175      if (LOG) logerror("RP5C01A '%s' Test %u not supported!\n", device->tag(), data);
176      break;
177
178   case RP5C01A_REGISTER_RESET:
179      if (data & RP5C01A_RESET_ALARM)
180      {
181         int i;
182
183         /* reset alarm registers */
184         for (i = RP5C01A_REGISTER_1_MINUTE; i < RP5C01A_REGISTER_1_MONTH; i++)
185         {
186            rp5c01a->reg[RP5C01A_MODE_ALARM][i] = 0;
187         }
188      }
189
190      rp5c01a->alarm_timer->enable(!(data & RP5C01A_RESET_16_HZ));
191
192      if (LOG)
193      {
194         if (data & RP5C01A_RESET_ALARM) logerror("RP5C01A '%s' Alarm Reset\n", device->tag());
195         if (data & RP5C01A_RESET_TIMER) logerror("RP5C01A '%s' Timer Reset not supported!\n", device->tag());
196         logerror("RP5C01A '%s' 16Hz Signal %s\n", device->tag(), (data & RP5C01A_RESET_16_HZ) ? "disabled" : "enabled");
197         logerror("RP5C01A '%s' 1Hz Signal %s\n", device->tag(), (data & RP5C01A_RESET_1_HZ) ? "disabled" : "enabled");
198      }
199      break;
200
201   default:
202      rp5c01a->reg[mode][offset & 0x0f] = data;
203
204      if (LOG) logerror("RP5C01A '%s' Register %u Write %02x\n", device->tag(), offset & 0x0f, data);
205      break;
206   }
207}
208
209/*-------------------------------------------------
210    advance_seconds - advance seconds counter
211-------------------------------------------------*/
212
213static void advance_seconds(rp5c01a_t *rp5c01a)
214{
215   static const int days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
216
217   int seconds = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_SECOND] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_SECOND];
218   int minutes = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_MINUTE] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_MINUTE];
219   int hours = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_HOUR] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_HOUR];
220   int days = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_DAY] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_DAY];
221   int month = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_MONTH] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_MONTH];
222   int year = (rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_YEAR] * 10) + rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_YEAR];
223   int day_of_week = rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_DAY_OF_THE_WEEK];
224   int i;
225
226   seconds++;
227
228   if (seconds > 59)
229   {
230      seconds = 0;
231      minutes++;
232   }
233
234   if (minutes > 59)
235   {
236      minutes = 0;
237      hours++;
238   }
239
240   if (hours > 23)
241   {
242      hours = 0;
243      days++;
244      day_of_week++;
245   }
246
247   if (day_of_week > 6)
248   {
249      day_of_week++;
250   }
251
252   if (days > days_per_month[month - 1])
253   {
254      days = 1;
255      month++;
256   }
257
258   if (month > 12)
259   {
260      month = 1;
261      year++;
262   }
263
264   if (year > 99)
265   {
266      year = 0;
267   }
268
269   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_SECOND] = seconds % 10;
270   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_SECOND] = seconds / 10;
271   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_MINUTE] = minutes % 10;
272   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_MINUTE] = minutes / 10;
273   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_HOUR] = hours % 10;
274   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_HOUR] = hours / 10;
275   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_DAY] = days % 10;
276   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_DAY] = days / 10;
277   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_MONTH] = month % 10;
278   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_MONTH] = month / 10;
279   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_1_YEAR] = year % 10;
280   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_10_YEAR] = year / 10;
281   rp5c01a->reg[RP5C01A_MODE_TIME][RP5C01A_REGISTER_DAY_OF_THE_WEEK] = day_of_week;
282
283   if (!(rp5c01a->mode & RP5C01A_RESET_1_HZ))
284   {
285      /* pulse 1Hz alarm signal */
286      devcb_call_write_line(&rp5c01a->out_alarm_func, 0);
287      devcb_call_write_line(&rp5c01a->out_alarm_func, 1);
288   }
289   else if (rp5c01a->mode & RP5C01A_MODE_ALARM_EN)
290   {
291      for (i = RP5C01A_REGISTER_1_MINUTE; i < RP5C01A_REGISTER_1_MONTH; i++)
292      {
293         if (rp5c01a->reg[RP5C01A_MODE_ALARM][i] != rp5c01a->reg[RP5C01A_MODE_TIME][i]) return;
294      }
295
296      /* trigger alarm */
297      devcb_call_write_line(&rp5c01a->out_alarm_func, 0);
298      devcb_call_write_line(&rp5c01a->out_alarm_func, 1);
299   }
300}
301
302/*-------------------------------------------------
303    TIMER_CALLBACK( clock_tick )
304-------------------------------------------------*/
305
306static TIMER_CALLBACK( clock_tick )
307{
308   device_t *device = (device_t *)ptr;
309   rp5c01a_t *rp5c01a = get_safe_token(device);
310
311   advance_seconds(rp5c01a);
312}
313
314/*-------------------------------------------------
315    TIMER_CALLBACK( alarm_tick )
316-------------------------------------------------*/
317
318static TIMER_CALLBACK( alarm_tick )
319{
320   device_t *device = (device_t *)ptr;
321   rp5c01a_t *rp5c01a = get_safe_token(device);
322
323   devcb_call_write_line(&rp5c01a->out_alarm_func, 0);
324   devcb_call_write_line(&rp5c01a->out_alarm_func, 1);
325}
326
327/*-------------------------------------------------
328    DEVICE_START( rp5c01a )
329-------------------------------------------------*/
330
331static DEVICE_START( rp5c01a )
332{
333   rp5c01a_t *rp5c01a = get_safe_token(device);
334   const rp5c01a_interface *intf = get_interface(device);
335
336   /* resolve callbacks */
337   devcb_resolve_write_line(&rp5c01a->out_alarm_func, &intf->out_alarm_func, device);
338
339   /* create the timers */
340   rp5c01a->clock_timer = device->machine().scheduler().timer_alloc(FUNC(clock_tick), (void *)device);
341   rp5c01a->clock_timer->adjust(attotime::zero, 0, attotime::from_hz(1));
342
343   rp5c01a->alarm_timer = device->machine().scheduler().timer_alloc(FUNC(alarm_tick), (void *)device);
344   rp5c01a->alarm_timer->adjust(attotime::zero, 0, attotime::from_hz(16));
345   rp5c01a->alarm_timer->enable(0);
346
347   /* register for state saving */
348    state_save_register_global(device->machine(), rp5c01a->mode);
349    state_save_register_global_array(device->machine(), rp5c01a->reg[0]);
350    state_save_register_global_array(device->machine(), rp5c01a->reg[1]);
351    state_save_register_global_array(device->machine(), rp5c01a->reg[2]);
352    state_save_register_global_array(device->machine(), rp5c01a->reg[3]);
353}
354
355/*-------------------------------------------------
356    DEVICE_GET_INFO( rp5c01a )
357-------------------------------------------------*/
358
359DEVICE_GET_INFO( rp5c01a )
360{
361   switch (state)
362   {
363      /* --- the following bits of info are returned as 64-bit signed integers --- */
364      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(rp5c01a_t);            break;
365      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = 0;                        break;
366
367      /* --- the following bits of info are returned as pointers to data or functions --- */
368      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(rp5c01a);   break;
369      case DEVINFO_FCT_STOP:                     /* Nothing */                        break;
370      case DEVINFO_FCT_RESET:                     /* Nothing */                        break;
371
372      /* --- the following bits of info are returned as NULL-terminated strings --- */
373      case DEVINFO_STR_NAME:                     strcpy(info->s, "Ricoh RP5C01A");         break;
374      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Ricoh RP5C01A");         break;
375      case DEVINFO_STR_VERSION:                  strcpy(info->s, "1.0");                  break;
376      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__);               break;
377      case DEVINFO_STR_CREDITS:                  /* Nothing */                        break;
378   }
379}
380
381DEFINE_LEGACY_DEVICE(RP5C01A, rp5c01a);
src/mess/machine/rp5c01a.h
r11201r11202
1/**********************************************************************
2
3    Ricoh RP5C01A Real Time Clock With Internal RAM emulation
4
5    Copyright MESS Team.
6    Visit http://mamedev.org for licensing and usage restrictions.
7
8**********************************************************************
9                            _____   _____
10                   _CS   1 |*    \_/     | 18  Vcc
11                    CS   2 |             | 17  OSCOUT
12                   ADJ   3 |             | 16  OSCIN
13                    A0   4 |             | 15  _ALARM
14                    A1   5 |   RP5C01A   | 14  D3
15                    A2   6 |             | 13  D2
16                    A3   7 |             | 12  D1
17                   _RD   8 |             | 11  D0
18                   GND   9 |_____________| 10  _WR
19
20**********************************************************************/
21
22#ifndef __RP5C01A__
23#define __RP5C01A__
24
25#include "devcb.h"
26
27/***************************************************************************
28    MACROS / CONSTANTS
29***************************************************************************/
30
31DECLARE_LEGACY_DEVICE(RP5C01A, rp5c01a);
32
33#define MCFG_RP5C01A_ADD(_tag, _clock, _config) \
34   MCFG_DEVICE_ADD(_tag, RP5C01A, _clock) \
35   MCFG_DEVICE_CONFIG(_config)
36
37#define MCFG_RP5C01A_REMOVE(_tag) \
38   MCFG_DEVICE_REMOVE(_tag)
39
40#define RP5C01A_INTERFACE(name) \
41   const rp5c01a_interface (name)=
42
43/***************************************************************************
44    TYPE DEFINITIONS
45***************************************************************************/
46
47typedef struct _rp5c01a_interface rp5c01a_interface;
48struct _rp5c01a_interface
49{
50   /* this gets called for every change of the _ALARM pin (pin 15) */
51   devcb_write_line      out_alarm_func;
52};
53
54/***************************************************************************
55    PROTOTYPES
56***************************************************************************/
57/* adjust */
58WRITE_LINE_DEVICE_HANDLER( rp5c01a_adj_w );
59
60/* register access */
61READ8_DEVICE_HANDLER( rp5c01a_r );
62WRITE8_DEVICE_HANDLER( rp5c01a_w );
63
64#endif /* __RP5C01A__ */
src/mess/includes/kyocera.h
r11201r11202
1313#include "machine/i8155.h"
1414#include "machine/msm8251.h"
1515#include "machine/ram.h"
16#include "machine/rp5c01a.h"
16#include "machine/rp5c01.h"
1717#include "machine/upd1990a.h"
1818#include "video/hd44102.h"
1919#include "video/hd61830.h"
r11201r11202
157157   tandy200_state(running_machine &machine, const driver_device_config_base &config)
158158      : driver_device(machine, config),
159159        m_maincpu(*this, I8085_TAG),
160        m_rtc(*this, UPD1990A_TAG),
160        m_rtc(*this, RP5C01A_TAG),
161161        m_lcdc(*this, HD61830_TAG),
162162        m_centronics(*this, CENTRONICS_TAG),
163163        m_speaker(*this, SPEAKER_TAG),
r11201r11202
166166   { }
167167
168168   required_device<cpu_device> m_maincpu;
169   required_device<device_t> m_rtc;
169   required_device<rp5c01_device> m_rtc;
170170   required_device<hd61830_device> m_lcdc;
171171   required_device<device_t> m_centronics;
172172   required_device<device_t> m_speaker;
src/mess/mess.mak
r11201r11202
530530   $(MESS_MACHINE)/pc_lpt.o   \
531531   $(MESS_MACHINE)/pc_mouse.o   \
532532   $(MESS_MACHINE)/pcf8593.o   \
533   $(MESS_MACHINE)/rp5c01a.o   \
534533   $(MESS_MACHINE)/rp5c15.o   \
535534   $(MESS_MACHINE)/rs232.o      \
536535   $(MESS_MACHINE)/scsibus.o   \
src/mess/drivers/kyocera.c
r11201r11202
614614
615615static ADDRESS_MAP_START( tandy200_io, AS_IO, 8, tandy200_state )
616616   ADDRESS_MAP_UNMAP_HIGH
617   AM_RANGE(0x90, 0x9f) AM_DEVREADWRITE_LEGACY(RP5C01A_TAG, rp5c01a_r, rp5c01a_w)
617   AM_RANGE(0x90, 0x9f) AM_DEVREADWRITE(RP5C01A_TAG, rp5c01_device, read, write)
618618//  AM_RANGE(0xa0, 0xa0) AM_MIRROR(0x0f) AM_DEVWRITE(TCM5089_TAG, write)
619619   AM_RANGE(0xb0, 0xb7) AM_MIRROR(0x08) AM_DEVREADWRITE(I8155_TAG, i8155_device, io_r, io_w)
620620   AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x0e) AM_DEVREADWRITE_LEGACY(MSM8251_TAG, msm8251_data_r, msm8251_data_w)
r11201r11202
880880
881881/* RP5C01A Interface */
882882
883static RP5C01A_INTERFACE( tandy200_rp5c01a_intf )
883static RP5C01_INTERFACE( tandy200_rtc_intf )
884884{
885885   DEVCB_NULL                        /* alarm */
886886};
r11201r11202
10951095
10961096/* MSM8251 Interface */
10971097
1098static const msm8251_interface tandy200_msm8251_interface =
1098static const msm8251_interface tandy200_uart_intf =
10991099{
11001100   DEVCB_NULL,
11011101   DEVCB_NULL,
r11201r11202
14221422
14231423   /* devices */
14241424   MCFG_I8155_ADD(I8155_TAG, XTAL_4_9152MHz/2, tandy200_8155_intf)
1425   MCFG_RP5C01A_ADD(RP5C01A_TAG, XTAL_32_768kHz, tandy200_rp5c01a_intf)
1426   MCFG_MSM8251_ADD(MSM8251_TAG, /*XTAL_4_9152MHz/2,*/ tandy200_msm8251_interface)
1425   MCFG_RP5C01_ADD(RP5C01A_TAG, XTAL_32_768kHz, tandy200_rtc_intf)
1426   MCFG_MSM8251_ADD(MSM8251_TAG, /*XTAL_4_9152MHz/2,*/ tandy200_uart_intf)
14271427//  MCFG_MC14412_ADD(MC14412_TAG, XTAL_1MHz)
14281428   MCFG_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics)
14291429   MCFG_CASSETTE_ADD("cassette", kc85_cassette_config)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team