From 21227970dcff21e4c87a64dc709bd195ef7e87d3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 19 Mar 2022 12:09:17 -0300 Subject: [PATCH] API documentation improvements --- dev/api/device.rst | 80 +++++++++++++++++++++++++++++++++------------- dev/api/index.rst | 2 +- dev/api/io.rst | 34 ++++++++++---------- 3 files changed, 77 insertions(+), 39 deletions(-) diff --git a/dev/api/device.rst b/dev/api/device.rst index 71d71e8..091fd5c 100644 --- a/dev/api/device.rst +++ b/dev/api/device.rst @@ -3,7 +3,7 @@ Devices ======= -The **device** is the main unit of emulated components in 86Box. Each device has one or more ``device_t`` structures, which contain metadata about the device itself, several callbacks and an array of user-facing configuration options. Unless otherwise stated, all structures and functions in this page are provided by ``86box/device.h``. +The **device** is the main unit of emulated components in 86Box. Each device has one or more ``device_t`` structures, 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 :header-rows: 1 @@ -40,27 +40,26 @@ The **device** is the main unit of emulated components in 86Box. Each device has Use this value to tell different subtypes of the same device, for example. * - :cspan:`1` init - - Function called whenever this device is initialized, either from starting 86Box or from a hard reset. Can be ``NULL``. Takes the form of: + - 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)`` - where ``info`` is a pointer to this ``device_t`` structure, and - the return value is an opaque pointer passed to the other callbacks below, usually a :ref:`state structure `. - The opaque pointer will be invalid if this function is ``NULL``. + * ``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 `. * - :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)`` - where ``priv`` is the opaque pointer that was returned by ``init``. + * ``priv``: opaque pointer previously returned by ``init``. * - :cspan:`1` reset - Function called whenever this device undergoes a soft reset. Can be ``NULL``. Takes the form of: ``void reset(void *priv)`` - where ``priv`` is the opaque pointer that was returned by ``init``. + * ``priv``: opaque pointer previously returned by ``init``. * - :rspan:`2` @@ -68,23 +67,22 @@ The **device** is the main unit of emulated components in 86Box. Each device has
union
- available - - Function called whenever this device's availability is being checked. Can be ``NULL``. Takes the form of: + - 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()`` - where the return value must be ``1`` if the device is available for selection, or ``0`` if it is unavailable (due to missing ROMs, for example). - The device will always be available if this function is ``NULL``. + * Return value: ``1`` if the device is available for selection, or ``0`` if it is unavailable (due to missing ROMs, for example). * - 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)`` - where ``x`` and ``y`` are the relative movement coordinates, - ``z`` is the relative wheel coordinate, - ``b`` is the button state (bit 0 / 0x01 set for left button, bit 1 / 0x02 set for right button, bit 3 / 0x04 set for middle button), - ``priv`` is the opaque pointer that was returned by ``init``, and - the return value must be ``0`` if the change was processed or any other value otherwise. + * ``x`` and ``y``: relative mouse movement coordinates (signed); + * ``z``: relative wheel movement coordinate (signed); + * ``b``: button state: bit 0 (0x1) set if left button pressed, bit 1 (0x2) set if right button pressed, bit 2 (0x4) set if middle button pressed; + * ``priv``: opaque pointer previously returned by ``init``; + * Return value: ``0`` if the change was processed, or any other value otherwise. * - register_pci_slot - Reserved for future use. @@ -94,17 +92,17 @@ The **device** is the main unit of emulated components in 86Box. Each device has ``void speed_changed(void *priv)`` - where ``priv`` is the opaque pointer that was returned by ``init``. + * ``priv``: opaque pointer previously returned by ``init``. * - :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)`` - where ``priv`` is the opaque pointer that was returned by ``init``. + * ``priv``: opaque pointer previously returned by ``init``. * - :cspan:`1` config - - Array of device configuration options, or ``NULL`` if no options are available. See :ref:`dev/api/device:Configuration`. + - Array of :ref:`device configuration options `, or ``NULL`` if no options are available. State structure --------------- @@ -183,7 +181,45 @@ These options are stored in the emulated machine's configuration file, in a sect midi_in = 0 -Configuration options can be specified in the ``config`` member of ``device_t``, as a pointer to a ``const`` array of ``device_config_t`` objects terminated by an object of ``type`` ``-1``. +Configuration options can be specified in the ``config`` member of ``device_t``, as a pointer to a ``const`` array of ``device_config_t`` objects terminated by an object of ``type`` ``-1``:: + + static const device_config_t foo_config[] = { + { "selection", "Selection", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Option", 0 }, + { "Another option", 1 }, + { "" } + } + }, + { "hex16", "16-bit hex", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { "0x220", 0x220 }, + { "0x330", 0x330 }, + { "" } + } + }, + { "hex20", "20-bit hex", CONFIG_HEX20, "", 0xd8000, "", { 0 }, + { + { "D800h", 0xd8000 }, + { "DC00h", 0xdc000 }, + { "" } + } + }, + { "string", "String", CONFIG_STRING, "Default" }, + { "fname", "Filename", CONFIG_FNAME, "", 0, "File type (*.foo)|*.foo|Another file type (*.bar)|*.bar" }, + { "binary", "Binary", CONFIG_BINARY, "", 1 /* checked by default */ }, + { "int", "Integer", CONFIG_INT, "", 1234 }, + { "spinner", "Spinner", CONFIG_SPINNER, "", 1234, "", { 1204, 1294, 10 } }, + { "mac", "MAC address", CONFIG_MAC, "", 0 } + { "midi_out", "MIDI output", CONFIG_MIDI_OUT, "", 0 }, + { "midi_int", "MIDI input", CONFIG_MIDI_IN, "", 0 }, + { "", "", -1 } + }; + + const device_t foo_device = { + /* ... */ + .config = foo_config + } .. flat-table:: device_config_t :header-rows: 1 @@ -193,7 +229,7 @@ Configuration options can be specified in the ``config`` member of ``device_t``, - Description * - name - - Internal name for this option, used in the emulated machine's configuration file. + - Internal name for this option, stored in the emulated machine's configuration file. * - description - Description for this option, displayed in the user interface. @@ -258,11 +294,11 @@ Configuration options can be specified in the ``config`` member of ``device_t``, - Description for this choice, displayed in the user interface. * - value - - Integer value corresponding to this choice, used in the emulated machine's configuration file. + - Integer value corresponding to this choice, stored in the emulated machine's configuration file. Configured option values can be accessed using ``device_get_config_*`` functions from within the device's ``init`` callback. -.. 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 your device's :ref:`state structure ` if necessary. +.. 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 ` if necessary. .. flat-table:: device_get_config_string :header-rows: 1 diff --git a/dev/api/index.rst b/dev/api/index.rst index d78d983..9cf3261 100644 --- a/dev/api/index.rst +++ b/dev/api/index.rst @@ -1,7 +1,7 @@ API === -This section documents the internal **Application Programming Interface** for implementing devices on 86Box. +This section documents the internal **Application Programming Interface** for extending on 86Box. .. toctree:: :maxdepth: 1 diff --git a/dev/api/io.rst b/dev/api/io.rst index 8f8face..77dd6b8 100644 --- a/dev/api/io.rst +++ b/dev/api/io.rst @@ -23,10 +23,10 @@ Port I/O ``TYPE callback(uint16_t addr, void *priv)`` - where ``TYPE`` corresponds to the operation's width (``uint8_t`` for ``inb``, ``uint16_t`` for ``inw`` or ``uint32_t`` for ``inl``), - ``addr`` is the exact I/O port being read, - ``priv`` is the opaque pointer (see ``priv`` below), and - the return value is the value to be read. + * ``TYPE``: operation width (``uint8_t`` for ``inb``, ``uint16_t`` for ``inw`` or ``uint32_t`` for ``inl``); + * ``addr``: exact I/O port being read; + * ``priv``: opaque pointer (see ``priv`` below); + * Return value: value read from this port. * - inw @@ -37,10 +37,10 @@ Port I/O ``void callback(uint16_t addr, TYPE val, void *priv)`` - where ``TYPE`` corresponds to the operation's width (``uint8_t`` for ``outb``, ``uint16_t`` for ``outw`` or ``uint32_t`` for ``outl``), - ``addr`` is the exact I/O port being written, - ``val`` is the value being written, and - ``priv`` is the opaque pointer (see ``priv`` below). + * ``TYPE``: operation width (``uint8_t`` for ``outb``, ``uint16_t`` for ``outw`` or ``uint32_t`` for ``outl``); + * ``addr``: exact I/O port being written; + * ``val``: value being written to this port; + * ``priv``: opaque pointer (see ``priv`` below). * - outw @@ -66,7 +66,7 @@ When an I/O handler receives an operation with a width for which it has no callb * ``inl`` callback not present, but ``inw`` callback present:: uint32_t val = inw(port); - val |= (inw(port + 1) << 16); + val |= (inw(port + 2) << 16); * ``inl`` and ``inw`` callbacks not present, but ``inb`` callback present:: @@ -77,9 +77,9 @@ When an I/O handler receives an operation with a width for which it has no callb * ``inl``, ``inw`` and ``inb`` callbacks not present:: - uint32_t val = 0xffffffff; + uint32_t val = 0xffffffff; /* don't care */ -The same applies to write callbacks: +The same rule applies to write callbacks: * ``outl`` callback present:: @@ -90,7 +90,7 @@ The same applies to write callbacks: uint32_t val = /* ... */; outw(port, val & 0xffff); - outw(port + 1, (val >> 16) & 0xffff); + outw(port + 2, (val >> 16) & 0xffff); * ``outl`` and ``outw`` callbacks not present, but ``outb`` callback present:: @@ -102,7 +102,9 @@ The same applies to write callbacks: * ``outl``, ``outw`` and ``outb`` callbacks not present: - No operation performed. + Don't care, no operation performed. + +.. note:: Each broken-down operation triggers the I/O handlers for its respective port number, no matter which handlers are responsible for the starting port number. A handler will **never** receive callbacks for ports outside its ``base`` and ``size`` boundaries. This feature's main use cases are devices which store registers that are 8-bit wide but may be accessed with 16- or 32-bit operations:: @@ -117,8 +119,8 @@ This feature's main use cases are devices which store registers that are 8-bit w return dev->regs[addr & 0xff]; /* example: register index = I/O port's least significant byte */ } - /* No foo_inw, so a 16-bit operation will read two 8-bit registers in succession. - No foo_inl, so a 32-bit operation will read four 8-bit registers in succession. */ + /* No foo_inw, so a 16-bit read will read two 8-bit registers in succession. + No foo_inl, so a 32-bit read will read four 8-bit registers in succession. */ Multiple I/O handlers --------------------- @@ -130,4 +132,4 @@ Any given I/O port can have an **unlimited** amount of I/O handlers, such that: 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``. -.. note:: The same callback fallback rules specified above also apply with multiple handlers. +.. 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.