The computer, or rather its OS, has no idea about a directory, in fact not even what constructs a file. It can only open/read/write/close data streams from devices on the bus. Getting a directory is a clever hack of 'loading' a dummy program. This works since
- LOAD command is implemented as opening a data stream and loading what is returned into memory at BASIC start.
- LOAD does not perform any check on the program.
- LIST command does not perform any checks on syntax or line number sequence.
- LIST simply outputs what is in BASIC memory by stupidly transforming what is found
As result, a directory listing is quite literally a LISTing (*1).
As so often, Michael Steil did sit down and wrote a short analysis to directory listing on Commodore machines.
What I'd like to know is how these pseudo-BASIC directory listings are produced. In particular, is the disk drive itself generating a BASIC listing from the file system and passing it to the computer?
Or is the main computer querying basic file system information from the drive and then constructing the BASIC listing itself?
No, the computer, or better the OS, has in fact no idea about a floppy at all. It can access data by using open/read calls send to a device. What is received back will be interpreted as a (program) file.
On the drives side the special file name of "$" is interpreted as command to read the directory and send the data read back within the framing of "program code":
- Two bytes (offsetted) string length
- Two bytes number of blocks
- A string containing file name and alike (the quotation marks are part of that string).
- A NULL byte at the end
This gets repeated until
- Three NULL in a row (like end of line and next pointer being both NULL) to terminate it.
Also, is the listing really represented in the computer's memory as a (non-functional) BASIC program with line numbers,
or is it stored in a dedicated format that the LIST command detects and specially parses?
Again, the computer has no idea about things like directories, not even what floppy is, only devices that respond to open/read/write/close instructions on the expansion bus.
It is a rather clever hack to add the functionality of a directory listing to a machine that has no higher level functions beyond initiating and acting upon data streams on the (serial) IEC bus.
It wasn't until after the C64 that Commodore BASIC got a bit more sophisticated by adding disk commands; except they were for most parts just syntactical sugar on top of existing commands/workings.
If the directory is stored as a BASIC program, how is it that two lines can start with the same line number (as is the case when two files have the same size)?
Because the LIST command does not do any syntax or sequence checks. It simply starts at $801 and interprets all bytes as BASIC code. No syntax or sequence checks at all. So whatever bytes are found at the position of a line number is turned from their 16 bit value into readable (ASCII) decimal.
*1 - Wouldn't be surprised if that naming similarity made way to that idea :)