*DECK DB$CDIS 
USETEXT UTCDFTX 
      FUNC DB$CDIS(VALUE,LENGTH,BASE,FILLER) C(10); 
 #
  *   DB$CDIS - CONVERT NUMBER TO DISPLAY CODE   PAGE  1
  *   STEVEN P. LEVIN                            DATE  12/12/74 
  *   REVISION STEVEN LEVIN (CONCURRENT CDCS)    DATE  10/17/75 
  
  DC  PURPOSE 
  
      CONVERT A NUMBER INTO THE DISPLAY CODE EQUIVALENT, USING THE
      PASSED VALUE, RESULT LENGTH, NUMBER BASE, AND FILLER PARAMETERS.
  
  DC  ENTRY CONDITIONS
  
      THE FOLLOWING FOUR PARAMETERS MUST BE PASSED: 
        VALUE  - THE NUMERIC VALUE TO BE CONVERTED INTO DISPLAY CODE
        LENGTH - RESULT SUBSTRING LENGTH IN CHARACTERS (1 TO DFCHARWD)
        BASE   - NUMBER BASE TO BE USED (SHOULD BE EITHER 8 OR 10)
        FILLER - CHARACTER TO BE USED FOR LEFT FILLING (BLANK OR ZERO)
  
  DC  EXIT CONDITIONS 
  
      UPON RETURN, THE LEFT LENGTH CHARACTERS (AT MOST DFCHARWD = 10) 
      OF DB$CDIS WILL CONTAIN THE PASSED NUMBER VALUE CONVERTED TO A
      DISPLAY CODE VALUE USING THE NUMBER BASE.  ALL CHARACTERS TO THE
      RIGHT OF THE LEFT LENGTH CHARACTERS OF DB$CDIS, IF ANY (I.E., IF
      LENGTH IS LESS THAN DFCHARWD), WILL BE BLANK.  IF A " " FILLER
      IS PASSED AND THE NUMBER VALUE IS NEGATIVE, THE RESULT WILL 
      CONTAIN A MINUS SIGN.  LEADING ZEROS ON BLANK-FILLED NUMBERS (A 
      " " FILLER PASSED) WILL BE REPLACED BY BLANKS, BUT LEADING
      ZEROES WILL REMAIN ON ZERO-FILLED NUMBERS (A "0" FILLER PASSED).
      HOWEVER, UPON RETURN ALL CHARACTERS OF DB$CDIS MAY BE SET TO THE
      SPECIAL ERROR VALUE OF ALL ASTERISKS ("*").  THIS RESULT CAN
      OCCUR EITHER FOR ILLEGAL (OUT OF BOUNDS OR UNRECOGNIZABLE)
      PARAMETERS, FOR NUMBERS TOO LARGE FOR THE ALGORITHM(S) USED 
      (BASE NOT A POWER OF TWO AND EITHER BLANK-FILLED WITH AN
      ABSOLUTE VALUE GQ 2**48 OR ZERO-FILLED WITH A FULL-WORD 
      BIT-STRING VALUE GQ 2**48, OR BASE A POWER OF TWO AND EITHER
      BLANK-FILLED WITH AN ABSOLUTE VALUE GQ BASE**DFCHARWD OR
      "0"-FILLED WITH A FULL-WORD BIT-STRING VALUE GQ BASE**DFCHARWD),
      OR FOR INSUFFICIENT LENGTH TO REPRESENT THE FULL RESULT STRING. 
      THE FOLLOWING EXAMPLES MAY HELP TO CLARIFY ALL OF THIS: 
        PARAMETERS      RETURNED VALUE      COMMENT 
        (17,7,8,"B")    **********          "B" IS ILLEGAL PARAMETER
        (17,7,8," ")         21             DECIMAL 17 IN BASE 8 IS 21
        (17,7,8,"0")    0000021             LEADING ZEROES REMAIN 
        (-17,7,8," ")       -21             BLANK-FILLED NEGATIVE 
        (-17,7,8,"0")   **********          0-FILL, BUT -17=+77...7756
  
  DC  CALLING ROUTINES
  
      DB$CERR - CST BUILDER PROC TO HANDLE FATAL ERROR MESSAGE/RETURN 
      DB$COUT - CST BUILDER PROC TO PUT STATISTICS ON THE OUTPUT FILE 
      DB$DS27 - LIST STATUS LINES ON OPERATOR CONSOLE (CDCS). 
      DB$DUDF - UPDATE DYNAMIC DISPLAY FIELDS (CDCS). 
  
  DC  CALLED ROUTINES 
  
      NO ROUTINES ARE CALLED BY DB$CDIS.
  
  DC  NON-LOCAL VARIABLES 
  
      DB$CDIS IS GIVEN A VALUE AS DESCRIBED IN EXIT CONDITIONS ABOVE. 
  
  DC  DESCRIPTION 
  
      IF ANY PARAMETER IS ILLEGAL SET DB$CDIS TO ASTERISKS AND RETURN.
      IF VALUE <0 (-0<0) AND FILLER IS " ", CONSIDER NUMBER NEGATIVE. 
      IF THE NUMBER IS TOO BIG FOR THE ALGORITHM(S) USED, RETURN *"S. 
      IF FILLER IS " ", SET UP DISPLAY WITH LEADING BLANKS, ELSE ZERO.
      CONVERT THE NUMBER TO DISPLAY USING A BASE-DEPENDENT ALGORITHM. 
      IF BASE 10 USE A NON-POWER-OF-TWO ITERATIVE DIVISION ALGORITHM. 
      IF BASE 8 USE A POWER-OF-2 ALGORITHM - CONVERT 3 BITS AT A TIME.
      IF DISPLAY EXCEEDS ALLOWED LENGTH SET DB$CDIS TO *"S AND RETURN.
      IF THE NUMBER VALUE IS CONSIDERED NEGATIVE, INSERT A MINUS SIGN.
      SET DB$CDIS TO LENGTH CHARACTERS OF DISPLAY, AND RETURN.
  
      NOTE, ALTHOUGH DB$CDIS IS CURRENTLY WRITTEN TO HANDLE DISPLAY 
      CODE STRINGS OF ONLY UP TO 10 CHARACTERS IN LENGTH AND ONLY 
      BASE 8 OR 10, BOTH RESTRICTIONS CAN BE CHANGED RELATIVELY 
      EASILY.  THE MAXIMUM LENGTH COULD BE INCREASED GENERALLY BY 
      REPLACING USE OF DFCHARWD BY SOME LARGER VALUE.  BASES 2 AND 4
      COULD USE THE SAME ALGORITHM AS BASE 8, BUT USING 1 OR 2 BITS AT
      A TIME INSTEAD OF 3.  BASES 3, 5-7, OR 9 COULD BE HANDLED BY THE
      SAME ALGORITHM AS BASE 10, REPLACING USE OF 10 BY USE OF BASE.
      ONE CAUTION, THOUGH, IS NECESSARY.  MORE SPEICAL CODE COULD BE
      REQUIRED TO HANDLE A ZERO-FILLED -0 TO PRODUCE ALL CHARACTERS.
 #
        CONTROL EJECT;
  
        BEGIN                # DB$CDIS #
  
# THE FOLLOWING ARE FORMAL PARAMETERS, IN THE ORDER THEY ARE PASSED # 
  
        ITEM VALUE I;        # THE NUMERIC VALUE TO BE CONVERTED #
        ITEM LENGTH I;       # RESULT SUBSTRING LENGTH IN CHARACTERS #
        ITEM BASE I;         # THE NUMBER BASE TO BE USED (8 OR 10) # 
        ITEM FILLER C(1);    # LEFT FILLING CHARACTER (BLANK OR ZERO)#
  
        CONTROL NOLIST;      # COMDECK NOT LISTED: UTCDFDCLS (DEF"S) #
        CONTROL LIST;        # RESUME LISTING OF THE SOURCE CODE #
  
# THE FOLLOWING ITEMS ARE LOCAL TO THIS ROUTINE # 
  
        ITEM DISPLAY C(DFCHARWD);      # DISPLAY CODE STRING BUILT UP#
        ITEM INDEX I;        # A GENERAL-PURPOSE INDEX COUNTER #
        ITEM NEGATIVE B;     # TRUE IFF VALUE < 0 AND BLANK-FILLED #
        ITEM NEWVALUE U;     # UNSIGNED NUMERIC VALUE OPERATED UPON # 
        CONTROL EJECT;
  
# IF ANY PARAMETER IS ILLEGAL, SET DB$CDIS TO ASTERISKS AND RETURN #
  
        IF LENGTH LS 1 OR LENGTH GR DFCHARWD     # CHECK THE LENGTH # 
          OR (BASE NQ 8 AND BASE NQ 10)          # CHECK NUMBER BASE #
          OR (FILLER NQ " " AND FILLER NQ "0")   # CHECK FILLER CHAR.#
            THEN             # THERE IS (ARE) AN ILLEGAL PARAMETER(S)#
              BEGIN 
                DB$CDIS = "**********";          # RETURN ERROR VALUE#
  
                RETURN;      # RETURN DUE TO ILLEGAL PARAMETER(S) # 
  
              END 
  
# IF VALUE < 0 (-0 < 0) AND FILLER IS " ", CONSIDER NUMBER NEGATIVE # 
  
        NEGATIVE = B<0> VALUE EQ 1 AND FILLER EQ " ";      # -0 < 0 # 
        IF NEGATIVE          # CHECK IF NUMBER IS CONSIDERED NEGATIVE#
          THEN NEWVALUE = -VALUE; # NEWVALUE = ABSOLUTE-VALUE(VALUE) #
          ELSE NEWVALUE = VALUE;  # NEWVALUE IS SAME BITS AS VALUE #
  
# IF THE NUMBER IS TOO LARGE FOR THE ALGORITHM(S) USED, RETURN *"S #
  
        IF (BASE EQ 8 AND B<0,30> NEWVALUE NQ 0) # GQ 8**DFCHARWD # 
          OR (BASE EQ 10 AND B<0,12> NEWVALUE NQ 0)        # GQ 2**48#
            THEN             # NUMBER TOO LARGE FOR ALGORITHM(S) USED#
              BEGIN 
                DB$CDIS = "**********";          # RETURN ERROR VALUE#
  
                RETURN;      # RETURN DUE TO NUMBER TOO LARGE # 
  
              END 
  
# IF FILLER IS " ", SET UP DISPLAY WITH LEADING BLANKS, ELSE ZEROES # 
  
        IF FILLER EQ " "     # CHECK IF DISPLAY IS TO BE BLANK-FILLED#
          THEN DISPLAY = "         0"; # A 0 WITH LEADING BLANKS #
          ELSE DISPLAY = "0000000000"; # A STRING OF ALL ZEROES # 
  
# CONVERT THE NUMBER TO DISPLAY CODE USING A BASE-DEPENDENT ALGORITHM#
  
        INDEX = 0;           # EXPLICIT SET FOR BETTER LOOP CONTROL # 
        IF BASE EQ 10        # CHECK WHICH BASE-DEPENDENT ALGORITHM # 
  
# IF BASE 10 USE A NON-POWER-OF-TWO ITERATIVE DIVISION ALGORITHM #
  
          THEN               # USE NON-POWER-OF-2 DIVISION ALGORITHM #
            LOOP WHILE INDEX LS DFCHARWD AND NEWVALUE NQ 0 DO 
              BEGIN 
                INDEX = INDEX + 1;     # INCREMENT CHARACTER COUNTER #
                C<DFCHARWD - INDEX> DISPLAY =    # CONVERT THE UNITS #
                  NEWVALUE - (NEWVALUE / 10) * 10 + DFDISZER; 
                NEWVALUE = NEWVALUE / 10;        # REMOVE THE UNITS # 
              END 
  
# IF BASE 8 USE A POWER-OF-2 ALGORITHM BY CONVERTING 3 BITS AT A TIME # 
  
          ELSE               # USE POWER-OF-2 3-BIT-GROUP ALGORITHM # 
            LOOP WHILE INDEX LS DFCHARWD         # LOOP IS A FOR-LOOP#
              AND B<0,DFBITSWD - 3 * INDEX> NEWVALUE NQ 0 DO
                BEGIN 
                  INDEX = INDEX + 1;   # INCREMENT CHARACTER COUNTER #
                  C<DFCHARWD - INDEX> DISPLAY =  # CONVERT 3 BITS # 
                    B<DFBITSWD - 3 * INDEX,3> NEWVALUE + DFDISZER;
                END 
  
# IF DISPLAY EXCEEDS ALLOWED LENGTH, SET DB$CDIS TO *"S AND RETURN #
  
        IF INDEX EQ 0 THEN INDEX = 1;  # RIGHTMOST CHARACTER IS "0" # 
        IF INDEX GR LENGTH OR (NEGATIVE AND INDEX EQ LENGTH)
          OR (BASE EQ 10 AND NEWVALUE NQ 0)      # IF EXCESS LENGTH # 
            THEN             # DISPLAY STRING EXCEEDS ALLOWED LENGTH #
              BEGIN 
                DB$CDIS = "**********";          # RETURN ERROR VALUE#
  
                RETURN;      # RETURN DUE TO ALLOWED LENGTH EXCEEDED #
  
              END 
  
# IF THE NUMBER VALUE IS CONSIDERED NEGATIVE, INSERT A MINUS SIGN (-)#
  
        IF NEGATIVE THEN C<DFCHARWD - (INDEX + 1)> DISPLAY = "-"; 
  
# SET DB$CDIS TO LENGTH CHARACTERS OF DISPLAY, AND RETURN # 
  
        DB$CDIS = C<DFCHARWD - LENGTH,LENGTH> DISPLAY;     #MOVE LEFT#
  
        RETURN;              # NUMBER VALUE CONVERTED TO DISPLAY CODE#
  
        END                  # DB$CDIS #
  
      TERM
