1 /*
2  * Copyright (c) 2015, Marcos Medeiros
3  * Licensed under BSD 3-clause.
4  */
5 #ifndef TMS34010_MOV_H
6 #define TMS34010_MOV_H
7 
8 #include "tms34010.h"
9 #include "tms34010_memacc.h"
10 #include "tms34010_defs.h"
11 
12 namespace tms { namespace ops {
13 
14 // MOVB RS, *RD
movb_rs_ird(cpu_state * cpu,word opcode)15 void movb_rs_ird(cpu_state *cpu, word opcode)
16 {
17     wrfield_8(_rd, (dword)(byte)_rs);
18 
19     CONSUME_CYCLES(1);
20 }
21 
22 // MOVB *RS, RD
movb_irs_rd(cpu_state * cpu,word opcode)23 void movb_irs_rd(cpu_state *cpu, word opcode)
24 {
25     _rd = rdfield_8_sx(_rs);
26     _st &= ~ST_V;
27     update_zn(_rd);
28 
29     CONSUME_CYCLES(3);
30 }
31 
32 // MOVB *RS, *RD
movb_irs_ird(cpu_state * cpu,word opcode)33 void movb_irs_ird(cpu_state *cpu, word opcode)
34 {
35     wrfield_8(_rd, (dword)(byte)rdfield_8(_rs));
36 
37     CONSUME_CYCLES(3);
38 }
39 
40 // MOVB RS, *RD(OFFS)
movb_rs_irdo(cpu_state * cpu,word opcode)41 void movb_rs_irdo(cpu_state *cpu, word opcode)
42 {
43     wrfield_8(_rd + wsign_ext(mem_read(_pc)), (dword)(byte)_rs);
44     _pc += 16;
45 
46     CONSUME_CYCLES(3);
47 }
48 
49 // MOVB *RS(OFFS), RD
movb_irso_rd(cpu_state * cpu,word opcode)50 void movb_irso_rd(cpu_state *cpu, word opcode)
51 {
52     _rd = rdfield_8_sx(_rs + wsign_ext(mem_read(_pc)));
53     _pc += 16;
54     _st &= ~ST_V;
55     update_zn(_rd);
56 
57     CONSUME_CYCLES(5);
58 }
59 
60 // MOVB *RS(OFFS), *RD(OFFS)
movb_irso_irdo(cpu_state * cpu,word opcode)61 void movb_irso_irdo(cpu_state *cpu, word opcode)
62 {
63     dword data = rdfield_8(_rs + wsign_ext(mem_read(_pc)));
64     wrfield_8(_rd + wsign_ext(mem_read(_pc + 16)), data);
65     _pc += 32;
66 
67     CONSUME_CYCLES(5);
68 }
69 
70 // MOVB RS, @DADDR
movb_rs_daddr(cpu_state * cpu,word opcode)71 void movb_rs_daddr(cpu_state *cpu, word opcode)
72 {
73     dword daddr = mem_read_d(_pc);
74     _pc += 32;
75     wrfield_8(daddr, (dword)(byte)_rd);
76 
77     CONSUME_CYCLES(1);
78 }
79 
80 // MOVB @SADDR, RD
movb_addr_rd(cpu_state * cpu,word opcode)81 void movb_addr_rd(cpu_state *cpu, word opcode)
82 {
83     _rd = rdfield_8_sx(mem_read_d(_pc));
84     _pc += 32;
85     _st &= ~ST_V;
86     update_zn(_rd);
87 
88     CONSUME_CYCLES(5);
89 }
90 
91 // MOVB @SADDR, @DADDR
movb_saddr_daddr(cpu_state * cpu,word opcode)92 void movb_saddr_daddr(cpu_state *cpu, word opcode)
93 {
94     dword src = mem_read_d(_pc);
95     _pc += 32;
96     dword dst = mem_read_d(_pc);
97     _pc += 32;
98     wrfield_8(dst, (dword)(byte)rdfield_8(src));
99 
100     CONSUME_CYCLES(7);
101 }
102 
103 // MOVE RS, RD
move_rs_rd(cpu_state * cpu,word opcode)104 void move_rs_rd(cpu_state *cpu, word opcode)
105 {
106     _rd = _rs;
107     _st &= ~ST_V;
108     update_zn(_rd);
109 
110     CONSUME_CYCLES(1);
111 }
112 
113 // MOVE RS, RD  [A->B]
move_rs_rd_a(cpu_state * cpu,word opcode)114 void move_rs_rd_a(cpu_state *cpu, word opcode)
115 {
116     cpu->b[RD_n].value = cpu->a[RS_n].value;
117     _st &= ~ST_V;
118     update_zn(cpu->b[RD_n].value);
119 
120     CONSUME_CYCLES(1);
121 }
122 
123 // MOVE RS, RD [B->A]
move_rs_rd_b(cpu_state * cpu,word opcode)124 void move_rs_rd_b(cpu_state *cpu, word opcode)
125 {
126     cpu->a[RD_n].value = cpu->b[RS_n].value;
127     _st &= ~ST_V;
128     update_zn(cpu->a[RD_n].value);
129 
130     CONSUME_CYCLES(1);
131 }
132 
133 // MOVE RS, *RD, 0
move_rs_ird_0(cpu_state * cpu,word opcode)134 void move_rs_ird_0(cpu_state *cpu, word opcode)
135 {
136     wrfield0(_rd, _rs);
137 
138     CONSUME_CYCLES(1);
139 }
140 
141 // MOVE RS, *RD, 1
move_rs_ird_1(cpu_state * cpu,word opcode)142 void move_rs_ird_1(cpu_state *cpu, word opcode)
143 {
144     wrfield1(_rd, _rs);
145 
146     CONSUME_CYCLES(1);
147 }
148 
149 // MOVE RS, -*RD, 0
move_rs_mird_0(cpu_state * cpu,word opcode)150 void move_rs_mird_0(cpu_state *cpu, word opcode)
151 {
152     _rd -= FW0;
153     wrfield0(_rd, _rs);
154 
155     CONSUME_CYCLES(2);
156 }
157 
158 // MOVE RS, -*RD, 1
move_rs_mird_1(cpu_state * cpu,word opcode)159 void move_rs_mird_1(cpu_state *cpu, word opcode)
160 {
161     _rd -= FW1;
162     wrfield1(_rd, _rs);
163 
164     CONSUME_CYCLES(2);
165 }
166 
167 // MOVE RS, *RD+, 0
move_rs_irdp_0(cpu_state * cpu,word opcode)168 void move_rs_irdp_0(cpu_state *cpu, word opcode)
169 {
170     wrfield0(_rd, _rs);
171     _rd += FW0;
172 
173     CONSUME_CYCLES(1);
174 }
175 
176 // MOVE RS, *RD+, 1
move_rs_irdp_1(cpu_state * cpu,word opcode)177 void move_rs_irdp_1(cpu_state *cpu, word opcode)
178 {
179     wrfield1(_rd, _rs);
180     _rd += FW1;
181 
182     CONSUME_CYCLES(1);
183 }
184 
185 // MOVE *RS, RD, 0
move_irs_rd_0(cpu_state * cpu,word opcode)186 void move_irs_rd_0(cpu_state *cpu, word opcode)
187 {
188     _rd = rdfield0(_rs);
189     _st &= ~ST_V;
190     update_zn(_rd);
191 
192     CONSUME_CYCLES(3);
193 }
194 
195 // MOVE *RS, RD, 1
move_irs_rd_1(cpu_state * cpu,word opcode)196 void move_irs_rd_1(cpu_state *cpu, word opcode)
197 {
198     _rd = rdfield1(_rs);
199     _st &= ~ST_V;
200     update_zn(_rd);
201 
202     CONSUME_CYCLES(3);
203 }
204 
205 
206 // MOVE -*RS, RD, 0
move_mirs_rd_0(cpu_state * cpu,word opcode)207 void move_mirs_rd_0(cpu_state *cpu, word opcode)
208 {
209     _rs -= FW0;
210     _rd = rdfield0(_rs);
211     _st &= ~ST_V;
212     update_zn(_rd);
213 
214     CONSUME_CYCLES(4);
215 }
216 
217 // MOVE -*RS, RD, 1
move_mirs_rd_1(cpu_state * cpu,word opcode)218 void move_mirs_rd_1(cpu_state *cpu, word opcode)
219 {
220     _rs -= FW1;
221     _rd = rdfield1(_rs);
222     _st &= ~ST_V;
223     update_zn(_rd);
224 
225     CONSUME_CYCLES(4);
226 }
227 
228 // MOVE *RS+, RD, 0
move_irsp_rd_0(cpu_state * cpu,word opcode)229 void move_irsp_rd_0(cpu_state *cpu, word opcode)
230 {
231     dword data = rdfield0(_rs);
232     _rs += FW0;
233     _rd = data;
234     _st &= ~ST_V;
235     update_zn(_rd);
236 
237     CONSUME_CYCLES(3);
238 }
239 
240 
241 // MOVE *RS+, RD, 1
move_irsp_rd_1(cpu_state * cpu,word opcode)242 void move_irsp_rd_1(cpu_state *cpu, word opcode)
243 {
244     dword data = rdfield1(_rs);
245     _rs += FW1;
246     _rd = data;
247     _st &= ~ST_V;
248     update_zn(_rd);
249 
250     CONSUME_CYCLES(3);
251 }
252 
253 // MOVE *RS, *RD, 0
move_irs_ird_0(cpu_state * cpu,word opcode)254 void move_irs_ird_0(cpu_state *cpu, word opcode)
255 {
256     wrfield0(_rd, rdfield0(_rs));
257 
258     CONSUME_CYCLES(3);
259 }
260 
261 // MOVE *RS, *RD, 1
move_irs_ird_1(cpu_state * cpu,word opcode)262 void move_irs_ird_1(cpu_state *cpu, word opcode)
263 {
264     wrfield1(_rd, rdfield1(_rs));
265 
266     CONSUME_CYCLES(3);
267 }
268 
269 // MOVE -*RS, -*RD, 0
move_mirs_mird_0(cpu_state * cpu,word opcode)270 void move_mirs_mird_0(cpu_state *cpu, word opcode)
271 {
272     _rs -= FW0;
273     sdword data = rdfield0(_rs);
274     _rd -= FW0;
275     wrfield0(_rd, data);
276 
277     CONSUME_CYCLES(4);
278 }
279 
280 
281 // MOVE -*RS, -*RD, 1
move_mirs_mird_1(cpu_state * cpu,word opcode)282 void move_mirs_mird_1(cpu_state *cpu, word opcode)
283 {
284     _rs -= FW1;
285     sdword data = rdfield1(_rs);
286     _rd -= FW1;
287     wrfield1(_rd, data);
288 
289     CONSUME_CYCLES(4);
290 }
291 
292 // MOVE *RS+, *RD+, 0
move_irsp_irdp_0(cpu_state * cpu,word opcode)293 void move_irsp_irdp_0(cpu_state *cpu, word opcode)
294 {
295     dword value = rdfield0(_rs);
296     _rs += FW0;
297     wrfield0(_rd, value);
298     _rd += FW0;
299 
300     CONSUME_CYCLES(4);
301 }
302 
303 // MOVE *RS+, *RD+, 1
move_irsp_irdp_1(cpu_state * cpu,word opcode)304 void move_irsp_irdp_1(cpu_state *cpu, word opcode)
305 {
306     dword value = rdfield1(_rs);
307     _rs += FW1;
308     wrfield1(_rd, value);
309     _rd += FW1;
310 
311     CONSUME_CYCLES(4);
312 }
313 
314 // MOVE RS, *RD(OFFS), 0
move_rs_irdo_0(cpu_state * cpu,word opcode)315 void move_rs_irdo_0(cpu_state *cpu, word opcode)
316 {
317     wrfield0(_rd + wsign_ext(mem_read(_pc)), _rs);
318     _pc += 16;
319 
320     CONSUME_CYCLES(3);
321 }
322 
323 // MOVE RS, *RD(OFFS), 1
move_rs_irdo_1(cpu_state * cpu,word opcode)324 void move_rs_irdo_1(cpu_state *cpu, word opcode)
325 {
326     wrfield1(_rd + wsign_ext(mem_read(_pc)), _rs);
327     _pc += 16;
328 
329     CONSUME_CYCLES(3);
330 }
331 
332 // MOVE *RS(OFFS), RD, 0
move_irso_rd_0(cpu_state * cpu,word opcode)333 void move_irso_rd_0(cpu_state *cpu, word opcode)
334 {
335     _rd = rdfield0(_rs + wsign_ext(mem_read(_pc)));
336     _pc += 16;
337     _st &= ~ST_V;
338     update_zn(_rd);
339 
340     CONSUME_CYCLES(5);
341 }
342 
343 // MOVE *RS(OFFS), RD, 1
move_irso_rd_1(cpu_state * cpu,word opcode)344 void move_irso_rd_1(cpu_state *cpu, word opcode)
345 {
346     _rd = rdfield1(_rs + wsign_ext(mem_read(_pc)));
347     _pc += 16;
348     _st &= ~ST_V;
349     update_zn(_rd);
350 
351     CONSUME_CYCLES(5);
352 }
353 
354 // MOVE *RS(OFFS), *RD+, 0
move_irso_irdp_0(cpu_state * cpu,word opcode)355 void move_irso_irdp_0(cpu_state *cpu, word opcode)
356 {
357     dword data = rdfield0(_rs + wsign_ext(mem_read(_pc)));
358     _pc += 16;
359     wrfield0(_rd, data);
360     _rd += FW0;
361 
362     CONSUME_CYCLES(5);
363 }
364 
365 // MOVE *RS(OFFS), *RD+, 1
move_irso_irdp_1(cpu_state * cpu,word opcode)366 void move_irso_irdp_1(cpu_state *cpu, word opcode)
367 {
368     dword data = rdfield1(_rs + wsign_ext(mem_read(_pc)));
369     _pc += 16;
370     wrfield1(_rd, data);
371     _rd += FW1;
372 
373     CONSUME_CYCLES(5);
374 }
375 
376 // MOVE *RS(OFFS), *RD(OFFS), 0
move_irso_irdo_0(cpu_state * cpu,word opcode)377 void move_irso_irdo_0(cpu_state *cpu, word opcode)
378 {
379     dword data = rdfield0(_rs + wsign_ext(mem_read(_pc)));
380     wrfield0(_rd + wsign_ext(mem_read(_pc + 16)), data);
381     _pc += 32;
382 
383     CONSUME_CYCLES(5);
384 }
385 
386 // MOVE *RS(OFFS), *RD(OFFS), 1
move_irso_irdo_1(cpu_state * cpu,word opcode)387 void move_irso_irdo_1(cpu_state *cpu, word opcode)
388 {
389     dword data = rdfield1(_rs + wsign_ext(mem_read(_pc)));
390     wrfield1(_rd + wsign_ext(mem_read(_pc + 16)), data);
391     _pc += 32;
392 
393     CONSUME_CYCLES(5);
394 }
395 
396 // MOVE RS, @DADDR, 0
move_rs_daddr_0(cpu_state * cpu,word opcode)397 void move_rs_daddr_0(cpu_state *cpu, word opcode)
398 {
399     dword addr = mem_read_d(_pc);
400     _pc += 32;
401     wrfield0(addr, _rd);
402 
403     CONSUME_CYCLES(3);
404 }
405 
406 // MOVE RS, @DADDR, 1
move_rs_daddr_1(cpu_state * cpu,word opcode)407 void move_rs_daddr_1(cpu_state *cpu, word opcode)
408 {
409     dword addr = mem_read_d(_pc);
410     _pc += 32;
411     wrfield1(addr, _rd);
412 
413     CONSUME_CYCLES(3);
414 }
415 
416 // MOVE @SADDR, RD, 0
move_saddr_rd_0(cpu_state * cpu,word opcode)417 void move_saddr_rd_0(cpu_state *cpu, word opcode)
418 {
419     dword addr = mem_read_d(_pc);
420     _pc += 32;
421     _rd = rdfield0(addr);
422     _st &= ~ST_V;
423     update_zn(_rd);
424 
425     CONSUME_CYCLES(5);
426 }
427 
428 // MOVE @SADDR, RD, 0
move_saddr_rd_1(cpu_state * cpu,word opcode)429 void move_saddr_rd_1(cpu_state *cpu, word opcode)
430 {
431     dword addr = mem_read_d(_pc);
432     _pc += 32;
433     _rd = rdfield1(addr);
434     _st &= ~ST_V;
435     update_zn(_rd);
436 
437     CONSUME_CYCLES(5);
438 }
439 
440 // MOVE @SADDR, *RS+, 0
move_addr_irsp_0(cpu_state * cpu,word opcode)441 void move_addr_irsp_0(cpu_state *cpu, word opcode)
442 {
443     dword addr = mem_read_d(_pc);
444     _pc += 32;
445     wrfield0(addr, _rd);
446     _rd += FW0;
447 
448     CONSUME_CYCLES(5);
449 }
450 
451 // MOVE @SADDR, *RS+, 0
move_addr_irsp_1(cpu_state * cpu,word opcode)452 void move_addr_irsp_1(cpu_state *cpu, word opcode)
453 {
454     dword addr = mem_read_d(_pc);
455     _pc += 32;
456     wrfield1(addr, _rd);
457     _rd += FW1;
458 
459     CONSUME_CYCLES(5);
460 }
461 
462 // MOVE @SADDR, @DADDR, 0
move_saddr_daddr_0(cpu_state * cpu,word opcode)463 void move_saddr_daddr_0(cpu_state *cpu, word opcode)
464 {
465     dword src = mem_read_d(_pc);
466     _pc += 32;
467     dword dst = mem_read_d(_pc);
468     _pc += 32;
469     wrfield0(dst, rdfield0(src));
470 
471     CONSUME_CYCLES(7);
472 }
473 
474 // MOVE @SADDR, @DADDR, 0
move_saddr_daddr_1(cpu_state * cpu,word opcode)475 void move_saddr_daddr_1(cpu_state *cpu, word opcode)
476 {
477     dword src = mem_read_d(_pc);
478     _pc += 32;
479     dword dst = mem_read_d(_pc);
480     _pc += 32;
481     wrfield1(dst, rdfield1(src));
482 
483     CONSUME_CYCLES(7);
484 }
485 
486 // MOVEI IW, RD
movi_iw_rd(cpu_state * cpu,word opcode)487 void movi_iw_rd(cpu_state *cpu, word opcode)
488 {
489     _rd = wsign_ext(mem_read(_pc));
490     _pc += 16;
491     _st &= ~ST_V;
492     update_zn(_rd);
493 
494     CONSUME_CYCLES(2);
495 }
496 
497 
498 // MOVEI IL, RD
movi_il_rd(cpu_state * cpu,word opcode)499 void movi_il_rd(cpu_state *cpu, word opcode)
500 {
501     _rd = mem_read_d(_pc);
502     _pc += 32;
503     _st &= ~ST_V;
504     update_zn(_rd);
505 
506     CONSUME_CYCLES(3);
507 }
508 
509 // MOVX RS, RD
movx_rs_rd(cpu_state * cpu,word opcode)510 void movx_rs_rd(cpu_state *cpu, word opcode)
511 {
512     _rdx = _rsx;
513     CONSUME_CYCLES(1);
514 }
515 
516 // MOVY RS, RD
movy_rs_rd(cpu_state * cpu,word opcode)517 void movy_rs_rd(cpu_state *cpu, word opcode)
518 {
519     _rdy = _rsy;
520     CONSUME_CYCLES(1);
521 }
522 
523 // MOVK K, RD
movk_k_rd(cpu_state * cpu,word opcode)524 void movk_k_rd(cpu_state *cpu, word opcode)
525 {
526     _rd = fw_lut[K];
527     CONSUME_CYCLES(1);
528 }
529 
530 
531 } // ops
532 } // tms
533 
534 #endif // TMS34010_MOV_H
535