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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
{
This file is part of the Free Pascal run time library.
Copyright (c) 2020 by Free Pascal development team
Low level file functions for the Sinclair QL
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{****************************************************************************
Low level File Routines
All these functions can set InOutRes on errors
****************************************************************************}
{ close a file from the handle value }
procedure do_close(handle : longint);
begin
Error2InOutRes(io_close(handle));
end;
{ delete a file, given its name }
procedure do_erase(p : pchar; pchangeable: boolean);
begin
Error2InOutRes(io_delet(p));
end;
procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
begin
end;
function do_write(h: longint; addr: pointer; len: longint) : longint;
var
res: longint;
begin
do_write:=0;
res:=io_sstrg(h, -1, addr, len);
if res < 0 then
Error2InOutRes(res)
else
do_write:=res;
end;
function do_read(h: longint; addr: pointer; len: longint) : longint;
var
res: longint;
begin
do_read := 0;
res := io_fline(h, -1, addr, len);
if res = ERR_EF then
res := 0;
if res < 0 then
Error2InOutRes(res)
else
do_read := res;
end;
function do_filepos(handle: longint): longint;
var
res: longint;
pos: longint;
begin
do_filepos := 0;
pos := 0;
res := fs_posre(handle, pos);
if res = ERR_EF then
res := 0;
if (res < 0) then
Error2InOutRes(res)
else
do_filepos := pos;
end;
procedure do_seek(handle, pos: longint);
var
res: longint;
begin
res := fs_posab(handle, pos);
if res = ERR_EF then
res := 0;
if (res < 0) then
Error2InOutRes(res);
end;
{ The maximum length of a QL file is 2^31 - 64 bytes ($7FFFFFC0)
so the maximum offset is that, minus 1. ($7fffffBF) }
const
MAX_QL_FILE_LENGTH = $7FFFFFBF;
function do_seekend(handle: longint): longint;
var
res: longint;
pos: longint;
begin
do_seekend:=-1;
pos:=MAX_QL_FILE_LENGTH;
res:=fs_posab(handle, pos);
if res = ERR_EF then
res := 0;
if res < 0 then
Error2InOutRes(res)
else
do_seekend := pos;
end;
function do_filesize(handle: longint): longint;
var
res: longint;
header: array [0..$39] of byte;
begin
do_filesize := 0;
res := fs_headr(handle, @header, $40);
if res < 0 then
Error2InOutRes(res)
else
do_filesize := plongint(@header[0])^;
end;
{ truncate at a given position }
procedure do_truncate(handle, pos: longint);
begin
do_seek(handle, pos);
fs_truncate(handle);
end;
procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{
filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating.
when (flags and $100) the file will be append
when (flags and $1000) the file will be truncate/rewritten
when (flags and $10000) there is no check for close (needed for textfiles)
}
var
res: longint;
openMode: longint;
begin
openMode:=Q_OPEN;
{ close first if opened }
if ((flags and $10000)=0) then
begin
case filerec(f).mode of
fmInput, fmOutput, fmInout:
do_close(filerec(f).handle);
fmClosed: ;
else
begin
InOutRes:=102; {not assigned}
exit;
end;
end;
end;
{ reset file handle }
filerec(f).handle:=UnusedHandle;
{ convert filemode to filerec modes }
case (flags and 3) of
0 : filerec(f).mode:=fmInput;
1 : filerec(f).mode:=fmOutput;
2 : filerec(f).mode:=fmInout;
end;
{ empty name is special }
if p[0]=#0 then begin
case filerec(f).mode of
fminput :
filerec(f).handle:=StdInputHandle;
fmappend,
fmoutput : begin
filerec(f).handle:=StdOutputHandle;
filerec(f).mode:=fmOutput; {fool fmappend}
end;
end;
exit;
end;
{ rewrite (create a new file) }
if (flags and $1000)<>0 then openMode:=Q_OPEN_OVER;
res:=io_open(p,openMode);
if res < 0 then
begin
Error2InOutRes(res);
filerec(f).mode:=fmClosed;
exit;
end
else
filerec(f).handle:=res;
{ append mode }
if ((Flags and $100)<>0) and
(FileRec(F).Handle<>UnusedHandle) then begin
do_seekend(filerec(f).handle);
filerec(f).mode:=fmOutput; {fool fmappend}
end;
end;
function do_isdevice(handle: thandle): boolean;
begin
do_isdevice:=false;
end;
|