49c9769b55a3ec5ecd940e21269166ea84d8569f
[fw/sdcc] / sim / ucsim / avr.src / jump_inst.cc
1 /*
2  * Simulator of microcontrollers (jmp_inst.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 /* 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 #include "avrcl.h"
29 #include "regsavr.h"
30
31
32 /*
33  * Indirect Jump
34  * IJMP
35  * 1001 0100 XXXX 1001
36  *____________________________________________________________________________
37  */
38
39 int
40 cl_avr::ijmp(t_mem code)
41 {
42   t_addr z;
43
44   z= ram->get(ZH)*256 + ram->get(ZL);
45   PC= ((PC & ~0xffff) | z) % rom->size;
46   //FIXME: analyze
47   return(resGO);
48 }
49
50
51 int
52 cl_avr::eijmp(t_mem code)
53 {
54   return(resGO);
55 }
56
57
58 /*
59  * Indirect Call to Subroutine
60  * ICALL
61  * 1001 0101 XXXX 1001
62  *____________________________________________________________________________
63  */
64
65 int
66 cl_avr::icall(t_mem code)
67 {
68   t_mem zl, zh;
69   t_addr z;
70   
71   push_addr(PC);
72   zl= ram->read(ZL);
73   zh= ram->read(ZH);
74   z= zh*256 + zl;
75   PC= (PC & ~0xffff) | (z & 0xffff);
76   //FIXME: analyze
77   tick(2);
78   return(resGO);
79 }
80
81
82 int
83 cl_avr::eicall(t_mem code)
84 {
85   return(resGO);
86 }
87
88
89 /*
90  * Return from Subroutine
91  * RET
92  * 1001 0101 0XX0 1000
93  *____________________________________________________________________________
94  */
95
96 int
97 cl_avr::ret(t_mem code)
98 {
99   t_addr a;
100
101   pop_addr(&a);
102   PC= a % rom->size;
103   tick(3);
104   return(resGO);
105 }
106
107
108 /*
109  * Return from Interrupt
110  * RETI
111  * 1001 0101 0XX1 1000
112  *____________________________________________________________________________
113  */
114
115 int
116 cl_avr::reti(t_mem code)
117 {
118   t_addr a;
119
120   pop_addr(&a);
121   PC= a % rom->size;
122   t_mem sreg= ram->read(SREG);
123   sreg|= BIT_I;
124   ram->write(SREG, sreg);
125   tick(3);
126   return(resGO);
127 }
128
129
130 /*
131  * Relative Jump
132  * RJMP k -2K<=k<=2K
133  * 1100 kkkk kkkk kkkk
134  *____________________________________________________________________________
135  */
136
137 int
138 cl_avr::rjmp_k(t_mem code)
139 {
140   long k= code & 0xfff, pc;
141
142   if (k & 0x800)
143     k|= -4096;
144   pc= PC+k;
145   if (pc < 0)
146     pc= rom->size + pc;
147   PC= pc % rom->size;
148   tick(1);
149   return(resGO);
150 }
151
152
153 /*
154  * Relative Call to Subroutine
155  * RCALL k
156  * 1101 kkkk kkkk kkkk -1K<=k<=+1k
157  *____________________________________________________________________________
158  */
159
160 int
161 cl_avr::rcall_k(t_mem code)
162 {
163   t_addr k;
164
165   push_addr(PC);
166   k= code & 0xfff;
167   if (k & 0x800)
168     k|= ~0xfff;
169   PC= (signed)PC + (signed)k;
170   PC= PC % rom->size;
171   tick(2);
172
173   return(resGO);
174 }
175
176
177 /*
178  * Compare Skip if Equal
179  * CPSE Rd,Rr 0<=d<=31, 0<=r<=31
180  * 0001 00rd dddd rrrr
181  *____________________________________________________________________________
182  */
183
184 int
185 cl_avr::cpse_Rd_Rr(t_mem code)
186 {
187   t_addr d, r;
188
189   d= (code&0x1f0)>>4;
190   r= ((code&0x200)>>5)|(code&0xf);
191   if (ram->read(r) == ram->read(d))
192     {
193       t_mem next_code= rom->get(PC);
194       int i= 0;
195       struct dis_entry *dt= dis_tbl();
196       while ((next_code & dt[i].mask) != dt[i].code &&
197              dt[i].mnemonic)
198         i++;
199       if (dt[i].mnemonic != NULL)
200         {
201           PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
202           tick(1);
203         }
204       else
205         return(resINV_INST);
206     }
207   return(resGO);
208 }
209
210
211 /*
212  * Jump
213  * JMP k 0<=k<=4M
214  * 1001 010k kkkk 110k
215  * kkkk kkkk kkkk kkkk
216  *____________________________________________________________________________
217  */
218
219 int
220 cl_avr::jmp_k(t_mem code)
221 {
222   t_addr k;
223
224   k= ((code&0x1f0)>>3)|(code&1);
225   k= (k<<16)|fetch();
226   PC= k % rom->size;
227   tick(2);
228   return(resGO);
229 }
230
231
232 /*
233  * Long Call to a Subroutine
234  * CALL k 0<=k<=64k/4M
235  * 1001 010k kkkk 111k
236  * kkkk kkkk kkkk kkkk
237  *____________________________________________________________________________
238  */
239
240 int
241 cl_avr::call_k(t_mem code)
242 {
243   t_addr k;
244
245   k= (((code&0x1f0)>>3)|(code&1))*0x10000;
246   k= k + fetch();
247   push_addr(PC);
248   PC= k % rom->size;
249   tick(3);
250   return(resGO);
251 }
252
253
254 /*
255  * Branch if Bit in SREG is Set
256  * BRBS s,k 0<=s<=7, -64<=k<=+63
257  * 1111 00kk kkkk ksss
258  *____________________________________________________________________________
259  */
260
261 int
262 cl_avr::brbs_s_k(t_mem code)
263 {
264   int s, k;
265
266   k= (code&0x3f8)>>3;
267   s= code&7;
268   t_mem sreg= ram->get(SREG);
269   t_mem mask= 1<<s;
270   if (sreg & mask)
271     {
272       if (code&0x200)
273         k|= -128;
274       PC= (PC+k) % rom->size;
275       tick(1);
276     }
277   return(resGO);
278 }
279
280
281 /*
282  * Branch if Bit in SREG is Cleared
283  * BRBC s,k 0<=s<=7, -64<=k<=+63
284  * 1111 01kk kkkk ksss
285  *____________________________________________________________________________
286  */
287
288 int
289 cl_avr::brbc_s_k(t_mem code)
290 {
291   int s, k;
292
293   k= (code&0x3f8)>>3;
294   s= code&7;
295   t_mem sreg= ram->get(SREG);
296   t_mem mask= 1<<s;
297   if (!(sreg & mask))
298     {
299       if (code&0x200)
300         k|= -128;
301       PC= (PC+k) % rom->size;
302       tick(1);
303     }
304   return(resGO);
305 }
306
307
308 /*
309  * Skip if Bit in Register is Cleared
310  * SBRC Rr,b  0<=r<=31, 0<=b<=7
311  * 1111 110r rrrr Xbbb
312  *____________________________________________________________________________
313  */
314
315 int
316 cl_avr::sbrc_Rr_b(t_mem code)
317 {
318   t_addr r= (code&0x1f0)>>4;
319   int b= code&7;
320   t_mem mask= 1<<b;
321   if (!(ram->read(r) & mask))
322     {
323       t_mem next_code= rom->get(PC);
324       int i= 0;
325       struct dis_entry *dt= dis_tbl();
326       while ((next_code & dt[i].mask) != dt[i].code &&
327              dt[i].mnemonic)
328         i++;
329       if (dt[i].mnemonic != NULL)
330         {
331           PC= (PC + dt[i].length) % rom->size;
332           tick(1);
333         }
334       else
335         return(resINV_INST);
336     }
337   return(resGO);
338 }
339
340
341 /*
342  * Skip if Bit in Register is Set
343  * SBRS Rr,b  0<=r<=31, 0<=b<=7
344  * 1111 111r rrrr Xbbb
345  *____________________________________________________________________________
346  */
347
348 int
349 cl_avr::sbrs_Rr_b(t_mem code)
350 {
351   t_addr r= (code&0x1f0)>>4;
352   int b= code&7;
353   t_mem mask= 1<<b;
354   if (ram->read(r) & mask)
355     {
356       t_mem next_code= rom->get(PC);
357       int i= 0;
358       struct dis_entry *dt= dis_tbl();
359       while ((next_code & dt[i].mask) != dt[i].code &&
360              dt[i].mnemonic)
361         i++;
362       if (dt[i].mnemonic != NULL)
363         {
364           PC= (PC + dt[i].length) % rom->size;
365           tick(1);
366         }
367       else
368         return(resINV_INST);
369     }
370   return(resGO);
371 }
372
373
374 /*
375  * Skip if Bit in I/O Register is Clear
376  * SBIC P,b 0<=P<=31 0<=b<=7
377  * 1001 1001 pppp pbbb
378  *____________________________________________________________________________
379  */
380
381 int
382 cl_avr::sbic_P_b(t_mem code)
383 {
384   uint addr, mask;
385   
386   addr= ((code&0xf8)>>3)+0x20;
387   mask= 1 << (code&7);
388   if (0 == (mask & ram->read(addr)))
389     {
390       code= fetch();
391       int size= inst_length(code);
392       while (size > 1)
393         {
394           fetch();
395           size--;
396         }
397       tick(1);
398     }
399   return(resGO);
400 }
401
402
403 /*
404  * Skip if Bit in I/O Register is Set
405  * SBIS P,b 0<=P<=31 0<=b<=7
406  * 1001 1011 pppp pbbb
407  *____________________________________________________________________________
408  */
409
410 int
411 cl_avr::sbis_P_b(t_mem code)
412 {
413   uint addr, mask;
414   
415   addr= ((code&0xf8)>>3)+0x20;
416   mask= 1 << (code&7);
417   if (mask & ram->read(addr))
418     {
419       code= fetch();
420       int size= inst_length(code);
421       while (size > 1)
422         {
423           fetch();
424           size--;
425         }
426       tick(1);
427     }
428   return(resGO);
429 }
430
431
432 /* End of avr.src/jump_inst.cc */