/*
 * 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 <sys/mman.h>
#include <signal.h>
#include <malloc.h>

#include "cpu.h"

//#define SIGTEST

void cpu_outb(CPUState *env, int addr, int val)
{
    fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
}

void cpu_outw(CPUState *env, int addr, int val)
{
    fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
}

void cpu_outl(CPUState *env, int addr, int val)
{
    fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
}

int cpu_inb(CPUState *env, int addr)
{
    fprintf(stderr, "inb: port=0x%04x\n", addr);
    return 0;
}

int cpu_inw(CPUState *env, int addr)
{
    fprintf(stderr, "inw: port=0x%04x\n", addr);
    return 0;
}

int cpu_inl(CPUState *env, int addr)
{
    fprintf(stderr, "inl: port=0x%04x\n", addr);
    return 0;
}

int cpu_get_pic_interrupt(CPUState *env)
{
    return -1;
}

uint64_t cpu_get_tsc(CPUState *env)
{
    return 0;
}

static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
                     unsigned long addr, unsigned int sel)
{
    unsigned int e1, e2;
    e1 = (addr & 0xffff) | (sel << 16);
    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
    stl((uint8_t *)ptr, e1);
    stl((uint8_t *)ptr + 4, e2);
}

uint64_t idt_table[256];

/* only dpl matters as we do only user space emulation */
static void set_idt(int n, unsigned int dpl)
{
    set_gate(idt_table + n, 0, dpl, 0, 0);
}

void qemu_free(void *ptr)
{
    free(ptr);
}

void *qemu_malloc(size_t size)
{
    return malloc(size);
}

void *qemu_mallocz(size_t size)
{
    void *ptr;
    ptr = qemu_malloc(size);
    if (!ptr)
        return NULL;
    memset(ptr, 0, size);
    return ptr;
}

void *qemu_vmalloc(size_t size)
{
    return memalign(4096, size);
}

void qemu_vfree(void *ptr)
{
    free(ptr);
}

void qemu_printf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
}

/* 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);
}

static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
{
    return (uint8_t *)((seg << 4) + (reg & 0xffff));
}

static inline void pushw(CPUState *env, int val)
{
    env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | ((env->regs[R_ESP] - 2) & 0xffff);
    *(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val;
}

static void host_segv_handler(int host_signum, siginfo_t *info,
                              void *puc)
{
    if (cpu_signal_handler(host_signum, info, puc)) {
        return;
    }
    abort();
}

int main(int argc, char **argv)
{
    uint8_t *vm86_mem;
    const char *filename;
    int fd, ret, seg;
    CPUState *env;

    if (argc != 2)
        usage();
    filename = argv[1];

    vm86_mem = mmap((void *)0x00000000, 0x110000,
                    PROT_WRITE | PROT_READ | PROT_EXEC,
                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
    if (vm86_mem == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }

    /* load the MSDOS .com executable */
    fd = open(filename, O_RDONLY);
    if (fd < 0) {
        perror(filename);
        exit(1);
    }
    ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
    if (ret < 0) {
        perror("read");
        exit(1);
    }
    close(fd);

    /* install exception handler for CPU emulator */
    {
        struct sigaction act;

        sigfillset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO;
        //        act.sa_flags |= SA_ONSTACK;

        act.sa_sigaction = host_segv_handler;
        sigaction(SIGSEGV, &act, NULL);
        sigaction(SIGBUS, &act, NULL);
    }

    //    cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);

    env = cpu_init("qemu32");

    cpu_x86_set_cpl(env, 3);

    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
    /* NOTE: hflags duplicates some of the virtual CPU state */
    env->hflags |= HF_PE_MASK | VM_MASK;

    /* flags setup : we activate the IRQs by default as in user
       mode. We also activate the VM86 flag to run DOS code */
    env->eflags |= IF_MASK | VM_MASK;

    /* init basic registers */
    env->eip = 0x100;
    env->regs[R_ESP] = 0xfffe;
    seg = (COM_BASE_ADDR - 0x100) >> 4;

    cpu_x86_load_seg_cache(env, R_CS, seg,
                           (seg << 4), 0xffff, 0);
    cpu_x86_load_seg_cache(env, R_SS, seg,
                           (seg << 4), 0xffff, 0);
    cpu_x86_load_seg_cache(env, R_DS, seg,
                           (seg << 4), 0xffff, 0);
    cpu_x86_load_seg_cache(env, R_ES, seg,
                           (seg << 4), 0xffff, 0);
    cpu_x86_load_seg_cache(env, R_FS, seg,
                           (seg << 4), 0xffff, 0);
    cpu_x86_load_seg_cache(env, R_GS, seg,
                           (seg << 4), 0xffff, 0);

    /* exception support */
    env->idt.base = (unsigned long)idt_table;
    env->idt.limit = sizeof(idt_table) - 1;
    set_idt(0, 0);
    set_idt(1, 0);
    set_idt(2, 0);
    set_idt(3, 3);
    set_idt(4, 3);
    set_idt(5, 3);
    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 */
    *seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */
    *seg_to_linear(env->segs[R_CS].selector, 1) = 0x00;
    *seg_to_linear(env->segs[R_CS].selector, 2) = 0xcd; /* int $0x21 */
    *seg_to_linear(env->segs[R_CS].selector, 3) = 0x21;
    pushw(env, 0x0000);

    /* the value of these registers seem to be assumed by pi_10.com */
    env->regs[R_ESI] = 0x100;
    env->regs[R_ECX] = 0xff;
    env->regs[R_EBP] = 0x0900;
    env->regs[R_EDI] = 0xfffe;

    /* inform the emulator of the mmaped memory */
    page_set_flags(0x00000000, 0x110000,
                   PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);

    for(;;) {
        ret = cpu_x86_exec(env);
        switch(ret) {
        case EXCP0D_GPF:
            {
                int int_num, ah;
                int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
                if (int_num != 0x21)
                    goto unknown_int;
                ah = (env->regs[R_EAX] >> 8) & 0xff;
                switch(ah) {
                case 0x00: /* exit */
                    exit(0);
                case 0x02: /* write char */
                    {
                        uint8_t c = env->regs[R_EDX];
                        write(1, &c, 1);
                    }
                    break;
                case 0x09: /* write string */
                    {
                        uint8_t c;
                        for(;;) {
                            c = *seg_to_linear(env->segs[R_DS].selector, env->regs[R_EAX]);
                            if (c == '$')
                                break;
                            write(1, &c, 1);
                        }
                        env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | '$';
                    }
                    break;
                default:
                unknown_int:
                    fprintf(stderr, "unsupported int 0x%02x\n", int_num);
                    cpu_dump_state(env, stderr, fprintf, 0);
                    //                    exit(1);
                }
                env->eip += 2;
            }
            break;
        default:
            fprintf(stderr, "unhandled cpu_exec return code (0x%x)\n", ret);
            cpu_dump_state(env, stderr, fprintf, 0);
            exit(1);
        }
    }
}
