Subastra
Loading...
Searching...
No Matches
ops.h
Go to the documentation of this file.
1#ifndef __H__OPS__
2#define __H__OPS__
3
4#include "../defs.h"
5#include "./generated/lookup.h"
6#include "addressing.h"
7#include "chip.h"
8#include "memory.h"
9
10static void chip_op_beq(chip_t *self) {
12 if (chip_flags_get(self, FLAG_ZERO) == 1)
13 self->pc += offset;
14}
15
16static void chip_op_bmi(chip_t *self) {
18 if (chip_flags_get(self, FLAG_NEGATIVE) == 1)
19 self->pc += offset;
20}
21
22static void chip_op_bpl(chip_t *self) {
24 if (chip_flags_get(self, FLAG_NEGATIVE) == 0)
25 self->pc += offset;
26}
27
28static void chip_op_bne(chip_t *self) {
30 if (chip_flags_get(self, FLAG_ZERO) == 0)
31 self->pc += offset;
32}
33
34// STore X into memory
35static void chip_op_stx(chip_t *self, addressing_mode_t mode) {
36 chip_memory_perform_write(self, mode, self->x);
37}
38
39// STore Y into memory
40static void chip_op_sty(chip_t *self, addressing_mode_t mode) {
41 chip_memory_perform_write(self, mode, self->y);
42}
43
44// STore Accumulator into memory
45static void chip_op_sta(chip_t *self, addressing_mode_t mode) {
46 chip_memory_perform_write(self, mode, self->ac);
47}
48
49// INCrement memory
50static void chip_op_inc(chip_t *self, addressing_mode_t mode) {
51 u32 read = chip_memory_perform_read(self, mode);
52 u16 addr = get_memory_addr(read);
53 byte value = get_memory_word(read) + 1;
54
56 chip_memory_write_direct(self, addr, value);
57}
58
59// DEcrement Y
60static void chip_op_dey(chip_t *self) {
61 self->y = (self->y - 1) & 0xFF;
63}
64
65// DEcrement X
66static void chip_op_dex(chip_t *self) {
67 self->x = (self->x - 1) & 0xFF;
69}
70
71// INcrement Y
72static void chip_op_iny(chip_t *self) {
73 self->y = (self->y + 1) & 0xFF;
75}
76
77// INcrement X
78static void chip_op_inx(chip_t *self) {
79 self->x = (self->x + 1) & 0xFF;
81}
82
83// Jump with Saved Return
84static void chip_op_jsr(chip_t *self) {
85 u16 pc = (self->pc + 1) & 0xFFFF;
86
87 chip_stack_push(self, (pc >> 8) & 0xFF);
88 chip_stack_push(self, pc & 0xFF);
89
91}
92
93static void chip_op_pla(chip_t *self) {
94 byte value = chip_stack_pull(self);
95 self->ac = value;
97}
98
99static void chip_op_pha(chip_t *self) { chip_stack_push(self, self->ac); }
100
101static void chip_op_phx(chip_t *self) { chip_stack_push(self, self->x); }
102
103static void chip_op_phy(chip_t *self) { chip_stack_push(self, self->y); }
104
105static void chip_op_cpy(chip_t *self, addressing_mode_t mode) {
106 byte value = chip_memory_read_word(self, mode);
107 byte result = self->y - value;
108
110 chip_flags_update_carry(self, self->y >= value);
111}
112
113static void chip_op_cpx(chip_t *self, addressing_mode_t mode) {
114 byte value = chip_memory_read_word(self, mode);
115 byte result = self->x - value;
116
118 chip_flags_update_carry(self, self->x >= value);
119}
120
121static void chip_op_rts(chip_t *self) {
122 u16 addr = 0;
123 addr |= (u16)chip_stack_pull(self);
124 addr |= (u16)chip_stack_pull(self) << 8;
125 self->pc = (addr + 1) & 0xFFFF;
126}
127
128static void chip_op_lda(chip_t *self, addressing_mode_t mode) {
129 byte value = chip_memory_read_word(self, mode);
130 self->ac = value;
132}
133
134static void chip_op_jmp(chip_t *self, addressing_mode_t mode) {
135 u16 read = chip_memory_read_addr(self, mode);
136 self->pc = read & 0xFFFF;
137}
138
139static void chip_op_ldy(chip_t *self, addressing_mode_t mode) {
140 byte value = chip_memory_read_word(self, mode);
141 self->y = value;
143}
144
145static void chip_op_ldx(chip_t *self, addressing_mode_t mode) {
146 byte value = chip_memory_read_word(self, mode);
147 self->x = value;
149}
150
151static void chip_op_tay(chip_t *self) {
152 self->y = self->ac;
153 // NOTE(Artur): Just philosophically, is it more beneficial to
154 // use self->y or self->ac here?
156}
157
158static void chip_op_tya(chip_t *self) {
159 self->ac = self->y;
161}
162
163static void chip_op_txa(chip_t *self) {
164 self->ac = self->x;
166}
167
168static void chip_op_txs(chip_t *self) { self->sp = self->x; }
169
170static void chip_op_tsx(chip_t *self) {
171 self->x = self->sp;
173}
174
175static void chip_op_tax(chip_t *self) {
176 self->x = self->ac;
178}
179
180// SEt Carry
181static void chip_op_sec(chip_t *self) { chip_flags_set(self, FLAG_CARRY, 1); }
182
183// SEt Interrupt disable
184static void chip_op_sei(chip_t *self) {
186}
187
188// SEt Decimal
189static void chip_op_sed(chip_t *self) { chip_flags_set(self, FLAG_DECIMAL, 1); }
190
191static void chip_op_sbc(chip_t *self, addressing_mode_t mode) {
192 byte value = chip_memory_read_word(self, mode);
193 byte carry = chip_flags_get(self, FLAG_CARRY);
194
195 u16 result = (u16)self->ac - value - (1 - carry);
196
197 chip_flags_update_carry(self, self->ac >= (value + (1 - carry)));
199
200 // TODO: sanity check this, looks too complicated
201 byte overflow = ((self->ac ^ result) & (self->ac ^ value)) & 0x80;
202 chip_flags_update_overflow(self, overflow);
203
204 self->ac = result;
205}
206
207static void chip_op_adc(chip_t *self, addressing_mode_t mode) {
208 byte value = chip_memory_read_word(self, mode);
209 byte carry = chip_flags_get(self, FLAG_CARRY);
210
211 u16 result = (u16)self->ac + value + carry;
212
213 chip_flags_update_carry(self, result > 0xFF);
215
216 // byte overflow = (self->ac ^ result8) & (value ^ result8) & 0x80;
217 byte overflow =
218 (self->ac ^ (byte)result) & ((~(self->ac ^ value) & 0x80) != 0);
219 chip_flags_update_overflow(self, overflow);
220
221 self->ac = result;
222}
223
224// Branch on Carry Set
225static void chip_op_bcs(chip_t *self) {
227 if (chip_flags_get(self, FLAG_CARRY) == 1)
228 self->pc += offset;
229}
230
231// Branch on Carry Clear
232static void chip_op_bcc(chip_t *self) {
234 if (chip_flags_get(self, FLAG_CARRY) == 0)
235 self->pc += offset;
236}
237
238// DECrement memory
239static void chip_op_dec(chip_t *self, addressing_mode_t mode) {
240 u32 read = chip_memory_perform_read(self, mode);
241 u16 addr = get_memory_addr(read);
242 byte value = get_memory_word(read) - 1;
243
245 chip_memory_write_direct(self, addr, value);
246}
247
248// CoMPare accumulator
249static void chip_op_cmp(chip_t *self, addressing_mode_t mode) {
250 byte value = chip_memory_read_word(self, mode);
251 byte result = (self->ac - value) & 0xFF;
252
253 chip_flags_update_carry(self, self->ac >= value);
255}
256
257static void chip_op_bvc(chip_t *self) {
259 if (chip_flags_get(self, FLAG_OVERFLOW) == 0)
260 self->pc += offset;
261}
262
263static void chip_op_bvs(chip_t *self) {
265 if (chip_flags_get(self, FLAG_OVERFLOW) == 1)
266 self->pc += offset;
267}
268
269static void chip_op_eor(chip_t *self, addressing_mode_t mode) {
270 byte value = chip_memory_read_word(self, mode);
271 self->ac = self->ac ^ value;
273}
274
275static void chip_op_and(chip_t *self, addressing_mode_t mode) {
276 byte value = chip_memory_read_word(self, mode);
277 self->ac = self->ac & value;
279}
280
281static void chip_op_ora(chip_t *self, addressing_mode_t mode) {
282 byte value = chip_memory_read_word(self, mode);
283 self->ac = self->ac | value;
285}
286
287// Arithmetic Shift Left
288static void chip_op_asl(chip_t *self, addressing_mode_t mode) {
289 byte value;
290 u16 addr;
291 if (mode == ADDR_MODE_ACCUMULATOR)
292 value = self->ac;
293 else {
294 u32 read = chip_memory_perform_read(self, mode);
295 value = get_memory_word(read);
296 addr = get_memory_addr(read);
297 }
298
299 byte carry = (value >> 7) & 1;
300 byte result = (value << 1) & 0xFF;
301
302 chip_flags_update_carry(self, carry);
304
305 if (mode == ADDR_MODE_ACCUMULATOR)
306 self->ac = result;
307 else
308 chip_memory_write_direct(self, addr, result);
309}
310
311static void chip_op_ror(chip_t *self, addressing_mode_t mode) {
312 byte value;
313 u16 addr;
314 if (mode == ADDR_MODE_ACCUMULATOR)
315 value = self->ac;
316 else {
317 u32 read = chip_memory_perform_read(self, mode);
318 value = get_memory_word(read);
319 addr = get_memory_addr(read);
320 }
321
322 byte old_carry = chip_flags_get(self, FLAG_CARRY);
323 byte new_carry = value & 1;
324 byte result = (old_carry << 7) | (value >> 1);
325 chip_flags_update_carry(self, new_carry);
327
328 if (mode == ADDR_MODE_ACCUMULATOR)
329 self->ac = result;
330 else
331 chip_memory_write_direct(self, addr, result);
332}
333
334static void chip_op_lsr(chip_t *self, addressing_mode_t mode) {
335 byte value;
336 u16 addr;
337 if (mode == ADDR_MODE_ACCUMULATOR)
338 value = self->ac;
339 else {
340 u32 read = chip_memory_perform_read(self, mode);
341 value = get_memory_word(read);
342 addr = get_memory_addr(read);
343 }
344
345 byte carry = value & 1;
346 byte result = value >> 1;
347
348 chip_flags_update_carry(self, carry);
350
351 if (mode == ADDR_MODE_ACCUMULATOR)
352 self->ac = result;
353 else
354 chip_memory_write_direct(self, addr, result);
355}
356
357static void chip_op_rol(chip_t *self, addressing_mode_t mode) {
358 byte value;
359 u16 addr;
360 if (mode == ADDR_MODE_ACCUMULATOR)
361 value = self->ac;
362 else {
363 u32 read = chip_memory_perform_read(self, mode);
364 value = get_memory_word(read);
365 addr = get_memory_addr(read);
366 }
367
368 byte carry = (value >> 7) & 1;
369 byte result = ((value << 1) & 0xFF) | chip_flags_get(self, FLAG_CARRY);
370
371 chip_flags_update_carry(self, carry);
373
374 if (mode == ADDR_MODE_ACCUMULATOR)
375 self->ac = result;
376 else
377 chip_memory_write_direct(self, addr, result);
378}
379
380// CLear Carry
381static void chip_op_clc(chip_t *self) { chip_flags_set(self, FLAG_CARRY, 0); }
382
383// CLear Interrupt disable
384static void chip_op_cli(chip_t *self) {
386}
387
388// CLear Decimal
389static void chip_op_cld(chip_t *self) { chip_flags_set(self, FLAG_DECIMAL, 0); }
390
391// CLear oVerflow
392static void chip_op_clv(chip_t *self) {
394}
395
396// BReaK
397static void chip_op_brk(chip_t *self) {
398 u16 pc = (self->pc + 1) & 0xFFFF;
399
400 chip_stack_push(self, (pc >> 8) & 0xFF);
401 chip_stack_push(self, pc & 0xFF);
402
403 byte status = self->sr | FLAG_MASK_B | FLAG_MASK_B;
404 chip_stack_push(self, status);
406
407 byte lo = chip_memory_read_direct(self, 0xFFFE);
408 byte hi = chip_memory_read_direct(self, 0xFFFF);
409
410 self->pc = ((u16)hi << 8) | lo;
411}
412
413// NO oPeration
414static void chip_op_nop(chip_t *self) {}
415
416static void chip_step(chip_t *self) {
417 if (self->halted)
418 return;
419
420 byte opcode = chip_pc_inc(self);
421 if (opcode == 0x80) {
422 self->halted = true;
423 return;
424 } else if (opcode == 0x89) {
425 if (self->external_call)
426 self->external_call(self);
427 else
428 self->halted = true;
429 return;
430 }
431
432 chip_decode_execute(self, opcode);
433}
434
435#endif
addressing_mode_t
Definition addressing.h:6
@ ADDR_MODE_ACCUMULATOR
Definition addressing.h:19
@ ADDR_MODE_ABSOLUTE
Definition addressing.h:7
@ ADDR_MODE_RELATIVE
Definition addressing.h:11
static void chip_stack_push(chip_t *self, byte value)
Definition chip.h:242
static u32 chip_memory_perform_read(chip_t *self, addressing_mode_t mode)
Definition chip.h:131
static byte chip_memory_read_word(chip_t *self, addressing_mode_t mode)
Definition chip.h:234
static u16 get_memory_addr(u32 read)
Definition chip.h:226
static void chip_flags_update_overflow(chip_t *self, byte value)
Definition chip.h:284
static u16 chip_memory_perform_write(chip_t *self, addressing_mode_t mode, byte value)
Definition chip.h:177
static byte get_memory_word(u32 read)
Definition chip.h:228
static void chip_flags_set(chip_t *self, register_flags_t flag, byte value)
Definition chip.h:267
static byte chip_pc_inc(chip_t *self)
Definition chip.h:127
static void chip_memory_write_direct(chip_t *self, u16 at, byte value)
Definition chip.h:119
static u16 chip_memory_read_addr(chip_t *self, addressing_mode_t mode)
Definition chip.h:230
@ FLAG_MASK_B
Definition chip.h:59
static byte chip_memory_read_direct(chip_t *self, u16 at)
Definition chip.h:109
static void chip_flags_update_carry(chip_t *self, byte value)
Definition chip.h:272
@ FLAG_NEGATIVE
Definition chip.h:51
@ FLAG_OVERFLOW
Definition chip.h:50
@ FLAG_ZERO
Definition chip.h:44
@ FLAG_CARRY
Definition chip.h:43
@ FLAG_DECIMAL
Definition chip.h:46
@ FLAG_INTERRUPT_DISABLE
Definition chip.h:45
static byte chip_stack_pull(chip_t *self)
Definition chip.h:252
static void chip_flags_update_zero_negative(chip_t *self, byte value)
Definition chip.h:276
static byte chip_flags_get(chip_t *self, register_flags_t flag)
Definition chip.h:263
unsigned char byte
Definition defs.h:49
uint16_t u16
Definition defs.h:48
char i8
Definition defs.h:50
uint32_t u32
Definition defs.h:45
static void chip_op_adc(chip_t *self, addressing_mode_t mode)
Definition ops.h:207
static void chip_op_asl(chip_t *self, addressing_mode_t mode)
Definition ops.h:288
static void chip_op_lda(chip_t *self, addressing_mode_t mode)
Definition ops.h:128
static void chip_op_dex(chip_t *self)
Definition ops.h:66
static void chip_op_jsr(chip_t *self)
Definition ops.h:84
static void chip_op_phy(chip_t *self)
Definition ops.h:103
static void chip_op_inc(chip_t *self, addressing_mode_t mode)
Definition ops.h:50
static void chip_op_cld(chip_t *self)
Definition ops.h:389
static void chip_op_beq(chip_t *self)
Definition ops.h:10
static void chip_op_clc(chip_t *self)
Definition ops.h:381
static void chip_op_cli(chip_t *self)
Definition ops.h:384
static void chip_op_txa(chip_t *self)
Definition ops.h:163
static void chip_op_ldy(chip_t *self, addressing_mode_t mode)
Definition ops.h:139
static void chip_op_pha(chip_t *self)
Definition ops.h:99
static void chip_op_sei(chip_t *self)
Definition ops.h:184
static void chip_op_bpl(chip_t *self)
Definition ops.h:22
static void chip_op_sty(chip_t *self, addressing_mode_t mode)
Definition ops.h:40
static void chip_op_eor(chip_t *self, addressing_mode_t mode)
Definition ops.h:269
static void chip_op_bcc(chip_t *self)
Definition ops.h:232
static void chip_op_cpy(chip_t *self, addressing_mode_t mode)
Definition ops.h:105
static void chip_op_cpx(chip_t *self, addressing_mode_t mode)
Definition ops.h:113
static void chip_op_pla(chip_t *self)
Definition ops.h:93
static void chip_op_jmp(chip_t *self, addressing_mode_t mode)
Definition ops.h:134
static void chip_op_bcs(chip_t *self)
Definition ops.h:225
static void chip_op_tsx(chip_t *self)
Definition ops.h:170
static void chip_op_dey(chip_t *self)
Definition ops.h:60
static void chip_op_tay(chip_t *self)
Definition ops.h:151
static void chip_op_bvc(chip_t *self)
Definition ops.h:257
static void chip_op_txs(chip_t *self)
Definition ops.h:168
static void chip_op_ldx(chip_t *self, addressing_mode_t mode)
Definition ops.h:145
static void chip_op_bne(chip_t *self)
Definition ops.h:28
static void chip_op_sbc(chip_t *self, addressing_mode_t mode)
Definition ops.h:191
static void chip_op_rts(chip_t *self)
Definition ops.h:121
static void chip_op_brk(chip_t *self)
Definition ops.h:397
static void chip_op_sec(chip_t *self)
Definition ops.h:181
static void chip_step(chip_t *self)
Definition ops.h:416
static void chip_op_and(chip_t *self, addressing_mode_t mode)
Definition ops.h:275
static void chip_op_sta(chip_t *self, addressing_mode_t mode)
Definition ops.h:45
static void chip_op_inx(chip_t *self)
Definition ops.h:78
static void chip_op_dec(chip_t *self, addressing_mode_t mode)
Definition ops.h:239
static void chip_op_lsr(chip_t *self, addressing_mode_t mode)
Definition ops.h:334
static void chip_op_tax(chip_t *self)
Definition ops.h:175
static void chip_op_bmi(chip_t *self)
Definition ops.h:16
static void chip_op_rol(chip_t *self, addressing_mode_t mode)
Definition ops.h:357
static void chip_op_ora(chip_t *self, addressing_mode_t mode)
Definition ops.h:281
static void chip_op_nop(chip_t *self)
Definition ops.h:414
static void chip_op_tya(chip_t *self)
Definition ops.h:158
static void chip_op_clv(chip_t *self)
Definition ops.h:392
static void chip_op_cmp(chip_t *self, addressing_mode_t mode)
Definition ops.h:249
static void chip_op_phx(chip_t *self)
Definition ops.h:101
static void chip_op_sed(chip_t *self)
Definition ops.h:189
static void chip_op_iny(chip_t *self)
Definition ops.h:72
static void chip_op_ror(chip_t *self, addressing_mode_t mode)
Definition ops.h:311
static void chip_op_stx(chip_t *self, addressing_mode_t mode)
Definition ops.h:35
static void chip_op_bvs(chip_t *self)
Definition ops.h:263
Definition chip.h:27
byte ac
Definition chip.h:39
byte sp
Definition chip.h:39
bool halted
Definition chip.h:34
chip_external_call_f external_call
Definition chip.h:29
u16 pc
Definition chip.h:38
byte x
Definition chip.h:39
byte y
Definition chip.h:39
byte sr
Definition chip.h:39