Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "../std.h"
  2.  
  3. #include "../emul.h"
  4. #include "../vars.h"
  5. #include "emul_2203.h"
  6. /*
  7.    YM-2149F emulator for Unreal Speccy project
  8.    created under public domain license by SMT, jan.2006
  9. */
  10.  
  11. #include "sndchip.h"
  12. /* [vv]
  13. unsigned SNDCHIP::render(AYOUT *src, unsigned srclen, unsigned clk_ticks, bufptr_t dst)
  14. {
  15.    start_frame(dst);
  16.    for (unsigned index = 0; index < srclen; index++) {
  17.       // if (src[index].timestamp > clk_ticks) continue; // wrong input data leads to crash
  18.       select(src[index].reg_num);
  19.       write(src[index].timestamp, src[index].reg_value);
  20.    }
  21.    return end_frame(clk_ticks);
  22. }
  23. */
  24.  
  25. const unsigned MULT_C_1 = 14; // fixed point precision for 'system tick -> ay tick'
  26. // b = 1+ln2(max_ay_tick/8) = 1+ln2(max_ay_fq/8 / min_intfq) = 1+ln2(10000000/(10*8)) = 17.9
  27. // assert(b+MULT_C_1 <= 32)
  28.  
  29. //=============================================================================
  30. void SNDCHIP::start_frame(bufptr_t dst)
  31. {
  32.    r13_reloaded = 0;
  33.    SNDRENDER::start_frame(dst);
  34. }
  35. //=============================================================================
  36.  
  37.  
  38. //=============================================================================
  39. unsigned SNDCHIP::end_frame(unsigned clk_ticks)
  40. {
  41.    // adjusting 't' with whole history will fix accumulation of rounding errors
  42.  
  43.    uint64_t end_chip_tick = ((passed_clk_ticks + clk_ticks) * chip_clock_rate) / system_clock_rate;
  44.  
  45.    flush( (unsigned) (end_chip_tick - passed_chip_ticks) );
  46.    unsigned res = SNDRENDER::end_frame(t);
  47.  
  48.    passed_clk_ticks += clk_ticks;
  49.    passed_chip_ticks += t; t = 0;
  50.    nextfmtickfloat = 0.; //Alone Coder
  51.    nextfmtick = 0; //Alone Coder
  52.  
  53.    return res;
  54. }
  55. //=============================================================================
  56.  
  57.  
  58. //=============================================================================
  59. void SNDCHIP::flush(unsigned chiptick) // todo: noaction at (temp.sndblock || !conf.sound.ay)
  60. {
  61.     while(t < chiptick)
  62.     {
  63.         t++;
  64.         if(++ta >= fa)
  65.         {
  66.             ta = 0;
  67.             bitA ^= -1U;
  68.         }
  69.         if(++tb >= fb)
  70.         {
  71.             tb = 0;
  72.             bitB ^= -1U;
  73.         }
  74.         if(++tc >= fc)
  75.         {
  76.             tc = 0;
  77.             bitC ^= -1U;
  78.         }
  79.         if(++tn >= fn)
  80.         {
  81.             tn = 0;
  82.             ns = (ns * 2 + 1) ^ (((ns >> 16) ^ (ns >> 13)) & 1);
  83.             bitN = 0 - ((ns >> 16) & 1);
  84.         }
  85.         if(++te >= fe)
  86.         {
  87.             te = 0;
  88.             env = unsigned(int(env) + denv);
  89.             if(env & ~31U)
  90.             {
  91.                 unsigned mask = (1 << r.env);
  92.                 if(mask & ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 9) | (1 << 15)))
  93.                     env = denv = 0;
  94.                 else if(mask & ((1 << 8) | (1 << 12)))
  95.                     env &= 31;
  96.                 else if(mask & ((1 << 10) | (1 << 14)))
  97.                 {
  98.                     denv = -denv;
  99.                     env = unsigned(int(env) + denv);
  100.                 }
  101.                 else
  102.                 {
  103.                     env = 31; denv = 0;
  104.                 } //11,13
  105.             }
  106.         }
  107.  
  108.         unsigned en, mix_l, mix_r;
  109.  
  110.         en = ((ea & env) | va) & ((bitA | bit0) & (bitN | bit3));
  111.         mix_l = vols[0][en]; mix_r = vols[1][en];
  112.  
  113.         en = ((eb & env) | vb) & ((bitB | bit1) & (bitN | bit4));
  114.         mix_l += vols[2][en]; mix_r += vols[3][en];
  115.  
  116.         en = ((ec & env) | vc) & ((bitC | bit2) & (bitN | bit5));
  117.         mix_l += vols[4][en]; mix_r += vols[5][en];
  118.         //YM2203 here
  119.         if(/*temp.sndblock ||*/ conf.sound.ay_chip == CHIP_YM2203)
  120.         {
  121.             if(t >= nextfmtick)
  122.             {
  123.                 nextfmtickfloat += ayticks_per_fmtick;
  124.                 nextfmtick = unsigned(nextfmtickfloat);
  125.                 if(++FMbufN == FMBUFSIZE)
  126.                 {
  127.                     YM2203UpdateOne(Chip2203, FMbufs/*&FMbuf*/, FMBUFSIZE/*1*/);
  128.                     FMbufN = 0;
  129.                 };
  130.                 if(fmsoundon0 == 0)
  131.                 {
  132.                     //FMbufOUT=(int)(FMbuf*conf.sound.ay/8192*0.7f);
  133.                     FMbufOUT = ((((INT16)FMbufs[FMbufN])*FMbufMUL) >> 16);
  134.                 }
  135.                 else FMbufOUT = 0;
  136.             }
  137.             mix_l = unsigned(int(mix_l) + FMbufOUT);
  138.             mix_r = unsigned(int(mix_r) + FMbufOUT);
  139.         }; //Alone Coder
  140.   //
  141.         if((mix_l ^ SNDRENDER::mix_l) | (mix_r ^ SNDRENDER::mix_r)) // similar check inside update()
  142.             update(t, mix_l, mix_r);    //SNDRENDER::update тшфшью
  143.     }
  144. }
  145. //=============================================================================
  146.  
  147.  
  148. //=============================================================================
  149. void SNDCHIP::select(unsigned char nreg)
  150. {
  151.     if (chiptype == CHIP_AY) nreg &= 0x0F;      //фы  фхЄхъЎшш AY / YM
  152.     activereg = nreg;
  153. }
  154. //=============================================================================
  155.  
  156.  
  157. //=============================================================================
  158. void SNDCHIP::write(unsigned timestamp, unsigned char val)
  159. {
  160.     //-------------------------------------------------------------------------
  161.     if (conf.sound.ay_chip == CHIP_YM2203)
  162.     {
  163.         //2203 xtra regs
  164.         if (activereg >= 0x20)
  165.         {
  166.             if (timestamp)
  167.                 flush((timestamp * mult_const) >> MULT_C_1); // cputick * ( (chip_clock_rate/8) / system_clock_rate );
  168.             if ((activereg >= 0x2D) && (activereg <= 0x2F))
  169.             {
  170.                 int oldayfq = Chip2203->OPN.ST.SSGclock /*ayfq*/;
  171.                 YM2203Write(Chip2203,0,activereg);
  172.                 YM2203Write(Chip2203,1,val);
  173.                 if (oldayfq != Chip2203->OPN.ST.SSGclock)
  174.                 {
  175.                     //if (!conf.sound.ay_samples)
  176.                     //  flush(cpu.t);
  177.                     //
  178.                     //ayfq=Chip2203->OPN.ST.SSGclock;
  179.                     //t=(unsigned)((__int64)t*ayfq/oldayfq);
  180.                     //mult_const2 = ((ayfq/conf.intfq) << (MULT_C_1-3))/conf.frame;
  181.                     //mult_const3 = TICK_F/2+(unsigned)((__int64)temp.snd_frame_ticks*conf.intfq*(1<<(MULT_C+3))/ayfq);
  182.                     //ay_div = ((unsigned)((double)ayfq*0x10*(double)SAMPLE_T/(double)conf.sound.fq));
  183.                     //ay_div2 = (ayfq*0x100)/(conf.sound.fq/32);
  184.                     set_timings(system_clock_rate,unsigned(Chip2203->OPN.ST.SSGclock),SNDRENDER::sample_rate);
  185.                 }
  186.             }
  187.             else
  188.             {
  189.                 YM2203Write(Chip2203,0,activereg);
  190.                 YM2203Write(Chip2203,1,val);
  191.             }
  192.             return;
  193.         } //Dexus
  194.     }
  195.     //-------------------------------------------------------------------------
  196.     if (activereg >= 0x10) return;
  197.     //-------------------------------------------------------------------------
  198.     // [NS] р ЄєЄ эєцэю тэ Єэюх єЄюўэхэшх
  199.     // ўЄю ўшЄрхЄёю шч яєёЄюЄ√ эр AY ш YM
  200.     //
  201.     // юсЁхчър 4-ї сшЄэ√ї ЁхушёЄЁют
  202.     if ((1 << activereg) & ( (1<<0x01) | (1<<0x03) | (1<<0x05) | (1<<0x0D) ))
  203.         val &= 0x0F;            //1,3,5,13
  204.     // юсЁхчър 5-Єш сшЄэ√ї ЁхушёЄЁют
  205.     if ((1 << activereg) & ( (1<<0x06) | (1<<0x08) | (1<<0x09) | (1<<0x0A) ))
  206.         val &= 0x1F;                            //6,8,9,10
  207.     //-------------------------------------------------------------------------
  208.     // Єю цх чэрўхэшх эшўхую эх ьхэ хЄ (ъЁюьх Єшяр юушср■∙хщ)
  209.     if ((activereg != 0x0D) && (reg[activereg] == val))         //13
  210.         return;
  211.     //-------------------------------------------------------------------------
  212.     reg[activereg] = val;       // юЄ ё■фр яюЄюь ўЄхэшх эрчрф
  213.     //-------------------------------------------------------------------------
  214.     if (timestamp)
  215.         flush( (timestamp * mult_const) >> MULT_C_1);   //MULT_C_1 = 14 !!!
  216.         // cputick * ( (chip_clock_rate/8) / system_clock_rate );
  217. //-----------------------------------------------------------------------------
  218.     switch (activereg)
  219.     {
  220.         //---------------------------------------------------------------------
  221.         case 0x00:                              //r0 r1         channel A FRQ
  222.         case 0x01:
  223.             fa = r.fA;
  224.             break;
  225.         //---------------------------------------------------------------------
  226.         case 0x02:                              //r2 r3         channel B FRQ
  227.         case 0x03:
  228.             fb = r.fB;
  229.             break;
  230.         //---------------------------------------------------------------------
  231.         case 0x04:                              //r4 r5         channel C FRQ
  232.         case 0x05:
  233.             fc = r.fC;
  234.             break;
  235.         //---------------------------------------------------------------------
  236.         case 0x06:                              //r6            noise FRQ
  237.             if (val == 0)
  238.                 val++;          // fixed noise 0/ 2021.11.24 /Dexus     // NEDOREPO
  239.                                 // [NS] ўшЄрхЄёю цх юсЁрЄэю 0 шч reg[activereg]
  240.                                 // Єръ ўЄю ¤Єю шёяЁртэ√щ Їшъё
  241.             fn = val*2;
  242.             break;
  243.         //---------------------------------------------------------------------
  244.         case 0x07:                              //r7            mixer
  245.             bit0 = 0 - ((val>>0) & 1);
  246.             bit1 = 0 - ((val>>1) & 1);
  247.             bit2 = 0 - ((val>>2) & 1);
  248.             bit3 = 0 - ((val>>3) & 1);
  249.             bit4 = 0 - ((val>>4) & 1);
  250.             bit5 = 0 - ((val>>5) & 1);
  251.             break;
  252.         //---------------------------------------------------------------------
  253.         case 0x08:                              //r8            channel A VOL
  254.             ea = unsigned((val & 0x10)? -1 : 0);
  255.             va = ((val & 0x0F)*2+1) & ~ea;
  256.             break;
  257.         //---------------------------------------------------------------------
  258.         case 0x09:                              //r9            channel B VOL
  259.             eb = unsigned((val & 0x10)? -1 : 0);
  260.             vb = ((val & 0x0F)*2+1) & ~eb;
  261.             break;
  262.         //---------------------------------------------------------------------
  263.         case 0x0A:                              //rA            channel C VOL
  264.             ec = unsigned((val & 0x10) ? -1 : 0);
  265.             vc = ((val & 0x0F)*2+1) & ~ec;
  266.             break;
  267.         //---------------------------------------------------------------------
  268.         case 0x0B:                              //rB rC         envelopre FRQ
  269.         case 0x0C:
  270.             fe = r.envT;
  271.             break;
  272.         //---------------------------------------------------------------------
  273.     case 0x0D:                          //rD            envelopre SHAPE
  274.         r13_reloaded = 1;
  275.         te = 0;
  276.         if(r.env & 4)
  277.         {
  278.             env = 0; denv = 1;
  279.         } // attack
  280.         else
  281.         {
  282.             env = 31; denv = -1;
  283.         } // decay
  284.         break;
  285.    }
  286. //-----------------------------------------------------------------------------
  287. }
  288. //=============================================================================
  289.  
  290.  
  291. //=============================================================================
  292. unsigned char SNDCHIP::read()           //ЄЁхсєхЄёю єЄюўэхэшх !!!!
  293. {
  294.     if (activereg >= 0x10)
  295.         return 0xFF;
  296.     return reg[activereg & 0x0F];
  297. }
  298. //=============================================================================
  299.  
  300.  
  301. //=============================================================================
  302. void SNDCHIP::set_timings(unsigned system_clock_rate, unsigned chip_clock_rate, unsigned sample_rate)
  303. {
  304.    if (conf.sound.ay_chip == CHIP_YM2203) { //install YM2203 frequencies
  305.          Chip2203->OPN.ST.clock = int(conf.sound.ayfq*2);
  306.          Chip2203->OPN.ST.rate = int(conf.sound.fq) /*44100*/;
  307.          OPNPrescaler_w(&Chip2203->OPN, 1 , 1 );
  308.          //ayfq=Chip2203->OPN.ST.SSGclock;
  309.                  //┬юЄ ЄєЄ ъръ Ёрч ayfq фрхЄ єцх "єьэюцхээє■" ўрёЄюЄє, ъюЄюЁє■ ш эєцэю тч Є№ чр юёэютє.
  310.          chip_clock_rate = unsigned(Chip2203->OPN.ST.SSGclock);
  311.    } //Dexus
  312.    
  313.    chip_clock_rate /= 8;
  314.  
  315.    SNDCHIP::system_clock_rate = system_clock_rate;
  316.    SNDCHIP::chip_clock_rate = chip_clock_rate;
  317.  
  318.    mult_const = (unsigned) (((uint64_t)chip_clock_rate << MULT_C_1) / system_clock_rate);
  319.    SNDRENDER::set_timings(chip_clock_rate, sample_rate);
  320.    passed_chip_ticks = passed_clk_ticks = 0;
  321.    t = 0; ns = 0xFFFF;
  322.  
  323.    nextfmtickfloat = 0.; //Alone Coder
  324.    nextfmtick = 0; //Alone Coder
  325.    ayticks_per_fmtick = (float)chip_clock_rate/conf.sound.fq /*44100*/; //Alone Coder
  326.    FMbufMUL=(UINT16)(((float)conf.sound.ay_vol/8192 /* =0..1 */)*0.1f*65536); //Alone Coder 0.36.4
  327.  
  328.    //тюЄ ¤Єю чръюьхэўхэю є TSL
  329.    //apply_regs();              //NS
  330.    //ш эхЄ яхЁЁхшэшЎшрышчрЎшш
  331. }
  332. //=============================================================================
  333.  
  334.  
  335. //=============================================================================
  336. void SNDCHIP::set_volumes(unsigned global_vol, const SNDCHIP_VOLTAB *voltab, const SNDCHIP_PANTAB *stereo)
  337. {
  338.    for (int j = 0; j < 6; j++)
  339.       for (int i = 0; i < 32; i++)
  340.          vols[j][i] = (unsigned) (((uint64_t)global_vol * voltab->v[i] * stereo->raw[j])/(65535*100*3));
  341. }
  342. //=============================================================================
  343.  
  344.  
  345. //=============================================================================
  346. void SNDCHIP::reset(unsigned timestamp)
  347. {
  348.    activereg = 0;
  349.    for (int i = 0; i < 14; i++)
  350.        reg[i] = 0;
  351.  
  352.    if (Chip2203) YM2203ResetChip((void*)Chip2203); //Dexus
  353. /*
  354.    ayfq=Chip2203->OPN.ST.SSGclock; //Dexus
  355.    mult_const2 = ((ayfq/conf.intfq) << (MULT_C_1-3))/conf.frame; //Dexus
  356.    mult_const3 = TICK_F/2+(unsigned)((__int64)temp.snd_frame_ticks*conf.intfq*(1<<(MULT_C+3))/ayfq); //Dexus
  357.    ay_div = ((unsigned)((double)ayfq*0x10*(double)SAMPLE_T/(double)conf.sound.fq)); //Dexus
  358.    ay_div2 = (ayfq*0x100)/(conf.sound.fq/32); //Dexus
  359. */
  360.    apply_regs(timestamp);
  361. }
  362. //=============================================================================
  363.  
  364.  
  365. //=============================================================================
  366. //void SNDCHIP::apply_regs(unsigned timestamp)  //TSL
  367. //{
  368. //   for (u8 r = 0; r < 16; r++) {      //эхяюьюурхЄ
  369. //      select(r); u8 p = reg[r];      
  370. //      /* clr cached values */
  371. //      write(timestamp, p ^ 1); write(timestamp, p);
  372. //   }
  373. //}
  374.  
  375. //=============================================================================
  376. void SNDCHIP::apply_regs(unsigned timestamp)    //0.39.0
  377. {
  378.    unsigned char ar = activereg;
  379.    for (unsigned char r = 0; r < 16; r++)
  380.    {
  381.       select(r);
  382.       unsigned char p = reg[r];
  383.  
  384.       /* clr cached values */
  385.       write(timestamp, p ^ 1);
  386.       write(timestamp, p);
  387.    }
  388.    activereg = ar;
  389. }
  390. //=============================================================================
  391.  
  392.  
  393. //=============================================================================
  394. SNDCHIP::SNDCHIP()
  395. {
  396.     bitA = bitB = bitC = 0;
  397.     nextfmtick = 0; //Alone Coder
  398.     set_timings(SNDR_DEFAULT_SYSTICK_RATE, SNDR_DEFAULT_AY_RATE, SNDR_DEFAULT_SAMPLE_RATE);
  399.     Chip2203 = (YM2203 *) YM2203Init(nullptr, 0, int(conf.sound.ayfq*2), int(conf.sound.fq) /*44100*/); //Dexus
  400.     set_chip(CHIP_YM);
  401.     set_volumes(0x7FFF, SNDR_VOL_YM, SNDR_PAN_ABC);
  402.     reset();
  403. }
  404. //=============================================================================
  405.  
  406.  
  407. //=============================================================================
  408. // corresponds enum CHIP_TYPE
  409.  
  410. const char * const ay_chips[] = {       "AY-3-8910",
  411.                                         "YM2149F",
  412.                                         "YM2203"        }; //Dexus
  413.  
  414. const SNDCHIP_VOLTAB SNDR_VOL_AY_S =
  415. { { 0x0000,0x0000,0x0340,0x0340,0x04C0,0x04C0,0x06F2,0x06F2,0x0A44,0x0A44,0x0F13,0x0F13,0x1510,0x1510,0x227E,0x227E,
  416.     0x289F,0x289F,0x414E,0x414E,0x5B21,0x5B21,0x7258,0x7258,0x905E,0x905E,0xB550,0xB550,0xD7A0,0xD7A0,0xFFFF,0xFFFF } };
  417.  
  418. const SNDCHIP_VOLTAB SNDR_VOL_YM_S =
  419. { { 0x0000,0x0000,0x00EF,0x01D0,0x0290,0x032A,0x03EE,0x04D2,0x0611,0x0782,0x0912,0x0A36,0x0C31,0x0EB6,0x1130,0x13A0,
  420.     0x1751,0x1BF5,0x20E2,0x2594,0x2CA1,0x357F,0x3E45,0x475E,0x5502,0x6620,0x7730,0x8844,0xA1D2,0xC102,0xE0A2,0xFFFF } };
  421.  
  422.  
  423. //їюЄ  ш Ёрёяшёрэ√ тёх трЁшрэЄ√
  424. //эю ЁрсюЄр■Є Єюы№ъю Єх ўЄю хёЄ№ т ъюэЇшух???
  425.  
  426. const SNDCHIP_PANTAB SNDR_PAN_MONO_S =
  427. { 100,100, 100,100, 100,100 };
  428.  
  429. const SNDCHIP_PANTAB SNDR_PAN_ABC_S =
  430. { 100,10,  66,66,   10,100 };
  431.  
  432. const SNDCHIP_PANTAB SNDR_PAN_ACB_S =
  433. { 100,10,  10,100,  66,66 };
  434.  
  435. const SNDCHIP_PANTAB SNDR_PAN_BAC_S =
  436. { 66,66,   100,10,  10,100 };
  437.  
  438. const SNDCHIP_PANTAB SNDR_PAN_BCA_S =
  439. { 10,100,  100,10,  66,66 };
  440.  
  441. const SNDCHIP_PANTAB SNDR_PAN_CAB_S =
  442. { 66,66,   10,100,  100,10 };
  443.  
  444. const SNDCHIP_PANTAB SNDR_PAN_CBA_S =
  445. { 10,100,  66,66,   100,10 };
  446.