Class: DSK

Inherits:
Object
  • Object
show all
Defined in:
lib/DSK.rb

Overview

For manipulating DSK files, as created by ADT (adt.berlios.de) and ADTPRo (adtpro.sourceforge.net) used by many Apple 2 emulators.

Direct Known Subclasses

DOSDisk

Constant Summary collapse

DSK_FILE_LENGTH =
143360

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_bytes = "\0"*DSK_FILE_LENGTH) ⇒ DSK

create a new DSK structure (in memory, not on disk)



28
29
30
31
32
33
34
# File 'lib/DSK.rb', line 28

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

Class Method Details

.is_dsk_file?(filename) ⇒ Boolean

does this filename have a suitable extension?

Returns:

  • (Boolean)


12
13
14
# File 'lib/DSK.rb', line 12

def DSK.is_dsk_file?(filename)
	!(filename.upcase=~/\.DSK$|\.DSK\.GZ$|\.PO$|\.PO\.GZ$/).nil?
end

.read(filename) ⇒ Object

read in an existing DSK file (must exist)



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/DSK.rb', line 37

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
	dsk
end

Instance Method Details

#dump_diskObject

print to stdout a formatted hex dump of all sectors on all tracks



94
95
96
97
98
99
100
101
# File 'lib/DSK.rb', line 94

def dump_disk

	(0..34).each {|track|
		(0..15).each {|sector|
			dump_sector(track,sector)
		}
	}
end

#dump_sector(track, sector) ⇒ Object

print to stdout a formatted hex dump of a single 256 byte sector



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/DSK.rb', line 67

def dump_sector(track,sector)

	start_byte=track*16*256+sector*256
	s=@file_bytes[start_byte..start_byte+255]

	print_hline
	printf("TRACK: $%02X SECTOR $%02X\ OFFSET $%04X\n",track,sector,start_byte)
	printf "\t"

	(0..15).each {|x| printf("%02X ",x) }
	puts
	print_hline
	(0..15).each {|line_number|
		 lhs=""
		 rhs=""
		 start_byte=line_number*16
		 line=s[start_byte..start_byte+15]
		 line.each_byte {|byte|
			  lhs+= sprintf("%02X ", byte)
			  rhs+= (byte%128).chr.sub(/[\x00-\x1f]/,'.')
	 	}
		 printf("%02X\t%s %s\n",start_byte,lhs,rhs)
	}

end

#filesObject



62
63
64
# File 'lib/DSK.rb', line 62

def files
	@files
end

#get_sector(track, sector) ⇒ Object



57
58
59
60
# File 'lib/DSK.rb', line 57

def get_sector(track,sector)
	start_byte=track*16*256+sector*256
	@file_bytes[start_byte..start_byte+255]
end

#is_dos33?Boolean

does this DSK have a standard Apple DOS 3.3 VTOC?

Returns:

  • (Boolean)


18
19
20
21
22
23
24
# File 'lib/DSK.rb', line 18

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