void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) { /* Copy file table from calling process */ for (Bit16u i=0;i<20;i++) { Bit8u handle = srcpsp->GetFileHandle(i); if(createchildpsp) { //copy obeying not inherit flag.(but dont duplicate them) bool allowCopy = true;//(handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); if((handle<DOS_FILES) && Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT) && allowCopy) { Files[handle]->AddRef(); SetFileHandle(i,handle); } else { SetFileHandle(i,0xff); } } else { //normal copy so don't mind the inheritance SetFileHandle(i,handle); } } }
void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ // DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bitu i; const Bitu Bit8uSize = sizeof(Bit8u); const Bitu Bit16uSize = sizeof(Bit16u); const Bitu RealPtSize = sizeof(RealPt); const Bitu CommandTailSize = sizeof(CommandTail); const Bitu sizePSP = sizeof(sPSP); for (i=0;i<sizePSP;i++) mem_writeb(pt+i,0); // Set size sSave(sPSP,next_seg,seg+mem_size); /* far call opcode */ sSave(sPSP,far_call,0xea); // far call to interrupt 0x21 - faked for bill & ted // lets hope nobody really uses this address sSave(sPSP,cpm_entry,RealMake(0xDEAD,0xFFFF)); /* 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,0xffffffff); sSave(sPSP,dos_version,0x0005); /* terminate 22,break 23,crititcal error 24 address stored */ SaveVectors(); /* FCBs are filled with 0 */ // .... /* Init file pointer and max_files */ sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files))); sSave(sPSP,max_files,20); for (Bit16u ct=0;ct<20;ct++) SetFileHandle(ct,0xff); /* User Stack pointer */ // if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); if (rootpsp==0) rootpsp = seg; }
void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ // DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bit16u i; for (i=0;i<sizeof(sPSP);i++) mem_writeb(pt+i,0); // Set size sSave(sPSP,next_seg,(unsigned int)seg+mem_size); /* cpm_entry is an alias for the int 30 vector (0:c0 = c:0); the offset is also the maximum program size */ if (cpm_compat_mode == CPM_COMPAT_MSDOS2) { /* MS-DOS 2.x behavior, where offset is the memory size (for some reason) */ /* far call opcode */ sSave(sPSP,far_call,0x9a); /* and where to call to */ if (mem_size>CPM_MAX_SEG_SIZE) mem_size=CPM_MAX_SEG_SIZE; mem_size-=0x10; sSave(sPSP,cpm_entry,RealMake(0xc-mem_size,mem_size<<4)); } else if (cpm_compat_mode == CPM_COMPAT_MSDOS5) { /* MS-DOS 5.x behavior, for whatever reason */ /* far call opcode */ sSave(sPSP,far_call,0x9a); /* and where to call to. * if 64KB or more, call far to F01D:FEF0. * else, call far to 0000:00C0. * don't ask me why MS-DOS 5.0 does this, ask Microsoft. */ if (mem_size >= CPM_MAX_SEG_SIZE) sSave(sPSP,cpm_entry,RealMake(0xF01D,0xFEF0)); else sSave(sPSP,cpm_entry,RealMake(0x0000,0x00C0)); } else if (cpm_compat_mode == CPM_COMPAT_DIRECT) { /* direct and to the point, though impossible to hook INT 21h without patching all PSP segments * which is probably why Microsoft never did this in the DOS kernel. Choosing this method * removes the need for the copy of INT 30h in the HMA area, and therefore opens up all 64KB of * HMA if you want. */ Bit32u DOS_Get_CPM_entry_direct(void); /* far call opcode */ sSave(sPSP,far_call,0x9a); /* and where to call to */ sSave(sPSP,cpm_entry,DOS_Get_CPM_entry_direct()); } else { /* off */ /* stick an INT 20h in there to make calling the CP/M entry point an immediate exit */ /* this is NOT default, but an option for users who are absolutely certain no CP/M code is going to run in their DOS box. */ sSave(sPSP,far_call,0xCD); // INT 20h + NOP NOP NOP sSave(sPSP,cpm_entry,0x90909020); } /* 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,0xffffffff); sSave(sPSP,dos_version,0x0005); /* terminate 22,break 23,crititcal error 24 address stored */ SaveVectors(); /* FCBs are filled with 0 */ // .... /* Init file pointer and max_files */ sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files))); sSave(sPSP,max_files,20); for (Bit16u ct=0;ct<20;ct++) SetFileHandle(ct,0xff); /* User Stack pointer */ // if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); if (rootpsp==0) rootpsp = seg; }