This commit is contained in:
2025-07-16 14:27:59 +02:00
parent 442b775cec
commit 1b66052212

214
mos6502.c
View File

@@ -93,13 +93,6 @@ void mos6502_step(MOS6502 *m) {
m->A |= READ_U8();
mos6502_set_zn(m, m->A);
} break;
case 0x11: {
uint16_t oper = READ_U8();
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
m->A |= mos6502_mem_read(m, addr + m->Y);
mos6502_set_zn(m, m->A);
} break;
case 0x0A: {
uint8_t carry = (m->A & 0x80) != 0;
m->A <<= 1;
@@ -114,7 +107,6 @@ void mos6502_step(MOS6502 *m) {
uint16_t addr = READ_U16();
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = oper << 1;
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper & 0x80) != 0);
mos6502_set_zn(m, res);
@@ -125,9 +117,44 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0x11: {
uint16_t oper = READ_U8();
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
m->A |= mos6502_mem_read(m, addr + m->Y);
mos6502_set_zn(m, m->A);
} break;
case 0x15: {
m->A |= mos6502_mem_read(m, READ_U8() + m->X);
mos6502_set_zn(m, m->A);
} break;
case 0x16: {
uint8_t addr = READ_U8() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = oper << 1;
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper >> 7) & 1);
mos6502_set_zn(m, res);
} break;
case 0x18: {
mos6502_set_flag(m, FLAG_C, 0);
} break;
case 0x19: {
m->A |= mos6502_mem_read(m, READ_U16() + m->Y);
mos6502_set_zn(m, m->A);
} break;
case 0x1D: {
m->A |= mos6502_mem_read(m, READ_U16() + m->X);
mos6502_set_zn(m, m->A);
} break;
case 0x1E: {
uint16_t addr = READ_U16() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = oper << 1;
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper & 0x80) != 0);
mos6502_set_zn(m, res);
} break;
case 0x20: {
uint16_t target = READ_U16();
uint16_t ret_addr = m->pc - 1;
@@ -152,6 +179,14 @@ void mos6502_step(MOS6502 *m) {
m->A &= mos6502_mem_read(m, READ_U8());
mos6502_set_zn(m, m->A);
} break;
case 0x26: {
uint16_t addr = READ_U8();
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper << 1) | ((m->P & FLAG_C) ? 1 : 0);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper & 0x80) >> 7);
mos6502_set_zn(m, res);
} break;
case 0x28: {
m->P = mos6502_mem_read(m, 0x0100 + (++m->SP));
} break;
@@ -201,6 +236,14 @@ void mos6502_step(MOS6502 *m) {
m->A &= mos6502_mem_read(m, READ_U8() + m->X);
mos6502_set_zn(m, m->A);
} break;
case 0x36: {
uint16_t addr = READ_U8() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper << 1) | ((m->P & FLAG_C) ? 1 : 0);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper & 0x80) >> 7);
mos6502_set_zn(m, res);
} break;
case 0x38: {
mos6502_set_flag(m, FLAG_C, 1);
} break;
@@ -212,6 +255,14 @@ void mos6502_step(MOS6502 *m) {
m->A &= mos6502_mem_read(m, READ_U16() + m->X);
mos6502_set_zn(m, m->A);
} break;
case 0x3E: {
uint16_t addr = READ_U16() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper << 1) | ((m->P & FLAG_C) ? 1 : 0);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, (oper & 0x80) >> 7);
mos6502_set_zn(m, res);
} break;
case 0x41: {
uint16_t oper = READ_U8() + m->X;
uint16_t addr =
@@ -275,6 +326,18 @@ void mos6502_step(MOS6502 *m) {
uint16_t high = mos6502_mem_read(m, 0x0100 + (++m->SP));
m->pc = (((uint16_t)high << 8) | low) + 1;
} break;
case 0x61: {
uint8_t oper = READ_U8() + m->X;
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
uint8_t value = mos6502_mem_read(m, addr);
uint16_t res = (uint16_t)m->A + value + (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));
m->A = res;
mos6502_set_zn(m, m->A);
} break;
case 0x65: {
uint8_t oper = mos6502_mem_read(m, READ_U8());
uint16_t res = m->A + oper + (m->P & FLAG_C);
@@ -283,6 +346,14 @@ void mos6502_step(MOS6502 *m) {
mos6502_set_zn(m, res);
m->A = res;
} break;
case 0x66: {
uint16_t addr = READ_U8();
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper >> 1) | ((m->P & FLAG_C) << 7);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, oper & 0x01);
mos6502_set_zn(m, res);
} break;
case 0x68: {
m->A = mos6502_mem_read(m, 0x0100 + (++m->SP));
mos6502_set_zn(m, m->A);
@@ -329,16 +400,66 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0x71: {
uint8_t oper = READ_U8();
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
uint8_t value = mos6502_mem_read(m, addr + m->Y);
uint16_t res = (uint16_t)m->A + value + (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));
m->A = res;
mos6502_set_zn(m, m->A);
} break;
case 0x75: {
uint8_t oper = mos6502_mem_read(m, (uint8_t)(READ_U8() + m->X));
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);
mos6502_set_zn(m, res);
m->A = res;
} break;
case 0x76: {
uint8_t addr = READ_U8() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper >> 1) | ((m->P & FLAG_C) << 7);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, oper & 0x01);
mos6502_set_zn(m, res);
} break;
case 0x78: {
mos6502_set_flag(m, FLAG_I, 1);
} break;
case 0x88: {
m->Y--;
mos6502_set_zn(m, m->Y);
case 0x79: {
uint8_t oper = mos6502_mem_read(m, READ_U16() + m->Y);
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);
mos6502_set_zn(m, res);
m->A = res;
} break;
case 0x8A: {
m->A = m->X;
mos6502_set_zn(m, m->A);
case 0x7D: {
uint8_t oper = mos6502_mem_read(m, READ_U16() + m->X);
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);
mos6502_set_zn(m, res);
m->A = res;
} break;
case 0x7E: {
uint16_t addr = READ_U16() + m->X;
uint8_t oper = mos6502_mem_read(m, addr);
uint8_t res = (oper >> 1) | ((m->P & FLAG_C) << 7);
mos6502_mem_write(m, addr, res);
mos6502_set_flag(m, FLAG_C, oper & 0x01);
mos6502_set_zn(m, res);
} break;
case 0x81: {
uint8_t oper = READ_U8() + m->X;
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
mos6502_mem_write(m, addr, m->A);
} break;
case 0x84: {
mos6502_mem_write(m, READ_U8(), m->Y);
@@ -349,6 +470,14 @@ void mos6502_step(MOS6502 *m) {
case 0x86: {
mos6502_mem_write(m, READ_U8(), m->X);
} break;
case 0x88: {
m->Y--;
mos6502_set_zn(m, m->Y);
} break;
case 0x8A: {
m->A = m->X;
mos6502_set_zn(m, m->A);
} break;
case 0x8C: {
mos6502_mem_write(m, READ_U16(), m->Y);
} break;
@@ -364,6 +493,12 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0x91: {
uint8_t oper = READ_U8();
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
mos6502_mem_write(m, addr + m->Y, m->A);
} break;
case 0x94: {
mos6502_mem_write(m, READ_U8() + m->X, m->Y);
} break;
@@ -462,10 +597,17 @@ void mos6502_step(MOS6502 *m) {
m->X = mos6502_mem_read(m, READ_U8() + m->Y);
mos6502_set_zn(m, m->X);
} break;
case 0xB8: {
mos6502_set_flag(m, FLAG_V, 0);
} break;
case 0xB9: {
m->A = mos6502_mem_read(m, READ_U16() + m->Y);
mos6502_set_zn(m, m->A);
} break;
case 0xBA: {
m->Y = m->SP;
mos6502_set_zn(m, m->Y);
} break;
case 0xBC: {
m->Y = mos6502_mem_read(m, READ_U16() + m->X);
mos6502_set_zn(m, m->Y);
@@ -484,6 +626,14 @@ void mos6502_step(MOS6502 *m) {
mos6502_set_flag(m, FLAG_C, m->Y >= oper);
mos6502_set_zn(m, res);
} break;
case 0xC1: {
uint8_t oper = READ_U8() + m->X;
uint16_t addr =
mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8);
uint8_t res = mos6502_mem_read(m, addr);
mos6502_set_flag(m, FLAG_C, m->A >= res);
mos6502_set_zn(m, m->A - res);
} break;
case 0xC4: {
uint8_t oper = mos6502_mem_read(m, READ_U8());
uint16_t res = m->Y - oper;
@@ -537,6 +687,14 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0xD1: {
uint8_t oper = READ_U8();
uint16_t addr = mos6502_mem_read(m, oper) |
(mos6502_mem_read(m, (oper + 1 & 0xFF)) << 8);
uint8_t res = mos6502_mem_read(m, addr + m->Y);
mos6502_set_flag(m, FLAG_C, m->A >= res);
mos6502_set_zn(m, m->A - res);
} break;
case 0xD5: {
uint8_t oper = mos6502_mem_read(m, READ_U8() + m->X);
mos6502_set_flag(m, FLAG_C, m->A >= oper);
@@ -573,6 +731,17 @@ void mos6502_step(MOS6502 *m) {
mos6502_set_flag(m, FLAG_C, m->X >= oper);
mos6502_set_zn(m, res);
} break;
case 0xE1: {
uint8_t oper = READ_U8() + m->X;
uint16_t addr = mos6502_mem_read(m, oper) |
(mos6502_mem_read(m, (oper + 1 & 0xFF)) << 8);
oper = mos6502_mem_read(m, addr);
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 0xE4: {
uint8_t oper = mos6502_mem_read(m, READ_U8());
uint16_t res = m->X - oper;
@@ -633,6 +802,17 @@ void mos6502_step(MOS6502 *m) {
m->pc += offset;
}
} break;
case 0xF1: {
uint8_t oper = READ_U8();
uint16_t addr = mos6502_mem_read(m, oper) |
(mos6502_mem_read(m, (oper + 1 & 0xFF)) << 8);
oper = mos6502_mem_read(m, addr + m->Y);
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 0xF5: {
uint8_t oper = mos6502_mem_read(m, READ_U8() + m->X);
uint16_t res = m->A - oper - ((m->P & FLAG_C) ? 0 : 1);
@@ -641,6 +821,12 @@ void mos6502_step(MOS6502 *m) {
m->A = res;
mos6502_set_zn(m, m->A);
} break;
case 0xF6: {
uint16_t addr = READ_U8() + m->X;
uint8_t res = mos6502_mem_read(m, addr) + 1;
mos6502_mem_write(m, addr, res);
mos6502_set_zn(m, res);
} break;
case 0xF8: {
mos6502_set_flag(m, FLAG_D, 1);
} break;