PCem

changeset 111:912e602b3406

Moved PIT to common timer API.
author TomW
date Thu Jun 19 21:02:59 2014 +0100
parents 036dc3a418ac
children c5989dbbc2ce
files src/386.c src/808x.c src/ibm.h src/pit.c src/timer.c src/timer.h
diffstat 6 files changed, 87 insertions(+), 59 deletions(-) [+]
line diff
     1.1 --- a/src/386.c	Fri Jun 13 18:43:25 2014 +0100
     1.2 +++ b/src/386.c	Thu Jun 19 21:02:59 2014 +0100
     1.3 @@ -1248,6 +1248,7 @@
     1.4          {
     1.5                  cycdiff=0;
     1.6                  oldcyc=cycles;
     1.7 +                timer_start_period(cycles);
     1.8  //                pclog("%i %02X\n", ins, ram[8]);
     1.9                  while (cycdiff<100)
    1.10                  {
    1.11 @@ -1414,18 +1415,6 @@
    1.12                  
    1.13                  tsc += cycdiff;
    1.14                  
    1.15 -/*                keybsenddelay -= cycdiff;
    1.16 -                if (keybsenddelay<1)
    1.17 -                {
    1.18 -                        keybsenddelay = 1000;
    1.19 -                        keyboard_at_poll();
    1.20 -                }*/
    1.21 -                
    1.22 -                pit.c[0] -= cycdiff;
    1.23 -                pit.c[1] -= cycdiff;
    1.24 -                if (pit.gate[2]) pit.c[2] -= cycdiff;
    1.25 -                if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll();
    1.26 -
    1.27 -                timer_clock(cycdiff);
    1.28 +                timer_end_period(cycles);
    1.29          }
    1.30  }
     2.1 --- a/src/808x.c	Fri Jun 13 18:43:25 2014 +0100
     2.2 +++ b/src/808x.c	Thu Jun 19 21:02:59 2014 +0100
     2.3 @@ -798,8 +798,8 @@
     2.4          if (pit.running[1]) pit.c[1] -= diff;
     2.5          if (pit.running[2]) pit.c[2] -= diff;
     2.6          if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll();
     2.7 -        
     2.8 -        timer_clock(diff);
     2.9 +  
    2.10 +        timer_end_period(cycles);      
    2.11  }
    2.12  
    2.13  static int takeint = 0;
    2.14 @@ -1076,6 +1076,7 @@
    2.15  //                if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; }
    2.16  //                if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime);
    2.17                  cycdiff=cycles;
    2.18 +                timer_start_period(cycles);
    2.19                  current_diff = 0;
    2.20                  cycles-=nextcyc;
    2.21  //                if (instime) pclog("Cycles %i %i\n",cycles,cycdiff);
     3.1 --- a/src/ibm.h	Fri Jun 13 18:43:25 2014 +0100
     3.2 +++ b/src/ibm.h	Thu Jun 19 21:02:59 2014 +0100
     3.3 @@ -190,7 +190,7 @@
     3.4  typedef struct PIT
     3.5  {
     3.6          uint32_t l[3];
     3.7 -        double c[3];
     3.8 +        int c[3];
     3.9          uint8_t m[3];
    3.10          uint8_t ctrl,ctrls[2];
    3.11          int wp,rm[3],wm[3];
     4.1 --- a/src/pit.c	Fri Jun 13 18:43:25 2014 +0100
     4.2 +++ b/src/pit.c	Thu Jun 19 21:02:59 2014 +0100
     4.3 @@ -68,8 +68,10 @@
     4.4  
     4.5  float pit_timer0_freq()
     4.6  {
     4.7 -//        pclog("PIT timer 0 freq %04X %f %f\n",pit.l[0],(float)pit.l[0],1193182.0f/(float)pit.l[0]);
     4.8 -        return 1193182.0f/(float)pit.l[0];
     4.9 +        if (pit.l[0])
    4.10 +                return 1193182.0f/(float)pit.l[0];
    4.11 +        else
    4.12 +                return 1193182.0f/(float)0x10000;
    4.13  }
    4.14  
    4.15  static void (*pit_set_out_funcs[3])(int new_out, int old_out);
    4.16 @@ -83,12 +85,14 @@
    4.17  static void pit_load(int t)
    4.18  {
    4.19          int l = pit.l[t] ? pit.l[t] : 0x10000;
    4.20 +        timer_process();
    4.21          pit.newcount[t] = 0;
    4.22 +//        pclog("pit_load: t=%i l=%x\n", t, l);
    4.23          switch (pit.m[t])
    4.24          {
    4.25                  case 0: /*Interrupt on terminal count*/
    4.26                  pit.count[t] = l;
    4.27 -                pit.c[t] = l * PITCONST;
    4.28 +                pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
    4.29                  pit_set_out(t, 0);
    4.30                  pit.thit[t] = 0;
    4.31                  pit.enabled[t] = pit.gate[t];
    4.32 @@ -100,7 +104,7 @@
    4.33                  if (pit.initial[t])
    4.34                  {
    4.35                          pit.count[t] = l - 1;
    4.36 -                        pit.c[t] = (l - 1) * PITCONST;
    4.37 +                        pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
    4.38                          pit_set_out(t, 1);
    4.39                          pit.thit[t] = 0;
    4.40                  }
    4.41 @@ -110,11 +114,12 @@
    4.42                  if (pit.initial[t])
    4.43                  {
    4.44                          pit.count[t] = l;
    4.45 -                        pit.c[t] = ((l + 1) >> 1) * PITCONST;
    4.46 +                        pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
    4.47                          pit_set_out(t, 1);
    4.48                          pit.thit[t] = 0;
    4.49                  }
    4.50                  pit.enabled[t] = pit.gate[t];
    4.51 +//                pclog("pit_load: square wave mode c=%x\n", pit.c[t]);
    4.52                  break;
    4.53                  case 4: /*Software triggered stobe*/
    4.54                  if (!pit.thit[t] && !pit.initial[t])
    4.55 @@ -122,7 +127,7 @@
    4.56                  else
    4.57                  {
    4.58                          pit.count[t] = l;
    4.59 -                        pit.c[t] = l * PITCONST;
    4.60 +                        pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
    4.61                          pit_set_out(t, 0);
    4.62                          pit.thit[t] = 0;
    4.63                  }
    4.64 @@ -134,12 +139,14 @@
    4.65          }
    4.66          pit.initial[t] = 0;
    4.67          pit.running[t] = pit.enabled[t] && pit.using_timer[t];
    4.68 +        timer_update_outstanding();
    4.69  //        pclog("pit_load: t=%i running=%i thit=%i enabled=%i m=%i l=%x c=%g gate=%i\n", t, pit.running[t], pit.thit[t], pit.enabled[t], pit.m[t], pit.l[t], pit.c[t], pit.gate[t]);
    4.70  }
    4.71  
    4.72  void pit_set_gate(int t, int gate)
    4.73  {
    4.74          int l = pit.l[t] ? pit.l[t] : 0x10000;
    4.75 +        timer_process();
    4.76          switch (pit.m[t])
    4.77          {
    4.78                  case 0: /*Interrupt on terminal count*/
    4.79 @@ -151,7 +158,7 @@
    4.80                  if (gate && !pit.gate[t])
    4.81                  {
    4.82                          pit.count[t] = l;
    4.83 -                        pit.c[t] = l * PITCONST;
    4.84 +                        pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
    4.85                          pit_set_out(t, 0);
    4.86                          pit.thit[t] = 0;
    4.87                          pit.enabled[t] = 1;
    4.88 @@ -161,7 +168,7 @@
    4.89                  if (gate && !pit.gate[t])
    4.90                  {
    4.91                          pit.count[t] = l - 1;
    4.92 -                        pit.c[t] = (l - 1) * PITCONST;
    4.93 +                        pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
    4.94                          pit_set_out(t, 1);
    4.95                          pit.thit[t] = 0;
    4.96                  }                
    4.97 @@ -171,7 +178,7 @@
    4.98                  if (gate && !pit.gate[t])
    4.99                  {
   4.100                          pit.count[t] = l;
   4.101 -                        pit.c[t] = ((l + 1) >> 1) * PITCONST;
   4.102 +                        pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
   4.103                          pit_set_out(t, 1);
   4.104                          pit.thit[t] = 0;
   4.105                  }
   4.106 @@ -180,12 +187,14 @@
   4.107          }
   4.108          pit.gate[t] = gate;
   4.109          pit.running[t] = pit.enabled[t] && pit.using_timer[t];
   4.110 +        timer_update_outstanding();
   4.111  //        pclog("pit_set_gate: t=%i gate=%i\n", t, gate);
   4.112  }
   4.113  
   4.114  static void pit_over(int t)
   4.115  {
   4.116          int l = pit.l[t] ? pit.l[t] : 0x10000;
   4.117 +//        if (!t) pclog("pit_over: t=%i l=%x c=%x %i\n", t, pit.l[t], pit.c[t], pit.c[t] >> TIMER_SHIFT);
   4.118          switch (pit.m[t])
   4.119          {
   4.120                  case 0: /*Interrupt on terminal count*/
   4.121 @@ -194,11 +203,11 @@
   4.122                          pit_set_out(t, 1);
   4.123                  pit.thit[t] = 1;
   4.124                  pit.count[t] += 0xffff;
   4.125 -                pit.c[t] += 0xffff * PITCONST;
   4.126 +                pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
   4.127                  break;
   4.128                  case 2: /*Rate generator*/
   4.129                  pit.count[t] += l;
   4.130 -                pit.c[t] += l * PITCONST;
   4.131 +                pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST);
   4.132                  pit_set_out(t, 0);
   4.133                  pit_set_out(t, 1);
   4.134                  break;
   4.135 @@ -207,14 +216,15 @@
   4.136                  {
   4.137                          pit_set_out(t, 0);
   4.138                          pit.count[t] += (l >> 1);
   4.139 -                        pit.c[t] += (l >> 1) * PITCONST;
   4.140 +                        pit.c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST);
   4.141                  }
   4.142                  else
   4.143                  {
   4.144                          pit_set_out(t, 1);
   4.145                          pit.count[t] += ((l + 1) >> 1);
   4.146 -                        pit.c[t] = ((l + 1) >> 1) * PITCONST;
   4.147 +                        pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
   4.148                  }
   4.149 +//                if (!t) pclog("pit_over: square wave mode c=%x  %lli  %f\n", pit.c[t], tsc, PITCONST);
   4.150                  break;
   4.151                  case 4: /*Software triggered strove*/
   4.152                  if (!pit.thit[t])
   4.153 @@ -226,19 +236,19 @@
   4.154                  {
   4.155                          pit.newcount[t] = 0;
   4.156                          pit.count[t] += l;
   4.157 -                        pit.c[t] += l * PITCONST;
   4.158 +                        pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST);
   4.159                  }
   4.160                  else
   4.161                  {
   4.162                          pit.thit[t] = 1;
   4.163                          pit.count[t] += 0xffff;
   4.164 -                        pit.c[t] += 0xffff * PITCONST;
   4.165 +                        pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
   4.166                  }
   4.167                  break;
   4.168                  case 5: /*Hardware triggered strove*/
   4.169                  if (!pit.thit[t])
   4.170                  {
   4.171 -                                pit_set_out(t, 0);
   4.172 +                        pit_set_out(t, 0);
   4.173                          pit_set_out(t, 1);
   4.174                  }
   4.175                  pit.thit[t] = 1;
   4.176 @@ -249,10 +259,11 @@
   4.177  
   4.178  static int pit_read_timer(int t)
   4.179  {
   4.180 +        timer_clock();
   4.181  //        pclog("pit_read_timer: t=%i using_timer=%i m=%i\n", t, pit.using_timer[t], pit.m[t]);
   4.182          if (pit.using_timer[t])
   4.183          {
   4.184 -                int read = (pit.c[t] / PITCONST);
   4.185 +                int read = (int)((pit.c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT;
   4.186                  if (pit.m[t] == 2)
   4.187                          read++;
   4.188                  if (read < 0)
   4.189 @@ -273,7 +284,7 @@
   4.190  {
   4.191          int t;
   4.192          cycles -= (int)PITCONST;
   4.193 -//        if (val != 0x40) pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit.gate[0]);
   4.194 +//        /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit.gate[0]);
   4.195          
   4.196          switch (addr&3)
   4.197          {
   4.198 @@ -283,11 +294,11 @@
   4.199                          if (!(val&0x20))
   4.200                          {
   4.201                                  if (val & 2)
   4.202 -                                        pit.rl[0] = pit.using_timer[0] ? (pit.c[0] / PITCONST) : pit.count[0];
   4.203 +                                        pit.rl[0] = pit.using_timer[0] ? ((int)(pit.c[0] / PITCONST) >> TIMER_SHIFT) : pit.count[0];
   4.204                                  if (val & 4)
   4.205 -                                        pit.rl[1] = pit.using_timer[1] ? (pit.c[1] / PITCONST) : pit.count[1];
   4.206 +                                        pit.rl[1] = pit.using_timer[1] ? ((int)(pit.c[1] / PITCONST) >> TIMER_SHIFT) : pit.count[1];
   4.207                                  if (val & 8)
   4.208 -                                        pit.rl[2] = pit.using_timer[2] ? (pit.c[2] / PITCONST) : pit.count[2];
   4.209 +                                        pit.rl[2] = pit.using_timer[2] ? ((int)(pit.c[2] / PITCONST) >> TIMER_SHIFT) : pit.count[2];
   4.210                          }
   4.211                          return;
   4.212                  }
   4.213 @@ -440,6 +451,14 @@
   4.214                  pit_over(2);
   4.215  }
   4.216  
   4.217 +void pit_timer_over(void *p)
   4.218 +{
   4.219 +        int timer = (int) p;
   4.220 +//        pclog("pit_timer_over %i\n", timer);
   4.221 +        
   4.222 +        pit_over(timer);
   4.223 +}
   4.224 +
   4.225  void pit_clock(int t)
   4.226  {
   4.227          if (pit.thit[t] || !pit.enabled[t])
   4.228 @@ -456,12 +475,14 @@
   4.229  void pit_set_using_timer(int t, int using_timer)
   4.230  {
   4.231  //        pclog("pit_set_using_timer: t=%i using_timer=%i\n", t, using_timer);        
   4.232 +        timer_process();
   4.233          if (pit.using_timer[t] && !using_timer)
   4.234                  pit.count[t] = pit_read_timer(t);
   4.235          if (!pit.using_timer[t] && using_timer)
   4.236 -                pit.c[t] = pit.count[t] * PITCONST;
   4.237 +                pit.c[t] = (int)((pit.count[t] << TIMER_SHIFT) * PITCONST);
   4.238          pit.using_timer[t] = using_timer;
   4.239          pit.running[t] = pit.enabled[t] && pit.using_timer[t];
   4.240 +        timer_update_outstanding();
   4.241  }
   4.242  
   4.243  void pit_set_out_func(int t, void (*func)(int new_out, int old_out))
   4.244 @@ -516,7 +537,11 @@
   4.245          pit.gate[0] = pit.gate[1] = 1;
   4.246          pit.gate[2] = 0;
   4.247          pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1;
   4.248 -        
   4.249 +
   4.250 +        timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)0);
   4.251 +        timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)1);
   4.252 +        timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)2);
   4.253 +                
   4.254          pit_set_out_func(0, pit_irq0_timer);
   4.255          pit_set_out_func(1, pit_null_timer);
   4.256          pit_set_out_func(2, pit_speaker_timer);
     5.1 --- a/src/timer.c	Fri Jun 13 18:43:25 2014 +0100
     5.2 +++ b/src/timer.c	Thu Jun 19 21:02:59 2014 +0100
     5.3 @@ -25,26 +25,35 @@
     5.4  int timer_one = 1;
     5.5  	
     5.6  int timer_count = 0, timer_latch = 0;
     5.7 +int timer_start = 0;
     5.8  
     5.9  void timer_process()
    5.10  {
    5.11  	int c;
    5.12 -	
    5.13 +	int retry;
    5.14  	/*Get actual elapsed time*/
    5.15 -	timer_latch -= timer_count;
    5.16 +	int diff = timer_latch - timer_count;
    5.17  
    5.18 -	for (c = 0; c < timers_present; c++)
    5.19 -	{
    5.20 -//		pclog("timer_process : %i enable %i %X\n", c, timers[c].enable, *timers[c].enable);
    5.21 -		if (*timers[c].enable)
    5.22 -		{
    5.23 -			*timers[c].count = *timers[c].count - (timer_latch << TIMER_SHIFT);
    5.24 -			if (*timers[c].count <= 0)
    5.25 -			{
    5.26 -				timers[c].callback(timers[c].priv);
    5.27 +
    5.28 +	timer_latch = 0;
    5.29 +
    5.30 +        do
    5.31 +        {
    5.32 +                retry = 0;
    5.33 +        	for (c = 0; c < timers_present; c++)
    5.34 +                {
    5.35 +                        if (*timers[c].enable)
    5.36 +                        {
    5.37 +                                *timers[c].count = *timers[c].count - (diff << TIMER_SHIFT);
    5.38 +                                if (*timers[c].count <= 0)
    5.39 +                                        timers[c].callback(timers[c].priv);
    5.40 +                                if (*timers[c].count <= 0)
    5.41 +                                        retry = 1;
    5.42  			}
    5.43  		}
    5.44 +		diff = 0;
    5.45  	}
    5.46 +	while (retry);
    5.47  }
    5.48  
    5.49  void timer_update_outstanding()
    5.50 @@ -56,11 +65,6 @@
    5.51  		if (*timers[c].enable && *timers[c].count < timer_latch)
    5.52  			timer_latch = *timers[c].count;
    5.53  	}
    5.54 -	if (spktime < timer_latch)	timer_latch = spktime;
    5.55 -	//if (soundtime < timer_latch)	timer_latch = soundtime;
    5.56 -	//if (gustime   < timer_latch)	timer_latch = gustime;
    5.57 -	//if (gustime2  < timer_latch)	timer_latch = gustime2;
    5.58 -	//if (vidtime   < timer_latch)	timer_latch = vidtime;
    5.59  	timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)) >> TIMER_SHIFT;
    5.60  }
    5.61  
    5.62 @@ -76,7 +80,7 @@
    5.63  {
    5.64  	if (timers_present < TIMERS_MAX)
    5.65  	{
    5.66 -		pclog("timer_add : adding timer %i\n", timers_present);
    5.67 +//		pclog("timer_add : adding timer %i\n", timers_present);
    5.68  		timers[timers_present].present = 1;
    5.69  		timers[timers_present].callback = callback;
    5.70  		timers[timers_present].priv = priv;
     6.1 --- a/src/timer.h	Fri Jun 13 18:43:25 2014 +0100
     6.2 +++ b/src/timer.h	Thu Jun 19 21:02:59 2014 +0100
     6.3 @@ -1,14 +1,23 @@
     6.4 -#define timer_clock(cycles) 				\
     6.5 +extern int timer_start;
     6.6 +
     6.7 +#define timer_start_period(cycles)                      \
     6.8 +        timer_start = cycles;
     6.9 +
    6.10 +#define timer_end_period(cycles) 			\
    6.11  	do 						\
    6.12  	{						\
    6.13 -		timer_count -= cycles;			\
    6.14 +                int diff = timer_start - cycles;        \
    6.15 +		timer_count -= diff;			\
    6.16 +                timer_start = cycles;                   \
    6.17  		if (timer_count <= 0)			\
    6.18  		{					\
    6.19  			timer_process();		\
    6.20  			timer_update_outstanding();	\
    6.21  		}					\
    6.22  	} while (0)
    6.23 -	
    6.24 +
    6.25 +#define timer_clock() timer_end_period(cycles)
    6.26 +
    6.27  void timer_process();
    6.28  void timer_update_outstanding();
    6.29  void timer_reset();