version 0.5.2
[fw/sdcc] / sim / ucsim / s51.src / uc51r.cc
1 /*
2  * Simulator of microcontrollers (uc51r.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
32 // local
33 #include "uc51rcl.h"
34 #include "regs51.h"
35 #include "types51.h"
36 #include "wdtcl.h"
37
38
39 /*
40  * Making an 8051r CPU object
41  */
42
43 cl_uc51r::cl_uc51r(int Itype, int Itech, class cl_sim *asim):
44   cl_uc52(Itype, Itech, asim)
45 {
46   /*  int i;
47   for (i= 0; i < ERAM_SIZE; i++)
48   ERAM[i]= 0;*/
49   clock_out= 0;
50 }
51
52
53 void
54 cl_uc51r::mk_hw_elements(void)
55 {
56   class cl_hw *h;
57
58   cl_uc52::mk_hw_elements();
59   hws->add(h= new cl_wdt(this, 0x3fff));
60   h->init();
61   hws->add(h= new cl_uc51r_dummy_hw(this));
62   h->init();
63 }
64
65
66 void
67 cl_uc51r::make_memories(void)
68 {
69   class cl_address_space *as;
70
71   rom= as= new cl_address_space("rom", 0, 0x10000, 8);
72   as->init();
73   address_spaces->add(as);
74   iram= as= new cl_address_space("iram", 0, 0x100, 8);
75   as->init();
76   address_spaces->add(as);
77   sfr= as= new cl_address_space("sfr", 0x80, 0x80, 8);
78   as->init();
79   address_spaces->add(as);
80   xram= as= new cl_address_space("xram", 0, 0x10000, 8);
81   as->init();
82   address_spaces->add(as);
83
84   class cl_address_decoder *ad;
85   class cl_memory_chip *chip;
86
87   chip= new cl_memory_chip("rom_chip", 0x10000, 8);
88   chip->init();
89   memchips->add(chip);
90   ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
91   ad->init();
92   as->decoders->add(ad);
93   ad->activate(0);
94
95   chip= new cl_memory_chip("iram_chip", 0x100, 8);
96   chip->init();
97   memchips->add(chip);
98   ad= new cl_address_decoder(as= address_space("iram"), chip, 0, 0xff, 0);
99   ad->init();
100   as->decoders->add(ad);
101   ad->activate(0);
102
103   chip= new cl_memory_chip("xram_chip", 0x10000, 8);
104   chip->init();
105   memchips->add(chip);
106   ad= new cl_address_decoder(as= address_space("xram"), chip, 0, 0xffff, 0);
107   ad->init();
108   as->decoders->add(ad);
109   ad->activate(0);
110   chip= new cl_memory_chip("eram_chip", 0x100, 8);
111   chip->init();
112   memchips->add(chip);
113
114   chip= new cl_memory_chip("sfr_chip", 0x80, 8);
115   chip->init();
116   memchips->add(chip);
117   ad= new cl_address_decoder(as= address_space("sfr"), chip, 0x80, 0xff, 0);
118   ad->init();
119   as->decoders->add(ad);
120   ad->activate(0);
121
122   acc= sfr->get_cell(ACC);
123   psw= sfr->get_cell(PSW);
124 }
125
126
127 /*
128  * Resetting of the microcontroller
129  *
130  * Original method is extended with handling of WDT.
131  */
132
133 void
134 cl_uc51r::reset(void)
135 {
136   cl_uc52::reset();
137   sfr->write(SADDR, 0);
138   sfr->write(SADEN, 0);
139   sfr->write(AUXR, 0);
140 }
141
142 void
143 cl_uc51r::clear_sfr(void)
144 {
145   cl_uc52::clear_sfr();
146   sfr->write(SADDR, 0);
147   sfr->write(SADEN, 0);
148   sfr->write(AUXR, 0);
149   sfr->write(IPH, 0);
150 }
151
152
153 void
154 cl_uc51r::received(int c)
155 {
156   t_mem br= sfr->get(SADDR) | sfr->get(SADEN);
157   int scon= sfr->get(SCON);
158
159   if ((0 < scon >> 6) &&
160       (scon & bmSM2))
161     {
162       if (/* Check for individual address */
163           ((sfr->get(SADDR) & sfr->get(SADEN)) == (c & sfr->get(SADEN)))
164           ||
165           /* Check for broadcast address */
166           (br == (br & c)))
167         sfr->set_bit1(SCON, bmRI);
168       return;
169     }
170   sfr->set_bit1(SCON, bmRI);
171 }
172
173
174 /*
175  */
176
177 cl_uc51r_dummy_hw::cl_uc51r_dummy_hw(class cl_uc *auc):
178   cl_hw(auc, HW_DUMMY, 0, "_51r_dummy")
179 {}
180
181 int
182 cl_uc51r_dummy_hw::init(void)
183 {
184   class cl_address_space *sfr= uc->address_space(MEM_SFR_ID);
185   if (!sfr)
186     {
187       fprintf(stderr, "No SFR to register %s[%d] into\n", id_string, id);
188     }
189   //use_cell(sfr, PSW, &cell_psw, wtd_restore);
190   register_cell(sfr, AUXR, &cell_auxr, wtd_restore);
191   return(0);
192 }
193
194 void
195 cl_uc51r_dummy_hw::write(class cl_memory_cell *cell, t_mem *val)
196 {
197   if (cell == cell_auxr)
198     {
199       class cl_address_space *xram= uc->address_space(MEM_XRAM_ID);
200       class cl_memory_chip *eram=
201         dynamic_cast<class cl_memory_chip *>(uc->memory("eram_chip"));
202       class cl_address_decoder *d;
203       if (eram &&
204           xram)
205         {
206           if (*val & bmEXTRAM)
207             d= new cl_address_decoder(xram, uc->memory("xram_chip"), 0,0xff,0);
208           else
209             d= new cl_address_decoder(xram, eram, 0, 0xff, 0);
210           d->init();
211           xram->decoders->add(d);
212           d->activate(0);
213         }
214     }
215   /*else if (cell == cell_pcon)
216     {
217       printf("PCON write 0x%x (PC=0x%x)\n", *val, uc->PC);
218       uc->sim->stop(0);
219       }*/
220 }
221
222 /*void
223 cl_uc51r_dummy_hw::happen(class cl_hw *where, enum hw_event he, void *params)
224 {
225   struct ev_port_changed *ep= (struct ev_port_changed *)params;
226
227   if (where->cathegory == HW_PORT &&
228       he == EV_PORT_CHANGED &&
229       ep->id == 3)
230     {
231       t_mem p3o= ep->pins & ep->prev_value;
232       t_mem p3n= ep->new_pins & ep->new_value;
233       if ((p3o & bm_INT0) &&
234           !(p3n & bm_INT0))
235         uc51->p3_int0_edge++;
236       if ((p3o & bm_INT1) &&
237           !(p3n & bm_INT1))
238         uc51->p3_int1_edge++;
239     }
240 }*/
241
242
243 /* End of s51.src/uc51r.cc */