243 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 2000 Keith Packard
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Keith Packard not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Keith Packard makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
#include "vesa.h"
 | 
						|
 | 
						|
static const VesaModeRec vgaModes[] = {
 | 
						|
    {
 | 
						|
	6,  0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
 | 
						|
	1, 1, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	640, 200, 80,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0xd, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
 | 
						|
	4, 4, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	320, 200, 40,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0xe, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
 | 
						|
	4, 4, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	640, 200, 80,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0x10, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
 | 
						|
	4, 4, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	640, 350, 80,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0x11, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
 | 
						|
	1, 1, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	640, 480, 80,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0x12, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
 | 
						|
	4, 4, MEMORY_PLANAR, 
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	640, 480, 80,
 | 
						|
    },
 | 
						|
    {
 | 
						|
	0x13, 0,
 | 
						|
	MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR | MODE_LINEAR,
 | 
						|
	8, 8, MEMORY_PSEUDO,
 | 
						|
	0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
						|
	320, 200, 320,
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_VGA_MODE	(sizeof vgaModes / sizeof vgaModes[0])
 | 
						|
 | 
						|
int
 | 
						|
VgaGetNmode (Vm86InfoPtr vi)
 | 
						|
{
 | 
						|
    return NUM_VGA_MODE;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode)
 | 
						|
{
 | 
						|
    if (nmode > NUM_VGA_MODE)
 | 
						|
	nmode = NUM_VGA_MODE;
 | 
						|
    memcpy (mode, vgaModes, nmode * sizeof (VesaModeRec));
 | 
						|
    return nmode;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
VgaSetMode(Vm86InfoPtr vi, int mode)
 | 
						|
{
 | 
						|
    int code;
 | 
						|
    
 | 
						|
    vi->vms.regs.eax = mode & 0x7f;
 | 
						|
    code = Vm86DoInterrupt (vi, 0x10);
 | 
						|
    if(code < 0)
 | 
						|
        return -1;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
VgaGetMode (Vm86InfoPtr vi, int *mode)
 | 
						|
{
 | 
						|
    *mode = Vm86Memory (vi, 0x449);
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask)
 | 
						|
{
 | 
						|
    asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4));
 | 
						|
    asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
VgaSetReadPlaneMap(Vm86InfoPtr vi, int map)
 | 
						|
{
 | 
						|
    asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce));
 | 
						|
    asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf));
 | 
						|
}
 | 
						|
 | 
						|
int 
 | 
						|
VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
 | 
						|
{
 | 
						|
    U8	    *palette_scratch;
 | 
						|
    int	    mark;
 | 
						|
    int	    palette_base;
 | 
						|
    int	    i, j, code;
 | 
						|
 | 
						|
    if(number == 0)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if(first < 0 || number < 0 || first + number > 256) {
 | 
						|
        ErrorF("Cannot set %d, %d palette entries\n", first, number);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    mark = Vm86MarkMemory (vi);
 | 
						|
    palette_base = Vm86AllocateMemory (vi, 3 * 256);
 | 
						|
    
 | 
						|
    palette_scratch = &LM(vi, palette_base);
 | 
						|
 | 
						|
    vi->vms.regs.eax = 0x1012;
 | 
						|
    vi->vms.regs.ebx = first;
 | 
						|
    vi->vms.regs.ecx = number;
 | 
						|
    vi->vms.regs.es = POINTER_SEGMENT(palette_base);
 | 
						|
    vi->vms.regs.edx = POINTER_OFFSET(palette_base);
 | 
						|
    j = 0;
 | 
						|
    i = 0;
 | 
						|
    while (number--)
 | 
						|
    {
 | 
						|
	palette_scratch[j++] = entries[i++] >> 2;
 | 
						|
	palette_scratch[j++] = entries[i++] >> 2;
 | 
						|
	palette_scratch[j++] = entries[i++] >> 2;
 | 
						|
	i++;
 | 
						|
    }
 | 
						|
    code = Vm86DoInterrupt(vi, 0x10);
 | 
						|
    Vm86ReleaseMemory (vi, mark);
 | 
						|
    
 | 
						|
    if(code < 0)
 | 
						|
	return -1;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
        
 | 
						|
int 
 | 
						|
VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
 | 
						|
{
 | 
						|
    U8	    *palette_scratch;
 | 
						|
    int	    mark;
 | 
						|
    int	    palette_base;
 | 
						|
    int	    i, j, code;
 | 
						|
 | 
						|
    if(number == 0)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if(first < 0 || number < 0 || first + number > 256) {
 | 
						|
        ErrorF("Cannot get %d, %d palette entries\n", first, number);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    mark = Vm86MarkMemory (vi);
 | 
						|
    palette_base = Vm86AllocateMemory (vi, 3 * 256);
 | 
						|
    
 | 
						|
    palette_scratch = &LM(vi, palette_base);
 | 
						|
 | 
						|
    vi->vms.regs.eax = 0x1017;
 | 
						|
    vi->vms.regs.ebx = first;
 | 
						|
    vi->vms.regs.ecx = number;
 | 
						|
    vi->vms.regs.es = POINTER_SEGMENT(palette_base);
 | 
						|
    vi->vms.regs.edx = POINTER_OFFSET(palette_base);
 | 
						|
    
 | 
						|
    code = VbeDoInterrupt10(vi);
 | 
						|
    if(code < 0)
 | 
						|
	return -1;
 | 
						|
    
 | 
						|
    j = 0;
 | 
						|
    i = 0;
 | 
						|
    while (number--)
 | 
						|
    {
 | 
						|
	entries[i++] = palette_scratch[j++] << 2;
 | 
						|
	entries[i++] = palette_scratch[j++] << 2;
 | 
						|
	entries[i++] = palette_scratch[j++] << 2;
 | 
						|
	entries[i++] = 0;
 | 
						|
    }
 | 
						|
    
 | 
						|
    Vm86ReleaseMemory (vi, mark);
 | 
						|
 | 
						|
    return 0;
 | 
						|
}   
 | 
						|
        
 | 
						|
#define VGA_FB(vm)  ((vm) < 8 ? 0xb8000 : 0xa0000)
 | 
						|
 | 
						|
void *
 | 
						|
VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size)
 | 
						|
{
 | 
						|
    *size = 0x10000 - bytes;
 | 
						|
    return &LM(vi,VGA_FB(vmode) + bytes);
 | 
						|
}
 | 
						|
 | 
						|
void *
 | 
						|
VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *ret_phys)
 | 
						|
{
 | 
						|
    if (VGA_FB(vmode) == 0xa0000)
 | 
						|
	*size = 0x10000;
 | 
						|
    else
 | 
						|
	*size = 0x4000;
 | 
						|
    *ret_phys = VGA_FB(vmode);
 | 
						|
    return &LM(vi,VGA_FB(vmode));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
VgaUnmapFramebuffer (Vm86InfoPtr vi)
 | 
						|
{
 | 
						|
}
 |