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:
parent
79f9d333b3
commit
bd35a40c9d
8 changed files with 319 additions and 312 deletions
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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++));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue