* docs(input): user guide for the mouse, and why no titledb row ships PR 4 of 4 of the input-devices track (epic #428), steps 8-9 of the design spec. Step 8 was "titledb: JagDoomEX rows gain {virtualjaguar_p2_device, mouse_st} -- only if step 5 confirmed JagDoomEX reads the mouse". It does not, so no row ships, and the reason is recorded where the next person will look for it. JagDoomEX does not read port 2. Verified by disassembly against every JagDoomEX CRC in titledb (each reproduced by applying the matching IPS patch to the verified retail dump 0x5E2CDBC0), plus the local Doom (World) EX.j64 (0xEE7B84EB) and the newest patch archive (JagDoomEX-ips-250318.7z, which reapplies to the existing 0x35743B9C row). Every build: - writes only the port-1 row selects $81FE/$81FD/$81FB/$81F7 -- the port-2 nibble is $F in all four, so every port-2 row is deselected; - ORs #$F0FFFFFC into the read before folding it into an 8-bit accumulator, so $F14000 bits 12-15 (the lines a mouse adapter drives) cannot reach the result; - accounts for all 11 absolute-long $F14000 references as 8 in that poll, one move.l #$100 at init and two lea $F14000,a0 in the EEPROM driver. There is no third path to the register. A row would therefore disconnect the port-2 RetroPad for a title that reads nothing from port 2, in exchange for no function. #429's "auto-select the mouse for JagDoomEX by CRC" checklist item is not applicable to any released build. Elansar was the other candidate and it cannot have a row either, for a structural reason rather than an evidential one: titledb is keyed on cartridge CRCs and libretro.c deliberately never hashes a disc image, so no CD title can auto-select a device. That dissolves the "which wiring case does Elansar's Atari/Amiga selector mean" question for this PR -- whichever it is, it stays a manual option choice. Defender of the Crown, Gridrunner and Star Wars Arcade are absent from the corpus, so their CRCs are unverifiable and no row is guessed for them. New docs/input-devices-user-guide.md covers the options, the three wiring cases and how to tell you picked the wrong one, why raising sensitivity past the game's poll rate buys lag rather than speed, the mouse-capable titles, the reproduced-not-broken hardware quirks, and the known limitation that real-frontend mouse routing is unverified (RetroArch has historically bound mice to port index 0; #449 deliberately shipped no speculative port-0 fallback). docs/jaguar-mouse-adapter-mapping.md section 8 F is updated: the JagDoomEX half of "not attempted" is now done and negative; Elansar is still not disassembled and item A is still open. No behaviour change -- the joymatrix identity digests are asserted unchanged. Refs #429, #428. Stacked on #446 and #449. Co-Authored-By: Claude Opus 5 <[email protected]> * docs(input): match the guide to what actually merged in #449 The user guide was written against the pre-review mouse snapshot. Three of its claims no longer describe the merged code: - the port-2 pad is not dropped the moment a mouse is selected, only once the frontend has proven it routes mouse state (inputdev_live[]); - a frontend setting JOYPAD/NONE releases its claim back to the core option rather than forcing a pad; - the symptom of the unverified-routing limitation is therefore "mouse does nothing, pad still works", not "port 2 is dead". --------- Co-authored-by: Claude Opus 5 <[email protected]>
36 KiB
Atari ST / Amiga mouse adapter → Jaguar $F14000 bit mapping
Research spike for #433, blocking #429 (ST/Amiga mouse support).
Status: #429 is unblocked. The ST and Amiga pin → row/column-bit tables are
VERIFIED against four mutually independent sources (a wiring diagram, the adapter
author's own 68000 driver, the Jaguar Technical Reference V10, and an independent vendor
pinout table). The row-0 pad matrix they land on agrees bit-for-bit with what
src/jerry/joystick.c already models — but a mouse adapter is not a matrix device
(it never sees the row select; see §7), so the device shape itself is new work. The PS/2
question is answered from vendor documentation (§6). Residual open
items — all sign/permutation choices settled by one test, none blocking — are in
§8 Unresolved / not sourced.
Answers to #433's five questions: §4 (1 and 3), §2 + §4 (2), §6 (4), §5 (5).
No emulator code was written for this spike.
1. Sources
| # | Source | Kind | Used for |
|---|---|---|---|
| S1 | http://www.mdgames.de/jag_eng.htm#DIGITALMOUSE → jagmouse.gif — "Atari Jaguar Mouse Connector by Matthias Domin, for digital mice (Atari STM1 or PCM1)" |
Schematic / wiring diagram | ST adapter wiring, quadrature waveform |
| S2 | http://www.mdgames.de/twomice2_20071230.zip → twomice2.s — Domin's own 68000 test program (derived from Atari's JOYPAD.S) |
Author's driver source | ST and Amiga adapter pinouts (header comment), row select, decode tables |
| S3 | http://www.mdgames.de/colmouse.zip → READMOUS.TXT — Domin's mouse driver notes + earlier readmouse routine |
Author's prose + source | Quadrature decode table, required poll rate |
| S4 | docs/atari-jaguar-1999/Technical Reference v10.pdf (Jaguar Technical Reference V10.0, SgM Electrosoft), §"Signals and Pin outs", §"Register Addressing – Digital Inputs", §"Standard Jaguar Controller Matrix", §"Rotary 'Tempest' Controller" |
Hardware manual | Physical connector pin ↔ J/B signal names, register bit layout, row codes |
| S5 | https://wiki.icomp.de/wiki/DE-9_Mouse (Individual Computers hardware wiki, DE-9 mouse comparison table) |
Vendor hardware wiki | Independent ST and Amiga mouse DE-9 pinouts |
| S6 | https://retrostuff.org/2013/12/31/atari-jaguar-mouse-adapter/ |
Build log | Corroborates S1 as the reference; ST/Amiga "not directly compatible"; Elansar */# |
| S7 | src/jerry/joystick.c (this repo) |
Our model | Terms the mapping is expressed in |
Note on fetching S1/S2/S3
https://mdgames.de fails TLS negotiation (TLSV1_ALERT_INTERNAL_ERROR) — this is the
failure recorded on #433 and #429. The site serves fine over plain HTTP. Use:
curl -sL http://www.mdgames.de/jag_eng.htm # index, has #DIGITALMOUSE anchor
curl -sL http://www.mdgames.de/jagmouse.gif # the wiring diagram
curl -sL http://www.mdgames.de/twomice2_20071230.zip # TwoMice demo + source
curl -sL http://www.mdgames.de/colmouse.zip # driver + READMOUS.TXT
curl -sL http://www.mdgames.de/oneaxis20060222.zip # single-axis variant
The pages are ISO-8859-1; pipe through iconv -f ISO-8859-1 -t UTF-8. No Wayback
Machine fallback was needed.
2. Jaguar side: what the hardware can express
From S4, §"Signals and Pin outs" (verbatim structure):
| Conn. pin | Port 1 | Port 2 | Description |
|---|---|---|---|
| 1 | J3 | J4 | Bi-directional, used as output (row select) |
| 2 | J2 | J5 | Bi-directional, used as output |
| 3 | J1 | J6 | Bi-directional, used as output |
| 4 | J0 | J7 | Bi-directional, used as output |
| 5 | — | — | Reserved |
| 6 | B0 / LP | B2 | Button input (light gun on Port 1) |
| 7 | +5V | +5V | +5V, 50 mA max |
| 8 | n/c | n/c | Pulled to +5V on 4-player adaptor |
| 9 | Gnd | Gnd | Ground |
| 10 | B1 | B3 | Button input |
| 11 | J11 | J15 | Input only |
| 12 | J10 | J14 | Input only |
| 13 | J9 | J13 | Input only |
| 14 | J8 | J12 | Input only |
| 15 | — | — | Reserved |
Register layout, S4 §"Register Addressing – Digital Inputs":
JOYSTICK $F14000 R/W
Read fedcba98 7654321q f-1 = signals J15..J1 ; q = cart EEPROM data out
Write exxxxxxm 76543210 e = 1 enables J7..J0 outputs
m = audio mute (1 = audio enabled)
7-4 = J7..J4 outputs (Port 2)
3-0 = J3..J0 outputs (Port 1)
JOYBUTS $F14002 RO
Read xxxxxxxx rrdv3210 v = 1 NTSC / 0 PAL
3-2 = button inputs B3 & B2 (Port 2)
1-0 = button inputs B1 & B0 (Port 1)
So for port 2: J12..J15 are $F14000 bits 12..15, and B2/B3 are
$F14002 bits 2/3. Reading a zero means asserted (active low, S4
§"Standard Jaguar Controller Matrix": "Reading a zero means the appropriate button
is depressed.").
Row select
S4: "writing a value of $817E to JOYSTICK would allow you read row 0 of the
first controller connected to Port 1 and the first controller connected to Port 2…
$0070 = Setup read of row 0 (code %0111) of controller 0, port 2."
Domin's driver (S2, S3) writes $817F — the same port-2 row 0 code
%0111 in bits 7-4, with bits 3-0 all high so port 1 is not selected:
move.w #$817f,JOYSTICK ; Socket A of Port 2
move.l JOYSTICK,d0 ; Read joypad, pause button, A button
Row 0 of the standard matrix (S4) is exactly the row that carries the four
direction lines plus A and Pause — which is why the adapter hangs the mouse off it:
| B2 | B3 | J12 | J13 | J14 | J15 | |
|---|---|---|---|---|---|---|
| Row 0 | Pause | A | Up | Down | Left | Right |
The same in src/jerry/joystick.c terms
JoystickWriteWord stores $817F as joystick_ram[0]=$81, joystick_ram[1]=$7F.
The port-2 nibble is (joystick_ram[1] >> 4) & 0x0F == 7, and
joypad1Offset[7] == 0x00 → row 0, base index 0 into joypad1Buttons[].
joypad1Buttons[] index |
Enum | $F14000 read mask |
Bit | Port-2 signal | Conn. pin |
|---|---|---|---|---|---|
| 0 | BUTTON_U |
0xEFFF |
12 | J12 | 14 |
| 1 | BUTTON_D |
0xDFFF |
13 | J13 | 13 |
| 2 | BUTTON_L |
0xBFFF |
14 | J14 | 12 |
| 3 | BUTTON_R |
0x7FFF |
15 | J15 | 11 |
joypad1Buttons[] entry |
$F14002 read mask |
Bit | Port-2 signal | Conn. pin |
|---|---|---|---|---|
BUTTON_A |
0xFFF7 |
3 | B3 | 10 |
BUTTON_PAUSE |
0xFFFB |
2 | B2 | 6 |
Our existing model is bit-exact against S4. No change to the matrix is required to carry a mouse; the adapter is passive wiring onto lines we already emulate.
3. Mouse side: DE-9 pinouts
From S5 (Individual Computers wiki, DE-9_Mouse), raw table columns:
| DE-9 pin | Atari ST mouse | Amiga mouse |
|---|---|---|
| 1 | XB | /V-Pulse (YA) |
| 2 | XA | /H-Pulse (XA) |
| 3 | YA | /VQ-Pulse (YB) |
| 4 | YB | /HQ-Pulse (XB) |
| 5 | unused | /Button 3, MMB, Wheel (POTX) |
| 6 | /Button 1, LMB | /Button 1, LMB |
| 7 | VCC (+5V) | VCC (+5V) |
| 8 | GND | GND |
| 9 | /Button 2, RMB | /Button 2, RMB (POTY) |
The ST column matches S1's diagram exactly (S1 labels pins 1/2/3/4 as XB/XA/YA/YB and 6/7/8/9 as left button/+5V/GND/right button). Two independent sources, identical.
Amiga naming convention: H/HQ are the two horizontal quadrature phases, V/VQ
the two vertical ones. So the axis pairing is {1,3} = vertical and {2,4} =
horizontal — the opposite grouping to the ST's {1,2} = X, {3,4} = Y. That is the
incompatibility, and it is why an adapter cannot serve both mice with one wiring.
4. Adapter wirings (VERIFIED)
4a. Atari ST adapter
S1 (diagram table, verbatim) and S2 (source header) agree exactly:
; The pinout for the adapter for Atari ST digital mice:
; DSUB 9 male - Jaguar DSUB-HD15 male
; 1 - 14 ( J8/J12)
; 2 - 13 ( J9/J13)
; 3 - 12 (J10/J14)
; 4 - 11 (J11/J15)
; 5 - not connected
; 6 - 10 ( B1/ B3)
; 7 - 7 ( +5V DC)
; 8 - 9 ( Gnd)
; 9 - 6 ( B0/ B2)
Resolved through §2 and §3 into the terms joystick.c uses — port 2, row select
$817F:
| ST mouse pin | Signal | Jag pin | Port-2 line | $F14000/$F14002 bit |
joypad1Buttons[] slot |
|---|---|---|---|---|---|
| 1 | XB (X phase B) | 14 | J12 | $F14000 bit 12 |
BUTTON_U (idx 0) |
| 2 | XA (X phase A) | 13 | J13 | $F14000 bit 13 |
BUTTON_D (idx 1) |
| 3 | YA (Y phase A) | 12 | J14 | $F14000 bit 14 |
BUTTON_L (idx 2) |
| 4 | YB (Y phase B) | 11 | J15 | $F14000 bit 15 |
BUTTON_R (idx 3) |
| 5 | n/c | — | — | — | — |
| 6 | Left button | 10 | B3 | $F14002 bit 3 |
BUTTON_A |
| 7 | +5V | 7 | +5V | — | — |
| 8 | GND | 9 | Gnd | — | — |
| 9 | Right button | 6 | B2 | $F14002 bit 2 |
BUTTON_PAUSE |
All active low (0 = asserted).
- X axis = bits 12 + 13 (the Up/Down lines), A phase on bit 13.
- Y axis = bits 14 + 15 (the Left/Right lines), A phase on bit 14.
Cross-check against S2's ST decode table (AxisTestbits, first entry of each pair):
XA = KEY_D (bit 13) ✔, XB = KEY_U (bit 12) ✔, YA = KEY_R (bit 15),
YB = KEY_L (bit 14). The X entries match the wiring exactly; the Y entries are
A/B-swapped relative to the diagram — see
Y-phase labelling. This is a sign
convention only, absorbed by dirtab_vertical; the pairing (bits 14+15 = Y) is
unaffected and agreed by both.
Domin's own comments confirm the pairing in prose:
; Joyport-input pins for buttons R and L are tied to YA and YB of the mouse-adapter; Joyport-input pins for buttons U and D are tied to XA and XB of the mouse-adapter
4b. Amiga adapter
S2 source header, verbatim:
; And here ist the pinout for an Amiga-mouse-adapter.
; DSUB 9 male - Jaguar DSUB-HD15 male
; 1 - 11 (J11/J15)
; 2 - 13 ( J9/J13)
; 3 - 12 (J10/J14)
; 4 - 14 ( J8/J12)
; 5 - not connected
; 6 - 10 ( B1/ B3)
; 7 - 7 ( +5V DC)
; 8 - 9 ( Gnd)
; 9 - 6 ( B0/ B2)
Only mouse pins 1 and 4 are swapped relative to the ST adapter. Buttons and power are identical.
| Amiga mouse pin | Signal | Jag pin | Port-2 line | Bit | joypad1Buttons[] slot |
|---|---|---|---|---|---|
| 1 | V (Y phase A) | 11 | J15 | $F14000 bit 15 |
BUTTON_R (idx 3) |
| 2 | H (X phase A) | 13 | J13 | $F14000 bit 13 |
BUTTON_D (idx 1) |
| 3 | VQ (Y phase B) | 12 | J14 | $F14000 bit 14 |
BUTTON_L (idx 2) |
| 4 | HQ (X phase B) | 14 | J12 | $F14000 bit 12 |
BUTTON_U (idx 0) |
| 5 | n/c | — | — | — | — |
| 6 | Left button | 10 | B3 | $F14002 bit 3 |
BUTTON_A |
| 7 | +5V | 7 | +5V | — | — |
| 8 | GND | 9 | Gnd | — | — |
| 9 | Right button | 6 | B2 | $F14002 bit 2 |
BUTTON_PAUSE |
- X axis = bits 12 + 13 — same lines as ST.
- Y axis = bits 14 + 15 — same lines as ST.
The dedicated Amiga adapter deliberately normalises an Amiga mouse onto the identical
Jaguar-side lines as the ST adapter. The pin-1/pin-4 swap exists precisely to undo the
Amiga's {1,3}-vertical / {2,4}-horizontal grouping. Domin says so operationally:
an Amiga mouse on the Amiga adapter is used in mode 1, the same mode as an ST mouse
on the ST adapter (S2 header: "If you have an Amiga-mouse and this adapter you can
use the software in mode '1' with the red canvas").
4c. Amiga mouse in an ST-wired adapter (the "pick your mouse type" case)
S2 header: "to run the software in mode '2' with the blue canvas is only necessary if you have an Amiga-mouse and the above described 'Atari ST mouse'-adapter."
This is the case a software ST/Amiga selector exists to serve: one physical adapter, either mouse. Composing the ST adapter wiring (§4a) with the Amiga mouse pinout (§3):
| Amiga mouse pin | Signal | Jag pin | Bit | Axis role |
|---|---|---|---|---|
| 1 | V (Y phase A) | 14 | 12 | Y-A |
| 2 | H (X phase A) | 13 | 13 | X-A |
| 3 | VQ (Y phase B) | 12 | 14 | Y-B |
| 4 | HQ (X phase B) | 11 | 15 | X-B |
- X axis = bits 13 + 15 (A on 13, B on 15).
- Y axis = bits 12 + 14 (A on 12, B on 14).
Cross-validation. S2's mode-2 (Amiga) entries in AxisTestbits are:
bitsYA: dc.l KEY_R (ST) dc.l KEY_U (Amiga) -> bit 12
bitsYB: dc.l KEY_L (ST) dc.l KEY_L (Amiga) -> bit 14
bitsXA: dc.l KEY_D (ST) dc.l KEY_D (Amiga) -> bit 13
bitsXB: dc.l KEY_U (ST) dc.l KEY_R (Amiga) -> bit 15
X = {13, 15}, Y = {12, 14}, with A on 13 and 12 respectively — an exact match, including phase sense.
This agreement is the strongest Amiga evidence in this document, and it is mutual: Domin's mode-2 table only resolves into clean, unmixed axis pairs if S5's Amiga column (1=V, 2=H, 3=VQ, 4=HQ) is correct; and S5's Amiga column is only consistent with S2's Amiga adapter wiring (§4b) if that same grouping holds. Two sources with no common ancestry — a German homebrew author's 2006 assembler and a German hardware vendor's wiki table — each independently confirm the other. Neither was written with the other in view.
4d. Summary of the three cases
| Case | Adapter | Mouse | X pair (A, B) | Y pair (A, B) |
|---|---|---|---|---|
| 1 | ST | ST | bits 13, 12 | bits 14, 15 |
| 2 | Amiga | Amiga | bits 13, 12 | bits 15, 14 |
| 3 | ST | Amiga | bits 13, 15 | bits 12, 14 |
Buttons are identical in all three: LMB → $F14002 bit 3 (BUTTON_A),
RMB → $F14002 bit 2 (BUTTON_PAUSE).
Cases 1 and 2 use the same lines; they differ only in Y phase sense (a sign flip on the vertical axis — see unresolved). Case 3 is a genuinely different pairing.
5. Quadrature decode
Phase ordering — there is none
Item 5 of #433 asks whether phase output is "X then Y, or interleaved". Neither: the
premise does not apply. XA, XB, YA and YB are four parallel wires (Jaguar pins 14,
13, 12, 11) sampled simultaneously by a single read of $F14000 in row 0. There is no
time multiplexing and no ordering between the axes. Both axes advance independently and
concurrently. Verified from S1 (four separate conductors) and S2 (one
move.l JOYSTICK,d0 yields all four bits).
Encoding
S1's waveform panel shows XA and XB as two square waves in quadrature, annotated
"positive direction" (XA leading) and "negative direct." (XB leading), with the
parenthetical (YA)/(YB) marking the Y axis as identical in form.
S3 gives the state encoding as a weighted sum, s = 2·A − 1·B:
XA (YA) 0 1 1 0 0 1 --> 0 +2 +2 0 0 +2
XB (YB) 0 0 1 1 0 0 --> 0 0 -1 -1 0 0
------------------
0 2 1 -1 0 2 --> positive
XA (YA) 0 0 1 1 0 0 --> 0 0 +2 +2 0 0
XB (YB) 0 1 1 0 0 1 --> 0 -1 -1 0 0 -1
------------------
0 -1 1 2 0 -1 --> negative
Equivalently, in (A, B) pairs, the standard 2-bit Gray code:
positive: (0,0) -> (1,0) -> (1,1) -> (0,1) -> (0,0) ... A leads B
negative: (0,0) -> (0,1) -> (1,1) -> (1,0) -> (0,0) ... B leads A
S2 replaces the arithmetic with a 16-entry lookup indexed by
(old_state << 2) | new_state, where state = (B << 1) | A. Its comment block states
the full truth table:
; New Old
; 0,0 ; 0,0 --> no movement / 0,1 --> negative / 1,0 --> positive / 1,1 --> undetermined
; 0,1 ; 0,0 --> positive / 0,1 --> no movement / 1,0 --> undetermined / 1,1 --> negative
; 1,0 ; 0,0 --> negative / 0,1 --> no movement / 1,0 --> undetermined / 1,1 --> positive
; 1,1 ; 0,0 --> undetermined/ 0,1 --> positive / 1,0 --> negative / 1,1 --> no movement
Direction sense, from dirtab_horizontal / dirtab_vertical (S2):
| Transition | Horizontal | Vertical |
|---|---|---|
| A leads B (positive) | KEY_R |
KEY_D |
| B leads A (negative) | KEY_L |
KEY_U |
| No change | none | none |
| Diagonal jump (2 states) | -1 — silently discarded |
-1 — silently discarded |
So A-leads-B = right / down.
Corroborating Atari spec for a quadrature device on these very pins
S4 documents the Rotary "Tempest" controller, which puts a two-phase optical encoder
on J10/J11 (port 1 pins 12/11 — the same physical pins the mouse adapter uses for
its Y axis), read from row 0 alongside Pause and A:
Anticlockwise Sequence J10 (pin 12) 0 1 1 0 0 1 1 ...
J11 (pin 11) 0 0 1 1 0 0 1 ...
Clockwise Sequence J10 (pin 12) 0 0 1 1 0 0 1 ...
J11 (pin 11) 0 1 1 0 0 1 1 ...
Atari's own row-0 matrix for it reads … J14 = Phase 0, J15 = Phase 1. This is bit-for-bit
the same Gray-code sequence as S3's table, on the same lines, sanctioned by the
hardware manual. It independently establishes that a quadrature device read from port
row 0 on the direction lines is a supported, documented Jaguar controller shape — the
ST mouse adapter is not an off-spec hack.
Rate ceiling
S3: "The readmouse-function should be called more than 1000 times per second to get good results. After the readmouse()-call the RLDU-results should be evaluated immediately; the mouse-buttons (redirected to FireA and Pause) should be evaluated the normal 50/60 times per second."
S2 implements exactly that with a 1200 Hz timer IRQ: "Now a Timer-IRQ (1200Hz) is used to read from port 2 where the digital mouse (or RotaryController) is plugged in."
The binding constraint is not the mouse's physical pulse rate — it is the decoder. A
transition of two Gray-code states between consecutive polls indexes a -1 entry
and is silently dropped (see table above); the decoder cannot recover direction from
it. Therefore:
Emitted state transitions must not exceed the rate at which the game polls row 0 of port 2. Exceeding it does not merely lag — it loses motion outright, and near the threshold it loses motion non-uniformly, which reads as jitter.
A game polling only at VBL (50/60 Hz) would cap out around 50–60 states/s ≈ 12–15 quadrature cycles/s, which is why Domin insists on a >1 kHz timer IRQ. The emulator cannot know a given title's poll rate a priori.
Recommendation (not a sourced fact): advance the synthesised quadrature by at most
one Gray-code state per read of $F14000 with port 2's row select asserted — i.e.
self-clock the emission against the game's own polling. That is correct for any poll rate
without needing to know it, and it degrades to "pointer lags" rather than "pointer
jitters or reverses" when the accumulated delta outruns the poll rate.
Note the hook must be any port-2 row, not row 0 specifically: per §7 the adapter is row-blind, so a game is free to poll the mouse from rows 1–3, and a row-0-only hook would return a frozen mouse to such a title.
6. PS/2 adapter — vendor-documented as ST-compatible
Answer: yes, effectively — one implementation covers both. This rests on a vendor behavioural statement, not a schematic; see the caveat below.
AtariAge's own product page for the PS/2 adapter (S8,
https://store.atariage.com/products/ps2-mouse-adapter-for-atari-jaguar) states:
"Use a PS/2 mouse with games that include Atari ST mouse support, as well as any future games that include ST mouse support."
"Plug the 15-pin end of the adapter into the second controller port on your Jaguar and then plug your PS/2 mouse into the other end. Boot up the game and select Atari ST mouse as your controller."
The listed compatible titles are the same set as the ST/Amiga adapter — Defender of the Crown, Gridrunner (Jeff Minter Classics), Elansar, Star Wars Arcade (ST port). The instruction to select Atari ST in games that offer an ST/Amiga choice is a direct statement that the adapter's Jaguar-side output is the ST arrangement of §4a.
Caveat, and why no schematic can settle it. PS/2 is a clocked bidirectional serial protocol; the Jaguar side is parallel quadrature. A PS/2 adapter therefore must contain a microcontroller synthesising quadrature from PS/2 packets. Whether that output is ST-identical is a firmware choice, not a wiring fact — only firmware source or measurement could prove it. The vendor instruction above is the strongest available evidence and is consistent with the ecosystem argument: ST quadrature on port 2 row 0 is the only mouse encoding any shipped Jaguar title is known to decode, so an adapter emitting anything else would work with nothing.
Consequence for #429: the PS/2 adapter needs no separate emulation path. It is the ST wiring (case 1 of §4d).
(Songbird also sells a Jaguar PS/2 mouse adapter, S9 — its page carries no mouse-type or technical detail at all, listing only ImpulseX and Vroom as compatible titles.)
7. Implementation traps (INFERRED from the S4 matrix, not from any mouse document)
The generating principle: the adapter is row-blind
Look at what the adapter does not connect. In both wirings (§4a, §4b) the Jaguar-side
pins used are 6, 7, 9, 10, 11, 12, 13, 14. Jaguar pins 1–4 are absent — and those are
exactly J4–J7, the port-2 row-select outputs (S4 §"Signals and Pin outs").
The adapter cannot see the row select at all. It is passive wiring from a mouse that has no notion of rows. Therefore all six port-2 input lines —
J12,J13,J14,J15,B2,B3— carry the mouse's state continuously and identically in rows 0, 1, 2 and 3.
A Jaguar pad is a matrix; a mouse adapter is not. This single fact generates every trap below, and it is the main thing an implementer will otherwise rediscover the hard way.
Corroboration from S2: Domin's program contains a normal full four-row scan
($817F/$81BF/$81DF/$81EF, lines 408–480) and a readmouse routine that
deliberately reads only row 0 and ignores the rest. That asymmetry in the author's own
code is consistent with the effect being real and sidestepped rather than absent.
Consequences
-
Direction lines produce phantom keypad presses. In rows 1/2/3, bits 12–15 carry
*/7/4/1, then 2/5/8/0, then 3/6/9/# (S4 standard matrix;joypad1Offset[]andjoypad1Buttons[]indices 4–15 injoystick.c). With the mouse moving, a game that performs a full four-row scan sees keypad digits asserted on every row.The emulator's divergence runs the opposite way from a naive fix: if #429 simply sets
joypad1Buttons[BUTTON_U/D/L/R](indices 0–3), the core returns the mouse in row 0 and nothing in rows 1–3, where hardware returns the same bits. Both the naive model and the hardware differ from each other — the mouse device must drive the raw$F14000bits 12–15 irrespective of the selected row, not occupy pad slots. -
LMB reads as A and B and C and Option.
joystick.creportsBUTTON_A/B/C/OPTIONon$F14002bit 3 according to the selected row (mask[4][2]inJoystickReadWord). A real adapter holds bit 3 low in every row while LMB is down. -
RMB perturbs controller-type identification.
B2is theC1/C2/C3type-ID bit in rows 1/2/3 (S4 §"Standard Jaguar Controller Matrix" and §"Identifying Controller Types":C2 C3 = 1 1means "Standard Jaguar Joypad (or nothing connected)"). Holding RMB pullsB2low in those rows too, changing the reported type — so a title that re-probes controller type while the right button is held may misidentify the device. Our current model decodesBUTTON_PAUSEon bit 2 only in row 0 and hard-codes$FF6Felsewhere, so it does not reproduce this today.
Unrelated but adjacent
-
$F14002bit 4 is the NTSC/PAL bit (vin the S4 layout,vjs.hardwareTypeNTSCinjoystick.c). Nothing mouse-related may disturb it. -
Guardrail for #429 holds trivially. The adapter changes no register semantics — it only asserts existing port-2 input lines. With no mouse device selected,
$F14000/$F14002behaviour is unchanged by construction.
8. Unresolved / not sourced
Everything below is explicitly not established. None of it blocks #429; each item is a permutation or sign choice over the same four bits, settled by one test against a real title.
A. Which case an in-game "Atari / Amiga" selector expects
Elansar's * = Atari / # = Amiga selector is documented (S6, and #429's own
description), but nothing retrieved connects Elansar's two modes to Domin's mode 1 /
mode 2. Elansar is a different author (Orion_/Powertrip). Its "Amiga" mode could mean:
- case 3 (Amiga mouse in an ST-wired adapter) — pairing X = {13,15}, Y = {12,14}; or
- case 2 (a dedicated Amiga adapter) — same pairing as ST, Y phases swapped.
These are different bit pairings and produce visibly different wrong behaviour if mismatched (case 3 read as case 1 gives motion coupled diagonally between axes, not just an inverted axis).
Evidence favouring case 3 (strong, but still not a schematic). AtariAge's product page for the ST/Amiga adapter (S10) describes one physical adapter serving both mice, with the type chosen in software:
"Plug the 15-pin end of the adapter into the second controller port on your Jaguar and then plug your Atari ST or Amiga mouse into the other end. Boot up the game and select which type of mouse you have plugged in and you're good to go!"
and it additionally supports "any Atari ST-compatible trackballs" — which only works if that single adapter is ST-wired. So the shipping hardware is an ST-wired adapter into which an Amiga mouse may be plugged, and the in-game selector exists to compensate. That is precisely case 3, and it is the same situation Domin's mode 2 addresses. The remaining gap is only that no source states Elansar implements the selector this way rather than some other convention of its own.
Resolution: implement §4d as a 3-entry table and settle the Elansar mapping empirically — drive synthetic quadrature per case and observe which produces clean 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), 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
(Y phase B) on bit 14, whereas the ST adapter lands YA on bit 14 and YB on bit 15 —
i.e. the two are A/B-swapped on the vertical axis, which inverts Y. Domin nonetheless
uses one software mode for both. Possible explanations, none sourced:
- ST and Amiga mice differ in encoder orientation, so the swap cancels a physical difference (plausible — it would explain why he chose that wiring);
- S5's
(YA)/(YB)parentheticals on the Amiga column are the wiki author's own editorial equivalence to ST naming rather than a measurement, so the A/B labels may not be comparable across columns at all; - Domin simply tolerated an inverted Y.
Resolution: a sign flip, verifiable in one run against a real title. Recorded so it is not silently guessed.
C. Y-phase labelling slip in S2's ST table
S1's diagram puts ST YA on Jaguar pin 12 (bit 14) and YB on pin 11 (bit 15).
S2's ST software table names bit 15 YA and bit 14 YB — the reverse. The
physical wiring is not in doubt (S1 and S2's own header comment agree, and S5
independently confirms the ST mouse pinout); only the driver's internal variable naming
differs, and dirtab_vertical absorbs it. Flagged because anyone reading S2 alone
would derive an inverted Y.
D. PS/2 adapter — answered by vendor prose, not by schematic
§6 answers item 4 in the affirmative on the strength of AtariAge's own instruction to "select Atari ST mouse". No schematic or firmware source was located, and by the nature of the device none would be conclusive anyway (§6 caveat). Treat "PS/2 = ST wiring" as vendor-documented behaviour, adequate for #429, not as a measured fact.
E. jag_sim / MiSTer — no model; no netlist tie-breaker exists
Checked because netlists outrank prose in this project (cf. #354). Confirmed negative in both (method and results in §9): neither models a mouse adapter.
This is the expected result, not a gap. The ST adapter is passive wiring onto the
standard pad matrix, so there is nothing for a netlist to model beyond the matrix itself
— which S4 specifies and joystick.c already implements bit-exactly.
One useful positive did come out of jag_sim: netlists/jerry/JMISC.NET implements the
joystick output enable as Joyen := LDP2Q (joyen, din[15], joy1w, resetl) — the write
data bit 15 latched as the J7..J0 output enable, corroborating S4's register layout
at netlist level (and hence Domin's $81xx writes).
F. Not attempted
- 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.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:
- The pad poll writes only the port-1 row selects
$81FE,$81FD,$81FB,$81F7. The port-2 nibble is$Fin all four, i.e. every port-2 row is deselected. - The poll reads
move.l $F14000and immediately doesor.l #$F0FFFFFC,d0before folding into an 8-bit accumulator. That mask clears everything except$F14000bits 8-11 and$F14002bits 0-1 — the port-1 columns.$F14000bits 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.
9. Search log
Recorded so the next person does not repeat it.
Succeeded
| Attempt | Outcome |
|---|---|
WebFetch https://mdgames.de/... |
Failed — TLSV1_ALERT_INTERNAL_ERROR. Same failure recorded on #429/#433. |
curl --tlsv1.2 https://mdgames.de/ |
Failed — HTTP 000, TLS handshake refused. |
curl http://mdgames.de/ (plain HTTP) |
Worked, HTTP 200. This is the fix. No Wayback needed. |
retrostuff.org build log |
Gave the exact primary URL (jag_eng.htm#DIGITALMOUSE). |
http://www.mdgames.de/jagmouse.gif |
Wiring diagram (S1). Converted GIF→PNG with sips to read. |
http://www.mdgames.de/twomice2_20071230.zip |
Best single source — twomice2.s header carries both ST and Amiga adapter pinouts plus the ST/Amiga decode tables (S2). |
http://www.mdgames.de/colmouse.zip |
READMOUS.TXT: decode arithmetic + poll-rate guidance (S3). |
docs/atari-jaguar-1999/Technical Reference v10.pdf |
Physical pinout, register bits, row codes, standard matrix, Rotary quadrature spec (S4). Extract with pdftotext -layout. |
wiki.icomp.de/wiki/DE-9_Mouse |
Independent ST and Amiga DE-9 pinouts (S5). Fetch the raw HTML — the summarising fetch transposed the ST and Amiga columns. |
| AtariAge product pages (S8, S10) | PS/2 = "select Atari ST mouse"; ST/Amiga = one adapter, in-game selection, ST-compatible trackballs. |
Came up empty
| Attempt | Outcome |
|---|---|
GitHub code search for mouse/quadrature/F14000 in ElectronAsh/jag_sim, Torlus/Jaguar_MiSTer_master |
0 hits — but the API appears not to index these repos (0 hits for joystick too). Do not trust this method here; clone and grep. |
git clone + grep jag_sim |
Only "mouse" hit repo-wide is GPL boilerplate (soft/hello/gpl.txt). 0 hits for "quadrature". No mouse model. |
git clone + grep Torlus/Jaguar_MiSTer_master |
ps2_mouse appears only in sys/hps_io.v, the generic MiSTer framework file; never referenced by Jaguar.sv or any core source. The core never consumes it. No mouse model. |
| Web search for open-source Jaguar mouse/PS-2 adapter firmware | Nothing Jaguar-specific. Nearest neighbours are all Atari-computer-side or Jaguar-pad-to-USB (opposite direction): jjmz/Atari-Quadrature-USB-Mouse-Adapter, IJeffray/WeeMouse, raphnet/jaguar_usb, dgrubb/Jaguar-USB-tap. jjmz's project does emit ST/Amiga quadrature and has explicit ST vs Amiga modes, so it may be useful as a second opinion on phase conventions, but it targets Atari/Amiga computers, not the Jaguar port, and was not relied on here. |
| Songbird PS/2 adapter page (S9) | No mouse-type or technical detail. |
| The Brewing Academy ST adapter page | No schematic. |
Additional sources referenced above
| # | Source |
|---|---|
| S8 | https://store.atariage.com/products/ps2-mouse-adapter-for-atari-jaguar |
| S9 | https://songbird-productions.com/product/ps2-mouse-adapter/ |
| S10 | https://store.atariage.com/products/atari-stamiga-mouse-adapter-for-atari-jaguar |
| S11 | ElectronAsh/jag_sim, netlists/jerry/JMISC.NET (joystick output enable) |
10. Verdict for #429
Unblocked. #433's "Done when" asks for a written pin → row/column-bit table for both ST and Amiga with sources cited; §4a, §4b and §4c deliver that, with four independent sources in agreement and no contradiction requiring a schematic-over-prose tiebreak (the only two label discrepancies, §8 B and §8 C, are sign conventions internal to one source's variable naming).
What an implementer needs is entirely in §2, §4d and §5:
- Row select
$817F→ port 2 row 0 is what the known drivers use (alreadyjoypad1Offset[7] == 0x00injoystick.c). - Four direction bits 12–15 and two button bits 3/2, all active low — but driven row-independently, not through the pad matrix (§7). This is the one part that is genuinely new work rather than reuse.
- Three wiring cases as a table (§4d); case 1 for ST and PS/2, case 3 the expected Amiga selector meaning.
- Emit at most one Gray-code state per port-2 read.
Carry forward into #429: settle §8 A (which case the Elansar selector means) and §8 B (Y sign) by test, and honour the two button traps in §7.