Hardware Independent Device Drivers
Note
This document is currently only a draft and as such will most likely change
before it is accepted as an official specification. It might also be
deprecated if a better approach has been found in the mean time, and
doesn't necessarily correspond precisely with the current implementations.
A HIDD is a Hardware Independent Device Driver - a collection of code
that provides an interface to hardware that hides as many details of
the hardware as practical. Most applications do not need to know all
the details of the device they use, they simply want to get on with
using the device.
As we are implementing the Amiga Operation System we still want to
support the existing software that runs on this platform. This means
that we need to also provide an interface to the Exec style devices.
With this in mind, the design goals of the HIDD system are:
- Hardware independent interfaces
- The interface that the driver presents should be independent of the
underlying hardware. It should provide as much of the functionality of that
device as possible.
- Compatibility with AmigaOS
- There is a large amount of software either with source or binary only that
uses the Amiga style device drivers. We should provide a way of keeping
this software working, but without too much of a speed/compatibility
problem.
- Interface reuse
- Many interfaces provide common functionality - for example SCSI, IDE and
floppy disk drives all provide a way of writing blocks to disk. We should
use this to allow code to work on any kinds of these devices simply by
changing the device name.
- Code reuse
- Many device implementations share common facilities that allow them to
reuse code. There are a number of Ethernet cards available that, whilst
they may work on PCI, ISA or Zorro buses, share the same chip set but
differ in access methods. We should attempt to provide the ability to use
the same driver code. This has benefits in terms of code testing and
reliability, and also the reduced number of drivers that need to be
written.
- Dynamic Properties
- Device drivers should be dynamically loadable and unloadable from the
system - this helps with systems with low memory, removable hardware and
most importantly, works well with the AmigaOS philosophy.
- Language Independence
- Whilst true language independence is quite difficult, the interface design
has been constructed so that it is relatively simple to add calling
methods for different languages. To help with this the interfaces shall be
described in some kind of interface description language
(such as OMG IDL), and this will be processed to generate the required
header files, and class glue files. The language used for most drivers
will be C.
To implement the code and interface reuse design goal we have implemented
our drivers in an object-oriented fashion, providing single
inheritance but multiple interfaces (similar to the Java language).
The inheritance hierarchy allows us to start with a basic driver, and
enhance this by adding more levels of device dependence until we come
to a driver for a specific device.
To provide a method of dynamic driver-functionality the driver objects
are arranged in a tree that shows their connection mechanism. For example,
a PCI-based Ethernet card is connected to a PCI bus, so the Ethernet card
driver is a child of the PCI bus. Similar an IDE hard disk is normally
connected to an IDE controller - so the disk will be a child of the
IDE controller.
Note
This does not mean that the Ethernet card driver is a subclass of
the bus driver. Only the dynamic behaviour of the drivers is subject
to the connection-oriented approach.
A few concepts are hidden in all the above. To begin with, knowledge
of object-oriented programming is assumed for this document,
as is a basic understand of device drivers. This manual is not
designed to teach either object-oriented programming or device driver
programming - both of these come only from experience. I hope that
this manual will help however - I am learning as I write it.
Throughout this manual a few terms will be used frequently and often
interchangeably, hopefully for the few times that I miss these in
editing I shall try and clarify them here.
The first two are class and device. The device is the physical
implementation of the hardware we are controlling, and the class is
the code that is controlling that hardware. You normally only have one
class for each device, although some devices may provide multiple
functions. In that case you would need to provide multiple classes for
the different functions.
The second two are object and driver. The object is an instantiated
class and this is the driver for the device. There can be a number of
drivers for the same device, but they must all control separate
devices. There will be one instantiated driver for every class of
device that exists in the system.
The HIDD system embodies a collection of object classes and a shared
library providing device driver facilities to the AROS operating
system. This chapter describes the operating model of the classes and
objects.
It consists of the following sections
- Static Model
- describing the class structure and properties that make up the
static device model.
- Object Model
- describing the object structure and connection-oriented approach
of object linkage.
- Dynamic Model
- Examining the runtime behaviour of classes and objects and the
life-cycle of a driver.
The HIDD system is broken up into a collection of classes with a
strict inheritance hierarchy. A HIDD class implements a device driver
for a single device or in rare cases a group of devices and provides
an interface for other programs and devices to access.
In order to maintain portability of interfaces across a wide range of
hardware this interface will in general not present the raw interface
to the underlying hardware. Instead it will present a generic
interface that describes many different hardware implementations. This
allows for the best reuse of both interfaces and code.
This reuse is enforced by the hierarchy of classes with common device
functions restricted to a subsection of the hierarchy. An example of
this is disk devices. There are three common disk interfaces available
today - SCSI, IDE and floppy. All these devices provide similar
functions such as the ability to read and write blocks, and determine
the geometry of the disk.
Whilst the implementations of these devices may change, the interface
does not. A file system needs to talk to a disk-like device, but it
does not care what the underlying hardware supports -- it only
requires the interface. This idea forms the first part of the
hierarchy structure - and from where the name HIDD comes. These
interfaces provide a hardware independent method of access devices.
<!-- img src="hidd-model-class-1.png" alt="HIDD Class Tree Structure" /-->
hidd
+- disk
| +- floppy
| +- ide
| +- ram
| +- scsi
| +- virtual
+- graphics
+- parallel
+- serial
If we examine the tree structure above we can see that the class tree
starts with the hidd class. This is the base class that all HIDD
classes inherit from. It provides many useful facilities dealing with
initialisation and interaction of HIDDs. A complete discussion of this
class is found in the HIDD Class chapter.
Below this there are a number of different classes, each providing a
different type of functionality. At the moment the diagram only shows
the hidd.disk tree. This contains five entries -- all
detailing slightly different kinds of devices. The
hidd.disk.virtual is a virtual disk device which
provides the ability to address a file as is it were a real device.
Similarly the hidd.disk.ram provides access to a fixed
size virtual RAM disk.
The hidd.disk.floppy provides access to the normal
floppy disk controller. The hidd.disk.ide and
hidd.disk.scsi provide access to common hard disk drive
implementations.
XXX - Where do CD-ROM's and the like fit in? They are like disk
devices, but have some other features that make them different. The
Amiga device structure had them as a disk device but with an extra
interface. I think that this is probably the way to go. But then you
have to differentiate from IDE CD-ROMs, SCSI CD-ROMs and the like. In
which case you would use hidd.cdrom... but then you have two
different interfaces on the same level declaring the same
functionality? Does this mean we actually need another level? I hope
not. An alternative would be to hidd.disk.cdrom.whatever to emphasise
that CD-ROMs are like disk devices, but with a few extra functions?
To complicate matters however the above is only half the story. There
is another half of the tree that have different semantics -- providing
access to the raw hardware. An example of this type of class would be
a SCSI controller -- something that is not always accessed by user
programs.
There are however a number of different SCSI controllers available, so
there is more specialisation of classes here.
<!-- img src="hidd-model-class-2.png" alt="HIDD Class Tree Structure" /-->
hidd
+- disk
+- graphics
+- parallel
+- scsi
| +- ...
+- serial
The above picture adds more devices into the class hierarchy. We see
now that there is a hidd.scsi subtree containing a
number of different SCSI controllers. In this case the
hidd.scsi layer provides an interface to the functions
that a SCSI bus provides, and the hidd.scsi.#? classes provide
the implementation for a specific SCSI controller.
This is still not where the story ends. These SCSI controllers may
have different ways of interfacing with the computer, and may even
have different controllers for different hardware platforms. This
introduces another layer of the tree structure.
<!--img src="hidd-model-class-3.png" alt="XXX" /-->
hidd
+- disk
| +- ...
| +- scsi
| +- ...
+- graphics
+- parallel
+- scsi
| +- aha
| +- cont
| +- isa
| +- pci
| +- zorroii
+- serial
We now see that there are more classes with
hidd.scsi.aha as the parent. These provide different
versions of the SCSI controller. We can see in the example above that
there are three extra classes: hidd.scsi.cont.isa,
hidd.scsi.cont.pci, and hidd.scsi.cont.zorroii. These
allow us to interface to the controller no matter what form of
hardware platform we are using.
hidd.scsi.cont.pci access the controller through a PCI
interface -- possibly using memory-mapped IO.
hidd.scsi.cont.isa access the device through the ISA bus --
using inb() and outb() style instructions. Finally
the hidd.scsi.cont.zorroii device may access the device
through the Zorro-II bus, or in some cases it may only act as an
interface to the ROM-based Exec device.
The class model as described previously allows the definition of
classes providing some degree of abstraction between types of devices
(for example disk devices) and the implementation of those devices
(disk controllers). It does not however address the problem of
connecting the two distinct classes.
Most computer systems have some degree of flexibility about device
connections -- you can add, move, or remove devices. This
possibility allows for device connectivity to change (from the
operating system point of view) every time the operating system
starts. This coupled with the dynamic nature of plug-and-play hardware
resource allocation, requires a dynamic connection model.
The HIDD system provides this by describing the connections at the
object level. This has two advantages: you can easily reconfigure
the connections at any time -- without having to restart the system in
many cases, and it allows classes to be reused easily to support multiple
instances of the same device.
The interconnection model used could be loosely described as being a
bus model. All devices are connected to the object that could be
considered to be their parent in the hardware of the system.
Take the example of a SCSI disk again. The SCSI disk is connected to a
SCSI controller (optionally one of many). This SCSI controller is
connected to some kind of bus -- for example PCI. Finally the PCI bus
is connected to some central point of the system that is the parent of
all available devices. This is shown more clearly in a diagram.
<!-- img src="hidd-model-obj-1.png" alt="Connection of SCSI disk" /-->
hidd
+- disk
| +- ...
| +- scsi
| +- ...
+- ...
+- scsi
| + aha
| + cont
| +- isa
| +- pci
| +- zorroii
+- ...
It is important here to realise that the connection diagram shown
above does not have anything to do with class hierarchies. If we
provide a slightly different version of the diagram showing class
names this should become clearer.
This is arguably the most important thing to remember when discussing
this topic.
The benefits of this connection model are numerous, providing:
- an easy way to describe the connections described
between the hardware dependent and independent device classes as
described in the class model
- a method of allocating and maintaining the resources available on a
given bus or controller such as DMA channels, interrupt numbers and
I/O address.
- the ability to add and remove devices at any time. This is useful with
the increase in hot-swappable devices such as USB devices.
- the ability to enable or disable drivers when their parent device
is removed or is temporarily brought off line. You may have a USB
hub with a number of devices connected to it, and you decide to unplug
the hub. In this case all devices connected to that hub should
also be removed.
A HIDD driver can exist in different states throughout the life of the
operating system. The following section describes all the states known
about by the root HIDD class.
- Unknown
All HIDD drivers start in the unknown state. This is the state
of a driver when it has either just been loaded into memory, or when
it is inside the kernel, but before it is first initialised.
At this point the driver cannot tell whether the hardware it is tied
to exist, and cannot access the device. There will have been no
objects created for this driver yet.
From the unloaded state, the only allowed next state is the probed state.
- Probed
The probed state is entered after the driver has checked whether
the device exists. Normally a driver will only be in this state
when the device exists, however kernel-based drivers that cannot
be unloaded will also be in this state.
Note that the driver still has not allocated any resources and
there have been no instances of this driver created. It is
possible for the driver to be unloaded from memory in this state,
but only under low memory conditions.
- Ready
- The device will enter the ready state when it has been linked into
the system driver list and has allocated any static resources that
it requires for its own use. It is at this point that instances of
the device can be created. Whilst it it is possible for the driver
to be unloaded in this state, it will only happen when there are
drivers in the probed or earlier states.
- Opened
This can only be reached from the ready state, but signifies that
there are instances of the driver created and in use by either a
user program or another driver. In this state the driver will not
be unloaded from memory, even under low memory conditions.
The opened state does not consider the number of instances that
have been created of this driver.
- Removed
When a removable device has been removed, the driver enters the
remove state. Note that this does not apply to removable media
such as floppy disks, but rather removable devices such as PCMCIA
cards and USB devices.
This state is not normally used by many drivers, however it is
available for those drivers that may require it.
Note
This is a preliminary document. It's neither complete nor
correct. It's purpose is to offer a basis for discussion not to put
things into concrete.
The AmigaOS is built on the Amiga's custom chips. This is a fact which is
eventually discovered when you hit the rather tight limits they impose
and try to circumvent them by adding new hardware. For the new hardware,
you also need a device driver. But sometimes, the applications can't be
made to use this new driver because the old one is compiled in or, even
worse, the OS refuses to use anything besides the built in driver or,
even more worse, the OS doesn't use a driver to access this chip at all.
AROS was designed to be a portable OS and be compatible to the old AmigaOS.
But we had to design something which lessens these burdens without
becoming incompatible or loosing too much speed. So we developed the
idea of the HIDD - the Hardware Independent Device Driver.
HIDDs offer a consistent API for everything one could want to do with
a device. Here is a quick overview:
- Query the system for all available HIDDs or only for certain types
(e.g. all serial HIDDs or all graphics HIDDs).
- Configure a HIDD
- Use a HIDD
The complete life cycle of a HIDD is like this:
- The OS boots. HIDDs on external cards and in the ROM get installed by
the OS in the global list of all available HIDDs. Also the OS searches for
HIDDs installed on the hard disk.
- The OS reads the extended romtags from all HIDDs and puts that
information in the global list of all available HIDDs.
- Some application asks for a list with the informations about
all HIDDs or a specific type of HIDD.
- The application loads the HIDD and the config plugin. This makes the
HIDD initialize some internal data structures but not always the hardware
because a HIDD might be the driver for several different kinds of hardware,
which might or might not be available. Thus it must be configured first.
- The application asks for the current config of the HIDD. If the
config plugin has its own GUI, the application displays it. Otherwise,
the application displays the information in an own window. For this,
the application queries the config plugin for all available modes.
- The application reads the config from the config plugin, then reads the
list of available modes for this config (i.e. what can be changed in the
current config) and displays this. Then the user can select some mode, the
application changes the config and starts over.
- When the user presses OK, the application or config plugin closes
the window/GUI. The OK or Apply button must be ghosted as long as
the HIDD indicates that the configuration is not OK. The application can
now expunge the config plugin. If a HIDD supports saving its config,
it must do so.
- When the device is explicitly activated or used for the first time
(e.g. data is written to it), it will use the configuration to initialize
the hardware.
- The user can deactivate the device and change the config if the
HIDD permits that.
- ULONG HIDD_FindHIDD (struct TagItem * tags, Class ** hiddArray)
- Get a list of HIDDs with the specified attributes. The HIDDs must
match all attribute/value pairs in tags. Note that this is a normal
function and not a method.
- ULONG HIDDM_Class_Get(struct TagItem * AttrList)
- Use this method on the class on a HIDD to get the static attributes (e.g.
HIDDA_Type, HIDDA_SubType, etc.).
You can then use the HIDD API to query the devices for their infos. Use
FreeVec() to dispose the array. HIDDV_FindHIDD_All as type gives
the complete list of all known HIDDs.
HIDDs are BOOPSI objects which support the Exec Device API.
- LONG OM_SET (struct TagItem * AttrList)
Change some attributes of a HIDD.
The return code is 0 in case of success or != 0 in case of an error.
If the return code is > 0, then it's the number of the offending tag
in the list, if it's < 0, then it's an error code.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert this error code into a string.
- LONG OM_GET (Tag AttrID, IPTR * Storage)
Query a single attribute from the HIDD in general (e.g. its name and
version) and the current status. You can only query attributes which are
gettable.
The return code is 0 in case of success or < 0 in case of an error.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert the error code into a string.
- LONG OM_MGET (struct TagItem * AttrList)
Query one or more attributes from the HIDD in general (e.g. its name and
version) and the current status. You can only query attributes which are
gettable. The ti_Data fields of AttrList must be pointers of the
type which is expected for the respective attribute.
The return code is 0 in case of success or != 0 in case of an error.
If the return code is > 0, then it's the number of the offending tag
in the list, if it's < 0, then it's an error code.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert this error code into a string.
- LONG HIDDM_BeginIO (struct IORequest *)
- Initiate a device operation.
See the Exec Device API for details.
- LONG HIDDM_AbortIO (struct IORequest *)
- Abort a running device operation. See the Exec Device API for details.
- HIDDT_Config HIDDM_LoadConfigPlugin (APTR PluginData)
- Tells the HIDD to load its configuration plugin. This method
returns a pointer to the plugin. PluginData is a pointer with
plugin-specific data. For details, look into the manual for the HIDD.
- LONG OM_SET (struct TagItem * AttrList)
Change some attributes of a HIDD Config Plugin (HIDD CP).
The return code is 0 in case of success or != 0 in case of an error.
If the return code is > 0, then it's the number of the offending tag
in the list, if it's < 0, then it's an error code.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert this error code into a string.
Note that changing attributes changes only the HIDD CP, never the HIDD
itself. When the HIDD CP tells you that the current config works, then
you can copy the config to the HIDD.
- LONG OM_GET (Tag AttrID, IPTR * Storage)
Query a single attribute from the HIDD CP. You can only query attributes
which are gettable.
The return code is 0 in case of success or < 0 in case of an error.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert the error code into a string.
- LONG OM_MGET (struct TagItem * AttrList)
Query one or more attributes from the HIDD CP. You can only query
attributes which are gettable. The ti_Data fields of AttrList must
be pointers of the type which is expected for the respective attribute.
The return code is 0 in case of success or != 0 in case of an error.
If the return code is > 0, then it's the number of the offending tag
in the list, if it's < 0, then it's an error code.
You can use HIDDM_ValueToString() with the special tag
HIDDA_ErrorCode to convert this error code into a string.
- struct TagItem * AttrList HIDDM_QueryConfig (void)
Ask the HIDD CP about its current configuration. The AttrList should be
built in such a way that one can go back to the current config by loading
the device for the first time and use OM_SET with this AttrList
or by disabling it and use OM_SET. A typical use of this will be to
save this list to a file and load it next time when one needs to configure
the HIDD.
The current configuration of the HIDD CP is a copy of the HIDDs current
configuration when the HIDD CP is created. Then you can change it and the
HIDD CP will act as if the HIDD itself had changed. When you are done, you
can apply the changes to the HIDD itself (aka OK or Apply) or just forget
about them (aka Cancel).
Astuce
If you write a HIDD, then you can use the power of BOOPSI and
TagItem lists to create this list. Pass this method to the
superclass first and then attach your local taglist with
TAG_MORE. Or you can filter the taglist of the superclass
and build your own taglist (and dispose the taglist of the
superclass by HIDDM_FreeConfig()).
- void HIDDM_FreeConfig (struct TagItem * AttrList)
- Dispose the list of attributes which you got by HIDDM_QueryConfig().
- struct TagItem * HIDDM_QueryModeList (void)
Ask the HIDD CP about the currently available modes.
The taglist consists of tags which have the types BOOL,
HIDDT_Limit (a minimum and maximum value), HIDDT_List (a list with
string/value pairs or one-of-many selection) or HIDDT_OptionList
(same as HIDDT_List but for some-of-many selection. The result is
passed as a bitfield).
HIDD CPs which supply their own GUI don't need to support this
tag (but most will because you need something like this internally
anyway).
- void HIDDM_FreeModeList (struct TagItem * AttrList)
- Dispose the list of attributes which you got by HIDDM_QueryModeList().
- ULONG HIDDM_Apply (void)
- Apply the current config to the HIDD.
If you dispose the HIDD CP, then all changes will be lost.
- ULONG HIDDM_SaveConfig (STRPTR filename)
- Save the current config in the specified file. If filename is NULL
then save the current config as default. This might need not result in
writing a file to the hard disk, if e.g. the hardware has a FlashROM or
EEPROM.
- ULONG HIDDM_LoadConfig (STRPTR filename)
- Load the config from the specified file, or the last saved defaults if
filename is NULL. As some devices will read the defaults from an
EEPROM, this need not always generate disc access.
- STRPTR HIDDM_ValueToString (Tag tag, IPTR value)
Convert the value value for the tag tag into a human readable
string. The string returned must not be written to or be freed.
HIDD CPs which supply their own GUI don't need to support this tag
(but most will, because something like this is needed internally
anyway).
The application will use this value to generate the visual feedback
in its GUI.
- IPTR HIDDM_StringToValue (Tag tag, STRPTR string)
Convert the string string for the tag tag back into a value.
HIDD CPs which supply their own GUI don't need to support this tag
(but most will, because something like this is needed internally
anyway).
Also note that a HIDD can ask that you return exactly the string
which was passed to you by HIDDM_ValueToString() (i.e. the
string must have the same address).
- STRPTR HIDDM_GetTagName (Tag tag)
- Return a human readable string with the name for a tag. For example, a
serial HIDD with the tag HIDDV_Serial_BPSRate might return
"BPS rate". The application will use this to generate its GUI.
- ULONG HIDDM_GetTagType (Tag tag)
- Return the type of an attribute. Examples are HIDDV_TagType_ULONG,
HIDDV_TagType_STRPTR, HIDDV_TagType_Other (i.e. something
special). This can be used to generate a general GUI for a HIDD or to load
and save attributes of a HIDD. Always remember that a HIDD can have many
more attributes than this document describes. A HIDD can store private
data in a taglist which it needs to configure itself but which should be
invisible to the user.
- HIDDA_Type,ULONG,G
- This is the basic type of the HIDD (e.g.
HIDDV_Type_Serial for serial HIDDs, HIDDV_Type_Parallel for
parallel HIDDs or HIDDV_Type_Graphics for graphical HIDDs).
- HIDDA_SubType,ULONG,G
- This is a more specific type. If HIDDA_Type is
HIDDV_Type_Serial, then this is a bitfield with one or more bits
of HIDDV_Type_Serial_RS232 or HIDDV_Type_Serial_RS488 set.
- HIDDA_Producer,ULONG,G
- The ID of the producer as handed out by Amiga International.
- HIDDA_Name,STRPTR,G
- The name of this device (e.g. serial.device).
- HIDDA_HardwareName,STRPTR,G
- The name of the hardware (e.g. "Builtin Serial Port", "COM1",
"CyberVision/3D", etc.). Note that some HIDDs have to be initialised
before you can query this attribute because some HIDDs work with more
than one type of hardware.
- HIDDA_Active,BOOL,ISG
- Tells if the device is active or (de-)activates it when set.
- HIDDA_Status,ULONG,G
- The current status of a HIDD. This is a
set of bits which show if the init of the hardware was successful,
if the device is active or if the device is ready to be activated.
- HIDDA_ErrorCode,LONG,G
In case of an error, you can ask for the error code and use this code in
HIDDM_ValueToString() to get a string with the meaning of the error.
This is mostly used when the HIDD tells you that it doesn't like a
certain tag in a taglist. When this happens, you can query this code to
find out what the HIDD doesn't like about the tag.
Note that you can supply this tag when you try to create or change
attributes of a HIDD. If you do this, you must still pass a pointer to
LONG to NewObject() or SetAttrs(). In case of an error,
it will be filled with the error code.
- HIDDA_Locking,ULONG,G
Tells which kinds of locking the HIDD supports. Can be read from the
class and from an existing HIDD. The possible values are:
- HIDDV_Lock_None
- No locking is supported. Note that some HIDDs have a
kind of hidden locking: They can't be created more than once. The
second attempt to create such a HIDD will just fail with the error
HIDDV_Error_UniqueObject. Also note that this can also mean that
no locking is necessary.
- HIDDV_Lock_Shared
- Shared and exclusive locking are supported (several tasks can access
the HIDD simultanously). This doesn't mean that it makes sense to have
several tasks access the HIDD at the same time, only that it is
possible.
- HIDDV_Lock_Exclusive
- Only one task can access the HIDD at any one time. Note that a HIDD
which can't exist more than once should not use this kind of
locking but just fail on the second attempt to create it.
- HIDDA_HasOwnGUI,BOOL,G
- Ask the HIDD CP if it has its own GUI for configuration.
- HIDDA_ShowGUI,BOOL,ISG
- Make the GUI of the HIDD CP visible or hide it or ask if it's visible
right now. If you hide the GUI and dispose the HIDD CP, then the
changes the user made will be lost.
- HIDDA_UseScreen,struct Screen *,ISG
- Tell the HIDD CP to open the GUI on this screen.
- HIDDA_AppMsgPort,struct MsgPort *,ISG
- When the HIDD CP has its own GUI, this GUI runs independent of the
application. You can supply a message port to synchronise your
application with the GUI of the HIDD CP. Some HIDD CPs will also use
this to talk to the application.
- IPTR HIDDM_Lock(ULONG mode)
Try to get access to the HIDD if you opened it in shared mode. The values
for mode are HIDDV_Lock_Exclusive and HIDDV_Lock_Shared.
You can add the flag HIDDV_Lock_Try. HIDDV_Lock_Exclusive means
that you want the HIDD for your own. If someone else has a lock on the
HIDD, this will block unless HIDDV_Lock_Try is set.
HIDDV_Lock_Shared will only block if no exclusive locks exist and
HIDDV_Lock_Try is not set.
If HIDDV_Lock_Try is not set, this will block until the HIDD can be
locked as you wish.
The method will return FALSE if the lock could not be established. It
will return something else if the lock could be established.
Note that some HIDDs don't support locking. Use HIDDM_Class_Get() to
find out which do and which don't at runtime and read the documentation
for the HIDDs.
- void HIDDM_Unlock(IPTR lock)
- Unlock the HIDD. lock must contain what you got back from
HIDDM_Lock().
The alarm HIDD allows to call a hook after a certain time.
The type of an alarm HIDD is HIDDV_Type_Alarm and the names for
alarm-specific things are prefixed with HIDD?_Alarm_.
Subtypes of this HIDD are HIDDV_Type_Alarm_VB (vertical blank interrupt),
and HIDDV_Type_Alarm_Real (real time clock).
This kind of HIDD cannot be shared. If you try to create a second alarm HIDD
of a specific class, you will get the error HIDDV_Error_UniqueObject.
If you need shared access to this HIDD, use the timer.hidd.
Ticks are the smallest interval an alarm HIDD can provide. This tells how
long n ticks would last in real life.
- HIDDM_Alarm_TimeToTicks(struct tv *, ULONG ticks)
- How many ticks would a certain time be?
Type: | struct tv * |
Applicability: | ISG |
This is the time for the next alarm. This implies single shot mode. The hook
is called only once. The time is specified as absolute system time.
Type: | struct tv * |
Applicability: | ISG |
This is the time for the next alarm. This implies repeat mode. The hook is
called every time after interval has elapsed.
Type: | struct Hook * |
Applicability: | ISG |
Call this function when the alarm comes.
Type: | BOOL |
Applicability: | SG |
(De-)Activate this alarm HIDD. When created, the alarm hidd is always
inactive.
Type: | ULONG |
Applicability: | G |
This is a tag of the class. It contains the unit number you must pass to the
timer.hidd if you want to access this alarm HIDD.
The type of a serial HIDD is HIDDV_Type_Serial and the names
for serial-specific things is prefixed with HIDD?_Serial_.
Subtypes of serial HIDDs are HIDDV_Type_Serial_RS232 and
HIDDV_Type_Serial_RS488, for example.
Type: | ULONG |
Applicability: | ISG |
The bits per second or a logical BPS rate (300baud, 600baud, 1200,
2400, 4800, 9600, 19200, 31500 (MIDI), 38400, etc.) The logical BPS rates
have the bit 31 set.
When you query the list of available modes, you will get an HIDDT_Limit
for this attribute. If the limits have bit 31 set, the device supports only
fixed BPS rates. If the limits don't have this bit set, this means that the
device supports variable BPS rates. If you use a logical BPS rate, you must
make sure that you don't exceed the limits. For example, some device might
support any BPS rate between 5000bps and 100000bps. This means that only
the logical BPS rates between 9600 and 74k (including both) are available.
Also note that a HIDD might not support every BPS rate in the range. There
might be arbitrary steps, so you must set the BPS rate and then read it
back to see what the HIDD can do. The HIDD should always select a BPS
rate which is next to the one the user wants.
Type: | ULONG |
Applicability: | ISG |
The number of data bits. Most HIDDs support only 7 or 8 bits but you should
expect at least anything between 5 and 8.
Type: | ULONG |
Applicability: | ISG |
The number of stopbits between two data bytes multiplied by 16 (i.e. one
stopbit is 16, one and a half would be 24 and two stopbits is 32).
- ULONG HIDDM_QueryKeys (ULONG ** keyptr)
- Ask for all really available keys on this keyboard. The method will fill
in a pointer to a read-only array and return the number of elements in
that array.
You must not free this array nor write to it.
- ULONG HIDDM_QueryKeyStates (ULONG ** keyptr)
- Ask for all currently pressed keys on this keyboard. The method will fill
in a pointer to an array and return the number of elements in that array.
- ULONG HIDDM_FreeKeyStates (ULONG * keyptr)
- Free the result of a HIDDM_QueryKeyStates().
Type: | ULONG |
Applicability: | ISG |
If the Keyboard HIDD can work with more than one type of keyboard, you can
specify the type here or if the HIDD can figure the type of keyboard itself,
it can offer the type here. If the HIDD doesn't support this, this value is
0 and can't be changed by setting it. The method HIDDM_QueryModes()
should return a type HIDDT_Limit with minimum and maximum both 0.
Type: | struct MsgPort * |
Applicability: | ISG |
When the user presses a key, the HIDD should report this by sending a
HIDDT_Keyboard_Event message to this port. The message looks like this:
typedef struct
{
struct Message ke_Message;
ULONG ke_Key[1];
}
HIDDT_Keyboard_Event;
ke_Key[] contains the X11 code for the key. See
/usr/include/X11/keysymdef.h for available keycodes. If the key has been
pressed, bit 31 will be set. If the key has been released, bit 31 will be
cleared.
If the user pressed more then one key, the other keys are in ke_Key[1],
ke_Key[2], etc. The number of keys in the message is calculated by the
macro HIDDQ_Keyboard_GetNumKeys(msg).
A graphics HIDD allows to create bitmaps, display them and draw in them.
The graphics HIDD supports the following methods:
- IPTR HIDDM_Graphics_QCmd,UWORD Length,UWORD Command,...)
Make the HIDD execute a simple command. Simple commands execute
very fast and don't do any checks. They were implemented to give
you raw speed when you need it.
Command is the command to execute and Length is the size
of the command (including both Command and Length).
The result of HIDDM_Graphics_QCmd() depends on the command
that is to be executed.
- IPTR HIDDM_Graphics_Cmd,UWORD Length,UWORD Command,...)
Make the HIDD execute a command. The commands executed this
way are checked for validity (e.g. clipping is performed) and
they may take very long to execute.
Command is the command to execute and Length is the size
of the command (including both Command and Length).
The result of HIDDM_Graphics_Cmd() depends on the command
that is to be executed.
- void HIDDM_Graphics_MCmd,UWORD length,UWORD length1, UWORD cmd1, ...)
This is like HIDDM_Graphics_Cmd() but executes more than one
command at once. length is the size of all commands plus all
parameters. The format of the separate commands is the same as in
HIDDM_Graphics_Cmd().
You can't use commands which return values with HIDDM_Graphics_MCmd().
If you use such commands with HIDDM_Graphics_MCmd(), the returned
values will be lost.
- void HIDDM_Graphics_MQCmd,UWORD length,UWORD length1, UWORD cmd1, ...)
- This is like HIDDM_Graphics_QCmd() but executes more than one
command at once. length is the size of all commands plus all
parameters. The format of the separate commands is the same as in
HIDDM_Graphics_QCmd().
- void HIDDV_Graphics_Cmd_WaitTOF (void)
- Wait for the vertical blank. This is a short time span during which
updates of the screen are invisible because the hardware of the monitor
moves the ray from the bottom right to the top left corner. This will
block until the next time it happens. If you use this command in
HIDDM_Graphics_MCmd() or HIDDM_Graphics_MQCmd(), the drawing
command after the HIDDV_Graphics_Cmd_WaitTOF() will be executed
exactly right after the system has been signalled that the vblank
is happening. If several processes try to do this, they will be
executed in first-come-first-served order.
- BOOL HIDDV_Graphics_Cmd_CheckTOF (void)
- Query whether a vertical
blank is happening right now. This isn't really useful because you can't
use it to draw because in a multitasking system, you might loose the
CPU just after HIDDV_Graphics_Cmd_CheckTOF() told you that a
vblank is happening right now.
- HIDDT_BitMap HIDDV_Graphics_Cmd_CreateBitMap (Tag tag, ...)
- Create a drawing area with the specified attributes.
Type: | ULONG |
Applicability: | ISG |
Create a bitmap with this width or query the width. Note that most HIDD don't
support to resize a bitmap. The width is in HIDD units. Some graphics HIDDs
support text mode, where this is in characters. But most of the time, this
will be in screen or printer pixels.
Type: | ULONG |
Applicability: | ISG |
Create a bitmap with this height or query the height. Note that most HIDD
don't support to resize a bitmap. The height is in HIDD units. Some graphics
HIDDs support text mode, where this is in characters. But most of the time,
this will be in screen or printer pixels.
Type: | UWORD |
Applicability: | IG |
Create a bitmap with this depth. When the bitmap has been created, you can
query the attribute. The number of distinct colors is 1L << depth. Most
HIDDs will support depths like 1, 8, 15, 16, 24 and 32 bit.
Type: | BOOL |
Applicability: | IG |
Create a bitmap which should later be displayed. When the bitmap has been
created, you can query the attribute. On some systems, this will also display
the bitmap when the method returns. To be safe, always call
HIDDV_Graphics_Cmd_ShowBitmap() afterwards.
Type: | ULONG |
Applicability: | G |
Check if a bitmap is visible. Can return HIDDV_Bitmap_Visible_No,
HIDDV_Bitmap_Visible_Yes and HIDDV_Bitmap_Visible_Partial (if it's not
fully visible).
Type: | ULONG |
Applicability: | ISG |
The display mode. Every HIDD defines its own list and uses its own values. Use
the method HIDDM_ValueToString() to get the meanings of this attribute.
Type: | APTR |
Applicability: | ISG |
This is the address of the RAM of the graphics memory. Note that most HIDDs
don't support to set this value. This can be used to access the video hardware
directly. If you plan this, you must check if the HIDD supports this and if it
does, then you must take the appropriate steps specified in the HIDDs' docs to
tell the HIDD what you are doing (e.g. disable the HIDD). After you did this,
you can use HIDDA_Graphics_Format to find out the format in which the data
is stored here.
A HIDD which doesn't support direct memory access will return NULL.
Type: | ULONG |
Applicability: | ISG |
Tell the format of the data at HIDDA_BitMap_BaseAddress. See this tag for
details.
Type: | ULONG |
Applicability: | G |
Query the number of bytes which make up one line on the display. This can be
different from HIDDA_BitMap_BytesPerPixel * HIDDA_BitMap_Width.
Type: | ULONG |
Applicability: | G |
Query the number of bytes which make up one pixel on the display. This can be
different from the number of bits divided by eight. If one byte contains
informations of several pixels, then this will be 0.
Type: | ULONG |
Applicability: | G |
Query the HIDD for the best size for drawing areas or drawing commands. Most
graphics chips have a certain blocking size, i.e. it doesn't matter if you
copy 6 bits or 30 but 33 is slow. The HIDD will return 32 in this case.
Type: | LONG |
Applicability: | IG |
Query or initialize the left edge position of a bitmap which is displayable.
The position can be change with HIDDV_Graphics_Cmd_MoveBitMap. The value of
the position is in HIDD units. Some graphics HIDDs support text mode, where
this is in characters. But most of the time, this will be in screen or
printer pixels.
Type: | LONG |
Applicability: | IG |
Query or initialize the top edge position of a bitmap which is displayable.
The position can be change with HIDDV_Graphics_Cmd_MoveBitMap. The value of
the position is in HIDD units. Some graphics HIDDs support text mode, where
this is in characters. But most of the time, this will be in screen or printer
pixels.
- ULONG HIDDV_Graphics_Cmd_ShowBitMap (HIDDT_BitMap bm, BOOL wait)
- Make a bitmap visible. Some systems allow to show more than one bitmap at
a time. On these systems, the specified bitmap appears before all other
bitmaps. If wait is TRUE, then the call will block until the
bitmap is made visible (i.e. at the next HIDDV_Graphics_Cmd_WaitTOF).
The call returns whether bitmap is visible or not if wait is FALSE
or TRUE otherwise.
- VOID HIDDV_Graphics_Cmd_MoveBitMap (HIDDT_BitMap bm, WORD horizontal, WORD vertical)
- Move a visible bitmap around the screen. Positive values mean move to the
left or down, negative values means right and up. If the horizontal and
vertical variables you specify would move the bitmap beyond any
restrictions then the bitmap is moved only as far as possible. You can
query the real position to which the bitmap was move with the
HIDDA_BitMap_LeftEdge and HIDDA_BitMap_TopEdge attributes.
- ULONG HIDDV_Graphics_Cmd_DepthArrangeBitMap (HIDDT_BitMap bm, ULONG mode, HIDDT_BitMap other)
- Move a bitmap to the front or back of all bitmaps or a specific bitmap.
The mode can be HIDDV_Graphics_DepthArrange_ToFront or
HIDDV_Graphics_DepthArrange_ToBack. If other is != NULL, then
the bitmap will be moved just in front or behind that bitmap. If the
other is NULL, then bitmap will be moved in front or behind all
other bitmaps.
If the bitmap was invisible, then HIDDV_Graphics_Cmd_ShowBitMap() will
implicitly be called.
- void HIDDV_Graphics_Cmd_DeleteBitMap (HIDDT_BitMap bm)
- Return a drawing area for reuse. You can also dispose it with
DisposeObject().
- HIDDT_GC HIDDV_Graphics_Cmd_CreateGC (HIDDT_BitMap bm)
- Create a graphics context. The graphics context is used to store
information which is needed for more than one command (for example the
color or the drawmode). A GC is a BOOPSI object and can be changed with
the normal BOOPSI API.
- void HIDDV_Graphics_Cmd_DeleteGC (HIDDT_GC gc)
- Return a gc for reuse. You can also dispose the GC with
DisposeObject(). The bitmap that is connected to this graphics context
will not be deleted.
- BOOL HIDDV_Graphics_Cmd_CopyArea (HIDDT_GC src, WORD srcX, WORD srcY, UWORD width, UWORD height, HIDDT_GC dest, WORD destX, WORD destY)
Copy a rectangular area from the drawing area src to the drawing area
stored in dest (which may be src). The source area is not changed
(except when both rectangles overlap). The mode of the GC dest
determines how the copy takes place.
In quick mode, the following restrictions are not checked: It's not
checked whether the source and destination rectangles are is completely
inside the valid area, nor whether the areas overlap. If they overlap, the
results are unpredictable. Also drawing modes are ignored. If the two
bitmaps in the GCs have a different depth, copying might be slow.
Copying bitmaps between two different HIDDs is executed in a way that
matches the following pseudo-algorithm: First the destination HIDD is
queried to determine whether it understands the format of the source HIDD.
If it does, then the destination HIDD does the copying. If it doesn't,
then the source is asked whether it understands the destination HIDDs'
format. If it does, then the source HIDD does the copying. If neither
supports the format of the other, then the default CopyArea of the
graphics HIDD base class will be invoked, which copies the bitmaps pixel
by pixel with HIDDV_Graphics_Cmd_GetPixel() and
HIDDV_Graphics_Cmd_SetPixel().
- BOOL HIDDV_Graphics_Cmd_WritePixelDirect (HIDDT_GC gc, WORD x, WORD y, ULONG val)
Set the pixel at (x,``y``) direct to val without making use of the
gc attributes, like colors, drawmode, colormask, etc. This command is
available in quick and normal mode.
In quick mode, the pixel is always set, even if the coordinates are
illegal, and it will always return 1 (but it might crash the machine if
the coordinates are invalid).
- BOOL HIDDV_Graphics_Cmd_WritePixel (HIDDT_GC gc, WORD x, WORD y)
Changes the pixel at (x,``y``). The color of the pixel depends on the
attributes of gc, e.g. colors, drawmode, colormask, etc. This command
is available in quick and normal mode.
If the command is executed in normal mode, the coordinates are checked. If
the pixel could be set, the command will return 1 else 0.
In quick mode, the pixel is always set, even if the coordinates are
illegal, and it will always return 1 (but it might crash the machine if
the coordinates are invalid).
- ULONG HIDDV_Graphics_Cmd_ReadPixel (HIDDT_GC gc, WORD x, WORD y)
Queries the color of the pixel at (x,``y``). This command is available
in quick and normal mode. When executed in quick mode, the color will be
returned as the physical value for that color in the format used by the
HIDD. If the command is executed in normal mode, the coordinates are
checked and the color returned is a logical color (i.e. a 24-bit RGB
value). If the pixel could be queried, the command will return its value
and ~0 (i.e. all bits set) otherwise.
Note that in quick mode, the command always returns something, but if the
coordinates are outside the valid coordinates, this can crash your machine
or return random values.
- BOOL HIDDV_Graphics_Cmd_DrawLine (HIDDT_GC gc, WORD x1, WORD y1, WORD x2, WORD y2)
- Draws a line from (x1,``y1``) to (x2,``y2``) in the specified gc.
This command is available in quick and normal mode. In normal mode, the
line is clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_DrawRect (HIDDT_GC gc, WORD x1, WORD y1, WORD x2, WORD y2)
- Draws a hollow rectangle from (x1,``y1``) to (x2,``y2``) in the
specified gc. This command is available in quick and normal mode. In
normal mode, the rectangle is clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_FillRect (HIDDT_GC gc, WORD x1, WORD y1, WORD x2, WORD y2)
- Draws a solid rectangle from (x1,``y1``) to (x2,``y2``) in the
specified gc. This command is available in quick and normal mode. In
normal mode, the rectangle is clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_DrawEllipse (HIDDT_GC gc, WORD x1, WORD y1, WORD rx, WORD ry)
- Draws a hollow ellipse from (x1,``y1``) with the radii rx and
ry in the specified gc. This command is available in quick and normal
mode. In normal mode, the ellipse is clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_FillEllipse (HIDDT_GC gc, WORD x1, WORD y1, WORD rx, WORD ry)
- Draws a solid ellipse from (x1,``y1``) with the radii rx and
ry in the specified gc. This command is available in quick and normal
mode. In normal mode, the ellipse is clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_DrawPolygon (HIDDT_GC gc, UWORD n, WORD coords[2*n])
- Draws a hollow polygon from the list of coordinates in the specified gc.
This command is available in quick and normal mode. In normal mode, the
polygon is clipped against the drawing area and no point is drawn twice.
- BOOL HIDDV_Graphics_Cmd_FillPolygon (HIDDT_GC gc, UWORD n, WORD coords[2*n])
Draws a solid polygon from (x1,``y1``) to (x2,``y2``) in the
specified gc. This command is available in quick and normal mode. In
normal mode, the polygon is clipped against the drawing area and no point
is drawn twice.
In quick mode, the polygon should be convex, otherwise the results are
unpredictable.
- BOOL HIDDV_Graphics_Cmd_DrawText (HIDDT_GC gc, WORD x, WORD y, STRPTR text, UWORD length)
- Draws the first length characters of text at (x,``y``). This
command is available in quick and normal mode. In normal mode, the text is
clipped against the drawing area.
- BOOL HIDDV_Graphics_Cmd_FillText (HIDDT_GC gc, WORD x, WORD y, STRPTR text, UWORD length)
- Fills the area of the text with the background color and draws the first
length characters of text at (x,``y``). This command is
available in quick and normal mode. In normal mode, the text is clipped
against the drawing area.
- BOOL HIDDV_Graphics_Cmd_FillSpan (HIDDT_GC gc, HIDDT_Span span)
- Draws a solid from a shape description in the specified gc. This command
is available in quick and normal mode. In normal mode, the spans are
clipped against the drawing area.
- void HIDDV_Graphics_Cmd_Clear (HIDDT_GC gc)
- All pixels of the drawing area are changed to the background color stored
in gc. This command is available in quick and normal mode and behaves
similar in both modes.
- IPTR HIDDV_Graphics_Cmd_Special (...)
- This is for HIDD-specific commands. You can use this for sending commands
to the HIDD which are not covered by this doc. This command is available
in quick and normal mode. It's behaviour is HIDD-specific.
Type: | APTR |
Applicability: | SG |
The user can store arbitrary data in here.
Type: | HIDDT_BitMap |
Applicability: | G |
This is the bitmap which is connected to this GC.
Type: | ULONG |
Applicability: | SG |
This is the foreground color.
Type: | ULONG |
Applicability: | SG |
This is the background color.
Type: | ULONG |
Applicability: | SG |
This is the draw mode. There are 16 possible modes and they are defined as
follows:
dest = ((mode & 1) && src && dest)
```` ((mode & 2) && src && !dest)
```` ((mode & 4) && !src && dest)
```` ((mode & 8) && !src && !dest)
;
The most useful values are HIDDV_GC_DrawMode_Copy (0x03) which copies
src into dest (this is the default) and HIDDV_GC_DrawMode_XOr (0x06)
which inverts dest according to src.
Type: | HIDDT_Font |
Applicability: | SG |
The current font.
Type: | ULONG |
Applicability: | SG |
Prevents some color bits from changing. This attribute is only considered in
normal mode. This can slow rendering somewhat.
Type: | UWORD |
Applicability: | SG |
Provide a simple pattern while drawing lines. This attribute is only
considered in normal mode.
Type: | HIDDT_BitMap |
Applicability: | SG |
This is a shape bitmap. When drawing into the destination bitmap, only those
bits will be changed where this bitmap has bits set. This bitmap can be
smaller than the destination bitmap; bits outside this bitmap are considered
to be 0.
To disable this, set the attribute to NULL (this is also the default).
Note that enabling this slows rendering down, sometimes very much so.
Okay, here are some examples of how a sound.hidd could be implemented on
different hardware-bases. This is how the class would behave, if a
method HIDDM_SendMIDI was sent (I don't know, if such a method would make
sense, but it's only for illustration issues).
There are two possibilities of how to handle it. The first is to not handle
it, so that the method is passed on to the hiddclass (which doesn't know this
method either) and then on to the rootclass, which returns 0 (FALSE) on
unknown methods. The second possibility is to implement it in soundhiddclass
and return FALSE immediately (because we know that the internal Amiga
soundsystem can't handle MIDI).
The sound-card passes all methods through to its superclass, except methods
for playing/receiving/whatever music. It can either implement them totally
on its own or might use some features of its superclass, for example a general
method for sending data to a Zorro-card.
This configuration would have two HIDDs, one for MIDI only and one for sound
in general. For the implementation of the last one see above (either Amiga
with internal sound or Amiga with sound-card). The MIDI HIDD-class could
subclass the general sound class (without knowing if it is capable of playing
MIDI) and pass on all methods except MIDI relevant methods. It would fully
overload these.
Another solution would be to subclass hiddclass directly and ignore every
non-MIDI sound command. While the general class would be unit 0, the MIDI
class would be unit 1, so that an application can choose between the normal
sound-system (either the internal Amiga soundsystem or a sound-card, which
might have MIDI capabilities on its own) or the MIDI card. If the MIDI class
would subclass the normal soundhidd, it would feature non-MIDI sound too (by
passing the methods on). Of course, it would have to pass a query for a
HIDDA_Capabilities attribute on to the superclass, so that the capabilities
of the superclass would be recognized by the application for unit 1, too.
This HIDD could(!) subclass a class, which handles soundblaster-cards in
general, i.e. the functions that are common to all soundblaster-card (which
itself could subclass something like a pcbusclass). Normally this class would
pass all methods on to its superclass, but it could implement some methods on
its own or partly overload some methods, where this specific soundblaster-card
had advantages/different features than the other soundblaster-cards.
- An attribute HIDDA_Capabilities [..G], which could define things like:
- HIDDV_Sound_MIDI - sound-system is able to play MIDI sounds (possibly by
using an external MIDI device, such as a keyboard)
- HIDDV_Sound_SFX - sound-system is capable of playing simple sounds (e.g.
the internal pc-speaker)
- HIDDV_Sound_Music
- HIDDV_Sound_Speech
- Possible attributes HIDDA_Sound_ActivateHook, ..._InactivateHook [ISG]
These attributes could be used by an application to provide hooks, which are
called if a not-locked unit is exclusively locked by another application (or
this exclusive lock is freed). So these attributes makes only sense with
HIDDV_Sound_NonExclusiveNotLocked.
An IRQ HIDD is a frontend for the IRQ hardware of your computer. Whenever the
computer generates an IRQ, the IRQ HIDD will catch it and check for handlers
for this IRQ. If any handlers are available, the IRQ HIDD will call them.
An IRQ HIDD uses IRQ IDs to do its job. Those IDs are not related to the IRQ
numbers in the hardware.
An IRQ handler is a callback hook with a priority. The handler gets a
pointer the handler info given to HIDDM_IRQ_AddHandler() and to the
hardware-specific IRQ data. For the format of this data, see the docs of
the specific IRQ HIDD.
- BOOL HIDDM_IRQ_AddHandler (HIDDT_IRQ_Handler * handlerInfo, ULONG id)
- Install a handler for the ID id. If the handler could be installed,
then TRUE is returned, else FALSE. See the HIDDA_ErrorCode for
details if FALSE was returned.
- void HIDDM_IRQ_RemHandler (HIDDT_IRQ_Handler * handlerInfo)
- Removes a handler. If the handler is running, this will block until the
handler can be safely removed. If it is called from inside an IRQ, it will
not block but postpone the remove.
- void HIDDM_CauseIRQ (ULONG id, APTR hardwareInfo)
- Generates a pseudo IRQ with the specified id. The hardwareInfo
will be passed to the handlers instead of the normal hardware IRQ infos.
A HIDD is a normal Exec Device which creates a BOOPSI class when loaded.
A HIDD is recognised by the name in the ROMtag structure. This name must begin
with the four letters "HIDD" (in that order). Note that the name of the HIDD
is the string after the first four letters. Also note that a HIDD need not
have a unique name.
Every HIDD has an extended ROMtag structure which contains the infos needed to
find a HIDD by HIDD_FindHIDD().
HIDDs are BOOPSI objects but unlike other BOOPSI objects, they are not created
by classname but by the pointer returned by HIDD_FindHIDD().
The HIDD Tool Library (HIDDTL) must offer a way to make the process which
wants to execute a method on the HIDD to wait if the HIDD is locked. It must
also offer functions to lock/unlock a semaphore to allow the HIDD to block. If
no locking is possible (e.g. NetBSD), then there must be a way to query this,
too.
There must be a set of functions to install IRQ handlers.
|
|