In v26, this research was done, to potentially improve sound synchronization by timing the tstate-per-scanline more accurately. When a scanline K executes more tstates than allocated, the timing module makes the next scanline K+1 "pay the debt". From the regular allocation of scanline K+1 we subtract what scanline K borrowed multiplied by a compensation factor.

The reason why scanline K+1 pays more than scanline K borrowed is that scanlines always spend their entire allocations (and possibly more).

Versions 1 through 26 have used a compensation factor of 1.5.

Since on average the Z80 CPU runs too fast (e.g. over 100.%), higher compensation factors were researched. Compensation factor 2.0 versus 1.5 noticeably decreases resyncs in most tests, but dramatically reduces performance in some tests, like Manic Miner.

==============
= CONCLUSION =
==============
Compensation factor is too "blunt" to be increased from 1.5 to even 2.0. Another method must be found to reduce sound resynchronizations. It is left unchanged in version 26.

==========
= TABLES =
==========

Long resyncs are counted separately. They are very noticeable by the user, and thus undesirable.
Table entry format:
    read-too-fast resyncs, read-too-slow resyncs, actual/expected tstates-per-frame
  
  =========================================
  = compensation factor=1.5f   (v1 to v26)=
  =========================================
  QueueTimer
                    384k                     96k                       48k
  basic             0.0, 4.0, 99.6%          0.0, 4.1, 99.7%           0.0, 4.1, 99.6%
  nipper2           0.0, 7.7, 100.2%         0.0, 7.7, 100.2%          0.0, 7.7, 100.2%
  def crown         0.0, 8.7, 100.3%         0.0, 8.7, 100.3%          0.0, 8.7, 100.4%
  manic miner       0.0, 12.6, 101.0%        0.0, 12.1, 101.0%      ** 0.0, 12.5, 101.0%
  dizzy             0.0, 9.0, 100.5%         0.0, 8.9, 100.4%          0.0, 9.1, 100.4%
  robin             0.0, 6.6, 100.0%         0.0, 6.6, 100.1%          0.0, 6.7, 100.1%
  1943              0.0, 13.5, 101.2%        0.0, 13.2, 101.2%         0.0, 13.7, 101.2%
  pingpong          0.0, 6.7, 100.1%       * 0.0, 6.7, 100.0%          0.0, 6.6, 100.0%
  mr beep           0.0, 9.8, 100.6%         0.0, 10.2, 100.6%         0.0, 10.5, 100.6%

  SDL_Timer
                    384k                     96k                       48k
  basic             5.9, 0.0, 99.6%          5.4, 0.0, 99.6%           6.1, 0.0, 99.6%
  nipper2        ** 0.0, 3.6, 100.2%       * 0.9, 2.3, 100.2%      *** 0.2, 9.0, 100.2%
  def crown         0.4, 0.3, 100.3%         0.2, 0.2, 100.3%          0.8, 0.1, 100.4%
  manic miner       0.0, 4.1, 101.0%         0.0, 3.4, 100.9%          0.0, 2.2, 101.0%
  dizzy             4.6, 23.0, 100.5%      * 1.3, 6.5, 100.5%          0.9, 0.0, 100.5%
  robin           * 1.3, 4.2, 100.1%     *** 0.3, 12.3, 100.1%      ** 0.4, 8.8, 100.1%
  1943            * 5.4, 2.1, 101.2%         0.0, 3.9, 101.2%          0.0, 4.3, 101.2%
  pingpong     **** 0.1, 13.5, 100.0%    *** 0.0, 8.5, 100.1%      *** 0.0, 9.6, 100.1%
  mr beep           0.0, 0.8, 100.7%         0.0, 0.5, 100.7%          0.0, 0.7, 100.6%

*: count of long resyncs; these are clearly noticeable by the user

  ============================
  = compensation factor=2.0f =
  ============================
  QueueTimer
                    384k                     96k                       48k
  basic             0.0, 4.0, 99.6%
  nipper2           0.0, 0.9, 99.1%
  def crown         0.0, 5.1, 99.7%
  manic miner    6* 1.7, 19.7, 98.2%
  dizzy             0.0, 0.1, 99.2%
  robin             0.0, 6.5, 100.1%
  1943              0.0, 4.8, 99.7%
  pingpong          0.0, 0.8, 99.0%
  mr beep           0.0, 5.1, 99.8%

  SDL_Timer
                    384k                     96k                       48k
  basic             4.2, 0.0, 99.6%
  nipper2        8* 4.0, 34.3, 99.2%     12* 5.8, 39.9, 99.2%      12* 6.1, 42.1, 99.1%
  def crown         
  manic miner       
  dizzy             
  robin             
  1943              
  pingpong          
  mr beep

*: count of long resyncs; these are clearly noticeable by the user

  ============================*
  = compensation factor=1.75f =
  ============================*
  QueueTimer
                    384k                     96k                       48k
  basic             0.0, 4.0, 99.6%
  nipper2           0.0, 1.8, 99.2%
  def crown         0.0, 7.0, 100.1%
  manic miner       0.0, 12.3, 100.9%
  dizzy             0.0, 8.5, 100.3%
  robin             0.0, 6.6, 100.0%
  1943              0.0, 9.8, 100.6%
  pingpong          0.0, 1.1, 99.1%
  mr beep           0.0, 8.3, 100.3%

  SDL_Timer
                    384k                     96k                       48k
  basic             
  nipper2        
  def crown         
  manic miner       
  dizzy             
  robin             
  1943              
  pingpong          awful
  mr beep

*: count of long resyncs; these are clearly noticeable by the user

  ====================================
  = compensation factor = *1.5 - 1   =
  ====================================
  QueueTimer
                    384k                     96k                       48k
  basic             
  nipper2           
  def crown         
  manic miner       
  dizzy             
  robin             
  1943              
  pingpong          
  mr beep           

  SDL_Timer
                    384k                     96k                       48k
  basic             
  nipper2        
  def crown         
  manic miner       
  dizzy             
  robin             
  1943              
  pingpong          awful
  mr beep

*: count of long resyncs; these are clearly noticeable by the user
