char *__save_state(int *psize) { struct LRMI_regs r; char *buffer; unsigned int size; memset(&r, 0, sizeof(r)); r.eax = 0x4f04; r.ecx = 0xf; /* all states */ r.edx = 0; /* get buffer size */ r.ds = 0x0040; if (!LRMI_int(0x10, &r)) { fprintf(stderr, "Can't get video state buffer size (vm86 failure)\n"); } if ((r.eax & 0xffff) != 0x4f) { fprintf(stderr, "Get video state buffer size failed\n"); } *psize = size = (r.ebx & 0xffff) * 64; buffer = LRMI_alloc_real(size); if (buffer == NULL) { fprintf(stderr, "Can't allocate video state buffer\n"); return NULL; } memset(&r, 0, sizeof(r)); fprintf(stderr, "Allocated buffer at %p (base is 0x%x)\n", buffer, LRMI_base_addr()); r.eax = 0x4f04; r.ecx = 0xf; /* all states */ r.edx = 1; /* save state */ r.es = (unsigned int) (buffer - LRMI_base_addr()) >> 4; r.ebx = (unsigned int) (buffer - LRMI_base_addr()) & 0xf; r.ds = 0x0040; fprintf(stderr, "ES: 0x%04X EBX: 0x%04X\n", r.es, r.ebx); if (!LRMI_int(0x10, &r)) { fprintf(stderr, "Can't save video state (vm86 failure)\n"); } if ((r.eax & 0xffff) != 0x4f) { fprintf(stderr, "Save video state failed\n"); } return buffer; }
void restore_state_from(char *data) { struct LRMI_regs r; /* VGA BIOS mode 3 is text mode */ do_set_mode(3,1); memset(&r, 0, sizeof(r)); r.eax = 0x4f04; r.ecx = 0xf; /* all states */ r.edx = 2; /* restore state */ r.es = (unsigned int) (data - LRMI_base_addr()) >> 4; r.ebx = (unsigned int) (data - LRMI_base_addr()) & 0xf; r.ds = 0x0040; if (!LRMI_int(0x10, &r)) { fprintf(stderr, "Can't restore video state (vm86 failure)\n"); } else if ((r.eax & 0xffff) != 0x4f) { fprintf(stderr, "Restore video state failed\n"); } LRMI_free_real(data); ioctl(0, KDSETMODE, KD_TEXT); }
/* Figure out what the current video mode is. */ int32_t vbe_get_mode() { struct LRMI_regs regs; int32_t ret = -1; /* Initialize LRMI. */ if(LRMI_init() == 0) { return -1; } memset(®s, 0, sizeof(regs)); regs.eax = 0x4f03; /* Do it. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { return -1; } /* Save the returned value. */ if((regs.eax & 0xffff) == 0x004f) { ret = regs.ebx & 0xffff; } else { ret = -1; } /* Clean up and return. */ return ret; }
void set_vesa_mode(int mode){ struct LRMI_regs r; memset(&r, 0, sizeof(r)); r.eax = 0x4f02; r.ebx = mode; if (!LRMI_int(0x10, &r)) { fprintf(stderr, "Can't set video mode (vm86 failure)\n"); } }
/* * Perform a simulated interrupt call. */ int v86_int(int num, struct v86_regs *regs) { struct LRMI_regs r; int err; rconv_v86_to_LRMI(regs, &r); err = LRMI_int(num, &r); rconv_LRMI_to_v86(&r, regs); return (err == 1) ? 0 : 1; }
/* Return information about a particular video mode. */ struct vbe_mode_info *vbe_get_mode_info(u_int16_t mode) { struct LRMI_regs regs; char *mem; struct vbe_mode_info *ret = NULL; /* Initialize LRMI. */ if(LRMI_init() == 0) { return NULL; } /* Allocate a chunk of memory. */ mem = LRMI_alloc_real(sizeof(struct vbe_mode_info)); if(mem == NULL) { return NULL; } memset(mem, 0, sizeof(struct vbe_mode_info)); memset(®s, 0, sizeof(regs)); regs.eax = 0x4f01; regs.ecx = mode; regs.es = ((u_int32_t)mem) >> 4; regs.edi = ((u_int32_t)mem) & 0x0f; /* Do it. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { LRMI_free_real(mem); return NULL; } /* Check for successful return. */ if((regs.eax & 0xffff) != 0x004f) { LRMI_free_real(mem); return NULL; } /* Get memory for return. */ ret = malloc(sizeof(struct vbe_mode_info)); if(ret == NULL) { LRMI_free_real(mem); return NULL; } /* Copy the buffer for return. */ memcpy(ret, mem, sizeof(struct vbe_mode_info)); /* Clean up and return. */ LRMI_free_real(mem); return ret; }
/* Set the video mode. */ void vbe_set_mode(u_int16_t mode) { struct LRMI_regs regs; /* Initialize LRMI. */ if(LRMI_init() == 0) { return; } memset(®s, 0, sizeof(regs)); regs.eax = 0x4f02; regs.ebx = mode; /* Do it. */ iopl(3); ioperm(0, 0x400, 1); LRMI_int(0x10, ®s); /* Return. */ return; }
/* Check if EDID queries are suorted. */ int vbe_get_edid_supported(int adapter) { struct LRMI_regs regs; int ret = 0; /* Initialize LRMI. */ if(LRMI_init() == 0) { return 0; } memset(®s, 0, sizeof(regs)); regs.eax = 0x4f15; regs.ebx = 0x0000; regs.ecx = adapter; regs.es = 0x3000; regs.edi = 0x3000; /* Do it. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { return 0; } /* Check for successful return. */ if((regs.eax & 0xff) == 0x4f) { /* Supported. */ //ret = 1; ret = regs.ebx & 0x03; } else { /* Not supported. */ ret = 0; } /* Clean up and return. */ return ret; }
/* Get VBE info. */ struct vbe_info *vbe_get_vbe_info() { struct LRMI_regs regs; unsigned char *mem; struct vbe_info *ret = NULL; int i; /* Initialize LRMI. */ if(LRMI_init() == 0) { return NULL; } /* Allocate a chunk of memory. */ mem = LRMI_alloc_real(sizeof(struct vbe_mode_info)); if(mem == NULL) { return NULL; } memset(mem, 0, sizeof(struct vbe_mode_info)); /* Set up registers for the interrupt call. */ memset(®s, 0, sizeof(regs)); regs.eax = 0x4f00; regs.es = ((u_int32_t)mem) >> 4; regs.edi = ((u_int32_t)mem) & 0x0f; memcpy(mem, "VBE2", 4); /* Do it. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { LRMI_free_real(mem); return NULL; } /* Check for successful return code. */ if((regs.eax & 0xffff) != 0x004f) { LRMI_free_real(mem); return NULL; } /* Get memory to return the information. */ ret = malloc(sizeof(struct vbe_info)); if(ret == NULL) { LRMI_free_real(mem); return NULL; } memcpy(ret, mem, sizeof(struct vbe_info)); /* Set up pointers to usable memory. */ ret->mode_list.list = (u_int16_t*) ((ret->mode_list.addr.seg << 4) + (ret->mode_list.addr.ofs)); ret->oem_name.string = (char*) ((ret->oem_name.addr.seg << 4) + (ret->oem_name.addr.ofs)); /* Snip, snip. */ mem = strdup(ret->oem_name.string); /* leak */ while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { mem[i - 1] = '\0'; } ret->oem_name.string = mem; /* Set up pointers for VESA 3.0+ strings. */ if(ret->version[1] >= 3) { /* Vendor name. */ ret->vendor_name.string = (char*) ((ret->vendor_name.addr.seg << 4) + (ret->vendor_name.addr.ofs)); mem = strdup(ret->vendor_name.string); /* leak */ while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { mem[i - 1] = '\0'; } ret->vendor_name.string = mem; /* Product name. */ ret->product_name.string = (char*) ((ret->product_name.addr.seg << 4) + (ret->product_name.addr.ofs)); mem = strdup(ret->product_name.string); /* leak */ while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { mem[i - 1] = '\0'; } ret->product_name.string = mem; /* Product revision. */ ret->product_revision.string = (char*) ((ret->product_revision.addr.seg << 4) + (ret->product_revision.addr.ofs)); mem = strdup(ret->product_revision.string); /* leak */ while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { mem[i - 1] = '\0'; } ret->product_revision.string = mem; } /* Cleanup. */ LRMI_free_real(mem); return ret; }
void vbe_restore_svga_state(const void *state) { struct LRMI_regs regs; unsigned char *mem; u_int16_t block_size; /* Initialize LRMI. */ if(LRMI_init() == 0) { return; } memset(®s, 0, sizeof(regs)); regs.eax = 0x4f04; regs.ecx = 0x000f; regs.edx = 0; /* Find out how much memory we need. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { return; } if((regs.eax & 0xff) != 0x4f) { fprintf(stderr, "Get SuperVGA Video State not supported.\n"); return; } if((regs.eax & 0xffff) != 0x004f) { fprintf(stderr, "Get SuperVGA Video State Info failed.\n"); return; } block_size = 64 * (regs.ebx & 0xffff); /* Allocate a chunk of memory. */ mem = LRMI_alloc_real(block_size); if(mem == NULL) { return; } memset(mem, 0, sizeof(block_size)); memset(®s, 0, sizeof(regs)); regs.eax = 0x4f04; regs.ecx = 0x000f; regs.edx = 0x0002; regs.es = 0x2000; regs.ebx = 0x0000; memcpy(mem, state, block_size); iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { LRMI_free_real(mem); return; } if((regs.eax & 0xffff) != 0x004f) { fprintf(stderr, "Get SuperVGA Video State Restore failed.\n"); return; } }
const void *vbe_save_svga_state() { struct LRMI_regs regs; unsigned char *mem; u_int16_t block_size; void *data; /* Initialize LRMI. */ if(LRMI_init() == 0) { return NULL; } memset(®s, 0, sizeof(regs)); regs.eax = 0x4f04; regs.ecx = 0xffff; regs.edx = 0; iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { return NULL; } if((regs.eax & 0xff) != 0x4f) { fprintf(stderr, "Get SuperVGA Video State not supported.\n"); return NULL; } if((regs.eax & 0xffff) != 0x004f) { fprintf(stderr, "Get SuperVGA Video State Info failed.\n"); return NULL; } block_size = 64 * (regs.ebx & 0xffff); /* Allocate a chunk of memory. */ mem = LRMI_alloc_real(block_size); if(mem == NULL) { return NULL; } memset(mem, 0, sizeof(block_size)); memset(®s, 0, sizeof(regs)); regs.eax = 0x4f04; regs.ecx = 0x000f; regs.edx = 0x0001; regs.es = ((u_int32_t)mem) >> 4; regs.ebx = ((u_int32_t)mem) & 0x0f; memset(mem, 0, block_size); iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { LRMI_free_real(mem); return NULL; } if((regs.eax & 0xffff) != 0x004f) { fprintf(stderr, "Get SuperVGA Video State Save failed.\n"); return NULL; } data = malloc(block_size); if(data == NULL) { LRMI_free_real(mem); return NULL; } /* Clean up and return. */ memcpy(data, mem, block_size); LRMI_free_real(mem); return data; }
/* Get EDID info. */ struct vbe_edid1_info *vbe_get_edid_info(int adapter) { struct LRMI_regs regs; unsigned char *mem; struct vbe_edid1_info *ret = NULL; u_int16_t man; /* Initialize LRMI. */ if(LRMI_init() == 0) { return NULL; } /* Allocate a chunk of memory. */ mem = LRMI_alloc_real(sizeof(struct vbe_edid1_info)); if(mem == NULL) { return NULL; } memset(mem, 0, sizeof(struct vbe_edid1_info)); memset(®s, 0, sizeof(regs)); regs.eax = 0x4f15; regs.ebx = 0x0001; regs.ecx = adapter; regs.es = ((u_int32_t)mem) >> 4; regs.edi = ((u_int32_t)mem) & 0x0f; /* Do it. */ iopl(3); ioperm(0, 0x400, 1); if(LRMI_int(0x10, ®s) == 0) { LRMI_free_real(mem); return NULL; } #if 0 /* Check for successful return. */ if((regs.eax & 0xffff) != 0x004f) { LRMI_free_real(mem); return NULL; } #elseif /* Check for successful return. */ if((regs.eax & 0xff) != 0x4f) { LRMI_free_real(mem); return NULL; } #endif /* Get memory for return. */ ret = malloc(sizeof(struct vbe_edid1_info)); if(ret == NULL) { LRMI_free_real(mem); return NULL; } /* Copy the buffer for return. */ memcpy(ret, mem, sizeof(struct vbe_edid1_info)); memcpy(&man, &ret->manufacturer_name, 2); man = ntohs(man); memcpy(&ret->manufacturer_name, &man, 2); LRMI_free_real(mem); return ret; }