# HG changeset patch # User TomW # Date 1403208179 -3600 # Node ID 912e602b340640d08b2351ecf2bb95b0847ca9d1 # Parent 036dc3a418acce488cc0d53e000cc07f85462469 Moved PIT to common timer API. diff -r 036dc3a418ac -r 912e602b3406 src/386.c --- a/src/386.c Fri Jun 13 18:43:25 2014 +0100 +++ b/src/386.c Thu Jun 19 21:02:59 2014 +0100 @@ -1248,6 +1248,7 @@ { cycdiff=0; oldcyc=cycles; + timer_start_period(cycles); // pclog("%i %02X\n", ins, ram[8]); while (cycdiff<100) { @@ -1414,18 +1415,6 @@ tsc += cycdiff; -/* keybsenddelay -= cycdiff; - if (keybsenddelay<1) - { - keybsenddelay = 1000; - keyboard_at_poll(); - }*/ - - pit.c[0] -= cycdiff; - pit.c[1] -= cycdiff; - if (pit.gate[2]) pit.c[2] -= cycdiff; - if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll(); - - timer_clock(cycdiff); + timer_end_period(cycles); } } diff -r 036dc3a418ac -r 912e602b3406 src/808x.c --- a/src/808x.c Fri Jun 13 18:43:25 2014 +0100 +++ b/src/808x.c Thu Jun 19 21:02:59 2014 +0100 @@ -798,8 +798,8 @@ if (pit.running[1]) pit.c[1] -= diff; if (pit.running[2]) pit.c[2] -= diff; if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll(); - - timer_clock(diff); + + timer_end_period(cycles); } static int takeint = 0; @@ -1076,6 +1076,7 @@ // if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; } // 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); cycdiff=cycles; + timer_start_period(cycles); current_diff = 0; cycles-=nextcyc; // if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); diff -r 036dc3a418ac -r 912e602b3406 src/ibm.h --- a/src/ibm.h Fri Jun 13 18:43:25 2014 +0100 +++ b/src/ibm.h Thu Jun 19 21:02:59 2014 +0100 @@ -190,7 +190,7 @@ typedef struct PIT { uint32_t l[3]; - double c[3]; + int c[3]; uint8_t m[3]; uint8_t ctrl,ctrls[2]; int wp,rm[3],wm[3]; diff -r 036dc3a418ac -r 912e602b3406 src/pit.c --- a/src/pit.c Fri Jun 13 18:43:25 2014 +0100 +++ b/src/pit.c Thu Jun 19 21:02:59 2014 +0100 @@ -68,8 +68,10 @@ float pit_timer0_freq() { -// pclog("PIT timer 0 freq %04X %f %f\n",pit.l[0],(float)pit.l[0],1193182.0f/(float)pit.l[0]); - return 1193182.0f/(float)pit.l[0]; + if (pit.l[0]) + return 1193182.0f/(float)pit.l[0]; + else + return 1193182.0f/(float)0x10000; } static void (*pit_set_out_funcs[3])(int new_out, int old_out); @@ -83,12 +85,14 @@ static void pit_load(int t) { int l = pit.l[t] ? pit.l[t] : 0x10000; + timer_process(); pit.newcount[t] = 0; +// pclog("pit_load: t=%i l=%x\n", t, l); switch (pit.m[t]) { case 0: /*Interrupt on terminal count*/ pit.count[t] = l; - pit.c[t] = l * PITCONST; + pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); pit_set_out(t, 0); pit.thit[t] = 0; pit.enabled[t] = pit.gate[t]; @@ -100,7 +104,7 @@ if (pit.initial[t]) { pit.count[t] = l - 1; - pit.c[t] = (l - 1) * PITCONST; + pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); pit_set_out(t, 1); pit.thit[t] = 0; } @@ -110,11 +114,12 @@ if (pit.initial[t]) { pit.count[t] = l; - pit.c[t] = ((l + 1) >> 1) * PITCONST; + pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); pit_set_out(t, 1); pit.thit[t] = 0; } pit.enabled[t] = pit.gate[t]; +// pclog("pit_load: square wave mode c=%x\n", pit.c[t]); break; case 4: /*Software triggered stobe*/ if (!pit.thit[t] && !pit.initial[t]) @@ -122,7 +127,7 @@ else { pit.count[t] = l; - pit.c[t] = l * PITCONST; + pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); pit_set_out(t, 0); pit.thit[t] = 0; } @@ -134,12 +139,14 @@ } pit.initial[t] = 0; pit.running[t] = pit.enabled[t] && pit.using_timer[t]; + timer_update_outstanding(); // 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]); } void pit_set_gate(int t, int gate) { int l = pit.l[t] ? pit.l[t] : 0x10000; + timer_process(); switch (pit.m[t]) { case 0: /*Interrupt on terminal count*/ @@ -151,7 +158,7 @@ if (gate && !pit.gate[t]) { pit.count[t] = l; - pit.c[t] = l * PITCONST; + pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); pit_set_out(t, 0); pit.thit[t] = 0; pit.enabled[t] = 1; @@ -161,7 +168,7 @@ if (gate && !pit.gate[t]) { pit.count[t] = l - 1; - pit.c[t] = (l - 1) * PITCONST; + pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); pit_set_out(t, 1); pit.thit[t] = 0; } @@ -171,7 +178,7 @@ if (gate && !pit.gate[t]) { pit.count[t] = l; - pit.c[t] = ((l + 1) >> 1) * PITCONST; + pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); pit_set_out(t, 1); pit.thit[t] = 0; } @@ -180,12 +187,14 @@ } pit.gate[t] = gate; pit.running[t] = pit.enabled[t] && pit.using_timer[t]; + timer_update_outstanding(); // pclog("pit_set_gate: t=%i gate=%i\n", t, gate); } static void pit_over(int t) { int l = pit.l[t] ? pit.l[t] : 0x10000; +// 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); switch (pit.m[t]) { case 0: /*Interrupt on terminal count*/ @@ -194,11 +203,11 @@ pit_set_out(t, 1); pit.thit[t] = 1; pit.count[t] += 0xffff; - pit.c[t] += 0xffff * PITCONST; + pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); break; case 2: /*Rate generator*/ pit.count[t] += l; - pit.c[t] += l * PITCONST; + pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST); pit_set_out(t, 0); pit_set_out(t, 1); break; @@ -207,14 +216,15 @@ { pit_set_out(t, 0); pit.count[t] += (l >> 1); - pit.c[t] += (l >> 1) * PITCONST; + pit.c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST); } else { pit_set_out(t, 1); pit.count[t] += ((l + 1) >> 1); - pit.c[t] = ((l + 1) >> 1) * PITCONST; + pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); } +// if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); break; case 4: /*Software triggered strove*/ if (!pit.thit[t]) @@ -226,19 +236,19 @@ { pit.newcount[t] = 0; pit.count[t] += l; - pit.c[t] += l * PITCONST; + pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST); } else { pit.thit[t] = 1; pit.count[t] += 0xffff; - pit.c[t] += 0xffff * PITCONST; + pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); } break; case 5: /*Hardware triggered strove*/ if (!pit.thit[t]) { - pit_set_out(t, 0); + pit_set_out(t, 0); pit_set_out(t, 1); } pit.thit[t] = 1; @@ -249,10 +259,11 @@ static int pit_read_timer(int t) { + timer_clock(); // pclog("pit_read_timer: t=%i using_timer=%i m=%i\n", t, pit.using_timer[t], pit.m[t]); if (pit.using_timer[t]) { - int read = (pit.c[t] / PITCONST); + int read = (int)((pit.c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT; if (pit.m[t] == 2) read++; if (read < 0) @@ -273,7 +284,7 @@ { int t; cycles -= (int)PITCONST; -// if (val != 0x40) pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit.gate[0]); +// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit.gate[0]); switch (addr&3) { @@ -283,11 +294,11 @@ if (!(val&0x20)) { if (val & 2) - pit.rl[0] = pit.using_timer[0] ? (pit.c[0] / PITCONST) : pit.count[0]; + pit.rl[0] = pit.using_timer[0] ? ((int)(pit.c[0] / PITCONST) >> TIMER_SHIFT) : pit.count[0]; if (val & 4) - pit.rl[1] = pit.using_timer[1] ? (pit.c[1] / PITCONST) : pit.count[1]; + pit.rl[1] = pit.using_timer[1] ? ((int)(pit.c[1] / PITCONST) >> TIMER_SHIFT) : pit.count[1]; if (val & 8) - pit.rl[2] = pit.using_timer[2] ? (pit.c[2] / PITCONST) : pit.count[2]; + pit.rl[2] = pit.using_timer[2] ? ((int)(pit.c[2] / PITCONST) >> TIMER_SHIFT) : pit.count[2]; } return; } @@ -440,6 +451,14 @@ pit_over(2); } +void pit_timer_over(void *p) +{ + int timer = (int) p; +// pclog("pit_timer_over %i\n", timer); + + pit_over(timer); +} + void pit_clock(int t) { if (pit.thit[t] || !pit.enabled[t]) @@ -456,12 +475,14 @@ void pit_set_using_timer(int t, int using_timer) { // pclog("pit_set_using_timer: t=%i using_timer=%i\n", t, using_timer); + timer_process(); if (pit.using_timer[t] && !using_timer) pit.count[t] = pit_read_timer(t); if (!pit.using_timer[t] && using_timer) - pit.c[t] = pit.count[t] * PITCONST; + pit.c[t] = (int)((pit.count[t] << TIMER_SHIFT) * PITCONST); pit.using_timer[t] = using_timer; pit.running[t] = pit.enabled[t] && pit.using_timer[t]; + timer_update_outstanding(); } void pit_set_out_func(int t, void (*func)(int new_out, int old_out)) @@ -516,7 +537,11 @@ pit.gate[0] = pit.gate[1] = 1; pit.gate[2] = 0; pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1; - + + timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)0); + timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)1); + timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)2); + pit_set_out_func(0, pit_irq0_timer); pit_set_out_func(1, pit_null_timer); pit_set_out_func(2, pit_speaker_timer); diff -r 036dc3a418ac -r 912e602b3406 src/timer.c --- a/src/timer.c Fri Jun 13 18:43:25 2014 +0100 +++ b/src/timer.c Thu Jun 19 21:02:59 2014 +0100 @@ -25,26 +25,35 @@ int timer_one = 1; int timer_count = 0, timer_latch = 0; +int timer_start = 0; void timer_process() { int c; - + int retry; /*Get actual elapsed time*/ - timer_latch -= timer_count; + int diff = timer_latch - timer_count; - for (c = 0; c < timers_present; c++) - { -// pclog("timer_process : %i enable %i %X\n", c, timers[c].enable, *timers[c].enable); - if (*timers[c].enable) - { - *timers[c].count = *timers[c].count - (timer_latch << TIMER_SHIFT); - if (*timers[c].count <= 0) - { - timers[c].callback(timers[c].priv); + + timer_latch = 0; + + do + { + retry = 0; + for (c = 0; c < timers_present; c++) + { + if (*timers[c].enable) + { + *timers[c].count = *timers[c].count - (diff << TIMER_SHIFT); + if (*timers[c].count <= 0) + timers[c].callback(timers[c].priv); + if (*timers[c].count <= 0) + retry = 1; } } + diff = 0; } + while (retry); } void timer_update_outstanding() @@ -56,11 +65,6 @@ if (*timers[c].enable && *timers[c].count < timer_latch) timer_latch = *timers[c].count; } - if (spktime < timer_latch) timer_latch = spktime; - //if (soundtime < timer_latch) timer_latch = soundtime; - //if (gustime < timer_latch) timer_latch = gustime; - //if (gustime2 < timer_latch) timer_latch = gustime2; - //if (vidtime < timer_latch) timer_latch = vidtime; timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)) >> TIMER_SHIFT; } @@ -76,7 +80,7 @@ { if (timers_present < TIMERS_MAX) { - pclog("timer_add : adding timer %i\n", timers_present); +// pclog("timer_add : adding timer %i\n", timers_present); timers[timers_present].present = 1; timers[timers_present].callback = callback; timers[timers_present].priv = priv; diff -r 036dc3a418ac -r 912e602b3406 src/timer.h --- a/src/timer.h Fri Jun 13 18:43:25 2014 +0100 +++ b/src/timer.h Thu Jun 19 21:02:59 2014 +0100 @@ -1,14 +1,23 @@ -#define timer_clock(cycles) \ +extern int timer_start; + +#define timer_start_period(cycles) \ + timer_start = cycles; + +#define timer_end_period(cycles) \ do \ { \ - timer_count -= cycles; \ + int diff = timer_start - cycles; \ + timer_count -= diff; \ + timer_start = cycles; \ if (timer_count <= 0) \ { \ timer_process(); \ timer_update_outstanding(); \ } \ } while (0) - + +#define timer_clock() timer_end_period(cycles) + void timer_process(); void timer_update_outstanding(); void timer_reset();