Avr8bit-emulator
An emulator for the Atmel AVR 8-bit microcontroller
Loading...
Searching...
No Matches
arithm_logic.c
Go to the documentation of this file.
1#include "arithm_logic.h"
2
3void add(uint8_t d, uint8_t r, struct CORE *core) {
4 // Add without carry
5 // Rd <- Rd + Rr
6 // 1 cycle
7
8 uint8_t R_tmp = core->gp.R[d];
9
10 // Execute instruction
11 core->gp.R[d] = core->gp.R[d] + core->gp.R[r];
12
13 // Update SREG
14 update_sreg_arithm(core, R_tmp, core->gp.R[r], core->gp.R[d]);
15
16 inc_pc(core);
17}
18
19void adc(uint8_t d, uint8_t r, struct CORE *core) {
20 // Add with cary
21 // Rd <- Rd + Rr + C
22 // 1 cycle
23
24 uint8_t R_tmp = core->gp.R[d];
25
26 // Execute instruction
27 core->gp.R[d] = core->gp.R[d] + core->gp.R[r] + core->sreg.C;
28
29 // Update SREG
30 update_sreg_arithm(core, R_tmp, core->gp.R[r], core->gp.R[d]);
31
32 inc_pc(core);
33}
34
35void adiw(uint8_t d, uint8_t K, struct CORE *core) {
36 // Add immediate to word
37 // Rd:Rd+1 <- Rd:Rd+1 + K
38 // 2 cycle
39
40 // Execute instruction
41 uint16_t Rd = core->gp.R[d] | (core->gp.R[d + 1] << 8);
42 uint16_t result = Rd + K;
43 core->gp.R[d] = result & 0xFF;
44 core->gp.R[d + 1] = (result >> 8) & 0xFF;
45
46 // Update SREG
47 udpate_sreg_arithm_16bit(core, Rd, result);
48
49 inc_pc(core);
50}
51
52void sub(uint8_t d, uint8_t r, struct CORE *core) {
53 // Subtract without cary
54 // Rd <- Rd - Rr
55 // 1 cycle
56
57 uint8_t R_tmp = core->gp.R[d];
58
59 // Execute instruction
60 core->gp.R[d] = core->gp.R[d] - core->gp.R[r];
61
62 // Update SREG
63 update_sreg_arithm(core, R_tmp, core->gp.R[r], core->gp.R[d]);
64
65 inc_pc(core);
66}
67
68void subi(uint8_t d, uint8_t K, struct CORE *core) {
69 // Subtract immediate
70 // Rd <- Rd - K
71 // 1 cycle
72
73 uint8_t R_tmp = core->gp.R[d];
74
75 // Execute instruction
76 core->gp.R[d] = core->gp.R[d] - K;
77
78 // Update SREG
79 update_sreg_arithm(core, R_tmp, K, core->gp.R[d]);
80
81 inc_pc(core);
82}
83
84void sbc(uint8_t d, uint8_t r, struct CORE *core) {
85 // Subtract with cary
86 // Rd <- Rd - Rr - C
87 // 1 cycle
88
89 uint8_t R_tmp = core->gp.R[d];
90
91 // Execute instruction
92 core->gp.R[d] = core->gp.R[d] - core->gp.R[r] - core->sreg.C;
93
94 // Update SREG
95 update_sreg_arithm(core, R_tmp, core->gp.R[r], core->gp.R[d]);
96
97 inc_pc(core);
98}
99
100void sbci(uint8_t d, uint8_t K, struct CORE *core) {
101 // Subtract immediate with cary
102 // Rd <- Rd - K - C
103 // 1 cycle
104
105 uint8_t R_tmp = core->gp.R[d];
106
107 // Execute instruction
108 core->gp.R[d] = core->gp.R[d] - K - core->sreg.C;
109
110 // Update SREG
111 update_sreg_arithm(core, R_tmp, K, core->gp.R[d]);
112
113 inc_pc(core);
114}
115
116void sbiw(uint8_t d, uint8_t K, struct CORE *core) {
117 // Subtract immediate from word
118 // Rd:Rd+1 <- Rd:Rd+1 - K
119 // 2 cycle
120
121 // Execute instruction
122 uint16_t Rd = core->gp.R[d] | (core->gp.R[d + 1] << 8);
123 uint16_t result = Rd - K;
124 core->gp.R[d] = result & 0xFF;
125 core->gp.R[d + 1] = (result >> 8) & 0xFF;
126
127 // Update SREG
128 udpate_sreg_arithm_16bit(core, Rd, result);
129
130 inc_pc(core);
131}
132
133void and(uint8_t d, uint8_t r, struct CORE *core) {
134 // Logical AND
135 // Rd <- Rd & Rr
136 // 1 cycle
137
138 // Execute instruction
139 core->gp.R[d] = core->gp.R[d] & core->gp.R[r];
140
141 // Update SREG
142 update_sreg_logic(core, core->gp.R[d]);
143
144 inc_pc(core);
145}
146
147void andi(uint8_t d, uint8_t K, struct CORE *core) {
148 // Logical AND with immediate
149 // Rd <- Rd & K
150 // 1 cycle
151
152 // Execute instruction
153 core->gp.R[d] = core->gp.R[d] & K;
154
155 // Update SREG
156 update_sreg_logic(core, core->gp.R[d]);
157
158 inc_pc(core);
159}
160
161void or(uint8_t d, uint8_t r, struct CORE *core) {
162 // Logical OR
163 // Rd <- Rd | Rr
164 // 1 cycle
165
166 // Execute instruction
167 core->gp.R[d] = core->gp.R[d] | core->gp.R[r];
168
169 // Update SREG
170 update_sreg_logic(core, core->gp.R[d]);
171
172 inc_pc(core);
173}
174
175void ori(uint8_t d, uint8_t K, struct CORE *core) {
176 // Logical OR with immediate
177 // Rd <- Rd | K
178 // 1 cycle
179
180 // Execute instruction
181 core->gp.R[d] = core->gp.R[d] | K;
182
183 // Update SREG
184 update_sreg_logic(core, core->gp.R[d]);
185
186 inc_pc(core);
187}
188
189void eor(uint8_t d, uint8_t r, struct CORE *core) {
190 // Logical Exclusive OR
191 // Rd <- Rd ^ Rr
192 // 1 cycle
193
194 // Execute instruction
195 core->gp.R[d] = core->gp.R[d] ^ core->gp.R[r];
196
197 // Update SREG
198 update_sreg_logic(core, core->gp.R[d]);
199
200 inc_pc(core);
201}
202
203void com(uint8_t d, struct CORE *core) {
204 // Logical Complement
205 // Rd <- $FF - Rd
206 // 1 cycle
207
208 // Execute instruction
209 core->gp.R[d] = ~core->gp.R[d];
210
211 // Update SREG
212 update_sreg_logic(core, core->gp.R[d]);
213 update_sreg_C(core, true);
214
215 inc_pc(core);
216}
217
218void neg(uint8_t d, struct CORE *core) {
219 // Two's Complement
220 // Rd <- $00 - Rd
221 // 1 cycle
222
223 // Execute instruction
224 core->gp.R[d] = -core->gp.R[d];
225 inc_pc(core);
226}
227
228void sbr(uint8_t d, uint8_t K, struct CORE *core) {
229 // Set Bit in Register
230 // Rd <- Rd | K
231 // 1 cycle
232
233 // Execute instruction
234 core->gp.R[d] = core->gp.R[d] | K;
235 inc_pc(core);
236}
237
238void cbr(uint8_t d, uint8_t K, struct CORE *core) {
239 // Clear Bit in Register
240 // Rd <- Rd & ($FF - K)
241 // 1 cycle
242
243 // Execute instruction
244 core->gp.R[d] = core->gp.R[d] & ~K;
245 inc_pc(core);
246}
247
248void inc(uint8_t d, struct CORE *core) {
249 // Increment
250 // Rd <- Rd + 1
251 // 1 cycle
252
253 // Execute instruction
254 core->gp.R[d] = core->gp.R[d] + 1;
255 inc_pc(core);
256}
257
258void dec(uint8_t d, struct CORE *core) {
259 // Decrement
260 // Rd <- Rd - 1
261 // 1 cycle
262
263 // Execute instruction
264 core->gp.R[d] = core->gp.R[d] - 1;
265 inc_pc(core);
266}
267
268void tst(uint8_t d, struct CORE *core) {
269 // Test for Zero or Minus
270 // Rd <- Rd & Rd
271 // 1 cycle
272
273 // Execute instruction
274 core->gp.R[d] = core->gp.R[d] & core->gp.R[d];
275 inc_pc(core);
276}
277
278void clr(uint8_t d, struct CORE *core) {
279 // Clear Register
280 // Rd <- 0
281 // 1 cycle
282
283 // Execute instruction
284 core->gp.R[d] = 0;
285 inc_pc(core);
286}
287
288void ser(uint8_t d, struct CORE *core) {
289 // Set Register
290 // Rd <- $FF
291 // 1 cycle
292
293 // Execute instruction
294 core->gp.R[d] = 0xFF;
295 inc_pc(core);
296}
297
298void mul(uint8_t d, uint8_t r, struct CORE *core) {
299 // Multiply Unsigned
300 // R1:R0 <- Rd * Rr (UU)
301 // 2 cycle
302
303 // Execute instruction
304 uint16_t result = (uint16_t)core->gp.R[d] * (uint16_t)core->gp.R[r];
305 core->gp.R[0] = result & 0xFF;
306 core->gp.R[1] = (result >> 8) & 0xFF;
307 inc_pc(core);
308}
309
310void muls(uint8_t d, uint8_t r, struct CORE *core) {
311 // Multiply Signed
312 // R1:R0 <- Rd * Rr (SS)
313 // 2 cycle
314
315 // Execute instruction
316 int16_t result = (int16_t)core->gp.R[d] * (int16_t)core->gp.R[r];
317 core->gp.R[0] = result & 0xFF;
318 core->gp.R[1] = (result >> 8) & 0xFF;
319 inc_pc(core);
320}
321
322void mulsu(uint8_t d, uint8_t r, struct CORE *core) {
323 // Multiply Signed with Unsigned
324 // R1:R0 <- Rd * Rr (SU)
325 // 2 cycle
326
327 // Execute instruction
328 int16_t result = (int16_t)core->gp.R[d] * (uint16_t)core->gp.R[r];
329 core->gp.R[0] = result & 0xFF;
330 core->gp.R[1] = (result >> 8) & 0xFF;
331 inc_pc(core);
332}
333
334void fmul(uint8_t d, uint8_t r, struct CORE *core) {
335 // Fractional Multiply Unsigned
336 // R1:R0 <- Rd * Rr (UU)
337 // 2 cycle
338
339 // Execute instruction
340 uint16_t result = (uint16_t)core->gp.R[d] * (uint16_t)(core->gp.R[r] << 1);
341 core->gp.R[0] = result & 0xFF;
342 core->gp.R[1] = (result >> 8) & 0xFF;
343 inc_pc(core);
344}
345
346void fmuls(uint8_t d, uint8_t r, struct CORE *core) {
347 // Fractional Multiply Signed
348 // R1:R0 <- Rd * Rr (SS)
349 // 2 cycle
350
351 // Execute instruction
352 int16_t result = (int16_t)core->gp.R[d] * (int16_t)(core->gp.R[r] << 1);
353 core->gp.R[0] = result & 0xFF;
354 core->gp.R[1] = (result >> 8) & 0xFF;
355 inc_pc(core);
356}
357
358void fmulsu(uint8_t d, uint8_t r, struct CORE *core) {
359 // Fractional Multiply Signed with Unsigned
360 // R1:R0 <- Rd * Rr (SU)
361 // 2 cycle
362
363 // Execute instruction
364 int16_t result = (int16_t)core->gp.R[d] * (uint16_t)(core->gp.R[r] << 1);
365 core->gp.R[0] = result & 0xFF;
366 core->gp.R[1] = (result >> 8) & 0xFF;
367 inc_pc(core);
368}
void mul(uint8_t d, uint8_t r, struct CORE *core)
Multiplies two unsigned 8-bit integers and stores the result in the CORE structure.
void adc(uint8_t d, uint8_t r, struct CORE *core)
Add with carry.
void subi(uint8_t d, uint8_t K, struct CORE *core)
Subtract immediate.
void sub(uint8_t d, uint8_t r, struct CORE *core)
Subtract.
void tst(uint8_t d, struct CORE *core)
Test for zero or minus after AND operation.
void inc(uint8_t d, struct CORE *core)
Increment the value of a register.
void add(uint8_t d, uint8_t r, struct CORE *core)
Add without carry.
Definition arithm_logic.c:3
void ser(uint8_t d, struct CORE *core)
Set all bits in a register.
void fmul(uint8_t d, uint8_t r, struct CORE *core)
Multiplies two unsigned 8-bit integers with fractional representation and stores the result in the CO...
void dec(uint8_t d, struct CORE *core)
Decrement the value of a register.
void muls(uint8_t d, uint8_t r, struct CORE *core)
Multiplies two signed 8-bit integers and stores the result in the CORE structure.
void andi(uint8_t d, uint8_t K, struct CORE *core)
Logical AND with immediate.
void eor(uint8_t d, uint8_t r, struct CORE *core)
Perform bitwise exclusive OR between two registers.
void sbr(uint8_t d, uint8_t K, struct CORE *core)
Set bits in a register.
void clr(uint8_t d, struct CORE *core)
Clear a register (set to zero).
void ori(uint8_t d, uint8_t K, struct CORE *core)
Logical OR with immediate.
void sbci(uint8_t d, uint8_t K, struct CORE *core)
Subtract immediate with carry.
void mulsu(uint8_t d, uint8_t r, struct CORE *core)
Multiplies a signed 8-bit integer with an unsigned 8-bit integer and stores the result in the CORE st...
void fmulsu(uint8_t d, uint8_t r, struct CORE *core)
Multiplies a signed 8-bit integer with an unsigned 8-bit integer with fractional representation and s...
void or(uint8_t d, uint8_t r, struct CORE *core)
Logical OR.
void cbr(uint8_t d, uint8_t K, struct CORE *core)
Clear bits in a register.
void com(uint8_t d, struct CORE *core)
Perform one's complement on a register.
void fmuls(uint8_t d, uint8_t r, struct CORE *core)
Multiplies two signed 8-bit integers with fractional representation and stores the result in the CORE...
void and(uint8_t d, uint8_t r, struct CORE *core)
Logical AND.
void neg(uint8_t d, struct CORE *core)
Perform two's complement (negation) on a register.
void adiw(uint8_t d, uint8_t K, struct CORE *core)
Add immediate to word.
void sbc(uint8_t d, uint8_t r, struct CORE *core)
Subtract with carry.
void sbiw(uint8_t d, uint8_t K, struct CORE *core)
Subtract immediate from word.
Arithmetic and logic operations.
void inc_pc(struct CORE *core)
Definition core.c:3
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
void update_sreg_logic(struct CORE *core, uint8_t result)
Updates the Status Register (SREG) for logical operations.
Definition sreg_utils.c:60
void udpate_sreg_arithm_16bit(struct CORE *core, uint16_t Rd, uint16_t result)
Updates the Status Register (SREG) for 16-bit arithmetic operations.
Definition sreg_utils.c:67
void update_sreg_C(struct CORE *core, bool state)
Update the Carry flag (C) in the status register.
Definition sreg_utils.c:75
Core structure containing general purpose registers, program counter, stack pointer,...
Definition core.h:67
union GP gp
Definition core.h:68
union SREG sreg
Definition core.h:71
uint8_t R[32]
Definition core.h:29
bool C
Definition core.h:13