Annotation of hatari/src/clocks_timings.c, revision 1.1.1.4

1.1       root        1: /*
                      2:   Hatari - clocks_timings.c
                      3: 
1.1.1.2   root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   Clocks Timings for the hardware components in each supported machine type,
                      8:   as well as functions taking into account the exact length of a VBL to
                      9:   precisely emulate video/audio parts (number of VBL per sec, number of
                     10:   audio samples per VBL, ...)
                     11: 
                     12:   The video freq is not exactly 50 or 60 Hz because the number of cpu cycles
                     13:   per second is not a multiple of the number of cpu cycles per VBL.
                     14:   This can cause synchronisation errors between audio and video effects
                     15:   when both components use different clocks (eg in STE where audio DMA clock
                     16:   is not the same as the cpu clock).
                     17: 
                     18:   To get the best results, it's recommanded to set RoundVBLPerSec=false.
                     19: 
                     20:   Note that if you do so, the number of VBL won't be exactly 50 or 60 per sec
                     21:   but 50.05 or 60.04 ; if this does not work with your display, set RoundVBLPerSec=true
                     22:   to get an integer number of VBL per sec (but this should not be needed).
                     23: 
                     24: 
                     25: 
                     26: ST :
                     27:   MCLK         = 32 MHz
                     28:   SHIFTER      IN = 32 MHz                                     OUT = 16 MHz
                     29:   MMU          IN = 16 MHz                                     OUT = 8 MHz, 4 MHz
                     30:   GLUE         IN = 8 MHz                                      OUT = 2 MHz, 500 kHz
                     31:   BUS          = 8 MHz
                     32: 
                     33:   CPU 68000    IN = 8 MHz
                     34:   DMA          IN = 8 MHz
                     35:   MFP 68901    IN = 4 MHz, 2.4576 MHz (external clock)
                     36:   FDC WD1772   IN = 8 MHz
                     37:   BLITTER      IN = 8 MHz
                     38:   YM2149       IN = 2 MHz
                     39:   ACIA MC6850  IN = 500 kHz
                     40:   IKBD HD6301  IN = 1 MHZ (local clock)
                     41: 
                     42: 
                     43: STE :
                     44:   MCLK         = 32 MHz
                     45:   EXT OSC      = 8 MHZ                                         OUT = 8 MHz (SCLK), 2 MHz (CLK2)
                     46:   GST SHIFTER  IN = 32 MHz, 8 MHz (external clock SCLK)        OUT = 16 MHz, 8 MHz (FCLK=SCLK)
                     47:   GST MCU      IN = 16 MHz                                     OUT = 8 MHz (CLK8), 4 MHz (CLK4), 500 kHz (KHZ500)
                     48:   BUS          = 8 MHz
                     49: 
                     50:   CPU 68000    IN = 8 MHz (CLK8)
                     51:   DMA          IN = 8 MHz (CLK8)
                     52:   DMA AUDIO    IN = 8 MHz (SCLK)
                     53:   MFP 68901    IN = 4 MHz (CLK4), 2.4576 MHz (external clock)
                     54:   FDC WD1772   IN = 8 MHz (SCLK)
                     55:   BLITTER      IN = 8 MHz (CLK8)
                     56:   YM2149       IN = 2 MHz (CLK2)
                     57:   ACIA MC6850  IN = 500 kHz (KHZ500)
                     58:   IKBD HD6301  IN = 1 MHZ (local clock)
                     59: 
                     60: 
                     61: MEGA STE :
                     62:   MCLK         = 32 MHz
                     63:   SCLK         = 8 MHz
                     64:   GST SHIFTER  IN = 32 MHz, 8 MHz (external clock SCLK)        OUT = 16 MHz (CLK16), 8 MHz (FCLK=SCLK)
                     65:   GST MCU      IN = 16 MHz (CLK16)                             OUT = 8 MHz (CLK8), 4 MHz (CLK4), 500 kHz (KHZ500)
                     66:   BUS          = 8 MHz
                     67: 
                     68:   CPU 68000    IN = 16 MHz (CLK16)
                     69:   FPU 68881    IN = 16 MHz (CLK16)
                     70:   DMA          IN = 8 MHz (CLK8)
                     71:   DMA AUDIO    IN = 8 MHz (SCLK)
                     72:   MFP 68901    IN = 4 MHz (CLK4), 2.4576 MHz (external clock)
                     73:   FDC WD1772   IN = 8 MHz (SCLK)
                     74:   BLITTER      IN = 8 MHz (CLK8)
                     75:   YM2149       IN = 2 MHz (CLK2 = SCLK / 4)
                     76:   ACIA MC6850  IN = 500 kHz (KHZ500)
                     77:   IKBD HD6301  IN = 1 MHZ (local clock)
                     78: 
                     79: 
                     80: TT :
                     81:   MCLK         = 32 MHz (CLK32)
                     82:   TT VIDEO     IN = 32 MHz (CLK32)                             OUT = 16 MHz (CLK16), 4 MHz (CLK4), 2 MHz (CLK2)
                     83:   GST MCU      IN = 16 MHz (CLK16A), 2 MHz (CLK2)              OUT = 8 MHz (CLK8), 8 MHz (FCCLK), 1 MHz (CLKE), 500 kHz (CLKX5)
                     84:   BUS          = 16 MHz
                     85: 
                     86:   CPU 68030    IN = 32 MHz (CLK32)
                     87:   FPU 68882    IN = 32 MHz (CLK32)
                     88:   DMA          IN = 8 MHz (CLK8)
                     89:   SND SHIFTER  IN = 16 MHz (CLK16F), 2 MHz (CLK2)              OUT = ? MHz (FCLK)
                     90:   MFP 68901    IN = 4 MHz (CLK4), 2.4576 MHz (external clock)  NOTE : TT has 2 MFPs 68901
                     91:   FDC WD1772   IN = 8 MHz (FCCLK)
                     92:   BLITTER      NOT AVAILABLE
                     93:   YM2149       IN = 2 MHz (CLK2)
                     94:   ACIA MC6850  IN = 500 kHz (CLKX5)
                     95:   IKBD HD6301  IN = 1 MHZ (local clock)
                     96: 
                     97: 
                     98: FALCON :
                     99:   MCLK         = 32 MHz (CLK32)
                    100:   VIDEL        IN      = 32 MHz (VID32MHZ), 25 MHz (25K)
                    101:   COMBEL       IN = 32 MHz (CLK32)                             OUT = 4 MHz (CLK4), 500 kHz (KHZ500)
                    102:   BUS          = 16 MHz
                    103: 
                    104:   CPU 68030    IN = 16 MHz (CPUCLKB)
                    105:   FPU 68882    IN = 16 MHz (CPUCLKA)
                    106:   DMA          IN = 8 MHz (CLK8)
                    107:   CODEC                IN = 25 MHz (25K)
                    108:   MFP 68901    IN = 4 MHz (CLK4), 2.4576 MHz (external clock)
                    109:   FDC AJAX     IN = 16 MHz (FCCLK)
                    110:   BLITTER      IN = 16 MHz
                    111:   YM3439       IN = 2 MHz (CLK2)
                    112:   ACIA MC6850  IN = 500 kHz (KHZ500)
                    113:   IKBD HD6301  IN = 1 MHZ (local clock)
                    114: 
                    115:   DSP 56001    IN = 32 MHz (DSP_32M)
                    116: 
                    117: */
                    118: 
                    119: 
                    120: const char ClocksTimings_fileid[] = "Hatari clocks_timings.c : " __DATE__ " " __TIME__;
                    121: 
                    122: #include <SDL.h>
                    123: #include <SDL_endian.h>
                    124: 
                    125: #include "main.h"
                    126: #include "configuration.h"
                    127: #include "log.h"
                    128: #include "clocks_timings.h"
1.1.1.4 ! root      129: #include "m68000.h"
1.1       root      130: 
                    131: 
                    132: 
                    133: /* The possible master frequencies used in the different machines */
                    134: /* depending on PAL/NTSC version. */
                    135: 
                    136: #define ATARI_STF_PAL_MCLK             32084988                        /* CPU_Freq = 8.021247 MHz */
                    137: #define ATARI_STF_NTSC_MCLK            32042400                        /* CPU_Freq = 8.010600 MHz */
                    138: #define ATARI_STF_CYCLES_PER_VBL_PAL   160256                          /* 512 cycles * 313 lines */
                    139: #define ATARI_STF_CYCLES_PER_VBL_NTSC  133604                          /* 508 cycles * 263 lines */
                    140: #define ATARI_STF_CYCLES_PER_VBL_HI    112224                          /* 224 cycles * 501 lines */
                    141: 
                    142: #define ATARI_STE_PAL_MCLK             32084988                        /* CPU_Freq = 8.021247 MHz */
                    143: #define ATARI_STE_NTSC_MCLK            32215905                        /* CPU_Freq = 8.05397625 MHz */
                    144: #define ATARI_STE_EXT_OSC              8010613                         /* OSC U303 */
                    145: #define ATARI_STE_CYCLES_PER_VBL_PAL   160256                          /* 512 cycles * 313 lines */
                    146: #define ATARI_STE_CYCLES_PER_VBL_NTSC  133604                          /* 508 cycles * 263 lines */
                    147: #define ATARI_STE_CYCLES_PER_VBL_HI    112224                          /* 224 cycles * 501 lines */
                    148: 
                    149: #define ATARI_MEGA_STE_PAL_MCLK                32084988                        /* CPU_Freq = 16.042494 MHz */
                    150: #define ATARI_MEGA_STE_NTSC_MCLK       32215905                        /* CPU_Freq = 16.1079525 MHz */
                    151: #define ATARI_MEGA_STE_EXT_OSC         16021226                        /* OSC U408 */
                    152: 
                    153: #define ATARI_TT_PAL_MCLK              32084988                        /* CPU_Freq = 32.084988 MHz */
                    154: #define ATARI_TT_NTSC_MCLK             32215905                        /* CPU_Freq = 32.215905 MHz */
                    155: 
                    156: #define ATARI_FALCON_PAL_MCLK          32084988                        /* CPU_Freq = 16.042494 MHz */
                    157: #define ATARI_FALCON_NTSC_MCLK         32215905                        /* CPU_Freq = 16.1079525 MHz */
                    158: #define ATARI_FALCON_25M_CLK           25175000
                    159: 
                    160: #define ATARI_MFP_XTAL                 2457600                         /* external clock for the MFP */
                    161: #define ATARI_IKBD_CLK                 1000000                         /* clock of the HD6301 ikbd cpu */
                    162: 
                    163: 
                    164: 
                    165: CLOCKS_STRUCT  MachineClocks;
                    166: 
                    167: 
                    168: bool   RoundVBLPerSec = false;                                         /* if false, don't round number of VBL to 50/60 Hz */
                    169:                                                                        /* but compute the exact value based on cpu/video clocks */
                    170: 
                    171: 
                    172: 
                    173: 
                    174: /*--------------------------------------------------------------------------*/
                    175: /**
                    176:  * Initialize all the clocks informations related to a specific machine type.
                    177:  * We consider the machine is running with PAL clocks.
                    178:  */
                    179: 
                    180: void   ClocksTimings_InitMachine ( MACHINETYPE MachineType )
                    181: {
1.1.1.4 ! root      182: //fprintf ( stderr , "clock init mach=%d shift=%d\n" , MachineType , nCpuFreqShift );
1.1       root      183:        memset ( (void *)&MachineClocks , 0 , sizeof ( MachineClocks ) );
                    184: 
1.1.1.3   root      185:        if (MachineType == MACHINE_ST || MachineType == MACHINE_MEGA_ST)
1.1       root      186:        {
                    187:                int     CLK16, CLK8, CLK4, CLK2, CLK500;
                    188: 
                    189:                MachineClocks.MCLK_Freq         = ATARI_STF_PAL_MCLK;                   /* 32.084988 MHz */
                    190: 
                    191:                MachineClocks.SHIFTER_Freq      = MachineClocks.MCLK_Freq;              /* 32 MHz */
                    192:                CLK16                           = MachineClocks.SHIFTER_Freq / 2;
                    193: 
                    194:                MachineClocks.MMU_Freq          = CLK16;                                /* 16 MHz */
                    195:                CLK8                            = MachineClocks.MMU_Freq / 2;
                    196:                CLK4                            = MachineClocks.MMU_Freq / 4;
                    197: 
                    198:                MachineClocks.GLUE_Freq         = CLK8;                                 /* 8 MHz */
                    199:                CLK2                            = MachineClocks.GLUE_Freq / 4;
                    200:                CLK500                          = MachineClocks.GLUE_Freq / 16;
                    201: 
                    202:                MachineClocks.BUS_Freq          = CLK8;                                 /* 8 MHz */
                    203: 
                    204:                MachineClocks.CPU_Freq          = CLK8;                                 /* 8 MHz */
                    205:                MachineClocks.DMA_Freq          = CLK8;                                 /* 8 MHz */
                    206:                MachineClocks.MFP_Freq          = CLK4;                                 /* 4 MHz */
                    207:                MachineClocks.MFP_Timer_Freq    = ATARI_MFP_XTAL;                       /* 2.4576 MHz (XTAL)*/
                    208:                MachineClocks.FDC_Freq          = CLK8;                                 /* 8 MHz */
                    209:                MachineClocks.BLITTER_Freq      = CLK8;                                 /* 8 MHz */
                    210:                MachineClocks.YM_Freq           = CLK2;                                 /* 2 MHz */;
                    211:                MachineClocks.ACIA_Freq         = CLK500;                               /* 500 kHz */
                    212:                MachineClocks.IKBD_Freq         = ATARI_IKBD_CLK;                       /* 1 MHz */
                    213:        }
                    214: 
                    215:        else if ( MachineType == MACHINE_STE )
                    216:        {
                    217:                int     SCLK, CLK16, CLK8, CLK4, CLK2, KHZ500;
                    218:                //int   FCLK;                                                           /* not used (audio filters) */
                    219: 
                    220:                MachineClocks.MCLK_Freq         = ATARI_STE_PAL_MCLK;                   /* 32.084988 MHz */
                    221:                SCLK                            = ATARI_STE_EXT_OSC;                    /* 8.010613 MHz (SCLK) */
                    222:                CLK2                            = SCLK / 4;
                    223: 
                    224:                MachineClocks.SHIFTER_Freq      = MachineClocks.MCLK_Freq;              /* 32 MHz */
                    225:                CLK16                           = MachineClocks.SHIFTER_Freq / 2;
                    226:                //FCLK                          = SCLK;
                    227: 
                    228:                MachineClocks.MCU_Freq          = CLK16;                                /* 16 MHz */
                    229:                CLK8                            = MachineClocks.MCU_Freq / 2;
                    230:                CLK4                            = MachineClocks.MCU_Freq / 4;
                    231:                KHZ500                          = MachineClocks.MCU_Freq / 32;
                    232: 
                    233:                MachineClocks.BUS_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    234: 
                    235:                MachineClocks.CPU_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    236:                MachineClocks.DMA_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    237:                MachineClocks.DMA_Audio_Freq    = SCLK;                                 /* 8 MHz (SCLK) */
                    238:                MachineClocks.MFP_Freq          = CLK4;                                 /* 4 MHz (CLK4) */
                    239:                MachineClocks.MFP_Timer_Freq    = ATARI_MFP_XTAL;                       /* 2.4576 MHz (XTAL)*/
                    240:                MachineClocks.FDC_Freq          = SCLK;                                 /* 8 MHz (SCLK) */
                    241:                MachineClocks.BLITTER_Freq      = CLK8;                                 /* 8 MHz (CLK8) */
                    242:                MachineClocks.YM_Freq           = CLK2;                                 /* 2 MHz (CLK2) */
                    243:                MachineClocks.ACIA_Freq         = KHZ500;                               /* 500 kHz (KHZ500) */
                    244:                MachineClocks.IKBD_Freq         = ATARI_IKBD_CLK;                       /* 1 MHz */
                    245:        }
                    246: 
                    247:        else if ( MachineType == MACHINE_MEGA_STE )
                    248:        {
                    249:                int     SCLK, CLK16, CLK8, CLK4, CLK2, KHZ500;
                    250:                //int   FCLK;                                                           /* not used (audio filters) */
                    251: 
                    252:                MachineClocks.MCLK_Freq         = ATARI_MEGA_STE_PAL_MCLK;              /* 32.084988 MHz */
                    253:                SCLK                            = ATARI_MEGA_STE_EXT_OSC / 2;           /* 16.021226 MHz / 2 = 8.010613 MHz */
                    254:                CLK2                            = SCLK / 4;
                    255: 
                    256:                MachineClocks.SHIFTER_Freq      = MachineClocks.MCLK_Freq;              /* 32 MHz */
                    257:                CLK16                           = MachineClocks.SHIFTER_Freq / 2;
                    258:                //FCLK                          = SCLK;
                    259: 
                    260:                MachineClocks.MCU_Freq          = CLK16;                                /* 16 MHz (CLK16) */
                    261:                CLK8                            = MachineClocks.MCU_Freq / 2;
                    262:                CLK4                            = MachineClocks.MCU_Freq / 4;
                    263:                KHZ500                          = MachineClocks.MCU_Freq / 32;
                    264: 
                    265:                MachineClocks.BUS_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    266: 
1.1.1.3   root      267:                /* Special case : the Mega STE has an internal 16 MHz CPU clock */
                    268:                /* but it can be set to 8 MHz for compatibility with STE using $FF8E21 */
1.1.1.4 ! root      269:                MachineClocks.CPU_Freq          = CLK16;                                /* 16 MHz (CLK16) */
1.1       root      270:                MachineClocks.FPU_Freq          = CLK16;                                /* 16 MHz (CLK16) */
                    271:                MachineClocks.DMA_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    272:                MachineClocks.DMA_Audio_Freq    = SCLK;                                 /* 8 MHz (SCLK) */
                    273:                MachineClocks.MFP_Freq          = CLK4;                                 /* 4 MHz (CLK4) */
                    274:                MachineClocks.MFP_Timer_Freq    = ATARI_MFP_XTAL;                       /* 2.4576 MHz (XTAL)*/
                    275:                MachineClocks.FDC_Freq          = SCLK;                                 /* 8 MHz (SCLK) */
                    276:                MachineClocks.BLITTER_Freq      = CLK8;                                 /* 8 MHz (CLK8) */
                    277:                MachineClocks.YM_Freq           = CLK2;                                 /* 2 MHz (CLK2) */
                    278:                MachineClocks.ACIA_Freq         = KHZ500;                               /* 500 kHz (KHZ500) */
                    279:                MachineClocks.IKBD_Freq         = ATARI_IKBD_CLK;                       /* 1 MHz */
                    280:        }
                    281: 
                    282:        else if ( MachineType == MACHINE_TT )
                    283:        {
                    284:                int     CLK32, CLK16, CLK8, FCCLK, CLK4, CLK2, CLKX5;
                    285: 
                    286:                MachineClocks.MCLK_Freq         = ATARI_TT_PAL_MCLK;                    /* 32.084988 MHz */
                    287:                CLK32                           = MachineClocks.MCLK_Freq;
                    288: 
                    289:                MachineClocks.TTVIDEO_Freq      = MachineClocks.MCLK_Freq;              /* 32 MHz */
                    290:                CLK16                           = MachineClocks.TTVIDEO_Freq / 2;
                    291:                CLK4                            = MachineClocks.TTVIDEO_Freq / 8;
                    292:                CLK2                            = MachineClocks.TTVIDEO_Freq / 16;
                    293: 
                    294:                MachineClocks.MCU_Freq          = CLK16;                                /* 16 MHz (CLK16A) */
                    295:                CLK8                            = MachineClocks.MCU_Freq / 2;
                    296:                FCCLK                           = MachineClocks.MCU_Freq / 2;
                    297:                CLKX5                           = MachineClocks.MCU_Freq / 32;
                    298: 
                    299:                MachineClocks.BUS_Freq          = CLK16;                                /* 16 MHz (CLK16) */
                    300: 
                    301:                MachineClocks.CPU_Freq          = CLK32;                                /* 32 MHz (CLK32) */
                    302:                MachineClocks.FPU_Freq          = CLK32;                                /* 32 MHz (CLK32) */
                    303:                MachineClocks.DMA_Freq          = CLK8;                                 /* 8 MHz (CLK8) */
                    304:                MachineClocks.DMA_Audio_Freq    = CLK16;                                /* 16 MHz (CLK16) SND SHIFTER */
                    305:                MachineClocks.MFP_Freq          = CLK4;                                 /* 4 MHz (CLK4) */
                    306:                MachineClocks.MFP_Timer_Freq    = ATARI_MFP_XTAL;                       /* 2.4576 MHz (XTAL)*/
                    307:                MachineClocks.FDC_Freq          = FCCLK;                                /* 8 MHz (FCCLK) */
                    308:                MachineClocks.BLITTER_Freq      = 0;                                    /* No blitter in TT */
                    309:                MachineClocks.YM_Freq           = CLK2;                                 /* 2 MHz (CLK2) */
                    310:                MachineClocks.ACIA_Freq         = CLKX5;                                /* 500 kHz (CLKX5) */
                    311:                MachineClocks.IKBD_Freq         = ATARI_IKBD_CLK;                       /* 1 MHz */
                    312:        }
                    313: 
                    314:        else if ( MachineType == MACHINE_FALCON )
                    315:        {
                    316:                /* TODO : need more docs for Falcon's clocks */
                    317:                int     CLK32, CLK25, CLK16, FCCLK, CLK4, CLK2, KHZ500;
                    318: 
                    319:                MachineClocks.MCLK_Freq         = ATARI_FALCON_PAL_MCLK;                /* 32.084988 MHz */
                    320:                CLK32                           = MachineClocks.MCLK_Freq;
                    321:                CLK25                           = ATARI_FALCON_25M_CLK;
                    322:                CLK16                           = CLK32 / 2;
                    323:                CLK2                            = CLK32 / 16;
                    324:                FCCLK                           = CLK16;
                    325: 
                    326:                MachineClocks.VIDEL_Freq        = CLK32;                                /* 32 MHz */
                    327: 
                    328:                MachineClocks.COMBEL_Freq       = CLK32;                                /* 16 MHz (CLK16A) */
                    329:                CLK4                            = MachineClocks.COMBEL_Freq / 8;
                    330:                KHZ500                          = MachineClocks.COMBEL_Freq / 64;
                    331: 
                    332:                MachineClocks.BUS_Freq          = CLK16;                                /* 16 MHz (CPUCLK16A) */
                    333:                MachineClocks.CPU_Freq          = CLK16;                                /* 16 MHz (CPUCLK16B) */
                    334:                MachineClocks.FPU_Freq          = CLK16;                                /* 16 MHz (CLK32) */
                    335:                MachineClocks.DSP_Freq          = CLK32;                                /* 32 MHz */
                    336:                MachineClocks.DMA_Freq          = CLK16;                                /* 16 MHz (CLK16) ? */
                    337:                MachineClocks.CODEC_Freq        = CLK25;                                /* 25 MHz (CLK25) */
                    338:                MachineClocks.MFP_Freq          = CLK4;                                 /* 4 MHz (CLK4) */
                    339:                MachineClocks.MFP_Timer_Freq    = ATARI_MFP_XTAL;                       /* 2.4576 MHz (XTAL)*/
                    340:                MachineClocks.FDC_Freq          = FCCLK;                                /* 16 MHz (FCCLK) ? */
                    341:                MachineClocks.BLITTER_Freq      = CLK16;                                /* 16 MHz */
                    342:                MachineClocks.YM_Freq           = CLK2;                                 /* 2 MHz (CLK2) */
                    343:                MachineClocks.ACIA_Freq         = KHZ500;                               /* 500 kHz (KHZ500) */
                    344:                MachineClocks.IKBD_Freq         = ATARI_IKBD_CLK;                       /* 1 MHz */
                    345:        }
                    346: 
                    347: 
1.1.1.4 ! root      348:        /* Update some other variables depending on the current nCpuFreqShift */
        !           349:        ClocksTimings_UpdateCpuFreqEmul ( MachineType , nCpuFreqShift );
1.1       root      350: }
                    351: 
                    352: 
                    353: 
                    354: 
                    355: /*-----------------------------------------------------------------------------------------*/
                    356: /**
1.1.1.4 ! root      357:  * Update the number of emulated cycles per second for the current CPU settings, depending on the
        !           358:  * base CPU freq in MachineClocks.CPU_Freq and nCpuFreqShift
        !           359:  *
        !           360:  * We use CPU_Freq as a base (instead of fixed values of 8, 16 or 32 MHz) to handle different CPU
        !           361:  * clocks in case the machine is a PAL or NTSC model for example (in which cases CPU_Freq
        !           362:  * values are slightly different)
1.1       root      363:  */
1.1.1.4 ! root      364: void   ClocksTimings_UpdateCpuFreqEmul ( MACHINETYPE MachineType , int nCpuFreqShift )
        !           365: {
        !           366:        Uint32 Cpu_Freq_Emul;
        !           367: 
        !           368:        Cpu_Freq_Emul = MachineClocks.CPU_Freq;
        !           369: 
        !           370:        /* Machines where the base CPU is 8 MHz */
        !           371:        if (MachineType == MACHINE_ST || MachineType == MACHINE_MEGA_ST
        !           372:            || MachineType == MACHINE_STE)
        !           373:        {
        !           374:                Cpu_Freq_Emul <<= nCpuFreqShift;                        /* 8, 16 or 32 MHz */
        !           375:        }
        !           376: 
        !           377:        /* Machines where the base CPU is 16 MHz */
        !           378:        else if (MachineType == MACHINE_MEGA_STE || MachineType == MACHINE_FALCON )
        !           379:        {
        !           380:                if ( nCpuFreqShift == 0 )       Cpu_Freq_Emul >>= 1;    /*  8 MHz */
        !           381:                else if ( nCpuFreqShift == 2 )  Cpu_Freq_Emul <<= 1;    /* 32 MHz */
        !           382:        }
        !           383: 
        !           384:        /* Machines where the base CPU is 32 MHz */
        !           385:        else if (MachineType == MACHINE_TT )
        !           386:        {
        !           387:                if ( nCpuFreqShift == 0 )       Cpu_Freq_Emul >>= 2;    /*  8 MHz */
        !           388:                else if ( nCpuFreqShift == 1 )  Cpu_Freq_Emul >>= 1;    /* 16 MHz */
        !           389:        }
1.1       root      390: 
1.1.1.4 ! root      391:        MachineClocks.CPU_Freq_Emul = Cpu_Freq_Emul;
        !           392: //fprintf ( stderr , "clock cpu freq mach=%d shift=%d base=%d -> %d\n" , MachineType , nCpuFreqShift , MachineClocks.CPU_Freq , MachineClocks.CPU_Freq_Emul );
        !           393: }
        !           394: 
        !           395: 
        !           396: 
        !           397: 
        !           398: /*-----------------------------------------------------------------------------------------*/
        !           399: /**
        !           400:  * Return the number of cycles per VBL, depending on the video settings and the simulated cpu freq.
        !           401:  * This value is only precisely known for STF/STE running at 50, 60 or 71 Hz.
        !           402:  * For the other machines, we return CPU_Freq_Emul / ScreenRefreshRate
        !           403:  */
1.1       root      404: Uint32 ClocksTimings_GetCyclesPerVBL ( MACHINETYPE MachineType , int ScreenRefreshRate )
                    405: {
                    406:        Uint32  CyclesPerVBL;
                    407: 
1.1.1.4 ! root      408:        /* STF and STE have the same numbers of cycles per VBL (numbers are for an 8 MHz CPU) */
1.1.1.3   root      409:        if (MachineType == MACHINE_ST || MachineType == MACHINE_MEGA_ST
                    410:            || MachineType == MACHINE_STE || MachineType == MACHINE_MEGA_STE)
1.1       root      411:        {
                    412:                if ( ScreenRefreshRate == 50 )
                    413:                        CyclesPerVBL = ATARI_STF_CYCLES_PER_VBL_PAL;
                    414:                else if ( ScreenRefreshRate == 60 )
                    415:                        CyclesPerVBL = ATARI_STF_CYCLES_PER_VBL_NTSC;
                    416:                else if ( ScreenRefreshRate == 71 )
                    417:                        CyclesPerVBL = ATARI_STF_CYCLES_PER_VBL_HI;
                    418:                else
1.1.1.4 ! root      419:                        CyclesPerVBL = MachineClocks.CPU_Freq / ScreenRefreshRate;      /* unknown refresh rate, should not happen */
1.1       root      420: 
1.1.1.4 ! root      421:                /* At this point CyclesPerVBL is the number of cycles per VBL for a 8 MHz CPU */
        !           422:                /* We need to apply nCpuFreqShift to get the number of cycles at the currently simulated CPU speed (8, 16 or 32 MHz) */
        !           423:                CyclesPerVBL <<= nCpuFreqShift;
        !           424:        }
1.1       root      425: 
1.1.1.4 ! root      426:        /* For machines where cpu freq can be changed, the number of cycles per VBL is not constant */
        !           427:        else                                                                            /* MACHINE_TT or MACHINE_FALCON */
        !           428:                CyclesPerVBL = MachineClocks.CPU_Freq_Emul / ScreenRefreshRate;
1.1       root      429: 
1.1.1.4 ! root      430: //fprintf ( stderr , "clock cycles per vbl %d %d -> %d\n" , MachineType , ScreenRefreshRate , CyclesPerVBL );
1.1       root      431:        return CyclesPerVBL;
                    432: }
                    433: 
                    434: 
                    435: 
                    436: 
                    437: /*-----------------------------------------------------------------------------------------*/
                    438: /**
1.1.1.4 ! root      439:  * Return the number of VBL per second, depending on the video settings and the simulated cpu freq.
1.1       root      440:  * Since the cpu freq is not an exact multiple of the number of cycles per VBL, the real
                    441:  * value slightly differs from the usual 50/60 Hz.
1.1.1.4 ! root      442:  * Precise (not rounded) values are needed in STE mode to synchronize cpu and dma sound (as they both use
1.1       root      443:  * 2 different clocks).
                    444:  * example for STF/STE :
                    445:  *     PAL  STF/STE video PAL :        50.053 VBL/sec
                    446:  *     PAL  STF/STE video NTSC :       60.037 VBL/sec
                    447:  *     NTSC STF/STE video PAL :        49.986 VBL/sec
                    448:  *     NTSC STF/STE video NTSC :       59.958 VBL/sec
                    449:  *
                    450:  * The returned number of VBL per sec is << 24 (=CLOCKS_TIMINGS_SHIFT_VBL) to simulate floating point using Uint32.
                    451:  */
                    452: Uint32 ClocksTimings_GetVBLPerSec ( MACHINETYPE MachineType , int ScreenRefreshRate )
                    453: {
                    454:        Uint32  VBLPerSec;                                                      /* Upper 8 bits are for int part, 24 lower bits for float part */
                    455: 
                    456: 
1.1.1.4 ! root      457:        if ( RoundVBLPerSec == true )
1.1       root      458:        {
1.1.1.4 ! root      459:                VBLPerSec = ScreenRefreshRate << CLOCKS_TIMINGS_SHIFT_VBL;
1.1       root      460:        }
                    461: 
1.1.1.4 ! root      462:        else
        !           463:        {
        !           464:                VBLPerSec = ( (Sint64)MachineClocks.CPU_Freq_Emul << CLOCKS_TIMINGS_SHIFT_VBL ) / ClocksTimings_GetCyclesPerVBL ( MachineType , ScreenRefreshRate );
        !           465:        }
1.1       root      466: 
1.1.1.4 ! root      467: //fprintf ( stderr , "clock vbl per sec %d %d %d -> %d\n" , MachineType , MachineClocks.CPU_Freq_Emul , ScreenRefreshRate , VBLPerSec );
1.1       root      468:        return VBLPerSec;
                    469: }
                    470: 
                    471: 
                    472: 
                    473: 
                    474: /*-----------------------------------------------------------------------------------------*/
                    475: /**
                    476:  * Return the length in microsec of a VBL (opposite function of ClocksTimings_GetVBLPerSec)
                    477:  * We use precise values only in STF/STE mode, else we use 1000000 / ScreenRefreshRate.
                    478:  * example for STF/STE :
                    479:  *     PAL  STF/STE video PAL :        19979 micro sec  (instead of 20000 for 50 Hz)
                    480:  *     PAL  STF/STE video NTSC :       16656 micro sec  (instead of 16667 for 60 Hz)
                    481:  */
                    482: Uint32 ClocksTimings_GetVBLDuration_micro ( MACHINETYPE MachineType , int ScreenRefreshRate )
                    483: {
                    484:        Uint32  VBLDuration_micro;
                    485: 
1.1.1.4 ! root      486:        if ( RoundVBLPerSec == true )
1.1       root      487:        {
1.1.1.4 ! root      488:                VBLDuration_micro = (Uint32) (1000000.0 / ScreenRefreshRate + 0.5);
1.1       root      489:        }
                    490: 
1.1.1.4 ! root      491:        else
        !           492:        {
        !           493:                VBLDuration_micro = (Uint32) (1000000.0 * ClocksTimings_GetCyclesPerVBL ( MachineType , ScreenRefreshRate ) / MachineClocks.CPU_Freq_Emul + 0.5);
        !           494:        }
1.1       root      495: 
1.1.1.4 ! root      496: //fprintf ( stderr , "clock vbl duration %d %d %d -> %d\n" , MachineType , MachineClocks.CPU_Freq_Emul , ScreenRefreshRate , VBLDuration_micro );
1.1       root      497:        return VBLDuration_micro;
                    498: }
                    499: 
                    500: 
                    501: 
                    502: 
                    503: /*-----------------------------------------------------------------------------------------*/
                    504: /**
                    505:  * Return the number of samples needed to emulate the sound that was produced during one VBL.
                    506:  * This depends on the chosen audio output frequency, as well as the VBL's duration,
                    507:  *
                    508:  * We use precise values only in STF/STE mode, else we use AudioFreq/ScreenRefreshRate.
                    509:  *
                    510:  * The returned number of samples per VBL is << 28 to simulate maximum precision using
                    511:  * 64 bits integers (lower 28 bits are for the floating point part).
                    512:  * example for STF/STE with emulation's audio freq = 44100 :
                    513:  *     PAL  STF/STE video PAL :        881.07 samples per VBL  (instead of 882 for 50 Hz)
                    514:  *                                     44053.56 samples for 50 VBLs (instead of 44100 for 1 sec at 50 Hz)
                    515:  */
                    516: Sint64 ClocksTimings_GetSamplesPerVBL ( MACHINETYPE MachineType , int ScreenRefreshRate , int AudioFreq )
                    517: {
                    518:        Sint64  SamplesPerVBL;
                    519: 
1.1.1.4 ! root      520:        if ( RoundVBLPerSec == true )
1.1       root      521:        {
1.1.1.4 ! root      522:                SamplesPerVBL = ( ((Sint64)AudioFreq) << 28 ) / ScreenRefreshRate;
1.1       root      523:        }
                    524: 
1.1.1.4 ! root      525:        else
        !           526:        {
        !           527:                SamplesPerVBL = ( ((Sint64)AudioFreq * ClocksTimings_GetCyclesPerVBL ( MachineType , ScreenRefreshRate ) ) << 28 ) / MachineClocks.CPU_Freq_Emul;
        !           528:        }
1.1       root      529: 
1.1.1.4 ! root      530: //fprintf ( stderr , "clock sample per vbl %d %d %d -> %ld\n" , MachineType , MachineClocks.CPU_Freq_Emul , AudioFreq , SamplesPerVBL );
1.1       root      531:        return SamplesPerVBL;
                    532: }
                    533: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.