HIINT Deep Analysis - Complete Receiver Interrupt Handler Flow¶
Overview¶
HIINT is the SINTRAN receiver interrupt handler (Line 104436) that processes all incoming HDLC frames. It performs critical status validation, buffer management, and packet processing with sophisticated error handling and state tracking.
Critical Constants and Variables (from SYMBOL-1-LIST.SYMB.TXT)¶
Memory Variables (Read/Write)¶
% Core Status Variables:
HASTA = 000076 % HASTAT - Hardware status storage (16-bit)
ACTSW = 000074 % Activity switch: 0=inactive, 1=active
Status Bit Constants (Read-Only)¶
% Receiver Status Detection Constants:
EMTY = 004000 % 0x0800, bit 11 - List Empty (No Buffers)
HX21M = 060000 % 0x6000, bits 13-14 - X.21 Error Mask
HX21S = 000016 % 0x000E, bits 1,2,3 - Receiver State Check
BLDON = 000010 % 0x0008, bit 3 - Block Done Flag
ERB = 001000 % 0x0200, bit 9 - Error Block Indicator
% DMA Descriptor Control (BREAKTHROUGH DISCOVERY):
% Receiver uses different LKEY values than transmitter
% Bits 10-8: Block status (Empty=010, Full=011)
% Bits 7-0: COM5025 register values for frame detection
Counters (Not Found in Symbol Tables - Likely Local Variables)¶
% Diagnostic Counters:
T9 = ? % Dummy interrupt counter (HIINT specific)
STPCNT = ? % Stop counter for receiver buffer exhaustion
BREAKTHROUGH: DMA KEY Field Contains COM5025 Register Values¶
Revolutionary Discovery for Receiver Operations¶
Just as with transmission, the receiver DMA descriptor LKEY field contains actual COM5025 chip register values in its low 8 bits. However, for reception, these control frame detection rather than frame generation.
% Receiver DMA Descriptor LKEY Structure:
% Bits 15-8: Block control (Empty=010, Full=011, etc.)
% Bits 7-0: COM5025 RSOM/REOM detection flags and control bits
% Receiver LKEY values (expected patterns):
% Empty block ready for reception: 001000₈ (Empty block + detection flags)
% Full block with complete frame: 001403₈ (Full block + RSOM + REOM)
% Full block with frame start: 001401₈ (Full block + RSOM only)
% Full block with frame end: 001402₈ (Full block + REOM only)
WRTC Interrupt Enable Control - Critical Understanding¶
How HIINT Gets Called - Interrupt Enable Analysis¶
HIINT only executes when specific RRTS status bits generate hardware interrupts. This is controlled by WRTC (Write Receiver Transfer Control) register values that SINTRAN sets to enable/disable interrupt generation for different status conditions.
WRTC Control Values Found in SINTRAN Source¶
Based on the SINTRAN source analysis, these are the key WRTC values that control when HIINT is called:
1. Basic Receiver Clear (WRTC = 100 octal = 0x40)¶
% Used during device shutdown/clear:
A:=100; T:=HDEV+WRTC; *EXR ST % Clear receiver, minimal interrupts
2. Maintenance Mode (WRTC = 140 octal = 0x60)¶
% Used during maintenance operations:
IF A = MAMOD THEN A:=140 ELSE A:=100 FI % Maintenance or normal mode
A=:MAINT; T:=HDEV+WRTC; *EXR ST % Set maintenance mode
3. Full DMA Reception Mode (WRTC = 1734 octal = 0x3DC)¶
% PRIMARY operational mode for packet reception:
A:="1734"\/MAINT/\HXDOK % Combine with maintenance flags
T:=HDEV+WRTC; *EXR ST % Enable full reception
4. Combined Control Logic¶
% SINTRAN combines WRTC value with flags:
HXDOK/\MAINT; T:=HDEV+WRTC; *EXR ST % Clear old state
1734\/MAINT/\HXDOK; T:=HDEV+WRTC; *EXR ST % Set full mode with flags
% Where:
HXDOK = Hardware OK flags (device-specific enables)
MAINT = Maintenance mode flags (100 or 140)
WRTC Bit Analysis for Interrupt Generation¶
The WRTC value 1734 (octal) = 0x3DC breaks down as:
Binary: 0011 1101 1100
Hex: 0x3DC
Decimal: 988
Octal: 1734
Bit Pattern:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0
^ ^ ^ ^
Enables for bits:
- Bit 13-14: X.21 error interrupt enables
- Bit 11: Buffer empty interrupt enable
- Bit 10: List end interrupt enable
- Bit 9: Frame end interrupt enable
- Bit 8: Block end interrupt enable
Critical Interrupt Enable Logic¶
For HIINT to be called, the corresponding WRTC enable bit must be set AND the RRTS status bit must become active:
Normal Packet Reception Flow:¶
% 1. SINTRAN sets WRTC = 1734 (enables multiple interrupt sources)
1734\/MAINT/\HXDOK; T:=HDEV+WRTC; *EXR ST
% 2. Hardware sets RRTS bits when conditions occur:
% - DataAvailable (bit 0) when packet received
% - ListEmpty (bit 11) when no more buffers
% - X21D/X21S (bits 13-14) when protocol errors occur
% 3. Interrupt generated ONLY if both:
% - WRTC enable bit is set (interrupt permission)
% - RRTS status bit becomes active (condition detected)
% 4. HIINT called with RRTS status available to read
HIINT: T:=HDEV+RRTS; *EXR ST % Read status that triggered interrupt
WRTC Configuration Sequence in SINTRAN¶
Device Start Sequence:¶
ZSTARC: IF ACTSW = 0 THEN % If device not active
% Step 1: Clear old state
HXDOK/\MAINT; T:=HDEV+WRTC; *EXR ST % Clear garbage (value = MAINT & HXDOK)
% Step 2: Start DMA
LIINT+DPITPHYS; T:=HDEV+WDMA; *EXR ST % Set DMA address
A:=1001; T+"WDCR-WDMA"; *EXR ST % Start receiver DMA
% Step 3: Enable full reception mode
1734\/MAINT/\HXDOK; T:=HDEV+WRTC; *EXR ST % Enable all receiver interrupts
1=:ACTSW % Mark device active
FI
Impact on C# HDLC Emulator¶
Your C# HDLC controller emulator needs to:
- Track WRTC register writes to understand which interrupt sources are enabled
-
Only generate interrupts for enabled conditions:
// Example interrupt logic: ushort wrtcValue = currentWRTCRegister; // Value SINTRAN last wrote ushort rrtsStatus = currentReceiverStatus; // Check each potential interrupt source: if ((wrtcValue & 0x0001) && (rrtsStatus & 0x0001)) { // DataAvailable interrupt enabled and data is available TriggerReceiverInterrupt(); } if ((wrtcValue & 0x0800) && (rrtsStatus & 0x0800)) { // ListEmpty interrupt enabled and no buffers TriggerReceiverInterrupt(); } if ((wrtcValue & 0x6000) && (rrtsStatus & 0x6000)) { // X.21 error interrupts enabled and error occurred TriggerReceiverInterrupt(); } -
Understand the WRTC patterns:
- WRTC = 100: Minimal interrupts (cleanup/shutdown)
- WRTC = 140: Maintenance mode interrupts
- WRTC = 1734: Full operational interrupts (normal reception)
WRTC/HIINT Relationship Summary¶
| WRTC Value | Context | Interrupt Sources | HIINT Called When |
|---|---|---|---|
| 100 (0x40) | Cleanup/shutdown | Minimal (errors only) | Critical errors only |
| 140 (0x60) | Maintenance | Diagnostic + errors | Test conditions + errors |
| 1734 (0x3DC) | Normal operation | All reception events | DataAvailable, ListEmpty, X.21 errors, DMA status |
Key Insight: HIINT is NOT called automatically - it only executes when WRTC-enabled interrupt conditions occur in the RRTS register. The value 1734 (octal) is the key operational setting that enables comprehensive receiver interrupt generation.
Deep Analysis: RRTS DMA Status Bits vs. Packet Indicators¶
Critical Understanding: BlockEnd vs FrameEnd vs ListEnd vs ListEmpty¶
Based on SINTRAN source analysis and HIINT processing logic, these DMA status bits have very different meanings and usage patterns:
BlockEnd (Bit 8) - DMA Block Completion¶
% SINTRAN Usage Pattern:
IF A BIT BLDON THEN % Block done check
% Process completed DMA block
FI
Scope: One block in a multi-block transfer
HDLC Context: One receive buffer filled, but packet may span multiple blocks
HIINT Processing: NOT used in main packet validation logic
Emulator Usage: Set when individual receive buffer is filled, regardless of packet completeness
FrameEnd (Bit 9) - HDLC Frame Completion¶
% SINTRAN Usage: Limited direct usage in HIINT packet processing
% More relevant for hardware frame boundary detection
Scope: Single HDLC frame (flag-to-flag)
HDLC Context: Hardware detected end-of-frame flag sequence
HIINT Processing: NOT used in main packet validation logic
Emulator Usage: Set when HDLC frame is complete (FCS validated, closing flag detected)
ListEnd (Bit 10) - DMA Descriptor List Exhausted¶
% SINTRAN Usage Pattern (more common in transmitter):
IF BSKP ONE 10 THEN % List end check
% Handle end of DMA descriptor list
FI
Scope: Multiple blocks/buffers in linked list structure
HDLC Context: All allocated receive buffers have been used
HIINT Processing: NOT directly referenced in receiver processing
Emulator Usage: Set when running out of pre-allocated DMA descriptors
ListEmpty (Bit 11) - FATAL System Condition ⚠️¶
% SINTRAN Usage Pattern in HIINT (CRITICAL):
IF HASTA/\"EMTY" >< 0 THEN % List empty check (bit 11)
0=:ACTSW % *** STOP RECEIVER ***
STPCNT+1=:STPCNT % Count stop events
GO OUT1 % Exit - no buffers
FI
Scope: System-wide buffer exhaustion
HDLC Context: Cannot receive any more packets - catastrophic condition
HIINT Processing: CRITICAL - Forces receiver shutdown (ACTSW = 0)
Emulator Usage: Set ONLY to simulate system buffer starvation
RRTS DMA Status Bit Hierarchy and Relationships¶
RECEIVER DMA OPERATION LEVELS (from smallest to largest scope):
BlockEnd (bit 8) ─── Single buffer/block completed
│
├─ FrameEnd (bit 9) ─── HDLC frame boundary detected
│
├─ ListEnd (bit 10) ─── All DMA descriptors processed
│
└─ ListEmpty (bit 11) ─── NO buffers available (FATAL)
NORMAL HIINT PROCESSING:
1. BlockEnd: Buffer full → continue filling next buffer (ignored by HIINT)
2. FrameEnd: Frame complete → hardware status (ignored by HIINT)
3. ListEnd: All buffers used → may need more descriptors (ignored by HIINT)
4. ListEmpty: No buffers left → STOP RECEIVER (CRITICAL for HIINT)
5. DataAvailable: Packet ready → CALL PROCPKT (CRITICAL for HIINT)
HIINT-Specific Packet Reception Scenarios for HDLC Emulator¶
Understanding HIINT's RRTS Status Bit Processing¶
HIINT performs specific bit checks in order. Your emulator must set RRTS bits that match HIINT's expectations:
Scenario 1: Normal Single-Block Packet Reception ✅¶
/// <summary>
/// Normal packet that fits in one DMA buffer - HIINT SUCCESS PATH
/// </summary>
public ushort HandleSingleBlockPacketReceived()
{
// HIINT expects ONLY DataAvailable for normal packets
// Phase 5 check: IF A NBIT 0 OR A/\60000><0 THEN GO OUT1 FI
var status = ReceiverStatusBits.DataAvailable; // Bit 0
// DO NOT set BlockEnd, FrameEnd, ListEnd - HIINT ignores these
// HIINT only cares about: DataAvailable(0), ListEmpty(11), X21D/X21S(13-14)
return (ushort)status; // 0x0001 → HIINT calls PROCPKT
}
Scenario 2: Multi-Block Packet Reception (Large Packet) 🔄¶
/// <summary>
/// Large packet spanning multiple DMA buffers - HIINT intermediate processing
/// </summary>
public ushort HandleMultiBlockPacketReceived(bool isLastBlock, bool isFrameComplete)
{
var status = ReceiverStatusBits.None;
if (!isLastBlock)
{
// Intermediate block - set BlockEnd but NOT DataAvailable
// HIINT will see DataAvailable=0 and GO OUT1 (exit without processing)
status |= ReceiverStatusBits.BlockEnd; // Bit 8
// Result: HIINT exits, no packet processing, waits for final block
}
else
{
// Final block of packet - NOW set DataAvailable
status |= ReceiverStatusBits.DataAvailable; // Bit 0 - CRITICAL for HIINT
if (isFrameComplete)
{
// Optionally set FrameEnd (HIINT ignores it but shows hardware state)
status |= ReceiverStatusBits.FrameEnd; // Bit 9
}
// Result: HIINT calls PROCPKT for complete packet
}
return (ushort)status;
}
Scenario 3: Buffer List Exhaustion - HIINT FATAL CONDITION ⚠️¶
/// <summary>
/// Simulate system running out of receive buffers - HIINT SHUTDOWN
/// </summary>
public ushort HandleBufferExhaustion()
{
// Set DataAvailable + ListEmpty to trigger HIINT controlled shutdown
var status = ReceiverStatusBits.DataAvailable | // Bit 0 - process current packet
ReceiverStatusBits.ListEmpty; // Bit 11 - no more buffers
// HIINT Phase 4 processing:
// IF HASTA/\"EMTY" >< 0 THEN
// 0=:ACTSW *** FORCED DEACTIVATION ***
// STPCNT+1=:STPCNT Count stop events
// GO OUT1 Exit without processing
// FI
return (ushort)status; // 0x0801 → HIINT shuts down receiver
}
Scenario 4: X.21 Protocol Error - HIINT ERROR HANDLING 🚨¶
/// <summary>
/// Simulate X.21 protocol errors - HIINT error path
/// </summary>
public ushort HandleX21ProtocolError(X21ErrorType errorType)
{
var status = ReceiverStatusBits.DataAvailable; // Still have data to process
switch (errorType)
{
case X21ErrorType.DataIndication:
status |= ReceiverStatusBits.X21D; // Bit 13
break;
case X21ErrorType.CallSetupClear:
status |= ReceiverStatusBits.X21S; // Bit 14
break;
case X21ErrorType.Both:
status |= ReceiverStatusBits.X21D | ReceiverStatusBits.X21S;
break;
}
// HIINT Phase 3 processing:
// IF A/\ HX21M >< 0 THEN X.21 error check (bits 13-14)
// IF A BIT HX21S THEN Check receiver state (bits 1,2,3)
// HASTA BONE BLDON=:HASTA Set block done flag (bit 3)
// FI
// CALL X21ERR Handle X.21 protocol error
// GO OUT1 Exit - packet NOT processed
// FI
return (ushort)status; // 0x2001, 0x4001, or 0x6001 → HIINT calls X21ERR
}
Scenario 5: Receiver Overrun - HIINT DIAGNOSTIC 📊¶
/// <summary>
/// Simulate receiver hardware overrun condition - HIINT logging
/// </summary>
public ushort HandleReceiverOverrun()
{
// Set ReceiverOverrun but still indicate data available
var status = ReceiverStatusBits.DataAvailable | // Bit 0
ReceiverStatusBits.ReceiverOverrun; // Bit 15
// Note: HIINT doesn't explicitly check bit 15 in main processing logic
// but it gets stored in HASTAT and logged to circular buffers (BUFF2)
// Result: Packet processed normally, overrun logged for diagnostics
return (ushort)status; // 0x8001 → HIINT processes packet + logs overrun
}
HIINT Decision Tree with RRTS Status Bits¶
/// <summary>
/// Emulate HIINT's exact RRTS status bit processing logic
/// </summary>
public class HiintStatusProcessor
{
public HiintResult ProcessRrtsStatus(ushort rrtsStatus)
{
// HIINT Phase 2: Activity Check (handled before RRTS read)
// Assume ACTSW != 0 for this analysis
// HIINT Phase 3: X.21 ERROR CHECK (bits 13-14)
if ((rrtsStatus & 0x6000) != 0) // HX21M mask = 0x6000
{
bool receiverStateActive = (rrtsStatus & 0x000E) != 0; // HX21S = bits 1,2,3
if (receiverStateActive)
{
// Set BLDON flag and handle cleanly
rrtsStatus |= 0x0008; // BLDON = bit 3
}
return new HiintResult
{
Action = HiintAction.CallX21Err,
PacketProcessed = false,
DeviceActive = true // ACTSW unchanged
};
}
// HIINT Phase 4: BUFFER AVAILABILITY CHECK (bit 11) - CRITICAL
if ((rrtsStatus & 0x0800) != 0) // EMTY = bit 11
{
return new HiintResult
{
Action = HiintAction.ShutdownReceiver,
PacketProcessed = false,
DeviceActive = false, // ACTSW = 0 - FORCED DEACTIVATION
StopCount = true
};
}
// HIINT Phase 5: DATA VALIDATION (bit 0) + X.21 recheck
bool dataAvailable = (rrtsStatus & 0x0001) != 0; // DataAvailable = bit 0
bool x21ErrorRecheck = (rrtsStatus & 0x6000) != 0; // 60000 octal = 0x6000
if (!dataAvailable || x21ErrorRecheck)
{
return new HiintResult
{
Action = HiintAction.DropPacket,
PacketProcessed = false,
DeviceActive = true // ACTSW unchanged
};
}
// HIINT Phase 6: PACKET PROCESSING - Success path
return new HiintResult
{
Action = HiintAction.ProcessPacket,
PacketProcessed = true,
DeviceActive = true, // ACTSW unchanged
RestartReceiver = true // Call ZSTARC if still active
};
}
}
public enum HiintAction
{
CallX21Err, // X.21 protocol error handling
ShutdownReceiver, // ListEmpty - fatal condition
DropPacket, // Invalid data or errors
ProcessPacket // Normal packet processing
}
Entry Point and Initial State¶
Function Signature¶
SUBR HIINT % Receiver interrupt handler (Line 104436)
% Entry state: Interrupt triggered by HDLC receiver hardware
% - DMA operation completed or error condition occurred
% - Hardware has filled receive buffer or detected status change
% - Interrupt level 13 processed, CPU state saved
Detailed Execution Flowchart¶
┌─────────────────────────────────────────┐
│ HIINT ENTRY │
│ (Receiver Interrupt) │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ PHASE 1: STATUS READ │
│ T := HDEV+RRTS │
│ A := [RRTS_REGISTER] │
│ HASTA(000076) := A │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ PHASE 2: ACTIVITY CHECK │
│ IF ACTSW(000074) = 0 THEN │
└─────────────────┬───────────────────────┘
│
┌────────┴────────┐
│ ACTSW=0 │ ACTSW≠0
▼ └────────────────────────┐
┌──────────────────┐ │
│ SPURIOUS PATH │ │
│ T9 := T9-1 │ │
│ P+0 │ │
│ GO OUT1 │ │
└──────────────────┘ │
▼
┌─────────────────────────────────────────┐
│ PHASE 3: X.21 ERROR CHECK │
│ IF (HASTA & HX21M) ≠ 0 │
│ (A & 060000) ≠ 0 ? │
└─────────────────┬───────────────────────┘
│
┌─────────────┴─────────────┐
X21_OK│ X21_ERROR
(= 0) │ (≠ 0)
▼ ▼
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ PHASE 4: BUFFER │ │ X.21 ERROR HANDLER │
│ AVAILABILITY CHECK │ │ │
│ IF (HASTA & EMTY) ≠ 0 │ │ IF A BIT HX21S THEN │
│ (A & 004000) ≠ 0 ? │ │ HASTA BONE BLDON := HASTA │
└─────────────┬───────────────┘ │ FI │
│ │ CALL X21ERR │
┌──────────┴──────────┐ │ GO OUT1 │
BUFFERS│ │NO └─────────────────────────────┘
AVAIL │ │BUFFERS │
(=0) │ │(≠0) │
▼ ▼ │
┌─────────────────────────┐ ┌─────────────────────────┐ │
│ PHASE 5: DATA │ │ BUFFER EXHAUSTION │ │
│ VALIDATION CHECK │ │ │ │
│ IF A NBIT 0 OR │ │ ACTSW := 0 │ │
│ A/\60000><0 │ │ STPCNT := STPCNT + 1 │ │
└─────────────┬───────────┘ │ GO OUT1 │ │
│ └─────────────────────────┘ │
┌─────────────┴─────────────┐ │
VALID │ │ INVALID │
DATA │ │ DATA │
▼ ▼ │
┌─────────────────────────┐ ┌─────────────────────────┐ │
│ PHASE 6: PACKET │ │ DROP PACKET │ │
│ PROCESSING │ │ GO OUT1 │ │
│ │ └─────────────────────────┘ │
│ CALL PROCPKT │ │ │
│ (Process received │ │ │
│ packet data) │ │ │
└─────────────┬───────────┘ │ │
│ │ │
▼ │ │
┌─────────────────────────┐ │ │
│ PHASE 7: RESTART │ │ │
│ CHECK │ │ │
│ IF ACTSW ≠ 0 THEN │ │ │
│ CALL ZSTARC │ │ │
│ (Restart receiver) │ │ │
└─────────────┬───────────┘ │ │
│ │ │
▼ │ │
┌─────────────────────────┐ │ │
│ OUT1 EXIT │ ◄──────────────────┴───────────────────────┘
│ (All paths merge) │
│ │
│ - Status logged │
│ - Counters updated │
│ - Device state set │
│ │
└─────────────┬───────────┘
│
▼
┌─────────────────────────┐
│ RBUS │
│ (Return to System) │
└─────────────────────────┘
Step-by-Step Execution Flow with Variable Updates¶
Phase 1: Hardware Status Read¶
HIINT: T:=HDEV+RRTS; *EXR ST % IOX+10 - Read receiver transfer status
A=:HASTAT % Store raw status in HASTAT variable
Variable Updates:
- T := HDEV+RRTS (address calculation for IOX+10)
- A := [HDLC_RECEIVER_STATUS_REGISTER] (16-bit hardware status)
- HASTAT := A (global status storage for this interrupt)
Hardware Effects: - DMA status bits may be cleared by the read operation - Hardware interrupt condition is acknowledged - Status snapshot captured before any processing
Phase 2: Activity Validation Check¶
IF T:=ACTSW = 0 THEN % Device activity check
MIN T9; P+0 % Increment dummy interrupt counter
GO OUT1 % Exit immediately - spurious interrupt
FI
Variable Updates (if ACTSW = 0):
- T := ACTSW (load activity switch value)
- T9 := T9 - 1 (decrement dummy interrupt counter)
- P := P + 0 (no-op, possibly for timing)
State Transitions: - ACTIVE → SPURIOUS: Device not active, interrupt ignored - SPURIOUS → EXIT: No processing, maintain device state
Critical Logic: This prevents processing interrupts when receiver is supposed to be stopped, which could happen due to: - Hardware race conditions - Multiple interrupt sources - Cleanup timing issues
Phase 3: X.21 Protocol Error Detection¶
% PRIMARY X.21 ERROR CHECK (bits 13-14)
IF A/\ HX21M >< 0 THEN % X.21 error mask (0x6000)
IF A BIT HX21S THEN % Receiver state check (0x000E, bits 1,2,3)
HASTAT BONE BLDON=:HASTAT % Set block done flag (bit 3)
FI
CALL X21ERR % Handle X.21 protocol error
GO OUT1 % Exit - error processed
FI
Variable Updates:
- A := HASTAT & HX21M (0x6000 mask applied)
- If X.21 error detected:
- A := HASTAT (reload original status)
- If receiver active state (HX21S test):
- HASTAT := HASTAT | BLDON (set bit 3 - block done)
State Transitions: - NORMAL → X21_ERROR: X.21 protocol violation detected - X21_ERROR → TERMINATED: Frame terminated cleanly if receiver was active - X21_ERROR → ERROR_HANDLED: Error processing completed
Critical Logic: X.21 errors (bits 13-14) indicate serious protocol issues: - Bit 13 (X21D): Data indication error - Bit 14 (X21S): Call setup/clear indication error
Phase 4: Buffer Availability Check¶
% CRITICAL BUFFER CHECK (bit 11)
IF HASTA/\"EMTY" >< 0 THEN % EMpTY list check (0x0800)
0=:ACTSW % *** FORCED DEACTIVATION (1→0) *** - critical!
STPCNT+1=:STPCNT % Increment SToP CouNTer
GO OUT1 % Exit - no buffers available
FI
ACTSW Buffer Exhaustion Logic:
- A := HASTA & EMTY (0x0800 mask applied)
- If list empty (no receive buffers):
- ACTSW(000074) := 0 (FORCED DEACTIVATION 1→0)
- STPCNT := STPCNT + 1 (increment receiver stop counter)
ACTSW CRITICAL State Transition:
- Previous State: ACTSW = 1 (active, DMA reception running)
- Trigger: EMTY bit set (no receive buffers available)
- Action: ACTSW := 0 (IMMEDIATE SHUTDOWN)
- Result: Device now INACTIVE, all reception stops
ACTSW Buffer Exhaustion Impact: - FATAL CONDITION: When EMTY (bit 11) is set, ACTSW forced to 0 - All further packet reception stops until manual restart - Future interrupts become spurious (ACTSW = 0) - System-wide buffer exhaustion indication - Requires ZSTARC call to reactivate (ACTSW 0→1)
Phase 5: Data Availability and Final X.21 Validation¶
% DATA AVAILABILITY CHECK (bit 0) + REVALIDATION
IF A NBIT 0 OR A/\60000><0 THEN % No data OR X.21 error recheck
GO OUT1 % Drop packet - invalid conditions
FI
Variable Updates:
- A := HASTAT (status reloaded for checks)
- Condition evaluation:
- A NBIT 0: Test if DataAvailable (bit 0) is clear
- A /\ 60000: Apply X.21 mask (0x6000 octal = 0x3000 hex)
State Transitions: - VALID → INVALID: No data available or X.21 error - INVALID → DROPPED: Packet discarded, no processing
Critical Logic: This is the final validation: - DataAvailable (bit 0) must be set for valid packets - X.21 status (bits 13-14) must be clear for clean reception - Both conditions must pass for packet processing
Phase 6: Packet Processing (Only if all checks pass)¶
% PACKET PROCESSING - CRITICAL SECTION
CALL PROCPKT % Process received packet
% This subroutine handles:
% - DMA buffer list processing
% - Packet length validation
% - Frame check sequence verification
% - Data transfer to user buffers
% - Buffer recycling
Variable Updates (within PROCPKT): - Packet length calculations - Buffer pointer updates - Frame validation status - User data transfer operations
State Transitions: - VALIDATED → PROCESSING: Packet meets all criteria - PROCESSING → COMPLETED: Successful packet delivery - PROCESSING → ERROR: Packet validation failed
Phase 7: Circular Logging and Status Recording¶
% STATUS LOGGING (throughout interrupt processing)
% HASTAT value is logged to circular buffers for debugging:
% Buffer structure:
BUFF0(BUFSIZ) % First word in frame
BUFF1(BUFSIZ) % Device number used
BUFF2(BUFSIZ) % Device status (HASTAT value) ← CRITICAL LOGGING
BUFF3(11) % List keys when device stopped
% Status updates:
LHAST = HASTAT % Last hardware status for export
Variable Updates:
- BUFF2[buffer_index] := HASTAT (circular buffer status logging)
- BUFF1[buffer_index] := device_number (device identification)
- BUFF0[buffer_index] := frame_first_word (frame data)
- LHAST := HASTAT (exportable status value)
Phase 8: Receiver Restart (Conditional)¶
% CONTINUE RECEIVING
IF ACTSW >< 0 THEN % Still active?
CALL ZSTARC % Restart receiver DMA
% This sets up next DMA operation:
% - LIINT+DPITPHYS; T:=HDEV+WDMA; *EXR ST
% - A:=1001; T+"WDCR-WDMA"; *EXR ST
% - 1734\/MAINT/\HXDOK; T:=HDEV+WRTC; *EXR ST
FI
Variable Updates (if restarting): - DMA address registers updated - Control registers reconfigured - Activity state maintained
State Transitions: - ACTIVE → RESTARTED: Continue receiving more packets - INACTIVE → STOPPED: Device remains stopped
Phase 9: Exit Processing¶
OUT1: % Exit point for all code paths
% - Normal packet processing completion
% - Spurious interrupt dismissal
% - Error condition handling
% - Buffer exhaustion shutdown
% Hardware state at exit:
% - Interrupt acknowledged and cleared
% - DMA status captured in HASTAT
% - Device activity state updated
% - Receiver restarted if conditions permit
RBUS % Return from subroutine
Complete Variable State Table¶
| Variable | Purpose | Updated When | Value Range | Critical Impact |
|---|---|---|---|---|
| HASTAT | Hardware status storage | Every interrupt | 0x0000-0xFFFF | Core status for all decisions |
| ACTSW | Activity switch | Device start/stop | 0 (inactive) / 1 (active) | Controls all processing |
| T9 | Dummy interrupt counter | Spurious interrupts | Decremented | Diagnostic counter |
| STPCNT | Stop counter | Buffer exhaustion | Incremented | Critical resource monitoring |
| LHAST | Last hardware status | Status export | Copy of HASTAT | External visibility |
| BUFF2[] | Status log buffer | Every interrupt | Circular buffer | Historical debugging |
| T | Temporary register | Address/data ops | Various | Intermediate calculations |
| A | Accumulator | Status processing | HASTAT value | Primary working register |
State Transition Diagram¶
INTERRUPT_ENTRY
↓
READ_RRTS (HASTAT := hardware_status)
↓
CHECK_ACTIVITY
├─ ACTSW=0 → COUNT_DUMMY → EXIT
└─ ACTSW≠0 → CONTINUE
↓
CHECK_X21_ERRORS
├─ HX21M≠0 → HANDLE_X21_ERROR → EXIT
└─ HX21M=0 → CONTINUE
↓
CHECK_BUFFER_AVAILABILITY
├─ EMTY≠0 → STOP_DEVICE → INCREMENT_STPCNT → EXIT
└─ EMTY=0 → CONTINUE
↓
VALIDATE_DATA_AND_X21
├─ INVALID → DROP_PACKET → EXIT
└─ VALID → CONTINUE
↓
PROCESS_PACKET
↓
LOG_STATUS (BUFF2, LHAST)
↓
CHECK_RESTART_NEEDED
├─ ACTSW≠0 → RESTART_RECEIVER → EXIT
└─ ACTSW=0 → EXIT
Critical Failure Points and Effects¶
1. Spurious Interrupt (ACTSW=0)¶
- Effect: T9 counter decremented, immediate exit
- Impact: No data processing, diagnostic tracking
- Recovery: Manual device restart required
2. X.21 Protocol Error (bits 13-14)¶
- Effect: X21ERR subroutine called, possible frame termination
- Impact: Connection-level error handling
- Recovery: Protocol renegotiation may be required
3. Buffer Exhaustion (EMTY bit 11)¶
- Effect: Device stopped (ACTSW=0), STPCNT incremented
- Impact: All reception ceases until restart
- Recovery: Buffer allocation and manual restart
4. Invalid Data (bit 0 clear or X.21 error)¶
- Effect: Packet dropped, no processing
- Impact: Frame lost, potential retransmission needed
- Recovery: Automatic - next frame will be processed
Performance Implications¶
Fast Path (Normal Operation)¶
- RRTS read (hardware access)
- Activity check (memory compare)
- X.21 check (bit mask)
- Buffer check (bit mask)
- Data validation (bit tests)
- Packet processing (subroutine call)
- Receiver restart (DMA setup)
Approximate cycle count: 50-100 CPU cycles for status checks + PROCPKT overhead
Error Paths (Exception Handling)¶
- Spurious: ~10 cycles (minimal processing)
- X.21 Error: ~100+ cycles (error subroutine)
- Buffer Exhaustion: ~20 cycles (state update)
- Invalid Data: ~15 cycles (status checks only)
Debugging Insights¶
Key Variables to Monitor¶
- HASTAT - Shows exact hardware status received
- ACTSW - Device activity state
- STPCNT - Buffer exhaustion events
- BUFF2 circular buffer - Historical status values
- T9 - Spurious interrupt frequency
Common Failure Patterns¶
- High T9 count - Hardware generating spurious interrupts
- Increasing STPCNT - Buffer starvation condition
- X.21 error frequency - Line/protocol quality issues
- DataAvailable failures - DMA timing problems
Complete Variable Reference with Symbol Details¶
Core Variables with Exact Addresses¶
| Variable | Symbol | Address | Purpose | Read/Write | Value Range |
|---|---|---|---|---|---|
| HASTAT | HASTA | 000076 | Hardware status storage | R/W | 0x0000-0xFFFF |
| ACTSW | ACTSW | 000074 | Activity switch | R/W | 0=inactive, 1=active |
| T9 | ? | Not found | Dummy interrupt counter | W | Decremented |
| STPCNT | ? | Not found | Stop counter (buffer exhaustion) | W | Incremented |
Constants with Exact Values¶
| Constant | Symbol | Octal | Hex | Bits | Purpose |
|---|---|---|---|---|---|
| EMTY | EMTY | 004000 | 0x0800 | 11 | List Empty (No Buffers) |
| HX21M | HX21M | 060000 | 0x6000 | 13-14 | X.21 Error Mask |
| HX21S | HX21S | 000016 | 0x000E | 1,2,3 | Receiver State Check |
| BLDON | BLDON | 000010 | 0x0008 | 3 | Block Done Flag |
| ERB | ERB | 001000 | 0x0200 | 9 | Error Block Indicator |
Memory Access Patterns¶
HASTAT Usage Pattern¶
% Write Pattern (every interrupt):
T:=HDEV+RRTS; *EXR ST; A=:HASTA(000076)
% Read Patterns (decision logic):
IF A/\ HX21M >< 0 THEN % X.21 error check
IF HASTA(000076)/\"EMTY" >< 0 THEN % Buffer availability check
IF A NBIT 0 OR A/\60000><0 THEN % Data validation check
ACTSW State Management¶
% State transitions:
1 =: ACTSW(000074) % Mark active (receiver started)
0 =: ACTSW(000074) % Mark inactive (stopped/error)
% State checking:
IF T:=ACTSW(000074) = 0 THEN % Check if device should be active
Bit-Level Status Processing¶
% EMTY (List Empty) Check - CRITICAL:
IF HASTA(000076)/\"EMTY" >< 0 THEN % (status & 0x0800) != 0
0=:ACTSW(000074) % Stop receiver immediately
STPCNT+1=:STPCNT % Count buffer exhaustion events
FI
% X.21 Error Detection:
IF A/\ HX21M >< 0 THEN % (status & 0x6000) != 0
IF A BIT HX21S THEN % Check receiver state (bits 1,2,3)
HASTA BONE BLDON=:HASTA % Set block done flag (bit 3)
FI
CALL X21ERR % Handle X.21 protocol error
FI
% Data Availability Validation:
IF A NBIT 0 OR A/\60000><0 THEN % No data OR X.21 error recheck
GO OUT1 % Drop packet
FI
Critical Decision Tree¶
RRTS Read → HASTA(000076) Storage
↓
Activity Check: ACTSW(000074) = 0?
├─ YES → T9-=1, EXIT (spurious interrupt)
└─ NO → Continue
↓
X.21 Error Check: (HASTA & HX21M) != 0?
├─ YES → Handle X.21 error, EXIT
└─ NO → Continue
↓
Buffer Check: (HASTA & EMTY) != 0?
├─ YES → ACTSW=0, STPCNT++, EXIT (fatal)
└─ NO → Continue
↓
Data Valid: (HASTA & 1) != 0 AND (HASTA & 0x6000) = 0?
├─ YES → Process packet
└─ NO → Drop packet, EXIT
Performance Analysis¶
Critical Path Latency (Normal Reception)¶
- RRTS read + HASTAT store: ~6 cycles
- Activity validation: ~3 cycles
- X.21 error check: ~4 cycles
- Buffer availability check: ~4 cycles
- Data validation: ~5 cycles
- Packet processing call: Variable (major overhead)
Total status validation: ~22 CPU cycles before packet processing
Error Path Latencies¶
- Spurious interrupt: ~8 cycles (T9 decrement + exit)
- X.21 error: ~15 cycles (state check + subroutine call)
- Buffer exhaustion: ~10 cycles (ACTSW + STPCNT updates)
- Invalid data: ~7 cycles (bit tests + exit)
Debugging Strategy¶
Status Monitoring Sequence¶
% Key diagnostic values to log:
1. HASTA(000076) - Raw hardware status
2. (HASTA & HX21M) - X.21 error bits (13-14)
3. (HASTA & EMTY) - Buffer availability (bit 11)
4. (HASTA & 1) - Data available (bit 0)
5. ACTSW(000074) - Device activity state
6. T9, STPCNT - Error frequency counters
Common Failure Signatures¶
- T9 increasing: Hardware interrupt timing issues
- STPCNT increasing: System memory/buffer problems
- ACTSW stuck at 0: Device not restarting after errors
- HASTA bit patterns: Specific hardware conditions
The HIINT handler demonstrates sophisticated real-time interrupt processing with comprehensive error handling and state management, making it a critical component for reliable HDLC communication.