* sim/ucsim/sim.src/memcl.h: added get_decoder() to cl_address_space
[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 **)calloc(size, sizeof(class cl_memory_cell*));
706
707   dummy= new cl_dummy_cell();
708 }
709
710 cl_address_space::~cl_address_space(void)
711 {
712   delete decoders;
713   int i;
714   for (i= 0; i < size; i++)
715     if (cells[i])
716       delete cells[i];
717   delete dummy;
718 }
719
720   
721 t_mem
722 cl_address_space::read(t_addr addr)
723 {
724   return get_cell(addr)->read();
725 }
726
727 t_mem
728 cl_address_space::read(t_addr addr, enum hw_cath skip)
729 {
730   cl_memory_cell *cell = get_cell(addr);
731   if (cell == dummy)
732     {
733       return dummy->read();
734     }
735   return cell->read(skip);
736 }
737
738 t_mem
739 cl_address_space::get(t_addr addr)
740 {
741   return get_cell(addr)->get();
742 }
743
744 t_mem
745 cl_address_space::write(t_addr addr, t_mem val)
746 {
747   return get_cell(addr)->write(val);
748 }
749
750 void
751 cl_address_space::set(t_addr addr, t_mem val)
752 {
753   get_cell(addr)->set(val);
754 }
755
756 t_mem
757 cl_address_space::wadd(t_addr addr, long what)
758 {
759   return get_cell(addr)->wadd(what);
760 }
761
762 /* Set or clear bits, without callbacks */
763
764 void
765 cl_address_space::set_bit1(t_addr addr, t_mem bits)
766 {
767   cl_memory_cell *cell = get_cell(addr);
768   if (cell == dummy)
769     {
770     return;
771     }
772   cell->set_bit1(bits);
773 }
774
775 void
776 cl_address_space::set_bit0(t_addr addr, t_mem bits)
777 {
778   cl_memory_cell *cell = get_cell(addr);
779   if (cell == dummy)
780     {
781       return;
782     }
783   cell->set_bit0(bits);
784 }
785
786 class cl_address_decoder *
787 cl_address_space::get_decoder(t_addr addr)
788 {
789   int i;
790   for (i= 0; i < decoders->count; i++)
791     {
792       class cl_address_decoder *d=
793         dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
794       if (!d)
795         continue;
796       if (d->covers(addr, addr))
797         {
798           return d;
799         }
800     }
801     return NULL;
802 }
803
804 class cl_memory_cell *
805 cl_address_space::get_cell(t_addr addr)
806 {
807   t_addr idx= addr-start_address;
808   if (idx >= size ||
809       addr < start_address)
810     {
811       err_inv_addr(addr);
812       return(dummy);
813     }
814   if (cells[idx] == NULL)
815     {
816       cells[idx]= new cl_memory_cell();
817       cells[idx]->init();
818       class cl_address_decoder *decoder;
819       decoder = get_decoder(addr);
820       if (decoder && decoder->activated)
821         {
822           decode_cell(addr, decoder->memchip,
823                       addr - decoder->as_begin + decoder->chip_begin);
824         }
825     }
826   return(cells[idx]);
827 }
828
829
830 int
831 cl_address_space::get_cell_flag(t_addr addr)
832 {
833   return get_cell(addr)->get_flags();
834 }
835
836 bool
837 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
838 {
839   return get_cell(addr)->get_flag(flag);
840 }
841
842 void
843 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
844 {
845   get_cell(addr)->set_flag(flag, set_to);
846 }
847
848
849 bool
850 cl_address_space::decode_cell(t_addr addr,
851                               class cl_memory_chip *chip, t_addr chipaddr)
852 {
853   cl_memory_cell *cell = get_cell(addr);
854   if (cell == dummy)
855     {
856       return(DD_FALSE);
857     }
858
859   if (!cell->get_flag(CELL_NON_DECODED))
860     {
861       // un-decode first!
862       cell->un_decode();
863     }
864   cell->decode(chip, chipaddr);
865
866   return(!cell->get_flag(CELL_NON_DECODED));
867 }
868
869 void
870 cl_address_space::undecode_cell(t_addr addr)
871 {
872   t_addr idx= addr-start_address;
873   if (idx >= size ||
874       addr < start_address)
875     {
876       err_inv_addr(addr);
877       return;
878     }
879   if (cells[idx] == NULL)
880     {
881       return;
882     }
883   cells[idx]->un_decode();
884 }
885
886 void
887 cl_address_space::undecode_area(class cl_address_decoder *skip,
888                                 t_addr begin, t_addr end,class cl_console *con)
889 {
890 #define D if (con) con->debug
891   D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
892   int i;
893   for (i= 0; i < decoders->count; i++)
894     {
895       class cl_address_decoder *d=
896         dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
897       if (!d ||
898           d == skip)
899         continue;
900       D("  Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
901         d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
902       if (d->fully_covered_by(begin, end))
903         {
904           // decoder can be removed
905           D("    Can be removed\n");
906           decoders->disconn(d);
907           i--;
908           delete d;
909           if (decoders->count == 0)
910             break;
911         }
912       else if (d->covers(begin, end))
913         {
914           // decoder must be split
915           D("    Must be split\n");
916           class cl_address_decoder *nd= d->split(begin, end);
917           D("    After split:\n");
918           D("      0x%x-0x%x -> %s[0x%x]\n",
919             d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
920           if (nd)
921             {
922               decoders->add(nd);
923               D("      0x%x-0x%x -> %s[0x%x]\n",
924                 nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
925               nd->activate(con);
926             }
927         }
928       else if (d->is_in(begin, end))
929         {
930           // decoder sould shrink
931           D("    Sould shrink\n");
932           if (d->shrink_out_of(begin, end))
933             {
934               D("    Can be removed after shrink\n");
935               decoders->disconn(d);
936               i--;
937               delete d;
938               if (decoders->count == 0)
939                 break;
940             }
941           else
942             {
943               D("    Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
944                 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
945             }
946         }
947     }
948 #undef D
949 }
950
951
952 class cl_memory_cell *
953 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
954                               int *ith,
955                               bool announce)
956 {
957   cl_memory_cell *cell = get_cell(addr);
958   if (cell == dummy)
959     {
960       return(NULL);
961     }
962   cell->add_hw(hw, ith, addr);
963   //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
964   if (announce)
965     ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
966   return(cell);
967 }
968
969
970 void
971 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
972 {
973   cl_memory_cell *cell = get_cell(addr);
974   if (cell == dummy)
975     {
976       return;
977     }
978
979   class cl_memory_operator *op;
980
981   switch (brk->get_event())
982     {
983     case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
984       //e= 'W';
985       op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
986                                 uc, brk);
987       break;
988     case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
989       //e= 'R';
990       op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
991                                uc, brk);
992       break;
993     case brkNONE:
994       set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
995       return;
996       break;
997     default:
998       //e= '.';
999       op= 0;
1000       break;  
1001     }
1002   if (op)
1003     cell->append_operator(op);
1004 }
1005
1006 void
1007 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1008 {
1009   cl_memory_cell *cell = get_cell(addr);
1010   if (cell == dummy)
1011     {
1012       return;
1013     }
1014
1015   switch (brk->get_event())
1016     {
1017     case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1018     case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1019       cell->del_operator(brk);
1020       break;
1021     case brkNONE:
1022       set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1023       return;
1024       break;
1025     default:
1026       break;
1027     }
1028 }
1029
1030
1031 /*
1032  * List of address spaces
1033  */
1034
1035 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1036   cl_list(2, 2, "address spaces")
1037 {
1038   uc= the_uc;
1039 }
1040
1041 t_index
1042 cl_address_space_list::add(class cl_address_space *mem)
1043 {
1044   mem->set_uc(uc);
1045   t_index ret= cl_list::add(mem);
1046   if (uc)
1047     {
1048       class cl_event_address_space_added e(mem);
1049       uc->handle_event(e);
1050     }
1051   return(ret);
1052 }
1053
1054
1055 /*
1056  *                                                                  Memory chip
1057  */
1058
1059 cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
1060   cl_memory(id, asize, awidth)
1061 {
1062   array= (t_mem *)malloc(size * sizeof(t_mem));
1063   init_value= initial;
1064 }
1065
1066 cl_memory_chip::~cl_memory_chip(void)
1067 {
1068   if (array)
1069     free(array);
1070 }
1071
1072 int
1073 cl_memory_chip::init(void)
1074 {
1075   cl_memory::init();
1076   int i;
1077   for (i= 0; i < size; i++)
1078     set(i,
1079         (init_value<0)?rand():(init_value));
1080   return(0);
1081 }
1082
1083
1084 t_mem *
1085 cl_memory_chip::get_slot(t_addr addr)
1086 {
1087   if (!array ||
1088       size <= addr)
1089     return(0);
1090   return(&array[addr]);
1091 }
1092
1093
1094 t_mem
1095 cl_memory_chip::get(t_addr addr)
1096 {
1097   if (!array ||
1098       size <= addr)
1099     return(0);
1100   return(array[addr]);
1101 }
1102
1103 void
1104 cl_memory_chip::set(t_addr addr, t_mem val)
1105 {
1106   if (!array ||
1107       size <= addr)
1108     return;
1109   array[addr]= val & data_mask;
1110 }
1111
1112 void
1113 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1114 {
1115   if (!array ||
1116       size <= addr)
1117     return;
1118   array[addr]|= (bits & data_mask);
1119 }
1120
1121 void
1122 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1123 {
1124   if (!array ||
1125       size <= addr)
1126     return;
1127   array[addr]&= ((~bits) & data_mask);
1128 }
1129
1130
1131 /*
1132  *                                                              Address decoder
1133  */
1134
1135 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1136                                        class cl_memory *chip,
1137                                        t_addr asb, t_addr ase, t_addr cb)
1138 {
1139   if (as->is_address_space())
1140     address_space= (class cl_address_space *)as;
1141   else
1142     address_space= 0;
1143   if (chip->is_chip())
1144     memchip= (class cl_memory_chip *)chip;
1145   else
1146     memchip= 0;
1147   as_begin= asb;
1148   as_end= ase;
1149   chip_begin= cb;
1150   activated= DD_FALSE;
1151 }
1152
1153 cl_address_decoder::~cl_address_decoder(void)
1154 {
1155   t_addr a;
1156   if (address_space)
1157     for (a= as_begin; a <= as_end; a++)
1158       address_space->undecode_cell(a);
1159 }
1160
1161 int
1162 cl_address_decoder::init(void)
1163 {
1164   return(0);
1165 }
1166
1167
1168 bool
1169 cl_address_decoder::activate(class cl_console *con)
1170 {
1171 #define D if (con) con->debug
1172   D("Activation of an address decoder\n");
1173   if (activated)
1174     {
1175       D("Already activated\n");
1176       return(DD_FALSE);
1177     }
1178   if (!address_space ||
1179       !address_space->is_address_space())
1180     {
1181       D("No or non address space\n");
1182       return(DD_FALSE);
1183     }
1184   if (!memchip ||
1185       !memchip->is_chip())
1186     {
1187       D("No or non memory chip\n");
1188       return(DD_FALSE);
1189     }
1190   if (as_begin > as_end)
1191     {
1192       D("Wrong address area specification\n");
1193       return(DD_FALSE);
1194     }
1195   if (chip_begin >= memchip->get_size())
1196     {
1197       D("Wrong chip area specification\n");
1198       return(DD_FALSE);
1199     }
1200   if (as_begin < address_space->start_address ||
1201       as_end >= address_space->start_address + address_space->get_size())
1202     {
1203       D("Specified area is out of address space\n");
1204       return(DD_FALSE);
1205     }
1206   if (as_end-as_begin > memchip->get_size()-chip_begin)
1207     {
1208       D("Specified area is out of chip size\n");
1209       return(DD_FALSE);
1210     }
1211
1212   address_space->undecode_area(this, as_begin, as_end, con);
1213
1214   activated= DD_TRUE;
1215
1216 #undef D
1217   return(activated);
1218 }
1219
1220
1221 bool
1222 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
1223 {
1224   if (begin <= as_begin &&
1225       end >= as_end)
1226     return(DD_TRUE);
1227   return(DD_FALSE);
1228 }
1229
1230 bool
1231 cl_address_decoder::is_in(t_addr begin, t_addr end)
1232 {
1233   if (begin >= as_begin &&
1234       begin <= as_end)
1235     return(DD_TRUE);
1236   if (end >= as_begin &&
1237       end <= as_end)
1238     return(DD_TRUE);
1239   return(DD_FALSE);
1240 }
1241
1242 bool
1243 cl_address_decoder::covers(t_addr begin, t_addr end)
1244 {
1245   if (begin > as_begin &&
1246       end < as_end)
1247     return(DD_TRUE);
1248   return(DD_FALSE);
1249 }
1250
1251
1252 /* Returns TRUE if shrunken decoder is unnecessary */
1253
1254 bool
1255 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
1256 {
1257   t_addr a= as_begin;
1258   
1259   if (!address_space)
1260     return(DD_TRUE);
1261   if (begin > a)
1262     a= begin;
1263   while (a <= end &&
1264          a <= as_end)
1265     {
1266       address_space->undecode_cell(a);
1267       a++;
1268     }
1269   if (begin > as_begin)
1270     as_end= begin-1;
1271   if (as_end > end)
1272     {
1273       chip_begin+= (end-as_begin+1);
1274       as_begin= end+1;
1275     }
1276   if (as_end < as_begin)
1277     return(DD_TRUE);
1278   return(DD_FALSE);
1279 }
1280
1281 class cl_address_decoder *
1282 cl_address_decoder::split(t_addr begin, t_addr end)
1283 {
1284   class cl_address_decoder *nd= 0;
1285   if (begin > as_begin)
1286     {
1287       if (as_end > end)
1288         nd= new cl_address_decoder(address_space, memchip,
1289                                    end+1, as_end, chip_begin+(end-as_begin)+1);
1290       shrink_out_of(begin, as_end);
1291     }
1292   else if (end < as_end)
1293     {
1294       if (as_begin < begin)
1295         nd= new cl_address_decoder(address_space, memchip,
1296                                    as_begin, begin-1, chip_begin);
1297       shrink_out_of(end+1, as_end);
1298     }
1299   if (nd)
1300     nd->init();
1301   return(nd);
1302 }
1303
1304
1305 /*
1306  * List of address decoders
1307  */
1308
1309 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
1310   cl_sorted_list(alimit, adelta, "decoder list")
1311 {
1312   Duplicates= DD_TRUE;
1313   by_chip= bychip;
1314 }
1315
1316 void *
1317 cl_decoder_list::key_of(void *item)
1318 {
1319   class cl_address_decoder *d= (class cl_address_decoder *)item;
1320   if (by_chip)
1321     return(&(d->chip_begin));
1322   else
1323     return(&(d->as_begin));
1324 }
1325
1326 int
1327 cl_decoder_list::compare(void *key1, void *key2)
1328 {
1329   t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
1330   if (k1 == k2)
1331     return(0);
1332   else if (k1 > k2)
1333     return(1);
1334   return(-1);
1335 }
1336
1337
1338 /*
1339  * Errors in memory handling
1340  */
1341
1342 /* All of memory errors */
1343
1344 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
1345 {
1346   mem= amem;
1347   addr= aaddr;
1348   classification= mem_error_registry.find("memory");
1349 }
1350
1351 /* Invalid address in memory access */
1352
1353 cl_error_mem_invalid_address::
1354 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
1355   cl_error_mem(amem, aaddr)
1356 {
1357   classification= mem_error_registry.find("invalid_address");
1358 }
1359
1360 void
1361 cl_error_mem_invalid_address::print(class cl_commander *c)
1362 {
1363   FILE *f= c->get_out();
1364   cmd_fprintf(f, "%s: invalid address ", get_type_name());
1365   cmd_fprintf(f, mem->addr_format, addr);
1366   cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1367 }
1368
1369 /* Non-decoded address space access */
1370
1371 cl_error_mem_non_decoded::
1372 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
1373   cl_error_mem(amem, aaddr)
1374 {
1375   classification= mem_error_registry.find("non_decoded");
1376 }
1377
1378 void
1379 cl_error_mem_non_decoded::print(class cl_commander *c)
1380 {
1381   FILE *f= c->get_out();
1382   cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
1383   cmd_fprintf(f, mem->addr_format, addr);
1384   cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1385 }
1386
1387 cl_mem_error_registry::cl_mem_error_registry(void)
1388 {
1389   class cl_error_class *prev = mem_error_registry.find("non-classified");
1390   prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
1391   prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
1392   prev = register_error(new cl_error_class(err_error, "non_decoded", prev));
1393 }
1394
1395
1396 /* End of mem.cc */