curses lib detection fix
[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   return(resGO);
47 }
48
49
50 int
51 cl_avr::eijmp(t_mem code)
52 {
53   return(resGO);
54 }
55
56
57 int
58 cl_avr::icall(t_mem code)
59 {
60   return(resGO);
61 }
62
63
64 int
65 cl_avr::eicall(t_mem code)
66 {
67   return(resGO);
68 }
69
70
71 int
72 cl_avr::ret(t_mem code)
73 {
74   return(resGO);
75 }
76
77
78 int
79 cl_avr::reti(t_mem code)
80 {
81   return(resGO);
82 }
83
84
85 /*
86  * Relative Jump
87  * RJMP k -2K<=k<=2K
88  * 1100 kkkk kkkk kkkk
89  *____________________________________________________________________________
90  */
91
92 int
93 cl_avr::rjmp_k(t_mem code)
94 {
95   long k= code & 0xfff, pc;
96
97   if (k & 0x800)
98     k|= -4096;
99   pc= PC+k;
100   if (pc < 0)
101     pc= rom->size + pc;
102   PC= pc % rom->size;
103   tick(1);
104   return(resGO);
105 }
106
107
108 int
109 cl_avr::rcall_k(t_mem code)
110 {
111   return(resGO);
112 }
113
114
115 /*
116  * Compare Skip if Equal
117  * CPSE Rd,Rr 0<=d<=31, 0<=r<=31
118  * 0001 00rd dddd rrrr
119  *____________________________________________________________________________
120  */
121
122 int
123 cl_avr::cpse_Rd_Rr(t_mem code)
124 {
125   t_addr d, r;
126
127   d= (code&0x1f0)>>4;
128   r= ((code&0x200)>>5)|(code&0xf);
129   if (ram->read(r) == ram->read(d))
130     {
131       t_mem next_code= rom->get(PC);
132       int i= 0;
133       struct dis_entry *dt= dis_tbl();
134       while ((next_code & dt[i].mask) != dt[i].code &&
135              dt[i].mnemonic)
136         i++;
137       if (dt[i].mnemonic != NULL)
138         {
139           PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
140           tick(1);
141         }
142       else
143         return(resINV_INST);
144     }
145   return(resGO);
146 }
147
148
149 /*
150  * Jump
151  * JMP k 0<=k<=4M
152  * 1001 010k kkkk 110k
153  * kkkk kkkk kkkk kkkk
154  *____________________________________________________________________________
155  */
156
157 int
158 cl_avr::jmp_k(t_mem code)
159 {
160   t_addr k;
161
162   k= ((code&0x1f0)>>3)|(code&1);
163   k= (k<<16)|fetch();
164   PC= k;
165   //FIXME: analyze
166   tick(2);
167   return(resGO);
168 }
169
170
171 /*
172  * Long Call to a Subroutine
173  * CALL k 0<=k<=64k/4M
174  * 1001 010k kkkk 111k
175  * kkkk kkkk kkkk kkkk
176  *____________________________________________________________________________
177  */
178
179 int
180 cl_avr::call_k(t_mem code)
181 {
182   t_addr k;
183
184   k= (((code&0x1f0)>>3)|(code&1))*0x10000;
185   k= k + fetch();
186
187   tick(3);
188   return(resGO);
189 }
190
191
192 /*
193  * Branch if Bit in SREG is Set
194  * BRBS s,k 0<=s<=7, -64<=k<=+63
195  * 1111 00kk kkkk ksss
196  *____________________________________________________________________________
197  */
198
199 int
200 cl_avr::brbs_s_k(t_mem code)
201 {
202   int s, k;
203
204   k= (code&0x3f8)>>3;
205   s= code&7;
206   t_mem sreg= ram->get(SREG);
207   t_mem mask= 1<<s;
208   if (sreg & mask)
209     {
210       if (code&0x200)
211         k|= -128;
212       PC= (PC+k) % get_mem_size(MEM_ROM);
213       tick(1);
214     }
215   return(resGO);
216 }
217
218
219 /*
220  * Branch if Bit in SREG is Cleared
221  * BRBC s,k 0<=s<=7, -64<=k<=+63
222  * 1111 01kk kkkk ksss
223  *____________________________________________________________________________
224  */
225
226 int
227 cl_avr::brbc_s_k(t_mem code)
228 {
229   int s, k;
230
231   k= (code&0x3f8)>>3;
232   s= code&7;
233   t_mem sreg= ram->get(SREG);
234   t_mem mask= 1<<s;
235   if (!(sreg & mask))
236     {
237       if (code&0x200)
238         k|= -128;
239       PC= (PC+k) % get_mem_size(MEM_ROM);
240       tick(1);
241     }
242   return(resGO);
243 }
244
245
246 /*
247  * Skip if Bit in Register is Cleared
248  * SBRC Rr,b  0<=r<=31, 0<=b<=7
249  * 1111 110r rrrr Xbbb
250  *____________________________________________________________________________
251  */
252
253 int
254 cl_avr::sbrc_Rr_b(t_mem code)
255 {
256   t_addr r= (code&0x1f0)>>4;
257   int b= code&7;
258   t_mem mask= 1<<b;
259   if (!(ram->read(r) & mask))
260     {
261       t_mem next_code= rom->get(PC);
262       int i= 0;
263       struct dis_entry *dt= dis_tbl();
264       while ((next_code & dt[i].mask) != dt[i].code &&
265              dt[i].mnemonic)
266         i++;
267       if (dt[i].mnemonic != NULL)
268         {
269           PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
270           tick(1);
271         }
272       else
273         return(resINV_INST);
274     }
275   return(resGO);
276 }
277
278
279 /*
280  * Skip if Bit in Register is Set
281  * SBRS Rr,b  0<=r<=31, 0<=b<=7
282  * 1111 111r rrrr Xbbb
283  *____________________________________________________________________________
284  */
285
286 int
287 cl_avr::sbrs_Rr_b(t_mem code)
288 {
289   t_addr r= (code&0x1f0)>>4;
290   int b= code&7;
291   t_mem mask= 1<<b;
292   if (ram->read(r) & mask)
293     {
294       t_mem next_code= rom->get(PC);
295       int i= 0;
296       struct dis_entry *dt= dis_tbl();
297       while ((next_code & dt[i].mask) != dt[i].code &&
298              dt[i].mnemonic)
299         i++;
300       if (dt[i].mnemonic != NULL)
301         {
302           PC= (PC + dt[i].length) % get_mem_size(MEM_ROM);
303           tick(1);
304         }
305       else
306         return(resINV_INST);
307     }
308   return(resGO);
309 }
310
311
312 /*
313  * Skip if Bit in I/O Register is Clear
314  * SBIC P,b 0<=P<=31 0<=b<=7
315  * 1001 1001 pppp pbbb
316  *____________________________________________________________________________
317  */
318
319 int
320 cl_avr::sbic_P_b(t_mem code)
321 {
322   uint addr, mask;
323   
324   addr= ((code&0xf8)>>3)+0x20;
325   mask= 1 << (code&7);
326   if (0 == (mask & ram->read(addr)))
327     {
328       code= fetch();
329       int size= inst_length(code);
330       while (size > 1)
331         {
332           fetch();
333           size--;
334         }
335       tick(1);
336     }
337   return(resGO);
338 }
339
340
341 /*
342  * Skip if Bit in I/O Register is Set
343  * SBIS P,b 0<=P<=31 0<=b<=7
344  * 1001 1011 pppp pbbb
345  *____________________________________________________________________________
346  */
347
348 int
349 cl_avr::sbis_P_b(t_mem code)
350 {
351   uint addr, mask;
352   
353   addr= ((code&0xf8)>>3)+0x20;
354   mask= 1 << (code&7);
355   if (mask & ram->read(addr))
356     {
357       code= fetch();
358       int size= inst_length(code);
359       while (size > 1)
360         {
361           fetch();
362           size--;
363         }
364       tick(1);
365     }
366   return(resGO);
367 }
368
369
370 /* End of avr.src/jump_inst.cc */