def self.add_file(file_system_image,native_filetype_class,filename,file_contents,file_type=nil,aux_code=nil)
raise "#{native_filetype_class} not supported on Apple DOS 3.3 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?
catalog_slot=find_catalog_slot(file_system_image,nil)
raise "CATALOG IS FULL!" if catalog_slot.nil?
raise "invalid catalog slot " if catalog_slot[2].nil?
free_sectors=free_sector_list(file_system_image)
sectors_needed=1+(255+file_contents.length)/256
raise "not enough free space - #{sectors_needed} sectors needed, #{free_sectors.length} available " unless sectors_needed<=free_sectors.length
raise "only files up to 122 sectors currently supported " if sectors_needed>122
track_sector_list="\0"*256
track_sector_list_sector=free_sectors[0]
(0..sectors_needed-2).each do |sector_in_file|
sector_to_use=free_sectors[sector_in_file+1]
track_sector_list[(sector_in_file*2)+0x0C]=sector_to_use[0]
track_sector_list[(sector_in_file*2)+0X0D]=sector_to_use[1]
sector_contents=file_contents[(sector_in_file*256),256] || ""
self.set_sector(file_system_image,sector_to_use[0],sector_to_use[1],sector_contents)
end
self.set_sector(file_system_image,track_sector_list_sector[0],track_sector_list_sector[1],track_sector_list)
catalog_sector=file_system_image.get_sector(catalog_slot[0],catalog_slot[1])
raise "invalid catalog track #{catalog_slot[0]},sector #{catalog_slot[1]}" if catalog_sector.nil?
file_descriptive_entry="\0"*0x23
file_descriptive_entry[0]=track_sector_list_sector[0]
file_descriptive_entry[1]=track_sector_list_sector[1]
file_descriptive_entry[2]=file_type
file_descriptive_entry[3..0x20]=catalog_filename(filename)
file_descriptive_entry[0x21]=(sectors_needed-1)%256
file_descriptive_entry[0x22]=(sectors_needed-1)/256
catalog_sector[catalog_slot[2],0x23]=file_descriptive_entry
self.set_sector(file_system_image,catalog_slot[0],catalog_slot[1],catalog_sector)
raise "catalog not updated correctly!" if find_catalog_slot(file_system_image,filename).nil?
raise "error: file should now be in catalog" if files(file_system_image)[filename].nil?
return native_file
end