2009-05-02 23:03:37 +02:00
/*
2009-05-02 23:53:27 +02:00
* Copyright ( C ) 2002 - 2004 The DOSBox Team
2009-05-02 23:03:37 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2009-05-03 00:02:15 +02:00
* GNU General Public License for more details .
2009-05-02 23:03:37 +02:00
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
2009-05-03 00:02:15 +02:00
/* $Id: shell.cpp,v 1.49 2004/09/28 15:31:21 qbix79 Exp $ */
2009-05-02 23:03:37 +02:00
# include <stdlib.h>
# include <stdarg.h>
2009-05-02 23:43:00 +02:00
# include <string.h>
2009-05-02 23:20:05 +02:00
# include "setup.h"
2009-05-02 23:53:27 +02:00
# include "shell.h"
2009-05-02 23:03:37 +02:00
Bitu call_shellstop ;
static Bitu shellstop_handler ( void ) {
return CBRET_STOP ;
}
2009-05-02 23:20:05 +02:00
static void SHELL_ProgramStart ( Program * * make ) {
* make = new DOS_Shell ;
2009-05-02 23:03:37 +02:00
}
# define AUTOEXEC_SIZE 4096
static char autoexec_data [ AUTOEXEC_SIZE ] = { 0 } ;
void SHELL_AddAutoexec ( char * line , . . . ) {
char buf [ 2048 ] ;
va_list msg ;
va_start ( msg , line ) ;
vsprintf ( buf , line , msg ) ;
va_end ( msg ) ;
size_t auto_len = strlen ( autoexec_data ) ;
if ( ( auto_len + strlen ( line ) + 3 ) > AUTOEXEC_SIZE ) {
2009-05-03 00:02:15 +02:00
E_Exit ( " SYSTEM:Autoexec.bat file overflow " ) ;
2009-05-02 23:03:37 +02:00
}
sprintf ( ( autoexec_data + auto_len ) , " %s \r \n " , buf ) ;
}
2009-05-02 23:20:05 +02:00
DOS_Shell : : DOS_Shell ( ) : Program ( ) {
2009-05-02 23:03:37 +02:00
input_handle = STDIN ;
echo = true ;
exit = false ;
bf = 0 ;
2009-05-02 23:43:00 +02:00
call = false ;
completion_start = NULL ;
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:43:00 +02:00
Bitu DOS_Shell : : GetRedirection ( char * s , char * * ifn , char * * ofn , bool * append ) {
char * lr = s ;
char * lw = s ;
char ch ;
Bitu num = 0 ;
2009-05-02 23:53:27 +02:00
while ( ( ch = * lr + + ) ) {
2009-05-02 23:43:00 +02:00
switch ( ch ) {
case ' > ' :
* append = ( ( * lr ) = = ' > ' ) ;
if ( * append ) lr + + ;
lr = ltrim ( lr ) ;
if ( * ofn ) free ( * ofn ) ;
* ofn = lr ;
while ( * lr & & * lr ! = ' ' ) lr + + ;
if ( * lr & & * ( lr + 1 ) )
* lr + + = 0 ;
else
* lr = 0 ;
* ofn = strdup ( * ofn ) ;
continue ;
case ' < ' :
if ( * ifn ) free ( * ifn ) ;
lr = ltrim ( lr ) ;
* ifn = lr ;
while ( * lr & & * lr ! = ' ' ) lr + + ;
if ( * lr & & * ( lr + 1 ) )
* lr + + = 0 ;
else
* lr = 0 ;
* ifn = strdup ( * ifn ) ;
continue ;
case ' | ' :
ch = 0 ;
num + + ;
}
* lw + + = ch ;
}
* lw = 0 ;
return num ;
2009-05-02 23:35:44 +02:00
}
2009-05-02 23:03:37 +02:00
void DOS_Shell : : ParseLine ( char * line ) {
2009-05-03 00:02:15 +02:00
LOG ( LOG_EXEC , LOG_ERROR ) ( " Parsing command line: %s " , line ) ;
2009-05-02 23:03:37 +02:00
/* Check for a leading @ */
2009-05-02 23:27:47 +02:00
if ( line [ 0 ] = = ' @ ' ) line [ 0 ] = ' ' ;
2009-05-02 23:03:37 +02:00
line = trim ( line ) ;
2009-05-02 23:43:00 +02:00
# if 1
/* Do redirection and pipe checks */
char * in = 0 ;
char * out = 0 ;
Bit16u old_in , old_out ;
Bitu num = 0 ; /* Number of commands in this line */
bool append ;
num = GetRedirection ( line , & in , & out , & append ) ;
if ( num > 1 ) LOG_MSG ( " SHELL:Multiple command on 1 line not supported " ) ;
// if (in || num>1) DOS_DuplicateEntry(0,&old_in);
if ( in ) {
LOG_MSG ( " SHELL:Redirect input from %s " , in ) ;
DOS_CloseFile ( 0 ) ;
free ( in ) ;
}
if ( out ) {
LOG_MSG ( " SHELL:Redirect output to %s " , out ) ;
free ( out ) ;
}
# endif
2009-05-02 23:03:37 +02:00
DoCommand ( line ) ;
}
2009-05-02 23:43:00 +02:00
void DOS_Shell : : RunInternal ( void )
{
char input_line [ CMD_MAXLINE ] ;
std : : string line ;
while ( bf & & bf - > ReadLine ( input_line ) )
{
if ( echo ) {
if ( input_line [ 0 ] ! = ' @ ' ) {
ShowPrompt ( ) ;
WriteOut ( input_line ) ;
WriteOut ( " \n " ) ;
} ;
} ;
ParseLine ( input_line ) ;
}
return ;
}
2009-05-02 23:03:37 +02:00
void DOS_Shell : : Run ( void ) {
2009-05-02 23:20:05 +02:00
char input_line [ CMD_MAXLINE ] ;
std : : string line ;
2009-05-02 23:27:47 +02:00
if ( cmd - > FindStringRemain ( " /C " , line ) ) {
2009-05-02 23:20:05 +02:00
strcpy ( input_line , line . c_str ( ) ) ;
2009-05-02 23:43:00 +02:00
DOS_Shell temp ;
temp . echo = echo ;
temp . ParseLine ( input_line ) ; //for *.exe *.com |*.bat creates the bf needed by runinternal;
temp . RunInternal ( ) ; // exits when no bf is found.
2009-05-02 23:03:37 +02:00
return ;
}
/* Start a normal shell and check for a first command init */
WriteOut ( MSG_Get ( " SHELL_STARTUP " ) ) ;
2009-05-02 23:20:05 +02:00
if ( cmd - > FindString ( " /INIT " , line , true ) ) {
strcpy ( input_line , line . c_str ( ) ) ;
line . erase ( ) ;
ParseLine ( input_line ) ;
2009-05-02 23:03:37 +02:00
}
do {
2009-05-02 23:43:00 +02:00
if ( bf ) {
if ( bf - > ReadLine ( input_line ) ) {
if ( echo ) {
if ( input_line [ 0 ] ! = ' @ ' ) {
2009-05-03 00:02:15 +02:00
ShowPrompt ( ) ;
2009-05-02 23:43:00 +02:00
WriteOut ( input_line ) ;
WriteOut ( " \n " ) ;
} ;
2009-05-02 23:03:37 +02:00
} ;
2009-05-02 23:43:00 +02:00
ParseLine ( input_line ) ;
if ( echo ) WriteOut ( " \n " ) ;
}
2009-05-02 23:03:37 +02:00
} else {
if ( echo ) ShowPrompt ( ) ;
InputCommand ( input_line ) ;
2009-05-02 23:43:00 +02:00
ParseLine ( input_line ) ;
if ( echo ) WriteOut ( " \n " ) ;
2009-05-02 23:03:37 +02:00
}
} while ( ! exit ) ;
}
void DOS_Shell : : SyntaxError ( void ) {
WriteOut ( MSG_Get ( " SHELL_SYNTAXERROR " ) ) ;
}
2009-05-02 23:20:05 +02:00
void AUTOEXEC_Init ( Section * sec ) {
/* Register a virtual AUOEXEC.BAT file */
2009-05-02 23:43:00 +02:00
std : : string line ;
2009-05-02 23:20:05 +02:00
Section_line * section = static_cast < Section_line * > ( sec ) ;
char * extra = ( char * ) section - > data . c_str ( ) ;
2009-05-02 23:43:00 +02:00
if ( extra ) SHELL_AddAutoexec ( " %s " , extra ) ;
/* Check to see for extra command line options to be added (before the command specified on commandline) */
while ( control - > cmdline - > FindString ( " -c " , line , true ) )
SHELL_AddAutoexec ( ( char * ) line . c_str ( ) ) ;
/* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */
bool addexit = control - > cmdline - > FindExist ( " -exit " , true ) ;
2009-05-02 23:20:05 +02:00
/* Check for first command being a directory or file */
char buffer [ CROSS_LEN ] ;
if ( control - > cmdline - > FindCommand ( 1 , line ) ) {
struct stat test ;
strcpy ( buffer , line . c_str ( ) ) ;
2009-05-02 23:43:00 +02:00
if ( stat ( buffer , & test ) ) {
2009-05-02 23:20:05 +02:00
getcwd ( buffer , CROSS_LEN ) ;
strcat ( buffer , line . c_str ( ) ) ;
if ( stat ( buffer , & test ) ) goto nomount ;
}
if ( test . st_mode & S_IFDIR ) {
2009-05-02 23:35:44 +02:00
SHELL_AddAutoexec ( " MOUNT C \" %s \" " , buffer ) ;
2009-05-02 23:20:05 +02:00
SHELL_AddAutoexec ( " C: " ) ;
} else {
char * name = strrchr ( buffer , CROSS_FILESPLIT ) ;
if ( ! name ) goto nomount ;
* name + + = 0 ;
if ( access ( buffer , F_OK ) ) goto nomount ;
2009-05-02 23:35:44 +02:00
SHELL_AddAutoexec ( " MOUNT C \" %s \" " , buffer ) ;
2009-05-02 23:20:05 +02:00
SHELL_AddAutoexec ( " C: " ) ;
2009-05-03 00:02:15 +02:00
upcase ( name ) ;
if ( strstr ( name , " .BAT " ) = = 0 ) {
SHELL_AddAutoexec ( name ) ;
} else {
char call [ CROSS_LEN ] = { 0 } ;
strcpy ( call , " CALL " ) ;
strcat ( call , name ) ;
SHELL_AddAutoexec ( call ) ;
}
2009-05-02 23:43:00 +02:00
if ( addexit ) SHELL_AddAutoexec ( " exit " ) ;
2009-05-02 23:20:05 +02:00
}
}
nomount :
VFILE_Register ( " AUTOEXEC.BAT " , ( Bit8u * ) autoexec_data , strlen ( autoexec_data ) ) ;
}
static char * path_string = " PATH=Z: \\ " ;
static char * comspec_string = " COMSPEC=Z: \\ COMMAND.COM " ;
static char * full_name = " Z: \\ COMMAND.COM " ;
static char * init_line = " /INIT AUTOEXEC.BAT " ;
2009-05-02 23:03:37 +02:00
void SHELL_Init ( ) {
2009-05-02 23:20:05 +02:00
/* Add messages */
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_ILLEGAL_PATH " , " Illegal Path. \n " ) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " SHELL_CMD_HELP " , " supported commands are: \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_ECHO_ON " , " ECHO is on. \n " ) ;
MSG_Add ( " SHELL_CMD_ECHO_OFF " , " ECHO is off. \n " ) ;
MSG_Add ( " SHELL_ILLEGAL_SWITCH " , " Illegal switch: %s. \n " ) ;
MSG_Add ( " SHELL_CMD_CHDIR_ERROR " , " Unable to change to: %s. \n " ) ;
MSG_Add ( " SHELL_CMD_MKDIR_ERROR " , " Unable to make: %s. \n " ) ;
MSG_Add ( " SHELL_CMD_RMDIR_ERROR " , " Unable to remove: %s. \n " ) ;
MSG_Add ( " SHELL_CMD_DEL_ERROR " , " Unable to delete: %s. \n " ) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " SHELL_SYNTAXERROR " , " The syntax of the command is incorrect. \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_SET_NOT_SET " , " Environment variable %s not defined. \n " ) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " SHELL_CMD_SET_OUT_OF_SPACE " , " Not enough environment space left. \n " ) ;
MSG_Add ( " SHELL_CMD_IF_EXIST_MISSING_FILENAME " , " IF EXIST: Missing filename. \n " ) ;
MSG_Add ( " SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER " , " IF ERRORLEVEL: Missing number. \n " ) ;
MSG_Add ( " SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER " , " IF ERRORLEVEL: Invalid number. \n " ) ;
MSG_Add ( " SHELL_CMD_GOTO_MISSING_LABEL " , " No label supplied to GOTO command. \n " ) ;
MSG_Add ( " SHELL_CMD_GOTO_LABEL_NOT_FOUND " , " GOTO: Label %s not found. \n " ) ;
MSG_Add ( " SHELL_CMD_FILE_NOT_FOUND " , " File %s not found. \n " ) ;
MSG_Add ( " SHELL_CMD_FILE_EXISTS " , " File %s already exists. \n " ) ;
MSG_Add ( " SHELL_CMD_DIR_INTRO " , " Directory of %s. \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_DIR_BYTES_USED " , " %5d File(s) %17s Bytes. \n " ) ;
MSG_Add ( " SHELL_CMD_DIR_BYTES_FREE " , " %5d Dir(s) %17s Bytes free. \n " ) ;
MSG_Add ( " SHELL_EXECUTE_DRIVE_NOT_FOUND " , " Drive %c does not exist! \n You must \033 [31mmount \033 [0m it first. Type \033 [1;33mintro \033 [0m for more information. \n " ) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " SHELL_EXECUTE_ILLEGAL_COMMAND " , " Illegal command: %s. \n " ) ;
2009-05-02 23:53:27 +02:00
MSG_Add ( " SHELL_CMD_PAUSE " , " Press any key to continue. \n " ) ;
2009-05-02 23:35:44 +02:00
MSG_Add ( " SHELL_CMD_PAUSE_HELP " , " Waits for 1 keystroke to continue. \n " ) ;
MSG_Add ( " SHELL_CMD_COPY_FAILURE " , " Copy failure : %s. \n " ) ;
MSG_Add ( " SHELL_CMD_COPY_SUCCESS " , " %d File(s) copied. \n " ) ;
2009-05-02 23:53:27 +02:00
MSG_Add ( " SHELL_CMD_SUBST_NO_REMOVE " , " Removing drive not supported. Doing nothing. \n " ) ;
MSG_Add ( " SHELL_CMD_SUBST_FAILURE " , " SUBST failed. You either made an error in your commandline or the target drive is already used. \n It's only possible to use SUBST on Local drives " ) ;
2009-05-02 23:27:47 +02:00
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_STARTUP " ,
" \033 [44;1m \xC9 \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD "
" \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD "
" \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xBB \n "
" \xBA \033 [32mDOSBox Shell v " VERSION " \033 [37m \xBA \n "
" \xBA DOSBox runs real and protected mode games. \xBA \n "
" \xBA For supported shell commands type: \033 [1;33mHELP \033 [37m \xBA \n "
" \xBA For a short introduction type: \033 [33mINTRO \033 [37m \xBA \n "
" \xBA \xBA \n "
" \xBA If you want more speed, try \033 [31mctrl-F8 \033 [37m and \033 [31mctrl-F12 \033 [37m. \xBA \n "
" \xBA To activate the keymapper \033 [31mctrl-F1 \033 [37m. \xBA \n "
" \xBA For more information read the \033 [36mREADME \033 [37m file in the DOSBox directory. \xBA \n "
" \xBA \xBA \n "
" \xBA \033 [32mHAVE FUN! \033 [37m \xBA \n "
" \xBA \033 [32mThe DOSBox Team \033 [37m \xBA \n "
" \xC8 \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD "
" \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD "
" \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xCD \xBC \033 [0m \n "
//"\n" //Breaks the startup message if you type a mount and a drive change.
2009-05-02 23:27:47 +02:00
) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " SHELL_CMD_CHDIR_HELP " , " Change Directory. \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_CLS_HELP " , " Clear screen. \n " ) ;
MSG_Add ( " SHELL_CMD_DIR_HELP " , " Directory View. \n " ) ;
MSG_Add ( " SHELL_CMD_ECHO_HELP " , " Display messages and enable/disable command echoing. \n " ) ;
MSG_Add ( " SHELL_CMD_EXIT_HELP " , " Exit from the shell. \n " ) ;
MSG_Add ( " SHELL_CMD_HELP_HELP " , " Show help. \n " ) ;
MSG_Add ( " SHELL_CMD_MKDIR_HELP " , " Make Directory. \n " ) ;
MSG_Add ( " SHELL_CMD_RMDIR_HELP " , " Remove Directory. \n " ) ;
MSG_Add ( " SHELL_CMD_SET_HELP " , " Change environment variables. \n " ) ;
MSG_Add ( " SHELL_CMD_IF_HELP " , " Performs conditional processing in batch programs. \n " ) ;
MSG_Add ( " SHELL_CMD_GOTO_HELP " , " Jump to a labeled line in a batch script. \n " ) ;
MSG_Add ( " SHELL_CMD_TYPE_HELP " , " Display the contents of a text-file. \n " ) ;
MSG_Add ( " SHELL_CMD_REM_HELP " , " Add comments in a batch file. \n " ) ;
2009-05-02 23:27:47 +02:00
MSG_Add ( " SHELL_CMD_NO_WILD " , " This is a simple version of the command, no wildcards allowed! \n " ) ;
MSG_Add ( " SHELL_CMD_RENAME_HELP " , " Renames files. \n " ) ;
2009-05-02 23:53:27 +02:00
MSG_Add ( " SHELL_CMD_DELETE_HELP " , " Removes files. \n " ) ;
2009-05-02 23:35:44 +02:00
MSG_Add ( " SHELL_CMD_COPY_HELP " , " Copy files. \n " ) ;
2009-05-02 23:43:00 +02:00
MSG_Add ( " SHELL_CMD_CALL_HELP " , " Start a batch file from within another batch file. \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_SUBST_HELP " , " Assign an internal directory to a drive. \n " ) ;
2009-05-02 23:53:27 +02:00
MSG_Add ( " SHELL_CMD_LOADHIGH_HELP " , " Run a program. For batch file compatibility only. \n " ) ;
2009-05-03 00:02:15 +02:00
MSG_Add ( " SHELL_CMD_CHOICE_HELP " , " Waits for a keypress and sets ERRORLEVEL. \n " ) ;
MSG_Add ( " SHELL_CMD_ATTRIB_HELP " , " Does nothing. Provided for compatibility. \n " ) ;
2009-05-02 23:53:27 +02:00
2009-05-03 00:02:15 +02:00
/* Regular startup */
2009-05-02 23:03:37 +02:00
call_shellstop = CALLBACK_Allocate ( ) ;
2009-05-02 23:27:47 +02:00
/* Setup the startup CS:IP to kill the last running machine when exitted */
RealPt newcsip = CALLBACK_RealPointer ( call_shellstop ) ;
SegSet16 ( cs , RealSeg ( newcsip ) ) ;
reg_ip = RealOff ( newcsip ) ;
2009-05-02 23:20:05 +02:00
2009-05-02 23:03:37 +02:00
CALLBACK_Setup ( call_shellstop , shellstop_handler , CB_IRET ) ;
PROGRAMS_MakeFile ( " COMMAND.COM " , SHELL_ProgramStart ) ;
2009-05-02 23:20:05 +02:00
2009-05-02 23:03:37 +02:00
/* Now call up the shell for the first time */
2009-05-02 23:20:05 +02:00
Bit16u psp_seg = DOS_GetMemory ( 16 + 1 ) + 1 ;
Bit16u env_seg = DOS_GetMemory ( 1 + ( 4096 / 16 ) ) + 1 ;
2009-05-02 23:12:18 +02:00
Bit16u stack_seg = DOS_GetMemory ( 2048 / 16 ) ;
SegSet16 ( ss , stack_seg ) ;
reg_sp = 2046 ;
2009-05-02 23:20:05 +02:00
/* Setup MCB and the environment */
2009-05-02 23:35:44 +02:00
DOS_MCB envmcb ( ( Bit16u ) ( env_seg - 1 ) ) ;
envmcb . SetPSPSeg ( psp_seg ) ;
envmcb . SetSize ( 4096 / 16 ) ;
2009-05-02 23:20:05 +02:00
PhysPt env_write = PhysMake ( env_seg , 0 ) ;
MEM_BlockWrite ( env_write , path_string , strlen ( path_string ) + 1 ) ;
env_write + = strlen ( path_string ) + 1 ;
MEM_BlockWrite ( env_write , comspec_string , strlen ( comspec_string ) + 1 ) ;
env_write + = strlen ( comspec_string ) + 1 ;
mem_writeb ( env_write + + , 0 ) ;
mem_writew ( env_write , 1 ) ;
env_write + = 2 ;
MEM_BlockWrite ( env_write , full_name , strlen ( full_name ) + 1 ) ;
DOS_PSP psp ( psp_seg ) ;
psp . MakeNew ( 0 ) ;
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 */
psp . SetEnvironment ( env_seg ) ;
/* Set the command line for the shell start up */
CommandTail tail ;
tail . count = strlen ( init_line ) ;
strcpy ( tail . buffer , init_line ) ;
MEM_BlockWrite ( PhysMake ( psp_seg , 128 ) , & tail , 128 ) ;
2009-05-02 23:03:37 +02:00
/* Setup internal DOS Variables */
2009-05-03 00:02:15 +02:00
dos . dta ( RealMake ( psp_seg , 0x80 ) ) ;
dos . psp ( psp_seg ) ;
2009-05-02 23:20:05 +02:00
Program * new_program ;
SHELL_ProgramStart ( & new_program ) ;
new_program - > Run ( ) ;
delete new_program ;
2009-05-02 23:03:37 +02:00
}