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 CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft)*2; Bitu copy=(Bitu)(cright-cleft)*2u;Bitu nextline=CurMode->twidth*2; attr=(attr & 0x3) | ((attr & 0x3) << 2) | ((attr & 0x3) << 4) | ((attr & 0x3) << 6); for (Bitu i=0;i<cheight/2U;i++) { for (Bitu x=0;x<copy;x++) { mem_writeb(dest+x,attr); mem_writeb(dest+8*1024+x,attr); } dest+=nextline; } }
void DOS_FCB::Create(bool _extended) { Bitu fill; if (_extended) fill=33+7; else fill=33; Bitu i; for (i=0;i<fill;i++) mem_writeb(real_pt+i,0); pt=real_pt; if (_extended) { mem_writeb(real_pt,0xff); pt+=7; extended=true; } else extended=false; }
void DOS_PSP::SetCommandTail(RealPt src) { if (src) { // valid source MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),CTBUF+1); } else { // empty sSave(sPSP,cmdtail.count,0x00); mem_writeb(pt+offsetof(sPSP,cmdtail.buffer),0x0d); }; }
Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { Bit8u r,g,b; if (index>255) return VESA_FAIL; if (index+count>256) return VESA_FAIL; IO_Write(0x3c7,(Bit8u)index); while (count) { r = IO_Read(0x3c9); g = IO_Read(0x3c9); b = IO_Read(0x3c9); mem_writeb(data++,b); mem_writeb(data++,g); mem_writeb(data++,r); data++; count--; } return VESA_SUCCESS; }
//-------------------------------------------------------------------------- ssize_t idaapi dosbox_debmod_t::dbg_write_memory(ea_t ea, const void *buffer, size_t size) { if ( ea == 0 ) return 0; for(int i=0;i<size;i++) mem_writeb(ea + i, ((Bit8u *)buffer)[i]); return size; }
static void dma(uint8_t value) { int addr = value << 8; if (value > 0xF1) return; for (int i = 0; i < 160; i++) mem_writeb(0xFE00 + i, mem_readb(addr + i)); }
static void VGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { /* Write some bytes */ Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+8*((CurMode->twidth*row)*cheight+cleft); Bitu nextline=8*CurMode->twidth; Bitu copy = cheight;Bitu rowsize=8u*(Bitu)(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;x<rowsize;x++) mem_writeb(dest+x,attr); dest+=nextline; } }
//=========================================================================== BOOL MemImportar(WORD EndInicial) { #ifdef _WINDOWS OPENFILENAME ofn; #endif // _WINDOWS FILE *Arquivo; char *Buffer; DWORD TamMem; char directory[MAX_PATH] = ""; char filename[MAX_PATH] = ""; unsigned int c; #ifdef _WINDOWS memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = (HWND)framewindow; ofn.hInstance = (HINSTANCE)instance; ofn.lpstrFilter = "Todos os Arquivos\0*.*\0"; ofn.lpstrFile = filename; ofn.nMaxFile = MAX_PATH; ofn.lpstrInitialDir = directory; ofn.Flags = OFN_PATHMUSTEXIST; ofn.lpstrTitle = "Escolha o Arquivo"; if (GetOpenFileName(&ofn)) #else if (0) #endif { Arquivo = fopen(filename, "rb"); if (!Arquivo) { FrameMostraMensagemErro("Erro ao abrir o arquivo!"); return -1; } fseek(Arquivo, 0, SEEK_END); TamMem = ftell(Arquivo); if ((EndInicial+TamMem) > 0xC000) { FrameMostraMensagemErro("O conteúdo do arquivo excede a capacidade de memória do TK2000"); return -1; } Buffer = (char *)malloc(TamMem); fseek(Arquivo, 0, SEEK_SET); fread(Buffer, TamMem, 1, Arquivo); //memcpy((void *)(mem+EndInicial), (const void*)Buffer, (size_t)(TamMem)); for (c = 0; c < TamMem; c++) mem_writeb(EndInicial + c, Buffer[c]); fclose(Arquivo); return 0; } return -1; }
static void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); Bit8u banks=CurMode->twidth/10; PhysPt dest=base+((CurMode->twidth*row)*(cheight/banks)+cleft)*4; Bitu copy=(Bitu)(cright-cleft)*4u;Bitu nextline=CurMode->twidth*4; attr=(attr & 0xf) | (attr & 0xf) << 4; for (Bitu i=0;i<static_cast<Bitu>(cheight/banks);i++) { for (Bitu x=0;x<copy;x++) { for (Bitu b=0;b<banks;b++) mem_writeb(dest+b*8*1024+x,attr); } dest+=nextline; } }
static void VGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); dest=base+8u*((CurMode->twidth*rnew)*cheight+cleft); src=base+8u*((CurMode->twidth*rold)*cheight+cleft); Bitu nextline=8u*(Bitu)CurMode->twidth; Bitu rowsize=8u*(Bitu)(cright-cleft); copy=cheight; for (;copy>0;copy--) { for (Bitu x=0;x<rowsize;x++) mem_writeb(dest+x,mem_readb(src+x)); dest+=nextline;src+=nextline; } }
static Bitu INT70_Handler(void) { /* Acknowledge irq with cmos */ IO_Write(0x70,0xc); IO_Read(0x71); if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { Bit32u count=mem_readd(BIOS_WAIT_FLAG_COUNT); if (count>997) { mem_writed(BIOS_WAIT_FLAG_COUNT,count-997); } else { mem_writed(BIOS_WAIT_FLAG_COUNT,0); PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); mem_writeb(where,mem_readb(where)|0x80); mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(0,BIOS_WAIT_FLAG_TEMP)); IO_Write(0x70,0xb); IO_Write(0x71,IO_Read(0x71)&~0x40); } } /* Signal EOI to both pics */ IO_Write(0xa0,0x20); IO_Write(0x20,0x20); return 0; }
void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ // DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bitu i; const Bitu Bit8uSize = sizeof(Bit8u); const Bitu Bit16uSize = sizeof(Bit16u); const Bitu RealPtSize = sizeof(RealPt); const Bitu CommandTailSize = sizeof(CommandTail); const Bitu sizePSP = sizeof(sPSP); for (i=0;i<sizePSP;i++) mem_writeb(pt+i,0); // Set size sSave(sPSP,next_seg,seg+mem_size); /* far call opcode */ sSave(sPSP,far_call,0xea); // far call to interrupt 0x21 - faked for bill & ted // lets hope nobody really uses this address sSave(sPSP,cpm_entry,RealMake(0xDEAD,0xFFFF)); /* Standard blocks,int 20 and int21 retf */ sSave(sPSP,exit[0],0xcd); sSave(sPSP,exit[1],0x20); sSave(sPSP,service[0],0xcd); sSave(sPSP,service[1],0x21); sSave(sPSP,service[2],0xcb); /* psp and psp-parent */ sSave(sPSP,psp_parent,dos.psp()); sSave(sPSP,prev_psp,0xffffffff); sSave(sPSP,dos_version,0x0005); /* terminate 22,break 23,crititcal error 24 address stored */ SaveVectors(); /* FCBs are filled with 0 */ // .... /* Init file pointer and max_files */ sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files))); sSave(sPSP,max_files,20); for (Bit16u ct=0;ct<20;ct++) SetFileHandle(ct,0xff); /* User Stack pointer */ // if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); if (rootpsp==0) rootpsp = seg; }
static void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { /* Set Bitmask / Color / Full Set Reset */ IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); IO_Write(0x3ce,0x0);IO_Write(0x3cf,attr); IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); /* Enable all Write planes */ IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Write some bytes */ Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+(CurMode->twidth*row)*cheight+cleft; Bitu nextline=CurMode->twidth; Bitu copy = cheight;Bitu rowsize=(Bitu)(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;x<rowsize;x++) mem_writeb(dest+x,0xff); dest+=nextline; } IO_Write(0x3cf,0); }
void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { sSave(sDTA,sdrive,_sdrive); sSave(sDTA,sattr,_sattr); /* Fill with spaces */ Bitu i; for (i=0;i<11;i++) mem_writeb(pt+offsetof(sDTA,sname)+i,' '); char * find_ext; find_ext=strchr(pattern,'.'); if (find_ext) { Bitu size=(Bitu)(find_ext-pattern); if (size>8) size=8; MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,size); find_ext++; MEM_BlockWrite(pt+offsetof(sDTA,sext),find_ext,(strlen(find_ext)>3) ? 3 : (Bitu)strlen(find_ext)); } else { MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,(strlen(pattern) > 8) ? 8 : (Bitu)strlen(pattern)); } }
static void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); dest=base+(CurMode->twidth*rnew)*cheight+cleft; src=base+(CurMode->twidth*rold)*cheight+cleft; Bitu nextline=(Bitu)CurMode->twidth; /* Setup registers correctly */ IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Enable all Write planes */ /* Do some copying */ Bitu rowsize=(Bitu)(cright-cleft); copy=cheight; for (;copy>0;copy--) { for (Bitu x=0;x<rowsize;x++) mem_writeb(dest+x,mem_readb(src+x)); dest+=nextline;src+=nextline; } /* Restore registers */ IO_Write(0x3ce,5);IO_Write(0x3cf,0); /* Normal transfer mode */ }
static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ DOS_PSP psp(dos.psp()); PhysPt envread,envwrite; Bit16u envsize=1; bool parentenv=true; if (*segment==0) { if (!psp.GetEnvironment()) parentenv=false; //environment seg=0 envread=PhysMake(psp.GetEnvironment(),0); } else { if (!*segment) parentenv=false; //environment seg=0 envread=PhysMake(*segment,0); } if (parentenv) { for (envsize=0; ;envsize++) { if (envsize>=MAXENV - ENV_KEEPFREE) { DOS_SetError(DOSERR_ENVIRONMENT_INVALID); return false; } if (mem_readw(envread+envsize)==0) break; } envsize += 2; /* account for trailing \0\0 */ } Bit16u size=long2para(envsize+ENV_KEEPFREE); if (!DOS_AllocateMemory(segment,&size)) return false; envwrite=PhysMake(*segment,0); if (parentenv) { MEM_BlockCopy(envwrite,envread,envsize); // mem_memcpy(envwrite,envread,envsize); envwrite+=envsize; } else { mem_writeb(envwrite++,0); } mem_writew(envwrite,1); envwrite+=2; char namebuf[DOS_PATHLENGTH]; if (DOS_Canonicalize(name,namebuf)) { MEM_BlockWrite(envwrite,namebuf,strlen(namebuf)+1); return true; } else return false; }
void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { sSave(sDTA,sdrive,_sdrive); sSave(sDTA,sattr,_sattr); /* Fill with char 0 */ int i; for (i=0;i<LFN_NAMELENGTH;i++) { if (pattern[i]==0) break; sname[i]=pattern[i]; } while (i<=LFN_NAMELENGTH) sname[i++]=0; for (i=0;i<11;i++) mem_writeb(pt+offsetof(sDTA,spname)+i,0); char * find_ext; find_ext=strchr(pattern,'.'); if (find_ext) { Bitu size=(Bitu)(find_ext-pattern); if (size>8) size=8; MEM_BlockWrite(pt+offsetof(sDTA,spname),pattern,size); find_ext++; MEM_BlockWrite(pt+offsetof(sDTA,spext),find_ext,(strlen(find_ext)>3) ? 3 : (Bitu)strlen(find_ext)); } else { MEM_BlockWrite(pt+offsetof(sDTA,spname),pattern,(strlen(pattern) > 8) ? 8 : (Bitu)strlen(pattern)); } }
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 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 }
static Bitu DOS_21Handler(void) { if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { DOS_PSP psp(dos.psp()); psp.SetStack(RealMake(SegValue(ss),reg_sp-18)); } char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; static Bitu time_start = 0; //For emulating temporary time changes. switch (reg_ah) { case 0x00: /* Terminate Program */ DOS_Terminate(mem_readw(SegPhys(ss)+reg_sp+2),false,0); break; case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; dos.echo=true; DOS_ReadFile(STDIN,&c,&n); reg_al=c; dos.echo=false; } break; case 0x02: /* Write character to STDOUT */ { Bit8u c=reg_dl;Bit16u n=1; DOS_WriteFile(STDOUT,&c,&n); //Not in the official specs, but happens nonetheless. (last written character) reg_al = c;// reg_al=(c==9)?0x20:c; //Officially: tab to spaces } break; case 0x03: /* Read character from STDAUX */ { Bit16u port = real_readw(0x40,0); if(port!=0 && serialports[0]) { Bit8u status; // RTS/DTR on IO_WriteB(port+4,0x3); serialports[0]->Getchar(®_al, &status, true, 0xFFFFFFFF); } } break; case 0x04: /* Write Character to STDAUX */ { Bit16u port = real_readw(0x40,0); if(port!=0 && serialports[0]) { // RTS/DTR on IO_WriteB(port+4,0x3); serialports[0]->Putchar(reg_dl,true,true, 0xFFFFFFFF); // RTS off IO_WriteB(port+4,0x1); } } break; case 0x05: /* Write Character to PRINTER */ E_Exit("DOS:Unhandled call %02X",reg_ah); break; case 0x06: /* Direct Console Output / Input */ switch (reg_dl) { case 0xFF: /* Input */ { //Simulate DOS overhead for timing sensitive games //MM1 overhead(); //TODO Make this better according to standards if (!DOS_GetSTDINStatus()) { reg_al=0; CALLBACK_SZF(true); break; } Bit8u c;Bit16u n=1; DOS_ReadFile(STDIN,&c,&n); reg_al=c; CALLBACK_SZF(false); break; } default: { Bit8u c = reg_dl;Bit16u n = 1; DOS_WriteFile(STDOUT,&c,&n); reg_al = reg_dl; } break; }; break; case 0x07: /* Character Input, without echo */ { Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); reg_al=c; break; }; case 0x08: /* Direct Character Input, without echo (checks for breaks officially :)*/ { Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); reg_al=c; break; }; case 0x09: /* Write string to STDOUT */ { Bit8u c;Bit16u n=1; PhysPt buf=SegPhys(ds)+reg_dx; while ((c=mem_readb(buf++))!='$') { DOS_WriteFile(STDOUT,&c,&n); } } break; case 0x0a: /* Buffered Input */ { //TODO ADD Break checkin in STDIN but can't care that much for it PhysPt data=SegPhys(ds)+reg_dx; Bit8u free=mem_readb(data); Bit8u read=0;Bit8u c;Bit16u n=1; if (!free) break; free--; for(;;) { DOS_ReadFile(STDIN,&c,&n); if (c == 8) { // Backspace if (read) { //Something to backspace. // STDOUT treats backspace as non-destructive. DOS_WriteFile(STDOUT,&c,&n); c = ' '; DOS_WriteFile(STDOUT,&c,&n); c = 8; DOS_WriteFile(STDOUT,&c,&n); --read; } continue; } if (read == free && c != 13) { // Keyboard buffer full Bit8u bell = 7; DOS_WriteFile(STDOUT, &bell, &n); continue; } DOS_WriteFile(STDOUT,&c,&n); mem_writeb(data+read+2,c); if (c==13) break; read++; }; mem_writeb(data+1,read); break; }; case 0x0b: /* Get STDIN Status */ if (!DOS_GetSTDINStatus()) {reg_al=0x00;} else {reg_al=0xFF;} //Simulate some overhead for timing issues //Tankwar menu (needs maybe even more) overhead(); break; case 0x0c: /* Flush Buffer and read STDIN call */ { /* flush buffer if STDIN is CON */ Bit8u handle=RealHandle(STDIN); if (handle!=0xFF && Files[handle] && Files[handle]->IsName("CON")) { Bit8u c;Bit16u n; while (DOS_GetSTDINStatus()) { n=1; DOS_ReadFile(STDIN,&c,&n); } } switch (reg_al) { case 0x1: case 0x6: case 0x7: case 0x8: case 0xa: { Bit8u oldah=reg_ah; reg_ah=reg_al; DOS_21Handler(); reg_ah=oldah; } break; default: // LOG_ERROR("DOS:0C:Illegal Flush STDIN Buffer call %d",reg_al); reg_al=0; break; } } break; //TODO Find out the values for when reg_al!=0 //TODO Hope this doesn't do anything special case 0x0d: /* Disk Reset */ //Sure let's reset a virtual disk break; case 0x0e: /* Select Default Drive */ DOS_SetDefaultDrive(reg_dl); reg_al=DOS_DRIVES; break; case 0x0f: /* Open File using FCB */ if(DOS_FCBOpen(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x0f FCB-fileopen used, result:al=%d",reg_al); break; case 0x10: /* Close File using FCB */ if(DOS_FCBClose(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); break; case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); break; case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); break; case 0x13: /* Delete File using FCB */ if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x16 FCB-Delete used, result:al=%d",reg_al); break; case 0x14: /* Sequential read from FCB */ reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x14 FCB-Read used, result:al=%d",reg_al); break; case 0x15: /* Sequential write to FCB */ reg_al=DOS_FCBWrite(SegValue(ds),reg_dx,0); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; case 0x16: /* Create or truncate file using FCB */ if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x16 FCB-Create used, result:al=%d",reg_al); break; case 0x17: /* Rename file using FCB */ if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; break; case 0x1b: /* Get allocation info for default drive */ if (!DOS_GetAllocationInfo(0,®_cx,®_al,®_dx)) reg_al=0xff; break; case 0x1c: /* Get allocation info for specific drive */ if (!DOS_GetAllocationInfo(reg_dl,®_cx,®_al,®_dx)) reg_al=0xff; break; case 0x21: /* Read random record from FCB */ { Bit16u toread=1; reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,&toread,true); } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); break; case 0x22: /* Write random record to FCB */ { Bit16u towrite=1; reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,&towrite,true); } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x22 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ if (DOS_FCBGetFileSize(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; break; case 0x24: /* Set Random Record number for FCB */ DOS_FCBSetRandomRecord(SegValue(ds),reg_dx); break; case 0x27: /* Random block read from FCB */ reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,®_cx,false); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,®_cx,false); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ { Bit8u difference; char string[1024]; MEM_StrCopy(SegPhys(ds)+reg_si,string,1023); // 1024 toasts the stack reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); reg_si+=difference; } LOG(LOG_FCB,LOG_NORMAL)("DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; case 0x19: /* Get current default drive */ reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ dos.dta(RealMakeSeg(ds,reg_dx)); break; case 0x25: /* Set Interrupt Vector */ RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ DOS_NewPSP(reg_dx,DOS_PSP(dos.psp()).GetSize()); reg_al=0xf0; /* al destroyed */ break; case 0x2a: /* Get System Date */ { reg_ax=0; // get time CALLBACK_RunRealInt(0x1a); if(reg_al) DOS_AddDays(reg_al); int a = (14 - dos.date.month)/12; int y = dos.date.year - a; int m = dos.date.month + 12*a - 2; reg_al=(dos.date.day+y+(y/4)-(y/100)+(y/400)+(31*m)/12) % 7; reg_cx=dos.date.year; reg_dh=dos.date.month; reg_dl=dos.date.day; } break; case 0x2b: /* Set System Date */ if (reg_cx<1980) { reg_al=0xff;break;} if ((reg_dh>12) || (reg_dh==0)) { reg_al=0xff;break;} if (reg_dl==0) { reg_al=0xff;break;} if (reg_dl>DOS_DATE_months[reg_dh]) { if(!((reg_dh==2)&&(reg_cx%4 == 0)&&(reg_dl==29))) // february pass { reg_al=0xff;break; } } dos.date.year=reg_cx; dos.date.month=reg_dh; dos.date.day=reg_dl; reg_al=0; break; case 0x2c: { /* Get System Time */ reg_ax=0; // get time CALLBACK_RunRealInt(0x1a); if(reg_al) DOS_AddDays(reg_al); reg_ah=0x2c; Bitu ticks=((Bitu)reg_cx<<16)|reg_dx; if(time_start<=ticks) ticks-=time_start; Bitu time=(Bitu)((100.0/((double)PIT_TICK_RATE/65536.0)) * (double)ticks); reg_dl=(Bit8u)((Bitu)time % 100); // 1/100 seconds time/=100; reg_dh=(Bit8u)((Bitu)time % 60); // seconds time/=60; reg_cl=(Bit8u)((Bitu)time % 60); // minutes time/=60; reg_ch=(Bit8u)((Bitu)time % 24); // hours //Simulate DOS overhead for timing-sensitive games //Robomaze 2 overhead(); break; } case 0x2d: /* Set System Time */ LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported"); //Check input parameters nonetheless if( reg_ch > 23 || reg_cl > 59 || reg_dh > 59 || reg_dl > 99 ) reg_al = 0xff; else { //Allow time to be set to zero. Restore the orginal time for all other parameters. (QuickBasic) if (reg_cx == 0 && reg_dx == 0) {time_start = mem_readd(BIOS_TIMER);LOG_MSG("Warning: game messes with DOS time!");} else time_start = 0; reg_al = 0; } break; case 0x2e: /* Set Verify flag */ dos.verify=(reg_al==1); break; case 0x2f: /* Get Disk Transfer Area */ SegSet16(es,RealSeg(dos.dta())); reg_bx=RealOff(dos.dta()); break; case 0x30: /* Get DOS Version */ if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */ reg_al=dos.version.major; reg_ah=dos.version.minor; /* Serialnumber */ reg_bl=0x00; reg_cx=0x0000; break; case 0x31: /* Terminate and stay resident */ // Important: This service does not set the carry flag! DOS_ResizeMemory(dos.psp(),®_dx); DOS_Terminate(dos.psp(),true,reg_al); break; case 0x1f: /* Get drive parameter block for default drive */ case 0x32: /* Get drive parameter block for specific drive */ { /* Officially a dpb should be returned as well. The disk detection part is implemented */ Bit8u drive=reg_dl; if (!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive(); else drive--; if (Drives[drive]) { reg_al = 0x00; SegSet16(ds,dos.tables.dpb); reg_bx = drive;//Faking only the first entry (that is the driveletter) LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); } else { reg_al=0xff; } } break; case 0x33: /* Extended Break Checking */ switch (reg_al) { case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */ case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */ case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break; case 3: /* Get cpsw */ /* Fallthrough */ case 4: /* Set cpsw */ LOG(LOG_DOSMISC,LOG_ERROR)("Someone playing with cpsw %x",reg_ax); break; case 5:reg_dl=3;break;//TODO should be z /* Always boot from c: :) */ case 6: /* Get true version number */ reg_bl=dos.version.major; reg_bh=dos.version.minor; reg_dl=dos.version.revision; reg_dh=0x10; /* Dos in HMA */ break; default: LOG(LOG_DOSMISC,LOG_ERROR)("Weird 0x33 call %2X",reg_al); reg_al =0xff; break; } break; case 0x34: /* Get INDos Flag */ SegSet16(es,DOS_SDA_SEG); reg_bx=DOS_SDA_OFS + 0x01; break; case 0x35: /* Get interrupt vector */ reg_bx=real_readw(0,((Bit16u)reg_al)*4); SegSet16(es,real_readw(0,((Bit16u)reg_al)*4+2)); break; case 0x36: /* Get Free Disk Space */ { Bit16u bytes,clusters,free; Bit8u sectors; if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { reg_ax=sectors; reg_bx=free; reg_cx=bytes; reg_dx=clusters; } else { Bit8u drive=reg_dl; if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; if (drive<2) { // floppy drive, non-present drivesdisks issue floppy check through int24 // (critical error handler); needed for Mixed up Mother Goose (hook) // CALLBACK_RunRealInt(0x24); } reg_ax=0xffff; // invalid drive specified } } break; case 0x37: /* Get/Set Switch char Get/Set Availdev thing */ //TODO Give errors for these functions to see if anyone actually uses this shit- switch (reg_al) { case 0: reg_al=0;reg_dl=0x2f;break; /* always return '/' like dos 5.0+ */ case 1: reg_al=0;break; case 2: reg_al=0;reg_dl=0x2f;break; case 3: reg_al=0;break; }; LOG(LOG_MISC,LOG_ERROR)("DOS:0x37:Call for not supported switchchar"); break; case 0x38: /* Set Country Code */ if (reg_al==0) { /* Get country specidic information */ PhysPt dest = SegPhys(ds)+reg_dx; MEM_BlockWrite(dest,dos.tables.country,0x18); reg_ax = reg_bx = 0x01; CALLBACK_SCF(false); break; } else { /* Set country code */ LOG(LOG_MISC,LOG_ERROR)("DOS:Setting country code not supported"); } CALLBACK_SCF(true); break; case 0x39: /* MKDIR Create directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_MakeDir(name1)) { reg_ax=0x05; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x3a: /* RMDIR Remove directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_RemoveDir(name1)) { reg_ax=0x05; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); LOG(LOG_MISC,LOG_NORMAL)("Remove dir failed on %s with error %X",name1,dos.errorcode); } break; case 0x3b: /* CHDIR Set current directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_ChangeDir(name1)) { reg_ax=0x00; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x3c: /* CREATE Create of truncate file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_CreateFile(name1,reg_cx,®_ax)) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x3d: /* OPEN Open existing file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_OpenFile(name1,reg_al,®_ax)) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x3e: /* CLOSE Close file */ if (DOS_CloseFile(reg_bx)) { // reg_al=0x01; /* al destroyed. Refcount */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; dos.echo=true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } modify_cycles(reg_ax); dos.echo=false; break; } case 0x40: /* WRITE Write to file or device */ { Bit16u towrite=reg_cx; MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_ax=towrite; CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } modify_cycles(reg_ax); break; }; case 0x41: /* UNLINK Delete file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_UnlinkFile(name1)) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; case 0x42: /* LSEEK Set current file position */ { Bit32u pos=(reg_cx<<16) + reg_dx; if (DOS_SeekFile(reg_bx,&pos,reg_al)) { reg_dx=(Bit16u)(pos >> 16); reg_ax=(Bit16u)(pos & 0xFFFF); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); } break; }
void DOS_InfoBlock::SetLocation(Bit16u segment) { seg = segment; pt=PhysMake(seg,0); /* Clear the initial Block */ for(Bitu i=0;i<sizeof(sDIB);i++) mem_writeb(pt+i,0xff); for(Bitu i=0;i<14;i++) mem_writeb(pt+i,0); sSave(sDIB,regCXfrom5e,(Bit16u)0); sSave(sDIB,countLRUcache,(Bit16u)0); sSave(sDIB,countLRUopens,(Bit16u)0); sSave(sDIB,protFCBs,(Bit16u)0); sSave(sDIB,specialCodeSeg,(Bit16u)0); sSave(sDIB,joindedDrives,(Bit8u)0); sSave(sDIB,lastdrive,(Bit8u)0x01);//increase this if you add drives to cds-chain sSave(sDIB,diskInfoBuffer,RealMake(segment,offsetof(sDIB,diskBufferHeadPt))); sSave(sDIB,setverPtr,(Bit32u)0); sSave(sDIB,a20FixOfs,(Bit16u)0); sSave(sDIB,pspLastIfHMA,(Bit16u)0); sSave(sDIB,blockDevices,(Bit8u)0); sSave(sDIB,bootDrive,(Bit8u)0); sSave(sDIB,useDwordMov,(Bit8u)1); sSave(sDIB,extendedSize,(Bit16u)(MEM_TotalPages()*4-1024)); sSave(sDIB,magicWord,(Bit16u)0x0001); // dos5+ sSave(sDIB,sharingCount,(Bit16u)0); sSave(sDIB,sharingDelay,(Bit16u)0); sSave(sDIB,ptrCONinput,(Bit16u)0); // no unread input available sSave(sDIB,maxSectorLength,(Bit16u)0x200); sSave(sDIB,dirtyDiskBuffers,(Bit16u)0); sSave(sDIB,lookaheadBufPt,(Bit32u)0); sSave(sDIB,lookaheadBufNumber,(Bit16u)0); sSave(sDIB,bufferLocation,(Bit8u)0); // buffer in base memory, no workspace sSave(sDIB,workspaceBuffer,(Bit32u)0); sSave(sDIB,minMemForExec,(Bit16u)0); sSave(sDIB,memAllocScanStart,(Bit16u)DOS_MEM_START); sSave(sDIB,startOfUMBChain,(Bit16u)0xffff); sSave(sDIB,chainingUMB,(Bit8u)0); sSave(sDIB,nulNextDriver,(Bit32u)0xffffffff); sSave(sDIB,nulAttributes,(Bit16u)0x8004); sSave(sDIB,nulStrategy,(Bit32u)0x00000000); sSave(sDIB,nulString[0],(Bit8u)0x4e); sSave(sDIB,nulString[1],(Bit8u)0x55); sSave(sDIB,nulString[2],(Bit8u)0x4c); sSave(sDIB,nulString[3],(Bit8u)0x20); sSave(sDIB,nulString[4],(Bit8u)0x20); sSave(sDIB,nulString[5],(Bit8u)0x20); sSave(sDIB,nulString[6],(Bit8u)0x20); sSave(sDIB,nulString[7],(Bit8u)0x20); /* Create a fake SFT, so programs think there are 100 file handles */ Bit16u sftOffset=offsetof(sDIB,firstFileTable)+0xa2; sSave(sDIB,firstFileTable,RealMake(segment,sftOffset)); real_writed(segment,sftOffset+0x00,RealMake(segment+0x26,0)); //Next File Table real_writew(segment,sftOffset+0x04,100); //File Table supports 100 files real_writed(segment+0x26,0x00,0xffffffff); //Last File Table real_writew(segment+0x26,0x04,100); //File Table supports 100 files }
void DOS_SDA::Init() { /* Clear */ for(Bitu i=0;i<sizeof(sSDA);i++) mem_writeb(pt+i,0x00); sSave(sSDA,drive_crit_error,0xff); }
void DOS_FCB::SetResult(Bit32u size,Bit16u date,Bit16u time,Bit8u attr) { mem_writed(pt + 0x1d,size); mem_writew(pt + 0x19,date); mem_writew(pt + 0x17,time); mem_writeb(pt + 0x0c,attr); }
void DOS_FCB::SetAttr(Bit8u attr) { if(extended) mem_writeb(pt - 1,attr); }
bool INT10_VideoState_Restore(Bitu state,RealPt buffer) { Bitu ct; if ((state&7)==0) return false; Bit16u base_seg=RealSeg(buffer); Bit16u base_dest; if (state&1) { base_dest=real_readw(base_seg,RealOff(buffer)); Bit16u crt_reg=real_readw(base_seg,base_dest+0x40); // reprogram for full access to plane latches IO_WriteW(0x3c4,0x0704); IO_WriteW(0x3ce,0x0406); IO_WriteW(0x3ce,0x0005); IO_WriteW(0x3c4,0x0002); mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x42)); IO_WriteW(0x3c4,0x0102); mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x43)); IO_WriteW(0x3c4,0x0202); mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x44)); IO_WriteW(0x3c4,0x0402); mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x45)); IO_WriteW(0x3c4,0x0f02); mem_readb(0xaffff); IO_WriteW(0x3c4,0x0100); // sequencer for (ct=1; ct<5; ct++) { IO_WriteW(0x3c4,ct+(real_readb(base_seg,base_dest+0x04+ct)<<8)); } IO_WriteB(0x3c2,real_readb(base_seg,base_dest+0x09)); IO_WriteW(0x3c4,0x0300); IO_WriteW(crt_reg,0x0011); // crt controller for (ct=0; ct<0x19; ct++) { IO_WriteW(crt_reg,ct+(real_readb(base_seg,base_dest+0x0a+ct)<<8)); } IO_ReadB(crt_reg+6); // attr registers for (ct=0; ct<4; ct++) { IO_WriteB(0x3c0,0x10+ct); IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x33+ct)); } // graphics registers for (ct=0; ct<9; ct++) { IO_WriteW(0x3ce,ct+(real_readb(base_seg,base_dest+0x37+ct)<<8)); } IO_WriteB(crt_reg+6,real_readb(base_seg,base_dest+0x04)); IO_ReadB(crt_reg+6); // attr registers for (ct=0; ct<0x10; ct++) { IO_WriteB(0x3c0,ct); IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x23+ct)); } IO_WriteB(0x3c4,real_readb(base_seg,base_dest+0x00)); IO_WriteB(0x3d4,real_readb(base_seg,base_dest+0x01)); IO_WriteB(0x3ce,real_readb(base_seg,base_dest+0x02)); IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x03)); } if (state&2) { base_dest=real_readw(base_seg,RealOff(buffer)+2); mem_writeb(0x410,(mem_readb(0x410)&0xcf) | real_readb(base_seg,base_dest+0x00)); for (ct=0; ct<0x1e; ct++) { mem_writeb(0x449+ct,real_readb(base_seg,base_dest+0x01+ct)); } for (ct=0; ct<0x07; ct++) { mem_writeb(0x484+ct,real_readb(base_seg,base_dest+0x1f+ct)); } mem_writed(0x48a,real_readd(base_seg,base_dest+0x26)); mem_writed(0x14,real_readd(base_seg,base_dest+0x2a)); // int 5 mem_writed(0x74,real_readd(base_seg,base_dest+0x2e)); // int 1d mem_writed(0x7c,real_readd(base_seg,base_dest+0x32)); // int 1f mem_writed(0x10c,real_readd(base_seg,base_dest+0x36)); // int 43 } if (state&4) { base_dest=real_readw(base_seg,RealOff(buffer)+4); Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_WriteB(0x3c6,real_readb(base_seg,base_dest+0x002)); for (ct=0; ct<0x100; ct++) { IO_WriteB(0x3c8,ct); IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+0)); IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+1)); IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+2)); } IO_ReadB(crt_reg+6); IO_WriteB(0x3c0,0x14); IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x303)); Bitu dac_state=real_readb(base_seg,base_dest+0x000); if (dac_state==0) { IO_WriteB(0x3c8,real_readb(base_seg,base_dest+0x001)); } else { IO_WriteB(0x3c7,real_readb(base_seg,base_dest+0x001)); } } if ((svgaCard==SVGA_S3Trio) && (state&8)) { base_dest=real_readw(base_seg,RealOff(buffer)+6); Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); Bitu seq_idx=IO_ReadB(0x3c4); 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_WriteW(0x3c4,(0x09+ct)+(real_readb(base_seg,base_dest+0x00+ct)<<8)); } IO_WriteB(0x3c4,seq_idx); // Bitu crtc_idx=IO_ReadB(0x3d4); // 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); IO_WriteB(crt_reg,real_readb(base_seg,base_dest+(ct_dest++))); } else { IO_WriteW(crt_reg,(0x30+ct)+(real_readb(base_seg,base_dest+(ct_dest++))<<8)); } } // mmio /* IO_WriteB(crt_reg,0x40); Bitu sysval1=IO_ReadB(crt_reg+1); IO_WriteB(crt_reg+1,sysval|1); IO_WriteB(crt_reg,0x53); Bitu sysva2=IO_ReadB(crt_reg+1); IO_WriteB(crt_reg+1,sysval2|0x10); real_writew(0xa000,0x8128,0xffff); IO_WriteB(crt_reg,0x40); IO_WriteB(crt_reg,sysval1); IO_WriteB(crt_reg,0x53); IO_WriteB(crt_reg,sysval2); IO_WriteB(crt_reg,crtc_idx); */ } return true; }
void DOS_PSP::RestoreCommandTail() { mem_writeb(pt+offsetof(sPSP,cmdtail.count),strlen(storect)>0?strlen(storect)-1:0); MEM_BlockWrite(pt+offsetof(sPSP,cmdtail.buffer),storect,strlen(storect)); }
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 DOS_PSP::SetFileHandle(Bit16u index, Bit8u handle) { if (index<sGet(sPSP,max_files)) { PhysPt files=Real2Phys(sGet(sPSP,file_table)); mem_writeb(files+index,handle); } }