Difference between revisions of "83Plus:Ports:04"
m (→Credits and Contributions: Link to MV's docs fixed) |
m (make it clear that bits 5-7 do not actually signify an interrupt) |
||
(32 intermediate revisions by 12 users not shown) | |||
Line 1: | Line 1: | ||
− | [[Category:83Plus:Ports:By_Address|04 - Memory Map / Interrupt | + | [[Category:83Plus:Ports:By_Address|04 - Memory Map / Interrupt]] [[Category:83Plus:Ports:By_Name|Memory Map / Interrupt]] |
− | [[Category:83Plus:Ports:By_Name|Memory Map / Interrupt | + | |
== Synopsis == | == Synopsis == | ||
'''Port Number:''' 04h | '''Port Number:''' 04h | ||
Line 6: | Line 5: | ||
'''Function:''' Interrupting Device Identification and Memory Map Control | '''Function:''' Interrupting Device Identification and Memory Map Control | ||
− | This port serves two purposes. When read it indicates the device that triggered an interrupt. When written it sets the memory map mode and hardware timer speed. | + | ''See also: [[83Plus:Interrupts]], [[83Plus:Memory_Mapping]]'' |
+ | |||
+ | This port serves two purposes. When read it indicates the device that triggered an interrupt. When written it sets the memory map mode and hardware timer speed. When an interrupt is triggered, it should be cleared by reseting the corresponding bit in [[83Plus:Ports:03|port 3]]. Otherwise, it will continuously call the interrupt code once interrupts are reenabled with ei. | ||
=== Read Values === | === Read Values === | ||
* Bits 0~2 and 4~7 are set according to which device triggered the running interrupt. | * Bits 0~2 and 4~7 are set according to which device triggered the running interrupt. | ||
** Bit 0: Set if pressing the ON Key triggered the interrupt. | ** Bit 0: Set if pressing the ON Key triggered the interrupt. | ||
− | ** Bit 1: Set if the hardware timer triggered the interrupt. | + | ** Bit 1: Set if the first hardware timer triggered the interrupt. |
− | ** Bit 2: | + | ** Bit 2: Set if the second hardware timer triggered the interrupt. |
** Bit 4: Link activity generated an interrupt. | ** Bit 4: Link activity generated an interrupt. | ||
− | ** '''83+SE / 84+ only:''' Bit 5: First crystal timer | + | ** '''83+SE / 84+ only:''' Bit 5: First crystal timer has expired. |
− | ** '''83+SE / 84+ only:''' Bit 6: Second crystal timer | + | ** '''83+SE / 84+ only:''' Bit 6: Second crystal timer has expired. |
− | ** '''83+SE / 84+ only:''' Bit 7: Third crystal timer | + | ** '''83+SE / 84+ only:''' Bit 7: Third crystal timer has expired. |
* Bit 3 is reset if the ON key is being pressed, set otherwise. | * Bit 3 is reset if the ON key is being pressed, set otherwise. | ||
Line 23: | Line 24: | ||
** Address 0000h ~ 3FFFh: ROM Page 0 | ** Address 0000h ~ 3FFFh: ROM Page 0 | ||
** Address 4000h ~ 7FFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]]) | ** Address 4000h ~ 7FFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]]) | ||
− | ** Address 8000h ~ BFFFh: Memory Bank B (Page selected in [[83Plus:Ports: | + | ** Address 8000h ~ BFFFh: Memory Bank B (Page selected in [[83Plus:Ports:07|Port 07h]]) |
** '''83+ Basic''': Address C000h ~ FFFFh: RAM Page 0 | ** '''83+ Basic''': Address C000h ~ FFFFh: RAM Page 0 | ||
** '''Everything else''': Address C000h ~ FFFFh: Page selected in [[83Plus:Ports:05|Port 05h]] | ** '''Everything else''': Address C000h ~ FFFFh: Page selected in [[83Plus:Ports:05|Port 05h]] | ||
* Bit 0 set to select memory map mode 1. In mode 1 the RAM and ROM is mapped to CPU memory as follows: | * Bit 0 set to select memory map mode 1. In mode 1 the RAM and ROM is mapped to CPU memory as follows: | ||
** Address 0000h ~ 3FFFh: ROM Page 0 | ** Address 0000h ~ 3FFFh: ROM Page 0 | ||
− | ** Address 4000h ~ 7FFFh: | + | ** Address 4000h ~ 7FFFh: Memory Bank A, ''even'' page (value of [[83Plus:Ports:06|port 06h]] ANDed with FEh) |
− | ** Address 8000h ~ BFFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]]) | + | ** '''83+ Basic''': Address 8000h ~ BFFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]]) |
− | ** Address C000h ~ FFFFh: Memory Bank B (Page selected in [[83Plus:Ports: | + | ** '''Everything else''': Address 8000h ~ BFFFh: Memory Bank A, ''odd'' page (value of [[83Plus:Ports:06|port 06h]] ORed with 1) |
− | + | ** Address C000h ~ FFFFh: Memory Bank B (Page selected in [[83Plus:Ports:07|Port 07h]]) | |
* Bits 1 and 2 control the hardware timer frequency. Setting both 0 sets the timer to the fastest speed, and both 1 is the slowest speed. The normal speed is with both bits 1. | * Bits 1 and 2 control the hardware timer frequency. Setting both 0 sets the timer to the fastest speed, and both 1 is the slowest speed. The normal speed is with both bits 1. | ||
+ | {| width="90%" border="1" cellpadding="2" cellspacing="0" align="center" style="text-align: center" | ||
+ | |+Frequency (Hz) | ||
+ | |- | ||
+ | ! | ||
+ | !colspan="2"|first timer | ||
+ | !colspan="2"|second timer | ||
+ | !colspan="2"|both enabled | ||
+ | |- | ||
+ | !value | ||
+ | !width="15%"|83+ | ||
+ | !width="15%"|83+SE 84+(SE) | ||
+ | !width="15%"|83+ | ||
+ | !width="15%"|83+SE 84+(SE) | ||
+ | !width="15%"|83+ | ||
+ | !width="15%"|83+SE 84+(SE) | ||
+ | |- | ||
+ | !00 | ||
+ | |560||512||1120||1024||1680||1536 | ||
+ | |- | ||
+ | !01 | ||
+ | |248||227.55||497||455.11||746||682.66 | ||
+ | |- | ||
+ | !10 | ||
+ | |170||146.29||344||292.57||517||438.86 | ||
+ | |- | ||
+ | !11 | ||
+ | |118||107.79||236||215.58||353||323.37 | ||
+ | |} | ||
+ | * Bits 3~5: Unused. | ||
+ | * Bits 6 and 7: | ||
+ | ** '''83+ Basic''': No function | ||
+ | ** '''Everything else''': These two bits are used to determine the battery state. They act as a 2-bit number and the higher it is, the higher the voltage cutoff for bit 0 of [[83Plus:Ports:02|Port 2]]. Unless you are trying to determine battery state, these two bits should be zero. | ||
+ | *** '''TI-83+SE''': Only has one bit, bit 7; the second bit was added for the 84-series. | ||
+ | *** '''TI-84+/SE''': Numbers 00 and 10 are not currently used. 01 measures if the batteries are removed (0v). 11 measures if the main batteries are present but "low". | ||
+ | *** '''TI-84+CSE''': Based on the OS battery check routine, these two bits are in reverse order; that is, bit 6 is ''more'' significant than bit 7. (This probably also applies to the B&W models.) The routine always delays between changing these bits and checking bit 0 of [[83Plus:Ports:02|port 2]]. Also, for each check value, it writes 06 (i.e. resets the port) and then writes the value it intends to write. It writes, in order, 06, 86, 46, C6. If bit 0 of port 2 is reset after any of those writes, it returns 0 through 3, respectively; if bit 0 of port 2 remains set after all of those writes, it returns 4. Bit 7 of [[83Plus:Ports:3A|port 3A]] is also related; that bit is normally kept reset, but is set for the duration of the test routine. | ||
== Comments == | == Comments == | ||
− | The calculator uses mode 0 for normal operation. If you change the memory map mode be sure to change it back before returning control. | + | The calculator uses memory mapping mode 0 for normal operation. If you change the memory map mode be sure to change it back before returning control. |
− | Also, do not switch from mode 0 to mode 1 inside the 4000h ~ 7FFFh range | + | Also, do not switch from mode 0 to mode 1 inside the 4000h ~ 7FFFh range unless you've changed the RAM Execution Limits with ports [[83Plus:Ports:25|25]] and [[83Plus:Ports:26|26]]. This is because switching modes in this manner will start executing on RAM page 0, which will crash under normal conditions. |
+ | |||
+ | Interrupt timers may not be independent of the CPU speed for the 83+. However on the 83+SE, 84+ and 84+SE the standard timers are based on the crystal timer. Timer1 fires at 32768/(64+(80*i))hz, where i is bit 1 and 2 set in port 4, making it 0<=i<=3. | ||
+ | |||
+ | Bits 5-7 will also read 1 if the timer's interrupts are disabled and the timer has expired. | ||
== Example == | == Example == | ||
− | This example shows successful use of this port, switching to mode 1 and back. Mode 1 is the only way to execute code beyond address C000h on the 83+ Basic. | + | This example shows successful use of this port, switching to mode 1 and back. Mode 1 is the only way to execute code beyond address C000h on the 83+ Basic, unless you use a combination of ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] to enable execution on RAM page 00. (Assumes code is running from 4000h (i.e. an application)) |
<nowiki> in a, (7) ;Save current Bank B page because we'll trash it. | <nowiki> in a, (7) ;Save current Bank B page because we'll trash it. | ||
push af | push af | ||
− | + | in a,(6) ;Put this app's page into 8000 | |
out (7), a | out (7), a | ||
jp $ + 4003h ;This will actually jump to the next statement, but in Bank B. | jp $ + 4003h ;This will actually jump to the next statement, but in Bank B. | ||
Line 58: | Line 98: | ||
* '''Dan Englender''': Originally documented memory map modes [http://www.detachedsolutions.com/forum/viewtopic.php?p=21593#21593 here] | * '''Dan Englender''': Originally documented memory map modes [http://www.detachedsolutions.com/forum/viewtopic.php?p=21593#21593 here] | ||
* '''Michael Vincent''': For his docs [http://www.michaelv.org/programs/calcs/ports/port4.html here], which helped me figure out the interrupt device bits. | * '''Michael Vincent''': For his docs [http://www.michaelv.org/programs/calcs/ports/port4.html here], which helped me figure out the interrupt device bits. | ||
+ | * '''James Montelongo''': For his docs [http://www.geocities.com/jimm09876/calc/port4.html here] on the hardware timer. |
Latest revision as of 08:21, 15 March 2020
Contents
Synopsis
Port Number: 04h
Function: Interrupting Device Identification and Memory Map Control
See also: 83Plus:Interrupts, 83Plus:Memory_Mapping
This port serves two purposes. When read it indicates the device that triggered an interrupt. When written it sets the memory map mode and hardware timer speed. When an interrupt is triggered, it should be cleared by reseting the corresponding bit in port 3. Otherwise, it will continuously call the interrupt code once interrupts are reenabled with ei.
Read Values
- Bits 0~2 and 4~7 are set according to which device triggered the running interrupt.
- Bit 0: Set if pressing the ON Key triggered the interrupt.
- Bit 1: Set if the first hardware timer triggered the interrupt.
- Bit 2: Set if the second hardware timer triggered the interrupt.
- Bit 4: Link activity generated an interrupt.
- 83+SE / 84+ only: Bit 5: First crystal timer has expired.
- 83+SE / 84+ only: Bit 6: Second crystal timer has expired.
- 83+SE / 84+ only: Bit 7: Third crystal timer has expired.
- Bit 3 is reset if the ON key is being pressed, set otherwise.
Write Values
- Bit 0 reset to select memory map mode 0. In mode 0 the RAM and ROM is mapped to CPU memory as follows:
- Bit 0 set to select memory map mode 1. In mode 1 the RAM and ROM is mapped to CPU memory as follows:
- Address 0000h ~ 3FFFh: ROM Page 0
- Address 4000h ~ 7FFFh: Memory Bank A, even page (value of port 06h ANDed with FEh)
- 83+ Basic: Address 8000h ~ BFFFh: Memory Bank A (Page selected in Port 06h)
- Everything else: Address 8000h ~ BFFFh: Memory Bank A, odd page (value of port 06h ORed with 1)
- Address C000h ~ FFFFh: Memory Bank B (Page selected in Port 07h)
- Bits 1 and 2 control the hardware timer frequency. Setting both 0 sets the timer to the fastest speed, and both 1 is the slowest speed. The normal speed is with both bits 1.
first timer | second timer | both enabled | ||||
---|---|---|---|---|---|---|
value | 83+ | 83+SE 84+(SE) | 83+ | 83+SE 84+(SE) | 83+ | 83+SE 84+(SE) |
00 | 560 | 512 | 1120 | 1024 | 1680 | 1536 |
01 | 248 | 227.55 | 497 | 455.11 | 746 | 682.66 |
10 | 170 | 146.29 | 344 | 292.57 | 517 | 438.86 |
11 | 118 | 107.79 | 236 | 215.58 | 353 | 323.37 |
- Bits 3~5: Unused.
- Bits 6 and 7:
- 83+ Basic: No function
- Everything else: These two bits are used to determine the battery state. They act as a 2-bit number and the higher it is, the higher the voltage cutoff for bit 0 of Port 2. Unless you are trying to determine battery state, these two bits should be zero.
- TI-83+SE: Only has one bit, bit 7; the second bit was added for the 84-series.
- TI-84+/SE: Numbers 00 and 10 are not currently used. 01 measures if the batteries are removed (0v). 11 measures if the main batteries are present but "low".
- TI-84+CSE: Based on the OS battery check routine, these two bits are in reverse order; that is, bit 6 is more significant than bit 7. (This probably also applies to the B&W models.) The routine always delays between changing these bits and checking bit 0 of port 2. Also, for each check value, it writes 06 (i.e. resets the port) and then writes the value it intends to write. It writes, in order, 06, 86, 46, C6. If bit 0 of port 2 is reset after any of those writes, it returns 0 through 3, respectively; if bit 0 of port 2 remains set after all of those writes, it returns 4. Bit 7 of port 3A is also related; that bit is normally kept reset, but is set for the duration of the test routine.
Comments
The calculator uses memory mapping mode 0 for normal operation. If you change the memory map mode be sure to change it back before returning control. Also, do not switch from mode 0 to mode 1 inside the 4000h ~ 7FFFh range unless you've changed the RAM Execution Limits with ports 25 and 26. This is because switching modes in this manner will start executing on RAM page 0, which will crash under normal conditions.
Interrupt timers may not be independent of the CPU speed for the 83+. However on the 83+SE, 84+ and 84+SE the standard timers are based on the crystal timer. Timer1 fires at 32768/(64+(80*i))hz, where i is bit 1 and 2 set in port 4, making it 0<=i<=3.
Bits 5-7 will also read 1 if the timer's interrupts are disabled and the timer has expired.
Example
This example shows successful use of this port, switching to mode 1 and back. Mode 1 is the only way to execute code beyond address C000h on the 83+ Basic, unless you use a combination of ports 5 and 16 to enable execution on RAM page 00. (Assumes code is running from 4000h (i.e. an application))
in a, (7) ;Save current Bank B page because we'll trash it. push af in a,(6) ;Put this app's page into 8000 out (7), a jp $ + 4003h ;This will actually jump to the next statement, but in Bank B. ld a, 77h ;Select mode 1 and keep the timer speed at normal... out (4), a ;Now we're in mode 1. ;We're still at 8000h here but we are back in Bank A. ;Now to go back. ld a, 76h ;I could dec a for this example, but... out (4), a ;Back in mode 0 and bank B. jp $ - 3FFDh ;Jump back to bank A. pop af out (7), a ;Restore bank B.