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.

102 lines
2.6KB

  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 struct {
  13. uint16_t PC;
  14. uint8_t S;
  15. uint8_t A;
  16. uint8_t X;
  17. uint8_t Y;
  18. uint8_t P;
  19. } e6502_Registers;
  20. typedef uint16_t e6502_Mem_Addr;
  21. typedef uint8_t(e6502_Read)(void*, e6502_Mem_Addr);
  22. typedef void(e6502_Write)(void*, e6502_Mem_Addr, uint8_t);
  23. typedef struct {
  24. e6502_Registers registers;
  25. e6502_Read* bus_read;
  26. e6502_Write* bus_write;
  27. void* bus_context;
  28. int cycle;
  29. } e6502_Core;
  30. #define e6502_Memory_Stack (0x0100U)
  31. #define e6502_IRQ_Vec (0xFFFEU)
  32. #define e6502_Reset_Vec (0xFFFCU)
  33. #define e6502_NMI_Vec (0xFFFAU)
  34. void e6502_init(e6502_Core*, e6502_Read, e6502_Write, void*);
  35. /*
  36. uint8_t e6502_r8(e6502_Core* core, e6502_Mem_Addr adr);
  37. void e6502_w8(e6502_Core* core, e6502_Mem_Addr adr, uint8_t val);
  38. */
  39. static inline uint8_t e6502_r8(e6502_Core* core,
  40. e6502_Mem_Addr adr) {
  41. // return core->memory[adr];
  42. return core->bus_read(core->bus_context, adr);
  43. }
  44. static inline void e6502_w8(e6502_Core* core,
  45. e6502_Mem_Addr adr,
  46. uint8_t val) {
  47. // core->memory[adr] = val;
  48. return core->bus_write(core->bus_context, adr, val);
  49. }
  50. static inline uint16_t e6502_r16(e6502_Core* core,
  51. e6502_Mem_Addr adr) {
  52. return e6502_r8(core, adr) |
  53. ((uint16_t)e6502_r8(core, adr + 1) << 8);
  54. }
  55. static inline void e6502_w16(e6502_Core* core,
  56. e6502_Mem_Addr adr,
  57. uint16_t val) {
  58. e6502_w8(core, adr, val);
  59. e6502_w8(core, adr + 1, val >> 8);
  60. }
  61. static inline void e6502_push8(e6502_Core* core, uint8_t val) {
  62. e6502_w8(core, e6502_Memory_Stack + core->registers.S--, val);
  63. }
  64. static inline void e6502_push16(e6502_Core* core, uint16_t val) {
  65. e6502_push8(core, val >> 8);
  66. e6502_push8(core, val & 0xFF);
  67. }
  68. static inline uint8_t e6502_pop8(e6502_Core* core) {
  69. return e6502_r8(core, e6502_Memory_Stack +
  70. ++core->registers.S);
  71. }
  72. static inline uint16_t e6502_pop16(e6502_Core* core) {
  73. return (e6502_pop8(core) | ((uint16_t)e6502_pop8(core) << 8));
  74. }
  75. int e6502_run(e6502_Core* core,
  76. int remaining,
  77. int* run,
  78. int instructions);
  79. int e6502_reset(e6502_Core* core);