<?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=Zeroko</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=Zeroko"/>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Special:Contributions/Zeroko"/>
		<updated>2026-05-09T14:12:10Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.5</generator>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000C</id>
		<title>84PCE:Ports:000C</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000C"/>
				<updated>2022-05-21T01:14:33Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Typo in port number&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|000C - GPIO B OUT]] [[Category:84PCE:Ports:By_Name|GPIO B OUT]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 000C&lt;br /&gt;
&lt;br /&gt;
'''Function:''' GPIO B Output&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
These GPIOs appear to be connected to battery info.&lt;br /&gt;
&lt;br /&gt;
=== Bits [0] ===&lt;br /&gt;
Set while USB is connected to disable the charging circuit. Reset to re-enable charging.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:1] ===&lt;br /&gt;
TBD&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000C</id>
		<title>84PCE:Ports:000C</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000C"/>
				<updated>2022-05-21T01:13:45Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Charging circuit control&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|000C - GPIO B OUT]] [[Category:84PCE:Ports:By_Name|GPIO B OUT]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 000B&lt;br /&gt;
&lt;br /&gt;
'''Function:''' GPIO B Output&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
These GPIOs appear to be connected to battery info.&lt;br /&gt;
&lt;br /&gt;
=== Bits [0] ===&lt;br /&gt;
Set while USB is connected to disable the charging circuit. Reset to re-enable charging.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:1] ===&lt;br /&gt;
TBD&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:1000</id>
		<title>84PCE:Ports:1000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:1000"/>
				<updated>2022-01-22T04:38:54Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added need for flash unlock on M+&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|1000 - Flash Controller]] [[Category:84PCE:Ports:By_Name|Flash Controller]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 1000-1FFF&lt;br /&gt;
&lt;br /&gt;
'''Memory-mapped Address:''' E00000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Flash Controller&lt;br /&gt;
&lt;br /&gt;
== Parallel Controller ==&lt;br /&gt;
&lt;br /&gt;
For more information see the [[83Plus:OS:Raw_Flash_Commands|parallel commands]].&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|01&lt;br /&gt;
|01&lt;br /&gt;
|Reset bit 0 to crash. Seems to reduce minimum flash wait states to 2.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1001|1001]]&lt;br /&gt;
|00&lt;br /&gt;
|??&lt;br /&gt;
|Freeze if write value greater than 3F&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1002|1002]]&lt;br /&gt;
|06&lt;br /&gt;
|0F&lt;br /&gt;
|Mapped flash chip address space size.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1003|1003]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1003|1004]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1005|1005]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Added flash wait states over 5.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1006|1006]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1007|1007]]&lt;br /&gt;
|FF&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1008|1008]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1009|1009]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 1009-100F latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Serial Controller ==&lt;br /&gt;
&lt;br /&gt;
Only used in HW revisions M and later (NB: all python edition calcs are M+). Flash must be unlocked in order to write to these ports, or the write will be ignored.&lt;br /&gt;
&lt;br /&gt;
For more information see the [[84PCE:OS:Serial_Flash_Commands|serial commands]].&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|1005&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Probably ignored for compatibility with the parallel interface.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1010|1010]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:1011|1011]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 1011-1017 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|1800&lt;br /&gt;
|00000000&lt;br /&gt;
|FFFFFFFF&lt;br /&gt;
|Extra data to send after command byte (usually used for a flash address).&lt;br /&gt;
|-&lt;br /&gt;
|1804&lt;br /&gt;
|00&lt;br /&gt;
|07&lt;br /&gt;
|How many bytes from ports $1800-$1803 to send after the command byte.&lt;br /&gt;
|-&lt;br /&gt;
|1805&lt;br /&gt;
|00&lt;br /&gt;
|00&lt;br /&gt;
|Unknown, something to do with the current flash command, always seems to be $00.&lt;br /&gt;
|-&lt;br /&gt;
|1806&lt;br /&gt;
|00&lt;br /&gt;
|07&lt;br /&gt;
|Number of dummy bytes after command byte.&lt;br /&gt;
|-&lt;br /&gt;
|1807&lt;br /&gt;
|00&lt;br /&gt;
|11&lt;br /&gt;
|Unknown, something to do with the current flash command. Bit 0 is always set and bit 4 is rarely set.&lt;br /&gt;
|-&lt;br /&gt;
|1808&lt;br /&gt;
|00000000&lt;br /&gt;
|FFFFFFFF&lt;br /&gt;
|Number of bytes to transfer through port $1900 with the current flash command.&lt;br /&gt;
|-&lt;br /&gt;
|180C&lt;br /&gt;
|00&lt;br /&gt;
|C6&lt;br /&gt;
|Bit 1 might be direction (0 = in, 1 = out). Other bits unknown.&lt;br /&gt;
|-&lt;br /&gt;
|180D&lt;br /&gt;
|0000&lt;br /&gt;
|B000&lt;br /&gt;
|Unknown, something to do with the current flash command, usually $0000, rarely $B000.&lt;br /&gt;
|-&lt;br /&gt;
|180F&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Current command byte.&lt;br /&gt;
|-&lt;br /&gt;
|1818&lt;br /&gt;
|00&lt;br /&gt;
|03&lt;br /&gt;
|Bit 0/1 is set when bytes can be written/read through port $1900.&lt;br /&gt;
|-&lt;br /&gt;
|1824&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Bit 0 set when the command finishes and the busy bit is cleared, write 1 to clear.&lt;br /&gt;
|-&lt;br /&gt;
|182C-182F&lt;br /&gt;
|FFC00000&lt;br /&gt;
|FFFFFFFF&lt;br /&gt;
|Address mask for memory-mapped access to flash.&lt;br /&gt;
|-&lt;br /&gt;
|1830&lt;br /&gt;
|00000000&lt;br /&gt;
|FFFFFFFF&lt;br /&gt;
|Unknown.&lt;br /&gt;
|-&lt;br /&gt;
|1900&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Read or write command data.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:General_Hardware_Information</id>
		<title>Category:84PCE:General Hardware Information</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:General_Hardware_Information"/>
				<updated>2021-12-09T19:35:00Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Changed reset length threshold&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TI-84 Plus CE and TI-83 Premium are two models new in 2015. The former is for the USA region (maybe all of North American?) and the latter is for France. The hardware is virtually identical between the two models. In 2019, a new revision beginning with revision M was introduced, using a cached serial flash chip and optionally featuring an [[84PCE:Ports:E000|ARM coprocessor]] for running Python programs.&lt;br /&gt;
&lt;br /&gt;
Known hardware facts:&lt;br /&gt;
* eZ80 CPU&lt;br /&gt;
** Physical clock speed believed to be 48 MHz&lt;br /&gt;
** CPU performance is severely constrained by wait states for accessing RAM and flash&lt;br /&gt;
** On devices manufactured before revision M, the effective clock is speed between 8-16 MHz depending on ratio of RAM to flash accesses&lt;br /&gt;
** On later devices, the effective clock speed may be closer to 20 MHz, depending on RAM-to-flash access ratio as well as cache utilization&lt;br /&gt;
* 4 MB flash chip&lt;br /&gt;
** Bottom-boot organization this time&lt;br /&gt;
* 256 K main RAM&lt;br /&gt;
* Memory-mapped LCD&lt;br /&gt;
** 153600 bytes of &amp;quot;VRAM&amp;quot; (actually just RAM) confirmed&lt;br /&gt;
** Possibly an ARM Primecell PL111[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0293c/index.html &amp;lt;nowiki&amp;gt;[HTML]&amp;lt;/nowiki&amp;gt;][http://infocenter.arm.com/help/topic/com.arm.doc.ddi0293c/DDI0293.pdf &amp;lt;nowiki&amp;gt;[PDF]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
* French version (TI-83 Premium CE), and other european versions (TI-84 Plus CE-T), have an LED on top for exams&lt;br /&gt;
* User programs are prohibited from using any IN/OUT instructions&lt;br /&gt;
** OUT causes a reset&lt;br /&gt;
** IN produces a constant value&lt;br /&gt;
* There is memory-mapped I/O, starting at E00000. Most port ranges have a mapped address, and RAM programs are allowed to use the memory-mapped I/O.&lt;br /&gt;
** The 00xx range of ports is not mapped. This range includes permissions control, flash control, the testing LED, NMI control, and possibly master power management.&lt;br /&gt;
* Flash starts at $000000&lt;br /&gt;
** There is also still a flash unlock sequence&lt;br /&gt;
* RAM starts at $D00000&lt;br /&gt;
* Assembly programs and TI-BASIC programs are limited to one sector (64KB)&lt;br /&gt;
* VRAM starts at $D40000&lt;br /&gt;
** VRAM is executable&lt;br /&gt;
* USB IP is the Faraday FOTG210&lt;br /&gt;
* The reset button on the back resets the CPU, but may not always reset RAM&lt;br /&gt;
** Briefly pressing reset (for shorter than about 1.5 seconds) results in the calculator turning on if it was off. On revisions before M, the boot code always clears RAM, while on revision M or later, the boot code does not clear RAM, but the OS might under some circumstances. This is the same behavior as RST 00.&lt;br /&gt;
** Holding reset for longer than about 1.5 seconds results in the calculator turning off if it was on; regardless of revision, RAM is cleared.&lt;br /&gt;
** If charging via USB, a long press behaves exactly like a short press.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:General_Hardware_Information</id>
		<title>Category:84PCE:General Hardware Information</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:General_Hardware_Information"/>
				<updated>2021-12-09T07:35:59Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Reset button behavior&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TI-84 Plus CE and TI-83 Premium are two models new in 2015. The former is for the USA region (maybe all of North American?) and the latter is for France. The hardware is virtually identical between the two models. In 2019, a new revision beginning with revision M was introduced, using a cached serial flash chip and optionally featuring an [[84PCE:Ports:E000|ARM coprocessor]] for running Python programs.&lt;br /&gt;
&lt;br /&gt;
Known hardware facts:&lt;br /&gt;
* eZ80 CPU&lt;br /&gt;
** Physical clock speed believed to be 48 MHz&lt;br /&gt;
** CPU performance is severely constrained by wait states for accessing RAM and flash&lt;br /&gt;
** On devices manufactured before revision M, the effective clock is speed between 8-16 MHz depending on ratio of RAM to flash accesses&lt;br /&gt;
** On later devices, the effective clock speed may be closer to 20 MHz, depending on RAM-to-flash access ratio as well as cache utilization&lt;br /&gt;
* 4 MB flash chip&lt;br /&gt;
** Bottom-boot organization this time&lt;br /&gt;
* 256 K main RAM&lt;br /&gt;
* Memory-mapped LCD&lt;br /&gt;
** 153600 bytes of &amp;quot;VRAM&amp;quot; (actually just RAM) confirmed&lt;br /&gt;
** Possibly an ARM Primecell PL111[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0293c/index.html &amp;lt;nowiki&amp;gt;[HTML]&amp;lt;/nowiki&amp;gt;][http://infocenter.arm.com/help/topic/com.arm.doc.ddi0293c/DDI0293.pdf &amp;lt;nowiki&amp;gt;[PDF]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
* French version (TI-83 Premium CE), and other european versions (TI-84 Plus CE-T), have an LED on top for exams&lt;br /&gt;
* User programs are prohibited from using any IN/OUT instructions&lt;br /&gt;
** OUT causes a reset&lt;br /&gt;
** IN produces a constant value&lt;br /&gt;
* There is memory-mapped I/O, starting at E00000. Most port ranges have a mapped address, and RAM programs are allowed to use the memory-mapped I/O.&lt;br /&gt;
** The 00xx range of ports is not mapped. This range includes permissions control, flash control, the testing LED, NMI control, and possibly master power management.&lt;br /&gt;
* Flash starts at $000000&lt;br /&gt;
** There is also still a flash unlock sequence&lt;br /&gt;
* RAM starts at $D00000&lt;br /&gt;
* Assembly programs and TI-BASIC programs are limited to one sector (64KB)&lt;br /&gt;
* VRAM starts at $D40000&lt;br /&gt;
** VRAM is executable&lt;br /&gt;
* USB IP is the Faraday FOTG210&lt;br /&gt;
* The reset button on the back resets the CPU, but may not always reset RAM&lt;br /&gt;
** Briefly pressing reset results in the calculator turning on if it was off. On revisions before M, the boot code always clears RAM, while on revision M or later, the boot code does not clear RAM, but the OS might under some circumstances. This is the same behavior as RST 00.&lt;br /&gt;
** Holding reset for longer (5 seconds works) results in the calculator turning off if it was on; regardless of revision, RAM is cleared.&lt;br /&gt;
** If charging via USB, a long press behaves exactly like a short press.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:LCD_Controller</id>
		<title>86:LCD Controller</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:LCD_Controller"/>
				<updated>2021-09-22T12:59:03Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added link to ASIC &amp;amp; replaced port 4 with 04 to match usage elsewhere.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|LCD Controller]]&lt;br /&gt;
The TI-86 has a memory-mapped STN liquid crystal display. The main portion of LCD controller is inside the [[86:ASIC|ASIC]], with row &amp;amp; column drivers &amp;amp; circuitry to produce the necessary voltages located on a daughterboard on which the LCD itself is also mounted.&lt;br /&gt;
&lt;br /&gt;
== DMA ==&lt;br /&gt;
When the LCD is enabled, the ASIC needs to send pixels to it continuously. In order to allow the CPU to operate at the same time, the ASIC contains an internal buffer used to hold the pixels for the current row. This buffer is filled via DMA (direct memory access) that pauses the CPU once per row. This pause appears to be implemented internally by way of the Z80 signals /BUSREQ &amp;amp; /BUSACK, &amp;amp; as such, it is even able to occur in between the M cycles of a single instruction. No DMA is performed when the LCD is disabled.&lt;br /&gt;
&lt;br /&gt;
The LCD always uses all 64 rows per physical frame. If the number of rows per logical frame is set lower than 64 via bits 1-2 of [[86:Ports:04|Port 04]], the subsequent logical frames are stacked vertically until the whole 64 rows are filled, with the last one being cut short if the rows per frame is set to 48. This stacking also makes the image darker, presumably because it increases the effective duty cycle.&lt;br /&gt;
&lt;br /&gt;
The LCD controller always sends 160 pixels per row to the daughterboard, of which the first 80 &amp;amp; last 48 are visible on screen, for a total of 128 visible columns. However, DMA only reads as many bytes as necessary to contain the number of columns chosen via bits 3-4 of [[86:Ports:04|Port 04]]. Of the columns read via DMA, the first 80 are placed at the beginning of the buffer, &amp;amp; the remainder are placed at the end of the buffer. If this is fewer than the full 160 columns, the 4 columns immediately after the first 80 are copied from the last 4 of the previous row's DMA transfer. The remaining columns are copied starting from the beginning of the current row's DMA transfer.&lt;br /&gt;
&lt;br /&gt;
== Interrupts ==&lt;br /&gt;
LCD interrupts occur twice per logical frame. They occur one row after one quarter &amp;amp; three quarters of the way down the frame, which is rows 17 &amp;amp; 49 (counting from 0) when set to 64 rows per frame. DMA occurs after the interrupt acknowledgement, which in particular is after the CPU reads the byte used to determine which offset to use for IM 2. The start of the interrupt service routine itself is then delayed until DMA finishes.&lt;br /&gt;
&lt;br /&gt;
Warning: Toggling individual pixels every other interrupt may damage the LCD by causing a net charge to accumulate. Any given pixel's value should only be changed (at most) once every fourth interrupt. This is because the pixels of STN LCDs must be driven using AC waveforms to prevent damage due to charge buildup, &amp;amp; the calculator achieves this by alternating between 2 sets of voltages on consecutive frames.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:ASIC</id>
		<title>86:ASIC</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:ASIC"/>
				<updated>2021-09-22T12:56:24Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;The ASIC used in all known revisions of the TI-86 is an 80-pin QFP with part number T6A43. It contains a Z80-compatible CPU core &amp;amp; additional logic that implements the :Cate...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The ASIC used in all known revisions of the TI-86 is an 80-pin QFP with part number T6A43. It contains a Z80-compatible CPU core &amp;amp; additional logic that implements the [[:Category:86:Ports:By_Address|I/O ports]], as well as the [[86:LCD_Controller|LCD Controller]]. It is also used in some TI-81 revisions, the TI-85, &amp;amp; the PS-6600 Organizer.&lt;br /&gt;
&lt;br /&gt;
== CPU ==&lt;br /&gt;
The CPU is a CMOS Z80 clocked around 5-6 MHz depending on the battery level. An extra wait state is automatically inserted during every M1 cycle, so instruction timings need to be adjusted accordingly for timing-critical code. The LCD controller pauses the CPU during DMA using internal /BUSREQ &amp;amp; /BUSACK signals (or some behaviorally-equivalent mechanism), which will not interrupt an M cycle but can occur between M cycles of a single instruction. As a result, behavior that depends on bus content (such as reading from [[86:Memory_Mapping#Unused_Banks|Unused Banks]]) can be altered by DMA happening in the middle of an instruction. DMA also affects timing-critical code, &amp;amp; can only be disabled by turning the LCD off entirely (via bit 3 of [[86:Ports:03|Port 03]]).&lt;br /&gt;
&lt;br /&gt;
== Pinout ==&lt;br /&gt;
The pins are numbered counterclockwise around the ASIC package when viewed from above. Pins 1, 25, 41, &amp;amp; 65 are labeled on the PCB, although the label for 25 is offset from the actual pin due to other components being in the way. These labels are taken from [https://www.ticalc.org/archives/files/fileinfo/32/3240.html this schematic for the TI-85], since it uses the same ASIC, except where those labels are incorrect. Pins with labels prefixed by a slash (/) are active low. The additional signal names for V1-V15 are taken from the datasheets for the T6A23 column driver &amp;amp; T6A40 row driver on the LCD daughterboard.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Right side from bottom to top&lt;br /&gt;
|-&lt;br /&gt;
| 1. || A2 || A0-A19 are the address bus.&lt;br /&gt;
|-&lt;br /&gt;
| 2. || A1&lt;br /&gt;
|-&lt;br /&gt;
| 3. || A0&lt;br /&gt;
|-&lt;br /&gt;
| 4. || D7 || D0-D7 are the data bus.&lt;br /&gt;
|-&lt;br /&gt;
| 5. || D6&lt;br /&gt;
|-&lt;br /&gt;
| 6. || D5&lt;br /&gt;
|-&lt;br /&gt;
| 7. || D4&lt;br /&gt;
|-&lt;br /&gt;
| 8. || D3&lt;br /&gt;
|-&lt;br /&gt;
| 9. || D2&lt;br /&gt;
|-&lt;br /&gt;
| 10. || D1&lt;br /&gt;
|-&lt;br /&gt;
| 11. || D0&lt;br /&gt;
|-&lt;br /&gt;
| 12. || LCDOSCGND || LCD oscillator ground. (Usage of pins 12-14 for the LCD controller clock needs verification.)&lt;br /&gt;
|-&lt;br /&gt;
| 13. || LCDOSC1&lt;br /&gt;
|-&lt;br /&gt;
| 14. || LCDOSC2&lt;br /&gt;
|-&lt;br /&gt;
| 15. || /ON&lt;br /&gt;
|-&lt;br /&gt;
| 16. || KR0 || KR0-KR7 are keypad rows 0-7, corresponding to the bits of [[86:Ports:01|Port 01]] when written.&lt;br /&gt;
|-&lt;br /&gt;
| 17. || KR1&lt;br /&gt;
|-&lt;br /&gt;
| 18. || KR2&lt;br /&gt;
|-&lt;br /&gt;
| 19. || KR3&lt;br /&gt;
|-&lt;br /&gt;
| 20. || KR4&lt;br /&gt;
|-&lt;br /&gt;
| 21. || KR5&lt;br /&gt;
|-&lt;br /&gt;
| 22. || KR6&lt;br /&gt;
|-&lt;br /&gt;
| 23. || KR7&lt;br /&gt;
|-&lt;br /&gt;
| 24. || KC0 || KC0-KC7 are keypad columns 0-7, corresponding to the bits of Port 01 when read.&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Top side from right to left&lt;br /&gt;
|-&lt;br /&gt;
| 25. || KC1&lt;br /&gt;
|-&lt;br /&gt;
| 26. || KC2&lt;br /&gt;
|-&lt;br /&gt;
| 27. || KC3&lt;br /&gt;
|-&lt;br /&gt;
| 28. || KC4&lt;br /&gt;
|-&lt;br /&gt;
| 29. || KC5&lt;br /&gt;
|-&lt;br /&gt;
| 30. || KC6&lt;br /&gt;
|-&lt;br /&gt;
| 31. || KC7&lt;br /&gt;
|-&lt;br /&gt;
| 32. || VCC&lt;br /&gt;
|-&lt;br /&gt;
| 33. || V15 || Bit 0 of [[86:Ports:02|Port 02]] (contrast); V1-V15 are connected to the LCD daughterboard.&lt;br /&gt;
|-&lt;br /&gt;
| 34. || V14 || Bit 1 of Port 02&lt;br /&gt;
|-&lt;br /&gt;
| 35. || V13 || Bit 2 of Port 02&lt;br /&gt;
|-&lt;br /&gt;
| 36. || V12 || Bit 3 of Port 02&lt;br /&gt;
|-&lt;br /&gt;
| 37. || V11 || Bit 4 of Port 02&lt;br /&gt;
|-&lt;br /&gt;
| 38. || V10 || (Unknown; apparently contrast-related)&lt;br /&gt;
|-&lt;br /&gt;
| 39. || V9 || (Unknown; apparently contrast-related)&lt;br /&gt;
|-&lt;br /&gt;
| 40. || V8 || FR (frame): alternates on consecutive frames to ensure LCD drive voltages alternate.&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Left side from top to bottom&lt;br /&gt;
|-&lt;br /&gt;
| 41. || V7 || FP (frame pulse) &amp;amp; DIO1: starts a frame.&lt;br /&gt;
|-&lt;br /&gt;
| 42. || V6 || LP (latch pulse) &amp;amp; EIO1: starts a row.&lt;br /&gt;
|-&lt;br /&gt;
| 43. || V5 || SCP (shift clock pulse): pixel clock.&lt;br /&gt;
|-&lt;br /&gt;
| 44. || V4 || DI4; DI1-DI4 are pixel data.&lt;br /&gt;
|-&lt;br /&gt;
| 45. || V3 || DI3&lt;br /&gt;
|-&lt;br /&gt;
| 46. || V2 || DI2&lt;br /&gt;
|-&lt;br /&gt;
| 47. || V1 || DI1&lt;br /&gt;
|-&lt;br /&gt;
| 48. || IORQ || External I/O enable; used for [[86:Ports:20|Ports 20-3F]] (active high, unlike the Z80 signal). Apparently also used by prototype TI-86es with flash ROM as the flash chip's output enable signal (needs clarification).&lt;br /&gt;
|-&lt;br /&gt;
| 49. || CPUOSCGND || CPU oscillator ground.&lt;br /&gt;
|-&lt;br /&gt;
| 50. || CPUOSC1&lt;br /&gt;
|-&lt;br /&gt;
| 51. || CPUOSC2&lt;br /&gt;
|-&lt;br /&gt;
| 52. || GND&lt;br /&gt;
|-&lt;br /&gt;
| 53. || /INT || External interrupt request (needs verification); see bit 2 of [[86:Ports:03|Port 03]].&lt;br /&gt;
|-&lt;br /&gt;
| 54. || LP0 || LP0-LP3 are the corresponding bits of [[86:Ports:07|Port 07]]&lt;br /&gt;
|-&lt;br /&gt;
| 55. || LP1&lt;br /&gt;
|-&lt;br /&gt;
| 56. || LP2&lt;br /&gt;
|-&lt;br /&gt;
| 57. || LP3&lt;br /&gt;
|-&lt;br /&gt;
| 58. || /CE0 || /CE0-/CE3 are chip enables for memory banks (see [[86:Memory_Mapping|Memory Mapping]])&lt;br /&gt;
|-&lt;br /&gt;
| 59. || /CE1&lt;br /&gt;
|-&lt;br /&gt;
| 60. || /CE2&lt;br /&gt;
|-&lt;br /&gt;
| 61. || /CE3&lt;br /&gt;
|-&lt;br /&gt;
| 62. || /WE || Write enable. Note that there is no output enable.&lt;br /&gt;
|-&lt;br /&gt;
| 63. || A19&lt;br /&gt;
|-&lt;br /&gt;
| 64. || A18&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Bottom from left to right&lt;br /&gt;
|-&lt;br /&gt;
| 65. || A17&lt;br /&gt;
|-&lt;br /&gt;
| 66. || A16&lt;br /&gt;
|-&lt;br /&gt;
| 67. || A15&lt;br /&gt;
|-&lt;br /&gt;
| 68. || A14&lt;br /&gt;
|-&lt;br /&gt;
| 69. || A13&lt;br /&gt;
|-&lt;br /&gt;
| 70. || A12&lt;br /&gt;
|-&lt;br /&gt;
| 71. || VCC&lt;br /&gt;
|-&lt;br /&gt;
| 72. || A11&lt;br /&gt;
|-&lt;br /&gt;
| 73. || A10&lt;br /&gt;
|-&lt;br /&gt;
| 74. || A9&lt;br /&gt;
|-&lt;br /&gt;
| 75. || A8&lt;br /&gt;
|-&lt;br /&gt;
| 76. || A7&lt;br /&gt;
|-&lt;br /&gt;
| 77. || A6&lt;br /&gt;
|-&lt;br /&gt;
| 78. || A5&lt;br /&gt;
|-&lt;br /&gt;
| 79. || A4&lt;br /&gt;
|-&lt;br /&gt;
| 80. || A3&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts</id>
		<title>86:Interrupts</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts"/>
				<updated>2021-09-21T07:01:28Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added brief description of OS ISR &amp;amp; its user interrupt handler support&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Individual interrupt sources can be enabled, disabled, or acknowledged using [[86:Ports:03|Port 3]]. When an interrupt occurs, the CPU automatically masks interrupts, so there is no need to start with DI. Interrupts must be acknowledged before executing EI, or the interrupt will retrigger immediately after the instruction following the EI is executed. RET &amp;amp; RETI have the same effects on the TI-86, so RET can be used to save one byte.&lt;br /&gt;
&lt;br /&gt;
There is no way to cause a non-maskable interrupt, so the OS does not have an NMI handler.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 0 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as an opcode &amp;amp; executes it. If the interrupt source was the [[86:LCD_Controller|LCD Controller]], this will be the last byte transferred by DMA. For any other interrupt source, it will be the last byte accessed by the instruction that was executing when the interrupt condition arose, either as part of the instruction itself or as a memory operand. If the resulting opcode requires additional opcode or operand bytes, they will all have the same value fetched from the address in PC without changing the value of PC. Under normal circumstances, IM 0 is likely to result in a crash.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 1 ==&lt;br /&gt;
When an interrupt occurs, the CPU pushes the return address &amp;amp; then jumps to address 0038h. Note that ROM access should not be disabled (see bit 6 of [[86:Ports:04|Port 4]]) while IM 1 is set &amp;amp; interrupts are enabled, or the calculator will likely crash.&lt;br /&gt;
&lt;br /&gt;
The first thing the OS interrupt service routine does (after doing EX AF,AF' &amp;amp; EXX to preserve the registers of the code that was interrupted) is to check whether bit 2 of (IY+23h) is set. If so, it will call the user interrupt handler, provided its checksum is correct. The user interrupt handler starts execution at address D2FEh, &amp;amp; the last usable byte is at D2C5h. The checksum, which is stored at D2FDh, must contain the sum of the bytes stored at D2FEh, D325h, D34Dh, D375h, D39Dh, &amp;amp; D3C5h, or else the aforementioned IY flag will be cleared instead of executing the handler.&lt;br /&gt;
&lt;br /&gt;
If the user handler is not set (or after it returns), the OS checks if ON triggered the interrupt. If so, it either turns the calculator on (if it was off), turns the calculator off (if 2nd was pressed), or makes note of ON having been pressed. Regardless of the interrupt type, it then checks the keypad state, updates the cursor &amp;amp; run indicator if they are enabled, &amp;amp; updates the APD timer. If the APD timer expires, it turns the calculator off after setting a flag (bit 4 of (IY+08)) to indicate that it should resume where it left off instead of returning to the home screen. (Note that certain special cases have been ignored in this description.)&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 2 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as the lower 8 bits of an address, with the upper 8 bits being the value of the I register. Regardless of interrupt source, the bus content will be the last byte accessed (either as part of the opcode or as a memory operand) by the instruction that was executing when the interrupt condition arose, because if [[86:LCD_Controller#DMA|LCD DMA]] occurs, it takes place after the CPU reads the previous bus content. The CPU then pushes the return address &amp;amp; jumps to the address stored at the address saved earlier. If the first or both of the bytes of this new address are read from an [[86:Memory_Mapping#Unused_Banks|unused bank]], their value will be the lower 8 bits of the return address. If just the second byte is read from an unused bank, its value will be the same as the first.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts</id>
		<title>86:Interrupts</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts"/>
				<updated>2021-09-21T04:38:19Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Fixed behavior of IM 2 vectors in unused banks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Individual interrupt sources can be enabled, disabled, or acknowledged using [[86:Ports:03|Port 3]]. When an interrupt occurs, the CPU automatically masks interrupts, so there is no need to start with DI. Interrupts must be acknowledged before executing EI, or the interrupt will retrigger immediately after the instruction following the EI is executed. RET &amp;amp; RETI have the same effects on the TI-86, so RET can be used to save one byte.&lt;br /&gt;
&lt;br /&gt;
There is no way to cause a non-maskable interrupt, so the OS does not have an NMI handler.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 0 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as an opcode &amp;amp; executes it. If the interrupt source was the [[86:LCD_Controller|LCD Controller]], this will be the last byte transferred by DMA. For any other interrupt source, it will be the last byte accessed by the instruction that was executing when the interrupt condition arose, either as part of the instruction itself or as a memory operand. If the resulting opcode requires additional opcode or operand bytes, they will all have the same value fetched from the address in PC without changing the value of PC. Under normal circumstances, IM 0 is likely to result in a crash.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 1 ==&lt;br /&gt;
When an interrupt occurs, the CPU pushes the return address &amp;amp; then jumps to address 0038h. If the ROM is disabled at the time (see bit 6 of [[86:Ports:04|Port 4]]), the calculator will likely crash.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 2 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as the lower 8 bits of an address, with the upper 8 bits being the value of the I register. Regardless of interrupt source, the bus content will be the last byte accessed (either as part of the opcode or as a memory operand) by the instruction that was executing when the interrupt condition arose, because if [[86:LCD_Controller#DMA|LCD DMA]] occurs, it takes place after the CPU reads the previous bus content. The CPU then pushes the return address &amp;amp; jumps to the address stored at the address saved earlier. If the first or both of the bytes of this new address are read from an [[86:Memory_Mapping#Unused_Banks|unused bank]], their value will be the lower 8 bits of the return address. If just the second byte is read from an unused bank, its value will be the same as the first.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts</id>
		<title>86:Interrupts</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts"/>
				<updated>2021-09-21T04:34:04Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;Interrupts  Individual interrupt sources can be enabled, disabled, or acknowledged using Port 3. When an interrupt...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Individual interrupt sources can be enabled, disabled, or acknowledged using [[86:Ports:03|Port 3]]. When an interrupt occurs, the CPU automatically masks interrupts, so there is no need to start with DI. Interrupts must be acknowledged before executing EI, or the interrupt will retrigger immediately after the instruction following the EI is executed. RET &amp;amp; RETI have the same effects on the TI-86, so RET can be used to save one byte.&lt;br /&gt;
&lt;br /&gt;
There is no way to cause a non-maskable interrupt, so the OS does not have an NMI handler.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 0 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as an opcode &amp;amp; executes it. If the interrupt source was the [[86:LCD_Controller|LCD Controller]], this will be the last byte transferred by DMA. For any other interrupt source, it will be the last byte accessed by the instruction that was executing when the interrupt condition arose, either as part of the instruction itself or as a memory operand. If the resulting opcode requires additional opcode or operand bytes, they will all have the same value fetched from the address in PC without changing the value of PC. Under normal circumstances, IM 0 is likely to result in a crash.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 1 ==&lt;br /&gt;
When an interrupt occurs, the CPU pushes the return address &amp;amp; then jumps to address 0038h. If the ROM is disabled at the time (see bit 6 of [[86:Ports:04|Port 4]]), the calculator will likely crash.&lt;br /&gt;
&lt;br /&gt;
== Interrupt Mode 2 ==&lt;br /&gt;
When an interrupt occurs, the CPU treats the current bus content as the lower 8 bits of an address, with the upper 8 bits being the value of the I register. Regardless of interrupt source, the bus content will be the last byte accessed (either as part of the opcode or as a memory operand) by the instruction that was executing when the interrupt condition arose, because if [[86:LCD_Controller#DMA|LCD DMA]] occurs, it takes place after the CPU reads the previous bus content. The CPU then pushes the return address &amp;amp; jumps to the address stored at the address saved earlier. If either or both of the bytes of this new address are read from an [[86:Memory_Mapping#Unused_Banks|unused bank]], their value will be the lower 8 bits of the return address.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-09-20T20:32:38Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated unmapped address space known revision range&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least I-S).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
|1&lt;br /&gt;
&lt;br /&gt;
20-21/22&lt;br /&gt;
&lt;br /&gt;
15/13&lt;br /&gt;
&lt;br /&gt;
11&lt;br /&gt;
&lt;br /&gt;
9&lt;br /&gt;
&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
15-16/13&lt;br /&gt;
&lt;br /&gt;
12/10&lt;br /&gt;
&lt;br /&gt;
10/8&lt;br /&gt;
&lt;br /&gt;
8&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
&lt;br /&gt;
Special timing for 4000-400F &amp;amp; 4018-401B (pre-M/M+) at 48 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz&lt;br /&gt;
&lt;br /&gt;
Special timing for 4200-43FF (any CPU speed)&lt;br /&gt;
&lt;br /&gt;
Special timing for 4C00-4DFF (pre-M/M+) at 48 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address</id>
		<title>Category:84PCE:RAM:By Address</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address"/>
				<updated>2021-09-20T20:32:30Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated unmapped address space known revision range&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also [[:Category:84PCE:RAM:By Name|list of RAM areas by name]].&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;br /&gt;
&lt;br /&gt;
The eZ80 has a 24-bit linear address space. Layout:&lt;br /&gt;
* 000000h: Start of flash. The first 128 K are locked boot sectors. The first 8 are divided into 8 K sectors, all of which are locked. The certificate is now a single 64 K sector, so I hope you don't crash while rebuilding it.&lt;br /&gt;
* 000066h: Flash exception handler. Write-to-flash without permission triggers the non-maskable interrupt to fire.&lt;br /&gt;
* 00007Eh: Hardware/Emu flag: This byte indicates whether the ROM is a hardware ROM or emulator.&lt;br /&gt;
* 000080h: Start of boot code jump table.&lt;br /&gt;
* 020000h: Start of OS.&lt;br /&gt;
* 0C0000h: Start of user archive.&lt;br /&gt;
* 3B0000h: Certificate.&lt;br /&gt;
* 3C0000h: Temp RAM backup, on newer versions of TIOS debug output is also written here.&lt;br /&gt;
* 3E0000h: Temp RAM backup.&lt;br /&gt;
* 3F0000h: Temp RAM backup, temp certificate backup, swap sector.&lt;br /&gt;
* 400000h: Can be setup to mirror flash, but usually unmapped.&lt;br /&gt;
* 800000h: Always unmapped.&lt;br /&gt;
* D00000h: Start of RAM. 256 K.&lt;br /&gt;
* D1A87Eh: Top of the SPL stack.&lt;br /&gt;
* D1A881h: Start of UserMem.&lt;br /&gt;
* D40000h: Start of VRAM. 320x240x2 bytes = 153600 bytes.&lt;br /&gt;
* D65800h: Unmapped memory.&lt;br /&gt;
* D72C00h: Unmapped memory (revisions up to at least C) or mirror of D52C00h (at least I-S).&lt;br /&gt;
* D80000h: Mirror of D00000h.&lt;br /&gt;
* E00000h: Start of [[84PCE:Wait_States|memory-mapped I/O]] address spaces.&lt;br /&gt;
&lt;br /&gt;
SafeRAM Areas:&lt;br /&gt;
* D031F6h: [[84PCE:RAM:D031F6|pixelShadow]] - 8400 bytes&lt;br /&gt;
* D052C6h: [[84PCE:RAM:D052C6|pixelShadow2]] - 8400 bytes&lt;br /&gt;
* D07396h: [[84PCE:RAM:D07396|cmdPixelShadow]] - 8400 bytes&lt;br /&gt;
* D09466h: [[84PCE:RAM:D09466|plotSScreen]] - 21945 bytes&lt;br /&gt;
* D0EA1Fh: [[84PCE:RAM:D0EA1F|saveSScreen]] - 21945 bytes&lt;br /&gt;
** Note that the above is contiguous, which provides a total linear free space of 69090 bytes of RAM.&lt;br /&gt;
** [[84PCE:RAM:D052C6|pixelShadow2]] is the most stable; and is a viable option for ''testing'' TSRs and hooks.&lt;br /&gt;
&lt;br /&gt;
More SafeRAM Areas:&lt;br /&gt;
* D006C0h: [[84PCE:RAM:D006C0|textShadow]] - 260 bytes&lt;br /&gt;
* D0232Dh: [[84PCE:RAM:D0232D|cmdShadow]] - 260 bytes&lt;br /&gt;
&lt;br /&gt;
Also, if you do not wish to use the LCD cursor (This is not RAM, but can be used as scrap)&lt;br /&gt;
* E30800h: cursorImage - 1024 bytes&lt;br /&gt;
[[Category:84PCE:RAM|RAM Areas by Address]]&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:20</id>
		<title>86:Ports:20</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:20"/>
				<updated>2021-09-20T19:59:42Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;20 - External I/O External I/O == Synopsis == '''Port Number:''' 20-3Fh  '''Function:''' None  This port range i...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|20 - External I/O]] [[Category:86:Ports:By_Name|External I/O]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 20-3Fh&lt;br /&gt;
&lt;br /&gt;
'''Function:''' None&lt;br /&gt;
&lt;br /&gt;
This port range is meant for communication with external I/O devices, but the TI-86 has no such devices.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
Because these ports are not connected to anything, their read behavior is the same as [[86:Memory_Mapping#Unused_Banks|Unused Banks]].&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
Because these ports are not connected to anything, their write behavior is the same as unused banks. That is, writes are ignored.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:86:Ports:By_Address</id>
		<title>Category:86:Ports:By Address</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:86:Ports:By_Address"/>
				<updated>2021-09-20T19:50:34Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Port mirroring&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports|Ports by Address/Number]]&lt;br /&gt;
&lt;br /&gt;
See also [[:Category:86:Ports:By Name|list of ports by name]].&lt;br /&gt;
&lt;br /&gt;
Ports are mirrored: Adding 8, 10h, or 18h to ports in the 0-7 range will access the same port, &amp;amp; adding 40h, 80h, or C0h to any port will access the same port.&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:01</id>
		<title>86:Ports:01</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:01"/>
				<updated>2021-09-20T19:47:19Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Based on 83Plus:Ports:01, changed key labels &amp;amp; added battery level&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|01 - Keyboard]] [[Category:86: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;
See also [[83Plus:Ports:01|TI-83 Plus Port 01]], which is identical apart from the key labels &amp;amp; the lack of battery level detection.&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.&lt;br /&gt;
* Bit 0 will also read as 0 if groups 0-2 are all selected &amp;amp; the battery level is low.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* FFh : Reset the keypad. This unselects all groups and resets the keypad state.&lt;br /&gt;
* F8h : Check battery level. This also selects keypad groups 0-2 for monitoring.&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  ||     || F5  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 1 !! (FD)&lt;br /&gt;
| LEFT||  +  ||  3   ||  2  ||  1  || STO || F4  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 2 !! (FB)&lt;br /&gt;
|RIGHT||  -  ||  6   ||  5  ||  4  ||  ,  || F3  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 3 !! (F7)&lt;br /&gt;
| UP  ||  *  ||  9   ||  8  ||  7  || x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; || F2  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 4 !! (EF)&lt;br /&gt;
|     ||  /  ||  )   ||  (  || EE  || LN  || F1  ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 5 !! (DF)&lt;br /&gt;
|     ||  ^  || TAN  || COS || SIN || LOG || 2nd ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 6 !! (BF)&lt;br /&gt;
|     ||CLEAR||CUSTOM||PRGM ||TABLE||GRAPH||EXIT ||     ||&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! (7F)&lt;br /&gt;
|     ||     ||      || DEL ||x-VAR||ALPHA||MORE ||     ||&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 [[86:Ports:03|Port 03]], bit 3.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* The OS delays about 1400 cycles (100 iterations of a tight DJNZ loop) when checking the battery level at startup, which is much longer than used to test if keys are pressed.&lt;br /&gt;
* Bit 0 will be 0 when testing the battery level if the warning message would appear. However, because it is still also wired to the keypad, holding any of DOWN, ENTER, or (-) when turning the calculator on will also cause the warning message to appear.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:03</id>
		<title>86:Ports:03</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:03"/>
				<updated>2021-09-20T13:03:03Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Fixed bit 1 &amp;amp; 3 write descriptions &amp;amp; linked to LCD controller page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|03 - Interrupt Control]] [[Category:86:Ports:By_Name|Interrupt Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 03h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Interrupt Control Port&lt;br /&gt;
&lt;br /&gt;
This port controls all devices that can generate interrupts.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0: Set if the ON key generated an interrupt.&lt;br /&gt;
* Bit 1: Set if the [[86:LCD_Controller|LCD controller]] generated an interrupt (after [[86:LCD_Controller#DMA|DMA]] for rows 17 &amp;amp; 49). Used by the OS as a periodic interrupt source (approximately 200 Hz).&lt;br /&gt;
* Bit 2: Set if the /INT pin generated an interrupt (unused on the TI-86).&lt;br /&gt;
* Bit 3: Reset if the ON key is being pressed; set otherwise.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: Set 0 to disable ON key interrupts and to acknowledge an ON key interrupt. Set 1 to enable ON key interrupts.&lt;br /&gt;
* Bit 1: Set 0 to disable [[86:LCD_Controller#Interrupts|LCD controller interrupts]] &amp;amp; to acknowledge an interrupt from the LCD controller. Set 1 to enable interrupts from the LCD controller.&lt;br /&gt;
* Bit 2: Set 0 to disable external interrupts &amp;amp; to acknowledge an external interrupt. Set 1 to enable external interrupts.&lt;br /&gt;
* Bit 3: Set 0 to turn off the LCD. Set 1 to turn on the LCD. When the LCD is off, DMA &amp;amp; LCD interrupts do not occur.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* You need to acknowledge interrupts. Otherwise a new interrupt will be generated directly after you enable interrupts again with EI. Because that disables that particular interrupt at the same time, you may have to write a second value to this port to re-enable it.&lt;br /&gt;
* The OS shuts down by turning off the LCD &amp;amp; HALTing with the ON key interrupt enabled.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:86:General_Hardware_Information</id>
		<title>Category:86:General Hardware Information</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:86:General_Hardware_Information"/>
				<updated>2021-09-20T12:56:14Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: No TI-86 &amp;quot;family&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is the central location for generic documentation on the TI-86 hardware.&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:86:General_Hardware_Information</id>
		<title>Category:86:General Hardware Information</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:86:General_Hardware_Information"/>
				<updated>2021-09-20T12:55:21Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;This is the central location for generic documentation on the TI-86 family hardware.  Please read our page on Contributing before editing these pages!&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is the central location for generic documentation on the TI-86 family hardware.&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Calculator_Documentation</id>
		<title>Calculator Documentation</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Calculator_Documentation"/>
				<updated>2021-09-20T12:52:54Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added general hardware information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TI-83 (Regular) ==&lt;br /&gt;
&lt;br /&gt;
Available Information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:83:ROMCalls:By_Name|ROMCalls (System Entrypoints)]]&lt;br /&gt;
* [[:Category:83:Flags:By_Name|Flags]]&lt;br /&gt;
* [[:Category:83:OS_Information|General OS Documentation]]&lt;br /&gt;
* [[:Category:83:Ports:By_Address|Ports]]&lt;br /&gt;
* [[:Category:83:RAM:By_Name|RAM Areas]]&lt;br /&gt;
&lt;br /&gt;
== TI-83 Plus Family ==&lt;br /&gt;
&lt;br /&gt;
Available Information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:83Plus:BCALLs:By_Name|B_CALLs (System Entrypoints)]]&lt;br /&gt;
* [[:Category:83Plus:Flags:By_Name|Flags]]&lt;br /&gt;
* [[:Category:83Plus:OS_Information|General OS Documentation]]&lt;br /&gt;
* [[:Category:83Plus:General_Hardware_Information|General Hardware Documentation]]&lt;br /&gt;
* [[:Category:83Plus:Hooks:By_Name|Hooks]]&lt;br /&gt;
* [[:Category:83Plus:Ports:By_Address|Ports]]&lt;br /&gt;
* [[:Category:83Plus:RAM:By_Name|RAM Areas]]&lt;br /&gt;
* [[:Category:83Plus:Basic|TI-83+ Basic]]&lt;br /&gt;
* [[:Category:83Plus:Quirks|Quirks]]&lt;br /&gt;
&lt;br /&gt;
== TI-84+CSE ==&lt;br /&gt;
&lt;br /&gt;
Available Information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:84PCSE:BCALLs:By_Name|B_CALLs (System Entrypoints)]]&lt;br /&gt;
* [[:Category:84PCSE:Flags:By_Name|Flags]]&lt;br /&gt;
* [[:Category:84PCSE:OS_Information|General OS Documentation]]&lt;br /&gt;
* [[:Category:84PCSE:General_Hardware_Information|General Hardware Documentation]]&lt;br /&gt;
* [[:Category:84PCSE:Hooks:By_Name|Hooks]]&lt;br /&gt;
* [[:Category:84PCSE:RAM:By_Name|RAM Areas]]&lt;br /&gt;
* [[:Category:84PCSE:Basic|TI-83+ Basic]]&lt;br /&gt;
Note: Because the TI-84+CSE is based on the older TI-84+ ASIC, much of the hardware related documentation is the same. Therefore, the port list for the TI-84+CSE shall be combined with the TI-83+ ports.&lt;br /&gt;
&lt;br /&gt;
== TI-84 Plus CE[-T], TI-83 Premium CE ==&lt;br /&gt;
&lt;br /&gt;
Available information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:84PCE:Syscalls:By_Name|System Entrypoints]]&lt;br /&gt;
* [[:Category:83PCE:Hooks:By_Name|Hooks]]&lt;br /&gt;
* [[:Category:84PCE:General_Hardware_Information|General Hardware Documentation]]&lt;br /&gt;
* [[:Category:84PCE:OS_Information|General OS Documentation]]&lt;br /&gt;
* [[:Category:84PCE:RAM:By_Address|RAM areas]]&lt;br /&gt;
* [[:Category:84PCE:Ports:By_Name|Ports]]&lt;br /&gt;
&lt;br /&gt;
The TI-84 Plus CE and TI-83 Premium CE are two models new in 2015. The former is for the USA region (maybe all of North America?) and the latter is for France (Features a PTT LED and an exact math engine, whose new vartypes are documented [https://docs.google.com/document/d/1P_OUbnZMZFg8zuOPJHAx34EnwxcQZ8HER9hPeOQ_dtI here]).&amp;lt;br/&amp;gt;&lt;br /&gt;
The hardware is virtually identical between the two models. The TI-84 Plus CE-T is the European counterpart of the TI-84 Plus CE, but has the PTT LED like the 83PCE.&lt;br /&gt;
&lt;br /&gt;
== TI-86 ==&lt;br /&gt;
&lt;br /&gt;
Available Information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:86:ROMCalls:By_Name|ROMCalls (System Entrypoints)]]&lt;br /&gt;
* [[:Category:86:Flags:By_Name|Flags]]&lt;br /&gt;
* [[:Category:86:General_Hardware_Information|General Hardware Documentation]]&lt;br /&gt;
* [[:Category:86:OS_Information|General OS Documentation]]&lt;br /&gt;
* [[:Category:86:Ports:By_Address|Ports]]&lt;br /&gt;
* [[:Category:86:RAM:By_Name|RAM Areas]]&lt;br /&gt;
&lt;br /&gt;
== M68K Family ==&lt;br /&gt;
&lt;br /&gt;
Available Information:&lt;br /&gt;
&lt;br /&gt;
* [[:Category:68k:Ports:By_Address|Ports]]&lt;br /&gt;
&lt;br /&gt;
== Z80 programming ==&lt;br /&gt;
* [[Meta-tutorial]]&lt;br /&gt;
* [[:Category:Z80_Routines|Z80 Routines]]&lt;br /&gt;
* [[Z80 Instruction Set]]&lt;br /&gt;
* [[Z80 Good Programming Practices]]&lt;br /&gt;
* [[Z80 Optimization]]&lt;br /&gt;
* [[Programming cross z80 calculators]]&lt;br /&gt;
* [[Programming APPS vs. Ram Programs]]&lt;br /&gt;
* [[Programming under Unix-like operating systems]]&lt;br /&gt;
* [[Programming an OS for z80 calculators]]&lt;br /&gt;
&lt;br /&gt;
== Calculator Software ==&lt;br /&gt;
* [[Notable programs]]&lt;br /&gt;
* [[:Category:83Plus:Software|83Plus Software Documentation]]&lt;br /&gt;
* [[Experiments]]&lt;br /&gt;
&lt;br /&gt;
== Computer Software ==&lt;br /&gt;
* [[Link software]]&lt;br /&gt;
* [[:Category:Emulators|Emulators]]&lt;br /&gt;
* [[Assemblers]]&lt;br /&gt;
* [[Compilers]]&lt;br /&gt;
* [[IDEs]]&lt;br /&gt;
* [[Disassemblers]]&lt;br /&gt;
&lt;br /&gt;
== TI Community ==&lt;br /&gt;
&lt;br /&gt;
* [[Beginners|Beginners' manual]]&lt;br /&gt;
* [[Calculator General FAQ]]&lt;br /&gt;
* [[History of the TI Z80 community]]&lt;br /&gt;
* [[:Category:Teams|Programming Teams List]]&lt;br /&gt;
* [[TI websites|TI Web Sites List]]&lt;br /&gt;
&lt;br /&gt;
== Contributing ==&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before you start contributing to WikiTI.&lt;br /&gt;
&lt;br /&gt;
If you feel like contributing but do not know where, see the [[To Do List]].&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping</id>
		<title>86:Memory Mapping</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping"/>
				<updated>2021-09-20T12:50:58Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Fixed a link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Memory Mapping]]&lt;br /&gt;
== Memory Mapping ==&lt;br /&gt;
Memory on the TI-86 is divided into pages of 16 KiB each. Addresses in the 4000-BFFFh range can be mapped to any page in any bank, while 0000-3FFFh is permanently mapped to ROM page 0, &amp;amp; C000-FFFFh is permanently mapped to RAM page 0.&lt;br /&gt;
&lt;br /&gt;
Bits 0-5 of [[86:Ports:05|Port 05]] &amp;amp; [[86:Ports:06|Port 06]] select the page for the 4000-7FFFh &amp;amp; 8000-BFFFh ranges, respectively. These are output on external address lines 14-19 when the corresponding range is accessed. There are 4 memory banks, which can be chosen by bits 6-7 of these ports:&lt;br /&gt;
* 00: 256 KiB of ROM, divided into 16 pages. Port bits 4-5 (address bits 18-19) are unused, so ROM repeats 4 times.&lt;br /&gt;
* 01: 128 KiB of RAM, divided into 8 pages. Port bits 3-5 (address bits 17-19) are unused, so RAM repeats 8 times.&lt;br /&gt;
* 10: Unused.&lt;br /&gt;
* 11: Unused on mass-production TI-86es, or mirror of bank 00 on prototype TI-86es with flash ROM. The flash update code uses this bank for writing, in conjunction with bit 6 of [[86:Ports:04|Port 04]].&lt;br /&gt;
Each bank has its own /CE (chip enable) output, while all banks share a common /WE (write enable) output.&lt;br /&gt;
&lt;br /&gt;
The memory mapping when a user program starts has port 05 set to 0Dh (a ROM page containing all the public ROM calls) &amp;amp; port 06 set to 41h (a RAM page containing the operation stack &amp;amp; the floating-point stack). The port 05 value must be restored before returning to the OS, but the port 06 value at exit is ignored.&lt;br /&gt;
&lt;br /&gt;
== Unused Banks ==&lt;br /&gt;
Writing to ROM or to an unused bank has no effect. Reading from an unused bank will return the current bus content. This is generally the last byte of the instruction doing the reading, unless that instruction is interrupted by [[86:LCD_Controller#DMA|LCD DMA]], in which case it will be the last byte of the next LCD row to be displayed. However, if the bus is not updated for long enough (by reason of PC being in an unused bank while the LCD is turned off), the bits it reads will gradually decay to 0, causing it to execute various opcodes until it either transfers execution to a normal bank, HALTs, or gets stuck executing NOPs.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:00</id>
		<title>86:Ports:00</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:00"/>
				<updated>2021-09-20T12:48:44Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;00 - LCD Base Address LCD Base Address == Synopsis == '''Port Number:''' 00h  '''Function:''' LCD DMA Base Addre...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|00 - LCD Base Address]] [[Category:86:Ports:By_Name|LCD Base Address]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 00h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD DMA Base Address&lt;br /&gt;
&lt;br /&gt;
This port controls the base address used as video memory by [[86:LCD_Controller#DMA|LCD DMA]].&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
Because this port is write-only, its read behavior is the same as [[86:Memory_Mapping#Unused_Banks|Unused Banks]].&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0-5: Bits 8-13 of LCD base address. The lower 8 bits of the address are always 0, &amp;amp; it is always in RAM page 0.&lt;br /&gt;
* Bit 6-7: Unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* The OS sets this port to 7Ch, which results in video memory being accessible at FC00-FFFFh. However, it only sets it when the CPU is reset, so it should be set back to 7Ch (or 3Ch, BCh, or FCh, which behave identically) before returning to the OS.&lt;br /&gt;
* Changing this port causes the LCD image to change at the start (probably) of the next frame, so it can be used for double buffering, but not for a split screen effect.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:04</id>
		<title>86:Ports:04</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:04"/>
				<updated>2021-09-20T12:36:09Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;04 - LCD Control LCD Control == Synopsis == '''Port Number:''' 04h  '''Function:''' LCD Control, Memory Access C...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|04 - LCD Control]] [[Category:86:Ports:By_Name|LCD Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 04h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Control, Memory Access Control&lt;br /&gt;
&lt;br /&gt;
This port controls the [[86:LCD_Controller|LCD controller]] &amp;amp; access to RAM &amp;amp; ROM.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
Because this port is write-only, its read behavior is the same as [[86:Memory_Mapping#Unused_Banks|Unused Banks]].&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: Set 0 to enable CPU access to RAM. Set 1 to disable CPU access to RAM, in which case RAM behaves like an unused bank. [[86:LCD_Controller#DMA|DMA]] is still able to read from RAM normally when this bit is 1.&lt;br /&gt;
* Bit 1-2: Number of rows per logical frame. This also affects the LCD interrupt speed.&lt;br /&gt;
** 00: 16 rows &amp;amp; 4X interrupt speed.&lt;br /&gt;
** 01: 32 rows &amp;amp; 2X interrupt speed.&lt;br /&gt;
** 10: 48 rows &amp;amp; 4/3X interrupt speed.&lt;br /&gt;
** 11: 64 rows &amp;amp; normal interrupt speed.&lt;br /&gt;
* Bit 3-4: Number of columns per row to obtain via DMA.&lt;br /&gt;
** 00: 80 columns.&lt;br /&gt;
** 01: 96 columns (used by the TI-81).&lt;br /&gt;
** 10: 128 columns (used by the TI-85 &amp;amp; TI-86).&lt;br /&gt;
** 11: 160 columns (used by the PS-6600).&lt;br /&gt;
* Bit 5: Set 0 to use slower DMA (about 6 cycles per byte). Set 1 to use faster DMA (about 2 cycles per byte).&lt;br /&gt;
* Bit 6: Set 0 to enable writing to flash ROM. Set 1 to disable writing to flash ROM. On mass-production TI-86es, a missing AND gate results in the ROM behaving as if it were an unused bank if this is set to 0.&lt;br /&gt;
* Bit 7: Apparently unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* The OS sets this port to 56h when the calculator is operating normally, &amp;amp; it uses 57h when the CPU is reset &amp;amp; when turning off. This appears to be intended either to save power or to protect the contents of RAM from accidental modification when the main batteries are low or are being changed.&lt;br /&gt;
* Setting fewer than 64 rows causes vertical repetition. It also makes the image darker.&lt;br /&gt;
* Setting fewer than 128 columns per row results in horizontal repetition in a pattern explained by [[86:LCD_Controller#DMA|DMA]].&lt;br /&gt;
* The OS uses the slower DMA mode. It is unknown whether the faster mode works on all calculators. The numbers of CPU cycles per byte are approximate because the LCD controller uses a separate clock from the CPU clock.&lt;br /&gt;
* Disabling access to RAM from within RAM is not recommended.&lt;br /&gt;
* Disabling access to ROM while the OS interrupt service routine is enabled is not recommended.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:LCD_Controller</id>
		<title>86:LCD Controller</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:LCD_Controller"/>
				<updated>2021-09-20T12:36:03Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;LCD Controller The TI-86 has a memory-mapped STN liquid crystal display. The main portion of LCD controller is inside the ASIC, wi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|LCD Controller]]&lt;br /&gt;
The TI-86 has a memory-mapped STN liquid crystal display. The main portion of LCD controller is inside the ASIC, with row &amp;amp; column drivers &amp;amp; circuitry to produce the necessary voltages located on a daughterboard on which the LCD itself is also mounted.&lt;br /&gt;
&lt;br /&gt;
== DMA ==&lt;br /&gt;
When the LCD is enabled, the ASIC needs to send pixels to it continuously. In order to allow the CPU to operate at the same time, the ASIC contains an internal buffer used to hold the pixels for the current row. This buffer is filled via DMA (direct memory access) that pauses the CPU once per row. This pause appears to be implemented internally by way of the Z80 signals /BUSREQ &amp;amp; /BUSACK, &amp;amp; as such, it is even able to occur in between the M cycles of a single instruction. No DMA is performed when the LCD is disabled.&lt;br /&gt;
&lt;br /&gt;
The LCD always uses all 64 rows per physical frame. If the number of rows per logical frame is set lower than 64 via bits 1-2 of [[86:Ports:04|Port 4]], the subsequent logical frames are stacked vertically until the whole 64 rows are filled, with the last one being cut short if the rows per frame is set to 48. This stacking also makes the image darker, presumably because it increases the effective duty cycle.&lt;br /&gt;
&lt;br /&gt;
The LCD controller always sends 160 pixels per row to the daughterboard, of which the first 80 &amp;amp; last 48 are visible on screen, for a total of 128 visible columns. However, DMA only reads as many bytes as necessary to contain the number of columns chosen via bits 3-4 of [[86:Ports:04|Port 4]]. Of the columns read via DMA, the first 80 are placed at the beginning of the buffer, &amp;amp; the remainder are placed at the end of the buffer. If this is fewer than the full 160 columns, the 4 columns immediately after the first 80 are copied from the last 4 of the previous row's DMA transfer. The remaining columns are copied starting from the beginning of the current row's DMA transfer.&lt;br /&gt;
&lt;br /&gt;
== Interrupts ==&lt;br /&gt;
LCD interrupts occur twice per logical frame. They occur one row after one quarter &amp;amp; three quarters of the way down the frame, which is rows 17 &amp;amp; 49 (counting from 0) when set to 64 rows per frame. DMA occurs after the interrupt acknowledgement, which in particular is after the CPU reads the byte used to determine which offset to use for IM 2. The start of the interrupt service routine itself is then delayed until DMA finishes.&lt;br /&gt;
&lt;br /&gt;
Warning: Toggling individual pixels every other interrupt may damage the LCD by causing a net charge to accumulate. Any given pixel's value should only be changed (at most) once every fourth interrupt. This is because the pixels of STN LCDs must be driven using AC waveforms to prevent damage due to charge buildup, &amp;amp; the calculator achieves this by alternating between 2 sets of voltages on consecutive frames.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:02</id>
		<title>86:Ports:02</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:02"/>
				<updated>2021-09-20T10:15:48Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;02 - Contrast Contrast == Synopsis == '''Port Number:''' 02h  '''Function:''' LCD Contrast  This port controls t...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|02 - Contrast]] [[Category:86:Ports:By_Name|Contrast]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 02h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Contrast&lt;br /&gt;
&lt;br /&gt;
This port controls the LCD contrast.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
Because this port is write-only, its read behavior is the same as [[86:Memory_Mapping#Unused_Banks|Unused Banks]].&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0-4: Contrast level. 00h is lightest &amp;amp; 1Fh is darkest.&lt;br /&gt;
* Bit 5-7: Unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* In addition to writing to this port, the OS saves the current contrast at address C008h so that it is able to read it back later. If the value written to this port is different from the value at C008h, the value at C008h will be used the next time the user changes the contrast using the OS.&lt;br /&gt;
* If the value at C008h is greater than 1Fh, it is impossible to increase the contrast until it falls below 1Fh. Because the upper 3 bits are ignored by the hardware, this can result in having to cycle through all apparent contrast levels multiple times.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping</id>
		<title>86:Memory Mapping</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping"/>
				<updated>2021-09-20T09:22:30Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added section heading for unused banks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Memory Mapping]]&lt;br /&gt;
== Memory Mapping ==&lt;br /&gt;
Memory on the TI-86 is divided into pages of 16 KiB each. Addresses in the 4000-BFFFh range can be mapped to any page in any bank, while 0000-3FFFh is permanently mapped to ROM page 0, &amp;amp; C000-FFFFh is permanently mapped to RAM page 0.&lt;br /&gt;
&lt;br /&gt;
Bits 0-5 of [[86:Ports:05|Port 05]] &amp;amp; [[86:Ports:06|Port 06]] select the page for the 4000-7FFFh &amp;amp; 8000-BFFFh ranges, respectively. These are output on external address lines 14-19 when the corresponding range is accessed. There are 4 memory banks, which can be chosen by bits 6-7 of these ports:&lt;br /&gt;
* 00: 256 KiB of ROM, divided into 16 pages. Port bits 4-5 (address bits 18-19) are unused, so ROM repeats 4 times.&lt;br /&gt;
* 01: 128 KiB of RAM, divided into 8 pages. Port bits 3-5 (address bits 17-19) are unused, so RAM repeats 8 times.&lt;br /&gt;
* 10: Unused.&lt;br /&gt;
* 11: Unused on mass-production TI-86es, or mirror of bank 00 on prototype TI-86es with flash ROM. The flash update code uses this bank for writing, in conjunction with bit 6 of [[86:Ports:04|Port 04]].&lt;br /&gt;
Each bank has its own /CE (chip enable) output, while all banks share a common /WE (write enable) output.&lt;br /&gt;
&lt;br /&gt;
The memory mapping when a user program starts has port 05 set to 0Dh (a ROM page containing all the public ROM calls) &amp;amp; port 06 set to 41h (a RAM page containing the operation stack &amp;amp; the floating-point stack). The port 05 value must be restored before returning to the OS, but the port 06 value at exit is ignored.&lt;br /&gt;
&lt;br /&gt;
== Unused Banks ==&lt;br /&gt;
Writing to ROM or to an unused bank has no effect. Reading from an unused bank will return the current bus content. This is generally the last byte of the instruction doing the reading, unless that instruction is interrupted by [[86:LCD_DMA|LCD DMA]], in which case it will be the last byte of the next LCD row to be displayed. However, if the bus is not updated for long enough (by reason of PC being in an unused bank while the LCD is turned off), the bits it reads will gradually decay to 0, causing it to execute various opcodes until it either transfers execution to a normal bank, HALTs, or gets stuck executing NOPs.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping</id>
		<title>86:Memory Mapping</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Memory_Mapping"/>
				<updated>2021-09-20T09:09:04Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;Memory Mapping == Memory Mapping == Memory on the TI-86 is divided into pages of 16 KiB each. Addresses in the 4000-BFFFh range ca...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:General Hardware Information|Memory Mapping]]&lt;br /&gt;
== Memory Mapping ==&lt;br /&gt;
Memory on the TI-86 is divided into pages of 16 KiB each. Addresses in the 4000-BFFFh range can be mapped to any page in any bank, while 0000-3FFFh is permanently mapped to ROM page 0, &amp;amp; C000-FFFFh is permanently mapped to RAM page 0.&lt;br /&gt;
&lt;br /&gt;
Bits 0-5 of [[86:Ports:05|Port 05]] &amp;amp; [[86:Ports:06|Port 06]] select the page for the 4000-7FFFh &amp;amp; 8000-BFFFh ranges, respectively. These are output on external address lines 14-19 when the corresponding range is accessed. There are 4 memory banks, which can be chosen by bits 6-7 of these ports:&lt;br /&gt;
* 00: 256 KiB of ROM, divided into 16 pages. Port bits 4-5 (address bits 18-19) are unused, so ROM repeats 4 times.&lt;br /&gt;
* 01: 128 KiB of RAM, divided into 8 pages. Port bits 3-5 (address bits 17-19) are unused, so RAM repeats 8 times.&lt;br /&gt;
* 10: Unused.&lt;br /&gt;
* 11: Unused on mass-production TI-86es, or mirror of bank 00 on prototype TI-86es with flash ROM. The flash update code uses this bank for writing, in conjunction with bit 6 of [[86:Ports:04|Port 04]].&lt;br /&gt;
Each bank has its own /CE (chip enable) output, while all banks share a common /WE (write enable) output.&lt;br /&gt;
&lt;br /&gt;
The memory mapping when a user program starts has port 05 set to 0Dh (a ROM page containing all the public ROM calls) &amp;amp; port 06 set to 41h (a RAM page containing the operation stack &amp;amp; the floating-point stack). The port 05 value must be restored before returning to the OS, but the port 06 value at exit is ignored.&lt;br /&gt;
&lt;br /&gt;
Writing to ROM or to an unused bank has no effect. Reading from an unused bank will return the current bus content. This is generally the last byte of the instruction doing the reading, unless that instruction is interrupted by [[86:LCD_DMA|LCD DMA]], in which case it will be the last byte of the next LCD row to be displayed. However, if the bus is not updated for long enough (by reason of PC being in an unused bank while the LCD is turned off), the bits it reads will gradually decay to 0, causing it to execute various opcodes until it either transfers execution to a normal bank, HALTs, or gets stuck executing NOPs.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:06</id>
		<title>86:Ports:06</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:06"/>
				<updated>2021-09-20T09:08:52Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;06 - Upper Memory Bank Upper Memory Bank == Synopsis == '''Port Number:''' 06h  '''Function:''' Upper Memory Ban...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|06 - Upper Memory Bank]] [[Category:86:Ports:By_Name|Upper Memory Bank]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 06h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Upper Memory Bank Port&lt;br /&gt;
&lt;br /&gt;
This port controls which memory bank is accessible in the 8000-BFFFh range. See [[86:Memory_Mapping|Memory Mapping]] for the interpretation of the banks &amp;amp; pages.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0-7: Reads last value written.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0-5: Page select (external address bits 14-19).&lt;br /&gt;
* Bit 6-7: Bank select.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* This port is set to 41h when the OS passes control to a program. Its value at program exit is ignored.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:05</id>
		<title>86:Ports:05</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:05"/>
				<updated>2021-09-20T09:07:06Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Fixed an incorrect link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|05 - Lower Memory Bank]] [[Category:86:Ports:By_Name|Lower Memory Bank]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 05h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Lower Memory Bank Port&lt;br /&gt;
&lt;br /&gt;
This port controls which memory bank is accessible in the 4000-7FFFh range. See [[86:Memory_Mapping|Memory Mapping]] for the interpretation of the banks &amp;amp; pages.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0-7: Reads last value written.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0-5: Page select (external address bits 14-19).&lt;br /&gt;
* Bit 6-7: Bank select.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* This port is set to 0Dh when the OS passes control to a program.&lt;br /&gt;
* Set this port to 0Dh before attempting to call OS functions, because that page contains the public ROM call table. Also be sure to set it to 0Dh before returning to the OS.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:05</id>
		<title>86:Ports:05</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:05"/>
				<updated>2021-09-20T09:06:38Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;05 - Lower Memory Bank Lower Memory Bank == Synopsis == '''Port Number:''' 05h  '''Function:''' Lower Memory Ban...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|05 - Lower Memory Bank]] [[Category:86:Ports:By_Name|Lower Memory Bank]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 05h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Lower Memory Bank Port&lt;br /&gt;
&lt;br /&gt;
This port controls which memory bank is accessible in the 4000-7FFFh range. See [[86:OS:Memory_Mapping|Memory Mapping]] for the interpretation of the banks &amp;amp; pages.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0-7: Reads last value written.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0-5: Page select (external address bits 14-19).&lt;br /&gt;
* Bit 6-7: Bank select.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* This port is set to 0Dh when the OS passes control to a program.&lt;br /&gt;
* Set this port to 0Dh before attempting to call OS functions, because that page contains the public ROM call table. Also be sure to set it to 0Dh before returning to the OS.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:07</id>
		<title>86:Ports:07</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:07"/>
				<updated>2021-09-20T07:15:51Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;07 - Link Link == Synopsis == '''Port Number:''' 07h  '''Function:''' Link Port  This port controls the calculat...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|07 - Link]] [[Category:86:Ports:By_Name|Link]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 07h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Link Port&lt;br /&gt;
&lt;br /&gt;
This port controls the calculator's serial link port. It is a GPIO port that is wired to open-collector drivers connected to the jack's tip &amp;amp; ring, with the sleeve connected to ground.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0: Tip (red wire) state.&lt;br /&gt;
* Bit 1: Ring (white wire) state.&lt;br /&gt;
* Bit 2-3: Reads last value written.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: Unused if bit 4 is 0. Should be set to 0 if bits 2 &amp;amp; 4 are both set to 1.&lt;br /&gt;
* Bit 1: Unused if bit 5 is 0. Should be set to 0 if bits 3 &amp;amp; 5 are both set to 1.&lt;br /&gt;
* Bit 2: Set 0 to let other device control the tip. Set 1 to pull the tip voltage low.&lt;br /&gt;
* Bit 3: Set 0 to let other device control the ring. Set 1 to pull the ring voltage low.&lt;br /&gt;
* Bit 4: Set 0 to configure bit 0 for input. Set 1 to configure bit 0 for output. This is always set to the same value as bit 2 by the OS, but always 0 has the same effect.&lt;br /&gt;
* Bit 5: Set 0 to configure bit 1 for input. Set 1 to configure bit 1 for output. This is always set to the same value as bit 3 by the OS, but always 0 has the same effect.&lt;br /&gt;
* Bit 6-7: Controls direction for bits 2-3. Should always be set to 1 (output).&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* Be sure to set this port to C0h before using OS functions that check the link (including getKey) &amp;amp; before returning to the OS, or it will be confused by what it sees as a silent link attempt.&lt;br /&gt;
* While the TI-86 uses 5 V as its high level, linking with suitably-designed 3.3 V open-collector circuitry (such as in TI's 68K-based calculators) also works.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:03</id>
		<title>86:Ports:03</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:03"/>
				<updated>2021-09-20T06:24:11Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Typo in category link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|03 - Interrupt Control]] [[Category:86:Ports:By_Name|Interrupt Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 03h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Interrupt Control Port&lt;br /&gt;
&lt;br /&gt;
This port controls all devices that can generate interrupts.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0: Set if the ON key generated an interrupt.&lt;br /&gt;
* Bit 1: Set if the LCD controller generated an interrupt (after DMA for rows 17 &amp;amp; 49). Used by the OS as a periodic interrupt source (approximately 200 Hz).&lt;br /&gt;
* Bit 2: Set if the /INT pin generated an interrupt (unused on the TI-86).&lt;br /&gt;
* Bit 3: Reset if the ON key is being pressed; set otherwise.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: Set 0 to disable ON key interrupts and to acknowledge an ON key interrupt. Set 1 to enable ON key interrupts.&lt;br /&gt;
* Bit 1: Set 0 to disable LCD controller interrupts &amp;amp; to acknowledge an interrupt from the LCD controller. Set 1 to enable interrupts from the first timer.&lt;br /&gt;
* Bit 2: Set 0 to disable external interrupts &amp;amp; to acknowledge an external interrupt. Set 1 to enable external interrupts.&lt;br /&gt;
* Bit 3: Set 0 to turn off the LCD. Set 1 to turn on the LCD.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* You need to acknowledge interrupts. Otherwise a new interrupt will be generated directly after you enable interrupts again with EI. Because that disables that particular interrupt at the same time, you may have to write a second value to this port to re-enable it.&lt;br /&gt;
* The OS shuts down by turning off the LCD &amp;amp; HALTing with the ON key interrupt enabled.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Ports:03</id>
		<title>86:Ports:03</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Ports:03"/>
				<updated>2021-09-20T06:23:06Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Based on 83Plus:Ports:03&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:86:Ports:By_Address|06 - Interrupt Control]] [[Category:86:Ports:By_Name|Interrupt Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 03h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Interrupt Control Port&lt;br /&gt;
&lt;br /&gt;
This port controls all devices that can generate interrupts.&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0: Set if the ON key generated an interrupt.&lt;br /&gt;
* Bit 1: Set if the LCD controller generated an interrupt (after DMA for rows 17 &amp;amp; 49). Used by the OS as a periodic interrupt source (approximately 200 Hz).&lt;br /&gt;
* Bit 2: Set if the /INT pin generated an interrupt (unused on the TI-86).&lt;br /&gt;
* Bit 3: Reset if the ON key is being pressed; set otherwise.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* Bit 0: Set 0 to disable ON key interrupts and to acknowledge an ON key interrupt. Set 1 to enable ON key interrupts.&lt;br /&gt;
* Bit 1: Set 0 to disable LCD controller interrupts &amp;amp; to acknowledge an interrupt from the LCD controller. Set 1 to enable interrupts from the first timer.&lt;br /&gt;
* Bit 2: Set 0 to disable external interrupts &amp;amp; to acknowledge an external interrupt. Set 1 to enable external interrupts.&lt;br /&gt;
* Bit 3: Set 0 to turn off the LCD. Set 1 to turn on the LCD.&lt;br /&gt;
* Bit 4-7: Unused.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
* You need to acknowledge interrupts. Otherwise a new interrupt will be generated directly after you enable interrupts again with EI. Because that disables that particular interrupt at the same time, you may have to write a second value to this port to re-enable it.&lt;br /&gt;
* The OS shuts down by turning off the LCD &amp;amp; HALTing with the ON key interrupt enabled.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:E000</id>
		<title>84PCE:Ports:E000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:E000"/>
				<updated>2021-05-06T19:59:38Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Added divisor latch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|E000 - ARM Coprocessor]] [[Category:84PCE:Ports:By_Name|ARM Coprocessor]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' E000-EFFF&lt;br /&gt;
&lt;br /&gt;
'''Memory-mapped Address:''' F90000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' ARM Coprocessor&lt;br /&gt;
&lt;br /&gt;
This appears to be an FTUART010 (which is 16550A-compatible), &amp;amp; is connected to the ARM coprocessor on Python Edition. The 16550 register layout (see [https://www.lammertbies.nl/comm/info/serial-uart], for example) works after multiplying its offsets by 4.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Direction&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|E000&lt;br /&gt;
|Read&lt;br /&gt;
Write&lt;br /&gt;
&lt;br /&gt;
Read Write&lt;br /&gt;
|Receive Holding Register (when bit 7 of E00C is 0)&lt;br /&gt;
Transmit Holding Register (when bit 7 of E00C is 0)&lt;br /&gt;
&lt;br /&gt;
Divisor Latch LSB (when bit 7 of E00C is 1)&lt;br /&gt;
|-&lt;br /&gt;
|E004&lt;br /&gt;
|Read Write&lt;br /&gt;
Read Write&lt;br /&gt;
|Interrupt Enable Register (when bit 7 of E00C is 0)&lt;br /&gt;
Divisor Latch MSB (when bit 7 of E00C is 1)&lt;br /&gt;
|-&lt;br /&gt;
|E008&lt;br /&gt;
|Read&lt;br /&gt;
Write&lt;br /&gt;
|Interupt Status Register&lt;br /&gt;
FIFO Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E00C&lt;br /&gt;
|Read Write&lt;br /&gt;
|Line Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E010&lt;br /&gt;
|Read Write&lt;br /&gt;
|Modem Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E014&lt;br /&gt;
|Read&lt;br /&gt;
|Line Status Register&lt;br /&gt;
|-&lt;br /&gt;
|E018&lt;br /&gt;
|Read&lt;br /&gt;
|Modem Status Register&lt;br /&gt;
|-&lt;br /&gt;
|E01C&lt;br /&gt;
|Read Write&lt;br /&gt;
|Scratchpad Register&lt;br /&gt;
|-&lt;br /&gt;
|E068&lt;br /&gt;
|Read&lt;br /&gt;
|01? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|E06C&lt;br /&gt;
|Read&lt;br /&gt;
|01? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|E070&lt;br /&gt;
|Read&lt;br /&gt;
|10? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:E000</id>
		<title>84PCE:Ports:E000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:E000"/>
				<updated>2021-05-06T00:35:46Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated based on FTUART010&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|E000 - ARM Coprocessor]] [[Category:84PCE:Ports:By_Name|ARM Coprocessor]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' E000-EFFF&lt;br /&gt;
&lt;br /&gt;
'''Memory-mapped Address:''' F90000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' ARM Coprocessor&lt;br /&gt;
&lt;br /&gt;
This appears to be an FTUART010 (which is 16550A-compatible), &amp;amp; is connected to the ARM coprocessor on Python Edition. The 16550 register layout (see [https://www.lammertbies.nl/comm/info/serial-uart], for example) works after multiplying its offsets by 4.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Direction&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|E000&lt;br /&gt;
|Read&lt;br /&gt;
Write&lt;br /&gt;
|Receive Holding Register&lt;br /&gt;
Transmit Holding Register&lt;br /&gt;
|-&lt;br /&gt;
|E004&lt;br /&gt;
|Read Write&lt;br /&gt;
|Interrupt Enable Register&lt;br /&gt;
|-&lt;br /&gt;
|E008&lt;br /&gt;
|Read&lt;br /&gt;
Write&lt;br /&gt;
|Interupt Status Register&lt;br /&gt;
FIFO Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E00C&lt;br /&gt;
|Read Write&lt;br /&gt;
|Line Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E010&lt;br /&gt;
|Read Write&lt;br /&gt;
|Modem Control Register&lt;br /&gt;
|-&lt;br /&gt;
|E014&lt;br /&gt;
|Read&lt;br /&gt;
|Line Status Register&lt;br /&gt;
|-&lt;br /&gt;
|E018&lt;br /&gt;
|Read&lt;br /&gt;
|Modem Status Register&lt;br /&gt;
|-&lt;br /&gt;
|E01C&lt;br /&gt;
|Read Write&lt;br /&gt;
|Scratchpad Register&lt;br /&gt;
|-&lt;br /&gt;
|E068&lt;br /&gt;
|Read&lt;br /&gt;
|01? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|E06C&lt;br /&gt;
|Read&lt;br /&gt;
|01? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|E070&lt;br /&gt;
|Read&lt;br /&gt;
|10? (not from 16550)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-02-23T06:51:28Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Detailed timing for LCD controller&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least I+).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz.&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
1&lt;br /&gt;
|1&lt;br /&gt;
&lt;br /&gt;
20-21/22&lt;br /&gt;
&lt;br /&gt;
15/13&lt;br /&gt;
&lt;br /&gt;
11&lt;br /&gt;
&lt;br /&gt;
9&lt;br /&gt;
&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
15-16/13&lt;br /&gt;
&lt;br /&gt;
12/10&lt;br /&gt;
&lt;br /&gt;
10/8&lt;br /&gt;
&lt;br /&gt;
8&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
&lt;br /&gt;
Special timing for 4000-400F &amp;amp; 4018-401B (pre-M/M+) at 48 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz&lt;br /&gt;
&lt;br /&gt;
Special timing for 4200-43FF (any CPU speed)&lt;br /&gt;
&lt;br /&gt;
Special timing for 4C00-4DFF (pre-M/M+) at 48 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 24 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 12 MHz&lt;br /&gt;
&lt;br /&gt;
Same at 6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-02-21T08:28:12Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: F000 mirroring&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least I+).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 24Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 12Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 6Mhz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0005</id>
		<title>84PCE:Ports:0005</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0005"/>
				<updated>2021-02-21T07:57:44Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: (Mostly) not unknown&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0005 - Port access controls]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0005&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Controls access to ports &amp;amp; the backlight PWM.&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port enables access to various parts of the ASIC.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Enables access to [[84PCE:Ports:F000|F000]] port range.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
Enables access to [[84PCE:Ports:E000|E000]] port range (ARM coprocessor).&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Enables access to [[84PCE:Ports:D000|D000]] port range (LCD SPI).&lt;br /&gt;
&lt;br /&gt;
=== Bit [3] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
Enables access to [[84PCE:Ports:B000_Unknowns|B000]] port range (backlight).&lt;br /&gt;
&lt;br /&gt;
=== Bit [5] ===&lt;br /&gt;
Enables writes to [[84PCE:Ports:A000|A000]] port range (keypad). When disabled, read access still succeeds.&lt;br /&gt;
&lt;br /&gt;
=== Bit [6] ===&lt;br /&gt;
Enables the backlight PWM. When disabled, the screen will be fully dark or bright, depending on which part of the PWM cycle it was in when last enabled.&lt;br /&gt;
&lt;br /&gt;
=== Bit [7] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006</id>
		<title>84PCE:Ports:0006</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006"/>
				<updated>2021-02-21T05:52:52Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated effect of bits 0 &amp;amp; 1 on port access (oops)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0006 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0006&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port seems to affect the display refresh.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Latches value written, OS defaults this to set. Resetting this bit reduces current consumption by about 3 mA, so it does ''something.'' When reset, the [[84PCE:Ports:3000|USB controller ports]] cannot be accessed.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
Reset this bit to disable display upadates. When reset, the [[84PCE:Ports:4000|LCD controller ports]] also cannot be accessed.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Set this bit to enable display updates if bit 1 is ever reset. ???&lt;br /&gt;
&lt;br /&gt;
This bit is known to unlock protected ports, such as [[84PCE:Ports:2000|SHA256]],&lt;br /&gt;
and enables the [[84PCE:Ports:0028#Bit_.5B3.5D|flash unlock sequence]].&lt;br /&gt;
It is cleared every time the boot code interrupt handler runs.&lt;br /&gt;
&lt;br /&gt;
=== Bit [3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;br /&gt;
&lt;br /&gt;
Used by OS on Python Edition.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
&amp;lt;s&amp;gt;Flash lock status.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006</id>
		<title>84PCE:Ports:0006</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006"/>
				<updated>2021-02-21T05:40:01Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated effect of bits 0 &amp;amp; 1 on port access&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0006 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0006&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port seems to affect the display refresh.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Latches value written, OS defaults this to set. Resetting this bit reduces current consumption by about 3 mA, so it does ''something.'' When reset, the [[84PCE:Ports:3000|USB controller ports]] cannot be written &amp;amp; read as 20 0E 3E 00, repeating every 4 bytes.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
Reset this bit to disable display upadates. When reset, the [[84PCE:Ports:4000|LCD controller ports]] cannot be written &amp;amp; read as B1 00 00 00 (revision C) or 2D 09 00 00 (revision N), repeating every 4 bytes.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Set this bit to enable display updates if bit 1 is ever reset. ???&lt;br /&gt;
&lt;br /&gt;
This bit is known to unlock protected ports, such as [[84PCE:Ports:2000|SHA256]],&lt;br /&gt;
and enables the [[84PCE:Ports:0028#Bit_.5B3.5D|flash unlock sequence]].&lt;br /&gt;
It is cleared every time the boot code interrupt handler runs.&lt;br /&gt;
&lt;br /&gt;
=== Bit [3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;br /&gt;
&lt;br /&gt;
Used by OS on Python Edition.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
&amp;lt;s&amp;gt;Flash lock status.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2021-02-21T05:25:58Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated port 000D&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address. It is mirrored every 0x100 bytes.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Power control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000D</id>
		<title>84PCE:Ports:000D</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000D"/>
				<updated>2021-02-21T05:23:23Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Created page with &amp;quot;000D - Power control == Synopsis == '''Port Number:''' 000D  '''Function:''' Power control  == Details ==  This port enables power to vario...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|000D - Power control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 000D&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Power control&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port enables power to various parts of the ASIC. Each region reads as 0 when unpowered.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
[[84PCE:Ports:3000|USB controller]] power. Resets when unpowered. Returning to the OS without reinitializing causes it to freeze while USB is connected.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
[[84PCE:Ports:4000|LCD controller]] power. Resets when unpowered. The LCD does not update until the controller is initialized properly.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Power for RAM range D20000-D3FFFF. When unpowered, its content is quickly randomized.&lt;br /&gt;
&lt;br /&gt;
=== Bit [3] ===&lt;br /&gt;
Power for VRAM range D40000-D7FFFF. When unpowered, its content is quickly randomized.&lt;br /&gt;
&lt;br /&gt;
=== Bits [4:7] ===&lt;br /&gt;
Writes have no effect. These bits read as 1 if the subsystems controlled by the corresponding bits in 0-3 are receiving power. There is a slight delay between changing bits 0-3 &amp;amp; these changing in response.&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-02-07T00:59:01Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: VRAM mirroring in unmapped space updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least I+).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 24Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 12Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 6Mhz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address</id>
		<title>Category:84PCE:RAM:By Address</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address"/>
				<updated>2021-02-07T00:58:01Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: (VRAM mirroring in unmapped space updated)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also [[:Category:84PCE:RAM:By Name|list of RAM areas by name]].&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;br /&gt;
&lt;br /&gt;
The eZ80 has a 24-bit linear address space. Layout:&lt;br /&gt;
* 000000h: Start of flash. The first 128 K are locked boot sectors. The first 8 are divided into 8 K sectors, all of which are locked. The certificate is now a single 64 K sector, so I hope you don't crash while rebuilding it.&lt;br /&gt;
* 000066h: Flash exception handler. Write-to-flash without permission triggers the non-maskable interrupt to fire.&lt;br /&gt;
* 00007Eh: Hardware/Emu flag: This byte indicates whether the ROM is a hardware ROM or emulator.&lt;br /&gt;
* 000080h: Start of boot code jump table.&lt;br /&gt;
* 020000h: Start of OS.&lt;br /&gt;
* 0C0000h: Start of user archive.&lt;br /&gt;
* 3B0000h: Certificate.&lt;br /&gt;
* 3C0000h: Temp RAM backup, on newer versions of TIOS debug output is also written here.&lt;br /&gt;
* 3E0000h: Temp RAM backup.&lt;br /&gt;
* 3F0000h: Temp RAM backup, temp certificate backup, swap sector.&lt;br /&gt;
* 400000h: Can be setup to mirror flash, but usually unmapped.&lt;br /&gt;
* 800000h: Always unmapped.&lt;br /&gt;
* D00000h: Start of RAM. 256 K.&lt;br /&gt;
* D1A87Eh: Top of the SPL stack.&lt;br /&gt;
* D1A881h: Start of UserMem.&lt;br /&gt;
* D40000h: Start of VRAM. 320x240x2 bytes = 153600 bytes.&lt;br /&gt;
* D65800h: Unmapped memory.&lt;br /&gt;
* D72C00h: Unmapped memory (revisions up to at least C) or mirror of D52C00h (at least I+).&lt;br /&gt;
* D80000h: Mirror of D00000h.&lt;br /&gt;
* E00000h: Start of [[84PCE:Wait_States|memory-mapped I/O]] address spaces.&lt;br /&gt;
&lt;br /&gt;
SafeRAM Areas:&lt;br /&gt;
* D031F6h: [[84PCE:RAM:D031F6|pixelShadow]] - 8400 bytes&lt;br /&gt;
* D052C6h: [[84PCE:RAM:D052C6|pixelShadow2]] - 8400 bytes&lt;br /&gt;
* D07396h: [[84PCE:RAM:D07396|cmdPixelShadow]] - 8400 bytes&lt;br /&gt;
* D09466h: [[84PCE:RAM:D09466|plotSScreen]] - 21945 bytes&lt;br /&gt;
* D0EA1Fh: [[84PCE:RAM:D0EA1F|saveSScreen]] - 21945 bytes&lt;br /&gt;
** Note that the above is contiguous, which provides a total linear free space of 69090 bytes of RAM.&lt;br /&gt;
** [[84PCE:RAM:D052C6|pixelShadow2]] is the most stable; and is a viable option for ''testing'' TSRs and hooks.&lt;br /&gt;
&lt;br /&gt;
More SafeRAM Areas:&lt;br /&gt;
* D006C0h: [[84PCE:RAM:D006C0|textShadow]] - 260 bytes&lt;br /&gt;
* D0232Dh: [[84PCE:RAM:D0232D|cmdShadow]] - 260 bytes&lt;br /&gt;
&lt;br /&gt;
Also, if you do not wish to use the LCD cursor (This is not RAM, but can be used as scrap)&lt;br /&gt;
* E30800h: cursorImage - 1024 bytes&lt;br /&gt;
[[Category:84PCE:RAM|RAM Areas by Address]]&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-01-28T17:03:03Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: VRAM mirroring in unmapped space updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least L+).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 24Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 12Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 6Mhz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address</id>
		<title>Category:84PCE:RAM:By Address</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address"/>
				<updated>2021-01-28T17:03:02Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: VRAM mirroring in unmapped space updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also [[:Category:84PCE:RAM:By Name|list of RAM areas by name]].&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;br /&gt;
&lt;br /&gt;
The eZ80 has a 24-bit linear address space. Layout:&lt;br /&gt;
* 000000h: Start of flash. The first 128 K are locked boot sectors. The first 8 are divided into 8 K sectors, all of which are locked. The certificate is now a single 64 K sector, so I hope you don't crash while rebuilding it.&lt;br /&gt;
* 000066h: Flash exception handler. Write-to-flash without permission triggers the non-maskable interrupt to fire.&lt;br /&gt;
* 00007Eh: Hardware/Emu flag: This byte indicates whether the ROM is a hardware ROM or emulator.&lt;br /&gt;
* 000080h: Start of boot code jump table.&lt;br /&gt;
* 020000h: Start of OS.&lt;br /&gt;
* 0C0000h: Start of user archive.&lt;br /&gt;
* 3B0000h: Certificate.&lt;br /&gt;
* 3C0000h: Temp RAM backup, on newer versions of TIOS debug output is also written here.&lt;br /&gt;
* 3E0000h: Temp RAM backup.&lt;br /&gt;
* 3F0000h: Temp RAM backup, temp certificate backup, swap sector.&lt;br /&gt;
* 400000h: Can be setup to mirror flash, but usually unmapped.&lt;br /&gt;
* 800000h: Always unmapped.&lt;br /&gt;
* D00000h: Start of RAM. 256 K.&lt;br /&gt;
* D1A87Eh: Top of the SPL stack.&lt;br /&gt;
* D1A881h: Start of UserMem.&lt;br /&gt;
* D40000h: Start of VRAM. 320x240x2 bytes = 153600 bytes.&lt;br /&gt;
* D65800h: Unmapped memory.&lt;br /&gt;
* D72C00h: Unmapped memory (revisions up to at least C) or mirror of D52C00h (at least L+).&lt;br /&gt;
* D80000h: Mirror of D00000h.&lt;br /&gt;
* E00000h: Start of [[84PCE:Wait_States|memory-mapped I/O]] address spaces.&lt;br /&gt;
&lt;br /&gt;
SafeRAM Areas:&lt;br /&gt;
* D031F6h: [[84PCE:RAM:D031F6|pixelShadow]] - 8400 bytes&lt;br /&gt;
* D052C6h: [[84PCE:RAM:D052C6|pixelShadow2]] - 8400 bytes&lt;br /&gt;
* D07396h: [[84PCE:RAM:D07396|cmdPixelShadow]] - 8400 bytes&lt;br /&gt;
* D09466h: [[84PCE:RAM:D09466|plotSScreen]] - 21945 bytes&lt;br /&gt;
* D0EA1Fh: [[84PCE:RAM:D0EA1F|saveSScreen]] - 21945 bytes&lt;br /&gt;
** Note that the above is contiguous, which provides a total linear free space of 69090 bytes of RAM.&lt;br /&gt;
** [[84PCE:RAM:D052C6|pixelShadow2]] is the most stable; and is a viable option for ''testing'' TSRs and hooks.&lt;br /&gt;
&lt;br /&gt;
More SafeRAM Areas:&lt;br /&gt;
* D006C0h: [[84PCE:RAM:D006C0|textShadow]] - 260 bytes&lt;br /&gt;
* D0232Dh: [[84PCE:RAM:D0232D|cmdShadow]] - 260 bytes&lt;br /&gt;
&lt;br /&gt;
Also, if you do not wish to use the LCD cursor (This is not RAM, but can be used as scrap)&lt;br /&gt;
* E30800h: cursorImage - 1024 bytes&lt;br /&gt;
[[Category:84PCE:RAM|RAM Areas by Address]]&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address</id>
		<title>Category:84PCE:RAM:By Address</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Category:84PCE:RAM:By_Address"/>
				<updated>2021-01-28T07:14:17Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: VRAM mirroring in unmapped address space on L-N&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also [[:Category:84PCE:RAM:By Name|list of RAM areas by name]].&lt;br /&gt;
&lt;br /&gt;
Please read our page on [[Contributing]] before editing these pages!&lt;br /&gt;
&lt;br /&gt;
The eZ80 has a 24-bit linear address space. Layout:&lt;br /&gt;
* 000000h: Start of flash. The first 128 K are locked boot sectors. The first 8 are divided into 8 K sectors, all of which are locked. The certificate is now a single 64 K sector, so I hope you don't crash while rebuilding it.&lt;br /&gt;
* 000066h: Flash exception handler. Write-to-flash without permission triggers the non-maskable interrupt to fire.&lt;br /&gt;
* 00007Eh: Hardware/Emu flag: This byte indicates whether the ROM is a hardware ROM or emulator.&lt;br /&gt;
* 000080h: Start of boot code jump table.&lt;br /&gt;
* 020000h: Start of OS.&lt;br /&gt;
* 0C0000h: Start of user archive.&lt;br /&gt;
* 3B0000h: Certificate.&lt;br /&gt;
* 3C0000h: Temp RAM backup, on newer versions of TIOS debug output is also written here.&lt;br /&gt;
* 3E0000h: Temp RAM backup.&lt;br /&gt;
* 3F0000h: Temp RAM backup, temp certificate backup, swap sector.&lt;br /&gt;
* 400000h: Can be setup to mirror flash, but usually unmapped.&lt;br /&gt;
* 800000h: Always unmapped.&lt;br /&gt;
* D00000h: Start of RAM. 256 K.&lt;br /&gt;
* D1A87Eh: Top of the SPL stack.&lt;br /&gt;
* D1A881h: Start of UserMem.&lt;br /&gt;
* D40000h: Start of VRAM. 320x240x2 bytes = 153600 bytes.&lt;br /&gt;
* D65800h: Unmapped memory.&lt;br /&gt;
* D72C00h: Unmapped memory (revisions up to at least C) or mirror of D52C00h (at least L through N).&lt;br /&gt;
* D80000h: Mirror of D00000h.&lt;br /&gt;
* E00000h: Start of [[84PCE:Wait_States|memory-mapped I/O]] address spaces.&lt;br /&gt;
&lt;br /&gt;
SafeRAM Areas:&lt;br /&gt;
* D031F6h: [[84PCE:RAM:D031F6|pixelShadow]] - 8400 bytes&lt;br /&gt;
* D052C6h: [[84PCE:RAM:D052C6|pixelShadow2]] - 8400 bytes&lt;br /&gt;
* D07396h: [[84PCE:RAM:D07396|cmdPixelShadow]] - 8400 bytes&lt;br /&gt;
* D09466h: [[84PCE:RAM:D09466|plotSScreen]] - 21945 bytes&lt;br /&gt;
* D0EA1Fh: [[84PCE:RAM:D0EA1F|saveSScreen]] - 21945 bytes&lt;br /&gt;
** Note that the above is contiguous, which provides a total linear free space of 69090 bytes of RAM.&lt;br /&gt;
** [[84PCE:RAM:D052C6|pixelShadow2]] is the most stable; and is a viable option for ''testing'' TSRs and hooks.&lt;br /&gt;
&lt;br /&gt;
More SafeRAM Areas:&lt;br /&gt;
* D006C0h: [[84PCE:RAM:D006C0|textShadow]] - 260 bytes&lt;br /&gt;
* D0232Dh: [[84PCE:RAM:D0232D|cmdShadow]] - 260 bytes&lt;br /&gt;
&lt;br /&gt;
Also, if you do not wish to use the LCD cursor (This is not RAM, but can be used as scrap)&lt;br /&gt;
* E30800h: cursorImage - 1024 bytes&lt;br /&gt;
[[Category:84PCE:RAM|RAM Areas by Address]]&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States</id>
		<title>84PCE:Wait States</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Wait_States"/>
				<updated>2021-01-28T07:10:55Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: VRAM mirroring in unmapped address space on L-N&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:General_Hardware_Information|Wait States]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
The eZ80 processor is able to perform a memory access in a single cycle. However, on the TI-84+CE, accesses will actually take longer due to wait states. For example, a read from RAM will take 4 cycles, because it has 3 wait states. The wait states for parallel Flash accesses can be customized, but it is unknown whether that is the case for other memory regions or for the newer serial flash.&lt;br /&gt;
&lt;br /&gt;
== Flash Access Wait States ==&lt;br /&gt;
&lt;br /&gt;
=== Parallel Flash ===&lt;br /&gt;
Calculators produced prior to revision M use a parallel flash chip. These chips are limited to a maximum read rate under 20 MHz, necessitating at least 1 wait state for the ASIC's faster 48 MHz clock. The ASIC's internal memory mapping hardware adds a minimum of 5 wait states just to ferry the request to the flash chip and the response back to the CPU, but additional external wait states are required for the flash chip to make its reply. See [[84PCE:Ports:1005]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Serial Flash ===&lt;br /&gt;
Calculators produced starting in 2019 with revision M no longer use a parallel flash chip, but instead an SPI flash chip. This flash chip needs much longer to initially retrieve data from a random address, but can stream sequential data at a reasonable rate. A new ASIC design takes advantage of this capability by adding a cache between the flash chip and CPU.&lt;br /&gt;
&lt;br /&gt;
According to tests performed by [[User:Jacobly|Jacobly]], the cache is 8&amp;amp;nbsp;K in size, structured as a 2-way set associative cache with 128 sets of 32 bytes chosen by address bits 5-11. A fetch from the same cache line as previously accessed costs 1 wait state (so the read takes a total of 2 cycles), a fetch from a different cache line costs 2 wait states, and a cache miss costs 194-200 wait states.&lt;br /&gt;
&lt;br /&gt;
Code execution from flash displays high locality of reference, so amortized performance should be reasonably good, although the 200 cycle penalty for a cache miss probably hurts a fair bit. For flash-resident data files, programmers should try to organize them to keep related data together to maximize cache utilization. A good access pattern can make accessing data in flash twice as fast as getting it from RAM, while a bad pattern can make it substantially worse than even pulling it from the old parallel flash.&lt;br /&gt;
&lt;br /&gt;
== LCD DMA ==&lt;br /&gt;
The LCD controller uses Direct Memory Access to retrieve the pixels from RAM. However, since the CPU and the LCD controller cannot access RAM at the same time, there are some waitstates caused asynchronously by the DMA during RAM accesses. The rate of waitstates caused by the DMA appears to be directly proportional to the rate of data being sent to the screen, so lower bit-per-pixel modes will reduce the general performance hit.&lt;br /&gt;
&lt;br /&gt;
== Wait State Layout ==&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Address Range&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Read&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Write&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|5+&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:Ports:1000|Parallel flash]]: Wait states are controlled by [[:84PCE:Ports:1005|1005]], adding to the minimum of 5. The OS sets a total of 9 wait states.&lt;br /&gt;
|-&lt;br /&gt;
|000000-3FFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|[[84PCE:OS:Serial_Flash_Commands|Serial flash:]] See above discussion.&lt;br /&gt;
|-&lt;br /&gt;
|400000-7FFFFF&lt;br /&gt;
|257&lt;br /&gt;
|Crash&lt;br /&gt;
|Parallel flash: Unmapped address space. Can be mapped to Flash using [[:84PCE:Ports:1002|1002]], after which Flash wait states are active.&lt;br /&gt;
|-&lt;br /&gt;
|400000-BFFFFF&lt;br /&gt;
|1-200&lt;br /&gt;
|Crash&lt;br /&gt;
|Serial flash: Flash mirrors. Appears to be subject to flash cache timing as discussed above&lt;br /&gt;
|-&lt;br /&gt;
|800000-CFFFFF&lt;br /&gt;
|257&lt;br /&gt;
|257&lt;br /&gt;
|Parallel flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|C00000-CFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Serial flash: Unmapped address space.&lt;br /&gt;
|-&lt;br /&gt;
|D00000-D3FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|RAM&lt;br /&gt;
|-&lt;br /&gt;
|D40000-D657FF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|VRAM&lt;br /&gt;
|-&lt;br /&gt;
|D65800-D72BFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage.&lt;br /&gt;
|-&lt;br /&gt;
|D72C00-D7FFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped address space. Reads garbage (revisions up to at least C) or mirror of D52C00-D5FFFF (at least revisions L through N).&lt;br /&gt;
|-&lt;br /&gt;
|D80000-DFFFFF&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Mirror of D00000-D7FFFF&lt;br /&gt;
|-&lt;br /&gt;
|Not mapped&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Port range [[:84PCE:Ports:0000|0000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E00000-E0FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:1000|1000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E10000-E1FFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:2000|2000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E20000-E2FFFF&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|3&lt;br /&gt;
&lt;br /&gt;
9-12&lt;br /&gt;
&lt;br /&gt;
6-8&lt;br /&gt;
&lt;br /&gt;
5-6&lt;br /&gt;
&lt;br /&gt;
4-5&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:3000|3000]] (mirrored every 0200 bytes)&lt;br /&gt;
&lt;br /&gt;
Extra cycles if bit 7 ''or'' 8 of the address is set, when cpu is running at 48Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 24Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 12Mhz.&lt;br /&gt;
&lt;br /&gt;
Same at 6Mhz.&lt;br /&gt;
|-&lt;br /&gt;
|E30000-E3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:4000|4000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|E40000-EFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|F00000-F0FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:5000|5000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F10000-F1FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:6000|6000]] (mirrored every 0020 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F20000-F2FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:7000|7000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F30000-F3FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:8000|8000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F40000-F4FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:9000|9000]] (mirrored every 1000 bytes, possibly protected port range)&lt;br /&gt;
|-&lt;br /&gt;
|F50000-F5FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:A000|A000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F60000-F6FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:B000|B000]] (mirrored every 1000 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F70000-F7FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:C000|C000]] (mirrored every 0100 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F80000-F8FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:D000|D000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|F90000-F9FFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:E000|E000]] (mirrored every 0080 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|FA0000-FAFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Memory-mapped port range [[:84PCE:Ports:F000|F000]] (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FB0000-FEFFFF&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-&lt;br /&gt;
|FF0000-FFFFFF&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Unmapped port range (reads all zeros)&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:D000</id>
		<title>84PCE:Ports:D000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:D000"/>
				<updated>2020-04-08T21:07:05Z</updated>
		
		<summary type="html">&lt;p&gt;Zeroko: Updated based on FTSSP010 driver for Linux&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|D000 - SPI]] [[Category:84PCE:Ports:By_Name|SPI]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' D000&lt;br /&gt;
&lt;br /&gt;
'''Memory-mapped Address:''' F80000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' LCD Interface&lt;br /&gt;
&lt;br /&gt;
This appears to be an FTSSP010 or compatible SPI controller that interfaces with the LCD.  Non-extended commands from [https://cdn-shop.adafruit.com/datasheets/ILI9340.pdf] appear to work, but there's plenty of unknown commands used by the boot code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|D000&amp;lt;br/&amp;gt;F80000&lt;br /&gt;
|&lt;br /&gt;
|0000F38C&lt;br /&gt;
|CR0: Boot code writes 180B/09 before/after turning on/off the lcd.&lt;br /&gt;
|-&lt;br /&gt;
|D004&amp;lt;br/&amp;gt;F80004&lt;br /&gt;
|0000182B&lt;br /&gt;
|007FFFFF&lt;br /&gt;
|CR1: Boot code initializes to 02000B. Bits 0-15 are clock divider - 1, bits 16-23 are data length - 1, and bits 24-31 are padding length.&lt;br /&gt;
|-&lt;br /&gt;
|D008&amp;lt;br/&amp;gt;F80008&lt;br /&gt;
|0002000B&lt;br /&gt;
|00000F8F&lt;br /&gt;
|CR2: Boot code initializes to 010C.&amp;lt;br/&amp;gt;Bit 0 is set to transfer data.&amp;lt;br/&amp;gt;Bit 7 is set/reset for reading/writing.&lt;br /&gt;
|-&lt;br /&gt;
|D00C&amp;lt;br/&amp;gt;F8000C&lt;br /&gt;
|&lt;br /&gt;
|000007F6&lt;br /&gt;
|Status bits.&amp;lt;br/&amp;gt;Bit 2 is set if data is being sent or received and bits 12-15 are the number of bits queued.&amp;lt;br/&amp;gt;Boot code waits for bits 2 and 12-15 to be 0 before/after reading/writing.&lt;br /&gt;
|-&lt;br /&gt;
|D010&amp;lt;br/&amp;gt;F80010&lt;br /&gt;
|00002100&lt;br /&gt;
|&lt;br /&gt;
|Interrupt control.&lt;br /&gt;
|-&lt;br /&gt;
|D014&amp;lt;br/&amp;gt;F80014&lt;br /&gt;
|00000008&lt;br /&gt;
|&lt;br /&gt;
|Interrupt status.&lt;br /&gt;
|-&lt;br /&gt;
|D018&amp;lt;br/&amp;gt;F80018&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FIFO in/out.&lt;br /&gt;
|-&lt;br /&gt;
|D01C&amp;lt;br/&amp;gt;F8001C&lt;br /&gt;
|0E0F0F1F&lt;br /&gt;
|&lt;br /&gt;
|Inside reserved range. Appears to be a copy of the feature register at D064.&lt;br /&gt;
|-&lt;br /&gt;
|D060&amp;lt;br/&amp;gt;F80060&lt;br /&gt;
|00012100&lt;br /&gt;
|&lt;br /&gt;
|Revision (read-only)&lt;br /&gt;
|-&lt;br /&gt;
|D064&amp;lt;br/&amp;gt;F80064&lt;br /&gt;
|0E0F0F1F&lt;br /&gt;
|&lt;br /&gt;
|Features (read-only): 32-bit data width, 16-bit FIFOs, list of extra protocols supported.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Known Commands ==&lt;br /&gt;
{|-&lt;br /&gt;
|Hex&amp;lt;br/&amp;gt;Defaults&lt;br /&gt;
|Command&lt;br /&gt;
|Details&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Software Reset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|10&amp;lt;br/&amp;gt;10&lt;br /&gt;
|Enable Sleep Mode&lt;br /&gt;
|Turns pixels black, low power mode?&lt;br /&gt;
|-&lt;br /&gt;
|11&amp;lt;br/&amp;gt;11&lt;br /&gt;
|Disable Sleep Mode&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Enable Partial Mode&lt;br /&gt;
|Resets vertical scrolling start to 0.&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Disable Partial Mode&lt;br /&gt;
|Also disables vertical scrolling mode and resets vertical scrolling start to 0.&lt;br /&gt;
|-&lt;br /&gt;
|20&lt;br /&gt;
|Uninvert Colors&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|21&lt;br /&gt;
|Invert Colors&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|26 &amp;lt;8:GC&amp;gt;&amp;lt;br/&amp;gt;26 00&amp;lt;br/&amp;gt;26 02&lt;br /&gt;
|Set Gamma&lt;br /&gt;
|Selects between 4 preset gamma curves: Valid values are 1, 2, 4, 8, invalid values appear to use 1.&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Turn Off Display&lt;br /&gt;
|Turns all pixels white.&lt;br /&gt;
|-&lt;br /&gt;
|29&amp;lt;br/&amp;gt;29&lt;br /&gt;
|Turn On Display&lt;br /&gt;
|Restore GRAM pixels.&lt;br /&gt;
|-&lt;br /&gt;
|2A &amp;lt;BE16:StartCol&amp;gt; &amp;lt;BE16:EndCol&amp;gt;&amp;lt;br/&amp;gt;2A 0000 013F&lt;br /&gt;
|Set Window Columns&lt;br /&gt;
|Set the pixel update window from StartCol to EndCol inclusive.&lt;br /&gt;
|-&lt;br /&gt;
|2B &amp;lt;BE16:StartLine&amp;gt; &amp;lt;BE16:EndRow&amp;gt;&amp;lt;br/&amp;gt;2B 0000 00EF&lt;br /&gt;
|Set Window Rows&lt;br /&gt;
|Set the pixel update window from StartRow to EndRow inclusive.&lt;br /&gt;
|-&lt;br /&gt;
|30 &amp;lt;BE16:StartRow&amp;gt; &amp;lt;BE16:EndRow&amp;gt;&lt;br /&gt;
|Set Partial Area Rows&lt;br /&gt;
|Only displays from StartRow to EndRow inclusive, other lines white.&lt;br /&gt;
|-&lt;br /&gt;
|33 &amp;lt;BE16:TopArea&amp;gt; &amp;lt;BE16:ScrollArea&amp;gt; &amp;lt;BE16:BottomArea&amp;gt;&lt;br /&gt;
|Vertical Scrolling Definition&lt;br /&gt;
|TopArea/BottomArea are static (non-scrolling) line counts before and after the ScrollArea whose value is ignored.&lt;br /&gt;
|-&lt;br /&gt;
|36 &amp;lt;8:MAC&amp;gt;&amp;lt;br/&amp;gt;36 08&lt;br /&gt;
|Memory Address Control&lt;br /&gt;
|Bit 2: Horizontal Refresh Order&amp;lt;br/&amp;gt;Bit 3: BGR Order&amp;lt;br/&amp;gt;Bit 4: Vertical Refresh Order&amp;lt;br/&amp;gt;Bit 5: Column Major Update&amp;lt;br/&amp;gt;Bit 6: Column Update Order&amp;lt;br/&amp;gt;Bit 7: Row Update Order&lt;br /&gt;
|-&lt;br /&gt;
|37 &amp;lt;BE16:VSP&amp;gt;&lt;br /&gt;
|Vertical Scrolling Start Position&lt;br /&gt;
|First line of ScrollArea starts at this GRAM line.&lt;br /&gt;
|-&lt;br /&gt;
|38&lt;br /&gt;
|Disable Idle Mode&lt;br /&gt;
|Restore 18bpp mode.&lt;br /&gt;
|-&lt;br /&gt;
|39&lt;br /&gt;
|Enable Idle Mode&lt;br /&gt;
|3bpp 8 color mode (only uses msb of each color component).&lt;br /&gt;
|-&lt;br /&gt;
|3A ?&amp;lt;br/&amp;gt;3A 66&lt;br /&gt;
|Interface Pixel Format&lt;br /&gt;
|Upper and lower nibbles are modes for the two interfaces: 3 is 12bpp, 5 is 16bpp, 6 is 18bpp (msb is ignored, invalid uses 18bpp).&lt;br /&gt;
|-&lt;br /&gt;
|B0 ? ?&amp;lt;br/&amp;gt;B0 11 F0&lt;br /&gt;
|Interface Control&lt;br /&gt;
|First Param:&amp;lt;br/&amp;gt;Bit 0: Use lcd controller clocks instead of internal clocks.&amp;lt;br/&amp;gt;Bit 4: Get GRAM data from lcd controller instead of spi interface.&amp;lt;br/&amp;gt; Bit 7: Bypass GRAM and output directly to lcd.&amp;lt;br/&amp;gt;Second Param:&amp;lt;br/&amp;gt;Polarity of clocks?&lt;br /&gt;
|-&lt;br /&gt;
|B1 ? ? ?&amp;lt;br/&amp;gt;B1 01 05 14&amp;lt;br/&amp;gt;B1 01 15 14&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|B2 ? ? ? ? ?&amp;lt;br/&amp;gt;B2 0C 0C 00 33 33&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|B7 ?&amp;lt;br/&amp;gt;B7 35&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|BB ?&amp;lt;br/&amp;gt;BB 17&amp;lt;br/&amp;gt;BB 1B&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|C0 ?&amp;lt;br/&amp;gt;C0 2C&amp;lt;br/&amp;gt;C0 22&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|C2 ?&amp;lt;br/&amp;gt;C2 01&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|C3 ?&amp;lt;br/&amp;gt;C3 03&amp;lt;br/&amp;gt;C3 15&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|C4 ?&amp;lt;br/&amp;gt;C4 20&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|C6 ?&amp;lt;br/&amp;gt;C6 0F&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|D0 ? ?&amp;lt;br/&amp;gt;D0 AF A1&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|D2 ?&amp;lt;br/&amp;gt;D2 00&lt;br /&gt;
|Unknown?&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|DC&lt;br /&gt;
|Unknown?&lt;br /&gt;
|One parameter &amp;quot;read&amp;quot; and checked if equal to 0x35, but reading doesn't appear to work in the first place...&lt;br /&gt;
|-&lt;br /&gt;
|E0 ? ? ? ? ? ? ? ? ? ? ? ? ? ?&amp;lt;br/&amp;gt;E0 D0 00 00 10 0F 1A 2D 54 3F 3B 18 17 13 17&amp;lt;br/&amp;gt;E0 D0 00 00 10 0F 1A 2D 54 3F 3B 18 17 13 17&lt;br /&gt;
|Positive Gamma Correction&lt;br /&gt;
|Definitely affects gamma, parameters unknown and don't match docs.&lt;br /&gt;
|-&lt;br /&gt;
|E1 ? ? ? ? ? ? ? ? ? ? ? ? ? ?&amp;lt;br/&amp;gt;E1 D0 00 00 10 0F 09 2B 43 40 3B 18 17 13 17&amp;lt;br/&amp;gt;E1 D0 00 00 10 0F 09 2B 43 40 3B 18 17 13 17&lt;br /&gt;
|Negative Gamma Correction&lt;br /&gt;
|Definitely affects gamma, parameters unknown and don't match docs.&lt;br /&gt;
|-&lt;br /&gt;
|E9 ? ? ?&amp;lt;br/&amp;gt;E9 08 08 08&lt;br /&gt;
|Unknown?&lt;br /&gt;
|-&lt;br /&gt;
|EB&lt;br /&gt;
|Something!&lt;br /&gt;
|-&lt;br /&gt;
|F0&lt;br /&gt;
|Gamma?&lt;br /&gt;
|-&lt;br /&gt;
|F1&lt;br /&gt;
|Gamma?&lt;br /&gt;
|-&lt;br /&gt;
|F2&lt;br /&gt;
|Gamma?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; ld a,036h ; Flips the lcd horizontally, vertically, and swaps the b and r components&lt;br /&gt;
 call spiCmd&lt;br /&gt;
 ld a,0C0h&lt;br /&gt;
 call spiParam&lt;br /&gt;
&lt;br /&gt;
 ld a,002h ; Resetting the lcd on exit&lt;br /&gt;
 call spiCmd&lt;br /&gt;
 jp boot_InitializeHardware&lt;br /&gt;
&lt;br /&gt;
; Input: A = parameter&lt;br /&gt;
spiParam:&lt;br /&gt;
 scf ; First bit is set for data&lt;br /&gt;
 .db 030h ; jr nc,? ; skips over one byte&lt;br /&gt;
; Input: A = command&lt;br /&gt;
spiCmd:&lt;br /&gt;
 or a,a ; First bit is clear for commands&lt;br /&gt;
 ld hl,0F80818h&lt;br /&gt;
 call spiWrite&lt;br /&gt;
 ld l,h&lt;br /&gt;
 ld (hl),001h&lt;br /&gt;
spiWait:&lt;br /&gt;
 ld l,00Dh&lt;br /&gt;
spiWait1:&lt;br /&gt;
 ld a,(hl)&lt;br /&gt;
 and a,0F0h&lt;br /&gt;
 jr nz,spiWait1&lt;br /&gt;
 dec l&lt;br /&gt;
spiWait2:&lt;br /&gt;
 bit 2,(hl)&lt;br /&gt;
 jr nz,spiWait2&lt;br /&gt;
 ld l,h&lt;br /&gt;
 ld (hl),a&lt;br /&gt;
 ret&lt;br /&gt;
spiWrite:&lt;br /&gt;
 ld b,3&lt;br /&gt;
spiWriteLoop:&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 ld (hl),a ; send 3 bits&lt;br /&gt;
 djnz spiWriteLoop&lt;br /&gt;
 ret&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
'''This does not appear to work, always returning 0 on the calcs I've tested, due to either a TI bug or hardware issue.'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;; Input: A = command&lt;br /&gt;
; Ouput: A = data&lt;br /&gt;
spiRead:&lt;br /&gt;
 ld hl,0F80808&lt;br /&gt;
 ld (hl),00Ch&lt;br /&gt;
 ld l,018h&lt;br /&gt;
 or a,a&lt;br /&gt;
 call spiWrite&lt;br /&gt;
 xor a,a ; not sure what this is for&lt;br /&gt;
 call spiWrite&lt;br /&gt;
 ld l,009h&lt;br /&gt;
 ld (hl),001h&lt;br /&gt;
 dec l&lt;br /&gt;
 ld (hl),081h&lt;br /&gt;
 call spiWait&lt;br /&gt;
 ld l,$18&lt;br /&gt;
 ld a,(hl) ; dummy read&lt;br /&gt;
 ld a,(hl)&lt;br /&gt;
 ld a,(hl) ; Why is there no wait after dummy read?&lt;br /&gt;
 ld a,(hl)&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 and a,0E0h&lt;br /&gt;
 ld c,a&lt;br /&gt;
 ld a,(hl)&lt;br /&gt;
 rla&lt;br /&gt;
 rla&lt;br /&gt;
 and a,01Ch&lt;br /&gt;
 or a,c&lt;br /&gt;
 ld c,a&lt;br /&gt;
 ld a,(hl)&lt;br /&gt;
 rra ; why are we throwing away the lsb instead of the msb&lt;br /&gt;
 and a,003h&lt;br /&gt;
 or a,c&lt;br /&gt;
 ret&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	</feed>