summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-05-24 12:20:04 +0530
committervin <git@vineetk.net>2024-05-24 12:20:04 +0530
commit8493837ef921880196c29f0b766bebe9d2bf33ad (patch)
tree9bc00785935d12b85518a0533ec741a293758042 /cpu.c
parent24ca08a83d8b420d337d29c87d672b624890b5bf (diff)
implement tax and inx and print status each time
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c114
1 files changed, 97 insertions, 17 deletions
diff --git a/cpu.c b/cpu.c
index 0843189..14c2ce3 100644
--- a/cpu.c
+++ b/cpu.c
@@ -1,4 +1,10 @@
1#include <stdint.h> 1#include <stdint.h>
2#include <stdio.h>
3
4#define STATUS_UPDATE_ZERO(r) \
5 (regs.status.zero = r == 0)
6#define STATUS_UPDATE_NEGATIVE(r) \
7 (regs.status.negative = ((r & (1 << 7)) > 0))
2 8
3struct cpu_flags { 9struct cpu_flags {
4 uint8_t carry : 1; 10 uint8_t carry : 1;
@@ -12,7 +18,7 @@ struct cpu_flags {
12}; 18};
13 19
14struct registers { 20struct registers {
15 uint8_t acc, x, y, sp; 21 uint8_t a, x, y, sp;
16 struct cpu_flags status; 22 struct cpu_flags status;
17 uint16_t pc; 23 uint16_t pc;
18}; 24};
@@ -40,28 +46,64 @@ uint8_t addrbus[0x10000];
40/* example program taken from https://bugzmanov.github.io/nes_ebook/chapter_3_1.html */ 46/* example program taken from https://bugzmanov.github.io/nes_ebook/chapter_3_1.html */
41uint8_t program[] = { 0xa9, 0xc0, 0xaa, 0xe8, 0x00 }; 47uint8_t program[] = { 0xa9, 0xc0, 0xaa, 0xe8, 0x00 };
42 48
43void brk(void) 49void
50brk(void)
44{ 51{
52 /* $00 */
45 /* TODO: push regs.pc and regs.status to stack and load IRQ vector */ 53 /* TODO: push regs.pc and regs.status to stack and load IRQ vector */
46 regs.status.brk = 1; 54 regs.status.brk = 1;
47 return; 55 return;
48} 56}
49 57
50void lda(enum addressing_mode mode) 58void
59tax(void)
60{
61 /* $AA */
62 regs.x = regs.a;
63
64 STATUS_UPDATE_ZERO(regs.x);
65 STATUS_UPDATE_NEGATIVE(regs.x);
66}
67
68void
69inx(void)
70{
71 /* $E8 */
72 regs.x++;
73
74 STATUS_UPDATE_ZERO(regs.x);
75 STATUS_UPDATE_NEGATIVE(regs.x);
76}
77
78void
79lda(enum addressing_mode mode)
51{ 80{
52 uint8_t val; 81 uint8_t val;
53 82
54 switch (mode) { 83 switch (mode) {
55 case AM_IMMEDIATE: /* $A9 */ 84 case AM_IMMEDIATE: /* $A9 */
56 val = program[regs.pc++]; 85 val = program[regs.pc++];
57 regs.acc = val; 86 printf("arg1 $%02X\n", val);
87 regs.a = val;
58 break; 88 break;
59 case AM_ZERO_PAGE: /* $A5 */ 89 case AM_ZERO_PAGE: /* $A5 */
90 /* TODO */
91 break;
60 case AM_ZERO_PAGE_X: /* $B5 */ 92 case AM_ZERO_PAGE_X: /* $B5 */
93 /* TODO */
94 break;
61 case AM_ABSOLUTE: /* $AD */ 95 case AM_ABSOLUTE: /* $AD */
96 /* TODO */
97 break;
62 case AM_ABSOLUTE_X: /* $BD */ 98 case AM_ABSOLUTE_X: /* $BD */
99 /* TODO */
100 break;
63 case AM_ABSOLUTE_Y: /* $B9 */ 101 case AM_ABSOLUTE_Y: /* $B9 */
102 /* TODO */
103 break;
64 case AM_INDIRECT_X: /* $A1 */ 104 case AM_INDIRECT_X: /* $A1 */
105 /* TODO */
106 break;
65 case AM_INDIRECT_Y: /* $B1 */ 107 case AM_INDIRECT_Y: /* $B1 */
66 /* TODO */ 108 /* TODO */
67 break; 109 break;
@@ -69,48 +111,86 @@ void lda(enum addressing_mode mode)
69 return; 111 return;
70 } 112 }
71 113
72 regs.status.zero = regs.acc == 0; 114 STATUS_UPDATE_ZERO(regs.a);
73 regs.status.negative = (regs.acc & (1 << 7)) != 0; 115 STATUS_UPDATE_NEGATIVE(regs.a);
74} 116}
75 117
76void interpret(void) 118void
119interpret(void)
77{ 120{
78 uint8_t opcode; 121 uint8_t opcode;
79 regs.pc = 0; 122 regs.pc = 0;
123 regs.status.unused = 1;
124
125 printf("Initial State:\n");
126 printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry,
127 regs.status.zero, regs.status.interrupt_disable,
128 regs.status.decimal_mode, regs.status.brk,
129 regs.status.unused, regs.status.overflow,
130 regs.status.negative);
131 printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%02X\n",
132 regs.a, regs.x, regs.y, regs.sp, regs.pc);
133
134 putchar('\n');
80 135
81 for (;;) { 136 for (;;) {
82 opcode = program[regs.pc++]; 137 opcode = program[regs.pc++];
83 138
139 printf("opcode: $%02X\n", opcode);
140
84 switch (opcode) { 141 switch (opcode) {
85 case 0x00: 142 case 0x00:
86 brk(); 143 brk();
87 return; 144 return;
88 case 0xa9: 145 case 0xa1:
89 lda(AM_IMMEDIATE); 146 lda(AM_INDIRECT_X);
90 break; 147 break;
91 case 0xa5: 148 case 0xa5:
92 lda(AM_ZERO_PAGE); 149 lda(AM_ZERO_PAGE);
93 break; 150 break;
94 case 0xb5: 151 case 0xa9:
95 lda(AM_ZERO_PAGE_X); 152 lda(AM_IMMEDIATE);
153 break;
154 case 0xaa:
155 tax();
96 break; 156 break;
97 case 0xad: 157 case 0xad:
98 lda(AM_ABSOLUTE); 158 lda(AM_ABSOLUTE);
99 break; 159 break;
100 case 0xbd: 160 case 0xb1:
101 lda(AM_ABSOLUTE_X); 161 lda(AM_INDIRECT_Y);
162 break;
163 case 0xb5:
164 lda(AM_ZERO_PAGE_X);
102 break; 165 break;
103 case 0xb9: 166 case 0xb9:
104 lda(AM_ABSOLUTE_Y); 167 lda(AM_ABSOLUTE_Y);
105 break; 168 break;
106 case 0xa1: 169 case 0xbd:
107 lda(AM_INDIRECT_X); 170 lda(AM_ABSOLUTE_X);
108 break; 171 break;
109 case 0xb1: 172 case 0xe8:
110 lda(AM_INDIRECT_Y); 173 inx();
111 break; 174 break;
112 default: 175 default:
176 printf("opcode $%02X not implemented\n", opcode);
113 break; 177 break;
114 } 178 }
179
180 printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry,
181 regs.status.zero, regs.status.interrupt_disable,
182 regs.status.decimal_mode, regs.status.brk,
183 regs.status.unused, regs.status.overflow,
184 regs.status.negative);
185 printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%02X\n",
186 regs.a, regs.x, regs.y, regs.sp, regs.pc);
115 } 187 }
116} 188}
189
190int
191main(void)
192{
193 interpret();
194
195 return 0;
196}