d8bae3600d8dbeb75bb268dc672f5df1f070d696
[fw/sdcc] / sim / ucsim / s51.src / uc390hw.cc
1 /*
2  * Simulator of microcontrollers (serial.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  *
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 // local
34 #include "uc390hwcl.h"
35 #include "regs51.h"
36 #include "uc51cl.h"
37
38
39 cl_uc390_hw::cl_uc390_hw (class cl_uc *auc):
40   cl_hw (auc, HW_DUMMY, 0, "ds390hw")
41 {
42   uc390 = (class t_uc390 *) uc;
43 }
44
45 int
46 cl_uc390_hw::init(void)
47 {
48   class cl_mem *sfr;
49
50   sfr = uc->mem (MEM_SFR);
51   if (sfr)
52     {
53       /*cell_dps   = sfr->register_hw (DPS  , this, 0);
54       cell_p4cnt = sfr->register_hw (P4CNT, this, 0);
55       cell_exif  = sfr->register_hw (EXIF , this, 0);
56       cell_acon  = sfr->register_hw (ACON , this, 0);
57       cell_p5cnt = sfr->register_hw (P5CNT, this, 0);
58       cell_c0c   = sfr->register_hw (C0C  , this, 0);
59       cell_pmr   = sfr->register_hw (PMR  , this, 0);
60       cell_mcon  = sfr->register_hw (MCON , this, 0);
61       cell_ta    = sfr->register_hw (TA   , this, 0);
62       cell_cor   = sfr->register_hw (COR  , this, 0);
63       cell_mcnt0 = sfr->register_hw (MCNT0, this, 0);
64       cell_mcnt1 = sfr->register_hw (MCNT1, this, 0);
65       cell_ma    = sfr->register_hw (MA   , this, 0);
66       cell_mb    = sfr->register_hw (MB   , this, 0);
67       cell_mc    = sfr->register_hw (MC   , this, 0);
68       cell_wdcon = sfr->register_hw (WDCON, this, 0);
69       cell_c1c   = sfr->register_hw (C1C  , this, 0);*/
70       register_cell (sfr, DPS  , &cell_dps  , wtd_restore);
71       register_cell (sfr, P4CNT, &cell_p4cnt, wtd_restore);
72       register_cell (sfr, EXIF , &cell_exif , wtd_restore);
73       register_cell (sfr, ACON , &cell_acon , wtd_restore);
74       register_cell (sfr, P5CNT, &cell_p5cnt, wtd_restore);
75       register_cell (sfr, C0C  , &cell_c0c  , wtd_restore);
76       register_cell (sfr, PMR  , &cell_pmr  , wtd_restore);
77       register_cell (sfr, MCON , &cell_mcon , wtd_restore);
78       register_cell (sfr, TA   , &cell_ta   , wtd_restore);
79       register_cell (sfr, COR  , &cell_cor  , wtd_restore);
80       register_cell (sfr, MCNT0, &cell_mcnt0, wtd_restore);
81       register_cell (sfr, MCNT1, &cell_mcnt1, wtd_restore);
82       register_cell (sfr, MA   , &cell_ma   , wtd_restore);
83       register_cell (sfr, MB   , &cell_mb   , wtd_restore);
84       register_cell (sfr, MC   , &cell_mc   , wtd_restore);
85       register_cell (sfr, WDCON, &cell_wdcon, wtd_restore);
86       register_cell (sfr, C1C  , &cell_c1c  , wtd_restore);
87     }
88   return 0;
89 }
90
91 t_mem
92 cl_uc390_hw::read (class cl_cell *cell)
93 {
94   if (cell == cell_exif)
95     {
96       if (ctm_ticks &&
97           uc390->ticks->ticks >= ctm_ticks + 65535)
98         {
99           ctm_ticks = 0;
100           cell->set (cell->get() | 0x08); /* set CKRDY */
101         }
102     }
103   return cell->get();
104 }
105
106 void
107 cl_uc390_hw::write (class cl_cell *cell, t_mem *val)
108 {
109   if (cell == cell_dps)
110     *val = (*val & 0xe5) | 0x04;
111   else if (cell == cell_exif)
112     {
113       /* Bit 0 (BGS) is TA-protected */
114       if (timed_access_state != 2 ||
115           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
116         *val = (*val & ~0x01) | (cell_exif->get() & 0x01);
117
118       /* CKRDY and RGMD are read-only */
119       *val = (*val & 0x0c) | (*val & ~0x0c);
120     }
121   else if (cell == cell_p4cnt)
122     {
123       /* P4CNT is TA-protected */
124       if (timed_access_state != 2 ||
125           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
126         *val = cell_p4cnt->get();
127       *val |= 0x80; /* always 1 */
128     }
129   else if (cell == cell_acon)
130     {
131       /* ACON is TA-protected */
132       if (timed_access_state != 2 ||
133           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
134         *val = cell_acon->get();
135       else
136         {
137
138           /* lockout: IDM1:IDM0 and SA can't be set at the same time */
139             if ((cell_mcon->get() & 0xc0) == 0xc0) /* IDM1 and IDM0 set? */
140               *val &= ~0x04; /* lockout SA */
141         }
142       *val |= 0xf8; /* always 1 */
143     }
144   else if (cell == cell_p5cnt)
145     {
146       /* Bits 0...2 are TA-protected */
147       if (timed_access_state != 2 ||
148           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
149         *val = (*val & ~0x07) | (cell_p5cnt->get() & 0x07);
150     }
151   else if (cell == cell_c0c)
152     {
153       /* Bit 3 (CRST) is TA-protected */
154       if (timed_access_state != 2 ||
155           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
156         *val = (*val & ~0x08) | (cell_c0c->get() & 0x08);
157     }
158   else if (cell == cell_pmr)
159     {
160       /* fixme: check previous state */
161       if ((*val & 0xd0) == 0x90) /* CD1:CD0 set to 10, CTM set */
162         {
163           ctm_ticks = uc390->ticks->ticks;
164           cell_exif->set (cell_exif->get() & ~0x08); /* clear CKRDY */
165         }
166       else
167         ctm_ticks = 0;
168       *val |= 0x03; /* always 1 */
169     }
170   else if (cell == cell_mcon)
171     {
172       /* MCON is TA-protected */
173       if (timed_access_state != 2 ||
174           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
175         *val = cell_mcon->get();
176       else
177         /* lockout: IDM1:IDM0 and SA can't be set at the same time */
178         if ((cell_acon->get() & 0x04) == 0x04) /* SA set? */
179           *val &= ~0xc0; /* lockout IDM1:IDM0 */
180       *val |= 0x10; /* always 1 */
181     }
182   else if (cell == cell_ta)
183     {
184       if (*val == 0xAA)
185         {
186           timed_access_state = 1;
187           timed_access_ticks = uc390->ticks->ticks;
188         }
189       else if (*val == 0x55 &&
190                timed_access_state == 1 &&
191                timed_access_ticks + 2*12 >= uc390->ticks->ticks) // fixme: 3 cycles
192         {
193           timed_access_state = 2;
194           timed_access_ticks = uc390->ticks->ticks;
195         }
196       else
197         timed_access_state = 0;
198     }
199   else if (cell == cell_cor)
200     {
201       /* COR is TA-protected */
202       if (timed_access_state != 2 ||
203           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
204         *val = cell_cor->get();
205     }
206   else if (cell == cell_mcnt0)
207     {
208       ;
209     }
210   else if (cell == cell_mcnt1)
211     {
212       *val |= 0x0f; /* always 1 */
213     }
214   else if (cell == cell_ma)
215     {
216       ;
217     }
218   else if (cell == cell_mb)
219     {
220       ;
221     }
222   else if (cell == cell_mc)
223     {
224       ;
225     }
226   else if (cell == cell_wdcon)
227     {
228       /* Bits 0, 1, 3 and 6 are TA-protected */
229       if (timed_access_state != 2 ||
230           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
231         *val = (*val & ~0x4b) | (cell_wdcon->get() & 0x4b);
232     }
233   else if (cell == cell_c1c)
234     {
235       /* Bit 3 (CRST) is TA-protected */
236       if (timed_access_state != 2 ||
237           timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles
238         *val = (*val & ~0x08) | (cell_c1c->get() & 0x08);
239     }
240 }
241
242 /*void
243 cl_uc390_hw::mem_cell_changed (class cl_mem *mem, t_addr addr)
244 {
245   class cl_mem *sfr = uc->mem (MEM_SFR);
246
247   if (mem && sfr && mem == sfr)
248     switch (addr)
249       {
250         case DPS:   cell_dps   = sfr->get_cell (DPS);   break;
251         case P4CNT: cell_p4cnt = sfr->get_cell (P4CNT); break;
252         case EXIF:  cell_exif  = sfr->get_cell (EXIF);  break;
253         case ACON:  cell_acon  = sfr->get_cell (ACON);  break;
254         case P5CNT: cell_p5cnt = sfr->get_cell (P5CNT); break;
255         case C0C:   cell_c0c   = sfr->get_cell (C0C);   break;
256         case PMR:   cell_pmr   = sfr->get_cell (PMR);   break;
257         case MCON:  cell_mcon  = sfr->get_cell (MCON);  break;
258         case TA:    cell_ta    = sfr->get_cell (TA);    break;
259         case COR:   cell_cor   = sfr->get_cell (COR);   break;
260         case MCNT0: cell_mcnt0 = sfr->get_cell (MCNT0); break;
261         case MCNT1: cell_mcnt1 = sfr->get_cell (MCNT1); break;
262         case MA:    cell_ma    = sfr->get_cell (MA);    break;
263         case MB:    cell_mb    = sfr->get_cell (MB);    break;
264         case MC:    cell_mc    = sfr->get_cell (MC);    break;
265         case WDCON: cell_wdcon = sfr->get_cell (WDCON); break;
266         case C1C:   cell_c1c   = sfr->get_cell (C1C);   break;
267       }
268 }*/
269
270 void
271 cl_uc390_hw::reset(void)
272 {
273   ctm_ticks = 0;
274   timed_access_state = 0;
275 }
276
277 void
278 cl_uc390_hw::print_info(class cl_console *con)
279 {
280   int i;
281   long l;
282
283   i = uc->get_mem (MEM_SFR, EXIF);
284   con->dd_printf ("%s"
285                   " EXIF 0x%02x: IE5 %c IE4 %c IE3 %c IE2 %c CKRDY %c RGMD %c RGSL %c BGS %c\n",
286                   id_string,
287                   i,
288                   (i & 0x80) ? '1' : '0',
289                   (i & 0x40) ? '1' : '0',
290                   (i & 0x20) ? '1' : '0',
291                   (i & 0x10) ? '1' : '0',
292                   (i & 0x08) ? '1' : '0',
293                   (i & 0x04) ? '1' : '0',
294                   (i & 0x02) ? '1' : '0',
295                   (i & 0x01) ? '1' : '0');
296   i = uc->get_mem (MEM_SFR, DPS);
297   con->dd_printf ("\tDPS  0x%02x: ID1 %c ID0 %c TSL %c SEL %c\n",
298                   i,
299                   (i & 0x80) ? '1' : '0',
300                   (i & 0x40) ? '1' : '0',
301                   (i & 0x20) ? '1' : '0',
302                   (i & 0x01) ? '1' : '0');
303   l = uc->get_mem (MEM_SFR, DPX) * 256*256 +
304       uc->get_mem (MEM_SFR, DPH) * 256 +
305       uc->get_mem (MEM_SFR, DPL);
306   con->dd_printf ("\tDPTR  0x%06x\n", l);
307   l = uc->get_mem (MEM_SFR, DPX1) * 256*256 +
308       uc->get_mem (MEM_SFR, DPH1) * 256 +
309       uc->get_mem (MEM_SFR, DPL1);
310   con->dd_printf ("\tDPTR1 0x%06x\n", l);
311 }
312
313 /* End of s51.src/uc390hw.cc */