more opcodes

This commit is contained in:
2025-07-15 12:38:46 +02:00
parent 53b90af719
commit df162fd642
2 changed files with 115 additions and 37 deletions

View File

@@ -344,11 +344,11 @@ void chip8_step(CHIP8 *c) {
c->reg[x] = c->delay_timer;
break;
case 0x0A: {
bool key_pressed = false;
uint8_t key_pressed = 0;
while (!key_pressed && WindowShouldClose()) {
for (size_t i = 0; i < 16; i++) {
if (IsKeyDown(keyboard_map[i])) {
key_pressed = true;
key_pressed = 1;
break;
}
}

148
mos6502.c
View File

@@ -32,17 +32,17 @@ MOS6502 mos6502_create(void) {
return m;
}
void mos6502_set_flag(MOS6502 *m, uint8_t flag, uint8_t value) {
if (value) {
m->P |= flag;
} else {
m->P &= ~flag;
}
}
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;
}
mos6502_set_flag(m, FLAG_Z, v == 0);
mos6502_set_flag(m, FLAG_N, v & 0x80);
}
uint8_t mos6502_mem_read(MOS6502 *m, uint16_t addr) { return m->memory[addr]; }
@@ -57,33 +57,58 @@ void mos6502_mem_write(MOS6502 *m, uint16_t addr, uint8_t v) {
void mos6502_step(MOS6502 *m) {
uint8_t op = READ_U8();
// printf("$%04X: %02X A: %02X X: %02X Y: %02X\n", m->pc, op, m->A, m->X,
// m->Y);
// printf("$%04X: %02X A: %02X X: %02X Y: %02X\n", m->pc - 1, op, m->A,
// m->X, m->Y);
switch (op) {
case 0x00: {
// TODO: its supposed to do some interrupt magic
exit(0);
m->pc--;
} break;
case 0x09: {
m->A |= READ_U8();
mos6502_set_zn(m, m->A);
} break;
case 0x0A: {
uint8_t carry = (m->A & 0x80) != 0;
m->A <<= 1;
mos6502_set_flag(m, FLAG_C, carry);
mos6502_set_zn(m, m->A);
} break;
case 0x18: {
mos6502_set_flag(m, FLAG_C, 0);
} break;
case 0x20: {
uint16_t ret_addr = m->pc + 2;
uint16_t target = READ_U16();
uint16_t ret_addr = m->pc - 1;
mos6502_mem_write(m, 0x0100 + m->SP--, (ret_addr >> 8) & 0xFF);
mos6502_mem_write(m, 0x0100 + m->SP--, ret_addr & 0xFF);
m->pc = READ_U16();
m->pc = target;
} break;
case 0x29: {
m->A &= READ_U8();
mos6502_set_zn(m, m->A);
} break;
case 0x2A: {
uint8_t old_carry = m->P & FLAG_C;
uint8_t new_carry = (m->A & 0x80) >> 7;
m->A = ((m->A << 1) & 0xFE) | old_carry;
mos6502_set_flag(m, FLAG_C, new_carry);
mos6502_set_zn(m, m->A);
} break;
case 0x38: {
mos6502_set_flag(m, FLAG_C, 1);
} break;
case 0x48: {
mos6502_mem_write(m, 0x0100 + m->SP--, m->A);
} break;
case 0x49: {
m->A ^= READ_U8();
mos6502_set_zn(m, m->A);
} break;
case 0x4A: {
uint8_t c = m->A & 0x01;
mos6502_set_flag(m, FLAG_C, m->A & 0x01);
m->A >>= 1;
if (c) {
m->P |= FLAG_C;
} else {
m->P &= ~FLAG_C;
}
mos6502_set_zn(m, m->A);
} break;
case 0x4C: {
@@ -92,7 +117,30 @@ void mos6502_step(MOS6502 *m) {
case 0x60: {
uint16_t low = mos6502_mem_read(m, 0x0100 + (++m->SP));
uint16_t high = mos6502_mem_read(m, 0x0100 + (++m->SP));
m->pc = (((uint16_t)high << 8) | low);
m->pc = (((uint16_t)high << 8) | low) + 1;
} break;
case 0x68: {
m->A = mos6502_mem_read(m, 0x0100 + (++m->SP));
mos6502_set_zn(m, m->A);
} break;
case 0x69: {
uint8_t oper = READ_U8();
uint16_t res = m->A + oper + (m->P & FLAG_C);
mos6502_set_flag(m, FLAG_C, res > 0xFF);
mos6502_set_flag(m, FLAG_V, (~(m->A ^ oper) & (m->A ^ res) & 0x80) != 0);
m->A = res;
mos6502_set_zn(m, m->A);
} break;
case 0x6A: {
uint8_t old_carry = m->P & FLAG_C;
uint8_t new_carry = m->A & 0x01;
m->A = (m->A >> 1) | (old_carry << 7);
mos6502_set_flag(m, FLAG_C, new_carry);
mos6502_set_zn(m, m->A);
} break;
case 0x8A: {
m->A = m->X;
mos6502_set_zn(m, m->A);
} break;
case 0x8D: {
mos6502_mem_write(m, READ_U16(), m->A);
@@ -103,6 +151,10 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0x98: {
m->A = m->Y;
mos6502_set_zn(m, m->A);
} break;
case 0x99: {
mos6502_mem_write(m, READ_U16() + m->Y, m->A);
} break;
@@ -117,10 +169,18 @@ void mos6502_step(MOS6502 *m) {
m->X = READ_U8();
mos6502_set_zn(m, m->X);
} break;
case 0xA8: {
m->X = m->A;
mos6502_set_zn(m, m->X);
} break;
case 0xA9: {
m->A = READ_U8();
mos6502_set_zn(m, m->A);
} break;
case 0xAA: {
m->X = m->A;
mos6502_set_zn(m, m->X);
} break;
case 0xAD: {
m->A = mos6502_mem_read(m, READ_U16());
mos6502_set_zn(m, m->A);
@@ -145,13 +205,13 @@ void mos6502_step(MOS6502 *m) {
} break;
case 0xC9: {
uint8_t oper = READ_U8();
if (m->A >= oper) {
m->P |= FLAG_C;
} else {
m->P &= ~FLAG_C;
}
mos6502_set_flag(m, FLAG_C, m->A >= oper);
mos6502_set_zn(m, m->A - oper);
} break;
case 0xCA: {
m->X--;
mos6502_set_zn(m, m->X);
} break;
case 0xCE: {
uint16_t addr = READ_U16();
uint8_t res = mos6502_mem_read(m, addr) - 1;
@@ -164,6 +224,12 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0xE0: {
uint8_t oper = READ_U8();
uint16_t res = m->X - oper;
mos6502_set_flag(m, FLAG_C, m->X >= oper);
mos6502_set_zn(m, res);
} break;
case 0xEE: {
uint16_t addr = READ_U16();
uint8_t res = mos6502_mem_read(m, addr) + 1;
@@ -174,6 +240,14 @@ void mos6502_step(MOS6502 *m) {
m->X++;
mos6502_set_zn(m, m->X);
} break;
case 0xE9: {
uint8_t oper = READ_U8();
uint16_t res = m->A - oper - ((m->P & FLAG_C) ? 0 : 1);
mos6502_set_flag(m, FLAG_C, res < 0x100);
mos6502_set_flag(m, FLAG_V, (m->A ^ oper) & (m->A ^ res) & 0x80);
m->A = res;
mos6502_set_zn(m, m->A);
} break;
case 0xF0: {
int8_t offset = READ_U8();
if (m->P & FLAG_Z) {
@@ -188,7 +262,7 @@ void mos6502_step(MOS6502 *m) {
void mos6502_disassemble(MOS6502 *m, size_t program_size) {
while (m->pc < 0x600 + program_size) {
printf("%04X: ", m->pc);
printf("$%04X: ", m->pc);
uint8_t op = READ_U8();
switch (op) {
@@ -662,15 +736,15 @@ void mos6502_disassemble(MOS6502 *m, size_t program_size) {
void mos6502_free(MOS6502 m) { free(m.memory); }
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
if (argc < 3) {
fprintf(stderr, "Usage: %s <d|r> <path>\n", argv[0]);
return 1;
}
MOS6502 m = mos6502_create();
uint8_t buffer[1 << 16] = {0};
FILE *f = fopen(argv[1], "rb");
FILE *f = fopen(argv[2], "rb");
size_t n = fread(buffer, 1, 1 << 16, f);
fclose(f);
@@ -678,7 +752,11 @@ int main(int argc, char *argv[]) {
m.memory[0x600 + i] = buffer[i];
}
while (1) {
mos6502_step(&m);
if (argv[1][0] == 'd') {
mos6502_disassemble(&m, n);
} else {
while (1) {
mos6502_step(&m);
}
}
}