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