written by Johan Borg, johbo050@student.liu.se 14th Jan, 2000 This file is about the hardware of the TI-89 calculator (HW 1.0, see the end), expecially about how to control the microcontroller in it. Because the same chip is in the TI-92, large parts probably applies to it too, but not all. More or less everything in this file is more or less guesses, based on what seem to happen when for an example a bit is set, and there are probably many more things to be observed to happen for many or all of the bits in the registers. Some of the info for in this text is from LowLevel.txt from fargo-0.2.7.1.tar.gz the keyboard map is from kbd89.txt by Th.FERNIQUE Ofcourse you can not hold me responsible for anything that happens because of how someone have used the information in this file, even if it turns out to be an error in this file that caused it. Even though it seems hard to destroy the hardware from software (my calc still works fine and ive written just about everything possible to every register) it might still be possible to do so. On the TI-89, memory is mapped: 000000-1FFFFF : RAM (000000-03ffff used) 200000-3FFFFF : (flash) ROM 400000-5FFFFF : Nothing (pin 17, ~CS to ROM at $400000, used in the ti-92...) 600000-60001F : Memory mapped I/O (lower 5 bits) C00000-Dfffff : Nothing, (pin 16, ~CS active.... no memory implemented there in any calc yet, i think...) The flashrom is protected by a special chip U8, which only let you write commands to the chip when it is in a mode only possible to get it in to by writeing to $1c0000-$1fffff after 3 or more readacceses in a row from $200000-$20ffff, 0x212000-0x217fff or 0x21a000-0x21ffff. In its normal mode this chip also protects the area 0x210000-0x211fff from being read, in this area is a small number of bytes which probably are the calculator specific certificate code. It is possible to disable U8, eighter by adding a small switch making CS go directly to the rom instead through U8. Simply connecting the CS-line direcly does not work, the bootloader contained in $200000-$20FFFF (an area writeprotected by a feature on the flashrom _and_ by U8) checks wether the U8 works before it branches to the writeable part of the ROM. (the switch should connect the pad below pin 10 on U8 to eigther pin 10 or pin 9). The other way is to do branch to somewhere in $200000-$20ffff, 0x212000-0x217fff or 0x21a000-0x21ffff, to normal executable code wont do, because every write that uses a register to determin adress is preceded by a read from a "wrong" area, BUT by branching into code that is not intended to be executable, but happens to be it anyway, a lookup table or text-string for example, which happens to generate 3 reads from "right" areas before a write to a selectable adress, and then getting trapped for an illeagal instruction or similar, then U8 can be disabled. It does work. It seams to me it is possible to make the calc unuseable by clearing the area that is read-protected, the bootloader in the first 64k that is completely write protected and checks a byte in this area, if incorrect value, it stops with the message "Corrupt certificate memory" or something similar, without ever giving the user a chans to install new software (or certificate memory). (the software that recieves and writes new software is completely in the first 64k i think). BUT this is nothing im sure of, and would be happy if someone could check. The TI-89 contains 2 oscilators, one running at ~10MHz, turned off when $600005 is written to and restarted by an interrupt not "masked" by the bits written. This oscillator controlls the program execution in the processor. It can be made run at well over 20MHz, but the calc will not work very vell, if at all, at above ~16MHz, probably because of a unnecessarily short active-time of the 2 bank-select signals for the RAM-banks. This could possibly be fixed with some logic. Increcing the frequency from 10 to 16MHz doesnt increse the powerconsumption when standby (this oscillator is turned of most of the time in this mode) and increses the powerconsumption quite linearily for nonstandby-mode. The other, runs at ~740kHz when 600015:0 is set, controlling the timer-interrupts and the LCD (and a voltage multiplier used to generate the 16v needed by the LCD) "OSC" in this text refers to this oscillator If both oscillators is turned off, the calc uses almost no power at all, and this is probbably what the calc does when the calc is turned "OFF". The memory mapped registers and what they do or appears to do: 600000:7 pin 100 output enable :6 pin 99 output enable :5 data to pin 100 (TI-92: used for LSB in LCD contrast) :4 data to pin 99 :2 data from pin 99 (used for battery level detection) default $0 600001:2 Auto-Int 7 generated for writes to <120. :0 1 bank of 8-bit ram, (cleared= 2 banks) default:$4 600003:2..0 wait states for RAM (7-n) 3 ??? 6..4 wait states for ROM (7-n) (all of the 3 other areas it seems) 7 ??? if set to $ED, $EE, $EF or $F0 the LCD behaves strange... 600005 powerdown control, writeing to this adress puts the calc in low power mode, ON always makes the calc go back to normal the other autointerrupts acording to what is written: Autoint #: :0 1 timer fixed at 350Hz :1 2 key other than ON pressed :2 3 timer fixed at 1.4Hz :3 4 link-service (the fargo-Lowlevel.txt states that this bit: set: 000000..1FFFFF mapped to 200000..3FFFFF, something i dont agree with) :4 5 programmable timer (having bit 0 AND 4 set doesnt work well) note that the calc returns whether the interrupt is serviced or not (the interruptmask in SR set to 7 or so doesnt make the calc inpossible to get out of low power mode) but cant be put in low power mode again before it has been. 60000C link port contol :6 enable direct port access :3 enable interrupt on error :1 enable interrupt on transmit buffer empty :0 ebable interrupt onbyte recived 60000D:7 error(?) :6 transmit buffer is empty (2 byte buffer (?)) :5 receive buffer has a byte :4 link-interrupt is waiting to be serviced (?) :2 port is in use? 60000E:0 data to "tip" on link-connector, if direct port access enabled :1 data to "ring" on link-connector, if direct port access enabled :2 data from "tip" :3 data from "ring" :6 enable direct port access 60000F-byte data from-to recive/transmit buffer 600010-word adress the LCD takes its image from (multiplied by 8) 600012:5..0 (64-n)*16 = Number of pixels wide the LCD controller thinks the LCD is. if changed to something else, $60001c should be modified TO some apropriate value to set the ROW-change-frequency to something that matches the number of horisontal pixels default $31 600013-byte $100 - number of LCD scanlines default: $80 600015:0 turns on the ~740kHz oscillator used for the LCD and the timers :1 turns on data to the LCD, if 0, the LCD is all "white" :2 enables Autointerrupt 3, OSC/2^19 (1.4Hz) :3 enables incrementing of $600017 :5..4 frequency of increment of $600017: 0 = OSC/2^5 (~22kHz) 1 = OSC/2^9 (~1.5kHz) 2 = OSC/2^12 (~18Hz) 3 = OSC/2^19 (1.4Hz) :7 disables all the interrupt generating counters (Autointerrupt 1 is NOT fixed at LCD-update*4, if the number of rows or the row-change frequency is changed, grayscale and similar things doesnt nececarily work) default: $1b 600017-byte counter, Autointerrupt 5 generated when it changes from FF to 00 contolled by $600015 600018-19 keyboard row mask register :9..7 : used for battery level detection in the TI89, (TI92 to perhaps?) : set 0-7, and read $600000:2 if 0, the battery voltage is below: 0 ~4.6v 1 ~4.5v 2 ~4.3v 3 ~4.0v 4 ~3.7v 5 ~3.4v 6 ~3.2v 7 ? (less than or equal to 2.9v, where the calc was reset, probbably by the other voltage detecting chip U7, which seems to be connected to what seems to be reset) :6..0 ROW mask used for keyboard, a bit set=row not read at 60001b default: $280 60001A:1 ON-key, 0 if down. 60001B-byte keyboard column input, a 0 indicates a key on a nonmasked row in the corresponding column is held down. 60001C:5..2 ROW change frequency for the LCD, OSC/((16-n)*8) default: $21, $FF turns the LCD off in some way 60001d:7 if set, pin 69 is pin 68 inverted, and pin 70-73 is controlled as a normal output by bit 0-3 if cleared pin 68 is low and pin 70-73 is pin 68 inverted IF the coresponding bit 0-3 is set, low othervise :4 LCD on if low, controls pin 74 :3..0 contrast, pin 73..70 Other things: Autointerrupt 2: have to be aknowlaged by writeing a byte to $60001B, (what doesnt matter it seems) Autointerrupt 6: have to be aknowlaged by writeing a byte to $60001A, (what doesnt matter it seems) if this is done, they occur when ON/other key is pressed or released The ti89's keyboard matrix : Row +-------+-------+-------+-------+-------+-------+-------+-------+ V Col>| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +-------+-------+-------+-------+-------+-------+-------+-------+-------| | Bit 0 | alpha |diamond| shift | 2nd | right | down | left | up | | Bit 1 | F5 | clear | ^ | / | * | - | + | ENTER | | Bit 2 | F4 |backspc| T | , | 9 | 6 | 3 | (-) | | Bit 3 | F3 |catalog| Z | ) | 8 | 5 | 2 | . | | Bit 4 | F2 | mode | Y | ( | 7 | 4 | 1 | 0 | | Bit 5 | F1 | home | X | = | | | EE | STO | APPS | | Bit 6 | | | | | | | | ESC | +-------+-------+-------+-------+-------+-------+-------+-------+-------+ HW>1.0: Some parts are correct for HW2 (and probably other reported uncommon versions too) but not all, known exeptions: The flashrom-protection works slightly differently, as far as i know, no workaround is known. (it would be nice to know if this is not true) The LCD has its own chip, that buffers the display, making the calc slightly faster, but makeing grayscale slower, and the LCD-control registers at $6000xx isn't valid, new registers exists at $7000xx).