$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) $:.unshift(File.dirname(__FILE__+"\\..")) unless $:.include?(File.dirname(__FILE__+"\\..")) || $:.include?(File.expand_path(File.dirname(__FILE__+"\\.."))) require 'FileSystem' #TRSDOS (and compatables, e.g. LDOS, NEWDOS) #Reference - http://www.classic-computers.org.nz/system-80/software-manuals/manuals-NewDOS-80_v2.0_manual.pdf pages 99-101 #sectors 2-9 of the directory track (17) contain File Primary Directory Entries, which are 32 bytes made up of: # byte $00: # bit 7 : 0 = FPDE, 1 = FXDE # bit 6 : 1 means a SYSTEM file # bit 5 : undefined # bit 4 : 1 = in use, 0 = entry empty # bit 3 : 1 = file is hidden # bit 2 - 0 : access level code # byte $01: # bit 7 : 0 = file may be allocated more space when necessary # bit 6 : 0 = any excess space past the EOF may be deallocated # bit 5 : 1 = at least one sector of the file has been written to since this bit was last reset # bit 4 - 0 : undefined # byte $02: undefined # byte $03: low order byte of the file's EOF (position of the EOF within the EOF sector) # byte $04: logical record length # byte $05-$0C : file name (right padded with blanks) # byte $0D-$0F: file extension (right padded with blanks) # byte $10-$11 : encode of the upate password # byte $12-$13 : encode of the access password # byte $14 : middle order byte of the EOF # byte $15 : high order byte of the EOF # byte $16 - $1F : 5 pairs of extent elements, each pair made up of: # byte $00 : if $FF, then end of extent elements for this file. if $FE, then next byte contains the DEC for the first (or next) FXDE assigned to this file. # any other value ($00-$FD) equals the number of the diskette's lump in which the area starts. # byte $01 : bits 7-5 = number of granules (0-7) from the start of the lump to the start of the area # : bits 4- 0 = number less one of contiguous granules assigned to this area. # # when a file has more than 4 space areas assigned, the additional extent elements are contained in FXDE's assigned to the file. # the format of a FXDE is: # byte $00: bits 7 and 4 are both 1 to indicate this entry is a FXDE, all other bits are 0 # bute $01: the DEC for the previous FPDE or FXDE of this file. This is a backward chain. the previous entry's byte $1E will be $FD, and it's byte $1F will contain the DEC of this FXDE # # the EOF value (bytes $03, $14, $15) is decoded as: # if low order byte ($03) = 0, then EOF is in RBA format # if low order byte ($03) != 0, then EOF in the FPDE is equal to the RBA value plus 256 (the value in the high two bytes is incremented by 1) # # RBA = Relative Byte Address : a method of addressing where addressing starts at 0 rather than 1 # # DEC = Directory Entry Code - a one byte code used to specify a particular FDE. Format is rrrssss, where sssss+2 = the relative # number within the directory of the sector containing the FDE, and rrr times $20 = the relative byte address within the sector # of the FDE. class TrsDos0) then file_length-=0x100 end # byte $16 - $1F : 5 pairs of extent elements, each pair made up of: # byte $00 : if $FF, then end of extent elements for this file. if $FE, then next byte contains the DEC for the first (or next) FXDE assigned to this file. # any other value ($00-$FD) equals the number of the diskette's lump in which the area starts. # byte $01 : bits 7-5 = number of granules (0-7) from the start of the lump to the start of the area # : bits 4- 0 = number less one of contiguous granules assigned to this area. 5.times do |extent_no| extent=fde[(extent_no*2)+0x16,2] break if extent[0]==0xFF raise "FXDE's not implemented yet" if extent[0]==0xFE track_no=extent[0] granule_offset=extent[1]>>5 number_of_granules=1+(extent[1] & 0b00011111) start_sector=granule_offset*sectors_per_granule(file_system_image) number_of_sectors=number_of_granules*sectors_per_granule(file_system_image) number_of_sectors.times {|i| contents<