INT 21h AH=39h creates one directory, what MD (MKDIR) does at the prompt. The name at DS:DX ends with a 0 byte, not with "$": all the DOS services that take a path use ASCIIZ strings, and only the console's 09h uses "$". The path can be relative to the current directory (TESTDIR, SUB\NEW) or absolute (\TOOLS\NEW, C:\TOOLS\NEW), up to 64 characters, and each part is an 8.3 name.
Only the last part of the path is created. Every directory before it must exist, or the call fails with error 3.
| AX (CF = 1) | Why |
|---|---|
| 3 | path not found: a directory on the way does not exist, or the name is not valid |
| 5 | access denied: a file or directory of that name exists, the parent directory is full, or the disk is write-protected |
A FAT disk's root directory has a fixed number of entries (112 on a 360 KB floppy, 512 on a hard disk), so making one more directory there fails with 5 even when the disk has room. Subdirectories grow as needed. The example makes TESTDIR, tries again, and removes it:
MOV DX, OFFSET MKM1MOV AH, 09hINT 21hMOV AH, 39h ; DOS: make the directory named at DS:DXMOV DX, OFFSET DIR1INT 21hCALL RESULT ; okMOV DX, OFFSET AGAINM1MOV AH, 09hINT 21hMOV AH, 39hMOV DX, OFFSET DIR1INT 21hCALL RESULT ; error 5: it exists nowMOV DX, OFFSET RMM1MOV AH, 09hINT 21hMOV AH, 3Ah ; DOS: remove it againMOV DX, OFFSET DIR1INT 21hCALL RESULTDIR1 DB "TESTDIR", 0MKM1 DB "mkdir TESTDIR: $"AGAINM1 DB "mkdir TESTDIR again: $"RMM1 DB "rmdir TESTDIR: $"RESULT PROC NEAR ; print "ok", or "error" and AX when CF = 1PUSHF ; keeps AX and CF for the callerPUSH AXMOV DX, OFFSET OKMSGJNC RESULT1MOV DX, OFFSET ERRMSGMOV AH, 09hINT 21hPOP AXPUSH AXCALL PDEC ; the error codeMOV DX, OFFSET CRLFRESULT1:MOV AH, 09hINT 21hPOP AXPOPFRETRESULT ENDPOKMSG DB "ok", 13, 10, "$"ERRMSG DB "error $"PDEC PROC NEAR ; print AX in decimal (changes AX BX CX DX)MOV BX, 10XOR CX, CX ; digits on the stackPDEC1:XOR DX, DXDIV BX ; AX = AX / 10, DX = the last digitPUSH DXINC CXOR AX, AXJNZ PDEC1PDEC2:POP DX ; the digits come back first to lastADD DL, "0"MOV AH, 02hINT 21hLOOP PDEC2RETPDEC ENDPCRLF DB 13, 10, "$"
Making a whole path
To create several levels, make each in turn and treat error 5 on the way as "already there":
MOV AH, 39hMOV DX, OFFSET LEVEL1 ; "OUT", 0INT 21h ; error 5 is fine: it existsMOV AH, 39hMOV DX, OFFSET LEVEL2 ; "OUT\LOGS", 0INT 21h
In DOSBox-X a drive mounted from a host folder gets a real folder on the host. The name is stored as DOS gives it, in capitals; with long file names enabled, function 7139h of INT 21h makes directories with long names.