# -------------------------------------------------------------------
# JERRY                                 (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 the ADCs.
# Thanks to NEUROMANCER for the information about JOYIN bit#15
# Thanks to Mr.Nemo for the second PIT 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 flamewars on r.g.v.a or the mailing list.
#
# HTML soon ?
# -------------------------------------------------------------------
# $Id: jerry.html,v 1.22 1997/11/16 18:14:41 nat Exp $
# -------------------------------------------------------------------
Here are some of the leftovers of JERRY that aren't described in the 
RISC dox.


  1. Joystick/Joypad

  2. Analog Joystick

  3. Interrupt control

  4. Sound Production

  5. Clock Registers

  6. Programmable Timers

  7. Networking


JOYSTICK/JOYPAD:
===============

Digital Joypad JOYSTICK:
=-=-=-=-=-=-=-=-=-=-=-=-=

   It seems that as a rule the bits are low active in these
   registers.


W: JOYSTICK ($F01400)
~~~~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +-+-------^------+--+---------+---------+
   |r|    unused    |mu|  col 1  |  col 0  |  
   +-+--------------+--+---------+---------+
    15                8   7...4     3...0

   col 0:   column control of joypad 0 

      Here you select which column of the joypad to poll. 
      The columns are:

                Joystick       Joybut 
      col_bit|11 10  9  8     1    0  
      -------+--+--+--+--    ---+------
         0   | R  L  D  U     A  PAUSE       (RLDU = Joypad directions)
         1   | *  7  4  1     B       
         2   | 2  5  8  0     C       
         3   | 3  6  9  #   OPTION

      You select a column my clearing the appropriate bit and setting
      all the other "column" bits. 


   col1:    column control of joypad 1

      This is pretty much the same as for joypad EXCEPT that the
      column addressing is reversed (strange!!)
            
                Joystick      Joybut 
      col_bit|15 14 13 12     3    2
      -------+--+--+--+--    ---+------
         4   | 3  6  9  #   OPTION
         5   | 2  5  8  0     C
         6   | *  7  4  1     B
         7   | R  L  D  U     A  PAUSE     (RLDU = Joypad directions)

   mute (mu):   sound control

      You can turn off the sound by clearing this bit.

   read enable (r):  

      Set this bit to read from the joysticks, clear it to write
      to them.

    
R: JOYSTICK ($F14000)
~~~~~~~~~~~~~~~~~~~~~
   16        12        8         4         0
   +---------+---------+---------^---------+
   |  pad 1  |  pad 0  |      unused       |
   +---------+---------+-------------------+
     15...12   11...8          7...0

   Reading this register gives you the output of the selected columns
   of the pads.
   The buttons pressed will appear as cleared bits. 
   See the description of the column addressing to map the bits 
   to the buttons.


RO: JOYBUTS/CONFIG ($F14002)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   16       12         8         4         0
   +---------^---------^----+--+-+----+----+
   |           unused       | e|p| b1 | b0 |  
   +------------------------+--+-+----+----+
         15...9       8 7..6  5 4 3..2 1..0
   
   b0:   button read out for pad 0
      bit 0:   PAUSE, OPTION status
      bit 1:   A, B, C status

   b1:   button read out for pad 1
      bit 2:   PAUSE, OPTION status
      bit 3:   A, B, C status

   Returns the status of some of the Joypad buttons. You address which
   information you want with the JOYSTICK register (described above).

   palflag (p):  
      if this flag is set, you have a NTSC jaguar else
      it's a PAL Jag

   endianess (e):
      Always set for Motorola endianess.

   unused/unkown (u):



Analog Joystick:
=-=-=-=-=-=-=-=

The analog joystick feature was apparently removed from later
models of the Jaguar. The registers might exist still, but you 
might not necessarily get anything useable.


W: ANAJOY ($F17C00)
~~~~~~~~~~~~~~~~~~~
   16       12         8         4         0
   +---------^---------^---------^-+--+--+-+
   |            ???                |p |n |a|    WO
   +-------------------------------+--+--+-+

   axis (a) :  select X or Y for polling

      Set this bit to 1 for Y-axis polling, cleared: X-axis

   joystick (n):  select joystick   (??)
   
      Clear for joystick 0, set for joystick 1

   poll (p):    poll bit (??)

      Set this to one to initiate polling/ADC conversion ?
      It appears that after you start polling you need to give the ADC
      40 us time to convert the value.


R: ANAJOY ($F17C00) 
~~~~~~~~~~~~~~~~~~~
   16       12         8         4         0
   +---------^---------+---------^---------+
   |       unused      |       value       |    
   +-------------------+-------------------+
                         7...............0

   value:   8 bit value from the ADC



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

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

   enable:
      bit 0:   LEVEL 0 IRQ enable  (CPU)
      bit 1:   LEVEL 1 IRQ enable  (DSP)
      bit 2:   LEVEL 2 IRQ enable  (PIT1)
      bit 3:   LEVEL 3 IRQ enable  (PIT2)    
      bit 4:   LEVEL 4 IRQ enable  (NETWORK)    
      bit 5:   LEVEL 5 IRQ enable  (I2S)
      bit 6:   unused

   Enable by setting the appropriate bits

   latches:
      bit 8:   LEVEL 0 IRQ         (CPU)
      bit 9:   LEVEL 1 IRQ         (DSP)
      bit10:   LEVEL 2 IRQ         (PIT1)
      bit11:   LEVEL 3 IRQ         (PIT2)
      bit12:   LEVEL 4 IRQ         (NETWORK)
      bit13:   LEVEL 5 IRQ         (I2S)
      bit14:   unused

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

   The interrupts that occur are not routed to the 68K directly,
   but rather to   sound production:="===============" rw: l_i2s ($f1a148) ~~~~~~~~~~~~~~~~~~~ 32 28 24 20 16 12 8 4 0 +--------^--------^--------^--------+--------^--------^--------^--------+ | unused | value | +-----------------------------------+-----------------------------------+ just a guess rw: r_i2s ($f1a14c) ~~~~~~~~~~~~~~~~~~~ 32 28 24 20 16 12 8 4 0 +--------^--------^--------^--------+--------^--------^--------^--------+ | unused | value | +-----------------------------------+-----------------------------------+ just a guess actually these are apparently not just dacs but rather ports, where you can read and write data. the written data is sent to the dacs. the data you read might come from the cdrom (or some other device ?) i suspect this is a synchronous serial port. only the lower 16 bits are in actual use. rw: sclk ($f1a150) ~~~~~~~~~~~~~~~~~~ 32 28 24 20 16 12 8 4 0 +--------^--------^--------^--------^--------^--------^--------^--------+ | unused | divide | +-----------------------------------------------------------------------+ divide: this determines the sampling rate (or the irq rate). a source clock is divided by the "divide" value according to the following highly mathematical formula: frequency="clock_frequency" / (divide + 1) if the sclk isn't tied to one of the "mystery clocks", then the clock_frequency is running at a rate of: bus_frequency / 64 so the other way around now: desired_frequency="bus_frequency" / 64 / (divide + 1) divide="bus_frequency" / 64 / desired_frequeny - 1 lets try with 44100: 26591000 / 64 / 44100 - 1="8.42" ~ 8 -> 45072
        and with 32000: 26591000 / 64 / 32000 - 1 = 11.98 ~ 12 -> 31960
        and with 25000: 26591000 / 64 / 44100 - 1 = 15.62 ~ 16 -> 25968

   
         
RW: SMODE ($F1A154)
~~~~~~~~~~~~~~~~~~~
  32       28       24       20       16       12        8        4        0
   +--------^--------^--------^--------^--------^--------^--------^--------+
   |                                                                       |
   +-----------------------------------------------------------------------+

   Set this to $15 for sound production. Maybe this is a bit like the
   Falcon Matrix, where you can switch between several input sources and
   output sinks.



CLOCK REGISTERS:
=-=-=-=-=-=-=-=

The clock registers are said to be for jaguar hardware on a card, that
wants to communicate its configuration with the outside world. The registers
don't have any effect on the working of the Jaguar.

R: CLK1 ($F10010)
~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------^---------^---------+
   |                unknown                |  
   +---------------------------------------+

   Supposedly has something to do with the processor 
   clock frequency. I'd guess read only. 
   This register neither affects sound (SCLK) nor video appreciably.


WR: CLK2 ($F10012)
~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------^---------^---------+
   |                unknown                |  
   +---------------------------------------+

   Sets the video clock frequency ? Hmm,I don't really know what
   this is good for. Haven't noticed any effects either.
   This register neither affects sound (SCLK) nor video appreciably.
   
   Default values:   NTSC=181 PAL=226


RW: CHRO_CLK ($F10014)
~~~~~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------^---------^---------+
   |                unknown                |  
   +---------------------------------------+

   Maybe used to control the color DACs ? I haven't seen any effect
   with this register.
   This register neither affects sound (SCLK) nor video appreciably.

   Default value: 4



PROGRAMMABLE TIMERS:
====================

RW: JPIT1 ($F10000)
~~~~~~~~~~~~~~~~~~
RW: JPIT2 ($F10004)
~~~~~~~~~~~~~~~~~~
 32       28        24        20       16       12        8        4        0
  +--------^---------^---------^--------^--------^--------^--------^--------+
  |           pre-scale                 |             divider               |
  +-------------------------------------------------------------------------+

value:
   Probably works like this:
   As soon as you write a value into the register, then the counter is cleared
   and starts decrementing immediately. If the register reaches zero then
   it will issue an IRQ and will keep on decrementing. (JUST A GUESS)



NETWORKING:
==========

Finally there's a little description of networking code. Most probably
some of the ASISTAT bits are hooked to the JERRY interrupts, that's 
for future research...

The transmitter/receiver hardware is double register buffered on input and
output (as usual). You have quite some freedom in configuring the 
hardware to drive the serial protocol to your liking.

The network hardware can generate four input interrupts, namely:

receive register full and parity error, framing error, overrun error

   and one output interrupt:

transmit register empty 

I'd suspect that the DSP provides three IRQs slots for TRANSMIT/RECEIVE 
and ERROR, but that remains to be tested.

As you can see, the ASI is a normal serial line, that is said to be
interfaceable with MIDI and COMLYNX. Because the voltage on the signal
lines is TTL (0V - 5V) level, you can't connect your modem (-15V - 15V) 
to it.

Data is encoded in the format below:
       ___  ___  ___  ___  ___  ___  ___  ___  ___  ______
\     / 0 \/ 1 \/ 2 \/ 3 \/ 4 \/ 5 \/ 6 \/ 7 \/   \/ 
 \___/\___/\___/\___/\___/\___/\___/\___/\___/\___/
One                                                  One
Start|------------8 BITS--------------------|Parity  Stop
Bit                                          Bit     Bit



R: ASIDATA ($F10030)
~~~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------+---------^---------+
   |      zeroes       |        data       |  
   +-------------------+-------------------+
     15.............8     7.............0

zeroes:     just zero bits
data:       incoming data byte. Only the lower byte contains data,
            the upper byte will be/should be zero.
 
   Reading this register will clear the receiver register full bit
   in the status register.


W: ASIDATA ($F10030)
~~~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------+---------^---------+
   |      zeroes       |       data        |  
   +-------------------+-------------------+
     15.............8     7.............0

zeroes:     just zero bits
data:       data to be written  


W: ASICTRL ($F10032)
~~~~~~~~~~~~~~~~~~~~
  16          12            8           4           0
   +--+--+-----^------------^--+--+--+--+--+--+--+--+
   | u|br|      unused         |cl|ri|ti|rp|tp|pa|od|
   +--+--+---------------------+--+--+--+--+--+--+--+
    15 14  13...............7    6  5  4  3  2  1  0

odd (od):                     0: even parity   1: odd parity
parity (pa):                  0: no parity     1: parity
transmitter polarity (tp):    0: active hi     1: active lo
receiver polarity (rp):       0: active hi     1: active lo
transmitter irq (ti):         0: disable       1: enable
receiver irq (ri):            0: disable       1: enable
clear (cl):                   1: clear all errors (see below)
break (br):                   1: send a break level
unused (u):                   unused write zeroes


R: ASISTAT ($F10032)
~~~~~~~~~~~~~~~~~~~~
  16          12           8           4           0
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |er|br|si| u|oe|fe|pe|te|rf| u|ri|ti|rp|tp|pa|od|
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

odd (od):                     see ASICTRL
parity (pa):                   "     "
transmitter polarity (tp):     "     "
receiver polarity (rp):        "     "
transmitter irq (ti):          "     "
receiver irq (ri):             "     "
receive register full (rf):   1: there's something for you to read
transmit register empty (te): 1: you may write something
parity error (pe):            1: a parity error has occurred 
frame error (fe):             1: frame error (serial protocol fault)
overrun error (oe):           1: overrun error (CPU to slow to grab data)
serial input state (si):      look at the current bit received by the hardware
break (br):                   see ASICTRL
error (er):                   all the error states combined (pe, fe, oe)
unused (u):                   unused write zeroes


RW: ASICLK ($F10034)
~~~~~~~~~~~~~~~~~~~~
  16        12         8         4         0
   +---------^---------^---------^---------+
   |                 value                 |  
   +---------------------------------------+
     15.................................0

   This register is used to set the network transfer speed.
   Use this formula to calculate the clock value:
   'frq' is the desired serial transfer frequency

      value = 26593900 / (frq << 4) - 1


BUGS:
~~~~~

Everyone knows the network is buggy, but noone seems to know why. Judging
from some example code, I could get a glimpse at, it might be a good idea
to treat ASICLK carefully like this:

      move.l   #clock_val,d0
      move.l   #ctrl_val,d1
      move.l   d0,ASICLK
      move.l   d1,ASICTRL
      move.l   d0,ASICLK
      move.l   d1,ASICTRL

but maybe this is just superstition!


Example:
~~~~~~~~

Here's some example code how to read a byte from the network and
to write it back, no timeouts no error checking, no optimizing...

; read a byte, return in D0
read_a_byte:
.wait:
      move.w   ASISTAT,d0
      btst     #7,d0
      beq.b    .wait

      move.w   ASIDATA,d0
      rts


; send byte in D0, waste D1
write_a_byte:
.wait:
      move.w   ASISTAT,d1
      btst     #8,d1
      beq.b    .wait

      move.w   d0,ASIDATA
      rts

Nat! (nat@zumdick.ruhr.de)
Klaus (kp@eegholm.dk)

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