move addressing mode parsing into separate function
This commit is contained in:
parent
1ac30a026b
commit
72e29b3d25
117
cpu.c
117
cpu.c
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user