void INT10_SetupVESA(void) { /* Put the mode list somewhere in memory */ Bitu i; i=0; int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used); //TODO Maybe add normal vga modes too, but only seems to complicate things while (ModeList_VGA[i].mode!=0xffff) { bool canuse_mode=false; if (!svga.accepts_mode) canuse_mode=true; else { if (svga.accepts_mode(ModeList_VGA[i].mode)) canuse_mode=true; } if (ModeList_VGA[i].mode>=0x100 && canuse_mode) { if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) { phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); int10.rom.used+=2; } } i++; } phys_writew(PhysMake(0xc000,int10.rom.used),0xffff); int10.rom.used+=2; int10.rom.oemstring=RealMake(0xc000,int10.rom.used); Bitu len=(Bitu)(strlen(string_oem)+1); for (i=0;i<len;i++) { phys_writeb(0xc0000+int10.rom.used++,string_oem[i]); } switch (svgaCard) { case SVGA_S3Trio: break; } callback.setwindow=CALLBACK_Allocate(); callback.pmPalette=CALLBACK_Allocate(); callback.pmStart=CALLBACK_Allocate(); CALLBACK_Setup(callback.setwindow,VESA_SetWindow,CB_RETF, "VESA Real Set Window"); /* Prepare the pmode interface */ int10.rom.pmode_interface=RealMake(0xc000,int10.rom.used); int10.rom.used += 8; //Skip the byte later used for offsets /* PM Set Window call */ int10.rom.pmode_interface_window = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 0, int10.rom.pmode_interface_window ); callback.pmWindow=CALLBACK_Allocate(); int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window"); /* PM Set start call */ int10.rom.pmode_interface_start = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 2, int10.rom.pmode_interface_start); callback.pmStart=CALLBACK_Allocate(); int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); /* PM Set Palette call */ int10.rom.pmode_interface_palette = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 4, int10.rom.pmode_interface_palette); callback.pmPalette=CALLBACK_Allocate(); int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette"); /* Finalize the size and clear the required ports pointer */ phys_writew( Real2Phys(int10.rom.pmode_interface) + 6, 0); int10.rom.pmode_interface_size=int10.rom.used - RealOff( int10.rom.pmode_interface ); }
void DOS_SetupMisc(void) { /* Setup the dos multiplex interrupt */ call_int2f=CALLBACK_Allocate(); CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET,"DOS Int 2f"); RealSetVec(0x2f,CALLBACK_RealPointer(call_int2f)); DOS_AddMultiplexHandler(DOS_MultiplexFunctions); /* Setup the dos network interrupt */ call_int2a=CALLBACK_Allocate(); CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET,"DOS Int 2a"); RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); }
void BIOS_SetupDisks(void) { call_int13 = CALLBACK_Allocate(); CALLBACK_Setup(call_int13, &INT13_DiskHandler, CB_IRET_STI, "Int 13 Bios disk"); RealSetVec(0x13, CALLBACK_RealPointer(call_int13)); vPC_rStosb(BIOS_HARDDISK_COUNT, 2); // Setup the Bios Area }
void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description){ if(!installed) { installed=true; m_type=SETUP; m_callback=CALLBACK_Allocate(); CALLBACK_Setup(m_callback,handler,type,addr,description); } else E_Exit("Callback handler object already installed"); }
void MOUSE_Init(Section* sec) { // Callback 0x33 CreateMouseCallback(); call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET,"int 74"); if(MOUSE_IRQ > 7) { real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); mouse.shown=-1; //Hide mouse on startup mouse_reset_hardware(); mouse_reset(); }
void PROGRAMS_Init(Section* /*sec*/) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program"); PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart); // listconf MSG_Add("PROGRAM_CONFIG_NOCONFIGFILE","No config file loaded!\n"); MSG_Add("PROGRAM_CONFIG_PRIMARY_CONF","Primary config file: \n%s\n"); MSG_Add("PROGRAM_CONFIG_ADDITIONAL_CONF","Additional config files:\n"); MSG_Add("PROGRAM_CONFIG_CONFDIR","DOSBox %s configuration directory: \n%s\n\n"); // writeconf MSG_Add("PROGRAM_CONFIG_FILE_ERROR","\nCan't open file %s\n"); MSG_Add("PROGRAM_CONFIG_FILE_WHICH","Writing config file %s"); // help MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\n"\ "-writeconf or -wc without parameter: write to primary loaded config file.\n"\ "-writeconf or -wc with filename: write file to config directory.\n"\ "Use -writelang or -wl filename to write the current language strings.\n"\ "-r [parameters]\n Restart DOSBox, either using the previous parameters or any that are appended.\n"\ "-wcp [filename]\n Write config file to the program directory, dosbox.conf or the specified \n filename.\n"\ "-wcd\n Write to the default config file in the config directory.\n"\ "-l lists configuration parameters.\n"\ "-h, -help, -? sections / sectionname / propertyname\n"\ " Without parameters, displays this help screen. Add \"sections\" for a list of\n sections."\ " For info about a specific section or property add its name behind.\n"\ "-axclear clears the autoexec section.\n"\ "-axadd [line] adds a line to the autoexec section.\n"\ "-axtype prints the content of the autoexec section.\n"\ "-securemode switches to secure mode.\n"\ "-get \"section property\" returns the value of the property.\n"\ "-set \"section property=value\" sets the value." ); MSG_Add("PROGRAM_CONFIG_HLP_PROPHLP","Purpose of property \"%s\" (contained in section \"%s\"):\n%s\n\nPossible Values: %s\nDefault value: %s\nCurrent value: %s\n"); MSG_Add("PROGRAM_CONFIG_HLP_LINEHLP","Purpose of section \"%s\":\n%s\nCurrent value:\n%s\n"); MSG_Add("PROGRAM_CONFIG_HLP_NOCHANGE","This property cannot be changed at runtime.\n"); MSG_Add("PROGRAM_CONFIG_HLP_POSINT","positive integer"); MSG_Add("PROGRAM_CONFIG_HLP_SECTHLP","Section %s contains the following properties:\n"); MSG_Add("PROGRAM_CONFIG_HLP_SECTLIST","DOSBox configuration contains the following sections:\n\n"); MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); MSG_Add("PROGRAM_CONFIG_VALUE_ERROR","\"%s\" is not a valid value for property %s.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); MSG_Add("PROGRAM_CONFIG_SET_SYNTAX","Correct syntax: config -set \"section property\".\n"); MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n"); MSG_Add("PROGRAM_CONFIG_PRINT_STARTUP","\nDOSBox was started with the following command line parameters:\n%s"); MSG_Add("PROGRAM_CONFIG_MISSINGPARAM","Missing parameter."); }
void BIOS_Init() { Mem_rStosb(0x400, 0, 0x200); // Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) // Setup all the interrupt handlers the Bios controls CALLBACK_SetupExtra(0, CB_IRQ0, dWord2Ptr(BIOS_DEFAULT_IRQ0_LOCATION)); RealSetVec(0x08, BIOS_DEFAULT_IRQ0_LOCATION); BIOS_HostTimeSync(); // Initialize the timer ticks CALLBACK_Install(0x11, &INT11_Handler, CB_IRET); // INT 11 Get equipment list CALLBACK_Install(0x12, &INT12_Handler, CB_IRET); // INT 12 Memory size default at 640 kb Mem_Stosw(BIOS_MEMORY_SIZE, 640); CALLBACK_Install(0x13, &INT13_DiskHandler, CB_IRET_STI); // INT 13 BIOS Disk support Mem_Stosb(BIOS_HARDDISK_COUNT, 2); // Setup the Bios Area CALLBACK_Install(0x14, &INT14_Handler, CB_IRET_STI); // INT 14 Serial ports CALLBACK_Install(0x15, &INT15_Handler, CB_IRET_STI); // INT 15 Misc calls BIOS_SetupKeyboard(); // INT 16 Keyboard handled in another file CALLBACK_Install(0x17, &INT17_Handler, CB_IRET_STI); // INT 17 Printer Routines CALLBACK_Install(0x1a, &INT1A_Handler, CB_IRET_STI); // INT 1A Time and some other functions // These are already setup as dummy by CALLBACK_Init() // CALLBACK_SetupDummyIRET(0x1c); // INT 1C System timer tick called from INT 8 // CALLBACK_Install(0x71, NULL, CB_IRQ9); // Irq 9 rerouted to irq 2 // CALLBACK_SetupDummyIRET(0x18); // Reboot dummies // CALLBACK_SetupDummyIRET(0x19); // set system BIOS entry point too Mem_aStosb(0xffff0, 0xEA); // FAR JMP Mem_aStosd(0xffff1, Mem_Lodsd(0x18*4)); Bitu cbID = CALLBACK_Allocate(); // Irq 2 CALLBACK_Setup(cbID, NULL, CB_IRET_EOI_PIC1, dWord2Ptr(BIOS_DEFAULT_IRQ2_LOCATION)); RealSetVec(0x0a, BIOS_DEFAULT_IRQ2_LOCATION); Mem_aStosb(BIOS_DEFAULT_HANDLER_LOCATION, 0xcf); // BIOS default interrupt vector location -> IRET Mem_aWrites(0xfff00, "vDos BIOS", 9); // System BIOS identification Mem_aWrites(0xffff5, "01/01/99\x00\xfc\x24", 11); // System BIOS date + signature for (Bitu i = BIOS_COM1_TIMEOUT; i <= BIOS_COM4_TIMEOUT; i++) // Port timeouts Mem_Stosb(i, 1); }
void PROGRAMS_Init(Section* /*sec*/) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program"); PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart); MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n"); }
void CreateMouseCallback(void) { // Create callback call_int33=CALLBACK_Allocate(); CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); // Create a mouse vector with weird address // for strange mouse detection routines in Sim City & Wasteland Bit16u ofs = call_int33<<4; phys_writeb(CB_BASE+ofs+0,(Bit8u)0x90); //NOP phys_writeb(CB_BASE+ofs+1,(Bit8u)0xFE); //GRP 4 phys_writeb(CB_BASE+ofs+2,(Bit8u)0x38); //Extra Callback instruction phys_writew(CB_BASE+ofs+3,call_int33); //The immediate word phys_writeb(CB_BASE+ofs+5,(Bit8u)0xCF); //An IRET Instruction // Write weird vector WriteMouseIntVector(); };
void DOS_SetupMemory(bool low) { /* Let DOS claim a few bios interrupts. Makes vDos more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ Bitu cbID = CALLBACK_Allocate(); // DOS default int CALLBACK_Setup(cbID, &DOS_default_handler, CB_IRET, 0x708); RealSetVec(0x01, 0x700008); RealSetVec(0x03, 0x700008); RealSetVec(0x04, 0x700008); // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); mcb_devicedummy.SetPSPSeg(MCB_DOS); // Devices mcb_devicedummy.SetSize(1); mcb_devicedummy.SetType(0x4d); // More blocks will follow // mcb_devicedummy.SetFileName("SD "); Bit16u mcb_sizes = 2; // Create a small empty MCB (result from a growing environment block) // DOS_MCB tempmcb((Bit16u)DOS_MEM_START+mcb_sizes); // tempmcb.SetPSPSeg(MCB_FREE); // tempmcb.SetSize(4); // mcb_sizes += 5; // tempmcb.SetType(0x4d); int extra_size = low ? 0 : 4096 - DOS_MEM_START - mcb_sizes - 17; // Disable first 64Kb if low not set in config // Lock the previous empty MCB DOS_MCB tempmcb2((Bit16u)DOS_MEM_START+mcb_sizes); tempmcb2.SetPSPSeg(0x40); tempmcb2.SetSize(16+extra_size); mcb_sizes += 17+extra_size; tempmcb2.SetType(0x4d); DOS_MCB mcb((Bit16u)DOS_MEM_START+mcb_sizes); mcb.SetPSPSeg(MCB_FREE); // Free mcb.SetType(0x5a); // Last Block // mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes); mcb.SetSize(EndConvMem - 1 - DOS_MEM_START - mcb_sizes); dos.firstMCB = DOS_MEM_START; dos_infoblock.SetFirstMCB(DOS_MEM_START); }
void SHELL_Init() { /* Add messages */ MSG_Add("SHELL_ILLEGAL_PATH","Illegal Path.\n"); MSG_Add("SHELL_CMD_HELP","If you want a list of all supported commands type \033[33;1mhelp /all\033[0m .\nA short list of the most often used commands:\n"); 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_MISSING_PARAMETER","Required parameter missing.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\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"); MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined.\n"); 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"); 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!\nYou must \033[31mmount\033[0m it first. Type \033[1;33mintro\033[0m or \033[1;33mintro mount\033[0m for more information.\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); 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"); 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.\nIt's only possible to use SUBST on Local drives"); MSG_Add("SHELL_STARTUP_BEGIN", "\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[32mWelcome to DOSBox v%-8s\033[37m \xBA\n" "\xBA \xBA\n" // "\xBA DOSBox runs real and protected mode games. \xBA\n" "\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n" "\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n" "\xBA \xBA\n" "\xBA To adjust the emulated CPU speed, use \033[31mctrl-F11\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" ); MSG_Add("SHELL_STARTUP_CGA","\xBA DOSBox supports Composite CGA mode. \xBA\n" "\xBA Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_DEBUG", "\xBA Press \033[31malt-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_END", "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" "\xBA \033[32mThe DOSBox Team \033[33mhttp://www.dosbox.com\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. ); MSG_Add("SHELL_CMD_CHDIR_HELP","Displays/changes the current directory.\n"); MSG_Add("SHELL_CMD_CHDIR_HELP_LONG","CHDIR [drive:][path]\n" "CHDIR [..]\n" "CD [drive:][path]\n" "CD [..]\n\n" " .. Specifies that you want to change to the parent directory.\n\n" "Type CD drive: to display the current directory in the specified drive.\n" "Type CD without parameters to display the current drive and directory.\n"); 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_MKDIR_HELP_LONG","MKDIR [drive:][path]\n" "MD [drive:][path]\n"); MSG_Add("SHELL_CMD_RMDIR_HELP","Remove Directory.\n"); MSG_Add("SHELL_CMD_RMDIR_HELP_LONG","RMDIR [drive:][path]\n" "RD [drive:][path]\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_SHIFT_HELP","Leftshift commandline parameters in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); MSG_Add("SHELL_CMD_TYPE_HELP_LONG","TYPE [drive:][path][filename]\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); MSG_Add("SHELL_CMD_REM_HELP_LONG","REM [comment]\n"); 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 one or more files.\n"); MSG_Add("SHELL_CMD_RENAME_HELP_LONG","RENAME [drive:][path]filename1 filename2.\n" "REN [drive:][path]filename1 filename2.\n\n" "Note that you can not specify a new drive or path for your destination file.\n"); MSG_Add("SHELL_CMD_DELETE_HELP","Removes one or more files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive.\n"); MSG_Add("SHELL_CMD_LOADHIGH_HELP","Loads a program into upper memory (requires xms=true,umb=true).\n"); MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); MSG_Add("SHELL_CMD_CHOICE_HELP_LONG","CHOICE [/C:choices] [/N] [/S] text\n" " /C[:]choices - Specifies allowable keys. Default is: yn.\n" " /N - Do not display the choices at end of prompt.\n" " /S - Enables case-sensitive choices to be selected.\n" " text - The text to display as a prompt.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); MSG_Add("SHELL_CMD_VER_HELP","View and set the reported DOS version.\n"); MSG_Add("SHELL_CMD_VER_VER","DOSBox version %s. Reported DOS version %d.%02d.\n"); #ifdef IPHONEOS MSG_Add("SHELL_CMD_UNZIP_HELP","Extract zip file to current directory.\n"); #endif /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* 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); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET,"shell stop"); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); /* Now call up the shell for the first time */ Bit16u psp_seg=DOS_FIRST_SHELL; Bit16u env_seg=DOS_FIRST_SHELL+19; //DOS_GetMemory(1+(4096/16))+1; Bit16u stack_seg=DOS_GetMemory(2048/16); SegSet16(ss,stack_seg); reg_sp=2046; /* Set up int 24 and psp (Telarium games) */ real_writeb(psp_seg+16+1,0,0xea); /* far jmp */ real_writed(psp_seg+16+1,1,real_readd(0,0x24*4)); real_writed(0,0x24*4,((Bit32u)psp_seg<<16) | ((16+1)<<4)); /* Set up int 23 to "int 20" in the psp. Fixes what.exe */ real_writed(0,0x23*4,((Bit32u)psp_seg<<16)); /* Setup MCBs */ DOS_MCB pspmcb((Bit16u)(psp_seg-1)); pspmcb.SetPSPSeg(psp_seg); // MCB of the command shell psp pspmcb.SetSize(0x10+2); pspmcb.SetType(0x4d); DOS_MCB envmcb((Bit16u)(env_seg-1)); envmcb.SetPSPSeg(psp_seg); // MCB of the command shell environment envmcb.SetSize(DOS_MEM_START-env_seg); envmcb.SetType(0x4d); /* Setup environment */ PhysPt env_write=PhysMake(env_seg,0); MEM_BlockWrite(env_write,path_string,(Bitu)(strlen(path_string)+1)); env_write += (PhysPt)(strlen(path_string)+1); MEM_BlockWrite(env_write,comspec_string,(Bitu)(strlen(comspec_string)+1)); env_write += (PhysPt)(strlen(comspec_string)+1); mem_writeb(env_write++,0); mem_writew(env_write,1); env_write+=2; MEM_BlockWrite(env_write,full_name,(Bitu)(strlen(full_name)+1)); DOS_PSP psp(psp_seg); psp.MakeNew(0); dos.psp(psp_seg); /* The start of the filetable in the psp must look like this: * 01 01 01 00 02 * In order to achieve this: First open 2 files. Close the first and * duplicate the second (so the entries get 01) */ Bit16u dummy=0; DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDIN */ DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDOUT */ DOS_CloseFile(0); /* Close STDIN */ DOS_ForceDuplicateEntry(1,0); /* "new" STDIN */ DOS_ForceDuplicateEntry(1,2); /* STDERR */ DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDAUX */ DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDPRN */ psp.SetParent(psp_seg); /* Set the environment */ psp.SetEnvironment(env_seg); /* Set the command line for the shell start up */ CommandTail tail; tail.count=(Bit8u)strlen(init_line); strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); /* Setup internal DOS Variables */ dos.dta(RealMake(psp_seg,0x80)); dos.psp(psp_seg); SHELL_ProgramStart(&first_shell); first_shell->Run(); delete first_shell; first_shell = 0;//Make clear that it shouldn't be used anymore }
void DOS_SetupTables(void) { dos_memseg=0xd000; Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); for (i=0;i<DOS_DRIVES;i++) mem_writew(Real2Phys(dos.tables.mediaid)+i*2,0); /* Create the DOS Info Block */ dos_infoblock.SetLocation(DOS_INFOBLOCK_SEG); //c2woody /* create SDA */ DOS_SDA(DOS_SDA_SEG,0).Init(); /* Some weird files >20 detection routine */ /* Possibly obselete when SFT is properly handled */ real_writed(DOS_CONSTRING_SEG,0x0a,0x204e4f43); real_writed(DOS_CONSTRING_SEG,0x1a,0x204e4f43); real_writed(DOS_CONSTRING_SEG,0x2a,0x204e4f43); /* create a CON device driver */ seg=DOS_CONDRV_SEG; real_writed(seg,0x00,0xffffffff); // next ptr real_writew(seg,0x04,0x8013); // attributes real_writed(seg,0x06,0xffffffff); // strategy routine real_writed(seg,0x0a,0x204e4f43); // driver name real_writed(seg,0x0e,0x20202020); // driver name dos_infoblock.SetDeviceChainStart(RealMake(seg,0)); /* Create a fake Current Directory Structure */ seg=DOS_CDS_SEG; real_writed(seg,0x00,0x005c3a43); dos_infoblock.SetCurDirStruct(RealMake(seg,0)); /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ dos.tables.dcbs=RealMake(DOS_GetMemory(12),0); mem_writed(Real2Phys(dos.tables.dcbs),0); //empty table /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); real_writed(seg,0,0xffffffff); //Last File Table real_writew(seg,4,100); //File Table supports 100 files dos_infoblock.SetFCBTable(RealMake(seg,0)); /* Create a fake disk buffer head */ seg=DOS_GetMemory(6); for (Bitu ct=0; ct<0x20; ct++) real_writeb(seg,ct,0); real_writew(seg,0x00,0xffff); // forward ptr real_writew(seg,0x02,0xffff); // backward ptr real_writeb(seg,0x04,0xff); // not in use real_writeb(seg,0x0a,0x01); // number of FATs real_writed(seg,0x0d,0xffffffff); // pointer to DPB dos_infoblock.SetDiskBufferHeadPt(RealMake(seg,0)); /* Set buffers to a nice value */ dos_infoblock.SetBuffers(50,50); /* case map routine INT 0x21 0x38 */ call_casemap = CALLBACK_Allocate(); CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap"); /* Add it to country structure */ host_writed(country_info + 0x12, CALLBACK_RealPointer(call_casemap)); dos.tables.country=country_info; }
void DOS_SetupTables(void) { Bit16u seg;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); for (i=0;i<DOS_DRIVES;i++) mem_writew(Real2Phys(dos.tables.mediaid)+i*2,0); /* Create the DOS Info Block */ dos_infoblock.SetLocation(DOS_INFOBLOCK_SEG); //c2woody /* create SDA */ DOS_SDA(DOS_SDA_SEG,0).Init(); /* Some weird files >20 detection routine */ /* Possibly obselete when SFT is properly handled */ real_writed(DOS_CONSTRING_SEG,0x0a,0x204e4f43); real_writed(DOS_CONSTRING_SEG,0x1a,0x204e4f43); real_writed(DOS_CONSTRING_SEG,0x2a,0x204e4f43); /* create a CON device driver */ seg=DOS_CONDRV_SEG; real_writed(seg,0x00,0xffffffff); // next ptr real_writew(seg,0x04,0x8013); // attributes real_writed(seg,0x06,0xffffffff); // strategy routine real_writed(seg,0x0a,0x204e4f43); // driver name real_writed(seg,0x0e,0x20202020); // driver name dos_infoblock.SetDeviceChainStart(RealMake(seg,0)); /* Create a fake Current Directory Structure */ seg=DOS_CDS_SEG; real_writed(seg,0x00,0x005c3a43); dos_infoblock.SetCurDirStruct(RealMake(seg,0)); /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ dos.tables.dbcs=RealMake(DOS_GetMemory(12),0); mem_writed(Real2Phys(dos.tables.dbcs),0); //empty table /* FILENAME CHARACTER TABLE */ dos.tables.filenamechar=RealMake(DOS_GetMemory(2),0); mem_writew(Real2Phys(dos.tables.filenamechar)+0x00,0x16); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x02,0x01); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x03,0x00); // allowed chars from mem_writeb(Real2Phys(dos.tables.filenamechar)+0x04,0xff); // ...to mem_writeb(Real2Phys(dos.tables.filenamechar)+0x05,0x00); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x06,0x00); // excluded chars from mem_writeb(Real2Phys(dos.tables.filenamechar)+0x07,0x20); // ...to mem_writeb(Real2Phys(dos.tables.filenamechar)+0x08,0x02); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x09,0x0e); // number of illegal separators mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0a,0x2e); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0b,0x22); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0c,0x2f); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0d,0x5c); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0e,0x5b); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0f,0x5d); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x10,0x3a); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x11,0x7c); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x12,0x3c); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x13,0x3e); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x14,0x2b); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x15,0x3d); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x16,0x3b); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x17,0x2c); /* COLLATING SEQUENCE TABLE + UPCASE TABLE*/ // 256 bytes for col table, 128 for upcase, 4 for number of entries dos.tables.collatingseq=RealMake(DOS_GetMemory(25),0); mem_writew(Real2Phys(dos.tables.collatingseq),0x100); for (i=0; i<256; i++) mem_writeb(Real2Phys(dos.tables.collatingseq)+i+2,i); dos.tables.upcase=dos.tables.collatingseq+258; mem_writew(Real2Phys(dos.tables.upcase),0x80); for (i=0; i<128; i++) mem_writeb(Real2Phys(dos.tables.upcase)+i+2,0x80+i); /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); real_writed(seg,0,0xffffffff); //Last File Table real_writew(seg,4,100); //File Table supports 100 files dos_infoblock.SetFCBTable(RealMake(seg,0)); /* Create a fake DPB */ dos.tables.dpb=DOS_GetMemory(2); for(Bitu d=0;d<26;d++) real_writeb(dos.tables.dpb,d,d); /* Create a fake disk buffer head */ seg=DOS_GetMemory(6); for (Bitu ct=0; ct<0x20; ct++) real_writeb(seg,ct,0); real_writew(seg,0x00,0xffff); // forward ptr real_writew(seg,0x02,0xffff); // backward ptr real_writeb(seg,0x04,0xff); // not in use real_writeb(seg,0x0a,0x01); // number of FATs real_writed(seg,0x0d,0xffffffff); // pointer to DPB dos_infoblock.SetDiskBufferHeadPt(RealMake(seg,0)); /* Set buffers to a nice value */ dos_infoblock.SetBuffers(50,50); /* case map routine INT 0x21 0x38 */ call_casemap = CALLBACK_Allocate(); CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap"); /* Add it to country structure */ host_writed(country_info + 0x12, CALLBACK_RealPointer(call_casemap)); dos.tables.country=country_info; }
void MOUSE_Init(Section* /*sec*/) { // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); // RealPt i33loc=RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10); RealPt i33loc=RealMake(DOS_GetMemory(0x1)-1,0x10); CALLBACK_Setup(call_int33,&INT33_Handler,CB_MOUSE,Real2Phys(i33loc),"Mouse"); // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 real_writed(0,0x33<<2,i33loc); call_mouse_bd=CALLBACK_Allocate(); CALLBACK_Setup(call_mouse_bd,&MOUSE_BD_Handler,CB_RETF8, PhysMake(RealSeg(i33loc),RealOff(i33loc)+2),"MouseBD"); // pseudocode for CB_MOUSE (including the special backdoor entry point): // jump near i33hd // callback MOUSE_BD_Handler // retf 8 // label i33hd: // callback INT33_Handler // iret // Callback for ps2 irq call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRQ12,"int 74"); // pseudocode for CB_IRQ12: // push ds // push es // pushad // sti // callback INT74_Handler // doesn't return here, but rather to CB_IRQ12_RET // (ps2 callback/user callback inbetween if requested) int74_ret_callback=CALLBACK_Allocate(); CALLBACK_Setup(int74_ret_callback,&MOUSE_UserInt_CB_Handler,CB_IRQ12_RET,"int 74 ret"); // pseudocode for CB_IRQ12_RET: // callback MOUSE_UserInt_CB_Handler // cli // mov al, 0x20 // out 0xa0, al // out 0x20, al // popad // pop es // pop ds // iret Bit8u hwvec=(MOUSE_IRQ>7)?(0x70+MOUSE_IRQ-8):(0x8+MOUSE_IRQ); RealSetVec(hwvec,CALLBACK_RealPointer(call_int74)); // Callback for ps2 user callback handling useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); mouse.hidden = 1; //Hide mouse on startup mouse.timer_in_progress = false; mouse.mode = 0xFF; //Non existing mode mouse.sub_mask=0; mouse.sub_seg=0x6362; // magic value mouse.sub_ofs=0; Mouse_ResetHardware(); Mouse_Reset(); Mouse_SetSensitivity(50,50,50); }
void CALLBACK_Init() { for (Bitu i = 0; i < CB_MAX; i++) CallBack_Handlers[i] = &illegal_handler; // Setup the Stop Handler call_stop = CALLBACK_Allocate(); CallBack_Handlers[call_stop] = stop_handler; CALLBACK_SetDescription(call_stop, "stop"); vPC_aStosw(CALLBACK_PhysPointer(call_stop)+0, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(CALLBACK_PhysPointer(call_stop)+2, (Bit16u)call_stop); // Setup the idle handler call_idle = CALLBACK_Allocate(); CallBack_Handlers[call_idle] = stop_handler; CALLBACK_SetDescription(call_idle, "idle"); for (Bitu i = 0; i <= 11; i++) vPC_aStosb(CALLBACK_PhysPointer(call_idle)+i, 0x90); // NOP vPC_aStosw(CALLBACK_PhysPointer(call_idle)+12, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(CALLBACK_PhysPointer(call_idle)+14, (Bit16u)call_idle); // Default handlers for unhandled interrupts that have to be non-null call_default = CALLBACK_Allocate(); CALLBACK_Setup(call_default, &default_handler, CB_IRET, "default"); call_default2 = CALLBACK_Allocate(); CALLBACK_Setup(call_default2, &default_handler, CB_IRET, "default"); // Only setup default handler for first part of interrupt table for (Bit16u ct = 0; ct < 0x60; ct++) vPC_rStosd(ct*4, CALLBACK_RealPointer(call_default)); for (Bit16u ct = 0x68; ct < 0x70; ct++) vPC_rStosd(ct*4, CALLBACK_RealPointer(call_default)); // Setup block of 0xCD 0xxx instructions PhysPt rint_base = CALLBACK_GetBase()+CB_MAX*CB_SIZE; for (Bitu i = 0; i <= 0xff; i++) { vPC_aStosb(rint_base, 0xCD); vPC_aStosb(rint_base+1, (Bit8u)i); vPC_aStosw(rint_base+2, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(rint_base+4, (Bit16u)call_stop); rint_base += 6; } // setup a few interrupt handlers that point to bios IRETs by default vPC_rStosd(0x0e*4, CALLBACK_RealPointer(call_default2)); // design your own railroad vPC_rStosd(0x66*4, CALLBACK_RealPointer(call_default)); // war2d vPC_rStosd(0x67*4, CALLBACK_RealPointer(call_default)); vPC_rStosd(0x68*4, CALLBACK_RealPointer(call_default)); vPC_rStosd(0x5c*4, CALLBACK_RealPointer(call_default)); // Network stuff // virtualizable in-out opcodes call_priv_io = CALLBACK_Allocate(); vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x00, 0xcbec); // in al, dx + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x02, 0xcbed); // in ax, dx + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x04, 0xed66); // in eax, dx vPC_aStosb(CALLBACK_PhysPointer(call_priv_io)+0x06, (Bit8u)0xcb); // retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x08, 0xcbee); // out dx, al + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x0a, 0xcbef); // out dx, ax + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x0c, 0xef66); // out dx, eax vPC_aStosb(CALLBACK_PhysPointer(call_priv_io)+0x0e, (Bit8u)0xcb); // retf }
void CALLBACK_Init(Section* /*sec*/) { Bitu i; for (i=0;i<CB_MAX;i++) { CallBack_Handlers[i]=&illegal_handler; } /* Setup the Stop Handler */ call_stop=CALLBACK_Allocate(); CallBack_Handlers[call_stop]=stop_handler; CALLBACK_SetDescription(call_stop,"stop"); phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE); phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38); phys_writew(CALLBACK_PhysPointer(call_stop)+2,(Bit16u)call_stop); /* Setup the idle handler */ call_idle=CALLBACK_Allocate(); CallBack_Handlers[call_idle]=stop_handler; CALLBACK_SetDescription(call_idle,"idle"); for (i=0;i<=11;i++) phys_writeb(CALLBACK_PhysPointer(call_idle)+i,0x90); phys_writeb(CALLBACK_PhysPointer(call_idle)+12,0xFE); phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38); phys_writew(CALLBACK_PhysPointer(call_idle)+14,(Bit16u)call_idle); /* Default handlers for unhandled interrupts that have to be non-null */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); call_default2=CALLBACK_Allocate(); CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default"); /* Only setup default handler for first part of interrupt table */ for (Bit16u ct=0;ct<0x60;ct++) { real_writed(0,ct*4,CALLBACK_RealPointer(call_default)); } for (Bit16u ct=0x68;ct<0x70;ct++) { real_writed(0,ct*4,CALLBACK_RealPointer(call_default)); } /* Setup block of 0xCD 0xxx instructions */ PhysPt rint_base=CALLBACK_GetBase()+CB_MAX*CB_SIZE; for (i=0;i<=0xff;i++) { phys_writeb(rint_base,0xCD); phys_writeb(rint_base+1,(Bit8u)i); phys_writeb(rint_base+2,0xFE); phys_writeb(rint_base+3,0x38); phys_writew(rint_base+4,(Bit16u)call_stop); rint_base+=6; } // setup a few interrupt handlers that point to bios IRETs by default real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x68*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it call_priv_io=CALLBACK_Allocate(); // virtualizable in-out opcodes phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x00,(Bit8u)0xec); // in al, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x01,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x02,(Bit8u)0xed); // in ax, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x03,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x04,(Bit8u)0x66); // in eax, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x05,(Bit8u)0xed); phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x06,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x08,(Bit8u)0xee); // out dx, al phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x09,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0a,(Bit8u)0xef); // out dx, ax phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0b,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0c,(Bit8u)0x66); // out dx, eax phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0d,(Bit8u)0xef); phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0e,(Bit8u)0xcb); // retf }
void CALLBACK_Init(Section* sec) { Bitu i; for (i=0;i<CB_MAX;i++) { CallBack_Handlers[i]=&illegal_handler; } /* Setup the Stop Handler */ call_stop=CALLBACK_Allocate(); CallBack_Handlers[call_stop]=stop_handler; CALLBACK_SetDescription(call_stop,"stop"); phys_writeb(CB_BASE+(call_stop<<4)+0,0xFE); phys_writeb(CB_BASE+(call_stop<<4)+1,0x38); phys_writew(CB_BASE+(call_stop<<4)+2,call_stop); /* Setup the idle handler */ call_idle=CALLBACK_Allocate(); CallBack_Handlers[call_idle]=stop_handler; CALLBACK_SetDescription(call_idle,"idle"); for (i=0;i<=11;i++) phys_writeb(CB_BASE+(call_idle<<4)+i,0x90); phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE); phys_writeb(CB_BASE+(call_idle<<4)+13,0x38); phys_writew(CB_BASE+(call_idle<<4)+14,call_idle); /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); /* Only setup default handler for first half of interrupt table */ for (i=0;i<0x40;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } /* Setup block of 0xCD 0xxx instructions */ PhysPt rint_base=CB_BASE+CB_MAX*16; for (i=0;i<=0xff;i++) { phys_writeb(rint_base,0xCD); phys_writeb(rint_base+1,i); phys_writeb(rint_base+2,0xFE); phys_writeb(rint_base+3,0x38); phys_writew(rint_base+4,call_stop); rint_base+=6; } real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it call_priv_io=CALLBACK_Allocate(); phys_writeb(CB_BASE+(call_priv_io<<4)+0x00,(Bit8u)0xec); // in al, dx phys_writeb(CB_BASE+(call_priv_io<<4)+0x01,(Bit8u)0xcb); // retf phys_writeb(CB_BASE+(call_priv_io<<4)+0x02,(Bit8u)0xed); // in ax, dx phys_writeb(CB_BASE+(call_priv_io<<4)+0x03,(Bit8u)0xcb); // retf phys_writeb(CB_BASE+(call_priv_io<<4)+0x04,(Bit8u)0x66); // in eax, dx phys_writeb(CB_BASE+(call_priv_io<<4)+0x05,(Bit8u)0xed); phys_writeb(CB_BASE+(call_priv_io<<4)+0x06,(Bit8u)0xcb); // retf phys_writeb(CB_BASE+(call_priv_io<<4)+0x08,(Bit8u)0xee); // out dx, al phys_writeb(CB_BASE+(call_priv_io<<4)+0x09,(Bit8u)0xcb); // retf phys_writeb(CB_BASE+(call_priv_io<<4)+0x0a,(Bit8u)0xef); // out dx, ax phys_writeb(CB_BASE+(call_priv_io<<4)+0x0b,(Bit8u)0xcb); // retf phys_writeb(CB_BASE+(call_priv_io<<4)+0x0c,(Bit8u)0x66); // out dx, eax phys_writeb(CB_BASE+(call_priv_io<<4)+0x0d,(Bit8u)0xef); phys_writeb(CB_BASE+(call_priv_io<<4)+0x0e,(Bit8u)0xcb); // retf }