dsktool 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/bin/dsktool.rb +157 -0
  2. data/doc/classes/AppleSoftFile.html +215 -0
  3. data/doc/classes/AppleSoftFile.src/M000005.html +18 -0
  4. data/doc/classes/AppleSoftFile.src/M000006.html +18 -0
  5. data/doc/classes/AppleSoftFile.src/M000008.html +18 -0
  6. data/doc/classes/AppleSoftFile.src/M000009.html +18 -0
  7. data/doc/classes/AppleSoftFile.src/M000010.html +18 -0
  8. data/doc/classes/AppleSoftFile.src/M000011.html +18 -0
  9. data/doc/classes/AppleSoftFile.src/M000012.html +18 -0
  10. data/doc/classes/BinaryFile.html +179 -0
  11. data/doc/classes/BinaryFile.src/M000015.html +18 -0
  12. data/doc/classes/BinaryFile.src/M000020.html +18 -0
  13. data/doc/classes/BinaryFile.src/M000021.html +18 -0
  14. data/doc/classes/BinaryFile.src/M000022.html +19 -0
  15. data/doc/classes/BinaryFile.src/M000023.html +18 -0
  16. data/doc/classes/BinaryFile.src/M000024.html +18 -0
  17. data/doc/classes/BinaryFile.src/M000025.html +19 -0
  18. data/doc/classes/D65.html +180 -0
  19. data/doc/classes/D65.src/M000002.html +18 -0
  20. data/doc/classes/D65.src/M000003.html +18 -0
  21. data/doc/classes/D65.src/M000004.html +64 -0
  22. data/doc/classes/D65.src/M000005.html +18 -0
  23. data/doc/classes/D65.src/M000006.html +18 -0
  24. data/doc/classes/D65.src/M000007.html +18 -0
  25. data/doc/classes/D65.src/M000008.html +18 -0
  26. data/doc/classes/D65.src/M000009.html +64 -0
  27. data/doc/classes/DOSDisk.html +272 -0
  28. data/doc/classes/DOSDisk.src/M000007.html +20 -0
  29. data/doc/classes/DOSDisk.src/M000008.html +77 -0
  30. data/doc/classes/DOSDisk.src/M000010.html +20 -0
  31. data/doc/classes/DOSDisk.src/M000011.html +20 -0
  32. data/doc/classes/DOSDisk.src/M000012.html +19 -0
  33. data/doc/classes/DOSDisk.src/M000013.html +20 -0
  34. data/doc/classes/DOSDisk.src/M000014.html +19 -0
  35. data/doc/classes/DOSDisk.src/M000015.html +76 -0
  36. data/doc/classes/DOSFile.html +221 -0
  37. data/doc/classes/DOSFile.src/M000016.html +22 -0
  38. data/doc/classes/DOSFile.src/M000017.html +17 -0
  39. data/doc/classes/DOSFile.src/M000018.html +18 -0
  40. data/doc/classes/DOSFile.src/M000021.html +22 -0
  41. data/doc/classes/DOSFile.src/M000022.html +22 -0
  42. data/doc/classes/DOSFile.src/M000023.html +22 -0
  43. data/doc/classes/DOSFile.src/M000024.html +17 -0
  44. data/doc/classes/DOSFile.src/M000025.html +18 -0
  45. data/doc/classes/DOSFile.src/M000026.html +22 -0
  46. data/doc/classes/DOSFile.src/M000027.html +17 -0
  47. data/doc/classes/DOSFile.src/M000028.html +18 -0
  48. data/doc/classes/DSK.html +285 -0
  49. data/doc/classes/DSK.src/M000009.html +22 -0
  50. data/doc/classes/DSK.src/M000010.html +27 -0
  51. data/doc/classes/DSK.src/M000011.html +19 -0
  52. data/doc/classes/DSK.src/M000012.html +18 -0
  53. data/doc/classes/DSK.src/M000013.html +22 -0
  54. data/doc/classes/DSK.src/M000014.html +22 -0
  55. data/doc/classes/DSK.src/M000015.html +22 -0
  56. data/doc/classes/DSK.src/M000016.html +22 -0
  57. data/doc/classes/DSK.src/M000017.html +22 -0
  58. data/doc/classes/DSK.src/M000018.html +27 -0
  59. data/doc/classes/DSK.src/M000019.html +19 -0
  60. data/doc/classes/DSK.src/M000020.html +18 -0
  61. data/doc/classes/DSK.src/M000021.html +40 -0
  62. data/doc/classes/DSK.src/M000022.html +23 -0
  63. data/doc/classes/IntegerBasicFile.html +276 -0
  64. data/doc/classes/IntegerBasicFile.src/M000001.html +18 -0
  65. data/doc/classes/IntegerBasicFile.src/M000004.html +18 -0
  66. data/doc/classes/IntegerBasicFile.src/M000005.html +18 -0
  67. data/doc/classes/IntegerBasicFile.src/M000006.html +18 -0
  68. data/doc/classes/TestDOSDisks.html +174 -0
  69. data/doc/classes/TestDOSDisks.src/M000001.html +19 -0
  70. data/doc/classes/TestDOSDisks.src/M000002.html +19 -0
  71. data/doc/classes/TestDOSDisks.src/M000003.html +43 -0
  72. data/doc/classes/TestDisassembly.html +144 -0
  73. data/doc/classes/TestDisassembly.src/M000005.html +19 -0
  74. data/doc/classes/TestDisassembly.src/M000006.html +19 -0
  75. data/doc/classes/TestDisassembly.src/M000007.html +19 -0
  76. data/doc/classes/TextFile.html +179 -0
  77. data/doc/classes/TextFile.src/M000019.html +18 -0
  78. data/doc/classes/TextFile.src/M000020.html +20 -0
  79. data/doc/classes/TextFile.src/M000024.html +18 -0
  80. data/doc/classes/TextFile.src/M000025.html +18 -0
  81. data/doc/classes/TextFile.src/M000026.html +18 -0
  82. data/doc/classes/TextFile.src/M000027.html +20 -0
  83. data/doc/classes/TextFile.src/M000029.html +18 -0
  84. data/doc/classes/TextFile.src/M000030.html +18 -0
  85. data/doc/classes/TextFile.src/M000031.html +20 -0
  86. data/doc/created.rid +1 -0
  87. data/doc/dot/f_0.dot +14 -0
  88. data/doc/dot/f_0.png +0 -0
  89. data/doc/dot/f_1.dot +23 -0
  90. data/doc/dot/f_1.png +0 -0
  91. data/doc/dot/f_2.dot +32 -0
  92. data/doc/dot/f_2.png +0 -0
  93. data/doc/dot/f_3.dot +75 -0
  94. data/doc/dot/f_3.png +0 -0
  95. data/doc/dot/f_4.dot +23 -0
  96. data/doc/dot/f_4.png +0 -0
  97. data/doc/dot/f_5.dot +32 -0
  98. data/doc/dot/f_5.png +0 -0
  99. data/doc/dot/f_6.dot +32 -0
  100. data/doc/dot/f_6.png +0 -0
  101. data/doc/dot/f_7.dot +14 -0
  102. data/doc/dot/f_7.png +0 -0
  103. data/doc/files/bin/dsktool_rb.html +171 -0
  104. data/doc/files/lib/D65_rb.html +114 -0
  105. data/doc/files/lib/DOSDisk_rb.html +115 -0
  106. data/doc/files/lib/DOSFile_rb.html +118 -0
  107. data/doc/files/lib/DSK_rb.html +114 -0
  108. data/doc/files/test/tc_disassembly_rb.html +117 -0
  109. data/doc/files/test/tc_dos_disks_rb.html +116 -0
  110. data/doc/files/test/test_dos_disks_rb.html +109 -0
  111. data/doc/files/test/ts_test_all_rb.html +114 -0
  112. data/doc/fr_class_index.html +36 -0
  113. data/doc/fr_file_index.html +34 -0
  114. data/doc/fr_method_index.html +57 -0
  115. data/doc/index.html +24 -0
  116. data/lib/D65.rb +178 -0
  117. data/lib/DOSDisk.rb +186 -0
  118. data/lib/DOSFile.rb +356 -0
  119. data/lib/DSK.rb +121 -0
  120. data/lib/a2_symbols.yaml +199 -0
  121. data/test/dos33_with_adt.dsk +0 -0
  122. data/test/tc_disassembly.rb +16 -0
  123. data/test/tc_dos_disks.rb +49 -0
  124. data/test/ts_test_all.rb +5 -0
  125. metadata +184 -0
data/doc/index.html ADDED
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+
6
+ <!--
7
+
8
+ RDoc Documentation
9
+
10
+ -->
11
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
+ <head>
13
+ <title>RDoc Documentation</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15
+ </head>
16
+ <frameset rows="20%, 80%">
17
+ <frameset cols="25%,35%,45%">
18
+ <frame src="fr_file_index.html" title="Files" name="Files" />
19
+ <frame src="fr_class_index.html" name="Classes" />
20
+ <frame src="fr_method_index.html" name="Methods" />
21
+ </frameset>
22
+ <frame src="files/bin/dsktool_rb.html" name="docwin" />
23
+ </frameset>
24
+ </html>
data/lib/D65.rb ADDED
@@ -0,0 +1,178 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ class D65
4
+ # 6502 Disassembler with annotations
5
+ # based on 6502disassembler.js : n. landsteiner, electronic tradion 2005; e-tradion.net
6
+
7
+ unless defined?(OPCODES) then
8
+ OPCODES= [
9
+ ['BRK',:imp], ['ORA',:inx], ['???',:imp], ['???',:imp], #00..03
10
+ ['TSB',:zpg], ['ORA',:zpg], ['ASL',:zpg], ['???',:imp], #04..07
11
+ ['PHP',:imp], ['ORA',:imm], ['ASL',:acc], ['???',:imp], #08..0b
12
+ ['TSB',:abs], ['ORA',:abs], ['ASL',:abs], ['???',:imp], #0c..0f
13
+ ['BPL',:rel], ['ORA',:iny], ['ORA',:inz], ['???',:imp], #10..13
14
+ ['TRB',:zpg], ['ORA',:zpx], ['ASL',:zpx], ['???',:imp], #14..17
15
+ ['CLC',:imp], ['ORA',:aby], ['INC',:acc], ['???',:imp], #18..1B
16
+ ['INC',:abs], ['ORA',:abx], ['ASL',:abx], ['???',:imp], #1c..1f
17
+ ['JSR',:abs], ['AND',:inx], ['???',:imp], ['???',:imp], #20..23
18
+ ['BIT',:zpg], ['AND',:zpg], ['ROL',:zpg], ['???',:imp], #24..27
19
+ ['PLP',:imp], ['AND',:imm], ['ROL',:acc], ['???',:imp], #28..2b
20
+ ['BIT',:abs], ['AND',:abs], ['ROL',:abs], ['???',:imp], #2c..2f
21
+ ['BMI',:rel], ['AND',:iny], ['AND',:inz], ['???',:imp], #30..33
22
+ ['BIT',:zpx], ['AND',:zpx], ['ROL',:zpx], ['???',:imp], #34..37
23
+ ['SEC',:imp], ['AND',:aby], ['DEC',:acc], ['???',:imp], #38..3b
24
+ ['BIT',:inx], ['AND',:abx], ['ROL',:abx], ['???',:imp], #3c..3f
25
+ ['RTI',:imp], ['EOR',:inx], ['???',:imp], ['???',:imp], #40..43
26
+ ['???',:imp], ['EOR',:zpg], ['LSR',:zpg], ['???',:imp], #44..47
27
+ ['PHA',:imp], ['EOR',:imm], ['LSR',:acc], ['???',:imp], #48..4b
28
+ ['JMP',:abs], ['EOR',:abs], ['LSR',:abs], ['???',:imp], #4c..4f
29
+ ['BVC',:rel], ['EOR',:iny], ['EOR',:inz], ['???',:imp], #50..53
30
+ ['???',:imp], ['EOR',:zpx], ['LSR',:zpx], ['???',:imp], #54..57
31
+ ['CLI',:imp], ['EOR',:aby], ['PHY',:imp], ['???',:imp], #58..5b
32
+ ['???',:imp], ['EOR',:abx], ['LSR',:abx], ['???',:imp], #5c..5f
33
+ ['RTS',:imp], ['ADC',:inx], ['???',:imp], ['???',:imp], #60..63
34
+ ['STZ',:zpg], ['ADC',:zpg], ['ROR',:zpg], ['???',:imp], #64..67
35
+ ['PLA',:imp], ['ADC',:imm], ['ROR',:acc], ['???',:imp], #68..6b
36
+ ['JMP',:ind], ['ADC',:abs], ['ROR',:abs], ['???',:imp], #6c..6f
37
+ ['BVS',:rel], ['ADC',:iny], ['ADC',:inz], ['???',:imp], #70..73
38
+ ['STZ',:zpx], ['ADC',:zpx], ['ROR',:zpx], ['???',:imp], #74..77
39
+ ['SEI',:imp], ['ADC',:aby], ['PLY',:imp], ['???',:imp], #78..7b
40
+ ['JMP',:inx], ['ADC',:abx], ['ROR',:abx], ['???',:imp], #7c..7f
41
+ ['BRA',:rel], ['STA',:inx], ['???',:imp], ['???',:imp], #80..83
42
+ ['STY',:zpg], ['STA',:zpg], ['STX',:zpg], ['???',:imp], #84..87
43
+ ['DEY',:imp], ['BIT',:imm], ['TXA',:imp], ['???',:imp], #88..8b
44
+ ['STY',:abs], ['STA',:abs], ['STX',:abs], ['???',:imp], #8c..8f
45
+ ['BCC',:rel], ['STA',:iny], ['STA',:inz], ['???',:imp], #90..93
46
+ ['STY',:zpx], ['STA',:zpx], ['STX',:zpy], ['???',:imp], #94..97
47
+ ['TYA',:imp], ['STA',:aby], ['TXS',:imp], ['???',:imp], #98..9b
48
+ ['STZ',:abs], ['STA',:abx], ['STZ',:abx], ['???',:imp], #9c..9f
49
+ ['LDY',:imm], ['LDA',:inx], ['LDX',:imm], ['???',:imp], #a0..a3
50
+ ['LDY',:zpg], ['LDA',:zpg], ['LDX',:zpg], ['???',:imp], #a4..a7
51
+ ['TAY',:imp], ['LDA',:imm], ['TAX',:imp], ['???',:imp], #a8..ab
52
+ ['LDY',:abs], ['LDA',:abs], ['LDX',:abs], ['???',:imp], #ab..af
53
+ ['BCS',:rel], ['LDA',:iny], ['LDA',:inz], ['???',:imp], #b0..b3
54
+ ['LDY',:zpx], ['LDA',:zpx], ['LDX',:zpy], ['???',:imp], #b4..b7
55
+ ['CLV',:imp], ['LDA',:aby], ['TSX',:imp], ['???',:imp], #b8..bb
56
+ ['LDY',:abx], ['LDA',:abx], ['LDX',:aby], ['???',:imp], #bc..bf
57
+ ['CPY',:imm], ['CMP',:inx], ['???',:imp], ['???',:imp], #c0..c3
58
+ ['CPY',:zpg], ['CMP',:zpg], ['DEC',:zpg], ['???',:imp], #c4..c7
59
+ ['INY',:imp], ['CMP',:imm], ['DEX',:imp], ['???',:imp], #c8..cb
60
+ ['CPY',:abs], ['CMP',:abs], ['DEC',:abs], ['???',:imp], #cc..cf
61
+ ['BNE',:rel], ['CMP',:iny], ['CMP',:inz], ['???',:imp], #d0..d3
62
+ ['???',:imp], ['CMP',:zpx], ['DEC',:zpx], ['???',:imp], #d4..d7
63
+ ['CLD',:imp], ['CMP',:aby], ['PHX',:imp], ['???',:imp], #d8..db
64
+ ['???',:imp], ['CMP',:abx], ['DEC',:abx], ['???',:imp], #db..df
65
+ ['CPX',:imm], ['SBC',:inx], ['???',:imp], ['???',:imp], #e0..e3
66
+ ['CPX',:zpg], ['SBC',:zpg], ['INC',:zpg], ['???',:imp], #e4..e7
67
+ ['INX',:imp], ['SBC',:imm], ['NOP',:imp], ['???',:imp], #e8..eb
68
+ ['CPX',:abs], ['SBC',:abs], ['INC',:abs], ['???',:imp], #ec..ef
69
+ ['BEQ',:rel], ['SBC',:iny], ['SBC',:ind], ['???',:imp], #f0..f3
70
+ ['???',:imp], ['SBC',:zpx], ['INC',:zpx], ['???',:imp], #f4..f7
71
+ ['SED',:imp], ['SBC',:aby], ['PLX',:imp], ['???',:imp], #f8..fb
72
+ ['???',:imp], ['SBC',:abx], ['INC',:abx], ['???',:imp] #fc..ff
73
+ ]
74
+
75
+
76
+ OPCODE_SIZE={
77
+ :imp,1,
78
+ :acc,1,
79
+ :imm,2,
80
+ :abs,3,
81
+ :abx,3,
82
+ :aby,3,
83
+ :zpg,2,
84
+ :zpx,2,
85
+ :zpy,2,
86
+ :ind,3,
87
+ :inx,2,
88
+ :iny,2,
89
+ :inz,2,
90
+ :rel,2
91
+ }
92
+
93
+ end
94
+ require 'YAML' unless defined? YAML
95
+ @@annotations=YAML::load(File.open(File.dirname(__FILE__)+"/a2_symbols.yaml"))
96
+
97
+ #map of memory locations and annotations
98
+ #e.g. {0xFF3A=>"BELL - writes a ^G to stdout"}
99
+ def D65.annotations
100
+ @@annotations
101
+ end
102
+
103
+
104
+ def D65.disassemble(buffer,start_address=0)
105
+
106
+ index=0
107
+ s=""
108
+ while index<buffer.length
109
+ byte=buffer[index]
110
+ current_address=start_address+index
111
+ opcode_name=OPCODES[byte][0]
112
+ operand_type=OPCODES[byte][1]
113
+ next_byte=(index<buffer.length-1?buffer[index+1]:0)
114
+ next_word=(index<buffer.length-2?buffer[index+1]+buffer[index+2]*256:0)
115
+ operand_format,operand_address= case operand_type
116
+ when :imp then ['','']
117
+ when :acc then ["A",'']
118
+ when :imm then ["\#$%02X",next_byte]
119
+ when :abs then ["$%04X",next_word]
120
+ when :abx then ["$%04X,X",next_word]
121
+ when :aby then ["$%04X,Y",next_word]
122
+ when :zpg then ["$%02X",next_byte]
123
+ when :zpx then ["$%02X,X",next_byte]
124
+ when :zpy then ["$%02X,Y",next_byte]
125
+ when :ind then ["($%04X)",next_word]
126
+ when :inx then ["($%04X),X",next_word]
127
+ when :iny then ["($%04X),Y",next_word]
128
+ when :inz then ["($%02X),Y",next_byte]
129
+ when :rel then ["$%04X",(current_address+next_byte.chr.unpack("c")[0]+2)%0x10000]
130
+ else
131
+ abort("unknown symbol #{operand_type}")
132
+ end
133
+ operand = sprintf(operand_format,operand_address)
134
+ opcode_size=OPCODE_SIZE[operand_type]
135
+ instruction_bytes=case opcode_size
136
+ when 1 then sprintf("%02X ",byte)
137
+ when 2 then sprintf("%02X %02X ",byte,next_byte)
138
+ when 3 then sprintf("%02X %02X %02X",byte,next_byte,next_word>>8)
139
+ end
140
+
141
+
142
+ s+=sprintf("%04X: %s %s %s ; ",current_address,instruction_bytes,opcode_name,operand.ljust(10))
143
+ annotation=annotations[operand_address]
144
+ if (annotation && (operand_type!=:imm)) then
145
+ s+=" "+annotation.to_s
146
+ end
147
+ s+= "\n"
148
+ index+=opcode_size
149
+ end
150
+
151
+ s
152
+ end
153
+
154
+ end
155
+ # == Author
156
+ # Jonno Downes (jonno@jamtronix.com)
157
+ #
158
+ # == Copyright
159
+ # Copyright (c) 2007 Jonno Downes (jonno@jamtronix.com)
160
+ #
161
+ #Permission is hereby granted, free of charge, to any person obtaining
162
+ #a copy of this software and associated documentation files (the
163
+ #"Software"), to deal in the Software without restriction, including
164
+ #without limitation the rights to use, copy, modify, merge, publish,
165
+ #distribute, sublicense, and/or sell copies of the Software, and to
166
+ #permit persons to whom the Software is furnished to do so, subject to
167
+ #the following conditions:
168
+
169
+ # The above copyright notice and this permission notice shall be
170
+ # included in all copies or substantial portions of the Software.
171
+
172
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
173
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
174
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
175
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
176
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
177
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
178
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/DOSDisk.rb ADDED
@@ -0,0 +1,186 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'DOSFile'
5
+
6
+ #
7
+ # Disk image with a standard Apple DOS 3.3 VTOC at track $11, sector $00
8
+ #
9
+ #
10
+ #VTOC : Volume Table of Contents (from Beneath Apple DOS pp 4-2 & 4-3)
11
+ # 00 not used
12
+ # 01 track number of first catalog sector
13
+ # 02 sector number of first catalog sector
14
+ # 03 release number of DOS used to INIT this disk
15
+ # 04-05 not used
16
+ # 06 Diskette volume number (1-254)
17
+ # 07-26 not used
18
+ # 27 maximum number of track/sector pairs which will fit in one file track/sector
19
+ # list sector (122 for 256 byte sectors)
20
+ # 28-2F not used
21
+ # 30 last track where sectors were allocated
22
+ # 31 direction of track allocation (+1 or -1)
23
+ # 32-33 not used
24
+ # 34 number of tracks per diskette (normally 35)
25
+ # 35 number of sectors per track (13 or 16)
26
+ # 36-37 number of bytes per sector (LO/HI format)
27
+ # 38-3B bit map of free sectors in track 0
28
+ # 3C-3F bit map of free sectors in track 1
29
+ # 40-43 bit map of free sectors in track 2
30
+ # ...
31
+ # BC-BF bit map of free sectors in track 33
32
+ # CO-C3 bit map of free sectors in track 34
33
+ # C4-FF bit maps for additional tracks if there are more than 35 tracks per diskette
34
+ #
35
+ #CATALOG (from Beneath Apple DOS p 4-6)
36
+ # 00 Not Used
37
+ # 01 track number of next catalog sector
38
+ # 02 sector number of next catalog sector
39
+ # 03-0A not used
40
+ # 0B-2D First file descriptive entry
41
+ # 2E-50 Second file descriptive entry
42
+ # 51-73 Third file descriptive entry
43
+ # 74-96 Fourth file descriptive entry
44
+ # 97-B9 Fifth file descriptive entry
45
+ # BA-DC Sixth file descriptive entry
46
+ # DD-FF Seventh file descriptive entry
47
+ #
48
+ #FILE DESCRIPTIVE ENTRY (from Beneath Apple DOS p 4-6)
49
+ # 00 Track of first track/sector list sector, if this is a deleted file this contains FF
50
+ # and the original track number is copied to the last byte of the file name (BYTE 20)
51
+ # If this byte contains a 00, the entry is assumed to never have been used and is
52
+ # available for use. (This means track 0 can never be used for data even if the DOS image
53
+ # is 'wiped' from the disk)
54
+ #
55
+ # 01 Sector of first track/sector list sector
56
+ # 02 File type and flags:
57
+ # 80+file type - file is locked
58
+ # 00+file type - file is not locked
59
+ #
60
+ # 00 - TEXT file
61
+ # 01 - INTEGER BASIC file
62
+ # 02 - APPLESOFT BASIC file
63
+ # 04 - BINARY file
64
+ # 08 - S type file
65
+ # 10 - RELOCATABLE object module file
66
+ # 20 - a type file
67
+ # 40 - b type file
68
+ #
69
+ # 03-20 File Name (30 characters)
70
+ # 21-22 Length of file in sectors (LO/HI format)
71
+ #
72
+ #
73
+ #TRACK/SECTOR LIST FORMAT (from Beneath Apple DOS p 4-6)
74
+ # 00 Not used
75
+ # 01 Track number of next T/S list of one is needed or zero if no more t/s list
76
+ # 02 Sector number of next T/S list (if one is present)
77
+ # 03-04 Not used
78
+ # 05-06 Sector offset in file of the first sector described by this list
79
+ # 07-oB Not used
80
+ # 0C-0D Track and sector of first data sector or zeros
81
+ # 0E-0F Track and sector of second data sector or zeros
82
+ # 10-FF Up to 120 more track and sector pairs
83
+
84
+
85
+ class DOSDisk < DSK
86
+
87
+ def dump_catalog
88
+ files.each_value { |file|
89
+ puts "#{file.locked ? '*':' '}#{file.file_type} #{sprintf('%03X',file.sector_count)} #{file.filename}"
90
+ }
91
+ end
92
+
93
+
94
+ def initialize(file_bytes)
95
+ super(file_bytes)
96
+ self.read_vtoc
97
+ end
98
+ #reads the VTOC, and populate the "files" array with files
99
+
100
+ def read_vtoc
101
+ vtoc_sector=get_sector(17,0)
102
+
103
+ catalog_sector=get_sector(vtoc_sector[01],vtoc_sector[02])
104
+ done=false
105
+ while !done
106
+ (0..6).each {|file_number|
107
+ file_descriptive_entry_start=11+file_number*35
108
+ file_descriptive_entry=catalog_sector[file_descriptive_entry_start..file_descriptive_entry_start+35]
109
+ break if (file_descriptive_entry[0]==0xFF) # skip deleted files
110
+ filename=""
111
+ file_descriptive_entry[3..32].to_s.each_byte{|b| filename+=(b.%128).chr}
112
+ filename.sub!(/ *$/,"") #strip off trailing spaces
113
+ locked=(file_descriptive_entry[2]>=0x80)
114
+ sector_count=file_descriptive_entry[0x21]+file_descriptive_entry[0x22]*256
115
+
116
+ file_type_code=file_descriptive_entry[2]%0x80
117
+
118
+
119
+ if (sector_count>0) then
120
+ contents=""
121
+ ts_list_track_no=file_descriptive_entry[0]
122
+ ts_list_sector_no=file_descriptive_entry[1]
123
+ while (ts_list_track_no>0) && (ts_list_track_no<=0X22) && (ts_list_sector_no<=0x0f)
124
+ ts_list_sector=get_sector(ts_list_track_no,ts_list_sector_no)
125
+ ts_list_track_no=ts_list_sector[1]
126
+ ts_list_sector_no=ts_list_sector[2]
127
+
128
+ 0x0C.step(0xff,2) {|i|
129
+ data_track_no=ts_list_sector[i]
130
+ data_sector_no=ts_list_sector[i+1]
131
+ if (data_track_no>0) && (data_track_no<=0X22) && (data_sector_no<=0x0f) then
132
+ contents+=get_sector(data_track_no,data_sector_no)
133
+ end
134
+ }
135
+ end
136
+
137
+ @files[filename]= case file_type_code
138
+ when 0x00 then TextFile.new(filename,locked,sector_count,contents)
139
+ when 0x01 then IntegerBasicFile.new(filename,locked,sector_count,contents)
140
+ when 0x02 then AppleSoftFile.new(filename,locked,sector_count,contents)
141
+ when 0x04 then BinaryFile.new(filename,locked,sector_count,contents)
142
+ # when 0x08 then "S" #S type file
143
+ # when 0x10 then "R" #RELOCATABLE object module file
144
+ # when 0x20 then "a" #??
145
+ # when 0x40 then "b" #??
146
+ else DOSFile.new(filename,locked,sector_count,contents)
147
+ end
148
+
149
+ end
150
+ }
151
+ next_track=catalog_sector[1]
152
+ next_sector=catalog_sector[2]
153
+ if (next_track==0) &&( next_sector==0) then
154
+ done=true
155
+ else
156
+ catalog_sector=get_sector(next_track,next_sector)
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ end
163
+ # == Author
164
+ # Jonno Downes (jonno@jamtronix.com)
165
+ #
166
+ # == Copyright
167
+ # Copyright (c) 2007 Jonno Downes (jonno@jamtronix.com)
168
+ #
169
+ #Permission is hereby granted, free of charge, to any person obtaining
170
+ #a copy of this software and associated documentation files (the
171
+ #"Software"), to deal in the Software without restriction, including
172
+ #without limitation the rights to use, copy, modify, merge, publish,
173
+ #distribute, sublicense, and/or sell copies of the Software, and to
174
+ #permit persons to whom the Software is furnished to do so, subject to
175
+ #the following conditions:
176
+
177
+ # The above copyright notice and this permission notice shall be
178
+ # included in all copies or substantial portions of the Software.
179
+
180
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
181
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
182
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
184
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
185
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
186
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/DOSFile.rb ADDED
@@ -0,0 +1,356 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'D65'
5
+
6
+ #Apple DOS 3.3 file
7
+ class DOSFile
8
+
9
+ attr_accessor(:filename,:locked,:file_type,:sector_count,:contents)
10
+ def initialize(filename,locked,sector_count,contents)
11
+ @filename=filename
12
+ @locked=locked
13
+ @sector_count=sector_count
14
+ @file_type="?"
15
+ @contents=contents
16
+ end
17
+
18
+ #File type as displayed in Apple DOS 3.3 Catalog
19
+ def file_type
20
+ end
21
+
22
+ def to_s
23
+ @contents
24
+ end
25
+
26
+ end
27
+
28
+ class TextFile < DOSFile
29
+ def file_type
30
+ "T"
31
+ end
32
+
33
+ def file_extension
34
+ ".txt"
35
+ end
36
+
37
+ def to_s
38
+ s=""
39
+ @contents.each_byte{|b| s+=(b%0x80).chr.tr(0x0D.chr,"\n")}
40
+ s
41
+ end
42
+ end
43
+
44
+ class BinaryFile < DOSFile
45
+ def file_type
46
+ "B"
47
+ end
48
+
49
+ def file_extension
50
+ ".bin"
51
+ end
52
+
53
+ def disassembly
54
+ start_address=(@contents[0]+@contents[1]*256)
55
+ D65.disassemble(@contents[2..@contents.length-1],start_address)
56
+ end
57
+ end
58
+
59
+ # Adapted from FID.C -- a utility to browse Apple II .DSK image files by Paul Schlyter (pausch@saaf.se)
60
+ #Integer Basic file format:
61
+ # <Length_of_file> (16-bit little endian)
62
+ # <Line>
63
+ # ......
64
+ # <Line>
65
+ #
66
+ # where <Line> is:
67
+ # 1 byte: Line length
68
+ # 2 bytes: Line number, binary little endian
69
+ # <token>
70
+ # <token>
71
+ # <token>
72
+ # ......
73
+ # <end-of-line token>
74
+ #
75
+ # <token> is one of:
76
+ # $12 - $7F: Tokens as listed below: 1 byte/token
77
+ # $80 - $FF: ASCII characters with high bit set
78
+ # $B0 - $B9: Integer constant, 3 bytes: $B0-$B9,
79
+ # followed by the integer value in
80
+ # 2-byte binary little-endian format
81
+ # (Note: a $B0-$B9 byte preceded by an
82
+ # alphanumeric ASCII(hi_bit_set) byte
83
+ # is not the start of an integer
84
+ # constant, but instead part of a
85
+ # variable name)
86
+ #
87
+ # <end-of-line token> is:
88
+ # $01: One byte having the value $01
89
+ # (Note: a $01 byte may also appear
90
+ # inside an integer constant)
91
+ #
92
+ # Note that the tokens $02 to $11 represent commands which
93
+ # can be executed as direct commands only -- any attempt to
94
+ # enter then into an Integer Basic program will be rejected
95
+ # as a syntax error. Therefore, no Integer Basic program
96
+ # which was entered through the Integer Basic interpreter
97
+ # will contain any of the tokens $02 to $11. The token $00
98
+ # appears to be unused and won't appear in Integer Basic
99
+ # programs either. However, $00 is used as an end-of-line
100
+ # marker in S-C Assembler source files, which also are of
101
+ # DOS file type "I".
102
+ #
103
+ # (note here a difference from Applesoft Basic, where there
104
+ # are no "direct mode only" commands - any Applesoft commands
105
+ # can be entered into an Applesoft program as well).
106
+ class IntegerBasicFile < DOSFile
107
+ def file_type
108
+ "I"
109
+ end
110
+
111
+ def file_extension
112
+ ".bas"
113
+ end
114
+
115
+ #display file with all INTEGER BASIC tokens expanded to ASCII
116
+ def to_s
117
+ buffer_as_integer_basic_file(@contents)
118
+ end
119
+
120
+ private
121
+
122
+ IB_REM_TOKEN =0x5D
123
+ IB_UNARY_PLUS = 0x35
124
+ IB_UNARY_MINUS = 0x36
125
+ IB_QUOTE_START = 0x28
126
+ IB_QUOTE_END = 0x29
127
+ INTEGER_BASIC_TOKENS= [
128
+ # $00-$0F
129
+ "HIMEM:","<$01>", "_", " : ",
130
+ "LOAD", "SAVE", "CON", "RUN", # Direct commands
131
+ "RUN", "DEL", ",", "NEW",
132
+ "CLR", "AUTO", ",", "MAN",
133
+
134
+ # $10-$1F
135
+ "HIMEM:","LOMEM:","+", "-", # Binary ops
136
+ "*", "/", "=", "#",
137
+ ">=", ">", "<=", "<>",
138
+ "<", "AND", "OR", "MOD",
139
+
140
+ # $20-$2F
141
+ "^", "+", "(", ",",
142
+ "THEN", "THEN", ",", ",",
143
+ "\"", "\"", "(", "!",
144
+ "!", "(", "PEEK", "RND",
145
+
146
+ # $30-$3F
147
+ "SGN", "ABS", "PDL", "RNDX",
148
+ "(", "+", "-", "NOT", # Unary ops
149
+ "(", "=", "#", "LEN(",
150
+ "ASC(", "SCRN(", ",", "(",
151
+
152
+ # $40-$4F
153
+ "$", "$", "(", ",",
154
+ ",", ";", ";", ";",
155
+ ",", ",", ",", "TEXT", # Statements
156
+ "GR", "CALL", "DIM", "DIM",
157
+
158
+ # $50-$5F
159
+ "TAB", "END", "INPUT", "INPUT",
160
+ "INPUT", "FOR", "=", "TO",
161
+ "STEP", "NEXT", ",", "RETURN",
162
+ "GOSUB", "REM", "LET", "GOTO",
163
+
164
+ # $60-$6F
165
+ "IF", "PRINT", "PRINT", "PRINT",
166
+ "POKE", ",", "COLOR=","PLOT",
167
+ ",", "HLIN", ",", "AT",
168
+ "VLIN", ",", "AT", "VTAB",
169
+
170
+ # $70-$7F
171
+ "=", "=", ")", ")",
172
+ "LIST", ",", "LIST", "POP",
173
+ "NODSP", "DSP", "NOTRACE","DSP",
174
+ "DSP", "TRACE", "PR#", "IN#",
175
+ ]
176
+
177
+
178
+ def is_alnum(c)
179
+ !((c.chr=~/[A-Za-z0-9]/).nil?)
180
+ end
181
+ def buffer_as_integer_basic_file(buffer)
182
+
183
+ length=buffer[0]+buffer[1]*256
184
+ index=2
185
+ s=""
186
+
187
+ while (index<length)
188
+ in_REM = false
189
+ in_QUOTE = false
190
+ lead_SP = false
191
+ last_AN = false
192
+ last_TOK = false
193
+
194
+ line_length=buffer[index]
195
+ index+=1 #skip over the "line length" field
196
+ line_no=buffer[index]+buffer[index+1]*256
197
+ index+=2 #skip over the "line number" field
198
+ s+=sprintf("%u ",line_no)
199
+ done_line=false
200
+ while (!done_line)
201
+ lead_SP = lead_SP || last_AN
202
+ b=buffer[index]
203
+ if (b >= 0x80 ) then
204
+ if ( !in_REM && !in_QUOTE && !last_AN && (b>= 0xB0 && b <= 0xB9) ) then
205
+ integer = buffer[index+1]+buffer[index+2]*256
206
+ index+=2
207
+ s+=sprintf( (last_TOK && lead_SP ) ? " %d" : "%d", integer )
208
+ lead_SP = true
209
+ else
210
+
211
+ c = b & 0x7F
212
+ if (!in_REM && !in_QUOTE && last_TOK && lead_SP && is_alnum(c)) then
213
+ s+=" "
214
+ end
215
+ if ( c >= 0x20 ) then
216
+ s+=c.chr
217
+ else
218
+ s+="^"+(c+0x40).chr
219
+ end
220
+ last_AN = is_alnum(c)
221
+ end
222
+ last_TOK =false
223
+ else
224
+
225
+ token = INTEGER_BASIC_TOKENS[b]
226
+ lastchar = token[token.length-1]
227
+ case b
228
+ when IB_REM_TOKEN then in_REM = true
229
+ when IB_QUOTE_START then in_QUOTE = true
230
+ when IB_QUOTE_END then in_QUOTE = false
231
+ end
232
+
233
+ if lead_SP && ( is_alnum(token[0]) ||
234
+ b == IB_UNARY_PLUS ||
235
+ b == IB_UNARY_MINUS ||
236
+ b == IB_QUOTE_START ) then
237
+ s+=" "
238
+ end
239
+ s+=token
240
+ last_AN = false
241
+ lead_SP = is_alnum(lastchar) || lastchar == ')' || lastchar == '\"'
242
+ last_TOK = true
243
+ end
244
+ index+=1
245
+ done_line=(index>length)||(buffer[index]==0x01)
246
+ end
247
+ s+="\n"
248
+ index+=1 # skip over "end of line" marker
249
+ end
250
+ s
251
+ end
252
+
253
+ end
254
+
255
+ # Adapted from FID.C -- a utility to browse Apple II .DSK image files by Paul Schlyter (pausch@saaf.se)
256
+ #
257
+ #Applesoft file format:
258
+ # <Length_of_file> (16-bit little endian)
259
+ # <Line>
260
+ # ......
261
+ # <Line>
262
+ # where <Line> is:
263
+ # <Next addr> (16-bit little endian)
264
+ # <Line no> (16-bit little endian: 0-65535)
265
+ # <Tokens and/or characters>
266
+ # <End-of-line marker: $00 >
267
+ #
268
+ class AppleSoftFile < DOSFile
269
+
270
+
271
+ def file_type
272
+ "A"
273
+ end
274
+ #display file with all AppleSoft BASIC tokens expanded to ASCII
275
+ def to_s
276
+ buffer_as_applesoft_file(@contents)
277
+ end
278
+
279
+ def file_extension
280
+ ".bas"
281
+ end
282
+
283
+ private
284
+
285
+ APPLESOFT_TOKENS = [
286
+ "END","FOR","NEXT","DATA","INPUT","DEL","DIM","READ",
287
+ "GR","TEXT","PR#","IN#","CALL","PLOT","HLIN","VLIN",
288
+ "HGR2","HGR","HCOLOR=","HPLOT","DRAW","XDRAW","HTAB",
289
+ "HOME","ROT=","SCALE=","SHLOAD","TRACE","NOTRACE",
290
+ "NORMAL","INVERSE","FLASH","COLOR=","POP","VTAB",
291
+ "HIMEM=","LOMEM=","ONERR","RESUME","RECALL","STORE",
292
+ "SPEED=","LET","GOTO","RUN","IF","RESTORE","&","GOSUB",
293
+ "RETURN","REM","STOP","ON","WAIT","LOAD","SAVE","DEF",
294
+ "POKE","PRINT","CONT","LIST","CLEAR","GET","NEW",
295
+ "TAB(","TO","FN","SPC(","THEN","AT","NOT","STEP","+",
296
+ "-","*","/","^","AND","OR",">","=","<","SGN","INT",
297
+ "ABS","USR","FRE","SCRN(","PDL","POS","SQR","RND",
298
+ "LOG","EXP","COS","SIN","TAN","ATN","PEEK","LEN",
299
+ "STR$","VAL","ASC","CHR$", "LEFT$","RIGHT$","MID$","?",
300
+ "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
301
+ ]
302
+
303
+
304
+
305
+ def buffer_as_applesoft_file(buffer)
306
+
307
+ length=buffer[0]+buffer[1]*256
308
+ index=2
309
+ s=""
310
+ while (index<length)
311
+ index+=2 #skip over the "next address" field
312
+ line_no=buffer[index]+buffer[index+1]*256
313
+ index+=2 #skip over the "line number" field
314
+ s+=sprintf("%u ",line_no)
315
+ done_line=false
316
+ while (!done_line)
317
+ b=buffer[index]
318
+ if b>=0x80 then
319
+ s+=APPLESOFT_TOKENS[b-0x80]+" "
320
+ else
321
+ s+=b.chr
322
+ end
323
+ index+=1
324
+ done_line=(index>=length)||(buffer[index]==0)
325
+ end
326
+ s+="\n"
327
+ index+=1 # skip over "end of line" marker
328
+ end
329
+ s
330
+ end
331
+
332
+ end
333
+ # == Author
334
+ # Jonno Downes (jonno@jamtronix.com)
335
+ #
336
+ # == Copyright
337
+ # Copyright (c) 2007 Jonno Downes (jonno@jamtronix.com)
338
+ #
339
+ #Permission is hereby granted, free of charge, to any person obtaining
340
+ #a copy of this software and associated documentation files (the
341
+ #"Software"), to deal in the Software without restriction, including
342
+ #without limitation the rights to use, copy, modify, merge, publish,
343
+ #distribute, sublicense, and/or sell copies of the Software, and to
344
+ #permit persons to whom the Software is furnished to do so, subject to
345
+ #the following conditions:
346
+
347
+ # The above copyright notice and this permission notice shall be
348
+ # included in all copies or substantial portions of the Software.
349
+
350
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
351
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
352
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
353
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
354
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
355
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
356
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.