# File lib/native_file_types/zx81/Zx81Basic.rb, line 16
def to_listing
    
    d_file=contents[3]+(contents[4]<<8)# what would be memory offset 16396    

    vars=contents[7]+(contents[8]<<8)# what would be memory offset 16400

    e_line=contents[11]+(contents[12]<<8)# what would be memory offset 16404

    s=""
    p=0x74 #start at offset 16509

    while p<(d_file-load_address)
      line_number=(contents[p]<<8)+contents[p+1]
      p+=2
      line_length=contents[p]+(contents[p+1]<<8)
      s<<"#{line_number.to_s} "
      i=2
      while i<=line_length && !contents[p+i].nil? do 
        b=contents[p+i]
        if b==126 then       
          #the next 5 bytes are binary form of the number we have just displayed

          i+=5 
          s<<" " unless (i>=line_length-1) || (contents[p+i+1]==17)
        else
          token=Zx81.tokens[b]          
          token="<#{"$%02X" % b}>" if token.nil?
          s<<" " if (token.length>1) && (token[token.length-1].chr==" ") && (s[s.length-1].chr!=" ") #make sure there is at least 1 space around keywords

          s<<token
        end
        i+=1          
      end
      s<<"\n"
      p+=line_length+2      
    end
    #all lines detokenised, now list the variables

    
    s<<"\nVARIABLES\n\n"
    p=(vars-load_address)
    while p<(e_line-load_address)    && (p<contents.length) && (contents[p]!=0x80)
      #read a variable name

      
      first_char=contents[p]
#      puts "%2X" % first_char

      #first byte of name implies type:

      #011nnnnn = single letter variable name, followed by 5 byte number

      #101nnnnn = multi letter variable name (last letter has high bit set), followed by 5 byte number

      #100nnnnn = array of numbers: 

      #111nnnnnn = control variable of a for-next loop

      #010nnnnn = single letter variable name - 0x20, 2 byte string length, text of string

      #110nnnnn = array of characters

      var_type=(first_char>>5)
    
      case var_type
        when 0b010 # string

          var_name=Zx81.tokens[first_char-0x20]
          string_length=(contents[p+2]<<8)+contents[p+1]
          value=Zx81.s_to_ascii(contents[p+3,string_length])
          
          v="#{var_name}$=\"#{value}\" (length=#{string_length})"
          p+=string_length+3
 
        when 0b011 # single letter variable name

          var_name=Zx81.tokens[first_char & 0x3F]
          var_name=first_char.to_s if var_name.nil?
          value=Zx81.buffer_to_number(contents[p+1,5])
          v="#{var_name}=#{value}"
          p+=6
        when 0b100 #array of numbers

          var_name=Zx81.tokens[first_char-0x60]
          length_of_table=(contents[p+2]<<8)+contents[p+1]
          number_of_dimensions=contents[p+3]
          p+=length_of_table+3
          value="?"          
          v="(array of numbers) #{var_name}=#{value}\n dimensions: #{number_of_dimensions}"
        when 0b110 #array of characters

          var_name=Zx81.tokens[first_char-0x20]
          length_of_table=(contents[p+2]<<8)+contents[p+1]
          number_of_dimensions=contents[p+3]
          p+=length_of_table+3
          value="?"          
          v="(array of chars) #{var_name}$=#{value}\n dimensions: #{number_of_dimensions}"

        when 0b101 #multi letter variable name        

          var_name=Zx81.tokens[first_char]
          p+=1          
          until contents[p]>0x7F do
            var_name+=Zx81.tokens[contents[p]]
            p+=1
          end
          var_name+=Zx81.tokens[contents[p]-0x80]
          p+=1
          value=Zx81.buffer_to_number(contents[p,5])
          p+=5
          v="#{var_name}=#{value}"
        when 0b111 # for_next loop

          var_name=Zx81.tokens[first_char& 0x3F]
          value=Zx81.buffer_to_number(contents[p+1,5])
          limit=Zx81.buffer_to_number(contents[p+6,5])
          step=Zx81.buffer_to_number(contents[p+11,5])
          looping_line=(contents[p+17]<<8)+contents[p+16]-1
          p+=18
          v="(for loop) #{var_name}=#{value} LIMIT #{limit} STEP #{step} LINE #{looping_line}"
        else
          raise "unknown var_type %03b" % var_type
        end
        
#      puts v

      s<<v
      s<<"\n"
    end
  s
end