A MOS 6502 emulator written in C with a focus on speed, especially for ARM targets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.3KB

  1. #include <stdint.h>
  2. typedef enum {
  3. e6502_Status_C = 0b00000001,
  4. e6502_Status_Z = 0b00000010,
  5. e6502_Status_I = 0b00000100,
  6. e6502_Status_D = 0b00001000,
  7. e6502_Status_B = 0b00010000,
  8. e6502_Status_1 = 0b00100000,
  9. e6502_Status_V = 0b01000000,
  10. e6502_Status_N = 0b10000000,
  11. } e6502_Status_Flag_Bit;
  12. typedef struct {
  13. uint16_t PC;
  14. uint8_t SP;
  15. uint8_t A;
  16. uint8_t X;
  17. uint8_t Y;
  18. uint8_t S;
  19. } e6502_Registers;
  20. typedef struct {
  21. e6502_Registers registers;
  22. int cycle;
  23. int instr;
  24. uint8_t memory[65536];
  25. } e6502_Core;
  26. #define e6502_Memory_Stack (0x0100U)
  27. #define e6502_IRQ_Vec (0xFFFEU)
  28. #define e6502_Reset_Vec (0xFFFCU)
  29. #define e6502_NMI_Vec (0xFFFAU)
  30. typedef uint16_t e6502_Mem_Addr;
  31. /*
  32. uint8_t e6502_r8(e6502_Core* core, e6502_Mem_Addr adr);
  33. void e6502_w8(e6502_Core* core, e6502_Mem_Addr adr, uint8_t val);
  34. */
  35. static inline uint8_t e6502_r8(e6502_Core* core,
  36. e6502_Mem_Addr adr) {
  37. return core->memory[adr];
  38. }
  39. static inline void e6502_w8(e6502_Core* core,
  40. e6502_Mem_Addr adr,
  41. uint8_t val) {
  42. core->memory[adr] = val;
  43. }
  44. static inline uint16_t e6502_r16(e6502_Core* core,
  45. e6502_Mem_Addr adr) {
  46. return e6502_r8(core, adr) |
  47. ((uint16_t)e6502_r8(core, adr + 1) << 8);
  48. }
  49. static inline void e6502_w16(e6502_Core* core,
  50. e6502_Mem_Addr adr,
  51. uint16_t val) {
  52. e6502_w8(core, adr, val);
  53. e6502_w8(core, adr + 1, val >> 8);
  54. }
  55. static inline void e6502_push8(e6502_Core* core, uint8_t val) {
  56. e6502_w8(core, e6502_Memory_Stack + core->registers.SP--, val);
  57. }
  58. static inline void e6502_push16(e6502_Core* core, uint16_t val) {
  59. e6502_push8(core, val >> 8);
  60. e6502_push8(core, val & 0xFF);
  61. }
  62. static inline uint8_t e6502_pop8(e6502_Core* core) {
  63. return e6502_r8(core, e6502_Memory_Stack +
  64. ++core->registers.SP);
  65. }
  66. static inline uint16_t e6502_pop16(e6502_Core* core) {
  67. return (e6502_pop8(core) | ((uint16_t)e6502_pop8(core) << 8));
  68. }
  69. int e6502_run(e6502_Core* core,
  70. int remaining,
  71. int* run,
  72. int instructions);
  73. int e6502_reset(e6502_Core* core);