[fpc-pascal] More problems in Sinclair QL port (M68K)

Norman Dunbar Norman at dunbar-it.co.uk
Thu Apr 1 16:33:08 CEST 2021


Good afternoon all,

I've been working on the Sinclair QL version of the FPC runtimes and 
I've got quite a lot of progress made. Unfortunately, I've hit a problem 
with the Append() function. This is my stripped down test file showing 
the problem:

{ Program to demonstrate the Append function. }

Var f : text;

begin
   Assign (f,'ram1_test.txt');
   Append(f);
   { Fwrite(f, 'This is the second line of text'); }
   close (f);
end.

The Fwrite() call after Append() is commented out as it never gets that far.

The ram1_test.txt file already exists, and has a single line of text in 
it. When I execute the compiled program I get a runtime error 103.

Looking at the RTL code, I see the following:


 From sysfile.inc

At the end of do_open() we have the file already open in the correct 
mode (Q_OPEN -- confirmed with debugger) and this gets executed:

   { 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;


The call to do_seekend(), also in sysfile.inc, is this:

function do_seekend(handle: longint): longint;
begin
   do_seek(handle, -1);
   do_seekend := do_filepos(handle);
end;


And do_seek() is this:

procedure do_seek(handle, pos: longint);
var
   res: longint;
begin
   res := fs_posab(handle, pos);
   if res < 0 then
     Error2InOutRes(res);
end;

Finally, fs_posab() has been changed to the following, in qdos.inc:


function fs_posab(chan: Tchanid; new_pos: dword):longint; assembler; 
nostackframe; public name '_fs_posab';
asm
   { D0 = chan, D1 = new_pos! }
   move.l d3,-(sp)
   move.l chan,a0
   move.l new_pos,d1
   moveq #_FS_POSAB,d0
   moveq #-1,d3
   trap #3
   { Test for EOF, else we get runtime errors }
   cmpi.l #ERR_EF,d0
   bne.s @noteof
@eof:
   { At EOF, we need to zero D0 to clear the error. }
   moveq #0,d0
   bra.s @done
@noteof:
   tst.l d0
   bne.s  @quit
@done:
   { D1 is the new file position, unless EOF. }
   move.l d1,d0
@quit:
   move.l (sp)+,d3
end;

I changed it as I had problems with D0 being set to _FS_POSAB ($42) 
before A0 was set to the channel id, which was passed in D0 due to the 
"register" calling convention. Once I figured that out, I reorganised 
the code to that shown above to be sure that we didn't get an "invalid 
channel" error back from the OS as we were from A0 being $42 instead of 
an actual channel ID.

Another problem is that when requesting a new position which is after 
the end of the file, you get the "EOF error" code back ($FFFFFFF6 or 
-10) from the OS. This wasn't checked for in the original code, so 
caused an error exit. The code above resolves that problem.

Unfortunately, now when I exit from fs_posab() and there are no errors 
in D0, I'm still getting a runtime error 103 from the Append(F) call. 
When the code was attempting to write to the file after the Append() 
call, the second line of text was not written to the file as it barfs in 
Append().

The OS is returning the correct error code, $FFFFFFF6 or -10, for the 
seek to the end of file, and the code exits from fs_posab() with D0 
cleared of any errors when the request is for a file position bigger 
than the file size. On a QL, Close() doesn't return any errors, so it's 
definitely not there.

I've traced the fs_posab() calls through a debugger on my QL, and the 
code does as it should, it exits back to Pascal with no errors in D0 as 
it should.

Any pointers to where I should be looking are gratefully received, thanks.


Cheers,
Norm.

-- 
Norman Dunbar
Dunbar IT Consultants Ltd

Registered address:
27a Lidget Hill
Pudsey
West Yorkshire
United Kingdom
LS28 7LG

Company Number: 05132767


More information about the fpc-pascal mailing list