summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Wilbert Pol <wilbert@jdg.info>2008-07-29 18:29:01 +0000
committer Wilbert Pol <wilbert@jdg.info>2008-07-29 18:29:01 +0000
commitc67737a40c53c648f965839a6bed9142be22c7fe (patch)
treeb5d1ac931d065d95e024db4772df1828d391e9a7
parent3052db3fa9b2547cd04032af668cf6729497ed9b (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.c294
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;
}