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
46 * Memory location handled specially by a hw element
49 cl_memloc::cl_memloc(long addr):
53 hws= new cl_list(2, 2);
57 cl_memloc::~cl_memloc(void)
64 cl_memloc::read(class cl_mem *mem)
72 if ((hw= (class cl_hw *)(hws->at(0))))
73 ret= hw->read(mem, address);
78 cl_memloc::write(class cl_mem *mem, long addr, ulong *val)
85 for (i= 0; i < hws->count; i++)
87 hw= (class cl_hw *)hws->at(0);
88 hw->write(mem, addr, val);
93 /* Sorted collection of memory locations */
95 cl_memloc_coll::cl_memloc_coll(void):
102 cl_memloc_coll::key_of(void *item)
104 return(&(((class cl_memloc *)item)->address));
108 cl_memloc_coll::compare(void *key1, void *key2)
110 if (*(long*)key1 > *(long*)key2)
113 if (*(long*)key1 < *(long*)key2)
120 cl_memloc_coll::get_loc(long address)
124 if (search(&address, i))
125 return((class cl_memloc*)(at(i)));
132 ******************************************************************************
135 cl_mem::cl_mem(enum mem_class atype, t_addr asize, int awidth):
144 for (i= width, mask= 0; i; i--)
147 mem= (TYPE_UBYTE *)malloc(size);
148 else if (width <= 16)
149 mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD));
151 mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD));
152 read_locs= new cl_memloc_coll();
153 write_locs= new cl_memloc_coll();
157 cl_mem::~cl_mem(void)
170 for (i= 0; i < size; i++)
171 set(i, (type==MEM_ROM)?(-1):0);
176 cl_mem::id_string(void)
178 char *s= get_id_string(mem_ids, type);
180 return(s?s:(char*)"NONE");
184 cl_mem::read(t_addr addr)
186 class cl_memloc *loc;
191 fprintf(stderr, "Address 0x%06lx is over 0x%06lx\n", addr, size);
194 if ((loc= read_locs->get_loc(addr)))
195 return(loc->read(this));
197 return((((TYPE_UBYTE*)mem)[addr])&mask);
198 else if (width <= 16)
199 return((((TYPE_UWORD*)mem)[addr])&mask);
201 return((((TYPE_UDWORD*)mem)[addr])&mask);
205 cl_mem::get(t_addr addr)
210 return((((TYPE_UBYTE*)mem)[addr])&mask);
211 else if (width <= 16)
212 return((((TYPE_UWORD*)mem)[addr])&mask);
214 return((((TYPE_UDWORD*)mem)[addr])&mask);
219 * Modify memory location
222 /* Write calls callbacks of HW elements */
225 cl_mem::write(t_addr addr, t_mem *val)
227 class cl_memloc *loc;
231 if ((loc= write_locs->get_loc(addr)))
232 loc->write(this, addr, val);
234 ((TYPE_UBYTE*)mem)[addr]= (*val)&mask;
235 else if (width <= 16)
236 ((TYPE_UWORD*)mem)[addr]= (*val)&mask;
238 ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;
241 /* Set doesn't call callbacks */
244 cl_mem::set(t_addr addr, t_mem val)
249 ((TYPE_UBYTE*)mem)[addr]= val&mask;
250 else if (width <= 16)
251 ((TYPE_UWORD*)mem)[addr]= val&mask;
253 ((TYPE_UDWORD*)mem)[addr]= val&mask;
256 /* Set or clear bits, without callbacks */
259 cl_mem::set_bit1(t_addr addr, t_mem bits)
265 ((TYPE_UBYTE*)mem)[addr]|= bits;
266 else if (width <= 16)
267 ((TYPE_UWORD*)mem)[addr]|= bits;
269 ((TYPE_UDWORD*)mem)[addr]|= bits;
273 cl_mem::set_bit0(t_addr addr, t_mem bits)
279 ((TYPE_UBYTE*)mem)[addr]&= ~bits;
280 else if (width <= 16)
281 ((TYPE_UWORD*)mem)[addr]&= ~bits;
283 ((TYPE_UDWORD*)mem)[addr]&= ~bits;
287 cl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
293 start= dump_finished;
296 while ((start <= stop) &&
299 con->printf("%06x ", start);
300 for (i= 0; (i < bpl) &&
306 sprintf(format, "%%0%dx ", width/4);
307 con->printf(format/*"%02x "*/, get(start+i));
315 for (i= 0; (i < bpl) &&
320 long c= get(start+i);
321 con->printf("%c", isprint(255&c)?(255&c):'.');
323 con->printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
325 con->printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
327 con->printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
330 dump_finished= start+i;
340 cl_bitmap::cl_bitmap(long asize):
343 map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR));
344 memset(map, 0, size);
347 cl_bitmap::~cl_bitmap(void)
353 cl_bitmap::set(long pos)
357 if ((i= pos/(8*SIZEOF_CHAR)) < size)
358 map[i]|= (1 << (pos & ((8*SIZEOF_CHAR)-1)));
362 cl_bitmap::clear(long pos)
366 if ((i= pos/(8*SIZEOF_CHAR)) < size)
367 map[i]&= ~(1 << (pos & ((8*SIZEOF_CHAR)-1)));
371 cl_bitmap::get(long pos)
373 return(map[pos/(8*SIZEOF_CHAR)] & (1 << (pos & ((8*SIZEOF_CHAR)-1))));
377 cl_bitmap::empty(void)
381 for (i= 0; i < size && map[i] == 0; i++) ;
386 * Special memory for code (ROM)
389 cl_rom::cl_rom(long asize, int awidth):
390 cl_mem(MEM_ROM, asize, awidth)
392 bp_map= new cl_bitmap(asize);
393 inst_map= new cl_bitmap(asize);
396 cl_rom::~cl_rom(void)