6502 hello world

This commit is contained in:
2025-07-14 13:36:40 +02:00
parent 2f2d9cf8ee
commit 1f4815ce8c

View File

@@ -7,15 +7,21 @@
#define READ_U8() m->memory[m->pc++]
#define READ_U16() (READ_U8() | (READ_U8() << 8))
#define FLAG_N 0x80
#define FLAG_V 0x40
#define FLAG_D 0x04
#define FLAG_I 0x04
#define FLAG_Z 0x02
#define FLAG_C 0x01
typedef struct MOS6502 {
uint8_t *memory;
uint16_t pc;
// TODO
// uint8_t A;
// uint8_t X;
// uint8_t Y;
// uint8_t SP;
// uint8_t P;
uint8_t A;
uint8_t X;
uint8_t Y;
uint8_t SP;
uint8_t P;
} MOS6502;
MOS6502 mos6502_create(void) {
@@ -25,6 +31,60 @@ MOS6502 mos6502_create(void) {
return m;
}
void mos6502_set_zn(MOS6502 *m, uint8_t v) {
if (v == 0) {
m->P |= FLAG_Z;
} else {
m->P &= ~FLAG_Z;
}
if (v & 0x80) {
m->P |= FLAG_N;
} else {
m->P &= ~FLAG_N;
}
}
void mos6502_step(MOS6502 *m) {
uint8_t op = READ_U8();
switch (op) {
case 0x00: {
// TODO: its supposed to do some interrupt magic
exit(0);
} break;
case 0x4C: {
m->pc = READ_U16();
} break;
case 0x8D: {
uint16_t addr = READ_U16();
m->memory[addr] = m->A;
if (addr == 0x0400) {
putchar(m->memory[addr]);
}
} break;
case 0xA0: {
m->Y = READ_U8();
mos6502_set_zn(m, m->Y);
} break;
case 0xB9: {
m->A = m->memory[READ_U16() + m->Y];
mos6502_set_zn(m, m->A);
} break;
case 0xC8: {
m->Y++;
mos6502_set_zn(m, m->Y);
} break;
case 0xF0: {
int8_t offset = READ_U8();
if (m->P & FLAG_Z) {
m->pc += offset;
}
} break;
default:
fprintf(stderr, "unrecognized opcode: $%02X\n", op);
exit(1);
}
}
void mos6502_disassemble(MOS6502 *m, size_t program_size) {
while (m->pc < 0x600 + program_size) {
printf("%04X: ", m->pc);
@@ -517,7 +577,7 @@ int main(int argc, char *argv[]) {
m.memory[0x600 + i] = buffer[i];
}
mos6502_disassemble(&m, n);
mos6502_free(m);
while (1) {
mos6502_step(&m);
}
}