1
0
Fork 0

new psp class used for all psp actions

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@264
This commit is contained in:
Ulf Wohlers 2002-09-08 09:59:16 +00:00
parent 79f9d333b3
commit bd35a40c9d
8 changed files with 319 additions and 312 deletions

View file

@ -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){

View file

@ -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;
};

View file

@ -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);

View file

@ -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;i<sizeof(sPSP);i++) mem_writeb(pt+i,0);
// Set size
// SaveIt(((sPSP*)Phys2Host(pt))->next_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 (index<sGet(sPSP,max_files)) {
PhysPt files=Real2Phys(sGet(sPSP,file_table));
mem_writeb(files+index,handle);
}
};
Bit16u DOS_PSP::FindFreeFileEntry(void)
{
PhysPt files=Real2Phys(sGet(sPSP,file_table));
for (Bit16u i=0;i<sGet(sPSP,max_files);i++) {
if (mem_readb(files+i)==0xff) return i;
}
return 0xff;
};
void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp)
{
/* Copy file table from calling process */
for (Bit16u i=0;i<20;i++) {
Bit8u handle = srcpsp->GetFileHandle(i);
SetFileHandle(i,handle);
}
};
void DOS_PSP::CloseFiles(void)
{
for (Bit16u i=0;i<sGet(sPSP,max_files);i++) {
DOS_CloseFile(i);
}
}
void DOS_PSP::SaveVectors(void)
{
/* Save interrupt 22,23,24 */
sSave(sPSP,int_22,RealGetVec(0x22));
sSave(sPSP,int_23,RealGetVec(0x23));
sSave(sPSP,int_24,RealGetVec(0x24));
};
void DOS_PSP::RestoreVectors(void)
{
/* Restore interrupt 22,23,24 */
RealSetVec(0x22,sGet(sPSP,int_22));
RealSetVec(0x23,sGet(sPSP,int_23));
RealSetVec(0x24,sGet(sPSP,int_24));
};
void DOS_PSP::SetCommandTail(RealPt src)
{
if (src) { // valid source
memcpy((void*)(Phys2Host(pt)+offsetof(sPSP,cmdtail)),(void*)Real2Host(src),128);
} else { // empty
sSave(sPSP,cmdtail.count,0x00);
mem_writeb(pt+offsetof(sPSP,cmdtail.buffer[0]),0x0d);
};
};
void DOS_PSP::SetFCB1(RealPt src)
{
if (src) MEM_BlockCopy(PhysMake(seg,offsetof(sPSP,fcb1)),Real2Phys(src),16);
};
void DOS_PSP::SetFCB2(RealPt src)
{
if (src) MEM_BlockCopy(PhysMake(seg,offsetof(sPSP,fcb2)),Real2Phys(src),16);
};

View file

@ -64,31 +64,30 @@ __attribute__ ((packed));
bool DOS_Terminate(bool tsr) {
PSP * psp=(PSP *)HostMake(dos.psp,0);
if (!tsr) {
/* Free Files owned by process */
for (Bit16u i=0;i<psp->max_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);

View file

@ -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;i<psp->max_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;i<psp->max_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;i<psp->max_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';

View file

@ -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++));

View file

@ -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;