Spooky Pinball pinHeck

pinmame.pinheck

controllers/pinmame/pinheck.json
4
Machines
0
Author ready
3
Address groups

Polarity is already normalised

PinMAME reports logical active state on this platform. A consumer must not invert again. Whether a real switch is normally closed stays recorded per device as a physical fact, so a recreation can build the right hardware without changing what the emulator reports.

Address groups

Cabinet inputs, 8x8 playfield matrix, and PinMAME flipper column

pinmame.input.switch

Switch
Legal addresses
  • 1 … 88 slots
  • 11 … 188 slots
  • 21 … 288 slots
  • 31 … 388 slots
  • 41 … 488 slots
  • 51 … 588 slots
  • 61 … 688 slots
  • 71 … 788 slots
  • 81 … 888 slots
  • 91 … 988 slots
  • 101 … 1088 slots
  • 111 … 1188 slots
Transports
  • libpinmamechannel=switch
Technical details for Cabinet inputs, 8x8 playfield matrix, and PinMAME flipper columnSource-derived address behavior and exceptions

MACHINE_DRIVER_START(PINHECK) in src/wpc/pinheck.c installs MDRV_SWITCH_CONV(pinheck_sw2m, pinheck_m2sw): public address n is internal column n / 10 and row n % 10 - 1, so pinheck_m2sw(col, row) = col * 10 + row + 1 and only rows 1-8 of each decade exist. Any other number maps to an unread column.

Public Internal column What it is
1-8 0 Cabinet inputs U12 D0-D7 (factory cabinet switches 1-8)
11-88 1-8 The 8x8 playfield matrix: factory switch n (0-63) is public (n / 8 + 1) * 10 + n % 8 + 1
91-98 9 Cabinet inputs U11 D0-D7 (factory cabinet switches 9-15 at 91-97)
101-108 10 Unused core allocation (CORE_STDSWCOLS = 12)
111-118 11 PinMAME's flipper column (CORE_FLIPPERSWCOL)

Matrix 11-88. pinheck_brd_swcol(col) hands the board emulation (src/wpc/pinheck/board.c) swMatrix[col + 1] for strobe column 0-7, and pinheck_board_read pulls a return line low for every set bit, which is how the PIC32 sees a closed contact. Public 1 is therefore the closed (active) contact and no invSw mask exists: consume the level as delivered. The factory charts print the same 0-63 numbering, and the ROM's own Switch Edge test draws each closure at the chart's column and row.

Cabinet 1-8 and 91-98. pinheck_brd_cab packs swMatrix[0] (bits 0-7) and swMatrix[9] (bits 8-15) into the cabinet word the board shifts in through its 74HC165 pair, read active-low like the matrix. pinheck.c documents the mapping as firmware cabinet switch n = public n for 1-8 and n + 82 for 9-15. SWITCH_UPDATE(pinheck) names the bits: 1 coin door closed (swMatrix[0] bit 0, set at every board reset because the door rests closed), 2 the operator User button, 3 and 4 the flipper buttons, 5 Back, 6 Enter, 7 coin, 8 tilt, and 94 (swMatrix[9] bit 3) Start. With keyboard handling off (the LibPinMAME default) core_updateSw passes SWITCH_UPDATE a null port array and it returns at once, so a host writes 1, 2, 5-8 and 91-98 directly. Which of 91-98 a game fits (optos, extra buttons) is per game.

Flipper buttons 3, 4 and 111-118. Every pinHeck driver declares FLIP_SWNO(PINHECK_SWLFLIP, PINHECK_SWRFLIP) = FLIP_SWNO(4, 3) with no FLIP_SOL. core_updateSw reads the host's lower button bits from the flipper column, CORE_SWLRFLIPBUTBIT at 112 (right) and CORE_SWLLFLIPBUTBIT at 114 (left), and copies them into cabinet switches 3 and 4 on every vblank, so drive 112/114, not 3/4: a host write to 3 or 4 is overwritten on the next vblank. The vblank calls core_updateSw(0), so no synthetic flipper solenoid is fabricated, and without FLIP_EOS no end-of-stroke bit is synthesized: 111, 113 and 115-118 hold whatever a host writes and nothing reads them. The flippers are ordinary board coils fired by the ROM, and their end-of-stroke contacts, where fitted, are matrix switches.

Coils, GI/flasher strings, RGB LEDs and servos

pinmame.output.solenoid

Solenoid
Legal addresses
  • 1 … 6464 slots
Transports
  • libpinmamechannel=solenoid
Technical details for Coils, GI/flasher strings, RGB LEDs and servosSource-derived address behavior and exceptions

All addresses come from src/wpc/pinheck.c (PINHECK_SOL_*, pinheck_brd_*, pinheck_getsol) and the generic getters in src/wpc/core.c (core_getSol, core_getAllPhysicSols). pinheck_brd_init sets CORE_MODOUT_FORCE_ON, so LibPinMAME reports these as 0-255 physical levels.

Public Source Output type
1-24 The 24 MOSFET coil drivers: factory coil n (0-23) is public n + 1 (pinheck_brd_sols) two-state
25-32 GI/flasher outputs GI 0-7, the first 74HC595 byte (pinheck_brd_gi, PINHECK_SOL_GI0) LED (PWM level)
33-36 Dead: core_getAllPhysicSols fills them from upper-flipper bits that no pinHeck driver sets always 0
37-44 GI 8-15, the second 74HC595 byte (PINHECK_SOL_GI8, read through the 37-44 branch GEN_PINHECK shares with System 11 and SAM) LED (PWM level)
45-48 Dead: lower-flipper bits, never set because the vblank calls core_updateSw(0) always 0
49 PinMAME's simulator-only shooter output; the ROM never drives it simulator
50 Reserved always 0
51-56 On-board WS2801 RGB LEDs 0 and 1, channels R, G, B (PINHECK_SOL_RGB) 0-255 level
57-61 Servos 0-4: the pulse width scaled between the game's servoMin and servoMax to 0-255 in integer clock ticks, rounded half up (pinheck_brd_servo; revisions before 97aa922b scaled in floating point); a servo without pulses keeps its last level 0-255 position
62-64 External WS2801 LED 0 R, G, B, or on-board LED 2 when the game sets onbLed2 (America's Most Haunted) 0-255 level

The coil outputs are gated by the board's watchdog (board.c: a PG15 low edge keeps wd_on for 9/8 s), so every coil drops when the PIC32 stops kicking it. The ROM fires the flippers through ordinary coil drivers; PinMAME publishes no Fliptronic flipper states for this platform. hw.custSol = PINHECK_CUSTSOLS = 14 gives coreGlobals.nSolenoids = 64. A WS2801 LED beyond those listed has no public output; the driver logs that once. Which GI output feeds general illumination and which a flasher is wired per game.

8x8 lamp matrix and Start-button lamp

pinmame.output.lamp

Lamp
Legal addresses
  • 11 … 188 slots
  • 21 … 288 slots
  • 31 … 388 slots
  • 41 … 488 slots
  • 51 … 588 slots
  • 61 … 688 slots
  • 71 … 788 slots
  • 81 … 888 slots
  • 91 … 988 slots
Transports
  • libpinmamechannel=lamp
Technical details for 8x8 lamp matrix and Start-button lampSource-derived address behavior and exceptions

MDRV_LAMP_CONV(pinheck_lamp2m, pinheck_m2sw) numbers lamps like switches: factory lamp n (0-63) of the 8x8 column/row matrix is public (n / 8 + 1) * 10 + n % 8 + 1, so the matrix is 11-88. The Start-button lamp is a separate board output (PA3, pinheck_brd_start) published as internal lamp 64, public 91. coreGlobals.nLamps = 72, so 92-98 also exist and are never lit. Matrix lamps are PWM-integrated (core_set_pwm_output_led_vfd; a lamp is lit at most 2 of every 24 strobe periods); the Start lamp is an LED output. There is no separate general-illumination channel (coreGlobals.nGI = 0): the GI strings are solenoid outputs 25-32 and 37-44.

Evidence

  • Reference

    https://github.com/vpinball/pinmame

    Source locations

    src/wpc/pinheck.c (file header; PINHECK_SOL_GI0/GI8/RGB/SRV/EXT, PINHECK_LAMP_ST, PINHECK_NSOLS, PINHECK_NLAMPS; pinheck_brd_swcol, pinheck_brd_cab, pinheck_brd_lamps, pinheck_brd_sols, pinheck_brd_gi, pinheck_brd_start, pinheck_brd_rgb, pinheck_brd_servo, pinheck_2m/pinheck_sw2m/pinheck_lamp2m/pinheck_m2sw, pinheck_getsol, pinheck_brd_init, pinheck_brd_reset, pinheck_brd_vblank, SWITCH_UPDATE(pinheck), pinheck_vblank, MACHINE_DRIVER_START(PINHECK)/(PINHECKDMD)); src/wpc/pinheck.h (PINHECK_SWLFLIP/SWRFLIP, PINHECK_CUSTSOLS, PINHECK_COMPORTS, PINHECK_GAMEDEF, pinheck_tGameData); src/wpc/pinheck/board.c and board.h (coil port/bit tables, watchdog, lamp strobe, 74HC595 GI and 74HC165 cabinet shift registers, WS2801 chains, servo pulse timing, switch read); src/wpc/pinheckgames.c and src/wpc/sims/pinheck/{amh,dominos,jetsons,rzspook}.c (per-game core_tGameData); src/wpc/core.c (core_updateSw, core_getSol, core_getAllSol, core_getAllPhysicSols GEN_PINHECK branches); src/wpc/core.h (CORE_FLIPPERSWCOL, CORE_SWLRFLIPBUTBIT/CORE_SWLLFLIPBUTBIT, CORE_STDSWCOLS, CORE_FIRSTCUSTSOL); src/wpc/gen.h (GEN_PINHECK); src/libpinmame/libpinmame.h (PINMAME_HARDWARE_GEN_PINHECK = 0x10000000000000)

    rev
    97aa922bf8e4

Something wrong or missing?

Address ranges, transports and normalisation rules live in one profile file. If PinMAME exposes a group this profile does not describe — or describes wrongly — the fix belongs there.

Cite a source for anything you change — a manual page, a line in a working VPX script, PinMAME source, or a reading from the machine's own service menu. Claims without provenance cannot be validated.

Machines on this platform

All 4 machines