mirror of
https://github.com/andwati/mos-6502.git
synced 2026-10-18 03:02:51 +00:00
remove CPU, memory, emulator, and instruction implementations
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
// CPU Functions
|
||||
void cpu_init(CPU* cpu) {
|
||||
// Initialize registers
|
||||
cpu->A = 0;
|
||||
cpu->X = 0;
|
||||
cpu->Y = 0;
|
||||
cpu->SP = 0xFF; // Stack pointer starts at 0xFF
|
||||
cpu->P = FLAG_UNUSED; // Status flags initialized with unused bit set
|
||||
cpu->PC = 0; // Program counter starts at 0
|
||||
cpu->cycles = 0;
|
||||
}
|
||||
|
||||
// Status flag operations
|
||||
bool cpu_get_flag(CPU* cpu, uint8_t flag) {
|
||||
return (cpu->P & flag) != 0;
|
||||
}
|
||||
|
||||
void cpu_set_flag(CPU* cpu, uint8_t flag, bool value) {
|
||||
if (value) {
|
||||
cpu->P |= flag;
|
||||
} else {
|
||||
cpu->P &= ~flag;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// CPU Status Flags
|
||||
#define FLAG_CARRY (1 << 0)
|
||||
#define FLAG_ZERO (1 << 1)
|
||||
#define FLAG_INTERRUPT (1 << 2)
|
||||
#define FLAG_DECIMAL (1 << 3)
|
||||
#define FLAG_BREAK (1 << 4)
|
||||
#define FLAG_UNUSED (1 << 5)
|
||||
#define FLAG_OVERFLOW (1 << 6)
|
||||
#define FLAG_NEGATIVE (1 << 7)
|
||||
|
||||
typedef struct {
|
||||
uint8_t A; // Accumulator
|
||||
uint8_t X; // X Index Register
|
||||
uint8_t Y; // Y Index Register
|
||||
uint8_t SP; // Stack Pointer
|
||||
uint8_t P; // Status Register
|
||||
uint16_t PC; // Program Counter
|
||||
uint64_t cycles;
|
||||
} CPU;
|
||||
|
||||
void cpu_init(CPU* cpu);
|
||||
bool cpu_get_flag(CPU* cpu, uint8_t flag);
|
||||
void cpu_set_flag(CPU* cpu, uint8_t flag, bool value);
|
||||
|
||||
#endif // CPU_H
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
#include "instructions.h"
|
||||
|
||||
typedef struct {
|
||||
CPU cpu;
|
||||
Memory memory;
|
||||
bool running;
|
||||
} Emulator;
|
||||
|
||||
void emulator_init(Emulator* emu) {
|
||||
cpu_init(&emu->cpu);
|
||||
memory_init(&emu->memory);
|
||||
emu->running = false;
|
||||
}
|
||||
|
||||
void emulator_reset(Emulator* emu) {
|
||||
// Reset CPU
|
||||
cpu_init(&emu->cpu);
|
||||
|
||||
// Set Program Counter to the reset vector location (0xFFFC-0xFFFD)
|
||||
uint16_t reset_vector = (uint16_t)emu->memory.data[0xFFFD] << 8 | emu->memory.data[0xFFFC];
|
||||
emu->cpu.PC = reset_vector;
|
||||
|
||||
emu->running = true;
|
||||
}
|
||||
|
||||
void emulator_step(Emulator* emu) {
|
||||
if (!emu->running) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch
|
||||
uint8_t opcode = memory_read(&emu->memory, emu->cpu.PC);
|
||||
emu->cpu.PC++;
|
||||
|
||||
// Decode and Execute
|
||||
switch (opcode) {
|
||||
// LDA
|
||||
case 0xA9: // LDA Immediate
|
||||
ins_lda(&emu->cpu, &emu->memory, addr_immediate(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 2;
|
||||
break;
|
||||
case 0xA5: // LDA Zero Page
|
||||
ins_lda(&emu->cpu, &emu->memory, addr_zeropage(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 3;
|
||||
break;
|
||||
case 0xB5: // LDA Zero Page,X
|
||||
ins_lda(&emu->cpu, &emu->memory, addr_zeropage_x(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
case 0xAD: // LDA Absolute
|
||||
ins_lda(&emu->cpu, &emu->memory, addr_absolute(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
|
||||
// STA
|
||||
case 0x85: // STA Zero Page
|
||||
ins_sta(&emu->cpu, &emu->memory, addr_zeropage(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 3;
|
||||
break;
|
||||
case 0x95: // STA Zero Page,X
|
||||
ins_sta(&emu->cpu, &emu->memory, addr_zeropage_x(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
case 0x8D: // STA Absolute
|
||||
ins_sta(&emu->cpu, &emu->memory, addr_absolute(&emu->cpu, &emu->memory));
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
|
||||
// Register Transfers
|
||||
case 0xAA: // TAX
|
||||
ins_tax(&emu->cpu);
|
||||
emu->cpu.cycles += 2;
|
||||
break;
|
||||
case 0xA8: // TAY
|
||||
ins_tay(&emu->cpu);
|
||||
emu->cpu.cycles += 2;
|
||||
break;
|
||||
case 0x8A: // TXA
|
||||
ins_txa(&emu->cpu);
|
||||
emu->cpu.cycles += 2;
|
||||
break;
|
||||
case 0x98: // TYA
|
||||
ins_tya(&emu->cpu);
|
||||
emu->cpu.cycles += 2;
|
||||
break;
|
||||
|
||||
// Stack Operations
|
||||
case 0x48: // PHA
|
||||
ins_pha(&emu->cpu, &emu->memory);
|
||||
emu->cpu.cycles += 3;
|
||||
break;
|
||||
case 0x08: // PHP
|
||||
ins_php(&emu->cpu, &emu->memory);
|
||||
emu->cpu.cycles += 3;
|
||||
break;
|
||||
case 0x68: // PLA
|
||||
ins_pla(&emu->cpu, &emu->memory);
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
case 0x28: // PLP
|
||||
ins_plp(&emu->cpu, &emu->memory);
|
||||
emu->cpu.cycles += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void emulator_run(Emulator* emu) {
|
||||
emu->running = true;
|
||||
while (emu->running) {
|
||||
emulator_step(emu);
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
#include "instructions.h"
|
||||
|
||||
// Addressing Modes Implementation
|
||||
uint16_t addr_immediate(CPU* cpu, Memory* memory) {
|
||||
return cpu->PC++;
|
||||
}
|
||||
|
||||
uint16_t addr_zeropage(CPU* cpu, Memory* memory) {
|
||||
return memory_read(memory, cpu->PC++);
|
||||
}
|
||||
|
||||
uint16_t addr_zeropage_x(CPU* cpu, Memory* memory) {
|
||||
uint8_t addr = memory_read(memory, cpu->PC++);
|
||||
return (uint8_t)(addr + cpu->X);
|
||||
}
|
||||
|
||||
uint16_t addr_zeropage_y(CPU* cpu, Memory* memory) {
|
||||
uint8_t addr = memory_read(memory, cpu->PC++);
|
||||
return (uint8_t)(addr + cpu->Y);
|
||||
}
|
||||
|
||||
uint16_t addr_absolute(CPU* cpu, Memory* memory) {
|
||||
uint16_t addr_low = memory_read(memory, cpu->PC++);
|
||||
uint16_t addr_high = memory_read(memory, cpu->PC++);
|
||||
return (addr_high << 8) | addr_low;
|
||||
}
|
||||
|
||||
uint16_t addr_absolute_x(CPU* cpu, Memory* memory) {
|
||||
uint16_t base = addr_absolute(cpu, memory);
|
||||
return base + cpu->X;
|
||||
}
|
||||
|
||||
uint16_t addr_absolute_y(CPU* cpu, Memory* memory) {
|
||||
uint16_t base = addr_absolute(cpu, memory);
|
||||
return base + cpu->Y;
|
||||
}
|
||||
|
||||
uint16_t addr_indirect(CPU* cpu, Memory* memory) {
|
||||
uint16_t ptr = addr_absolute(cpu, memory);
|
||||
// Simulate the 6502 page boundary bug
|
||||
uint16_t page = ptr & 0xFF00;
|
||||
uint8_t low = memory_read(memory, ptr);
|
||||
uint8_t high = memory_read(memory, (ptr & 0xFF00) | ((ptr + 1) & 0xFF));
|
||||
return (high << 8) | low;
|
||||
}
|
||||
|
||||
uint16_t addr_indirect_x(CPU* cpu, Memory* memory) {
|
||||
uint8_t zero_addr = memory_read(memory, cpu->PC++);
|
||||
uint8_t ptr = (uint8_t)(zero_addr + cpu->X);
|
||||
uint16_t low = memory_read(memory, ptr);
|
||||
uint16_t high = memory_read(memory, (uint8_t)(ptr + 1));
|
||||
return (high << 8) | low;
|
||||
}
|
||||
|
||||
uint16_t addr_indirect_y(CPU* cpu, Memory* memory) {
|
||||
uint8_t zero_addr = memory_read(memory, cpu->PC++);
|
||||
uint16_t low = memory_read(memory, zero_addr);
|
||||
uint16_t high = memory_read(memory, (uint8_t)(zero_addr + 1));
|
||||
uint16_t base = (high << 8) | low;
|
||||
return base + cpu->Y;
|
||||
}
|
||||
|
||||
// Load/Store Instructions
|
||||
void ins_lda(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
cpu->A = memory_read(memory, addr);
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->A == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->A & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_ldx(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
cpu->X = memory_read(memory, addr);
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->X == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->X & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_ldy(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
cpu->Y = memory_read(memory, addr);
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->Y == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->Y & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_sta(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
memory_write(memory, addr, cpu->A);
|
||||
}
|
||||
|
||||
void ins_stx(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
memory_write(memory, addr, cpu->X);
|
||||
}
|
||||
|
||||
void ins_sty(CPU* cpu, Memory* memory, uint16_t addr) {
|
||||
memory_write(memory, addr, cpu->Y);
|
||||
}
|
||||
|
||||
// Register Transfer Instructions
|
||||
void ins_tax(CPU* cpu) {
|
||||
cpu->X = cpu->A;
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->X == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->X & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_tay(CPU* cpu) {
|
||||
cpu->Y = cpu->A;
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->Y == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->Y & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_txa(CPU* cpu) {
|
||||
cpu->A = cpu->X;
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->A == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->A & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_tya(CPU* cpu) {
|
||||
cpu->A = cpu->Y;
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->A == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->A & 0x80) != 0);
|
||||
}
|
||||
|
||||
// Stack Operations
|
||||
void ins_pha(CPU* cpu, Memory* memory) {
|
||||
memory_stack_push(memory, &cpu->SP, cpu->A);
|
||||
}
|
||||
|
||||
void ins_php(CPU* cpu, Memory* memory) {
|
||||
memory_stack_push(memory, &cpu->SP, cpu->P | FLAG_BREAK | FLAG_UNUSED);
|
||||
}
|
||||
|
||||
void ins_pla(CPU* cpu, Memory* memory) {
|
||||
cpu->A = memory_stack_pull(memory, &cpu->SP);
|
||||
cpu_set_flag(cpu, FLAG_ZERO, cpu->A == 0);
|
||||
cpu_set_flag(cpu, FLAG_NEGATIVE, (cpu->A & 0x80) != 0);
|
||||
}
|
||||
|
||||
void ins_plp(CPU* cpu, Memory* memory) {
|
||||
cpu->P = (memory_stack_pull(memory, &cpu->SP) & ~FLAG_BREAK) | FLAG_UNUSED;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#ifndef INSTRUCTIONS_H
|
||||
#define INSTRUCTIONS_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
// Addressing Modes
|
||||
uint16_t addr_immediate(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_zeropage(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_zeropage_x(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_zeropage_y(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_absolute(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_absolute_x(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_absolute_y(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_indirect(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_indirect_x(CPU* cpu, Memory* memory);
|
||||
uint16_t addr_indirect_y(CPU* cpu, Memory* memory);
|
||||
|
||||
// Instructions
|
||||
void ins_lda(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_ldx(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_ldy(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_sta(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_stx(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_sty(CPU* cpu, Memory* memory, uint16_t addr);
|
||||
void ins_tax(CPU* cpu);
|
||||
void ins_tay(CPU* cpu);
|
||||
void ins_txa(CPU* cpu);
|
||||
void ins_tya(CPU* cpu);
|
||||
|
||||
// Stack operations
|
||||
void ins_pha(CPU* cpu, Memory* memory);
|
||||
void ins_php(CPU* cpu, Memory* memory);
|
||||
void ins_pla(CPU* cpu, Memory* memory);
|
||||
void ins_plp(CPU* cpu, Memory* memory);
|
||||
|
||||
#endif // INSTRUCTIONS_H
|
||||
@@ -1,39 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MEMORY_SIZE 65536 // 64K memory space
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[MEMORY_SIZE];
|
||||
} Memory;
|
||||
|
||||
void memory_init(Memory* memory) {
|
||||
// Initialize all memory to 0
|
||||
memset(memory->data, 0, MEMORY_SIZE);
|
||||
}
|
||||
|
||||
uint8_t memory_read(Memory* memory, uint16_t address) {
|
||||
return memory->data[address];
|
||||
}
|
||||
|
||||
void memory_write(Memory* memory, uint16_t address, uint8_t value) {
|
||||
memory->data[address] = value;
|
||||
}
|
||||
|
||||
// Helper function to write multiple bytes to memory
|
||||
void memory_write_bytes(Memory* memory, uint16_t address, const uint8_t* data, uint16_t length) {
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
memory_write(memory, address + i, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Stack operations (stack is located at 0x0100-0x01FF)
|
||||
uint8_t memory_stack_pull(Memory* memory, uint8_t* sp) {
|
||||
(*sp)++;
|
||||
return memory_read(memory, 0x0100 | *sp);
|
||||
}
|
||||
|
||||
void memory_stack_push(Memory* memory, uint8_t* sp, uint8_t value) {
|
||||
memory_write(memory, 0x0100 | *sp, value);
|
||||
(*sp)--;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MEMORY_SIZE 65536
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[MEMORY_SIZE];
|
||||
} Memory;
|
||||
|
||||
void memory_init(Memory* memory);
|
||||
uint8_t memory_read(Memory* memory, uint16_t address);
|
||||
void memory_write(Memory* memory, uint16_t address, uint8_t value);
|
||||
void memory_write_bytes(Memory* memory, uint16_t address, const uint8_t* data, uint16_t length);
|
||||
uint8_t memory_stack_pull(Memory* memory, uint8_t* sp);
|
||||
void memory_stack_push(Memory* memory, uint8_t* sp, uint8_t value);
|
||||
|
||||
#endif // MEMORY_H
|
||||
Reference in New Issue
Block a user