@DATABASE "ros"
@MASTER   "ram:ros.doc"
@REMARK   This file was created by ADtoHT 2.0 on 31-Okt-96  19:31:25
@REMARK   Do not edit
@REMARK   ADtoHT is © 1993-1995 Christian Stieber

@NODE MAIN "ros.doc"

                                 @{b}ros.library@{ub}

@{"Overview" LINK "Overview"}
@{"History" LINK "History"}

@{"AddTimerInt()" LINK "ROSAddTimerInt"}         @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}   @{"ROSAllocAudio()" LINK "ROSAllocAudio"}
@{"ROSAllocMem()" LINK "ROSAllocMem"}         @{"ROSAwakeSystem()" LINK "ROSAwakeSystem"}   @{"ROSChipsetCheck()" LINK "ROSChipsetCheck"}
@{"ROSCPUCheck()" LINK "ROSCPUCheck"}         @{"ROSCPUClock()" LINK "ROSCPUClock"}      @{"ROSDeleteFile()" LINK "ROSDeleteFile"}
@{"ROSDisableReq()" LINK "ROSDisableReq"}       @{"ROSDiskLoad()" LINK "ROSDiskLoad"}      @{"ROSDiskState()" LINK "ROSDiskState"}
@{"ROSEnableReq()" LINK "ROSEnableReq"}        @{"ROSFreeAudio()" LINK "ROSFreeAudio"}     @{"ROSFreeMem()" LINK "ROSFreeMem"}
@{"ROSGetDMA()" LINK "ROSGetDMA"}           @{"ROSGetInt()" LINK "ROSGetInt"}        @{"ROSGetKey()" LINK "ROSGetKey"}
@{"ROSKillSystem()" LINK "ROSKillSystem"}       @{"ROSQueryKeys()" LINK "ROSQueryKeys"}     @{"ROSReadExe()" LINK "ROSReadExe"}
@{"ROSReadFile()" LINK "ROSReadFile"}         @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"}   @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}
@{"ROSRequester()" LINK "ROSRequester"}        @{"ROSScreenToBack()" LINK "ROSScreenToBack"}  @{"ROSScreenToFront()" LINK "ROSScreenToFront"}
@{"ROSSetCache()" LINK "ROSSetCache"}         @{"ROSSetCopper()" LINK "ROSSetCopper"}     @{"ROSSetDMA()" LINK "ROSSetDMA"}
@{"ROSSetExitHandler()" LINK "ROSSetExitHandler"}   @{"ROSSetInt()" LINK "ROSSetInt"}        @{"ROSSetIntVec()" LINK "ROSSetIntVec"}
@{"ROSSetJoyPortAttrs()" LINK "ROSSetJoyPortAttrs"}  @{"ROSSetTimerVec()" LINK "ROSSetTimerVec"}   @{"ROSStartTimer()" LINK "ROSStartTimer"}
@{"ROSStopTimer()" LINK "ROSStopTimer"}        @{"ROSSysCall()" LINK "ROSSysCall"}       @{"ROSSysCallEnd()" LINK "ROSSysCallEnd"}
@{"ROSWaitVBlank()" LINK "ROSWaitVBlank"}       @{"ROSWriteFile()" LINK "ROSWriteFile"}     

@ENDNODE
@NODE "Overview" "ros.library/Overview (information)"


This section describes the way how to use the RETIRE Operating System within
your own applications:

The @{"ros.library" LINK "ros/MAIN"} is an enhanced lowlevel.library. It's compatible with currently
all available machines and CPU's (upto '060) and OS1.3 compatible too!
The ROS provides additional functions to take over the entire system so it
should be useful for demo & game coders.
Another advantage is the ability to call important system functions (memory
allocation, read, write) from a killed system.
ROS offers a way to run your hardware bashing application within multitasking.
And finally a ROS prefs file is provided to support custom settings.
On startup ROS tries to load the ros.prefs from your ENV: directory. You may
edit this file to configure the library for your needs.

But remember: It's impossible to open the @{"ros.library" LINK "ros/MAIN"} from two applications at
the same time. The second application will fail to open the library!

Programming guidelines:

The @{"ros.library" LINK "ros/MAIN"} is a standard Amiga library so normal restrictions applies to
function calls:  - a6 loaded with _ROSBase
                 - d0/d1/a0/a1 scratch registers (destroyed by libcall)
                 - functions can't be called from within interrupts
Some ROS functions are special in these cases; they need no scratch registers
or they may be called from within interrupts. Look at the appropriate 'note'
comment for further information.

Do not call any ROS function from supervisor mode. The machine will crash!!!
I think there is no need to switch to supervisor mode. Think of the '060 CPU;
its supervisor model differs from the '040 CPU and a few basic commands will be
emulated by software. Executing such a command from supervisor mode may crash
the machine!!!

Call @{"ROSKillSystem" LINK "ros/ROSKillSystem"}(ROSKSF_DEATHMODE) to take over the entire system. But do not
modify DMA & interrupt stuff by yourself! Use the appropriate ROS routines!!!!!
@{"ROSKillSystem()" LINK "ros/ROSKillSystem"} opens a @{"PAL" LINK "graphics/gfxbase.h/File" 140}-LowRes screen so all 'special' AGA registers are
flushed (FMODE & sprites may not!?!) and it forces graphics boards to switch to
the Amiga custom chip display.

With ROS V2 I introduce a new os-friendly mode. From now there are 4 possible
methods killing the system:

- @{"ROSKillSystem" LINK "ros/ROSKillSystem"}(ROSKSF_DEATHMODE):
  Here you may trash all display related registers.
  You may also use the blitter. It is owned by ROS so do not use OwnBlitter().
  But remember: If you call a ROS function which may interrupt the deathmode
  with @{"ROSSysCall()" LINK "ros/ROSSysCall"} you should finish all your blits before entering this
  function (because the OS needs his blitter!).
  ROS V2 uses a waitblit before entering any system function so the only thing
  you have to do is to suppress all blits in your interrupt code until the
  called function returns.

- @{"ROSKillSystem" LINK "ros/ROSKillSystem"}(ROSKSF_SYSMODE):
  Here is the system active but ROS opens a @{"PAL" LINK "graphics/gfxbase.h/File" 140}-LowRes screen like in the
  deathmode. This means real multitasking, screen switching, and so on. That's
  why you shouldn't use the blitter. If you need it you have to call
  OwnBlitter()/DisownBlitter(), but remember:
  The Amiga OS relies on his blitter! Never allocate it for long times, the
  system may run in a deadlock state!!!
  In the sysmode you may trash all display related registers only if ROS
  screen in front (preferably via copper).

- @{"ROSKillSystem" LINK "ros/ROSKillSystem"}(ROSKSF_DEATHMODE!ROSKSF_OSFRIENDLY), new for ROS V2:
  This is an system-friendly deathmode. ROS opens a screen according to the
  supplied taglist. All input events are catched by ROS and your taskpriority
  is raised to the input.device's priority for maximum performance.
  Screen switching is disabled so you do not call system functions which may
  depth-arrange screens -> result is a deadlock!
  Now you do @{"NOT" LINK "intuition/intuition.h/File" 1501} trash any display related custom registers, use system calls
  for screen manipulation.
  @{"ROSSetCopper()" LINK "ros/ROSSetCopper"} and @{"ROSSetDMA()" LINK "ros/ROSSetDMA"} have no effect, use OS calls!

- @{"ROSKillSystem" LINK "ros/ROSKillSystem"}(ROSKSF_SYSMODE!ROSKSF_OSFRIENDLY), new for ROS V2:
  This is the system-friendly sysmode?!? ROS opens a screen according to the
  supplied taglist. Multitasking and screen switching are active.
  Do @{"NOT" LINK "intuition/intuition.h/File" 1501} trash any display related custom registers, use system calls.
  @{"ROSSetCopper()" LINK "ros/ROSSetCopper"} and @{"ROSSetDMA()" LINK "ros/ROSSetDMA"} have no effect!

In all modes above you may trash the audio custom chip registers and the CIA
registers if successfully allocated via appropriate ROS calls!

You should never touch the following:
- DMACON and INTENA registers
- CIA ICR registers
- CPU interrupt vectors
- serial registers
- disk related registers

Tips 'n' hints for using ROS:

In a multitasking environment your vblank code may be called after the display
is started depending on the speed of higher prioritized vblank interrupts.
If you want to synchronize custom chip modifications with the display you
should use the copper.
And remember: The vblank frequency may vary (not always 50 Hz) if ROS screen
behind other screens or if os-friendly mode!

Some words about the ROS file functions: First of all avoid these SENSELESS
disk assigns. Since OS2.0 it's possible to load additional data files relativ
to your programm directory by using a filename like this "progdir:data1".
Use it!!! On OS1.3 ROS removes the "progdir:" prefix automatically from your
supplied filename, so the only thing the user have to do is a "CD" to the
programm directory before starting your application!
Another ROS feature is the "disk waiting". That means if you load files from
disk (providing the ROSRWF_DISKWAIT flag and a filename like "Disk1:data1") ROS
is waiting for the right disk to be inserted.
Prior to ROS V2 this disk-wait can't be cancelled (see also @{"ROSDiskState()" LINK "ros/ROSDiskState"}).


Please read the following docs carefully!
If you have questions, problems, idea's or bug reports feel free to contact me:

TIK/RETIRE via email:  Nico.Schmidt@Student.Uni-Magdeburg.de

or write to:           Nico Schmidt
                       Möhlauer Str. 9
                       06773 Jüdenberg
                       GERMANY

Thanks to:  TODI/RETIRE for hints and useful idea's
            PABLO/RETIRE for beta testing
            Christian Oldiges for testing, hints & bug reports

@ENDNODE
@NODE "History" "ros.library/History (information)"


                                  ROS HISTORY

*******************************************************************************
RELEASE 1.0, 29.12.95 (Library version 1.0)

    The first release.

*******************************************************************************
RELEASE 1.1, 05.01.96 (Library version 1.1)

    Fixed two minor bugs:
      - @{"ROSCPUClock()" LINK "ros/ROSCPUClock"} shouldn't display a requester if no free CIA available,
        but it does
      - user vblank code was called from vblank server with priority 9, this
        may confuse the timer.device (priority 0) and thus all CIA interrupts
        (e.g. level6 p61) if it steals to much rastertime;
        now user vblank code is executed from a priority 0 vblank server

*******************************************************************************
RELEASE 1.2, 08.01.96 (Library version 1.2)

    Library name changed from 'ROS.library' to '@{"ros.library" LINK "ros/MAIN"}' because a library
    name should always be a lower-case string (thanks to Thomas Kessler)

*******************************************************************************
RELEASE 1.21, 05.02.96 (Library version 1.2)

    P61 initialization bug fixed (wrong offset if 020 optimization),
    thanks to PABLO/RETIRE

*******************************************************************************
RELEASE 2.0, 01.11.96 (Library version 2.0)

    Minor bug fixes:
      - ROSOpenScreen() changed the forbidden state on retry, now fixed
      - @{"ROSWaitVBlank()" LINK "ros/ROSWaitVBlank"} now uses graphics/WaitTOF() in non-deathmode
      - @{"ROSSetCache()" LINK "ros/ROSSetCache"} always enables the data cache on 68060, seems to be a
        problem in 68060.library CacheControl() patch, now a workaround added
      - Some errors fixed in this autodoc

    Changes:
      - @{"ROSChipsetCheck()" LINK "ros/ROSChipsetCheck"} examines gfxbase on OS3.0 instead of reading the
        Alice/Lise ID chip registers
      - CIA allocation rewritten, now ROS should run without CIA hardware if
        you don't need a timer
      - WaitBlits added in Kill-/AwakeSystem() & @{"ROSSysCall" LINK "ros/ROSSysCall"}/-End() functions

    New features:
      - New os-friendly mode for @{"ROSKillSystem()" LINK "ros/ROSKillSystem"} added to support standard
        OS screens for e.g. CyberGraphics applications
      - Joyport routines @{"ROSReadJoyPort()" LINK "ros/ROSReadJoyPort"}/@{"ROSSetJoyPortAttrs()" LINK "ros/ROSSetJoyPortAttrs"} added
      - @{"ROSDiskLoad()" LINK "ros/ROSDiskLoad"}/@{"ROSDiskState()" LINK "ros/ROSDiskState"} added
      - Now the user may disable audio allocation via ros.prefs
      - Joy/mouse buttons may act as exit keycodes (see @{"ROSSetJoyPortAttrs()" LINK "ros/ROSSetJoyPortAttrs"})

*******************************************************************************

@ENDNODE
@NODE "ROSAddTimerInt" "ros.library/ROSAddTimerInt()"
@{b}

   NAME@{ub}
        ROSAddTimerInt -- add an interrupt that is executed at regular
                          intervals@{b}

   SYNOPSIS@{ub}
        intHandle = ROSAddTimerInt(Flags, intRoutine);
        D0                         D0     A0

        @{"ULONG" LINK "exec/types.h/File" 37} AddTimerInt(@{"ULONG" LINK "exec/types.h/File" 37}, @{"APTR" LINK "exec/types.h/File" 34});@{b}

   FUNCTION@{ub}
        Calling this routine causes the system to allocate a CIA timer
        depending on 'Flags' and set up 'intRoutine' to service any interrupts
        caused by the timer.
        Although the timer is allocated it is neither running, nor enabled.
        @{"ROSStartTimer()" LINK "ROSStartTimer"} must be called to establish the time interval and
        start the timer.

        The routine is called from within an interrupt, so normal
        restrictions apply. On entry A5 holds the custom base ($dff000) and
        A6 holds _ROSBase. Your code may trash all registers.

        The CIA timer used by this routine is not guaranteed to always be
        the same. This routine utilizes the CIA resource and uses an
        unallocated CIA timer.

        You should remove the timer with @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}.
        Closing the ros.library removes this timer interrupt automatically.@{b}

   INPUTS@{ub}
        Flags - specify the timer to allocate:
                        TIMF_ANY  - try to allocate any timer
                        TIMF_LEV2 - try to allocate level 2 timers (CIA A)
                        TIMF_LEV6 - try to allocate level 6 timers (CIA B)
        intRoutine - the routine to invoke upon timer interrupts.@{b}

   RESULT@{ub}
        intHandle - a handle used to manipulate the interrupt, or @{"NULL" LINK "exec/types.h/File" 79}
                    if it was not possible to attach the routine.@{b}

   NOTE@{ub}
        If allocation failed a Retry/Cancel-Requester appears to inform the
        user about the problem (if not suppressed and if not in deathmode).

        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}, @{"ROSStartTimer()" LINK "ROSStartTimer"}, @{"ROSStopTimer()" LINK "ROSStopTimer"}, @{"ROSSetTimerVec()" LINK "ROSSetTimerVec"}

@ENDNODE
@NODE "ROSAllocAudio" "ros.library/ROSAllocAudio()"
@{b}

   NAME@{ub}
        ROSAllocAudio -- allocate audio channels@{b}

   SYNOPSIS@{ub}
        success = ROSAllocAudio()
        D0

        @{"BOOL" LINK "exec/types.h/File" 69} ROSAllocAudio(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function allocates all audio channels. Audio DMA is updated
        so that matches with current DMA settings (former @{"ROSSetDMA()" LINK "ROSSetDMA"} calls).
        --> New for V2: The user may disable audio allocation via ros.prefs!

        You should free the audio channels with @{"ROSFreeAudio()" LINK "ROSFreeAudio"}.
        Closing the ros.library frees audio channels automatically.@{b}

   RESULT@{ub}
        success - boolean@{b}

   NOTE@{ub}
        If allocation failed a Retry/Cancel-Requester appears to inform the
        user about the problem (if not suppressed and if not in deathmode).

        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSFreeAudio()" LINK "ROSFreeAudio"}

@ENDNODE
@NODE "ROSAllocMem" "ros.library/ROSAllocMem()"
@{b}

   NAME@{ub}
        ROSAllocMem -- allocate memory and keep track of the size@{b}

   SYNOPSIS@{ub}
        memoryBlock = ROSAllocMem(byteSize, attributes, alignmask)
        D0                        D0        D1          D2

        @{"VOID" LINK "exec/types.h/File" 25} *ROSAllocMem(@{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This function works identically to Exec's AllocMem(), but tracks the
        size of the allocation and provides additional memory alignment.

        See the AllocMem() documentation for details.

        You should free the memory with @{"ROSFreeMem()" LINK "ROSFreeMem"}.
        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use exec.library functions!!!!!!!
        Closing the ros.library frees allocated memory automatically.@{b}

   INPUTS@{ub}
        byteSize - # of bytes to allocate
        attributes - memory requirements
        alignmask - used to allocate memory at special boundaries, if @{"NULL" LINK "exec/types.h/File" 79}
                    Exec's standard alignment applies

                    --> newaddr = memaddr AND @{"NOT" LINK "intuition/intuition.h/File" 1501}(alignmask)
                    e.g. mem align: even by 8 bytes -> alignmask = $00000007@{b}

   RESULT@{ub}
        memoryBlock - a pointer to the newly allocated memory block or @{"NULL" LINK "exec/types.h/File" 79}@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSFreeMem()" LINK "ROSFreeMem"}, exec.lib/AllocMem()

@ENDNODE
@NODE "ROSAwakeSystem" "ros.library/ROSAwakeSystem()"
@{b}

   NAME@{ub}
        ROSAwakeSystem -- close ROS screen and awake from deathmode@{b}

   SYNOPSIS@{ub}
        ROSAwakeSystem()

        @{"VOID" LINK "exec/types.h/File" 25} ROSAwakeSystem(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function deallocates all things allocated with @{"ROSKillSystem()" LINK "ROSKillSystem"}.
        It closes the opened screen and sets the display related DMA to the
        appropriate system values.
        Calling this function without a matching @{"ROSKillSystem()" LINK "ROSKillSystem"} is harmless.

        Closing the ros.library calls automatically ROSAwakeSystem().@{b}

   SEE ALSO@{ub}
        @{"ROSKillSystem()" LINK "ROSKillSystem"}

@ENDNODE
@NODE "ROSChipsetCheck" "ros.library/ROSChipsetCheck()"
@{b}

   NAME@{ub}
        ROSChipsetCheck -- check if desired custom chipset available@{b}

   SYNOPSIS@{ub}
        result = ROSChipsetCheck(chipsetbit)
        D0                       D0

        @{"UWORD" LINK "exec/types.h/File" 40} ROSChipsetCheck(@{"UWORD" LINK "exec/types.h/File" 40});@{b}

   FUNCTION@{ub}
        Use this routine to obtain the available chipset.
        As input you may specify the chipset requirement (bitnumber) and if
        @{"NOT" LINK "intuition/intuition.h/File" 1501} found a requester appears to inform the user about his lack of
        hardware (if not suppressed and if not in deathmode).@{b}

   INPUTS@{ub}
        chipsetbit - the required chipset; currently defined are
                         ROSCSB_ECS for at least HR-@{"AGNUS" LINK "graphics/gfx.h/File" 20} rev3 and 8373 DENISE
                         ROSCSB_AGA for at least ALICE rev2 and LISA,
                     or -1 for only obtaining chipset (no requester appears)@{b}

   RESULT@{ub}
        result - chipset flags (ROSCF_xxx, AGA includes the ECS flag) or @{"NULL" LINK "exec/types.h/File" 79}
                 if required chipset not found

@ENDNODE
@NODE "ROSCPUCheck" "ros.library/ROSCPUCheck()"
@{b}

   NAME@{ub}
        ROSCPUCheck -- check if desired CPU/FPU available@{b}

   SYNOPSIS@{ub}
        result = ROSCPUCheck(cpubit)
        D0                   D0

        @{"UWORD" LINK "exec/types.h/File" 40} ROSCPUCheck(@{"UWORD" LINK "exec/types.h/File" 40});@{b}

   FUNCTION@{ub}
        Use this routine to obtain the available CPU/FPU.
        As input you may specify the processor requirement (bitnumber) and if
        @{"NOT" LINK "intuition/intuition.h/File" 1501} found a requester appears to inform the user about his hardware
        problem (if not suppressed and if not in deathmode).
        Call this routine twice if you need a CPU (AFB_680x0) check and a FPU
        (AFB_6888x/FPU40) check.@{b}

   INPUTS@{ub}
        cpubit - the required CPU/FPU -> AttnFlags AFB_xxxxx
                 or -1 for only obtaining CPU/FPU (no requester appears)@{b}

   RESULT@{ub}
        result - AttnFlags or @{"NULL" LINK "exec/types.h/File" 79} if required chipset not found@{b}

   NOTE@{ub}
        This code handles the FPU40 flag correct: it's only valid if @{"AFB_68040" LINK "exec/execbase.h/File" 160}
        set. Keep this in mind if you examine the RESULT (AttnFlags)!!!

@ENDNODE
@NODE "ROSCPUClock" "ros.library/ROSCPUClock()"
@{b}

   NAME@{ub}
        ROSCPUClock -- CPU/FPU clock calculation@{b}

   SYNOPSIS@{ub}
        CPU/FPUclock = ROSCPUClock()
        D0  D1

        @{"ULONG" LINK "exec/types.h/File" 37}/@{"ULONG" LINK "exec/types.h/File" 37} ROSCPUClock(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        Calculate CPU/FPU clock. The values returned should be accurate at
        least 1/10 MHz, so it's enough for everyone.
        This routine works with all (currently) available processors and it
        takes only a few milliseconds!!!
        In some cases the returned clock is @{"NULL" LINK "exec/types.h/File" 79} because of the lack of
        free CIA timers (or other problems, see BUGS) so it's best to call
        this routine first (e.g. before any timer function).@{b}

   RESULT@{ub}
        CPUclock - the CPU clock in kHz or @{"NULL" LINK "exec/types.h/File" 79} on error (see also BUGS)
        FPUclock - the FPU clock in kHz or @{"NULL" LINK "exec/types.h/File" 79} on error@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   BUGS@{ub}
        In some rare cases the function returns @{"NULL" LINK "exec/types.h/File" 79}:
         - on 68000/10 with only chipmem
         - on _really_ slow machines (e.g. a 10MHz 68040?!?)
         - on 68040/60 systems where it's impossible to turn on instruction
           cache (e.g. A4000 with only chipmem and 68040.library loaded)

        The FPU clock is ALWAYS @{"NULL" LINK "exec/types.h/File" 79} for 68881/2 systems because I'm
        (currently) unable to find a reliable algorithm (blame on me).
        It's hard to deal with the asynchronous data transfer between CPU
        and FPU.
        On 68040/60 systems with FPU the returned value is the same like
        CPU clock.

@ENDNODE
@NODE "ROSDeleteFile" "ros.library/ROSDeleteFile()"
@{b}

   NAME@{ub}
        ROSDeleteFile -- Delete a file or directory@{b}

   SYNOPSIS@{ub}
        success = ROSDeleteFile(flags, name)
        D0                      D0     A0

        @{"ULONG" LINK "exec/types.h/File" 37} ROSDeleteFile(@{"ULONG" LINK "exec/types.h/File" 37}, @{"STRPTR" LINK "exec/types.h/File" 52});@{b}

   FUNCTION@{ub}
        This attempts to delete the file or directory specified by 'name'.
        Note that all the files within a directory must be deleted before the
        directory itself can be deleted.

        If ROSRWF_DISKWAIT flag set the routine assumes that you want to delete
        'name' from a floppy. This means:
         - waiting for the right disk to be inserted
           (implementation: DOS error codes DEVICE_NOT_MOUNTED, NOT_A_DOS_DISK,
           NO_DISK force retry until any other error occurs)
           --> New for V2: waiting may be cancelled via @{"ROSDiskState()" LINK "ROSDiskState"}
         - waiting until disk drive stopped
           (implementation: polling disk.resource until drives are ready)

        Since OS2.0 it's possible to delete files from your program path
        instead of the current directory using progdir:xxx.
        On OS1.3 the "progdir:" string is automatically removed by ROS so you
        don't have to worry about it. The only thing the user have to do is a
        "CD" to the program directory before starting (only on OS1.3). ;-)

        WARNING: It may be dangerous to use this routine within deathmode!
                 Because of the AMIGA's multitasking facilities it isn't
                 possible (isn't it???) to wait till the final end of a delete
                 operation. That's why I use a simple delay of 2 seconds after
                 any delete operation in deathmode. If your filesystem is to
                 slow to write all the data within this time your partition
                 will be @{"NOT" LINK "intuition/intuition.h/File" 1501} validated!!!
                 You've been warned!!!@{b}

   INPUTS@{ub}
        flags - use ROSRWF_DISKWAIT if you want to delete from a floppy
        name - pointer to a null-terminated string@{b}

   RESULT@{ub}
        success - DOS error code on failure or @{"NULL" LINK "exec/types.h/File" 79} for success@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        dos.lib/DeleteFile(), @{"ROSDiskState()" LINK "ROSDiskState"}

@ENDNODE
@NODE "ROSDisableReq" "ros.library/ROSDisableReq()"
@{b}

   NAME@{ub}
        ROSDisableReq -- suspend requesters for our task@{b}

   SYNOPSIS@{ub}
        ROSDisableReq()

        @{"VOID" LINK "exec/types.h/File" 25} ROSDisableReq(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        Suspend all upcoming requesters for our task (ROS- and DOS-Requesters).
        By default requesters are enabled.@{b}

   SEE ALSO@{ub}
        @{"ROSEnableReq()" LINK "ROSEnableReq"}, @{"ROSRequester()" LINK "ROSRequester"}

@ENDNODE
@NODE "ROSDiskLoad" "ros.library/ROSDiskLoad()"
@{b}

   NAME@{ub}
        ROSDiskLoad -- returns whether your program loaded from disk  (V2)@{b}

   SYNOPSIS@{ub}
        result = ROSDiskLoad(diskname)
        D0                   A0

        @{"BOOL" LINK "exec/types.h/File" 69} ROSDiskLoad(@{"STRPTR" LINK "exec/types.h/File" 52});@{b}

   FUNCTION@{ub}
        Returns whether your program loaded from a disk labeled 'diskname' or
        not. Therefore you have to pass the name of your disk to this function.
        After this you should set the flags of all subsequent read/write calls
        according to the result (e.g. @{"ROSReadFile" LINK "ROSReadFile"}(ROSRWF_DISKWAIT, ...) if the
        result was @{"TRUE" LINK "exec/types.h/File" 73})!

        Implementation:
        This function compares the 'diskname' with the name of the disk where
        the home dir of your program (on OS1.3 the current dir) is located. If
        both strings are equal (case-insensitive) this function returns @{"TRUE" LINK "exec/types.h/File" 73}.
        Whenever locale.library is installed in your system, the string
        comparision is replaced by language-specific code.@{b}

   INPUTS@{ub}
        diskname - name of the disk@{b}

   RESULT@{ub}
        result - @{"TRUE" LINK "exec/types.h/File" 73} if your program loaded from a disk labeled 'diskname'@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSDeleteFile()" LINK "ROSDeleteFile"}, @{"ROSReadExe()" LINK "ROSReadExe"}, @{"ROSReadFile()" LINK "ROSReadFile"}, @{"ROSWriteFile()" LINK "ROSWriteFile"}

@ENDNODE
@NODE "ROSDiskState" "ros.library/ROSDiskState()"
@{b}

   NAME@{ub}
        ROSDiskState -- return state of current disk operation  (V2)@{b}

   SYNOPSIS@{ub}
        state = ROSDiskState(diskbreak)
        D0                   D0

        @{"UWORD" LINK "exec/types.h/File" 40} ROSDiskState(@{"BOOL" LINK "exec/types.h/File" 69});@{b}

   FUNCTION@{ub}
        This function is used to determine the state of the current disk
        operation. Therefore it's save to call this function from within
        interrupts.
        Set 'diskbreak' @{"TRUE" LINK "exec/types.h/File" 73} for cancelling the 'wait for disk'-state of
        current disk operation. In this case the current disk operation
        returns with one of the following DOS error codes:
        DEVICE_NOT_MOUNTED, NOT_A_DOS_DISK or NO_DISK.@{b}

   INPUTS@{ub}
        diskbreak - @{"TRUE" LINK "exec/types.h/File" 73} for cancelling the 'wait for disk'-state@{b}

   RESULT@{ub}
        state - the state of the current disk operation (defines from ros.i):
                   DISK_NOP        currently no disk operation, 'diskbreak' has
                                   no effect
                   DISK_Init       initialize (check for disk) in progress
                   DISK_Waiting    ROS is waiting for the (right) disk to be
                                   inserted, cancel this with 'diskbreak'=@{"TRUE" LINK "exec/types.h/File" 73}
                   DISK_Busy       read/write/delete in progress@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers and is save to call
        from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSDeleteFile()" LINK "ROSDeleteFile"}, @{"ROSReadExe()" LINK "ROSReadExe"}, @{"ROSReadFile()" LINK "ROSReadFile"}, @{"ROSWriteFile()" LINK "ROSWriteFile"}

@ENDNODE
@NODE "ROSEnableReq" "ros.library/ROSEnableReq()"
@{b}

   NAME@{ub}
        ROSEnableReq -- permit requesters for our task@{b}

   SYNOPSIS@{ub}
        ROSEnableReq()

        @{"VOID" LINK "exec/types.h/File" 25} ROSEnableReq(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        Permit all upcoming requesters for our task (ROS- and DOS-Requesters).
        By default requesters are enabled.@{b}

   SEE ALSO@{ub}
        @{"ROSDisableReq()" LINK "ROSDisableReq"}, @{"ROSRequester()" LINK "ROSRequester"}

@ENDNODE
@NODE "ROSFreeAudio" "ros.library/ROSFreeAudio()"
@{b}

   NAME@{ub}
        ROSFreeAudio -- free audio channels@{b}

   SYNOPSIS@{ub}
        ROSFreeAudio()

        @{"VOID" LINK "exec/types.h/File" 25} ROSFreeAudio(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function removes probably installed audio interrupt handlers and
        resets the audio DMA (former system values). Then channels are freed.

        Freeing channels without allocation is harmless.

        Closing the ros.library frees audio channels automatically.@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSAllocAudio()" LINK "ROSAllocAudio"}

@ENDNODE
@NODE "ROSFreeMem" "ros.library/ROSFreeMem()"
@{b}

   NAME@{ub}
        ROSFreeMem -- return allocated memory to the system@{b}

   SYNOPSIS@{ub}
        ROSFreeMem(memoryBlock)
                   A0

        @{"VOID" LINK "exec/types.h/File" 25} ROSFreeMem(@{"VOID" LINK "exec/types.h/File" 25} *);@{b}

   FUNCTION@{ub}
        Free an allocation made by the @{"ROSAllocMem()" LINK "ROSAllocMem"} call. The memory will be
        returned to the system pool from which it came.

        WARNING: Before freeing some chip memory be sure that the blitter has
                 finished its work within this memory block!!!
                 The same applies to closing the ros.library.

        Closing the ros.library frees allocated memory automatically.@{b}

   NOTE@{ub}
        Passing a wrong pointer is harmless ;-)

        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   INPUTS@{ub}
        memoryBlock - pointer to the memory block to free, or @{"NULL" LINK "exec/types.h/File" 79}@{b}

   SEE ALSO@{ub}
        @{"ROSAllocMem()" LINK "ROSAllocMem"}

@ENDNODE
@NODE "ROSGetDMA" "ros.library/ROSGetDMA()"
@{b}

   NAME@{ub}
        ROSGetDMA -- obtain DMA settings@{b}

   SYNOPSIS@{ub}
        DMACONR = ROSGetDMA()
        D0

        @{"UWORD" LINK "exec/types.h/File" 40} ROSGetDMA(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function returns current DMA settings (set via @{"ROSSetDMA()" LINK "ROSSetDMA"}).

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use "move.w $dff002,d0" !!!!!!!
        This may return wrong bits if you are in non-deathmode (e.g. copper
        DMA -> the OS may change the bit during screen switching).
        But ROSGetDMA() returns the right value.

        Closing the ros.library reset former system DMA.@{b}

   RESULT@{ub}
        DMACONR - DMA settings set via @{"ROSSetDMA()" LINK "ROSSetDMA"} with additional BBUSY/BZERO
                  bits (unsupported (disk) & unallocated (audio, ...) DMA bits
                  are always 0)@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all other registers and is save
        to call from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSSetDMA()" LINK "ROSSetDMA"}

@ENDNODE
@NODE "ROSGetInt" "ros.library/ROSGetInt()"
@{b}

   NAME@{ub}
        ROSGetInt -- obtain interrupt settings@{b}

   SYNOPSIS@{ub}
        INTENAR = ROSGetInt()
        D0

        @{"UWORD" LINK "exec/types.h/File" 40} ROSGetInt(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function returns interrupt enable bits (set via @{"ROSSetDMA()" LINK "ROSSetDMA"}).
        Additional bits are defined in "ros.i".

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use "move.w $dff01c,d0" !!!!!!! This may return wrong bits.

        Closing the ros.library reset former system interrupt bits.@{b}

   RESULT@{ub}
        INTENAR - Interrupt bits set via @{"ROSSetInt()" LINK "ROSSetInt"}
                  Note: level 1/2/5/6 bits (disk, serial, timer) are not
                        supported!!!
                        Instead additonal bits are defined:  - KEYB
                                                             - CIAATIMA/B
                                                             - CIABTIMA/B@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all other registers and is save
        to call from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSSetInt()" LINK "ROSSetInt"}, libraries/ros.i

@ENDNODE
@NODE "ROSGetKey" "ros.library/ROSGetKey()"
@{b}

   NAME@{ub}
        ROSGetKey -- returns the currently pressed rawkey code and qualifiers@{b}

   SYNOPSIS@{ub}
        key = ROSGetKey()
        D0

        @{"ULONG" LINK "exec/types.h/File" 37} ROSGetKey(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
        This function returns the currently pressed non-qualifier key and
        all pressed qualifiers.

        The values returned by this function are not modified by which
        window/screen currently has input focus.@{b}

   RESULT@{ub}
        key - key code for the last non-qualifier key pressed in the low
              order word ($0..$67). If no key is pressed this word will be $ff.
              The upper order word contains the qualifiers which can be found
              within the long word as follows (lowlevel.library like):
                        Qualifier               Key
                        @{"LLKB_LSHIFT" LINK "libraries/lowlevel.h/File" 41}             Left Shift
                        @{"LLKB_RSHIFT" LINK "libraries/lowlevel.h/File" 42}             Rigt Shift
                        @{"LLKB_CAPSLOCK" LINK "libraries/lowlevel.h/File" 43}           Caps Lock
                        @{"LLKB_CONTROL" LINK "libraries/lowlevel.h/File" 44}            Control
                        @{"LLKB_LALT" LINK "libraries/lowlevel.h/File" 45}               Left Alt
                        @{"LLKB_RALT" LINK "libraries/lowlevel.h/File" 46}               Right Alt
                        @{"LLKB_LAMIGA" LINK "libraries/lowlevel.h/File" 47}             Left Amiga
                        @{"LLKB_RAMIGA" LINK "libraries/lowlevel.h/File" 48}             Right Amiga@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all other registers and is save
        to call from interrupts.@{b}

   SEE ALSO@{ub}
        lowlevel.lib/GetKey(), libraries/lowlevel.i

@ENDNODE
@NODE "ROSKillSystem" "ros.library/ROSKillSystem()"
@{b}

   NAME@{ub}
        ROSKillSystem -- kill the system and open ROS screen@{b}

   SYNOPSIS@{ub}
        success = ROSKillSystem(mode, taglist)
        D0                      D0    A0

        @{"BOOL" LINK "exec/types.h/File" 69}/@{"struct Screen" LINK "intuition/screens.h/File" 133} *ROSKillSystem(@{"ULONG" LINK "exec/types.h/File" 37}, @{"struct TagItem" LINK "libraries/xpk.h/File" 35} *);@{b}

   FUNCTION@{ub}
        Depending on the mode this function acts different:

        In non-os-friendly mode this function opens a @{"PAL" LINK "graphics/gfxbase.h/File" 140}-LowRes screen,
        installs your copper list and sets additional DMA (copper, bitplane,
        sprite). By default all DMA will be cleared.
        Whenever this screen is the frontmost you may bash all display related
        custom chip registers (preferably via copper list).
        If the ROS is unable to open the screen or if it's not @{"PAL" LINK "graphics/gfxbase.h/File" 140}-LowRes
        (promoted screen) a Retry/Cancel-Requester appears (if not suppressed).

        If you specify the flag KILLF_DEATHMODE the multitasking will be turned
        off. Now ROS has taken over the entire system. But interrupts and DMA
        should only be set with ROS functions!!!
        The blitter is owned via OwnBlitter() so you may use it.
        But before using you should do a WaitBlit because it may still working,
        --> this is now obsolete with ROS V2.
        You may interrupt the deathmode via @{"ROSSysCall()" LINK "ROSSysCall"}. At this time the
        blitter will be disowned so you do @{"NOT" LINK "intuition/intuition.h/File" 1501} use it during a SysCall!!!

        Call ROSKillSystem() with KILLF_SYSMODE to run your application within
        multitasking. But be polite and bash the hardware as less as possible.
        The blitter is under system control so you should use OwnBlitter()/
        DisownBlitter() if you need it. But allocate the blitter only for a
        short time because the system uses it too!

        With ROS V2 we introduce a new os-friendly mode. From now it's possible
        to use the death/sysmode with a standard OS screen by passing the
        appropriate taglist to this function. NO MORE HARDWARE BASHING!!!
        Use OS calls for screen rendering! You have to clear the mouse pointer
        with OS calls too! (look at --Overview-- for further details)
        This feature works only on OS2.0+. Setting this flag on OS1.3 this call
        fails with "Couldn't open OS2.0 screen" error.

        Note: Do not make this screen public because ROS captures most rawkey
              events (see also @{"ROSSetIntVec()" LINK "ROSSetIntVec"}/KEYB-Int) so applications opened
              on ROS screen will never receive it. The os-friendly mode should
              be used to provide compatibility with e.g. CyberGraphics!

        Also check out the ROS_KillSysFlags (the current ROS state).
        You may call ROSKillSystem() multiple times to switch between death-
        and sysmode, but calling again the KILLF_OSFRIENDLY flag has NO effect.
        To swith between os-friendly and bashmode you have to call first
        @{"ROSAwakeSystem()" LINK "ROSAwakeSystem"} to close the current ROS screen and after that
        call ROSKillSystem() to re-open the screen.
        A switch from sysmode into deathmode automatically makes the ROS screen
        the frontmost so you don't have to call @{"ROSScreenToFront()" LINK "ROSScreenToFront"}.
        Once ROSKillSystem() returns successful further calls to this function
        will never fail so there is no need to check the result again.

        You should return to the system with @{"ROSAwakeSystem()" LINK "ROSAwakeSystem"}.
        Closing the ros.library calls @{"ROSAwakeSystem()" LINK "ROSAwakeSystem"} automatically.@{b}

   INPUTS@{ub}
        mode - KILLF_SYSMODE for a multitasking environment
               KILLF_DEATHMODE to take over the entire system
               --> New for V2: KILLF_OSFRIENDLY for os-friendly mode,
               use it in conjunction with one of the flags above
               (not supported if ROS runs on OS1.3, ROSKillSystem() will fail)
        taglist - ptr to taglist passed to OpenScreen(), only neccessary if
                  KILLF_OSFRIENDLY@{b}

   RESULT@{ub}
        success - result type depends on the KILLF_OSFRIENDLY flag:
                  if flag set (ROS V2): ptr to ROS screen or @{"NULL" LINK "exec/types.h/File" 79} on failure
                  if flag not set: @{"FALSE" LINK "exec/types.h/File" 76} if ROS was unable to open the
                                   @{"PAL" LINK "graphics/gfxbase.h/File" 140}-LowRes screen, else @{"TRUE" LINK "exec/types.h/File" 73}@{b}

   SEE ALSO@{ub}
        @{"ROSAwakeSystem()" LINK "ROSAwakeSystem"}, @{"ROSSysCall()" LINK "ROSSysCall"}, @{"ROSSysCallEnd()" LINK "ROSSysCallEnd"}

@ENDNODE
@NODE "ROSQueryKeys" "ros.library/ROSQueryKeys()"
@{b}

   NAME@{ub}
        ROSQueryKeys -- return the states for a set of keys@{b}

   SYNOPSIS@{ub}
        ROSQueryKeys(queryArray, arraySize)
                     A0          D0

        @{"VOID" LINK "exec/types.h/File" 25} ROSQueryKeys(@{"struct KeyQuery" LINK "libraries/lowlevel.h/File" 30} *, @{"UBYTE" LINK "exec/types.h/File" 47});@{b}

   FUNCTION@{ub}
        Scans the keyboard to determine which of the rawkey codes
        listed in the 'queryArray' are currently pressed. The state for each
        key is returned in the array.

        The values returned by this function are not modified by which
        window/screen currently has input focus.@{b}

   INPUTS@{ub}
        queryArray - an array of KeyQuery structures. The kq_KeyCode fields
                     of these structures should be filled with the rawkey
                     codes you wish to query about. Upon return from this
                     function, the kq_Pressed field of these structures
                     will be set to @{"TRUE" LINK "exec/types.h/File" 73} if the associated key is down,
                     and @{"FALSE" LINK "exec/types.h/File" 76} if not.
        arraySize - number of key code entries in 'queryArray'@{b}

   NOTE@{ub}
        This function is save to call from interrupts.@{b}

   SEE ALSO@{ub}
        lowlevel.lib/QueryKeys(), libraries/lowlevel.i

@ENDNODE
@NODE "ROSReadExe" "ros.library/ROSReadExe()"
@{b}

   NAME@{ub}
        ROSReadExe -- scatterload a loadable file@{b}

   SYNOPSIS@{ub}
        seglist/errorcode = ROSReadExe(flags, name)
        D0      D1                     D0     A0

        @{"BPTR" LINK "dos/dos.h/File" 130}/@{"ULONG" LINK "exec/types.h/File" 37} ROSReadExe(@{"ULONG" LINK "exec/types.h/File" 37}, @{"STRPTR" LINK "exec/types.h/File" 52});@{b}

   FUNCTION@{ub}
        This function tries to scatterload the file 'name' using dos.library's
        LoadSeg().

        If ROSRWF_DISKWAIT flag set the routine assumes that you want to load
        'name' from a floppy. This means:
         - waiting for the right disk to be inserted
           (implementation: DOS error codes DEVICE_NOT_MOUNTED, NOT_A_DOS_DISK,
           NO_DISK force retry until any other error occurs)
           --> New for V2: waiting may be cancelled via @{"ROSDiskState()" LINK "ROSDiskState"}
         - waiting until disk drive stopped
           (implementation: polling disk.resource until drives are ready)

        Since OS2.0 it's possible to load files from your program path instead
        of the current directory using progdir:xxx.
        On OS1.3 the "progdir:" string is automatically removed by ROS so you
        don't have to worry about it. The only thing the user have to do is a
        "CD" to the program directory before starting (only on OS1.3). ;-)

        You should unload the file with @{"ROSFreeMem" LINK "ROSFreeMem"}(seglist)!
        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use dos.library's UnLoadSeg()!!!!!!!
        Closing the ros.library unloads file automatically.@{b}

   INPUTS@{ub}
        flags - use ROSRWF_DISKWAIT if you want to load from a floppy
        name - pointer to a null-terminated string@{b}

   RESULT@{ub}
        seglist - BCPL pointer to a seglist or @{"NULL" LINK "exec/types.h/File" 79} if error
        errorcode - DOS error code on failure (may be @{"NULL" LINK "exec/types.h/File" 79}!!!)@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSDiskState()" LINK "ROSDiskState"}, @{"ROSFreeMem()" LINK "ROSFreeMem"}, dos.lib/LoadSeg()

@ENDNODE
@NODE "ROSReadFile" "ros.library/ROSReadFile()"
@{b}

   NAME@{ub}
        ROSReadFile -- read a number bytes from a file@{b}

   SYNOPSIS@{ub}
        actLength/errorcode/actBuffer = ROSReadFile(flags, length, offset,
        D0        D1        A0                      D0     D1      D2
                                               memtype, memalign, name, buffer)
                                               D3       D4        A0    A1

        @{"ULONG" LINK "exec/types.h/File" 37}/@{"ULONG" LINK "exec/types.h/File" 37}/@{"VOID" LINK "exec/types.h/File" 25} *  ROSReadFile(@{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37},
                                                 @{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37}, @{"STRPTR" LINK "exec/types.h/File" 52}, @{"VOID" LINK "exec/types.h/File" 25} *);@{b}

   FUNCTION@{ub}
        This function tries to load 'length' bytes from the file 'name' using
        dos.library's Read(). Set 'length` = 0 to load the whole file.
        A1 points to a buffer where the data should be placed, or set A1=0
        to force an automatic memory allocation. In this case you must specify
        'memtype' and 'memalign' (see also @{"ROSAllocMem()" LINK "ROSAllocMem"}).

        If ROSRWF_DISKWAIT flag set the routine assumes that you want to load
        'name' from a floppy. This means:
         - waiting for the right disk to be inserted
           (implementation: DOS error codes DEVICE_NOT_MOUNTED, NOT_A_DOS_DISK,
           NO_DISK force retry until any other error occurs)
           --> New for V2: waiting may be cancelled via @{"ROSDiskState()" LINK "ROSDiskState"}
         - waiting until disk drive stopped
           (implementation: polling disk.resource until drives are ready)

        Since OS2.0 it's possible to load files from your program path instead
        of the current directory using progdir:xxx.
        On OS1.3 the "progdir:" string is automatically removed by ROS so you
        don't have to worry about it. The only thing the user have to do is a
        "CD" to the program directory before starting (only on OS1.3). ;-)

        You should free the automatically allocated memory with @{"ROSFreeMem()" LINK "ROSFreeMem"}!
        Closing the ros.library unloads file automatically (if automatic
        memory allocation).@{b}

   INPUTS@{ub}
        flags - use ROSRWF_DISKWAIT if you want to load from a floppy
        length - number of bytes to load or @{"NULL" LINK "exec/types.h/File" 79} for the whole file
        offset - number of bytes to skip before reading from file
        memtype - see @{"ROSAllocMem()" LINK "ROSAllocMem"}, only neccessary if 'buffer' == @{"NULL" LINK "exec/types.h/File" 79}
        memalign - see @{"ROSAllocMem()" LINK "ROSAllocMem"}, only neccessary if 'buffer' == @{"NULL" LINK "exec/types.h/File" 79}
        name - pointer to a null-terminated string
        buffer - pointer to buffer or @{"NULL" LINK "exec/types.h/File" 79} to force an automitic memory
                 allocation@{b}

   RESULT@{ub}
        actLength - number of bytes read from file or -1 if error
        errorcode - DOS error code on failure (may be @{"NULL" LINK "exec/types.h/File" 79}!!!)
        actBuffer - points to loaded data, only valid on success (D0 <> -1)!!!@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSAllocMem()" LINK "ROSAllocMem"}, @{"ROSDiskState()" LINK "ROSDiskState"}, @{"ROSFreeMem()" LINK "ROSFreeMem"}, dos.lib/Read()

@ENDNODE
@NODE "ROSReadJoyPort" "ros.library/ROSReadJoyPort()"
@{b}

   NAME@{ub}
        ROSReadJoyPort -- return the state of the selected joy/mouse port  (V2)@{b}

   SYNOPSIS@{ub}
        portState = ROSReadJoyPort(portNumber);
        D0                         D0

        @{"ULONG" LINK "exec/types.h/File" 37} ROSReadJoyPort(@{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This function is used to determine what device is attached to the
        joy port and the current position/button state. The user may attach
        a mouse, game controller, or joystick to the port and this function
        will dynamically detect which device is attached and return the
        appropriatly formatted 'portState'.

        This function works similar to lowlevel.lib's ReadJoyport(), so look
        there for further information.
        The only exceptions is the port assignment: port0/1 joyport as usual,
        but port2/3 is assigned to the parallel port, with the appropriate
        adapter you are able to connect two extra joysticks.
        Mouse and gamecontrollers are not supported by those adapters!@{b}

   INPUTS@{ub}
        portNumber - port to read, in the range 0 to 3.@{b}

   RESULT@{ub}
        portState - bit map that identifies the device and the current state
                    of that device dependant on the type of device attached
                    (like lowlevel.lib's ReadJoyPort()).

                    The following constants from <@{"libraries/lowlevel.h" LINK "libraries/lowlevel.h/File"}>
                    are used to determine which device is attached and
                    the state of that device.

                    The type of device can be determined by applying
                    the mask @{"JP_TYPE_MASK" LINK "libraries/lowlevel.h/File" 86} to the return value and comparing
                    the resultant value with the following:

                        @{"JP_TYPE_NOTAVAIL" LINK "libraries/lowlevel.h/File" 81}        port data unavailable
                        @{"JP_TYPE_GAMECTLR" LINK "libraries/lowlevel.h/File" 82}        game controller
                        @{"JP_TYPE_MOUSE" LINK "libraries/lowlevel.h/File" 83}           mouse
                        @{"JP_TYPE_JOYSTK" LINK "libraries/lowlevel.h/File" 84}          joystick
                        @{"JP_TYPE_UNKNOWN" LINK "libraries/lowlevel.h/File" 85}         unknown device

                    If type = @{"JP_TYPE_GAMECTLR" LINK "libraries/lowlevel.h/File" 82} the bit map of portState is:
                        @{"JPF_BUTTON_BLUE" LINK "libraries/lowlevel.h/File" 96}         Blue - Stop
                        @{"JPF_BUTTON_RED" LINK "libraries/lowlevel.h/File" 97}          Red - Select
                        @{"JPF_BUTTON_YELLOW" LINK "libraries/lowlevel.h/File" 98}       Yellow - Repeat
                        @{"JPF_BUTTON_GREEN" LINK "libraries/lowlevel.h/File" 99}        Green - Shuffle
                        @{"JPF_BUTTON_FORWARD" LINK "libraries/lowlevel.h/File" 100}      Charcoal - Forward
                        @{"JPF_BUTTON_REVERSE" LINK "libraries/lowlevel.h/File" 101}      Charcoal - Reverse
                        @{"JPF_BUTTON_PLAY" LINK "libraries/lowlevel.h/File" 102}         Grey - Play/Pause
                        @{"JPF_JOY_UP" LINK "libraries/lowlevel.h/File" 110}              Up
                        @{"JPF_JOY_DOWN" LINK "libraries/lowlevel.h/File" 111}            Down
                        @{"JPF_JOY_LEFT" LINK "libraries/lowlevel.h/File" 112}            Left
                        @{"JPF_JOY_RIGHT" LINK "libraries/lowlevel.h/File" 113}           Right

                    If type = @{"JP_TYPE_JOYSTK" LINK "libraries/lowlevel.h/File" 84} the bit map of portState is:
                        @{"JPF_BUTTON_BLUE" LINK "libraries/lowlevel.h/File" 96}         Right
                        @{"JPF_BUTTON_RED" LINK "libraries/lowlevel.h/File" 97}          Fire
                        @{"JPF_JOY_UP" LINK "libraries/lowlevel.h/File" 110}              Up
                        @{"JPF_JOY_DOWN" LINK "libraries/lowlevel.h/File" 111}            Down
                        @{"JPF_JOY_LEFT" LINK "libraries/lowlevel.h/File" 112}            Left
                        @{"JPF_JOY_RIGHT" LINK "libraries/lowlevel.h/File" 113}           Right

                    If type = @{"JP_TYPE_MOUSE" LINK "libraries/lowlevel.h/File" 83} the bit map of portState is:
                        @{"JPF_BUTTON_BLUE" LINK "libraries/lowlevel.h/File" 96}         Right mouse
                        @{"JPF_BUTTON_RED" LINK "libraries/lowlevel.h/File" 97}          Left mouse
                        @{"JPF_BUTTON_PLAY" LINK "libraries/lowlevel.h/File" 102}         Middle mouse
                        @{"JP_MVERT_MASK" LINK "libraries/lowlevel.h/File" 118}           Mask for vertical counter
                        @{"JP_MHORZ_MASK" LINK "libraries/lowlevel.h/File" 117}           Mask for horizontal counter@{b}

   NOTE@{ub}
        When called the first time, for each port, this function tries to
        allocate the desired port, so do @{"NOT" LINK "intuition/intuition.h/File" 1501} call this routine from interrupts
        until the approprite resources are allocated (return value other than
        @{"JP_TYPE_NOTAVAIL" LINK "libraries/lowlevel.h/File" 81}, see also @{"ROSSetJoyPortAttrs()" LINK "ROSSetJoyPortAttrs"}).
        If allocation failed a Retry/Cancel-Requester appears to inform the
        user about the problem (if not suppressed and if not in deathmode)
        and the function will return @{"JP_TYPE_NOTAVAIL" LINK "libraries/lowlevel.h/File" 81}.

        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"} when
        called the first time!@{b}

   SEE ALSO@{ub}
        @{"ROSSetJoyPortAttrs()" LINK "ROSSetJoyPortAttrs"}, lowlevel.lib/ReadJoyPort()

@ENDNODE
@NODE "ROSRemTimerInt" "ros.library/ROSRemTimerInt()"
@{b}

   NAME@{ub}
        ROSRemTimerInt -- remove a previously installed timer interrupt@{b}

   SYNOPSIS@{ub}
        ROSRemTimerInt(intHandle);
                       A1

        @{"VOID" LINK "exec/types.h/File" 25} @{"AddTimerInt" LINK "ROSAddTimerInt"}(@{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        Removes a timer interrupt routine previously installed with
        @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}.

        Closing the ros.library removes this timer interrupt automatically.@{b}

   INPUTS@{ub}
        intHandle - handle obtained from @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}, if @{"NULL" LINK "exec/types.h/File" 79} nothing
                    happens@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}, @{"ROSStartTimer()" LINK "ROSStartTimer"}, @{"ROSStopTimer()" LINK "ROSStopTimer"}, @{"ROSSetTimerVec()" LINK "ROSSetTimerVec"}

@ENDNODE
@NODE "ROSRequester" "ros.library/ROSRequester()"
@{b}

    NAME@{ub}
        ROSRequester -- Display a requester@{b}

    SYNOPSIS@{ub}
        result = ROSRequester(TextFormat, ArgList, GadgetFormat)
        D0                    A0          A1       A2

        @{"LONG" LINK "exec/types.h/File" 36} ROSRequester(@{"STRPTR" LINK "exec/types.h/File" 52}, @{"APTR" LINK "exec/types.h/File" 34}, @{"STRPTR" LINK "exec/types.h/File" 52})@{b}

    FUNCTION@{ub}
        This procedure automatically builds a requester for you using
        intuition's EasyRequestArgs() (AutoRequest() on OS1.3) and then
        waits for a response from the user.

        The requester appears only if it is not disabled via @{"ROSDisableReq()" LINK "ROSDisableReq"}
        or your tasks pr_WindowPtr = -1.
        Do not set this pointer directly. Use instead ROSDisable()/ROSEnable().
        By default requesters are enabled.

        In deathmode requesters are always disabled.
        If requesters are disabled the 'result' will be always @{"FALSE" LINK "exec/types.h/File" 76} (@{"NULL" LINK "exec/types.h/File" 79}).@{b}

    INPUTS@{ub}
        TextFormat - Format string, a la RawDoFmt(), for message in
            requester body. Lines are separated by the newline character ($0A).
            Formatting '%' functions are supported exactly as in RawDoFmt().
            Note: on OS1.3 max 5 textlines
        GadgetFormat - Format string for gadgets.  Text for separate
            gadgets is separated by '|'. You MUST specify at least one gadget.
            Note: max 2 gadgets on OS1.3
                  gadget format functions only supported on OS2.0+.
        argList - Arguments for format commands. Arguments for gadgets
                  follow arguments for bodytext@{b}

    RESULT@{ub}
        0, 1, ..., N - Successive GadgetID values, for the gadgets
                       you specify for the requester.  NOTE: The numbering
                       from left to right is actually: 1, 2, ..., N, 0.
                       This is for compatibility with AutoRequest(), which has
                       @{"FALSE" LINK "exec/types.h/File" 76} for the rightmost gadget.@{b}

    BUGS@{ub}
        Do not rely on the 'result' of an one-button requester!
        Due a bug in intuitions AutoRequest()/EasyRequestArgs() the 'result'
        may be @{"TRUE" LINK "exec/types.h/File" 73} (1) or @{"FALSE" LINK "exec/types.h/File" 76} (0) because it's possible to satisfy an one-
        button requester with both short-cuts: AMIGA-B and AMIGA-V.@{b}

    SEE ALSO@{ub}
        intuition.lib/AutoRequest(), intuition.lib/EasyRequestArgs(),
        exec.lib/RawDoFmt(), @{"ROSDisableReq()" LINK "ROSDisableReq"}, @{"ROSEnableReq()" LINK "ROSEnableReq"}

@ENDNODE
@NODE "ROSScreenToBack" "ros.library/ROSScreenToBack()"
@{b}

    NAME@{ub}
        ROSScreenToBack -- Send ROS screen to the back of the display@{b}

    SYNOPSIS@{ub}
        ROSScreenToBack()

        @{"VOID" LINK "exec/types.h/File" 25} ROSScreenToBack(@{"VOID" LINK "exec/types.h/File" 25});@{b}

    FUNCTION@{ub}
        Sends the ROS screen to the back of the display if it is open and
        if @{"NOT" LINK "intuition/intuition.h/File" 1501} in deathmode.@{b}

    SEE ALSO@{ub}
        @{"ROSScreenToFront()" LINK "ROSScreenToFront"}

@ENDNODE
@NODE "ROSScreenToFront" "ros.library/ROSScreenToFront()"
@{b}

    NAME@{ub}
        ROSScreenToFront -- Make ROS screen the frontmost@{b}

    SYNOPSIS@{ub}
        ROSScreenToFront()

        @{"VOID" LINK "exec/types.h/File" 25} ROSScreenToFront(@{"VOID" LINK "exec/types.h/File" 25});@{b}

    FUNCTION@{ub}
        Brings the ROS screen to the front of the display if it is open and
        if @{"NOT" LINK "intuition/intuition.h/File" 1501} in deathmode.@{b}

    SEE ALSO@{ub}
        @{"ROSScreenToBack()" LINK "ROSScreenToBack"}

@ENDNODE
@NODE "ROSSetCache" "ros.library/ROSSetCache()"
@{b}

   NAME@{ub}
        ROSSetCache -- Instruction & data cache control@{b}

   SYNOPSIS@{ub}
        oldBits = ROSSetCache(cacheBits, cacheMask)
        D0                    D0         D1

        @{"ULONG" LINK "exec/types.h/File" 37} ROSSetCache(@{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This function provides global control of any instruction or data
        caches that may be connected to the system.  All settings are
        global (until ros.library closed) -- per task control is not provided.

        Closing the ros.library reset former system cache settings.@{b}

   INPUTS@{ub}
        cacheBits - new values for the bits specified in cacheMask.
                    use -1 to reset to system defaults (ignores cacheMask)
        cacheMask - a mask with ones for all bits to be changed

        Note: cacheBits/cacheMask may be overridden by values specified in
              ros.prefs (to support individual cache settings)@{b}

   RESULT@{ub}
        oldBits - the complete prior values for all settings.@{b}

   NOTE@{ub}
        As a side effect, this function clears all caches.
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        exec/execbase.i, exec.lib/CacheControl()

@ENDNODE
@NODE "ROSSetCopper" "ros.library/ROSSetCopper()"
@{b}

   NAME@{ub}
        ROSSetCopper -- install copperlist for ROS screen@{b}

   SYNOPSIS@{ub}
        ROSSetCopper(flags, coplist)
                     D0     A0

        @{"VOID" LINK "exec/types.h/File" 25} ROSSetCopper(@{"ULONG" LINK "exec/types.h/File" 37}, @{"APTR" LINK "exec/types.h/File" 34});@{b}

   FUNCTION@{ub}
        This function installs a new copper list for our ROS screen.
        Whenever this screen is the frontmost this copper list becomes the
        active (only in non-os-friedly mode!).

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use "move.l #mycoplist,$dff080" or "move.w #0,$dff088" !!!!!!!
        This may crash the display if you are in non-deathmode and the ROS
        screen is not yet available or behind others.
        ROSSetCopper() takes this into account and displays this copper list as
        soon as possible.

        A screen switch forces always copper1 starting in a long frame!@{b}

   INPUTS@{ub}
        flags - COPF_COPPER1/2: modify copper1 or copper2
                    Remember: copper1 is always started during vertical blank
                COPF_STROBE: force an immediate copper start, move.w #0,$dff088
                    set 'coplist' to @{"NULL" LINK "exec/types.h/File" 79} for only strobe
                COPF_LOF/SHF: forces a long/short frame while starting copper
                    (to display interlaced screens correctly)
        coplist - copper list pointer, if @{"NULL" LINK "exec/types.h/File" 79} the old copper pointer remains@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers (except D0!!!) and is
        save to call from interrupts.@{b}

   SEE ALSO@{ub}
        libraries/ros.i, @{"ROSKillSystem()" LINK "ROSKillSystem"}

@ENDNODE
@NODE "ROSSetDMA" "ros.library/ROSSetDMA()"
@{b}

   NAME@{ub}
        ROSSetDMA -- modify DMA bits@{b}

   SYNOPSIS@{ub}
        ROSSetDMA(DMACON)
                  D0

        @{"VOID" LINK "exec/types.h/File" 25} ROSSetDMA(@{"UWORD" LINK "exec/types.h/File" 40});@{b}

   FUNCTION@{ub}
        This function acts like a write to the DMACON register.

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use "move.w #xxx,$dff096" !!!!!!!
        This may interfere with the system you are in non-deathmode, but
        ROSSetDMA() handles all exceptions correctly.

        DMA bit modification:
          - DMAF_BLTPRI: only in deathmode, but during a @{"ROSSysCall()" LINK "ROSSysCall"} the
                         system DMA bit will be restored
          - DMAF_DMAEN: same like BLTPRI
          - DMAF_BPLEN: only if ROS screen in front (non-os-friendly mode!)
          - DMAF_COPEN: same like BPLEN
          - DMAF_BLTEN: same like BLTPRI
          - DMAF_SPREN: same like BPLEN
          - DMAF_DSKEN: never modified!!!
          - DMAF_AUDxEN: only if audio channels allocated

        A currently forbidden DMA modification is automatically updated as
        soon as possible (e.g. bitplane DMA if ROS screen behind others).

        Closing the ros.library reset former system DMA.@{b}

   INPUTS@{ub}
        DMACON - DMA bits@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers (except D0!!!) and is
        save to call from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSGetDMA()" LINK "ROSGetDMA"}, hardware/dmabits.i

@ENDNODE
@NODE "ROSSetExitHandler" "ros.library/ROSSetExitHandler()"
@{b}

   NAME@{ub}
        ROSSetExitHandler -- add handler that is executed at exit key condition@{b}

   SYNOPSIS@{ub}
        ROSSetExitHandler(handler);
                          A0

        @{"VOID" LINK "exec/types.h/File" 25} ROSSetExitHandler(@{"APTR" LINK "exec/types.h/File" 34});@{b}

   FUNCTION@{ub}
        Calling this routine causes the ROS to install an exit key conditon
        handler. Whenever this special key is pressed your handler is invoked
        (should be only once). Now it's time to finish your application.

        The routine is called from within an interrupt, so normal
        restrictions apply. On entry A5 holds the custom base ($dff000) and
        A6 holds _ROSBase. Your code may trash all registers.

        The default exit key code is ESC but may be changed in ros.prefs.
        --> New for V2: Now joyport events may also generate exit events if
                        enabled via @{"ROSSetJoyPortAttrs()" LINK "ROSSetJoyPortAttrs"}.

        You should remove this handler with ROSSetExitHandler(@{"NULL" LINK "exec/types.h/File" 79}).
        Closing the ros.library removes this exit handler automatically.

        But remember: Exit conditions occurs only if you set the master
                      interrupt bit via @{"ROSSetInt" LINK "ROSSetInt"}(@{"INTF_INTEN" LINK "hardware/intbits.h/File" 35})!@{b}

   INPUTS@{ub}
        handler - the routine to invoke upon exit key condition or @{"NULL" LINK "exec/types.h/File" 79} to
                  detach the handler@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers (except A0!!!) and is
        save to call from interrupts.

        The handler may be called more than once if your application isn't
        fast enough to exit!!!@{b}

   SEE ALSO@{ub}

@ENDNODE
@NODE "ROSSetInt" "ros.library/ROSSetInt()"
@{b}

   NAME@{ub}
        ROSSetInt -- modify interrupt settings@{b}

   SYNOPSIS@{ub}
        ROSSetInt(INTENA)
                  D0

        @{"VOID" LINK "exec/types.h/File" 25} ROSSetInt(@{"UWORD" LINK "exec/types.h/File" 40});@{b}

   FUNCTION@{ub}
        This function acts like a write to the INTENA register.

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use "move.w #xxx,$dff09a" !!!!!!!
        This may interfere with the system if you are in non-deathmode, but
        ROSSetInt() handles all exceptions correctly.

        Only those bits are affected which belongs to previous @{"ROSSetIntVec()" LINK "ROSSetIntVec"}
        calls. Look at @{"ROSSetIntVec()" LINK "ROSSetIntVec"} for further information.

        In non-deathmode the master interrupt bit (@{"INTB_INTEN" LINK "hardware/intbits.h/File" 16}) is emulated to
        support enable/disable of all ROS interrupts at once (system interrupts
        are still active!!!)

        Closing the ros.library reset former system interrupt bits.@{b}

   INPUTS@{ub}
        INTENA - Int bits
                 Note: level 1/2/5/6 bits (disk, serial, timer) are not
                       supported!!!
                       Instead additonal bits are defined:  - KEYB
                                                            - CIAATIMA/B
                                                            - CIABTIMA/B
                 Look at @{"ROSSetIntVec()" LINK "ROSSetIntVec"} for further details@{b}
   NOTE@{ub}
        This call is guaranteed to preserve all registers (except D0!!!).

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} call this routine from interrupts if you want to modify the
        CIA interrupts (CIAATIMA/B, CIABTIMA/B)!!!!@{b}

   SEE ALSO@{ub}
        @{"ROSGetInt()" LINK "ROSGetInt"}, @{"ROSSetIntVec()" LINK "ROSSetIntVec"}, libraries/ros.i

@ENDNODE
@NODE "ROSSetIntVec" "ros.library/ROSSetIntVec()"
@{b}

   NAME@{ub}
        ROSSetIntVec -- set a new handler for an interrupt vector@{b}

   SYNOPSIS@{ub}
        success = ROSSetIntVec(intNum, handler)
        D0                     D0      A0

        @{"BOOL" LINK "exec/types.h/File" 69} ROSSetIntVec(@{"UWORD" LINK "exec/types.h/File" 40}, @{"APTR" LINK "exec/types.h/File" 34});@{b}

   FUNCTION@{ub}
        This function attaches a new handler to the interrupt specified with
        'intNum'. Detach a handler with A0 = @{"NULL" LINK "exec/types.h/File" 79}.
        The routine is called from within an interrupt, so normal
        restrictions apply. On entry A5 holds the custom base ($dff000) and
        A6 holds _ROSBase. Your code may trash all registers.
        Your handler won't be invoked until you enable it (and the master int)
        via @{"ROSSetInt()" LINK "ROSSetInt"}. After enabling your handler it's always invoked
        whether you taken over the systen or not.

        Interrupts are executed as follows:

        » @{"INTB_BLIT" LINK "hardware/intbits.h/File" 24}
            - only in deathmode, during a @{"ROSSysCall()" LINK "ROSSysCall"} the system routine
              will be restored so you do @{"NOT" LINK "intuition/intuition.h/File" 1501} use the blitter while the system
              is (partially) active
            - returncode is always @{"TRUE" LINK "exec/types.h/File" 73}
        » @{"INTB_VERTB" LINK "hardware/intbits.h/File" 25}
            - always invoked, also without a call to @{"ROSKillSystem()" LINK "ROSKillSystem"}
            - in non-deathmode your vblank code may be called after display
              is started depending on the speed of higher prioritized vblank
              interrupts. If you want to synchronize custom chip modifications
              with the display you should use the copper.
            - but remember: in non-deathmode the vblank frequency may vary
              (not always 50Hz) if ROS screen behind others!
            - returncode is always @{"TRUE" LINK "exec/types.h/File" 73}
        » @{"INTB_COPER" LINK "hardware/intbits.h/File" 26}
            - only if ROS screen in front
            - returncode is always @{"TRUE" LINK "exec/types.h/File" 73}
        » @{"INTB_NMI" LINK "exec/interrupts.h/File" 44} (bit 15)
            - always invoked
            - returncode is always @{"TRUE" LINK "exec/types.h/File" 73}
        » @{"INTB_AUD0" LINK "hardware/intbits.h/File" 23}..3
            - only if channels allocated, else the returncode will be @{"FALSE" LINK "exec/types.h/File" 76}

        Further 5 new int definitions are supported:

        » INTB_CIAATIMA/CIAATIMB/CIABTIMA/CIABTIMB
            - used to attach a handler to the specified CIA timer
            - returncode may be @{"FALSE" LINK "exec/types.h/File" 76} if CIA allocation failed, in this case a
              Retry/Cancel-Requester appears (if not suppressed)
            - if returncode @{"TRUE" LINK "exec/types.h/File" 73} the specified timer bits are set to 0 (timer
              stopped) and now you may modify the contents of the CIA control
              register (CRA/CRB)
            - never read or write the CIA interrupt control register (ICR),
              use instead @{"ROSSetInt()" LINK "ROSSetInt"} to enable/disble CIA interrupts!!!!!!

        » INTB_KEYB
            - used to track keyboard events (see also @{"ROSGetKey()" LINK "ROSGetKey"})
            - only invoked if ROS screen in front!!!
            - your handler is called with additional register D0 setup:
                * the lower word contains the keycode ($0..$67) with the
                  additional key_up/down flag (bit7 set for key-up condition)
                * the upper word contains the qualifier bits (shift, alt, ...)
            - in non-deathmode it's up to you passing this key to other system
              components (like intuition.lib, commodities.lib, ...)
                * set the ZERO-flag at the end of your handler to pass the key
                  to other system components, e.g.  moveq #0,d0
                * else clear the ZERO-flag, e.g.  moveq #1,d0
                * but remember: if you catch all key events screen switching
                  and other system hotkeys dosn't work!!!
                * by default all keys without left-amiga or without control
                  qualifiers are catched to prevent background menu activities
                  and other undesirable things
            - returncode is always @{"TRUE" LINK "exec/types.h/File" 73}

        All other interrupt bits are @{"NOT" LINK "intuition/intuition.h/File" 1501} supported!!!

        Closing the ros.library detaches interrupt handlers automatically.@{b}

   INPUTS@{ub}
        intnum - the Paula interrupt bit number (0 through 14). Processor
                 level seven interrupts (NMI) are encoded as intNum 15.
                 Note: level 1/2/5/6 bits (disk, serial, timer) are not
                       supported!!!
                       Instead additonal bits are defined:  - KEYB
                                                            - CIAATIMA/B
                                                            - CIABTIMA/B
        handler - the routine to invoke or @{"NULL" LINK "exec/types.h/File" 79} to detach the handler@{b}

   RESULT@{ub}
        success - @{"TRUE" LINK "exec/types.h/File" 73} if handler successfully attached@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all other registers.

        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} call this routine from interrupts if you want to add a CIA
        handler for the first time!!! After a successful call you may change
        this vector with ROSSetIntVec() also from interrupts because the
        desired CIA is already allocated.@{b}

   SEE ALSO@{ub}
        @{"ROSSetInt()" LINK "ROSSetInt"}, @{"ROSGetInt()" LINK "ROSGetInt"}, libraries/ros.i

@ENDNODE
@NODE "ROSSetJoyPortAttrs" "ros.library/ROSSetJoyPortAttrs()"
@{b}

   NAME@{ub}
        ROSSetJoyPortAttrs -- change attributes of a joy port  (V2)@{b}

   SYNOPSIS@{ub}
        success = ROSSetJoyPortAttrs(portNumber, attribute);
        D0                           D0          D1

        @{"BOOL" LINK "exec/types.h/File" 69} ROSSetJoyPortAttrs(@{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This function allows modification of several attributes held by
        @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"} about both it's operation and the type of controller
        currently plugged into the port.

        @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"}'s default behavior is to attempt to automatically
        sense the type of controller plugged into any given port, when
        asked to read that port. This causes most reads to take longer than
        if there were no auto-sensing.
        That's why ROSSetJoyPortAttrs() allows the programmer to notify
        @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"} to stop spending time attempting to sense which type
        of controller is in use -- and, optionally, to force @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"}
        into utilizing a certain controller type.

        This function is also used to turn on the rawkey code creation for the
        given port. This means @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"} is called every frame to
        determine current port state and it's return values are converted into
        corresponding rawkey codes. To reduce the overhead caused by this
        attribute you should avoid the autosensing!
        ROS uses the same rawkey codes like lowlevel.library so look there
        (libraries/lowlevel.i) for further information.@{b}

   INPUTS@{ub}
        portNumber - the joyport in question (0-3).
        attribute  - one of the following attributes (from libraries/ros.i):

            » ROSJPA_AUTOSENSE
                - @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"} will attempt to determine the type of
                  controller plugged into the given port automatically
                - returns @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded
            » ROSJPA_MOUSE
                - sets current controller type to mouse
                - returns @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded
            » ROSJPA_JOYSTCK
                - sets current controller type to joystick
                - returns @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded
            » ROSJPA_GAMECTLR
                - sets current controller type to game controller
                - returns @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded
            » ROSJPA_ADDKEYS
                - starts creating rawkey codes for the joystick/game controller
                  on the given unit, codes are passed to your keyboard-handler
                  (see also @{"ROSSetIntVec()" LINK "ROSSetIntVec"}) so the same restrictions apply:
                  - only invoked if ROS screen in front!!!
                  - your handler is called with additional register D0 setup:
                      * the lower word contains the keycode with the additional
                        key_up/down flag (bit7 set for key-up condition)
                      * the upper word contains the qualifier bits
                  - but:
                      * these rawkey codes are NEVER passed to other system
                        components (like intuition), only you will receive it!
                      * in addition to the keyboard interrupt (@{"INTB_INTEN" LINK "hardware/intbits.h/File" 16}/KEYB)
                        the vblank interrupt (@{"INTB_VERTB" LINK "hardware/intbits.h/File" 25}) must be active
                - NOTE (1): Now your keyboard-handler is also called from a
                            level3 interrupt. That's why it must be reentrant!!
                            (reason: joystick-movement (lev3) may interrupt a
                            currently in-progress keypress-event (lev2))
                - NOTE (2): Your handler may be called more than once per frame
                            because multiple joy-movements generate multiple
                            keycodes!
                - NOTE (3): Now your exit-handler must also be reentrant
                            because joyport events may generate exit events!
                - returns @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded
            » ROSJPA_REMKEYS
                - stops rawkey code creation on the given unit
                - returns always @{"TRUE" LINK "exec/types.h/File" 73}, whether port allocated or not!!!
            » ROSJPA_REINITIALIZE
                - return a given port to it's initial state:
                    * set to autosense
                    * stop rawkey code creation
                    * deallocate resources
                - closing the ros.library reinitializes joy ports automatically
                - returns always @{"TRUE" LINK "exec/types.h/File" 73}, whether port allocated or not!!!@{b}

   RESULT@{ub}
        success - @{"TRUE" LINK "exec/types.h/File" 73} if port allocation succeeded, or @{"FALSE" LINK "exec/types.h/File" 76} upon failure@{b}

   NOTE@{ub}
        When called the first time, for each port, this function tries to
        allocate the desired port. Once it returns @{"TRUE" LINK "exec/types.h/File" 73} (except for ROSJPA_
        REMKEYS/REINITIALIZE) the appropriate port is allocated and you may
        call @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"} from interrupts.
        If allocation failed a Retry/Cancel-Requester appears to inform the
        user about the problem (if not suppressed and if not in deathmode)
        and this function will return @{"FALSE" LINK "exec/types.h/File" 76}.

        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSReadJoyPort()" LINK "ROSReadJoyPort"}, <libraries/lowlevel.i>

@ENDNODE
@NODE "ROSSetTimerVec" "ros.library/ROSSetTimerVec()"
@{b}

   NAME@{ub}
        ROSSetTimerVec -- change the timer interrupt entry point@{b}

   SYNOPSIS@{ub}
        ROSSetTimerVec(intRoutine, intHandle);
                       A0          A1

        @{"VOID" LINK "exec/types.h/File" 25} ROSSetTimerVec(@{"APTR" LINK "exec/types.h/File" 34}, @{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This routine changes the interrupt entry point that is assocatied with
        a timer interrupt created by @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}.
        No timer modification is done (no restart, no stop). The next interrupt
        will execute your new 'intRoutine'.@{b}

   INPUTS@{ub}
        intRoutine - the routine to invoke upon timer interrupts.
        intHandle - handle obtained from @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}.@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers (except A1!!!) and is
        save to call from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}, @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}, @{"ROSStartTimer()" LINK "ROSStartTimer"}, @{"ROSStopTimer()" LINK "ROSStopTimer"}

@ENDNODE
@NODE "ROSStartTimer" "ros.library/ROSStartTimer()"
@{b}

   NAME@{ub}
        ROSStartTimer -- start the timer associated with the timer interrupt@{b}

   SYNOPSIS@{ub}
        ROSStartTimer(timeInterval, continuous, intHandle);
                      D0            D1          A1

        @{"VOID" LINK "exec/types.h/File" 25} ROSStartTimer(@{"ULONG" LINK "exec/types.h/File" 37}, @{"BOOL" LINK "exec/types.h/File" 69}, @{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        This routine starts a stopped timer that is assocatied with a
        timer interrupt created by @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}.

        But remember: Timer interupts occurs only if you set the master
                      interrupt bit via @{"ROSSetInt" LINK "ROSSetInt"}(@{"INTF_INTEN" LINK "hardware/intbits.h/File" 35})!@{b}

   INPUTS@{ub}
        timeInterval - number of micoseconds between interrupts. The
                       maximum value allowed is 90,000. If higher values
                       are passed there will be unexpected results.
        continuous - @{"FALSE" LINK "exec/types.h/File" 76} for a one shot interrupt. @{"TRUE" LINK "exec/types.h/File" 73} for multiple
                     interrupts.
        intHandle - handle obtained from @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}.@{b}

   NOTE@{ub}
        This call is guaranteed to preserve register A0 and is save to call
        from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}, @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}, @{"ROSSetTimerVec()" LINK "ROSSetTimerVec"}, @{"ROSStopTimer()" LINK "ROSStopTimer"}

@ENDNODE
@NODE "ROSStopTimer" "ros.library/ROSStopTimer()"
@{b}

   NAME@{ub}
        ROSStopTimer -- stop the timer associated with the timer interrupt@{b}

   SYNOPSIS@{ub}
        ROSStopTimer(intHandle);
                     A1

        @{"VOID" LINK "exec/types.h/File" 25} ROSStopTimer(@{"ULONG" LINK "exec/types.h/File" 37});@{b}

   FUNCTION@{ub}
        Stops the timer associated with the timer interrupt handle passed.
        This is used to stop a continuous timer started by
        @{"ROSStartTimer()" LINK "ROSStartTimer"}.@{b}

   INPUTS@{ub}
        intHandle - handle obtained from @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers (except A1!!!) and is
        save to call from interrupts.@{b}

   SEE ALSO@{ub}
        @{"ROSAddTimerInt()" LINK "ROSAddTimerInt"}, @{"ROSRemTimerInt()" LINK "ROSRemTimerInt"}, @{"ROSSetTimerVec()" LINK "ROSSetTimerVec"}, @{"ROSStartTimer()" LINK "ROSStartTimer"}

@ENDNODE
@NODE "ROSSysCall" "ros.library/ROSSysCall()"
@{b}

   NAME@{ub}
        ROSSysCall -- interrupts deathmode to enable system calls@{b}

   SYNOPSIS@{ub}
        ROSSysCall()

        @{"VOID" LINK "exec/types.h/File" 25} ROSSysCall(@{"VOID" LINK "exec/types.h/File" 25})@{b}

   FUNCTION@{ub}
        This function provides a method to call system functions from within
        deathmode.

        YOU SHOULD NEVER NEED THIS FUNCTION! IT SHOULD BE A PRIVATE ROS CALL.
        DO @{"NOT" LINK "intuition/intuition.h/File" 1501} USE THIS CALL WITHOUT GOOD JUSTIFICATION.

        In order to restore normal deathmode, the programmer must execute
        exactly one call to @{"ROSSysCallEnd()" LINK "ROSSysCallEnd"} for every call to ROSSysCall().

        During a SysCall all ROS interrupts continue executing (look at
        @{"ROSSetIntVec()" LINK "ROSSetIntVec"} for details).
        But remember: system interrupts are also active and additional system
        DMA will be set!
        The blitter will be disowned so you do @{"NOT" LINK "intuition/intuition.h/File" 1501} bash the blitter until
        @{"ROSSysCallEnd()" LINK "ROSSysCallEnd"} is called.
        With ROS V2 WaitBlit() is also called before entering the system.
        Do @{"NOT" LINK "intuition/intuition.h/File" 1501} call system functions during a SysCall which may cause any
        visual modifications (like OpenScreen(), ScreenToBack(), ...).
        These functions will never return as long as the deathmode is the
        active one!!!

        Calling ROSSysCall() without a deathmode killed system is harmless.@{b}

   RESULT@{ub}
        A partially active system.@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers.@{b}

   SEE ALSO@{ub}
        @{"ROSKillSystem()" LINK "ROSKillSystem"}, @{"ROSSetDMA()" LINK "ROSSetDMA"}, @{"ROSSetIntVec()" LINK "ROSSetIntVec"}, @{"ROSSysCallEnd()" LINK "ROSSysCallEnd"}

@ENDNODE
@NODE "ROSSysCallEnd" "ros.library/ROSSysCallEnd()"
@{b}

   NAME@{ub}
        ROSSysCallEnd -- return from a SysCall@{b}

   SYNOPSIS@{ub}
        ROSSysCallEnd()

        @{"VOID" LINK "exec/types.h/File" 25} ROSSysCallEnd(@{"VOID" LINK "exec/types.h/File" 25})@{b}

   FUNCTION@{ub}
        Call this function to return from a SysCall after a matching
        @{"ROSSysCall()" LINK "ROSSysCall"} has been executed.@{b}

   RESULT@{ub}
        A deathmode killed system.@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers.@{b}

   SEE ALSO@{ub}
        @{"ROSSysCall()" LINK "ROSSysCall"}

@ENDNODE
@NODE "ROSWaitVBlank" "ros.library/ROSWaitVBlank()"
@{b}

   NAME@{ub}
       ROSWaitVBlank -- Wait for the vertical blank to occur@{b}

   SYNOPSIS@{ub}
       ROSWaitVBlank()

       @{"VOID" LINK "exec/types.h/File" 25} ROSWaitVBlank(@{"VOID" LINK "exec/types.h/File" 25});@{b}

   FUNCTION@{ub}
       Waits for vertical blank to occur and than returns to the caller.
       --> New for V2: If not in real deathmode this function uses the
                       graphics.library WaitTOF() call to ensure
                       compatibility with foreign OS screens!@{b}

   NOTE@{ub}
        This call is guaranteed to preserve all registers.
        This call does not require A6 to be loaded with the library base.@{b}

   BUGS@{ub}
        Previous V1.xx documentation stated:  "... and is save to call from
        interrupts."
        This is always wrong! Do @{"NOT" LINK "intuition/intuition.h/File" 1501} use this function from within interrupts!

@ENDNODE
@NODE "ROSWriteFile" "ros.library/ROSWriteFile()"
@{b}

   NAME@{ub}
        ROSWriteFile -- Write a number bytes to a file@{b}

   SYNOPSIS@{ub}
        actLength/errorcode = ROSWriteFile(flags, length, offset, name, buffer)
        D0        D1                       D0     D1      D2      A0    A1

        @{"ULONG" LINK "exec/types.h/File" 37}/@{"ULONG" LINK "exec/types.h/File" 37} ROSWriteFile(@{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37}, @{"ULONG" LINK "exec/types.h/File" 37}, @{"STRPTR" LINK "exec/types.h/File" 52}, @{"VOID" LINK "exec/types.h/File" 25} *);@{b}

   FUNCTION@{ub}
        This function writes 'length' bytes to the file 'name' using
        dos.library's Write().
        Set 'offset' to @{"NULL" LINK "exec/types.h/File" 79} to overwrite an existing file (file opened with
        @{"MODE_NEWFILE" LINK "dos/dos.h/File" 28}). In the other case the data is written to the file 'name'
        with an 'offset' from the beginning (file opened with @{"MODE_READWRITE" LINK "dos/dos.h/File" 30}).
        This can be used to append/replace data to/in an existing file. If the
        file doesn't exists or if filelength shorter than 'offset' a seek error
        occurs.
        A1 points to a buffer from where the data is taken from.

        Remember: On error a corrupt or a 0-byte-file may still exists!!!
                  It's up to you to delete this.

        If ROSRWF_DISKWAIT flag set the routine assumes that you want to write
        'name' to a floppy. This means:
         - waiting for the right disk to be inserted
           (implementation: DOS error codes DEVICE_NOT_MOUNTED, NOT_A_DOS_DISK,
           NO_DISK force retry until any other error occurs)
           --> New for V2: waiting may be cancelled via @{"ROSDiskState()" LINK "ROSDiskState"}
         - waiting until disk drive stopped
           (implementation: polling disk.resource until drives are ready)

        Since OS2.0 it's possible to write files to your program path instead
        of the current directory using progdir:xxx.
        On OS1.3 the "progdir:" string is automatically removed by ROS so you
        don't have to worry about it. The only thing the user have to do is a
        "CD" to the program directory before starting (only on OS1.3). ;-)

        WARNING: It may be dangerous to use this routine within deathmode!
                 Because of the AMIGA's multitasking facilities it isn't
                 possible (isn't it???) to wait till the final end of a write
                 operation. That's why I use a simple delay of 2 seconds after
                 any write operation in deathmode. If your filesystem is to
                 slow to write all the data within this time your partition
                 will be @{"NOT" LINK "intuition/intuition.h/File" 1501} validated!!!
                 You've been warned!!!@{b}

   INPUTS@{ub}
        flags - use ROSRWF_DISKWAIT if you want to write to a floppy
        length - number of bytes to write
        offset - @{"NULL" LINK "exec/types.h/File" 79} for overwrite mode, else a number of bytes to skip
                 before writing into an existing file
        name - pointer to a null-terminated string
        buffer - pointer to buffer where data is taken from@{b}

   RESULT@{ub}
        actLength - number of bytes written or -1 if error
        errorcode - DOS error code on failure (may be @{"NULL" LINK "exec/types.h/File" 79}!!!)@{b}

   NOTE@{ub}
        This function interrupts the deathmode state with @{"ROSSysCall()" LINK "ROSSysCall"}!@{b}

   SEE ALSO@{ub}
        @{"ROSDeleteFile()" LINK "ROSDeleteFile"}, @{"ROSDiskState()" LINK "ROSDiskState"}, dos.lib/Write()

@ENDNODE
