diff --git a/include/dos_inc.h b/include/dos_inc.h index b2d2b868..43ba1d15 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -97,6 +97,7 @@ bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); /* Routines for Drive Class */ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); +bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); bool DOS_UnlinkFile(char * name); bool DOS_FindFirst(char *search,Bit16u attr); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index c7c548a6..fc6da360 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -833,7 +833,13 @@ static Bitu DOS_21Handler(void) { break; } case 0x6c: /* Extended Open/Create */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF); + if (DOS_OpenFileExtended(name1,reg_bx,reg_cx,reg_dx,®_ax,®_cx)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } break; case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a5babc4b..95f7ae07 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -370,6 +370,32 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } +bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) +// FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error +{ + Bit16u result = 0; + if (DOS_OpenFile(name, flags, entry)) { + // File already exists + switch (action & 0x0f) { + case 0x00 : return false; // failed + case 0x01 : result = 1; break; // file open (already done) + case 0x02 : DOS_CloseFile(*entry); // replace + if (!DOS_CreateFile(name, flags, entry)) return false; + result = 3; + break; + default : E_Exit("DOS: OpenFileExtended: Unknown action."); + }; + } else { + // File doesnt exist + if ((action & 0xf0)==0) return false; + // Create File + if (!DOS_CreateFile(name, flags, entry)) return false; + result = 2; + }; + *status = result; + return true; +}; + bool DOS_UnlinkFile(char * name) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false;