Previous 15994 Revisions Next

r802 Thursday 9th August, 2007 at 11:47:30 UTC by Nathan Woods
[X68K] Added support for the Ricoh RP5C15 RTC, a few more memory size options,
and the .2HD file extension for disk images. [Barry Rodewald]
[docs]messnew.txt
[src/mess]mess.mak
[src/mess/drivers]x68k.c
[src/mess/includes]x68k.h
[src/mess/machine]rp5c15.c* rp5c15.h*

src/mess/includes/x68k.h
r801r802
158158   } ioc;
159159   struct
160160   {
161      unsigned char regbank0[13];
162      unsigned char regbank1[13];
163      int mode;
164      int test;
165      int reset;
166   } rtc;  //  Ricoh RP5C15
167   struct
168   {
169161      int inputtype;  // determines which input is to be received
170162      int irqactive;  // non-zero if IRQ is being serviced
171163      char last_mouse_x;  // previous mouse x-axis value
r801r802
174166   } mouse;
175167};
176168
169
177170TIMER_CALLBACK(mfp_timer_a_callback);
178171TIMER_CALLBACK(mfp_timer_b_callback);
179172TIMER_CALLBACK(mfp_timer_c_callback);
src/mess/machine/rp5c15.c
r0r802
1/*
2
3   Ricoh RP5C15 Real-time Clock
4   Written by Barry Rodewald
5   Started 04/07/07
6
7   Registers are separated into two banks, switchable through
8   the LSB of the MODE register.
9   
10   Date and time are stored in BCD, one digit to each register
11   
12   Register   BANK 0               BANK 1
13   0         Timer seconds         CLKOUT
14   1         Timer seconds (10s)      RTC Adjustment
15   2         Timer minutes         Alarm minutes
16   3         Timer minutes (10s)      Alarm minutes (10s)
17   4         Timer hours            Alarm hours
18   5         Timer hours (10s)      Alarm hours (10s)
19   6         Timer day-of-week      Alarm day-of-week
20   7         Timer day            Alarm day
21   8         Timer day (10s)         Alarm day (10s)
22   9         Timer month            (unused)
23   10         Timer month (10s)      12/24 hour clock selection
24   11         Timer year            Years until next leap year
25   12         Timer year (10s)      (unused)
26   13         MODE register         MODE register
27   14         TEST register         TEST register
28   15         RESET register         RESET register
29   
30   
31   CLKOUT (W/O) - on the X68000, this is connected to the Timer LED
32      xxxxx000 = always high (on)
33      xxxxx001 = 16384Hz
34      xxxxx010 =  1024Hz
35      xxxxx011 =   128Hz
36      xxxxx100 =    16Hz
37      xxxxx101 =     1Hz
38      xxxxx110 =  1/60Hz
39      xxxxx111 =  always low (off)
40     
41   Adjustment register (R/W)
42      bit 0 = if set, will reset the seconds to zero, and if the
43              seconds were > 30, increment the minutes by 1.
44              Always returns 0.
45             
46   12/24 hour clock register (R/W) (not implemented yet)
47      bit 0 = selects 12 or 24 hour clock
48              presumably, on reading, returns AM/PM status.
49             
50   Leap year register
51      bit 0,1 = returns number of years until next leap year.
52                Is simply year % 4.
53               
54   MODE register (R/W)
55      bit 0 = if set, selects BANK 1, if reset, selects BANK 0
56      bit 2 = Alarm enable
57      bit 3 = Timer enable
58     
59   TEST register (not implemented yet)
60      bits 0-3 = generally all set to 0, use is unknown.
61     
62   RESET register (not implemented yet)
63      bit 0 = Alarm reset
64      bit 1 = Timer reset
65      bit 2 = if set, 16Hz pulse is off
66      bit 3 = if set, 1Hz pulse is off
67
68*/
69
70#include "rp5c15.h"
71
72struct rp5c15 rtc;
73
74mame_timer* rtc_timer;
75
76TIMER_CALLBACK(rtc_alarm_pulse)
77{
78   if(rtc.pulse16_state == 0)  // low
79   {
80      rtc.pulse16_state = 1;  // make high
81      rtc.pulse_count++;
82   }
83   else
84   {
85      rtc.pulse16_state = 0;  // make low
86   }
87     
88   if(rtc.pulse_count == 8)
89   {
90      rtc.pulse1_state = 0;
91   }
92   if(rtc.pulse_count == 16)
93   {
94      rtc.pulse_count = 0;
95      rtc.pulse1_state = 1;
96      rtc_add_second();
97   }
98}
99
100void rp5c15_init(struct rp5c15_interface* intf)
101{
102   mame_system_time systm;
103   mame_system_tm time;
104   
105   rtc.alarm_callback = intf->alarm_irq_callback;
106   
107   mame_get_base_datetime(Machine,&systm);
108   time = systm.local_time;
109   
110   // date/time is stored as BCD
111   rtc.systime.sec_1 = time.second % 10;
112   rtc.systime.sec_10 = time.second / 10;
113   rtc.systime.min_1 = time.minute % 10;
114   rtc.systime.min_10 = time.minute / 10;
115   rtc.systime.hour_1 = time.hour % 10;
116   rtc.systime.hour_10 = time.hour / 10;
117   rtc.systime.day_1 = time.mday % 10;
118   rtc.systime.day_10 = time.mday / 10;
119   rtc.systime.month_1 = (time.month+1) % 10;
120   rtc.systime.month_10 = (time.month+1) / 10;
121   rtc.systime.year_1 = (time.year - 1980) % 10;
122   rtc.systime.year_10 = (time.year - 1980) / 10;
123   rtc.systime.dayofweek = time.weekday;
124   rtc.alarm.min_1 = time.minute % 10;
125   rtc.alarm.min_10 = time.minute / 10;
126   rtc.alarm.hour_1 = time.hour % 10;
127   rtc.alarm.hour_10 = time.hour / 10;
128   rtc.alarm.day_1 = time.mday % 10;
129   rtc.alarm.day_10 = time.mday / 10;
130   rtc.alarm.dayofweek = time.weekday;
131   rtc.leap = time.year % 4;
132
133   rtc.mode = 0x08;  // Timer enabled, Alarm disable, BANK 0 selected (defaults are guessed)
134   rtc.reset = 0x00;  // enable both 1Hz and 16Hz alarm counters by default
135   rtc.test = 0x00;
136   rtc.pulse_count = 0;
137   
138   rtc_timer = mame_timer_alloc(rtc_alarm_pulse);
139   mame_timer_adjust(rtc_timer, time_zero, 0, MAME_TIME_IN_HZ(32));
140}
141
142int rp5c15_read(int offset, UINT16 mem_mask)
143{
144   if((rtc.mode & 0x01) == 0x00)  // BANK 0 selected
145   {
146      switch(offset)
147      {
148         case 0:
149            return rtc.systime.sec_1;
150         case 1:
151            return rtc.systime.sec_10;
152         case 2:
153            return rtc.systime.min_1;
154         case 3:
155            return rtc.systime.min_10;
156         case 4:
157            return rtc.systime.hour_1;
158         case 5:
159            return rtc.systime.hour_10;
160         case 6:
161            return rtc.systime.dayofweek;
162         case 7:
163            return rtc.systime.day_1;
164         case 8:
165            return rtc.systime.day_10;
166         case 9:
167            return rtc.systime.month_1;
168         case 10:
169            return rtc.systime.month_10;
170         case 11:
171            return rtc.systime.year_1;
172         case 12:
173            return rtc.systime.year_10;
174         case 13:
175            return rtc.mode & 0x0f;   
176      }
177   }
178   else  // BANK 1 selected
179   {
180      switch(offset)
181      {
182         case 0:  // CLKOUT
183            return rtc.clkout & 0x07;
184         case 1:  // Adjustment (always returns 0)
185            return 0;
186         case 2:
187            return rtc.alarm.min_1;
188         case 3:
189            return rtc.alarm.min_10;
190         case 4:
191            return rtc.alarm.hour_1;
192         case 5:
193            return rtc.alarm.hour_10;
194         case 6:
195            return rtc.alarm.dayofweek;
196         case 7:
197            return rtc.alarm.day_1;
198         case 8:
199            return rtc.alarm.day_10;
200         case 10:  // 12/24 hour selection (returns AM/PM?)
201            return 0;
202         case 11:  // Leap year
203            return rtc.leap;
204         case 13:
205            return rtc.mode & 0x0f;
206         default:
207            return 0;
208      }
209   }
210   return 0;
211}
212
213void rp5c15_write(int offset, int data, UINT16 mem_mask)
214{
215   if(offset == 13)
216   {
217      rtc.mode = data & 0x0f;
218      return;
219   }
220   if((rtc.mode & 0x01) == 0x00)  // BANK 0 selected
221   {
222      switch(offset)
223      {
224         case 0:
225            rtc.systime.sec_1 = data & 0x0f;
226            break;
227         case 1:
228            rtc.systime.sec_10 = data & 0x0f;
229            break;
230         case 2:
231            rtc.systime.min_1 = data & 0x0f;
232            break;
233         case 3:
234            rtc.systime.min_10 = data & 0x0f;
235            break;
236         case 4:
237            rtc.systime.hour_1 = data & 0x0f;
238            break;
239         case 5:
240            rtc.systime.hour_10 = data & 0x0f;
241            break;
242         case 6:
243            rtc.systime.dayofweek = data & 0x0f;
244            break;
245         case 7:
246            rtc.systime.day_1 = data & 0x0f;
247            break;
248         case 8:
249            rtc.systime.day_10 = data & 0x0f;
250            break;
251         case 9:
252            rtc.systime.month_1 = data & 0x0f;
253            break;
254         case 10:
255            rtc.systime.month_10 = data & 0x0f;
256            break;
257         case 11:
258            rtc.systime.year_1 = data & 0x0f;
259            break;
260         case 12:
261            rtc.systime.year_10 = data & 0x0f;
262            break;
263      }
264   }
265   else  // BANK 1 selected
266   {
267      switch(offset)
268      {
269         case 0:
270            rtc.clkout = data & 0x07;
271            break;
272         case 1:  // Adjustment  (resets seconds to 0, increases minute by 1 if seconds are > 30
273            if(rtc.systime.sec_10 >= 3)
274               rtc_add_minute();
275            rtc.systime.sec_1 = 0;
276            rtc.systime.sec_10 = 0;
277            break;
278         case 2:
279            rtc.alarm.min_1 = data & 0x0f;
280            break;
281         case 3:
282            rtc.alarm.min_10 = data & 0x0f;
283            break;
284         case 4:
285            rtc.alarm.hour_1 = data & 0x0f;
286            break;
287         case 5:
288            rtc.alarm.hour_10 = data & 0x0f;
289            break;
290         case 6:
291            rtc.alarm.dayofweek = data & 0x0f;
292            break;
293         case 7:
294            rtc.alarm.day_1 = data & 0x0f;
295            break;
296         case 8:
297            rtc.alarm.day_10 = data & 0x0f;
298            break;
299         case 10:  // 12/24 hour clock selection
300            rtc.hour24 = data;
301            break;
302         
303      }
304   }
305}
306
307void rtc_add_second()  // add one second to current time
308{
309   if((rtc.mode & 0x08) == 0x00) // if timer is not enabled
310      return;
311   rtc.systime.sec_1++;
312   if(rtc.systime.sec_1 < 10)
313      return;
314   rtc.systime.sec_1 = 0;
315   rtc.systime.sec_10++;
316   if(rtc.systime.sec_10 < 6)
317      return;
318   rtc.systime.sec_10 = 0;
319   rtc_add_minute();
320}
321
322void rtc_add_minute()
323{
324   rtc.systime.min_1++;
325   if(rtc.systime.min_1 < 10)
326      return;
327   rtc.systime.min_1 = 0;
328   rtc.systime.min_10++;
329   if(rtc.systime.min_10 < 6)
330      return;
331   rtc.systime.min_10 = 0;
332   rtc.systime.hour_1++;
333   if(rtc.systime.hour_1 < 10 && rtc.systime.hour_10 < 2)
334      return;
335   if(rtc.systime.hour_10 < 3 && rtc.systime.hour_1 < 4)
336      return;
337   rtc.systime.hour_1 = 0;
338   rtc.systime.hour_10++;
339   if(rtc.systime.hour_10 < 3)
340      return;
341   rtc.systime.hour_10 = 0;
342   rtc_add_day();
343}
344
345void rtc_add_day()
346{
347   int d,m;
348   
349   rtc.systime.dayofweek++;
350   if(rtc.systime.dayofweek >= 7)
351      rtc.systime.dayofweek = 0;
352   d = (rtc.systime.day_10 << 4) | rtc.systime.day_1;
353   m = (rtc.systime.month_10 << 4) | rtc.systime.month_1;
354   d++;
355   if((d & 0x0f) >= 10)
356   {
357      d &= 0xf0;
358      d += 0x10;
359   }
360   rtc.systime.day_1 = (d & 0x0f);
361   rtc.systime.day_10 = (d & 0xf0) >> 4;
362   switch(m)
363   {
364      case 1:
365      case 3:
366      case 5:
367      case 7:
368      case 8:
369      case 0x10:
370      case 0x12:
371         if(d > 0x31)
372         {
373            rtc.systime.day_1 = 1;
374            rtc.systime.day_10 = 0;
375            rtc_add_month();
376         }
377         break;
378      case 4:
379      case 6:
380      case 9:
381      case 11:
382         if(d > 0x30)
383         {
384            rtc.systime.day_1 = 1;
385            rtc.systime.day_10 = 0;
386            rtc_add_month();
387         }
388         break;
389      case 2:
390         if(rtc.leap == 0)  // this is a leap year
391         {
392            if(d > 0x29)
393            {
394               rtc.systime.day_1 = 1;
395               rtc.systime.day_10 = 0;
396               rtc_add_month();
397            }
398         }
399         else  // not a leap year
400         {
401            if(d > 0x28)
402            {
403               rtc.systime.day_1 = 1;
404               rtc.systime.day_10 = 0;
405               rtc_add_month();
406            }
407         }
408         break;
409   }
410}
411
412void rtc_add_month()
413{
414   rtc.systime.month_1++;
415   if(rtc.systime.month_1 < 10 && rtc.systime.month_10 < 1)
416      return;
417   if(rtc.systime.month_1 < 3 && rtc.systime.month_10 < 2)
418      return;
419   rtc.systime.month_1 = 0;
420   rtc.systime.month_10++;
421   if(rtc.systime.month_10 < 2)
422      return;
423   rtc.systime.month_1 = 1;
424   rtc.systime.month_10 = 0;
425   rtc.systime.year_1++;
426   if(rtc.systime.year_1 < 10)
427      return;
428   rtc.systime.year_1 = 0;
429   rtc.systime.year_10++;
430   if(rtc.systime.year_10 < 10)
431      return;
432   rtc.systime.year_10 = 0;
433}
434
435READ16_HANDLER(rp5c15_r) { return rp5c15_read(offset,mem_mask); }
436WRITE16_HANDLER(rp5c15_w) { return rp5c15_write(offset,data,mem_mask); }
src/mess/machine/rp5c15.h
r0r802
1/*
2 *  Ricoh RP5C15 RTC header
3 */
4
5#ifndef RP5C15_H_
6#define RP5C15_H_
7
8#include "driver.h"
9
10struct rp5c15_interface
11{
12   void (*alarm_irq_callback)(int state);
13};
14
15struct rp5c15
16{
17   struct
18   {
19      unsigned char sec_1;
20      unsigned char sec_10;
21      unsigned char min_1;
22      unsigned char min_10;
23      unsigned char hour_1;
24      unsigned char hour_10;
25      unsigned char dayofweek;
26      unsigned char day_1;
27      unsigned char day_10;
28      unsigned char month_1;
29      unsigned char month_10;
30      unsigned char year_1;
31      unsigned char year_10;
32   } systime;
33   struct
34   {
35      unsigned char min_1;
36      unsigned char min_10;
37      unsigned char hour_1;
38      unsigned char hour_10;
39      unsigned char dayofweek;
40      unsigned char day_1;
41      unsigned char day_10;
42   } alarm;
43   int clkout;
44   int adjust;
45   int hour24;  // 12/24 hour clock
46   int leap;  // Years until next leap year (0-3, 0 = this year is leap year)
47   int mode;
48   int test;
49   int reset;
50   int pulse_count;
51   int pulse1_state;
52   int pulse16_state;
53   void (*timer_callback)(int state);
54   void (*alarm_callback)(int state);
55};  //  Ricoh RP5C15
56
57void rp5c15_init(struct rp5c15_interface*);
58
59void rtc_add_second(void);
60void rtc_add_minute(void);
61void rtc_add_day(void);
62void rtc_add_month(void);
63
64TIMER_CALLBACK(rtc_alarm_pulse);
65
66READ16_HANDLER( rp5c15_r );
67WRITE16_HANDLER( rp5c15_w );
68
69#endif /*RP5C15_H_*/
src/mess/mess.mak
r801r802
944944   $(MESS_DRIVERS)/x68k.o   \
945945   $(MESS_VIDEO)/x68k.o   \
946946   $(MESS_MACHINE)/hd63450.o   \
947   $(MESS_MACHINE)/rp5c15.o   \
947948
948949$(MESSOBJ)/hp48.a:     \
949950   $(MESS_MACHINE)/hp48.o     \
src/mess/drivers/x68k.c
r801r802
135135#include "sound/okim6295.h"
136136#include "machine/8530scc.h"
137137#include "machine/hd63450.h"
138#include "machine/rp5c15.h"
138139#include "devices/basicdsk.h"
139140#include "includes/x68k.h"
140141
r801r802
11091110
11101111READ16_HANDLER( x68k_rtc_r )
11111112{
1112   if(offset < 13)
1113   {
1114      if(sys.rtc.mode & 0x01)
1115         return sys.rtc.regbank1[offset];
1116      else
1117         return sys.rtc.regbank0[offset];
1118   }
1119   else
1120   {
1121      if(offset == 0x13)
1122         return sys.rtc.mode & 0x0f;
1123//      logerror("RTC: [%08x] read from offset %i\n",activecpu_get_pc(),offset);
1124      return 0xff;
1125   }
1113   return rp5c15_r(offset,mem_mask);
11261114}
11271115
11281116WRITE16_HANDLER( x68k_rtc_w )
11291117{
1130   if(offset < 13)
1118   rp5c15_w(offset,data,mem_mask);
1119}
1120
1121void x68k_rtc_alarm_irq(int state)
1122{
1123   if(sys.mfp.aer & 0x01)
11311124   {
1132      if(sys.rtc.mode & 0x01)
1133         sys.rtc.regbank1[offset] = data;
1134      else
1135         sys.rtc.regbank0[offset] = data;
1125      if(state == 1)
1126         mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
11361127   }
11371128   else
11381129   {
1139      switch(offset)
1140      {
1141      case 14:  // MODE
1142         sys.rtc.mode = data & 0x0f;
1143         break;
1144      case 15:  // TEST  (will usually always be all 0)
1145         sys.rtc.test = data & 0x0f;
1146         break;
1147      case 16:  // RESET
1148         sys.rtc.reset = data & 0x0f;
1149         // TODO:  clocking up the RTC counter.
1150         break;
1151      default:
1152//         logerror("RTC: [%08x] write to invalid offset %i\n",activecpu_get_pc(),offset);
1153         break;
1154      }
1130      if(state == 0)
1131         mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
11551132   }
11561133}
11571134
r801r802
14961473   NULL//x68k_scc_ack
14971474};
14981475
1476static struct rp5c15_interface rtc_intf =
1477{
1478   x68k_rtc_alarm_irq
1479};
1480
14991481INPUT_PORTS_START( x68000 )
15001482   PORT_START_TAG( "joy1" )
15011483   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_CODE(JOYCODE_Y_UP_SWITCH)    PORT_PLAYER(1)
r801r802
17681750      info->unload = device_unload_x68k_floppy;
17691751      break;
17701752   case DEVINFO_STR_FILE_EXTENSIONS:           
1771      strcpy(info->s = device_temp_str(), "xdf,hdm,dim");
1753      strcpy(info->s = device_temp_str(), "xdf,hdm,2hd,dim");
17721754      break;
17731755   default:
17741756      legacybasicdsk_device_getinfo(devclass, state, info);
r801r802
18731855   nec765_reset(0);
18741856   mfp_init();
18751857   scc_init(&scc_interface);
1858   rp5c15_init(&rtc_intf);
18761859
18771860   cpunum_set_irq_callback(0, x68k_int_ack);
18781861
r801r802
19271910
19281911SYSTEM_CONFIG_START(x68000)
19291912   CONFIG_DEVICE(x68k_floppy_getinfo)
1913   CONFIG_RAM(0x100000)
1914   CONFIG_RAM(0x200000)
19301915   CONFIG_RAM_DEFAULT(0x400000)  // 4MB - should be enough for most things
1916   CONFIG_RAM(0x800000)
1917   CONFIG_RAM(0xc00000)  // 12MB - maximum possible
19311918SYSTEM_CONFIG_END
19321919
19331920ROM_START( x68000 )
docs/messnew.txt
r801r802
7777
7878- [THOMSON] Reworked memory handling and added support for RAM size
7979  configuration (w, w/o RAM extension).  [Antoine Mine]
80 
81- [X68K] Added support for the Ricoh RP5C15 RTC, a few more memory size
82  options, and the .2HD file extension for disk images.  [Barry Rodewald]
8083
8184
8285

Previous 15994 Revisions Next


© 1998-2018 The MESS Team