diff --git a/include/dos_inc.h b/include/dos_inc.h index 8de46b2b..299e8358 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -29,32 +29,31 @@ struct CommandTail{ char buffer[127]; /* the buffer itself */ } GCC_ATTRIBUTE(packed); -struct PSP { - Bit8u exit[2]; /* CP/M-like exit poimt */ - Bit16u mem_size; /* memory size in paragraphs */ - Bit8u fill_1; /* single char fill */ +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 */ + RealPt dta; /* Pointer to current Process DTA */ + Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */ + 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; -/* CPM Stuff dunno what this is*/ -//TODO Add some checks for people using this i think - 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 */ - RealPt dta; /* Pointer to current Process DTA */ - Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */ - Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */ - Bit8u fill_3[45]; /* This has some blocks with FCB info */ - - CommandTail cmdtail; - } GCC_ATTRIBUTE(packed); struct ParamBlock { @@ -114,6 +113,76 @@ struct DOS_Block { } tables; }; +class MemStruct { +public: + Bit8u GetIt(Bit8u,PhysPt addr) { + return mem_readb(pt+addr); + }; + Bit16u GetIt(Bit16u,PhysPt addr) { + return mem_readw(pt+addr); + }; + Bit32u GetIt(Bit32u,PhysPt addr) { + return mem_readd(pt+addr); + }; + void SaveIt(Bit8u,PhysPt addr,Bit8u val) { + mem_writeb(pt+addr,val); + }; + void SaveIt(Bit16u,PhysPt addr,Bit16u val) { + mem_writew(pt+addr,val); + }; + void SaveIt(Bit32u,PhysPt addr,Bit32u val) { + mem_writed(pt+addr,val); + }; + + +protected: +PhysPt pt; + +}; + +#define sGet(s,m) GetIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m)) +#define sSave(s,m,val) SaveIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m),val) + +class DOS_PSP :public MemStruct { +public: + DOS_PSP () { seg=0; pt=0; }; + DOS_PSP (Bit16u segment) { NewPt(segment); }; + void NewPt (Bit16u segment); + void MakeNew (Bit16u memSize); + + void CopyFileTable (DOS_PSP* srcpsp); + Bit16u FindFreeFileEntry (void); + void CloseFiles (void); + + void SaveVectors (void); + void RestoreVectors (void); + void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; + Bit16u GetSize () { return sGet(sPSP,next_seg); }; + void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); }; + RealPt GetDTA (void) { return sGet(sPSP,dta); }; + void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; + Bit16u GetEnvironment (void) { return 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 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); + +private: + Bit16u seg; + sPSP* psp; + +public: + static Bit16u rootpsp; +}; + enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; @@ -170,7 +239,7 @@ bool DOS_GetSTDINStatus(); Bit8u DOS_FindDevice(char * name); void DOS_SetupDevices(void); /* Execute and new process creation */ -bool DOS_NewPSP(Bit16u pspseg); +bool DOS_NewPSP(Bit16u pspseg,Bit16u size); bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags); bool DOS_Terminate(bool tsr); @@ -213,9 +282,9 @@ INLINE Bit16u long2para(Bit32u size) { }; INLINE Bit8u RealHandle(Bit16u handle) { - PSP * psp=(PSP *)HostMake(dos.psp,0); - if (handle>=psp->max_files) return 0xff; - return mem_readb(Real2Phys(psp->file_table)+handle); + + DOS_PSP psp(dos.psp); + return psp.GetFileHandle((Bit8u)handle); }; /* Dos Error Codes */ @@ -274,8 +343,6 @@ private: PhysPt off; }; - - class DOS_ParamBlock { public: DOS_ParamBlock(PhysPt pt){ diff --git a/include/programs.h b/include/programs.h index d716510c..8151ce5b 100644 --- a/include/programs.h +++ b/include/programs.h @@ -26,7 +26,7 @@ char * MSG_Get(char * msg); struct PROGRAM_Info { Bit16u psp_seg; - PSP psp_copy; + sPSP psp_copy; char full_name[32]; //Enough space for programs only on the z:\ drive char * cmd_line; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index f847aced..bee05a3d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -313,7 +313,7 @@ static Bitu DOS_21Handler(void) { RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ - DOS_NewPSP(reg_dx); + DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize()); break; case 0x2a: /* Get System Date */ reg_al=0; /* It's always sunday TODO find that correct formula */ @@ -685,9 +685,12 @@ static Bitu DOS_21Handler(void) { case 0x53: /* Translate BIOS parameter block to drive parameter block */ //YEAH RIGHT case 0x54: /* Get verify flag */ - case 0x55: /* Create Child PSP*/ E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; + case 0x55: /* Create Child PSP*/ + DOS_NewPSP(reg_dx,reg_si); + dos.psp = reg_dx; + break; case 0x56: /* RENAME Rename file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); MEM_StrCopy(SegPhys(es)+reg_di,name2,DOSNAMEBUF); diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index f84995ed..a63e5302 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -31,32 +31,6 @@ #pragma pack (1) -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 */ - -/* CPM Stuff dunno what this is*/ -//TODO Add some checks for people using this i think - 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 */ - RealPt dta; /* Pointer to current Process DTA */ - Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */ - Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */ - Bit8u fill_3[45]; /* This has some blocks with FCB info */ - CommandTail cmdtail; -} GCC_ATTRIBUTE(packed); - union sParamBlock { struct { Bit16u loadseg; @@ -88,100 +62,6 @@ struct sFCB { #pragma pack () -#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) -#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) - - -class MemStruct { -public: - Bit8u GetIt(Bit8u,PhysPt addr) { - return mem_readb(pt+addr); - }; - Bit16u GetIt(Bit16u,PhysPt addr) { - return mem_readw(pt+addr); - }; - Bit32u GetIt(Bit32u,PhysPt addr) { - return mem_readd(pt+addr); - }; - void SaveIt(Bit8u,PhysPt addr,Bit8u val) { - mem_writeb(pt+addr,val); - }; - void SaveIt(Bit16u,PhysPt addr,Bit16u val) { - mem_writew(pt+addr,val); - }; - void SaveIt(Bit32u,PhysPt addr,Bit32u val) { - mem_writed(pt+addr,val); - }; - - -private: -PhysPt pt; - -}; - - -class DOS_PSP :public MemStruct { -public: - DOS_PSP(Bit16u segment){NewPt(segment);}; - void NewPt(Bit16u segment); - void MakeNew(Bit16u mem_size); - Bit8u GetFileHandle(Bitu index); - -private: - Bit16u seg; - PhysPt pt; -}; - -void DOS_PSP::NewPt(Bit16u segment) { - seg=segment; - pt=PhysMake(segment,0); -}; - - - -void DOS_PSP::MakeNew(Bit16u mem_size) { - Bitu i; - /* Clear it first */ - for (i=0;i<256;i++) mem_writeb(pt+i,0); - /* Standard blocks,int 20 and int21 retf */ - sGet(sPSP,max_files); - sSave(sPSP,exit[0],0xcd); - sSave(sPSP,exit[1],0x20); - sSave(sPSP,service[0],0xcd); - sSave(sPSP,service[1],0x21); - sSave(sPSP,service[2],0xcb); - /* psp and psp-parent */ - sSave(sPSP,psp_parent,dos.psp); - sSave(sPSP,prev_psp,RealMake(dos.psp,0)); - /* terminate 22,break 23,crititcal error 24 address stored */ - sSave(sPSP,int_22,RealGetVec(0x22)); - sSave(sPSP,int_23,RealGetVec(0x23)); - sSave(sPSP,int_24,RealGetVec(0x24)); - /* Memory size */ - sSave(sPSP,next_seg,seg+mem_size); - /* Process DTA */ - sSave(sPSP,dta,RealMake(seg,128)); - /* User Stack pointer */ - //Copy from previous psp - // mem_writed(pt+offsetof(sPSP,stack), - - /* Init file pointer and max_files */ - sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); - sSave(sPSP,max_files,20); - /* Copy file table from calling process */ - for (i=0;i<20;i++) { - Bit8u handle=0; - // Bitu handle=dos.psp.GetFileHandle(i); - sSave(sPSP,files[i],handle); - } -} - -Bit8u DOS_PSP::GetFileHandle(Bitu index) { - if (index>=sGet(sPSP,max_files)) return 0xff; - PhysPt files=Real2Phys(sGet(sPSP,file_table)); - return mem_readb(files+index); -}; - #define FCB_EXTENDED (mem_readb(off)==0xFF ? 7:0) void DOS_FCB::Set_drive(Bit8u a){ @@ -298,3 +178,132 @@ void DOS_InfoBlock::GetDIBPointer(Bit16u& segment, Bit16u& offset) segment = seg; offset = offsetof(SDosInfoBlock,firstDPB); }; + + +/* program Segment prefix */ + +Bit16u DOS_PSP::rootpsp = 0; + +void DOS_PSP::NewPt(Bit16u segment) +{ + seg = segment; + pt = PhysMake(segment,0); + // debug + psp = (sPSP*)Phys2Host(pt); +}; + +void DOS_PSP::MakeNew(Bit16u mem_size) +{ + /* get previous */ + DOS_PSP prevpsp(dos.psp); + /* Clear it first */ + for (Bitu i=0;inext_seg,0,mem_size); + sSave(sPSP,next_seg,mem_size); + /* far call opcode */ + sSave(sPSP,far_call,0xea); +// sSave(sPSP,cmp_entry + /* Standard blocks,int 20 and int21 retf */ + sSave(sPSP,exit[0],0xcd); + sSave(sPSP,exit[1],0x20); + sSave(sPSP,service[0],0xcd); + sSave(sPSP,service[1],0x21); + sSave(sPSP,service[2],0xcb); + /* psp and psp-parent */ + sSave(sPSP,psp_parent,dos.psp); + sSave(sPSP,prev_psp,RealMake(dos.psp,0)); + /* terminate 22,break 23,crititcal error 24 address stored */ + SaveVectors(); + /* Memory size */ + sSave(sPSP,next_seg,seg+mem_size); + /* Process DTA */ + sSave(sPSP,dta,RealMake(seg,128)); + /* FCBs are filled with 0 */ + // .... + /* Init file pointer and max_files */ + sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); + sSave(sPSP,max_files,20); + for (i=0;i<20;i++) SetFileHandle(i,0xff); + + /* User Stack pointer */ + if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); + + if (rootpsp==0) rootpsp = seg; +} + +Bit8u DOS_PSP::GetFileHandle(Bit16u index) +{ + if (index>=sGet(sPSP,max_files)) return 0xff; + PhysPt files=Real2Phys(sGet(sPSP,file_table)); + return mem_readb(files+index); +}; + +void DOS_PSP::SetFileHandle(Bit16u index, Bit8u handle) +{ + if (indexGetFileHandle(i); + SetFileHandle(i,handle); + } +}; + +void DOS_PSP::CloseFiles(void) +{ + for (Bit16u i=0;imax_files;i++) { - DOS_CloseFile(i); - } - DOS_FreeProcessMemory(dos.psp); - }; - dos.psp=psp->psp_parent; - PSP * oldpsp=(PSP *)HostMake(dos.psp,0); - /* Restore the DTA */ - dos.dta=psp->dta; - /* Restore the old CS:IP from int 22h */ - RealPt old22; - old22=RealGetVec(0x22); - SegSet16(cs,RealSeg(old22)); - reg_ip=RealOff(old22); - /* Restore the SS:SP to the previous one */ - SegSet16(ss,RealSeg(oldpsp->stack)); - reg_sp=RealOff(oldpsp->stack); - /* Restore interrupt 22,23,24 */ - RealSetVec(0x22,psp->int_22); - RealSetVec(0x23,psp->int_23); - RealSetVec(0x24,psp->int_24); + Bit16u mempsp = dos.psp; + DOS_PSP curpsp(dos.psp); + if (dos.psp==curpsp.GetParent()) return true; + + /* Free Files owned by process */ + if (!tsr) curpsp.CloseFiles(); + // restore vectors + curpsp.RestoreVectors(); + // Set parent psp + dos.psp = curpsp.GetParent(); + DOS_PSP parentpsp(curpsp.GetParent()); + /* Restore the DTA */ + parentpsp.SetDTA(curpsp.GetDTA()); + /* Restore the SS:SP to the previous one */ + SegSet16(ss,RealSeg(parentpsp.GetStack())); + reg_sp = RealOff(parentpsp.GetStack()); + /* Restore the old CS:IP from int 22h */ + RealPt old22 = curpsp.GetInt22(); + reg_ip = RealOff(old22); + SegSet16 (cs,RealSeg(old22)); + // Free memory owned by process + if (!tsr) DOS_FreeProcessMemory(mempsp); + return true; } @@ -97,14 +96,14 @@ bool DOS_Terminate(bool tsr) { static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); Bit8u * envread,*envwrite; Bit16u envsize=1; bool parentenv=true; if (*segment==0) { - if (!psp->environment) parentenv=false; //environment seg=0 - envread=HostMake(psp->environment,0); + if (!psp.GetEnvironment()) parentenv=false; //environment seg=0 + envread=HostMake(psp.GetEnvironment(),0); } else { if (!*segment) parentenv=false; //environment seg=0 envread=HostMake(*segment,0); @@ -136,103 +135,51 @@ static bool MakeEnv(char * name,Bit16u * segment) { return DOS_Canonicalize(name,(char *)envwrite); }; -bool DOS_NewPSP(Bit16u pspseg) { - PSP * newpsp=(PSP *)HostMake(pspseg,0); - PSP * prevpsp=(PSP *)HostMake(dos.psp,0); - - memset((void *)newpsp,0,sizeof(PSP)); - newpsp->exit[0]=0xcd;newpsp->exit[1]=0x20; - newpsp->service[0]=0xcd;newpsp->service[0]=0x21;newpsp->service[0]=0xcb; - - newpsp->mem_size=prevpsp->mem_size; - newpsp->environment=0; - - newpsp->int_22=RealGetVec(0x22); - newpsp->int_23=RealGetVec(0x23); - newpsp->int_24=RealGetVec(0x24); - - newpsp->psp_parent=dos.psp; - newpsp->prev_psp=0xFFFFFFFF; - - Bit32u i; - Bit8u * prevfile=Real2Host(prevpsp->file_table); - for (i=0;i<20;i++) newpsp->files[i]=prevfile[i]; - - newpsp->max_files=20; - newpsp->file_table=RealMake(pspseg,offsetof(PSP,files)); - /* Save the old DTA in this psp */ - newpsp->dta=dos.dta; - /* Setup the DTA */ - dos.dta=RealMake(pspseg,0x80); +bool DOS_NewPSP(Bit16u segment, Bit16u size) +{ + DOS_PSP psp(segment); + psp.MakeNew(size); + psp.CopyFileTable(&DOS_PSP(psp.GetParent())); return true; }; static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { - PSP * psp=(PSP *)HostMake(pspseg,0); /* Fix the PSP index of this MCB */ MCB * pspmcb=(MCB *)HostMake(pspseg-1,0); pspmcb->psp_segment=pspseg; MCB * envmcb=(MCB *)HostMake(envseg-1,0); envmcb->psp_segment=pspseg; - memset((void *)psp,0,sizeof(PSP)); - Bit32u i; - - psp->exit[0]=0xcd;psp->exit[1]=0x20; - psp->mem_size=memsize+pspseg; - psp->environment=envseg; - - psp->int_22=RealGetVec(0x22); - psp->int_23=RealGetVec(0x23); - psp->int_24=RealGetVec(0x24); - - psp->service[0]=0xcd;psp->service[0]=0x21;psp->service[0]=0xcb; - - psp->psp_parent=dos.psp; - psp->prev_psp=RealMake(dos.psp,0); - - for (i=0;i<20;i++) psp->files[i]=0xff; - psp->files[STDIN]=DOS_FindDevice("CON"); - psp->files[STDOUT]=DOS_FindDevice("CON"); - psp->files[STDERR]=DOS_FindDevice("CON"); - psp->files[STDAUX]=DOS_FindDevice("CON"); - psp->files[STDNUL]=DOS_FindDevice("CON"); - psp->files[STDPRN]=DOS_FindDevice("CON"); - - psp->max_files=20; - psp->file_table=RealMake(pspseg,offsetof(PSP,files)); + DOS_PSP psp(pspseg); + psp.MakeNew(memsize+pspseg); + psp.SetEnvironment(envseg); + psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); + psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); + psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); + psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); + psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); + psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); /* Save old DTA in psp */ - psp->dta=dos.dta; - + psp.SetDTA(dos.dta); /* Setup the DTA */ dos.dta=RealMake(pspseg,0x80); } -static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) { - PSP * psp=(PSP *)HostMake(pspseg,0); - - if (block->exec.cmdtail) { - memcpy((void *)&psp->cmdtail,(void *)Real2Host(block->exec.cmdtail),128); - } else { - char temp[]=""; - psp->cmdtail.count=strlen(temp); - strcpy((char *)&psp->cmdtail.buffer,temp); - psp->cmdtail.buffer[0]=0x0d; - - } +static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) +{ + DOS_PSP psp(pspseg); + // if cmdtail==0 it will inited as empty in SetCommandTail + psp.SetCommandTail(block->exec.cmdtail); } - - - static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { Bit16u fhandle; Bit16u size;Bit16u readsize; Bit16u envseg,comseg; Bit32u pos; - PSP * callpsp=(PSP *)HostMake(dos.psp,0); + DOS_PSP callpsp(dos.psp); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -269,14 +216,20 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { SetupCMDLine(comseg,block); /* Setup termination Address */ RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); + DOS_PSP compsp(comseg); + compsp.SetInt22(RealMakeSeg(cs,reg_ip)); /* Everything setup somewhat setup CS:IP and SS:SP */ /* First save the SS:SP of program that called execute */ - callpsp->stack=RealMakeSeg(ss,reg_sp); + callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Clear out first Stack entry to point to int 20h at psp:0 */ real_writew(comseg,0xfffe,0); dos.psp=comseg; switch (flag) { case LOADNGO: + /* copy fcbs */ + compsp.SetFCB1(block->exec.fcb1); + compsp.SetFCB2(block->exec.fcb2); + /* setup reg */ SegSet16(cs,comseg); SegSet16(ss,comseg); SegSet16(ds,comseg); @@ -310,7 +263,7 @@ static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { ParamBlock block; memcpy(&block,_block,sizeof(ParamBlock)); - PSP * callpsp=(PSP *)HostMake(dos.psp,0); + DOS_PSP callpsp(dos.psp); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -401,9 +354,11 @@ static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { /* Setup termination Address */ RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); + DOS_PSP exepsp(pspseg); + exepsp.SetInt22(RealMakeSeg(cs,reg_ip)); /* Start up the actual EXE if we need to */ //TODO check for load and return - callpsp->stack=RealMakeSeg(ss,reg_sp); + callpsp.SetStack(RealMakeSeg(ss,reg_sp)); dos.psp=pspseg; SegSet16(cs,exeseg+header.initCS); SegSet16(ss,exeseg+header.initSS); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index dab3a320..7a8c5a9d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -269,9 +269,9 @@ bool DOS_CloseFile(Bit16u entry) { }; //TODO Figure this out with devices :) - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - table[entry]=0xFF; + DOS_PSP psp(dos.psp); + psp.SetFileHandle(entry,0xff); + /* Devices won't allow themselves to be closed or killed */ if (Files[handle]->Close()) { delete Files[handle]; @@ -282,7 +282,7 @@ bool DOS_CloseFile(Bit16u entry) { bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { char fullname[DOS_PATHLENGTH];Bit8u drive; - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES;Bit8u i; @@ -297,21 +297,14 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { return false; } /* We have a position in the main table now find one in the psp table */ - Bit8u * table=Real2Host(psp->file_table); - *entry=0xff; - for (i=0;imax_files;i++) { - if (table[i]==0xFF) { - *entry=i; - break; - } - } + *entry = psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { - table[*entry]=handle; + psp.SetFileHandle(*entry,handle); return true; } else { return false; @@ -320,7 +313,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; if (handle!=255) { @@ -341,14 +334,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } /* We have a position in the main table now find one in the psp table */ - Bit8u * table=Real2Host(psp->file_table); - *entry=0xff; - for (i=0;imax_files;i++) { - if (table[i]==0xFF) { - *entry=i; - break; - } - } + *entry = psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; @@ -356,7 +342,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { bool exists=false; if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists || device ) { - table[*entry]=handle; + psp.SetFileHandle(*entry,handle); return true; } else { DOS_SetError(DOSERR_FILE_NOT_FOUND); @@ -413,20 +399,13 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - *newentry=0xff; - for (Bit16u i=0;imax_files;i++) { - if (table[i]==0xFF) { - *newentry=i; - break; - } - } + DOS_PSP psp(dos.psp); + *newentry = psp.FindFreeFileEntry(); if (*newentry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } - table[*newentry]=handle; + psp.SetFileHandle(*newentry,handle); return true; }; @@ -449,9 +428,8 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_CloseFile(newentry); return false; }; - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - table[newentry]=(Bit8u)entry; + DOS_PSP psp(dos.psp); + psp.SetFileHandle(newentry,(Bit8u)entry); return true; }; @@ -522,7 +500,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * Bit8u retwaarde=0; char naam[9]=" "; char ext[4]=" "; - if(parser & 1) { //ignore leading seperator + if((parser & 1) && *string) { //ignore leading seperator char sep[] = FCB_SEP; char a[2]; a[0]= *string;a[1]='\0'; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 6b66f009..b1f7b490 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -60,7 +60,7 @@ static Bitu PROGRAMS_Handler(void) { /* First get the current psp */ PROGRAM_Info * info=new PROGRAM_Info; info->psp_seg=dos.psp; - MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(sPSP)); /* Get the file name cmd_line 0 */ PhysPt envblock=PhysMake(info->psp_copy.environment,0); do {} while (mem_readw(envblock++)); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2020d9b5..62000851 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -149,29 +149,24 @@ void SHELL_Init() { env_mcb->size=4096/16; real_writed(env_seg+1,0,0); - PSP * psp=(PSP *)HostMake(psp_seg,0); - Bit32u i; - for (i=0;i<20;i++) psp->files[i]=0xff; - psp->files[STDIN]=DOS_FindDevice("CON"); - psp->files[STDOUT]=DOS_FindDevice("CON"); - psp->files[STDERR]=DOS_FindDevice("CON"); - psp->files[STDAUX]=DOS_FindDevice("CON"); - psp->files[STDNUL]=DOS_FindDevice("CON"); - psp->files[STDPRN]=DOS_FindDevice("CON"); - psp->max_files=20; - psp->file_table=RealMake(psp_seg,offsetof(PSP,files)); - /* Save old DTA in psp */ - psp->dta=dos.dta; + DOS_PSP psp(psp_seg); psp.MakeNew(env_mcb->size); + psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); + psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); + psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); + psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); + psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); + psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); + psp.SetParent(psp_seg); /* Set the environment and clear it */ - psp->environment=env_seg+1; - mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); + psp.SetEnvironment(env_seg+1); + mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); /* Setup internal DOS Variables */ - dos.dta=RealMake(psp_seg,0x80); + dos.dta=psp.GetDTA(); dos.psp=psp_seg; PROGRAM_Info info; strcpy(info.full_name,"Z:\\COMMAND.COM"); info.psp_seg=psp_seg; - MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(sPSP)); char line[256]; strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); info.cmd_line=line;