1 /*
2 * Simulator of microcontrollers (mem.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 /*
11 This file is part of microcontroller simulator: ucsim.
12
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING. If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 02111-1307, USA.
27 */
28 /*@1@*/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <stdarg.h>
34 #include "i_string.h"
35
36 // prj
37 #include "utils.h"
38 #include "globals.h"
39
40 // sim
41 #include "simcl.h"
42
43 // cmd
44 #include "newcmdcl.h"
45 #include "cmdutil.h"
46
47 // local
48 #include "memcl.h"
49 #include "hwcl.h"
50
51
52 static class cl_mem_error_registry mem_error_registry;
53
54 /*
55 * 3rd version of memory system
56 */
57
cl_memory(const char * id,t_addr asize,int awidth)58 cl_memory::cl_memory(const char *id, t_addr asize, int awidth):
59 cl_base()
60 {
61 if ((size= asize) > max_mem_size)
62 size= max_mem_size;
63 set_name(id);
64 addr_format= data_format= 0;
65 width= awidth;
66 start_address= 0;
67 uc= 0;
68 hidden= false;
69 }
70
~cl_memory(void)71 cl_memory::~cl_memory(void)
72 {
73 if (addr_format)
74 free(addr_format);
75 if (data_format)
76 free(data_format);
77 }
78
79 int
init(void)80 cl_memory::init(void)
81 {
82 chars c= chars("",
83 //addr_format= (char *)malloc(10);
84 /*sprintf(addr_format,*/ "0x%%0%d",
85 size-1<=0xf?1:
86 (size-1<=0xff?2:
87 (size-1<=0xfff?3:
88 (size-1<=0xffff?4:
89 (size-1<=0xfffff?5:
90 (size-1<=0xffffff?6:12))))));
91 if (sizeof(t_addr) > sizeof(long))
92 c+= cchars("L");//strcat(addr_format, "L");
93 else if (sizeof(t_addr) > sizeof(int))
94 c+= cchars("l");//strcat(addr_format, "l");
95 c+= cchars("x");//strcat(addr_format, "x");
96 addr_format= strdup((char*)c);
97 //data_format= (char *)malloc(10);
98 c= cchars("");
99 /*sprintf(data_*/c.format(/*"0x"*/"%%0%d", width/4+((width%4)?1:0));
100 if (sizeof(t_mem) > sizeof(long))
101 c+= cchars("L");//strcat(data_format, "L");
102 else if (sizeof(t_mem) > sizeof(int))
103 c+= cchars("l");//strcat(data_format, "l");
104 c+= cchars("x");//strcat(data_format, "x");
105 data_format= strdup((char*)c);
106 data_mask= 1;
107 int w= width;
108 for (--w; w; w--)
109 {
110 data_mask<<= 1;
111 data_mask|= 1;
112 }
113 dump_finished= start_address;
114 return(0);
115 }
116
117
118 bool
valid_address(t_addr addr)119 cl_memory::valid_address(t_addr addr)
120 {
121 return(addr >= start_address &&
122 addr < start_address+size);
123 }
124
125 t_addr
inc_address(t_addr addr,int val)126 cl_memory::inc_address(t_addr addr, int val)
127 {
128 if (!start_address)
129 return(((signed)addr+val)%size);
130 addr-= start_address;
131 addr+= val;
132 addr%= size;
133 addr+= start_address;
134 return(addr);
135 }
136
137 t_addr
inc_address(t_addr addr)138 cl_memory::inc_address(t_addr addr)
139 {
140 if (!start_address)
141 return(((signed)addr+1)%size);
142 addr-= start_address;
143 addr++;
144 addr%= size;
145 addr+= start_address;
146 return(addr);
147 }
148
149 t_addr
validate_address(t_addr addr)150 cl_memory::validate_address(t_addr addr)
151 {
152 while (addr < start_address)
153 addr+= size;
154 if (addr > start_address+size)
155 {
156 addr-= start_address;
157 addr%= size;
158 addr+= start_address;
159 }
160 return(addr);
161 }
162
163
164 void
err_inv_addr(t_addr addr)165 cl_memory::err_inv_addr(t_addr addr)
166 {
167 if (!uc)
168 return;
169 class cl_error *e= new cl_error_mem_invalid_address(this, addr);
170 uc->error(e);
171 }
172
173 void
err_non_decoded(t_addr addr)174 cl_memory::err_non_decoded(t_addr addr)
175 {
176 if (!uc)
177 return;
178 class cl_error *e= new cl_error_mem_non_decoded(this, addr);
179 uc->error(e);
180 }
181
182
183 t_addr
dump(t_addr start,t_addr stop,int bpl,class cl_console_base * con)184 cl_memory::dump(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
185 {
186 int i, step;
187 t_addr lva= lowest_valid_address();
188 t_addr hva= highest_valid_address();
189 class cl_f *f= con->get_fout();
190
191 if (!f)
192 return dump_finished;
193
194 if (start < lva)
195 start= lva;
196 if (start > hva)
197 return dump_finished;
198 if (stop > hva)
199 stop= hva;
200 if (stop < lva)
201 return dump_finished;
202 if (stop >= start)
203 {
204 step= +1;
205 stop++;
206 if (start + bpl > stop)
207 bpl= stop - start;
208 }
209 else
210 {
211 step= -1;
212 stop--;
213 if (start - bpl < stop)
214 bpl= start - stop;
215 }
216 while ((step>0)?(start < stop):(start > stop))
217 {
218 // 1. field: address
219 /*f->prntf*/con->dd_cprintf("dump_address", addr_format, start);
220 /*f->write_str*/con->dd_printf(" ");
221 // 2. field: hex list
222 for (i= 0;
223 (i < bpl) &&
224 (start+i*step >= lva) &&
225 (start+i*step <= hva) &&
226 (start+i*step != stop);
227 i++)
228 {
229 /*f->prntf*/con->dd_cprintf("dump_number", data_format, read/*get*/(start+i*step));
230 /*f->write_str*/con->dd_printf(" ");
231 }
232 // 3. field: char list
233 while (i < bpl)
234 {
235 int j;
236 j= width/4 + ((width%4)?1:0) + 1;
237 while (j)
238 {
239 /*f->write_str*/con->dd_printf(" ");
240 j--;
241 }
242 i++;
243 }
244 for (i= 0; (i < bpl) &&
245 (start+i*step >= lva) &&
246 (start+i*step <= hva) &&
247 (start+i*step != stop);
248 i++)
249 {
250 long c= read(start+i*step);
251 /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&c)?(255&c):'.');
252 if (width > 8)
253 /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
254 if (width > 16)
255 /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
256 if (width > 24)
257 /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
258 }
259 /*f->prntf*/con->dd_printf("\n");
260 dump_finished= start+i*step;
261 start+= i*step;
262 }
263 return(dump_finished);
264 }
265
266 t_addr
dump_s(t_addr start,t_addr stop,int bpl,class cl_console_base * con)267 cl_memory::dump_s(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
268 {
269 t_addr lva= lowest_valid_address();
270 t_addr hva= highest_valid_address();
271 class cl_f *f= con->get_fout();
272
273 if (!f)
274 return dump_finished;
275 if (start < 0)
276 start= dump_finished;
277 if (stop < 0)
278 stop= start + 10*8 - 1;
279
280 if (start < lva)
281 start= lva;
282 if (start > hva)
283 return dump_finished;
284 if (stop > hva)
285 stop= hva;
286 if (stop < lva)
287 return dump_finished;
288
289 if (bpl < 0)
290 bpl= 8;
291 t_addr a= start;
292 t_mem d= read(a);
293 char last= '\n';
294 con->dd_printf("%s", (char*)(con->get_color_ansiseq("dump_char")));
295 while ((a <= stop) &&
296 (d != 0) &&
297 (a <= hva))
298 {
299 char c= d;
300 int i= d;
301 chars s;
302 if (a >= lva)
303 {
304 switch (c)
305 { // ' " ? \ a b f n r t v
306 case '\'': s= (char*)"\\\'"; f->write((char*)s, s.len()); break;
307 case '\"': s= (char*)"\\\""; f->write((char*)s, s.len()); break;
308 case '\?': s= (char*)"\\\?"; f->write((char*)s, s.len()); break;
309 case '\\': s= (char*)"\\\\"; f->write((char*)s, s.len()); break;
310 case '\a': s= (char*)"\\a"; f->write((char*)s, s.len()); break;
311 case '\b': s= (char*)"\\b"; f->write((char*)s, s.len()); break;
312 case '\f': s= (char*)"\\f"; f->write((char*)s, s.len()); break;
313 case '\n': s= (char*)"\\n"; f->write((char*)s, s.len()); break;
314 case '\r': s= (char*)"\\r"; f->write((char*)s, s.len()); break;
315 case '\t': s= (char*)"\\t"; f->write((char*)s, s.len()); break;
316 case '\v': s= (char*)"\\v"; f->write((char*)s, s.len()); break;
317 default:
318 if (isprint(i))
319 f->write(&c, 1);
320 else
321 {
322 s.format("\\%03o", i);
323 f->write((char*)s, s.len());
324 }
325 }
326 last= c;
327 }
328 d= read(++a);
329 }
330 if (last != '\n')
331 f->write_str("\n");
332 return dump_finished= a;
333 }
334
335 t_addr
dump_b(t_addr start,t_addr stop,int bpl,class cl_console_base * con)336 cl_memory::dump_b(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
337 {
338 t_addr lva= lowest_valid_address();
339 t_addr hva= highest_valid_address();
340 class cl_f *f= con->get_fout();
341
342 if (!f)
343 return dump_finished;
344 if (start < 0)
345 start= dump_finished;
346 if (stop < 0)
347 stop= start + 10*8 - 1;
348
349 if (start < lva)
350 start= lva;
351 if (start > hva)
352 return dump_finished;
353 if (stop > hva)
354 stop= hva;
355 if (stop < lva)
356 return dump_finished;
357
358 if (bpl < 0)
359 bpl= 8;
360 t_addr a= start;
361 t_mem d= read(a);
362 while ((a <= stop) &&
363 (a <= hva))
364 {
365 char c= d;
366 if (a >= lva)
367 {
368 f->write(&c, 1);
369 }
370 d= read(++a);
371 }
372 return dump_finished= a;
373 }
374
375 t_addr
dump_i(t_addr start,t_addr stop,int bpl,class cl_console_base * con)376 cl_memory::dump_i(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
377 {
378 t_addr lva= lowest_valid_address();
379 t_addr hva= highest_valid_address();
380 unsigned int sum;
381 t_addr start_line;
382 class cl_f *f= con->get_fout();
383
384 if (!f)
385 return dump_finished;
386 if (start < 0)
387 start= dump_finished;
388 if (start < lva)
389 start= lva;
390 if (stop < 0)
391 stop= start + 10*8 - 1;
392 if (stop > hva)
393 stop= hva;
394
395 if (start < lva)
396 start= lva;
397 if (start > hva)
398 return dump_finished;
399 if (stop > hva)
400 stop= hva;
401 if (stop < lva)
402 return dump_finished;
403
404 if (start > stop)
405 return dump_finished= stop;
406
407 if (bpl < 0)
408 bpl= 16;
409 if (bpl > 32)
410 bpl= 32;
411 t_addr a= start;
412 sum= 0;
413 start_line= a;
414 while (a <= stop)
415 {
416 a++;
417 if (((a % bpl) == 0) ||
418 (a > stop))
419 {
420 // dump line
421 if ((a - start_line) > 0)
422 {
423 unsigned char c;
424 sum= 0;
425 c= a-start_line;
426 f->prntf(":%02X%04X00", c, start_line);
427 sum+= c;
428 c= int(start_line >> 8) & 0xff;
429 sum+= c;
430 c= start_line & 0xff;
431 sum+= c;
432 int i;
433 for (i= 0; i < a-start_line; i++)
434 {
435 c= read(start_line + i);
436 f->prntf("%02X", c);
437 sum+= c;
438 }
439 sum&= 0xff;
440 unsigned char chk= 0x100 - sum;
441 f->prntf("%02X\r\n", chk);
442 }
443 start_line= a;
444 }
445 }
446 f->write_str(":00000001FF\r\n");
447 return dump_finished= a;
448 }
449
450 t_addr
dump(class cl_console_base * con)451 cl_memory::dump(/*class cl_f *f*/class cl_console_base *con)
452 {
453 if (con->get_fout() == NULL)
454 return dump_finished;
455 return(dump(dump_finished, dump_finished+10*8-1, 8, /*f*/con));
456 }
457
458 t_addr
dump(enum dump_format fmt,t_addr start,t_addr stop,int bpl,class cl_console_base * con)459 cl_memory::dump(enum dump_format fmt,
460 t_addr start, t_addr stop, int bpl,
461 /*class cl_f *f*/class cl_console_base *con)
462 {
463 t_addr lva= lowest_valid_address();
464 t_addr hva= highest_valid_address();
465
466 //if (!f)
467 //return dump_finished;
468 if (start < 0)
469 start= dump_finished;
470 if (stop < 0)
471 stop= start + 10*8 - 1;
472
473 if (start < lva)
474 start= lva;
475 if (start > hva)
476 return dump_finished;
477 if (stop > hva)
478 stop= hva;
479 if (stop < lva)
480 return dump_finished;
481
482 if (bpl < 0)
483 bpl= 8;
484 switch (fmt & df_format)
485 {
486 case df_hex:
487 return dump(start, stop, bpl, /*f*/con);
488 case df_string:
489 return dump_s(start, stop, bpl, /*f*/con);
490 case df_ihex:
491 return dump_i(start, stop, bpl, /*f*/con);
492 case df_binary:
493 return dump_b(start, stop, bpl, /*f*/con);
494 default:
495 return dump(start, stop, bpl, /*f*/con);
496 }
497 return dump_finished;
498 }
499
500 bool
search_next(bool case_sensitive,t_mem * array,int len,t_addr * addr)501 cl_memory::search_next(bool case_sensitive,
502 t_mem *array, int len, t_addr *addr)
503 {
504 t_addr a;
505 int i;
506 bool found;
507
508 if (addr == NULL)
509 a= 0;
510 else
511 a= *addr;
512
513 if (a+len > size)
514 return(false);
515
516 found= false;
517 while (!found &&
518 a+len <= size)
519 {
520 bool match= true;
521 for (i= 0; i < len && match; i++)
522 {
523 t_mem d1, d2;
524 d1= get(a+i);
525 d2= array[i];
526 if (!case_sensitive)
527 {
528 if (/*d1 < 128*/isalpha(d1))
529 d1= toupper(d1);
530 if (/*d2 < 128*/isalpha(d2))
531 d2= toupper(d2);
532 }
533 match= d1 == d2;
534 }
535 found= match;
536 if (!found)
537 a++;
538 }
539
540 if (addr)
541 *addr= a;
542 return(found);
543 }
544
545 void
print_info(chars pre,class cl_console_base * con)546 cl_memory::print_info(chars pre, class cl_console_base *con)
547 {
548 char *n= (char*)(get_name());
549 if (!hidden)
550 {
551 con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
552 AU(get_start_address()),
553 AU(highest_valid_address()),
554 AU(get_size()),
555 n,
556 width, data_format, addr_format);
557 }
558 }
559
560
561 /*
562 * Memory operators
563 */
564
cl_memory_operator(class cl_memory_cell * acell)565 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell/*,
566 t_addr addr*/):
567 cl_base()
568 {
569 cell= acell;
570 if (cell)
571 {
572 //data= cell->data;
573 mask= cell->mask;
574 }
575 else
576 {
577 //data= 0;
578 mask= ~0;
579 }
580 next_operator= 0;
581 //address= addr;
582 }
583 /*
584 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
585 t_addr addr,
586 t_mem *data_place, t_mem the_mask):
587 cl_base()
588 {
589 cell= acell;
590 //data= data_place;
591 mask= the_mask;
592 next_operator= 0;
593 address= addr;
594 }
595 */
596 /*
597 void
598 cl_memory_operator::set_data(t_mem *data_place, t_mem the_mask)
599 {
600 data= data_place;
601 mask= the_mask;
602 }
603 */
604
605 t_mem
read(void)606 cl_memory_operator::read(void)
607 {
608 if (next_operator)
609 return(next_operator->read());
610 else if (cell)
611 return(/* *data*/cell->get());
612 return 0;
613 }
614
615 t_mem
write(t_mem val)616 cl_memory_operator::write(t_mem val)
617 {
618 if (next_operator)
619 return(next_operator->write(val));
620 else if (cell)
621 return(/* *data=*/cell->set(val & mask));
622 return val;
623 }
624
625
626 /* Memory operator for bank switcher */
627
cl_bank_switcher_operator(class cl_memory_cell * acell,class cl_banker * the_banker)628 cl_bank_switcher_operator::cl_bank_switcher_operator(class cl_memory_cell *acell,
629 /*t_addr addr,*/
630 class cl_banker *the_banker):
631 cl_memory_operator(acell/*, addr*/)
632 {
633 banker= the_banker;
634 set_name("bank_switcher");
635 }
636
637 t_mem
write(t_mem val)638 cl_bank_switcher_operator::write(t_mem val)
639 {
640 if (next_operator)
641 next_operator->write(val);
642 if (cell) /* *data=*/ cell->set(val & mask);
643 banker->activate(NULL);
644 if (cell)
645 return cell->get();
646 return /* *data*/ 0;
647 }
648
649
650 /* Memory operator for hw callbacks */
651
cl_hw_operator(class cl_memory_cell * acell,class cl_hw * ahw)652 cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell/*, t_addr addr*/,
653 //t_mem *data_place, t_mem the_mask,
654 class cl_hw *ahw):
655 cl_memory_operator(acell/*, addr*//*, data_place, the_mask*/)
656 {
657 hw= ahw;
658 set_name(chars("hw:")+hw->get_name());
659 }
660
661
662 t_mem
read(void)663 cl_hw_operator::read(void)
664 {
665 t_mem d1= 0, d2= 0;
666
667 if (hw)
668 d1= hw->read(cell);
669
670 if (next_operator)
671 d2= next_operator->read();
672
673 return(hw?d1:d2);
674 }
675
676 t_mem
read(enum hw_cath skip)677 cl_hw_operator::read(enum hw_cath skip)
678 {
679 t_mem d1= 0/* *data*/, d2= d1;
680 bool use= false;
681
682 if (hw &&
683 hw->cathegory != skip)
684 use= true, d1= hw->read(cell);
685
686 if (next_operator)
687 d2= next_operator->read();
688 else if (cell)
689 d2= cell->get();
690 else
691 return use= true;
692
693 return(use?d1:d2);
694 }
695
696 t_mem
write(t_mem val)697 cl_hw_operator::write(t_mem val)
698 {
699 if (hw)
700 hw->write(cell, &val);
701 if (next_operator)
702 val= next_operator->write(val);
703 //if (cell) return(/* *data=*//*cell->set(val & mask)*/val);
704 return val;
705 }
706
707
708 /* Write event break on cell */
709
cl_write_operator(class cl_memory_cell * acell,class cl_uc * auc,class cl_brk * the_bp)710 cl_write_operator::cl_write_operator(class cl_memory_cell *acell/*, t_addr addr*/,
711 //t_mem *data_place, t_mem the_mask,
712 class cl_uc *auc, class cl_brk *the_bp):
713 cl_event_break_operator(acell/*, addr*//*, data_place, the_mask*/, auc, the_bp)
714 {
715 uc= auc;
716 bp= the_bp;
717 set_name("write_event");
718 }
719
720 t_mem
write(t_mem val)721 cl_write_operator::write(t_mem val)
722 {
723 //printf("write event at 0x%x bp=%p\n",address,bp);
724 if (bp->do_hit())
725 uc->events->add(bp);
726 if (next_operator)
727 return(next_operator->write(val));
728 else if (cell)
729 return(/* *data=*/cell->set(val & mask));
730 return val;
731 }
732
733
734 /* Read event break on cell */
735
cl_read_operator(class cl_memory_cell * acell,class cl_uc * auc,class cl_brk * the_bp)736 cl_read_operator::cl_read_operator(class cl_memory_cell *acell/*, t_addr addr*/,
737 //t_mem *data_place, t_mem the_mask,
738 class cl_uc *auc, class cl_brk *the_bp):
739 cl_event_break_operator(acell/*, addr*//*, data_place, the_mask*/, auc, the_bp)
740 {
741 uc= auc;
742 bp= the_bp;
743 set_name("read_event");
744 }
745
746 t_mem
read(void)747 cl_read_operator::read(void)
748 {
749 //printf("read event at 0x%x bp=%p\n",address,bp);
750 if (bp->do_hit())
751 uc->events->add(bp);
752 if (next_operator)
753 return(next_operator->read());
754 else if (cell)
755 return(/* *data*/cell->get());
756 return 0;
757 }
758
759
760 /*
761 * Cell data
762 */
763
764 t_mem
d()765 cl_cell_data::d()
766 {
767 return data?(*data):0;
768 }
769
770 void
d(t_mem v)771 cl_cell_data::d(t_mem v)
772 {
773 data?(*data=v):0;
774 }
775
776 void
dl(t_mem v)777 cl_cell_data::dl(t_mem v)
778 {
779 data?(*data=v):0;
780 }
781
782 // bit cell for bit spaces
783
784 t_mem
d()785 cl_bit_cell::d()
786 {
787 if (!data)
788 return 0;
789 return (*data&mask)?1:0;
790 }
791
792 void
d(t_mem v)793 cl_bit_cell::d(t_mem v)
794 {
795 if (!data)
796 return;
797 if (v)
798 *data|= mask;
799 else
800 *data&= ~mask;
801 }
802
803
804 // 8 bit cell;
805
806 t_mem
d()807 cl_cell8::d()
808 {
809 return data?((/*u8_t*/uchar)*data):0;
810 }
811
812 void
d(t_mem v)813 cl_cell8::d(t_mem v)
814 {
815 data?(*data=(/*u8_t*/uchar)v):0;
816 }
817
818 // 8 bit cell for bit spaces
819
820 t_mem
d()821 cl_bit_cell8::d()
822 {
823 if (!data)
824 return 0;
825 /*u8_t*/uchar x= (/*u8_t*/uchar) *data;
826 x&= mask;
827 return x?1:0;
828 }
829
830 void
d(t_mem v)831 cl_bit_cell8::d(t_mem v)
832 {
833 if (!data)
834 return;
835 if (v)
836 *data |= (/*u8_t*/uchar)mask;
837 else
838 *data &= ~(/*u8_t*/uchar)mask;
839 }
840
841 // 16 bit cell;
842
843 t_mem
d()844 cl_cell16::d()
845 {
846 return data?((u16_t)*data):0;
847 }
848
849 void
d(t_mem v)850 cl_cell16::d(t_mem v)
851 {
852 data?(*data=(u16_t)v):0;
853 }
854
855 // 16 bit cell for bit spaces
856
857 t_mem
d()858 cl_bit_cell16::d()
859 {
860 if (!data)
861 return 0;
862 return (((u16_t)*data)&((u16_t)mask))?1:0;
863 }
864
865 void
d(t_mem v)866 cl_bit_cell16::d(t_mem v)
867 {
868 if (!data)
869 return;
870 if (v)
871 *data |= (u16_t)mask;
872 else
873 *data &= ~(u16_t)mask;
874 }
875
876
877 /*
878 * Memory cell
879 */
880
cl_memory_cell(uchar awidth)881 cl_memory_cell::cl_memory_cell(uchar awidth)//: cl_base()
882 {
883 data= 0;
884 flags= CELL_NON_DECODED;
885 width= awidth;
886 //*data= 0;
887 def_data= 0;
888 operators= NULL;
889 //bank= 0;
890 //banked_data_ptrs= 0;
891 #ifdef STATISTIC
892 nuof_writes= nuof_reads= 0;
893 #endif
894 mask= 1;
895 int w= width;
896 for (--w; w; w--)
897 {
898 mask<<= 1;
899 mask|= 1;
900 }
901 }
902
~cl_memory_cell(void)903 cl_memory_cell::~cl_memory_cell(void)
904 {
905 if ((flags & CELL_NON_DECODED) &&
906 data)
907 ;//free(data);
908 }
909
910 int
init(void)911 cl_memory_cell::init(void)
912 {
913 //cl_base::init();
914 data= &def_data;
915 //flags= CELL_NON_DECODED;
916 /*mask= 1;
917 int w= width;
918 for (--w; w; w--)
919 {
920 mask<<= 1;
921 mask|= 1;
922 }*/
923 //set(0/*rand()*/);
924 return(0);
925 }
926
927
928 uchar
get_flags(void)929 cl_memory_cell::get_flags(void)
930 {
931 return(flags);
932 }
933
934 bool
get_flag(enum cell_flag flag)935 cl_memory_cell::get_flag(enum cell_flag flag)
936 {
937 return(flags & flag);
938 }
939
940 void
set_flags(uchar what)941 cl_memory_cell::set_flags(uchar what)
942 {
943 flags= what;
944 }
945
946 void
set_flag(enum cell_flag flag,bool val)947 cl_memory_cell::set_flag(enum cell_flag flag, bool val)
948 {
949 if (val)
950 flags|= flag;
951 else
952 flags&= ~(flag);
953 }
954
955
956 void
un_decode(void)957 cl_memory_cell::un_decode(void)
958 {
959 if ((flags & CELL_NON_DECODED) == 0)
960 {
961 data= &def_data;//(t_mem *)malloc(sizeof(t_mem));
962 flags|= CELL_NON_DECODED;
963 }
964 }
965
966 void
decode(class cl_memory_chip * chip,t_addr addr)967 cl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr)
968 {
969 if (flags & CELL_NON_DECODED)
970 ;//free(data);
971 data= chip->get_slot(addr);
972 if (!data)
973 {
974 data= &def_data;//(t_mem *)malloc(sizeof(t_mem));
975 flags|= CELL_NON_DECODED;
976 }
977 else
978 flags&= ~(CELL_NON_DECODED);
979 }
980
981 void
decode(t_mem * data_ptr)982 cl_memory_cell::decode(t_mem *data_ptr)
983 {
984 if (data_ptr == NULL)
985 {
986 data= &def_data;
987 flags|= CELL_NON_DECODED;
988 }
989 else
990 {
991 data= data_ptr;
992 flags&= ~CELL_NON_DECODED;
993 }
994 }
995
996 void
decode(t_mem * data_ptr,t_mem bit_mask)997 cl_memory_cell::decode(t_mem *data_ptr, t_mem bit_mask)
998 {
999 if (data_ptr == NULL)
1000 {
1001 data= &def_data;
1002 flags|= CELL_NON_DECODED;
1003 }
1004 else
1005 {
1006 data= data_ptr;
1007 flags&= ~CELL_NON_DECODED;
1008 }
1009 mask= bit_mask;
1010 }
1011
1012 t_mem
read(void)1013 cl_memory_cell::read(void)
1014 {
1015 #ifdef STATISTIC
1016 nuof_reads++;
1017 #endif
1018 if (operators)
1019 return(operators->read());
1020 return /* *data*/d();
1021 }
1022
1023 t_mem
read(enum hw_cath skip)1024 cl_memory_cell::read(enum hw_cath skip)
1025 {
1026 #ifdef STATISTIC
1027 nuof_reads++;
1028 #endif
1029 if (operators)
1030 return(operators->read(skip));
1031 return /* *data*/d();
1032 }
1033
1034 t_mem
get(void)1035 cl_memory_cell::get(void)
1036 {
1037 return /* *data*/d();
1038 }
1039
1040 t_mem
write(t_mem val)1041 cl_memory_cell::write(t_mem val)
1042 {
1043 #ifdef STATISTIC
1044 nuof_writes++;
1045 #endif
1046 if (operators)
1047 val= operators->write(val);
1048 if (flags & CELL_READ_ONLY)
1049 return d();
1050 if (width == 1)
1051 d(val);
1052 else
1053 d(val & mask);
1054 return d();
1055 }
1056
1057 t_mem
set(t_mem val)1058 cl_memory_cell::set(t_mem val)
1059 {
1060 if (flags & CELL_READ_ONLY)
1061 return d();
1062 if (width == 1)
1063 d(val);
1064 else
1065 /* *data=*/d(val & mask);
1066 return /* *data*/d();
1067 }
1068
1069 t_mem
download(t_mem val)1070 cl_memory_cell::download(t_mem val)
1071 {
1072 if (width == 1)
1073 dl(val);
1074 else
1075 /* *data=*/dl(val & mask);
1076 return /* *data*/d();
1077 }
1078
1079 t_mem
add(long what)1080 cl_memory_cell::add(long what)
1081 {
1082 /* *data=*/ d( (*data + what) & mask);
1083 return(/* *data*/d());
1084 }
1085
1086 t_mem
wadd(long what)1087 cl_memory_cell::wadd(long what)
1088 {
1089 t_mem d= (*data + what) & mask;
1090 return(write(d));
1091 }
1092
1093 void
set_bit1(t_mem bits)1094 cl_memory_cell::set_bit1(t_mem bits)
1095 {
1096 bits&= mask;
1097 /*(*data)|=*//*d*/set(d()| bits);
1098 }
1099
1100 void
write_bit1(t_mem bits)1101 cl_memory_cell::write_bit1(t_mem bits)
1102 {
1103 bits&= mask;
1104 /*(*data)|=*//*d*/write(d()| bits);
1105 }
1106
1107 void
set_bit0(t_mem bits)1108 cl_memory_cell::set_bit0(t_mem bits)
1109 {
1110 bits&= mask;
1111 /*(*data)&=*//*d*/set(d()& ~bits);
1112 }
1113
1114 void
write_bit0(t_mem bits)1115 cl_memory_cell::write_bit0(t_mem bits)
1116 {
1117 bits&= mask;
1118 /*(*data)&=*//*d*/write(d()& ~bits);
1119 }
1120
1121 void
toggle_bits(t_mem bits)1122 cl_memory_cell::toggle_bits(t_mem bits)
1123 {
1124 bits&= mask;
1125 /*d*/set(d() ^ bits);
1126 }
1127
1128 void
wtoggle_bits(t_mem bits)1129 cl_memory_cell::wtoggle_bits(t_mem bits)
1130 {
1131 bits&= mask;
1132 /*d*/write(d() ^ bits);
1133 }
1134
1135
1136 void
append_operator(class cl_memory_operator * op)1137 cl_memory_cell::append_operator(class cl_memory_operator *op)
1138 {
1139 if (!operators)
1140 operators= op;
1141 else
1142 {
1143 class cl_memory_operator *o= operators, *n;
1144 n= o->get_next();
1145 while (n)
1146 {
1147 o= n;
1148 n= o->get_next();
1149 }
1150 o->set_next(op);
1151 }
1152 }
1153
1154 void
prepend_operator(class cl_memory_operator * op)1155 cl_memory_cell::prepend_operator(class cl_memory_operator *op)
1156 {
1157 if (op)
1158 {
1159 op->set_next(operators);
1160 operators= op;
1161 }
1162 }
1163
1164 void
del_operator(class cl_brk * brk)1165 cl_memory_cell::del_operator(class cl_brk *brk)
1166 {
1167 if (!operators)
1168 return;
1169 class cl_memory_operator *op= operators;
1170 if (operators->match(brk))
1171 {
1172 operators= op->get_next();
1173 delete op;
1174 }
1175 else
1176 {
1177 while (op->get_next() &&
1178 !op->get_next()->match(brk))
1179 op= op->get_next();
1180 if (op->get_next())
1181 {
1182 class cl_memory_operator *m= op->get_next();
1183 op->set_next(m->get_next());;
1184 delete m;
1185 }
1186 }
1187 }
1188
1189 void
del_operator(class cl_hw * hw)1190 cl_memory_cell::del_operator(class cl_hw *hw)
1191 {
1192 if (!operators)
1193 return;
1194 class cl_memory_operator *op= operators;
1195 if (operators->match(hw))
1196 {
1197 operators= op->get_next();
1198 delete op;
1199 }
1200 else
1201 {
1202 while (op->get_next() &&
1203 !op->get_next()->match(hw))
1204 op= op->get_next();
1205 if (op->get_next())
1206 {
1207 class cl_memory_operator *m= op->get_next();
1208 op->set_next(m->get_next());
1209 delete m;
1210 }
1211 }
1212 }
1213
1214 class cl_banker *
get_banker(void)1215 cl_memory_cell::get_banker(void)
1216 {
1217 class cl_memory_operator *op= operators;
1218 class cl_banker *b= NULL;
1219
1220 while (op)
1221 {
1222 b= op->get_banker();
1223 if (b)
1224 return b;
1225 op= op->get_next();
1226 }
1227 return NULL;
1228 }
1229
1230 class cl_memory_cell *
add_hw(class cl_hw * hw)1231 cl_memory_cell::add_hw(class cl_hw *hw/*, t_addr addr*/)
1232 {
1233 class cl_hw_operator *o= new cl_hw_operator(this/*, addr*//*, data, mask*/, hw);
1234 append_operator(o);
1235 return(this);
1236 }
1237
1238 void
remove_hw(class cl_hw * hw)1239 cl_memory_cell::remove_hw(class cl_hw *hw)
1240 {
1241 del_operator(hw);
1242 }
1243
1244 /*class cl_hw *
1245 cl_memory_cell::get_hw(int ith)
1246 {
1247 return(0);
1248 }*/
1249
1250 class cl_event_handler *
get_event_handler(void)1251 cl_memory_cell::get_event_handler(void)
1252 {
1253 return(0);
1254 }
1255
1256 void
print_info(chars pre,class cl_console_base * con)1257 cl_memory_cell::print_info(chars pre, class cl_console_base *con)
1258 {
1259 con->dd_printf("%sFlags:", (char*)pre);
1260 if (flags & CELL_VAR)
1261 con->dd_printf(" VAR");
1262 if (flags & CELL_INST)
1263 con->dd_printf(" INST");
1264 if (flags & CELL_FETCH_BRK)
1265 con->dd_printf(" FBRK");
1266 if (flags & CELL_READ_ONLY)
1267 con->dd_printf(" RO");
1268 if (flags & CELL_NON_DECODED)
1269 con->dd_printf(" NDC");
1270 con->dd_printf("\n");
1271 print_operators(pre, con);
1272 }
1273
1274 void
print_operators(chars pre,class cl_console_base * con)1275 cl_memory_cell::print_operators(chars pre, class cl_console_base *con)
1276 {
1277 class cl_memory_operator *o= operators;
1278 if (!operators)
1279 return;
1280 int i= 0;
1281 while (o)
1282 {
1283 printf("%s %02d. %s\n", (char*)pre, i, o->get_name("?"));
1284 i++;
1285 o= o->get_next();
1286 }
1287 }
1288
1289
1290 /*
1291 * Dummy cell for non-existent addresses
1292 */
1293
1294 t_mem
write(t_mem val)1295 cl_dummy_cell::write(t_mem val)
1296 {
1297 #ifdef STATISTIC
1298 nuof_writes++;
1299 #endif
1300 *data= rand() & mask;
1301 return(*data);
1302 }
1303
1304 t_mem
set(t_mem val)1305 cl_dummy_cell::set(t_mem val)
1306 {
1307 *data= rand() & mask;
1308 return(*data);
1309 }
1310
1311
1312 /*
1313 * Address space
1314 */
1315
cl_address_space(const char * id,t_addr astart,t_addr asize,int awidth)1316 cl_address_space::cl_address_space(const char *id,
1317 t_addr astart, t_addr asize, int awidth):
1318 cl_memory(id, asize, awidth)
1319 {
1320 class cl_memory_cell c(awidth);
1321 class cl_bit_cell8 bc8(awidth);
1322 class cl_cell8 c8(awidth);
1323 class cl_cell16 c16(awidth);
1324 class cl_memory_cell *cell= &c;
1325 start_address= astart;
1326 decoders= new cl_decoder_list(2, 2, false);
1327 cella= (class cl_memory_cell *)malloc(size * sizeof(class cl_memory_cell));
1328 if (awidth == 1)
1329 cell= &bc8;
1330 else if (awidth <= 8)
1331 cell= &c8;
1332 else if (awidth <= 16)
1333 cell= &c16;
1334 //cell->init();
1335 int i;
1336 for (i= 0; i < size; i++)
1337 {
1338 void *p1= &(cella[i]);
1339 void *p2= cell;
1340 memcpy(p1, p2, sizeof(c));
1341 cella[i].init();
1342 }
1343 dummy= new cl_dummy_cell(awidth);
1344 dummy->init();
1345 }
1346
~cl_address_space(void)1347 cl_address_space::~cl_address_space(void)
1348 {
1349 delete decoders;
1350 int i;
1351 for (i= 0; i < size; i++)
1352 {
1353 cella[i].~cl_memory_cell();
1354 }
1355 free(cella);
1356 delete dummy;
1357 }
1358
1359
1360 t_mem
read(t_addr addr)1361 cl_address_space::read(t_addr addr)
1362 {
1363 t_addr idx= addr-start_address;
1364 if (idx >= size ||
1365 addr < start_address)
1366 {
1367 err_inv_addr(addr);
1368 return(dummy->read());
1369 }
1370 return(cella[idx].read());
1371 }
1372
1373 t_mem
read(t_addr addr,enum hw_cath skip)1374 cl_address_space::read(t_addr addr, enum hw_cath skip)
1375 {
1376 t_addr idx= addr-start_address;
1377 if (idx >= size ||
1378 addr < start_address)
1379 {
1380 err_inv_addr(addr);
1381 return(dummy->read());
1382 }
1383 return(cella[idx].read(skip));
1384 }
1385
1386 t_mem
get(t_addr addr)1387 cl_address_space::get(t_addr addr)
1388 {
1389 t_addr idx= addr-start_address;
1390 if (idx >= size ||
1391 addr < start_address)
1392 {
1393 err_inv_addr(addr);
1394 return(dummy->get());
1395 }
1396 return cella[idx].get();//*(cella[idx].data);
1397 }
1398
1399 t_mem
write(t_addr addr,t_mem val)1400 cl_address_space::write(t_addr addr, t_mem val)
1401 {
1402 t_addr idx= addr-start_address;
1403 if (idx >= size ||
1404 addr < start_address)
1405 {
1406 err_inv_addr(addr);
1407 return(dummy->write(val));
1408 }
1409 //if (cella[idx].get_flag(CELL_NON_DECODED)) printf("%s[%d] nondec write=%x\n",get_name(),addr,val);
1410 return(cella[idx].write(val));
1411 }
1412
1413 void
set(t_addr addr,t_mem val)1414 cl_address_space::set(t_addr addr, t_mem val)
1415 {
1416 t_addr idx= addr-start_address;
1417 if (idx >= size ||
1418 addr < start_address)
1419 {
1420 err_inv_addr(addr);
1421 dummy->set(val);
1422 return;
1423 }
1424 /* *(cella[idx].data)=*/cella[idx].set( val/*&(data_mask)*/);
1425 }
1426
1427 void
download(t_addr addr,t_mem val)1428 cl_address_space::download(t_addr addr, t_mem val)
1429 {
1430 t_addr idx= addr-start_address;
1431 if (idx >= size ||
1432 addr < start_address)
1433 {
1434 err_inv_addr(addr);
1435 dummy->download(val);
1436 return;
1437 }
1438 /* *(cella[idx].data)=*/cella[idx].download( val/*&(data_mask)*/);
1439 }
1440
1441 t_mem
wadd(t_addr addr,long what)1442 cl_address_space::wadd(t_addr addr, long what)
1443 {
1444 t_addr idx= addr-start_address;
1445 if (idx >= size ||
1446 addr < start_address)
1447 {
1448 err_inv_addr(addr);
1449 }
1450 return(cella[idx].wadd(what));
1451 }
1452
1453 /* Set or clear bits, without callbacks */
1454
1455 void
set_bit1(t_addr addr,t_mem bits)1456 cl_address_space::set_bit1(t_addr addr, t_mem bits)
1457 {
1458 t_addr idx= addr-start_address;
1459 if (idx >= size ||
1460 addr < start_address)
1461 return;
1462 class cl_memory_cell *cell= &(cella[idx]);
1463 cell->set_bit1(bits);
1464 }
1465
1466 void
set_bit0(t_addr addr,t_mem bits)1467 cl_address_space::set_bit0(t_addr addr, t_mem bits)
1468 {
1469 t_addr idx= addr-start_address;
1470 if (idx >= size ||
1471 addr < start_address)
1472 return;
1473 class cl_memory_cell *cell= &(cella[idx]);
1474 cell->set_bit0(bits);
1475 }
1476
1477
1478 class cl_memory_cell *
get_cell(t_addr addr)1479 cl_address_space::get_cell(t_addr addr)
1480 {
1481 t_addr idx= addr-start_address;
1482 if (idx >= size ||
1483 addr < start_address)
1484 {
1485 err_inv_addr(addr);
1486 return(dummy);
1487 }
1488 return(&cella[idx]);
1489 }
1490
1491
1492 int
get_cell_flag(t_addr addr)1493 cl_address_space::get_cell_flag(t_addr addr)
1494 {
1495 t_addr idx= addr-start_address;
1496 if (idx >= size ||
1497 addr < start_address)
1498 {
1499 return(dummy->get_flags());
1500 }
1501 return(cella[idx].get_flags());
1502 }
1503
1504 bool
get_cell_flag(t_addr addr,enum cell_flag flag)1505 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
1506 {
1507 t_addr idx= addr-start_address;
1508 if (idx >= size ||
1509 addr < start_address)
1510 {
1511 return(dummy->get_flag(flag));
1512 }
1513 return(cella[idx].get_flag(flag));
1514 }
1515
1516 void
set_cell_flag(t_addr addr,bool set_to,enum cell_flag flag)1517 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
1518 {
1519 t_addr idx= addr-start_address;
1520 class cl_memory_cell *cell;
1521
1522 if (idx >= size ||
1523 addr < start_address)
1524 {
1525 cell= dummy;
1526 }
1527 else
1528 cell= &cella[idx];
1529 cell->set_flag(flag, set_to);
1530 }
1531
1532 void
set_cell_flag(t_addr start_addr,t_addr end_addr,bool set_to,enum cell_flag flag)1533 cl_address_space::set_cell_flag(t_addr start_addr, t_addr end_addr, bool set_to, enum cell_flag flag)
1534 {
1535 t_addr a;
1536
1537 for (a= start_addr; a <= end_addr; a++)
1538 set_cell_flag(a, set_to, flag);
1539 }
1540
1541 class cl_memory_cell *
search_cell(enum cell_flag flag,bool value,t_addr * addr)1542 cl_address_space::search_cell(enum cell_flag flag, bool value, t_addr *addr)
1543 {
1544 int i;
1545
1546 for (i= 0; i < size; i++)
1547 {
1548 bool f= cella[i].get_flag(flag);
1549 if ((f && value) ||
1550 (!f && !value))
1551 {
1552 if (addr)
1553 *addr= i;
1554 return &cella[i];
1555 }
1556 }
1557 return NULL;
1558 }
1559
1560 bool
is_owned(class cl_memory_cell * cell,t_addr * addr)1561 cl_address_space::is_owned(class cl_memory_cell *cell, t_addr *addr)
1562 {
1563 if (cell < cella)
1564 return false;
1565 if (cell > &cella[size-1])
1566 return false;
1567 int idx= cell - cella;
1568 if (addr)
1569 *addr= start_address+idx;
1570 return true;
1571 }
1572
1573 class cl_address_decoder *
get_decoder_of(t_addr addr)1574 cl_address_space::get_decoder_of(t_addr addr)
1575 {
1576 class cl_address_decoder *dc;
1577 int i;
1578 for (i= 0; i < decoders->count; i++)
1579 {
1580 dc= (class cl_address_decoder *)(decoders->at(i));
1581 if (dc->covers(addr, addr))
1582 return dc;
1583 }
1584 return NULL;
1585 }
1586
1587 bool
decode_cell(t_addr addr,class cl_memory_chip * chip,t_addr chipaddr)1588 cl_address_space::decode_cell(t_addr addr,
1589 class cl_memory_chip *chip, t_addr chipaddr)
1590 {
1591 t_addr idx= addr-start_address;
1592 if (idx >= size ||
1593 addr < start_address)
1594 return(false);
1595 class cl_memory_cell *cell= &cella[idx];
1596
1597 if (!cell->get_flag(CELL_NON_DECODED))
1598 {
1599 // un-decode first!
1600 cell->un_decode();
1601 }
1602 cell->decode(chip, chipaddr);
1603
1604 return(!cell->get_flag(CELL_NON_DECODED));
1605 }
1606
1607 void
undecode_cell(t_addr addr)1608 cl_address_space::undecode_cell(t_addr addr)
1609 {
1610 t_addr idx= addr-start_address;
1611 if (idx >= size ||
1612 addr < start_address)
1613 return;
1614 class cl_memory_cell *cell= &cella[idx];
1615
1616 cell->un_decode();
1617 }
1618
1619 void
undecode_area(class cl_address_decoder * skip,t_addr begin,t_addr end,class cl_console_base * con)1620 cl_address_space::undecode_area(class cl_address_decoder *skip,
1621 t_addr begin, t_addr end,
1622 class cl_console_base *con)
1623 {
1624 #define D if (con) con->debug
1625 //#define D printf
1626 D("Undecoding area 0x%lx-0x%lx of %s (skip=%s)\n", begin, end, get_name(), skip?(skip->get_name()):"-");
1627 int i;
1628 for (i= 0; i < decoders->count; i++)
1629 {
1630 class cl_address_decoder *d=
1631 dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
1632 if (!d ||
1633 d == skip)
1634 continue;
1635 D(" Checking decoder 0x%lx-0x%lx -> %s[0x%lx]\n",
1636 d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
1637 if (d->fully_covered_by(begin, end))
1638 {
1639 // decoder can be removed
1640 D(" Can be removed\n");
1641 decoders->disconn(d);
1642 i--;
1643 delete d;
1644 if (decoders->count == 0)
1645 break;
1646 }
1647 else if (d->covers(begin, end))
1648 {
1649 // decoder must be split
1650 D(" Must be split\n");
1651 class cl_address_decoder *nd= d->split(begin, end);
1652 D(" After split:\n");
1653 D(" 0x%lx-0x%lx -> %s[0x%lx]\n",
1654 d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
1655 if (nd)
1656 {
1657 decoders->add(nd);
1658 D(" 0x%lx-0x%lx -> %s[0x%lx]\n",
1659 nd->as_begin, nd->as_end, (nd->memchip)?(nd->memchip->get_name()):"none", nd->chip_begin);
1660 nd->activate(con);
1661 }
1662 }
1663 else if (d->is_in(begin, end))
1664 {
1665 // decoder sould shrink
1666 D(" Sould shrink\n");
1667 if (d->shrink_out_of(begin, end))
1668 {
1669 D(" Can be removed after shrink\n");
1670 decoders->disconn(d);
1671 i--;
1672 delete d;
1673 if (decoders->count == 0)
1674 break;
1675 }
1676 else
1677 {
1678 D(" Shrinked to 0x%lx-0x%lx -> %s[0x%lx]\n",
1679 d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
1680 }
1681 }
1682 }
1683 #undef D
1684 }
1685
1686
1687 class cl_memory_cell *
register_hw(t_addr addr,class cl_hw * hw,bool announce)1688 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
1689 bool announce)
1690 {
1691 t_addr idx= addr-start_address;
1692 if (idx >= size ||
1693 addr < start_address)
1694 return(0);
1695 class cl_memory_cell *cell= &cella[idx];
1696 cell->add_hw(hw/*, addr*/);
1697 if (announce)
1698 ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
1699 return(cell);
1700 }
1701
1702 void
unregister_hw(class cl_hw * hw)1703 cl_address_space::unregister_hw(class cl_hw *hw)
1704 {
1705 t_addr idx;
1706
1707 for (idx= 0; idx < size; idx++)
1708 {
1709 class cl_memory_cell *cell= &cella[idx];
1710 cell->remove_hw(hw);
1711 }
1712 }
1713
1714 void
set_brk(t_addr addr,class cl_brk * brk)1715 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
1716 {
1717 t_addr idx= addr-start_address;
1718 if (idx >= size ||
1719 addr < start_address)
1720 return;
1721 class cl_memory_cell *cell= &cella[idx];
1722 class cl_memory_operator *op;
1723
1724 switch (brk->get_event())
1725 {
1726 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1727 //e= 'W';
1728 op= new cl_write_operator(cell/*, addr*/, //cell->get_data(), cell->get_mask(),
1729 uc, brk);
1730 break;
1731 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1732 //e= 'R';
1733 op= new cl_read_operator(cell/*, addr*/, //cell->get_data(), cell->get_mask(),
1734 uc, brk);
1735 break;
1736 case brkNONE:
1737 set_cell_flag(addr, true, CELL_FETCH_BRK);
1738 return;
1739 break;
1740 default:
1741 //e= '.';
1742 op= 0;
1743 break;
1744 }
1745 if (op)
1746 cell->append_operator(op);
1747 }
1748
1749 void
del_brk(t_addr addr,class cl_brk * brk)1750 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1751 {
1752 t_addr idx= addr-start_address;
1753 if (idx >= size ||
1754 addr < start_address)
1755 return;
1756 class cl_memory_cell *cell= &cella[idx];
1757
1758 switch (brk->get_event())
1759 {
1760 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1761 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1762 cell->del_operator(brk);
1763 break;
1764 case brkNONE:
1765 set_cell_flag(addr, false, CELL_FETCH_BRK);
1766 return;
1767 break;
1768 default:
1769 break;
1770 }
1771 }
1772
1773 void
print_info(chars pre,class cl_console_base * con)1774 cl_address_space::print_info(chars pre, class cl_console_base *con)
1775 {
1776 char *n= (char*)(get_name());
1777 if (!hidden)
1778 {
1779 con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
1780 AU(get_start_address()),
1781 AU(highest_valid_address()),
1782 AU(get_size()),
1783 n,
1784 width, data_format, addr_format);
1785 }
1786 }
1787
1788
1789 /*
1790 * List of address spaces
1791 */
1792
cl_address_space_list(class cl_uc * the_uc)1793 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1794 cl_list(2, 2, "address spaces")
1795 {
1796 uc= the_uc;
1797 }
1798
1799 t_index
add(class cl_address_space * mem)1800 cl_address_space_list::add(class cl_address_space *mem)
1801 {
1802 mem->set_uc(uc);
1803 t_index ret= cl_list::add(mem);
1804 if (uc)
1805 {
1806 class cl_event_address_space_added e(mem);
1807 uc->handle_event(e);
1808 }
1809 return(ret);
1810 }
1811
1812
1813 /*
1814 * Memory chip
1815 */
1816
cl_memory_chip(const char * id,int asize,int awidth,int initial)1817 cl_memory_chip::cl_memory_chip(const char *id,
1818 int asize,
1819 int awidth,
1820 int initial):
1821 cl_memory(id, asize, awidth)
1822 {
1823 array= (t_mem *)malloc(size * sizeof(t_mem));
1824 init_value= initial;
1825 array_is_mine= true;
1826 }
1827
cl_memory_chip(const char * id,int asize,int awidth,t_mem * aarray)1828 cl_memory_chip::cl_memory_chip(const char *id,
1829 int asize,
1830 int awidth,
1831 t_mem *aarray):
1832 cl_memory(id, asize, awidth)
1833 {
1834 array= aarray;
1835 init_value= 0;
1836 array_is_mine= false;
1837 }
1838
~cl_memory_chip(void)1839 cl_memory_chip::~cl_memory_chip(void)
1840 {
1841 if (array &&
1842 array_is_mine)
1843 free(array);
1844 }
1845
1846 int
init(void)1847 cl_memory_chip::init(void)
1848 {
1849 cl_memory::init();
1850 int i;
1851 if (array_is_mine)
1852 {
1853 for (i= 0; i < size; i++)
1854 set(i,
1855 (init_value<0)?rand():(init_value)
1856 );
1857 }
1858 return(0);
1859 }
1860
1861
1862 t_mem *
get_slot(t_addr addr)1863 cl_memory_chip::get_slot(t_addr addr)
1864 {
1865 if (!array ||
1866 size <= addr)
1867 return(0);
1868 return(&array[addr]);
1869 }
1870
1871 t_addr
is_slot(t_mem * data_ptr)1872 cl_memory_chip::is_slot(t_mem *data_ptr)
1873 {
1874 if (data_ptr < &(array[0]))
1875 return -1;
1876 if (data_ptr > &(array[size-1]))
1877 return -2;
1878 return data_ptr - &(array[0]);
1879 }
1880
1881 t_mem
get(t_addr addr)1882 cl_memory_chip::get(t_addr addr)
1883 {
1884 if (!array ||
1885 size <= addr)
1886 return(0);
1887 return(array[addr]);
1888 }
1889
1890 void
set(t_addr addr,t_mem val)1891 cl_memory_chip::set(t_addr addr, t_mem val)
1892 {
1893 if (!array ||
1894 size <= addr)
1895 return;
1896 array[addr]= val & data_mask;
1897 }
1898
1899 void
set_bit1(t_addr addr,t_mem bits)1900 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1901 {
1902 if (!array ||
1903 size <= addr)
1904 return;
1905 array[addr]|= (bits & data_mask);
1906 }
1907
1908 void
set_bit0(t_addr addr,t_mem bits)1909 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1910 {
1911 if (!array ||
1912 size <= addr)
1913 return;
1914 array[addr]&= ((~bits) & data_mask);
1915 }
1916
1917 void
print_info(chars pre,class cl_console_base * con)1918 cl_memory_chip::print_info(chars pre, class cl_console_base *con)
1919 {
1920 char *n= (char*)(get_name());
1921 if (!hidden)
1922 {
1923 //con->dd_printf(pre0);
1924 con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
1925 AU(get_start_address()),
1926 AU(highest_valid_address()),
1927 AU(get_size()),
1928 n,
1929 width, data_format, addr_format);
1930 }
1931 }
1932
1933
1934 /*
1935 * Address decoder
1936 */
1937
cl_address_decoder(class cl_memory * as,class cl_memory * chip,t_addr asb,t_addr ase,t_addr cb)1938 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1939 class cl_memory *chip,
1940 t_addr asb, t_addr ase, t_addr cb)
1941 {
1942 if (as && (as->is_address_space()))
1943 address_space= (class cl_address_space *)as;
1944 else
1945 address_space= 0;
1946 if (chip && (chip->is_chip()))
1947 memchip= (class cl_memory_chip *)chip;
1948 else
1949 memchip= 0;
1950 as_begin= asb;
1951 as_end= ase;
1952 chip_begin= cb;
1953 activated= false;
1954 }
1955
~cl_address_decoder(void)1956 cl_address_decoder::~cl_address_decoder(void)
1957 {
1958 t_addr a;
1959 if (address_space)
1960 for (a= as_begin; a <= as_end; a++)
1961 address_space->undecode_cell(a);
1962 }
1963
1964 int
init(void)1965 cl_address_decoder::init(void)
1966 {
1967 return(0);
1968 }
1969
1970
1971 bool
activate(class cl_console_base * con)1972 cl_address_decoder::activate(class cl_console_base *con)
1973 {
1974 #define D if (con) con->debug
1975 //#define D printf
1976 D("Activation of an address decoder %s (%s[%06lx-%06lx]\n", get_name(""), address_space->get_name(), as_begin, as_end);
1977 if (activated)
1978 {
1979 D("Already activated\n");
1980 return(false);
1981 }
1982 if (!address_space ||
1983 !address_space->is_address_space())
1984 {
1985 D("No or non address space\n");
1986 return(false);
1987 }
1988 if (!memchip ||
1989 !memchip->is_chip())
1990 {
1991 D("No or non memory chip\n");
1992 return(false);
1993 }
1994 if (as_begin > as_end)
1995 {
1996 D("Wrong address area specification\n");
1997 return(false);
1998 }
1999 if (chip_begin >= memchip->get_size())
2000 {
2001 D("Wrong chip area specification\n");
2002 return(false);
2003 }
2004 if (as_begin < address_space->start_address ||
2005 as_end >= address_space->start_address + address_space->get_size())
2006 {
2007 D("Specified area is out of address space\n");
2008 return(false);
2009 }
2010 if (as_end-as_begin > memchip->get_size()-chip_begin)
2011 {
2012 D("Specified area is out of chip size\n");
2013 return(false);
2014 }
2015
2016 address_space->undecode_area(this, as_begin, as_end, con);
2017
2018 D("Decoder maps %s[%06lx-%06lx] -> %s[%06lx]...\n",address_space->get_name(),as_begin,as_end,memchip->get_name(),chip_begin);
2019 t_addr asa, ca;
2020 for (asa= as_begin, ca= chip_begin;
2021 asa <= as_end;
2022 asa++, ca++)
2023 {
2024 if (!address_space->decode_cell(asa, memchip, ca))
2025 {
2026 D("Decoding 0x%06lx->0x%06lx failed\n", asa, ca);
2027 }
2028 }
2029 activated= true;
2030
2031 #undef D
2032 return(activated);
2033 }
2034
2035 /* Check if this DEC is fully within the specified area
2036
2037 as_begin....................as_end
2038 ^ ^
2039 begin end
2040
2041 */
2042
2043 bool
fully_covered_by(t_addr begin,t_addr end)2044 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
2045 {
2046 if (begin <= as_begin &&
2047 end >= as_end)
2048 return(true);
2049 return(false);
2050 }
2051
2052 /* Check if some part of this DEC is in the specified area:
2053
2054 as_begin......................as_end
2055 ^ ^
2056 begin end
2057
2058 as_begin......................as_end
2059 ^ ^
2060 begin end
2061
2062 */
2063
2064 bool
is_in(t_addr begin,t_addr end)2065 cl_address_decoder::is_in(t_addr begin, t_addr end)
2066 {
2067 if (begin >= as_begin &&
2068 begin <= as_end)
2069 return(true);
2070 if (end >= as_begin &&
2071 end <= as_end)
2072 return(true);
2073 return(false);
2074 }
2075
2076 /* Check if this DEC covers the specified area:
2077
2078 as_begin....................as_end
2079 ^ ^
2080 begin end
2081
2082 */
2083
2084 bool
covers(t_addr begin,t_addr end)2085 cl_address_decoder::covers(t_addr begin, t_addr end)
2086 {
2087 if (begin >= as_begin &&
2088 end <= as_end)
2089 return(true);
2090 return(false);
2091 }
2092
2093
2094 /* Returns TRUE if shrunken decoder is unnecessary */
2095
2096 bool
shrink_out_of(t_addr begin,t_addr end)2097 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
2098 {
2099 t_addr a= as_begin;
2100
2101 if (!address_space)
2102 return(true);
2103 if (begin > a)
2104 a= begin;
2105 while (a <= end &&
2106 a <= as_end)
2107 {
2108 address_space->undecode_cell(a);
2109 a++;
2110 }
2111 if (begin > as_begin)
2112 as_end= begin-1;
2113 if (as_end > end)
2114 {
2115 chip_begin+= (end-as_begin+1);
2116 as_begin= end+1;
2117 }
2118 if (as_end < as_begin)
2119 return(true);
2120 return(false);
2121 }
2122
2123 class cl_address_decoder *
split(t_addr begin,t_addr end)2124 cl_address_decoder::split(t_addr begin, t_addr end)
2125 {
2126 class cl_address_decoder *nd= 0;
2127 if (begin > as_begin)
2128 {
2129 if (as_end > end)
2130 nd= new cl_address_decoder(address_space, memchip,
2131 end+1, as_end, chip_begin+(end-as_begin)+1);
2132 shrink_out_of(begin, as_end);
2133 }
2134 else if (end < as_end)
2135 {
2136 if (as_begin < begin)
2137 nd= new cl_address_decoder(address_space, memchip,
2138 as_begin, begin-1, chip_begin);
2139 shrink_out_of(as_begin, end);
2140 }
2141 if (nd)
2142 nd->init();
2143 return(nd);
2144 }
2145
2146 void
print_info(chars pre,class cl_console_base * con)2147 cl_address_decoder::print_info(chars pre, class cl_console_base *con)
2148 {
2149 if (address_space &&
2150 address_space->hidden)
2151 return;
2152 if (memchip &&
2153 memchip->hidden)
2154 return;
2155 con->dd_printf(pre);
2156 if (address_space)
2157 {
2158 con->dd_printf("%s ", address_space->get_name("unknown"));
2159 con->dd_printf(address_space->addr_format, as_begin);
2160 con->dd_printf(" ");
2161 con->dd_printf(address_space->addr_format, as_end);
2162 }
2163 else
2164 con->dd_printf("x");
2165 con->dd_printf(" -> ");
2166 if (memchip)
2167 {
2168 con->dd_printf("%s ", memchip->get_name("unknown"));
2169 con->dd_printf(memchip->addr_format, chip_begin);
2170 }
2171 else
2172 con->dd_printf("x");
2173 con->dd_printf(" %s\n", (activated)?"activated":"inactive");
2174 }
2175
2176
2177 /*
2178 * Bank switcher
2179 */
2180
cl_banker(class cl_address_space * the_banker_as,t_addr the_banker_addr,t_mem the_banker_mask,class cl_address_space * the_as,t_addr the_asb,t_addr the_ase)2181 cl_banker::cl_banker(class cl_address_space *the_banker_as,
2182 t_addr the_banker_addr,
2183 t_mem the_banker_mask,
2184 //int the_banker_shift,
2185 class cl_address_space *the_as,
2186 t_addr the_asb,
2187 t_addr the_ase):
2188 cl_address_decoder(the_as, NULL, the_asb, the_ase, (t_addr)-1)
2189 {
2190 banker_as= the_banker_as;
2191 banker_addr= the_banker_addr;
2192 banker_mask= the_banker_mask;
2193 //banker_shift= the_banker_shift;
2194 banker2_as= NULL;
2195 banker2_addr= 0;
2196 banker2_mask= 0;
2197 banker2_shift= 0;
2198 nuof_banks= 0;
2199 banks= 0;
2200 //bank_ptrs= 0;
2201 bank= -1;
2202 }
2203
cl_banker(class cl_address_space * the_banker_as,t_addr the_banker_addr,t_mem the_banker_mask,class cl_address_space * the_banker2_as,t_addr the_banker2_addr,t_mem the_banker2_mask,int the_banker2_shift,class cl_address_space * the_as,t_addr the_asb,t_addr the_ase)2204 cl_banker::cl_banker(class cl_address_space *the_banker_as,
2205 t_addr the_banker_addr,
2206 t_mem the_banker_mask,
2207 //int the_banker_shift,
2208 class cl_address_space *the_banker2_as,
2209 t_addr the_banker2_addr,
2210 t_mem the_banker2_mask,
2211 int the_banker2_shift,
2212 class cl_address_space *the_as,
2213 t_addr the_asb,
2214 t_addr the_ase):
2215 cl_address_decoder(the_as, NULL, the_asb, the_ase, (t_addr)-1)
2216 {
2217 banker_as= the_banker_as;
2218 banker_addr= the_banker_addr;
2219 banker_mask= the_banker_mask;
2220 //banker_shift= the_banker_shift;
2221 banker2_as= the_banker2_as;
2222 banker2_addr= the_banker2_addr;
2223 banker2_mask= the_banker2_mask;
2224 banker2_shift= the_banker2_shift;
2225 nuof_banks= 0;
2226 banks= 0;
2227 //bank_ptrs= 0;
2228 bank= -1;
2229 }
2230
2231 int
init()2232 cl_banker::init()
2233 {
2234 int m= banker_mask;
2235 int b, b2;
2236
2237 shift_by= 0;
2238 shift2_by= 0;
2239 if (m == 0)
2240 nuof_banks= 0;
2241 else
2242 {
2243 while ((m&1) == 0)
2244 m>>= 1, shift_by++;
2245 b= 1;
2246 m>>= 1;
2247 while ((m&1) != 0)
2248 {
2249 m>>= 1;
2250 b++;
2251 }
2252 nuof_banks= 1 << b;
2253 }
2254 shift2_by= 0;
2255 if (banker2_as &&
2256 banker2_mask)
2257 {
2258 m= banker2_mask;
2259 while ((m&1) == 0)
2260 m>>=1, shift2_by++;
2261 b2= 1;
2262 m>>= 1;
2263 while ((m&1) != 0)
2264 m>>= 1, b2++;
2265 if (b2)
2266 nuof_banks*= (1 << b2);
2267 }
2268 if (nuof_banks > 0)
2269 {
2270 banks= (class cl_address_decoder **)malloc(nuof_banks * sizeof(class cl_address_decoder *));
2271 //bank_ptrs= (t_mem **)calloc(nuof_banks*(as_end-as_begin+1), sizeof(t_mem *));
2272 for (b= 0; b < nuof_banks; b++)
2273 {
2274 banks[b]= NULL;
2275 }
2276 }
2277
2278 class cl_memory_cell *c= banker_as->get_cell(banker_addr);
2279 if (c)
2280 {
2281 class cl_bank_switcher_operator *o=
2282 new cl_bank_switcher_operator(c/*, banker_addr*/, this);
2283 c->prepend_operator(o);
2284 }
2285 if (banker2_as &&
2286 banker2_mask)
2287 {
2288 c= banker2_as->get_cell(banker2_addr);
2289 if (c)
2290 {
2291 class cl_bank_switcher_operator *o=
2292 new cl_bank_switcher_operator(c/*, banker_addr*/, this);
2293 c->prepend_operator(o);
2294 }
2295 }
2296 return 0;
2297 }
2298
~cl_banker()2299 cl_banker::~cl_banker()
2300 {
2301 int i;
2302 if (banks)
2303 {
2304 for (i= 0; i < nuof_banks; i++)
2305 {
2306 if (banks[i])
2307 delete banks[i];
2308 }
2309 free(banks);
2310 }
2311 //if (bank_ptrs) free(bank_ptrs);
2312 }
2313
2314 void
add_bank(int bank_nr,class cl_memory * chip,t_addr chip_start)2315 cl_banker::add_bank(int bank_nr, class cl_memory *chip, t_addr chip_start)
2316 {
2317 if (!chip)
2318 return;
2319 if (!address_space)
2320 return;
2321 if (!chip->is_chip())
2322 return;
2323
2324 if (bank_nr >= nuof_banks)
2325 return;
2326
2327 class cl_address_decoder *ad= new cl_address_decoder(address_space,
2328 chip,
2329 as_begin, as_end,
2330 chip_start);
2331 ad->init();
2332 if (banks[bank_nr])
2333 {
2334 delete banks[bank_nr];
2335 banks[bank_nr]= 0;
2336 }
2337 banks[bank_nr]= ad;
2338 /*
2339 t_addr a, s, i;
2340 s= as_end - as_begin + 1;
2341 for (i= 0; i < s; i++)
2342 {
2343 a= chip_start + i;
2344 //bank_ptrs[bank_nr*s + i]= ad->memchip->get_slot(a);
2345 }
2346 */
2347 activate(0);
2348 }
2349
2350 t_mem
actual_bank()2351 cl_banker::actual_bank()
2352 {
2353 //t_mem m= banker_mask;
2354 t_mem v= banker_as->read(banker_addr) & banker_mask;
2355 t_mem v2;
2356
2357 v= (v >> shift_by);
2358 if (banker2_as &&
2359 banker2_mask)
2360 {
2361 v2= banker2_as->read(banker2_addr) & banker2_mask;
2362 v2>>= shift2_by;
2363 v2= v2 << banker2_shift;
2364 v= v | v2;
2365 }
2366 return v;
2367 }
2368
2369 bool
activate(class cl_console_base * con)2370 cl_banker::activate(class cl_console_base *con)
2371 {
2372 int b= actual_bank();
2373 t_addr i, s;
2374 t_mem *data;
2375 class cl_memory_cell *c;
2376
2377 if (b == bank)
2378 return true;
2379 if (banks[b] == NULL)
2380 return true;
2381 s= as_end - as_begin + 1;
2382 for (i= 0; i < s; i++)
2383 {
2384 t_addr ca= banks[b]->chip_begin + i;
2385 data= banks[b]->memchip->get_slot(ca);
2386 c= address_space->get_cell(as_begin+i);
2387 c->decode(data);
2388 }
2389 bank= b;
2390
2391 return true;
2392 }
2393
2394 bool
switch_to(int bank_nr,class cl_console_base * con)2395 cl_banker::switch_to(int bank_nr, class cl_console_base *con)
2396 {
2397 int b= bank_nr;//actual_bank();
2398 t_addr i, s;
2399 t_mem *data;
2400 class cl_memory_cell *c;
2401
2402 if (b == bank)
2403 return true;
2404 if (banks[b] == NULL)
2405 return true;
2406 s= as_end - as_begin + 1;
2407 for (i= 0; i < s; i++)
2408 {
2409 t_addr ca= banks[b]->chip_begin + i;
2410 data= banks[b]->memchip->get_slot(ca);
2411 c= address_space->get_cell(as_begin+i);
2412 c->decode(data);
2413 }
2414 bank= b;
2415
2416 return true;
2417 }
2418
2419 void
print_info(chars pre,class cl_console_base * con)2420 cl_banker::print_info(chars pre, class cl_console_base *con)
2421 {
2422 int b;
2423 con->dd_printf(pre);
2424 //con->dd_printf(" banked area= ");
2425 if (address_space)
2426 {
2427 con->dd_printf("%s ", address_space->get_name("unknown"));
2428 con->dd_printf(address_space->addr_format, as_begin);
2429 con->dd_printf(" ");
2430 con->dd_printf(address_space->addr_format, as_end);
2431 }
2432 else
2433 con->dd_printf("x");
2434 con->dd_printf(" -> banked\n");
2435
2436 con->dd_printf(pre);
2437 con->dd_printf(" bank selector: %s[", banker_as->get_name("unknown"));
2438 con->dd_printf(banker_as->addr_format, banker_addr);
2439 con->dd_printf("] mask=0x%x banks=%d act=%d\n",
2440 banker_mask, nuof_banks,
2441 b= actual_bank());
2442
2443 con->dd_printf(pre);
2444 con->dd_printf(" banks:\n");
2445
2446 class cl_address_decoder *dc;
2447 int i;
2448 for (i= 0; i < nuof_banks; i++)
2449 {
2450 dc= (class cl_address_decoder *)(banks[i]);
2451 con->dd_printf(pre);
2452 con->dd_printf(" %c %2d. ", (b==i)?'*':' ', i);
2453 if (dc)
2454 {
2455 if (dc->memchip)
2456 {
2457 con->dd_printf("%s ", dc->memchip->get_name("unknown"));
2458 con->dd_printf(dc->memchip->addr_format, dc->chip_begin);
2459 }
2460 else
2461 con->dd_printf("x");
2462 }
2463 else
2464 con->dd_printf("-");
2465 con->dd_printf("\n");
2466 }
2467 }
2468
2469
2470 /*
2471 * Bit bander
2472 */
2473
cl_bander(class cl_address_space * the_as,t_addr the_asb,t_addr the_ase,class cl_memory * the_chip,t_addr the_cb,int the_bpc,int the_distance)2474 cl_bander::cl_bander(class cl_address_space *the_as,
2475 t_addr the_asb,
2476 t_addr the_ase,
2477 class cl_memory *the_chip,
2478 t_addr the_cb,
2479 int the_bpc,
2480 int the_distance):
2481 cl_address_decoder(the_as, the_chip, the_asb, the_ase, the_cb)
2482 {
2483 bpc= the_bpc;
2484 distance= the_distance;
2485 }
2486
2487 bool
activate(class cl_console_base * con)2488 cl_bander::activate(class cl_console_base *con)
2489 {
2490 address_space->undecode_area(this, as_begin, as_end, con);
2491
2492 t_addr asa, ca;
2493 int b, m;
2494 for (asa= as_begin, ca= chip_begin, b= 0, m= 1;
2495 asa <= as_end;
2496 asa++)
2497 {
2498 if (b >= bpc)
2499 {
2500 ca+= distance;
2501 b= 0;
2502 m= 1;
2503 }
2504 t_mem *slot= memchip->get_slot(ca);
2505 cl_memory_cell *c= address_space->get_cell(asa);
2506 c->decode(slot, m);
2507 b++;
2508 m<<= 1;
2509 }
2510 return activated= true;
2511 }
2512
2513 void
print_info(chars pre,class cl_console_base * con)2514 cl_bander::print_info(chars pre, class cl_console_base *con)
2515 {
2516 if (address_space &&
2517 address_space->hidden)
2518 return;
2519 if (memchip &&
2520 memchip->hidden)
2521 return;
2522 con->dd_printf(pre);
2523 if (address_space)
2524 {
2525 con->dd_printf("%s ", address_space->get_name("unknown"));
2526 con->dd_printf(address_space->addr_format, as_begin);
2527 con->dd_printf(" ");
2528 con->dd_printf(address_space->addr_format, as_end);
2529 }
2530 else
2531 con->dd_printf("x");
2532 con->dd_printf(" -> bander(%d/%d) ", bpc, distance);
2533 if (memchip)
2534 {
2535 con->dd_printf("%s ", memchip->get_name("unknown"));
2536 con->dd_printf(memchip->addr_format, chip_begin);
2537 }
2538 else
2539 con->dd_printf("x");
2540 con->dd_printf(" %s\n", (activated)?"activated":"inactive");
2541 }
2542
2543
2544 /*
2545 * List of address decoders
2546 */
2547
cl_decoder_list(t_index alimit,t_index adelta,bool bychip)2548 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
2549 cl_sorted_list(alimit, adelta, "decoder list")
2550 {
2551 Duplicates= true;
2552 by_chip= bychip;
2553 }
2554
2555 void *
key_of(void * item)2556 cl_decoder_list::key_of(void *item)
2557 {
2558 class cl_address_decoder *d= (class cl_address_decoder *)item;
2559 if (by_chip)
2560 return(&(d->chip_begin));
2561 else
2562 return(&(d->as_begin));
2563 }
2564
2565 int
compare(void * key1,void * key2)2566 cl_decoder_list::compare(void *key1, void *key2)
2567 {
2568 t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
2569 if (k1 == k2)
2570 return(0);
2571 else if (k1 > k2)
2572 return(1);
2573 return(-1);
2574 }
2575
2576
2577 /*
2578 * Errors in memory handling
2579 */
2580
2581 /* All of memory errors */
2582
cl_error_mem(class cl_memory * amem,t_addr aaddr)2583 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
2584 {
2585 mem= amem;
2586 addr= aaddr;
2587 classification= mem_error_registry.find("memory");
2588 }
2589
2590 /* Invalid address in memory access */
2591
2592 cl_error_mem_invalid_address::
cl_error_mem_invalid_address(class cl_memory * amem,t_addr aaddr)2593 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
2594 cl_error_mem(amem, aaddr)
2595 {
2596 classification= mem_error_registry.find("invalid_address");
2597 }
2598
2599 void
print(class cl_commander_base * c)2600 cl_error_mem_invalid_address::print(class cl_commander_base *c)
2601 {
2602 //FILE *f= c->get_fout();
2603 /*cmd_fprintf(f,*/c->dd_printf("%s: invalid address ", get_type_name());
2604 /*cmd_fprintf(f,*/c->dd_printf(mem->addr_format, addr);
2605 /*cmd_fprintf(f,*/c->dd_printf(" in memory %s.\n", mem->get_name());
2606 }
2607
2608 /* Non-decoded address space access */
2609
2610 cl_error_mem_non_decoded::
cl_error_mem_non_decoded(class cl_memory * amem,t_addr aaddr)2611 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
2612 cl_error_mem(amem, aaddr)
2613 {
2614 classification= mem_error_registry.find("non_decoded");
2615 }
2616
2617 void
print(class cl_commander_base * c)2618 cl_error_mem_non_decoded::print(class cl_commander_base *c)
2619 {
2620 //FILE *f= c->get_fout();
2621 /*cmd_fprintf(f,*/c->dd_printf("%s: access of non-decoded address ", get_type_name());
2622 /*cmd_fprintf(f,*/c->dd_printf(mem->addr_format, addr);
2623 /*cmd_fprintf(f,*/c->dd_printf(" in memory %s.\n", mem->get_name());
2624 }
2625
cl_mem_error_registry(void)2626 cl_mem_error_registry::cl_mem_error_registry(void)
2627 {
2628 class cl_error_class *prev = mem_error_registry.find("non-classified");
2629 prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
2630 prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
2631 prev = register_error(new cl_error_class(err_error, "non_decoded", prev));
2632 }
2633
2634 /* End of mem.cc */
2635