001package jmri.jmrix.tmcc.serialmon;
002
003import jmri.jmrix.tmcc.SerialListener;
004import jmri.jmrix.tmcc.SerialMessage;
005import jmri.jmrix.tmcc.SerialReply;
006import jmri.jmrix.tmcc.TmccSystemConnectionMemo;
007
008/**
009 * Frame displaying (and logging) TMCC serial command messages.
010 *
011 * @author Bob Jacobsen Copyright (C) 2001, 2006
012 * with edits/additions by
013 * @author Timothy Jump Copyright (C) 2025
014 */
015public class SerialMonFrame extends jmri.jmrix.AbstractMonFrame implements SerialListener {
016
017    private TmccSystemConnectionMemo _memo = null;
018
019    public SerialMonFrame(TmccSystemConnectionMemo memo) {
020        super();
021        _memo = memo;
022    }
023
024    @Override
025    protected String title() {
026        return Bundle.getMessage("MonitorXTitle", "TMCC");
027    }
028
029    @Override
030    protected void init() {
031        // connect to TrafficController
032        _memo.getTrafficController().addSerialListener(this);
033    }
034
035    @Override
036    public void dispose() {
037        _memo.getTrafficController().removeSerialListener(this);
038        super.dispose();
039    }
040
041    @Override
042    public synchronized void message(SerialMessage l) { // receive a message and log it
043        // check for valid length
044        if (l.getNumDataElements() < 3) {
045            nextLine("Truncated message of length " + l.getNumDataElements() + "\n",
046                    l.toString());
047        } else {
048            nextLine("Cmd: " + parse(l.getOpCode(), l.getAsWord()) + "\n", l.toString());
049        }
050    }
051
052    @Override
053    public synchronized void reply(SerialReply l) { // receive a reply message and log it
054        // check for valid length
055        if (l.getNumDataElements() < 2) {
056            nextLine("Truncated reply of length " + l.getNumDataElements() + ": \"" + l.toString() + "\"\n",
057                    l.toString());
058        } else {
059            nextLine("Rep: " + parse(l.getOpCode(), l.getAsWord()) + "\n", l.toString());
060        }
061    }
062
063    String parse(int opCode, int val) {
064        // TMCC 2 parsing
065        if (opCode == 0xF8) {
066            // TMCC2 Engine Commands
067            int A = (val / 512) & 0x7F; // A is TMCC Adddress Code
068            int C = (val / 32) & 0x03; // C is TMCC Command Code
069            int D = val & 0x3F; // D is TMCC Data Code
070            if (A < 99) {
071                if ((val & 0x0100) == 0x0100) {
072                    switch (C) {
073                        case 0: // If C (TMCC Command Code) == 0                    
074                            switch (D) {
075                                case 0:
076                                    return "TMCC2 - Engine " + A + " - Forward Direction";
077                                case 1:
078                                    return "TMCC2 - Engine " + A + " - Toggle Direction";
079                                case 2:
080                                    
081                                case 3:
082                                    return "TMCC2 - Engine " + A + " - Reverse Direction";
083                                case 4:
084                                    return "TMCC2 - Engine " + A + " - Boost";
085                                case 5:
086                                    return "TMCC2 - Engine " + A + " - Open Front Coupler";
087                                case 6:
088                                    return "TMCC2 - Engine " + A + " - Open Rear Coupler";
089                                case 7:
090                                    return "TMCC2 - Engine " + A + " - Brake";
091                                case 8:
092                                    return "TMCC2 - Engine " + A + " - AUX1 Off";
093                                case 9:
094                                    return "TMCC2 - Engine " + A + " - AUX1 Option 1 (CAB AUX1 Button; On While Pressed/On Until Next Button Pressed)";
095                                case 10:
096                                    return "TMCC2 - Engine " + A + " - AUX1 Option 2 (Toggle On/Toggle Off)";
097                                case 11:
098                                    return "TMCC2 - Engine " + A + " - AUX1 On";
099                                case 12:
100                                    return "TMCC2 - Engine " + A + " - AUX2 Off";
101                                case 13:
102                                    return "TMCC2 - Engine " + A + " - Headlight Toggle On/Off (AUX2 Option 1/AUX2 Button)";
103                                case 14:
104                                    return "TMCC2 - Engine " + A + " - AUX2 Option 2 (On While Pressed)";
105                                case 15:
106                                    return "TMCC2 - Engine " + A + " - AUX2 On";
107                                case 16:
108                                    return "TMCC2 - Engine " + A + " - Num 0 - Engine Reset - TMCC2 Loco Feature Type 0";
109                                case 17:
110                                    return "TMCC2 - Engine " + A + " - Num 1 - Sound Volume Increase - TMCC2 Loco Feature Type 1";
111                                case 18:
112                                    return "TMCC2 - Engine " + A + " - Num 2 - Crew Talk - TMCC2 Loco Feature Type 2";
113                                case 19:
114                                    return "TMCC2 - Engine " + A + " - Num 3 - Sound On w/Start-Up Sequence/RPM Increase";
115                                case 20:
116                                    return "TMCC2 - Engine " + A + " - Num 4 - Sound Volume Decrease";
117                                case 21:
118                                    return "TMCC2 - Engine " + A + " - Num 5 - Sound Off w/Shut-Down Sequence";
119                                case 22:
120                                    return "TMCC2 - Engine " + A + " - Num 6 - Steam Release/RPM Decrease";
121                                case 23:
122                                    return "TMCC2 - Engine " + A + " - Num 7 - Tower Com Announcement";
123                                case 24:
124                                    return "TMCC2 - Engine " + A + " - Num 8 - Feature Off (Smoke/Aux Lighting)";
125                                case 25:
126                                    return "TMCC2 - Engine " + A + " - Num 9 - Feature On (Smoke/Aux Lighting)";
127                                case 26:
128                                    
129                                case 27:
130                                    
131                                case 28:
132                                    return "TMCC2 - Engine " + A + " - Blow Whistle/Horn 1";
133                                case 29:
134                                    return "TMCC2 - Engine " + A + " - Ring Bell";
135                                case 30:
136                                    return "TMCC2 - Engine " + A + " - Letoff Sound";
137                                case 31:
138                                    return "TMCC2 - Engine " + A + " - Blow Horn 2";
139                                default:
140                                    return "TMCC2 - Engine " + A + " - Unassigned FnKey TMCC2 (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
141                            }
142
143                        case 1: // If C (TMCC Command Code) == 1
144                            switch (D & 0x1F) {
145                                case 0:
146                                    return "TMCC2 - Engine " + A + " - Assign as Single Unit - Forward Direction";
147                                case 1:
148                                    return "TMCC2 - Engine " + A + " - Assign as Single Unit - Reverse Direction";
149                                case 2:
150                                    return "TMCC2 - Engine " + A + " - Assign as Head Unit  - Forward Direction";
151                                case 3:
152                                    return "TMCC2 - Engine " + A + " - Assign as Head Unit - Reverse Direction";
153                                case 4:
154                                    return "TMCC2 - Engine " + A + " - Assign as Middle Unit - Forward Direction";
155                                case 5:
156                                    return "TMCC2 - Engine " + A + " - Assign as Middle Unit - Reverse Direction";
157                                case 6:
158                                    return "TMCC2 - Engine " + A + " - Assign as Rear Unit - Forward Direction";
159                                case 7:
160                                    return "TMCC2 - Engine " + A + " - Assign as Rear Unit - Reverse Direction";
161                                case 8:
162                                    return "TMCC2 - Engine " + A + " - Momentum Low";
163                                case 9:
164                                    return "TMCC2 - Engine " + A + " - Momentum Medium";
165                                case 10:
166                                    return "TMCC2 - Engine " + A + " - Momentum High";
167                                case 11:
168                                    return "TMCC2 - Engine ID " + A + " - Set";
169                                case 12:
170                                    
171                                case 13:
172                                    
173                                case 14:
174                                    
175                                case 15:
176                                    
177                                case 16:
178                                    return "TMCC2 - Engine " + A + " - Clear Train (Consist) Assignment";
179                                case 17:
180                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 1";
181                                case 18:
182                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 2";
183                                case 19:
184                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 3";
185                                case 20:
186                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 4";
187                                case 21:
188                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 5";
189                                case 22:
190                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 6";
191                                case 23:
192                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 7";
193                                case 24:
194                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 8";
195                                case 25:
196                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 9";
197                                case 26:
198                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 10";
199                                case 27:
200                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 11";
201                                case 28:
202                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 12";
203                                case 29:
204                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 13";
205                                case 30:
206                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 14";
207                                case 31:
208                                    return "TMCC2 - Engine " + A + " - Assign to Train (Consist) 15";
209                                default:
210                                    return "TMCC2 - Engine " + A + " - Unassigned FnKey TMCC2 (Case C=1) - with A= " + A + " C= " + C + " D= " + D;
211                            }
212                    
213                        //$FALL-THROUGH$
214                        case 2: // If C (TMCC Command Code) == 2
215                            // return "TMCC2 - Engine " + A + " - Change Speed (Relative) by " + (D - 5);
216                        
217                        case 3: // If C (TMCC Command Code) == 3
218                        default:    // to let the compiler know there are only 3 cases
219                            return "TMCC2 (32 Speed Steps) - Engine " + A + " - Speed (Absolute) = " + (D-32);
220                    }
221                }
222            }
223
224            if (val == 0xFF8B) {
225                return "TMCC2 - HALT - Emergency System Stop; ALL";
226            } else {
227                return "TMCC2 (200 Speed Steps) - Engine " + A + " - Speed (Absolute) = " + (val & 0xFF);
228            }
229        }
230
231        if (opCode == 0xF9) {
232            // TMCC2 Train Commands
233            int A = (val / 512) & 0x7F; // A is TMCC Adddress Code
234            int C = (val / 32) & 0x03; // C is TMCC Command Code
235            int D = val & 0x1F; // D is TMCC Data Code
236            if (A < 99) {
237                if ((val & 0x0100) == 0x0100) {
238                    switch (C) {
239                        case 0: // If C (TMCC Command Code) == 0                    
240                            switch (D) {
241                                case 0:
242                                    return "TMCC2 - Train " + A + " - Forward Direction";
243                                case 1:
244                                    return "TMCC2 - Train " + A + " - Toggle Direction";
245                                case 2:
246                                    
247                                case 3:
248                                    return "TMCC2 - Train " + A + " - Reverse Direction";
249                                case 4:
250                                    return "TMCC2 - Train " + A + " - Boost";
251                                case 5:
252                                    return "TMCC2 - Train " + A + " - Open Front Coupler";
253                                case 6:
254                                    return "TMCC2 - Train " + A + " - Open Rear Coupler";
255                                case 7:
256                                    return "TMCC2 - Train " + A + " - Brake";
257                                case 8:
258                                    return "TMCC2 - Train " + A + " - AUX1 Off";
259                                case 9:
260                                    return "TMCC2 - Train " + A + " - AUX1 Option 1 (CAB AUX1 Button; On While Pressed/On Until Next Button Pressed)";
261                                case 10:
262                                    return "TMCC2 - Train " + A + " - AUX1 Option 2 (Toggle On/Toggle Off)";
263                                case 11:
264                                    return "TMCC2 - Train " + A + " - AUX1 On";
265                                case 12:
266                                    return "TMCC2 - Train " + A + " - AUX2 Off";
267                                case 13:
268                                    return "TMCC2 - Train " + A + " - Headlight Toggle On/Off (AUX2 Option 1/AUX2 Button)";
269                                case 14:
270                                    return "TMCC2 - Train " + A + " - AUX2 Option 2 (On While Pressed)";
271                                case 15:
272                                    return "TMCC2 - Train " + A + " - AUX2 On";
273                                case 16:
274                                    return "TMCC2 - Train " + A + " - Num 0 - Train Reset - TMCC2 Loco Feature Type 0";
275                                case 17:
276                                    return "TMCC2 - Train " + A + " - Num 1 - Sound Volume Increase - TMCC2 Loco Feature Type 1";
277                                case 18:
278                                    return "TMCC2 - Train " + A + " - Num 2 - Crew Talk - TMCC2 Loco Feature Type 2";
279                                case 19:
280                                    return "TMCC2 - Train " + A + " - Num 3 - Sound On w/Start-Up Sequence/RPM Increase";
281                                case 20:
282                                    return "TMCC2 - Train " + A + " - Num 4 - Sound Volume Decrease";
283                                case 21:
284                                    return "TMCC2 - Train " + A + " - Num 5 - Sound Off w/Shut-Down Sequence";
285                                case 22:
286                                    return "TMCC2 - Train " + A + " - Num 6 - Steam Release/RPM Decrease";
287                                case 23:
288                                    return "TMCC2 - Train " + A + " - Num 7 - Tower Com Announcement";
289                                case 24:
290                                    return "TMCC2 - Train " + A + " - Num 8 - Feature Off (Smoke/Aux Lighting)";
291                                case 25:
292                                    return "TMCC2 - Train " + A + " - Num 9 - Feature On (Smoke/Aux Lighting)";
293                                case 26:
294                                    
295                                case 27:
296                                    
297                                case 28:
298                                    return "TMCC2 - Train " + A + " - Blow Whistle/Horn 1";
299                                case 29:
300                                    return "TMCC2 - Train " + A + " - Ring Bell";
301                                case 30:
302                                    return "TMCC2 - Train " + A + " - Letoff Sound";
303                                case 31:
304                                    return "TMCC2 - Train " + A + " - Blow Horn 2";
305                                default:
306                                    return "TMCC2 - Train " + A + " - Unassigned FnKey TMCC2 (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
307                            }
308
309                        case 1: // If C (TMCC Command Code) == 1
310                            switch (D & 0x17) {
311                                case 0:
312                                    return "TMCC2 - Train " + A + " - Momentum Low";
313                                case 1:
314                                    return "TMCC2 - Train " + A + " - Momentum Medium";
315                                case 2:
316                                    return "TMCC2 - Train " + A + " - Momentum High";
317                                case 3:
318                                    return "TMCC2 - Train ID " + A + " - Set";
319                                default:
320                                    return "TMCC2 - Train " + A + " - Unassigned FnKey TMCC2 (Case C=1) - with A= " + A + " C= " + C + " D= " + D;
321                            }
322                    
323                        //$FALL-THROUGH$
324                        case 2: // If C (TMCC Command Code) == 2
325                            // return "TMCC2 - Train " + A + " - Change Speed (Relative) by " + (D - 5);
326                        
327                        case 3: // If C (TMCC Command Code) == 3
328                        default:    // to let the compiler know there are only 3 cases
329                            return "TMCC2 (32 Speed Steps) - Train " + A + " - Speed (Absolute) = " + D;
330                    }
331                }
332            }
333
334            if (val == 0xFF8B) {
335                return "TMCC2 - HALT - Emergency System Stop; ALL";
336            } else {
337                return "TMCC2 (200 Speed Steps) - Train " + A + " - Speed (Absolute) = " + (val & 0xFF);
338            }
339
340        }        
341        
342        // TMCC 1 parsing
343        if (opCode == 0xFE) {
344            if (val == 0xFFFF) {
345                return "TMCC1 - HALT - Emergency System Stop; ALL";
346
347            } else if ((val & 0xC000) == 0x4000) {
348                // TMCC1 Switch Commands
349                int A = (val / 128) & 0x7F; // A is TMCC Adddress Code
350                int C = (val / 32) & 0x03; // C is TMCC Command Code
351                int D = val & 0x1F; // D is TMCC Data Code
352                switch (C) {
353                    case 0: // If C (TMCC Command Code) == 0
354                        switch (D) {
355                            case 0:
356                                return "Throw Switch " + A + " - THROUGH/CLOSED";
357                            case 31:
358                                return "Throw Switch " + A + " - OUT/THROWN";
359                            default:
360                                return "Unrecognized Switch(SW) Command (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
361                        }
362
363                    case 1: // If C (TMCC Command Code) == 1
364                        switch (D) {
365                            case 11:
366                                return "Switch ID " + A + " - Set";
367                            default:
368                                return "Unrecognized Switch(SW) Command (Cases C=1) - with A= " + A + " C= " + C + " D= " + D;                                
369                        }
370
371                    //$FALL-THROUGH$
372                    case 2: // If C (TMCC Command Code) == 2
373                        return "Assign switch " + A + " to route " + D + " - THROUGH";
374
375                    case 3: // If C (TMCC Command Code) == 3
376                        return "Assign switch " + A + " to route " + D + " - OUT";
377                    default:
378                        return "Unrecognized Switch(SW) Command (Cases C= 2-3) - with A= " + A + " C= " + C + " D= " + D;
379                }
380
381
382            } else if ((val & 0xF000) == 0xD000) {
383                // TMCC1 Route Commands
384                int A = (val / 128) & 0x1F; // A is TMCC Adddress Code
385                int C = (val / 32) & 0x03; // C is TMCC Command Code
386                int D = val & 0x1F; // D is TMCC Data Code
387                switch (C) {
388                    case 0: // If C (TMCC Command Code) == 0
389                        switch (D) {
390                            case 15:
391                                return "Route " + A + " - THROW";
392                            default:
393                                return "Unrecognized Route(RTE) Command (Cases C=0) - with A= " + A + " C= " + C + " D= " + D;
394                        }
395
396                    case 1: // If C (TMCC Command Code) == 0
397                        switch (D) {
398                            case 12:
399                                return "Route " + A + " - CLEAR";
400                            default:
401                                return "Unrecognized Route(RTE) Command (Cases C=1) - with A= " + A + " C= " + C + " D= " + D;
402
403                        }
404
405                default:
406                    return "Unrecognized Route(RTE) Command (Cases C) - with A= " + A + " C= " + C + " D= " + D;
407                }
408
409            } else if ((val & 0xC000) == 0x0000) {
410                // TMCC1 Engine Commands
411                int A = (val / 128) & 0x7F; // A is TMCC Adddress Code
412                int C = (val / 32) & 0x03; // C is TMCC Command Code
413                int D = val & 0x3F; // D is TMCC Data Code
414                switch (C) {
415                    case 0: // If C (TMCC Command Code) == 0
416                        switch (D) {
417                            case 0:
418                                return "TMCC1 - Engine " + A + " - Forward Direction";
419                            case 1:
420                                return "TMCC1 - Engine " + A + " - Toggle Direction";
421                            case 2:
422                            
423                            case 3:
424                                return "TMCC1 - Engine " + A + " - Reverse Direction";
425                            case 4:
426                                return "TMCC1 - Engine " + A + " - Boost";
427                            case 5:
428                                return "TMCC1 - Engine " + A + " - Open Front Coupler";
429                            case 6:
430                                return "TMCC1 - Engine " + A + " - Open Rear Coupler";
431                            case 7:
432                                return "TMCC1 - Engine " + A + " - Brake";
433                            case 8:
434                            
435                            case 9:
436                                return "TMCC1 - Engine " + A + " - AUX1 Option 1 (CAB AUX1 Button; On While Pressed/On Until Next Button Pressed)";
437                            case 10:
438                            
439                            case 11:
440                            
441                            case 12:
442                            
443                            case 13:
444                                return "TMCC1 - Engine " + A + " - Headlight Toggle On/Off (AUX2 Option 1/AUX2 Button)";
445                            case 14:
446                            
447                            case 15:
448                            
449                            case 16:
450                                return "TMCC1 - Engine " + A + " - Num 0 - Engine Reset";
451                            case 17:
452                                return "TMCC1 - Engine " + A + " - Num 1 - Sound Volume Increase";
453                            case 18:
454                                return "TMCC1 - Engine " + A + " - Num 2 - Crew Talk";
455                            case 19:
456                                return "TMCC1 - Engine " + A + " - Num 3 - Sound On w/Start-Up Sequence";
457                            case 20:
458                                return "TMCC1 - Engine " + A + " - Num 4 - Sound Volume Decrease - TMCC1 Loco Feature Type 4";
459                            case 21:
460                                return "TMCC1 - Engine " + A + " - Num 5 - Sound Off w/Shut-Down Sequence - TMCC1 Loco Feature Type 5";
461                            case 22:
462                                return "TMCC1 - Engine " + A + " - Num 6 - Steam Release/RPM Decrease - TMCC1 Loco Feature Type 6";
463                            case 23:
464                                return "TMCC1 - Engine " + A + " - Num 7 - Tower Com Announcement";
465                            case 24:
466                                return "TMCC1 - Engine " + A + " - Num 8 - Feature Off (Smoke/Aux Lighting) - TMCC1 Loco eature Type 8";
467                            case 25:
468                                return "TMCC1 - Engine " + A + " - Num 9 - Feature On (Smoke/Aux Lighting)";
469                            case 26:
470                            
471                            case 27:
472                            
473                            case 28:
474                                return "TMCC1 - Engine " + A + " - Blow Whistle/Horn 1";
475                            case 29:
476                                return "TMCC1 - Engine " + A + " - Ring Bell";
477                            case 30:
478                                return "TMCC1 - Engine " + A + " - Letoff Sound";
479                            case 31:
480                                return "TMCC1 - Engine " + A + " - Blow Horn 2";
481                            default:
482                                return "TMCC1 - Engine " + A + " - Unassigned FnKey TMCC1 (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
483                        }
484
485                    case 1: // If C (TMCC Command Code) == 1
486                        switch (D & 0x1F) {
487                            case 0:
488                                return "TMCC1 - Engine " + A + " - Assign as Single Unit - Forward Direction";
489                            case 1:
490                                return "TMCC1 - Engine " + A + " - Assign as Head Unit  - Forward Direction";
491                            case 2:
492                                return "TMCC1 - Engine " + A + " - Assign as Middle Unit  - Forward Direction";
493                            case 3:
494                                return "TMCC1 - Engine " + A + " - Assign as Rear Unit  - Forward Direction";
495                            case 4:
496                                return "TMCC1 - Engine " + A + " - Assign as Single Unit - Reverse Direction";
497                            case 5:
498                                return "TMCC1 - Engine " + A + " - Assign as Head Unit - Reverse Direction";
499                            case 6:
500                                return "TMCC1 - Engine " + A + " - Assign as Middle Unit - Reverse Direction";
501                            case 7:
502                                return "TMCC1 - Engine " + A + " - Assign as Rear Unit - Reverse Direction";
503                            case 8:
504                                return "TMCC1 - Engine " + A + " - Momentum Low";
505                            case 9:
506                                return "TMCC1 - Engine " + A + " - Momentum Medium";
507                            case 10:
508                                return "TMCC1 - Engine " + A + " - Momentum High";
509                            case 11:
510                                return "TMCC1 - Engine ID " + A + " - Set";
511                            case 12:
512                                
513                            case 13:
514                                
515                            case 14:
516                                
517                            case 15:
518                                
519                            case 16:
520                                return "TMCC1 - Engine " + A + " - Clear Train (Consist) Assignment";
521                            case 17:
522                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 1";
523                            case 18:
524                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 2";
525                            case 19:
526                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 3";
527                            case 20:
528                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 4";
529                            case 21:
530                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 5";
531                            case 22:
532                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 6";
533                            case 23:
534                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 7";
535                            case 24:
536                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 8";
537                            case 25:
538                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 9";
539                            case 26:
540                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 10";
541                            case 27:
542                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 11";
543                            case 28:
544                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 12";
545                            case 29:
546                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 13";
547                            case 30:
548                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 14";
549                            case 31:
550                                return "TMCC1 - Engine " + A + " - Assign to Train (Consist) 15";
551                            default:
552                                return "TMCC1 - Engine " + A + " - Unassigned FnKey TMCC1 (Case C=1) - with A= " + A + " C= " + C + " D= " + D;
553                        }
554                    
555                    //$FALL-THROUGH$
556                    case 2: // If C (TMCC Command Code) == 2
557                        return "TMCC1 - Engine " + A + " - Change Speed (Relative) by " + (D - 5);
558
559                    case 3: // If C (TMCC Command Code) == 3
560                    default: // to let the compiler know there are only 3 cases
561                        return "TMCC1 (32 Speed Steps) - Engine " + A + " - Speed (Absolute) = " + (D-32);
562                }
563
564
565            } else if ((val & 0xC000) == 0xC000) {
566                // TMCC1 Train Commands
567                int A = (val / 128) & 0x0F; // A is TMCC Adddress Code
568                int C = (val / 32) & 0x03; // C is TMCC Command Code
569                int D = val & 0x3F; // D is TMCC Data Code
570                switch (C) {
571                    case 0: // If C (TMCC Command Code) == 0
572                        switch (D) {
573                            case 0:
574                                return "TMCC1 - Train " + A + " - Forward Direction";
575                            case 1:
576                                return "TMCC1 - Train " + A + " - Toggle Direction";
577                            case 2:
578                            
579                            case 3:
580                                return "TMCC1 - Train " + A + " - Reverse Direction";
581                            case 4:
582                                return "TMCC1 - Train " + A + " - Boost";
583                            case 5:
584                                return "TMCC1 - Train " + A + " - Open Front Coupler";
585                            case 6:
586                                return "TMCC1 - Train " + A + " - Open Rear Coupler";
587                            case 7:
588                                return "TMCC1 - Train " + A + " - Brake";
589                            case 8:
590                            
591                            case 9:
592                                return "TMCC1 - Train " + A + " - AUX1 Option 1 (CAB AUX1 Button; On While Pressed/On Until Next Button Pressed)";
593                            case 10:
594                            
595                            case 11:
596                            
597                            case 12:
598                            
599                            case 13:
600                                return "TMCC1 - Train " + A + " - Headlight Toggle On/Off (AUX2 Option 1/AUX2 Button)";
601                            case 14:
602                            
603                            case 15:
604                            
605                            case 16:
606                                return "TMCC1 - Train " + A + " - Num 0 - Train Reset";
607                            case 17:
608                                return "TMCC1 - Train " + A + " - Num 1 - Sound Volume Increase";
609                            case 18:
610                                return "TMCC1 - Train " + A + " - Num 2 - Crew Talk";
611                            case 19:
612                                return "TMCC1 - Train " + A + " - Num 3 - Sound On w/Start-Up Sequence";
613                            case 20:
614                                return "TMCC1 - Train " + A + " - Num 4 - Sound Volume Decrease - TMCC1 Loco Feature Type 4";
615                            case 21:
616                                return "TMCC1 - Train " + A + " - Num 5 - Sound Off w/Shut-Down Sequence - TMCC1 Loco Feature Type 5";
617                            case 22:
618                                return "TMCC1 - Train " + A + " - Num 6 - Steam Release/RPM Decrease - TMCC1 Loco Feature Type 6";
619                            case 23:
620                                return "TMCC1 - Train " + A + " - Num 7 - Tower Com Announcement";
621                            case 24:
622                                return "TMCC1 - Train " + A + " - Num 8 - Feature Off (Smoke/Aux Lighting) - TMCC1 Loco Feature Type 8";
623                            case 25:
624                                return "TMCC1 - Train " + A + " - Num 9 - Feature On (Smoke/Aux Lighting)";
625                            case 26:
626                            
627                            case 27:
628                            
629                            case 28:
630                                return "TMCC1 - Train " + A + " - Blow Whistle/Horn 1";
631                            case 29:
632                                return "TMCC1 - Train " + A + " - Ring Bell";
633                            case 30:
634                                return "TMCC1 - Train " + A + " - Letoff Sound";
635                            case 31:
636                                return "TMCC1 - Train " + A + " - Blow Horn 2";
637                            default:
638                                return "TMCC1 - Train " + A + " - Unassigned FnKey TMCC1 (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
639                        }
640
641                    case 1: // If C (TMCC Command Code) == 1
642                        switch (D & 0x17) {
643                            case 0:
644                                return "TMCC1 - Train " + A + " - Momentum Low";
645                            case 1:
646                                return "TMCC1 - Train " + A + " - Momentum Medium";
647                            case 2:
648                                return "TMCC1 - Train " + A + " - Momentum High";
649                            case 3:
650                                return "TMCC1 - Track/Train ID " + A + " - Set";
651                            default:
652                                return "Unrecognized Train(TR) Command with A= " + A + " C= " + C + " D= " + D;
653                        }
654
655                    //$FALL-THROUGH$
656                    case 2: // If C (TMCC Command Code) == 2
657                        return "TMCC1 - Train " + A + " - Change Speed (Relative) by " + (D - 5);
658
659                    case 3: // If C (TMCC Command Code) == 3
660                    default: // to let the compiler know there are only 3 cases
661                        return "TMCC1 (32 Speed Steps) - Train " + A + " - Speed (Absolute) = " + (D-32);
662                }
663
664            } else if ((val & 0xC000) == 0x8000) {
665                // TMCC1 Accessory Commands
666                int A = (val / 128) & 0x7F; // A is TMCC Adddress Code
667                int C = (val / 32) & 0x03; // C is TMCC Command Code
668                int D = val & 0x1F; // D is TMCC Data Code
669                switch (C) {
670                    case 0: // If C (TMCC Command Code) == 0
671                        switch (D) {
672                            case 0:
673                            case 1:
674                            case 2:
675                            case 3:
676                            case 4:
677                            case 5:
678                            case 6:
679                            case 7:
680                            case 8:
681                                return "Aux 1 - ACC " + A + " - OFF";
682                            case 9:
683                                return "Aux 1 - ACC " + A + " - OPTION 1 (On While Pressed)";
684                            case 10:
685                                return "Aux 1 - ACC " + A + " - OPTION 2 (Toggle On/Toggle Off)";
686                            case 11:
687                                return "Aux 1 - ACC " + A + " - ON";
688                            case 12:
689                                return "Aux 2 - ACC " + A + " - OFF";
690                            case 13:
691                                return "Aux 2 - ACC " + A + " - OPTION 1 (Toggle On/Toggle Off)";
692                            case 14:
693                                return "Aux 2 - ACC " + A + " - OPTION 2 (On While Pressed)";
694                            case 15:
695                                return "Aux 2 - ACC " + A + " - ON";
696                            default:
697                                return "Unrecognized Accessory(ACC) Command (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
698                        }
699                        
700                    case 1: // If C (TMCC Command Code) == 1
701                        switch (D) {
702                            case 0:
703                                return "ALL ACC OFF";
704                            case 11:
705                                return "Accessory ID " + A + " - Set";
706                            case 15:
707                                return "ALL ACC ON";
708//                } else if ((C == 1) && (D == 0x??)) {
709//                    return "Assign Aux 1 to Group D " + A + " - 0-9";
710//                } else if ((C == 1) && (D == 0x??)) {
711//                    return "Assign Aux 2 to Group D " + A + " - 0-9"";
712                            default:
713                                return "Unrecognized Accessory(ACC) Command (Case C=1) - with A= " + A + " C= " + C + " D= " + D;
714                        }
715
716               default:
717                    return "Unrecognized Accessory(ACC) Command (Case C) - with A= " + A + " C= " + C + " D= " + D;
718                }
719
720            } else if ((val & 0xF800) == 0xC000) {
721                // TMCC1 Group Commands
722                int A = (val / 128) & 0x0F; // A is TMCC Adddress Code
723                int C = (val / 32) & 0x03; // C is TMCC Command Code
724                int D = val & 0x1F; // D is TMCC Data Code
725                switch (C) {
726                    case 0: // If C (TMCC Command Code) == 0
727                        switch (D) {
728                            case 0:
729                            case 1:
730                            case 2:
731                            case 3:
732                            case 4:
733                            case 5:
734                            case 6:
735                            case 7:
736                            case 8:
737                                return "GROUP - ACC " + A + " - OFF";
738                            case 9:
739                                return "GROUP - ACC " + A + " - OPTION 1 (On While Pressed)";
740                            case 10:
741                                return "GROUP - ACC " + A + " - OPTION 2 (Toggle On/Toggle Off)";
742                            case 11:
743                                return "GROUP - ACC " + A + " - ON";
744                            default:
745                                return "Unrecognized Group(GR) Command (Case C=0) - with A= " + A + " C= " + C + " D= " + D;
746                        }
747
748                    case 1: // If C (TMCC Command Code) == 1
749                        switch (D) {
750                            case 12:
751                                return "GROUP - ACC " + A + " - CLEAR";
752                            default:
753                                return "Unrecognized Group(GR) Command (Case C=1) - with A= " + A + " C= " + C + " D= " + D;                              
754                        }
755
756                default:
757                    return "Unrecognized Group(GR) Command (Case C) - with A= " + A + " C= " + C + " D= " + D;
758                }
759            }            
760        }
761
762        // TMCC Error parsing
763        if (opCode == 0x00) {
764            int C = (val / 32) & 0x03; // C is TMCC Command Code
765            int D = val & 0x1F; // D is TMCC Data Code
766            switch (C) {
767                case 0: // If C (TMCC Command Code) == 0
768                    switch (D) {
769                        case 0:
770                            return "Address Must be Between 1-98 for TMCC1 and TMCC2 ENG/SW/ACC and TMCC2 TR. Address Must be Between 1-9 for TMCC1 TR";
771                        case 1:
772                            return "CV Must Equal 1 for Programming TMCC Loco/Engine, Switch, Accessory, Track ID#s";
773                        case 2:
774                            return "CV Must Equal 2 for Programming TMCC Loco Feature Type";
775                        case 3:
776                            return "Value Entered is Not a TMCC1 Loco Feature Type";
777                        case 4:
778                            return "Value Entered is Not a TMCC2 Loco Feature Type";
779                        default:
780                            return "Unrecognized TMCC Error (Case C=0) - with C= " + C + " D= " + D;
781                    }
782            default:
783                return "Unrecognized TMCC Error (Case C) - with C= " + C + " D= " + D;
784            }
785        }
786
787        return "TMCC - Direct Command Sent";
788//        return "TMCC - CV#, Loco ID#/Address/Loco Feature Value - Out of Range";
789
790    }
791}
792