/***************************************************************************** * FILE: rsx.c * * * * DESC: * * - get rsx options * * - switch protected mode (16bit) * * - init protected mode * * - check copro, install emu * * - load first a.out prg * * * * Copyright (C) 1993,1994 * * Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld * * email: rainer@mathematik.uni-bielefeld.de * * * *****************************************************************************/ #include #include #include #include "DPMI.H" #include "PRINTF.H" #include "PROCESS.H" #include "START32.H" #include "LOADPRG.H" #include "FPU.H" #include "RSX.H" #include "DOSERRNO.H" #include "RMLIB.H" #include "COPY32.H" #include "SYSDEP.H" #include "DJIO.H" #include "VERSION.H" /* command-line options */ char copro = 1; /* prg need 387 : 0=no 1=yes 3=emulate */ char opt_memaccess = 0; /* allows memaccess */ char opt_stack = 0; /* stack: expand down or data segment */ char rsx387_in_dosmem = 1; /* rsx387 in dos memory (not rsx32) */ char opt_force_dpmi09 = 1; /* force only DPMI 0.9 calls */ char opt_version = 0; /* print rsx version */ char opt_force_copro; /* force copro status */ int opt_stackval = 0; /* stack size in KB */ int opt_max_dos_handles; /* DOS handles for RSX */ char opt_nocore; /* don't write core file */ char opt_schedule; /* enable schedule() */ int opt_memalloc = 0; /* pre-alloc heap */ char opt_zero = 0; /* zero heap */ char opt_os2 = 0; /* set os/2 bit */ /* special test options */ char opt_kdeb; /* Kernel debug mode */ char opt_printall = 0; /* show all information (testing RSX) */ char opt_print_syscalls = 0; /* show every sys_call (testing RSX) */ char opt_redir; /* redirect handle 1 (testing RSX) */ char opt_debugrsx; /* debug rsx; don't set int3 */ /* other globals */ char npx_present; /* npx present 1/0 */ char kdeb_program[80]; /* program for kernel debug mode */ int rsx_stdout = 1; int kread; /* keyboard read */ int kready; /* keyboard check */ unsigned bios_selector; /* selector bios area */ char **org_env; /* org. environment to rsx */ int org_envc; /* org. env items */ static int emxl_psp = 0; /* exe-stub emxl.exe psp */ int hexstr2int(char *s) { int i, res=0; for (i = 0; i < 4; i++) { char c = s[i]; if (c >= 'a') c -= ('a' - 10); else if (c >= 'A') c -= ('A' - 10); else c -= '0'; res <<= 4; res |= c; } return res; } /* return first non-digit */ static char * asc2int(char *s, int *retv) { char *str = s; *retv = 0; while (*str != 0) { if ((*str < '0') || (*str > '9')) break; *retv *= 10; *retv += *str - '0'; str++; } return (str); } /* ** get one options for rsx ** return last char pos, if successful */ char *scan_for_option(char *s, NEWPROCESS *p) { int temp; char *t; switch (*s) { /* ** emx options with emxbind: ** -a*, -c, -f#, -h#, -p, -s#, -C#, -L */ case 'a': /* DOS features */ for (++s; *s > ' '; ++s) { if (*s == 'm') { if (p) p->options |= OPT_MEMACCESS; else opt_memaccess = 1; } else if (*s == 'c' || *s == 'i' || *s == 'w') continue; else return NULL; } if (*(--s) == 'a') return NULL; break; case 'c': /* core */ opt_nocore = 1; break; case 'e': /* changed !! */ puts("-e option for copro has changed to -Re"); return NULL; case 'f': /* frame size (ignore) */ case 's': /* stack size (ignore) */ case 'C': /* commit */ while (isdigit(*++s)) ; --s; break; case 'h': /* max handles */ ++s; if (!isdigit(*s)) return NULL; t = asc2int(s, &temp); if (p && temp > opt_max_dos_handles) rm_sethandles(temp); opt_max_dos_handles = temp; return t; case 'p': /* don't use lower DOS mem */ rsx387_in_dosmem = 0; break; case 'R': /* special RSX options */ for (++s; *s > ' '; ++s) { if (*s == ',') ++s; switch (*s) { case 'a': /* ss = ds */ opt_stack = 1; break; case 'e': /* copro */ copro = 0; if (isdigit(*(s+1))) opt_force_copro = *(++s) - '0' + 1; break; case 'm': /* malloc for memaccess */ if (!isdigit(*(s+1))) break; s = asc2int(++s, &opt_memalloc) - 1; break; case 's': /* stack frame */ ++s; if (!isdigit(*s)) return NULL; return asc2int(s, &opt_stackval); case 'x': /* enable schedule */ opt_schedule = 1; break; case 'z': /* zero heap */ opt_zero = 1; break; case '1': /* no dpmi10 calls */ opt_force_dpmi09 = 0; break; case '9': /* no dpmi10 calls */ opt_force_dpmi09 = 1; break; case 'D': /* don't touch int3 */ opt_debugrsx = 1; break; case 'F': /* redirect output */ opt_redir = 1; break; case 'I': /* print syscalls */ opt_print_syscalls = 1; break; case 'K': /* kernel debug */ opt_kdeb = 1; break; case 'O': /* set OS/2 bit */ opt_os2 = 1; break; case 'P': /* print syscalls */ opt_printall = 1; break; default: puts("unknown -Rxx option"); return NULL; } } if (*(--s) == 'R') return NULL; break; case 'V': /* version print */ opt_version = 1; break; default: return NULL; } /* switch (*s) */ return s; } static void init_bios_keyboard(void) { /* get DPMI selector for BIOS area, on error try 0x40 */ if (SegToSel(0x40, &bios_selector)) bios_selector = 0x40; /* services for enhanced keyboards, otherwise older types */ if ((BYTE) read32(bios_selector, 0x96) & 0x10) { kread = 0x10; kready = 0x11; } else { kread = 0; kready = 1; } /* flush input */ while (rm_bios_read_keybrd(kready)) rm_bios_read_keybrd(kread); } static int setup_environment(char **env) { char *s; /* save environment, env-size */ for (org_envc = 0; env[org_envc] != NULL; org_envc++) ; org_env = env; /* get enviroment options */ s = getenv("RSXOPT"); if (s != NULL) { for (; *s != '\0'; ++s) { while (*s == ' ') ++s; if (*s == '-') { s = scan_for_option(++s, NULL); if (s == NULL) { puts(version); puts("error in RSXOPT"); return (1); } } else break; } } return 0; } static int get_rsx_options(int start, char **argv) { int i; char *s; for (i = start; argv[i]; i++) { if (argv[i][0] == '-') { s = scan_for_option(& argv[i][1], NULL); if (s == NULL) { puts(version); printf("bad option: %s\n", argv[i]); return -1; } } else break; } return i; } #ifdef __EMX__ #define exit(x) dos_exit(x) #endif /* ** MAIN(): ** real mode for rsx16 ** protected mode rsx32 */ void main(int argc, char **argv, char **env) { static char exefile[128]; int file_arg, err; #ifndef __EMX__ set_stdout(); #endif init_real_mode(); if (setup_environment(environ)) exit(1); /* check bound exe-file */ if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '/' && argv[1][6] == '/') { emxl_psp = hexstr2int(&argv[1][2]); get_emxl_psp(emxl_psp); build_emx_args(&argc, &argv); file_arg = 0; } else if (argc > 1 && strcmp(argv[1], "!proxy") == 0) { build_dj_args(&argc, &argv); emxl_psp = 1; file_arg = 0; } else if (strcmp(argv[0], "!RSX") == 0) { emxl_psp = 1; file_arg = 1; } else { file_arg = get_rsx_options(1, argv); if (file_arg == -1) exit(1); opt_version = 1; } /* print version, if rsx running from prompt */ if (opt_version) puts(version); /* check filename */ if (argc <= file_arg) { puts("no filename defined"); exit(1); } /* copro required, 387 there ? */ npx_present = (char) npx_installed(); if (opt_force_copro) copro = opt_force_copro - (char) 1; else if (copro == 1 && !npx_present) copro = 3; if (real_to_protected(1)) exit(1); /* - - - now protected mode! - - - rsx/rsx32 */ if (test_dpmi_capabilities()) protected_to_real(1); if (hangin_extender()) { puts("ERROR: can't hang in extensions"); protected_to_real(1); } if (opt_kdeb && argv[file_arg + 2]) strcpy(kdeb_program, argv[file_arg + 2]); /* init process-tables */ init_this_process(); /* init bios_selector & get keyboard */ init_bios_keyboard(); strcpy(exefile, argv[file_arg]); if (rm_access(exefile, 0) == -1) { strcat(exefile, ".exe"); if (rm_access(exefile, 0) == -1) { printf("file not found: %s\n", argv[file_arg]); shut_down(1); } } if (!opt_max_dos_handles) opt_max_dos_handles = N_FILES; else if (opt_max_dos_handles > RSX_NFILES) opt_max_dos_handles = RSX_NFILES; rm_sethandles(opt_max_dos_handles); /* hang in emulation */ if (copro == 3) if (install_rsx387()) shut_down(2); init_fpu(); /* rsx output */ if (opt_redir) if ((rsx_stdout = rm_creat("rsx.log", _A_NORMAL)) < 0) rsx_stdout = 1; err = exec32(P_WAIT, exefile, argc - file_arg, argv + file_arg, org_envc, org_env); printf("%s: ", exefile); switch (err) { case EMX_ENOEXEC: puts("Not a valid a.out format"); break; case EMX_ENOMEM: puts("Not enough DPMI memory"); break; default: printf("Can't load file, emx errno = %d\n", err); break; } shut_down(1); /* never reached */ }