NESe (pronounced "Nessie") is a NES emulator based on the e6502 emulator, also written in C with a focus on speed and portability for use on embedded platforms, especially ARM.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

96 行
2.2KB

  1. #include "memory.h"
  2. void nes_apu_init(nes_APU* apu, nes_APU_Memory* mem, int freq) {
  3. // TODO
  4. }
  5. int nes_apu_hsync(nes_APU* apu, nes_Memory* core_mem) {
  6. nes_APU_Memory* mem = &core_mem->apu;
  7. for (int i = 0; i < core_mem->apu.n_events; ++i) {
  8. int reg = core_mem->apu.events[i].reg;
  9. int val = core_mem->apu.events[i].val;
  10. switch (reg) {
  11. // TODO: 0x00 - 0x13
  12. // TODO: 0x15
  13. case 0x17: // Frame Counter
  14. apu->frame_reg = val & ( apu_Frame_Mode |
  15. apu_Frame_Inhibit);
  16. apu->frame = 0;
  17. apu->frame_delay = 0;
  18. if (val & apu_Frame_Mode) {
  19. // TODO
  20. /*
  21. nes_apu_clock_quarter_frame(apu);
  22. nes_apu_clock_half_frame(apu);
  23. */
  24. }
  25. if (val & apu_Frame_Inhibit) {
  26. mem->status &= ~apu_Status_Frame_Int;
  27. }
  28. break;
  29. }
  30. }
  31. core_mem->apu.n_events = 0;
  32. // Frame advance
  33. apu->frame_delay += nes_apu_hsync_ticks;
  34. if (apu->frame_delay >= nes_apu_quarter_frame_ticks) {
  35. apu->frame_delay -= nes_apu_quarter_frame_ticks;
  36. int end = 0;
  37. int quarter_frame = 1;
  38. int half_frame = 0;
  39. if (1 == apu->frame) {
  40. half_frame = 1;
  41. }
  42. if (apu->frame_reg & apu_Frame_Mode) {
  43. if (3 == apu->frame) {
  44. quarter_frame = 0;
  45. } else if (4 <= apu->frame) {
  46. half_frame = 1;
  47. end = 1;
  48. }
  49. } else {
  50. if (3 <= apu->frame) {
  51. half_frame = 1;
  52. end = 1;
  53. }
  54. }
  55. if (half_frame) {
  56. // TODO
  57. //nes_apu_clock_half_frame(apu);
  58. }
  59. if (quarter_frame) {
  60. // TODO
  61. //nes_apu_clock_quarter_frame(apu);
  62. }
  63. if (end) {
  64. if (0 == apu->frame_reg) {
  65. mem->status |= apu_Status_Frame_Int;
  66. }
  67. apu->frame = 0;
  68. } else {
  69. apu->frame++;
  70. }
  71. }
  72. // TODO: DMC Interrupt
  73. return (mem->status & apu_Status_Frame_Int);
  74. }