94ad439a802da1e00de0be1583d82ab3bd50daeb
[fw/sdcc] / sim / ucsim / s51.src / uc390.cc
1 /*
2  * Simulator of microcontrollers (uc390.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  * uc390.cc - module created by Karl Bongers 2001, karl@turbobit.com
9  */
10
11 /* This file is part of microcontroller simulator: ucsim.
12
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING.  If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 02111-1307, USA. */
27 /*@1@*/
28
29 #include "ddconfig.h"
30
31 #include <stdio.h>
32
33 #include "uc390cl.h"
34 #include "regs51.h"
35
36
37 /*
38  * Making an 390 CPU object
39  */
40
41 t_uc390::t_uc390(int Itype, int Itech, class cl_sim *asim):
42   t_uc52(Itype, Itech, asim)
43 {
44 }
45
46 /*
47  * 0x05 2 12 INC addr
48  *____________________________________________________________________________
49  *
50  */
51 int
52 t_uc390::inst_inc_addr(uchar code)
53 {
54   uchar *addr;
55
56   addr= get_direct(fetch(), &event_at.wi, &event_at.ws);
57
58   /* mask off the 2Hex bit adjacent to the 1H bit which selects
59      which DPTR we use.  This is a feature of 80C390.
60      You can do INC DPS and it only effects bit 1. */
61   if (code  == DPS)
62     (*addr) ^= 1;  /* just toggle */
63   else {
64     (*addr)++;
65   }
66
67   proc_write(addr);
68   return(resGO);
69 }
70
71 /*
72  * 0xa3 1 24 INC DPTR
73  *____________________________________________________________________________
74  *
75  */
76
77 int
78 t_uc390::inst_inc_dptr(uchar code)
79 {
80   uint dptr;
81
82   unsigned char pl,ph,dps;
83
84   dps = sfr->get(DPS);
85   if (dps & 1) {
86     pl = DPL1;
87     ph = DPH1;
88   } else {
89     pl = DPL;
90     ph = DPH;
91   }
92
93   if (dps & 1) { /* alternate DPTR */
94     if (dps & 0x80)  /* decr set */
95       dptr= sfr->get(ph)*256 + sfr->get(pl) - 1;
96     else
97       dptr= sfr->get(ph)*256 + sfr->get(pl) + 1;
98   } else {
99     if (dps & 0x40)  /* decr set */
100       dptr= sfr->get(ph)*256 + sfr->get(pl) - 1;
101     else
102       dptr= sfr->get(ph)*256 + sfr->get(pl) + 1;
103   }
104
105   sfr->set(event_at.ws= ph, (dptr >> 8) & 0xff);
106   sfr->set(pl, dptr & 0xff);
107
108   if (dps & 0x20) {                  /* auto-switch dptr */
109     sfr->set(DPS, (dps ^ 1));  /* toggle dual-dptr switch */
110   }
111   tick(1);
112   return(resGO);
113 }
114
115 /*
116  * 0x73 1 24 JMP @A+DPTR
117  *____________________________________________________________________________
118  *
119  */
120
121 int
122 t_uc390::inst_jmp_$a_dptr(uchar code)
123 {
124     unsigned char pl,ph,dps;
125
126     dps = sfr->get(DPS);
127     if (dps & 1) {
128       pl = DPL1;
129       ph = DPH1;
130     } else {
131       pl = DPL;
132       ph = DPH;
133     }
134
135     PC= (sfr->get(ph)*256 + sfr->get(pl) +
136          read_mem(MEM_SFR, ACC)) &
137       (EROM_SIZE - 1);
138
139   tick(1);
140   return(resGO);
141 }
142
143 /*
144  * 0x90 3 24 MOV DPTR,#data
145  *____________________________________________________________________________
146  *
147  */
148
149 int
150 t_uc390::inst_mov_dptr_$data(uchar code)
151 {
152     unsigned char pl,ph,dps;
153
154     dps = sfr->get(DPS);
155     if (dps & 1) {
156       pl = DPL1;
157       ph = DPH1;
158     } else {
159       pl = DPL;
160       ph = DPH;
161     }
162
163     sfr->set(event_at.ws= ph, fetch());
164     sfr->set(pl, fetch());
165
166     if (dps & 0x20) {                  /* auto-switch dptr */
167       sfr->set(DPS, (dps ^ 1));  /* toggle dual-dptr switch */
168     }
169
170   tick(1);
171   return(resGO);
172 }
173
174
175 /*
176  * 0x93 1 24 MOVC A,@A+DPTR
177  *____________________________________________________________________________
178  *
179  */
180
181 int
182 t_uc390::inst_movc_a_$a_dptr(uchar code)
183 {
184     unsigned char pl,ph,dps;
185
186     dps = sfr->get(DPS);
187     if (dps & 1) {
188       pl = DPL1;
189       ph = DPH1;
190     } else {
191       pl = DPL;
192       ph = DPH;
193     }
194
195     sfr->set(ACC, get_mem(MEM_ROM, event_at.rc=
196                                 (sfr->get(ph)*256+sfr->get(pl) +
197                                  sfr->get(ACC)) & (EROM_SIZE-1)));
198
199 #if 0
200     if (dps & 0x10) {                  /* auto-incr */
201       unsigned char t;
202       t = (sfr->get(pl) + 1) & 0xff;
203       sfr->set(pl, t);
204       if (t == 0) { /* overflow */
205         t = (sfr->get(ph) + 1) & 0xff;
206         sfr->set(ph, t);
207       }
208     }
209 #endif
210
211     if (dps & 0x20) {                  /* auto-switch dptr */
212       sfr->set(DPS, (dps ^ 1));  /* toggle dual-dptr switch */
213     }
214
215   tick(1);
216   return(resGO);
217 }
218
219 /*
220  * 0xe0 1 24 MOVX A,@DPTR
221  *____________________________________________________________________________
222  *
223  */
224
225 int
226 t_uc390::inst_movx_a_$dptr(uchar code)
227 {
228     unsigned char pl,ph,dps;
229
230     dps = sfr->get(DPS);
231     if (dps & 1) {
232       pl = DPL1;
233       ph = DPH1;
234     } else {
235       pl = DPL;
236       ph = DPH;
237     }
238
239     sfr->set(event_at.ws= ACC,
240            get_mem(MEM_XRAM, event_at.rx=sfr->get(ph)*256+sfr->get(pl)));
241
242 #if 0
243     if (dps & 0x10) {                  /* auto-incr */
244       unsigned char t;
245       t = (sfr->get(pl) + 1) & 0xff;
246       sfr->set(pl, t);
247       if (t == 0) { /* overflow */
248         t = (sfr->get(ph) + 1) & 0xff;
249         sfr->set(ph, t);
250       }
251     }
252 #endif
253
254     if (dps & 0x20) {                  /* auto-switch dptr */
255       sfr->set(DPS, (dps ^ 1));  /* toggle dual-dptr switch */
256     }
257   tick(1);
258   return(resGO);
259 }
260
261 /*
262  * 0xf0 1 24 MOVX @DPTR,A
263  *____________________________________________________________________________
264  *
265  */
266
267 int
268 t_uc390::inst_movx_$dptr_a(uchar code)
269 {
270     unsigned char pl,ph,dps;
271
272     dps = sfr->get(DPS);
273     if (dps & 1) {
274       pl = DPL1;
275       ph = DPH1;
276     } else {
277       pl = DPL;
278       ph = DPH;
279     }
280
281     set_mem(MEM_XRAM, event_at.wx= sfr->get(ph)*256+sfr->get(pl),
282           sfr->get(event_at.rs= ACC));
283
284 #if 0
285     if (dps & 0x10) {                  /* auto-incr */
286       unsigned char t;
287       t = (sfr->get(pl) + 1) & 0xff;
288       sfr->set(pl, t);
289       if (t == 0) { /* overflow */
290         t = (sfr->get(ph) + 1) & 0xff;
291         sfr->set(ph, t);
292       }
293     }
294 #endif
295
296     if (dps & 0x20) {                  /* auto-switch dptr */
297       sfr->set(DPS, (dps ^ 1));  /* toggle dual-dptr switch */
298     }
299   tick(1);
300   return(resGO);
301 }
302
303
304
305 /* End of s51.src/uc390.cc */