📄 v86bios.c
字号:
fprintf(stderr,"Cannot read\n"); goto Error; } free(tmp); close(mem_fd); if (!chksum((CARD8*)v_base)) return (0); return (1);Error: perror("v_bios"); close(mem_fd); return (0);}static intcopy_sys_bios(void){#define SYS_BIOS 0xF0000 int mem_fd; if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) { perror("opening memory"); return (0); } if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS) goto Error; if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF) goto Error; close(mem_fd); return (1);Error: perror("sys_bios"); close(mem_fd); return (0);}voidloadCodeToMem(unsigned char *ptr, CARD8 code[]){ int i; CARD8 val; int size = code[0]; for ( i=1;i<=size;i++) { val = code[i]; *ptr++ = val; } return;}voiddprint(unsigned long start, unsigned long size){ int i,j; char *c = (char *)start; for (j = 0; j < (size >> 4); j++) { char *d = c; printf("\n0x%lx: ",(unsigned long)c); for (i = 0; i<16; i++) printf("%2.2x ",(unsigned char) (*(c++))); c = d; for (i = 0; i<16; i++) { printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ? (unsigned char) (*(c)): '.'); c++; } } printf("\n");}static voidsave_bios_to_file(void){ static int num = 0; int size, count; char file_name[256]; int fd; sprintf(file_name,"bios_%i.fil",num); if ((fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1) return; size = (*(unsigned char*)(V_BIOS + 2)) * 512;#ifdef V86BIOS_DEBUG dprint(V_BIOS,20);#endif if ((count = write(fd,(void *)(V_BIOS),size)) != size) fprintf(stderr,"only saved %i of %i bytes\n",size,count); num++;}static voidsig_handler(int unused){ fflush(stdout); fflush(stderr); /* put system back in a save state */ unmap_vram(); pciVideoRestore(); outb(0x102, save_pos102); outb(0x46e8, save_46e8); outb(0x3C3, save_vse); outb(0x3C2, save_msr); close_console(Console); iopl(0); unmap(); exit(1);}/* * For initialization we just pass ax to the BIOS. * PCI BIOSes need this. All other register are set 0. */static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax){ regs->ax = ax; regs->bx = 0; regs->cx = 0; regs->dx = 0; regs->es = 0; regs->ds = 0x40; /* standard pc ds */ regs->si = 0; regs->di = 0;}/* * here we are really paranoid about faking a "real" * BIOS. Most of this information was pulled from * dosem. */#ifdef __ia32__static CARD32setup_primary_int_vect(void){ int mem_fd; CARD32 vbase; void *map; if ((mem_fd = open(MEM_FILE,O_RDWR))<0) { perror("opening memory"); return (0); } if ((map = mmap((void *) 0, (size_t) 0x2000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0)) == (void *)-1) { perror("mmap error in map_hardware_ram (2)"); close(mem_fd); return (0); } close(mem_fd); memcpy(0,map,BIOS_MEM); munmap(map,0x2000); /* * create a backup copy of the bios variables to write back the * modified values */ if (!bios_var) bios_var = (char *)malloc(BIOS_MEM); memcpy(bios_var,0,BIOS_MEM); vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4; if (Config.Verbose > 0) printf("vbase: 0x%x\n",vbase); return vbase;}#endifstatic CARD32setup_int_vect(void){ const CARD16 cs = 0x0; const CARD16 ip = 0x0; int i; /* let the int vects point to the SYS_BIOS seg */ for (i=0; i<0x80; i++) { ((CARD16*)0)[i<<1] = ip; ((CARD16*)0)[(i<<1)+1] = cs; } /* video interrupts default location */ ((CARD16*)0)[(0x42<<1)+1] = 0xf000; ((CARD16*)0)[0x42<<1] = 0xf065; ((CARD16*)0)[(0x10<<1)+1] = 0xf000; ((CARD16*)0)[0x10<<1] = 0xf065; /* video param table default location (int 1d) */ ((CARD16*)0)[(0x1d<<1)+1] = 0xf000; ((CARD16*)0)[0x1d<<1] = 0xf0A4; /* font tables default location (int 1F) */ ((CARD16*)0)[(0x1f<<1)+1] = 0xf000; ((CARD16*)0)[0x1f<<1] = 0xfa6e; /* int 11 default location */ ((CARD16*)0)[(0x11<<1)+1] = 0xf000; ((CARD16*)0)[0x11<<1] = 0xf84d; /* int 12 default location */ ((CARD16*)0)[(0x12<<1)+1] = 0xf000; ((CARD16*)0)[0x12<<1] = 0xf841; /* int 15 default location */ ((CARD16*)0)[(0x15<<1)+1] = 0xf000; ((CARD16*)0)[0x15<<1] = 0xf859; /* int 1A default location */ ((CARD16*)0)[(0x1a<<1)+1] = 0xf000; ((CARD16*)0)[0x1a<<1] = 0xff6e; /* int 05 default location */ ((CARD16*)0)[(0x05<<1)+1] = 0xf000; ((CARD16*)0)[0x05<<1] = 0xff54; /* int 08 default location */ ((CARD16*)0)[(0x8<<1)+1] = 0xf000; ((CARD16*)0)[0x8<<1] = 0xfea5; /* int 13 default location (fdd) */ ((CARD16*)0)[(0x13<<1)+1] = 0xf000; ((CARD16*)0)[0x13<<1] = 0xec59; /* int 0E default location */ ((CARD16*)0)[(0xe<<1)+1] = 0xf000; ((CARD16*)0)[0xe<<1] = 0xef57; /* int 17 default location */ ((CARD16*)0)[(0x17<<1)+1] = 0xf000; ((CARD16*)0)[0x17<<1] = 0xefd2; /* fdd table default location (int 1e) */ ((CARD16*)0)[(0x1e<<1)+1] = 0xf000; ((CARD16*)0)[0x1e<<1] = 0xefc7; return V_BIOS;}static intsetup_system_bios(void){ char *date = "06/01/99"; char *eisa_ident = "PCI/ISA"; if (Config.MapSysBios) { if (!copy_sys_bios()) return 0; return 1; } else {/* memset((void *)0xF0000,0xf4,0xfff7); */ /* * we trap the "industry standard entry points" to the BIOS * and all other locations by filling them with "hlt" * TODO: implement hlt-handler for these */ memset((void *)0xF0000,0xf4,0x10000); /* * TODO: we should copy the fdd table (0xfec59-0xfec5b) * the video parameter table (0xf0ac-0xf0fb) * and the font tables (0xfa6e-0xfe6d) * from the original bios here */ /* set bios date */ strcpy((char *)0xFFFF5,date); /* set up eisa ident string */ strcpy((char *)0xFFFD9,eisa_ident); /* write system model id for IBM-AT */ ((char *)0)[0xFFFFE] = 0xfc; return 1; }}static voidupdate_bios_vars(void){ int mem_fd; void *map; memType i;#ifdef __ia64__ if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)#else if ((mem_fd = open(MEM_FILE,O_RDWR))<0)#endif { perror("opening memory"); return; } if ((map = mmap((void *) 0, (size_t) 0x2000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0)) == (void *)-1) { perror("mmap error in map_hardware_ram (3)"); close(mem_fd); return; } for (i = 0; i < BIOS_MEM; i++) { if (bios_var[i] != *(CARD8*)i) *((CARD8*)map + i) = *(CARD8*)i; } munmap(map,0x2000); close(mem_fd);}static intchksum(CARD8 *start){ CARD16 size; CARD8 val = 0; int i; size = *(start+2) * 512; for (i = 0; i<size; i++) val += *(start + i); if (!val) return 1; fprintf(stderr,"BIOS cksum wrong!\n"); return 0;}voidrunINT(int num, i86biosRegsPtr Regs){ Bool isVideo = FALSE; CARD8 code_int[] = { 3, 0xcd, 0x00, 0xf4 }; code_int[2] = (CARD8) num; if (num == 0x10) isVideo = TRUE; if (!setup_system_bios()) return; if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo) { CARD32 vbios_base;#ifdef __ia32__ if (!(vbios_base = setup_primary_int_vect()))#else if (!(vbios_base = setup_int_vect()))#endif return; if (!copy_vbios(vbios_base)) return; } if (!map_vram()) return;#ifdef V86BIOS_DEBUG printf("starting BIOS\n");#endif loadCodeToMem((unsigned char *) BIOS_START, code_int); setup_io(); print_regs(Regs); set_ioperm(); set_hlt(TRUE); do_x86(BIOS_START,Regs); set_hlt(FALSE); print_regs(Regs);#ifdef V86BIOS_DEBUG printf("done\n");#endif if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo) update_bios_vars();}static voidprint_regs(i86biosRegsPtr regs){ printf("ax=%x bx=%x cx=%x dx=%x ds=%x es=%x di=%x si=%x\n", (CARD16)regs->ax,(CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx, (CARD16)regs->ds,(CARD16)regs->es,(CARD16)regs->di, (CARD16)regs->si);}static voidprint_usage(void){}voidadd_hlt(unsigned long val){ int i; if (val < BIOS_MEM || (val > VRAM_START && val < (VRAM_START + VRAM_SIZE)) || val >= SIZE) { printf("address out of range\n"); return; } for (i=0; i<20; i++) { if (hltp[i].address == 0) { hltp[i].address = (void*)val; break; } } if (i == 20) printf("no more hltpoints available\n");}voiddel_hlt(int val){ if (val == 21) { /* delete all */ int i; printf("clearing all hltpoints\n"); for (i=0; i <20; i++) hltp[i].address = NULL; } else if (val >= 0 && val <20) hltp[val].address = NULL; else printf("hltpoint %i out of range: valid range 0-19\n",val);}voidlist_hlt(){ int i; for (i=0; i<20; i++) if (hltp[i].address) printf("hltpoint[%i]: 0x%lx\n",i,(unsigned long)hltp[i].address);}static voidset_hlt(Bool set){ int i; for (i=0; i<20; i++) if (hltp[i].address) { if (set) { hltp[i].orgval = *(CARD8*)hltp[i].address; *(CARD8*)hltp[i].address = 0xf4; } else *(CARD8*)hltp[i].address = hltp[i].orgval; }}static voidset_ioperm(void){ int i, start; ioperm(0,IOPERM_BITS,0); for (i = 0; i < IOPERM_BITS;i++) if (ioperm_list[i]) { start = i; for (;i < IOPERM_BITS; i++) { if (!ioperm_list[i]) { ioperm(start,i - start, 1); break; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -