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();
