Assembly Disc Access Primer, a TatungBytes course: DISKMON reading the hidden sector IDs of the course's own practice disc, on a rainbow sunburst
← Back to Modules
module
16

The Directory, by Hand

Introduction

DIR is the DOS reading the directory for you. DISKMON can now read any sector - so it can read the directory, and list the files, itself.

Four Sectors, Sixty-Four Entries

READDIR reads track 2, sectors 0 to 3, one after another into DIRBUF, 512 bytes apart: 2,048 bytes, 64 entries. It moves the address on by adding 2 to H - 512 is 200h - and keeps its counter and address on the stack across each call, since call 162 changes BC and HL.

CMDD walks the 64 entries with IX, 32 bytes at a time. An entry whose byte 0 is E5h is empty or deleted; every other one is shown by SHOWENT: the name and extension (each byte without its top bit, since bit 7 of byte 9 is the locked flag), a * if locked, the extent (byte 12) and the record count (byte 15).

PDEC prints a number in decimal, using DIV10 - the Z80 has no divide instruction, so DIV10 does long division by 10 a bit at a time.

The Code

After the line JP Z,CMDNXT, add:

        CP 'D'
        JP Z,CMDD

After the last line of DISCERR (JP CRMAIN), add:

; D d: list the files on drive d by reading the directory itself.
CMDD:   CALL GETNUM
        JP C,WHAT
        LD (SDRV),A
        CALL READDIR
        JP NZ,DISCERR
        LD IX,DIRBUF
        LD B,64
CMDD1:  PUSH BC
        LD A,(IX+0)
        CP 0E5H                 ; E5h: an empty or deleted slot
        JR Z,CMDD2
        CALL SHOWENT
CMDD2:  LD DE,32
        ADD IX,DE
        POP BC
        DJNZ CMDD1
        JP MAIN

; READDIR: track 2 sectors 0-3 of drive SDRV into DIRBUF. Z if all read.
READDIR: LD A,2
        LD (STRK),A
        LD HL,DIRBUF
        LD B,0
RD1:    PUSH BC
        PUSH HL
        LD A,B
        LD (SSEC),A
        CALL SETPAD
        POP HL
        LD (0FB53H),HL          ; this sector's place in DIRBUF
        PUSH HL
        RST 8
        DEFB 162
        POP HL
        POP BC
        RET NZ
        INC H                   ; 512 bytes on: H + 2
        INC H
        INC B
        LD A,B
        CP 4
        JR NZ,RD1
        XOR A                   ; Z: all four read
        RET

; SHOWENT: one directory entry at IX: name, extent, record count.
SHOWENT: PUSH IX
        POP HL
        INC HL
        LD B,8
        CALL PNAME
        LD A,'.'
        CALL PUTC
        LD B,3
        CALL PNAME
        BIT 7,(IX+9)
        LD A,' '
        JR Z,SE1
        LD A,'*'                ; bit 7 of byte 9: locked
SE1:    CALL PUTC
        LD HL,EXTM
        CALL PRINT
        LD L,(IX+12)
        LD H,0
        CALL PDEC
        LD HL,RECM
        CALL PRINT
        LD L,(IX+15)
        LD H,0
        CALL PDEC
        JP NEWLINE

; PNAME: print B name characters from HL, without their top bits.
PNAME:  LD A,(HL)
        AND 7FH
        CALL PUTC
        INC HL
        DJNZ PNAME
        RET

After the line BADM: DEFB ': BAD DATA',13,10,0, add:

EXTM:   DEFB ' EXTENT ',0
RECM:   DEFB ' RECORDS ',0

Run it with a copy of FILES.DSK, from Inside the Einstein: The Disc, in drive 1:

D 1

What you should see

> D 1
README  .TXT* EXTENT 0 RECORDS 1
STORY   .TXT  EXTENT 0 RECORDS 128
STORY   .TXT  EXTENT 1 RECORDS 29
NUMBERS .BIN  EXTENT 0 RECORDS 24
DISKMON .COM  EXTENT 0 RECORDS 13
>

One line per entry, not per file: STORY.TXT is over 16K, so it has two. And the * on README.TXT is bit 7 of its byte 9.

Change One Thing

  • Remove the CP 0E5H test. What will D 1 print for the empty slots?
  • Make DISKMON print each file once, not once per extent. (Hint: only entries whose extent is 0.)

Summary

DISKMON reads the directory with four MOS calls and decodes the entries itself: the DOS's DIR, done by hand.

Next

S17 follows an entry's blocks to the file's data.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.