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, NADOLDisk

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)



33
34
35
36
37
38
39
# File 'lib/DSK.rb', line 33

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)



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/DSK.rb', line 42

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

Instance Method Details

#disassemble_sector(track, sector) ⇒ Object

return a formatted hex dump of a single 256 byte sector



102
103
104
105
106
107
108
109
110
# File 'lib/DSK.rb', line 102

def disassemble_sector(track,sector)
	require 'D65'
	sector_data=get_sector(track,sector)
	if (track==0) && (sector==0) then
		return D65.disassemble(sector_data[1..255],0x801)
	else
		return D65.disassemble(sector_data)
	end
end

#dump_diskObject

return a formatted hex dump of all sectors on all tracks



113
114
115
116
117
118
119
120
121
# File 'lib/DSK.rb', line 113

def dump_disk
	s=""
	(0..34).each {|track|
		(0..15).each {|sector|
			s<<dump_sector(track,sector)
		}
	}
	s
end

#dump_sector(track, sector) ⇒ Object

return a formatted hex dump of a single 256 byte sector



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/DSK.rb', line 78

def dump_sector(track,sector)
	start_byte=track.to_i*16*256+sector.to_i*256
	s=hline
	s<<sprintf("TRACK: $%02X SECTOR $%02X\ OFFSET $%04X\n",track,sector,start_byte)
	s<< "\t"
	sector_data=get_sector(track,sector)
	(0..15).each {|x| s<<sprintf("%02X ",x) }
	s<<"\n"
	s<<hline
	(0..15).each {|line_number|
		 lhs=""
		 rhs=""
		 start_byte=line_number*16
		 line=sector_data[start_byte..start_byte+15]
		 line.each_byte {|byte|
			  lhs<< sprintf("%02X ", byte)
			  rhs<< (byte%128).chr.sub(/[\x00-\x1f]/,'.')
	 	}
		s<<sprintf("%02X\t%s %s\n",start_byte,lhs,rhs)
	}
	s
end

#filesObject



73
74
75
# File 'lib/DSK.rb', line 73

def files
	@files
end

#get_sector(track, sector) ⇒ Object



68
69
70
71
# File 'lib/DSK.rb', line 68

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

#is_nadol?Boolean

Returns:

  • (Boolean)


26
27
28
29
# File 'lib/DSK.rb', line 26

def	is_nadol?
	# track $00, sector $02 , bytes $11 - "NADOL"
	(@file_bytes[0x00211..0x00215]=="NADOL")
end