From: Michael Current (aa700@cleveland.Freenet.Edu)
Date: 01/18/92-12:44:08 PM Z

From: aa700@cleveland.Freenet.Edu (Michael Current)
Date: Sat Jan 18 12:44:08 1992

Reprinted from A.C.E.C. BBS (614)-471-8559

    Accessing & Using the CIOV

The Central Input/Output Vector
(CIOV) is how Atari BASIC accesses
all of the peripherals (the disk
drive, modem, screen, etc.).
Performing various I/O functions
from BASIC is easy since BASIC
contains special commands to allow
the user to access the CIOV easily.
>From machine language, however, it
is quite a different story.  This
Programming Guide will explain how
to use and access the CIOV in your
machine language programs.  It
assumes a working knowledge of 6502
machine language.

All I/O functions are executed by
setting several locations in page 3
and then jumping the the CIOV.  The
address of the CIOV is $E456
(58454 decimal).

The areas in Page 3 that contains
the locations that must be set
prior to accessing the CIOV are
called Input/Output Control Blocks
(IOCB).  Each I/O Channel has one
corresponding IOCB.  Each IOCB is
16 bytes long.  The addresses of
each IOCB are as follows:
$340-$34F: IOCB For Channel 0
$350-$35F: IOCB For Channel 1
$360-$36F: IOCB For Channel 2
$370-$37F: IOCB For Channel 3
$380-$38F: IOCB For Channel 4
$390-$39F: IOCB For Channel 5
$3A0-$3AF: IOCB For Channel 6
$3B0-$3BF: IOCB For Channel 7
You only access locations which are
in the IOCB for the channel you are
accessing.  In other words, if you
are doing I/O with channel #3, the
only locations you will deal with
are $370-$37F.  The following are
"Location Names" for each byte of
the IOCB.  After the name is the
offset of the byte within each
IOCB and a short description of the
purpose of the location.
ICCOM: (+2) Command to be executed.
 You must set this before accessing
 the CIOV.
ICBAL/ICBAH: (+4, +5) This is a two
 byte number that contains the
 buffer address for the data being
 involved in the operation.  This
 is not always required but usually
ICBLL/ICBLH (+8, +9) This is a two
 byte number that contains the
 number of bytes to be written or
 ICAX6 (+10, +11, +12, +13, +14,
 +15) The last three bytes in the
 IOCB contain misc. data.  The
 contents of these differ depending
 on what handler you are accessing.

The first thing you must do is set
ICCOM to the command you want to
execute.  ICCOM should be set to
the following values depending on
the desired operation:
3: Open Channel Command
5: Input One Line (same as BASIC's
    INPUT Command)
7: Load Binary Buffer (similar to
    using multiple GETs in BASIC)
9: Write One Line (same as BASIC's
    PRINT Command)
11: Write Binary Buffer (similar to
     using multiple PUTs in BASIC)
12: Close Channel Command
13: Status Command (same as the
     STATUS function in BASIC)

The second thing you must do is
set ICBAL and ICBAH.  You should
set these to the low/high byte of
the address where the data to be
transfered is in memory.  For
example, if you wanted to dump
some of memory starting at address
$3035, you would set ICCOM to 11
ICBAL to $35 (the low byte of the
source address), and ICBAH to $30
(the high byte of the source
address).  If you were reading data
into memory from a device you would
set ICBAL and ICBAH to the address
where you want the data to be put
in memory.

The third and, usually, final thing
you must do is set ICBLL and ICBLH.
These contain the number of bytes
that are going to be involved in
the operation.  This location must
be set when using the following
commands: 3, 5, 7, 9, and 11.  It
need not be set for the commands
12 and 13.  Setting this location
is VERY important.  Expanding on
the above example, lets say you
wanted to dump locations $3035
through $3236 (a total of $201
bytes).  You would set up ICCOM,
ICBAL, and ICBAH as explained
above.  Then you would set ICBLL
to $01 (the low byte of the number
of bytes you wish to write) and set
ICBLH to $02 (the high byte of the
number of bytes you wish to write).
When reading, the number stored
here is the maximum number of bytes
that are to be read--any bytes that
are in excess of this value will
be ignored and CIOV will return an
error 137 (record truncated).  This
location must be set for the
following commands: 5, 7, 9, and
11.  When doing INPUTs (command 5)
the CIOV will not accept lines that
are longer than the size specified
here.  That means if you set ICBLL
and ICBLH to 20 and get input from
the user, the CIOV will not accept
any more than 20 characters.  The
user will be able to continue
entering input but only the first
20 bytes will be saved--the rest
discarded.  This is useful since
you can set aside a fixed number
of bytes in an input buffer and be
sure that the user will not be able
to overflow the buffer.  When doing
PRINTs (command 9) be sure to set
this to the length of the longest
line you expect to print.  If you
set these locations to 20 and try
to print 30 characters only the
first 20 will actually be printed.

The fourth thing is EXTREMELY
important (don't worry, we've made
it through the tough stuff).  You
MUST set the X register to the
channel number you are doing to
access MUL
TIPLIED BY 16.  This
means if you are accessing channel
1, you should LDX #16 (LDX #$10).  If you are accessing 
channel 3, you
should LDX #48 (LDX #$30).  This is
very important since this is the
way the CIOV knows which IOCB to
work with.

Finally, simply JSR $E456 to call
the CIOV.  The CIOV will do the
rest.  When it returns, the Y
register will contain the error
code.  A code of 1 means the
operation was successful.  Any
value greater than 127 indicates
an error occured.  The error codes
are the same as those in BASIC.

One quick, and important note:  You
must set ICAX1 when issuing the
OPEN command.  ICAX1 should be set
to the value for the type of
operation you are going to do.
That is, it should be 4 for READ
access, 6 for directory access,
8 for write access, etc.  This
works just like the corresponding
codes in the BASIC OPEN command.

That's basically it!  For general
purpose I/O such as accessing disk
files (or creating them), printing
to the screen, and getting input
from the user, this is all you
need.  Some device-specific
commands may require that you set
some of the Auxillary bytes (such
as NOTE, POINT, etc.) but that is
not in the scope of this particular
Programming Guide.  Look for
another Programming Guide in the
future that will explain some of
the device-specific commands such

                 -- Craig Steiner

 Michael Current, Cleveland Free-Net 8-bit Atari SIGOp   -->>  go atari8  <<--
   The Cleveland Free-Net Atari SIG is the Central Atari Information Network
      Internet: currentm@carleton.edu / UUCP: ...!umn-cs!ccnfld!currentm
      BITNET: currentm%carleton.edu@interbit / Cleveland Free-Net: aa700

Return to message index