Timer 4/5 and the Sequencer Clock

The KN5000 firmware paces its sequencer, metronome and demo-song cycling from the TMP94C241’s Timer 4/5 pair. This page states how the firmware programs it, what the chip does on a compare match, and which parts of that the MAME core models.

How the Firmware Programs It

Timer 4 (16-bit up counter UC4)
  ├── TREG4 (low compare register)  → INTTR4 on match
  └── TREG5 (high compare register) → INTTR5 on match + counter reset

T4FFCR (flip-flop control register)
  ├── Bit 2: invert the flip-flop on a TREG4 match
  └── Bit 3: invert the flip-flop on a TREG5 match

Boot (v10/maincpu/shared/boot_hw_init.s:76-82) starts only timer 4 (T16RUN bit 0) with T4MOD = 0x05, TREG4 = 1 and TREG5 = 0x3D09, and sets up the interrupts:

Interrupt Priority Handler
INTTR5 3 (enabled) 0xEF086A
INTTR4 0 (disabled) 0xEF0E21

TREG5 is therefore the interval register, and INTTR5 is the sequencer clock. Its handler drives the tick counters at DRAM 1047, 1051 and 1052, which pace the accompaniment engine, the metronome and demo song cycling. If INTTR5 does not fire, demo songs never advance.

What a Compare Match Does

Three things are independent, and the emulation keeps them independent:

On match Condition
Raise the interrupt flag — 0x80 (INTTR5) for TREG_HIGH, 0x08 (INTTR4) for TREG_LOW always
Reset the up counter (TREG_HIGH only) always, given T4MOD bit 2 (CLE) set
Invert the timer flip-flop only if the matching T4FFCR bit is set

The T4FFCR bits gate only the flip-flop. They must not gate the interrupt or the counter reset — that is what the 8-bit timers in the same file have always done, and the 16-bit path matches them. TREG_HIGH must raise the upper flag (0x80), not the lower one.

Two Documented Gaps in the 16-Bit Path

timer_16bits in src/devices/cpu/tlcs900/tmp94c241.cpp deliberately leaves two datasheet behaviours unmodelled. The sibling tmp95c061.cpp implements both in its run16() lambda; port that if a driver ever needs them.

  1. CLE is assumed set. T4MOD/T5MOD bit 2 chooses whether a TREG_HIGH match clears the up counter; CLE = 0 means a free-running counter. The code always clears.
  2. The two comparators are chained, not independent. The else if means that when TREG_LOW and TREG_HIGH hold the same value the lower interrupt can never be raised.

Neither is observable on any Technics machine: the KN5000 sets T4MOD bit 2, so (1) is moot, and TREG4 = 1 against TREG5 = 0x3D09 are different, so (2) is moot. The Toshiba TMP95C061 databook passages are Figure 3.9 (3) p.95 and section 3.9 (5) p.103; the quotes are re-checkable with notes/wsa1-probes/tlcs900_datasheet_quotes.py in the MAME tree.

Source Locations

File Location Role
tmp94c241.cpp timer_16bits lambda 16-bit timer match handling for T4/T6/T8/TA
tmp94c241.h INTET45 = 6 Interrupt register index mapping
ROM vector 0xFFFF64 0x00EF086A INTTR5 handler
system_handlers.s:626 INTTR4 handler Disabled at boot (priority 0)
system_handlers.s:387 INTT1 handler Internal clock, for comparison
sequencer_engine.s:18893 AccPlayMode state 3 Waits on tick counter 1052
accompaniment_engine.s:8040 AccPlayMode_Dispatch Promotion chain endpoint

Sequencer DRAM Counters

Address Name Purpose
1047 Metro sub-tick Metronome timing (driven by INTTR5)
1050 Internal clock Internal clock counter (driven by INTT1)
1051 Alt seq sub-tick Alternate sequencer sub-tick
1052 Alt seq tick Alternate sequencer tick counter
1054 Enable flags Bit 2: sequencer enabled
1056 Alt clock state Promotion chain variable
1057 Alt seq state Promotion chain variable
8956 AccPlayMode state State machine index

Timer 4 SFR Addresses

Address Register Purpose
0x90-0x91 TREG4 Timer 4 compare register (write-only)
0x92-0x93 TREG5 Timer 5 compare register (write-only)
0x98 T4MOD Timer 4 mode
0x99 T4FFCR Timer 4 flip-flop control
0x9E T16RUN 16-bit timer run control
0xE6 INTET45 Interrupt priority/flags for INTTR4/INTTR5