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