TL;DR:
There may be a bug in SMSQ where FS_POSAB/IOF_POSA is called to set a new position beyond EOF for a file. The new file position returned in D1 is always zero in this case, and subsequent calls to FS_POSRE/IOF_POSR with an offset of zero also return zero as the current file position in D1. This problem does not occur when FS_POSAB/IOF_POSA is called with a new position which is within the bounds of the file.
If the file is 100 bytes long, calling FS_POSAB/IOF_POSA with a position of anything between 0 and 100 will return D1 correctly set. Subsequent calls to FS_POSRE with an offset of zero return the current position.
If the call to FS_POSAB/IOF_POSA is greater than 100, D1 is returned as zero, the file's new position is not set at EOF, D0 is returned set to ERR_EF (-10) to indicate EOF, but the file position doesn't change. Subsequent calls to FS_POSRE/IOF_POSR return zero.
The above assumes that the file is open in mode 0, OLD_EXCLUSIVE mode.
Gory Details:
The Pascal Append() function opens the file in Q_OPEN mode, (=0 = OPEN in SuperBASIC), which is fine. It then calls fs_posab/iof_posa to set the file position to $FFFFFFFF which works, but as this is beyond EOF, it returns D1 set to 0 and not as the new file position. It then calls fs_posre/iof_posr with an offset of 0 to get the current file position.
Scenario 1:
When the fs_posab/iof_posa new position is within the bounds of the file, D1 returns with the new file position correctly set. If I request position 2, it comes back from fs_posab/iof_posa set to 2. When I subsequently call fs_posre/iof_posr with an offset of zero, it comes back with D1 = 2. All is well and correct.
Scenario 2:
When the fs_posab/iof_posa new position is past the current EOF, D1 returns with the value zero. This is not correct!. When I subsequently call fs_posre/iof_posr with an offset of zero, it comes back with D1 = 0. All is not at well and is incorrect.
So, this small Pascal file:
Code: Select all
{ Program to demonstrate the Append function. }
Var f : text;
begin
Assign (f,'ram1_test.txt');
Rewrite(f);
Writeln(f, 'This is the first line of text.');
close(f);
Append(f);
Writeln(f,'This is the second line of text.');
close (f);
end.
If, on the other hand, I use QMON to break into setting the fs_posab position, and change D1 from $FFFFFFFF to $10, for example, or any other valid "in bounds" value, the text is correctly appended at that position.
I had a suspicion that Pascal was making a call to fs_truncate with the position returned from fs_posre but I tested this and it doesn't call fs_truncate, so that went out the window. I knocked up an assembly test instead:
Code: Select all
Open moveq #io_open,d0
moveq #-1,d1
moveq #3,d3 ; OPEN_OVER
lea file,a0
trap #2
nop
Reset moveq #io_sstrg,d0
moveq #11,d2
moveq #-1,d3
lea digits,a1
trap #3
nop
Close_1 moveq #io_close,d0
trap #2
nop
ReOpen moveq #io_open,d0
moveq #-1,d1
moveq #0,d3 ; OPEN
lea file,a0
trap #2
nop
Posab moveq #fs_posab,d0
moveq #-1,d1
trap #3
nop
Posre moveq #fs_posre,d0
moveq #0,d1
trap #3
nop
Append moveq #io_sstrg,d0
moveq #27,d2
moveq #-1,d3
lea letters,a1
trap #3
nop
Close_2 moveq #io_close,d0
trap #2
nop
Exit rts
file dc.w file_end-file-2
dc.b 'ram1_test'
file_end equ *
digits dc.b '1234567890',$0a
letters dc.b 'AbcdeFghijkLmnopQrstuVwxyz',$0a
When I traced this through, I got the same problem, fs_posab/iof_posa returned zero in D1, fs_posre/iof_posr did the same, and the only text in the file were the letters. I think we have a bug in SMSQ (or QPC's version) where D1 is not being correctly returned when a file is opened, positioned at EOF using fs_posab/iof_posa with D1 set to $FFFFFFFF, then calling fs_posre/iof_posr with a relative position of zero to get current file position. I suspect fs_posab/iof_posa is not setting the new file position if EOF errors are reported?
Cheers,
Norm.