Avr8bit-emulator
An emulator for the Atmel AVR 8-bit microcontroller
Loading...
Searching...
No Matches
branch.c
Go to the documentation of this file.
1#include "branch.h"
2
3void rjmp(uint8_t k, struct CORE *core) {
4 // Relative jump
5 // PC <- PC + k + 1
6 // 2 cycles
7
8 // Execute instruction
9 core->PC = core->PC + k + 1;
10
11 // Update SREG
12 // NONE
13}
14
15void ijmp(struct CORE *core) {
16 // Indirect jump to address contained in Z
17 // PC <- Z
18 // 2 cycles
19
20 // Execute instruction
21 core->PC = core->gp.R[30] << 8 | core->gp.R[31];
22
23 // Update SREG
24 // NONE
25}
26
27void jmp(uint32_t k, struct CORE *core) {
28 // Absolute jump
29 // PC <- k
30 // 3 cycles
31
32 // Execute instruction
33 core->PC = k;
34
35 // Update SREG
36 // NONE
37}
38
39void rcall(uint8_t k, struct CORE *core, struct SRAM *sram) {
40 // Relative call
41 // PC <- PC + k + 1
42 // Push return address to stack
43 // 3 cycles
44
45 // Execute instruction
46 sram->mem[core->SP] = core->PC + 1;
47 core->SP = core->SP - 2;
48 core->PC = core->PC + k + 1;
49
50 // Update SREG
51 // NONE
52}
53
54void icall(struct CORE *core, struct SRAM *sram) {
55 // Indirect call to address contained in Z
56 // PC <- Z
57 // Push return address to stack
58 // 3 cycles
59
60 // Execute instruction
61 sram->mem[core->SP] = core->PC + 1;
62 core->SP = core->SP - 2;
63 core->PC = core->gp.Z;
64
65 // Update SREG
66 // NONE
67}
68
69// void eicall(struct CORE *core, struct SRAM *sram) {
70
71// }
72
73void ret(struct CORE *core, struct SRAM *sram) {
74 // Return from subroutine
75 // Pop return address from stack
76 // PC <- (SP + 1)
77 // 4 cycles
78
79 // Execute instruction
80 core->SP = core->SP + 1;
81 core->PC = sram->mem[core->SP] << 8 | sram->mem[core->SP + 1];
82
83 // Update SREG
84 // NONE
85}
86
87void reti(struct CORE *core, struct SRAM *sram) {
88 // Return from interrupt
89 // Pop return address from stack
90 // PC <- (SP + 1)
91 // Enable global interrupts
92 // 4 cycles
93
94 // Execute instruction
95 core->SP = core->SP + 1;
96 core->PC = sram->mem[core->SP] << 8 | sram->mem[core->SP + 1];
97
98 // Update SREG
99 update_sreg_I(&core->sreg, true);
100}
101
102void cpse(uint8_t d, uint8_t r, struct CORE *core) {
103 // Compare, skip if equal
104 // If Rd = Rr, PC <- PC + 2
105 // 1 cycle
106
107 // Execute instruction
108 if (core->gp.R[d] == core->gp.R[r]) {
109 core->PC = core->PC + 2;
110 // LACKS IMPLEMENTATION + 3 if instruction skipped is 2word long
111 }
112 else {
113 core->PC = core->PC + 1;
114 }
115
116 // Update SREG
117 // NONE
118}
119
120void cp(uint8_t d, uint8_t r, struct CORE *core) {
121 // Compare
122 // Rd - Rr
123 // 1 cycle
124
125 // Execute instruction
126 uint8_t result = core->gp.R[d] - core->gp.R[r];
127
128 // Update SREG
129 update_sreg_arithm(core, core->gp.R[d], core->gp.R[r], result);
130}
131
132void cpc(uint8_t d, uint8_t r, struct CORE *core) {
133 // Compare with carry
134 // Rd - Rr - C
135 // 1 cycle
136
137 // Execute instruction
138 uint8_t result = core->gp.R[d] - core->gp.R[r] - core->sreg.C;
139
140 // Update SREG
141 update_sreg_arithm(core, core->gp.R[d], core->gp.R[r], result);
142}
143
144void cpi(uint8_t d, uint8_t K, struct CORE *core) {
145 // Compare with immediate
146 // Rd - K
147 // 1 cycle
148
149 // Execute instruction
150 uint8_t result = core->gp.R[d] - K;
151
152 // Update SREG
153 update_sreg_arithm(core, core->gp.R[d], K, result);
154}
155
156void sbrc(uint8_t r, uint8_t b, struct CORE *core) {
157 // Skip if bit in register cleared
158 // If Rr(b) = 0, PC <- PC + 2
159 // 1 cycle
160
161 // Execute instruction
162 if ((core->gp.R[r] & (1 << b)) == 0) {
163 core->PC = core->PC + 2;
164 // LACKS IMPLEMENTATION + 3 if instruction skipped is 2word long
165 }
166 else {
167 core->PC = core->PC + 1;
168 }
169
170 // Update SREG
171 // NONE
172}
173
174void sbrs(uint8_t r, uint8_t b, struct CORE *core) {
175 // Skip if bit in register set
176 // If Rr(b) = 1, PC <- PC + 2
177 // 1 cycle
178
179 // Execute instruction
180 if ((core->gp.R[r] & (1 << b)) == 1) {
181 core->PC = core->PC + 2;
182 // LACKS IMPLEMENTATION + 3 if instruction skipped is 2word long
183 }
184 else {
185 core->PC = core->PC + 1;
186 }
187
188 // Update SREG
189 // NONE
190}
191
192void sbic(uint8_t A, uint8_t b, struct CORE *core, union DATA_SPACE *data_space) {
193 // Skip if bit in I/O register cleared
194 // Only for 0 <= A <= 31
195 // If I/O(A)(b) = 0, PC <- PC + 2
196 // 1 cycle
197
198 // Execute instruction
199 if ((data_space->io_reg[A] & (1 << b)) == 0) {
200 core->PC = core->PC + 2;
201 // LACKS IMPLEMENTATION + 3 if instruction skipped is 2word long
202 }
203 else {
204 core->PC = core->PC + 1;
205 }
206
207 // Update SREG
208 // NONE
209}
210
211void sbis(uint8_t A, uint8_t b, struct CORE *core, union DATA_SPACE *data_space) {
212 // Skip if bit in I/O register set
213 // Only for 0 <= A <= 31
214 // If I/O(A)(b) = 1, PC <- PC + 2
215 // 1 cycle
216
217 // Execute instruction
218 if ((data_space->io_reg[A] & (1 << b)) == 1) {
219 core->PC = core->PC + 2;
220 // LACKS IMPLEMENTATION + 3 if instruction skipped is 2word long
221 }
222 else {
223 core->PC = core->PC + 1;
224 }
225
226 // Update SREG
227 // NONE
228}
229
230void brbs(uint8_t s, uint8_t k, struct CORE *core) {
231 // Branch if bit in SREG set
232 // If S(s) = 1, PC <- PC + k + 1
233 // 1 cycle
234
235 // Execute instruction
236 if ((core->sreg.sreg & (1 << s)) == 1) {
237 core->PC = core->PC + k + 1;
238 }
239 else {
240 core->PC = core->PC + 1;
241 }
242
243 // Update SREG
244 // NONE
245}
246
247void brbc(uint8_t s, uint8_t k, struct CORE *core) {
248 // Branch if bit in SREG cleared
249 // If S(s) = 0, PC <- PC + k + 1
250 // 1 cycle
251
252 // Execute instruction
253 if ((core->sreg.sreg & (1 << s)) == 0) {
254 core->PC = core->PC + k + 1;
255 }
256 else {
257 core->PC = core->PC + 1;
258 }
259
260 // Update SREG
261 // NONE
262}
263
264void breq(uint8_t k, struct CORE *core) {
265 // Branch if equal
266 // If Z = 1, PC <- PC + k + 1
267 // 1 cycle
268
269 // Execute instruction
270 if (core->sreg.Z == 1) {
271 core->PC = core->PC + k + 1;
272 }
273 else {
274 core->PC = core->PC + 1;
275 }
276
277 // Update SREG
278 // NONE
279}
280
281void brne(uint8_t k, struct CORE *core) {
282 // Branch if not equal
283 // If Z = 0, PC <- PC + k + 1
284 // 1 cycle
285
286 // Execute instruction
287 if (core->sreg.Z == 0) {
288 core->PC = core->PC + k + 1;
289 }
290 else {
291 core->PC = core->PC + 1;
292 }
293
294 // Update SREG
295 // NONE
296}
297
298void brcs(uint8_t k, struct CORE *core) {
299 // Branch if carry set
300 // If C = 1, PC <- PC + k + 1
301 // 1 cycle
302
303 // Execute instruction
304 if (core->sreg.C == 1) {
305 core->PC = core->PC + k + 1;
306 }
307 else {
308 core->PC = core->PC + 1;
309 }
310
311 // Update SREG
312 // NONE
313}
314
315void brcc(uint8_t k, struct CORE *core) {
316 // Branch if carry cleared
317 // If C = 0, PC <- PC + k + 1
318 // 1 cycle
319
320 // Execute instruction
321 if (core->sreg.C == 0) {
322 core->PC = core->PC + k + 1;
323 }
324 else {
325 core->PC = core->PC + 1;
326 }
327
328 // Update SREG
329 // NONE
330}
331
332void brsh(uint8_t k, struct CORE *core) {
333 // Branch if same or higher
334 // If C = 1, PC <- PC + k + 1
335 // 1 cycle
336
337 // Execute instruction
338 if (core->sreg.C == 1) {
339 core->PC = core->PC + k + 1;
340 }
341 else {
342 core->PC = core->PC + 1;
343 }
344
345 // Update SREG
346 // NONE
347}
348
349void brlo(uint8_t k, struct CORE *core) {
350 // Branch if lower
351 // If C = 0, PC <- PC + k + 1
352 // 1 cycle
353
354 // Execute instruction
355 if (core->sreg.C == 0) {
356 core->PC = core->PC + k + 1;
357 }
358 else {
359 core->PC = core->PC + 1;
360 }
361
362 // Update SREG
363 // NONE
364}
365
366void brmi(uint8_t k, struct CORE *core) {
367 // Branch if minus
368 // If N = 1, PC <- PC + k + 1
369 // 1 cycle
370
371 // Execute instruction
372 if (core->sreg.N == 1) {
373 core->PC = core->PC + k + 1;
374 }
375 else {
376 core->PC = core->PC + 1;
377 }
378
379 // Update SREG
380 // NONE
381}
382
383void brpl(uint8_t k, struct CORE *core) {
384 // Branch if plus
385 // If N = 0, PC <- PC + k + 1
386 // 1 cycle
387
388 // Execute instruction
389 if (core->sreg.N == 0) {
390 core->PC = core->PC + k + 1;
391 }
392 else {
393 core->PC = core->PC + 1;
394 }
395
396 // Update SREG
397 // NONE
398}
399
400void brge(uint8_t k, struct CORE *core) {
401 // Branch if greater or equal
402 // If N = V, PC <- PC + k + 1
403 // 1 cycle
404
405 // Execute instruction
406 if (core->sreg.N == core->sreg.V) {
407 core->PC = core->PC + k + 1;
408 }
409 else {
410 core->PC = core->PC + 1;
411 }
412
413 // Update SREG
414 // NONE
415}
416
417void brlt(uint8_t k, struct CORE *core) {
418 // Branch if less than
419 // If N != V, PC <- PC + k + 1
420 // 1 cycle
421
422 // Execute instruction
423 if (core->sreg.N != core->sreg.V) {
424 core->PC = core->PC + k + 1;
425 }
426 else {
427 core->PC = core->PC + 1;
428 }
429
430 // Update SREG
431 // NONE
432}
433
434void brhs(uint8_t k, struct CORE *core) {
435 // Branch if half carry set
436 // If H = 1, PC <- PC + k + 1
437 // 1 cycle
438
439 // Execute instruction
440 if (core->sreg.H == 1) {
441 core->PC = core->PC + k + 1;
442 }
443 else {
444 core->PC = core->PC + 1;
445 }
446
447 // Update SREG
448 // NONE
449}
450
451void brhc(uint8_t k, struct CORE *core) {
452 // Branch if half carry cleared
453 // If H = 0, PC <- PC + k + 1
454 // 1 cycle
455
456 // Execute instruction
457 if (core->sreg.H == 0) {
458 core->PC = core->PC + k + 1;
459 }
460 else {
461 core->PC = core->PC + 1;
462 }
463
464 // Update SREG
465 // NONE
466}
467
468void brts(uint8_t k, struct CORE *core) {
469 // Branch if T flag set
470 // If T = 1, PC <- PC + k + 1
471 // 1 cycle
472
473 // Execute instruction
474 if (core->sreg.T == 1) {
475 core->PC = core->PC + k + 1;
476 }
477 else {
478 core->PC = core->PC + 1;
479 }
480
481 // Update SREG
482 // NONE
483}
484
485void brtc(uint8_t k, struct CORE *core) {
486 // Branch if T flag cleared
487 // If T = 0, PC <- PC + k + 1
488 // 1 cycle
489
490 // Execute instruction
491 if (core->sreg.T == 0) {
492 core->PC = core->PC + k + 1;
493 }
494 else {
495 core->PC = core->PC + 1;
496 }
497
498 // Update SREG
499 // NONE
500}
501
502void brvs(uint8_t k, struct CORE *core) {
503 // Branch if overflow set
504 // If V = 1, PC <- PC + k + 1
505 // 1 cycle
506
507 // Execute instruction
508 if (core->sreg.V == 1) {
509 core->PC = core->PC + k + 1;
510 }
511 else {
512 core->PC = core->PC + 1;
513 }
514
515 // Update SREG
516 // NONE
517}
518
519void brvc(uint8_t k, struct CORE *core) {
520 // Branch if overflow cleared
521 // If V = 0, PC <- PC + k + 1
522 // 1 cycle
523
524 // Execute instruction
525 if (core->sreg.V == 0) {
526 core->PC = core->PC + k + 1;
527 }
528 else {
529 core->PC = core->PC + 1;
530 }
531
532 // Update SREG
533 // NONE
534}
535
536void brie(uint8_t k, struct CORE *core) {
537 // Branch if global interrupt enabled
538 // If I = 1, PC <- PC + k + 1
539 // 1 cycle
540
541 // Execute instruction
542 if (core->sreg.I == 1) {
543 core->PC = core->PC + k + 1;
544 }
545 else {
546 core->PC = core->PC + 1;
547 }
548
549 // Update SREG
550 // NONE
551}
552
553void brid(uint8_t k, struct CORE *core) {
554 // Branch if global interrupt disabled
555 // If I = 0, PC <- PC + k + 1
556 // 1 cycle
557
558 // Execute instruction
559 if (core->sreg.I == 0) {
560 core->PC = core->PC + k + 1;
561 }
562 else {
563 core->PC = core->PC + 1;
564 }
565
566 // Update SREG
567 // NONE
568}
void brsh(uint8_t k, struct CORE *core)
Branch if same or higher.
Definition branch.c:332
void sbis(uint8_t A, uint8_t b, struct CORE *core, union DATA_SPACE *data_space)
Skip if bit in I/O register is set.
Definition branch.c:211
void brbs(uint8_t s, uint8_t k, struct CORE *core)
Branch if status flag is set.
Definition branch.c:230
void ret(struct CORE *core, struct SRAM *sram)
Return from a subroutine.
Definition branch.c:73
void brvc(uint8_t k, struct CORE *core)
Branch if overflow cleared.
Definition branch.c:519
void brbc(uint8_t s, uint8_t k, struct CORE *core)
Branch if status flag is cleared.
Definition branch.c:247
void breq(uint8_t k, struct CORE *core)
Branch if equal.
Definition branch.c:264
void brts(uint8_t k, struct CORE *core)
Branch if T flag set.
Definition branch.c:468
void brlt(uint8_t k, struct CORE *core)
Branch if less than.
Definition branch.c:417
void brie(uint8_t k, struct CORE *core)
Branch if interrupts enabled.
Definition branch.c:536
void brvs(uint8_t k, struct CORE *core)
Branch if overflow set.
Definition branch.c:502
void brhc(uint8_t k, struct CORE *core)
Branch if half carry cleared.
Definition branch.c:451
void jmp(uint32_t k, struct CORE *core)
Perform an absolute jump.
Definition branch.c:27
void brge(uint8_t k, struct CORE *core)
Branch if greater or equal.
Definition branch.c:400
void brid(uint8_t k, struct CORE *core)
Branch if interrupts disabled.
Definition branch.c:553
void brtc(uint8_t k, struct CORE *core)
Branch if T flag cleared.
Definition branch.c:485
void brlo(uint8_t k, struct CORE *core)
Branch if lower.
Definition branch.c:349
void brne(uint8_t k, struct CORE *core)
Branch if not equal.
Definition branch.c:281
void brcc(uint8_t k, struct CORE *core)
Branch if carry cleared.
Definition branch.c:315
void cpc(uint8_t d, uint8_t r, struct CORE *core)
Compare two registers with carry.
Definition branch.c:132
void brcs(uint8_t k, struct CORE *core)
Branch if carry set.
Definition branch.c:298
void reti(struct CORE *core, struct SRAM *sram)
Return from an interrupt.
Definition branch.c:87
void cp(uint8_t d, uint8_t r, struct CORE *core)
Compare two registers.
Definition branch.c:120
void icall(struct CORE *core, struct SRAM *sram)
Perform an indirect call to a subroutine.
Definition branch.c:54
void cpse(uint8_t d, uint8_t r, struct CORE *core)
Compare and skip if equal.
Definition branch.c:102
void cpi(uint8_t d, uint8_t K, struct CORE *core)
Compare register with an immediate value.
Definition branch.c:144
void brpl(uint8_t k, struct CORE *core)
Branch if plus.
Definition branch.c:383
void brhs(uint8_t k, struct CORE *core)
Branch if half carry set.
Definition branch.c:434
void sbrc(uint8_t r, uint8_t b, struct CORE *core)
Skip if bit in register is cleared.
Definition branch.c:156
void rjmp(uint8_t k, struct CORE *core)
Perform a relative jump.
Definition branch.c:3
void sbrs(uint8_t r, uint8_t b, struct CORE *core)
Skip if bit in register is set.
Definition branch.c:174
void sbic(uint8_t A, uint8_t b, struct CORE *core, union DATA_SPACE *data_space)
Skip if bit in I/O register is cleared.
Definition branch.c:192
void brmi(uint8_t k, struct CORE *core)
Branch if minus.
Definition branch.c:366
void ijmp(struct CORE *core)
Perform an indirect jump.
Definition branch.c:15
void rcall(uint8_t k, struct CORE *core, struct SRAM *sram)
Perform a relative call to a subroutine.
Definition branch.c:39
Branching and jumps instructions.
void update_sreg_I(struct CORE *core, bool state)
Update the Interrupt flag (I) in the status register.
Definition sreg_utils.c:103
void update_sreg_arithm(struct CORE *core, uint8_t Rd, uint8_t Rr, uint8_t result)
Updates the Status Register (SREG) for arithmetic operations.
Definition sreg_utils.c:51
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
uint32_t PC
Definition core.h:69
union SREG sreg
Definition core.h:71
Definition sram.h:7
uint8_t mem[SRAM_SIZE]
Definition sram.h:8
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 R[32]
Definition core.h:29
uint16_t Z
Definition core.h:59
bool N
Definition core.h:15
bool C
Definition core.h:13
bool V
Definition core.h:16
bool Z
Definition core.h:14
bool I
Definition core.h:20
bool H
Definition core.h:18
uint8_t sreg
Definition core.h:11
bool T
Definition core.h:19