diff --git a/mos6502.c b/mos6502.c index 50839a3..699510e 100644 --- a/mos6502.c +++ b/mos6502.c @@ -1,5 +1,4 @@ // https://www.masswerk.at/6502/6502_instruction_set.html -// https://tutorial-6502.sourceforge.io/specification/opcodes/ #include #include #include @@ -52,7 +51,8 @@ uint8_t mos6502_mem_read(MOS6502 *m, uint16_t addr) { return m->memory[addr]; } void mos6502_mem_write(MOS6502 *m, uint16_t addr, uint8_t v) { m->memory[addr] = v; if (addr == 0x0400) { - putchar(m->memory[addr]); + printf("%c", m->memory[addr]); + fflush(stdout); } } @@ -125,6 +125,14 @@ 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 0x65: { + uint8_t oper = mos6502_mem_read(m, 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); + mos6502_set_zn(m, res); + m->A = res; + } break; case 0x68: { m->A = mos6502_mem_read(m, 0x0100 + (++m->SP)); mos6502_set_zn(m, m->A); @@ -134,8 +142,8 @@ void mos6502_step(MOS6502 *m) { 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; - mos6502_set_zn(m, m->A); } break; case 0x6A: { uint8_t old_carry = m->P & FLAG_C; @@ -144,13 +152,40 @@ void mos6502_step(MOS6502 *m) { mos6502_set_flag(m, FLAG_C, new_carry); mos6502_set_zn(m, m->A); } break; + case 0x6C: { + uint16_t oper = READ_U16(); + uint16_t addr = + mos6502_mem_read(m, oper) | (mos6502_mem_read(m, oper + 1) << 8); + m->pc = addr; + } break; + case 0x6D: { + uint8_t oper = mos6502_mem_read(m, READ_U16()); + 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 0x78: { + mos6502_set_flag(m, FLAG_I, 1); + } 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 0x85: { + mos6502_mem_write(m, READ_U8(), m->A); + } break; case 0x8D: { mos6502_mem_write(m, READ_U16(), m->A); } break; + case 0x8E: { + mos6502_mem_write(m, READ_U16(), m->X); + } break; case 0x90: { int8_t offset = READ_U8(); if (!(m->P & FLAG_C)) { @@ -164,6 +199,9 @@ void mos6502_step(MOS6502 *m) { case 0x99: { mos6502_mem_write(m, READ_U16() + m->Y, m->A); } break; + case 0x9A: { + m->SP = m->X; + } break; case 0x9D: { mos6502_mem_write(m, READ_U16() + m->X, m->A); } break; @@ -171,14 +209,29 @@ void mos6502_step(MOS6502 *m) { m->Y = READ_U8(); mos6502_set_zn(m, m->Y); } break; + case 0xA1: { + uint8_t oper = READ_U8() + m->X; + uint16_t addr = mos6502_mem_read(m, oper) | + (mos6502_mem_read(m, (oper + 1 & 0xFF)) << 8); + m->A = mos6502_mem_read(m, addr); + mos6502_set_zn(m, m->A); + } break; case 0xA2: { m->X = READ_U8(); mos6502_set_zn(m, m->X); } break; - case 0xA8: { - m->X = m->A; + case 0xA5: { + m->A = mos6502_mem_read(m, READ_U8()); + mos6502_set_zn(m, m->A); + } break; + case 0xA6: { + m->X = mos6502_mem_read(m, READ_U8()); mos6502_set_zn(m, m->X); } break; + case 0xA8: { + m->Y = m->A; + mos6502_set_zn(m, m->Y); + } break; case 0xA9: { m->A = READ_U8(); mos6502_set_zn(m, m->A); @@ -191,12 +244,23 @@ void mos6502_step(MOS6502 *m) { m->A = mos6502_mem_read(m, READ_U16()); mos6502_set_zn(m, m->A); } break; + case 0xAE: { + m->X = mos6502_mem_read(m, READ_U16()); + mos6502_set_zn(m, m->X); + } break; case 0xB0: { int8_t offset = READ_U8(); if (m->P & FLAG_C) { m->pc += offset; } } break; + case 0xB1: { + uint8_t oper = READ_U8(); + uint16_t addr = mos6502_mem_read(m, oper) | + (mos6502_mem_read(m, (oper + 1 & 0xFF)) << 8); + m->A = mos6502_mem_read(m, addr + m->Y); + mos6502_set_zn(m, m->A); + } break; case 0xB9: { m->A = mos6502_mem_read(m, READ_U16() + m->Y); mos6502_set_zn(m, m->A); @@ -205,6 +269,18 @@ void mos6502_step(MOS6502 *m) { m->A = mos6502_mem_read(m, READ_U16() + m->X); mos6502_set_zn(m, m->A); } break; + case 0xC0: { + uint8_t oper = READ_U8(); + uint16_t res = m->Y - oper; + mos6502_set_flag(m, FLAG_C, m->Y >= oper); + mos6502_set_zn(m, res); + } break; + case 0xC6: { + uint16_t addr = READ_U8(); + uint8_t res = mos6502_mem_read(m, addr) - 1; + mos6502_mem_write(m, addr, res); + mos6502_set_zn(m, res); + } break; case 0xC8: { m->Y++; mos6502_set_zn(m, m->Y); @@ -230,6 +306,9 @@ void mos6502_step(MOS6502 *m) { m->pc += offset; } } break; + case 0xD8: { + mos6502_set_flag(m, FLAG_D, 0); + } break; case 0xE0: { uint8_t oper = READ_U8(); uint16_t res = m->X - oper; @@ -242,6 +321,12 @@ void mos6502_step(MOS6502 *m) { mos6502_mem_write(m, addr, res); mos6502_set_zn(m, res); } break; + case 0xE6: { + uint16_t addr = READ_U8(); + uint8_t res = mos6502_mem_read(m, addr) + 1; + mos6502_mem_write(m, addr, res); + mos6502_set_zn(m, res); + } break; case 0xE8: { m->X++; mos6502_set_zn(m, m->X); @@ -493,13 +578,13 @@ void mos6502_disassemble_ins(MOS6502 *m) { printf("STA ($%02X,X)", READ_U8()); } break; case 0x84: { - printf("STY $%02X", READ_U8()); + printf("STY $%02X\t", READ_U8()); } break; case 0x85: { - printf("STA $%02X", READ_U8()); + printf("STA $%02X\t", READ_U8()); } break; case 0x86: { - printf("STX $%02X", READ_U8()); + printf("STX $%02X\t", READ_U8()); } break; case 0x88: { printf("DEY\t"); @@ -769,4 +854,6 @@ int main(int argc, char *argv[]) { mos6502_step(&m); } } + + mos6502_free(m); }