diff --git a/README.md b/README.md index 1294a501..fc303176 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ This is a libretro core, so the whole frontend feature set applies — and the c - **Jaguar CD, two ways.** CUE/BIN and CDI images boot through a high-level-emulated CD BIOS *or* through the real CD BIOS driving emulated BUTCH/DSA/FIFO hardware. Audio CDs play and the Virtual Light Machine visualizer works. ([v3.0.0 notes](docs/RELEASE_NOTES_v3.0.0.md) · [v3.1.0 notes](docs/RELEASE_NOTES_v3.1.0.md)) - **Damaged-rip repair.** CDI images from the old V2 ripper that lost each track's leading bytes used to be rejected outright. The loader now classifies the boot track and repairs slides or head-loss at read time; when bytes are provably gone it logs a precise diagnosis instead of a black screen. ([PR #342](https://github.com/libretro/virtualjaguar-libretro/pull/342)) - **JagLink / netlink link-cable networking.** The Jaguar's link-port serial hardware is emulated at the register level with a TCP transport and a multi-peer hub — Doom deathmatch over LAN validated end to end. ([user guide](docs/netlink-user-guide.md) · [design doc](docs/netlink-design.md)) +- **ST/Amiga mouse adapter.** The port-2 mouse adapter sold by AtariAge and The Brewing Academy (and its PS/2 variant) is emulated from a sourced pin-level mapping, including the fact that the real adapter is *row-blind* — all three wiring cases ship as selectable devices. Opt-in: with no mouse selected the controller register is bit-identical to before, proven by a test. ([user guide](docs/input-devices-user-guide.md) · [mapping](docs/jaguar-mouse-adapter-mapping.md) · [#429](https://github.com/libretro/virtualjaguar-libretro/issues/429)) - **Jaguar GameDrive (JagGD).** Detection plus full 16 MB bank switching (6×1 MB pages over 16 banks), implemented from RetroHQ's published GDBIOS bindings, so GD-locked homebrew boots. ([interface notes](docs/jgd-interface-notes.md) · v3.1.0 #312, #320) - **Memory Track saves.** The Jaguar CD's Memory Track cartridge is emulated — a flash window at `$900000` plus an HLE'd NVM BIOS module — so CD titles keep their saves, round-tripping through the frontend's `.srm`. ([`memory-track.md`](docs/memory-track.md) · [PR #259](https://github.com/libretro/virtualjaguar-libretro/pull/259)) - **A crash watchdog that names the bug.** A runtime watchdog recognises hang and crash signatures (GPU/DSP program-counter escape, wedges, video stalls, CD seek wedges) and writes the diagnosis into your frontend log at the moment of failure — so a bug report points at the subsystem, not just "black screen". ([`crash_detect.c`](src/core/crash_detect.c)) @@ -267,7 +268,7 @@ System clock 26.590906 MHz NTSC / 26.593900 MHz PAL. Full source map: [`docs/sou - **[GitHub Discussions](https://github.com/libretro/virtualjaguar-libretro/discussions)** — questions and compatibility reports. Bring your frontend log. - **[Issues](https://github.com/libretro/virtualjaguar-libretro/issues)** — confirmed bugs. - **[Releases](https://github.com/libretro/virtualjaguar-libretro/releases)** — tagged builds for 16 platforms. The rolling **[`nightly` prerelease](https://github.com/libretro/virtualjaguar-libretro/releases/tag/nightly)** is rebuilt from every push to `develop`; it is gated on *compiling*, not on the test suite — treat it as bleeding edge. -- **[`docs/`](docs)** — the full document index: [network play setup](docs/netlink-user-guide.md), [file formats](docs/README), [source layout](docs/source-layout.md), [savestate compatibility](docs/savestate-compat.md), [ROM patches / soft patching](docs/rom-patches.md), [CD read speed](docs/cd-read-speed.md), [CD known issues](docs/cd-known-issues.md), [cartridge triage](docs/cart-issue-triage.md), [profiling](docs/profiling.md), [release process](docs/release-process.md), [changelog](docs/WHATSNEW), [TODO](docs/TODO), and the distilled JTRM hardware references (`docs/jtrm-*.md`). +- **[`docs/`](docs)** — the full document index: [network play setup](docs/netlink-user-guide.md), [input devices / mouse](docs/input-devices-user-guide.md), [file formats](docs/README), [source layout](docs/source-layout.md), [savestate compatibility](docs/savestate-compat.md), [ROM patches / soft patching](docs/rom-patches.md), [CD read speed](docs/cd-read-speed.md), [CD known issues](docs/cd-known-issues.md), [cartridge triage](docs/cart-issue-triage.md), [profiling](docs/profiling.md), [release process](docs/release-process.md), [changelog](docs/WHATSNEW), [TODO](docs/TODO), and the distilled JTRM hardware references (`docs/jtrm-*.md`). - **[SECURITY.md](SECURITY.md)** — security policy and binary verification. ## Contributors diff --git a/docs/input-devices-user-guide.md b/docs/input-devices-user-guide.md new file mode 100644 index 00000000..cc7f27dd --- /dev/null +++ b/docs/input-devices-user-guide.md @@ -0,0 +1,176 @@ +# Jaguar Input Devices — User Guide + +Virtual Jaguar emulates the **ST/Amiga mouse adapter**, a real port-2 +peripheral sold by AtariAge and The Brewing Academy (and, in a PS/2 flavour, +by AtariAge as well). A handful of Jaguar titles read one instead of a joypad. + +This guide covers what to turn on, which wiring to pick, and the one +limitation you should know about before filing a bug. + +**The mouse is opt-in.** With the options left alone the core behaves exactly +as it did before the feature existed — `$F14000` is bit-identical, proven by +`test/tools/joymatrix_identity`. Nothing here can affect a title you play +with a pad. + +## Core options + +All three live under **Port 2** in the core options menu. + +| Option | Values | Default | +|---|---|---| +| *Port 2 > Controller Type* (`virtualjaguar_p2_device`) | Auto (per-title default), Standard Joypad, Atari ST / PS2 Mouse, Amiga Mouse (ST adapter), Amiga Mouse (Amiga adapter) | Auto | +| *Port 2 > Mouse Sensitivity* (`virtualjaguar_mouse_sensitivity`) | 25% – 400% | 100% | + +*Mouse Sensitivity* only appears while a mouse is actually attached to port 2. + +**Auto currently means Standard Joypad for every title.** See +[No per-title auto-select](#no-per-title-auto-select-and-why) below — that is +a deliberate result, not an unfinished switch. + +Your frontend can also select the device directly (RetroArch: *Controls → +Port 2 → Device Type*), which offers the same four devices. A **mouse** set +that way outranks the core option. Setting the port back to *Joypad* or *None* +releases that claim rather than forcing a pad — the core option decides again, +immediately. + +### Once a mouse is live, the port-2 RetroPad is disconnected + +That is the hardware being faithful, not a bug. The adapter occupies the port; +there is no pad plugged into it. Port 1 is untouched — a mouse on port 2 +cannot perturb port 1's bits, and there is a test asserting exactly that. + +**The pad is not dropped until the mouse has actually moved.** Selecting a +mouse must never leave the port with no working input, and whether your +frontend routes host mouse deltas to port 2 is not something the core can +know in advance (see [the limitation below](#known-limitation-frontend-mouse-routing-is-unverified)). +So port 2 keeps its RetroPad until the frontend reports a non-zero delta or a +mouse button; from that moment the pad stays suppressed for the session, or +until you change the device type. Consequence worth knowing: with a mouse +selected but not routed, port 2 behaves exactly like a joypad. + +## Which wiring do I pick? + +Three real hardware combinations exist, and **they are not compatible with +each other** — the four direction lines carry different axes in each. Picking +the wrong one gives you motion coupled diagonally between the axes, or one +axis inverted, rather than a subtle difference. + +| Option value | The hardware it models | Pick it when | +|---|---|---| +| **Atari ST / PS2 Mouse** (`mouse_st`) | An Atari ST mouse (or an ST-compatible trackball) in an ST-wired adapter — the AtariAge and Brewing Academy ST adapters. **The PS/2 adapter presents the same signals**, so use this for a PS/2 mouse too. | Default choice. This is what almost everyone owns. | +| **Amiga Mouse (ST adapter)** (`mouse_amiga`) | An **Amiga** mouse plugged into that same ST-wired adapter. The two mice differ in how their quadrature lines are pinned, so the axes land differently. | A game offers an in-game "Atari / Amiga" mouse-type selector and you set it to Amiga. That selector normally chooses between these first two rows. | +| **Amiga Mouse (Amiga adapter)** (`mouse_amiga_adapter`) | The rarer dedicated Amiga-wired adapter with an Amiga mouse. | You specifically have that adapter. If you are not sure, you do not. | + +If motion comes out diagonal — moving the mouse left also moves the cursor up +— you have picked the wrong row above. Try the other two. + +The pin-level evidence for all three is in +[`docs/jaguar-mouse-adapter-mapping.md`](jaguar-mouse-adapter-mapping.md) +§4d. Nothing in the table is guessed. + +## Sensitivity, and why more is not always faster + +The emulated adapter can only emit **one quadrature pulse per controller +poll**, because that is the constraint a real game's decoder imposes: a +two-state jump between consecutive polls is ambiguous and the decoder throws +it away. So the core rate-limits to one state per poll, always. + +The practical consequence: raising *Mouse Sensitivity* past what the game's +poll rate can carry buys you **lag, not speed** — the extra motion queues up +and drains at the game's own pace (bounded, so it cannot drift for seconds +after your hand stops). If the pointer feels like it keeps gliding after you +stop, lower the sensitivity rather than raising it. + +## Titles that read a mouse + +Reported mouse-capable Jaguar titles: + +- **Elansar** (CD) — has an in-game mouse-type selector, `*` = Atari, + `#` = Amiga +- **Philia — The Sequel to Elansar** (CD) +- **Defender of the Crown** +- **Gridrunner** (Jeff Minter Classics) +- **Star Wars Arcade** (ST port) + +This list comes from issue #429 and community reports; the core has not +verified each of them against a dump. If you have one of these and the mouse +works (or does not), that is useful — please say so on +[#429](https://github.com/libretro/virtualjaguar-libretro/issues/429). + +**JagDoomEX does not read a mouse** in any build released so far, despite +being the title that motivated the feature. See below. + +## No per-title auto-select, and why + +The core has a per-title defaults database (`src/core/titledb.c`, issue #368) +that can turn options on for a specific game by CRC. **No title gets the mouse +selected automatically**, for two separate reasons: + +**1. JagDoomEX does not read port 2.** Its CRCs are in the database already +(nine of them), so the row was easy to add — but the ROM was disassembled +first, and every build reads port 1 only. It writes only the port-1 row +selects and then masks away the four bits a mouse adapter drives, so the mouse +could not reach the game even if the option were on. Selecting a mouse for it +would only disconnect the port-2 pad in exchange for nothing. If a future +JagDoomEX release adds mouse support it will hash differently from every CRC +we know, so it would need a fresh row anyway. + +**2. The per-title database is cartridge-only.** It is keyed on the CRC of +cartridge content and deliberately never hashes a disc image (a disc CRC would +match nothing it knows while risking a collision with some cartridge's +settings). So **CD titles can never auto-select a device** — which is the +standing answer for Elansar and Philia, the two mouse titles most likely to +prompt the question. Select the mouse by hand for those. + +## Known limitation: frontend mouse routing is unverified + +The Jaguar mouse adapter is a **port 2** device — that is where the hardware +plugs in, that is where every known title reads it, and so that is the only +port the core offers it on. + +RetroArch has historically bound the host mouse to **port index 0**, and we +have not verified on which frontends and versions a mouse selected on port 2 +actually delivers its deltas there. The core deliberately ships **no +speculative port-0 fallback**: silently reading port 1's mouse into a port-2 +device would be a guess, and a wrong guess would be invisible until it +misbehaved. + +If you select a mouse on port 2 and nothing responds to the mouse — while the +port-2 **pad still works normally** — that is the symptom of this limitation +rather than of the emulation. (The pad still working is the deliberate +fallback described above, not a second bug.) Please +report it with your frontend and version on +[#429](https://github.com/libretro/virtualjaguar-libretro/issues/429) — real +frontend data is exactly what is needed to settle it. + +## Behaviour that looks wrong but is not + +The real adapter is wired straight onto the port's input lines and **cannot +see the row select**. It presents the mouse's state identically in all four +row scans. We reproduce that, so three odd-looking behaviours are faithful: + +- while the mouse moves, a title that scans all four rows sees **phantom + keypad digits** (the direction lines are the same wires as `*`/7/4/1, + 2/5/8/0, 3/6/9/`#`); +- the **left button reads as A, B, C and Option** at once; +- holding the **right button** perturbs the controller-type field, so a title + that re-probes what is plugged in while you hold it will misidentify the + device. + +All three happen on real hardware with a real adapter. They are commented as +such at the code sites so nobody "fixes" them later. + +## Not yet implemented + +The **Tempest rotary** controller (#436) is a separate device on the same +track and is not covered here. Lightgun (#437), analog/driving controllers +(#438) and per-axis tuning (#439) are also open. + +## See also + +- [`docs/jaguar-mouse-adapter-mapping.md`](jaguar-mouse-adapter-mapping.md) — + the sourced pin → register-bit mapping this is built from +- [#428](https://github.com/libretro/virtualjaguar-libretro/issues/428) — + input-devices epic +- [#429](https://github.com/libretro/virtualjaguar-libretro/issues/429) — + ST/Amiga mouse diff --git a/docs/jaguar-mouse-adapter-mapping.md b/docs/jaguar-mouse-adapter-mapping.md index f19309b2..276f4ac8 100644 --- a/docs/jaguar-mouse-adapter-mapping.md +++ b/docs/jaguar-mouse-adapter-mapping.md @@ -563,6 +563,15 @@ empirically — drive synthetic quadrature per case and observe which produces c axis-aligned cursor motion. Expect case 3; a mismatch shows up as motion coupled diagonally between axes, which is unmistakable. +*Still open.* The 3-entry table shipped (PR #449) but Elansar has not been run against +it. Note also that whichever way it lands, it cannot become a per-title default: +Elansar and Philia are **CD** titles, and `src/core/titledb.c` is keyed on cartridge +CRCs and deliberately never hashes a disc image (`libretro.c`, the +`info->data && !is_cd_content` guard). Elansar's wiring case will always be a manual +option choice, so the answer belongs in the user guide +([`docs/input-devices-user-guide.md`](input-devices-user-guide.md)), not in the +database. + ### B. Y-axis sign between case 1 and case 2 The dedicated Amiga adapter (§4b) lands the Amiga's `V` (Y phase A) on bit 15 and `VQ` @@ -615,9 +624,41 @@ at netlist level (and hence Domin's `$81xx` writes). - Physical measurement of a real adapter (none on hand). - Contacting AtariAge / The Brewing Academy for a schematic — worth doing for the PS/2 question if it ever becomes load-bearing. -- Disassembling Elansar or JagDoomEX to read their mouse routine directly. **This is the - highest-value unexplored lead for item A** and needs no external source: the row-select - write and bit tests are visible in the ROM. +- ~~Disassembling Elansar or JagDoomEX to read their mouse routine directly.~~ + **JagDoomEX: DONE, and the answer is negative** (see F.1). **Elansar: still not + attempted** — it is a CD title, so its executable has to be pulled out of the disc + image first, and item A remains open until someone does that or runs the game against + each option value. + +#### F.1. JagDoomEX does NOT read a mouse — settled by disassembly + +Checked against every JagDoomEX CRC carried in `src/core/titledb.c` +(`0x754096DB`, `0x4643E9DB`, `0x35743B9C`, `0xAD6B68BA`, `0xC4F4CACF`, `0x1F4EE4A5`, +`0x013A5359`, `0xB92D1CA3`, `0xEA12E234`), each reproduced by applying the matching IPS +patch to the verified retail dump (`Doom - Evil Unleashed (1994).jag`, `0x5E2CDBC0`), +plus the local `Doom (World) EX.j64` (`0xEE7B84EB`) and the newest patch archive +(`JagDoomEX-ips-250318.7z`, which reapplies to `0x35743B9C`). + +Every one of them is **port 1 only**, by two independent mechanisms: + +1. The pad poll writes only the port-1 row selects `$81FE`, `$81FD`, `$81FB`, `$81F7`. + The port-2 nibble is `$F` in all four, i.e. **every port-2 row is deselected**. +2. The poll reads `move.l $F14000` and immediately does `or.l #$F0FFFFFC,d0` before + folding into an 8-bit accumulator. That mask clears everything except `$F14000` + bits 8-11 and `$F14002` bits 0-1 — the port-1 columns. `$F14000` bits 12-15, the + four lines a mouse adapter drives, **cannot reach the result**. + +And there is no third path: all **11** absolute-long `$F14000` references in the image +are accounted for — 8 in that poll (4 writes + 4 reads), one `move.l #$100,$F14000` at +init, and two `lea $F14000,a0` in the EEPROM driver (which reads bit 0 and `$F15000`). +A driver reading the register through a register-indirect base would still need one of +these to load the address. + +Consequence, recorded at the site in `src/core/titledb.c`: **no +`virtualjaguar_p2_device` row ships for JagDoomEX**, and #429's "auto-select the mouse +for JagDoomEX by CRC" checklist item is not applicable to any released build. If a +future release adds mouse support it will hash differently from all nine CRCs above, so +it needs its own row and its own re-check. --- diff --git a/src/core/titledb.c b/src/core/titledb.c index 10a017f2..f9305b0e 100644 --- a/src/core/titledb.c +++ b/src/core/titledb.c @@ -119,7 +119,31 @@ static const TitleDBEntry titledb_table[] = { /* Doom EX romhack family — alias rows inheriting Doom (0x5E2CDBC0)'s * pairs. CRC = IPS patch applied to the verified retail dump; - * boot-verified via cart_boot_probe (issue #409). */ + * boot-verified via cart_boot_probe (issue #409). + * + * NO virtualjaguar_p2_device ROW HERE, and it is not an oversight + * (#429, #428). #429 proposed auto-selecting the ST/Amiga mouse for + * JagDoomEX by CRC; the design spec made that row conditional on + * first confirming the title actually reads port 2. It does not. + * Disassembled against every CRC in this block (plus the 250318 + * archive build, which hashes to 0x35743B9C above): + * + * - the pad poll writes only the port-1 row selects $81FE, $81FD, + * $81FB and $81F7. The port-2 nibble is $F in all four, i.e. + * every port-2 row is deselected; + * - the poll then does or.l #$F0FFFFFC before and.l into an 8-bit + * accumulator, so $F14000 bits 12-15 -- the four lines a mouse + * adapter drives -- cannot reach the result; + * - all 11 absolute-long $F14000 references in the image are + * accounted for: 8 in that poll, one move.l #$100 at init, and + * two lea $F14000,a0 in the EEPROM driver (which reads bit 0). + * There is no other path to the register. + * + * A row here would therefore disconnect the port-2 RetroPad for a + * title that reads nothing from port 2, in exchange for no function. + * Do not add one without re-running that check against the build in + * hand -- a future JagDoomEX release may add mouse support, and it + * will hash differently from every CRC listed here anyway. */ { 0x754096DB, "Doom EX (JagDoomEX)", {