$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) require 'open-uri' # # For manipulating DSK files, as created by ADT (http://adt.berlios.de) and ADTPRo (http://adtpro.sourceforge.net) # used by many Apple 2 emulators. # class DSK #does this filename have a suitable extension? def DSK.is_dsk_file?(filename) !(filename.upcase=~/\.DSK$|\.DSK\.GZ$|\.PO$|\.PO\.GZ$/).nil? end DSK_FILE_LENGTH=143360 attr_accessor (:file_bytes) # does this DSK have a standard Apple DOS 3.3 VTOC? def is_dos33? # VTOC is at offset 0x11000 # bytes 1/2/3 are a track number, sector number and DOS version number # see if these are reasonable values (@file_bytes[0x11001]<=34) && (@file_bytes[0x11002]<=15) && (@file_bytes[0x11003]==3) end def is_nadol? # track $00, sector $02 , bytes $11 - "NADOL" (@file_bytes[0x00211..0x00215]=="NADOL") end #create a new DSK structure (in memory, not on disk) def initialize(file_bytes="\0"*DSK_FILE_LENGTH) if (file_bytes.length!=DSK_FILE_LENGTH) then raise "DSK files must be #{DSK_FILE_LENGTH} bytes long (was #{file_bytes.length} bytes)" end @file_bytes=file_bytes @files={} end #read in an existing DSK file (must exist) def DSK.read(filename) #is the file extension .gz? if !(filename=~/\.gz$/).nil? then require 'zlib' file_bytes=Zlib::GzipReader.new(open(filename,"rb")).read else file_bytes=open(filename,"rb").read end if (file_bytes.length!=DSK_FILE_LENGTH) then abort("#{filename} is not a valid DSK format file") end dsk=DSK.new(file_bytes) if (dsk.is_dos33?) require 'DOSDisk' dsk=DOSDisk.new(file_bytes) end if (dsk.is_nadol?) require 'NADOLDisk' dsk=NADOLDisk.new(file_bytes) end dsk end def get_sector(track,sector) start_byte=track*16*256+sector*256 @file_bytes[start_byte..start_byte+255] end def files @files end #return a formatted hex dump of a single 256 byte sector def dump_sector(track,sector) start_byte=track.to_i*16*256+sector.to_i*256 s=hline s<