unsigned ReqProg_go( void ) { prog_go_ret *ret; unsigned len; if( !TaskLoaded ) { ret = GetOutPtr( 0 ); ret->conditions = COND_TERMINATE; return( sizeof( *ret ) ); } RestoreVectors( CurrVectors ); len = DoAccess(); SaveVectors( CurrVectors ); RestoreVectors( LoadVectors ); return( len ); }
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; }
unsigned ReqProg_load( void ) { char buffer[160]; char *src; char *dst; char *name; char *endparm; char *err; tiny_ret_t rc; prog_load_ret *ret; unsigned_16 len; SaveVectors( OrigVectors ); _DBG_EnterFunc( "AccLoadProg()" ); ret = GetOutPtr( 0 ); src = name = GetInPtr( sizeof( prog_load_req ) ); rc = FindFilePath( src, buffer, DosXExtList ); endparm = LinkParm; while( *endparm++ != '\0' ) {} // skip program name strcpy( endparm, buffer ); err = RemoteLink( LinkParm, 0 ); if( err != NULL ) { _DBG_Writeln( "Can't RemoteLink" ); TinyWrite( TINY_ERR, err, strlen( err ) ); LoadError = err; ret->err = 1; len = 0; } else { if( TINY_OK( rc ) ) { while( *src++ != '\0' ) {} len = GetTotalSize() - ( src - name ) - sizeof( prog_load_req ); dst = (char *)buffer; while( *dst++ != '\0' ) {}; memcpy( dst, src, len ); dst += len; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( sizeof( prog_load_req ), In_Mx_Ptr[0].ptr ); _DBG_Writeln( "AddPacket" ); AddPacket( dst - buffer, buffer ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); len = GetPacket(); _DBG_Writeln( "RemovePacket" ); RemovePacket( sizeof( *ret ), ret ); } else { len = DoAccess(); } _DBG_Writeln( "Linked --" ); if( ret->err != 0 ) { get_err_text_req erracc; prog_kill_req killacc; int msg_len; _DBG_Writeln( "loadret->errcode != 0" ); if( LoadError == NULL ) { _DBG_Writeln( "making a REQ_GET_ERR_TEXT request" ); erracc.req = REQ_GET_ERR_TEXT; erracc.err = ret->err; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( sizeof( erracc ), &erracc ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); msg_len = GetPacket(); _DBG_Writeln( "RemovePacket" ); RemovePacket( msg_len, FailMsg ); _DBG_Write( "FailMsg : " ); _DBG_NoTabWriteln( FailMsg ); LoadError = FailMsg; } _DBG_Writeln( "making a REQ_PROG_KILL request" ); killacc.req = REQ_PROG_KILL; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( sizeof( killacc ), &killacc ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); GetPacket(); //RemovePacket( msg_len, &erracc ); RemoteUnLink(); TaskLoaded = FALSE; } } if( ret->err == 0 ) { _DBG_Writeln( "loadret->error_code == 0" ); TaskLoaded = TRUE; } SaveVectors( LoadVectors ); SaveVectors( CurrVectors ); _DBG_ExitFunc( "AccLoadProg()" ); return( len ); }
trap_retval ReqProg_load( void ) { char buffer[160]; char *src; char *dst; char *name; char *endparm; const char *err; tiny_ret_t rc; prog_load_ret *ret; trap_elen len; SaveVectors( OrigVectors ); _DBG_EnterFunc( "AccLoadProg()" ); ret = GetOutPtr( 0 ); src = name = GetInPtr( sizeof( prog_load_req ) ); rc = FindProgFile( src, buffer, DosExtList ); endparm = LinkParms; while( *endparm++ != '\0' ) {} // skip trap parameters strcpy( endparm, buffer ); // add command line // result is as follow // "trap parameters string"+"\0"+"command line string"+"\0" err = RemoteLink( LinkParms, false ); if( err != NULL ) { _DBG_Writeln( "Can't RemoteLink" ); TinyWrite( TINY_ERR, err, strlen( err ) ); LoadError = err; ret->err = 1; len = 0; } else { if( TINY_OK( rc ) ) { while( *src++ != '\0' ) {} len = GetTotalSize() - ( src - name ) - sizeof( prog_load_req ); dst = (char *)buffer; while( *dst++ != '\0' ) {}; memcpy( dst, src, len ); dst += len; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( In_Mx_Ptr[0].ptr, sizeof( prog_load_req ) ); _DBG_Writeln( "AddPacket" ); AddPacket( buffer, dst - buffer ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); len = GetPacket(); _DBG_Writeln( "RemovePacket" ); RemovePacket( ret, sizeof( *ret ) ); } else { len = DoAccess(); } _DBG_Writeln( "Linked --" ); if( ret->err != 0 ) { get_err_text_req erracc; prog_kill_req killacc; trap_elen msg_len; _DBG_Writeln( "loadret->errcode != 0" ); if( LoadError == NULL ) { _DBG_Writeln( "making a REQ_GET_ERR_TEXT request" ); erracc.req = REQ_GET_ERR_TEXT; erracc.err = ret->err; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( &erracc, sizeof( erracc ) ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); msg_len = GetPacket(); _DBG_Writeln( "RemovePacket" ); RemovePacket( FailMsg, msg_len ); _DBG_Write( "FailMsg : " ); _DBG_NoTabWriteln( FailMsg ); LoadError = FailMsg; } _DBG_Writeln( "making a REQ_PROG_KILL request" ); killacc.req = REQ_PROG_KILL; _DBG_Writeln( "StartPacket" ); StartPacket(); _DBG_Writeln( "AddPacket" ); AddPacket( &killacc, sizeof( killacc ) ); _DBG_Writeln( "PutPacket" ); PutPacket(); _DBG_Writeln( "GetPacket" ); GetPacket(); //RemovePacket( &erracc, msg_len ); RemoteUnLink(); TaskLoaded = false; } } if( ret->err == 0 ) { _DBG_Writeln( "loadret->error_code == 0" ); TaskLoaded = true; } SaveVectors( LoadVectors ); SaveVectors( CurrVectors ); _DBG_ExitFunc( "AccLoadProg()" ); return( len ); }
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; }