ALL ABOUT XBIOS FUNCTIONS by Richard Karsmakers
Originally published in ST NEWS Volume 1 Issue 5, launched on
October 5th 1986.
In the previous issues of ST NEWS we already had a little chat
concerning System Variables, BIOS routines and GEMDOS routines;
this time, we'll have an in-depth look at XBIOS routines,
sometimes called EBIOS routines - it stands for Extended BIOS.
These functions are there to enable the programmer to use specific
hardware characteristics of the Atari ST. For MC68000 programmers,
it is handy to know that TRAP #14 is needed for calling these
routines. Thereby, the function number must be put on the stack.
While writing this article, we made use of Data Becker's "ST
Intern" (ISBN 3-89011-119-X, Data Becker, Merowingestr. 30, 4000
Düsseldorf, West Germany; in Holland: Postbus 8411, 3503 RK,
Utrecht, Tel. 030-430254). If you want to know everything about
XBIOS functions, you should buy that publication; it's a must for
all serious ST programmers/users. In this article, we will only
have a look at how to program these routines from assembler. All C
freaks will definately have to get "ST Intern", as will the people
that want better examples....
In each example, you might wonder why we added the last line, that
usually includes an 'add' instruction. This instruction is
necessary to clear the stack (as far as I've understood). The
number that goes with it, can be calculated as follows:
Each .l you put on the stack: +4
Each .w you put on the stack: +2
Each .b you put on the stack: +1
See? Now, let's go on.....
Example: move.l vector,-(sp)
This function can be used to initialize all routines that handle
'vector' is the address of a routine that is called by the
keyboard processor when a mouse-report occurs.
'type' can choose one of the following alternatives:
0 Disable Mouse
1 Enable Mouse, Relative mode
2 Enable Mouse, Absolute mode
4 enable Mouse, Keyboard mode
'parameter' points to a parameter block, that is built up as
'topmode' can have on of the following values:
0 Y=0 is located at the bottom corner
1 Y=0 is located at the top corner
'buttons' is a parameter for the 'Set Mouse Buttons' command of
the IKBD (we might publish an article about that in the near
future as well).
'xparam' & 'yparam' are factors for the mouse movement. When you
have choosen 'type' to be 2 (that means that you work with the
mouse in absolute mode), vier additional parameters are added to
These are the x-and y-coördinates of the maximal value of the
mouse, and the other parameters specify the position at which the
mouse should originally be put.
Example: move.w quantity,-(sp)
This function may be used to allocate (reserve) a piece of memory.
'quantity' is the number of bytes that should be reserved. That
chunk of memory will be allocated at the top of memory. This
function should be called before the Operating System starts
Example: move.w #2,-(sp)
This function returns a longword, that signifies the Base of the
physical screen. On a 512 K machine, this would result in $78000.
Example: move.w #3,-(sp)
This function sets the logical base of screen memory. All
operations that use screen memory will be working on this part of
memory. If physical and logical screen memory are the same, you
will also be able to see what happens on the screen. The function
returns a longword, which will be $78000 if you have a 512 K
Example: move.w #4,-(sp)
The 'getrez' function returns the screen resolution, which can be
one of the following values:
0 Low Resolution (320x200 pixels; 16 colors)
1 Medium Resolution (640x200 pixels; 4 colors)
2 High Resolution (640x400 pixels; 2 colors)
Example: move.w res,-(sp)
This function allows the user to change the screen parameters that
could be read using one of the three functions we already
mentioned before. If one of those parameters should not be set, it
is necessary to enter a negative value. The parameters will be set
on the next Vertical Blank Interrupt (VBL).
Example: move.l paletpntr,-(sp)
This function enables you to load a new color palette. Therefore
you must give a pointer to a table with color values (16 values,
all words). The address of the pointer should be even. The colors
will be loaded at the next VBL. If you know how to handle this
routine quite well, it's possible to simulate more then 16 colors
on your screen at one time. I think Magnetic Scrolls used this
trick on the first picture of "The Pawn" (which is said to use 500
colors!). Examples: $000 is black, $777 is white, $700 is red,
$070 is green and $007 is blue.
Example: move.w color,-(sp)
This function makes it possible to change just one color at a time
(just like "Press '1' or '2' to Start" with Michtron's "Time
'colnumber' is the number of the color that should be changed.
'color' is the new value of that color, ranging from $000-$777.
If you enter -1 as color, you will simply get the old color value
of the color with the number 'colnumber'.
Example: move.w count,-(sp)
This function enables the reading of one or several sectors from a
'count' is the number of tracks that should be read sequentially.
Values between 1 and 9 are normally possible (number of sectors
per track), but with maxi-formatted disks I see no reason why one
shouldn't use '10' as well.
'side' selects the side that should be read from. 0 is side A, and
1 is side B. On single sided floppy-drives (like the one I have -
snif, snif!) you can only use 0 - side A.
'track' specifies the number of the track the sectors should be
read from. This value can vary; it depends on the number of tracks
per side. Mostly, this will be 80 (so the value can be from 0 to
79), but is can also be 40, 83, or even another value (that is
because of the flexibility of the Disk format for Atari system
'sector' is the sector number of the sector that should be read
first. Normally, this can be from 0-9, but sometimes it can be 10
as well (on maxi-formatted disks).
'device' is the number of the device the information should be
read from. This can be 0 (for drive A) or 1 (for drive B).
The line 'clr.l -(sp)' just puts an empty longword on the stack.
This is unused.
'buffer' is the address of a piece of memory where the data read
should be put. This should always be at a longword-boundary, and
there should be enough room to put to info in (512 bytes x the
number of sectors you read).
The 'floprd' function returns an error code. This can be:
-1 General Error
-2 Drive not Ready
-3 Unknown command
-4 CRC Error
-5 Bad Request
-6 Seek Error
-7 Unknown Media
-8 Sector not Found
-9 (No Paper)
-10 Write Error
-11 Read Error
-12 General error
-13 Disk is Writeprotected
-14 Disk has been Changed
-15 Unknown Device
-16 Bad Sector
-17 Put Disk in Drive
Example: move.w count,-(sp)
This function enables the user to write one or several sectors to
a disk. The parameters have the same meaning as those listed at
function 8 (floprd). This function also returns an error code,
which can also be one of those listed at the 'floprd' function.
Example: move.w virgin.-(sp)
This routine can format one single track. The parameters have the
'virgin' is the value with which all sectors of the specified
track will be filled when formatted. $E5E5 is mostly used for
this. You must look out not to use $F as value for the high
'magic' is the magic number (the ST is crawling with them!) that
has to accompany the formatting. In this case, it has to be
$87654321 (I suppose the people at Atari had a lack of originality
when they used introduced this magic number; some other 'magic'
numbers are birth-dates, BIOS launch-dates, etc.).
'interleave' specified the sequence in which sectors are written
to disk. Normally this is 1. I think the guy who designed Copystar
at RDS software used this variable for his "fast-load disk"-bit.
'side' determines the side on which the track is located that
should be formatted. Ofcourse, one cannot select another value for
this than 0 if one has a single sided disk drive.
'track' is the number of the track that should be formatted.
Normally, this will be 0-79, but it can also be a higher number
(even upto 83!). Watch out: if you want the track to be used for
program storage, the boot sector must 'know' that there are such
high tracks! Also, not all disk drives are able to read tracks
above number 79. As a part of copy protection, this function can
cause quite a lot of grey hairs with certain people.
'sectra' is the number of sectors on that track. Unless you're
designing some hot-shot copy protection, this should be of the
same value that all other tracks are formatted with. This will
normally be from 0 to 9, but it can also be 10.
'device' is the device number (have a look at 'floprd' for whihc
numbers you may use).
'clr.l -(sp)' is here used to put an empty - unused - longword on
the stack, just like its counterpart in the function 'floprd' and
'buffer' for the complete trackdata. If you use 9 sectors per
track, this must be at least 8 Kb in size.
The function returns an error code. If it is -16, bad sector, it
means that the data couldn't be properly verified. In that case,
the buffer will contain a list of bad sectors (seperated by '0').
You can try to format the track again, or you can mark the bad
Just like the 'floprd' and 'flopwr' functions, you can check for
an error with the following sequence:
....Rest of the program
error ....Error handle routine
Example: move.l pntr,-(sp)
With this function, it is possible to send a string of data to the
MIDI OUT port.
'pntr' is the pointer to the memory address on which the string is
'count' is the number of bytes that should be sent -1. So if you
want to send 12 bytes, that value should be 11.
Example: move.l vector,-(sp)
This function is used to initialize an Interrupt routine in the
'number' is the number of the MFP-Interrupt, which can be from 0
'vector' is the address on which the vector that belongs to that
Interrupt routine is located.
Example: move.w device,-(sp)
This routine is there to get the pointer to a buffer-data-line for
an input device. The following input devices may be selected:
The buffer-data-line is built up as follows:
long ibuf Pointer to input buffer
int ibufsize Size of input buffer
int ibufhd Head Index
int ibuftl Tail Index
int ibuflow Low water Mark
int ibufhi High water Mark
For more specific information, I am afraid I must tell you to have
a look at pages 200 and 201 of Data Becker's "ST Intern". The
specifications and examples mentioned there might make working
with this XBIOS function more clear, whereas talking about them in
this article would be too much of a hassle.
Example: move.w scr,-(sp)
This XBIOS function configurates the RS232 Interface. The
parameters thereby have the following meaning:
'scr' is the Synchronous Character Register in the MFP.
'tsr' is the Transmitter Status Register in the MFP.
'rsr' is the Receiver Status Register in the MFP.
'ucr' is the USART Control Register in the MFP.
'ctrl' is a communication-parameter.
'baud' is the baudrate.
Whenever a parameter turns out to be -1, the old value is kept on
the MFP 68901. You should have a look at some documentation about
the MFP 68901 processor for the meaning of the MFP registers.
'ctrl' is used to specify the Handshake-Mode:
0 No Handshake (that is default on power-up)
3 XON/XOFF and RTS/CTS (not very useful)
'baud' can have one of the following values:
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.