sysfile.inc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2005 by Free Pascal development team
  4. Low level file functions
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$asmmode motorola}
  12. {****************************************************************************
  13. Low Level File Routines
  14. ****************************************************************************}
  15. procedure DoDirSeparators(p:pchar);
  16. var
  17. i : longint;
  18. begin
  19. { allow slash as backslash }
  20. for i:=0 to strlen(p) do
  21. if p[i] in AllowDirectorySeparators then p[i]:=DirectorySeparator;
  22. end;
  23. procedure do_close(h : longint);
  24. begin
  25. asm
  26. movem.l d2/d3/a2/a3,-(sp)
  27. move.l h,d0
  28. move.w d0,-(sp)
  29. move.w #$3e,-(sp)
  30. trap #1
  31. add.l #4,sp { restore stack ... }
  32. movem.l (sp)+,d2/d3/a2/a3
  33. end;
  34. end;
  35. procedure do_erase(p : pchar);
  36. begin
  37. DoDirSeparators(p);
  38. asm
  39. move.l d2,d6 { save d2 }
  40. movem.l d3/a2/a3,-(sp) { save regs }
  41. move.l p,-(sp)
  42. move.w #$41,-(sp)
  43. trap #1
  44. add.l #6,sp
  45. move.l d6,d2 { restore d2 }
  46. movem.l (sp)+,d3/a2/a3
  47. tst.w d0
  48. beq @doserend
  49. move.w d0,errno
  50. @doserend:
  51. end;
  52. if errno <> 0 then
  53. Error2InOut;
  54. end;
  55. procedure do_rename(p1,p2 : pchar);
  56. begin
  57. DoDirSeparators(p1);
  58. DoDirSeparators(p2);
  59. asm
  60. move.l d2,d6 { save d2 }
  61. movem.l d3/a2/a3,-(sp)
  62. move.l p1,-(sp)
  63. move.l p2,-(sp)
  64. clr.w -(sp)
  65. move.w #$56,-(sp)
  66. trap #1
  67. lea 12(sp),sp
  68. move.l d6,d2 { restore d2 }
  69. movem.l (sp)+,d3/a2/a3
  70. tst.w d0
  71. beq @dosreend
  72. move.w d0,errno { error ... }
  73. @dosreend:
  74. end;
  75. if errno <> 0 then
  76. Error2InOut;
  77. end;
  78. function do_isdevice(handle:word):boolean;
  79. begin
  80. if (handle=stdoutputhandle) or (handle=stdinputhandle) or
  81. (handle=stderrorhandle) then
  82. do_isdevice:=FALSE
  83. else
  84. do_isdevice:=TRUE;
  85. end;
  86. function do_write(h,addr,len : longint) : longint;
  87. begin
  88. asm
  89. move.l d2,d6 { save d2 }
  90. movem.l d3/a2/a3,-(sp)
  91. move.l addr,-(sp)
  92. move.l len,-(sp)
  93. move.l h,d0
  94. move.w d0,-(sp)
  95. move.w #$40,-(sp)
  96. trap #1
  97. lea 12(sp),sp
  98. move.l d6,d2 { restore d2 }
  99. movem.l (sp)+,d3/a2/a3
  100. tst.l d0
  101. bpl @doswrend
  102. move.w d0,errno { error ... }
  103. @doswrend:
  104. move.l d0,@RESULT
  105. end;
  106. if errno <> 0 then
  107. Error2InOut;
  108. end;
  109. function do_read(h,addr,len : longint) : longint;
  110. begin
  111. asm
  112. move.l d2,d6 { save d2 }
  113. movem.l d3/a2/a3,-(sp)
  114. move.l addr,-(sp)
  115. move.l len,-(sp)
  116. move.l h,d0
  117. move.w d0,-(sp)
  118. move.w #$3f,-(sp)
  119. trap #1
  120. lea 12(sp),sp
  121. move.l d6,d2 { restore d2 }
  122. movem.l (sp)+,d3/a2/a3
  123. tst.l d0
  124. bpl @dosrdend
  125. move.w d0,errno { error ... }
  126. @dosrdend:
  127. move.l d0,@Result
  128. end;
  129. if errno <> 0 then
  130. Error2InOut;
  131. end;
  132. function do_filepos(handle : longint) : longint;
  133. begin
  134. asm
  135. move.l d2,d6 { save d2 }
  136. movem.l d3/a2/a3,-(sp)
  137. move.w #1,-(sp) { seek from current position }
  138. move.l handle,d0
  139. move.w d0,-(sp)
  140. move.l #0,-(sp) { with a seek offset of zero }
  141. move.w #$42,-(sp)
  142. trap #1
  143. lea 10(sp),sp
  144. move.l d6,d2 { restore d2 }
  145. movem.l (sp)+,d3/a2/a3
  146. move.l d0,@Result
  147. end;
  148. end;
  149. procedure do_seek(handle,pos : longint);
  150. begin
  151. asm
  152. move.l d2,d6 { save d2 }
  153. movem.l d3/a2/a3,-(sp)
  154. move.w #0,-(sp) { seek from start of file }
  155. move.l handle,d0
  156. move.w d0,-(sp)
  157. move.l pos,-(sp)
  158. move.w #$42,-(sp)
  159. trap #1
  160. lea 10(sp),sp
  161. move.l d6,d2 { restore d2 }
  162. movem.l (sp)+,d3/a2/a3
  163. end;
  164. end;
  165. function do_seekend(handle:longint):longint;
  166. var
  167. t: longint;
  168. begin
  169. asm
  170. move.l d2,d6 { save d2 }
  171. movem.l d3/a2/a3,-(sp)
  172. move.w #2,-(sp) { seek from end of file }
  173. move.l handle,d0
  174. move.w d0,-(sp)
  175. move.l #0,-(sp) { with an offset of 0 from end }
  176. move.w #$42,-(sp)
  177. trap #1
  178. lea 10(sp),sp
  179. move.l d6,d2 { restore d2 }
  180. movem.l (sp)+,d3/a2/a3
  181. move.l d0,t
  182. end;
  183. do_seekend:=t;
  184. end;
  185. function do_filesize(handle : longint) : longint;
  186. var
  187. aktfilepos : longint;
  188. begin
  189. aktfilepos:=do_filepos(handle);
  190. do_filesize:=do_seekend(handle);
  191. do_seek(handle,aktfilepos);
  192. end;
  193. procedure do_truncate (handle,pos:longint);
  194. begin
  195. do_seek(handle,pos);
  196. {!!!!!!!!!!!!}
  197. end;
  198. procedure do_open(var f;p:pchar;flags:longint);
  199. {
  200. filerec and textrec have both handle and mode as the first items so
  201. they could use the same routine for opening/creating.
  202. when (flags and $100) the file will be append
  203. when (flags and $1000) the file will be truncate/rewritten
  204. when (flags and $10000) there is no check for close (needed for textfiles)
  205. }
  206. var
  207. i : word;
  208. oflags: longint;
  209. begin
  210. DoDirSeparators(p);
  211. { close first if opened }
  212. if ((flags and $10000)=0) then
  213. begin
  214. case filerec(f).mode of
  215. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  216. fmclosed : ;
  217. else
  218. begin
  219. inoutres:=102; {not assigned}
  220. exit;
  221. end;
  222. end;
  223. end;
  224. { reset file handle }
  225. filerec(f).handle:=UnusedHandle;
  226. oflags:=$02; { read/write mode }
  227. { convert filemode to filerec modes }
  228. case (flags and 3) of
  229. 0 : begin
  230. filerec(f).mode:=fminput;
  231. oflags:=$00; { read mode only }
  232. end;
  233. 1 : filerec(f).mode:=fmoutput;
  234. 2 : filerec(f).mode:=fminout;
  235. end;
  236. if (flags and $1000)<>0 then
  237. begin
  238. filerec(f).mode:=fmoutput;
  239. oflags:=$04; { read/write with create }
  240. end
  241. else
  242. if (flags and $100)<>0 then
  243. begin
  244. filerec(f).mode:=fmoutput;
  245. oflags:=$02; { read/write }
  246. end;
  247. { empty name is special }
  248. if p[0]=#0 then
  249. begin
  250. case filerec(f).mode of
  251. fminput : filerec(f).handle:=StdInputHandle;
  252. fmappend,
  253. fmoutput : begin
  254. filerec(f).handle:=StdOutputHandle;
  255. filerec(f).mode:=fmoutput; {fool fmappend}
  256. end;
  257. end;
  258. exit;
  259. end;
  260. asm
  261. movem.l d2/d3/a2/a3,-(sp) { save used registers }
  262. cmp.l #4,oflags { check if rewrite mode ... }
  263. bne @opencont2
  264. { rewrite mode - create new file }
  265. move.w #0,-(sp)
  266. move.l p,-(sp)
  267. move.w #$3c,-(sp)
  268. trap #1
  269. add.l #8,sp { restore stack of os call }
  270. bra @end
  271. { reset - open existing files }
  272. @opencont2:
  273. move.l oflags,d0 { use flag as source ... }
  274. @opencont1:
  275. move.w d0,-(sp)
  276. move.l p,-(sp)
  277. move.w #$3d,-(sp)
  278. trap #1
  279. add.l #8,sp { restore stack of os call }
  280. @end:
  281. movem.l (sp)+,d2/d3/a2/a3
  282. tst.w d0
  283. bpl @opennoerr { if positive return values then ok }
  284. cmp.w #-1,d0 { if handle is -1 CON: }
  285. beq @opennoerr
  286. cmp.w #-2,d0 { if handle is -2 AUX: }
  287. beq @opennoerr
  288. cmp.w #-3,d0 { if handle is -3 PRN: }
  289. beq @opennoerr
  290. move.w d0,errno { otherwise normal error }
  291. @opennoerr:
  292. move.w d0,i { get handle as SIGNED VALUE... }
  293. end;
  294. if errno <> 0 then
  295. begin
  296. Error2InOut;
  297. FileRec(f).mode:=fmclosed;
  298. end;
  299. filerec(f).handle:=i;
  300. if ((flags and $100) <> 0) and
  301. (FileRec (F).Handle <> UnusedHandle) then
  302. do_seekend(filerec(f).handle);
  303. end;