/* This is file CONTROL.C */ /* ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954 ** ** This file is distributed under the terms listed in the document ** "copying.dj", available from DJ Delorie at the address above. ** A copy of "copying.dj" should accompany this file; if not, a copy ** should be available from where this file was obtained. This file ** may not be distributed without a verbatim copy of "copying.dj". ** ** This file is distributed WITHOUT ANY WARRANTY; without even the implied ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* History:87,1 */ #include #include #include #include #include #include #include "build.h" #include "types.h" #include "gdt.h" #include "idt.h" #include "tss.h" #include "valloc.h" #include "utils.h" #include "syms.h" #include "graphics.h" #include "mono.h" TSS *tss_ptr; int debug_mode = 0; int self_contained; long header_offset = 0; int use_ansi=0; int use_mono=0; static int old_video_mode; extern near go32(); extern near go_real_mode(); extern int was_exception; extern near ivec0(), ivec1(), ivec7(), ivec75(); extern near interrupt_common(), page_fault(); extern near test(); extern word32 far *pd; fillgdt(int sel, word32 limit, word32 base, word8 type, int G) { GDT_S *g; g = gdt+sel; if (G & 2) limit = limit >> 12; g->lim0 = limit & 0xffff; g->lim1 = (limit>>16) & 0x0f; g->base0 = base & 0xffff; g->base1 = (base>>16) & 0xff; g->base2 = (base>>24) & 0xff; g->stype = type; g->lim1 |= G * 0x40; } word32 ptr2linear(void far *ptr) { return (word32)FP_SEG(ptr) * 16L + (word32)FP_OFF(ptr); } setup_tss(TSS *t, int (*eip)()) { memset(t, 0, sizeof(TSS)); t->tss_cs = g_rcode*8; t->tss_eip = (long)FP_OFF(eip); t->tss_ss = g_rdata*8; t->tss_esp = (long)FP_OFF(t->tss_stack); t->tss_ds = g_rdata*8; t->tss_es = g_rdata*8; t->tss_fs = g_rdata*8; t->tss_gs = g_rdata*8; t->tss_eflags = 0x0200; t->tss_iomap = 0xffff; /* no map */ } exit_func() { int i; dalloc_uninit(); uninit_controllers(); xms_free(); #if TOPLINEINFO for (i=0; i<80; i++) poke(screen_seg, i*2, 0x0720); #endif } int ctrl_c_flag = 0; ctrlbrk_func() { #if DEBUGGER ctrl_c_flag = 1; #else exit(3); #endif } usage(char *s) { printf("Usage: %s [program [options . . . ]]\n", s); _exit(1); } int have_80387; static word32 push32(void *ptr, int len); main(int argc, char **argv, char **envp) { int i, n, set_brk=0, emu_installed=0; struct stat stbuf; char *cp, *path, *argv0, *emu_fn=0; unsigned short header[3]; old_video_mode = peekb(0x40, 0x49); if (strcmp(argv[1], "!proxy") == 0) { int oseg, optr, i; int far *oargv; char far *oargve; sscanf(argv[2], "%x", &argc); sscanf(argv[3], "%x", &oseg); sscanf(argv[4], "%x", &optr); oargv = MK_FP(oseg, optr); argv = (char **)malloc(sizeof(char *) * (argc+1)); for (i=0; itss_irqn == 0x79) fprintf(stderr, "Ctrl-C Hit! Stopped at address %lx\n", tss_ptr->tss_eip); else fprintf(stderr, "Exception %d at eip=%lx\n", tss_ptr->tss_irqn, tss_ptr->tss_eip); return 1; #endif } #if !DEBUGGER gdtprint(i) { printf("0x%02x: base=%02x%02x%04x lim=%02x%04x G=%d type=%02x\n", i*8, gdt[i].base2, gdt[i].base1, gdt[i].base0, gdt[i].lim1&0x0f, gdt[i].lim0, gdt[i].lim1>>6, gdt[i].stype); } #endif static word32 push32(void *ptr, int len) { if ((a_tss.tss_esp & ~0xFFF) != ((a_tss.tss_esp-len) & ~0xFFF)) { a_tss.tss_cr2 = a_tss.tss_esp - len + ARENA; page_in(); } a_tss.tss_esp -= len; a_tss.tss_esp = a_tss.tss_esp & (~3); memput(a_tss.tss_esp+ARENA, ptr, len); return a_tss.tss_esp; } static foreach_arg(char **argv, int (*func)()) { int i; FILE *f; char buf[80]; for (i=0; argv[i]; i++) { if (argv[i][0] == '@') { f = fopen(argv[i]+1, "rt"); while (fscanf(f, "%s", buf) == 1) { if (strcmp(buf, "\032") != 0) func(buf); } fclose(f); } else func(argv[i]); } } static int num_actual_args; static just_incr() { num_actual_args++; } static word32 *a; pusharg(char *ar) { a[num_actual_args] = push32(ar, strlen(ar)+1); num_actual_args++; } set_command_line(char **argv, char **envv) { unsigned envc; word32 *e, v, argp, envp; a_tss.tss_cr2 = a_tss.tss_esp + ARENA; page_in(); num_actual_args = 0; foreach_arg(argv, just_incr); for (envc=0; envv[envc]; envc++); e = (word32 *)malloc((envc+1)*sizeof(word32)); if (e == 0) { printf("Fatal! no memory to copy environment\n"); exit(1); } for (envc=0; envv[envc]; envc++) { v = push32(envv[envc], strlen(envv[envc])+1); e[envc] = v; } e[envc] = 0; a = (word32 *)malloc((num_actual_args+1)*sizeof(word32)); if (e == 0) { printf("Fatal! no memory to copy arguments\n"); exit(1); } num_actual_args = 0; foreach_arg(argv, pusharg); a[num_actual_args] = 0; envp = push32(e, (envc+1)*sizeof(word32)); argp = push32(a, (num_actual_args+1)*sizeof(word32)); push32(&envp, sizeof(word32)); push32(&argp, sizeof(word32)); v = num_actual_args; push32(&v, sizeof(word32)); }