----------------------------------------------------------------------------- INTRODUCTION ----------------------------------------------------------------------------- If all a computer had was its RAM and ROM, it would just be an inert box doing invisible calculations. To connect to the outside world, computers need I/O ports. On the TI-92, these ports are used to access the keyboard, link port, LCD, and some other hardware settings. This text file describes how the TI-92 organizes its memory, and lists all of the known I/O ports. Since the 68000 processor has no dedicated instructions for reading and writing I/O ports, all I/O must be memory-mapped. This means that I/O ports are read and written by accessing specific addresses in memory. The addresses in the range 600000-60001F correspond to memory-mapped I/O. Directly accessing I/O ports has its advantages and disadvantages. It is very low-level, and gives you complete control. However, it can be a complex process, and why reinvent the wheel? For this reason, most I/O tasks (such as reading keys, sending and receiving through the link port, and changing the contrast) are already handled by the TI-92's ROM. There are some times when it is still best to directly access the I/O ports. The TI-92 is capable of recognizing several keys held down at once, but the ROM has no built-in provision for this. When you want to read multiple keys at once in a program, you must use direct I/O. ---------------------------------------------------------------------------- THE MEMORY MAP ---------------------------------------------------------------------------- Memory addresses are 4 bytes long (32 bits). However, the 68000 processor has a 24 bit addressing bus. For this reason, addresses listed here in hexidecimal will be 6 digits long. On the TI-92, memory is mapped out as follows: 000000-1FFFFF : RAM 200000-3FFFFF : Module ROM, or masked ROM if there's no module 400000-5FFFFF : Module ROM 600000-6FFFFF : Memory mapped I/O (lower 6 bits) 700000-FFFFFF : Nothing (floating bus) : This will probably be used by the TI-92 Plus Module. Note that, for example, the RAM range covers 2 Mb. This does not mean there is 2 Mb of RAM; it means that any RAM accesses beyond the maximum (usually 128 kb) will wrap around to the beginning. The same goes for ROM, except that the maximum is usually 1 Mb. Most TI-92 ROMs use: 000000-01FFFF to address RAM. 200000-2FFFFF to address ROM if it is masked (soldered onto the board). 400000-4FFFFF to address ROM if it is contained in a ROM module. 600000-60001F to address I/O. Note: The TI-92 is capable of addressing 256 kb of interleaved RAM. In this case, it would be addressed in the range 000000-03FFFF. The European language upgrade module (ROM 2.1 / TI-92 II) and the TI-92 Plus Module take advantage of this capability, as well as expanding the ROM to 2 MB (400000-5FFFFF). ----------------------------------------------------------------------------- THE I/O PORTS ----------------------------------------------------------------------------- :RO = read-only :WO = write-only (returns random values when read) :RW = read/write MSB LSB <76543210|76543210> :RW [600000] <.....2..|........> = something to do with keyboard <..5.....|........> = bits <....0> of contrast <........|.......0> = clear: interleave RAM (allows use of 256K of RAM) <........|.....2..> = set: generate Auto-Int 7 when memory below [000120] : is written :WO [600002] <........|........> = :WO [600004] <........|....3...> = set: 000000..1FFFFF mapped to 200000..3FFFFF :WO [600006] <........|........> = :WO [600008] <........|........> = :WO [60000A] <........|........> = :RW [60000C] <765.3210|........> = (write) link status <........|7...321.> = (read) link status <........|..5.....> = (read) set: one byte receive buffer has a byte <........|.6......> = (read) set: one byte transmit buffer is empty :RW [60000E] <.......0|........> = set red output, if direct port access enabled <......1.|........> = set white output, if direct port access enabled <.....2..|........> = read red output <....3...|........> = read white output <.6......|........> = enable direct port access <........|76543210> = read a byte from the receive buffer (1 byte buffer) <........|76543210> = write a byte to the transmit buffer (1 byte buffer) :WO [600010] <76543210|76543210> = Address of LCD memory divided by 8 :WO [600012] <..543210|........> = LCD horizontal frequency (?maybe?) : The TI-92's ROM writes $31 to this port during : initialization. <........|76543210> = $100 - number of LCD scanlines : If the number of scanlines is smaller than $80 (the : actual height of the LCD) the display will be : duplicated in the lower half. Decreasing the height : darkens the LCD; increasing the height lightens the : LCD. The TI-92's ROM writes $80 to this port during : initialization. :RW [600014] <........|........> = :RW [600016] <........|76543210> = Programmable rate generator. Set the timer's init- : ial value by writing it to this port. The timer is : incremented every 6250 clock cycles, unless it has : a value of zero, in which case it is reset to its : initial value. The LCD is refreshed every 16th time : this timer is incremented. : : See also Auto-Ints 1 and 5 in Traps.txt. : : The incrementation rate would be exactly 1600 Hz if : the processor's clock rate were exactly 10 MHz. In : reality, it averages around 1400 Hz, and is depen- : dent on battery power (among other things). : : The ROM sets the initial value of the timer to $B2, : effectively giving it a period of 79 ticks. It uses : the timer for Auto Power Down, which is set to : occur after 6000 interrupts. If the clock rate were : 9.875 MHz, the interrupt rate would be 20 Hz and : countdown delay would be 5 minutes. I think it is : safe to assume that the designers of the TI-92 : intended the APD delay to be 5 minutes. : : For this reason, and becaues it is unlikely that : the designers intended the clock rate to be any- : thing other than 10 MHz, I am inclined to think : that they chose the initial value to be $B2 instead : of $B1 for a very particular reason: auto-int 5 : will coincide with auto-int 1 with a period of 4, : the maximum period possible. This insures that the : TI-92 will run more smoothly than it would if the : two interrupts coincided with a period of 2 or 1. : If you don't understand this, don't worry -- it is : only a matter of curiosity. :RW [600018] <......10:76543210> = keyboard row mask; setting a bit masks the : corresponding row of the keyboard from being : read by [60001B]. :RO [60001A] <......1.|........> = ON key status (0=down, 1=up) <........|76543210> = keyboard column mask; if a bit is clear, one or : more keys in the corresponding column are being : held down. Keys in rows masked by [600018] are : ignored. :WO [60001C] <...43210|........> = Something to do with LCD : The TI-92's ROM writes $21 to this port during : initialization, and $FF when the calculator is : turned off. <........|....3210> = bits <4321.> of contrast :WO [60001E] <........|........> = ----------------------------------------------------------------------------- THE KEYBOARD MATRIX ----------------------------------------------------------------------------- As was hinted in the I/O ports section, the keyboard is accessed internally as a matrix with 10 rows and 8 columns. This matrix can be read by writing [600018], pausing to allow the I/O to recover, then reading [60001B]. Row +-------+-------+-------+-------+-------+-------+-------+-------+ V Col>| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +-------+-------+-------+-------+-------+-------+-------+-------+-------+ | Bit 0 | down | right | up | left | hand | shift |diamond| 2nd | | Bit 1 | 3 | 2 | 1 | F8 | W | S | Z | unused| | Bit 2 | 6 | 5 | 4 | F3 | E | D | X | unused| | Bit 3 | 9 | 8 | 7 | F7 | R | F | C | STO | | Bit 4 | , | ) | ( | F2 | T | G | V | space | | Bit 5 | TAN | COS | SIN | F6 | Y | H | B | / | | Bit 6 | P | ENTER2| LN | F1 | U | J | N | ^ | | Bit 7 | * | APPS | CLEAR | F5 | I | K | M | = | | Bit 8 | unused| ESC | MODE | + | O | L | theta |backspc| | Bit 9 | (-) | . | 0 | F4 | Q | A | ENTER1| - | +-------+-------+-------+-------+-------+-------+-------+-------+-------+ Note: ENTER1 is on the alphabetic _and_ numeric keypads. ENTER2 is next to the cursor pad. Because of the way the TI-92's keyboard is wired, if you hold down three keys that form the corners of a rectangle, the TI-92 will think you are also holding down the key at the fourth corner. The [ON] key is special, and is not part of the matrix. ----------------------------------------------------------------------------- INTERNAL ROUTINES ----------------------------------------------------------------------------- This section contains some system routines that are used in the TI-92's ROM to perform specific tasks. ------------ Reset_Link() ------------ Wait $4E20 Mask Int 5 Read [60000C].W [60000C].B = $E0 Wait $0100 Set bit 0 of [60000E].B Set bit 1 of [60000E].B Wait $0100 Clear bit 0 of [60000E].B Clear bit 1 of [60000E].B Wait $0100 Flush() ------- Flush() ------- [60000C].B = $8D