# File lib/native_file_types/atari800/AtariBasic.rb, line 252
def to_listing
  s=""
  variable_name_table_displacement=(contents[2]+(contents[3]<<8))-0x100
#  puts "%02x %02x" % [contents[6],contents[7]]

  variable_value_table_displacement=(contents[6]+(contents[7]<<8))-0x100
  statement_table_displacement=(contents[8]+(contents[9]<<8))-0x100
  file_end_displacement=(contents[12]+(contents[13]<<8))-0x100
  
#  puts "DVNT $#{"%02x" % variable_name_table_displacement} DVVT $#{"%02x" % variable_value_table_displacement} DST $#{"%02x" % statement_table_displacement}"

  
  #extract all the variable names

  variable_name_table=contents[variable_name_table_displacement+START_OF_FILE_PART_TWO,(variable_value_table_displacement-variable_name_table_displacement)]
  variable_names={}
  variable_token=0x80
  current_variable_name=""
  variable_name_table.each_byte do |byte|
    if byte>=0x80 then      
      current_variable_name+=(byte-0x80).chr
      variable_names[variable_token]=current_variable_name
      variable_token+=1
      current_variable_name=""
    else
      current_variable_name+=byte.chr
    end
  end
  #~ variable_names.keys.sort.each do |token|

    #~ puts "$%02x : #{variable_names[token]}" % token

  #~ end

  
  statement_table=contents[statement_table_displacement+START_OF_FILE_PART_TWO,(file_end_displacement-statement_table_displacement)]
  p=0
  s=""
  while p<statement_table.length    
#    puts "%02x" % statement_table[p] 

    line_number=statement_table[p,2].unpack("v")[0]
    break if line_number==0x8000
    line_length=statement_table[p+2]
    line=statement_table[p+3,line_length-2]
    s<<"#{line_number} "
#    puts "#{line_number} #{"%02x" % line_length}"

    break if line_length==0
    t=0 
    start_of_statement=true
    while (!line.nil?) && t<line.length && line[t]!=0x16 
      actual_file_offset=statement_table_displacement+START_OF_FILE_PART_TWO+p+t #track for debugging

      token=line[t]      
      if start_of_statement then
        t+=1 #skip over the 'displacement till next statement' byte

        token=line[t]
        command=ATARI_BASIC_COMMAND_TOKENS[token]
        command="[UNK CMD %02X]" % token if command.nil?
        s<<"#{command} " unless token==0x36 #don't print anything on an implied let

        start_of_statement=false
        if token==0x00 then #REM

          s<<line[t+1,line.length-(t+3)]
          t=line.length
        end
      elsif token>=0x80 then
        variable=variable_names[token]
        variable="[UNK VAR %02X]" % token if variable.nil?
        s<<variable
      elsif token==0x14 then #end of statement

        s<<":"
        start_of_statement=true
      elsif token==0x0D then #numeric hex constant - TURBO BASIC

#        raise "NHCONST not implemented yet : offset $#{"%x" % actual_file_offset} of #{filename}"

        const=line[t+1]+(line[t+2]<<8)
        s<<"&%x"%const
        t+=2
      elsif token==0x0E then #numeric constant - 6 BCD floating point

        buffer=line[t+1,6]
        s<<parse_bytes_as_float(buffer).to_s.sub(/\.0$/,'')#strip off ".0"

        t+=6
      elsif token==0x0F then #string

        length=line[t+1]        
        s<<"\"#{line[t+2,length]}\""
        t+=length+1
      elsif token==0x1B then
        s<<"THEN "
        start_of_statement=true        
      else
        op_func=ATARI_BASIC_OPERATORS_AND_FUNCTIONS[token]
        op_func="[UNK OP/FUNC %02X]" % token if op_func.nil?
        s<<"#{op_func}"        
      end      
        
      t+=1
    end
    s<<"\n"
    p+=line_length
  end
  s
end