Unfortunately, the "crap series" (everything lower than a TI-85) uses a driver that stores the screen image in its own RAM. In order to change the display, you have to send each byte in the image to the driver. It is also a very slow driver which needs a delay every time it is accessed.
Hopefully you are sufficiently depressed now, so let's look at how to make the Toshiba T6A04 (that's the name of the driver) our bitch.
$10 | Command Port | Alters the driver's status. |
---|---|---|
$11 | Data Port | Let's you muck about with the driver's RAM. |
_LCD_BUSY_QUICK | Creates a sufficient delay for the LCD driver, regardless of what model. |
---|---|
Location | $000B |
Remarks | For this routine, you use a CALL instead of the normal b_call(). |
Instruction | Effect |
---|---|
$20 to $2E | Set column: 0 (leftmost 8 pixels) to 14 (rightmost 8 pixels). |
$80 to $BF | Set row: 0 (top row) to 63 (bottom row). |
$04 | X auto-decrement | Driver moves back one byte along X. |
---|---|---|
$05 | X auto-increment | Driver moves forward one byte along X. |
$06 | Y auto-decrement | Driver moves back one byte along Y. |
$07 | Y auto-increment | Driver moves forward one byte along Y. |
The TI-OS expects X auto-increment mode for all its routines, and must be set back to this mode if you change it. Although the results could be interesting if you don't.
IN A, ($11)A dummy read is an intermediary between setting a coordinate and reading a byte. Therefore, you don't need a dummy read between setting coordinates, nor between two successive reads.
To write (which doesn't require a dummy):
OUT ($11), A
_LCD_BUSY_QUICK .EQU $000B LD HL, Pic0Name RST 20h RST 10h JR NC, ExistError b_call(_CreatePict) EX DE, HL INC HL INC HL CALL ScanLCDToPic EI RET ScanLCDToPic: DI LD A, $80 ; Set row 0 OUT ($10), A LD C, $20-1 ; C will hold column Row: INC C LD A, C CP $2C ; See if C exceeded maximum column value RET Z CALL _LCD_BUSY_QUICK OUT ($10), A ; Set column CALL _LCD_BUSY_QUICK IN A, ($11) ; Dummy read LD B, 63 ; 63 display rows to a picture LD DE, 12 ; Because LCD is read in column-major order, ; and picture data is in row-major order. Column: CALL _LCD_BUSY_QUICK IN A, ($11) ; Read one byte LD (HL), A ; And put it to the picture ADD HL, DE DJNZ Column CALL _LCD_BUSY_QUICK ; Restart at row 0 LD A, $80 OUT ($10), A LD DE, -(12 * 63) + 1 ; -(12*63) returns to the first row. ADD HL, DE ; + 1 moves one column over. JR Row ExistError: ; Display an error message if Pic0 already exists b_call(_ClrLCDFull) LD HL, 0 LD (CurRow), HL LD HL, ExistErrorMsg SET TextInverse, (IY + TextFlags) b_call(_PutS) RES TextInverse, (IY + TextFlags) b_call(_PutS) b_call(_GetKey) RET Pic0Name: .DB PictObj, tVarPict, tPic0, 0 ExistErrorMsg: .DB "ERR: PIC EXISTS", 0 .DB "Press any key...", 0
command = contrast + (24 OR $C0)
Reading the command port does not tell you what the current contrast setting is, so the system's contrast value is held in (contrast). The value here is in the range 0 to 39.
_LCD_BUSY_QUICK .EQU $000B #define DEC_A_OP $3D #define INC_A_OP $3C b_call(_RunIndicOff) b_call(_GrBufClr) LD A, (contrast) LD B, A ; Number of times to decrease contrast ADD A, $18 | $C0 ; "|": TASM command for bitwise OR PUSH BC ; Save current contrast so we can fade back LD HL, FadePatch ; SMC Fade routine to fade to white. LD (HL), DEC_A_OP CALL Fade ; Display a picture here. Make sure to keep A intact. POP BC ; Restore counter -- number of times to increase ; contrast to restore the original setting. LD HL, FadePatch ; SMC Fade routine to fade in. LD (HL), INC_A_OP Fade: OUT ($10), A HALT HALT ; Delay for approx. 1/20th second HALT HALT HALT HALT HALT HALT FadePatch: DEC A DJNZ Fade RET
Now that you know about test mode, please, don't use it. There is no way to make the
BLODs appear on a specific row, nor can they be constrained. If you had any hopes of
making some kind of waterfall animation, you can just as well forget about it.
As well, test mode is dangerous. If you leave the calculator in test mode for more than
a minute, you risk damaging the LCD. Even a few seconds of BLODs may leave an imprint
on the screen (not unlike phosphor burn-in when you forget your screen saver).
LD B, 63 LD A, $41 Scroll: OUT ($10), A INC A LD C, 5 ;Use a bigger number for slower scrolling. Delay: HALT DEC C JR NZ, Delay DJNZ Scroll LD A, $40 OUT ($10), A RET
The word size is changed with two commands:
$00 | Configure six bits per word |
---|---|
$01 | Configure eight bits per word |
b_call(_ClrLCDFull) b_call(_HomeUp) LD HL, text CALL CustomStr RET text: .DB "Hello ", 1, 0 CustomStr: LD A, (HL) OR A RET Z CP 1 JR NZ, NormalChar ; Trap for char $01 (custom) PUSH AF XOR A ; Configure word size OUT ($10), A LD A, $05 ; Configure X auto-increment CALL $000B OUT ($10), A LD A, (CurCol) ; Set LCD Row ADD A, $20 CALL $000B OUT ($10), A LD A, (CurRow) ; Set LCD Row ADD A, A ADD A, A ADD A, A ADD A, $80 OUT ($10), A LD DE, Smilie LD B, 8 FontLoop: LD A, (DE) CALL $000B OUT ($11), A INC DE DJNZ FontLoop LD A, (CurCol) ; Advance cursor position INC A AND %00001111 LD (CurCol), A JR NZ, DoneCustomFont LD A, (CurRow) ; Advance row. This doesn't check for a bad INC A ; position or scroll. Do that on your own time. LD (CurRow), A DoneCustomFont: POP AF JR DoneChar NormalChar: b_call(_PutC) DoneChar: INC HL JR CustomStr ; Our custom character! smilie: .DB %00011110 .DB %00101101 .DB %00101101 .DB %00111111 .DB %00101101 .DB %00110011 .DB %00011110 .DB %00000000
Command | Function |
---|---|
$00 | Configure six bits per word |
$01 | Configure eight bits per word |
$02 | Turn off |
$03 | Turn on |
$04 | X auto-decrement mode |
$05 | X auto-increment mode |
$06 | Y auto-decrement mode |
$07 | Y auto-increment mode |
$08 – $0B | Power supply enhancement. $08 is lowest. |
$10 – $13 | Power supply level. $10 is lowest. |
$14 – $17 | Unknown |
$18 | Exit test mode |
$19 – $1B | Unknown |
$1C – $1F | Enter test mode |
$20 – $2E | Set column in 8-bit word mode |
$20 – $33 | Set column in 6-bit word mode |
$34 – $3F | Unknown |
$40 – $7F | Set Z-address |
$80 – $BF | Set row |
$C0 – $FF | Set contrast |
Bit | State |
---|---|
7 | 1: LCD is busy 0: LCD can accept a command |
6 | 1: 8 bits-per-word 0: 6 bits-per-word |
5 | 1: Display is on 0: Display is off |
4 | 1: In reset state 0: In operating state |
3 | Not defined |
2 | Not defined |
1 | 1: Y-Auto mode 0: X-Auto mode |
0 | 1: Auto increment mode 0: Auto decrement mode |