qruncom.c revision dc596afcb55b186049993a53a06fd9eba8eb025c
/*
* Example of use of user mode libqemu: launch a basic .com DOS
* executable
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <malloc.h>
#include "cpu.h"
//#define SIGTEST
{
}
{
}
{
}
{
return 0;
}
{
return 0;
}
{
return 0;
}
{
return -1;
}
{
return 0;
}
{
}
/* only dpl matters as we do only user space emulation */
{
}
{
}
{
}
{
void *ptr;
if (!ptr)
return NULL;
return ptr;
}
{
}
void qemu_vfree(void *ptr)
{
}
void qemu_printf(const char *fmt, ...)
{
}
/* XXX: this is a bug in helper2.c */
int errno;
/**********************************************/
#define COM_BASE_ADDR 0x10100
void usage(void)
{
printf("qruncom version 0.1 (c) 2003 Fabrice Bellard\n"
"usage: qruncom file.com\n"
"user mode libqemu demo: run simple .com DOS executables\n");
exit(1);
}
{
}
{
}
void *puc)
{
return;
}
abort();
}
{
const char *filename;
if (argc != 2)
usage();
if (vm86_mem == MAP_FAILED) {
perror("mmap");
exit(1);
}
/* load the MSDOS .com executable */
if (fd < 0) {
exit(1);
}
if (ret < 0) {
perror("read");
exit(1);
}
/* install exception handler for CPU emulator */
{
// act.sa_flags |= SA_ONSTACK;
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
#endif
}
// cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);
/* disable code copy to simplify debugging */
code_copy_enabled = 0;
/* set user mode state (XXX: should be done automatically by
cpu_init ?) */
/* NOTE: hflags duplicates some of the virtual CPU state */
/* flags setup : we activate the IRQs by default as in user
mode. We also activate the VM86 flag to run DOS code */
/* init basic registers */
/* exception support */
set_idt(0, 0);
set_idt(1, 0);
set_idt(2, 0);
set_idt(6, 0);
set_idt(7, 0);
set_idt(8, 0);
set_idt(9, 0);
set_idt(10, 0);
set_idt(11, 0);
set_idt(12, 0);
set_idt(13, 0);
set_idt(14, 0);
set_idt(15, 0);
set_idt(16, 0);
set_idt(17, 0);
set_idt(18, 0);
set_idt(19, 0);
/* put return code */
/* the value of these registers seem to be assumed by pi_10.com */
/* inform the emulator of the mmaped memory */
for(;;) {
switch(ret) {
case EXCP0D_GPF:
{
if (int_num != 0x21)
goto unknown_int;
switch(ah) {
case 0x00: /* exit */
exit(0);
case 0x02: /* write char */
{
}
break;
case 0x09: /* write string */
{
uint8_t c;
for(;;) {
if (c == '$')
break;
}
}
break;
default:
// exit(1);
}
}
break;
default:
exit(1);
}
}
}