1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 /* 68307 TIMER module */
4 // 2x timers
5
6 #include "emu.h"
7 #include "68307tmu.h"
8
9 #define m68307TIMER_TMR (0x0)
10 #define m68307TIMER_TRR (0x1)
11 #define m68307TIMER_TCR (0x2)
12 #define m68307TIMER_TCN (0x3)
13 #define m68307TIMER_TER (0x4)
14 #define m68307TIMER_WRR (0x5)
15 #define m68307TIMER_WCR (0x6)
16 #define m68307TIMER_XXX (0x7)
17
m68307_internal_timer_r(offs_t offset,uint16_t mem_mask)18 uint16_t m68307_cpu_device::m68307_internal_timer_r(offs_t offset, uint16_t mem_mask)
19 {
20 assert(m_m68307TIMER);
21 m68307_timer &timer = *m_m68307TIMER;
22
23 int which = offset & 0x8;
24
25 switch (offset&0x7)
26 {
27 case m68307TIMER_TCN: /* 0x3 (0x126 / 0x136) */
28 //if (m_ppc!=0x2182e) logerror("%08x m68307_internal_timer_r %08x (%04x) (TCN - Timer Counter for timer %d)\n", m_ppc, offset*2,mem_mask, which);
29 return timer.read_tcn(mem_mask, which);
30
31 default:
32 logerror("%08x m68307_internal_timer_r %08x, (%04x)\n", m_ppc, offset*2,mem_mask);
33 break;
34 }
35
36 return 0x0000;
37 }
38
m68307_internal_timer_w(offs_t offset,uint16_t data,uint16_t mem_mask)39 void m68307_cpu_device::m68307_internal_timer_w(offs_t offset, uint16_t data, uint16_t mem_mask)
40 {
41 assert(m_m68307TIMER);
42 m68307_timer &timer = *m_m68307TIMER;
43
44 int which = offset & 0x8;
45
46 switch (offset&0x7)
47 {
48 case m68307TIMER_TMR: /* 0x0 (0x120 / 0x130) */
49 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TMR - Timer Mode Register for timer %d)\n", m_ppc, offset*2,data,mem_mask, which);
50 timer.write_tmr(data, mem_mask, which);
51 break;
52
53 case m68307TIMER_TRR: /* 0x1 (0x122 / 0x132) */
54 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TRR - Timer Reference Register for timer %d)\n", m_ppc, offset*2,data,mem_mask, which);
55 timer.write_trr(data, mem_mask, which);
56 break;
57
58 case m68307TIMER_TCR: /* 0x2 (0x124 / 0x134) */
59 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TCR - Timer Capture Register for timer %d) (illegal, read-only)\n", m_ppc, offset*2,data,mem_mask, which);
60 break;
61
62 case m68307TIMER_TCN: /* 0x3 (0x126 / 0x136) */
63 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TCN - Timer Counter for timer %d)\n", m_ppc, offset*2,data,mem_mask, which);
64 break;
65
66 case m68307TIMER_TER: /* 0x4 (0x128 / 0x138) */
67 /* 8-bit only!! */
68 //logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TER - Timer Event Register for timer %d)\n", m_ppc, offset*2,data,mem_mask, which);
69 timer.write_ter(data, mem_mask, which);
70 break;
71
72 case m68307TIMER_WRR: /* 0x5 (0x12a / 0x13a) */
73 if (which==0)
74 {
75 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (WRR - Watchdog Reference Register)\n", m_ppc, offset*2,data,mem_mask);
76 }
77 else
78 {
79 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", m_ppc, offset*2,data,mem_mask);
80 }
81 break;
82
83 case m68307TIMER_WCR: /* 0x6 (0x12c / 0x13c) */
84 if (which==0)
85 {
86 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (WRR - Watchdog Counter Register)\n", m_ppc, offset*2,data,mem_mask);
87 }
88 else
89 {
90 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", m_ppc, offset*2,data,mem_mask);
91 }
92 break;
93
94 case m68307TIMER_XXX: /* 0x7 (0x12e / 0x13e) */
95 logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", m_ppc, offset*2,data,mem_mask);
96 break;
97 }
98 }
99
TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::timer0_callback)100 TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::timer0_callback )
101 {
102 m68307_cpu_device* m68k = (m68307_cpu_device *)ptr;
103 single_timer* tptr = &m68k->m_m68307TIMER->singletimer[0];
104 tptr->regs[m68307TIMER_TER] |= 0x2;
105
106 if (BIT(tptr->regs[m68307TIMER_TMR], 4))
107 m68k->timer0_interrupt(1);
108
109 tptr->mametimer->adjust(m68k->cycles_to_attotime(20000));
110 }
111
TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::timer1_callback)112 TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::timer1_callback )
113 {
114 m68307_cpu_device* m68k = (m68307_cpu_device *)ptr;
115 single_timer* tptr = &m68k->m_m68307TIMER->singletimer[1];
116 tptr->regs[m68307TIMER_TER] |= 0x2;
117
118 if (BIT(tptr->regs[m68307TIMER_TMR], 4))
119 m68k->timer1_interrupt(1);
120
121 tptr->mametimer->adjust(m68k->cycles_to_attotime(20000));
122
123 }
124
TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::wd_timer_callback)125 TIMER_CALLBACK_MEMBER(m68307_cpu_device::m68307_timer::wd_timer_callback )
126 {
127 printf("wd timer\n");
128 }
129
init(m68307_cpu_device * device)130 void m68307_cpu_device::m68307_timer::init(m68307_cpu_device *device)
131 {
132 parent = device;
133
134 single_timer* tptr;
135
136 tptr = &singletimer[0];
137 tptr->mametimer = device->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68307_timer::timer0_callback),this), parent);
138
139 tptr = &singletimer[1];
140 tptr->mametimer = device->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68307_timer::timer1_callback),this), parent);
141
142 wd_mametimer = device->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68307_timer::wd_timer_callback),this), parent);
143 }
144
read_tcn(uint16_t mem_mask,int which)145 uint16_t m68307_cpu_device::m68307_timer::read_tcn(uint16_t mem_mask, int which)
146 {
147 // we should return the current timer value by
148 // calculating what it should be based on the time
149 // since it was last set
150 return 0x3a98;
151 }
152
write_ter(uint16_t data,uint16_t mem_mask,int which)153 void m68307_cpu_device::m68307_timer::write_ter(uint16_t data, uint16_t mem_mask, int which)
154 {
155 assert(which >= 0 && which < ARRAY_LENGTH(singletimer));
156 single_timer* tptr = &singletimer[which];
157 if (data & 0x2)
158 {
159 tptr->regs[m68307TIMER_TER] &= ~0x2;
160 if (which)
161 parent->timer1_interrupt(0);
162 else
163 parent->timer0_interrupt(0);
164 }
165 }
166
write_tmr(uint16_t data,uint16_t mem_mask,int which)167 void m68307_cpu_device::m68307_timer::write_tmr(uint16_t data, uint16_t mem_mask, int which)
168 {
169 m68307_cpu_device* m68k = parent;
170 assert(which >= 0 && which < ARRAY_LENGTH(singletimer));
171 single_timer* tptr = &singletimer[which];
172
173 COMBINE_DATA(&tptr->regs[m68307TIMER_TMR]);
174
175 data = tptr->regs[m68307TIMER_TMR];
176
177 int ps = data & (0xff00)>>8;
178 int ce = data & (0x00c0)>>6;
179 int om = data & (0x0020)>>5;
180 int ori = data & (0x0010)>>4;
181 int frr = data & (0x0008)>>3;
182 int iclk = data & (0x0006)>>1;
183 int rst = data & (0x0001)>>0;
184
185
186 m68k->logerror("tmr value %04x : Details :\n", data);
187 m68k->logerror("prescale %d\n", ps);
188 m68k->logerror("(clock divided by %d)\n", ps+1);
189 m68k->logerror("capture edge / enable interrupt %d\n", ce);
190 if (ce==0x0) m68k->logerror("(disable interrupt on capture event)\n");
191 if (ce==0x1) m68k->logerror("(capture on rising edge only + enable capture interrupt)\n");
192 if (ce==0x2) m68k->logerror("(capture on falling edge only + enable capture interrupt)\n");
193 if (ce==0x3) m68k->logerror("(capture on any edge + enable capture interrupt)\n");
194 m68k->logerror("output mode %d\n", om);
195 if (om==0x0) m68k->logerror("(active-low pulse for one cycle))\n");
196 if (om==0x1) m68k->logerror("(toggle output)\n");
197 m68k->logerror("output reference interrupt %d\n", ori);
198 if (ori==0x0) m68k->logerror("(disable reference interrupt)\n");
199 if (ori==0x1) m68k->logerror("(enable interrupt on reaching reference value))\n");
200 m68k->logerror("free running %d\n", frr);
201 if (frr==0x0) m68k->logerror("(free running mode, counter continues after value reached)\n");
202 if (frr==0x1) m68k->logerror("(restart mode, counter resets after value reached)\n");
203 m68k->logerror("interrupt clock source %d\n", iclk);
204 if (iclk==0x0) m68k->logerror("(stop count)\n");
205 if (iclk==0x1) m68k->logerror("(master system clock)\n");
206 if (iclk==0x2) m68k->logerror("(master system clock divided by 16)\n");
207 if (iclk==0x3) m68k->logerror("(TIN Pin)\n");
208 m68k->logerror("reset %d\n", rst);
209 if (rst==0x0) m68k->logerror("(timer is reset)\n");
210 if (rst==0x1) m68k->logerror("(timer is running)\n");
211
212 tptr->mametimer->adjust(m68k->cycles_to_attotime(100000));
213
214 m68k->logerror("\n");
215 }
216
write_trr(uint16_t data,uint16_t mem_mask,int which)217 void m68307_cpu_device::m68307_timer::write_trr(uint16_t data, uint16_t mem_mask, int which)
218 {
219 assert(which >= 0 && which < ARRAY_LENGTH(singletimer));
220 single_timer* tptr = &singletimer[which];
221
222 COMBINE_DATA(&tptr->regs[m68307TIMER_TRR]);
223 }
224
225
226
reset()227 void m68307_cpu_device::m68307_timer::reset()
228 {
229 for (auto & elem : singletimer)
230 {
231 single_timer* tptr = &elem;
232
233 tptr->regs[m68307TIMER_TMR] = 0x0000;
234 tptr->regs[m68307TIMER_TRR] = 0xffff;
235 tptr->regs[m68307TIMER_TCR] = 0x0000;
236 tptr->regs[m68307TIMER_TCN] = 0x0000;
237 tptr->regs[m68307TIMER_TER] = 0x0000;
238 tptr->regs[m68307TIMER_WRR] = 0xffff;
239 tptr->regs[m68307TIMER_WCR] = 0xffff;
240 tptr->regs[m68307TIMER_XXX] = 0;
241 tptr->enabled = false;
242 tptr->mametimer->adjust(attotime::never);
243 }
244
245 wd_mametimer->adjust(attotime::never);
246 }
247
248
timer_int_pending(int which) const249 bool m68307_cpu_device::m68307_timer::timer_int_pending(int which) const
250 {
251 assert(which >= 0 && which < ARRAY_LENGTH(singletimer));
252 const single_timer* tptr = &singletimer[which];
253
254 return BIT(tptr->regs[m68307TIMER_TER], 1) && BIT(tptr->regs[m68307TIMER_TMR], 4);
255 }
256