diff options
| author | 2008-07-29 18:29:01 +0000 | |
|---|---|---|
| committer | 2008-07-29 18:29:01 +0000 | |
| commit | c67737a40c53c648f965839a6bed9142be22c7fe (patch) | |
| tree | b5d1ac931d065d95e024db4772df1828d391e9a7 | |
| parent | 3052db3fa9b2547cd04032af668cf6729497ed9b (diff) | |
i8051 cpu core timer updates:
- Added support for timer mode 0 (13 bit timer)
- Cleaned up timer code a bit, fixing some off-by-one errors when timers overflow.
| -rw-r--r-- | src/emu/cpu/i8051/i8051.c | 294 |
1 files changed, 153 insertions, 141 deletions
diff --git a/src/emu/cpu/i8051/i8051.c b/src/emu/cpu/i8051/i8051.c index 24650eac7bb..d19ad0a5f02 100644 --- a/src/emu/cpu/i8051/i8051.c +++ b/src/emu/cpu/i8051/i8051.c @@ -1975,198 +1975,210 @@ INLINE void update_timer(int cyc) //Note: Counting modes increment on 1 machine cycle (12 oscilator periods) - except Timer 2 in certain modes - //Update Timer 0 + /* Update Timer 0 */ if(GET_TR0) { //Determine Mode int mode = (GET_M0_1<<1) | GET_M0_0; - int overflow; - UINT16 count = 0; + UINT32 count = 0; switch(mode) { - case 0: //13 Bit Timer Mode - count = ((R_TH0<<8) | R_TL0); - overflow = 0x3fff; - //Todo - really, we update HI counter when LO counter hits 0x20 - case 1: //16 Bit Timer Mode + case 0: /* 13 Bit Timer Mode */ + count = ((R_TH0<<5) | ( R_TL0 & 0x1F ) ); + /* Update the timer */ + /* Gate Bit Set? Timer only incremented if Int0 is set! */ + if(GET_GATE0 && GET_IE0) + count += (cyc/12); + /* Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line */ + if(GET_CT0) + { + /* Not supported */ + } + /* Neither, regular timer mode */ + if(!GET_GATE0 && !GET_CT0) + count += (cyc/12); + + /* Check for overflow */ + if ( count & 0xffffe000 ) + { + SET_TF0(1); + } + /* Update new values of the counter */ + R_TH0 = (count>>5) & 0xff; + R_TL0 = count & 0x1f; + break; + case 1: /* 16 Bit Timer Mode */ count = ((R_TH0<<8) | R_TL0); - overflow = 0xffff; - //Check for overflow - if((UINT32)(count+(cyc/12))>overflow) { - //Any overflow from cycles? - cyc-= (overflow-count)*12; - count = 0; - SET_TF0(1); + /* Update the timer */ + /* Gate Bit Set? Timer only incremented if Int0 is set! */ + if(GET_GATE0 && GET_IE0) + count += (cyc/12); + /* Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line */ + if(GET_CT0) + { + /* Not supported */ } - //Update the timer - if(cyc) { - int inctimer = 0; - //Gate Bit Set? Timer only incremented if Int0 is set! - if(GET_GATE0 && GET_IE0) - inctimer = (cyc/12); - //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line - if(GET_CT0) { - //Not supported - } - //Neither, regular timer mode - if(!GET_GATE0 && !GET_CT0) - inctimer = (cyc/12); - - count+=inctimer; //Increment counter + /* Neither, regular timer mode */ + if(!GET_GATE0 && !GET_CT0) + count += (cyc/12); + + /* Check for overflow */ + if ( count & 0xffff0000 ) + { + SET_TF0(1); } - //Update new values of the counter + /* Update new values of the counter */ R_TH0 = (count>>8) & 0xff; R_TL0 = count & 0xff; break; - case 2: //8 Bit Autoreload - overflow = 0xff; + case 2: /* 8 Bit Autoreload */ count = R_TL0; - //Check for overflow - if(count+(cyc/12)>overflow) { - SET_TF0(1); - //Reload - count = R_TH0+(overflow-count); + count += (cyc/12); + /* Check for overflow */ + if ( count & 0xffffff00 ) + { + SET_TF0(1); + /* Reload timer */ + count += R_TH0; } - else - count+=(cyc/12); - //Update new values of the counter + /* Update new values of the counter */ R_TL0 = count & 0xff; break; - case 3: //Split Timer - //Split Timer 1 - overflow = 0xff; + case 3: /* Split Timer */ + /* Split Timer 1 */ count = R_TL0; - //Check for overflow - if(count+(cyc/12)>overflow) { - count = overflow-count; - SET_TF0(1); - } - else - count+=(cyc/12); - //Update new values of the counter + count += (cyc/12); + /* Check for overflow */ + if ( count & 0xffffff00 ) + { + SET_TF0(1); + } + /* Update new values of the counter */ R_TL0 = count & 0xff; - //Split Timer 2 - overflow = 0xff; - count = R_TH0; - //Check for overflow - if(count+(cyc/12)>overflow) { - count = overflow-count; - SET_TF1(1); - } - else - count+=(cyc/12); - //Update new values of the counter - R_TH0 = count & 0xff; + /* Split Timer 2 */ + count = R_TH0; + count += (cyc/12); + /* Check for overflow */ + if ( count & 0xffffff00 ) + { + SET_TF1(1); + } + /* Update new values of the counter */ + R_TH0 = count & 0xff; break; } } - //Update Timer 1 + /* Update Timer 1 */ if(GET_TR1) { - //Determine Mode + /* Determine Mode */ int mode = (GET_M1_1<<1) | GET_M1_0; - int overflow; - UINT16 count = 0; + UINT32 count = 0; switch(mode) { - case 0: //13 Bit Timer Mode - count = ((R_TH1<<8) | R_TL1); - overflow = 0x3fff; - //Todo - really, we update HI counter when LO counter hits 0x20 - case 1: //16 Bit Timer Mode + case 0: /* 13 Bit Timer Mode */ + count = ((R_TH1<<5) | ( R_TL1 & 0x1F ) ); + /* Update the timer */ + /* Gate Bit Set? Timer only incremented if Int0 is set! */ + if(GET_GATE1 && GET_IE1) + count += (cyc/12); + /* Counter Mode? Only increment on 1-0 transition of the Port 3's T1 Line */ + if(GET_CT1) + { + /* Not supported */ + } + /* Neither, regular timer mode */ + if(!GET_GATE1 && !GET_CT1) + count += (cyc/12); + + /* Check for overflow */ + if ( count & 0xffffe000 ) + { + SET_TF1(1); + } + /* Update new values of the counter */ + R_TH1 = (count>>5) & 0xff; + R_TL1 = count & 0x1f; + break; + case 1: /* 16 Bit Timer Mode */ count = ((R_TH1<<8) | R_TL1); - overflow = 0xffff; - //Check for overflow - if((UINT32)(count+(cyc/12))>overflow) { - - //TODO: Timer 1 can be set as Serial Baud Rate in the 8051 only... process bits here.. - - //Any overflow from cycles? - cyc-= (overflow-count)*12; - count = 0; - SET_TF1(1); + /* Update the timer */ + /* Gate Bit Set? Timer only incremented if Int1 is set! */ + if(GET_GATE1 && GET_IE1) + count += (cyc/12); + /* Counter Mode? Only increment on 1-0 transition of the Port 3's T1 Line */ + if(GET_CT1) + { + /* Not supported */ } - //Update the timer - if(cyc) { - int inctimer = 0; - //Gate Bit Set? Timer only incremented if Int0 is set! - if(GET_GATE1 && GET_IE1) - inctimer = (cyc/12); - //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line - if(GET_CT1) { - //Not supported - } - //Neither, regular timer mode - if(!GET_GATE1 && !GET_CT1) - inctimer = (cyc/12); + /* Neither, regular timer mode */ + if(!GET_GATE1 && !GET_CT1) + count += (cyc/12); - count+=inctimer; //Increment counter + /* Check for overflow */ + if ( count & 0xffff0000 ) + { + //TODO: Timer 1 can be set as Serial Baud Rate in the 8051 only... process bits here.. + SET_TF1(1); } - //Update new values of the counter + /* Update new values of the counter */ R_TH1 = (count>>8) & 0xff; R_TL1 = count & 0xff; break; - case 2: //8 Bit Autoreload - overflow = 0xff; + case 2: /* 8 Bit Autoreload */ count = R_TL1; - //Check for overflow - if(count+(cyc/12)>overflow) { - SET_TF1(1); - //Reload - count = R_TH1+(overflow-count); + count += (cyc/12); + /* Check for overflow */ + if ( count & 0xffffff00 ) + { + SET_TF1(1); + /* Reload timer */ + count += R_TH1; } - else - count+=(cyc/12); - //Update new values of the counter + /* Update new values of the counter */ R_TL1 = count & 0xff; break; - case 3: //Split Timer - break; } } #if (HAS_I8052 || HAS_I8752) - //Update Timer 2 + /* Update Timer 2 */ if(GET_TR2) { - int timerinc, overflow; - UINT16 count = ((R_TH2<<8) | R_TL2); - timerinc = overflow = 0; + UINT32 count = ((R_TH2<<8) | R_TL2); - //Are we in counter mode? - if(GET_CT2) { - //Not supported + /* Are we in counter mode? */ + if(GET_CT2) + { + /* Not supported */ } - //Are we in timer mode? - else { - //16 Bit Timer Mode - overflow = 0xffff; - //Timer 2 Used as Baud Generator? (For now, only *same* send/receive rates supported) + /* Are we in timer mode? */ + else + { + /* 16 Bit Timer Mode */ + /* Timer 2 Used as Baud Generator? (For now, only *same* send/receive rates supported) */ if(GET_TCLK || GET_RCLK) - timerinc = cyc/2; //Timer increments ever 1/2 cycle in baud mode + count += cyc/2; /* Timer increments every cycles/2 in baud mode */ else - //REGULAR TIMER - - timerinc = cyc/12; //Timer increments ever 1/12 cycles in normal mode - - //Check for overflow - if((UINT32)(count+timerinc)>overflow) { - //Set Interrupt flag *unless* used as baud generator - if(!GET_TCLK && !GET_RCLK) { + /* REGULAR TIMER - */ + count += cyc/12; /* Timer increments every cycles/12 in normal mode */ + + /* Check for overflow */ + if ( count & 0xffff0000 ) + { + /* Set Interrupt flag *unless* used as baud generator */ + if(!GET_TCLK && !GET_RCLK) + { SET_TF2(1); } - else { - //Update bits sent if sending & bits left to send! + else + { + /* Update bits sent if sending & bits left to send! */ if(uart.sending && uart.bits_to_send && uart.timerbaud) uart.bits_to_send-=1; } - //Auto reload? + /* Auto reload? */ if(!GET_CP) - count = ((R_RCAP2H<<8) | R_RCAP2L); //+(overflow-count); - else - count = overflow-count; - } - else { - //No overflow, just increment timer - count+=timerinc; + count += ((R_RCAP2H<<8) | R_RCAP2L); } - //Update flags + /* Update new values of the counter */ R_TH2 = (count>>8) & 0xff; R_TL2 = count & 0xff; } |
