Page 1 of 1

Help with FS.HEADR call

Posted: Fri Oct 23, 2020 7:09 am
by chernandezba
Hi

In my ZEsarUX emulator I handle the QDOS microdrive calls to emulate them to use computer files, instead of microdrives. I'm trying to understand how the FS. HEADR call works.

The parameters, as I read in the "QL Technical Guide" are:

Call:

D2.W buffer length
D3.W timeout
A0 channel lD
A1 base of read buffer

Return:

D1.W length of header read
A1 top of read buffer

First, I don't understand the difference between "A1 base of read buffer" and "A1 top of read buffer". What is the difference between "base" and "top" in this case?
Also, what are the header fields returned? The info says "The buffer provided must be at least 14 bytes long."

Are these 14 bytes the first 14 of the 64-byte header:

00 long file length
04 byte file access key (not yet implemented - currently always zero)
05 byte file type
06 8 bytes file type-dependent information
0E 2+36 bytes filename
34 long reserved for update date (not yet implemented)
38 long reserved for reference date (not yet implemented)
3c long reserved for backup date (not yet implemented)

So the call returns until the first 14:

00 long file length
04 byte file access key (not yet implemented - currently always zero)
05 byte file type
06 8 bytes file type-dependent information

Is that right?

I hope someone can help me with this. Thanks a lot!

Cheers
Cesar

Re: Help with FS.HEADR call

Posted: Fri Oct 23, 2020 8:27 am
by tofro
chernandezba wrote:Hi

In my ZEsarUX emulator I handle the QDOS microdrive calls to emulate them to use computer files, instead of microdrives. I'm trying to understand how the FS. HEADR call works.

The parameters, as I read in the "QL Technical Guide" are:

Call:

D2.W buffer length
D3.W timeout
A0 channel lD
A1 base of read buffer

Return:

D1.W length of header read
A1 top of read buffer


Is that right?

I hope someone can help me with this. Thanks a lot!

Cheers
Cesar
Well,

on entry a1 needs to point to the lowest byte of the buffer, d2 contains how many bytes you want (min 14, max. 64).

The function transfers max. d2 bytes from the header to the buffer, on return a1 points to the byte behind the last transferred byte in the buffer, d1 holds the number of bytes that were actually moved to the buffer.

The call and return values could look much simpler if QDOS weren't a multi-tasking system: The apparently weird format stems from the fact that all QDOS I/O functions also have a timeout, i.e. the number of 1/50s frames the function should try and obtain the result before returning with a "NOT COMPLETE" status code.

The parameters are laid out in a way that the caller can, for example, specify a timeout of 3 frames and issue the trap. QDOS will try to get some result from the file system within the next 3*0.02s and return whatever it got in this time span. The function will return with a "NOT COMPLETE" status code, but whatever QDOS managed to do in this short time frame will be reflected in the return values. The call and return parameters are laid out in a way that the caller can simply "re-arm" d2 and do the trap again with otherwise unchanged registers to retrieve "the rest" it didn't get on the first call.

"Does this make sense?", you might ask. Well, maybe not so much for only 64 bytes of a header. For large file read actions, this behaviour even makes sense on a local file, for network files (remember, the QL supports a network) it even might make sense for the FS.HEADR call. The call parameters are set up in a way that the application can ask the OS to "get me as much as you can (but not more than d1 bytes) in the next d0 ticks" and get a useful answer. When "as much as you can" was not enough to your liking, you can simply re-do the trap with "but I want d2 bytes more". You rarely see this fully used in applications, but the OS does support it (BTW: The read() system call in Unix works pretty much the same).

Re: Help with FS.HEADR call

Posted: Tue Oct 27, 2020 5:11 pm
by chernandezba
Thanks

But my doubts are with:

"
First, I don't understand the difference between "A1 base of read buffer" and "A1 top of read buffer". What is the difference between "base" and "top" in this case?
Also, what are the header fields returned? The info says "The buffer provided must be at least 14 bytes long."
"

Re: Help with FS.HEADR call

Posted: Tue Oct 27, 2020 7:19 pm
by martyn_hill
Hi!

Another way to explain the use of A1 for these QDOS string-fetch type calls is:

On entry: a1 -> the first location/base of your buffer to receive whatever characters are available from the device (up to d2.w bytes)
On exit: a1 -> the location _after_ the last one actually populated by the last string-fetch-call. It's handy as you can then just repeat the call without adjusting these two parameters to collect the 'rest' of what you expected on the earlier call - assuming that not all the available characters could be returned in one TRAP #3 invocation.

The reference to '14 bytes' might be a bit confusing in that only the 'simple serial' type QDOS devices use the 14-byte header format which is basically the first 14-bytes subset of the full 64-byte header format used by 'file-system' type device as documented earlier:
00 long file length
04 byte file access key (not yet implemented - currently always zero)
05 byte file type
06 8 bytes file type-dependent information

<<only FS-type devices use the following>>

0E 2+36 bytes filename
34 long reserved for update date (not yet implemented)
38 long reserved for reference date (not yet implemented)
3c long reserved for backup date (not yet implemented)
Any clearer?

Re: Help with FS.HEADR call

Posted: Tue Oct 27, 2020 7:29 pm
by tofro
chernandezba wrote:Thanks

But my doubts are with:

"
First, I don't understand the difference between "A1 base of read buffer" and "A1 top of read buffer". What is the difference between "base" and "top" in this case?
Also, what are the header fields returned? The info says "The buffer provided must be at least 14 bytes long."
"
before:
a1 = buffer pointer
d2 = bytes wanted

after:
d1 = bytes actually put into buffer
a1 = before a1 + d1

"top of read buffer" simply means "one byte after the last byte transferred to buffer", i.e the end of the bytes transferred from the file header to the buffer - normally (with d0 == 0), the caller wouldn't even use this. Don't know how I could explain this better.

The header format is

Code: Select all

$00 long file length
$04 byte file access key (not yet implemented - currently byte always zero)
$05 byte file type
$06 8 bytes file type-dependent information
$0E 2+36 bytes filename (first 2 bytes are the length of the name)
$34 long reserved for update date (not yet implemented)
$38 long  reserved for reference date (not yet implemented)
$3C long  reserved for backup date (not yet implemented)
All the fields marked as "not yet implemented" except the "access key" are actually used for the intended purpose when Toolkit 2 or a specific backup software is used.

The file types (byte at offset $5) are:

Code: Select all

2:   relocatable object file;
1:   executable program; 
255  directory
0    anything else.
Executable files (type == 1) have the amount of data space in the first longword of the "type dependent information"

Re: Help with FS.HEADR call

Posted: Wed Oct 28, 2020 7:23 am
by chernandezba
Thanks everyone! Lot easier now :)

Cheers
Cesar