•  Back 
  •  MiNT 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  %About 
  •  Show info about hypertext 
  •  View a new file 
Topic       : The ATARI Compendium
Author      : Scott Sanders / JAY Software
Version     : 1.25 (20/6/2003)
Subject     : Documentation
Nodes       : 1117
Index Size  : 32614
HCP-Version : 6
Compiled on : Atari
@charset    : UTF-8
@lang       : en
@default    : 
@help       : %About
@options    : +g -i -t4 +y +z
@width      : 100
View Ref-File
                              Loadable Devices


MiNT contains a number of built-in devices and also supports loadable
device drivers. Current versions of MiNT may contain any of the following
devices:

Device Filename  Device

CENTR            Centronics Parallel Port

MODEM1           Modem Port 1

MODEM2           Modem Port 2

SERIAL1          Serial Port 1

SERIAL2          Serial Port 2

MIDI             MIDI ports

PRN              PRN: device (usually the Centronics Parallel Port)

AUX              AUX: device (usually the RS232 Port)

CON              Current Terminal

TTY              Current Terminal (same as CON)

STDIN            Current File Handle 0 (standard input)

STDOUT           Current File Handle 1 (standard output)

STDERR           Current File Handle 2 (standard error)

CONSOLE          Physical Console (keyboard/screen)

MOUSE            Mouse (system use only)

NULL             NULL device

AES_BIOS         AES BIOS Device (system use only)

AES_MT           AES Multitasking Device (system use only)

Each of these devices is represented by a filename (as shown in the table
above) in the 'U:\DEV\' directory. Using standard GEMDOS calls (ex: Fread()
and Fwrite()) on these files yields the same results as accessing the
device directly. New devices, including those directly accessible by the
BIOS, may be added to the system with the Dcntl() call using a parameter
of DEV_INSTALL, DEV_NEWBIOS, or DEV_NEWTTY. See the Dcntl() call for details.

MiNT versions 1.08 and above will automatically load device drivers with
an extension of '.XDD' found in the root or '\MULTITOS' directory. '.XDD'
files are special device driver executables which are responsible for
installing one (or more) new devices. MiNT will load the file and JSR to
the first instruction in the TEXT segment (no parameters are passed). The
device driver executable should not attempt to Mshrink() or create a stack
(one has already been created).

The '.XDD' may then either install its device itself with Dcntl() and
return DEV_SELFINST (1L) in register D0 or return a pointer to a DEVDRV
structure to have the MiNT kernel install it (the 'U:\DEV\' filename will
be the same as the first eight characters of the '.XDD' file). If for some
reason, the device can not be initialized, 0L should be returned in D0.

When creating a new MiNT device with Dcntl( DEV_INSTALL, devname,
&dev_descr ) the structure dev_descr contains a pointer to your DEVDRV
structure defined as follows:

typedef struct devdrv
{
    LONG (*open)( FILEPTR *f );
    LONG (*write)( FILEPTR *f, char *buf, LONG bytes );
    LONG (*read)( FILEPTR *f, char *buf, LONG bytes );
    LONG (*lseek)( FILEPTR *f, LONG where, LONG whence );
    LONG (*ioctl)( FILEPTR *f, WORD mode, VOIDP buf );
    LONG (*datime)( FILEPTR *f, WORD *timeptr, WORD rwflag );
    LONG (*close)( FILEPTR *f, WORD pid );
    LONG (*select)( FILEPTR *f, LONG proc, WORD mode );
    LONG (*unselect)( FILEPTR *f, LONG proc, WORD mode );
    LONG reserved[3];
} DEVDRV;

Each of the assigned members of this structure should point to a valid
routine that provides the named operation on the device. The routine must
preserve registers D2-D7 and A2-A7 returning its completion code in D0. No
operating system TRAPs should be called from within these routines,
however, using the vector tables provided in the kerinfo structure
returned from the Dcntl() call, GEMDOS and BIOS calls may be used. The
specific function that each routine is responsible for is as follows:

Member    Meaning

open      This routine is called by the MiNT kernel after a FILEPTR
          structure has been created for a file determined to be
          associated with the device. The routine should perform whatever
          initialization is necessary and exit with a standard GEMDOS
          completion code. This routine is responsible for validating the
          sharing mode and other file flags to verify that the file may be
          legally opened and should respond with an appropriate error code
          if necessary.

write     This routine should write bytes number of BYTEs from buf to the
          file specified in FILEPTR. If the file pointer has the O_APPEND
          bit set, the kernel will perform an lseek() call to the end of
          the file prior to calling this function. If the lseek()/write()
          series of calls does not guarantee that data will be written at
          the end of a file associated with your device, this function
          must ensure that the data specified is actually written at the
          end of the file. This function should return with a standard
          GEMDOS error code or the actual number of BYTEs written to the
          file when complete.

read      This routine should read bytes number of BYTEs from the file
          specified in FILEPTR and place them in the buffer buf. This
          function should return with a standard GEMDOS error code or the
          actual number of bytes read by the routine.

lseek     This routine should move the file position pointer to the
          appropriate location in the file as specified by the parameter
          where in relation to the seek mode whence. Seek modes are the
          same as with Fseek(). The routine should return a GEMDOS error
          code or the absolute new position from the start of the file if
          successful.

ioctl     This routine is called from the system's perspective as Fcntl()
          and is used to perform file system/device specific functions. At
          the very least, your device should support FIONREAD, FIONWRITE,
          and the file/record locking modes of Fcntl(). The arg parameter
          of Fcntl() is passed as buf.

datime    This routine is used to read or modify the date/time attributes
          of a file. timeptr is a pointer to two LONGs containing the time
          and date of the file respectively. These LONGs should be used to
          set the file date and time if rwflag is non-zero or filled in
          with the file's creation date and time if rwflag is 0. This
          function should return with a standard GEMDOS error code or E_OK
          (0) if successful.

close     This routine is used by the kernel to close an open file. Be
          aware that if f->links is non-zero, additional processes still
          have valid handles to the file. If f->links is 0 then the file
          is really being closed. pid specifies the process closing the
          file and may not necessarily be the same as the process that
          opened it. Device drivers should set the O_LOCK bit on f->flag
          when the F_SETLK or F_SETLKW ioctl() call is made. This bit can
          be tested for when a file is closed and all locks on all files
          associated with the same physical file owned by process pid
          should be removed. If the file did not have any locks created on
          it by process pid, then no locks should be removed. This routine
          should return with a standard GEMDOS error code or E_OK (0) if
          successful.

select    This routine is called when a call to Fselect() names a file
          handled by this device. If mode is O_RDONLY then the select is
          for reading, otherwise, if mode is O_WRONLY then it is for
          writing. If the user Fselect()'s for both reading and writing
          then two calls to this function will be made. The routine should
          return 1L if the device is ready for reading or writing (as
          appropriate) or it should return 0L and arrange to 'wake up'
          process proc when I/O becomes possible. This is usually
          accomplished by calling the wakeselect() member function of the
          kernel structure. Note that the value in proc is not the same as
          a PID and is actually a pointer to a PROC structure private to
          the MiNT kernel.

unselect  This routine is called when a device waiting for I/O should no
          longer be waited for. The mode and proc parameters are the same
          as with select(). As with select(), if neither reading nor
          writing is to be waited for, two calls to this function will be
          made. This routine should return a standard GEMDOS error code or
          E_OK (0) if successful.

The FILEPTR structure pointed to by a parameter of each of the above
calls is defined as follows:

typedef struct fileptr
{
    WORD            links;
    UWORD           flags;
    LONG            pos;
    LONG            devinfo;
    fcookie         fc;
    struct devdrv   *dev;
    struct fileptr  *next;
} FILEPTR;

The members of FILEPTR have significance as follows:

Member   Meaning

links    This member contains a value indicating the number of copies of
         this file descriptor currently in existence.

flags    This member contains a bit mask which indicates several
         attributes (logically OR'ed together) of the file as follows:

         Name        Mask    Meaning
         O_RDONLY    0x0000  File is read-only.
         O_WRONLY    0x0001  File is write-only.
         O_RDWR      0x0002  File may be read or written.
         O_EXEC      0x0003  File was opened to be executed.
         O_APPEND    0x0008  Writes start at the end of the file.
         O_COMPAT    0x0000  File-sharing compatibility mode.
         O_DENYRW    0x0010  Deny read and write access.
         O_DENYW     0x0020  Deny write access.
         O_DENYR     0x0030  Deny read access.
         O_DENYNONE  0x0040  Allow reads and writes.
         O_NOINHERIT 0x0080  Children cannot use this file.
         O_NDELAY    0x0100  Device should not block for I/O on this file.
         O_CREAT     0x0200  File should be created if it doesn't exist.
         O_TRUNC     0x0400  File should be truncated to 0 BYTEs if it
                             already exists.
         O_EXCL      0x0800  Open should fail if file already exists.
         O_TTY       0x2000  File is a terminal.
         O_HEAD      0x4000  File is a pseudo-terminal "master."
         O_LOCK      0x8000  File has been locked.

pos      This field is initialized to 0 when a file is created and should
         be used by the device driver to store the file position pointer.

devinfo  This field is reserved for use between the file system and the
         device driver and may be used as desired. The exception to this
         is if the file is a TTY, in which case devinfo must be a pointer
         to a tty structure.

fc       This is the file cookie for the file as follows:

         typedef struct f_cookie
         {
          FILESYS *fs;
          UWORD  dev;
          UWORD  aux;
          LONG  index;
         } fcookie;

         fs is a pointer to the file system structure responsible for this
         device. dev is a UWORD giving a useful device ID (such as the
         Rwabs() device number). The meaning of aux is file system
         dependent. index should be used by file systems to provide a
         unique means of identifying a file.

dev      This is a pointer to the DEVDRV structure of the device driver
         responsible for this file.

next     This pointer may be used by device drivers to link copies of
         duplicate file descriptors to implement file locking or sharing
         code.

Upon successful return from the Dcntl() call, a pointer to a kerinfo
structure will be returned. The kerinfo structure is defined below:

typedef LONG (*Func)();

struct kerinfo
{
    WORD        maj_version;
    WORD        min_version;
    UWORD       default_mode;
    WORD        reserved1;

    Func        *bios_tab;
    Func        *dos_tab;

    VOID        (*drvchng)( UWORD dev );

    VOID        (*trace)( char *, ... );
    VOID        (*debug)( char *, ... );
    VOID        (*alert)( char *, ... );
    VOID        (*fatal)( char *, ... );

    VOIDP       (*kmalloc)( LONG size );
    VOID        (*kfree)( VOIDP memptr );
    VOIDP       (*umalloc)( LONG size );
    VOID        (*ufree)( LONG memptr );

    WORD        (*strnicmp)( char *str1, char *str2, WORD maxsrch );
    WORD        (*stricmp)( char *str1, char *str2 );
    char *      (*strlwr)( char *str );
    char *      (*strupr)( char *str );
    WORD        (*sprintf)( char *strbuf, const char *fmtstr, ... );

    VOID        (*millis_time)( ULONG ms, WORD *td );
    LONG        (*unixtim)( UWORD time, UWORD date );
    LONG        (*dostim)( LONG unixtime );

    VOID        (*nap)( UWORD n );
    VOID        (*sleep)( WORD que, WORD cond );
    VOID        (*wake)( WORD que, WORD cond );
    VOID        (*wakeselect)( LONG proc );

    WORD        (*denyshare)( FILEPTR *list, FILEPTR *f );
    LOCK *      (*denylock)( LOCK *list, LOCK *new );

    LONG        res2[9];
};

The members of the kerinfo structure are defined as follows:

Member        Meaning

maj_version   This WORD contains the kernel version number.

min_version   This WORD contains the minor kernel version number.

default_mode  This UWORD contains the default access permissions for a file.

reserved1     Reserved.

bios_tab      This is a pointer to the BIOS function jump table. Calling
              bios_tab[0x00]() is equivalent to calling Getmpb() and is
              the only safe way from within a device driver or file
              system.

dos_tab       This is a pointer to the GEMDOS function jump table. Calling
              dos_tab[0x3D]() is equivalent to calling Fopen() and is the
              only safe way from within a device driver or file system.

drvchng       This function should be called by a device driver if a media
              change was detected on the device during an operation. The
              parameter dev is the BIOS device number of the device.

trace         This function is used to send information messages to the
              kernel for debugging purposes.

debug         This function is used to send error messages to the kernel
              for debugging purposes.

alert         This function is used to send serious error messages to the
              kernel for debugging purposes.

fatal         This function is used to send fatal error messages to the
              kernel for debugging purposes.

kmalloc       Use this internal heap memory management function to
              allocate memory.

kfree         Use this internal heap memory management function to free
              memory allocated with kmalloc().

umalloc       Use this internal heap memory management function to
              allocate memory and attach it to the current process. The
              memory will be released automatically when the current
              process exits.

ufree         Use this internal heap memory management function to
              allocate memory allocated with ufree().

strnicmp      This function compares maxsrch characters of str1 to str2
              and returns a negative value if str1 is lower than str2,
              a positive value if str1 is higher than str2, or 0 if they
              are equal.

stricmp       This function compares two NULL terminated strings, str1 to
              str2, and returns a negative value if str1 is lower than
              str2, a positive value if str1 is higher than str2, or 0 if
              they are equal.

strlwr        This function converts all alphabetic characters in str to
              lower case.

strupr        This function converts all alphabetic characters in str to
              upper case.

sprintf       This function is the same as the 'C' library sprintf()
              function except that it will only convert SPRINTF_MAX
              characters (defined in TOSDEFS.H).

millis_time   This function converts the millisecond time value in ms to
              a GEMDOS time in td[0] and date in td[1].

unixtim       This function converts a GEMDOS time and date in a UNIX
              format LONG.

dostim        This function converts a UNIX format LONG time/date value
              into a GEMDOS time/date value. The return value contains the
              time in the upper WORD and the date in the lower WORD.

nap           This function causes a delay of n milliseconds.

sleep         This function causes the current process to sleep, placing
              it on the system que que until condition cond is met.

wake          This function causes all processes in que que, waiting for
              condition cond, to be woken.

wakeselect    This function wakes a process named by the code proc
              currently doing a select operation.

denyshare     This function determines whether the sharing mode of f
              conflicts with any of the files given in the linked list
              list.

denylock      This function determines whether a new lock new conflicts
              with any existing lock in the linked list list. The LOCK
              structure is used internally by the kernel and is defined
              as follows:

              typedef struct ilock
              {
               FLOCK   l;
               struct ilock *next;
               LONG    reserved[4];
              } LOCK;

              l is the structure actually containing the lock data (as
              defined in Fcntl()). next is a pointer to the next LOCK
              structure in the linked list or NULL if this is the last lock.
              reserved is a pointer to four LONGs currently reserved.

res2          These longwords are reserved for future expansion.