# File lib/file_systems/CbmDos.rb, line 126
def self.add_file(file_system_image,native_filetype_class,filename,file_contents,file_type=nil,aux_code=nil)
  #make sure the file type is supported on CBM DOS!

  raise "#{native_filetype_class} not supported on CBM DOS 2.6 file system" if  native_filetype_class.file_system_file_types[self].nil?
  expected_file_type=native_filetype_class.file_system_file_types[self] 
  file_type=expected_file_type if file_type.nil?
  raise "inconsistent file_type (should be #{expected_file_type} but was #{file_type})" unless expected_file_type==file_type
  native_file=native_filetype_class.new(file_system_image,filename,file_contents,file_type,aux_code)
  raise "couldn't make #{native_filetype_class}" if native_file.nil?
  
  file_system_image.delete_file(filename) unless file_system_image.files[filename].nil?

  
  free_sectors=free_sector_list(file_system_image)
  sectors_needed=1+(file_contents.length/254)
  file_sectors=free_sectors[(free_sectors.length-sectors_needed)/2,sectors_needed] #we take a chunk out of the middle of the available sectors, so we keep as close to track 18 as possible

  raise "not enough free space - #{sectors_needed} sectors needed, #{file_sectors.length} available " unless sectors_needed==file_sectors.length  
  directory_slot=find_free_directory_slot(file_system_image)
#  file_sectors.each {|ts| puts "T#{ts[0]} S#{ts[1]}"}

  directory_slot=create_empty_directory_sector(file_system_image) if directory_slot.nil?
  raise "DIRECTORY IS FULL!" if directory_slot.nil?
  raise "invalid directory slot " if directory_slot[2].nil?
#  puts "T#{directory_slot[0]} S#{directory_slot[1]} OFFSET #{directory_slot[2]}"

  directory_track_no=directory_slot[0]
  directory_sector_no=directory_slot[1]
  directory_offset=directory_slot[2]
  directory_sector=file_system_image.get_sector(directory_track_no,directory_sector_no)
  directory_filename=directory_entry_for_filename(filename)
  file_code=FILE_TYPES.index(native_file.class.file_system_file_types[CbmDos])
  raise "invalid file type" if file_code.nil?
  file_code+=0x80 unless file_code==0 #DEL files should be OPEN, all other files should be CLOSED

#  puts "%x" % file_code

  directory_entry=[file_code,file_sectors[0][0],file_sectors[0][1],directory_filename,file_sectors.length].pack("CCCa16x9v")
#  puts "start of file #{filename} will be T #{file_sectors[0][0]} S #{file_sectors[0][1]}"

  sectors_needed.times do |i|
    this_track_no=file_sectors[i][0]
    this_sector_no=file_sectors[i][1]
    if i==(sectors_needed-1) then
      next_track_no=0
      data_length=(file_contents.length % 254)
      next_sector_no=data_length+1
    else
      next_track_no=file_sectors[i+1][0]
      next_sector_no=file_sectors[i+1][1]
      data_length=254
    end
    sector_data=[next_track_no,next_sector_no,file_contents[i*254,data_length] ].pack("CCA254")
    file_system_image.set_sector(this_track_no,this_sector_no,sector_data)
    mark_sector_as_used(file_system_image,this_track_no,this_sector_no)
  end
  directory_sector[directory_offset+2,0x1D]=directory_entry #skip over the first 2 bytes, which are the track / sector of next directory sector in slot 1, or 0/0 in other slots

  file_system_image.set_sector(directory_track_no,directory_sector_no,directory_sector)
  return native_file
end