mame icon indicating copy to clipboard operation
mame copied to clipboard

Drafting serial port implementation for TMP94C241 that is used for control panel and MIDI on Technics KN5000.

Open felipesanches opened this issue 1 month ago • 15 comments

This PR is being opened as a draft for anyone who feels like offering help with an early code-review and suggestions of what else could we try doing to make this work.

The serial communications protocol used by the KN5000 maincpu (TLCS900) and the undumped MCUs of the control panel is currently unknown, so this PR contains boilerplate code for the HLE implementation to aid in further research to find out what the protocol looks like.

felipesanches avatar Oct 26 '25 18:10 felipesanches

cpanel_serial_port_kn5000

If I understood it correctly, both CPDATA ("Control Panel Data") and CPSCK ("Control Panel Serial Clock") are bidirectional.

In this diagram green is RXD1, red is TXD1 and in blue are the clock signals.

I am a bit confused about how the clock signal is handled here. The diagram seems to indicate that maincpu can emit a clock signal via SCLK1 pin, while the control panel can also send a serial clock signal via the INTA pin. Does it mean there must be some protocol in place to avoid both the CPU and the MCU transmitting serial data simultaneously?

felipesanches avatar Nov 22 '25 22:11 felipesanches

I have a hunch that the serial receive part of control panel communication is handled by some interrupt routine (called when INTA pin is asserted) that reads the state of the RXD pin instead of relying on the rx_shift_register (and INTRX interrupt signal) that must also be available in the main cpu serial channel subsystem (according to the datasheet).

It is still unclear to me how that would be implemented in MAME. Does anybody here have suggestions to help me with this?

felipesanches avatar Nov 22 '25 22:11 felipesanches

On the other hand, the part highlighted in blue in the diagram does show the clock signal from the cpanel MCU also going to SCLK1, so maybe it actually uses the RX shift register, after all...

felipesanches avatar Nov 22 '25 22:11 felipesanches

That usage of the INTA pin is just a bit puzzling to me... Not sure what's going on there.

felipesanches avatar Nov 22 '25 22:11 felipesanches

Is it that the CPU either use its synchronous serial hardware or handle each clock edge via an interrupt? The control-panel MCU is the sole source of the clock (CPSCK), which passes through a small filter, and the cleaned signal is then fed to both SCLK1 and INTA on the TLCS-900. CPDATA looks like a shared open-collector data line (wired-AND) - maybe both sides can only pull it low (assuming the MCU also uses a similar open-collector), and the pull-up provides the high level. The CPU drives low through a transistor stage and samples the line on RXD1. So in effect, a half-duplex, panel-clocked synchronous serial link using a single shared data wire?

To answer your point though, i think it's done that way so the TLCS-900 can use either the hardware RX shift register or handle each bit edge in an interrupt. INTA gives the firmware the option to bit-bang or detect framing/attention events instead of relying solely on the serial hardware - not sure what that would be needed though.

MagikalUnicorn avatar Nov 23 '25 17:11 MagikalUnicorn

What is the part number of IC2? Also, any idea what the CPSCK frequency might be, when it is operating?

The time constant (R3 x C2) is large enough that the clock will be filtered to some extend. But the exact effect on INTA depends on the details above. Note that SCLK1 is connected to the unfiltered clock.

[...] communication is handled by some interrupt routine (called when INTA pin is asserted) that reads the state of the RXD pin [...]

Is it that the CPU either use its synchronous serial hardware or handle each clock edge via an interrupt?

This is also what I thought at first. But then I noticed the filter's large time constant. So this is only possible if CPSCK's frequency is less than a few KHz. The exact value of "a few" depends on IC2's specs.

If CPSCK's frequency is large enough, then INTA will transition from LOW to HIGH if CPSCK remains low for too long. This could be a way for the MCU to trigger INTA, by holding CPSCK low for a bit. But this is just one guess.

m1macrophage avatar Nov 23 '25 22:11 m1macrophage

A thought while the part number and frequency are confirmed - perhaps INTA isn’t a separate “slow” or pulse-width detector i.e. it just sees the same schmitt-cleaned CPSCK edge that SCLK1 receives, so it only triggers on actual rising/falling edges of the clock, not on how long the line is held?

MagikalUnicorn avatar Nov 23 '25 22:11 MagikalUnicorn

If R3 and C2 did not exist, then INTA would indeed just be a Schmitt-cleaned SCLK1.

But given the values of R3 and C2, and if I am interpreting this right, INTA's behavior will depend on CPSCK's frequency.

If the frequency is low enough, INTA will just see an inverted (and a bit delayed) version of SCLK1. Similar to what would happen if R3 and C2 did not exist, but with some delay.

If the frequency is high enough, INTA will be LOW under normal operation (resting or transmission), and will go HIGH if CPSCK goes LOW for too long. This assumes that the resting state for CPSCK is HIGH (given R2), that CPSCK has a ~50% duty cycle under normal operation, and that IC2A is a Schmitt trigger inverter.

EDIT:

perhaps INTA isn’t a separate “slow” or pulse-width detector i.e. it just sees the same schmitt-cleaned CPSCK edge that SCLK1 receives

In summary, I think both (slow detector vs. schmitt-cleaned CPSCK) are a possibility. It depends on CPSCK's frequency.

m1macrophage avatar Nov 23 '25 23:11 m1macrophage

Hmm, this is probably at the limits of my expertise, but my understanding is that R3/C2 only slow the CPSCK edge going into the schmitt input - they don’t create a separate timing path. IC2A will still regenerate a clean digital edge whenever that slowed waveform crosses its thresholds. Since both SCLK1 and INTA come from the same schmitt-cleaned output, they’ll always toggle together.

So isn’t it the case that there’s no frequency range where SCLK1 stays usable but INTA somehow becomes a pulse-width detector?

MagikalUnicorn avatar Nov 24 '25 00:11 MagikalUnicorn

What is the part number of IC2?

TC7W14F: https://www.alldatasheet.com/datasheet-pdf/view/32067/TOSHIBA/TC7W14F.html

Also, any idea what the CPSCK frequency might be, when it is operating?

I'm not entirely sure, but these routines seem to set it up for either 250kHz or 62.5kHz Screenshot From 2025-11-23 21-41-09

felipesanches avatar Nov 24 '25 00:11 felipesanches

I'm not entirely sure, but these routines seem to set it up for either 250kHz or 62.5kHz

If CPSCK were generated by the TLCS-900, R3/C2 would make no sense (no need to low pass your own clock). As a rough guide though: R3/C2 = 100 µs time constant Schmitt threshold crossing about 120-150 µs Maximum reliable clock frequency about 3-5 kHz

MagikalUnicorn avatar Nov 24 '25 01:11 MagikalUnicorn

my understanding is that R3/C2 only slow the CPSCK edge going into the schmitt input

Correct. R3/C2 is just a low-pass filter. It will indeed cause the Schmitt input to "see" a slowed down CPSCK. But when the frequency of CPSCK is very high, that slowdown will result in the schmitt input seeing the average voltage of the clock (~2.5), and it won't trip.

A picture is worth a thousand words, so here is a Falstad simulation :).

For some reason it isn't initialized properly, so make sure to click "reset" after loading the page.

The circuit to the left uses a slow clock, while the one to the right uses a fast one. Moving the mouse over the graphs at the bottom will also highlight the part of the circuit being graphed.

Notice how the SCHMITT INPUT signal looks different for the two circuits, which also results in INTA acting differently.

Since both SCLK1 and INTA come from the same schmitt-cleaned output

Note that SCLK1 is the same as CPSCK, but not the same as INTA. SCLK1/CPSCK is the clock signal before it is processed by the low-pass filter (R3/C2) and schmitt trigger.

m1macrophage avatar Nov 24 '25 01:11 m1macrophage

TC7W14F

Cool, that verifies this is indeed a Schmitt trigger inverter, which verifies one of the assumption we were making earlier.

I'm not entirely sure, but these routines seem to set it up for either 250kHz or 62.5kHz

I guess CPSCK might be bi-directional after all?

Though INTA is probably only relevant when the panel MCU is driving CPSCK. And I take it that clock rate is not known.

But if we assume it is >= 62.5KHz, then INTA won't be a cleaned up CPSCK, and it might be acting as a "clock is low for too long" detector.

However, and as validated by MagikalUnicorn's calculations, if the incoming clock is slow (a few KHz), then INTA will just be an inverted and delayed CPSCK.

m1macrophage avatar Nov 24 '25 01:11 m1macrophage

Note that SCLK1 is the same as CPSCK, but not the same as INTA. SCLK1/CPSCK is the clock signal before it is processed by the low-pass filter (R3/C2) and schmitt trigger.

You are indeed right, and I have misread the diagram.

Thank you for the simulation, and the explanation.

MagikalUnicorn avatar Nov 24 '25 01:11 MagikalUnicorn

This is just a very small step towards understanding the control panel protocol.

Adding this line to the memory map (which is a just a hack to fool the boot code to think that the cpanel MCUs are working properly), one gets this "initial settings" splash screen and then the main system UI is loaded:

map(0x008d7c, 0x008d7c).lr8(NAME([this] (offs_t o) { return 0x09; })); // Fool the self-test at address FB7824 of Program ROM v10 ;-) We still need proper HLE of the control panel MCUs.
image Screenshot From 2025-11-24 09-33-20

felipesanches avatar Nov 24 '25 12:11 felipesanches

This weekend I've made a little bit more progress on this, but it is certainly still very broken. I may still be doing a few silly things in the code, so please be kind if you're looking at it.

felipesanches avatar Dec 01 '25 03:12 felipesanches