[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / sims / pdk.src / pdk13.cc
blobff11929d5065f67357d85a725166f94deab4f06c
1 /*
2 * Simulator of microcontrollers (pdk13.cc)
4 * Copyright (C) 2016 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
10 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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@*/
28 #include "glob.h"
30 #include "t16cl.h"
31 #include "wdtcl.h"
33 #include "pdk13cl.h"
36 cl_fpp13::cl_fpp13(int aid, class cl_pdk *the_puc, class cl_sim *asim):
37 cl_fpp(aid, the_puc, asim)
39 type= new struct cpu_entry;
40 type->type= CPU_PDK13;
43 cl_fpp13::cl_fpp13(int aid, class cl_pdk *the_puc, struct cpu_entry *IType, class cl_sim *asim):
44 cl_fpp(aid, the_puc, IType, asim)
49 struct dis_entry *cl_fpp13::dis_tbl(void)
51 return disass_pdk_13;
55 int
56 cl_fpp13::execute(unsigned int code)
58 int write_result = resGO;
59 if (code == 0x0000) {
60 // nop
61 } else if (CODE_MASK(0x0100, 0xFF)) {
62 // ret k
63 cA.W(code & 0xFF);
64 cSP->W(rSP-2);
65 PC = get_mem(rSP) | (get_mem(rSP + 1) << 8);
66 } else if (code == 0x003A) {
67 // ret
68 cSP->W(rSP-2);
69 PC = get_mem(rSP) | (get_mem(rSP + 1) << 8);
70 } else if (CODE_MASK(0x1700, 0xFF)) {
71 // mov a, k
72 cA.W(code);
73 } else if (CODE_MASK(0x0080, 0x1F)) {
74 // mov io, a
75 sfr->write(code&0x1f, rA);
76 } else if (CODE_MASK(0x00A0, 0x1F)) {
77 // mov a, io
78 cA.W(get_io(code & 0x1F));
79 } else if (CODE_MASK(0x05C0, 0x3F)) {
80 // mov m, a
81 wr8(code & 0x3F, rA);
82 } else if (CODE_MASK(0x07C0, 0x3F)) {
83 // mov a, m
84 cA.W(get_mem(code & 0x3F));
85 } else if (CODE_MASK(0x00C1, 0x1E)) {
86 // ldt16
87 wr16(code & 0x001e, puc?(puc->t16->cnt):0);
88 } else if (CODE_MASK(0x00C0, 0x1E)) {
89 // stt16
90 if (puc)
91 puc->t16->cnt= rd16(code & 0x001e);
92 } else if ((CODE_MASK(0x0E1, 0x1E))) {
93 // idxm a, m
94 cA.W(get_mem(get_mem(code & 0x1E)));
95 } else if ((CODE_MASK(0x0E0, 0x1E))) {
96 // idxm m, a
97 wr8(get_mem(code & 0x1E), rA);
98 } else if (CODE_MASK(0x09C0, 0x3F)) {
99 // xch m
100 int mem = get_mem(code & 0x3F);
101 wr8(code & 0x3F, rA);
102 cA.W(mem);
103 } else if (code == 0x0032) {
104 // pushaf
105 ram->write(rSP, rA);
106 ram->write(rSP + 1, rF);
107 cSP->W(rSP + 2);
108 } else if (code == 0x0033) {
109 // popaf
110 cF->W(get_mem(rSP - 1));
111 cA.W(get_mem(rSP - 2));
112 cSP->W(rSP - 2);
113 } else if (CODE_MASK(0x1000, 0xFF)) {
114 // add a, k
115 cA.W(add_to(rA, code & 0xFF));
116 } else if (CODE_MASK(0x0600, 0x3F)) {
117 // add a, m
118 cA.W(add_to(rA, get_mem(code & 0x3F)));
119 } else if (CODE_MASK(0x0400, 0x3F)) {
120 // add m, a
121 int addr = code & 0x3F;
122 wr8(addr, add_to(rA, get_mem(addr)));
123 } else if (CODE_MASK(0x1100, 0xFF)) {
124 // sub a, k
125 cA.W(sub_to(rA, code & 0xFF));
126 } else if (CODE_MASK(0x0640, 0x3F)) {
127 // sub a, m
128 cA.W(sub_to(rA, get_mem(code & 0x3F)));
129 } else if (CODE_MASK(0x0440, 0x3F)) {
130 // sub m, a
131 int addr = code & 0x3F;
132 wr8(addr, sub_to(get_mem(addr), rA));
133 } else if (CODE_MASK(0x0680, 0x3F)) {
134 // addc a, m
135 cA.W(add_to(rA, get_mem(code & 0x3F), fC));
136 } else if (CODE_MASK(0x0480, 0x3F)) {
137 // addc m, a
138 int addr = code & 0x3F;
139 wr8(addr, add_to(rA, get_mem(addr), fC));
140 } else if (code == 0x0010) {
141 // addc a
142 cA.W(add_to(rA, fC));
143 } else if (CODE_MASK(0x0800, 0x3F)) {
144 // addc m
145 int addr = code & 0x3F;
146 wr8(addr, add_to(get_mem(addr), fC));
147 } else if (CODE_MASK(0x06C0, 0x3F)) {
148 // subc a, m
149 cA.W(sub_to(rA, get_mem(code & 0x3F), fC));
150 } else if (CODE_MASK(0x04C0, 0x3F)) {
151 // subc m, a
152 int addr = code & 0x3F;
153 wr8(addr, sub_to(get_mem(addr), rA, fC));
154 } else if (code == 0x0011) {
155 // subc a
156 cA.W(sub_to(rA, fC));
157 } else if (CODE_MASK(0x0840, 0x3F)) {
158 // subc m
159 int addr = code & 0x3F;
160 wr8(addr, sub_to(get_mem(addr), fC));
161 } else if (CODE_MASK(0x0900, 0x3F)) {
162 // inc m
163 int addr = code & 0x3F;
164 wr8(addr, add_to(get_mem(addr), 1));
165 } else if (CODE_MASK(0x0940, 0x3F)) {
166 // dec m
167 int addr = code & 0x3F;
168 wr8(addr, sub_to(get_mem(addr), 1));
169 } else if (CODE_MASK(0x0980, 0x3F)) {
170 // clear m
171 wr8(code & 0x3F, 0);
172 } else if (code == 0x001A) {
173 // sr a
174 SETC(rA & 1);
175 cA.W(rA >> 1);
176 } else if (CODE_MASK(0x0A80, 0x3F)) {
177 // sr m
178 int value = get_mem(code & 0x3F);
179 SETC(value & 1);
180 wr8(code & 0x3F, value >> 1);
181 } else if (code == 0x001B) {
182 // sl a
183 SETC(rA & 0x80);
184 cA.W(rA << 1);
185 } else if (CODE_MASK(0x0AC0, 0x3F)) {
186 // sl m
187 int value = get_mem(code & 0x3F);
188 SETC(value & 0x80);
189 wr8(code & 0x3F, value << 1);
190 } else if (code == 0x001C) {
191 // src a
192 int c = rA & 1;
193 rA >>= 1;
194 cA.W(rA | (fC << 7));
195 SETC(c);
196 } else if (CODE_MASK(0x0B00, 0x3F)) {
197 // src m
198 int value = get_mem(code & 0x3F);
199 int c = value & 1;
200 wr8(code & 0x3F, (value >> 1) | (fC << 7));
201 SETC(c);
202 } else if (code == 0x001D) {
203 // slc a
204 int c = (rA & 0x80) >> 7;
205 rA <<= 1;
206 cA.W(rA | fC);
207 SETC(c);
208 } else if (CODE_MASK(0x0B40, 0x3F)) {
209 // slc m
210 int value = get_mem(code & 0x3F);
211 int c = (value & 0x80) >> 7;
212 wr8(code & 0x3F, (value << 1) | fC);
213 SETC(c);
214 } else if (CODE_MASK(0x1400, 0xFF)) {
215 // and a, k
216 cA.W(rA & code);
217 SETZ(!rA);
218 } else if (CODE_MASK(0x0700, 0x3F)) {
219 // and a, m
220 cA.W(rA & get_mem(code & 0x3F));
221 SETZ(!rA);
222 } else if (CODE_MASK(0x0500, 0x3F)) {
223 // and m, a
224 int store = rA & get_mem(code & 0x3F);
225 SETZ(!store);
226 wr8(code & 0x3F, store);
227 } else if (CODE_MASK(0x1500, 0xFF)) {
228 // or a, k
229 cA.W(rA | code);
230 SETZ(!rA);
231 } else if (CODE_MASK(0x0740, 0x3F)) {
232 // or a, m
233 cA.W(rA | get_mem(code & 0x3F));
234 SETZ(!rA);
235 } else if (CODE_MASK(0x0540, 0x3F)) {
236 // or m, a
237 int store = rA | get_mem(code & 0x3F);
238 SETZ(!store);
239 wr8(code & 0x3F, store);
240 } else if (CODE_MASK(0x1600, 0xFF)) {
241 // xor a, k
242 cA.W(rA ^ code);
243 SETZ(!rA);
244 } else if (CODE_MASK(0x0780, 0x3F)) {
245 // xor a, m
246 cA.W(rA ^ get_mem(code & 0x3F));
247 SETZ(!rA);
248 } else if (CODE_MASK(0x0580, 0x3F)) {
249 // xor m, a
250 int store = rA ^ get_mem(code & 0x3F);
251 SETZ(!store);
252 wr8(code & 0x3F, store);
253 } else if (CODE_MASK(0x0060, 0x1F)) {
254 // xor io, a
255 sfr->write(code & 0x1F, rA ^ get_io(code & 0x1F));
256 } else if (code == 0x0018) {
257 // not a
258 cA.W(~rA);
259 SETZ(!rA);
260 } else if (CODE_MASK(0x0A00, 0x3F)) {
261 // not m
262 int store = (~get_mem(code & 0x3F) & 0xff);
263 SETZ(!store);
264 wr8(code & 0x3F, store);
265 } else if (code == 0x0019) {
266 // neg a
267 cA.W(-rA);
268 SETZ(!rA);
269 } else if (CODE_MASK(0x0A40, 0x3F)) {
270 // neg m
271 int store = (-get_mem(code & 0x3F) & 0xff);
272 SETZ(!store);
273 wr8(code & 0x3F, store);
274 } else if (CODE_MASK(0x0E00, 0xFF)) {
275 // set0 io, k
276 const u8_t bit = (code & 0xE0) >> 5;
277 const u8_t addr = code & 0x1F;
278 sfr->write(addr, get_io(addr) & ~(1 << bit));
279 } else if (CODE_MASK(0x0300, 0xEF)) {
280 // set0 m, k
281 const u8_t bit = (code & 0xE0) >> 5;
282 const u8_t addr = code & 0x0F;
283 wr8(addr, get_mem(addr) & ~(1 << bit));
284 } else if (CODE_MASK(0x0F00, 0xFF)) {
285 // set1 io, k
286 const u8_t bit = (code & 0xE0) >> 5;
287 const u8_t addr = code & 0x1F;
288 sfr->write(addr, get_io(addr) | (1 << bit));
289 } else if (CODE_MASK(0x0310, 0xEF)) {
290 // set1 m, k
291 const u8_t bit = (code & 0xE0) >> 5;
292 const u8_t addr = code & 0x0F;
293 wr8(addr, get_mem(addr) | (1 << bit));
294 } else if (CODE_MASK(0x0C00, 0xFF)) {
295 // t0sn io, k
296 int n = (code & 0xE0) >> 5;
297 if (!(get_io(code & 0x1F) & (1 << n)))
298 ++PC;
299 } else if (CODE_MASK(0x0200, 0xEF)) {
300 // t0sn m, k
301 int n = (code & 0xE0) >> 5;
302 if (!(get_mem(code & 0x0F) & (1 << n)))
303 ++PC;
304 } else if (CODE_MASK(0x0D00, 0xFF)) {
305 // t1sn io, k
306 int n = (code & 0xE0) >> 5;
307 if (get_io(code & 0x1F) & (1 << n))
308 ++PC;
309 } else if (CODE_MASK(0x0210, 0xEF)) {
310 // t1sn m, k
311 int n = (code & 0xE0) >> 5;
312 if (get_mem(code & 0x0F) & (1 << n))
313 ++PC;
314 } else if (CODE_MASK(0x1200, 0xFF)) {
315 // ceqsn a, k
316 sub_to(rA, code & 0xFF);
317 if (rA == (code & 0xFF))
318 ++PC;
319 } else if (CODE_MASK(0x0B80, 0x3F)) {
320 // ceqsn a, m
321 int addr = code & 0x3F;
322 sub_to(rA, get_mem(addr));
323 if (rA == get_mem(addr))
324 ++PC;
325 } else if (code == 0x0012) {
326 // izsn
327 rA = add_to(rA, 1);
328 if (!rA)
329 ++PC;
330 } else if (CODE_MASK(0x0880, 0x3F)) {
331 // izsn m
332 const int addr = code & 0x3F;
333 int result = add_to(get_mem(addr), 1);
334 wr8(addr, result);
335 if (!result)
336 ++PC;
337 } else if (code == 0x0013) {
338 // dzsn
339 cA.W(sub_to(rA, 1));
340 if (!rA)
341 ++PC;
342 } else if (CODE_MASK(0x08C0, 0x3F)) {
343 // dzsn m
344 const int addr = code & 0x3F;
345 int result = sub_to(get_mem(addr), 1);
346 wr8(addr, result);
347 if (!result)
348 ++PC;
349 } else if (CODE_MASK(0x1C00, 0x3FF)) {
350 // call k
351 push(PC);
352 PC = code & 0x3FF;
353 tick(1);
354 } else if (CODE_MASK(0x1800, 0x3FF)) {
355 // goto k
356 PC = code & 0x3FF;
357 tick(1);
358 } else if (code == 0x001E) {
359 // swap
360 int high = rA & 0xF;
361 cA.W((high << 4) | (rA >> 4));
362 } else if (code == 0x0017) {
363 // pcadd
364 PC += rA - 1;
365 } else if (code == 0x0038) {
366 // TODO: engint
367 } else if (code == 0x0039) {
368 // TODO: disint
370 else if (code == 0x0036) {
371 // stopsys
372 if (puc) puc->mode= pm_pd;
374 else if (code == 0x0037) {
375 // stopexe
376 if (puc) puc->mode= pm_ps;
378 else if (code == 0x0035) {
379 // reset
380 reset();
382 else if (code == 0x0030) {
383 // wdreset
384 if (puc) puc->wdt->clear();
386 else if (code == 0x0006) {
387 // ldsptl
388 cA.W(rom->read(rSP) & 0xFF);
389 } else if (code == 0x0007) {
390 // ldregs[0x02]th
391 //rA = (rom->get(rSP) & 0xFF00) >> 8;
392 cA.W(rom->read(rSP+1));
393 } else if (code == 0x003C) {
394 // mul
395 unsigned result = rA * get_io(0x08);
396 cA.W(result & 0xFF);
397 if (puc) puc->rMULRH= result >> 8;
398 } else {
399 return (resINV_INST);
401 return (resGO);
405 /* End of pdk.src/pdk13.cc */