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