MS HIDlib v0.4
--------------
(c) Fabio Ricardo Schmidlin, 2020
Licensed as LGPL. Please check the details in the LICENSE.TXT file.

HIDlib is a library that implements easy and efficient auto-detection and
handling of MSX-HID compliant devices. For a detailed description about
the MSX-HID protocol, please check the respective article on the MSX-Wiki at
https://www.msx.org/wiki/MSX-HID


=Introduction=

Are the MSX HID details and awkwardness driving you programmers insane??
- The MSX1 BIOS doesn't support a mouse or trackball?!
- Do you find it annoying that the mouse pointer gets stuck to going down+right
  when the mouse is disconnected in applications with mouse support?
- Tired of wearing your the joystick ports of your favorite MSX computer by
  being forced to disconnect non-joystick devices (mouse, touchpad, etc)
  every time you want to play a game, even if you are only using the keyboard?
- Would you like easy multi-button joystick support?
- The proprietary protocols are an insane babel?
- Wanting better analog devices support beyond the GTPAD interface?
- Feeling that some devices have obscure protocols and are hard to program,
  like the Light gun, Vaus Arkanoid paddle, etc?
- Do you think that it's boring to have to manually select the type of the
  device connected to the joystick port, when everything else on MSX is
  plug-and-play?

HIDlib deals with all these issues and has the following features:

- Designed to use fast and efficient algorithms
- It's fully compliant to the MSX coding guidelines. This means that the
  underlying hardware can be changed transparently, or the BIOS functions can
  be redirected and everything will still work.
- While this library is huge, only the functions you actually use will be
  compiled in. This means that no memory will be wasted with unused code.
- Auto-detection is optional (though recommended). If you prefer, the drivers
  can be individually used and you can implement a manual selection in some
  menu in the game.
- It has its own mouse / trackball / light-pen drivers for the MSX1 that can be
  optionally be compiled-in, since those machines have no support for such
  devices on their BIOSes. But it will automatically fallback to the BIOS
  access on MSX2 and higher machines. This way, a program that redirects
  such BIOS routines (SofaRun / NandemoSCC style) will be supported at least
  on the newer MSX generations.
- It also features drivers for the following devices:
  - MSX Light Gun
  - Arkanoid Vaus Paddle
  - Micomsoft XE-1AP, XE-1AJ and Sharp CZ-8NJ2
  - Sega Megadrive 3-button joypad
  - Sega Megadrive 6-button joypad
  - Sega Megadrive MK-1654 Multi-tap (and compatibles)
  - Sega Saturn digital joypad
  - Sega Saturn analog joystick
  - Light pen (Sanyo interface)
  - Light pen (V9938 interface)
  - PWM Analog devices
  - IBM DA-15 joysticks
  - Atari 2600 dual paddle


==Notes==

1) This library is licensed as LGPL, detailed in the license.txt file. You're
only allowed to use this library if you agree with the terms contained in the
license.txt file.

2) Be aware that this code is still alpha and might be heavily changed in
future releases. Since its completely based on reverse-engineering, the code had
to be restructured many times to reflect the new findings and use the best
possible algorithms for that. It might need to happen again if new devices are
reverse engineered, but it seems stable enough to be released now.

3) The library is not micro-optimized, nor it's meant to be for now, for the
reasons explained in note-2. Micro-optimized code would have made such
restructurings nearly impossible, for little gain.

4) It's not advisable to force the light-pen driver to be used on MSX Turbo-R
machines. Such machines should use the TRnewdrv set of drivers instead, as this
will allow much easier updates in the future if necessary.

5) Please do not modify the library to use direct I/O. It's not worth to ruin
the compatibility, the main reason for the MSX existence, to save some few
cycles per frame.

6) If you use this library in your program, please be kind and mention it in
the credits.    ;)

7) There might still be some references to the term "signature" in the code and
docs. This term was changed to "fingerprint" to better express how the devices
are detected.

=Programmer's blurb=

1) General purpose port protocol drivers

The centerpiece of this library is the JOYLIB.GTJOYDIG function. It's
responsible for reading the standard 2-button joystick and shall be called at
most once per frame, at the interrupt handling routine. The data it has read
from the device must be stored in a variable for later use by the main program
loop.
If JOYLIB.GTJOYDIG detects that a different device was connected to the
specified general purpose port, it will return the carry flag set, a DEVID
code and a PWM analog channel mask. Your software must then begin calling
instead the appropriate specific protocol driver to handle that device, until
the driver signals a disconnection, also by a carry flag being set. This will
tell your program that it must return to the state where it does the usual
calls to JOYLIB.GTJOYDIG again.

Since an image says more than a thousand words, the following diagram shows the
finite-state machine that your program must have, to handle each general purpose
port input on each frame: 


   +-----------------+  Another protocol     +-------------------+
   |                 |  detected             |                   |
   | JOYLIB.GTJOYDIG +---------------------->| Specific protocol |
   |                 |                       |      driver       |
   +---------------+-+                       |                   |
      ^  ^         |                         +---------------+---+
      |  |   MSX   |                                         |
      |  | Joystick|                           device        |
      |  +---------+                           disconnection |
      |                                        detected      |
      +------------------------------------------------------+


The "Specific protocol drivers" might be:
- JOYLIB.GTJOYMEG3: Megadrive 3-button protocol
- JOYLIB.GTJOYMEG6: Megadrive 6-button protocol
- JOYLIB.GTJOYSATD: Saturn digital joypad
- JOYLIB.GTMULTITAP: Megadrive multi-tap
- ALGLIB.GTPWM: Generic PWM devices
- ALGLIB.GTPDLVAUS: Arkanoid Vaus paddle
- ALGLIB.GTSAT3LDEV: Saturn 3-line protocol device
- ALGLIB.GTXE1AJA: Micomsoft XE-1AJ analog mode
- ALGLIB.GTXE1AJD: Micomsoft XE-1AJ digital mode
- GUNLIB.GTLGUNCRT1: Read the light-gun without raster effects
- GUNLIB.GTLGUNCRT2: Read the light-gun with raster effects (MSX2 or higher)
- MOUSELIB.GTMOUSE: Mouse or trackball, with disconnection detection and
  support for the improved GTPAD interface that has mouse wheel support.
- TOUCHLIB.GTTPAD: Get the touchpad coordinates

The "another protocol detected" transition is simplified in the diagram. In
real world, there's an additional intermediary state there to confirm that the
same fingerprint is read for at least 1 second. In each time a different
fingerprint is read inside this period, the machine returns to the central
JOYLIB.GTJOYDIG state. Only after the fingerprint is confirmed for a whole
second that the state is changed to the "Specific protocol driver". This is
necessary because not all pins of the DE9 connector get a good electric
contact at the same time while the plug is being inserted. So some spurious
fingerprints might be read on insertion.

In some rare cases where there are fingerprint colisions, an intermediary
detection step might be present between JOYLIB.GTJOYDIG and the "Specific
protocol driver", to extend the detection and differentiate between the two
dev



2) Light-pen port driver

The light-pens are connected to specific ports instead of the General-purpose
ports. The MSX standard supports two of such ports simultaneously:

- Port1: Usually a Sanyo interface
- Port2: Usually a V9938 built-in interface

Since these ports are specific, no detection is tried. They're also used with
specific drivers:

- TOUCHLIB.GTSCRCOORD: Light-pen, get the screen coordinates that are being
  touched
- TOUCHLIB.GTSCRCALIBR: Light-pen, calibration

3) Specific implementation details of the HIDlib

a) As described in the MSX-HID wikipedia article, the device fingerprints are
   composed by two 6-bit values, followed by at least one additional 6-bit
   value that is used to differentiate devices from the same family. In HIDlib,
   for performance reasons, the first two 6-bit values of the fingerprint are
   condensed into a single byte "DEVID" with some bit juggling that reuses some
   otherwise illegal ranges.
b) Also for performance reasons, JOYLIB.GTJOYDIG only returns the 3rd 6-bit
   value for PWM devices, as the PWM mask. If the drivers need additional bytes
   to differentiate between devices of the same family, they must implement it
   themselves.
c) Similarly to (b), in some rare cases an additional detection step might
   be necessary between GTJOYLIB and the "Specific Protocol Driver". It
   will fetch additional bytes to differentiate devices from the same family,
   or also perform any eventual additional detection necessary to resolve
   some rare fingerprint conflicts like the Light-gun versus the XE-1AJ. This
   complementary differentiation step is only executed once, as soon as such
   DEVID is detected.

Both (b) and (c) were enforced by design in the architecture, as a way to keep
the detection made by JOYLIB.GTJOYDIG very light, with only three reads and
two writes to the general purpose port.


=Sample code=

HIDTEST.COM is the showcase utility for this library. It uses all drivers and
all features extensively. You can take a look at its source code if you need
more detailed examples of how the functions are meant to be used.



