1 /*
2 * Simulator of microcontrollers (cmd.src/cmdmem.cc)
3 *
4 * Copyright (C) 2001,01 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 // prj
29 #include "globals.h"
30 #include "utils.h"
31
32 // sim
33 #include "simcl.h"
34
35 // local
36 #include "cmd_memcl.h"
37
38
39 void
set_memory_help(class cl_cmd * cmd)40 set_memory_help(class cl_cmd *cmd)
41 {
42 cmd->set_help("memory subcommand",
43 "Manage memory chips and address spaces",
44 "Long of memory");
45 }
46
47 void
set_memory_create_help(class cl_cmd * cmd)48 set_memory_create_help(class cl_cmd *cmd)
49 {
50 cmd->set_help("memory create subcommand",
51 "Set of commands to create memory objects",
52 "Long of memory create");
53 }
54
55 /*
56 * Command: memory create chip
57 *----------------------------------------------------------------------------
58 */
59
60 //int
61 //cl_conf_addmem_cmd::do_work(class cl_sim *sim,
62 // class cl_cmdline *cmdline, class cl_console *con)
COMMAND_DO_WORK_UC(cl_memory_create_chip_cmd)63 COMMAND_DO_WORK_UC(cl_memory_create_chip_cmd)
64 {
65 class cl_cmd_arg *params[4]= { cmdline->param(0),
66 cmdline->param(1),
67 cmdline->param(2),
68 cmdline->param(3) };
69 char *memid= NULL;
70 int size= -1;
71 int width= 8;
72
73 if (cmdline->syntax_match(uc, STRING NUMBER)) {
74 memid= params[0]->value.string.string;
75 size= params[1]->value.number;
76 }
77 else if (cmdline->syntax_match(uc, STRING NUMBER NUMBER)) {
78 memid= params[0]->value.string.string;
79 size= params[1]->value.number;
80 width= params[2]->value.number;
81 }
82 else
83 syntax_error(con);
84
85 if (!memid ||
86 !*memid)
87 con->dd_printf("Wrong id\n");
88 else if ((size < 1) ||
89 (size > max_mem_size))
90 con->dd_printf("Wrong size\n");
91 else if ((width < 1) ||
92 (width > 32))
93 con->dd_printf("Wrong width\n");
94 else
95 {
96 class cl_memory *mem= new cl_memory_chip(memid, size, width);
97 mem->init();
98 uc->memchips->add(mem);
99 mem->set_uc(uc);
100 }
101 return(false);
102 }
103
104 CMDHELP(cl_memory_create_chip_cmd,
105 "memory create chip id size cellsize",
106 "Create a new memory chip",
107 "long help of memory create chip")
108
109 /*
110 * Command: memory create addressspace
111 *----------------------------------------------------------------------------
112 */
113
114 //int
115 //cl_conf_addmem_cmd::do_work(class cl_sim *sim,
116 // class cl_cmdline *cmdline, class cl_console *con)
COMMAND_DO_WORK_UC(cl_memory_create_addressspace_cmd)117 COMMAND_DO_WORK_UC(cl_memory_create_addressspace_cmd)
118 {
119 class cl_cmd_arg *params[4]= { cmdline->param(0),
120 cmdline->param(1),
121 cmdline->param(2),
122 cmdline->param(3) };
123 char *memid= NULL;
124 int start= 0, size= -1, width= 8;
125
126 if (cmdline->syntax_match(uc, STRING NUMBER)) {
127 memid= params[0]->value.string.string;
128 size= params[1]->value.number;
129 }
130 else if (cmdline->syntax_match(uc, STRING NUMBER NUMBER)) {
131 memid= params[0]->value.string.string;
132 start= params[1]->value.number;
133 size= params[2]->value.number;
134 }
135 else if (cmdline->syntax_match(uc, STRING NUMBER NUMBER NUMBER)) {
136 memid= params[0]->value.string.string;
137 start= params[1]->value.number;
138 size= params[2]->value.number;
139 width= params[3]->value.number;
140 }
141 else
142 syntax_error(con);
143
144 if (!memid ||
145 !*memid)
146 con->dd_printf("Wrong id\n");
147 else if ((size < 1) ||
148 (size > max_mem_size))
149 con->dd_printf("Wrong size\n");
150 else if ((width < 1) ||
151 (width > 32))
152 con->dd_printf("Wrong width\n");
153 else
154 {
155 class cl_address_space *mem=
156 new cl_address_space(memid, start, size, width);
157 mem->init();
158 uc->address_spaces->add(mem);
159 mem->set_uc(uc);
160 }
161 return(false);
162 }
163
164 CMDHELP(cl_memory_create_addressspace_cmd,
165 "memory create addressspace id startaddr size",
166 "Create a new address space",
167 "long help of memory create addressspace")
168
169 /*
170 * Command: memory create addressdecoder
171 *----------------------------------------------------------------------------
172 */
173
174 //int
175 //cl_conf_addmem_cmd::do_work(class cl_sim *sim,
176 // class cl_cmdline *cmdline, class cl_console *con)
COMMAND_DO_WORK_UC(cl_memory_create_addressdecoder_cmd)177 COMMAND_DO_WORK_UC(cl_memory_create_addressdecoder_cmd)
178 {
179 class cl_cmd_arg *params[5]= { cmdline->param(0),
180 cmdline->param(1),
181 cmdline->param(2),
182 cmdline->param(3),
183 cmdline->param(4) };
184 class cl_memory *as= 0, *chip= 0;
185 t_addr as_begin= 0, as_end= 0, chip_begin= 0;
186
187 if (cmdline->syntax_match(uc, MEMORY MEMORY)) {
188 as= params[0]->value.memory.memory;
189 as_end= as->highest_valid_address();
190 chip= params[1]->value.memory.memory;
191 }
192 else if (cmdline->syntax_match(uc, MEMORY MEMORY NUMBER)) {
193 as= params[0]->value.memory.memory;
194 as_end= as->highest_valid_address();
195 chip= params[1]->value.memory.memory;
196 chip_begin= params[2]->value.number;
197 }
198 else if (cmdline->syntax_match(uc, MEMORY NUMBER MEMORY)) {
199 as= params[0]->value.memory.memory;
200 as_begin= params[1]->value.number;
201 as_end= as->highest_valid_address();
202 chip= params[2]->value.memory.memory;
203 }
204 else if (cmdline->syntax_match(uc, MEMORY NUMBER MEMORY NUMBER)) {
205 as= params[0]->value.memory.memory;
206 as_begin= params[1]->value.number;
207 as_end= as->highest_valid_address();
208 chip= params[2]->value.memory.memory;
209 chip_begin= params[3]->value.number;
210 }
211 else if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY)) {
212 as= params[0]->value.memory.memory;
213 as_begin= params[1]->value.number;
214 as_end= params[2]->value.number;
215 chip= params[3]->value.memory.memory;
216 }
217 else if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY NUMBER)) {
218 as= params[0]->value.memory.memory;
219 as_begin= params[1]->value.number;
220 as_end= params[2]->value.number;
221 chip= params[3]->value.memory.memory;
222 chip_begin= params[4]->value.number;
223 }
224 else
225 syntax_error(con);
226
227 if (!as->is_address_space())
228 con->dd_printf("%s is not an address space\n", as->get_name("unknown"));
229 else if (!chip->is_chip())
230 con->dd_printf("%s is not a memory chip\n", chip->get_name("unknown"));
231 else if (as_begin > as_end)
232 con->dd_printf("Wrong address area specification\n");
233 else if (chip_begin >= chip->get_size())
234 con->dd_printf("Wrong chip area specification\n");
235 else if (as_begin < as->start_address ||
236 as_end > as->highest_valid_address())
237 con->dd_printf("Specified area is out of address space\n");
238 else if (as_end-as_begin > chip->get_size()-chip_begin)
239 con->dd_printf("Specified area is out of chip size\n");
240 else
241 {
242 class cl_address_decoder *d=
243 new cl_address_decoder(as, chip, as_begin, as_end, chip_begin);
244 d->init();
245 ((class cl_address_space *)as)->decoders->add(d);
246 d->activate(con);
247 }
248 return(false);
249 }
250
251 CMDHELP(cl_memory_create_addressdecoder_cmd,
252 "memory create addressdecoder addressspace begin end chip begin",
253 "Create a new address decoder",
254 "long help of memory create addressdecoder")
255
256 /*
257 * Command: memory create banker
258 *----------------------------------------------------------------------------
259 */
260
COMMAND_DO_WORK_UC(cl_memory_create_banker_cmd)261 COMMAND_DO_WORK_UC(cl_memory_create_banker_cmd)
262 {
263 class cl_cmd_arg *params[6]= { cmdline->param(0),
264 cmdline->param(1),
265 cmdline->param(2),
266 cmdline->param(3),
267 cmdline->param(4),
268 cmdline->param(5) };
269 class cl_memory *banker_as= 0, *banked_as= 0;
270 t_addr addr= 0, asb= 0, ase= 0;
271 t_mem mask= 0;
272
273 if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY NUMBER NUMBER)) {
274 banker_as= params[0]->value.memory.memory;
275 addr= params[1]->value.number;
276 mask= params[2]->value.number;
277 banked_as= params[3]->value.memory.memory;
278 asb= params[4]->value.number;
279 ase= params[5]->value.number;
280 }
281 else
282 return syntax_error(con), false;
283
284 if (!banker_as->is_address_space())
285 con->dd_printf("%s is not an address space\n", banker_as->get_name("unknown"));
286 else if (!banked_as->is_address_space())
287 con->dd_printf("%s is not an address space\n", banked_as->get_name("unknown"));
288 else if (addr < banker_as->start_address ||
289 addr > banker_as->highest_valid_address())
290 con->dd_printf("Specified banker address is out of address space\n");
291 else if (asb < banked_as->start_address ||
292 asb > banked_as->highest_valid_address())
293 con->dd_printf("Specified banked start address is out of address space\n");
294 else if (ase < banked_as->start_address ||
295 ase > banked_as->highest_valid_address())
296 con->dd_printf("Specified banked end address is out of address space\n");
297 else
298 {
299 class cl_banker *d=
300 new cl_banker((class cl_address_space *)banker_as, addr, mask, //0,
301 (class cl_address_space *)banked_as, asb, ase);
302 d->init();
303 ((class cl_address_space *)banked_as)->decoders->add(d);
304 ((class cl_address_space *)banked_as)->undecode_area(d, asb, ase, con);
305 d->activate(con);
306 }
307 return(false);
308 }
309
310 CMDHELP(cl_memory_create_banker_cmd,
311 "memory create banker switcher_addressspace switcher_address switcher_mask banked_addressspace start end",
312 "Create a new bank switcher",
313 "long help of memory create banker")
314
315 /*
316 * Command: memory create bander
317 *----------------------------------------------------------------------------
318 */
319
COMMAND_DO_WORK_UC(cl_memory_create_bander_cmd)320 COMMAND_DO_WORK_UC(cl_memory_create_bander_cmd)
321 {
322 class cl_cmd_arg *params[7]= { cmdline->param(0),
323 cmdline->param(1),
324 cmdline->param(2),
325 cmdline->param(3),
326 cmdline->param(4),
327 cmdline->param(5),
328 cmdline->param(6) };
329 class cl_memory *as= 0;
330 t_addr asb= 0, ase= 0;
331 class cl_memory *chip= 0;
332 t_addr cb= 0;
333 int bpc= 0, dist= 1;
334
335 if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY NUMBER NUMBER NUMBER))
336 {
337 as= params[0]->value.memory.memory;
338 asb= params[1]->value.number;
339 ase= params[2]->value.number;
340 chip= params[3]->value.memory.memory;
341 cb= params[4]->value.number;
342 bpc= params[5]->value.number;
343 dist= params[6]->value.number;
344 }
345 else if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY NUMBER NUMBER))
346 {
347 as= params[0]->value.memory.memory;
348 asb= params[1]->value.number;
349 ase= params[2]->value.number;
350 chip= params[3]->value.memory.memory;
351 cb= params[4]->value.number;
352 bpc= params[5]->value.number;
353 }
354 else
355 return syntax_error(con), false;
356
357 if (!as->is_address_space())
358 con->dd_printf("%s is not an address space\n", as->get_name("unknown"));
359 else if (!chip->is_chip())
360 con->dd_printf("%s is not a chip\n", chip->get_name("unknown"));
361 else if (asb < as->start_address ||
362 asb > as->highest_valid_address())
363 con->dd_printf("Specified begin address is out of address space\n");
364 else if (ase < as->start_address ||
365 ase > as->highest_valid_address())
366 con->dd_printf("Specified end address is out of address space\n");
367 else if (cb < chip->start_address ||
368 cb > chip->highest_valid_address())
369 con->dd_printf("Specified chip address is out of size\n");
370 else
371 {
372 class cl_bander *b=
373 new cl_bander((class cl_address_space *)as, asb, ase,
374 (class cl_memory_chip *)chip, cb,
375 bpc, dist);
376 b->init();
377 ((class cl_address_space *)as)->decoders->add(b);
378 b->activate(con);
379 }
380 return(false);
381 }
382
383 CMDHELP(cl_memory_create_bander_cmd,
384 "memory create bander addressspace begin end chip begin bits_per_chip [distance]",
385 "Create a new bit bander",
386 "long help of memory create bander")
387
388 /*
389 * Command: memory create bank
390 *----------------------------------------------------------------------------
391 */
392
COMMAND_DO_WORK_UC(cl_memory_create_bank_cmd)393 COMMAND_DO_WORK_UC(cl_memory_create_bank_cmd)
394 {
395 class cl_cmd_arg *params[5]= { cmdline->param(0),
396 cmdline->param(1),
397 cmdline->param(2),
398 cmdline->param(3),
399 cmdline->param(4) };
400 class cl_memory *as= 0, *chip= 0;
401 t_addr as_begin= 0, chip_begin= 0;
402 int bank= -1;
403
404 if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY NUMBER)) {
405 as= params[0]->value.memory.memory;
406 as_begin= params[1]->value.number;
407 bank= params[2]->value.number;
408 chip= params[3]->value.memory.memory;
409 chip_begin= params[4]->value.number;
410 }
411 else if (cmdline->syntax_match(uc, MEMORY NUMBER NUMBER MEMORY)) {
412 as= params[0]->value.memory.memory;
413 as_begin= params[1]->value.number;
414 bank= params[2]->value.number;
415 chip= params[3]->value.memory.memory;
416 }
417 else
418 return syntax_error(con), false;
419
420 if (!as->is_address_space())
421 con->dd_printf("%s is not an address space\n", as->get_name("unknown"));
422 else if (!chip->is_chip())
423 con->dd_printf("%s is not a memory chip\n", chip->get_name("unknown"));
424 else if (chip_begin >= chip->get_size())
425 con->dd_printf("Wrong chip area specification\n");
426 else if (as_begin < as->start_address ||
427 as_begin > as->highest_valid_address())
428 con->dd_printf("Specified area is out of address space\n");
429 else
430 {
431 class cl_banker *d=
432 (class cl_banker *)((class cl_address_space *)as)->get_decoder_of(as_begin);
433 if (!d)
434 con->dd_printf("Specified address is not decoded, create a banker first\n");
435 else if (!d->is_banker())
436 con->dd_printf("Specified area is not decoded by banker\n");
437 else
438 {
439 d->add_bank(bank, chip, chip_begin);
440 }
441 }
442 return(false);
443 }
444
445 CMDHELP(cl_memory_create_bank_cmd,
446 "memory create bank addressspace begin bank_nr chip begin",
447 "Add a new bank to bank switcher",
448 "long help of memory create bank")
449
450 /*
451 * Command: memory cell
452 *----------------------------------------------------------------------------
453 */
454
COMMAND_DO_WORK_UC(cl_memory_cell_cmd)455 COMMAND_DO_WORK_UC(cl_memory_cell_cmd)
456 {
457 class cl_cmd_arg *params[5]= { cmdline->param(0),
458 cmdline->param(1) };
459 class cl_memory *m= 0;
460 t_addr a= 0;
461 class cl_address_space *as= 0;
462 class cl_memory_cell *c= 0;
463
464 if (cmdline->syntax_match(uc, CELL))
465 {
466 c= params[0]->value.cell;
467 m= as= uc->address_space(c, &a);
468 }
469 else if (cmdline->syntax_match(uc, MEMORY ADDRESS /*NUMBER*/))
470 {
471 m= params[0]->value.memory.memory;
472 a= params[1]->value.number;
473 if (m->is_address_space())
474 as= (cl_address_space *)m;
475 }
476 if (as == 0)
477 return syntax_error(con), false;
478
479 if (!c)
480 c= as->get_cell(a);
481 con->dd_printf("%s", as->get_name());
482 con->dd_printf("[");
483 con->dd_printf(as->addr_format, a);
484 con->dd_printf("] %s\n", (char*)uc->cell_name(c));
485
486 con->dd_printf("cell data=%p/%d mask=%x flags=%x\n",
487 c->get_data(),
488 MU(c->get_width()),
489 MU(c->get_mask()),
490 MU(c->get_flags()));
491
492 int i;
493 for (i= 0; i < uc->memchips->count; i++)
494 {
495 cl_memory_chip *ch= (cl_memory_chip*)(uc->memchips->at(i));
496 t_addr ad;
497 if ((ad= ch->is_slot(c->get_data())) >= 0)
498 {
499 con->dd_printf(" decoded to %s[%u]\n",
500 ch->get_name(), AU(ad));
501 break;
502 }
503 }
504
505 con->dd_printf("Operators:\n");
506 c->print_operators(" ", con);
507
508 return false;
509 }
510
511 CMDHELP(cl_memory_cell_cmd,
512 "memory cell",
513 "Information about a memory cell",
514 "long help of memory cell")
515
516 /* End of cmd.src/cmd_mem.cc */
517