mirror of
https://github.com/86Box/docs.git
synced 2026-02-21 17:15:33 -07:00
Sweeping formatting changes
This commit is contained in:
@@ -3,20 +3,20 @@ Devices
|
||||
|
||||
The **device** is the main unit of emulated components in 86Box. Each device is represented by one or more constant ``device_t`` objects, which contain metadata about the device itself, several callbacks and an array of user-facing configuration options. Unless otherwise stated, all structures, functions and constants in this page are provided by ``86box/device.h``.
|
||||
|
||||
.. flat-table:: device_t
|
||||
.. flat-table:: ``device_t``
|
||||
:header-rows: 1
|
||||
:widths: 1 1 999
|
||||
|
||||
* - :cspan:`1` Member
|
||||
- Description
|
||||
|
||||
* - :cspan:`1` name
|
||||
* - :cspan:`1` ``name``
|
||||
- The device's name, displayed in the user interface. ``"Foo-1234"`` for example. Suffixes like ``"(PCI)"`` are removed at run-time.
|
||||
|
||||
* - :cspan:`1` internal_name
|
||||
* - :cspan:`1` ``internal_name``
|
||||
- The device's internal name, used to identify it in the emulated machine's configuration file. ``"foo1234"`` for example.
|
||||
|
||||
* - :cspan:`1` flags
|
||||
* - :cspan:`1` ``flags``
|
||||
- One or more bit flags to indicate the expansion bus(es) supported by the device, for determining :ref:`device availability <dev/api/device:Availability>` on the selected machine:
|
||||
|
||||
* ``DEVICE_ISA``: 8-bit ISA;
|
||||
@@ -33,11 +33,11 @@ The **device** is the main unit of emulated components in 86Box. Each device is
|
||||
* ``DEVICE_COM``: serial port (reserved for future use);
|
||||
* ``DEVICE_LPT``: parallel port (reserved for future use).
|
||||
|
||||
* - :cspan:`1` local
|
||||
* - :cspan:`1` ``local``
|
||||
- 32-bit value which can be read from this structure by the ``init`` callback.
|
||||
Use this value to tell different subtypes of the same device, for example.
|
||||
|
||||
* - :cspan:`1` init
|
||||
* - :cspan:`1` ``init``
|
||||
- Function called whenever this device is initialized, either from starting 86Box or from a hard reset. Can be ``NULL``, in which case the opaque pointer passed to other callbacks will be invalid. Takes the form of:
|
||||
|
||||
``void *init(const struct device_t *info)``
|
||||
@@ -45,14 +45,14 @@ The **device** is the main unit of emulated components in 86Box. Each device is
|
||||
* ``info``: pointer to this ``device_t`` structure;
|
||||
* Return value: opaque pointer passed to the other callbacks below, usually a pointer to the device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
* - :cspan:`1` close
|
||||
* - :cspan:`1` ``close``
|
||||
- Function called whenever this device is de-initialized, either from closing 86Box or from a hard reset. Can be ``NULL``. Takes the form of:
|
||||
|
||||
``void close(void *priv)``
|
||||
|
||||
* ``priv``: opaque pointer previously returned by ``init``.
|
||||
|
||||
* - :cspan:`1` reset
|
||||
* - :cspan:`1` ``reset``
|
||||
- Function called whenever this device undergoes a soft reset. Can be ``NULL``. Takes the form of:
|
||||
|
||||
``void reset(void *priv)``
|
||||
@@ -64,14 +64,14 @@ The **device** is the main unit of emulated components in 86Box. Each device is
|
||||
.. raw:: html
|
||||
|
||||
<div class="vertical-text">union</div>
|
||||
- available
|
||||
- ``available``
|
||||
- Function called whenever this device's availability is being checked. Can be ``NULL``, in which case the device will always be available. Takes the form of:
|
||||
|
||||
``int available()``
|
||||
|
||||
* Return value: ``1`` if the device is available for selection, or ``0`` if it is unavailable (due to missing ROMs, for example).
|
||||
|
||||
* - poll
|
||||
* - ``poll``
|
||||
- Function called whenever the mouse position is updated. Valid for mouse devices only. Takes the form of:
|
||||
|
||||
``int poll(int x, int y, int z, int b, void *priv)``
|
||||
@@ -82,24 +82,24 @@ The **device** is the main unit of emulated components in 86Box. Each device is
|
||||
* ``priv``: opaque pointer previously returned by ``init``;
|
||||
* Return value: ``0`` if the change was processed, or any other value otherwise.
|
||||
|
||||
* - register_pci_slot
|
||||
* - ``register_pci_slot``
|
||||
- Reserved for future use.
|
||||
|
||||
* - :cspan:`1` speed_changed
|
||||
* - :cspan:`1` ``speed_changed``
|
||||
- Function called whenever the emulated CPU clock speed is changed. Can be ``NULL``. Timer intervals (when using the undocumented legacy timer API) and anything else sensitive to the CPU clock speed should be updated in this callback. Takes the form of:
|
||||
|
||||
``void speed_changed(void *priv)``
|
||||
|
||||
* ``priv``: opaque pointer previously returned by ``init``.
|
||||
|
||||
* - :cspan:`1` force_redraw
|
||||
* - :cspan:`1` ``force_redraw``
|
||||
- Function called whenever the emulated screen has to be fully redrawn. Can be ``NULL``. Only useful for video cards. Takes the form of:
|
||||
|
||||
``void force_redraw(void *priv)``
|
||||
|
||||
* ``priv``: opaque pointer previously returned by ``init``.
|
||||
|
||||
* - :cspan:`1` config
|
||||
* - :cspan:`1` ``config``
|
||||
- Array of :ref:`device configuration options <dev/api/device:Configuration>`, or ``NULL`` if no options are available.
|
||||
|
||||
State structure
|
||||
@@ -171,15 +171,15 @@ Registration
|
||||
|
||||
New devices must be **registered** before they can be selected by the user. This is usually accomplished by adding one or more ``device_t`` pointers to the **device table** for the device's class:
|
||||
|
||||
* **Video cards:** ``video_cards`` in ``video/vid_table.c``
|
||||
* **Sound cards:** ``sound_cards`` in ``sound/sound.c``
|
||||
* **Network cards:** ``net_cards`` in ``network/network.c``
|
||||
* **Parallel port devices:** ``lpt_devices`` in ``lpt.c``
|
||||
* **Hard disk controllers:** ``controllers`` in ``disk/hdc.c``
|
||||
* **Floppy disk controllers:** ``fdc_cards`` in ``floppy/fdc.c``
|
||||
* **SCSI controllers:** ``scsi_cards`` in ``scsi/scsi.c``
|
||||
* **ISA RTC cards:** ``boards`` in ``device/isartc.c``
|
||||
* **ISA memory expansion cards:** ``boards`` in ``device/isamem.c``
|
||||
* **Video cards:** ``video_cards`` in ``src/video/vid_table.c``
|
||||
* **Sound cards:** ``sound_cards`` in ``src/sound/sound.c``
|
||||
* **Network cards:** ``net_cards`` in ``src/network/network.c``
|
||||
* **Parallel port devices:** ``lpt_devices`` in ``src/lpt.c``
|
||||
* **Hard disk controllers:** ``controllers`` in ``src/disk/hdc.c``
|
||||
* **Floppy disk controllers:** ``fdc_cards`` in ``src/floppy/fdc.c``
|
||||
* **SCSI controllers:** ``scsi_cards`` in ``src/scsi/scsi.c``
|
||||
* **ISA RTC cards:** ``boards`` in ``src/device/isartc.c``
|
||||
* **ISA memory expansion cards:** ``boards`` in ``src/device/isamem.c``
|
||||
|
||||
Devices not covered by any of the above classes may require further integration through modifications to the user interface and configuration loading/saving systems.
|
||||
|
||||
@@ -294,20 +294,20 @@ Configuration options can be specified in the ``config`` member of ``device_t``,
|
||||
.config = foo_config
|
||||
};
|
||||
|
||||
.. flat-table:: device_config_t
|
||||
.. flat-table:: ``device_config_t``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Member
|
||||
- Description
|
||||
|
||||
* - name
|
||||
* - ``name``
|
||||
- Internal name for this option, used to identify it in the emulated machine's configuration file.
|
||||
|
||||
* - description
|
||||
* - ``description``
|
||||
- Description for this option, displayed in the user interface.
|
||||
|
||||
* - type
|
||||
* - ``type``
|
||||
- One of the following option types:
|
||||
|
||||
* ``CONFIG_SELECTION``: combobox containing a list of values specified by the ``selection`` member;
|
||||
@@ -323,18 +323,18 @@ Configuration options can be specified in the ``config`` member of ``device_t``,
|
||||
* ``CONFIG_MIDI_IN``: combobox containing a list of system MIDI input devices;
|
||||
* ``-1``: **mandatory** terminator to indicate the end of the option list.
|
||||
|
||||
* - default_string
|
||||
* - ``default_string``
|
||||
- Default string value for a ``CONFIG_STRING`` option. Can be ``""`` if not applicable.
|
||||
|
||||
* - default_int
|
||||
* - ``default_int``
|
||||
- Default integer value for a ``CONFIG_HEX16``, ``CONFIG_HEX20``, ``CONFIG_BINARY``, ``CONFIG_INT`` or ``CONFIG_SPINNER`` option. Can be ``0`` if not applicable.
|
||||
|
||||
* - file_filter
|
||||
* - ``file_filter``
|
||||
- File type filter for a ``CONFIG_FNAME`` option. Can be ``""`` if not applicable. Must be specified in Windows ``description|mask|description|mask...`` format, for example:
|
||||
|
||||
``"Raw image (*.img)|*.img|Virtual Hard Disk (*.vhd)|*.vhd"``
|
||||
|
||||
* - spinner
|
||||
* - ``spinner``
|
||||
- ``device_config_spinner_t`` sub-structure containing the minimum/maximum/step values for a ``CONFIG_SPINNER`` option. Can be ``{ 0 }`` if not applicable.
|
||||
|
||||
.. flat-table::
|
||||
@@ -344,16 +344,16 @@ Configuration options can be specified in the ``config`` member of ``device_t``,
|
||||
* - Member
|
||||
- Description
|
||||
|
||||
* - min
|
||||
* - ``min``
|
||||
- Minimum selectable value.
|
||||
|
||||
* - max
|
||||
* - ``max``
|
||||
- Maximum selectable value.
|
||||
|
||||
* - step
|
||||
* - ``step``
|
||||
- Units to be incremented/decremented with the arrow buttons. Note that the user can still type in arbitrary numbers that are within ``min`` and ``max`` but not aligned to ``step``.
|
||||
|
||||
* - selection
|
||||
* - ``selection``
|
||||
- Array of ``device_config_selection_t`` sub-structures containing the choices for a ``CONFIG_SELECTION``, ``CONFIG_HEX16`` or ``CONFIG_HEX20`` option. Can be ``{ 0 }`` if not applicable. Must be terminated with an object with a ``description`` of ``""``.
|
||||
|
||||
.. flat-table::
|
||||
@@ -363,37 +363,37 @@ Configuration options can be specified in the ``config`` member of ``device_t``,
|
||||
* - Member
|
||||
- Description
|
||||
|
||||
* - description
|
||||
* - ``description``
|
||||
- Description for this choice, displayed in the user interface.
|
||||
|
||||
* - value
|
||||
* - ``value``
|
||||
- Integer value corresponding to this choice, used to identify it in the emulated machine's configuration file.
|
||||
|
||||
Configured option values can be read from within the device's ``init`` callback with the ``device_get_config_*`` functions. These functions automatically operate in the context of the device currently being initialized.
|
||||
|
||||
.. note:: ``device_get_config_*`` functions should **never** be called outside of a device's ``init`` callback. You are responsible for reading the options' configured values in the ``init`` callback and storing them in the device's :ref:`state structure <dev/api/device:State structure>` if necessary.
|
||||
|
||||
.. flat-table:: device_get_config_string
|
||||
.. flat-table:: ``device_get_config_string``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - name
|
||||
* - ``name``
|
||||
- The option's ``name``. Accepted option types are ``CONFIG_STRING`` and ``CONFIG_FNAME``.
|
||||
|
||||
* - **Return value**
|
||||
- The option's configured string value, or its ``default_string`` if no value is present. Note that a ``const char *`` is returned.
|
||||
|
||||
.. flat-table:: device_get_config_int / device_get_config_hex16 / device_get_config_hex20
|
||||
.. flat-table:: ``device_get_config_int`` / ``device_get_config_hex16`` / ``device_get_config_hex20``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - name
|
||||
* - ``name``
|
||||
- The option's ``name``. Accepted option types are:
|
||||
|
||||
* ``device_get_config_int``: ``CONFIG_SELECTION``, ``CONFIG_BINARY``, ``CONFIG_INT``, ``CONFIG_SPINNER``, ``CONFIG_MIDI_OUT``, ``CONFIG_MIDI_IN``
|
||||
@@ -403,20 +403,20 @@ Configured option values can be read from within the device's ``init`` callback
|
||||
* - **Return value**
|
||||
- The option's configured integer value (``CONFIG_BINARY`` returns 1 if checked or 0 otherwise), or its ``default_int`` if no value is present.
|
||||
|
||||
.. flat-table:: device_get_config_int_ex / device_get_config_mac
|
||||
.. flat-table:: ``device_get_config_int_ex`` / ``device_get_config_mac``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - name
|
||||
* - ``name``
|
||||
- The option's ``name``. Accepted option types are:
|
||||
|
||||
* ``device_get_config_int_ex``: ``CONFIG_SELECTION``, ``CONFIG_BINARY``, ``CONFIG_INT``, ``CONFIG_SPINNER``, ``CONFIG_MIDI_OUT``, ``CONFIG_MIDI_IN``
|
||||
* ``device_get_config_mac``: ``CONFIG_MAC``
|
||||
|
||||
* - dflt_int
|
||||
* - ``dflt_int``
|
||||
- The default value to return if no configured value is present.
|
||||
|
||||
* - **Return value**
|
||||
|
||||
@@ -8,14 +8,14 @@ DMA
|
||||
|
||||
``86box/dma.h`` provides the ``dma_channel_read`` and ``dma_channel_write`` functions to read or write (respectively) a value from or to an **8237 DMA channel**.
|
||||
|
||||
.. flat-table:: dma_channel_read
|
||||
.. flat-table:: ``dma_channel_read``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - channel
|
||||
* - ``channel``
|
||||
- DMA channel number: ``0``-``3`` for 8-bit channels or ``5``-``7`` for 16-bit channels.
|
||||
|
||||
* - **Return value**
|
||||
@@ -23,17 +23,17 @@ DMA
|
||||
|
||||
May include a ``DMA_OVER`` bit flag (located above the most significant data bit so as to not interfere with the data) indicating that this was the last byte or word transferred, after which the channel is auto-initialized or masked depending on its configuration.
|
||||
|
||||
.. flat-table:: dma_channel_write
|
||||
.. flat-table:: ``dma_channel_write``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - channel
|
||||
* - ``channel``
|
||||
- DMA channel number: ``0``-``3`` for 8-bit channels or ``5``-``7`` for 16-bit channels.
|
||||
|
||||
* - val
|
||||
* - ``val``
|
||||
- 8- (channels ``0``-``3``) or 16-bit (channels ``5``-``7``) value to write to the given DMA channel.
|
||||
|
||||
* - **Return value**
|
||||
@@ -46,29 +46,29 @@ Direct memory read/write
|
||||
|
||||
``86box/mem.h`` provides the ``mem_read*_phys`` and ``mem_write*_phys`` functions, which read or write physical memory directly. These are useful for **PCI devices**, which perform DMA on their own.
|
||||
|
||||
.. flat-table:: mem_readb_phys / mem_readw_phys / mem_readl_phys
|
||||
.. flat-table:: ``mem_readb_phys`` / ``mem_readw_phys`` / ``mem_readl_phys``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - addr
|
||||
* - ``addr``
|
||||
- 32-bit memory address to read.
|
||||
|
||||
* - **Return value**
|
||||
- 8- (``mem_readb_phys``), 16- (``mem_readw_phys``) or 32-bit (``mem_readl_phys``) value read from the given memory address.
|
||||
|
||||
|
||||
.. flat-table:: mem_writeb_phys / mem_writew_phys / mem_writel_phys
|
||||
.. flat-table:: ``mem_writeb_phys`` / ``mem_writew_phys`` / ``mem_writel_phys``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - addr
|
||||
* - ``addr``
|
||||
- 32-bit memory address to write.
|
||||
|
||||
* - val
|
||||
* - ``val``
|
||||
- 8- (``mem_readb_phys``), 16- (``mem_readw_phys``) or 32-bit (``mem_readl_phys``) value to write to the given memory address.
|
||||
|
||||
@@ -10,13 +10,13 @@ Port I/O
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - base
|
||||
* - ``base``
|
||||
- First I/O port (0x0000-0xffff) covered by this handler.
|
||||
|
||||
* - size
|
||||
* - ``size``
|
||||
- Amount of I/O ports (1-65536) covered by this handler, starting at ``base``.
|
||||
|
||||
* - inb
|
||||
* - ``inb``
|
||||
- :rspan:`2` I/O read operation callback functions. Can be ``NULL``. Each callback takes the form of:
|
||||
|
||||
``TYPE callback(uint16_t addr, void *priv)``
|
||||
@@ -26,11 +26,11 @@ Port I/O
|
||||
* ``priv``: opaque pointer (see ``priv`` below);
|
||||
* Return value: 8- (``inb``), 16- (``inw``) or 32-bit (``inl``) value read from this port.
|
||||
|
||||
* - inw
|
||||
* - ``inw``
|
||||
|
||||
* - inl
|
||||
* - ``inl``
|
||||
|
||||
* - outb
|
||||
* - ``outb``
|
||||
- :rspan:`2` I/O write operation callback functions. Can be ``NULL``. Each callback takes the form of:
|
||||
|
||||
``void callback(uint16_t addr, TYPE val, void *priv)``
|
||||
@@ -40,11 +40,11 @@ Port I/O
|
||||
* ``val``: 8- (``outb``), 16- (``outw``) or 32-bit (``outl``) value being written to this port;
|
||||
* ``priv``: opaque pointer (see ``priv`` below).
|
||||
|
||||
* - outw
|
||||
* - ``outw``
|
||||
|
||||
* - outl
|
||||
* - ``outl``
|
||||
|
||||
* - priv
|
||||
* - ``priv``
|
||||
- Opaque pointer passed to this handler's read/write operation callbacks.
|
||||
Usually a pointer to a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
@@ -136,14 +136,14 @@ Any given I/O port can have an **unlimited** amount of I/O handlers, such that:
|
||||
* when a **read** operation occurs, all read callbacks will be called, and their return values will be logically **AND**\ ed together;
|
||||
* when a **write** operation occurs, all write callbacks will be called with the same written value.
|
||||
|
||||
Read callbacks can effectively return "don't care" (without interfering with other handlers) by returning a value with all bits set: ``0xff`` with ``inb``, ``0xffff`` with ``inw`` or ``0xffffffff`` with ``inl``.
|
||||
Read callbacks can effectively return "don't care" (without interfering with other handlers) by returning a value with all bits set: ``0xff`` for ``inb``, ``0xffff`` for ``inw`` or ``0xffffffff`` for ``inl``.
|
||||
|
||||
.. note:: The same callback fallback rules specified above also apply with multiple handlers. Handlers without valid callbacks for the operation's type and width are automatically skipped.
|
||||
|
||||
I/O traps
|
||||
---------
|
||||
|
||||
A second type of I/O handler, **I/O traps** allow a device (usually System Management Mode on chipsets and legacy compatibility on PCI sound cards) to act upon a read/write operation to an I/O port operation without affecting its result.
|
||||
A second type of I/O handler, **I/O traps** allow a device (usually System Management Mode on chipsets or legacy compatibility mechanisms on PCI sound cards) to act upon a read/write operation to an I/O port operation without affecting its result.
|
||||
|
||||
.. container:: toggle
|
||||
|
||||
@@ -210,7 +210,7 @@ A second type of I/O handler, **I/O traps** allow a device (usually System Manag
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - func
|
||||
* - ``func``
|
||||
- Function called whenever an I/O operation of any type or size is performed to the trap's I/O address range. Takes the form of:
|
||||
|
||||
``void func(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)``
|
||||
@@ -221,7 +221,7 @@ A second type of I/O handler, **I/O traps** allow a device (usually System Manag
|
||||
* ``val``: value being written if this operation is a write;
|
||||
* ``priv``: opaque pointer (see ``priv`` below).
|
||||
|
||||
* - priv
|
||||
* - ``priv``
|
||||
- Opaque pointer passed to the ``func`` callback above.
|
||||
Usually a pointer to a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
@@ -235,15 +235,15 @@ A second type of I/O handler, **I/O traps** allow a device (usually System Manag
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - trap
|
||||
* - ``trap``
|
||||
- Opaque pointer representing the I/O trap to remap.
|
||||
|
||||
* - enable
|
||||
* - ``enable``
|
||||
- * ``1`` to enable this trap;
|
||||
* ``0`` to disable it.
|
||||
|
||||
* - addr
|
||||
* - ``addr``
|
||||
- First I/O port (0x0000-0xffff) covered by this trap.
|
||||
|
||||
* - size
|
||||
* - ``size``
|
||||
- Amount of I/O ports (1-65536) covered by this trap.
|
||||
|
||||
106
dev/api/pci.rst
106
dev/api/pci.rst
@@ -22,8 +22,8 @@ PCI devices can be added with the ``pci_add_card`` function in the device's ``in
|
||||
#define FOO_ONBOARD 0x80000000 /* most significant bit set = on-board */
|
||||
|
||||
typedef struct {
|
||||
uint8_t pci_regs[256]; /* 256*8-bit configuration register array */
|
||||
int slot;
|
||||
uint8_t pci_regs[256]; /* 256*8-bit configuration register array */
|
||||
} foo_t;
|
||||
|
||||
static uint8_t
|
||||
@@ -75,17 +75,17 @@ PCI devices can be added with the ``pci_add_card`` function in the device's ``in
|
||||
/* ... */
|
||||
};
|
||||
|
||||
.. flat-table:: pci_add_card
|
||||
.. flat-table:: ``pci_add_card``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - add_type
|
||||
* - ``add_type``
|
||||
- :ref:`PCI slot type <dev/api/pci:Slot types>` to add this card to.
|
||||
|
||||
* - read
|
||||
* - ``read``
|
||||
- :ref:`Configuration space <dev/api/pci:Configuration space>` register read callback. Takes the form of:
|
||||
|
||||
``uint8_t read(int func, int addr, void *priv)``
|
||||
@@ -95,7 +95,7 @@ PCI devices can be added with the ``pci_add_card`` function in the device's ``in
|
||||
* ``priv``: opaque pointer (see ``priv`` below);
|
||||
* Return value: 8-bit value read from this register index.
|
||||
|
||||
* - write
|
||||
* - ``write``
|
||||
- :ref:`Configuration space <dev/api/pci:Configuration space>` register write callback. Takes the form of:
|
||||
|
||||
``void write(int func, int addr, uint8_t val, void *priv)``
|
||||
@@ -105,7 +105,7 @@ PCI devices can be added with the ``pci_add_card`` function in the device's ``in
|
||||
* ``val``: 8-bit value being written from this register index.
|
||||
* ``priv``: opaque pointer (see ``priv`` below);
|
||||
|
||||
* - priv
|
||||
* - ``priv``
|
||||
- Opaque pointer passed to this device's configuration space register read/write callbacks.
|
||||
Usually a pointer to a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
@@ -194,59 +194,49 @@ The most important registers in the standard set are:
|
||||
- Register
|
||||
- Description
|
||||
|
||||
* - 0x00 - 0x01
|
||||
* - ``0x00 - 0x01``
|
||||
- Vendor ID
|
||||
- :rspan:`1` Unique IDs assigned to the device's vendor (2 bytes) and the device itself (2 more bytes). The `PCI ID Repository <https://pci-ids.ucw.cz>`_ is a comprehensive repository of many (but not all) known PCI IDs.
|
||||
|
||||
* - 0x02 - 0x03
|
||||
* - ``0x02 - 0x03``
|
||||
- Device ID
|
||||
|
||||
* - 0x04 - 0x05
|
||||
* - ``0x04 - 0x05``
|
||||
- Command
|
||||
- Control several core aspects of the PCI device:
|
||||
|
||||
* **I/O Space** (bit 0 or 0x0001) should enable all I/O base address registers if set, or disable them if cleared;
|
||||
* **Memory Space** (bit 1 or 0x0002) should enable all memory base address registers if set, or disable them if cleared;
|
||||
* **Interrupt Disable** (bit 10 or 0x0400) should prevent the device from triggering interrupts if set.
|
||||
* **I/O Space** (bit 0 or ``0x0001``) should enable all I/O base address registers if set, or disable them if cleared;
|
||||
* **Memory Space** (bit 1 or ``0x0002``) should enable all memory base address registers if set, or disable them if cleared;
|
||||
* **Interrupt Disable** (bit 10 or ``0x0400``) should prevent the device from triggering interrupts if set.
|
||||
|
||||
* - 0x0e
|
||||
* - ``0x0e``
|
||||
- Header type
|
||||
- Usually ``0`` to indicate a normal PCI header.
|
||||
Bit 7 (``0x80``) must be set if this is the first function (function ``0``) of a :ref:`multi-function device <dev/api/pci:Multi-function devices>`.
|
||||
|
||||
* - 0x10 - 0x13
|
||||
- :rspan:`5` :ref:`dev/api/pci:Base Address Registers`
|
||||
- :rspan:`5` Sets the base address for each memory or :doc:`I/O <io>` range provided by this device.
|
||||
* - ``0x10 - 0x27``
|
||||
- :ref:`dev/api/pci:Base Address Registers`
|
||||
- Sets the base address for each memory or :doc:`I/O <io>` range provided by this device.
|
||||
|
||||
* - 0x14 - 0x17
|
||||
|
||||
* - 0x18 - 0x1b
|
||||
|
||||
* - 0x1c - 0x1f
|
||||
|
||||
* - 0x20 - 0x23
|
||||
|
||||
* - 0x24 - 0x27
|
||||
|
||||
* - 0x2c - 0x2d
|
||||
* - ``0x2c - 0x2d``
|
||||
- Subvendor ID
|
||||
- :rspan:`1` Unique vendor (2 bytes) and device (2 bytes) IDs sometimes assigned to different implementations of the same PCI device without having to change the main Vendor and Device IDs.
|
||||
Usually all ``0`` if the device doesn't call for such IDs.
|
||||
|
||||
* - 0x2e - 0x2f
|
||||
* - ``0x2e - 0x2f``
|
||||
- Subsystem ID
|
||||
|
||||
* - 0x30 - 0x33
|
||||
* - ``0x30 - 0x33``
|
||||
- Expansion ROM
|
||||
- Base address and enable bit for the device's :ref:`option ROM <dev/api/pci:Option ROM>`.
|
||||
Must be read-only if the device does not provide an option ROM.
|
||||
|
||||
* - 0x3c
|
||||
* - ``0x3c``
|
||||
- Interrupt Line
|
||||
- The PIC IRQ number assigned to this device's :ref:`interrupt pin <dev/api/pci:Interrupts>` (see ``Interrupt Pin`` below).
|
||||
This register's contents should be ignored by the device; however, the register itself **must be writable** if the device uses interrupts, since 86Box actively uses its value to route interrupts on machines with early PCI chipsets not capable of IRQ steering.
|
||||
|
||||
* - 0x3d
|
||||
* - ``0x3d``
|
||||
- Interrupt Pin
|
||||
- Read-only value indicating the PCI :ref:`interrupt pin <dev/api/pci:Interrupts>` (``INTx#``) used by this device:
|
||||
|
||||
@@ -276,6 +266,7 @@ The ``func`` parameter passed to a device's configuration space read/write callb
|
||||
.. code-block::
|
||||
|
||||
typedef struct {
|
||||
int slot;
|
||||
uint8_t pci_regs[2][256]; /* two 256*8-bit configuration register arrays,
|
||||
one for each function */
|
||||
} foo_t;
|
||||
@@ -336,8 +327,24 @@ The ``func`` parameter passed to a device's configuration space read/write callb
|
||||
dev->pci_regs[0][0x0e] = 0x80;
|
||||
}
|
||||
|
||||
static void *
|
||||
foo_init(const device_t *info)
|
||||
{
|
||||
/* Allocate the device state structure. */
|
||||
foo_t *dev = /* ... */
|
||||
|
||||
/* Add PCI device. No changes are required here for multi-function devices. */
|
||||
dev->slot = pci_add_card(PCI_ADD_NORMAL, foo_pci_read, foo_pci_write, dev);
|
||||
|
||||
/* Initialize PCI configuration registers. */
|
||||
foo_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t foo4321_device = {
|
||||
/* ... */
|
||||
.init = foo_init,
|
||||
.reset = foo_reset,
|
||||
/* ... */
|
||||
};
|
||||
@@ -360,15 +367,15 @@ The aforementioned base address alignment allows software (BIOSes and operating
|
||||
|
||||
.. container:: bit-table
|
||||
|
||||
.. flat-table:: Memory BAR (example: 4 KB large, starting at 0x10)
|
||||
.. flat-table:: Memory BAR (example: 4 KB large, starting at ``0x10``)
|
||||
:header-rows: 2
|
||||
:stub-columns: 1
|
||||
|
||||
* - Byte
|
||||
- :cspan:`7` 0x13
|
||||
- :cspan:`7` 0x12
|
||||
- :cspan:`7` 0x11
|
||||
- :cspan:`7` 0x10
|
||||
- :cspan:`7` ``0x13``
|
||||
- :cspan:`7` ``0x12``
|
||||
- :cspan:`7` ``0x11``
|
||||
- :cspan:`7` ``0x10``
|
||||
|
||||
* - Bit
|
||||
- 31
|
||||
@@ -411,18 +418,18 @@ The aforementioned base address alignment allows software (BIOSes and operating
|
||||
|
||||
.. raw:: html
|
||||
|
||||
Flags (<abbr title="Read-only">RO</span>)
|
||||
<abbr title="Read-only">Flags</span>
|
||||
- ``0``
|
||||
|
||||
.. flat-table:: I/O BAR (example: 64 ports large, starting at 0x14)
|
||||
.. flat-table:: I/O BAR (example: 64 ports large, starting at ``0x14``)
|
||||
:header-rows: 2
|
||||
:stub-columns: 1
|
||||
|
||||
* - Byte
|
||||
- :cspan:`7` 0x17
|
||||
- :cspan:`7` 0x16
|
||||
- :cspan:`7` 0x15
|
||||
- :cspan:`7` 0x14
|
||||
- :cspan:`7` ``0x17``
|
||||
- :cspan:`7` ``0x16``
|
||||
- :cspan:`7` ``0x15``
|
||||
- :cspan:`7` ``0x14``
|
||||
|
||||
* - Bit
|
||||
- 31
|
||||
@@ -612,6 +619,8 @@ The aforementioned base address alignment allows software (BIOSes and operating
|
||||
foo_remap_io(dev);
|
||||
}
|
||||
|
||||
/* Don't forget to add the PCI device on init first. */
|
||||
|
||||
const device_t foo4321_device = {
|
||||
/* ... */
|
||||
.reset = foo_reset,
|
||||
@@ -634,10 +643,10 @@ The main difference between this register and BARs is that the ROM can be enable
|
||||
:stub-columns: 1
|
||||
|
||||
* - Byte
|
||||
- :cspan:`7` 0x33
|
||||
- :cspan:`7` 0x32
|
||||
- :cspan:`7` 0x31
|
||||
- :cspan:`7` 0x30
|
||||
- :cspan:`7` ``0x33``
|
||||
- :cspan:`7` ``0x32``
|
||||
- :cspan:`7` ``0x31``
|
||||
- :cspan:`7` ``0x30``
|
||||
|
||||
* - Bit
|
||||
- 31
|
||||
@@ -786,7 +795,7 @@ The main difference between this register and BARs is that the ROM can be enable
|
||||
/* Allocate the device state structure. */
|
||||
foo_t *dev = /* ... */
|
||||
|
||||
/* Don't forget to add the PCI device. */
|
||||
/* Don't forget to add the PCI device first. */
|
||||
|
||||
/* Load 32 KB ROM... */
|
||||
rom_init(&dev->rom, "roms/scsi/foo/foo4321.bin", 0, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
@@ -794,6 +803,9 @@ The main difference between this register and BARs is that the ROM can be enable
|
||||
/* ...but don't map it right now. */
|
||||
mem_mapping_disable(&dev->rom.mapping);
|
||||
|
||||
/* Initialize PCI configuration registers. */
|
||||
foo_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,21 +12,21 @@ Starting
|
||||
|
||||
Threads can be started with the ``thread_create`` function. Additionally, the ``thread_wait`` function can be used to wait for a thread's function to return.
|
||||
|
||||
.. flat-table:: thread_create
|
||||
.. flat-table:: ``thread_create``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - thread_func
|
||||
* - ``thread_func``
|
||||
- Function to run in the thread. Takes the form of:
|
||||
|
||||
``void thread_func(void *priv)``
|
||||
|
||||
* ``priv``: opaque pointer (see ``priv`` below).
|
||||
|
||||
* - priv
|
||||
* - ``priv``
|
||||
- Opaque pointer passed to the ``thread_func`` above.
|
||||
Usually a pointer to a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
@@ -34,14 +34,14 @@ Threads can be started with the ``thread_create`` function. Additionally, the ``
|
||||
- ``thread_t`` pointer representing the newly-created thread.
|
||||
That pointer will become **invalid** once the thread's function returns.
|
||||
|
||||
.. flat-table:: thread_wait
|
||||
.. flat-table:: ``thread_wait``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - arg
|
||||
* - ``arg``
|
||||
- ``thread_t`` pointer representing the thread to wait for.
|
||||
|
||||
* - **Return value**
|
||||
@@ -53,7 +53,7 @@ Events
|
||||
|
||||
**Events** allow for synchronization between threads. An event, represented by an ``event_t`` pointer returned by the ``thread_create_event`` function, can be *set* (``thread_set_event`` function) or *reset* (``thread_reset_event`` function), and a thread can wait for an event to be *set* with the ``thread_wait_event`` function. Events that are no longer to be used should be deallocated with the ``thread_destroy_event`` function.
|
||||
|
||||
.. flat-table:: thread_create_event
|
||||
.. flat-table:: ``thread_create_event``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
@@ -63,27 +63,27 @@ Events
|
||||
* - **Return value**
|
||||
- ``event_t`` pointer representing the newly-created event.
|
||||
|
||||
.. flat-table:: thread_set_event / thread_reset_event / thread_destroy_event
|
||||
.. flat-table:: ``thread_set_event`` / ``thread_reset_event`` / ``thread_destroy_event``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - arg
|
||||
* - ``arg``
|
||||
- ``event_t`` pointer representing the event to *set* (``thread_set_event``), *reset* (``thread_reset_event``) or deallocate (``thread_destroy_event``).
|
||||
|
||||
.. flat-table:: thread_wait_event
|
||||
.. flat-table:: ``thread_wait_event``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - arg
|
||||
* - ``arg``
|
||||
- ``event_t`` pointer representing the event to wait for.
|
||||
|
||||
* - timeout
|
||||
* - ``timeout``
|
||||
- Maximum amount of time in **milliseconds** (not microseconds, unlike :doc:`timers <timer>`) to spend waiting for this event to be *set*. If set to ``-1``, this function will not return until the event is *set*.
|
||||
|
||||
* - **Return value**
|
||||
@@ -97,7 +97,7 @@ Mutexes
|
||||
|
||||
`Mutexes <https://en.wikipedia.org/wiki/Mutual_exclusion>`_, also known as **locks**, can control access to a shared resource, ensuring no concurrent modifications or other issues arise from multiple threads attempting to use the same resource at the same time. A mutex, represented by a ``mutex_t`` pointer returned by the ``thread_create_mutex`` function, can be *locked* with the ``thread_wait_mutex`` function (which waits until the mutex is *released*) and *released* with the ``thread_release_mutex`` function. Additionally, the status of a mutex can be independently checked with the ``thread_test_mutex`` function. Mutexes that are no longer to be used should be deallocated with the ``thread_close_mutex`` function.
|
||||
|
||||
.. flat-table:: thread_create_mutex
|
||||
.. flat-table:: ``thread_create_mutex``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
@@ -107,25 +107,25 @@ Mutexes
|
||||
* - **Return value**
|
||||
- ``mutex_t`` pointer representing the newly-created mutex.
|
||||
|
||||
.. flat-table:: thread_wait_mutex / thread_release_mutex / thread_close_mutex
|
||||
.. flat-table:: ``thread_wait_mutex`` / ``thread_release_mutex`` / ``thread_close_mutex``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - arg
|
||||
* - ``arg``
|
||||
- ``mutex_t`` pointer representing the mutex to *lock* (``thread_wait_mutex``), *release* (``thread_release_mutex``) or deallocate (``thread_close_mutex``).
|
||||
If this mutex is locked, ``thread_wait_mutex`` will not return until the mutex is *released* by another thread.
|
||||
|
||||
.. flat-table:: thread_test_mutex
|
||||
.. flat-table:: ``thread_test_mutex``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - arg
|
||||
* - ``arg``
|
||||
- ``mutex_t`` pointer representing the mutex to check.
|
||||
|
||||
* - **Return value**
|
||||
|
||||
@@ -51,28 +51,28 @@ Timers can be added with the ``timer_add`` function. The best place for adding a
|
||||
/* ... */
|
||||
};
|
||||
|
||||
.. flat-table:: timer_add
|
||||
.. flat-table:: ``timer_add``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - timer
|
||||
* - ``timer``
|
||||
- Pointer to a ``pc_timer_t`` object stored somewhere, usually in a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
* - callback
|
||||
* - ``callback``
|
||||
- Function called every time the timer's period is reached. Takes the form of:
|
||||
|
||||
``void callback(void *priv)``
|
||||
|
||||
* ``priv``: opaque pointer (see ``priv`` below).
|
||||
|
||||
* - priv
|
||||
* - ``priv``
|
||||
- Opaque pointer passed to the ``callback`` above.
|
||||
Usually a pointer to a device's :ref:`state structure <dev/api/device:State structure>`.
|
||||
|
||||
* - start_timer
|
||||
* - ``start_timer``
|
||||
- Part of the :ref:`legacy API <dev/api/timer:Legacy API>`, should always be ``0``.
|
||||
|
||||
Triggering
|
||||
@@ -92,7 +92,7 @@ The ``timer_on_auto`` function can be used to start (with the provided microseco
|
||||
|
||||
typedef struct {
|
||||
uint8_t regs[256];
|
||||
pc_timer_t countdown_timer; /* remember to timer_add on init, per the example above */
|
||||
pc_timer_t countdown_timer; /* don't forget to timer_add on init, per the example above */
|
||||
} foo_t;
|
||||
|
||||
static void
|
||||
@@ -101,14 +101,16 @@ The ``timer_on_auto`` function can be used to start (with the provided microseco
|
||||
/* Get the device state structure. */
|
||||
foo_t *dev = (foo_t *) priv;
|
||||
|
||||
/* Restart timer automatically if bit 1 (0x02) of register 0x80 is set. */
|
||||
/* Restart timer automatically if the relevant
|
||||
bit (see register description below) is set. */
|
||||
if (dev->regs[0x80] & 0x02)
|
||||
timer_on_auto(&dev->countdown_timer, 100.0);
|
||||
}
|
||||
|
||||
/* Example: writing to I/O port register 0x__80:
|
||||
/* Our device handles I/O port register 0x__80 like this:
|
||||
- Bit 0 (0x01) set: start 100-microsecond countdown timer;
|
||||
- Bit 0 (0x01) clear: stop countdown timer. */
|
||||
- Bit 0 (0x01) clear: stop countdown timer;
|
||||
- Bit 1 (0x02) set: automatically restart timer. */
|
||||
static void
|
||||
foo_outb(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -118,24 +120,24 @@ The ``timer_on_auto`` function can be used to start (with the provided microseco
|
||||
/* Handle writes to register 0x80. */
|
||||
if ((addr & 0xff) == 0x80) {
|
||||
dev->regs[0x80] = val;
|
||||
if (val & 0x01)
|
||||
if (val & 0x01) /* bit 0 set */
|
||||
timer_on_auto(&dev->countdown_timer, 100.0);
|
||||
else
|
||||
else /* bit 0 clear */
|
||||
timer_on_auto(&dev->countdown_timer, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
.. flat-table:: timer_on_auto
|
||||
.. flat-table:: ``timer_on_auto``
|
||||
:header-rows: 1
|
||||
:widths: 1 999
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
|
||||
* - timer
|
||||
* - ``timer``
|
||||
- Pointer to the timer's ``pc_timer_t`` object.
|
||||
|
||||
* - period
|
||||
* - ``period``
|
||||
- Period after which the timer callback is called, in microseconds (1/1,000,000th of a second or 1/1,000th of a millisecond) as a ``double``.
|
||||
A period of ``0.0`` stops the timer if it's active.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user