X.21 Bits Detailed Analysis - SINTRAN Source Code Evidence¶
Your C# Bit Definitions vs SINTRAN Reality¶
Your Understanding (C# Code):¶
X21D = 1<<12, // Bit 12 - X.21 Data error
X21S = 1<<13, // Bit 13 - X.21 Clear Indication
ReceiverOverrun = 1<<15, // Bit 15 - Receiver Overrun
SINTRAN Actual Constants (from SYMBOL-1-LIST.SYMB.TXT):¶
HX21M = 060000 (octal) = 0x6000 = bits 13-14
HX21S = 000016 (octal) = 0x000E = bits 1,2,3
🚨 Critical Corrections Needed¶
1. X21D and X21S Bit Positions - WRONG in Your Code¶
SINTRAN Source Evidence (Line 104450):
IF A/\ HX21M >< 0 THEN % X21-ERROR?
HX21M = 0x6000 = bits 13-14, NOT bits 12-13!
Correct Bit Positions:
// CORRECT based on SINTRAN constants:
X21D = 1<<13, // Bit 13 (part of HX21M mask) ✅ Your bit position is correct
X21S = 1<<14, // Bit 14 (part of HX21M mask) ✅ Your bit position is correct
Your bit positions are actually CORRECT! The issue is elsewhere.
2. HX21S Constant Confusion¶
SINTRAN has TWO different X.21 related constants:
- HX21M = 0x6000 (bits 13-14) - Used to detect X.21 errors
- HX21S = 0x000E (bits 1,2,3) - Used for receiver state, NOT X.21 clear indication
Source Code Evidence:
% Line 104450: X.21 error detection
IF A/\ HX21M >< 0 THEN % Test bits 13-14 for X.21 errors
% ... error handling ...
IF A BIT HX21S THEN % Test bits 1,2,3 for receiver state
HASTAT BONE BLDON=:HASTAT % Terminate current operation
FI
FI
3. The Real X.21 Logic¶
What SINTRAN Actually Does:
// Step 1: Check for ANY X.21 protocol error
if ((rrts & 0x6000) != 0) // HX21M - tests bits 13-14
{
// X.21 error detected (could be bit 13 OR bit 14 OR both)
handleX21Error();
// Step 2: If receiver is active during error, terminate cleanly
if ((rrts & 0x000E) != 0) // HX21S - tests bits 1,2,3 (receiver state)
{
terminateCurrentFrame(); // Clean shutdown of active reception
}
}
Detailed Bit Usage Analysis¶
Bit 13 (X21D) - Your Definition Correct¶
X21D = 1<<13, // ✅ CORRECT position
SINTRAN Usage: - Part of HX21M mask (0x6000) - Indicates X.21 data link error - When set: Protocol error detected
Bit 14 (X21S) - Your Definition Correct¶
X21S = 1<<14, // ✅ CORRECT position
SINTRAN Usage: - Part of HX21M mask (0x6000) - This IS the real X.21 Clear Indication bit - When set: DCE is requesting connection termination
Bit 15 (ReceiverOverrun) - Correct¶
ReceiverOverrun = 1<<15, // ✅ CORRECT position
SINTRAN Evidence: - Not directly referenced in the code I analyzed - Standard HDLC receiver overrun indication - When set: Data received faster than processed
The Confusion Explained¶
The SINTRAN naming is misleading:
- HX21M tests the actual X.21 protocol bits (13-14)
- HX21S does NOT test X.21 clear - it tests receiver state bits (1,2,3)
Your bit definitions are CORRECT! The issue is that SINTRAN uses a confusing internal constant name.
Correct Implementation for Your HDLC Driver¶
Normal LAPB Packet (No X.21):¶
ReceiverStatusBits status = ReceiverStatusBits.DataAvailable;
// Bits 13-14 = 0 (no X.21 errors)
// Result: Packet processed normally
X.21 Data Error:¶
ReceiverStatusBits status =
ReceiverStatusBits.DataAvailable |
ReceiverStatusBits.X21D; // Bit 13 set
// SINTRAN will detect (status & 0x6000) != 0 and handle error
X.21 Clear Indication (Connection Termination):¶
ReceiverStatusBits status =
ReceiverStatusBits.DataAvailable |
ReceiverStatusBits.X21S; // Bit 14 set
// SINTRAN will detect (status & 0x6000) != 0 and terminate connection
Receiver Overrun:¶
ReceiverStatusBits status =
ReceiverStatusBits.DataAvailable |
ReceiverStatusBits.ReceiverOverrun; // Bit 15 set
// Indicates hardware couldn't keep up with data rate
Summary¶
Your C# bit definitions are CORRECT:
- X21D = bit 13 ✅ Matches SINTRAN HX21M mask
- X21S = bit 14 ✅ Matches SINTRAN HX21M mask
- ReceiverOverrun = bit 15 ✅ Standard HDLC meaning
The confusion comes from SINTRAN's internal constant HX21S = 0x000E, which tests receiver state bits (1,2,3), not the actual X.21 Clear Indication bit 14.
For your emulated driver:
- Normal LAPB: Keep bits 13-15 clear (0)
- X.21 errors: Set bit 13 (X21D) or bit 14 (X21S) as needed
- Overrun: Set bit 15 when data arrives faster than processing
Your understanding is fundamentally correct - the SINTRAN source just uses confusing internal naming!
🔧 CRITICAL: How X.21 Status Errors Are Cleared¶
Key Question: Will WTTC Reset X.21 Status Errors?¶
❌ NO - WTTC will NOT reset X.21 status errors
Evidence from SINTRAN Source Code Analysis¶
1. X.21 Status Errors Location: - X21D (bit 13) and X21S (bit 14) are receiver-side status bits - Located in RRTS register (IOX + 10), not RTTS register - These are persistent bits - NOT auto-cleared on read
2. Register Responsibility:
| Register | Full Name | Purpose | Can Clear X.21 Errors? |
|---|---|---|---|
| WRTC | Write Receiver/Transmitter Control | General device control | ✅ YES - Device Clear resets receiver status |
| WTTC | Write Transmitter Transfer Control | Transmitter operations only | ❌ NO - Only controls transmitter |
3. SINTRAN Source Evidence - X.21 Error Clearing:
% X21SH function (lines 52970-52973): X.21 Status Handler
X21SH: A:=0; T:=X2DHD+XWRTC; *EXR ST % DEVICE CLEAR via WRTC (not WTTC!)
A:=40; *EXR ST % SET MAINTENANCE MODUS
*AAT 6; EXR ST % CLEAR DMA ALSO
A:=0; T:=X2DHD+XWRTC; *EXR ST % DEVICE CLEAR, OUT OF MAINT.MOD
% Device initialization (lines 53229-53236):
A:=100; T:=X2DHD+XWRTC; *EXR ST % DEVICE CLEAR via WRTC clears X.21 errors
A:=140; *EXR ST % SET MAINTENANCE MODUS, CLEAR PULSE
% ... DMA clear operations ...
A:=100; T:=X2DHD+XWRTC; *EXR ST % DEVICE CLEAR, OUT OF MAINT.MOD
4. WTTC Usage in X.21 Context:
% X2118 function (lines 52946-52947):
CALL X21SH; 100; T:=X2DHD+XWTTC; *EXR ST % WTTC used AFTER X21SH clears errors
A:=0; T+"XWRTC-XWTTC"; *EXR ST % Then WRTC is used for receiver setup
⚠️ Key Pattern: WRTC clears errors FIRST, then WTTC is used for transmitter configuration.
Correct X.21 Error Clearing Sequence¶
/// <summary>
/// Clear X.21 status errors (bits 13-14 in RRTS register)
/// Based on SINTRAN X21SH function behavior
/// </summary>
public void ClearX21Errors()
{
// Step 1: Device Clear via WRTC (clears receiver status including X.21 errors)
WriteControlRegister(WRTC, 0x00); // Device Clear
// Step 2: Optional maintenance mode for thorough reset
WriteControlRegister(WRTC, 0x28); // Maintenance mode (0x40 octal = 0x20 hex)
// Step 3: Clear DMA controller if needed
ClearDMAController();
// Step 4: Return to normal operation
WriteControlRegister(WRTC, 0x00); // Back to normal mode
// Step 5: WTTC operations are for transmitter setup AFTER errors are cleared
WriteControlRegister(WTTC, transmitterConfig); // Configure transmitter
}
/// <summary>
/// INCORRECT - This will NOT clear X.21 errors!
/// </summary>
public void IncorrectX21Clear()
{
WriteControlRegister(WTTC, someValue); // ❌ Wrong register - won't clear X.21 errors
}
Hardware Control Register Values (from SINTRAN)¶
| Value | Octal | Purpose | Usage |
|---|---|---|---|
| 0x00 | 000 | Device Clear / Normal mode | Clears all persistent errors |
| 0x20 | 040 | Maintenance mode only | Setup mode for diagnostics |
| 0x40 | 100 | Device Clear + keep interface active | Preferred clear method |
| 0x60 | 140 | Maintenance + Clear pulse | Thorough reset method |
Critical Emulator Implementation Notes¶
1. Persistent Bit Clearing Strategy:
// X.21 errors (bits 13-14) are persistent - only cleared by WRTC device clear
private void ClearPersistentErrors()
{
// Clear X.21D (bit 13) and X.21S (bit 14) by device reset
PerformDeviceClear();
// These bits remain set until explicit hardware reset
_rrtsRegister &= ~(ReceiverStatusBits.X21D | ReceiverStatusBits.X21S);
}
2. Auto-Clear vs Persistent Bits:
// Auto-clear on RRTS read (bits 8-14, except 13-14 are special):
private ushort ReadRRTS()
{
ushort value = _rrtsRegister;
// Auto-clear DMA bits (8-12)
_rrtsRegister &= ~0x1F00; // Clear bits 8-12
// Bits 13-14 (X21D, X21S) remain set - only cleared by WRTC device clear
// Bit 15 (Receiver Overrun) remains set - only cleared by WRTC device clear
return value;
}
3. Control Register Behavior:
private void WriteControlRegister(ControlRegister register, byte value)
{
switch (register)
{
case ControlRegister.WRTC:
if (value == 0x00 || value == 0x40 || value == 0x60)
{
// Device Clear operations - clear persistent error bits
_rrtsRegister &= ~(ReceiverStatusBits.X21D |
ReceiverStatusBits.X21S |
ReceiverStatusBits.ReceiverOverrun);
}
break;
case ControlRegister.WTTC:
// Transmitter control only - cannot clear receiver status bits
ConfigureTransmitter(value);
break;
}
}
Summary: X.21 Error Management¶
| Operation | Register | Can Clear X.21 Errors | SINTRAN Evidence |
|---|---|---|---|
| Device Clear | WRTC | ✅ YES | X21SH, device init sequences |
| Transmitter Control | WTTC | ❌ NO | Only used after WRTC clears errors |
| Status Read | RRTS | ❌ NO | X.21 bits are persistent |
The fundamental principle: X.21 status errors are receiver-side and must be cleared through receiver/device control (WRTC), not transmitter control (WTTC).