1 /*
2  * Simulator of microcontrollers (sim.src/uccl.h)
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 /* This file is part of microcontroller simulator: ucsim.
11 
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.
16 
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.
21 
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
25 02111-1307, USA. */
26 /*@1@*/
27 
28 #ifndef SIM_UCCL_HEADER
29 #define SIM_UCCL_HEADER
30 
31 // prj
32 #include "stypes.h"
33 #include "pobjcl.h"
34 #include "pobjt.h"
35 
36 // sim
37 #include "hwcl.h"
38 #include "memcl.h"
39 #include "brkcl.h"
40 #include "stackcl.h"
41 #include "varcl.h"
42 
43 
44 class cl_uc;
45 
46 typedef int (*instruction_wrapper_fn)(class cl_uc *uc, t_mem code);
47 
48 /* Counter to count clock ticks */
49 
50 #define TICK_RUN	0x01
51 #define TICK_INISR	0x02
52 #define TICK_IDLE	0x03
53 
54 class cl_ticker: public cl_base
55 {
56 public:
57   unsigned long ticks;
58   int options; // see TICK_XXX above
59   int dir;
60   //char *name;
61 
62   cl_ticker(int adir, int in_isr, const char *aname);
63   virtual ~cl_ticker(void);
64 
65   virtual int tick(int nr);
66   virtual double get_rtime(double xtal);
67   virtual void dump(int nr, double xtal, class cl_console_base *con);
68 };
69 
70 
71 /* Options of the microcontroller */
72 class cl_xtal_option: public cl_optref
73 {
74 protected:
75   class cl_uc *uc;
76 public:
77   cl_xtal_option(class cl_uc *the_uc);
78   virtual void option_changed(void);
79 };
80 
81 struct vcounter_t {
82   t_mem inst;
83   t_mem fetch;
84   t_mem rd;
85   t_mem wr;
86 };
87 
88 class cl_time_measurer: public cl_base
89 {
90 public:
91   unsigned long to_reach;
92   class cl_uc *uc;
93 public:
94   cl_time_measurer(class cl_uc *the_uc);
95   virtual void set_reach(unsigned long val);
96   virtual void from_now(unsigned long val);
97   virtual bool reached();
98   virtual unsigned long now();
99 };
100 
101 class cl_time_clk: public cl_time_measurer
102 {
103 public:
cl_time_clk(class cl_uc * the_uc)104   cl_time_clk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("clk"); }
105   virtual unsigned long now();
106 };
107 
108 class cl_time_vclk: public cl_time_measurer
109 {
110 public:
cl_time_vclk(class cl_uc * the_uc)111   cl_time_vclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("vclk"); }
112   virtual unsigned long now();
113 };
114 
115 class cl_time_fclk: public cl_time_measurer
116 {
117 public:
cl_time_fclk(class cl_uc * the_uc)118   cl_time_fclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("fclk"); }
119   virtual unsigned long now();
120 };
121 
122 class cl_time_rclk: public cl_time_measurer
123 {
124 public:
cl_time_rclk(class cl_uc * the_uc)125   cl_time_rclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("rclk"); }
126   virtual unsigned long now();
127 };
128 
129 class cl_time_wclk: public cl_time_measurer
130 {
131 public:
cl_time_wclk(class cl_uc * the_uc)132   cl_time_wclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("wclk"); }
133   virtual unsigned long now();
134 };
135 
136 
137 class cl_omf_rec: public cl_base
138 {
139  protected:
140   unsigned int f_offset, offset;
141  public:
142   u8_t type;
143   u16_t len;
144   u8_t *rec;
145   u8_t chk;
146  public:
147   cl_omf_rec(void);
148   virtual ~cl_omf_rec(void);
149   virtual unsigned char g(cl_f *f);
150   virtual u16_t pick_word(int i);
151   virtual chars pick_str(int i);
152   virtual bool read(cl_f *f);
153 };
154 
155 class cl_cdb_rec: public cl_base
156 {
157  public:
158   chars fname;
159   t_addr addr;
160  public:
cl_cdb_rec(chars fn)161  cl_cdb_rec(chars fn): cl_base() { fname= fn; }
cl_cdb_rec(chars fn,t_addr a)162  cl_cdb_rec(chars fn, t_addr a): cl_base() { fname= fn; addr= a; }
163 };
164 
165 class cl_cdb_recs: public cl_sorted_list
166 {
167  public:
cl_cdb_recs()168  cl_cdb_recs(): cl_sorted_list(2,2,"cdb_recs_list") {}
key_of(void * item)169   virtual void *key_of(void *item)
170   { return (char*)(((cl_cdb_rec *)item)->fname); }
compare(void * k1,void * k2)171   virtual int compare(void *k1, void *k2) {
172     return strcmp((char*)k1,(char*)k2);
173   }
rec(chars n)174   virtual cl_cdb_rec *rec(chars n) {
175     t_index i;
176     if (search((char*)n, i))
177       return (cl_cdb_rec*)(at(i));
178     return NULL;
179   }
del(chars n)180   virtual void del(chars n) {
181     t_index i;
182     if (search((char*)n,i))
183       free_at(i);
184   }
185 };
186 
187 /* Abstract microcontroller */
188 
189 class cl_uc: public cl_base
190 {
191 public:
192   struct cpu_entry *type;
193   //enum cpu_type type;			// CPU family
194   //int technology;		// CMOS, HMOS
195   int state;			// GO, IDLE, PD
196   //class cl_list *options;
197   class cl_xtal_option *xtal_option;
198 
199   t_addr PC, instPC;		// Program Counter
200   bool inst_exec;		// Instruction is executed
201   class cl_ticker *ticks;	// Nr of XTAL clocks
202   class cl_ticker *isr_ticks;	// Time in ISRs
203   class cl_ticker *idle_ticks;	// Time in idle mode
204   class cl_list *counters;	// User definable timers (tickers)
205   int inst_ticks;		// ticks of an instruction
206   double xtal;			// Clock speed
207   struct vcounter_t vc;		// Virtual clk counter
208 
209   int brk_counter;		// Number of breakpoints
210   class brk_coll *fbrk;		// Collection of FETCH break-points
211   class brk_coll *ebrk;		// Collection of EVENT breakpoints
212   class cl_sim *sim;
213   //class cl_list *mems;
214   class cl_time_measurer *stop_at_time;
215  public:
216   class cl_hw *cpu;
217   class cl_hws *hws;
218 
219  public:
220   class cl_list *memchips;      // v3
221   class cl_address_space_list *address_spaces;
222   class cl_address_space *rom;  // Required for almost every uc
223   //class cl_list *address_decoders;
224   class cl_address_space *variables;
225   class cl_var_list *vars;
226 
227   bool irq;
228   class cl_irqs *it_sources;	// Sources of interrupts
229   class cl_list *it_levels;	// Follow interrupt services
230   class cl_list *stack_ops;	// Track stack operations
231 
232   class cl_list *errors;	// Errors of instruction execution
233   class cl_list *events;	// Events happened during inst exec
234 
235   t_addr sp_max;
236   t_addr sp_avg;
237 
238 public:
239   cl_uc(class cl_sim *asim);
240   virtual ~cl_uc(void);
241   virtual int init(void);
242   virtual char *id_string(void);
243   virtual void reset(void);
244 
245   // making objects
246   virtual void make_memories(void);
247   virtual void make_variables(void);
248   virtual void make_cpu_hw(void);
249   virtual void mk_hw_elements(void);
250   virtual void build_cmdset(class cl_cmdset *cmdset);
251 
252   // manipulating memories
253   virtual t_mem read_mem(char *id, t_addr addr);
254   virtual t_mem get_mem(char *id, t_addr addr);
255   virtual void write_mem(char *id, t_addr addr, t_mem val);
256   virtual void set_mem(char *id, t_addr addr, t_mem val);
257   virtual class cl_address_space *address_space(const char *id);
258   virtual class cl_address_space *address_space(class cl_memory_cell *cell);
259   virtual class cl_address_space *address_space(class cl_memory_cell *cell, t_addr *addr);
260   virtual class cl_memory *memory(const char *id);
261 
262   // file handling
263   virtual void set_rom(t_addr addr, t_mem val);
264   virtual long read_hex_file(const char *nam);
265   virtual long read_hex_file(cl_console_base *con);
266   virtual long read_hex_file(cl_f *f);
267   virtual long read_omf_file(cl_f *f);
268   virtual long read_cdb_file(cl_f *f);
269   virtual cl_f *find_loadable_file(chars nam);
270   virtual long read_file(chars nam, class cl_console_base *con);
271 
272   // instructions, code analyzer
analyze(t_addr addr)273   virtual void analyze(t_addr addr) {}
274   virtual bool inst_at(t_addr addr);
275   virtual void set_inst_at(t_addr addr);
276   virtual void del_inst_at(t_addr addr);
277   virtual bool there_is_inst(void);
278 
279   // manipulating hw elements
280   virtual void add_hw(class cl_hw *hw);
281   virtual int nuof_hws(void);
282   virtual class cl_hw *get_hw(int idx);
283   virtual class cl_hw *get_hw(enum hw_cath cath, int *idx);
284   virtual class cl_hw *get_hw(char *id_string, int *idx);
285   virtual class cl_hw *get_hw(enum hw_cath cath, int hwid, int *idx);
286   virtual class cl_hw *get_hw(char *id_string, int hwid, int *idx);
287   virtual int get_max_hw_id(enum hw_cath cath);
288 
289   // "virtual" timers
290   virtual int tick_hw(int cycles);
291   virtual void do_extra_hw(int cycles);
292   virtual int tick(int cycles);
293   virtual class cl_ticker *get_counter(int nr);
294   virtual class cl_ticker *get_counter(const char *nam);
295   virtual void add_counter(class cl_ticker *ticker, int nr);
296   virtual void add_counter(class cl_ticker *ticker, const char *nam);
297   virtual void del_counter(int nr);
298   virtual void del_counter(const char *nam);
299   virtual double get_rtime(void);
300   virtual unsigned long clocks_of_time(double t);
301   virtual int clock_per_cycle(void);
302   virtual void touch(void);
303 
304   // execution
305   virtual t_mem fetch(void);
306   virtual bool fetch(t_mem *code);
307   virtual int do_inst(int step);
308   virtual void pre_inst(void);
309   virtual int exec_inst(void);
310   virtual int exec_inst_tab(instruction_wrapper_fn itab[]);
311   virtual void post_inst(void);
312 
313   virtual int do_interrupt(void);
priority_of(uchar nuof_it)314   virtual int priority_of(uchar nuof_it) {return(0);}
priority_main()315   virtual int priority_main() { return 0; }
316   virtual int accept_it(class it_level *il);
it_enabled(void)317   virtual bool it_enabled(void) { return false; }
318 
319 #include "uccl_instructions.h"
320 
321   // stack tracking
322   virtual void stack_write(class cl_stack_op *op);
323   virtual void stack_read(class cl_stack_op *op);
324 
325   // breakpoints
326   virtual class cl_fetch_brk *fbrk_at(t_addr addr);
327   virtual class cl_ev_brk *ebrk_at(t_addr addr, char *id);
328   virtual class cl_brk *brk_by_nr(int nr);
329   virtual class cl_brk *brk_by_nr(class brk_coll *bpcoll, int nr);
330   virtual void rm_ebrk(t_addr addr, char *id);
331   virtual bool rm_brk(int nr);
332   virtual void put_breaks(void);
333   virtual void remove_all_breaks(void);
334   virtual int make_new_brknr(void);
335   virtual class cl_ev_brk *mk_ebrk(enum brk_perm perm,
336 				   class cl_address_space *mem,
337 				   char op, t_addr addr, int hit);
338   virtual void check_events(void);
339   virtual void stop_when(class cl_time_measurer *t);
340 
341   // disassembling and symbol recognition
342   virtual char *disass(t_addr addr, const char *sep);
343   virtual struct dis_entry *dis_tbl(void);
344   virtual void print_disass(t_addr addr, class cl_console_base *con);
345   virtual void print_regs(class cl_console_base *con);
346   virtual int inst_length(t_addr addr);
347   virtual int inst_branch(t_addr addr);
348   virtual bool is_call(t_addr addr);
349   virtual int longest_inst(void);
350   virtual bool addr_name(t_addr addr, class cl_address_space *as, char *buf);
351   virtual bool addr_name(t_addr addr, class cl_address_space *as, int bitnr, char *buf);
352   virtual bool symbol2address(char *sym,
353 			      class cl_address_space **as,
354 			      t_addr *addr);
355   virtual char *symbolic_bit_name(t_addr bit_address,
356 				  class cl_memory *mem,
357 				  t_addr mem_addr,
358 				  t_mem bit_mask);
359   virtual name_entry *get_name_entry(struct name_entry tabl[],
360 				     char *name);
361   virtual chars cell_name(class cl_memory_cell *cell);
362   virtual class cl_var *var(char *nam);
363 
364   /* Converting abstract address spaces into real ones */
365   virtual class cl_address_space *bit2mem(t_addr bitaddr,
366 					  t_addr *memaddr,
367 					  t_mem *bitmask);
bit_address(class cl_memory * mem,t_addr mem_address,int bit_number)368   virtual t_addr bit_address(class cl_memory *mem,
369                              t_addr mem_address,
370                              int bit_number) { return(-1); }
371 
372   // messages from app to handle and broadcast
373   virtual bool handle_event(class cl_event &event);
374   virtual void address_space_added(class cl_address_space *as);
375 
376   // Error handling
377   virtual void error(class cl_error *error);
378   virtual void check_errors(void);
379 
380   /* Following fields and virtual methods defined in uc51 I don't have
381      energy to redesign them:-( */
382 public:
eram2xram(void)383   virtual void eram2xram(void) {} // Dirty hack for 51R
xram2eram(void)384   virtual void xram2eram(void) {}
385 };
386 
387 
388 /*
389  * Errors
390  */
391 
392 #include "errorcl.h"
393 
394 class cl_error_unknown_code: public cl_error
395 {
396  protected:
397   class cl_uc *uc;
398  public:
399   cl_error_unknown_code(class cl_uc *the_uc);
400 
401   virtual void print(class cl_commander_base *c);
402 };
403 
404 class cl_uc_error_registry: public cl_error_registry
405 {
406 public:
407   cl_uc_error_registry(void);
408 };
409 
410 
411 #endif
412 
413 /* End of uccl.h */
414