Subversion Repositories pentevo

Rev

Rev 1153 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // From https://github.com/tslabs/zx-evo/blob/master/pentevo/unreal/Unreal/sound/dev_moonsound.cpp
  2.  
  3. #include "../std.h"
  4. #include "../emul.h"
  5. #include "../vars.h"
  6. #include "../util.h"
  7. #include "dev_moonsound.h"
  8.  
  9.  
  10. #define MASTER_CLOCK 33868800
  11.  
  12.  
  13. inline EmuTime SystemTime()
  14. {
  15.         return cpu.t + comp.frame_counter * conf.frame;
  16. }
  17.  
  18. ZXMMoonSound_priv::ZXMMoonSound_priv() : ymf262(0, 0), ymf278(0, 4096/*ram*/, 2048/*rom*/, 0)
  19. {
  20.         EmuTime systemTime = 0;
  21.  
  22. //      ymf262 = new YMF262(0, systemTime);
  23.         ymf262.setSampleRate(44100, 1);
  24.         ymf262.setVolume(32767 * 2 / 10);
  25.  
  26. //      ymf278 = new YMF278(0, 4096, 2048*1024, systemTime);
  27.         ymf278.setSampleRate(44100, 1);
  28.         ymf278.setVolume(32767 * 2 / 10);
  29. }
  30.  
  31. ZXMMoonSound_priv::~ZXMMoonSound_priv()
  32. {
  33. //      delete ymf262;
  34. //      delete ymf278;
  35. }
  36.  
  37. /*  */
  38. ZXMMoonSound::ZXMMoonSound() :
  39.         system_clock_rate( 0 )
  40. {
  41. //      d = new ZXMMoonSound_priv();
  42.         reset();
  43. }
  44.  
  45. int ZXMMoonSound::load_rom(char *path)
  46. {
  47.         u8 * moon_rom;
  48.  
  49.         moon_rom = d.ymf278.getRom();
  50.  
  51.         if( !moon_rom )
  52.                 return -1;
  53.  
  54.         FILE *fp = fopen( path, "rb" );
  55.         if ( !fp )
  56.         {
  57.                 return -2;
  58.         }
  59.  
  60.         if( 1 != fread( moon_rom, d.ymf278.getRomSize(), 1, fp ) )
  61.         {
  62.                 fclose(fp);
  63.                 return -3;
  64.         }
  65.  
  66.         fclose( fp );
  67.  
  68.         return 0;
  69. }
  70.  
  71. void ZXMMoonSound::reset()
  72. {
  73.         unsigned tStatesPerSecond = conf.frame * conf.intfq;
  74.         EmuTime systemTime = SystemTime();
  75.  
  76.         d.ymf262.reset( systemTime, tStatesPerSecond );
  77.         d.ymf278.reset( systemTime );
  78. }
  79.  
  80. bool ZXMMoonSound::wr_opl3( u8 port, u8 val )
  81. {
  82.         EmuTime systemTime = SystemTime();
  83.  
  84.         if ( !(port & 0xFC) )
  85.         {
  86.                 switch (port & 0x03) {
  87.                 case 0:
  88.                         d.opl3latch = val;
  89.                         break;
  90.                 case 2: // select register bank 1
  91.                         d.opl3latch = val | 0x100;
  92.                         break;
  93.                 case 1:
  94.                 case 3: // write fm register
  95.                         d.ymf262.writeReg(d.opl3latch, val, systemTime);
  96.                         break;
  97.                 }
  98.  
  99.                 return true;
  100.         }
  101.  
  102.         return false;
  103. }
  104.  
  105. bool ZXMMoonSound::wr_opl4( u8 port, u8 val )
  106. {
  107.         EmuTime systemTime = SystemTime();
  108.  
  109.         if ( !(port & 0xFE) )
  110.         {
  111.                 switch (port & 0x01) {
  112.                 case 0: // select register
  113.                         d.opl4latch = val;
  114.                         break;
  115.                 case 1:
  116.                         d.ymf278.writeRegOPL4(d.opl4latch, val, systemTime);
  117.                         break;
  118.                 }
  119.  
  120.                 return true;
  121.         }
  122.  
  123.         return false;
  124. }
  125.  
  126. bool ZXMMoonSound::rd_opl3( u8 port, u8 &val )
  127. {
  128.         EmuTime systemTime = SystemTime();
  129.  
  130.         if( !(port & 0xFC) )
  131.         {
  132.                 switch (port & 0x03) {
  133.                 case 0: // read status
  134.                 case 2:
  135.                         val = d.ymf262.readStatus(systemTime) | d.ymf278.readStatus(systemTime);
  136.                         break;
  137.                 case 1:
  138.                 case 3: // read fm register
  139.                         val = d.ymf262.readReg(d.opl3latch);
  140.                         break;
  141.                 }
  142.  
  143.                 return true;
  144.         }
  145.  
  146.         return false;
  147. }
  148.  
  149. bool ZXMMoonSound::rd_opl4( u8 port, u8 &val )
  150. {
  151.         EmuTime systemTime = SystemTime();
  152.  
  153.         if ( !(port & 0xFE) )
  154.         {
  155.                 switch (port & 0x01) {
  156.                 case 1: // read wave register
  157.                         val = d.ymf278.readRegOPL4(d.opl4latch, systemTime);
  158.                         break;
  159.                 }
  160.  
  161.                 return true;
  162.         }
  163.  
  164.         return false;
  165. }
  166.  
  167.  
  168. void ZXMMoonSound::set_timings(unsigned system_clock_rate, unsigned chip_clock_rate, unsigned sample_rate)
  169. {
  170.         d.ymf262.setSampleRate( sample_rate, 1 );
  171.         d.ymf262.setVolume((u16)(1 * (conf.sound.moonsound_vol / 8192.0))); // doesn't work
  172.         d.ymf278.setSampleRate( sample_rate, 1 );
  173.         d.ymf278.setVolume((u16)(2000 * (conf.sound.moonsound_vol / 8192.0)));
  174.        
  175.         chip_clock_rate = sample_rate;
  176.  
  177.         ZXMMoonSound::system_clock_rate = system_clock_rate;
  178.         ZXMMoonSound::chip_clock_rate = chip_clock_rate;
  179.  
  180.         SNDRENDER::set_timings(chip_clock_rate, sample_rate);
  181.         passed_chip_ticks = passed_clk_ticks = 0;
  182.         t = 0;
  183. }
  184.  
  185. void ZXMMoonSound::start_frame(bufptr_t dst)
  186. {
  187.     SNDRENDER::start_frame(dst);
  188. }
  189.  
  190. unsigned ZXMMoonSound::end_frame(unsigned clk_ticks)
  191. {
  192.         u64 end_chip_tick = ((passed_clk_ticks + clk_ticks) * chip_clock_rate) / system_clock_rate;
  193.  
  194.         flush((unsigned)(end_chip_tick - passed_chip_ticks));
  195.  
  196.     unsigned Val = SNDRENDER::end_frame(t);
  197.         passed_clk_ticks += clk_ticks;
  198.     passed_chip_ticks += t;
  199.     t = 0;
  200.  
  201.     return Val;
  202. }
  203.  
  204. void ZXMMoonSound::flush(unsigned chiptick)
  205. {
  206.         while (t < chiptick)
  207.     {
  208.                 int buffer[2] = { 0, 0 };
  209.                 int *buf;
  210.  
  211.                 t++;
  212.  
  213.                 buf = d.ymf262.updateBuffer(1);
  214.                 if ( buf )
  215.                 {
  216.                         buffer[0] += buf[0] / 10;
  217.                         buffer[1] += buf[1] / 10;
  218.                 }
  219.  
  220.                 buf = d.ymf278.updateBuffer(1);
  221.                 if ( buf )
  222.                 {
  223.                         buffer[0] += buf[0];
  224.                         buffer[1] += buf[1];
  225.                 }
  226.                
  227.                 SNDRENDER::update( t, buffer[0], buffer[1] );
  228.         }
  229. }
  230.  
  231. ZXMMoonSound zxmmoonsound;
  232.