summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-06-08 22:08:51 +0530
committervin <git@vineetk.net>2024-06-08 22:08:51 +0530
commit72e29b3d25bfe93810b3faf3133dfc3c15f15e14 (patch)
tree56b346179eb7da1b64f11de836f086b30dd87b9e /cpu.c
parent1ac30a026b7877ca6b295c661d91b20eaddb01c9 (diff)
move addressing mode parsing into separate function
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c117
1 files changed, 44 insertions, 73 deletions
diff --git a/cpu.c b/cpu.c
index 08c6119..86fbcb0 100644
--- a/cpu.c
+++ b/cpu.c
@@ -62,49 +62,58 @@ peek16(uint16_t addr)
62 return (uint16_t)memory[addr] | ((uint16_t)memory[addr + 1] << 8); 62 return (uint16_t)memory[addr] | ((uint16_t)memory[addr + 1] << 8);
63} 63}
64 64
65void 65uint8_t
66adc(enum addressing_mode mode) 66opmode_arg(enum addressing_mode mode)
67{ 67{
68 uint8_t arg, val; 68 uint8_t arg, val;
69 uint16_t sum; // 16-bit sum makes it easier to determine carry flag
70 69
71 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) 70 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y)
72 arg = peek(regs.pc++); 71 arg = peek(regs.pc++);
73 else 72 else
74 arg = peek16(regs.pc++); 73 arg = peek16(regs.pc), regs.pc += 2;
75 74
76 switch (mode) { 75 switch (mode) {
77 case AM_IMM: /* $69 */ 76 case AM_IMM:
78 val = arg; 77 val = arg;
79 break; 78 break;
80 case AM_ZP: /* $65 */ 79 case AM_ZP:
81 val = peek(arg % 256); 80 val = peek(arg % 256);
82 break; 81 break;
83 case AM_ABS: /* $6D */ 82 case AM_ZP_X:
84 val = peek16(arg);
85 break;
86 case AM_ZP_X: /* $75 */
87 val = peek((arg + regs.x) % 256); 83 val = peek((arg + regs.x) % 256);
88 break; 84 break;
89 case AM_ABS_X: /* $7D */ 85 case AM_ZP_Y:
86 val = peek((arg + regs.y) % 256);
87 break;
88 case AM_ABS:
89 val = peek16(arg);
90 break;
91 case AM_ABS_X:
90 val = peek16(arg + regs.x); 92 val = peek16(arg + regs.x);
91 break; 93 break;
92 case AM_ABS_Y: /* $79 */ 94 case AM_ABS_Y:
93 val = peek16(arg + regs.y); 95 val = peek16(arg + regs.y);
94 break; 96 break;
95 case AM_IND_X: /* $61 */ 97 case AM_IND_X:
96 val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256); 98 val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
97 break; 99 break;
98 case AM_IND_Y: /* $71 */ 100 case AM_IND_Y:
99 val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y); 101 val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y);
100 break; 102 break;
101 default: 103 default:
102 fprintf(stderr, "INVALID ADC ADDRESSING MODE\n"); 104 fprintf(stderr, "INVALID ADDRESSING MODE\n");
103 abort(); 105 abort();
104 return;
105 } 106 }
106 107
107 sum = regs.a + val + regs.status.carry; 108 return val;
109}
110
111void
112adc(uint8_t arg)
113{
114 uint16_t sum; // 16-bit sum makes it easier to determine carry flag
115
116 sum = regs.a + arg + regs.status.carry;
108 regs.a = sum & 0xFF; 117 regs.a = sum & 0xFF;
109 118
110 regs.status.carry = sum > 0xFF; 119 regs.status.carry = sum > 0xFF;
@@ -144,48 +153,10 @@ inx(void)
144} 153}
145 154
146void 155void
147lda(enum addressing_mode mode) 156lda(uint8_t arg)
148{ 157{
149 uint8_t arg, val;
150
151 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y)
152 arg = peek(regs.pc++);
153 else
154 arg = peek16(regs.pc++);
155
156 switch (mode) {
157 case AM_IMM: /* $A9 */
158 val = arg;
159 break;
160 case AM_ZP: /* $A5 */
161 val = peek(arg % 256);
162 break;
163 case AM_ABS: /* $AD */
164 val = peek16(arg);
165 break;
166 case AM_ZP_X: /* $B5 */
167 val = peek((arg + regs.x) % 256);
168 break;
169 case AM_ABS_X: /* $BD */
170 val = peek16(arg + regs.x);
171 break;
172 case AM_ABS_Y: /* $B9 */
173 val = peek16(arg + regs.y);
174 break;
175 case AM_IND_X: /* $A1 */
176 val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
177 break;
178 case AM_IND_Y: /* $B1 */
179 val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y);
180 break;
181 default:
182 fprintf(stderr, "INVALID LDA ADDRESSING MODE\n");
183 abort();
184 return;
185 }
186
187 printf("arg1 $%02X\n", arg); 158 printf("arg1 $%02X\n", arg);
188 regs.a = val; 159 regs.a = arg;
189 160
190 STATUS_UPDATE_ZERO(regs.a); 161 STATUS_UPDATE_ZERO(regs.a);
191 STATUS_UPDATE_NEGATIVE(regs.a); 162 STATUS_UPDATE_NEGATIVE(regs.a);
@@ -206,55 +177,55 @@ interpret(void)
206 brk(); 177 brk();
207 return; 178 return;
208 case 0x61: 179 case 0x61:
209 adc(AM_IND_X); 180 adc(opmode_arg(AM_IND_X));
210 break; 181 break;
211 case 0x65: 182 case 0x65:
212 adc(AM_ZP); 183 adc(opmode_arg(AM_ZP));
213 break; 184 break;
214 case 0x69: 185 case 0x69:
215 adc(AM_IMM); 186 adc(opmode_arg(AM_IMM));
216 break; 187 break;
217 case 0x6D: 188 case 0x6D:
218 adc(AM_ABS); 189 adc(opmode_arg(AM_ABS));
219 break; 190 break;
220 case 0x71: 191 case 0x71:
221 adc(AM_IND_Y); 192 adc(opmode_arg(AM_IND_Y));
222 break; 193 break;
223 case 0x75: 194 case 0x75:
224 adc(AM_ZP_X); 195 adc(opmode_arg(AM_ZP_X));
225 break; 196 break;
226 case 0x79: 197 case 0x79:
227 adc(AM_ABS_Y); 198 adc(opmode_arg(AM_ABS_Y));
228 break; 199 break;
229 case 0x7D: 200 case 0x7D:
230 adc(AM_ABS_X); 201 adc(opmode_arg(AM_ABS_X));
231 break; 202 break;
232 case 0xa1: 203 case 0xa1:
233 lda(AM_IND_X); 204 lda(opmode_arg(AM_IND_X));
234 break; 205 break;
235 case 0xa5: 206 case 0xa5:
236 lda(AM_ZP); 207 lda(opmode_arg(AM_ZP));
237 break; 208 break;
238 case 0xa9: 209 case 0xa9:
239 lda(AM_IMM); 210 lda(opmode_arg(AM_IMM));
240 break; 211 break;
241 case 0xaa: 212 case 0xaa:
242 tax(); 213 tax();
243 break; 214 break;
244 case 0xad: 215 case 0xad:
245 lda(AM_ABS); 216 lda(opmode_arg(AM_ABS));
246 break; 217 break;
247 case 0xb1: 218 case 0xb1:
248 lda(AM_IND_Y); 219 lda(opmode_arg(AM_IND_Y));
249 break; 220 break;
250 case 0xb5: 221 case 0xb5:
251 lda(AM_ZP_X); 222 lda(opmode_arg(AM_ZP_X));
252 break; 223 break;
253 case 0xb9: 224 case 0xb9:
254 lda(AM_ABS_Y); 225 lda(opmode_arg(AM_ABS_Y));
255 break; 226 break;
256 case 0xbd: 227 case 0xbd:
257 lda(AM_ABS_X); 228 lda(opmode_arg(AM_ABS_X));
258 break; 229 break;
259 case 0xe8: 230 case 0xe8:
260 inx(); 231 inx();