Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.21 KB | None | 0 0
  1. //Ricoh RF5C164
  2.  
  3. auto MCD::PCM::clock() -> void {
  4. int left = 0;
  5. int right = 0;
  6. if(io.enable)
  7. for(auto& channel : channels) {
  8. if(!channel.enable) continue;
  9. int data = ram[channel.address >> 11];
  10. if(data == 0xff) { //loop?
  11. channel.address = channel.loop << 11;
  12. data = ram[channel.loop];
  13. if(data == 0xff) continue; //infinite loop; does not output any sound
  14. }
  15. channel.address += channel.step;
  16. if(data & 0x80) {
  17. data = +(data & 0x7f);
  18. } else {
  19. data = -(data & 0x7f);
  20. }
  21. left += data * channel.envelope * uint4(channel.pan >> 0) >> 5;
  22. right += data * channel.envelope * uint4(channel.pan >> 4) >> 5;
  23. }
  24.  
  25. //clamp to 10-bit DAC output rate
  26. left = sclamp<16>(left ) & ~63;
  27. right = sclamp<16>(right) & ~63;
  28. stream->sample(left / 32768.0, right / 32768.0);
  29. }
  30.  
  31. auto MCD::PCM::read(uint13 address, uint8 data) -> uint8 {
  32. if(address >= 0x1000 && address <= 0x1fff) {
  33. data = ram[io.bank << 12 | (uint12)address];
  34. return data;
  35. }
  36.  
  37. if(address >= 0x0010 && address <= 0x001f) {
  38. auto& channel = channels[address.bits(1,3)];
  39. uint shift = 11 + (!address.bit(0) ? 0 : 8);
  40. data = channel.address >> shift;
  41. return data;
  42. }
  43.  
  44. return data = 0xff;
  45. }
  46.  
  47. auto MCD::PCM::write(uint13 address, uint8 data) -> void {
  48. if(address >= 0x1000 && address <= 0x1fff) {
  49. ram[io.bank << 12 | (uint12)address] = data;
  50. return;
  51. }
  52.  
  53. auto& channel = channels[io.channel];
  54.  
  55. switch(address) {
  56.  
  57. case 0x0: { //ENV
  58. channel.envelope = data;
  59. } break;
  60.  
  61. case 0x1: { //PAN
  62. channel.pan = data;
  63. } break;
  64.  
  65. case 0x2: { //FDL
  66. channel.step.byte(0) = data;
  67. } break;
  68.  
  69. case 0x3: { //FDH
  70. channel.step.byte(1) = data;
  71. } break;
  72.  
  73. case 0x4: { //LSL
  74. channel.loop.byte(0) = data;
  75. } break;
  76.  
  77. case 0x5: { //LSH
  78. channel.loop.byte(1) = data;
  79. } break;
  80.  
  81. case 0x6: { //ST
  82. channel.start = data;
  83. if(!channel.enable) channel.address = channel.start << 8 << 11;
  84. } break;
  85.  
  86. case 0x7: { //CTRL
  87. if(data.bit(6)) {
  88. io.channel = data.bits(0,2);
  89. } else {
  90. io.bank = data.bits(0,3);
  91. }
  92. io.enable = data.bit(7);
  93. } break;
  94.  
  95. case 0x8: { //ONOFF
  96. for(auto& channel : channels) {
  97. channel.enable = !(data & 1); data >>= 1;
  98. if(!channel.enable) channel.address = channel.start << 8 << 11;
  99. }
  100. } break;
  101.  
  102. }
  103. }
  104.  
  105. auto MCD::PCM::power(bool reset) -> void {
  106. stream = audio.createStream(2, mcd.frequency() / 384.0);
  107. io = {};
  108. for(auto& channel : channels) channel = {};
  109. }
  110.  
  111. ...
  112.  
  113. struct PCM {
  114. shared_pointer<Stream> stream;
  115. Memory::Writable<uint8> ram;
  116.  
  117. //pcm.cpp
  118. auto clock() -> void;
  119. auto read(uint13 address, uint8 data) -> uint8;
  120. auto write(uint13 address, uint8 data) -> void;
  121. auto power(bool reset) -> void;
  122.  
  123. //serialization.cpp
  124. auto serialize(serializer&) -> void;
  125.  
  126. struct IO {
  127. uint1 enable;
  128. uint4 bank;
  129. uint3 channel;
  130. } io;
  131.  
  132. struct Channel {
  133. uint1 enable;
  134. uint8 envelope;
  135. uint8 pan = 0xff;
  136. uint16 step;
  137. uint16 loop;
  138. uint8 start;
  139. uint32 address;
  140. } channels[8];
  141. } pcm;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement