// Wengier: LFN support #ifndef vDOS_DOS_INC_H #define vDOS_DOS_INC_H #include "dos_system.h" #include "mem.h" #ifdef _MSC_VER #pragma pack (1) #endif struct CommandTail{ Bit8u count; // number of bytes returned char buffer[127]; // the buffer itself }; #ifdef _MSC_VER #pragma pack () #endif struct DOS_Date { Bit16u year; Bit8u month; Bit8u day; }; struct DOS_Version { Bit8u major, minor; }; enum {MCB_FREE = 0x0000, MCB_DOS = 0x0008}; enum {RETURN_EXIT = 0, RETURN_CTRLC = 1, RETURN_ABORT = 2, RETURN_TSR = 3}; #define DOS_DRIVES 26 #define DOS_DEVICES 25 // dos swappable area is 0x320 bytes beyond the sysvars table // device driver chain is inside sysvars #define DOS_INFOBLOCK_SEG 0x80 // sysvars (list of lists) #define DOS_CONDRV_SEG 0xa0 #define DOS_CONSTRING_SEG 0xa8 #define DOS_SDA_SEG 0xb2 // dos swappable area #define DOS_SDA_OFS 0 #define DOS_CDS_SEG 0x108 #define DOS_FIRST_SHELL 0x118 #define DOS_MEM_START 0x16f // First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc400 #define DOS_PRIVATE_SEGMENT_END 0xc800 // internal Dos Tables extern DOS_File ** Files; extern DOS_Drive * Drives[DOS_DRIVES]; extern DOS_Device * Devices[DOS_DEVICES]; extern Bit8u dos_copybuf[0x10000]; void DOS_SetError(Bit16u code); // File Handling Routines enum {STDIN = 0, STDOUT = 1, STDERR = 2, STDAUX = 3, STDPRN = 4}; //enum {HAND_NONE = 0, HAND_FILE, HAND_DEVICE}; // Routines for File Class void DOS_SetupFiles (void); bool DOS_ReadFile(Bit16u handle, Bit8u * data, Bit16u * amount); bool DOS_WriteFile(Bit16u handle, Bit8u * data, Bit16u * amount); bool DOS_SeekFile(Bit16u handle, Bit32u * pos, Bit32u type); bool DOS_LockFile(Bit16u entry, Bit8u mode, Bit32u pos, Bit32u size); bool DOS_CloseFile(Bit16u handle); bool DOS_FlushFile(Bit16u handle); bool DOS_DuplicateEntry(Bit16u entry, Bit16u * newentry); bool DOS_ForceDuplicateEntry(Bit16u entry, Bit16u newentry); bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate, int type); bool DOS_SetFileDate(Bit16u entry, Bit16u ntime, Bit16u ndate, int type); // Routines for Drive Class bool DOS_OpenFile(char const * name, Bit8u flags, Bit16u * entry); bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); bool DOS_CreateFile(char const * name, Bit16u attribute, Bit16u * entry); bool DOS_DeleteFile(char const * const name, bool wildcard); bool DOS_FindFirst(char *search, Bit16u attr, int handle); bool DOS_FindNext(int handle); bool DOS_Canonicalize(char const * const name, char * const big); bool DOS_CreateTempFile(char * const name, Bit16u * entry); bool DOS_FileExists(char const * const name); // Helper Functions bool DOS_MakeName(char const * const name, char * const fullname, Bit8u * drive); bool DOS_GetSFNPath(char const * const path, char * SFNPath, bool LFN); // Drive Handing Routines Bit8u DOS_GetDefaultDrive(void); void DOS_SetDefaultDrive(Bit8u drive); bool DOS_GetCurrentDir(Bit8u drive, char * const buffer, bool LFN); bool DOS_ChangeDir(char const * const dir); bool DOS_MakeDir(char const * const dir); bool DOS_RemoveDir(char const * const dir); bool DOS_Rename(char const * const oldname, char const * const newname); bool DOS_GetFreeDiskSpace(Bit8u drive, Bit16u* bytes_sector, Bit8u* sectors_cluster, Bit16u* total_clusters, Bit16u* free_clusters); bool DOS_GetDiskFreeSpace32(char* name, DWORD* sectors_per_cluster, DWORD* bytes_per_sector, DWORD* free_clusters, DWORD* total_clusters); bool DOS_GetFileAttr(char const * const name, Bit16u * attr); bool DOS_SetFileAttr(char const * const name, Bit16u attr); bool DOS_GetFileAttrEx(char const* const name, LPVOID fad, Bit8u hdrive=-1); bool DOS_GetVolumeInfo(char* name, char* volume_label, DWORD *serial_number); DWORD DOS_GetCompressedFileSize(char const* const name); HANDLE DOS_CreateOpenFile(char const* const name); bool DOS_GetAllocationInfo(Bit8u drive, Bit16u * bytes_sector, Bit8u * sectors_cluster, Bit16u * total_clusters); // IOCTL Stuff bool DOS_IOCTL(void); bool DOS_GetSTDINStatus(); Bit8u DOS_FindDevice(char const * name); void DOS_SetupDevices(void); // Execute and new process creation bool DOS_NewPSP(Bit16u pspseg, Bit16u size); bool DOS_ChildPSP(Bit16u pspseg, Bit16u size); bool DOS_Execute(char * name, PhysPt block, Bit8u flags); void DOS_Terminate(Bit16u pspseg, bool tsr, Bit8u exitcode); // Memory Handling Routines void DOS_SetupMemory(bool low); bool DOS_GetFreeUMB(Bit16u * total, Bit16u * largest, Bit16u * count); bool DOS_AllocateMemory(Bit16u * segment, Bit16u * blocks); bool DOS_ResizeMemory(Bit16u segment, Bit16u * blocks); bool DOS_FreeMemory(Bit16u segment); void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetPrivatMemory(Bit16u pages); bool DOS_FreePrivatMemory(Bit16u seg, Bit16u pages); bool DOS_SetMemAllocStrategy(Bit16u strat); Bit16u DOS_GetMemAllocStrategy(void); void DOS_BuildUMBChain(void); bool DOS_LinkUMBsToMemChain(Bit16u linkstate); // FCB stuff bool FCB_OpenFile(Bit16u seg, Bit16u offset); bool FCB_CreateFile(Bit16u seg, Bit16u offset); bool FCB_CloseFile(Bit16u seg, Bit16u offset); bool FCB_FindFirst(Bit16u seg, Bit16u offset); bool FCB_FindNext(Bit16u seg, Bit16u offset); Bit8u FCB_ReadFile(Bit16u seg, Bit16u offset, Bit16u numBlocks); Bit8u FCB_WriteFile(Bit16u seg, Bit16u offset, Bit16u numBlocks); Bit8u FCB_RandomRead(Bit16u seg, Bit16u offset, Bit16u *numRec, bool restore); Bit8u FCB_RandomWrite(Bit16u seg, Bit16u offset, Bit16u *numRec, bool restore); bool FCB_GetFileSize(Bit16u seg, Bit16u offset); bool FCB_DeleteFile(Bit16u seg, Bit16u offset); bool FCB_RenameFile(Bit16u seg, Bit16u offset); void FCB_SetRandomRecord(Bit16u seg, Bit16u offset); Bit8u FCB_Parsename(Bit16u seg, Bit16u offset, Bit8u parser ,char *string, Bit8u *change); // Extra DOS Interrupts void DOS_SetupMisc(void); // The DOS Tables void DOS_SetupTables(void); static Bit16u long2para(Bit32u size) { if (size > 0xFFFF0) return 0xffff; return (Bit16u)((size+15)/16); } static Bit16u DOS_PackTime(Bit16u hour, Bit16u min, Bit16u sec) { return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f); } static Bit16u DOS_PackDate(Bit16u year, Bit16u mon, Bit16u day) { return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f); } // Dos Error Codes #define DOSERR_NONE 0 #define DOSERR_FUNCTION_NUMBER_INVALID 1 #define DOSERR_FILE_NOT_FOUND 2 #define DOSERR_PATH_NOT_FOUND 3 #define DOSERR_TOO_MANY_OPEN_FILES 4 #define DOSERR_ACCESS_DENIED 5 #define DOSERR_INVALID_HANDLE 6 #define DOSERR_MCB_DESTROYED 7 #define DOSERR_INSUFFICIENT_MEMORY 8 #define DOSERR_MB_ADDRESS_INVALID 9 #define DOSERR_ENVIRONMENT_INVALID 10 #define DOSERR_FORMAT_INVALID 11 #define DOSERR_ACCESS_CODE_INVALID 12 #define DOSERR_DATA_INVALID 13 #define DOSERR_RESERVED 14 #define DOSERR_FIXUP_OVERFLOW 14 #define DOSERR_INVALID_DRIVE 15 #define DOSERR_REMOVE_CURRENT_DIRECTORY 16 #define DOSERR_NOT_SAME_DEVICE 17 #define DOSERR_NO_MORE_FILES 18 #define DOSERR_DRIVE_NOT_READY 21 #define DOSERR_FILE_ALREADY_EXISTS 80 // Remains some classes used to access certain things #define sGet(s ,m) GetIt(sizeof(((s *)&pt)->m), (PhysPt)offsetof(s, m)) #define sSave(s, m, val) SaveIt(sizeof(((s *)&pt)->m), (PhysPt)offsetof(s, m), val) class MemStruct { public: Bitu GetIt(Bitu size, PhysPt addr) { switch (size) { case 1: return Mem_Lodsb(pt+addr); case 2: return Mem_Lodsw(pt+addr); case 4: return Mem_Lodsd(pt+addr); } return 0; } void SaveIt(Bitu size, PhysPt addr, Bitu val) { switch (size) { case 1: Mem_Stosb(pt+addr, (Bit8u)val); break; case 2: Mem_Stosw(pt+addr, (Bit16u)val); break; case 4: Mem_Stosd(pt+addr, (Bit32u)val); break; } } void SetPt(Bit16u seg) { pt = seg<<4; } void SetPt(Bit16u seg, Bit16u off) { pt = SegOff2Ptr(seg, off); } void SetPt(RealPt addr) { pt = dWord2Ptr(addr); } PhysPt GetPt(void) { return pt; } protected: PhysPt pt; }; class DOS_PSP :public MemStruct { public: DOS_PSP (Bit16u segment) {SetPt(segment); seg=segment;}; void MakeNew (Bit16u memSize); void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp); Bit16u FindFreeFileEntry (void); void CloseFiles (void); void SaveVectors (void); void RestoreVectors (void); void SetSize (Bit16u size) {sSave(sPSP, next_seg, size); }; Bit16u GetSize (void) {return (Bit16u)sGet(sPSP, next_seg); }; void SetEnvironment (Bit16u envseg) {sSave(sPSP, environment, envseg); }; Bit16u GetEnvironment (void) {return (Bit16u)sGet(sPSP, environment); }; Bit16u GetSegment (void) {return seg; }; void SetFileHandle (Bit16u index, Bit8u handle); Bit8u GetFileHandle (Bit16u index); void SetParent (Bit16u parent) {sSave(sPSP, psp_parent, parent); }; Bit16u GetParent (void) {return (Bit16u)sGet(sPSP, psp_parent); }; void SetStack (RealPt stackpt) {sSave(sPSP, stack, stackpt); }; RealPt GetStack (void) {return sGet(sPSP, stack); }; void SetInt22 (RealPt int22pt) {sSave(sPSP,int_22, int22pt); }; RealPt GetInt22 (void) {return sGet(sPSP, int_22); }; void SetFCB1 (RealPt src); void SetFCB2 (RealPt src); void SetCommandTail (RealPt src); void StoreCommandTail (void); void RestoreCommandTail (void); void SetNumFiles (Bit16u fileNum); Bit16u FindEntryByHandle (Bit8u handle); private: #ifdef _MSC_VER #pragma pack(1) #endif struct sPSP { Bit8u exit[2]; // CP/M-like exit poimt Bit16u next_seg; // Segment of first byte beyond memory allocated or program Bit8u fill_1; // single char fill Bit8u far_call; // far call opcode RealPt cpm_entry; // CPM Service Request address RealPt int_22; // Terminate Address RealPt int_23; // Break Address RealPt int_24; // Critical Error Address Bit16u psp_parent; // Parent PSP Segment Bit8u files[20]; // File Table - 0xff is unused Bit16u environment; // Segment of evironment table RealPt stack; // SS:SP Save point for int 0x21 calls Bit16u max_files; // Maximum open files RealPt file_table; // Pointer to File Table PSP:0x18 RealPt prev_psp; // Pointer to previous PSP Bit8u interim_flag; Bit8u truename_flag; Bit16u nn_flags; Bit16u dos_version; Bit8u fill_2[14]; // Lot's of unused stuff i can't care about Bit8u service[3]; // INT 0x21 Service call int 0x21;retf; Bit8u fill_3[9]; // This has some blocks with FCB info Bit8u fcb1[16]; // first FCB Bit8u fcb2[16]; // second FCB Bit8u fill_4[4]; // unused CommandTail cmdtail; }; #ifdef _MSC_VER #pragma pack() #endif Bit16u seg; public: static Bit16u rootpsp; }; class DOS_ParamBlock:public MemStruct { public: DOS_ParamBlock(PhysPt addr) {pt = addr;} void Clear(void); void LoadData(void); void SaveData(void); // Save it as an exec block #ifdef _MSC_VER #pragma pack (1) #endif struct sOverlay { Bit16u loadseg; Bit16u relocation; }; struct sExec { Bit16u envseg; RealPt cmdtail; RealPt fcb1; RealPt fcb2; RealPt initsssp; RealPt initcsip; }; #ifdef _MSC_VER #pragma pack() #endif sExec exec; sOverlay overlay; }; class DOS_InfoBlock:public MemStruct { public: DOS_InfoBlock () {}; void SetLocation(Bit16u seg); void SetFirstMCB(Bit16u _first_mcb); void SetBuffers(Bit16u x,Bit16u y); void SetCurDirStruct(Bit32u _curdirstruct); void SetFCBTable(Bit32u _fcbtable); void SetDeviceChainStart(Bit32u _devchain); void SetDiskBufferHeadPt(Bit32u _dbheadpt); void SetStartOfUMBChain(Bit16u _umbstartseg); void SetUMBChainState(Bit8u _umbchaining); Bit16u GetStartOfUMBChain(void); Bit8u GetUMBChainState(void); RealPt GetPointer(void); Bit32u GetDeviceChain(void); #ifdef _MSC_VER #pragma pack(1) #endif struct sDIB { Bit8u unknown1[4]; Bit16u magicWord; // -0x22 needs to be 1 Bit8u unknown2[8]; Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e Bit16u countLRUcache; // -0x16 LRU counter for FCB caching Bit16u countLRUopens; // -0x14 LRU counter for FCB openings Bit8u stuff[6]; // -0x12 some stuff, hopefully never used.... Bit16u sharingCount; // -0x0c sharing retry count Bit16u sharingDelay; // -0x0a sharing retry delay RealPt diskBufPtr; // -0x08 pointer to disk buffer Bit16u ptrCONinput; // -0x04 pointer to con input Bit16u firstMCB; // -0x02 first memory control block RealPt firstDPB; // 0x00 first drive parameter block RealPt firstFileTable; // 0x04 first system file table RealPt activeClock; // 0x08 active clock device header RealPt activeCon; // 0x0c active console device header Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device; RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer RealPt curDirStructure; // 0x16 pointer to current array of directory structure RealPt fcbTable; // 0x1a pointer to system FCB table Bit16u protFCBs; // 0x1e protected fcbs Bit8u blockDevices; // 0x20 installed block devices Bit8u lastdrive; // 0x21 lastdrive Bit32u nulNextDriver; // 0x22 NUL driver next pointer Bit16u nulAttributes; // 0x26 NUL driver aattributes Bit32u nulStrategy; // 0x28 NUL driver strategy routine Bit8u nulString[8]; // 0x2c NUL driver name string Bit8u joindedDrives; // 0x34 joined drives Bit16u specialCodeSeg; // 0x35 special code segment RealPt setverPtr; // 0x37 pointer to setver Bit16u a20FixOfs; // 0x3b a20 fix routine offset Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma) Bit16u buffers_x; // 0x3f x in BUFFERS x,y Bit16u buffers_y; // 0x41 y in BUFFERS x,y Bit8u bootDrive; // 0x43 boot drive Bit8u useDwordMov; // 0x44 use dword moves Bit16u extendedSize; // 0x45 size of extended memory Bit32u diskBufferHeadPt; // 0x47 pointer to least-recently used buffer header Bit16u dirtyDiskBuffers; // 0x4b number of dirty disk buffers Bit32u lookaheadBufPt; // 0x4d pointer to lookahead buffer Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers Bit8u bufferLocation; // 0x53 workspace buffer location Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer Bit8u unknown3[11]; // 0x58 Bit8u chainingUMB; // 0x63 bit0: UMB chain linked to MCB chain Bit16u minMemForExec; // 0x64 minimum paragraphs needed for current program Bit16u startOfUMBChain; // 0x66 segment of first UMB-MCB Bit16u memAllocScanStart; // 0x68 start paragraph for memory allocation }; #ifdef _MSC_VER #pragma pack () #endif Bit16u seg; }; class DOS_DTA:public MemStruct{ public: DOS_DTA(RealPt addr) { SetPt(addr); } void SetupSearch(Bit8u _sdrive,int handle,Bit8u _sattr,Bit8u _rattr,char * _pattern); void SetResult(int handle,const char * _name,const char * _lname,Bit32u _hsize,Bit32u _size,Bit16u _date,Bit16u _time,Bit16u _adate,Bit16u _atime,Bit16u _cdate,Bit16u _ctime,Bit8u _attr); int GetFindData(int fmt,char * finddata,int *c); Bit8u GetSearchDrive(int handle); void GetSearchParams(int handle,Bit8u & _sattr,Bit8u & _rattr,char * _spattern); void GetResult(int handle,char * _name,char * _lname,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr); private: #ifdef _MSC_VER #pragma pack(1) #endif struct sDTA { Bit8u sdrive; // The Drive the search is taking place Bit8u spname[8]; // The Search pattern for the filename Bit8u spext[3]; // The Search pattern for the extenstion Bit8u sattr; // The Attributes that need to be found Bit32u nop; // Custom: Windows search handle for multiple searches at the same time Bit8u fill[4]; Bit8u attr; Bit16u time; Bit16u date; Bit32u size; char name[DOS_NAMELENGTH_ASCII]; }; #ifdef _MSC_VER #pragma pack() #endif }; class DOS_FCB: public MemStruct { public: DOS_FCB(Bit16u seg, Bit16u off, bool allow_extended = true); void Create(bool _extended); void SetName(Bit8u _drive,char * _fname,char * _ext); void SetResult(Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr); void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time); void GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time); void GetName(char * fillname); void FileOpen(Bit8u _fhandle); void FileClose(Bit8u & _fhandle); void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec); void SetRecord(Bit16u _cur_block,Bit8u _cur_rec); void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size); void GetRandom(Bit32u & _random); void SetRandom(Bit32u _random); Bit8u GetDrive(void); bool Extended(void); void GetAttr(Bit8u & attr); void SetAttr(Bit8u attr); bool Valid(void); private: bool extended; PhysPt real_pt; #ifdef _MSC_VER #pragma pack (1) #endif struct sFCB { Bit8u drive; // Drive number 0=default, 1=A, etc Bit8u filename[8]; // Space padded name Bit8u ext[3]; // Space padded extension Bit16u cur_block; // Current Block Bit16u rec_size; // Logical record size Bit32u filesize; // File Size Bit16u date; Bit16u time; // Reserved Block should be 8 bytes Bit8u sft_entries; Bit8u share_attributes; Bit8u extra_info; Bit8u file_handle; Bit8u reserved[4]; // end Bit8u cur_rec; // Current record in current block Bit32u rndm; // Current relative record number }; #ifdef _MSC_VER #pragma pack () #endif }; class DOS_MCB : public MemStruct { public: DOS_MCB(Bit16u seg) { SetPt(seg);} void SetFileName(char const * const _name) { strncpy((char *)(MemBase+pt+offsetof(sMCB, filename)), _name, 8); } void GetFileName(char * const _name) { Mem_CopyFrom(pt+offsetof(sMCB, filename), _name, 8); _name[8] = 0;} void SetType(Bit8u _type) { sSave(sMCB, type, _type);} void SetSize(Bit16u _size) {sSave(sMCB, size, _size);} void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB, psp_segment, _pspseg); if (_pspseg == MCB_FREE) SetFileName(" ");} Bit8u GetType(void) { return (Bit8u)sGet(sMCB, type);} Bit16u GetSize(void) { return (Bit16u)sGet(sMCB, size);} Bit16u GetPSPSeg(void) { return (Bit16u)sGet(sMCB, psp_segment);} private: #ifdef _MSC_VER #pragma pack (1) #endif struct sMCB { Bit8u type; Bit16u psp_segment; Bit16u size; Bit8u unused[3]; Bit8u filename[8]; }; #ifdef _MSC_VER #pragma pack () #endif }; class DOS_SDA : public MemStruct { public: DOS_SDA(Bit16u _seg, Bit16u _offs) { SetPt(_seg, _offs); } void Init(); void SetDrive(Bit8u _drive) { sSave(sSDA, current_drive, _drive); } void SetDTA(Bit32u _dta) { sSave(sSDA, current_dta, _dta); } void SetPSP(Bit16u _psp) { sSave(sSDA, current_psp, _psp); } Bit8u GetDrive(void) { return (Bit8u)sGet(sSDA, current_drive); } Bit16u GetPSP(void) { return (Bit16u)sGet(sSDA, current_psp); } Bit32u GetDTA(void) { return (Bit32u)sGet(sSDA, current_dta); } private: #ifdef _MSC_VER #pragma pack (1) #endif struct sSDA { Bit8u crit_error_flag; // 0x00 Critical Error Flag Bit8u inDOS_flag; // 0x01 InDOS flag (count of active INT 21 calls) Bit8u drive_crit_error; // 0x02 Drive on which current critical error occurred or FFh Bit8u locus_of_last_error; // 0x03 locus of last error Bit16u extended_error_code; // 0x04 extended error code of last error Bit8u suggested_action; // 0x06 suggested action for last error Bit8u error_class; // 0x07 class of last error Bit32u last_error_pointer; // 0x08 ES:DI pointer for last error Bit32u current_dta; // 0x0C current DTA (Disk Transfer Address) Bit16u current_psp; // 0x10 current PSP Bit16u sp_int_23; // 0x12 stores SP across an INT 23 Bit16u return_code; // 0x14 return code from last process termination (zerod after reading with AH=4Dh) Bit8u current_drive; // 0x16 current drive Bit8u extended_break_flag; // 0x17 extended break flag Bit8u fill[2]; // 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort }; #ifdef _MSC_VER #pragma pack() #endif }; extern DOS_InfoBlock dos_infoblock; struct DOS_Block { DOS_Date date; bool hostdate; DOS_Version version; Bit16u firstMCB; Bit16u errorcode; Bit16u psp(){ return DOS_SDA(DOS_SDA_SEG, DOS_SDA_OFS).GetPSP(); }; void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG, DOS_SDA_OFS).SetPSP(_seg); }; Bit16u env; RealPt cpmentry; RealPt dta(){ return DOS_SDA(DOS_SDA_SEG, DOS_SDA_OFS).GetDTA(); }; void dta(RealPt _dta){ DOS_SDA(DOS_SDA_SEG, DOS_SDA_OFS).SetDTA(_dta); }; Bit8u return_code, return_mode; Bit8u current_drive; bool verify; bool breakcheck; bool echo; // If set to true dev_con::read will echo input struct { RealPt mediaid; RealPt tempdta; RealPt tempdta_fcbdelete; RealPt dbcs; RealPt filenamechar; RealPt collatingseq; RealPt upcase; Bit8u* country; // Will be copied to dos memory. resides in real mem Bit16u dpb; // Fake Disk parameter system using only the first entry so the drive letter matches } tables; Bit16u loaded_codepage; }; extern DOS_Block dos; static Bit8u RealHandle(Bit16u handle) { DOS_PSP psp(dos.psp()); return psp.GetFileHandle(handle); } #endif