function decom, rec, strval, qstr
;
;
;strval can take the form of: WORDxxxFxx to allow direct extraction of a word
;
;rec = major frame record (144, 64) (144 = 128 + 16 for GPIB)
;qstr = 1==> output string, else output value
;
;Words (exist for every minor frame)
;Bytes (single minor frame)
;Break Bytes up (sub-commutated)
;
;TODO?? Decom byte (string) for single byte array?
;
;Ver 1.0 ??
;Ver 1.1  15-Jun-90	Modification to DECOM.LST - reversed "guard" and "flush"
;			nibbles
;
common blk_decom, val_arr, wtyp_arr, w1_arr, w2_arr, w3_arr, bs_arr, nb_arr, sf_arr, fmt_arr, narr
decom_rd	;read data file into arrays
;
valtrim = strtrim(strupcase(strval),2)
;
if (strmid(valtrim, 0, 4) eq 'WORD') then begin		;WORDxxxFxx
    word = fix(strmid(valtrim, 4, 3))
    frame = fix(strmid(valtrim, 8, 2))
    valtrim = 'MANUAL'
    wtyp = 'MANUAL'
end else begin
    val = strmid( valtrim+'          ', 0, 10)
    ;
    isub = -1
    repeat isub=isub+1 until ( (val eq val_arr(isub)) or (isub eq narr) )
    if (isub eq narr) then begin	;did not find element in database
	print,'Do not recognize the word', string(byte(7))
	print,'Word: ', val
	;; stop
	out = -1
	if (qstr) then out = '?WORD?'
	return, out
    end
    wtyp = wtyp_arr(isub)
end

case wtyp of
    'SXTOS1': off = 16 + 113
    'SXTOS2': off = 16 + 114
    'SXTOS3': off = 16 + 115
    'DPOS1 ': off = 16 + 50
    'DPOS2 ': off = 16 + 51
    'STAT1 ': off = 16 + 48
    'HEADER':
    'SYNC  ': off = 16 + 0
    'FI    ': off = 16 + 3
    'MANUAL': off = 16 + word
    else: begin
	print, 'Invalid word type.  Valid types are:'
	print, 'SXTOS1, SXTOS2, DPOS1, DPOS2, STAT1'
	print, 'Word type listed is: ', wtyp
	stop
	return, 0
    end
endcase
;
out = -9999
case valtrim of
   'TIMEHEAD': begin
	out = intarr(5)			;day, hour, minute, sec, microsec
	out(0) = rec(0)*100 + (rec(1)/16)*10 + (rec(1) mod 16)	;day
	out(1) = (rec(2)/16)*10 + (rec(2) mod 16)			;hour
	out(2) = (rec(3)/16)*10 + (rec(3) mod 16)			;minute
	out(3) = (rec(4)/16)*10 + (rec(4) mod 16)			;second
	out(4) = (rec(5)/16)*100 + (rec(5) mod 16)*10 + (rec(6)/16)	;mSec
	;
	fmt = "(1x, i2, ':', i2.2, ':', i2.2, '.', i3.3)"
	if (qstr) then out = string(out(1:4), format=fmt)
    end

    ;---------------------------------------- raw OS words

    'SXTOS1': out = rec(off, *)
    'SXTOS2': out = rec(off, *)
    'SXTOS3': out = rec(off, *)
    'DPOS1':  out = rec(off, *)
    'DPOS2':  out = rec(off, *)

    'MANUAL': out = rec(off, frame)

    else: begin
	    w1  = w1_arr(isub)
	    w2  = w2_arr(isub)
	    w3  = w3_arr(isub)
	    bs  = bs_arr(isub)		;starting byte number
	    nb  = nb_arr(isub)		;number of bits in byte
	    sf  = sf_arr(isub)		;special flag

	    if (bs eq -1) then bs=7	;inverted from normal (bit 7 is LSB)
	    if (nb eq -1) then nb=8
	    bs  = 7 - bs 		;(inverted from nominal)
	    if (nb ne 8) then bs = bs - (nb-1)

	    if (w1 ge 0) then out = rec(off, w1)

	    ;----- decommutate to less than a byte
	    if (nb ne 8) then out = ( fix(out) / (2^bs) ) mod (2^nb)

	    ;----- add together two bytes
	    if (w2 gt -1) then out = fix(rec(off,w1))*long(256) + rec(off,w2)

	    ;----- add together three bytes
	    if ((w3 gt -1) and (not sf)) then out = long(rec(off,w1))*256*long(256) + $
				fix(rec(off,w2))*256 + rec(off,w3)

	    if (w3 lt -1) then begin	;many values in one major frame
		nrep = abs(w3)
		out = bytarr(nrep)
		for j=0,nrep-1 do begin
		    out(j) = ( fix(rec(off,j*(64/nrep)+w1)) / (2^bs) ) mod (2^nb)
		end
	    end

	    if (sf) then begin		    ;----- Special handling

		;; print, 'Special Handling Case'

		case valtrim of	
			'SYNCCODE1':	out = rec(off:off+2,0)	;only first minfor frame
			'SYNCCODE':	out = rec(off:off+2,*)	;all sync codes
			'FRAME_ID1':	out = rec(off,0)	;only first minfor frame
			'FRAME_ID':	out = rec(off,*)	;
			'POW_ALL': 	bits, rec(off,w1), out
			'F_LINENO':	out = rec(off,w1)*16 + rec(off,w2)/16	;high nibble of second word
			'P_COLWD': 	out = 64		;to fix - need new word - TEMP
			'P_ROWWD':	out = 64		;to fix - need new word - TEMP
			'JERR_POW': 	bits, rec(off,w1), out
			'JERR_COM1': 	bits, rec(off,w1), out
			else: ;do nothing
		endcase

		if (strpos(val,'SYNC_ERR') ne -1) then begin
		    bits, rec(off,w1), b
		    out = b(bs:bs+nb-1)
		end

		if (strpos(val,'SEQNO') ne -1) then if (out gt 13) then out = 0

		if (strpos(val,'DPTIME') ne -1) then begin
		    out = bytarr(3)
		    out(0) = rec(off, w1)
		    out(1) = rec(off, w2)
		    if (wtyp eq 'DPOS1 ') then off2 = 1 else off2 = 0
		    out(2) = ( fix(rec(off+off2, w3)) / (2^bs) ) mod (2^nb)
		end

		if (strmid(val,0,5) eq 'SUN_C') then begin
		    out = (rec(off, w1) mod 16)*256 + rec(off, w2)	;only use low nibble of high byte
		end

	        if (sf eq 3) then out = out + 1
	        ;	strpos(val,'NROI') ne -1)
		;	((strmid(val,0,2) eq 'OR') and (strmid(val,3,2) eq '_N'))
	    end

	end
endcase
;
;---------------------------------------- Turn into string type
;
if (qstr) then begin
    fmt = strupcase(strtrim(fmt_arr(isub),2))
    temp = out

    p = strpos(fmt, '(')
    if (p ne -1) then begin	;case using format statement
	out = string( fix(out), format=fmt)
    end else begin
	if ( (fmt ne '---------') and (fmt ne '') ) then out = conv2str(temp, fmt)
    end
end
;
return, out
end
