dsktool 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/dsktool.rb +157 -0
- data/doc/classes/AppleSoftFile.html +215 -0
- data/doc/classes/AppleSoftFile.src/M000005.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000006.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000008.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000009.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000010.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000011.html +18 -0
- data/doc/classes/AppleSoftFile.src/M000012.html +18 -0
- data/doc/classes/BinaryFile.html +179 -0
- data/doc/classes/BinaryFile.src/M000015.html +18 -0
- data/doc/classes/BinaryFile.src/M000020.html +18 -0
- data/doc/classes/BinaryFile.src/M000021.html +18 -0
- data/doc/classes/BinaryFile.src/M000022.html +19 -0
- data/doc/classes/BinaryFile.src/M000023.html +18 -0
- data/doc/classes/BinaryFile.src/M000024.html +18 -0
- data/doc/classes/BinaryFile.src/M000025.html +19 -0
- data/doc/classes/D65.html +180 -0
- data/doc/classes/D65.src/M000002.html +18 -0
- data/doc/classes/D65.src/M000003.html +18 -0
- data/doc/classes/D65.src/M000004.html +64 -0
- data/doc/classes/D65.src/M000005.html +18 -0
- data/doc/classes/D65.src/M000006.html +18 -0
- data/doc/classes/D65.src/M000007.html +18 -0
- data/doc/classes/D65.src/M000008.html +18 -0
- data/doc/classes/D65.src/M000009.html +64 -0
- data/doc/classes/DOSDisk.html +272 -0
- data/doc/classes/DOSDisk.src/M000007.html +20 -0
- data/doc/classes/DOSDisk.src/M000008.html +77 -0
- data/doc/classes/DOSDisk.src/M000010.html +20 -0
- data/doc/classes/DOSDisk.src/M000011.html +20 -0
- data/doc/classes/DOSDisk.src/M000012.html +19 -0
- data/doc/classes/DOSDisk.src/M000013.html +20 -0
- data/doc/classes/DOSDisk.src/M000014.html +19 -0
- data/doc/classes/DOSDisk.src/M000015.html +76 -0
- data/doc/classes/DOSFile.html +221 -0
- data/doc/classes/DOSFile.src/M000016.html +22 -0
- data/doc/classes/DOSFile.src/M000017.html +17 -0
- data/doc/classes/DOSFile.src/M000018.html +18 -0
- data/doc/classes/DOSFile.src/M000021.html +22 -0
- data/doc/classes/DOSFile.src/M000022.html +22 -0
- data/doc/classes/DOSFile.src/M000023.html +22 -0
- data/doc/classes/DOSFile.src/M000024.html +17 -0
- data/doc/classes/DOSFile.src/M000025.html +18 -0
- data/doc/classes/DOSFile.src/M000026.html +22 -0
- data/doc/classes/DOSFile.src/M000027.html +17 -0
- data/doc/classes/DOSFile.src/M000028.html +18 -0
- data/doc/classes/DSK.html +285 -0
- data/doc/classes/DSK.src/M000009.html +22 -0
- data/doc/classes/DSK.src/M000010.html +27 -0
- data/doc/classes/DSK.src/M000011.html +19 -0
- data/doc/classes/DSK.src/M000012.html +18 -0
- data/doc/classes/DSK.src/M000013.html +22 -0
- data/doc/classes/DSK.src/M000014.html +22 -0
- data/doc/classes/DSK.src/M000015.html +22 -0
- data/doc/classes/DSK.src/M000016.html +22 -0
- data/doc/classes/DSK.src/M000017.html +22 -0
- data/doc/classes/DSK.src/M000018.html +27 -0
- data/doc/classes/DSK.src/M000019.html +19 -0
- data/doc/classes/DSK.src/M000020.html +18 -0
- data/doc/classes/DSK.src/M000021.html +40 -0
- data/doc/classes/DSK.src/M000022.html +23 -0
- data/doc/classes/IntegerBasicFile.html +276 -0
- data/doc/classes/IntegerBasicFile.src/M000001.html +18 -0
- data/doc/classes/IntegerBasicFile.src/M000004.html +18 -0
- data/doc/classes/IntegerBasicFile.src/M000005.html +18 -0
- data/doc/classes/IntegerBasicFile.src/M000006.html +18 -0
- data/doc/classes/TestDOSDisks.html +174 -0
- data/doc/classes/TestDOSDisks.src/M000001.html +19 -0
- data/doc/classes/TestDOSDisks.src/M000002.html +19 -0
- data/doc/classes/TestDOSDisks.src/M000003.html +43 -0
- data/doc/classes/TestDisassembly.html +144 -0
- data/doc/classes/TestDisassembly.src/M000005.html +19 -0
- data/doc/classes/TestDisassembly.src/M000006.html +19 -0
- data/doc/classes/TestDisassembly.src/M000007.html +19 -0
- data/doc/classes/TextFile.html +179 -0
- data/doc/classes/TextFile.src/M000019.html +18 -0
- data/doc/classes/TextFile.src/M000020.html +20 -0
- data/doc/classes/TextFile.src/M000024.html +18 -0
- data/doc/classes/TextFile.src/M000025.html +18 -0
- data/doc/classes/TextFile.src/M000026.html +18 -0
- data/doc/classes/TextFile.src/M000027.html +20 -0
- data/doc/classes/TextFile.src/M000029.html +18 -0
- data/doc/classes/TextFile.src/M000030.html +18 -0
- data/doc/classes/TextFile.src/M000031.html +20 -0
- data/doc/created.rid +1 -0
- data/doc/dot/f_0.dot +14 -0
- data/doc/dot/f_0.png +0 -0
- data/doc/dot/f_1.dot +23 -0
- data/doc/dot/f_1.png +0 -0
- data/doc/dot/f_2.dot +32 -0
- data/doc/dot/f_2.png +0 -0
- data/doc/dot/f_3.dot +75 -0
- data/doc/dot/f_3.png +0 -0
- data/doc/dot/f_4.dot +23 -0
- data/doc/dot/f_4.png +0 -0
- data/doc/dot/f_5.dot +32 -0
- data/doc/dot/f_5.png +0 -0
- data/doc/dot/f_6.dot +32 -0
- data/doc/dot/f_6.png +0 -0
- data/doc/dot/f_7.dot +14 -0
- data/doc/dot/f_7.png +0 -0
- data/doc/files/bin/dsktool_rb.html +171 -0
- data/doc/files/lib/D65_rb.html +114 -0
- data/doc/files/lib/DOSDisk_rb.html +115 -0
- data/doc/files/lib/DOSFile_rb.html +118 -0
- data/doc/files/lib/DSK_rb.html +114 -0
- data/doc/files/test/tc_disassembly_rb.html +117 -0
- data/doc/files/test/tc_dos_disks_rb.html +116 -0
- data/doc/files/test/test_dos_disks_rb.html +109 -0
- data/doc/files/test/ts_test_all_rb.html +114 -0
- data/doc/fr_class_index.html +36 -0
- data/doc/fr_file_index.html +34 -0
- data/doc/fr_method_index.html +57 -0
- data/doc/index.html +24 -0
- data/lib/D65.rb +178 -0
- data/lib/DOSDisk.rb +186 -0
- data/lib/DOSFile.rb +356 -0
- data/lib/DSK.rb +121 -0
- data/lib/a2_symbols.yaml +199 -0
- data/test/dos33_with_adt.dsk +0 -0
- data/test/tc_disassembly.rb +16 -0
- data/test/tc_dos_disks.rb +49 -0
- data/test/ts_test_all.rb +5 -0
- 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.
|