src/emu/cpu/i8051/i8051.c
| r2994 | r2995 | |
| 1975 | 1975 | |
| 1976 | 1976 | //Note: Counting modes increment on 1 machine cycle (12 oscilator periods) - except Timer 2 in certain modes |
| 1977 | 1977 | |
| 1978 | | //Update Timer 0 |
| 1978 | /* Update Timer 0 */ |
| 1979 | 1979 | if(GET_TR0) { |
| 1980 | 1980 | //Determine Mode |
| 1981 | 1981 | int mode = (GET_M0_1<<1) | GET_M0_0; |
| 1982 | | int overflow; |
| 1983 | | UINT16 count = 0; |
| 1982 | UINT32 count = 0; |
| 1984 | 1983 | switch(mode) { |
| 1985 | | case 0: //13 Bit Timer Mode |
| 1984 | case 0: /* 13 Bit Timer Mode */ |
| 1985 | count = ((R_TH0<<5) | ( R_TL0 & 0x1F ) ); |
| 1986 | /* Update the timer */ |
| 1987 | /* Gate Bit Set? Timer only incremented if Int0 is set! */ |
| 1988 | if(GET_GATE0 && GET_IE0) |
| 1989 | count += (cyc/12); |
| 1990 | /* Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line */ |
| 1991 | if(GET_CT0) |
| 1992 | { |
| 1993 | /* Not supported */ |
| 1994 | } |
| 1995 | /* Neither, regular timer mode */ |
| 1996 | if(!GET_GATE0 && !GET_CT0) |
| 1997 | count += (cyc/12); |
| 1998 | |
| 1999 | /* Check for overflow */ |
| 2000 | if ( count & 0xffffe000 ) |
| 2001 | { |
| 2002 | SET_TF0(1); |
| 2003 | } |
| 2004 | /* Update new values of the counter */ |
| 2005 | R_TH0 = (count>>5) & 0xff; |
| 2006 | R_TL0 = count & 0x1f; |
| 2007 | break; |
| 2008 | case 1: /* 16 Bit Timer Mode */ |
| 1986 | 2009 | count = ((R_TH0<<8) | R_TL0); |
| 1987 | | overflow = 0x3fff; |
| 1988 | | //Todo - really, we update HI counter when LO counter hits 0x20 |
| 1989 | | case 1: //16 Bit Timer Mode |
| 1990 | | count = ((R_TH0<<8) | R_TL0); |
| 1991 | | overflow = 0xffff; |
| 1992 | | //Check for overflow |
| 1993 | | if((UINT32)(count+(cyc/12))>overflow) { |
| 1994 | | //Any overflow from cycles? |
| 1995 | | cyc-= (overflow-count)*12; |
| 1996 | | count = 0; |
| 1997 | | SET_TF0(1); |
| 2010 | /* Update the timer */ |
| 2011 | /* Gate Bit Set? Timer only incremented if Int0 is set! */ |
| 2012 | if(GET_GATE0 && GET_IE0) |
| 2013 | count += (cyc/12); |
| 2014 | /* Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line */ |
| 2015 | if(GET_CT0) |
| 2016 | { |
| 2017 | /* Not supported */ |
| 1998 | 2018 | } |
| 1999 | | //Update the timer |
| 2000 | | if(cyc) { |
| 2001 | | int inctimer = 0; |
| 2002 | | //Gate Bit Set? Timer only incremented if Int0 is set! |
| 2003 | | if(GET_GATE0 && GET_IE0) |
| 2004 | | inctimer = (cyc/12); |
| 2005 | | //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line |
| 2006 | | if(GET_CT0) { |
| 2007 | | //Not supported |
| 2008 | | } |
| 2009 | | //Neither, regular timer mode |
| 2010 | | if(!GET_GATE0 && !GET_CT0) |
| 2011 | | inctimer = (cyc/12); |
| 2019 | /* Neither, regular timer mode */ |
| 2020 | if(!GET_GATE0 && !GET_CT0) |
| 2021 | count += (cyc/12); |
| 2012 | 2022 | |
| 2013 | | count+=inctimer; //Increment counter |
| 2023 | /* Check for overflow */ |
| 2024 | if ( count & 0xffff0000 ) |
| 2025 | { |
| 2026 | SET_TF0(1); |
| 2014 | 2027 | } |
| 2015 | | //Update new values of the counter |
| 2028 | /* Update new values of the counter */ |
| 2016 | 2029 | R_TH0 = (count>>8) & 0xff; |
| 2017 | 2030 | R_TL0 = count & 0xff; |
| 2018 | 2031 | break; |
| 2019 | | case 2: //8 Bit Autoreload |
| 2020 | | overflow = 0xff; |
| 2032 | case 2: /* 8 Bit Autoreload */ |
| 2021 | 2033 | count = R_TL0; |
| 2022 | | //Check for overflow |
| 2023 | | if(count+(cyc/12)>overflow) { |
| 2024 | | SET_TF0(1); |
| 2025 | | //Reload |
| 2026 | | count = R_TH0+(overflow-count); |
| 2034 | count += (cyc/12); |
| 2035 | /* Check for overflow */ |
| 2036 | if ( count & 0xffffff00 ) |
| 2037 | { |
| 2038 | SET_TF0(1); |
| 2039 | /* Reload timer */ |
| 2040 | count += R_TH0; |
| 2027 | 2041 | } |
| 2028 | | else |
| 2029 | | count+=(cyc/12); |
| 2030 | | //Update new values of the counter |
| 2042 | /* Update new values of the counter */ |
| 2031 | 2043 | R_TL0 = count & 0xff; |
| 2032 | 2044 | break; |
| 2033 | | case 3: //Split Timer |
| 2034 | | //Split Timer 1 |
| 2035 | | overflow = 0xff; |
| 2045 | case 3: /* Split Timer */ |
| 2046 | /* Split Timer 1 */ |
| 2036 | 2047 | count = R_TL0; |
| 2037 | | //Check for overflow |
| 2038 | | if(count+(cyc/12)>overflow) { |
| 2039 | | count = overflow-count; |
| 2040 | | SET_TF0(1); |
| 2041 | | } |
| 2042 | | else |
| 2043 | | count+=(cyc/12); |
| 2044 | | //Update new values of the counter |
| 2048 | count += (cyc/12); |
| 2049 | /* Check for overflow */ |
| 2050 | if ( count & 0xffffff00 ) |
| 2051 | { |
| 2052 | SET_TF0(1); |
| 2053 | } |
| 2054 | /* Update new values of the counter */ |
| 2045 | 2055 | R_TL0 = count & 0xff; |
| 2046 | 2056 | |
| 2047 | | //Split Timer 2 |
| 2048 | | overflow = 0xff; |
| 2049 | | count = R_TH0; |
| 2050 | | //Check for overflow |
| 2051 | | if(count+(cyc/12)>overflow) { |
| 2052 | | count = overflow-count; |
| 2053 | | SET_TF1(1); |
| 2054 | | } |
| 2055 | | else |
| 2056 | | count+=(cyc/12); |
| 2057 | | //Update new values of the counter |
| 2058 | | R_TH0 = count & 0xff; |
| 2057 | /* Split Timer 2 */ |
| 2058 | count = R_TH0; |
| 2059 | count += (cyc/12); |
| 2060 | /* Check for overflow */ |
| 2061 | if ( count & 0xffffff00 ) |
| 2062 | { |
| 2063 | SET_TF1(1); |
| 2064 | } |
| 2065 | /* Update new values of the counter */ |
| 2066 | R_TH0 = count & 0xff; |
| 2059 | 2067 | break; |
| 2060 | 2068 | } |
| 2061 | 2069 | } |
| 2062 | 2070 | |
| 2063 | | //Update Timer 1 |
| 2071 | /* Update Timer 1 */ |
| 2064 | 2072 | if(GET_TR1) { |
| 2065 | | //Determine Mode |
| 2073 | /* Determine Mode */ |
| 2066 | 2074 | int mode = (GET_M1_1<<1) | GET_M1_0; |
| 2067 | | int overflow; |
| 2068 | | UINT16 count = 0; |
| 2075 | UINT32 count = 0; |
| 2069 | 2076 | switch(mode) { |
| 2070 | | case 0: //13 Bit Timer Mode |
| 2077 | case 0: /* 13 Bit Timer Mode */ |
| 2078 | count = ((R_TH1<<5) | ( R_TL1 & 0x1F ) ); |
| 2079 | /* Update the timer */ |
| 2080 | /* Gate Bit Set? Timer only incremented if Int0 is set! */ |
| 2081 | if(GET_GATE1 && GET_IE1) |
| 2082 | count += (cyc/12); |
| 2083 | /* Counter Mode? Only increment on 1-0 transition of the Port 3's T1 Line */ |
| 2084 | if(GET_CT1) |
| 2085 | { |
| 2086 | /* Not supported */ |
| 2087 | } |
| 2088 | /* Neither, regular timer mode */ |
| 2089 | if(!GET_GATE1 && !GET_CT1) |
| 2090 | count += (cyc/12); |
| 2091 | |
| 2092 | /* Check for overflow */ |
| 2093 | if ( count & 0xffffe000 ) |
| 2094 | { |
| 2095 | SET_TF1(1); |
| 2096 | } |
| 2097 | /* Update new values of the counter */ |
| 2098 | R_TH1 = (count>>5) & 0xff; |
| 2099 | R_TL1 = count & 0x1f; |
| 2100 | break; |
| 2101 | case 1: /* 16 Bit Timer Mode */ |
| 2071 | 2102 | count = ((R_TH1<<8) | R_TL1); |
| 2072 | | overflow = 0x3fff; |
| 2073 | | //Todo - really, we update HI counter when LO counter hits 0x20 |
| 2074 | | case 1: //16 Bit Timer Mode |
| 2075 | | count = ((R_TH1<<8) | R_TL1); |
| 2076 | | overflow = 0xffff; |
| 2077 | | //Check for overflow |
| 2078 | | if((UINT32)(count+(cyc/12))>overflow) { |
| 2103 | /* Update the timer */ |
| 2104 | /* Gate Bit Set? Timer only incremented if Int1 is set! */ |
| 2105 | if(GET_GATE1 && GET_IE1) |
| 2106 | count += (cyc/12); |
| 2107 | /* Counter Mode? Only increment on 1-0 transition of the Port 3's T1 Line */ |
| 2108 | if(GET_CT1) |
| 2109 | { |
| 2110 | /* Not supported */ |
| 2111 | } |
| 2112 | /* Neither, regular timer mode */ |
| 2113 | if(!GET_GATE1 && !GET_CT1) |
| 2114 | count += (cyc/12); |
| 2079 | 2115 | |
| 2116 | /* Check for overflow */ |
| 2117 | if ( count & 0xffff0000 ) |
| 2118 | { |
| 2080 | 2119 | //TODO: Timer 1 can be set as Serial Baud Rate in the 8051 only... process bits here.. |
| 2081 | | |
| 2082 | | //Any overflow from cycles? |
| 2083 | | cyc-= (overflow-count)*12; |
| 2084 | | count = 0; |
| 2085 | | SET_TF1(1); |
| 2120 | SET_TF1(1); |
| 2086 | 2121 | } |
| 2087 | | //Update the timer |
| 2088 | | if(cyc) { |
| 2089 | | int inctimer = 0; |
| 2090 | | //Gate Bit Set? Timer only incremented if Int0 is set! |
| 2091 | | if(GET_GATE1 && GET_IE1) |
| 2092 | | inctimer = (cyc/12); |
| 2093 | | //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line |
| 2094 | | if(GET_CT1) { |
| 2095 | | //Not supported |
| 2096 | | } |
| 2097 | | //Neither, regular timer mode |
| 2098 | | if(!GET_GATE1 && !GET_CT1) |
| 2099 | | inctimer = (cyc/12); |
| 2100 | | |
| 2101 | | count+=inctimer; //Increment counter |
| 2102 | | } |
| 2103 | | //Update new values of the counter |
| 2122 | /* Update new values of the counter */ |
| 2104 | 2123 | R_TH1 = (count>>8) & 0xff; |
| 2105 | 2124 | R_TL1 = count & 0xff; |
| 2106 | 2125 | break; |
| 2107 | | case 2: //8 Bit Autoreload |
| 2108 | | overflow = 0xff; |
| 2126 | case 2: /* 8 Bit Autoreload */ |
| 2109 | 2127 | count = R_TL1; |
| 2110 | | //Check for overflow |
| 2111 | | if(count+(cyc/12)>overflow) { |
| 2112 | | SET_TF1(1); |
| 2113 | | //Reload |
| 2114 | | count = R_TH1+(overflow-count); |
| 2128 | count += (cyc/12); |
| 2129 | /* Check for overflow */ |
| 2130 | if ( count & 0xffffff00 ) |
| 2131 | { |
| 2132 | SET_TF1(1); |
| 2133 | /* Reload timer */ |
| 2134 | count += R_TH1; |
| 2115 | 2135 | } |
| 2116 | | else |
| 2117 | | count+=(cyc/12); |
| 2118 | | //Update new values of the counter |
| 2136 | /* Update new values of the counter */ |
| 2119 | 2137 | R_TL1 = count & 0xff; |
| 2120 | 2138 | break; |
| 2121 | | case 3: //Split Timer |
| 2122 | | break; |
| 2123 | 2139 | } |
| 2124 | 2140 | } |
| 2125 | 2141 | |
| 2126 | 2142 | #if (HAS_I8052 || HAS_I8752) |
| 2127 | | //Update Timer 2 |
| 2143 | /* Update Timer 2 */ |
| 2128 | 2144 | if(GET_TR2) { |
| 2129 | | int timerinc, overflow; |
| 2130 | | UINT16 count = ((R_TH2<<8) | R_TL2); |
| 2131 | | timerinc = overflow = 0; |
| 2145 | UINT32 count = ((R_TH2<<8) | R_TL2); |
| 2132 | 2146 | |
| 2133 | | //Are we in counter mode? |
| 2134 | | if(GET_CT2) { |
| 2135 | | //Not supported |
| 2147 | /* Are we in counter mode? */ |
| 2148 | if(GET_CT2) |
| 2149 | { |
| 2150 | /* Not supported */ |
| 2136 | 2151 | } |
| 2137 | | //Are we in timer mode? |
| 2138 | | else { |
| 2139 | | //16 Bit Timer Mode |
| 2140 | | overflow = 0xffff; |
| 2141 | | //Timer 2 Used as Baud Generator? (For now, only *same* send/receive rates supported) |
| 2152 | /* Are we in timer mode? */ |
| 2153 | else |
| 2154 | { |
| 2155 | /* 16 Bit Timer Mode */ |
| 2156 | /* Timer 2 Used as Baud Generator? (For now, only *same* send/receive rates supported) */ |
| 2142 | 2157 | if(GET_TCLK || GET_RCLK) |
| 2143 | | timerinc = cyc/2; //Timer increments ever 1/2 cycle in baud mode |
| 2158 | count += cyc/2; /* Timer increments every cycles/2 in baud mode */ |
| 2144 | 2159 | else |
| 2145 | | //REGULAR TIMER - |
| 2146 | | timerinc = cyc/12; //Timer increments ever 1/12 cycles in normal mode |
| 2160 | /* REGULAR TIMER - */ |
| 2161 | count += cyc/12; /* Timer increments every cycles/12 in normal mode */ |
| 2147 | 2162 | |
| 2148 | | //Check for overflow |
| 2149 | | if((UINT32)(count+timerinc)>overflow) { |
| 2150 | | //Set Interrupt flag *unless* used as baud generator |
| 2151 | | if(!GET_TCLK && !GET_RCLK) { |
| 2163 | /* Check for overflow */ |
| 2164 | if ( count & 0xffff0000 ) |
| 2165 | { |
| 2166 | /* Set Interrupt flag *unless* used as baud generator */ |
| 2167 | if(!GET_TCLK && !GET_RCLK) |
| 2168 | { |
| 2152 | 2169 | SET_TF2(1); |
| 2153 | 2170 | } |
| 2154 | | else { |
| 2155 | | //Update bits sent if sending & bits left to send! |
| 2171 | else |
| 2172 | { |
| 2173 | /* Update bits sent if sending & bits left to send! */ |
| 2156 | 2174 | if(uart.sending && uart.bits_to_send && uart.timerbaud) |
| 2157 | 2175 | uart.bits_to_send-=1; |
| 2158 | 2176 | } |
| 2159 | | //Auto reload? |
| 2177 | /* Auto reload? */ |
| 2160 | 2178 | if(!GET_CP) |
| 2161 | | count = ((R_RCAP2H<<8) | R_RCAP2L); //+(overflow-count); |
| 2162 | | else |
| 2163 | | count = overflow-count; |
| 2179 | count += ((R_RCAP2H<<8) | R_RCAP2L); |
| 2164 | 2180 | } |
| 2165 | | else { |
| 2166 | | //No overflow, just increment timer |
| 2167 | | count+=timerinc; |
| 2168 | | } |
| 2169 | | //Update flags |
| 2181 | /* Update new values of the counter */ |
| 2170 | 2182 | R_TH2 = (count>>8) & 0xff; |
| 2171 | 2183 | R_TL2 = count & 0xff; |
| 2172 | 2184 | } |