*DECK XDRBYTE 
USETEXT TEXTXDR 
      PROC XDRBYTE (BUFFER, BUFPOS, BYTEARR, BYTELEN, OPERATION); 
*CALL COPYRITE          CDCNET - COPYRIGHT CONTROL DATA. 1992.
# TITLE XDRBYTE  CONVERT BETWEEN BYTES AND EXT DATA REPRESENTATION     #
  
      BEGIN                            # XDRBYTE                       #
# 
****  XDRBYTE - CONVERT BETWEEN BYTES AND EXT DATA REPRESENTATION 
* 
*     THIS PROCEDURE WILL READ DATA OUT OF *BUFFER*, OR WRITE DATA INTO 
*     *BUFFER* DEPENDING ON THE *OPERATION* PARAMETER.  THE DATA IN 
*     *BUFFER* IS IN XDR (EXTERNAL DATA REPRESENTATION) FORMAT, 8 BIT 
*     BYTES PACKED 7.5/CYBER WORD.  THE DATA IN *BYTEARR* IS 8 BIT
*     INTEGERS. 
* 
*     PROC XDRBYTE (BUFFER, BUFPOS, BYTEARR, BYTELEN, OPERATION)
* 
*     ENTRY    BUFFER    = INTEGER ARRAY PACKED 7.5 BYTES/WORD. 
*              BUFPOS    = INDEX OF NEXT BYTE TO BE READ OR WRITTEN.
*              BYTEARR   = 8 BIT BYTE ARRAY.
*              BYTELEN   = NUMBER OF BYTE VALUES TO BE READ OR
*                          WRITTEN TO BYTEARRAY.
*              OPERATION = EITHER *READ* FROM OR *WRITE* TO *BUFFER*. 
* 
*     EXIT     BUFFER    = DATA READ OUT OR WRITTEN TO. 
*              BUFPOS    = BYTE POSITION IN *BUFFER* AFTER OPERATION. 
*              BYTEARR   = DATA READ OUT OR WRITTEN TO. 
* 
*     METHOD   IF OPERATION IS *READ*, *BYTELEN* BYTES ARE READ OUT OF
*              *BUFFER* AND STORED IN *BYTEARR*.
*              IF THE OPERATION IS *WRITE*, *BYTELEN* BYTES ARE READ
*              FROM *BYTEARR* AND ARE STORED IN *BUFFER*. 
*              *BUFPOS* IS UPDATED TO THE NEXT READ/WRITE BYTE POSITION.
*              THE ARITHMETIC MODULO BASE 60 FUNCTION IS PERFORMED ON 
*              *BUFPOS* MULTIPLIED BY EIGHT TO DETERMINE THE BIT
*              POSITION WITHIN BUFFER.  IF THE POSITION IS 56, THE
*              BYTE IS SPLIT ACROSS TWO WORDS.  THE BYTE IS THEN READ 
*              FROM OR WRITTEN TO THE PROPER LOCATION.
*              THE CALLER IS RESPONSIBLE FOR MAKING SURE THAT THE 
*              DESTINATION ARRAY IS LARGE ENOUGH TO HOLD THE NUMBER 
*              OF VALUES SPECIFIED. 
* 
# 
  
# 
**
# 
  
      ARRAY BUFFER [0:0] S(1);         # ARRAY OF DATA, 7.5 BYTES/WORD #
        ITEM BUF$WRD   U(00,00,60);    # WORD REFERENCE                #
      ITEM BUFPOS            I;        # CUR BYTE POSITION IN BUFFER   #
      ARRAY BYTEARR [0:0] S(1);        # ARRAY OF INTEGERS             #
        ITEM BYTE$WRD  U(00,00,60);    # WORD REFERENCE                #
      ITEM BYTELEN           I;        # NUMBER OF BYTES TO BE PROCESSD#
      ITEM OPERATION S:XDROPER;        # OPERATION TO PERFORM ON BUFFER#
  
      ITEM INDEX             I;        # LOOP INDEX                    #
      ITEM BITPOS            I;        # BIT POSITION IN BUFFER        #
      ITEM WORDPOS           I;        # WORD POSITION IN BUFFER       #
      CONTROL EJECT;
# 
****  START MAIN PROCEDURE
# 
  
      BITPOS = XDRMODU (BUFPOS * 8, 60);# INITIAL BIT POSITION IN BUF  #
      WORDPOS = (BUFPOS * 2) / 15;     # INITIAL WORD INDEX WITHIN     #
      BUFPOS = BUFPOS + BYTELEN;       # ENDING BUFFER LOCATION        #
  
      SWITCH OPER$:XDROPER  OPER$READ:READ, 
                           OPER$WRITE:WRITE;
  
      GOTO OPER$ [OPERATION]; 
        BEGIN                          # OPERATION TYPE                #
  
    OPER$READ:  
  
        FOR INDEX = 0 STEP 1 UNTIL (BYTELEN - 1) DO 
          BEGIN                        # LOOP THROUGH REQUESTED BYTES  #
          IF BITPOS EQ 56 
          THEN
            BEGIN                      # BYTE SPLIT BETWEEN WORDS      #
            BYTE$WRD [INDEX] = B<56,4>BUF$WRD [WORDPOS] * 16 +
                               B<0,4>BUF$WRD [WORDPOS + 1]; 
            WORDPOS = WORDPOS + 1;
            BITPOS = 4; 
            END 
          ELSE
            BEGIN                      # BYTE IN SINGLE CM WORD        #
            BYTE$WRD [INDEX] = B<BITPOS,8>BUF$WRD [WORDPOS];
            BITPOS = BITPOS + 8;
            IF BITPOS GQ 60 
            THEN
              BEGIN 
              BITPOS = 0; 
              WORDPOS = WORDPOS + 1;
              END 
            END 
          END                          # LOOP THROUGH REQUESTED BYTES  #
  
        GOTO OPER$END;
  
    OPER$WRITE: 
  
        FOR INDEX = 0 STEP 1 UNTIL (BYTELEN - 1) DO 
          BEGIN                        # LOOP THROUGH REQUESTED BYTES  #
          IF BITPOS EQ 56 
          THEN
            BEGIN                      # BYTE SPLIT BETWEEN WORDS      #
            B<56,4>BUF$WRD [WORDPOS] = B<52,4>BYTE$WRD [INDEX]; 
            B<0,4>BUF$WRD [WORDPOS + 1] = B<56,4>BYTE$WRD [INDEX];
            WORDPOS = WORDPOS + 1;
            BITPOS = 4; 
            END 
          ELSE
            BEGIN                      # BYTE IN SINGLE CM WORD        #
            B<BITPOS,8>BUF$WRD [WORDPOS] = BYTE$WRD [INDEX];
            BITPOS = BITPOS + 8;
            IF BITPOS GQ 60 
            THEN
              BEGIN 
              BITPOS = 0; 
              WORDPOS = WORDPOS + 1;
              END 
            END 
          END                          # LOOP THROUGH REQUESTED BYTES  #
  
        GOTO OPER$END;
  
        END                            # OPERATION TYPE                #
  
  OPER$END: 
  
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # XDRBYTE                       #
  
      TERM
