Previous 199869 Revisions Next

r33274 Friday 7th November, 2014 at 21:19:16 UTC by Sandro Ronco
MM58167: implemented IRQs and counters write, this allow to pass the K803 diagnostic test. (nw)

dirtc: call clock_updated() after increasing the minutes counter. (nw)
[src/emu]dirtc.c
[src/emu/bus/dmv]k803.c
[src/emu/machine]mm58167.c mm58167.h

trunk/src/emu/bus/dmv/k803.c
r241785r241786
129129void dmv_k803_device::update_int()
130130{
131131   bool state = ((m_latch & 0x80) && m_rtc_int);
132   m_bus->m_out_irq_cb(state ? ASSERT_LINE : CLEAR_LINE);
132   m_bus->m_out_int_cb(state ? ASSERT_LINE : CLEAR_LINE);
133133}
trunk/src/emu/dirtc.c
r241785r241786
177177      m_register[RTC_HOUR] = 0;
178178      advance_days();
179179   }
180   else
181   {
182      clock_updated();
183   }
180184}
181185
182186
trunk/src/emu/machine/mm58167.c
r241785r241786
22
33    mm58167.c - National Semiconductor MM58167 real-time clock emulation
44
5    TODO: alarms and IRQs not used by the Apple /// and aren't implemented.
5    TODO: standby interrupt
66
77**********************************************************************/
88
r241785r241786
7070
7171   // state saving
7272   save_item(NAME(m_regs));
73   save_item(NAME(m_milliseconds));
74   save_item(NAME(m_comparator_state));
7375}
7476
7577
r241785r241786
8284   set_current_time(machine());
8385
8486   m_regs[R_CTL_STATUS] = 0;   // not busy
87   m_regs[R_CTL_IRQSTATUS] = 0;
8588   m_milliseconds = 0;
89   m_comparator_state = false;
8690}
8791
8892
r241785r241786
101105
102106   if (m_milliseconds >= 999)
103107   {
108      int old_seconds = m_regs[R_CNT_SECONDS];
109      int old_minutes = m_regs[R_CNT_MINUTES];
110      int old_hours = m_regs[R_CNT_HOURS];
111      int old_dayofmonth = m_regs[R_CNT_DAYOFMONTH];
112      int old_dayofweek = m_regs[R_CNT_DAYOFWEEK];
113      int old_month = m_regs[R_CNT_MONTH];
114
104115      advance_seconds();
105116      m_milliseconds = 0;
117
118      if ((m_regs[R_CTL_IRQCONTROL] & 0x04) && m_regs[R_CNT_SECONDS]    != old_seconds)       set_irq(2); // every second
119      if ((m_regs[R_CTL_IRQCONTROL] & 0x08) && m_regs[R_CNT_MINUTES]    != old_minutes)       set_irq(3); // every minute
120      if ((m_regs[R_CTL_IRQCONTROL] & 0x10) && m_regs[R_CNT_HOURS]      != old_hours)         set_irq(4); // every hour
121      if ((m_regs[R_CTL_IRQCONTROL] & 0x20) && m_regs[R_CNT_DAYOFMONTH] != old_dayofmonth)    set_irq(5); // every day
122      if ((m_regs[R_CTL_IRQCONTROL] & 0x40) && m_regs[R_CNT_DAYOFWEEK]  <  old_dayofweek)     set_irq(6); // every week
123      if ((m_regs[R_CTL_IRQCONTROL] & 0x80) && m_regs[R_CNT_MONTH]      != old_month)         set_irq(7); // every month
106124   }
107125
108126   m_regs[R_CNT_MILLISECONDS] = make_bcd(m_milliseconds % 10);
109127   m_regs[R_CNT_HUNDTENTHS] = make_bcd(m_milliseconds / 10);
128
129   // 10Hz IRQ
130   if ((m_regs[R_CTL_IRQCONTROL] & 0x02) && (m_milliseconds % 100) == 0)
131      set_irq(1);
132
133   // comparator IRQ
134   bool new_state = true;
135   for (int i = R_CNT_MILLISECONDS; i <= R_CNT_MONTH; i++)
136   {
137      // nibbles that have the 2 MSB set always compares true
138      // Milliseconds use only the high nibble and Day of Week only the low nibble
139      if ((i != R_CNT_MILLISECONDS && (m_regs[i + 8] & 0x0c) != 0x0c && (m_regs[i + 8] & 0x0f) != (m_regs[i] & 0x0f)) ||
140         (i != R_CNT_DAYOFWEEK    && (m_regs[i + 8] & 0xc0) != 0xc0 && (m_regs[i + 8] & 0xf0) != (m_regs[i] & 0xf0)))
141      {
142         new_state = false;
143         break;
144      }
145   }
146
147   if ((m_regs[R_CTL_IRQCONTROL] & 0x01) && !m_comparator_state && new_state)  // positive-edge-triggered
148      set_irq(0);
149
150   m_comparator_state = new_state;
110151}
111152
112153
r241785r241786
124165   m_regs[R_CNT_MONTH] = make_bcd(month);              // month (BCD)
125166}
126167
168void mm58167_device::set_irq(int bit)
169{
170   m_regs[R_CTL_IRQSTATUS] |= (1 << bit);
171   m_irq_w(ASSERT_LINE);
172}
173
174void mm58167_device::update_rtc()
175{
176   set_clock_register(RTC_SECOND, bcd_to_integer(m_regs[R_CNT_SECONDS]));
177   set_clock_register(RTC_MINUTE, bcd_to_integer(m_regs[R_CNT_MINUTES]));
178   set_clock_register(RTC_HOUR, bcd_to_integer(m_regs[R_CNT_HOURS]));
179   set_clock_register(RTC_DAY, bcd_to_integer(m_regs[R_CNT_DAYOFMONTH]));
180   set_clock_register(RTC_DAY_OF_WEEK, bcd_to_integer(m_regs[R_CNT_DAYOFWEEK]));
181   set_clock_register(RTC_MONTH, bcd_to_integer(m_regs[R_CNT_MONTH]));
182   m_milliseconds = (bcd_to_integer(m_regs[R_CNT_HUNDTENTHS]) * 10) + (bcd_to_integer(m_regs[R_CNT_MILLISECONDS] >> 4) % 10);
183}
184
127185READ8_MEMBER(mm58167_device::read)
128186{
129187//  printf("read reg %x = %02x\n", offset, m_regs[offset]);
188
189   if (offset == R_CTL_IRQSTATUS && !space.debugger_access())
190   {
191      // reading the IRQ status clears IRQ line and IRQ status
192      UINT8 data = m_regs[offset];
193      m_regs[R_CTL_IRQSTATUS] = 0;
194      m_irq_w(CLEAR_LINE);
195      return data;
196   }
197
130198   return m_regs[offset];
131199}
132200
r241785r241786
141209
142210   switch (offset)
143211   {
212      case R_CNT_MILLISECONDS:
213      case R_CNT_HUNDTENTHS:
214      case R_CNT_SECONDS:
215      case R_CNT_MINUTES:
216      case R_CNT_HOURS:
217      case R_CNT_DAYOFWEEK:
218      case R_CNT_DAYOFMONTH:
219      case R_CNT_MONTH:
220         m_regs[offset] = data;
221         update_rtc();
222         break;
223
144224      // any write to this starts at the current time and zero milliseconds
145225      case R_CTL_GOCMD:
146226         m_milliseconds = 0;
147227         break;
148228
229      case R_CTL_RESETCOUNTERS:
230         if (data == 0xff)
231         {
232            for (int i = R_CNT_MILLISECONDS; i <= R_CNT_MONTH; i++)
233            {
234               m_regs[i] = 0;
235            }
236
237            update_rtc();
238         }
239         break;
240
149241      case R_CTL_RESETRAM:
150242         if (data == 0xff)
151243         {
trunk/src/emu/machine/mm58167.h
r241785r241786
5353   virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second);
5454   virtual bool rtc_feature_leap_year() { return true; }
5555
56   void set_irq(int bit);
57   void update_rtc();
58
5659private:
5760   int m_regs[32];
5861   int m_milliseconds;
62   bool m_comparator_state;
5963
6064   // timers
6165   emu_timer *m_clock_timer;


Previous 199869 Revisions Next


© 1997-2024 The MAME Team