* sim/ucsim/error.cc, sim/ucsim/errorcl.h,
[fw/sdcc] / sim / ucsim / sim.src / mem.cc
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 "i_string.h"
34
35 // prj
36 #include "utils.h"
37 #include "globals.h"
38
39 // sim
40 #include "simcl.h"
41
42 // cmd
43 #include "newcmdcl.h"
44 #include "cmdutil.h"
45
46 // local
47 #include "memcl.h"
48 #include "hwcl.h"
49
50
51 static class cl_mem_error_registry mem_error_registry;
52
53 /*
54  *                                                3rd version of memory system
55  */
56
57 cl_memory::cl_memory(char *id, t_addr asize, int awidth):
58   cl_base()
59 {
60   size= asize;
61   set_name(id);
62   addr_format= data_format= 0;
63   width= awidth;
64   start_address= 0;
65   uc= 0;
66 }
67
68 cl_memory::~cl_memory(void)
69 {
70   if (addr_format)
71     free(addr_format);
72   if (data_format)
73     free(data_format);
74 }
75
76 int
77 cl_memory::init(void)
78 {
79   addr_format= (char *)malloc(10);
80   sprintf(addr_format, "0x%%0%dx",
81           size-1<=0xf?1:
82           (size-1<=0xff?2:
83            (size-1<=0xfff?3:
84             (size-1<=0xffff?4:
85              (size-1<=0xfffff?5:
86               (size-1<=0xffffff?6:12))))));
87   data_format= (char *)malloc(10);
88   sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
89   data_mask= 1;
90   int w= width;
91   for (--w; w; w--)
92     {
93       data_mask<<= 1;
94       data_mask|= 1;
95     }
96   dump_finished= start_address;
97   return(0);
98 }
99
100
101 bool
102 cl_memory::valid_address(t_addr addr)
103 {
104   return(addr >= start_address &&
105          addr < start_address+size);
106 }
107
108 t_addr
109 cl_memory::inc_address(t_addr addr, int val)
110 {
111   if (!start_address)
112     return(((signed)addr+val)%size);
113   addr-= start_address;
114   addr+= val;
115   addr%= size;
116   addr+= start_address;
117   return(addr);
118 }
119
120 t_addr
121 cl_memory::inc_address(t_addr addr)
122 {
123   if (!start_address)
124     return(((signed)addr+1)%size);
125   addr-= start_address;
126   addr++;
127   addr%= size;
128   addr+= start_address;
129   return(addr);
130 }
131
132 t_addr
133 cl_memory::validate_address(t_addr addr)
134 {
135   while (addr < start_address)
136     addr+= size;
137   if (addr > start_address+size)
138     {
139       addr-= start_address;
140       addr%= size;
141       addr+= start_address;
142     }
143   return(addr);
144 }
145
146
147 void
148 cl_memory::err_inv_addr(t_addr addr)
149 {
150   if (!uc)
151     return;
152   class cl_error *e= new cl_error_mem_invalid_address(this, addr);
153   uc->error(e);
154 }
155
156 void
157 cl_memory::err_non_decoded(t_addr addr)
158 {
159   if (!uc)
160     return;
161   class cl_error *e= new cl_error_mem_non_decoded(this, addr);
162   uc->error(e);
163 }
164
165
166 t_addr
167 cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
168 {
169   int i;
170   t_addr lva= lowest_valid_address();
171   t_addr hva= highest_valid_address();
172
173   if (start < lva)
174     start= lva;
175   if (stop > hva)
176     stop= hva;
177   while ((start <= stop) &&
178          (start < hva))
179     {
180       con->dd_printf(addr_format, start); con->dd_printf(" ");
181       for (i= 0;
182            (i < bpl) &&
183              (start+i < hva) &&
184              (start+i <= stop);
185            i++)
186         {
187           con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
188         }
189       while (i < bpl)
190         {
191           int j;
192           j= width/4 + ((width%4)?1:0) + 1;
193           while (j)
194             {
195               con->dd_printf(" ");
196               j--;
197             }
198           i++;
199         }
200       for (i= 0; (i < bpl) &&
201              (start+i < hva) &&
202              (start+i <= stop);
203            i++)
204         {
205           long c= read(start+i);
206           con->dd_printf("%c", isprint(255&c)?(255&c):'.');
207           if (width > 8)
208             con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
209           if (width > 16)
210             con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
211           if (width > 24)
212             con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
213         }
214       con->dd_printf("\n");
215       dump_finished= start+i;
216       start+= bpl;
217     }
218   return(dump_finished);
219 }
220
221 t_addr
222 cl_memory::dump(class cl_console *con)
223 {
224   return(dump(dump_finished, dump_finished+10*8-1, 8, con));
225 }
226
227 bool
228 cl_memory::search_next(bool case_sensitive,
229                        t_mem *array, int len, t_addr *addr)
230 {
231   t_addr a;
232   int i;
233   bool found;
234
235   if (addr == NULL)
236     a= 0;
237   else
238     a= *addr;
239   
240   if (a+len > size)
241     return(DD_FALSE);
242
243   found= DD_FALSE;
244   while (!found &&
245          a+len <= size)
246     {
247       bool match= DD_TRUE;
248       for (i= 0; i < len && match; i++)
249         {
250           t_mem d1, d2;
251           d1= get(a+i);
252           d2= array[i];
253           if (!case_sensitive)
254             {
255               if (/*d1 < 128*/isalpha(d1))
256                 d1= toupper(d1);
257               if (/*d2 < 128*/isalpha(d2))
258                 d2= toupper(d2);
259             }
260           match= d1 == d2;
261         }
262       found= match;
263       if (!found)
264         a++;
265     }
266
267   if (addr)
268     *addr= a;
269   return(found);
270 }
271
272
273 /*
274  *                                                             Memory operators
275  */
276
277 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
278                                        t_addr addr):
279   cl_base()
280 {
281   cell= acell;
282   data= 0;
283   mask= ~0;
284   next_operator= 0;
285   address= addr;
286 }
287
288 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
289                                        t_addr addr,
290                                        t_mem *data_place, t_mem the_mask):
291   cl_base()
292 {
293   cell= acell;
294   data= data_place;
295   mask= the_mask;
296   next_operator= 0;
297   address= addr;
298 }
299
300 void
301 cl_memory_operator::set_data(t_mem *data_place, t_mem the_mask)
302 {
303   data= data_place;
304   mask= the_mask;
305 }
306
307
308 t_mem
309 cl_memory_operator::read(void)
310 {
311   if (next_operator)
312     return(next_operator->read());
313   else
314     return(*data);
315 }
316
317 t_mem
318 cl_memory_operator::write(t_mem val)
319 {
320   if (next_operator)
321     return(next_operator->write(val));
322   else
323     return(*data= (val & mask));
324 }
325
326
327 /* Memory operator for hw callbacks */
328
329 cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell, t_addr addr,
330                                t_mem *data_place, t_mem the_mask,
331                                class cl_hw *ahw):
332   cl_memory_operator(acell, addr, data_place, the_mask)
333 {
334   hw= ahw;
335 }
336
337
338 t_mem
339 cl_hw_operator::read(void)
340 {
341   t_mem d= 0;
342
343   if (hw)
344     d= hw->read(cell);
345
346   if (next_operator)
347     next_operator->read();
348
349   return(d);
350 }
351
352 t_mem
353 cl_hw_operator::read(enum hw_cath skip)
354 {
355   t_mem d= *data;
356
357   if (hw &&
358       hw->cathegory != skip)
359     d= hw->read(cell);
360
361   if (next_operator)
362     next_operator->read();
363
364   return(d);  
365 }
366
367 t_mem
368 cl_hw_operator::write(t_mem val)
369 {
370   if (hw)
371     hw->write(cell, &val);
372   if (next_operator)
373     val= next_operator->write(val);
374   return(*data= (val & mask));
375 }
376
377
378 /* Write event break on cell */
379
380 cl_write_operator::cl_write_operator(class cl_memory_cell *acell, t_addr addr,
381                                      t_mem *data_place, t_mem the_mask,
382                                      class cl_uc *auc, class cl_brk *the_bp):
383   cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
384 {
385   uc= auc;
386   bp= the_bp;
387 }
388
389 t_mem
390 cl_write_operator::write(t_mem val)
391 {
392   //printf("write event at 0x%x bp=%p\n",address,bp);
393   uc->events->add(bp);
394   if (next_operator)
395     return(next_operator->write(val));
396   else
397     return(*data= (val & mask));
398 }
399
400
401 /* Read event break on cell */
402
403 cl_read_operator::cl_read_operator(class cl_memory_cell *acell, t_addr addr,
404                                    t_mem *data_place, t_mem the_mask,
405                                    class cl_uc *auc, class cl_brk *the_bp):
406   cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
407 {
408   uc= auc;
409   bp= the_bp;
410 }
411
412 t_mem
413 cl_read_operator::read(void)
414 {
415   //printf("read event at 0x%x bp=%p\n",address,bp);
416   uc->events->add(bp);
417   if (next_operator)
418     return(next_operator->read());
419   else
420     return(*data);
421 }
422
423
424 /*
425  *                                                                  Memory cell
426  */
427
428 cl_memory_cell::cl_memory_cell(void):
429   cl_base()
430 {
431   data= (t_mem *)malloc(sizeof(t_mem));
432   flags= CELL_NON_DECODED;
433   width= 8;
434   *data= 0;
435   operators= NULL;
436
437 #ifdef STATISTIC
438   nuof_writes= nuof_reads= 0;
439 #endif
440
441   mask= 1;
442   int w= width;
443   for (--w; w; w--)
444     {
445       mask<<= 1;
446       mask|= 1;
447     }
448 }
449
450 cl_memory_cell::~cl_memory_cell(void)
451 {
452   if ((flags & CELL_NON_DECODED) &&
453       data)
454     free(data);
455 }
456
457 int
458 cl_memory_cell::init(void)
459 {
460   cl_base::init();
461   set(0/*rand()*/);
462   return(0);
463 }
464
465
466 TYPE_UBYTE
467 cl_memory_cell::get_flags(void)
468 {
469   return(flags);
470 }
471
472 bool
473 cl_memory_cell::get_flag(enum cell_flag flag)
474 {
475   return(flags & flag);
476 }
477
478 void
479 cl_memory_cell::set_flags(TYPE_UBYTE what)
480 {
481   flags= what;
482 }
483
484 void
485 cl_memory_cell::set_flag(enum cell_flag flag, bool val)
486 {
487   if (val)
488     flags|= flag;
489   else
490     flags&= ~(flag);
491 }
492
493
494 void
495 cl_memory_cell::un_decode(void)
496 {
497   if ((flags & CELL_NON_DECODED) == 0)
498     {
499       data= (t_mem *)malloc(sizeof(t_mem));
500       flags|= CELL_NON_DECODED;
501     }
502 }
503
504 void
505 cl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr)
506 {
507   if (flags & CELL_NON_DECODED)
508     free(data);
509   data= chip->get_slot(addr);
510   if (!data)
511     {
512       data= (t_mem *)malloc(sizeof(t_mem));
513       flags|= CELL_NON_DECODED;
514     }
515   else
516     flags&= ~(CELL_NON_DECODED);
517 }
518
519
520 t_mem
521 cl_memory_cell::read(void)
522 {
523 #ifdef STATISTIC
524   nuof_reads++;
525 #endif
526   if (operators)
527     return(operators->read());
528   return(*data);
529 }
530
531 t_mem
532 cl_memory_cell::read(enum hw_cath skip)
533 {
534 #ifdef STATISTIC
535   nuof_reads++;
536 #endif
537   if (operators)
538     return(operators->read(skip));
539   return(*data);
540 }
541  
542 t_mem
543 cl_memory_cell::get(void) 
544 {
545   return(*data);
546 }
547
548 t_mem
549 cl_memory_cell::write(t_mem val)
550 {
551 #ifdef STATISTIC
552   nuof_writes++;
553 #endif
554   if (operators)
555     return(operators->write(val));
556   *data= val & mask;
557   return(*data);
558 }
559
560 t_mem
561 cl_memory_cell::set(t_mem val)
562 {
563   *data= val & mask;
564   return(*data);
565 }
566
567
568
569 t_mem
570 cl_memory_cell::add(long what)
571 {
572   *data= (*data + what) & mask;
573   return(*data);
574 }
575
576 t_mem
577 cl_memory_cell::wadd(long what)
578 {
579   t_mem d= (*data + what) & mask;
580   return(write(d));
581 }
582
583 void
584 cl_memory_cell::set_bit1(t_mem bits)
585 {
586   bits&= mask;
587   (*data)|= bits;
588 }
589
590 void
591 cl_memory_cell::set_bit0(t_mem bits)
592 {
593   bits&= mask;
594   (*data)&= ~bits;
595 }
596
597
598 void
599 cl_memory_cell::append_operator(class cl_memory_operator *op)
600 {
601   if (!operators)
602     operators= op;
603   else
604     {
605       class cl_memory_operator *o= operators, *n;
606       n= o->get_next();
607       while (n)
608         {
609           o= n;
610           n= o->get_next();
611         }
612       o->set_next(op);
613     }
614 }
615
616 void
617 cl_memory_cell::prepend_operator(class cl_memory_operator *op)
618 {
619   if (op)
620     {
621       op->set_next(operators);
622       operators= op;
623     }
624 }
625
626 void
627 cl_memory_cell::del_operator(class cl_brk *brk)
628 {
629   if (!operators)
630     return;
631   class cl_memory_operator *op= operators;
632   if (operators->match(brk))
633     {
634       operators= op->get_next();
635       delete op;
636     }
637   else
638     {
639       while (op->get_next() &&
640              !op->get_next()->match(brk))
641         op= op->get_next();
642       if (op->get_next())
643         {
644           class cl_memory_operator *m= op->get_next();
645           op->set_next(m->get_next());;
646           delete m;
647         }
648     }
649 }
650
651
652 class cl_memory_cell *
653 cl_memory_cell::add_hw(class cl_hw *hw, int *ith, t_addr addr)
654 {
655   class cl_hw_operator *o= new cl_hw_operator(this, addr, data, mask, hw);
656   append_operator(o);
657   return(this);
658 }
659
660 /*class cl_hw *
661 cl_memory_cell::get_hw(int ith)
662 {
663   return(0);
664 }*/
665
666 class cl_event_handler *
667 cl_memory_cell::get_event_handler(void)
668 {
669   return(0);
670 }
671
672
673 /*
674  * Dummy cell for non-existent addresses
675  */
676
677 t_mem
678 cl_dummy_cell::write(t_mem val)
679 {
680 #ifdef STATISTIC
681   nuof_writes++;
682 #endif
683   *data= rand() & mask;
684   return(*data);
685 }
686
687 t_mem
688 cl_dummy_cell::set(t_mem val)
689 {
690   *data= rand() & mask;
691   return(*data);
692 }
693
694
695 /*
696  *                                                                Address space
697  */
698
699 cl_address_space::cl_address_space(char *id,
700                                    t_addr astart, t_addr asize, int awidth):
701   cl_memory(id, asize, awidth)
702 {
703   start_address= astart;
704   decoders= new cl_decoder_list(2, 2, DD_FALSE);
705   cells= (class cl_memory_cell **)malloc(size * sizeof(class cl_memory_cell*));
706   int i;
707   for (i= 0; i < size; i++)
708     {
709       cells[i]= new cl_memory_cell();
710       cells[i]->init();
711     }
712   dummy= new cl_dummy_cell();
713 }
714
715 cl_address_space::~cl_address_space(void)
716 {
717   delete decoders;
718   int i;
719   for (i= 0; i < size; i++)
720     if (cells[i])
721       delete cells[i];
722   delete dummy;
723 }
724
725   
726 t_mem
727 cl_address_space::read(t_addr addr)
728 {
729   t_addr idx= addr-start_address;
730   if (idx >= size ||
731       addr < start_address)
732     {
733       err_inv_addr(addr);
734       return(dummy->read());
735     }
736   return(cells[idx]->read());
737 }
738
739 t_mem
740 cl_address_space::read(t_addr addr, enum hw_cath skip)
741 {
742   t_addr idx= addr-start_address;
743   if (idx >= size ||
744       addr < start_address)
745     {
746       err_inv_addr(addr);
747       return(dummy->read());
748     }
749   return(cells[idx]->read(skip));
750 }
751
752 t_mem
753 cl_address_space::get(t_addr addr)
754 {
755   t_addr idx= addr-start_address;
756   if (idx >= size ||
757       addr < start_address)
758     {
759       err_inv_addr(addr);
760       return(dummy->get());
761     }
762   return(cells[idx]->get());
763 }
764
765 t_mem
766 cl_address_space::write(t_addr addr, t_mem val)
767 {
768   t_addr idx= addr-start_address;
769   if (idx >= size ||
770       addr < start_address)
771     {
772       err_inv_addr(addr);
773       return(dummy->write(val));
774     }
775   return(cells[idx]->write(val));
776 }
777
778 void
779 cl_address_space::set(t_addr addr, t_mem val)
780 {
781   t_addr idx= addr-start_address;
782   if (idx >= size ||
783       addr < start_address)
784     {
785       err_inv_addr(addr);
786       dummy->set(val);
787       return;
788     }
789   cells[idx]->set(val);
790 }
791
792 t_mem
793 cl_address_space::wadd(t_addr addr, long what)
794 {
795   t_addr idx= addr-start_address;
796   if (idx >= size ||
797       addr < start_address)
798     {
799       err_inv_addr(addr);
800     }
801   return(cells[idx]->wadd(what));
802 }
803
804 /* Set or clear bits, without callbacks */
805
806 void
807 cl_address_space::set_bit1(t_addr addr, t_mem bits)
808 {
809   t_addr idx= addr-start_address;
810   if (idx >= size ||
811       addr < start_address)
812     return;
813   class cl_memory_cell *cell= cells[idx];
814   cell->set_bit1(bits);
815 }
816
817 void
818 cl_address_space::set_bit0(t_addr addr, t_mem bits)
819 {
820   t_addr idx= addr-start_address;
821   if (idx >= size ||
822       addr < start_address)
823     return;
824   class cl_memory_cell *cell= cells[idx];
825   cell->set_bit0(bits);
826 }
827
828
829 class cl_memory_cell *
830 cl_address_space::get_cell(t_addr addr)
831 {
832   t_addr idx= addr-start_address;
833   if (idx >= size ||
834       addr < start_address)
835     {
836       err_inv_addr(addr);
837       return(dummy);
838     }
839   return(cells[idx]);
840 }
841
842
843 int
844 cl_address_space::get_cell_flag(t_addr addr)
845 {
846   t_addr idx= addr-start_address;
847   if (idx >= size ||
848       addr < start_address)
849     {
850       return(dummy->get_flags());
851     }
852   return(cells[addr]->get_flags());
853 }
854
855 bool
856 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
857 {
858   t_addr idx= addr-start_address;
859   if (idx >= size ||
860       addr < start_address)
861     {
862       return(dummy->get_flag(flag));
863     }
864   return(cells[addr]->get_flag(flag));
865 }
866
867 void
868 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
869 {
870   t_addr idx= addr-start_address;
871   class cl_memory_cell *cell;
872   
873   if (idx >= size ||
874       addr < start_address)
875     {
876       cell= dummy;
877     }
878   else
879     cell= cells[addr];
880   cell->set_flag(flag, set_to);
881 }
882
883
884 bool
885 cl_address_space::decode_cell(t_addr addr,
886                               class cl_memory_chip *chip, t_addr chipaddr)
887 {
888   t_addr idx= addr-start_address;
889   if (idx >= size ||
890       addr < start_address)
891     return(DD_FALSE);
892   class cl_memory_cell *cell= cells[idx];
893
894   if (!cell->get_flag(CELL_NON_DECODED))
895     {
896       // un-decode first!
897       cell->un_decode();
898     }
899   cell->decode(chip, chipaddr);
900
901   return(!cell->get_flag(CELL_NON_DECODED));
902 }
903
904 void
905 cl_address_space::undecode_cell(t_addr addr)
906 {
907   t_addr idx= addr-start_address;
908   if (idx >= size ||
909       addr < start_address)
910     return;
911   class cl_memory_cell *cell= cells[idx];
912
913   cell->un_decode();
914 }
915
916 void
917 cl_address_space::undecode_area(class cl_address_decoder *skip,
918                                 t_addr begin, t_addr end,class cl_console *con)
919 {
920 #define D if (con) con->debug
921   D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
922   int i;
923   for (i= 0; i < decoders->count; i++)
924     {
925       class cl_address_decoder *d=
926         dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
927       if (!d ||
928           d == skip)
929         continue;
930       D("  Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
931         d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
932       if (d->fully_covered_by(begin, end))
933         {
934           // decoder can be removed
935           D("    Can be removed\n");
936           decoders->disconn(d);
937           i--;
938           delete d;
939           if (decoders->count == 0)
940             break;
941         }
942       else if (d->covers(begin, end))
943         {
944           // decoder must be split
945           D("    Must be split\n");
946           class cl_address_decoder *nd= d->split(begin, end);
947           D("    After split:\n");
948           D("      0x%x-0x%x -> %s[0x%x]\n",
949             d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
950           if (nd)
951             {
952               decoders->add(nd);
953               D("      0x%x-0x%x -> %s[0x%x]\n",
954                 nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
955               nd->activate(con);
956             }
957         }
958       else if (d->is_in(begin, end))
959         {
960           // decoder sould shrink
961           D("    Sould shrink\n");
962           if (d->shrink_out_of(begin, end))
963             {
964               D("    Can be removed after shrink\n");
965               decoders->disconn(d);
966               i--;
967               delete d;
968               if (decoders->count == 0)
969                 break;
970             }
971           else
972             {
973               D("    Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
974                 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
975             }
976         }
977     }
978 #undef D
979 }
980
981
982 class cl_memory_cell *
983 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
984                               int *ith,
985                               bool announce)
986 {
987   t_addr idx= addr-start_address;
988   if (idx >= size ||
989       addr < start_address)
990     return(0);
991   class cl_memory_cell *cell= cells[idx];
992   cell->add_hw(hw, ith, addr);
993   //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
994   if (announce)
995     ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
996   return(cell);
997 }
998
999
1000 void
1001 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
1002 {
1003   t_addr idx= addr-start_address;
1004   if (idx >= size ||
1005       addr < start_address)
1006     return;
1007   class cl_memory_cell *cell= cells[idx];
1008   class cl_memory_operator *op;
1009
1010   switch (brk->get_event())
1011     {
1012     case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1013       //e= 'W';
1014       op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
1015                                 uc, brk);
1016       break;
1017     case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1018       //e= 'R';
1019       op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
1020                                uc, brk);
1021       break;
1022     case brkNONE:
1023       set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
1024       return;
1025       break;
1026     default:
1027       //e= '.';
1028       op= 0;
1029       break;  
1030     }
1031   if (op)
1032     cell->append_operator(op);
1033 }
1034
1035 void
1036 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1037 {
1038   t_addr idx= addr-start_address;
1039   if (idx >= size ||
1040       addr < start_address)
1041     return;
1042   class cl_memory_cell *cell= cells[idx];
1043
1044   switch (brk->get_event())
1045     {
1046     case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1047     case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1048       cell->del_operator(brk);
1049       break;
1050     case brkNONE:
1051       set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1052       return;
1053       break;
1054     default:
1055       break;
1056     }
1057 }
1058
1059
1060 /*
1061  * List of address spaces
1062  */
1063
1064 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1065   cl_list(2, 2, "address spaces")
1066 {
1067   uc= the_uc;
1068 }
1069
1070 t_index
1071 cl_address_space_list::add(class cl_address_space *mem)
1072 {
1073   mem->set_uc(uc);
1074   t_index ret= cl_list::add(mem);
1075   if (uc)
1076     {
1077       class cl_event_address_space_added e(mem);
1078       uc->handle_event(e);
1079     }
1080   return(ret);
1081 }
1082
1083
1084 /*
1085  *                                                                  Memory chip
1086  */
1087
1088 cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
1089   cl_memory(id, asize, awidth)
1090 {
1091   array= (t_mem *)malloc(size * sizeof(t_mem));
1092   init_value= initial;
1093 }
1094
1095 cl_memory_chip::~cl_memory_chip(void)
1096 {
1097   if (array)
1098     free(array);
1099 }
1100
1101 int
1102 cl_memory_chip::init(void)
1103 {
1104   cl_memory::init();
1105   int i;
1106   for (i= 0; i < size; i++)
1107     set(i,
1108         (init_value<0)?rand():(init_value));
1109   return(0);
1110 }
1111
1112
1113 t_mem *
1114 cl_memory_chip::get_slot(t_addr addr)
1115 {
1116   if (!array ||
1117       size <= addr)
1118     return(0);
1119   return(&array[addr]);
1120 }
1121
1122
1123 t_mem
1124 cl_memory_chip::get(t_addr addr)
1125 {
1126   if (!array ||
1127       size <= addr)
1128     return(0);
1129   return(array[addr]);
1130 }
1131
1132 void
1133 cl_memory_chip::set(t_addr addr, t_mem val)
1134 {
1135   if (!array ||
1136       size <= addr)
1137     return;
1138   array[addr]= val & data_mask;
1139 }
1140
1141 void
1142 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1143 {
1144   if (!array ||
1145       size <= addr)
1146     return;
1147   array[addr]|= (bits & data_mask);
1148 }
1149
1150 void
1151 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1152 {
1153   if (!array ||
1154       size <= addr)
1155     return;
1156   array[addr]&= ((~bits) & data_mask);
1157 }
1158
1159
1160 /*
1161  *                                                              Address decoder
1162  */
1163
1164 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1165                                        class cl_memory *chip,
1166                                        t_addr asb, t_addr ase, t_addr cb)
1167 {
1168   if (as->is_address_space())
1169     address_space= (class cl_address_space *)as;
1170   else
1171     address_space= 0;
1172   if (chip->is_chip())
1173     memchip= (class cl_memory_chip *)chip;
1174   else
1175     memchip= 0;
1176   as_begin= asb;
1177   as_end= ase;
1178   chip_begin= cb;
1179   activated= DD_FALSE;
1180 }
1181
1182 cl_address_decoder::~cl_address_decoder(void)
1183 {
1184   t_addr a;
1185   if (address_space)
1186     for (a= as_begin; a <= as_end; a++)
1187       address_space->undecode_cell(a);
1188 }
1189
1190 int
1191 cl_address_decoder::init(void)
1192 {
1193   return(0);
1194 }
1195
1196
1197 bool
1198 cl_address_decoder::activate(class cl_console *con)
1199 {
1200 #define D if (con) con->debug
1201   D("Activation of an address decoder\n");
1202   if (activated)
1203     {
1204       D("Already activated\n");
1205       return(DD_FALSE);
1206     }
1207   if (!address_space ||
1208       !address_space->is_address_space())
1209     {
1210       D("No or non address space\n");
1211       return(DD_FALSE);
1212     }
1213   if (!memchip ||
1214       !memchip->is_chip())
1215     {
1216       D("No or non memory chip\n");
1217       return(DD_FALSE);
1218     }
1219   if (as_begin > as_end)
1220     {
1221       D("Wrong address area specification\n");
1222       return(DD_FALSE);
1223     }
1224   if (chip_begin >= memchip->get_size())
1225     {
1226       D("Wrong chip area specification\n");
1227       return(DD_FALSE);
1228     }
1229   if (as_begin < address_space->start_address ||
1230       as_end >= address_space->start_address + address_space->get_size())
1231     {
1232       D("Specified area is out of address space\n");
1233       return(DD_FALSE);
1234     }
1235   if (as_end-as_begin > memchip->get_size()-chip_begin)
1236     {
1237       D("Specified area is out of chip size\n");
1238       return(DD_FALSE);
1239     }
1240
1241   address_space->undecode_area(this, as_begin, as_end, con);
1242
1243   t_addr asa, ca;
1244   for (asa= as_begin, ca= chip_begin;
1245        asa <= as_end;
1246        asa++, ca++)
1247     {
1248       if (!address_space->decode_cell(asa, memchip, ca))
1249         {
1250           D("Decoding 0x%06x->0x%06x failed\n", asa, ca);
1251         }
1252     }
1253   activated= DD_TRUE;
1254
1255 #undef D
1256   return(activated);
1257 }
1258
1259
1260 bool
1261 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
1262 {
1263   if (begin <= as_begin &&
1264       end >= as_end)
1265     return(DD_TRUE);
1266   return(DD_FALSE);
1267 }
1268
1269 bool
1270 cl_address_decoder::is_in(t_addr begin, t_addr end)
1271 {
1272   if (begin >= as_begin &&
1273       begin <= as_end)
1274     return(DD_TRUE);
1275   if (end >= as_begin &&
1276       end <= as_end)
1277     return(DD_TRUE);
1278   return(DD_FALSE);
1279 }
1280
1281 bool
1282 cl_address_decoder::covers(t_addr begin, t_addr end)
1283 {
1284   if (begin > as_begin &&
1285       end < as_end)
1286     return(DD_TRUE);
1287   return(DD_FALSE);
1288 }
1289
1290
1291 /* Returns TRUE if shrunken decoder is unnecessary */
1292
1293 bool
1294 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
1295 {
1296   t_addr a= as_begin;
1297   
1298   if (!address_space)
1299     return(DD_TRUE);
1300   if (begin > a)
1301     a= begin;
1302   while (a <= end &&
1303          a <= as_end)
1304     {
1305       address_space->undecode_cell(a);
1306       a++;
1307     }
1308   if (begin > as_begin)
1309     as_end= begin-1;
1310   if (as_end > end)
1311     {
1312       chip_begin+= (end-as_begin+1);
1313       as_begin= end+1;
1314     }
1315   if (as_end < as_begin)
1316     return(DD_TRUE);
1317   return(DD_FALSE);
1318 }
1319
1320 class cl_address_decoder *
1321 cl_address_decoder::split(t_addr begin, t_addr end)
1322 {
1323   class cl_address_decoder *nd= 0;
1324   if (begin > as_begin)
1325     {
1326       if (as_end > end)
1327         nd= new cl_address_decoder(address_space, memchip,
1328                                    end+1, as_end, chip_begin+(end-as_begin)+1);
1329       shrink_out_of(begin, as_end);
1330     }
1331   else if (end < as_end)
1332     {
1333       if (as_begin < begin)
1334         nd= new cl_address_decoder(address_space, memchip,
1335                                    as_begin, begin-1, chip_begin);
1336       shrink_out_of(end+1, as_end);
1337     }
1338   if (nd)
1339     nd->init();
1340   return(nd);
1341 }
1342
1343
1344 /*
1345  * List of address decoders
1346  */
1347
1348 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
1349   cl_sorted_list(alimit, adelta, "decoder list")
1350 {
1351   Duplicates= DD_TRUE;
1352   by_chip= bychip;
1353 }
1354
1355 void *
1356 cl_decoder_list::key_of(void *item)
1357 {
1358   class cl_address_decoder *d= (class cl_address_decoder *)item;
1359   if (by_chip)
1360     return(&(d->chip_begin));
1361   else
1362     return(&(d->as_begin));
1363 }
1364
1365 int
1366 cl_decoder_list::compare(void *key1, void *key2)
1367 {
1368   t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
1369   if (k1 == k2)
1370     return(0);
1371   else if (k1 > k2)
1372     return(1);
1373   return(-1);
1374 }
1375
1376
1377 /*
1378  * Errors in memory handling
1379  */
1380
1381 /* All of memory errors */
1382
1383 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
1384 {
1385   mem= amem;
1386   addr= aaddr;
1387   classification= mem_error_registry.find("memory");
1388 }
1389
1390 /* Invalid address in memory access */
1391
1392 cl_error_mem_invalid_address::
1393 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
1394   cl_error_mem(amem, aaddr)
1395 {
1396   classification= mem_error_registry.find("invalid_address");
1397 }
1398
1399 void
1400 cl_error_mem_invalid_address::print(class cl_commander *c)
1401 {
1402   FILE *f= c->get_out();
1403   cmd_fprintf(f, "%s: invalid address ", get_type_name());
1404   cmd_fprintf(f, mem->addr_format, addr);
1405   cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1406 }
1407
1408 /* Non-decoded address space access */
1409
1410 cl_error_mem_non_decoded::
1411 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
1412   cl_error_mem(amem, aaddr)
1413 {
1414   classification= mem_error_registry.find("non_decoded");
1415 }
1416
1417 void
1418 cl_error_mem_non_decoded::print(class cl_commander *c)
1419 {
1420   FILE *f= c->get_out();
1421   cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
1422   cmd_fprintf(f, mem->addr_format, addr);
1423   cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1424 }
1425
1426 cl_mem_error_registry::cl_mem_error_registry(void)
1427 {
1428   class cl_error_class *prev = mem_error_registry.find("non-classified");
1429   prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
1430   prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
1431   prev = register_error(new cl_error_class(err_error, "non_decoded", prev));
1432 }
1433
1434
1435 /* End of mem.cc */