📄 x86interface.c
字号:
PRINTF("Trying to remove init data\n"); remove_init_data(); PRINTF("Removed init data from cache, now in RAM\n"); reloc_ops(reloc_addr); PRINTF("Attempting to run emulator on %02x:%02x:%02x\n", PCI_BUS(gr_dev), PCI_DEV(gr_dev), PCI_FUNC(gr_dev)); /* Enable compatibility hole for emulator access to frame buffer */ PRINTF("Enabling compatibility hole\n"); enable_compatibility_hole(); /* Allocate memory */ /* FIXME: We shouldn't use this much memory really. */ memset(&M, 0, sizeof(X86EMU_sysEnv)); M.mem_base = malloc(EMULATOR_MEM_SIZE); M.mem_size = EMULATOR_MEM_SIZE; if (!M.mem_base) { PRINTF("Unable to allocate one megabyte for emulator\n"); return 0; } if (attempt_map_rom(gr_dev, M.mem_base + EMULATOR_BIOS_OFFSET) == 0) { PRINTF("Error mapping rom. Emulation terminated\n"); return 0; }#if 1 /*def DEBUG*/ s = getenv("x86_ask_start"); if (s) { printf("Press 'q' to skip initialization, 'd' for dry init\n'i' for i/o session"); while (!tstc()); c = getc(); if (c == 'q') return 0; if (c == 'd') { extern void bios_set_mode(int mode); bios_set_mode(0x03); return 0; } if (c == 'i') do_inout(); }#endif#ifdef EASTEREGG/* if (tstc()) { if (getc() == 'c') { easteregg_active = 1; } }*/ if (getenv("easteregg")) { easteregg_active = 1; } if (easteregg_active) { /* Yay! */ setenv("x86_mode", "1"); setenv("vga_fg_color", "11"); setenv("vga_bg_color", "1"); easteregg_active = 1; }#endif strap = (u8*)M.mem_base + EMULATOR_STRAP_OFFSET; { char *m = getenv("x86_mode"); if (m) { more_strap[3] = atoi(m); if (more_strap[3] == 1) video_size(40, 25); else video_size(80, 25); } } /* * Poke the strap routine. This might need a bit of extending * if there is a mode switch involved, i.e. we want to int10 * afterwards to set a different graphics mode, or alternatively * there might be a different start address requirement if the * ROM doesn't have an x86 image in its first image. */ PRINTF("Poking strap...\n"); /* FAR CALL c000:0003 */ *strap++ = 0x9A; *strap++ = 0x03; *strap++ = 0x00; *strap++ = 0x00; *strap++ = 0xC0;#if 1 /* insert additional strap code */ for (i=0; i < MORE_STRAP_BYTES; i++) { *strap++ = more_strap[i]; }#endif /* HALT */ *strap++ = 0xF4; PRINTF("Setting up logo data\n"); logo = (unsigned char *)M.mem_base + EMULATOR_LOGO_OFFSET; for (i=0; i<16; i++) { *logo++ = 0xFF; } /* * Setup the init parameters. * Per PCI specs, AH must contain the bus and AL * must contain the devfn, encoded as (dev<<3)|fn */ /* Execution starts here */ M.x86.R_CS = SEG(EMULATOR_STRAP_OFFSET); M.x86.R_IP = OFF(EMULATOR_STRAP_OFFSET); /* Stack at top of ram */ M.x86.R_SS = SEG(EMULATOR_STACK_OFFSET); M.x86.R_SP = OFF(EMULATOR_STACK_OFFSET); /* Input parameters */ M.x86.R_AH = PCI_BUS(gr_dev); M.x86.R_AL = (PCI_DEV(gr_dev)<<3) | PCI_FUNC(gr_dev); /* Set the I/O and memory access functions */ X86EMU_setupMemFuncs(&_A1_mem); X86EMU_setupPioFuncs(&_A1_pio); /* Enable timer 2 */ cfg = in_byte(0x61); /* Get Misc control */ cfg |= 0x01; /* Enable timer 2 */ out_byte(0x61, cfg); /* output again */ /* Set up the timers */ out_byte(0x43, 0x54); out_byte(0x41, 0x18); out_byte(0x43, 0x36); out_byte(0x40, 0x00); out_byte(0x40, 0x00); out_byte(0x43, 0xb6); out_byte(0x42, 0x31); out_byte(0x42, 0x13); /* Init the "BIOS". */ bios_init(); /* Video Card Reset */ out_byte(0x3D8, 0); out_byte(0x3B8, 1); (void)in_byte(0x3BA); (void)in_byte(0x3DA); out_byte(0x3C0, 0); out_byte(0x61, 0xFC);#ifdef DEBUG s = _getenv("x86_singlestep"); if (s && strcmp(s, "on")==0) { PRINTF("Enabling single stepping for debug\n"); X86EMU_trace_on(); }#endif /* Ready set go... */ PRINTF("Running emulator\n"); X86EMU_exec(); PRINTF("Done running emulator\n");/* FIXME: Remove me */ pal_reset = getenv("x86_palette_reset"); if (pal_reset && strcmp(pal_reset, "on") == 0) { PRINTF("Palette reset\n"); /*(void)in_byte(0x3da); */ /*out_byte(0x3c0, 0); */ out_byte(0x3C8, 0); out_byte(0x3C9, 0); out_byte(0x3C9, 0); out_byte(0x3C9, 0); for (i=0; i<254; i++) { out_byte(0x3C9, 63); out_byte(0x3C9, 63); out_byte(0x3C9, 63); } out_byte(0x3c0, 0x20); }/* FIXME: remove me */#ifdef EASTEREGG if (easteregg_active) { extern void video_easteregg(void); video_easteregg(); }#endif/* current_attr = video_get_attr(); fb = (u8 *)VIDEO_BASE; for (i=0; i<video_rows()*video_cols()*2; i+=2) { *(fb+i) = ' '; *(fb+i+1) = current_attr; } fb = (u8 *)VIDEO_BASE + (video_rows())-1*(video_cols()*2); for (i=0; i<video_cols(); i++) { *(fb + 2*i) = 32; *(fb + 2*i + 1) = 0x17; } msg = done_msg; while (*msg) { *fb = *msg; fb += 2; msg ++; }*/#ifdef DEBUG if (getenv("x86_do_inout")) do_inout();#endif/*FIXME: dcache_disable(); */ return 1;}/* Clean up the x86 mess */void shutdown_bios(void){/* disable_compatibility_hole(); */ /* Free the memory associated */ free(M.mem_base);}int to_int(char *buffer){ int base = 0; int res = 0; if (*buffer == '$') { base = 16; buffer++; } else base = 10; for (;;) { switch(*buffer) { case '0' ... '9': res *= base; res += *buffer - '0'; break; case 'A': case 'a': res *= base; res += 10; break; case 'B': case 'b': res *= base; res += 11; break; case 'C': case 'c': res *= base; res += 12; break; case 'D': case 'd': res *= base; res += 13; break; case 'E': case 'e': res *= base; res += 14; break; case 'F': case 'f': res *= base; res += 15; break; default: return res; } buffer++; } return res;}void one_arg(char *buffer, int *a){ while (*buffer && *buffer != '\n') { if (*buffer == ' ') buffer++; else break; } *a = to_int(buffer);}void two_args(char *buffer, int *a, int *b){ while (*buffer && *buffer != '\n') { if (*buffer == ' ') buffer++; else break; } *a = to_int(buffer); while (*buffer && *buffer != '\n') { if (*buffer != ' ') buffer++; else break; } while (*buffer && *buffer != '\n') { if (*buffer == ' ') buffer++; else break; } *b = to_int(buffer);}void do_inout(void){ char buffer[256]; char *arg1, *arg2; int a,b; printf("In/Out Session\nUse 'i[bwl]' for in, 'o[bwl]' for out and 'q' to quit\n"); do { cons_gets(buffer); printf("\n"); *arg1 = buffer; while (*arg1 != ' ' ) arg1++; while (*arg1 == ' ') arg1++; if (buffer[0] == 'i') { one_arg(buffer+2, &a); switch (buffer[1]) { case 'b': printf("in_byte(%xh) = %xh\n", a, A1_inb(a)); break; case 'w': printf("in_word(%xh) = %xh\n", a, A1_inw(a)); break; case 'l': printf("in_dword(%xh) = %xh\n", a, A1_inl(a)); break; default: printf("Invalid length '%c'\n", buffer[1]); break; } } else if (buffer[0] == 'o') { two_args(buffer+2, &a, &b); switch (buffer[1]) { case 'b': printf("out_byte(%d, %d)\n", a, b); A1_outb(a,b); break; case 'w': printf("out_word(%d, %d)\n", a, b); A1_outw(a, b); break; case 'l': printf("out_long(%d, %d)\n", a, b); A1_outl(a, b); break; default: printf("Invalid length '%c'\n", buffer[1]); break; } } else if (buffer[0] == 'q') return; } while (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -