/* 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); }
int commands_plugin_inte6_done(void) { if (!pool_used) return 0; LWORD(ebx) = BMEM(retcode); if (BMEM(allocated)) { com_strfree(BMEM(cmd)); lowmem_free((void *)BMEM(pa4), sizeof(struct param4a)); lowmem_free(BMEM(cmdl), 256); if (BMEM(quit)) coopth_add_post_handler(do_exit, NULL); } pool_used--; if (!pool_used) { int leaked = smdestroy(&mp); if (leaked) error("inte6_plugin: leaked %i bytes, builtin=%s\n", leaked, builtin_name); lowmem_heap_free(lowmem_pool); } return 1; }
/* 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); }