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