AtariSIO driver and utilities V0.20 beta

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.

   AtariSIO supports the following interfaces:
   - one chip SIO2PC (with MAX232), command connected to RI
   - one chip SIO2PC, command connected to DSR
   - 1050-2-PC (with MAX232), command connected to RTS
   - Ape ProSystem cable (with 14C89), command connected to DTR

   The old two-chip SIO2PC interface (with a MAX232 and an LS368)
   is NOT supported, and probably never will be.

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).
   In case you don't have zlib installed on your system, or if
   you don't want .gz-file support, comment out the definition of
   "ZLIB_CXX_FLAGS" and "ZLIB_LD_FLAGS".

   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.

   If you are NOT using devfs, you have to create the device node
   /dev/atarisio by typing "make /dev/atarisio". The default permissions
   are set to "666", you may want to change them to something more
   appropriate.

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

   If "make install" is not able to determine the correct kernel
   version from the "linux/version.h" header file, edit the
   "VERSION" variable.

   Since version 0.04 the atarisio kernel driver also supports the
   Linux device filesystem. If you upgrade from an earlier version
   and want to have full devfs support with the kernel module
   autoloader, please also update your modutils/modules.conf file
   (see next section).

   Please note that atariserver and atarixfer are installed setuid root.
   You can also run these utilities with normal user privileges, but then
   they 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".

   If the kernel module autoloader is activated (which is the
   default on most systems), the kernel module will be loaded
   automatically when a program opens /dev/atarisio.

   In the case you're not running the autoloader, load the module
   manually by typing "modprobe atarisio". If you want atarisio to
   be enabeled at boot time, please consult your linux documentation
   on how to achieve this. Usually it is sufficient to add a line
   containing "atarisio" (without the double quotes) to the file
   "/etc/modules".

   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 :-)

   Notes on upgrading from versions below 0.11: The alias line in
   the modutils template, which is necessary for the kernel module
   autoloader, was added in version 0.11. So please update the
   modutils file if you want the autoloader to work!

5. 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 recheck 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!

6. 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.20 beta and atariserver V0.20 beta.

Starting with version V0.20 these utilities support reading and
writing of DCM, DI and XFD images, in addition to the standard
ATR images. Furthermore, transparent compression and decompression
is supported if you compile AtariSIO with zlib support. This means,
for example, that you can directly read and write from/to an
.atr.gz file without needing to (de)compress it by hand.

The file type is determined by examining the file-extension.
Recognized extensions are .atr, .atr.gz, .dcm, .dcm.gz, .xfd, .xfd.gz
(which are not case-sensitive, so .ATR.gz will also work).

In case the image-file has a non-recognized extension (eg. .foo),
the ATR-format is assumed.


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

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

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

If you want to read a disk inserted into your 1050 and create
a disk 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
-c          use alternative SIO2PC cable (command=DSR)
-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.

-c tells AtariSIO that your Atari is connected via an alternative
   SIO2PC cable. The standard SIO2PC cable uses the RI pin for
   command line input. Some Windows SIO emulators use a slightly
   modified SIO2PC cable, using DSR instead of RI. If you are not
   sure what kind of SIO2PC cable you have, just try starting
   atariserver with and without the "-c" switch and test if your
   Atari can boot from atariserver.
   BTW: there's no performance benefit using the DSR line instead
   of the RI line, both cables work identically with AtariSIO.

-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. Read the list of SIO commands at the end of this
   README for more details.

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

This will load dos.atr into D1:, data1.atr into D3: and data2.dcm
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           |
| u - unload image                  |
| p - write protect disk            |
| P - unprotect disk                |
| x - exchange drives               |
| d - display directory of image    |
| 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 contains three status flags: 'C' (changed),
     'P' (write protected), and 'S' or 'D' (single or double density).

     'C' tells you whether the image has been changed since it was
     written to / read from disk the last time.
     Images created with 'c' will always show up as changed 'til they
     are saved for the first time.

     'P' tells you that the image is write protected (this flag
     can be changed with the 'p' and 'P' keys).

     'S' or 'D' tell you whether the image is in single (128 bytes
     per sector) or double (256 bytes per sector) density.

     The third colum contains the size of the image in kByte.

     The fourth column contains the path and filename of the image.

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 a disk image file (ATR/DCM/DI/XFD) into a disk drive.

2.5  'w' writes the image of a disk drive into a disk image file.
     You may either specify a single drive number (1-8) or 'A' for
     'all changed' disks, to quickly write back all images that
     have been changed.

2.6  'u' unloads (frees) a disk drive.
     Specify a drive number to unload, or 'A' for all drives.

2.7  'p' and 'P' write-(un)-protect a disk drive
     Specify a drive number to (un)protect, or 'a' for all drives.
     If you save a drive to an ATR image, the write protect
     flag will also be saved. So this is a simple solution if you
     want a certain image to be write protected permanently.
     Note: this does not work with DCM, DI and XFD images, since these
     image formats don't support a write protect flag!

2.8  'x' exchanges two disk drive numbers.

2.9 'd' displays the (DOS2.x) directory of an image.
     Please note that this function only works with DOS2.x compatible
     disk formats (like DOS2.x, MyDOS, Turbo-DOS, ...), but _not_
     with Sparta-DOS disks!

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
image 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.
The commands marked with an asterisk (*) are only available when
the high speed mode is activated.

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)
0x68 - (*) get SIO code length in bytes
0x69 - (*) get high speed SIO code, relocated to address found in
       AUX1 and AUX2

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)


Credits
=======

Thanks to:

Atari Bit Byter User Club (ABBUC) for the 6502 highspeed SIO code
Jindroush for the DCM codec and DI format documentation


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
