x86interface.c
来自「适合KS8695X」· C语言 代码 · 共 815 行 · 第 1/2 页
C
815 行
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 + =
减小字号Ctrl + -
显示快捷键?