-
Notifications
You must be signed in to change notification settings - Fork 26
/
fatget.pla
177 lines (161 loc) · 3.75 KB
/
fatget.pla
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
include "inc/cmdsys.plh"
include "inc/fileio.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
const COPY_BUF_SIZE = 8192 // 8K
const LOWER_DIFF = 'a' - 'A'
byte[17] proname
byte protype
word proaux
word arg
def putByte(val)#0
byte c
c = ((val >> 4) & $0F) + '0'
if c > '9'
c = c + 7
fin
putc(c)
c = (val & $0F) + '0'
if c > '9'
c = c + 7
fin
putc(c)
end
def putWord(val)#0
putByte(val.1)
putByte(val.0)
end
def hexByte(hexChars)
byte lo, hi
lo = toupper(^(hexChars + 1)) - '0'
if lo > 9
lo = lo - 7
fin
hi = toupper(^hexChars) - '0'
if hi > 9
hi = hi - 7
fin
return (hi << 4) | lo
end
def hexWord(hexChars)
return (hexByte(hexChars) << 8) | hexByte(hexChars + 2)
end
def mkProName(fatName, proName, proType, proAux)#0
byte n, l
^proType = $02 // default to BIN
*proAux = $0000 // default to 0
//
// Check for CiderPress style extension
//
l = ^fatName
if l > 7 and ^(fatName + l - 6) == '#'
^proType = hexByte(fatName + l - 5)
*proAux = hexWord(fatName + l - 3)
l = l - 7
fin
//
// Scan backward looking for dir seperator
//
for n = l downto 1
if ^(fatName + n) == '/'
break
fin
next
if l - n > 15
l = n + 15
fin
memcpy(proName + 1, fatName + 1 + n, l - n)
^proName = l - n
end
def getYN(prompt)
byte yn
puts(prompt)
yn = getc
return yn == 'Y' or yn == 'y'
end
def bigFatRead(buf, len)
word xferLen, fatLen
xferLen = 0
repeat
if len > MAX_FAT_BUF_SIZE
fatLen = MAX_FAT_BUF_SIZE
else
fatLen = len
fin
fatLen = sdFAT:readFile(buf, fatLen)
if fatLen > 0
xferLen = xferLen + fatLen
len = len - fatLen
buf = buf + fatLen
else
len = 0
fin
until len == 0
return xferLen
end
def fatCopyFrom(src, dst, type, aux)
word copyBuf, copyLen, freeAddr
byte ref
copyBuf = heapallocalign(COPY_BUF_SIZE, 8, @freeAddr)
if not copyBuf
puts("Not enough free memory!\n"); putln
return -1
fin
//
// Check if dst already exists
//
ref = fileio:open(dst)
if ref
fileio:close(ref)
puts("Overwrite "); puts(dst)
if not getYN("(Y/N)?")
heaprelease(freeAddr)
return -1
fin
putln
destroy(dst)
fin
//
// Create dst file
//
if fileio:create(dst, type, aux)
puts("Create file error: "); putByte(perr); putln
fin
ref = fileio:open(dst)
if not ref
puts("Error opening file: "); puts(dst); putln
puts("Open file error: "); putByte(perr); putln
return -1
fin
//
// Copy FAT file over in big chunks
//
if sdFAT:openFile(src, O_READ)
repeat
copyLen = bigFatRead(copyBuf, COPY_BUF_SIZE)
if copyLen
if fileio:write(ref, copyBuf, copyLen) <> copyLen
puts("Error writing file:"); puts(dst); putln
puts("Write file error: "); putByte(perr); putln
copyLen = 0 // Force end of copy
fin
fin
until copyLen == 0
sdFAT:closeFile()
else
puts("Error opening FAT file:"); puts(src); putln
fin
fileio:close(ref)
heaprelease(freeAddr)
return 0
end
arg = argNext(argFirst)
if ^arg
mkProName(arg, @proname, @protype, @proaux)
puts(arg);puts(" ==> ");puts(@proname)
putc(' ');putByte(protype);putc(',');putWord(proaux);putln
fatCopyFrom(arg, @proname, protype, proaux)
else
puts("Usage: +FATGET <FAT filename>"); putln
fin
done