Previous 199869 Revisions Next

r18081 Sunday 23rd September, 2012 at 03:37:54 UTC by R. Belmont
Made Epson R4543 RTC a proper RTC device, eliminates duplicated code in Namco Systems 12 and 23 [R. Belmont]
[src/emu]emu.mak
[src/emu/machine]rtc4543.c* rtc4543.h*
[src/mame/drivers]namcos12.c namcos23.c

trunk/src/mame/drivers/namcos12.c
r18080r18081
10391039#include "includes/psx.h"
10401040#include "machine/at28c16.h"
10411041#include "sound/c352.h"
1042#include "machine/rtc4543.h"
10421043
10431044#define VERBOSE_LEVEL ( 0 )
10441045
r18080r18081
10471048public:
10481049   namcos12_state(const machine_config &mconfig, device_type type, const char *tag)
10491050      : psx_state(mconfig, type, tag),
1051          m_rtc(*this, "rtc"),
10501052        m_sharedram(*this, "sharedram") { }
10511053
1054    required_device<rtc4543_device> m_rtc;
10521055   required_shared_ptr<UINT32> m_sharedram;
10531056   UINT32 m_n_bankoffset;
10541057
r18080r18081
14671470
14681471WRITE8_MEMBER(namcos12_state::s12_mcu_pa_w)
14691472{
1470
1471   // bit 0 = chip enable for the RTC
1472   // reset the state on the rising edge of the bit
1473   if ((!(m_s12_porta & 1)) && (data & 1))
1474   {
1475      m_s12_rtcstate = 0;
1476   }
1477
1473    m_rtc->ce_w(data & 1);
14781474   m_s12_porta = data;
14791475}
14801476
1481INLINE UINT8 make_bcd(UINT8 data)
1482{
1483   return ((data / 10) << 4) | (data % 10);
1484}
1485
14861477READ8_MEMBER(namcos12_state::s12_mcu_rtc_r)
14871478{
1488   UINT8 ret = 0;
1489   system_time systime;
1490   static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 };
1479    UINT8 ret = 0;
14911480
1492   machine().current_datetime(systime);
1481    for (int i = 0; i < 8; i++)
1482    {
1483        m_rtc->clk_w(0);
1484        m_rtc->clk_w(1);
1485        ret <<= 1;
1486        ret |= m_rtc->data_r();
1487    }
14931488
1494   switch (m_s12_rtcstate)
1495   {
1496      case 0:
1497         ret = make_bcd(systime.local_time.second);   // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low
1498         break;
1499      case 1:
1500         ret = make_bcd(systime.local_time.minute);   // minutes (BCD, 0-59)
1501         break;
1502      case 2:
1503         ret = make_bcd(systime.local_time.hour);   // hour (BCD, 0-23)
1504         break;
1505      case 3:
1506         ret = make_bcd(weekday[systime.local_time.weekday]);   // low nibble = day of the week
1507         ret |= (make_bcd(systime.local_time.mday) & 0x0f)<<4;   // high nibble = low digit of day
1508         break;
1509      case 4:
1510         ret = (make_bcd(systime.local_time.mday) >> 4);         // low nibble = high digit of day
1511         ret |= (make_bcd(systime.local_time.month + 1) & 0x0f)<<4;   // high nibble = low digit of month
1512         break;
1513      case 5:
1514         ret = make_bcd(systime.local_time.month + 1) >> 4;   // low nibble = high digit of month
1515         ret |= (make_bcd(systime.local_time.year % 10) << 4);   // high nibble = low digit of year
1516         break;
1517      case 6:
1518         ret = make_bcd(systime.local_time.year % 100) >> 4;   // low nibble = tens digit of year (BCD, 0-9)
1519         break;
1520   }
1521
1522   m_s12_rtcstate++;
1523
15241489   return ret;
15251490}
15261491
r18080r18081
16821647
16831648   MCFG_MACHINE_RESET_OVERRIDE(namcos12_state, namcos12 )
16841649
1650    MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz)
1651
16851652   /* video hardware */
16861653   MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz )
16871654   MCFG_PSXGPU_VBLANK_CALLBACK( vblank_state_delegate( FUNC( namcos12_sub_irq ), (namcos12_state *) owner ) )
trunk/src/mame/drivers/namcos23.c
r18080r18081
12281228#include "cpu/sh2/sh2.h"
12291229#include "sound/c352.h"
12301230#include "machine/nvram.h"
1231#include "machine/rtc4543.h"
12311232
12321233#define S23_BUSCLOCK   (66664460/2)   /* 33MHz CPU bus clock / input, somehow derived from 14.31721 MHz crystal */
12331234#define S23_H8CLOCK      (14745600)
r18080r18081
13201321public:
13211322   namcos23_state(const machine_config &mconfig, device_type type, const char *tag)
13221323      : driver_device(mconfig, type, tag) ,
1324        m_rtc(*this, "rtc"),
13231325      m_shared_ram(*this, "shared_ram"),
13241326      m_charram(*this, "charram"),
13251327      m_textram(*this, "textram"),
r18080r18081
13331335   render_t m_render;
13341336
13351337   tilemap_t *m_bgtilemap;
1338    required_device<rtc4543_device> m_rtc;
13361339   required_shared_ptr<UINT32> m_shared_ram;
13371340   required_shared_ptr<UINT32> m_charram;
13381341   required_shared_ptr<UINT32> m_textram;
r18080r18081
26102613WRITE8_MEMBER(namcos23_state::s23_mcu_pa_w)
26112614{
26122615   // bit 0 = chip enable for the RTC
2613   // reset the state on the rising edge of the bit
2614   if ((!(m_s23_porta & 1)) && (data & 1))
2615   {
2616      m_s23_rtcstate = 0;
2617   }
2618
2616    m_rtc->ce_w(data & 1);
26192617   m_s23_porta = data;
26202618}
26212619
2622INLINE UINT8 make_bcd(UINT8 data)
2623{
2624   return ((data / 10) << 4) | (data % 10);
2625}
2626
26272620READ8_MEMBER(namcos23_state::s23_mcu_rtc_r)
26282621{
2629   UINT8 ret = 0;
2630   system_time systime;
2631   static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 };
2622    UINT8 ret = 0;
26322623
2633   machine().current_datetime(systime);
2624    for (int i = 0; i < 8; i++)
2625    {
2626        m_rtc->clk_w(0);
2627        m_rtc->clk_w(1);
2628        ret <<= 1;
2629        ret |= m_rtc->data_r();
2630    }
26342631
2635   switch (m_s23_rtcstate)
2636   {
2637      case 0:
2638         ret = make_bcd(systime.local_time.second);   // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low
2639         break;
2640      case 1:
2641         ret = make_bcd(systime.local_time.minute);   // minutes (BCD, 0-59)
2642         break;
2643      case 2:
2644         ret = make_bcd(systime.local_time.hour);   // hour (BCD, 0-23)
2645         break;
2646      case 3:
2647         ret = make_bcd(weekday[systime.local_time.weekday]);   // low nibble = day of the week
2648         ret |= (make_bcd(systime.local_time.mday) & 0x0f)<<4;   // high nibble = low digit of day
2649         break;
2650      case 4:
2651         ret = (make_bcd(systime.local_time.mday) >> 4);         // low nibble = high digit of day
2652         ret |= (make_bcd(systime.local_time.month + 1) & 0x0f)<<4;   // high nibble = low digit of month
2653         break;
2654      case 5:
2655         ret = make_bcd(systime.local_time.month + 1) >> 4;   // low nibble = high digit of month
2656         ret |= (make_bcd(systime.local_time.year % 10) << 4);   // high nibble = low digit of year
2657         break;
2658      case 6:
2659         ret = make_bcd(systime.local_time.year % 100) >> 4;   // low nibble = tens digit of year (BCD, 0-9)
2660         break;
2661   }
2662
2663   m_s23_rtcstate++;
2664
26652632   return ret;
26662633}
26672634
r18080r18081
31613128
31623129   MCFG_QUANTUM_TIME(attotime::from_hz(60000))
31633130
3131    MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz)
3132
31643133   MCFG_SCREEN_ADD("screen", RASTER)
31653134   MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1)
31663135   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate
r18080r18081
32063175
32073176   MCFG_QUANTUM_TIME(attotime::from_hz(60000))
32083177
3178    MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz)
3179
32093180   MCFG_SCREEN_ADD("screen", RASTER)
32103181   MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1)
32113182   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate
r18080r18081
32473218
32483219   MCFG_QUANTUM_TIME(attotime::from_hz(60000))
32493220
3221    MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz)
3222
32503223   MCFG_SCREEN_ADD("screen", RASTER)
32513224   MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1)
32523225   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate
trunk/src/emu/emu.mak
r18080r18081
239239   $(EMUMACHINE)/rp5c01.o      \
240240   $(EMUMACHINE)/rp5c15.o      \
241241   $(EMUMACHINE)/rp5h01.o      \
242   $(EMUMACHINE)/rtc4543.o      \
242243   $(EMUMACHINE)/rtc65271.o   \
243244   $(EMUMACHINE)/rtc9701.o      \
244245   $(EMUMACHINE)/s3c2400.o      \
trunk/src/emu/machine/rtc4543.c
r0r18081
1/**********************************************************************
2
3    rtc4543.c - Epson R4543 real-time clock chip emulation
4    by R. Belmont
5 
6    TODO: writing (not done by System 12 or 23 so no test case)
7 
8**********************************************************************/
9
10#include "rtc4543.h"
11
12//**************************************************************************
13//  MACROS / CONSTANTS
14//**************************************************************************
15
16#define VERBOSE 0
17
18//**************************************************************************
19//  LIVE DEVICE
20//**************************************************************************
21
22// device type definition
23const device_type RTC4543 = &device_creator<rtc4543_device>;
24
25
26//-------------------------------------------------
27//  rtc4543_device - constructor
28//-------------------------------------------------
29
30rtc4543_device::rtc4543_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
31    : device_t(mconfig, RTC4543, "Epson R4543", tag, owner, clock),
32     device_rtc_interface(mconfig, *this)
33{
34}
35
36
37//-------------------------------------------------
38//  device_start - device-specific startup
39//-------------------------------------------------
40
41void rtc4543_device::device_start()
42{
43   // allocate timers
44   m_clock_timer = timer_alloc();
45   m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
46
47   // state saving
48   save_item(NAME(m_ce));
49   save_item(NAME(m_clk));
50   save_item(NAME(m_wr));
51   save_item(NAME(m_data));
52   save_item(NAME(m_regs));
53   save_item(NAME(m_curreg));
54}
55
56
57//-------------------------------------------------
58//  device_reset - device-specific reset
59//-------------------------------------------------
60
61void rtc4543_device::device_reset()
62{
63   set_current_time(machine());
64
65    m_ce = 0;
66    m_wr = 0;
67    m_clk = 0;
68    m_data = 0;
69    m_curreg = 0;
70}
71
72
73//-------------------------------------------------
74//  device_timer - handler timer events
75//-------------------------------------------------
76
77void rtc4543_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
78{
79    advance_seconds();
80}
81
82
83INLINE UINT8 make_bcd(UINT8 data)
84{
85   return ((data / 10) << 4) | (data % 10);
86}
87
88//-------------------------------------------------
89//  rtc_clock_updated -
90//-------------------------------------------------
91
92void rtc4543_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
93{
94   static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 };
95
96    m_regs[0] = make_bcd(second);               // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low
97    m_regs[1] = make_bcd(minute);               // minutes (BCD, 0-59)
98    m_regs[2] = make_bcd(hour);                 // hour (BCD, 0-23)
99    m_regs[3] = make_bcd(weekday[day_of_week]);   // low nibble = day of the week
100    m_regs[3] |= (make_bcd(day) & 0x0f)<<4;       // high nibble = low digit of day
101    m_regs[4] = (make_bcd(day) >> 4);         // low nibble = high digit of day
102    m_regs[4] |= (make_bcd(month & 0x0f)<<4);   // high nibble = low digit of month
103    m_regs[5] = make_bcd(month & 0x0f) >> 4;    // low nibble = high digit of month
104    m_regs[5] |= (make_bcd(year % 10) << 4);   // high nibble = low digit of year
105    m_regs[6] = make_bcd(year % 100) >> 4;   // low nibble = tens digit of year (BCD, 0-9)
106}
107
108//-------------------------------------------------
109//  ce_w - chip enable write
110//-------------------------------------------------
111
112WRITE_LINE_MEMBER( rtc4543_device::ce_w )
113{
114   if (VERBOSE) printf("RTC4543 '%s' CE: %u\n", tag(), state);
115
116   if (!state && m_ce)         // complete transfer
117   {
118   }
119   else if (state && !m_ce)    // start new data transfer
120   {
121        m_curreg = 0;
122        m_bit = 8;      // force immediate reload of output data
123   }
124
125   m_ce = state;
126}
127
128//-------------------------------------------------
129//  wr_w - data direction line write
130//-------------------------------------------------
131
132WRITE_LINE_MEMBER( rtc4543_device::wr_w )
133{
134   if (VERBOSE) logerror("RTC4543 '%s' WR: %u\n", tag(), state);
135
136   m_wr = state;
137}
138
139//-------------------------------------------------
140//  clk_w - serial clock write
141//-------------------------------------------------
142
143WRITE_LINE_MEMBER( rtc4543_device::clk_w )
144{
145   if (VERBOSE) logerror("RTC4543 '%s' CLK: %u\n", tag(), state);
146
147   if (!m_ce) return;
148
149   if (!m_clk && state) // rising edge - read data becomes valid here
150   {
151        if (m_bit > 7)  // reload data?
152        {
153            m_bit = 0;
154            m_data = m_regs[m_curreg++];
155        }
156        else            // no reload, just continue with the current byte
157        {
158            m_data <<= 1;
159        }
160
161        m_bit++;
162   }
163   else if (m_clk && !state) // falling edge - write data becomes valid here
164   {
165   }
166
167   m_clk = state;
168}
169
170
171//-------------------------------------------------
172//  data_w - I/O write
173//-------------------------------------------------
174
175WRITE_LINE_MEMBER( rtc4543_device::data_w )
176{
177   if (VERBOSE) logerror("RTC4543 '%s' I/O: %u\n", tag(), state);
178
179   m_data |= (state & 1);
180}
181
182
183//-------------------------------------------------
184//  data_r - I/O read
185//-------------------------------------------------
186
187READ_LINE_MEMBER( rtc4543_device::data_r )
188{
189   return (m_data & 0x80) ? 1 : 0;
190}
191
trunk/src/emu/machine/rtc4543.h
r0r18081
1/**********************************************************************
2
3    rtc4543.h - Epson R4543 real-time clock emulation
4    by R. Belmont
5
6**********************************************************************/
7
8#pragma once
9
10#ifndef __RTC4543_H__
11#define __RTC4543_H__
12
13#include "emu.h"
14
15
16
17//**************************************************************************
18//  INTERFACE CONFIGURATION MACROS
19//**************************************************************************
20
21#define MCFG_RTC4543_ADD(_tag, _clock) \
22   MCFG_DEVICE_ADD(_tag, RTC4543, _clock)
23
24
25
26//**************************************************************************
27//  TYPE DEFINITIONS
28//**************************************************************************
29
30// ======================> rtc4543_device
31
32class rtc4543_device :  public device_t,
33                       public device_rtc_interface
34{
35public:
36    // construction/destruction
37    rtc4543_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
38
39    DECLARE_WRITE_LINE_MEMBER( ce_w );
40    DECLARE_WRITE_LINE_MEMBER( wr_w );
41    DECLARE_WRITE_LINE_MEMBER( clk_w );
42    DECLARE_READ_LINE_MEMBER( data_r );
43    DECLARE_WRITE_LINE_MEMBER( data_w );
44
45protected:
46    // device-level overrides
47    virtual void device_start();
48    virtual void device_reset();
49    virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
50
51    // device_rtc_interface overrides
52    virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second);
53    virtual bool rtc_feature_leap_year() { return true; }
54
55private:
56    int m_ce;
57    int m_clk;
58    int m_wr;
59    int m_data;
60    int m_regs[7];
61    int m_curreg;
62    int m_bit;
63
64    // timers
65    emu_timer *m_clock_timer;
66};
67
68
69// device type definition
70extern const device_type RTC4543;
71
72#endif

Previous 199869 Revisions Next


© 1997-2024 The MAME Team