    # -------------------------------------------------------------------
    # TOM                                   (c) Copyright 1996 Nat! & KKP
    # -------------------------------------------------------------------
    # These are some of the results/guesses that Klaus and Nat! found
    # out about the Jaguar with a few helpful hints by other people,
    # who'd prefer to remain anonymous.
    # Thanks to Bastian Schick for the information about RAM accesses.
    # Thanks to NEUROMANCER for more MEMCON info.
    #
    # Since we are not under NDA or anything from Atari we feel free to
    # give this to you for educational purposes only.
    #
    # Please note, that this is not official documentation from Atari
    # or derived work thereof (both of us have never seen the Atari docs)
    # and Atari isn't connected with this in any way.
    #
    # Please use this informationphile as a starting point for your own
    # exploration and not as a reference. If you find anything inaccurate,
    # missing, needing more explanation etc. by all means please write
    # to us:
    #    nat@zumdick.ruhr.de
    # or
    #    kp@eegholm.dk
    #
    # If you could do us a small favor, don't use this information for
    # those lame flame-wars on r.g.v.a or the mailing list.
    #
    # HTML soon ?
    # -------------------------------------------------------------------
    # $Id: tom.html,v 1.22 1997/11/16 18:14:42 nat Exp $
    # -------------------------------------------------------------------

Here are the leftovers of TOM that aren't described in the OP, Blitter or RISC dox.

### Table of Contents

#### System configuration

- MEMCON1
- MEMCON2

#### Interrupt control

- INT1
- INT2

#### Programmable Timer

- PIT

    MEMORY CONFIGURATION:
    ====================

    RW: MEMCON1 ($F00000)
    ~~~~~~~~~~~~~~~~~~~~~
      16        12         8         4         0
       +-+--+--+-^--+------+--+----+-^--+----+-+
       |0| c| 0| io | 0 0 0|f |rams|roms|rtyp|d|
       +-+--+--+----+------+--+----+----+----+-+
       15 14 13 12.11 10..8  7 6..5 4..3 2..1 0

       Default value: $1861

       romdecode (d) :
         Whether the ROM is mapped into the upper 8MB of the address space
         or into the lower 8MB. Keep this set...

       romtype (rtyp):
         ROM organisation, number of bits you'd get with one access:

         0:     8 bit ROM
         1:     16 bit ROM
         2:     32 bit ROM
         3:     64 bit ROM

         Of course setting these bits doesn't change physical realities of
         the cartridge.

       romspeed (roms):
          Rom-speed is set to zero on reset.
          0: 10 clock cycles
          1:  8  "      "
          2:  6  "      "
          3:  5  "      "

       ramspeed (rams) / ramtype:

                   Precharge   RAS->CAS    Refresh
          -------+-----------+------------+---------
          0:         4             3          5           (2 wait states)
          1:         4             3          4           (2 wait states)
          2:         3             2          4           (1 wait state)
          3:         2             1          3           (0 wait state)

          The page mode cycle is always two clock cycles.

       io:
          Specifies the speed of external peripherals. (Whatever they are).
          This supposedly gives the overall cycle time according to this table:

             0: 18 cycles
             1: 10 cycles
             2:  6 cycles
             3:  4 cycles

       fastrom (f):
          FASTROM (2 cycles for ROM access)
          For testing...

       cpu (c):          0: 16 bit cpu   1: 32 bit cpu (speculation)
                         The 68020 is a 32 bit chip, the 68000 is a
                         16 bit chip (externally)
       unused (0) :      unused, set those bits to zero

    RW: MEMCON2 ($F00002)
    ~~~~~~~~~~~~~~~~~~~~~
      16        12         8         4         0
       +----+----+---------+----+----+----+----+
       | un | end| refresh | wd1| cl1| wd0| cl0|
       +----+----+---------+----+----+----+----+
       15.14 13.12  11...8  7..6 5..4 3..2 1..0

       Configure the RAM banks using the lower byte of this register

    columns bank0 (cl0):
    columns bank1 (cl1):
          0: 256
          1: 512
          2: 1024
          3: 2048

    width bank0 (wd0):
    width bank1 (wd1):
          0: 8 bit
          1: 16 bit
          2: 32 bit
          3: 64 bit

    refresh:
       Configures the speed of the memory controllers DRAM refresh.
       I'd assume the default is sensible. The refresh frequency is
                         CLK / (64*(refresh+1))
       Zero disables. The refresh is said to occur only at the end of
        object processing .
       Maybe you can tweak a little performance by changing the value ???
       Most DRAM types need a refresh frequency of 64Khz. So the maximum
       time for a row between refreshes should be:

                1 / 64 Khz * #rows in DRAM

    endianness (end) :
       bit 12, supposedly controls the way a byte is addressed within a phrase
       either bigendiand style (set) or littleendian style (cleared).

       Big-endian    means "the bigger end first"  or $76543210 -> $76 $54 $32 $10
       Little-endian means "the smaller end first" or $76543210 -> $10 $32 $54 $76

       bit 13, supposedly controls the way a bit is addressed within a phrase
       (maybe only by the OP (?))
       Either bigendiand style (set) or littleendian style (cleared) can be
       selected

       Big-endian    means "the bigger end first"  or $76543210 -> $76543210
       Little-endian means "the smaller end first" or $76543210 -> $084C2A6E

    unused (un):

    INTERRUPT CONTROL:
    =================

    This controls, I believe, the interrupts that TOM generates to external
    destinations (f.e. the 68K).

    W: INT1 ($F000E0):
    ~~~~~~~~~~~~~~~~~~
      16        12         8         4         0
       +---------^---------+---------^---------+
       |       latches     |       enable      |
       +-------------------+-------------------+
               15...8              7...0

       enable:
          bit 0:   LEVEL 0 IRQ enable  (VBLANK)
          bit 1:   LEVEL 1 IRQ enable  (GPU)
          bit 2:   LEVEL 2 IRQ enable  (HBLANK - OP-Flag)
          bit 3:   LEVEL 3 IRQ enable  (TIMER)
          bit 4:   LEVEL 4 IRQ enable  (DSP)
          bit 5:   unused
          bit 6:   unused

       Enable by setting the appropriate bits

       latches:
          bit 8:   LEVEL 0 IRQ         (VBLANK)
          bit 9:   LEVEL 1 IRQ         (GPU)
          bit10:   LEVEL 2 IRQ         (HBLANK OP-Flag)
          bit11:   LEVEL 3 IRQ         (TIMER)
          bit12:   LEVEL 4 IRQ         (DSP)
          bit13:   unused
          bit14:   unused

       Clear the latch by setting the appropriate bit. This will clear
       a pending interrupt.

    R: INT1 ($F000E0):
    ~~~~~~~~~~~~~~~~~~
      16        12         8         4         0
       +---------^---------+---------^---------+
       |       unused      |       active      |
       +-------------------+-------------------+
               15...8              7...0

       active:
          bit 0:   LEVEL 0 IRQ enable  (VBLANK)
          bit 1:   LEVEL 1 IRQ enable  (GPU)
          bit 2:   LEVEL 2 IRQ enable  (HBLANK OP-Flag)
          bit 3:   LEVEL 3 IRQ enable  (TIMER)
          bit 4:   LEVEL 4 IRQ enable  (DSP)
          bit 5:   unused
          bit 6:   unused

       Poll this register to check, which interrupts generated the IRQ.
       I think there's a possibility that more than one bit is set.

    W:  INT2 ($F000E2):
    ~~~~~~~~~~~~~~~~~~
      16        12         8         4         0
       +---------^---------+---------^---------+
       |               restart                 |
       +---------------------------------------+

    restart:
       Writing to this register lowers the CPU priority back to normal,
       giving the GPU and the Blitter time to breath. You really should
       write this register at the end of your IRQ routine, or suffer the
       consequences of _really_ slow blits. Actually if you're done with
       your timecritical setup of the OP-list, you might want to set this
       register much sooner. (Also read the old theory: the INT1 stuff is
       still true in a way ;))

    Old theory:
       Restart a suspended GPU. The GPU is suspended during 68K interrupt
       processing. There is a feature (bug) when the IRQ is processed by
       the 68K instead of the GPU. As soon as the interrupt "goes up" the
       GPU (but not the DSP) is halted and then, if the interrupt is not
       enabled the GPU remains halted! It will restart after a write to
       INT2, but ONLY if the interrupt's latch bit (INT1 upper byte) has
       been cleared.

    PROGRAMMABLE TIMER:
    ===================

    RW: PIT ($F00050)
    ~~~~~~~~~~~~~~~~~
     32       28        24        20       16       12        8        4        0
      +--------^---------^---------^--------^--------^--------^--------^--------+
      |               lo_word               |               hi_word             |
      +-------------------------------------------------------------------------+

    lo_word:
    hi_word:
       You load up the counter and it starts as soon as you write the low
       word (?). It will generate a IRQ when it reaches zero, and then
       will restart with the value written to it. It will, when it reaches
       zero again, field another IRQ.
       The frequency with which this timer counts down is the CPU frequency.
       A value of $195CA6C is therefore approximately one second.
       Note that the register halves are flipped (6502 or ugh Intel style).
       The least significant word comes first.

$Id: tom.html,v 1.22 1997/11/16 18:14:42 nat Exp $