TNFSDRV Virtual Drive E: Progress Summary (June 2026)

Goal

Build a DOS TSR that creates a virtual drive letter (initially E:, later T:) without modifying DOS itself.

The long-term goal is:

  • E: (later T:) appears as a valid DOS drive
  • DIR works
  • README.TXT can be viewed
  • GAMES appears as a directory
  • Eventually connect the virtual filesystem to TNFS

We deliberately chose a very incremental approach with extensive logging.

Debugging Architecture

Early attempts used:

  • Screen output
  • DEBUG.TXT written directly by the TSR

This caused recursion and stability problems because DOS INT 21h services were being called from inside an INT 21h hook.

We replaced this with a memory-based ring buffer.

Components:

  • TSR allocates a ring buffer in resident memory
  • TSR writes debug messages directly into RAM
  • SHOWBUF.EXE reads the ring buffer
  • SHOWBUF can write DEBUG.TXT afterwards

Advantages:

  • No DOS calls inside the hook
  • No recursion
  • No filesystem dependency
  • Much safer debugging

Phase 1: Observe DOS

Initial TSR only logged INT 21h activity.

We discovered that:

C:
D:

generated:

AH=0E

but:

T:

generated no AH=0E at all.

Conclusion:

COMMAND.COM validates drive letters before calling Select Drive.

Phase 2: Investigating AH=29

Logging was expanded for:

AH=29 Parse Filename

Results:

D:
    AH=29
    AH=0E

E:
    AH=29
    no AH=0E

Further logging showed:

D:
    AH=29 AL=00 FCB[0]=04

E:
    AH=29 AL=FF FCB[0]=05

Conclusion:

DOS parser rejected E: before drive selection occurred.

Phase 3: AH=29 Patch

Implemented:

  • Detect input string "E:"
  • Let DOS process AH=29 normally
  • If DOS returns: AL=FF FCB[0]=05 then patch AL to 00

Result:

E:

no longer produced:

Invalid drive

and DOS now executed:

AH=0E DL=04

Phase 4: Investigating AH=0E

Logging revealed:

AH=0E return AL=1A

Meaning:

DOS already knows about 26 drives

Therefore:

  • LASTDRIVE was not the problem
  • Drive count was not the problem

Additional logging showed:

AH=19 return AL=03

even after:

E:

Conclusion:

DOS still considered D: the current drive.

Phase 5: Virtual Current Drive

Implemented TSR-managed drive state:

current_drive

Added handlers:

AH=0E  Select Drive
AH=19  Get Current Drive

Result:

E:

changed prompt to:

E:\TNFS>

and:

CD

reported:

E:\

This proved that the virtual drive selection mechanism works.

Phase 6: Directory Enumeration

Implemented:

AH=4E  FindFirst
AH=4F  FindNext

Virtual entries:

GAMES
README.TXT

Also implemented:

AH=11  FCB FindFirst
AH=12  FCB FindNext

Internal state:

find_state

States:

0 = inactive
1 = GAMES returned
2 = README returned
next = EOF

Current Behaviour

Commands tested:

DIR E:\*.*
E:
CD ..
DIR

Observed output:

CKONG     <DIR>
TXT

instead of:

GAMES
README.TXT

Logging revealed:

HANDLED AH=4E E:

but no:

HANDLED AH=4F E:

for:

DIR E:\*.*

However plain:

DIR

on E: produced:

HANDLED AH=12 E: ENTRY=1
HANDLED AH=12 E: EOF

Conclusion:

DOS is using different enumeration paths:

DIR E:\*.*  -> AH=4E
DIR         -> AH=11/12

and something is still wrong in the FindFirst result.

Additional Observations

Attempt:

CD E:\

generates:

AH=3B
AH=59

and fails.

Conclusion:

AH=3B Change Directory

is not implemented yet.

Current implementation only emulates:

E:
current drive handling

not directory navigation.

Current Working Features

Working:

  • Ring buffer debugging
  • SHOWBUF
  • AH=29 patch
  • Virtual E: drive selection
  • AH=19 current drive emulation
  • AH=47 root directory query
  • AH=36 disk free space
  • AH=4E interception
  • AH=11/12 interception

Partially working:

  • Directory enumeration

Not working yet:

  • Correct DIR output
  • CD E:\
  • CD GAMES
  • README.TXT access
  • File open/read
  • TNFS integration

Most Important Current Problem

Investigate:

Why does

    DIR E:\*.*

execute:

    AH=4E

but never:

    AH=4F

before adding more functionality.

Strong suspicion:

  • First DTA entry is malformed
  • DOS interprets it incorrectly
  • Enumeration stops after the first entry
  • Therefore FindNext is never requested

Next Session

Focus only on:

AH=4E
DTA layout
FindFirst return data

Do NOT work on:

AH=3B
README.TXT reading
file opens
TNFS

until:

DIR E:\*.*

correctly displays:

GAMES
README.TXT

and:

AH=4F

is observed in the log.