move addressing mode parsing into separate function

This commit is contained in:
Vineet K 2024-06-08 22:08:51 +05:30
parent 1ac30a026b
commit 72e29b3d25

117
cpu.c
View File

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