PROGRAM cwotas;

{
  File:[22,310]CWOTAS.PAS
  Author: Jim Bostwick 17-Oct-83  (from P2 version)

  Last Edit: 23-JUN-1988 22:14:08 

  History:
	 23-JUN-1988 21:56:25  - JMB PA3UTL upgrade.

}

{$nomain}
 {$NOLIST}
{[A+,B+,L-,K+,R+] Pasmat directive }
 %INCLUDE 'PAS$EXT:General.typ';
 %INCLUDE 'PAS$EXT:ERROR.EXT';

 {$LIST}

{-------------- Convert Word to Ascii -----------------------------}

 PROCEDURE CWOTAS(Bin:Word; 
		Var asc:Packed array [lo..Hi:Integer] of char;
  	    	Pos:integer;
		radix:integer
	);external;

{ 
  Convert unsigned 16-bit value to ASCII string, using specified
radix. Pos > 0: left-justify output starting at pos. Pos = 0: right
justify, using entire string. Pos < 0: right-justify ending at pos.
Legal radix is 2 to 16. 
}

{*USER*
 PASCAL-3 procedure to convert 16-bit, unsigned integer into ASCII
print string, using a specified radix. 

Pos controlls position, fill, and justification of output string.
	Pos > 0  --  left-justify, starting at pos
	Pos = 0  --  right-justify, starting at "hi" (use whole string)
	Pos < 0  --  right-justify, ending at pos
In all cases, Pos returns the rightmost position used in the output string.

 RADIX specifies the conversion radix. Values from 2 to 16 are accepted.
 If "lo"=0, Asc is assumed to be a Pascal-3 "string" type, with ord(Asc[0])
being the current length of the string.
  The maximum possible buffer requirement is 16 bytes (16-bit word with
 radix=2). 
 Illegal radix values, or conversion errors will result in one or more
asterisks in the output string, plus a call to the error routine with
class=warning.
}

procedure cwotas;

VAR
  num,
  dig:word;
  start,			{ position of first digit to convert }
  direction, 			{ +1 for left-justify, -1 for right }
  index, 			{ position of next digit to convert }
  endpos, 			{ position of last digit }
  number_of_digits:integer; 	{ number of digits in output }
  foo:boolean;			{ used during error checks }

{----------------- Local Error Procedure ---------------------------------}

Procedure err(num:integer;
  		param:integer);

{*LOCAL*
 set at least one asterisk in the output string, clean up, and chain to 
  the P3UTIL Error routine for message and walkback 
}

Var
  i:integer;

  BEGIN 
  foo := true; 		{ flag error seen }
  if (lo = 0 ) and (index = 0) then index := 1;
  if (index >= lo) and (index <= hi) then
     asc[index] := '*';
  pos := index + 1; { set return value }
  if pos > hi then pos := hi;
  case num of
   1: error(num, warning_err, 'CWOTAS -- Illegal conversion radix:',param);
   2: error(num, warning_err, 'CWOTAS -- Illegal string index:', param)
  end {case}
end; { err }
  

BEGIN    { Cwotas }
  foo := false;  { no error yet }

{ set up start, direction first, in case of error }

  if pos = 0 then 
    BEGIN 
    pos := -hi;  { right justified at end of string }
    if lo = 0 then index := 1 else index := lo;
    for index := index to hi do asc[index] := ' ' { blank fill }
    END;

  if pos < 0 then
    BEGIN 
    pos := -(pos);
    direction := -1
    END
  else direction := 1;
  start := pos;
  index := start;
    
{ is the radix legal? }

  if (radix < 2) or (Radix > 16) 
    THEN Err(1,radix)
  ELSE
    BEGIN 
    { determine number of digits in output string }

    number_of_digits := 0;
    num := bin;   {copy of input value }
    while num > 0 do 
      BEGIN 
      number_of_digits := number_of_digits + 1;
      num := num div radix
      END;

    { recompute start, endpos, and index }
    if number_of_digits > 1 then 
  	endpos := start + (direction * (number_of_digits - 1))
  	else endpos := start;

    if direction > 0 THEN
      BEGIN   	{ interchange start and end - we convert 'backwards' }
      index := endpos;
      endpos := start;
      start := index
      END;

{ will they fit in the field width? }

    if (endpos < lo) OR ((lo=0) AND (endpos < 1)) then err(2, start)
      else if start > hi then err(2, endpos) 
    	else if lo = 0 
          then if start > ord(asc[0]) then asc[0] := chr(start);
    pos := start + 1; { set up return value }
    if pos > hi then pos := hi;
    
{ finally, if no errors, do the conversion }        

    if not(foo) THEN
        BEGIN 
	  num := bin; 
          repeat
	    dig:=num mod radix;
	    IF dig < 10  then asc[index]:=chr(ord('0')+dig)
	      else asc[index]:=chr(ord('A')+dig-10);
	    index:=index-1;	
	    num:=num div radix;
	  until num=0
        END;
    while index >= start do 
      BEGIN 
      asc[index] := ' ';
      index := index - 1
      END
    END
end;

