Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { /* Fill 256 byte buffer with VESA information */ PhysPt buffer=PhysMake(seg,off); Bitu i; bool vbe2=false;Bit16u vbe2_pos=256+off; Bitu id=mem_readd(buffer); if (((id==0x56424532)||(id==0x32454256)) && (!int10.vesa_oldvbe)) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); } else { for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); } /* Fill common data */ MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification if (!int10.vesa_oldvbe) mem_writew(buffer+0x04,0x200); //Vesa version 2.0 else mem_writew(buffer+0x04,0x102); //Vesa version 1.2 if (vbe2) { mem_writed(buffer+0x06,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_oem);i++) real_writeb(seg,vbe2_pos++,string_oem[i]); mem_writew(buffer+0x14,0x200); //VBE 2 software revision mem_writed(buffer+0x16,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_vendorname);i++) real_writeb(seg,vbe2_pos++,string_vendorname[i]); mem_writed(buffer+0x1a,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_productname);i++) real_writeb(seg,vbe2_pos++,string_productname[i]); mem_writed(buffer+0x1e,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_productrev);i++) real_writeb(seg,vbe2_pos++,string_productrev[i]); } else { mem_writed(buffer+0x06,int10.rom.oemstring); //Oemstring } mem_writed(buffer+0x0a,0x0); //Capabilities and flags mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list mem_writew(buffer+0x12,(Bit16u)(vga.vmemsize/(64*1024))); // memory size in 64kb blocks return VESA_SUCCESS; }
Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { /* Fill 256 byte buffer with VESA information */ PhysPt buffer=PhysMake(seg,off); Bitu i; bool vbe2=false;Bit16u vbe2_pos; Bitu id=mem_readd(buffer); if (((id==0x56424532)||(id==0x32454256)) && (!int10.vesa_oldvbe)) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); } else { for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); } /* Fill common data */ MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification if (!int10.vesa_oldvbe) mem_writew(buffer+0x04,0x200); //Vesa version 2.0 else mem_writew(buffer+0x04,0x102); //Vesa version 1.2 if (vbe2) { vbe2_pos=256+off; mem_writed(buffer+0x06,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_oem);i++) real_writeb(seg,vbe2_pos++,(Bit8u)string_oem[i]); mem_writew(buffer+0x14,0x200); //VBE 2 software revision mem_writed(buffer+0x16,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_vendorname);i++) real_writeb(seg,vbe2_pos++,(Bit8u)string_vendorname[i]); mem_writed(buffer+0x1a,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_productname);i++) real_writeb(seg,vbe2_pos++,(Bit8u)string_productname[i]); mem_writed(buffer+0x1e,RealMake(seg,vbe2_pos)); for (i=0;i<sizeof(string_productrev);i++) real_writeb(seg,vbe2_pos++,(Bit8u)string_productrev[i]); } else { vbe2_pos=0x20+off; mem_writed(buffer+0x06,int10.rom.oemstring); //Oemstring } if (vesa_bios_modelist_in_info) { /* put the modelist into the VBE struct itself, as modern BIOSes like to do. * NOTICE: This limits the modelist to what is able to fit! Extended modes may not fit, which is why the option is OFF by default. */ uint16_t modesg = int10.rom.vesa_modes >> 16; uint16_t modoff = int10.rom.vesa_modes & 0xFFFF; uint16_t m; mem_writed(buffer+0x0e,RealMake(seg,vbe2_pos)); //VESA Mode list do { if (vbe2) { if (vbe2_pos >= (509+off)) break; } else { if (vbe2_pos >= (253+off)) break; } m = real_readw(modesg,modoff); if (m == 0xFFFF) break; real_writew(seg,vbe2_pos,m); vbe2_pos += 2; modoff += 2; } while (1); real_writew(seg,vbe2_pos,0xFFFF); } else {
static void udbg_real_scc_putc(char c) { while ((real_readb(sccc) & SCC_TXRDY) == 0) ; real_writeb(c, sccd); if (c == '\n') udbg_real_scc_putc('\r'); }
static void udbg_40x_real_putc(char c) { if (udbg_comport) { if (c == '\n') udbg_40x_real_putc('\r'); udbg_40x_real_flush(); real_writeb(c, &udbg_comport->thr); eieio(); } }
void udbg_maple_real_putc(char c) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; real_writeb(c, &udbg_comport->thr); eieio(); if (c == '\n') udbg_maple_real_putc('\r'); } }
static Bitu INT10_Handler(void) { // NTS: We do have to check the "current video mode" from the BIOS data area every call. // Some OSes like Windows 95 rely on overwriting the "current video mode" byte in // the BIOS data area to play tricks with the BIOS. If we don't call this, tricks // like the Windows 95 boot logo or INT 10h virtualization in Windows 3.1/9x/ME // within the DOS "box" will not work properly. INT10_SetCurMode(); switch (reg_ah) { case 0x00: /* Set VideoMode */ INT10_SetVideoMode(reg_al); break; case 0x01: /* Set TextMode Cursor Shape */ INT10_SetCursorShape(reg_ch,reg_cl); break; case 0x02: /* Set Cursor Pos */ INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); break; case 0x03: /* get Cursor Pos and Cursor Shape*/ // reg_ah=0; reg_dl=CURSOR_POS_COL(reg_bh); reg_dh=CURSOR_POS_ROW(reg_bh); reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE); break; case 0x04: /* read light pen pos YEAH RIGHT */ /* Light pen is not supported */ reg_ax=0; break; case 0x05: /* Set Active Page */ if ((reg_al & 0x80) && IS_TANDY_ARCH) { Bit8u crtcpu=real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE); switch (reg_al) { case 0x80: reg_bh=crtcpu & 7; reg_bl=(crtcpu >> 3) & 0x7; break; case 0x81: crtcpu=(crtcpu & 0xc7) | ((reg_bl & 7) << 3); break; case 0x82: crtcpu=(crtcpu & 0xf8) | (reg_bh & 7); break; case 0x83: crtcpu=(crtcpu & 0xc0) | (reg_bh & 7) | ((reg_bl & 7) << 3); break; } if (machine==MCH_PCJR) { /* always return graphics mapping, even for invalid values of AL */ reg_bh=crtcpu & 7; reg_bl=(crtcpu >> 3) & 0x7; } IO_WriteB(0x3df,crtcpu); real_writeb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE,crtcpu); }
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_SetupMemory(void) { /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); real_writeb(0x70,4,(Bit8u)0xFE); //GRP 4 real_writeb(0x70,5,(Bit8u)0x38); //Extra Callback instruction real_writew(0x70,6,callbackhandler.Get_callback()); //The immediate word real_writeb(0x70,8,(Bit8u)0xCF); //An IRET Instruction real_writed(0,0x01*4,0x700004); real_writed(0,0x02*4,0x700004); //BioMenace (segment<0x8000) real_writed(0,0x03*4,0x700004); //Alien Incident (offset!=0) real_writed(0,0x04*4,0x700004); //Shadow President (lower byte of segment!=0) // real_writed(0,0x0f*4,0x700004); //Always a tricky one (soundblaster irq) // 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); // Lock the previous empty MCB DOS_MCB tempmcb2((Bit16u)DOS_MEM_START+mcb_sizes); tempmcb2.SetPSPSeg(0x40); // can be removed by loadfix tempmcb2.SetSize(16); mcb_sizes+=17; tempmcb2.SetType(0x4d); DOS_MCB mcb((Bit16u)DOS_MEM_START+mcb_sizes); mcb.SetPSPSeg(MCB_FREE); //Free mcb.SetType(0x5a); //Last Block if (machine==MCH_TANDY) { /* memory up to 608k available, the rest (to 640k) is used by the tandy graphics system's variable mapping of 0xb800 */ mcb.SetSize(0x97FE - DOS_MEM_START - mcb_sizes); } else if (machine==MCH_PCJR) { /* memory from 128k to 640k is available */ mcb_devicedummy.SetPt((Bit16u)0x2000); mcb_devicedummy.SetPSPSeg(MCB_FREE); mcb_devicedummy.SetSize(0x9FFE - 0x2000); mcb_devicedummy.SetType(0x5a); /* exclude PCJr graphics region */ mcb_devicedummy.SetPt((Bit16u)0x17ff); mcb_devicedummy.SetPSPSeg(MCB_DOS); mcb_devicedummy.SetSize(0x800); mcb_devicedummy.SetType(0x4d); /* memory below 96k */ mcb.SetSize(0x1800 - DOS_MEM_START - (2+mcb_sizes)); mcb.SetType(0x4d); } else { /* complete memory up to 640k available */ mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes); } dos.firstMCB=DOS_MEM_START; dos_infoblock.SetFirstMCB(DOS_MEM_START); }
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; }
static Bitu INT10_Handler(void) { #if 0 switch (reg_ah) { case 0x02: case 0x03: case 0x09: case 0xc: case 0xd: case 0x0e: case 0x10: case 0x4f: break; default: LOG(LOG_INT10,LOG_NORMAL)("Function AX:%04X , BX %04X DX %04X",reg_ax,reg_bx,reg_dx); break; } #endif switch (reg_ah) { case 0x00: /* Set VideoMode */ INT10_SetVideoMode(reg_al); break; case 0x01: /* Set TextMode Cursor Shape */ INT10_SetCursorShape(reg_ch,reg_cl); break; case 0x02: /* Set Cursor Pos */ INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); break; case 0x03: /* get Cursor Pos and Cursor Shape*/ // reg_ah=0; reg_dl=CURSOR_POS_COL(reg_bh); reg_dh=CURSOR_POS_ROW(reg_bh); reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE); break; case 0x04: /* read light pen pos YEAH RIGHT */ /* Light pen is not supported */ reg_ax=0; break; case 0x05: /* Set Active Page */ if ((reg_al & 0x80) && IS_TANDY_ARCH) { Bit8u crtcpu=real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE); switch (reg_al) { case 0x80: reg_bh=crtcpu & 7; reg_bl=(crtcpu >> 3) & 0x7; break; case 0x81: crtcpu=(crtcpu & 0xc7) | ((reg_bl & 7) << 3); break; case 0x82: crtcpu=(crtcpu & 0xf8) | (reg_bh & 7); break; case 0x83: crtcpu=(crtcpu & 0xc0) | (reg_bh & 7) | ((reg_bl & 7) << 3); break; } if (machine==MCH_PCJR) { /* always return graphics mapping, even for invalid values of AL */ reg_bh=crtcpu & 7; reg_bl=(crtcpu >> 3) & 0x7; } IO_WriteB(0x3df,crtcpu); real_writeb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE,crtcpu); }
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; }
static void udbg_uart_out_40x(unsigned int reg, u8 val) { real_writeb(val, (void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR + reg); }
static void udbg_uart_out_maple(unsigned int reg, u8 val) { real_writeb(val, UDBG_UART_MAPLE_ADDR + reg); }
static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { Bitu length=real_readw(0x40,0xd0); if (length==0) return; /* nothing to do... */ if ((tandy_sb.port==0) && (tandy_dac.port==0)) return; Bit8u tandy_irq = 7; if (tandy_sb.port) tandy_irq = tandy_sb.irq; else if (tandy_dac.port) tandy_irq = tandy_dac.irq; Bit8u tandy_irq_vector = tandy_irq; if (tandy_irq_vector<8) tandy_irq_vector += 8; else tandy_irq_vector += (0x70-8); /* revector IRQ-handler if necessary */ RealPt current_irq=RealGetVec(tandy_irq_vector); if (current_irq!=tandy_DAC_callback[0]->Get_RealPointer()) { real_writed(0x40,0xd6,current_irq); RealSetVec(tandy_irq_vector,tandy_DAC_callback[0]->Get_RealPointer()); } Bit8u tandy_dma = 1; if (tandy_sb.port) tandy_dma = tandy_sb.dma; else if (tandy_dac.port) tandy_dma = tandy_dac.dma; if (tandy_sb.port) { IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */ IO_Write(0x21,IO_Read(0x21)&(~(1<<tandy_irq))); /* unmask IRQ */ IO_Write(tandy_sb.port+0xc,0xd1); /* turn speaker on */ } else { IO_Write(tandy_dac.port,IO_Read(tandy_dac.port)&0x60); /* disable DAC */ IO_Write(0x21,IO_Read(0x21)&(~(1<<tandy_irq))); /* unmask IRQ */ } IO_Write(0x0a,0x04|tandy_dma); /* mask DMA channel */ IO_Write(0x0c,0x00); /* clear DMA flipflop */ if (isplayback) IO_Write(0x0b,0x48|tandy_dma); else IO_Write(0x0b,0x44|tandy_dma); /* set physical address of buffer */ Bit8u bufpage=(Bit8u)((bufpt>>16)&0xff); IO_Write(tandy_dma*2,(Bit8u)(bufpt&0xff)); IO_Write(tandy_dma*2,(Bit8u)((bufpt>>8)&0xff)); switch (tandy_dma) { case 0: IO_Write(0x87,bufpage); break; case 1: IO_Write(0x83,bufpage); break; case 2: IO_Write(0x81,bufpage); break; case 3: IO_Write(0x82,bufpage); break; } real_writeb(0x40,0xd4,bufpage); /* calculate transfer size (respects segment boundaries) */ Bit32u tlength=length; if (tlength+(bufpt&0xffff)>0x10000) tlength=0x10000-(bufpt&0xffff); real_writew(0x40,0xd0,(Bit16u)(length-tlength)); /* remaining buffer length */ tlength--; /* set transfer size */ IO_Write(tandy_dma*2+1,(Bit8u)(tlength&0xff)); IO_Write(tandy_dma*2+1,(Bit8u)((tlength>>8)&0xff)); Bit16u delay=(Bit16u)(real_readw(0x40,0xd2)&0xfff); Bit8u amplitude=(Bit8u)((real_readw(0x40,0xd2)>>13)&0x7); if (tandy_sb.port) { IO_Write(0x0a,tandy_dma); /* enable DMA channel */ /* set frequency */ IO_Write(tandy_sb.port+0xc,0x40); IO_Write(tandy_sb.port+0xc,256-delay*100/358); /* set playback type to 8bit */ if (isplayback) IO_Write(tandy_sb.port+0xc,0x14); else IO_Write(tandy_sb.port+0xc,0x24); /* set transfer size */ IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff)); IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff)); } else {
bool INT10_VideoState_Save(Bitu state,RealPt buffer) { Bitu ct; if ((state&7)==0) return false; Bitu base_seg=RealSeg(buffer); Bitu base_dest=RealOff(buffer)+0x20; if (state&1) { real_writew(base_seg,RealOff(buffer),base_dest); Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); real_writew(base_seg,base_dest+0x40,crt_reg); real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c4)); real_writeb(base_seg,base_dest+0x01,IO_ReadB(0x3d4)); real_writeb(base_seg,base_dest+0x02,IO_ReadB(0x3ce)); IO_ReadB(crt_reg+6); real_writeb(base_seg,base_dest+0x03,IO_ReadB(0x3c0)); real_writeb(base_seg,base_dest+0x04,IO_ReadB(0x3ca)); // sequencer for (ct=1; ct<5; ct++) { IO_WriteB(0x3c4,ct); real_writeb(base_seg,base_dest+0x04+ct,IO_ReadB(0x3c5)); } real_writeb(base_seg,base_dest+0x09,IO_ReadB(0x3cc)); // crt controller for (ct=0; ct<0x19; ct++) { IO_WriteB(crt_reg,ct); real_writeb(base_seg,base_dest+0x0a+ct,IO_ReadB(crt_reg+1)); } // attr registers for (ct=0; ct<4; ct++) { IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,0x10+ct); real_writeb(base_seg,base_dest+0x33+ct,IO_ReadB(0x3c1)); } // graphics registers for (ct=0; ct<9; ct++) { IO_WriteB(0x3ce,ct); real_writeb(base_seg,base_dest+0x37+ct,IO_ReadB(0x3cf)); } // save some registers IO_WriteB(0x3c4,2); Bit8u crtc_2=IO_ReadB(0x3c5); IO_WriteB(0x3c4,4); Bit8u crtc_4=IO_ReadB(0x3c5); IO_WriteB(0x3ce,6); Bit8u gfx_6=IO_ReadB(0x3cf); IO_WriteB(0x3ce,5); Bit8u gfx_5=IO_ReadB(0x3cf); IO_WriteB(0x3ce,4); Bit8u gfx_4=IO_ReadB(0x3cf); // reprogram for full access to plane latches IO_WriteW(0x3c4,0x0f02); IO_WriteW(0x3c4,0x0704); IO_WriteW(0x3ce,0x0406); IO_WriteW(0x3ce,0x0105); mem_writeb(0xaffff,0); for (ct=0; ct<4; ct++) { IO_WriteW(0x3ce,0x0004+ct*0x100); real_writeb(base_seg,base_dest+0x42+ct,mem_readb(0xaffff)); } // restore registers IO_WriteW(0x3ce,0x0004|(gfx_4<<8)); IO_WriteW(0x3ce,0x0005|(gfx_5<<8)); IO_WriteW(0x3ce,0x0006|(gfx_6<<8)); IO_WriteW(0x3c4,0x0004|(crtc_4<<8)); IO_WriteW(0x3c4,0x0002|(crtc_2<<8)); for (ct=0; ct<0x10; ct++) { IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,ct); real_writeb(base_seg,base_dest+0x23+ct,IO_ReadB(0x3c1)); } IO_WriteB(0x3c0,0x20); base_dest+=0x46; } if (state&2) { real_writew(base_seg,RealOff(buffer)+2,base_dest); real_writeb(base_seg,base_dest+0x00,mem_readb(0x410)&0x30); for (ct=0; ct<0x1e; ct++) { real_writeb(base_seg,base_dest+0x01+ct,mem_readb(0x449+ct)); } for (ct=0; ct<0x07; ct++) { real_writeb(base_seg,base_dest+0x1f+ct,mem_readb(0x484+ct)); } real_writed(base_seg,base_dest+0x26,mem_readd(0x48a)); real_writed(base_seg,base_dest+0x2a,mem_readd(0x14)); // int 5 real_writed(base_seg,base_dest+0x2e,mem_readd(0x74)); // int 1d real_writed(base_seg,base_dest+0x32,mem_readd(0x7c)); // int 1f real_writed(base_seg,base_dest+0x36,mem_readd(0x10c)); // int 43 base_dest+=0x3a; } if (state&4) { real_writew(base_seg,RealOff(buffer)+4,base_dest); Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,0x14); real_writeb(base_seg,base_dest+0x303,IO_ReadB(0x3c1)); Bitu dac_state=IO_ReadB(0x3c7)&1; Bitu dac_windex=IO_ReadB(0x3c8); if (dac_state!=0) dac_windex--; real_writeb(base_seg,base_dest+0x000,dac_state); real_writeb(base_seg,base_dest+0x001,dac_windex); real_writeb(base_seg,base_dest+0x002,IO_ReadB(0x3c6)); for (ct=0; ct<0x100; ct++) { IO_WriteB(0x3c7,ct); real_writeb(base_seg,base_dest+0x003+ct*3+0,IO_ReadB(0x3c9)); real_writeb(base_seg,base_dest+0x003+ct*3+1,IO_ReadB(0x3c9)); real_writeb(base_seg,base_dest+0x003+ct*3+2,IO_ReadB(0x3c9)); } IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,0x20); base_dest+=0x303; } if ((svgaCard==SVGA_S3Trio) && (state&8)) { real_writew(base_seg,RealOff(buffer)+6,base_dest); Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_WriteB(0x3c4,0x08); // Bitu seq_8=IO_ReadB(0x3c5); IO_ReadB(0x3c5); // real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5)); IO_WriteB(0x3c5,0x06); // unlock s3-specific registers // sequencer for (ct=0; ct<0x13; ct++) { IO_WriteB(0x3c4,0x09+ct); real_writeb(base_seg,base_dest+0x00+ct,IO_ReadB(0x3c5)); } // unlock s3-specific registers IO_WriteW(crt_reg,0x4838); IO_WriteW(crt_reg,0xa539); // crt controller Bitu ct_dest=0x13; for (ct=0; ct<0x40; ct++) { if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) { IO_WriteB(crt_reg,0x45); IO_ReadB(crt_reg+1); IO_WriteB(crt_reg,0x30+ct); real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); } else { IO_WriteB(crt_reg,0x30+ct); real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); } } } return true; }
void DOS_SetupMemory(void) { /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ Bit16u ihseg = 0x70; Bit16u ihofs = 0x08; real_writeb(ihseg,ihofs,(Bit8u)0xCF); //An IRET Instruction RealSetVec(0x01,RealMake(ihseg,ihofs)); //BioMenace (offset!=4) RealSetVec(0x02,RealMake(ihseg,ihofs)); //BioMenace (segment<0x8000) RealSetVec(0x03,RealMake(ihseg,ihofs)); //Alien Incident (offset!=0) RealSetVec(0x04,RealMake(ihseg,ihofs)); //Shadow President (lower byte of segment!=0) RealSetVec(0x0f,RealMake(ihseg,ihofs)); //Always a tricky one (soundblaster irq) // 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); // Lock the previous empty MCB DOS_MCB tempmcb2((Bit16u)DOS_MEM_START+mcb_sizes); tempmcb2.SetPSPSeg(0x40); // can be removed by loadfix tempmcb2.SetSize(16); mcb_sizes+=17; tempmcb2.SetType(0x4d); DOS_MCB mcb((Bit16u)DOS_MEM_START+mcb_sizes); mcb.SetPSPSeg(MCB_FREE); //Free mcb.SetType(0x5a); //Last Block if (machine==MCH_TANDY) { /* memory up to 608k available, the rest (to 640k) is used by the tandy graphics system's variable mapping of 0xb800 */ mcb.SetSize(0x9BFF - DOS_MEM_START - mcb_sizes); } else if (machine==MCH_PCJR) { /* memory from 128k to 640k is available */ mcb_devicedummy.SetPt((Bit16u)0x2000); mcb_devicedummy.SetPSPSeg(MCB_FREE); mcb_devicedummy.SetSize(0x9FFF - 0x2000); mcb_devicedummy.SetType(0x5a); /* exclude PCJr graphics region */ mcb_devicedummy.SetPt((Bit16u)0x17ff); mcb_devicedummy.SetPSPSeg(MCB_DOS); mcb_devicedummy.SetSize(0x800); mcb_devicedummy.SetType(0x4d); /* memory below 96k */ mcb.SetSize(0x1800 - DOS_MEM_START - (2+mcb_sizes)); mcb.SetType(0x4d); } else { /* complete memory up to 640k available */ /* last paragraph used to add UMB chain to low-memory MCB chain */ mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes); } dos.firstMCB=DOS_MEM_START; dos_infoblock.SetFirstMCB(DOS_MEM_START); }
TANDYSOUND(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast<Section_prop *>(configuration); bool enable_hw_tandy_dac=true; Bitu sbport, sbirq, sbdma; if (SB_Get_Address(sbport, sbirq, sbdma)) { enable_hw_tandy_dac=false; } //Select the correct tandy chip implementation if (machine == MCH_PCJR) activeDevice = &device_sn76496; else activeDevice = &device_ncr8496; real_writeb(0x40,0xd4,0x00); if (IS_TANDY_ARCH) { /* enable tandy sound if tandy=true/auto */ if ((strcmp(section->Get_string("tandy"),"true")!=0) && (strcmp(section->Get_string("tandy"),"on")!=0) && (strcmp(section->Get_string("tandy"),"auto")!=0)) return; } else { /* only enable tandy sound if tandy=true */ if ((strcmp(section->Get_string("tandy"),"true")!=0) && (strcmp(section->Get_string("tandy"),"on")!=0)) return; /* ports from second DMA controller conflict with tandy ports */ CloseSecondDMAController(); if (enable_hw_tandy_dac) { WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2); WriteHandler[3].Install(0x1e4,TandyDACWrite,IO_MB,4); // ReadHandler[3].Install(0x1e4,TandyDACRead,IO_MB,4); } } Bit32u sample_rate = section->Get_int("tandyrate"); tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); if (enable_hw_tandy_dac) { // enable low-level Tandy DAC emulation WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); ReadHandler[1].Install(0xc4,TandyDACRead,IO_MB,4); tandy.dac.enabled=true; tandy.dac.chan=MixerChanDAC.Install(&TandyDACUpdate,sample_rate,"TANDYDAC"); tandy.dac.hw.base=0xc4; tandy.dac.hw.irq =7; tandy.dac.hw.dma =1; } else { tandy.dac.enabled=false; tandy.dac.hw.base=0; tandy.dac.hw.irq =0; tandy.dac.hw.dma =0; } tandy.dac.control=0; tandy.dac.mode =0; tandy.dac.irq_activated=false; tandy.dac.frequency=0; tandy.dac.amplitude=0; tandy.dac.dma.last_sample=0; tandy.enabled=false; real_writeb(0x40,0xd4,0xff); /* BIOS Tandy DAC initialization value */ ((device_t&)device).device_start(); device.convert_samplerate(sample_rate); }