#473 Plug command plugs a device to an occupied port

SD Snatcher

This bug is somehow related to the bug #472.

The console "plug" command plugs a device to a port without unplugging one that is already there.

That is mechanically impossible on the real MSX computer. The port will always stay idle for some time while one device is disconnected and a new one is connected. The lack of this disconnection step causes the autodetection algorithms to fail.

To reproduce the problem, run the same JOYTEST.COM utility that is attached to the bug #442, and try the following steps bellow:

1) Run Joytest v2.2 on MSX-DOS
2) open the openMSX console
3) type "plug joyporta mouse"
4) Move the mouse for some seconds to check that it's working, then leave it idle.
5) type "plug joyporta joymega"

The Joytest will fail to detect that the mouse was changed to a megadrive joypad and will keep showing "MSX mouse" as the device connected to the port. On a real MSX, it will always detect this change properly because the mechanical requirement of disconnecting/connecting devices.


  • Wouter Vermaelen

    You're right, on real hardware it's not possible to infinitely fast switch the device that's plugged into the MSX.

    But I'm not sure what to do about this. If you want you can of course first execute the 'unplug' command before executing 'plug' with the new peripheral. But not requiring an explicit 'unplug' is very convenient. Alternatively we can artificially add some delay between the moment the 'plug' command is given and the moment the peripheral is actually inserted, but then this would be annoying for e.g. Tcl scripting.

    The same (or similar) issue exists for swapping disks. And for disks there are already Tcl scripts that rely on the 'diska' command immediately inserting the disk (typically in combination with the 'diskmanipulator' command).

  • SD Snatcher

    SD Snatcher - 2013-07-17

    Humm. What about a small delay? (1/2 second seems enough) Would that be too annoying for TCL scripting?

    Last edit: SD Snatcher 2013-07-17
  • Wouter Vermaelen

    It's certainly possible to add a small delay. But I'm hesitant to implement this for the following reasons:

    • (most important) There is already a workaround via the 'unplug' command.
    • Everything related to joystick ports (and connectors in general) becomes more complex because next to the plugged/not-plugged states there is now a 3rd state 'about-to-be-plugged'. And this has consequences in the pluggable/connector code, but also in e.g. the savestate code: need to remember how much time remains before the device is actually plugged (this is important for e.g. the reverse function which periodically creates savestates).
    • (least important) Tcl scripting. For example querying the plugged device and re-plugging that is no longer a no-op (it resets the timer). Also it's possible that the plug command reports a certain device is plugged, but when you read from the port (e.g. joystick port but also any other connector port) then it doesn't return the expected values.

    Anyway, the specific problems are not that important. The summary is that it does add complexity and that there already is an easy workaround.

    [I'm mostly guessing in this paragraph] I also wonder if this feature 'really' solves your problem. E.g. what if the mouse/joymega is already plugged before the joytest program starts? Shouldn't the prog be able to correctly detect the device in that situation? And how is that situation different from your original scenario. Or in other words: why does the detection algorithm depend on the history (while that same history is not available when joytest starts)?

  • SD Snatcher

    SD Snatcher - 2013-07-17

    Ok, I'll explain my side so we can try to find a compromise solution.

    I'm currently developing a library to with the following objectives:

    1) Help MSX gamers to use the joyport based devices transparently and with proper hot plug/unplug, or
    2) To fix existing games as they panic if a Mouse (or any other device with a different protocol) is left connected to the joyport
    3) To fix program/games that panic because the Mouse was disconnected and require a reset (like Graph Saurus)

    Joytest is just the example application that will be given with the library.

    On the MSX programmer side, it is implemented like this:

    • It's a state machine
    • There are many protocols for the joyport interface, namely:
    • Traditional joystick.
    • Joymega protocol (aka "TH control method"). It's considered a subset of the previous one.
    • MSX-Mouse
    • MSX-Paddles (unsupported by Joytest as I have none to test and there's no emulation)
    • MSX-Touchpad (unsupported by Joytest as I have none to test and there's no emulation)
    • TH/TR protocol, used by the Sega Saturn Standard PAD
    • 3-Line Handshake protocol, used by the rest of Sega Saturn joyport devices and the Megadrive Multi-Tap

    • The program starts on the "Standard Joystick/unconnected" state. This state reads normal MSX joysticks

    • It will change to another state if a specific signature is detected. Then a module which reads that specific protocol will be used.
    • The joymega detection triggers a sub-state of the joystick protocol, to read the additional buttons. But it's still treated as a joystick device.
    • If a different protocol is detected, causes joytest to change to the respective state that calls the module that deals with that protocol. Each module knows how to detect if its device was disconnected, so it can signal for joytest to return to the default "Standard joystick/unconnected" state.
    • Joymega disconnection detection comes "for free" as part of reading the buttons
    • The MSX-Mouse disconnection detection is a bit tricky. The following heuristic is used:
    • If X=Y=1 is read by GTPAD for more than 20 frames (1/3s)
    • Then check if the raw value being read from the joyport is 3Fh. If it is, signal that the mouse was disconnected. Joytest will then return to the default "Standard joystick/Unconnected" state.

    On the openMSX side, what about having low-level (meant for scripts) and high-level (meant for users) commands? Something like:

    • unplug_lowlevel/plug_lowlevel: Those will be current plug/unplug commands, just renamed. They don't do any tricks and are meant to be used by TCL scripts.
    • New plug/unplug: Those will be high level TCL scripts that keep the state of the port in mind and add any delays necessary. Internally they call the unplug_lowlevel/plug_lowlevel.

    Would that be a plausible solution? Maybe this approach could solve the disk problem you mentioned too.

    The good thing with this approach is that it seems to give solutions for both the "Gamer" and the "openMSX Developer" use cases, which are very different.

    btw, I always consider that openMSX have three main groups of different users with very different requirements. Please check if I captured this correctly:

    1) Plain user/Gamers (just want an easy to use platform to play games/programs without worrying about the details. Don't want to waste time with configurations, command line parameters or investigating why a given MSX software or the emulator isn't working as expected)
    2) MSX Developer (wants all possible details on the MSX inner working, and any features that help him to figure out bugs quickly. For him the emulator is just another developer tool, so he doesn't want to invest more time on it than on the MSX coding itself)
    3) openMSX Developer (wants to deal only with openMSX code & scripts, with minimal Z80 coding. Treats the MSX programs (including the BIOS) as a black box surrounded by the emulator. He wants the emulator to be as fast as possible, easy to maintain and with good scripting support. Doesn't want its code to become inefficient or impossible to maintain.)


Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks