summaryrefslogtreecommitdiff
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
parent1ac30a026b7877ca6b295c661d91b20eaddb01c9 (diff)
move addressing mode parsing into separate function
-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)
return (uint16_t)memory[addr] | ((uint16_t)memory[addr + 1] << 8);
}
-void
-adc(enum addressing_mode mode)
+uint8_t
+opmode_arg(enum addressing_mode mode)
{
uint8_t arg, val;
- uint16_t sum; // 16-bit sum makes it easier to determine carry flag
if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y)
arg = peek(regs.pc++);
else
- arg = peek16(regs.pc++);
+ arg = peek16(regs.pc), regs.pc += 2;
switch (mode) {
- case AM_IMM: /* $69 */
+ case AM_IMM:
val = arg;
break;
- case AM_ZP: /* $65 */
+ case AM_ZP:
val = peek(arg % 256);
break;
- case AM_ABS: /* $6D */
- val = peek16(arg);
- break;
- case AM_ZP_X: /* $75 */
+ case AM_ZP_X:
val = peek((arg + regs.x) % 256);
break;
- case AM_ABS_X: /* $7D */
+ case AM_ZP_Y:
+ val = peek((arg + regs.y) % 256);
+ break;
+ case AM_ABS:
+ val = peek16(arg);
+ break;
+ case AM_ABS_X:
val = peek16(arg + regs.x);
break;
- case AM_ABS_Y: /* $79 */
+ case AM_ABS_Y:
val = peek16(arg + regs.y);
break;
- case AM_IND_X: /* $61 */
+ case AM_IND_X:
val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
break;
- case AM_IND_Y: /* $71 */
+ case AM_IND_Y:
val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y);
break;
default:
- fprintf(stderr, "INVALID ADC ADDRESSING MODE\n");
+ fprintf(stderr, "INVALID ADDRESSING MODE\n");
abort();
- return;
}
- sum = regs.a + val + regs.status.carry;
+ return val;
+}
+
+void
+adc(uint8_t arg)
+{
+ uint16_t sum; // 16-bit sum makes it easier to determine carry flag
+
+ sum = regs.a + arg + regs.status.carry;
regs.a = sum & 0xFF;
regs.status.carry = sum > 0xFF;
@@ -144,48 +153,10 @@ inx(void)
}
void
-lda(enum addressing_mode mode)
+lda(uint8_t arg)
{
- uint8_t arg, val;
-
- if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y)
- arg = peek(regs.pc++);
- else
- arg = peek16(regs.pc++);
-
- switch (mode) {
- case AM_IMM: /* $A9 */
- val = arg;
- break;
- case AM_ZP: /* $A5 */
- val = peek(arg % 256);
- break;
- case AM_ABS: /* $AD */
- val = peek16(arg);
- break;
- case AM_ZP_X: /* $B5 */
- val = peek((arg + regs.x) % 256);
- break;
- case AM_ABS_X: /* $BD */
- val = peek16(arg + regs.x);
- break;
- case AM_ABS_Y: /* $B9 */
- val = peek16(arg + regs.y);
- break;
- case AM_IND_X: /* $A1 */
- val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
- break;
- case AM_IND_Y: /* $B1 */
- val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y);
- break;
- default:
- fprintf(stderr, "INVALID LDA ADDRESSING MODE\n");
- abort();
- return;
- }
-
printf("arg1 $%02X\n", arg);
- regs.a = val;
+ regs.a = arg;
STATUS_UPDATE_ZERO(regs.a);
STATUS_UPDATE_NEGATIVE(regs.a);
@@ -206,55 +177,55 @@ interpret(void)
brk();
return;
case 0x61:
- adc(AM_IND_X);
+ adc(opmode_arg(AM_IND_X));
break;
case 0x65:
- adc(AM_ZP);
+ adc(opmode_arg(AM_ZP));
break;
case 0x69:
- adc(AM_IMM);
+ adc(opmode_arg(AM_IMM));
break;
case 0x6D:
- adc(AM_ABS);
+ adc(opmode_arg(AM_ABS));
break;
case 0x71:
- adc(AM_IND_Y);
+ adc(opmode_arg(AM_IND_Y));
break;
case 0x75:
- adc(AM_ZP_X);
+ adc(opmode_arg(AM_ZP_X));
break;
case 0x79:
- adc(AM_ABS_Y);
+ adc(opmode_arg(AM_ABS_Y));
break;
case 0x7D:
- adc(AM_ABS_X);
+ adc(opmode_arg(AM_ABS_X));
break;
case 0xa1:
- lda(AM_IND_X);
+ lda(opmode_arg(AM_IND_X));
break;
case 0xa5:
- lda(AM_ZP);
+ lda(opmode_arg(AM_ZP));
break;
case 0xa9:
- lda(AM_IMM);
+ lda(opmode_arg(AM_IMM));
break;
case 0xaa:
tax();
break;
case 0xad:
- lda(AM_ABS);
+ lda(opmode_arg(AM_ABS));
break;
case 0xb1:
- lda(AM_IND_Y);
+ lda(opmode_arg(AM_IND_Y));
break;
case 0xb5:
- lda(AM_ZP_X);
+ lda(opmode_arg(AM_ZP_X));
break;
case 0xb9:
- lda(AM_ABS_Y);
+ lda(opmode_arg(AM_ABS_Y));
break;
case 0xbd:
- lda(AM_ABS_X);
+ lda(opmode_arg(AM_ABS_X));
break;
case 0xe8:
inx();