-----------------------------------------------------------------------------
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.

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.

:RO = read-only port
:WO = write-only port (returns either $0009 or $00B9 when read)
:RW = read/write port

-----------------------------------------------------------------------------
THE I/O PORTS
-----------------------------------------------------------------------------

:RW [600000]
    <..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]
    <........|........> =

:WO [600006]
    <........|........> =

:WO [600008]
    <........|........> =

:WO [60000A]
    <........|........> =

:RW [60000C]
    <765.3210|........> = ? link status
    <........|7...321.> = ? link status
    <........|..5.....> = set: receive buffer has a byte (1 byte buffer)
    <........|.6......> = set: transmit buffer is empty (1 byte buffer)

:RW [60000E]
    <.......0|........> = ? link control
    <......1.|........> = ? link control
    <.....2..|........> = ? red output
    <....3...|........> = ? white output
    <........|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
			: The TI-92's ROM writes $0888 to this port during
			: initialization.

: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
			: initial value by writing it to this port. The
			: TI-92's ROM writes $B2 to this port during
			: initialization. The timer is incremented every
			: 6400(?) clock cycles (approximately 1580 times per
			: second). The value $FF overflows to $00; the next
			: time it is incremented, it is reset to its intial
			: value. The LCD is refreshed every 16th time this
			: timer is incremented. See the descriptions for
			: Auto-Ints 1 and 5 in TRAPS.TXT.

: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]
    <76543210|........> = (Function unknown)
			: The TI-92's ROM writes $21 to this port during
			: initialization.
    <........|....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
