/* Restore and write chipset-specific registers */ static void vesa_restore_ext_regs(u_char xregs[], u_short xregs16[]) { void *lowmem; unsigned long current_int10; if (xregs16[0] == 0) return; lowmem = lowmem_heap_alloc(xregs16[0]); memcpy(lowmem, xregs, xregs16[0]); vesa_r.eax = 0x4f04; vesa_r.ebx = 0; vesa_r.es = FP_SEG32(lowmem); vesa_r.edx = 2; vesa_r.ecx = VESA_SAVE_BITMAP; /* swap int10 vectors with the original int10 vector as it was when the registers were saved to avoid conflicts with univbe */ current_int10 = MK_FP16(ISEG(0x10), IOFF(0x10)); SETIVEC(0x10, xregs16[2], xregs16[1]); do_int10_callback(&vesa_r); SETIVEC(0x10, FP_SEG16(current_int10), FP_OFF16(current_int10)); lowmem_heap_free(lowmem); }
/* Read and save chipset-specific registers */ static void vesa_save_ext_regs(u_char xregs[], u_short xregs16[]) { void *lowmem; /* if int10 changed we may have to reinitialize */ if (MK_FP16(ISEG(0x10), IOFF(0x10)) != vesa_int10) vesa_reinit(); if (vesa_regs_size == 0) return; lowmem = lowmem_heap_alloc(vesa_regs_size); vesa_r.eax = 0x4f04; vesa_r.ebx = 0; vesa_r.es = FP_SEG32(lowmem); vesa_r.edx = 1; vesa_r.ecx = VESA_SAVE_BITMAP; do_int10_callback(&vesa_r); /* abuse xregs16 to store some important info: size and int10 vector */ xregs16[0] = vesa_regs_size; xregs16[1] = IOFF(0x10); xregs16[2] = ISEG(0x10); memcpy(xregs, lowmem, vesa_regs_size); lowmem_heap_free(lowmem); }
/* vesa_reinit: a function to reinitialize in case the DOS VESA driver changes at runtime (e.g. univbe). Also called at startup */ static void vesa_reinit(void) { unsigned char *vbe_buffer, *info_buffer, *s; vesa_int10 = MK_FP16(ISEG(0x10), IOFF(0x10)); vbe_buffer = info_buffer = lowmem_heap_alloc(VBE_viSize+VBE_vmSize); vesa_r.eax = 0x4f00; vesa_r.es = FP_SEG32(vbe_buffer); vesa_r.edi = 0; VBE_viVBESig = 0x32454256; /* "VBE2" */ do_int10_callback(&vesa_r); if ((vesa_r.eax & 0xffff) != 0x4f || VBE_viVBESig != 0x41534556 /* "VESA" */ ) { v_printf("No VESA bios detected!\n"); if (config.gfxmemsize < 0) config.gfxmemsize = 256; vesa_regs_size = 0; vesa_linear_vbase = 0; goto out; } /* check if the VESA BIOS has changed */ s = MK_FP32(FP_SEG16(VBE_viOEMID), FP_OFF16(VBE_viOEMID)); if (vesa_oemstring && VBE_viOEMID == vesa_oemid && strcmp(s, vesa_oemstring) == 0) goto out; vesa_oemid = VBE_viOEMID; if (vesa_oemstring) free(vesa_oemstring); vesa_oemstring = strdup(s); if (config.gfxmemsize < 0) config.gfxmemsize = VBE_viMemory*64; vesa_version = VBE_viVESAVersion; vbe_buffer += VBE_viSize; memset(&vesa_r, 0, sizeof(vesa_r)); vesa_granularity = 64; vesa_read_write = 6; vesa_linear_vbase = 0; vesa_r.eax = 0x4f01; vesa_r.ecx = vesa_version >= 0x200 ? 0x81ff : 0x101; vesa_r.es = (size_t)vbe_buffer >> 4; vesa_r.edi = (size_t)vbe_buffer & 0xf; do_int10_callback(&vesa_r); if ((vesa_r.eax & 0xffff) == 0x4f) { vesa_granularity= VBE_vmWinGran; vesa_read_write = VBE_vmWinAAttrib & 6; if (vesa_version >= 0x200 && (VBE_vmModeAttrib & 0x80) && config.pci_video) { vesa_linear_vbase = (size_t)get_hardware_ram(VBE_vmPhysBasePtr); v_printf("VESA: physical base = %x, virtual base = %zx\n", VBE_vmPhysBasePtr, vesa_linear_vbase); } } else { v_printf("VESA: Can't get mode info\n"); } /* if not reported then guess */ if (vesa_granularity == 0) vesa_granularity = 64; vesa_regs_size = 0; vesa_r.eax = 0x4f04; vesa_r.edx = 0; vesa_r.ecx = VESA_SAVE_BITMAP; vesa_r.ebx = 0; do_int10_callback(&vesa_r); if ((vesa_r.eax & 0xffff) == 0x4f) vesa_regs_size = vesa_r.ebx * 64; out: lowmem_heap_free(info_buffer); v_printf("VESA: memory size = %lu, regs_size=%x\n", config.gfxmemsize, vesa_regs_size); }
int commands_plugin_inte6(void) { #define MAX_ARGS 63 char *args[MAX_ARGS + 1]; struct PSP *psp; struct MCB *mcb; struct com_program_entry *com; int argc; if (pool_used >= MAX_NESTING) { com_error("Cannot invoke more than %i builtins\n", MAX_NESTING); return 0; } if (!pool_used) { if (!(lowmem_pool = lowmem_heap_alloc(LOWMEM_POOL_SIZE))) { error("Unable to allocate memory pool\n"); return 0; } sminit(&mp, lowmem_pool, LOWMEM_POOL_SIZE); } pool_used++; BMEM(allocated) = 0; BMEM(retcode) = 0; if (HI(ax) != BUILTINS_PLUGIN_VERSION) { com_error("builtins plugin version mismatch: found %i, required %i\n", HI(ax), BUILTINS_PLUGIN_VERSION); com_error("You should update your generic.com, ems.sys, isemu.com and other utilities\n" "from the latest dosemu package!\n"); commands_plugin_inte6_done(); return 0; } psp = COM_PSP_ADDR; mcb = LOWMEM(SEGOFF2LINEAR(COM_PSP_SEG - 1,0)); /* first parse commandline */ args[0] = strdup(com_getarg0()); strupperDOS(args[0]); argc = com_argparse((char *)&psp->cmdline_len, &args[1], MAX_ARGS - 1) + 1; /* DOS 4 and up */ strncpy(builtin_name, mcb->name, sizeof(builtin_name) - 1); builtin_name[sizeof(builtin_name) - 1] = 0; strupperDOS(builtin_name); com = find_com_program(builtin_name); /* DOS 3.0->3.31 construct the program name from the environment */ if(!com) { char *p = strrchr(args[0],'\\'); strncpy(builtin_name, p+1, sizeof(builtin_name) - 1); builtin_name[sizeof(builtin_name) - 1] = 0; p = strchr(builtin_name, '.'); if(p) *p = '\0'; com = find_com_program(builtin_name); } if (com) { int err = com->program(argc, args); if (!err) { NOCARRY; } else { CARRY; _AL = err; } } else { com_error("inte6: unknown builtin: %s\n",builtin_name); CARRY; _AL = 1; } free(args[0]); return 1; }