Personal Computer News


QL Headers

 
Published in Personal Computer News #092

Alan Turnbull explains how you can make better use of headers on the QL.

QL: Inside The Header

Alan Turnbull explains how you can make better use of headers on the QL

Among QODS system calls documented in the QDOS manuals is one which reads 'header' details from QL Microdrive files. These headers hold information not listed when you take a simple directory listing of a cartridge. The headers can accommodate file length, file access flag, file type, file-dependent information, file name and date information.

Currently, QDOS uses neither the file access flag nor the date information. Presumably, these would offer file access privilege protection and extended directories, including date and time when saved, as provided on 'proper' disk operating systems.

At the moment, QDOS recognises only two types of file: those generated by SAVE (for Basic), SBYTES (for code) or PRINT# (for data), and those which are generated by SEXEC (for 'transient', multi-tasking machine code programs).

In the case of Basic, code and data files, the only information held in the header besides the file name is the length of the file itself, in bytes. For transient programs, the default size of their data spaces is held as well.

The machine code program for the MC68008 processor in Listing 1 reads headers from QL Microdrive cartridges. It has three main parts. First, a channel is opened by calling the QDOS system routine IO OPEN using TRAP 2 with registers D0 = 1 (to identify which system routine is required); D1 = -1 (to specify the current 'job' - that is, the SuperBasic command processor; D3 = 0 to signal that an old, exclusive file is to be opened and A0 pointing to the channel name in the format "mdv1_somename". The system call opens the channel and returns the channel ID in A0. This channel ID is subsequently held in A0 and used by the following system calls.

Second, the file header is read into a 64-byte buffer in memory so that a SuperBasic program may examine it. This requires a call to QDOS system routine FS HEADR using TRAP 3 with D0 = 71; D2 = 64 (the memory buffer length); D3 = -1 (the 'time-out' value needed by the serial access routines); the channel ID in A0 and A1 holding a pointer to the memory buffer itself.

Lastly, the channel created by IO OPEN using the temporary channel ID in A0 is closed by a call to IO CLOSE using TRAP 2 with D0 = 2.

To use the machine code routine properly, a SuperBasic program is also needed. The program in Figure 2 uses the machine code (held in DATA statements) to print out the header information for each file found on QL Microdrive 'mdv1'. It uses 'mdv2' as a temporary store for the DIRectory listing from 'mdv1'. This is stored on cartridge and read back, one file name at a time.

The file names are put into the table required by the machine code and the routine is called to read the header for that file direct from the cartridge.

When this is finished (and it is quite fast), the header may be examined as it now lies in memory above the original machine code.

The header, when read into memory, starts at (start of machine code)+96 and the file length is held as a long word (four bytes) at this position. The file type is stored as the sixth byte in the header, so is at an offset 101 bytes from the machine code start.

For transient programs, the default data space size is held as a long word starting at the seventh byte in the header and so is at (start of machine code)+102.

Of course, the routines presented here would be of more use when files are saved with date and file protection information. But you should now know how to write simple utility programs in conjunction with the QDOS Manual.

Alan Turnbull