summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c70
1 files changed, 55 insertions, 15 deletions
diff --git a/cpu.c b/cpu.c
index 076e887..65e60d4 100644
--- a/cpu.c
+++ b/cpu.c
@@ -67,7 +67,7 @@ peek16(uint16_t addr)
67static void 67static void
68memwrite(uint16_t addr, uint8_t byte) 68memwrite(uint16_t addr, uint8_t byte)
69{ 69{
70 memory[addr] = b; 70 memory[addr] = byte;
71} 71}
72 72
73static void 73static void
@@ -125,6 +125,50 @@ opcode_arg(enum addressing_mode mode)
125 return val; 125 return val;
126} 126}
127 127
128static uint16_t
129opcode_mem(enum addressing_mode mode)
130{
131 uint8_t arg;
132 uint16_t val;
133
134 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y)
135 arg = peek(regs.pc++);
136 else
137 arg = peek16(regs.pc), regs.pc += 2;
138
139 switch (mode) {
140 case AM_ZP:
141 val = arg % 256;
142 break;
143 case AM_ZP_X:
144 val = (arg + regs.x) % 256;
145 break;
146 case AM_ZP_Y:
147 val = (arg + regs.y) % 256;
148 break;
149 case AM_ABS:
150 val = arg;
151 break;
152 case AM_ABS_X:
153 val = arg + regs.x;
154 break;
155 case AM_ABS_Y:
156 val = arg + regs.y;
157 break;
158 case AM_IND_X:
159 val = peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256;
160 break;
161 case AM_IND_Y:
162 val = peek(arg) + peek((arg + 1) % 256) * 256 + regs.y;
163 break;
164 default:
165 fprintf(stderr, "INVALID ADDRESSING MODE\n");
166 abort();
167 }
168
169 return val;
170}
171
128static void 172static void
129adc(uint8_t arg) 173adc(uint8_t arg)
130{ 174{
@@ -313,9 +357,9 @@ cpy(uint8_t arg)
313} 357}
314 358
315static void 359static void
316dec(uint8_t arg) 360dec(uint16_t mem)
317{ 361{
318/* TODO: complete this */ 362 memwrite(mem, peek(mem) - 1);
319} 363}
320 364
321static void 365static void
@@ -839,19 +883,19 @@ interpret(void)
839 cycles += 2; 883 cycles += 2;
840 break; 884 break;
841 case 0x18: 885 case 0x18:
842 clc(opcode_arg(AM_ACC)); 886 clc();
843 cycles += 2; 887 cycles += 2;
844 break; 888 break;
845 case 0xd8: 889 case 0xd8:
846 cld(opcode_arg(AM_ACC)); 890 cld();
847 cycles += 2; 891 cycles += 2;
848 break; 892 break;
849 case 0x58: 893 case 0x58:
850 cli(opcode_arg(AM_ACC)); 894 cli();
851 cycles += 2; 895 cycles += 2;
852 break; 896 break;
853 case 0xb8: 897 case 0xb8:
854 clv(opcode_arg(AM_ACC)); 898 clv();
855 cycles += 2; 899 cycles += 2;
856 break; 900 break;
857 case 0xc9: 901 case 0xc9:
@@ -914,24 +958,20 @@ interpret(void)
914 cpy(opcode_arg(AM_ABS)); 958 cpy(opcode_arg(AM_ABS));
915 cycles += 4; 959 cycles += 4;
916 break; 960 break;
917 case 0x3a:
918 dec(opcode_arg(AM_ACC));
919 cycles += 2;
920 break;
921 case 0xc6: 961 case 0xc6:
922 dec(opcode_arg(AM_ZP)); 962 dec(opcode_mem(AM_ZP));
923 cycles += 5; 963 cycles += 5;
924 break; 964 break;
925 case 0xd6: 965 case 0xd6:
926 dec(opcode_arg(AM_ZP_X)); 966 dec(opcode_mem(AM_ZP_X));
927 cycles += 6; 967 cycles += 6;
928 break; 968 break;
929 case 0xce: 969 case 0xce:
930 dec(opcode_arg(AM_ABS)); 970 dec(opcode_mem(AM_ABS));
931 cycles += 6; 971 cycles += 6;
932 break; 972 break;
933 case 0xde: 973 case 0xde:
934 dec(opcode_arg(AM_ABS_X)); 974 dec(opcode_mem(AM_ABS_X));
935 cycles += 7; 975 cycles += 7;
936 break; 976 break;
937 case 0xca: 977 case 0xca: