2 * Simulator of microcontrollers (mem.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
49 * Memory location handled specially by a hw element
52 /*cl_memloc::cl_memloc(t_addr addr):
56 hws= new cl_list(2, 2);
60 /*cl_memloc::~cl_memloc(void)
67 cl_memloc::read(class cl_mem *mem)
75 if ((hw= (class cl_hw *)(hws->at(0))))
76 ret= hw->read(mem, address);
81 cl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val)
88 for (i= 0; i < hws->count; i++)
90 hw= (class cl_hw *)hws->at(0);
91 hw->write(mem, addr, val);
96 /* Sorted collection of memory locations */
98 /*cl_memloc_coll::cl_memloc_coll(void):
101 Duplicates= DD_FALSE;
105 cl_memloc_coll::key_of(void *item)
107 return(&(((class cl_memloc *)item)->address));
111 cl_memloc_coll::compare(void *key1, void *key2)
113 if (*(long*)key1 > *(long*)key2)
116 if (*(long*)key1 < *(long*)key2)
123 cl_memloc_coll::get_loc(t_addr address)
127 if (search(&address, i))
128 return((class cl_memloc*)(at(i)));
135 ******************************************************************************
138 cl_mem::cl_mem(enum mem_class atype, char *aclass_name,
139 t_addr asize, int awidth, class cl_uc *auc):
146 class_name= aclass_name;
150 for (i= width, mask= 0; i; i--)
156 mem= (TYPE_UBYTE *)malloc(size);
157 else if (width <= 16)
158 mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD));
160 mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD));
161 //read_locs= new cl_memloc_coll();
162 //write_locs= new cl_memloc_coll();
164 addr_format= data_format= 0;
167 cl_mem::~cl_mem(void)
184 addr_format= (char *)malloc(10);
185 sprintf(addr_format, "0x%%0%dx",
191 (size-1<=0xffffff?6:12))))));
192 data_format= (char *)malloc(10);
193 sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
195 for (i= 0; i < size; i++)
196 set(i, (type==MEM_ROM)?(-1):0);
201 cl_mem::id_string(void)
203 char *s= get_id_string(mem_ids, type);
205 return(s?s:(char*)"NONE");
209 cl_mem::read(t_addr addr)
211 //class cl_memloc *loc;
216 fprintf(stderr, "Address 0x%06"_A_"x is over 0x%06"_A_"x\n", addr, size);
219 /*if ((loc= read_locs->get_loc(addr)))
220 return(loc->read(this));*/
222 return((((TYPE_UBYTE*)mem)[addr])&mask);
223 else if (width <= 16)
224 return((((TYPE_UWORD*)mem)[addr])&mask);
226 return((((TYPE_UDWORD*)mem)[addr])&mask);
230 cl_mem::get(t_addr addr)
235 return((((TYPE_UBYTE*)mem)[addr])&mask);
236 else if (width <= 16)
237 return((((TYPE_UWORD*)mem)[addr])&mask);
239 return((((TYPE_UDWORD*)mem)[addr])&mask);
244 * Modify memory location
247 /* Write calls callbacks of HW elements */
250 cl_mem::write(t_addr addr, t_mem val)
252 /* class cl_memloc *loc;
256 if ((loc= write_locs->get_loc(addr)))
257 loc->write(this, addr, val);
259 ((TYPE_UBYTE*)mem)[addr]= (*val)&mask;
260 else if (width <= 16)
261 ((TYPE_UWORD*)mem)[addr]= (*val)&mask;
263 ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;*/
264 fprintf(stderr, "FIXME cl_mem::write(0x%06"_A_"x, 0x%04"_M_"x)\n",
269 /* Set doesn't call callbacks */
272 cl_mem::set(t_addr addr, t_mem val)
277 ((TYPE_UBYTE*)mem)[addr]= val&mask;
278 else if (width <= 16)
279 ((TYPE_UWORD*)mem)[addr]= val&mask;
281 ((TYPE_UDWORD*)mem)[addr]= val&mask;
284 /* Set or clear bits, without callbacks */
287 cl_mem::set_bit1(t_addr addr, t_mem bits)
293 ((TYPE_UBYTE*)mem)[addr]|= bits;
294 else if (width <= 16)
295 ((TYPE_UWORD*)mem)[addr]|= bits;
297 ((TYPE_UDWORD*)mem)[addr]|= bits;
301 cl_mem::set_bit0(t_addr addr, t_mem bits)
307 ((TYPE_UBYTE*)mem)[addr]&= ~bits;
308 else if (width <= 16)
309 ((TYPE_UWORD*)mem)[addr]&= ~bits;
311 ((TYPE_UDWORD*)mem)[addr]&= ~bits;
315 cl_mem::add(t_addr addr, long what)
321 ((TYPE_UBYTE*)mem)[addr]= ((TYPE_UBYTE*)mem)[addr] + what;
322 return(((TYPE_UBYTE*)mem)[addr]);
324 else if (width <= 16)
326 ((TYPE_UWORD*)mem)[addr]= ((TYPE_UWORD*)mem)[addr] + what;
327 return(((TYPE_UWORD*)mem)[addr]);
331 ((TYPE_UDWORD*)mem)[addr]= ((TYPE_UDWORD*)mem)[addr] + what;
332 return(((TYPE_UDWORD*)mem)[addr]);
337 cl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
341 while ((start <= stop) &&
344 con->dd_printf(addr_format, start); con->dd_printf(" ");
351 con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
356 j= width/4 + ((width%4)?1:0) + 1;
364 for (i= 0; (i < bpl) &&
369 long c= get(start+i);
370 con->dd_printf("%c", isprint(255&c)?(255&c):'.');
372 con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
374 con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
376 con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
378 con->dd_printf("\n");
379 dump_finished= start+i;
382 return(dump_finished);
386 cl_mem::dump(class cl_console *con)
388 return(dump(dump_finished, dump_finished+10*8-1, 8, con));
392 cl_mem::search_next(bool case_sensitive, t_mem *array, int len, t_addr *addr)
411 for (i= 0; i < len && match; i++)
418 if (/*d1 < 128*/isalpha(d1))
420 if (/*d2 < 128*/isalpha(d2))
440 /*cl_bitmap::cl_bitmap(t_addr asize):
443 map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR));
444 memset(map, 0, size);
447 cl_bitmap::~cl_bitmap(void)
453 cl_bitmap::set(t_addr pos)
457 if ((i= pos/(8*SIZEOF_CHAR)) < size)
458 map[i]|= (1 << (pos & ((8*SIZEOF_CHAR)-1)));
462 cl_bitmap::clear(t_addr pos)
466 if ((i= pos/(8*SIZEOF_CHAR)) < size)
467 map[i]&= ~(1 << (pos & ((8*SIZEOF_CHAR)-1)));
471 cl_bitmap::get(t_addr pos)
473 return(map[pos/(8*SIZEOF_CHAR)] & (1 << (pos & ((8*SIZEOF_CHAR)-1))));
477 cl_bitmap::empty(void)
481 for (i= 0; i < size && map[i] == 0; i++) ;
486 * Special memory for code (ROM)
489 /*cl_rom::cl_rom(t_addr asize, int awidth, class cl_uc *auc):
490 cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth, auc)
492 bp_map= new cl_bitmap(asize);
493 inst_map= new cl_bitmap(asize);
496 cl_rom::~cl_rom(void)
504 * New type of memory simulation
507 cl_normal_cell::cl_normal_cell(uchar awidth):
514 for (--awidth; awidth; awidth--)
522 cl_normal_cell::add(long what)
527 d= TYPE_BYTE(data) + what;
528 else if (width <= 16)
529 d= TYPE_WORD(data) + what;
531 d= TYPE_DWORD(data) + what;
532 return(data= d & mask);
536 cl_normal_cell::wadd(long what)
541 d= TYPE_BYTE(data) + what;
542 else if (width <= 16)
543 d= TYPE_WORD(data) + what;
545 d= TYPE_DWORD(data) + what;
550 cl_normal_cell::set_bit1(t_mem bits)
557 cl_normal_cell::set_bit0(t_mem bits)
567 cl_registered_cell::cl_registered_cell(uchar awidth):
568 cl_normal_cell(awidth)
570 type= CELL_HW_READ | CELL_HW_WRITE;
571 //hws= new cl_list(1, 1);
576 cl_registered_cell::~cl_registered_cell(void)
583 cl_registered_cell::destroy(void)
590 cl_registered_cell::read(void)
596 for (i= 0; i < nuof_hws; i++)
598 d= hardwares[i]->read(this);
605 cl_registered_cell::read(enum hw_cath skip)
611 for (i= 0; i < nuof_hws; i++)
613 if ((skip & hardwares[i]->cathegory) == 0)
614 d= hardwares[i]->read(this);
621 cl_registered_cell::write(t_mem val)
627 for (i= 0; i < nuof_hws; i++)
629 hardwares[i]->write(this, &val);
632 return(data= val & mask);
636 cl_registered_cell::add_hw(class cl_hw *hw, int *ith)
644 hardwares= (class cl_hw **)malloc(sizeof(class cl_hw *));
646 hardwares= (class cl_hw **)realloc(hardwares,
647 sizeof(class c_hw *) * (nuof_hws+1));
648 hardwares[nuof_hws]= hw;
656 cl_registered_cell::get_hw(int ith)
660 return(hardwares[ith]);
667 cl_event_handler::cl_event_handler(class cl_uc *auc):
671 read_bps= new cl_list(1, 1);
672 write_bps= new cl_list(1, 1);
675 cl_event_handler::~cl_event_handler(void)
677 read_bps->disconn_all();
678 write_bps->disconn_all();
684 cl_event_handler::write(void)
688 for (i= 0; i < write_bps->count; i++)
690 class cl_brk *bp= (class cl_brk *)(write_bps->at(i));
696 cl_event_handler::read(void)
700 for (i= 0; i < read_bps->count; i++)
702 class cl_brk *bp= (class cl_brk *)(read_bps->at(i));
708 cl_event_handler::add_bp(class cl_brk *bp)
714 switch (bp->get_event())
716 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
720 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
725 t|= CELL_READ_BRK | CELL_WRITE_BRK;
734 cl_event_handler::copy_from(class cl_event_handler *eh)
736 int i, t= CELL_NORMAL;
740 for (i= 0; i < eh->read_bps->count; i++)
742 class cl_brk *bp= (class cl_brk *)(eh->read_bps->at(i));
745 for (i= 0; i < eh->write_bps->count; i++)
747 class cl_brk *bp= (class cl_brk *)(eh->write_bps->at(i));
754 cl_event_handler::del_bp(class cl_brk *bp)
758 write_bps->disconn(bp);
759 read_bps->disconn(bp);
760 if (write_bps->count)
771 cl_event_cell::cl_event_cell(uchar awidth, class cl_uc *auc):
772 cl_normal_cell(awidth)
774 eh= new cl_event_handler(auc);
777 cl_event_cell::~cl_event_cell(void)
783 cl_event_cell::read(void)
785 if (type & CELL_READ_BRK)
787 return(cl_normal_cell::read());
791 cl_event_cell::write(t_mem val)
793 if (type & CELL_WRITE_BRK)
795 return(cl_normal_cell::write(val));
802 cl_ev_reg_cell::cl_ev_reg_cell(uchar awidth, class cl_uc *auc):
803 cl_registered_cell(awidth)
805 eh= new cl_event_handler(auc);
808 cl_ev_reg_cell::~cl_ev_reg_cell(void)
812 cl_ev_reg_cell::read(void)
814 if (type & CELL_READ_BRK)
816 return(cl_registered_cell::read());
820 cl_ev_reg_cell::write(t_mem val)
822 if (type & CELL_WRITE_BRK)
824 return(cl_registered_cell::write(val));
831 cl_mapped_cell::cl_mapped_cell(class cl_cell *realcell)
836 cl_mapped_cell::~cl_mapped_cell(void)
840 cl_mapped_cell::read(void)
842 return(real_cell->read());
846 cl_mapped_cell::read(enum hw_cath skip)
848 return(real_cell->read(skip));
852 cl_mapped_cell::get(void)
854 return(real_cell->get());
858 cl_mapped_cell::write(t_mem val)
860 return(real_cell->write(val));
864 cl_mapped_cell::set(t_mem val)
866 return(real_cell->set(val));
870 cl_mapped_cell::add(long what)
872 return(real_cell->add(what));
876 cl_mapped_cell::wadd(long what)
878 return(real_cell->wadd(what));
882 cl_mapped_cell::set_bit1(t_mem bits)
884 return(real_cell->set_bit1(bits));
888 cl_mapped_cell::set_bit0(t_mem bits)
890 return(real_cell->set_bit0(bits));
894 cl_mapped_cell::add_hw(class cl_hw *hw, int *ith)
896 return(real_cell->add_hw(hw, ith));
900 cl_mapped_cell::get_hw(int ith)
902 return(real_cell->get_hw(ith));
905 class cl_event_handler *
906 cl_mapped_cell::get_event_handler(void)
908 return(real_cell->get_event_handler());
915 cl_m::cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth,
917 cl_mem(atype, aclass_name, 0, awidth, auc)
923 array= (class cl_cell **)calloc(size, sizeof(class cl_cell *));
924 for (a= 0; a < size; a++)
925 array[a]= new cl_normal_cell(width);
928 for (i= 1; i < size; i<<=1)
929 bus_mask= (bus_mask<<1)|1;
930 dummy= new cl_normal_cell(width);
938 for (a= 0; a < size; a++)
945 cl_m::err_inv_addr(t_addr addr)
949 class cl_error *e= new cl_err_inv_addr(this, addr);
954 cl_m::mk_cell(t_addr addr, class cl_cell *cell)
957 cell= new cl_cell(width);
965 p= (class cl_cell *)calloc(1, sizeof(*cell));
970 p= (class cl_cell *)realloc(p, sizeof(cell));
972 memcpy(p, cell, sizeof(*cell));
978 cl_m::get_cell_flag(t_addr addr)
982 return(dummy->get_type());
984 return(array[addr]->get_type());
988 cl_m::get_cell_flag(t_addr addr, int flag)
992 return(dummy->get_type() & flag);
994 return(array[addr]->get_type() & flag);
998 cl_m::set_cell_flag(t_addr addr, bool set_to, int flag)
1000 class cl_cell *cell;
1009 cell->set_type(cell->get_type() | flag);
1011 cell->set_type(cell->get_type() & ~flag);
1015 cl_m::read(t_addr addr)
1021 return(dummy->read());
1023 return(array[addr]->read());
1027 cl_m::read(t_addr addr, enum hw_cath skip)
1033 return(dummy->read(skip));
1035 return(array[addr]->read(skip));
1039 cl_m::get(t_addr addr)
1045 return(dummy->get());
1047 return(array[addr]->get());
1051 cl_m::write(t_addr addr, t_mem val)
1057 return(dummy->write(val));
1059 return(array[addr]->write(val));
1063 cl_m::set(t_addr addr, t_mem val)
1073 array[addr]->set(val);
1077 cl_m::get_cell(t_addr addr)
1085 return(array[addr]);
1089 /* Set or clear bits, without callbacks */
1092 cl_m::set_bit1(t_addr addr, t_mem bits)
1094 class cl_cell *cell;
1104 bits&= cell->get_mask();
1105 cell->set(cell->get() | bits);
1109 cl_m::write_bit1(t_addr addr, t_mem bits)
1111 class cl_cell *cell;
1121 bits&= cell->get_mask();
1122 cell->write(cell->get() | bits);
1126 cl_m::set_bit0(t_addr addr, t_mem bits)
1128 class cl_cell *cell;
1138 bits&= cell->get_mask();
1139 cell->set(cell->get() & ~bits);
1143 cl_m::write_bit0(t_addr addr, t_mem bits)
1145 class cl_cell *cell;
1155 bits&= cell->get_mask();
1156 cell->write(cell->get() & ~bits);
1160 cl_m::add(t_addr addr, long what)
1166 return(dummy->add(what));
1168 return(array[addr]->add(what));
1172 cl_m::wadd(t_addr addr, long what)
1178 return(dummy->wadd(what));
1180 return(array[addr]->wadd(what));
1184 cl_m::register_hw(t_addr addr, class cl_hw *hw, int *ith, bool announce)
1186 class cl_cell *cell, *nc;
1194 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
1196 /* Already registered */
1197 return(cell->add_hw(hw, ith));
1199 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
1201 /* Event break is set on it, now register hw */
1202 nc= new cl_ev_reg_cell(width, uc);
1203 nc->set(cell->get());
1204 nc->set_type(nc->get_type() &
1205 ~(CELL_GENERAL|CELL_READ_BRK|CELL_WRITE_BRK));
1206 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
1207 class cl_event_handler *eh= nc->get_event_handler();
1209 nc->set_type(nc->get_type() | eh->copy_from(cell->get_event_handler()));
1210 nc->add_hw(hw, ith);
1214 /* Normal cell, register hw */
1215 nc= new cl_registered_cell(width);
1216 nc->set(cell->get());
1217 nc->set_type(nc->get_type() & ~CELL_GENERAL);
1218 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
1219 nc->add_hw(hw, ith);
1233 uc->sim->/*app->*/mem_cell_changed(this, addr);
1238 cl_m::set_brk(t_addr addr, class cl_brk *brk)
1240 class cl_cell *cell, *nc;
1249 switch (brk->get_event())
1251 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1254 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1258 set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
1261 default: e= '.'; break;
1264 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
1266 /* Hw is registered on it, now set event break */
1267 nc= new cl_ev_reg_cell(width, uc);
1268 nc->set(cell->get());
1269 nc->set_type(nc->get_type() & ~CELL_GENERAL);
1270 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
1273 while ((hw= cell->get_hw(i)) != 0)
1278 if (((class cl_registered_cell *)cell)->hardwares)
1280 free(((class cl_registered_cell *)cell)->hardwares);
1281 ((class cl_registered_cell *)cell)->hardwares= 0;
1283 class cl_event_handler *eh;
1284 if ((eh= nc->get_event_handler()))
1285 nc->set_type(nc->get_type() | eh->add_bp(brk));
1287 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
1289 /* Break is already set on it */
1290 class cl_event_handler *eh;
1291 if ((eh= cell->get_event_handler()))
1292 cell->set_type(cell->get_type() | eh->add_bp(brk));
1297 /* Normal cell, set event break */
1298 nc= new cl_event_cell(width, uc);
1299 nc->set(cell->get());
1300 nc->set_type(nc->get_type() & ~CELL_GENERAL);
1301 nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
1302 class cl_event_handler *eh;
1303 if ((eh= nc->get_event_handler()))
1304 nc->set_type(nc->get_type() | eh->add_bp(brk));
1317 uc->sim->/*app->*/mem_cell_changed(this, addr);
1321 cl_m::del_brk(t_addr addr, class cl_brk *brk)
1323 class cl_cell *cell, *nc;
1332 switch (brk->get_event())
1334 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break;
1335 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1339 set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1342 default: e= '.'; break;
1345 if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
1347 /* Hw is registered on it, delete event break */
1348 class cl_event_handler *eh;
1350 if ((eh= cell->get_event_handler()))
1352 if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
1354 cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
1355 cell->set_type(cell->get_type() | t);
1358 nc= new cl_registered_cell(width);
1359 nc->set(cell->get());
1360 nc->set_type(cell->get_type() & ~CELL_GENERAL);
1361 nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
1364 while ((hw= cell->get_hw(i)) != 0)
1369 if (((class cl_registered_cell *)cell)->hardwares)
1370 free(((class cl_registered_cell *)cell)->hardwares);
1372 else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
1374 /* Break already set on it, delete brk */
1375 class cl_event_handler *eh;
1377 if ((eh= cell->get_event_handler()))
1379 if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
1381 cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
1382 cell->set_type(cell->get_type() | t);
1385 nc= new cl_normal_cell(width);
1386 nc->set(cell->get());
1387 nc->set_type(cell->get_type() & ~CELL_GENERAL);
1388 nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
1407 uc->sim->/*app->*/mem_cell_changed(this, addr);
1412 * Errors in memory handling
1415 cl_err_inv_addr::cl_err_inv_addr(class cl_mem *amem, t_addr aaddr):
1423 cl_err_inv_addr::print(class cl_commander *c)
1425 c->dd_printf("Error: invalid address ");
1426 c->dd_printf(mem->addr_format, addr);
1427 c->dd_printf(" in memory %s.\n", mem->class_name);