DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/dos_inc.h
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 
00020 #ifndef DOSBOX_DOS_INC_H
00021 #define DOSBOX_DOS_INC_H
00022 
00023 #include <stddef.h>
00024 #define CTBUF 127
00025 
00026 #ifndef DOSBOX_DOS_SYSTEM_H
00027 #include "dos_system.h"
00028 #endif
00029 #ifndef DOSBOX_MEM_H
00030 #include "mem.h"
00031 #endif
00032 #include <stddef.h> //for offsetof
00033 
00034 #ifdef _MSC_VER
00035 #pragma pack (1)
00036 #endif
00037 struct CommandTail{
00038   Bit8u count;                          /* number of bytes returned */
00039   char buffer[CTBUF];           /* the buffer itself */
00040 } GCC_ATTRIBUTE(packed);
00041 #ifdef _MSC_VER
00042 #pragma pack ()
00043 #endif
00044 
00045 extern Bit16u first_umb_seg;
00046 extern Bit16u first_umb_size;
00047 
00048 bool MEM_unmap_physmem(Bitu start,Bitu end);
00049 bool MEM_map_RAM_physmem(Bitu start,Bitu end);
00050 
00051 struct BuiltinFileBlob {
00052         const char              *recommended_file_name;
00053         const unsigned char     *data;
00054         size_t                  length;
00055 };
00056 
00057 struct DOS_Date {
00058         Bit16u year;
00059         Bit8u month;
00060         Bit8u day;
00061 };
00062 
00063 struct DOS_Version {
00064         Bit8u major,minor,revision;
00065 };
00066 
00067 #ifndef MACOSX
00068 #if defined (__APPLE__)
00069 #define MACOSX 1
00070 #endif
00071 #endif
00072 
00073 #ifdef __cplusplus
00074 extern "C" {
00075 #endif
00076 
00077 typedef signed char         INT8, *PINT8;
00078 typedef signed short        INT16, *PINT16;
00079 typedef signed int          INT32, *PINT32;
00080 //typedef signed __int64      INT64, *PINT64;
00081 typedef unsigned char       UINT8, *PUINT8;
00082 typedef unsigned short      UINT16, *PUINT16;
00083 typedef unsigned int        UINT32, *PUINT32;
00084 //typedef unsigned __int64    UINT64, *PUINT64;
00085 #ifdef __cplusplus
00086 }
00087 #endif
00088 
00089 #define SECTOR_SIZE_MAX     2048
00090 
00091 #ifdef _MSC_VER
00092 #pragma pack (1)
00093 #endif
00094 union bootSector {
00095         struct entries {
00096                 Bit8u jump[3];
00097                 Bit8u oem_name[8];
00098                 Bit16u bytesect;
00099                 Bit8u sectclust;
00100                 Bit16u reserve_sect;
00101         } bootdata;
00102         Bit8u rawdata[SECTOR_SIZE_MAX];
00103 } GCC_ATTRIBUTE(packed);
00104 #ifdef _MSC_VER
00105 #pragma pack ()
00106 #endif
00107 
00108 
00109 enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
00110 enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
00111 
00112 extern Bitu DOS_FILES;
00113 
00114 #define DOS_DRIVES 26
00115 #define DOS_DEVICES 20
00116 
00117 
00118 #if 0 /* ORIGINAL DEFINES FOR REFERENCE */
00119 // dos swappable area is 0x320 bytes beyond the sysvars table
00120 // device driver chain is inside sysvars
00121 #define DOS_INFOBLOCK_SEG 0x80  // sysvars (list of lists)
00122 #define DOS_CONDRV_SEG 0xa0
00123 #define DOS_CONSTRING_SEG 0xa8
00124 #define DOS_SDA_SEG 0xb2                // dos swappable area
00125 #define DOS_SDA_OFS 0
00126 #define DOS_CDS_SEG 0x108
00127 #define DOS_MEM_START 0x158      // regression to r3437 fixes nascar 2 colors
00128 //#define DOS_MEM_START 0x16f           //First Segment that DOS can use 
00129 
00130 #define DOS_PRIVATE_SEGMENT 0xc800
00131 #define DOS_PRIVATE_SEGMENT_END 0xd000
00132 #endif
00133 
00134 // dos swappable area is 0x320 bytes beyond the sysvars table
00135 // device driver chain is inside sysvars
00136 extern Bit16u DOS_INFOBLOCK_SEG;// 0x80 // sysvars (list of lists)
00137 extern Bit16u DOS_CONDRV_SEG;// 0xa0
00138 extern Bit16u DOS_CONSTRING_SEG;// 0xa8
00139 extern Bit16u DOS_SDA_SEG;// 0xb2               // dos swappable area
00140 extern Bit16u DOS_SDA_SEG_SIZE;
00141 extern Bit16u DOS_SDA_OFS;// 0
00142 extern Bit16u DOS_CDS_SEG;// 0x108
00143 extern Bit16u DOS_MEM_START;// 0x158     // regression to r3437 fixes nascar 2 colors
00144 
00145 extern Bit16u DOS_PRIVATE_SEGMENT;// 0xc800
00146 extern Bit16u DOS_PRIVATE_SEGMENT_END;// 0xd000
00147 
00148 /* internal Dos Tables */
00149 
00150 extern DOS_File ** Files;
00151 extern DOS_Drive * Drives[DOS_DRIVES];
00152 extern DOS_Device * Devices[DOS_DEVICES];
00153 
00154 extern Bit8u dos_copybuf[0x10000];
00155 
00156 
00157 void DOS_SetError(Bit16u code);
00158 
00159 /* File Handling Routines */
00160 
00161 enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDPRN=4};
00162 enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE};
00163 
00164 /* Routines for File Class */
00165 void DOS_SetupFiles (void);
00166 bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount, bool fcb = false);
00167 bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount,bool fcb = false);
00168 bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type,bool fcb = false);
00169 /* ert, 20100711: Locking extensions */
00170 bool DOS_LockFile(Bit16u entry,Bit8u mode,Bit32u pos,Bit32u size);
00171 bool DOS_CloseFile(Bit16u entry,bool fcb = false);
00172 bool DOS_FlushFile(Bit16u entry);
00173 bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
00174 bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry);
00175 bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate);
00176 bool DOS_SetFileDate(Bit16u entry, Bit16u ntime, Bit16u ndate);
00177 
00178 /* Routines for Drive Class */
00179 bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry,bool fcb = false);
00180 bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
00181 bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry, bool fcb = false);
00182 bool DOS_UnlinkFile(char const * const name);
00183 bool DOS_GetSFNPath(char const * const path, char *SFNpath, bool LFN);
00184 bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false);
00185 bool DOS_FindNext(void);
00186 bool DOS_Canonicalize(char const * const name,char * const big);
00187 bool DOS_CreateTempFile(char * const name,Bit16u * entry);
00188 bool DOS_FileExists(char const * const name);
00189 
00190 /* Helper Functions */
00191 bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive);
00192 /* Drive Handing Routines */
00193 Bit8u DOS_GetDefaultDrive(void);
00194 void DOS_SetDefaultDrive(Bit8u drive);
00195 bool DOS_SetDrive(Bit8u drive);
00196 bool DOS_GetCurrentDir(Bit8u drive,char * const buffer, bool LFN);
00197 bool DOS_ChangeDir(char const * const dir);
00198 bool DOS_MakeDir(char const * const dir);
00199 bool DOS_RemoveDir(char const * const dir);
00200 bool DOS_Rename(char const * const oldname,char const * const newname);
00201 bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free);
00202 bool DOS_GetFreeDiskSpace32(Bit8u drive,Bit32u * bytes,Bit32u * sectors,Bit32u * clusters,Bit32u * free);
00203 bool DOS_GetFileAttr(char const * const name,Bit16u * attr);
00204 bool DOS_SetFileAttr(char const * const name,Bit16u attr);
00205 bool DOS_GetFileAttrEx(char const* const name, struct stat *status, Bit8u hdrive=-1);
00206 unsigned long DOS_GetCompressedFileSize(char const* const name);
00207 #if defined (WIN32)
00208 HANDLE DOS_CreateOpenFile(char const* const name);
00209 #endif
00210 
00211 /* IOCTL Stuff */
00212 bool DOS_IOCTL(void);
00213 bool DOS_GetSTDINStatus();
00214 Bit8u DOS_FindDevice(char const * name);
00215 void DOS_SetupDevices(void);
00216 
00217 /* Execute and new process creation */
00218 bool DOS_NewPSP(Bit16u segment,Bit16u size);
00219 bool DOS_ChildPSP(Bit16u segment,Bit16u size);
00220 bool DOS_Execute(const char* name, PhysPt block_pt, Bit8u flags);
00221 void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode);
00222 
00223 /* Memory Handling Routines */
00224 void DOS_SetupMemory(void);
00225 bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks);
00226 bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks);
00227 bool DOS_FreeMemory(Bit16u segment);
00228 void DOS_FreeProcessMemory(Bit16u pspseg);
00229 Bit16u DOS_GetMemory(Bit16u pages,const char *who=NULL);
00230 bool DOS_SetMemAllocStrategy(Bit16u strat);
00231 Bit16u DOS_GetMemAllocStrategy(void);
00232 void DOS_BuildUMBChain(bool umb_active,bool ems_active);
00233 bool DOS_LinkUMBsToMemChain(Bit16u linkstate);
00234 
00235 /* FCB stuff */
00236 bool DOS_FCBOpen(Bit16u seg,Bit16u offset);
00237 bool DOS_FCBCreate(Bit16u seg,Bit16u offset);
00238 bool DOS_FCBClose(Bit16u seg,Bit16u offset);
00239 bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset);
00240 bool DOS_FCBFindNext(Bit16u seg,Bit16u offset);
00241 Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u recno);
00242 Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno);
00243 Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore);
00244 Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore);
00245 bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset);
00246 bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset);
00247 bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset);
00248 void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset);
00249 Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change);
00250 bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters);
00251 
00252 /* Extra DOS Interrupts */
00253 void DOS_SetupMisc(void);
00254 
00255 /* The DOS Tables */
00256 void DOS_SetupTables(void);
00257 
00258 /* Internal DOS Setup Programs */
00259 void DOS_SetupPrograms(void);
00260 
00261 /* Initialize Keyboard Layout */
00262 void DOS_KeyboardLayout_Init(Section* sec);
00263 
00264 bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3);
00265 
00266 enum {
00267         KEYB_NOERROR=0,
00268         KEYB_FILENOTFOUND,
00269         KEYB_INVALIDFILE,
00270         KEYB_LAYOUTNOTFOUND,
00271         KEYB_INVALIDCPFILE
00272 };
00273 
00274 
00275 static INLINE Bit16u long2para(Bit32u size) {
00276         if (size>0xFFFF0) return 0xffff;
00277         if (size&0xf) return (Bit16u)((size>>4)+1);
00278         else return (Bit16u)(size>>4);
00279 }
00280 
00281 
00282 static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) {
00283         return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f);
00284 }
00285 
00286 static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
00287         return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f);
00288 }
00289 
00290 /* fopen64, ftello64, fseeko64 */
00291 #if defined(__linux__)
00292  #define fseek_ofs_t long
00293 #elif defined (_MSC_VER)
00294  #define fopen64 fopen
00295  #if (_MSC_VER >= 1400)
00296   #define ftello64 _ftelli64
00297   #define fseeko64 _fseeki64
00298   #define fseek_ofs_t __int64
00299  #else
00300   #define ftello64 ftell
00301   #define fseeko64 fseek
00302   #define fseek_ofs_t long
00303  #endif
00304 #else
00305  #define fopen64 fopen
00306  #define ftello64 ftell
00307  #define fseeko64 fseek
00308  #define fseek_ofs_t off_t
00309 #endif
00310 
00311 /* Dos Error Codes */
00312 #define DOSERR_NONE 0
00313 #define DOSERR_FUNCTION_NUMBER_INVALID 1
00314 #define DOSERR_FILE_NOT_FOUND 2
00315 #define DOSERR_PATH_NOT_FOUND 3
00316 #define DOSERR_TOO_MANY_OPEN_FILES 4
00317 #define DOSERR_ACCESS_DENIED 5
00318 #define DOSERR_INVALID_HANDLE 6
00319 #define DOSERR_MCB_DESTROYED 7
00320 #define DOSERR_INSUFFICIENT_MEMORY 8
00321 #define DOSERR_MB_ADDRESS_INVALID 9
00322 #define DOSERR_ENVIRONMENT_INVALID 10
00323 #define DOSERR_FORMAT_INVALID 11
00324 #define DOSERR_ACCESS_CODE_INVALID 12
00325 #define DOSERR_DATA_INVALID 13
00326 #define DOSERR_RESERVED 14
00327 #define DOSERR_FIXUP_OVERFLOW 14
00328 #define DOSERR_INVALID_DRIVE 15
00329 #define DOSERR_REMOVE_CURRENT_DIRECTORY 16
00330 #define DOSERR_NOT_SAME_DEVICE 17
00331 #define DOSERR_NO_MORE_FILES 18
00332 #define DOSERR_WRITE_PROTECTED 19
00333 #define DOSERR_FILE_ALREADY_EXISTS 80
00334 
00335 
00336 /* Remains some classes used to access certain things */
00337 #define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL)
00338 #define sGet(s,m) GetIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m))
00339 #define sSave(s,m,val) SaveIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m),val)
00340 
00341 class MemStruct {
00342 public:
00343     inline Bit32u GetIt(const Bit32u size, const PhysPt addr) {
00344                 switch (size) {
00345                 case 1:return mem_readb(pt+addr);
00346                 case 2:return mem_readw(pt+addr);
00347                 case 4:return mem_readd(pt+addr);
00348                 }
00349                 return 0;
00350         }
00351         inline void SaveIt(const Bit32u size, const PhysPt addr, const Bit32u val) {
00352                 switch (size) {
00353                 case 1:mem_writeb(pt+addr,(Bit8u)val);break;
00354                 case 2:mem_writew(pt+addr,(Bit16u)val);break;
00355                 case 4:mem_writed(pt+addr,(Bit32u)val);break;
00356                 }
00357         }
00358     inline void SetPt(const Bit16u seg) { pt=PhysMake(seg,0);}
00359     inline void SetPt(const Bit16u seg, const Bit16u off) { pt=PhysMake(seg,off);}
00360     inline void SetPt(const RealPt addr) { pt=Real2Phys(addr);}
00361     inline PhysPt GetPtPhys(void) const { return pt; }
00362     inline void SetPtPhys(const PhysPt _pt) { pt=_pt; }
00363 protected:
00364         PhysPt pt;
00365 };
00366 
00367 class DOS_PSP :public MemStruct {
00368 public:
00369         DOS_PSP                                         (Bit16u segment)                { SetPt(segment);seg=segment;};
00370         void    MakeNew                         (Bit16u mem_size);
00371         void    CopyFileTable           (DOS_PSP* srcpsp,bool createchildpsp);
00372         Bit16u  FindFreeFileEntry       (void);
00373         void    CloseFiles                      (void);
00374 
00375         void    SaveVectors                     (void);
00376         void    RestoreVectors          (void);
00377         void    SetSize                         (Bit16u size)                   { sSave(sPSP,next_seg,size);            };
00378         Bit16u  GetSize                         (void)                                  { return (Bit16u)sGet(sPSP,next_seg);           };
00379         void    SetEnvironment          (Bit16u envseg)                 { sSave(sPSP,environment,envseg);       };
00380         Bit16u  GetEnvironment          (void)                                  { return (Bit16u)sGet(sPSP,environment);        };
00381         Bit16u  GetSegment                      (void)                                  { return seg;                                           };
00382         void    SetFileHandle           (Bit16u index, Bit8u handle);
00383         Bit8u   GetFileHandle           (Bit16u index);
00384         void    SetParent                       (Bit16u parent)                 { sSave(sPSP,psp_parent,parent);        };
00385         Bit16u  GetParent                       (void)                                  { return (Bit16u)sGet(sPSP,psp_parent);         };
00386         void    SetStack                        (RealPt stackpt)                { sSave(sPSP,stack,stackpt);            };
00387         RealPt  GetStack                        (void)                                  { return sGet(sPSP,stack);                      };
00388         void    SetInt22                        (RealPt int22pt)                { sSave(sPSP,int_22,int22pt);           };
00389         RealPt  GetInt22                        (void)                                  { return sGet(sPSP,int_22);                     };
00390         void    SetFCB1                         (RealPt src);
00391         void    SetFCB2                         (RealPt src);
00392         void    SetCommandTail          (RealPt src);
00393         void    StoreCommandTail    (void);
00394         void    RestoreCommandTail  (void);
00395         bool    SetNumFiles                     (Bit16u fileNum);
00396         Bit16u  FindEntryByHandle       (Bit8u handle);
00397                         
00398 private:
00399         #ifdef _MSC_VER
00400         #pragma pack(1)
00401         #endif
00402         struct sPSP {
00403                 Bit8u   exit[2];                        /* CP/M-like exit poimt */
00404                 Bit16u  next_seg;                       /* Segment of first byte beyond memory allocated or program */
00405                 Bit8u   fill_1;                         /* single char fill */
00406                 Bit8u   far_call;                       /* far call opcode */
00407                 RealPt  cpm_entry;                      /* CPM Service Request address*/
00408                 RealPt  int_22;                         /* Terminate Address */
00409                 RealPt  int_23;                         /* Break Address */
00410                 RealPt  int_24;                         /* Critical Error Address */
00411                 Bit16u  psp_parent;                     /* Parent PSP Segment */
00412                 Bit8u   files[20];                      /* File Table - 0xff is unused */
00413                 Bit16u  environment;            /* Segment of evironment table */
00414                 RealPt  stack;                          /* SS:SP Save point for int 0x21 calls */
00415                 Bit16u  max_files;                      /* Maximum open files */
00416                 RealPt  file_table;                     /* Pointer to File Table PSP:0x18 */
00417                 RealPt  prev_psp;                       /* Pointer to previous PSP */
00418                 Bit8u interim_flag;
00419                 Bit8u truename_flag;
00420                 Bit16u nn_flags;
00421                 Bit16u dos_version;
00422                 Bit8u   fill_2[14];                     /* Lot's of unused stuff i can't care aboue */
00423                 Bit8u   service[3];                     /* INT 0x21 Service call int 0x21;retf; */
00424                 Bit8u   fill_3[9];                      /* This has some blocks with FCB info */
00425                 Bit8u   fcb1[16];                       /* first FCB */
00426                 Bit8u   fcb2[16];                       /* second FCB */
00427                 Bit8u   fill_4[4];                      /* unused */
00428                 CommandTail cmdtail;            
00429         } GCC_ATTRIBUTE(packed);
00430         #ifdef _MSC_VER
00431         #pragma pack()
00432         #endif
00433         Bit16u  seg;
00434 public:
00435         static  Bit16u rootpsp;
00436 };
00437 
00438 class DOS_ParamBlock:public MemStruct {
00439 public:
00440         DOS_ParamBlock(PhysPt addr) {pt=addr;}
00441         void Clear(void);
00442         void LoadData(void);
00443         void SaveData(void);            /* Save it as an exec block */
00444         #ifdef _MSC_VER
00445         #pragma pack (1)
00446         #endif
00447         struct sOverlay {
00448                 Bit16u loadseg;
00449                 Bit16u relocation;
00450         } GCC_ATTRIBUTE(packed);
00451         struct sExec {
00452                 Bit16u envseg;
00453                 RealPt cmdtail;
00454                 RealPt fcb1;
00455                 RealPt fcb2;
00456                 RealPt initsssp;
00457                 RealPt initcsip;
00458         }GCC_ATTRIBUTE(packed);
00459         #ifdef _MSC_VER
00460         #pragma pack()
00461         #endif
00462     sExec exec = {};
00463     sOverlay overlay = {};
00464 };
00465 
00466 class DOS_InfoBlock:public MemStruct {
00467 public:
00468     DOS_InfoBlock() : seg(0) {};
00469         void SetLocation(Bit16u  segment);
00470     void SetFirstDPB(Bit32u _first_dpb);
00471         void SetFirstMCB(Bit16u _firstmcb);
00472         void SetBuffers(Bit16u x,Bit16u y);
00473         void SetCurDirStruct(Bit32u _curdirstruct);
00474         void SetFCBTable(Bit32u _fcbtable);
00475         void SetDeviceChainStart(Bit32u _devchain);
00476         void SetDiskBufferHeadPt(Bit32u _dbheadpt);
00477         void SetStartOfUMBChain(Bit16u _umbstartseg);
00478         void SetUMBChainState(Bit8u _umbchaining);
00479         void SetBlockDevices(Bit8u _count);
00480         Bit16u  GetStartOfUMBChain(void);
00481         Bit8u   GetUMBChainState(void);
00482         RealPt  GetPointer(void);
00483         Bit32u GetDeviceChain(void);
00484 
00485         #ifdef _MSC_VER
00486         #pragma pack(1)
00487         #endif
00488         struct sDIB {           
00489                 Bit8u   unknown1[4];
00490                 Bit16u  magicWord;                      // -0x22 needs to be 1
00491                 Bit8u   unknown2[8];
00492                 Bit16u  regCXfrom5e;            // -0x18 CX from last int21/ah=5e
00493                 Bit16u  countLRUcache;          // -0x16 LRU counter for FCB caching
00494                 Bit16u  countLRUopens;          // -0x14 LRU counter for FCB openings
00495                 Bit8u   stuff[6];               // -0x12 some stuff, hopefully never used....
00496                 Bit16u  sharingCount;           // -0x0c sharing retry count
00497                 Bit16u  sharingDelay;           // -0x0a sharing retry delay
00498                 RealPt  diskBufPtr;             // -0x08 pointer to disk buffer
00499                 Bit16u  ptrCONinput;            // -0x04 pointer to con input
00500                 Bit16u  firstMCB;               // -0x02 first memory control block
00501                 RealPt  firstDPB;               //  0x00 first drive parameter block
00502                 RealPt  firstFileTable;         //  0x04 first system file table
00503                 RealPt  activeClock;            //  0x08 active clock device header
00504                 RealPt  activeCon;              //  0x0c active console device header
00505                 Bit16u  maxSectorLength;        //  0x10 maximum bytes per sector of any block device;
00506                 RealPt  diskInfoBuffer;         //  0x12 pointer to disk info buffer
00507                 RealPt  curDirStructure;        //  0x16 pointer to current array of directory structure
00508                 RealPt  fcbTable;               //  0x1a pointer to system FCB table
00509                 Bit16u  protFCBs;               //  0x1e protected fcbs
00510                 Bit8u   blockDevices;           //  0x20 installed block devices
00511                 Bit8u   lastdrive;              //  0x21 lastdrive
00512                 Bit32u  nulNextDriver;  //  0x22 NUL driver next pointer
00513                 Bit16u  nulAttributes;  //  0x26 NUL driver aattributes
00514         Bit16u  nulStrategy;    //  0x28 NUL driver strategy routine
00515         Bit16u  nulInterrupt;   //  0x2A NUL driver interrupt routine
00516                 Bit8u   nulString[8];   //  0x2c NUL driver name string
00517                 Bit8u   joindedDrives;          //  0x34 joined drives
00518                 Bit16u  specialCodeSeg;         //  0x35 special code segment
00519                 RealPt  setverPtr;              //  0x37 pointer to setver
00520                 Bit16u  a20FixOfs;              //  0x3b a20 fix routine offset
00521                 Bit16u  pspLastIfHMA;           //  0x3d psp of last program (if dos in hma)
00522                 Bit16u  buffers_x;              //  0x3f x in BUFFERS x,y
00523                 Bit16u  buffers_y;              //  0x41 y in BUFFERS x,y
00524                 Bit8u   bootDrive;              //  0x43 boot drive
00525                 Bit8u   useDwordMov;            //  0x44 use dword moves
00526                 Bit16u  extendedSize;           //  0x45 size of extended memory
00527                 Bit32u  diskBufferHeadPt;       //  0x47 pointer to least-recently used buffer header
00528                 Bit16u  dirtyDiskBuffers;       //  0x4b number of dirty disk buffers
00529                 Bit32u  lookaheadBufPt;         //  0x4d pointer to lookahead buffer
00530                 Bit16u  lookaheadBufNumber;             //  0x51 number of lookahead buffers
00531                 Bit8u   bufferLocation;                 //  0x53 workspace buffer location
00532                 Bit32u  workspaceBuffer;                //  0x54 pointer to workspace buffer
00533                 Bit8u   unknown3[11];                   //  0x58
00534                 Bit8u   chainingUMB;                    //  0x63 bit0: UMB chain linked to MCB chain
00535                 Bit16u  minMemForExec;                  //  0x64 minimum paragraphs needed for current program
00536                 Bit16u  startOfUMBChain;                //  0x66 segment of first UMB-MCB
00537                 Bit16u  memAllocScanStart;              //  0x68 start paragraph for memory allocation
00538         } GCC_ATTRIBUTE(packed);
00539         #ifdef _MSC_VER
00540         #pragma pack ()
00541         #endif
00542         Bit16u  seg;
00543 };
00544 
00545 class DOS_DTA:public MemStruct{
00546 public:
00547         DOS_DTA(RealPt addr) { SetPt(addr); }
00548 
00549     int GetFindData(int fmt,char * finddata,int *c);
00550         
00551         void SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern);
00552         void SetResult(const char * _name,const char * _lname,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr);
00553         
00554         Bit8u GetSearchDrive(void);
00555         void GetSearchParams(Bit8u & _sattr,char * _spattern,bool lfn);
00556     void GetResult(char * _name,char * _lname,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr);
00557 
00558         void    SetDirID(Bit16u entry)                  { sSave(sDTA,dirID,entry); };
00559         void    SetDirIDCluster(Bit32u entry)   { sSave(sDTA,dirCluster,entry); };
00560         Bit16u  GetDirID(void)                          { return (Bit16u)sGet(sDTA,dirID); };
00561         Bit32u  GetDirIDCluster(void)           { return (Bit32u)sGet(sDTA,dirCluster); };
00562     Bit8u   GetAttr(void)               { return (Bit8u)sGet(sDTA,sattr); }
00563 private:
00564         #ifdef _MSC_VER
00565         #pragma pack(1)
00566         #endif
00567         struct sDTA {
00568                 Bit8u sdrive;                                           /* The Drive the search is taking place */
00569         Bit8u spname[8];                    /* The Search pattern for the filename */              
00570         Bit8u spext[3];                     /* The Search pattern for the extension */
00571                 Bit8u sattr;                                            /* The Attributes that need to be found */
00572                 Bit16u dirID;                                           /* custom: dir-search ID for multiple searches at the same time */
00573                 Bit32u dirCluster;                                      /* custom (drive_fat only): cluster number for multiple searches at the same time. 32-bit wide on FAT32 aware MS-DOS 7.1 or higher. */
00574                 Bit8u fill[2];
00575                 Bit8u attr;
00576                 Bit16u time;
00577                 Bit16u date;
00578                 Bit32u size;
00579                 char name[DOS_NAMELENGTH_ASCII];
00580         } GCC_ATTRIBUTE(packed);
00581         static_assert(offsetof(sDTA,dirID) == 0x0D,"oops");
00582         static_assert(offsetof(sDTA,dirCluster) == 0x0F,"oops");
00583         static_assert(offsetof(sDTA,fill) == 0x13,"oops");
00584         static_assert(offsetof(sDTA,attr) == 0x15,"oops");
00585         #ifdef _MSC_VER
00586         #pragma pack()
00587         #endif
00588 };
00589 
00590 class DOS_FCB: public MemStruct {
00591 public:
00592         DOS_FCB(Bit16u seg,Bit16u off,bool allow_extended=true);
00593         void Create(bool _extended);
00594     void SetName(Bit8u _drive, const char* _fname, const char* _ext);
00595         void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time);
00596         void GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time);
00597     void GetVolumeName(char * fillname);
00598         void GetName(char * fillname);
00599         void FileOpen(Bit8u _fhandle);
00600         void FileClose(Bit8u & _fhandle);
00601         void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec);
00602         void SetRecord(Bit16u _cur_block,Bit8u _cur_rec);
00603         void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size);
00604         void SetSeqData(Bit8u _fhandle,Bit16u _rec_size);
00605         void GetRandom(Bit32u & _random);
00606         void SetRandom(Bit32u  _random);
00607         Bit8u GetDrive(void);
00608         bool Extended(void);
00609         void GetAttr(Bit8u & attr);
00610         void SetAttr(Bit8u attr);
00611         void SetResult(Bit32u size,Bit16u date,Bit16u time,Bit8u attr);
00612         bool Valid(void);
00613         void ClearBlockRecsize(void);
00614 private:
00615         bool extended = false;
00616         PhysPt real_pt;
00617         #ifdef _MSC_VER
00618         #pragma pack (1)
00619         #endif
00620         struct sFCB {
00621                 Bit8u drive;                    /* Drive number 0=default, 1=A, etc */
00622                 Bit8u filename[8];              /* Space padded name */
00623                 Bit8u ext[3];                   /* Space padded extension */
00624                 Bit16u cur_block;               /* Current Block */
00625                 Bit16u rec_size;                /* Logical record size */
00626                 Bit32u filesize;                /* File Size */
00627                 Bit16u date;
00628                 Bit16u time;
00629                 /* Reserved Block should be 8 bytes */
00630                 Bit8u sft_entries;
00631                 Bit8u share_attributes;
00632                 Bit8u extra_info;
00633                 /* Maybe swap file_handle and sft_entries now that fcbs 
00634                  * aren't stored in the psp filetable anymore */
00635                 Bit8u file_handle;
00636                 Bit8u reserved[4];
00637                 /* end */
00638                 Bit8u  cur_rec;                 /* Current record in current block */
00639                 Bit32u rndm;                    /* Current relative record number */
00640         } GCC_ATTRIBUTE(packed);
00641         #ifdef _MSC_VER
00642         #pragma pack ()
00643         #endif
00644 };
00645 
00646 class DOS_MCB : public MemStruct{
00647 public:
00648         DOS_MCB(Bit16u seg) { SetPt(seg); }
00649         void SetFileName(const char * const _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); }
00650         void GetFileName(char * const _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;}
00651         void SetType(Bit8u _type) { sSave(sMCB,type,_type);}
00652         void SetSize(Bit16u _size) { sSave(sMCB,size,_size);}
00653         void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);}
00654         Bit8u GetType(void) { return (Bit8u)sGet(sMCB,type);}
00655         Bit16u GetSize(void) { return (Bit16u)sGet(sMCB,size);}
00656         Bit16u GetPSPSeg(void) { return (Bit16u)sGet(sMCB,psp_segment);}
00657 private:
00658         #ifdef _MSC_VER
00659         #pragma pack (1)
00660         #endif
00661         struct sMCB {
00662                 Bit8u type;
00663                 Bit16u psp_segment;
00664                 Bit16u size;    
00665                 Bit8u unused[3];
00666                 Bit8u filename[8];
00667         } GCC_ATTRIBUTE(packed);
00668         #ifdef _MSC_VER
00669         #pragma pack ()
00670         #endif
00671 };
00672 
00673 class DOS_SDA : public MemStruct {
00674 public:
00675         DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); }
00676         void Init();   
00677         void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); }
00678         void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); }
00679         void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); }
00680         Bit8u GetDrive(void) { return (Bit8u)sGet(sSDA,current_drive); }
00681         Bit16u GetPSP(void) { return (Bit16u)sGet(sSDA,current_psp); }
00682         Bit32u GetDTA(void) { return (Bit32u)sGet(sSDA,current_dta); }
00683         
00684         
00685 private:
00686         #ifdef _MSC_VER
00687         #pragma pack (1)
00688         #endif
00689         struct sSDA {
00690                 Bit8u crit_error_flag;          /* 0x00 Critical Error Flag */
00691                 Bit8u inDOS_flag;               /* 0x01 InDOS flag (count of active INT 21 calls) */
00692                 Bit8u drive_crit_error;         /* 0x02 Drive on which current critical error occurred or FFh */
00693                 Bit8u locus_of_last_error;      /* 0x03 locus of last error */
00694                 Bit16u extended_error_code;     /* 0x04 extended error code of last error */
00695                 Bit8u suggested_action;         /* 0x06 suggested action for last error */
00696                 Bit8u error_class;              /* 0x07 class of last error*/
00697                 Bit32u last_error_pointer;      /* 0x08 ES:DI pointer for last error */
00698                 Bit32u current_dta;             /* 0x0C current DTA (Disk Transfer Address) */
00699                 Bit16u current_psp;             /* 0x10 current PSP */
00700                 Bit16u sp_int_23;               /* 0x12 stores SP across an INT 23 */
00701                 Bit16u return_code;             /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */
00702                 Bit8u current_drive;            /* 0x16 current drive */
00703                 Bit8u extended_break_flag;      /* 0x17 extended break flag */
00704                 Bit8u fill[2];                  /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/
00705         } GCC_ATTRIBUTE(packed);
00706         #ifdef _MSC_VER
00707         #pragma pack()
00708         #endif
00709 };
00710 extern DOS_InfoBlock dos_infoblock;
00711 
00712 struct DOS_Block {
00713     DOS_Date date = {};
00714     DOS_Version version = {};
00715     Bit16u firstMCB = 0;
00716     Bit16u errorcode = 0;
00717     Bit16u psp();//{return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();};
00718     void psp(Bit16u _seg);//{ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);};
00719     RealPt dta();//{return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();};
00720     void dta(RealPt _dta);//{DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);};
00721     Bit8u return_code = 0, return_mode = 0;
00722 
00723     Bit8u current_drive = 0;
00724     bool verify = false;
00725     bool breakcheck = false;
00726     bool echo = false;          // if set to true dev_con::read will echo input
00727     bool direct_output = false;
00728     bool internal_output = false;
00729     struct {
00730         RealPt mediaid = 0;
00731         RealPt tempdta = 0;
00732         RealPt tempdta_fcbdelete = 0;
00733         RealPt dbcs = 0;
00734         RealPt filenamechar = 0;
00735         RealPt collatingseq = 0;
00736         RealPt upcase = 0;
00737         Bit8u* country = NULL;//Will be copied to dos memory. resides in real mem
00738         Bit16u dpb = 0; //Fake Disk parameter system using only the first entry so the drive letter matches
00739         Bit16u dpb_size = 0x21; // bytes per DPB entry (MS-DOS 4.x-6.x size)
00740         Bit16u mediaid_offset = 0x17; // media ID offset in DPB (MS-DOS 4.x-6.x case)
00741     } tables;
00742     Bit16u loaded_codepage = 0;
00743 };
00744 
00745 extern DOS_Block dos;
00746 
00747 static INLINE Bit8u RealHandle(Bit16u handle) {
00748         DOS_PSP psp(dos.psp()); 
00749         return psp.GetFileHandle(handle);
00750 }
00751 
00752 struct DOS_GetMemLog_Entry {
00753     Bit16u      segbase = 0;
00754     Bit16u      pages = 0;
00755     std::string who;
00756 };
00757 
00758 extern std::list<DOS_GetMemLog_Entry> DOS_GetMemLog;
00759 
00760 #endif