def read_catalog(starting_block=2,dir_path="")
next_block_no=starting_block
while (next_block_no!=0)
block=get_block(next_block_no)
offset=4
while (offset<(0x200-0x27))
directory_entry=block[offset..offset+0x27]
storage_type=directory_entry[0]>>4
name_length=directory_entry[0]%0x10
name=directory_entry[1..name_length]
file_type=directory_entry[0x10]
key_pointer=directory_entry[0x11]+directory_entry[0x12]*0x100
blocks_used=directory_entry[0x13]+directory_entry[0x14]*0x100
file_length=directory_entry[0x15]+directory_entry[0x16]*0x100+directory_entry[0x17]*0x10000
aux_type=directory_entry[0x1f]+directory_entry[0x20]*0x100
case storage_type
when 0x00 then
when 0x01 then
file_contents=get_block(key_pointer)
files[name]=ProDOSFile.new(name,file_contents,file_type,aux_type)
when 0x02 then
block_list=[]
index_block=get_block(key_pointer)
0.upto((file_length/0x200)) do |i|
block_list<<index_block[i]+(index_block[i+0x100]*0x100)
end
file_contents=""
block_list.each do |next_block_no|
if next_block_no==0 then
file_contents+="\x00"*0x200
elsif next_block_no>self.last_block then
STDERR<<"file #{name} attempted to read bad block # #{next_block_no}\n"
file_contents+="\x00"*0x200
else
file_contents+=get_block(next_block_no)
end
end
file_contents=file_contents[0..file_length-1]
files["#{dir_path}#{name}"]=ProDOSFile.new(name,file_contents,file_type,aux_type)
when 0x03 then
master_index_block=get_block(key_pointer)
block_list=[]
number_of_index_entries=1+(file_length/0x200)
number_of_index_blocks=1+(number_of_index_entries/0x100)
number_of_index_entries_in_last_block=number_of_index_entries-(number_of_index_blocks-1)*0x100
0.upto(number_of_index_blocks-1) do |i|
index_block_no=master_index_block[i]+master_index_block[i+0x100]*0x100
index_block=get_block(index_block_no)
if i==number_of_index_blocks-1 then
entries_in_this_index_block=number_of_index_entries_in_last_block
else
entries_in_this_index_block=256
end
0.upto(entries_in_this_index_block-1) do |j|
block_list<<index_block[j]+(index_block[j+0x100]*0x100)
end
end
file_contents=""
block_list.each do |next_block_no|
if next_block_no==0 then
file_contents+="\x00"*0x200
else
file_contents+=get_block(next_block_no)
end
end
file_contents=file_contents[0..file_length-1]
files["#{dir_path}#{name}"]=ProDOSFile.new(name,file_contents,file_type,aux_type)
when 0x0D then
read_catalog(key_pointer,"#{dir_path}#{name}/")
when 0x0E then
when 0x0F then
@volume_name=name
else
puts "skipping unknown storage_type #{sprintf '%02X',storage_type} for #{dir_path}#{name}"
end
offset+=0x27
end
next_block_no=block[2]+block[3]*256
end
end