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 CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { reg_sp-=4; mem_writew(SegPhys(ss)+reg_sp,RealOff(CALLBACK_RealPointer(call_stop))); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(CALLBACK_RealPointer(call_stop))); Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); reg_eip=off; SegSet16(cs,seg); DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); }
static Bitu INT74_Handler(void) { if (mouse.events>0) { mouse.events--; /* Check for an active Interrupt Handler that will get called */ if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { reg_ax=mouse.event_queue[mouse.events].type; reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; reg_dx=POS_Y; reg_si=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); reg_di=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); SegSet16(cs, mouse.sub_seg); reg_ip = mouse.sub_ofs; if(mouse.in_UIR) LOG(LOG_MOUSE,LOG_ERROR)("Already in UIR!"); mouse.in_UIR = true; } else if (useps2callback) { CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); } else { SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } } else { SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } return CBRET_NONE; }
Bitu IO_ReadD(Bitu port) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; old_cpudecoder=cpudecoder; cpudecoder=&IOFaultCore; IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; entry->cs=SegValue(cs); entry->eip=reg_eip; CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); Bit16u old_dx = reg_dx; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x04; CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); iof_queue.used--; Bitu retval = reg_eax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; return retval; } else return io_readhandlers[2][port](port,4); }
void IO_WriteW(Bitu port,Bitu val) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; old_cpudecoder=cpudecoder; cpudecoder=&IOFaultCore; IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; entry->cs=SegValue(cs); entry->eip=reg_eip; CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); Bit16u old_ax = reg_ax; Bit16u old_dx = reg_dx; reg_al = val; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x0a; CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); iof_queue.used--; reg_ax = old_ax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } else { IO_USEC_write_delay(); io_writehandlers[1][port](port,val,2); } }
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 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 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; }
bool DOS_Shell::Execute(char * name,char * args) { /* return true => don't check for hardware changes in do_command * return false => check for hardware changes in do_command */ char fullname[DOS_PATHLENGTH+4]; //stores results from Which char* p_fullname; char line[CMD_MAXLINE]; if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front line[0]=' ';line[1]=0; strncat(line,args,CMD_MAXLINE-2); line[CMD_MAXLINE-1]=0; } else { safe_strncpy(line,args,CMD_MAXLINE); } }else{ line[0]=0; }; /* check for a drive change */ if (((strcmp(name + 1, ":") == 0) || (strcmp(name + 1, ":\\") == 0)) && isalpha(*name)) { if (!DOS_SetDrive(toupper(name[0])-'A')) { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); } return true; } /* Check for a full name */ p_fullname = Which(name); if (!p_fullname) return false; strcpy(fullname,p_fullname); const char* extension = strrchr(fullname,'.'); __android_log_print(ANDROID_LOG_INFO, "dosbox", "command fullname:%s", fullname); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { //Check if the result will fit in the parameters. Else abort if(strlen(fullname) >( DOS_PATHLENGTH - 1) ) return false; char temp_name[DOS_PATHLENGTH+4],* temp_fullname; //try to add .com, .exe and .bat extensions to filename strcpy(temp_name,fullname); strcat(temp_name,".COM"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".com";strcpy(fullname,temp_fullname); } else { strcpy(temp_name,fullname); strcat(temp_name,".EXE"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".exe";strcpy(fullname,temp_fullname);} else { strcpy(temp_name,fullname); strcat(temp_name,".BAT"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".bat";strcpy(fullname,temp_fullname);} else { return false; } } } } if (strcasecmp(extension, ".bat") == 0) { /* Run the .bat file */ /* delete old batch file if call is not active*/ bool temp_echo=echo; /*keep the current echostate (as delete bf might change it )*/ if(bf && !call) delete bf; bf=new BatchFile(this,fullname,name,line); echo=temp_echo; //restore it. } else { /* only .bat .exe .com extensions maybe be executed by the shell */ if(strcasecmp(extension, ".com") !=0) { if(strcasecmp(extension, ".exe") !=0) return false; } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; //Add Parameter block DOS_ParamBlock block(SegPhys(ss)+reg_sp); block.Clear(); //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,(Bitu)(strlen(fullname)+1)); /* HACK: Store full commandline for mount and imgmount */ full_arguments.assign(line); /* Fill the command line */ CommandTail cmdtail; cmdtail.count = 0; memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; cmdtail.count=(Bit8u)strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add); FCB_Parsename(dos.psp(),0x6C,0x00,&cmdtail.buffer[add],&add); block.exec.fcb1=RealMake(dos.psp(),0x5C); block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); #if 0 /* Save CS:IP to some point where i can return them from */ Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); #endif /* Start up a dos execute interrupt */ reg_ax=0x4b00; //Filename pointer SegSet16(ds,SegValue(ss)); reg_dx=RealOff(file_name); //Paramblock SegSet16(es,SegValue(ss)); reg_bx=reg_sp; SETFLAGBIT(IF,false); CALLBACK_RunRealInt(0x21); /* Restore CS:IP and the stack */ reg_sp+=0x200; #if 0 reg_eip=oldeip; SegSet16(cs,oldcs); #endif } return true; //Executable started }
Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { MODE_INFO minfo; memset(&minfo,0,sizeof(minfo)); PhysPt buf=PhysMake(seg,off); Bitu pageSize; Bit8u modeAttributes; Bitu i=0; mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits if (mode<0x100) return 0x01; if (svga.accepts_mode) { if (!svga.accepts_mode(mode)) return 0x01; } while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } return VESA_FAIL; foundit: if ((int10.vesa_oldvbe) && (ModeList_VGA[i].mode>=0x120)) return 0x01; VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN4: pageSize = mblock->sheight * mblock->swidth/2; var_write(&minfo.BytesPerScanLine,mblock->swidth/8); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,3); //ega planar mode modeAttributes = 0x1b; // Color, graphics, no linear buffer break; case M_LIN8: pageSize = mblock->sheight * mblock->swidth; var_write(&minfo.BytesPerScanLine,mblock->swidth); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,8); var_write(&minfo.MemoryModel,4); //packed pixel modeAttributes = 0x1b; // Color, graphics if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN15: pageSize = mblock->sheight * mblock->swidth*2; var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,15); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,5); var_write(&minfo.RedMaskPos,10); var_write(&minfo.GreenMaskSize,5); var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); var_write(&minfo.ReservedMaskSize,0x01); var_write(&minfo.ReservedMaskPos,0x0f); modeAttributes = 0x1b; // Color, graphics if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN16: pageSize = mblock->sheight * mblock->swidth*2; var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,16); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,5); var_write(&minfo.RedMaskPos,11); var_write(&minfo.GreenMaskSize,6); var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); modeAttributes = 0x1b; // Color, graphics if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN32: pageSize = mblock->sheight * mblock->swidth*4; var_write(&minfo.BytesPerScanLine,mblock->swidth*4); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,32); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,8); var_write(&minfo.RedMaskPos,0x10); var_write(&minfo.GreenMaskSize,0x8); var_write(&minfo.GreenMaskPos,0x8); var_write(&minfo.BlueMaskSize,0x8); var_write(&minfo.BlueMaskPos,0x0); var_write(&minfo.ReservedMaskSize,0x8); var_write(&minfo.ReservedMaskPos,0x18); modeAttributes = 0x1b; // Color, graphics if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_TEXT: pageSize = 0; var_write(&minfo.BytesPerScanLine, mblock->twidth * 2); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,0); // text modeAttributes = 0x0f; //Color, text, bios output break; default: return VESA_FAIL; } if (pageSize & 0xFFFF) { // It is documented that many applications assume 64k-aligned page sizes // VBETEST is one of them pageSize += 0x10000; pageSize &= ~0xFFFF; } Bitu pages = 0; if (pageSize > vga.vmemsize) { // mode not supported by current hardware configuration modeAttributes &= ~0x1; } else if (pageSize) { pages = (vga.vmemsize / pageSize)-1; } var_write(&minfo.NumberOfImagePages, pages); var_write(&minfo.ModeAttributes, modeAttributes); var_write(&minfo.WinAAttributes, 0x7); // Exists/readable/writable if (mblock->type==M_TEXT) { var_write(&minfo.WinGranularity,32); var_write(&minfo.WinSize,32); var_write(&minfo.WinASegment,0xb800); var_write(&minfo.XResolution,mblock->twidth); var_write(&minfo.YResolution,mblock->theight); } else { var_write(&minfo.WinGranularity,64); var_write(&minfo.WinSize,64); var_write(&minfo.WinASegment,0xa000); var_write(&minfo.XResolution,mblock->swidth); var_write(&minfo.YResolution,mblock->sheight); } var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); var_write(&minfo.NumberOfBanks,0x1); var_write(&minfo.Reserved_page,0x1); var_write(&minfo.XCharSize,mblock->cwidth); var_write(&minfo.YCharSize,mblock->cheight); if (!int10.vesa_nolfb) var_write(&minfo.PhysBasePtr,S3_LFB_BASE); MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); return VESA_SUCCESS; }
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 }
void Mouse_NewVideoMode(void) { //Does way to much. Many of this stuff should be moved to mouse_reset one day 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)); } // mouse.shown=-1;//Disabled as ida doesn't have mousecursor anymore /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); switch (mode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0d: case 0x0e: case 0x13: mouse.max_y=199; break; case 0x0f: case 0x10: mouse.max_y=349; break; case 0x11: case 0x12: mouse.max_y=479; break; default: mouse.max_y=199; LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); // Hide mouse cursor on non supported modi. Pirates Gold mouse.shown = -1; break; } mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; // Dont set max coordinates here. it is done by SetResolution! mouse.x = static_cast<float>((mouse.max_x + 1)/ 2); mouse.y = static_cast<float>((mouse.max_y + 1)/ 2); mouse.events = 0; mouse.mickey_x = 0; mouse.mickey_y = 0; mouse.hotx = 0; mouse.hoty = 0; mouse.background = false; mouse.screenMask = defaultScreenMask; mouse.cursorMask = defaultCursorMask; mouse.textAndMask= defaultTextAndMask; mouse.textXorMask= defaultTextXorMask; mouse.language = 0; mouse.page = 0; mouse.doubleSpeedThreshold = 64; mouse.updateRegion_x[0] = 1; mouse.updateRegion_y[0] = 1; mouse.updateRegion_x[1] = 1; mouse.updateRegion_y[1] = 1; mouse.cursorType = 0; mouse.enabled=true; mouse.oldshown=-1; SetMickeyPixelRate(8,16); oldmouseX = static_cast<Bit16s>(mouse.x); oldmouseY = static_cast<Bit16s>(mouse.y); }