Skip to content

TAD (Terminal Access Device) Protocol Analysis

Overview

This document analyzes SINTRAN III's TAD protocol implementation for X.25 network communication. TAD enables terminal access over X.25 networks, allowing remote terminals to connect to SINTRAN systems.

Source Files: - MP-P2-TAD.NPL (989 lines) - TAD driver with XMSG interface and interrupt handling - RP-P2-TAD.NPL (1480 lines) - TAD protocol routines with message creation/processing


Message Types

Core Message Type Constants

Defined in MP-P2-TAD.NPL:328-338:

Symbol Octal Code Hex Message Type Purpose
EBUFF 7DUMM 0x7D554D Empty Buffer/Dummy Padding or empty message
BDESC 7ESCA 0x7E5343 Escape Escape character received
RLOCA 7RLOC 0x7D4C4F Remote Local Remote/local mode switch (NORD-NET)
BDDIS 7DCON 0x7D434F Disconnect TAD disconnection request
CESCR 7CERS 0x7D455253 CESC Response Escape response
RESCF 7RECO 0x7D45434F Reset Confirm Reset confirmation
NWREM 7NWRE 0x7D5752 Nowait Restart Restart nowait mode
ISZRS 7ISRS\2 0x7D495253 ISIZE Response Buffer size response (2 bytes data)
ERRSP 7ERRS\2 0x7D455252 Error Response Error code response (2 bytes data)
TREPS 7TREP\2 0x7D545245 TREP Status Transmission status (2 bytes data)

Additional Message Types

Found in RP-P2-TAD.NPL:

Symbol Octal Code Message Type Purpose Data Size
7BDAT 7BDAT Data Message User data transmission Variable
7TMOD 7TMOD Terminal Mode Terminal mode settings 1 byte
7TTYP 7TTYP Terminal Type Terminal type code 2 bytes
7DESC 7DESC Define Escape Set escape character 1 byte
78MOD 78MOD 8-bit Mode Enable 8-bit UMOD 2 bytes
7OPSV 7OPSV OPSYS Version OS version and protocol 3 bytes
7REJE 7REJE Reject Reject invalid message 1 byte (rejected type)
7RFI 7RFI Ready For Input Request more input data 0 bytes
7RESE 7RESE Reset Reset connection 0 bytes
7BMMX 7BMMX Break Message Break strategy 3 or 23 bytes
7ECKM 7ECKM Echo Message Echo strategy 1 or 21 bytes
7SYCN 7SYCN System Control System control command 2 bytes
7USCN 7USCN User Control User control command 2 bytes
7CPCO 7CPCO Completion Code Operation completion 4 bytes
7NOWT 7NOWT Nowait Status Nowait operation status 1 byte
7TNOW 7TNOW Terminate Nowait End nowait mode 1 byte
7ISRQ 7ISRQ ISIZE Request Query buffer size 0 bytes
7UMOD 7UMOD UMOD Strategy User mode strategy 2 bytes

Message Format Structure

General Message Format

+-------------------+-------------------+-------------------+
| Message Type      | Byte Count        | Data Field        |
| (1 byte)          | (1 byte)          | (0-255 bytes)     |
+-------------------+-------------------+-------------------+

Alignment Rules: - Messages can start on even or odd byte boundaries - If message starts on odd byte, a pad byte (0x00) is inserted first - Byte count includes only the data field, not the header

Message Header Creation

Source: RP-P2-TAD.NPL:162-178 (WRMHEAD)

WRMHEAD: A=:D; T:=TDTAFI; X:=TDTALA
         IF TDBTPT BIT "0" THEN                    % ODD START, CREATE PAD BYTE
            A SHZ -1; X+A; *LDATX
            A/\177400; *STATX
            MIN TDBTPT; REMSIZ-1=:REMSIZ
         FI
         X:=TDTALA
         TDBTPT SHZ -1; X+A; D=:A; *STATX          % WRITE IN BUFFER
         TDBTPT+2=:TDBTPT; REMSIZ-2=:REMSIZ
         EXIT

Message Parsing

Source: RP-P2-TAD.NPL:224-242 (GETMES)

GETMES: IF BUFFID=0 THEN A:=1; EXIT FI             % NO BUFFER
TSTSP:  IF REMSIZ<2 THEN T=:A; EXIT FI
        T:=TDTAFI; X:=TDTALA; TDBTPT=:D SHZ -1
        X+A; *LDATX
        MIN TDBTPT
        IF D BIT "0" THEN                          % ODD BYTE
           IF A/\377=0 THEN REMSIZ-1=:REMSIZ; GO TSTSP FI  % PAD BYTE
           A=:CURMES; X+1; *LDATX
           A SHZ -10; MIN TDBTPT; GO RCHK
        FI
        A=:T SHZ -10
        IF A=0 THEN
           REMSIZ-1=:REMSIZ; GO TSTSP              % PAD BYTE
        FI
        A=:CURMES:=T/\377; MIN TDBTPT
RCHK:   IF A>REMSIZ-2 THEN A:=3; EXIT FI           % INCONSISTENT MESSAGE
        A=:T+1-=:REMBYT; X:=REMSIZ-2=:REMSIZ
        A:=CURMES; EXITA                           % MESSAGE FOUND

Returns: - Skip return (EXITA): Message found - A-REG = Message type - T-REG = Number of bytes in data field - CURMES = Message type - REMBYT = Bytes remaining in message - Error returns: - A=1: No input buffer - A=2: Buffer empty - A=3: Inconsistent message (bigger than buffer)


TAD Driver Entry Points

Main Entry Points

Source: MP-P2-TAD.NPL:363-367

Entry Point Line Purpose Called From
INIBDR 382 Initialize TAD connection TADADM (connection phase)
INISND 398 Send initial buffer TADADM (after INIBDR)
BDRINP 439 Input driver (receive) XMSG when buffer queued
TDRINP 440 Input driver entry (internal) BDRINP, BDROUT
BDROUT 800 Output driver (transmit) Output monitor calls
BERESP 638 Send escape response Escape handling
STOTAD 660 Stop TAD connection User logout/disconnect
DSTOTA 661 Disconnect TAD (internal) STOTAD, FAERR
BDLOUT 695 Logout TAD user STOTAD when TLREP disabled
BDDSCN 713 Disconnect without logout Explicit disconnect request
TDDSCN 714 Disconnect (internal) BDDSCN, DSTOTA
BDRWT 847 Leave driver level All driver routines
BMAIRES 741 Reserve mail buffer Mail system (TWMESS)
MSNDBUF 769 Send mail buffer Mail timeout routine
MRELBUF 789 Release mail buffer Mail timeout (partner not responding)
FAERR 843 Fatal error handler Error conditions

RPIT Entry Points

Source: RP-P2-TAD.NPL

Entry Point Line Purpose Context
PUTPOOL 20 Return buffer to free pool IOF (interrupt off)
GETPOOL 44 Get buffer from free pool IOF (interrupt off)
MOVITO 63 Move input buffer to output Buffer relocation
SNDBUF 87 Send output buffer Output operations
SNDWT 84 Send and wait for response Operations requiring response
CBRERSP 106 Send escape response callback Escape handling
BDTOU 121 Normal output timeout Timeout timer
MTDTOU 135 Mail output timeout Mail system timeout
WRMHEAD 168 Write message header Message creation
CREMES 198 Create message Output operations
CRHEEV 263 Create header (even byte) Complete messages
CRHEOD 293 Create header (odd byte) Complete messages
UPDMBC 315 Update message byte count Byte operations
GETMBC 343 Get message byte count Query operations
BYTPUT 365 Put byte in buffer Output operations
WORDPUT 398 Put word in buffer Output operations
BYTGET 431 Get byte from buffer Input operations
LOADBYT 452 Load byte (no buffer update) Scanning operations
STORBYT 469 Store byte in buffer Output operations
GETMES 224 Get next message Input processing
REDOM 495 Redo monitor call Buffer wait conditions
IEDCHK 514 Check delayed escape Input validation
CNVERR 536 Convert XMSG error Error handling

Data Structure Fields

TAD Input Datafield

Field Purpose Type
BUFFID Current input buffer ID INTEGER
TDTADD Buffer address (TDTAFI:TDTALA) TRIPLE
TDTAFI Buffer address (file index) INTEGER
TDTALA Buffer address (local address) INTEGER
TDBTPT Byte pointer in buffer INTEGER
REMSIZ Remaining size in buffer INTEGER
CURMES Current message type INTEGER
REMBYT Remaining bytes in message INTEGER
PORTNO XMSG port number INTEGER
PARTNER Partner port number TRIPLE
RPORT Remote port number INTEGER
DFLAG Datafield flags INTEGER
FLAGB Additional flags INTEGER
TINFO Terminal information INTEGER
CESCP Escape character INTEGER
CTTYP Terminal type INTEGER
FBSIZ Frame buffer size INTEGER
NOBUFF Number of buffers INTEGER
LAST Last character processed INTEGER
DERROR Error code INTEGER
BRECST Break/echo strategy INTEGER
OSVTPN OS version + TAD protocol INTEGER
TDRADDR TAD resident datafield address ADDRESS
ISTATE Input state (0=normal, <0=nowait) INTEGER

TAD Output Datafield

All input fields plus:

Field Purpose Type
POOLLI Free buffer pool list TRIPLE
BUDIS Buffer displacement INTEGER
NOBDIS Message start displacement INTEGER
RSPNUM Response number waiting INTEGER
CURBRST Current break strategy INTEGER
CURECST Current echo strategy INTEGER
SCREEN Screen/page control INTEGER
MBFID Mail buffer ID INTEGER
BRCOUNT Buffer rotate count INTEGER

Critical Flag Bits

DFLAG bits: | Bit | Name | Purpose | |-----|------|---------| | 5CAPITAL | Capital letters mode | Convert to uppercase | | 5IESC | Escape disabled | Escape processing disabled | | 5RQI | RFI sent | Ready-for-input message sent | | 5WRQI | Wait RFI | Waiting to send RFI |

FLAGB bits: | Bit | Name | Purpose | |-----|------|---------| | 5LBLOG | Logout on carrier loss | Auto-logout on disconnect | | 5LSTA | Line status | Line active/dead | | 5LOGOUT | Logout pending | User logout requested | | 5TLREP | Terminal reply | Wait for terminal response | | 5LCHAR | Local character | Local character mode | | 5ESCLOFF | Escape delayed | Delayed escape action | | 5WESC | Wait escape | Escape waiting | | 5WLOC | Wait local | Local mode waiting |

TINFO bits: | Bit | Name | Purpose | |-----|------|---------| | 5CRDLY | CR delay | Carriage return delay | | 58BIT | 8-bit mode | Allow 8-bit characters | | 5UMOD | User mode | User mode active | | 5BFUL | Buffer overrun | Buffer overflow occurred | | 5PAER | Parity error | Parity error detected | | 5FRER | Framing error | Framing error detected |


TAD Connection Lifecycle

1. Connection Establishment

Sequence: INIBDR → INISND → BDRINP

Phase 1: Initialize Connection (INIBDR - Line 382)

INIBDR: CALL STADIWINDOW                           % SET WINDOW
        IF PORTNO=0 THEN                           % NO PORT OPENED
          0=:TDRADDR.BXTADD; T:=XFOPN; CALL MXMSG  % OPEN XMSG PORT
          A=:PORTNO                                % SET PORTNO IN DATAFIELD
          A:=0=:D; AD=:OTAD.POOLLI                 % POOL EMPTY
          T:=XFALM; FBSIZ; X:=NOBUFF; CALL MXMSG   % ALLOCATE MESSAGE SPACE
          FOR X:=1 TO NOBUFF DO
             T:=XFGET; A:=FBSIZ; CALL MXMSG        % RESERVE BUFFERS
             % ... add to pool ...
          OD
        FI
        GO BDRWT

Operations: 1. Open XMSG port (XFOPN) 2. Allocate message space (XFALM) 3. Reserve NOBUFF buffers of size FBSIZ 4. Build free buffer pool (POOLLI)

Phase 2: Send Initial Buffer (INISND - Line 398)

INISND: CALL STADIWINDOW
        OTAD=:B; CALL MGETPOOL                     % GET BUFFER FROM POOL
        T:=ITAD=:B; T:=PORTNO=:D
        T:=XFSCM; CALL MXMSG                       % SET CURRENT BUFFER
        TAD:=DMMES; T=:X:=XFWHD; CALL MXMSG        % WRITE DUMMY MESSAGE
        AD:=OTAD.PARTNER; X:=PORTNO
        T:=XFSND; CALL MXMSG                       % SEND BUFFER
        T:=XFDBK; A:=DPITBANK; CALL MXMSG          % SET BANK FOR R/W
        T:=XFWDF; A:="BDRINP"; CALL MXMSG          % SET WAKE-UP MODE
        FLAGB BZERO 5LSTA=:FLAGB                   % SET LINE OK BIT
        GO TDRINP                                  % ENTER RECEIVE MODE

Operations: 1. Get buffer from free pool 2. Set current buffer (XFSCM) 3. Write dummy message header 4. Send initial buffer to partner (XFSND) 5. Configure XMSG wake-up for BDRINP 6. Enter receive mode

2. Data Transfer

Sending Data

Entry: BDPUT (Line 1217) or BM8OUT/BB8OUT (Line 1307)

Flow:

User Data → BDPUT → BYTPUT → CREMES (if needed) → Buffer → SNDBUF → XMSG

Key Steps: 1. Check if current message is data message (7BDAT) 2. If not, create new data message (CREMES) 3. Add bytes to buffer (BYTPUT) 4. If buffer full or timeout, send buffer (SNDBUF)

Receiving Data

Entry: BDGET (Line 1257) or BB4INW/BB8INP (Line 1354, 1419)

Flow:

XMSG → BDRINP → GETMES → BYTGET → User Data

Key Steps: 1. Driver receives buffer from XMSG 2. Parse messages with GETMES 3. If data message (7BDAT), extract bytes 4. If buffer empty, send RFI (SNDRFI)

3. Disconnection

Graceful Disconnect (BDDSCN - Line 713)

BDDSCN: CALL STADIWINDOW
TDDSCN: FLAGB BONE 5LSTA=:FLAGB                    % SET LINE DEAD BIT
        IF PORTNO><0 AND TDRADDR.BXTADD><0 THEN
          IF TMPBUF><0 THEN
             0=:TMPBUF; T:=XFREL; CALL MXMSG       % RELEASE CURRENT BUFFER
          FI
          0=:PORTNO=:BUFFID=:OTAD.BUFFID           % CLEAR DATAFIELD
          TDRADDR=:B; BXTADD=:L; 0=:BXTADD
          T:=XFDCT; *MON 2XMSG                     % DISCONNECT PORT
        FI

Operations: 1. Set line dead flag (5LSTA) 2. Release current buffer if any 3. Clear all buffer IDs 4. Disconnect XMSG port (XFDCT)

Forced Disconnect with Logout (STOTAD - Line 660)

STOTAD: CALL STADIWINDOW
        IF DBPROG><0 THEN
          IF DBPROG=TDRADDR.RTRES AND FLAGB NBIT 5LOGOUT THEN
             IF FLAGB BIT 5TLREP THEN
                A BONE 5LOGOUT=:FLAGB              % MARK LOGOUT
                "IORESTART"; CALL CXRTACT          % RESTART PROGRAM
             ELSE
                CALL BDLOUT                        % LOGOUT USER
             FI
          FI
        FI
        GO TDDSCN                                  % DISCONNECT

Example Message Sequences

Connection Establishment

Local TAD                    Remote TAD
    |                            |
    |------ XFOPN (open) ------->|
    |<----- Port Allocated ------|
    |                            |
    |------ XFALM (alloc) ------>|
    |<----- Space Reserved ------|
    |                            |
    |------ DUMMY Message ------>|
    |                            |
    |<----- 7TMOD (mode) --------|
    |<----- 7TTYP (type) --------|
    |<----- 7DESC (escape) ------|
    |                            |
    |------ Ready ------------->|

Data Transfer

Terminal                     TAD                      Remote TAD
    |                         |                            |
    |--- User types "ABC" --->|                            |
    |                         |                            |
    |                         |--- 7BDAT [ABC] ----------->|
    |                         |                            |
    |                         |<-- 7RFI (ready) -----------|
    |                         |                            |
    |                         |<-- 7BDAT [response] -------|
    |                         |                            |
    |<-- Display response ----|                            |

Break Handling

Terminal                     TAD                      Remote TAD
    |                         |                            |
    |--- Break key pressed -->|                            |
    |                         |                            |
    |                         |--- 7BMMX [strategy] ------>|
    |                         |                            |
    |                         |<-- 7ECKM [echo] -----------|
    |                         |                            |
    |<-- Echo response -------|                            |

Disconnection

Terminal                     TAD                      Remote TAD
    |                         |                            |
    |--- Logout command ----->|                            |
    |                         |                            |
    |                         |--- 7DCON (disconnect) ---->|
    |                         |                            |
    |                         |--- XFREL (release) ------->|
    |                         |--- XFDCT (disconnect) ---->|
    |                         |                            |
    |<-- Connection closed ---|                            |

Error Recovery

Local TAD                    Remote TAD
    |                            |
    |------ Invalid Message ---->|
    |                            |
    |<----- 7REJE (reject) ------|
    |                            |
    |------ 7RFI (request) ----->|
    |                            |
    |<----- 7BDAT (data) --------|

Continue in Part 2...

This document continues in TAD-Protocol-Analysis-Part2.md with: - Detailed message format for each message type - XMSG integration details - State machine diagrams - C# emulator implementation guide