/* rexx */

/**
 ** Creates Direction Bit Masks for ASPIDATA.C from SCSI OpCode
 ** text file. (DIRTBL.TXT>
 **/

if arg(1) = '' then
  do
    say "GENDIRTBL source_file > output_file"
    exit
  end

infile = arg(1)

i = 1
do while i \= 0

  call nextline

  if substr(text,1,1) = '+' then
    do
      i = 0
      iterate
    end

  n = word(text,1)

  if Op.n = 1 then
    do
      say "*ERROR* - redefinition: <"text">"
      exit
    end

  Op.n = 1
  Op.n.TITLE = text

  do p = 0 to 255
    code = D2X(p)
    Op.n.code.MASK = 0
    Op.n.code.DEF  = 0
    Op.n.code.DIR  = 'NONE'
    Op.n.code.NAME = ''
  end

  j = 1
  do while j \= 0

    call nextline

    if substr(text,1,1) \= '+' then
      do
        PARSE VAR text CDBcode CDBname CDBdir .

        CDBcode = D2X(X2D(CDBcode))
        CDBdir  = STRIP(CDBdir)

        if Op.n.CDBcode.DEF = 1 then
          do
            say "*ERROR* - redefinition: <" text ">"
            exit
          end
        if CDBdir \= 'ItoT' & CDBdir \= 'TtoI' & CDBdir \= 'NONE' then
          do
            say "*ERROR* - Invalid direction: <" text ">"
            exit
          end

        Op.n.CDBcode.DEF  = 1
        Op.n.CDBcode.NAME = CDBname
        Op.n.CDBcode.DIR  = CDBdir

        if CDBdir = 'ItoT' then
          do
            Op.n.CDBcode.MASK = 1
          end
      end
    else
      j = 0
  end

  say
  say 'Table for' Op.n.TITLE
  say

  j = 0
  do l = 0 to 3

    OutL = '  '

    do m = 0 to 7

      byte = ''
      do p = 0 to 7
        code = D2X(j)
        byte = byte||Op.n.code.MASK
        j = j + 1
      end
      OutL = OutL||'0x'||B2X(byte)||', '

    end

    say OutL

  end

end

if word(text,1) = "+COMBINE" then
  do
    do p = 0 to 255
      code = D2X(p)
      OpC.code.MASK = 0
      OpC.code.DEF  = 0
      OpC.code.DIR  = 'NONE'
      OpC.code.NAME = ''
    end

  say
  say 'Combined Table'
  say

    x= 2
    do while word(text,x) \= ''

      n = word(text,x)

      do p = 0 to 255

        code = D2X(p)

        if OpC.code.DEF = 1 & Op.n.code.Def = 1 then
          do
            if OpC.code.DIR \= Op.n.code.DIR then
              do
                say '*Warning* Direction Conflict N =' n 'Op =' code "<"OpC.code.Dir"> <"Op.n.code.DIR">"
                say OpC.code.NAME Op.n.code.NAME
              end
          end

        if ((OpC.code.DEF \= 1 & Op.n.code.Def = 1) | (OpC.code.DEF = 1 & Op.n.code.Def = 1 & OpC.code.DIR = 'NONE')) then
          do
            OpC.code.DEF  = Op.n.code.DEF
            OpC.code.MASK = Op.n.code.MASK
            OpC.code.DIR  = Op.n.code.DIR
            OpC.code.NAME = Op.n.code.NAME
          end

      end

      x = x+1
    end

  end

  say

  j = 0
  do l = 0 to 3

    OutL = '  '

    do m = 0 to 7

      byte = ''
      do p = 0 to 7
        code = D2X(j)
        byte = byte||OpC.code.MASK
        j = j + 1
      end
      OutL = OutL||'0x'||B2X(byte)||', '

    end

    say OutL

  end

exit




NextLine:

  k = 1
  do while k \= 0
    text = LINEIN(infile)
    if text \= '' & substr(text,1,1) \= '*' then k=0
  end

  return
