<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://wikiti.brandonw.net/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wikiti.brandonw.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fghsgh</id>
		<title>WikiTI - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wikiti.brandonw.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fghsgh"/>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Special:Contributions/Fghsgh"/>
		<updated>2026-04-29T16:47:07Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.5</generator>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=User:Fghsgh</id>
		<title>User:Fghsgh</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=User:Fghsgh"/>
				<updated>2024-01-27T22:46:05Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi! I do Z80 programming &amp;amp; own an 84+ (rev AB) and an 89T (rev K). I am probably available in the #cemetech IRC channel (or rather, their discord server). Trying to keep the wiki up to date as TI keeps releasing new hardware revisions.&lt;br /&gt;
Born in 2002 (figured i wouldn't bother updating this page every year). Pleasure to meet you!&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:30</id>
		<title>83Plus:Ports:30</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:30"/>
				<updated>2021-06-16T02:01:12Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: Cycle behavior: addition to non-looping mode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|30-38 - Timers]] [[Category:83Plus:Ports:By_Name|Timers]]&lt;br /&gt;
{{SE-Only Port|00}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 30 - 38&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Timers&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;40%&amp;quot; cellspacing=&amp;quot;1&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; |&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | On/Off&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Loop Control&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Counter&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer1&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 30&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 31&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 32&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer2&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 33&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 34&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 35&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer3&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 36&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 37&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 38&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===On/Off ports:===&lt;br /&gt;
&lt;br /&gt;
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 &amp;amp; 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.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;30%&amp;quot; cellspacing=&amp;quot;1&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;808080&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | Value&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | Frequency&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 00h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | OFF&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | ~&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | ~&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 40h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 10922.667 Hz (32768/3)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 41h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 992.9697 Hz (32768/33)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 42h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 99.902 Hz (32768/328)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 43h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 9.9993 Hz (32768/3277)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 44h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 32768 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 45h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 2048 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 46h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 128 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 47h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 8 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | ~&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | ~&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 80h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock speed&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 81h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 2&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 82h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 4&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 84h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 8&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 88h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 16&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 90h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 32&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | A0h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Since Silver Edition calculators CPU speed can be adjusted the timers will run at whatever the current CPU speed is(if selected of course).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loop Control ports:===&lt;br /&gt;
&lt;br /&gt;
The Loop Control ports are 31, 34, and 37.&lt;br /&gt;
&lt;br /&gt;
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 &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Counter ports:===&lt;br /&gt;
&lt;br /&gt;
The Counter ports are 32, 35, and 38.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
=== Cycle behavior ===&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Whether interrupts are enabled or not has no effect on this behaviour.&lt;br /&gt;
&lt;br /&gt;
== Example Code ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ;Setup up a timer that waits 2 seconds&lt;br /&gt;
   di&lt;br /&gt;
   ld a,$47      ;8 hz&lt;br /&gt;
   out ($30),a&lt;br /&gt;
   ld a,0        ; no loop, no interrupt&lt;br /&gt;
   out ($31),a&lt;br /&gt;
   ld a,16       ;16 ticks / 8 hz equals 2 seconds&lt;br /&gt;
   out ($32),a&lt;br /&gt;
wait:&lt;br /&gt;
   in a,(4)&lt;br /&gt;
   bit 5,a       ;bit 5 tells if timer 1&lt;br /&gt;
   jr z,wait     ;is done&lt;br /&gt;
   xor a&lt;br /&gt;
   out ($30),a   ;Turn off the timer.&lt;br /&gt;
   out ($31),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Michael Vincent''': Documentation found [http://www.michaelv.org/programs/calcs/rtc.txt here].&lt;br /&gt;
* '''James Montelongo''': Documentation found [http://www.geocities.com/jimm09876/calc/timers.html here].&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:22</id>
		<title>83Plus:Ports:22</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:22"/>
				<updated>2021-01-20T21:58:10Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: err... grammar, didn't reread properly&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address:Protected|22 - Flash Lower Limit]] [[Category:83Plus:Ports:By_Address|22 - Flash Lower Limit]] [[Category:83Plus:Ports:By_Name|Flash Lower Limit]]&lt;br /&gt;
{{SE-Only Port|02}}&lt;br /&gt;
{{Protected Port}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 22h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Execution Lower Limit&lt;br /&gt;
&lt;br /&gt;
This port controls the first of two flash page execution limits.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* [00h - FFh]: Flash Pages strictly below this value have execution permission.  This is always set to 08 in TIOS.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* [00h - FFh]: The new execution limit.  You must enable flash access through [[83Plus:Ports:14|port 14]] first.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port does not exist on the standard 83 Plus.  See ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] instead.  Execution of code from a page at or above this port's value and at or below the value in [[83Plus:Ports:23|Port 23]] will cause the calculator to reset.&lt;br /&gt;
&lt;br /&gt;
For some reason, page 00 seems to always be executable.&lt;br /&gt;
&lt;br /&gt;
This port can be completely overridden by [[83Plus:Ports:24|port 24]].&lt;br /&gt;
&lt;br /&gt;
If port 23h is less than 22h, all pages will be executable.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:23</id>
		<title>83Plus:Ports:23</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:23"/>
				<updated>2021-01-20T21:57:05Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: clarifications about what happens if the page is equal to the value of the port&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address:Protected|23 - Flash Upper Limit]] [[Category:83Plus:Ports:By_Address|23 - Flash Upper Limit]] [[Category:83Plus:Ports:By_Name|Flash Upper Limit]]&lt;br /&gt;
{{SE-Only Port|03}}&lt;br /&gt;
{{Protected Port}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 23h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Execution Upper Limit&lt;br /&gt;
&lt;br /&gt;
This port controls the upper of two flash execution limits.  &lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* [00h - FFh]: Flash pages strictly above this value have execution permission.  In TIOS this will be set to the last app page minus one.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* [00h - FFh]: The new execution limit.  You must enable flash access through [[83Plus:Ports:14|port 14]] first.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
If port 23h is less than 22h, all pages will be executable.&lt;br /&gt;
&lt;br /&gt;
This port can be completely overridden by [[83Plus:Ports:24|port 24]].&lt;br /&gt;
&lt;br /&gt;
This port does not exist on the standard 83 Plus.  See ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] instead.  Execution of code from a page at or below this port's value and at or above the value in [[83Plus:Ports:22|port 22]] will cause the calculator to reset.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:22</id>
		<title>83Plus:Ports:22</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:22"/>
				<updated>2021-01-20T21:56:10Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: updated to make it make sense and add new findings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address:Protected|22 - Flash Lower Limit]] [[Category:83Plus:Ports:By_Address|22 - Flash Lower Limit]] [[Category:83Plus:Ports:By_Name|Flash Lower Limit]]&lt;br /&gt;
{{SE-Only Port|02}}&lt;br /&gt;
{{Protected Port}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 22h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Execution Lower Limit&lt;br /&gt;
&lt;br /&gt;
This port controls the first of two flash page execution limits.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* [00h - FFh]: Flash Pages strictly below this value have execution permission.  This is always set to 08 in TIOS.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* [00h - FFh]: The new execution limit.  You must enable flash access through [[83Plus:Ports:14|port 14]] first.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port does not exist on the standard 83 Plus.  See ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] instead.  Execution of code from a page at or above this port's value and at or below to the value in [[83Plus:Ports:23|Port 23]] will cause the calculator to reset.&lt;br /&gt;
&lt;br /&gt;
For some reason, page 00 seems to always be executable.&lt;br /&gt;
&lt;br /&gt;
This port can be completely overridden by [[83Plus:Ports:24|port 24]].&lt;br /&gt;
&lt;br /&gt;
If port 23h is less than 22h, all pages will be executable.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:23</id>
		<title>83Plus:Ports:23</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:23"/>
				<updated>2021-01-20T21:53:11Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: this was making no sense&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address:Protected|23 - Flash Upper Limit]] [[Category:83Plus:Ports:By_Address|23 - Flash Upper Limit]] [[Category:83Plus:Ports:By_Name|Flash Upper Limit]]&lt;br /&gt;
{{SE-Only Port|03}}&lt;br /&gt;
{{Protected Port}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 23h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Execution Upper Limit&lt;br /&gt;
&lt;br /&gt;
This port controls the upper of two flash execution limits.  &lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* [00h - FFh]: Flash pages above this value have execution permission.  In TIOS this will be set to the last app page minus one.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* [00h - FFh]: The new execution limit.  You must enable flash access through [[83Plus:Ports:14|port 14]] first.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
If port 23h is less than 22h, all pages will be executable.&lt;br /&gt;
&lt;br /&gt;
This port can be completely overridden by [[83Plus:Ports:24|port 24]].&lt;br /&gt;
&lt;br /&gt;
This port does not exist on the standard 83 Plus.  See ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] instead.  Execution of code from a page at or below this port's value and above the value in [[83Plus:Ports:22|port 22]] will cause the calculator to reset.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:24</id>
		<title>83Plus:Ports:24</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:24"/>
				<updated>2021-01-20T21:52:26Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: this was making no sense&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address:Protected|24 - Flash Execution Limits High Bit]] [[Category:83Plus:Ports:By_Address|24 - Flash Execution Limits High Bit]] [[Category:83Plus:Ports:By_Name|Flash Execution Limit High Bit]]&lt;br /&gt;
{{SE-Only Port|04}}&lt;br /&gt;
{{Protected Port}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 24h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Execution Limits High Bit&lt;br /&gt;
&lt;br /&gt;
Bit 0 of this port forms the high bit of page number for port 22. Bit 1 of this port forms the high bit of the page number for port 23. Therefore, this port supports 8 MB flash chips.&lt;br /&gt;
&lt;br /&gt;
Since no 8 MB flash chip exists, this port in effect overrides both [[83Plus:Ports:22|port 22]] and [[83Plus:Ports:23|port 23]].&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: High bit (bit 8) of port 22&lt;br /&gt;
* Bit 1: High bit (bit 8) of port 23&lt;br /&gt;
* Bits 2-7: Toggleable, but no effect is apparent. These bits are currently unused.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0-7: Reads whatever was last written&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port does not exist on the standard 83 Plus.  See ports [[83Plus:Ports:05|5]] and [[83Plus:Ports:16|16]] instead.  &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:26|Port 26]]&lt;br /&gt;
* [[83Plus:Ports:21|Port 21]]&lt;br /&gt;
* [[83Plus:Ports:26|Port 22]]&lt;br /&gt;
* [[83Plus:Ports:26|Port 23]]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Calculator_General_FAQ</id>
		<title>Calculator General FAQ</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Calculator_General_FAQ"/>
				<updated>2021-01-17T16:33:21Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: fixed grammar and spelling errors, made things a bit more consistent, corrected some wrong things&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The WikiTI Calculator FAQ. =&lt;br /&gt;
&lt;br /&gt;
FAQ stands for Frequently Asked Questions.&lt;br /&gt;
You should start to seek your answer here and in the other FAQs before asking. There are currently active users willing to help on the [https://www.cemetech.net Cemetech], [http://www.omnimaga.org/index.php?board=6.0 Omnimaga], and [https://codewalr.us/ CodeWalrus] forums.&lt;br /&gt;
&lt;br /&gt;
{{stub}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Linking ===&lt;br /&gt;
&lt;br /&gt;
==== How do I connect my calculator to my computer? ====&lt;br /&gt;
First, you need a cable to connect the calculator. Most new calculators ship with one. For older calculators, you might need to buy a SilverLink cable.&lt;br /&gt;
You also need a linking program. There are several:&lt;br /&gt;
* [https://education.ti.com/en/products/computer-software/ti-connect-sw TI-Connect] (Only for Mac and Windows, NOT compatible with the CE)&lt;br /&gt;
* [https://education.ti.com/en/products/computer-software/ti-connect-ce-sw TI-Connect CE] (Only for Mac and Windows, specifically for the CE)&lt;br /&gt;
* [https://lpg.ticalc.org/prj_tilp/ TiLP] (compatible with several models)&lt;br /&gt;
* [https://ticalc.link Ticalc.link] (only compatible with TI-84 plus)&lt;br /&gt;
&lt;br /&gt;
==== Where do I get programs for my calculator? ====&lt;br /&gt;
For a large collection of programs you can check out [https://ticalc.org ticalc.org] or the forum links below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calculator Specific ==&lt;br /&gt;
&lt;br /&gt;
=== TI-83 ===&lt;br /&gt;
&lt;br /&gt;
=== TI-83/84+[SE] ===&lt;br /&gt;
&lt;br /&gt;
==== Can I downgrade my OS? ====&lt;br /&gt;
First let's check the bootcode. Click [mode][alpha][ln].&lt;br /&gt;
&lt;br /&gt;
The bootcode and your base code (the OS) versions will be presented. If the bootcode is anything below 1.03 you can downgrade by simply sending an older .8xu or a different OS like [https://knightos.org/ KnightOS] to your calculator.&lt;br /&gt;
&lt;br /&gt;
==== What do I do if my bootcode is 1.03 ====&lt;br /&gt;
TI implemented an RSA-SHA256 encryption method to their bootcode that prevents unsigned OSes and downgrades from happening, but TI's attempts were thwarted. There is a handy tool called [https://www.ticalc.org/archives/files/fileinfo/441/44190.html UNSIGNED] that you can send to your calculator. It will patch the boot code after you change the certificate revision and/or click Signed OS's. Once that happens you can send any .8xu file you want to your calculator.&lt;br /&gt;
&lt;br /&gt;
=== TI-84+/CE ===&lt;br /&gt;
&lt;br /&gt;
==== Why can't I run assembly programs on my TI-84+ CE? ====&lt;br /&gt;
TI has decided that from OS version 5.5.5, assembly programs were a security threat and have hence removed the functionality to run them from TI-OS. A full explanation video by Thelastmillennial can be found [https://youtu.be/dSkN0aMswXs here].&lt;br /&gt;
&lt;br /&gt;
However, not all hope is lost. A workaround has been made to restore assembly functionality.&lt;br /&gt;
# Send [https://yvantt.github.io/arTIfiCE/ arTIfiCE] to your calculator&lt;br /&gt;
# For easier use of assembly programs: install [https://github.com/mateoconlechuga/cesium/releases/latest Cesium]&lt;br /&gt;
# For even more convenience: install [https://github.com/jacobly0/asmhook/releases/latest asmhook]&lt;br /&gt;
&lt;br /&gt;
==== Can I downgrade my OS? ====&lt;br /&gt;
''Placeholder''&lt;br /&gt;
&lt;br /&gt;
==== How do I reset the calculator? ====&lt;br /&gt;
Sometimes it will happen that the calculator freezes or that you just need to reset it. There are several options for resetting.&lt;br /&gt;
To reset your calculator you can:&lt;br /&gt;
* Press the reset button at the back of your calculator (if your calculator is only frozen, press it shortly, if you want a complete RAM reset, hold it for some seconds.)&lt;br /&gt;
* Press [2nd]-[+]-[7], then you can choose what you want to reset. This of course doesn't work if it is frozen.&lt;br /&gt;
&lt;br /&gt;
==== Why is there stuff on my screen going through my graphs? ====&lt;br /&gt;
Some programs use the graph screen to draw the interface of the program. Sometimes, this isn't cleared by the program.&amp;lt;br/&amp;gt;&lt;br /&gt;
This can be solved very easy by pressing: [2nd][prgm][1][enter].&lt;br /&gt;
&lt;br /&gt;
== Programming and developing ==&lt;br /&gt;
&lt;br /&gt;
=== What programming languages are possible? ===&lt;br /&gt;
That depends on your calculator.&lt;br /&gt;
 &lt;br /&gt;
TI-83(84)+[SE]&lt;br /&gt;
 [http://tutorials.eeems.ca/ASMin28Days/welcome.html z80]&lt;br /&gt;
 [https://github.com/KnightOS/kcc C]&lt;br /&gt;
 [https://www.ticalc.org/archives/files/fileinfo/456/45659.html Axe Parser]&lt;br /&gt;
 [https://github.com/Zeda/Grammer2 Grammer 2]&lt;br /&gt;
 [http://tibasicdev.wikidot.com/home TI-BASIC]&lt;br /&gt;
 [https://www.ticalc.org/archives/files/fileinfo/416/41608.html BBC BASIC]&lt;br /&gt;
&lt;br /&gt;
TI-84 Plus CE / TI-83 Premium CE&lt;br /&gt;
 [http://ez80.readthedocs.io/en/latest/tutorial/intro.html ez80 ASM]&lt;br /&gt;
 [https://github.com/CE-Programming/ C &amp;amp; C++]&lt;br /&gt;
 [https://github.com/PeterTillema/ICE ICE]&lt;br /&gt;
 [http://tibasicdev.wikidot.com/home TI-BASIC]&lt;br /&gt;
 Python (Exclusive to the French &amp;quot;TI-83 Premium CE Edition Python&amp;quot; and European &amp;quot;TI-84 Plus CE Python Edition&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Where or how do I make programs for my calculator? ===&lt;br /&gt;
First, you will probably be using the TI-BASIC Editor found by pressing [prgm][right] and selecting the program to edit. The programs on your calc can be made to fit a certain syntax for the different compilers and parsers that you may install on your calculator. The only two languages that you can use on your calculator are TI-BASIC and hex machine code (assembly), until you install an application such as Grammer 2, Axe, or ICE. These languages enable the user to have more control over their calculator while still allowing you to program on-calc. Another thing you might consider is BASIC libraries. BASIC libraries use tokens to pass arguments to their own flash library while still executing TI-BASIC. Hex machine code is not recommended. If you insist on programming z80 on-calc, you could try [https://www.ticalc.org/archives/files/fileinfo/431/43140.html Mimas].&lt;br /&gt;
&lt;br /&gt;
If you decide to dabble in some low level programming languages you will want to use a computer. C is a [https://github.com/KnightOS/kcc work in progress] on the TI-84+ but is still used in KnightOS. C is fully supported on any ez80 calculator and C++ is getting there. You will want to use the toolchain and libraries found [https://github.com/CE-Programming/ here]. For ez80 and z80 all you need is a text editor and an [https://wikiti.brandonw.net/index.php?title=Assemblers assembler]. The two most commonly used assemblers, both for z80 and ez80, are [https://github.com/alberthdev/spasm-ng/releases spasm-ng] and [https://flatassembler.net/docs.php?article=fasmg fasmg]. spasm-ng is easier to set up, but the CE C toolchain uses fasmg because of its more advanced functionality and fewer bugs. If you would like to use fasmg on the CE, it is recommended you use the version that ships with the C toolchain as it is already set up with the correct include files.&lt;br /&gt;
&lt;br /&gt;
Below are some Online IDEs/Assemblers/Emulators&lt;br /&gt;
* [https://cemetech.net/sc/ SourceCoder3 (Cemetech)]&lt;br /&gt;
* [https://tiplanet.org/pb/ Project Builder (TI-planet)]&lt;br /&gt;
* [https://clrhome.org/asm/ ClrHome.org]&lt;br /&gt;
&lt;br /&gt;
== Other FAQs and Forum Links ==&lt;br /&gt;
* [https://omnimaga.org/ Omnimaga]&lt;br /&gt;
* [https://cemetech.net/ Cemetech]&lt;br /&gt;
* [https://codewalr.us/ CodeWalrus]&lt;br /&gt;
* [https://tiplanet.org/ TI-Planet] ''(French mostly, English spoken too)''&lt;br /&gt;
* [http://tibasicdev.wikidot.com/ TIBD]&lt;br /&gt;
* [http://tibasicdev.wikidot.com/faq TI-BASIC FAQ]&lt;br /&gt;
* [https://www.ocf.berkeley.edu/~pad/faq/index.html The Ultimate TI Calculator FAQ]&lt;br /&gt;
* [https://www.technicalc.org/tifaq/ TI Graphing Calculator FAQ]&lt;br /&gt;
* [https://www.technicalc.org/tifaq/mltifaq.txt Mattias Lindqvist's Calc-TI FAQ]&lt;br /&gt;
* [https://www.ti-89.org/faq.html The TI-89 FAQ]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:4FA8</id>
		<title>83Plus:BCALLs:4FA8</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:4FA8"/>
				<updated>2021-01-17T16:14:44Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: fix mojibake &amp;quot;âˆ’&amp;quot; which was supposed to be &amp;quot;−&amp;quot;, using ASCII &amp;quot;-&amp;quot; instead&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:BCALLs:By Name|Bit_VertSplit]] [[Category:83Plus:BCALLs:By Name:Display|Bit_VertSplit]] [[Category:83Plus:BCALLs:By Address|4FA8 - Bit_VertSplit]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Official Name:''' Bit_VertSplit&lt;br /&gt;
&lt;br /&gt;
'''BCALL Address:''' 4FA8&lt;br /&gt;
&lt;br /&gt;
Tests if the TI-83 Plus is set to G-T (graph-table) display mode.&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
''None''&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
NZ = 1 if G-T mode is set&lt;br /&gt;
&lt;br /&gt;
=== Registers Destroyed ===&lt;br /&gt;
''none''&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
Applications may want to reset the calc to full screen mode if graphing&lt;br /&gt;
functionality is used. In G-T mode the screen is split vertically with 1/2 being&lt;br /&gt;
the graph screen and the other the table display.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=User:Fghsgh</id>
		<title>User:Fghsgh</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=User:Fghsgh"/>
				<updated>2020-10-31T14:00:46Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am an 18-year-old Z80 programmer who owns one 84+ because it was mandatory at my (Belgian) school. I started learning Z80 half a year before I even got the calculator thanks to the TI Flash Debugger and the &amp;quot;Learn TI-83 Plus Assembly In 28 Days&amp;quot; tutorial by Sean McLaughlin. I am currently active on Cemetech and you can often find me on its IRC channel. Later I also got a 89T.&lt;br /&gt;
&lt;br /&gt;
I have noticed a lot of out-of-date information on this website (mainly because of new hardware revisions, probably) and asked DrDnar to change them when he revealed that he had an account here. He then told me to create my own account so here I am. I will try to update this wiki using new data I get from my own calculator and discussions we have in the chatroom.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:Raw_Flash_Commands</id>
		<title>83Plus:OS:Raw Flash Commands</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:Raw_Flash_Commands"/>
				<updated>2020-10-04T23:50:20Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: add clarifications about 68k and eZ80&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:General Hardware Information|Raw Flash Commands]]&lt;br /&gt;
[[Category:84PCSE:General Hardware Information|Raw Flash Commands]]&lt;br /&gt;
All calculators with an &amp;quot;archive&amp;quot; and upgradable OS have a flash chip whose data can be erased and rewritten. Issuing write and erase commands is done through memory-mapped writes. The flash chip will not accept any commands unless flash is unlocked. Additionally, any read from flash while issuing a command sequence will abort the command sequence. Consequentially, command sequences can only be issued from RAM and the OS interrupt must be disabled. (You can have a custom interrupt if the IVT and ISR are located in RAM.)&lt;br /&gt;
&lt;br /&gt;
Note: Although the code on this page is Z80-only, the commands described also apply to eZ80-based calculators that also have flash memory; the flash chips they use accept the same command set. However, the Z80 series requires to write a 0 over a 0, the eZ80 series doesn't care if you write a 0 or a 1 over a 0. In both cases, the resulting bit will be unchanged. Furthermore, the eZ80 series' chips have smaller sectors.&lt;br /&gt;
&lt;br /&gt;
== Chip documentation ==&lt;br /&gt;
&lt;br /&gt;
Calculators with parallel Flash use AM29F-series Flash chips, which have a common interface and are made by a number of manufacturers. For more detailed but not calculator-specific documentation, refer to [[File:AM29F400BT.pdf]], where AM29F400BT chips were used in early 83+ revisions.&lt;br /&gt;
&lt;br /&gt;
== Basic Flash Commands ==&lt;br /&gt;
It takes the flash chip a long time to perform a write or erase operation. During this time, it is impossible to read data from the flash chip, because all reads will simply report a status byte.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
You can reset the flash chip by writing 0F0h to 0000h.&lt;br /&gt;
 ld a, 0F0h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
Reset the flash chip if a program or erase operation fails, to abort either of those, and to leave autoselect mode. The flash chip does not accept resets during write or erase operations.&lt;br /&gt;
&lt;br /&gt;
=== Writing ===&lt;br /&gt;
The design of flash memory is such that a 0 can be written over a 1, but the reverse is not possible. Any write attempting to do this will fail. To write a 1 over a 0, see the below section. If it is attempted to write a 1 over a 0, the chip may fail to execute the operation. Therefore, it is a best practice to AND the value to be written with the value already there. This differs from the 68k series, where writing a 0 over a 0 will hurt the chip, and writing a 1 over a 0 will not change the value. On the eZ80 series, both are possible.&lt;br /&gt;
&lt;br /&gt;
The write command consists of a series of four writes to memory areas mapping flash. The first two writes inform the flash chip that a command is being issued (preventing accidental writes), the next informs the flash chip what you want to do, and the final gives the address you want to write to and the data to write. If any reads or out-of-sequence writes are performed before the fourth write, the command will be aborted and the actual data write will not take place. Remember to copy flash write/erase code to RAM before execution.&lt;br /&gt;
&lt;br /&gt;
The first three writes of the write sequence must be performed to addresses whose bottom 12 bits have a specific value. (TI's code writes to port 6 because they mistakenly believe 16 bits are required.) Specifically, write AA to xxxAAA, 55 to xxx555, A0 to xxxAAA, and then finally write what you want to the page and address you want.&lt;br /&gt;
&lt;br /&gt;
When a byte is read while a write operation is in progress, the value returned is a status byte, where bit 7 is the inverse of what it will be when it is finished, and bit 5 will be reset during the operation and set if an error occured. To prevent a race condition inside the flash chip's circuitry, make sure to check the value again if bit 5 is set. After this, reset the chip using the appropriate command mentioned above.&lt;br /&gt;
&lt;br /&gt;
Please note: this code needs to be rewritten.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
writeFlashByte:&lt;br /&gt;
; Writes a byte to flash.  Flash must be unlocked.  Be aware that pressing CLEAR&lt;br /&gt;
; will abort the write.&lt;br /&gt;
; Inputs:&lt;br /&gt;
;  - B: Byte to write&lt;br /&gt;
;  - C: Page&lt;br /&gt;
;  - HL: Address to write to.  This will not be wrapped.&lt;br /&gt;
; Outputs:&lt;br /&gt;
;  - NZ on failure&lt;br /&gt;
; Kills:&lt;br /&gt;
;  - AF, BC&lt;br /&gt;
; Protips:&lt;br /&gt;
;  - Calling writeFlashByteRaw instead will skip the page changing&lt;br /&gt;
;  - Do push bc \ pop af afterwards to restore flags to pre-call values.  That's&lt;br /&gt;
;    right, documented side-effect programming! &lt;br /&gt;
	in	a, (memPageAPort)	; save page&lt;br /&gt;
	push	af&lt;br /&gt;
	ld	a, c&lt;br /&gt;
	out	(6), a&lt;br /&gt;
	di&lt;br /&gt;
	call	writeFlashByteRaw&lt;br /&gt;
	ei&lt;br /&gt;
	pop	bc	; restore page without screwing up flags&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ret&lt;br /&gt;
writeFlashByteRaw:&lt;br /&gt;
; Flash program sequence&lt;br /&gt;
	ld	a, 0AAh	; First bus cycle---unlock&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Second bus cycle---unlock&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 0A0h	; Third bus cycle---write command&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	(hl), b	; Fourth bus cycle---program data&lt;br /&gt;
; Wait for the write operation to complete&lt;br /&gt;
	ld	a, 0FDh		; This checks for the CLEAR key.&lt;br /&gt;
	out	(keyPort), a		; If pressed, it aborts.&lt;br /&gt;
	inc	hl&lt;br /&gt;
	dec	hl&lt;br /&gt;
programWaitLoop:&lt;br /&gt;
	in	a, (keyPort)&lt;br /&gt;
	cp	0BFh&lt;br /&gt;
	jr	z, abortProgram&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	xor	(hl)&lt;br /&gt;
	bit	7, a&lt;br /&gt;
	jr	z, programDone&lt;br /&gt;
	bit	5, (hl)&lt;br /&gt;
	jr	z, programWaitLoop&lt;br /&gt;
abortProgram:&lt;br /&gt;
	ld	a, 0F0h&lt;br /&gt;
	ld	(0000h), a&lt;br /&gt;
	inc	a&lt;br /&gt;
programDone:&lt;br /&gt;
	ret&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erasing ===&lt;br /&gt;
The design of flash memory is such that writing a 1 over a 0 is not possible, except in large blocks known as sectors. The flash chips TI likes to use have sectors that are almost all 64 K in size, except the last, which is broken up into one 32 K sector, two 8 K sectors, and one 16 K sector (in this order). These are split and grouped into 16 K pages for memory mapping. Erase operations take a long time, during which running code from flash is impossible. If you want, you could probably make something blink or something while you're waiting.&lt;br /&gt;
&lt;br /&gt;
The status byte read has the same format as when writing a byte, but bit 7 is of course guaranteed to be reset during the operation, because the target byte is always FF.&lt;br /&gt;
&lt;br /&gt;
Please note: this code needs to be rewritten.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
eraseSector:&lt;br /&gt;
; Erases a sector of flash. Note: Use eraseSectorRaw for the certificate.&lt;br /&gt;
; Inputs:&lt;br /&gt;
;  - C: Page&lt;br /&gt;
; Outputs:&lt;br /&gt;
;  - Z on fail (this is opposite of writeFlashByte)&lt;br /&gt;
; Kills:&lt;br /&gt;
;  - AF, BC, HL&lt;br /&gt;
	in	a, (memPageAPort)&lt;br /&gt;
	push	af&lt;br /&gt;
	ld	a, c&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ld	hl, 4000h&lt;br /&gt;
	di&lt;br /&gt;
	call	eraseSectorRaw&lt;br /&gt;
	ei&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ret&lt;br /&gt;
eraseSectorRaw:&lt;br /&gt;
; Flash program sequence&lt;br /&gt;
	ld	a, 0AAh	; First bus cycle---unlock&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Second bus cycle---unlock&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 080h	; Third bus cycle---write command&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 0AAh	; Fourth bus cycle---unlock (again)&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Fifth bus cycle---unlock (again)&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 30h ; Do not change this value. You could superbrick your calculator.&lt;br /&gt;
	ld	(hl), a&lt;br /&gt;
; Wait for the erase operation to complete&lt;br /&gt;
	ld	a, 0FDh&lt;br /&gt;
	out	(keyPort), a&lt;br /&gt;
	inc	hl&lt;br /&gt;
	dec	hl        &lt;br /&gt;
eraseWaitLoop:&lt;br /&gt;
	in	a, (keyPort)&lt;br /&gt;
	cp	0BFh&lt;br /&gt;
	jr	z, abortErase&lt;br /&gt;
	ld	a, (hl)&lt;br /&gt;
	bit	7, a&lt;br /&gt;
	jr	nz, eraseDone&lt;br /&gt;
	bit	5, a&lt;br /&gt;
	jr	z, eraseWaitLoop&lt;br /&gt;
abortErase:&lt;br /&gt;
	ld	a, 0F0h&lt;br /&gt;
	ld	(4000h), a&lt;br /&gt;
	xor	a&lt;br /&gt;
eraseDone:&lt;br /&gt;
	ret&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erase Suspend ===&lt;br /&gt;
The flash chip supports suspending an erase operation in program. This allows you to read data from the flash chip again. I'm not sure why would want to do this, but&lt;br /&gt;
 ld a, 0B0h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
will suspend an erase operation. Then&lt;br /&gt;
 ld a, 30h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
will resume the erase operation. According to the data sheet, you can actually start writing data to another sector and resume the erase later.&lt;br /&gt;
&lt;br /&gt;
=== Full Chip Erase ===&lt;br /&gt;
Do not use this command under any circumstances. It will fully brick your calculator by means of erasing the boot sector(s) (and everything else). (For the skeptics, this has actually been tested.)&lt;br /&gt;
&lt;br /&gt;
The command itself is not included here for obvious reasons. In the odd case you would need it (you wouldn't), you can find it in the original datasheet.&lt;br /&gt;
&lt;br /&gt;
== Autoselect Mode ==&lt;br /&gt;
The flash chips support a set of commands known as the autoselect commands. These commands are intended to allow the flash chip to identify itself to a manufacturer and to verify that sectors are protected. However, they are also usable in-system. To use the autoselect commands, you must first unlock flash. &lt;br /&gt;
&lt;br /&gt;
The basic code for an autoselect operation is&lt;br /&gt;
 ; First bus cycle---unlock&lt;br /&gt;
 ld	a, 0AAh&lt;br /&gt;
 ld	(0AAAh), a&lt;br /&gt;
 ; Second bus cycle---unlock&lt;br /&gt;
 ld	a, 55h&lt;br /&gt;
 ld	(0555h), a&lt;br /&gt;
 ; Third bus cycle---write command&lt;br /&gt;
 ld	a, 090h&lt;br /&gt;
 ld	(0AAAh), a&lt;br /&gt;
 ; Read autoselect code&lt;br /&gt;
 ld	a, (address)&lt;br /&gt;
 ld	b, a&lt;br /&gt;
 ld	a, 0F0h ; You need to issue a reset command to exit autoselect mode&lt;br /&gt;
 ld	(0000h), a&lt;br /&gt;
where address is the code for the autoselect command. Address 0 returns the Manufacturer ID; address 2 returns the device ID. Known manufacturer IDs are&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Manufacturer&amp;lt;/u&amp;gt;&lt;br /&gt;
|&amp;lt;u&amp;gt;ID&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|01&lt;br /&gt;
|-&lt;br /&gt;
|Fujitsu&lt;br /&gt;
|04&lt;br /&gt;
|-&lt;br /&gt;
|EON (read from 200h)&lt;br /&gt;
|1C&lt;br /&gt;
|-&lt;br /&gt;
|Extended code, read real code from 200h&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|7F&lt;br /&gt;
|-&lt;br /&gt;
|Macronix&lt;br /&gt;
|C2&lt;br /&gt;
|}&lt;br /&gt;
Though the manufacturer ID changes from unit to unit, the device ID should be consistent:&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Flash Chip Size&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;ID&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|512 K (5.0 V)&lt;br /&gt;
|23&lt;br /&gt;
|-&lt;br /&gt;
|512 K (3.0 V)&lt;br /&gt;
|B9&lt;br /&gt;
|-&lt;br /&gt;
|1 MB&lt;br /&gt;
|DA&lt;br /&gt;
|-&lt;br /&gt;
|2 MB&lt;br /&gt;
|C4&lt;br /&gt;
|-&lt;br /&gt;
|4 MB&lt;br /&gt;
|A7&lt;br /&gt;
|}&lt;br /&gt;
Thus, a TI-83+SE and a TI-84+SE should both have C4 for the device ID; a TI-84+ should have DA for the device ID; and a TI-83+ should have 23 or B9 for the device.&lt;br /&gt;
&lt;br /&gt;
If you swap the first page of any sector into the 4000h memory bank and read from 4004h (or 6004h for the second half of 8 K pages), it will return whether or not that sector is protected by the flash chip's built-in write/erase lock. The older TI-83+SE and TI-84+/SE units did not use the lock feature on the boot sector(s), so they return 0 for all sectors. The TI-84+CSE and TI-84+/SEs manufactured from 2013 up till an unknown date (before 2016) DO, however, have their boot sectors locked. The flash chip's lock feature can only be overridden by applying 12 V to the correct pin. (Applying 12 V to the wrong pin will probably fry the chip.)&lt;br /&gt;
&lt;br /&gt;
It appears that TI used to use the flash chip's locking feature on the original TI-83+, because older units read 01 for sector 1Fh. (Older units read 23 for the device ID, and newer units read B9 for the device ID. It is possible that the switch to the B9 devices occurred at the same time as the switch to the ASIC for the TI-83+.) However, since at least 2007, TI has not used the locking feature on the TI-83+. These units always read 0. Therefore, it is still possible that the ASIC supports unlocking the boot sector of these units.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:Raw_Flash_Commands</id>
		<title>83Plus:OS:Raw Flash Commands</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:Raw_Flash_Commands"/>
				<updated>2020-10-04T23:31:49Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: fix accuracy issues, add more info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:General Hardware Information|Raw Flash Commands]]&lt;br /&gt;
[[Category:84PCSE:General Hardware Information|Raw Flash Commands]]&lt;br /&gt;
All calculators with an &amp;quot;archive&amp;quot; and upgradable OS have a flash chip whose data can be erased and rewritten. Issuing write and erase commands is done through memory-mapped writes. The flash chip will not accept any commands unless flash is unlocked. Additionally, any read from flash while issuing a command sequence will abort the command sequence. Consequentially, command sequences can only be issued from RAM and the OS interrupt must be disabled. (You can have a custom interrupt if the IVT and ISR are located in RAM.)&lt;br /&gt;
&lt;br /&gt;
Note: Although the code on this page is Z80-only, the commands described also apply to eZ80- and 68K-based calculators that also have flash memory; the flash chips they use accept the same command set. However, there is one important difference between the Z80 series and the 68k series. The Z80 series requires to write a 0 over a 0, the 68k series requires to write a 1 over a 0. In both cases, the resulting bit will be unchanged.&lt;br /&gt;
&lt;br /&gt;
== Basic Flash Commands ==&lt;br /&gt;
It takes the flash chip a long time to perform a write or erase operation. During this time, it is impossible to read data from the flash chip, because all reads will simply report a status byte.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
You can reset the flash chip by writing 0F0h to 0000h.&lt;br /&gt;
 ld a, 0F0h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
Reset the flash chip if a program or erase operation fails, to abort either of those, and to leave autoselect mode. The flash chip does not accept resets during write or erase operations.&lt;br /&gt;
&lt;br /&gt;
=== Writing ===&lt;br /&gt;
The design of flash memory is such that a 0 can be written over a 1, but the reverse is not possible. Any write attempting to do this will fail. To write a 1 over a 0, see the below section. If it is attempted to write a 1 over a 0, the chip may fail to execute the operation. Therefore, it is a best practice to AND the value to be written with the value already there. This differs from the 68k series, where writing a 0 over a 0 will hurt the chip, and writing a 1 over a 0 will not change the value.&lt;br /&gt;
&lt;br /&gt;
The write command consists of a series of four writes to memory areas mapping flash. The first two writes inform the flash chip that a command is being issued (preventing accidental writes), the next informs the flash chip what you want to do, and the final gives the address you want to write to and the data to write. If any reads or out-of-sequence writes are performed before the fourth write, the command will be aborted and the actual data write will not take place. Remember to copy flash write/erase code to RAM before execution.&lt;br /&gt;
&lt;br /&gt;
The first three writes of the write sequence must be performed to addresses whose bottom 12 bits have a specific value. (TI's code writes to port 6 because they mistakenly believe 16 bits are required.) Specifically, write AA to xxxAAA, 55 to xxx555, A0 to xxxAAA, and then finally write what you want to the page and address you want.&lt;br /&gt;
&lt;br /&gt;
When a byte is read while a write operation is in progress, the value returned is a status byte, where bit 7 is the inverse of what it will be when it is finished, and bit 5 will be reset during the operation and set if an error occured. To prevent a race condition inside the flash chip's circuitry, make sure to check the value again if bit 5 is set. After this, reset the chip using the appropriate command mentioned above.&lt;br /&gt;
&lt;br /&gt;
Please note: this code needs to be rewritten.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
writeFlashByte:&lt;br /&gt;
; Writes a byte to flash.  Flash must be unlocked.  Be aware that pressing CLEAR&lt;br /&gt;
; will abort the write.&lt;br /&gt;
; Inputs:&lt;br /&gt;
;  - B: Byte to write&lt;br /&gt;
;  - C: Page&lt;br /&gt;
;  - HL: Address to write to.  This will not be wrapped.&lt;br /&gt;
; Outputs:&lt;br /&gt;
;  - NZ on failure&lt;br /&gt;
; Kills:&lt;br /&gt;
;  - AF, BC&lt;br /&gt;
; Protips:&lt;br /&gt;
;  - Calling writeFlashByteRaw instead will skip the page changing&lt;br /&gt;
;  - Do push bc \ pop af afterwards to restore flags to pre-call values.  That's&lt;br /&gt;
;    right, documented side-effect programming! &lt;br /&gt;
	in	a, (memPageAPort)	; save page&lt;br /&gt;
	push	af&lt;br /&gt;
	ld	a, c&lt;br /&gt;
	out	(6), a&lt;br /&gt;
	di&lt;br /&gt;
	call	writeFlashByteRaw&lt;br /&gt;
	ei&lt;br /&gt;
	pop	bc	; restore page without screwing up flags&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ret&lt;br /&gt;
writeFlashByteRaw:&lt;br /&gt;
; Flash program sequence&lt;br /&gt;
	ld	a, 0AAh	; First bus cycle---unlock&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Second bus cycle---unlock&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 0A0h	; Third bus cycle---write command&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	(hl), b	; Fourth bus cycle---program data&lt;br /&gt;
; Wait for the write operation to complete&lt;br /&gt;
	ld	a, 0FDh		; This checks for the CLEAR key.&lt;br /&gt;
	out	(keyPort), a		; If pressed, it aborts.&lt;br /&gt;
	inc	hl&lt;br /&gt;
	dec	hl&lt;br /&gt;
programWaitLoop:&lt;br /&gt;
	in	a, (keyPort)&lt;br /&gt;
	cp	0BFh&lt;br /&gt;
	jr	z, abortProgram&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	xor	(hl)&lt;br /&gt;
	bit	7, a&lt;br /&gt;
	jr	z, programDone&lt;br /&gt;
	bit	5, (hl)&lt;br /&gt;
	jr	z, programWaitLoop&lt;br /&gt;
abortProgram:&lt;br /&gt;
	ld	a, 0F0h&lt;br /&gt;
	ld	(0000h), a&lt;br /&gt;
	inc	a&lt;br /&gt;
programDone:&lt;br /&gt;
	ret&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erasing ===&lt;br /&gt;
The design of flash memory is such that writing a 1 over a 0 is not possible, except in large blocks known as sectors. The flash chips TI likes to use have sectors that are almost all 64 K in size, except the last, which is broken up into one 32 K sector, two 8 K sectors, and one 16 K sector (in this order). Erase operations take a long time, during which running code from flash is impossible. If you want, you could probably make something blink or something while you're waiting.&lt;br /&gt;
&lt;br /&gt;
The status byte read has the same format as when writing a byte, but bit 7 is of course guaranteed to be reset during the operation, because the target byte is always FF.&lt;br /&gt;
&lt;br /&gt;
Please note: this code needs to be rewritten.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
eraseSector:&lt;br /&gt;
; Erases a sector of flash. Note: Use eraseSectorRaw for the certificate.&lt;br /&gt;
; Inputs:&lt;br /&gt;
;  - C: Page&lt;br /&gt;
; Outputs:&lt;br /&gt;
;  - Z on fail (this is opposite of writeFlashByte)&lt;br /&gt;
; Kills:&lt;br /&gt;
;  - AF, BC, HL&lt;br /&gt;
	in	a, (memPageAPort)&lt;br /&gt;
	push	af&lt;br /&gt;
	ld	a, c&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ld	hl, 4000h&lt;br /&gt;
	di&lt;br /&gt;
	call	eraseSectorRaw&lt;br /&gt;
	ei&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	a, b&lt;br /&gt;
	out	(memPageAPort), a&lt;br /&gt;
	ret&lt;br /&gt;
eraseSectorRaw:&lt;br /&gt;
; Flash program sequence&lt;br /&gt;
	ld	a, 0AAh	; First bus cycle---unlock&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Second bus cycle---unlock&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 080h	; Third bus cycle---write command&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 0AAh	; Fourth bus cycle---unlock (again)&lt;br /&gt;
	ld	(0AAAh), a&lt;br /&gt;
	ld	a, 55h	; Fifth bus cycle---unlock (again)&lt;br /&gt;
	ld	(0555h), a&lt;br /&gt;
	ld	a, 30h ; Do not change this value. You could superbrick your calculator.&lt;br /&gt;
	ld	(hl), a&lt;br /&gt;
; Wait for the erase operation to complete&lt;br /&gt;
	ld	a, 0FDh&lt;br /&gt;
	out	(keyPort), a&lt;br /&gt;
	inc	hl&lt;br /&gt;
	dec	hl        &lt;br /&gt;
eraseWaitLoop:&lt;br /&gt;
	in	a, (keyPort)&lt;br /&gt;
	cp	0BFh&lt;br /&gt;
	jr	z, abortErase&lt;br /&gt;
	ld	a, (hl)&lt;br /&gt;
	bit	7, a&lt;br /&gt;
	jr	nz, eraseDone&lt;br /&gt;
	bit	5, a&lt;br /&gt;
	jr	z, eraseWaitLoop&lt;br /&gt;
abortErase:&lt;br /&gt;
	ld	a, 0F0h&lt;br /&gt;
	ld	(4000h), a&lt;br /&gt;
	xor	a&lt;br /&gt;
eraseDone:&lt;br /&gt;
	ret&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erase Suspend ===&lt;br /&gt;
The flash chip supports suspending an erase operation in program. This allows you to read data from the flash chip again. I'm not sure why would want to do this, but&lt;br /&gt;
 ld a, 0B0h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
will suspend an erase operation. Then&lt;br /&gt;
 ld a, 30h&lt;br /&gt;
 ld (0), a&lt;br /&gt;
will resume the erase operation. According to the data sheet, you can actually start writing data to another sector and resume the erase later.&lt;br /&gt;
&lt;br /&gt;
=== Full Chip Erase ===&lt;br /&gt;
Do not use this command under any circumstances. It will fully brick your calculator by means of erasing the boot sector(s) (and everything else). (For the skeptics, this has actually been tested.)&lt;br /&gt;
&lt;br /&gt;
The command itself is not included here for obvious reasons. In the odd case you would need it (you wouldn't), you can find it in the original datasheet.&lt;br /&gt;
&lt;br /&gt;
== Autoselect Mode ==&lt;br /&gt;
The flash chips support a set of commands known as the autoselect commands. These commands are intended to allow the flash chip to identify itself to a manufacturer and to verify that sectors are protected. However, they are also usable in-system. To use the autoselect commands, you must first unlock flash. &lt;br /&gt;
&lt;br /&gt;
The basic code for an autoselect operation is&lt;br /&gt;
 ; First bus cycle---unlock&lt;br /&gt;
 ld	a, 0AAh&lt;br /&gt;
 ld	(0AAAh), a&lt;br /&gt;
 ; Second bus cycle---unlock&lt;br /&gt;
 ld	a, 55h&lt;br /&gt;
 ld	(0555h), a&lt;br /&gt;
 ; Third bus cycle---write command&lt;br /&gt;
 ld	a, 090h&lt;br /&gt;
 ld	(0AAAh), a&lt;br /&gt;
 ; Read autoselect code&lt;br /&gt;
 ld	a, (address)&lt;br /&gt;
 ld	b, a&lt;br /&gt;
 ld	a, 0F0h ; You need to issue a reset command to exit autoselect mode&lt;br /&gt;
 ld	(0000h), a&lt;br /&gt;
where address is the code for the autoselect command. Address 0 returns the Manufacturer ID; address 2 returns the device ID. Known manufacturer IDs are&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Manufacturer&amp;lt;/u&amp;gt;&lt;br /&gt;
|&amp;lt;u&amp;gt;ID&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|01&lt;br /&gt;
|-&lt;br /&gt;
|Fujitsu&lt;br /&gt;
|04&lt;br /&gt;
|-&lt;br /&gt;
|EON (read from 200h)&lt;br /&gt;
|1C&lt;br /&gt;
|-&lt;br /&gt;
|Extended code, read real code from 200h&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|7F&lt;br /&gt;
|-&lt;br /&gt;
|Macronix&lt;br /&gt;
|C2&lt;br /&gt;
|}&lt;br /&gt;
Though the manufacturer ID changes from unit to unit, the device ID should be consistent:&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Flash Chip Size&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;ID&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|512 K (5.0 V)&lt;br /&gt;
|23&lt;br /&gt;
|-&lt;br /&gt;
|512 K (3.0 V)&lt;br /&gt;
|B9&lt;br /&gt;
|-&lt;br /&gt;
|1 MB&lt;br /&gt;
|DA&lt;br /&gt;
|-&lt;br /&gt;
|2 MB&lt;br /&gt;
|C4&lt;br /&gt;
|-&lt;br /&gt;
|4 MB&lt;br /&gt;
|A7&lt;br /&gt;
|}&lt;br /&gt;
Thus, a TI-83+SE and a TI-84+SE should both have C4 for the device ID; a TI-84+ should have DA for the device ID; and a TI-83+ should have 23 or B9 for the device.&lt;br /&gt;
&lt;br /&gt;
If you swap the first page of any sector into the 4000h memory bank and read from 4004h (or 6004h for the second half of 8 K pages), it will return whether or not that sector is protected by the flash chip's built-in write/erase lock. The older TI-83+SE and TI-84+/SE units did not use the lock feature on the boot sector(s), so they return 0 for all sectors. The TI-84+CSE and TI-84+/SEs manufactured from 2013 up till an unknown date (before 2016) DO, however, have their boot sectors locked. The flash chip's lock feature can only be overridden by applying 12 V to the correct pin. (Applying 12 V to the wrong pin will probably fry the chip.)&lt;br /&gt;
&lt;br /&gt;
It appears that TI used to use the flash chip's locking feature on the original TI-83+, because older units read 01 for sector 1Fh. (Older units read 23 for the device ID, and newer units read B9 for the device ID. It is possible that the switch to the B9 devices occurred at the same time as the switch to the ASIC for the TI-83+.) However, since at least 2007, TI has not used the locking feature on the TI-83+. These units always read 0. Therefore, it is still possible that the ASIC supports unlocking the boot sector of these units.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:RST_Routines</id>
		<title>83Plus:OS:RST Routines</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:RST_Routines"/>
				<updated>2020-07-13T23:16:13Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: heard about this on #cemetech IRC&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:OS_Information|RST Routines]]&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Z80 restart instruction, or &amp;lt;code&amp;gt;RST&amp;lt;/code&amp;gt;, can be used instead of a B_CALL for some system entry points. The advantage is that using the RST instruction takes only one byte, instead of the three bytes required for a B_CALL, and is very quick when compared with the relatively large overhead inherent of a B_CALL.&lt;br /&gt;
&lt;br /&gt;
== RST Routines ==&lt;br /&gt;
All the RST routines work exactly the same as the corresponding B_CALLs:&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
| '''B_CALL''' || '''RST'''&lt;br /&gt;
|-[[83Plus:BCALLs:412F|OP1ToOP2]] || rOP1ToOP2&lt;br /&gt;
|-&lt;br /&gt;
|[[83Plus:BCALLs:42F4|FindSym]] || rFindSym&lt;br /&gt;
|-&lt;br /&gt;
|[[83Plus:BCALLs:43BA|PushRealO1]] || rPushRealO1&lt;br /&gt;
|-&lt;br /&gt;
|[[83Plus:BCALLs:417A|Mov9ToOP1]] || rMov9ToOP1&lt;br /&gt;
|-&lt;br /&gt;
|[[83Plus:BCALLs:4072|FPAdd]] || rFPAdd&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rst rFPAdd&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Equates ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
rOP1ToOP2   EQU  08h&lt;br /&gt;
rFindSym    EQU  10h&lt;br /&gt;
rPushRealO1 EQU  18h&lt;br /&gt;
rMov9ToOP1  EQU  20h&lt;br /&gt;
rFPAdd      EQU  30h&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
You cannot define your own RSTs; they are part of the operating system.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rst 00 is the OS reset&lt;br /&gt;
rst 28h is BCALL&lt;br /&gt;
rst 38h is the interrupt routine&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20</id>
		<title>83Plus:Ports:20</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20"/>
				<updated>2020-07-02T21:49:26Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: add details about TA1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|20 - CPU Speed Port]] [[Category:83Plus:Ports:By Name|CPU Speed Port]]&lt;br /&gt;
{{SE-Only Port|00}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 20h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' CPU Speed Port&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's CPU speed. The CPU can be set to run at either 6MHz or 15MHz with this port.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* 00h : The CPU is running at 6MHz.&lt;br /&gt;
* 01h: The CPU is running at 15MHz.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* 00h : Set the CPU speed to 6MHz.&lt;br /&gt;
* 01h: Set the CPU speed to 15MHz.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port is not available on the normal TI-83+. On the normal TI-83+ this port is a shadow of [[83Plus:Ports:00|Port 00h]].&lt;br /&gt;
&lt;br /&gt;
This port can contain values of 2 and 3, but the difference in speed is negligible. Michal_V has indicated that values 2 and 3 were intended for use with 20 MHz and 25 MHz speeds, but this functionality was left out before production began. Using the crystal timers I came to these approximate values.&lt;br /&gt;
{| width=&amp;quot;30%&amp;quot; border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;1&amp;quot; bgcolor=&amp;quot;white&amp;quot;&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | Port Contents&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | CPU Clock Speed&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 00&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~6.089 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 01&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.965 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 02&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.980 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 03&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.990 mhz&lt;br /&gt;
|}&lt;br /&gt;
I suggest still using 1 as the speed setting value since the speed of the other values may change in the future---unlikely as that may be---, which could seriously mess up your screen routines, or even cause opcode fetches to fail if required delay states are not configured. The slightly extra speed observed is due to capacitance of the unused pins. These modes are distinguished by LCD delaying hardware, ports 29-2C.&lt;br /&gt;
&lt;br /&gt;
Newer models (with new TA1 ASICs with fewer pins) don't show any difference between 01~03, suggesting that the extra pins for speeds 02 and 03 don't exist. Furthermore, the speed is closer to 16 MHz than it is to 15 MHz, even slightly above it on 4 out of 5 calculators I've tested.&lt;br /&gt;
&lt;br /&gt;
You can actually re-enable the extra values on production models with the TA3 ASIC if you find the right pins. On the TI-83+SE, there are helpful solder pads on the PCB; on the TI-84+/C/SE, you have to solder directly to the ASIC. You'll need to find a set of six pins, where one is a ground shared by a capacitor and two resistors, the next is connected to a capacitor, the next is connected to a resistor, the next two are not connected (solder to these pins), and the last is connected to another resistor. On the TA3 ASIC, they're pins 66-72, with 70 and 71 being the pins you want to tap (there are 144 pins, the side with #1 will be marked in some special way, and they're numbered counter-clockwise). On the TA1 ASIC, there are no known pins for this. Experiments on the TI-83+SE showed that the ASIC was unstable above about 22-23 MHz. The flash chip is only rated for 20 MHz, which could explain the instability.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a, (2)&lt;br /&gt;
 and 80h&lt;br /&gt;
 jp z, NoCPUGoverner&lt;br /&gt;
 rlca ;Move the 1 bit in bit 7 to bit 0 (80h -&amp;gt; 01h)&lt;br /&gt;
 out (20h), a&lt;br /&gt;
NoCPUGoverner:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Michael Vincent documented another method to set the CPU speed (which is probably faster than my example).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;in a, (2)&lt;br /&gt;
 rla&lt;br /&gt;
 sbc a, a&lt;br /&gt;
 out (20h), a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only side effect of this is that on the TI-83+ Basic this will cause both linkport lines to go high - which shouldn't matter too much if you're not using the linkport at that time, especially since both lines are high normally...&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Michael Vincent:''' Documentation and his faster approach as found [http://michaelv.org/programs/calcs/ports/port20.html here].&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:00</id>
		<title>83Plus:Ports:00</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:00"/>
				<updated>2020-03-17T15:14:33Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: oops I was wrong, Undo revision 11679 by Fghsgh (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|00 - Link]] [[Category:83Plus:Ports:By_Name|Link]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 00h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Link&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's serial link port (the standard link port present on the 83+, 83+ SE, 84+ and 84+ SE - do not confuse this with the 84+/84+SE's USB link port).&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bits 0 and 1: These bits indicate the state of the link port's two lines. If a bit is set that indicates the line is high, and if it is reset that indicates the line is low. When idle (no transfer in progress, no cable plugged in, etc), both lines are usually high. When a cable is connected on both ends, a line reads high if and only if both ends have set the line high. The line will read low if either calculator sets it low. Bit 0 is the tip and bit 1 is the ring.&lt;br /&gt;
*'''83+ only:''' Bit 2: Set means link receive assist is active.&lt;br /&gt;
*'''83+ only:''' Bit 3: Set when link assist has received a complete byte. The only way to reset this bit is to read [[83Plus:Ports:05|port 5]].&lt;br /&gt;
* Bit 4 and 5: Bits 4 and 5 indicate which lines are pulled low by the calculator (unlike bits 0 and 1 they are not influenced by the other calculator). A 1 bit indicates your calculator is holding the line low. A 0 bit indicates your calculator is not holding the line low. (When both calculators have a 0 bit here, the corresponding line will read 1.) In other words, these bits reflect bits 0 and 1 from the most recent write to this port.&lt;br /&gt;
* '''83+ only:''' Bit 6: Set if the link assist is currently receiving data.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bits 0 and 1: Setting a bit will pull the line low. Resetting a bit will stop holding the line low (allowing it to go high if the other calculator is not holding it low). Remember a low line will read as a bit being reset, but when writing setting a bit brings the line low.&lt;br /&gt;
*'''83+ only:''' Bit 2: Set this bit to enable the link receive assist. After setting this bit, poll port 0 until bit 3 is high, at which point read from [[83Plus:Ports:05|port 5]] to get the byte.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
=== TI-OS Interference ===&lt;br /&gt;
One thing to keep in mind when writing link port related software is that the Ti-OS checks for silent transfers in the background of input routines. When two calculators are connected and one pulls a line low, the other calculator will respond by pulling the other line low to acknowledge that it has received a bit. Even when the other calculator is running an assembly program that uses the getkey romcall. This phenomenon is known to cause severe headaches for programmers who attempt to write synchronization routines :).&lt;br /&gt;
&lt;br /&gt;
=== Data Transfer ===&lt;br /&gt;
Transferring an entire byte requires you to implement some form of protocol. Examples include TI's official linking protocol, [http://www.ticalc.org/archives/files/fileinfo/277/27718.html Michael Vincent's TachyonLink protocol] and [http://bell.timendus.com/ Timendus' Bell library].&lt;br /&gt;
&lt;br /&gt;
Other useful information on linking in general:&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/247/24750.html TI Link Protocol &amp;amp; File Format Guide]&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/294/29418.html Ti-83 Link Port Tutorial] (note that this deals with the TI-83, not the 83 Plus, where the the hardware is [[83:Ports:00|somewhat different]].)&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/242/24244.html All about the Ti-86 link port]&lt;br /&gt;
*  [http://bell.timendus.com/ Bell] and [http://clap.timendus.com/ CLAP] projects&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
=== Sending/Setting ===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,0     ; Set both lines high&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,2     ; Set tip high, ring low&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,1     ; Set tip low, ring high&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,3     ; Set both low&lt;br /&gt;
 out (0),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Receiving/Reading ===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a,(0)        ; Get link port value&lt;br /&gt;
&lt;br /&gt;
 bit 0,a         ; Check tip&lt;br /&gt;
 jr z,tip_low&lt;br /&gt;
 jr nz,tip_high&lt;br /&gt;
&lt;br /&gt;
 bit 1,a         ; Check ring&lt;br /&gt;
 jr z,ring_low&lt;br /&gt;
 jr nz,ring_high&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:00</id>
		<title>83Plus:Ports:00</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:00"/>
				<updated>2020-03-17T15:13:21Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: set reset swapped around?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|00 - Link]] [[Category:83Plus:Ports:By_Name|Link]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 00h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Link&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's serial link port (the standard link port present on the 83+, 83+ SE, 84+ and 84+ SE - do not confuse this with the 84+/84+SE's USB link port).&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bits 0 and 1: These bits indicate the state of the link port's two lines. If a bit is reset that indicates the line is high, and if it is set that indicates the line is low. When idle (no transfer in progress, no cable plugged in, etc), both lines are usually high. When a cable is connected on both ends, a line reads high if and only if both ends have set the line high. The line will read low if either calculator sets it low. Bit 0 is the tip and bit 1 is the ring.&lt;br /&gt;
*'''83+ only:''' Bit 2: Set means link receive assist is active.&lt;br /&gt;
*'''83+ only:''' Bit 3: Set when link assist has received a complete byte. The only way to reset this bit is to read [[83Plus:Ports:05|port 5]].&lt;br /&gt;
* Bit 4 and 5: Bits 4 and 5 indicate which lines are pulled low by the calculator (unlike bits 0 and 1 they are not influenced by the other calculator). A 1 bit indicates your calculator is holding the line low. A 0 bit indicates your calculator is not holding the line low. (When both calculators have a 0 bit here, the corresponding line will read 1.) In other words, these bits reflect bits 0 and 1 from the most recent write to this port.&lt;br /&gt;
* '''83+ only:''' Bit 6: Set if the link assist is currently receiving data.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bits 0 and 1: Setting a bit will pull the line low. Resetting a bit will stop holding the line low (allowing it to go high if the other calculator is not holding it low). Remember a low line will read as a bit being reset, but when writing setting a bit brings the line low.&lt;br /&gt;
*'''83+ only:''' Bit 2: Set this bit to enable the link receive assist. After setting this bit, poll port 0 until bit 3 is high, at which point read from [[83Plus:Ports:05|port 5]] to get the byte.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
=== TI-OS Interference ===&lt;br /&gt;
One thing to keep in mind when writing link port related software is that the Ti-OS checks for silent transfers in the background of input routines. When two calculators are connected and one pulls a line low, the other calculator will respond by pulling the other line low to acknowledge that it has received a bit. Even when the other calculator is running an assembly program that uses the getkey romcall. This phenomenon is known to cause severe headaches for programmers who attempt to write synchronization routines :).&lt;br /&gt;
&lt;br /&gt;
=== Data Transfer ===&lt;br /&gt;
Transferring an entire byte requires you to implement some form of protocol. Examples include TI's official linking protocol, [http://www.ticalc.org/archives/files/fileinfo/277/27718.html Michael Vincent's TachyonLink protocol] and [http://bell.timendus.com/ Timendus' Bell library].&lt;br /&gt;
&lt;br /&gt;
Other useful information on linking in general:&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/247/24750.html TI Link Protocol &amp;amp; File Format Guide]&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/294/29418.html Ti-83 Link Port Tutorial] (note that this deals with the TI-83, not the 83 Plus, where the the hardware is [[83:Ports:00|somewhat different]].)&lt;br /&gt;
*  [http://www.ticalc.org/archives/files/fileinfo/242/24244.html All about the Ti-86 link port]&lt;br /&gt;
*  [http://bell.timendus.com/ Bell] and [http://clap.timendus.com/ CLAP] projects&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
=== Sending/Setting ===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,0     ; Set both lines high&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,2     ; Set tip high, ring low&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,1     ; Set tip low, ring high&lt;br /&gt;
 out (0),a&lt;br /&gt;
&lt;br /&gt;
 ld a,3     ; Set both low&lt;br /&gt;
 out (0),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Receiving/Reading ===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a,(0)        ; Get link port value&lt;br /&gt;
&lt;br /&gt;
 bit 0,a         ; Check tip&lt;br /&gt;
 jr z,tip_low&lt;br /&gt;
 jr nz,tip_high&lt;br /&gt;
&lt;br /&gt;
 bit 1,a         ; Check ring&lt;br /&gt;
 jr z,ring_low&lt;br /&gt;
 jr nz,ring_high&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:04</id>
		<title>83Plus:Ports:04</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:04"/>
				<updated>2020-03-15T16:21:47Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: make it clear that bits 5-7 do not actually signify an interrupt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|04 - Memory Map / Interrupt]] [[Category:83Plus:Ports:By_Name|Memory Map / Interrupt]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 04h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Interrupting Device Identification and Memory Map Control&lt;br /&gt;
&lt;br /&gt;
''See also: [[83Plus:Interrupts]], [[83Plus:Memory_Mapping]]''&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bits 0~2 and 4~7 are set according to which device triggered the running interrupt.&lt;br /&gt;
** Bit 0: Set if pressing the ON Key triggered the interrupt.&lt;br /&gt;
** Bit 1: Set if the first hardware timer triggered the interrupt.&lt;br /&gt;
** Bit 2: Set if the second hardware timer triggered the interrupt.&lt;br /&gt;
** Bit 4: Link activity generated an interrupt.&lt;br /&gt;
** '''83+SE / 84+ only:''' Bit 5: First crystal timer has expired.&lt;br /&gt;
** '''83+SE / 84+ only:''' Bit 6: Second crystal timer has expired.&lt;br /&gt;
** '''83+SE / 84+ only:''' Bit 7: Third crystal timer has expired.&lt;br /&gt;
* Bit 3 is reset if the ON key is being pressed, set otherwise.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0 reset to select memory map mode 0. In mode 0 the RAM and ROM is mapped to CPU memory as follows:&lt;br /&gt;
** Address 0000h ~ 3FFFh: ROM Page 0&lt;br /&gt;
** Address 4000h ~ 7FFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]])&lt;br /&gt;
** Address 8000h ~ BFFFh: Memory Bank B (Page selected in [[83Plus:Ports:07|Port 07h]])&lt;br /&gt;
** '''83+ Basic''': Address C000h ~ FFFFh: RAM Page 0&lt;br /&gt;
** '''Everything else''': Address C000h ~ FFFFh: Page selected in [[83Plus:Ports:05|Port 05h]]&lt;br /&gt;
* Bit 0 set to select memory map mode 1. In mode 1 the RAM and ROM is mapped to CPU memory as follows:&lt;br /&gt;
** Address 0000h ~ 3FFFh: ROM Page 0&lt;br /&gt;
** Address 4000h ~ 7FFFh: Memory Bank A, ''even'' page (value of [[83Plus:Ports:06|port 06h]] ANDed with FEh)&lt;br /&gt;
** '''83+ Basic''': Address 8000h ~ BFFFh: Memory Bank A (Page selected in [[83Plus:Ports:06|Port 06h]])&lt;br /&gt;
** '''Everything else''': Address 8000h ~ BFFFh: Memory Bank A, ''odd'' page (value of [[83Plus:Ports:06|port 06h]] ORed with 1)&lt;br /&gt;
** Address C000h ~ FFFFh: Memory Bank B (Page selected in [[83Plus:Ports:07|Port 07h]])&lt;br /&gt;
* 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.&lt;br /&gt;
{| width=&amp;quot;90%&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
|+Frequency (Hz)&lt;br /&gt;
|-&lt;br /&gt;
!&amp;amp;nbsp;&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|first timer&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|second timer&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|both enabled&lt;br /&gt;
|-&lt;br /&gt;
!value&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+SE 84+(SE)&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+SE 84+(SE)&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+&lt;br /&gt;
!width=&amp;quot;15%&amp;quot;|83+SE 84+(SE)&lt;br /&gt;
|-&lt;br /&gt;
!00&lt;br /&gt;
|560||512||1120||1024||1680||1536&lt;br /&gt;
|-&lt;br /&gt;
!01&lt;br /&gt;
|248||227.55||497||455.11||746||682.66&lt;br /&gt;
|-&lt;br /&gt;
!10&lt;br /&gt;
|170||146.29||344||292.57||517||438.86&lt;br /&gt;
|-&lt;br /&gt;
!11&lt;br /&gt;
|118||107.79||236||215.58||353||323.37&lt;br /&gt;
|}&lt;br /&gt;
* Bits 3~5: Unused.&lt;br /&gt;
* Bits 6 and 7:&lt;br /&gt;
** '''83+ Basic''': No function&lt;br /&gt;
** '''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.&lt;br /&gt;
*** '''TI-83+SE''': Only has one bit, bit 7; the second bit was added for the 84-series.&lt;br /&gt;
*** '''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 &amp;quot;low&amp;quot;.&lt;br /&gt;
*** '''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&amp;amp;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.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
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.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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&amp;lt;=i&amp;lt;=3.&lt;br /&gt;
&lt;br /&gt;
Bits 5-7 will also read 1 if the timer's interrupts are disabled and the timer has expired.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
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))&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a, (7) ;Save current Bank B page because we'll trash it.&lt;br /&gt;
 push af&lt;br /&gt;
 in a,(6) ;Put this app's page into 8000&lt;br /&gt;
 out (7), a&lt;br /&gt;
 jp $ + 4003h ;This will actually jump to the next statement, but in Bank B.&lt;br /&gt;
 ld a, 77h ;Select mode 1 and keep the timer speed at normal...&lt;br /&gt;
 out (4), a ;Now we're in mode 1.&lt;br /&gt;
 ;We're still at 8000h here but we are back in Bank A.&lt;br /&gt;
 ;Now to go back.&lt;br /&gt;
 ld a, 76h ;I could dec a for this example, but...&lt;br /&gt;
 out (4), a ;Back in mode 0 and bank B.&lt;br /&gt;
 jp $ - 3FFDh ;Jump back to bank A.&lt;br /&gt;
 pop af&lt;br /&gt;
 out (7), a ;Restore bank B.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Dan Englender''': Originally documented memory map modes [http://www.detachedsolutions.com/forum/viewtopic.php?p=21593#21593 here]&lt;br /&gt;
* '''Michael Vincent''': For his docs [http://www.michaelv.org/programs/calcs/ports/port4.html here], which helped me figure out the interrupt device bits.&lt;br /&gt;
* '''James Montelongo''': For his docs [http://www.geocities.com/jimm09876/calc/port4.html here] on the hardware timer.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:30</id>
		<title>83Plus:Ports:30</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:30"/>
				<updated>2020-03-15T12:50:25Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: add cycle behavior section, source: my own experiments&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|30-38 - Timers]] [[Category:83Plus:Ports:By_Name|Timers]]&lt;br /&gt;
{{SE-Only Port|00}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 30 - 38&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Timers&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;40%&amp;quot; cellspacing=&amp;quot;1&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; |&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | On/Off&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Loop Control&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Counter&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer1&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 30&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 31&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 32&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer2&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 33&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 34&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 35&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;808080&amp;quot; | Timer3&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 36&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 37&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; bgcolor=&amp;quot;C0C0C0&amp;quot; | 38&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===On/Off ports:===&lt;br /&gt;
&lt;br /&gt;
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 &amp;amp; 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.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;30%&amp;quot; cellspacing=&amp;quot;1&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;808080&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | Value&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | Frequency&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 00h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | OFF&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | ~&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | ~&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 40h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 10922.667 Hz (32768/3)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 41h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 992.9697 Hz (32768/33)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 42h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 99.902 Hz (32768/328)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 43h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 9.9993 Hz (32768/3277)&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 44h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 32768 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 45h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 2048 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 46h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 128 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 47h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | 8 Hz&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | ~&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | ~&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 80h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock speed&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 81h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 2&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 82h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 4&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 84h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 8&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 88h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 16&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | 90h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 32&lt;br /&gt;
|- bgcolor=&amp;quot;C0C0C0&amp;quot;&lt;br /&gt;
| width=&amp;quot;20%&amp;quot; | A0h&lt;br /&gt;
| width=&amp;quot;80%&amp;quot; | CPU clock / 64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Since Silver Edition calculators CPU speed can be adjusted the timers will run at whatever the current CPU speed is(if selected of course).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loop Control ports:===&lt;br /&gt;
&lt;br /&gt;
The Loop Control ports are 31, 34, and 37.&lt;br /&gt;
&lt;br /&gt;
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 &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Counter ports:===&lt;br /&gt;
&lt;br /&gt;
The Counter ports are 32, 35, and 38.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
=== Cycle behavior ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Whether interrupts are enabled or not has no effect on this behaviour.&lt;br /&gt;
&lt;br /&gt;
== Example Code ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ;Setup up a timer that waits 2 seconds&lt;br /&gt;
   di&lt;br /&gt;
   ld a,$47      ;8 hz&lt;br /&gt;
   out ($30),a&lt;br /&gt;
   ld a,0        ; no loop, no interrupt&lt;br /&gt;
   out ($31),a&lt;br /&gt;
   ld a,16       ;16 ticks / 8 hz equals 2 seconds&lt;br /&gt;
   out ($32),a&lt;br /&gt;
wait:&lt;br /&gt;
   in a,(4)&lt;br /&gt;
   bit 5,a       ;bit 5 tells if timer 1&lt;br /&gt;
   jr z,wait     ;is done&lt;br /&gt;
   xor a&lt;br /&gt;
   out ($30),a   ;Turn off the timer.&lt;br /&gt;
   out ($31),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Michael Vincent''': Documentation found [http://www.michaelv.org/programs/calcs/rtc.txt here].&lt;br /&gt;
* '''James Montelongo''': Documentation found [http://www.geocities.com/jimm09876/calc/timers.html here].&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Talk:83Plus:OS:System_Table</id>
		<title>Talk:83Plus:OS:System Table</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Talk:83Plus:OS:System_Table"/>
				<updated>2020-03-12T23:21:16Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: Created page with &amp;quot;The object type part of T should be extended with the other possible values. ~~~~&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The object type part of T should be extended with the other possible values. [[User:Fghsgh|Fghsgh]] ([[User talk:Fghsgh|talk]]) 16:21, 12 March 2020 (PDT)&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10</id>
		<title>83Plus:Ports:10</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10"/>
				<updated>2020-03-12T23:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: change link to comments&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|10 - LCD Command/Status Port]][[Category:83Plus:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:83:Ports:By Address|10 - LCD Command/Status Port]][[Category:83:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:82:Ports:By Address|10 - LCD Command/Status Port]][[Category:82:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 10h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command and Status Port&lt;br /&gt;
&lt;br /&gt;
This port is used to check the status of and send commands to the calculator's LCD driver.&lt;br /&gt;
&lt;br /&gt;
= TI 84 Plus C SE =&lt;br /&gt;
Information on the LCD driver for the TI-84 Plus C SE is on [[84PCSE:LCD_Controller|another page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= TI-83 Plus, TI-83 Plus SE, TI-84 Plus, TI-84 Plus SE =&lt;br /&gt;
'''Note: Official documentation for the LCD controller uses &amp;quot;X&amp;quot; to refer to rows and &amp;quot;Y&amp;quot; to refer to columns.'''&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
The state of the LCD can be determined by reading this port.&lt;br /&gt;
* Bit 0: Set if auto-increment mode (commands 05 and 07) is selected, reset if auto-decrement mode (commands 04 and 06) is selected.&lt;br /&gt;
* Bit 1: Set if auto-increment or auto-decrement will affect the current column, or reset if auto-increment/decrement will affect the current row.&lt;br /&gt;
* Bit 2, 3: Not used.&lt;br /&gt;
* Bit 4: Set if in reset state, reset if in operating state. (Whatever that means.)&lt;br /&gt;
* Bit 5: Set if the display is enabled. Reset if disabled. (Note: LCD is completely turned off via [[83Plus:Ports:03|Port 03h]].)&lt;br /&gt;
* Bit 6: Set if the LCD will transfer 8 bits at a time through [[83Plus:Ports:11|Port 11]]. Reset if the LCD will only transfer 6 bits at a time.&lt;br /&gt;
* Bit 7: Set if the LCD is busy. Reset if a command can be accepted. (Not on newer models, see [[#Necessary_LCD_communication_delay|Comments]].)&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
Writing this port sends a command to the LCD. Once you send a command, wait until bit 7 reads 0 before sending another. You need a minimum delay of 10 microseconds (60 cycles of whatever else on the 6MHz TI-83+, or ~150 on a TI-83+ Silver or any TI-84+ when running in [[83Plus:Ports:20|fast mode]]).&lt;br /&gt;
&lt;br /&gt;
* 00 : Switch to '''6-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 6-bits at a time.)&lt;br /&gt;
* 01 : Switch to '''8-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 8-bits at a time.)&lt;br /&gt;
* 02 : Disable the screen. This blanks the screen and disconnects the LCD RAM from the physical screen, thus allowing you to use the LCD RAM as extra saferam. (But accessing it is so horribly slow that you should only do this if the usual saferam areas aren't enough and you don't need to display anything.)&lt;br /&gt;
* 03 : Enable the screen. This resumes displaying the LCD's RAM contents to the physical screen. (So any garbage you put into LCD RAM while it was off will show up, so B_CALL ClrLCDFull before this!)&lt;br /&gt;
* 04 : Set X auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''up''' one row.&lt;br /&gt;
* 05 : Set X auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''down''' one row. The TI-83+ expects the LCD to be in this mode for most display routines.&lt;br /&gt;
* 06 : Set Y auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''left''' one column.&lt;br /&gt;
* 07 : Set Y auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''right''' one column.&lt;br /&gt;
* [08~0B]: Set power supply enhancement. You'd be well advised to just leave this alone.&lt;br /&gt;
* [0C~0F]: Applies screen mirroring on newer calculators. Bit 0 set enables horizontal mirroring, bit 1 set enables vertical mirroring.&lt;br /&gt;
* [10~13]: Set power supply level. You'd be well advised to just leave this alone.&lt;br /&gt;
* [14~17]: Undefined.&lt;br /&gt;
* [18]: Cancel test mode (see Comments).&lt;br /&gt;
* [19~1B]: Undefined.&lt;br /&gt;
* [1C~1F]: Enter test mode (see Comments).&lt;br /&gt;
* [20~3F]: '''Set column'''.  [20~2E] are valid columns in 8-bit mode, [20~33] are valid columns in 6-bit mode. [34~3F] values are also accepted, but do not correspond to a drawable area.&lt;br /&gt;
* [40~7F]: &amp;quot;Z addressing&amp;quot; (It just changed what phyiscal row the top row of RAM is displayed on. The LCD will wrap the bottom of it's RAM to the top of the screen as needed.)&lt;br /&gt;
* [80~BF]: '''Set row'''.&lt;br /&gt;
* [C0~FF]: '''Set contrast'''. (C0 is lowest. Note that there is a [[83Plus:RAM:8447|System RAM area (contrast)]] for this which will need to be updated if you want 2nd+Up/2nd+Down to change the contrast as expected (instead of causing a sudden jump...).)&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
===Necessary LCD communication delay===&lt;br /&gt;
As mentioned, a 10 microsecond delay is required after sending the command. TI provides a routine at 000B (use normal CALL, not BCALL) that will delay the required amount of time. (Because this was not originally an LCD delay routine, on OS's prior to 1.13, calling it destroys the zero flag.)&lt;br /&gt;
&lt;br /&gt;
On older calculators, this code sequence should also provide sufficient delay while also preserving the carry flag:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ex (sp),hl ;19&lt;br /&gt;
 ex (sp),hl ;38&lt;br /&gt;
 inc (hl)   ;49&lt;br /&gt;
 dec (hl)   ;60&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But I would advise you actually make use of these waste cycles somehow (process a buffer or something).&lt;br /&gt;
&lt;br /&gt;
On some newer calculators, a fixed delay can still be used in combination with slowing the CPU through port [[83Plus:Ports:20|20]] and/or adjusting ports [[83Plus:Ports:29|29]] and [[83Plus:Ports:2A|2A]].  However, a large number of calculators have been produced recently whose LCD drivers, for whatever reason, do not respond as quickly.  For this reason, except where the speed loss is absolutely unacceptable (such as for grayscale display) fixed delays should '''not''' be used.  Instead either use the routine at 000B, or poll this port or [[83Plus:Ports:02|Port 02h]] manually.&lt;br /&gt;
&lt;br /&gt;
Since recently (late 2018), new calculators have started appearing which do not set the 7th bit when busy. Therefore, you can't use it to check if the LCD is ready. The best workaround is to wait for long enough and hope for the best, or use a different port to measure the delay.&lt;br /&gt;
&lt;br /&gt;
===Unused screen area===&lt;br /&gt;
The LCD driver's video memory holds a display 120 pixels wide, even though the screen is only 96 pixels wide.  The 24 pixel wide offscreen area can still be read from and written to, and is not affected by soft power-off.&lt;br /&gt;
&lt;br /&gt;
===Test mode===&lt;br /&gt;
This is a very dangerous mode. The first test mode command (1C~1F) causes the screen to receive an unusually high amount of energy. The result is that the screen seems to go blank, save for a single blue(!) line on the TI 83, but on the TI 84's, the entire screen turns blue! Each subsequent command adds more blue lines. After you've had your fill of blueness, exit test mode by sending a exit test mode command (18), which also sets the contrast to it's highest. Now why is it dangerous? Sure it looks cool to make a supposedly black and white LCD to display BLUE, but you are pumping so much energy through the LCD to get this effect that leaving it in this mode for too long can cause long-term damage. Ever left your monitor on for a day or two and forget to set a screen saver? Remember how when you turned it off a burnt image of your screen remained? Well that's what can happen if you leave test mode on for too long. Other possible side effects include &amp;quot;dead pixels&amp;quot; (pixels that stay off no matter what you do).&lt;br /&gt;
&lt;br /&gt;
So don't use test mode okay? Just pretend you didn't hear about it...&lt;br /&gt;
&lt;br /&gt;
On newer calculators, the test mode commands seem to be ignored, so this is yet another reason to not rely on this function.&lt;br /&gt;
&lt;br /&gt;
===Power settings===&lt;br /&gt;
On my (fghsgh's) calculator, the power supply command extends to 17. The boot code even initializes this setting to 17. Settings 10~13 all make the screen slowly fade to black, then fade to white, and then it stays blank. Writing any command in the range 14~17 makes the display come back to life. The power supply enhancement doesn't seem to do anything, but the (1.03) boot code initializes it to 0B.&lt;br /&gt;
&lt;br /&gt;
== Cursor movement and out-of-bounds behavior ==&lt;br /&gt;
It is possible to set the column number out of range, either by directly writing a column number out of bounds, or by switching to 6-bit mode, moving the column to a position outside of 8-bit mode's range, then switching back to 8-bit mode.&lt;br /&gt;
&lt;br /&gt;
If the column is out of range, no write is made to the display, but the column will continue to increment or decrement.&lt;br /&gt;
&lt;br /&gt;
===8-bit mode===&lt;br /&gt;
In 8-bit mode, the column will wrap from 14 to 0 when moving right, and wrap from 0 to 14 when moving left.  If the column&amp;gt;14, then there is no wrapping, the column will continue to increment or decrement within the full range of 0-31.  Exceeding column 31 returns to column 0.&lt;br /&gt;
&lt;br /&gt;
===6-bit-mode===&lt;br /&gt;
Same as 8-bit mode, but column wraps from 19 to 0 when moving right, and 0 to 19 when moving left.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Turn the LCD &amp;quot;off&amp;quot; and back &amp;quot;on&amp;quot;.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,02h&lt;br /&gt;
 out (10h),a&lt;br /&gt;
 ex (sp),hl ;Or do something else that takes ~60 cycles.&lt;br /&gt;
 ex (sp),hl&lt;br /&gt;
 inc (hl)&lt;br /&gt;
 dec (hl)&lt;br /&gt;
 inc a&lt;br /&gt;
 out (10h),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Safely wait for the LCD to become available&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lcd_busy_loop:&lt;br /&gt;
 in a,($10) ;bit 7 set if LCD is busy&lt;br /&gt;
 rla&lt;br /&gt;
 jr c,lcd_busy_loop&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:11|Port 11]] - LCD Data Port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10</id>
		<title>83Plus:Ports:10</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10"/>
				<updated>2020-03-12T23:13:53Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: bit 7 on new revisions: forgot one &amp;quot;not&amp;quot; which completely changes the meaning&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|10 - LCD Command/Status Port]][[Category:83Plus:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:83:Ports:By Address|10 - LCD Command/Status Port]][[Category:83:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:82:Ports:By Address|10 - LCD Command/Status Port]][[Category:82:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 10h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command and Status Port&lt;br /&gt;
&lt;br /&gt;
This port is used to check the status of and send commands to the calculator's LCD driver.&lt;br /&gt;
&lt;br /&gt;
= TI 84 Plus C SE =&lt;br /&gt;
Information on the LCD driver for the TI-84 Plus C SE is on [[84PCSE:LCD_Controller|another page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= TI-83 Plus, TI-83 Plus SE, TI-84 Plus, TI-84 Plus SE =&lt;br /&gt;
'''Note: Official documentation for the LCD controller uses &amp;quot;X&amp;quot; to refer to rows and &amp;quot;Y&amp;quot; to refer to columns.'''&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
The state of the LCD can be determined by reading this port.&lt;br /&gt;
* Bit 0: Set if auto-increment mode (commands 05 and 07) is selected, reset if auto-decrement mode (commands 04 and 06) is selected.&lt;br /&gt;
* Bit 1: Set if auto-increment or auto-decrement will affect the current column, or reset if auto-increment/decrement will affect the current row.&lt;br /&gt;
* Bit 2, 3: Not used.&lt;br /&gt;
* Bit 4: Set if in reset state, reset if in operating state. (Whatever that means.)&lt;br /&gt;
* Bit 5: Set if the display is enabled. Reset if disabled. (Note: LCD is completely turned off via [[83Plus:Ports:03|Port 03h]].)&lt;br /&gt;
* Bit 6: Set if the LCD will transfer 8 bits at a time through [[83Plus:Ports:11|Port 11]]. Reset if the LCD will only transfer 6 bits at a time.&lt;br /&gt;
* Bit 7: Set if the LCD is busy. Reset if a command can be accepted. (Not on newer models, see [[#Comments|Comments]].)&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
Writing this port sends a command to the LCD. Once you send a command, wait until bit 7 reads 0 before sending another. You need a minimum delay of 10 microseconds (60 cycles of whatever else on the 6MHz TI-83+, or ~150 on a TI-83+ Silver or any TI-84+ when running in [[83Plus:Ports:20|fast mode]]).&lt;br /&gt;
&lt;br /&gt;
* 00 : Switch to '''6-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 6-bits at a time.)&lt;br /&gt;
* 01 : Switch to '''8-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 8-bits at a time.)&lt;br /&gt;
* 02 : Disable the screen. This blanks the screen and disconnects the LCD RAM from the physical screen, thus allowing you to use the LCD RAM as extra saferam. (But accessing it is so horribly slow that you should only do this if the usual saferam areas aren't enough and you don't need to display anything.)&lt;br /&gt;
* 03 : Enable the screen. This resumes displaying the LCD's RAM contents to the physical screen. (So any garbage you put into LCD RAM while it was off will show up, so B_CALL ClrLCDFull before this!)&lt;br /&gt;
* 04 : Set X auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''up''' one row.&lt;br /&gt;
* 05 : Set X auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''down''' one row. The TI-83+ expects the LCD to be in this mode for most display routines.&lt;br /&gt;
* 06 : Set Y auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''left''' one column.&lt;br /&gt;
* 07 : Set Y auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''right''' one column.&lt;br /&gt;
* [08~0B]: Set power supply enhancement. You'd be well advised to just leave this alone.&lt;br /&gt;
* [0C~0F]: Applies screen mirroring on newer calculators. Bit 0 set enables horizontal mirroring, bit 1 set enables vertical mirroring.&lt;br /&gt;
* [10~13]: Set power supply level. You'd be well advised to just leave this alone.&lt;br /&gt;
* [14~17]: Undefined.&lt;br /&gt;
* [18]: Cancel test mode (see Comments).&lt;br /&gt;
* [19~1B]: Undefined.&lt;br /&gt;
* [1C~1F]: Enter test mode (see Comments).&lt;br /&gt;
* [20~3F]: '''Set column'''.  [20~2E] are valid columns in 8-bit mode, [20~33] are valid columns in 6-bit mode. [34~3F] values are also accepted, but do not correspond to a drawable area.&lt;br /&gt;
* [40~7F]: &amp;quot;Z addressing&amp;quot; (It just changed what phyiscal row the top row of RAM is displayed on. The LCD will wrap the bottom of it's RAM to the top of the screen as needed.)&lt;br /&gt;
* [80~BF]: '''Set row'''.&lt;br /&gt;
* [C0~FF]: '''Set contrast'''. (C0 is lowest. Note that there is a [[83Plus:RAM:8447|System RAM area (contrast)]] for this which will need to be updated if you want 2nd+Up/2nd+Down to change the contrast as expected (instead of causing a sudden jump...).)&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
===Necessary LCD communication delay===&lt;br /&gt;
As mentioned, a 10 microsecond delay is required after sending the command. TI provides a routine at 000B (use normal CALL, not BCALL) that will delay the required amount of time. (Because this was not originally an LCD delay routine, on OS's prior to 1.13, calling it destroys the zero flag.)&lt;br /&gt;
&lt;br /&gt;
On older calculators, this code sequence should also provide sufficient delay while also preserving the carry flag:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ex (sp),hl ;19&lt;br /&gt;
 ex (sp),hl ;38&lt;br /&gt;
 inc (hl)   ;49&lt;br /&gt;
 dec (hl)   ;60&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But I would advise you actually make use of these waste cycles somehow (process a buffer or something).&lt;br /&gt;
&lt;br /&gt;
On some newer calculators, a fixed delay can still be used in combination with slowing the CPU through port [[83Plus:Ports:20|20]] and/or adjusting ports [[83Plus:Ports:29|29]] and [[83Plus:Ports:2A|2A]].  However, a large number of calculators have been produced recently whose LCD drivers, for whatever reason, do not respond as quickly.  For this reason, except where the speed loss is absolutely unacceptable (such as for grayscale display) fixed delays should '''not''' be used.  Instead either use the routine at 000B, or poll this port or [[83Plus:Ports:02|Port 02h]] manually.&lt;br /&gt;
&lt;br /&gt;
Since recently (late 2018), new calculators have started appearing which do not set the 7th bit when busy. Therefore, you can't use it to check if the LCD is ready. The best workaround is to wait for long enough and hope for the best, or use a different port to measure the delay.&lt;br /&gt;
&lt;br /&gt;
===Unused screen area===&lt;br /&gt;
The LCD driver's video memory holds a display 120 pixels wide, even though the screen is only 96 pixels wide.  The 24 pixel wide offscreen area can still be read from and written to, and is not affected by soft power-off.&lt;br /&gt;
&lt;br /&gt;
===Test mode===&lt;br /&gt;
This is a very dangerous mode. The first test mode command (1C~1F) causes the screen to receive an unusually high amount of energy. The result is that the screen seems to go blank, save for a single blue(!) line on the TI 83, but on the TI 84's, the entire screen turns blue! Each subsequent command adds more blue lines. After you've had your fill of blueness, exit test mode by sending a exit test mode command (18), which also sets the contrast to it's highest. Now why is it dangerous? Sure it looks cool to make a supposedly black and white LCD to display BLUE, but you are pumping so much energy through the LCD to get this effect that leaving it in this mode for too long can cause long-term damage. Ever left your monitor on for a day or two and forget to set a screen saver? Remember how when you turned it off a burnt image of your screen remained? Well that's what can happen if you leave test mode on for too long. Other possible side effects include &amp;quot;dead pixels&amp;quot; (pixels that stay off no matter what you do).&lt;br /&gt;
&lt;br /&gt;
So don't use test mode okay? Just pretend you didn't hear about it...&lt;br /&gt;
&lt;br /&gt;
On newer calculators, the test mode commands seem to be ignored, so this is yet another reason to not rely on this function.&lt;br /&gt;
&lt;br /&gt;
===Power settings===&lt;br /&gt;
On my (fghsgh's) calculator, the power supply command extends to 17. The boot code even initializes this setting to 17. Settings 10~13 all make the screen slowly fade to black, then fade to white, and then it stays blank. Writing any command in the range 14~17 makes the display come back to life. The power supply enhancement doesn't seem to do anything, but the (1.03) boot code initializes it to 0B.&lt;br /&gt;
&lt;br /&gt;
== Cursor movement and out-of-bounds behavior ==&lt;br /&gt;
It is possible to set the column number out of range, either by directly writing a column number out of bounds, or by switching to 6-bit mode, moving the column to a position outside of 8-bit mode's range, then switching back to 8-bit mode.&lt;br /&gt;
&lt;br /&gt;
If the column is out of range, no write is made to the display, but the column will continue to increment or decrement.&lt;br /&gt;
&lt;br /&gt;
===8-bit mode===&lt;br /&gt;
In 8-bit mode, the column will wrap from 14 to 0 when moving right, and wrap from 0 to 14 when moving left.  If the column&amp;gt;14, then there is no wrapping, the column will continue to increment or decrement within the full range of 0-31.  Exceeding column 31 returns to column 0.&lt;br /&gt;
&lt;br /&gt;
===6-bit-mode===&lt;br /&gt;
Same as 8-bit mode, but column wraps from 19 to 0 when moving right, and 0 to 19 when moving left.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Turn the LCD &amp;quot;off&amp;quot; and back &amp;quot;on&amp;quot;.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,02h&lt;br /&gt;
 out (10h),a&lt;br /&gt;
 ex (sp),hl ;Or do something else that takes ~60 cycles.&lt;br /&gt;
 ex (sp),hl&lt;br /&gt;
 inc (hl)&lt;br /&gt;
 dec (hl)&lt;br /&gt;
 inc a&lt;br /&gt;
 out (10h),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Safely wait for the LCD to become available&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lcd_busy_loop:&lt;br /&gt;
 in a,($10) ;bit 7 set if LCD is busy&lt;br /&gt;
 rla&lt;br /&gt;
 jr c,lcd_busy_loop&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:11|Port 11]] - LCD Data Port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:01</id>
		<title>83Plus:Ports:01</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:01"/>
				<updated>2020-03-09T03:07:43Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: more detailed information on delay&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|01 - Keyboard]] [[Category:83Plus:Ports:By_Name|Keyboard]] [[Category:83:Ports:By_Address|01 - Keyboard]] [[Category:83:Ports:By_Name|Keyboard]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 01h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Keyboard Port&lt;br /&gt;
&lt;br /&gt;
This port reads key presses from the keypad. The keypad is divided into a series of groups.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bits are set according whether corresponding keys from selected groups are pressed. Groups are selected through writing to the port. A pressed key reads a 0 bit. An unpressed key reads a 1 bit. The port reads FF after a reset (write FF).&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* $FF : Reset the keypad. This unselects all groups and resets the keypad state.&lt;br /&gt;
* Anything else : Any 0 bit adds the corresponding group to the list of monitored groups. When a key in a monitored group is pressed, the corresponding key bit reads 0, otherwise it reads 1 (active-low).&lt;br /&gt;
&lt;br /&gt;
== Key Map ==&lt;br /&gt;
The key map is laid out as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
! Group Bit&lt;br /&gt;
| 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Group Mask&lt;br /&gt;
| FE || FD || FB || F7 || EF || DF || BF || 7F&lt;br /&gt;
|-&lt;br /&gt;
! Key Bit !! (Mask)&lt;br /&gt;
|-&lt;br /&gt;
! 0 !! (FE)&lt;br /&gt;
| DOWN||ENTER|| (-) ||  .  ||  0  ||     ||GRAPH||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 1 !! (FD)&lt;br /&gt;
| LEFT||  +  ||  3  ||  2  ||  1  || STO ||TRACE||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 2 !! (FB)&lt;br /&gt;
|RIGHT||  -  ||  6  ||  5  ||  4  || LN  ||ZOOM ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 3 !! (F7)&lt;br /&gt;
| UP  ||  *  ||  9  ||  8  ||  7  || LOG ||WIND ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 4 !! (EF)&lt;br /&gt;
|     ||  /  ||  )  ||  (  ||  ,  || x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; || Y=  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 5 !! (DF)&lt;br /&gt;
|     ||  ^  || TAN || COS || SIN ||x&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; || 2nd ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 6 !! (BF)&lt;br /&gt;
|     ||CLEAR||VARS ||PRGM ||APPS ||MATH ||MODE ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! (7F)&lt;br /&gt;
|     ||     ||     ||STAT ||X,T,&amp;amp;#952;,''n''||ALPHA|| DEL ||     ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''Note:''' Group FB Key FE is NEGATE, not to be confused with SUBTRACT.&lt;br /&gt;
* '''Note:''' Group DF Key FE would be ON, but the ON key is tested through [[83Plus:Ports:04|Port 04]], bit 3.&lt;br /&gt;
* '''Note:''' Group EF Key BF (APPS) is called MATRIX on the TI-83.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
You should disable interrupts or use a custom interrupt before manually reading this port, because TI's interrupt scans the keypad. If you leave TI's interrupt active when manually reading the keypad, sometimes it will fire between when you set and read the port, and you'll read garbage.&lt;br /&gt;
&lt;br /&gt;
All nonexistent keys read 1.&lt;br /&gt;
&lt;br /&gt;
=== Delay ===&lt;br /&gt;
TI's code always resets the keypad before scanning; sometimes, you may get incorrect values if you scan without resetting first.&lt;br /&gt;
&lt;br /&gt;
Traditionally, a delay of a dozen or so clock cycles (6 MHz mode) is used between changing key groups and reading the result. The required delay seems to vary depending on the calculator; some require no delay, others a longer one. The delay is based on real time, not CPU clock cycles; you'll need to make your delay about 3 times longer in 15 MHz mode. However, as in the example, other people seem to find that resetting before every group change negates the need for a delay; some more experimentation is required.&lt;br /&gt;
&lt;br /&gt;
For me (Sorunome) this didn't seem to work: Using the following code didn't always have the correct keygroup selected when scanning (on a TI-84+SE of a friend of mine):  &lt;br /&gt;
&amp;lt;pre&amp;gt;ld a,$ff&lt;br /&gt;
out (1),a&lt;br /&gt;
ld a,%10111110&lt;br /&gt;
out (1),a&lt;br /&gt;
in a,(1)&amp;lt;/pre&amp;gt;&lt;br /&gt;
While the following fixed it:&lt;br /&gt;
&amp;lt;pre&amp;gt;ld a,$ff&lt;br /&gt;
out (1),a&lt;br /&gt;
ld a,%10111110&lt;br /&gt;
out (1),a&lt;br /&gt;
ex (sp),hl&lt;br /&gt;
ex (sp),hl&lt;br /&gt;
in a,(1)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason for this has since been discovered to not be caused by slow hardware, but rather by capacitance in the keypad. When unselecting a group, it takes a while before the charge has dissipated. Resetting the keypad every time after using it will make this discharge happen while you're doing something else, and activating a group happens instantly. The more keys are pressed in the same keygroup, the faster the values are correct. The more keys are pressed in a different keygroup, but on the same bit, the longer you need to wait. A key that's pressed in a different keygroup on a different bit does not seem to influence the time required too much. Some combinations can take more than 50 clock cycles to deactivate, but for single keys being pressed, 8 clock cycles should be enough. However, this may vary from keypad to keypad.&lt;br /&gt;
&lt;br /&gt;
=== Ghosting ===&lt;br /&gt;
Because TI didn't add a diode to each key, you can also detect keys that aren't in a currently selected keygroup, as long as the other keygroup has at least one key in common with a selected keygroup. This means, for example, if F7 is selected, and the keys 2, 3, and 6 are pressed, Then keygroup FB will also be activated because F7 and FB have one key in common (namely FD). This makes it appear as though the 5 key is also pressed. This can also be used to make nonexistent keys appear active. However, as at least three keys have to be pressed for it to be noticeable, you don't have to worry in the most common use cases.&lt;br /&gt;
&lt;br /&gt;
=== Debouncing ===&lt;br /&gt;
While a key is in a state between pressed and released, it will repeatedly turn on and off. If you are reading the keypad extremely quickly, it will appear as though the key is being pressed and released a number of times. You need to either wait longer between keypad scans, or you need to implement a proper debouncing algorithm. TI-OS does the first one by scanning the keypad in an interrupt that runs slowly enough for it to not have a noticeable effect.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ld a, 0FFh ;Reset the keypad.&lt;br /&gt;
out (1), a&lt;br /&gt;
ld a, 0FEh ;Select group 0.&lt;br /&gt;
out (1), a&lt;br /&gt;
in a, (1) ;Test for keys.&lt;br /&gt;
and 2 ;Test for Left Arrow key by making A 0 if left was pressed.&lt;br /&gt;
call z, LeftArrowPressed ;If 0 then left was pressed.&lt;br /&gt;
ld a, 0FFh ;Reset the keypad.&lt;br /&gt;
out (1), a&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Talk:83Plus:Ports:01</id>
		<title>Talk:83Plus:Ports:01</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Talk:83Plus:Ports:01"/>
				<updated>2020-03-09T02:54:42Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: new information on delay and ghosting sources&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==new information==&lt;br /&gt;
This information isn't that new, but I'm putting my source for what I wrote a few days ago here: https://www.omnimaga.org/asm-language/port-1-stuff/msg384239/#msg384239 (mainly about the delay and resetting, but it also casually mentions ghosting) and https://www.omnimaga.org/asm-language/(8x)-keyboard-madness/msg407118/#msg407118 (ghosting) [[User:Fghsgh|Fghsgh]] ([[User talk:Fghsgh|talk]]) 19:54, 8 March 2020 (PDT)&lt;br /&gt;
&lt;br /&gt;
==reset needed==&lt;br /&gt;
From my experimentation with PindurTI, it seems to me that it is impossible to poll more than one group without reseting the keyport in betweeen. Being that I have never tested any direct key input routines.  I know the directin routine from MirageOS resets before polling, and LearnAsm28d merely says that one &amp;quot;should&amp;quot; reset the port before switching groups. I hesitate to add this to the comments section without further confirmation. [[User:Saibot84|Saibot84]] 21:48, 1 June 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
:Well, for one 28days is not the best reference for hardware. And pindur is an emulator, so it has the limitations of the PC hardware and what CoBB was willing to put in.   However, I decided to check this more since some people keep bringing it up.  I have to say my result is not what I expected.  It seems  that it's possible that groups not even being monitored can affect what is read.  I wrote this test program: [http://jim.revsoft.org/code/key.zip Link for download].  It checks the top row and the arrow group.&lt;br /&gt;
&lt;br /&gt;
{| WIDTH=600 BORDER=1 CELLPADDING=1 CELLSPACING=1 STYLE=&amp;quot;page-break-before: always&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Actually being pressed&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Arrow&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Top Row&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Setting arrow without reset&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Both arrow and top row&amp;lt;/P&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Down&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111111&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Zoom &amp;amp; Graph&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111111&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111111&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Zoom &amp;amp; Graph &amp;amp; Down&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111010&amp;lt;/P&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Down &amp;amp; 0 &amp;amp; Sin&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11011110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111111&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11011110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11011110&amp;lt;/P&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;Down &amp;amp; sin&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111111&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
| WIDTH=120 | &amp;lt;P ALIGN=CENTER&amp;gt;11111110&amp;lt;/P&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
It seems to be a bug in hardware, dealing with when multiple keys are being pressed.  It looks like the AND logic doesn't exists as much as we all thought before. Still though TI set the convention of reseting the key port, but they do it following reads, that may have an impact on the results.  Though we still need more confirmation, I tested this with an 83+, 83+SE and 84+SE. --[[User:Jim e|Jim e]] 09:14, 2 June 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Actually, your results look exactly like what I would expect.  You need to keep in mind that all of the keys are eventually connected to the same &amp;quot;matrix.&amp;quot;  (This is true of most keyboards; we've discussed its effects on the [[Talk:83Plus:OS:TI_Keyboard|TI Keyboard]] in the past.)  Let's simplify the problem: say you have a keyboard with only four keys on it, arranged as follows:&lt;br /&gt;
   |    |&lt;br /&gt;
 -(A)--(B)-&lt;br /&gt;
   |    |&lt;br /&gt;
 -(C)--(D)-&lt;br /&gt;
   |    |&lt;br /&gt;
:Pressing one of the keys A, B, C, or D results in a (very low-resistance) electrical connection between the vertical and horizontal trace.  So, to scan one column of the keyboard, we connect that vertical trace to ground while leaving the other disconnected.  Meanwhile we connect each horizontal trace to +5V through a large resistor.  (OK, I don't know if that's exactly how it works in the TI, but let's pretend it does.)  If we connect the first vertical trace to ground and we see that the first horizontal trace is high and the second is low, we can infer that the C key has been pressed.&lt;br /&gt;
:But... what happens when you press A, B, and C all at once?  If we pull just the first vertical trace low, obviously both horizontal traces go low.  If we pull just the second vertical trace low... still both horizontal traces are low!  This is because current can flow from the C key to the A key to the B key.  It doesn't matter whether D is pressed or not.  And in fact, there is no reliable way (in software) for us to tell which three of the four keys have been pressed.&lt;br /&gt;
:I would guess that the reason for &amp;quot;resetting&amp;quot; port 1 each time, and for the delay between writing and reading, is to give the input some time to stabilize (it is, after all, an analog signal... the resistance of each key depends on how hard the user is pressing it.)  Which in turn will decrease the bouncing effect, which is really important for TIOS, but less important for your average game.&lt;br /&gt;
:So that's my non-electrical-engineer's answer :) [[User:FloppusMaximus|FloppusMaximus]] 08:34, 4 June 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
actualy, this is wrong..&lt;br /&gt;
the system looks like this&lt;br /&gt;
&lt;br /&gt;
     (port, bit 0)&lt;br /&gt;
       *--I--|&lt;br /&gt;
             |      bit n, output&lt;br /&gt;
 |----^      |&lt;br /&gt;
 |  &amp;lt;   &amp;gt;----O--I-  3&lt;br /&gt;
 |  | V------O--I-  2&lt;br /&gt;
 |  *--------O--I-  1&lt;br /&gt;
 *-----------O--I-  0&lt;br /&gt;
&lt;br /&gt;
those bit O's are AND switches whit the port (port input is inverted first) &amp;lt;br&amp;gt;&lt;br /&gt;
the I's are NOT switches &amp;lt;br&amp;gt;&lt;br /&gt;
- and | and * are wires &amp;lt;br&amp;gt;&lt;br /&gt;
i guess the reseting does only matter if you dont wair the required amount of time &amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Darkstone knight|Darkstone knight]] 01:17, 11 November 2008 (PST)&lt;br /&gt;
&lt;br /&gt;
notice this is all theory.... i havent actualy tesed it myself [[User:Darkstone knight|Darkstone knight]] 01:25, 11 November 2008 (PST)&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10</id>
		<title>83Plus:Ports:10</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10"/>
				<updated>2020-03-08T01:43:23Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: new LCDs don't read bit 7 correctly&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|10 - LCD Command/Status Port]][[Category:83Plus:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:83:Ports:By Address|10 - LCD Command/Status Port]][[Category:83:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:82:Ports:By Address|10 - LCD Command/Status Port]][[Category:82:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 10h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command and Status Port&lt;br /&gt;
&lt;br /&gt;
This port is used to check the status of and send commands to the calculator's LCD driver.&lt;br /&gt;
&lt;br /&gt;
= TI 84 Plus C SE =&lt;br /&gt;
Information on the LCD driver for the TI-84 Plus C SE is on [[84PCSE:LCD_Controller|another page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= TI-83 Plus, TI-83 Plus SE, TI-84 Plus, TI-84 Plus SE =&lt;br /&gt;
'''Note: Official documentation for the LCD controller uses &amp;quot;X&amp;quot; to refer to rows and &amp;quot;Y&amp;quot; to refer to columns.'''&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
The state of the LCD can be determined by reading this port.&lt;br /&gt;
* Bit 0: Set if auto-increment mode (commands 05 and 07) is selected, reset if auto-decrement mode (commands 04 and 06) is selected.&lt;br /&gt;
* Bit 1: Set if auto-increment or auto-decrement will affect the current column, or reset if auto-increment/decrement will affect the current row.&lt;br /&gt;
* Bit 2, 3: Not used.&lt;br /&gt;
* Bit 4: Set if in reset state, reset if in operating state. (Whatever that means.)&lt;br /&gt;
* Bit 5: Set if the display is enabled. Reset if disabled. (Note: LCD is completely turned off via [[83Plus:Ports:03|Port 03h]].)&lt;br /&gt;
* Bit 6: Set if the LCD will transfer 8 bits at a time through [[83Plus:Ports:11|Port 11]]. Reset if the LCD will only transfer 6 bits at a time.&lt;br /&gt;
* Bit 7: Set if the LCD is busy. Reset if a command can be accepted. (Also see [[#Comments|Comments]].)&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
Writing this port sends a command to the LCD. Once you send a command, wait until bit 7 reads 0 before sending another. You need a minimum delay of 10 microseconds (60 cycles of whatever else on the 6MHz TI-83+, or ~150 on a TI-83+ Silver or any TI-84+ when running in [[83Plus:Ports:20|fast mode]]).&lt;br /&gt;
&lt;br /&gt;
* 00 : Switch to '''6-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 6-bits at a time.)&lt;br /&gt;
* 01 : Switch to '''8-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 8-bits at a time.)&lt;br /&gt;
* 02 : Disable the screen. This blanks the screen and disconnects the LCD RAM from the physical screen, thus allowing you to use the LCD RAM as extra saferam. (But accessing it is so horribly slow that you should only do this if the usual saferam areas aren't enough and you don't need to display anything.)&lt;br /&gt;
* 03 : Enable the screen. This resumes displaying the LCD's RAM contents to the physical screen. (So any garbage you put into LCD RAM while it was off will show up, so B_CALL ClrLCDFull before this!)&lt;br /&gt;
* 04 : Set X auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''up''' one row.&lt;br /&gt;
* 05 : Set X auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''down''' one row. The TI-83+ expects the LCD to be in this mode for most display routines.&lt;br /&gt;
* 06 : Set Y auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''left''' one column.&lt;br /&gt;
* 07 : Set Y auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''right''' one column.&lt;br /&gt;
* [08~0B]: Set power supply enhancement. You'd be well advised to just leave this alone.&lt;br /&gt;
* [0C~0F]: Applies screen mirroring on newer calculators. Bit 0 set enables horizontal mirroring, bit 1 set enables vertical mirroring.&lt;br /&gt;
* [10~13]: Set power supply level. You'd be well advised to just leave this alone.&lt;br /&gt;
* [14~17]: Undefined.&lt;br /&gt;
* [18]: Cancel test mode (see Comments).&lt;br /&gt;
* [19~1B]: Undefined.&lt;br /&gt;
* [1C~1F]: Enter test mode (see Comments).&lt;br /&gt;
* [20~3F]: '''Set column'''.  [20~2E] are valid columns in 8-bit mode, [20~33] are valid columns in 6-bit mode. [34~3F] values are also accepted, but do not correspond to a drawable area.&lt;br /&gt;
* [40~7F]: &amp;quot;Z addressing&amp;quot; (It just changed what phyiscal row the top row of RAM is displayed on. The LCD will wrap the bottom of it's RAM to the top of the screen as needed.)&lt;br /&gt;
* [80~BF]: '''Set row'''.&lt;br /&gt;
* [C0~FF]: '''Set contrast'''. (C0 is lowest. Note that there is a [[83Plus:RAM:8447|System RAM area (contrast)]] for this which will need to be updated if you want 2nd+Up/2nd+Down to change the contrast as expected (instead of causing a sudden jump...).)&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
===Necessary LCD communication delay===&lt;br /&gt;
As mentioned, a 10 microsecond delay is required after sending the command. TI provides a routine at 000B (use normal CALL, not BCALL) that will delay the required amount of time. (Because this was not originally an LCD delay routine, on OS's prior to 1.13, calling it destroys the zero flag.)&lt;br /&gt;
&lt;br /&gt;
On older calculators, this code sequence should also provide sufficient delay while also preserving the carry flag:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ex (sp),hl ;19&lt;br /&gt;
 ex (sp),hl ;38&lt;br /&gt;
 inc (hl)   ;49&lt;br /&gt;
 dec (hl)   ;60&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But I would advise you actually make use of these waste cycles somehow (process a buffer or something).&lt;br /&gt;
&lt;br /&gt;
On some newer calculators, a fixed delay can still be used in combination with slowing the CPU through port [[83Plus:Ports:20|20]] and/or adjusting ports [[83Plus:Ports:29|29]] and [[83Plus:Ports:2A|2A]].  However, a large number of calculators have been produced recently whose LCD drivers, for whatever reason, do not respond as quickly.  For this reason, except where the speed loss is absolutely unacceptable (such as for grayscale display) fixed delays should '''not''' be used.  Instead either use the routine at 000B, or poll this port or [[83Plus:Ports:02|Port 02h]] manually.&lt;br /&gt;
&lt;br /&gt;
Since recently (late 2018), new calculators have started appearing which set the 7th bit when busy. Therefore, you can't use it to check if the LCD is ready. The best workaround is to wait for long enough and hope for the best, or use a different port.&lt;br /&gt;
&lt;br /&gt;
===Unused screen area===&lt;br /&gt;
The LCD driver's video memory holds a display 120 pixels wide, even though the screen is only 96 pixels wide.  The 24 pixel wide offscreen area can still be read from and written to, and is not affected by soft power-off.&lt;br /&gt;
&lt;br /&gt;
===Test mode===&lt;br /&gt;
This is a very dangerous mode. The first test mode command (1C~1F) causes the screen to receive an unusually high amount of energy. The result is that the screen seems to go blank, save for a single blue(!) line on the TI 83, but on the TI 84's, the entire screen turns blue! Each subsequent command adds more blue lines. After you've had your fill of blueness, exit test mode by sending a exit test mode command (18), which also sets the contrast to it's highest. Now why is it dangerous? Sure it looks cool to make a supposedly black and white LCD to display BLUE, but you are pumping so much energy through the LCD to get this effect that leaving it in this mode for too long can cause long-term damage. Ever left your monitor on for a day or two and forget to set a screen saver? Remember how when you turned it off a burnt image of your screen remained? Well that's what can happen if you leave test mode on for too long. Other possible side effects include &amp;quot;dead pixels&amp;quot; (pixels that stay off no matter what you do).&lt;br /&gt;
&lt;br /&gt;
So don't use test mode okay? Just pretend you didn't hear about it...&lt;br /&gt;
&lt;br /&gt;
On newer calculators, the test mode commands seem to be ignored, so this is yet another reason to not rely on this function.&lt;br /&gt;
&lt;br /&gt;
===Power settings===&lt;br /&gt;
On my (fghsgh's) calculator, the power supply command extends to 17. The boot code even initializes this setting to 17. Settings 10~13 all make the screen slowly fade to black, then fade to white, and then it stays blank. Writing any command in the range 14~17 makes the display come back to life. The power supply enhancement doesn't seem to do anything, but the (1.03) boot code initializes it to 0B.&lt;br /&gt;
&lt;br /&gt;
== Cursor movement and out-of-bounds behavior ==&lt;br /&gt;
It is possible to set the column number out of range, either by directly writing a column number out of bounds, or by switching to 6-bit mode, moving the column to a position outside of 8-bit mode's range, then switching back to 8-bit mode.&lt;br /&gt;
&lt;br /&gt;
If the column is out of range, no write is made to the display, but the column will continue to increment or decrement.&lt;br /&gt;
&lt;br /&gt;
===8-bit mode===&lt;br /&gt;
In 8-bit mode, the column will wrap from 14 to 0 when moving right, and wrap from 0 to 14 when moving left.  If the column&amp;gt;14, then there is no wrapping, the column will continue to increment or decrement within the full range of 0-31.  Exceeding column 31 returns to column 0.&lt;br /&gt;
&lt;br /&gt;
===6-bit-mode===&lt;br /&gt;
Same as 8-bit mode, but column wraps from 19 to 0 when moving right, and 0 to 19 when moving left.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Turn the LCD &amp;quot;off&amp;quot; and back &amp;quot;on&amp;quot;.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,02h&lt;br /&gt;
 out (10h),a&lt;br /&gt;
 ex (sp),hl ;Or do something else that takes ~60 cycles.&lt;br /&gt;
 ex (sp),hl&lt;br /&gt;
 inc (hl)&lt;br /&gt;
 dec (hl)&lt;br /&gt;
 inc a&lt;br /&gt;
 out (10h),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Safely wait for the LCD to become available&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lcd_busy_loop:&lt;br /&gt;
 in a,($10) ;bit 7 set if LCD is busy&lt;br /&gt;
 rla&lt;br /&gt;
 jr c,lcd_busy_loop&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:11|Port 11]] - LCD Data Port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages</id>
		<title>83Plus:OS:Ram Pages</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages"/>
				<updated>2020-03-04T19:44:02Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: grammatical incoherence fix and spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:OS_Information|Ram Pages]]&lt;br /&gt;
&lt;br /&gt;
This is to mark what ram pages may be used for short term or long term use.&lt;br /&gt;
&lt;br /&gt;
'''It should be noted that on the newer calculator models ([[83Plus:Ports:15|port 15]] &amp;gt;= 55h) pages 82-87 refer to the same physical memory'''&lt;br /&gt;
&lt;br /&gt;
'''80'''&lt;br /&gt;
* Default for TIOS at C000h&lt;br /&gt;
* Execution protected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''81'''&lt;br /&gt;
* Default for TIOS at 8000h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''82'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''83'''&lt;br /&gt;
* OS 2.x uses at least some of the range 4000h through 4080h to store app base pages prior to app execution. This is always regenerated and the OS doesn't seem to have any issue when you modify it.&lt;br /&gt;
* 4100h through 433Ah is used for various buffers during USB communication.&lt;br /&gt;
* On OSes with MathPrint, 577Eh through 5A7Dh is used to store the previous entries (command history). When this is modified, the calculator will crash if you scroll up on the homescreen past the program that modified it. Write 00 to 8E29 (numLastEntries) to prevent the user from scrolling up and to avoid the crash. This does not cause a memory leak and has no effect on older OSes (except with the OmniCalc entries menu). Zeroing this out doesn't seem to be necessary. Beware that on 48 KiB models, any page in the 82-87 range maps to this page.&lt;br /&gt;
* On OSes with MathPrint, 5A7Eh through 5D7Dh is the homescreen graph buffer. Modifying this has caused flickering for some. You'll probably want to zero this if you use it.&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Temporary swap for Virtual Calc by Michael Vincent&lt;br /&gt;
** Temporary code execution for Real Sound by James Montelongo&lt;br /&gt;
** Temporary CALCnet buffers for direct USB for Doors CS 7.2 and higher by Christopher &amp;quot;Kerm Martian&amp;quot; Mitchell&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''84'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Virtual Calc by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''85'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Virtual Calc by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''86'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Restore Mem by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
'''87'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Restore Mem by Michael Vincent&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:OS_2.53MP_Changes</id>
		<title>83Plus:OS:OS 2.53MP Changes</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:OS_2.53MP_Changes"/>
				<updated>2020-03-04T19:42:20Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: Change memory addresses to bank A as this is more standard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;2.53 has been released officially. Merger with [[83Plus:OS:VersionDifferences]] will happen when it happens.&lt;br /&gt;
&lt;br /&gt;
To disable MathPrint: Press MODE, up, and select CLASSIC, not MATHPRINT.&lt;br /&gt;
&lt;br /&gt;
= Added Features =&lt;br /&gt;
* MathPrint is TI's own pretty printing.  All the cool companies are using CamelCaps!&lt;br /&gt;
* New menu Alpha+F1-F4 for use with MathPrint.  All these new tokens have been moved to logical menu, except the fraction-related tokens. These are not in the symbol section of the Catalog.&lt;br /&gt;
* In MathPrint, press up to scroll through previous entries, which allows basic copy and paste.&lt;br /&gt;
* The WINDOW screen now has an option for setting &amp;amp;Delta;X, but not &amp;amp;Delta;Y. The ability to store directly to the &amp;amp;Delta;X and &amp;amp;Delta;Y tokens has always existed.&lt;br /&gt;
* The TABLE screen now has a shortcut for setting &amp;amp;Delta;Tbl.&lt;br /&gt;
* New ZOptions under ZOOM&lt;br /&gt;
* Catalog help updated. Exactly what has changed remains a mystery, as the new tokens haven't been added. Note that the old Catalog Help 83 app gives a version error when run. See [http://education.ti.com/educationportal/downloadcenter/SoftwareDetail.do?website=US&amp;amp;tabId=1&amp;amp;appId=164 http://education.ti.com/educationportal/downloadcenter/SoftwareDetail.do?website=US&amp;amp;tabId=1&amp;amp;appId=164] to download the latest version. It's interesting to note that even the splash screen still says &amp;quot;TI-83 Plus&amp;quot; and &amp;quot;(C) Texas Instruments 2009&amp;quot;.&lt;br /&gt;
* If an error occurred in a program, an &amp;quot;Error&amp;quot; message is displayed in place of the default &amp;quot;Done&amp;quot; message on the home screen.&lt;br /&gt;
* When the ENTER key is pressed, e.g. to re-evaluate a command or to rerun a program, the last entry is automatically displayed. For example, if you type in 2+2 and press ENTER, it will return 4. If you press ENTER again, then, instead of simply displaying the answer on a new line, it displays the entry 2+2 again and the answer on new lines.&lt;br /&gt;
On the old OS:&lt;br /&gt;
 2+2&lt;br /&gt;
       4&lt;br /&gt;
       4&lt;br /&gt;
&lt;br /&gt;
On the new OS:&lt;br /&gt;
 2+2&lt;br /&gt;
       4&lt;br /&gt;
 2+2&lt;br /&gt;
       4&lt;br /&gt;
&lt;br /&gt;
== New Tokens ==&lt;br /&gt;
* AUTO Answer -- basic [EF 3B]&lt;br /&gt;
* CLASSIC -- basic [EF 38]&lt;br /&gt;
* DEC Answer -- basic [EF 3C]&lt;br /&gt;
* &amp;amp;#x25b6;F&amp;amp;#x25c0;&amp;amp;#x25b6;D -- swap between fraction and decimal [EF 31]&lt;br /&gt;
* FRAC Answer -- basic [EF 3D]&lt;br /&gt;
* logBASE( -- log to any base, logBASE(x,base [EF 34]&lt;br /&gt;
* MATHPRINT  -- basic [EF 37]&lt;br /&gt;
* n'''/'''d - normal fraction, numerator n'''/'''d denominator [EF 2E]&lt;br /&gt;
* &amp;amp;#x25b6;n'''/'''d&amp;amp;#x25c0;&amp;amp;#x25b6;Un'''/'''d -- swap between improper and proper fractions in MathPrint [EF 30]&lt;br /&gt;
* randIntNoRep( -- gives a list of random integers, with dimension high-low+1 randIntNoRep(low,high [EF 35]&lt;br /&gt;
* remainder( --  essentially modulo, x % y, remainder(x,y [EF 32]&lt;br /&gt;
* summation  &amp;amp;sum;( --  &amp;amp;sum;(expression,variable,start,end [EF 33]&lt;br /&gt;
* Un'''/'''d -- mixed number, whole Un/d numerator n/d denominator [EF 2F]&lt;br /&gt;
* ZFrac1'''/'''2, -- delta-x,y = 1/2, graph centered [EF 18]&lt;br /&gt;
* ZFrac1'''/'''3, -- delta-x,y = 1/3, graph centered [EF 19]&lt;br /&gt;
* ZFrac1'''/'''4, -- delta-x,y = 1/4, graph centered [EF 1A]&lt;br /&gt;
* ZFrac1'''/'''5, -- delta-x,y = 1/5, graph centered [EF 1B]&lt;br /&gt;
* ZFrac1'''/'''8, -- delta-x,y = 1/8, graph centered [EF 1C]&lt;br /&gt;
* ZFrac1'''/'''10, -- delta-x,y = 1/10, graph centered [EF 1D]&lt;br /&gt;
* ZQuadrant1, [EF 17]&lt;br /&gt;
* fraction related tokens&lt;br /&gt;
** _, EF2F, not the same as printing _. New font codepoint 0F5h.&lt;br /&gt;
** '''/''', EF2E, not the same as division /. New font codepoint 0F6h.&lt;br /&gt;
* &amp;amp;#x2b1a;box, EF1E. New font codepoint 0F7h.&lt;br /&gt;
&lt;br /&gt;
== Flags ==&lt;br /&gt;
* 5, (iy+44h) MathPrint. You should clear the screen as well as fill [[83Plus:RAM:966E|CmdShadow]] and [[83Plus:RAM:8508|TextShadow]] 20h's if you change this flag.&lt;br /&gt;
* 0, (iy+48h) controls the fraction mode&lt;br /&gt;
* bits 1 and 4 of (iy+47h) are related to when the OS decides to format an answer as a fraction&lt;br /&gt;
* 4, (iy+45h): set this to disable the message about shortcut menus from Press-to-Test. Not affected by Reset Defaults, though MathPrint is.&lt;br /&gt;
&lt;br /&gt;
== Bcalls ==&lt;br /&gt;
96 new bcalls added. &amp;lt;!--Really? Just 96 for all this new functionality?--&amp;gt;&lt;br /&gt;
* 5410h -- alpha menu reminder pop up&lt;br /&gt;
&lt;br /&gt;
== Memory ==&lt;br /&gt;
* RAM page 3, 577Eh–5A7Dh -- previous entries. Destroying this causes crashes.&lt;br /&gt;
* RAM page 3, 5A7Eh–5D7Dh -- homescreen graph buffer. Zero after destroying to prevent flicker.&lt;br /&gt;
&lt;br /&gt;
= Compatibility Issues =&lt;br /&gt;
* Programs using the homescreen may be very broken graphically. This includes applications that do strange things on the homescreen. Users should disable MathPrint before running them, and programs should definitely clear the screen first thing. Whether or not this is sufficient to ensure normal operation or if disabling MathPrint too is required requires further investigation; it appears that just clearing the screen is enough for now.&lt;br /&gt;
* Programs that encounter an error on the graphscreen may end up with the graphscreen contents in the homescreen buffer&lt;br /&gt;
* In Omnicalc, parenthesis assistant does not work properly. (Display error)&lt;br /&gt;
* In Omnicalc's entries menu: Using the entries menu without MathPrint symbols has some display issues, and when selecting an entry, it crashes.&lt;br /&gt;
* In Omnicalc's entries menu: With MathPrint symbols in the entries log, there are serious display issues accompanied with a dramatic crash.&lt;br /&gt;
* Omnicalc's partial line clearing (always enabled) crashes or glitches when you try to use it in MathPrint.&lt;br /&gt;
* All custom fonts of Omnicalc will need to be updated with the new font codepoints or else MathPrint will not look right.&lt;br /&gt;
* Calcutil will sometimes not run correctly and will crash your calculator when you turn it off and back on. This doesn't happen on some user's calculators.&lt;br /&gt;
* ld a,1 \ ld (appInfo+2),a \ bcall($50CB) no longer unlocks the flash ROM.&lt;br /&gt;
* Outputting something at the end of a program no longer prevents the &amp;quot;Done&amp;quot; message from displaying.&lt;br /&gt;
&lt;br /&gt;
= Performance Issues =&lt;br /&gt;
* Disp and Output may be up to 4× slower than on previous OS version when MathPrint is enabled (see [http://www.cemetech.net/forum/viewtopic.php?p=93740#93740 TI-84+ OS v2.53 Leaked])&lt;br /&gt;
* When MathPrint is enabled, when you go to the &amp;quot;Y=&amp;quot; menu to type a function, it's displaying slowly the Y&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, Y&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, Y&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt;, Y&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Bugs =&lt;br /&gt;
This is for bugs or strange functionality. Note the above &amp;quot;Compatibility Issues&amp;quot; section; use that for issues with third-party software.&lt;br /&gt;
* MathPrint Bug: When a list is displayed as a result, you can't take it back for you new entry: selecting it and pressing enter doesn't work&lt;br /&gt;
* MathPrint can't handle overly complex expressions; specifically, nesting multiple levels of fractions and the pretty printed FUNC symbols will eventually cause the calculator to refuse to let you nest any further. In practice, this limit may rarely, if ever, be encountered in the classroom. If your expression is starting to require vertical scrolling, expect to encounter the old out-of-memory checkered box soon. Try to recall this expression and it won't get fully MathPrintified.&lt;br /&gt;
* It is not possible to calculate the inverse of a matrix in MathPrint mode. This is because the OS converts the &amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; token into the into the token sequence ^(-1), and there appears to be no way to override this behavior. This is because the OS interprets (and has always interpreted) the &amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; token as a request for the inverse, whereas it thinks using ^ means you want to raise the matrix to a power, and giving it a negative number means division.&lt;br /&gt;
* There are definitely stability issues with MathPrint, even without the help of assembly programs.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages</id>
		<title>83Plus:OS:Ram Pages</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:OS:Ram_Pages"/>
				<updated>2020-03-04T19:07:42Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: update for MathPrint&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:OS_Information|Ram Pages]]&lt;br /&gt;
&lt;br /&gt;
This is to mark what ram pages may be used for short term or long term use.&lt;br /&gt;
&lt;br /&gt;
'''It should be noted that on the newer calculator models ([[83Plus:Ports:15|port 15]] &amp;gt;= 55h) pages 82-87 refer to the same physical memory'''&lt;br /&gt;
&lt;br /&gt;
'''80'''&lt;br /&gt;
* Default for TIOS at C000h&lt;br /&gt;
* Execution protected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''81'''&lt;br /&gt;
* Default for TIOS at 8000h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''82'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''83'''&lt;br /&gt;
* OS 2.x uses at least some of the range 4000h through 4080h to store app base pages prior to app execution. This is always regenerated and the OS doesn't seem to have any issue when you modify it.&lt;br /&gt;
* 4100h through 433Ah is used for various buffers during USB communication.&lt;br /&gt;
* On OSes with MathPrint, 577Eh through 5A7Dh is used to store the previous entries (command history). When this is modified, the calculator will crash if you scroll up on the homescreen past the program that modified it. Write 00 to 8E29 (numLastEntries) to prevent the user from scrolling up and avoiding the crash. This does not cause a memory leak and has no effect on older OSes (except with the OmniCalc entries menu). Zeroing this out doesn't seem to be neccesary. Beware that on 48 KiB models, any page in the 82-87 range maps to this page.&lt;br /&gt;
* On OSes with MathPrint, 5A7Eh through 5D7Dh is the homescreen graph buffer. Modifying this has caused flickering for some. You'll probably want to zero this if you use it.&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Temporary swap for Virtual Calc by Michael Vincent&lt;br /&gt;
** Temporary code execution for Real Sound by James Montelongo&lt;br /&gt;
** Temporary CALCnet buffers for direct USB for Doors CS 7.2 and higher by Christopher &amp;quot;Kerm Martian&amp;quot; Mitchell&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''84'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Virtual Calc by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''85'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Virtual Calc by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''86'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* Execution protected&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Restore Mem by Michael Vincent&lt;br /&gt;
&lt;br /&gt;
'''87'''&lt;br /&gt;
* Not used by TIOS under typical execution&lt;br /&gt;
* 3rd Party Uses&lt;br /&gt;
** Long term use for Restore Mem by Michael Vincent&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20</id>
		<title>83Plus:Ports:20</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20"/>
				<updated>2020-03-04T00:55:19Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: add TA1 information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|20 - CPU Speed Port]] [[Category:83Plus:Ports:By Name|CPU Speed Port]]&lt;br /&gt;
{{SE-Only Port|00}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 20h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' CPU Speed Port&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's CPU speed. The CPU can be set to run at either 6MHz or 15MHz with this port.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* 00h : The CPU is running at 6MHz.&lt;br /&gt;
* 01h: The CPU is running at 15MHz.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* 00h : Set the CPU speed to 6MHz.&lt;br /&gt;
* 01h: Set the CPU speed to 15MHz.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port is not available on the normal TI-83+. On the normal TI-83+ this port is a shadow of [[83Plus:Ports:00|Port 00h]].&lt;br /&gt;
&lt;br /&gt;
This port can contain values of 2 and 3, but the difference in speed is negligible. Michal_V has indicated that values 2 and 3 were intended for use with 20 MHz and 25 MHz speeds, but this functionality was left out before production began. Using the crystal timers I came to these approximate values.&lt;br /&gt;
{| width=&amp;quot;30%&amp;quot; border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;1&amp;quot; bgcolor=&amp;quot;white&amp;quot;&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | Port Contents&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | CPU Clock Speed&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 00&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~6.089 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 01&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.965 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 02&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.980 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 03&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.990 mhz&lt;br /&gt;
|}&lt;br /&gt;
I suggest still using 1 as the speed setting value since the speed of the other values may change in the future---unlikely as that may be---, which could seriously mess up your screen routines, or even cause opcode fetches to fail if required delay states are not configured. The slightly extra speed observed is due to capacitance of the unused pins. These modes are distinguished by LCD delaying hardware, ports 29-2C.&lt;br /&gt;
&lt;br /&gt;
Newer models (with new TA1 ASICs with fewer pins) don't show any difference between 01~03, suggesting that the extra pins for speeds 02 and 03 don't exist. Furthermore, the speed is closer to 16 MHz than it is to 15 MHz, even slightly above it on 4 out of 5 calculators I've tested.&lt;br /&gt;
&lt;br /&gt;
You can actually re-enable the extra values on production models if you find the right pins. On the TI-83+SE, there are helpful solder pads on the PCB; on the TI-84+/C/SE, you have to solder directly to the ASIC. You'll need to find a set of six pins, where one is a ground shared by a capacitor and two resistors, the next is connected to a capacitor, the next is connected to a resistor, the next two are not connected (solder to these pins), and the last is connected to another resistor. On the TA3 ASIC, they're pins 66-72, with 70 and 71 being the pins you want to tap (there are 144 pins, the side with #1 will be marked in some special way, and they're numbered counter-clockwise). On the TA1 ASIC, there are no known pins for this. Experiments on the TI-83+SE showed that the ASIC was unstable above about 22-23 MHz.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a, (2)&lt;br /&gt;
 and 80h&lt;br /&gt;
 jp z, NoCPUGoverner&lt;br /&gt;
 rlca ;Move the 1 bit in bit 7 to bit 0 (80h -&amp;gt; 01h)&lt;br /&gt;
 out (20h), a&lt;br /&gt;
NoCPUGoverner:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Michael Vincent documented another method to set the CPU speed (which is probably faster than my example).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;in a, (2)&lt;br /&gt;
 rla&lt;br /&gt;
 sbc a, a&lt;br /&gt;
 out (20h), a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only side effect of this is that on the TI-83+ Basic this will cause both linkport lines to go high - which shouldn't matter too much if you're not using the linkport at that time, especially since both lines are high normally...&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Michael Vincent:''' Documentation and his faster approach as found [http://michaelv.org/programs/calcs/ports/port20.html here].&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:11</id>
		<title>83Plus:Ports:11</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:11"/>
				<updated>2020-03-04T00:42:54Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|11 - LCD Data]][[Category:83Plus:Ports:By Name|LCD Data]]&lt;br /&gt;
[[Category:83:Ports:By Address|11 - LCD Data]][[Category:83:Ports:By Name|LCD Data]]&lt;br /&gt;
[[Category:82:Ports:By Address|11 - LCD Data]][[Category:82:Ports:By Name|LCD Data]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 11h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Data Port&lt;br /&gt;
&lt;br /&gt;
This port transfers data to and from the LCD driver's internal RAM.&lt;br /&gt;
&lt;br /&gt;
= TI 84 Plus C SE =&lt;br /&gt;
Information on the LCD driver for the TI-84 Plus C SE is on [[84PCSE:LCD_Controller|another page]].&lt;br /&gt;
&lt;br /&gt;
= TI-83 Plus, TI-83 Plus SE, TI-84 Plus, TI-84 Plus SE =&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* The byte at the current location in RAM. Each bit corresponds to one pixel.&lt;br /&gt;
&lt;br /&gt;
NOTE: When the LCD is first turned on (eg, after a removing ALL batteries from the calculator including the backup one) or after the location pointer is changed via the command port, the contents of the LCD's output register will be invalid. Since the output register is only updated on a data read, an extra dummy read is required before you will be able read what is at the new location. This is not required when the location pointer is updated by the auto-increment/decrement.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Sets the byte at the current RAM location. Each bit corresponds to one pixel.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
In 6-bit transfer mode, only bits 0~5 have any significance.&lt;br /&gt;
&lt;br /&gt;
The RAM location affected can be changed through the [[83Plus:Ports:10|command port]]. The location will also automatically change according to the auto-increment or auto-decrement mode as set in the command port. As with sending commands, you must wait a full LCD Cycle (10 microseconds) between reads and writes.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ;Cause all the pixels at the current location to be black.&lt;br /&gt;
 ld a, 0FFh&lt;br /&gt;
 out (11h), a&lt;br /&gt;
 push hl&lt;br /&gt;
 push de&lt;br /&gt;
 pop de&lt;br /&gt;
 pop hl&lt;br /&gt;
 nop&lt;br /&gt;
 ;And turn them back off.&lt;br /&gt;
 xor a&lt;br /&gt;
 out (11h), a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:10|Port 10]] - LCD command port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:13</id>
		<title>83Plus:Ports:13</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:13"/>
				<updated>2020-03-04T00:42:41Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|13 - LCD Data Mirror]][[Category:83Plus:Ports:By Name|LCD Data Mirror]]&lt;br /&gt;
[[Category:83:Ports:By Address|13 - LCD Data Mirror]][[Category:83:Ports:By Name|LCD Data Mirror]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 13h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Data port mirror&lt;br /&gt;
&lt;br /&gt;
This asserts a second chip select line from the ASIC. I suspect the CS line may not be present on later pin-reduced chips. The mirror is still present on the TA1 ASIC.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:11|Port 11]] - LCD data port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:12</id>
		<title>83Plus:Ports:12</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:12"/>
				<updated>2020-03-04T00:41:55Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|12 - LCD Command Mirror]][[Category:83Plus:Ports:By Name|LCD Command Mirror]]&lt;br /&gt;
[[Category:83:Ports:By Address|12 - LCD Command Mirror]][[Category:83:Ports:By Name|LCD Command Mirror]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 12h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command port mirror&lt;br /&gt;
&lt;br /&gt;
This asserts a second chip select line from the ASIC. I suspect the CS line may not be present on later pin-reduced chips. The mirror is still present on the TA1 ASIC.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:10|Port 10]] - LCD command port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:12</id>
		<title>83Plus:Ports:12</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:12"/>
				<updated>2020-03-04T00:41:17Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|12 - LCD Command Mirror]][[Category:83Plus:Ports:By Name|LCD Command Mirror]]&lt;br /&gt;
[[Category:83:Ports:By Address|12 - LCD Command Mirror]][[Category:83:Ports:By Name|LCD Command Mirror]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 12h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command port mirror&lt;br /&gt;
&lt;br /&gt;
This asserts a second chip select line from the ASIC. I suspect the CS line may not be present on later pin-reduced chips.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:10|Port 10]] - LCD command port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:01</id>
		<title>83Plus:Ports:01</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:01"/>
				<updated>2020-03-04T00:37:09Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By_Address|01 - Keyboard]] [[Category:83Plus:Ports:By_Name|Keyboard]] [[Category:83:Ports:By_Address|01 - Keyboard]] [[Category:83:Ports:By_Name|Keyboard]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 01h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Keyboard Port&lt;br /&gt;
&lt;br /&gt;
This port reads key presses from the keypad. The keypad is divided into a series of groups.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bits are set according whether corresponding keys from selected groups are pressed. Groups are selected through writing to the port. A pressed key reads a 0 bit. An unpressed key reads a 1 bit. The port reads FF after a reset (write FF).&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* $FF : Reset the keypad. This unselects all groups and resets the keypad state.&lt;br /&gt;
* Anything else : Any 0 bit adds the corresponding group to the list of monitored groups. When a key in a monitored group is pressed, the corresponding key bit reads 0, otherwise it reads 1 (active-low).&lt;br /&gt;
&lt;br /&gt;
== Key Map ==&lt;br /&gt;
The key map is laid out as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
! Group Bit&lt;br /&gt;
| 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Group Mask&lt;br /&gt;
| FE || FD || FB || F7 || EF || DF || BF || 7F&lt;br /&gt;
|-&lt;br /&gt;
! Key Bit !! (Mask)&lt;br /&gt;
|-&lt;br /&gt;
! 0 !! (FE)&lt;br /&gt;
| DOWN||ENTER|| (-) ||  .  ||  0  ||     ||GRAPH||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 1 !! (FD)&lt;br /&gt;
| LEFT||  +  ||  3  ||  2  ||  1  || STO ||TRACE||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 2 !! (FB)&lt;br /&gt;
|RIGHT||  -  ||  6  ||  5  ||  4  || LN  ||ZOOM ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 3 !! (F7)&lt;br /&gt;
| UP  ||  *  ||  9  ||  8  ||  7  || LOG ||WIND ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 4 !! (EF)&lt;br /&gt;
|     ||  /  ||  )  ||  (  ||  ,  || x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; || Y=  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 5 !! (DF)&lt;br /&gt;
|     ||  ^  || TAN || COS || SIN ||x&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; || 2nd ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 6 !! (BF)&lt;br /&gt;
|     ||CLEAR||VARS ||PRGM ||APPS ||MATH ||MODE ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! (7F)&lt;br /&gt;
|     ||     ||     ||STAT ||X,T,&amp;amp;#952;,''n''||ALPHA|| DEL ||     ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''Note:''' Group FB Key FE is NEGATE, not to be confused with SUBTRACT.&lt;br /&gt;
* '''Note:''' Group DF Key FE would be ON, but the ON key is tested through [[83Plus:Ports:04|Port 04]], bit 3.&lt;br /&gt;
* '''Note:''' Group EF Key BF (APPS) is called MATRIX on the TI-83.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
You should disable interrupts or use a custom interrupt before manually reading this port, because TI's interrupt scans the keypad. If you leave TI's interrupt active when manually reading the keypad, sometimes it will fire between when you set and read the port, and you'll read garbage.&lt;br /&gt;
&lt;br /&gt;
All nonexistent keys read 1.&lt;br /&gt;
&lt;br /&gt;
=== Delay ===&lt;br /&gt;
TI's code always resets the keypad before scanning; sometimes, you may get incorrect values if you scan without resetting first.&lt;br /&gt;
&lt;br /&gt;
Traditionally, a delay of a dozen or so clock cycles (6 MHz mode) is used between changing key groups and reading the result. The required delay seems to vary depending on the calculator; some require no delay, others a longer one. The delay is based on real time, not CPU clock cycles; you'll need to make your delay about 3 times longer in 15 MHz mode. However, as in the example, other people seem to find that resetting before every group change negates the need for a delay; some more experimentation is required.&lt;br /&gt;
&lt;br /&gt;
For me (Sorunome) this didn't seem to work: Using the following code didn't always have the correct keygroup selected when scanning (on a TI-84+SE of a friend of mine):  &lt;br /&gt;
&amp;lt;pre&amp;gt;ld a,$ff&lt;br /&gt;
out (1),a&lt;br /&gt;
ld a,%10111110&lt;br /&gt;
out (1),a&lt;br /&gt;
in a,(1)&amp;lt;/pre&amp;gt;&lt;br /&gt;
While the following fixed it:&lt;br /&gt;
&amp;lt;pre&amp;gt;ld a,$ff&lt;br /&gt;
out (1),a&lt;br /&gt;
ld a,%10111110&lt;br /&gt;
out (1),a&lt;br /&gt;
ex (sp),hl&lt;br /&gt;
ex (sp),hl&lt;br /&gt;
in a,(1)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason for this has since been discovered to not be caused by slow hardware, but rather by capacitance in the keypad. When unselecting a group, it takes a while before the charge has dissipated. Resetting the keypad every time after using it will make this discharge happen while you're doing something else, and activating a group happens instantly. The number of pressed keys and the number of groups being deactivated plays a role in the time the discharge takes, but generally, 7 clock cycles should be enough. However, this may vary from keypad to keypad.&lt;br /&gt;
&lt;br /&gt;
=== Ghosting ===&lt;br /&gt;
Because TI didn't add a diode to each key, you can also detect keys that aren't in a currently selected keygroup, as long as the other keygroup has at least one key in common with a selected keygroup. This means, for example, if F7 is selected, and the keys 2, 3, and 6 are pressed, Then keygroup FB will also be activated because F7 and FB have one key in common (namely FD). This makes it appear as though the 5 key is also pressed. This can also be used to make nonexistent keys appear active. However, as at least three keys have to be pressed for it to be noticeable, you don't have to worry in the most common use cases.&lt;br /&gt;
&lt;br /&gt;
=== Debouncing ===&lt;br /&gt;
While a key is in a state between pressed and released, it will repeatedly turn on and off. If you are reading the keypad extremely quickly, it will appear as though the key is being pressed and released a number of times. You need to either wait longer between keypad scans, or you need to implement a proper debouncing algorithm. TI-OS does the first one by scanning the keypad in an interrupt that runs slowly enough for it to not have a noticeable effect.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ld a, 0FFh ;Reset the keypad.&lt;br /&gt;
out (1), a&lt;br /&gt;
ld a, 0FEh ;Select group 0.&lt;br /&gt;
out (1), a&lt;br /&gt;
in a, (1) ;Test for keys.&lt;br /&gt;
and 2 ;Test for Left Arrow key by making A 0 if left was pressed.&lt;br /&gt;
call z, LeftArrowPressed ;If 0 then left was pressed.&lt;br /&gt;
ld a, 0FFh ;Reset the keypad.&lt;br /&gt;
out (1), a&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20</id>
		<title>83Plus:Ports:20</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:20"/>
				<updated>2020-03-04T00:14:38Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|20 - CPU Speed Port]] [[Category:83Plus:Ports:By Name|CPU Speed Port]]&lt;br /&gt;
{{SE-Only Port|00}}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 20h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' CPU Speed Port&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's CPU speed. The CPU can be set to run at either 6MHz or 15MHz with this port.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* 00h : The CPU is running at 6MHz.&lt;br /&gt;
* 01h: The CPU is running at 15MHz.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* 00h : Set the CPU speed to 6MHz.&lt;br /&gt;
* 01h: Set the CPU speed to 15MHz.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
This port is not available on the normal TI-83+. On the normal TI-83+ this port is a shadow of [[83Plus:Ports:00|Port 00h]].&lt;br /&gt;
&lt;br /&gt;
This port can contain values of 2 and 3, but the difference in speed is negligible. Michal_V has indicated that values 2 and 3 were intended for use with 20 MHz and 25 MHz speeds, but this functionality was left out before production began. Using the crystal timers I came to these approximate values.&lt;br /&gt;
{| width=&amp;quot;30%&amp;quot; border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;1&amp;quot; bgcolor=&amp;quot;white&amp;quot;&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | Port Contents&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | CPU Clock Speed&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 00&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~6.089 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 01&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.965 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 02&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.980 mhz&lt;br /&gt;
|-&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | 03&lt;br /&gt;
| width=&amp;quot;60%&amp;quot; | ~14.990 mhz&lt;br /&gt;
|}&lt;br /&gt;
I suggest still using 1 as the speed setting value since the speed of the other values may change in the future---unlikely as that may be---, which could seriously mess up your screen routines, or even cause opcode fetches to fail if required delay states are not configured. The slightly extra speed observed is due to capacitance of the unused pins. These modes are distinguished by LCD delaying hardware, ports 29-2C.&lt;br /&gt;
&lt;br /&gt;
Newer models (with new TA1 ASICs with fewer pins) don't show any difference between 01~03, suggesting that the extra pins for speeds 02 and 03 don't exist. Furthermore, the speed is closer to 16 MHz than it is to 15 MHz, even slightly above it on 4 out of 5 calculators I've tested.&lt;br /&gt;
&lt;br /&gt;
You can actually re-enable the extra values on production models if you find the right pins. On the TI-83+SE, there are helpful solder pads on the PCB; on the TI-84+/C/SE, you have to solder directly to the ASIC. You'll need to find a set of six pins, where one is a ground shared by a capacitor and two resistors, the next is connected to a capacitor, the next is connected to a resistor, the next two are not connected (solder to these pins), and the last is connected to another resistor. On the TA3 ASIC, they're pins 66-72, with 70 and 71 being the pins you want to tap (there are 144 pins, the side with #1 will be marked in some special way, and they're numbered counter-clockwise). Experiments on the TI-83+SE showed that the ASIC was unstable above about 22-23 MHz.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; in a, (2)&lt;br /&gt;
 and 80h&lt;br /&gt;
 jp z, NoCPUGoverner&lt;br /&gt;
 rlca ;Move the 1 bit in bit 7 to bit 0 (80h -&amp;gt; 01h)&lt;br /&gt;
 out (20h), a&lt;br /&gt;
NoCPUGoverner:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Michael Vincent documented another method to set the CPU speed (which is probably faster than my example).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;in a, (2)&lt;br /&gt;
 rla&lt;br /&gt;
 sbc a, a&lt;br /&gt;
 out (20h), a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only side effect of this is that on the TI-83+ Basic this will cause both linkport lines to go high - which shouldn't matter too much if you're not using the linkport at that time, especially since both lines are high normally...&lt;br /&gt;
&lt;br /&gt;
== Credits and Contributions ==&lt;br /&gt;
* '''Michael Vincent:''' Documentation and his faster approach as found [http://michaelv.org/programs/calcs/ports/port20.html here].&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10</id>
		<title>83Plus:Ports:10</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:10"/>
				<updated>2020-03-04T00:04:48Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: add comments on newer calculators and renew link to datasheet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|10 - LCD Command/Status Port]][[Category:83Plus:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:83:Ports:By Address|10 - LCD Command/Status Port]][[Category:83:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
[[Category:82:Ports:By Address|10 - LCD Command/Status Port]][[Category:82:Ports:By Name|LCD Command/Status Port]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 10h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Command and Status Port&lt;br /&gt;
&lt;br /&gt;
This port is used to check the status of and send commands to the calculator's LCD driver.&lt;br /&gt;
&lt;br /&gt;
= TI 84 Plus C SE =&lt;br /&gt;
Information on the LCD driver for the TI-84 Plus C SE is on [[84PCSE:LCD_Controller|another page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= TI-83 Plus, TI-83 Plus SE, TI-84 Plus, TI-84 Plus SE =&lt;br /&gt;
'''Note: Official documentation for the LCD controller uses &amp;quot;X&amp;quot; to refer to rows and &amp;quot;Y&amp;quot; to refer to columns.'''&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
The state of the LCD can be determined by reading this port.&lt;br /&gt;
* Bit 0: Set if auto-increment mode (commands 05 and 07) is selected, reset if auto-decrement mode (commands 04 and 06) is selected.&lt;br /&gt;
* Bit 1: Set if auto-increment or auto-decrement will affect the current column, or reset if auto-increment/decrement will affect the current row.&lt;br /&gt;
* Bit 2, 3: Not used.&lt;br /&gt;
* Bit 4: Set if in reset state, reset if in operating state. (Whatever that means.)&lt;br /&gt;
* Bit 5: Set if the display is enabled. Reset if disabled. (Note: LCD is completely turned off via [[83Plus:Ports:03|Port 03h]].)&lt;br /&gt;
* Bit 6: Set if the LCD will transfer 8 bits at a time through [[83Plus:Ports:11|Port 11]]. Reset if the LCD will only trasfer 6 bits at a time.&lt;br /&gt;
* Bit 7: Set if the LCD is busy. Reset if a command can be accepted.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
Writing this port sends a command to the LCD. Once you send a command, wait until bit 7 reads 0 before sending another. You need a minimum delay of 10 microseconds (60 cycles of whatever else on the 6MHz TI-83+, or ~150 on a TI-83+ Silver or any TI-84+ when running in [[83Plus:Ports:20|fast mode]]).&lt;br /&gt;
&lt;br /&gt;
* 00 : Switch to '''6-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 6-bits at a time.)&lt;br /&gt;
* 01 : Switch to '''8-bit mode'''. ([[83Plus:Ports:11|Port 11]] transfers 8-bits at a time.)&lt;br /&gt;
* 02 : Disable the screen. This blanks the screen and disconnects the LCD RAM from the physical screen, thus allowing you to use the LCD RAM as extra saferam. (But accessing it is so horribly slow that you should only do this if the usual saferam areas aren't enough and you don't need to display anything.)&lt;br /&gt;
* 03 : Enable the screen. This resumes displaying the LCD's RAM contents to the physical screen. (So any garbage you put into LCD RAM while it was off will show up, so B_CALL ClrLCDFull before this!)&lt;br /&gt;
* 04 : Set X auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''up''' one row.&lt;br /&gt;
* 05 : Set X auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''down''' one row. The TI-83+ expects the LCD to be in this mode for most display routines.&lt;br /&gt;
* 06 : Set Y auto-decrement mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''left''' one column.&lt;br /&gt;
* 07 : Set Y auto-increment mode. Every read or write operation from the data port will cause the LCD's internal pointer to move '''right''' one column.&lt;br /&gt;
* [08~0B]: Set power supply enhancement. You'd be well advised to just leave this alone.&lt;br /&gt;
* [0C~0F]: Applies screen mirroring on newer calculators. Bit 0 set enables horizontal mirroring, bit 1 set enables vertical mirroring.&lt;br /&gt;
* [10~13]: Set power supply level. You'd be well advised to just leave this alone.&lt;br /&gt;
* [14~17]: Undefined.&lt;br /&gt;
* [18]: Cancel test mode (see Comments).&lt;br /&gt;
* [19~1B]: Undefined.&lt;br /&gt;
* [1C~1F]: Enter test mode (see Comments).&lt;br /&gt;
* [20~3F]: '''Set column'''.  [20~2E] are valid columns in 8-bit mode, [20~33] are valid columns in 6-bit mode. [34~3F] values are also accepted, but do not correspond to a drawable area.&lt;br /&gt;
* [40~7F]: &amp;quot;Z addressing&amp;quot; (It just changed what phyiscal row the top row of RAM is displayed on. The LCD will wrap the bottom of it's RAM to the top of the screen as needed.)&lt;br /&gt;
* [80~BF]: '''Set row'''.&lt;br /&gt;
* [C0~FF]: '''Set contrast'''. (C0 is lowest. Note that there is a [[83Plus:RAM:8447|System RAM area (contrast)]] for this which will need to be updated if you want 2nd+Up/2nd+Down to change the contrast as expected (instead of causing a sudden jump...).)&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
===Necessary LCD communication delay===&lt;br /&gt;
As mentioned, a 10 microsecond delay is required after sending the command. TI provides a routine at 000B (use normal CALL, not BCALL) that will delay the required amount of time. (Because this was not originally an LCD delay routine, on OS's prior to 1.13, calling it destroys the zero flag.)&lt;br /&gt;
&lt;br /&gt;
On older calculators, this code sequence should also provide sufficient delay while also preserving the zero flag:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ex (sp),hl ;19&lt;br /&gt;
 ex (sp),hl ;38&lt;br /&gt;
 inc (hl)   ;49&lt;br /&gt;
 dec (hl)   ;60&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But I would advise you actually make use of these waste cycles somehow (process a buffer or something).&lt;br /&gt;
&lt;br /&gt;
On some newer calculators, a fixed delay can still be used in combination with slowing the CPU through port [[83Plus:Ports:20|20]] and/or adjusting ports [[83Plus:Ports:29|29]] and [[83Plus:Ports:2A|2A]].  However, a large number of calculators have been produced recently whose LCD drivers, for whatever reason, do not respond as quickly.  For this reason, except where the speed loss is absolutely unacceptable (such as for grayscale display) fixed delays should '''not''' be used.  Instead either use the routine at 000B, or poll this port or [[83Plus:Ports:02|port 2]] manually.&lt;br /&gt;
&lt;br /&gt;
===Unused screen area===&lt;br /&gt;
The LCD driver's video memory holds a display 120 pixels wide, even though the screen is only 96 pixels wide.  The 24 pixel wide offscreen area can still be read from and written to, and is not affected by soft power-off.&lt;br /&gt;
&lt;br /&gt;
===Test mode===&lt;br /&gt;
This is a very dangerous mode. The first test mode command (1C~1F) causes the screen to receive an unusually high amount of energy. The result is that the screen seems to go blank, save for a single blue(!) line on the TI 83, but on the TI 84's, the entire screen turns blue! Each subsequent command adds more blue lines. After you've had your fill of blueness, exit test mode by sending a exit test mode command (18), which also sets the contrast to it's highest. Now why is it dangerous? Sure it looks cool to make a supposedly black and white LCD to display BLUE, but you are pumping so much energy through the LCD to get this effect that leaving it in this mode for too long can cause long-term damage. Ever left your monitor on for a day or two and forget to set a screen saver? Remember how when you turned it off a burnt image of your screen remained? Well that's what can happen if you leave test mode on for too long. Other possible side effects include &amp;quot;dead pixels&amp;quot; (pixels that stay off no matter what you do).&lt;br /&gt;
&lt;br /&gt;
So don't use test mode okay? Just pretend you didn't hear about it...&lt;br /&gt;
&lt;br /&gt;
On newer calculators, the test mode commands seem to be ignored, so this is yet another reason to not rely on this function.&lt;br /&gt;
&lt;br /&gt;
===Power settings===&lt;br /&gt;
On my (fghsgh's) calculator, the power supply command extends to 17. The boot code even initializes this setting to 17. Settings 10~13 all make the screen slowly fade to black, then fade to white, and then it stays blank. Writing any command in the range 14~17 makes the display come back to life. The power supply enhancement doesn't seem to do anything, but the (1.03) boot code initializes it to 0B.&lt;br /&gt;
&lt;br /&gt;
== Cursor movement and out-of-bounds behavior ==&lt;br /&gt;
It is possible to set the column number out of range, either by directly writing a column number out of bounds, or by switching to 6-bit mode, moving the column to a position outside of 8-bit mode's range, then switching back to 8-bit mode.&lt;br /&gt;
&lt;br /&gt;
If the column is out of range, no write is made to the display, but the column will continue to increment or decrement.&lt;br /&gt;
&lt;br /&gt;
===8-bit mode===&lt;br /&gt;
In 8-bit mode, the column will wrap from 14 to 0 when moving right, and wrap from 0 to 14 when moving left.  If the column&amp;gt;14, then there is no wrapping, the column will continue to increment or decrement within the full range of 0-31.  Exceeding column 31 returns to column 0.&lt;br /&gt;
&lt;br /&gt;
===6-bit-mode===&lt;br /&gt;
Same as 8-bit mode, but column wraps from 19 to 0 when moving right, and 0 to 19 when moving left.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Turn the LCD &amp;quot;off&amp;quot; and back &amp;quot;on&amp;quot;.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,02h&lt;br /&gt;
 out (10h),a&lt;br /&gt;
 ex (sp),hl ;Or do something else that takes ~60 cycles.&lt;br /&gt;
 ex (sp),hl&lt;br /&gt;
 inc (hl)&lt;br /&gt;
 dec (hl)&lt;br /&gt;
 inc a&lt;br /&gt;
 out (10h),a&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Safely wait for the LCD to become available&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lcd_busy_loop:&lt;br /&gt;
 in a,($10) ;bit 7 set if LCD is busy&lt;br /&gt;
 rla&lt;br /&gt;
 jr c,lcd_busy_loop&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[83Plus:Ports:11|Port 11]] - LCD Data Port&lt;br /&gt;
* [https://archive.org/details/t6a04a-datasheet LCD driver datasheet]&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=User:Fghsgh</id>
		<title>User:Fghsgh</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=User:Fghsgh"/>
				<updated>2020-03-03T23:29:19Z</updated>
		
		<summary type="html">&lt;p&gt;Fghsgh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am a 17-year-old Z80 programmer who owns one 84+ because it was mandatory at my (Belgian) school. I started learning Z80 half a year before I even got the calculator thanks to the TI Flash Debugger and the &amp;quot;Learn TI-83 Plus Assembly In 28 Days&amp;quot; tutorial by Sean McLaughlin. I am currently active on Cemetech and you can often find me on its IRC channel.&lt;br /&gt;
&lt;br /&gt;
I have noticed a lot of out-of-date information on this website (mainly because of new hardware revisions, probably) and asked DrDnar to change them when he revealed that he could edit this. He then told me to create my own account so here I am. I will try to update this wiki using new data I get from my own calculator.&lt;/div&gt;</summary>
		<author><name>Fghsgh</name></author>	</entry>

	</feed>