MCSファイルの読み込み

ノウハウ紹介

XilinxのコンフィギュレーションROM用のファイルフォーマットとしてよく用いられるMCSファイル.このファイル,Intel MCS-86 Hexadecimal Objectというフォーマットです.

というわけで(?),パーザを書いてみました.

ファイルフォーマットの説明はいろんなところにありましたが,Wikipediaを参考にしました.http://en.wikipedia.org/wiki/Intel_HEX

Rubyだと,こんな感じのコードで解析できます.

 

def usage_and_exit(str)
  puts str
  exit
end

def validate(a, c)
#  puts "checksum = #{c}"
  return false unless a.size % 2 == 0 # length of the data must be even.
  sum = 0
  (a.size/2).times{|x|
    sum = sum + (a[(2*x)..(2*x+1)].join.to_i(16))
  }
  result = ((~sum) + 1) & 0x0ff
#  puts "result = #{result}"
  return result == c
end

@ext_addr = 0

def put_data(addr, data)
  printf("%08x: ", addr + (@ext_addr << 16))
  sep = ""
  (data.size/2).times{|x|
    printf("%s0x%02x", sep, data[(2*x)..(2*x+1)].join.to_i(16))
    sep = ", "
  }
  puts ""
end

def parse_line(line)
  a = line.split("")
  usage_and_exit("Illegal line: #{line}") unless a[0] == ":"
  count    = a[1..2].join.to_i(16)
  offset   = a[3..6].join.to_i(16)
  type     = a[7..8].join.to_i(16)
  data     = a[9..-3]
  checksum = a[-2..-1].join.to_i(16)
  usage_ane_exit("Checksum missmatch: #{line}") unless validate(a[1..-3], checksum)
  case(type)
  when 0x00
    #puts "DATA"
    put_data(offset, data)
  when 0x01
    #puts "END"
  when 0x02
    #puts "EXTENDED SEGMENT ADDRESS"
  when 0x03
    #puts "SEGMENT ADDRESS"
  when 0x04
    #puts "EXTENDED LINEAR ADDRESS: #{data}"
    @ext_addr = data.join.to_i(16)
  when 0x05
    #puts "LINEAR ADDRESS BEGIN"
  else
    #puts "Unknown type: #{type}"
  end
end

def parse(src)
  src.read.split("\n").each{|l|
#    p l.strip
    parse_line(l.strip)
  }
end

parse($stdin)

これで,オリジナルのROMライタが作れそうですね(違.

コメント

タイトルとURLをコピーしました