2009-05-02 23:03:37 +02:00
/*
2009-05-02 23:43:00 +02:00
* Copyright ( C ) 2002 - 2003 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
* GNU Library General Public License for more details .
*
* 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-02 23:43:00 +02:00
/* $Id: dos_programs.cpp,v 1.20 2003/09/08 18:10:08 qbix79 Exp $ */
2009-05-02 23:03:37 +02:00
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include "programs.h"
# include "support.h"
# include "drives.h"
# include "cross.h"
2009-05-02 23:12:18 +02:00
# include "regs.h"
# include "callback.h"
2009-05-02 23:35:44 +02:00
# include "cdrom.h"
2009-05-02 23:27:47 +02:00
# include "../shell/shell_inc.h"
2009-05-02 23:03:37 +02:00
2009-05-02 23:35:44 +02:00
void MSCDEX_SetCDInterface ( int intNr , int forceCD ) ;
2009-05-02 23:03:37 +02:00
class MOUNT : public Program {
public :
2009-05-02 23:20:05 +02:00
void Run ( void )
{
DOS_Drive * newdrive ; char drive ;
2009-05-02 23:43:00 +02:00
std : : string label ;
2009-05-02 23:20:05 +02:00
2009-05-02 23:35:44 +02:00
// Show list of cdroms
if ( cmd - > FindExist ( " -cd " , false ) ) {
int num = SDL_CDNumDrives ( ) ;
WriteOut ( " CDROMs found: %d \n " , num ) ;
for ( int i = 0 ; i < num ; i + + ) {
WriteOut ( " %2d. %s \n " , i , SDL_CDName ( i ) ) ;
} ;
return ;
}
2009-05-02 23:12:18 +02:00
/* Parse the command line */
/* if the command line is empty show current mounts */
2009-05-02 23:20:05 +02:00
if ( ! cmd - > GetCount ( ) ) {
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_STATUS_1 " ) ) ;
2009-05-02 23:12:18 +02:00
for ( int d = 0 ; d < DOS_DRIVES ; d + + ) {
if ( Drives [ d ] ) {
2009-05-02 23:20:05 +02:00
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_STATUS_2 " ) , d + ' A ' , Drives [ d ] - > GetInfo ( ) ) ;
2009-05-02 23:12:18 +02:00
}
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:12:18 +02:00
return ;
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:35:44 +02:00
2009-05-02 23:20:05 +02:00
std : : string type = " dir " ;
cmd - > FindString ( " -t " , type , true ) ;
2009-05-02 23:35:44 +02:00
if ( type = = " floppy " | | type = = " dir " | | type = = " cdrom " ) {
2009-05-02 23:20:05 +02:00
Bit16u sizes [ 4 ] ;
Bit8u mediaid ;
std : : string str_size ;
if ( type = = " floppy " ) {
str_size = " 512,1,2847,2847 " ; /* All space free */
mediaid = 0xF0 ; /* Floppy 1.44 media */
2009-05-02 23:43:00 +02:00
} else if ( type = = " dir " ) {
2009-05-02 23:20:05 +02:00
str_size = " 512,127,16513,1700 " ;
mediaid = 0xF8 ; /* Hard Disk */
2009-05-02 23:43:00 +02:00
} else if ( type = = " cdrom " ) {
2009-05-02 23:35:44 +02:00
str_size = " 650,127,16513,1700 " ;
mediaid = 0xF8 ; /* Hard Disk */
2009-05-02 23:43:00 +02:00
} else {
WriteOut ( MSG_Get ( " PROGAM_MOUNT_ILL_TYPE " ) , type . c_str ( ) ) ;
return ;
2009-05-02 23:35:44 +02:00
}
2009-05-02 23:20:05 +02:00
cmd - > FindString ( " -size " , str_size , true ) ;
char number [ 20 ] ; const char * scan = str_size . c_str ( ) ;
Bitu index = 0 ; Bitu count = 0 ;
/* Parse the str_size string */
while ( * scan ) {
if ( * scan = = ' , ' ) {
number [ index ] = 0 ; sizes [ count + + ] = atoi ( number ) ;
index = 0 ;
} else number [ index + + ] = * scan ;
scan + + ;
}
number [ index ] = 0 ; sizes [ count + + ] = atoi ( number ) ;
2009-05-02 23:35:44 +02:00
// get the drive letter
cmd - > FindCommand ( 1 , temp_line ) ;
if ( ( temp_line . size ( ) > 2 ) | | ( ( temp_line . size ( ) > 1 ) & & ( temp_line [ 1 ] ! = ' : ' ) ) ) goto showusage ;
drive = toupper ( temp_line [ 0 ] ) ;
if ( ! isalpha ( drive ) ) goto showusage ;
2009-05-02 23:03:37 +02:00
2009-05-02 23:20:05 +02:00
if ( ! cmd - > FindCommand ( 2 , temp_line ) ) goto showusage ;
if ( ! temp_line . size ( ) ) goto showusage ;
struct stat test ;
if ( stat ( temp_line . c_str ( ) , & test ) ) {
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_ERROR_1 " ) , temp_line . c_str ( ) ) ;
return ;
}
/* Not a switch so a normal directory/file */
if ( ! ( test . st_mode & S_IFDIR ) ) {
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_ERROR_2 " ) , temp_line . c_str ( ) ) ;
return ;
}
if ( temp_line [ temp_line . size ( ) - 1 ] ! = CROSS_FILESPLIT ) temp_line + = CROSS_FILESPLIT ;
2009-05-02 23:27:47 +02:00
Bit8u bit8size = ( Bit8u ) sizes [ 1 ] ;
2009-05-02 23:35:44 +02:00
if ( type = = " cdrom " ) {
int num = - 1 ;
cmd - > FindInt ( " -usecd " , num , true ) ;
int error ;
if ( cmd - > FindExist ( " -aspi " , false ) ) MSCDEX_SetCDInterface ( CDROM_USE_ASPI , num ) ; else
if ( cmd - > FindExist ( " -ioctl " , false ) ) MSCDEX_SetCDInterface ( CDROM_USE_IOCTL , num ) ;
else MSCDEX_SetCDInterface ( CDROM_USE_SDL , num ) ;
newdrive = new cdromDrive ( drive , temp_line . c_str ( ) , sizes [ 0 ] , bit8size , sizes [ 2 ] , 0 , mediaid , error ) ;
// Check Mscdex, if it worked out...
switch ( error ) {
case 0 : WriteOut ( MSG_Get ( " MSCDEX_SUCCESS " ) ) ; break ;
case 1 : WriteOut ( MSG_Get ( " MSCDEX_ERROR_MULTIPLE_CDROMS " ) ) ; break ;
case 2 : WriteOut ( MSG_Get ( " MSCDEX_ERROR_NOT_SUPPORTED " ) ) ; break ;
case 3 : WriteOut ( MSG_Get ( " MSCDEX_ERROR_PATH " ) ) ; break ;
case 4 : WriteOut ( MSG_Get ( " MSCDEX_TOO_MANY_DRIVES " ) ) ; break ;
case 5 : WriteOut ( MSG_Get ( " MSCDEX_LIMITED_SUPPORT " ) ) ; break ;
default : WriteOut ( MSG_Get ( " MSCDEX_UNKNOWN_ERROR " ) ) ; break ;
} ;
} else {
newdrive = new localDrive ( temp_line . c_str ( ) , sizes [ 0 ] , bit8size , sizes [ 2 ] , sizes [ 3 ] , mediaid ) ;
}
2009-05-02 23:43:00 +02:00
} else {
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_ILL_TYPE " ) , type . c_str ( ) ) ;
return ;
2009-05-02 23:12:18 +02:00
}
if ( Drives [ drive - ' A ' ] ) {
2009-05-02 23:35:44 +02:00
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_ALLREADY_MOUNTED " ) , drive , Drives [ drive - ' A ' ] - > GetInfo ( ) ) ;
2009-05-02 23:20:05 +02:00
if ( newdrive ) delete newdrive ;
2009-05-02 23:12:18 +02:00
return ;
}
2009-05-02 23:20:05 +02:00
if ( ! newdrive ) E_Exit ( " DOS:Can't create drive " ) ;
Drives [ drive - ' A ' ] = newdrive ;
/* Set the correct media byte in the table */
mem_writeb ( Real2Phys ( dos . tables . mediaid ) + drive - ' A ' , newdrive - > GetMediaByte ( ) ) ;
WriteOut ( " Drive %c mounted as %s \n " , drive , newdrive - > GetInfo ( ) ) ;
2009-05-02 23:43:00 +02:00
/* check if volume label is given */
if ( cmd - > FindString ( " -label " , label , true ) ) newdrive - > dirCache . SetLabel ( label . c_str ( ) ) ;
2009-05-02 23:20:05 +02:00
return ;
showusage :
WriteOut ( MSG_Get ( " PROGRAM_MOUNT_USAGE " ) ) ;
return ;
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:12:18 +02:00
} ;
2009-05-02 23:03:37 +02:00
2009-05-02 23:20:05 +02:00
static void MOUNT_ProgramStart ( Program * * make ) {
* make = new MOUNT ;
2009-05-02 23:03:37 +02:00
}
class MEM : public Program {
public :
2009-05-02 23:12:18 +02:00
void Run ( void ) {
/* Show conventional Memory */
WriteOut ( " \n " ) ;
Bit16u seg , blocks ; blocks = 0xffff ;
DOS_AllocateMemory ( & seg , & blocks ) ;
2009-05-02 23:20:05 +02:00
WriteOut ( MSG_Get ( " PROGRAM_MEM_CONVEN " ) , blocks * 16 / 1024 ) ;
2009-05-02 23:12:18 +02:00
/* Test for and show free XMS */
reg_ax = 0x4300 ; CALLBACK_RunRealInt ( 0x2f ) ;
if ( reg_al = = 0x80 ) {
reg_ax = 0x4310 ; CALLBACK_RunRealInt ( 0x2f ) ;
Bit16u xms_seg = SegValue ( es ) ; Bit16u xms_off = reg_bx ;
reg_ah = 8 ;
CALLBACK_RunRealFar ( xms_seg , xms_off ) ;
if ( ! reg_bl ) {
2009-05-02 23:20:05 +02:00
WriteOut ( MSG_Get ( " PROGRAM_MEM_EXTEND " ) , reg_dx ) ;
2009-05-02 23:12:18 +02:00
}
}
/* Test for and show free EMS */
Bit16u handle ;
if ( DOS_OpenFile ( " EMMXXXX0 " , 0 , & handle ) ) {
DOS_CloseFile ( handle ) ;
reg_ah = 0x42 ;
CALLBACK_RunRealInt ( 0x67 ) ;
2009-05-02 23:20:05 +02:00
WriteOut ( MSG_Get ( " PROGRAM_MEM_EXPAND " ) , reg_bx * 16 ) ;
2009-05-02 23:12:18 +02:00
}
}
2009-05-02 23:03:37 +02:00
} ;
2009-05-02 23:20:05 +02:00
static void MEM_ProgramStart ( Program * * make ) {
* make = new MEM ;
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:27:47 +02:00
// LOADFIX
class LOADFIX : public Program {
public :
void Run ( void ) ;
} ;
void LOADFIX : : Run ( void )
{
Bit16u commandNr = 1 ;
Bit16u kb = 64 ;
if ( cmd - > FindCommand ( commandNr , temp_line ) ) {
if ( temp_line [ 0 ] = = ' - ' ) {
char ch = temp_line [ 1 ] ;
if ( ( * upcase ( & ch ) = = ' D ' ) | | ( * upcase ( & ch ) = = ' F ' ) ) {
// Deallocate all
DOS_FreeProcessMemory ( 0x40 ) ;
WriteOut ( MSG_Get ( " PROGRAM_LOADFIX_DEALLOCALL " ) , kb ) ;
return ;
} else {
// Set mem amount to allocate
kb = atoi ( temp_line . c_str ( ) + 1 ) ;
if ( kb = = 0 ) kb = 64 ;
commandNr + + ;
}
}
}
// Allocate Memory
Bit16u segment ;
Bit16u blocks = kb * 1024 / 16 ;
if ( DOS_AllocateMemory ( & segment , & blocks ) ) {
2009-05-02 23:35:44 +02:00
DOS_MCB mcb ( ( Bit16u ) ( segment - 1 ) ) ;
mcb . SetPSPSeg ( 0x40 ) ; // use fake segment
2009-05-02 23:27:47 +02:00
WriteOut ( MSG_Get ( " PROGRAM_LOADFIX_ALLOC " ) , kb ) ;
// Prepare commandline...
if ( cmd - > FindCommand ( commandNr + + , temp_line ) ) {
// get Filename
char filename [ 128 ] ;
strncpy ( filename , temp_line . c_str ( ) , 128 ) ;
// Setup commandline
bool ok ;
char args [ 256 ] ;
args [ 0 ] = 0 ;
do {
ok = cmd - > FindCommand ( commandNr + + , temp_line ) ;
strncat ( args , temp_line . c_str ( ) , 256 ) ;
strncat ( args , " " , 256 ) ;
} while ( ok ) ;
// Use shell to start program
DOS_Shell shell ;
shell . Execute ( filename , args ) ;
DOS_FreeMemory ( segment ) ;
WriteOut ( MSG_Get ( " PROGRAM_LOADFIX_DEALLOC " ) , kb ) ;
}
} else {
WriteOut ( MSG_Get ( " PROGRAM_LOADFIX_ERROR " ) , kb ) ;
}
} ;
static void LOADFIX_ProgramStart ( Program * * make ) {
* make = new LOADFIX ;
}
2009-05-02 23:35:44 +02:00
// RESCAN
class RESCAN : public Program {
public :
void Run ( void ) ;
} ;
void RESCAN : : Run ( void )
{
// Get current drive
Bit8u drive = DOS_GetDefaultDrive ( ) ;
if ( Drives [ drive ] ) {
Drives [ drive ] - > EmptyCache ( ) ;
WriteOut ( MSG_Get ( " PROGRAM_RESCAN_SUCCESS " ) ) ;
}
} ;
static void RESCAN_ProgramStart ( Program * * make ) {
* make = new RESCAN ;
}
class INTRO : public Program {
public :
void Run ( void ) {
WriteOut ( MSG_Get ( " PROGRAM_INTRO " ) ) ;
}
} ;
static void INTRO_ProgramStart ( Program * * make ) {
* make = new INTRO ;
}
2009-05-02 23:03:37 +02:00
void DOS_SetupPrograms ( void ) {
2009-05-02 23:20:05 +02:00
/*Add Messages */
MSG_Add ( " PROGRAM_MOUNT_STATUS_2 " , " Drive %c is mounted as %s \n " ) ;
MSG_Add ( " PROGRAM_MOUNT_STATUS_1 " , " Current mounted drives are: \n " ) ;
MSG_Add ( " PROGRAM_MOUNT_ERROR_1 " , " Directory %s doesn't exist. \n " ) ;
MSG_Add ( " PROGRAM_MOUNT_ERROR_2 " , " %s isn't a directory \n " ) ;
2009-05-02 23:43:00 +02:00
MSG_Add ( " PROGRAM_MOUNT_ILL_TYPE " , " Illegal type %s \n " ) ;
2009-05-02 23:20:05 +02:00
MSG_Add ( " PROGRAM_MOUNT_ALLREADY_MOUNTED " , " Drive %c already mounted with %s \n " ) ;
MSG_Add ( " PROGRAM_MOUNT_USAGE " , " Usage MOUNT Drive-Letter Local-Directory \n So a MOUNT c c: \\ windows mounts windows directory as the c: drive in DOSBox \n " ) ;
MSG_Add ( " PROGRAM_MEM_CONVEN " , " %10d Kb free conventional memory \n " ) ;
MSG_Add ( " PROGRAM_MEM_EXTEND " , " %10d Kb free extended memory \n " ) ;
MSG_Add ( " PROGRAM_MEM_EXPAND " , " %10d Kb free expanded memory \n " ) ;
2009-05-02 23:27:47 +02:00
MSG_Add ( " PROGRAM_LOADFIX_ALLOC " , " %d kb allocated. \n " ) ;
MSG_Add ( " PROGRAM_LOADFIX_DEALLOC " , " %d kb freed. \n " ) ;
MSG_Add ( " PROGRAM_LOADFIX_DEALLOCALL " , " Used memory freed. \n " ) ;
MSG_Add ( " PROGRAM_LOADFIX_ERROR " , " Memory allocation error. \n " ) ;
2009-05-02 23:35:44 +02:00
MSG_Add ( " MSCDEX_SUCCESS " , " MSCDEX installed. \n " ) ;
MSG_Add ( " MSCDEX_ERROR_MULTIPLE_CDROMS " , " MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous. \n " ) ;
MSG_Add ( " MSCDEX_ERROR_NOT_SUPPORTED " , " MSCDEX: Failure: Not yet supported. \n " ) ;
MSG_Add ( " MSCDEX_ERROR_PATH " , " MSCDEX: Failure: Path not valid. \n " ) ;
MSG_Add ( " MSCDEX_TOO_MANY_DRIVES " , " MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed. \n " ) ;
MSG_Add ( " MSCDEX_LIMITED_SUPPORT " , " MSCDEX: Mounted subdirectory: limited support. \n " ) ;
MSG_Add ( " MSCDEX_UNKNOWN_ERROR " , " MSCDEX: Failure: Unknown error. \n " ) ;
MSG_Add ( " PROGRAM_RESCAN_SUCCESS " , " Drive cache cleared. \n " ) ;
MSG_Add ( " PROGRAM_INTRO " ,
2009-05-02 23:43:00 +02:00
" [2J [32;1mWelcome to DOSBox [0m, an x86 emulator with sound and graphics.\n "
2009-05-02 23:35:44 +02:00
" DOSBox creates a shell for you which looks like old plain DOS. \n "
" \n "
" Here are some commands to get you started: \n "
" Before you can use the files located on your own filesystem, \n "
" You have to mount the directory containing the files. \n "
" For Windows: \n "
2009-05-02 23:43:00 +02:00
" \033 [33mmount c c: \\ dosprog \033 [0m will create a C drive in dosbox with c: \\ dosprog as contents. \n "
2009-05-02 23:35:44 +02:00
" \n "
2009-05-02 23:43:00 +02:00
" For other platforms: \n "
" \033 [33mmount c /home/user/dosprog \033 [0m will do the same. \n "
2009-05-02 23:35:44 +02:00
" \n "
2009-05-02 23:43:00 +02:00
" When the mount has succesfully completed you can type \033 [33mc: \033 [0m to go to your freshly \n "
" mounted C-drive. Typing \033 [33mdir \033 [0m there will show its contents. "
" \033 [33mcd \033 [0m will allow you to \n "
2009-05-02 23:35:44 +02:00
" enter a directory (recognised by the [] in a directory listing). \n "
2009-05-02 23:43:00 +02:00
" You can run programs/files which end with [31m.exe .bat [0m and [31m.com [0m. \n "
2009-05-02 23:35:44 +02:00
" \n "
2009-05-02 23:43:00 +02:00
" [43;30mDOSBox will stop/exit without a warning if an error occured! [0m\n "
2009-05-02 23:35:44 +02:00
) ;
2009-05-02 23:20:05 +02:00
/*regular setup*/
2009-05-02 23:03:37 +02:00
PROGRAMS_MakeFile ( " MOUNT.COM " , MOUNT_ProgramStart ) ;
2009-05-02 23:12:18 +02:00
PROGRAMS_MakeFile ( " MEM.COM " , MEM_ProgramStart ) ;
2009-05-02 23:27:47 +02:00
PROGRAMS_MakeFile ( " LOADFIX.COM " , LOADFIX_ProgramStart ) ;
2009-05-02 23:35:44 +02:00
PROGRAMS_MakeFile ( " RESCAN.COM " , RESCAN_ProgramStart ) ;
PROGRAMS_MakeFile ( " INTRO.COM " , INTRO_ProgramStart ) ;
2009-05-02 23:03:37 +02:00
}