A MOS 6502 emulator written in C with a focus on speed, especially for ARM targets.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

134 lignes
3.2KB

  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;
  12. typedef enum __attribute__ ((__packed__)) {
  13. e6502_Pin_NMI = 0b01,
  14. e6502_Pin_IRQ = 0b10,
  15. e6502_NMI_Serviced = 0b10000000
  16. } e6502_Pin;
  17. typedef struct __attribute__ ((__packed__)) {
  18. uint16_t PC;
  19. uint8_t S;
  20. uint8_t A;
  21. uint8_t X;
  22. uint8_t Y;
  23. uint8_t P;
  24. } e6502_Registers;
  25. typedef uint16_t e6502_Mem_Addr;
  26. #ifndef E6502_POLL_MEM
  27. typedef uint8_t(e6502_Read)(void*, e6502_Mem_Addr);
  28. typedef void(e6502_Write)(void*, e6502_Mem_Addr, uint8_t);
  29. #endif
  30. typedef struct {
  31. e6502_Registers registers;
  32. e6502_Pin pins;
  33. #ifdef E6502_POLL_MEM
  34. uint8_t memory[65536];
  35. #else
  36. e6502_Read* bus_read;
  37. e6502_Write* bus_write;
  38. void* bus_context;
  39. #endif
  40. int cycle;
  41. } e6502_Core;
  42. #define e6502_Memory_Stack (0x0100U)
  43. #define e6502_IRQ_Vec (0xFFFEU)
  44. #define e6502_Reset_Vec (0xFFFCU)
  45. #define e6502_NMI_Vec (0xFFFAU)
  46. #ifdef E6502_POLL_MEM
  47. static inline uint8_t e6502_r8(e6502_Core* core,
  48. e6502_Mem_Addr adr) {
  49. return core->memory[adr];
  50. }
  51. static inline void e6502_w8(e6502_Core* core,
  52. e6502_Mem_Addr adr,
  53. uint8_t val) {
  54. core->memory[adr] = val;
  55. }
  56. #else
  57. static inline uint8_t e6502_r8(e6502_Core* core,
  58. e6502_Mem_Addr adr) {
  59. return core->bus_read(core->bus_context, adr);
  60. }
  61. static inline void e6502_w8(e6502_Core* core,
  62. e6502_Mem_Addr adr,
  63. uint8_t val) {
  64. return core->bus_write(core->bus_context, adr, val);
  65. }
  66. #endif
  67. static inline uint16_t e6502_r16(e6502_Core* core,
  68. e6502_Mem_Addr adr) {
  69. return e6502_r8(core, adr) |
  70. ((uint16_t)e6502_r8(core, adr + 1) << 8);
  71. }
  72. static inline void e6502_w16(e6502_Core* core,
  73. e6502_Mem_Addr adr,
  74. uint16_t val) {
  75. e6502_w8(core, adr, val);
  76. e6502_w8(core, adr + 1, val >> 8);
  77. }
  78. static inline void e6502_push8(e6502_Core* core, uint8_t val) {
  79. e6502_w8(core, e6502_Memory_Stack + core->registers.S--, val);
  80. }
  81. static inline void e6502_push16(e6502_Core* core, uint16_t val) {
  82. e6502_push8(core, val >> 8);
  83. e6502_push8(core, val & 0xFF);
  84. }
  85. static inline uint8_t e6502_pop8(e6502_Core* core) {
  86. return e6502_r8(core, e6502_Memory_Stack +
  87. ++core->registers.S);
  88. }
  89. static inline uint16_t e6502_pop16(e6502_Core* core) {
  90. return (e6502_pop8(core) | ((uint16_t)e6502_pop8(core) << 8));
  91. }
  92. #ifdef E6502_POLL_MEM
  93. void e6502_init(e6502_Core*);
  94. #else
  95. void e6502_init(e6502_Core*, e6502_Read, e6502_Write, void*);
  96. #endif
  97. int e6502_step(e6502_Core* core);
  98. int e6502_run(e6502_Core* core,
  99. int remaining,
  100. int* run,
  101. int instructions);
  102. void e6502_reset(e6502_Core* core);
  103. void e6502_set_irq(e6502_Core* core, int active);
  104. void e6502_set_nmi(e6502_Core* core, int active);