diff options
Diffstat (limited to 'hw/kdrive/vesa/vbe.c')
-rw-r--r-- | hw/kdrive/vesa/vbe.c | 1344 |
1 files changed, 358 insertions, 986 deletions
diff --git a/hw/kdrive/vesa/vbe.c b/hw/kdrive/vesa/vbe.c index fa2fbeaa3..d4a2817c8 100644 --- a/hw/kdrive/vesa/vbe.c +++ b/hw/kdrive/vesa/vbe.c @@ -19,539 +19,409 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.c,v 1.5 2000/09/27 20:46:37 keithp Exp $ */ -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/vm86.h> -#include <sys/io.h> -#include "vbe.h" +#include "vesa.h" -#ifdef NOT_IN_X_SERVER -#include <stdio.h> -#include <stdarg.h> -#include <malloc.h> -static void ErrorF(char*, ...); -#define xalloc(a) malloc(a) -#define xcalloc(a,b) calloc(a,b) -#define xfree(a) free(a) -#else -#include "X.h" -#include "Xproto.h" -#include "Xos.h" -#include "os.h" -#endif - -static int vm86old(struct vm86_struct *vms); -static int vm86_loop(VbeInfoPtr vi); - -static U8 rev_ints[32] = -{ 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x80, -}; - -static U8 retcode_data[2] = -{ 0xCD, 0xFF }; - -#define LM(vi,i) (((char*)vi->loMem)[i-LOMEM_BASE]) -#define LMW(vi,i) (*(U16*)(&LM(vi,i))) -#define LML(vi,i) (*(U32*)(&LM(vi,i))) -#define MM(vi,i) (((char*)vi->magicMem)[i-MAGICMEM_BASE]) -#define MMW(vi,i) (*(U16*)(&MM(vi,i))) -#define MML(vi,i) (*(U32*)(&MM(vi,i))) -#define HM(vi,i) (((char*)vi->hiMem)[i-HIMEM_BASE]) -#define HMW(vi,i) (*(U16*)(&MM(vi,i))) -#define HML(vi,i) (*(U32*)(&MM(vi,i))) - -#define PUSHW(vi, i) \ -{ vi->vms.regs.esp -= 2;\ - LMW(vi,MAKE_POINTER(vi->vms.regs.ss, vi->vms.regs.esp)) = i;} - -VbeInfoPtr -VbeSetup() +int +VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib) { - int devmem = -1, devzero = -1; - void *magicMem, *loMem, *hiMem; - U32 stack_base, vib_base, vmib_base, ret_code; - VbeInfoPtr vi = NULL; - - devmem = open("/dev/mem", O_RDWR); - if(devmem < 0) { - perror("open /dev/mem"); - goto fail; - } - - devzero = open("/dev/zero", O_RDWR); - if(devmem < 0) { - perror("open /dev/zero"); - goto fail; - } - - - magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_FIXED, devmem, MAGICMEM_BASE); - if(magicMem == MAP_FAILED) { - ErrorF("Couldn't map magic memory\n"); - goto fail; - } - - loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_FIXED, devzero, LOMEM_BASE); - if(loMem == MAP_FAILED) { - ErrorF("Couldn't map low memory\n"); - munmap(magicMem, MAGICMEM_SIZE); - goto fail; - } - - hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_SHARED | MAP_FIXED, - devmem, HIMEM_BASE); - if(hiMem == MAP_FAILED) { - ErrorF("Couldn't map high memory\n"); - munmap(magicMem, MAGICMEM_SIZE); - munmap(loMem, LOMEM_SIZE); - goto fail; + int code; + int mark; + int vib_base; + VbeInfoBlock *vib_low; + + mark = Vm86MarkMemory (vi); + vib_base = Vm86AllocateMemory (vi, sizeof (VbeInfoBlock)); + vib_low = (VbeInfoBlock*)&(LM(vi, vib_base)); + vi->vms.regs.eax = 0x4F00; + vi->vms.regs.es = POINTER_SEGMENT(vib_base); + vi->vms.regs.edi = POINTER_OFFSET(vib_base); + memcpy(vib_low->VbeSignature, "VBE2", 4); + code = VbeDoInterrupt10(vi); + if(code >= 0) + { + if(memcmp(vib_low->VbeSignature, "VESA", 4) == 0) + *vib = *vib_low; + else + code = -1; } + Vm86ReleaseMemory (vi, mark); + return code; +} - vi = xalloc(sizeof(VbeInfoRec)); - if (!vi) - goto unmapfail; - - vi->devmem = devmem; - vi->devzero = devzero; - vi->magicMem = magicMem; - vi->loMem = loMem; - vi->hiMem = hiMem; - vi->brk = LOMEM_BASE; - - stack_base = VbeAllocateMemory(vi, STACK_SIZE); - if(stack_base == ALLOC_FAIL) - goto unmapfail; - ret_code = VbeAllocateMemory(vi, sizeof(retcode_data)); - if(ret_code == ALLOC_FAIL) - goto unmapfail; - vib_base = VbeAllocateMemory(vi, sizeof(VbeInfoBlock)); - if(vib_base == ALLOC_FAIL) - goto unmapfail; - vmib_base = VbeAllocateMemory(vi, sizeof(VbeModeInfoBlock)); - if(vmib_base == ALLOC_FAIL) - goto unmapfail; - - vi->stack_base = stack_base; - vi->ret_code = ret_code; - vi->vib_base = vib_base; - vi->vmib_base = vmib_base; - vi->statebuffer_base = ~0; - vi->palette_scratch_base = ~0; - vi->palette_format = 6; - vi->palette_wait = 0; - vi->windowA_offset = vi->windowB_offset = -1; - vi->last_window = 1; - vi->vga_palette = 1; +int +VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib) +{ + int code; + int mark; + int vib_base; + int vmib_base; + VbeModeInfoBlock *vmib_low; - memset(&vi->vms, 0, sizeof(struct vm86_struct)); - vi->vms.flags = 0; - vi->vms.screen_bitmap = 0; - vi->vms.cpu_type = CPU_586; - memcpy(&vi->vms.int_revectored, rev_ints, sizeof(rev_ints)); - - ioperm(0, 0x400, 1); - iopl(3); - - return vi; - - unmapfail: - munmap(magicMem, MAGICMEM_SIZE); - munmap(loMem, LOMEM_SIZE); - munmap(hiMem, HIMEM_SIZE); - fail: - if(devmem >= 0) - close(devmem); - if(devzero >= 0) - close(devzero); - if(vi) - xfree(vi); - return NULL; + mark = Vm86MarkMemory (vi); + + vmib_base = Vm86AllocateMemory (vi, sizeof (VbeModeInfoBlock)); + vmib_low = (VbeModeInfoBlock*)&(LM(vi, vmib_base)); + + vi->vms.regs.eax = 0x4F01; + vi->vms.regs.ecx = mode&0xFFFF; + vi->vms.regs.es = POINTER_SEGMENT(vmib_base); + vi->vms.regs.edi = POINTER_OFFSET(vmib_base); + code = VbeDoInterrupt10(vi); + + if(code >= 0) + *vmib = *vmib_low; + Vm86ReleaseMemory (vi, mark); + return code; } void -VbeCleanup(VbeInfoPtr vi) +VbeReportInfo (Vm86InfoPtr vi) { - munmap(vi->magicMem, MAGICMEM_SIZE); - munmap(vi->loMem, LOMEM_SIZE); - munmap(vi->hiMem, HIMEM_SIZE); - close (vi->devmem); - close (vi->devzero); - xfree(vi); -} + VbeInfoBlock vib; + int code; -VbeInfoBlock * -VbeGetInfo(VbeInfoPtr vi) -{ - int code; - VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); - vi->vms.regs.eax = 0x4F00; - vi->vms.regs.es = POINTER_SEGMENT(vi->vib_base); - vi->vms.regs.edi = POINTER_OFFSET(vi->vib_base); - memcpy(vib->VbeSignature, "VBE2", 4); - code = VbeDoInterrupt10(vi); - if(code < 0) - return NULL; - if(memcmp(vib->VbeSignature, "VESA", 4) != 0) { - ErrorF("Int 10 didn't return VESA signature in info block"); - return NULL; - } - return vib; + code = VbeGetVib (vi, &vib); + if (code >= 0) + VbeReportVib(vi, &vib); } -VbeModeInfoBlock * -VbeGetModeInfo(VbeInfoPtr vi, int mode) +int +VbeGetNmode (Vm86InfoPtr vi) { - int code; - U32 p; - VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); - VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base)); - p = MAKE_POINTER_1(vib->VideoModePtr); - if(!VbeIsMemory(vi, p)) { - ErrorF("VideoModePtr 0x%08X doesn't point at low memory\n", - vib->VideoModePtr); - return NULL; + VbeInfoBlock vib; + int code; + int ret = 0; + unsigned int p; + int n; + int mode; + + code = VbeGetVib (vi, &vib); + if (code >= 0) + { + p = MAKE_POINTER_1(vib.VideoModePtr); + for (n = 0; ; n++) + { + mode = Vm86MemoryW(vi, p); + if (mode == 0xffff) + break; + p += 2; + } + code = n; } - vi->vms.regs.eax = 0x4F01; - vi->vms.regs.ecx = mode&0xFFFF; - vi->vms.regs.es = POINTER_SEGMENT(vi->vmib_base); - vi->vms.regs.edi = POINTER_OFFSET(vi->vmib_base); - code = VbeDoInterrupt10(vi); - if(code < 0) - return NULL; - else - return vmib; + return code; } int -VbeSetMode(VbeInfoPtr vi, int mode, int linear) +VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode) { - int code; + VbeInfoBlock vib; + int code; + int ret = 0; + unsigned int p; + int n; + int mode; + VbeModeInfoBlock vmib; - vi->windowA_offset = vi->windowB_offset = -1; - vi->last_window = 1; + code = VbeGetVib (vi, &vib); + if (code < 0) + return code; + + memset (modes, '\0', n * sizeof (VesaModeRec)); - vi->vms.regs.eax = 0x4F02; - vi->vms.regs.ebx = (mode & 0xFFFF) | 0x8000; - if(linear) - vi->vms.regs.ebx |= 0x4000; - code = VbeDoInterrupt10(vi); - if(code < 0) - return -1; - return 0; + p = MAKE_POINTER_1(vib.VideoModePtr); + for (n = 0; n < nmode; n++) + { + mode = Vm86MemoryW(vi, p); + if (mode == 0xffff) + break; + modes[n].mode = mode; + modes[n].vbe = 1; + p += 2; + } + + nmode = n; + + for (n = 0; n < nmode; n++) + { + code = VbeGetVmib (vi, modes[n].mode, &vmib); + if (code >= 0) + { + modes[n].ModeAttributes = vmib.ModeAttributes; + modes[n].NumberOfPlanes = vmib.NumberOfPlanes; + modes[n].BitsPerPixel = vmib.BitsPerPixel; + modes[n].MemoryModel = vmib.MemoryModel; + modes[n].RedMaskSize = vmib.RedMaskSize; + modes[n].RedFieldPosition = vmib.RedFieldPosition; + modes[n].GreenMaskSize = vmib.GreenMaskSize; + modes[n].GreenFieldPosition = vmib.GreenFieldPosition; + modes[n].BlueMaskSize = vmib.BlueMaskSize; + modes[n].BlueFieldPosition = vmib.BlueFieldPosition; + modes[n].RsvdMaskSize = vmib.RsvdMaskSize; + modes[n].RsvdFieldPosition = vmib.RsvdFieldPosition; + modes[n].DirectColorModeInfo = vmib.DirectColorModeInfo; + modes[n].XResolution = vmib.XResolution; + modes[n].YResolution = vmib.YResolution; + modes[n].BytesPerScanLine = vmib.BytesPerScanLine; + } + } + + return nmode; } -int -VbeGetMode(VbeInfoPtr vi, int *mode) +VbeInfoPtr +VbeInit (Vm86InfoPtr vi) { - int code; - vi->vms.regs.eax = 0x4F03; - code = VbeDoInterrupt10(vi); - if(code < 0) - return - 1; - *mode = vi->vms.regs.ebx & 0xFFFF; - return 0; -} + VbeInfoPtr vbe; + int code; + VbeInfoBlock vib; -int -VbeSetupStateBuffer(VbeInfoPtr vi) -{ - int code; - if(vi->statebuffer_base != ~0) - return 0; - vi->vms.regs.eax = 0x4F04; - vi->vms.regs.edx = 0x0000; - vi->vms.regs.ecx = 0x000F; - code = VbeDoInterrupt10(vi); - if(code < 0) - return -1; - vi->statebuffer_base = VbeAllocateMemory(vi, vi->vms.regs.ebx & 0xFFFF); - return 0; + code = VbeGetVib (vi, &vib); + if (code < 0) + return 0; + + vbe = xalloc (sizeof (VbeInfoRec)); + if (!vbe) + return 0; + vbe->palette_format = 6; + vbe->palette_wait = TRUE; + return vbe; } -int -VbeSaveState(VbeInfoPtr vi) +void +VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe) { - int code; - code = VbeSetupStateBuffer(vi); - if(code < 0) - return -1; - vi->vms.regs.eax = 0x4F04; - vi->vms.regs.edx = 0x0001; - vi->vms.regs.ecx = 0x000F; - vi->vms.regs.es = POINTER_SEGMENT(vi->statebuffer_base); - vi->vms.regs.ebx = POINTER_OFFSET(vi->statebuffer_base); - code = VbeDoInterrupt10(vi); - if(code < 0) - return -1; - return 0; + xfree (vbe); } int -VbeRestoreState(VbeInfoPtr vi) +VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear) { - int code; - vi->vms.regs.eax = 0x4F04; - vi->vms.regs.edx = 0x0002; - vi->vms.regs.ecx = 0x000F; - vi->vms.regs.es = POINTER_SEGMENT(vi->statebuffer_base); - vi->vms.regs.ebx = POINTER_OFFSET(vi->statebuffer_base); + int code; + VbeInfoBlock vib; + int palette_wait = 0, palette_hi = 0; + + code = VbeGetVib (vi, &vib); + if (code < 0) + return -1; + + code = VbeGetVmib (vi, mode, &vbe->vmib); + if (code < 0) + return -1; + + mode = (mode & 0xffff) | 0x8000; + if (linear) + mode |= 0x4000; + + vi->vms.regs.eax = 0x4F02; + vi->vms.regs.ebx = mode; code = VbeDoInterrupt10(vi); if(code < 0) return -1; + + vbe->windowA_offset = vbe->windowB_offset = -1; + vbe->last_window = 1; + + if(vib.Capabilities[0] & 1) + palette_hi = 1; + if(vib.Capabilities[0] & 4) + palette_wait = 1; + + if(palette_hi || palette_wait) + VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait); + return 0; } -int -VbeSetTextMode(VbeInfoPtr vi, int mode) +int +VbeGetMode(Vm86InfoPtr vi, int *mode) { int code; - vi->vms.regs.eax = mode & 0x7f; + vi->vms.regs.eax = 0x4F03; code = VbeDoInterrupt10(vi); if(code < 0) - return -1; + return - 1; + *mode = vi->vms.regs.ebx & 0xFFFF; return 0; } void * -VbeMapFramebuffer(VbeInfoPtr vi, - VbeModeInfoBlock *vmib) -{ - U8 *fb; - VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); - int size; - int pagesize = getpagesize(), before, after; - - size = 1024 * 64L * vib->TotalMemory; +VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size) +{ + U8 *fb; + VbeInfoBlock vib; + VbeModeInfoBlock vmib; + int size; + int pagesize = getpagesize(); + int before, after; + int devmem; + + if (VbeGetVib (vi, &vib) < 0) + return 0; + + if (VbeGetVmib (vi, mode, &vmib) < 0) + return 0; + + size = 1024 * 64L * vib.TotalMemory; + + *ret_size = size; - before = vmib->PhysBasePtr % pagesize; - after = pagesize - ((vmib->PhysBasePtr + size) % pagesize); + before = vmib.PhysBasePtr % pagesize; + after = pagesize - ((vmib.PhysBasePtr + size) % pagesize); if(after == pagesize) after = 0; - fb = mmap(0, before + size + after, - PROT_READ | PROT_WRITE, MAP_SHARED, - vi->devmem, vmib->PhysBasePtr - before); - if(fb == MAP_FAILED) { - ErrorF("Failed to map framebuffer: %d\n", errno); + fb = KdMapDevice (vmib.PhysBasePtr - before, before + size + after); + + if(fb == 0) + { + ErrorF("Failed to map framebuffer\n"); return NULL; } return fb + before; } -int -VbeUnmapFramebuffer(VbeInfoPtr vi, - VbeModeInfoBlock *vmib, - void *fb) +void +VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb) { - int code; - VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); - int size; - int pagesize = getpagesize(), before, after; + VbeInfoBlock vib; + VbeModeInfoBlock vmib; + int size; + int pagesize = getpagesize(); + int before, after; - size = 1024 * 64L * vib->TotalMemory; + if (VbeGetVib (vi, &vib) < 0) + return; + + if (VbeGetVmib (vi, mode, &vmib) < 0) + return; + + size = 1024 * 64L * vib.TotalMemory; - before = vmib->PhysBasePtr % pagesize; - after = pagesize - ((vmib->PhysBasePtr + size) % pagesize); + before = vmib.PhysBasePtr % pagesize; + after = pagesize - ((vmib.PhysBasePtr + size) % pagesize); if(after == pagesize) after = 0; fb = (void *) ((char *) fb - before); - code = munmap(fb, before + size + after); - if(code) { - ErrorF("Couldn't unmap framebuffer: %d\n", errno); - return -1; - } - return 0; -} - -static int -PreparePalette(VbeInfoPtr vi) -{ - int code; - if(vi->palette_scratch_base == ~0) { - vi->palette_scratch_base = VbeAllocateMemory(vi, 4*256); - if(vi->palette_scratch_base == ALLOC_FAIL) { - ErrorF("Couldn't allocate scratch area for palette transfer\n"); - return -1; - } - } - if(!vi->palette_format) { - /* This isn't used currently */ - vi->vms.regs.eax = 0x4F08; - vi->vms.regs.ebx = 0x01; - code = VbeDoInterrupt10(vi); - if(code < 0) - return -1; - vi->palette_format = vi->vms.regs.ebx & 0xFF; - } - return 0; + KdUnmapDevice (fb, before + size + after); } int -VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries) +VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries) { - U8 *palette_scratch; - int i, j, code; + U8 *palette_scratch; + int mark; + int palette_base; + int i, j, code; if(number == 0) return 0; - code = PreparePalette(vi); - if(code < 0) - return -1; - if(first < 0 || number < 0 || first + number > 256) { ErrorF("Cannot set %d, %d palette entries\n", first, number); return -1; } - palette_scratch = &LM(vi, vi->palette_scratch_base); - - if(vi->palette_format < 6 || vi->palette_format > 8) { - ErrorF("Impossible palette format %d\n", vi->palette_format); + if(vbe->palette_format < 6 || vbe->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vbe->palette_format); return -1; } - if (vi->vga_palette) - { - vi->vms.regs.eax = 0x1012; - vi->vms.regs.ebx = first; - vi->vms.regs.ecx = number; - vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); - vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base); - j = 0; - i = 0; - while (number--) - { - palette_scratch[j++] = entries[i++] >> (8-vi->palette_format); - palette_scratch[j++] = entries[i++] >> (8-vi->palette_format); - palette_scratch[j++] = entries[i++] >> (8-vi->palette_format); - i++; - } - } + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 4 * 256); + + palette_scratch = &LM(vi, palette_base); + + for(i=0; i<number*4; i++) + palette_scratch[i] = entries[i] >> (8 - vbe->palette_format); + + vi->vms.regs.eax = 0x4F09; + if(vbe->palette_wait) + vi->vms.regs.ebx = 0x80; else - { - for(i=0; i<number*4; i++) - palette_scratch[i] = entries[i] >> (8 - vi->palette_format); - - vi->vms.regs.eax = 0x4F09; - if(vi->palette_wait) - vi->vms.regs.ebx = 0x80; - else - vi->vms.regs.ebx = 0x00; - vi->vms.regs.ecx = number; - vi->vms.regs.edx = first; - vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); - vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base); - } + vi->vms.regs.ebx = 0x00; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edi = POINTER_OFFSET(palette_base); code = VbeDoInterrupt10(vi); + Vm86ReleaseMemory (vi, mark); + if(code < 0) return -1; return 0; -} +} int -VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries) +VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries) { - U8 *palette_scratch; - int i, j, code; + U8 *palette_scratch; + int mark; + int palette_base; + int i, j, code; - code = PreparePalette(vi); - if(code < 0) - return -1; + if(number == 0) + return 0; - if(first< 0 || number < 0 || first + number > 256) { + if(first < 0 || number < 0 || first + number > 256) { ErrorF("Cannot get %d, %d palette entries\n", first, number); return -1; } - palette_scratch = &LM(vi, vi->palette_scratch_base); - - if(vi->palette_format < 6 || vi->palette_format > 8) { - ErrorF("Impossible palette format %d\n", vi->palette_format); + if(vbe->palette_format < 6 || vbe->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vbe->palette_format); return -1; } -retry: - if (vi->vga_palette) - { - vi->vms.regs.eax = 0x1017; - vi->vms.regs.ebx = first; - vi->vms.regs.ecx = number; - vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); - vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base); - code = VbeDoInterrupt10(vi); - if(code < 0) - return -1; - j = 0; - i = 0; - while (number--) - { - entries[i++] = palette_scratch[j++] << (8-vi->palette_format); - entries[i++] = palette_scratch[j++] << (8-vi->palette_format); - entries[i++] = palette_scratch[j++] << (8-vi->palette_format); - entries[i++] = 0; - } - } - else - { - vi->vms.regs.eax = 0x4F09; - vi->vms.regs.ebx = 0x01; - vi->vms.regs.ecx = number; - vi->vms.regs.edx = first; - vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); - vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base); - code = VbeDoInterrupt10(vi); - if(code < 0) - { - vi->vga_palette = TRUE; - goto retry; - } + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 4 * 256); + palette_scratch = &LM(vi, palette_base); + + vi->vms.regs.eax = 0x4F09; + vi->vms.regs.ebx = 0x01; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edi = POINTER_OFFSET(palette_base); + code = VbeDoInterrupt10(vi); + if(code >= 0) + { for(i=0; i<number*4; i++) - entries[i] = palette_scratch[i] << (8-vi->palette_format); + entries[i] = palette_scratch[i] << (8-vbe->palette_format); } + Vm86ReleaseMemory (vi, mark); return 0; } int -VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait) +VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait) { int code; + if(bits < 6 || bits > 8) { - ErrorF("Impossible palette format %d\n", vi->palette_format); + ErrorF("Impossible palette format %d\n", bits); return -1; } - if(bits != vi->palette_format) { - vi->palette_format = 0; + if(bits != vbe->palette_format) + { + vbe->palette_format = 0; vi->vms.regs.eax = 0x4F08; vi->vms.regs.ebx = bits << 8; code = VbeDoInterrupt10(vi); if(code < 0) return -1; - vi->palette_format = bits; + vbe->palette_format = bits; } - vi->palette_wait = wait; + vbe->palette_wait = wait; return 0; } static int -VbeReallySetWindow(VbeInfoPtr vi, U8 window, U16 winnum) +VbeReallySetWindow(Vm86InfoPtr vi, U8 window, U16 winnum) { int code; vi->vms.regs.eax = 0x4F05; @@ -564,82 +434,66 @@ VbeReallySetWindow(VbeInfoPtr vi, U8 window, U16 winnum) } void * -VbeSetWindow(VbeInfoPtr vi, int offset, int purpose, int *size_return) +VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return) { - VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base)); - int window_size = vmib->WinSize * 1024; + int window_size = vbe->vmib.WinSize * 1024; int code; int winnum; - if(vi->windowA_offset >= 0) - if(vi->windowA_offset <= offset && vi->windowA_offset + window_size > offset) - if(vmib->WinAAttributes & purpose) - goto windowA; + if(vbe->windowA_offset >= 0) + if(vbe->windowA_offset <= offset && vbe->windowA_offset + window_size > offset) + if(vbe->vmib.WinAAttributes & purpose) + goto windowA; - if(vi->windowB_offset >= 0) - if(vi->windowB_offset <= offset && vi->windowB_offset + window_size > offset) - if(vmib->WinBAttributes & purpose) - goto windowB; + if(vbe->windowB_offset >= 0) + if(vbe->windowB_offset <= offset && vbe->windowB_offset + window_size > offset) + if(vbe->vmib.WinBAttributes & purpose) + goto windowB; - if(!(vmib->WinBAttributes & purpose) || - !(vmib->WinBAttributes & VBE_WINDOW_RELOCATE)) - goto set_windowA; + if(!(vbe->vmib.WinBAttributes & purpose) || + !(vbe->vmib.WinBAttributes & VBE_WINDOW_RELOCATE)) + goto set_windowA; - if(!(vmib->WinAAttributes & purpose) || - !(vmib->WinAAttributes & VBE_WINDOW_RELOCATE)) - goto set_windowB; + if(!(vbe->vmib.WinAAttributes & purpose) || + !(vbe->vmib.WinAAttributes & VBE_WINDOW_RELOCATE)) + goto set_windowB; - if(vi->last_window) - goto set_windowA; + if(vbe->last_window) + goto set_windowA; else - goto set_windowB; + goto set_windowB; - set_windowA: - winnum = offset / (vmib->WinGranularity * 1024); +set_windowA: + winnum = offset / (vbe->vmib.WinGranularity * 1024); code = VbeReallySetWindow(vi, 0, winnum); if(code < 0) { - ErrorF("Couldn't set window A to %d*%d\n", - (int)winnum, (int)vmib->WinGranularity); - return NULL; - } - vi->windowA_offset = winnum * vmib->WinGranularity * 1024; - windowA: - vi->last_window = 0; - *size_return = vmib->WinSize * 1024 - (offset - vi->windowA_offset); - return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinASegment, 0)))) + - offset - vi->windowA_offset; - - set_windowB: - winnum = offset / (vmib->WinGranularity * 1024); + ErrorF("Couldn't set window A to %d*%d\n", + (int)winnum, (int)vbe->vmib.WinGranularity); + return NULL; + } + vbe->windowA_offset = winnum * vbe->vmib.WinGranularity * 1024; +windowA: + vbe->last_window = 0; + *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowA_offset); + return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinASegment, 0)))) + offset - vbe->windowA_offset; + +set_windowB: + winnum = offset / (vbe->vmib.WinGranularity * 1024); code = VbeReallySetWindow(vi, 1, winnum); if(code < 0) { - ErrorF("Couldn't set window B to %d*%d\n", - (int)winnum, (int)vmib->WinGranularity); - return NULL; + ErrorF("Couldn't set window B to %d*%d\n", + (int)winnum, (int)vbe->vmib.WinGranularity); + return NULL; } - vi->windowB_offset = winnum * vmib->WinGranularity * 1024; - windowB: - vi->last_window = 1; - *size_return = vmib->WinSize * 1024 - (offset - vi->windowB_offset); - return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinBSegment, 0)))) + offset - vi->windowB_offset; -} - -int -VbeSetWritePlaneMask(VbeInfoPtr vi, int mask) -{ - asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4)); - asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5)); -} - -int -VbeSetReadPlaneMap(VbeInfoPtr vi, int map) -{ - asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce)); - asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf)); + vbe->windowB_offset = winnum * vbe->vmib.WinGranularity * 1024; +windowB: + vbe->last_window = 1; + *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowB_offset); + return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinBSegment, 0)))) + offset - vbe->windowB_offset; } int -VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib) +VbeReportVib(Vm86InfoPtr vi, VbeInfoBlock *vib) { U32 i, p; unsigned char c; @@ -649,9 +503,10 @@ VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib) (vib->VbeVersion & 0xFF)+'0'); p = vib->OemStringPtr; for(i = 0; 1; i++) { - c = VbeMemory(vi, MAKE_POINTER_1(p+i)); + c = Vm86Memory(vi, MAKE_POINTER_1(p+i)); if(!c) break; - ErrorF("%c", c); + if (c >= ' ') + ErrorF("%c", c); if (i > 32000) { error = 1; break; @@ -669,7 +524,7 @@ VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib) } int -VbeReportModeInfo(VbeInfoPtr vi, U16 mode, VbeModeInfoBlock *vmib) +VbeReportModeInfo(Vm86InfoPtr vi, U16 mode, VbeModeInfoBlock *vmib) { int supported = (vmib->ModeAttributes&0x1)?1:0; int colour = (vmib->ModeAttributes&0x8)?1:0; @@ -725,526 +580,43 @@ VbeReportModeInfo(VbeInfoPtr vi, U16 mode, VbeModeInfoBlock *vmib) ErrorF("\n"); return 0; } + int -VbeDoInterrupt10(VbeInfoPtr vi) +VbeDoInterrupt10(Vm86InfoPtr vi) { int code; int oldax; oldax = vi->vms.regs.eax & 0xFFFF; - code = VbeDoInterrupt(vi, 0x10); - + code = Vm86DoInterrupt(vi, 0x10); if(code < 0) - return -1; + return -1; if((vi->vms.regs.eax & 0xFFFF) != 0x4F && (oldax & 0xFF00) == 0x4F00) { - ErrorF("Int 10h (0x%04X) failed: 0x%04X", - oldax, vi->vms.regs.eax & 0xFFFF); - if((oldax & 0xFF00) == 0x4F00) { - switch((vi->vms.regs.eax & 0xFF00)>>8) { - case 0: - ErrorF(" (success)\n"); - break; - case 1: - ErrorF(" (function call failed)\n"); - break; - case 2: - ErrorF(" (function not supported on this hardware)\n"); - break; - case 3: - ErrorF(" (function call invalid in this video mode)\n"); - break; - default: - ErrorF(" (unknown error)\n"); - break; - } - return -1; - } else { - ErrorF("\n"); - } + ErrorF("Int 10h (0x%04X) failed: 0x%04X", + oldax, vi->vms.regs.eax & 0xFFFF); + if((oldax & 0xFF00) == 0x4F00) { + switch((vi->vms.regs.eax & 0xFF00)>>8) { + case 0: + ErrorF(" (success)\n"); + return 0; + case 1: + ErrorF(" (function call failed)\n"); + break; + case 2: + ErrorF(" (function not supported on this hardware)\n"); + break; + case 3: + ErrorF(" (function call invalid in this video mode)\n"); + break; + default: + ErrorF(" (unknown error)\n"); + break; + } return -1; + } else { + ErrorF("\n"); + } } return code; } - -int -VbeDoInterrupt(VbeInfoPtr vi, int num) -{ - U16 seg, off; - int code; - - if(num < 0 || num>256) { - ErrorF("Interrupt %d doesn't exist\n"); - return -1; - } - seg = MMW(vi,num * 4 + 2); - off = MMW(vi,num * 4); - if(MAKE_POINTER(seg, off) < ROM_BASE || - MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) { - ErrorF("Interrupt pointer doesn't point at ROM\n"); - return -1; - } - memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data)); - vi->vms.regs.eflags = IF_MASK | IOPL_MASK; - vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base); - vi->vms.regs.esp = STACK_SIZE; - PUSHW(vi, IF_MASK | IOPL_MASK); - PUSHW(vi, POINTER_SEGMENT(vi->ret_code)); - PUSHW(vi, POINTER_OFFSET(vi->ret_code)); - vi->vms.regs.cs = seg; - vi->vms.regs.eip = off; - OsBlockSignals (); - code = vm86_loop(vi); - OsReleaseSignals (); - if(code < 0) { - perror("vm86 failed"); - return -1; - } else if(code != 0) { - ErrorF("vm86 returned 0x%04X\n", code); - return -1; - } else - return 0; -} - -static inline U8 -vm86_inb(U16 port) -{ - U8 value; - asm volatile ("inb %w1,%b0" : "=a" (value) : "d" (port)); - return value; -} - -static inline U16 -vm86_inw(U16 port) -{ - U16 value; - asm volatile ("inw %w1,%w0" : "=a" (value) : "d" (port)); - return value; -} - -static inline U32 -vm86_inl(U16 port) -{ - U32 value; - asm volatile ("inl %w1,%0" : "=a" (value) : "d" (port)); - return value; -} - -static inline void -vm86_outb(U16 port, U8 value) -{ - asm volatile ("outb %b0,%w1" : : "a" (value), "d" (port)); -} - -static inline void -vm86_outw(U16 port, U16 value) -{ - asm volatile ("outw %w0,%w1" : : "a" (value), "d" (port)); -} - -static inline void -vm86_outl(U16 port, U32 value) -{ - asm volatile ("outl %0,%w1" : : "a" (value), "d" (port)); -} - -#define SEG_CS 1 -#define SEG_DS 2 -#define SEG_ES 3 -#define SEG_SS 4 -#define SEG_GS 5 -#define SEG_FS 6 -#define REP 1 -#define REPNZ 2 -#define SET_8(_x, _y) (_x) = (_x & ~0xFF) | (_y & 0xFF); -#define SET_16(_x, _y) (_x) = (_x & ~0xFFFF) | (_y & 0xFFFF); -#define INC_IP(_i) SET_16(regs->eip, (regs->eip + _i)) -#define AGAIN INC_IP(1); goto again; - -static int -vm86_emulate(VbeInfoPtr vi) -{ - struct vm86_regs *regs = &vi->vms.regs; - U8 opcode; - int size; - int pref_seg = 0, pref_rep = 0, pref_66 = 0, pref_67 = 0; - U32 count; - int code; - - again: - if(!VbeIsMemory(vi, MAKE_POINTER(regs->cs, regs->eip))) { - ErrorF("Trying to execute unmapped memory\n"); - return -1; - } - opcode = VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip)); - switch(opcode) { - case 0x2E: pref_seg = SEG_CS; AGAIN; - case 0x3E: pref_seg = SEG_DS; AGAIN; - case 0x26: pref_seg = SEG_ES; AGAIN; - case 0x36: pref_seg = SEG_SS; AGAIN; - case 0x65: pref_seg = SEG_GS; AGAIN; - case 0x64: pref_seg = SEG_FS; AGAIN; - case 0x66: pref_66 = 1; AGAIN; - case 0x67: pref_67 = 1; AGAIN; - case 0xF2: pref_rep = REPNZ; AGAIN; - case 0xF3: pref_rep = REP; AGAIN; - - case 0xEC: /* IN AL, DX */ - SET_8(regs->eax, vm86_inb(regs->edx & 0xFFFF)); - INC_IP(1); - break; - case 0xED: /* IN AX, DX */ - if(pref_66) - regs->eax = vm86_inl(regs->edx & 0xFFFF); - else - SET_16(regs->eax, vm86_inw(regs->edx & 0xFFFF)); - INC_IP(1); - break; - case 0xE4: /* IN AL, imm8 */ - SET_8(regs->eax, - vm86_inb(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1)))); - INC_IP(2); - break; - case 0xE5: /* IN AX, imm8 */ - if(pref_66) - regs->eax = - vm86_inl(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1))); - else - SET_16(regs->eax, - vm86_inw(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1)))); - INC_IP(2); - break; - case 0x6C: /* INSB */ - case 0x6D: /* INSW */ - if(opcode == 0x6C) { - VbeWriteMemory(vi, MAKE_POINTER(regs->es, regs->edi), - vm86_inb(regs->edx & 0xFFFF)); - size = 1; - } else if(pref_66) { - VbeWriteMemoryL(vi, MAKE_POINTER(regs->es, regs->edi), - vm86_inl(regs->edx & 0xFFFF)); - size = 4; - } else { - VbeWriteMemoryW(vi, MAKE_POINTER(regs->es, regs->edi), - vm86_inw(regs->edx & 0xFFFF)); - size = 2; - } - if(regs->eflags & (1<<10)) - regs->edi -= size; - else - regs->edi += size; - if(pref_rep) { - if(pref_66) { - regs->ecx--; - if(regs->ecx != 0) { - goto again; - } else { - SET_16(regs->ecx, regs->ecx - 1); - if(regs->ecx & 0xFFFF != 0) - goto again; - } - } - } - INC_IP(1); - break; - - case 0xEE: /* OUT DX, AL */ - vm86_outb(regs->edx & 0xFFFF, regs->eax & 0xFF); - INC_IP(1); - break; - case 0xEF: /* OUT DX, AX */ - if(pref_66) - vm86_outl(regs->edx & 0xFFFF, regs->eax); - else - vm86_outw(regs->edx & 0xFFFF, regs->eax & 0xFFFF); - INC_IP(1); - break; - case 0xE6: /* OUT imm8, AL */ - vm86_outb(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), - regs->eax & 0xFF); - INC_IP(2); - break; - case 0xE7: /* OUT imm8, AX */ - if(pref_66) - vm86_outl(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), - regs->eax); - else - vm86_outw(VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), - regs->eax & 0xFFFF); - INC_IP(2); - break; - case 0x6E: /* OUTSB */ - case 0x6F: /* OUTSW */ - if(opcode == 0x6E) { - vm86_outb(regs->edx & 0xFFFF, - VbeMemory(vi, MAKE_POINTER(regs->es, regs->edi))); - size = 1; - } else if(pref_66) { - vm86_outl(regs->edx & 0xFFFF, - VbeMemory(vi, MAKE_POINTER(regs->es, regs->edi))); - size = 4; - } else { - vm86_outw(regs->edx & 0xFFFF, - VbeMemory(vi, MAKE_POINTER(regs->es, regs->edi))); - size = 2; - } - if(regs->eflags & (1<<10)) - regs->edi -= size; - else - regs->edi += size; - if(pref_rep) { - if(pref_66) { - regs->ecx--; - if(regs->ecx != 0) { - goto again; - } else { - SET_16(regs->ecx, regs->ecx - 1); - if(regs->ecx & 0xFFFF != 0) - goto again; - } - } - } - INC_IP(1); - break; - - case 0x0F: - ErrorF("Hit 0F trap in VM86 code\n"); - return -1; - case 0xF0: - ErrorF("Hit lock prefix in VM86 code\n"); - return -1; - case 0xF4: - ErrorF("Hit HLT in VM86 code\n"); - return -1; - - default: - ErrorF("Unhandled GP fault in VM86 code (opcode = 0x%02X)\n", - opcode); - return -1; - } - return 0; -} -#undef SEG_CS -#undef SEG_DS -#undef SEG_ES -#undef SEG_SS -#undef SEG_GS -#undef SEG_FS -#undef REP -#undef REPNZ -#undef SET_8 -#undef SET_16 -#undef INC_IP -#undef AGAIN - -static int -vm86_loop(VbeInfoPtr vi) -{ - int code; - - while(1) { - code = vm86old(&vi->vms); - switch(VM86_TYPE(code)) { - case VM86_SIGNAL: - continue; - case VM86_UNKNOWN: - code = vm86_emulate(vi); - if(code < 0) { - VbeDebug(vi); - return -1; - } - break; - case VM86_INTx: - if(VM86_ARG(code) == 0xFF) - return 0; - else { - PUSHW(vi, vi->vms.regs.eflags) - PUSHW(vi, vi->vms.regs.cs); - PUSHW(vi, vi->vms.regs.eip); - vi->vms.regs.cs = MMW(vi,VM86_ARG(code) * 4 + 2); - vi->vms.regs.eip = MMW(vi,VM86_ARG(code) * 4); - } - break; - case VM86_STI: - ErrorF("VM86 code enabled interrupts\n"); - VbeDebug(vi); - return -1; - default: - ErrorF("Unexpected result code 0x%X from vm86\n", code); - VbeDebug(vi); - return -1; - } - } -} - -int -VbeIsMemory(VbeInfoPtr vi, U32 i) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - return 1; - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - return 1; - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - return 1; - else - return 0; -} - -U8 -VbeMemory(VbeInfoPtr vi, U32 i) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - return MM(vi, i); - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - return LM(vi, i); - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - return HM(vi, i); - else { - ErrorF("Reading unmapped memory at 0x%08X\n", i); - } -} - -U16 -VbeMemoryW(VbeInfoPtr vi, U32 i) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - return MMW(vi, i); - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - return LMW(vi, i); - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - return HMW(vi, i); - else { - ErrorF("Reading unmapped memory at 0x%08X\n", i); - return 0; - } -} - -U32 -VbeMemoryL(VbeInfoPtr vi, U32 i) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - return MML(vi, i); - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - return LML(vi, i); - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - return HML(vi, i); - else { - ErrorF("Reading unmapped memory at 0x%08X\n", i); - return 0; - } -} - -void -VbeWriteMemory(VbeInfoPtr vi, U32 i, U8 val) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - MM(vi, i) = val; - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - LM(vi, i) = val; - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - HM(vi, i) = val; - else { - ErrorF("Writing unmapped memory at 0x%08X\n", i); - } -} - -void -VbeWriteMemoryW(VbeInfoPtr vi, U32 i, U16 val) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - MMW(vi, i) = val; - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - LMW(vi, i) = val; - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - HMW(vi, i) = val; - else { - ErrorF("Writing unmapped memory at 0x%08X\n", i); - } -} - -void -VbeWriteMemoryL(VbeInfoPtr vi, U32 i, U32 val) -{ - if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) - MML(vi, i) = val; - else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) - LML(vi, i) = val; - else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) - HML(vi, i) = val; - else { - ErrorF("Writing unmapped memory at 0x%08X\n", i); - } -} - -int -VbeAllocateMemory(VbeInfoPtr vi, int n) -{ - int ret; - if(n<0) { - ErrorF("Asked to allocate negative amount of memory\n"); - return vi->brk; - } - - n = (n + 15) & ~15; - if(vi->brk + n > LOMEM_BASE + LOMEM_SIZE) { - ErrorF("Out of low memory\n"); - exit(2); - } - ret = vi->brk; - vi->brk += n; - return ret; -} - -static int -vm86old(struct vm86_struct *vm) -{ - int res; - - asm volatile ( - "pushl %%ebx\n\t" - "movl %2, %%ebx\n\t" - "movl %1,%%eax\n\t" - "int $0x80\n\t" - "popl %%ebx" - : "=a" (res) : "n" (113), "r" (vm)); - if(res < 0) { - errno = -res; - res = -1; - } else - errno = 0; - OsReleaseSignals (); - return res; -} - -void -VbeDebug(VbeInfoPtr vi) -{ - struct vm86_regs *regs = &vi->vms.regs; - int i; - - ErrorF("eax=0x%08lX ebx=0x%08lX ecx=0x%08lX edx=0x%08lX\n", - regs->eax, regs->ebx, regs->ecx, regs->edx); - ErrorF("esi=0x%08lX edi=0x%08lX ebp=0x%08lX\n", - regs->esi, regs->edi, regs->ebp); - ErrorF("eip=0x%08lX esp=0x%08lX eflags=0x%08lX\n", - regs->eip, regs->esp, regs->eflags); - ErrorF("cs=0x%04lX ds=0x%04lX es=0x%04lX fs=0x%04lX gs=0x%04lX\n", - regs->cs, regs->ds, regs->es, regs->fs, regs->gs); - for(i=-7; i<8; i++) { - ErrorF(" %s%02X", - i==0?"->":"", - VbeMemory(vi, MAKE_POINTER(regs->cs, regs->eip + i))); - } - ErrorF("\n"); -} - -#ifdef NOT_IN_X_SERVER -static void -ErrorF(char *f, ...) -{ - va_list args; - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); -} -#endif |