trunk/src/emu/machine/s3520cf.c
r17467 | r17468 | |
6 | 6 | |
7 | 7 | TODO: |
8 | 8 | - kludge on address? |
| 9 | - SRAM hook-ups; |
| 10 | - SRAM load/save; |
| 11 | - system bits; |
9 | 12 | |
10 | 13 | ***************************************************************************/ |
11 | 14 | |
r17467 | r17468 | |
36 | 39 | |
37 | 40 | } |
38 | 41 | |
| 42 | void s3520cf_device::timer_callback() |
| 43 | { |
| 44 | static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; |
| 45 | int dpm_count; |
39 | 46 | |
| 47 | m_rtc.sec++; |
| 48 | |
| 49 | if((m_rtc.sec & 0x0f) >= 0x0a) { m_rtc.sec+=0x10; m_rtc.sec&=0xf0; } |
| 50 | if((m_rtc.sec & 0xf0) >= 0x60) { m_rtc.min++; m_rtc.sec = 0; } |
| 51 | if((m_rtc.min & 0x0f) >= 0x0a) { m_rtc.min+=0x10; m_rtc.min&=0xf0; } |
| 52 | if((m_rtc.min & 0xf0) >= 0x60) { m_rtc.hour++; m_rtc.min = 0; } |
| 53 | if((m_rtc.hour & 0x0f) >= 0x0a) { m_rtc.hour+=0x10; m_rtc.hour&=0xf0; } |
| 54 | if((m_rtc.hour & 0xff) >= 0x24) { m_rtc.day++; m_rtc.wday++; m_rtc.hour = 0; } |
| 55 | if(m_rtc.wday >= 7) { m_rtc.wday = 0; } |
| 56 | if((m_rtc.day & 0x0f) >= 0x0a) { m_rtc.day+=0x10; m_rtc.day&=0xf0; } |
| 57 | |
| 58 | /* TODO: crude leap year support */ |
| 59 | dpm_count = (m_rtc.month & 0xf) + (((m_rtc.month & 0x10) >> 4)*10)-1; |
| 60 | |
| 61 | if(((m_rtc.year % 4) == 0) && m_rtc.month == 2) |
| 62 | { |
| 63 | if((m_rtc.day & 0xff) >= dpm[dpm_count]+1+1) |
| 64 | { m_rtc.month++; m_rtc.day = 0x01; } |
| 65 | } |
| 66 | else if((m_rtc.day & 0xff) >= dpm[dpm_count]+1){ m_rtc.month++; m_rtc.day = 0x01; } |
| 67 | if((m_rtc.month & 0x0f) >= 0x0a) { m_rtc.month = 0x10; } |
| 68 | if(m_rtc.month >= 0x13) { m_rtc.year++; m_rtc.month = 1; } |
| 69 | if((m_rtc.year & 0x0f) >= 0x0a) { m_rtc.year+=0x10; m_rtc.year&=0xf0; } |
| 70 | if((m_rtc.year & 0xf0) >= 0xa0) { m_rtc.year = 0; } //1901-2000 possible timeframe |
| 71 | } |
| 72 | |
| 73 | TIMER_CALLBACK( s3520cf_device::rtc_inc_callback ) |
| 74 | { |
| 75 | reinterpret_cast<s3520cf_device *>(ptr)->timer_callback(); |
| 76 | } |
| 77 | |
40 | 78 | //------------------------------------------------- |
41 | 79 | // device_validity_check - perform validity checks |
42 | 80 | // on this device |
r17467 | r17468 | |
53 | 91 | |
54 | 92 | void s3520cf_device::device_start() |
55 | 93 | { |
| 94 | /* let's call the timer callback every second for now */ |
| 95 | machine().scheduler().timer_pulse(attotime::from_hz(clock() / XTAL_32_768kHz), FUNC(rtc_inc_callback), 0, (void *)this); |
56 | 96 | |
| 97 | system_time systime; |
| 98 | machine().base_datetime(systime); |
| 99 | |
| 100 | m_rtc.day = ((systime.local_time.mday / 10)<<4) | ((systime.local_time.mday % 10) & 0xf); |
| 101 | m_rtc.month = (((systime.local_time.month+1) / 10) << 4) | (((systime.local_time.month+1) % 10) & 0xf); |
| 102 | m_rtc.wday = systime.local_time.weekday; |
| 103 | m_rtc.year = (((systime.local_time.year % 100)/10)<<4) | ((systime.local_time.year % 10) & 0xf); |
| 104 | m_rtc.hour = ((systime.local_time.hour / 10)<<4) | ((systime.local_time.hour % 10) & 0xf); |
| 105 | m_rtc.min = ((systime.local_time.minute / 10)<<4) | ((systime.local_time.minute % 10) & 0xf); |
| 106 | m_rtc.sec = ((systime.local_time.second / 10)<<4) | ((systime.local_time.second % 10) & 0xf); |
57 | 107 | } |
58 | 108 | |
59 | 109 | |
r17467 | r17468 | |
63 | 113 | |
64 | 114 | void s3520cf_device::device_reset() |
65 | 115 | { |
| 116 | m_mode = 0; |
66 | 117 | } |
67 | 118 | |
68 | 119 | //------------------------------------------------- |
r17467 | r17468 | |
75 | 126 | |
76 | 127 | res = 0; |
77 | 128 | |
78 | | switch(offset) |
| 129 | if(m_mode != 0) |
79 | 130 | { |
80 | | // case 0: // 1 sec |
81 | | // case 1: // 10 sec |
82 | | // case 2: // 1 min |
83 | | // case 3: // 10 min |
84 | | // case 6: // week |
85 | | // case 7: // 1 day |
86 | | case 4: // 1 hour |
87 | | res = 1; |
88 | | break; |
89 | | case 5: // 10 hour |
90 | | res = 2; |
91 | | break; |
| 131 | if(offset == 0xf) |
| 132 | res = (m_sysr << 3) | m_mode; |
| 133 | else |
| 134 | { |
| 135 | res = 0; |
| 136 | printf("Warning: S-3520CF RTC reads SRAM %02x %02x\n",offset,m_mode); |
| 137 | } |
92 | 138 | } |
| 139 | else |
| 140 | { |
| 141 | switch(offset) |
| 142 | { |
| 143 | case 0x0: res = m_rtc.sec & 0xf; break; |
| 144 | case 0x1: res = m_rtc.sec >> 4; break; |
| 145 | case 0x2: res = m_rtc.min & 0xf; break; |
| 146 | case 0x3: res = m_rtc.min >> 4; break; |
| 147 | case 0x4: res = m_rtc.hour & 0xf; break; |
| 148 | case 0x5: res = m_rtc.hour >> 4; break; |
| 149 | case 0x6: res = m_rtc.wday & 0xf; break; |
| 150 | case 0x7: res = m_rtc.day & 0xf; break; |
| 151 | case 0x8: res = m_rtc.day >> 4; break; |
| 152 | case 0x9: res = m_rtc.month & 0xf; break; |
| 153 | case 0xa: res = m_rtc.month >> 4; break; |
| 154 | case 0xb: res = m_rtc.year & 0xf; break; |
| 155 | case 0xc: res = m_rtc.year >> 4; break; |
| 156 | } |
| 157 | } |
93 | 158 | |
94 | | |
95 | | |
96 | 159 | return res; |
97 | 160 | } |
98 | 161 | |
99 | 162 | inline void s3520cf_device::rtc_write(UINT8 offset,UINT8 data) |
100 | 163 | { |
101 | | |
| 164 | if(offset == 0xf) |
| 165 | { |
| 166 | m_mode = data & 3; |
| 167 | m_sysr = (data & 8) >> 3; |
| 168 | printf("%02x\n",data); |
| 169 | } |
| 170 | else |
| 171 | { |
| 172 | if(m_mode != 0) |
| 173 | printf("Warning: S-3520CF RTC writes SRAM %02x %d\n",offset,m_mode); |
| 174 | } |
102 | 175 | } |
103 | 176 | |
104 | 177 | |
r17467 | r17468 | |
154 | 227 | |
155 | 228 | if(m_cmd_stream_pos == 4) |
156 | 229 | { |
157 | | m_rtc_addr = (m_current_cmd + 1) & 0xf; /* TODO: +1??? */ |
| 230 | m_rtc_addr = (m_current_cmd) & 0xf; |
158 | 231 | m_rtc_state = RTC_SET_DATA; |
159 | 232 | m_cmd_stream_pos = 0; |
160 | 233 | m_current_cmd = 0; |
r17467 | r17468 | |
167 | 240 | { |
168 | 241 | //printf("%02x %d\n",m_rtc_addr,m_cmd_stream_pos); |
169 | 242 | } |
170 | | m_read_latch = (rtc_read(m_rtc_addr) >> (m_cmd_stream_pos)) & 1; |
| 243 | m_read_latch = (rtc_read((m_rtc_addr+1) & 0xf) >> (m_cmd_stream_pos)) & 1; /* TODO: +1??? */ |
171 | 244 | } |
172 | 245 | |
173 | 246 | m_current_cmd = (m_current_cmd >> 1) | ((m_latch<<3)&8); |
r17467 | r17468 | |
176 | 249 | { |
177 | 250 | if(m_dir == 0) // WRITE |
178 | 251 | { |
179 | | printf("%02x %02x\n",m_rtc_addr,m_current_cmd); |
180 | | rtc_write(m_rtc_addr,m_current_cmd); |
| 252 | //printf("%02x %02x\n",m_rtc_addr,m_current_cmd); |
| 253 | rtc_write((m_rtc_addr - 1) & 0xf,m_current_cmd); /* TODO: -1??? */ |
181 | 254 | } |
182 | 255 | |
183 | 256 | m_rtc_addr = m_current_cmd; |