<?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/index.php?action=history&amp;feed=atom&amp;title=86%3AInterrupts</id>
		<title>86:Interrupts - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://wikiti.brandonw.net/index.php?action=history&amp;feed=atom&amp;title=86%3AInterrupts"/>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;action=history"/>
		<updated>2026-05-06T03:27:25Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.23.5</generator>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11838&amp;oldid=prev</id>
		<title>Zeroko: Added brief description of OS ISR &amp; its user interrupt handler support</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11838&amp;oldid=prev"/>
				<updated>2021-09-21T07:01:28Z</updated>
		
		<summary type="html">&lt;p&gt;Added brief description of OS ISR &amp;amp; its user interrupt handler support&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 07:01, 21 September 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 9:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 9:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 1 ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 1 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When an interrupt occurs, the CPU pushes the return address &amp;amp; then jumps to address 0038h. &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;If the &lt;/del&gt;ROM &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;is &lt;/del&gt;disabled &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;at the time &lt;/del&gt;(see bit 6 of [[86:Ports:04|Port 4]]), the calculator will likely crash.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When an interrupt occurs, the CPU pushes the return address &amp;amp; then jumps to address 0038h. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Note that &lt;/ins&gt;ROM &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;access should not be &lt;/ins&gt;disabled (see bit 6 of [[86:Ports:04|Port 4]]) &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;while IM 1 is set &amp;amp; interrupts are enabled&lt;/ins&gt;, &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;or &lt;/ins&gt;the calculator will likely crash.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&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;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&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;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 2 ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 2 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&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;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&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;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11837&amp;oldid=prev</id>
		<title>Zeroko: Fixed behavior of IM 2 vectors in unused banks</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11837&amp;oldid=prev"/>
				<updated>2021-09-21T04:38:19Z</updated>
		
		<summary type="html">&lt;p&gt;Fixed behavior of IM 2 vectors in unused banks&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 04:38, 21 September 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 12:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 12:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 2 ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Interrupt Mode 2 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&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 &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;either &lt;/del&gt;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;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&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 &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;the first &lt;/ins&gt;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;ins class=&quot;diffchange diffchange-inline&quot;&gt;. If just the second byte is read from an unused bank, its value will be the same as the first&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zeroko</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11836&amp;oldid=prev</id>
		<title>Zeroko: Created page with &quot;Interrupts  Individual interrupt sources can be enabled, disabled, or acknowledged using Port 3. When an interrupt...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=86:Interrupts&amp;diff=11836&amp;oldid=prev"/>
				<updated>2021-09-21T04:34:04Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;&lt;a href=&quot;/index.php?title=Category:86:General_Hardware_Information&quot; title=&quot;Category:86:General Hardware Information&quot;&gt;Interrupts&lt;/a&gt;  Individual interrupt sources can be enabled, disabled, or acknowledged using &lt;a href=&quot;/index.php?title=86:Ports:03&quot; title=&quot;86:Ports:03&quot;&gt;Port 3&lt;/a&gt;. When an interrupt...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&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>

	</feed>