123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2005 by Free Pascal development team
- Low level file functions
- 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.
- **********************************************************************}
- {$asmmode motorola}
- {****************************************************************************
- Low Level File Routines
- ****************************************************************************}
- procedure DoDirSeparators(p:pchar);
- var
- i : longint;
- begin
- { allow slash as backslash }
- for i:=0 to strlen(p) do
- if p[i] in AllowDirectorySeparators then p[i]:=DirectorySeparator;
- end;
- procedure do_close(h : longint);
- begin
- asm
- movem.l d2/d3/a2/a3,-(sp)
- move.l h,d0
- move.w d0,-(sp)
- move.w #$3e,-(sp)
- trap #1
- add.l #4,sp { restore stack ... }
- movem.l (sp)+,d2/d3/a2/a3
- end;
- end;
- procedure do_erase(p : pchar);
- begin
- DoDirSeparators(p);
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp) { save regs }
- move.l p,-(sp)
- move.w #$41,-(sp)
- trap #1
- add.l #6,sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- tst.w d0
- beq @doserend
- move.w d0,errno
- @doserend:
- end;
- if errno <> 0 then
- Error2InOut;
- end;
- procedure do_rename(p1,p2 : pchar);
- begin
- DoDirSeparators(p1);
- DoDirSeparators(p2);
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.l p1,-(sp)
- move.l p2,-(sp)
- clr.w -(sp)
- move.w #$56,-(sp)
- trap #1
- lea 12(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- tst.w d0
- beq @dosreend
- move.w d0,errno { error ... }
- @dosreend:
- end;
- if errno <> 0 then
- Error2InOut;
- end;
- function do_isdevice(handle:word):boolean;
- begin
- if (handle=stdoutputhandle) or (handle=stdinputhandle) or
- (handle=stderrorhandle) then
- do_isdevice:=FALSE
- else
- do_isdevice:=TRUE;
- end;
- function do_write(h,addr,len : longint) : longint;
- begin
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.l addr,-(sp)
- move.l len,-(sp)
- move.l h,d0
- move.w d0,-(sp)
- move.w #$40,-(sp)
- trap #1
- lea 12(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- tst.l d0
- bpl @doswrend
- move.w d0,errno { error ... }
- @doswrend:
- move.l d0,@RESULT
- end;
- if errno <> 0 then
- Error2InOut;
- end;
- function do_read(h,addr,len : longint) : longint;
- begin
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.l addr,-(sp)
- move.l len,-(sp)
- move.l h,d0
- move.w d0,-(sp)
- move.w #$3f,-(sp)
- trap #1
- lea 12(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- tst.l d0
- bpl @dosrdend
- move.w d0,errno { error ... }
- @dosrdend:
- move.l d0,@Result
- end;
- if errno <> 0 then
- Error2InOut;
- end;
- function do_filepos(handle : longint) : longint;
- begin
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.w #1,-(sp) { seek from current position }
- move.l handle,d0
- move.w d0,-(sp)
- move.l #0,-(sp) { with a seek offset of zero }
- move.w #$42,-(sp)
- trap #1
- lea 10(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- move.l d0,@Result
- end;
- end;
- procedure do_seek(handle,pos : longint);
- begin
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.w #0,-(sp) { seek from start of file }
- move.l handle,d0
- move.w d0,-(sp)
- move.l pos,-(sp)
- move.w #$42,-(sp)
- trap #1
- lea 10(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- end;
- end;
- function do_seekend(handle:longint):longint;
- var
- t: longint;
- begin
- asm
- move.l d2,d6 { save d2 }
- movem.l d3/a2/a3,-(sp)
- move.w #2,-(sp) { seek from end of file }
- move.l handle,d0
- move.w d0,-(sp)
- move.l #0,-(sp) { with an offset of 0 from end }
- move.w #$42,-(sp)
- trap #1
- lea 10(sp),sp
- move.l d6,d2 { restore d2 }
- movem.l (sp)+,d3/a2/a3
- move.l d0,t
- end;
- do_seekend:=t;
- end;
- function do_filesize(handle : longint) : longint;
- var
- aktfilepos : longint;
- begin
- aktfilepos:=do_filepos(handle);
- do_filesize:=do_seekend(handle);
- do_seek(handle,aktfilepos);
- end;
- procedure do_truncate (handle,pos:longint);
- begin
- do_seek(handle,pos);
- {!!!!!!!!!!!!}
- end;
- procedure do_open(var f;p:pchar;flags:longint);
- {
- 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
- i : word;
- oflags: longint;
- begin
- DoDirSeparators(p);
- { 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;
- oflags:=$02; { read/write mode }
- { convert filemode to filerec modes }
- case (flags and 3) of
- 0 : begin
- filerec(f).mode:=fminput;
- oflags:=$00; { read mode only }
- end;
- 1 : filerec(f).mode:=fmoutput;
- 2 : filerec(f).mode:=fminout;
- end;
- if (flags and $1000)<>0 then
- begin
- filerec(f).mode:=fmoutput;
- oflags:=$04; { read/write with create }
- end
- else
- if (flags and $100)<>0 then
- begin
- filerec(f).mode:=fmoutput;
- oflags:=$02; { read/write }
- 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;
- asm
- movem.l d2/d3/a2/a3,-(sp) { save used registers }
- cmp.l #4,oflags { check if rewrite mode ... }
- bne @opencont2
- { rewrite mode - create new file }
- move.w #0,-(sp)
- move.l p,-(sp)
- move.w #$3c,-(sp)
- trap #1
- add.l #8,sp { restore stack of os call }
- bra @end
- { reset - open existing files }
- @opencont2:
- move.l oflags,d0 { use flag as source ... }
- @opencont1:
- move.w d0,-(sp)
- move.l p,-(sp)
- move.w #$3d,-(sp)
- trap #1
- add.l #8,sp { restore stack of os call }
- @end:
- movem.l (sp)+,d2/d3/a2/a3
- tst.w d0
- bpl @opennoerr { if positive return values then ok }
- cmp.w #-1,d0 { if handle is -1 CON: }
- beq @opennoerr
- cmp.w #-2,d0 { if handle is -2 AUX: }
- beq @opennoerr
- cmp.w #-3,d0 { if handle is -3 PRN: }
- beq @opennoerr
- move.w d0,errno { otherwise normal error }
- @opennoerr:
- move.w d0,i { get handle as SIGNED VALUE... }
- end;
- if errno <> 0 then
- begin
- Error2InOut;
- FileRec(f).mode:=fmclosed;
- end;
- filerec(f).handle:=i;
- if ((flags and $100) <> 0) and
- (FileRec (F).Handle <> UnusedHandle) then
- do_seekend(filerec(f).handle);
- end;
|