2 * Memory location handled specially by a hw element
5 /*cl_memloc::cl_memloc(t_addr addr):
9 hws= new cl_list(2, 2);
13 /*cl_memloc::~cl_memloc(void)
20 cl_memloc::read(class cl_mem *mem)
28 if ((hw= (class cl_hw *)(hws->at(0))))
29 ret= hw->read(mem, address);
34 cl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val)
41 for (i= 0; i < hws->count; i++)
43 hw= (class cl_hw *)hws->at(0);
44 hw->write(mem, addr, val);
49 /* Sorted collection of memory locations */
51 /*cl_memloc_coll::cl_memloc_coll(void):
58 cl_memloc_coll::key_of(void *item)
60 return(&(((class cl_memloc *)item)->address));
64 cl_memloc_coll::compare(void *key1, void *key2)
66 if (*(long*)key1 > *(long*)key2)
69 if (*(long*)key1 < *(long*)key2)
76 cl_memloc_coll::get_loc(t_addr address)
80 if (search(&address, i))
81 return((class cl_memloc*)(at(i)));
88 ******************************************************************************
95 /*cl_bitmap::cl_bitmap(t_addr asize):
98 map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR));
102 cl_bitmap::~cl_bitmap(void)
108 cl_bitmap::set(t_addr pos)
112 if ((i= pos/(8*SIZEOF_CHAR)) < size)
113 map[i]|= (1 << (pos & ((8*SIZEOF_CHAR)-1)));
117 cl_bitmap::clear(t_addr pos)
121 if ((i= pos/(8*SIZEOF_CHAR)) < size)
122 map[i]&= ~(1 << (pos & ((8*SIZEOF_CHAR)-1)));
126 cl_bitmap::get(t_addr pos)
128 return(map[pos/(8*SIZEOF_CHAR)] & (1 << (pos & ((8*SIZEOF_CHAR)-1))));
132 cl_bitmap::empty(void)
136 for (i= 0; i < size && map[i] == 0; i++) ;
141 * Special memory for code (ROM)
144 /*cl_rom::cl_rom(t_addr asize, int awidth, class cl_uc *auc):
145 cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth, auc)
147 bp_map= new cl_bitmap(asize);
148 inst_map= new cl_bitmap(asize);
151 cl_rom::~cl_rom(void)
158 cl_mem::cl_mem(enum mem_class atype, char *aclass_name,
159 t_addr asize, int awidth, class cl_uc *auc):
166 class_name= aclass_name;
170 for (i= width, mask= 0; i; i--)
176 mem= (TYPE_UBYTE *)malloc(size);
177 else if (width <= 16)
178 mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD));
180 mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD));
181 //read_locs= new cl_memloc_coll();
182 //write_locs= new cl_memloc_coll();
184 addr_format= data_format= 0;
187 cl_mem::~cl_mem(void)
204 addr_format= (char *)malloc(10);
205 sprintf(addr_format, "0x%%0%dx",
211 (size-1<=0xffffff?6:12))))));
212 data_format= (char *)malloc(10);
213 sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
215 for (i= 0; i < size; i++)
216 set(i, (type==MEM_ROM)?(-1):0);
221 cl_mem::id_string(void)
223 char *s= get_id_string(mem_ids, type);
225 return(s?s:(char*)"NONE");
229 cl_mem::read(t_addr addr)
231 //class cl_memloc *loc;
236 fprintf(stderr, "Address 0x%06"_A_"x is over 0x%06"_A_"x\n", addr, size);
239 /*if ((loc= read_locs->get_loc(addr)))
240 return(loc->read(this));*/
242 return((((TYPE_UBYTE*)mem)[addr])&mask);
243 else if (width <= 16)
244 return((((TYPE_UWORD*)mem)[addr])&mask);
246 return((((TYPE_UDWORD*)mem)[addr])&mask);
250 cl_mem::get(t_addr addr)
255 return((((TYPE_UBYTE*)mem)[addr])&mask);
256 else if (width <= 16)
257 return((((TYPE_UWORD*)mem)[addr])&mask);
259 return((((TYPE_UDWORD*)mem)[addr])&mask);
264 * Modify memory location
267 /* Write calls callbacks of HW elements */
270 cl_mem::write(t_addr addr, t_mem val)
272 /* class cl_memloc *loc;
276 if ((loc= write_locs->get_loc(addr)))
277 loc->write(this, addr, val);
279 ((TYPE_UBYTE*)mem)[addr]= (*val)&mask;
280 else if (width <= 16)
281 ((TYPE_UWORD*)mem)[addr]= (*val)&mask;
283 ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;*/
284 fprintf(stderr, "FIXME cl_mem::write(0x%06"_A_"x, 0x%04"_M_"x)\n",
289 /* Set doesn't call callbacks */
292 cl_mem::set(t_addr addr, t_mem val)
297 ((TYPE_UBYTE*)mem)[addr]= val&mask;
298 else if (width <= 16)
299 ((TYPE_UWORD*)mem)[addr]= val&mask;
301 ((TYPE_UDWORD*)mem)[addr]= val&mask;
305 cl_mem::add(t_addr addr, long what)
311 ((TYPE_UBYTE*)mem)[addr]= ((TYPE_UBYTE*)mem)[addr] + what;
312 return(((TYPE_UBYTE*)mem)[addr]);
314 else if (width <= 16)
316 ((TYPE_UWORD*)mem)[addr]= ((TYPE_UWORD*)mem)[addr] + what;
317 return(((TYPE_UWORD*)mem)[addr]);
321 ((TYPE_UDWORD*)mem)[addr]= ((TYPE_UDWORD*)mem)[addr] + what;
322 return(((TYPE_UDWORD*)mem)[addr]);
327 cl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console_base *con)
331 while ((start <= stop) &&
334 con->dd_printf(addr_format, start); con->dd_printf(" ");
341 con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
346 j= width/4 + ((width%4)?1:0) + 1;
354 for (i= 0; (i < bpl) &&
359 long c= get(start+i);
360 con->dd_printf("%c", isprint(255&c)?(255&c):'.');
362 con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
364 con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
366 con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
368 con->dd_printf("\n");
369 dump_finished= start+i;
372 return(dump_finished);
376 cl_mem::dump(class cl_console_base *con)
378 return(dump(dump_finished, dump_finished+10*8-1, 8, con));
386 cl_mapped_cell::cl_mapped_cell(class cl_cell *realcell)
391 cl_mapped_cell::~cl_mapped_cell(void)
395 cl_mapped_cell::read(void)
397 return(real_cell->read());
401 cl_mapped_cell::read(enum hw_cath skip)
403 return(real_cell->read(skip));
407 cl_mapped_cell::get(void)
409 return(real_cell->get());
413 cl_mapped_cell::write(t_mem val)
415 return(real_cell->write(val));
419 cl_mapped_cell::set(t_mem val)
421 return(real_cell->set(val));
425 cl_mapped_cell::add(long what)
427 return(real_cell->add(what));
431 cl_mapped_cell::wadd(long what)
433 return(real_cell->wadd(what));
437 cl_mapped_cell::set_bit1(t_mem bits)
439 return(real_cell->set_bit1(bits));
443 cl_mapped_cell::set_bit0(t_mem bits)
445 return(real_cell->set_bit0(bits));
449 cl_mapped_cell::add_hw(class cl_hw *hw, int *ith)
451 return(real_cell->add_hw(hw, ith));
455 cl_mapped_cell::get_hw(int ith)
457 return(real_cell->get_hw(ith));
460 class cl_event_handler *
461 cl_mapped_cell::get_event_handler(void)
463 return(real_cell->get_event_handler());
470 cl_m::cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth,
472 cl_memory(aclass_name, asize, awidth)
473 //cl_mem(atype, aclass_name, 0, awidth, auc)
479 set_name(aclass_name);
483 array= (class cl_cell **)calloc(size, sizeof(class cl_cell *));
484 for (a= 0; a < size; a++)
485 array[a]= new cl_normal_cell(width);
488 for (i= 1; i < size; i<<=1)
489 bus_mask= (bus_mask<<1)|1;
490 dummy= new cl_normal_cell(width);
498 for (a= 0; a < size; a++)
511 for (i= 0; i < size; i++)
512 set(i, (type==MEM_ROM)?(-1):0);
517 cl_m::id_string(void)
519 char *s= get_id_string(mem_ids, type);
521 return(s?s:(char*)"NONE");
525 cl_m::mk_cell(t_addr addr, class cl_cell *cell)
528 cell= new cl_cell(width);
536 p= (class cl_cell *)calloc(1, sizeof(*cell));
541 p= (class cl_cell *)realloc(p, sizeof(cell));
543 memcpy(p, cell, sizeof(*cell));
549 cl_m::read(t_addr addr)
555 return(dummy->read());
557 return(array[addr]->read());
561 cl_m::read(t_addr addr, enum hw_cath skip)
567 return(dummy->read(skip));
569 return(array[addr]->read(skip));
573 cl_m::get(t_addr addr)
579 return(dummy->get());
581 return(array[addr]->get());
585 cl_m::write(t_addr addr, t_mem val)
591 return(dummy->write(val));
593 return(array[addr]->write(val));
597 cl_m::set(t_addr addr, t_mem val)
607 array[addr]->set(val);
611 cl_m::get_cell(t_addr addr)
623 /* Set or clear bits, without callbacks */
626 cl_m::set_bit1(t_addr addr, t_mem bits)
638 bits&= cell->get_mask();
639 cell->set(cell->get() | bits);
643 cl_m::write_bit1(t_addr addr, t_mem bits)
655 bits&= cell->get_mask();
656 cell->write(cell->get() | bits);
660 cl_m::set_bit0(t_addr addr, t_mem bits)
672 bits&= cell->get_mask();
673 cell->set(cell->get() & ~bits);
677 cl_m::write_bit0(t_addr addr, t_mem bits)
689 bits&= cell->get_mask();
690 cell->write(cell->get() & ~bits);
694 cl_m::add(t_addr addr, long what)
700 return(dummy->add(what));
702 return(array[addr]->add(what));
706 cl_m::wadd(t_addr addr, long what)
712 return(dummy->wadd(what));
714 return(array[addr]->wadd(what));
718 cl_m::search_next(bool case_sensitive, t_mem *array, int len, t_addr *addr)
737 for (i= 0; i < len && match; i++)
744 if (/*d1 < 128*/isalpha(d1))
746 if (/*d2 < 128*/isalpha(d2))
762 cl_m::register_hw(t_addr addr, class cl_hw *hw, int *ith, bool announce)
764 class cl_cell *cell, *nc;
772 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
774 /* Already registered */
775 return(cell->add_hw(hw, ith));
777 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
779 /* Event break is set on it, now register hw */
780 nc= new cl_ev_reg_cell(width, uc);
781 nc->set(cell->get());
782 nc->set_type(nc->get_type() &
783 ~(CELL_GENERAL|CELL_READ_BRK|CELL_WRITE_BRK));
784 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
785 class cl_event_handler *eh= nc->get_event_handler();
787 nc->set_type(nc->get_type() | eh->copy_from(cell->get_event_handler()));
792 /* Normal cell, register hw */
793 nc= new cl_registered_cell(width);
794 nc->set(cell->get());
795 nc->set_type(nc->get_type() & ~CELL_GENERAL);
796 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
811 uc->sim->/*app->*/mem_cell_changed(this, addr);
816 cl_m::set_brk(t_addr addr, class cl_brk *brk)
818 class cl_cell *cell, *nc;
827 switch (brk->get_event())
829 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
832 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
836 set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
839 default: e= '.'; break;
842 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
844 /* Hw is registered on it, now set event break */
845 nc= new cl_ev_reg_cell(width, uc);
846 nc->set(cell->get());
847 nc->set_type(nc->get_type() & ~CELL_GENERAL);
848 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
851 while ((hw= cell->get_hw(i)) != 0)
856 if (((class cl_registered_cell *)cell)->hardwares)
858 free(((class cl_registered_cell *)cell)->hardwares);
859 ((class cl_registered_cell *)cell)->hardwares= 0;
861 class cl_event_handler *eh;
862 if ((eh= nc->get_event_handler()))
863 nc->set_type(nc->get_type() | eh->add_bp(brk));
865 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
867 /* Break is already set on it */
868 class cl_event_handler *eh;
869 if ((eh= cell->get_event_handler()))
870 cell->set_type(cell->get_type() | eh->add_bp(brk));
875 /* Normal cell, set event break */
876 nc= new cl_event_cell(width, uc);
877 nc->set(cell->get());
878 nc->set_type(nc->get_type() & ~CELL_GENERAL);
879 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
880 class cl_event_handler *eh;
881 if ((eh= nc->get_event_handler()))
882 nc->set_type(nc->get_type() | eh->add_bp(brk));
895 uc->sim->/*app->*/mem_cell_changed(this, addr);
899 cl_m::del_brk(t_addr addr, class cl_brk *brk)
901 class cl_cell *cell, *nc;
910 switch (brk->get_event())
912 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break;
913 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
917 set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
920 default: e= '.'; break;
923 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
925 /* Hw is registered on it, delete event break */
926 class cl_event_handler *eh;
928 if ((eh= cell->get_event_handler()))
930 if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
932 cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
933 cell->set_type(cell->get_type() | t);
936 nc= new cl_registered_cell(width);
937 nc->set(cell->get());
938 nc->set_type(cell->get_type() & ~CELL_GENERAL);
939 nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
942 while ((hw= cell->get_hw(i)) != 0)
947 if (((class cl_registered_cell *)cell)->hardwares)
948 free(((class cl_registered_cell *)cell)->hardwares);
950 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
952 /* Break already set on it, delete brk */
953 class cl_event_handler *eh;
955 if ((eh= cell->get_event_handler()))
957 if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
959 cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
960 cell->set_type(cell->get_type() | t);
963 nc= new cl_normal_cell(width);
964 nc->set(cell->get());
965 nc->set_type(cell->get_type() & ~CELL_GENERAL);
966 nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
985 uc->sim->/*app->*/mem_cell_changed(this, addr);
991 cl_m::get_nuof_reads(void)
993 unsigned long res= 0;
995 for (i= 0; i < size; i++)
996 res+= array[i]->nuof_reads;
1001 cl_m::get_nuof_writes(void)
1003 unsigned long res= 0;
1005 for (i= 0; i < size; i++)
1006 res+= array[i]->nuof_writes;
1011 cl_m::set_nuof_reads(unsigned long value)
1014 for (i= 0; i < size; i++)
1015 array[i]->nuof_reads= value;
1016 dummy->nuof_reads= value;
1020 cl_m::set_nuof_writes(unsigned long value)
1023 for (i= 0; i < size; i++)
1024 array[i]->nuof_writes= value;
1025 dummy->nuof_writes= value;
1030 cl_normal_cell::cl_normal_cell(uchar awidth):
1037 for (--awidth; awidth; awidth--)
1045 cl_normal_cell::add(long what)
1050 d= TYPE_BYTE(data) + what;
1051 else if (width <= 16)
1052 d= TYPE_WORD(data) + what;
1054 d= TYPE_DWORD(data) + what;
1055 return(data= d & mask);
1059 cl_normal_cell::wadd(long what)
1064 d= TYPE_BYTE(data) + what;
1065 else if (width <= 16)
1066 d= TYPE_WORD(data) + what;
1068 d= TYPE_DWORD(data) + what;
1073 cl_normal_cell::set_bit1(t_mem bits)
1080 cl_normal_cell::set_bit0(t_mem bits)
1090 cl_registered_cell::cl_registered_cell(uchar awidth):
1091 cl_normal_cell(awidth)
1093 type= CELL_HW_READ | CELL_HW_WRITE;
1094 //hws= new cl_list(1, 1);
1099 cl_registered_cell::~cl_registered_cell(void)
1106 cl_registered_cell::destroy(void)
1113 cl_registered_cell::read(void)
1119 for (i= 0; i < nuof_hws; i++)
1121 d= hardwares[i]->read(this);
1131 cl_registered_cell::read(enum hw_cath skip)
1137 for (i= 0; i < nuof_hws; i++)
1139 if ((skip & hardwares[i]->cathegory) == 0)
1140 d= hardwares[i]->read(this);
1150 cl_registered_cell::write(t_mem val)
1156 for (i= 0; i < nuof_hws; i++)
1158 hardwares[i]->write(this, &val);
1164 return(data= val & mask);
1168 cl_registered_cell::add_hw(class cl_hw *hw, int *ith)
1176 hardwares= (class cl_hw **)malloc(sizeof(class cl_hw *));
1178 hardwares= (class cl_hw **)realloc(hardwares,
1179 sizeof(class c_hw *) * (nuof_hws+1));
1180 hardwares[nuof_hws]= hw;
1188 cl_registered_cell::get_hw(int ith)
1190 if (ith >= nuof_hws)
1192 return(hardwares[ith]);
1199 cl_event_cell::cl_event_cell(uchar awidth, class cl_uc *auc):
1200 cl_normal_cell(awidth)
1202 eh= new cl_event_handler(auc);
1205 cl_event_cell::~cl_event_cell(void)
1211 cl_event_cell::read(void)
1213 if (type & CELL_READ_BRK)
1215 return(cl_normal_cell::read());
1219 cl_event_cell::write(t_mem val)
1221 if (type & CELL_WRITE_BRK)
1223 return(cl_normal_cell::write(val));
1230 cl_ev_reg_cell::cl_ev_reg_cell(uchar awidth, class cl_uc *auc):
1231 cl_registered_cell(awidth)
1233 eh= new cl_event_handler(auc);
1236 cl_ev_reg_cell::~cl_ev_reg_cell(void)
1240 cl_ev_reg_cell::read(void)
1242 if (type & CELL_READ_BRK)
1244 return(cl_registered_cell::read());
1248 cl_ev_reg_cell::write(t_mem val)
1250 if (type & CELL_WRITE_BRK)
1252 return(cl_registered_cell::write(val));
1259 cl_event_handler::cl_event_handler(class cl_uc *auc):
1263 read_bps= new cl_list(1, 1);
1264 write_bps= new cl_list(1, 1);
1267 cl_event_handler::~cl_event_handler(void)
1269 read_bps->disconn_all();
1270 write_bps->disconn_all();
1276 cl_event_handler::write(void)
1280 for (i= 0; i < write_bps->count; i++)
1282 class cl_brk *bp= (class cl_brk *)(write_bps->at(i));
1283 uc->events->add(bp);
1288 cl_event_handler::read(void)
1292 for (i= 0; i < read_bps->count; i++)
1294 class cl_brk *bp= (class cl_brk *)(read_bps->at(i));
1295 uc->events->add(bp);
1300 cl_event_handler::add_bp(class cl_brk *bp)
1305 return(CELL_NORMAL);
1306 switch (bp->get_event())
1308 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1312 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1317 t|= CELL_READ_BRK | CELL_WRITE_BRK;
1326 cl_event_handler::copy_from(class cl_event_handler *eh)
1328 int i, t= CELL_NORMAL;
1332 for (i= 0; i < eh->read_bps->count; i++)
1334 class cl_brk *bp= (class cl_brk *)(eh->read_bps->at(i));
1337 for (i= 0; i < eh->write_bps->count; i++)
1339 class cl_brk *bp= (class cl_brk *)(eh->write_bps->at(i));
1346 cl_event_handler::del_bp(class cl_brk *bp)
1350 write_bps->disconn(bp);
1351 read_bps->disconn(bp);
1352 if (write_bps->count)
1354 if (read_bps->count)