ucsim-0.2.37-pre3 into cvs
[fw/sdcc] / sim / ucsim / s51.src / jmp.cc
1 /*
2  * Simulator of microcontrollers (jmp.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 /* Bugs fixed by Sandeep Dutta:
29  *      relative<->absolute jump in "jmp @a+dptr"
30  */
31
32 #include "ddconfig.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 // local
38 #include "uc51cl.h"
39 #include "regs51.h"
40
41
42 /*
43  * 0x[02468ace]1 2 24 AJMP addr
44  *____________________________________________________________________________
45  *
46  */
47
48 int
49 t_uc51::inst_ajmp_addr(uchar code)
50 {
51   uchar h, l;
52
53   h= (code >> 5) & 0x07;
54   l= fetch();
55   tick(1);
56   PC= (PC & 0xf800) | (h*256 + l);
57   return(resGO);
58 }
59
60
61 /*
62  * 0x10 3 12 JBC bit,addr
63  *____________________________________________________________________________
64  *
65  */
66
67 int
68 t_uc51::inst_jbc_bit_addr(uchar code)
69 {
70   uchar bitaddr, *addr, jaddr;
71
72   bitaddr= fetch();
73   jaddr  = fetch();
74   addr   = get_bit(bitaddr, &event_at.ri, &event_at.rs);
75   if (*addr & BIT_MASK(bitaddr))
76     {
77       (*addr)&= ~BIT_MASK(bitaddr);
78       PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1);
79     }
80   return(resGO);
81 }
82
83
84 /*
85  * 0x02 3 24 LJMP addr
86  *____________________________________________________________________________
87  *
88  */
89
90 int
91 t_uc51::inst_ljmp(uchar code)
92 {
93   PC= fetch()*256 + fetch();
94   tick(1);
95   return(resGO);
96 }
97
98
99 /*
100  * 0x[13579bdf]1 2 24 ACALL addr
101  *____________________________________________________________________________
102  *
103  */
104
105 int
106 t_uc51::inst_acall_addr(uchar code)
107 {
108   uchar h, l, *sp, *aof_SP;
109   int res;
110
111   h= (code >> 5) & 0x07;
112   l= fetch();
113   aof_SP= &((sfr->umem8)[SP]);
114   //MEM(MEM_SFR)[SP]++;
115   (*aof_SP)++;
116   proc_write_sp(*aof_SP);
117   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
118   if (res != resGO)
119     res= resSTACK_OV;
120   (*sp)= PC & 0xff; // push low byte
121   tick(1);
122
123   //MEM(MEM_SFR)[SP]++;
124   (*aof_SP)++;
125   proc_write_sp(*aof_SP);
126   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
127   if (res != resGO)
128     res= resSTACK_OV;
129   (*sp)= (PC >> 8) & 0xff; // push high byte
130   PC= (PC & 0xf800) | (h*256 + l);
131   return(res);
132 }
133
134
135 /*
136  * 0x12 3 24 LCALL addr
137  *____________________________________________________________________________
138  *
139  */
140
141 int
142 t_uc51::inst_lcall(uchar code, uint addr)
143 {
144   uchar h= 0, l= 0, *sp, *aof_SP;
145   int res;
146
147   if (!addr)
148     {
149       h= fetch();
150       l= fetch();
151     }
152   aof_SP= &((sfr->umem8)[SP]);
153   //MEM(MEM_SFR)[SP]++;
154   (*aof_SP)++;
155   proc_write_sp(*aof_SP);
156   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
157   if (res != resGO)
158     res= resSTACK_OV;
159   (*sp)= PC & 0xff; // push low byte
160   if (!addr)
161     tick(1);
162
163   //MEM(MEM_SFR)[SP]++;
164   (*aof_SP)++;
165   proc_write_sp(*aof_SP);
166   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
167   if (res != resGO)
168     res= resSTACK_OV;
169   (*sp)= (PC >> 8) & 0xff; // push high byte
170   if (addr)
171     PC= addr;
172   else
173     PC= h*256 + l;
174   return(res);
175 }
176
177
178 /*
179  * 0x20 3 24 JB bit,addr
180  *____________________________________________________________________________
181  *
182  */
183
184 int
185 t_uc51::inst_jb_bit_addr(uchar code)
186 {
187   uchar *addr, bitaddr, jaddr;
188
189   addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs);
190   tick(1);
191   jaddr= fetch();
192   if (read(addr) & BIT_MASK(bitaddr))
193     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
194   return(resGO);
195 }
196
197
198 /*
199  * 0x22 1 24 RET
200  *____________________________________________________________________________
201  *
202  */
203
204 int
205 t_uc51::inst_ret(uchar code)
206 {
207   uchar h, l, *sp, *aof_SP;
208   int res;
209
210   aof_SP= &((sfr->umem8)[SP]);
211   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
212   if (res != resGO)
213     res= resSTACK_OV;
214   h= *sp;
215   //MEM(MEM_SFR)[SP]--;
216   (*aof_SP)--;
217   proc_write_sp(*aof_SP);
218   tick(1);
219
220   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
221   if (res != resGO)
222     res= resSTACK_OV;
223   l= *sp;
224   //MEM(MEM_SFR)[SP]--;
225   (*aof_SP)--;
226   proc_write_sp(*aof_SP);
227   PC= h*256 + l;
228   return(res);
229 }
230
231
232 /*
233  * 0x30 3 24 JNB bit,addr
234  *____________________________________________________________________________
235  *
236  */
237
238 int
239 t_uc51::inst_jnb_bit_addr(uchar code)
240 {
241   uchar *addr, bitaddr, jaddr;
242
243   addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs);
244   tick(1);
245   jaddr= fetch();
246   if (!(read(addr) & BIT_MASK(bitaddr)))
247     PC= (PC + (signed char)jaddr) & (get_mem_size(MEM_ROM)-1);
248   return(resGO);
249 }
250
251
252 /*
253  * 0x32 1 24 RETI
254  *____________________________________________________________________________
255  *
256  */
257
258 int
259 t_uc51::inst_reti(uchar code)
260 {
261   uchar h, l, *sp, *aof_SP;
262   int res;
263
264   aof_SP= &((sfr->umem8)[SP]);
265   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
266   if (res != resGO)
267     res= resSTACK_OV;
268   h= *sp;
269   //MEM(MEM_SFR)[SP]--;
270   (*aof_SP)--;
271   proc_write_sp(*aof_SP);
272   tick(1);
273
274   sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res);
275   if (res != resGO)
276     res= resSTACK_OV;
277   l= *sp;
278   //MEM(MEM_SFR)[SP]--;
279   (*aof_SP)--;
280   proc_write_sp(*aof_SP);
281   PC= h*256 + l;
282
283   was_reti= TRUE;
284   class it_level *il= (class it_level *)(it_levels->top());
285   if (il &&
286       il->level >= 0)
287     {
288       il= (class it_level *)(it_levels->pop());
289       delete il;
290     }
291   return(res);
292 }
293
294
295 /*
296  * 0x40 2 24 JC addr
297  *____________________________________________________________________________
298  *
299  */
300
301 int
302 t_uc51::inst_jc_addr(uchar code)
303 {
304   uchar jaddr;
305
306   jaddr= fetch();
307   tick(1);
308   if (GET_C)
309     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
310   event_at.rs= PSW;
311   return(resGO);
312 }
313
314
315 /*
316  * 0x50 2 24 JNC addr
317  *____________________________________________________________________________
318  *
319  */
320
321 int
322 t_uc51::inst_jnc_addr(uchar code)
323 {
324   uchar jaddr;
325
326   jaddr= fetch();
327   tick(1);
328   if (!GET_C)
329     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
330   event_at.rs= ACC;
331   return(resGO);
332 }
333
334
335 /*
336  * 0x60 2 24 JZ addr
337  *____________________________________________________________________________
338  *
339  */
340
341 int
342 t_uc51::inst_jz_addr(uchar code)
343 {
344   uchar jaddr;
345
346   jaddr= fetch();
347   tick(1);
348   if (!sfr->get(ACC))
349     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
350   return(resGO);
351 }
352
353
354 /*
355  * 0x70 2 24 JNZ addr
356  *____________________________________________________________________________
357  *
358  */
359
360 int
361 t_uc51::inst_jnz_addr(uchar code)
362 {
363   uchar jaddr;
364
365   jaddr= fetch();
366   tick(1);
367   if (sfr->get(ACC))
368     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
369   return(resGO);
370 }
371
372
373 /*
374  * 0x73 1 24 JMP @A+DPTR
375  *____________________________________________________________________________
376  *
377  */
378
379 int
380 t_uc51::inst_jmp_$a_dptr(uchar code)
381 {
382   PC= (sfr->get(DPH)*256 + sfr->get(DPL) +
383        read_mem(MEM_SFR, ACC)) &
384     (EROM_SIZE - 1);
385   return(resGO);
386 }
387
388
389 /*
390  * 0x80 2 24 SJMP addr
391  *____________________________________________________________________________
392  *
393  */
394
395 int
396 t_uc51::inst_sjmp(uchar code)
397 {
398   signed char target= fetch();
399   PC= (PC + target) & (EROM_SIZE -1);
400   tick(1);
401   return(resGO);
402 }
403
404
405 /*
406  * 0xb4 3 24 CJNE A,#data,addr
407  *____________________________________________________________________________
408  *
409  */
410
411 int
412 t_uc51::inst_cjne_a_$data_addr(uchar code)
413 {
414   uchar data, jaddr;
415
416   data = fetch();
417   jaddr= fetch();
418   tick(1);
419   SET_C(sfr->get(ACC) < data);
420   if (read_mem(MEM_SFR, event_at.rs= ACC) != data)
421     PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1);
422   return(resGO);
423 }
424
425
426 /*
427  * 0xb5 3 24 CJNE A,addr,addr
428  *____________________________________________________________________________
429  *
430  */
431
432 int
433 t_uc51::inst_cjne_a_addr_addr(uchar code)
434 {
435   uchar data, *addr, jaddr;
436
437   addr = get_direct(fetch(), &event_at.ri, &event_at.rs);
438   jaddr= fetch();
439   tick(1);
440   data= read(addr);
441   SET_C(sfr->get(ACC) < data);
442   if (sfr->get(event_at.rs= ACC) != data)
443     PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1);
444   return(resGO);
445 }
446
447
448 /*
449  * 0xb6-0xb7 3 24 CJNE @Ri,#data,addr
450  *____________________________________________________________________________
451  *
452  */
453
454 int
455 t_uc51::inst_cjne_$ri_$data_addr(uchar code)
456 {
457   uchar *addr, data, jaddr;
458   int res;
459
460   addr = get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
461   data = fetch();
462   jaddr= fetch();
463   tick(1);
464   SET_C(*addr < data);
465   if (*addr != data)
466     PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1);
467   return(res);
468 }
469
470
471 /*
472  * 0xb8-0xbf 3 24 CJNE Rn,#data,addr
473  *____________________________________________________________________________
474  *
475  */
476
477 int
478 t_uc51::inst_cjne_rn_$data_addr(uchar code)
479 {
480   uchar *reg, data, jaddr;
481
482   reg  = get_reg(code & 0x07, &event_at.ri);
483   data = fetch();
484   jaddr= fetch();
485   tick(1);
486   SET_C(*reg < data);
487   if (*reg != data)
488     PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1);
489   return(resGO);
490 }
491
492
493 /*
494  * 0xd5 3 24 DJNZ addr,addr
495  *____________________________________________________________________________
496  *
497  */
498
499 int
500 t_uc51::inst_djnz_addr_addr(uchar code)
501 {
502   uchar *addr, jaddr;
503   
504   addr = get_direct(fetch(), &event_at.wi, &event_at.ws);
505   jaddr= fetch();
506   if (--(*addr))
507     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
508   return(resGO);
509 }
510
511
512 /*
513  * 0xd8-0xdf 2 24 DJNZ Rn,addr
514  *____________________________________________________________________________
515  *
516  */
517
518 int
519 t_uc51::inst_djnz_rn_addr(uchar code)
520 {
521   uchar *reg, jaddr;
522   
523   reg  = get_reg(code & 0x07, &event_at.wi);
524   jaddr= fetch();
525   if (--(*reg))
526     PC= (PC + (signed char)jaddr) & (EROM_SIZE-1);
527   return(resGO);
528 }
529
530
531 /* End of s51.src/jmp.cc */