AtariSIO driver and utilities V0.10b alpha

Copyright (C) 2002, 2003 Matthias Reichl <hias@horus.com>

This program is proteced under the terms of the GNU General Public
License, version 2. Please read LICENSE for further details.

Visit http://www.horus.com/~hias/atari/ for new versions of AtariSIO.


INSTALLATION
============

0. You need several things to compile and use AtariSIO:

   * a 2.2.x or 2.4.x version of the Linux kernel, with
     enabled module support
   * the kernel headers, matching your running linux kernel
   * libreadline

   Furthermore, you'll need a fully 16550 compatible serial port.
   If you have a serial port on your mainboard, it most certainly
   will work, but eg. a USB-to-serial converter doesn't work.

   Then, you need a SIO2PC interface and/or a 1050-2-PC interface
   cable to connect your Atari (1050) to your PC. I won't describe
   how to build such a cable in this document, so just download
   SIO2PC and read it's documentation.

1. Edit the Makefile

   Sorry, no autoconf yet - you'll have to do the config manually.

   Set "KERNEL_INCLUDES" to your linux kernel include directory
   (normally /usr/src/linux/include).
   Change the installation directory "INST_DIR", if needed
   (default is /usr/local)

   The most important part in Makefile configuration is selecting
   the right gcc version for compiling the kernel module. You must
   not use a different major gcc version than it was used to compile
   the linux kernel, otherwise your system may crash!
   
   First of all do a "cat /proc/version" to get the gcc version used
   for compiling the kernel.

   If "gcc --version" reports the same version number, everything
   is fine.

   If the version numbers don't match, find out how the gcc with
   the right version number is named and edit the "KERNEL_CC"
   definition in the Makefile.

2. Type "make"

   This should compile all programs without warnings.
   If you get something like
   /tmp/xxx.s:9: Warning: ignoring changed section attributes for .modinfo
   just ignore it, It's harmless.

3. Become root and type "make install"

   This will copy the kernel driver atarisio.o to the "misc" directory
   of your kernel modules (eg. /lib/modules/2.4.18/misc) and
   install atariserver and atarixfer in the installation directory.
   "make install" will also create a device node "atarisio" in the
   "/dev" directory, if it does not yet exist. The default permissions
   are "666" - change them to something you like, if needed.

   At the moment I'm using a major number of 10 and a minor number of
   240 for the (character) device driver. This numbers are reserved
   for experimental use, maybe I'll try to register an official
   number pair sometime...

   Please note that atariserver is installed setuid root. You can
   also run this utility with normal user privileges, but then it won't
   be able to take advantage of realtime scheduling priorities. In other
   words: performance might be better when run with root privileges.

4. Activate the kernel driver
   
   Please keep in mind that the atarisio kernel driver cannot
   co-exist with the serial port driver, so you have to deactivate
   the serial port you'll be using for Atari-connection before
   installing the kernel module. Note: this _only_ effects the serial
   port you'll be using for Atari connections, all other serial ports
   will stay usable (and can even be used while running eg. the
   atariserver utility).

   First of all, decide which serial port you'll be using. I'll
   explain installation for the first serial port (ttyS0) here.
   If you chose another port, just replace the "ttyS0" with the
   appropriate device.

   Become root and type "setserial /dev/ttyS0". The output will
   approximately be something of this kind:
   
   /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4

   Remember / write down the UART type, the Port address and 
   the IRQ number. You'll need them.

   Next, take the provided modutils templates "modutils-ttyS0",
   and edit it. If needed, change the following two lines to
   match the output of setserial:

   - change the "io=" and "irq=" parameters in the
     "options atarisio ..." line, so that they match the Port
     and IRQ output of setserial.

   - change the "16550A" parameter in the "post-remove ..."
     line to match the UART: output of setserial.

   If you are installing a port different than ttyS0, either
   take one of the other provided templates (maybe they already
   match with your setup), or take anyone of them and replace
   "ttyS?" with the appropriate device name.

   Now copy the edited file to "/etc/modutils" (or whereever
   your modutils configuration is stored" and type "update-modules".

   To start the kernel driver, type "modprobe atarisio".

   If you later decide that you'd like to disable the atarisio kernel
   driver and use the standard serial port, just unload atarisio
   with "modprobe -r atarisio", that will re-activate your serial
   port so that you can access it with "/dev/ttyS?" (if you didn't
   make a mistake with the setserial-stuff :-)

5. That's it.

   Please note that you need to have the atarisio kernel driver
   loaded if you want to use AtariSIO utilities.

   So either type "modprobe atarisio" as root everytime you need
   it, or consult your Linux documentation on how to permanently
   activate a kernel module (usually, adding a line containing
   atarisio to "/etc/modules" will do the job).

6. Troubleshooting

   If you didn't install the kernel module correctly, the utilities
   will most likely bail out with an error message saying
   "unable to open /dev/atarisio". If that's the case, look into
   syslog ("/var/log/syslog" or "/var/log/messages") if you can
   find some error messages from atarisio, and re­check the last
   steps.

   You'll also get "unable to open /dev/atarisio" if another
   program is using /dev/atarisio.

   If your system locks up when using atariserver although you have
   been using the same gcc version as it was used for kernel compilation,
   this might be due to a gcc problem. Especially several older
   non-official gcc snapshot releases are known to cause troubles.
   In this case, try using another gcc version, for example 2.95.

   Please keep in mind that gcc 3.x versions are still not recommended
   officially for kernel compilation!

7. Uninstalling

   If you've got enough of AtariSIO, just become root and use
   "make uninstall" to remove it.


UTILITIES
=========

At the moment two utilites are shipped in this package:
atarixfer V0.01alpha and atariserver V0.10alpha.


Using atarixfer
===============

atarixfer is used to read/write ATR images from/to a Atari drive
connected to your Linux box with an 1050-2-PC cable. An APE
ProSystem cable could work also (it's currently untested), but
you have to add the command-line switch "-p".

If you want to write an ATR-image to a floppy disk, simply
type "atarixfer -w filename.atr".

If you want to read a disk inserted into your 1050 and create
an ATR-image from it, type "atarixfer -r filename.atr".

That's it - currently there are no more options in atarixfer :-)


Using atariserver
=================

atariserver is an SIO-server, like SIO2PC or APE for MSDOS-machines.

I have to admit that the user interface could be a lot better
(eg curses or slang style), but at least it has got some kind of UI :-)

1. Command line options

-h          display help
-a          disable auto status update
-p          write protect the next image
-s          slow mode - disable highspeed SIO
-t          increase SIO trace level (default:0, max:3)
-1..-8      set current drive number (default: 1)
<filename>  load <filename> into current drive number, and then
            increment drive number by one

-h just prints the above help screen.

-a disables the automatical display of the status screen after
   user interactions. Usually a new status screen is printed
   after you change something. If you find this behaviour
   annoying, you can disable it.

-p loads the next image with "write protect" enabled. This
   option is only valid for the next image, if you want to load
   multiple write protected images, you have to specify this
   options before each filename.

-s disables high speed (57600 bit/sec) SIO support. It sets
   the baudrate to fixed 19200 bit/sec and also disables several
   special commands like "get ultraspeed byte" or "flush disk"
   that are only supported by high-speed drives like the
   1050 speedy.

-t increases the trace level. You may use this option up to
   three times if you want more output. Read below for a
   description of the various trace levels

To load several images you could start atariserver with
the following options (for example):

atariserver dos.atr -3 -p data1.atr data2.atr.

This will load dos.atr into D1:, data1.atr into D3: and data2.atr
into D4:. Forthermore, D1: and D4: will be writeable, whereas
D3: will be write protected.


2. User interface commands

The key-assignment of the user interface was greatly inspired by
SIO2PC. So if you are already familiar with SIO2PC, you'll find
atariserver easy to use :-)

After you started atariserver, it'll print "press h for help"
and show the current status.

Pressing 'h' will print the help screen. It looks like this:

+-----------------------------------+
|         AtariServer help:         |
+-----------------------------------+
| h - help                          |
| q - quit                          |
| <space> - status                  |
| c - create image                  |
| l - load image                    |
| w - write image to file           |
| W - write back all changed images |
| u - unload image                  |
| p - write protect disk            |
| P - unprotect disk                |
| x - exchange drives               |
| s - high speed SIO on/off         |
| a - auto status update on/off     |
| t - set SIO trace level           |
+-----------------------------------+

2.1 'q' quits atariserver. Note: any changes made to currently loaded
    images will be discarded!

2.2 '<space>' prints the current status.

    The first line contains the current high-speed, auto-status-update,
    and trace-level settings.

    Below you'll see an overview of the currently active disk
    drives. For each drive (D1: to D8:) you get the following
    information:

    The first column shows the drive number.

    The second column tells you whether the image has been changed
    since it was written to / read from an ATR-file the last time.
    If an image was changed, this column will contain a 'C'.
    Images created with 'c' will always show up as changed 'til they
    are saved for the first time.

    The third colum is the 'write protect' flag. A 'P' in this
    column means the disk is write protected.

2.3 'c' creates an empty image. You have to specify the drive number
    in which the image should be created and the size. Just enter
    any (empty) drive number and then choose from the following
    image sizes:

    '1' is 90k SD (720 sectors, 128 bytes per sector)
    '2' is 130k SD (1040 sectors, 128 bytes per sector)
    '3' is 180k DD (720 sectors, 256 bytes per sector)
    '4' is 360k QD (1440 sectors, 256 bytes per sector)

    'S' is 1-65535 SD sectors (128 bytes per sector)
    'D' is 1-65535 DD sectors (256 bytes per sector)

    If you entered 'S' or 'D' you'll get asked how many sectors
    you'd like to have in the image.

2.4 'l' loads an ATR-image into a disk drive.

2.5 'w' writes the image of a disk drive into an ATR-file.

2.6 'W' writes back all images with assigned names (see status screen)
    to disk. Note: if you create an empty image with the 'c' option,
    it won't have a name assigned. After you first write it to disk
    with 'w' it'll have a name.

2.7 'u' unloads (frees) a disk drive.

2.8 'p' and 'P' write-(un)-protect a disk drive

2.9 'x' exchanges two disk drive numbers.

2.10 's' enables/disables high-speed SIO support

2.11 'a' enables/disables auto-status-update

2.12 't' changes the SIO trace level.

2.13 Notes on entering filenames:

    atariserver uses "readline" and takes use of the history functions,
    so whenever you have to enter a filename you may take advantage of
    filename-completion (with TAB) and the input history (cursor up
    and cursor down) together with all other readline editing functions.

    If you want to abort the current operation, just enter a blank line.


3. SIO trace levels

By default (in debug level 0) atariserver will only print warnings
and error messages related to user input.

In trace level 1 atariserver will output all received command frames.

In trace level 2 atariserver will also output the result of the
processed command frames (OK / ERROR)

In trace level 3 atariserver will dump everything from level 1 and 2
plus the contents of the transmitted data blocks. Furthermore it
will output the data in more readable form (eg the interpretation
of the percom block).


BEHIND THE SCENES
=================

Atariserver emulates almost all commands of an enhanced 1050 drive.
It supports standard (19200 bit/sec) and high-speed (57600 bit/sec)
SIO. High-speed SIO even works on slower PC (like for example my
old 486SX/33).

Speaking of performance: When writing this document the Linux kernel
threads are still non-preemptable. I don't know if this is going to
change in the near future, but this can severely impact reliability,
especially on slow PCs. Normally, the PC should be able to respond
to a received command frame within some 10mSec. If another process
is running, this process will be interrupted immediately (due to
the use of realtime scheduling priorities). But if a kernel thread
(like the kernel update daemon) is running, it won't get preempted
and atariserver is not able to respond quickly enough. Usually this
is not too bad, since the Atari will retry each command some 14
times, so there's a good chance at least one of those retries will
succeed. But under very bad circumstances the command may still
fail and the Atari will get a timeout error (error 138). So, if
you experience performance and/or reliability problems, try to shut
down as many background processes as you can.

Compared to SIO2PC and APE, atariserver uses a slightly different
philosophy when dealing with (virtual) disk images. SIO2PC and APE
both use a "harddisk type" philosophy: if you loaded a, lets say,
130k (enhanced density) image, the disk will always be a 130k disk
from the Atari's point of view - the Atari cannot change this,
just like you are not able to format a 10MB harddisk with 8MB or
with 20MB.

Atariserver uses a "floppy disk type" philosophy. When you insert
a disk into your 1050, you may choose to format it either with
90k (SD), with 130k (ED) or even with 180k (DD). The floppy disk
itself may store up to 360k (if you have a double-sided drive like
the XF551), so there's no reason why you should be limited to a
single density that you selected a long time ago.

Whenever atariserver receives a "format disk" command, it automatically
creates an image matching the selected format (i.e.: matching the
format the Atari sent via the "percom put" command). This make
copying disks really easy: just fire up your favourite sector copier
on your Atari, and be sure any image is loaded into a virtual disk
drive. When the sector copier finishes, just write the image to an
ATR file and copy the next disk.

At the moment atariserver only supports memory images. This means,
any changes (eg. writes / format disk) are stored in RAM. Be sure
to write back the changes using the 'w' or 'W' command if you don't
want to loose them!

If you want to write programs using the atarisio kernel driver by
yourself, here's a short introduction:

Most of the "dirty work", like handling timing constraints,
calculating and comparing checksums is already done in the
kernel driver. This means, you don't need to care about it when
writing a user space application.

The atarisio character device driver only supports two types
of operations (besides open/close): select/poll for waiting
for a new command frame, and IOCTLs for all other tasks.
atarisio doesn't support read/write IO (which wouldn't be
too useful anyway).

You can either use the ioctls (as defined in atarisio.h)
or you may use the C++ wrapper SIOWrapper.{C,h}.

If you want to do kind of a 1050-2-PC communication with a
connected disk drive, just look into the source of atarixfer.
It's not too complicated at all, in fact the interface is
quite similar to the Atari SIO call $E459.

In sioserver mode, you have to poll for the receipt of a command
frame, and then implement the rest of the SIO protocol 'by hand'.
Have a look at the source code (AtrSIOHandler) and try to get
the SIOspecs.pdf from the 'net.

******************** IMPORTANT NOTICE: *********************
* If you want to modify atariserver, either test it as     *
* a normal user (to disable realtime scheduling), or take  *
* the necessary precautions! Otherwise an endless loop     *
* might completely lock up your computer and you'll have   *
* to do a hard reset!                                      *
* A simple, but very effective solution for this problem   *
* is to un-comment the three lines of code in the          *
* set_realtime_scheduling function in atariserver.C that   *
* will install an ALARM handler. This will shut down       *
* atariserver 5 minutes after startup. So if your PC locks *
* up, just wait a few minutes and everything will be fine. *
************************************************************

Finally, here's a list of the currently supported SIO commands:

0x20 - format disk automatically (Speedy command)
0x21 - format disk (uses percom config)
0x22 - format enhanced
0x3f - get ultra speed byte (returns 8 in high-speed mode)
0x4e - percom get
0x4f - percom put
0x50 - put sector
0x52 - read sector
0x53 - get status
0x57 - write sector (that's handled identically to put sector)

The following commands are just ACK'ed, but don't do anything:

0x44 - configure drive (Speedy)
0x4b - slow/fast config (Speedy)
0x51 - flush drive cache (Speedy)


You have reached the end of the document
========================================

If you still have any problems, found a bug, have some ideas for
future versions, or if you just want to talk to me, feel free to
contact me by email at <hias@horus.com>.

so long,

Hias
