# How webMAN MOD Handles Multi-Disc PSXISO Support with USB Eject/Insert Triggers

> Discover how webMAN MOD enables seamless multi-disc PSXISO support by intelligently tracking USB eject and insert events for uninterrupted gameplay.

- Repository: [Aldo Vargas/webman-mod](https://github.com/aldostools/webman-mod)
- Tags: internals
- Published: 2026-02-24

---

**webMAN MOD automatically advances to the next disc in multi-disc PSXISO games by monitoring USB eject/insert events through the `check_multipsx` state tracker and the `mount_on_insert_usb()` polling mechanism.**

webMAN MOD enables seamless playback of multi-disc PlayStation 1 games on PlayStation 3 by detecting specific filename patterns and monitoring USB drive hot-swap events. When a game is marked as multi-disc, the system enters a wait state that tracks USB presence and automatically mounts the next disc image upon physical re-insertion of the drive.

## Detecting Multi-Disc PSXISO Titles

The detection logic resides in [`include/scan/games_html.h`](https://github.com/aldostools/webman-mod/blob/main/include/scan/games_html.h), where the `is_multi_cd()` function scans filenames for multi-disc indicators during directory scanning.

```c
/* include/scan/games_html.h – lines 274-280 */
static char *is_multi_cd(const char *name)
{
    char *p = strstr(name, "CD");
    if (!p) { p = strcasestr(name, "Vol"); }
    if (!p)  p = strcasestr(name, "Disc");
    return p;                 // non-NULL → multi-disc name
}

```

When `set_sort_key()` processes entries in `/PSXISO` or `/PSXGAMES`, it invokes `is_multi_cd()` to identify titles spanning multiple volumes. The function returns a non-NULL pointer if the filename contains **"CD"**, **"Vol"**, or **"Disc"**, flagging the entry for multi-disc handling.

## Initializing the Multi-Disc State

During the mount operation, `mount_game()` sets the `multiCD` boolean flag based on the filename check:

```c
/* include/mount/mount_lastgames.h – lines 34-40 */
bool multiCD = (is_multi_cd(_path) != NULL);
if (!multiCD) goto mounting_done;

```

If `multiCD` is true, the system records the current USB state in the `check_multipsx` variable defined in [`include/mount/mount.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount.h) (line 25):

```c
/* include/mount/mount.h – line 25 */
static int8_t check_multipsx = NONE;   // NONE = -1

```

The value is populated in [`include/mount/mount_rawiso.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount_rawiso.h) (line 17):

```c
/* include/mount/mount_rawiso.h – line 17 */
if (multiCD) check_multipsx = !isDir("/dev_usb000");   // remember USB state

```

This **signed byte** stores `0` when `/dev_usb000` is present at mount time, or `1` when the device is already ejected, creating a toggle mechanism for the polling loop.

## Polling for USB Eject/Insert Triggers

The XMB polling routine continuously monitors for USB state changes. In [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) (line 242), the main loop invokes the trigger check:

```c
/* include/poll/poll.h – line 242 */
mount_on_insert_usb(_IS_ON_XMB_, msg);

```

The core logic in [`include/mount/mount.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount.h) (lines 1401-1412) compares the current USB presence against the stored `check_multipsx` value:

```c
/* include/mount/mount.h – lines 1401-1412 */
else if ((check_multipsx >= 0) && IS_INGAME)
{
    if (isDir("/dev_usb000") == check_multipsx)   // USB appears again
    {
        check_multipsx = NONE;
        show_msg(STR_GAMEUM);                    // "Game Unmounted"
        wait_for("/dev_usb000", 5);               // give user time to re-plug
        mount_game("_next", MOUNT_NEXT_CD);       // mount next CD
    }
}

```

When the physical USB device is removed and re-inserted, the equality condition matches, resetting `check_multipsx` to `NONE` (-1) and invoking `mount_game()` with the `MOUNT_NEXT_CD` directive to load the subsequent disc image.

## Manual Disc Ejection via Web Commands

Users can manually trigger the eject sequence without physically removing hardware by accessing the `/eject.ps3` endpoint. This command invokes `eject_insert(1, 0)` defined in [`include/cmd/insert_eject.h`](https://github.com/aldostools/webman-mod/blob/main/include/cmd/insert_eject.h), which sends a fake disc eject event via `cobra_send_fake_disc_eject_event()` and sets the `check_multipsx` state if a multi-disc game is active.

The automatic mounting sequence requires no additional scripting; the polling loop handles the transition seamlessly when the USB device reappears or when the eject command is issued.

## Summary

- **Filename Detection**: The `is_multi_cd()` function in [`include/scan/games_html.h`](https://github.com/aldostools/webman-mod/blob/main/include/scan/games_html.h) identifies multi-disc sets by scanning for "CD", "Vol", or "Disc" substrings.
- **State Tracking**: The `check_multipsx` variable stores the initial USB presence state as an `int8_t`, enabling the system to detect changes.
- **Event Polling**: `mount_on_insert_usb()` in [`include/mount/mount.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount.h) monitors `/dev_usb000` status during gameplay, triggering `mount_game("_next", MOUNT_NEXT_CD)` upon re-insertion.
- **Manual Control**: The `/eject.ps3` command provides software-based disc ejection without physical USB removal.

## Frequently Asked Questions

### How does webMAN MOD detect multi-disc PSXISO files?

The system scans filenames during directory enumeration using `is_multi_cd()` in [`include/scan/games_html.h`](https://github.com/aldostools/webman-mod/blob/main/include/scan/games_html.h). If the filename contains **"CD"**, **"Vol"**, or **"Disc"** (case-insensitive for the latter two), the function returns a non-NULL pointer, causing `mount_game()` to set the `multiCD` flag and initialize the USB monitoring state.

### What happens when I eject the USB drive during gameplay?

When you eject the USB drive containing the PSXISO files, the system notes the absence of `/dev_usb000`. Upon re-insertion, the polling loop detects that `isDir("/dev_usb000")` now matches the stored `check_multipsx` value, automatically invoking `mount_game("_next", MOUNT_NEXT_CD)` to load the next disc in the sequence.

### Can I trigger disc changes without physically removing the USB?

Yes. Accessing `http://<ps3-ip>/eject.ps3` triggers the `eject_insert(1, 0)` function in [`include/cmd/insert_eject.h`](https://github.com/aldostools/webman-mod/blob/main/include/cmd/insert_eject.h), which sends a fake disc eject event and prepares the system for the next mount operation. This software-based method achieves the same result as physical USB hot-swapping.

### Where is the multi-disc logic implemented in the source code?

The multi-disc implementation spans several files: [`include/scan/games_html.h`](https://github.com/aldostools/webman-mod/blob/main/include/scan/games_html.h) handles detection, [`include/mount/mount_lastgames.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount_lastgames.h) and [`include/mount/mount_rawiso.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount_rawiso.h) manage state initialization, [`include/mount/mount.h`](https://github.com/aldostools/webman-mod/blob/main/include/mount/mount.h) contains the `mount_on_insert_usb()` polling logic (lines 1401-1412), and [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) (line 242) integrates the checks into the main XMB polling loop.