The following program reads the directory and prints it on the screen. This was intentionally NOT broken down into subroutines (GOSUB/RETURN), for simplicity's sake.
The CBM directory structure is broken down exactly like a BASIC program.
The first two bytes of the file are the load address and can be safely discarded (1010).
Lines 1100-1050 read the line link (the address of the next line in memory) and discard those, as well. The file size is a two-byte integer, which we have to read in low-high order. This is why the H*256+L in line 1140.
Then we can read the disk title. This is just PETSCII text, prefixed with the Reverse symbol. So I read up to the next quote symbol, turn off RVS, and finish out the line.
Line 1210 is my standard practice for getting a byte out of a file. The program not only needs to read from disk, but needs to check for zero bytes. Since a zero byte is read as an empty string (""), the program checks for this and assigns A the PETSCII value. This allows us to check for special characters later. (Yes, this can be simplified for performance.)
BASIC lines end with a zero byte, so line 1220 finishes the line when we read a zero.
Finally, the main loop:
1300-1360 reads the link and file size, then prints them on the screen.
1400-1490 trims the leading spaces and prints the text of the filename and date.
1500-1550 is just a "raw read" routine that we don't need, but I left in as an example of reading hex data from the disk.
9000: don't forget to close your files, or you'll run out of channels pretty quickly. The only way to recover from that is a reset.
0 REM READ DIRECTORY IN BASIC
5 COLOR 1,6
10 OPEN 8,8,0,"$=T"
1000 REM READ 2 BYTES AND DISCARD
1010 GET#8,A$:GET#8,A$
1100 REM READ LINK AND FILE SIZE
1110 GET#8,A$:GET#8,A$
1120 L=0:GET#8,A$:IF A$<>"" THEN L=ASC(A$)
1130 H=0:GET#8,A$:IF A$<>"" THEN H=ASC(A$)
1140 FS=H*256+L
1150 PRINT FS;
1200 REM READ DISK TITLE
1210 GET#8,A$:A=0:IF A$<>""THEN A=ASC(A$)
1220 IF A=0 THEN PRINT: GOTO 1300
1230 PRINT A$;
1240 IF A=34 THEN PRINT "\X92";
1270 IF ST=0 THEN 1210
1300 REM READ LINK AND FILE SIZE
1310 GET#8,A$:GET#8,A$
1320 L=0:GET#8,A$:IF A$<>"" THEN L=ASC(A$)
1330 H=0:GET#8,A$:IF A$<>"" THEN H=ASC(A$)
1340 FS=H*256+L
1350 PRINT FS;
1360 IF ST<>0 THEN 9000
1400 REM READ FILENAME
1410 PRINT TAB(5);
1420 GET#8,A$:A=0:IF A$<>""THEN A=ASC(A$)
1430 IF A<>32 THEN 1460
1440 GOTO 1420
1450 GET#8,A$:A=0:IF A$<>""THEN A=ASC(A$)
1460 IF A=0 THEN PRINT : GOTO 1300
1470 PRINT A$;
1480 IF ST<>0 THEN 9000
1490 GOTO 1450
1500 REM DEBUG - READ RAW DATA
1510 GET#8,A$:A=0:IF A$<>""THEN A=ASC(A$)
1520 IF A>=32 AND A<128 THEN PRINT A$;:GOTO 1340
1530 PRINT "\XCD";HEX$(A);
1540 IF ST=0 THEN 1310
1550 RETURN
9000 CLOSE 8
9101 END