*DECK,NP$N2D
*IF,DEF,XFR 
          IDENT     NP$N2D
          ENTRY     NP$N2D
NP$N2D    BSS       1 
* 
*         THIS TRANSLATION ROUTINE TAKES ONE CHARACTER AT A TIME
*         FROM THE NETWORK BUFFER, AND CONVERTS IT TO DISPLAY CODE
*         IN THE DISK BUFFER. 
* 
*         ENTRY PARAMETERS :  
*         - ADDRESS OF NETWORK FET
*         - ADDRESS OF DISK BUFFER FET
*         - ADDRESS OF CONVERTION TABLE PARAMETER BLOCK.
* 
*         THE STRUCTURE OF THE PARAMETER BLOCK IS : 
*         +------------------+
*     1   1 NBUF EMPTY FLAG  1
*         + -----------------+
*     2   1 DISKBUF FULL FLAG1
*         +------------------+
*     3   1 NCOUNT           1 NO. OF REMAINING CHARS. IN NET BUFFER
*         +------------------+
*     4   1 NBYTE            1
*         +------------------+
*     5   1 DBIT             1
*         +------------------+
*     6   1 STATE OF CONVER. 1
*         +------------------+
*     7   1 CONVER. TBL ADDR.1
*         +------------------+
*     8   1  STEPSIZE (6/12) 1
*         +------------------+
* 
*     NBYTE - NUMBER OF BITS TO SHIFT CURRENT NETWORK WORD TO GET 
*             CURRENT CHARACTER AT RIGHT MOST LOCATION. 
*             COUNTS FROM 8 (12 IF WORD BEGINS WITH HALF CHARACTER) 
*             STEP 8 UNTIL 64 (60)
*     DBIT  - NUMBER OF BITS TO SHIFT A CHARACTER FROM RIGHTMOST
*             LOCATION TO CURRENT REQUIRED IN DISKBUF.
*             FOR DISPLAY CODE FILES : STARTS WITH 54 STEP -6 UNTIL 0 
*                 DISK ASCII FILES   : STARTS WITH 48 STEP -12 TILL 0 
*     STATE - 0 = ALL DONE IN PREVIOUS ENTRY. 
*             1 = ZERO WORD REQUIRED
*             2 = LAST CHARACTER WRITTEN WAS (:) (SO THAT IF A *US* 
*                 ARRIVES WE FIRST WRITE A BLANK, THAN A Z-BYTE)
* 
* 
*         THE PRESETTING INCLUDES : 
* 
*         A1 - ADDRESS OF NET FET+1  (*IN* POINTER) 
*         A2 - ADDRESS OF DISK FET+1 (*IN* POINTER) 
*         A4 - POINTER TO DISK BUFFER  *IN* WORD. 
*         A5 - POINTER TO NET BUFFER  *OUT* WORD. 
* 
*         X4 - ACCUMULATING THE WORD TO BE WRITTEN TO DISKBUF 
*         X5 - CURRENT NETBUF WORD POINTED BY *OUT* (WORKING WORD)
* 
*         B1 - 1
*         B2 - ADDRESS OF FIRST ENTRY IN CONVERSION TABLE 
*         B3 - STATE OF CONVERSION
*         B4 - DBIT 
*         B5 - NBYTE
*         B6 - COUNT
* 
          SB1       1 
  
          SA2       A1+B1 
          SA3       A2+B1 
* 
*         THE PARAMETERS PASSED ARE WORDS CONTAINING THE  A D D R E S S 
*         OF THE REQUIRED PARAMETERS (FETS,PARAMETER-BLOCK) 
* 
          SA1       X1        GET POINTER TO ACTUAL PARAMETER 
          SA2       X2
          SA3       X3
  
          SA1       X1+B1     POINT TO NFET WORD CONTAINING *IN*
          SA5       A1+B1              NFET WORD CONTAINING *OUT* 
          SA5       X5        ADDRESS OF *OUT* OURD IN NETBUF 
          SA2       X2+B1     POINT TO DFET WORD CONTAINING *IN*
          SA4       X2        ADDRESS OF *IN* WORD OF DISK BUF
          BX6       X3        SAVE PARAM TABLE ADDRESS
          SA6       PARAM 
          MX6       0 
  
          SA6       X3        SET TO 'NETBUF AVAILABLE' INITIAL STATE 
          SA3       X3+B1     GET THE 'DISKFULL' INDICATOR
          SA6       A3        SET TO 'DISK AVAILABLE' INITIAL STATE 
  
          SA3       A3+B1     WORD NUMBER 3 IN TABLE
          SB6       X3        NCOUNT
  
          SA3       A3+B1     WORD NUMBER 4 IN TABLE
          SB5       X3        NBYTE 
  
          SA3       A3+B1 
          SB4       X3        DBIT (WORD 5 )
  
          SA3       A3+B1     STATE INTO X3 FROM WORD 6 
          SB3       X3        B3=1 IS Z-WORD REQUIRED 
*                             B3=2 IS LAST CHAR IN NETBUF WAS : 
* 
          SA6       A3        RESET THE STATE IN PARAMETER BLOCK
          SA3       A3+B1     WORD 7 - CONVERSION TABLE ADDRESS 
          SB2       X3
  
          SA3       A3+B1     WORD 8 = STEP SIZE IN DISKBUF (6 OR 12) 
          BX6       X3
          SA6       STEP
  
*         COMPARE *OUT* AND *FIRST* TO SEE IF IT IS FIRST TIME ENTRY
  
          SA3       A1-B1     POINT AT FET WORD CONTAINING *FIRST*
          SB7       X3        *FIRST* ADDRESS IN B7 
          SB7       A5-B7     *NETBUF *OUT* - *FIRST* 
          NE        B0,B7,READBLK0
* 
*         YES,IT IS FIRST TIME ENTRY. FIRST BLOCK HAS A TBH(6 OCTETS) 
* 
          MX0       48
          BX5       -X0*X5
          SB6       X5        NUMBER OF CHARS FROM ABH
          SB6       B6-6      DECREMENT THE NBH SIZE
          SB5       56
          SA5       A5+B1     MOVE *OUT* TO FIRST WORD OF DATA
  
READBLK0  BSS       0 
******* 
* 
*         CHECK IF WE STILL HAVE ROOM IN *DISKBUF* SO THAT WE CAN GO
*         ON WITH THE PROCESS.
*         1. CHECK IF *B4* SHOWS NEW CHARACTER IN WORD. 
*         2. CHECK IF *IN+1* = *OUT*. 
* 
*           IF  B O T H CONDITIONS OCCUR THAN WE USED ALL DISK SPACE WE 
*           COULD, WE FLAG THE *DISKFULL* AND QUIT. 
********
  
          SX0       A4+B1     *IN+1*     (X0) 
          SA3       A2+B1     POINT TO DFET CONTAINING *OUT* POINTER
          MX6       42
          BX0       -X6*X0
          BX7       -X6*X3    ADDRESS OF DISKBUF *OUT* WORD  (X7) 
          SA3       A3+B1     POINT TO DFET CONTAINING *LIMIT* POINTER
          BX3       -X6*X3    ADDRESS OF DISKBUF *LIMIT* POINTER  (X3)
          BX3       X0-X3     DISKBUF *IN+1* - *LIMIT*
          NZ        X3,ENDW2  SKIP THE FOLLOWING IF *IN+1*.NE.*LIMIT* 
          SA3       A2-B1     POINT TO DFET WORD CONTAINING *FIRST* 
          BX0       -X6*X3    ADDRESS OF *FIRST* REPLACES *IN+1*
  
ENDW2     BX6       X0-X7     CHECK IF *IN+1* = *OUT* 
  
*      NEW *IN+1* ADDRESS NOW IN X0 
  
          BX7       X0
          SA7       NEXTIN    SAVE FOR NEXT WORD ADVANCE
  
          SA3       STEP
          SB7       X3
          SB7       B7-60     SETTING FOR FIRST CHARACTER IN DISK WRITE 
          SB7       B0-B7 
          NE        B4,B7,ENTER1        IF NOT 1ST CHARACTER OF A WORD
  
          NZ        X6,ENTER1   IF *IN+1* .NE. *OUT*
  
*         DISK FULL, SO WE CAN NOT GO TO NEXT WORD FOR WRITE
  
DISKFUL   SX6       1 
          SA3       PARAM 
          SA6       X3+B1   SET FLAG OF *DISK BUFFER FULL* (WORD 2) 
          MX6       0 
          SA6       A4        CLEAN WORD WE HAD NO CHANCE TO WRITE
          EQ        NEXIT 
* 
**********
  
* 
*         IF COUNT=0 READ NEXT BLOCK (OR RETURN IF LAST BLOCK)
* 
ENTER1    BSS       0 
* 
*         CHECK FOR SPECIAL ENTRIES : 
*         B3 = 1  - A ZERO WORD IS REQUIRED IN *DISKBUF*
*         B3 = 2  - LAST CHARACTER IN *DISKBUF* WAS A COLON (:) 
* 
          EQ        B3,B1,ZRBYT1        TO WRITE A ZERO WORD
  
READBLK   NE        B6,B0,NEXT
          SB7       X1        NETBUF *IN* ADDRESS 
          SX6       A5-B7     NETBUF *OUT* - *IN* 
          NZ        X6,NEXT2
  
*         *IN* = *OUT* - NETWORK BUFFER EMPTIED.
  
          SA3       PARAM 
          SX6       1         SET FLAG 'NETWORK BUFFER EMPTY' 
          SA6       X3        ADDRESS ON FLAG LOCATION
  
          BX7       X4
          SA7       A4        FLUSH OUT LAST CHARACTERS ACCUMULATED 
          EQ        NEXIT 
  
*         ANOTHER BLOCK EXISTS IN NETBUF (BLK OR MSG) 
  
NEXT2     SA5       A5+B1     ADVANCE THE POINTER TO NETBUF *OUT* WORD
          MX0       48
          BX5       -X0*X5    EXTRAXT TLC FROM BIT 48 THR 59
          SB6       X5        GET COUNT FROM TLC OF ABH 
          SA5       A5+B1     POINT TO FIRST WORD OF DATA AREA
          SB5       8         SET TO 1ST CHARACTER IN WORD
* 
*********** 
  
*         GET THE NEXT CHARACTER TO BE TRANSLATED 
  
NEXT      SB7       64
          NE        B5,B7,REGBYTE       IF NBYTE.NE.64 GO TO REGBYTE
* 
*         WE HAVE A BYTE SPLIT BETWEEN TWO WORDS (NBYTE = 64) 
* 
          MX0       56
          BX3       -X0*X5    SAVE RIGHTMOST 4 BITS (BIT 7 FORCED TO 0) 
          LX3       4         AND PUT THEM IN BITS 4-7
          SA5       A5+B1     ADVANCE TO NEXT WORD FOR 2ND HALF 
* 
*         NOW COMBINE WITH PREVIOUS 4 BITS
* 
          MX0       4 
          BX6       X5*X0 
          LX6       4         TO MOVE THEM FROM LEFT TO RIGHT 
          BX7       X3+X6     COMBINE AND REMEMBER IN  *X7* 
          SB5       12        START COUNTING FROM 12 (NOT 8)
          EQ        TBLENT
* 
*         REGULAR ASCII BYTE (ALL IN THE SAME WORD) 
* 
REGBYTE   LX3       B5,X5     GET ASCII CHAR TO RIGHTMOST BYTE
          MX0       52        KEEP LEFTMOST PARITY BIT
          BX7       -X0*X3    CHAR MASKED AT RIGHTMOST BITS OF *X7* 
          SB5       B5+8      GET READY FOR NEXT BYTE 
* 
*         IF NBYTE BECAME 68 RESET AND MOVE TO NEXT WORD OF NETBUF
* 
          SB7       B5-68 
          LT        B7,B0,TBLENT
***** 
*         WE ARE AT THE LAST CHARACTER IN THE WORD
* 
          SB7       X1        NETBUF *IN* WORD ADDRESS
          SB7       A5-B7     NETBUF *OUT* - *IN* 
  
          EQ        B7,B0,TBLENT  GO TO TBLENT IF NETBUF EMPTY(IN=OUT)
* 
*         NOT END OF BUFFER YET. GET NEXT WORD AND POSITION READY 
* 
          SA5       A5+B1 
          SB5       8 
***** 
*         GET CHAR USING OFFSET OF CHARACTER STORED IN X7 PREVIOUSLY
* 
TBLENT    SB6       B6-B1     DECREMENT CHARACTER COUNTER 
          SA3       STEP
          SX3       X3-6
          ZR        X3,TBLENT1          8/8 TO DISPLAY CODE (6) CONV. 
* 
*         ASCII (12 BITS) CONVERSION. 
* 
          SB7       X7-37B    37B IS ASCII *UNIT SEPARATOR* 
          EQ        B0,B7,ZRBYT 
* 
*         ONLY SPECIAL CASING IS NULL THAT GOES FROM 0000 TO 4000 
* 
          NZ        X7,NORM 
          MX7       1 
          LX7       12        X7 = 4000B
          EQ        NORM
  
TBLENT1   SA3       X7+B2     CONV. TBL. ADDR. + THE OFFSET FOUND 
  
          MX0       12
          BX6       X3*X0     FUNCTION INTO X6
          MX0       48
          BX7       -X0*X3    VALUE OF DISPLAY CODE/ASCII12  INTO X7
  
          NG        X6,SPECIAL
  
          SB3       B0        CLEAR POSSIBLE 'COLON READ' INDICATOR 
NORM      LX7       B4        SHIFT VALUE TO CURRENT LOCATION 
          BX4       X7+X4     ADD NEW CHARACTER 
  
          EQ        B0,B4,ENDW
  
*         NOT E-O-L YET. JUST GET NEXT LOCATION 
  
          SA3       STEP
          SB7       X3        STEP 6 OR 12 DEPENDING ON TRANSLATION MOD 
          SB4       B4-B7 
          EQ        READBLK   FOR NEXT CHARACTER FROM NETWORK 
  
ENDW      BX7       X4
          SA7       A4        STORE WORD JUST COMPOSED INTO DISKBUF 
          SA4       NEXTIN
          SA4       X4        ADVANCE FOR NEXT WORD TO USE
          MX4       0         PRESET FOR NEXT ACCUMULATION
* 
*         SET *B4* TO THE FIRST CHARACTER SHIFT AMOUNT FOR NEXT WORD
* 
          SA3       STEP
          SB7       X3
          SB4       60
          SB4       B4-B7     STEP 6 OR 12 DEPENDING ON TRANSLATION MOD 
          EQ        READBLK0
* 
*         SPECIAL CASES SECTION 
* 
SPECIAL   MX0       1 
          BX3       -X0*X6    CLEAR LEFTMOST BIT OF FUNCTION (X'800') 
          NZ        X3,SP1
*                             CODE = '800' JUST DELETE CHARACTER
          SB3       B0        CLEAR THE 'COLON READ' INDICATOR
          EQ        READBLK   GET NEXT CHARACTER
  
SP1       LX3       11        X'001'
          BX3       -X0*X3
          NZ        X3,COLON  ONLY POSSIBILITY LEFT (X'803')
  
*---------- CODE IS X'801' = Z-BYTE  -----------------
  
ZRBYT     SB7       B1+B1 
          NE        B3,B7,ZRBYT1        IF LAST CHAR WAS NOT COLON
          SX7       55B       LAST CHAR COLON. SUFFIX A BLANK CHAR
          LX7       B4        MOVE TO CURRENT REQUESTED LOCATION
          BX4       X7+X4     INSERT INTO WORKING OUTPUT REGISTER.
  
          SA3       STEP
          SB7       X3        STEP 6 OR 12 DEPENDING ON TRANSLATION MOD 
  
          SB4       B4-B7     GET READY FOR NEXT LOCATION 
  
ZRBYT1    SB3       B0        CLEAR POSSIBLE 'LAST CHAR WAS COLON'
  
          SA3       STEP
          SX3       X3-12     TO CHECK IF ASCII MOD 
  
          ZR        X3,ENDW   ONLY ONE ASCII CHAR WILL DO AS A Z-BYTE 
          GE        B4,B1,ENDW          OR AT LEAST 2 DISPLAY CODE
  
          SB3       1         SIGNAL ANOTHER ZERO WORD IS REQUIRED
  
          EQ        ENDW
COLON     SB3       B1+B1     RECORD INTERNALLY THE EVENT 
          EQ        NORM      GO INSERT CHARACTER 
* 
*         STORE VARIABLES IN TABLES AND RETURN
* 
NEXIT     SA3       PARAM     RESERVE VARIABLES IN TABLE
          SX6       B6
          SA6       X3+2      SAVE NCOUNT ( WORD 3 OF PARAM TABLE)
          SX6       B5
          SA6       A6+B1     SAVE NBYTE (IN WORD 4)
          SX6       B4
          SA6       A6+B1     SAVE DBIT (IN WORD 5) 
  
          SX6       B3        RECORD THE STATE OF DISKBUF 
          SA6       A6+B1     STORE IN WORD 6 OF PARAMETER BLOCK
* 
*         SAVE A4 (*IN* POINTER OF DISKBUF) BACK IN FET 
* 
NEXIT2    MX0       42
          SA2       A2        ADDRESS OF DFET WORD WITH *IN* POINTER
          BX2       X2*X0     MASK OUT OLD POINTER
          MX3       0 
          SX3       A4        NEW *IN* ADDRESS
          BX7       X2+X3     INSERT ADDRESS TO WORD
          SA7       A2        WRITE BACK
* 
*         SAVE A5 (*OUT* POINTER OF NETBUF) BACK INTO FET 
* 
          SA3       A1+B1     NFET WORD CONTAINING *OUT*
          BX3       X3*X0     MASK OUT OLD ADDRESS
          MX2       0 
          SX2       A5        NEW ADDRESS 
          BX6       X2+X3     INSERT NEW ADDRESS TO WORD
          SA6       A3        WRITE BACK
  
          EQ        NP$N2D
  
PARAM     BSSZ      1 
STEP      BSSZ      1 
NEXTIN    BSSZ      1 
          END 
*ENDIF
