amiga-bootcamp/10_devices/gameport.md
Ilia Sharin f61c26b542 Expand documentation suite: 30+ articles enriched with diagrams, code examples, and hardware details
Graphics: text_fonts (bitmap layout, styles), sprites (DMA, multiplexing), gfx_base (chipset detection), rastport (draw modes, clipping), ham_ehb (mermaid fixes), display_modes (HAM palettes)

Devices: scsi (per-model interfaces, Gayle limits, CD-ROM, native vs vendor drivers), console (ANSI sequences, CON:/RAW:), parallel (CIA registers, pinout), timer (resource exhaustion), gameport (quadrature, XOR state)

Libraries: workbench (WBStartup, AppWindow/Icon/MenuItem), rexxsyslib (ARexx port hosting, command parsing), diskfont (font directory, colour fonts), keymap (rawkey codes, dead keys), locale (catalogue system, date formatting), layers (ClipRect, refresh types), utility (TagItem chains), icon (DiskObject, ToolTypes), iffparse (IFF structure, ByteRun1), expansion (Zorro AutoConfig)

Networking: tcp_ip_stacks (major rewrite - Amiga vs Unix architecture, SANA-II pipeline, PPP/SLIP dial-up, Ethernet cards, MiSTer), bsdsocket (pure API ref), sana2 (buffer hooks, driver requirements), protocols (all code examples). Deduplicated overlap between the three files.

Toolchain: debugging (Enforcer patterns, SnoopDOS, GDB remote, kprintf checklist), sasc (pragma encoding, __saveds idioms), stormc (NEW - StormC IDE, C++, PowerPC)

References: error_codes (DOS, Exec, trackdisk, Intuition error tables)
Driver development: rtg_driver (Native driver analysis, P96 tuning)

All 22 README indexes updated. Root README synced with stormc.md entry.
2026-04-23 21:37:26 -04:00

4.1 KiB
Raw Permalink Blame History

← Home · Devices

gameport.device — Joystick and Mouse Ports

Overview

gameport.device provides access to the Amiga's two controller ports (mouse/joystick). The hardware reads controller state through custom chip registers JOY0DAT/JOY1DAT and the CIA-A port for fire buttons. Understanding the hardware protocol is critical for FPGA cores.


Hardware Registers

Register Address Controller Function
JOY0DAT $DFF00A Port 1 (mouse) Quadrature-encoded position data
JOY1DAT $DFF00C Port 2 (joystick) Direction bits or quadrature data
JOYTEST $DFF036 Both Write to set counter test value
POTGO $DFF034 Both Proportional/paddle port control
POTGOR $DFF016 Both Read paddle/proportional values
CIA-A PRA $BFE001 Both Fire buttons (active low)

JOYxDAT Bit Layout

Bits 158: Y counter (or vertical quadrature)
Bits 70:  X counter (or horizontal quadrature)

Mouse Quadrature Decoding

For mouse input, the X/Y values are quadrature counters — they increment/decrement as the mouse moves:

/* Read mouse delta: */
UWORD joy = custom->joy0dat;  /* current counter */
WORD dx = (WORD)(joy & 0xFF) - (WORD)(prev_joy & 0xFF);
WORD dy = (WORD)(joy >> 8) - (WORD)(prev_joy >> 8);
/* dx/dy = movement since last read (signed, wraps at 255→0) */
prev_joy = joy;

Joystick Digital Decoding

For digital joysticks, the direction bits are encoded:

UWORD joy = custom->joy1dat;
BOOL right = joy & 0x0002;
BOOL left  = (joy >> 1) ^ (joy & 0x0001);  /* XOR of bit 1 and bit 0 */
BOOL down  = joy & 0x0200;
BOOL up    = (joy >> 9) ^ ((joy >> 8) & 0x0001);

/* Fire button — from CIA-A: */
BOOL fire  = !(ciaa->ciapra & 0x80);  /* port 2 button, active low */
/* Port 1 fire = bit 6 of CIAA PRA */

Important

The joystick directional decoding uses XOR between adjacent bits — not direct reads. This is because the hardware shares the same quadrature interface used for mice. This is a common source of bugs in FPGA implementations.

Fire Buttons

Button Register Bit Port
Port 1 fire (left mouse) CIA-A PRA $BFE001 6 Mouse port
Port 2 fire (joystick) CIA-A PRA $BFE001 7 Joystick port
Port 1 middle/right POTGOR $DFF016 8, 10 Mouse port
Port 2 second button POTGOR $DFF016 12, 14 Joystick port

Using gameport.device (OS Level)

struct MsgPort *gpPort = CreateMsgPort();
struct IOStdReq *gpReq = (struct IOStdReq *)
    CreateIORequest(gpPort, sizeof(struct IOStdReq));

/* Open port 1 (joystick port): */
OpenDevice("gameport.device", 1, (struct IORequest *)gpReq, 0);

/* Set controller type: */
UBYTE type = GPCT_ABSJOYSTICK;
gpReq->io_Command = GPD_SETCTYPE;
gpReq->io_Data    = (APTR)&type;
gpReq->io_Length  = 1;
DoIO((struct IORequest *)gpReq);

/* Set trigger conditions: */
struct GamePortTrigger trigger;
trigger.gpt_Keys   = GPTF_UPKEYS | GPTF_DOWNKEYS;
trigger.gpt_Timeout = 0;   /* no timeout */
trigger.gpt_XDelta  = 1;   /* report on any movement */
trigger.gpt_YDelta  = 1;
gpReq->io_Command = GPD_SETTRIGGER;
gpReq->io_Data    = (APTR)&trigger;
gpReq->io_Length  = sizeof(trigger);
DoIO((struct IORequest *)gpReq);

/* Read events: */
struct InputEvent ie;
gpReq->io_Command = GPD_READEVENT;
gpReq->io_Data    = (APTR)&ie;
gpReq->io_Length  = sizeof(ie);
SendIO((struct IORequest *)gpReq);

/* Wait for joystick event: */
Wait(1L << gpPort->mp_SigBit);
WaitIO((struct IORequest *)gpReq);
/* ie now contains joystick movement/button data */

Controller Types

Constant Value Device
GPCT_MOUSE 1 Standard Amiga mouse
GPCT_RELJOYSTICK 2 Relative joystick (proportional)
GPCT_ABSJOYSTICK 3 Absolute/digital joystick

References

  • NDK39: devices/gameport.h, hardware/custom.h, hardware/cia.h
  • HRM: Amiga Hardware Reference Manual — Controller Ports chapter
  • See also: input.md — input handler chain that receives gameport events
  • See also: keyboard.md — keyboard shares CIA-A interrupt infrastructure