Avr8bit-emulator
An emulator for the Atmel AVR 8-bit microcontroller
Loading...
Searching...
No Matches
data_transfer.c
Go to the documentation of this file.
1#include "data_transfer.h"
2
3void mov(uint8_t d, uint8_t r, struct CORE *core) {
4 // Copy register r to register d
5 // Rd <- Rr
6 // 1 cycle
7
8 // Execute instruction
9 core->gp.R[d] = core->gp.R[r];
10
11 // Update SREG
12 // NONE
13
14 inc_pc(core);
15}
16
17void movw(uint8_t d, uint8_t r, struct CORE *core) {
18 // Copy register pair r to register pair d
19 // Rd <- Rr
20 // Rd+1 <- Rr+1
21 // 1 cycle
22
23 // Execute instruction
24 core->gp.R[d] = core->gp.R[r];
25 core->gp.R[d + 1] = core->gp.R[r + 1];
26
27 // Update SREG
28 // NONE
29
30 inc_pc(core);
31}
32
33void ldi(uint8_t d, uint8_t K, struct CORE *core) {
34 // Load immediate 16 <= d <= 31
35 // Rd <- K
36 // 1 cycle
37
38 // Execute instruction
39 core->gp.R[d] = K;
40
41 // Update SREG
42 // NONE
43
44 inc_pc(core);
45}
46
47void lds(uint8_t d, int16_t k, struct CORE *core, union DATA_SPACE *data_space) {
48 // Load direct from data space
49 // Rd <- k
50 // 2 cycles
51
52 // Execute instruction
53 core->gp.R[d] = data_space->data[k];
54
55 // Update SREG
56 // NONE
57
58 inc_pc(core);
59}
60
61void ld_x(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
62 // Load indirect from data space using X as address
63 // Rd <- (X)
64 // 1 cycle
65
66 // Execute instruction
67 core->gp.R[d] = data_space->data[core->gp.X];
68
69 // Update SREG
70 // NONE
71
72 inc_pc(core);
73}
74
75void ld_x_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
76 // Load indirect from data space using X as address and post-increment X
77 // Rd <- (X)
78 // X <- X + 1
79 // 2 cycle
80
81 // Execute instruction
82 core->gp.R[d] = data_space->data[core->gp.X];
83 core->gp.X++;
84
85 // Update SREG
86 // NONE
87
88 inc_pc(core);
89}
90
91void ld_x_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
92 // Load indirect from data space using X as address and post-decrement X
93 // X <- X - 1
94 // Rd <- (X)
95 // 3 cycle
96
97 // Execute instruction
98 core->gp.X--;
99 core->gp.R[d] = data_space->data[core->gp.X];
100
101 // Update SREG
102 // NONE
103
104 inc_pc(core);
105}
106
107void ld_y(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
108 // Load indirect from data space using Y as address
109 // Rd <- (Y)
110 // 1 cycle
111
112 // Execute instruction
113 core->gp.R[d] = data_space->data[core->gp.Y];
114
115 // Update SREG
116 // NONE
117
118 inc_pc(core);
119}
120
121void ld_y_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
122 // Load indirect from data space using Y as address and post-increment Y
123 // Rd <- (Y)
124 // Y <- Y + 1
125 // 2 cycle
126
127 // Execute instruction
128 core->gp.R[d] = data_space->data[core->gp.Y];
129 core->gp.Y++;
130
131 // Update SREG
132 // NONE
133
134 inc_pc(core);
135}
136
137void ld_y_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
138 // Load indirect from data space using Y as address and post-decrement Y
139 // Y <- Y - 1
140 // Rd <- (Y)
141 // 3 cycle
142
143 // Execute instruction
144 core->gp.Y--;
145 core->gp.R[d] = data_space->data[core->gp.Y];
146
147 // Update SREG
148 // NONE
149
150 inc_pc(core);
151}
152
153void ldd_y(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space) {
154 // Load indirect with displacement from data space using Y as address
155 // Rd <- (Y + q)
156 // 2 cycle
157
158 // Execute instruction
159 core->gp.R[d] = data_space->data[core->gp.Y + q];
160
161 // Update SREG
162 // NONE
163
164 inc_pc(core);
165}
166
167void ld_z(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
168 // Load indirect from data space using Z as address
169 // Rd <- (Z)
170 // 1 cycle
171
172 // Execute instruction
173 core->gp.R[d] = data_space->data[core->gp.Z];
174
175 // Update SREG
176 // NONE
177
178 inc_pc(core);
179}
180
181void ld_z_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
182 // Load indirect from data space using Z as address and post-increment Z
183 // Rd <- (Z)
184 // Z <- Z + 1
185 // 2 cycle
186
187 // Execute instruction
188 core->gp.R[d] = data_space->data[core->gp.Z];
189 core->gp.Z++;
190
191 // Update SREG
192 // NONE
193
194 inc_pc(core);
195}
196
197void ld_z_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
198 // Load indirect from data space using Z as address and post-decrement Z
199 // Z <- Z - 1
200 // Rd <- (Z)
201 // 3 cycle
202
203 // Execute instruction
204 core->gp.Z--;
205 core->gp.R[d] = data_space->data[core->gp.Z];
206
207 // Update SREG
208 // NONE
209
210 inc_pc(core);
211}
212
213void ldd_z(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space) {
214 // Load indirect with displacement from data space using Z as address
215 // Rd <- (Z + q)
216 // 2 cycle
217
218 // Execute instruction
219 core->gp.R[d] = data_space->data[core->gp.Z + q];
220
221 // Update SREG
222 // NONE
223
224 inc_pc(core);
225}
226
227void sts(int16_t k, uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
228 // Store direct to data space
229 // k <- Rd
230 // 2 cycles
231
232 // Execute instruction
233 data_space->data[k] = core->gp.R[d];
234
235 // Update SREG
236 // NONE
237
238 inc_pc(core);
239}
240
241void st_x(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
242 // Store indirect to data space using X as address
243 // (X) <- Rd
244 // 1 cycle
245
246 // Execute instruction
247 data_space->data[core->gp.X] = core->gp.R[d];
248
249 // Update SREG
250 // NONE
251
252 inc_pc(core);
253}
254
255void st_x_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
256 // Store indirect to data space using X as address and post-increment X
257 // (X) <- Rd
258 // X <- X + 1
259 // 2 cycle
260
261 // Execute instruction
262 data_space->data[core->gp.X] = core->gp.R[d];
263 core->gp.X++;
264
265 // Update SREG
266 // NONE
267
268 inc_pc(core);
269}
270
271void st_x_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
272 // Store indirect to data space using X as address and post-decrement X
273 // X <- X - 1
274 // (X) <- Rd
275 // 3 cycle
276
277 // Execute instruction
278 core->gp.X--;
279 data_space->data[core->gp.X] = core->gp.R[d];
280
281 // Update SREG
282 // NONE
283
284 inc_pc(core);
285}
286
287void st_y(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
288 // Store indirect to data space using Y as address
289 // (Y) <- Rd
290 // 1 cycle
291
292 // Execute instruction
293 data_space->data[core->gp.Y] = core->gp.R[d];
294
295 // Update SREG
296 // NONE
297
298 inc_pc(core);
299}
300
301void st_y_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
302 // Store indirect to data space using Y as address and post-increment Y
303 // (Y) <- Rd
304 // Y <- Y + 1
305 // 2 cycle
306
307 // Execute instruction
308 data_space->data[core->gp.Y] = core->gp.R[d];
309 core->gp.Y++;
310
311 // Update SREG
312 // NONE
313
314 inc_pc(core);
315}
316
317void st_y_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
318 // Store indirect to data space using Y as address and post-decrement Y
319 // Y <- Y - 1
320 // (Y) <- Rd
321 // 3 cycle
322
323 // Execute instruction
324 core->gp.Y--;
325 data_space->data[core->gp.Y] = core->gp.R[d];
326
327 // Update SREG
328 // NONE
329
330 inc_pc(core);
331}
332
333void std_y(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space) {
334 // Store indirect with displacement to data space using Y as address
335 // (Y + q) <- Rd
336 // 2 cycle
337
338 // Execute instruction
339 data_space->data[core->gp.Y + q] = core->gp.R[d];
340
341 // Update SREG
342 // NONE
343
344 inc_pc(core);
345}
346
347void st_z(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
348 // Store indirect to data space using Z as address
349 // (Z) <- Rd
350 // 1 cycle
351
352 // Execute instruction
353 data_space->data[core->gp.Z] = core->gp.R[d];
354
355 // Update SREG
356 // NONE
357
358 inc_pc(core);
359}
360
361void st_z_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
362 // Store indirect to data space using Z as address and post-increment Z
363 // (Z) <- Rd
364 // Z <- Z + 1
365 // 2 cycle
366
367 // Execute instruction
368 data_space->data[core->gp.Z] = core->gp.R[d];
369 core->gp.Z++;
370
371 // Update SREG
372 // NONE
373
374 inc_pc(core);
375}
376
377void st_z_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
378 // Store indirect to data space using Z as address and post-decrement Z
379 // Z <- Z - 1
380 // (Z) <- Rd
381 // 3 cycle
382
383 // Execute instruction
384 core->gp.Z--;
385 data_space->data[core->gp.Z] = core->gp.R[d];
386
387 // Update SREG
388 // NONE
389
390 inc_pc(core);
391}
392
393void std_z(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space) {
394 // Store indirect with displacement to data space using Z as address
395 // (Z + q) <- Rd
396 // 2 cycle
397
398 // Execute instruction
399 data_space->data[core->gp.Z + q] = core->gp.R[d];
400
401 // Update SREG
402 // NONE
403
404 inc_pc(core);
405}
406
407void lpm_0(struct CORE *core, union PROGMEM_SPACE *progmem_space) {
408 // Load program memory to R0
409 // R0 <- Z
410 // 3 cycle
411
412 // Execute instruction
413 core->gp.R0 = progmem_space->data[core->gp.Z];
414
415 // Update SREG
416 // NONE
417
418 inc_pc(core);
419}
420
421void lpm_z(uint8_t d, struct CORE *core, union PROGMEM_SPACE *progmem_space) {
422 // Load program memory to register using Z as address
423 // Rd <- (Z)
424 // 3 cycle
425
426 // Execute instruction
427 core->gp.R[d] = progmem_space->data[core->gp.Z];
428
429 // Update SREG
430 // NONE
431
432 inc_pc(core);
433}
434
435void lpm_z_inc(uint8_t d, struct CORE *core, union PROGMEM_SPACE *progmem_space) {
436 // Load program memory to register using Z as address and post-increment Z
437 // Rd <- (Z)
438 // Z <- Z + 1
439 // 3 cycle
440
441 // Execute instruction
442 core->gp.R[d] = progmem_space->data[core->gp.Z];
443 core->gp.Z++;
444
445 // Update SREG
446 // NONE
447
448 inc_pc(core);
449}
450
451void in(uint8_t d, uint8_t A, struct CORE *core, union DATA_SPACE *data_space) {
452 // Read from I/O register
453 // Rd <- I/O[A]
454 // 1 cycle
455
456 // Execute instruction
457 core->gp.R[d] = data_space->io_reg[A];
458
459 // Update SREG
460 // NONE
461
462 inc_pc(core);
463}
464
465void out(uint8_t A, uint8_t r, struct CORE *core, union DATA_SPACE *data_space) {
466 // Write to I/O register
467 // I/O[A] <- Rr
468 // 1 cycle
469
470 // Execute instruction
471 data_space->io_reg[A] = core->gp.R[r];
472
473 // Update SREG
474 // NONE
475
476 inc_pc(core);
477}
478
479void push(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
480 // Push register to stack
481 // (SP) <- Rr
482 // SP <- SP - 1
483 // 2 cycle
484
485 // Execute instruction
486 data_space->sram[core->SP] = core->gp.R[d];
487 core->SP--;
488
489 // Update SREG
490 // NONE
491
492 inc_pc(core);
493}
494
495void pop(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
496 // Pop register from stack
497 // SP <- SP + 1
498 // Rd <- (SP)
499 // 2 cycle
500
501 // Execute instruction
502 core->SP++;
503 core->gp.R[d] = data_space->sram[core->SP];
504
505 // Update SREG
506 // NONE
507
508 inc_pc(core);
509}
510
511void xch(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
512 // Exchange register with stack
513 // Rd <-> (SP)
514 // 2 cycle
515
516 // Execute instruction
517 uint8_t temp = core->gp.R[d];
518 core->gp.R[d] = data_space->data[core->gp.Z];
519 data_space->data[core->gp.Z] = temp;
520
521 // Update SREG
522 // NONE
523
524 inc_pc(core);
525}
526
527void las(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
528 // Load and set register
529 // Only on SRAM
530 // In same time:
531 // (Z) <- Rd || (Z)
532 // Rd <- (Z)
533 // 2 cycle
534
535 // Execute instruction
536 uint8_t temp = data_space->data[core->gp.Z];
537 data_space->data[core->gp.Z] = core->gp.R[d] || temp;
538 core->gp.R[d] = temp;
539
540 // Update SREG
541 // NONE
542
543 inc_pc(core);
544}
545
546void lac(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
547 // Load and clear register
548 // Only on SRAM
549 // In same time:
550 // (Z) <- (0xFF - Rd) & (Z)
551 // Rd <- (Z)
552 // 2 cycle
553
554 // Execute instruction
555 uint8_t temp = data_space->data[core->gp.Z];
556 data_space->data[core->gp.Z] = (0xFF - core->gp.R[d]) & temp;
557 core->gp.R[d] = temp;
558
559 // Update SREG
560 // NONE
561
562 inc_pc(core);
563}
564
565void lat(uint8_t d, struct CORE *core, union DATA_SPACE *data_space) {
566 // Load and toggle register
567 // Only on SRAM
568 // In same time:
569 // (Z) <- Rd ^ (Z)
570 // Rd <- (Z)
571 // 2 cycle
572
573 // Execute instruction
574 uint8_t temp = data_space->data[core->gp.Z];
575 data_space->data[core->gp.Z] = core->gp.R[d] ^ temp;
576 core->gp.R[d] = temp;
577
578 // Update SREG
579 // NONE
580
581 inc_pc(core);
582}
void inc_pc(struct CORE *core)
Definition core.c:3
void ld_y_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using Y register and pre-decrement.
void sts(int16_t k, uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store direct from register to data space.
void st_z_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Z pointer and pre-decrement Z.
void ldd_y(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space to register using Y pointer with displacement.
void std_z(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Z pointer with displacement.
void lac(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load and clear data space.
void st_x_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store indirect from register to data space using X pointer and post-increment.
void lpm_z(uint8_t d, struct CORE *core, union PROGMEM_SPACE *progmem_space)
Load program memory into register using Z pointer.
void ldd_z(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space to register using Z pointer with displacement.
void las(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load and set data space.
void ld_y_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using Y register and post-increment.
void push(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Push register onto stack.
void ld_y(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using Y register.
void xch(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Exchange register with data space.
void ld_x(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using X register.
void st_y_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Y pointer and pre-decrement Y.
void lpm_0(struct CORE *core, union PROGMEM_SPACE *progmem_space)
Load program memory into register using Z pointer.
void ld_x_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using X register and post-increment.
void st_z_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Z pointer and post-increment Z.
void std_y(uint8_t d, uint8_t q, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Y pointer with displacement.
void movw(uint8_t d, uint8_t r, struct CORE *core)
Move word from register pair r to register pair d.
void lat(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load and toggle data space.
void pop(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Pop register from stack.
void ldi(uint8_t d, uint8_t K, struct CORE *core)
Load immediate value K into register d.
void ld_z_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space to register using Z pointer and post-increment.
void st_x_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store indirect from register to data space using X pointer and pre-decrement.
void st_x(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store indirect from register to data space using X pointer.
void mov(uint8_t d, uint8_t r, struct CORE *core)
Move data from register r to register d.
void in(uint8_t d, uint8_t A, struct CORE *core, union DATA_SPACE *data_space)
Read from I/O space into register.
void ld_z_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space to register using Z pointer and pre-decrement.
void st_z(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Z pointer.
void st_y(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store indirect from register to data space using Y pointer.
void st_y_inc(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Store register to data space using Y pointer and post-increment Y.
void out(uint8_t A, uint8_t r, struct CORE *core, union DATA_SPACE *data_space)
Write from register to I/O space.
void lpm_z_inc(uint8_t d, struct CORE *core, union PROGMEM_SPACE *progmem_space)
Load program memory and post-increment Z register.
void lds(uint8_t d, int16_t k, struct CORE *core, union DATA_SPACE *data_space)
Load direct from data space using 16-bit address.
void ld_z(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space to register using Z pointer.
void ld_x_dec(uint8_t d, struct CORE *core, union DATA_SPACE *data_space)
Load indirect from data space using X register and pre-decrement.
Data transfer instructions.
Core structure containing general purpose registers, program counter, stack pointer,...
Definition core.h:67
union GP gp
Definition core.h:68
uint16_t SP
Definition core.h:70
Represents the data space in the AVR emulator.
Definition data_space.h:13
uint8_t io_reg[64]
Definition data_space.h:17
uint8_t data[DATA_SPACE_SIZE]
Definition data_space.h:14
uint8_t sram[2048]
Definition data_space.h:19
uint16_t Y
Definition core.h:58
uint8_t R0
Definition core.h:31
uint8_t R[32]
Definition core.h:29
uint16_t Z
Definition core.h:59
uint16_t X
Definition core.h:57
Represents the program memory space in the AVR emulator.
Definition data_space.h:27
uint8_t data[PROGMEM_SPACE_SIZE]
Definition data_space.h:28