Difference between revisions of "83Plus:Ports:30"
(So many spelling errors, What moron wrote this?) |
(Cycle behavior: addition to non-looping mode) |
||
(6 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:83Plus:Ports:By_Address|30-38 - Timers]] [[Category:83Plus:Ports:By_Name|Timers]] | [[Category:83Plus:Ports:By_Address|30-38 - Timers]] [[Category:83Plus:Ports:By_Name|Timers]] | ||
− | {{SE-Only Port| | + | {{SE-Only Port|00}} |
== Synopsis == | == Synopsis == | ||
Line 33: | Line 33: | ||
===On/Off ports:=== | ===On/Off ports:=== | ||
− | The On/Off ports are 30, 33, and 36. These ports control what clock is used for this timer and a divisor(needed since the counter is only 8bit). The upper two bits(6 & 7) tell what clock is being used. 00 if none and the timer is off, 01 for the crystal timer, and 02 for the CPU clock. 03 | + | The On/Off ports are 30, 33, and 36. These ports control what clock is used for this timer and a divisor(needed since the counter is only 8bit). The upper two bits(6 & 7) tell what clock is being used. 00 if none and the timer is off, 01 for the crystal timer, and 02 for the CPU clock. 03 also draws from the CPU clock, but also applies a pre-scaler from port [[83Plus:Ports:2F|2F]] depending on CPU speed. Bits 0-5 of the On/Off ports control the divisor. For simplicity, here is a table with the output values next to the the frequencies that would be generated. |
{| width="30%" cellspacing="1" | {| width="30%" cellspacing="1" | ||
Line 47: | Line 47: | ||
|- bgcolor="C0C0C0" | |- bgcolor="C0C0C0" | ||
| width="20%" | 40h | | width="20%" | 40h | ||
− | | width="80%" | 10922. | + | | width="80%" | 10922.667 Hz (32768/3) |
|- bgcolor="C0C0C0" | |- bgcolor="C0C0C0" | ||
| width="20%" | 41h | | width="20%" | 41h | ||
− | | width="80%" | | + | | width="80%" | 992.9697 Hz (32768/33) |
|- bgcolor="C0C0C0" | |- bgcolor="C0C0C0" | ||
| width="20%" | 42h | | width="20%" | 42h | ||
− | | width="80%" | | + | | width="80%" | 99.902 Hz (32768/328) |
|- bgcolor="C0C0C0" | |- bgcolor="C0C0C0" | ||
| width="20%" | 43h | | width="20%" | 43h | ||
− | | width="80%" | | + | | width="80%" | 9.9993 Hz (32768/3277) |
|- bgcolor="C0C0C0" | |- bgcolor="C0C0C0" | ||
| width="20%" | 44h | | width="20%" | 44h | ||
Line 102: | Line 102: | ||
The Loop Control ports are 31, 34, and 37. | The Loop Control ports are 31, 34, and 37. | ||
− | When bit 0 is set on this port it causes the timer to loop when the counter hits 0. Once it does, the counter will start back at the value you initially placed in it. To keep it looping from that value, you must output to the loop control port at every loop. If you miss one bit 2 of this port will be set, and the counter will carry to FF continue to count down. | + | When bit 0 is set on this port it causes the timer to loop when the counter hits 0. Once it does, the counter will start back at the value you initially placed in it. To keep it looping from that value, you must output to the loop control port at every loop. If you miss one bit 2 of this port will be set, and the counter will carry to FF continue to count down. However, you don't have to output immediately when it reaches zero. If you outputted at least once to the loop control port during the cycle, it will repeat from the value you set. This includes the out you used to set up the timer initially. As long as you |
− | When bit 1 is set this timer will generate an interrupt when the counter hits 0. The interrupt must acknowledge or it will recurse upon EI. Acknowledge it by writing to the Loop control port. Depending on whether you have looping enabled or not, you can start the timer again by write to the counter port. | + | When bit 1 is set this timer will generate an interrupt when the counter hits 0. The interrupt must acknowledge or it will recurse upon EI. Acknowledge it by writing to the Loop control port. Depending on whether you have looping enabled or not, you can start the timer again by write to the counter port. The bit in [[83Plus:Ports:04|port 04h]] will be set even if interrupts weren't enabled. |
− | At this point I want to stress that you must acknowledge the timers whenever the counter reaches zero. Every time the counter hits zero the appropriate bit is set in [[83Plus:Ports:04|port 04h]]. To reset those bits you MUST write to the loop control port, whether you have interrupts enabled or not. | + | At this point I want to stress that you must acknowledge the timers whenever the counter reaches zero. Every time the counter hits zero the appropriate bit is set in [[83Plus:Ports:04|port 04h]], even if the interrupt is disabled. To reset those bits you MUST write to the loop control port, whether you have interrupts enabled or not. |
Line 121: | Line 121: | ||
For some reasons the timers do not seem to generate interrupts if the CPU is halt. I can only imagine that this is either a bug in the hardware or that there is more information missing. In any case, if you intend to use the crystal timers to generate an interrupt leave the normal timers on so that you can escape any halt. | For some reasons the timers do not seem to generate interrupts if the CPU is halt. I can only imagine that this is either a bug in the hardware or that there is more information missing. In any case, if you intend to use the crystal timers to generate an interrupt leave the normal timers on so that you can escape any halt. | ||
+ | The TI-84 uses the timers for its own purposes, leaving only timer 1 free. A set of undocumented bcalls can be used to manipulate it. Whether or not you use those calls, TI-OS's interrupt checks the status of each of the timers and will disable interrupts from them and set them to loop. (See code at 0E11h) | ||
+ | |||
+ | === Cycle behavior === | ||
+ | If looping is disabled, once the counter reaches 0 it will stop the timer and the value you can read from the counter port is the value you initially set it to. You can restart the timer by reading this value and writing it back, or you can write a different value from the one you used before. Beware that 0 itself is not counted. That means, between 01 and the timer ending, there is no 00. However, if you don't also write to the loop control port at least once, it will overflow (as if looping was enabled). | ||
+ | |||
+ | If looping is enabled, once the counter reaches 0, it will loop back to the value you set it to. Then, before it reaches 0 again, you need to write to the loop control port. Not doing this will cause the counter to overflow and bit 2 will be set. Once you do write to the loop control port, bit 2 will reset, the interrupt will stop being fired, the bit of [[83Plus:Ports:04|port 04h]] will be reset, and when the timer reaches 0 the next time, it will repeat again. If you still don't do this and let the counter reach 0 another time, it will loop back to FF again. Beware that 0 itself is not counted. That means, between 01 and the timer repeating, there is no 00. When the counter has overflowed at least once, though, 00 will be reached, but only if you didn't acknowledge the loop. Writing 00 to the counter port initially is identical to 256. In fact, the counter works exactly like DJNZ. | ||
+ | |||
+ | Whether interrupts are enabled or not has no effect on this behaviour. | ||
== Example Code == | == Example Code == |
Latest revision as of 18:01, 15 June 2021
This port only exists as a distinct port on the TI-83 Plus Silver Edition, the TI-84 Plus, and the TI-84 Plus Silver Edition. On the standard TI-83 Plus, it acts as a shadow of port 00. |
Contents
Synopsis
Port Number: 30 - 38
Function: Timers On the 83+SE and 84+(SE) there are 3 timers that are independent of each other and each timer is controlled by 3 ports, On/off, Loop control, and the counter itself. They can be used for accurate delay waiting, interrupts that execute at almost any desired frequency, or for just keeping time.
On/Off | Loop Control | Counter | |
Timer1 | 30 | 31 | 32 |
Timer2 | 33 | 34 | 35 |
Timer3 | 36 | 37 | 38 |
On/Off ports:
The On/Off ports are 30, 33, and 36. These ports control what clock is used for this timer and a divisor(needed since the counter is only 8bit). The upper two bits(6 & 7) tell what clock is being used. 00 if none and the timer is off, 01 for the crystal timer, and 02 for the CPU clock. 03 also draws from the CPU clock, but also applies a pre-scaler from port 2F depending on CPU speed. Bits 0-5 of the On/Off ports control the divisor. For simplicity, here is a table with the output values next to the the frequencies that would be generated.
Value | Frequency |
00h | OFF |
~ | ~ |
40h | 10922.667 Hz (32768/3) |
41h | 992.9697 Hz (32768/33) |
42h | 99.902 Hz (32768/328) |
43h | 9.9993 Hz (32768/3277) |
44h | 32768 Hz |
45h | 2048 Hz |
46h | 128 Hz |
47h | 8 Hz |
~ | ~ |
80h | CPU clock speed |
81h | CPU clock / 2 |
82h | CPU clock / 4 |
84h | CPU clock / 8 |
88h | CPU clock / 16 |
90h | CPU clock / 32 |
A0h | CPU clock / 64 |
Since Silver Edition calculators CPU speed can be adjusted the timers will run at whatever the current CPU speed is(if selected of course).
Loop Control ports:
The Loop Control ports are 31, 34, and 37.
When bit 0 is set on this port it causes the timer to loop when the counter hits 0. Once it does, the counter will start back at the value you initially placed in it. To keep it looping from that value, you must output to the loop control port at every loop. If you miss one bit 2 of this port will be set, and the counter will carry to FF continue to count down. However, you don't have to output immediately when it reaches zero. If you outputted at least once to the loop control port during the cycle, it will repeat from the value you set. This includes the out you used to set up the timer initially. As long as you
When bit 1 is set this timer will generate an interrupt when the counter hits 0. The interrupt must acknowledge or it will recurse upon EI. Acknowledge it by writing to the Loop control port. Depending on whether you have looping enabled or not, you can start the timer again by write to the counter port. The bit in port 04h will be set even if interrupts weren't enabled.
At this point I want to stress that you must acknowledge the timers whenever the counter reaches zero. Every time the counter hits zero the appropriate bit is set in port 04h, even if the interrupt is disabled. To reset those bits you MUST write to the loop control port, whether you have interrupts enabled or not.
Counter ports:
The Counter ports are 32, 35, and 38.
Once the prior 2 ports have been setup all that is need to activate the timer is to send the desired value you wish to count down from to the counter port. However if you send 0 it will loop no matter what and it will not affect port 4, so keep it above 0.
Also note that you should turn off the timer when you are done, do this by writing 0 to the on/off port and loop control.
Comments
For some reasons the timers do not seem to generate interrupts if the CPU is halt. I can only imagine that this is either a bug in the hardware or that there is more information missing. In any case, if you intend to use the crystal timers to generate an interrupt leave the normal timers on so that you can escape any halt.
The TI-84 uses the timers for its own purposes, leaving only timer 1 free. A set of undocumented bcalls can be used to manipulate it. Whether or not you use those calls, TI-OS's interrupt checks the status of each of the timers and will disable interrupts from them and set them to loop. (See code at 0E11h)
Cycle behavior
If looping is disabled, once the counter reaches 0 it will stop the timer and the value you can read from the counter port is the value you initially set it to. You can restart the timer by reading this value and writing it back, or you can write a different value from the one you used before. Beware that 0 itself is not counted. That means, between 01 and the timer ending, there is no 00. However, if you don't also write to the loop control port at least once, it will overflow (as if looping was enabled).
If looping is enabled, once the counter reaches 0, it will loop back to the value you set it to. Then, before it reaches 0 again, you need to write to the loop control port. Not doing this will cause the counter to overflow and bit 2 will be set. Once you do write to the loop control port, bit 2 will reset, the interrupt will stop being fired, the bit of port 04h will be reset, and when the timer reaches 0 the next time, it will repeat again. If you still don't do this and let the counter reach 0 another time, it will loop back to FF again. Beware that 0 itself is not counted. That means, between 01 and the timer repeating, there is no 00. When the counter has overflowed at least once, though, 00 will be reached, but only if you didn't acknowledge the loop. Writing 00 to the counter port initially is identical to 256. In fact, the counter works exactly like DJNZ.
Whether interrupts are enabled or not has no effect on this behaviour.
Example Code
;Setup up a timer that waits 2 seconds di ld a,$47 ;8 hz out ($30),a ld a,0 ; no loop, no interrupt out ($31),a ld a,16 ;16 ticks / 8 hz equals 2 seconds out ($32),a wait: in a,(4) bit 5,a ;bit 5 tells if timer 1 jr z,wait ;is done xor a out ($30),a ;Turn off the timer. out ($31),a