INT 21h AH=5Bh is INT 21h AH=3Ch with a safety catch. If no file of that name exists, it creates one and returns a handle open for reading and writing, exactly as 3Ch does. If one exists, nothing is touched and the call fails with CF = 1 and AX = 50h, "file exists". The function came with DOS 3.0; DOS 2 does not have it.
Why not test first with INT 21h AH=3Dh and create when the open fails? Because between the test and the create another program (a TSR, or another machine on a network) can make the file. 5Bh checks and creates in one step, and that makes it the tool for lock files: whoever creates LOCK.TMP first owns the resource, everyone after gets 50h until the owner deletes it.
MOV AH, 5Bh ; DOS: create TEST.TXT, which must be newXOR CX, CXMOV DX, OFFSET FNAMEINT 21hCALL CHECKMOV BX, AXMOV AH, 3Eh ; close itINT 21hMOV DX, OFFSET M1MOV AH, 09h ; DOS: print the string at DS:DXINT 21hMOV DX, OFFSET M2MOV AH, 09h ; DOS: print the string at DS:DXINT 21hMOV AH, 5Bh ; again: now the file existsXOR CX, CXMOV DX, OFFSET FNAMEINT 21hCALL REPORT ; CF = 1, AX = 50hMOV AH, 41h ; delete TEST.TXTMOV DX, OFFSET FNAMEINT 21hFNAME DB "TEST.TXT", 0M1 DB "first 5Bh: created", 13, 10, "$"M2 DB "second 5Bh: $"CRLF DB 13, 10, "$"CHECK PROC NEAR ; CF = 1: print the error code in AL and exitJNC CHECK1PUSH AXMOV DX, OFFSET FAILMSGMOV AH, 09hINT 21hPOP AXCALL PHEXBMOV AX, 4C01h ; exit with code 1INT 21hCHECK1:RETCHECK ENDPFAILMSG DB "failed: error $"REPORT PROC NEAR ; CF = 0: "ok"; CF = 1: "error" and ALJC REPORT1MOV DX, OFFSET OKMSGMOV AH, 09hINT 21hRETREPORT1:PUSH AXMOV DX, OFFSET ERRMSGMOV AH, 09hINT 21hPOP AXCALL PHEXB ; the error codeMOV DX, OFFSET CRLFMOV AH, 09hINT 21hRETREPORT ENDPOKMSG DB "ok", 13, 10, "$"ERRMSG DB "error $"PHEXB PROC NEAR ; print AL as two hex digitsPUSH CXPUSH DXMOV DH, AL ; keep the byteMOV CL, 4SHR AL, CL ; the high digit firstMOV CX, 2PHEXB1:AND AL, 0FhADD AL, "0"CMP AL, "9"JBE PHEXB2ADD AL, 7 ; 10..15 -> "A".."F"PHEXB2:MOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hMOV AL, DH ; then the low digitLOOP PHEXB1POP DXPOP CXRETPHEXB ENDP
The other errors are those of 3Ch: 03h for a directory in the path that does not exist, 04h when no handle is free, 05h when the directory cannot take another entry. 50h is the only new one, and it is the one a lock-file loop waits on.
Relatives
DOS 3 also added 5Ah, which creates a file with a unique name in a given directory and writes the chosen name back into your buffer: the way to make a temporary file. DOS 4 added 6Ch, extended open / create, which does the work of 3Ch, 3Dh and 5Bh in one call, with flags that say what to do when the file exists and when it does not.
DOSBox-X implements 5Bh as an open to test, then a create. A DOS program gets the same answers; only a host program changing the same folder at the same instant could slip in between.