summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-06-10 22:56:06 +0530
committervin <git@vineetk.net>2024-06-10 23:27:11 +0530
commit3412a03a5ec20e1d3fb5dbd38888cf0c0eae09fc (patch)
tree4b2a01e16a25a1887d4a4c64039e25c975c4e38a /cpu.c
parentdbb952a52b1b7168b4d1e98e9819d632ad16e087 (diff)
implement untested most of stack-related opcodes
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c123
1 files changed, 57 insertions, 66 deletions
diff --git a/cpu.c b/cpu.c
index 5bd114e..e63760c 100644
--- a/cpu.c
+++ b/cpu.c
@@ -10,6 +10,11 @@
#define STATUS_UPDATE_NEGATIVE(r) \
(regs.status.negative = ((r & (1 << 7)) > 0))
+#define PUSH(b) \
+ (memwrite(0x0100 + regs.sp--, b))
+#define PULL() \
+ (peek(0x0100 + regs.sp++))
+
struct cpu_flags {
uint8_t carry : 1;
uint8_t zero : 1;
@@ -467,51 +472,48 @@ ora(uint8_t arg)
}
static void
-pha(uint8_t arg)
+pha(void)
{
-/* TODO: complete this */
+ PUSH(regs.a);
}
static void
-php(uint8_t arg)
+php(void)
{
-/* TODO: complete this */
-}
+ uint8_t status;
-static void
-phx(uint8_t arg)
-{
-/* TODO: complete this */
-}
+ status = (regs.status.carry << 7) | (regs.status.zero << 6)
+ | (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4)
+ | (regs.status.brk << 3) | (regs.status.unused << 2)
+ | (regs.status.overflow << 1) | regs.status.negative;
-static void
-phy(uint8_t arg)
-{
-/* TODO: complete this */
+ PUSH(status);
}
static void
-pla(uint8_t arg)
+pla(void)
{
-/* TODO: complete this */
-}
+ regs.a = PULL();
-static void
-plp(uint8_t arg)
-{
-/* TODO: complete this */
+ STATUS_UPDATE_ZERO(regs.a);
+ STATUS_UPDATE_NEGATIVE(regs.a);
}
static void
-plx(uint8_t arg)
+plp(void)
{
-/* TODO: complete this */
-}
+ uint8_t status;
-static void
-ply(uint8_t arg)
-{
-/* TODO: complete this */
+ status = PULL();
+
+ regs.status.carry = (status & (1 << 7)) > 0;
+ regs.status.zero = (status & (1 << 6)) > 0;
+ regs.status.interrupt_disable = (status & (1 << 5)) > 0;
+ regs.status.decimal_mode = (status & (1 << 4)) > 0;
+ regs.status.brk = (status & (1 << 3)) > 0;
+ regs.status.unused = (status & (1 << 2)) > 0;
+ regs.status.overflow = (status & (1 << 1)) > 0;
+ regs.status.negative = (status & 1) > 0;
}
static void
@@ -562,19 +564,19 @@ sbc(uint8_t arg)
}
static void
-sec(uint8_t arg)
+sec(void)
{
regs.status.carry = 1;
}
static void
-sed(uint8_t arg)
+sed(void)
{
regs.status.decimal_mode = 1;
}
static void
-sei(uint8_t arg)
+sei(void)
{
regs.status.interrupt_disable = 1;
}
@@ -607,7 +609,7 @@ tax(void)
}
static void
-tay(uint8_t arg)
+tay(void)
{
regs.y = regs.a;
@@ -616,13 +618,16 @@ tay(uint8_t arg)
}
static void
-tsx(uint8_t arg)
+tsx(void)
{
-/* TODO: complete this */
+ regs.x = PULL();
+
+ STATUS_UPDATE_ZERO(regs.x);
+ STATUS_UPDATE_NEGATIVE(regs.x);
}
static void
-txa(uint8_t arg)
+txa(void)
{
regs.a = regs.x;
@@ -631,13 +636,13 @@ txa(uint8_t arg)
}
static void
-txs(uint8_t arg)
+txs(void)
{
-/* TODO: complete this */
+ PUSH(regs.x);
}
static void
-tya(uint8_t arg)
+tya(void)
{
regs.a = regs.y;
@@ -1121,35 +1126,19 @@ interpret(void)
cycles += 5;
break;
case 0x48:
- pha(opcode_arg(AM_ACC));
+ pha();
cycles += 3;
break;
case 0x08:
- php(opcode_arg(AM_ACC));
- cycles += 3;
- break;
- case 0xda:
- phx(opcode_arg(AM_ACC));
- cycles += 3;
- break;
- case 0x5a:
- phy(opcode_arg(AM_ACC));
+ php();
cycles += 3;
break;
case 0x68:
- pla(opcode_arg(AM_ACC));
+ pla();
cycles += 4;
break;
case 0x28:
- plp(opcode_arg(AM_ACC));
- cycles += 4;
- break;
- case 0xfa:
- plx(opcode_arg(AM_ACC));
- cycles += 4;
- break;
- case 0x7a:
- ply(opcode_arg(AM_ACC));
+ plp();
cycles += 4;
break;
case 0x2a:
@@ -1237,15 +1226,15 @@ interpret(void)
cycles += 5;
break;
case 0x38:
- sec(opcode_arg(AM_ACC));
+ sec();
cycles += 2;
break;
case 0xf8:
- sed(opcode_arg(AM_ACC));
+ sed();
cycles += 2;
break;
case 0x78:
- sei(opcode_arg(AM_ACC));
+ sei();
cycles += 2;
break;
case 0x85:
@@ -1309,23 +1298,23 @@ interpret(void)
cycles += 2;
break;
case 0xa8:
- tay(opcode_arg(AM_ACC));
+ tay();
cycles += 2;
break;
case 0xba:
- tsx(opcode_arg(AM_ACC));
+ tsx();
cycles += 2;
break;
case 0x8a:
- txa(opcode_arg(AM_ACC));
+ txa();
cycles += 2;
break;
case 0x9a:
- txs(opcode_arg(AM_ACC));
+ txs();
cycles += 2;
break;
case 0x98:
- tya(opcode_arg(AM_ACC));
+ tya();
cycles += 2;
break;
default:
@@ -1353,6 +1342,8 @@ cpu_init(void)
memset(&regs.status, 0, sizeof(regs.status));
regs.status.unused = 1;
+
+ cycles += 7;
}
int