#include typedef enum { e6502_Status_C = 0b00000001, e6502_Status_Z = 0b00000010, e6502_Status_I = 0b00000100, e6502_Status_D = 0b00001000, e6502_Status_B = 0b00010000, e6502_Status_1 = 0b00100000, e6502_Status_V = 0b01000000, e6502_Status_N = 0b10000000, } e6502_Status_Flag; typedef enum __attribute__ ((__packed__)) { e6502_Pin_NMI = 0b01, e6502_Pin_IRQ = 0b10, e6502_NMI_Serviced = 0b10000000 } e6502_Pin; typedef struct __attribute__ ((__packed__)) { uint16_t PC; uint8_t S; uint8_t A; uint8_t X; uint8_t Y; uint8_t P; } e6502_Registers; typedef uint16_t e6502_Mem_Addr; #ifndef E6502_POLL_MEM typedef uint8_t(e6502_Read)(void*, e6502_Mem_Addr); typedef void(e6502_Write)(void*, e6502_Mem_Addr, uint8_t); #endif typedef struct { e6502_Registers registers; e6502_Pin pins; #ifdef E6502_POLL_MEM uint8_t memory[65536]; #else e6502_Read* bus_read; e6502_Write* bus_write; void* bus_context; #endif int cycle; } e6502_Core; #define e6502_Memory_Stack (0x0100U) #define e6502_IRQ_Vec (0xFFFEU) #define e6502_Reset_Vec (0xFFFCU) #define e6502_NMI_Vec (0xFFFAU) #ifdef E6502_POLL_MEM static inline uint8_t e6502_r8(e6502_Core* core, e6502_Mem_Addr adr) { return core->memory[adr]; } static inline void e6502_w8(e6502_Core* core, e6502_Mem_Addr adr, uint8_t val) { core->memory[adr] = val; } #else static inline uint8_t e6502_r8(e6502_Core* core, e6502_Mem_Addr adr) { return core->bus_read(core->bus_context, adr); } static inline void e6502_w8(e6502_Core* core, e6502_Mem_Addr adr, uint8_t val) { return core->bus_write(core->bus_context, adr, val); } #endif static inline uint16_t e6502_r16(e6502_Core* core, e6502_Mem_Addr adr) { return e6502_r8(core, adr) | ((uint16_t)e6502_r8(core, adr + 1) << 8); } static inline void e6502_w16(e6502_Core* core, e6502_Mem_Addr adr, uint16_t val) { e6502_w8(core, adr, val); e6502_w8(core, adr + 1, val >> 8); } static inline void e6502_push8(e6502_Core* core, uint8_t val) { e6502_w8(core, e6502_Memory_Stack + core->registers.S--, val); } static inline void e6502_push16(e6502_Core* core, uint16_t val) { e6502_push8(core, val >> 8); e6502_push8(core, val & 0xFF); } static inline uint8_t e6502_pop8(e6502_Core* core) { return e6502_r8(core, e6502_Memory_Stack + ++core->registers.S); } static inline uint16_t e6502_pop16(e6502_Core* core) { return (e6502_pop8(core) | ((uint16_t)e6502_pop8(core) << 8)); } #ifdef E6502_POLL_MEM void e6502_init(e6502_Core*); #else void e6502_init(e6502_Core*, e6502_Read, e6502_Write, void*); #endif int e6502_step(e6502_Core* core); int e6502_run(e6502_Core* core, int remaining, int* run, int instructions); void e6502_reset(e6502_Core* core); void e6502_set_irq(e6502_Core* core, int active); void e6502_set_nmi(e6502_Core* core, int active);